Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/svx/source/toolbars/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 47 kB image not shown  

Quelle  extrusionbar.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */



#include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/ProjectionMode.hpp>
#include <svx/svxids.hrc>
#include <svx/svdundo.hxx>
#include <sfx2/request.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/bindings.hxx>
#include <svx/xsflclit.hxx>
#include <svx/dialmgr.hxx>
#include <svx/svdoashp.hxx>
#include <svx/strings.hrc>
#include <svx/svdview.hxx>
#include <editeng/colritem.hxx>
#include <svx/chrtitem.hxx>
#include <svx/sdasitm.hxx>
#include <svl/intitem.hxx>
#include <rtl/math.hxx>
#include <basegfx/numeric/ftools.hxx>

#include <svx/extrusionbar.hxx>
#include <extrusiondepthdialog.hxx>

using namespace ::svx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::uno;

// Declare the default interface. (The slotmap must not be empty, so
// we enter something which never occurs here (hopefully).)
static SfxSlot aExtrusionBarSlots_Impl[] =
{
    { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, u""_ustr }
};

SFX_IMPL_INTERFACE(ExtrusionBar, SfxShell)

void ExtrusionBar::InitInterface_Impl()
{
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Svx_Extrusion_Bar);
}


ExtrusionBar::ExtrusionBar(SfxViewShell* pViewShell )
: SfxShell(pViewShell)
{
    DBG_ASSERT( pViewShell, "svx::ExtrusionBar::ExtrusionBar(), I need a viewshell!" );
    if( pViewShell )
        SetPool(&pViewShell->GetPool());

    SetName(SvxResId(RID_SVX_EXTRUSION_BAR));
}

ExtrusionBar::~ExtrusionBar()
{
    SetRepeatTarget(nullptr);
}

static void getLightingDirectionDefaults( const Direction3D **pLighting1Defaults, const Direction3D **pLighting2Defaults )
{

    static const Direction3D aLighting1Defaults[9] =
    {
        Direction3D( -50000, -50000, 10000 ),
        Direction3D( 0, -50000, 10000 ),
        Direction3D( 50000, -50000, 10000 ),
        Direction3D( -50000, 0, 10000 ),
        Direction3D( 0, 0, 10000 ),
        Direction3D( 50000, 0, 10000 ),
        Direction3D( -50000, 50000, 10000 ),
        Direction3D( 0, 50000, 10000 ),
        Direction3D( 50000, 50000, 10000 )
    };

    static const Direction3D aLighting2Defaults[9] =
    {
        Direction3D( 50000,0, 10000 ),
        Direction3D( 0, 50000, 10000 ),
        Direction3D( -50000, 0, 10000 ),
        Direction3D( 50000, 0, 10000 ),
        Direction3D( 0, 0, 10000 ),
        Direction3D( -50000, 0, 10000 ),
        Direction3D( 50000, 0, 10000 ),
        Direction3D( 0, -50000, 10000 ),
        Direction3D( -50000, 0, 10000 )
    };

    *pLighting1Defaults = aLighting1Defaults;
    *pLighting2Defaults = aLighting2Defaults;
};

