/* -*- 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 "ShapeController.hxx"
#include <ShapeController.h>
#include <ChartController.hxx>
#include <ViewElementListProvider.hxx>
#include <dlg_ShapeFont.hxx>
#include <dlg_ShapeParagraph.hxx>
#include <chartview/DrawModelWrapper.hxx>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
#include <com/sun/star/frame/CommandGroup.hpp>
#include <com/sun/star/frame/XStorable.hpp>

#include <vcl/svapp.hxx>
#include <editeng/formatbreakitem.hxx>
#include <editeng/editids.hrc>
#include <editeng/eeitem.hxx>
#include <editeng/hyphenzoneitem.hxx>
#include <editeng/orphitem.hxx>
#include <editeng/spltitem.hxx>
#include <svx/svxdlg.hxx>
#include <editeng/widwitem.hxx>
#include <tools/diagnose_ex.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::frame;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;

namespace chart
{

ShapeController::ShapeController( const Reference< uno::XComponentContext >& rxContext,
        ChartController* pController )
    :FeatureCommandDispatchBase( rxContext )
    ,m_pChartController( pController )
{
}

ShapeController::~ShapeController()
{
}

// WeakComponentImplHelperBase
void ShapeController::disposing()
{
}

// XEventListener
void ShapeController::disposing( const lang::EventObject& /* Source */ )
{
}

FeatureState ShapeController::getState( const OUString& rCommand )
{
    FeatureState aReturn;
    aReturn.bEnabled = false;
    aReturn.aState <<= false;

    bool bWritable = false;
    if ( m_pChartController )
    {
        Reference< frame::XStorable > xStorable( m_pChartController->getModel(), uno::UNO_QUERY );
        if ( xStorable.is() )
        {
            bWritable = !xStorable->isReadonly();
        }
    }

    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( rCommand );
    if ( aIter != m_aSupportedFeatures.end() )
    {
        sal_uInt16 nFeatureId = aIter->second.nFeatureId;
        switch ( nFeatureId )
        {
            case COMMAND_ID_FORMAT_LINE:
            case COMMAND_ID_FORMAT_AREA:
            case COMMAND_ID_TEXT_ATTRIBUTES:
            case COMMAND_ID_TRANSFORM_DIALOG:
            case COMMAND_ID_OBJECT_TITLE_DESCRIPTION:
            case COMMAND_ID_RENAME_OBJECT:
                {
                    aReturn.bEnabled = bWritable;
                    aReturn.aState <<= false;
                }
                break;
            case COMMAND_ID_BRING_TO_FRONT:
            case COMMAND_ID_FORWARD:
                {
                    aReturn.bEnabled = ( bWritable && isForwardPossible() );
                    aReturn.aState <<= false;
                }
                break;
            case COMMAND_ID_BACKWARD:
            case COMMAND_ID_SEND_TO_BACK:
                {

                    aReturn.bEnabled = ( bWritable && isBackwardPossible() );
                    aReturn.aState <<= false;
                }
                break;
            case COMMAND_ID_FONT_DIALOG:
            case COMMAND_ID_PARAGRAPH_DIALOG:
                {
                    aReturn.bEnabled = bWritable;
                    aReturn.aState <<= false;
                }
                break;
            default:
                {
                    aReturn.bEnabled = false;
                    aReturn.aState <<= false;
                }
                break;
        }
    }

    return aReturn;
}

