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 #include "precompiled_svx.hxx"
29 
30 #include <svx/sdr/attribute/sdrtextattribute.hxx>
31 #include <svx/sdr/attribute/sdrformtextattribute.hxx>
32 #include <svx/svdotext.hxx>
33 #include <editeng/outlobj.hxx>
34 #include <editeng/editobj.hxx>
35 #include <editeng/flditem.hxx>
36 #include <svx/sdr/properties/properties.hxx>
37 
38 //////////////////////////////////////////////////////////////////////////////
39 
40 namespace drawinglayer
41 {
42 	namespace attribute
43 	{
44 		class ImpSdrTextAttribute
45 		{
46 		public:
47 			// refcounter
48 			sal_uInt32							mnRefCount;
49 
50             // all-text attributes. The SdrText itself and a copy
51             // of te OPO
52 			const SdrText*						mpSdrText;
53 			const OutlinerParaObject*			mpOutlinerParaObject;
54 
55             // Set when it's a FormText; contains all FormText attributes
56             SdrFormTextAttribute                maSdrFormTextAttribute;
57 
58             // text distances
59 			sal_Int32							maTextLeftDistance;
60 			sal_Int32							maTextUpperDistance;
61 			sal_Int32							maTextRightDistance;
62 			sal_Int32							maTextLowerDistance;
63 
64             // #i101556# use versioning from text attributes to detect changes
65             sal_uInt32                          maPropertiesVersion;
66 
67             // text alignments
68             SdrTextHorzAdjust                   maSdrTextHorzAdjust;
69             SdrTextVertAdjust                   maSdrTextVertAdjust;
70 
71 			// bitfield
72 			unsigned							mbContour : 1;
73 			unsigned							mbFitToSize : 1;
74 			unsigned							mbHideContour : 1;
75 			unsigned							mbBlink : 1;
76 			unsigned							mbScroll : 1;
77 			unsigned							mbInEditMode : 1;
78 			unsigned							mbFixedCellHeight : 1;
79 			unsigned							mbWrongSpell : 1;
80 
81 		public:
82 			ImpSdrTextAttribute(
83 				const SdrText* pSdrText,
84                 const OutlinerParaObject& rOutlinerParaObject,
85 				XFormTextStyle eFormTextStyle,
86 				sal_Int32 aTextLeftDistance,
87 				sal_Int32 aTextUpperDistance,
88 				sal_Int32 aTextRightDistance,
89 				sal_Int32 aTextLowerDistance,
90                 SdrTextHorzAdjust aSdrTextHorzAdjust,
91                 SdrTextVertAdjust aSdrTextVertAdjust,
92 				bool bContour,
93                 bool bFitToSize,
94 				bool bHideContour,
95                 bool bBlink,
96 				bool bScroll,
97                 bool bInEditMode,
98                 bool bFixedCellHeight,
99 				bool bWrongSpell)
100 			:	mnRefCount(0),
101 				mpSdrText(pSdrText),
102 				mpOutlinerParaObject(new OutlinerParaObject(rOutlinerParaObject)),
103 				maSdrFormTextAttribute(),
104 				maTextLeftDistance(aTextLeftDistance),
105 				maTextUpperDistance(aTextUpperDistance),
106 				maTextRightDistance(aTextRightDistance),
107 				maTextLowerDistance(aTextLowerDistance),
108 				maPropertiesVersion(0),
109 				maSdrTextHorzAdjust(aSdrTextHorzAdjust),
110 				maSdrTextVertAdjust(aSdrTextVertAdjust),
111 				mbContour(bContour),
112 				mbFitToSize(bFitToSize),
113 				mbHideContour(bHideContour),
114 				mbBlink(bBlink),
115 				mbScroll(bScroll),
116 				mbInEditMode(bInEditMode),
117 				mbFixedCellHeight(bFixedCellHeight),
118 				mbWrongSpell(bWrongSpell)
119 			{
120 				if(pSdrText)
121 				{
122 					if(XFT_NONE != eFormTextStyle)
123 					{
124 						// text on path. Create FormText attribute
125         				const SfxItemSet& rSet = pSdrText->GetItemSet();
126 						maSdrFormTextAttribute = SdrFormTextAttribute(rSet);
127 					}
128 
129 					// #i101556# init with version number to detect changes of single text
130 					// attribute and/or style sheets in primitive data without having to
131 					// copy that data locally (which would be better from principle)
132 					maPropertiesVersion = pSdrText->GetObject().GetProperties().getVersion();
133 				}
134 			}
135 
136 			ImpSdrTextAttribute()
137 			:	mnRefCount(0),
138 				mpSdrText(0),
139 				mpOutlinerParaObject(0),
140 				maSdrFormTextAttribute(),
141 				maTextLeftDistance(0),
142 				maTextUpperDistance(0),
143 				maTextRightDistance(0),
144 				maTextLowerDistance(0),
145 				maPropertiesVersion(0),
146 				maSdrTextHorzAdjust(SDRTEXTHORZADJUST_LEFT),
147 				maSdrTextVertAdjust(SDRTEXTVERTADJUST_TOP),
148 				mbContour(false),
149 				mbFitToSize(false),
150 				mbHideContour(false),
151 				mbBlink(false),
152 				mbScroll(false),
153 				mbInEditMode(false),
154 				mbFixedCellHeight(false),
155 				mbWrongSpell(false)
156 			{
157 			}
158 
159 			~ImpSdrTextAttribute()
160 			{
161 				if(mpOutlinerParaObject)
162 				{
163 					delete mpOutlinerParaObject;
164 				}
165 			}
166 
167 			// data read access
168 			const SdrText& getSdrText() const
169 			{
170 				OSL_ENSURE(mpSdrText, "Access to text of default version of ImpSdrTextAttribute (!)");
171 				return *mpSdrText;
172 			}
173             const OutlinerParaObject& getOutlinerParaObject() const
174 			{
175 				OSL_ENSURE(mpOutlinerParaObject, "Access to OutlinerParaObject of default version of ImpSdrTextAttribute (!)");
176 				return *mpOutlinerParaObject;
177 			}
178 			bool isContour() const { return mbContour; }
179 			bool isFitToSize() const { return mbFitToSize; }
180 			bool isHideContour() const { return mbHideContour; }
181 			bool isBlink() const { return mbBlink; }
182 			bool isScroll() const { return mbScroll; }
183             bool isInEditMode() const { return mbInEditMode; }
184             bool isFixedCellHeight() const { return mbFixedCellHeight; }
185 			bool isWrongSpell() const { return mbWrongSpell; }
186             const SdrFormTextAttribute& getSdrFormTextAttribute() const { return maSdrFormTextAttribute; }
187 			sal_Int32 getTextLeftDistance() const { return maTextLeftDistance; }
188 			sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; }
189 			sal_Int32 getTextRightDistance() const { return maTextRightDistance; }
190 			sal_Int32 getTextLowerDistance() const { return maTextLowerDistance; }
191             sal_uInt32 getPropertiesVersion() const { return maPropertiesVersion; }
192             SdrTextHorzAdjust getSdrTextHorzAdjust() const { return maSdrTextHorzAdjust; }
193             SdrTextVertAdjust getSdrTextVertAdjust() const { return maSdrTextVertAdjust; }
194 
195 			// compare operator
196 			bool operator==(const ImpSdrTextAttribute& rCandidate) const
197 			{
198 				if(mpOutlinerParaObject != rCandidate.mpOutlinerParaObject)
199 				{
200 					if(mpOutlinerParaObject && rCandidate.mpOutlinerParaObject)
201 					{
202 						// compares OPO and it's contents, but traditionally not the RedLining
203 						// which is not seen as model, but as temporary information
204 						if(!(getOutlinerParaObject() == rCandidate.getOutlinerParaObject()))
205 						{
206 							return false;
207 						}
208 
209 						// #i102062# for primitive visualisation, the WrongList (SpellChecking)
210 						// is important, too, so use isWrongListEqual since there is no WrongList
211 						// comparison in the regular OutlinerParaObject compare (since it's
212 						// not-persistent data)
213 						if(!(getOutlinerParaObject().isWrongListEqual(rCandidate.getOutlinerParaObject())))
214 						{
215 							return false;
216 						}
217 					}
218 					else
219 					{
220 						// only one is zero; not equal
221 						return false;
222 					}
223 				}
224 
225 				return (
226 					   getSdrFormTextAttribute() == rCandidate.getSdrFormTextAttribute()
227 					&& getTextLeftDistance() == rCandidate.getTextLeftDistance()
228 					&& getTextUpperDistance() == rCandidate.getTextUpperDistance()
229 					&& getTextRightDistance() == rCandidate.getTextRightDistance()
230 					&& getTextLowerDistance() == rCandidate.getTextLowerDistance()
231 					&& getPropertiesVersion() == rCandidate.getPropertiesVersion()
232 
233 					&& getSdrTextHorzAdjust() == rCandidate.getSdrTextHorzAdjust()
234 					&& getSdrTextVertAdjust() == rCandidate.getSdrTextVertAdjust()
235 
236 					&& isContour() == rCandidate.isContour()
237 					&& isFitToSize() == rCandidate.isFitToSize()
238 					&& isHideContour() == rCandidate.isHideContour()
239 					&& isBlink() == rCandidate.isBlink()
240 					&& isScroll() == rCandidate.isScroll()
241 					&& isInEditMode() == rCandidate.isInEditMode()
242 					&& isFixedCellHeight() == rCandidate.isFixedCellHeight()
243 					&& isWrongSpell() == rCandidate.isWrongSpell());
244 			}
245 
246 			static ImpSdrTextAttribute* get_global_default()
247             {
248                 static ImpSdrTextAttribute* pDefault = 0;
249 
250                 if(!pDefault)
251                 {
252 					// use default constructor
253                     pDefault = new ImpSdrTextAttribute();
254 
255                     // never delete; start with RefCount 1, not 0
256     			    pDefault->mnRefCount++;
257                 }
258 
259                 return pDefault;
260             }
261 		};
262 
263         SdrTextAttribute::SdrTextAttribute(
264 			const SdrText& rSdrText,
265             const OutlinerParaObject& rOutlinerParaObject,
266 			XFormTextStyle eFormTextStyle,
267 			sal_Int32 aTextLeftDistance,
268 			sal_Int32 aTextUpperDistance,
269 			sal_Int32 aTextRightDistance,
270 			sal_Int32 aTextLowerDistance,
271             SdrTextHorzAdjust aSdrTextHorzAdjust,
272             SdrTextVertAdjust aSdrTextVertAdjust,
273 			bool bContour,
274             bool bFitToSize,
275 			bool bHideContour,
276             bool bBlink,
277 			bool bScroll,
278             bool bInEditMode,
279             bool bFixedCellHeight,
280 			bool bWrongSpell)
281 		:	mpSdrTextAttribute(new ImpSdrTextAttribute(
282 				&rSdrText, rOutlinerParaObject, eFormTextStyle, aTextLeftDistance, aTextUpperDistance,
283 				aTextRightDistance, aTextLowerDistance, aSdrTextHorzAdjust, aSdrTextVertAdjust, bContour,
284 				bFitToSize, bHideContour, bBlink, bScroll, bInEditMode, bFixedCellHeight, bWrongSpell))
285 		{
286 		}
287 
288 		SdrTextAttribute::SdrTextAttribute()
289         :	mpSdrTextAttribute(ImpSdrTextAttribute::get_global_default())
290 		{
291 			mpSdrTextAttribute->mnRefCount++;
292 		}
293 
294         SdrTextAttribute::SdrTextAttribute(const SdrTextAttribute& rCandidate)
295 		:	mpSdrTextAttribute(rCandidate.mpSdrTextAttribute)
296 		{
297 			mpSdrTextAttribute->mnRefCount++;
298 		}
299 
300 		SdrTextAttribute::~SdrTextAttribute()
301 		{
302 			if(mpSdrTextAttribute->mnRefCount)
303 			{
304 				mpSdrTextAttribute->mnRefCount--;
305 			}
306 			else
307 			{
308 				delete mpSdrTextAttribute;
309 			}
310 		}
311 
312         bool SdrTextAttribute::isDefault() const
313         {
314             return mpSdrTextAttribute == ImpSdrTextAttribute::get_global_default();
315         }
316 
317         SdrTextAttribute& SdrTextAttribute::operator=(const SdrTextAttribute& rCandidate)
318 		{
319 			if(rCandidate.mpSdrTextAttribute != mpSdrTextAttribute)
320 			{
321 				if(mpSdrTextAttribute->mnRefCount)
322 				{
323 					mpSdrTextAttribute->mnRefCount--;
324 				}
325 				else
326 				{
327 					delete mpSdrTextAttribute;
328 				}
329 
330 				mpSdrTextAttribute = rCandidate.mpSdrTextAttribute;
331 				mpSdrTextAttribute->mnRefCount++;
332 			}
333 
334 			return *this;
335 		}
336 
337 		bool SdrTextAttribute::operator==(const SdrTextAttribute& rCandidate) const
338 		{
339 			if(rCandidate.mpSdrTextAttribute == mpSdrTextAttribute)
340 			{
341 				return true;
342 			}
343 
344 			if(rCandidate.isDefault() != isDefault())
345 			{
346 				return false;
347 			}
348 
349 			return (*rCandidate.mpSdrTextAttribute == *mpSdrTextAttribute);
350 		}
351 
352 		const SdrText& SdrTextAttribute::getSdrText() const
353 		{
354 			return mpSdrTextAttribute->getSdrText();
355 		}
356 
357 		const OutlinerParaObject& SdrTextAttribute::getOutlinerParaObject() const
358 		{
359 			return mpSdrTextAttribute->getOutlinerParaObject();
360 		}
361 
362 		bool SdrTextAttribute::isContour() const
363 		{
364 			return mpSdrTextAttribute->isContour();
365 		}
366 
367 		bool SdrTextAttribute::isFitToSize() const
368 		{
369 			return mpSdrTextAttribute->isFitToSize();
370 		}
371 
372 		bool SdrTextAttribute::isHideContour() const
373 		{
374 			return mpSdrTextAttribute->isHideContour();
375 		}
376 
377 		bool SdrTextAttribute::isBlink() const
378 		{
379 			return mpSdrTextAttribute->isBlink();
380 		}
381 
382 		bool SdrTextAttribute::isScroll() const
383 		{
384 			return mpSdrTextAttribute->isScroll();
385 		}
386 
387 		bool SdrTextAttribute::isInEditMode() const
388 		{
389 			return mpSdrTextAttribute->isInEditMode();
390 		}
391 
392 		bool SdrTextAttribute::isFixedCellHeight() const
393 		{
394 			return mpSdrTextAttribute->isFixedCellHeight();
395 		}
396 
397 		bool SdrTextAttribute::isWrongSpell() const
398 		{
399 			return mpSdrTextAttribute->isWrongSpell();
400 		}
401 
402 		const SdrFormTextAttribute& SdrTextAttribute::getSdrFormTextAttribute() const
403 		{
404 			return mpSdrTextAttribute->getSdrFormTextAttribute();
405 		}
406 
407 		sal_Int32 SdrTextAttribute::getTextLeftDistance() const
408 		{
409 			return mpSdrTextAttribute->getTextLeftDistance();
410 		}
411 
412 		sal_Int32 SdrTextAttribute::getTextUpperDistance() const
413 		{
414 			return mpSdrTextAttribute->getTextUpperDistance();
415 		}
416 
417 		sal_Int32 SdrTextAttribute::getTextRightDistance() const
418 		{
419 			return mpSdrTextAttribute->getTextRightDistance();
420 		}
421 
422 		sal_Int32 SdrTextAttribute::getTextLowerDistance() const
423 		{
424 			return mpSdrTextAttribute->getTextLowerDistance();
425 		}
426 
427 		sal_uInt32 SdrTextAttribute::getPropertiesVersion() const
428 		{
429 			return mpSdrTextAttribute->getPropertiesVersion();
430 		}
431 
432 		SdrTextHorzAdjust SdrTextAttribute::getSdrTextHorzAdjust() const
433 		{
434 			return mpSdrTextAttribute->getSdrTextHorzAdjust();
435 		}
436 
437 		SdrTextVertAdjust SdrTextAttribute::getSdrTextVertAdjust() const
438 		{
439 			return mpSdrTextAttribute->getSdrTextVertAdjust();
440 		}
441 
442 		void SdrTextAttribute::getBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const
443 		{
444 			if(isBlink())
445 			{
446 				getSdrText().GetObject().impGetBlinkTextTiming(rAnimList);
447 			}
448 		}
449 
450 		void SdrTextAttribute::getScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const
451 		{
452 			if(isScroll())
453 			{
454 				getSdrText().GetObject().impGetScrollTextTiming(rAnimList, fFrameLength, fTextLength);
455 			}
456 		}
457 	} // end of namespace attribute
458 } // end of namespace drawinglayer
459 
460 //////////////////////////////////////////////////////////////////////////////
461 // eof
462