| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_sfx2.hxx" |
| |
| #include "sfx2/taskpane.hxx" |
| #include "imagemgr.hxx" |
| #include "sfx2/sfxsids.hrc" |
| #include "sfx2/bindings.hxx" |
| #include "sfx2/dispatch.hxx" |
| #include "sfxresid.hxx" |
| #include "sfxlocal.hrc" |
| #include "helpid.hrc" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/ui/XToolPanel.hpp> |
| #include <com/sun/star/ui/XUIElementFactory.hpp> |
| #include <com/sun/star/awt/XWindowPeer.hpp> |
| #include <com/sun/star/awt/PosSize.hpp> |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #include <com/sun/star/graphic/XGraphicProvider.hpp> |
| #include <com/sun/star/accessibility/XAccessible.hpp> |
| #include <com/sun/star/awt/XControl.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <comphelper/componentcontext.hxx> |
| #include <comphelper/namedvaluecollection.hxx> |
| #include <comphelper/types.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <svtools/toolpanel/toolpaneldeck.hxx> |
| #include <svtools/toolpanel/tablayouter.hxx> |
| #include <svtools/toolpanel/drawerlayouter.hxx> |
| #include <unotools/confignode.hxx> |
| #include <vcl/menu.hxx> |
| #include <vcl/svapp.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <tools/urlobj.hxx> |
| #include <boost/noncopyable.hpp> |
| |
| //...................................................................................................................... |
| namespace sfx2 |
| { |
| //...................................................................................................................... |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::XInterface; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_SET_THROW; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Type; |
| using ::com::sun::star::frame::XModuleManager; |
| using ::com::sun::star::container::XNameAccess; |
| using ::com::sun::star::ui::XToolPanel; |
| using ::com::sun::star::ui::XUIElementFactory; |
| using ::com::sun::star::ui::XUIElement; |
| using ::com::sun::star::awt::XWindow; |
| using ::com::sun::star::frame::XModuleManager; |
| using ::com::sun::star::frame::XFrame; |
| using ::com::sun::star::lang::XComponent; |
| using ::com::sun::star::graphic::XGraphicProvider; |
| using ::com::sun::star::graphic::XGraphic; |
| using ::com::sun::star::accessibility::XAccessible; |
| using ::com::sun::star::awt::XControl; |
| /** === end UNO using === **/ |
| namespace PosSize = ::com::sun::star::awt::PosSize; |
| |
| //================================================================================================================== |
| //= helpers |
| //================================================================================================================== |
| namespace |
| { |
| //-------------------------------------------------------------------------------------------------------------- |
| ::utl::OConfigurationTreeRoot lcl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier, |
| const ::rtl::OUString& i_rResourceURL = ::rtl::OUString() ) |
| { |
| const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| ::rtl::OUStringBuffer aPathComposer; |
| try |
| { |
| const Reference< XNameAccess > xModuleAccess( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); |
| const ::comphelper::NamedValueCollection aModuleProps( xModuleAccess->getByName( i_rModuleIdentifier ) ); |
| |
| const ::rtl::OUString sWindowStateRef( aModuleProps.getOrDefault( "ooSetupFactoryWindowStateConfigRef", ::rtl::OUString() ) ); |
| |
| aPathComposer.appendAscii( "org.openoffice.Office.UI." ); |
| aPathComposer.append( sWindowStateRef ); |
| aPathComposer.appendAscii( "/UIElements/States" ); |
| if ( i_rResourceURL.getLength() ) |
| { |
| aPathComposer.appendAscii( "/" ); |
| aPathComposer.append( i_rResourceURL ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return ::utl::OConfigurationTreeRoot( aContext, aPathComposer.makeStringAndClear(), false ); |
| } |
| |
| //-------------------------------------------------------------------------------------------------------------- |
| ::rtl::OUString lcl_identifyModule( const Reference< XFrame >& i_rDocumentFrame ) |
| { |
| ::rtl::OUString sModuleName; |
| try |
| { |
| const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| const Reference< XModuleManager > xModuleManager( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); |
| sModuleName = xModuleManager->identify( i_rDocumentFrame ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return sModuleName; |
| } |
| |
| //-------------------------------------------------------------------------------------------------------------- |
| Reference< XFrame > lcl_getFrame( const SfxBindings* i_pBindings ) |
| { |
| const SfxViewFrame* pViewFrame = i_pBindings->GetDispatcher()->GetFrame(); |
| const SfxFrame& rFrame = pViewFrame->GetFrame(); |
| const Reference< XFrame > xFrame( rFrame.GetFrameInterface() ); |
| return xFrame; |
| } |
| |
| //-------------------------------------------------------------------------------------------------------------- |
| ::rtl::OUString lcl_getPanelHelpURL( const ::utl::OConfigurationNode& i_rPanelConfigNode ) |
| { |
| const ::rtl::OUString sHelpURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "HelpURL" ) ) ); |
| return sHelpURL; |
| } |
| |
| //-------------------------------------------------------------------------------------------------------------- |
| Image lcl_getPanelImage( const Reference< XFrame >& i_rDocFrame, const ::utl::OConfigurationNode& i_rPanelConfigNode ) |
| { |
| const ::rtl::OUString sImageURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "ImageURL" ) ) ); |
| if ( sImageURL.getLength() ) |
| { |
| try |
| { |
| ::comphelper::NamedValueCollection aMediaProperties; |
| aMediaProperties.put( "URL", sImageURL ); |
| |
| // special handling: if the ImageURL denotes a CommandName, then retrieve the image for that command |
| const sal_Char* pCommandImagePrefix = "private:commandimage/"; |
| const sal_Int32 nCommandImagePrefixLen = strlen( pCommandImagePrefix ); |
| if ( sImageURL.compareToAscii( pCommandImagePrefix, nCommandImagePrefixLen ) == 0 ) |
| { |
| ::rtl::OUStringBuffer aCommandName; |
| aCommandName.appendAscii( ".uno:" ); |
| aCommandName.append( sImageURL.copy( nCommandImagePrefixLen ) ); |
| const ::rtl::OUString sCommandName( aCommandName.makeStringAndClear() ); |
| |
| const sal_Bool bHiContrast( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ); |
| const Image aPanelImage( GetImage( i_rDocFrame, sCommandName, sal_False, bHiContrast ) ); |
| return aPanelImage.GetXGraphic(); |
| } |
| |
| // otherwise, delegate to the GraphicProvider |
| const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| const Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW ); |
| |
| const Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_SET_THROW ); |
| return Image( xGraphic ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| return Image(); |
| } |
| } |
| |
| //================================================================================================================== |
| //= TaskPaneDockingWindow |
| //================================================================================================================== |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneDockingWindow::TaskPaneDockingWindow( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits ) |
| :TitledDockingWindow( i_pBindings, &i_rWrapper, i_pParent, i_nBits ) |
| ,m_aTaskPane( GetContentWindow(), lcl_getFrame( i_pBindings ) ) |
| ,m_aPaneController( m_aTaskPane, *this ) |
| { |
| m_aTaskPane.Show(); |
| SetText( String( SfxResId( SID_TASKPANE ) ) ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneDockingWindow::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) |
| { |
| m_aPaneController.ActivateToolPanel( i_rPanelURL ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneDockingWindow::GetFocus() |
| { |
| TitledDockingWindow::GetFocus(); |
| m_aTaskPane.GrabFocus(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneDockingWindow::onLayoutDone() |
| { |
| m_aTaskPane.SetPosSizePixel( Point(), GetContentWindow().GetOutputSizePixel() ); |
| } |
| |
| //================================================================================================================== |
| //= TaskPaneWrapper |
| //================================================================================================================== |
| //------------------------------------------------------------------------------------------------------------------ |
| SFX_IMPL_DOCKINGWINDOW( TaskPaneWrapper, SID_TASKPANE ); |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneWrapper::TaskPaneWrapper( Window* i_pParent, sal_uInt16 i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pInfo ) |
| :SfxChildWindow( i_pParent, i_nId ) |
| { |
| pWindow = new TaskPaneDockingWindow( i_pBindings, *this, i_pParent, |
| WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE); |
| eChildAlignment = SFX_ALIGN_RIGHT; |
| |
| pWindow->SetHelpId( HID_TASKPANE_WINDOW ); |
| pWindow->SetOutputSizePixel( Size( 300, 450 ) ); |
| |
| dynamic_cast< SfxDockingWindow* >( pWindow )->Initialize( i_pInfo ); |
| SetHideNotDelete( sal_True ); |
| |
| pWindow->Show(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneWrapper::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) |
| { |
| TaskPaneDockingWindow* pDockingWindow = dynamic_cast< TaskPaneDockingWindow* >( GetWindow() ); |
| ENSURE_OR_RETURN_VOID( pDockingWindow, "TaskPaneWrapper::ActivateToolPanel: invalid docking window implementation!" ); |
| pDockingWindow->ActivateToolPanel( i_rPanelURL ); |
| } |
| |
| //================================================================================================================== |
| //= CustomPanelUIElement |
| //================================================================================================================== |
| class CustomPanelUIElement |
| { |
| public: |
| CustomPanelUIElement() |
| :m_xUIElement() |
| ,m_xToolPanel() |
| ,m_xPanelWindow() |
| { |
| } |
| |
| CustomPanelUIElement( const Reference< XUIElement >& i_rUIElement ) |
| :m_xUIElement( i_rUIElement, UNO_SET_THROW ) |
| ,m_xToolPanel( i_rUIElement->getRealInterface(), UNO_QUERY_THROW ) |
| ,m_xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW ) |
| { |
| } |
| |
| bool is() const { return m_xPanelWindow.is(); } |
| |
| const Reference< XUIElement >& getUIElement() const { return m_xUIElement; } |
| const Reference< XToolPanel >& getToolPanel() const { return m_xToolPanel; } |
| const Reference< XWindow >& getPanelWindow() const { return m_xPanelWindow; } |
| |
| private: |
| Reference< XUIElement > m_xUIElement; |
| Reference< XToolPanel > m_xToolPanel; |
| Reference< XWindow > m_xPanelWindow; |
| }; |
| |
| //================================================================================================================== |
| //= CustomToolPanel |
| //================================================================================================================== |
| class CustomToolPanel : public ::svt::ToolPanelBase |
| { |
| public: |
| CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame ); |
| |
| virtual ::rtl::OUString GetDisplayName() const; |
| virtual Image GetImage() const; |
| virtual rtl::OString GetHelpID() const; |
| virtual void Activate( Window& i_rParentWindow ); |
| virtual void Deactivate(); |
| virtual void SetSizePixel( const Size& i_rPanelWindowSize ); |
| virtual void GrabFocus(); |
| virtual void Dispose(); |
| virtual Reference< XAccessible > |
| CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ); |
| |
| const ::rtl::OUString& |
| GetResourceURL() const { return m_sResourceURL; } |
| |
| protected: |
| ~CustomToolPanel(); |
| |
| private: |
| bool impl_ensureToolPanelWindow( Window& i_rPanelParentWindow ); |
| void impl_updatePanelConfig( const bool i_bVisible ) const; |
| |
| private: |
| const ::rtl::OUString m_sUIName; |
| const Image m_aPanelImage; |
| const ::rtl::OUString m_aPanelHelpURL; |
| const ::rtl::OUString m_sResourceURL; |
| const ::rtl::OUString m_sPanelConfigPath; |
| Reference< XFrame > m_xFrame; |
| CustomPanelUIElement m_aCustomPanel; |
| bool m_bAttemptedCreation; |
| }; |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| CustomToolPanel::CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame ) |
| :m_sUIName( ::comphelper::getString( i_rPanelWindowState.getNodeValue( "UIName" ) ) ) |
| ,m_aPanelImage( lcl_getPanelImage( i_rFrame, i_rPanelWindowState ) ) |
| ,m_aPanelHelpURL( lcl_getPanelHelpURL( i_rPanelWindowState ) ) |
| ,m_sResourceURL( i_rPanelWindowState.getLocalName() ) |
| ,m_sPanelConfigPath( i_rPanelWindowState.getNodePath() ) |
| ,m_xFrame( i_rFrame ) |
| ,m_aCustomPanel() |
| ,m_bAttemptedCreation( false ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| CustomToolPanel::~CustomToolPanel() |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| bool CustomToolPanel::impl_ensureToolPanelWindow( Window& i_rPanelParentWindow ) |
| { |
| if ( m_bAttemptedCreation ) |
| return m_aCustomPanel.is(); |
| |
| m_bAttemptedCreation = true; |
| try |
| { |
| const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| const Reference< XUIElementFactory > xFactory( aContext.createComponent( "com.sun.star.ui.UIElementFactoryManager" ), UNO_QUERY_THROW ); |
| |
| ::comphelper::NamedValueCollection aCreationArgs; |
| aCreationArgs.put( "Frame", makeAny( m_xFrame ) ); |
| aCreationArgs.put( "ParentWindow", makeAny( i_rPanelParentWindow.GetComponentInterface() ) ); |
| |
| const Reference< XUIElement > xElement( |
| xFactory->createUIElement( m_sResourceURL, aCreationArgs.getPropertyValues() ), |
| UNO_SET_THROW ); |
| |
| m_aCustomPanel = CustomPanelUIElement( xElement ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return m_aCustomPanel.is(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::impl_updatePanelConfig( const bool i_bVisible ) const |
| { |
| ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| ::utl::OConfigurationTreeRoot aConfig( aContext, m_sPanelConfigPath, true ); |
| |
| aConfig.setNodeValue( "Visible", makeAny( i_bVisible ) ); |
| aConfig.commit(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::rtl::OUString CustomToolPanel::GetDisplayName() const |
| { |
| return m_sUIName; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| Image CustomToolPanel::GetImage() const |
| { |
| return m_aPanelImage; |
| } |
| |
| static rtl::OString lcl_getHelpId( const ::rtl::OUString& _rHelpURL ) |
| { |
| INetURLObject aHID( _rHelpURL ); |
| if ( aHID.GetProtocol() == INET_PROT_HID ) |
| return rtl::OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 ); |
| else |
| return rtl::OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| rtl::OString CustomToolPanel::GetHelpID() const |
| { |
| return lcl_getHelpId( m_aPanelHelpURL ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::Activate( Window& i_rParentWindow ) |
| { |
| ENSURE_OR_RETURN_VOID( impl_ensureToolPanelWindow( i_rParentWindow ), "no panel to activate!" ); |
| |
| // TODO: we might need a mechanism to decide whether the panel should be destroyed/re-created, or (as it is |
| // done now) hidden/shown |
| m_aCustomPanel.getPanelWindow()->setVisible( sal_True ); |
| |
| // update the panel's configuration |
| impl_updatePanelConfig( true ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::Deactivate() |
| { |
| ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to deactivate!" ); |
| |
| m_aCustomPanel.getPanelWindow()->setVisible( sal_False ); |
| |
| // update the panel's configuration |
| impl_updatePanelConfig( false ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::SetSizePixel( const Size& i_rPanelWindowSize ) |
| { |
| ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to position!" ); |
| |
| try |
| { |
| m_aCustomPanel.getPanelWindow()->setPosSize( 0, 0, i_rPanelWindowSize.Width(), i_rPanelWindowSize.Height(), |
| PosSize::POSSIZE ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::GrabFocus() |
| { |
| ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to focus!" ); |
| |
| m_aCustomPanel.getPanelWindow()->setFocus(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void CustomToolPanel::Dispose() |
| { |
| if ( !m_bAttemptedCreation ) |
| // nothing to dispose |
| return; |
| |
| ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to destroy!" ); |
| try |
| { |
| Reference< XComponent > xUIElementComponent( m_aCustomPanel.getUIElement(), UNO_QUERY_THROW ); |
| xUIElementComponent->dispose(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| Reference< XAccessible > CustomToolPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ) |
| { |
| ENSURE_OR_RETURN( m_aCustomPanel.is(), "no panel to ask!", NULL ); |
| |
| Reference< XAccessible > xPanelAccessible; |
| try |
| { |
| xPanelAccessible.set( m_aCustomPanel.getToolPanel()->createAccessible( i_rParentAccessible ), UNO_SET_THROW ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return xPanelAccessible; |
| } |
| |
| //================================================================================================================== |
| //= ModuleTaskPane_Impl |
| //================================================================================================================== |
| class ModuleTaskPane_Impl : public ::boost::noncopyable |
| { |
| public: |
| ModuleTaskPane_Impl( ModuleTaskPane& i_rAntiImpl, const Reference< XFrame >& i_rDocumentFrame, |
| const IToolPanelCompare* i_pPanelCompare ) |
| :m_rAntiImpl( i_rAntiImpl ) |
| ,m_sModuleIdentifier( lcl_identifyModule( i_rDocumentFrame ) ) |
| ,m_xFrame( i_rDocumentFrame ) |
| ,m_aPanelDeck( i_rAntiImpl ) |
| { |
| m_aPanelDeck.Show(); |
| OnResize(); |
| impl_initFromConfiguration( i_pPanelCompare ); |
| } |
| |
| ~ModuleTaskPane_Impl() |
| { |
| } |
| |
| void OnResize(); |
| void OnGetFocus(); |
| |
| static bool ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ); |
| |
| ::svt::ToolPanelDeck& GetPanelDeck() { return m_aPanelDeck; } |
| const ::svt::ToolPanelDeck& GetPanelDeck() const { return m_aPanelDeck; } |
| |
| ::boost::optional< size_t > |
| GetPanelPos( const ::rtl::OUString& i_rResourceURL ); |
| ::rtl::OUString |
| GetPanelResourceURL( const size_t i_nPanelPos ) const; |
| |
| void SetDrawersLayout(); |
| void SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ); |
| |
| private: |
| void impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare ); |
| |
| static bool |
| impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL ); |
| |
| DECL_LINK( OnActivatePanel, void* ); |
| |
| private: |
| ModuleTaskPane& m_rAntiImpl; |
| const ::rtl::OUString m_sModuleIdentifier; |
| const Reference< XFrame > m_xFrame; |
| ::svt::ToolPanelDeck m_aPanelDeck; |
| }; |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane_Impl::OnResize() |
| { |
| m_aPanelDeck.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane_Impl::OnGetFocus() |
| { |
| m_aPanelDeck.GrabFocus(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| IMPL_LINK( ModuleTaskPane_Impl, OnActivatePanel, void*, i_pArg ) |
| { |
| m_aPanelDeck.ActivatePanel( reinterpret_cast< size_t >( i_pArg ) ); |
| return 1L; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| bool ModuleTaskPane_Impl::impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL ) |
| { |
| return i_rResourceURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/" ) ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane_Impl::impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare ) |
| { |
| const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( m_sModuleIdentifier ) ); |
| if ( !aWindowStateConfig.isValid() ) |
| return; |
| |
| ::rtl::OUString sFirstVisiblePanelResource; |
| ::rtl::OUString sFirstPanelResource; |
| |
| const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() ); |
| for ( const ::rtl::OUString* resource = aUIElements.getConstArray(); |
| resource != aUIElements.getConstArray() + aUIElements.getLength(); |
| ++resource |
| ) |
| { |
| if ( !impl_isToolPanelResource( *resource ) ) |
| continue; |
| |
| sFirstPanelResource = *resource; |
| |
| ::utl::OConfigurationNode aResourceNode( aWindowStateConfig.openNode( *resource ) ); |
| ::svt::PToolPanel pCustomPanel( new CustomToolPanel( aResourceNode, m_xFrame ) ); |
| |
| size_t nPanelPos = m_aPanelDeck.GetPanelCount(); |
| if ( i_pPanelCompare ) |
| { |
| // assuming that nobody will insert hundreths of panels, a simple O(n) search should suffice here ... |
| while ( nPanelPos > 0 ) |
| { |
| const short nCompare = i_pPanelCompare->compareToolPanelsURLs( |
| *resource, |
| GetPanelResourceURL( --nPanelPos ) |
| ); |
| if ( nCompare >= 0 ) |
| { |
| ++nPanelPos; |
| break; |
| } |
| } |
| } |
| nPanelPos = m_aPanelDeck.InsertPanel( pCustomPanel, nPanelPos ); |
| |
| if ( ::comphelper::getBOOL( aResourceNode.getNodeValue( "Visible" ) ) ) |
| sFirstVisiblePanelResource = *resource; |
| } |
| |
| if ( sFirstVisiblePanelResource.getLength() == 0 ) |
| sFirstVisiblePanelResource = sFirstPanelResource; |
| |
| if ( sFirstVisiblePanelResource.getLength() ) |
| { |
| ::boost::optional< size_t > aPanelPos( GetPanelPos( sFirstVisiblePanelResource ) ); |
| OSL_ENSURE( !!aPanelPos, "ModuleTaskPane_Impl::impl_isToolPanelResource: just inserted it, and it's not there?!" ); |
| if ( !!aPanelPos ) |
| m_rAntiImpl.PostUserEvent( LINK( this, ModuleTaskPane_Impl, OnActivatePanel ), reinterpret_cast< void* >( *aPanelPos ) ); |
| } |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| bool ModuleTaskPane_Impl::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ) |
| { |
| const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( i_rModuleIdentifier ) ); |
| if ( !aWindowStateConfig.isValid() ) |
| return false; |
| |
| const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() ); |
| for ( const ::rtl::OUString* resource = aUIElements.getConstArray(); |
| resource != aUIElements.getConstArray() + aUIElements.getLength(); |
| ++resource |
| ) |
| { |
| if ( impl_isToolPanelResource( *resource ) ) |
| return true; |
| } |
| return false; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::boost::optional< size_t > ModuleTaskPane_Impl::GetPanelPos( const ::rtl::OUString& i_rResourceURL ) |
| { |
| ::boost::optional< size_t > aPanelPos; |
| for ( size_t i = 0; i < m_aPanelDeck.GetPanelCount(); ++i ) |
| { |
| const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i ) ); |
| const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() ); |
| ENSURE_OR_CONTINUE( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!" ); |
| if ( pCustomPanel->GetResourceURL() == i_rResourceURL ) |
| { |
| aPanelPos = i; |
| break; |
| } |
| } |
| return aPanelPos; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::rtl::OUString ModuleTaskPane_Impl::GetPanelResourceURL( const size_t i_nPanelPos ) const |
| { |
| ENSURE_OR_RETURN( i_nPanelPos < m_aPanelDeck.GetPanelCount(), "ModuleTaskPane_Impl::GetPanelResourceURL: illegal panel position!", ::rtl::OUString() ); |
| const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i_nPanelPos ) ); |
| const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() ); |
| ENSURE_OR_RETURN( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!", ::rtl::OUString() ); |
| return pCustomPanel->GetResourceURL(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane_Impl::SetDrawersLayout() |
| { |
| const ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() ); |
| const ::svt::DrawerDeckLayouter* pDrawerLayouter = dynamic_cast< const ::svt::DrawerDeckLayouter* >( pLayouter.get() ); |
| if ( pDrawerLayouter != NULL ) |
| // already have the proper layout |
| return; |
| m_aPanelDeck.SetLayouter( new ::svt::DrawerDeckLayouter( m_aPanelDeck, m_aPanelDeck ) ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane_Impl::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ) |
| { |
| ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() ); |
| ::svt::TabDeckLayouter* pTabLayouter = dynamic_cast< ::svt::TabDeckLayouter* >( pLayouter.get() ); |
| if ( ( pTabLayouter != NULL ) |
| && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) |
| && ( pTabLayouter->GetTabItemContent() == i_eTabContent ) |
| ) |
| // already have the requested layout |
| return; |
| |
| if ( pTabLayouter && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) ) |
| { |
| // changing only the item content does not require a new layouter instance |
| pTabLayouter->SetTabItemContent( i_eTabContent ); |
| return; |
| } |
| |
| m_aPanelDeck.SetLayouter( new ::svt::TabDeckLayouter( m_aPanelDeck, m_aPanelDeck, i_eTabAlignment, i_eTabContent ) ); |
| } |
| |
| //================================================================================================================== |
| //= ModuleTaskPane |
| //================================================================================================================== |
| //------------------------------------------------------------------------------------------------------------------ |
| ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame ) |
| :Window( &i_rParentWindow, WB_DIALOGCONTROL ) |
| ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, NULL ) ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame, |
| const IToolPanelCompare& i_rCompare ) |
| :Window( &i_rParentWindow, WB_DIALOGCONTROL ) |
| ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, &i_rCompare ) ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ModuleTaskPane::~ModuleTaskPane() |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| bool ModuleTaskPane::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ) |
| { |
| return ModuleTaskPane_Impl::ModuleHasToolPanels( i_rModuleIdentifier ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| bool ModuleTaskPane::ModuleHasToolPanels( const Reference< XFrame >& i_rDocumentFrame ) |
| { |
| return ModuleTaskPane_Impl::ModuleHasToolPanels( lcl_identifyModule( i_rDocumentFrame ) ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane::Resize() |
| { |
| Window::Resize(); |
| m_pImpl->OnResize(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane::GetFocus() |
| { |
| Window::GetFocus(); |
| m_pImpl->OnGetFocus(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() |
| { |
| return m_pImpl->GetPanelDeck(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| const ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() const |
| { |
| return m_pImpl->GetPanelDeck(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::boost::optional< size_t > ModuleTaskPane::GetPanelPos( const ::rtl::OUString& i_rResourceURL ) |
| { |
| return m_pImpl->GetPanelPos( i_rResourceURL ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::rtl::OUString ModuleTaskPane::GetPanelResourceURL( const size_t i_nPanelPos ) const |
| { |
| return m_pImpl->GetPanelResourceURL( i_nPanelPos ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane::SetDrawersLayout() |
| { |
| m_pImpl->SetDrawersLayout(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void ModuleTaskPane::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ) |
| { |
| m_pImpl->SetTabsLayout( i_eTabAlignment, i_eTabContent ); |
| } |
| |
| // ===================================================================================================================== |
| // = PanelSelectorLayout |
| // ===================================================================================================================== |
| enum PanelSelectorLayout |
| { |
| LAYOUT_DRAWERS, |
| LAYOUT_TABS_RIGHT, |
| LAYOUT_TABS_LEFT, |
| LAYOUT_TABS_TOP, |
| LAYOUT_TABS_BOTTOM |
| }; |
| |
| //================================================================================================================== |
| //= helper |
| //================================================================================================================== |
| namespace |
| { |
| PanelSelectorLayout lcl_getTabLayoutFromAlignment( const SfxChildAlignment i_eAlignment ) |
| { |
| switch ( i_eAlignment ) |
| { |
| case SFX_ALIGN_LEFT: |
| return LAYOUT_TABS_LEFT; |
| case SFX_ALIGN_TOP: |
| return LAYOUT_TABS_TOP; |
| case SFX_ALIGN_BOTTOM: |
| return LAYOUT_TABS_BOTTOM; |
| default: |
| return LAYOUT_TABS_RIGHT; |
| } |
| } |
| } |
| |
| // ===================================================================================================================== |
| // = PanelDescriptor |
| // ===================================================================================================================== |
| /** is a helper class for TaskPaneController_Impl, holding the details about a single panel which is not |
| contained in the IToolPanel implementation itself. |
| */ |
| struct PanelDescriptor |
| { |
| ::svt::PToolPanel pPanel; |
| bool bHidden; |
| |
| PanelDescriptor() |
| :pPanel() |
| ,bHidden( false ) |
| { |
| } |
| |
| PanelDescriptor( const ::svt::PToolPanel& i_rPanel ) |
| :pPanel( i_rPanel ) |
| ,bHidden( false ) |
| { |
| } |
| }; |
| |
| //================================================================================================================== |
| //= TaskPaneController_Impl |
| //================================================================================================================== |
| class TaskPaneController_Impl :public ::boost::noncopyable |
| ,public ::svt::IToolPanelDeckListener |
| { |
| public: |
| TaskPaneController_Impl( |
| ModuleTaskPane& i_rTaskPane, |
| TitledDockingWindow& i_rDockingWindow |
| ); |
| ~TaskPaneController_Impl(); |
| |
| void SetDefaultTitle( const String& i_rTitle ); |
| void ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ); |
| |
| protected: |
| // IToolPanelDeckListener overridables |
| virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); |
| virtual void PanelRemoved( const size_t i_nPosition ); |
| virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); |
| virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); |
| virtual void Dying(); |
| |
| private: |
| DECL_LINK( OnToolboxClicked, ToolBox* ); |
| DECL_LINK( OnMenuItemSelected, Menu* ); |
| DECL_LINK( DockingChanged, TitledDockingWindow* ); |
| ::std::auto_ptr< PopupMenu > impl_createPopupMenu() const; |
| |
| /// sets the given layout for the panel selector |
| void impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce = false ); |
| |
| /// returns the current layout of the panel selector |
| PanelSelectorLayout |
| impl_getLayout() const { return m_eCurrentLayout; } |
| |
| void impl_updateDockingWindowTitle(); |
| void impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex ); |
| size_t impl_getLogicalPanelIndex( const size_t i_nVisibleIndex ); |
| |
| private: |
| enum MenuId |
| { |
| MID_UNLOCK_TASK_PANEL = 1, |
| MID_LOCK_TASK_PANEL = 2, |
| MID_LAYOUT_TABS = 3, |
| MID_LAYOUT_DRAWERS = 4, |
| MID_FIRST_PANEL = 5 |
| }; |
| |
| private: |
| typedef ::std::vector< PanelDescriptor > PanelDescriptors; |
| |
| ModuleTaskPane& m_rTaskPane; |
| TitledDockingWindow& m_rDockingWindow; |
| sal_uInt16 m_nViewMenuID; |
| PanelSelectorLayout m_eCurrentLayout; |
| PanelDescriptors m_aPanelRepository; |
| bool m_bTogglingPanelVisibility; |
| ::rtl::OUString m_sDefaultTitle; |
| }; |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneController_Impl::TaskPaneController_Impl( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow ) |
| :m_rTaskPane( i_rTaskPane ) |
| ,m_rDockingWindow( i_rDockingWindow ) |
| ,m_nViewMenuID( 0 ) |
| ,m_eCurrentLayout( LAYOUT_DRAWERS ) |
| ,m_aPanelRepository() |
| ,m_bTogglingPanelVisibility( false ) |
| ,m_sDefaultTitle() |
| { |
| m_rDockingWindow.ResetToolBox(); |
| m_nViewMenuID = m_rDockingWindow.AddDropDownToolBoxItem( |
| String( SfxResId( STR_SFX_TASK_PANE_VIEW ) ), |
| HID_TASKPANE_VIEW_MENU, |
| LINK( this, TaskPaneController_Impl, OnToolboxClicked ) |
| ); |
| m_rDockingWindow.SetEndDockingHdl( LINK( this, TaskPaneController_Impl, DockingChanged ) ); |
| impl_setLayout(LAYOUT_TABS_RIGHT, true); |
| |
| m_rTaskPane.GetPanelDeck().AddListener( *this ); |
| |
| // initialize the panel repository |
| for ( size_t i = 0; i < m_rTaskPane.GetPanelDeck().GetPanelCount(); ++i ) |
| { |
| ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( i ) ); |
| m_aPanelRepository.push_back( PanelDescriptor( pPanel ) ); |
| } |
| |
| SetDefaultTitle( String( SfxResId( STR_SFX_TASKS ) ) ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneController_Impl::~TaskPaneController_Impl() |
| { |
| m_rTaskPane.GetPanelDeck().RemoveListener( *this ); |
| |
| // remove the panels which are not under the control of the panel deck currently |
| for ( PanelDescriptors::iterator panelPos = m_aPanelRepository.begin(); |
| panelPos != m_aPanelRepository.end(); |
| ++panelPos |
| ) |
| { |
| if ( panelPos->bHidden ) |
| panelPos->pPanel->Dispose(); |
| } |
| m_aPanelRepository.clear(); |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::SetDefaultTitle( const String& i_rTitle ) |
| { |
| m_sDefaultTitle = i_rTitle; |
| impl_updateDockingWindowTitle(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneController_Impl::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) |
| { |
| ::boost::optional< size_t > aPanelPos( m_rTaskPane.GetPanelPos( i_rPanelURL ) ); |
| ENSURE_OR_RETURN_VOID( !!aPanelPos, "TaskPaneController_Impl::ActivateToolPanel: no such panel!" ); |
| |
| if ( aPanelPos == m_rTaskPane.GetPanelDeck().GetActivePanel() ) |
| { |
| ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( *aPanelPos ) ); |
| pPanel->GrabFocus(); |
| } |
| else |
| { |
| m_rTaskPane.GetPanelDeck().ActivatePanel( aPanelPos ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| IMPL_LINK( TaskPaneController_Impl, DockingChanged, TitledDockingWindow*, i_pDockingWindow ) |
| { |
| ENSURE_OR_RETURN( i_pDockingWindow && &m_rDockingWindow, "TaskPaneController_Impl::DockingChanged: where does this come from?", 0L ); |
| |
| if ( impl_getLayout() == LAYOUT_DRAWERS ) |
| return 0L; |
| |
| impl_setLayout( lcl_getTabLayoutFromAlignment( i_pDockingWindow->GetAlignment() ) ); |
| return 1L; |
| } |
| |
| // ----------------------------------------------------------------------------------------------------------------- |
| IMPL_LINK( TaskPaneController_Impl, OnToolboxClicked, ToolBox*, i_pToolBox ) |
| { |
| if ( i_pToolBox->GetCurItemId() == m_nViewMenuID ) |
| { |
| i_pToolBox->EndSelection(); |
| |
| ::std::auto_ptr< PopupMenu > pMenu = impl_createPopupMenu(); |
| pMenu->SetSelectHdl( LINK( this, TaskPaneController_Impl, OnMenuItemSelected ) ); |
| |
| // pass toolbox button rect so the menu can stay open on button up |
| Rectangle aMenuRect( i_pToolBox->GetItemRect( m_nViewMenuID ) ); |
| aMenuRect.SetPos( i_pToolBox->GetPosPixel() ); |
| pMenu->Execute( &m_rDockingWindow, aMenuRect, POPUPMENU_EXECUTE_DOWN ); |
| } |
| |
| return 0; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| IMPL_LINK( TaskPaneController_Impl, OnMenuItemSelected, Menu*, i_pMenu ) |
| { |
| ENSURE_OR_RETURN( i_pMenu, "TaskPaneController_Impl::OnMenuItemSelected: illegal menu!", 0L ); |
| |
| i_pMenu->Deactivate(); |
| switch ( i_pMenu->GetCurItemId() ) |
| { |
| case MID_UNLOCK_TASK_PANEL: |
| m_rDockingWindow.SetFloatingMode( sal_True ); |
| break; |
| |
| case MID_LOCK_TASK_PANEL: |
| m_rDockingWindow.SetFloatingMode( sal_False ); |
| break; |
| |
| case MID_LAYOUT_DRAWERS: |
| impl_setLayout( LAYOUT_DRAWERS ); |
| break; |
| |
| case MID_LAYOUT_TABS: |
| impl_setLayout( lcl_getTabLayoutFromAlignment( m_rDockingWindow.GetAlignment() ) ); |
| break; |
| |
| default: |
| { |
| size_t nPanelIndex = size_t( i_pMenu->GetCurItemId() - MID_FIRST_PANEL ); |
| impl_togglePanelVisibility( nPanelIndex ); |
| } |
| break; |
| } |
| |
| return 1L; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| size_t TaskPaneController_Impl::impl_getLogicalPanelIndex( const size_t i_nVisibleIndex ) |
| { |
| size_t nLogicalIndex = 0; |
| size_t nVisibleIndex( i_nVisibleIndex ); |
| for ( size_t i=0; i < m_aPanelRepository.size(); ++i ) |
| { |
| if ( !m_aPanelRepository[i].bHidden ) |
| { |
| if ( !nVisibleIndex ) |
| break; |
| --nVisibleIndex; |
| } |
| ++nLogicalIndex; |
| } |
| return nLogicalIndex; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) |
| { |
| if ( m_bTogglingPanelVisibility ) |
| return; |
| |
| const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) ); |
| m_aPanelRepository.insert( m_aPanelRepository.begin() + nLogicalIndex, PanelDescriptor( i_pPanel ) ); |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::PanelRemoved( const size_t i_nPosition ) |
| { |
| if ( m_bTogglingPanelVisibility ) |
| return; |
| |
| const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) ); |
| m_aPanelRepository.erase( m_aPanelRepository.begin() + nLogicalIndex ); |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) |
| { |
| if ( impl_getLayout() == LAYOUT_DRAWERS ) |
| // no adjustment of the title when we use the classical "drawers" layout |
| return; |
| |
| impl_updateDockingWindowTitle( ); |
| (void)i_rOldActive; |
| (void)i_rNewActive; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) |
| { |
| // not interested in |
| (void)i_rNewLayouter; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::Dying() |
| { |
| OSL_ENSURE( false, "TaskPaneController_Impl::Dying: unexpected call!" ); |
| // We are expected to live longer than the ToolPanelDeck we work with. Since we remove ourself, in our dtor, |
| // as listener from the panel deck, this method here should never be called. |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex ) |
| { |
| ENSURE_OR_RETURN_VOID( i_nLogicalPanelIndex < m_aPanelRepository.size(), "illegal index" ); |
| |
| // get the actual panel index, within the deck |
| size_t nActualPanelIndex(0); |
| for ( size_t i=0; i < i_nLogicalPanelIndex; ++i ) |
| { |
| if ( !m_aPanelRepository[i].bHidden ) |
| ++nActualPanelIndex; |
| } |
| |
| ::boost::optional< size_t > aActivatePanel; |
| |
| m_bTogglingPanelVisibility = true; |
| if ( m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden ) |
| { |
| OSL_VERIFY( m_rTaskPane.GetPanelDeck().InsertPanel( m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel, nActualPanelIndex ) == nActualPanelIndex ); |
| // if there has not been an active panel before, activate the newly inserted one |
| ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() ); |
| if ( !aActivePanel ) |
| aActivatePanel = nActualPanelIndex; |
| } |
| else |
| { |
| OSL_VERIFY( m_rTaskPane.GetPanelDeck().RemovePanel( nActualPanelIndex ).get() == m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel.get() ); |
| } |
| m_bTogglingPanelVisibility = false; |
| m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden = !m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden; |
| |
| if ( !!aActivatePanel ) |
| m_rTaskPane.GetPanelDeck().ActivatePanel( *aActivatePanel ); |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce ) |
| { |
| if ( !i_bForce && ( m_eCurrentLayout == i_eLayout ) ) |
| return; |
| |
| switch ( i_eLayout ) |
| { |
| case LAYOUT_DRAWERS: |
| m_rTaskPane.SetDrawersLayout(); |
| break; |
| case LAYOUT_TABS_TOP: |
| m_rTaskPane.SetTabsLayout( ::svt::TABS_TOP, ::svt::TABITEM_IMAGE_ONLY ); |
| break; |
| case LAYOUT_TABS_BOTTOM: |
| m_rTaskPane.SetTabsLayout( ::svt::TABS_BOTTOM, ::svt::TABITEM_IMAGE_ONLY ); |
| break; |
| case LAYOUT_TABS_LEFT: |
| m_rTaskPane.SetTabsLayout( ::svt::TABS_LEFT, ::svt::TABITEM_IMAGE_ONLY ); |
| break; |
| case LAYOUT_TABS_RIGHT: |
| m_rTaskPane.SetTabsLayout( ::svt::TABS_RIGHT, ::svt::TABITEM_IMAGE_ONLY ); |
| break; |
| } |
| m_eCurrentLayout = i_eLayout; |
| |
| impl_updateDockingWindowTitle(); |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void TaskPaneController_Impl::impl_updateDockingWindowTitle() |
| { |
| ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() ); |
| if ( !aActivePanel || ( impl_getLayout() == LAYOUT_DRAWERS ) ) |
| m_rDockingWindow.SetTitle( m_sDefaultTitle ); |
| else |
| { |
| size_t nNewActive( *aActivePanel ); |
| for ( size_t i=0; i < m_aPanelRepository.size(); ++i ) |
| { |
| if ( m_aPanelRepository[i].bHidden ) |
| continue; |
| |
| if ( !nNewActive ) |
| { |
| m_rDockingWindow.SetTitle( m_aPanelRepository[i].pPanel->GetDisplayName() ); |
| break; |
| } |
| --nNewActive; |
| } |
| } |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| ::std::auto_ptr< PopupMenu > TaskPaneController_Impl::impl_createPopupMenu() const |
| { |
| ::std::auto_ptr<PopupMenu> pMenu( new PopupMenu ); |
| FloatingWindow* pMenuWindow = static_cast< FloatingWindow* >( pMenu->GetWindow() ); |
| if ( pMenuWindow != NULL ) |
| { |
| pMenuWindow->SetPopupModeFlags ( pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE ); |
| } |
| |
| // Add one entry for every tool panel element to individually make |
| // them visible or hide them. |
| sal_uInt16 nIndex = MID_FIRST_PANEL; |
| for ( size_t i=0; i<m_aPanelRepository.size(); ++i, ++nIndex ) |
| { |
| const PanelDescriptor& rPanelDesc( m_aPanelRepository[i] ); |
| pMenu->InsertItem( nIndex, rPanelDesc.pPanel->GetDisplayName(), MIB_CHECKABLE ); |
| pMenu->CheckItem( nIndex, !rPanelDesc.bHidden ); |
| } |
| pMenu->InsertSeparator(); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| pMenu->InsertItem( MID_LAYOUT_TABS, String::CreateFromAscii( "Tab-Layout (exp.)" ), MIB_CHECKABLE ); |
| pMenu->CheckItem( MID_LAYOUT_TABS, impl_getLayout() != LAYOUT_DRAWERS ); |
| pMenu->InsertItem( MID_LAYOUT_DRAWERS, String::CreateFromAscii( "Drawer-Layout" ), MIB_CHECKABLE ); |
| pMenu->CheckItem( MID_LAYOUT_DRAWERS, impl_getLayout() == LAYOUT_DRAWERS ); |
| |
| pMenu->InsertSeparator(); |
| #endif |
| |
| // Add entry for docking or un-docking the tool panel. |
| if ( m_rDockingWindow.IsFloatingMode() ) |
| pMenu->InsertItem( |
| MID_LOCK_TASK_PANEL, |
| String( SfxResId( STR_SFX_DOCK ) ) |
| ); |
| else |
| pMenu->InsertItem( |
| MID_UNLOCK_TASK_PANEL, |
| String( SfxResId( STR_SFX_UNDOCK ) ) |
| ); |
| |
| pMenu->RemoveDisabledEntries( sal_False, sal_False ); |
| |
| return pMenu; |
| } |
| |
| //================================================================================================================== |
| //= TaskPaneController |
| //================================================================================================================== |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneController::TaskPaneController( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow ) |
| :m_pImpl( new TaskPaneController_Impl( i_rTaskPane, i_rDockingWindow ) ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| TaskPaneController::~TaskPaneController() |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneController::SetDefaultTitle( const String& i_rTitle ) |
| { |
| m_pImpl->SetDefaultTitle( i_rTitle ); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void TaskPaneController::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) |
| { |
| m_pImpl->ActivateToolPanel( i_rPanelURL ); |
| } |
| |
| //...................................................................................................................... |
| } // namespace sfx2 |
| //...................................................................................................................... |