void ShapeController::execute( const OUString& rCommand, const Sequence< beans::PropertyValue>& )
{
    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( rCommand );
    if ( aIter == m_aSupportedFeatures.end() )
        return;

    sal_uInt16 nFeatureId = aIter->second.nFeatureId;
    switch ( nFeatureId )
    {
        case COMMAND_ID_FORMAT_LINE:
            {
                executeDispatch_FormatLine();
            }
            break;
        case COMMAND_ID_FORMAT_AREA:
            {
                executeDispatch_FormatArea();
            }
            break;
        case COMMAND_ID_TEXT_ATTRIBUTES:
            {
                executeDispatch_TextAttributes();
            }
            break;
        case COMMAND_ID_TRANSFORM_DIALOG:
            {
                executeDispatch_TransformDialog();
            }
            break;
        case COMMAND_ID_OBJECT_TITLE_DESCRIPTION:
            {
                executeDispatch_ObjectTitleDescription();
            }
            break;
        case COMMAND_ID_RENAME_OBJECT:
            {
                executeDispatch_RenameObject();
            }
            break;
        case COMMAND_ID_BRING_TO_FRONT:
        case COMMAND_ID_FORWARD:
        case COMMAND_ID_BACKWARD:
        case COMMAND_ID_SEND_TO_BACK:
            {
                executeDispatch_ChangeZOrder( nFeatureId );
            }
            break;
        case COMMAND_ID_FONT_DIALOG:
            {
                executeDispatch_FontDialog();
            }
            break;
        case COMMAND_ID_PARAGRAPH_DIALOG:
            {
                executeDispatch_ParagraphDialog();
            }
            break;
        default:
            {
            }
            break;
    }
}

void ShapeController::describeSupportedFeatures()
{
    implDescribeSupportedFeature( ".uno:FormatLine",                COMMAND_ID_FORMAT_LINE,                 CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:FormatArea",                COMMAND_ID_FORMAT_AREA,                 CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:TextAttributes",            COMMAND_ID_TEXT_ATTRIBUTES,             CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:TransformDialog",           COMMAND_ID_TRANSFORM_DIALOG,            CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:ObjectTitleDescription",    COMMAND_ID_OBJECT_TITLE_DESCRIPTION,    CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:RenameObject",              COMMAND_ID_RENAME_OBJECT,               CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:BringToFront",              COMMAND_ID_BRING_TO_FRONT,              CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:Forward",                   COMMAND_ID_FORWARD,                     CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:Backward",                  COMMAND_ID_BACKWARD,                    CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:SendToBack",                COMMAND_ID_SEND_TO_BACK,                CommandGroup::FORMAT );
    implDescribeSupportedFeature( ".uno:FontDialog",                COMMAND_ID_FONT_DIALOG,                 CommandGroup::EDIT );
    implDescribeSupportedFeature( ".uno:ParagraphDialog",           COMMAND_ID_PARAGRAPH_DIALOG,            CommandGroup::EDIT );
}

IMPL_LINK( ShapeController, CheckNameHdl, AbstractSvxObjectNameDialog&, rDialog, bool )
{
    OUString aName;
    rDialog.GetName( aName );

    if ( !aName.isEmpty() )
    {
        DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : nullptr );
        if ( pDrawViewWrapper && pDrawViewWrapper->getNamedSdrObject( aName ) )
        {
            return false;
        }
    }
    return true;
}

void ShapeController::executeDispatch_FormatLine()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper();
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pChartWindow && pDrawModelWrapper && pDrawViewWrapper) )
        return;

    SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
    SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() );
    bool bHasMarked = pDrawViewWrapper->AreObjectsMarked();
    if ( bHasMarked )
    {
        pDrawViewWrapper->MergeAttrFromMarked( aAttr, false );
    }
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    ScopedVclPtr< SfxAbstractTabDialog > pDlg(
        pFact->CreateSvxLineTabDialog(pChartWindow, &aAttr, &pDrawModelWrapper->getSdrModel(),
            pSelectedObj, bHasMarked));
    if ( pDlg->Execute() == RET_OK )
    {
        const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet();
        if ( bHasMarked )
        {
            pDrawViewWrapper->SetAttrToMarked( *pOutAttr, false );
        }
        else
        {
            pDrawViewWrapper->SetDefaultAttr( *pOutAttr, false );
        }
    }
}

void ShapeController::executeDispatch_FormatArea()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper();
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pChartWindow && pDrawModelWrapper && pDrawViewWrapper) )
        return;

    SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() );
    bool bHasMarked = pDrawViewWrapper->AreObjectsMarked();
    if ( bHasMarked )
    {
        pDrawViewWrapper->MergeAttrFromMarked( aAttr, false );
    }
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    ScopedVclPtr< AbstractSvxAreaTabDialog > pDlg(
            pFact->CreateSvxAreaTabDialog(pChartWindow, &aAttr, &pDrawModelWrapper->getSdrModel(), true));
    if ( pDlg->Execute() == RET_OK )
    {
        const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet();
        if ( bHasMarked )
        {
            pDrawViewWrapper->SetAttrToMarked( *pOutAttr, false );
        }
        else
        {
            pDrawViewWrapper->SetDefaultAttr( *pOutAttr, false );
        }
    }
}

void ShapeController::executeDispatch_TextAttributes()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pChartWindow && pDrawViewWrapper) )
        return;

    SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() );
    bool bHasMarked = pDrawViewWrapper->AreObjectsMarked();
    if ( bHasMarked )
    {
        pDrawViewWrapper->MergeAttrFromMarked( aAttr, false );
    }
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    ScopedVclPtr< SfxAbstractTabDialog > pDlg(
        pFact->CreateTextTabDialog(pChartWindow, &aAttr, pDrawViewWrapper));
    if ( pDlg->Execute() == RET_OK )
    {
        const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet();
        if ( bHasMarked )
        {
            pDrawViewWrapper->SetAttributes( *pOutAttr );
        }
        else
        {
            pDrawViewWrapper->SetDefaultAttr( *pOutAttr, false );
        }
    }
}

void ShapeController::executeDispatch_TransformDialog()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pChartWindow && pDrawViewWrapper) )
        return;

    SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
    if ( pSelectedObj && pSelectedObj->GetObjIdentifier() == OBJ_CAPTION )
    {
        // item set for caption
        SfxItemSet aAttr( pDrawViewWrapper->GetModel()->GetItemPool() );
        pDrawViewWrapper->GetAttributes( aAttr );
        // item set for position and size
        SfxItemSet aGeoAttr( pDrawViewWrapper->GetGeoAttrFromMarked() );
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
        ScopedVclPtr< SfxAbstractTabDialog > pDlg(
            pFact->CreateCaptionDialog(pChartWindow, pDrawViewWrapper));
        const sal_uInt16* pRange = pDlg->GetInputRanges( *aAttr.GetPool() );
        SfxItemSet aCombAttr( *aAttr.GetPool(), pRange );
        aCombAttr.Put( aAttr );
        aCombAttr.Put( aGeoAttr );
        pDlg->SetInputSet( &aCombAttr );
        if ( pDlg->Execute() == RET_OK )
        {
            const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet();
            pDrawViewWrapper->SetAttributes( *pOutAttr );
            pDrawViewWrapper->SetGeoAttrToMarked( *pOutAttr );
        }
    }
    else
    {
        SfxItemSet aGeoAttr( pDrawViewWrapper->GetGeoAttrFromMarked() );
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
        ScopedVclPtr< SfxAbstractTabDialog > pDlg(
            pFact->CreateSvxTransformTabDialog(pChartWindow, &aGeoAttr, pDrawViewWrapper));
        if ( pDlg->Execute() == RET_OK )
        {
            const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet();
            pDrawViewWrapper->SetGeoAttrToMarked( *pOutAttr );
        }
    }
}

void ShapeController::executeDispatch_ObjectTitleDescription()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pDrawViewWrapper && pDrawViewWrapper->GetMarkedObjectCount() == 1) )
        return;

    SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
    if ( !pSelectedObj )
        return;

    OUString aTitle( pSelectedObj->GetTitle() );
    OUString aDescription( pSelectedObj->GetDescription() );
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    ScopedVclPtr< AbstractSvxObjectTitleDescDialog > pDlg(
        pFact->CreateSvxObjectTitleDescDialog(pChartWindow, aTitle, aDescription));
    if ( pDlg->Execute() == RET_OK )
    {
        pDlg->GetTitle( aTitle );
        pDlg->GetDescription( aDescription );
        pSelectedObj->SetTitle( aTitle );
        pSelectedObj->SetDescription( aDescription );
    }
}

