xref: /AOO41X/main/svx/source/svdraw/svdotxed.cxx (revision 5df46f50f7fee44c78edd2cc41d77993871aea66)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/svdotext.hxx>
28 #include "svx/svditext.hxx"
29 #include <svx/svdmodel.hxx> // fuer GetMaxObjSize
30 #include <svx/svdoutl.hxx>
31 #include <editeng/outliner.hxx>
32 #include <editeng/editstat.hxx>
33 #include <svl/itemset.hxx>
34 #include <editeng/eeitem.hxx>
35 #include <svx/sdtfchim.hxx>
36 
37 ////////////////////////////////////////////////////////////////////////////////////////////////////
38 //
39 //  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
40 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
41 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
42 //    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
43 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
44 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
45 //    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
46 //
47 //  TextEdit
48 //
49 ////////////////////////////////////////////////////////////////////////////////////////////////////
50 
HasTextEdit() const51 FASTBOOL SdrTextObj::HasTextEdit() const
52 {
53     // lt. Anweisung von MB duerfen gelinkte Textobjekte nun doch
54     // geaendert werden (kein automatisches Reload)
55     return sal_True;
56 }
57 
BegTextEdit(SdrOutliner & rOutl)58 sal_Bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
59 {
60     if (pEdtOutl!=NULL) return sal_False; // Textedit laeuft evtl. schon an einer anderen View!
61     pEdtOutl=&rOutl;
62 
63     // #101684#
64     mbInEditMode = sal_True;
65 
66     sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
67     if ( !IsOutlText() )
68         nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
69     rOutl.Init( nOutlinerMode );
70     rOutl.SetRefDevice( pModel->GetRefDevice() );
71 
72     SdrFitToSizeType eFit=GetFitToSize();
73     FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
74     FASTBOOL bContourFrame=IsContourTextFrame();
75     ImpSetTextEditParams();
76 
77     if (!bContourFrame) {
78         sal_uIntPtr nStat=rOutl.GetControlWord();
79         nStat|=EE_CNTRL_AUTOPAGESIZE;
80         if (bFitToSize) nStat|=EE_CNTRL_STRETCHING; else nStat&=~EE_CNTRL_STRETCHING;
81         rOutl.SetControlWord(nStat);
82     }
83 
84     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
85     if(pOutlinerParaObject!=NULL)
86     {
87         rOutl.SetText(*GetOutlinerParaObject());
88         rOutl.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
89     }
90 
91     // ggf. Rahmenattribute am 1. (neuen) Absatz des Outliners setzen
92     if( !HasTextImpl( &rOutl ) )
93     {
94         // Outliner has no text so we must set some
95         // empty text so the outliner initialise itself
96         rOutl.SetText( String(), rOutl.GetParagraph( 0 ) );
97 
98         if(GetStyleSheet())
99             rOutl.SetStyleSheet( 0, GetStyleSheet());
100 
101         // Beim setzen der harten Attribute an den ersten Absatz muss
102         // der Parent pOutlAttr (=die Vorlage) temporaer entfernt
103         // werden, da sonst bei SetParaAttribs() auch alle in diesem
104         // Parent enthaltenen Items hart am Absatz attributiert werden.
105         // -> BugID 22467
106         const SfxItemSet& rSet = GetObjectItemSet();
107         SfxItemSet aFilteredSet(*rSet.GetPool(), EE_ITEMS_START, EE_ITEMS_END);
108         aFilteredSet.Put(rSet);
109         rOutl.SetParaAttribs(0, aFilteredSet);
110     }
111     if (bFitToSize)
112     {
113         Rectangle aAnchorRect;
114         Rectangle aTextRect;
115         TakeTextRect(rOutl, aTextRect, sal_False,
116             &aAnchorRect/* #97097# give sal_True here, not sal_False */);
117         Fraction aFitXKorreg(1,1);
118         ImpSetCharStretching(rOutl,aTextRect,aAnchorRect,aFitXKorreg);
119     }
120 
121     if(pOutlinerParaObject)
122     {
123         // #78476# also repaint when animated text is put to edit mode
124         // to not make appear the text double
125         // #111096# should now repaint automatically.
126         // sal_Bool bIsAnimated(pPlusData && pPlusData->pAnimator);
127 
128         if(aGeo.nDrehWink || IsFontwork() /*|| bIsAnimated*/)
129         {
130             // only repaint here, no real objectchange
131 
132 //          ActionChanged();
133             BroadcastObjectChange();
134         }
135     }
136 
137     rOutl.UpdateFields();
138     rOutl.ClearModifyFlag();
139 
140     return sal_True;
141 }
142 
TakeTextEditArea(Size * pPaperMin,Size * pPaperMax,Rectangle * pViewInit,Rectangle * pViewMin) const143 void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
144 {
145     SdrFitToSizeType eFit=GetFitToSize();
146     FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
147     Size aPaperMin,aPaperMax;
148     Rectangle aViewInit;
149     TakeTextAnchorRect(aViewInit);
150     if (aGeo.nDrehWink!=0) {
151         Point aCenter(aViewInit.Center());
152         aCenter-=aViewInit.TopLeft();
153         Point aCenter0(aCenter);
154         RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
155         aCenter-=aCenter0;
156         aViewInit.Move(aCenter.X(),aCenter.Y());
157     }
158     Size aAnkSiz(aViewInit.GetSize());
159     aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
160     Size aMaxSiz(1000000,1000000);
161     if (pModel!=NULL) {
162         Size aTmpSiz(pModel->GetMaxObjSize());
163         if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
164         if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
165     }
166 
167     // #106879#
168     // Done earlier since used in else tree below
169     SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
170     SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
171 
172     if(IsTextFrame())
173     {
174         long nMinWdt=GetMinTextFrameWidth();
175         long nMinHgt=GetMinTextFrameHeight();
176         long nMaxWdt=GetMaxTextFrameWidth();
177         long nMaxHgt=GetMaxTextFrameHeight();
178         if (nMinWdt<1) nMinWdt=1;
179         if (nMinHgt<1) nMinHgt=1;
180         if (!bFitToSize) {
181             if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width())  nMaxWdt=aMaxSiz.Width();
182             if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
183 
184             if (!IsAutoGrowWidth() )
185             {
186                 nMinWdt = aAnkSiz.Width();
187                 nMaxWdt = nMinWdt;
188             }
189 
190             if (!IsAutoGrowHeight())
191             {
192                 nMinHgt = aAnkSiz.Height();
193                 nMaxHgt = nMinHgt;
194             }
195 
196             SdrTextAniKind      eAniKind=GetTextAniKind();
197             SdrTextAniDirection eAniDirection=GetTextAniDirection();
198 
199             // #101684#
200             sal_Bool bInEditMode = IsInEditMode();
201 
202             if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
203             {
204                 // Grenzenlose Papiergroesse fuer Laufschrift
205                 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
206                 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
207             }
208 
209             // #119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
210             if(IsVerticalWriting())
211             {
212                 nMaxWdt = 1000000;
213             }
214             else
215             {
216                 nMaxHgt = 1000000;
217             }
218 
219             aPaperMax.Width()=nMaxWdt;
220             aPaperMax.Height()=nMaxHgt;
221         }
222         else
223         {
224             aPaperMax=aMaxSiz;
225         }
226         aPaperMin.Width()=nMinWdt;
227         aPaperMin.Height()=nMinHgt;
228     }
229     else
230     {
231         // #106879#
232         // aPaperMin needs to be set to object's size if full width is activated
233         // for hor or ver writing respectively
234         if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
235             || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
236         {
237             aPaperMin = aAnkSiz;
238         }
239 
240         aPaperMax=aMaxSiz;
241     }
242 
243     if (pViewMin!=NULL) {
244         *pViewMin=aViewInit;
245 
246         long nXFree=aAnkSiz.Width()-aPaperMin.Width();
247         if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
248         else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
249         else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
250 
251         long nYFree=aAnkSiz.Height()-aPaperMin.Height();
252         if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
253         else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
254         else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
255     }
256 
257     // Die PaperSize soll in den meisten Faellen von selbst wachsen
258     // #89459#
259     if(IsVerticalWriting())
260         aPaperMin.Width() = 0;
261     else
262         aPaperMin.Height() = 0; // #33102#
263 
264     if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
265         aPaperMin.Width()=0;
266     }
267 
268     // #103516# For complete ver adjust support, set paper min height to 0, here.
269     if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
270     {
271         aPaperMin.Height() = 0;
272     }
273 
274     if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
275     if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
276     if (pViewInit!=NULL) *pViewInit=aViewInit;
277 }
278 
EndTextEdit(SdrOutliner & rOutl)279 void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
280 {
281     if(rOutl.IsModified())
282     {
283         OutlinerParaObject* pNewText = NULL;
284 
285         if(HasTextImpl( &rOutl ) )
286         {
287             // Damit der grauen Feldhintergrund wieder verschwindet
288             rOutl.UpdateFields();
289 
290             sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( rOutl.GetParagraphCount() );
291             pNewText = rOutl.CreateParaObject( 0, nParaAnz );
292         }
293 
294         // need to end edit mode early since SetOutlinerParaObject already
295         // uses GetCurrentBoundRect() which needs to take the text into account
296         // to work correct
297         mbInEditMode = sal_False;
298         SetOutlinerParaObject(pNewText);
299     }
300 
301     pEdtOutl = NULL;
302     rOutl.Clear();
303     sal_uInt32 nStat = rOutl.GetControlWord();
304     nStat &= ~EE_CNTRL_AUTOPAGESIZE;
305     rOutl.SetControlWord(nStat);
306 
307     // #101684#
308     mbInEditMode = sal_False;
309 }
310 
GetOutlinerViewAnchorMode() const311 sal_uInt16 SdrTextObj::GetOutlinerViewAnchorMode() const
312 {
313     SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
314     SdrTextVertAdjust eV=GetTextVerticalAdjust();
315     EVAnchorMode eRet=ANCHOR_TOP_LEFT;
316     if (IsContourTextFrame()) return (sal_uInt16)eRet;
317     if (eH==SDRTEXTHORZADJUST_LEFT) {
318         if (eV==SDRTEXTVERTADJUST_TOP) {
319             eRet=ANCHOR_TOP_LEFT;
320         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
321             eRet=ANCHOR_BOTTOM_LEFT;
322         } else {
323             eRet=ANCHOR_VCENTER_LEFT;
324         }
325     } else if (eH==SDRTEXTHORZADJUST_RIGHT) {
326         if (eV==SDRTEXTVERTADJUST_TOP) {
327             eRet=ANCHOR_TOP_RIGHT;
328         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
329             eRet=ANCHOR_BOTTOM_RIGHT;
330         } else {
331             eRet=ANCHOR_VCENTER_RIGHT;
332         }
333     } else {
334         if (eV==SDRTEXTVERTADJUST_TOP) {
335             eRet=ANCHOR_TOP_HCENTER;
336         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
337             eRet=ANCHOR_BOTTOM_HCENTER;
338         } else {
339             eRet=ANCHOR_VCENTER_HCENTER;
340         }
341     }
342     return (sal_uInt16)eRet;
343 }
344 
ImpSetTextEditParams() const345 void SdrTextObj::ImpSetTextEditParams() const
346 {
347     if (pEdtOutl!=NULL) {
348         FASTBOOL bUpdMerk=pEdtOutl->GetUpdateMode();
349         if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_False);
350         Size aPaperMin;
351         Size aPaperMax;
352         Rectangle aEditArea;
353         TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
354         //SdrFitToSizeType eFit=GetFitToSize();
355         //FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
356         FASTBOOL bContourFrame=IsContourTextFrame();
357         //EVAnchorMode eAM=(EVAnchorMode)GetOutlinerViewAnchorMode();
358         //sal_uIntPtr nViewAnz=pEdtOutl->GetViewCount();
359         pEdtOutl->SetMinAutoPaperSize(aPaperMin);
360         pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
361         pEdtOutl->SetPaperSize(Size());
362         if (bContourFrame) {
363             Rectangle aAnchorRect;
364             TakeTextAnchorRect(aAnchorRect);
365             ImpSetContourPolygon(*pEdtOutl,aAnchorRect, sal_True);
366         }
367         if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_True);
368     }
369 }
370 
371