xref: /trunk/main/svx/source/svdraw/svdotxed.cxx (revision cdf0e10c)
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