static void impl_execute( SfxRequest const & rReq, SdrCustomShapeGeometryItem& rGeometryItem, SdrObject* pObj )
{
    static constexpr OUString sExtrusion = u"Extrusion"_ustr;
    static constexpr OUString sRotateAngle = u"RotateAngle"_ustr;

    sal_uInt16 nSID = rReq.GetSlot();
    switch( nSID )
    {
    case SID_EXTRUSION_TOGGLE:
    {
        bool bOn(false);
        css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
        if ( pAny )
        {
            (*pAny) >>= bOn;
            bOn = !bOn;
            css::beans::PropertyValue aPropValue;
            aPropValue.Name = sExtrusion;
            aPropValue.Value <<= bOn;
            rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
        }
        else
        {
            css::beans::PropertyValue aPropValue;
            aPropValue.Name = sExtrusion;
            aPropValue.Value <<= true;
            rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
            bOn = true;
        }

        // draw:extrusion-diffusion has default 0% and c3DDiffuseAmt has default 100%. We set property
        // "Diffusion" with value 100% here if it does not exist already. This forces, that the
        // property is written to file in case an extrusion is newly created, and users of old
        // documents, which usually do not have this property, can force the value to 100% by toggling
        // the extrusion off and on.
        if (bOn)
        {
            pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Diffusion"_ustr);
            if (!pAny)
            {
                css::beans::PropertyValue aPropValue;
                aPropValue.Name = u"Diffusion"_ustr;
                aPropValue.Value <<= 100.0;
                rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
            }
        }
    }
    break;

    case SID_EXTRUSION_TILT_DOWN:
    case SID_EXTRUSION_TILT_UP:
    case SID_EXTRUSION_TILT_LEFT:
    case SID_EXTRUSION_TILT_RIGHT:
    {
        bool bHorizontal = ( nSID == SID_EXTRUSION_TILT_DOWN ) || ( nSID == SID_EXTRUSION_TILT_UP );
        sal_Int32 nDiff = ( nSID == SID_EXTRUSION_TILT_LEFT ) || ( nSID == SID_EXTRUSION_TILT_UP ) ? 5 : -5;
        EnhancedCustomShapeParameterPair aRotateAnglePropPair;
        double fX = 0.0;
        double fY = 0.0;
        aRotateAnglePropPair.First.Value <<= fX;
        aRotateAnglePropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
        aRotateAnglePropPair.Second.Value <<= fY;
        aRotateAnglePropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
        css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sRotateAngle );
        if( pAny && ( *pAny >>= aRotateAnglePropPair ) )
        {
            aRotateAnglePropPair.First.Value >>= fX;
            aRotateAnglePropPair.Second.Value >>= fY;
        }
        if ( bHorizontal )
            fX += nDiff;
        else
            fY += nDiff;
        aRotateAnglePropPair.First.Value <<= fX;
        aRotateAnglePropPair.Second.Value <<= fY;
        css::beans::PropertyValue aPropValue;
        aPropValue.Name = sRotateAngle;
        aPropValue.Value <<= aRotateAnglePropPair;
        rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
    }
    break;

    case SID_EXTRUSION_DIRECTION:
    {
        const SfxInt32Item* pExtrusionItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DIRECTION, true, &pExtrusionItem ) == SfxItemState::SET )
        {
            sal_Int32 nSkew = pExtrusionItem->GetValue();

            Position3D  aViewPoint( 3472, -3472, 25000 );
            double      fOriginX = 0.50;
            double      fOriginY = -0.50;
            double      fSkewAngle = nSkew;
            double      fSkew = 50.0;

            switch( nSkew )
            {
            case 135:
                aViewPoint.PositionY = 3472;
                fOriginY = 0.50;
                break;
            case 90:
                aViewPoint.PositionX = 0;
                aViewPoint.PositionY = 3472;
                fOriginX = 0;
                fOriginY = 0.50;
                break;
            case 45:
                aViewPoint.PositionX = -3472;
                aViewPoint.PositionY = 3472;
                fOriginX = -0.50;
                fOriginY = 0.50;
                break;
            case 180:
                aViewPoint.PositionY = 0;
                fOriginY = 0;
                break;
            case 0:
                aViewPoint.PositionX = 0;
                aViewPoint.PositionY = 0;
                fOriginX = 0;
                fOriginY = 0;
                fSkew = 0.0;
                break;
            case -360:
                aViewPoint.PositionX = -3472;
                aViewPoint.PositionY = 0;
                fOriginX = -0.50;
                fOriginY = 0;
                break;
            case -90:
                aViewPoint.PositionX = 0;
                fOriginX = 0;
                break;
            case -45:
                aViewPoint.PositionX = -3472;
                fOriginX = -0.50;
                break;
            }

            css::beans::PropertyValue aPropValue;

            aPropValue.Name = "ViewPoint";
            aPropValue.Value <<= aViewPoint;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );


            EnhancedCustomShapeParameterPair aOriginPropPair;
            aOriginPropPair.First.Value <<= fOriginX;
            aOriginPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
            aOriginPropPair.Second.Value <<= fOriginY;
            aOriginPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
            aPropValue.Name = "Origin";
            aPropValue.Value <<= aOriginPropPair;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

            EnhancedCustomShapeParameterPair aSkewPropPair;
            aSkewPropPair.First.Value <<= fSkew;
            aSkewPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
            aSkewPropPair.Second.Value <<= fSkewAngle;
            aSkewPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
            aPropValue.Name = "Skew";
            aPropValue.Value <<= aSkewPropPair;
            rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );
        }
    }
    break;
    case SID_EXTRUSION_PROJECTION:
    {
        const SfxInt32Item* pExtrusionItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_PROJECTION, true, &pExtrusionItem ) == SfxItemState::SET )
        {
            sal_Int32 nProjection = pExtrusionItem->GetValue();
            ProjectionMode eProjectionMode = nProjection == 1 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
            css::beans::PropertyValue aPropValue;
            aPropValue.Name = "ProjectionMode";
            aPropValue.Value <<= eProjectionMode;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
        }
    }
    break;
    case SID_EXTRUSION_DEPTH:
    {
        const SvxDoubleItem* pExtrusionItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH, true, &pExtrusionItem ) == SfxItemState::SET)
        {
            double fDepth = pExtrusionItem->GetValue();
            EnhancedCustomShapeParameterPair aDepthPropPair;
            aDepthPropPair.First.Value <<= fDepth;
            aDepthPropPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
            aDepthPropPair.Second.Value <<= 0.0; // fraction
            aDepthPropPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;

            css::beans::PropertyValue aPropValue;
            aPropValue.Name = "Depth";
            aPropValue.Value <<= aDepthPropPair;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
        }
    }
    break;
    case SID_EXTRUSION_3D_COLOR:
    {
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_3D_COLOR ) == SfxItemState::SET)
        {
            Color aColor( static_cast<const SvxColorItem&>(rReq.GetArgs()->Get(SID_EXTRUSION_3D_COLOR)).GetValue() );

            const bool bAuto = aColor == COL_AUTO;

            css::beans::PropertyValue aPropValue;
            aPropValue.Name = "Color";
            aPropValue.Value <<= !bAuto;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

            if( bAuto )
            {
                pObj->ClearMergedItem( XATTR_SECONDARYFILLCOLOR );
            }
            else
            {
                pObj->SetMergedItem( XSecondaryFillColorItem( u""_ustr, aColor ) );
            }
            pObj->BroadcastObjectChange();
        }
    }
    break;
    case SID_EXTRUSION_SURFACE:
    {
        const SfxInt32Item* pExtrusionItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_SURFACE, true, &pExtrusionItem ) == SfxItemState::SET)
        {
            sal_Int32 nSurface = pExtrusionItem->GetValue();

            // Set ShadeMode only when changing from or to wireframe, otherwise keep existing value.
            ShadeMode eOldShadeMode(ShadeMode_FLAT);
            css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"ShadeMode"_ustr);
            if (pAny)
                *pAny >>= eOldShadeMode;
            ShadeMode eShadeMode(eOldShadeMode);
            switch (nSurface)
            {
                case 0: // wireframe
                    eShadeMode = ShadeMode_DRAFT;
                    break;
                case 1: // matte
                case 2: // plastic
                case 3: // metal ODF
                case 4: // metal MS Office
                    if (eOldShadeMode == ShadeMode_DRAFT)
                        eShadeMode = ShadeMode_FLAT; // ODF default
                    break;
            }

            // ODF has no dedicated property for 'surface'. MS Office binary format uses attribute
            // c3DSpecularAmt to distinguish between 'matte' (=0) and 'plastic'.
            // We do the same.
            double fOldSpecularity = 0.0;
            pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Specularity"_ustr);
            if (pAny)
                *pAny >>= fOldSpecularity;
            double fSpecularity = fOldSpecularity;
            switch( nSurface )
            {
            case 0: // wireframe
                break;
            case 1: // matte
                fSpecularity = 0.0;
                break;
            case 2: // plastic
            case 3: // metal ODF
            case 4: // metal MS Office
                if (basegfx::fTools::equalZero(fOldSpecularity, 0.0001))
                    // MS Office uses 80000/65536. That is currently not allowed in ODF.
                    // But the ODF error will be caught in xmloff.
                    fSpecularity = 80000.0 / 655.36; // interpreted as %
                break;
            }

            // MS Office binary format uses attribute c3DDiffuseAmt with value =43712 (Fixed 16.16) in
            // addition to the 'metal' flag. For other surface kinds default = 65536 is used.
            // We toggle between 100 and 43712.0 / 655.36 here, to get better ODF -> MSO binary.
            // We keep other values, those might be set outside regular UI, e.g by macro.
            double fOldDiffusion = 100.0;
            pAny = rGeometryItem.GetPropertyValueByName(sExtrusion, u"Diffusion"_ustr);
            if (pAny)
                *pAny >>= fOldDiffusion;
            double fDiffusion = fOldDiffusion;
            if (nSurface == 4)
            {
                if (fOldDiffusion == 100.0)
                    fDiffusion = 43712.0 / 655.36; // interpreted as %
            }
            else
            {
                if (basegfx::fTools::equalZero(fOldDiffusion - 43712.0 / 655.36, 0.0001))
                    fDiffusion = 100.0;
            }

            css::beans::PropertyValue aPropValue;
            aPropValue.Name = "ShadeMode";
            aPropValue.Value <<= eShadeMode;
            rGeometryItem.SetPropertyValue( sExtrusion, aPropValue );

            aPropValue.Name = "Metal";
            aPropValue.Value <<= nSurface == 3 || nSurface == 4;
            rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);

            if (nSurface == 3 || nSurface == 4)
            {
                aPropValue.Name = "MetalType";
                aPropValue.Value <<= nSurface == 4
                                         ? EnhancedCustomShapeMetalType::MetalMSCompatible
                                         : EnhancedCustomShapeMetalType::MetalODF;
                rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
            }

            if (!basegfx::fTools::equalZero(fOldSpecularity - fSpecularity, 0.0001))
            {
                aPropValue.Name = "Specularity";
                aPropValue.Value <<= fSpecularity;
                rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
            }

            if (!basegfx::fTools::equalZero(fOldDiffusion - fDiffusion, 0.0001))
            {
                aPropValue.Name = "Diffusion";
                aPropValue.Value <<= fDiffusion;
                rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
            }
        }
    }
    break;
    case SID_EXTRUSION_LIGHTING_INTENSITY:
    {
        const SfxInt32Item* pLightItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_INTENSITY, true, &pLightItem ) == SfxItemState::SET)
        {
            sal_Int32 nLevel = pLightItem->GetValue();

            double fBrightness; // c3DAmbientIntensity in MS Office
            double fLevel1; // c3DKeyIntensity in MS Office
            double fLevel2; // c3DFillIntensity in MS Office

            // ToDo: "bright" values are different from MS Office. Should they be kept?
            switch( nLevel )
            {
            case 0: // bright
                fBrightness = 33.0; // ODF default.
                fLevel1 = 66.0; // ODF default
                fLevel2 = 66.0; // ODF default
                break;
            case 1: // normal
                fBrightness = 15.0;
                fLevel1 = 67.0;
                fLevel2 = 37.0;
                break;
            case 2: // dim
                fBrightness = 6.0;
                fLevel1 = 79.0;
                fLevel2 = 21.0;
                break;
            }

            css::beans::PropertyValue aPropValue;
            aPropValue.Name = "Brightness";
            aPropValue.Value <<= fBrightness;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

            aPropValue.Name = "FirstLightLevel";
            aPropValue.Value <<= fLevel1;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

            aPropValue.Name = "SecondLightLevel";
            aPropValue.Value <<= fLevel2;
            rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

            // If a user sets light preset 'Dim' in MS Office, MS Office sets second light to harsh.
            // In other cases it is soft.
            aPropValue.Name = "SecondLightHarsh";
            aPropValue.Value <<= nLevel == 2;
            rGeometryItem.SetPropertyValue(sExtrusion, aPropValue);
        }
    }
    break;
    case SID_EXTRUSION_LIGHTING_DIRECTION:
    {
        const SfxInt32Item* pLightDirectionItem = nullptr;
        if( rReq.GetArgs() && rReq.GetArgs()->GetItemState( SID_EXTRUSION_LIGHTING_DIRECTION, true, &pLightDirectionItem ) == SfxItemState::SET)
        {
            sal_Int32 nDirection = pLightDirectionItem->GetValue();

            if((nDirection >= 0) && (nDirection < 9))
            {
                const Direction3D * pLighting1Defaults;
                const Direction3D * pLighting2Defaults;

                getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );

                css::beans::PropertyValue aPropValue;
                aPropValue.Name = "FirstLightDirection";
                aPropValue.Value <<= pLighting1Defaults[nDirection];
                rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );

                aPropValue.Name = "SecondLightDirection";
                aPropValue.Value <<= pLighting2Defaults[nDirection];
                rGeometryItem.SetPropertyValue( sExtrusion,  aPropValue );
            }
        }
    }
    break;

    }
}

