1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/string.hxx>
21 #include <svl/style.hxx>
22 #include <svx/svdotext.hxx>
23 #include <svx/svdmodel.hxx> // for GetMaxObjSize and GetStyleSheetPool
24 #include <svx/svdoutl.hxx>
25 #include <svx/svdorect.hxx> // for SetDirty at NbcAdjustTextFrameWidthAndHeight
26 #include <svx/svdocapt.hxx> // for SetDirty at NbcAdjustTextFrameWidthAndHeight
27 #include <svx/svdetc.hxx>
28 #include <editeng/writingmodeitem.hxx>
29 #include <editeng/editdata.hxx>
30 #include <editeng/editeng.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <editeng/flditem.hxx>
33 #include <svx/sdtfchim.hxx>
36 #include <editeng/editview.hxx>
37 #include <svl/smplhint.hxx>
38 #include <svl/whiter.hxx>
39 #include <editeng/outlobj.hxx>
40 #include <editeng/outliner.hxx>
41 #include <editeng/editobj.hxx>
42 #include <editeng/fhgtitem.hxx>
44 #include <editeng/charscaleitem.hxx>
45 #include <svl/itemiter.hxx>
46 #include <editeng/lrspitem.hxx>
47 #include <svl/itempool.hxx>
48 #include <editeng/numitem.hxx>
49 #include <editeng/postitem.hxx>
54 bool SdrTextObj::AdjustTextFrameWidthAndHeight(Rectangle
& rR
, bool bHgt
, bool bWdt
) const
56 if (bTextFrame
&& pModel
!=NULL
&& !rR
.IsEmpty())
58 bool bFitToSize(IsFitToSize());
59 bool bWdtGrow
=bWdt
&& IsAutoGrowWidth();
60 bool bHgtGrow
=bHgt
&& IsAutoGrowHeight();
61 SdrTextAniKind eAniKind
=GetTextAniKind();
62 SdrTextAniDirection eAniDir
=GetTextAniDirection();
63 bool bScroll
=eAniKind
==SDRTEXTANI_SCROLL
|| eAniKind
==SDRTEXTANI_ALTERNATE
|| eAniKind
==SDRTEXTANI_SLIDE
;
64 bool bHScroll
=bScroll
&& (eAniDir
==SDRTEXTANI_LEFT
|| eAniDir
==SDRTEXTANI_RIGHT
);
65 bool bVScroll
=bScroll
&& (eAniDir
==SDRTEXTANI_UP
|| eAniDir
==SDRTEXTANI_DOWN
);
66 if (!bFitToSize
&& (bWdtGrow
|| bHgtGrow
))
69 long nHgt
=0,nMinHgt
=0,nMaxHgt
=0;
70 long nWdt
=0,nMinWdt
=0,nMaxWdt
=0;
71 Size
aSiz(rR
.GetSize()); aSiz
.Width()--; aSiz
.Height()--;
72 Size
aMaxSiz(100000,100000);
73 Size
aTmpSiz(pModel
->GetMaxObjSize());
74 if (aTmpSiz
.Width()!=0) aMaxSiz
.Width()=aTmpSiz
.Width();
75 if (aTmpSiz
.Height()!=0) aMaxSiz
.Height()=aTmpSiz
.Height();
78 nMinWdt
=GetMinTextFrameWidth();
79 nMaxWdt
=GetMaxTextFrameWidth();
80 if (nMaxWdt
==0 || nMaxWdt
>aMaxSiz
.Width()) nMaxWdt
=aMaxSiz
.Width();
81 if (nMinWdt
<=0) nMinWdt
=1;
86 nMinHgt
=GetMinTextFrameHeight();
87 nMaxHgt
=GetMaxTextFrameHeight();
88 if (nMaxHgt
==0 || nMaxHgt
>aMaxSiz
.Height()) nMaxHgt
=aMaxSiz
.Height();
89 if (nMinHgt
<=0) nMinHgt
=1;
90 aSiz
.Height()=nMaxHgt
;
92 long nHDist
=GetTextLeftDistance()+GetTextRightDistance();
93 long nVDist
=GetTextUpperDistance()+GetTextLowerDistance();
95 aSiz
.Height()-=nVDist
;
96 if (aSiz
.Width()<2) aSiz
.Width()=2;
97 if (aSiz
.Height()<2) aSiz
.Height()=2;
99 sal_Bool bInEditMode
= IsInEditMode();
103 if (bHScroll
) aSiz
.Width()=0x0FFFFFFF; // don't break ticker text
104 if (bVScroll
) aSiz
.Height()=0x0FFFFFFF;
109 pEdtOutl
->SetMaxAutoPaperSize(aSiz
);
111 Size
aSiz2(pEdtOutl
->CalcTextSize());
112 nWdt
=aSiz2
.Width()+1; // a little tolerance
113 if (bHgtGrow
) nHgt
=aSiz2
.Height()+1; // a little tolerance
115 nHgt
=pEdtOutl
->GetTextHeight()+1; // a little tolerance
118 Outliner
& rOutliner
=ImpGetDrawOutliner();
119 rOutliner
.SetPaperSize(aSiz
);
120 rOutliner
.SetUpdateMode(sal_True
);
121 // TODO: add the optimization with bPortionInfoChecked etc. here
122 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
123 if ( pOutlinerParaObject
!= NULL
)
125 rOutliner
.SetText(*pOutlinerParaObject
);
126 rOutliner
.SetFixedCellHeight(((const SdrTextFixedCellHeightItem
&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
)).GetValue());
130 Size
aSiz2(rOutliner
.CalcTextSize());
131 nWdt
=aSiz2
.Width()+1; // a little tolerance
132 if (bHgtGrow
) nHgt
=aSiz2
.Height()+1; // a little tolerance
134 nHgt
=rOutliner
.GetTextHeight()+1; // a little tolerance
138 if (nWdt
<nMinWdt
) nWdt
=nMinWdt
;
139 if (nWdt
>nMaxWdt
) nWdt
=nMaxWdt
;
141 if (nWdt
<1) nWdt
=1; // nHDist may be negative
142 if (nHgt
<nMinHgt
) nHgt
=nMinHgt
;
143 if (nHgt
>nMaxHgt
) nHgt
=nMaxHgt
;
145 if (nHgt
<1) nHgt
=1; // nVDist may be negative
146 long nWdtGrow
=nWdt
-(rR
.Right()-rR
.Left());
147 long nHgtGrow
=nHgt
-(rR
.Bottom()-rR
.Top());
148 if (nWdtGrow
==0) bWdtGrow
=sal_False
;
149 if (nHgtGrow
==0) bHgtGrow
=sal_False
;
150 if (bWdtGrow
|| bHgtGrow
) {
152 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
153 if (eHAdj
==SDRTEXTHORZADJUST_LEFT
) rR
.Right()+=nWdtGrow
;
154 else if (eHAdj
==SDRTEXTHORZADJUST_RIGHT
) rR
.Left()-=nWdtGrow
;
156 long nWdtGrow2
=nWdtGrow
/2;
157 rR
.Left()-=nWdtGrow2
;
158 rR
.Right()=rR
.Left()+nWdt
;
162 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
163 if (eVAdj
==SDRTEXTVERTADJUST_TOP
) rR
.Bottom()+=nHgtGrow
;
164 else if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
) rR
.Top()-=nHgtGrow
;
166 long nHgtGrow2
=nHgtGrow
/2;
168 rR
.Bottom()=rR
.Top()+nHgt
;
171 if (aGeo
.nDrehWink
!=0) {
172 Point
aD1(rR
.TopLeft());
175 RotatePoint(aD2
,Point(),aGeo
.nSin
,aGeo
.nCos
);
177 rR
.Move(aD2
.X(),aD2
.Y());
186 bool SdrTextObj::NbcAdjustTextFrameWidthAndHeight(bool bHgt
, bool bWdt
)
188 bool bRet
=AdjustTextFrameWidthAndHeight(aRect
,bHgt
,bWdt
);
191 if (HAS_BASE(SdrRectObj
,this)) { // this is a hack
192 ((SdrRectObj
*)this)->SetXPolyDirty();
194 if (HAS_BASE(SdrCaptionObj
,this)) { // this is a hack
195 ((SdrCaptionObj
*)this)->ImpRecalcTail();
201 bool SdrTextObj::AdjustTextFrameWidthAndHeight(bool bHgt
, bool bWdt
)
203 Rectangle
aNeuRect(aRect
);
204 bool bRet
=AdjustTextFrameWidthAndHeight(aNeuRect
,bHgt
,bWdt
);
206 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
209 if (HAS_BASE(SdrRectObj
,this)) { // this is a hack
210 ((SdrRectObj
*)this)->SetXPolyDirty();
212 if (HAS_BASE(SdrCaptionObj
,this)) { // this is a hack
213 ((SdrCaptionObj
*)this)->ImpRecalcTail();
216 BroadcastObjectChange();
217 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
222 void SdrTextObj::ImpSetTextStyleSheetListeners()
224 SfxStyleSheetBasePool
* pStylePool
=pModel
!=NULL
? pModel
->GetStyleSheetPool() : NULL
;
225 if (pStylePool
!=NULL
)
227 std::vector
<XubString
*> aStyleNames
;
228 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
229 if (pOutlinerParaObject
!=NULL
)
231 // First, we collect all stylesheets contained in the ParaObject in
232 // the container aStyles. The Family is always appended to the name
233 // of the stylesheet.
234 const EditTextObject
& rTextObj
=pOutlinerParaObject
->GetTextObject();
235 XubString aStyleName
;
236 SfxStyleFamily eStyleFam
;
237 sal_Int32 nParaAnz
=rTextObj
.GetParagraphCount();
239 for(sal_Int32
nParaNum(0); nParaNum
< nParaAnz
; nParaNum
++)
241 rTextObj
.GetStyleSheet(nParaNum
, aStyleName
, eStyleFam
);
246 aFam
.append(static_cast<sal_Int32
>(eStyleFam
));
247 comphelper::string::padToLength(aFam
, 5, ' ');
249 aStyleName
+= sal_Unicode('|');
250 aStyleName
+= aFam
.makeStringAndClear();
252 sal_Bool
bFnd(sal_False
);
253 sal_uInt32
nNum(aStyleNames
.size());
255 while(!bFnd
&& nNum
> 0)
257 // we don't want duplicate stylesheets
259 bFnd
= aStyleName
.Equals(*aStyleNames
[nNum
]);
264 aStyleNames
.push_back(new XubString(aStyleName
));
270 // now convert the strings in the vector from names to StyleSheet*
271 std::set
<SfxStyleSheet
*> aStyleSheets
;
272 while (!aStyleNames
.empty()) {
273 XubString
* pName
=aStyleNames
.back();
274 aStyleNames
.pop_back();
276 String aFam
= pName
->Copy(0, pName
->Len() - 6);
279 aFam
= comphelper::string::stripEnd(aFam
, ' ');
281 sal_uInt16 nFam
= (sal_uInt16
)aFam
.ToInt32();
283 SfxStyleFamily eFam
=(SfxStyleFamily
)nFam
;
284 SfxStyleSheetBase
* pStyleBase
=pStylePool
->Find(*pName
,eFam
);
285 SfxStyleSheet
* pStyle
=PTR_CAST(SfxStyleSheet
,pStyleBase
);
287 if (pStyle
!=NULL
&& pStyle
!=GetStyleSheet()) {
288 aStyleSheets
.insert(pStyle
);
291 // now remove all superfluous stylesheets
292 sal_uIntPtr nNum
=GetBroadcasterCount();
295 SfxBroadcaster
* pBroadcast
=GetBroadcasterJOE((sal_uInt16
)nNum
);
296 SfxStyleSheet
* pStyle
=PTR_CAST(SfxStyleSheet
,pBroadcast
);
297 if (pStyle
!=NULL
&& pStyle
!=GetStyleSheet()) { // special case for stylesheet of the object
298 if (aStyleSheets
.find(pStyle
)==aStyleSheets
.end()) {
299 EndListening(*pStyle
);
303 // and finally, merge all stylesheets that are contained in aStyles with previous broadcasters
304 for(std::set
<SfxStyleSheet
*>::const_iterator it
= aStyleSheets
.begin(); it
!= aStyleSheets
.end(); ++it
) {
305 SfxStyleSheet
* pStyle
=*it
;
306 // let StartListening see for itself if there's already a listener registered
307 StartListening(*pStyle
,sal_True
);
312 /** iterates over the paragraphs of a given SdrObject and removes all
313 hard set character attributes with the which ids contained in the
316 void SdrTextObj::RemoveOutlinerCharacterAttribs( const std::vector
<sal_uInt16
>& rCharWhichIds
)
318 sal_Int32 nText
= getTextCount();
320 while( --nText
>= 0 )
322 SdrText
* pText
= getText( nText
);
323 OutlinerParaObject
* pOutlinerParaObject
= pText
? pText
->GetOutlinerParaObject() : 0;
325 if(pOutlinerParaObject
)
327 Outliner
* pOutliner
= 0;
329 if( pEdtOutl
|| (pText
== getActiveText()) )
330 pOutliner
= pEdtOutl
;
334 pOutliner
= &ImpGetDrawOutliner();
335 pOutliner
->SetText(*pOutlinerParaObject
);
338 ESelection
aSelAll( 0, 0, EE_PARA_ALL
, EE_TEXTPOS_ALL
);
339 std::vector
<sal_uInt16
>::const_iterator
aIter( rCharWhichIds
.begin() );
340 while( aIter
!= rCharWhichIds
.end() )
342 pOutliner
->RemoveAttribs( aSelAll
, false, (*aIter
++) );
345 if(!pEdtOutl
|| (pText
!= getActiveText()) )
347 const sal_Int32 nParaCount
= pOutliner
->GetParagraphCount();
348 OutlinerParaObject
* pTemp
= pOutliner
->CreateParaObject(0, nParaCount
);
350 NbcSetOutlinerParaObjectForText(pTemp
, pText
);
356 bool SdrTextObj::HasText() const
359 return HasEditText();
361 OutlinerParaObject
* pOPO
= GetOutlinerParaObject();
363 bool bHasText
= false;
366 const EditTextObject
& rETO
= pOPO
->GetTextObject();
367 sal_Int32 nParaCount
= rETO
.GetParagraphCount();
370 bHasText
= (nParaCount
> 1) || (rETO
.GetText( 0 ).Len() != 0);
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */