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