void ExtrusionBar::execute( SdrView* pSdrView, SfxRequest const & rReq, SfxBindings&&nbsp;rBindings )
{
    sal_uInt16 nSID = rReq.GetSlot();
    TranslateId pStrResId;

    const bool bUndo = pSdrView && pSdrView->IsUndoEnabled();

    switch( nSID )
    {
        case SID_EXTRUSION_TOGGLE:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ON_OFF;
            [[fallthrough]];
        }
        case SID_EXTRUSION_TILT_DOWN:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_DOWN;
            [[fallthrough]];
        }
        case SID_EXTRUSION_TILT_UP:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_UP;
            [[fallthrough]];
        }
        case SID_EXTRUSION_TILT_LEFT:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_LEFT;
            [[fallthrough]];
        }
        case SID_EXTRUSION_TILT_RIGHT:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ROTATE_RIGHT;
            [[fallthrough]];
        }
        case SID_EXTRUSION_DIRECTION:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_ORIENTATION;
            [[fallthrough]];
        }
        case SID_EXTRUSION_PROJECTION:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_PROJECTION;
            [[fallthrough]];
        }
        case SID_EXTRUSION_DEPTH:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_DEPTH;
            [[fallthrough]];
        }
        case SID_EXTRUSION_3D_COLOR:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_COLOR;
            [[fallthrough]];
        }
        case SID_EXTRUSION_SURFACE:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_SURFACE;
            [[fallthrough]];
        }
        case SID_EXTRUSION_LIGHTING_INTENSITY:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_BRIGHTNESS;
            [[fallthrough]];
        }
        case SID_EXTRUSION_LIGHTING_DIRECTION:
        {
            if ( !pStrResId )
                pStrResId = RID_SVXSTR_UNDO_APPLY_EXTRUSION_LIGHTING;

            if (pSdrView)
            {
                const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
                const size_t nCount = rMarkList.GetMarkCount();

                for(size_t i=0; i<nCount; ++i)
                {
                    SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
                    ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
                    {
                        if( bUndo )
                        {
                            OUString aStr( SvxResId( pStrResId ) );
                            pSdrView->BegUndo( aStr );
                            pSdrView->AddUndo( pSdrView->GetModel().GetSdrUndoFactory().CreateUndoAttrObject( *pObj ) );
                        }
                        SdrCustomShapeGeometryItem aGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
                        impl_execute( rReq, aGeometryItem, pObj );
                        pObj->SetMergedItem( aGeometryItem );
                        pObj->BroadcastObjectChange();
                        if( bUndo )
                            pSdrView->EndUndo();

                        // simulate a context change:
                        // force SelectionHasChanged() being called
                        // so that extrusion bar will be visible/hidden
                        pSdrView->MarkListHasChanged();
                    }
                }
            }
        }
        break;

        case SID_EXTRUSION_DEPTH_DIALOG:
        {
            const SvxDoubleItem* pDepthItem = nullptr;
            const SfxUInt16Item* pMetricItem = nullptr;
            if( rReq.GetArgs() &&
                (rReq.GetArgs()->GetItemState( SID_EXTRUSION_DEPTH, true, &pDepthItem ) == SfxItemState::SET) &&
                (rReq.GetArgs()->GetItemState( SID_ATTR_METRIC, true, &pMetricItem ) == SfxItemState::SET))
            {
                double fDepth = pDepthItem->GetValue();
                FieldUnit eUnit = static_cast<FieldUnit>(pMetricItem->GetValue());

                ExtrusionDepthDialog aDlg(rReq.GetFrameWeld(), fDepth, eUnit);
                sal_uInt16 nRet = aDlg.run();
                if (nRet == RET_OK)
                {
                    fDepth = aDlg.getDepth();

                    SvxDoubleItem aItem( fDepth, SID_EXTRUSION_DEPTH );
                    SfxPoolItem* aItems[] = { &aItem, nullptr };
                    rBindings.Execute( SID_EXTRUSION_DEPTH, const_cast<const SfxPoolItem**>(aItems) );
                }
            }
            break;
        }
    }

    if( nSID != SID_EXTRUSION_TOGGLE )
        return;

    static const sal_uInt16 SidArray[] = {
            SID_EXTRUSION_TILT_DOWN,
            SID_EXTRUSION_TILT_UP,
            SID_EXTRUSION_TILT_LEFT,
            SID_EXTRUSION_TILT_RIGHT,
            SID_EXTRUSION_DEPTH_FLOATER,
            SID_EXTRUSION_DIRECTION_FLOATER,
            SID_EXTRUSION_LIGHTING_FLOATER,
            SID_EXTRUSION_SURFACE_FLOATER,
            SID_EXTRUSION_3D_COLOR,
            SID_EXTRUSION_DEPTH,
            SID_EXTRUSION_DIRECTION,
            SID_EXTRUSION_PROJECTION,
            SID_EXTRUSION_LIGHTING_DIRECTION,
            SID_EXTRUSION_LIGHTING_INTENSITY,
            SID_EXTRUSION_SURFACE,
            0 };

    rBindings.Invalidate( SidArray );
}

