summaryrefslogtreecommitdiff
path: root/sfx2/source/dialog/taskpane.cxx
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-04-07 22:36:26 +0200
committerFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-04-07 22:36:26 +0200
commit1cf2a482871ba237ec9470b88da074b97a2dbf41 (patch)
treec9b0520fa86bf4512a198524483f970525da9843 /sfx2/source/dialog/taskpane.cxx
parentf0cd4535a2d40ce66c346596bedbc7eac97a0b63 (diff)
slidecopy: improved the generic TaskPane, now filled from the configuration, including a small sample extension
still some way to go .... open items include: - add to all affected applications - respect the ImageURL property of the config data - clarify how this interacts with SD's Drawing Framework, and Impress' TaskPane - re-activate the previously-active tool panel when opening the pane again - obtain the XAccessible from the tool panel - title when docked - proper TAB handling when multiple panel/drawers exist
Diffstat (limited to 'sfx2/source/dialog/taskpane.cxx')
-rw-r--r--sfx2/source/dialog/taskpane.cxx481
1 files changed, 441 insertions, 40 deletions
diff --git a/sfx2/source/dialog/taskpane.cxx b/sfx2/source/dialog/taskpane.cxx
index 80273f5e517a..383306da42e8 100644
--- a/sfx2/source/dialog/taskpane.cxx
+++ b/sfx2/source/dialog/taskpane.cxx
@@ -28,11 +28,28 @@
#include "sfx2/taskpane.hxx"
#include "sfx2/sfxsids.hrc"
+#include "sfx2/bindings.hxx"
+#include "sfx2/dispatch.hxx"
#include "sfxresid.hxx"
#include "helpid.hrc"
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/view/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>
+/** === 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 <unotools/confignode.hxx>
#if OSL_DEBUG_LEVEL > 0
#include <com/sun/star/accessibility/XAccessible.hpp>
@@ -46,7 +63,31 @@ namespace sfx2
{
//......................................................................................................................
-#define USE_DUMMY_PANEL
+ /** === 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::view::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;
+ /** === end UNO using === **/
+ namespace PosSize = ::com::sun::star::awt::PosSize;
+
+//#define USE_DUMMY_PANEL
#if OSL_DEBUG_LEVEL > 0
//==================================================================================================================
@@ -168,69 +209,76 @@ namespace sfx2
#endif
//==================================================================================================================
- //= TaskPane_Impl
+ //= helpers
//==================================================================================================================
- class TaskPane_Impl : public ::boost::noncopyable
+ namespace
{
- public:
- TaskPane_Impl( TaskPane& i_rAntiImpl )
- :m_rAntiImpl( i_rAntiImpl )
- ,m_aToolPanels( i_rAntiImpl, 0 )
+ ::rtl::OUString lcl_identifyModule( const Reference< XFrame >& i_rDocumentFrame )
{
- m_aToolPanels.Show();
-#if ( OSL_DEBUG_LEVEL > 0 ) && defined ( USE_DUMMY_PANEL )
- m_aToolPanels.InsertPanel( ::svt::PToolPanel( new DummyPanel( m_aToolPanels.GetPanelWindowAnchor() ) ), m_aToolPanels.GetPanelCount() );
-#endif
- OnResize();
+ ::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;
}
- ~TaskPane_Impl()
+ ::rtl::OUString lcl_identifyModule( const SfxBindings* i_pBindings )
{
+ const SfxViewFrame* pViewFrame = i_pBindings->GetDispatcher()->GetFrame();
+ const SfxFrame* pFrame = pViewFrame->GetFrame();
+ const Reference< XFrame > xFrame( pFrame->GetFrameInterface() );
+ return lcl_identifyModule( xFrame );
}
-
- void OnResize();
- void OnGetFocus();
-
- private:
- TaskPane& m_rAntiImpl;
- ::svt::ToolPanelDeck m_aToolPanels;
- };
-
- //------------------------------------------------------------------------------------------------------------------
- void TaskPane_Impl::OnResize()
- {
- m_aToolPanels.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() );
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void TaskPane_Impl::OnGetFocus()
- {
- m_aToolPanels.GrabFocus();
}
//==================================================================================================================
- //= TaskPane
+ //= TaskPaneDockingWindow
//==================================================================================================================
//------------------------------------------------------------------------------------------------------------------
- TaskPane::TaskPane( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits )
+ TaskPaneDockingWindow::TaskPaneDockingWindow( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits )
:SfxDockingWindow( i_pBindings, &i_rWrapper, i_pParent, i_nBits )
- ,m_pImpl( new TaskPane_Impl( *this ) )
+ ,m_aTaskPane( *this, lcl_identifyModule( i_pBindings ) )
{
+ m_aTaskPane.Show();
SetText( String( SfxResId( SID_TASKPANE ) ) );
}
//------------------------------------------------------------------------------------------------------------------
- void TaskPane::GetFocus()
+ void TaskPaneDockingWindow::GetFocus()
{
SfxDockingWindow::GetFocus();
- m_pImpl->OnGetFocus();
+ m_aTaskPane.GrabFocus();
}
//------------------------------------------------------------------------------------------------------------------
- void TaskPane::Resize()
+ void TaskPaneDockingWindow::Resize()
{
SfxDockingWindow::Resize();
- m_pImpl->OnResize();
+ m_aTaskPane.SetPosSizePixel( Point(), GetOutputSizePixel() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ long TaskPaneDockingWindow::Notify( NotifyEvent& i_rNotifyEvent )
+ {
+ // in case this is a MouseButtonDown event, consume it - VCL's DockingWindow would otherwise
+ // start undocking, no matter which window this event was intended for
+ if ( i_rNotifyEvent.GetType() == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseEvent& rMouseEvent = *i_rNotifyEvent.GetMouseEvent();
+ if ( rMouseEvent.IsLeft() && ( rMouseEvent.GetClicks() == 1 ) && !rMouseEvent.IsMod1() )
+ {
+ if ( m_aTaskPane.IsWindowOrChild( i_rNotifyEvent.GetWindow() ) )
+ return TRUE;
+ }
+ }
+ return SfxDockingWindow::Notify( i_rNotifyEvent );
}
//==================================================================================================================
@@ -243,7 +291,7 @@ namespace sfx2
TaskPaneWrapper::TaskPaneWrapper( Window* i_pParent, USHORT i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pInfo )
:SfxChildWindow( i_pParent, i_nId )
{
- pWindow = new TaskPane( i_pBindings, *this, i_pParent,
+ pWindow = new TaskPaneDockingWindow( i_pBindings, *this, i_pParent,
WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE);
eChildAlignment = SFX_ALIGN_RIGHT;
@@ -255,6 +303,359 @@ namespace sfx2
SetHideNotDelete( TRUE );
}
+ //==================================================================================================================
+ //= 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 );
+
+ 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();
+ virtual Reference< XAccessible >
+ CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible );
+
+ protected:
+ ~CustomToolPanel();
+
+ private:
+ bool impl_ensureToolPanelWindow( Window& i_rPanelParentWindow );
+
+ private:
+ const ::rtl::OUString m_sUIName;
+ const ::rtl::OUString m_sResourceURL;
+ CustomPanelUIElement m_aCustomPanel;
+ bool m_bAttemptedCreation;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ CustomToolPanel::CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState )
+ :m_sUIName( ::comphelper::getString( i_rPanelWindowState.getNodeValue( "UIName" ) ) )
+ ,m_sResourceURL( i_rPanelWindowState.getLocalName() )
+ ,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( "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();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString CustomToolPanel::GetDisplayName() const
+ {
+ return m_sUIName;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Image CustomToolPanel::GetImage() const
+ {
+ // TODO: read from configuration
+ return Image();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ 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 );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void CustomToolPanel::Deactivate()
+ {
+ ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to deactivate!" );
+
+ m_aCustomPanel.getPanelWindow()->setVisible( sal_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 )
+ {
+ // TODO
+ (void)i_rParentAccessible;
+ return NULL;
+ }
+
+ //==================================================================================================================
+ //= ModuleTaskPane_Impl
+ //==================================================================================================================
+ class ModuleTaskPane_Impl : public ::boost::noncopyable
+ {
+ public:
+ ModuleTaskPane_Impl( ModuleTaskPane& i_rAntiImpl, const ::rtl::OUString& i_rModuleIdentifier )
+ :m_rAntiImpl( i_rAntiImpl )
+ ,m_sModuleIdentifier( i_rModuleIdentifier )
+ ,m_aPanels( i_rAntiImpl, 0 )
+ {
+ m_aPanels.Show();
+ #if ( OSL_DEBUG_LEVEL > 0 ) && defined ( USE_DUMMY_PANEL )
+ m_aPanels.InsertPanel( ::svt::PToolPanel( new DummyPanel( m_aPanels.GetPanelWindowAnchor() ) ), m_aPanels.GetPanelCount() );
+ #endif
+ OnResize();
+ impl_initFromConfiguration();
+ }
+
+ ~ModuleTaskPane_Impl()
+ {
+ }
+
+ void OnResize();
+ void OnGetFocus();
+
+ static bool ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier );
+
+ private:
+ void impl_initFromConfiguration();
+
+ static ::utl::OConfigurationTreeRoot
+ impl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier );
+ static bool
+ impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL );
+
+ private:
+ ModuleTaskPane& m_rAntiImpl;
+ ::rtl::OUString m_sModuleIdentifier;
+ ::svt::ToolPanelDeck m_aPanels;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ModuleTaskPane_Impl::OnResize()
+ {
+ m_aPanels.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ModuleTaskPane_Impl::OnGetFocus()
+ {
+ m_aPanels.GrabFocus();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::utl::OConfigurationTreeRoot ModuleTaskPane_Impl::impl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier )
+ {
+ 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" );
+
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return ::utl::OConfigurationTreeRoot( aContext, aPathComposer.makeStringAndClear(), false );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ 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 ::utl::OConfigurationTreeRoot aWindowStateConfig( impl_getModuleUIElementStatesConfig( m_sModuleIdentifier ) );
+ if ( !aWindowStateConfig.isValid() )
+ return;
+
+ 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;
+
+ ::utl::OConfigurationNode aResourceNode( aWindowStateConfig.openNode( *resource ) );
+ ::svt::PToolPanel pCustomPanel( new CustomToolPanel( aResourceNode ) );
+ m_aPanels.InsertPanel( pCustomPanel, m_aPanels.GetPanelCount() );
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ bool ModuleTaskPane_Impl::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier )
+ {
+ const ::utl::OConfigurationTreeRoot aWindowStateConfig( impl_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;
+ }
+
+ //==================================================================================================================
+ //= ModuleTaskPane
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const ::rtl::OUString& i_rModuleIdentifier )
+ :Window( &i_rParentWindow, 0 )
+ ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rModuleIdentifier ) )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ 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();
+ }
+
//......................................................................................................................
} // namespace sfx2
//......................................................................................................................