Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <comphelper/string.hxx>
30 : : #include <svl/style.hxx>
31 : : #include <svx/svdotext.hxx>
32 : : #include "svx/svditext.hxx"
33 : : #include <svx/svdmodel.hxx> // for GetMaxObjSize and GetStyleSheetPool
34 : : #include <svx/svdoutl.hxx>
35 : : #include <svx/svdorect.hxx> // for SetDirty at NbcAdjustTextFrameWidthAndHeight
36 : : #include <svx/svdocapt.hxx> // for SetDirty at NbcAdjustTextFrameWidthAndHeight
37 : : #include <svx/svdetc.hxx>
38 : : #include <editeng/writingmodeitem.hxx>
39 : : #include <editeng/editeng.hxx>
40 : : #include <editeng/eeitem.hxx>
41 : : #include <editeng/flditem.hxx>
42 : : #include <svx/sdtfchim.hxx>
43 : :
44 : :
45 : : #include <editeng/editview.hxx>
46 : : #include <svl/smplhint.hxx>
47 : : #include <svl/whiter.hxx>
48 : : #include <editeng/outlobj.hxx>
49 : : #include <editeng/outliner.hxx>
50 : : #include <editeng/editobj.hxx>
51 : : #include <editeng/fhgtitem.hxx>
52 : :
53 : : #include <editeng/charscaleitem.hxx>
54 : : #include <svl/itemiter.hxx>
55 : : #include <editeng/lrspitem.hxx>
56 : : #include <svl/itempool.hxx>
57 : : #include <editeng/numitem.hxx>
58 : : #include <editeng/postitem.hxx>
59 : :
60 : : #include <set>
61 : :
62 : :
63 : 160781 : bool SdrTextObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, bool bHgt, bool bWdt) const
64 : : {
65 [ + - ][ + + ]: 160781 : if (bTextFrame && pModel!=NULL && !rR.IsEmpty())
[ + + ][ + + ]
66 : : {
67 : 136983 : bool bFitToSize(IsFitToSize());
68 [ + + ][ + - ]: 136983 : bool bWdtGrow=bWdt && IsAutoGrowWidth();
69 [ + - ][ + + ]: 136983 : bool bHgtGrow=bHgt && IsAutoGrowHeight();
70 : 136983 : SdrTextAniKind eAniKind=GetTextAniKind();
71 : 136983 : SdrTextAniDirection eAniDir=GetTextAniDirection();
72 [ + - ][ - + ]: 136983 : bool bScroll=eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE;
[ + - ]
73 [ - + ][ # # ]: 136983 : bool bHScroll=bScroll && (eAniDir==SDRTEXTANI_LEFT || eAniDir==SDRTEXTANI_RIGHT);
[ # # ]
74 [ - + ][ # # ]: 136983 : bool bVScroll=bScroll && (eAniDir==SDRTEXTANI_UP || eAniDir==SDRTEXTANI_DOWN);
[ # # ]
75 [ + - ][ + + ]: 136983 : if (!bFitToSize && (bWdtGrow || bHgtGrow))
[ + + ]
76 : : {
77 : 129556 : Rectangle aR0(rR);
78 : 129556 : long nHgt=0,nMinHgt=0,nMaxHgt=0;
79 : 129556 : long nWdt=0,nMinWdt=0,nMaxWdt=0;
80 [ + - ]: 129556 : Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
81 : 129556 : Size aMaxSiz(100000,100000);
82 : 129556 : Size aTmpSiz(pModel->GetMaxObjSize());
83 [ + + ]: 129556 : if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
84 [ + + ]: 129556 : if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
85 [ + + ]: 129556 : if (bWdtGrow)
86 : : {
87 [ + - ]: 56339 : nMinWdt=GetMinTextFrameWidth();
88 [ + - ]: 56339 : nMaxWdt=GetMaxTextFrameWidth();
89 [ + + ][ - + ]: 56339 : if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
[ + + ]
90 [ + - ]: 56339 : if (nMinWdt<=0) nMinWdt=1;
91 : 56339 : aSiz.Width()=nMaxWdt;
92 : : }
93 [ + - ]: 129556 : if (bHgtGrow)
94 : : {
95 [ + - ]: 129556 : nMinHgt=GetMinTextFrameHeight();
96 [ + - ]: 129556 : nMaxHgt=GetMaxTextFrameHeight();
97 [ - + ][ # # ]: 129556 : if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
[ + - ]
98 [ + + ]: 129556 : if (nMinHgt<=0) nMinHgt=1;
99 : 129556 : aSiz.Height()=nMaxHgt;
100 : : }
101 [ + - ][ + - ]: 129556 : long nHDist=GetTextLeftDistance()+GetTextRightDistance();
102 [ + - ][ + - ]: 129556 : long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
103 : 129556 : aSiz.Width()-=nHDist;
104 : 129556 : aSiz.Height()-=nVDist;
105 [ + + ]: 129556 : if (aSiz.Width()<2) aSiz.Width()=2;
106 [ - + ]: 129556 : if (aSiz.Height()<2) aSiz.Height()=2;
107 : :
108 : 129556 : sal_Bool bInEditMode = IsInEditMode();
109 : :
110 [ + - ]: 129556 : if(!bInEditMode)
111 : : {
112 [ - + ]: 129556 : if (bHScroll) aSiz.Width()=0x0FFFFFFF; // don't break ticker text
113 [ - + ]: 129556 : if (bVScroll) aSiz.Height()=0x0FFFFFFF;
114 : : }
115 : :
116 [ - + ]: 129556 : if(pEdtOutl)
117 : : {
118 [ # # ]: 0 : pEdtOutl->SetMaxAutoPaperSize(aSiz);
119 [ # # ]: 0 : if (bWdtGrow) {
120 [ # # ]: 0 : Size aSiz2(pEdtOutl->CalcTextSize());
121 : 0 : nWdt=aSiz2.Width()+1; // a little tolerance
122 [ # # ]: 0 : if (bHgtGrow) nHgt=aSiz2.Height()+1; // a little tolerance
123 : : } else {
124 [ # # ]: 0 : nHgt=pEdtOutl->GetTextHeight()+1; // a little tolerance
125 : : }
126 : : } else {
127 [ + - ]: 129556 : Outliner& rOutliner=ImpGetDrawOutliner();
128 [ + - ]: 129556 : rOutliner.SetPaperSize(aSiz);
129 [ + - ]: 129556 : rOutliner.SetUpdateMode(sal_True);
130 : : // TODO: add the optimization with bPortionInfoChecked etc. here
131 [ + - ]: 129556 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
132 [ + + ]: 129556 : if ( pOutlinerParaObject != NULL )
133 : : {
134 [ + - ]: 83090 : rOutliner.SetText(*pOutlinerParaObject);
135 [ + - ][ + - ]: 83090 : rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
136 : : }
137 [ + + ]: 129556 : if (bWdtGrow)
138 : : {
139 [ + - ]: 56339 : Size aSiz2(rOutliner.CalcTextSize());
140 : 56339 : nWdt=aSiz2.Width()+1; // a little tolerance
141 [ + - ]: 56339 : if (bHgtGrow) nHgt=aSiz2.Height()+1; // a little tolerance
142 : : } else {
143 [ + - ]: 73217 : nHgt=rOutliner.GetTextHeight()+1; // a little tolerance
144 : : }
145 [ + - ]: 129556 : rOutliner.Clear();
146 : : }
147 [ - + ]: 129556 : if (nWdt<nMinWdt) nWdt=nMinWdt;
148 [ - + ]: 129556 : if (nWdt>nMaxWdt) nWdt=nMaxWdt;
149 : 129556 : nWdt+=nHDist;
150 [ + + ]: 129556 : if (nWdt<1) nWdt=1; // nHDist may be negative
151 [ + + ]: 129556 : if (nHgt<nMinHgt) nHgt=nMinHgt;
152 [ - + ]: 129556 : if (nHgt>nMaxHgt) nHgt=nMaxHgt;
153 : 129556 : nHgt+=nVDist;
154 [ - + ]: 129556 : if (nHgt<1) nHgt=1; // nVDist may be negative
155 : 129556 : long nWdtGrow=nWdt-(rR.Right()-rR.Left());
156 : 129556 : long nHgtGrow=nHgt-(rR.Bottom()-rR.Top());
157 [ + + ]: 129556 : if (nWdtGrow==0) bWdtGrow=sal_False;
158 [ + + ]: 129556 : if (nHgtGrow==0) bHgtGrow=sal_False;
159 [ + + ][ + + ]: 129556 : if (bWdtGrow || bHgtGrow) {
160 [ + + ]: 120436 : if (bWdtGrow) {
161 [ + - ]: 54507 : SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
162 [ + + ]: 54507 : if (eHAdj==SDRTEXTHORZADJUST_LEFT) rR.Right()+=nWdtGrow;
163 [ + + ]: 50857 : else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) rR.Left()-=nWdtGrow;
164 : : else {
165 : 30703 : long nWdtGrow2=nWdtGrow/2;
166 : 30703 : rR.Left()-=nWdtGrow2;
167 : 30703 : rR.Right()=rR.Left()+nWdt;
168 : : }
169 : : }
170 [ + + ]: 120436 : if (bHgtGrow) {
171 [ + - ]: 117064 : SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
172 [ + + ]: 117064 : if (eVAdj==SDRTEXTVERTADJUST_TOP) rR.Bottom()+=nHgtGrow;
173 [ + + ]: 30966 : else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) rR.Top()-=nHgtGrow;
174 : : else {
175 : 24817 : long nHgtGrow2=nHgtGrow/2;
176 : 24817 : rR.Top()-=nHgtGrow2;
177 : 24817 : rR.Bottom()=rR.Top()+nHgt;
178 : : }
179 : : }
180 [ - + ]: 120436 : if (aGeo.nDrehWink!=0) {
181 : 0 : Point aD1(rR.TopLeft());
182 : 0 : aD1-=aR0.TopLeft();
183 : 0 : Point aD2(aD1);
184 : 0 : RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
185 : 0 : aD2-=aD1;
186 [ # # ]: 0 : rR.Move(aD2.X(),aD2.Y());
187 : : }
188 : 129556 : return sal_True;
189 : : }
190 : : }
191 : : }
192 : 160781 : return sal_False;
193 : : }
194 : :
195 : 160789 : bool SdrTextObj::NbcAdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
196 : : {
197 : 160789 : bool bRet=AdjustTextFrameWidthAndHeight(aRect,bHgt,bWdt);
198 [ + + ]: 160789 : if (bRet) {
199 : 120442 : SetRectsDirty();
200 [ + + ][ + + ]: 120442 : if (HAS_BASE(SdrRectObj,this)) { // this is a hack
[ + - ]
201 : 120436 : ((SdrRectObj*)this)->SetXPolyDirty();
202 : : }
203 [ + - ][ + + ]: 120442 : if (HAS_BASE(SdrCaptionObj,this)) { // this is a hack
[ + + ]
204 : 66 : ((SdrCaptionObj*)this)->ImpRecalcTail();
205 : : }
206 : : }
207 : 160789 : return bRet;
208 : : }
209 : :
210 : 10 : bool SdrTextObj::AdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
211 : : {
212 : 10 : Rectangle aNeuRect(aRect);
213 [ + - ]: 10 : bool bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
214 [ - + ]: 10 : if (bRet) {
215 [ # # ][ # # ]: 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
[ # # ]
216 : 0 : aRect=aNeuRect;
217 [ # # ]: 0 : SetRectsDirty();
218 [ # # ][ # # ]: 0 : if (HAS_BASE(SdrRectObj,this)) { // this is a hack
[ # # ][ # # ]
[ # # ]
219 [ # # ]: 0 : ((SdrRectObj*)this)->SetXPolyDirty();
220 : : }
221 [ # # ][ # # ]: 0 : if (HAS_BASE(SdrCaptionObj,this)) { // this is a hack
[ # # ][ # # ]
[ # # ]
222 [ # # ]: 0 : ((SdrCaptionObj*)this)->ImpRecalcTail();
223 : : }
224 [ # # ]: 0 : SetChanged();
225 [ # # ]: 0 : BroadcastObjectChange();
226 [ # # ]: 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
227 : : }
228 : 10 : return bRet;
229 : : }
230 : :
231 : 54088 : void SdrTextObj::ImpSetTextStyleSheetListeners()
232 : : {
233 [ + - ]: 54088 : SfxStyleSheetBasePool* pStylePool=pModel!=NULL ? pModel->GetStyleSheetPool() : NULL;
234 [ + + ]: 54088 : if (pStylePool!=NULL)
235 : : {
236 [ + - ]: 5080 : std::vector<XubString*> aStyleNames;
237 [ + - ]: 5080 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
238 [ + + ]: 5080 : if (pOutlinerParaObject!=NULL)
239 : : {
240 : : // First, we collect all stylesheets contained in the ParaObject in
241 : : // the container aStyles. The Family is always appended to the name
242 : : // of the stylesheet.
243 [ + - ]: 4855 : const EditTextObject& rTextObj=pOutlinerParaObject->GetTextObject();
244 [ + - ]: 4855 : XubString aStyleName;
245 : : SfxStyleFamily eStyleFam;
246 [ + - ]: 4855 : sal_uInt16 nParaAnz=rTextObj.GetParagraphCount();
247 : :
248 [ + + ]: 13242 : for(sal_uInt16 nParaNum(0); nParaNum < nParaAnz; nParaNum++)
249 : : {
250 [ + - ]: 8387 : rTextObj.GetStyleSheet(nParaNum, aStyleName, eStyleFam);
251 : :
252 [ + - ]: 8387 : if(aStyleName.Len())
253 : : {
254 [ + - ]: 8387 : XubString aFam = UniString::CreateFromInt32((sal_uInt16)eStyleFam);
255 [ + - ]: 8387 : aFam.Expand(5);
256 : :
257 [ + - ]: 8387 : aStyleName += sal_Unicode('|');
258 [ + - ]: 8387 : aStyleName += aFam;
259 : :
260 : 8387 : sal_Bool bFnd(sal_False);
261 : 8387 : sal_uInt32 nNum(aStyleNames.size());
262 : :
263 [ + + ][ + + ]: 13089 : while(!bFnd && nNum > 0)
[ + + ]
264 : : {
265 : : // we don't want duplicate stylesheets
266 : 4702 : nNum--;
267 [ + - ][ + - ]: 4702 : bFnd = aStyleName.Equals(*aStyleNames[nNum]);
268 : : }
269 : :
270 [ + + ]: 8387 : if(!bFnd)
271 : : {
272 [ + - ][ + - ]: 5323 : aStyleNames.push_back(new XubString(aStyleName));
[ + - ]
273 [ + - ]: 8387 : }
274 : : }
275 [ + - ]: 4855 : }
276 : : }
277 : :
278 : : // now convert the strings in the vector from names to StyleSheet*
279 [ + - ]: 5080 : std::set<SfxStyleSheet*> aStyleSheets;
280 [ + + ]: 10403 : while (!aStyleNames.empty()) {
281 [ + - ]: 5323 : XubString* pName=aStyleNames.back();
282 [ + - ]: 5323 : aStyleNames.pop_back();
283 : :
284 [ + - ]: 5323 : String aFam = pName->Copy(0, pName->Len() - 6);
285 : :
286 [ + - ]: 5323 : aFam.Erase(0,1);
287 [ + - ][ + - ]: 5323 : aFam = comphelper::string::stripEnd(aFam, ' ');
[ + - ]
288 : :
289 [ + - ]: 5323 : sal_uInt16 nFam = (sal_uInt16)aFam.ToInt32();
290 : :
291 : 5323 : SfxStyleFamily eFam=(SfxStyleFamily)nFam;
292 [ + - ]: 5323 : SfxStyleSheetBase* pStyleBase=pStylePool->Find(*pName,eFam);
293 [ - + ][ # # ]: 5323 : SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pStyleBase);
[ # # ][ # # ]
294 [ + - ][ + - ]: 5323 : delete pName;
295 [ - + ][ # # ]: 5323 : if (pStyle!=NULL && pStyle!=GetStyleSheet()) {
[ # # ][ - + ]
296 [ # # ]: 0 : aStyleSheets.insert(pStyle);
297 : : }
298 [ + - ]: 5323 : }
299 : : // now remove all superfluous stylesheets
300 : 5080 : sal_uIntPtr nNum=GetBroadcasterCount();
301 [ + + ]: 5257 : while (nNum>0) {
302 : 177 : nNum--;
303 [ + - ]: 177 : SfxBroadcaster* pBroadcast=GetBroadcasterJOE((sal_uInt16)nNum);
304 [ + - ][ + - ]: 177 : SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pBroadcast);
[ + - ][ + - ]
[ + - ]
305 [ + - ][ + - ]: 177 : if (pStyle!=NULL && pStyle!=GetStyleSheet()) { // special case for stylesheet of the object
[ + + ][ + + ]
306 [ + - ][ + - ]: 120 : if (aStyleSheets.find(pStyle)==aStyleSheets.end()) {
[ + - ]
307 [ + - ]: 177 : EndListening(*pStyle);
308 : : }
309 : : }
310 : : }
311 : : // and finally, merge all stylesheets that are contained in aStyles with previous broadcasters
312 [ # # ][ + - ]: 5080 : for(std::set<SfxStyleSheet*>::const_iterator it = aStyleSheets.begin(); it != aStyleSheets.end(); ++it) {
[ - + ]
313 [ # # ]: 0 : SfxStyleSheet* pStyle=*it;
314 : : // let StartListening see for itself if there's already a listener registered
315 [ # # ]: 0 : StartListening(*pStyle,sal_True);
316 : 5080 : }
317 : : }
318 : 54088 : }
319 : :
320 : : /** iterates over the paragraphs of a given SdrObject and removes all
321 : : hard set character attributes with the which ids contained in the
322 : : given vector
323 : : */
324 : 0 : void SdrTextObj::RemoveOutlinerCharacterAttribs( const std::vector<sal_uInt16>& rCharWhichIds )
325 : : {
326 : 0 : sal_Int32 nText = getTextCount();
327 : :
328 [ # # ]: 0 : while( --nText >= 0 )
329 : : {
330 : 0 : SdrText* pText = getText( nText );
331 [ # # ]: 0 : OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
332 : :
333 [ # # ]: 0 : if(pOutlinerParaObject)
334 : : {
335 : 0 : Outliner* pOutliner = 0;
336 : :
337 [ # # ][ # # ]: 0 : if( pEdtOutl || (pText == getActiveText()) )
[ # # ][ # # ]
338 : 0 : pOutliner = pEdtOutl;
339 : :
340 [ # # ]: 0 : if(!pOutliner)
341 : : {
342 [ # # ]: 0 : pOutliner = &ImpGetDrawOutliner();
343 [ # # ]: 0 : pOutliner->SetText(*pOutlinerParaObject);
344 : : }
345 : :
346 : 0 : ESelection aSelAll( 0, 0, 0xffff, 0xffff );
347 : 0 : std::vector<sal_uInt16>::const_iterator aIter( rCharWhichIds.begin() );
348 [ # # ][ # # ]: 0 : while( aIter != rCharWhichIds.end() )
349 : : {
350 [ # # ][ # # ]: 0 : pOutliner->RemoveAttribs( aSelAll, false, (*aIter++) );
[ # # ]
351 : : }
352 : :
353 [ # # ][ # # ]: 0 : if(!pEdtOutl || (pText != getActiveText()) )
[ # # ][ # # ]
354 : : {
355 [ # # ]: 0 : const sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
356 [ # # ]: 0 : OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount);
357 [ # # ]: 0 : pOutliner->Clear();
358 [ # # ]: 0 : NbcSetOutlinerParaObjectForText(pTemp, pText);
359 : : }
360 : : }
361 : : }
362 : 0 : }
363 : :
364 : 20031 : bool SdrTextObj::HasText() const
365 : : {
366 [ - + ]: 20031 : if( pEdtOutl )
367 : 0 : return HasEditText();
368 : :
369 : 20031 : OutlinerParaObject* pOPO = GetOutlinerParaObject();
370 : :
371 : 20031 : bool bHasText = false;
372 [ + + ]: 20031 : if( pOPO )
373 : : {
374 : 11706 : const EditTextObject& rETO = pOPO->GetTextObject();
375 : 11706 : sal_uInt16 nParaCount = rETO.GetParagraphCount();
376 : :
377 [ + - ]: 11706 : if( nParaCount > 0 )
378 [ + + ][ + - ]: 11706 : bHasText = (nParaCount > 1) || (rETO.GetText( 0 ).Len() != 0);
[ + - ][ + + ]
[ # # ]
379 : : }
380 : :
381 : 20031 : return bHasText;
382 : : }
383 : :
384 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|