xref: /AOO41X/main/svx/source/svdraw/svdotxed.cxx (revision c073947639c1be49b927d6e1ad12bed61bae3795)
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 
51 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 
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     const sal_Bool bFitToSize(GetFitToSize());
73     FASTBOOL bContourFrame=IsContourTextFrame();
74     ImpSetTextEditParams();
75 
76     if (!bContourFrame) {
77         sal_uIntPtr nStat=rOutl.GetControlWord();
78         nStat|=EE_CNTRL_AUTOPAGESIZE;
79         if (bFitToSize) nStat|=EE_CNTRL_STRETCHING; else nStat&=~EE_CNTRL_STRETCHING;
80         rOutl.SetControlWord(nStat);
81     }
82 
83     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
84     if(pOutlinerParaObject!=NULL)
85     {
86         rOutl.SetText(*GetOutlinerParaObject());
87         rOutl.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
88     }
89 
90     // ggf. Rahmenattribute am 1. (neuen) Absatz des Outliners setzen
91     if( !HasTextImpl( &rOutl ) )
92     {
93         // Outliner has no text so we must set some
94         // empty text so the outliner initialise itself
95         rOutl.SetText( String(), rOutl.GetParagraph( 0 ) );
96 
97         if(GetStyleSheet())
98             rOutl.SetStyleSheet( 0, GetStyleSheet());
99 
100         // Beim setzen der harten Attribute an den ersten Absatz muss
101         // der Parent pOutlAttr (=die Vorlage) temporaer entfernt
102         // werden, da sonst bei SetParaAttribs() auch alle in diesem
103         // Parent enthaltenen Items hart am Absatz attributiert werden.
104         // -> BugID 22467
105         const SfxItemSet& rSet = GetObjectItemSet();
106         SfxItemSet aFilteredSet(*rSet.GetPool(), EE_ITEMS_START, EE_ITEMS_END);
107         aFilteredSet.Put(rSet);
108         rOutl.SetParaAttribs(0, aFilteredSet);
109     }
110     if (bFitToSize)
111     {
112         Rectangle aAnchorRect;
113         Rectangle aTextRect;
114         TakeTextRect(rOutl, aTextRect, sal_False,
115             &aAnchorRect/* #97097# give sal_True here, not sal_False */);
116         Fraction aFitXKorreg(1,1);
117         ImpSetCharStretching(rOutl,aTextRect,aAnchorRect,aFitXKorreg);
118     }
119 
120     if(pOutlinerParaObject)
121     {
122         // #78476# also repaint when animated text is put to edit mode
123         // to not make appear the text double
124         // #111096# should now repaint automatically.
125         // sal_Bool bIsAnimated(pPlusData && pPlusData->pAnimator);
126 
127         if(aGeo.nDrehWink || IsFontwork() /*|| bIsAnimated*/)
128         {
129             // only repaint here, no real objectchange
130 
131 //          ActionChanged();
132             BroadcastObjectChange();
133         }
134     }
135 
136     rOutl.UpdateFields();
137     rOutl.ClearModifyFlag();
138 
139     return sal_True;
140 }
141 
142 void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
143 {
144     const sal_Bool bFitToSize(GetFitToSize());
145     Size aPaperMin,aPaperMax;
146     Rectangle aViewInit;
147     TakeTextAnchorRect(aViewInit);
148     if (aGeo.nDrehWink!=0) {
149         Point aCenter(aViewInit.Center());
150         aCenter-=aViewInit.TopLeft();
151         Point aCenter0(aCenter);
152         RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
153         aCenter-=aCenter0;
154         aViewInit.Move(aCenter.X(),aCenter.Y());
155     }
156     Size aAnkSiz(aViewInit.GetSize());
157     aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
158     Size aMaxSiz(1000000,1000000);
159     if (pModel!=NULL) {
160         Size aTmpSiz(pModel->GetMaxObjSize());
161         if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
162         if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
163     }
164 
165     // #106879#
166     // Done earlier since used in else tree below
167     SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
168     SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
169 
170     if(IsTextFrame())
171     {
172         long nMinWdt=GetMinTextFrameWidth();
173         long nMinHgt=GetMinTextFrameHeight();
174         long nMaxWdt=GetMaxTextFrameWidth();
175         long nMaxHgt=GetMaxTextFrameHeight();
176         if (nMinWdt<1) nMinWdt=1;
177         if (nMinHgt<1) nMinHgt=1;
178         if (!bFitToSize) {
179             if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width())  nMaxWdt=aMaxSiz.Width();
180             if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
181             if (!IsAutoGrowWidth() ) { nMaxWdt=aAnkSiz.Width();  nMinWdt=nMaxWdt; }
182             if (!IsAutoGrowHeight()) { nMaxHgt=aAnkSiz.Height(); nMinHgt=nMaxHgt; }
183             SdrTextAniKind      eAniKind=GetTextAniKind();
184             SdrTextAniDirection eAniDirection=GetTextAniDirection();
185 
186             // #101684#
187             sal_Bool bInEditMode = IsInEditMode();
188 
189             if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
190             {
191                 // Grenzenlose Papiergroesse fuer Laufschrift
192                 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
193                 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
194             }
195             aPaperMax.Width()=nMaxWdt;
196             aPaperMax.Height()=nMaxHgt;
197         } else {
198             aPaperMax=aMaxSiz;
199         }
200         aPaperMin.Width()=nMinWdt;
201         aPaperMin.Height()=nMinHgt;
202     }
203     else
204     {
205         // #106879#
206         // aPaperMin needs to be set to object's size if full width is activated
207         // for hor or ver writing respectively
208         if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
209             || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
210         {
211             aPaperMin = aAnkSiz;
212         }
213 
214         aPaperMax=aMaxSiz;
215     }
216 
217     if (pViewMin!=NULL) {
218         *pViewMin=aViewInit;
219 
220         long nXFree=aAnkSiz.Width()-aPaperMin.Width();
221         if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
222         else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
223         else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
224 
225         long nYFree=aAnkSiz.Height()-aPaperMin.Height();
226         if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
227         else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
228         else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
229     }
230 
231     // Die PaperSize soll in den meisten Faellen von selbst wachsen
232     // #89459#
233     if(IsVerticalWriting())
234         aPaperMin.Width() = 0;
235     else
236         aPaperMin.Height() = 0; // #33102#
237 
238     if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
239         aPaperMin.Width()=0;
240     }
241 
242     // #103516# For complete ver adjust support, set paper min height to 0, here.
243     if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
244     {
245         aPaperMin.Height() = 0;
246     }
247 
248     if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
249     if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
250     if (pViewInit!=NULL) *pViewInit=aViewInit;
251 }
252 
253 void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
254 {
255     if(rOutl.IsModified())
256     {
257         OutlinerParaObject* pNewText = NULL;
258 
259         if(HasTextImpl( &rOutl ) )
260         {
261             // Damit der grauen Feldhintergrund wieder verschwindet
262             rOutl.UpdateFields();
263 
264             sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( rOutl.GetParagraphCount() );
265             pNewText = rOutl.CreateParaObject( 0, nParaAnz );
266         }
267 
268         // need to end edit mode early since SetOutlinerParaObject already
269         // uses GetCurrentBoundRect() which needs to take the text into account
270         // to work correct
271         mbInEditMode = sal_False;
272         SetOutlinerParaObject(pNewText);
273     }
274 
275     pEdtOutl = NULL;
276     rOutl.Clear();
277     sal_uInt32 nStat = rOutl.GetControlWord();
278     nStat &= ~EE_CNTRL_AUTOPAGESIZE;
279     rOutl.SetControlWord(nStat);
280 
281     // #101684#
282     mbInEditMode = sal_False;
283 }
284 
285 sal_uInt16 SdrTextObj::GetOutlinerViewAnchorMode() const
286 {
287     SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
288     SdrTextVertAdjust eV=GetTextVerticalAdjust();
289     EVAnchorMode eRet=ANCHOR_TOP_LEFT;
290     if (IsContourTextFrame()) return (sal_uInt16)eRet;
291     if (eH==SDRTEXTHORZADJUST_LEFT) {
292         if (eV==SDRTEXTVERTADJUST_TOP) {
293             eRet=ANCHOR_TOP_LEFT;
294         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
295             eRet=ANCHOR_BOTTOM_LEFT;
296         } else {
297             eRet=ANCHOR_VCENTER_LEFT;
298         }
299     } else if (eH==SDRTEXTHORZADJUST_RIGHT) {
300         if (eV==SDRTEXTVERTADJUST_TOP) {
301             eRet=ANCHOR_TOP_RIGHT;
302         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
303             eRet=ANCHOR_BOTTOM_RIGHT;
304         } else {
305             eRet=ANCHOR_VCENTER_RIGHT;
306         }
307     } else {
308         if (eV==SDRTEXTVERTADJUST_TOP) {
309             eRet=ANCHOR_TOP_HCENTER;
310         } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
311             eRet=ANCHOR_BOTTOM_HCENTER;
312         } else {
313             eRet=ANCHOR_VCENTER_HCENTER;
314         }
315     }
316     return (sal_uInt16)eRet;
317 }
318 
319 void SdrTextObj::ImpSetTextEditParams() const
320 {
321     if (pEdtOutl!=NULL) {
322         FASTBOOL bUpdMerk=pEdtOutl->GetUpdateMode();
323         if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_False);
324         Size aPaperMin;
325         Size aPaperMax;
326         Rectangle aEditArea;
327         TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
328         FASTBOOL bContourFrame=IsContourTextFrame();
329         pEdtOutl->SetMinAutoPaperSize(aPaperMin);
330         pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
331         pEdtOutl->SetPaperSize(Size());
332         if (bContourFrame) {
333             Rectangle aAnchorRect;
334             TakeTextAnchorRect(aAnchorRect);
335             ImpSetContourPolygon(*pEdtOutl,aAnchorRect, sal_True);
336         }
337         if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_True);
338     }
339 }
340 
341