Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / toolbars / extrusionbar.cxx
blob5b0b18c8f12a4cf977dda30a87e89eaf5217a3d5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp>
22 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
23 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
24 #include <com/sun/star/drawing/ShadeMode.hpp>
25 #include <com/sun/star/drawing/Position3D.hpp>
26 #include <com/sun/star/drawing/Direction3D.hpp>
27 #include <com/sun/star/drawing/ProjectionMode.hpp>
28 #include <svx/svxids.hrc>
29 #include <svx/svdundo.hxx>
30 #include <sfx2/request.hxx>
31 #include <sfx2/objface.hxx>
32 #include <sfx2/viewsh.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <svx/xsflclit.hxx>
35 #include <svx/dialmgr.hxx>
36 #include <svx/svdoashp.hxx>
37 #include <svx/strings.hrc>
38 #include <svx/svdview.hxx>
39 #include <editeng/colritem.hxx>
40 #include <svx/chrtitem.hxx>
41 #include <svx/sdasitm.hxx>
42 #include <svl/intitem.hxx>
43 #include <rtl/math.hxx>
44 #include <basegfx/numeric/ftools.hxx>
46 #include <svx/extrusionbar.hxx>
47 #include <extrusiondepthdialog.hxx>
49 using namespace ::svx;
50 using namespace ::cppu;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::drawing;
53 using namespace ::com::sun::star::uno;
55 // Declare the default interface. (The slotmap must not be empty, so
56 // we enter something which never occurs here (hopefully).)
57 static SfxSlot aExtrusionBarSlots_Impl[] =
59 { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, "" }
62 SFX_IMPL_INTERFACE(ExtrusionBar, SfxShell)
64 void ExtrusionBar::InitInterface_Impl()
66 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Svx_Extrusion_Bar);
70 ExtrusionBar::ExtrusionBar(SfxViewShell* pViewShell )
71 : SfxShell(pViewShell)
73 DBG_ASSERT( pViewShell, "svx::ExtrusionBar::ExtrusionBar(), I need a viewshell!" );
74 if( pViewShell )
75 SetPool(&pViewShell->GetPool());
77 SetName(SvxResId(RID_SVX_EXTRUSION_BAR));
80 ExtrusionBar::~ExtrusionBar()
82 SetRepeatTarget(nullptr);
85 static void getLightingDirectionDefaults( const Direction3D **pLighting1Defaults, const Direction3D **pLighting2Defaults )
88 static const Direction3D aLighting1Defaults[9] =
90 Direction3D( -50000, -50000, 10000 ),
91 Direction3D( 0, -50000, 10000 ),
92 Direction3D( 50000, -50000, 10000 ),
93 Direction3D( -50000, 0, 10000 ),
94 Direction3D( 0, 0, 10000 ),
95 Direction3D( 50000, 0, 10000 ),
96 Direction3D( -50000, 50000, 10000 ),
97 Direction3D( 0, 50000, 10000 ),
98 Direction3D( 50000, 50000, 10000 )
101 static const Direction3D aLighting2Defaults[9] =
103 Direction3D( 50000,0, 10000 ),
104 Direction3D( 0, 50000, 10000 ),
105 Direction3D( -50000, 0, 10000 ),
106 Direction3D( 50000, 0, 10000 ),
107 Direction3D( 0, 0, 10000 ),
108 Direction3D( -50000, 0, 10000 ),
109 Direction3D( 50000, 0, 10000 ),
110 Direction3D( 0, -50000, 10000 ),
111 Direction3D( -50000, 0, 10000 )
114 *pLighting1Defaults = aLighting1Defaults;
115 *pLighting2Defaults = aLighting2Defaults;
118 static void impl_execute( SfxRequest const & rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
120 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
121 static constexpr OUStringLiteral sRotateAngle = u"RotateAngle";
123 sal_uInt16 nSID = rReq.GetSlot();
124 switch( nSID )
126 case SID_EXTRUSION_TOGGLE:
128 bool bOn(false);
129 css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
130 if ( pAny )
132 (*pAny) >>= bOn;
133 bOn = !bOn;
134 css::beans::PropertyValue aPropValue;
135 aPropValue.Name = sExtrusion;
136 aPropValue.Value <<= bOn;
137 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
139 else
141 css::beans::PropertyValue aPropValue;
142 aPropValue.Name = sExtrusion;
143 aPropValue.Value <<= true;
144 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
145 bOn = true;
148 // draw:extrusion-diffusion has default 0% and c3DDiffuseAmt has default 100%. We set property
149 // "Diffusion" with value 100% here if it does not exist already. This forces, that the
150 // property is written to file in case an extrusion is newly created, and users of old
151 // documents, which usually do not have this property, can force the value to 100% by toggling
152 // the extrusion off and on.
153 if (bOn)
155 pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Diffusion");
156 if (!pAny)
158 css::beans::PropertyValue aPropValue;
159 aPropValue.Name = u"Diffusion";
160 aPropValue.Value <<= 100.0;
161 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
165 break;
167 case SID_EXTRUSION_TILT_DOWN:
168 case SID_EXTRUSION_TILT_UP:
169 case SID_EXTRUSION_TILT_LEFT:
170 case SID_EXTRUSION_TILT_RIGHT:
172 bool bHorizontal = ( nSID == SID_EXTRUSION_TILT_DOWN ) || ( nSID == SID_EXTRUSION_TILT_UP );
173 sal_Int32 nDiff = ( nSID == SID_EXTRUSION_TILT_LEFT ) || ( nSID == SID_EXTRUSION_TILT_UP ) ? 5 : -5;
174 EnhancedCustomShapeParameterPair aRotateAnglePropPair;
175 double fX = 0.0;
176 double fY = 0.0;
177 aRotateAnglePropPair.First.Value <<= fX;
178 aRotateAnglePropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
179 aRotateAnglePropPair.Second.Value <<= fY;
180 aRotateAnglePropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
181 css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sRotateAngle );
182 if( pAny && ( *pAny >>= aRotateAnglePropPair ) )
184 aRotateAnglePropPair.First.Value >>= fX;
185 aRotateAnglePropPair.Second.Value >>= fY;
187 if ( bHorizontal )
188 fX += nDiff;
189 else
190 fY += nDiff;
191 aRotateAnglePropPair.First.Value <<= fX;
192 aRotateAnglePropPair.Second.Value <<= fY;
193 css::beans::PropertyValue aPropValue;
194 aPropValue.Name = sRotateAngle;
195 aPropValue.Value <<= aRotateAnglePropPair;
196 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
198 break;
200 case SID_EXTRUSION_DIRECTION:
202 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DIRECTION ) == SfxItemState::SET )
204 sal_Int32 nSkew = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_DIRECTION)->GetValue();
206 Position3D aViewPoint( 3472, -3472, 25000 );
207 double fOriginX = 0.50;
208 double fOriginY = -0.50;
209 double fSkewAngle = nSkew;
210 double fSkew = 50.0;
212 switch( nSkew )
214 case 135:
215 aViewPoint.PositionY = 3472;
216 fOriginY = 0.50;
217 break;
218 case 90:
219 aViewPoint.PositionX = 0;
220 aViewPoint.PositionY = 3472;
221 fOriginX = 0;
222 fOriginY = 0.50;
223 break;
224 case 45:
225 aViewPoint.PositionX = -3472;
226 aViewPoint.PositionY = 3472;
227 fOriginX = -0.50;
228 fOriginY = 0.50;
229 break;
230 case 180:
231 aViewPoint.PositionY = 0;
232 fOriginY = 0;
233 break;
234 case 0:
235 aViewPoint.PositionX = 0;
236 aViewPoint.PositionY = 0;
237 fOriginX = 0;
238 fOriginY = 0;
239 fSkew = 0.0;
240 break;
241 case -360:
242 aViewPoint.PositionX = -3472;
243 aViewPoint.PositionY = 0;
244 fOriginX = -0.50;
245 fOriginY = 0;
246 break;
247 case -90:
248 aViewPoint.PositionX = 0;
249 fOriginX = 0;
250 break;
251 case -45:
252 aViewPoint.PositionX = -3472;
253 fOriginX = -0.50;
254 break;
257 css::beans::PropertyValue aPropValue;
259 aPropValue.Name = "ViewPoint";
260 aPropValue.Value <<= aViewPoint;
261 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
264 EnhancedCustomShapeParameterPair aOriginPropPair;
265 aOriginPropPair.First.Value <<= fOriginX;
266 aOriginPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
267 aOriginPropPair.Second.Value <<= fOriginY;
268 aOriginPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
269 aPropValue.Name = "Origin";
270 aPropValue.Value <<= aOriginPropPair;
271 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
273 EnhancedCustomShapeParameterPair aSkewPropPair;
274 aSkewPropPair.First.Value <<= fSkew;
275 aSkewPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
276 aSkewPropPair.Second.Value <<= fSkewAngle;
277 aSkewPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
278 aPropValue.Name = "Skew";
279 aPropValue.Value <<= aSkewPropPair;
280 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
283 break;
284 case SID_EXTRUSION_PROJECTION:
286 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_PROJECTION ) == SfxItemState::SET )
288 sal_Int32 nProjection = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_PROJECTION)->GetValue();
289 ProjectionMode eProjectionMode = nProjection == 1 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
290 css::beans::PropertyValue aPropValue;
291 aPropValue.Name = "ProjectionMode";
292 aPropValue.Value <<= eProjectionMode;
293 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
296 break;
297 case SID_EXTRUSION_DEPTH:
299 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH ) == SfxItemState::SET)
301 double fDepth = rReq.GetArgs()->GetItem<SvxDoubleItem>(SID_EXTRUSION_DEPTH)->GetValue();
302 EnhancedCustomShapeParameterPair aDepthPropPair;
303 aDepthPropPair.First.Value <<= fDepth;
304 aDepthPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
305 aDepthPropPair.Second.Value <<= 0.0; // fraction
306 aDepthPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
308 css::beans::PropertyValue aPropValue;
309 aPropValue.Name = "Depth";
310 aPropValue.Value <<= aDepthPropPair;
311 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
314 break;
315 case SID_EXTRUSION_3D_COLOR:
317 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_3D_COLOR ) == SfxItemState::SET)
319 Color aColor( static_cast<const SvxColorItem&>(rReq.GetArgs()->Get(SID_EXTRUSION_3D_COLOR)).GetValue() );
321 const bool bAuto = aColor == COL_AUTO;
323 css::beans::PropertyValue aPropValue;
324 aPropValue.Name = "Color";
325 aPropValue.Value <<= !bAuto;
326 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
328 if( bAuto )
330 pObj->ClearMergedItem( XATTR_SECONDARYFILLCOLOR );
332 else
334 pObj->SetMergedItem( XSecondaryFillColorItem( "", aColor ) );
336 pObj->BroadcastObjectChange();
339 break;
340 case SID_EXTRUSION_SURFACE:
342 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_SURFACE ) == SfxItemState::SET)
344 sal_Int32 nSurface = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_SURFACE)->GetValue();
346 // Set ShadeMode only when changing from or to wireframe, otherwise keep existing value.
347 ShadeMode eOldShadeMode(ShadeMode_FLAT);
348 css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"ShadeMode");
349 if (pAny)
350 *pAny >>= eOldShadeMode;
351 ShadeMode eShadeMode(eOldShadeMode);
352 switch (nSurface)
354 case 0: // wireframe
355 eShadeMode = ShadeMode_DRAFT;
356 break;
357 case 1: // matte
358 case 2: // plastic
359 case 3: // metal ODF
360 case 4: // metal MS Office
361 if (eOldShadeMode == ShadeMode_DRAFT)
362 eShadeMode = ShadeMode_FLAT; // ODF default
363 break;
366 // ODF has no dedicated property for 'surface'. MS Office binary format uses attribute
367 // c3DSpecularAmt to distinguish between 'matte' (=0) and 'plastic'.
368 // We do the same.
369 double fOldSpecularity = 0.0;
370 pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Specularity");
371 if (pAny)
372 *pAny >>= fOldSpecularity;
373 double fSpecularity = fOldSpecularity;
374 switch( nSurface )
376 case 0: // wireframe
377 break;
378 case 1: // matte
379 fSpecularity = 0.0;
380 break;
381 case 2: // plastic
382 case 3: // metal ODF
383 case 4: // metal MS Office
384 if (basegfx::fTools::equalZero(fOldSpecularity, 0.0001))
385 // MS Office uses 80000/65536. That is currently not allowed in ODF.
386 // But the ODF error will be caught in xmloff.
387 fSpecularity = 80000.0 / 655.36; // interpreted as %
388 break;
391 // MS Office binary format uses attribute c3DDiffuseAmt with value =43712 (Fixed 16.16) in
392 // addition to the 'metal' flag. For other surface kinds default = 65536 is used.
393 // We toggle between 100 and 43712.0 / 655.36 here, to get better ODF -> MSO binary.
394 // We keep other values, those might be set outside regular UI, e.g by macro.
395 double fOldDiffusion = 100.0;
396 pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Diffusion");
397 if (pAny)
398 *pAny >>= fOldDiffusion;
399 double fDiffusion = fOldDiffusion;
400 if (nSurface == 4)
402 if (fOldDiffusion == 100.0)
403 fDiffusion = 43712.0 / 655.36; // interpreted as %
405 else
407 if (basegfx::fTools::equalZero(fOldDiffusion - 43712.0 / 655.36, 0.0001))
408 fDiffusion = 100.0;
411 css::beans::PropertyValue aPropValue;
412 aPropValue.Name = "ShadeMode";
413 aPropValue.Value <<= eShadeMode;
414 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
416 aPropValue.Name = "Metal";
417 aPropValue.Value <<= nSurface == 3 || nSurface == 4;
418 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
420 if (nSurface == 3 || nSurface == 4)
422 aPropValue.Name = "MetalType";
423 aPropValue.Value <<= nSurface == 4
424 ? EnhancedCustomShapeMetalType::MetalMSCompatible
425 : EnhancedCustomShapeMetalType::MetalODF;
426 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
429 if (!basegfx::fTools::equalZero(fOldSpecularity - fSpecularity, 0.0001))
431 aPropValue.Name = "Specularity";
432 aPropValue.Value <<= fSpecularity;
433 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
436 if (!basegfx::fTools::equalZero(fOldDiffusion - fDiffusion, 0.0001))
438 aPropValue.Name = "Diffusion";
439 aPropValue.Value <<= fDiffusion;
440 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
444 break;
445 case SID_EXTRUSION_LIGHTING_INTENSITY:
447 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_INTENSITY ) == SfxItemState::SET)
449 sal_Int32 nLevel = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_LIGHTING_INTENSITY)->GetValue();
451 double fBrightness; // c3DAmbientIntensity in MS Office
452 double fLevel1; // c3DKeyIntensity in MS Office
453 double fLevel2; // c3DFillIntensity in MS Office
455 // ToDo: "bright" values are different from MS Office. Should they be kept?
456 switch( nLevel )
458 case 0: // bright
459 fBrightness = 33.0; // ODF default.
460 fLevel1 = 66.0; // ODF default
461 fLevel2 = 66.0; // ODF default
462 break;
463 case 1: // normal
464 fBrightness = 15.0;
465 fLevel1 = 67.0;
466 fLevel2 = 37.0;
467 break;
468 case 2: // dim
469 fBrightness = 6.0;
470 fLevel1 = 79.0;
471 fLevel2 = 21.0;
472 break;
475 css::beans::PropertyValue aPropValue;
476 aPropValue.Name = "Brightness";
477 aPropValue.Value <<= fBrightness;
478 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
480 aPropValue.Name = "FirstLightLevel";
481 aPropValue.Value <<= fLevel1;
482 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
484 aPropValue.Name = "SecondLightLevel";
485 aPropValue.Value <<= fLevel2;
486 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
488 // If a user sets light preset 'Dim' in MS Office, MS Office sets second light to harsh.
489 // In other cases it is soft.
490 aPropValue.Name = "SecondLightHarsh";
491 aPropValue.Value <<= nLevel == 2;
492 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
495 break;
496 case SID_EXTRUSION_LIGHTING_DIRECTION:
498 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_DIRECTION ) == SfxItemState::SET)
500 sal_Int32 nDirection = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_LIGHTING_DIRECTION)->GetValue();
502 if((nDirection >= 0) && (nDirection < 9))
504 const Direction3D * pLighting1Defaults;
505 const Direction3D * pLighting2Defaults;
507 getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
509 css::beans::PropertyValue aPropValue;
510 aPropValue.Name = "FirstLightDirection";
511 aPropValue.Value <<= pLighting1Defaults[nDirection];
512 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
514 aPropValue.Name = "SecondLightDirection";
515 aPropValue.Value <<= pLighting2Defaults[nDirection];
516 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
520 break;
525 void ExtrusionBar::execute( SdrView* pSdrView, SfxRequest const & rReq, SfxBindings& rBindings )
527 sal_uInt16 nSID = rReq.GetSlot();
528 TranslateId pStrResId;
530 const bool bUndo = pSdrView && pSdrView->IsUndoEnabled();
532 switch( nSID )
534 case SID_EXTRUSION_TOGGLE:
536 if ( !pStrResId )
537 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ON_OFF;
538 [[fallthrough]];
540 case SID_EXTRUSION_TILT_DOWN:
542 if ( !pStrResId )
543 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_DOWN;
544 [[fallthrough]];
546 case SID_EXTRUSION_TILT_UP:
548 if ( !pStrResId )
549 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_UP;
550 [[fallthrough]];
552 case SID_EXTRUSION_TILT_LEFT:
554 if ( !pStrResId )
555 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_LEFT;
556 [[fallthrough]];
558 case SID_EXTRUSION_TILT_RIGHT:
560 if ( !pStrResId )
561 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_RIGHT;
562 [[fallthrough]];
564 case SID_EXTRUSION_DIRECTION:
566 if ( !pStrResId )
567 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ORIENTATION;
568 [[fallthrough]];
570 case SID_EXTRUSION_PROJECTION:
572 if ( !pStrResId )
573 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_PROJECTION;
574 [[fallthrough]];
576 case SID_EXTRUSION_DEPTH:
578 if ( !pStrResId )
579 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_DEPTH;
580 [[fallthrough]];
582 case SID_EXTRUSION_3D_COLOR:
584 if ( !pStrResId )
585 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_COLOR;
586 [[fallthrough]];
588 case SID_EXTRUSION_SURFACE:
590 if ( !pStrResId )
591 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_SURFACE;
592 [[fallthrough]];
594 case SID_EXTRUSION_LIGHTING_INTENSITY:
596 if ( !pStrResId )
597 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_BRIGHTNESS;
598 [[fallthrough]];
600 case SID_EXTRUSION_LIGHTING_DIRECTION:
602 if ( !pStrResId )
603 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_LIGHTING;
605 if (pSdrView)
607 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
608 const size_t nCount = rMarkList.GetMarkCount();
610 for(size_t i=0; i<nCount; ++i)
612 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
613 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
615 if( bUndo )
617 OUString aStr( SvxResId( pStrResId ) );
618 pSdrView->BegUndo( aStr );
619 pSdrView->AddUndo( pSdrView->GetModel().GetSdrUndoFactory().CreateUndoAttrObject( *pObj ) );
621 SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
622 impl_execute( rReq, aGeometryItem, pObj );
623 pObj->SetMergedItem( aGeometryItem );
624 pObj->BroadcastObjectChange();
625 if( bUndo )
626 pSdrView->EndUndo();
628 // simulate a context change:
629 // force SelectionHasChanged() being called
630 // so that extrusion bar will be visible/hidden
631 pSdrView->MarkListHasChanged();
636 break;
638 case SID_EXTRUSION_DEPTH_DIALOG:
639 if( rReq.GetArgs() &&
640 (rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH ) == SfxItemState::SET) &&
641 (rReq.GetArgs()->GetItemState( SID_ATTR_METRIC ) == SfxItemState::SET))
643 double fDepth = rReq.GetArgs()->GetItem<SvxDoubleItem>(SID_EXTRUSION_DEPTH)->GetValue();
644 FieldUnit eUnit = static_cast<FieldUnit>(rReq.GetArgs()->GetItem<SfxUInt16Item>(SID_ATTR_METRIC)->GetValue());
646 ExtrusionDepthDialog aDlg(rReq.GetFrameWeld(), fDepth, eUnit);
647 sal_uInt16 nRet = aDlg.run();
648 if (nRet == RET_OK)
650 fDepth = aDlg.getDepth();
652 SvxDoubleItem aItem( fDepth, SID_EXTRUSION_DEPTH );
653 SfxPoolItem* aItems[] = { &aItem, nullptr };
654 rBindings.Execute( SID_EXTRUSION_DEPTH, const_cast<const SfxPoolItem**>(aItems) );
657 break;
660 if( nSID != SID_EXTRUSION_TOGGLE )
661 return;
663 static const sal_uInt16 SidArray[] = {
664 SID_EXTRUSION_TILT_DOWN,
665 SID_EXTRUSION_TILT_UP,
666 SID_EXTRUSION_TILT_LEFT,
667 SID_EXTRUSION_TILT_RIGHT,
668 SID_EXTRUSION_DEPTH_FLOATER,
669 SID_EXTRUSION_DIRECTION_FLOATER,
670 SID_EXTRUSION_LIGHTING_FLOATER,
671 SID_EXTRUSION_SURFACE_FLOATER,
672 SID_EXTRUSION_3D_COLOR,
673 SID_EXTRUSION_DEPTH,
674 SID_EXTRUSION_DIRECTION,
675 SID_EXTRUSION_PROJECTION,
676 SID_EXTRUSION_LIGHTING_DIRECTION,
677 SID_EXTRUSION_LIGHTING_INTENSITY,
678 SID_EXTRUSION_SURFACE,
679 0 };
681 rBindings.Invalidate( SidArray );
684 static void getExtrusionDirectionState( SdrView const * pSdrView, SfxItemSet& rSet )
686 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
687 const size_t nCount = rMarkList.GetMarkCount();
689 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
691 const css::uno::Any* pAny;
693 double fFinalSkewAngle = -1;
694 bool bHasCustomShape = false;
696 for(size_t i=0; i<nCount; ++i)
698 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
699 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
701 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
703 // see if this is an extruded customshape
704 if( !bHasCustomShape )
706 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
707 if( pAny_ )
708 *pAny_ >>= bHasCustomShape;
710 if( !bHasCustomShape )
711 continue;
714 bool bParallel = true;
715 Position3D aViewPoint( 3472, -3472, 25000 ); // MSO default
716 double fSkewAngle = -135; // MSO default
718 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "ProjectionMode" );
719 sal_Int16 nProjectionMode = sal_Int16();
720 if( pAny && ( *pAny >>= nProjectionMode ) )
721 bParallel = static_cast<ProjectionMode>(nProjectionMode) == ProjectionMode_PARALLEL;
723 if( bParallel )
725 double fSkew = 50.0;
726 EnhancedCustomShapeParameterPair aSkewPropPair;
727 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Skew" );
728 if( pAny && ( *pAny >>= aSkewPropPair ) )
730 aSkewPropPair.First.Value >>= fSkew;
731 aSkewPropPair.Second.Value >>= fSkewAngle;
733 if ( fSkew == 0.0 )
734 fSkewAngle = 0.0;
735 else if ( fSkewAngle == 0.0 )
736 fSkewAngle = -360.0;
738 else
740 double fOriginX = 0.50;
741 double fOriginY = -0.50;
742 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "ViewPoint" );
743 if( pAny )
744 *pAny >>= aViewPoint;
746 EnhancedCustomShapeParameterPair aOriginPropPair;
747 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Origin" );
748 if( pAny && ( *pAny >>= aOriginPropPair ) )
750 aOriginPropPair.First.Value >>= fOriginX;
751 aOriginPropPair.Second.Value >>= fOriginY;
753 fSkewAngle = -1;
754 const double e = 0.0001;
755 if( aViewPoint.PositionX > e )
757 if( aViewPoint.PositionY > e )
759 if( (fOriginX > e ) && ( fOriginY > e ) )
760 fSkewAngle = 135.0;
762 else if( aViewPoint.PositionY < -e )
764 if( ( fOriginX > e ) && ( fOriginY < -e ) )
765 fSkewAngle = -135.0;
767 else
769 if( ( fOriginX > e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
770 fSkewAngle = 180.0;
773 else if( aViewPoint.PositionX < -e )
775 if( aViewPoint.PositionY < -e )
777 if( ( fOriginX < -e ) && ( fOriginY < -e ) )
778 fSkewAngle = -45.0;
780 else if( aViewPoint.PositionY > e )
782 if( ( fOriginX < -e ) && ( fOriginY > e ) )
783 fSkewAngle = 45.0;
785 else
787 if( ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
788 fSkewAngle = -360.0;
791 else
793 if( aViewPoint.PositionY < -e )
795 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY < -e ) )
796 fSkewAngle = -90.0;
798 else if( aViewPoint.PositionY > e )
800 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > e ) )
801 fSkewAngle = 90.0;
803 else
805 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
806 fSkewAngle = 0.0;
811 if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
813 fFinalSkewAngle = fSkewAngle;
815 else if( !rtl::math::approxEqual(fSkewAngle, fFinalSkewAngle) )
817 fFinalSkewAngle = -1.0;
820 if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
821 break;
825 if( bHasCustomShape )
826 rSet.Put( SfxInt32Item( SID_EXTRUSION_DIRECTION, static_cast<sal_Int32>(fFinalSkewAngle) ) );
827 else
828 rSet.DisableItem( SID_EXTRUSION_DIRECTION );
831 static void getExtrusionProjectionState( SdrView const * pSdrView, SfxItemSet& rSet )
833 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
834 const size_t nCount = rMarkList.GetMarkCount();
836 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
838 const css::uno::Any* pAny;
840 sal_Int32 nFinalProjection = -1;
841 bool bHasCustomShape = false;
843 for(size_t i=0; i<nCount; ++i)
845 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
846 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
848 // see if this is an extruded customshape
849 if( !bHasCustomShape )
851 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
852 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
853 if( pAny_ )
854 *pAny_ >>= bHasCustomShape;
856 if( !bHasCustomShape )
857 continue;
860 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
862 bool bParallel = true;
863 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "ProjectionMode" );
864 ProjectionMode eProjectionMode;
865 if( pAny && ( *pAny >>= eProjectionMode ) )
866 bParallel = eProjectionMode == ProjectionMode_PARALLEL;
868 if( nFinalProjection == -1 )
870 nFinalProjection = bParallel ? 1 : 0;
872 else if( nFinalProjection != (bParallel ? 1 : 0) )
874 nFinalProjection = -1;
875 break;
880 if( bHasCustomShape )
881 rSet.Put( SfxInt32Item( SID_EXTRUSION_PROJECTION, nFinalProjection ) );
882 else
883 rSet.DisableItem( SID_EXTRUSION_PROJECTION );
886 static void getExtrusionSurfaceState( SdrView const * pSdrView, SfxItemSet& rSet )
888 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
889 const size_t nCount = rMarkList.GetMarkCount();
891 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
893 const css::uno::Any* pAny;
895 sal_Int32 nFinalSurface = -1;
896 bool bHasCustomShape = false;
898 for(size_t i=0; i<nCount; ++i)
900 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
901 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
903 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
905 // see if this is an extruded customshape
906 if( !bHasCustomShape )
908 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
909 if( pAny_ )
910 *pAny_ >>= bHasCustomShape;
912 if( !bHasCustomShape )
913 continue;
916 sal_Int32 nSurface = 0; // wire frame
918 ShadeMode eShadeMode( ShadeMode_FLAT );
919 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ShadeMode" );
920 if( pAny )
921 *pAny >>= eShadeMode;
923 if (eShadeMode != ShadeMode_DRAFT)
925 bool bMetal = false;
926 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Metal" );
927 if( pAny )
928 *pAny >>= bMetal;
930 if( bMetal )
932 nSurface = 3; // metal ODF
933 sal_Int16 eMetalType = EnhancedCustomShapeMetalType::MetalODF;
934 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"MetalType" );
935 if (pAny)
937 *pAny >>= eMetalType;
938 if (eMetalType == EnhancedCustomShapeMetalType::MetalMSCompatible)
939 nSurface = 4; // metal MS Office
942 else
944 double fSpecularity = 0;
945 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Specularity" );
946 if( pAny )
947 *pAny >>= fSpecularity;
949 const double e = 0.0001;
950 if( (fSpecularity > -e) && (fSpecularity < e) )
952 nSurface = 1; // matte
954 else
956 nSurface = 2; // plastic
961 if( nFinalSurface == -1 )
963 nFinalSurface = nSurface;
965 else if( nFinalSurface != nSurface )
967 nFinalSurface = -1;
968 break;
973 if( bHasCustomShape )
974 rSet.Put( SfxInt32Item( SID_EXTRUSION_SURFACE, nFinalSurface ) );
975 else
976 rSet.DisableItem( SID_EXTRUSION_SURFACE );
979 static void getExtrusionDepthState( SdrView const * pSdrView, SfxItemSet& rSet )
981 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
982 const size_t nCount = rMarkList.GetMarkCount();
984 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
986 const css::uno::Any* pAny;
988 double fFinalDepth = -1;
989 bool bHasCustomShape = false;
991 for(size_t i=0; i<nCount; ++i)
993 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
994 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
996 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
998 // see if this is an extruded customshape
999 if( !bHasCustomShape )
1001 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1002 if( pAny_ )
1003 *pAny_ >>= bHasCustomShape;
1005 if( !bHasCustomShape )
1006 continue;
1009 double fDepth = 1270.0; // =36pt ODF default
1010 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Depth" );
1011 if( pAny )
1013 EnhancedCustomShapeParameterPair aDepthPropPair;
1014 if ( *pAny >>= aDepthPropPair )
1015 aDepthPropPair.First.Value >>= fDepth;
1018 if( fFinalDepth == -1 )
1020 fFinalDepth = fDepth;
1022 else if( !rtl::math::approxEqual(fFinalDepth, fDepth) )
1024 fFinalDepth = -1;
1025 break;
1031 FieldUnit eUnit = pSdrView->GetModel().GetUIUnit();
1032 rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast<sal_uInt16>(eUnit) ) );
1034 if( bHasCustomShape )
1035 rSet.Put( SvxDoubleItem( fFinalDepth, SID_EXTRUSION_DEPTH ) );
1036 else
1037 rSet.DisableItem( SID_EXTRUSION_DEPTH );
1040 static bool compare_direction( const Direction3D& d1, const Direction3D& d2 )
1042 if( ((d1.DirectionX < 0) && (d2.DirectionX < 0)) || ((d1.DirectionX == 0) && (d2.DirectionX == 0)) || ((d1.DirectionX > 0) && (d2.DirectionX > 0)) )
1044 if( ((d1.DirectionY < 0) && (d2.DirectionY < 0)) || ((d1.DirectionY == 0) && (d2.DirectionY == 0)) || ((d1.DirectionY > 0) && (d2.DirectionY > 0)) )
1046 if( ((d1.DirectionZ < 0) && (d2.DirectionZ < 0)) || ((d1.DirectionZ == 0) && (d2.DirectionZ == 0)) || ((d1.DirectionZ > 0) && (d2.DirectionZ > 0)) )
1048 return true;
1053 return false;
1056 static void getExtrusionLightingDirectionState( SdrView const * pSdrView, SfxItemSet& rSet )
1058 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1059 const size_t nCount = rMarkList.GetMarkCount();
1061 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1063 const Direction3D * pLighting1Defaults;
1064 const Direction3D * pLighting2Defaults;
1066 getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
1068 const css::uno::Any* pAny;
1070 int nFinalDirection = -1;
1071 bool bHasCustomShape = false;
1073 for(size_t i=0; i<nCount; ++i)
1075 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1076 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1078 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1080 // see if this is an extruded customshape
1081 if( !bHasCustomShape )
1083 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1084 if( pAny_ )
1085 *pAny_ >>= bHasCustomShape;
1087 if( !bHasCustomShape )
1088 continue;
1091 Direction3D aFirstLightDirection( 50000, 0, 10000 );
1092 Direction3D aSecondLightDirection( -50000, 0, 10000 );
1094 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "FirstLightDirection" );
1095 if( pAny )
1096 *pAny >>= aFirstLightDirection;
1098 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "SecondLightDirection" );
1099 if( pAny )
1100 *pAny >>= aSecondLightDirection;
1102 int nDirection = -1;
1104 int j;
1105 for( j = 0; j < 9; j++ )
1107 if( compare_direction( aFirstLightDirection, pLighting1Defaults[j] ) &&
1108 compare_direction( aSecondLightDirection, pLighting2Defaults[j] ))
1110 nDirection = j;
1111 break;
1115 if( nFinalDirection == -1 )
1117 nFinalDirection = nDirection;
1119 else if( nDirection != nFinalDirection )
1121 nFinalDirection = -1;
1124 if( nFinalDirection == -1 )
1125 break;
1129 if( bHasCustomShape )
1130 rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_DIRECTION, static_cast<sal_Int32>(nFinalDirection) ) );
1131 else
1132 rSet.DisableItem( SID_EXTRUSION_LIGHTING_DIRECTION );
1135 static void getExtrusionLightingIntensityState( SdrView const * pSdrView, SfxItemSet& rSet )
1137 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1138 const size_t nCount = rMarkList.GetMarkCount();
1140 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1142 const css::uno::Any* pAny;
1144 int nFinalLevel = -1;
1145 bool bHasCustomShape = false;
1147 for(size_t i=0; i<nCount; ++i)
1149 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1150 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1152 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1154 // see if this is an extruded customshape
1155 if( !bHasCustomShape )
1157 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1158 if( pAny_ )
1159 *pAny_ >>= bHasCustomShape;
1161 if( !bHasCustomShape )
1162 continue;
1165 double fBrightness = 22178.0 / 655.36;
1166 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Brightness" );
1167 if( pAny )
1168 *pAny >>= fBrightness;
1170 int nLevel;
1171 if( fBrightness >= 30.0 )
1173 nLevel = 0; // Bright
1175 else if( fBrightness >= 10.0 )
1177 nLevel = 1; // Normal;
1179 else
1181 nLevel = 2; // Dim
1184 if( nFinalLevel == -1 )
1186 nFinalLevel = nLevel;
1188 else if( nFinalLevel != nLevel )
1190 nFinalLevel = -1;
1191 break;
1196 if( bHasCustomShape )
1197 rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_INTENSITY, nFinalLevel ) );
1198 else
1199 rSet.DisableItem( SID_EXTRUSION_LIGHTING_INTENSITY );
1202 static void getExtrusionColorState( SdrView const * pSdrView, SfxItemSet& rSet )
1204 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1205 const size_t nCount = rMarkList.GetMarkCount();
1207 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1209 const css::uno::Any* pAny;
1211 bool bInit = false;
1212 bool bAmbigius = false;
1213 Color aFinalColor;
1214 bool bHasCustomShape = false;
1216 for(size_t i=0; i<nCount; ++i)
1218 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1219 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1221 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1223 // see if this is an extruded customshape
1224 if( !bHasCustomShape )
1226 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1227 if( pAny_ )
1228 *pAny_ >>= bHasCustomShape;
1230 if( !bHasCustomShape )
1231 continue;
1234 Color aColor;
1236 bool bUseColor = false;
1237 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Color" );
1238 if( pAny )
1239 *pAny >>= bUseColor;
1241 if( bUseColor )
1243 const XSecondaryFillColorItem& rItem = pObj->GetMergedItem( XATTR_SECONDARYFILLCOLOR );
1244 aColor = rItem.GetColorValue();
1246 else
1248 aColor = COL_AUTO;
1251 if( !bInit )
1253 aFinalColor = aColor;
1254 bInit = true;
1256 else if( aFinalColor != aColor )
1258 bAmbigius = true;
1259 break;
1264 if( bAmbigius )
1265 aFinalColor = COL_AUTO;
1267 if( bHasCustomShape )
1268 rSet.Put( SvxColorItem( aFinalColor, SID_EXTRUSION_3D_COLOR ) );
1269 else
1270 rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
1273 namespace svx {
1274 bool checkForSelectedCustomShapes( SdrView const * pSdrView, bool bOnlyExtruded )
1276 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1278 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1279 const size_t nCount = rMarkList.GetMarkCount();
1280 bool bFound = false;
1282 for(size_t i=0;(i<nCount) && !bFound ; ++i)
1284 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1285 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1287 if( bOnlyExtruded )
1289 const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1290 const Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1291 if( pAny )
1292 *pAny >>= bFound;
1294 else
1296 bFound = true;
1301 return bFound;
1305 void ExtrusionBar::getState( SdrView const * pSdrView, SfxItemSet& rSet )
1307 getExtrusionDirectionState( pSdrView, rSet );
1308 getExtrusionProjectionState( pSdrView, rSet );
1310 const bool bOnlyExtrudedCustomShapes(checkForSelectedCustomShapes( pSdrView, true ));
1312 if (! bOnlyExtrudedCustomShapes)
1314 rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
1315 rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
1316 rSet.DisableItem( SID_EXTRUSION_TILT_UP );
1317 rSet.DisableItem( SID_EXTRUSION_TILT_LEFT );
1318 rSet.DisableItem( SID_EXTRUSION_TILT_RIGHT );
1319 rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
1320 rSet.DisableItem( SID_EXTRUSION_DEPTH_FLOATER );
1321 rSet.DisableItem( SID_EXTRUSION_DIRECTION_FLOATER );
1322 rSet.DisableItem( SID_EXTRUSION_LIGHTING_FLOATER );
1323 rSet.DisableItem( SID_EXTRUSION_SURFACE_FLOATER );
1326 if( !checkForSelectedCustomShapes( pSdrView, false ) )
1327 rSet.DisableItem( SID_EXTRUSION_TOGGLE );
1329 getExtrusionDepthState( pSdrView, rSet );
1330 getExtrusionSurfaceState( pSdrView, rSet );
1331 getExtrusionLightingIntensityState( pSdrView, rSet );
1332 getExtrusionLightingDirectionState( pSdrView, rSet );
1333 getExtrusionColorState( pSdrView, rSet );
1336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */