xref: /aoo41x/main/svx/source/svdraw/svdotxed.cxx (revision f6e50924)
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 	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 
143 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 			if (!IsAutoGrowWidth() ) { nMaxWdt=aAnkSiz.Width();  nMinWdt=nMaxWdt; }
184 			if (!IsAutoGrowHeight()) { nMaxHgt=aAnkSiz.Height(); nMinHgt=nMaxHgt; }
185 			SdrTextAniKind      eAniKind=GetTextAniKind();
186 			SdrTextAniDirection eAniDirection=GetTextAniDirection();
187 
188 			// #101684#
189 			sal_Bool bInEditMode = IsInEditMode();
190 
191 			if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
192 			{
193 				// Grenzenlose Papiergroesse fuer Laufschrift
194 				if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
195 				if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
196 			}
197 			aPaperMax.Width()=nMaxWdt;
198 			aPaperMax.Height()=nMaxHgt;
199 		} else {
200 			aPaperMax=aMaxSiz;
201 		}
202 		aPaperMin.Width()=nMinWdt;
203 		aPaperMin.Height()=nMinHgt;
204 	}
205 	else
206 	{
207 		// #106879#
208 		// aPaperMin needs to be set to object's size if full width is activated
209 		// for hor or ver writing respectively
210 		if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
211 			|| (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
212 		{
213 			aPaperMin = aAnkSiz;
214 		}
215 
216 		aPaperMax=aMaxSiz;
217 	}
218 
219 	if (pViewMin!=NULL) {
220 		*pViewMin=aViewInit;
221 
222 		long nXFree=aAnkSiz.Width()-aPaperMin.Width();
223 		if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
224 		else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
225 		else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
226 
227 		long nYFree=aAnkSiz.Height()-aPaperMin.Height();
228 		if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
229 		else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
230 		else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
231 	}
232 
233 	// Die PaperSize soll in den meisten Faellen von selbst wachsen
234 	// #89459#
235 	if(IsVerticalWriting())
236 		aPaperMin.Width() = 0;
237 	else
238 		aPaperMin.Height() = 0; // #33102#
239 
240 	if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
241 		aPaperMin.Width()=0;
242 	}
243 
244 	// #103516# For complete ver adjust support, set paper min height to 0, here.
245 	if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
246 	{
247 		aPaperMin.Height() = 0;
248 	}
249 
250 	if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
251 	if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
252 	if (pViewInit!=NULL) *pViewInit=aViewInit;
253 }
254 
255 void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
256 {
257 	if(rOutl.IsModified())
258 	{
259 		OutlinerParaObject* pNewText = NULL;
260 
261 		if(HasTextImpl( &rOutl ) )
262 		{
263 			// Damit der grauen Feldhintergrund wieder verschwindet
264 			rOutl.UpdateFields();
265 
266 			sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( rOutl.GetParagraphCount() );
267 			pNewText = rOutl.CreateParaObject( 0, nParaAnz );
268 		}
269 
270 		// need to end edit mode early since SetOutlinerParaObject already
271 		// uses GetCurrentBoundRect() which needs to take the text into account
272 		// to work correct
273 		mbInEditMode = sal_False;
274 		SetOutlinerParaObject(pNewText);
275 	}
276 
277 	pEdtOutl = NULL;
278 	rOutl.Clear();
279 	sal_uInt32 nStat = rOutl.GetControlWord();
280 	nStat &= ~EE_CNTRL_AUTOPAGESIZE;
281 	rOutl.SetControlWord(nStat);
282 
283 	// #101684#
284 	mbInEditMode = sal_False;
285 }
286 
287 sal_uInt16 SdrTextObj::GetOutlinerViewAnchorMode() const
288 {
289 	SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
290 	SdrTextVertAdjust eV=GetTextVerticalAdjust();
291 	EVAnchorMode eRet=ANCHOR_TOP_LEFT;
292 	if (IsContourTextFrame()) return (sal_uInt16)eRet;
293 	if (eH==SDRTEXTHORZADJUST_LEFT) {
294 		if (eV==SDRTEXTVERTADJUST_TOP) {
295 			eRet=ANCHOR_TOP_LEFT;
296 		} else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
297 			eRet=ANCHOR_BOTTOM_LEFT;
298 		} else {
299 			eRet=ANCHOR_VCENTER_LEFT;
300 		}
301 	} else if (eH==SDRTEXTHORZADJUST_RIGHT) {
302 		if (eV==SDRTEXTVERTADJUST_TOP) {
303 			eRet=ANCHOR_TOP_RIGHT;
304 		} else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
305 			eRet=ANCHOR_BOTTOM_RIGHT;
306 		} else {
307 			eRet=ANCHOR_VCENTER_RIGHT;
308 		}
309 	} else {
310 		if (eV==SDRTEXTVERTADJUST_TOP) {
311 			eRet=ANCHOR_TOP_HCENTER;
312 		} else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
313 			eRet=ANCHOR_BOTTOM_HCENTER;
314 		} else {
315 			eRet=ANCHOR_VCENTER_HCENTER;
316 		}
317 	}
318 	return (sal_uInt16)eRet;
319 }
320 
321 void SdrTextObj::ImpSetTextEditParams() const
322 {
323 	if (pEdtOutl!=NULL) {
324 		FASTBOOL bUpdMerk=pEdtOutl->GetUpdateMode();
325 		if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_False);
326 		Size aPaperMin;
327 		Size aPaperMax;
328 		Rectangle aEditArea;
329 		TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
330 		//SdrFitToSizeType eFit=GetFitToSize();
331 		//FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
332 		FASTBOOL bContourFrame=IsContourTextFrame();
333 		//EVAnchorMode eAM=(EVAnchorMode)GetOutlinerViewAnchorMode();
334 		//sal_uIntPtr nViewAnz=pEdtOutl->GetViewCount();
335 		pEdtOutl->SetMinAutoPaperSize(aPaperMin);
336 		pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
337 		pEdtOutl->SetPaperSize(Size());
338 		if (bContourFrame) {
339 			Rectangle aAnchorRect;
340 			TakeTextAnchorRect(aAnchorRect);
341 			ImpSetContourPolygon(*pEdtOutl,aAnchorRect, sal_True);
342 		}
343 		if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_True);
344 	}
345 }
346 
347