office-gobmx/sd/source/ui/toolpanel/ToolPanelViewShell.cxx

900 lines
36 KiB
C++
Executable file

/*************************************************************************
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include "taskpane/ToolPanelViewShell.hxx"
#include "TaskPaneShellManager.hxx"
#include "TaskPaneFocusManager.hxx"
#include "taskpane/TaskPaneControlFactory.hxx"
#include "controls/MasterPagesPanel.hxx"
#include "LayoutMenu.hxx"
#include "DrawDocShell.hxx"
#include "controls/TableDesignPanel.hxx"
#include "controls/CustomAnimationPanel.hxx"
#include "controls/SlideTransitionPanel.hxx"
#include "controls/MasterPagesSelector.hxx"
#include "ToolPanel.hxx"
#include "ToolPanelUIElement.hxx"
#include "PaneDockingWindow.hxx"
#include "FrameView.hxx"
#include "Window.hxx"
#include "sdmod.hxx"
#include "app.hrc"
#include "glob.hrc"
#include "res_bmp.hrc"
#include "helpids.h"
#include "strings.hrc"
#include "sdresid.hxx"
#include "framework/FrameworkHelper.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/drawing/framework/XResourceId.hpp>
#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
#include <com/sun/star/drawing/framework/AnchorBindingMode.hpp>
#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
#include <com/sun/star/drawing/XDrawSubController.hpp>
/** === end UNO includes === **/
#include <svtools/toolpanel/toolpanel.hxx>
#include <svtools/toolpanel/toolpaneldeck.hxx>
#include <svx/dlgctrl.hxx>
#include <sfx2/taskpane.hxx>
#include <sfx2/imagemgr.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/msg.hxx>
#include <sfx2/objface.hxx>
#include <svx/colrctrl.hxx>
#include <svx/xtable.hxx>
#include <vcl/dockwin.hxx>
#include "sdtreelb.hxx"
#include "DrawViewShell.hxx"
#include "drawdoc.hxx"
#include "ViewShellBase.hxx"
#include <svx/ruler.hxx>
#include <vcl/svapp.hxx>
#include <vcl/toolbox.hxx>
#include <tools/diagnose_ex.h>
#include <unotools/confignode.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/componentcontext.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/basemutex.hxx>
#include <vector>
using namespace ::sd::toolpanel;
#define ToolPanelViewShell
#include "sdslots.hxx"
/** === 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::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;
using ::com::sun::star::drawing::framework::XConfigurationController;
using ::com::sun::star::drawing::framework::XConfiguration;
using ::com::sun::star::drawing::framework::AnchorBindingMode_DIRECT;
using ::com::sun::star::ui::XUIElement;
using ::com::sun::star::ui::XToolPanel;
using ::com::sun::star::drawing::framework::ResourceActivationMode_REPLACE;
/** === end UNO using === **/
using ::sd::framework::FrameworkHelper;
namespace sd { namespace toolpanel {
// =====================================================================================================================
// = misc helper
// =====================================================================================================================
// ---------------------------------------------------------------------------------------------------------------------
PanelId GetStandardPanelId( const ::rtl::OUString& i_rTaskPanelResourceURL, const bool i_bIgnoreUnknown )
{
PanelId ePanelId( PID_UNKNOWN );
if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msMasterPagesTaskPanelURL ) )
{
ePanelId = PID_MASTER_PAGES;
}
else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msLayoutTaskPanelURL ) )
{
ePanelId = PID_LAYOUT;
}
else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msTableDesignPanelURL ) )
{
ePanelId = PID_TABLE_DESIGN;
}
else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msCustomAnimationTaskPanelURL ) )
{
ePanelId = PID_CUSTOM_ANIMATION;
}
else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msSlideTransitionTaskPanelURL ) )
{
ePanelId = PID_SLIDE_TRANSITION;
}
else
{
OSL_ENSURE( i_bIgnoreUnknown, "GetStandardPanelId: cannot translate the given resource URL!" );
(void)i_bIgnoreUnknown;
}
return ePanelId;
}
// ---------------------------------------------------------------------------------------------------------------------
PanelId GetStandardPanelId( const ::rtl::OUString& i_rTaskPanelResourceURL )
{
return GetStandardPanelId( i_rTaskPanelResourceURL, false );
}
// =====================================================================================================================
// = 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_Impl :public ::boost::noncopyable
,public ::svt::IToolPanelDeckListener
,public ::sfx2::IToolPanelCompare
{
public:
static const size_t mnInvalidId = static_cast< size_t >( -1 );
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.
*/
void Setup();
/** clean up the instance
*/
void Cleanup();
/** activates the panel which has the given resource URL
*/
void ActivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL );
/** de-activates the panel given by its resource URL, bypassing the configuration controller
If the panel is not active currently, nothing happens.
*/
void DeactivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL );
/** provides access to the the VCL window of the panel deck
*/
::sfx2::ModuleTaskPane& GetTaskPane() { return *m_pTaskPane; }
const ::sfx2::ModuleTaskPane& GetTaskPane() const { return *m_pTaskPane; }
::svt::ToolPanelDeck& GetToolPanelDeck() { return GetTaskPane().GetPanelDeck(); }
const ::svt::ToolPanelDeck& GetToolPanelDeck() const { return GetTaskPane().GetPanelDeck(); }
Reference< XAccessible >
CreateAccessible( ::sd::Window& i_rWindow );
void ConnectToDockingWindow();
private:
// 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();
// IToolPanelCompare overridables
virtual short compareToolPanelsURLs( const ::rtl::OUString& i_rLHS, const ::rtl::OUString& i_rRHS ) const;
private:
struct InitialPanel
{
::rtl::OUString sPanelResourceURL;
bool bActivateDirectly;
InitialPanel()
:sPanelResourceURL()
,bActivateDirectly( true )
{
}
};
InitialPanel impl_determineInitialPanel();
::rtl::OUString impl_getPanelURL( const ::boost::optional< size_t >& i_rPanel );
private:
ToolPanelViewShell& m_rPanelViewShell;
::boost::scoped_ptr< ::sfx2::ModuleTaskPane > m_pTaskPane;
::std::auto_ptr< ::sfx2::TaskPaneController > m_pTaskPaneController;
::rtl::Reference< ConfigurationListener > m_pConfigListener;
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();
// 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->ActivatePanelByResource( i_rEvent.ResourceId->getResourceURL() );
}
// ---------------------------------------------------------------------------------------------------------------------
void SAL_CALL ConfigurationListener::disposing( const EventObject& i_rEvent ) throw (RuntimeException)
{
(void)i_rEvent;
{
::osl::MutexGuard aGuard( m_aMutex );
impl_checkDisposed_throw();
}
dispose();
}
// ---------------------------------------------------------------------------------------------------------------------
void ConfigurationListener::dispose()
{
::osl::MutexGuard aGuard( m_aMutex );
m_pShellImpl = NULL;
}
// =====================================================================================================================
// = ToolPanelViewShell
// =====================================================================================================================
// ---------------------------------------------------------------------------------------------------------------------
SFX_IMPL_INTERFACE(ToolPanelViewShell, SfxShell, SdResId(STR_TASKPANEVIEWSHELL))
{
}
// ---------------------------------------------------------------------------------------------------------------------
TYPEINIT1(ToolPanelViewShell, ViewShell);
// ---------------------------------------------------------------------------------------------------------------------
ToolPanelViewShell_Impl::InitialPanel ToolPanelViewShell_Impl::impl_determineInitialPanel()
{
InitialPanel aPanelToActivate;
if ( GetAntiImpl().GetViewShellBase().GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_DRAW )
// for Draw, rely on SFX's default handling, which is to activate the previously active panel
return aPanelToActivate;
// Default to Layout panel, but check whether the requested configuration already contains a tool panel, in this case,
// use that one.
aPanelToActivate.sPanelResourceURL = FrameworkHelper::msLayoutTaskPanelURL;
aPanelToActivate.bActivateDirectly = false;
try
{
::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( m_rPanelViewShell.GetViewShellBase() ) );
const Reference< XResourceId > xToolPanelId( pFrameworkHelper->CreateResourceId( FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL ) );
Reference< XConfigurationController > xCC( pFrameworkHelper->GetConfigurationController(), UNO_QUERY_THROW );
Reference< XConfiguration > xConfiguration( xCC->getRequestedConfiguration(), UNO_QUERY_THROW );
Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources(
FrameworkHelper::CreateResourceId( FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL ),
FrameworkHelper::msTaskPanelURLPrefix, AnchorBindingMode_DIRECT ) );
if ( aViewIds.getLength() > 0 )
{
const ::rtl::OUString sResourceURL( aViewIds[0]->getResourceURL() );
PanelId nRequestedPanel = GetStandardPanelId( sResourceURL );
if ( nRequestedPanel != PID_UNKNOWN )
{
aPanelToActivate.sPanelResourceURL = sResourceURL;
aPanelToActivate.bActivateDirectly = true;
}
}
}
catch( const Exception& )
{
DBG_UNHANDLED_EXCEPTION();
}
return aPanelToActivate;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::Setup()
{
if ( m_bInitialized )
return;
m_bInitialized = true;
// initially activate a panel
const InitialPanel aInitialPanel = impl_determineInitialPanel();
if ( aInitialPanel.sPanelResourceURL.getLength() )
{
if ( aInitialPanel.bActivateDirectly )
{
ActivatePanelByResource( aInitialPanel.sPanelResourceURL );
}
else
{
::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( GetAntiImpl().GetViewShellBase() ) );
pFrameworkHelper->RequestTaskPanel( aInitialPanel.sPanelResourceURL );
}
}
// listen at the configuration
m_pConfigListener.set( new ConfigurationListener( *this ) );
m_pTaskPane->Show();
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::Cleanup()
{
if ( m_bInitialized )
{
if ( m_pConfigListener.is() )
m_pConfigListener->dispose();
}
GetToolPanelDeck().RemoveListener( *this );
m_pTaskPaneController.reset();
m_pTaskPane.reset();
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::ActivatePanelByResource( const ::rtl::OUString& i_rResourceURL )
{
// determine position of the requested panel
::boost::optional< size_t > aPanelPos = GetTaskPane().GetPanelPos( i_rResourceURL );
OSL_ENSURE( !!aPanelPos, "ToolPanelViewShell_Impl::ActivatePanelByResource: illegal panel resource, or illegal panel deck setup!" );
if ( !!aPanelPos )
GetToolPanelDeck().ActivatePanel( *aPanelPos );
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::DeactivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL )
{
// determine position of the requested panel
::boost::optional< size_t > aPanelPos = GetTaskPane().GetPanelPos( i_rPanelResourceURL );
OSL_ENSURE( !!aPanelPos, "ToolPanelViewShell_Impl::DeactivatePanelByResource: illegal panel resource, or illegal panel deck setup!" );
if ( !!aPanelPos )
{
if ( GetToolPanelDeck().GetActivePanel() == *aPanelPos )
GetToolPanelDeck().ActivatePanel( ::boost::optional< size_t >() );
}
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::Initialize()
{
mpImpl->Setup();
}
// ---------------------------------------------------------------------------------------------------------------------
ToolPanelViewShell::ToolPanelViewShell( SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow,
FrameView* pFrameViewArgument )
:ViewShell(pFrame, pParentWindow, rViewShellBase)
,mpImpl( new ToolPanelViewShell_Impl( *this, *mpContentWindow.get() ) )
,mpSubShellManager()
,mnMenuId(0)
{
meShellType = ST_TASK_PANE;
mpContentWindow->SetCenterAllowed( false );
pParentWindow->SetStyle( pParentWindow->GetStyle() | WB_DIALOGCONTROL );
GetParentWindow()->SetBackground( Wallpaper() );
mpContentWindow->SetBackground( Wallpaper() );
GetParentWindow()->SetHelpId(HID_SD_TASK_PANE);
mpImpl->ConnectToDockingWindow();
SetPool( &GetDoc()->GetPool() );
if ( pFrameViewArgument )
mpFrameView = pFrameViewArgument;
else
mpFrameView = new FrameView( GetDoc() );
GetFrameView()->Connect();
// Hide or delete unused controls that we have inherited from the
// ViewShell base class.
mpHorizontalScrollBar.reset();
mpVerticalScrollBar.reset();
mpScrollBarBox.reset();
mpHorizontalRuler.reset();
mpVerticalRuler.reset();
SetName( String( RTL_CONSTASCII_USTRINGPARAM( "ToolPanelViewShell" ) ) );
// For accessibility we have to shortly hide the content window. This
// triggers the construction of a new accessibility object for the new
// view shell. (One is created earlier while the construtor of the base
// class is executed. At that time the correct accessibility object can
// not be constructed.)
if ( mpContentWindow.get() )
{
mpContentWindow->Hide();
mpContentWindow->Show();
}
// Register the shell manager as factory at the ViewShellManager.
mpSubShellManager.reset( new TaskPaneShellManager(
GetViewShellBase().GetViewShellManager(),
*this
) );
GetViewShellBase().GetViewShellManager()->AddSubShellFactory( this, mpSubShellManager );
}
// ---------------------------------------------------------------------------------------------------------------------
ToolPanelViewShell::~ToolPanelViewShell()
{
mpImpl->Cleanup();
// reset our impl before destroying the panel deck, to ensure the hidden panels are properly
// disposed/destroyed, too
mpImpl.reset();
GetViewShellBase().GetViewShellManager()->RemoveSubShellFactory(this, mpSubShellManager);
}
// ---------------------------------------------------------------------------------------------------------------------
// static
void ToolPanelViewShell::RegisterControls()
{
SfxModule* pModule = SD_MOD();
controls::MasterPagesSelector::RegisterInterface( pModule );
LayoutMenu::RegisterInterface( pModule );
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::ArrangeGUIElements()
{
ViewShell::ArrangeGUIElements();
Initialize();
mpImpl->GetTaskPane().SetPosSizePixel( Point(), maViewSize );
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::GetFocus()
{
Invalidate();
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::LoseFocus()
{
Invalidate();
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::KeyInput( const KeyEvent& i_rKeyEvent )
{
const KeyCode nCode = i_rKeyEvent.GetKeyCode();
if ( nCode == KEY_RETURN )
{
if ( !mpImpl->GetTaskPane().HasChildPathFocus() )
mpImpl->GetTaskPane().GrabFocus();
}
else
ViewShell::KeyInput( i_rKeyEvent, NULL );
}
// ---------------------------------------------------------------------------------------------------------------------
SdPage* ToolPanelViewShell::GetActualPage()
{
return NULL;
}
// ---------------------------------------------------------------------------------------------------------------------
SdPage* ToolPanelViewShell::getCurrentPage() const
{
return NULL;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::Execute( SfxRequest& )
{
OSL_ENSURE( false, "ToolPanelViewShell::Execute: not to be called! (right?)" );
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::GetState( SfxItemSet& )
{
OSL_ENSURE( false, "ToolPanelViewShell::GetState: not to be called! (right?)" );
}
// ---------------------------------------------------------------------------------------------------------------------
TaskPaneShellManager& ToolPanelViewShell::GetSubShellManager() const
{
return *mpSubShellManager.get();
}
// ---------------------------------------------------------------------------------------------------------------------
DockingWindow* ToolPanelViewShell::GetDockingWindow()
{
::Window* pParentWindow = GetParentWindow();
DockingWindow* pDockingWindow = NULL;
while (pParentWindow!=NULL && pDockingWindow==NULL)
{
pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow);
pParentWindow = pParentWindow->GetParent();
}
return pDockingWindow;
}
// ---------------------------------------------------------------------------------------------------------------------
Reference< XAccessible > ToolPanelViewShell::CreateAccessibleDocumentView( ::sd::Window* i_pWindow )
{
ENSURE_OR_RETURN( i_pWindow, "ToolPanelViewShell::CreateAccessibleDocumentView: illegal window!", NULL );
return mpImpl->CreateAccessible( *i_pWindow );
}
// ---------------------------------------------------------------------------------------------------------------------
Reference< XDrawSubController > ToolPanelViewShell::CreateSubController()
{
// This view shell is not designed to be the main view shell and thus
// does not support a UNO sub controller.
return Reference< XDrawSubController >();
}
// ---------------------------------------------------------------------------------------------------------------------
bool ToolPanelViewShell::RelocateToParentWindow( ::Window* pParentWindow )
{
::Window* pOldParentWindow = GetParentWindow();
FocusManager::Instance().RemoveLinks( pOldParentWindow, &mpImpl->GetTaskPane() );
FocusManager::Instance().RemoveLinks( &mpImpl->GetTaskPane(), pOldParentWindow );
PaneDockingWindow* pDockingWindow = dynamic_cast< PaneDockingWindow* >( GetDockingWindow() );
if ( pDockingWindow != NULL )
{
pDockingWindow->SetEndDockingHdl( Link() );
}
ViewShell::RelocateToParentWindow(pParentWindow);
mpImpl->ConnectToDockingWindow();
Resize();
return true;
}
//---------------------------------------------------------------------------------------------------------------------
bool ToolPanelViewShell::IsPanelAnchorWindow( const ::Window& i_rWindow ) const
{
return &mpImpl->GetToolPanelDeck().GetPanelWindowAnchor() == &i_rWindow;
}
//---------------------------------------------------------------------------------------------------------------------
namespace
{
typedef std::auto_ptr< ControlFactory > (*ControlFactoryFactory)( ToolPanelViewShell& i_rToolPanelShell );
struct PanelFactory
{
ControlFactoryFactory pFactory;
ULONG nHelpID;
PanelFactory( const ControlFactoryFactory i_pFactory, const ULONG i_nHelpID )
:pFactory( i_pFactory )
,nHelpID( i_nHelpID )
{
}
};
const PanelFactory lcl_describePanel( const PanelId i_ePanelId )
{
switch ( i_ePanelId )
{
case PID_MASTER_PAGES:
return PanelFactory( &controls::MasterPagesPanel::CreateControlFactory, HID_SD_SLIDE_DESIGNS );
case PID_LAYOUT:
return PanelFactory( &LayoutMenu::CreateControlFactory, HID_SD_SLIDE_LAYOUTS );
case PID_TABLE_DESIGN:
return PanelFactory( &controls::TableDesignPanel::CreateControlFactory, HID_SD_TABLE_DESIGN );
case PID_CUSTOM_ANIMATION:
return PanelFactory( &controls::CustomAnimationPanel::CreateControlFactory, HID_SD_CUSTOM_ANIMATIONS );
case PID_SLIDE_TRANSITION:
return PanelFactory( &controls::SlideTransitionPanel::CreateControlFactory, HID_SD_SLIDE_TRANSITIONS );
default:
break;
}
throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal panel ID" ) ), NULL );
}
}
//---------------------------------------------------------------------------------------------------------------------
Reference< XUIElement > ToolPanelViewShell::CreatePanelUIElement( const Reference< XFrame >& i_rDocFrame, const ::rtl::OUString& i_rPanelResourceURL )
{
const PanelId ePanelId( GetStandardPanelId( i_rPanelResourceURL ) );
ENSURE_OR_RETURN( ePanelId != PID_UNKNOWN, "ToolPanelViewShell::CreatePanelUIElement: illegal panel URL!", NULL );
// a TreeNode which will resemble the panel
const PanelFactory aPanelFactory( lcl_describePanel( ePanelId ) );
::std::auto_ptr< ControlFactory > pControlFactory( (*aPanelFactory.pFactory)( *this ) );
::std::auto_ptr< TreeNode > pNode( pControlFactory->CreateControl( mpImpl->GetToolPanelDeck().GetPanelWindowAnchor() ) );
ENSURE_OR_THROW( ( pNode.get() != NULL ) && ( pNode->GetWindow() != NULL ),
"illegal node returned by the control factory" );
pNode->GetWindow()->SetHelpId( aPanelFactory.nHelpID );
// create an XToolPanel
Reference< XToolPanel > xPanel( new ToolPanel( pNode ) );
// create an XUIElement providing this panel
const Reference< XUIElement > xUIElement( new ToolPanelUIElement( i_rDocFrame, i_rPanelResourceURL, xPanel ) );
return xUIElement;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::ActivatePanel( const ::rtl::OUString& i_rPanelResourceURL )
{
OSL_ENSURE( i_rPanelResourceURL.indexOf( FrameworkHelper::msTaskPanelURLPrefix ) < 0,
"ToolPanelViewShell::ActivatePanel: for drawing-framework-controller panels, please use FrameworkHelper::RequestTaskPanel!" );
mpImpl->ActivatePanelByResource( i_rPanelResourceURL );
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell::DeactivatePanel( const ::rtl::OUString& i_rPanelResourceURL )
{
mpImpl->DeactivatePanelByResource( i_rPanelResourceURL );
}
// =====================================================================================================================
// = ToolPanelViewShell_Impl - implementation
// =====================================================================================================================
// ---------------------------------------------------------------------------------------------------------------------
ToolPanelViewShell_Impl::ToolPanelViewShell_Impl( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent )
:m_rPanelViewShell( i_rPanelViewShell )
,m_pTaskPane( new ::sfx2::ModuleTaskPane( i_rPanelDeckParent, i_rPanelViewShell.GetViewShellBase().GetViewFrame()->GetFrame().GetFrameInterface(), *this ) )
,m_bInitialized( false )
{
const String sPaneTitle( SdResId( STR_RIGHT_PANE_TITLE ) );
GetToolPanelDeck().SetAccessibleName( sPaneTitle );
GetToolPanelDeck().SetAccessibleDescription( sPaneTitle );
GetToolPanelDeck().AddListener( *this );
}
// ---------------------------------------------------------------------------------------------------------------------
ToolPanelViewShell_Impl::~ToolPanelViewShell_Impl()
{
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition )
{
// not interested in
(void)i_pPanel;
(void)i_nPosition;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::PanelRemoved( const size_t i_nPosition )
{
// not interested in
(void)i_nPosition;
}
// ---------------------------------------------------------------------------------------------------------------------
::rtl::OUString ToolPanelViewShell_Impl::impl_getPanelURL( const ::boost::optional< size_t >& i_rPanel )
{
::rtl::OUString sPanelURL;
if ( !!i_rPanel )
{
sPanelURL = GetTaskPane().GetPanelResourceURL( *i_rPanel );
const PanelId ePanelId( GetStandardPanelId( sPanelURL, true ) );
if ( ePanelId == PID_UNKNOWN )
sPanelURL = ::rtl::OUString();
}
return sPanelURL;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
{
// update the configuration controller, since this change in the active panel might have been triggered by means other
// than the drawing framework, so it does not yet know about it.
const ::rtl::OUString sOldPanelURL( impl_getPanelURL( i_rOldActive ) );
const ::rtl::OUString sNewPanelURL( impl_getPanelURL( i_rNewActive ) );
const ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( GetAntiImpl().GetViewShellBase() ) );
if ( sNewPanelURL.getLength() )
{
// activate the resource belonging to the new panel. This will automatically de-activate the previously active
// panel resource (since ResourceActivationMode_REPLACE is used)
pFrameworkHelper->RequestTaskPanel( sNewPanelURL );
}
else if ( sOldPanelURL.getLength() )
{
// there is no new active panel, or it is not one of our standard panels, i.e. it is not covered by the
// resource framework. => Deactivate the old resource.
try
{
Reference< XConfigurationController > xConfigController( pFrameworkHelper->GetConfigurationController(), UNO_QUERY_THROW );
xConfigController->requestResourceDeactivation(
pFrameworkHelper->CreateResourceId(
sOldPanelURL,
FrameworkHelper::msTaskPaneURL,
FrameworkHelper::msRightPaneURL
)
);
}
catch( const Exception& )
{
DBG_UNHANDLED_EXCEPTION();
}
}
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter )
{
// not interested in
(void)i_rNewLayouter;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::Dying()
{
// not interested in
}
// ---------------------------------------------------------------------------------------------------------------------
short ToolPanelViewShell_Impl::compareToolPanelsURLs( const ::rtl::OUString& i_rLHS, const ::rtl::OUString& i_rRHS ) const
{
const PanelId eLHS( GetStandardPanelId( i_rLHS, true ) );
const PanelId eRHS( GetStandardPanelId( i_rRHS, true ) );
if ( eLHS < eRHS )
return -1;
if ( eLHS == eRHS )
return 0;
return 1;
}
// ---------------------------------------------------------------------------------------------------------------------
void ToolPanelViewShell_Impl::ConnectToDockingWindow()
{
m_pTaskPaneController.reset();
DockingWindow* pDockingWindow( GetAntiImpl().GetDockingWindow() );
if ( pDockingWindow )
{
PaneDockingWindow* pPaneDockingWindow = dynamic_cast< PaneDockingWindow* >( pDockingWindow );
OSL_ENSURE( pPaneDockingWindow, "ToolPanelViewShell_Impl::ConnectToDockingWindow: unsupported docking window type!" );
if ( pPaneDockingWindow != NULL )
m_pTaskPaneController.reset( new ::sfx2::TaskPaneController( GetTaskPane(), *pPaneDockingWindow ) );
}
// Tell the focus manager that we want to pass the focus to our
// child.
FocusManager::Instance().RegisterDownLink( GetAntiImpl().GetParentWindow(), &GetTaskPane() );
}
// ---------------------------------------------------------------------------------------------------------------------
Reference< XAccessible > ToolPanelViewShell_Impl::CreateAccessible( ::sd::Window& i_rWindow )
{
Reference< XAccessible > xAccessible( GetToolPanelDeck().GetAccessible( FALSE ) );
if ( !xAccessible.is() )
{
// determine the XAccessible which is the parent of the to-be-created object
::Window* pAccessibleParent = i_rWindow.GetAccessibleParentWindow();
OSL_ENSURE( pAccessibleParent, "ToolPanelViewShell_Impl::CreateAccessible: illegal accessible parent provided by the sd::Window!" );
GetToolPanelDeck().SetAccessibleParentWindow( pAccessibleParent );
xAccessible = GetToolPanelDeck().GetAccessible( TRUE );
ENSURE_OR_RETURN( xAccessible.is(), "ToolPanelViewShell_Impl::CreateAccessible: illegal ToolPanelDeck accessible!", NULL );
OSL_ENSURE( xAccessible->getAccessibleContext().is()
&& xAccessible->getAccessibleContext()->getAccessibleParent() == pAccessibleParent->GetAccessible(),
"ToolPanelViewShell_Impl::CreateAccessible: illegal parenthood!" );
}
return xAccessible;
}
} } // end of namespace ::sd::toolpanel