static void getExtrusionDirectionState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    double fFinalSkewAngle = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            bool        bParallel = true;
            Position3D  aViewPoint( 3472, -3472, 25000 ); // MSO default
            double      fSkewAngle = -135; // MSO default

            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ProjectionMode"_ustr );
            sal_Int16 nProjectionMode = sal_Int16();
            if( pAny && ( *pAny >>= nProjectionMode ) )
                bParallel = static_cast<ProjectionMode>(nProjectionMode) == ProjectionMode_PARALLEL;

            if( bParallel )
            {
                double      fSkew = 50.0;
                EnhancedCustomShapeParameterPair aSkewPropPair;
                pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Skew"_ustr );
                if( pAny && ( *pAny >>= aSkewPropPair ) )
                {
                    aSkewPropPair.First.Value >>= fSkew;
                    aSkewPropPair.Second.Value >>= fSkewAngle;
                }
                if ( fSkew == 0.0 )
                    fSkewAngle = 0.0;
                else if ( fSkewAngle == 0.0 )
                    fSkewAngle = -360.0;
            }
            else
            {
                double      fOriginX = 0.50;
                double      fOriginY = -0.50;
                pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ViewPoint"_ustr );
                if( pAny )
                    *pAny >>= aViewPoint;

                EnhancedCustomShapeParameterPair aOriginPropPair;
                pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Origin"_ustr );
                if( pAny && ( *pAny >>= aOriginPropPair ) )
                {
                    aOriginPropPair.First.Value >>= fOriginX;
                    aOriginPropPair.Second.Value >>= fOriginY;
                }
                fSkewAngle = -1;
                const double e = 0.0001;
                if( aViewPoint.PositionX > e )
                {
                    if( aViewPoint.PositionY > e )
                    {
                        if( (fOriginX > e ) && ( fOriginY > e ) )
                            fSkewAngle = 135.0;
                    }
                    else if( aViewPoint.PositionY < -e )
                    {
                        if( ( fOriginX > e ) && ( fOriginY < -e ) )
                            fSkewAngle = -135.0;
                    }
                    else
                    {
                        if( ( fOriginX > e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
                            fSkewAngle = 180.0;
                    }
                }
                else if( aViewPoint.PositionX < -e )
                {
                    if( aViewPoint.PositionY < -e )
                    {
                        if( ( fOriginX < -e ) && ( fOriginY < -e ) )
                            fSkewAngle = -45.0;
                    }
                    else if( aViewPoint.PositionY > e )
                    {
                        if( ( fOriginX < -e ) && ( fOriginY > e ) )
                            fSkewAngle = 45.0;
                    }
                    else
                    {
                        if( ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
                            fSkewAngle = -360.0;
                    }
                }
                else
                {
                    if( aViewPoint.PositionY < -e )
                    {
                        if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY < -e ) )
                            fSkewAngle = -90.0;
                    }
                    else if( aViewPoint.PositionY > e )
                    {
                        if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > e ) )
                            fSkewAngle = 90.0;
                    }
                    else
                    {
                        if( ( fOriginX > -e ) && ( fOriginX < e ) && ( fOriginY > -e ) && ( fOriginY < e ) )
                            fSkewAngle = 0.0;
                    }
                }
            }

            if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
            {
                fFinalSkewAngle = fSkewAngle;
            }
            else if( !rtl::math::approxEqual(fSkewAngle, fFinalSkewAngle) )
            {
                fFinalSkewAngle = -1.0;
            }

            if( rtl::math::approxEqual(fFinalSkewAngle, -1.0) )
                break;
        }
    }

    if( bHasCustomShape )
        rSet.Put( SfxInt32Item( SID_EXTRUSION_DIRECTION, static_cast<sal_Int32>(fFinalSkewAngle) ) );
    else
        rSet.DisableItem( SID_EXTRUSION_DIRECTION );
}

