1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdotxat.cxx,v $
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
))
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();
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
;
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
127 BOOL bInEditMode
= IsInEditMode();
131 if (bHScroll
) aSiz
.Width()=0x0FFFFFFF; // Laufschrift nicht umbrechen
132 if (bVScroll
) aSiz
.Height()=0x0FFFFFFF;
137 pEdtOutl
->SetMaxAutoPaperSize(aSiz
);
139 Size
aSiz2(pEdtOutl
->CalcTextSize());
140 nWdt
=aSiz2
.Width()+1; // lieber etwas Tolleranz
141 if (bHgtGrow
) nHgt
=aSiz2
.Height()+1; // lieber etwas Tolleranz
143 nHgt
=pEdtOutl
->GetTextHeight()+1; // lieber etwas Tolleranz
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());
159 Size
aSiz2(rOutliner
.CalcTextSize());
160 nWdt
=aSiz2
.Width()+1; // lieber etwas Tolleranz
161 if (bHgtGrow
) nHgt
=aSiz2
.Height()+1; // lieber etwas Tolleranz
163 nHgt
=rOutliner
.GetTextHeight()+1; // lieber etwas Tolleranz
167 if (nWdt
<nMinWdt
) nWdt
=nMinWdt
;
168 if (nWdt
>nMaxWdt
) nWdt
=nMaxWdt
;
170 if (nWdt
<1) nWdt
=1; // nHDist kann auch negativ sein
171 if (nHgt
<nMinHgt
) nHgt
=nMinHgt
;
172 if (nHgt
>nMaxHgt
) nHgt
=nMaxHgt
;
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
) {
181 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
182 if (eHAdj
==SDRTEXTHORZADJUST_LEFT
) rR
.Right()+=nWdtGrow
;
183 else if (eHAdj
==SDRTEXTHORZADJUST_RIGHT
) rR
.Left()-=nWdtGrow
;
185 long nWdtGrow2
=nWdtGrow
/2;
186 rR
.Left()-=nWdtGrow2
;
187 rR
.Right()=rR
.Left()+nWdt
;
191 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
192 if (eVAdj
==SDRTEXTVERTADJUST_TOP
) rR
.Bottom()+=nHgtGrow
;
193 else if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
) rR
.Top()-=nHgtGrow
;
195 long nHgtGrow2
=nHgtGrow
/2;
197 rR
.Bottom()=rR
.Top()+nHgt
;
200 if (aGeo
.nDrehWink
!=0) {
201 Point
aD1(rR
.TopLeft());
204 RotatePoint(aD2
,Point(),aGeo
.nSin
,aGeo
.nCos
);
206 rR
.Move(aD2
.X(),aD2
.Y());
215 FASTBOOL
SdrTextObj::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt
, FASTBOOL bWdt
)
217 FASTBOOL bRet
=AdjustTextFrameWidthAndHeight(aRect
,bHgt
,bWdt
);
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();
230 FASTBOOL
SdrTextObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt
, FASTBOOL bWdt
)
232 Rectangle
aNeuRect(aRect
);
233 FASTBOOL bRet
=AdjustTextFrameWidthAndHeight(aNeuRect
,bHgt
,bWdt
);
235 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
236 // #110094#-14 SendRepaintBroadcast();
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();
246 BroadcastObjectChange();
247 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
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
);
275 XubString aFam
= UniString::CreateFromInt32((UINT16
)eStyleFam
);
278 aStyleName
+= sal_Unicode('|');
282 UINT32
nNum(aStyles
.Count());
284 while(!bFnd
&& nNum
> 0)
286 // kein StyleSheet doppelt!
288 bFnd
= (aStyleName
.Equals(*(XubString
*)aStyles
.GetObject(nNum
)));
293 aStyles
.Insert(new XubString(aStyleName
), CONTAINER_APPEND
);
299 // nun die Strings im Container durch StyleSheet* ersetzten
300 ULONG nNum
=aStyles
.Count();
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);
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
);
318 if (pStyle
!=NULL
&& pStyle
!=GetStyleSheet()) {
319 aStyles
.Replace(pStyle
,nNum
);
321 aStyles
.Remove(nNum
);
324 // jetzt alle ueberfluessigen StyleSheets entfernen
325 nNum
=GetBroadcasterCount();
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();
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
);
357 if (nX
>0xFFFF) nX
=0xFFFF;
360 if (nY
>0xFFFF) nY
=0xFFFF;
361 if (nX
!=100 || nY
!=100)
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
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
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
);
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
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
;
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
);
440 NbcSetOutlinerParaObjectForText(pTemp
, pText
);
446 bool SdrTextObj::HasText() const
449 return HasEditText();
451 OutlinerParaObject
* pOPO
= GetOutlinerParaObject();
453 bool bHasText
= false;
456 const EditTextObject
& rETO
= pOPO
->GetTextObject();
457 USHORT nParaCount
= rETO
.GetParagraphCount();
460 bHasText
= (nParaCount
> 1) || (rETO
.GetText( 0 ).Len() != 0);