1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/sdr/properties/e3dsceneproperties.hxx>
27cdf0e10cSrcweir #include <svl/itemset.hxx>
28cdf0e10cSrcweir #include <svl/whiter.hxx>
29cdf0e10cSrcweir #include <svx/svddef.hxx>
30cdf0e10cSrcweir #include <svx/scene3d.hxx>
31cdf0e10cSrcweir #include <svx/svditer.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace sdr
36cdf0e10cSrcweir {
37cdf0e10cSrcweir 	namespace properties
38cdf0e10cSrcweir 	{
E3dSceneProperties(SdrObject & rObj)39cdf0e10cSrcweir 		E3dSceneProperties::E3dSceneProperties(SdrObject& rObj)
40cdf0e10cSrcweir 		:	E3dProperties(rObj)
41cdf0e10cSrcweir 		{
42cdf0e10cSrcweir 		}
43cdf0e10cSrcweir 
E3dSceneProperties(const E3dSceneProperties & rProps,SdrObject & rObj)44cdf0e10cSrcweir 		E3dSceneProperties::E3dSceneProperties(const E3dSceneProperties& rProps, SdrObject& rObj)
45cdf0e10cSrcweir 		:	E3dProperties(rProps, rObj)
46cdf0e10cSrcweir 		{
47cdf0e10cSrcweir 		}
48cdf0e10cSrcweir 
~E3dSceneProperties()49cdf0e10cSrcweir 		E3dSceneProperties::~E3dSceneProperties()
50cdf0e10cSrcweir 		{
51cdf0e10cSrcweir 		}
52cdf0e10cSrcweir 
Clone(SdrObject & rObj) const53cdf0e10cSrcweir 		BaseProperties& E3dSceneProperties::Clone(SdrObject& rObj) const
54cdf0e10cSrcweir 		{
55cdf0e10cSrcweir 			return *(new E3dSceneProperties(*this, rObj));
56cdf0e10cSrcweir 		}
57cdf0e10cSrcweir 
GetObjectItemSet() const58cdf0e10cSrcweir 		const SfxItemSet& E3dSceneProperties::GetObjectItemSet() const
59cdf0e10cSrcweir 		{
60cdf0e10cSrcweir 			//DBG_ASSERT(sal_False, "E3dSceneProperties::GetObjectItemSet() maybe the wrong call (!)");
61cdf0e10cSrcweir 			return E3dProperties::GetObjectItemSet();
62cdf0e10cSrcweir 		}
63cdf0e10cSrcweir 
GetMergedItemSet() const64cdf0e10cSrcweir 		const SfxItemSet& E3dSceneProperties::GetMergedItemSet() const
65cdf0e10cSrcweir 		{
66cdf0e10cSrcweir 			// prepare ItemSet
67cdf0e10cSrcweir 			if(mpItemSet)
68cdf0e10cSrcweir 			{
69cdf0e10cSrcweir 				// filter for SDRATTR_3DSCENE_ items, only keep those items
70cdf0e10cSrcweir 				SfxItemSet aNew(*mpItemSet->GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST);
71cdf0e10cSrcweir 				aNew.Put(*mpItemSet);
72cdf0e10cSrcweir 				mpItemSet->ClearItem();
73cdf0e10cSrcweir 				mpItemSet->Put(aNew);
74cdf0e10cSrcweir 			}
75cdf0e10cSrcweir 			else
76cdf0e10cSrcweir 			{
77cdf0e10cSrcweir 				// No ItemSet yet, force local ItemSet
78cdf0e10cSrcweir 				GetObjectItemSet();
79cdf0e10cSrcweir 			}
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 			// collect all ItemSets of contained 3d objects
82cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
83cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
86cdf0e10cSrcweir 			{
87cdf0e10cSrcweir 				SdrObject* pObj = pSub->GetObj(a);
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 				if(pObj && pObj->ISA(E3dCompoundObject))
90cdf0e10cSrcweir 				{
91cdf0e10cSrcweir 					const SfxItemSet& rSet = pObj->GetMergedItemSet();
92cdf0e10cSrcweir 					SfxWhichIter aIter(rSet);
93cdf0e10cSrcweir 					sal_uInt16 nWhich(aIter.FirstWhich());
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 					while(nWhich)
96cdf0e10cSrcweir 					{
97cdf0e10cSrcweir 						// Leave out the SDRATTR_3DSCENE_ range, this would only be double
98cdf0e10cSrcweir 						// and always equal.
99cdf0e10cSrcweir 						if(nWhich <= SDRATTR_3DSCENE_FIRST || nWhich >= SDRATTR_3DSCENE_LAST)
100cdf0e10cSrcweir 						{
101cdf0e10cSrcweir 							if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
102cdf0e10cSrcweir 							{
103cdf0e10cSrcweir 								mpItemSet->InvalidateItem(nWhich);
104cdf0e10cSrcweir 							}
105cdf0e10cSrcweir 							else
106cdf0e10cSrcweir 							{
107cdf0e10cSrcweir 								mpItemSet->MergeValue(rSet.Get(nWhich), sal_True);
108cdf0e10cSrcweir 							}
109cdf0e10cSrcweir 						}
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 						nWhich = aIter.NextWhich();
112cdf0e10cSrcweir 					}
113cdf0e10cSrcweir 				}
114cdf0e10cSrcweir 			}
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 			// call parent
117cdf0e10cSrcweir 			return E3dProperties::GetMergedItemSet();
118cdf0e10cSrcweir 		}
119cdf0e10cSrcweir 
SetMergedItemSet(const SfxItemSet & rSet,sal_Bool bClearAllItems)120cdf0e10cSrcweir 		void E3dSceneProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
121cdf0e10cSrcweir 		{
122cdf0e10cSrcweir 			// Set SDRATTR_3DOBJ_ range at contained objects.
123cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
124cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 			if(nCount)
127cdf0e10cSrcweir 			{
128cdf0e10cSrcweir 				// Generate filtered ItemSet which contains all but the SDRATTR_3DSCENE items.
129cdf0e10cSrcweir 				// #i50808# Leak fix, Clone produces a new instance and we get ownership here
130cdf0e10cSrcweir 				SfxItemSet* pNewSet = rSet.Clone(sal_True);
131cdf0e10cSrcweir 				DBG_ASSERT(pNewSet, "E3dSceneProperties::SetMergedItemSet(): Could not clone ItemSet (!)");
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 				for(sal_uInt16 b(SDRATTR_3DSCENE_FIRST); b <= SDRATTR_3DSCENE_LAST; b++)
134cdf0e10cSrcweir 				{
135cdf0e10cSrcweir 					pNewSet->ClearItem(b);
136cdf0e10cSrcweir 				}
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 				if(pNewSet->Count())
139cdf0e10cSrcweir 				{
140cdf0e10cSrcweir 					for(sal_uInt32 a(0L); a < nCount; a++)
141cdf0e10cSrcweir 					{
142cdf0e10cSrcweir 						SdrObject* pObj = pSub->GetObj(a);
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 						if(pObj && pObj->ISA(E3dCompoundObject))
145cdf0e10cSrcweir 						{
146cdf0e10cSrcweir 							// set merged ItemSet at contained 3d object.
147cdf0e10cSrcweir 							pObj->SetMergedItemSet(*pNewSet, bClearAllItems);
148cdf0e10cSrcweir 						}
149cdf0e10cSrcweir 					}
150cdf0e10cSrcweir 				}
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 				delete pNewSet;
153cdf0e10cSrcweir 			}
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 			// call parent. This will set items on local object, too.
156cdf0e10cSrcweir 			E3dProperties::SetMergedItemSet(rSet, bClearAllItems);
157cdf0e10cSrcweir 		}
158cdf0e10cSrcweir 
SetMergedItem(const SfxPoolItem & rItem)159cdf0e10cSrcweir 		void E3dSceneProperties::SetMergedItem(const SfxPoolItem& rItem)
160cdf0e10cSrcweir 		{
161cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
162cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
165cdf0e10cSrcweir 			{
166cdf0e10cSrcweir 				pSub->GetObj(a)->SetMergedItem(rItem);
167cdf0e10cSrcweir 			}
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 			// #i43809# call parent. This will set items on local object, too.
170cdf0e10cSrcweir 			E3dProperties::SetMergedItem(rItem);
171cdf0e10cSrcweir 		}
172cdf0e10cSrcweir 
ClearMergedItem(const sal_uInt16 nWhich)173cdf0e10cSrcweir 		void E3dSceneProperties::ClearMergedItem(const sal_uInt16 nWhich)
174cdf0e10cSrcweir 		{
175cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
176cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
179cdf0e10cSrcweir 			{
180cdf0e10cSrcweir 				pSub->GetObj(a)->ClearMergedItem(nWhich);
181cdf0e10cSrcweir 			}
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 			// #i43809# call parent. This will clear items on local object, too.
184cdf0e10cSrcweir 			E3dProperties::ClearMergedItem(nWhich);
185cdf0e10cSrcweir 		}
186cdf0e10cSrcweir 
PostItemChange(const sal_uInt16 nWhich)187cdf0e10cSrcweir 		void E3dSceneProperties::PostItemChange(const sal_uInt16 nWhich)
188cdf0e10cSrcweir 		{
189cdf0e10cSrcweir 			// call parent
190cdf0e10cSrcweir 			E3dProperties::PostItemChange(nWhich);
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 			// local changes
193cdf0e10cSrcweir 			E3dScene& rObj = (E3dScene&)GetSdrObject();
194cdf0e10cSrcweir 			rObj.StructureChanged();
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 			switch(nWhich)
197cdf0e10cSrcweir 			{
198cdf0e10cSrcweir 				case SDRATTR_3DSCENE_PERSPECTIVE			:
199cdf0e10cSrcweir 				case SDRATTR_3DSCENE_DISTANCE				:
200cdf0e10cSrcweir 				case SDRATTR_3DSCENE_FOCAL_LENGTH			:
201cdf0e10cSrcweir 				{
202cdf0e10cSrcweir 					// #83387#, #83391#
203cdf0e10cSrcweir 					// one common function for the camera attributes
204cdf0e10cSrcweir 					// since SetCamera() sets all three back to the ItemSet
205cdf0e10cSrcweir 					Camera3D aSceneCam(rObj.GetCamera());
206cdf0e10cSrcweir 					sal_Bool bChange(sal_False);
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 					// for SDRATTR_3DSCENE_PERSPECTIVE:
209cdf0e10cSrcweir 					if(aSceneCam.GetProjection() != rObj.GetPerspective())
210cdf0e10cSrcweir 					{
211cdf0e10cSrcweir 						aSceneCam.SetProjection(rObj.GetPerspective());
212cdf0e10cSrcweir 						bChange = sal_True;
213cdf0e10cSrcweir 					}
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 					// for SDRATTR_3DSCENE_DISTANCE:
216cdf0e10cSrcweir 					basegfx::B3DPoint aActualPosition(aSceneCam.GetPosition());
217cdf0e10cSrcweir 					double fNew = rObj.GetDistance();
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 					if(fNew != aActualPosition.getZ())
220cdf0e10cSrcweir 					{
221cdf0e10cSrcweir 						aSceneCam.SetPosition(basegfx::B3DPoint(aActualPosition.getX(), aActualPosition.getY(), fNew));
222cdf0e10cSrcweir 						bChange = sal_True;
223cdf0e10cSrcweir 					}
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 					// for SDRATTR_3DSCENE_FOCAL_LENGTH:
226cdf0e10cSrcweir 					fNew = rObj.GetFocalLength() / 100.0;
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 					if(aSceneCam.GetFocalLength() != fNew)
229cdf0e10cSrcweir 					{
230cdf0e10cSrcweir 						aSceneCam.SetFocalLength(fNew);
231cdf0e10cSrcweir 						bChange = sal_True;
232cdf0e10cSrcweir 					}
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 					// for all
235cdf0e10cSrcweir 					if(bChange)
236cdf0e10cSrcweir 					{
237cdf0e10cSrcweir 						rObj.SetCamera(aSceneCam);
238cdf0e10cSrcweir 					}
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 					break;
241cdf0e10cSrcweir 				}
242cdf0e10cSrcweir 			}
243cdf0e10cSrcweir 		}
244cdf0e10cSrcweir 
SetStyleSheet(SfxStyleSheet * pNewStyleSheet,sal_Bool bDontRemoveHardAttr)245cdf0e10cSrcweir 		void E3dSceneProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
246cdf0e10cSrcweir 		{
247cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
248cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
251cdf0e10cSrcweir 			{
252cdf0e10cSrcweir 				pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
253cdf0e10cSrcweir 			}
254cdf0e10cSrcweir 		}
255cdf0e10cSrcweir 
GetStyleSheet() const256cdf0e10cSrcweir 		SfxStyleSheet* E3dSceneProperties::GetStyleSheet() const
257cdf0e10cSrcweir 		{
258cdf0e10cSrcweir 			SfxStyleSheet* pRetval = 0L;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
261cdf0e10cSrcweir 			const sal_uInt32 nCount(pSub->GetObjCount());
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 			for(sal_uInt32 a(0L); a < nCount; a++)
264cdf0e10cSrcweir 			{
265cdf0e10cSrcweir 				SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet();
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 				if(pRetval)
268cdf0e10cSrcweir 				{
269cdf0e10cSrcweir 					if(pCandidate != pRetval)
270cdf0e10cSrcweir 					{
271cdf0e10cSrcweir 						// different StyleSheelts, return none
272cdf0e10cSrcweir 						return 0L;
273cdf0e10cSrcweir 					}
274cdf0e10cSrcweir 				}
275cdf0e10cSrcweir 				else
276cdf0e10cSrcweir 				{
277cdf0e10cSrcweir 					pRetval = pCandidate;
278cdf0e10cSrcweir 				}
279cdf0e10cSrcweir 			}
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 			return pRetval;
282cdf0e10cSrcweir 		}
283cdf0e10cSrcweir 
MoveToItemPool(SfxItemPool * pSrcPool,SfxItemPool * pDestPool,SdrModel * pNewModel)284cdf0e10cSrcweir 		void E3dSceneProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
285cdf0e10cSrcweir 		{
286cdf0e10cSrcweir 			if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
287cdf0e10cSrcweir 			{
288cdf0e10cSrcweir 				// call parent
289cdf0e10cSrcweir 				E3dProperties::MoveToItemPool(pSrcPool, pDestPool, pNewModel);
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 				// own reaction, but only with outmost scene
292cdf0e10cSrcweir 				E3dScene& rObj = (E3dScene&)GetSdrObject();
293cdf0e10cSrcweir 				const SdrObjList* pSubList = rObj.GetSubList();
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 				if(pSubList && rObj.GetScene() == &rObj)
296cdf0e10cSrcweir 				{
297cdf0e10cSrcweir 					SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS);
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 					while(a3DIterator.IsMore())
300cdf0e10cSrcweir 					{
301cdf0e10cSrcweir 						E3dObject* pObj = (E3dObject*)a3DIterator.Next();
302cdf0e10cSrcweir 						DBG_ASSERT(pObj->ISA(E3dObject), "In scenes there are only 3D objects allowed (!)");
303cdf0e10cSrcweir 						pObj->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
304cdf0e10cSrcweir 					}
305cdf0e10cSrcweir 				}
306cdf0e10cSrcweir 			}
307cdf0e10cSrcweir 		}
308cdf0e10cSrcweir 
SetSceneItemsFromCamera()309cdf0e10cSrcweir 		void E3dSceneProperties::SetSceneItemsFromCamera()
310cdf0e10cSrcweir 		{
311cdf0e10cSrcweir 			// force ItemSet
312cdf0e10cSrcweir 			GetObjectItemSet();
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 			E3dScene& rObj = (E3dScene&)GetSdrObject();
315cdf0e10cSrcweir 			Camera3D aSceneCam(rObj.GetCamera());
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 			// ProjectionType
318cdf0e10cSrcweir 			mpItemSet->Put(Svx3DPerspectiveItem((sal_uInt16)aSceneCam.GetProjection()));
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 			// CamPos
321cdf0e10cSrcweir 			mpItemSet->Put(Svx3DDistanceItem((sal_uInt32)(aSceneCam.GetPosition().getZ() + 0.5)));
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 			// FocalLength
324cdf0e10cSrcweir 			mpItemSet->Put(Svx3DFocalLengthItem((sal_uInt32)((aSceneCam.GetFocalLength() * 100.0) + 0.5)));
325cdf0e10cSrcweir 		}
326cdf0e10cSrcweir 	} // end of namespace properties
327cdf0e10cSrcweir } // end of namespace sdr
328cdf0e10cSrcweir 
329cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
330cdf0e10cSrcweir // eof
331