static void getExtrusionProjectionState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    sal_Int32 nFinalProjection = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            bool    bParallel = true;
            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ProjectionMode"_ustr );
            ProjectionMode eProjectionMode;
            if( pAny && ( *pAny >>= eProjectionMode ) )
                bParallel = eProjectionMode == ProjectionMode_PARALLEL;

            if( nFinalProjection == -1 )
            {
                nFinalProjection = bParallel ? 1 : 0;
            }
            else if( nFinalProjection != (bParallel ? 1 : 0) )
            {
                nFinalProjection = -1;
                break;
            }
        }
    }

    if( bHasCustomShape )
        rSet.Put( SfxInt32Item( SID_EXTRUSION_PROJECTION, nFinalProjection ) );
    else
        rSet.DisableItem( SID_EXTRUSION_PROJECTION );
}

static void getExtrusionSurfaceState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    sal_Int32 nFinalSurface = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            sal_Int32 nSurface = 0; // wire frame

            ShadeMode eShadeMode( ShadeMode_FLAT );
            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"ShadeMode"_ustr );
            if( pAny )
                *pAny >>= eShadeMode;

            if (eShadeMode != ShadeMode_DRAFT)
            {
                bool bMetal = false;
                pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Metal"_ustr );
                if( pAny )
                    *pAny >>= bMetal;

                if( bMetal )
                {
                    nSurface = 3; // metal ODF
                    sal_Int16 eMetalType = EnhancedCustomShapeMetalType::MetalODF;
                    pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"MetalType"_ustr );
                    if (pAny)
                    {
                        *pAny >>= eMetalType;
                        if (eMetalType == EnhancedCustomShapeMetalType::MetalMSCompatible)
                            nSurface = 4; // metal MS Office
                    }
                }
                else
                {
                    double fSpecularity = 0;
                    pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Specularity"_ustr );
                    if( pAny )
                        *pAny >>= fSpecularity;

                    const double e = 0.0001;
                    if( (fSpecularity > -e) && (fSpecularity < e) )
                    {
                        nSurface = 1; // matte
                    }
                    else
                    {
                        nSurface = 2; // plastic
                    }
                }
            }

            if( nFinalSurface == -1 )
            {
                nFinalSurface = nSurface;
            }
            else if( nFinalSurface != nSurface )
            {
                nFinalSurface = -1;
                break;
            }
        }
    }

    if( bHasCustomShape )
        rSet.Put( SfxInt32Item( SID_EXTRUSION_SURFACE, nFinalSurface ) );
    else
        rSet.DisableItem( SID_EXTRUSION_SURFACE );
}