void ShapeController::executeDispatch_RenameObject()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pDrawViewWrapper && pDrawViewWrapper->GetMarkedObjectCount() == 1) )
        return;

    SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
    if ( !pSelectedObj )
        return;

    OUString aName = pSelectedObj->GetName();
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    ScopedVclPtr< AbstractSvxObjectNameDialog > pDlg(
        pFact->CreateSvxObjectNameDialog(pChartWindow, aName));
    pDlg->SetCheckNameHdl( LINK( this, ShapeController, CheckNameHdl ) );
    if ( pDlg->Execute() == RET_OK )
    {
        pDlg->GetName(aName);
        if (pSelectedObj->GetName() == aName)
        {
            pSelectedObj->SetName( aName );
        }
    }
}

void ShapeController::executeDispatch_ChangeZOrder( sal_uInt16 nId )
{
    SolarMutexGuard aGuard;
    DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : nullptr );
    if ( !pDrawViewWrapper )
        return;

    switch ( nId )
    {
        case COMMAND_ID_BRING_TO_FRONT:
            {
                if ( isForwardPossible() )
                {
                    pDrawViewWrapper->PutMarkedToTop();
                }
            }
            break;
        case COMMAND_ID_FORWARD:
            {
                if ( isForwardPossible() )
                {
                    pDrawViewWrapper->MovMarkedToTop();
                }
            }
            break;
        case COMMAND_ID_BACKWARD:
            {
                if ( isBackwardPossible() )
                {
                    pDrawViewWrapper->MovMarkedToBtm();
                }
            }
            break;
        case COMMAND_ID_SEND_TO_BACK:
            {
                if ( isBackwardPossible() )
                {
                    SdrObject* pFirstObj = getFirstAdditionalShape();
                    pDrawViewWrapper->PutMarkedBehindObj( pFirstObj );
                }
            }
            break;
        default:
            {
            }
            break;
    }
}

void ShapeController::executeDispatch_FontDialog()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper();
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( pChartWindow && pDrawModelWrapper && pDrawViewWrapper )
    {
        SfxItemSet aAttr( pDrawViewWrapper->GetModel()->GetItemPool() );
        pDrawViewWrapper->GetAttributes( aAttr );
        ViewElementListProvider aViewElementListProvider( pDrawModelWrapper );
        ShapeFontDialog aDlg(pChartWindow, &aAttr, &aViewElementListProvider);
        if (aDlg.run() == RET_OK)
        {
            const SfxItemSet* pOutAttr = aDlg.GetOutputItemSet();
            pDrawViewWrapper->SetAttributes( *pOutAttr );
        }
    }
}

void ShapeController::executeDispatch_ParagraphDialog()
{
    SolarMutexGuard aGuard;
    if ( !m_pChartController )
        return;

    weld::Window* pChartWindow(m_pChartController->GetChartFrame());
    DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
    if ( !(pChartWindow && pDrawViewWrapper) )
        return;

    SfxItemPool& rPool = pDrawViewWrapper->GetModel()->GetItemPool();
    SfxItemSet aAttr( rPool );
    pDrawViewWrapper->GetAttributes( aAttr );

    SfxItemSet aNewAttr(
        rPool,
        svl::Items<
            EE_ITEMS_START, EE_ITEMS_END,
            SID_ATTR_PARA_PAGEBREAK, SID_ATTR_PARA_WIDOWS>{});
    aNewAttr.Put( aAttr );
    aNewAttr.Put( SvxHyphenZoneItem( false, SID_ATTR_PARA_HYPHENZONE ) );
    aNewAttr.Put( SvxFormatBreakItem( SvxBreak::NONE, SID_ATTR_PARA_PAGEBREAK ) );
    aNewAttr.Put( SvxFormatSplitItem( true, SID_ATTR_PARA_SPLIT)  );
    aNewAttr.Put( SvxWidowsItem( 0, SID_ATTR_PARA_WIDOWS) );
    aNewAttr.Put( SvxOrphansItem( 0, SID_ATTR_PARA_ORPHANS) );

    ShapeParagraphDialog aDlg(pChartWindow, &aNewAttr);
    if (aDlg.run() == RET_OK)
    {
        const SfxItemSet* pOutAttr = aDlg.GetOutputItemSet();
        pDrawViewWrapper->SetAttributes( *pOutAttr );
    }
}

