merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdotxat.cxx
blobb5f48d72b3ee1bbc0b01b065f8aabe105c819acc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdotxat.cxx,v $
10 * $Revision: 1.32 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <svtools/style.hxx>
35 #include <svx/svdotext.hxx>
36 #include "svditext.hxx"
37 #include <svx/svdmodel.hxx> // fuer GetMaxObjSize und GetStyleSheetPool
38 #include <svx/svdoutl.hxx>
39 #include <svx/svdorect.hxx> // fuer SetDirty bei NbcAdjustTextFrameWidthAndHeight
40 #include <svx/svdocapt.hxx> // fuer SetDirty bei NbcAdjustTextFrameWidthAndHeight
41 #include <svx/svdetc.hxx>
42 #include <svx/writingmodeitem.hxx>
43 #include <svx/editeng.hxx>
44 #include <svx/eeitem.hxx>
45 #include <svx/flditem.hxx>
46 #include <svx/sdtfchim.hxx>
49 #include <svx/editview.hxx>
50 #include <svtools/smplhint.hxx>
51 #include <svtools/whiter.hxx>
52 #include <svx/outlobj.hxx>
53 #include <svx/outliner.hxx>
54 #include <svx/eeitem.hxx>
55 #include <svx/editobj.hxx>
56 #include <svx/fhgtitem.hxx>
58 #include <svx/charscaleitem.hxx>
59 #include <svtools/style.hxx>
60 #include <svtools/itemiter.hxx>
61 #include <svx/lrspitem.hxx>
62 #include <svtools/itempool.hxx>
63 #include <svx/numitem.hxx>
64 #include <svx/editeng.hxx>
65 #include <svx/postitem.hxx>
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
69 // @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
70 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
71 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
72 // @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
73 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
74 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
75 // @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
77 // Attribute, StyleSheets und AutoGrow
79 ////////////////////////////////////////////////////////////////////////////////////////////////////
81 FASTBOOL SdrTextObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const
83 if (bTextFrame && pModel!=NULL && !rR.IsEmpty())
85 FASTBOOL bFitToSize(IsFitToSize());
86 FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth();
87 FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight();
88 SdrTextAniKind eAniKind=GetTextAniKind();
89 SdrTextAniDirection eAniDir=GetTextAniDirection();
90 FASTBOOL bScroll=eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE;
91 FASTBOOL bHScroll=bScroll && (eAniDir==SDRTEXTANI_LEFT || eAniDir==SDRTEXTANI_RIGHT);
92 FASTBOOL bVScroll=bScroll && (eAniDir==SDRTEXTANI_UP || eAniDir==SDRTEXTANI_DOWN);
93 if (!bFitToSize && (bWdtGrow || bHgtGrow))
95 Rectangle aR0(rR);
96 long nHgt=0,nMinHgt=0,nMaxHgt=0;
97 long nWdt=0,nMinWdt=0,nMaxWdt=0;
98 Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
99 Size aMaxSiz(100000,100000);
100 Size aTmpSiz(pModel->GetMaxObjSize());
101 if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
102 if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
103 if (bWdtGrow)
105 nMinWdt=GetMinTextFrameWidth();
106 nMaxWdt=GetMaxTextFrameWidth();
107 if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
108 if (nMinWdt<=0) nMinWdt=1;
109 aSiz.Width()=nMaxWdt;
111 if (bHgtGrow)
113 nMinHgt=GetMinTextFrameHeight();
114 nMaxHgt=GetMaxTextFrameHeight();
115 if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
116 if (nMinHgt<=0) nMinHgt=1;
117 aSiz.Height()=nMaxHgt;
119 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
120 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
121 aSiz.Width()-=nHDist;
122 aSiz.Height()-=nVDist;
123 if (aSiz.Width()<2) aSiz.Width()=2; // Mindestgroesse 2
124 if (aSiz.Height()<2) aSiz.Height()=2; // Mindestgroesse 2
126 // #101684#
127 BOOL bInEditMode = IsInEditMode();
129 if(!bInEditMode)
131 if (bHScroll) aSiz.Width()=0x0FFFFFFF; // Laufschrift nicht umbrechen
132 if (bVScroll) aSiz.Height()=0x0FFFFFFF;
135 if(pEdtOutl)
137 pEdtOutl->SetMaxAutoPaperSize(aSiz);
138 if (bWdtGrow) {
139 Size aSiz2(pEdtOutl->CalcTextSize());
140 nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
141 if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
142 } else {
143 nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz
145 } else {
146 Outliner& rOutliner=ImpGetDrawOutliner();
147 rOutliner.SetPaperSize(aSiz);
148 rOutliner.SetUpdateMode(TRUE);
149 // !!! hier sollte ich wohl auch noch mal die Optimierung mit
150 // bPortionInfoChecked usw einbauen
151 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
152 if ( pOutlinerParaObject != NULL )
154 rOutliner.SetText(*pOutlinerParaObject);
155 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
157 if (bWdtGrow)
159 Size aSiz2(rOutliner.CalcTextSize());
160 nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
161 if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
162 } else {
163 nHgt=rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz
165 rOutliner.Clear();
167 if (nWdt<nMinWdt) nWdt=nMinWdt;
168 if (nWdt>nMaxWdt) nWdt=nMaxWdt;
169 nWdt+=nHDist;
170 if (nWdt<1) nWdt=1; // nHDist kann auch negativ sein
171 if (nHgt<nMinHgt) nHgt=nMinHgt;
172 if (nHgt>nMaxHgt) nHgt=nMaxHgt;
173 nHgt+=nVDist;
174 if (nHgt<1) nHgt=1; // nVDist kann auch negativ sein
175 long nWdtGrow=nWdt-(rR.Right()-rR.Left());
176 long nHgtGrow=nHgt-(rR.Bottom()-rR.Top());
177 if (nWdtGrow==0) bWdtGrow=FALSE;
178 if (nHgtGrow==0) bHgtGrow=FALSE;
179 if (bWdtGrow || bHgtGrow) {
180 if (bWdtGrow) {
181 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
182 if (eHAdj==SDRTEXTHORZADJUST_LEFT) rR.Right()+=nWdtGrow;
183 else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) rR.Left()-=nWdtGrow;
184 else {
185 long nWdtGrow2=nWdtGrow/2;
186 rR.Left()-=nWdtGrow2;
187 rR.Right()=rR.Left()+nWdt;
190 if (bHgtGrow) {
191 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
192 if (eVAdj==SDRTEXTVERTADJUST_TOP) rR.Bottom()+=nHgtGrow;
193 else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) rR.Top()-=nHgtGrow;
194 else {
195 long nHgtGrow2=nHgtGrow/2;
196 rR.Top()-=nHgtGrow2;
197 rR.Bottom()=rR.Top()+nHgt;
200 if (aGeo.nDrehWink!=0) {
201 Point aD1(rR.TopLeft());
202 aD1-=aR0.TopLeft();
203 Point aD2(aD1);
204 RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
205 aD2-=aD1;
206 rR.Move(aD2.X(),aD2.Y());
208 return TRUE;
212 return FALSE;
215 FASTBOOL SdrTextObj::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
217 FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aRect,bHgt,bWdt);
218 if (bRet) {
219 SetRectsDirty();
220 if (HAS_BASE(SdrRectObj,this)) { // mal wieder 'nen Hack
221 ((SdrRectObj*)this)->SetXPolyDirty();
223 if (HAS_BASE(SdrCaptionObj,this)) { // mal wieder 'nen Hack
224 ((SdrCaptionObj*)this)->ImpRecalcTail();
227 return bRet;
230 FASTBOOL SdrTextObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
232 Rectangle aNeuRect(aRect);
233 FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
234 if (bRet) {
235 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
236 // #110094#-14 SendRepaintBroadcast();
237 aRect=aNeuRect;
238 SetRectsDirty();
239 if (HAS_BASE(SdrRectObj,this)) { // mal wieder 'nen Hack
240 ((SdrRectObj*)this)->SetXPolyDirty();
242 if (HAS_BASE(SdrCaptionObj,this)) { // mal wieder 'nen Hack
243 ((SdrCaptionObj*)this)->ImpRecalcTail();
245 SetChanged();
246 BroadcastObjectChange();
247 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
249 return bRet;
252 void SdrTextObj::ImpSetTextStyleSheetListeners()
254 SfxStyleSheetBasePool* pStylePool=pModel!=NULL ? pModel->GetStyleSheetPool() : NULL;
255 if (pStylePool!=NULL)
257 Container aStyles(1024,64,64);
258 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
259 if (pOutlinerParaObject!=NULL)
261 // Zunaechst werden alle im ParaObject enthaltenen StyleSheets
262 // im Container aStyles gesammelt. Dazu wird die Family jeweils
263 // ans Ende des StyleSheet-Namen drangehaengt.
264 const EditTextObject& rTextObj=pOutlinerParaObject->GetTextObject();
265 XubString aStyleName;
266 SfxStyleFamily eStyleFam;
267 USHORT nParaAnz=rTextObj.GetParagraphCount();
269 for(UINT16 nParaNum(0); nParaNum < nParaAnz; nParaNum++)
271 rTextObj.GetStyleSheet(nParaNum, aStyleName, eStyleFam);
273 if(aStyleName.Len())
275 XubString aFam = UniString::CreateFromInt32((UINT16)eStyleFam);
276 aFam.Expand(5);
278 aStyleName += sal_Unicode('|');
279 aStyleName += aFam;
281 BOOL bFnd(FALSE);
282 UINT32 nNum(aStyles.Count());
284 while(!bFnd && nNum > 0)
286 // kein StyleSheet doppelt!
287 nNum--;
288 bFnd = (aStyleName.Equals(*(XubString*)aStyles.GetObject(nNum)));
291 if(!bFnd)
293 aStyles.Insert(new XubString(aStyleName), CONTAINER_APPEND);
299 // nun die Strings im Container durch StyleSheet* ersetzten
300 ULONG nNum=aStyles.Count();
301 while (nNum>0) {
302 nNum--;
303 XubString* pName=(XubString*)aStyles.GetObject(nNum);
305 // UNICODE: String aFam(pName->Cut(pName->Len()-6));
306 String aFam = pName->Copy(0, pName->Len() - 6);
308 aFam.Erase(0,1);
309 aFam.EraseTrailingChars();
311 // UNICODE: USHORT nFam=USHORT(aFam);
312 UINT16 nFam = (UINT16)aFam.ToInt32();
314 SfxStyleFamily eFam=(SfxStyleFamily)nFam;
315 SfxStyleSheetBase* pStyleBase=pStylePool->Find(*pName,eFam);
316 SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pStyleBase);
317 delete pName;
318 if (pStyle!=NULL && pStyle!=GetStyleSheet()) {
319 aStyles.Replace(pStyle,nNum);
320 } else {
321 aStyles.Remove(nNum);
324 // jetzt alle ueberfluessigen StyleSheets entfernen
325 nNum=GetBroadcasterCount();
326 while (nNum>0) {
327 nNum--;
328 SfxBroadcaster* pBroadcast=GetBroadcasterJOE((USHORT)nNum);
329 SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pBroadcast);
330 if (pStyle!=NULL && pStyle!=GetStyleSheet()) { // Sonderbehandlung fuer den StyleSheet des Objekts
331 if (aStyles.GetPos(pStyle)==CONTAINER_ENTRY_NOTFOUND) {
332 EndListening(*pStyle);
336 // und schliesslich alle in aStyles enthaltenen StyleSheets mit den vorhandenen Broadcastern mergen
337 nNum=aStyles.Count();
338 while (nNum>0) {
339 nNum--;
340 SfxStyleSheet* pStyle=(SfxStyleSheet*)aStyles.GetObject(nNum);
341 // StartListening soll selbst nachsehen, ob hier nicht evtl. schon gehorcht wird
342 StartListening(*pStyle,TRUE);
347 void SdrTextObj::NbcResizeTextAttributes(const Fraction& xFact, const Fraction& yFact)
349 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
350 if (pOutlinerParaObject!=NULL && xFact.IsValid() && yFact.IsValid())
352 Fraction n100(100,1);
353 long nX=long(xFact*n100);
354 long nY=long(yFact*n100);
355 if (nX<0) nX=-nX;
356 if (nX<1) nX=1;
357 if (nX>0xFFFF) nX=0xFFFF;
358 if (nY<0) nY=-nY;
359 if (nY<1) nY=1;
360 if (nY>0xFFFF) nY=0xFFFF;
361 if (nX!=100 || nY!=100)
363 // Rahmenattribute
364 const SfxItemSet& rSet = GetObjectItemSet();
365 const SvxCharScaleWidthItem& rOldWdt=(SvxCharScaleWidthItem&)rSet.Get(EE_CHAR_FONTWIDTH);
366 const SvxFontHeightItem& rOldHgt=(SvxFontHeightItem&)rSet.Get(EE_CHAR_FONTHEIGHT);
368 // erstmal die alten Werte holen
369 long nRelWdt=rOldWdt.GetValue();
370 long nAbsHgt=rOldHgt.GetHeight();
371 long nRelHgt=rOldHgt.GetProp();
373 // Relative Breite aendern
374 nRelWdt*=nX;
375 nRelWdt/=nY;
376 if (nRelWdt<0) nRelWdt=-nRelWdt; // nicht negativ
377 if (nRelWdt<=0) nRelWdt=1; // und mind. 1%
378 if (nRelWdt>0xFFFF) nRelWdt=0xFFFF;
380 // Absolute Hoehe aendern
381 nAbsHgt*=nY;
382 nAbsHgt/=100;
383 if (nAbsHgt<0) nAbsHgt=-nAbsHgt; // nicht negativ
384 if (nAbsHgt<=0) nAbsHgt=1; // und mind. 1
385 if (nAbsHgt>0xFFFF) nAbsHgt=0xFFFF;
387 // und nun attributieren
388 SetObjectItem(SvxCharScaleWidthItem( (USHORT) nRelWdt, EE_CHAR_FONTWIDTH));
389 SetObjectItem(SvxFontHeightItem(nAbsHgt,(USHORT)nRelHgt, EE_CHAR_FONTHEIGHT));
390 // Zeichen- und Absatzattribute innerhalb des OutlinerParaObjects
391 Outliner& rOutliner=ImpGetDrawOutliner();
392 rOutliner.SetPaperSize(Size(LONG_MAX,LONG_MAX));
393 rOutliner.SetText(*pOutlinerParaObject);
394 rOutliner.DoStretchChars((USHORT)nX,(USHORT)nY);
395 OutlinerParaObject* pNewPara=rOutliner.CreateParaObject();
396 NbcSetOutlinerParaObject(pNewPara);
397 rOutliner.Clear();
402 /** #103836# iterates over the paragraphs of a given SdrObject and removes all
403 hard set character attributes with the which ids contained in the
404 given vector
406 void SdrTextObj::RemoveOutlinerCharacterAttribs( const std::vector<sal_uInt16>& rCharWhichIds )
408 sal_Int32 nText = getTextCount();
410 while( --nText >= 0 )
412 SdrText* pText = getText( nText );
413 OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
415 if(pOutlinerParaObject)
417 Outliner* pOutliner = 0;
419 if( pEdtOutl || (pText == getActiveText()) )
420 pOutliner = pEdtOutl;
422 if(!pOutliner)
424 pOutliner = &ImpGetDrawOutliner();
425 pOutliner->SetText(*pOutlinerParaObject);
428 ESelection aSelAll( 0, 0, 0xffff, 0xffff );
429 std::vector<sal_uInt16>::const_iterator aIter( rCharWhichIds.begin() );
430 while( aIter != rCharWhichIds.end() )
432 pOutliner->RemoveAttribs( aSelAll, false, (*aIter++) );
435 if(!pEdtOutl || (pText != getActiveText()) )
437 const sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
438 OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount);
439 pOutliner->Clear();
440 NbcSetOutlinerParaObjectForText(pTemp, pText);
446 bool SdrTextObj::HasText() const
448 if( pEdtOutl )
449 return HasEditText();
451 OutlinerParaObject* pOPO = GetOutlinerParaObject();
453 bool bHasText = false;
454 if( pOPO )
456 const EditTextObject& rETO = pOPO->GetTextObject();
457 USHORT nParaCount = rETO.GetParagraphCount();
459 if( nParaCount > 0 )
460 bHasText = (nParaCount > 1) || (rETO.GetText( 0 ).Len() != 0);
463 return bHasText;