static void getExtrusionDepthState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    double fFinalDepth = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            double fDepth = 1270.0; // =36pt ODF default
            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Depth"_ustr );
            if( pAny )
            {
                EnhancedCustomShapeParameterPair aDepthPropPair;
                if ( *pAny >>= aDepthPropPair )
                    aDepthPropPair.First.Value >>= fDepth;
            }

            if( fFinalDepth == -1 )
            {
                fFinalDepth = fDepth;
            }
            else if( !rtl::math::approxEqual(fFinalDepth, fDepth) )
            {
                fFinalDepth = -1;
                break;
            }
        }
    }


    FieldUnit eUnit = pSdrView->GetModel().GetUIUnit();
    rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast<sal_uInt16>(eUnit) ) );

    if( bHasCustomShape )
        rSet.Put( SvxDoubleItem( fFinalDepth, SID_EXTRUSION_DEPTH ) );
    else
        rSet.DisableItem( SID_EXTRUSION_DEPTH );
}

static bool compare_direction( const Direction3D& d1, const Direction3D& d2 )
{
    if( ((d1.DirectionX < 0) && (d2.DirectionX < 0)) || ((d1.DirectionX == 0) && (d2.DirectionX == 0)) || ((d1.DirectionX > 0) && (d2.DirectionX > 0)) )
    {
        if( ((d1.DirectionY < 0) && (d2.DirectionY < 0)) || ((d1.DirectionY == 0) && (d2.DirectionY == 0)) || ((d1.DirectionY > 0) && (d2.DirectionY > 0)) )
        {
            if( ((d1.DirectionZ < 0) && (d2.DirectionZ < 0)) || ((d1.DirectionZ == 0) && (d2.DirectionZ == 0)) || ((d1.DirectionZ > 0) && (d2.DirectionZ > 0)) )
            {
                return true;
            }
        }
    }

    return false;
}

