xref: /trunk/main/svx/source/toolbars/extrusionbar.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #ifndef _COM_SUN_STAR_DRAWING_ENHANCEDCUSTOMSHAPEPARAMETERPARIR_HPP_
32 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
33 #endif
34 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
35 #include <com/sun/star/drawing/ShadeMode.hpp>
36 #include <com/sun/star/drawing/Position3D.hpp>
37 #include <com/sun/star/drawing/Direction3D.hpp>
38 #include <com/sun/star/drawing/ProjectionMode.hpp>
39 #include <svx/svdundo.hxx>
40 #include <sfx2/app.hxx>
41 #include <sfx2/request.hxx>
42 #include <sfx2/objface.hxx>
43 #include <sfx2/viewsh.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <svx/xsflclit.hxx>
46 #include <svx/dialmgr.hxx>
47 #include <svx/svdoashp.hxx>
48 #ifndef _SVX_DIALOGS_HRC
49 #include <svx/dialogs.hrc>
50 #endif
51 #include <svx/svdview.hxx>
52 #include <editeng/colritem.hxx>
53 #include "svx/chrtitem.hxx"
54 
55 #include <svx/extrusionbar.hxx>
56 #include "extrusiondepthdialog.hxx"
57 
58 
59 using namespace ::svx;
60 using namespace ::rtl;
61 using namespace ::cppu;
62 using namespace ::com::sun::star::beans;
63 using namespace ::com::sun::star::drawing;
64 using namespace ::com::sun::star::uno;
65 
66 /*************************************************************************
67 |*
68 |* Standardinterface deklarieren (Die Slotmap darf nicht leer sein, also
69 |* tragen wir etwas ein, was hier (hoffentlich) nie vorkommt).
70 |*
71 \************************************************************************/
72 
73 #define ShellClass ExtrusionBar
74 
75 SFX_SLOTMAP(ExtrusionBar)
76 {
77             { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
78 };
79 
80 SFX_IMPL_INTERFACE(ExtrusionBar, SfxShell, SVX_RES(RID_SVX_EXTRUSION_BAR))
81 {
82     SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT, SVX_RES(RID_SVX_EXTRUSION_BAR) );
83 }
84 
85 TYPEINIT1( ExtrusionBar, SfxShell );
86 
87 
88 /*************************************************************************
89 |*
90 |* Standard-Konstruktor
91 |*
92 \************************************************************************/
93 
94 ExtrusionBar::ExtrusionBar(SfxViewShell* pViewShell )
95 : SfxShell(pViewShell)
96 {
97     DBG_ASSERT( pViewShell, "svx::ExtrusionBar::ExtrusionBar(), I need a viewshell!" );
98     if( pViewShell )
99         SetPool(&pViewShell->GetPool());
100 
101     SetHelpId( SVX_INTERFACE_EXTRUSION_BAR );
102     SetName( String( SVX_RES( RID_SVX_EXTRUSION_BAR )));
103 }
104 
105 
106 /*************************************************************************
107 |*
108 |* Destruktor
109 |*
110 \************************************************************************/
111 
112 ExtrusionBar::~ExtrusionBar()
113 {
114     SetRepeatTarget(NULL);
115 }
116 
117 void getLightingDirectionDefaults( const Direction3D **pLighting1Defaults, const Direction3D **pLighting2Defaults )
118 {
119 
120     static const Direction3D aLighting1Defaults[9] =
121     {
122         Direction3D( -50000, -50000, 10000 ),
123         Direction3D( 0, -50000, 10000 ),
124         Direction3D( 50000, -50000, 10000 ),
125         Direction3D( -50000, 0, 10000 ),
126         Direction3D( 0, 0, 10000 ),
127         Direction3D( 50000, 0, 10000 ),
128         Direction3D( -50000, 50000, 10000 ),
129         Direction3D( 0, 50000, 10000 ),
130         Direction3D( 50000, 50000, 10000 )
131     };
132 
133     static const Direction3D aLighting2Defaults[9] =
134     {
135         Direction3D( 50000,0, 10000 ),
136         Direction3D( 0, 50000, 10000 ),
137         Direction3D( -50000, 0, 10000 ),
138         Direction3D( 50000, 0, 10000 ),
139         Direction3D( 0, 0, 10000 ),
140         Direction3D( -50000, 0, 10000 ),
141         Direction3D( 50000, 0, 10000 ),
142         Direction3D( 0, -50000, 10000 ),
143         Direction3D( -50000, 0, 10000 )
144     };
145 
146     *pLighting1Defaults = (const Direction3D *)aLighting1Defaults;
147     *pLighting2Defaults = (const Direction3D *)aLighting2Defaults;
148 };
149 
150 static void impl_execute( SdrView*, SfxRequest& rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
151 {
152     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
153     static const rtl::OUString  sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
154     static const rtl::OUString  sRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
155     static const rtl::OUString  sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
156     static const rtl::OUString  sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
157     static const rtl::OUString  sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
158     static const rtl::OUString  sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
159 
160     sal_uInt16 nSID = rReq.GetSlot();
161     switch( nSID )
162     {
163     case SID_EXTRUSION_TOOGLE:
164     {
165         com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
166 
167         if( pAny )
168         {
169             sal_Bool bOn;
170             (*pAny) >>= bOn;
171             bOn = !bOn;
172             (*pAny) <<= bOn;
173         }
174         else
175         {
176             com::sun::star::beans::PropertyValue aPropValue;
177             aPropValue.Name = sExtrusion;
178             aPropValue.Value <<= sal_True;
179             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
180         }
181     }
182     break;
183 
184     case SID_EXTRUSION_TILT_DOWN:
185     case SID_EXTRUSION_TILT_UP:
186     case SID_EXTRUSION_TILT_LEFT:
187     case SID_EXTRUSION_TILT_RIGHT:
188     {
189         sal_Bool bHorizontal = ( nSID == SID_EXTRUSION_TILT_DOWN ) || ( nSID == SID_EXTRUSION_TILT_UP );
190         sal_Int32 nDiff = ( nSID == SID_EXTRUSION_TILT_LEFT ) || ( nSID == SID_EXTRUSION_TILT_UP ) ? 5 : -5;
191         EnhancedCustomShapeParameterPair aRotateAnglePropPair;
192         double fX = 0.0;
193         double fY = 0.0;
194         aRotateAnglePropPair.First.Value <<= fX;
195         aRotateAnglePropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
196         aRotateAnglePropPair.Second.Value <<= fY;
197         aRotateAnglePropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
198         com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sRotateAngle );
199         if( pAny && ( *pAny >>= aRotateAnglePropPair ) )
200         {
201             aRotateAnglePropPair.First.Value >>= fX;
202             aRotateAnglePropPair.Second.Value >>= fY;
203         }
204         if ( bHorizontal )
205             fX += nDiff;
206         else
207             fY += nDiff;
208         aRotateAnglePropPair.First.Value <<= fX;
209         aRotateAnglePropPair.Second.Value <<= fY;
210         com::sun::star::beans::PropertyValue aPropValue;
211         aPropValue.Name = sRotateAngle;
212         aPropValue.Value <<= aRotateAnglePropPair;
213         rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
214     }
215     break;
216 
217     case SID_EXTRUSION_DIRECTION:
218     {
219         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DIRECTION ) == SFX_ITEM_SET )
220         {
221             sal_Int32 nSkew = ((const SfxInt32Item*)rReq.GetArgs()->GetItem(SID_EXTRUSION_DIRECTION))->GetValue();
222 
223             Position3D  aViewPoint( 3472, -3472, 25000 );
224             double      fOriginX = 0.50;
225             double      fOriginY = -0.50;
226             double      fSkewAngle = nSkew;
227             double      fSkew = 50.0;
228 
229             switch( nSkew )
230             {
231             case 135:
232                 aViewPoint.PositionY = 3472;
233                 fOriginY = 0.50;
234                 break;
235             case 90:
236                 aViewPoint.PositionX = 0;
237                 aViewPoint.PositionY = 3472;
238                 fOriginX = 0;
239                 fOriginY = -0.50;
240                 break;
241             case 45:
242                 aViewPoint.PositionX = -3472;
243                 aViewPoint.PositionY = 3472;
244                 fOriginX = -0.50;
245                 fOriginY = 0.50;
246                 break;
247             case 180:
248                 aViewPoint.PositionY = 0;
249                 fOriginY = 0;
250                 break;
251             case 0:
252                 aViewPoint.PositionX = 0;
253                 aViewPoint.PositionY = 0;
254                 fOriginX = 0;
255                 fOriginY = 0;
256                 fSkew = 0.0;
257                 break;
258             case -360:
259                 aViewPoint.PositionX = -3472;
260                 aViewPoint.PositionY = 0;
261                 fOriginX = -0.50;
262                 fOriginY = 0;
263                 break;
264             case -90:
265                 aViewPoint.PositionX = 0;
266                 fOriginX = 0;
267                 break;
268             case -45:
269                 aViewPoint.PositionX = -3472;
270                 fOriginX = -0.50;
271                 break;
272             }
273 
274             com::sun::star::beans::PropertyValue aPropValue;
275 
276             aPropValue.Name = sViewPoint;
277             aPropValue.Value <<= aViewPoint;
278             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
279 
280 
281             EnhancedCustomShapeParameterPair aOriginPropPair;
282             aOriginPropPair.First.Value <<= fOriginX;
283             aOriginPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
284             aOriginPropPair.Second.Value <<= fOriginY;
285             aOriginPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
286             aPropValue.Name = sOrigin;
287             aPropValue.Value <<= aOriginPropPair;
288             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
289 
290             EnhancedCustomShapeParameterPair aSkewPropPair;
291             aSkewPropPair.First.Value <<= fSkew;
292             aSkewPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
293             aSkewPropPair.Second.Value <<= fSkewAngle;
294             aSkewPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
295             aPropValue.Name = sSkew;
296             aPropValue.Value <<= aSkewPropPair;
297             rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
298         }
299     }
300     break;
301     case SID_EXTRUSION_PROJECTION:
302     {
303         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_PROJECTION ) == SFX_ITEM_SET )
304         {
305             sal_Int32 nProjection = ((const SfxInt32Item*)rReq.GetArgs()->GetItem(SID_EXTRUSION_PROJECTION))->GetValue();
306             ProjectionMode eProjectionMode = nProjection == 1 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
307             com::sun::star::beans::PropertyValue aPropValue;
308             aPropValue.Name = sProjectionMode;
309             aPropValue.Value <<= eProjectionMode;
310             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
311         }
312     }
313     break;
314     case SID_EXTRUSION_DEPTH:
315     {
316         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH ) == SFX_ITEM_SET)
317         {
318             double fDepth = ((const SvxDoubleItem*)rReq.GetArgs()->GetItem(SID_EXTRUSION_DEPTH))->GetValue();
319             double fFraction = 0.0;
320             EnhancedCustomShapeParameterPair aDepthPropPair;
321             aDepthPropPair.First.Value <<= fDepth;
322             aDepthPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
323             aDepthPropPair.Second.Value <<= fFraction;
324             aDepthPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
325 
326             com::sun::star::beans::PropertyValue aPropValue;
327             aPropValue.Name = sDepth;
328             aPropValue.Value <<= aDepthPropPair;
329             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
330         }
331     }
332     break;
333     case SID_EXTRUSION_3D_COLOR:
334     {
335         static const rtl::OUString  sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
336 
337         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_3D_COLOR ) == SFX_ITEM_SET)
338         {
339             Color aColor( ((const SvxColorItem&)rReq.GetArgs()->Get(SID_EXTRUSION_3D_COLOR)).GetValue() );
340 
341             const bool bAuto = aColor == COL_AUTO;
342 
343             com::sun::star::beans::PropertyValue aPropValue;
344             aPropValue.Name = sExtrusionColor;
345             aPropValue.Value <<= bAuto ? sal_False : sal_True;
346             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
347 
348             if( bAuto )
349             {
350                 pObj->ClearMergedItem( XATTR_SECONDARYFILLCOLOR );
351             }
352             else
353             {
354                 pObj->SetMergedItem( XSecondaryFillColorItem( String(), aColor ) );
355             }
356             pObj->BroadcastObjectChange();
357         }
358     }
359     break;
360     case SID_EXTRUSION_SURFACE:
361     {
362         static const rtl::OUString sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
363         static const rtl::OUString sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
364         static const rtl::OUString sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
365         static const rtl::OUString sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
366 
367         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_SURFACE ) == SFX_ITEM_SET)
368         {
369             sal_Int32 nSurface = ((const SfxInt32Item*)rReq.GetArgs()->GetItem(SID_EXTRUSION_SURFACE))->GetValue();
370 
371             ShadeMode eShadeMode( ShadeMode_FLAT );
372             sal_Bool bMetal = sal_False;
373             double fSpecularity = 0;
374             double fDiffusion = 0;
375 
376             switch( nSurface )
377             {
378             case 0: // wireframe
379                 eShadeMode = ShadeMode_DRAFT;
380                 break;
381             case 1: // matte
382                 break;
383             case 2: // plastic
384                 fSpecularity = 122.0;
385                 break;
386             case 3: // metal
387                 bMetal = true;
388                 fSpecularity = 122.0;
389                 fDiffusion = 122.0;
390                 break;
391             }
392 
393             com::sun::star::beans::PropertyValue aPropValue;
394             aPropValue.Name = sShadeMode;
395             aPropValue.Value <<= eShadeMode;
396             rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
397 
398             aPropValue.Name = sMetal;
399             aPropValue.Value <<= bMetal;
400             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
401 
402             aPropValue.Name = sSpecularity;
403             aPropValue.Value <<= fSpecularity;
404             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
405 
406             aPropValue.Name = sDiffusion;
407             aPropValue.Value <<= fDiffusion;
408             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
409         }
410     }
411     break;
412     case SID_EXTRUSION_LIGHTING_INTENSITY:
413     {
414         static const rtl::OUString sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
415         static const rtl::OUString sLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
416         static const rtl::OUString sFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
417         static const rtl::OUString sSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
418         static const rtl::OUString sFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
419         static const rtl::OUString sSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
420 
421         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_INTENSITY ) == SFX_ITEM_SET)
422         {
423             sal_Int32 nLevel = ((const SfxInt32Item*)rReq.GetArgs()->GetItem(SID_EXTRUSION_LIGHTING_INTENSITY))->GetValue();
424 
425             double fBrightness;
426             sal_Bool bHarsh2;
427             double fLevel1;
428             double fLevel2;
429 
430             switch( nLevel )
431             {
432             case 0: // bright
433                 fBrightness = 34.0;
434                 bHarsh2 = sal_False;
435                 fLevel1 = 66.0;
436                 fLevel2 = 66.0;
437                 break;
438             case 1: // normal
439                 fBrightness = 15.0;
440                 bHarsh2 = sal_False;
441                 fLevel1 = 67.0;
442                 fLevel2 = 37.0;
443                 break;
444             case 2: // dim
445                 fBrightness = 6.0;
446                 bHarsh2 = sal_True;
447                 fLevel1 = 79.0;
448                 fLevel2 = 21.0;
449                 break;
450             }
451 
452             com::sun::star::beans::PropertyValue aPropValue;
453             aPropValue.Name = sBrightness;
454             aPropValue.Value <<= fBrightness;
455             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
456 
457             aPropValue.Name = sLightFace;
458             aPropValue.Value <<= sal_True;
459             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
460 
461             aPropValue.Name = sFirstLightHarsh;
462             aPropValue.Value <<= sal_True;
463             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
464 
465             aPropValue.Name = sSecondLightHarsh;
466             aPropValue.Value <<= bHarsh2;
467             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
468 
469             aPropValue.Name = sFirstLightLevel;
470             aPropValue.Value <<= fLevel1;
471             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
472 
473             aPropValue.Name = sSecondLightLevel;
474             aPropValue.Value <<= fLevel2;
475             rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
476         }
477     }
478     break;
479     case SID_EXTRUSION_LIGHTING_DIRECTION:
480     {
481         if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_DIRECTION ) == SFX_ITEM_SET)
482         {
483             sal_Int32 nDirection = ((const SfxInt32Item*)rReq.GetArgs()->GetItem(SID_EXTRUSION_LIGHTING_DIRECTION))->GetValue();
484 
485             if((nDirection >= 0) && (nDirection < 9))
486             {
487                 const rtl::OUString sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
488                 const rtl::OUString sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
489 
490                 const Direction3D * pLighting1Defaults;
491                 const Direction3D * pLighting2Defaults;
492 
493                 getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
494 
495                 com::sun::star::beans::PropertyValue aPropValue;
496                 aPropValue.Name = sFirstLightDirection;
497                 aPropValue.Value <<= pLighting1Defaults[nDirection];
498                 rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
499 
500                 aPropValue.Name = sSecondLightDirection;
501                 aPropValue.Value <<= pLighting2Defaults[nDirection];
502                 rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
503             }
504         }
505     }
506     break;
507 
508     }
509 }
510 
511 void ExtrusionBar::execute( SdrView* pSdrView, SfxRequest& rReq, SfxBindings& rBindings )
512 {
513     sal_uInt16 nSID = rReq.GetSlot();
514     sal_uInt16 nStrResId = 0;
515 
516     const bool bUndo = pSdrView && pSdrView->IsUndoEnabled();
517 
518     switch( nSID )
519     {
520         case SID_EXTRUSION_TOOGLE:
521         {
522             if ( !nStrResId )
523                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ON_OFF;
524         }   // PASSTROUGH
525         case SID_EXTRUSION_TILT_DOWN:
526         {
527             if ( !nStrResId )
528                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_DOWN;
529         }   // PASSTROUGH
530         case SID_EXTRUSION_TILT_UP:
531         {
532             if ( !nStrResId )
533                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_UP;
534         }   // PASSTROUGH
535         case SID_EXTRUSION_TILT_LEFT:
536         {
537             if ( !nStrResId )
538                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_LEFT;
539         }   // PASSTROUGH
540         case SID_EXTRUSION_TILT_RIGHT:
541         {
542             if ( !nStrResId )
543                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_RIGHT;
544         }   // PASSTROUGH
545         case SID_EXTRUSION_DIRECTION:
546         {
547             if ( !nStrResId )
548                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ORIENTATION;
549         }   // PASSTROUGH
550         case SID_EXTRUSION_PROJECTION:
551         {
552             if ( !nStrResId )
553                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_PROJECTION;
554         }   // PASSTROUGH
555         case SID_EXTRUSION_DEPTH:
556         {
557             if ( !nStrResId )
558                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_DEPTH;
559         }   // PASSTROUGH
560         case SID_EXTRUSION_3D_COLOR:
561         {
562             if ( !nStrResId )
563                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_COLOR;
564         }   // PASSTROUGH
565         case SID_EXTRUSION_SURFACE:
566         {
567             if ( !nStrResId )
568                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_SURFACE;
569         }   // PASSTROUGH
570         case SID_EXTRUSION_LIGHTING_INTENSITY:
571         {
572             if ( !nStrResId )
573                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_BRIGHTNESS;
574         }   // PASSTROUGH
575         case SID_EXTRUSION_LIGHTING_DIRECTION:
576         {
577             if ( !nStrResId )
578                 nStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_LIGHTING;
579 
580             const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
581             sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
582 
583             for(i=0; i<nCount; i++)
584             {
585                 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
586                 if( pObj->ISA(SdrObjCustomShape) )
587                 {
588                     if( bUndo )
589                     {
590                         String aStr( SVX_RES( nStrResId ) );
591                         pSdrView->BegUndo( aStr );
592                         pSdrView->AddUndo( pSdrView->GetModel()->GetSdrUndoFactory().CreateUndoAttrObject( *pObj ) );
593                     }
594                     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
595                     impl_execute( pSdrView, rReq, aGeometryItem, pObj );
596                     pObj->SetMergedItem( aGeometryItem );
597                     pObj->BroadcastObjectChange();
598                     if( bUndo )
599                         pSdrView->EndUndo();
600 
601                     // simulate a context change:
602                     // force SelectionHasChanged() being called
603                     // so that extrusion bar will be visible/hidden
604                     pSdrView->MarkListHasChanged();
605                 }
606             }
607         }
608         break;
609 
610         case SID_EXTRUSION_DEPTH_DIALOG:
611             if( rReq.GetArgs() &&
612                 (rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH ) == SFX_ITEM_SET) &&
613                 (rReq.GetArgs()->GetItemState( SID_ATTR_METRIC ) == SFX_ITEM_SET))
614             {
615                 double fDepth = ((const SvxDoubleItem*)rReq.GetArgs()->GetItem(SID_EXTRUSION_DEPTH))->GetValue();
616                 FieldUnit eUnit = (FieldUnit)((const SfxUInt16Item*)rReq.GetArgs()->GetItem(SID_ATTR_METRIC))->GetValue();
617 
618                 ExtrusionDepthDialog aDlg( 0L, fDepth, eUnit );
619                 sal_uInt16 nRet = aDlg.Execute();
620                 if( nRet != 0 )
621                 {
622                     fDepth = aDlg.getDepth();
623 
624                     SvxDoubleItem aItem( fDepth, SID_EXTRUSION_DEPTH );
625                     SfxPoolItem* aItems[] = { &aItem, 0 };
626                     rBindings.Execute( SID_EXTRUSION_DEPTH, (const SfxPoolItem**)aItems );
627                 }
628             }
629             break;
630     }
631 
632     if( nSID == SID_EXTRUSION_TOOGLE )
633     {
634             static sal_uInt16 SidArray[] = {
635                 SID_EXTRUSION_TILT_DOWN,
636                 SID_EXTRUSION_TILT_UP,
637                 SID_EXTRUSION_TILT_LEFT,
638                 SID_EXTRUSION_TILT_RIGHT,
639                 SID_EXTRUSION_DEPTH_FLOATER,
640                 SID_EXTRUSION_DIRECTION_FLOATER,
641                 SID_EXTRUSION_LIGHTING_FLOATER,
642                 SID_EXTRUSION_SURFACE_FLOATER,
643                 SID_EXTRUSION_3D_COLOR,
644                 SID_EXTRUSION_DEPTH,
645                 SID_EXTRUSION_DIRECTION,
646                 SID_EXTRUSION_PROJECTION,
647                 SID_EXTRUSION_LIGHTING_DIRECTION,
648                 SID_EXTRUSION_LIGHTING_INTENSITY,
649                 SID_EXTRUSION_SURFACE,
650                 0 };
651 
652         rBindings.Invalidate( SidArray );
653     }
654 }
655 
656 void getExtrusionDirectionState( SdrView* pSdrView, SfxItemSet& rSet )
657 {
658     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
659     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
660 
661     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
662     static const rtl::OUString  sViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
663     static const rtl::OUString  sOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
664     static const rtl::OUString  sSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
665     static const rtl::OUString  sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
666 
667     com::sun::star::uno::Any* pAny;
668 
669     double fFinalSkewAngle = -1;
670     bool bHasCustomShape = false;
671 
672     for(i=0;i<nCount; i++)
673     {
674         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
675         if( pObj->ISA(SdrObjCustomShape) )
676         {
677             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
678 
679             // see if this is an extruded customshape
680             if( !bHasCustomShape )
681             {
682                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
683                 if( pAny_ )
684                     *pAny_ >>= bHasCustomShape;
685 
686                 if( !bHasCustomShape )
687                     continue;
688             }
689 
690             sal_Bool    bParallel = sal_True;
691             Position3D  aViewPoint( 3472, -3472, 25000 );
692             double      fOriginX = 0.50;
693             double      fOriginY = -0.50;
694             double      fSkewAngle = -135;
695             double      fSkew = 50.0;
696 
697             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode );
698             sal_Int16 nProjectionMode = sal_Int16();
699             if( pAny && ( *pAny >>= nProjectionMode ) )
700                 bParallel = nProjectionMode == ProjectionMode_PARALLEL;
701 
702             if( bParallel )
703             {
704                 EnhancedCustomShapeParameterPair aSkewPropPair;
705                 pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sSkew );
706                 if( pAny && ( *pAny >>= aSkewPropPair ) )
707                 {
708                     aSkewPropPair.First.Value >>= fSkew;
709                     aSkewPropPair.Second.Value >>= fSkewAngle;
710                 }
711                 if ( fSkew == 0.0 )
712                     fSkewAngle = 0.0;
713                 else if ( fSkewAngle == 0.0 )
714                     fSkewAngle = -360.0;
715             }
716             else
717             {
718                 pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sViewPoint );
719                 if( pAny )
720                     *pAny >>= aViewPoint;
721 
722                 EnhancedCustomShapeParameterPair aOriginPropPair;
723                 pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sOrigin );
724                 if( pAny && ( *pAny >>= aOriginPropPair ) )
725                 {
726                     aOriginPropPair.First.Value >>= fOriginX;
727                     aOriginPropPair.Second.Value >>= fOriginY;
728                 }
729                 fSkewAngle = -1;
730                 const double e = 0.0001;
731                 if( aViewPoint.PositionX > e )
732                 {
733                     if( aViewPoint.PositionY > e )
734                     {
735                         if( (fOriginX > e ) && ( fOriginY > e ) )
736                             fSkewAngle = 135.0;
737                     }
738                     else if( aViewPoint.PositionY < -e )
739                     {
740                         if( ( fOriginX > e ) && ( fOriginY < -e ) )
741                             fSkewAngle = -135.0;
742                     }
743                     else
744                     {
745                         if( ( fOriginX > e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
746                             fSkewAngle = 180.0;
747                     }
748                 }
749                 else if( aViewPoint.PositionX < -e )
750                 {
751                     if( aViewPoint.PositionY < -e )
752                     {
753                         if( ( fOriginX < -e ) && ( fOriginY < -e ) )
754                             fSkewAngle = -45.0;
755                     }
756                     else if( aViewPoint.PositionY > e )
757                     {
758                         if( ( fOriginX < -e ) && ( fOriginY > e ) )
759                             fSkewAngle = 45.0;
760                     }
761                     else
762                     {
763                         if( ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
764                             fSkewAngle = -360.0;
765                     }
766                 }
767                 else
768                 {
769                     if( aViewPoint.PositionY < -e )
770                     {
771                         if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY < -e ) )
772                             fSkewAngle = -90.0;
773                     }
774                     else if( aViewPoint.PositionY > e )
775                     {
776                         if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > e ) )
777                             fSkewAngle = 90.0;
778                     }
779                     else
780                     {
781                         if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
782                             fSkewAngle = 0.0;
783                     }
784                 }
785             }
786 
787             if( fFinalSkewAngle == -1.0 )
788             {
789                 fFinalSkewAngle = fSkewAngle;
790             }
791             else if( fSkewAngle != fFinalSkewAngle )
792             {
793                 fFinalSkewAngle = -1.0;
794             }
795 
796             if( fFinalSkewAngle == -1.0 )
797                 break;
798         }
799     }
800 
801     if( bHasCustomShape )
802         rSet.Put( SfxInt32Item( SID_EXTRUSION_DIRECTION, (sal_Int32)fFinalSkewAngle ) );
803     else
804         rSet.DisableItem( SID_EXTRUSION_DIRECTION );
805 }
806 
807 void getExtrusionProjectionState( SdrView* pSdrView, SfxItemSet& rSet )
808 {
809     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
810     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
811 
812     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
813     static const rtl::OUString  sProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
814 
815     com::sun::star::uno::Any* pAny;
816 
817     sal_Int32 nFinalProjection = -1;
818     bool bHasCustomShape = false;
819 
820     for(i=0;i<nCount; i++)
821     {
822         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
823         if( pObj->ISA(SdrObjCustomShape) )
824         {
825             // see if this is an extruded customshape
826             if( !bHasCustomShape )
827             {
828                 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
829                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
830                 if( pAny_ )
831                     *pAny_ >>= bHasCustomShape;
832 
833                 if( !bHasCustomShape )
834                     continue;
835             }
836 
837             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
838 
839             sal_Bool    bParallel = sal_True;
840             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sProjectionMode );
841             ProjectionMode eProjectionMode;
842             if( pAny && ( *pAny >>= eProjectionMode ) )
843                 bParallel = eProjectionMode == ProjectionMode_PARALLEL;
844 
845             if( nFinalProjection == -1 )
846             {
847                 nFinalProjection = bParallel;
848             }
849             else if( nFinalProjection != bParallel )
850             {
851                 nFinalProjection = -1;
852                 break;
853             }
854         }
855     }
856 
857     if( bHasCustomShape )
858         rSet.Put( SfxInt32Item( SID_EXTRUSION_PROJECTION, nFinalProjection ) );
859     else
860         rSet.DisableItem( SID_EXTRUSION_PROJECTION );
861 }
862 
863 void getExtrusionSurfaceState( SdrView* pSdrView, SfxItemSet& rSet )
864 {
865     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
866     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
867 
868     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
869     static const rtl::OUString  sShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
870     static const rtl::OUString  sSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
871     static const rtl::OUString  sDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
872     static const rtl::OUString  sMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
873 
874     com::sun::star::uno::Any* pAny;
875 
876     sal_Int32 nFinalSurface = -1;
877     bool bHasCustomShape = false;
878 
879     for(i=0;i<nCount; i++)
880     {
881         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
882         if( pObj->ISA(SdrObjCustomShape) )
883         {
884             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
885 
886             // see if this is an extruded customshape
887             if( !bHasCustomShape )
888             {
889                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
890                 if( pAny_ )
891                     *pAny_ >>= bHasCustomShape;
892 
893                 if( !bHasCustomShape )
894                     continue;
895             }
896 
897             sal_Int32 nSurface = 0; // wire frame
898 
899             ShadeMode eShadeMode( ShadeMode_FLAT );
900             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sShadeMode );
901             if( pAny )
902                 *pAny >>= eShadeMode;
903 
904             if( eShadeMode == ShadeMode_FLAT )
905             {
906                 sal_Bool bMetal = sal_False;
907                 pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sMetal );
908                 if( pAny )
909                     *pAny >>= bMetal;
910 
911                 if( bMetal )
912                 {
913                     nSurface = 3; // metal
914                 }
915                 else
916                 {
917                     double fSpecularity = 0;
918                     pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sSpecularity );
919                     if( pAny )
920                         *pAny >>= fSpecularity;
921 
922                     const double e = 0.0001;
923                     if( (fSpecularity > -e) && (fSpecularity < e) )
924                     {
925                         nSurface = 1; // matte
926                     }
927                     else
928                     {
929                         nSurface = 2; // plastic
930                     }
931                 }
932             }
933 
934             if( nFinalSurface == -1 )
935             {
936                 nFinalSurface = nSurface;
937             }
938             else if( nFinalSurface != nSurface )
939             {
940                 nFinalSurface = -1;
941                 break;
942             }
943         }
944     }
945 
946     if( bHasCustomShape )
947         rSet.Put( SfxInt32Item( SID_EXTRUSION_SURFACE, nFinalSurface ) );
948     else
949         rSet.DisableItem( SID_EXTRUSION_SURFACE );
950 }
951 
952 void getExtrusionDepthState( SdrView* pSdrView, SfxItemSet& rSet )
953 {
954     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
955     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
956 
957     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
958     static const rtl::OUString  sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
959 
960     com::sun::star::uno::Any* pAny;
961 
962     double fFinalDepth = -1;
963     bool bHasCustomShape = false;
964 
965     for(i=0;i<nCount; i++)
966     {
967         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
968         if( pObj->ISA(SdrObjCustomShape) )
969         {
970             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
971 
972             // see if this is an extruded customshape
973             if( !bHasCustomShape )
974             {
975                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
976                 if( pAny_ )
977                     *pAny_ >>= bHasCustomShape;
978 
979                 if( !bHasCustomShape )
980                     continue;
981             }
982 
983             double fDepth = 1270.0;
984             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sDepth );
985             if( pAny )
986             {
987                 EnhancedCustomShapeParameterPair aDepthPropPair;
988                 if ( *pAny >>= aDepthPropPair )
989                     aDepthPropPair.First.Value >>= fDepth;
990             }
991 
992             if( fFinalDepth == -1 )
993             {
994                 fFinalDepth = fDepth;
995             }
996             else if( fFinalDepth != fDepth )
997             {
998                 fFinalDepth = -1;
999                 break;
1000             }
1001         }
1002     }
1003 
1004     if( pSdrView->GetModel() )
1005     {
1006         FieldUnit eUnit = pSdrView->GetModel()->GetUIUnit();
1007         rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, (sal_uInt16)eUnit ) );
1008     }
1009 
1010     if( bHasCustomShape )
1011         rSet.Put( SvxDoubleItem( fFinalDepth, SID_EXTRUSION_DEPTH ) );
1012     else
1013         rSet.DisableItem( SID_EXTRUSION_DEPTH );
1014 }
1015 
1016 static bool compare_direction( const Direction3D& d1, const Direction3D& d2 )
1017 {
1018     if( ((d1.DirectionX < 0) && (d2.DirectionX < 0)) || ((d1.DirectionX == 0) && (d2.DirectionX == 0)) || ((d1.DirectionX > 0) && (d2.DirectionX > 0)) )
1019     {
1020         if( ((d1.DirectionY < 0) && (d2.DirectionY < 0)) || ((d1.DirectionY == 0) && (d2.DirectionY == 0)) || ((d1.DirectionY > 0) && (d2.DirectionY > 0)) )
1021         {
1022             if( ((d1.DirectionZ < 0) && (d2.DirectionZ < 0)) || ((d1.DirectionZ == 0) && (d2.DirectionZ == 0)) || ((d1.DirectionZ > 0) && (d2.DirectionZ > 0)) )
1023             {
1024                 return true;
1025             }
1026         }
1027     }
1028 
1029     return false;
1030 }
1031 
1032 void getExtrusionLightingDirectionState( SdrView* pSdrView, SfxItemSet& rSet )
1033 {
1034     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1035     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
1036 
1037     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1038     static const rtl::OUString  sFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
1039     static const rtl::OUString  sSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
1040 
1041     const Direction3D * pLighting1Defaults;
1042     const Direction3D * pLighting2Defaults;
1043 
1044     getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );
1045 
1046     com::sun::star::uno::Any* pAny;
1047 
1048     int nFinalDirection = -1;
1049     bool bHasCustomShape = false;
1050 
1051     for(i=0;i<nCount; i++)
1052     {
1053         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1054         if( pObj->ISA(SdrObjCustomShape) )
1055         {
1056             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1057 
1058             // see if this is an extruded customshape
1059             if( !bHasCustomShape )
1060             {
1061                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1062                 if( pAny_ )
1063                     *pAny_ >>= bHasCustomShape;
1064 
1065                 if( !bHasCustomShape )
1066                     continue;
1067             }
1068 
1069             Direction3D aFirstLightDirection( 50000, 0, 10000 );
1070             Direction3D aSecondLightDirection( -50000, 0, 10000 );
1071 
1072             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sFirstLightDirection );
1073             if( pAny )
1074                 *pAny >>= aFirstLightDirection;
1075 
1076             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sSecondLightDirection );
1077             if( pAny )
1078                 *pAny >>= aSecondLightDirection;
1079 
1080             int nDirection = -1;
1081 
1082             int j;
1083             for( j = 0; j < 9; j++ )
1084             {
1085                 if( compare_direction( aFirstLightDirection, pLighting1Defaults[j] ) &&
1086                     compare_direction( aSecondLightDirection, pLighting2Defaults[j] ))
1087                 {
1088                     nDirection = j;
1089                     break;
1090                 }
1091             }
1092 
1093             if( nFinalDirection == -1 )
1094             {
1095                 nFinalDirection = nDirection;
1096             }
1097             else if( nDirection != nFinalDirection )
1098             {
1099                 nFinalDirection = -1;
1100             }
1101 
1102             if( nFinalDirection == -1 )
1103                 break;
1104         }
1105     }
1106 
1107     if( bHasCustomShape )
1108         rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_DIRECTION, (sal_Int32)nFinalDirection ) );
1109     else
1110         rSet.DisableItem( SID_EXTRUSION_LIGHTING_DIRECTION );
1111 }
1112 
1113 void getExtrusionLightingIntensityState( SdrView* pSdrView, SfxItemSet& rSet )
1114 {
1115     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1116     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
1117 
1118     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1119     static const rtl::OUString  sBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
1120 
1121     com::sun::star::uno::Any* pAny;
1122 
1123     int nFinalLevel = -1;
1124     bool bHasCustomShape = false;
1125 
1126     for(i=0;i<nCount; i++)
1127     {
1128         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1129         if( pObj->ISA(SdrObjCustomShape) )
1130         {
1131             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1132 
1133             // see if this is an extruded customshape
1134             if( !bHasCustomShape )
1135             {
1136                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1137                 if( pAny_ )
1138                     *pAny_ >>= bHasCustomShape;
1139 
1140                 if( !bHasCustomShape )
1141                     continue;
1142             }
1143 
1144             double fBrightness = 22178.0 / 655.36;
1145             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sBrightness );
1146             if( pAny )
1147                 *pAny >>= fBrightness;
1148 
1149             int nLevel;
1150             if( fBrightness >= 30.0 )
1151             {
1152                 nLevel = 0; // Bright
1153             }
1154             else if( fBrightness >= 10.0 )
1155             {
1156                 nLevel = 1; // Noraml;
1157             }
1158             else
1159             {
1160                 nLevel = 2; // Dim
1161             }
1162 
1163             if( nFinalLevel == -1 )
1164             {
1165                 nFinalLevel = nLevel;
1166             }
1167             else if( nFinalLevel != nLevel )
1168             {
1169                 nFinalLevel = -1;
1170                 break;
1171             }
1172         }
1173     }
1174 
1175     if( bHasCustomShape )
1176         rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_INTENSITY, nFinalLevel ) );
1177     else
1178         rSet.DisableItem( SID_EXTRUSION_LIGHTING_INTENSITY );
1179 }
1180 
1181 void getExtrusionColorState( SdrView* pSdrView, SfxItemSet& rSet )
1182 {
1183     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1184     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
1185 
1186     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1187     static const rtl::OUString  sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
1188 
1189     com::sun::star::uno::Any* pAny;
1190 
1191     bool bInit = false;
1192     bool bAmbigius = false;
1193     Color aFinalColor;
1194     bool bHasCustomShape = false;
1195 
1196     for(i=0;i<nCount; i++)
1197     {
1198         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1199         if( pObj->ISA(SdrObjCustomShape) )
1200         {
1201             SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1202 
1203             // see if this is an extruded customshape
1204             if( !bHasCustomShape )
1205             {
1206                 Any* pAny_ = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1207                 if( pAny_ )
1208                     *pAny_ >>= bHasCustomShape;
1209 
1210                 if( !bHasCustomShape )
1211                     continue;
1212             }
1213 
1214             Color aColor;
1215 
1216             bool bUseColor = false;
1217             pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusionColor );
1218             if( pAny )
1219                 *pAny >>= bUseColor;
1220 
1221             if( bUseColor )
1222             {
1223                 const XSecondaryFillColorItem& rItem = *(XSecondaryFillColorItem*)&(pObj->GetMergedItem( XATTR_SECONDARYFILLCOLOR ));
1224                 aColor = rItem.GetColorValue();
1225             }
1226             else
1227             {
1228                 aColor = COL_AUTO;
1229             }
1230 
1231             if( !bInit )
1232             {
1233                 aFinalColor = aColor;
1234                 bInit = true;
1235             }
1236             else if( aFinalColor != aColor )
1237             {
1238                 bAmbigius = true;
1239                 break;
1240             }
1241         }
1242     }
1243 
1244     if( bAmbigius )
1245         aFinalColor = COL_AUTO;
1246 
1247     if( bHasCustomShape )
1248         rSet.Put( SvxColorItem( aFinalColor, SID_EXTRUSION_3D_COLOR ) );
1249     else
1250         rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
1251 }
1252 
1253 namespace svx {
1254 bool checkForSelectedCustomShapes( SdrView* pSdrView, bool bOnlyExtruded )
1255 {
1256     static const rtl::OUString  sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1257 
1258     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
1259     sal_uIntPtr nCount = rMarkList.GetMarkCount(), i;
1260     bool bFound = false;
1261 
1262     for(i=0;(i<nCount) && !bFound ; i++)
1263     {
1264         SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1265         if( pObj->ISA(SdrObjCustomShape) )
1266         {
1267             if( bOnlyExtruded )
1268             {
1269                 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1270                 Any* pAny = aGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
1271                 if( pAny )
1272                     *pAny >>= bFound;
1273             }
1274             else
1275             {
1276                 bFound = true;
1277             }
1278         }
1279     }
1280 
1281     return bFound;
1282 }
1283 }
1284 
1285 void ExtrusionBar::getState( SdrView* pSdrView, SfxItemSet& rSet )
1286 {
1287     if (rSet.GetItemState(SID_EXTRUSION_DIRECTION) != SFX_ITEM_UNKNOWN)
1288     {
1289         getExtrusionDirectionState( pSdrView, rSet );
1290     }
1291     if (rSet.GetItemState(SID_EXTRUSION_PROJECTION) != SFX_ITEM_UNKNOWN)
1292     {
1293         getExtrusionProjectionState( pSdrView, rSet );
1294     }
1295     const bool bOnlyExtrudedCustomShapes =
1296         checkForSelectedCustomShapes( pSdrView, true );
1297     if (rSet.GetItemState(SID_EXTRUSION_TILT_DOWN) != SFX_ITEM_UNKNOWN)
1298     {
1299         if (! bOnlyExtrudedCustomShapes)
1300             rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
1301     }
1302     if (rSet.GetItemState(SID_EXTRUSION_TILT_DOWN) != SFX_ITEM_UNKNOWN)
1303     {
1304         if (! bOnlyExtrudedCustomShapes)
1305             rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
1306     }
1307     if (rSet.GetItemState(SID_EXTRUSION_TILT_UP) != SFX_ITEM_UNKNOWN)
1308     {
1309         if (! bOnlyExtrudedCustomShapes)
1310             rSet.DisableItem( SID_EXTRUSION_TILT_UP );
1311     }
1312     if (rSet.GetItemState(SID_EXTRUSION_TILT_LEFT) != SFX_ITEM_UNKNOWN)
1313     {
1314         if (! bOnlyExtrudedCustomShapes)
1315             rSet.DisableItem( SID_EXTRUSION_TILT_LEFT );
1316     }
1317     if (rSet.GetItemState(SID_EXTRUSION_TILT_RIGHT) != SFX_ITEM_UNKNOWN)
1318     {
1319         if (! bOnlyExtrudedCustomShapes)
1320             rSet.DisableItem( SID_EXTRUSION_TILT_RIGHT );
1321     }
1322     if (rSet.GetItemState(SID_EXTRUSION_3D_COLOR) != SFX_ITEM_UNKNOWN)
1323     {
1324         if (! bOnlyExtrudedCustomShapes)
1325             rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
1326     }
1327     if (rSet.GetItemState(SID_EXTRUSION_DEPTH_FLOATER) != SFX_ITEM_UNKNOWN)
1328     {
1329         if (! bOnlyExtrudedCustomShapes)
1330             rSet.DisableItem( SID_EXTRUSION_DEPTH_FLOATER );
1331     }
1332     if (rSet.GetItemState(SID_EXTRUSION_DIRECTION_FLOATER) != SFX_ITEM_UNKNOWN)
1333     {
1334         if (! bOnlyExtrudedCustomShapes)
1335             rSet.DisableItem( SID_EXTRUSION_DIRECTION_FLOATER );
1336     }
1337     if (rSet.GetItemState(SID_EXTRUSION_LIGHTING_FLOATER) != SFX_ITEM_UNKNOWN)
1338     {
1339         if (! bOnlyExtrudedCustomShapes)
1340             rSet.DisableItem( SID_EXTRUSION_LIGHTING_FLOATER );
1341     }
1342     if (rSet.GetItemState(SID_EXTRUSION_SURFACE_FLOATER) != SFX_ITEM_UNKNOWN)
1343     {
1344         if(! bOnlyExtrudedCustomShapes)
1345             rSet.DisableItem( SID_EXTRUSION_SURFACE_FLOATER );
1346     }
1347     if (rSet.GetItemState(SID_EXTRUSION_TOOGLE) != SFX_ITEM_UNKNOWN)
1348     {
1349         if( !checkForSelectedCustomShapes( pSdrView, false ) )
1350             rSet.DisableItem( SID_EXTRUSION_TOOGLE );
1351     }
1352     if (rSet.GetItemState(SID_EXTRUSION_DEPTH) != SFX_ITEM_UNKNOWN)
1353     {
1354         getExtrusionDepthState( pSdrView, rSet );
1355     }
1356     if (rSet.GetItemState(SID_EXTRUSION_SURFACE) != SFX_ITEM_UNKNOWN)
1357     {
1358         getExtrusionSurfaceState( pSdrView, rSet );
1359     }
1360     if (rSet.GetItemState(SID_EXTRUSION_LIGHTING_INTENSITY) != SFX_ITEM_UNKNOWN)
1361     {
1362         getExtrusionLightingIntensityState( pSdrView, rSet );
1363     }
1364 
1365     if (rSet.GetItemState(SID_EXTRUSION_LIGHTING_DIRECTION) != SFX_ITEM_UNKNOWN)
1366     {
1367         getExtrusionLightingDirectionState( pSdrView, rSet );
1368     }
1369 
1370     if (rSet.GetItemState(SID_EXTRUSION_3D_COLOR) != SFX_ITEM_UNKNOWN)
1371     {
1372         getExtrusionColorState( pSdrView, rSet );
1373     }
1374 }
1375