diff options
author | Ingrid Halama <iha@openoffice.org> | 2010-03-15 13:09:41 +0100 |
---|---|---|
committer | Ingrid Halama <iha@openoffice.org> | 2010-03-15 13:09:41 +0100 |
commit | 8195643ff81f7a60e46522767c6b6483713f4af1 (patch) | |
tree | 42e3e2502b344817a441aa114b404cfbf2e676ef /chart2/source/controller/main | |
parent | 590a1a5225623eb922e63b02b62e711d153e9d55 (diff) | |
parent | f2cf0b3fde3d8577260c8b12e380d23a27dbae17 (diff) |
chart43: merge with DEV300_m75
Diffstat (limited to 'chart2/source/controller/main')
33 files changed, 4919 insertions, 734 deletions
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 382d85ac0c10..ff567636ba0e 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 "DiagramHelper.hxx" #include <com/sun/star/chart2/DataPointLabel.hpp> @@ -60,8 +61,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> @@ -78,8 +77,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; @@ -192,50 +200,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 { @@ -342,22 +306,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; @@ -390,14 +353,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 ) ); } } } @@ -449,7 +405,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 )) @@ -459,41 +414,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 >() ); + } + } + } } } @@ -506,9 +578,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) ) return true; @@ -522,6 +595,22 @@ bool ChartController::isObjectDeleteable( const uno::Any& rSelection ) if( (OBJECTTYPE_AXIS == aObjectType) || (OBJECTTYPE_GRID == aObjectType) || (OBJECTTYPE_SUBGRID == 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; } @@ -804,4 +893,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 \ |