static void getExtrusionLightingDirectionState( SdrView const * pSdrView, SfxItemSet&&nbsp;rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const Direction3D * pLighting1Defaults;
    const Direction3D * pLighting2Defaults;

    getLightingDirectionDefaults( &pLighting1Defaults, &pLighting2Defaults );

    const css::uno::Any* pAny;

    int nFinalDirection = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            Direction3D aFirstLightDirection( 50000, 0, 10000 );
            Direction3D aSecondLightDirection( -50000, 0, 10000 );

            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"FirstLightDirection"_ustr );
            if( pAny )
                *pAny >>= aFirstLightDirection;

            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"SecondLightDirection"_ustr );
            if( pAny )
                *pAny >>= aSecondLightDirection;

            int nDirection = -1;

            int j;
            for( j = 0; j < 9; j++ )
            {
                if( compare_direction( aFirstLightDirection, pLighting1Defaults[j] ) &&
                    compare_direction( aSecondLightDirection, pLighting2Defaults[j] ))
                {
                    nDirection = j;
                    break;
                }
            }

            if( nFinalDirection == -1 )
            {
                nFinalDirection = nDirection;
            }
            else if( nDirection != nFinalDirection )
            {
                nFinalDirection = -1;
            }

            if( nFinalDirection == -1 )
                break;
        }
    }

    if( bHasCustomShape )
        rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_DIRECTION, static_cast<sal_Int32>(nFinalDirection) ) );
    else
        rSet.DisableItem( SID_EXTRUSION_LIGHTING_DIRECTION );
}

