LibreOffice Module svx (master) 1
extrusionbar.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
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>
45
46#include <svx/extrusionbar.hxx>
48
49using namespace ::svx;
50using namespace ::cppu;
51using namespace ::com::sun::star::beans;
52using namespace ::com::sun::star::drawing;
53using namespace ::com::sun::star::uno;
54
55// Declare the default interface. (The slotmap must not be empty, so
56// we enter something which never occurs here (hopefully).)
58{
59 { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, "" }
60};
61
62SFX_IMPL_INTERFACE(ExtrusionBar, SfxShell)
63
64void ExtrusionBar::InitInterface_Impl()
65{
66 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Svx_Extrusion_Bar);
67}
68
69
70ExtrusionBar::ExtrusionBar(SfxViewShell* pViewShell )
71: SfxShell(pViewShell)
72{
73 DBG_ASSERT( pViewShell, "svx::ExtrusionBar::ExtrusionBar(), I need a viewshell!" );
74 if( pViewShell )
75 SetPool(&pViewShell->GetPool());
76
77 SetName(SvxResId(RID_SVX_EXTRUSION_BAR));
78}
79
81{
82 SetRepeatTarget(nullptr);
83}
84
85static void getLightingDirectionDefaults( const Direction3D **pLighting1Defaults, const Direction3D **pLighting2Defaults )
86{
87
88 static const Direction3D aLighting1Defaults[9] =
89 {
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 )
99 };
100
101 static const Direction3D aLighting2Defaults[9] =
102 {
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 )
112 };
113
114 *pLighting1Defaults = aLighting1Defaults;
115 *pLighting2Defaults = aLighting2Defaults;
116};
117
118static void impl_execute( SfxRequest const & rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
119{
120 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
121 static constexpr OUStringLiteral sRotateAngle = u"RotateAngle";
122
123 sal_uInt16 nSID = rReq.GetSlot();
124 switch( nSID )
125 {
126 case SID_EXTRUSION_TOGGLE:
127 {
128 bool bOn(false);
129 css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
130 if ( pAny )
131 {
132 (*pAny) >>= bOn;
133 bOn = !bOn;
134 css::beans::PropertyValue aPropValue;
135 aPropValue.Name = sExtrusion;
136 aPropValue.Value <<= bOn;
137 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
138 }
139 else
140 {
141 css::beans::PropertyValue aPropValue;
142 aPropValue.Name = sExtrusion;
143 aPropValue.Value <<= true;
144 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
145 bOn = true;
146 }
147
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)
154 {
155 pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Diffusion");
156 if (!pAny)
157 {
158 css::beans::PropertyValue aPropValue;
159 aPropValue.Name = u"Diffusion";
160 aPropValue.Value <<= 100.0;
161 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
162 }
163 }
164 }
165 break;
166
167 case SID_EXTRUSION_TILT_DOWN:
168 case SID_EXTRUSION_TILT_UP:
169 case SID_EXTRUSION_TILT_LEFT:
170 case SID_EXTRUSION_TILT_RIGHT:
171 {
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 ) )
183 {
184 aRotateAnglePropPair.First.Value >>= fX;
185 aRotateAnglePropPair.Second.Value >>= fY;
186 }
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 );
197 }
198 break;
199
200 case SID_EXTRUSION_DIRECTION:
201 {
202 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DIRECTION ) == SfxItemState::SET )
203 {
204 sal_Int32 nSkew = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_DIRECTION)->GetValue();
205
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;
211
212 switch( nSkew )
213 {
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;
255 }
256
257 css::beans::PropertyValue aPropValue;
258
259 aPropValue.Name = "ViewPoint";
260 aPropValue.Value <<= aViewPoint;
261 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
262
263
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 );
272
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 );
281 }
282 }
283 break;
284 case SID_EXTRUSION_PROJECTION:
285 {
286 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_PROJECTION ) == SfxItemState::SET )
287 {
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 );
294 }
295 }
296 break;
297 case SID_EXTRUSION_DEPTH:
298 {
299 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH ) == SfxItemState::SET)
300 {
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;
307
308 css::beans::PropertyValue aPropValue;
309 aPropValue.Name = "Depth";
310 aPropValue.Value <<= aDepthPropPair;
311 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
312 }
313 }
314 break;
315 case SID_EXTRUSION_3D_COLOR:
316 {
317 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_3D_COLOR ) == SfxItemState::SET)
318 {
319 Color aColor( static_cast<const SvxColorItem&>(rReq.GetArgs()->Get(SID_EXTRUSION_3D_COLOR)).GetValue() );
320
321 const bool bAuto = aColor == COL_AUTO;
322
323 css::beans::PropertyValue aPropValue;
324 aPropValue.Name = "Color";
325 aPropValue.Value <<= !bAuto;
326 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
327
328 if( bAuto )
329 {
331 }
332 else
333 {
334 pObj->SetMergedItem( XSecondaryFillColorItem( "", aColor ) );
335 }
336 pObj->BroadcastObjectChange();
337 }
338 }
339 break;
340 case SID_EXTRUSION_SURFACE:
341 {
342 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_SURFACE ) == SfxItemState::SET)
343 {
344 sal_Int32 nSurface = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_SURFACE)->GetValue();
345
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)
353 {
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;
364 }
365
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 )
375 {
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;
389 }
390
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)
401 {
402 if (fOldDiffusion == 100.0)
403 fDiffusion = 43712.0 / 655.36; // interpreted as %
404 }
405 else
406 {
407 if (basegfx::fTools::equalZero(fOldDiffusion - 43712.0 / 655.36, 0.0001))
408 fDiffusion = 100.0;
409 }
410
411 css::beans::PropertyValue aPropValue;
412 aPropValue.Name = "ShadeMode";
413 aPropValue.Value <<= eShadeMode;
414 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
415
416 aPropValue.Name = "Metal";
417 aPropValue.Value <<= nSurface == 3 || nSurface == 4;
418 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
419
420 if (nSurface == 3 || nSurface == 4)
421 {
422 aPropValue.Name = "MetalType";
423 aPropValue.Value <<= nSurface == 4
424 ? EnhancedCustomShapeMetalType::MetalMSCompatible
425 : EnhancedCustomShapeMetalType::MetalODF;
426 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
427 }
428
429 if (!basegfx::fTools::equalZero(fOldSpecularity - fSpecularity, 0.0001))
430 {
431 aPropValue.Name = "Specularity";
432 aPropValue.Value <<= fSpecularity;
433 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
434 }
435
436 if (!basegfx::fTools::equalZero(fOldDiffusion - fDiffusion, 0.0001))
437 {
438 aPropValue.Name = "Diffusion";
439 aPropValue.Value <<= fDiffusion;
440 rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
441 }
442 }
443 }
444 break;
445 case SID_EXTRUSION_LIGHTING_INTENSITY:
446 {
447 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_INTENSITY ) == SfxItemState::SET)
448 {
449 sal_Int32 nLevel = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_LIGHTING_INTENSITY)->GetValue();
450
451 double fBrightness; // c3DAmbientIntensity in MS Office
452 double fLevel1; // c3DKeyIntensity in MS Office
453 double fLevel2; // c3DFillIntensity in MS Office
454
455 // ToDo: "bright" values are different from MS Office. Should they be kept?
456 switch( nLevel )
457 {
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;
473 }
474
475 css::beans::PropertyValue aPropValue;
476 aPropValue.Name = "Brightness";
477 aPropValue.Value <<= fBrightness;
478 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
479
480 aPropValue.Name = "FirstLightLevel";
481 aPropValue.Value <<= fLevel1;
482 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
483
484 aPropValue.Name = "SecondLightLevel";
485 aPropValue.Value <<= fLevel2;
486 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
487
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);
493 }
494 }
495 break;
496 case SID_EXTRUSION_LIGHTING_DIRECTION:
497 {
498 if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_DIRECTION ) == SfxItemState::SET)
499 {
500 sal_Int32 nDirection = rReq.GetArgs()->GetItem<SfxInt32Item>(SID_EXTRUSION_LIGHTING_DIRECTION)->GetValue();
501
502 if((nDirection >= 0) && (nDirection < 9))
503 {
504 const Direction3D * pLighting1Defaults;
505 const Direction3D * pLighting2Defaults;
506
507 getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
508
509 css::beans::PropertyValue aPropValue;
510 aPropValue.Name = "FirstLightDirection";
511 aPropValue.Value <<= pLighting1Defaults[nDirection];
512 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
513
514 aPropValue.Name = "SecondLightDirection";
515 aPropValue.Value <<= pLighting2Defaults[nDirection];
516 rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
517 }
518 }
519 }
520 break;
521
522 }
523}
524
525void ExtrusionBar::execute( SdrView* pSdrView, SfxRequest const & rReq, SfxBindings& rBindings )
526{
527 sal_uInt16 nSID = rReq.GetSlot();
528 TranslateId pStrResId;
529
530 const bool bUndo = pSdrView && pSdrView->IsUndoEnabled();
531
532 switch( nSID )
533 {
534 case SID_EXTRUSION_TOGGLE:
535 {
536 if ( !pStrResId )
537 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ON_OFF;
538 [[fallthrough]];
539 }
540 case SID_EXTRUSION_TILT_DOWN:
541 {
542 if ( !pStrResId )
543 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_DOWN;
544 [[fallthrough]];
545 }
546 case SID_EXTRUSION_TILT_UP:
547 {
548 if ( !pStrResId )
549 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_UP;
550 [[fallthrough]];
551 }
552 case SID_EXTRUSION_TILT_LEFT:
553 {
554 if ( !pStrResId )
555 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_LEFT;
556 [[fallthrough]];
557 }
558 case SID_EXTRUSION_TILT_RIGHT:
559 {
560 if ( !pStrResId )
561 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_RIGHT;
562 [[fallthrough]];
563 }
564 case SID_EXTRUSION_DIRECTION:
565 {
566 if ( !pStrResId )
567 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ORIENTATION;
568 [[fallthrough]];
569 }
570 case SID_EXTRUSION_PROJECTION:
571 {
572 if ( !pStrResId )
573 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_PROJECTION;
574 [[fallthrough]];
575 }
576 case SID_EXTRUSION_DEPTH:
577 {
578 if ( !pStrResId )
579 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_DEPTH;
580 [[fallthrough]];
581 }
582 case SID_EXTRUSION_3D_COLOR:
583 {
584 if ( !pStrResId )
585 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_COLOR;
586 [[fallthrough]];
587 }
588 case SID_EXTRUSION_SURFACE:
589 {
590 if ( !pStrResId )
591 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_SURFACE;
592 [[fallthrough]];
593 }
594 case SID_EXTRUSION_LIGHTING_INTENSITY:
595 {
596 if ( !pStrResId )
597 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_BRIGHTNESS;
598 [[fallthrough]];
599 }
600 case SID_EXTRUSION_LIGHTING_DIRECTION:
601 {
602 if ( !pStrResId )
603 pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_LIGHTING;
604
605 if (pSdrView)
606 {
607 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
608 const size_t nCount = rMarkList.GetMarkCount();
609
610 for(size_t i=0; i<nCount; ++i)
611 {
612 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
613 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
614 {
615 if( bUndo )
616 {
617 OUString aStr( SvxResId( pStrResId ) );
618 pSdrView->BegUndo( aStr );
619 pSdrView->AddUndo( pSdrView->GetModel().GetSdrUndoFactory().CreateUndoAttrObject( *pObj ) );
620 }
622 impl_execute( rReq, aGeometryItem, pObj );
623 pObj->SetMergedItem( aGeometryItem );
624 pObj->BroadcastObjectChange();
625 if( bUndo )
626 pSdrView->EndUndo();
627
628 // simulate a context change:
629 // force SelectionHasChanged() being called
630 // so that extrusion bar will be visible/hidden
631 pSdrView->MarkListHasChanged();
632 }
633 }
634 }
635 }
636 break;
637
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))
642 {
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());
645
646 ExtrusionDepthDialog aDlg(rReq.GetFrameWeld(), fDepth, eUnit);
647 sal_uInt16 nRet = aDlg.run();
648 if (nRet == RET_OK)
649 {
650 fDepth = aDlg.getDepth();
651
652 SvxDoubleItem aItem( fDepth, SID_EXTRUSION_DEPTH );
653 SfxPoolItem* aItems[] = { &aItem, nullptr };
654 rBindings.Execute( SID_EXTRUSION_DEPTH, const_cast<const SfxPoolItem**>(aItems) );
655 }
656 }
657 break;
658 }
659
660 if( nSID != SID_EXTRUSION_TOGGLE )
661 return;
662
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 };
680
681 rBindings.Invalidate( SidArray );
682}
683
684static void getExtrusionDirectionState( SdrView const * pSdrView, SfxItemSet& rSet )
685{
686 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
687 const size_t nCount = rMarkList.GetMarkCount();
688
689 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
690
691 const css::uno::Any* pAny;
692
693 double fFinalSkewAngle = -1;
694 bool bHasCustomShape = false;
695
696 for(size_t i=0; i<nCount; ++i)
697 {
698 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
699 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
700 {
702
703 // see if this is an extruded customshape
704 if( !bHasCustomShape )
705 {
706 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
707 if( pAny_ )
708 *pAny_ >>= bHasCustomShape;
709
710 if( !bHasCustomShape )
711 continue;
712 }
713
714 bool bParallel = true;
715 Position3D aViewPoint( 3472, -3472, 25000 ); // MSO default
716 double fSkewAngle = -135; // MSO default
717
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;
722
723 if( bParallel )
724 {
725 double fSkew = 50.0;
726 EnhancedCustomShapeParameterPair aSkewPropPair;
727 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Skew" );
728 if( pAny && ( *pAny >>= aSkewPropPair ) )
729 {
730 aSkewPropPair.First.Value >>= fSkew;
731 aSkewPropPair.Second.Value >>= fSkewAngle;
732 }
733 if ( fSkew == 0.0 )
734 fSkewAngle = 0.0;
735 else if ( fSkewAngle == 0.0 )
736 fSkewAngle = -360.0;
737 }
738 else
739 {
740 double fOriginX = 0.50;
741 double fOriginY = -0.50;
742 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "ViewPoint" );
743 if( pAny )
744 *pAny >>= aViewPoint;
745
746 EnhancedCustomShapeParameterPair aOriginPropPair;
747 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Origin" );
748 if( pAny && ( *pAny >>= aOriginPropPair ) )
749 {
750 aOriginPropPair.First.Value >>= fOriginX;
751 aOriginPropPair.Second.Value >>= fOriginY;
752 }
753 fSkewAngle = -1;
754 const double e = 0.0001;
755 if( aViewPoint.PositionX > e )
756 {
757 if( aViewPoint.PositionY > e )
758 {
759 if( (fOriginX > e ) && ( fOriginY > e ) )
760 fSkewAngle = 135.0;
761 }
762 else if( aViewPoint.PositionY < -e )
763 {
764 if( ( fOriginX > e ) && ( fOriginY < -e ) )
765 fSkewAngle = -135.0;
766 }
767 else
768 {
769 if( ( fOriginX > e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
770 fSkewAngle = 180.0;
771 }
772 }
773 else if( aViewPoint.PositionX < -e )
774 {
775 if( aViewPoint.PositionY < -e )
776 {
777 if( ( fOriginX < -e ) && ( fOriginY < -e ) )
778 fSkewAngle = -45.0;
779 }
780 else if( aViewPoint.PositionY > e )
781 {
782 if( ( fOriginX < -e ) && ( fOriginY > e ) )
783 fSkewAngle = 45.0;
784 }
785 else
786 {
787 if( ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
788 fSkewAngle = -360.0;
789 }
790 }
791 else
792 {
793 if( aViewPoint.PositionY < -e )
794 {
795 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY < -e ) )
796 fSkewAngle = -90.0;
797 }
798 else if( aViewPoint.PositionY > e )
799 {
800 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > e ) )
801 fSkewAngle = 90.0;
802 }
803 else
804 {
805 if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
806 fSkewAngle = 0.0;
807 }
808 }
809 }
810
811 if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
812 {
813 fFinalSkewAngle = fSkewAngle;
814 }
815 else if( !rtl::math::approxEqual(fSkewAngle, fFinalSkewAngle) )
816 {
817 fFinalSkewAngle = -1.0;
818 }
819
820 if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
821 break;
822 }
823 }
824
825 if( bHasCustomShape )
826 rSet.Put( SfxInt32Item( SID_EXTRUSION_DIRECTION, static_cast<sal_Int32>(fFinalSkewAngle) ) );
827 else
828 rSet.DisableItem( SID_EXTRUSION_DIRECTION );
829}
830
831static void getExtrusionProjectionState( SdrView const * pSdrView, SfxItemSet& rSet )
832{
833 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
834 const size_t nCount = rMarkList.GetMarkCount();
835
836 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
837
838 const css::uno::Any* pAny;
839
840 sal_Int32 nFinalProjection = -1;
841 bool bHasCustomShape = false;
842
843 for(size_t i=0; i<nCount; ++i)
844 {
845 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
846 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
847 {
848 // see if this is an extruded customshape
849 if( !bHasCustomShape )
850 {
852 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
853 if( pAny_ )
854 *pAny_ >>= bHasCustomShape;
855
856 if( !bHasCustomShape )
857 continue;
858 }
859
861
862 bool bParallel = true;
863 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "ProjectionMode" );
864 ProjectionMode eProjectionMode;
865 if( pAny && ( *pAny >>= eProjectionMode ) )
866 bParallel = eProjectionMode == ProjectionMode_PARALLEL;
867
868 if( nFinalProjection == -1 )
869 {
870 nFinalProjection = bParallel ? 1 : 0;
871 }
872 else if( nFinalProjection != (bParallel ? 1 : 0) )
873 {
874 nFinalProjection = -1;
875 break;
876 }
877 }
878 }
879
880 if( bHasCustomShape )
881 rSet.Put( SfxInt32Item( SID_EXTRUSION_PROJECTION, nFinalProjection ) );
882 else
883 rSet.DisableItem( SID_EXTRUSION_PROJECTION );
884}
885
886static void getExtrusionSurfaceState( SdrView const * pSdrView, SfxItemSet& rSet )
887{
888 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
889 const size_t nCount = rMarkList.GetMarkCount();
890
891 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
892
893 const css::uno::Any* pAny;
894
895 sal_Int32 nFinalSurface = -1;
896 bool bHasCustomShape = false;
897
898 for(size_t i=0; i<nCount; ++i)
899 {
900 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
901 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
902 {
904
905 // see if this is an extruded customshape
906 if( !bHasCustomShape )
907 {
908 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
909 if( pAny_ )
910 *pAny_ >>= bHasCustomShape;
911
912 if( !bHasCustomShape )
913 continue;
914 }
915
916 sal_Int32 nSurface = 0; // wire frame
917
918 ShadeMode eShadeMode( ShadeMode_FLAT );
919 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ShadeMode" );
920 if( pAny )
921 *pAny >>= eShadeMode;
922
923 if (eShadeMode != ShadeMode_DRAFT)
924 {
925 bool bMetal = false;
926 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Metal" );
927 if( pAny )
928 *pAny >>= bMetal;
929
930 if( bMetal )
931 {
932 nSurface = 3; // metal ODF
933 sal_Int16 eMetalType = EnhancedCustomShapeMetalType::MetalODF;
934 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"MetalType" );
935 if (pAny)
936 {
937 *pAny >>= eMetalType;
938 if (eMetalType == EnhancedCustomShapeMetalType::MetalMSCompatible)
939 nSurface = 4; // metal MS Office
940 }
941 }
942 else
943 {
944 double fSpecularity = 0;
945 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Specularity" );
946 if( pAny )
947 *pAny >>= fSpecularity;
948
949 const double e = 0.0001;
950 if( (fSpecularity > -e) && (fSpecularity < e) )
951 {
952 nSurface = 1; // matte
953 }
954 else
955 {
956 nSurface = 2; // plastic
957 }
958 }
959 }
960
961 if( nFinalSurface == -1 )
962 {
963 nFinalSurface = nSurface;
964 }
965 else if( nFinalSurface != nSurface )
966 {
967 nFinalSurface = -1;
968 break;
969 }
970 }
971 }
972
973 if( bHasCustomShape )
974 rSet.Put( SfxInt32Item( SID_EXTRUSION_SURFACE, nFinalSurface ) );
975 else
976 rSet.DisableItem( SID_EXTRUSION_SURFACE );
977}
978
979static void getExtrusionDepthState( SdrView const * pSdrView, SfxItemSet& rSet )
980{
981 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
982 const size_t nCount = rMarkList.GetMarkCount();
983
984 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
985
986 const css::uno::Any* pAny;
987
988 double fFinalDepth = -1;
989 bool bHasCustomShape = false;
990
991 for(size_t i=0; i<nCount; ++i)
992 {
993 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
994 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
995 {
997
998 // see if this is an extruded customshape
999 if( !bHasCustomShape )
1000 {
1001 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1002 if( pAny_ )
1003 *pAny_ >>= bHasCustomShape;
1004
1005 if( !bHasCustomShape )
1006 continue;
1007 }
1008
1009 double fDepth = 1270.0; // =36pt ODF default
1010 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Depth" );
1011 if( pAny )
1012 {
1013 EnhancedCustomShapeParameterPair aDepthPropPair;
1014 if ( *pAny >>= aDepthPropPair )
1015 aDepthPropPair.First.Value >>= fDepth;
1016 }
1017
1018 if( fFinalDepth == -1 )
1019 {
1020 fFinalDepth = fDepth;
1021 }
1022 else if( !rtl::math::approxEqual(fFinalDepth, fDepth) )
1023 {
1024 fFinalDepth = -1;
1025 break;
1026 }
1027 }
1028 }
1029
1030
1031 FieldUnit eUnit = pSdrView->GetModel().GetUIUnit();
1032 rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast<sal_uInt16>(eUnit) ) );
1033
1034 if( bHasCustomShape )
1035 rSet.Put( SvxDoubleItem( fFinalDepth, SID_EXTRUSION_DEPTH ) );
1036 else
1037 rSet.DisableItem( SID_EXTRUSION_DEPTH );
1038}
1039
1040static bool compare_direction( const Direction3D& d1, const Direction3D& d2 )
1041{
1042 if( ((d1.DirectionX < 0) && (d2.DirectionX < 0)) || ((d1.DirectionX == 0) && (d2.DirectionX == 0)) || ((d1.DirectionX > 0) && (d2.DirectionX > 0)) )
1043 {
1044 if( ((d1.DirectionY < 0) && (d2.DirectionY < 0)) || ((d1.DirectionY == 0) && (d2.DirectionY == 0)) || ((d1.DirectionY > 0) && (d2.DirectionY > 0)) )
1045 {
1046 if( ((d1.DirectionZ < 0) && (d2.DirectionZ < 0)) || ((d1.DirectionZ == 0) && (d2.DirectionZ == 0)) || ((d1.DirectionZ > 0) && (d2.DirectionZ > 0)) )
1047 {
1048 return true;
1049 }
1050 }
1051 }
1052
1053 return false;
1054}
1055
1056static void getExtrusionLightingDirectionState( SdrView const * pSdrView, SfxItemSet& rSet )
1057{
1058 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1059 const size_t nCount = rMarkList.GetMarkCount();
1060
1061 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1062
1063 const Direction3D * pLighting1Defaults;
1064 const Direction3D * pLighting2Defaults;
1065
1066 getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
1067
1068 const css::uno::Any* pAny;
1069
1070 int nFinalDirection = -1;
1071 bool bHasCustomShape = false;
1072
1073 for(size_t i=0; i<nCount; ++i)
1074 {
1075 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1076 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1077 {
1079
1080 // see if this is an extruded customshape
1081 if( !bHasCustomShape )
1082 {
1083 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1084 if( pAny_ )
1085 *pAny_ >>= bHasCustomShape;
1086
1087 if( !bHasCustomShape )
1088 continue;
1089 }
1090
1091 Direction3D aFirstLightDirection( 50000, 0, 10000 );
1092 Direction3D aSecondLightDirection( -50000, 0, 10000 );
1093
1094 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "FirstLightDirection" );
1095 if( pAny )
1096 *pAny >>= aFirstLightDirection;
1097
1098 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "SecondLightDirection" );
1099 if( pAny )
1100 *pAny >>= aSecondLightDirection;
1101
1102 int nDirection = -1;
1103
1104 int j;
1105 for( j = 0; j < 9; j++ )
1106 {
1107 if( compare_direction( aFirstLightDirection, pLighting1Defaults[j] ) &&
1108 compare_direction( aSecondLightDirection, pLighting2Defaults[j] ))
1109 {
1110 nDirection = j;
1111 break;
1112 }
1113 }
1114
1115 if( nFinalDirection == -1 )
1116 {
1117 nFinalDirection = nDirection;
1118 }
1119 else if( nDirection != nFinalDirection )
1120 {
1121 nFinalDirection = -1;
1122 }
1123
1124 if( nFinalDirection == -1 )
1125 break;
1126 }
1127 }
1128
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 );
1133}
1134
1135static void getExtrusionLightingIntensityState( SdrView const * pSdrView, SfxItemSet& rSet )
1136{
1137 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1138 const size_t nCount = rMarkList.GetMarkCount();
1139
1140 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1141
1142 const css::uno::Any* pAny;
1143
1144 int nFinalLevel = -1;
1145 bool bHasCustomShape = false;
1146
1147 for(size_t i=0; i<nCount; ++i)
1148 {
1149 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1150 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1151 {
1153
1154 // see if this is an extruded customshape
1155 if( !bHasCustomShape )
1156 {
1157 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1158 if( pAny_ )
1159 *pAny_ >>= bHasCustomShape;
1160
1161 if( !bHasCustomShape )
1162 continue;
1163 }
1164
1165 double fBrightness = 22178.0 / 655.36;
1166 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Brightness" );
1167 if( pAny )
1168 *pAny >>= fBrightness;
1169
1170 int nLevel;
1171 if( fBrightness >= 30.0 )
1172 {
1173 nLevel = 0; // Bright
1174 }
1175 else if( fBrightness >= 10.0 )
1176 {
1177 nLevel = 1; // Normal;
1178 }
1179 else
1180 {
1181 nLevel = 2; // Dim
1182 }
1183
1184 if( nFinalLevel == -1 )
1185 {
1186 nFinalLevel = nLevel;
1187 }
1188 else if( nFinalLevel != nLevel )
1189 {
1190 nFinalLevel = -1;
1191 break;
1192 }
1193 }
1194 }
1195
1196 if( bHasCustomShape )
1197 rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_INTENSITY, nFinalLevel ) );
1198 else
1199 rSet.DisableItem( SID_EXTRUSION_LIGHTING_INTENSITY );
1200}
1201
1202static void getExtrusionColorState( SdrView const * pSdrView, SfxItemSet& rSet )
1203{
1204 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1205 const size_t nCount = rMarkList.GetMarkCount();
1206
1207 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1208
1209 const css::uno::Any* pAny;
1210
1211 bool bInit = false;
1212 bool bAmbigius = false;
1213 Color aFinalColor;
1214 bool bHasCustomShape = false;
1215
1216 for(size_t i=0; i<nCount; ++i)
1217 {
1218 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1219 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1220 {
1222
1223 // see if this is an extruded customshape
1224 if( !bHasCustomShape )
1225 {
1226 const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1227 if( pAny_ )
1228 *pAny_ >>= bHasCustomShape;
1229
1230 if( !bHasCustomShape )
1231 continue;
1232 }
1233
1234 Color aColor;
1235
1236 bool bUseColor = false;
1237 pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, "Color" );
1238 if( pAny )
1239 *pAny >>= bUseColor;
1240
1241 if( bUseColor )
1242 {
1244 aColor = rItem.GetColorValue();
1245 }
1246 else
1247 {
1248 aColor = COL_AUTO;
1249 }
1250
1251 if( !bInit )
1252 {
1253 aFinalColor = aColor;
1254 bInit = true;
1255 }
1256 else if( aFinalColor != aColor )
1257 {
1258 bAmbigius = true;
1259 break;
1260 }
1261 }
1262 }
1263
1264 if( bAmbigius )
1265 aFinalColor = COL_AUTO;
1266
1267 if( bHasCustomShape )
1268 rSet.Put( SvxColorItem( aFinalColor, SID_EXTRUSION_3D_COLOR ) );
1269 else
1270 rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
1271}
1272
1273namespace svx {
1274bool checkForSelectedCustomShapes( SdrView const * pSdrView, bool bOnlyExtruded )
1275{
1276 static constexpr OUStringLiteral sExtrusion = u"Extrusion";
1277
1278 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1279 const size_t nCount = rMarkList.GetMarkCount();
1280 bool bFound = false;
1281
1282 for(size_t i=0;(i<nCount) && !bFound ; ++i)
1283 {
1284 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1285 if( dynamic_cast<const SdrObjCustomShape*>( pObj) != nullptr )
1286 {
1287 if( bOnlyExtruded )
1288 {
1290 const Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1291 if( pAny )
1292 *pAny >>= bFound;
1293 }
1294 else
1295 {
1296 bFound = true;
1297 }
1298 }
1299 }
1300
1301 return bFound;
1302}
1303}
1304
1305void ExtrusionBar::getState( SdrView const * pSdrView, SfxItemSet& rSet )
1306{
1307 getExtrusionDirectionState( pSdrView, rSet );
1308 getExtrusionProjectionState( pSdrView, rSet );
1309
1310 const bool bOnlyExtrudedCustomShapes(checkForSelectedCustomShapes( pSdrView, true ));
1311
1312 if (! bOnlyExtrudedCustomShapes)
1313 {
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 );
1324 }
1325
1326 if( !checkForSelectedCustomShapes( pSdrView, false ) )
1327 rSet.DisableItem( SID_EXTRUSION_TOGGLE );
1328
1329 getExtrusionDepthState( pSdrView, rSet );
1330 getExtrusionSurfaceState( pSdrView, rSet );
1333 getExtrusionColorState( pSdrView, rSet );
1334}
1335
1336/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetPropertyValue(const css::beans::PropertyValue &rPropVal)
css::uno::Any * GetPropertyValueByName(const OUString &rPropName)
bool IsUndoEnabled() const
Definition: svdedtv.cxx:1056
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdedtv.hxx:196
void BegUndo()
Definition: svdedtv.hxx:178
void EndUndo()
Definition: svdedtv.cxx:295
size_t GetMarkCount() const
Definition: svdmark.hxx:178
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:230
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:258
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:68
FieldUnit GetUIUnit() const
Definition: svdmodel.hxx:380
SdrUndoFactory & GetSdrUndoFactory() const
returns the models undo factory.
Definition: svdmodel.cxx:1915
virtual void MarkListHasChanged() override
Definition: svdedxv.cxx:2647
Abstract DrawObject.
Definition: svdobj.hxx:260
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:2009
void BroadcastObjectChange() const
Definition: svdobj.cxx:1018
void ClearMergedItem(const sal_uInt16 nWhich=0)
Definition: svdobj.cxx:1989
void SetMergedItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1984
SdrModel & GetModel() const
Definition: svdpntv.hxx:282
virtual std::unique_ptr< SdrUndoAction > CreateUndoAttrObject(SdrObject &rObject, bool bStyleSheet1=false, bool bSaveText=false)
Definition: svdundo.cxx:1679
bool Execute(sal_uInt16 nSlot, const SfxPoolItem **pArgs=nullptr, SfxCallMode nCall=SfxCallMode::SLOT)
void Invalidate(sal_uInt16 nId)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
void DisableItem(sal_uInt16 nWhich)
sal_uInt16 GetSlot() const
const SfxItemSet * GetArgs() const
weld::Window * GetFrameWeld() const
SfxItemPool & GetPool() const
void SetRepeatTarget(SfxRepeatTarget *pTarget)
void SetPool(SfxItemPool *pNewPool)
void SetName(const OUString &rName)
const Color & GetValue() const
const Color & GetColorValue() const
Definition: xattr.cxx:302
static void execute(SdrView *pSdrView, SfxRequest const &rReq, SfxBindings &rBindings)
virtual ~ExtrusionBar() override
static void getState(SdrView const *pSdrView, SfxItemSet &rSet)
virtual short run()
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
int nCount
#define DBG_ASSERT(sCon, aError)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
float u
static SfxSlot aExtrusionBarSlots_Impl[]
static void getExtrusionDepthState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getExtrusionSurfaceState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getExtrusionLightingDirectionState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getLightingDirectionDefaults(const Direction3D **pLighting1Defaults, const Direction3D **pLighting2Defaults)
static void getExtrusionProjectionState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getExtrusionLightingIntensityState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getExtrusionColorState(SdrView const *pSdrView, SfxItemSet &rSet)
static void getExtrusionDirectionState(SdrView const *pSdrView, SfxItemSet &rSet)
static bool compare_direction(const Direction3D &d1, const Direction3D &d2)
FieldUnit
aStr
bool equalZero(const T &rfVal)
int i
const sal_uInt16 SidArray[]
bool checkForSelectedCustomShapes(SdrView const *pSdrView, bool bOnlyExtruded)
static void impl_execute(SfxRequest const &rReq, SdrCustomShapeGeometryItem &rGeometryItem, SdrObject *pObj)
static bool bInit
Definition: objfac3d.cxx:30
#define SFX_OBJECTBAR_OBJECT
const char GetValue[]
static SfxItemSet & rSet
#define SFX_IMPL_INTERFACE(Class, SuperClass)
constexpr TypedWhichId< SdrCustomShapeGeometryItem > SDRATTR_CUSTOMSHAPE_GEOMETRY(SDRATTR_CUSTOMSHAPE_FIRST+2)
RET_OK
constexpr TypedWhichId< XSecondaryFillColorItem > XATTR_SECONDARYFILLCOLOR(XATTR_FILL_FIRST+12)