1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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!" );
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();
126 case SID_EXTRUSION_TOGGLE
:
129 css::uno::Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, sExtrusion
);
134 css::beans::PropertyValue aPropValue
;
135 aPropValue
.Name
= sExtrusion
;
136 aPropValue
.Value
<<= bOn
;
137 rGeometryItem
.SetPropertyValue(sExtrusion
, aPropValue
);
141 css::beans::PropertyValue aPropValue
;
142 aPropValue
.Name
= sExtrusion
;
143 aPropValue
.Value
<<= true;
144 rGeometryItem
.SetPropertyValue(sExtrusion
, aPropValue
);
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.
155 pAny
= rGeometryItem
.GetPropertyValueByName(sExtrusion
, u
"Diffusion");
158 css::beans::PropertyValue aPropValue
;
159 aPropValue
.Name
= u
"Diffusion";
160 aPropValue
.Value
<<= 100.0;
161 rGeometryItem
.SetPropertyValue( sExtrusion
, aPropValue
);
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
;
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
;
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
);
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
;
215 aViewPoint
.PositionY
= 3472;
219 aViewPoint
.PositionX
= 0;
220 aViewPoint
.PositionY
= 3472;
225 aViewPoint
.PositionX
= -3472;
226 aViewPoint
.PositionY
= 3472;
231 aViewPoint
.PositionY
= 0;
235 aViewPoint
.PositionX
= 0;
236 aViewPoint
.PositionY
= 0;
242 aViewPoint
.PositionX
= -3472;
243 aViewPoint
.PositionY
= 0;
248 aViewPoint
.PositionX
= 0;
252 aViewPoint
.PositionX
= -3472;
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
);
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
);
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
);
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
);
330 pObj
->ClearMergedItem( XATTR_SECONDARYFILLCOLOR
);
334 pObj
->SetMergedItem( XSecondaryFillColorItem( "", aColor
) );
336 pObj
->BroadcastObjectChange();
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");
350 *pAny
>>= eOldShadeMode
;
351 ShadeMode
eShadeMode(eOldShadeMode
);
355 eShadeMode
= ShadeMode_DRAFT
;
360 case 4: // metal MS Office
361 if (eOldShadeMode
== ShadeMode_DRAFT
)
362 eShadeMode
= ShadeMode_FLAT
; // ODF default
366 // ODF has no dedicated property for 'surface'. MS Office binary format uses attribute
367 // c3DSpecularAmt to distinguish between 'matte' (=0) and 'plastic'.
369 double fOldSpecularity
= 0.0;
370 pAny
= rGeometryItem
.GetPropertyValueByName(sExtrusion
, u
"Specularity");
372 *pAny
>>= fOldSpecularity
;
373 double fSpecularity
= fOldSpecularity
;
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 %
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");
398 *pAny
>>= fOldDiffusion
;
399 double fDiffusion
= fOldDiffusion
;
402 if (fOldDiffusion
== 100.0)
403 fDiffusion
= 43712.0 / 655.36; // interpreted as %
407 if (basegfx::fTools::equalZero(fOldDiffusion
- 43712.0 / 655.36, 0.0001))
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
);
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?
459 fBrightness
= 33.0; // ODF default.
460 fLevel1
= 66.0; // ODF default
461 fLevel2
= 66.0; // ODF default
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
);
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
);
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();
534 case SID_EXTRUSION_TOGGLE
:
537 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ON_OFF
;
540 case SID_EXTRUSION_TILT_DOWN
:
543 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_DOWN
;
546 case SID_EXTRUSION_TILT_UP
:
549 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_UP
;
552 case SID_EXTRUSION_TILT_LEFT
:
555 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_LEFT
;
558 case SID_EXTRUSION_TILT_RIGHT
:
561 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_RIGHT
;
564 case SID_EXTRUSION_DIRECTION
:
567 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_ORIENTATION
;
570 case SID_EXTRUSION_PROJECTION
:
573 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_PROJECTION
;
576 case SID_EXTRUSION_DEPTH
:
579 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_DEPTH
;
582 case SID_EXTRUSION_3D_COLOR
:
585 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_COLOR
;
588 case SID_EXTRUSION_SURFACE
:
591 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_SURFACE
;
594 case SID_EXTRUSION_LIGHTING_INTENSITY
:
597 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_BRIGHTNESS
;
600 case SID_EXTRUSION_LIGHTING_DIRECTION
:
603 pStrResId
= RID_SVXSTR_UNDO_APPLY_EXTRUSION_LIGHTING
;
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 )
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();
628 // simulate a context change:
629 // force SelectionHasChanged() being called
630 // so that extrusion bar will be visible/hidden
631 pSdrView
->MarkListHasChanged();
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();
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
) );
660 if( nSID
!= SID_EXTRUSION_TOGGLE
)
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
,
674 SID_EXTRUSION_DIRECTION
,
675 SID_EXTRUSION_PROJECTION
,
676 SID_EXTRUSION_LIGHTING_DIRECTION
,
677 SID_EXTRUSION_LIGHTING_INTENSITY
,
678 SID_EXTRUSION_SURFACE
,
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
);
708 *pAny_
>>= bHasCustomShape
;
710 if( !bHasCustomShape
)
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
;
726 EnhancedCustomShapeParameterPair aSkewPropPair
;
727 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "Skew" );
728 if( pAny
&& ( *pAny
>>= aSkewPropPair
) )
730 aSkewPropPair
.First
.Value
>>= fSkew
;
731 aSkewPropPair
.Second
.Value
>>= fSkewAngle
;
735 else if ( fSkewAngle
== 0.0 )
740 double fOriginX
= 0.50;
741 double fOriginY
= -0.50;
742 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "ViewPoint" );
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
;
754 const double e
= 0.0001;
755 if( aViewPoint
.PositionX
> e
)
757 if( aViewPoint
.PositionY
> e
)
759 if( (fOriginX
> e
) && ( fOriginY
> e
) )
762 else if( aViewPoint
.PositionY
< -e
)
764 if( ( fOriginX
> e
) && ( fOriginY
< -e
) )
769 if( ( fOriginX
> e
) && ( fOriginY
> -e
) && ( fOriginY
< e
) )
773 else if( aViewPoint
.PositionX
< -e
)
775 if( aViewPoint
.PositionY
< -e
)
777 if( ( fOriginX
< -e
) && ( fOriginY
< -e
) )
780 else if( aViewPoint
.PositionY
> e
)
782 if( ( fOriginX
< -e
) && ( fOriginY
> e
) )
787 if( ( fOriginX
< e
) && ( fOriginY
> -e
) && ( fOriginY
< e
) )
793 if( aViewPoint
.PositionY
< -e
)
795 if( ( fOriginX
> -e
) && ( fOriginX
< e
) && ( fOriginY
< -e
) )
798 else if( aViewPoint
.PositionY
> e
)
800 if( ( fOriginX
> -e
) && ( fOriginX
< e
) && ( fOriginY
> e
) )
805 if( ( fOriginX
> -e
) && ( fOriginX
< e
) && ( fOriginY
> -e
) && ( fOriginY
< e
) )
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) )
825 if( bHasCustomShape
)
826 rSet
.Put( SfxInt32Item( SID_EXTRUSION_DIRECTION
, static_cast<sal_Int32
>(fFinalSkewAngle
) ) );
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
);
854 *pAny_
>>= bHasCustomShape
;
856 if( !bHasCustomShape
)
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;
880 if( bHasCustomShape
)
881 rSet
.Put( SfxInt32Item( SID_EXTRUSION_PROJECTION
, nFinalProjection
) );
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
);
910 *pAny_
>>= bHasCustomShape
;
912 if( !bHasCustomShape
)
916 sal_Int32 nSurface
= 0; // wire frame
918 ShadeMode
eShadeMode( ShadeMode_FLAT
);
919 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, u
"ShadeMode" );
921 *pAny
>>= eShadeMode
;
923 if (eShadeMode
!= ShadeMode_DRAFT
)
926 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, u
"Metal" );
932 nSurface
= 3; // metal ODF
933 sal_Int16 eMetalType
= EnhancedCustomShapeMetalType::MetalODF
;
934 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, u
"MetalType" );
937 *pAny
>>= eMetalType
;
938 if (eMetalType
== EnhancedCustomShapeMetalType::MetalMSCompatible
)
939 nSurface
= 4; // metal MS Office
944 double fSpecularity
= 0;
945 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, u
"Specularity" );
947 *pAny
>>= fSpecularity
;
949 const double e
= 0.0001;
950 if( (fSpecularity
> -e
) && (fSpecularity
< e
) )
952 nSurface
= 1; // matte
956 nSurface
= 2; // plastic
961 if( nFinalSurface
== -1 )
963 nFinalSurface
= nSurface
;
965 else if( nFinalSurface
!= nSurface
)
973 if( bHasCustomShape
)
974 rSet
.Put( SfxInt32Item( SID_EXTRUSION_SURFACE
, nFinalSurface
) );
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
);
1003 *pAny_
>>= bHasCustomShape
;
1005 if( !bHasCustomShape
)
1009 double fDepth
= 1270.0; // =36pt ODF default
1010 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "Depth" );
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
) )
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
) );
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)) )
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
);
1085 *pAny_
>>= bHasCustomShape
;
1087 if( !bHasCustomShape
)
1091 Direction3D
aFirstLightDirection( 50000, 0, 10000 );
1092 Direction3D
aSecondLightDirection( -50000, 0, 10000 );
1094 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "FirstLightDirection" );
1096 *pAny
>>= aFirstLightDirection
;
1098 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "SecondLightDirection" );
1100 *pAny
>>= aSecondLightDirection
;
1102 int nDirection
= -1;
1105 for( j
= 0; j
< 9; j
++ )
1107 if( compare_direction( aFirstLightDirection
, pLighting1Defaults
[j
] ) &&
1108 compare_direction( aSecondLightDirection
, pLighting2Defaults
[j
] ))
1115 if( nFinalDirection
== -1 )
1117 nFinalDirection
= nDirection
;
1119 else if( nDirection
!= nFinalDirection
)
1121 nFinalDirection
= -1;
1124 if( nFinalDirection
== -1 )
1129 if( bHasCustomShape
)
1130 rSet
.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_DIRECTION
, static_cast<sal_Int32
>(nFinalDirection
) ) );
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
);
1159 *pAny_
>>= bHasCustomShape
;
1161 if( !bHasCustomShape
)
1165 double fBrightness
= 22178.0 / 655.36;
1166 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "Brightness" );
1168 *pAny
>>= fBrightness
;
1171 if( fBrightness
>= 30.0 )
1173 nLevel
= 0; // Bright
1175 else if( fBrightness
>= 10.0 )
1177 nLevel
= 1; // Normal;
1184 if( nFinalLevel
== -1 )
1186 nFinalLevel
= nLevel
;
1188 else if( nFinalLevel
!= nLevel
)
1196 if( bHasCustomShape
)
1197 rSet
.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_INTENSITY
, nFinalLevel
) );
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
;
1212 bool bAmbigius
= false;
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
);
1228 *pAny_
>>= bHasCustomShape
;
1230 if( !bHasCustomShape
)
1236 bool bUseColor
= false;
1237 pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, "Color" );
1239 *pAny
>>= bUseColor
;
1243 const XSecondaryFillColorItem
& rItem
= pObj
->GetMergedItem( XATTR_SECONDARYFILLCOLOR
);
1244 aColor
= rItem
.GetColorValue();
1253 aFinalColor
= aColor
;
1256 else if( aFinalColor
!= aColor
)
1265 aFinalColor
= COL_AUTO
;
1267 if( bHasCustomShape
)
1268 rSet
.Put( SvxColorItem( aFinalColor
, SID_EXTRUSION_3D_COLOR
) );
1270 rSet
.DisableItem( SID_EXTRUSION_3D_COLOR
);
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 )
1289 const SdrCustomShapeGeometryItem
& rGeometryItem( pObj
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
1290 const Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sExtrusion
, sExtrusion
);
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: */