1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir #include <svx/sdr/properties/attributeproperties.hxx>
31*cdf0e10cSrcweir #include <svx/sdr/properties/itemsettools.hxx>
32*cdf0e10cSrcweir #include <tools/debug.hxx>
33*cdf0e10cSrcweir #include <svl/itemset.hxx>
34*cdf0e10cSrcweir #include <svl/style.hxx>
35*cdf0e10cSrcweir #include <svl/whiter.hxx>
36*cdf0e10cSrcweir #include <svl/poolitem.hxx>
37*cdf0e10cSrcweir #include <svx/svdobj.hxx>
38*cdf0e10cSrcweir #include <svx/svddef.hxx>
39*cdf0e10cSrcweir #include <svx/xit.hxx>
40*cdf0e10cSrcweir #include <svx/xbtmpit.hxx>
41*cdf0e10cSrcweir #include <svx/xlndsit.hxx>
42*cdf0e10cSrcweir #include <svx/xlnstit.hxx>
43*cdf0e10cSrcweir #include <svx/xlnedit.hxx>
44*cdf0e10cSrcweir #include <svx/xflgrit.hxx>
45*cdf0e10cSrcweir #include <svx/xflftrit.hxx>
46*cdf0e10cSrcweir #include <svx/xflhtit.hxx>
47*cdf0e10cSrcweir #include <svx/xlnasit.hxx>
48*cdf0e10cSrcweir #include <svx/xflasit.hxx>
49*cdf0e10cSrcweir #include <svx/svdmodel.hxx>
50*cdf0e10cSrcweir #include <svx/svdtrans.hxx>
51*cdf0e10cSrcweir #include <svx/svdpage.hxx>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir // #114265#
54*cdf0e10cSrcweir #include <svl/smplhint.hxx>
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir namespace sdr
59*cdf0e10cSrcweir {
60*cdf0e10cSrcweir 	namespace properties
61*cdf0e10cSrcweir 	{
62*cdf0e10cSrcweir 		void AttributeProperties::ImpAddStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
63*cdf0e10cSrcweir 		{
64*cdf0e10cSrcweir 			// test if old StyleSheet is cleared, else it would be lost
65*cdf0e10cSrcweir 			// after this method -> memory leak (!)
66*cdf0e10cSrcweir 			DBG_ASSERT(!mpStyleSheet, "Old style sheet not deleted before setting new one (!)");
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 			if(pNewStyleSheet)
69*cdf0e10cSrcweir 			{
70*cdf0e10cSrcweir 				mpStyleSheet = pNewStyleSheet;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 				// local ItemSet is needed here, force it
73*cdf0e10cSrcweir 				GetObjectItemSet();
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 				// register as listener
76*cdf0e10cSrcweir 				StartListening(pNewStyleSheet->GetPool());
77*cdf0e10cSrcweir 				StartListening(*pNewStyleSheet);
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir 				// Delete hard attributes where items are set in the style sheet
80*cdf0e10cSrcweir 				if(!bDontRemoveHardAttr)
81*cdf0e10cSrcweir 				{
82*cdf0e10cSrcweir 					const SfxItemSet& rStyle = pNewStyleSheet->GetItemSet();
83*cdf0e10cSrcweir 					SfxWhichIter aIter(rStyle);
84*cdf0e10cSrcweir 					sal_uInt16 nWhich = aIter.FirstWhich();
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 					while(nWhich)
87*cdf0e10cSrcweir 					{
88*cdf0e10cSrcweir 						if(SFX_ITEM_SET == rStyle.GetItemState(nWhich))
89*cdf0e10cSrcweir 						{
90*cdf0e10cSrcweir 							mpItemSet->ClearItem(nWhich);
91*cdf0e10cSrcweir 						}
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 						nWhich = aIter.NextWhich();
94*cdf0e10cSrcweir 					}
95*cdf0e10cSrcweir 				}
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 				// set new stylesheet as parent
98*cdf0e10cSrcweir 				mpItemSet->SetParent(&pNewStyleSheet->GetItemSet());
99*cdf0e10cSrcweir 			}
100*cdf0e10cSrcweir 		}
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir 		void AttributeProperties::ImpRemoveStyleSheet()
103*cdf0e10cSrcweir 		{
104*cdf0e10cSrcweir 			// Check type since it is destroyed when the type is deleted
105*cdf0e10cSrcweir 			if(GetStyleSheet() && HAS_BASE(SfxStyleSheet, mpStyleSheet))
106*cdf0e10cSrcweir 			{
107*cdf0e10cSrcweir 				EndListening(*mpStyleSheet);
108*cdf0e10cSrcweir 				EndListening(mpStyleSheet->GetPool());
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 				// reset parent of ItemSet
111*cdf0e10cSrcweir 				if(mpItemSet)
112*cdf0e10cSrcweir 				{
113*cdf0e10cSrcweir 					mpItemSet->SetParent(0L);
114*cdf0e10cSrcweir 				}
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 				SdrObject& rObj = GetSdrObject();
117*cdf0e10cSrcweir 				rObj.SetBoundRectDirty();
118*cdf0e10cSrcweir 				rObj.SetRectsDirty(sal_True);
119*cdf0e10cSrcweir 			}
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 			mpStyleSheet = 0L;
122*cdf0e10cSrcweir 		}
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 		// create a new itemset
125*cdf0e10cSrcweir 		SfxItemSet& AttributeProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
126*cdf0e10cSrcweir 		{
127*cdf0e10cSrcweir 			return *(new SfxItemSet(rPool,
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 				// ranges from SdrAttrObj
130*cdf0e10cSrcweir 				SDRATTR_START, SDRATTR_SHADOW_LAST,
131*cdf0e10cSrcweir 				SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
132*cdf0e10cSrcweir 				SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 				// end
135*cdf0e10cSrcweir 				0, 0));
136*cdf0e10cSrcweir 		}
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 		AttributeProperties::AttributeProperties(SdrObject& rObj)
139*cdf0e10cSrcweir 		:	DefaultProperties(rObj),
140*cdf0e10cSrcweir 			mpStyleSheet(0L)
141*cdf0e10cSrcweir 		{
142*cdf0e10cSrcweir 		}
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 		AttributeProperties::AttributeProperties(const AttributeProperties& rProps, SdrObject& rObj)
145*cdf0e10cSrcweir 		:	DefaultProperties(rProps, rObj),
146*cdf0e10cSrcweir 			mpStyleSheet(0L)
147*cdf0e10cSrcweir 		{
148*cdf0e10cSrcweir 			if(rProps.GetStyleSheet())
149*cdf0e10cSrcweir 			{
150*cdf0e10cSrcweir 				ImpAddStyleSheet(rProps.GetStyleSheet(), sal_True);
151*cdf0e10cSrcweir 			}
152*cdf0e10cSrcweir 		}
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir 		AttributeProperties::~AttributeProperties()
155*cdf0e10cSrcweir 		{
156*cdf0e10cSrcweir 			ImpRemoveStyleSheet();
157*cdf0e10cSrcweir 		}
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 		BaseProperties& AttributeProperties::Clone(SdrObject& rObj) const
160*cdf0e10cSrcweir 		{
161*cdf0e10cSrcweir 			return *(new AttributeProperties(*this, rObj));
162*cdf0e10cSrcweir 		}
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 		void AttributeProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
165*cdf0e10cSrcweir 		{
166*cdf0e10cSrcweir 			// own modifications
167*cdf0e10cSrcweir 			SdrObject& rObj = GetSdrObject();
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir 			rObj.SetBoundRectDirty();
170*cdf0e10cSrcweir 			rObj.SetRectsDirty(sal_True);
171*cdf0e10cSrcweir 			rObj.SetChanged();
172*cdf0e10cSrcweir 		}
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 		void AttributeProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
175*cdf0e10cSrcweir 		{
176*cdf0e10cSrcweir 			if(pNewItem)
177*cdf0e10cSrcweir 			{
178*cdf0e10cSrcweir 				const SfxPoolItem* pItem = pNewItem;
179*cdf0e10cSrcweir 				SdrModel* pModel = GetSdrObject().GetModel();
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 				switch( nWhich )
182*cdf0e10cSrcweir 				{
183*cdf0e10cSrcweir 					case XATTR_FILLBITMAP:
184*cdf0e10cSrcweir 					{
185*cdf0e10cSrcweir 						pItem = ((XFillBitmapItem*)pItem)->checkForUniqueItem( pModel );
186*cdf0e10cSrcweir 						break;
187*cdf0e10cSrcweir 					}
188*cdf0e10cSrcweir 					case XATTR_LINEDASH:
189*cdf0e10cSrcweir 					{
190*cdf0e10cSrcweir 						pItem = ((XLineDashItem*)pItem)->checkForUniqueItem( pModel );
191*cdf0e10cSrcweir 						break;
192*cdf0e10cSrcweir 					}
193*cdf0e10cSrcweir 					case XATTR_LINESTART:
194*cdf0e10cSrcweir 					{
195*cdf0e10cSrcweir 						pItem = ((XLineStartItem*)pItem)->checkForUniqueItem( pModel );
196*cdf0e10cSrcweir 						break;
197*cdf0e10cSrcweir 					}
198*cdf0e10cSrcweir 					case XATTR_LINEEND:
199*cdf0e10cSrcweir 					{
200*cdf0e10cSrcweir 						pItem = ((XLineEndItem*)pItem)->checkForUniqueItem( pModel );
201*cdf0e10cSrcweir 						break;
202*cdf0e10cSrcweir 					}
203*cdf0e10cSrcweir 					case XATTR_FILLGRADIENT:
204*cdf0e10cSrcweir 					{
205*cdf0e10cSrcweir 						pItem = ((XFillGradientItem*)pItem)->checkForUniqueItem( pModel );
206*cdf0e10cSrcweir 						break;
207*cdf0e10cSrcweir 					}
208*cdf0e10cSrcweir 					case XATTR_FILLFLOATTRANSPARENCE:
209*cdf0e10cSrcweir 					{
210*cdf0e10cSrcweir 						// #85953# allow all kinds of XFillFloatTransparenceItem to be set
211*cdf0e10cSrcweir 						pItem = ((XFillFloatTransparenceItem*)pItem)->checkForUniqueItem( pModel );
212*cdf0e10cSrcweir 						break;
213*cdf0e10cSrcweir 					}
214*cdf0e10cSrcweir 					case XATTR_FILLHATCH:
215*cdf0e10cSrcweir 					{
216*cdf0e10cSrcweir 						pItem = ((XFillHatchItem*)pItem)->checkForUniqueItem( pModel );
217*cdf0e10cSrcweir 						break;
218*cdf0e10cSrcweir 					}
219*cdf0e10cSrcweir 				}
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 				// set item
222*cdf0e10cSrcweir 				if(pItem)
223*cdf0e10cSrcweir 				{
224*cdf0e10cSrcweir 					// force ItemSet
225*cdf0e10cSrcweir 					GetObjectItemSet();
226*cdf0e10cSrcweir 					mpItemSet->Put(*pItem);
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 					// delete item if it was a generated one
229*cdf0e10cSrcweir 					if(pItem != pNewItem)
230*cdf0e10cSrcweir 					{
231*cdf0e10cSrcweir 						delete (SfxPoolItem*)pItem;
232*cdf0e10cSrcweir 					}
233*cdf0e10cSrcweir 				}
234*cdf0e10cSrcweir 			}
235*cdf0e10cSrcweir 			else
236*cdf0e10cSrcweir 			{
237*cdf0e10cSrcweir 				// clear item if ItemSet exists
238*cdf0e10cSrcweir 				if(mpItemSet)
239*cdf0e10cSrcweir 				{
240*cdf0e10cSrcweir 					mpItemSet->ClearItem(nWhich);
241*cdf0e10cSrcweir 				}
242*cdf0e10cSrcweir 			}
243*cdf0e10cSrcweir 		}
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 		void AttributeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
246*cdf0e10cSrcweir 		{
247*cdf0e10cSrcweir 			ImpRemoveStyleSheet();
248*cdf0e10cSrcweir 			ImpAddStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 			SdrObject& rObj = GetSdrObject();
251*cdf0e10cSrcweir 			rObj.SetBoundRectDirty();
252*cdf0e10cSrcweir 			rObj.SetRectsDirty(sal_True);
253*cdf0e10cSrcweir 		}
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 		SfxStyleSheet* AttributeProperties::GetStyleSheet() const
256*cdf0e10cSrcweir 		{
257*cdf0e10cSrcweir 			return mpStyleSheet;
258*cdf0e10cSrcweir 		}
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 		void AttributeProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
261*cdf0e10cSrcweir 		{
262*cdf0e10cSrcweir             OSL_ASSERT(pNewModel!=NULL);
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 			if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
265*cdf0e10cSrcweir 			{
266*cdf0e10cSrcweir 				if(mpItemSet)
267*cdf0e10cSrcweir 				{
268*cdf0e10cSrcweir 					// migrate ItemSet to new pool. Scaling is NOT necessary
269*cdf0e10cSrcweir 					// because this functionality is used by UNDO only. Thus
270*cdf0e10cSrcweir 					// objects and ItemSets would be moved back to their original
271*cdf0e10cSrcweir 					// pool before usage.
272*cdf0e10cSrcweir 					SfxItemSet* pOldSet = mpItemSet;
273*cdf0e10cSrcweir 					SfxStyleSheet* pStySheet = GetStyleSheet();
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 					if(pStySheet)
276*cdf0e10cSrcweir 					{
277*cdf0e10cSrcweir 						ImpRemoveStyleSheet();
278*cdf0e10cSrcweir 					}
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir 					mpItemSet = mpItemSet->Clone(sal_False, pDestPool);
281*cdf0e10cSrcweir 					GetSdrObject().GetModel()->MigrateItemSet(pOldSet, mpItemSet, pNewModel);
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 					// set stylesheet (if used)
284*cdf0e10cSrcweir 					if(pStySheet)
285*cdf0e10cSrcweir 					{
286*cdf0e10cSrcweir                         // #i109515#
287*cdf0e10cSrcweir                         SfxItemPool* pStyleSheetPool = &pStySheet->GetPool().GetPool();
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir                         if(pStyleSheetPool == pDestPool)
290*cdf0e10cSrcweir                         {
291*cdf0e10cSrcweir                             // just re-set stylesheet
292*cdf0e10cSrcweir     						ImpAddStyleSheet(pStySheet, sal_True);
293*cdf0e10cSrcweir                         }
294*cdf0e10cSrcweir                         else
295*cdf0e10cSrcweir                         {
296*cdf0e10cSrcweir                             // StyleSheet is NOT from the correct pool.
297*cdf0e10cSrcweir                             // Look one up in the right pool with the same
298*cdf0e10cSrcweir                             // name or use the default.
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir                             // Look up the style in the new document.
301*cdf0e10cSrcweir                             OSL_ASSERT(pNewModel->GetStyleSheetPool() != NULL);
302*cdf0e10cSrcweir                             SfxStyleSheet* pNewStyleSheet = dynamic_cast<SfxStyleSheet*>(
303*cdf0e10cSrcweir                                 pNewModel->GetStyleSheetPool()->Find(
304*cdf0e10cSrcweir                                     pStySheet->GetName(),
305*cdf0e10cSrcweir                                     SFX_STYLE_FAMILY_ALL));
306*cdf0e10cSrcweir                             if (pNewStyleSheet == NULL
307*cdf0e10cSrcweir                                 || &pNewStyleSheet->GetPool().GetPool() != pDestPool)
308*cdf0e10cSrcweir                             {
309*cdf0e10cSrcweir                                 // There is no copy of the style in the new
310*cdf0e10cSrcweir                                 // document.  Use the default as a fallback.
311*cdf0e10cSrcweir                                 pNewStyleSheet = pNewModel->GetDefaultStyleSheet();
312*cdf0e10cSrcweir                             }
313*cdf0e10cSrcweir     						ImpAddStyleSheet(pNewStyleSheet, sal_True);
314*cdf0e10cSrcweir                         }
315*cdf0e10cSrcweir 					}
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 					delete pOldSet;
318*cdf0e10cSrcweir 				}
319*cdf0e10cSrcweir 			}
320*cdf0e10cSrcweir 		}
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir 		void AttributeProperties::SetModel(SdrModel* pOldModel, SdrModel* pNewModel)
323*cdf0e10cSrcweir 		{
324*cdf0e10cSrcweir 			if(pOldModel != pNewModel && pNewModel && !pNewModel->IsLoading())
325*cdf0e10cSrcweir 			{
326*cdf0e10cSrcweir 				// For a living model move the items from one pool to the other
327*cdf0e10cSrcweir 				if(pOldModel)
328*cdf0e10cSrcweir 				{
329*cdf0e10cSrcweir 					// If metric has changed, scale items.
330*cdf0e10cSrcweir 					MapUnit aOldUnit(pOldModel->GetScaleUnit());
331*cdf0e10cSrcweir 					MapUnit aNewUnit(pNewModel->GetScaleUnit());
332*cdf0e10cSrcweir 					sal_Bool bScaleUnitChanged(aNewUnit != aOldUnit);
333*cdf0e10cSrcweir 					Fraction aMetricFactor;
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 					if(bScaleUnitChanged)
336*cdf0e10cSrcweir 					{
337*cdf0e10cSrcweir 						aMetricFactor = GetMapFactor(aOldUnit, aNewUnit).X();
338*cdf0e10cSrcweir 						Scale(aMetricFactor);
339*cdf0e10cSrcweir 					}
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 					// Move all styles which are used by the object to the new
342*cdf0e10cSrcweir 					// StyleSheet pool
343*cdf0e10cSrcweir 					SfxStyleSheet* pOldStyleSheet = GetStyleSheet();
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir 					if(pOldStyleSheet)
346*cdf0e10cSrcweir 					{
347*cdf0e10cSrcweir 						SfxStyleSheetBase* pSheet = pOldStyleSheet;
348*cdf0e10cSrcweir 						SfxStyleSheetBasePool* pOldPool = pOldModel->GetStyleSheetPool();
349*cdf0e10cSrcweir 						SfxStyleSheetBasePool* pNewPool = pNewModel->GetStyleSheetPool();
350*cdf0e10cSrcweir 						DBG_ASSERT(pOldPool, "Properties::SetModel(): Object has StyleSheet but no StyleSheetPool (!)");
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir 						if(pOldPool && pNewPool)
353*cdf0e10cSrcweir 						{
354*cdf0e10cSrcweir 							// build a list of to-be-copied Styles
355*cdf0e10cSrcweir 							List aList;
356*cdf0e10cSrcweir 							SfxStyleSheetBase* pAnchor = 0L;
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir 							while(pSheet)
359*cdf0e10cSrcweir 							{
360*cdf0e10cSrcweir 								pAnchor = pNewPool->Find(pSheet->GetName(), pSheet->GetFamily());
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir 								if(!pAnchor)
363*cdf0e10cSrcweir 								{
364*cdf0e10cSrcweir 									aList.Insert(pSheet, LIST_APPEND);
365*cdf0e10cSrcweir 									pSheet = pOldPool->Find(pSheet->GetParent(), pSheet->GetFamily());
366*cdf0e10cSrcweir 								}
367*cdf0e10cSrcweir 								else
368*cdf0e10cSrcweir 								{
369*cdf0e10cSrcweir 									// the style does exist
370*cdf0e10cSrcweir 									pSheet = 0L;
371*cdf0e10cSrcweir 								}
372*cdf0e10cSrcweir 							}
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 							// copy and set the parents
375*cdf0e10cSrcweir 							pSheet = (SfxStyleSheetBase*)aList.First();
376*cdf0e10cSrcweir 							SfxStyleSheetBase* pNewSheet = 0L;
377*cdf0e10cSrcweir 							SfxStyleSheetBase* pLastSheet = 0L;
378*cdf0e10cSrcweir 							SfxStyleSheetBase* pForThisObject = 0L;
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir 							while(pSheet)
381*cdf0e10cSrcweir 							{
382*cdf0e10cSrcweir 								pNewSheet = &pNewPool->Make(pSheet->GetName(), pSheet->GetFamily(), pSheet->GetMask());
383*cdf0e10cSrcweir 								pNewSheet->GetItemSet().Put(pSheet->GetItemSet(), sal_False);
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir 								if(bScaleUnitChanged)
386*cdf0e10cSrcweir 								{
387*cdf0e10cSrcweir 									sdr::properties::ScaleItemSet(pNewSheet->GetItemSet(), aMetricFactor);
388*cdf0e10cSrcweir 								}
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 								if(pLastSheet)
391*cdf0e10cSrcweir 								{
392*cdf0e10cSrcweir 									pLastSheet->SetParent(pNewSheet->GetName());
393*cdf0e10cSrcweir 								}
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir 								if(!pForThisObject)
396*cdf0e10cSrcweir 								{
397*cdf0e10cSrcweir 									pForThisObject = pNewSheet;
398*cdf0e10cSrcweir 								}
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir 								pLastSheet = pNewSheet;
401*cdf0e10cSrcweir 								pSheet = (SfxStyleSheetBase*)aList.Next();
402*cdf0e10cSrcweir 							}
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 							// Set link to the Style found in the Pool
405*cdf0e10cSrcweir 							if(pAnchor && pLastSheet)
406*cdf0e10cSrcweir 							{
407*cdf0e10cSrcweir 								pLastSheet->SetParent(pAnchor->GetName());
408*cdf0e10cSrcweir 							}
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 							// if list was empty (all Styles exist in destination pool)
411*cdf0e10cSrcweir 							// pForThisObject is not yet set
412*cdf0e10cSrcweir 							if(!pForThisObject && pAnchor)
413*cdf0e10cSrcweir 							{
414*cdf0e10cSrcweir 								pForThisObject = pAnchor;
415*cdf0e10cSrcweir 							}
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 							// De-register at old and register at new Style
418*cdf0e10cSrcweir 							if(GetStyleSheet() != pForThisObject)
419*cdf0e10cSrcweir 							{
420*cdf0e10cSrcweir 								ImpRemoveStyleSheet();
421*cdf0e10cSrcweir 								ImpAddStyleSheet((SfxStyleSheet*)pForThisObject, sal_True);
422*cdf0e10cSrcweir 							}
423*cdf0e10cSrcweir 						}
424*cdf0e10cSrcweir 						else
425*cdf0e10cSrcweir 						{
426*cdf0e10cSrcweir 							// there is no StyleSheetPool in the new model, thus set
427*cdf0e10cSrcweir 							// all items as hard items in the object
428*cdf0e10cSrcweir 							List aList;
429*cdf0e10cSrcweir 							const SfxItemSet* pItemSet = &pOldStyleSheet->GetItemSet();
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 							while(pItemSet)
432*cdf0e10cSrcweir 							{
433*cdf0e10cSrcweir 								aList.Insert((void*)pItemSet, CONTAINER_APPEND);
434*cdf0e10cSrcweir 								pItemSet = pItemSet->GetParent();
435*cdf0e10cSrcweir 							}
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir 							SfxItemSet* pNewSet = &CreateObjectSpecificItemSet(pNewModel->GetItemPool());
438*cdf0e10cSrcweir 							pItemSet = (SfxItemSet*)aList.Last();
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 							while(pItemSet)
441*cdf0e10cSrcweir 							{
442*cdf0e10cSrcweir 								pNewSet->Put(*pItemSet);
443*cdf0e10cSrcweir 								pItemSet = (SfxItemSet*)aList.Prev();
444*cdf0e10cSrcweir 							}
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 							// Items which were hard attributes before need to stay
447*cdf0e10cSrcweir 							if(mpItemSet)
448*cdf0e10cSrcweir 							{
449*cdf0e10cSrcweir 								SfxWhichIter aIter(*mpItemSet);
450*cdf0e10cSrcweir 								sal_uInt16 nWhich = aIter.FirstWhich();
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir 								while(nWhich)
453*cdf0e10cSrcweir 								{
454*cdf0e10cSrcweir 									if(mpItemSet->GetItemState(nWhich, sal_False) == SFX_ITEM_SET)
455*cdf0e10cSrcweir 									{
456*cdf0e10cSrcweir 										pNewSet->Put(mpItemSet->Get(nWhich));
457*cdf0e10cSrcweir 									}
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir 									nWhich = aIter.NextWhich();
460*cdf0e10cSrcweir 								}
461*cdf0e10cSrcweir 							}
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir 							if(bScaleUnitChanged)
464*cdf0e10cSrcweir 							{
465*cdf0e10cSrcweir 								ScaleItemSet(*pNewSet, aMetricFactor);
466*cdf0e10cSrcweir 							}
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir 							if(mpItemSet)
469*cdf0e10cSrcweir 							{
470*cdf0e10cSrcweir 								if(GetStyleSheet())
471*cdf0e10cSrcweir 								{
472*cdf0e10cSrcweir 									ImpRemoveStyleSheet();
473*cdf0e10cSrcweir 								}
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir 								delete mpItemSet;
476*cdf0e10cSrcweir 								mpItemSet = 0L;
477*cdf0e10cSrcweir 							}
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir 							mpItemSet = pNewSet;
480*cdf0e10cSrcweir 						}
481*cdf0e10cSrcweir 					}
482*cdf0e10cSrcweir 				}
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir 				// each object gets the default Style if there is none set yet.
485*cdf0e10cSrcweir 				if(mpItemSet && !GetStyleSheet() && pNewModel && !pNewModel->IsLoading())
486*cdf0e10cSrcweir 				{
487*cdf0e10cSrcweir 					SetStyleSheet(pNewModel->GetDefaultStyleSheet(), sal_True);
488*cdf0e10cSrcweir 				}
489*cdf0e10cSrcweir 			}
490*cdf0e10cSrcweir 		}
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir 		void AttributeProperties::ForceStyleToHardAttributes()
493*cdf0e10cSrcweir 		{
494*cdf0e10cSrcweir 			if(GetStyleSheet() && HAS_BASE(SfxStyleSheet, mpStyleSheet))
495*cdf0e10cSrcweir 			{
496*cdf0e10cSrcweir 				// prepare copied, new itemset, but WITHOUT parent
497*cdf0e10cSrcweir 				GetObjectItemSet();
498*cdf0e10cSrcweir 				SfxItemSet* pDestItemSet = new SfxItemSet(*mpItemSet);
499*cdf0e10cSrcweir 				pDestItemSet->SetParent(0L);
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir 				// pepare forgetting the current stylesheet like in RemoveStyleSheet()
502*cdf0e10cSrcweir 				EndListening(*mpStyleSheet);
503*cdf0e10cSrcweir 				EndListening(mpStyleSheet->GetPool());
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir 				// prepare the iter; use the mpObjectItemSet which may have less
506*cdf0e10cSrcweir 				// WhichIDs than the style.
507*cdf0e10cSrcweir 				SfxWhichIter aIter(*pDestItemSet);
508*cdf0e10cSrcweir 				sal_uInt16 nWhich(aIter.FirstWhich());
509*cdf0e10cSrcweir 				const SfxPoolItem *pItem = NULL;
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir 				// now set all hard attributes of the current at the new itemset
512*cdf0e10cSrcweir 				while(nWhich)
513*cdf0e10cSrcweir 				{
514*cdf0e10cSrcweir 					// #i61284# use mpItemSet with parents, makes things easier and reduces to
515*cdf0e10cSrcweir 					// one loop
516*cdf0e10cSrcweir 					if(SFX_ITEM_SET == mpItemSet->GetItemState(nWhich, true, &pItem))
517*cdf0e10cSrcweir 					{
518*cdf0e10cSrcweir 						pDestItemSet->Put(*pItem);
519*cdf0e10cSrcweir 					}
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir 					nWhich = aIter.NextWhich();
522*cdf0e10cSrcweir 				}
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir 				// replace itemsets
525*cdf0e10cSrcweir 				delete mpItemSet;
526*cdf0e10cSrcweir 				mpItemSet = pDestItemSet;
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir 				// set necessary changes like in RemoveStyleSheet()
529*cdf0e10cSrcweir 				GetSdrObject().SetBoundRectDirty();
530*cdf0e10cSrcweir 				GetSdrObject().SetRectsDirty(sal_True);
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 				mpStyleSheet = NULL;
533*cdf0e10cSrcweir 			}
534*cdf0e10cSrcweir 		}
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir 		void AttributeProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
537*cdf0e10cSrcweir 		{
538*cdf0e10cSrcweir 			sal_Bool bHintUsed(sal_False);
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir 			SfxStyleSheetHint *pStyleHint = PTR_CAST(SfxStyleSheetHint, &rHint);
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir 			if(pStyleHint && pStyleHint->GetStyleSheet() == GetStyleSheet())
543*cdf0e10cSrcweir 			{
544*cdf0e10cSrcweir 				SdrObject& rObj = GetSdrObject();
545*cdf0e10cSrcweir 				//SdrPage* pPage = rObj.GetPage();
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir 				switch(pStyleHint->GetHint())
548*cdf0e10cSrcweir 				{
549*cdf0e10cSrcweir 					case SFX_STYLESHEET_CREATED			:
550*cdf0e10cSrcweir 					{
551*cdf0e10cSrcweir 						// cannot happen, nothing to do
552*cdf0e10cSrcweir 						break;
553*cdf0e10cSrcweir 					}
554*cdf0e10cSrcweir 					case SFX_STYLESHEET_MODIFIED		:
555*cdf0e10cSrcweir 					case SFX_STYLESHEET_CHANGED			:
556*cdf0e10cSrcweir 					{
557*cdf0e10cSrcweir 						// notify change
558*cdf0e10cSrcweir 						break;
559*cdf0e10cSrcweir 					}
560*cdf0e10cSrcweir 					case SFX_STYLESHEET_ERASED			:
561*cdf0e10cSrcweir 					case SFX_STYLESHEET_INDESTRUCTION	:
562*cdf0e10cSrcweir 					{
563*cdf0e10cSrcweir 						// Style needs to be exchanged
564*cdf0e10cSrcweir 						SfxStyleSheet* pNewStSh = 0L;
565*cdf0e10cSrcweir 						SdrModel* pModel = rObj.GetModel();
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 						// #111111#
568*cdf0e10cSrcweir 						// Do nothing if object is in destruction, else a StyleSheet may be found from
569*cdf0e10cSrcweir 						// a StyleSheetPool which is just being deleted itself. and thus it would be fatal
570*cdf0e10cSrcweir 						// to register as listener to that new StyleSheet.
571*cdf0e10cSrcweir 						if(pModel && !rObj.IsInDestruction())
572*cdf0e10cSrcweir 						{
573*cdf0e10cSrcweir 							if(HAS_BASE(SfxStyleSheet, GetStyleSheet()))
574*cdf0e10cSrcweir 							{
575*cdf0e10cSrcweir 								pNewStSh = (SfxStyleSheet*)pModel->GetStyleSheetPool()->Find(
576*cdf0e10cSrcweir 									GetStyleSheet()->GetParent(), GetStyleSheet()->GetFamily());
577*cdf0e10cSrcweir 							}
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir 							if(!pNewStSh)
580*cdf0e10cSrcweir 							{
581*cdf0e10cSrcweir 								pNewStSh = pModel->GetDefaultStyleSheet();
582*cdf0e10cSrcweir 							}
583*cdf0e10cSrcweir 						}
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 						// remove used style, it's erased or in destruction
586*cdf0e10cSrcweir 						ImpRemoveStyleSheet();
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir 						if(pNewStSh)
589*cdf0e10cSrcweir 						{
590*cdf0e10cSrcweir 							ImpAddStyleSheet(pNewStSh, sal_True);
591*cdf0e10cSrcweir 						}
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir 						break;
594*cdf0e10cSrcweir 					}
595*cdf0e10cSrcweir 				}
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir 				// Get old BoundRect. Do this after the style change is handled
598*cdf0e10cSrcweir 				// in the ItemSet parts because GetBoundRect() may calculate a new
599*cdf0e10cSrcweir 				Rectangle aBoundRect = rObj.GetLastBoundRect();
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 				rObj.SetRectsDirty(sal_True);
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir 				// tell the object about the change
604*cdf0e10cSrcweir 				rObj.SetChanged();
605*cdf0e10cSrcweir 				rObj.BroadcastObjectChange();
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir 				//if(pPage && pPage->IsInserted())
608*cdf0e10cSrcweir 				//{
609*cdf0e10cSrcweir 				//	rObj.BroadcastObjectChange();
610*cdf0e10cSrcweir 				//}
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir 				rObj.SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect);
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir 				bHintUsed = sal_True;
615*cdf0e10cSrcweir 			}
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir 			if(!bHintUsed)
618*cdf0e10cSrcweir 			{
619*cdf0e10cSrcweir 				// forward to SdrObject ATM. Not sure if this will be necessary
620*cdf0e10cSrcweir 				// in the future.
621*cdf0e10cSrcweir 				GetSdrObject().Notify(rBC, rHint);
622*cdf0e10cSrcweir 			}
623*cdf0e10cSrcweir 		}
624*cdf0e10cSrcweir 	} // end of namespace properties
625*cdf0e10cSrcweir } // end of namespace sdr
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
628*cdf0e10cSrcweir // eof
629