diff options
Diffstat (limited to 'chart2/source/controller')
75 files changed, 6907 insertions, 1386 deletions
diff --git a/chart2/source/controller/accessibility/AccessibleBase.cxx b/chart2/source/controller/accessibility/AccessibleBase.cxx index cab7d3db0d62..00335eab296e 100644 --- a/chart2/source/controller/accessibility/AccessibleBase.cxx +++ b/chart2/source/controller/accessibility/AccessibleBase.cxx @@ -29,6 +29,7 @@ #include "precompiled_chart2.hxx" #include "AccessibleBase.hxx" +#include "AccessibleChartShape.hxx" #include "ObjectHierarchy.hxx" #include "ObjectIdentifier.hxx" #include "chartview/ExplicitValueProvider.hxx" @@ -269,15 +270,15 @@ bool AccessibleBase::ImplUpdateChildren() { ObjectHierarchy::tChildContainer aModelChildren( m_aAccInfo.m_spObjectHierarchy->getChildren( GetId() )); - ::std::vector< ChildCIDMap::key_type > aAccChildren; + ::std::vector< ChildOIDMap::key_type > aAccChildren; aAccChildren.reserve( aModelChildren.size()); - ::std::transform( m_aChildCIDMap.begin(), m_aChildCIDMap.end(), + ::std::transform( m_aChildOIDMap.begin(), m_aChildOIDMap.end(), ::std::back_inserter( aAccChildren ), - ::std::select1st< ChildCIDMap::value_type >()); + ::std::select1st< ChildOIDMap::value_type >()); ::std::sort( aModelChildren.begin(), aModelChildren.end()); - ::std::vector< OUString > aChildrenToRemove, aChildrenToAdd; + ::std::vector< ObjectHierarchy::tOID > aChildrenToRemove, aChildrenToAdd; ::std::set_difference( aModelChildren.begin(), aModelChildren.end(), aAccChildren.begin(), aAccChildren.end(), ::std::back_inserter( aChildrenToAdd )); @@ -285,10 +286,10 @@ bool AccessibleBase::ImplUpdateChildren() aModelChildren.begin(), aModelChildren.end(), ::std::back_inserter( aChildrenToRemove )); - ::std::vector< OUString >::const_iterator aIt( aChildrenToRemove.begin()); + ::std::vector< ObjectHierarchy::tOID >::const_iterator aIt( aChildrenToRemove.begin()); for( ; aIt != aChildrenToRemove.end(); ++aIt ) { - RemoveChildById( *aIt ); + RemoveChildByOId( *aIt ); } AccessibleElementInfo aAccInfo( GetInfo()); @@ -296,8 +297,15 @@ bool AccessibleBase::ImplUpdateChildren() for( aIt = aChildrenToAdd.begin(); aIt != aChildrenToAdd.end(); ++aIt ) { - aAccInfo.m_aCID = *aIt; - AddChild( ChartElementFactory::CreateChartElement( aAccInfo )); + aAccInfo.m_aOID = *aIt; + if ( aIt->isAutoGeneratedObject() ) + { + AddChild( ChartElementFactory::CreateChartElement( aAccInfo ) ); + } + else if ( aIt->isAdditionalShape() ) + { + AddChild( new AccessibleChartShape( aAccInfo, true, false ) ); + } } bResult = true; } @@ -316,7 +324,7 @@ void AccessibleBase::AddChild( AccessibleBase * pChild ) Reference< XAccessible > xChild( pChild ); m_aChildList.push_back( xChild ); - m_aChildCIDMap[ pChild->GetId() ] = xChild; + m_aChildOIDMap[ pChild->GetId() ] = xChild; // inform listeners of new child if( m_bChildrenInitialized ) @@ -335,18 +343,18 @@ void AccessibleBase::AddChild( AccessibleBase * pChild ) /** in this method we imply that the Reference< XAccessible > elements in the vector are AccessibleBase objects ! */ -void AccessibleBase::RemoveChildById( const ::rtl::OUString & rId ) +void AccessibleBase::RemoveChildByOId( const ObjectIdentifier& rOId ) { // /-- ClearableMutexGuard aGuard( GetMutex() ); - ChildCIDMap::iterator aIt( m_aChildCIDMap.find( rId )); - if( aIt != m_aChildCIDMap.end()) + ChildOIDMap::iterator aIt( m_aChildOIDMap.find( rOId )); + if( aIt != m_aChildOIDMap.end()) { Reference< XAccessible > xChild( aIt->second ); // remove from map - m_aChildCIDMap.erase( aIt ); + m_aChildOIDMap.erase( aIt ); // search child in vector ChildListVectorType::iterator aVecIter = @@ -444,7 +452,7 @@ void AccessibleBase::KillAllChildren() // remove all children m_aChildList.clear(); - m_aChildCIDMap.clear(); + m_aChildOIDMap.clear(); aGuard.clear(); // \-- @@ -485,7 +493,7 @@ void AccessibleBase::SetInfo( const AccessibleElementInfo & rNewInfo ) AccessibleUniqueId AccessibleBase::GetId() const { - return m_aAccInfo.m_aCID; + return m_aAccInfo.m_aOID; } // ____________________________________ @@ -662,14 +670,15 @@ Reference< XAccessibleStateSet > SAL_CALL AccessibleBase::getAccessibleStateSet( { if( ! m_bStateSetInitialized ) { - OUString aSelCID; Reference< view::XSelectionSupplier > xSelSupp( GetInfo().m_xSelectionSupplier ); - if( xSelSupp.is() && - ( xSelSupp->getSelection() >>= aSelCID ) && - GetId().equals( aSelCID ) ) + if ( xSelSupp.is() ) { - AddState( AccessibleStateType::SELECTED ); - AddState( AccessibleStateType::FOCUSED ); + ObjectIdentifier aOID( xSelSupp->getSelection() ); + if ( aOID.isValid() && GetId() == aOID ) + { + AddState( AccessibleStateType::SELECTED ); + AddState( AccessibleStateType::FOCUSED ); + } } m_bStateSetInitialized = true; } @@ -752,7 +761,7 @@ awt::Rectangle SAL_CALL AccessibleBase::getBounds() if( pExplicitValueProvider ) { Window* pWindow( VCLUnoHelper::GetWindow( m_aAccInfo.m_xWindow )); - awt::Rectangle aLogicRect( pExplicitValueProvider->getRectangleOfObject( m_aAccInfo.m_aCID )); + awt::Rectangle aLogicRect( pExplicitValueProvider->getRectangleOfObject( m_aAccInfo.m_aOID.getObjectCID() )); if( pWindow ) { Rectangle aRect( aLogicRect.X, aLogicRect.Y, @@ -825,10 +834,11 @@ void SAL_CALL AccessibleBase::grabFocus() { CheckDisposeState(); - OUString aSelCID; Reference< view::XSelectionSupplier > xSelSupp( GetInfo().m_xSelectionSupplier ); - if( xSelSupp.is()) - xSelSupp->select( uno::makeAny( GetId())); + if ( xSelSupp.is() ) + { + xSelSupp->select( GetId().getAny() ); + } } sal_Int32 SAL_CALL AccessibleBase::getForeground() @@ -849,9 +859,10 @@ sal_Int32 AccessibleBase::getColor( eColorType eColType ) if( m_bAlwaysTransparent ) return nResult; - ObjectType eType( ObjectIdentifier::getObjectType( m_aAccInfo.m_aCID )); + ObjectIdentifier aOID( m_aAccInfo.m_aOID ); + ObjectType eType( aOID.getObjectType() ); Reference< beans::XPropertySet > xObjProp; - OUString aObjectCID = m_aAccInfo.m_aCID; + OUString aObjectCID = aOID.getObjectCID(); if( eType == OBJECTTYPE_LEGEND_ENTRY ) { // for colors get the data series/point properties diff --git a/chart2/source/controller/accessibility/AccessibleChartElement.cxx b/chart2/source/controller/accessibility/AccessibleChartElement.cxx index a2c7b7aa8261..2361cc62c389 100644 --- a/chart2/source/controller/accessibility/AccessibleChartElement.cxx +++ b/chart2/source/controller/accessibility/AccessibleChartElement.cxx @@ -101,7 +101,7 @@ bool AccessibleChartElement::ImplUpdateChildren() bool bResult = false; Reference< chart2::XTitle > xTitle( ObjectIdentifier::getObjectPropertySet( - GetInfo().m_aCID, Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )), + GetInfo().m_aOID.getObjectCID(), Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )), uno::UNO_QUERY ); m_bHasText = xTitle.is(); @@ -136,7 +136,7 @@ void AccessibleChartElement::InitTextEdit() { Reference< lang::XInitialization > xInit( m_xTextHelper, uno::UNO_QUERY_THROW ); Sequence< uno::Any > aArgs( 3 ); - aArgs[0] <<= GetInfo().m_aCID; + aArgs[0] <<= GetInfo().m_aOID.getObjectCID(); aArgs[1] <<= Reference< XAccessible >( this ); aArgs[2] <<= Reference< awt::XWindow >( GetInfo().m_xWindow ); xInit->initialize( aArgs ); @@ -224,7 +224,7 @@ OUString SAL_CALL AccessibleChartElement::getAccessibleName() throw (::com::sun::star::uno::RuntimeException) { return ObjectNameProvider::getNameForCID( - GetInfo().m_aCID, GetInfo().m_xChartDocument ); + GetInfo().m_aOID.getObjectCID(), GetInfo().m_xChartDocument ); } // ________ AccessibleChartElement::XAccessibleContext (overloaded) ________ @@ -249,7 +249,7 @@ Reference< awt::XFont > SAL_CALL AccessibleChartElement::getFont() { Reference< beans::XMultiPropertySet > xObjProp( ObjectIdentifier::getObjectPropertySet( - GetInfo().m_aCID, Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )), uno::UNO_QUERY ); + GetInfo().m_aOID.getObjectCID(), Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )), uno::UNO_QUERY ); awt::FontDescriptor aDescr( CharacterProperties::createFontDescriptorFromPropertySet( xObjProp )); xFont = xDevice->getFont( aDescr ); @@ -270,7 +270,7 @@ OUString SAL_CALL AccessibleChartElement::getToolTipText() CheckDisposeState(); return ObjectNameProvider::getHelpText( - GetInfo().m_aCID, Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )); + GetInfo().m_aOID.getObjectCID(), Reference< chart2::XChartDocument >( GetInfo().m_xChartDocument )); } // ________ XAccessibleComponent ________ @@ -280,7 +280,7 @@ sal_Bool SAL_CALL AccessibleChartElement::containsPoint( const awt::Point& aPoin return AccessibleBase::containsPoint( aPoint ); } -Reference< accessibility::XAccessible > SAL_CALL AccessibleChartElement::getAccessibleAtPoint( const awt::Point& aPoint ) +Reference< XAccessible > SAL_CALL AccessibleChartElement::getAccessibleAtPoint( const awt::Point& aPoint ) throw (uno::RuntimeException) { return AccessibleBase::getAccessibleAtPoint( aPoint ); diff --git a/chart2/source/controller/accessibility/AccessibleChartShape.cxx b/chart2/source/controller/accessibility/AccessibleChartShape.cxx new file mode 100644 index 000000000000..bbf6176641da --- /dev/null +++ b/chart2/source/controller/accessibility/AccessibleChartShape.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "AccessibleChartShape.hxx" +#include "ObjectHierarchy.hxx" +#include "ObjectIdentifier.hxx" + +#include <toolkit/helper/vclunohelper.hxx> +#include <svx/ShapeTypeHandler.hxx> +#include <svx/AccessibleShape.hxx> +#include <svx/AccessibleShapeInfo.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; + + +namespace chart +{ + +AccessibleChartShape::AccessibleChartShape( + const AccessibleElementInfo& rAccInfo, + bool bMayHaveChildren, bool bAlwaysTransparent ) + :impl::AccessibleChartShape_Base( rAccInfo, bMayHaveChildren, bAlwaysTransparent ) + ,m_pAccShape( NULL ) +{ + if ( rAccInfo.m_aOID.isAdditionalShape() ) + { + Reference< drawing::XShape > xShape( rAccInfo.m_aOID.getAdditionalShape() ); + Reference< XAccessible > xParent; + if ( rAccInfo.m_pParent ) + { + xParent.set( rAccInfo.m_pParent ); + } + sal_Int32 nIndex = -1; + if ( rAccInfo.m_spObjectHierarchy ) + { + nIndex = rAccInfo.m_spObjectHierarchy->getIndexInParent( rAccInfo.m_aOID ); + } + ::accessibility::AccessibleShapeInfo aShapeInfo( xShape, xParent, nIndex ); + + m_aShapeTreeInfo.SetSdrView( rAccInfo.m_pSdrView ); + m_aShapeTreeInfo.SetController( NULL ); + m_aShapeTreeInfo.SetWindow( VCLUnoHelper::GetWindow( rAccInfo.m_xWindow ) ); + m_aShapeTreeInfo.SetViewForwarder( rAccInfo.m_pViewForwarder ); + + ::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance(); + m_pAccShape = rShapeHandler.CreateAccessibleObject( aShapeInfo, m_aShapeTreeInfo ); + if ( m_pAccShape ) + { + m_pAccShape->acquire(); + m_pAccShape->Init(); + } + } +} + +AccessibleChartShape::~AccessibleChartShape() +{ + OSL_ASSERT( CheckDisposeState( false /* don't throw exceptions */ ) ); + + if ( m_pAccShape ) + { + m_pAccShape->dispose(); + m_pAccShape->release(); + } +} + +// ________ XServiceInfo ________ +::rtl::OUString AccessibleChartShape::getImplementationName() + throw (RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AccessibleChartShape" ) ); +} + +// ________ XAccessibleContext ________ +sal_Int32 AccessibleChartShape::getAccessibleChildCount() + throw (RuntimeException) +{ + sal_Int32 nCount(0); + if ( m_pAccShape ) + { + nCount = m_pAccShape->getAccessibleChildCount(); + } + return nCount; +} + +Reference< XAccessible > AccessibleChartShape::getAccessibleChild( sal_Int32 i ) + throw (lang::IndexOutOfBoundsException, RuntimeException) +{ + Reference< XAccessible > xChild; + if ( m_pAccShape ) + { + xChild = m_pAccShape->getAccessibleChild( i ); + } + return xChild; +} + +sal_Int16 AccessibleChartShape::getAccessibleRole() + throw (RuntimeException) +{ + sal_Int16 nRole(0); + if ( m_pAccShape ) + { + nRole = m_pAccShape->getAccessibleRole(); + } + return nRole; +} + +::rtl::OUString AccessibleChartShape::getAccessibleDescription() + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString aDescription; + if ( m_pAccShape ) + { + aDescription = m_pAccShape->getAccessibleDescription(); + } + return aDescription; +} + +::rtl::OUString AccessibleChartShape::getAccessibleName() + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString aName; + if ( m_pAccShape ) + { + aName = m_pAccShape->getAccessibleName(); + } + return aName; +} + +// ________ XAccessibleComponent ________ +sal_Bool AccessibleChartShape::containsPoint( const awt::Point& aPoint ) + throw (uno::RuntimeException) +{ + sal_Bool bReturn = sal_False; + if ( m_pAccShape ) + { + bReturn = m_pAccShape->containsPoint( aPoint ); + } + return bReturn; +} + +Reference< XAccessible > AccessibleChartShape::getAccessibleAtPoint( const awt::Point& aPoint ) + throw (uno::RuntimeException) +{ + Reference< XAccessible > xResult; + if ( m_pAccShape ) + { + xResult.set( m_pAccShape->getAccessibleAtPoint( aPoint ) ); + } + return xResult; +} + +awt::Rectangle AccessibleChartShape::getBounds() + throw (uno::RuntimeException) +{ + awt::Rectangle aBounds; + if ( m_pAccShape ) + { + aBounds = m_pAccShape->getBounds(); + } + return aBounds; +} + +awt::Point AccessibleChartShape::getLocation() + throw (uno::RuntimeException) +{ + awt::Point aLocation; + if ( m_pAccShape ) + { + aLocation = m_pAccShape->getLocation(); + } + return aLocation; +} + +awt::Point AccessibleChartShape::getLocationOnScreen() + throw (uno::RuntimeException) +{ + awt::Point aLocation; + if ( m_pAccShape ) + { + aLocation = m_pAccShape->getLocationOnScreen(); + } + return aLocation; +} + +awt::Size AccessibleChartShape::getSize() + throw (uno::RuntimeException) +{ + awt::Size aSize; + if ( m_pAccShape ) + { + aSize = m_pAccShape->getSize(); + } + return aSize; +} + +void AccessibleChartShape::grabFocus() + throw (uno::RuntimeException) +{ + return AccessibleBase::grabFocus(); +} + +sal_Int32 AccessibleChartShape::getForeground() + throw (uno::RuntimeException) +{ + sal_Int32 nColor(0); + if ( m_pAccShape ) + { + nColor = m_pAccShape->getForeground(); + } + return nColor; +} + +sal_Int32 AccessibleChartShape::getBackground() + throw (uno::RuntimeException) +{ + sal_Int32 nColor(0); + if ( m_pAccShape ) + { + nColor = m_pAccShape->getBackground(); + } + return nColor; +} + +// ________ XAccessibleExtendedComponent ________ +Reference< awt::XFont > AccessibleChartShape::getFont() + throw (uno::RuntimeException) +{ + Reference< awt::XFont > xFont; + if ( m_pAccShape ) + { + xFont.set( m_pAccShape->getFont() ); + } + return xFont; +} + +::rtl::OUString AccessibleChartShape::getTitledBorderText() + throw (uno::RuntimeException) +{ + ::rtl::OUString aText; + if ( m_pAccShape ) + { + aText = m_pAccShape->getTitledBorderText(); + } + return aText; +} + +::rtl::OUString AccessibleChartShape::getToolTipText() + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString aText; + if ( m_pAccShape ) + { + aText = m_pAccShape->getToolTipText(); + } + return aText; +} + +} // namespace chart diff --git a/chart2/source/controller/accessibility/AccessibleChartShape.hxx b/chart2/source/controller/accessibility/AccessibleChartShape.hxx new file mode 100644 index 000000000000..a1236b697a69 --- /dev/null +++ b/chart2/source/controller/accessibility/AccessibleChartShape.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CHART2_ACCESSIBLECHARTSHAPE_HXX_ +#define _CHART2_ACCESSIBLECHARTSHAPE_HXX_ + +#include "AccessibleBase.hxx" + +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <cppuhelper/implbase1.hxx> +#include <svx/AccessibleShapeTreeInfo.hxx> + + +namespace accessibility +{ +class AccessibleShape; +} + +namespace chart +{ + +namespace impl +{ +typedef ::cppu::ImplInheritanceHelper1< + AccessibleBase, + ::com::sun::star::accessibility::XAccessibleExtendedComponent > AccessibleChartShape_Base; +} + +class AccessibleChartShape : + public impl::AccessibleChartShape_Base +{ +public: + AccessibleChartShape( const AccessibleElementInfo& rAccInfo, + bool bMayHaveChildren, bool bAlwaysTransparent = false ); + virtual ~AccessibleChartShape(); + + // ________ XServiceInfo ________ + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // ________ XAccessibleContext ________ + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL + getAccessibleChild( sal_Int32 i ) + throw (::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleDescription() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName() + throw (::com::sun::star::uno::RuntimeException); + + // ________ XAccessibleComponent ________ + virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grabFocus() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getForeground() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getBackground() throw (::com::sun::star::uno::RuntimeException); + + // ________ XAccessibleExtendedComponent ________ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL getFont() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTitledBorderText() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getToolTipText() + throw (::com::sun::star::uno::RuntimeException); + +private: + ::accessibility::AccessibleShape* m_pAccShape; + ::accessibility::AccessibleShapeTreeInfo m_aShapeTreeInfo; +}; + +} // namespace chart + +#endif diff --git a/chart2/source/controller/accessibility/AccessibleChartView.cxx b/chart2/source/controller/accessibility/AccessibleChartView.cxx index 611d75992832..4833991ad7cc 100644 --- a/chart2/source/controller/accessibility/AccessibleChartView.cxx +++ b/chart2/source/controller/accessibility/AccessibleChartView.cxx @@ -36,6 +36,7 @@ #include "ObjectIdentifier.hxx" #include "ResId.hxx" #include "Strings.hrc" +#include "AccessibleViewForwarder.hxx" #include <com/sun/star/accessibility/AccessibleEventId.hpp> #include <com/sun/star/accessibility/AccessibleStateType.hpp> @@ -66,19 +67,22 @@ namespace chart //............................................................................. AccessibleChartView::AccessibleChartView( - const Reference<uno::XComponentContext> & xContext ) : + const Reference< uno::XComponentContext >& xContext, SdrView* pView ) : impl::AccessibleChartView_Base( AccessibleElementInfo(), // empty for now true, // has children true // always transparent ), - m_xContext( xContext ) + m_xContext( xContext ), + m_pSdrView( pView ), + m_pViewForwarder( NULL ) { AddState( AccessibleStateType::OPAQUE ); } AccessibleChartView::~AccessibleChartView() { + delete m_pViewForwarder; } @@ -187,20 +191,6 @@ awt::Point SAL_CALL AccessibleChartView::getLocationOnScreen() } //----------------------------------------------------------------- -// lang::XServiceInfo -//----------------------------------------------------------------- - -APPHELPER_XSERVICEINFO_IMPL( AccessibleChartView, CHART2_ACCESSIBLE_SERVICE_IMPLEMENTATION_NAME ) - -uno::Sequence< rtl::OUString > AccessibleChartView::getSupportedServiceNames_Static() -{ - uno::Sequence< rtl::OUString > aSNS( 2 ); - aSNS.getArray()[ 0 ] = C2U("com.sun.star.accessibility.Accessible"); - aSNS.getArray()[ 1 ] = CHART2_ACCESSIBLE_SERVICE_NAME; - return aSNS; -} - -//----------------------------------------------------------------- // lang::XInitialization //----------------------------------------------------------------- @@ -350,7 +340,7 @@ void SAL_CALL AccessibleChartView::initialize( const Sequence< Any >& rArguments { AccessibleElementInfo aAccInfo; - aAccInfo.m_aCID = C2U("ROOT"); + aAccInfo.m_aOID = ObjectIdentifier( C2U( "ROOT" ) ); aAccInfo.m_xChartDocument = uno::WeakReference< chart2::XChartDocument >( uno::Reference< chart2::XChartDocument >( m_xChartModel.get(), uno::UNO_QUERY )); aAccInfo.m_xSelectionSupplier = m_xSelectionSupplier; @@ -358,6 +348,14 @@ void SAL_CALL AccessibleChartView::initialize( const Sequence< Any >& rArguments aAccInfo.m_xWindow = m_xWindow; aAccInfo.m_pParent = 0; aAccInfo.m_spObjectHierarchy = m_spObjectHierarchy; + aAccInfo.m_pSdrView = m_pSdrView; + Window* pWindow = VCLUnoHelper::GetWindow( m_xWindow ); + if ( m_pViewForwarder ) + { + delete m_pViewForwarder; + } + m_pViewForwarder = new AccessibleViewForwarder( this, pWindow ); + aAccInfo.m_pViewForwarder = m_pViewForwarder; // broadcasts an INVALIDATE_ALL_CHILDREN event globally SetInfo( aAccInfo ); } @@ -384,16 +382,16 @@ void SAL_CALL AccessibleChartView::selectionChanged( const lang::EventObject& /* if( xSelectionSupplier.is() ) { - rtl::OUString aSelectedObjectCID; - Any aSelection = xSelectionSupplier->getSelection(); - if(aSelection>>=aSelectedObjectCID) + ObjectIdentifier aSelectedOID( xSelectionSupplier->getSelection() ); + if ( m_aCurrentSelectionOID.isValid() ) + { + NotifyEvent( LOST_SELECTION, m_aCurrentSelectionOID ); + } + if( aSelectedOID.isValid() ) { - if( m_aCurrentSelectionCID.getLength()) - NotifyEvent( LOST_SELECTION, m_aCurrentSelectionCID ); - if( aSelectedObjectCID.getLength()) - NotifyEvent( GOT_SELECTION, aSelectedObjectCID ); - m_aCurrentSelectionCID = aSelectedObjectCID; + NotifyEvent( GOT_SELECTION, aSelectedOID ); } + m_aCurrentSelectionOID = aSelectedOID; } } diff --git a/chart2/source/controller/accessibility/AccessibleViewForwarder.cxx b/chart2/source/controller/accessibility/AccessibleViewForwarder.cxx new file mode 100644 index 000000000000..5014198761f8 --- /dev/null +++ b/chart2/source/controller/accessibility/AccessibleViewForwarder.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "AccessibleViewForwarder.hxx" +#include "AccessibleChartView.hxx" + +#include <vcl/window.hxx> + +using namespace ::com::sun::star; + + +namespace chart +{ + +AccessibleViewForwarder::AccessibleViewForwarder( AccessibleChartView* pAccChartView, Window* pWindow ) + :m_pAccChartView( pAccChartView ) + ,m_pWindow( pWindow ) + ,m_aMapMode( MAP_100TH_MM ) +{ +} + +AccessibleViewForwarder::~AccessibleViewForwarder() +{ +} + +// ________ IAccessibleViewforwarder ________ + +BOOL AccessibleViewForwarder::IsValid() const +{ + return sal_True; +} + +Rectangle AccessibleViewForwarder::GetVisibleArea() const +{ + Rectangle aVisibleArea; + if ( m_pWindow ) + { + aVisibleArea.SetPos( Point( 0, 0 ) ); + aVisibleArea.SetSize( m_pWindow->GetOutputSizePixel() ); + aVisibleArea = m_pWindow->PixelToLogic( aVisibleArea, m_aMapMode ); + } + return aVisibleArea; +} + +Point AccessibleViewForwarder::LogicToPixel( const Point& rPoint ) const +{ + Point aPoint; + if ( m_pAccChartView && m_pWindow ) + { + awt::Point aLocation = m_pAccChartView->getLocationOnScreen(); + Point aTopLeft( aLocation.X, aLocation.Y ); + aPoint = m_pWindow->LogicToPixel( rPoint, m_aMapMode ) + aTopLeft; + } + return aPoint; +} + +Size AccessibleViewForwarder::LogicToPixel( const Size& rSize ) const +{ + Size aSize; + if ( m_pWindow ) + { + aSize = m_pWindow->LogicToPixel( rSize, m_aMapMode ); + } + return aSize; +} + +Point AccessibleViewForwarder::PixelToLogic( const Point& rPoint ) const +{ + Point aPoint; + if ( m_pAccChartView && m_pWindow ) + { + awt::Point aLocation = m_pAccChartView->getLocationOnScreen(); + Point aTopLeft( aLocation.X, aLocation.Y ); + aPoint = m_pWindow->PixelToLogic( rPoint - aTopLeft, m_aMapMode ); + } + return aPoint; +} + +Size AccessibleViewForwarder::PixelToLogic( const Size& rSize ) const +{ + Size aSize; + if ( m_pWindow ) + { + aSize = m_pWindow->PixelToLogic( rSize, m_aMapMode ); + } + return aSize; +} + +} // namespace chart diff --git a/chart2/source/controller/accessibility/AccessibleViewForwarder.hxx b/chart2/source/controller/accessibility/AccessibleViewForwarder.hxx new file mode 100644 index 000000000000..e70aa58b8df7 --- /dev/null +++ b/chart2/source/controller/accessibility/AccessibleViewForwarder.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CHART2_ACCESSIBLEVIEWFORWARDER_HXX_ +#define _CHART2_ACCESSIBLEVIEWFORWARDER_HXX_ + +#include <vcl/mapmod.hxx> +#include <svx/IAccessibleViewForwarder.hxx> + +class Window; + +namespace chart +{ + +class AccessibleChartView; + +class AccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder +{ +public: + AccessibleViewForwarder( AccessibleChartView* pAccChartView, Window* pWindow ); + virtual ~AccessibleViewForwarder(); + + // ________ IAccessibleViewforwarder ________ + virtual BOOL IsValid() const; + virtual Rectangle GetVisibleArea() const; + virtual Point LogicToPixel( const Point& rPoint ) const; + virtual Size LogicToPixel( const Size& rSize ) const; + virtual Point PixelToLogic( const Point& rPoint ) const; + virtual Size PixelToLogic( const Size& rSize ) const; + +private: + AccessibleViewForwarder( AccessibleViewForwarder& ); + AccessibleViewForwarder& operator=( AccessibleViewForwarder& ); + + AccessibleChartView* m_pAccChartView; + Window* m_pWindow; + MapMode m_aMapMode; +}; + +} // namespace chart + +#endif diff --git a/chart2/source/controller/accessibility/ChartElementFactory.cxx b/chart2/source/controller/accessibility/ChartElementFactory.cxx index 43535a0d7fc5..b2599fec0c74 100644 --- a/chart2/source/controller/accessibility/ChartElementFactory.cxx +++ b/chart2/source/controller/accessibility/ChartElementFactory.cxx @@ -30,7 +30,6 @@ #include "ChartElementFactory.hxx" #include "ObjectIdentifier.hxx" - #include "AccessibleChartElement.hxx" namespace chart @@ -38,8 +37,8 @@ namespace chart AccessibleBase* ChartElementFactory::CreateChartElement( const AccessibleElementInfo& rAccInfo ) { - ObjectType eType( - ObjectIdentifier::getObjectType( rAccInfo.m_aCID )); + ObjectIdentifier aOID( rAccInfo.m_aOID ); + ObjectType eType( aOID.getObjectType() ); switch( eType ) { @@ -72,6 +71,8 @@ AccessibleBase* ChartElementFactory::CreateChartElement( const AccessibleElement return new AccessibleChartElement( rAccInfo, true, false ); case OBJECTTYPE_UNKNOWN: break; + default: + break; } return 0; diff --git a/chart2/source/controller/accessibility/makefile.mk b/chart2/source/controller/accessibility/makefile.mk index e79019ba8602..44c816d90d0e 100644 --- a/chart2/source/controller/accessibility/makefile.mk +++ b/chart2/source/controller/accessibility/makefile.mk @@ -44,7 +44,9 @@ SLOFILES= $(SLO)$/AccessibleChartView.obj \ $(SLO)$/ChartElementFactory.obj \ $(SLO)$/AccessibleBase.obj \ $(SLO)$/AccessibleChartElement.obj \ - $(SLO)$/AccessibleTextHelper.obj + $(SLO)$/AccessibleChartShape.obj \ + $(SLO)$/AccessibleTextHelper.obj \ + $(SLO)$/AccessibleViewForwarder.obj # --- Targets ----------------------------------------------------------------- diff --git a/chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx b/chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx index 375119ce521f..253699f4595c 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx @@ -61,59 +61,18 @@ using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; using ::osl::MutexGuard; +using ::com::sun::star::chart::XComplexDescriptionAccess; +using ::com::sun::star::chart::XChartData; +using ::com::sun::star::chart::XChartDataArray; namespace { static const ::rtl::OUString lcl_aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" )); -struct lcl_DataSequenceToDoubleSeq : public ::std::unary_function< - uno::Reference< chart2::data::XDataSequence >, - uno::Sequence< double > > -{ - uno::Sequence< double > operator() ( const uno::Reference< chart2::data::XDataSequence > & xSeq ) - { - uno::Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY ); - if( xNumSeq.is()) - { - return xNumSeq->getNumericalData(); - } - else if( xSeq.is()) - { - uno::Sequence< uno::Any > aValues = xSeq->getData(); - uno::Sequence< double > aResult( aValues.getLength()); - const sal_Int32 nLength = aValues.getLength(); - for( sal_Int32 i = 0; i < nLength; ++i ) - { - if( ! ( aValues[ i ] >>= aResult[ i ]) ) - { - aResult[ i ] = DBL_MIN; - } - double& rValue = aResult[ i ]; - if( ::rtl::math::isNan( rValue ) ) - rValue = DBL_MIN; - } - return aResult; - } - return uno::Sequence< double >(); - } -}; - -void lcl_AddSequences( uno::Reference< chart2::data::XLabeledDataSequence > xLSeq, - ::std::vector< uno::Reference< chart2::data::XDataSequence > > & rOutSeqVector, - ::std::vector< ::rtl::OUString > & rOutLabelVector ) -{ - if( xLSeq.is() ) - { - uno::Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues() ); - rOutSeqVector.push_back( xSeq ); - - ::rtl::OUString aLabel( ::chart::DataSeriesHelper::getLabelForLabeledDataSequence( xLSeq ) ); - rOutLabelVector.push_back( aLabel ); - } -} - uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData ) { uno::Sequence< uno::Sequence< double > > aRet; @@ -163,11 +122,197 @@ namespace chart namespace wrapper { +//-------------------------------------------------------------------------------------- + +struct lcl_Operator +{ + lcl_Operator() + { + } + virtual ~lcl_Operator() + { + } + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) = 0; + + virtual bool setsCategories( bool /*bDataInColumns*/ ) + { + return false; + } +}; + +//-------------------------------------------------------------------------- + +struct lcl_AllOperator : public lcl_Operator +{ + lcl_AllOperator( const Reference< XChartData >& xDataToApply ) + : lcl_Operator() + , m_xDataToApply( xDataToApply ) + { + } + + virtual bool setsCategories( bool /*bDataInColumns*/ ) + { + return true; + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( !xDataAccess.is() ) + return; + + Reference< XComplexDescriptionAccess > xNewComplex( m_xDataToApply, uno::UNO_QUERY ); + if( xNewComplex.is() ) + { + xDataAccess->setData( xNewComplex->getData() ); + xDataAccess->setComplexRowDescriptions( xNewComplex->getComplexRowDescriptions() ); + xDataAccess->setComplexColumnDescriptions( xNewComplex->getComplexColumnDescriptions() ); + } + else + { + Reference< XChartDataArray > xNew( m_xDataToApply, uno::UNO_QUERY ); + if( xNew.is() ) + { + xDataAccess->setData( xNew->getData() ); + xDataAccess->setRowDescriptions( xNew->getRowDescriptions() ); + xDataAccess->setColumnDescriptions( xNew->getColumnDescriptions() ); + } + } + } + + Reference< XChartData > m_xDataToApply; +}; + +//-------------------------------------------------------------------------- + +struct lcl_DataOperator : public lcl_Operator +{ + lcl_DataOperator( const Sequence< Sequence< double > >& rData ) + : lcl_Operator() + , m_rData( rData ) + { + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( xDataAccess.is() ) + xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) ); + } + + const Sequence< Sequence< double > >& m_rData; +}; + +//-------------------------------------------------------------------------- + +struct lcl_RowDescriptionsOperator : public lcl_Operator +{ + lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions ) + : lcl_Operator() + , m_rRowDescriptions( rRowDescriptions ) + { + } + + virtual bool setsCategories( bool bDataInColumns ) + { + return bDataInColumns; + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( xDataAccess.is() ) + xDataAccess->setRowDescriptions( m_rRowDescriptions ); + } + + const Sequence< OUString >& m_rRowDescriptions; +}; + +//-------------------------------------------------------------------------- + +struct lcl_ComplexRowDescriptionsOperator : public lcl_Operator +{ + lcl_ComplexRowDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexRowDescriptions ) + : lcl_Operator() + , m_rComplexRowDescriptions( rComplexRowDescriptions ) + { + } + + virtual bool setsCategories( bool bDataInColumns ) + { + return !bDataInColumns; + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( xDataAccess.is() ) + xDataAccess->setComplexRowDescriptions( m_rComplexRowDescriptions ); + } + + const Sequence< Sequence< OUString > >& m_rComplexRowDescriptions; +}; + +//-------------------------------------------------------------------------- + +struct lcl_ColumnDescriptionsOperator : public lcl_Operator +{ + lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions ) + : lcl_Operator() + , m_rColumnDescriptions( rColumnDescriptions ) + { + } + + virtual bool setsCategories( bool bDataInColumns ) + { + return !bDataInColumns; + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( xDataAccess.is() ) + xDataAccess->setColumnDescriptions( m_rColumnDescriptions ); + } + + const Sequence< OUString >& m_rColumnDescriptions; +}; + +//-------------------------------------------------------------------------- + +struct lcl_ComplexColumnDescriptionsOperator : public lcl_Operator +{ + lcl_ComplexColumnDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexColumnDescriptions ) + : lcl_Operator() + , m_rComplexColumnDescriptions( rComplexColumnDescriptions ) + { + } + + virtual bool setsCategories( bool bDataInColumns ) + { + return !bDataInColumns; + } + + virtual void apply( const Reference< XComplexDescriptionAccess >& xDataAccess ) + { + if( xDataAccess.is() ) + xDataAccess->setComplexColumnDescriptions( m_rComplexColumnDescriptions ); + } + + const Sequence< Sequence< OUString > >& m_rComplexColumnDescriptions; +}; + +//-------------------------------------------------------------------------- + ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) : m_spChart2ModelContact( spChart2ModelContact ), m_aEventListenerContainer( m_aMutex ) { - refreshData(); + initDataAccess(); +} + +ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact, + const Reference< XChartData >& xNewData ) : + m_spChart2ModelContact( spChart2ModelContact ), + m_aEventListenerContainer( m_aMutex ) +{ + lcl_AllOperator aOperator( xNewData ); + applyData( aOperator ); } ChartDataWrapper::~ChartDataWrapper() @@ -179,87 +324,80 @@ ChartDataWrapper::~ChartDataWrapper() // m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) ); } -// ____ XChartDataArray ____ -uno::Sequence< uno::Sequence< double > > SAL_CALL ChartDataWrapper::getData() +// ____ XChartDataArray (read)____ +Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData() throw (uno::RuntimeException) { - // until we have a data change notification mechanism we always have to - // update the data here - refreshData(); - // /-- - MutexGuard aGuard( GetMutex()); - return m_aData; - // \-- + initDataAccess(); + if( m_xDataAccess.is() ) + return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() ); + return Sequence< Sequence< double > >(); } - -void SAL_CALL ChartDataWrapper::setData( - const uno::Sequence< uno::Sequence< double > >& aData ) +Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions() throw (uno::RuntimeException) { - refreshData(); - { - // /-- - MutexGuard aGuard( GetMutex()); - m_aData = aData; - // \-- - } - applyData( true, false, false ); + initDataAccess(); + if( m_xDataAccess.is() ) + return m_xDataAccess->getRowDescriptions(); + return Sequence< OUString >(); } - -uno::Sequence< ::rtl::OUString > SAL_CALL ChartDataWrapper::getRowDescriptions() +Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions() throw (uno::RuntimeException) { - // until we have a data change notification mechanism we always have to - // update the data here - refreshData(); - - // /-- - MutexGuard aGuard( GetMutex()); - return m_aRowDescriptions; - // \-- + initDataAccess(); + if( m_xDataAccess.is() ) + return m_xDataAccess->getColumnDescriptions(); + return Sequence< OUString > (); +} +// ____ XComplexDescriptionAccess (read) ____ +Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexRowDescriptions() throw (uno::RuntimeException) +{ + initDataAccess(); + if( m_xDataAccess.is() ) + return m_xDataAccess->getComplexRowDescriptions(); + return Sequence< Sequence< OUString > >(); +} +Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexColumnDescriptions() throw (uno::RuntimeException) +{ + initDataAccess(); + if( m_xDataAccess.is() ) + return m_xDataAccess->getComplexColumnDescriptions(); + return Sequence< Sequence< OUString > >(); } -void SAL_CALL ChartDataWrapper::setRowDescriptions( - const uno::Sequence< ::rtl::OUString >& aRowDescriptions ) +// ____ XChartDataArray (write)____ +void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData ) throw (uno::RuntimeException) { - refreshData(); - { - // /-- - MutexGuard aGuard( GetMutex()); - m_aRowDescriptions = aRowDescriptions; - // \-- - } - applyData( false, true, false ); + lcl_DataOperator aOperator( rData ); + applyData( aOperator ); } - -uno::Sequence< - ::rtl::OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions() +void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions ) throw (uno::RuntimeException) { - // until we have a data change notification mechanism we always have to - // update the data here - refreshData(); - // /-- - MutexGuard aGuard( GetMutex()); - return m_aColumnDescriptions; - // \-- + lcl_RowDescriptionsOperator aOperator( rRowDescriptions ); + applyData( aOperator ); } - -void SAL_CALL ChartDataWrapper::setColumnDescriptions( - const uno::Sequence< ::rtl::OUString >& aColumnDescriptions ) +void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions ) throw (uno::RuntimeException) { - refreshData(); - { - // /-- - MutexGuard aGuard( GetMutex()); - m_aColumnDescriptions = aColumnDescriptions; - // \-- - } - applyData( false, false, true ); + lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions ); + applyData( aOperator ); +} + +// ____ XComplexDescriptionAccess (write) ____ +void SAL_CALL ChartDataWrapper::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rRowDescriptions ) throw (uno::RuntimeException) +{ + lcl_ComplexRowDescriptionsOperator aOperator( rRowDescriptions ); + applyData( aOperator ); +} +void SAL_CALL ChartDataWrapper::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rColumnDescriptions ) throw (uno::RuntimeException) +{ + lcl_ComplexColumnDescriptionsOperator aOperator( rColumnDescriptions ); + applyData( aOperator ); } +//-------------------------------------------------------------------------------------- // ____ XChartData (base of XChartDataArray) ____ void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener( @@ -297,13 +435,7 @@ void SAL_CALL ChartDataWrapper::dispose() throw (uno::RuntimeException) { m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this ))); - - // /-- - MutexGuard aGuard( GetMutex()); - m_aData.realloc( 0 ); - m_aColumnDescriptions.realloc( 0 ); - m_aRowDescriptions.realloc( 0 ); - // \-- + m_xDataAccess=0; } void SAL_CALL ChartDataWrapper::addEventListener( @@ -354,160 +486,39 @@ void ChartDataWrapper::fireChartDataChangeEvent( } } -void ChartDataWrapper::refreshData() +// -------------------------------------------------------------------------------- + +void ChartDataWrapper::switchToInternalDataProvider() +{ + //create an internal data provider that is connected to the model + Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); + if( xChartDoc.is() ) + xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ ); + initDataAccess(); +} + +void ChartDataWrapper::initDataAccess() { - //todo mutex... Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); if( !xChartDoc.is() ) return; - if( xChartDoc->hasInternalDataProvider()) - { - try { - uno::Reference< ::com::sun::star::chart::XChartDataArray > xInternalData( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); - m_aColumnDescriptions = xInternalData->getColumnDescriptions(); - m_aRowDescriptions = xInternalData->getRowDescriptions(); - m_aData = lcl_getDBL_MINInsteadNAN( xInternalData->getData() ); - } - catch( const uno::Exception & ex ) { - ASSERT_EXCEPTION( ex ); - } - } + if( xChartDoc->hasInternalDataProvider() ) + m_xDataAccess = Reference< XComplexDescriptionAccess >( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); else { - uno::Reference< chart2::XDiagram > xDia( - xChartDoc->getFirstDiagram() ); - if( ! xDia.is()) - return; - - // get information about the segmentation of the assumed "rectangular" data - // range - ::rtl::OUString aRangeString; - bool bUseColumns = true; - bool bFirstCellAsLabel = true; - bool bHasCategories = true; - uno::Sequence< sal_Int32 > aSequenceMapping; - - DataSourceHelper::detectRangeSegmentation( - uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ), - aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ); - - - // get data values from data series - // -------------------------------- - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSequences; - uno::Reference< chart2::data::XDataSource > xRectangularDataSource( - DataSourceHelper::pressUsedDataIntoRectangularFormat( xChartDoc, false /*bWithCategories*/ ) ); - if( xRectangularDataSource.is() ) - { - aLabeledSequences = xRectangularDataSource->getDataSequences(); - } - - ::std::vector< uno::Reference< chart2::data::XDataSequence > > aSequenceVector; - ::std::vector< ::rtl::OUString > aLabelVector; - for( sal_Int32 nN=0; nN<aLabeledSequences.getLength(); nN++ ) - lcl_AddSequences( aLabeledSequences[nN], aSequenceVector, aLabelVector ); - - if( aSequenceMapping.getLength() ) - { - //aSequenceVector and aLabelVector contain changed positions; resort them to the original position - ::std::vector< uno::Reference< chart2::data::XDataSequence > > aBackSortedSequences; - ::std::vector< ::rtl::OUString > aBackSortedLabels; - - std::map< sal_Int32, sal_Int32 > aReverseMap; - { - sal_Int32 nNewIndex, nOldIndex; - for( sal_Int32 nS=0; nS <aSequenceMapping.getLength(); nS++ ) - { - nOldIndex = aSequenceMapping[nS]; - nNewIndex = nS; - if( bHasCategories ) - nNewIndex--; - if( nOldIndex >= 0 && nNewIndex >= 0 ) - aReverseMap[nOldIndex] = nNewIndex; - } - } - - std::map< sal_Int32, sal_Int32 >::iterator aMapIt = aReverseMap.begin(); - std::map< sal_Int32, sal_Int32 >::const_iterator aMapEnd = aReverseMap.end(); - - for( ; aMapIt != aMapEnd; ++aMapIt ) - { - size_t nNewIndex = static_cast< size_t >( aMapIt->second ); - if( nNewIndex < aSequenceVector.size() ) - aBackSortedSequences.push_back( aSequenceVector[nNewIndex] ); - if( nNewIndex < aLabelVector.size() ) - aBackSortedLabels.push_back( aLabelVector[nNewIndex] ); - } - - // note: assign( beg, end ) doesn't work on solaris - aSequenceVector.clear(); - aSequenceVector.insert( - aSequenceVector.begin(), aBackSortedSequences.begin(), aBackSortedSequences.end() ); - aLabelVector.clear(); - aLabelVector.insert( - aLabelVector.begin(), aBackSortedLabels.begin(), aBackSortedLabels.end() ); - } - - if( bUseColumns ) - { - const sal_Int32 nInnerSize = aSequenceVector.size(); - if( nInnerSize > 0 && aSequenceVector[0].is() ) - { - // take the length of the first data series also as length for all - // other series - const sal_Int32 nOuterSize = aSequenceVector[0]->getData().getLength(); - - m_aData.realloc( nOuterSize ); - for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter ) - m_aData[nOuter].realloc( nInnerSize ); - - for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner ) - { - uno::Sequence< double > aValues = uno::Sequence< double > ( - lcl_DataSequenceToDoubleSeq() (aSequenceVector[nInner] )); - sal_Int32 nMax = ::std::min( nOuterSize, aValues.getLength()); - for( sal_Int32 nOuter=0; nOuter<nMax; ++nOuter ) - m_aData[nOuter][nInner] = aValues[nOuter]; - } - } - } - else - { - m_aData.realloc( static_cast< sal_Int32 >( aSequenceVector.size())); - ::std::transform( aSequenceVector.begin(), aSequenceVector.end(), - m_aData.getArray(), - lcl_DataSequenceToDoubleSeq() ); - } - - // labels (values already filled during parsing of data values) - if( bUseColumns ) - m_aColumnDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector ); - else - m_aRowDescriptions = ::chart::ContainerHelper::ContainerToSequence( aLabelVector ); - - // get row-/column descriptions - // ---------------------------- - // categories - uno::Sequence< ::rtl::OUString > & rSequence = - bUseColumns ? m_aRowDescriptions : m_aColumnDescriptions; - rSequence = DiagramHelper::generateAutomaticCategories( xChartDoc ); + //create a separate "internal data provider" that is not connected to the model + m_xDataAccess = Reference< XComplexDescriptionAccess >( ChartModelHelper::createInternalDataProvider( + xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW ); } } -void ChartDataWrapper::applyData( bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions ) +void ChartDataWrapper::applyData( lcl_Operator& rDataOperator ) { + //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); if( !xChartDoc.is() ) return; - // /-- locked controllers - ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); - // should do nothing if we already have an internal data provider - xChartDoc->createInternalDataProvider( sal_True /* bCloneExistingData */ ); - - uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider()); - uno::Reference< XChartDataArray > xDocDataArray( xDataProvider, uno::UNO_QUERY ); - // remember some diagram properties to reset later sal_Bool bStacked = sal_False; sal_Bool bPercent = sal_False; @@ -533,71 +544,24 @@ void ChartDataWrapper::applyData( bool bSetValues, bool bSetRowDescriptions, boo uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ), aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ); - if( !bFirstCellAsLabel ) - { - if( bSetRowDescriptions && !bUseColumns ) - bFirstCellAsLabel = true; - else if( bSetColumnDescriptions && bUseColumns ) - bFirstCellAsLabel = true; - } - if( !bHasCategories ) - { - if( bSetColumnDescriptions && bUseColumns ) - bHasCategories = true; - else if( bSetRowDescriptions && !bUseColumns ) - bHasCategories = true; - } + if( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) ) + bHasCategories = true; - aRangeString = C2U("all"); uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments( aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) ); - // create and attach new data source - uno::Reference< chart2::data::XDataSource > xSource; - if( xDocDataArray.is() ) - { - // we have an internal data provider that supports the XChartDataArray - // interface - if( bSetValues ) - xDocDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) ); - if( bSetRowDescriptions ) - xDocDataArray->setRowDescriptions( m_aRowDescriptions ); - if( bSetColumnDescriptions ) - xDocDataArray->setColumnDescriptions( m_aColumnDescriptions ); - - xSource.set( xDataProvider->createDataSource( aArguments )); - } - else - { - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - OSL_ASSERT( xChartDoc.is()); - OSL_ASSERT( xReceiver.is()); - if( ! (xChartDoc.is() && xReceiver.is())) - return; - // create a data provider containing the new data - uno::Reference< chart2::data::XDataProvider > xTempDataProvider( - ChartModelHelper::createInternalDataProvider() ); - if( ! xTempDataProvider.is()) - throw uno::RuntimeException( C2U("Couldn't create temporary data provider"), - static_cast< ::cppu::OWeakObject * >( this )); + // /-- locked controllers + ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); - uno::Reference< ::com::sun::star::chart::XChartDataArray > xDataArray( xTempDataProvider, uno::UNO_QUERY ); - OSL_ASSERT( xDataArray.is()); - if( xDataArray.is()) - { - if( bSetValues ) - xDataArray->setData( lcl_getNANInsteadDBL_MIN( m_aData ) ); - if( bSetRowDescriptions ) - xDataArray->setRowDescriptions( m_aRowDescriptions ); - if( bSetColumnDescriptions ) - xDataArray->setColumnDescriptions( m_aColumnDescriptions ); - - // removes existing data provider and attaches the new one - xReceiver->attachDataProvider( xTempDataProvider ); - xSource.set( xTempDataProvider->createDataSource( aArguments)); - } - } + // create and attach new data source + switchToInternalDataProvider(); + rDataOperator.apply(m_xDataAccess); + uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() ); + OSL_ASSERT( xDataProvider.is() ); + if( !xDataProvider.is() ) + return; + uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) ); // determine a template uno::Reference< lang::XMultiServiceFactory > xFact( xChartDoc->getChartTypeManager(), uno::UNO_QUERY ); @@ -621,8 +585,7 @@ void ChartDataWrapper::applyData( bool bSetValues, bool bSetRowDescriptions, boo // argument detection works with internal knowledge of the // ArrayDataProvider OSL_ASSERT( xDia.is()); - xTemplate->changeDiagramData( - xDia, xSource, aArguments ); + xTemplate->changeDiagramData( xDia, xSource, aArguments ); } //correct stacking mode diff --git a/chart2/source/controller/chartapiwrapper/ChartDataWrapper.hxx b/chart2/source/controller/chartapiwrapper/ChartDataWrapper.hxx index 6bdae0350184..d56397953d79 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDataWrapper.hxx +++ b/chart2/source/controller/chartapiwrapper/ChartDataWrapper.hxx @@ -31,7 +31,7 @@ #include "MutexContainer.hxx" #include <cppuhelper/implbase4.hxx> #include <cppuhelper/interfacecontainer.hxx> -#include <com/sun/star/chart/XChartDataArray.hpp> +#include <com/sun/star/chart/XComplexDescriptionAccess.hpp> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> @@ -45,23 +45,40 @@ namespace wrapper { class Chart2ModelContact; +struct lcl_Operator; class ChartDataWrapper : public MutexContainer, public ::cppu::WeakImplHelper4< - com::sun::star::chart::XChartDataArray, + com::sun::star::chart::XComplexDescriptionAccess, com::sun::star::lang::XServiceInfo, com::sun::star::lang::XEventListener, com::sun::star::lang::XComponent > { public: ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ); + ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact + , const ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartData >& xNewData ); virtual ~ChartDataWrapper(); /// XServiceInfo declarations APPHELPER_XSERVICEINFO_DECL() protected: - // ____ XChartDataArray ____ + // ____ XComplexDescriptionAccess ____ + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL + getComplexRowDescriptions() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setComplexRowDescriptions( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Sequence< ::rtl::OUString > >& aRowDescriptions ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > SAL_CALL + getComplexColumnDescriptions() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setComplexColumnDescriptions( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Sequence< ::rtl::OUString > >& aColumnDescriptions ) + throw (::com::sun::star::uno::RuntimeException); + + // ____ XChartDataArray (base of XComplexDescriptionAccess) ____ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< double > > SAL_CALL getData() @@ -112,20 +129,17 @@ protected: void fireChartDataChangeEvent( ::com::sun::star::chart::ChartDataChangeEvent& aEvent ); -private: - ::boost::shared_ptr< Chart2ModelContact > m_spChart2ModelContact; - ::cppu::OInterfaceContainerHelper m_aEventListenerContainer; - - ::com::sun::star::uno::Sequence< - ::com::sun::star::uno::Sequence< double > > m_aData; - ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aColumnDescriptions; - ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aRowDescriptions; +private: //methods + void switchToInternalDataProvider(); + void initDataAccess(); + void applyData( lcl_Operator& rDataOperator ); - /// re-reads the data from the model - void refreshData(); +private: //member + ::com::sun::star::uno::Reference< + ::com::sun::star::chart::XComplexDescriptionAccess > m_xDataAccess; - /// applies changed data to model - void applyData( bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions ); + ::boost::shared_ptr< Chart2ModelContact > m_spChart2ModelContact; + ::cppu::OInterfaceContainerHelper m_aEventListenerContainer; }; } // namespace wrapper diff --git a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx index 138a54a43036..67f537c49b98 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx @@ -54,10 +54,11 @@ #include "WrappedAddInProperty.hxx" #include "WrappedIgnoreProperty.hxx" #include "ChartRenderer.hxx" +#include "UndoManager.hxx" #include <com/sun/star/chart2/XTitled.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart/ChartDataRowSource.hpp> -#include <com/sun/star/chart/XChartDataArray.hpp> +#include <com/sun/star/chart/XComplexDescriptionAccess.hpp> #include <comphelper/InlineContainer.hxx> // header for function SvxShapeCollection_NewInstance #include <svx/unoshcol.hxx> @@ -76,6 +77,7 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::chart; +using ::com::sun::star::chart::XComplexDescriptionAccess; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; @@ -829,7 +831,7 @@ void SAL_CALL ChartDocumentWrapper::setDiagram( const Reference< XDiagram >& xDi Reference< XChartData > SAL_CALL ChartDocumentWrapper::getData() throw (uno::RuntimeException) { - if( ! m_xChartData.is()) + if( !m_xChartData.is() ) { m_xChartData.set( new ChartDataWrapper( m_spChart2ModelContact ) ); } @@ -838,128 +840,15 @@ Reference< XChartData > SAL_CALL ChartDocumentWrapper::getData() return m_xChartData; } -void SAL_CALL ChartDocumentWrapper::attachData( const Reference< XChartData >& xData ) +void SAL_CALL ChartDocumentWrapper::attachData( const Reference< XChartData >& xNewData ) throw (uno::RuntimeException) { - if( !xData.is()) + if( !xNewData.is() ) return; - Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); - if( !xChartDoc.is() ) - return; - - uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider()); - uno::Reference< XChartDataArray > xDocDataArray( xDataProvider, uno::UNO_QUERY ); - uno::Reference< XChartDataArray > xDataArray( xData, uno::UNO_QUERY ); - OSL_ASSERT( xDataArray.is()); - if( ! xDataArray.is() || - xDocDataArray == xDataArray ) - return; - - // remember some diagram properties to reset later - ChartDataRowSource eSeriesSource = ChartDataRowSource_ROWS; - sal_Bool bStacked = sal_False; - sal_Bool bPercent = sal_False; - sal_Bool bDeep = sal_False; - Reference< beans::XPropertySet > xDiaProp( getDiagram(), uno::UNO_QUERY ); - if( xDiaProp.is()) - { - xDiaProp->getPropertyValue( C2U("DataRowSource")) >>= eSeriesSource; - xDiaProp->getPropertyValue( C2U("Stacked")) >>= bStacked; - xDiaProp->getPropertyValue( C2U("Percent")) >>= bPercent; - xDiaProp->getPropertyValue( C2U("Deep")) >>= bDeep; - } - - // create and attach new data source - uno::Reference< chart2::data::XDataSource > xSource; - Sequence< beans::PropertyValue > aArguments( 4 ); - aArguments[0] = beans::PropertyValue( - C2U("CellRangeRepresentation"), -1, uno::makeAny( C2U("all") ), - beans::PropertyState_DIRECT_VALUE ); - aArguments[1] = beans::PropertyValue( - C2U("DataRowSource"), -1, uno::makeAny( eSeriesSource ), - beans::PropertyState_DIRECT_VALUE ); - aArguments[2] = beans::PropertyValue( - C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); - aArguments[3] = beans::PropertyValue( - C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); - // /-- locked controllers - ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); - if( xDocDataArray.is()) - { - // we have an internal data provider that supports the XChartDataArray - // interface - xDocDataArray->setData( xDataArray->getData()); - xDocDataArray->setRowDescriptions( xDataArray->getRowDescriptions()); - xDocDataArray->setColumnDescriptions( xDataArray->getColumnDescriptions()); - - xSource.set( xDataProvider->createDataSource( aArguments )); - } - else - { - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - OSL_ASSERT( xChartDoc.is()); - OSL_ASSERT( xReceiver.is()); - OSL_ASSERT( xDataArray.is()); - if( ! (xChartDoc.is() && - xReceiver.is())) - return; - - // create a data provider containing the new data - Reference< chart2::data::XDataProvider > xTempDataProvider( - ChartModelHelper::createInternalDataProvider( xDataArray )); - - if( ! xTempDataProvider.is()) - throw uno::RuntimeException( C2U("Couldn't create temporary data provider"), - static_cast< ::cppu::OWeakObject * >( this )); - - // removes existing data provider and attaches the new one - xReceiver->attachDataProvider( xTempDataProvider ); - xSource.set( xTempDataProvider->createDataSource( aArguments)); - } - - // determine a template - Reference< lang::XMultiServiceFactory > xFact( xChartDoc->getChartTypeManager(), uno::UNO_QUERY ); - Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram()); - DiagramHelper::tTemplateWithServiceName aTemplateAndService = - DiagramHelper::getTemplateForDiagram( xDia, xFact ); - OUString aServiceName( aTemplateAndService.second ); - Reference< chart2::XChartTypeTemplate > xTemplate = aTemplateAndService.first; - - // (fall-back) - if( ! xTemplate.is()) - { - if( aServiceName.getLength() == 0 ) - aServiceName = C2U("com.sun.star.chart2.template.Column"); - xTemplate.set( xFact->createInstance( aServiceName ), uno::UNO_QUERY ); - } - OSL_ASSERT( xTemplate.is()); - - if( xTemplate.is() && xSource.is()) - { - // argument detection works with internal knowledge of the - // ArrayDataProvider - OSL_ASSERT( xDia.is()); - xTemplate->changeDiagramData( - xDia, xSource, aArguments ); - } - - // should do nothing if we already have an internal data provider - xChartDoc->createInternalDataProvider( sal_True /* bCloneExistingData */ ); - - //correct stacking mode - if( bStacked || bPercent || bDeep ) - { - StackMode eStackMode = StackMode_Y_STACKED; - if( bDeep ) - eStackMode = StackMode_Z_STACKED; - else if( bPercent ) - eStackMode = StackMode_Y_STACKED_PERCENT; - DiagramHelper::setStackMode( xDia, eStackMode ); - } - - m_xChartData = xData; + ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( m_spChart2ModelContact->getChart2Document(), uno::UNO_QUERY )); + m_xChartData.set( new ChartDataWrapper( m_spChart2ModelContact, xNewData ) ); // \-- locked controllers } @@ -1489,6 +1378,12 @@ uno::Reference< uno::XInterface > SAL_CALL ChartDocumentWrapper::createInstance( xResult.set( m_xChartView ); bServiceFound = true; } + else if ( aServiceSpecifier.equals( CHART_UNDOMANAGER_SERVICE_NAME ) ) + { + Reference< chart2::XUndoManager > xUndoManager( new UndoManager() ); + xResult.set( xUndoManager ); + bServiceFound = true; + } else { // try to create a shape diff --git a/chart2/source/controller/dialogs/DataBrowser.cxx b/chart2/source/controller/dialogs/DataBrowser.cxx index 1265f4412f2a..67930fc6f7a7 100644 --- a/chart2/source/controller/dialogs/DataBrowser.cxx +++ b/chart2/source/controller/dialogs/DataBrowser.cxx @@ -45,6 +45,8 @@ #include "DataSeriesHelper.hxx" #include "DiagramHelper.hxx" #include "ChartModelHelper.hxx" +#include "CommonConverters.hxx" +#include "macros.hxx" #include "chartview/NumberFormatterWrapper.hxx" #include "servicenames_charttypes.hxx" #include "ResId.hxx" @@ -187,6 +189,8 @@ public: sal_Int32 GetStartColumn() const; sal_Int32 GetEndColumn() const; + static sal_Int32 GetRelativeAppFontXPosForNameField(); + void Show(); /** call this before destroying the class. This notifies the listeners to @@ -262,23 +266,30 @@ void SeriesHeader::SetColor( const Color & rCol ) m_spColorBar->SetControlBackground( rCol ); } +const sal_Int32 nSymbolHeight = 10; +const sal_Int32 nSymbolDistance = 2; + +sal_Int32 SeriesHeader::GetRelativeAppFontXPosForNameField() +{ + return nSymbolHeight + nSymbolDistance; +} + void SeriesHeader::SetPos( const Point & rPos ) { m_aPos = rPos; // chart type symbol - sal_Int32 nHeight = 10; Point aPos( rPos ); - aPos.setY( aPos.getY() + 2 ); - Size aSize( nHeight, nHeight ); + aPos.setY( aPos.getY() + nSymbolDistance ); + Size aSize( nSymbolHeight, nSymbolHeight ); m_spSymbol->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); m_spSymbol->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); - aPos.setY( aPos.getY() - 2 ); + aPos.setY( aPos.getY() - nSymbolDistance ); // series name edit field - aPos.setX( aPos.getX() + nHeight + 2 ); - aSize.setWidth( m_nWidth - nHeight - 2 ); - nHeight = 12; + aPos.setX( aPos.getX() + nSymbolHeight + nSymbolDistance ); + aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance ); + sal_Int32 nHeight = 12; aSize.setHeight( nHeight ); m_spSeriesName->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); m_spSeriesName->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); @@ -553,25 +564,14 @@ bool DataBrowser::MaySwapColumns() const return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1)); } + sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); return ! IsReadOnly() - && ( GetCurColumnId() > 1 ) - && ( GetCurColumnId() < ColCount() - 1 ); + && ( nColIdx > 0 ) + && ( nColIdx < ColCount()-2 ) + && m_apDataBrowserModel.get() + && !m_apDataBrowserModel->isCategoriesColumn( nColIdx ); } -// bool DataBrowser::MaySortRow() const -// { -// // not implemented -// return false; -// // return ! IsReadOnly() && ( GetCurRow() >= 0 ); -// } - -// bool DataBrowser::MaySortColumn() const -// { -// // not implemented -// return false; -// // return ! IsReadOnly() && ( GetCurColumnId() > 1 ); -// } - void DataBrowser::clearHeaders() { ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor()); @@ -601,9 +601,10 @@ void DataBrowser::RenewTable() InsertHandleColumn( static_cast< sal_uInt16 >( GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() )); - const sal_Int32 nDefaultColumnWidth = 94; - - sal_Int32 nColumnWidth( GetDataWindow().LogicToPixel( Size( nDefaultColumnWidth, 0 )).getWidth()); + OUString aDefaultSeriesName( ::chart::SchResId::getResString( STR_COLUMN_LABEL )); + replaceParamterInString( aDefaultSeriesName, C2U("%COLUMNNUMBER"), OUString::valueOf( sal_Int32(24) ) ); + sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName ) + + GetDataWindow().LogicToPixel( Point( 4 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0 ), MAP_APPFONT ).X(); sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount(); // nRowCount is a member of a base class sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount(); @@ -882,6 +883,22 @@ void DataBrowser::InsertColumn() } } +void DataBrowser::InsertTextColumn() +{ + sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); + + if( nColIdx >= 0 && + m_apDataBrowserModel.get()) + { + // save changes made to edit-field + if( IsModified() ) + SaveModified(); + + m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx ); + RenewTable(); + } +} + void DataBrowser::RemoveColumn() { sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); @@ -894,7 +911,7 @@ void DataBrowser::RemoveColumn() SaveModified(); m_bDataValid = true; - m_apDataBrowserModel->removeDataSeries( nColIdx ); + m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx ); RenewTable(); } } diff --git a/chart2/source/controller/dialogs/DataBrowser.hxx b/chart2/source/controller/dialogs/DataBrowser.hxx index 97c952c2cee9..3583db2770c0 100644 --- a/chart2/source/controller/dialogs/DataBrowser.hxx +++ b/chart2/source/controller/dialogs/DataBrowser.hxx @@ -121,12 +121,10 @@ public: bool MaySwapRows() const; bool MaySwapColumns() const; -// bool MaySortRow() const; -// bool MaySortColumn() const; - // mutators mutating data void InsertRow(); void InsertColumn(); + void InsertTextColumn(); void RemoveRow(); void RemoveColumn(); diff --git a/chart2/source/controller/dialogs/DataBrowserModel.cxx b/chart2/source/controller/dialogs/DataBrowserModel.cxx index decdda0f8793..c0b865536686 100644 --- a/chart2/source/controller/dialogs/DataBrowserModel.cxx +++ b/chart2/source/controller/dialogs/DataBrowserModel.cxx @@ -40,6 +40,7 @@ #include "ContainerHelper.hxx" #include "ChartTypeHelper.hxx" #include "chartview/ExplicitValueProvider.hxx" +#include "ExplicitCategoriesProvider.hxx" #include <com/sun/star/container/XIndexReplace.hpp> #include <com/sun/star/chart2/XDataSeriesContainer.hpp> @@ -51,6 +52,7 @@ #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp> #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp> #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> +#include <com/sun/star/util/XModifiable.hpp> #include <rtl/math.hxx> @@ -322,6 +324,9 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex ) m_apDialogModel->getDataProvider(), uno::UNO_QUERY ); if( xDataProvider.is()) { + if( isCategoriesColumn(nAfterColumnIndex) ) + nAfterColumnIndex = getCategoryColumnCount()-1; + sal_Int32 nStartCol = 0; Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartDocument )); Reference< chart2::XChartType > xChartType; @@ -353,7 +358,7 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex ) { sal_Int32 nOffset = 0; if( xDiagram.is() && lcl_ShowCategories( xDiagram )) - ++nOffset; + nOffset=getCategoryColumnCount(); // get shared sequences of current series Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY ); lcl_tSharedSeqVec aSharedSequences; @@ -423,7 +428,31 @@ void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex ) } } -void DataBrowserModel::removeDataSeries( sal_Int32 nAtColumnIndex ) +void DataBrowserModel::insertComplexCategoryLevel( sal_Int32 nAfterColumnIndex ) +{ + //create a new text column for complex categories + + OSL_ASSERT( m_apDialogModel.get()); + Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY ); + if( xDataProvider.is() ) + { + if( !isCategoriesColumn(nAfterColumnIndex) ) + nAfterColumnIndex = getCategoryColumnCount()-1; + + if(nAfterColumnIndex<0) + { + OSL_ENSURE( false, "wrong index for category level insertion" ); + return; + } + + m_apDialogModel->startControllerLockTimer(); + ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); + xDataProvider->insertComplexCategoryLevel( nAfterColumnIndex+1 ); + updateFromModel(); + } +} + +void DataBrowserModel::removeDataSeriesOrComplexCategoryLevel( sal_Int32 nAtColumnIndex ) { OSL_ASSERT( m_apDialogModel.get()); if( static_cast< tDataColumnVector::size_type >( nAtColumnIndex ) < m_aColumns.size()) @@ -474,6 +503,20 @@ void DataBrowserModel::removeDataSeries( sal_Int32 nAtColumnIndex ) } updateFromModel(); } + else + { + //delete a category column if there is more than one level (in case of a single column we do not get here) + OSL_ENSURE(nAtColumnIndex>0, "wrong index for categories deletion" ); + + Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY ); + if( xDataProvider.is() ) + { + m_apDialogModel->startControllerLockTimer(); + ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); + xDataProvider->deleteComplexCategoryLevel( nAtColumnIndex ); + updateFromModel(); + } + } } } @@ -614,6 +657,8 @@ bool DataBrowserModel::setCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow, const bResult = true; try { + ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); + // label if( nAtRow == -1 ) { @@ -627,6 +672,12 @@ bool DataBrowserModel::setCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow, const m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY_THROW ); xIndexReplace->replaceByIndex( nAtRow, rValue ); } + + m_apDialogModel->startControllerLockTimer(); + //notify change directly to the model (this is necessary here as sequences for complex categories not known directly to the chart model so they do not notify their changes) (for complex categories see issue #i82971#) + Reference< util::XModifiable > xModifiable( m_xChartDocument, uno::UNO_QUERY ); + if( xModifiable.is() ) + xModifiable->setModified(true); } catch( const uno::Exception & ex ) { @@ -683,11 +734,26 @@ OUString DataBrowserModel::getRoleOfColumn( sal_Int32 nColumnIndex ) const return OUString(); } -Reference< chart2::data::XLabeledDataSequence > - DataBrowserModel::getCategories() const throw() +bool DataBrowserModel::isCategoriesColumn( sal_Int32 nColumnIndex ) const { - OSL_ASSERT( m_apDialogModel.get()); - return m_apDialogModel->getCategories(); + bool bIsCategories = false; + if( nColumnIndex>=0 && nColumnIndex<static_cast< sal_Int32 >(m_aColumns.size()) ) + bIsCategories = !m_aColumns[ nColumnIndex ].m_xDataSeries.is(); + return bIsCategories; +} + +sal_Int32 DataBrowserModel::getCategoryColumnCount() +{ + sal_Int32 nLastTextColumnIndex = -1; + tDataColumnVector::const_iterator aIt = m_aColumns.begin(); + for( ; aIt != m_aColumns.end(); ++aIt ) + { + if( !aIt->m_xDataSeries.is() ) + nLastTextColumnIndex++; + else + break; + } + return nLastTextColumnIndex+1; } const DataBrowserModel::tDataHeaderVector& DataBrowserModel::getDataHeaders() const @@ -717,16 +783,27 @@ void DataBrowserModel::updateFromModel() sal_Int32 nHeaderEnd = 0; if( lcl_ShowCategories( xDiagram )) { - Reference< chart2::data::XLabeledDataSequence > xCategories( this->getCategories()); - tDataColumn aCategories; - aCategories.m_xLabeledDataSequence.set( xCategories ); - if( lcl_ShowCategoriesAsDataLabel( xDiagram )) - aCategories.m_aUIRoleName = DialogModel::GetRoleDataLabel(); - else - aCategories.m_aUIRoleName = lcl_getUIRoleName( xCategories ); - aCategories.m_eCellType = TEXT; - m_aColumns.push_back( aCategories ); - ++nHeaderStart; + Reference< frame::XModel > xChartModel( m_xChartDocument, uno::UNO_QUERY ); + ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel ); + + const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() ); + sal_Int32 nLevelCount = rSplitCategoriesList.getLength(); + for( sal_Int32 nL = 0; nL<nLevelCount; nL++ ) + { + Reference< chart2::data::XLabeledDataSequence > xCategories( rSplitCategoriesList[nL] ); + if( !xCategories.is() ) + continue; + + tDataColumn aCategories; + aCategories.m_xLabeledDataSequence.set( xCategories ); + if( lcl_ShowCategoriesAsDataLabel( xDiagram )) + aCategories.m_aUIRoleName = DialogModel::GetRoleDataLabel(); + else + aCategories.m_aUIRoleName = lcl_getUIRoleName( xCategories ); + aCategories.m_eCellType = TEXT; + m_aColumns.push_back( aCategories ); + ++nHeaderStart; + } } Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY ); diff --git a/chart2/source/controller/dialogs/DataBrowserModel.hxx b/chart2/source/controller/dialogs/DataBrowserModel.hxx index 5b6a6e41c01b..a4378972f70f 100644 --- a/chart2/source/controller/dialogs/DataBrowserModel.hxx +++ b/chart2/source/controller/dialogs/DataBrowserModel.hxx @@ -60,10 +60,14 @@ public: */ void insertDataSeries( sal_Int32 nAfterColumnIndex ); + /** Inserts a new text column for complex categories. + */ + void insertComplexCategoryLevel( sal_Int32 nAfterColumnIndex ); + /** Removes a data series to which the data column with index nAtColumnIndex belongs. */ - void removeDataSeries( sal_Int32 nAtColumnIndex ); + void removeDataSeriesOrComplexCategoryLevel( sal_Int32 nAtColumnIndex ); /** Swaps the series to which the data column with index nFirstIndex belongs with the next series (which starts at an index >= nFirstIndex + 1) @@ -97,6 +101,7 @@ public: // returns the UI string of the corresponding role ::rtl::OUString getRoleOfColumn( sal_Int32 nColumnIndex ) const; + bool isCategoriesColumn( sal_Int32 nColumnIndex ) const; struct tDataHeader { @@ -153,9 +158,7 @@ private: sal_Int32 & rInOutSequenceIndex, sal_Int32 & rInOutHeaderEnd ); - ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::data::XLabeledDataSequence > - getCategories() const throw(); + sal_Int32 getCategoryColumnCount(); ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > m_xChartDocument; diff --git a/chart2/source/controller/dialogs/DialogModel.cxx b/chart2/source/controller/dialogs/DialogModel.cxx index a8d9288e381f..f104045727bb 100644 --- a/chart2/source/controller/dialogs/DialogModel.cxx +++ b/chart2/source/controller/dialogs/DialogModel.cxx @@ -827,8 +827,6 @@ void DialogModel::applyInterpretedData( DialogModel::setCategories(rNewData.Categories); } - - OSL_ASSERT( ! rNewData.UnusedData.hasElements()); } sal_Int32 DialogModel::countSeries() const diff --git a/chart2/source/controller/dialogs/ObjectNameProvider.cxx b/chart2/source/controller/dialogs/ObjectNameProvider.cxx index a29e91457c93..0836ab9ca93a 100644 --- a/chart2/source/controller/dialogs/ObjectNameProvider.cxx +++ b/chart2/source/controller/dialogs/ObjectNameProvider.cxx @@ -46,8 +46,6 @@ #include <tools/debug.hxx> #include <tools/string.hxx> -// #include <unotools/syslocale.hxx> - #include <com/sun/star/chart2/XTitle.hpp> #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> @@ -197,7 +195,7 @@ OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal replaceParamterInString( aCategory , C2U("%CATEGORYVALUE") - , ExplicitCategoriesProvider::getCategoryByIndex( xCooSys, nPointIndex ) + , ExplicitCategoriesProvider::getCategoryByIndex( xCooSys, xChartModel, nPointIndex ) ); aRet = aCategory; diff --git a/chart2/source/controller/dialogs/ResourceIds.hrc b/chart2/source/controller/dialogs/ResourceIds.hrc index 02edc1a6bd96..2ab544c77ab1 100644 --- a/chart2/source/controller/dialogs/ResourceIds.hrc +++ b/chart2/source/controller/dialogs/ResourceIds.hrc @@ -48,6 +48,8 @@ #define DLG_SPLINE_PROPERTIES 904 #define DLG_DATA_TRENDLINE 841 #define DLG_DATA_YERRORBAR 842 +#define DLG_SHAPE_FONT 921 +#define DLG_SHAPE_PARAGRAPH 922 //----------------------------------------------------------------------------- //TabPage Ids: diff --git a/chart2/source/controller/dialogs/Strings.src b/chart2/source/controller/dialogs/Strings.src index 2d6fd9c04a66..4b4cec65426e 100644 --- a/chart2/source/controller/dialogs/Strings.src +++ b/chart2/source/controller/dialogs/Strings.src @@ -348,6 +348,11 @@ String STR_OBJECT_DIAGRAM_FLOOR Text [ en-US ] = "Chart Floor" ; }; +String STR_OBJECT_SHAPE +{ + Text [ en-US ] = "Drawing Object" ; +}; + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- diff --git a/chart2/source/controller/dialogs/dlg_DataEditor.cxx b/chart2/source/controller/dialogs/dlg_DataEditor.cxx index 41539df061b9..f1d441921a6a 100644 --- a/chart2/source/controller/dialogs/dlg_DataEditor.cxx +++ b/chart2/source/controller/dialogs/dlg_DataEditor.cxx @@ -144,34 +144,22 @@ IMPL_LINK( DataEditor, ToolboxHdl, void *, EMPTYARG ) break; case TBI_DATA_INSERT_COL: m_apBrwData->InsertColumn(); -// ImplAdjustHeaderControls( true /* bRefreshFromModel */ ); + break; + case TBI_DATA_INSERT_TEXT_COL: + m_apBrwData->InsertTextColumn(); break; case TBI_DATA_DELETE_ROW: m_apBrwData->RemoveRow(); break; case TBI_DATA_DELETE_COL: m_apBrwData->RemoveColumn(); -// ImplAdjustHeaderControls( true /* bRefreshFromModel */ ); break; case TBI_DATA_SWAP_COL : m_apBrwData->SwapColumn (); -// ImplAdjustHeaderControls( true /* bRefreshFromModel */ ); break; case TBI_DATA_SWAP_ROW : m_apBrwData->SwapRow (); break; -// case TBI_DATA_SORT_COL : -// m_apBrwData->QuickSortCol(); -// break; -// case TBI_DATA_SORT_ROW : -// m_apBrwData->QuickSortRow(); -// break; -// case TBI_DATA_SORT_TABLE_COL : -// m_apBrwData->QuickSortTableCols (); -// break; -// case TBI_DATA_SORT_TABLE_ROW : -// m_apBrwData->QuickSortTableRows (); -// break; } return 0; @@ -183,27 +171,16 @@ IMPL_LINK( DataEditor, BrowserCursorMovedHdl, void *, EMPTYARG ) if( m_bReadOnly ) return 0; - if( m_apBrwData->IsEnableItem() ) - { - m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, m_apBrwData->MayInsertRow() ); - m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, m_apBrwData->MayInsertColumn() ); - m_aTbxData.EnableItem( TBI_DATA_DELETE_ROW, m_apBrwData->MayDeleteRow() ); - m_aTbxData.EnableItem( TBI_DATA_DELETE_COL, m_apBrwData->MayDeleteColumn() ); + bool bIsDataValid = m_apBrwData->IsEnableItem(); - m_aTbxData.EnableItem( TBI_DATA_SWAP_COL, m_apBrwData->MaySwapColumns() ); - m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW, m_apBrwData->MaySwapRows() ); - } - else - { - m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, FALSE ); - m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, FALSE ); - m_aTbxData.EnableItem( TBI_DATA_SWAP_COL, FALSE ); - m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW, FALSE ); - } -// m_aTbxData.EnableItem( TBI_DATA_SORT_COL, m_apBrwData->MaySortColumn() ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_ROW, m_apBrwData->MaySortRow() ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_TABLE_COL, m_apBrwData->MaySortColumn() ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_TABLE_ROW, m_apBrwData->MaySortRow() ); + m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, bIsDataValid && m_apBrwData->MayInsertRow() ); + m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, bIsDataValid && m_apBrwData->MayInsertColumn() ); + m_aTbxData.EnableItem( TBI_DATA_INSERT_TEXT_COL, bIsDataValid && m_apBrwData->MayInsertColumn() ); + m_aTbxData.EnableItem( TBI_DATA_DELETE_ROW, m_apBrwData->MayDeleteRow() ); + m_aTbxData.EnableItem( TBI_DATA_DELETE_COL, m_apBrwData->MayDeleteColumn() ); + + m_aTbxData.EnableItem( TBI_DATA_SWAP_COL, bIsDataValid && m_apBrwData->MaySwapColumns() ); + m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW, bIsDataValid && m_apBrwData->MaySwapRows() ); return 0; } @@ -216,14 +193,11 @@ void DataEditor::SetReadOnly( bool bReadOnly ) { m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, FALSE ); m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, FALSE ); + m_aTbxData.EnableItem( TBI_DATA_INSERT_TEXT_COL, FALSE ); m_aTbxData.EnableItem( TBI_DATA_DELETE_ROW, FALSE ); m_aTbxData.EnableItem( TBI_DATA_DELETE_COL, FALSE ); m_aTbxData.EnableItem( TBI_DATA_SWAP_COL, FALSE ); m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW, FALSE ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_COL, FALSE ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_ROW, FALSE ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_TABLE_ROW, FALSE ); -// m_aTbxData.EnableItem( TBI_DATA_SORT_TABLE_COL, FALSE ); } m_apBrwData->SetReadOnly( m_bReadOnly ); diff --git a/chart2/source/controller/dialogs/dlg_DataEditor.hrc b/chart2/source/controller/dialogs/dlg_DataEditor.hrc index 8673f5e8cf80..d2675c5bb29e 100644 --- a/chart2/source/controller/dialogs/dlg_DataEditor.hrc +++ b/chart2/source/controller/dialogs/dlg_DataEditor.hrc @@ -33,19 +33,14 @@ #define CTL_DATA 1 // images for toolbox image list +//the numbers correspond to the icon names: default_images\chart2\res\dataeditor_icon_xy #define TBI_DATA_INSERT_ROW 1 #define TBI_DATA_INSERT_COL 2 #define TBI_DATA_DELETE_ROW 3 #define TBI_DATA_DELETE_COL 4 #define TBI_DATA_SWAP_COL 5 #define TBI_DATA_SWAP_ROW 6 -#define TBI_DATA_TRANSFER 7 - -// #define TBI_DATA_SORT_ROW 7 -// #define TBI_DATA_SORT_COL 8 -// #define TBI_DATA_SORT_TABLE_ROW 9 -// #define TBI_DATA_SORT_TABLE_COL 10 -// #define TBI_DATA_TRANSFER 11 +#define TBI_DATA_INSERT_TEXT_COL 7 // image lists (normal and high-contrast) for toolbox #define IL_DIAGRAM_DATA 1 diff --git a/chart2/source/controller/dialogs/dlg_DataEditor.src b/chart2/source/controller/dialogs/dlg_DataEditor.src index ce774e8f5bd2..dadd1ac3098d 100644 --- a/chart2/source/controller/dialogs/dlg_DataEditor.src +++ b/chart2/source/controller/dialogs/dlg_DataEditor.src @@ -80,6 +80,12 @@ ModalDialog DLG_DIAGRAM_DATA }; ToolBoxItem { + HelpID = HID_SCH_TBI_DATA_INSERT_TEXT_COL ; + Identifier = TBI_DATA_INSERT_TEXT_COL ; + Text [ en-US ] = "Insert Text Column" ; + }; + ToolBoxItem + { HelpID = HID_SCH_TBI_DATA_DELETE_ROW ; Identifier = TBI_DATA_DELETE_ROW ; Text [ en-US ] = "Delete Row" ; @@ -118,11 +124,11 @@ ModalDialog DLG_DIAGRAM_DATA { \ TBI_DATA_INSERT_ROW; \ TBI_DATA_INSERT_COL; \ + TBI_DATA_INSERT_TEXT_COL; \ TBI_DATA_DELETE_ROW; \ TBI_DATA_DELETE_COL; \ TBI_DATA_SWAP_COL; \ TBI_DATA_SWAP_ROW; \ - TBI_DATA_TRANSFER; \ }; \ IdCount = { 7; } diff --git a/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx b/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx index ec5f102bdaab..2a41d35313e8 100644 --- a/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx +++ b/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx @@ -204,7 +204,7 @@ void ObjectPropertiesDialogParameter::init( const uno::Reference< frame::XModel ScaleData aScale( xCrossingMainAxis->getScaleData() ); m_bIsCrossingAxisIsCategoryAxis = ( chart2::AxisType::CATEGORY == aScale.AxisType ); if( m_bIsCrossingAxisIsCategoryAxis ) - m_aCategories = DiagramHelper::generateAutomaticCategories( Reference< chart2::XChartDocument >( xChartModel, uno::UNO_QUERY) ); + m_aCategories = DiagramHelper::getExplicitSimpleCategories( Reference< chart2::XChartDocument >( xChartModel, uno::UNO_QUERY) ); } } } @@ -488,6 +488,8 @@ SchAttribTabDlg::SchAttribTabDlg(Window* pParent, SchAlignmentTabPage::CreateWithoutRotation can be deleted. */ AddTabPage(TP_ALIGNMENT, String(SchResId(STR_PAGE_ALIGNMENT)), SchAlignmentTabPage::CreateWithoutRotation, NULL); break; + default: + break; } // used to find out if user left the dialog with OK. When OK is pressed but diff --git a/chart2/source/controller/dialogs/dlg_ShapeFont.cxx b/chart2/source/controller/dialogs/dlg_ShapeFont.cxx new file mode 100644 index 000000000000..280a1adecba2 --- /dev/null +++ b/chart2/source/controller/dialogs/dlg_ShapeFont.cxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "dlg_ShapeFont.hxx" +#include "ViewElementListProvider.hxx" +#include "ResId.hxx" +#include "ResourceIds.hrc" + +#include <svl/intitem.hxx> +#include <sfx2/objsh.hxx> +#include <svx/dialogs.hrc> +#include <svx/flagsdef.hxx> +#include <editeng/flstitem.hxx> + +using ::com::sun::star::uno::Reference; +using namespace ::com::sun::star; + +//............................................................................. +namespace chart +{ +//............................................................................. + +ShapeFontDialog::ShapeFontDialog( Window* pParent, const SfxItemSet* pAttr, + const ViewElementListProvider* pViewElementListProvider ) + :SfxTabDialog( pParent, SchResId( DLG_SHAPE_FONT ), pAttr ) + ,m_pViewElementListProvider( pViewElementListProvider ) +{ + FreeResource(); + + AddTabPage( RID_SVXPAGE_CHAR_NAME ); + AddTabPage( RID_SVXPAGE_CHAR_EFFECTS ); + AddTabPage( RID_SVXPAGE_CHAR_POSITION ); +} + +ShapeFontDialog::~ShapeFontDialog() +{ +} + +void ShapeFontDialog::PageCreated( USHORT nId, SfxTabPage& rPage ) +{ + SfxAllItemSet aSet( *( GetInputSetImpl()->GetPool() ) ); + switch ( nId ) + { + case RID_SVXPAGE_CHAR_NAME: + { + aSet.Put( SvxFontListItem( m_pViewElementListProvider->getFontList(), SID_ATTR_CHAR_FONTLIST ) ); + rPage.PageCreated( aSet ); + } + break; + case RID_SVXPAGE_CHAR_EFFECTS: + { + aSet.Put( SfxUInt16Item( SID_DISABLE_CTL, DISABLE_CASEMAP ) ); + rPage.PageCreated( aSet ); + } + break; + default: + { + } + break; + } +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/controller/dialogs/dlg_ShapeFont.src b/chart2/source/controller/dialogs/dlg_ShapeFont.src new file mode 100644 index 000000000000..2065bd940988 --- /dev/null +++ b/chart2/source/controller/dialogs/dlg_ShapeFont.src @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "ResourceIds.hrc" +#include <svx/dialogs.hrc> + +TabDialog DLG_SHAPE_FONT +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 289 , 176 ) ; + Text [ en-US ] = "Character" ; + Moveable = TRUE ; + Closeable = TRUE ; + TabControl 1 + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT ( 260 , 135 ) ; + PageList = + { + PageItem + { + Identifier = RID_SVXPAGE_CHAR_NAME ; + Text [ en-US ] = "Font"; + }; + PageItem + { + Identifier = RID_SVXPAGE_CHAR_EFFECTS ; + Text [ en-US ] = "Font Effects"; + }; + PageItem + { + Identifier = RID_SVXPAGE_CHAR_POSITION ; + Text [ en-US ] = "Font Position"; + }; + }; + }; +}; diff --git a/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx b/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx new file mode 100644 index 000000000000..2f0173fc8408 --- /dev/null +++ b/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "dlg_ShapeParagraph.hxx" +#include "ResId.hxx" +#include "ResourceIds.hrc" + +#include <svl/cjkoptions.hxx> +#include <svl/intitem.hxx> +#include <svx/dialogs.hrc> +#include <svx/flagsdef.hxx> + +using ::com::sun::star::uno::Reference; +using namespace ::com::sun::star; + +//............................................................................. +namespace chart +{ +//............................................................................. + +ShapeParagraphDialog::ShapeParagraphDialog( Window* pParent, const SfxItemSet* pAttr ) + :SfxTabDialog( pParent, SchResId( DLG_SHAPE_PARAGRAPH ), pAttr ) +{ + FreeResource(); + + SvtCJKOptions aCJKOptions; + + AddTabPage( RID_SVXPAGE_STD_PARAGRAPH ); + AddTabPage( RID_SVXPAGE_ALIGN_PARAGRAPH ); + if ( aCJKOptions.IsAsianTypographyEnabled() ) + { + AddTabPage( RID_SVXPAGE_PARA_ASIAN ); + } + else + { + RemoveTabPage( RID_SVXPAGE_PARA_ASIAN ); + } + AddTabPage( RID_SVXPAGE_TABULATOR ); +} + +ShapeParagraphDialog::~ShapeParagraphDialog() +{ +} + +void ShapeParagraphDialog::PageCreated( USHORT nId, SfxTabPage& rPage ) +{ + SfxAllItemSet aSet( *( GetInputSetImpl()->GetPool() ) ); + switch ( nId ) + { + case RID_SVXPAGE_TABULATOR: + { + aSet.Put( SfxUInt16Item( SID_SVXTABULATORTABPAGE_CONTROLFLAGS, + ( TABTYPE_ALL &~TABTYPE_LEFT ) | ( TABFILL_ALL &~TABFILL_NONE ) ) ); + rPage.PageCreated( aSet ); + } + break; + default: + { + } + break; + } +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/controller/dialogs/dlg_ShapeParagraph.src b/chart2/source/controller/dialogs/dlg_ShapeParagraph.src new file mode 100644 index 000000000000..ff74fc1eef80 --- /dev/null +++ b/chart2/source/controller/dialogs/dlg_ShapeParagraph.src @@ -0,0 +1,67 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "ResourceIds.hrc" +#include <svx/dialogs.hrc> + +TabDialog DLG_SHAPE_PARAGRAPH +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 289 , 176 ) ; + Text [ en-US ] = "Paragraph" ; + Moveable = TRUE ; + Closeable = TRUE ; + TabControl 1 + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 3 , 3 ) ; + Size = MAP_APPFONT ( 260 , 135 ) ; + PageList = + { + PageItem + { + Identifier = RID_SVXPAGE_STD_PARAGRAPH ; + Text [ en-US ] = "Indents & Spacing"; + }; + PageItem + { + Identifier = RID_SVXPAGE_ALIGN_PARAGRAPH ; + Text [ en-US ] = "Alignment"; + }; + PageItem + { + Identifier = RID_SVXPAGE_PARA_ASIAN ; + Text [ en-US ] = "Asian Typography"; + }; + PageItem + { + Identifier = RID_SVXPAGE_TABULATOR ; + Text [ en-US ] = "Tab"; + }; + }; + }; +}; diff --git a/chart2/source/controller/dialogs/makefile.mk b/chart2/source/controller/dialogs/makefile.mk index 955c1764b5aa..d22f5c83b081 100644 --- a/chart2/source/controller/dialogs/makefile.mk +++ b/chart2/source/controller/dialogs/makefile.mk @@ -98,6 +98,8 @@ SLOFILES= \ $(SLO)$/dlg_ChartType_UNO.obj \ $(SLO)$/dlg_ChartType.obj \ $(SLO)$/dlg_NumberFormat.obj \ + $(SLO)$/dlg_ShapeFont.obj \ + $(SLO)$/dlg_ShapeParagraph.obj \ $(SLO)$/RangeSelectionButton.obj \ $(SLO)$/RangeSelectionHelper.obj \ $(SLO)$/RangeSelectionListener.obj \ @@ -150,7 +152,9 @@ SRC1FILES= \ dlg_InsertErrorBars.src \ dlg_InsertTitle.src \ dlg_ChartType.src \ - dlg_CreationWizard.src + dlg_CreationWizard.src \ + dlg_ShapeFont.src \ + dlg_ShapeParagraph.src SRS1NAME=$(TARGET) diff --git a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx index 299cd9efe859..fbcca6a26bde 100644 --- a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx +++ b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx @@ -31,6 +31,8 @@ #include "chartview/DrawModelWrapper.hxx" #include "ConfigurationAccess.hxx" +#include <unotools/lingucfg.hxx> +#include <editeng/langitem.hxx> // header for class SdrPage #include <svx/svdpage.hxx> //header for class SdrPageView @@ -51,6 +53,7 @@ // header for class SvxShape #include <svx/unoshape.hxx> +#include <editeng/fhgtitem.hxx> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> @@ -162,6 +165,24 @@ DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut, bool SetPagePaintingAllowed(bPaintPageForEditMode); + // #i12587# support for shapes in chart + SdrOutliner* pOutliner = getOutliner(); + SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : NULL ); + if ( pOutlinerPool ) + { + SvtLinguConfig aLinguConfig; + SvtLinguOptions aLinguOptions; + if ( aLinguConfig.GetOptions( aLinguOptions ) ) + { + pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) ); + pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) ); + pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) ); + } + + // set font height without changing SdrEngineDefaults + pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt + } + ReInit(); } diff --git a/chart2/source/controller/inc/AccessibleBase.hxx b/chart2/source/controller/inc/AccessibleBase.hxx index 46d63927a9d7..ea52a29c614b 100644 --- a/chart2/source/controller/inc/AccessibleBase.hxx +++ b/chart2/source/controller/inc/AccessibleBase.hxx @@ -27,6 +27,8 @@ #ifndef _CHART2_ACCESSIBLEBASE_HXX_ #define _CHART2_ACCESSIBLEBASE_HXX_ +#include "ObjectIdentifier.hxx" + #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/accessibility/XAccessible.hpp> #include <com/sun/star/accessibility/XAccessibleContext.hpp> @@ -50,6 +52,12 @@ class SfxItemSet; class SdrObject; +class SdrView; + +namespace accessibility +{ +class IAccessibleViewForwarder; +} namespace chart { @@ -57,11 +65,11 @@ namespace chart class AccessibleBase; class ObjectHierarchy; -typedef rtl::OUString AccessibleUniqueId; +typedef ObjectIdentifier AccessibleUniqueId; struct AccessibleElementInfo { - AccessibleUniqueId m_aCID; + AccessibleUniqueId m_aOID; ::com::sun::star::uno::WeakReference< ::com::sun::star::chart2::XChartDocument > m_xChartDocument; @@ -75,6 +83,8 @@ struct AccessibleElementInfo ::boost::shared_ptr< ObjectHierarchy > m_spObjectHierarchy; AccessibleBase * m_pParent; + SdrView* m_pSdrView; + ::accessibility::IAccessibleViewForwarder* m_pViewForwarder; }; @@ -173,7 +183,7 @@ protected: greater than the index of the removed element get an index one less than before. */ - void RemoveChildById( const ::rtl::OUString & rId ); + void RemoveChildByOId( const ObjectIdentifier& rOId ); /** Retrieve the pixel coordinates of logical coordinates (0,0) of the current logic coordinate system. This can be used for @@ -325,14 +335,14 @@ private: /** type of the hash containing a vector index for every AccessibleUniqueId of the object in the child list */ - typedef ::std::map< ::rtl::OUString, tAccessible > ChildCIDMap; + typedef ::std::map< ObjectIdentifier, tAccessible > ChildOIDMap; bool m_bIsDisposed; const bool m_bMayHaveChildren; bool m_bChildrenInitialized; ChildListVectorType m_aChildList; - ChildCIDMap m_aChildCIDMap; + ChildOIDMap m_aChildOIDMap; ::comphelper::AccessibleEventNotifier::TClientId m_nEventNotifierId; diff --git a/chart2/source/controller/inc/AccessibleChartView.hxx b/chart2/source/controller/inc/AccessibleChartView.hxx index 435871dbf55a..2cc46825a5aa 100644 --- a/chart2/source/controller/inc/AccessibleChartView.hxx +++ b/chart2/source/controller/inc/AccessibleChartView.hxx @@ -44,13 +44,17 @@ #include <boost/shared_ptr.hpp> +namespace accessibility +{ +class IAccessibleViewForwarder; +} + //............................................................................. namespace chart { //............................................................................. class ExplicitValueProvider; -class ObjectHierarchy; namespace impl { @@ -67,14 +71,9 @@ class AccessibleChartView : public: AccessibleChartView( const ::com::sun::star::uno::Reference< - ::com::sun::star::uno::XComponentContext > & xContext ); + ::com::sun::star::uno::XComponentContext >& xContext, SdrView* pView ); virtual ~AccessibleChartView(); - // ____ lang::XServiceInfo ____ - APPHELPER_XSERVICEINFO_DECL() - APPHELPER_SERVICE_FACTORY_HELPER( AccessibleChartView ) - -protected: // ____ WeakComponentHelper (called from XComponent::dispose()) ____ virtual void SAL_CALL disposing(); @@ -112,6 +111,7 @@ protected: virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen() throw (::com::sun::star::uno::RuntimeException); +protected: // ________ AccessibleChartElement ________ virtual ::com::sun::star::awt::Point GetUpperLeftOnScreen() const; @@ -141,7 +141,9 @@ private: // members ::com::sun::star::accessibility::XAccessible > m_xParent; ::boost::shared_ptr< ObjectHierarchy > m_spObjectHierarchy; - AccessibleUniqueId m_aCurrentSelectionCID; + AccessibleUniqueId m_aCurrentSelectionOID; + SdrView* m_pSdrView; + ::accessibility::IAccessibleViewForwarder* m_pViewForwarder; //no default constructor AccessibleChartView(); diff --git a/chart2/source/controller/inc/HelpIds.hrc b/chart2/source/controller/inc/HelpIds.hrc index 88cd1619bab8..1052b7ea962f 100644 --- a/chart2/source/controller/inc/HelpIds.hrc +++ b/chart2/source/controller/inc/HelpIds.hrc @@ -29,6 +29,7 @@ #include <svl/solar.hrc> //next is 120 +//free: 20, 21, 22, 30, 31, 32, 33 //see old chart: schhids.h @@ -61,21 +62,13 @@ //#define HID_SCH_CT_INDICATE2 (HID_SCH_START + 18) //#define HID_SCH_CT_REGRESS2 (HID_SCH_START + 19) -//#define HID_SCH_TBI_EDIT_CANCEL (HID_SCH_START + 20) -//#define HID_SCH_TBI_EDIT_ACCEPT (HID_SCH_START + 21) -#define HID_SCH_TBI_DATA_TRANSFER (HID_SCH_START + 22) #define HID_SCH_TBI_DATA_INSERT_ROW (HID_SCH_START + 23) #define HID_SCH_TBI_DATA_INSERT_COL (HID_SCH_START + 24) #define HID_SCH_TBI_DATA_DELETE_ROW (HID_SCH_START + 25) #define HID_SCH_TBI_DATA_DELETE_COL (HID_SCH_START + 26) #define HID_SCH_TBI_DATA_SWAP_COL (HID_SCH_START + 27) #define HID_SCH_TBI_DATA_SWAP_ROW (HID_SCH_START + 28) -//#define HID_SCH_TBI_DATA_SORT_ROW (HID_SCH_START + 29) -//#define HID_SCH_TBI_DATA_SORT_COL (HID_SCH_START + 30) -//#define HID_SCH_TBI_DATA_SORT_TABLE_ROW (HID_SCH_START + 31) -//#define HID_SCH_TBI_DATA_SORT_TABLE_COL (HID_SCH_START + 32) - -// #define HID_SCH_TBX_EDIT (HID_SCH_START + 33) +#define HID_SCH_TBI_DATA_INSERT_TEXT_COL (HID_SCH_START + 29) #define HID_SCH_TBX_DATA (HID_SCH_START + 34) #define HID_SCH_ALIGNMENT_CTR_DIAL (HID_SCH_START + 35) diff --git a/chart2/source/controller/inc/MenuResIds.hrc b/chart2/source/controller/inc/MenuResIds.hrc new file mode 100644 index 000000000000..38a09ad35ded --- /dev/null +++ b/chart2/source/controller/inc/MenuResIds.hrc @@ -0,0 +1,41 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART_MENURESIDS_HRC +#define CHART_MENURESIDS_HRC + +#ifndef _SOLAR_HRC +#include <svl/solar.hrc> +#endif + +//----------------------------------------------------------------------------- +// context menus + +#define RID_CONTEXTMENU_SHAPE (RID_APP_START + 1) +#define RID_CONTEXTMENU_SHAPEEDIT (RID_APP_START + 2) + +// CHART_MENURESIDS_HRC +#endif diff --git a/chart2/source/controller/inc/ObjectHierarchy.hxx b/chart2/source/controller/inc/ObjectHierarchy.hxx index f012fb500416..857b576fe6ef 100644 --- a/chart2/source/controller/inc/ObjectHierarchy.hxx +++ b/chart2/source/controller/inc/ObjectHierarchy.hxx @@ -27,6 +27,8 @@ #ifndef CHART2_OBJECTHIERARCHY_HXX #define CHART2_OBJECTHIERARCHY_HXX +#include "ObjectIdentifier.hxx" + #include <rtl/ustring.hxx> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/awt/KeyEvent.hpp> @@ -47,8 +49,8 @@ class ImplObjectHierarchy; class ObjectHierarchy { public: - typedef ::rtl::OUString tCID; - typedef ::std::vector< tCID > tChildContainer; + typedef ObjectIdentifier tOID; + typedef ::std::vector< tOID > tChildContainer; /** @param bFlattenDiagram If <TRUE/>, the content of the diaram (data series, wall, floor, @@ -63,20 +65,20 @@ public: bool bOrderingForElementSelector = false ); ~ObjectHierarchy(); - static tCID getRootNodeCID(); - static bool isRootNode( const tCID & rCID ); + static tOID getRootNodeOID(); + static bool isRootNode( const tOID& rOID ); - /// equal to getChildren( getRootNodeCID()) + /// equal to getChildren( getRootNodeOID()) tChildContainer getTopLevelChildren() const; - bool hasChildren( const tCID & rParent ) const; - tChildContainer getChildren( const tCID & rParent ) const; + bool hasChildren( const tOID& rParent ) const; + tChildContainer getChildren( const tOID& rParent ) const; - tChildContainer getSiblings( const tCID & rNode ) const; + tChildContainer getSiblings( const tOID& rNode ) const; /// The result is empty, if the node cannot be found in the tree - tCID getParent( const tCID & rNode ) const; + tOID getParent( const tOID& rNode ) const; /// @returns -1, if no parent can be determined - sal_Int32 getIndexInParent( const tCID & rNode ) const; + sal_Int32 getIndexInParent( const tOID& rNode ) const; private: @@ -86,16 +88,16 @@ private: class ObjectKeyNavigation { public: - explicit ObjectKeyNavigation( const ObjectHierarchy::tCID & rCurrentCID, + explicit ObjectKeyNavigation( const ObjectHierarchy::tOID & rCurrentOID, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > & xChartDocument, ExplicitValueProvider * pExplicitValueProvider = 0 ); bool handleKeyEvent( const ::com::sun::star::awt::KeyEvent & rEvent ); - ObjectHierarchy::tCID getCurrentSelection() const; + ObjectHierarchy::tOID getCurrentSelection() const; private: - void setCurrentSelection( const ObjectHierarchy::tCID & rCID ); + void setCurrentSelection( const ObjectHierarchy::tOID& rOID ); bool first(); bool last(); bool next(); @@ -105,7 +107,7 @@ private: bool veryFirst(); bool veryLast(); - ObjectHierarchy::tCID m_aCurrentCID; + ObjectHierarchy::tOID m_aCurrentOID; ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > m_xChartDocument; ExplicitValueProvider * m_pExplicitValueProvider; diff --git a/chart2/source/controller/inc/ShapeController.hrc b/chart2/source/controller/inc/ShapeController.hrc new file mode 100644 index 000000000000..6c7b43526d22 --- /dev/null +++ b/chart2/source/controller/inc/ShapeController.hrc @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART_SHAPECONTROLLER_HRC +#define CHART_SHAPECONTROLLER_HRC + +//----------------------------------------------------------------------------- +//Command Ids: +#define COMMAND_ID_FORMAT_LINE 1 +#define COMMAND_ID_FORMAT_AREA 2 +#define COMMAND_ID_TEXT_ATTRIBUTES 3 +#define COMMAND_ID_TRANSFORM_DIALOG 4 +#define COMMAND_ID_OBJECT_TITLE_DESCRIPTION 5 +#define COMMAND_ID_RENAME_OBJECT 6 +#define COMMAND_ID_ARRANGE_ROW 7 +#define COMMAND_ID_BRING_TO_FRONT 8 +#define COMMAND_ID_FORWARD 9 +#define COMMAND_ID_BACKWARD 10 +#define COMMAND_ID_SEND_TO_BACK 11 +#define COMMAND_ID_CUT 12 +#define COMMAND_ID_COPY 13 +#define COMMAND_ID_PASTE 14 +#define COMMAND_ID_FONT_DIALOG 15 +#define COMMAND_ID_PARAGRAPH_DIALOG 16 + +// CHART_SHAPECONTROLLER_HRC +#endif diff --git a/chart2/source/controller/inc/dlg_ShapeFont.hxx b/chart2/source/controller/inc/dlg_ShapeFont.hxx new file mode 100644 index 000000000000..ec1b6553bd64 --- /dev/null +++ b/chart2/source/controller/inc/dlg_ShapeFont.hxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_DLG_SHAPEFONT_HXX +#define CHART2_DLG_SHAPEFONT_HXX + +#include <sfx2/tabdlg.hxx> + +//............................................................................. +namespace chart +{ +//............................................................................. + +class ViewElementListProvider; + +/** dialog for font properties of shapes + */ +class ShapeFontDialog : public SfxTabDialog +{ +public: + ShapeFontDialog( Window* pParent, const SfxItemSet* pAttr, + const ViewElementListProvider* pViewElementListProvider ); + virtual ~ShapeFontDialog(); + +private: + virtual void PageCreated( USHORT nId, SfxTabPage& rPage ); + + const ViewElementListProvider* m_pViewElementListProvider; +}; + +//............................................................................. +} // namespace chart +//............................................................................. + +// CHART2_DLG_SHAPEFONT_HXX +#endif diff --git a/chart2/source/controller/inc/dlg_ShapeParagraph.hxx b/chart2/source/controller/inc/dlg_ShapeParagraph.hxx new file mode 100644 index 000000000000..2bc57bfcffc2 --- /dev/null +++ b/chart2/source/controller/inc/dlg_ShapeParagraph.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_DLG_SHAPEPARAGRAPH_HXX +#define CHART2_DLG_SHAPEPARAGRAPH_HXX + +#include <sfx2/tabdlg.hxx> + +//............................................................................. +namespace chart +{ +//............................................................................. + +/** dialog for paragraph properties of shapes + */ +class ShapeParagraphDialog : public SfxTabDialog +{ +public: + ShapeParagraphDialog( Window* pParent, const SfxItemSet* pAttr ); + virtual ~ShapeParagraphDialog(); + +private: + virtual void PageCreated( USHORT nId, SfxTabPage& rPage ); +}; + +//............................................................................. +} // namespace chart +//............................................................................. + +// CHART2_DLG_SHAPEPARAGRAPH_HXX +#endif diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index c2202b031a17..4c0c7dc38ae3 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -50,6 +50,10 @@ #include "dlg_CreationWizard.hxx" #include "dlg_ChartType.hxx" //#include "svx/ActionDescriptionProvider.hxx" +#include "AccessibleChartView.hxx" +#include "DrawCommandDispatch.hxx" +#include "ShapeController.hxx" +#include "UndoManager.hxx" #include <comphelper/InlineContainer.hxx> @@ -97,6 +101,7 @@ namespace chart //............................................................................. using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; using namespace ::com::sun::star::chart2; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; @@ -124,7 +129,8 @@ ChartController::ChartController(uno::Reference<uno::XComponentContext> const & , m_bWaitingForMouseUp(false) , m_bConnectingToView(false) , m_xUndoManager( 0 ) - , m_aDispatchContainer( m_xCC ) + , m_aDispatchContainer( m_xCC, this ) + , m_eDrawMode( CHARTDRAW_SELECT ) { DBG_CTOR(ChartController,NULL); // m_aDispatchContainer.setUndoManager( m_xUndoManager ); @@ -438,6 +444,11 @@ APPHELPER_XSERVICEINFO_IMPL(ChartController,CHART_CONTROLLER_SERVICE_IMPLEMENTAT //@todo: createElement should become unnecessary, remove when #i79198# is fixed xLayoutManager->createElement( C2U( "private:resource/toolbar/toolbar" ) ); xLayoutManager->requestElement( C2U( "private:resource/toolbar/toolbar" ) ); + + // #i12587# support for shapes in chart + xLayoutManager->createElement( C2U( "private:resource/toolbar/drawbar" ) ); + xLayoutManager->requestElement( C2U( "private:resource/toolbar/drawbar" ) ); + xLayoutManager->requestElement( C2U( "private:resource/statusbar/statusbar" ) ); xLayoutManager->unlock(); @@ -559,13 +570,27 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent // set new model at dispatchers m_aDispatchContainer.setModel( aNewModelRef->getModel()); - ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this ); + ControllerCommandDispatch * pDispatch = new ControllerCommandDispatch( m_xCC, this, &m_aDispatchContainer ); pDispatch->initialize(); // the dispatch container will return "this" for all commands returned by // impl_getAvailableCommands(). That means, for those commands dispatch() // is called here at the ChartController. - m_aDispatchContainer.setFallbackDispatch( pDispatch, impl_getAvailableCommands() ); + m_aDispatchContainer.setChartDispatch( pDispatch, impl_getAvailableCommands() ); + + DrawCommandDispatch* pDrawDispatch = new DrawCommandDispatch( m_xCC, this ); + if ( pDrawDispatch ) + { + pDrawDispatch->initialize(); + m_aDispatchContainer.setDrawCommandDispatch( pDrawDispatch ); + } + + ShapeController* pShapeController = new ShapeController( m_xCC, this ); + if ( pShapeController ) + { + pShapeController->initialize(); + m_aDispatchContainer.setShapeController( pShapeController ); + } #ifdef TEST_ENABLE_MODIFY_LISTENER uno::Reference< util::XModifyBroadcaster > xMBroadcaster( aNewModelRef->getModel(),uno::UNO_QUERY ); @@ -1061,7 +1086,7 @@ bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) void SAL_CALL ChartController ::dispatch( const util::URL& rURL - , const uno::Sequence< beans::PropertyValue >& /* rArgs */ ) + , const uno::Sequence< beans::PropertyValue >& rArgs ) throw (uno::RuntimeException) { //@todo avoid OString (see Mathias mail on bug #104387#) @@ -1161,7 +1186,16 @@ bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) else if( aCommand.equals("FormatSelection") ) this->executeDispatch_ObjectProperties(); else if( aCommand.equals("TransformDialog")) - this->executeDispatch_PositionAndSize(); + { + if ( isShapeContext() ) + { + this->impl_ShapeControllerDispatch( rURL, rArgs ); + } + else + { + this->executeDispatch_PositionAndSize(); + } + } else if( lcl_isFormatObjectCommand(aCommand) ) this->executeDispatch_FormatObject(rURL.Path); //more format @@ -1171,10 +1205,28 @@ bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) this->executeDispatch_ChartType(); else if( aCommand.equals("View3D")) this->executeDispatch_View3D(); - else if( aCommand.equals("Forward")) - this->executeDispatch_MoveSeries( sal_True ); - else if( aCommand.equals("Backward")) - this->executeDispatch_MoveSeries( sal_False ); + else if ( aCommand.equals( "Forward" ) ) + { + if ( isShapeContext() ) + { + this->impl_ShapeControllerDispatch( rURL, rArgs ); + } + else + { + this->executeDispatch_MoveSeries( sal_True ); + } + } + else if ( aCommand.equals( "Backward" ) ) + { + if ( isShapeContext() ) + { + this->impl_ShapeControllerDispatch( rURL, rArgs ); + } + else + { + this->executeDispatch_MoveSeries( sal_False ); + } + } else if( aCommand.equals("NewArrangement")) this->executeDispatch_NewArrangement(); else if( aCommand.equals("ToggleLegend")) @@ -1390,6 +1442,20 @@ void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ ) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- +IMPL_LINK( ChartController, NotifyUndoActionHdl, SdrUndoAction*, pUndoAction ) +{ + ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); + if ( aObjectCID.getLength() == 0 ) + { + UndoManager* pUndoManager = UndoManager::getImplementation( m_xUndoManager ); + if ( pUndoManager ) + { + pUndoManager->addShapeUndoAction( pUndoAction ); + } + } + return 0L; +} + DrawModelWrapper* ChartController::GetDrawModelWrapper() { if( !m_pDrawModelWrapper.get() ) @@ -1397,16 +1463,26 @@ DrawModelWrapper* ChartController::GetDrawModelWrapper() ExplicitValueProvider* pProvider = ExplicitValueProvider::getExplicitValueProvider( m_xChartView ); if( pProvider ) m_pDrawModelWrapper = pProvider->getDrawModelWrapper(); + if ( m_pDrawModelWrapper.get() ) + { + m_pDrawModelWrapper->getSdrModel().SetNotifyUndoActionHdl( LINK( this, ChartController, NotifyUndoActionHdl ) ); + } } return m_pDrawModelWrapper.get(); } -uno::Reference< accessibility::XAccessible > ChartController::CreateAccessible() +DrawViewWrapper* ChartController::GetDrawViewWrapper() { - uno::Reference< accessibility::XAccessible > xResult( - m_xCC->getServiceManager()->createInstanceWithContext( - CHART2_ACCESSIBLE_SERVICE_NAME, m_xCC ), uno::UNO_QUERY ); + if ( !m_pDrawViewWrapper ) + { + impl_createDrawViewController(); + } + return m_pDrawViewWrapper; +} +uno::Reference< XAccessible > ChartController::CreateAccessible() +{ + uno::Reference< XAccessible > xResult = new AccessibleChartView( m_xCC, GetDrawViewWrapper() ); impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) ); return xResult; } @@ -1438,7 +1514,7 @@ void ChartController::impl_initializeAccessible( const uno::Reference< lang::XIn uno::Reference<frame::XModel> xModel(m_aModel->getModel()); aArguments[1]=uno::makeAny(xModel); aArguments[2]=uno::makeAny(m_xChartView); - uno::Reference< accessibility::XAccessible > xParent; + uno::Reference< XAccessible > xParent; if( m_pChartWindow ) { Window* pParentWin( m_pChartWindow->GetAccessibleParentWindow()); diff --git a/chart2/source/controller/main/ChartController.hxx b/chart2/source/controller/main/ChartController.hxx index 130e40cb6828..8deffe47396f 100644 --- a/chart2/source/controller/main/ChartController.hxx +++ b/chart2/source/controller/main/ChartController.hxx @@ -57,6 +57,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/util/XModifyListener.hpp> #include <com/sun/star/util/XModeChangeListener.hpp> +#include <com/sun/star/awt/Point.hpp> #include <com/sun/star/awt/Size.hpp> #include <com/sun/star/util/XURLTransformer.hpp> #include <com/sun/star/frame/XLayoutManagerListener.hpp> @@ -88,6 +89,8 @@ namespace chart { //............................................................................. +enum ChartDrawMode { CHARTDRAW_INSERT, CHARTDRAW_SELECT }; + class WindowController { public: @@ -155,6 +158,9 @@ class ChartController : public ::cppu::WeakImplHelper12 < > , public WindowController { + friend class DrawCommandDispatch; + friend class ShapeController; + public: //no default constructor ChartController(::com::sun::star::uno::Reference< @@ -463,6 +469,13 @@ public: static bool isObjectDeleteable( const ::com::sun::star::uno::Any& rSelection ); + void setDrawMode( ChartDrawMode eMode ) { m_eDrawMode = eMode; } + ChartDrawMode getDrawMode() const { return m_eDrawMode; } + + bool isShapeContext() const; + + DECL_LINK( NotifyUndoActionHdl, SdrUndoAction* ); + public: //----------------------------------------------------------------- //----------------------------------------------------------------- @@ -477,6 +490,7 @@ public: private: DrawModelWrapper* GetDrawModelWrapper(); + DrawViewWrapper* GetDrawViewWrapper(); private: class TheModelRef; @@ -577,6 +591,8 @@ private: ::com::sun::star::frame::XLayoutManagerEventBroadcaster > m_xLayoutManagerEventBroadcaster; + ChartDrawMode m_eDrawMode; + private: //private methods @@ -637,11 +653,11 @@ private: void executeDispatch_DeleteMinorGrid(); void SAL_CALL executeDispatch_InsertSpecialCharacter(); - void SAL_CALL executeDispatch_EditText(); + void SAL_CALL executeDispatch_EditText( const Point* pMousePixel = NULL ); void SAL_CALL executeDispatch_SourceData(); void SAL_CALL executeDispatch_MoveSeries( sal_Bool bForward ); - void StartTextEdit(); + void StartTextEdit( const Point* pMousePixel = NULL ); bool EndTextEdit(); void SAL_CALL executeDispatch_View3D(); @@ -659,9 +675,12 @@ private: void executeDispatch_ToggleLegend(); void executeDispatch_ToggleGridHorizontal(); + void impl_ShapeControllerDispatch( const ::com::sun::star::util::URL& rURL, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs ); + // DECL_LINK( DoubleClickWaitingHdl, void* ); - void execute_DoubleClick(); + void execute_DoubleClick( const Point* pMousePixel = NULL ); void startDoubleClickWaiting(); void stopDoubleClickWaiting(); @@ -701,6 +720,8 @@ private: void impl_PasteGraphic( ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > & xGraphic, const ::Point & aPosition ); + void impl_PasteShapes( SdrModel* pModel ); + void impl_PasteStringAsTextShape( const ::rtl::OUString& rString, const ::com::sun::star::awt::Point& rPosition ); void impl_SetMousePointer( const MouseEvent & rEvent ); void impl_ClearSelection(); diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx index 4778f67f7bde..4df362ee80d2 100644 --- a/chart2/source/controller/main/ChartController_TextEdit.cxx +++ b/chart2/source/controller/main/ChartController_TextEdit.cxx @@ -64,15 +64,15 @@ using namespace ::com::sun::star; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void SAL_CALL ChartController::executeDispatch_EditText() +void SAL_CALL ChartController::executeDispatch_EditText( const Point* pMousePixel ) { - this->StartTextEdit(); + this->StartTextEdit( pMousePixel ); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void ChartController::StartTextEdit() +void ChartController::StartTextEdit( const Point* pMousePixel ) { //the first marked object will be edited @@ -111,6 +111,18 @@ void ChartController::StartTextEdit() */ m_pDrawViewWrapper->SetEditMode(); + // #i12587# support for shapes in chart + if ( pMousePixel ) + { + OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView(); + if ( pOutlinerView ) + { + MouseEvent aEditEvt( *pMousePixel, 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 ); + pOutlinerView->MouseButtonDown( aEditEvt ); + pOutlinerView->MouseButtonUp( aEditEvt ); + } + } + //we invalidate the outliner region because the outliner has some //paint problems (some characters are painted twice a little bit shifted) m_pChartWindow->Invalidate( m_pDrawViewWrapper->GetMarkedObjBoundRect() ); @@ -139,22 +151,38 @@ bool ChartController::EndTextEdit() String aString = pOutliner->GetText( pOutliner->GetParagraph( 0 ), pOutliner->GetParagraphCount() ); - uno::Reference< beans::XPropertySet > xPropSet = - ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ); - - // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); - //Paragraph* pPara = - TitleHelper::setCompleteString( aString, uno::Reference< - ::com::sun::star::chart2::XTitle >::query( xPropSet ), m_xCC ); - try + ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); + if ( aObjectCID.getLength() > 0 ) { - m_xUndoManager->postAction( C2U("Edit Text") ); + uno::Reference< beans::XPropertySet > xPropSet = + ObjectIdentifier::getObjectPropertySet( aObjectCID, getModel() ); + + // lock controllers till end of block + ControllerLockGuard aCLGuard( m_aModel->getModel()); + + TitleHelper::setCompleteString( aString, uno::Reference< + ::com::sun::star::chart2::XTitle >::query( xPropSet ), m_xCC ); + + try + { + m_xUndoManager->postAction( C2U("Edit Text") ); + } + catch( uno::RuntimeException& e) + { + ASSERT_EXCEPTION( e ); + } } - catch( uno::RuntimeException& e) + else { - ASSERT_EXCEPTION( e ); + try + { + m_xUndoManager->cancelAction(); + } + catch ( uno::RuntimeException& e ) + { + ASSERT_EXCEPTION( e ); + } } } return true; diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index 9edd2963aca4..352a7e1279cc 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -48,6 +48,7 @@ #include "LegendHelper.hxx" #include "AxisHelper.hxx" #include "RegressionCurveHelper.hxx" +#include "ShapeController.hxx" #include <com/sun/star/chart2/DataPointLabel.hpp> #include <com/sun/star/beans/XPropertyState.hpp> @@ -59,8 +60,6 @@ #include <com/sun/star/drawing/TextHorizontalAdjust.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp> -// #include <com/sun/star/drawing/XDrawPageSupplier.hpp> - #include <svx/ActionDescriptionProvider.hxx> // for TransferableDataHelper/TransferableHelper #include <svtools/transfer.hxx> @@ -77,8 +76,17 @@ // for SolarMutex #include <vcl/svapp.hxx> #include <vos/mutex.hxx> +#include <svx/dialmgr.hxx> +#include <svx/dialogs.hrc> // for OutlinerView #include <editeng/outliner.hxx> +#include <svx/svditer.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdundo.hxx> +#include <svx/unoapi.hxx> +#include <svx/unopage.hxx> + +#include <boost/scoped_ptr.hpp> using namespace ::com::sun::star; @@ -184,50 +192,6 @@ bool lcl_deleteDataCurve( } // anonymous namespace -namespace -{ -void lcl_InsertStringAsTextShapeIntoDrawPage( - const Reference< lang::XMultiServiceFactory > & xShapeFactory, - const Reference< drawing::XDrawPage > & xDrawPage, - OUString & rString, - const awt::Point & aPosition ) -{ - OSL_ASSERT( xShapeFactory.is() && xDrawPage.is()); - if( ! (xShapeFactory.is() && xDrawPage.is())) - return; - - try - { - Reference< drawing::XShape > xTextShape( - xShapeFactory->createInstance( C2U("com.sun.star.drawing.TextShape")), uno::UNO_QUERY_THROW ); - xDrawPage->add( xTextShape ); - - Reference< text::XTextRange > xRange( xTextShape, uno::UNO_QUERY_THROW ); - xRange->setString( rString ); - - float fCharHeight = 10.0; - Reference< beans::XPropertySet > xProperties( xTextShape, uno::UNO_QUERY_THROW ); - xProperties->setPropertyValue( C2U("TextAutoGrowHeight"), uno::makeAny( true )); - xProperties->setPropertyValue( C2U("TextAutoGrowWidth"), uno::makeAny( true )); - xProperties->setPropertyValue( C2U("CharHeight"), uno::makeAny( fCharHeight )); - xProperties->setPropertyValue( C2U("CharHeightAsian"), uno::makeAny( fCharHeight )); - xProperties->setPropertyValue( C2U("CharHeightComplex"), uno::makeAny( fCharHeight )); - xProperties->setPropertyValue( C2U("TextVerticalAdjust"), uno::makeAny( drawing::TextVerticalAdjust_CENTER )); - xProperties->setPropertyValue( C2U("TextHorizontalAdjust"), uno::makeAny( drawing::TextHorizontalAdjust_CENTER )); - xProperties->setPropertyValue( C2U("CharFontName"), uno::makeAny( C2U( "Albany" ))); - - awt::Point aAdaptedPos( aPosition ); - aAdaptedPos.Y -= (xTextShape->getSize().Height / 2); - aAdaptedPos.X -= (xTextShape->getSize().Width / 2); - xTextShape->setPosition( aAdaptedPos ); - } - catch( const uno::Exception & ex ) - { - ASSERT_EXCEPTION( ex ); - } -} - -} // anonymous namespace namespace chart { @@ -334,22 +298,21 @@ void ChartController::executeDispatch_Paste() TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( m_pChartWindow )); if( aDataHelper.GetTransferable().is()) { -// if( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING )) -// { -// SotStorageStreamRef xStm; -// if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm )) -// { -// xStm->Seek( 0 ); -// uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm )); -// SdrModel * pModel = new SdrModel(); -// DrawModelWrapper * pDrawModelWrapper( this->GetDrawModelWrapper()); -// if( SvxDrawingLayerImport( pModel, xInputStream )) -// lcl_CopyShapesToChart( *pModel, m_pDrawModelWrapper->getSdrModel()); -// delete pModel; -// } -// } -// else - if( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB )) + if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) ) + { + SotStorageStreamRef xStm; + if ( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) ) + { + xStm->Seek( 0 ); + Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) ); + ::boost::scoped_ptr< SdrModel > spModel( new SdrModel() ); + if ( SvxDrawingLayerImport( spModel.get(), xInputStream ) ) + { + impl_PasteShapes( spModel.get() ); + } + } + } + else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) ) { // graphic exchange format (graphic manager bitmap format?) SotStorageStreamRef xStm; @@ -382,14 +345,7 @@ void ChartController::executeDispatch_Paste() pOutlinerView->InsertText( aString ); else { - awt::Point aTextPos; - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel())); - aTextPos.X = (aPageSize.Width / 2); - aTextPos.Y = (aPageSize.Height / 2); - lcl_InsertStringAsTextShapeIntoDrawPage( - m_pDrawModelWrapper->getShapeFactory(), - m_pDrawModelWrapper->getMainDrawPage(), - aString, aTextPos ); + impl_PasteStringAsTextShape( aString, awt::Point( 0, 0 ) ); } } } @@ -441,7 +397,6 @@ void ChartController::impl_PasteGraphic( uno::Reference< beans::XPropertySet > xGraphicProp( xGraphic, uno::UNO_QUERY ); awt::Size aGraphicSize( 1000, 1000 ); - awt::Point aShapePos( 100,100 ); // first try size in 100th mm, then pixel size if( ! ( xGraphicProp->getPropertyValue( C2U("Size100thMM")) >>= aGraphicSize ) && ( ( xGraphicProp->getPropertyValue( C2U("SizePixel")) >>= aGraphicSize ) && m_pChartWindow )) @@ -451,41 +406,158 @@ void ChartController::impl_PasteGraphic( aGraphicSize.Height = aVCLSize.getHeight(); } xGraphicShape->setSize( aGraphicSize ); - - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel())); - aShapePos.X = (aPageSize.Width / 2) - (aGraphicSize.Width / 2); - aShapePos.Y = (aPageSize.Height / 2) - (aGraphicSize.Height / 2); - xGraphicShape->setPosition( aShapePos ); + xGraphicShape->setPosition( awt::Point( 0, 0 ) ); } } -void ChartController::executeDispatch_Copy() +void ChartController::impl_PasteShapes( SdrModel* pModel ) { + DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() ); + if ( pDrawModelWrapper && m_pDrawViewWrapper ) + { + Reference< drawing::XDrawPage > xDestPage( pDrawModelWrapper->getMainDrawPage() ); + SdrPage* pDestPage = GetSdrPageFromXDrawPage( xDestPage ); + if ( pDestPage ) + { + Reference< drawing::XShape > xSelShape; + m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) ); + sal_uInt16 nCount = pModel->GetPageCount(); + for ( sal_uInt16 i = 0; i < nCount; ++i ) + { + const SdrPage* pPage = pModel->GetPage( i ); + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + while ( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + SdrObject* pNewObj = ( pObj ? pObj->Clone() : NULL ); + if ( pNewObj ) + { + pNewObj->SetModel( &pDrawModelWrapper->getSdrModel() ); + pNewObj->SetPage( pDestPage ); + + // set position + Reference< drawing::XShape > xShape( pNewObj->getUnoShape(), uno::UNO_QUERY ); + if ( xShape.is() ) + { + xShape->setPosition( awt::Point( 0, 0 ) ); + } + + pDestPage->InsertObject( pNewObj ); + m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pNewObj ) ); + xSelShape = xShape; + } + } + } + + Reference< util::XModifiable > xModifiable( m_aModel->getModel(), uno::UNO_QUERY ); + if ( xModifiable.is() ) + { + xModifiable->setModified( true ); + } - Reference< datatransfer::XTransferable > xTransferable; + // select last inserted shape + m_aSelection.setSelection( xSelShape ); + m_aSelection.applySelection( m_pDrawViewWrapper ); + + m_pDrawViewWrapper->EndUndo(); + } + } +} +void ChartController::impl_PasteStringAsTextShape( const OUString& rString, const awt::Point& rPosition ) +{ + DrawModelWrapper* pDrawModelWrapper( this->GetDrawModelWrapper() ); + if ( pDrawModelWrapper && m_pDrawViewWrapper ) { - ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); - SdrObject * pSelectedObj = 0; - if( m_pDrawViewWrapper && m_pDrawModelWrapper ) - { - if( m_aSelection.getSelectedCID().getLength() ) - pSelectedObj = m_pDrawModelWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ); - else - pSelectedObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() ); + const Reference< lang::XMultiServiceFactory >& xShapeFactory( pDrawModelWrapper->getShapeFactory() ); + const Reference< drawing::XDrawPage >& xDrawPage( pDrawModelWrapper->getMainDrawPage() ); + OSL_ASSERT( xShapeFactory.is() && xDrawPage.is() ); - if( pSelectedObj ) + if ( xShapeFactory.is() && xDrawPage.is() ) + { + try { - xTransferable = Reference< datatransfer::XTransferable >( new ChartTransferable( - & m_pDrawModelWrapper->getSdrModel(), pSelectedObj )); + Reference< drawing::XShape > xTextShape( + xShapeFactory->createInstance( C2U( "com.sun.star.drawing.TextShape" ) ), uno::UNO_QUERY_THROW ); + xDrawPage->add( xTextShape ); + + Reference< text::XTextRange > xRange( xTextShape, uno::UNO_QUERY_THROW ); + xRange->setString( rString ); + + float fCharHeight = 10.0; + Reference< beans::XPropertySet > xProperties( xTextShape, uno::UNO_QUERY_THROW ); + xProperties->setPropertyValue( C2U( "TextAutoGrowHeight" ), uno::makeAny( true ) ); + xProperties->setPropertyValue( C2U( "TextAutoGrowWidth" ), uno::makeAny( true ) ); + xProperties->setPropertyValue( C2U( "CharHeight" ), uno::makeAny( fCharHeight ) ); + xProperties->setPropertyValue( C2U( "CharHeightAsian" ), uno::makeAny( fCharHeight ) ); + xProperties->setPropertyValue( C2U( "CharHeightComplex" ), uno::makeAny( fCharHeight ) ); + xProperties->setPropertyValue( C2U( "TextVerticalAdjust" ), uno::makeAny( drawing::TextVerticalAdjust_CENTER ) ); + xProperties->setPropertyValue( C2U( "TextHorizontalAdjust" ), uno::makeAny( drawing::TextHorizontalAdjust_CENTER ) ); + xProperties->setPropertyValue( C2U( "CharFontName" ), uno::makeAny( C2U( "Albany" ) ) ); + + xTextShape->setPosition( rPosition ); + + m_aSelection.setSelection( xTextShape ); + m_aSelection.applySelection( m_pDrawViewWrapper ); + + SdrObject* pObj = DrawViewWrapper::getSdrObject( xTextShape ); + if ( pObj ) + { + m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) ); + m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pObj ) ); + m_pDrawViewWrapper->EndUndo(); + } + } + catch ( const uno::Exception& ex ) + { + ASSERT_EXCEPTION( ex ); } } } - if( xTransferable.is() ) +} + +void ChartController::executeDispatch_Copy() +{ + if ( m_pDrawViewWrapper ) { - Reference< datatransfer::clipboard::XClipboard > xClipboard( TransferableHelper::GetSystemClipboard()); - if( xClipboard.is()) - xClipboard->setContents( xTransferable, Reference< datatransfer::clipboard::XClipboardOwner >() ); + OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView(); + if ( pOutlinerView ) + { + pOutlinerView->Copy(); + } + else + { + Reference< datatransfer::XTransferable > xTransferable; + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + SdrObject* pSelectedObj = 0; + if ( m_pDrawModelWrapper ) + { + ObjectIdentifier aSelOID( m_aSelection.getSelectedOID() ); + if ( aSelOID.isAutoGeneratedObject() ) + { + pSelectedObj = m_pDrawModelWrapper->getNamedSdrObject( aSelOID.getObjectCID() ); + } + else if ( aSelOID.isAdditionalShape() ) + { + pSelectedObj = DrawViewWrapper::getSdrObject( aSelOID.getAdditionalShape() ); + } + if ( pSelectedObj ) + { + xTransferable = Reference< datatransfer::XTransferable >( new ChartTransferable( + &m_pDrawModelWrapper->getSdrModel(), pSelectedObj, aSelOID.isAdditionalShape() ) ); + } + } + } + if ( xTransferable.is() ) + { + Reference< datatransfer::clipboard::XClipboard > xClipboard( TransferableHelper::GetSystemClipboard() ); + if ( xClipboard.is() ) + { + xClipboard->setContents( xTransferable, Reference< datatransfer::clipboard::XClipboardOwner >() ); + } + } + } } } @@ -498,9 +570,10 @@ void ChartController::executeDispatch_Cut() //static bool ChartController::isObjectDeleteable( const uno::Any& rSelection ) { - OUString aSelObjCID; - if( (rSelection >>= aSelObjCID) && aSelObjCID.getLength() > 0 ) + ObjectIdentifier aSelOID( rSelection ); + if ( aSelOID.isAutoGeneratedObject() ) { + OUString aSelObjCID( aSelOID.getObjectCID() ); ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID )); if( (OBJECTTYPE_TITLE == aObjectType) || (OBJECTTYPE_LEGEND == aObjectType) || (OBJECTTYPE_DATA_SERIES == aObjectType) ) @@ -513,6 +586,22 @@ bool ChartController::isObjectDeleteable( const uno::Any& rSelection ) if( (OBJECTTYPE_DATA_LABELS == aObjectType) || (OBJECTTYPE_DATA_LABEL == aObjectType) ) return true; } + else if ( aSelOID.isAdditionalShape() ) + { + return true; + } + + return false; +} + +bool ChartController::isShapeContext() const +{ + if ( m_aSelection.isAdditionalShapeSelected() || + ( m_pDrawViewWrapper && m_pDrawViewWrapper->AreObjectsMarked() && + ( m_pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT ) ) ) + { + return true; + } return false; } @@ -779,4 +868,13 @@ void ChartController::executeDispatch_ToggleGridHorizontal() } } +void ChartController::impl_ShapeControllerDispatch( const util::URL& rURL, const Sequence< beans::PropertyValue >& rArgs ) +{ + Reference< frame::XDispatch > xDispatch( m_aDispatchContainer.getShapeController() ); + if ( xDispatch.is() ) + { + xDispatch->dispatch( rURL, rArgs ); + } +} + } // namespace chart diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx index f66352d5870b..7822c8c1cc21 100644 --- a/chart2/source/controller/main/ChartController_Window.cxx +++ b/chart2/source/controller/main/ChartController_Window.cxx @@ -55,6 +55,8 @@ #include "AxisHelper.hxx" #include "LegendHelper.hxx" #include "servicenames_charttypes.hxx" +#include "MenuResIds.hrc" +#include "DrawCommandDispatch.hxx" #include <com/sun/star/chart2/RelativePosition.hpp> #include <com/sun/star/chart2/RelativeSize.hpp> @@ -623,7 +625,10 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) if( pDrawViewWrapper->IsTextEdit() ) { - if( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX) ) + SdrViewEvent aVEvt; + if ( pDrawViewWrapper->IsTextEditHit( aMPos, HITPIX ) || + // #i12587# support for shapes in chart + ( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt ) == SDRHIT_MARKEDOBJECT ) ) { pDrawViewWrapper->MouseButtonDown(rMEvt,m_pChartWindow); return; @@ -652,6 +657,39 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) //only change selection if no selection handles are hit if( !pHitSelectionHdl ) { + // #i12587# support for shapes in chart + if ( m_eDrawMode == CHARTDRAW_INSERT && + ( !pDrawViewWrapper->IsMarkedHit( aMPos ) || !m_aSelection.isDragableObjectSelected() ) ) + { + if ( m_aSelection.hasSelection() ) + { + m_aSelection.clearSelection(); + } + if ( !pDrawViewWrapper->IsAction() ) + { + if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_CAPTION ) + { + Size aCaptionSize( 2268, 1134 ); + pDrawViewWrapper->BegCreateCaptionObj( aMPos, aCaptionSize ); + } + else + { + pDrawViewWrapper->BegCreateObj( aMPos); + } + SdrObject* pObj = pDrawViewWrapper->GetCreateObj(); + DrawCommandDispatch* pDrawCommandDispatch = m_aDispatchContainer.getDrawCommandDispatch(); + if ( pObj && m_pDrawModelWrapper && pDrawCommandDispatch ) + { + SfxItemSet aSet( m_pDrawModelWrapper->GetItemPool() ); + pDrawCommandDispatch->setAttributes( pObj ); + pDrawCommandDispatch->setLineEnds( aSet ); + pObj->SetMergedItemSet( aSet ); + } + } + impl_SetMousePointer( rMEvt ); + return; + } + m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper , rMEvt.IsRight(), m_bWaitingForDoubleClick ); @@ -754,7 +792,38 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) return; } - if(pDrawViewWrapper->IsDragObj()) + // #i12587# support for shapes in chart + if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() ) + { + pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND ); + if ( pDrawViewWrapper->AreObjectsMarked() ) + { + if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT ) + { + executeDispatch_EditText(); + } + else + { + SdrObject* pObj = pDrawViewWrapper->getSelectedObject(); + if ( pObj ) + { + uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY ); + if ( xShape.is() ) + { + m_aSelection.setSelection( xShape ); + m_aSelection.applySelection( pDrawViewWrapper ); + } + } + } + } + else + { + m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper, rMEvt.IsRight(), m_bWaitingForDoubleClick ); + m_aSelection.applySelection( pDrawViewWrapper ); + setDrawMode( CHARTDRAW_SELECT ); + } + } + else if ( pDrawViewWrapper->IsDragObj() ) { bool bDraggingDone = false; SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod(); @@ -839,7 +908,11 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured(); } else if( isDoubleClick(rMEvt) ) - execute_DoubleClick(); + { + // #i12587# support for shapes in chart + Point aMousePixel = rMEvt.GetPosPixel(); + execute_DoubleClick( &aMousePixel ); + } //@todo ForcePointer(&rMEvt); pWindow->ReleaseMouse(); @@ -854,13 +927,39 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) impl_notifySelectionChangeListeners(); } -void ChartController::execute_DoubleClick() +void ChartController::execute_DoubleClick( const Point* pMousePixel ) { - ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); - if( OBJECTTYPE_TITLE==eObjectType ) - executeDispatch_EditText(); + bool bEditText = false; + if ( m_aSelection.hasSelection() ) + { + ::rtl::OUString aCID( m_aSelection.getSelectedCID() ); + if ( aCID.getLength() ) + { + ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID ); + if ( OBJECTTYPE_TITLE == eObjectType ) + { + bEditText = true; + } + } + else + { + // #i12587# support for shapes in chart + SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() ); + if ( pObj && pObj->ISA( SdrTextObj ) ) + { + bEditText = true; + } + } + } + + if ( bEditText ) + { + executeDispatch_EditText( pMousePixel ); + } else + { executeDispatch_ObjectProperties(); + } } void ChartController::execute_Resize() @@ -907,272 +1006,288 @@ void ChartController::execute_Command( const CommandEvent& rCEvt ) if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() ) impl_notifySelectionChangeListeners(); - // todo: the context menu should be specified by an xml file in uiconfig - uno::Reference< awt::XPopupMenu > xPopupMenu( - m_xCC->getServiceManager()->createInstanceWithContext( - C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY ); - uno::Reference< awt::XMenuExtended > xMenuEx( xPopupMenu, uno::UNO_QUERY ); - if( xPopupMenu.is() && xMenuEx.is()) + if ( isShapeContext() ) + { + // #i12587# support for shapes in chart + PopupMenu aContextMenu( SchResId( m_pDrawViewWrapper->IsTextEdit() ? + RID_CONTEXTMENU_SHAPEEDIT : RID_CONTEXTMENU_SHAPE ) ); + ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame ); + Point aPos( rCEvt.GetMousePosPixel() ); + if( !rCEvt.IsMouseEvent() ) + { + aPos = m_pChartWindow->GetPointerState().maPos; + } + aContextMenuHelper.completeAndExecute( aPos, aContextMenu ); + } + else { - sal_Int16 nUniqueId = 1; - ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); - Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( m_aModel->getModel() ); + // todo: the context menu should be specified by an xml file in uiconfig + uno::Reference< awt::XPopupMenu > xPopupMenu( + m_xCC->getServiceManager()->createInstanceWithContext( + C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY ); + uno::Reference< awt::XMenuExtended > xMenuEx( xPopupMenu, uno::UNO_QUERY ); + if( xPopupMenu.is() && xMenuEx.is()) + { + sal_Int16 nUniqueId = 1; + ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); + Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( m_aModel->getModel() ); - OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, aFormatCommand ); + OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, aFormatCommand ); - //some commands for dataseries and points: - //----- - if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType ) - { - bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType ); - uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); - uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY ); - Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) ); - bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline ); - Reference< chart2::XRegressionCurve > xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt ) ); - bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries, true ); - bool bHasDataLabelsAtSeries = DataSeriesHelper::hasDataLabelsAtSeries( xSeries ); - bool bHasDataLabelsAtPoints = DataSeriesHelper::hasDataLabelsAtPoints( xSeries ); - bool bHasDataLabelAtPoint = false; - sal_Int32 nPointIndex = -1; - if( bIsPoint ) + //some commands for dataseries and points: + //----- + if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType ) { - nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() ); - bHasDataLabelAtPoint = DataSeriesHelper::hasDataLabelAtPoint( xSeries, nPointIndex ); - } - bool bSelectedPointIsFormatted = false; - bool bHasFormattedDataPointsOtherThanSelected = false; + bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType ); + uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY ); + Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) ); + bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline ); + Reference< chart2::XRegressionCurve > xMeanValue( RegressionCurveHelper::getMeanValueLine( xCurveCnt ) ); + bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries, true ); + bool bHasDataLabelsAtSeries = DataSeriesHelper::hasDataLabelsAtSeries( xSeries ); + bool bHasDataLabelsAtPoints = DataSeriesHelper::hasDataLabelsAtPoints( xSeries ); + bool bHasDataLabelAtPoint = false; + sal_Int32 nPointIndex = -1; + if( bIsPoint ) + { + nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() ); + bHasDataLabelAtPoint = DataSeriesHelper::hasDataLabelAtPoint( xSeries, nPointIndex ); + } + bool bSelectedPointIsFormatted = false; + bool bHasFormattedDataPointsOtherThanSelected = false; - Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); - if( xSeriesProperties.is() ) - { - uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; - if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) + Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); + if( xSeriesProperties.is() ) { - if( aAttributedDataPointIndexList.hasElements() ) + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { - if( bIsPoint ) + if( aAttributedDataPointIndexList.hasElements() ) { - ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) ); - ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex ); - if( aIt != aIndices.end()) - bSelectedPointIsFormatted = true; + if( bIsPoint ) + { + ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) ); + ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex ); + if( aIt != aIndices.end()) + bSelectedPointIsFormatted = true; + else + bHasFormattedDataPointsOtherThanSelected = true; + } else bHasFormattedDataPointsOtherThanSelected = true; } - else - bHasFormattedDataPointsOtherThanSelected = true; } } - } - //const sal_Int32 nIdBeforeFormat = nUniqueId; - if( bIsPoint ) - { - if( bHasDataLabelAtPoint ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabel") ); - if( !bHasDataLabelAtPoint ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabel") ); - else - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabel") ); - if( bSelectedPointIsFormatted ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetDataPoint")); - - xPopupMenu->insertSeparator( -1 ); - - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataSeries") ); - } + //const sal_Int32 nIdBeforeFormat = nUniqueId; + if( bIsPoint ) + { + if( bHasDataLabelAtPoint ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabel") ); + if( !bHasDataLabelAtPoint ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabel") ); + else + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabel") ); + if( bSelectedPointIsFormatted ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetDataPoint")); + + xPopupMenu->insertSeparator( -1 ); + + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataSeries") ); + } - Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) ); - if( xChartType->getChartType().equals(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) ) - { - try + Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) ); + if( xChartType->getChartType().equals(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) ) { - Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY ); - if( xChartTypeProp.is() ) + try { - bool bJapaneseStyle = false; - xChartTypeProp->getPropertyValue( C2U( "Japanese" ) ) >>= bJapaneseStyle; - - if( bJapaneseStyle ) + Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY ); + if( xChartTypeProp.is() ) { - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") ); + bool bJapaneseStyle = false; + xChartTypeProp->getPropertyValue( C2U( "Japanese" ) ) >>= bJapaneseStyle; + + if( bJapaneseStyle ) + { + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") ); + } } } + catch( const uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } } - catch( const uno::Exception & ex ) + + if( bHasDataLabelsAtSeries ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabels") ); + if( xTrendline.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendline") ); + if( bHasEquation ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") ); + if( xMeanValue.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMeanValue") ); + if( bHasYErrorBars ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatYErrorBars") ); + + //if( nIdBeforeFormat != nUniqueId ) + xPopupMenu->insertSeparator( -1 ); + + //const sal_Int32 nIdBeforeInsert = nUniqueId; + + if( !bHasDataLabelsAtSeries ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabels") ); + if( !xTrendline.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendline") ); + else if( !bHasEquation ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") ); + if( !xMeanValue.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMeanValue") ); + if( !bHasYErrorBars ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertYErrorBars") ); + + //if( nIdBeforeInsert != nUniqueId ) + // xPopupMenu->insertSeparator( -1 ); + + //const sal_Int32 nIdBeforeDelete = nUniqueId; + + if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabels") ); + if( xTrendline.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendline") ); + if( bHasEquation ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") ); + if( xMeanValue.is() ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMeanValue") ); + if( bHasYErrorBars ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteYErrorBars") ); + + if( bHasFormattedDataPointsOtherThanSelected ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetAllDataPoints")); + + //if( nIdBeforeDelete != nUniqueId ) + xPopupMenu->insertSeparator( -1 ); + + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId, C2U(".uno:ArrangeRow")); + uno::Reference< awt::XPopupMenu > xArrangePopupMenu( + m_xCC->getServiceManager()->createInstanceWithContext( + C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY ); + uno::Reference< awt::XMenuExtended > xArrangeMenuEx( xArrangePopupMenu, uno::UNO_QUERY ); + if( xArrangePopupMenu.is() && xArrangeMenuEx.is()) { - ASSERT_EXCEPTION( ex ); + sal_Int16 nSubId = nUniqueId + 1; + lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId++, C2U(".uno:Forward") ); + lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId, C2U(".uno:Backward") ); + xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu ); + nUniqueId = nSubId; } + ++nUniqueId; } - - if( bHasDataLabelsAtSeries ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatDataLabels") ); - if( xTrendline.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendline") ); - if( bHasEquation ) + else if( OBJECTTYPE_DATA_CURVE == eObjectType ) + { lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") ); - if( xMeanValue.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMeanValue") ); - if( bHasYErrorBars ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatYErrorBars") ); - - //if( nIdBeforeFormat != nUniqueId ) - xPopupMenu->insertSeparator( -1 ); - - //const sal_Int32 nIdBeforeInsert = nUniqueId; - - if( !bHasDataLabelsAtSeries ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertDataLabels") ); - if( !xTrendline.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendline") ); - else if( !bHasEquation ) lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") ); - if( !xMeanValue.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMeanValue") ); - if( !bHasYErrorBars ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertYErrorBars") ); - - //if( nIdBeforeInsert != nUniqueId ) - // xPopupMenu->insertSeparator( -1 ); - - //const sal_Int32 nIdBeforeDelete = nUniqueId; - - if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteDataLabels") ); - if( xTrendline.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendline") ); - if( bHasEquation ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") ); lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") ); - if( xMeanValue.is() ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMeanValue") ); - if( bHasYErrorBars ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteYErrorBars") ); - - if( bHasFormattedDataPointsOtherThanSelected ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:ResetAllDataPoints")); - - //if( nIdBeforeDelete != nUniqueId ) - xPopupMenu->insertSeparator( -1 ); - - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId, C2U(".uno:ArrangeRow")); - uno::Reference< awt::XPopupMenu > xArrangePopupMenu( - m_xCC->getServiceManager()->createInstanceWithContext( - C2U("com.sun.star.awt.PopupMenu"), m_xCC ), uno::UNO_QUERY ); - uno::Reference< awt::XMenuExtended > xArrangeMenuEx( xArrangePopupMenu, uno::UNO_QUERY ); - if( xArrangePopupMenu.is() && xArrangeMenuEx.is()) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") ); + } + else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType ) { - sal_Int16 nSubId = nUniqueId + 1; - lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId++, C2U(".uno:Forward") ); - lcl_insertMenuCommand( xArrangePopupMenu, xArrangeMenuEx, nSubId, C2U(".uno:Backward") ); - xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu ); - nUniqueId = nSubId; + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") ); } - ++nUniqueId; - } - else if( OBJECTTYPE_DATA_CURVE == eObjectType ) - { - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatTrendlineEquation") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquation") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTrendlineEquationAndR2") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteTrendlineEquation") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") ); - } - else if( OBJECTTYPE_DATA_CURVE_EQUATION == eObjectType ) - { - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertR2Value") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteR2Value") ); - } - //some commands for axes: and grids - //----- - else if( OBJECTTYPE_AXIS == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType ) - { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); - if( xAxis.is() && xDiagram.is() ) + //some commands for axes: and grids + //----- + else if( OBJECTTYPE_AXIS == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType ) { - sal_Int32 nDimensionIndex = -1; - sal_Int32 nCooSysIndex = -1; - sal_Int32 nAxisIndex = -1; - AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ); - bool bIsSecondaryAxis = nAxisIndex!=0; - bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis ); - bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram ); - bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram ); - bool bHasTitle = false; - uno::Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY ); - if( xTitled.is()) - bHasTitle = TitleHelper::getCompleteString( xTitled->getTitleObject() ).getLength()>0; - - if( OBJECTTYPE_AXIS != eObjectType && bIsAxisVisible ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatAxis") ); - if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMajorGrid") ); - if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMinorGrid") ); - - xPopupMenu->insertSeparator( -1 ); - - if( OBJECTTYPE_AXIS != eObjectType && !bIsAxisVisible ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxis") ); - if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMajorGrid") ); - if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMinorGrid") ); - if( !bHasTitle ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxisTitle") ); - - if( bIsAxisVisible ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteAxis") ); - if( bIsMajorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMajorGrid") ); - if( bIsMinorGridVisible && !bIsSecondaryAxis ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMinorGrid") ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + if( xAxis.is() && xDiagram.is() ) + { + sal_Int32 nDimensionIndex = -1; + sal_Int32 nCooSysIndex = -1; + sal_Int32 nAxisIndex = -1; + AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ); + bool bIsSecondaryAxis = nAxisIndex!=0; + bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis ); + bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram ); + bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram ); + bool bHasTitle = false; + uno::Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY ); + if( xTitled.is()) + bHasTitle = TitleHelper::getCompleteString( xTitled->getTitleObject() ).getLength()>0; + + if( OBJECTTYPE_AXIS != eObjectType && bIsAxisVisible ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatAxis") ); + if( OBJECTTYPE_GRID != eObjectType && bIsMajorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMajorGrid") ); + if( OBJECTTYPE_SUBGRID != eObjectType && bIsMinorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatMinorGrid") ); + + xPopupMenu->insertSeparator( -1 ); + + if( OBJECTTYPE_AXIS != eObjectType && !bIsAxisVisible ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxis") ); + if( OBJECTTYPE_GRID != eObjectType && !bIsMajorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMajorGrid") ); + if( OBJECTTYPE_SUBGRID != eObjectType && !bIsMinorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertMinorGrid") ); + if( !bHasTitle ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertAxisTitle") ); + + if( bIsAxisVisible ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteAxis") ); + if( bIsMajorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMajorGrid") ); + if( bIsMinorGridVisible && !bIsSecondaryAxis ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteMinorGrid") ); + } } - } - if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") ); - else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") ); + if( OBJECTTYPE_DATA_STOCK_LOSS == eObjectType ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockGain") ); + else if( OBJECTTYPE_DATA_STOCK_GAIN == eObjectType ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:FormatStockLoss") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:TransformDialog")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:TransformDialog")); - if( OBJECTTYPE_PAGE == eObjectType || OBJECTTYPE_DIAGRAM == eObjectType - || OBJECTTYPE_DIAGRAM_WALL == eObjectType - || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType - || OBJECTTYPE_UNKNOWN == eObjectType ) - { - if( OBJECTTYPE_UNKNOWN != eObjectType ) - xPopupMenu->insertSeparator( -1 ); - bool bHasLegend = LegendHelper::hasLegend( xDiagram ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTitles") ); - if( !bHasLegend ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertLegend") ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertRemoveAxes") ); - if( bHasLegend ) - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteLegend") ); + if( OBJECTTYPE_PAGE == eObjectType || OBJECTTYPE_DIAGRAM == eObjectType + || OBJECTTYPE_DIAGRAM_WALL == eObjectType + || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType + || OBJECTTYPE_UNKNOWN == eObjectType ) + { + if( OBJECTTYPE_UNKNOWN != eObjectType ) + xPopupMenu->insertSeparator( -1 ); + bool bHasLegend = LegendHelper::hasLegend( xDiagram ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertTitles") ); + if( !bHasLegend ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertLegend") ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:InsertRemoveAxes") ); + if( bHasLegend ) + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DeleteLegend") ); + } + //----- + + xPopupMenu->insertSeparator( -1 ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramType")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DataRanges")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramData")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:View3D")); + xPopupMenu->insertSeparator( -1 ); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Cut")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Copy")); + lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Paste")); + + ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame ); + Point aPos( rCEvt.GetMousePosPixel() ); + if( !rCEvt.IsMouseEvent() ) + aPos = m_pChartWindow->GetPointerState().maPos; + aContextMenuHelper.completeAndExecute( aPos, xPopupMenu ); } - //----- - - xPopupMenu->insertSeparator( -1 ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramType")); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DataRanges")); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:DiagramData")); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:View3D")); - xPopupMenu->insertSeparator( -1 ); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Cut")); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Copy")); - lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, C2U(".uno:Paste")); - - ::svt::ContextMenuHelper aContextMenuHelper( m_xFrame ); - Point aPos( rCEvt.GetMousePosPixel() ); - if( !rCEvt.IsMouseEvent() ) - aPos = m_pChartWindow->GetPointerState().maPos; - aContextMenuHelper.completeAndExecute( aPos, xPopupMenu ); } } else if( ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT ) || @@ -1235,17 +1350,21 @@ bool ChartController::execute_KeyInput( const KeyEvent& rKEvt ) { // Natvigation (Tab/F3/Home/End) uno::Reference< XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); - ObjectKeyNavigation aObjNav( m_aSelection.getSelectedCID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView )); + ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView )); awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode )); bReturn = aObjNav.handleKeyEvent( aKeyEvent ); if( bReturn ) { - ::rtl::OUString aNewCID = aObjNav.getCurrentSelection(); + ObjectIdentifier aNewOID = aObjNav.getCurrentSelection(); uno::Any aNewSelection; - if( aNewCID.getLength()>0 && !ObjectHierarchy::isRootNode( aNewCID )) - aNewSelection <<= aNewCID; - if( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewCID, m_aModel->getModel() ) ) + if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) ) + { + aNewSelection = aNewOID.getAny(); + } + if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), m_aModel->getModel() ) ) + { m_eDragMode = SDRDRAG_MOVE; + } bReturn = select( aNewSelection ); } } @@ -1498,24 +1617,64 @@ bool ChartController::requestQuickHelp( ::select( const uno::Any& rSelection ) throw( lang::IllegalArgumentException ) { - rtl::OUString aNewCID; - if( rSelection.hasValue() && - ! (rSelection >>= aNewCID)) - return sal_False; + bool bSuccess = false; + if ( rSelection.hasValue() ) + { + const uno::Type& rType = rSelection.getValueType(); + if ( rType == ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) ) ) + { + ::rtl::OUString aNewCID; + if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) ) + { + bSuccess = true; + } + } + else if ( rType == ::getCppuType( static_cast< const uno::Reference< drawing::XShape >* >( 0 ) ) ) + { + uno::Reference< drawing::XShape > xShape; + if ( ( rSelection >>= xShape ) && m_aSelection.setSelection( xShape ) ) + { + bSuccess = true; + } + } + } + else + { + if ( m_aSelection.hasSelection() ) + { + m_aSelection.clearSelection(); + bSuccess = true; + } + } - if( m_aSelection.setSelection( aNewCID ) ) + if ( bSuccess ) { this->impl_selectObjectAndNotiy(); return sal_True; } + return sal_False; } uno::Any SAL_CALL ChartController ::getSelection() throw(uno::RuntimeException) { - return uno::makeAny(m_aSelection.getSelectedCID()); + uno::Any aReturn; + if ( m_aSelection.hasSelection() ) + { + ::rtl::OUString aCID( m_aSelection.getSelectedCID() ); + if ( aCID.getLength() ) + { + aReturn = uno::makeAny( aCID ); + } + else + { + // #i12587# support for shapes in chart + aReturn = uno::makeAny( m_aSelection.getSelectedAdditionalShape() ); + } + } + return aReturn; } void SAL_CALL ChartController @@ -1701,7 +1860,7 @@ void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) sal_uInt16 nModifier = rEvent.GetModifier(); BOOL bLeftDown = rEvent.IsLeft(); - if( m_pDrawViewWrapper->IsTextEdit() ) + if ( m_pDrawViewWrapper->IsTextEdit() ) { if( m_pDrawViewWrapper->IsTextEditHit( aMousePos, HITPIX) ) { @@ -1726,7 +1885,7 @@ void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) aMousePos, pWindow, nModifier, bLeftDown ); bool bForceArrowPointer = false; - ::rtl::OUString aObjectCID = m_aSelection.getSelectedCID(); + ObjectIdentifier aOID( m_aSelection.getSelectedOID() ); switch( aPointer.GetStyle()) { @@ -1742,7 +1901,7 @@ void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) bForceArrowPointer = true; break; case POINTER_MOVE: - if( ! ObjectIdentifier::isDragableObject( aObjectCID )) + if ( !aOID.isDragableObject() ) bForceArrowPointer = true; break; case POINTER_MOVEPOINT: @@ -1762,6 +1921,55 @@ void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) } else { + // #i12587# support for shapes in chart + if ( m_eDrawMode == CHARTDRAW_INSERT && + ( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) ) + { + PointerStyle ePointerStyle = POINTER_DRAW_RECT; + SdrObjKind eKind = static_cast< SdrObjKind >( m_pDrawViewWrapper->GetCurrentObjIdentifier() ); + switch ( eKind ) + { + case OBJ_LINE: + { + ePointerStyle = POINTER_DRAW_LINE; + } + break; + case OBJ_RECT: + case OBJ_CUSTOMSHAPE: + { + ePointerStyle = POINTER_DRAW_RECT; + } + break; + case OBJ_CIRC: + { + ePointerStyle = POINTER_DRAW_ELLIPSE; + } + break; + case OBJ_FREELINE: + { + ePointerStyle = POINTER_DRAW_POLYGON; + } + break; + case OBJ_TEXT: + { + ePointerStyle = POINTER_DRAW_TEXT; + } + break; + case OBJ_CAPTION: + { + ePointerStyle = POINTER_DRAW_CAPTION; + } + break; + default: + { + ePointerStyle = POINTER_DRAW_RECT; + } + break; + } + pWindow->SetPointer( Pointer( ePointerStyle ) ); + return; + } + ::rtl::OUString aHitObjectCID( SelectionHelper::getHitObjectCID( aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ )); diff --git a/chart2/source/controller/main/ChartTransferable.cxx b/chart2/source/controller/main/ChartTransferable.cxx index d64f163f634c..80041d4c3818 100644 --- a/chart2/source/controller/main/ChartTransferable.cxx +++ b/chart2/source/controller/main/ChartTransferable.cxx @@ -30,12 +30,21 @@ #include "ChartTransferable.hxx" +#include <unotools/streamwrap.hxx> #include <vcl/graph.hxx> +#include <svl/itempool.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <svx/svditer.hxx> #include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <svx/unomodel.hxx> // header for class SdrView #include <svx/svdview.hxx> +#define CHARTTRANSFER_OBJECTTYPE_DRAWMODEL 1 + using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; @@ -45,7 +54,9 @@ using ::rtl::OUString; namespace chart { -ChartTransferable::ChartTransferable( SdrModel * pDrawModel, SdrObject * pSelectedObj ) +ChartTransferable::ChartTransferable( SdrModel* pDrawModel, SdrObject* pSelectedObj, bool bDrawing ) + :m_pMarkedObjModel( NULL ) + ,m_bDrawing( bDrawing ) { SdrExchangeView * pExchgView( new SdrView( pDrawModel )); SdrPageView* pPv = pExchgView->ShowSdrPage( pDrawModel->GetPage( 0 )); @@ -55,6 +66,10 @@ ChartTransferable::ChartTransferable( SdrModel * pDrawModel, SdrObject * pSelect pExchgView->MarkAllObj( pPv ); Graphic aGraphic( pExchgView->GetMarkedObjMetaFile( TRUE )); m_xMetaFileGraphic.set( aGraphic.GetXGraphic()); + if ( m_bDrawing ) + { + m_pMarkedObjModel = ( pExchgView ? pExchgView->GetAllMarkedModel() : NULL ); + } delete pExchgView; } @@ -63,6 +78,10 @@ ChartTransferable::~ChartTransferable() void ChartTransferable::AddSupportedFormats() { + if ( m_bDrawing ) + { + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + } AddFormat( SOT_FORMAT_GDIMETAFILE ); AddFormat( SOT_FORMAT_BITMAP ); } @@ -74,7 +93,11 @@ sal_Bool ChartTransferable::GetData( const ::com::sun::star::datatransfer::DataF if( HasFormat( nFormat )) { - if( nFormat == FORMAT_GDIMETAFILE ) + if ( nFormat == SOT_FORMATSTR_ID_DRAWING ) + { + bResult = SetObject( m_pMarkedObjModel, CHARTTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor ); + } + else if ( nFormat == FORMAT_GDIMETAFILE ) { Graphic aGraphic( m_xMetaFileGraphic ); bResult = SetGDIMetaFile( aGraphic.GetGDIMetaFile(), rFlavor ); @@ -89,5 +112,61 @@ sal_Bool ChartTransferable::GetData( const ::com::sun::star::datatransfer::DataF return bResult; } +sal_Bool ChartTransferable::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, + const datatransfer::DataFlavor& /* rFlavor */ ) +{ + // called from SetObject, put data into stream + + sal_Bool bRet = sal_False; + switch ( nUserObjectId ) + { + case CHARTTRANSFER_OBJECTTYPE_DRAWMODEL: + { + SdrModel* pMarkedObjModel = reinterpret_cast< SdrModel* >( pUserObject ); + if ( pMarkedObjModel ) + { + rxOStm->SetBufferSize( 0xff00 ); + + // #108584# + // for the changed pool defaults from drawing layer pool set those + // attributes as hard attributes to preserve them for saving + const SfxItemPool& rItemPool = pMarkedObjModel->GetItemPool(); + const SvxFontHeightItem& rDefaultFontHeight = static_cast< const SvxFontHeightItem& >( + rItemPool.GetDefaultItem( EE_CHAR_FONTHEIGHT ) ); + sal_uInt16 nCount = pMarkedObjModel->GetPageCount(); + for ( sal_uInt16 i = 0; i < nCount; ++i ) + { + const SdrPage* pPage = pMarkedObjModel->GetPage( i ); + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + while ( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + const SvxFontHeightItem& rItem = static_cast< const SvxFontHeightItem& >( + pObj->GetMergedItem( EE_CHAR_FONTHEIGHT ) ); + if ( rItem.GetHeight() == rDefaultFontHeight.GetHeight() ) + { + pObj->SetMergedItem( rDefaultFontHeight ); + } + } + } + + Reference< io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) ); + if ( SvxDrawingLayerExport( pMarkedObjModel, xDocOut ) ) + { + rxOStm->Commit(); + } + + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + } + break; + default: + { + DBG_ERROR( "ChartTransferable::WriteObject: unknown object id" ); + } + break; + } + return bRet; +} } // namespace chart diff --git a/chart2/source/controller/main/ChartTransferable.hxx b/chart2/source/controller/main/ChartTransferable.hxx index 2ce4e811d809..401f43c6d1ae 100644 --- a/chart2/source/controller/main/ChartTransferable.hxx +++ b/chart2/source/controller/main/ChartTransferable.hxx @@ -44,7 +44,7 @@ namespace chart class ChartTransferable : public TransferableHelper { public: - explicit ChartTransferable( SdrModel * pDrawModel, SdrObject * pSelectedObj ); + explicit ChartTransferable( SdrModel* pDrawModel, SdrObject* pSelectedObj, bool bDrawing = false ); virtual ~ChartTransferable(); protected: @@ -52,9 +52,13 @@ protected: // implementation of TransferableHelper methods virtual void AddSupportedFormats(); virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); + virtual sal_Bool WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, + const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); private: ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > m_xMetaFileGraphic; + SdrModel* m_pMarkedObjModel; + bool m_bDrawing; }; } // namespace chart diff --git a/chart2/source/controller/main/CommandDispatchContainer.cxx b/chart2/source/controller/main/CommandDispatchContainer.cxx index 09da97b45014..3761d0c33ce0 100644 --- a/chart2/source/controller/main/CommandDispatchContainer.cxx +++ b/chart2/source/controller/main/CommandDispatchContainer.cxx @@ -33,6 +33,9 @@ #include "StatusBarCommandDispatch.hxx" #include "DisposeHelper.hxx" #include "macros.hxx" +#include "ChartController.hxx" +#include "DrawCommandDispatch.hxx" +#include "ShapeController.hxx" #include <comphelper/InlineContainer.hxx> @@ -48,8 +51,11 @@ namespace chart { CommandDispatchContainer::CommandDispatchContainer( - const Reference< uno::XComponentContext > & xContext ) : - m_xContext( xContext ) + const Reference< uno::XComponentContext > & xContext, ChartController* pController ) + :m_xContext( xContext ) + ,m_pChartController( pController ) + ,m_pDrawCommandDispatch( NULL ) + ,m_pShapeController( NULL ) { m_aContainerDocumentCommands = ::comphelper::MakeSet< OUString > @@ -75,21 +81,20 @@ void CommandDispatchContainer::setModel( // m_xUndoManager = xUndoManager; // } -void CommandDispatchContainer::setFallbackDispatch( - const Reference< frame::XDispatch > xFallbackDispatch, - const ::std::set< OUString > & rFallbackCommands ) +void CommandDispatchContainer::setChartDispatch( + const Reference< frame::XDispatch > xChartDispatch, + const ::std::set< OUString > & rChartCommands ) { - OSL_ENSURE(xFallbackDispatch.is(),"Invalid fall back dispatcher!"); - m_xFallbackDispatcher.set( xFallbackDispatch ); - m_aFallbackCommands = rFallbackCommands; - m_aToBeDisposedDispatches.push_back( m_xFallbackDispatcher ); + OSL_ENSURE(xChartDispatch.is(),"Invalid fall back dispatcher!"); + m_xChartDispatcher.set( xChartDispatch ); + m_aChartCommands = rChartCommands; + m_aToBeDisposedDispatches.push_back( m_xChartDispatcher ); } Reference< frame::XDispatch > CommandDispatchContainer::getDispatchForURL( const util::URL & rURL ) { Reference< frame::XDispatch > xResult; - tDispatchMap::const_iterator aIt( m_aCachedDispatches.find( rURL.Complete )); if( aIt != m_aCachedDispatches.end()) { @@ -127,10 +132,24 @@ Reference< frame::XDispatch > CommandDispatchContainer::getDispatchForURL( // ToDo: can those dispatches be cached? m_aCachedDispatches[ rURL.Complete ].set( xResult ); } - else if( m_xFallbackDispatcher.is() && - (m_aFallbackCommands.find( rURL.Path ) != m_aFallbackCommands.end()) ) + else if( m_xChartDispatcher.is() && + (m_aChartCommands.find( rURL.Path ) != m_aChartCommands.end()) ) + { + xResult.set( m_xChartDispatcher ); + m_aCachedDispatches[ rURL.Complete ].set( xResult ); + } + // #i12587# support for shapes in chart + // Note, that the chart dispatcher must be queried first, because + // the chart dispatcher is the default dispatcher for all context + // sensitive commands. + else if ( m_pDrawCommandDispatch && m_pDrawCommandDispatch->isFeatureSupported( rURL.Complete ) ) + { + xResult.set( m_pDrawCommandDispatch ); + m_aCachedDispatches[ rURL.Complete ].set( xResult ); + } + else if ( m_pShapeController && m_pShapeController->isFeatureSupported( rURL.Complete ) ) { - xResult.set( m_xFallbackDispatcher ); + xResult.set( m_pShapeController ); m_aCachedDispatches[ rURL.Complete ].set( xResult ); } } @@ -157,8 +176,11 @@ void CommandDispatchContainer::DisposeAndClear() m_aCachedDispatches.clear(); DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches ); m_aToBeDisposedDispatches.clear(); - m_xFallbackDispatcher.clear(); - m_aFallbackCommands.clear(); + m_xChartDispatcher.clear(); + m_aChartCommands.clear(); + m_pChartController = NULL; + m_pDrawCommandDispatch = NULL; + m_pShapeController = NULL; } Reference< frame::XDispatch > CommandDispatchContainer::getContainerDispatchForURL( @@ -179,4 +201,16 @@ Reference< frame::XDispatch > CommandDispatchContainer::getContainerDispatchForU return xResult; } +void CommandDispatchContainer::setDrawCommandDispatch( DrawCommandDispatch* pDispatch ) +{ + m_pDrawCommandDispatch = pDispatch; + m_aToBeDisposedDispatches.push_back( Reference< frame::XDispatch >( pDispatch ) ); +} + +void CommandDispatchContainer::setShapeController( ShapeController* pController ) +{ + m_pShapeController = pController; + m_aToBeDisposedDispatches.push_back( Reference< frame::XDispatch >( pController ) ); +} + } // namespace chart diff --git a/chart2/source/controller/main/CommandDispatchContainer.hxx b/chart2/source/controller/main/CommandDispatchContainer.hxx index 379e86481db1..2cee65405ef4 100644 --- a/chart2/source/controller/main/CommandDispatchContainer.hxx +++ b/chart2/source/controller/main/CommandDispatchContainer.hxx @@ -41,6 +41,10 @@ namespace chart { +class ChartController; +class DrawCommandDispatch; +class ShapeController; + /** @HTML Helper class for implementing the <code>XDispatchProvider</code> interface @@ -53,9 +57,9 @@ namespace chart <li>Check if the command is handled by this class, e.g. Undo. If so, return a corresponding <code>XDispatch</code> implementation, and cache this implementation for later use</li> - <li>Otherwise send the command to the fallback dispatch provider, if it + <li>Otherwise send the command to the chart dispatch provider, if it can handle this dispatch (determined by the list of commands given in - <code>setFallbackDispatch()</code>).</li> + <code>setChartDispatch()</code>).</li> </ul> <p>The <code>XDispatch</code>Provider is designed to return different @@ -65,17 +69,18 @@ namespace chart <p>As most commands need much information of the controller and are implemented there, the controller handles most of the commands itself (it also implements <code>XDispatch</code>). Therefore it is set here as - fallback dispatch.</p> + chart dispatch.</p> */ class CommandDispatchContainer { public: - // note: the fallback dispatcher should be removed when all commands are - // handled by other dispatchers. (Fallback is currently the controller + // note: the chart dispatcher should be removed when all commands are + // handled by other dispatchers. (Chart is currently the controller // itself) explicit CommandDispatchContainer( const ::com::sun::star::uno::Reference< - ::com::sun::star::uno::XComponentContext > & xContext ); + ::com::sun::star::uno::XComponentContext > & xContext, + ChartController* pController ); void setModel( const ::com::sun::star::uno::Reference< @@ -84,18 +89,18 @@ public: // const ::com::sun::star::uno::Reference< // ::com::sun::star::chart2::XUndoManager > & xUndoManager ); - /** Set a fallback dispatcher that is used for all commands contained in - rFallbackCommands + /** Set a chart dispatcher that is used for all commands contained in + rChartCommands */ - void setFallbackDispatch( + void setChartDispatch( const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XDispatch > xFallbackDispatch, - const ::std::set< ::rtl::OUString > & rFallbackCommands ); + ::com::sun::star::frame::XDispatch > xChartDispatch, + const ::std::set< ::rtl::OUString > & rChartCommands ); /** Returns the dispatch that is able to do the command given in rURL, if implemented here. If the URL is not implemented here, it should be - checked whether the command is one of the commands given as fallback via - the setFallbackDispatch() method. If so, call the fallback dispatch. + checked whether the command is one of the commands given via + the setChartDispatch() method. If so, call the chart dispatch. <p>If all this fails, return an empty dispatch.</p> */ @@ -116,6 +121,11 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > & xChartController, const ::com::sun::star::util::URL & rURL ); + void setDrawCommandDispatch( DrawCommandDispatch* pDispatch ); + DrawCommandDispatch* getDrawCommandDispatch() { return m_pDrawCommandDispatch; } + void setShapeController( ShapeController* pController ); + ShapeController* getShapeController() { return m_pShapeController; } + private: typedef ::std::map< ::rtl::OUString, @@ -133,10 +143,14 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xModel; ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XUndoManager > m_xUndoManager; - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > m_xFallbackDispatcher; - ::std::set< ::rtl::OUString > m_aFallbackCommands; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > m_xChartDispatcher; + ::std::set< ::rtl::OUString > m_aChartCommands; ::std::set< ::rtl::OUString > m_aContainerDocumentCommands; + + ChartController* m_pChartController; + DrawCommandDispatch* m_pDrawCommandDispatch; + ShapeController* m_pShapeController; }; } // namespace chart diff --git a/chart2/source/controller/main/ControllerCommandDispatch.cxx b/chart2/source/controller/main/ControllerCommandDispatch.cxx index 5fc58307b7a0..2652aadfdb32 100644 --- a/chart2/source/controller/main/ControllerCommandDispatch.cxx +++ b/chart2/source/controller/main/ControllerCommandDispatch.cxx @@ -42,6 +42,7 @@ #include "RegressionCurveHelper.hxx" #include "DataSeriesHelper.hxx" #include "StatisticsHelper.hxx" +#include "ShapeController.hxx" #include <com/sun/star/util/XModifyBroadcaster.hpp> #include <com/sun/star/frame/XStorable.hpp> @@ -178,22 +179,22 @@ void ControllerState::update( Reference< view::XSelectionSupplier > xSelectionSupplier( xController, uno::UNO_QUERY ); - OUString aSelObjCID; - // Update ControllerState variables. if( xSelectionSupplier.is()) { uno::Any aSelObj( xSelectionSupplier->getSelection() ); + ObjectIdentifier aSelOID( aSelObj ); + OUString aSelObjCID( aSelOID.getObjectCID() ); - bHasSelectedObject = ((aSelObj >>= aSelObjCID) && aSelObjCID.getLength() > 0); + bHasSelectedObject = aSelOID.isValid(); ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID )); - bIsPositionableObject = (OBJECTTYPE_DATA_POINT != aObjectType) && ObjectIdentifier::isDragableObject( aSelObjCID ); + bIsPositionableObject = (OBJECTTYPE_DATA_POINT != aObjectType) && aSelOID.isDragableObject(); bIsTextObject = OBJECTTYPE_TITLE == aObjectType; uno::Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel )); - bIsFormateableObjectSelected = bHasSelectedObject; + bIsFormateableObjectSelected = bHasSelectedObject && aSelOID.isAutoGeneratedObject(); if( OBJECTTYPE_DIAGRAM==aObjectType || OBJECTTYPE_DIAGRAM_WALL==aObjectType || OBJECTTYPE_DIAGRAM_FLOOR==aObjectType ) bIsFormateableObjectSelected = DiagramHelper::isSupportingFloorAndWall( xDiagram ); @@ -457,13 +458,15 @@ DBG_NAME(ControllerCommandDispatch) ControllerCommandDispatch::ControllerCommandDispatch( const Reference< uno::XComponentContext > & xContext, - const Reference< frame::XController > & xController ) : + ChartController* pController, CommandDispatchContainer* pContainer ) : impl::ControllerCommandDispatch_Base( xContext ), - m_xController( xController ), - m_xSelectionSupplier( xController, uno::UNO_QUERY ), - m_xDispatch( xController, uno::UNO_QUERY ), + m_pChartController( pController ), + m_xController( Reference< frame::XController >( pController ) ), + m_xSelectionSupplier( Reference< view::XSelectionSupplier >( pController ) ), + m_xDispatch( Reference< frame::XDispatch >( pController ) ), m_apModelState( new impl::ModelState() ), - m_apControllerState( new impl::ControllerState() ) + m_apControllerState( new impl::ControllerState() ), + m_pDispatchContainer( pContainer ) { DBG_CTOR(ControllerCommandDispatch,NULL); } @@ -523,6 +526,8 @@ void ControllerCommandDispatch::updateCommandAvailability() // @todo: determine correctly bool bHasSuitableClipboardContent = true; + bool bShapeContext = ( m_pChartController ? m_pChartController->isShapeContext() : false ); + // edit commands m_aCommandAvailability[ C2U(".uno:Cut")] = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsDeleteableObjectSelected; m_aCommandAvailability[ C2U(".uno:Copy")] = bControllerStateIsValid && m_apControllerState->bHasSelectedObject; @@ -540,7 +545,8 @@ void ControllerCommandDispatch::updateCommandAvailability() m_aCommandAvailability[ C2U(".uno:DefaultColors")] = bIsWritable; m_aCommandAvailability[ C2U(".uno:BarWidth")] = bIsWritable; m_aCommandAvailability[ C2U(".uno:NumberOfLines")] = bIsWritable; - m_aCommandAvailability[ C2U(".uno:ArrangeRow")] = m_apControllerState->bMayMoveSeriesForward || m_apControllerState->bMayMoveSeriesBackward; + m_aCommandAvailability[ C2U(".uno:ArrangeRow")] = + bShapeContext || ( bIsWritable && bControllerStateIsValid && ( m_apControllerState->bMayMoveSeriesForward || m_apControllerState->bMayMoveSeriesBackward ) ); // insert objects m_aCommandAvailability[ C2U(".uno:InsertTitles")] = m_aCommandAvailability[ C2U(".uno:InsertMenuTitles")] = bIsWritable; @@ -574,6 +580,7 @@ void ControllerCommandDispatch::updateCommandAvailability() m_aCommandAvailability[ C2U(".uno:Legend")] = bIsWritable && m_apModelState->bHasLegend; m_aCommandAvailability[ C2U(".uno:DiagramWall")] = bIsWritable && bModelStateIsValid && m_apModelState->bHasWall; m_aCommandAvailability[ C2U(".uno:DiagramArea")] = bIsWritable; + m_aCommandAvailability[ C2U(".uno:TransformDialog")] = bIsWritable && bControllerStateIsValid && m_apControllerState->bHasSelectedObject && m_apControllerState->bIsPositionableObject; // 3d commands @@ -623,8 +630,10 @@ void ControllerCommandDispatch::updateCommandAvailability() m_aCommandAvailability[ C2U(".uno:DiagramGridAll")] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyGrid(); // series arrangement - m_aCommandAvailability[ C2U(".uno:Forward")] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward; - m_aCommandAvailability[ C2U(".uno:Backward")] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward; + m_aCommandAvailability[ C2U(".uno:Forward")] = ( bShapeContext ? isShapeControllerCommandAvailable( C2U( ".uno:Forward" ) ) : + ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward ) ); + m_aCommandAvailability[ C2U(".uno:Backward")] = ( bShapeContext ? isShapeControllerCommandAvailable( C2U( ".uno:Backward" ) ) : + ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward ) ); m_aCommandAvailability[ C2U(".uno:InsertDataLabels")] = bIsWritable; m_aCommandAvailability[ C2U(".uno:InsertDataLabel")] = bIsWritable; @@ -667,6 +676,17 @@ bool ControllerCommandDispatch::commandAvailable( const OUString & rCommand ) return false; } +bool ControllerCommandDispatch::isShapeControllerCommandAvailable( const ::rtl::OUString& rCommand ) +{ + ShapeController* pShapeController = ( m_pDispatchContainer ? m_pDispatchContainer->getShapeController() : NULL ); + if ( pShapeController ) + { + FeatureState aState( pShapeController->getState( rCommand ) ); + return aState.bEnabled; + } + return false; +} + void ControllerCommandDispatch::fireStatusEvent( const OUString & rURL, const Reference< frame::XStatusListener > & xSingleListener /* = 0 */ ) diff --git a/chart2/source/controller/main/ControllerCommandDispatch.hxx b/chart2/source/controller/main/ControllerCommandDispatch.hxx index a37d8b059b57..08d57a0d6cbf 100644 --- a/chart2/source/controller/main/ControllerCommandDispatch.hxx +++ b/chart2/source/controller/main/ControllerCommandDispatch.hxx @@ -38,6 +38,9 @@ namespace chart { +class ChartController; +class CommandDispatchContainer; + namespace impl { struct ModelState; @@ -64,8 +67,7 @@ public: explicit ControllerCommandDispatch( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext, - const ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XController > & xController ); + ChartController* pController, CommandDispatchContainer* pContainer ); virtual ~ControllerCommandDispatch(); // late initialisation, especially for adding as listener @@ -109,6 +111,9 @@ private: bool commandAvailable( const ::rtl::OUString & rCommand ); void updateCommandAvailability(); + bool isShapeControllerCommandAvailable( const ::rtl::OUString& rCommand ); + + ChartController* m_pChartController; ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > m_xController; ::com::sun::star::uno::Reference< @@ -121,6 +126,8 @@ private: mutable ::std::map< ::rtl::OUString, bool > m_aCommandAvailability; mutable ::std::map< ::rtl::OUString, ::com::sun::star::uno::Any > m_aCommandArguments; + + CommandDispatchContainer* m_pDispatchContainer; }; } // namespace chart diff --git a/chart2/source/controller/main/DrawCommandDispatch.cxx b/chart2/source/controller/main/DrawCommandDispatch.cxx new file mode 100644 index 000000000000..aa28028c4861 --- /dev/null +++ b/chart2/source/controller/main/DrawCommandDispatch.cxx @@ -0,0 +1,674 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "DrawCommandDispatch.hxx" +#include "DrawCommandDispatch.hrc" +#include "ChartController.hxx" +#include "DrawViewWrapper.hxx" +#include "chartview/DrawModelWrapper.hxx" +#include "macros.hxx" + +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <svl/itempool.hxx> +#include <editeng/adjitem.hxx> +#include <svx/dialogs.hrc> +#include <svx/dialmgr.hxx> +#include <svx/fmmodel.hxx> +#include <svx/gallery.hxx> +#include <svx/svdoashp.hxx> +#include <svx/svdocapt.hxx> +#include <svx/svdopath.hxx> +#include <svx/svdpage.hxx> +#include <svx/unoapi.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnedwit.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xtable.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +#include <boost/bind.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::frame; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + + +//............................................................................. +namespace +{ +//............................................................................. + + // comparing two PropertyValue instances + struct PropertyValueCompare : public ::std::binary_function< beans::PropertyValue, ::rtl::OUString, bool > + { + bool operator() ( const beans::PropertyValue& rPropValue, const ::rtl::OUString& rName ) const + { + return rPropValue.Name.equals( rName ); + } + bool operator() ( const ::rtl::OUString& rName, const beans::PropertyValue& rPropValue ) const + { + return rName.equals( rPropValue.Name ); + } + }; + +//............................................................................. +} // anonymous namespace +//............................................................................. + + +//............................................................................. +namespace chart +{ +//............................................................................. + +DrawCommandDispatch::DrawCommandDispatch( const Reference< uno::XComponentContext >& rxContext, + ChartController* pController ) + :FeatureCommandDispatchBase( rxContext ) + ,m_pChartController( pController ) +{ +} + +DrawCommandDispatch::~DrawCommandDispatch() +{ +} + +void DrawCommandDispatch::initialize() +{ + FeatureCommandDispatchBase::initialize(); +} + +bool DrawCommandDispatch::isFeatureSupported( const ::rtl::OUString& rCommandURL ) +{ + sal_uInt16 nFeatureId = 0; + ::rtl::OUString aBaseCommand; + ::rtl::OUString aCustomShapeType; + return parseCommandURL( rCommandURL, &nFeatureId, &aBaseCommand, &aCustomShapeType ); +} + +::basegfx::B2DPolyPolygon getPolygon( sal_uInt16 nResId, SdrModel& rModel ) +{ + ::basegfx::B2DPolyPolygon aReturn; + XLineEndList* pLineEndList = rModel.GetLineEndList(); + if ( pLineEndList ) + { + String aName( SVX_RES( nResId ) ); + long nCount = pLineEndList->Count(); + for ( long nIndex = 0; nIndex < nCount; ++nIndex ) + { + XLineEndEntry* pEntry = pLineEndList->GetLineEnd( nIndex ); + if ( pEntry->GetName() == aName ) + { + aReturn = pEntry->GetLineEnd(); + break; + } + } + } + return aReturn; +} + +void DrawCommandDispatch::setAttributes( SdrObject* pObj ) +{ + if ( m_pChartController ) + { + DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper(); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pDrawModelWrapper && pDrawViewWrapper && pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_CUSTOMSHAPE ) + { + sal_Bool bAttributesAppliedFromGallery = sal_False; + if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) ) + { + ::std::vector< ::rtl::OUString > aObjList; + if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) ) + { + for ( sal_uInt16 i = 0; i < aObjList.size(); ++i ) + { + if ( aObjList[ i ].equalsIgnoreAsciiCase( m_aCustomShapeType ) ) + { + FmFormModel aModel; + SfxItemPool& rPool = aModel.GetItemPool(); + rPool.FreezeIdRanges(); + if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aModel ) ) + { + const SdrObject* pSourceObj = aModel.GetPage( 0 )->GetObj( 0 ); + if ( pSourceObj ) + { + const SfxItemSet& rSource = pSourceObj->GetMergedItemSet(); + SfxItemSet aDest( pObj->GetModel()->GetItemPool(), // ranges from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + // Graphic Attributes + SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, + // 3d Properties + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, + // CustomShape properties + SDRATTR_CUSTOMSHAPE_FIRST, SDRATTR_CUSTOMSHAPE_LAST, + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + // end + 0, 0); + aDest.Set( rSource ); + pObj->SetMergedItemSet( aDest ); + sal_Int32 nAngle = pSourceObj->GetRotateAngle(); + if ( nAngle ) + { + double a = nAngle * F_PI18000; + pObj->NbcRotate( pObj->GetSnapRect().Center(), nAngle, sin( a ), cos( a ) ); + } + bAttributesAppliedFromGallery = sal_True; + } + } + break; + } + } + } + } + if ( !bAttributesAppliedFromGallery ) + { + pObj->SetMergedItem( SvxAdjustItem( SVX_ADJUST_CENTER, 0 ) ); + pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); + pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) ); + pObj->SetMergedItem( SdrTextAutoGrowHeightItem( sal_False ) ); + ( dynamic_cast< SdrObjCustomShape* >( pObj ) )->MergeDefaultAttributes( &m_aCustomShapeType ); + } + } + } +} + +void DrawCommandDispatch::setLineEnds( SfxItemSet& rAttr ) +{ + if ( m_nFeatureId == COMMAND_ID_LINE_ARROW_END && m_pChartController ) + { + DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper(); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pDrawModelWrapper && pDrawViewWrapper ) + { + ::basegfx::B2DPolyPolygon aArrow( getPolygon( RID_SVXSTR_ARROW, pDrawModelWrapper->getSdrModel() ) ); + if ( !aArrow.count() ) + { + ::basegfx::B2DPolygon aNewArrow; + aNewArrow.append( ::basegfx::B2DPoint( 10.0, 0.0 ) ); + aNewArrow.append( ::basegfx::B2DPoint( 0.0, 30.0) ); + aNewArrow.append( ::basegfx::B2DPoint( 20.0, 30.0 ) ); + aNewArrow.setClosed( true ); + aArrow.append( aNewArrow ); + } + + SfxItemSet aSet( pDrawViewWrapper->GetModel()->GetItemPool() ); + pDrawViewWrapper->GetAttributes( aSet ); + + long nWidth = 300; // (1/100th mm) + if ( aSet.GetItemState( XATTR_LINEWIDTH ) != SFX_ITEM_DONTCARE ) + { + long nValue = ( ( const XLineWidthItem& ) aSet.Get( XATTR_LINEWIDTH ) ).GetValue(); + if ( nValue > 0 ) + { + nWidth = nValue * 3; + } + } + + rAttr.Put( XLineEndItem( SVX_RESSTR( RID_SVXSTR_ARROW ), aArrow ) ); + rAttr.Put( XLineEndWidthItem( nWidth ) ); + } + } +} + +// WeakComponentImplHelperBase +void DrawCommandDispatch::disposing() +{ +} + +// XEventListener +void DrawCommandDispatch::disposing( const lang::EventObject& /* Source */ ) + throw (uno::RuntimeException) +{ +} + +FeatureState DrawCommandDispatch::getState( const ::rtl::OUString& rCommand ) +{ + FeatureState aReturn; + aReturn.bEnabled = false; + aReturn.aState <<= false; + + sal_uInt16 nFeatureId = 0; + ::rtl::OUString aBaseCommand; + ::rtl::OUString aCustomShapeType; + if ( parseCommandURL( rCommand, &nFeatureId, &aBaseCommand, &aCustomShapeType ) ) + { + switch ( nFeatureId ) + { + case COMMAND_ID_OBJECT_SELECT: + case COMMAND_ID_DRAW_LINE: + case COMMAND_ID_LINE_ARROW_END: + case COMMAND_ID_DRAW_RECT: + case COMMAND_ID_DRAW_ELLIPSE: + case COMMAND_ID_DRAW_FREELINE_NOFILL: + case COMMAND_ID_DRAW_TEXT: + case COMMAND_ID_DRAW_CAPTION: + case COMMAND_ID_DRAWTBX_CS_BASIC: + case COMMAND_ID_DRAWTBX_CS_SYMBOL: + case COMMAND_ID_DRAWTBX_CS_ARROW: + case COMMAND_ID_DRAWTBX_CS_FLOWCHART: + case COMMAND_ID_DRAWTBX_CS_CALLOUT: + case COMMAND_ID_DRAWTBX_CS_STAR: + { + aReturn.bEnabled = true; + aReturn.aState <<= false; + } + break; + default: + { + aReturn.bEnabled = false; + aReturn.aState <<= false; + } + break; + } + } + + return aReturn; +} + +void DrawCommandDispatch::execute( const ::rtl::OUString& rCommand, const Sequence< beans::PropertyValue>& rArgs ) +{ + (void)rArgs; + + ChartDrawMode eDrawMode = CHARTDRAW_SELECT; + SdrObjKind eKind = OBJ_NONE; + bool bCreate = false; + + sal_uInt16 nFeatureId = 0; + ::rtl::OUString aBaseCommand; + ::rtl::OUString aCustomShapeType; + if ( parseCommandURL( rCommand, &nFeatureId, &aBaseCommand, &aCustomShapeType ) ) + { + m_nFeatureId = nFeatureId; + m_aCustomShapeType = aCustomShapeType; + + switch ( nFeatureId ) + { + case COMMAND_ID_OBJECT_SELECT: + { + eDrawMode = CHARTDRAW_SELECT; + eKind = OBJ_NONE; + } + break; + case COMMAND_ID_DRAW_LINE: + case COMMAND_ID_LINE_ARROW_END: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_LINE; + } + break; + case COMMAND_ID_DRAW_RECT: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_RECT; + } + break; + case COMMAND_ID_DRAW_ELLIPSE: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_CIRC; + } + break; + case COMMAND_ID_DRAW_FREELINE_NOFILL: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_FREELINE; + } + break; + case COMMAND_ID_DRAW_TEXT: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_TEXT; + bCreate = true; + } + break; + case COMMAND_ID_DRAW_CAPTION: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_CAPTION; + } + break; + case COMMAND_ID_DRAWTBX_CS_BASIC: + case COMMAND_ID_DRAWTBX_CS_SYMBOL: + case COMMAND_ID_DRAWTBX_CS_ARROW: + case COMMAND_ID_DRAWTBX_CS_FLOWCHART: + case COMMAND_ID_DRAWTBX_CS_CALLOUT: + case COMMAND_ID_DRAWTBX_CS_STAR: + { + eDrawMode = CHARTDRAW_INSERT; + eKind = OBJ_CUSTOMSHAPE; + } + break; + default: + { + eDrawMode = CHARTDRAW_SELECT; + eKind = OBJ_NONE; + } + break; + } + + if ( m_pChartController ) + { + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pDrawViewWrapper ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + m_pChartController->setDrawMode( eDrawMode ); + setInsertObj( sal::static_int_cast< USHORT >( eKind ) ); + if ( bCreate ) + { + pDrawViewWrapper->SetCreateMode(); + } + + const ::rtl::OUString sKeyModifier( C2U( "KeyModifier" ) ); + const beans::PropertyValue* pIter = rArgs.getConstArray(); + const beans::PropertyValue* pEnd = pIter + rArgs.getLength(); + const beans::PropertyValue* pKeyModifier = ::std::find_if( + pIter, pEnd, ::std::bind2nd( PropertyValueCompare(), boost::cref( sKeyModifier ) ) ); + sal_Int16 nKeyModifier = 0; + if ( pKeyModifier && ( pKeyModifier->Value >>= nKeyModifier ) && nKeyModifier == KEY_MOD1 ) + { + if ( eDrawMode == CHARTDRAW_INSERT ) + { + SdrObject* pObj = createDefaultObject( nFeatureId ); + if ( pObj ) + { + SdrPageView* pPageView = pDrawViewWrapper->GetSdrPageView(); + pDrawViewWrapper->InsertObjectAtView( pObj, *pPageView ); + Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY ); + if ( xShape.is() ) + { + m_pChartController->m_aSelection.setSelection( xShape ); + m_pChartController->m_aSelection.applySelection( pDrawViewWrapper ); + } + if ( nFeatureId == SID_DRAW_TEXT ) + { + m_pChartController->StartTextEdit(); + } + } + } + } + } + } + } +} + +void DrawCommandDispatch::describeSupportedFeatures() +{ + implDescribeSupportedFeature( ".uno:SelectObject", COMMAND_ID_OBJECT_SELECT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Line", COMMAND_ID_DRAW_LINE, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:LineArrowEnd", COMMAND_ID_LINE_ARROW_END, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Rect", COMMAND_ID_DRAW_RECT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Ellipse", COMMAND_ID_DRAW_ELLIPSE, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Freeline_Unfilled", COMMAND_ID_DRAW_FREELINE_NOFILL, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:DrawText", COMMAND_ID_DRAW_TEXT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:DrawCaption", COMMAND_ID_DRAW_CAPTION, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes", COMMAND_ID_DRAWTBX_CS_BASIC, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes", COMMAND_ID_DRAWTBX_CS_SYMBOL, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes", COMMAND_ID_DRAWTBX_CS_ARROW, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes", COMMAND_ID_DRAWTBX_CS_FLOWCHART, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes", COMMAND_ID_DRAWTBX_CS_CALLOUT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes", COMMAND_ID_DRAWTBX_CS_STAR, CommandGroup::INSERT ); +} + +void DrawCommandDispatch::setInsertObj( USHORT eObj ) +{ + DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : NULL ); + if ( pDrawViewWrapper ) + { + pDrawViewWrapper->SetCurrentObj( eObj /*, Inventor */); + } +} + +SdrObject* DrawCommandDispatch::createDefaultObject( const sal_uInt16 nID ) +{ + SdrObject* pObj = NULL; + DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : NULL ); + DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : NULL ); + + if ( pDrawViewWrapper && pDrawModelWrapper ) + { + Reference< drawing::XDrawPage > xDrawPage( pDrawModelWrapper->getMainDrawPage() ); + SdrPage* pPage = GetSdrPageFromXDrawPage( xDrawPage ); + if ( pPage ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + pObj = SdrObjFactory::MakeNewObject( pDrawViewWrapper->GetCurrentObjInventor(), + pDrawViewWrapper->GetCurrentObjIdentifier(), pPage ); + if ( pObj ) + { + long nDefaultObjectSizeWidth = 4000; + long nDefaultObjectSizeHeight = 2500; + Size aObjectSize( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ); + Rectangle aPageRect( Rectangle( Point( 0, 0 ), pPage->GetSize() ) ); + Point aObjectPos = aPageRect.Center(); + aObjectPos.X() -= aObjectSize.Width() / 2; + aObjectPos.Y() -= aObjectSize.Height() / 2; + Rectangle aRect( aObjectPos, aObjectSize ); + + switch ( nID ) + { + case COMMAND_ID_DRAW_LINE: + case COMMAND_ID_LINE_ARROW_END: + { + if ( pObj->ISA( SdrPathObj ) ) + { + Point aStart = aRect.TopLeft(); + Point aEnd = aRect.BottomRight(); + sal_Int32 nYMiddle( ( aRect.Top() + aRect.Bottom() ) / 2 ); + basegfx::B2DPolygon aPoly; + aPoly.append( basegfx::B2DPoint( aStart.X(), nYMiddle ) ); + aPoly.append( basegfx::B2DPoint( aEnd.X(), nYMiddle ) ); + ( dynamic_cast< SdrPathObj* >( pObj ) )->SetPathPoly( basegfx::B2DPolyPolygon( aPoly ) ); + SfxItemSet aSet( pDrawModelWrapper->GetItemPool() ); + setLineEnds( aSet ); + pObj->SetMergedItemSet( aSet ); + } + } + break; + case COMMAND_ID_DRAW_FREELINE_NOFILL: + { + if ( pObj->ISA( SdrPathObj ) ) + { + basegfx::B2DPolygon aInnerPoly; + aInnerPoly.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom() ) ); + aInnerPoly.appendBezierSegment( + basegfx::B2DPoint( aRect.Left(), aRect.Top() ), + basegfx::B2DPoint( aRect.Center().X(), aRect.Top() ), + basegfx::B2DPoint( aRect.Center().X(), aRect.Center().Y() ) ); + aInnerPoly.appendBezierSegment( + basegfx::B2DPoint( aRect.Center().X(), aRect.Bottom() ), + basegfx::B2DPoint( aRect.Right(), aRect.Bottom() ), + basegfx::B2DPoint( aRect.Right(), aRect.Top() ) ); + basegfx::B2DPolyPolygon aPoly; + aPoly.append( aInnerPoly ); + ( dynamic_cast< SdrPathObj* >( pObj ) )->SetPathPoly( aPoly ); + } + } + break; + case COMMAND_ID_DRAW_TEXT: + case COMMAND_ID_DRAW_TEXT_VERTICAL: + { + if ( pObj->ISA( SdrTextObj ) ) + { + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj ); + if ( pTextObj ) + { + pTextObj->SetLogicRect( aRect ); + BOOL bVertical = ( nID == SID_DRAW_TEXT_VERTICAL ); + pTextObj->SetVerticalWriting( bVertical ); + if ( bVertical ) + { + SfxItemSet aSet( pDrawModelWrapper->GetItemPool() ); + aSet.Put( SdrTextAutoGrowWidthItem( TRUE ) ); + aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) ); + aSet.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_TOP ) ); + aSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT ) ); + pTextObj->SetMergedItemSet( aSet ); + } + } + } + } + break; + case COMMAND_ID_DRAW_CAPTION: + case COMMAND_ID_DRAW_CAPTION_VERTICAL: + { + if ( pObj->ISA( SdrCaptionObj ) ) + { + sal_Bool bIsVertical( SID_DRAW_CAPTION_VERTICAL == nID ); + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj ); + if ( pTextObj ) + { + pTextObj->SetVerticalWriting( bIsVertical ); + } + if ( bIsVertical ) + { + SfxItemSet aSet( pObj->GetMergedItemSet() ); + aSet.Put( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); + aSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_RIGHT ) ); + pObj->SetMergedItemSet( aSet ); + } + SdrCaptionObj* pCaptionObj = dynamic_cast< SdrCaptionObj* >( pObj ); + if ( pCaptionObj ) + { + pCaptionObj->SetLogicRect( aRect ); + pCaptionObj->SetTailPos( + aRect.TopLeft() - Point( aRect.GetWidth() / 2, aRect.GetHeight() / 2 ) ); + } + } + } + break; + default: + { + pObj->SetLogicRect( aRect ); + SfxItemSet aSet( pDrawModelWrapper->GetItemPool() ); + setAttributes( pObj ); + pObj->SetMergedItemSet( aSet ); + } + break; + } + } + } + } + + return pObj; +} + +bool DrawCommandDispatch::parseCommandURL( const ::rtl::OUString& rCommandURL, sal_uInt16* pnFeatureId, + ::rtl::OUString* pBaseCommand, ::rtl::OUString* pCustomShapeType ) +{ + bool bFound = true; + sal_uInt16 nFeatureId = 0; + ::rtl::OUString aBaseCommand; + ::rtl::OUString aType; + + sal_Int32 nIndex = 1; + ::rtl::OUString aToken = rCommandURL.getToken( 0, '.', nIndex ); + if ( nIndex == -1 || !aToken.getLength() ) + { + aBaseCommand = rCommandURL; + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( aBaseCommand ); + if ( aIter != m_aSupportedFeatures.end() ) + { + nFeatureId = aIter->second.nFeatureId; + + switch ( nFeatureId ) + { + case COMMAND_ID_DRAWTBX_CS_BASIC: + { + aType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "diamond" ) ); + } + break; + case COMMAND_ID_DRAWTBX_CS_SYMBOL: + { + aType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "smiley" ) ); + } + break; + case COMMAND_ID_DRAWTBX_CS_ARROW: + { + aType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "left-right-arrow" ) ); + } + break; + case COMMAND_ID_DRAWTBX_CS_FLOWCHART: + { + aType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "flowchart-internal-storage" ) ); + } + break; + case COMMAND_ID_DRAWTBX_CS_CALLOUT: + { + aType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "round-rectangular-callout" ) ); + } + break; + case COMMAND_ID_DRAWTBX_CS_STAR: + { + aType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "star5" ) ); + } + break; + default: + { + } + break; + } + } + else + { + bFound = false; + } + } + else + { + aBaseCommand = rCommandURL.copy( 0, nIndex - 1 ); + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( aBaseCommand ); + if ( aIter != m_aSupportedFeatures.end() ) + { + nFeatureId = aIter->second.nFeatureId; + aType = rCommandURL.getToken( 0, '.', nIndex ); + } + else + { + bFound = false; + } + } + + *pnFeatureId = nFeatureId; + *pBaseCommand = aBaseCommand; + *pCustomShapeType = aType; + + return bFound; +} + +//............................................................................. +} // namespace chart +//............................................................................. diff --git a/chart2/source/controller/main/DrawCommandDispatch.hrc b/chart2/source/controller/main/DrawCommandDispatch.hrc new file mode 100644 index 000000000000..4e31fafaaf63 --- /dev/null +++ b/chart2/source/controller/main/DrawCommandDispatch.hrc @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART_DRAWCOMMANDDISPATCH_HRC +#define CHART_DRAWCOMMANDDISPATCH_HRC + +//----------------------------------------------------------------------------- +//Command Ids: +#define COMMAND_ID_OBJECT_SELECT 1 +#define COMMAND_ID_DRAW_LINE 2 +#define COMMAND_ID_LINE_ARROW_END 3 +#define COMMAND_ID_DRAW_RECT 4 +#define COMMAND_ID_DRAW_ELLIPSE 5 +#define COMMAND_ID_DRAW_FREELINE_NOFILL 6 +#define COMMAND_ID_DRAW_TEXT 7 +#define COMMAND_ID_DRAW_TEXT_VERTICAL 8 +#define COMMAND_ID_DRAW_CAPTION 9 +#define COMMAND_ID_DRAW_CAPTION_VERTICAL 10 +#define COMMAND_ID_DRAWTBX_CS_BASIC 11 +#define COMMAND_ID_DRAWTBX_CS_SYMBOL 12 +#define COMMAND_ID_DRAWTBX_CS_ARROW 13 +#define COMMAND_ID_DRAWTBX_CS_FLOWCHART 14 +#define COMMAND_ID_DRAWTBX_CS_CALLOUT 15 +#define COMMAND_ID_DRAWTBX_CS_STAR 16 + +// CHART_DRAWCOMMANDDISPATCH_HRC +#endif diff --git a/chart2/source/controller/main/DrawCommandDispatch.hxx b/chart2/source/controller/main/DrawCommandDispatch.hxx new file mode 100644 index 000000000000..38c886e29abb --- /dev/null +++ b/chart2/source/controller/main/DrawCommandDispatch.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_DRAWCOMMANDDISPATCH_HXX +#define CHART2_DRAWCOMMANDDISPATCH_HXX + +#include "FeatureCommandDispatchBase.hxx" + +#include <tools/solar.h> + +class SfxItemSet; +class SdrObject; + +//............................................................................. +namespace chart +{ +//............................................................................. + +class ChartController; + +/** This is a CommandDispatch implementation for drawing objects. + */ +class DrawCommandDispatch: public FeatureCommandDispatchBase +{ +public: + DrawCommandDispatch( const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XComponentContext >& rxContext, ChartController* pController ); + virtual ~DrawCommandDispatch(); + + // late initialisation, especially for adding as listener + virtual void initialize(); + + virtual bool isFeatureSupported( const ::rtl::OUString& rCommandURL ); + + void setAttributes( SdrObject* pObj ); + void setLineEnds( SfxItemSet& rAttr ); + +protected: + // WeakComponentImplHelperBase + virtual void SAL_CALL disposing(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException); + + // state of a feature + virtual FeatureState getState( const ::rtl::OUString& rCommand ); + + // execute a feature + virtual void execute( const ::rtl::OUString& rCommand, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs ); + + // all the features which should be handled by this class + virtual void describeSupportedFeatures(); + +private: + void setInsertObj( USHORT eObj ); + SdrObject* createDefaultObject( const sal_uInt16 nID ); + + bool parseCommandURL( const ::rtl::OUString& rCommandURL, sal_uInt16* pnFeatureId, ::rtl::OUString* pBaseCommand, ::rtl::OUString* pCustomShapeType ); + + ChartController* m_pChartController; + ::rtl::OUString m_aCustomShapeType; +}; + +//............................................................................. +} // namespace chart +//............................................................................. + +// CHART2_DRAWCOMMANDDISPATCH_HXX +#endif diff --git a/chart2/source/controller/main/ElementSelector.cxx b/chart2/source/controller/main/ElementSelector.cxx index 49a8736bb11b..3b41fd1b6b66 100644 --- a/chart2/source/controller/main/ElementSelector.cxx +++ b/chart2/source/controller/main/ElementSelector.cxx @@ -34,6 +34,9 @@ #include "ObjectHierarchy.hxx" #include "servicenames.hxx" #include <chartview/ExplicitValueProvider.hxx> +#include "DrawViewWrapper.hxx" +#include "ResId.hxx" +#include "Strings.hrc" #include <toolkit/helper/vclunohelper.hxx> #include <vos/mutex.hxx> @@ -71,20 +74,21 @@ SelectorListBox::~SelectorListBox() { } -void lcl_addObjectsToList( const ObjectHierarchy& rHierarchy, const ObjectHierarchy::tCID & rParent, std::vector< ListBoxEntryData >& rEntries +void lcl_addObjectsToList( const ObjectHierarchy& rHierarchy, const ObjectHierarchy::tOID & rParent, std::vector< ListBoxEntryData >& rEntries , const sal_Int32 nHierarchyDepth, const Reference< chart2::XChartDocument >& xChartDoc ) { ObjectHierarchy::tChildContainer aChildren( rHierarchy.getChildren(rParent) ); ObjectHierarchy::tChildContainer::const_iterator aIt( aChildren.begin()); while( aIt != aChildren.end() ) { - ::rtl::OUString aCID = *aIt; + ObjectHierarchy::tOID aOID = *aIt; + ::rtl::OUString aCID = aOID.getObjectCID(); ListBoxEntryData aEntry; - aEntry.CID = aCID; + aEntry.OID = aOID; aEntry.UIName += ObjectNameProvider::getNameForCID( aCID, xChartDoc ); aEntry.nHierarchyDepth = nHierarchyDepth; rEntries.push_back(aEntry); - lcl_addObjectsToList( rHierarchy, aCID, rEntries, nHierarchyDepth+1, xChartDoc ); + lcl_addObjectsToList( rHierarchy, aOID, rEntries, nHierarchyDepth+1, xChartDoc ); ++aIt; } } @@ -103,14 +107,18 @@ void SelectorListBox::UpdateChartElementsListAndSelection() if( xChartController.is() ) { Reference< view::XSelectionSupplier > xSelectionSupplier( xChartController, uno::UNO_QUERY); + ObjectHierarchy::tOID aSelectedOID; rtl::OUString aSelectedCID; if( xSelectionSupplier.is() ) - xSelectionSupplier->getSelection() >>= aSelectedCID; + { + aSelectedOID = ObjectIdentifier( xSelectionSupplier->getSelection() ); + aSelectedCID = aSelectedOID.getObjectCID(); + } Reference< chart2::XChartDocument > xChartDoc( xChartController->getModel(), uno::UNO_QUERY ); - ObjectType eType( ObjectIdentifier::getObjectType( aSelectedCID )); + ObjectType eType( aSelectedOID.getObjectType() ); bool bAddSelectionToList = false; - if( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL ) + if ( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL || eType == OBJECTTYPE_SHAPE ) bAddSelectionToList = true; Reference< uno::XInterface > xChartView; @@ -119,27 +127,39 @@ void SelectorListBox::UpdateChartElementsListAndSelection() xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME ); ExplicitValueProvider* pExplicitValueProvider = 0;//ExplicitValueProvider::getExplicitValueProvider(xChartView); dies erzeugt alle sichtbaren datenpinkte, das ist zu viel ObjectHierarchy aHierarchy( xChartDoc, pExplicitValueProvider, true /*bFlattenDiagram*/, true /*bOrderingForElementSelector*/ ); - lcl_addObjectsToList( aHierarchy, aHierarchy.getRootNodeCID(), m_aEntries, 0, xChartDoc ); + lcl_addObjectsToList( aHierarchy, aHierarchy.getRootNodeOID(), m_aEntries, 0, xChartDoc ); std::vector< ListBoxEntryData >::iterator aIt( m_aEntries.begin() ); if( bAddSelectionToList ) { - rtl::OUString aSeriesCID = ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::getSeriesParticleFromCID( aSelectedCID ) ); - for( aIt = m_aEntries.begin(); aIt != m_aEntries.end(); ++aIt ) + if ( aSelectedOID.isAutoGeneratedObject() ) { - if( aIt->CID.match( aSeriesCID ) ) + rtl::OUString aSeriesCID = ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::getSeriesParticleFromCID( aSelectedCID ) ); + for( aIt = m_aEntries.begin(); aIt != m_aEntries.end(); ++aIt ) { - ListBoxEntryData aEntry; - aEntry.UIName = ObjectNameProvider::getNameForCID( aSelectedCID, xChartDoc ); - aEntry.CID = aSelectedCID; - ++aIt; - if( aIt != m_aEntries.end() ) - m_aEntries.insert(aIt, aEntry); - else - m_aEntries.push_back( aEntry ); - break; + if( aIt->OID.getObjectCID().match( aSeriesCID ) ) + { + ListBoxEntryData aEntry; + aEntry.UIName = ObjectNameProvider::getNameForCID( aSelectedCID, xChartDoc ); + aEntry.OID = aSelectedOID; + ++aIt; + if( aIt != m_aEntries.end() ) + m_aEntries.insert(aIt, aEntry); + else + m_aEntries.push_back( aEntry ); + break; + } } } + else if ( aSelectedOID.isAdditionalShape() ) + { + ListBoxEntryData aEntry; + SdrObject* pSelectedObj = DrawViewWrapper::getSdrObject( aSelectedOID.getAdditionalShape() ); + ::rtl::OUString aName( pSelectedObj ? pSelectedObj->GetName() : String() ); + aEntry.UIName = ( aName.getLength() > 0 ? aName : ::rtl::OUString( String( SchResId( STR_OBJECT_SHAPE ) ) ) ); + aEntry.OID = aSelectedOID; + m_aEntries.push_back( aEntry ); + } } USHORT nEntryPosToSelect = 0; bool bSelectionFound = false; @@ -147,7 +167,7 @@ void SelectorListBox::UpdateChartElementsListAndSelection() for( USHORT nN=0; aIt != m_aEntries.end(); ++aIt, ++nN ) { InsertEntry( aIt->UIName ); - if( !bSelectionFound && aSelectedCID.equals( aIt->CID ) ) + if ( !bSelectionFound && aSelectedOID == aIt->OID ) { nEntryPosToSelect = nN; bSelectionFound = true; @@ -188,11 +208,10 @@ void SelectorListBox::Select() USHORT nPos = GetSelectEntryPos(); if( nPos < m_aEntries.size() ) { - rtl::OUString aCID = m_aEntries[nPos].CID; - uno::Any aASelection( uno::makeAny(aCID) ); + ObjectHierarchy::tOID aOID = m_aEntries[nPos].OID; Reference< view::XSelectionSupplier > xSelectionSupplier( m_xChartController.get(), uno::UNO_QUERY ); if( xSelectionSupplier.is() ) - xSelectionSupplier->select(aASelection); + xSelectionSupplier->select( aOID.getAny() ); } ReleaseFocus_Impl(); } diff --git a/chart2/source/controller/main/ElementSelector.hxx b/chart2/source/controller/main/ElementSelector.hxx index 6f51c1df0ce6..d85415d614e2 100644 --- a/chart2/source/controller/main/ElementSelector.hxx +++ b/chart2/source/controller/main/ElementSelector.hxx @@ -28,6 +28,7 @@ #define _CHART_ELEMENTSELECTOR_HXX #include "ServiceMacros.hxx" +#include "ObjectHierarchy.hxx" #include <com/sun/star/lang/XServiceInfo.hpp> #include <cppuhelper/implbase1.hxx> #include <svtools/toolboxcontroller.hxx> @@ -45,7 +46,7 @@ namespace chart struct ListBoxEntryData { rtl::OUString UIName; - rtl::OUString CID; + ObjectHierarchy::tOID OID; sal_Int32 nHierarchyDepth; ListBoxEntryData() : nHierarchyDepth(0) diff --git a/chart2/source/controller/main/FeatureCommandDispatchBase.cxx b/chart2/source/controller/main/FeatureCommandDispatchBase.cxx new file mode 100644 index 000000000000..39b4e1d4a171 --- /dev/null +++ b/chart2/source/controller/main/FeatureCommandDispatchBase.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "FeatureCommandDispatchBase.hxx" + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +FeatureCommandDispatchBase::FeatureCommandDispatchBase( const Reference< uno::XComponentContext >& rxContext ) + :CommandDispatch( rxContext ) + ,m_nFeatureId( 0 ) +{ +} + +FeatureCommandDispatchBase::~FeatureCommandDispatchBase() +{ +} + +void FeatureCommandDispatchBase::initialize() +{ + CommandDispatch::initialize(); + fillSupportedFeatures(); +} + +bool FeatureCommandDispatchBase::isFeatureSupported( const ::rtl::OUString& rCommandURL ) +{ + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( rCommandURL ); + if ( aIter != m_aSupportedFeatures.end() ) + { + return true; + } + return false; +} + +void FeatureCommandDispatchBase::fireStatusEvent( const ::rtl::OUString& rURL, + const Reference< frame::XStatusListener >& xSingleListener /* = 0 */ ) +{ + if ( rURL.getLength() == 0 ) + { + SupportedFeatures::const_iterator aEnd( m_aSupportedFeatures.end() ); + for ( SupportedFeatures::const_iterator aIter( m_aSupportedFeatures.begin() ); aIter != aEnd; ++aIter ) + { + FeatureState aFeatureState( getState( aIter->first ) ); + fireStatusEventForURL( aIter->first, aFeatureState.aState, aFeatureState.bEnabled, xSingleListener ); + } + } + else + { + FeatureState aFeatureState( getState( rURL ) ); + fireStatusEventForURL( rURL, aFeatureState.aState, aFeatureState.bEnabled, xSingleListener ); + } +} + +// XDispatch +void FeatureCommandDispatchBase::dispatch( const util::URL& URL, + const Sequence< beans::PropertyValue >& Arguments ) + throw (uno::RuntimeException) +{ + ::rtl::OUString aCommand( URL.Complete ); + if ( getState( aCommand ).bEnabled ) + { + execute( aCommand, Arguments ); + } +} + +void FeatureCommandDispatchBase::implDescribeSupportedFeature( const sal_Char* pAsciiCommandURL, + sal_uInt16 nId, sal_Int16 nGroup ) +{ + ControllerFeature aFeature; + aFeature.Command = ::rtl::OUString::createFromAscii( pAsciiCommandURL ); + aFeature.nFeatureId = nId; + aFeature.GroupId = nGroup; + + m_aSupportedFeatures[ aFeature.Command ] = aFeature; +} + +void FeatureCommandDispatchBase::fillSupportedFeatures() +{ + describeSupportedFeatures(); +} + +} // namespace chart diff --git a/chart2/source/controller/main/FeatureCommandDispatchBase.hxx b/chart2/source/controller/main/FeatureCommandDispatchBase.hxx new file mode 100644 index 000000000000..b3e2a568d3b9 --- /dev/null +++ b/chart2/source/controller/main/FeatureCommandDispatchBase.hxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_FEATURECOMMANDDISPATCHBASE_HXX +#define CHART2_FEATURECOMMANDDISPATCHBASE_HXX + +#include "CommandDispatch.hxx" + +#include <com/sun/star/frame/CommandGroup.hpp> +#include <com/sun/star/frame/DispatchInformation.hpp> +#include <com/sun/star/util/URL.hpp> + +namespace chart +{ + +struct ControllerFeature: public ::com::sun::star::frame::DispatchInformation +{ + sal_uInt16 nFeatureId; +}; + +typedef ::std::map< ::rtl::OUString, + ControllerFeature, + ::std::less< ::rtl::OUString > > SupportedFeatures; + +struct FeatureState +{ + bool bEnabled; + ::com::sun::star::uno::Any aState; + + FeatureState() : bEnabled( false ) { } +}; + +/** This is a base class for CommandDispatch implementations with feature support. + */ +class FeatureCommandDispatchBase: public CommandDispatch +{ +public: + FeatureCommandDispatchBase( const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~FeatureCommandDispatchBase(); + + // late initialisation, especially for adding as listener + virtual void initialize(); + + virtual bool isFeatureSupported( const ::rtl::OUString& rCommandURL ); + +protected: + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void fireStatusEvent( const ::rtl::OUString& rURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& xSingleListener ); + + // state of a feature + virtual FeatureState getState( const ::rtl::OUString& rCommand ) = 0; + + // execute a feature + virtual void execute( const ::rtl::OUString& rCommand, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs ) = 0; + + // all the features which should be handled by this class + virtual void describeSupportedFeatures() = 0; + + /** describes a feature supported by the controller + + Must not be called outside <member>describeSupportedFeatures</member>. + + @param pAsciiCommandURL + the URL of the feature command + @param nId + the id of the feature. Later references to this feature usually happen by id, not by + URL. + @param nGroup + the command group of the feature. This is important for configuring the controller UI + by the user, see also <type scope="com::sun::star::frame">CommandGroup</type>. + */ + void implDescribeSupportedFeature( const sal_Char* pAsciiCommandURL, sal_uInt16 nId, + sal_Int16 nGroup = ::com::sun::star::frame::CommandGroup::INTERNAL ); + + mutable SupportedFeatures m_aSupportedFeatures; + + sal_uInt16 m_nFeatureId; + +private: + void fillSupportedFeatures(); +}; + +} // namespace chart + +// CHART2_FEATURECOMMANDDISPATCHBASE_HXX +#endif diff --git a/chart2/source/controller/main/ImplUndoManager.cxx b/chart2/source/controller/main/ImplUndoManager.cxx new file mode 100644 index 000000000000..57e8e7315334 --- /dev/null +++ b/chart2/source/controller/main/ImplUndoManager.cxx @@ -0,0 +1,505 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "ImplUndoManager.hxx" +#include "DisposeHelper.hxx" +#include "CommonFunctors.hxx" +#include "ControllerLockGuard.hxx" +#include "PropertyHelper.hxx" +#include "DataSourceHelper.hxx" +#include "ChartModelHelper.hxx" + +#include <com/sun/star/chart/XComplexDescriptionAccess.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/XInternalDataProvider.hpp> +#include <com/sun/star/chart2/XTitled.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> + +#include <boost/bind.hpp> +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; +using ::com::sun::star::chart::XComplexDescriptionAccess; + +namespace chart +{ +namespace impl +{ + +void ImplApplyDataToModel( + Reference< frame::XModel > & xInOutModelToChange, + const Reference< chart2::XInternalDataProvider > & xData ) +{ + Reference< chart2::XChartDocument > xDoc( xInOutModelToChange, uno::UNO_QUERY ); + OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider()); + + // copy data from stored internal data provider + if( xDoc.is() && xDoc->hasInternalDataProvider()) + { + Reference< XComplexDescriptionAccess > xCurrentData( xDoc->getDataProvider(), uno::UNO_QUERY ); + Reference< XComplexDescriptionAccess > xSavedData( xData, uno::UNO_QUERY ); + if( xCurrentData.is() && xSavedData.is()) + { + xCurrentData->setData( xSavedData->getData()); + xCurrentData->setComplexRowDescriptions( xSavedData->getComplexRowDescriptions()); + xCurrentData->setComplexColumnDescriptions( xSavedData->getComplexColumnDescriptions()); + } + } +} + +// ---------------------------------------- + +UndoElement::UndoElement( + const OUString & rActionString, + const Reference< frame::XModel > & xModel ) : + m_aActionString( rActionString ) +{ + initialize( xModel ); +} + +UndoElement::UndoElement( + const Reference< frame::XModel > & xModel ) +{ + initialize( xModel ); +} + +UndoElement::UndoElement( const UndoElement & rOther ) : + m_aActionString( rOther.m_aActionString ) +{ + initialize( rOther.m_xModel ); +} + +UndoElement::~UndoElement() +{} + +void UndoElement::initialize( const Reference< frame::XModel > & xModel ) +{ + if ( xModel.is() ) + { + m_xModel.set( UndoElement::cloneModel( xModel ) ); + } +} + +void UndoElement::dispose() +{ + Reference< lang::XComponent > xComp( m_xModel, uno::UNO_QUERY ); + if( xComp.is()) + xComp->dispose(); + m_xModel.set( 0 ); +} + +void UndoElement::applyToModel( + Reference< frame::XModel > & xInOutModelToChange ) +{ + UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel ); +} + +UndoElement * UndoElement::createFromModel( + const Reference< frame::XModel > & xModel ) +{ + return new UndoElement( getActionString(), xModel ); +} + +void UndoElement::setActionString( const ::rtl::OUString & rActionString ) +{ + m_aActionString = rActionString; +} + +OUString UndoElement::getActionString() const +{ + return m_aActionString; +} + +// static +Reference< frame::XModel > UndoElement::cloneModel( const Reference< frame::XModel > & xModel ) +{ + Reference< frame::XModel > xResult; + uno::Reference< util::XCloneable > xCloneable( xModel, uno::UNO_QUERY ); + OSL_ENSURE( xCloneable.is(), "Cannot clone model" ); + if( xCloneable.is()) + xResult.set( xCloneable->createClone(), uno::UNO_QUERY ); + + return xResult; +} + +// static +void UndoElement::applyModelContentToModel( + Reference< frame::XModel > & xInOutModelToChange, + const Reference< frame::XModel > & xModelToCopyFrom, + const Reference< chart2::XInternalDataProvider > & xData /* = 0 */ ) +{ + + if( xModelToCopyFrom.is() && xInOutModelToChange.is()) + { + try + { + // /-- loccked controllers of destination + ControllerLockGuard aLockedControllers( xInOutModelToChange ); + Reference< chart2::XChartDocument > xSource( xModelToCopyFrom, uno::UNO_QUERY_THROW ); + Reference< chart2::XChartDocument > xDestination( xInOutModelToChange, uno::UNO_QUERY_THROW ); + + // propagate the correct flag for plotting of hidden values to the data provider and all used sequences + ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( xModelToCopyFrom ) , xInOutModelToChange ); + + // diagram + xDestination->setFirstDiagram( xSource->getFirstDiagram()); + + // main title + Reference< chart2::XTitled > xDestinationTitled( xDestination, uno::UNO_QUERY_THROW ); + Reference< chart2::XTitled > xSourceTitled( xSource, uno::UNO_QUERY_THROW ); + xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject()); + + // page background + comphelper::copyProperties( + xSource->getPageBackground(), + xDestination->getPageBackground() ); + + // apply data (not applied in standard Undo) + if( xData.is()) + ImplApplyDataToModel( xInOutModelToChange, xData ); + + // register all sequences at the internal data provider to get adapted + // indexes when columns are added/removed + if( xDestination->hasInternalDataProvider()) + { + Reference< chart2::XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), uno::UNO_QUERY ); + Reference< chart2::data::XDataSource > xUsedData( DataSourceHelper::getUsedData( xInOutModelToChange )); + if( xUsedData.is() && xNewDataProvider.is()) + { + Sequence< Reference< chart2::data::XLabeledDataSequence > > aData( xUsedData->getDataSequences()); + for( sal_Int32 i=0; i<aData.getLength(); ++i ) + { + xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues()); + xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel()); + } + } + } + + // restore modify status + Reference< util::XModifiable > xSourceMod( xSource, uno::UNO_QUERY ); + Reference< util::XModifiable > xDestMod( xDestination, uno::UNO_QUERY ); + if( xSourceMod.is() && xDestMod.is() && + ! xSourceMod->isModified() ) + { + xDestMod->setModified( sal_False ); + } + // \-- loccked controllers of destination + } + catch( uno::Exception & ) + { + } + } +} + +// ---------------------------------------- + +UndoElementWithData::UndoElementWithData( + const OUString & rActionString, + const Reference< frame::XModel > & xModel ) : + UndoElement( rActionString, xModel ) +{ + initializeData(); +} + +UndoElementWithData::UndoElementWithData( + const Reference< frame::XModel > & xModel ) : + UndoElement( xModel ) +{ + initializeData(); +} + + +UndoElementWithData::UndoElementWithData( + const UndoElementWithData & rOther ) : + UndoElement( rOther ) +{ + initializeData(); +} + +UndoElementWithData::~UndoElementWithData() +{} + +void UndoElementWithData::initializeData() +{ + try + { + Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY_THROW ); + OSL_ASSERT( xChartDoc->hasInternalDataProvider()); + if( xChartDoc->hasInternalDataProvider()) + { + Reference< util::XCloneable > xCloneable( xChartDoc->getDataProvider(), uno::UNO_QUERY ); + OSL_ENSURE( xCloneable.is(), "Cannot clone data" ); + if( xCloneable.is()) + m_xData.set( xCloneable->createClone(), uno::UNO_QUERY ); + } + } + catch( uno::Exception & ) + { + } +} + +void UndoElementWithData::dispose() +{ + UndoElement::dispose(); + m_xData.set( 0 ); +} + +void UndoElementWithData::applyToModel( + Reference< frame::XModel > & xInOutModelToChange ) +{ + UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel, m_xData ); +} + +UndoElement * UndoElementWithData::createFromModel( + const Reference< frame::XModel > & xModel ) +{ + return new UndoElementWithData( getActionString(), xModel ); +} + +// ======================================== + +// ---------------------------------------- + +UndoElementWithSelection::UndoElementWithSelection( + const OUString & rActionString, + const Reference< frame::XModel > & xModel ) : + UndoElement( rActionString, xModel ) +{ + initialize( xModel ); +} + +UndoElementWithSelection::UndoElementWithSelection( + const Reference< frame::XModel > & xModel ) : + UndoElement( xModel ) +{ + initialize( xModel ); +} + +UndoElementWithSelection::UndoElementWithSelection( + const UndoElementWithSelection & rOther ) : + UndoElement( rOther ) +{ + initialize( rOther.m_xModel ); +} + +UndoElementWithSelection::~UndoElementWithSelection() +{} + +void UndoElementWithSelection::initialize( const Reference< frame::XModel > & xModel ) +{ + try + { + uno::Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY ); + OSL_ASSERT( xSelSupp.is() ); + + if( xSelSupp.is() ) + m_aSelection = xSelSupp->getSelection(); + } + catch( const uno::Exception & ) + { + } +} + +void UndoElementWithSelection::dispose() +{ + UndoElement::dispose(); + m_aSelection.clear(); +} + +void UndoElementWithSelection::applyToModel( + Reference< frame::XModel > & xInOutModelToChange ) +{ + UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel ); + Reference< view::XSelectionSupplier > xCurrentSelectionSuppl( xInOutModelToChange->getCurrentController(), uno::UNO_QUERY ); + OSL_ASSERT( xCurrentSelectionSuppl.is() ); + + if( xCurrentSelectionSuppl.is()) + xCurrentSelectionSuppl->select( m_aSelection ); +} + +UndoElement * UndoElementWithSelection::createFromModel( + const Reference< frame::XModel > & xModel ) +{ + return new UndoElementWithSelection( getActionString(), xModel ); +} + +// ---------------------------------------- + +ShapeUndoElement::ShapeUndoElement( const OUString& rActionString, SdrUndoAction* pAction ) + :UndoElement( rActionString, Reference< frame::XModel >() ) + ,m_pAction( pAction ) +{ +} + +ShapeUndoElement::ShapeUndoElement( const ShapeUndoElement& rOther ) + :UndoElement( rOther ) + ,m_pAction( rOther.m_pAction ) +{ +} + +ShapeUndoElement::~ShapeUndoElement() +{ +} + +SdrUndoAction* ShapeUndoElement::getSdrUndoAction() +{ + return m_pAction; +} + +// ======================================== + +UndoStack::UndoStack() : + m_nSizeLimit( 1000 ) +{ +} + +UndoStack::~UndoStack() +{ + disposeAndClear(); +} + +void UndoStack::pop() +{ + if( ! empty()) + { + top()->dispose(); + delete top(); + m_aStack.pop_back(); + } +} + +void UndoStack::push( UndoElement * pElement ) +{ + m_aStack.push_back( pElement ); + applyLimitation(); +} + +UndoElement * UndoStack::top() const +{ + return m_aStack.back(); +} + +OUString UndoStack::topUndoString() const +{ + if( ! empty()) + return top()->getActionString(); + return OUString(); +} + +Sequence< OUString > UndoStack::getUndoStrings() const +{ + sal_Int32 nSize( static_cast< sal_Int32 >( m_aStack.size())); + Sequence< OUString > aResult( nSize ); + for( sal_Int32 i=0; i<nSize; ++i ) + aResult[i] = m_aStack[i]->getActionString(); + return aResult; +} + +bool UndoStack::empty() const +{ + return m_aStack.empty(); +} + +void UndoStack::disposeAndClear() +{ + ::std::for_each( m_aStack.begin(), m_aStack.end(), ::boost::mem_fn( & UndoElement::dispose )); + ::std::for_each( m_aStack.begin(), m_aStack.end(), CommonFunctors::DeletePtr< UndoElement >() ); + m_aStack.clear(); +} + +void UndoStack::limitSize( sal_Int32 nMaxSize ) +{ + m_nSizeLimit = nMaxSize; + applyLimitation(); +} + +void UndoStack::applyLimitation() +{ + if( m_aStack.size() > static_cast< sal_uInt32 >( m_nSizeLimit )) + { + tUndoStackType::iterator aBegin( m_aStack.begin()); + tUndoStackType::iterator aEnd( aBegin + (m_aStack.size() - m_nSizeLimit)); + // dispose and remove all undo elements that are over the limit + ::std::for_each( aBegin, aEnd, ::boost::mem_fn( & UndoElement::dispose )); + ::std::for_each( aBegin, aEnd, CommonFunctors::DeletePtr< UndoElement >() ); + m_aStack.erase( aBegin, aEnd ); + } +} + +// ================================================================================ + +namespace +{ +static const OUString aUndoStepsPropName( RTL_CONSTASCII_USTRINGPARAM("Steps")); +} // anonymous namespace + +UndoStepsConfigItem::UndoStepsConfigItem( ConfigItemListener & rListener ) : + ::utl::ConfigItem( OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Undo"))), + m_rListener( rListener ) +{ + EnableNotification( Sequence< OUString >( & aUndoStepsPropName, 1 )); +} + +UndoStepsConfigItem::~UndoStepsConfigItem() +{ +} + +void UndoStepsConfigItem::Notify( const Sequence< OUString > & aPropertyNames ) +{ + for( sal_Int32 nIdx=0; nIdx<aPropertyNames.getLength(); ++nIdx ) + { + if( aPropertyNames[nIdx].equals( aUndoStepsPropName )) + m_rListener.notify( aPropertyNames[nIdx] ); + } +} + +void UndoStepsConfigItem::Commit() +{ +} + +// mtehod is not const, because GetProperties is not const +sal_Int32 UndoStepsConfigItem::getUndoSteps() +{ + sal_Int32 nSteps = -1; + Sequence< uno::Any > aValues( + GetProperties( Sequence< OUString >( & aUndoStepsPropName, 1 ))); + if( aValues.getLength()) + aValues[0] >>= nSteps; + return nSteps; +} + +} // namespace impl +} // namespace chart diff --git a/chart2/source/controller/main/ImplUndoManager.hxx b/chart2/source/controller/main/ImplUndoManager.hxx new file mode 100644 index 000000000000..4dde0bc65719 --- /dev/null +++ b/chart2/source/controller/main/ImplUndoManager.hxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_IMPLUNDOMANAGER_HXX +#define CHART2_IMPLUNDOMANAGER_HXX + +#include "ConfigItemListener.hxx" + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/ustring.hxx> +#include <unotools/configitem.hxx> + +#include <utility> +#include <deque> + + +class SdrUndoAction; + +namespace com { namespace sun { namespace star { +namespace chart2 { + class XInternalDataProvider; +} +}}} + + +namespace chart +{ +namespace impl +{ + +class UndoElement +{ +public: + UndoElement( const ::rtl::OUString & rActionString, + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElement( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElement( const UndoElement & rOther ); + virtual ~UndoElement(); + + virtual void dispose(); + virtual UndoElement * createFromModel( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + + virtual void applyToModel( + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xInOutModelToChange ); + + void setActionString( const ::rtl::OUString & rActionString ); + ::rtl::OUString getActionString() const; + + static ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > cloneModel( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModel ); + + static void applyModelContentToModel( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xInOutModelToChange, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModelToCopyFrom, + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XInternalDataProvider > & xData = 0 ); + +protected: + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > m_xModel; + +private: + void initialize( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + + ::rtl::OUString m_aActionString; +}; + +class UndoElementWithData : public UndoElement +{ +public: + UndoElementWithData( const ::rtl::OUString & rActionString, + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElementWithData( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElementWithData( const UndoElementWithData & rOther ); + virtual ~UndoElementWithData(); + + virtual void dispose(); + virtual UndoElement * createFromModel( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + + virtual void applyToModel( + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xInOutModelToChange ); + +private: + void initializeData(); + + ::com::sun::star::uno::Reference< + ::com::sun::star::chart2::XInternalDataProvider > m_xData; +}; + +class UndoElementWithSelection : public UndoElement +{ +public: + UndoElementWithSelection( const ::rtl::OUString & rActionString, + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElementWithSelection( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + UndoElementWithSelection( const UndoElementWithSelection & rOther ); + virtual ~UndoElementWithSelection(); + + virtual void dispose(); + virtual UndoElement * createFromModel( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + + virtual void applyToModel( + ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xInOutModelToChange ); + +private: + void initialize( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel > & xModel ); + + ::com::sun::star::uno::Any m_aSelection; +}; + +class ShapeUndoElement : public UndoElement +{ +public: + ShapeUndoElement( const ::rtl::OUString& rActionString, SdrUndoAction* pAction ); + ShapeUndoElement( const ShapeUndoElement& rOther ); + virtual ~ShapeUndoElement(); + + SdrUndoAction* getSdrUndoAction(); + +private: + SdrUndoAction* m_pAction; +}; + +/** Note that all models that are put into this container are at some point + disposed of inside this class. (At least in the destructor). That means + the models retrieved here should never be used, but instead their content + should be copied to a living model. + */ +class UndoStack +{ +public: + UndoStack(); + // disposes of all models left in the stack + ~UndoStack(); + + // removes he last undo action and disposes of the model + void pop(); + void push( UndoElement * rElement ); + + // precondition: !empty() + UndoElement * top() const; + ::rtl::OUString topUndoString() const; + + ::com::sun::star::uno::Sequence< ::rtl::OUString > getUndoStrings() const; + + bool empty() const; + void disposeAndClear(); + + // removes all actions that have been inserted more than nMaxSize steps ago. + // The models of those actions are disposed of + void limitSize( sal_Int32 nMaxSize ); + +private: + void applyLimitation(); + + typedef ::std::deque< UndoElement * > tUndoStackType; + + tUndoStackType m_aStack; + sal_Int32 m_nSizeLimit; +}; + +// ---------------------------------------- + +class UndoStepsConfigItem : public ::utl::ConfigItem +{ +public: + explicit UndoStepsConfigItem( ConfigItemListener & rListener ); + virtual ~UndoStepsConfigItem(); + + sal_Int32 getUndoSteps(); + +protected: + // ____ ::utl::ConfigItem ____ + virtual void Notify( const ::com::sun::star::uno::Sequence< ::rtl::OUString > & aPropertyNames ); + virtual void Commit(); + +private: + ConfigItemListener & m_rListener; +}; + + +} // namespace impl +} // namespace chart + +// CHART2_IMPLUNDOMANAGER_HXX +#endif diff --git a/chart2/source/controller/main/ObjectHierarchy.cxx b/chart2/source/controller/main/ObjectHierarchy.cxx index bb290425090c..0fefa3d52310 100644 --- a/chart2/source/controller/main/ObjectHierarchy.cxx +++ b/chart2/source/controller/main/ObjectHierarchy.cxx @@ -40,6 +40,7 @@ #include "ChartTypeHelper.hxx" #include "DataSeriesHelper.hxx" #include "LegendHelper.hxx" +#include "chartview/DrawModelWrapper.hxx" #include <map> #include <algorithm> @@ -63,24 +64,25 @@ using ::rtl::OUString; namespace { -struct lcl_ObjectToCID : public ::std::unary_function< Reference< uno::XInterface >, OUString > + +struct lcl_ObjectToOID : public ::std::unary_function< Reference< uno::XInterface >, ::chart::ObjectIdentifier > { - explicit lcl_ObjectToCID( const Reference< chart2::XChartDocument > & xChartDoc ) : + explicit lcl_ObjectToOID( const Reference< chart2::XChartDocument > & xChartDoc ) : m_xModel( xChartDoc, uno::UNO_QUERY ) {} - OUString operator() ( const Reference< uno::XInterface > & xObj ) + ::chart::ObjectIdentifier operator() ( const Reference< uno::XInterface > & xObj ) { - return ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel ); + return ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel ) ); } private: Reference< frame::XModel > m_xModel; }; -void lcl_getChildCIDs( - ::chart::ObjectHierarchy::tChildContainer & rOutChildren, - const Reference< container::XIndexAccess > & xShapes ) +void lcl_getChildOIDs( + ::chart::ObjectHierarchy::tChildContainer& rOutChildren, + const Reference< container::XIndexAccess >& xShapes ) { if( xShapes.is()) { @@ -98,11 +100,11 @@ void lcl_getChildCIDs( aName.getLength() > 0 && ::chart::ObjectIdentifier::isCID( aName )) { - rOutChildren.push_back( aName ); + rOutChildren.push_back( ::chart::ObjectIdentifier( aName ) ); } Reference< container::XIndexAccess > xNewShapes( xShapeProp, uno::UNO_QUERY ); if( xNewShapes.is()) - lcl_getChildCIDs( rOutChildren, xNewShapes ); + lcl_getChildOIDs( rOutChildren, xNewShapes ); } } } @@ -116,31 +118,31 @@ void lcl_addAxisTitle( const Reference< XAxis >& xAxis, ::chart::ObjectHierarchy Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject()); if( xAxisTitle.is()) rContainer.push_back( - ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xChartModel )); + ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xChartModel ) ) ); } } } // anonymous namespace - namespace chart { namespace impl { + class ImplObjectHierarchy { public: explicit ImplObjectHierarchy( - const Reference< XChartDocument > & xChartDocument, - ExplicitValueProvider * pExplicitValueProvider, + const Reference< XChartDocument >& xChartDocument, + ExplicitValueProvider* pExplicitValueProvider, bool bFlattenDiagram, bool bOrderingForElementSelector ); - bool hasChildren( const OUString & rParent ); - ObjectHierarchy::tChildContainer getChildren( const OUString & rParent ); - ObjectHierarchy::tChildContainer getSiblings( const OUString & rNode ); + bool hasChildren( const ObjectHierarchy::tOID& rParent ); + ObjectHierarchy::tChildContainer getChildren( const ObjectHierarchy::tOID& rParent ); + ObjectHierarchy::tChildContainer getSiblings( const ObjectHierarchy::tOID& rNode ); - ObjectHierarchy::tCID getParent( const ObjectHierarchy::tCID & rCID ); + ObjectHierarchy::tOID getParent( const ObjectHierarchy::tOID& rOID ); private: void createTree( const Reference< XChartDocument > & xChartDocument ); @@ -149,9 +151,9 @@ private: const Reference< XChartDocument > & xChartDoc, const Reference< XDiagram > & xDiagram ); void createDiagramTree( - ObjectHierarchy::tChildContainer & rContainer, - const Reference< XChartDocument > & xChartDoc, - const Reference< XDiagram > & xDiagram ); + ObjectHierarchy::tChildContainer& rContainer, + const Reference< XChartDocument >& xChartDoc, + const Reference< XDiagram >& xDiagram ); void createDataSeriesTree( ObjectHierarchy::tChildContainer & rOutDiagramSubContainer, const Reference< XDiagram > & xDiagram ); @@ -162,22 +164,23 @@ private: ObjectHierarchy::tChildContainer & rContainer, const Reference< XChartDocument > & xChartDoc, const Reference< XDiagram > & xDiagram ); + void createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer ); - ObjectHierarchy::tCID getParentImpl( - const ObjectHierarchy::tCID & rParentCID, - const ObjectHierarchy::tCID & rCID ); + ObjectHierarchy::tOID getParentImpl( + const ObjectHierarchy::tOID& rParentOID, + const ObjectHierarchy::tOID& rOID ); - typedef ::std::map< OUString, ObjectHierarchy::tChildContainer > + typedef ::std::map< ObjectHierarchy::tOID, ObjectHierarchy::tChildContainer > tChildMap; tChildMap m_aChildMap; - ExplicitValueProvider * m_pExplicitValueProvider; + ExplicitValueProvider* m_pExplicitValueProvider; bool m_bFlattenDiagram; bool m_bOrderingForElementSelector; }; ImplObjectHierarchy::ImplObjectHierarchy( - const Reference< XChartDocument > & xChartDocument, - ExplicitValueProvider * pExplicitValueProvider, + const Reference< XChartDocument >& xChartDocument, + ExplicitValueProvider* pExplicitValueProvider, bool bFlattenDiagram, bool bOrderingForElementSelector ) : m_pExplicitValueProvider( pExplicitValueProvider ), @@ -189,15 +192,15 @@ ImplObjectHierarchy::ImplObjectHierarchy( m_pExplicitValueProvider = 0; } -void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChartDocument ) +void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartDocument ) { - if( !xChartDocument.is()) + if( !xChartDocument.is() ) return; //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY ); Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ) ); - OUString aDiaCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel )); + ObjectHierarchy::tOID aDiaOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) ) ); ObjectHierarchy::tChildContainer aTopLevelContainer; // First Level @@ -205,8 +208,8 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChart // Chart Area if( m_bOrderingForElementSelector ) { - aTopLevelContainer.push_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ); - aTopLevelContainer.push_back( aDiaCID ); + aTopLevelContainer.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) ); + aTopLevelContainer.push_back( aDiaOID ); createWallAndFloor( aTopLevelContainer, xDiagram ); createLegendTree( aTopLevelContainer, xChartDocument, xDiagram ); } @@ -218,7 +221,7 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChart Reference< XTitle > xMainTitle( xDocTitled->getTitleObject()); if( xMainTitle.is()) aTopLevelContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel )); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ) ) ); } if( xDiagram.is()) @@ -230,7 +233,7 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChart Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject()); if( xSubTitle.is()) aTopLevelContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel )); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ) ) ); } if( !m_bOrderingForElementSelector ) @@ -241,7 +244,7 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChart lcl_addAxisTitle( aAxes[i], aTopLevelContainer, xModel ); // Diagram - aTopLevelContainer.push_back( aDiaCID ); + aTopLevelContainer.push_back( aDiaOID ); } if( m_bFlattenDiagram ) @@ -250,21 +253,27 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChart { ObjectHierarchy::tChildContainer aSubContainer; createDiagramTree( aSubContainer, xChartDocument, xDiagram ); - if( ! aSubContainer.empty()) - m_aChildMap[ aDiaCID ] = aSubContainer; + if( !aSubContainer.empty() ) + m_aChildMap[ aDiaOID ] = aSubContainer; } if( !m_bOrderingForElementSelector ) createLegendTree( aTopLevelContainer, xChartDocument, xDiagram ); } + // #i12587# support for shapes in chart + if ( !m_bOrderingForElementSelector ) + { + createAdditionalShapesTree( aTopLevelContainer ); + } + // Chart Area if( !m_bOrderingForElementSelector ) aTopLevelContainer.push_back( - ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) ); if( ! aTopLevelContainer.empty()) - m_aChildMap[ ObjectHierarchy::getRootNodeCID() ] = aTopLevelContainer; + m_aChildMap[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer; } void ImplObjectHierarchy::createLegendTree( @@ -274,18 +283,18 @@ void ImplObjectHierarchy::createLegendTree( { if( xDiagram.is() && LegendHelper::hasLegend( xDiagram ) ) { - OUString aLegendCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram->getLegend(), Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) )); - rContainer.push_back( aLegendCID ); + ObjectHierarchy::tOID aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram->getLegend(), Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ) ); + rContainer.push_back( aLegendOID ); // iterate over child shapes of legend and search for matching CIDs if( m_pExplicitValueProvider ) { Reference< container::XIndexAccess > xLegendShapeContainer( - m_pExplicitValueProvider->getShapeForCID( aLegendCID ), uno::UNO_QUERY ); - ObjectHierarchy::tChildContainer aLegendEntryCIDs; - lcl_getChildCIDs( aLegendEntryCIDs, xLegendShapeContainer ); + m_pExplicitValueProvider->getShapeForCID( aLegendOID.getObjectCID() ), uno::UNO_QUERY ); + ObjectHierarchy::tChildContainer aLegendEntryOIDs; + lcl_getChildOIDs( aLegendEntryOIDs, xLegendShapeContainer ); - m_aChildMap[ aLegendCID ] = aLegendEntryCIDs; + m_aChildMap[ aLegendOID ] = aLegendEntryOIDs; } } } @@ -305,7 +314,7 @@ void ImplObjectHierarchy::createAxesTree( if( !m_bOrderingForElementSelector ) ::std::transform( aAxes.getConstArray(), aAxes.getConstArray() + aAxes.getLength(), ::std::back_inserter( rContainer ), - lcl_ObjectToCID( xChartDoc )); + lcl_ObjectToOID( xChartDoc )); // get all axes, also invisible ones aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ false ); @@ -329,7 +338,7 @@ void ImplObjectHierarchy::createAxesTree( // axis if( AxisHelper::isAxisVisible( xAxis ) ) rContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel ) ); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel ) ) ); // axis title lcl_addAxisTitle( aAxes[nA], rContainer, xChartModel ); @@ -340,7 +349,7 @@ void ImplObjectHierarchy::createAxesTree( { //main grid rContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) ); + ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) ) ) ); } Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );; @@ -352,7 +361,7 @@ void ImplObjectHierarchy::createAxesTree( { //sub grid rContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) ); + ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) ) ) ); } } } @@ -369,12 +378,12 @@ void ImplObjectHierarchy::createWallAndFloor( if( bHasWall && bIsThreeD ) { rContainer.push_back( - ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString())); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) ) ); Reference< beans::XPropertySet > xFloor( xDiagram->getFloor()); if( xFloor.is()) rContainer.push_back( - ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, rtl::OUString())); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, rtl::OUString() ) ) ); } } @@ -426,9 +435,9 @@ void ImplObjectHierarchy::createDataSeriesTree( OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx )); - ObjectHierarchy::tCID aSeriesCID( - ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle )); - rOutDiagramSubContainer.push_back( aSeriesCID ); + ObjectHierarchy::tOID aSeriesOID( + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ) ) ); + rOutDiagramSubContainer.push_back( aSeriesOID ); ObjectHierarchy::tChildContainer aSeriesSubContainer; @@ -440,7 +449,7 @@ void ImplObjectHierarchy::createDataSeriesTree( rtl::OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) ); aChildParticle+=(C2U("=")); aSeriesSubContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle )); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle ) ) ); } // Statistics @@ -454,11 +463,11 @@ void ImplObjectHierarchy::createDataSeriesTree( { bool bIsAverageLine = RegressionCurveHelper::isMeanValueLine( aCurves[nCurveIdx] ); aSeriesSubContainer.push_back( - ObjectIdentifier::createDataCurveCID( aSeriesParticle, nCurveIdx, bIsAverageLine )); + ObjectIdentifier( ObjectIdentifier::createDataCurveCID( aSeriesParticle, nCurveIdx, bIsAverageLine ) ) ); if( RegressionCurveHelper::hasEquation( aCurves[nCurveIdx] ) ) { aSeriesSubContainer.push_back( - ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle, nCurveIdx )); + ObjectIdentifier( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle, nCurveIdx ) ) ); } } Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY ); @@ -472,8 +481,8 @@ void ImplObjectHierarchy::createDataSeriesTree( ( nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE ) ) { aSeriesSubContainer.push_back( - ObjectIdentifier::createClassifiedIdentifierWithParent( - OBJECTTYPE_DATA_ERRORS, OUString(), aSeriesParticle )); + ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent( + OBJECTTYPE_DATA_ERRORS, OUString(), aSeriesParticle ) ) ); } } } @@ -484,12 +493,12 @@ void ImplObjectHierarchy::createDataSeriesTree( if( m_pExplicitValueProvider ) { Reference< container::XIndexAccess > xSeriesShapeContainer( - m_pExplicitValueProvider->getShapeForCID( aSeriesCID ), uno::UNO_QUERY ); - lcl_getChildCIDs( aSeriesSubContainer, xSeriesShapeContainer ); + m_pExplicitValueProvider->getShapeForCID( aSeriesOID.getObjectCID() ), uno::UNO_QUERY ); + lcl_getChildOIDs( aSeriesSubContainer, xSeriesShapeContainer ); } if( ! aSeriesSubContainer.empty()) - m_aChildMap[ aSeriesCID ] = aSeriesSubContainer; + m_aChildMap[ aSeriesOID ] = aSeriesSubContainer; } } } @@ -500,9 +509,38 @@ void ImplObjectHierarchy::createDataSeriesTree( } } -bool ImplObjectHierarchy::hasChildren( const OUString & rParent ) +void ImplObjectHierarchy::createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer ) { - if( rParent.getLength()) + try + { + if ( m_pExplicitValueProvider ) + { + Reference< drawing::XDrawPage > xDrawPage( m_pExplicitValueProvider->getDrawModelWrapper()->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 ) + { + rContainer.push_back( ObjectIdentifier( xShape ) ); + } + } + } + } + } + catch ( uno::Exception& ex ) + { + ASSERT_EXCEPTION( ex ); + } +} + +bool ImplObjectHierarchy::hasChildren( const ObjectHierarchy::tOID& rParent ) +{ + if ( rParent.isValid() ) { tChildMap::const_iterator aIt( m_aChildMap.find( rParent )); if( aIt != m_aChildMap.end()) @@ -511,9 +549,9 @@ bool ImplObjectHierarchy::hasChildren( const OUString & rParent ) return false; } -ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const OUString & rParent ) +ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID& rParent ) { - if( rParent.getLength()) + if ( rParent.isValid() ) { tChildMap::const_iterator aIt( m_aChildMap.find( rParent )); if( aIt != m_aChildMap.end()) @@ -522,9 +560,9 @@ ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const OUStrin return ObjectHierarchy::tChildContainer(); } -ObjectHierarchy::tChildContainer ImplObjectHierarchy::getSiblings( const OUString & rNode ) +ObjectHierarchy::tChildContainer ImplObjectHierarchy::getSiblings( const ObjectHierarchy::tOID& rNode ) { - if( rNode.getLength() && !ObjectHierarchy::isRootNode( rNode )) + if ( rNode.isValid() && !ObjectHierarchy::isRootNode( rNode ) ) { for( tChildMap::const_iterator aIt( m_aChildMap.begin()); aIt != m_aChildMap.end(); ++aIt ) @@ -538,23 +576,23 @@ ObjectHierarchy::tChildContainer ImplObjectHierarchy::getSiblings( const OUStrin return ObjectHierarchy::tChildContainer(); } -ObjectHierarchy::tCID ImplObjectHierarchy::getParentImpl( - const ObjectHierarchy::tCID & rParentCID, - const ObjectHierarchy::tCID & rCID ) +ObjectHierarchy::tOID ImplObjectHierarchy::getParentImpl( + const ObjectHierarchy::tOID & rParentOID, + const ObjectHierarchy::tOID & rOID ) { // search children - ObjectHierarchy::tChildContainer aChildren( getChildren( rParentCID )); + ObjectHierarchy::tChildContainer aChildren( getChildren( rParentOID )); ObjectHierarchy::tChildContainer::const_iterator aIt( - ::std::find( aChildren.begin(), aChildren.end(), rCID )); + ::std::find( aChildren.begin(), aChildren.end(), rOID )); // recursion end if( aIt != aChildren.end()) - return rParentCID; + return rParentOID; for( aIt = aChildren.begin(); aIt != aChildren.end(); ++aIt ) { // recursion - ObjectHierarchy::tCID aTempParent( getParentImpl( *aIt, rCID )); - if( aTempParent.getLength()) + ObjectHierarchy::tOID aTempParent( getParentImpl( *aIt, rOID )); + if ( aTempParent.isValid() ) { // exit on success return aTempParent; @@ -562,17 +600,18 @@ ObjectHierarchy::tCID ImplObjectHierarchy::getParentImpl( } // exit on fail - return ObjectHierarchy::tCID(); + return ObjectHierarchy::tOID(); } -ObjectHierarchy::tCID ImplObjectHierarchy::getParent( - const ObjectHierarchy::tCID & rCID ) +ObjectHierarchy::tOID ImplObjectHierarchy::getParent( + const ObjectHierarchy::tOID & rOID ) { - return getParentImpl( ObjectHierarchy::getRootNodeCID(), rCID ); + return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID ); } } // namespace impl + ObjectHierarchy::ObjectHierarchy( const Reference< XChartDocument > & xChartDocument, ExplicitValueProvider * pExplicitValueProvider /* = 0 */, @@ -585,60 +624,60 @@ ObjectHierarchy::~ObjectHierarchy() {} // static -ObjectHierarchy::tCID ObjectHierarchy::getRootNodeCID() +ObjectHierarchy::tOID ObjectHierarchy::getRootNodeOID() { - return C2U("ROOT"); + return ObjectIdentifier( C2U( "ROOT" ) ); } // static -bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tCID & rCID ) +bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID& rOID ) { - return rCID.equals( ObjectHierarchy::getRootNodeCID()); + return ( rOID == ObjectHierarchy::getRootNodeOID() ); } ObjectHierarchy::tChildContainer ObjectHierarchy::getTopLevelChildren() const { - return m_apImpl->getChildren( ObjectHierarchy::getRootNodeCID()); + return m_apImpl->getChildren( ObjectHierarchy::getRootNodeOID()); } -bool ObjectHierarchy::hasChildren( const tCID & rParent ) const +bool ObjectHierarchy::hasChildren( const tOID& rParent ) const { return m_apImpl->hasChildren( rParent ); } ObjectHierarchy::tChildContainer ObjectHierarchy::getChildren( - const ObjectHierarchy::tCID & rParent ) const + const ObjectHierarchy::tOID& rParent ) const { - if( rParent.getLength()) + if ( rParent.isValid() ) return m_apImpl->getChildren( rParent ); return ObjectHierarchy::tChildContainer(); } ObjectHierarchy::tChildContainer ObjectHierarchy::getSiblings( - const ObjectHierarchy::tCID & rNode ) const + const ObjectHierarchy::tOID& rNode ) const { - if( rNode.getLength() && !isRootNode( rNode )) + if ( rNode.isValid() && !isRootNode( rNode ) ) return m_apImpl->getSiblings( rNode ); return ObjectHierarchy::tChildContainer(); } -ObjectHierarchy::tCID ObjectHierarchy::getParent( - const ObjectHierarchy::tCID & rNode ) const +ObjectHierarchy::tOID ObjectHierarchy::getParent( + const ObjectHierarchy::tOID& rNode ) const { return m_apImpl->getParent( rNode ); } sal_Int32 ObjectHierarchy::getIndexInParent( - const ObjectHierarchy::tCID & rNode ) const + const ObjectHierarchy::tOID& rNode ) const { - tCID aParentCID( m_apImpl->getParent( rNode )); - tChildContainer aChildren( m_apImpl->getChildren( aParentCID )); - tChildContainer::const_iterator aIt( aChildren.begin()); + tOID aParentOID( m_apImpl->getParent( rNode )); + tChildContainer aChildren( m_apImpl->getChildren( aParentOID ) ); + tChildContainer::const_iterator aIt( aChildren.begin() ); for( sal_Int32 nIndex = 0; aIt != aChildren.end(); ++nIndex, ++aIt ) { - if( aIt->equals( rNode )) + if ( *aIt == rNode ) return nIndex; } return -1; @@ -647,16 +686,18 @@ sal_Int32 ObjectHierarchy::getIndexInParent( // ================================================================================ ObjectKeyNavigation::ObjectKeyNavigation( - const ObjectHierarchy::tCID & rCurrentCID, + const ObjectHierarchy::tOID & rCurrentOID, const Reference< chart2::XChartDocument > & xChartDocument, ExplicitValueProvider * pExplicitValueProvider /* = 0 */ ) : - m_aCurrentCID( rCurrentCID ), + m_aCurrentOID( rCurrentOID ), m_xChartDocument( xChartDocument ), m_pExplicitValueProvider( pExplicitValueProvider ), m_bStepDownInDiagram( true ) { - if( m_aCurrentCID.getLength() == 0 ) - setCurrentSelection( ObjectHierarchy::getRootNodeCID()); + if ( !m_aCurrentOID.isValid() ) + { + setCurrentSelection( ObjectHierarchy::getRootNodeOID() ); + } } bool ObjectKeyNavigation::handleKeyEvent( @@ -685,7 +726,7 @@ bool ObjectKeyNavigation::handleKeyEvent( bResult = down(); break; case awt::Key::ESCAPE: - setCurrentSelection( OUString()); + setCurrentSelection( ObjectIdentifier() ); bResult = true; break; default: @@ -695,20 +736,20 @@ bool ObjectKeyNavigation::handleKeyEvent( return bResult; } -void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tCID & rCID ) +void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID& rOID ) { - m_aCurrentCID = rCID; + m_aCurrentOID = rOID; } -ObjectHierarchy::tCID ObjectKeyNavigation::getCurrentSelection() const +ObjectHierarchy::tOID ObjectKeyNavigation::getCurrentSelection() const { - return m_aCurrentCID; + return m_aCurrentOID; } bool ObjectKeyNavigation::first() { ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram ); - ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection())); + ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) ); bool bResult = !aSiblings.empty(); if( bResult ) setCurrentSelection( aSiblings.front()); @@ -720,7 +761,7 @@ bool ObjectKeyNavigation::first() bool ObjectKeyNavigation::last() { ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram ); - ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection())); + ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) ); bool bResult = !aSiblings.empty(); if( bResult ) setCurrentSelection( aSiblings.back()); @@ -732,7 +773,7 @@ bool ObjectKeyNavigation::last() bool ObjectKeyNavigation::next() { ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram ); - ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection())); + ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) ); bool bResult = !aSiblings.empty(); if( bResult ) { diff --git a/chart2/source/controller/main/SelectionHelper.cxx b/chart2/source/controller/main/SelectionHelper.cxx index 0d0dddef169d..567a36473a5b 100644 --- a/chart2/source/controller/main/SelectionHelper.cxx +++ b/chart2/source/controller/main/SelectionHelper.cxx @@ -80,25 +80,29 @@ void impl_selectObject( SdrObject* pObjectToSelect, DrawViewWrapper& rDrawViewWr bool Selection::hasSelection() { - return m_aSelectedObjectCID.getLength() || m_xSelectAdditionalShape.is(); + return m_aSelectedOID.isValid(); } rtl::OUString Selection::getSelectedCID() { - return m_aSelectedObjectCID; + return m_aSelectedOID.getObjectCID(); } uno::Reference< drawing::XShape > Selection::getSelectedAdditionalShape() { - return m_xSelectAdditionalShape; + return m_aSelectedOID.getAdditionalShape(); +} + +ObjectIdentifier Selection::getSelectedOID() const +{ + return m_aSelectedOID; } bool Selection::setSelection( const ::rtl::OUString& rCID ) { - if( !rCID.equals( m_aSelectedObjectCID ) ) + if ( !rCID.equals( m_aSelectedOID.getObjectCID() ) ) { - m_aSelectedObjectCID = rCID; - m_xSelectAdditionalShape.set(0); + m_aSelectedOID = ObjectIdentifier( rCID ); return true; } return false; @@ -106,10 +110,10 @@ bool Selection::setSelection( const ::rtl::OUString& rCID ) bool Selection::setSelection( const uno::Reference< drawing::XShape >& xShape ) { - if( !(m_xSelectAdditionalShape==xShape) ) + if ( !( xShape == m_aSelectedOID.getAdditionalShape() ) ) { clearSelection(); - m_xSelectAdditionalShape = xShape; + m_aSelectedOID = ObjectIdentifier( xShape ); return true; } return false; @@ -117,18 +121,18 @@ bool Selection::setSelection( const uno::Reference< drawing::XShape >& xShape ) void Selection::clearSelection() { - m_aSelectedObjectCID = m_aSelectedObjectCID_beforeMouseDown - = m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = rtl::OUString(); - m_xSelectAdditionalShape.set(0); + m_aSelectedOID = ObjectIdentifier(); + m_aSelectedOID_beforeMouseDown = ObjectIdentifier(); + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier(); } bool Selection::maybeSwitchSelectionAfterSingleClickWasEnsured() { - if( m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength() - && !m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.equals(m_aSelectedObjectCID) ) + if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() + && m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing != m_aSelectedOID ) { - m_aSelectedObjectCID = m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing; - m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U(""); + m_aSelectedOID = m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing; + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier(); return true; } return false; @@ -136,18 +140,20 @@ bool Selection::maybeSwitchSelectionAfterSingleClickWasEnsured() void Selection::resetPossibleSelectionAfterSingleClickWasEnsured() { - if( m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength() ) - m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U(""); + if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() ) + { + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier(); + } } void Selection::remindSelectionBeforeMouseDown() { - m_aSelectedObjectCID_beforeMouseDown = m_aSelectedObjectCID; + m_aSelectedOID_beforeMouseDown = m_aSelectedOID; } bool Selection::isSelectionDifferentFromBeforeMouseDown() { - return !ObjectIdentifier::areIdenticalObjects( m_aSelectedObjectCID, m_aSelectedObjectCID_beforeMouseDown ); + return ( m_aSelectedOID != m_aSelectedOID_beforeMouseDown ); } void Selection::applySelection( DrawViewWrapper* pDrawViewWrapper ) @@ -159,10 +165,14 @@ void Selection::applySelection( DrawViewWrapper* pDrawViewWrapper ) pDrawViewWrapper->UnmarkAll(); } SdrObject* pObjectToSelect = 0; - if( m_aSelectedObjectCID.getLength() ) - pObjectToSelect = pDrawViewWrapper->getNamedSdrObject( m_aSelectedObjectCID ); - else if( m_xSelectAdditionalShape.is() ) - pObjectToSelect = DrawViewWrapper::getSdrObject( m_xSelectAdditionalShape ); + if ( m_aSelectedOID.isAutoGeneratedObject() ) + { + pObjectToSelect = pDrawViewWrapper->getNamedSdrObject( m_aSelectedOID.getObjectCID() ); + } + else if( m_aSelectedOID.isAdditionalShape() ) + { + pObjectToSelect = DrawViewWrapper::getSdrObject( m_aSelectedOID.getAdditionalShape() ); + } impl_selectObject( pObjectToSelect, *pDrawViewWrapper ); } @@ -176,7 +186,7 @@ void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* //do not toggel multiclick selection if right clicked on the selected object or waiting for double click bool bAllowMultiClickSelectionChange = !bIsRightMouse && !bWaitingForDoubleClick; - const rtl::OUString aNameOfLastSelectedObject( m_aSelectedObjectCID ); + ObjectIdentifier aLastSelectedObject( m_aSelectedOID ); ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); @@ -185,86 +195,89 @@ void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* //get object to select: SdrObject* pNewObj = 0; { - m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U(""); - m_xSelectAdditionalShape.set(0); + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier(); //the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree) //further we travel along the grouping hierarchy from child to parent pNewObj = pDrawViewWrapper->getHitObject(rMousePos); - m_aSelectedObjectCID = lcl_getObjectName( pNewObj );//name of pNewObj - rtl::OUString aTestFirstHit = m_aSelectedObjectCID; + m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) );//name of pNewObj //ignore handle only objects for hit test - while( pNewObj && m_aSelectedObjectCID.match(C2U("HandlesOnly")) ) + while( pNewObj && m_aSelectedOID.getObjectCID().match( C2U( "HandlesOnly" ) ) ) { pNewObj->SetMarkProtect(true); pNewObj = pDrawViewWrapper->getHitObject(rMousePos); - m_aSelectedObjectCID = lcl_getObjectName( pNewObj ); + m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) ); } //accept only named objects while searching for the object to select - //this call may change m_aSelectedObjectCID - if( SelectionHelper::findNamedParent( pNewObj, m_aSelectedObjectCID, true ) ) + //this call may change m_aSelectedOID + if ( SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, true ) ) { //if the so far found object is a multi click object further steps are necessary - while( ObjectIdentifier::isMultiClickObject( m_aSelectedObjectCID ) ) + while( ObjectIdentifier::isMultiClickObject( m_aSelectedOID.getObjectCID() ) ) { - bool bSameObjectAsLastSelected = ObjectIdentifier::areIdenticalObjects( aNameOfLastSelectedObject, m_aSelectedObjectCID ); + bool bSameObjectAsLastSelected = ( aLastSelectedObject == m_aSelectedOID ); if( bSameObjectAsLastSelected ) { //if the same child is clicked again don't go up further break; } - if( ObjectIdentifier::areSiblings(aNameOfLastSelectedObject,m_aSelectedObjectCID) ) + if ( ObjectIdentifier::areSiblings( aLastSelectedObject.getObjectCID(), m_aSelectedOID.getObjectCID() ) ) { //if a sibling of the last selected object is clicked don't go up further break; } SdrObject* pLastChild = pNewObj; - rtl::OUString aLastChildName = m_aSelectedObjectCID; - if(!SelectionHelper::findNamedParent( pNewObj, m_aSelectedObjectCID, false )) + ObjectIdentifier aLastChild = m_aSelectedOID; + if ( !SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, false ) ) { //take the one found so far break; } //if the last selected object is found don't go up further //but take the last child if selection change is allowed - if( ObjectIdentifier::areIdenticalObjects( aNameOfLastSelectedObject, m_aSelectedObjectCID ) ) + if ( aLastSelectedObject == m_aSelectedOID ) { if( bAllowMultiClickSelectionChange ) { pNewObj = pLastChild; - m_aSelectedObjectCID = aLastChildName; + m_aSelectedOID = aLastChild; } else - m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = aLastChildName; + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = aLastChild; break; } } - DBG_ASSERT(pNewObj && m_aSelectedObjectCID.getLength(),"somehow lost selected object"); + DBG_ASSERT( pNewObj && m_aSelectedOID.isValid(), "somehow lost selected object" ); } else { //maybe an additional shape was hit - m_aSelectedObjectCID = rtl::OUString(); - if( pNewObj ) + if ( pNewObj ) + { + m_aSelectedOID = ObjectIdentifier( uno::Reference< drawing::XShape >( pNewObj->getUnoShape(), uno::UNO_QUERY ) ); + } + else { - m_xSelectAdditionalShape = uno::Reference< drawing::XShape >( pNewObj->getUnoShape(), uno::UNO_QUERY); + m_aSelectedOID = ObjectIdentifier(); } } - if(!m_xSelectAdditionalShape.is()) + if ( !m_aSelectedOID.isAdditionalShape() ) { rtl::OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );//@todo read CID from model - if( !m_aSelectedObjectCID.getLength() ) - m_aSelectedObjectCID = aPageCID; + if ( !m_aSelectedOID.isAutoGeneratedObject() ) + { + m_aSelectedOID = ObjectIdentifier( aPageCID ); + } //check wether the diagram was hit but not selected (e.g. because it has no filling): rtl::OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) );//@todo read CID from model - if( m_aSelectedObjectCID.equals( aPageCID ) || m_aSelectedObjectCID.equals( aWallCID ) || !m_aSelectedObjectCID.getLength() ) + if ( m_aSelectedOID.getObjectCID().equals( aPageCID ) || m_aSelectedOID.getObjectCID().equals( aWallCID ) || !m_aSelectedOID.isAutoGeneratedObject() ) { rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) ); //todo: if more than one diagram is available in future do chack the list of all diagrams here @@ -273,7 +286,7 @@ void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* { if( pDrawViewWrapper->IsObjectHit( pDiagram, rMousePos ) ) { - m_aSelectedObjectCID = aDiagramCID; + m_aSelectedOID = ObjectIdentifier( aDiagramCID ); pNewObj = pDiagram; } } @@ -281,18 +294,21 @@ void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* } } - if( bIsRightMouse && m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength() ) - m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U(""); + if ( bIsRightMouse && m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() ) + { + m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier(); + } } } bool Selection::isResizeableObjectSelected() { - ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelectedObjectCID ); + ObjectType eObjectType = m_aSelectedOID.getObjectType(); switch( eObjectType ) { case OBJECTTYPE_DIAGRAM: case OBJECTTYPE_DIAGRAM_WALL: + case OBJECTTYPE_SHAPE: return true; default: return false; @@ -302,14 +318,17 @@ bool Selection::isResizeableObjectSelected() bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel ) { - return SelectionHelper::isRotateableObject( m_aSelectedObjectCID, xChartModel ); + return SelectionHelper::isRotateableObject( m_aSelectedOID.getObjectCID(), xChartModel ); } bool Selection::isDragableObjectSelected() { - if( m_aSelectedObjectCID.getLength() ) - return ObjectIdentifier::isDragableObject( m_aSelectedObjectCID ); - return m_xSelectAdditionalShape.is(); + return m_aSelectedOID.isDragableObject(); +} + +bool Selection::isAdditionalShapeSelected() const +{ + return m_aSelectedOID.isAdditionalShape(); } //----------------------------------------------------------------------------- @@ -351,6 +370,20 @@ bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject } //static +bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject + , ObjectIdentifier& rOutObject + , bool bGivenObjectMayBeResult ) +{ + rtl::OUString aName; + if ( findNamedParent( pInOutObject, aName, bGivenObjectMayBeResult ) ) + { + rOutObject = ObjectIdentifier( aName ); + return true; + } + return false; +} + +//static bool SelectionHelper::isDragableObjectHitTwice( const Point& rMPos , const rtl::OUString& rNameOfSelectedObject , const DrawViewWrapper& rDrawViewWrapper ) @@ -366,107 +399,6 @@ bool SelectionHelper::isDragableObjectHitTwice( const Point& rMPos return true; } -/* -rtl::OUString lcl_getObjectCIDToSelect( const Point& rMPos - , const rtl::OUString& rNameOfLastSelectedObject - , DrawViewWrapper& rDrawViewWrapper - , bool bAllowMultiClickSelectionChange - , rtl::OUString& rObjectToSelectIfNoDoubleClickIsFollowing //out parameter only - ) -{ - rtl::OUString aRet; - - ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); - - //bAllowMultiClickSelectionChange==true -> a second click on the same object can lead to a changed selection (e.g. series -> single data point) - - //get object to select: - SdrObject* pNewObj = 0; - { - rObjectToSelectIfNoDoubleClickIsFollowing = C2U(""); - - //the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree) - //further we travel along the grouping hierarchy from child to parent - pNewObj = rDrawViewWrapper.getHitObject(rMPos); - aRet = lcl_getObjectName( pNewObj );//name of pNewObj - rtl::OUString aTestFirstHit = aRet; - - //ignore handle only objects for hit test - while( pNewObj && aRet.match(C2U("HandlesOnly")) ) - { - pNewObj->SetMarkProtect(true); - pNewObj = rDrawViewWrapper.getHitObject(rMPos); - aRet = lcl_getObjectName( pNewObj ); - } - - //accept only named objects while searching for the object to select - //this call may change aRet - if( !findNamedParent( pNewObj, aRet, true ) ) - { - return C2U(""); - } - //if the so far found object is a multi click object further steps are necessary - while( ObjectIdentifier::isMultiClickObject( aRet ) ) - { - bool bSameObjectAsLastSelected = ObjectIdentifier::areIdenticalObjects( rNameOfLastSelectedObject, aRet ); - if( bSameObjectAsLastSelected ) - { - //if the same child is clicked again don't go up further - break; - } - if( ObjectIdentifier::areSiblings(rNameOfLastSelectedObject,aRet) ) - { - //if a sibling of the last selected object is clicked don't go up further - break; - } - SdrObject* pLastChild = pNewObj; - rtl::OUString aLastChildName = aRet; - if(!findNamedParent( pNewObj, aRet, false )) - { - //take the one found so far - break; - } - //if the last selected object is found don't go up further - //but take the last child if selection change is allowed - if( ObjectIdentifier::areIdenticalObjects( rNameOfLastSelectedObject, aRet ) ) - { - if( bAllowMultiClickSelectionChange ) - { - pNewObj = pLastChild; - aRet = aLastChildName; - } - else - rObjectToSelectIfNoDoubleClickIsFollowing = aLastChildName; - - break; - } - } - - //check wether the diagram was hit but not selected: - rtl::OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );//@todo read CID from model - rtl::OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) );//@todo read CID from model - if( aRet.equals( aPageCID ) || aRet.equals( aWallCID ) || !aRet.getLength() ) - { - rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) ); - //todo: if more than one diagram is available in future do chack the list of all diagrams here - SdrObject* pDiagram = rDrawViewWrapper.getNamedSdrObject( aDiagramCID ); - if( pDiagram ) - { - if( rDrawViewWrapper.IsObjectHit( pDiagram, rMPos ) ) - { - aRet = aDiagramCID; - pNewObj = pDiagram; - } - } - } - - DBG_ASSERT(pNewObj && aRet.getLength(),"somehow lost selected object"); - } - - return aRet; -} -*/ - // static ::rtl::OUString SelectionHelper::getHitObjectCID( const Point& rMPos, diff --git a/chart2/source/controller/main/SelectionHelper.hxx b/chart2/source/controller/main/SelectionHelper.hxx index 12b3ef9948ac..b3516e2326a4 100644 --- a/chart2/source/controller/main/SelectionHelper.hxx +++ b/chart2/source/controller/main/SelectionHelper.hxx @@ -28,6 +28,7 @@ #define _CHART2_SELECTIONHELPER_HXX #include "DrawViewWrapper.hxx" +#include "ObjectIdentifier.hxx" class SdrObject; // header for enum SdrDragMode @@ -39,6 +40,8 @@ namespace chart { //............................................................................. +class ObjectIdentifier; + //----------------------------------------------------------------------------- /** */ @@ -50,12 +53,15 @@ public: //methods rtl::OUString getSelectedCID(); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > getSelectedAdditionalShape(); + ObjectIdentifier getSelectedOID() const; bool isResizeableObjectSelected(); bool isRotateableObjectSelected( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel ); bool isDragableObjectSelected(); + bool isAdditionalShapeSelected() const; + //returns true if selection has changed bool setSelection( const ::rtl::OUString& rCID ); bool setSelection( const ::com::sun::star::uno::Reference< @@ -81,12 +87,9 @@ private: //member //the content of m_xSelectedShape is ignored in that case //the strings are used for autogenerated chart specific objects //the shape reference is used for additional shapes - ::rtl::OUString m_aSelectedObjectCID;//only single object selection so far - ::rtl::OUString m_aSelectedObjectCID_beforeMouseDown; - ::rtl::OUString m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing; - - ::com::sun::star::uno::Reference< - ::com::sun::star::drawing::XShape > m_xSelectAdditionalShape; + ObjectIdentifier m_aSelectedOID; //only single object selection so far + ObjectIdentifier m_aSelectedOID_beforeMouseDown; + ObjectIdentifier m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing; }; class SelectionHelper : public MarkHandleProvider @@ -95,6 +98,9 @@ public: static bool findNamedParent( SdrObject*& pInOutObject , rtl::OUString& rOutName , bool bGivenObjectMayBeResult ); + static bool findNamedParent( SdrObject*& pInOutObject + , ObjectIdentifier& rOutObject + , bool bGivenObjectMayBeResult ); static SdrObject* getMarkHandlesObject( SdrObject* pObj ); static E3dScene* getSceneToRotate( SdrObject* pObj ); static bool isDragableObjectHitTwice( const Point& rMPos diff --git a/chart2/source/controller/main/ShapeController.cxx b/chart2/source/controller/main/ShapeController.cxx new file mode 100644 index 000000000000..b6adf9bf7477 --- /dev/null +++ b/chart2/source/controller/main/ShapeController.cxx @@ -0,0 +1,738 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "ShapeController.hxx" +#include "ShapeController.hrc" +#include "ChartController.hxx" +#include "ChartWindow.hxx" +#include "ViewElementListProvider.hxx" +#include "dlg_ShapeFont.hxx" +#include "dlg_ShapeParagraph.hxx" +#include "chartview/DrawModelWrapper.hxx" +#include "macros.hxx" + +#include <com/sun/star/frame/XStorable.hpp> + +#include <vos/mutex.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/svapp.hxx> +#include <editeng/brkitem.hxx> +#include <svx/dialogs.hrc> +#include <svx/drawitem.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/hyznitem.hxx> +#include <editeng/orphitem.hxx> +#include <editeng/spltitem.hxx> +#include <svx/svxdlg.hxx> +#include <editeng/widwitem.hxx> + +#include <boost/scoped_ptr.hpp> + +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() +{ +} + +void ShapeController::initialize() +{ + FeatureCommandDispatchBase::initialize(); +} + +// WeakComponentImplHelperBase +void ShapeController::disposing() +{ +} + +// XEventListener +void ShapeController::disposing( const lang::EventObject& /* Source */ ) + throw (uno::RuntimeException) +{ +} + +FeatureState ShapeController::getState( const ::rtl::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 ::rtl::OUString& rCommand, const Sequence< beans::PropertyValue>& rArgs ) +{ + (void)rArgs; + + 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: + { + 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, AbstractSvxNameDialog*, pDialog ) +{ + String aName; + if ( pDialog ) + { + pDialog->GetName( aName ); + } + if ( aName.Len() ) + { + DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : NULL ); + if ( pDrawViewWrapper && pDrawViewWrapper->getNamedSdrObject( aName ) ) + { + return 0; + } + } + return 1; +} + +void ShapeController::executeDispatch_FormatLine() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper(); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawModelWrapper && pDrawViewWrapper ) + { + SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject(); + SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() ); + BOOL bHasMarked = pDrawViewWrapper->AreObjectsMarked(); + if ( bHasMarked ) + { + pDrawViewWrapper->MergeAttrFromMarked( aAttr, FALSE ); + } + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< SfxAbstractTabDialog > pDlg( + pFact->CreateSvxLineTabDialog( pParent, &aAttr, &pDrawModelWrapper->getSdrModel(), + pSelectedObj, bHasMarked ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet(); + if ( bHasMarked ) + { + pDrawViewWrapper->SetAttrToMarked( *pOutAttr, FALSE ); + } + else + { + pDrawViewWrapper->SetDefaultAttr( *pOutAttr, FALSE ); + } + } + } + } + } +} + +void ShapeController::executeDispatch_FormatArea() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper(); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawModelWrapper && pDrawViewWrapper ) + { + SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() ); + BOOL bHasMarked = pDrawViewWrapper->AreObjectsMarked(); + if ( bHasMarked ) + { + pDrawViewWrapper->MergeAttrFromMarked( aAttr, FALSE ); + } + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< AbstractSvxAreaTabDialog > pDlg( + pFact->CreateSvxAreaTabDialog( pParent, &aAttr, &pDrawModelWrapper->getSdrModel(), + pDrawViewWrapper ) ); + if ( pDlg.get() ) + { + SfxItemPool& rItemPool = pDrawViewWrapper->GetModel()->GetItemPool(); + SfxItemSet aSet( rItemPool, rItemPool.GetFirstWhich(), rItemPool.GetLastWhich() ); + const SvxColorTableItem* pColorItem = static_cast< const SvxColorTableItem* >( aSet.GetItem( SID_COLOR_TABLE ) ); + if ( pColorItem && pColorItem->GetColorTable() == XColorTable::GetStdColorTable() ) + { + pDlg->DontDeleteColorTable(); + } + 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() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawViewWrapper ) + { + SfxItemSet aAttr( pDrawViewWrapper->GetDefaultAttr() ); + BOOL bHasMarked = pDrawViewWrapper->AreObjectsMarked(); + if ( bHasMarked ) + { + pDrawViewWrapper->MergeAttrFromMarked( aAttr, FALSE ); + } + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< SfxAbstractTabDialog > pDlg( + pFact->CreateTextTabDialog( pParent, &aAttr, pDrawViewWrapper ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet(); + if ( bHasMarked ) + { + pDrawViewWrapper->SetAttributes( *pOutAttr ); + } + else + { + pDrawViewWrapper->SetDefaultAttr( *pOutAttr, FALSE ); + } + } + } + } + } +} + +void ShapeController::executeDispatch_TransformDialog() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawViewWrapper ) + { + 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() ); + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< SfxAbstractTabDialog > pDlg( + pFact->CreateCaptionDialog( pParent, pDrawViewWrapper ) ); + if ( pDlg.get() ) + { + const USHORT* 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() ); + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< SfxAbstractTabDialog > pDlg( + pFact->CreateSvxTransformTabDialog( pParent, &aGeoAttr, pDrawViewWrapper ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet(); + pDrawViewWrapper->SetGeoAttrToMarked( *pOutAttr ); + } + } + } + } + } +} + +void ShapeController::executeDispatch_ObjectTitleDescription() +{ + if ( m_pChartController ) + { + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pDrawViewWrapper && pDrawViewWrapper->GetMarkedObjectCount() == 1 ) + { + SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject(); + if ( pSelectedObj ) + { + String aTitle( pSelectedObj->GetTitle() ); + String aDescription( pSelectedObj->GetDescription() ); + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< AbstractSvxObjectTitleDescDialog > pDlg( + pFact->CreateSvxObjectTitleDescDialog( NULL, aTitle, aDescription ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + pDlg->GetTitle( aTitle ); + pDlg->GetDescription( aDescription ); + pSelectedObj->SetTitle( aTitle ); + pSelectedObj->SetDescription( aDescription ); + } + } + } + } + } +} + +void ShapeController::executeDispatch_RenameObject() +{ + if ( m_pChartController ) + { + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pDrawViewWrapper && pDrawViewWrapper->GetMarkedObjectCount() == 1 ) + { + SdrObject* pSelectedObj = pDrawViewWrapper->getSelectedObject(); + if ( pSelectedObj ) + { + String aName( pSelectedObj->GetName() ); + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + if ( pFact ) + { + ::boost::scoped_ptr< AbstractSvxObjectNameDialog > pDlg( + pFact->CreateSvxObjectNameDialog( NULL, aName ) ); + pDlg->SetCheckNameHdl( LINK( this, ShapeController, CheckNameHdl ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + pDlg->GetName( aName ); + if ( aName != pSelectedObj->GetName() ) + { + pSelectedObj->SetName( aName ); + } + } + } + } + } + } +} + +void ShapeController::executeDispatch_ChangeZOrder( sal_uInt16 nId ) +{ + DrawViewWrapper* pDrawViewWrapper = ( m_pChartController ? m_pChartController->GetDrawViewWrapper() : NULL ); + if ( pDrawViewWrapper ) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + 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() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawModelWrapper* pDrawModelWrapper = m_pChartController->GetDrawModelWrapper(); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawModelWrapper && pDrawViewWrapper ) + { + SfxItemSet aAttr( pDrawViewWrapper->GetModel()->GetItemPool() ); + pDrawViewWrapper->GetAttributes( aAttr ); + ViewElementListProvider aViewElementListProvider( pDrawModelWrapper ); + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + ::boost::scoped_ptr< ShapeFontDialog > pDlg( new ShapeFontDialog( pParent, &aAttr, &aViewElementListProvider ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet(); + pDrawViewWrapper->SetAttributes( *pOutAttr ); + } + } + } +} + +void ShapeController::executeDispatch_ParagraphDialog() +{ + if ( m_pChartController ) + { + Window* pParent = dynamic_cast< Window* >( m_pChartController->m_pChartWindow ); + DrawViewWrapper* pDrawViewWrapper = m_pChartController->GetDrawViewWrapper(); + if ( pParent && pDrawViewWrapper ) + { + SfxItemPool& rPool = pDrawViewWrapper->GetModel()->GetItemPool(); + SfxItemSet aAttr( rPool ); + pDrawViewWrapper->GetAttributes( aAttr ); + + SfxItemSet aNewAttr( rPool, + EE_ITEMS_START, EE_ITEMS_END, + SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_HYPHENZONE, + SID_ATTR_PARA_PAGEBREAK, SID_ATTR_PARA_PAGEBREAK, + SID_ATTR_PARA_SPLIT, SID_ATTR_PARA_SPLIT, + SID_ATTR_PARA_WIDOWS, SID_ATTR_PARA_WIDOWS, + SID_ATTR_PARA_ORPHANS, SID_ATTR_PARA_ORPHANS, + 0 ); + aNewAttr.Put( aAttr ); + aNewAttr.Put( SvxHyphenZoneItem( sal_False, SID_ATTR_PARA_HYPHENZONE ) ); + aNewAttr.Put( SvxFmtBreakItem( SVX_BREAK_NONE, SID_ATTR_PARA_PAGEBREAK ) ); + aNewAttr.Put( SvxFmtSplitItem( sal_True, SID_ATTR_PARA_SPLIT) ); + aNewAttr.Put( SvxWidowsItem( 0, SID_ATTR_PARA_WIDOWS) ); + aNewAttr.Put( SvxOrphansItem( 0, SID_ATTR_PARA_ORPHANS) ); + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + ::boost::scoped_ptr< ShapeParagraphDialog > pDlg( new ShapeParagraphDialog( pParent, &aNewAttr ) ); + if ( pDlg.get() && ( pDlg->Execute() == RET_OK ) ) + { + const SfxItemSet* pOutAttr = pDlg->GetOutputItemSet(); + pDrawViewWrapper->SetAttributes( *pOutAttr ); + } + } + } +} + +SdrObject* ShapeController::getFirstAdditionalShape() +{ + SdrObject* pFirstObj = NULL; + + try + { + DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : NULL ); + 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 ( uno::Exception& ex ) + { + ASSERT_EXCEPTION( ex ); + } + + return pFirstObj; +} + +SdrObject* ShapeController::getLastAdditionalShape() +{ + SdrObject* pLastObj = NULL; + + try + { + DrawModelWrapper* pDrawModelWrapper = ( m_pChartController ? m_pChartController->GetDrawModelWrapper() : NULL ); + 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 ( uno::Exception& ex ) + { + ASSERT_EXCEPTION( ex ); + } + + return pLastObj; +} + +bool ShapeController::isBackwardPossible() +{ + if ( m_pChartController && m_pChartController->m_aSelection.isAdditionalShapeSelected() ) + { + 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->m_aSelection.isAdditionalShapeSelected() ) + { + 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 +//............................................................................. diff --git a/chart2/source/controller/main/ShapeController.hxx b/chart2/source/controller/main/ShapeController.hxx new file mode 100644 index 000000000000..aea01d6c478d --- /dev/null +++ b/chart2/source/controller/main/ShapeController.hxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_SHAPECONTROLLER_HXX +#define CHART2_SHAPECONTROLLER_HXX + +#include "FeatureCommandDispatchBase.hxx" +#include <tools/link.hxx> + +class AbstractSvxNameDialog; +class SdrObject; + +//............................................................................. +namespace chart +{ +//............................................................................. + +class ChartController; + +/** This is a CommandDispatch implementation for shapes. + */ +class ShapeController: public FeatureCommandDispatchBase +{ + friend class ControllerCommandDispatch; + +public: + ShapeController( const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XComponentContext >& rxContext, ChartController* pController ); + virtual ~ShapeController(); + + // late initialisation, especially for adding as listener + virtual void initialize(); + +protected: + // WeakComponentImplHelperBase + virtual void SAL_CALL disposing(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException); + + // state of a feature + virtual FeatureState getState( const ::rtl::OUString& rCommand ); + + // execute a feature + virtual void execute( const ::rtl::OUString& rCommand, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs ); + + // all the features which should be handled by this class + virtual void describeSupportedFeatures(); + +private: + DECL_LINK( CheckNameHdl, AbstractSvxNameDialog* ); + + void executeDispatch_FormatLine(); + void executeDispatch_FormatArea(); + void executeDispatch_TextAttributes(); + void executeDispatch_TransformDialog(); + void executeDispatch_ObjectTitleDescription(); + void executeDispatch_RenameObject(); + void executeDispatch_ChangeZOrder( sal_uInt16 nId ); + void executeDispatch_FontDialog(); + void executeDispatch_ParagraphDialog(); + + SdrObject* getFirstAdditionalShape(); + SdrObject* getLastAdditionalShape(); + bool isBackwardPossible(); + bool isForwardPossible(); + + ChartController* m_pChartController; +}; + +//............................................................................. +} // namespace chart +//............................................................................. + +// CHART2_SHAPECONTROLLER_HXX +#endif diff --git a/chart2/source/controller/main/ShapeToolbarController.cxx b/chart2/source/controller/main/ShapeToolbarController.cxx new file mode 100644 index 000000000000..a8a6cfba20ff --- /dev/null +++ b/chart2/source/controller/main/ShapeToolbarController.cxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "ShapeToolbarController.hxx" + +#include <vos/mutex.hxx> +#include <comphelper/sequence.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <svx/svxids.hrc> +#include <svx/tbxcustomshapes.hxx> + + +using namespace com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +//............................................................................. +namespace chart +{ +//............................................................................. + +::rtl::OUString ShapeToolbarController::getImplementationName() throw (uno::RuntimeException) +{ + return getImplementationName_Static(); +} + +::rtl::OUString ShapeToolbarController::getImplementationName_Static() throw (uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.comp.ShapeToolbarController" ) ); +} + +Sequence< ::rtl::OUString > ShapeToolbarController::getSupportedServiceNames_Static() throw (uno::RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(1); + aSupported.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.ShapeToolbarController" ) ); + return aSupported; +} + +::sal_Bool ShapeToolbarController::supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException) +{ + return ::comphelper::existsValue( ServiceName, getSupportedServiceNames_Static() ); +} + +Sequence< ::rtl::OUString> ShapeToolbarController::getSupportedServiceNames() throw (uno::RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +Reference< uno::XInterface > ShapeToolbarController::create( const Reference< uno::XComponentContext >& xContext ) +{ + return *( new ShapeToolbarController( Reference< lang::XMultiServiceFactory >( xContext->getServiceManager(), uno::UNO_QUERY ) ) ); +} + +ShapeToolbarController::ShapeToolbarController( const Reference< lang::XMultiServiceFactory >& rxFact ) + :m_pToolbarController( NULL ) + ,m_nToolBoxId( 1 ) + ,m_nSlotId( 0 ) +{ + osl_incrementInterlockedCount( &m_refCount ); + m_xServiceManager = rxFact; + osl_decrementInterlockedCount( &m_refCount ); +} + +ShapeToolbarController::~ShapeToolbarController() +{ +} + +// ::com::sun::star::uno::XInterface +uno::Any ShapeToolbarController::queryInterface( const uno::Type& rType ) throw (uno::RuntimeException) +{ + uno::Any aReturn = ToolboxController::queryInterface( rType ); + if ( !aReturn.hasValue() ) + { + aReturn = ShapeToolbarController_Base::queryInterface( rType ); + } + return aReturn; +} + +void ShapeToolbarController::acquire() throw () +{ + ToolboxController::acquire(); +} + +void ShapeToolbarController::release() throw () +{ + ToolboxController::release(); +} + +// ::com::sun::star::lang::XInitialization +void ShapeToolbarController::initialize( const Sequence< uno::Any >& rArguments ) throw (uno::Exception, uno::RuntimeException) +{ + ToolboxController::initialize( rArguments ); + ::vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) ); + if ( pToolBox ) + { + const USHORT nCount = pToolBox->GetItemCount(); + for ( USHORT nPos = 0; nPos < nCount; ++nPos ) + { + const USHORT nItemId = pToolBox->GetItemId( nPos ); + if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) ) + { + m_nToolBoxId = nItemId; + break; + } + } + if ( m_aCommandURL.equalsAscii( ".uno:BasicShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:BasicShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_BASIC; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox ) ); + } + else if ( m_aCommandURL.equalsAscii( ".uno:SymbolShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SymbolShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_SYMBOL; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox ) ); + } + else if ( m_aCommandURL.equalsAscii( ".uno:ArrowShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ArrowShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_ARROW; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox) ); + } + else if ( m_aCommandURL.equalsAscii( ".uno:FlowChartShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FlowChartShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_FLOWCHART; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox ) ); + } + else if ( m_aCommandURL.equalsAscii( ".uno:CalloutShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CalloutShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_CALLOUT; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox ) ); + } + else if ( m_aCommandURL.equalsAscii( ".uno:StarShapes" ) ) + { + m_aStates.insert( TCommandState::value_type( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StarShapes" ) ), sal_True ) ); + m_nSlotId = SID_DRAWTBX_CS_STAR; + m_pToolbarController = TToolbarHelper::createFromQuery( new SvxTbxCtlCustomShapes( m_nSlotId, m_nToolBoxId, *pToolBox ) ); + } + + for ( TCommandState::iterator aIter( m_aStates.begin() ); aIter != m_aStates.end(); ++aIter ) + { + addStatusListener( aIter->first ); + } + + if ( m_pToolbarController.is() ) + { + m_pToolbarController->initialize( rArguments ); + } + + // check if paste special is allowed, when not don't add DROPDOWN + pToolBox->SetItemBits( m_nToolBoxId, pToolBox->GetItemBits( m_nToolBoxId ) | TIB_DROPDOWN ); + } +} + +// ::com::sun::star::frame::XStatusListener +void ShapeToolbarController::statusChanged( const frame::FeatureStateEvent& Event ) throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + TCommandState::iterator aFind = m_aStates.find( Event.FeatureURL.Complete ); + if ( aFind != m_aStates.end() ) + { + aFind->second = Event.IsEnabled; + if ( m_pToolbarController.is() ) + { + sal_Bool bCheckmark = sal_False; + ToolBox& rTb = m_pToolbarController->GetToolBox(); + + for ( USHORT i = 0; i < rTb.GetItemCount(); ++i ) + { + USHORT nId = rTb.GetItemId( i ); + if ( nId == 0 ) + { + continue; + } + ::rtl::OUString aCmd = rTb.GetItemCommand( nId ); + if ( aCmd == Event.FeatureURL.Complete ) + { + rTb.EnableItem( nId, Event.IsEnabled ); + if ( Event.State >>= bCheckmark ) + { + rTb.CheckItem( nId, bCheckmark ); + } + else + { + ::rtl::OUString aItemText; + if ( Event.State >>= aItemText ) + { + rTb.SetItemText( nId, aItemText ); + } + } + } + } + } + } +} + +// ::com::sun::star::frame::XToolbarController +Reference< awt::XWindow > ShapeToolbarController::createPopupWindow() throw (uno::RuntimeException) +{ + ::vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + Reference< awt::XWindow > xRet; + if ( m_pToolbarController.is() ) + { + xRet = m_pToolbarController.getRef()->createPopupWindow(); + } + + return xRet; +} + +// ::com::sun::star::frame::XSubToolbarController +::sal_Bool ShapeToolbarController::opensSubToolbar() throw (uno::RuntimeException) +{ + return ( m_nSlotId == SID_DRAWTBX_CS_BASIC || + m_nSlotId == SID_DRAWTBX_CS_SYMBOL || + m_nSlotId == SID_DRAWTBX_CS_ARROW || + m_nSlotId == SID_DRAWTBX_CS_FLOWCHART || + m_nSlotId == SID_DRAWTBX_CS_CALLOUT || + m_nSlotId == SID_DRAWTBX_CS_STAR ); +} + +::rtl::OUString ShapeToolbarController::getSubToolbarName() throw (uno::RuntimeException) +{ + ::vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< frame::XSubToolbarController > xSub( m_pToolbarController.getRef(), uno::UNO_QUERY ); + if ( xSub.is() ) + { + return xSub->getSubToolbarName(); + } + return ::rtl::OUString(); +} + +void ShapeToolbarController::functionSelected( const ::rtl::OUString& rCommand ) throw (uno::RuntimeException) +{ + ::vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< frame::XSubToolbarController > xSub( m_pToolbarController.getRef(), uno::UNO_QUERY ); + if ( xSub.is() ) + { + m_aCommandURL = rCommand; + xSub->functionSelected( rCommand ); + } +} + +void ShapeToolbarController::updateImage() throw (uno::RuntimeException) +{ + ::vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< frame::XSubToolbarController > xSub( m_pToolbarController.getRef(), uno::UNO_QUERY ); + if ( xSub.is() ) + { + xSub->updateImage(); + } +} + +//............................................................................. +} // namespace chart +//............................................................................. diff --git a/chart2/source/controller/main/ShapeToolbarController.hxx b/chart2/source/controller/main/ShapeToolbarController.hxx new file mode 100644 index 000000000000..544cac7f9831 --- /dev/null +++ b/chart2/source/controller/main/ShapeToolbarController.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef CHART2_SHAPETOOLBARCONTROLLER_HXX +#define CHART2_SHAPETOOLBARCONTROLLER_HXX + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/frame/XSubToolbarController.hpp> + +#include <cppuhelper/implbase2.hxx> +#include <comphelper/implementationreference.hxx> +#include <comphelper/stl_types.hxx> +#include <svtools/toolboxcontroller.hxx> + +class SfxToolBoxControl; + +//............................................................................. +namespace chart +{ +//............................................................................. + +typedef ::cppu::ImplHelper2 < ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::frame::XSubToolbarController> ShapeToolbarController_Base; + +typedef ::comphelper::ImplementationReference< SfxToolBoxControl, ::com::sun::star::frame::XToolbarController > TToolbarHelper; + +class ShapeToolbarController : public ::svt::ToolboxController + ,public ShapeToolbarController_Base +{ + DECLARE_STL_USTRINGACCESS_MAP( sal_Bool, TCommandState ); + TCommandState m_aStates; + TToolbarHelper m_pToolbarController; + sal_uInt16 m_nToolBoxId; + sal_uInt16 m_nSlotId; + ShapeToolbarController( const ShapeToolbarController& ); + void operator =( const ShapeToolbarController& ); + +public: + ShapeToolbarController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFact ); + virtual ~ShapeToolbarController(); + + // ::com::sun::star::uno::XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // ::com::sun::star::lang::XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // needed by registration + static ::rtl::OUString getImplementationName_Static() throw( ::com::sun::star::uno::RuntimeException ); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::frame::XStatusListener + virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::frame::XToolbarController + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createPopupWindow() throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::frame::XSubToolbarController + virtual ::sal_Bool SAL_CALL opensSubToolbar() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSubToolbarName() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL functionSelected( const ::rtl::OUString& aCommand ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateImage() throw (::com::sun::star::uno::RuntimeException); +}; + +//............................................................................. +} // namespace chart +//............................................................................. + +#endif //CHART2_SHAPETOOLBARCONTROLLER_HXX + diff --git a/chart2/source/controller/main/StatusBarCommandDispatch.cxx b/chart2/source/controller/main/StatusBarCommandDispatch.cxx index 8522d96191e8..d80d37eff7da 100644 --- a/chart2/source/controller/main/StatusBarCommandDispatch.cxx +++ b/chart2/source/controller/main/StatusBarCommandDispatch.cxx @@ -95,7 +95,7 @@ void StatusBarCommandDispatch::fireStatusEvent( { uno::Any aArg; Reference< chart2::XChartDocument > xDoc( m_xModifiable, uno::UNO_QUERY ); - aArg <<= ObjectNameProvider::getSelectedObjectText( m_aSelectedCID, xDoc ); + aArg <<= ObjectNameProvider::getSelectedObjectText( m_aSelectedOID.getObjectCID(), xDoc ); fireStatusEventForURL( C2U(".uno:Context"), aArg, true, xSingleListener ); } if( bFireModified ) @@ -147,9 +147,9 @@ void SAL_CALL StatusBarCommandDispatch::selectionChanged( const lang::EventObjec throw (uno::RuntimeException) { if( m_xSelectionSupplier.is()) - m_xSelectionSupplier->getSelection() >>= m_aSelectedCID; + m_aSelectedOID = ObjectIdentifier( m_xSelectionSupplier->getSelection() ); else - m_aSelectedCID = OUString(); + m_aSelectedOID = ObjectIdentifier(); fireAllStatusEvents( 0 ); } diff --git a/chart2/source/controller/main/StatusBarCommandDispatch.hxx b/chart2/source/controller/main/StatusBarCommandDispatch.hxx index 23a394ecad6e..c84f81f83258 100644 --- a/chart2/source/controller/main/StatusBarCommandDispatch.hxx +++ b/chart2/source/controller/main/StatusBarCommandDispatch.hxx @@ -28,6 +28,7 @@ #define CHART2_STATUSBARCOMMANDDISPATCH_HXX #include "CommandDispatch.hxx" +#include "ObjectIdentifier.hxx" #include <cppuhelper/implbase1.hxx> #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> @@ -100,7 +101,7 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionSupplier > m_xSelectionSupplier; bool m_bIsModified; - ::rtl::OUString m_aSelectedCID; + ObjectIdentifier m_aSelectedOID; }; } // namespace chart diff --git a/chart2/source/controller/main/UndoGuard.cxx b/chart2/source/controller/main/UndoGuard.cxx new file mode 100644 index 000000000000..61bed4029db5 --- /dev/null +++ b/chart2/source/controller/main/UndoGuard.cxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "UndoGuard.hxx" + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; + +namespace chart +{ + +UndoGuard_Base::UndoGuard_Base( const OUString& rUndoString + , const uno::Reference< chart2::XUndoManager > & xUndoManager + , const uno::Reference< frame::XModel > & xModel ) + : m_xModel( xModel ) + , m_xUndoManager( xUndoManager ) + , m_aUndoString( rUndoString ) + , m_bActionPosted( false ) +{ +} + +UndoGuard_Base::~UndoGuard_Base() +{ +} + +void UndoGuard_Base::commitAction() +{ + if( !m_bActionPosted ) + m_xUndoManager->postAction( m_aUndoString ); + m_bActionPosted = true; +} + +//----------------------------------------------------------------------------- + +UndoGuard::UndoGuard( const OUString& rUndoString + , const uno::Reference< chart2::XUndoManager > & xUndoManager + , const uno::Reference< frame::XModel > & xModel ) + : UndoGuard_Base( rUndoString, xUndoManager, xModel ) +{ + m_xUndoManager->preAction( m_xModel ); +} + +UndoGuard::~UndoGuard() +{ + if( !m_bActionPosted ) + m_xUndoManager->cancelAction(); +} + +//----------------------------------------------------------------------------- + +UndoLiveUpdateGuard::UndoLiveUpdateGuard( const OUString& rUndoString + , const uno::Reference< chart2::XUndoManager > & xUndoManager + , const uno::Reference< frame::XModel > & xModel ) + : UndoGuard_Base( rUndoString, xUndoManager, xModel ) +{ + m_xUndoManager->preAction( m_xModel ); +} + +UndoLiveUpdateGuard::~UndoLiveUpdateGuard() +{ + if( !m_bActionPosted ) + m_xUndoManager->cancelActionWithUndo( m_xModel ); +} + +//----------------------------------------------------------------------------- + +UndoLiveUpdateGuardWithData::UndoLiveUpdateGuardWithData( const OUString& rUndoString + , const uno::Reference< chart2::XUndoManager > & xUndoManager + , const uno::Reference< frame::XModel > & xModel ) + : UndoGuard_Base( rUndoString, xUndoManager, xModel ) +{ + Sequence< beans::PropertyValue > aArgs(1); + aArgs[0] = beans::PropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("WithData")), -1, uno::Any(), + beans::PropertyState_DIRECT_VALUE ); + m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); +} + +UndoLiveUpdateGuardWithData::~UndoLiveUpdateGuardWithData() +{ + if( !m_bActionPosted ) + m_xUndoManager->cancelActionWithUndo( m_xModel ); +} + +//----------------------------------------------------------------------------- + +UndoGuardWithSelection::UndoGuardWithSelection( const rtl::OUString& rUndoString + , const uno::Reference< chart2::XUndoManager > & xUndoManager + , const uno::Reference< frame::XModel > & xModel ) + : UndoGuard_Base( rUndoString, xUndoManager, xModel ) +{ + Sequence< beans::PropertyValue > aArgs(1); + aArgs[0] = beans::PropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("WithSelection")), -1, uno::Any(), + beans::PropertyState_DIRECT_VALUE ); + m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); +} + +UndoGuardWithSelection::~UndoGuardWithSelection() +{ + if( !m_bActionPosted ) + m_xUndoManager->cancelAction(); +} + +} // namespace chart diff --git a/chart2/source/controller/main/UndoManager.cxx b/chart2/source/controller/main/UndoManager.cxx new file mode 100644 index 000000000000..34157503e629 --- /dev/null +++ b/chart2/source/controller/main/UndoManager.cxx @@ -0,0 +1,436 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "UndoManager.hxx" +#include "ImplUndoManager.hxx" +#include "DisposeHelper.hxx" +#include "MutexContainer.hxx" +#include "macros.hxx" +#include "ChartViewHelper.hxx" + +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> + +#include <unotools/configitem.hxx> +#include <cppuhelper/compbase1.hxx> +#include <rtl/uuid.h> +#include <svx/svdundo.hxx> + +#include <functional> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::rtl::OUString; + + +// -------------------------------------------------------------------------------- + +namespace chart +{ + +namespace impl +{ +typedef ::cppu::WeakComponentImplHelper1< + util::XModifyBroadcaster > + ModifyBroadcaster_Base; + +class ModifyBroadcaster : + public ::chart::MutexContainer, + public ModifyBroadcaster_Base +{ +public: + ModifyBroadcaster(); + + void fireEvent(); + +protected: + // ____ XModifyBroadcaster ____ + virtual void SAL_CALL addModifyListener( const Reference< util::XModifyListener >& xListener ) + throw (uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const Reference< util::XModifyListener >& xListener ) + throw (uno::RuntimeException); +}; + +ModifyBroadcaster::ModifyBroadcaster() : + ModifyBroadcaster_Base( m_aMutex ) +{} + +void SAL_CALL ModifyBroadcaster::addModifyListener( + const Reference< util::XModifyListener >& xListener ) + throw (uno::RuntimeException) +{ + rBHelper.addListener( ::getCppuType( & xListener ), xListener); +} + +void SAL_CALL ModifyBroadcaster::removeModifyListener( + const Reference< util::XModifyListener >& xListener ) + throw (uno::RuntimeException) +{ + rBHelper.removeListener( ::getCppuType( & xListener ), xListener ); +} + +void ModifyBroadcaster::fireEvent() +{ + ::cppu::OInterfaceContainerHelper* pIC = rBHelper.getContainer( + ::getCppuType((const uno::Reference< util::XModifyListener >*)0) ); + if( pIC ) + { + lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) ); + ::cppu::OInterfaceIteratorHelper aIt( *pIC ); + while( aIt.hasMoreElements() ) + (static_cast< util::XModifyListener*>(aIt.next()))->modified( aEvent ); + } +} + +} // namespace impl + +UndoManager::UndoManager() : + impl::UndoManager_Base( m_aMutex ), + m_apUndoStack( new impl::UndoStack()), + m_apRedoStack( new impl::UndoStack()), + m_pLastRemeberedUndoElement( 0 ), + m_nMaxNumberOfUndos( 100 ), + m_pModifyBroadcaster( 0 ) +{} + +UndoManager::~UndoManager() +{ + DisposeHelper::Dispose( m_xModifyBroadcaster ); + m_apUndoStack->disposeAndClear(); + m_apRedoStack->disposeAndClear(); + + delete m_pLastRemeberedUndoElement; + m_pLastRemeberedUndoElement = 0; +} + +void UndoManager::addShapeUndoAction( SdrUndoAction* pAction ) +{ + if ( !pAction ) + { + return; + } + + impl::ShapeUndoElement* pShapeUndoElement = new impl::ShapeUndoElement( pAction->GetComment(), pAction ); + if ( pShapeUndoElement ) + { + m_apUndoStack->push( pShapeUndoElement ); + m_apRedoStack->disposeAndClear(); + if ( !m_apUndoStepsConfigItem.get() ) + { + retrieveConfigUndoSteps(); + } + fireModifyEvent(); + } +} + +void UndoManager::impl_undoRedo( + Reference< frame::XModel > & xCurrentModel, + impl::UndoStack * pStackToRemoveFrom, + impl::UndoStack * pStackToAddTo, + bool bUndo ) +{ + if( pStackToRemoveFrom && ! pStackToRemoveFrom->empty() ) + { + // get model from undo/redo + impl::UndoElement * pTop( pStackToRemoveFrom->top()); + if( pTop ) + { + impl::ShapeUndoElement* pShapeUndoElement = dynamic_cast< impl::ShapeUndoElement* >( pTop ); + if ( pShapeUndoElement ) + { + impl::ShapeUndoElement* pNewShapeUndoElement = new impl::ShapeUndoElement( *pShapeUndoElement ); + pStackToAddTo->push( pNewShapeUndoElement ); + SdrUndoAction* pAction = pNewShapeUndoElement->getSdrUndoAction(); + if ( pAction ) + { + if ( bUndo ) + { + pAction->Undo(); + } + else + { + pAction->Redo(); + } + } + } + else + { + // put a clone of current model into redo/undo stack with the same + // action string as the undo/redo + pStackToAddTo->push( pTop->createFromModel( xCurrentModel )); + // change current model by properties of the model from undo + pTop->applyToModel( xCurrentModel ); + } + // remove the top undo element + pStackToRemoveFrom->pop(), pTop = 0; + ChartViewHelper::setViewToDirtyState( xCurrentModel ); + fireModifyEvent(); + } + } + else + { + OSL_ENSURE( false, "Can't Undo/Redo" ); + } +} + +void UndoManager::fireModifyEvent() +{ + if( m_xModifyBroadcaster.is()) + m_pModifyBroadcaster->fireEvent(); +} + + +// ____ ConfigItemListener ____ +void UndoManager::notify( const ::rtl::OUString & rPropertyName ) +{ + OSL_ENSURE( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" )), + "Unwanted config property change Notified" ); + if( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" ))) + retrieveConfigUndoSteps(); +} + +void UndoManager::retrieveConfigUndoSteps() +{ + if( ! m_apUndoStepsConfigItem.get()) + m_apUndoStepsConfigItem.reset( new impl::UndoStepsConfigItem( *this )); + m_nMaxNumberOfUndos = m_apUndoStepsConfigItem->getUndoSteps(); + m_apUndoStack->limitSize( m_nMaxNumberOfUndos ); + m_apRedoStack->limitSize( m_nMaxNumberOfUndos ); + + // a list of available undo steps could shrink here + fireModifyEvent(); +} + +// ____ XModifyBroadcaster ____ +void SAL_CALL UndoManager::addModifyListener( const Reference< util::XModifyListener >& aListener ) + throw (uno::RuntimeException) +{ + if( ! m_xModifyBroadcaster.is()) + { + m_pModifyBroadcaster = new impl::ModifyBroadcaster(); + m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY ); + } + m_xModifyBroadcaster->addModifyListener( aListener ); +} + +void SAL_CALL UndoManager::removeModifyListener( const Reference< util::XModifyListener >& aListener ) + throw (uno::RuntimeException) +{ + if( ! m_xModifyBroadcaster.is()) + { + m_pModifyBroadcaster = new impl::ModifyBroadcaster(); + m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY ); + } + m_xModifyBroadcaster->removeModifyListener( aListener ); +} + +// ____ chart2::XUndoManager ____ +void SAL_CALL UndoManager::preAction( const Reference< frame::XModel >& xModelBeforeChange ) + throw (uno::RuntimeException) +{ + OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" ); + m_pLastRemeberedUndoElement = new impl::UndoElement( xModelBeforeChange ); +} + +void SAL_CALL UndoManager::preActionWithArguments( + const Reference< frame::XModel >& xModelBeforeChange, + const Sequence< beans::PropertyValue >& aArguments ) + throw (uno::RuntimeException) +{ + bool bActionHandled( false ); + OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" ); + if( aArguments.getLength() > 0 ) + { + OSL_ENSURE( aArguments.getLength() == 1, "More than one argument is not supported yet" ); + if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithData"))) + { + m_pLastRemeberedUndoElement = new impl::UndoElementWithData( xModelBeforeChange ); + bActionHandled = true; + } + else if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithSelection"))) + { + m_pLastRemeberedUndoElement = new impl::UndoElementWithSelection( xModelBeforeChange ); + bActionHandled = true; + } + } + + if( !bActionHandled ) + preAction( xModelBeforeChange ); +} + +void SAL_CALL UndoManager::postAction( const OUString& aUndoText ) + throw (uno::RuntimeException) +{ + OSL_ENSURE( m_pLastRemeberedUndoElement, "Looks like preAction call was missing" ); + if( m_pLastRemeberedUndoElement ) + { + m_pLastRemeberedUndoElement->setActionString( aUndoText ); + m_apUndoStack->push( m_pLastRemeberedUndoElement ); + m_pLastRemeberedUndoElement = 0; + + // redo no longer possible + m_apRedoStack->disposeAndClear(); + + // it suffices to get the number of undo steps from config after the + // first time postAction has been called + if( ! m_apUndoStepsConfigItem.get()) + retrieveConfigUndoSteps(); + + fireModifyEvent(); + } +} + +void SAL_CALL UndoManager::cancelAction() + throw (uno::RuntimeException) +{ + delete m_pLastRemeberedUndoElement; + m_pLastRemeberedUndoElement = 0; +} + +void SAL_CALL UndoManager::cancelActionWithUndo( Reference< frame::XModel >& xModelToRestore ) + throw (uno::RuntimeException) +{ + if( m_pLastRemeberedUndoElement ) + { + m_pLastRemeberedUndoElement->applyToModel( xModelToRestore ); + cancelAction(); + } +} + +void SAL_CALL UndoManager::undo( Reference< frame::XModel >& xCurrentModel ) + throw (uno::RuntimeException) +{ + OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); + impl_undoRedo( xCurrentModel, m_apUndoStack.get(), m_apRedoStack.get(), true ); +} + +void SAL_CALL UndoManager::redo( Reference< frame::XModel >& xCurrentModel ) + throw (uno::RuntimeException) +{ + OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get()); + impl_undoRedo( xCurrentModel, m_apRedoStack.get(), m_apUndoStack.get(), false ); +} + +::sal_Bool SAL_CALL UndoManager::undoPossible() + throw (uno::RuntimeException) +{ + return ! m_apUndoStack->empty(); +} + +::sal_Bool SAL_CALL UndoManager::redoPossible() + throw (uno::RuntimeException) +{ + return ! m_apRedoStack->empty(); +} + +OUString SAL_CALL UndoManager::getCurrentUndoString() + throw (uno::RuntimeException) +{ + return m_apUndoStack->topUndoString(); +} + +OUString SAL_CALL UndoManager::getCurrentRedoString() + throw (uno::RuntimeException) +{ + return m_apRedoStack->topUndoString(); +} + +Sequence< OUString > SAL_CALL UndoManager::getAllUndoStrings() + throw (uno::RuntimeException) +{ + return m_apUndoStack->getUndoStrings(); +} + +Sequence< OUString > SAL_CALL UndoManager::getAllRedoStrings() + throw (uno::RuntimeException) +{ + return m_apRedoStack->getUndoStrings(); +} + +// ____ XUndoHelper ____ +Reference< frame::XModel > SAL_CALL UndoManager::getModelCloneForUndo( + const Reference< frame::XModel >& xModelBeforeChange ) + throw (uno::RuntimeException) +{ + return impl::UndoElement::cloneModel( xModelBeforeChange ); +} + +void SAL_CALL UndoManager::applyModelContent( + Reference< frame::XModel >& xModelToChange, + const Reference< frame::XModel >& xModelToCopyFrom ) + throw (uno::RuntimeException) +{ + impl::UndoElement::applyModelContentToModel( xModelToChange, xModelToCopyFrom ); +} + +// ____ XUnoTunnel ____ +sal_Int64 UndoManager::getSomething( const Sequence< sal_Int8 >& rId ) + throw (uno::RuntimeException) +{ + if ( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) ); + } + return 0; +} + +// static +const Sequence< sal_Int8 >& UndoManager::getUnoTunnelId() +{ + static Sequence< sal_Int8 >* pSeq = 0; + if( !pSeq ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +// static +UndoManager* UndoManager::getImplementation( const Reference< uno::XInterface > xObj ) +{ + UndoManager* pRet = NULL; + Reference< lang::XUnoTunnel > xUT( xObj, uno::UNO_QUERY ); + if ( xUT.is() ) + { + pRet = reinterpret_cast< UndoManager* >( sal::static_int_cast< sal_IntPtr >( xUT->getSomething( getUnoTunnelId() ) ) ); + } + return pRet; +} + +} // namespace chart diff --git a/chart2/source/controller/main/_serviceregistration_controller.cxx b/chart2/source/controller/main/_serviceregistration_controller.cxx index 904c642c8a20..cf8f5525e624 100644 --- a/chart2/source/controller/main/_serviceregistration_controller.cxx +++ b/chart2/source/controller/main/_serviceregistration_controller.cxx @@ -34,6 +34,7 @@ #include "ChartDocumentWrapper.hxx" #include "AccessibleChartView.hxx" #include "ElementSelector.hxx" +#include "ShapeToolbarController.hxx" #include <cppuhelper/implementationentry.hxx> static struct ::cppu::ImplementationEntry g_entries_chart2_controller[] = @@ -79,17 +80,17 @@ static struct ::cppu::ImplementationEntry g_entries_chart2_controller[] = , 0 } ,{ - ::chart::AccessibleChartView::create - , ::chart::AccessibleChartView::getImplementationName_Static - , ::chart::AccessibleChartView::getSupportedServiceNames_Static + ::chart::ElementSelectorToolbarController::create + , ::chart::ElementSelectorToolbarController::getImplementationName_Static + , ::chart::ElementSelectorToolbarController::getSupportedServiceNames_Static , ::cppu::createSingleComponentFactory , 0 , 0 } ,{ - ::chart::ElementSelectorToolbarController::create - , ::chart::ElementSelectorToolbarController::getImplementationName_Static - , ::chart::ElementSelectorToolbarController::getSupportedServiceNames_Static + ::chart::ShapeToolbarController::create + , ::chart::ShapeToolbarController::getImplementationName_Static + , ::chart::ShapeToolbarController::getSupportedServiceNames_Static , ::cppu::createSingleComponentFactory , 0 , 0 diff --git a/chart2/source/controller/main/makefile.mk b/chart2/source/controller/main/makefile.mk index 8fe7cc8f783d..729276d5bd0e 100644 --- a/chart2/source/controller/main/makefile.mk +++ b/chart2/source/controller/main/makefile.mk @@ -67,7 +67,14 @@ SLOFILES = \ $(SLO)$/_serviceregistration_controller.obj \ $(SLO)$/ChartDropTargetHelper.obj \ $(SLO)$/StatusBarCommandDispatch.obj \ - $(SLO)$/ChartTransferable.obj + $(SLO)$/ChartTransferable.obj \ + $(SLO)$/FeatureCommandDispatchBase.obj \ + $(SLO)$/DrawCommandDispatch.obj \ + $(SLO)$/ShapeController.obj \ + $(SLO)$/ShapeToolbarController.obj \ + $(SLO)$/ImplUndoManager.obj \ + $(SLO)$/UndoManager.obj \ + $(SLO)$/UndoGuard.obj # $(SLO)$/CommonConverters.obj \ # $(SLO)$/Scaling.obj \ diff --git a/chart2/source/controller/makefile.mk b/chart2/source/controller/makefile.mk index b5a5975a2d03..8fdd6000fbe1 100644 --- a/chart2/source/controller/makefile.mk +++ b/chart2/source/controller/makefile.mk @@ -112,6 +112,7 @@ DEF1NAME= $(SHL1TARGET) # sfx.srs is needed for the strings for UNDO and REDO in the UndoCommandDispatch RESLIB1LIST=\ $(SRS)$/chcdialogs.srs \ + $(SRS)$/chcmenus.srs \ $(SOLARCOMMONRESDIR)$/sfx.srs RESLIB1NAME= $(TARGET) diff --git a/chart2/source/controller/menus/ShapeContextMenu.src b/chart2/source/controller/menus/ShapeContextMenu.src new file mode 100644 index 000000000000..79e424707807 --- /dev/null +++ b/chart2/source/controller/menus/ShapeContextMenu.src @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "MenuResIds.hrc" +#include "ShapeController.hrc" + + +Menu RID_CONTEXTMENU_SHAPE +{ + ItemList = + { + MenuItem + { + Identifier = COMMAND_ID_FORMAT_LINE; + Command = ".uno:FormatLine"; + }; + MenuItem + { + Identifier = COMMAND_ID_FORMAT_AREA; + Command = ".uno:FormatArea"; + }; + MenuItem + { + Identifier = COMMAND_ID_TEXT_ATTRIBUTES; + Command = ".uno:TextAttributes"; + }; + MenuItem + { + Identifier = COMMAND_ID_TRANSFORM_DIALOG; + Command = ".uno:TransformDialog"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = COMMAND_ID_OBJECT_TITLE_DESCRIPTION; + Command = ".uno:ObjectTitleDescription"; + }; + MenuItem + { + Identifier = COMMAND_ID_RENAME_OBJECT; + Command = ".uno:RenameObject"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = COMMAND_ID_ARRANGE_ROW; + Command = ".uno:ArrangeRow"; + SubMenu = Menu + { + ItemList = + { + MenuItem + { + Identifier = COMMAND_ID_BRING_TO_FRONT; + Command = ".uno:BringToFront"; + }; + MenuItem + { + Identifier = COMMAND_ID_FORWARD; + Command = ".uno:Forward"; + }; + MenuItem + { + Identifier = COMMAND_ID_BACKWARD; + Command = ".uno:Backward"; + }; + MenuItem + { + Identifier = COMMAND_ID_SEND_TO_BACK; + Command = ".uno:SendToBack"; + }; + }; + }; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = COMMAND_ID_CUT; + Command = ".uno:Cut"; + }; + MenuItem + { + Identifier = COMMAND_ID_COPY; + Command = ".uno:Copy"; + }; + MenuItem + { + Identifier = COMMAND_ID_PASTE; + Command = ".uno:Paste"; + }; + }; +}; diff --git a/chart2/source/controller/menus/ShapeEditContextMenu.src b/chart2/source/controller/menus/ShapeEditContextMenu.src new file mode 100644 index 000000000000..60f5d4eab5af --- /dev/null +++ b/chart2/source/controller/menus/ShapeEditContextMenu.src @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "MenuResIds.hrc" +#include "ShapeController.hrc" + + +Menu RID_CONTEXTMENU_SHAPEEDIT +{ + ItemList = + { + MenuItem + { + Identifier = COMMAND_ID_FONT_DIALOG; + Command = ".uno:FontDialog"; + }; + MenuItem + { + Identifier = COMMAND_ID_PARAGRAPH_DIALOG; + Command = ".uno:ParagraphDialog"; + }; + MenuItem + { + Separator = TRUE; + }; + MenuItem + { + Identifier = COMMAND_ID_CUT; + Command = ".uno:Cut"; + }; + MenuItem + { + Identifier = COMMAND_ID_COPY; + Command = ".uno:Copy"; + }; + MenuItem + { + Identifier = COMMAND_ID_PASTE; + Command = ".uno:Paste"; + }; + }; +}; diff --git a/chart2/source/controller/menus/makefile.mk b/chart2/source/controller/menus/makefile.mk new file mode 100644 index 000000000000..f97548963e38 --- /dev/null +++ b/chart2/source/controller/menus/makefile.mk @@ -0,0 +1,63 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ= ..$/..$/.. +PRJINC= $(PRJ)$/source +PRJNAME= chart2 +TARGET= chcmenus + +ENABLE_EXCEPTIONS= TRUE +VISIBILITY_HIDDEN=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE: settings.mk + +# i26518 the gcc-3.0.4 requires to enhance the template-depth +# this seems to be a compiler issue, so we recommend not to use 3.0.x anymore +.IF "$(COM)"=="GCC" + CFLAGS+=-ftemplate-depth-128 +.ENDIF + +# --- Resources --------------------------------------------------------------- + +SRC1FILES= \ + ShapeContextMenu.src \ + ShapeEditContextMenu.src + +SRS1NAME=$(TARGET) + +# --- Targets ----------------------------------------------------------------- + +.INCLUDE: target.mk + +#dependencies: + +$(SRS)$/chcmenus.srs: \ + ..$/inc$/MenuResIds.hrc + +#$(SRS)$/$(TARGET).srs: $(SOLARINCDIR)$/svx$/globlmn.hrc |