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