diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-03-22 12:09:10 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-03-22 12:09:10 +0100 |
commit | 35ce77a82b374828ef7b85bca8029672dced337f (patch) | |
tree | 78f180478c51f9c7a18d6e9d22f1473192ce6047 /sd/source | |
parent | 0dec5536c50fb545cf26701c6ecf158d3f9ab38a (diff) |
slidecopy: allow custom tool panels in the task pane to be implemented as extensions
Diffstat (limited to 'sd/source')
-rw-r--r-- | sd/source/ui/framework/factories/BasicViewFactory.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/framework/factories/TaskPanelFactory.cxx | 3 | ||||
-rw-r--r-- | sd/source/ui/framework/factories/ViewShellWrapper.cxx | 100 | ||||
-rw-r--r-- | sd/source/ui/framework/tools/FrameworkHelper.cxx | 85 | ||||
-rw-r--r-- | sd/source/ui/inc/framework/ViewShellWrapper.hxx | 63 | ||||
-rw-r--r-- | sd/source/ui/inc/taskpane/ToolPanelViewShell.hxx | 25 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/CustomToolPanel.cxx | 116 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/CustomToolPanel.hxx | 22 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/StandardToolPanel.cxx | 40 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/StandardToolPanel.hxx | 8 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/TaskPaneToolPanel.cxx | 33 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/TaskPaneToolPanel.hxx | 10 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/ToolPanelDrawer.cxx | 5 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/ToolPanelDrawer.hxx | 1 | ||||
-rw-r--r-- | sd/source/ui/toolpanel/ToolPanelViewShell.cxx | 226 |
15 files changed, 565 insertions, 174 deletions
diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx index d6ae0fea249d..8663b8676138 100644 --- a/sd/source/ui/framework/factories/BasicViewFactory.cxx +++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx @@ -377,7 +377,7 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence<Any>& aArguments) pDescriptor->mpViewShell, rxViewId, rxPane->getWindow()); - pDescriptor->mxView = Reference<XResource>(pDescriptor->mpWrapper); + pDescriptor->mxView.set( pDescriptor->mpWrapper->queryInterface( XResource::static_type() ), UNO_QUERY_THROW ); } return pDescriptor; diff --git a/sd/source/ui/framework/factories/TaskPanelFactory.cxx b/sd/source/ui/framework/factories/TaskPanelFactory.cxx index 0ff2893507c7..43a1a0280ba4 100644 --- a/sd/source/ui/framework/factories/TaskPanelFactory.cxx +++ b/sd/source/ui/framework/factories/TaskPanelFactory.cxx @@ -266,10 +266,7 @@ Reference<XResource> SAL_CALL TaskPanelFactory::createResource ( toolpanel::ToolPanelViewShell* pToolPanel = dynamic_cast< toolpanel::ToolPanelViewShell* >( pPaneViewShell.get() ); if ( pToolPanel != NULL ) - { xResource = new TaskPanelResource( rxResourceId ); - pToolPanel->ActivatePanel( ePanelId ); - } OSL_POSTCOND( xResource.is(), "TaskPanelFactory::createResource: did not find the given resource!" ); } diff --git a/sd/source/ui/framework/factories/ViewShellWrapper.cxx b/sd/source/ui/framework/factories/ViewShellWrapper.cxx index b2d64ebeccad..e2fa7ff570e6 100644 --- a/sd/source/ui/framework/factories/ViewShellWrapper.cxx +++ b/sd/source/ui/framework/factories/ViewShellWrapper.cxx @@ -33,22 +33,32 @@ #include "framework/ViewShellWrapper.hxx" #include "framework/Pane.hxx" +#include "taskpane/ToolPanelViewShell.hxx" #include "ViewShell.hxx" #include "Window.hxx" #include <com/sun/star/drawing/framework/XPane.hpp> +#include <com/sun/star/lang/DisposedException.hpp> #include <rtl/uuid.h> #include <toolkit/helper/vclunohelper.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/typeprovider.hxx> #include <vcl/svapp.hxx> #include <vos/mutex.hxx> +#include <tools/diagnose_ex.h> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; +using ::com::sun::star::awt::XWindow; +using ::com::sun::star::rendering::XCanvas; +using ::com::sun::star::lang::DisposedException; + using ::rtl::OUString; +using ::sd::toolpanel::ToolPanelViewShell; namespace sd { namespace framework { @@ -59,7 +69,8 @@ ViewShellWrapper::ViewShellWrapper ( : ViewShellWrapperInterfaceBase(MutexOwner::maMutex), mpViewShell(pViewShell), mxViewId(rxViewId), - mxWindow(rxWindow) + mxWindow(rxWindow), + mbIsPane( pViewShell == NULL ? false : ( pViewShell->GetShellType() == ViewShell::ST_TASK_PANE ) ) { if (rxWindow.is()) { @@ -83,6 +94,8 @@ ViewShellWrapper::~ViewShellWrapper (void) void SAL_CALL ViewShellWrapper::disposing (void) { + ::osl::MutexGuard aGuard( maMutex ); + OSL_TRACE("disposing ViewShellWrapper %x", this); Reference<awt::XWindow> xWindow (mxWindow); if (xWindow.is()) @@ -105,13 +118,92 @@ void SAL_CALL ViewShellWrapper::disposing (void) -bool ViewShellWrapper::IsUnique (void) +//----- XInterface ------------------------------------------------------------ + +Any SAL_CALL ViewShellWrapper::queryInterface( const Type& i_rType ) throw (RuntimeException) { - return m_refCount==1; + Any aInterface( ViewShellWrapperInterfaceBase::queryInterface( i_rType ) ); + if ( !aInterface.hasValue() ) + { + if ( mbIsPane ) + aInterface = ViewShellWrapper_PaneBase::queryInterface( i_rType ); + else + aInterface = ViewShellWrapper_ViewBase::queryInterface( i_rType ); + } + return aInterface; } +void SAL_CALL ViewShellWrapper::acquire() throw () +{ + ViewShellWrapperInterfaceBase::acquire(); +} +void SAL_CALL ViewShellWrapper::release() throw () +{ + ViewShellWrapperInterfaceBase::release(); +} +//----- XTypeProvider --------------------------------------------------------- + +Sequence< Type > SAL_CALL ViewShellWrapper::getTypes( ) throw (RuntimeException) +{ + const Sequence< Type > aCommonTypes( ViewShellWrapperInterfaceBase::getTypes() ); + const Sequence< Type > aSpecialTypes( + mbIsPane + ? ViewShellWrapper_PaneBase::getTypes() + : ViewShellWrapper_ViewBase::getTypes() + ); + return ::comphelper::concatSequences( aCommonTypes, aSpecialTypes ); +} + +Sequence< ::sal_Int8 > SAL_CALL ViewShellWrapper::getImplementationId( ) throw (RuntimeException) +{ + static ::cppu::OImplementationId* pViewId = NULL; + static ::cppu::OImplementationId* pPaneId = NULL; + if ( !pViewId ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pViewId ) + { + static ::cppu::OImplementationId aViewId; + static ::cppu::OImplementationId aPaneId; + pViewId = &aViewId; + pPaneId = &aPaneId; + } + } + + return ( mbIsPane ? pPaneId : pViewId )->getImplementationId(); +} + +//----- XPane ----------------------------------------------------------------- + +Reference< XInterface > ViewShellWrapper::impl_getPaneWindowOrCanvas( const bool i_bWindow ) +{ + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( maMutex ); + if ( !mpViewShell.get() ) + throw DisposedException( ::rtl::OUString(), *this ); + + ToolPanelViewShell* pToolPanelShell = dynamic_cast< ToolPanelViewShell* >( mpViewShell.get() ); + ENSURE_OR_RETURN( pToolPanelShell != NULL, "XPane should be accessible for a ToolPanelViewShell only", NULL ); + + ::Window* pPaneWindow = pToolPanelShell->GetToolPanelParentWindow(); + ENSURE_OR_RETURN( pPaneWindow, "shell is not able to provide a panel parent", NULL ); + + if ( i_bWindow ) + return VCLUnoHelper::GetInterface( pPaneWindow ); + return pPaneWindow->GetCanvas(); +} + +Reference< XWindow > SAL_CALL ViewShellWrapper::getWindow() throw (RuntimeException) +{ + return Reference< XWindow >( impl_getPaneWindowOrCanvas( true ), UNO_QUERY ); +} + +Reference< XCanvas > SAL_CALL ViewShellWrapper::getCanvas() throw (RuntimeException) +{ + return Reference< XCanvas >( impl_getPaneWindowOrCanvas( false ), UNO_QUERY ); +} //----- XResource ------------------------------------------------------------- @@ -181,7 +273,7 @@ const Sequence<sal_Int8>& ViewShellWrapper::getUnoTunnelId (void) static Sequence<sal_Int8>* pSequence = NULL; if (pSequence == NULL) { - const ::vos::OGuard aSolarGuard (Application::GetSolarMutex()); + const ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); if (pSequence == NULL) { static ::com::sun::star::uno::Sequence<sal_Int8> aSequence (16); diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx index 9a49aa88876d..cc68f79535ba 100644 --- a/sd/source/ui/framework/tools/FrameworkHelper.cxx +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -222,7 +222,7 @@ const OUString FrameworkHelper::msViewTabBarURL( // Task panel URLs. const ::rtl::OUString FrameworkHelper::msTaskPanelURLPrefix( - OUString::createFromAscii("private:resource/taskpanel/")); + OUString::createFromAscii("private:resource/toolpanel/")); const ::rtl::OUString FrameworkHelper::msMasterPagesTaskPanelURL( msTaskPanelURLPrefix + OUString::createFromAscii("MasterPages")); const ::rtl::OUString FrameworkHelper::msLayoutTaskPanelURL( @@ -256,6 +256,46 @@ const OUString FrameworkHelper::msModuleControllerService( const OUString FrameworkHelper::msConfigurationControllerService( OUString::createFromAscii("com.sun.star.drawing.framework.ConfigurationController")); +//----- helper ---------------------------------------------------------------- +namespace +{ + static ::boost::shared_ptr< ViewShell > lcl_getViewShell( const Reference< XResource >& i_rViewShellWrapper ) + { + ::boost::shared_ptr< ViewShell > pViewShell; + if ( !i_rViewShellWrapper.is() ) + return pViewShell; + + try + { + Reference<lang::XUnoTunnel> xViewTunnel( i_rViewShellWrapper, UNO_QUERY_THROW ); + pViewShell = reinterpret_cast< ViewShellWrapper* >( + xViewTunnel->getSomething( ViewShellWrapper::getUnoTunnelId() ) )->GetViewShell(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return pViewShell; + } + Reference< XResource > lcl_getFirstViewInPane( const Reference< XConfigurationController >& i_rConfigController, + const Reference< XResourceId >& i_rPaneId ) + { + try + { + Reference< XConfiguration > xConfiguration( i_rConfigController->getRequestedConfiguration(), UNO_SET_THROW ); + Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources( + i_rPaneId, FrameworkHelper::msViewURLPrefix, AnchorBindingMode_DIRECT ) ); + if ( aViewIds.getLength() > 0 ) + return i_rConfigController->getResource( aViewIds[0] ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } +} + //----- FrameworkHelper::ViewURLMap ------------------------------------------- @@ -442,8 +482,11 @@ bool FrameworkHelper::IsValid (void) ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const OUString& rsPaneURL) { - Reference<XResourceId> xPaneId (CreateResourceId(rsPaneURL)); - return GetViewShell(GetView(xPaneId)); + if ( !mxConfigurationController.is() ) + return ::boost::shared_ptr<ViewShell>(); + + Reference<XResourceId> xPaneId( CreateResourceId( rsPaneURL ) ); + return lcl_getViewShell( lcl_getFirstViewInPane( mxConfigurationController, xPaneId ) ); } @@ -451,22 +494,7 @@ bool FrameworkHelper::IsValid (void) ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const Reference<XView>& rxView) { - ::boost::shared_ptr<ViewShell> pViewShell; - - try - { - Reference<lang::XUnoTunnel> xViewTunnel (rxView, UNO_QUERY); - if (xViewTunnel.is()) - { - pViewShell = reinterpret_cast<ViewShellWrapper*>(xViewTunnel->getSomething( - ViewShellWrapper::getUnoTunnelId()))->GetViewShell(); - } - } - catch (RuntimeException&) - { - } - - return pViewShell; + return lcl_getViewShell( rxView.get() ); } @@ -483,21 +511,11 @@ Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneO { if (rxPaneOrViewId->getResourceURL().match(msViewURLPrefix)) { - xView = Reference<XView>( - mxConfigurationController->getResource(rxPaneOrViewId), UNO_QUERY); + xView.set( mxConfigurationController->getResource( rxPaneOrViewId ), UNO_QUERY ); } else { - Reference<XConfiguration> xConfiguration ( - mxConfigurationController->getRequestedConfiguration()); - if (xConfiguration.is()) - { - Sequence<Reference<XResourceId> > aViewIds (xConfiguration->getResources( - rxPaneOrViewId, msViewURLPrefix, AnchorBindingMode_DIRECT)); - if (aViewIds.getLength() >= 1) - xView = Reference<XView>( - mxConfigurationController->getResource(aViewIds[0]), UNO_QUERY); - } + xView.set( lcl_getFirstViewInPane( mxConfigurationController, rxPaneOrViewId ), UNO_QUERY ); } } catch (lang::DisposedException&) @@ -505,7 +523,8 @@ Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneO Dispose(); } catch (RuntimeException&) - {} + { + } return xView; } @@ -804,7 +823,7 @@ void FrameworkHelper::WaitForEvent (const OUString& rsEventType) const if( (osl_getGlobalTimer() - nStartTime) > 60000 ) { - DBG_ERROR("FrameworkHelper::WaitForEvent(), no event since a minute? giving up!"); + DBG_ERROR("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!"); break; } } diff --git a/sd/source/ui/inc/framework/ViewShellWrapper.hxx b/sd/source/ui/inc/framework/ViewShellWrapper.hxx index c648c2336bb3..d8406adb1632 100644 --- a/sd/source/ui/inc/framework/ViewShellWrapper.hxx +++ b/sd/source/ui/inc/framework/ViewShellWrapper.hxx @@ -33,22 +33,26 @@ #include "MutexOwner.hxx" #include <com/sun/star/drawing/framework/XView.hpp> +#include <com/sun/star/drawing/framework/XPane.hpp> #include <com/sun/star/drawing/framework/XRelocatableResource.hpp> #include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> #include <osl/mutex.hxx> -#include <cppuhelper/compbase4.hxx> +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/implbase1.hxx> #include <boost/shared_ptr.hpp> namespace { -typedef ::cppu::WeakComponentImplHelper4 < - ::com::sun::star::drawing::framework::XView, - ::com::sun::star::lang::XUnoTunnel, - ::com::sun::star::awt::XWindowListener, - ::com::sun::star::drawing::framework::XRelocatableResource - > ViewShellWrapperInterfaceBase; +typedef ::cppu::WeakComponentImplHelper3 < ::com::sun::star::lang::XUnoTunnel + , ::com::sun::star::awt::XWindowListener + , ::com::sun::star::drawing::framework::XRelocatableResource + > ViewShellWrapperInterfaceBase; +typedef ::cppu::ImplHelper1 < ::com::sun::star::drawing::framework::XView + > ViewShellWrapper_ViewBase; +typedef ::cppu::ImplHelper1 < ::com::sun::star::drawing::framework::XPane + > ViewShellWrapper_PaneBase; } // end of anonymous namespace. @@ -60,9 +64,10 @@ namespace sd { namespace framework { Most importantly it provides a tunnel to the ViewShell implementation. Then it forwards size changes of the pane window to the view shell. */ -class ViewShellWrapper - : private sd::MutexOwner, - public ViewShellWrapperInterfaceBase +class ViewShellWrapper :private sd::MutexOwner + ,public ViewShellWrapperInterfaceBase + ,public ViewShellWrapper_ViewBase + ,public ViewShellWrapper_PaneBase { public: /** Create a new ViewShellWrapper object that wraps the given ViewShell @@ -93,22 +98,26 @@ public: */ ::boost::shared_ptr<ViewShell> GetViewShell (void); - /** Returns whether there is exactly one reference to the called - ViewShellWrapper object (the number of references to the wrapped - ViewShell object is not taken into account). This method is - typically used by the owner of a ViewShellWrapper object to verify - that, at the end of the ViewShellWrapper object's lifetime, the - owner holds the last reference and by releasing it will destroy the - object. - */ - bool IsUnique (void); - - // XUnoTunnel virtual sal_Int64 SAL_CALL getSomething (const com::sun::star::uno::Sequence<sal_Int8>& rId) throw (com::sun::star::uno::RuntimeException); + // XInterface + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire( ) throw (); + virtual void SAL_CALL release( ) throw (); + + // XTypeProvider + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException); + + // XPane + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getWindow( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > SAL_CALL getCanvas( ) throw (::com::sun::star::uno::RuntimeException); // XResource @@ -154,10 +163,14 @@ public: throw (com::sun::star::uno::RuntimeException); private: - ::boost::shared_ptr<ViewShell> mpViewShell; - const ::com::sun::star::uno::Reference< - com::sun::star::drawing::framework::XResourceId> mxViewId; - ::com::sun::star::uno::Reference<com::sun::star::awt::XWindow> mxWindow; + ::boost::shared_ptr< ViewShell > mpViewShell; + const ::com::sun::star::uno::Reference< com::sun::star::drawing::framework::XResourceId > mxViewId; + ::com::sun::star::uno::Reference<com::sun::star::awt::XWindow > mxWindow; + const bool mbIsPane; + +private: + // only to be called when mbIsPane is <TRUE/> + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > impl_getPaneWindowOrCanvas( const bool i_bWindow ); }; } } // end of namespace sd::framework diff --git a/sd/source/ui/inc/taskpane/ToolPanelViewShell.hxx b/sd/source/ui/inc/taskpane/ToolPanelViewShell.hxx index 9e02194a71c6..a82908ec56e3 100644 --- a/sd/source/ui/inc/taskpane/ToolPanelViewShell.hxx +++ b/sd/source/ui/inc/taskpane/ToolPanelViewShell.hxx @@ -54,7 +54,7 @@ class TitleToolBox; class TitleBar; class TitledControl; class ToolPanelDeck; - +class ToolPanelViewShell_Impl; /** The tool panel is a view shell for some very specific reasons: - It fits better into the concept of panes being docking windows whose content, a view shell, can be exchanged on runtime. @@ -99,6 +99,10 @@ public: TaskPaneShellManager& GetSubShellManager (void) const; + /** returns the window which should be used as parent for tool panel windows + */ + ::Window* GetToolPanelParentWindow(); + /** activates the given panel, bypassing the configuration controller, deactivates the previously active one. */ void ActivatePanel( const PanelId i_ePanelId ); @@ -107,6 +111,14 @@ public: */ void DeactivatePanel( const PanelId i_ePanelId ); + /** Return a pointer to the docking window that is the parent or a + predecessor of the content window. + @return + When the view shell is not placed in a docking window, e.g. when + shown in the center pane, then <NULL?> is returned. + */ + DockingWindow* GetDockingWindow (void); + /** Called when a mouse button has been pressed but not yet released, this handler is used to show the popup menu of the title bar. @@ -126,8 +138,7 @@ public: virtual bool RelocateToParentWindow (::Window* pParentWindow); private: - class Implementation; - ::boost::scoped_ptr< Implementation > mpImpl; + ::boost::scoped_ptr< ToolPanelViewShell_Impl > mpImpl; ::boost::shared_ptr<TaskPaneShellManager> mpSubShellManager; @@ -146,14 +157,6 @@ private: ::std::auto_ptr<PopupMenu> CreatePopupMenu (bool bIsDocking); - /** Return a pointer to the docking window that is the parent or a - predecessor of the content window. - @return - When the view shell is not placed in a docking window, e.g. when - shown in the center pane, then <NULL?> is returned. - */ - DockingWindow* GetDockingWindow (void); - /** connects to a (new) (Pane)DockingWindow */ void ConnectToDockingWindow(); diff --git a/sd/source/ui/toolpanel/CustomToolPanel.cxx b/sd/source/ui/toolpanel/CustomToolPanel.cxx index 33ee1270ab1d..b09b03725c58 100644 --- a/sd/source/ui/toolpanel/CustomToolPanel.cxx +++ b/sd/source/ui/toolpanel/CustomToolPanel.cxx @@ -31,6 +31,7 @@ /** === begin UNO includes === **/ #include <com/sun/star/drawing/framework/ResourceId.hpp> +#include <com/sun/star/awt/PosSize.hpp> /** === end UNO includes === **/ #include <comphelper/processfactory.hxx> @@ -62,7 +63,9 @@ namespace sd { namespace toolpanel using ::com::sun::star::drawing::framework::XResourceId; using ::com::sun::star::drawing::framework::ResourceId; using ::com::sun::star::drawing::framework::XResource; + using ::com::sun::star::awt::XWindow; /** === end UNO using === **/ + namespace PosSize = ::com::sun::star::awt::PosSize; //================================================================================================================== //= helper @@ -98,8 +101,10 @@ namespace sd { namespace toolpanel :TaskPaneToolPanel( i_rPanelDeck, lcl_getPanelConfig( i_rPanelConfig, "DisplayTitle" ), Image() /* TODO */, SmartId() /* TODO */ ) ,m_pFrameworkHelper( i_pFrameworkHelper ) ,m_xPanelResourceId() - ,m_xPanel() + ,m_xResource() + ,m_xToolPanel() ,m_bAttemptedPanelCreation( false ) + ,m_nResourceAccessLock( 0 ) { ENSURE_OR_THROW( m_pFrameworkHelper.get() != NULL, "invalid framework helper" ); ENSURE_OR_THROW( i_rPaneResourceId.is(), "invalid pane resource id" ); @@ -126,56 +131,121 @@ namespace sd { namespace toolpanel } //------------------------------------------------------------------------------------------------------------------ - void CustomToolPanel::Dispose() + void CustomToolPanel::Activate( ::Window& i_rParentWindow ) + { + OSL_ENSURE( &getPanelWindowAnchor() == &i_rParentWindow, + "CustomToolPanel::Activate: invalid new parent window" ); + // getPanelWindowAnchor() is what is returned in the TaskPane's XPane::getWindow method. So, + // any custom panel which is loaded into the TaskPane will use this window as parent window. + // Consequently, this is the window which shall be passed here, since this method is intended to + // re-create the panel with the given parent. + + // we do not need to do anything here. The XResourceFactory::createResource method of the custom + // tool panel already created and showed the window. + } + + //------------------------------------------------------------------------------------------------------------------ + void CustomToolPanel::Deactivate() + { + // When a certain tool panel is activated, this is routed through the drawing framework, which ensures + // that the resource associated with the previously active panel is deactivated, which calls the + // XResourceFactory::destroyResource at our custom panel's factory. + + // So, we do not have to do anything here - except forgetting the XResource, at it might (or might not, + // if cached by the factory) be re-created next time. + m_xResource.clear(); + m_xToolPanel.clear(); + m_bAttemptedPanelCreation = false; + } + + //------------------------------------------------------------------------------------------------------------------ + void CustomToolPanel::SetSizePixel( const Size& i_rPanelWindowSize ) { - if ( m_xPanel.is() ) + impl_ensurePanel(); + if ( !m_xToolPanel.is() ) + // if the custom panel does not support XPanel, this just means it is its own responsibility + // to resize/layout everything within the pane window. + return; + + try { - try - { - // TODO: obtain the factory for our panel, and invoke its destroyResource method - } - catch ( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } + Reference< XWindow > xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW ); + xPanelWindow->setPosSize( 0, 0, i_rPanelWindowSize.Width(), i_rPanelWindowSize.Height(), + PosSize::POSSIZE ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void CustomToolPanel::GrabFocus() + { + impl_ensurePanel(); + if ( !m_xToolPanel.is() ) + // if the custom panel does not support XPanel, this just means it is its own responsibility + // to care for focus handling + return; + + try + { + Reference< XWindow > xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW ); + xPanelWindow->setFocus(); } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + void CustomToolPanel::Dispose() + { + // nothing to do here. Lifetime handling of the XResource which this panel represents is done by + // the drawing framework, we ourself do not have resources to release. TaskPaneToolPanel::Dispose(); } //------------------------------------------------------------------------------------------------------------------ - const Reference< XResourceId >& CustomToolPanel::getResourceId() const + void CustomToolPanel::LockResourceAccess() { - return m_xPanelResourceId; + ++m_nResourceAccessLock; } //------------------------------------------------------------------------------------------------------------------ - ::Window* CustomToolPanel::getPanelWindow() const + void CustomToolPanel::UnlockResourceAccess() { - ENSURE_OR_RETURN( impl_ensurePanel(), "could not create the panel", NULL ); - // TODO - return NULL; + OSL_ENSURE( m_nResourceAccessLock > 0, "CustomToolPanel::UnlockResourceAccess: not locked!" ); + --m_nResourceAccessLock; + } + + //------------------------------------------------------------------------------------------------------------------ + const Reference< XResourceId >& CustomToolPanel::getResourceId() const + { + return m_xPanelResourceId; } //------------------------------------------------------------------------------------------------------------------ - bool CustomToolPanel::impl_ensurePanel() const + void CustomToolPanel::impl_ensurePanel() { - ENSURE_OR_RETURN_FALSE( !isDisposed(), "already disposed" ); + ENSURE_OR_RETURN_VOID( !isDisposed(), "already disposed" ); - if ( !m_bAttemptedPanelCreation ) + if ( ( m_nResourceAccessLock == 0 ) && !m_bAttemptedPanelCreation ) { - const_cast< CustomToolPanel* >( this )->m_bAttemptedPanelCreation = true; + m_bAttemptedPanelCreation = true; try { Reference< XConfigurationController > xConfigController( m_pFrameworkHelper->GetConfigurationController(), UNO_QUERY_THROW ); - Reference< XResource > xToolPanelResource( xConfigController->getResource( m_xPanelResourceId ) ); + m_xResource.set( xConfigController->getResource( m_xPanelResourceId ), UNO_QUERY_THROW ); + m_xToolPanel.set( m_xResource, UNO_QUERY ); } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } - return m_xPanel.is(); } //...................................................................................................................... diff --git a/sd/source/ui/toolpanel/CustomToolPanel.hxx b/sd/source/ui/toolpanel/CustomToolPanel.hxx index 23a3dcbb3cfc..fe5865150063 100644 --- a/sd/source/ui/toolpanel/CustomToolPanel.hxx +++ b/sd/source/ui/toolpanel/CustomToolPanel.hxx @@ -30,8 +30,10 @@ #include "TaskPaneToolPanel.hxx" /** === begin UNO includes === **/ -#include <com/sun/star/drawing/framework/XPane2.hpp> +#include <com/sun/star/drawing/framework/XPane.hpp> #include <com/sun/star/drawing/framework/XResourceId.hpp> +#include <com/sun/star/drawing/framework/XResource.hpp> +#include <com/sun/star/view/XToolPanel.hpp> /** === end UNO includes === **/ #include <boost/shared_ptr.hpp> @@ -71,21 +73,33 @@ namespace sd { namespace toolpanel ~CustomToolPanel(); // IToolPanel overridables + virtual void Activate( ::Window& i_rParentWindow ); + virtual void Deactivate(); + virtual void SetSizePixel( const Size& i_rPanelWindowSize ); + virtual void GrabFocus(); virtual void Dispose(); + /** locks (aka prevents) the access to the associated XResource object + */ + void LockResourceAccess(); + /** unlocks (aka allows) the access to the associated XResource object + */ + void UnlockResourceAccess(); + protected: // TaskPaneToolPanel overridables virtual const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XResourceId >& getResourceId() const; - virtual ::Window* getPanelWindow() const; private: - bool impl_ensurePanel() const; + void impl_ensurePanel(); private: ::boost::shared_ptr< framework::FrameworkHelper > m_pFrameworkHelper; ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XResourceId > m_xPanelResourceId; - ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XPane2 > m_xPanel; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XResource > m_xResource; + ::com::sun::star::uno::Reference< ::com::sun::star::view::XToolPanel > m_xToolPanel; bool m_bAttemptedPanelCreation; + sal_uInt32 m_nResourceAccessLock; }; //...................................................................................................................... diff --git a/sd/source/ui/toolpanel/StandardToolPanel.cxx b/sd/source/ui/toolpanel/StandardToolPanel.cxx index 1e2ba8f6308e..f83f811fde28 100644 --- a/sd/source/ui/toolpanel/StandardToolPanel.cxx +++ b/sd/source/ui/toolpanel/StandardToolPanel.cxx @@ -76,6 +76,39 @@ namespace sd { namespace toolpanel } //------------------------------------------------------------------------------------------------------------------ + void StandardToolPanel::Activate( ::Window& i_rParentWindow ) + { + Window* pPanelWindow( impl_getPanelWindow() ); + ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to show" ); + pPanelWindow->SetPosSizePixel( Point(), i_rParentWindow.GetSizePixel() ); + pPanelWindow->Show(); + } + + //------------------------------------------------------------------------------------------------------------------ + void StandardToolPanel::Deactivate() + { + Window* pPanelWindow( impl_getPanelWindow() ); + ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to hide" ); + pPanelWindow->Hide(); + } + + //------------------------------------------------------------------------------------------------------------------ + void StandardToolPanel::SetSizePixel( const Size& i_rPanelWindowSize ) + { + Window* pPanelWindow( impl_getPanelWindow() ); + ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to resize" ); + pPanelWindow->SetSizePixel( i_rPanelWindowSize ); + } + + //------------------------------------------------------------------------------------------------------------------ + void StandardToolPanel::GrabFocus() + { + Window* pPanelWindow( impl_getPanelWindow() ); + ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to focus" ); + pPanelWindow->GrabFocus(); + } + + //------------------------------------------------------------------------------------------------------------------ void StandardToolPanel::Dispose() { m_pControl.reset(); @@ -89,10 +122,11 @@ namespace sd { namespace toolpanel } //------------------------------------------------------------------------------------------------------------------ - ::Window* StandardToolPanel::getPanelWindow() const + ::Window* StandardToolPanel::impl_getPanelWindow() const { - ENSURE_OR_RETURN( const_cast< StandardToolPanel* >( this )->impl_ensureControl(), "StandardToolPanel::getPanelWindow: no control!", NULL ); - return m_pControl->GetWindow(); + if ( const_cast< StandardToolPanel* >( this )->impl_ensureControl() ) + return m_pControl->GetWindow(); + return NULL; } //------------------------------------------------------------------------------------------------------------------ diff --git a/sd/source/ui/toolpanel/StandardToolPanel.hxx b/sd/source/ui/toolpanel/StandardToolPanel.hxx index 8e4ad7e8eeea..1f3fd8ff7a90 100644 --- a/sd/source/ui/toolpanel/StandardToolPanel.hxx +++ b/sd/source/ui/toolpanel/StandardToolPanel.hxx @@ -53,14 +53,18 @@ namespace sd { namespace toolpanel ~StandardToolPanel(); // IToolPanel overridables + virtual void Activate( ::Window& i_rParentWindow ); + virtual void Deactivate(); + virtual void SetSizePixel( const Size& i_rPanelWindowSize ); + virtual void GrabFocus(); virtual void Dispose(); // TaskPaneToolPanel overridables virtual const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XResourceId >& getResourceId() const; - virtual ::Window* getPanelWindow() const; private: - bool impl_ensureControl(); + bool impl_ensureControl(); + ::Window* impl_getPanelWindow() const; private: ::std::auto_ptr< ControlFactory > m_pControlFactory; diff --git a/sd/source/ui/toolpanel/TaskPaneToolPanel.cxx b/sd/source/ui/toolpanel/TaskPaneToolPanel.cxx index 5dc8498abbe4..4d0103086932 100644 --- a/sd/source/ui/toolpanel/TaskPaneToolPanel.cxx +++ b/sd/source/ui/toolpanel/TaskPaneToolPanel.cxx @@ -90,39 +90,6 @@ namespace sd { namespace toolpanel } //------------------------------------------------------------------------------------------------------------------ - void TaskPaneToolPanel::Activate( ::Window& i_rParentWindow ) - { - Window* pPanelWindow( getPanelWindow() ); - ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to show" ); - pPanelWindow->SetPosSizePixel( Point(), i_rParentWindow.GetSizePixel() ); - pPanelWindow->Show(); - } - - //------------------------------------------------------------------------------------------------------------------ - void TaskPaneToolPanel::Deactivate() - { - Window* pPanelWindow( getPanelWindow() ); - ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to hide" ); - pPanelWindow->Hide(); - } - - //------------------------------------------------------------------------------------------------------------------ - void TaskPaneToolPanel::SetSizePixel( const Size& i_rPanelWindowSize ) - { - Window* pPanelWindow( getPanelWindow() ); - ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to resize" ); - pPanelWindow->SetSizePixel( i_rPanelWindowSize ); - } - - //------------------------------------------------------------------------------------------------------------------ - void TaskPaneToolPanel::GrabFocus() - { - Window* pPanelWindow( getPanelWindow() ); - ENSURE_OR_RETURN_VOID( pPanelWindow, "no window to focus" ); - pPanelWindow->GrabFocus(); - } - - //------------------------------------------------------------------------------------------------------------------ void TaskPaneToolPanel::Dispose() { ENSURE_OR_RETURN_VOID( m_pPanelDeck, "disposed twice" ); diff --git a/sd/source/ui/toolpanel/TaskPaneToolPanel.hxx b/sd/source/ui/toolpanel/TaskPaneToolPanel.hxx index 7cf60b10325e..f62e0b7a8fb1 100644 --- a/sd/source/ui/toolpanel/TaskPaneToolPanel.hxx +++ b/sd/source/ui/toolpanel/TaskPaneToolPanel.hxx @@ -65,15 +65,15 @@ namespace sd { namespace toolpanel // IToolPanel overridables virtual ::rtl::OUString GetDisplayName() const; virtual Image GetImage() const; - virtual void Activate( ::Window& i_rParentWindow ); - virtual void Deactivate(); - virtual void SetSizePixel( const Size& i_rPanelWindowSize ); - virtual void GrabFocus(); virtual void Dispose(); + // those are still abstract, and waiting to be overloaded + virtual void Activate( ::Window& i_rParentWindow ) = 0; + virtual void Deactivate() = 0; + virtual void SetSizePixel( const Size& i_rPanelWindowSize ) = 0; + virtual void GrabFocus() = 0; // own overridables virtual const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::framework::XResourceId >& getResourceId() const = 0; - virtual ::Window* getPanelWindow() const = 0; protected: bool isDisposed() const { return m_pPanelDeck == NULL; } diff --git a/sd/source/ui/toolpanel/ToolPanelDrawer.cxx b/sd/source/ui/toolpanel/ToolPanelDrawer.cxx index c071e5e611c1..a52771650a04 100644 --- a/sd/source/ui/toolpanel/ToolPanelDrawer.cxx +++ b/sd/source/ui/toolpanel/ToolPanelDrawer.cxx @@ -44,6 +44,7 @@ namespace sd { namespace toolpanel :m_rParentWindow( i_rParentWindow ) ,m_rPanelDeck( i_rPanels ) ,m_aDrawers() + ,m_aLastKnownActivePanel() { m_rPanelDeck.AddListener( *this ); @@ -68,7 +69,9 @@ namespace sd { namespace toolpanel return i_rDeckPlayground; const int nWidth( i_rDeckPlayground.GetWidth() ); - const ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() ); + ::boost::optional< size_t > aActivePanel( m_rPanelDeck.GetActivePanel() ); + if ( !aActivePanel ) + aActivePanel = m_aLastKnownActivePanel; // arrange the title bars which are *above* the active panel (or *all* if there is no active panel), plus // the title bar of the active panel itself diff --git a/sd/source/ui/toolpanel/ToolPanelDrawer.hxx b/sd/source/ui/toolpanel/ToolPanelDrawer.hxx index 7972255b3a56..005194ab6a2b 100644 --- a/sd/source/ui/toolpanel/ToolPanelDrawer.hxx +++ b/sd/source/ui/toolpanel/ToolPanelDrawer.hxx @@ -84,6 +84,7 @@ private: Window& m_rParentWindow; ::svt::IToolPanelDeck& m_rPanelDeck; ::std::vector< PTitleBar > m_aDrawers; + ::boost::optional< size_t > m_aLastKnownActivePanel; }; //...................................................................................................................... diff --git a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx index 276cc5a83fec..d8af5aae2b53 100644 --- a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx +++ b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx @@ -79,6 +79,8 @@ #include <unotools/confignode.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/componentcontext.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/basemutex.hxx> #include <vector> @@ -103,6 +105,11 @@ using ::com::sun::star::accessibility::XAccessible; using ::com::sun::star::drawing::XDrawSubController; using ::com::sun::star::frame::XFrame; using ::com::sun::star::drawing::framework::XResourceId; +using ::com::sun::star::drawing::framework::XConfigurationChangeListener; +using ::com::sun::star::drawing::framework::ConfigurationChangeEvent; +using ::com::sun::star::lang::EventObject; +using ::com::sun::star::lang::DisposedException; +using ::com::sun::star::drawing::framework::XConfigurationControllerBroadcaster; /** === end UNO using === **/ using ::sd::framework::FrameworkHelper; @@ -112,7 +119,7 @@ namespace sd { namespace toolpanel { // ===================================================================================================================== // = PanelDescriptor // ===================================================================================================================== -/** is a helper class for ToolPanelViewShell::Implementation, holding the details about a single panel which is not +/** is a helper class for ToolPanelViewShell_Impl, holding the details about a single panel which is not contained in the IToolPanel implementation itself. */ struct PanelDescriptor @@ -149,17 +156,53 @@ enum PanelSelectorLayout }; // ===================================================================================================================== -// = ToolPanelViewShell::Implementation - declaration +// = ConfigurationListener - declaration +// ===================================================================================================================== +typedef ::cppu::WeakImplHelper1 < XConfigurationChangeListener + > ConfigurationListener_Base; + +class ConfigurationListener :public ::cppu::BaseMutex + ,public ConfigurationListener_Base +{ +public: + ConfigurationListener( ToolPanelViewShell_Impl& i_rShellImpl ); + + // XConfigurationChangeListener + virtual void SAL_CALL notifyConfigurationChange( const ConfigurationChangeEvent& aEvent ) throw (RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); + + // XComponent equivalents (not available per UNO interface) + void dispose(); + +protected: + ~ConfigurationListener(); + + void impl_checkDisposed_throw() + { + if ( !m_pShellImpl ) + throw DisposedException( ::rtl::OUString(), *this ); + } + +private: + ToolPanelViewShell_Impl* m_pShellImpl; +}; + +// ===================================================================================================================== +// = ToolPanelViewShell_Impl - declaration // ===================================================================================================================== /** Inner implementation class of ToolPanelViewShell. */ -class ToolPanelViewShell::Implementation : public ::svt::IToolPanelDeckListener +class ToolPanelViewShell_Impl : public ::svt::IToolPanelDeckListener { public: static const size_t mnInvalidId = static_cast< size_t >( -1 ); - Implementation( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent ); - ~Implementation(); + ToolPanelViewShell_Impl( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent ); + ~ToolPanelViewShell_Impl(); + + ToolPanelViewShell& GetAntiImpl() { return m_rPanelViewShell; } /** Here the panels are created that are shown in the task pane. */ @@ -178,11 +221,17 @@ public: PanelSelectorLayout GetLayout() const { return m_eCurrentLayout; } + /** called by our configuration controller listener when the request to activate a tool panel has been observed. + */ + void OnToolPanelActivationRequest( const ::rtl::OUString& i_rResourceURL ); + /** provides access to the the VCL window of the panel deck */ ::Window& GetPanelDeck() { return *m_pPanelDeck.get(); } const ::Window& GetPanelDeck() const { return *m_pPanelDeck.get(); } + ::Window* GetToolPanelParentWindow() { return m_pPanelDeck.get() ? &m_pPanelDeck->GetPanelWindowAnchor() : NULL; } + /** returns the logical number of panels. This is greater than or equal to the number of panels displayed in the panel deck */ @@ -231,11 +280,89 @@ private: PanelDescriptors m_aPanels; ToolPanelViewShell& m_rPanelViewShell; ::boost::scoped_ptr< ToolPanelDeck > m_pPanelDeck; + ::rtl::Reference< ConfigurationListener > m_pConfigListener; PanelSelectorLayout m_eCurrentLayout; bool m_bInitialized; }; // ===================================================================================================================== +// = ConfigurationListener - implementation +// ===================================================================================================================== +// --------------------------------------------------------------------------------------------------------------------- +ConfigurationListener::ConfigurationListener( ToolPanelViewShell_Impl& i_rShellImpl ) + :m_pShellImpl( &i_rShellImpl ) +{ + ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( i_rShellImpl.GetAntiImpl().GetViewShellBase() ) ); + Reference< XConfigurationControllerBroadcaster > xBroadcaster; + if ( pFrameworkHelper.get() ) + xBroadcaster.set( pFrameworkHelper->GetConfigurationController().get() ); + ENSURE_OR_THROW( pFrameworkHelper.get(), "no access to the config controller" ); + + osl_incrementInterlockedCount( &m_refCount ); + { + xBroadcaster->addConfigurationChangeListener( this, ::rtl::OUString(), Any() ); + } + osl_decrementInterlockedCount( &m_refCount ); +} + +// --------------------------------------------------------------------------------------------------------------------- +ConfigurationListener::~ConfigurationListener() +{ +} + +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL ConfigurationListener::notifyConfigurationChange( const ConfigurationChangeEvent& i_rEvent ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + impl_checkDisposed_throw(); + +// if ( i_rEvent.Type == FrameworkHelper::msConfigurationUpdateStartEvent ) +// { +// m_pShellImpl->GetPanelDeck().SetUpdateMode( FALSE ); +// return; +// } +// if ( i_rEvent.Type == FrameworkHelper::msConfigurationUpdateEndEvent ) +// { +// m_pShellImpl->GetPanelDeck().SetUpdateMode( TRUE ); +// return; +// } +// + // is this an event we're interested in? + if ( i_rEvent.Type != FrameworkHelper::msResourceActivationEvent ) + return; + + // is this a resource we're interested in? Must be anchored in the task pane ... + Reference< XResourceId > xAnchorId; + if ( i_rEvent.ResourceId.is() ) + xAnchorId = i_rEvent.ResourceId->getAnchor(); + if ( !xAnchorId.is() ) + return; + const ::rtl::OUString sAnchorURL( xAnchorId->getResourceURL() ); + if ( sAnchorURL != FrameworkHelper::msTaskPaneURL ) + return; + + m_pShellImpl->OnToolPanelActivationRequest( i_rEvent.ResourceId->getResourceURL() ); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL ConfigurationListener::disposing( const EventObject& i_rEvent ) throw (RuntimeException) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + impl_checkDisposed_throw(); + } + + dispose(); +} + +// --------------------------------------------------------------------------------------------------------------------- +void ConfigurationListener::dispose() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_pShellImpl = NULL; +} + +// ===================================================================================================================== // = helpers // ===================================================================================================================== // --------------------------------------------------------------------------------------------------------------------- @@ -263,7 +390,7 @@ SFX_IMPL_INTERFACE(ToolPanelViewShell, SfxShell, SdResId(STR_TASKPANEVIEWSHELL)) TYPEINIT1(ToolPanelViewShell, ViewShell); // --------------------------------------------------------------------------------------------------------------------- -size_t ToolPanelViewShell::Implementation::SetupDefaultPanels() +size_t ToolPanelViewShell_Impl::SetupDefaultPanels() { typedef std::auto_ptr<ControlFactory> (*ControlFactoryFactory)( ToolPanelViewShell& i_rToolPanelShell ); @@ -365,7 +492,7 @@ size_t ToolPanelViewShell::Implementation::SetupDefaultPanels() } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::SetupCustomPanels() +void ToolPanelViewShell_Impl::SetupCustomPanels() { // compose the resource ID for the ToolPanel view ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( m_rPanelViewShell.GetViewShellBase() ) ); @@ -396,7 +523,7 @@ void ToolPanelViewShell::Implementation::SetupCustomPanels() } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::Setup() +void ToolPanelViewShell_Impl::Setup() { if ( m_bInitialized ) return; @@ -417,11 +544,14 @@ void ToolPanelViewShell::Implementation::Setup() // initialize panel selector SetLayout( LAYOUT_DRAWERS, true ); + // listen at the configuration + m_pConfigListener.set( new ConfigurationListener( *this ) ); + m_pPanelDeck->Show(); } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::SetLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce ) +void ToolPanelViewShell_Impl::SetLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce ) { if ( !i_bForce && ( m_eCurrentLayout == i_eLayout ) ) return; @@ -449,9 +579,9 @@ void ToolPanelViewShell::Implementation::SetLayout( const PanelSelectorLayout i_ } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::Cleanup() +void ToolPanelViewShell_Impl::Cleanup() { - if ( !m_bInitialized ) + if ( m_bInitialized ) { m_pPanelDeck->RemoveListener( *this ); // remove the panels which are not under the control of the panel deck currently @@ -464,11 +594,49 @@ void ToolPanelViewShell::Implementation::Cleanup() panelPos->pPanel->Dispose(); } m_aPanels.clear(); + + if ( m_pConfigListener.is() ) + m_pConfigListener->dispose(); } m_pPanelDeck.reset(); } // --------------------------------------------------------------------------------------------------------------------- +void ToolPanelViewShell_Impl::OnToolPanelActivationRequest( const ::rtl::OUString& i_rResourceURL ) +{ + // look up the panel which belongs to the given resource + for ( size_t i=0; i<GetPanelCount(); ++i ) + { + const PanelDescriptor& rPanel = GetPanel( i ); + const TaskPaneToolPanel* pPanel( dynamic_cast< const TaskPaneToolPanel* >( rPanel.pPanel.get() ) ); + ENSURE_OR_CONTINUE( pPanel != NULL, "ToolPanelViewShell::OnToolPanelActivationRequest: illegal panel implementation!" ); + + Reference< XResourceId > xPanelId( pPanel->getResourceId() ); + ::rtl::OUString sPanelURL( xPanelId.is() ? xPanelId->getResourceURL() : ::rtl::OUString() ); + ENSURE_OR_CONTINUE( sPanelURL.getLength(), "illegal panel resource!" ); + + if ( sPanelURL == i_rResourceURL ) + { + CustomToolPanel* pCustomPanel = dynamic_cast< CustomToolPanel* >( rPanel.pPanel.get() ); + OSL_ENSURE( ( pCustomPanel != NULL ) == ( rPanel.nId >= PID_FIRST_CUSTOM_PANEL ), + "ToolPanelViewShell::OnToolPanelActivationRequest: inconsistency!" ); + if ( pCustomPanel != NULL ) + { + // if that's a custom tool panel, then temporarily disable the access of the tool panel implementation + // to the XPane object. Otherwise, it would request this resource from the configuration controller during + // the below ActivatePanelDirectly call, which would fail, since the resource is just to be created. + pCustomPanel->LockResourceAccess(); + } + ActivatePanelDirectly( rPanel.nId ); + if ( pCustomPanel != NULL ) + { + pCustomPanel->UnlockResourceAccess(); + } + } + } +} + +// --------------------------------------------------------------------------------------------------------------------- void ToolPanelViewShell::Initialize() { mpImpl->Setup(); @@ -478,7 +646,7 @@ void ToolPanelViewShell::Initialize() ToolPanelViewShell::ToolPanelViewShell( SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow, FrameView* pFrameViewArgument ) :ViewShell(pFrame, pParentWindow, rViewShellBase) - ,mpImpl( new Implementation( *this, *mpContentWindow.get() ) ) + ,mpImpl( new ToolPanelViewShell_Impl( *this, *mpContentWindow.get() ) ) ,mpSubShellManager() ,mnMenuId(0) { @@ -852,6 +1020,12 @@ bool ToolPanelViewShell::RelocateToParentWindow( ::Window* pParentWindow ) } // --------------------------------------------------------------------------------------------------------------------- +::Window* ToolPanelViewShell::GetToolPanelParentWindow() +{ + return mpImpl->GetToolPanelParentWindow(); +} + +//--------------------------------------------------------------------------------------------------------------------- void ToolPanelViewShell::DeactivatePanel( const PanelId i_ePanelId ) { mpImpl->DeactivatePanelDirectly( i_ePanelId ); @@ -865,10 +1039,10 @@ void ToolPanelViewShell::ActivatePanel( const PanelId i_ePanelId ) // ===================================================================================================================== -// = ToolPanelViewShell:Implementation - implementation +// = ToolPanelViewShell_Impl - implementation // ===================================================================================================================== // --------------------------------------------------------------------------------------------------------------------- -ToolPanelViewShell::Implementation::Implementation( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent ) +ToolPanelViewShell_Impl::ToolPanelViewShell_Impl( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent ) :m_aPanels() ,m_rPanelViewShell( i_rPanelViewShell ) ,m_pPanelDeck( new ToolPanelDeck( i_rPanelDeckParent, i_rPanelViewShell ) ) @@ -878,12 +1052,12 @@ ToolPanelViewShell::Implementation::Implementation( ToolPanelViewShell& i_rPanel } // --------------------------------------------------------------------------------------------------------------------- -ToolPanelViewShell::Implementation::~Implementation() +ToolPanelViewShell_Impl::~ToolPanelViewShell_Impl() { } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::TogglePanelVisibility( const size_t i_nLogicalPanelIndex ) +void ToolPanelViewShell_Impl::TogglePanelVisibility( const size_t i_nLogicalPanelIndex ) { ENSURE_OR_RETURN_VOID( i_nLogicalPanelIndex < m_aPanels.size(), "illegal index" ); @@ -910,7 +1084,7 @@ void ToolPanelViewShell::Implementation::TogglePanelVisibility( const size_t i_n } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::DeactivatePanelDirectly( const PanelId i_nPanelId ) +void ToolPanelViewShell_Impl::DeactivatePanelDirectly( const PanelId i_nPanelId ) { for ( size_t i=0; i<m_aPanels.size(); ++i ) { @@ -924,7 +1098,7 @@ void ToolPanelViewShell::Implementation::DeactivatePanelDirectly( const PanelId } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::ActivatePanelDirectly( const PanelId i_nPanelId ) +void ToolPanelViewShell_Impl::ActivatePanelDirectly( const PanelId i_nPanelId ) { size_t nActualPanelIndex(0); for ( size_t i=0; i<m_aPanels.size(); ++i ) @@ -943,34 +1117,34 @@ void ToolPanelViewShell::Implementation::ActivatePanelDirectly( const PanelId i_ } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::RegisterPanel( size_t i_nPosition, PanelId i_nPanelId, const ::svt::PToolPanel& i_rPanel ) +void ToolPanelViewShell_Impl::RegisterPanel( size_t i_nPosition, PanelId i_nPanelId, const ::svt::PToolPanel& i_rPanel ) { if ( i_nPosition >= m_aPanels.size() ) m_aPanels.resize( i_nPosition + 1 ); - OSL_PRECOND( m_aPanels[ i_nPosition ].nId == PID_UNKNOWN, "ToolPanelViewShell::Implementation::RegisterPanel: " + OSL_PRECOND( m_aPanels[ i_nPosition ].nId == PID_UNKNOWN, "ToolPanelViewShell_Impl::RegisterPanel: " "already registered a panel for this ID!" ); m_aPanels[ i_nPosition ] = PanelDescriptor( i_nPanelId, i_rPanel ); } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) +void ToolPanelViewShell_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) { (void)i_pPanel; (void)i_nPosition; } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::PanelRemoved( const size_t i_nPosition ) +void ToolPanelViewShell_Impl::PanelRemoved( const size_t i_nPosition ) { (void)i_nPosition; } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::UpdateDockingWindowTitle() +void ToolPanelViewShell_Impl::UpdateDockingWindowTitle() { PaneDockingWindow* pDockingWindow = dynamic_cast< PaneDockingWindow* >( m_rPanelViewShell.GetDockingWindow() ); - ENSURE_OR_RETURN_VOID( pDockingWindow, "ToolPanelViewShell::Implementation::UpdateDockingWindowTitle: no PaneDockingWindow!?" ); + ENSURE_OR_RETURN_VOID( pDockingWindow, "ToolPanelViewShell_Impl::UpdateDockingWindowTitle: no PaneDockingWindow!?" ); ::boost::optional< size_t > aActivePanel( m_pPanelDeck->GetActivePanel() ); if ( !aActivePanel || ( GetLayout() == LAYOUT_DRAWERS ) ) @@ -994,7 +1168,7 @@ void ToolPanelViewShell::Implementation::UpdateDockingWindowTitle() } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) +void ToolPanelViewShell_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) { if ( GetLayout() == LAYOUT_DRAWERS ) // no adjustment of the title when we use the classical "drawers" layout @@ -1006,7 +1180,7 @@ void ToolPanelViewShell::Implementation::ActivePanelChanged( const ::boost::opti } // --------------------------------------------------------------------------------------------------------------------- -void ToolPanelViewShell::Implementation::Dying() +void ToolPanelViewShell_Impl::Dying() { } |