SdrObject* ShapeController::getFirstAdditionalShape()
{
    SdrObject* pFirstObj = nullptr;

    try
    {
        DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : nullptr );
        if ( pDrawModelWrapper )
        {
            Reference< drawing::XShape > xFirstShape;
            Reference< drawing::XDrawPage > xDrawPage( pDrawModelWrapper->getMainDrawPage() );
            Reference< drawing::XShapes > xDrawPageShapes( xDrawPage, uno::UNO_QUERY_THROW );
            Reference< drawing::XShapes > xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage ) );
            sal_Int32 nCount = xDrawPageShapes->getCount();
            for ( sal_Int32 i = 0; i < nCount; ++i )
            {
                Reference< drawing::XShape > xShape;
                if ( xDrawPageShapes->getByIndex( i ) >>= xShape )
                {
                    if ( xShape.is() && xShape != xChartRoot )
                    {
                        xFirstShape = xShape;
                        break;
                    }
                }
            }
            if ( xFirstShape.is() )
            {
                pFirstObj = DrawViewWrapper::getSdrObject( xFirstShape );
            }
        }
    }
    catch ( const uno::Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }

    return pFirstObj;
}

SdrObject* ShapeController::getLastAdditionalShape()
{
    SdrObject* pLastObj = nullptr;

    try
    {
        DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : nullptr );
        if ( pDrawModelWrapper )
        {
            Reference< drawing::XShape > xLastShape;
            Reference< drawing::XDrawPage > xDrawPage( pDrawModelWrapper->getMainDrawPage() );
            Reference< drawing::XShapes > xDrawPageShapes( xDrawPage, uno::UNO_QUERY_THROW );
            Reference< drawing::XShapes > xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage ) );
            sal_Int32 nCount = xDrawPageShapes->getCount();
            for ( sal_Int32 i = nCount - 1; i >= 0; --i )
            {
                Reference< drawing::XShape > xShape;
                if ( xDrawPageShapes->getByIndex( i ) >>= xShape )
                {
                    if ( xShape.is() && xShape != xChartRoot )
                    {
                        xLastShape = xShape;
                        break;
                    }
                }
            }
            if ( xLastShape.is() )
            {
                pLastObj = DrawViewWrapper::getSdrObject( xLastShape );
            }
        }
    }
    catch ( const uno::Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }

    return pLastObj;
}

bool ShapeController::isBackwardPossible()
{
    if ( m_pChartController && m_pChartController->isAdditionalShapeSelected() )
    {
        SolarMutexGuard aGuard;
        DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
        if ( pDrawViewWrapper )
        {
            SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
            SdrObject* pFirstObj = getFirstAdditionalShape();
            if ( pSelectedObj && pFirstObj && pSelectedObj != pFirstObj )
            {
                return true;
            }
        }
    }
    return false;
}

bool ShapeController::isForwardPossible()
{
    if ( m_pChartController && m_pChartController->isAdditionalShapeSelected() )
    {
        SolarMutexGuard aGuard;
        DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper();
        if ( pDrawViewWrapper )
        {
            SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject();
            SdrObject* pLastObj = getLastAdditionalShape();
            if ( pSelectedObj && pLastObj && pSelectedObj != pLastObj )
            {
                return true;
            }
        }
    }
    return false;
}

} //  namespace chart

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