static void getExtrusionLightingIntensityState( SdrView const * pSdrView, SfxItemSet&&nbsp;rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    int nFinalLevel = -1;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            double fBrightness = 22178.0 / 655.36;
            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Brightness"_ustr );
            if( pAny )
                *pAny >>= fBrightness;

            int nLevel;
            if( fBrightness >= 30.0 )
            {
                nLevel = 0; // Bright
            }
            else if( fBrightness >= 10.0 )
            {
                nLevel = 1; // Normal;
            }
            else
            {
                nLevel = 2; // Dim
            }

            if( nFinalLevel == -1 )
            {
                nFinalLevel = nLevel;
            }
            else if( nFinalLevel != nLevel )
            {
                nFinalLevel = -1;
                break;
            }
        }
    }

    if( bHasCustomShape )
        rSet.Put( SfxInt32Item( SID_EXTRUSION_LIGHTING_INTENSITY, nFinalLevel ) );
    else
        rSet.DisableItem( SID_EXTRUSION_LIGHTING_INTENSITY );
}

static void getExtrusionColorState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();

    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const css::uno::Any* pAny;

    bool bInit = false;
    bool bAmbigius = false;
    Color aFinalColor;
    bool bHasCustomShape = false;

    for(size_t i=0; i<nCount; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );

            // see if this is an extruded customshape
            if( !bHasCustomShape )
            {
                const Any* pAny_ = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny_ )
                    *pAny_ >>= bHasCustomShape;

                if( !bHasCustomShape )
                    continue;
            }

            Color aColor;

            bool bUseColor = false;
            pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, u"Color"_ustr );
            if( pAny )
                *pAny >>= bUseColor;

            if( bUseColor )
            {
                const XSecondaryFillColorItem& rItem = pObj->GetMergedItem( XATTR_SECONDARYFILLCOLOR );
                aColor = rItem.GetColorValue();
            }
            else
            {
                aColor = COL_AUTO;
            }

            if( !bInit )
            {
                aFinalColor = aColor;
                bInit = true;
            }
            else if( aFinalColor != aColor )
            {
                bAmbigius = true;
                break;
            }
        }
    }

    if( bAmbigius )
        aFinalColor = COL_AUTO;

    if( bHasCustomShape )
        rSet.Put( SvxColorItem( aFinalColor, SID_EXTRUSION_3D_COLOR ) );
    else
        rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
}

namespace svx {
bool checkForSelectedCustomShapes( SdrView const * pSdrView, bool bOnlyExtruded )
{
    static constexpr OUString sExtrusion = u"Extrusion"_ustr;

    const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
    const size_t nCount = rMarkList.GetMarkCount();
    bool bFound = false;

    for(size_t i=0;(i<nCount) && !bFound ; ++i)
    {
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
        ifdynamic_cast<const SdrObjCustomShape*>( pObj) !=  nullptr )
        {
            if( bOnlyExtruded )
            {
                const SdrCustomShapeGeometryItem & rGeometryItem( pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
                const Any* pAny = rGeometryItem.GetPropertyValueByName( sExtrusion, sExtrusion );
                if( pAny )
                    *pAny >>= bFound;
            }
            else
            {
                bFound = true;
            }
        }
    }

    return bFound;
}
}

void ExtrusionBar::getState( SdrView const * pSdrView, SfxItemSet& rSet )
{
    getExtrusionDirectionState( pSdrView, rSet );
    getExtrusionProjectionState( pSdrView, rSet );

    const bool bOnlyExtrudedCustomShapes(checkForSelectedCustomShapes( pSdrView, true ));

    if (! bOnlyExtrudedCustomShapes)
    {
        rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
        rSet.DisableItem( SID_EXTRUSION_TILT_DOWN );
        rSet.DisableItem( SID_EXTRUSION_TILT_UP );
        rSet.DisableItem( SID_EXTRUSION_TILT_LEFT );
        rSet.DisableItem( SID_EXTRUSION_TILT_RIGHT );
        rSet.DisableItem( SID_EXTRUSION_3D_COLOR );
        rSet.DisableItem( SID_EXTRUSION_DEPTH_FLOATER );
        rSet.DisableItem( SID_EXTRUSION_DIRECTION_FLOATER );
        rSet.DisableItem( SID_EXTRUSION_LIGHTING_FLOATER );
        rSet.DisableItem( SID_EXTRUSION_SURFACE_FLOATER );
    }

    if( !checkForSelectedCustomShapes( pSdrView, false ) )
        rSet.DisableItem( SID_EXTRUSION_TOGGLE );

    getExtrusionDepthState( pSdrView, rSet );
    getExtrusionSurfaceState( pSdrView, rSet );
    getExtrusionLightingIntensityState( pSdrView, rSet );
    getExtrusionLightingDirectionState( pSdrView, rSet );
    getExtrusionColorState( pSdrView, rSet );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=92 G=93

¤ Dauer der Verarbeitung: 0.14 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.