diff options
Diffstat (limited to 'sd/source')
114 files changed, 12333 insertions, 351 deletions
diff --git a/sd/source/core/glob.src b/sd/source/core/glob.src index 5dfe3dc8f715..c2c12753c7b8 100644 --- a/sd/source/core/glob.src +++ b/sd/source/core/glob.src @@ -370,14 +370,14 @@ String STR_TASKPANEVIEWSHELL Text [ en-US ] = "Tasks" ; }; -String STR_MASTERPAGESSELECTOR +String STR_TASKPANELAYOUTMENU { - Text [ en-US ] = "Master Pages" ; + Text [ en-US ] = "Layout" ; }; -String STR_TASKPANELAYOUTMENU +String STR_MASTERPAGESSELECTOR { - Text [ en-US ] = "Layout" ; + Text [ en-US ] = "Master Pages" ; }; String STR_POWERPOINT_IMPORT diff --git a/sd/source/core/typemap.cxx b/sd/source/core/typemap.cxx index bb7cad78e5df..7e5277e55c79 100644 --- a/sd/source/core/typemap.cxx +++ b/sd/source/core/typemap.cxx @@ -32,6 +32,9 @@ #include <editeng/fontitem.hxx> #include <svl/poolitem.hxx> #include <editeng/tstpitem.hxx> +#include <editeng/kernitem.hxx> +#include <editeng/lspcitem.hxx> +#include <editeng/ulspitem.hxx> #include <editeng/lrspitem.hxx> #include <editeng/protitem.hxx> #include <svx/chrtitem.hxx> @@ -92,6 +95,10 @@ #include <svl/rectitem.hxx> #include <sfx2/frame.hxx> +#include <svx/xlncapit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xlinjoit.hxx> +#include <svx/AffineMatrixItem.hxx> #define SFX_TYPEMAP #include "sdslots.hxx" diff --git a/sd/source/ui/animations/CustomAnimationPane.cxx b/sd/source/ui/animations/CustomAnimationPane.cxx index 31cf222e00bb..267feea6eaa8 100644 --- a/sd/source/ui/animations/CustomAnimationPane.cxx +++ b/sd/source/ui/animations/CustomAnimationPane.cxx @@ -54,6 +54,7 @@ #include <comphelper/sequence.hxx> #include <sfx2/frame.hxx> +#include <sfx2/sidebar/Theme.hxx> #include <svx/unoapi.hxx> #include <svx/svxids.hrc> @@ -239,6 +240,8 @@ CustomAnimationPane::CustomAnimationPane( ::Window* pParent, ViewShellBase& rBas maLateInitTimer.SetTimeout(100); maLateInitTimer.SetTimeoutHdl(LINK(this, CustomAnimationPane, lateInitCallback)); maLateInitTimer.Start(); + + UpdateLook(); } CustomAnimationPane::~CustomAnimationPane() @@ -1059,6 +1062,42 @@ void CustomAnimationPane::onContextMenu( sal_uInt16 nSelectedPopupEntry ) updateControls(); } + + + +void CustomAnimationPane::DataChanged (const DataChangedEvent& rEvent) +{ + (void)rEvent; + UpdateLook(); +} + + + + +void CustomAnimationPane::UpdateLook (void) +{ + SetBackground(::sfx2::sidebar::Theme::GetWallpaper(::sfx2::sidebar::Theme::Paint_PanelBackground)); + if (mpFLModify != NULL) + mpFLModify->SetBackground(Wallpaper()); + if (mpFLEffect != NULL) + mpFLEffect->SetBackground(Wallpaper()); + if (mpFTStart != NULL) + mpFTStart->SetBackground(Wallpaper()); + if (mpFTProperty != NULL) + mpFTProperty->SetBackground(Wallpaper()); + if (mpFTSpeed != NULL) + mpFTSpeed->SetBackground(Wallpaper()); + if (mpFTChangeOrder != NULL) + mpFTChangeOrder->SetBackground(Wallpaper()); + if (mpFLSeperator1 != NULL) + mpFLSeperator1->SetBackground(Wallpaper()); + if (mpFLSeperator2 != NULL) + mpFLSeperator2->SetBackground(Wallpaper()); +} + + + + void addValue( STLPropertySet* pSet, sal_Int32 nHandle, const Any& rValue ) { switch( pSet->getPropertyState( nHandle ) ) @@ -2457,8 +2496,10 @@ void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference< Mot if( pDocSh ) { pWindow = new DialogListBox( pParent, WB_CLIPCHILDREN|WB_TABSTOP|WB_AUTOHSCROLL ); + const Size aMinSize( pWindow->LogicToPixel( Size( 80, 256 ), MAP_APPFONT ) ); + pWindow->SetSizePixel(aMinSize); + pWindow->SetBackground(Wallpaper(Color(COL_BLUE))); - Size aMinSize( pWindow->LogicToPixel( Size( 80, 256 ), MAP_APPFONT ) ); ::Window* pPaneWindow = new CustomAnimationPane( pWindow, rBase, aMinSize ); pWindow->SetChildWindow( pPaneWindow, aMinSize ); pWindow->SetText( pPaneWindow->GetText() ); @@ -2469,6 +2510,15 @@ void CustomAnimationPane::updatePathFromMotionPathTag( const rtl::Reference< Mot + +sal_Int32 getCustomAnimationPanelMinimumHeight (::Window* pDialog) +{ + if (pDialog != NULL) + return pDialog->LogicToPixel(Size( 80, 256 ), MAP_APPFONT).Height(); + else + return 0; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/animations/CustomAnimationPane.hxx b/sd/source/ui/animations/CustomAnimationPane.hxx index 9e4d5c514da2..a95b14e3e64c 100644 --- a/sd/source/ui/animations/CustomAnimationPane.hxx +++ b/sd/source/ui/animations/CustomAnimationPane.hxx @@ -88,6 +88,9 @@ public: virtual void onDoubleClick(); virtual void onContextMenu( sal_uInt16 nSelectedPopupEntry ); + // Window + virtual void DataChanged (const DataChangedEvent& rEvent); + void addUndo(); void updatePathFromMotionPathTag( const rtl::Reference< MotionPathTag >& xTag ); @@ -111,6 +114,7 @@ private: ::com::sun::star::uno::Any getProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect ); bool setProperty1Value( sal_Int32 nType, CustomAnimationEffectPtr pEffect, const ::com::sun::star::uno::Any& rValue ); + void UpdateLook (void); DECL_LINK( implControlHdl, Control* ); DECL_LINK(implPropertyHdl, void *); diff --git a/sd/source/ui/animations/SlideTransitionPane.cxx b/sd/source/ui/animations/SlideTransitionPane.cxx index 05ac403eaa07..20334b3477f9 100644 --- a/sd/source/ui/animations/SlideTransitionPane.cxx +++ b/sd/source/ui/animations/SlideTransitionPane.cxx @@ -49,6 +49,7 @@ #include "framework/FrameworkHelper.hxx" #include "DialogListBox.hxx" +#include <sfx2/sidebar/Theme.hxx> #include <algorithm> #include <memory> @@ -511,6 +512,8 @@ SlideTransitionPane::SlideTransitionPane( maLateInitTimer.SetTimeout(200); maLateInitTimer.SetTimeoutHdl(LINK(this, SlideTransitionPane, LateInitCallback)); maLateInitTimer.Start(); + + UpdateLook(); } SlideTransitionPane::~SlideTransitionPane() @@ -524,6 +527,33 @@ void SlideTransitionPane::Resize() updateLayout(); } + + + +void SlideTransitionPane::DataChanged (const DataChangedEvent& rEvent) +{ + (void)rEvent; + UpdateLook(); +} + + + + +void SlideTransitionPane::UpdateLook (void) +{ + SetBackground(::sfx2::sidebar::Theme::GetWallpaper(::sfx2::sidebar::Theme::Paint_PanelBackground)); + maFL_APPLY_TRANSITION.SetBackground(Wallpaper()); + maFL_MODIFY_TRANSITION.SetBackground(Wallpaper());; + maFT_SPEED.SetBackground(Wallpaper()); + maFT_SOUND.SetBackground(Wallpaper()); + maFL_ADVANCE_SLIDE.SetBackground(Wallpaper()); + maFL_EMPTY1.SetBackground(Wallpaper()); + maFL_EMPTY2.SetBackground(Wallpaper()); +} + + + + void SlideTransitionPane::onSelectionChanged() { updateControls(); @@ -1300,6 +1330,17 @@ IMPL_LINK_NOARG(SlideTransitionPane, LateInitCallback) } + + +sal_Int32 getSlideTransitionPanelMinimumHeight (::Window* pDialog) +{ + if (pDialog != NULL) + return pDialog->LogicToPixel(Size( 72, 216 ), MAP_APPFONT).Height(); + else + return 0; +} + + } // namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/animations/SlideTransitionPane.hxx b/sd/source/ui/animations/SlideTransitionPane.hxx index e0c9ddd4a443..102d005417ba 100644 --- a/sd/source/ui/animations/SlideTransitionPane.hxx +++ b/sd/source/ui/animations/SlideTransitionPane.hxx @@ -56,7 +56,9 @@ public: SdDrawDocument* pDoc ); virtual ~SlideTransitionPane(); + // Window virtual void Resize(); + virtual void DataChanged (const DataChangedEvent& rEvent); void onSelectionChanged(); void onChangeCurrentPage(); @@ -79,6 +81,8 @@ private: ::sd::slidesorter::SharedPageSelection getSelectedPages (void) const; + void UpdateLook (void); + DECL_LINK( ApplyToAllButtonClicked, void * ); DECL_LINK( PlayButtonClicked, void * ); DECL_LINK( SlideShowButtonClicked, void * ); @@ -93,7 +97,6 @@ private: DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent*); DECL_LINK(LateInitCallback, void *); -private: ViewShellBase & mrBase; SdDrawDocument * mpDrawDoc; Size maMinSize; diff --git a/sd/source/ui/app/sddll1.cxx b/sd/source/ui/app/sddll1.cxx index 5fecbce7b4ee..09a7346bc33d 100644 --- a/sd/source/ui/app/sddll1.cxx +++ b/sd/source/ui/app/sddll1.cxx @@ -37,7 +37,6 @@ #include "DrawDocShell.hxx" #include "GraphicDocShell.hxx" #include "SlideSorterViewShell.hxx" -#include "taskpane/ToolPanelViewShell.hxx" #include "FactoryIds.hxx" #include "sdmod.hxx" #include "app.hrc" @@ -115,10 +114,6 @@ void SdDLL::RegisterInterfaces() // View shells for the side panes. ::sd::slidesorter::SlideSorterViewShell::RegisterInterface (pMod); - ::sd::toolpanel::ToolPanelViewShell::RegisterInterface(pMod); - // Tell the tool panel view shell to register the interfaces of its - // controls. - ::sd::toolpanel::ToolPanelViewShell::RegisterControls(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/app/sddll2.cxx b/sd/source/ui/app/sddll2.cxx index dbd6d3d0e1a4..e961cbf06c6e 100644 --- a/sd/source/ui/app/sddll2.cxx +++ b/sd/source/ui/app/sddll2.cxx @@ -53,6 +53,7 @@ #include <svx/layctrl.hxx> #include <svx/subtoolboxcontrol.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> #include "sddll.hxx" #include "sdmod.hxx" @@ -125,7 +126,7 @@ void SdDLL::RegisterControllers() ::avmedia::MediaPlayer::RegisterChildWindow(0, pMod); ::sd::LeftPaneImpressChildWindow::RegisterChildWindow(0, pMod); ::sd::LeftPaneDrawChildWindow::RegisterChildWindow(0, pMod); - ::sd::ToolPanelChildWindow::RegisterChildWindow(0, pMod); + ::sfx2::sidebar::SidebarChildWindow::RegisterChildWindow(0, pMod); SvxFillToolBoxControl::RegisterControl(0, pMod); SvxLineStyleToolBoxControl::RegisterControl(0, pMod); diff --git a/sd/source/ui/app/sdmod1.cxx b/sd/source/ui/app/sdmod1.cxx index ec2c033c5911..61cfa61ff08b 100644 --- a/sd/source/ui/app/sdmod1.cxx +++ b/sd/source/ui/app/sdmod1.cxx @@ -729,7 +729,7 @@ SfxFrame* SdModule::ExecuteNewDocument( SfxRequest& rReq ) ::sd::ViewShellBase* pBase = ::sd::ViewShellBase::GetViewShellBase(pViewFrame); if (pBase != NULL) { - FrameworkHelper::Instance(*pBase)->RequestTaskPanel( + FrameworkHelper::Instance(*pBase)->RequestSidebarPanel( FrameworkHelper::msLayoutTaskPanelURL); } } diff --git a/sd/source/ui/dlg/NavigatorChildWindow.cxx b/sd/source/ui/dlg/NavigatorChildWindow.cxx index 2135eb8ec3b9..09b129617986 100644 --- a/sd/source/ui/dlg/NavigatorChildWindow.cxx +++ b/sd/source/ui/dlg/NavigatorChildWindow.cxx @@ -23,11 +23,31 @@ #include "app.hrc" #include "navigatr.hrc" #include <sfx2/app.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <svl/eitem.hxx> +#include <boost/bind.hpp> + namespace sd { SFX_IMPL_CHILDWINDOWCONTEXT(NavigatorChildWindow, SID_NAVIGATOR) +void RequestNavigatorUpdate (SfxBindings* pBindings) +{ + if (pBindings != NULL + && pBindings->GetDispatcher() != NULL) + { + SfxBoolItem aItem (SID_NAVIGATOR_INIT, sal_True); + pBindings->GetDispatcher()->Execute( + SID_NAVIGATOR_INIT, + SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, + &aItem, + 0L); + } +} + + NavigatorChildWindow::NavigatorChildWindow ( ::Window* pParent, sal_uInt16 nId, @@ -35,8 +55,12 @@ NavigatorChildWindow::NavigatorChildWindow ( SfxChildWinInfo* ) : SfxChildWindowContext( nId ) { - SdNavigatorWin* pNavWin = new SdNavigatorWin( pParent, this, - SdResId( FLT_NAVIGATOR ), pBindings ); + SdNavigatorWin* pNavWin = new SdNavigatorWin( + pParent, + this, + SdResId( FLT_NAVIGATOR ), + pBindings, + ::boost::bind(RequestNavigatorUpdate, pBindings)); SetWindow( pNavWin ); } diff --git a/sd/source/ui/dlg/PaneChildWindows.cxx b/sd/source/ui/dlg/PaneChildWindows.cxx index 67edc11a9f7b..3b12bf101e36 100644 --- a/sd/source/ui/dlg/PaneChildWindows.cxx +++ b/sd/source/ui/dlg/PaneChildWindows.cxx @@ -46,7 +46,7 @@ using ::com::sun::star::drawing::framework::ResourceActivationMode_REPLACE; SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneImpressChildWindow, SID_LEFT_PANE_IMPRESS) SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneDrawChildWindow, SID_LEFT_PANE_DRAW) -SFX_IMPL_DOCKINGWINDOW_WITHID( ToolPanelChildWindow, SID_TASKPANE) +SFX_IMPL_DOCKINGWINDOW_WITHID(ToolPanelChildWindow, SID_TASKPANE) //===== PaneChildWindow ======================================================= @@ -136,12 +136,6 @@ LeftPaneDrawChildWindow::LeftPaneDrawChildWindow ( } - - -//====================================================================================================================== -//= ToolPanelChildWindow -//====================================================================================================================== -//---------------------------------------------------------------------------------------------------------------------- ToolPanelChildWindow::ToolPanelChildWindow( ::Window* i_pParentWindow, sal_uInt16 i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pChildWindowInfo ) :PaneChildWindow( i_pParentWindow, i_nId, i_pBindings, i_pChildWindowInfo, @@ -200,7 +194,7 @@ void ToolPanelChildWindow::ActivateToolPanel( const OUString& i_rPanelURL ) if ( i_rPanelURL.indexOf( framework::FrameworkHelper::msTaskPanelURLPrefix ) == 0 ) { // it's one of our standard panels known to the drawing framework - pFrameworkHelper->RequestTaskPanel( i_rPanelURL ); + pFrameworkHelper->RequestSidebarPanel( i_rPanelURL ); // MMeeks } else { diff --git a/sd/source/ui/dlg/PaneShells.cxx b/sd/source/ui/dlg/PaneShells.cxx index 668d7abd9b09..023dbcc810a4 100644 --- a/sd/source/ui/dlg/PaneShells.cxx +++ b/sd/source/ui/dlg/PaneShells.cxx @@ -93,32 +93,6 @@ LeftDrawPaneShell::~LeftDrawPaneShell (void) } - - -//===== ToolPanelPaneShell ======================================================== - -SFX_SLOTMAP( ToolPanelPaneShell ) -{ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -SFX_IMPL_INTERFACE( ToolPanelPaneShell, SfxShell, SdResId( STR_TOOL_PANEL_SHELL ) ) -{ - SFX_CHILDWINDOW_REGISTRATION( ::sd::ToolPanelChildWindow::GetChildWindowId() ); -} - -TYPEINIT1( ToolPanelPaneShell, SfxShell ); - -ToolPanelPaneShell::ToolPanelPaneShell() - :SfxShell() -{ - SetName(OUString("ToolPanel")); -} - -ToolPanelPaneShell::~ToolPanelPaneShell(void) -{ -} - } // end of namespace ::sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx index b80f7e385ddf..88262d7668f0 100644 --- a/sd/source/ui/dlg/navigatr.cxx +++ b/sd/source/ui/dlg/navigatr.cxx @@ -63,17 +63,18 @@ SdNavigatorWin::SdNavigatorWin( ::Window* pParent, ::sd::NavigatorChildWindow* pChWinCtxt, const SdResId& rSdResId, - SfxBindings* pInBindings ) -: ::Window( pParent, rSdResId ) -, maToolbox ( this, SdResId( 1 ) ) -, maTlbObjects( this, SdResId( TLB_OBJECTS ) ) -, maLbDocs ( this, SdResId( LB_DOCS ) ) -, mpChildWinContext( pChWinCtxt ) -, mbDocImported ( sal_False ) - // On changes of the DragType: adjust SelectionMode of TLB! -, meDragType ( NAVIGATOR_DRAGTYPE_EMBEDDED ) -, mpBindings ( pInBindings ) -, maImageList ( SdResId( IL_NAVIGATR ) ) + SfxBindings* pInBindings, + const UpdateRequestFunctor& rUpdateRequest) + : ::Window( pParent, rSdResId ) + , maToolbox ( this, SdResId( 1 ) ) + , maTlbObjects( this, SdResId( TLB_OBJECTS ) ) + , maLbDocs ( this, SdResId( LB_DOCS ) ) + , mpChildWinContext( pChWinCtxt ) + , mbDocImported ( sal_False ) + // On changes of the DragType: adjust SelectionMode of TLB! + , meDragType ( NAVIGATOR_DRAGTYPE_EMBEDDED ) + , mpBindings ( pInBindings ) + , maImageList ( SdResId( IL_NAVIGATR ) ) { maTlbObjects.SetViewFrame( mpBindings->GetDispatcher()->GetFrame() ); @@ -81,8 +82,8 @@ SdNavigatorWin::SdNavigatorWin( maTlbObjects.SetAccessibleName(String(SdResId(STR_OBJECTS_TREE))); - mpNavigatorCtrlItem = new SdNavigatorControllerItem( SID_NAVIGATOR_STATE, this, mpBindings ); - mpPageNameCtrlItem = new SdPageNameControllerItem( SID_NAVIGATOR_PAGENAME, this, mpBindings ); + mpNavigatorCtrlItem = new SdNavigatorControllerItem( SID_NAVIGATOR_STATE, this, mpBindings, rUpdateRequest); + mpPageNameCtrlItem = new SdPageNameControllerItem( SID_NAVIGATOR_PAGENAME, this, mpBindings, rUpdateRequest); ApplyImageList(); // load images *before* calculating sizes to get something useful !!! @@ -126,13 +127,13 @@ SdNavigatorWin::SdNavigatorWin( if( nMinWidth > maMinSize.Width() ) maMinSize.Width() = nMinWidth; maMinSize.Height() -= 40; - ((SfxDockingWindow*)GetParent())->SetMinOutputSizePixel( maMinSize ); + SfxDockingWindow* pDockingParent = dynamic_cast<SfxDockingWindow*>(GetParent()); + if (pDockingParent != NULL) + pDockingParent->SetMinOutputSizePixel( maMinSize ); // InitTlb; is initiated over Slot - SfxBoolItem aItem( SID_NAVIGATOR_INIT, sal_True ); - mpBindings->GetDispatcher()->Execute( - SID_NAVIGATOR_INIT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); - + if (rUpdateRequest) + rUpdateRequest(); } // ----------------------------------------------------------------------- @@ -836,11 +837,14 @@ void SdNavigatorWin::ApplyImageList() /** * ControllerItem for Navigator */ -SdNavigatorControllerItem::SdNavigatorControllerItem( sal_uInt16 _nId, - SdNavigatorWin* pNavWin, - SfxBindings* _pBindings) : - SfxControllerItem( _nId, *_pBindings ), - pNavigatorWin( pNavWin ) +SdNavigatorControllerItem::SdNavigatorControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings, + const SdNavigatorWin::UpdateRequestFunctor& rUpdateRequest) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ), + maUpdateRequest(rUpdateRequest) { } @@ -908,9 +912,8 @@ void SdNavigatorControllerItem::StateChanged( sal_uInt16 nSId, if( nState & NAVTLB_UPDATE ) { // InitTlb; is initiated by Slot - SfxBoolItem aItem( SID_NAVIGATOR_INIT, sal_True ); - GetBindings().GetDispatcher()->Execute( - SID_NAVIGATOR_INIT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L ); + if (maUpdateRequest) + maUpdateRequest(); } } } @@ -919,11 +922,14 @@ void SdNavigatorControllerItem::StateChanged( sal_uInt16 nSId, /** * ControllerItem for Navigator to show page in TreeLB */ -SdPageNameControllerItem::SdPageNameControllerItem( sal_uInt16 _nId, - SdNavigatorWin* pNavWin, - SfxBindings* _pBindings) : - SfxControllerItem( _nId, *_pBindings ), - pNavigatorWin( pNavWin ) +SdPageNameControllerItem::SdPageNameControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings, + const SdNavigatorWin::UpdateRequestFunctor& rUpdateRequest) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ), + maUpdateRequest(rUpdateRequest) { } diff --git a/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx index 4b9f3e8b7adb..16a96f2ecca0 100644 --- a/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx +++ b/sd/source/ui/framework/configuration/ConfigurationControllerResourceManager.cxx @@ -150,9 +150,9 @@ void ConfigurationControllerResourceManager::ActivateResource ( // of registered factories. mpResourceFactoryContainer->RemoveFactoryForReference(xFactory); } - catch(Exception&) + catch (Exception& e) { - DBG_UNHANDLED_EXCEPTION(); + (void)e; } if (xResource.is()) @@ -187,9 +187,10 @@ void ConfigurationControllerResourceManager::ActivateResource ( /* In this method we do following steps. 1. Remove the resource from the URL->Object map of the configuration controller. - 2. Notify listeners. + 2. Notify listeners that deactivation has started. 3. Remove the resource id from the current configuration. 4. Release the resource. + 5. Notify listeners about that deactivation is completed. */ void ConfigurationControllerResourceManager::DeactivateResource ( const Reference<XResourceId>& rxResourceId, @@ -244,6 +245,12 @@ void ConfigurationControllerResourceManager::DeactivateResource ( DBG_UNHANDLED_EXCEPTION(); } + // 5. Notifiy listeners that the resource is being deactivated. + mpBroadcaster->NotifyListeners( + FrameworkHelper::msResourceDeactivationEndEvent, + rxResourceId, + NULL); + #if OSL_DEBUG_LEVEL >= 1 if (bSuccess) SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": successfully deactivated " << OUStringToOString( diff --git a/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx b/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx index f059efdb8c81..90b1d4359508 100644 --- a/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx +++ b/sd/source/ui/framework/configuration/ResourceFactoryManager.cxx @@ -32,6 +32,9 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; +#undef VERBOSE +//#define VERBOSE 1 + namespace sd { namespace framework { ResourceFactoryManager::ResourceFactoryManager (const Reference<XControllerManager>& rxManager) @@ -75,10 +78,22 @@ void ResourceFactoryManager::AddFactory ( { // The URL is a URL pattern not an single URL. maFactoryPatternList.push_back(FactoryPatternList::value_type(rsURL, rxFactory)); + +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("ResourceFactoryManager::AddFactory pattern %s %x\n", + OUStringToOString(rsURL, RTL_TEXTENCODING_UTF8).getStr(), + rxFactory.get()); +#endif } else { maFactoryMap[rsURL] = rxFactory; + +#if defined VERBOSE && VERBOSE>=1 + OSL_TRACE("ResourceFactoryManager::AddFactory fixed %s %x\n", + OUStringToOString(rsURL, RTL_TEXTENCODING_UTF8).getStr(), + rxFactory.get()); +#endif } } diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.cxx b/sd/source/ui/framework/factories/BasicPaneFactory.cxx index 4d2651dff923..5c5a043d41c7 100644 --- a/sd/source/ui/framework/factories/BasicPaneFactory.cxx +++ b/sd/source/ui/framework/factories/BasicPaneFactory.cxx @@ -45,8 +45,7 @@ namespace { CenterPaneId, FullScreenPaneId, LeftImpressPaneId, - LeftDrawPaneId, - RightPaneId + LeftDrawPaneId }; static const sal_Int32 gnConfigurationUpdateStartEvent(0); @@ -194,7 +193,7 @@ void SAL_CALL BasicPaneFactory::initialize (const Sequence<Any>& aArguments) mxConfigurationControllerWeak = xCC; // Add pane factories for the two left panes (one for Impress and one for - // Draw), the center pane, and the right pane. + // Draw) and the center pane. if (xController.is() && xCC.is()) { PaneDescriptor aDescriptor; @@ -220,11 +219,6 @@ void SAL_CALL BasicPaneFactory::initialize (const Sequence<Any>& aArguments) aDescriptor.mePaneId = LeftDrawPaneId; mpPaneContainer->push_back(aDescriptor); xCC->addResourceFactory(aDescriptor.msPaneURL, this); - - aDescriptor.msPaneURL = FrameworkHelper::msRightPaneURL; - aDescriptor.mePaneId = RightPaneId; - mpPaneContainer->push_back(aDescriptor); - xCC->addResourceFactory(aDescriptor.msPaneURL, this); } // Register as configuration change listener. @@ -293,7 +287,6 @@ Reference<XResource> SAL_CALL BasicPaneFactory::createResource ( case LeftImpressPaneId: case LeftDrawPaneId: - case RightPaneId: xPane = CreateChildWindowPane( rxPaneId, *iDescriptor); @@ -479,11 +472,6 @@ Reference<XResource> BasicPaneFactory::CreateChildWindowPane ( nChildWindowId = ::sd::LeftPaneDrawChildWindow::GetChildWindowId(); break; - case RightPaneId: - pShell.reset(new ToolPanelPaneShell()); - nChildWindowId = ::sd::ToolPanelChildWindow::GetChildWindowId(); - break; - default: break; } diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.hxx b/sd/source/ui/framework/factories/BasicPaneFactory.hxx index 472609a17677..de9c81b9d564 100644 --- a/sd/source/ui/framework/factories/BasicPaneFactory.hxx +++ b/sd/source/ui/framework/factories/BasicPaneFactory.hxx @@ -59,7 +59,6 @@ namespace sd { namespace framework { private:resource/pane/FullScreenPane private:resource/pane/LeftImpressPane private:resource/pane/LeftDrawPane - private:resource/pane/RightPane There are two left panes because this is (seems to be) the only way to show different titles for the left pane in Draw and Impress. */ diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx index 927a26159cd4..78d79888a9bc 100644 --- a/sd/source/ui/framework/factories/BasicViewFactory.cxx +++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx @@ -33,7 +33,6 @@ #include "DrawViewShell.hxx" #include "GraphicViewShell.hxx" #include "OutlineViewShell.hxx" -#include "taskpane/ToolPanelViewShell.hxx" #include "PresentationViewShell.hxx" #include "SlideSorterViewShell.hxx" #include "FrameView.hxx" @@ -319,7 +318,6 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence<Any>& aArguments) mxConfigurationController->addResourceFactory(FrameworkHelper::msNotesViewURL, this); mxConfigurationController->addResourceFactory(FrameworkHelper::msHandoutViewURL, this); mxConfigurationController->addResourceFactory(FrameworkHelper::msPresentationViewURL, this); - mxConfigurationController->addResourceFactory(FrameworkHelper::msTaskPaneURL, this); mxConfigurationController->addResourceFactory(FrameworkHelper::msSlideSorterURL, this); } catch (RuntimeException&) @@ -449,15 +447,6 @@ void SAL_CALL BasicViewFactory::initialize (const Sequence<Any>& aArguments) &rWindow, pFrameView)); } - else if (rsViewURL.equals(FrameworkHelper::msTaskPaneURL)) - { - pViewShell.reset( - new ::sd::toolpanel::ToolPanelViewShell( - &rFrame, - *mpBase, - &rWindow, - pFrameView)); - } else if (rsViewURL.equals(FrameworkHelper::msSlideSorterURL)) { pViewShell = ::sd::slidesorter::SlideSorterViewShell::Create ( @@ -533,8 +522,6 @@ bool BasicViewFactory::IsCacheable (const ::boost::shared_ptr<ViewDescriptor>& r FrameworkHelper::msSlideSorterURL, FrameworkHelper::msLeftDrawPaneURL)); maCacheableResources.push_back(pHelper->CreateResourceId( FrameworkHelper::msSlideSorterURL, FrameworkHelper::msLeftImpressPaneURL)); - maCacheableResources.push_back(pHelper->CreateResourceId( - FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL)); } ::std::vector<Reference<XResourceId> >::const_iterator iId; diff --git a/sd/source/ui/framework/factories/Pane.cxx b/sd/source/ui/framework/factories/Pane.cxx index 4eeb5c5f3e0c..30bcaa0f9c9f 100644 --- a/sd/source/ui/framework/factories/Pane.cxx +++ b/sd/source/ui/framework/factories/Pane.cxx @@ -75,6 +75,16 @@ void Pane::disposing (void) +void Pane::SetWindow (::Window* pWindow) +{ + OSL_TRACE("setting Pane::mpWindow to %x", pWindow); + mpWindow = pWindow; + mxWindow = VCLUnoHelper::GetInterface(mpWindow); +} + + + + //----- XPane ----------------------------------------------------------------- Reference<awt::XWindow> SAL_CALL Pane::getWindow (void) diff --git a/sd/source/ui/framework/factories/TaskPanelResource.cxx b/sd/source/ui/framework/factories/TaskPanelResource.cxx new file mode 100644 index 000000000000..f3201adea23d --- /dev/null +++ b/sd/source/ui/framework/factories/TaskPanelResource.cxx @@ -0,0 +1,129 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#include "precompiled_sd.hxx" + +#include "framework/TaskPanelResource.hxx" + +#include <vcl/window.hxx> +#include <toolkit/helper/vclunohelper.hxx> + + +using namespace css; +using namespace cssu; +using namespace cssdf; + + +namespace sd { namespace framework { + +namespace { + ::Window* GetWindowForResource ( + ViewShellBase& rViewShellBase, + const cssu::Reference<cssdf::XResourceId>& rxResourceId) + { + ::Window* pWindow = NULL; + if (rxResourceId.is() && rxResourceId->getAnchor().is()) + { + ::boost::shared_ptr<FrameworkHelper> pFrameworkHelper (FrameworkHelper::Instance(rViewShellBase)); + Reference<awt::XWindow> xWindow ( + pFrameworkHelper->GetPaneWindow(rxResourceId->getAnchor()->getAnchor())); + pWindow = VCLUnoHelper::GetWindow(xWindow); + } + return pWindow; + } +} + + + + +TaskPanelResource::TaskPanelResource ( + sidebar::SidebarViewShell& rSidebarViewShell, + sidebar::PanelId ePanelId, + const Reference<XResourceId>& rxResourceId) + : TaskPanelResourceInterfaceBase(m_aMutex), + mxResourceId(rxResourceId), + mpControl(rSidebarViewShell.CreatePanel( + GetWindowForResource(rSidebarViewShell.GetViewShellBase(), rxResourceId), + ePanelId)) +{ + if (mpControl.get() != NULL) + { + mpControl->Show(); + mpControl->GetParent()->Show(); + mpControl->AddEventListener(LINK(this,TaskPanelResource,WindowEventHandler)); + } +} + + + + +TaskPanelResource::~TaskPanelResource (void) +{ + mpControl.reset(); +} + + + + +void SAL_CALL TaskPanelResource::disposing () +{ + mpControl.reset(); +} + + + + +Reference<XResourceId> SAL_CALL TaskPanelResource::getResourceId () + throw (css::uno::RuntimeException) +{ + return mxResourceId; +} + + + + +sal_Bool SAL_CALL TaskPanelResource::isAnchorOnly (void) + throw (RuntimeException) +{ + return false; +} + + + + +::Window* TaskPanelResource::GetControl (void) const +{ + return mpControl.get(); +} + + + + +IMPL_LINK(TaskPanelResource,WindowEventHandler,VclWindowEvent*,pEvent) +{ + if (pEvent!=NULL && pEvent->GetId()==SFX_HINT_DYING) + { + // Somebody else deleted the window. Release our reference so + // that we do not delete it again. + mpControl.release(); + return sal_True; + } + else + return sal_False; +} + +} } // end of namespace sd::framework diff --git a/sd/source/ui/framework/factories/ViewShellWrapper.cxx b/sd/source/ui/framework/factories/ViewShellWrapper.cxx index e017cbf21566..1ff46da11d48 100644 --- a/sd/source/ui/framework/factories/ViewShellWrapper.cxx +++ b/sd/source/ui/framework/factories/ViewShellWrapper.cxx @@ -20,7 +20,6 @@ #include "framework/ViewShellWrapper.hxx" #include "framework/Pane.hxx" -#include "taskpane/ToolPanelViewShell.hxx" #include "sdpage.hxx" #include "ViewShell.hxx" #include "Window.hxx" @@ -55,7 +54,6 @@ using ::com::sun::star::awt::XWindow; using ::com::sun::star::rendering::XCanvas; using ::com::sun::star::lang::DisposedException; -using ::sd::toolpanel::ToolPanelViewShell; namespace sd { namespace framework { diff --git a/sd/source/ui/framework/module/ImpressModule.cxx b/sd/source/ui/framework/module/ImpressModule.cxx index 50e9cfb67f45..240a94a23cf3 100644 --- a/sd/source/ui/framework/module/ImpressModule.cxx +++ b/sd/source/ui/framework/module/ImpressModule.cxx @@ -47,7 +47,7 @@ void ImpressModule::Initialize (Reference<frame::XController>& rxController) FrameworkHelper::msLeftImpressPaneURL); new ToolPanelModule( rxController, - FrameworkHelper::msRightPaneURL); + FrameworkHelper::msSidebarViewURL); new ToolBarModule(rxController); new ShellStackGuard(rxController); } diff --git a/sd/source/ui/framework/module/ModuleController.cxx b/sd/source/ui/framework/module/ModuleController.cxx index 25abb78d2df9..1406d6e14d5a 100644 --- a/sd/source/ui/framework/module/ModuleController.cxx +++ b/sd/source/ui/framework/module/ModuleController.cxx @@ -282,10 +282,19 @@ void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL) // Create the factory service. Sequence<Any> aArguments(1); aArguments[0] <<= mxController; - xFactory = xContext->getServiceManager()->createInstanceWithArgumentsAndContext( - iFactory->second, - aArguments, - xContext); + OSL_TRACE("creating resource %s", + OUStringToOString(iFactory->second, RTL_TEXTENCODING_ASCII_US).getStr()); + try + { + xFactory = xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + iFactory->second, + aArguments, + xContext); + } + catch (const Exception&) + { + OSL_TRACE("caught exception while creating factory."); + } // Remember that this factory has been instanced. (*mpLoadedFactories)[iFactory->second] = xFactory; diff --git a/sd/source/ui/framework/module/ToolPanelModule.cxx b/sd/source/ui/framework/module/ToolPanelModule.cxx index aa2c9e8a9e24..c607fbd3820a 100644 --- a/sd/source/ui/framework/module/ToolPanelModule.cxx +++ b/sd/source/ui/framework/module/ToolPanelModule.cxx @@ -42,9 +42,9 @@ namespace sd { namespace framework { ToolPanelModule::ToolPanelModule ( const Reference<frame::XController>& rxController, - const OUString& rsRightPaneURL) + const OUString& rsSidebarPaneURL) : ResourceManager(rxController, - FrameworkHelper::CreateResourceId(FrameworkHelper::msTaskPaneURL, rsRightPaneURL)), + FrameworkHelper::CreateResourceId(FrameworkHelper::msSidebarViewURL, rsSidebarPaneURL)), mxControllerManager(rxController,UNO_QUERY) { if (mxConfigurationController.is()) diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx index fb7fa1a2a328..f3ed52523c39 100644 --- a/sd/source/ui/framework/tools/FrameworkHelper.cxx +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -17,7 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - #include <osl/time.h> #include "framework/FrameworkHelper.hxx" @@ -32,6 +31,7 @@ #include "DrawController.hxx" #include "app.hrc" #include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XPane.hpp> #include <cppuhelper/compbase1.hxx> #include <svl/lstner.hxx> @@ -97,8 +97,10 @@ public: virtual ~CallbackCaller (void); virtual void SAL_CALL disposing (void); + // XEventListener virtual void SAL_CALL disposing (const lang::EventObject& rEvent) throw (RuntimeException); + // XConfigurationChangeListener virtual void SAL_CALL notifyConfigurationChange (const ConfigurationChangeEvent& rEvent) throw (RuntimeException); @@ -169,7 +171,7 @@ const OUString FrameworkHelper::msCenterPaneURL( msPaneURLPrefix + "CenterPane") const OUString FrameworkHelper::msFullScreenPaneURL( msPaneURLPrefix + "FullScreenPane"); const OUString FrameworkHelper::msLeftImpressPaneURL( msPaneURLPrefix + "LeftImpressPane"); const OUString FrameworkHelper::msLeftDrawPaneURL( msPaneURLPrefix + "LeftDrawPane"); -const OUString FrameworkHelper::msRightPaneURL( msPaneURLPrefix + "RightPane"); +const OUString FrameworkHelper::msSidebarPaneURL( msPaneURLPrefix + "SidebarPane"); // View URLs. @@ -182,7 +184,7 @@ const OUString FrameworkHelper::msNotesViewURL( msViewURLPrefix + "NotesView"); const OUString FrameworkHelper::msHandoutViewURL( msViewURLPrefix + "HandoutView"); const OUString FrameworkHelper::msSlideSorterURL( msViewURLPrefix + "SlideSorter"); const OUString FrameworkHelper::msPresentationViewURL( msViewURLPrefix + "PresentationView"); -const OUString FrameworkHelper::msTaskPaneURL( msViewURLPrefix + "TaskPane"); +const OUString FrameworkHelper::msSidebarViewURL( msViewURLPrefix + "SidebarView"); // Tool bar URLs. @@ -192,21 +194,25 @@ const OUString FrameworkHelper::msViewTabBarURL( msToolBarURLPrefix + "ViewTabBa // Task panel URLs. -const OUString FrameworkHelper::msTaskPanelURLPrefix("private:resource/toolpanel/DrawingFramework/"); +const OUString FrameworkHelper::msTaskPanelURLPrefix( "private:resource/toolpanel/" ); const OUString FrameworkHelper::msMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "MasterPages"); -const OUString FrameworkHelper::msLayoutTaskPanelURL( msTaskPanelURLPrefix + "Layouts"); -const OUString FrameworkHelper::msTableDesignPanelURL( msTaskPanelURLPrefix + "TableDesign"); -const OUString FrameworkHelper::msCustomAnimationTaskPanelURL( msTaskPanelURLPrefix + "CustomAnimations"); -const OUString FrameworkHelper::msSlideTransitionTaskPanelURL( msTaskPanelURLPrefix + "SlideTransitions"); +const OUString FrameworkHelper::msAllMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "AllMasterPages" ); +const OUString FrameworkHelper::msRecentMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "RecentMasterPages" ); +const OUString FrameworkHelper::msUsedMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "UsedMasterPages" ); +const OUString FrameworkHelper::msLayoutTaskPanelURL( msTaskPanelURLPrefix + "Layouts" ); +const OUString FrameworkHelper::msTableDesignPanelURL( msTaskPanelURLPrefix + "TableDesign" ); +const OUString FrameworkHelper::msCustomAnimationTaskPanelURL( msTaskPanelURLPrefix + "CustomAnimations" ); +const OUString FrameworkHelper::msSlideTransitionTaskPanelURL( msTaskPanelURLPrefix + "SlideTransitions" ); // Event URLs. -const OUString FrameworkHelper::msResourceActivationRequestEvent("ResourceActivationRequested"); -const OUString FrameworkHelper::msResourceDeactivationRequestEvent("ResourceDeactivationRequest"); -const OUString FrameworkHelper::msResourceActivationEvent("ResourceActivation"); -const OUString FrameworkHelper::msResourceDeactivationEvent("ResourceDeactivation"); -const OUString FrameworkHelper::msConfigurationUpdateStartEvent("ConfigurationUpdateStart"); -const OUString FrameworkHelper::msConfigurationUpdateEndEvent("ConfigurationUpdateEnd"); +const OUString FrameworkHelper::msResourceActivationRequestEvent( "ResourceActivationRequested" ); +const OUString FrameworkHelper::msResourceDeactivationRequestEvent( "ResourceDeactivationRequest" ); +const OUString FrameworkHelper::msResourceActivationEvent( "ResourceActivation" ); +const OUString FrameworkHelper::msResourceDeactivationEvent( "ResourceDeactivation" ); +const OUString FrameworkHelper::msResourceDeactivationEndEvent( "ResourceDeactivationEnd" ); +const OUString FrameworkHelper::msConfigurationUpdateStartEvent( "ConfigurationUpdateStart" ); +const OUString FrameworkHelper::msConfigurationUpdateEndEvent( "ConfigurationUpdateEnd" ); // Service names of controllers. @@ -301,6 +307,20 @@ private: +//----- FrameworkHelper::Deleter ---------------------------------------------- + +class FrameworkHelper::Deleter +{ +public: + void operator()(FrameworkHelper* pObject) + { + delete pObject; + } +}; + + + + //----- FrameworkHelper ------------------------------------------------------- ::boost::scoped_ptr<FrameworkHelper::ViewURLMap> FrameworkHelper::mpViewURLMap(new ViewURLMap()); @@ -345,7 +365,9 @@ FrameworkHelper::InstanceMap FrameworkHelper::maInstanceMap; ::osl::MutexGuard aGuard (aMutexFunctor()); if (iHelper == maInstanceMap.end()) { - pHelper = ::boost::shared_ptr<FrameworkHelper>(new FrameworkHelper(rBase)); + pHelper = ::boost::shared_ptr<FrameworkHelper>( + new FrameworkHelper(rBase), + FrameworkHelper::Deleter()); pHelper->Initialize(); OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); SdGlobalResourceContainer::Instance().AddResource(pHelper); @@ -489,6 +511,61 @@ Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneO +Reference<awt::XWindow> FrameworkHelper::GetPaneWindow (const Reference<XResourceId>& rxPaneId) +{ + Reference<awt::XWindow> xWindow; + + if (rxPaneId.is() && mxConfigurationController.is()) + { + try + { + if (rxPaneId->getResourceURL().match(msPaneURLPrefix)) + { + Reference<XPane> xPane (mxConfigurationController->getResource(rxPaneId), UNO_QUERY); + if (xPane.is()) + xWindow = xPane->getWindow(); + } + } + catch (lang::DisposedException&) + { + Dispose(); + } + catch (RuntimeException&) + { + } + } + + return xWindow; +} + + + + +Reference<XResource> FrameworkHelper::GetResource (const Reference<XResourceId>& rxResourceId) +{ + Reference<XResource> xResource; + + if (rxResourceId.is() && mxConfigurationController.is()) + { + try + { + return mxConfigurationController->getResource(rxResourceId); + } + catch (lang::DisposedException&) + { + Dispose(); + } + catch (RuntimeException&) + { + } + } + + return NULL; +} + + + + Reference<XResourceId> FrameworkHelper::RequestView ( const OUString& rsResourceURL, const OUString& rsAnchorURL) @@ -524,7 +601,7 @@ Reference<XResourceId> FrameworkHelper::RequestView ( -void FrameworkHelper::RequestTaskPanel ( +Reference<XResourceId> FrameworkHelper::RequestSidebarPanel ( const OUString& rsTaskPanelURL, const bool bEnsureTaskPaneIsVisible) { @@ -537,26 +614,29 @@ void FrameworkHelper::RequestTaskPanel ( { Reference<XConfiguration> xConfiguration ( mxConfigurationController->getCurrentConfiguration()); - if (xConfiguration.is()) - if ( ! xConfiguration->hasResource( - CreateResourceId(msTaskPaneURL, msRightPaneURL))) - { - // Task pane does is not active. Do not force it. - return; - } + if (xConfiguration.is()) + if ( ! xConfiguration->hasResource( + CreateResourceId(msSidebarViewURL, msSidebarPaneURL))) + { + // Task pane is not active. Do not force it. + return NULL; + } } - // Create the resource id from URLs for the pane, the task pane - // view, and the task panel. + // Create the resource id from URLs for the sidebar pane + // and view and the requested panel. mxConfigurationController->requestResourceActivation( - CreateResourceId(msRightPaneURL), + CreateResourceId(msSidebarPaneURL), ResourceActivationMode_ADD); mxConfigurationController->requestResourceActivation( - CreateResourceId(msTaskPaneURL, msRightPaneURL), + CreateResourceId(msSidebarViewURL, msSidebarPaneURL), ResourceActivationMode_REPLACE); + Reference<XResourceId> xPanelId (CreateResourceId(rsTaskPanelURL, msSidebarViewURL, msSidebarPaneURL)); mxConfigurationController->requestResourceActivation( - CreateResourceId(rsTaskPanelURL, msTaskPaneURL, msRightPaneURL), + xPanelId, ResourceActivationMode_REPLACE); + + return xPanelId; } } catch (lang::DisposedException&) @@ -565,6 +645,26 @@ void FrameworkHelper::RequestTaskPanel ( } catch (RuntimeException&) {} + + return NULL; +} + + + + +void FrameworkHelper::RequestResourceDeactivation (const cssu::Reference<cssdf::XResourceId>& rxResourceId) +{ + try + { + if (mxConfigurationController.is() && rxResourceId.is()) + mxConfigurationController->requestResourceDeactivation(rxResourceId); + } + catch (lang::DisposedException&) + { + Dispose(); + } + catch (RuntimeException&) + {} } @@ -582,6 +682,7 @@ ViewShell::ShellType FrameworkHelper::GetViewId (const OUString& rsViewURL) (*mpViewURLMap)[msSlideSorterURL] = ViewShell::ST_SLIDE_SORTER; (*mpViewURLMap)[msPresentationViewURL] = ViewShell::ST_PRESENTATION; (*mpViewURLMap)[msTaskPaneURL] = ViewShell::ST_TASK_PANE; + (*mpViewURLMap)[msSidebarViewURL] = ViewShell::ST_SIDEBAR; } ViewURLMap::const_iterator iView (mpViewURLMap->find(rsViewURL)); if (iView != mpViewURLMap->end()) @@ -605,6 +706,7 @@ OUString FrameworkHelper::GetViewURL (ViewShell::ShellType eType) case ViewShell::ST_SLIDE_SORTER : return msSlideSorterURL; case ViewShell::ST_PRESENTATION : return msPresentationViewURL; case ViewShell::ST_TASK_PANE : return msTaskPaneURL; + case ViewShell::ST_SIDEBAR : return msSidebarViewURL; default: return OUString(); } @@ -753,6 +855,30 @@ void FrameworkHelper::RunOnResourceActivation( +void FrameworkHelper::RunOnResourceDeactivation( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, + const Callback& rCallback, + const bool bRunOnDeactivationEnd) +{ + if (mxConfigurationController.is() + && ! mxConfigurationController->getResource(rxResourceId).is()) + { + rCallback(false); + } + else + { + RunOnEvent( + bRunOnDeactivationEnd + ? msResourceDeactivationEndEvent + : msResourceDeactivationEvent, + FrameworkHelperResourceIdFilter(rxResourceId), + rCallback); + } +} + + + + /** A callback that sets a flag to a specified value when the callback is called. */ diff --git a/sd/source/ui/func/fuarea.cxx b/sd/source/ui/func/fuarea.cxx index bf1727480388..a4a35c81364a 100644 --- a/sd/source/ui/func/fuarea.cxx +++ b/sd/source/ui/func/fuarea.cxx @@ -77,6 +77,8 @@ void FuArea::DoExecute( SfxRequest& rReq ) SID_ATTR_FILL_GRADIENT, SID_ATTR_FILL_HATCH, SID_ATTR_FILL_BITMAP, + SID_ATTR_FILL_TRANSPARENCE, + SID_ATTR_FILL_FLOATTRANSPARENCE, 0 }; mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray ); diff --git a/sd/source/ui/func/fuchar.cxx b/sd/source/ui/func/fuchar.cxx index c288767a55a6..0b2750e7eff7 100644 --- a/sd/source/ui/func/fuchar.cxx +++ b/sd/source/ui/func/fuchar.cxx @@ -18,7 +18,7 @@ */ #include "fuchar.hxx" - +#include <svx/dialogs.hrc> #include <sfx2/viewfrm.hxx> #include <editeng/editdata.hxx> @@ -74,6 +74,10 @@ void FuChar::DoExecute( SfxRequest& rReq ) SfxAbstractTabDialog* pDlg = pFact ? pFact->CreateSdTabCharDialog( NULL, &aNewAttr, mpDoc->GetDocSh() ) : 0; if( pDlg ) { + if (rReq.GetSlot() == SID_CHAR_DLG_EFFECT) + { + pDlg->SetCurPageId(RID_SVXPAGE_CHAR_EFFECTS); + } sal_uInt16 nResult = pDlg->Execute(); if( nResult == RET_OK ) @@ -97,9 +101,12 @@ void FuChar::DoExecute( SfxRequest& rReq ) SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, + SID_ATTR_CHAR_SHADOWED, + SID_ATTR_CHAR_STRIKEOUT, SID_ATTR_CHAR_UNDERLINE, SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_COLOR, + SID_ATTR_CHAR_KERNING, SID_SET_SUPER_SCRIPT, SID_SET_SUB_SCRIPT, 0 }; diff --git a/sd/source/ui/func/fuline.cxx b/sd/source/ui/func/fuline.cxx index 3e1d9d02ed7f..cd33f409ffa9 100644 --- a/sd/source/ui/func/fuline.cxx +++ b/sd/source/ui/func/fuline.cxx @@ -84,11 +84,16 @@ void FuLine::DoExecute( SfxRequest& rReq ) // some attributes are changed, we have to update the listboxes in the objectbars static sal_uInt16 SidArray[] = { - SID_ATTR_LINE_STYLE, - SID_ATTR_LINE_DASH, - SID_ATTR_LINE_WIDTH, - SID_ATTR_LINE_COLOR, - 0 }; + SID_ATTR_LINE_STYLE, // ( SID_SVX_START + 169 ) + SID_ATTR_LINE_DASH, // ( SID_SVX_START + 170 ) + SID_ATTR_LINE_WIDTH, // ( SID_SVX_START + 171 ) + SID_ATTR_LINE_COLOR, // ( SID_SVX_START + 172 ) + SID_ATTR_LINE_START, // ( SID_SVX_START + 173 ) + SID_ATTR_LINE_END, // ( SID_SVX_START + 174 ) + SID_ATTR_LINE_TRANSPARENCE, // (SID_SVX_START+1107) + SID_ATTR_LINE_JOINT, // (SID_SVX_START+1110) + SID_ATTR_LINE_CAP, // (SID_SVX_START+1111) + 0 }; mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray ); diff --git a/sd/source/ui/func/fuolbull.cxx b/sd/source/ui/func/fuolbull.cxx index ae290329fbff..c029edabac7a 100644 --- a/sd/source/ui/func/fuolbull.cxx +++ b/sd/source/ui/func/fuolbull.cxx @@ -23,6 +23,9 @@ #include <editeng/outliner.hxx> #include <editeng/eeitem.hxx> #include <sfx2/request.hxx> +#include <editeng/numitem.hxx> +#include "sdresid.hxx" +#include "glob.hrc" #include <editeng/editdata.hxx> #include <svx/svxids.hrc> @@ -32,7 +35,11 @@ #include "Window.hxx" #include "drawdoc.hxx" #include "sdabstdlg.hxx" - +#include <svx/nbdtmg.hxx> +#include <svx/nbdtmgfact.hxx> +#include <svx/svdoutl.hxx> +#include <boost/scoped_ptr.hpp> +using namespace svx::sidebar; namespace sd { TYPEINIT1( FuOutlineBullet, FuPoor ); @@ -54,6 +61,16 @@ FunctionReference FuOutlineBullet::Create( ViewShell* pViewSh, ::sd::Window* pWi void FuOutlineBullet::DoExecute( SfxRequest& rReq ) { + sal_uInt16 nSId = rReq.GetSlot(); + if (nSId == FN_SVX_SET_BULLET){ + SetCurrentBullet(rReq); + return; + } + else if (nSId == FN_SVX_SET_NUMBER){ + SetCurrentNumbering(rReq); + return; + } + const SfxItemSet* pArgs = rReq.GetArgs(); if( !pArgs ) @@ -81,9 +98,7 @@ void FuOutlineBullet::DoExecute( SfxRequest& rReq ) OutlinerView* pOLV = mpView->GetTextEditOutlinerView(); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - std::auto_ptr< OutlineViewModelChangeGuard > aGuard; - SAL_WNODEPRECATED_DECLARATIONS_POP + boost::scoped_ptr< OutlineViewModelChangeGuard > aGuard; if (mpView->ISA(OutlineView)) { @@ -122,7 +137,391 @@ void FuOutlineBullet::DoExecute( SfxRequest& rReq ) */ } +void FuOutlineBullet::SetCurrentNumbering(SfxRequest& rReq) +{ + if (!mpDoc || !mpView) + return; + + SfxItemSet aEditAttr( mpDoc->GetPool() ); + mpView->GetAttributes( aEditAttr ); + + SfxItemSet aNewAttr( mpViewShell->GetPool(), + EE_ITEMS_START, EE_ITEMS_END ); + aNewAttr.Put( aEditAttr, sal_False ); + + SfxItemSet aSetAttr( mpViewShell->GetPool(), + EE_ITEMS_START, EE_ITEMS_END ); + + //Init bullet level in "Customize" tab page in bullet dialog in master page view + if( mpView && mpViewShell && mpViewShell->ISA(DrawViewShell) + && ((DrawViewShell *)mpViewShell)->GetEditMode() == EM_MASTERPAGE ) + { + SdrObject* pObj = mpView->GetTextEditObject(); + if( pObj && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) + { + sal_uInt16 nLevel = mpView->GetSelectionLevel(); + if( nLevel != 0xFFFF ) + { + + SfxItemSet aStoreSet( aNewAttr ); + aNewAttr.ClearItem(); + //extend range + aNewAttr.MergeRange( SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL ); + aNewAttr.Put( aStoreSet ); + //put current level user selected + aNewAttr.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) ); + } + } + } + //End of add + + sal_uInt16 nActNumLvl = (sal_uInt16)0xFFFF; + SvxNumRule* pNumRule = NULL; + const SfxPoolItem* pTmpItem=NULL; + sal_uInt32 nNumItemId = SID_ATTR_NUMBERING_RULE; + + if(SFX_ITEM_SET == aNewAttr.GetItemState(SID_PARAM_CUR_NUM_LEVEL, sal_False, &pTmpItem)) + nActNumLvl = ((const SfxUInt16Item*)pTmpItem)->GetValue(); + + pTmpItem=GetNumBulletItem(aNewAttr, nNumItemId); + + if (pTmpItem) + pNumRule = new SvxNumRule(*((SvxNumBulletItem*)pTmpItem)->GetNumRule()); + + SFX_REQUEST_ARG( rReq, pItem, SfxUInt16Item, FN_SVX_SET_NUMBER , sal_False ); + if (pItem && pNumRule) + { + sal_uInt16 nIdx = pItem->GetValue(); + // If the nIdx is (sal_uInt16)0xFFFF, means set bullet status to on/off + // And the bullet default status is 1. + bool bBulletSwitch = false; + sal_Bool isRemoveNum =false; + if( nIdx == (sal_uInt16)0xFFFF ) + { + nIdx = 1; + bBulletSwitch = true; + } + if (nIdx == DEFAULT_NONE) + { + bBulletSwitch = false; + isRemoveNum = true; + } + nIdx--; + + NBOTypeMgrBase* pNumbering = NBOutlineTypeMgrFact::CreateInstance(eNBOType::NUMBERING); + if ( pNumbering ) + { + //Sym3_2508, set unit attribute to NB Manager + pNumbering->SetItems(&aNewAttr); + SvxNumRule aTmpRule( *pNumRule ); + pNumbering->ApplyNumRule(aTmpRule,nIdx,nActNumLvl); + sal_uInt16 nMask = 1; + for(sal_uInt16 i = 0; i < pNumRule->GetLevelCount(); i++) + { + if(nActNumLvl & nMask) + { + SvxNumberFormat aFmt(aTmpRule.GetLevel(i)); + pNumRule->SetLevel(i, aFmt); + } + nMask <<= 1 ; + } + aSetAttr.Put(SvxNumBulletItem( *pNumRule ), nNumItemId); + OutlinerView* pOLV = mpView->GetTextEditOutlinerView(); + + boost::scoped_ptr< OutlineViewModelChangeGuard > aGuard; + + if (mpView->ISA(OutlineView)) + { + pOLV = static_cast<OutlineView*>(mpView) + ->GetViewByWindow(mpViewShell->GetActiveWindow()); + + aGuard.reset( new OutlineViewModelChangeGuard( static_cast<OutlineView&>(*mpView) ) ); + } + + SdrOutliner* pOwner = mpView->GetTextEditOutliner(); + bool bMasterView = false; + + DrawViewShell* pDrawViewShell = static_cast< DrawViewShell* >(mpViewShell); + + if ( pOwner && pDrawViewShell && pDrawViewShell->GetEditMode() == EM_MASTERPAGE ) + bMasterView = !pOwner->IsInUndo() && pOwner->IsUndoEnabled(); + + if( bMasterView ) + { + pOwner->UndoActionStart( OLUNDO_ATTR ); + pOLV->ToggleBullets( bBulletSwitch, sal_False, bMasterView, pNumRule,isRemoveNum); + mpView->SetAttributes(aSetAttr); //Modify for Sym2_3151 + pOwner->UndoActionEnd( OLUNDO_ATTR ); + } + else if( pOLV ) + pOLV->ToggleBullets( bBulletSwitch, sal_False, bMasterView, pNumRule ,isRemoveNum); + else + { + sal_Bool bInMasterView = pDrawViewShell && pDrawViewShell->GetEditMode() == EM_MASTERPAGE; + SdrModel* pSdrModel = mpView->GetModel(); + sal_Bool bModelUndoEnabled = pSdrModel ? pSdrModel->IsUndoEnabled() : sal_False; + if (bInMasterView && bModelUndoEnabled) + { + pSdrModel->BegUndo(); + } + mpView->ToggleMarkedObjectsBullets(bBulletSwitch, sal_False, bInMasterView, pNumRule,isRemoveNum); + if (bInMasterView) + { + mpView->SetAttributes(aSetAttr); + } + if (bInMasterView && bModelUndoEnabled) + { + pSdrModel->EndUndo(); + } + } + } + //End + } + delete pNumRule; + rReq.Done(); +} + +void FuOutlineBullet::SetCurrentBullet(SfxRequest& rReq) +{ + if (!mpDoc || !mpView) + return; + + SfxItemSet aEditAttr( mpDoc->GetPool() ); + mpView->GetAttributes( aEditAttr ); + + SfxItemSet aNewAttr( mpViewShell->GetPool(), + EE_ITEMS_START, EE_ITEMS_END ); + aNewAttr.Put( aEditAttr, sal_False ); + + //Add for Sym2_3151, should add new attributes in an empty item set, then use this item set as parameter in SetAttributes() + SfxItemSet aSetAttr( mpViewShell->GetPool(), + EE_ITEMS_START, EE_ITEMS_END ); + + //Init bullet level in "Customize" tab page in bullet dialog in master page view + if( mpView && mpViewShell && mpViewShell->ISA(DrawViewShell) + && ((DrawViewShell *)mpViewShell)->GetEditMode() == EM_MASTERPAGE ) + { + SdrObject* pObj = mpView->GetTextEditObject(); + if( pObj && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) + { + sal_uInt16 nLevel = mpView->GetSelectionLevel(); + if( nLevel != 0xFFFF ) + { + //aNewAttr.MergeRange( SID_ATTR_NUMBERING_RULE, SID_PARAM_CUR_NUM_LEVEL ); + //aNewAttr.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) ); + //save the itemset value + SfxItemSet aStoreSet( aNewAttr ); + aNewAttr.ClearItem(); + //extend range + aNewAttr.MergeRange( SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL ); + aNewAttr.Put( aStoreSet ); + //put current level user selected + aNewAttr.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) ); + } + } + } + //End of add + + sal_uInt16 nActNumLvl = (sal_uInt16)0xFFFF; + SvxNumRule* pNumRule = NULL; + const SfxPoolItem* pTmpItem=NULL; + sal_uInt32 nNumItemId = SID_ATTR_NUMBERING_RULE; + + if(SFX_ITEM_SET == aNewAttr.GetItemState(SID_PARAM_CUR_NUM_LEVEL, sal_False, &pTmpItem)) + nActNumLvl = ((const SfxUInt16Item*)pTmpItem)->GetValue(); + + pTmpItem=GetNumBulletItem(aNewAttr, nNumItemId); + + if (pTmpItem) + pNumRule = new SvxNumRule(*((SvxNumBulletItem*)pTmpItem)->GetNumRule()); + + SFX_REQUEST_ARG( rReq, pItem, SfxUInt16Item, FN_SVX_SET_BULLET , sal_False ); + if (pItem && pNumRule) + { + sal_uInt16 nIdx = pItem->GetValue(); + // If the nIdx is (sal_uInt16)0xFFFF, means set bullet status to on/off + // And the bullet default status is 2. + bool bBulletSwitch = false; + sal_Bool isRemoveNum =false; + if( nIdx == (sal_uInt16)0xFFFF ) + { + nIdx = 1; + bBulletSwitch = true; + } + if (nIdx == DEFAULT_NONE) + { + bBulletSwitch = false; + isRemoveNum = true; + } + + nIdx--; + //Modified for Numbering&Bullets Dialog UX Enh(Story 992) by chengjh,2011.8.7 + + NBOTypeMgrBase* pBullets = NBOutlineTypeMgrFact::CreateInstance(eNBOType::MIXBULLETS); + if ( pBullets ) + { + //Sym3_2508, set unit attribute to NB Manager + pBullets->SetItems(&aNewAttr); + SvxNumRule aTmpRule( *pNumRule ); + //Sym3_3423 Always apply the "." if wants a default numbering rule + if (bBulletSwitch==true && nIdx==0) //want to reset bullet + { + pBullets->ApplyNumRule(aTmpRule,nIdx,nActNumLvl,true); + } + else { + pBullets->ApplyNumRule(aTmpRule,nIdx,nActNumLvl); + } + sal_uInt16 nMask = 1; + for(sal_uInt16 i = 0; i < pNumRule->GetLevelCount(); i++) + { + if(nActNumLvl & nMask) + { + SvxNumberFormat aFmt(aTmpRule.GetLevel(i)); + pNumRule->SetLevel(i, aFmt); + } + nMask <<= 1; + } + aSetAttr.Put(SvxNumBulletItem( *pNumRule ), nNumItemId); + + OutlinerView* pOLV = mpView->GetTextEditOutlinerView(); + + boost::scoped_ptr< OutlineViewModelChangeGuard > aGuard; + + if (mpView->ISA(OutlineView)) + { + pOLV = static_cast<OutlineView*>(mpView) + ->GetViewByWindow(mpViewShell->GetActiveWindow()); + + aGuard.reset( new OutlineViewModelChangeGuard( static_cast<OutlineView&>(*mpView) ) ); + } + + SdrOutliner* pOwner = mpView->GetTextEditOutliner(); + bool bMasterView = false; + + DrawViewShell* pDrawViewShell = static_cast< DrawViewShell* >(mpViewShell); + + if ( pOwner && pDrawViewShell && pDrawViewShell->GetEditMode() == EM_MASTERPAGE ) + bMasterView = !pOwner->IsInUndo() && pOwner->IsUndoEnabled(); + + if( bMasterView ) + { + pOwner->UndoActionStart( OLUNDO_ATTR ); + pOLV->ToggleBullets( bBulletSwitch, sal_True, bMasterView, pNumRule, isRemoveNum ); + mpView->SetAttributes(aSetAttr); //Modify for Sym2_3151 + pOwner->UndoActionEnd( OLUNDO_ATTR ); + } + else if( pOLV ) + pOLV->ToggleBullets( bBulletSwitch, sal_True, bMasterView, pNumRule, isRemoveNum ); + else + { + sal_Bool bInMasterView = pDrawViewShell && pDrawViewShell->GetEditMode() == EM_MASTERPAGE; + SdrModel* pSdrModel = mpView->GetModel(); + sal_Bool bModelUndoEnabled = pSdrModel ? pSdrModel->IsUndoEnabled() : sal_False; + if (bInMasterView && bModelUndoEnabled) + { + pSdrModel->BegUndo(); + } + mpView->ToggleMarkedObjectsBullets(bBulletSwitch, sal_True, bInMasterView, pNumRule, isRemoveNum ); + if (bInMasterView) + { + mpView->SetAttributes(aSetAttr); + } + if (bInMasterView && bModelUndoEnabled) + { + pSdrModel->EndUndo(); + } + } + } + //End + } + delete pNumRule; + rReq.Done(); +} + +const SfxPoolItem* FuOutlineBullet::GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt32& nNumItemId) +{ + //SvxNumBulletItem* pRetItem = NULL; + const SfxPoolItem* pTmpItem = NULL; + + if(aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem) == SFX_ITEM_SET) + { + return pTmpItem; + } + else + { + nNumItemId = aNewAttr.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); + SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem); + if (eState == SFX_ITEM_SET) + return pTmpItem; + else + { + sal_Bool bOutliner = sal_False; + sal_Bool bTitle = sal_False; + + if( mpView ) + { + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + const sal_uInt32 nCount = rMarkList.GetMarkCount(); + + for(sal_uInt32 nNum = 0; nNum < nCount; nNum++) + { + SdrObject* pObj = rMarkList.GetMark(nNum)->GetMarkedSdrObj(); + if( pObj->GetObjInventor() == SdrInventor ) + { + switch(pObj->GetObjIdentifier()) + { + case OBJ_TITLETEXT: + bTitle = sal_True; + break; + case OBJ_OUTLINETEXT: + bOutliner = sal_True; + break; + } + } + } + } + + const SvxNumBulletItem *pItem = NULL; + if(bOutliner) + { + SfxStyleSheetBasePool* pSSPool = mpView->GetDocSh()->GetStyleSheetPool(); + String aStyleName((SdResId((sal_uInt16)STR_LAYOUT_OUTLINE))); + aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) ); + SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SD_STYLE_FAMILY_PSEUDO); + if( pFirstStyleSheet ) + pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, sal_False, (const SfxPoolItem**)&pItem); + } + + if( pItem == NULL ) + pItem = (SvxNumBulletItem*) aNewAttr.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET); + + //DBG_ASSERT( pItem, "Kein EE_PARA_NUMBULLET im Pool! [CL]" ); + + aNewAttr.Put(*pItem, EE_PARA_NUMBULLET); + + if(bTitle && aNewAttr.GetItemState(EE_PARA_NUMBULLET,sal_True) == SFX_ITEM_ON ) + { + SvxNumBulletItem* pBulletItem = (SvxNumBulletItem*)aNewAttr.GetItem(EE_PARA_NUMBULLET,sal_True); + SvxNumRule* pLclRule = pBulletItem->GetNumRule(); + if(pLclRule) + { + SvxNumRule aNewRule( *pLclRule ); + aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, sal_True ); + + SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET ); + aNewAttr.Put(aNewItem); + } + } + SfxItemState eItemState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem); + if (eItemState == SFX_ITEM_SET) + return pTmpItem; + + } + //DBG_ASSERT(eState == SFX_ITEM_SET, "kein Item gefunden!") + } + return pTmpItem; +} } // end of namespace sd diff --git a/sd/source/ui/func/fuoltext.cxx b/sd/source/ui/func/fuoltext.cxx index 250319e63e88..c1f259f4bfc4 100644 --- a/sd/source/ui/func/fuoltext.cxx +++ b/sd/source/ui/func/fuoltext.cxx @@ -51,9 +51,12 @@ static sal_uInt16 SidArray[] = { SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, + SID_ATTR_CHAR_SHADOWED, + SID_ATTR_CHAR_STRIKEOUT, SID_ATTR_CHAR_UNDERLINE, SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_COLOR, + SID_ATTR_CHAR_KERNING, SID_OUTLINE_UP, SID_OUTLINE_DOWN, SID_OUTLINE_LEFT, diff --git a/sd/source/ui/func/fuparagr.cxx b/sd/source/ui/func/fuparagr.cxx index 0c903f2e1f2f..7a0056a5ca06 100644 --- a/sd/source/ui/func/fuparagr.cxx +++ b/sd/source/ui/func/fuparagr.cxx @@ -138,6 +138,8 @@ void FuParagraph::DoExecute( SfxRequest& rReq ) // invalidate slots static sal_uInt16 SidArray[] = { SID_ATTR_TABSTOP, + SID_ATTR_PARA_LINESPACE, + SID_ATTR_PARA_ULSPACE, SID_ATTR_PARA_ADJUST_LEFT, SID_ATTR_PARA_ADJUST_RIGHT, SID_ATTR_PARA_ADJUST_CENTER, diff --git a/sd/source/ui/func/futext.cxx b/sd/source/ui/func/futext.cxx index a6c04a596925..6784daa67140 100644 --- a/sd/source/ui/func/futext.cxx +++ b/sd/source/ui/func/futext.cxx @@ -85,9 +85,12 @@ static sal_uInt16 SidArray[] = { SID_ATTR_CHAR_FONT, // 10007 SID_ATTR_CHAR_POSTURE, // 10008 SID_ATTR_CHAR_WEIGHT, // 10009 + SID_ATTR_CHAR_SHADOWED, //10010 + SID_ATTR_CHAR_STRIKEOUT, //10013 SID_ATTR_CHAR_UNDERLINE, // 10014 SID_ATTR_CHAR_FONTHEIGHT, // 10015 SID_ATTR_CHAR_COLOR, // 10017 + SID_ATTR_CHAR_KERNING, //10018 SID_ATTR_PARA_ADJUST_LEFT, // 10028 SID_ATTR_PARA_ADJUST_RIGHT, // 10029 SID_ATTR_PARA_ADJUST_CENTER, // 10030 @@ -95,14 +98,26 @@ static sal_uInt16 SidArray[] = { SID_ATTR_PARA_LINESPACE_10, // 10034 SID_ATTR_PARA_LINESPACE_15, // 10035 SID_ATTR_PARA_LINESPACE_20, // 10036 + SID_ATTR_PARA_ULSPACE, // 10042 SID_ATTR_PARA_LRSPACE, // 10043 + SID_ATTR_TRANSFORM_POS_X, // 10088 + SID_ATTR_TRANSFORM_POS_Y, // 10089 + SID_ATTR_TRANSFORM_WIDTH, // 10090 + SID_ATTR_TRANSFORM_HEIGHT,// 10091 + SID_ATTR_TRANSFORM_ROT_X, // 10093 + SID_ATTR_TRANSFORM_ROT_Y, // 10094 + SID_ATTR_TRANSFORM_ANGLE, // 10095 //Added SID_OUTLINE_UP, // 10150 SID_OUTLINE_DOWN, // 10151 SID_OUTLINE_LEFT, // 10152 SID_OUTLINE_RIGHT, // 10153 + SID_ATTR_TRANSFORM_PROTECT_POS,// 10236 + SID_ATTR_TRANSFORM_PROTECT_SIZE,// 10237 //Added SID_FORMTEXT_STYLE, // 10257 SID_SET_SUPER_SCRIPT, // 10294 SID_SET_SUB_SCRIPT, // 10295 + SID_ATTR_TRANSFORM_AUTOWIDTH,// 10310 + SID_ATTR_TRANSFORM_AUTOHEIGHT,// 10311 //Added SID_HYPERLINK_GETLINK, // 10361 SID_CHARMAP, // 10503 SID_TEXTDIRECTION_LEFT_TO_RIGHT, // 10907 @@ -1089,7 +1104,8 @@ void FuText::SetInEditMode(const MouseEvent& rMEvt, sal_Bool bQuickDrag) { // Move cursor to end of text ESelection aNewSelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND); - pOLV->SetSelection(aNewSelection); + if (pOLV != NULL) + pOLV->SetSelection(aNewSelection); } } else diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx index 9fd205ff8516..6d91b187e81f 100644 --- a/sd/source/ui/inc/DrawViewShell.hxx +++ b/sd/source/ui/inc/DrawViewShell.hxx @@ -24,8 +24,10 @@ #include "tools/AsynchronousCall.hxx" #include <sfx2/viewfac.hxx> #include <sfx2/viewsh.hxx> +#include <sfx2/sidebar/EnumContext.hxx> #include "TabControl.hxx" #include "pres.hxx" +#include <svx/sidebar/SelectionChangeHandler.hxx> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/scanner/XScannerManager2.hpp> #include <unotools/caserotate.hxx> @@ -158,6 +160,7 @@ public: void ExecCtrl(SfxRequest& rReq); void GetCtrlState(SfxItemSet& rSet); + void GetDrawAttrState(SfxItemSet& rSet); void GetMenuState(SfxItemSet& rSet); void GetTableMenuState(SfxItemSet& rSet); /** Set the items of the given item set that are related to @@ -190,6 +193,9 @@ public: void ExecNavigatorWin(SfxRequest& rReq); void GetNavigatorWinState(SfxItemSet& rSet); + void ExecutePropPanelAttr (SfxRequest& rReq); + void GetStatePropPanelAttr(SfxItemSet& rSet); + void ExecEffectWin(SfxRequest& rReq); void Update3DWindow(); @@ -213,6 +219,8 @@ public: void AttrExec (SfxRequest& rReq); void AttrState (SfxItemSet& rSet); + void ExecChar(SfxRequest& rReq); + void ExecuteAnnotation (SfxRequest& rRequest); void GetAnnotationState (SfxItemSet& rItemSet); @@ -422,6 +430,10 @@ private: RotateTransliteration m_aRotateCase; + /** Listen for selection changes and broadcast context changes for the sidebar. + */ + ::rtl::Reference<svx::sidebar::SelectionChangeHandler> mpSelectionChangeHandler; + void Construct (DrawDocShell* pDocSh, PageKind ePageKind); /** Depending on the given request create a new page or duplicate an @@ -475,6 +487,8 @@ private: const sal_uInt16 nSnapLineIndex, const Point& rMouseLocation); + ::sfx2::sidebar::EnumContext::Context GetContextForSelection (void) const; + using ViewShell::Notify; ::std::auto_ptr< AnnotationManager > mpAnnotationManager; diff --git a/sd/source/ui/inc/PaneChildWindows.hxx b/sd/source/ui/inc/PaneChildWindows.hxx index 9c1c04e63c7d..6da8cf18412f 100644 --- a/sd/source/ui/inc/PaneChildWindows.hxx +++ b/sd/source/ui/inc/PaneChildWindows.hxx @@ -65,28 +65,6 @@ public: }; - - -//====================================================================================================================== -//= ToolPanelChildWindow -//====================================================================================================================== -class ToolPanelChildWindow :public PaneChildWindow - ,public ::sfx2::ITaskPaneToolPanelAccess -{ -public: - ToolPanelChildWindow( - ::Window* i_pParentWindow, - sal_uInt16 i_nId, - SfxBindings* i_pBindings, - SfxChildWinInfo* i_pChildWindowInfo ); - - SFX_DECL_CHILDWINDOW_WITHID( ToolPanelChildWindow ); - - // ::sfx2::ITaskPaneToolPanelAccess - virtual void ActivateToolPanel( const OUString& i_rPanelURL ); -}; - - } // end of namespace ::sd #endif diff --git a/sd/source/ui/inc/SidebarPanelId.hxx b/sd/source/ui/inc/SidebarPanelId.hxx new file mode 100644 index 000000000000..f315914aeeb5 --- /dev/null +++ b/sd/source/ui/inc/SidebarPanelId.hxx @@ -0,0 +1,49 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_PANEL_ID_HXX +#define SD_SIDEBAR_PANEL_ID_HXX + +namespace rtl +{ + class OUString; +} + + +namespace sd { namespace sidebar { + +/** List of top level panels that can be shown in the task pane. +*/ +enum PanelId +{ + PID__START = 0, + PID_UNKNOWN = PID__START, + PID_MASTER_PAGES_ALL, + PID_MASTER_PAGES_RECENT, + PID_MASTER_PAGES_USED, + PID_LAYOUT, + PID_TABLE_DESIGN, + PID_ANIMATION_SCHEMES, + PID_CUSTOM_ANIMATION, + PID_SLIDE_TRANSITION, + PID__END = PID_SLIDE_TRANSITION +}; + +} } // namespace sd::sidebar + + +#endif diff --git a/sd/source/ui/inc/SlideSorterViewShell.hxx b/sd/source/ui/inc/SlideSorterViewShell.hxx index 4f72343f430f..32c3cc068d31 100644 --- a/sd/source/ui/inc/SlideSorterViewShell.hxx +++ b/sd/source/ui/inc/SlideSorterViewShell.hxx @@ -111,6 +111,7 @@ public: virtual void ArrangeGUIElements (void); virtual void Activate (sal_Bool IsMDIActivate); + virtual void Deactivate (sal_Bool IsMDIActivate); //===== Drag and Drop ===================================================== diff --git a/sd/source/ui/inc/TextObjectBar.hxx b/sd/source/ui/inc/TextObjectBar.hxx index c7421dd30c56..0b11a14b04df 100644 --- a/sd/source/ui/inc/TextObjectBar.hxx +++ b/sd/source/ui/inc/TextObjectBar.hxx @@ -46,6 +46,7 @@ public: virtual ~TextObjectBar (void); void GetAttrState( SfxItemSet& rSet ); + void GetCharState( SfxItemSet& rSet ); void Execute( SfxRequest &rReq ); virtual void Command( const CommandEvent& rCEvt ); diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx index 3dee2a95a310..6fc9dd178e09 100644 --- a/sd/source/ui/inc/View.hxx +++ b/sd/source/ui/inc/View.hxx @@ -31,6 +31,7 @@ #include "fupoor.hxx" #include "smarttag.hxx" +#include <editeng/numitem.hxx> class SdDrawDocument; class SdPage; @@ -193,6 +194,8 @@ public: virtual void CheckPossibilities(); virtual sal_Bool MarkPoints(const ::Rectangle* pRect, sal_Bool bUnmark); using SdrMarkView::MarkPoints; + sal_Bool ShouldToggleOn(sal_Bool bBulletOnOffMode, sal_Bool bNormalBullet); + void ToggleMarkedObjectsBullets(sal_Bool bBulletOnOffMode, sal_Bool bNormalBullet, sal_Bool bMasterView, SvxNumRule* pNumRule = NULL, sal_Bool bForceBulletOnOff = false); void SetPossibilitiesDirty() { bPossibilitiesDirty = true; } void SetMoveAllowed( bool bSet ) { bMoveAllowed = bSet; } diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 125229bcb9f2..94f5d7238a31 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -93,7 +93,8 @@ public: ST_OUTLINE, ST_SLIDE_SORTER, ST_PRESENTATION, - ST_TASK_PANE + ST_TASK_PANE, + ST_SIDEBAR }; static const int MAX_HSPLIT_CNT = 1; static const int MAX_VSPLIT_CNT = 1; @@ -194,6 +195,8 @@ public: virtual void SetUIUnit(FieldUnit eUnit); virtual void SetDefTabHRuler( sal_uInt16 nDefTab ); + const SfxPoolItem* GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt16& nNumItemId); + sal_Bool HasRuler (void); void SetRuler(sal_Bool bRuler); diff --git a/sd/source/ui/inc/framework/FrameworkHelper.hxx b/sd/source/ui/inc/framework/FrameworkHelper.hxx index 1b81f6870a74..4aac1861bd5d 100644 --- a/sd/source/ui/inc/framework/FrameworkHelper.hxx +++ b/sd/source/ui/inc/framework/FrameworkHelper.hxx @@ -39,6 +39,9 @@ class ViewShell; class ViewShellBase; } +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; +namespace cssdf = ::com::sun::star::drawing::framework; namespace sd { namespace framework { @@ -47,10 +50,10 @@ namespace sd { namespace framework { It has three main tasks: 1. Provide frequently used strings of resource URLs and event names. 2. Provide shortcuts for accessing the sd framework. - 3. Easy the migration to the drawing framwork. + 3. Ease the migration to the drawing framwork. Note that a FrameworkHelper disposes itself when one of the resource - controllers called by it throw a DisposedException. + controllers called by it throws a DisposedException. */ class FrameworkHelper : public ::boost::enable_shared_from_this<FrameworkHelper>, @@ -63,7 +66,7 @@ public: static const OUString msFullScreenPaneURL; static const OUString msLeftImpressPaneURL; static const OUString msLeftDrawPaneURL; - static const OUString msRightPaneURL; + static const OUString msSidebarPaneURL; // URLs of frequently used views. static const OUString msViewURLPrefix; @@ -74,7 +77,7 @@ public: static const OUString msHandoutViewURL; static const OUString msSlideSorterURL; static const OUString msPresentationViewURL; - static const OUString msTaskPaneURL; + static const OUString msSidebarViewURL; // URLs of frequently used tool bars. static const OUString msToolBarURLPrefix; @@ -82,7 +85,9 @@ public: // URLs of task panels. static const OUString msTaskPanelURLPrefix; - static const OUString msMasterPagesTaskPanelURL; + static const OUString msAllMasterPagesTaskPanelURL; + static const OUString msRecentMasterPagesTaskPanelURL; + static const OUString msUsedMasterPagesTaskPanelURL; static const OUString msLayoutTaskPanelURL; static const OUString msTableDesignPanelURL; static const OUString msCustomAnimationTaskPanelURL; @@ -93,6 +98,7 @@ public: static const OUString msResourceDeactivationRequestEvent; static const OUString msResourceActivationEvent; static const OUString msResourceDeactivationEvent; + static const OUString msResourceDeactivationEndEvent; static const OUString msConfigurationUpdateStartEvent; static const OUString msConfigurationUpdateEndEvent; @@ -107,7 +113,7 @@ public: static ::boost::shared_ptr<FrameworkHelper> Instance (ViewShellBase& rBase); static ::boost::shared_ptr<FrameworkHelper> Instance ( - const css::uno::Reference<css::frame::XController>& rxController); + const cssu::Reference<css::frame::XController>& rxController); /** Mark the FrameworkHelper object for the given ViewShellBase as disposed. A following ReleaseInstance() call will destroy the @@ -144,17 +150,15 @@ public: reference then an empty pointer is returned. */ static ::boost::shared_ptr<ViewShell> GetViewShell ( - const css::uno::Reference<css::drawing::framework::XView>& rxView); + const cssu::Reference<cssdf::XView>& rxView); - ~FrameworkHelper (void); - - typedef ::boost::function<bool(const css::drawing::framework::ConfigurationChangeEvent&)> + typedef ::boost::function<bool(const cssdf::ConfigurationChangeEvent&)> ConfigurationChangeEventFilter; typedef ::boost::function<void(bool bEventSeen)> Callback; typedef ::boost::function< void( - const css::uno::Reference< - css::drawing::framework::XResourceId>&) + const cssu::Reference< + cssdf::XResourceId>&) > ResourceFunctor; /** Test whether the called FrameworkHelper object is valid. @@ -187,10 +191,19 @@ public: of the involved objects does not support XTunnel (where necessary). */ - css::uno::Reference<css::drawing::framework::XView> - GetView ( - const css::uno::Reference< - css::drawing::framework::XResourceId>& rxPaneOrViewId); + cssu::Reference<cssdf::XView> GetView ( + const cssu::Reference<cssdf::XResourceId>& rxPaneOrViewId); + + /** Return the XWindow that is represented by the pane with the + given resource id. + */ + cssu::Reference<css::awt::XWindow> GetPaneWindow ( + const cssu::Reference<cssdf::XResourceId>& rxPaneId); + + /** Return the XResource object with the given resource id. + */ + cssu::Reference<cssdf::XResource> GetResource ( + const cssu::Reference<cssdf::XResourceId>& rxResourceId); /** Request the specified view to be displayed in the specified pane. When the pane is not visible its creation is also requested. The @@ -204,25 +217,34 @@ public: the caller can, for example, call RunOnResourceActivation() to do some initialization after the requested view becomes active. */ - css::uno::Reference<css::drawing::framework::XResourceId> RequestView ( + cssu::Reference<cssdf::XResourceId> RequestView ( const OUString& rsResourceURL, const OUString& rsAnchorURL); - /** Request the activation of the specified task panel in the standard - task pane. - @param rsTaskPanelURL + /** Request the activation of the specified panel in the + sidebar. + @param rsSidebarPanelURL The panel that is to be activated. - @param bEnsureTaskPaneIsVisible - When this is <TRUE/> then the task pane is activated when not + @param bEnsurePaneIsVisible + When this is <TRUE/> then the sidebar pane is activated when not yet active. When this flag is <FALSE/> then the requested panel is activated only when the task pane is already active. When it is not active then this call is silently ignored. + @return + The resource id of the requested sidebar panel is returned. With that + the caller can, for example, call RunOnResourceActivation() to + do some initialization after the requested view becomes active. */ - void RequestTaskPanel ( - const OUString& rsTaskPanelURL, + cssu::Reference<cssdf::XResourceId> RequestSidebarPanel ( + const OUString& rsSidebarPanelURL, const bool bEnsureTaskPaneIsVisible = true); + /** Request the deactivation of the specified resource. + */ + void RequestResourceDeactivation ( + const cssu::Reference<cssdf::XResourceId>& rxResourceId); + /** Process a slot call that requests a view shell change. */ void HandleModeChangeSlot ( @@ -251,9 +273,30 @@ public: */ void RunOnResourceActivation( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, + const cssu::Reference<cssdf::XResourceId>& rxResourceId, const Callback& rCallback); + /** Run the given callback when the specified resource has been + deactivated. When the resource is not active already when + this method is called then rCallback is called before this + method returns. + @param rxResourceId + Wait for the deactivation of this resource before calling + rCallback. + @param rCallback + The callback to be called when the resource is + deactivated. + @param bRunOnDeactivationEnd + The callback is run either when the deactivation starts + and the callback can still access the resource or when the + deactivatio is complete and the resource is no longer available. + + */ + void RunOnResourceDeactivation( + const cssu::Reference<cssdf::XResourceId>& rxResourceId, + const Callback& rCallback, + const bool bRunOnDeactivationEnd); + /** Normally the requested changes of the configuration are executed asynchronously. However, there is at least one situation (searching with the Outliner) where the surrounding code does not cope with @@ -287,21 +330,21 @@ public: /** Return a string representation of the given XResourceId object. */ static OUString ResourceIdToString ( - const css::uno::Reference< - css::drawing::framework::XResourceId>& rxResourceId); + const cssu::Reference< + cssdf::XResourceId>& rxResourceId); /** Create a new XResourceId object for the given resource URL. */ - static css::uno::Reference< - css::drawing::framework::XResourceId> + static cssu::Reference< + cssdf::XResourceId> CreateResourceId ( const OUString& rsResourceURL); /** Create a new XResourceId object for the given resource URL and a single anchor URL. */ - static css::uno::Reference< - css::drawing::framework::XResourceId> + static cssu::Reference< + cssdf::XResourceId> CreateResourceId ( const OUString& rsResourceURL, const OUString& rsAnchorURL); @@ -309,8 +352,8 @@ public: /** Create a new XResourceId object for the given resource URL and the two given anchor URLs. */ - static css::uno::Reference< - css::drawing::framework::XResourceId> + static cssu::Reference< + cssdf::XResourceId> CreateResourceId ( const OUString& rsResourceURL, const OUString& rsFirstAnchorURL, @@ -318,14 +361,14 @@ public: /** Create a new XResourceId object for the given resource URL. */ - static css::uno::Reference< - css::drawing::framework::XResourceId> + static cssu::Reference< + cssdf::XResourceId> CreateResourceId ( const OUString& rsResourceURL, - const css::uno::Reference< - css::drawing::framework::XResourceId>& rxAnchor); + const cssu::Reference< + cssdf::XResourceId>& rxAnchor); - css::uno::Reference<css::drawing::framework::XConfigurationController> + cssu::Reference<cssdf::XConfigurationController> GetConfigurationController (void) const; @@ -341,16 +384,18 @@ private: static ::boost::scoped_ptr<ViewURLMap> mpViewURLMap; ViewShellBase& mrBase; - css::uno::Reference<css::drawing::framework::XConfigurationController> + cssu::Reference<cssdf::XConfigurationController> mxConfigurationController; class DisposeListener; friend class DisposeListener; - css::uno::Reference<css::lang::XComponent> + cssu::Reference<css::lang::XComponent> mxDisposeListener; FrameworkHelper (ViewShellBase& rBase); FrameworkHelper (const FrameworkHelper& rHelper); // Not implemented. + ~FrameworkHelper (void); + class Deleter; friend class Deleter; FrameworkHelper& operator= (const FrameworkHelper& rHelper); // Not implemented. void Initialize (void); @@ -390,7 +435,7 @@ namespace { class FrameworkHelperAllPassFilter { public: - bool operator() (const css::drawing::framework::ConfigurationChangeEvent&) { return true; } + bool operator() (const cssdf::ConfigurationChangeEvent&) { return true; } }; @@ -398,12 +443,12 @@ namespace { { public: FrameworkHelperResourceIdFilter ( - const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId); - bool operator() (const css::drawing::framework::ConfigurationChangeEvent& rEvent) + const cssu::Reference<cssdf::XResourceId>& rxResourceId); + bool operator() (const cssdf::ConfigurationChangeEvent& rEvent) { return mxResourceId.is() && rEvent.ResourceId.is() && mxResourceId->compareTo(rEvent.ResourceId) == 0; } private: - css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId; + cssu::Reference<cssdf::XResourceId> mxResourceId; }; } // end of anonymous namespace diff --git a/sd/source/ui/inc/framework/Pane.hxx b/sd/source/ui/inc/framework/Pane.hxx index 49a99ce1e38d..de6e36015e26 100644 --- a/sd/source/ui/inc/framework/Pane.hxx +++ b/sd/source/ui/inc/framework/Pane.hxx @@ -88,6 +88,7 @@ public: */ virtual ::Window* GetWindow (void); + void SetWindow (::Window* pWindow); //----- XPane ------------------------------------------------------------- diff --git a/sd/source/ui/inc/framework/TaskPanelResource.hxx b/sd/source/ui/inc/framework/TaskPanelResource.hxx new file mode 100644 index 000000000000..36eecf6b1c9b --- /dev/null +++ b/sd/source/ui/inc/framework/TaskPanelResource.hxx @@ -0,0 +1,81 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#include <cppuhelper/compbase1.hxx> +#include <cppuhelper/basemutex.hxx> + +#include "SidebarPanelId.hxx" + +#include <com/sun/star/drawing/framework/XResource.hpp> +#include <boost/scoped_ptr.hpp> + + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; +namespace cssdf = ::com::sun::star::drawing::framework; + +class Window; + +namespace sd { namespace sidebar { + class SidebarViewShell; +} } + + +namespace sd { namespace framework { + +typedef ::cppu::WeakComponentImplHelper1 < + cssdf::XResource + > TaskPanelResourceInterfaceBase; + + +/** A simple wrapper around a legacy task pane control that gives + access to that control (via GetControl()). +*/ +class TaskPanelResource + : private ::cppu::BaseMutex, + public TaskPanelResourceInterfaceBase +{ +public: + /** Create a resource object that represents the legacy taskpane + panel. + @param rxResourceId + drawing framework resource id + @param pControl + The new TaskPanelResource object takes ownership for this control. + */ + TaskPanelResource ( + sidebar::SidebarViewShell& rSidebarViewShell, + sidebar::PanelId ePanelId, + const cssu::Reference<cssdf::XResourceId>& rxResourceId); + virtual ~TaskPanelResource (void); + virtual void SAL_CALL disposing (void); + + // XResource + virtual cssu::Reference<cssdf::XResourceId> SAL_CALL getResourceId (void) throw (cssu::RuntimeException); + virtual sal_Bool SAL_CALL isAnchorOnly () throw (cssu::RuntimeException); + + ::Window* GetControl (void) const; + +private: + const cssu::Reference<cssdf::XResourceId> mxResourceId; + // Using auto_ptr because it has release(), what scoped_ptr doesn't. + ::std::auto_ptr< ::Window> mpControl; + + DECL_LINK(WindowEventHandler,VclWindowEvent*); +}; + +} } // end of namespace sd::framework diff --git a/sd/source/ui/inc/fuolbull.hxx b/sd/source/ui/inc/fuolbull.hxx index 797c4da40b1a..995cda6b9e86 100644 --- a/sd/source/ui/inc/fuolbull.hxx +++ b/sd/source/ui/inc/fuolbull.hxx @@ -24,6 +24,8 @@ class SdDrawDocument; class SfxRequest; +class SfxItemSet; +class SfxPoolItem; namespace sd { @@ -42,6 +44,8 @@ public: static FunctionReference Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ); virtual void DoExecute( SfxRequest& rReq ); + void SetCurrentBullet(SfxRequest& rReq); + void SetCurrentNumbering(SfxRequest& rReq); private: FuOutlineBullet ( @@ -50,8 +54,11 @@ private: ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq); + + const SfxPoolItem* GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt32& nNumItemId); }; + } // end of namespace sd #endif diff --git a/sd/source/ui/inc/navigatr.hxx b/sd/source/ui/inc/navigatr.hxx index ca6bdf418b8d..4c5b8250bf46 100644 --- a/sd/source/ui/inc/navigatr.hxx +++ b/sd/source/ui/inc/navigatr.hxx @@ -81,11 +81,21 @@ class SdNavigatorWin : public Window { public: + typedef ::boost::function<void(void)> UpdateRequestFunctor; + + /** Create a new instance of the navigator. + @param bUseActiveUpdate + When <TRUE/>, the default, then the SdNavigatorWin object + will make a SID_NAVIGATOR_INIT call whenever it thinks an + update is necessary. When <FALSE/> the navigator will + rely on others to trigger updates. + */ SdNavigatorWin( ::Window* pParent, ::sd::NavigatorChildWindow* pChildWinContext, const SdResId& rSdResId, - SfxBindings* pBindings ); + SfxBindings* pBindings, + const UpdateRequestFunctor& rUpdateRequest); virtual ~SdNavigatorWin(); virtual void KeyInput( const KeyEvent& rKEvt ); @@ -128,7 +138,7 @@ private: /** This flag controls whether all shapes or only the named shapes are shown. */ - bool mbShowAllShapes; + // bool mbShowAllShapes; sal_uInt16 GetDragTypeSdResId( NavigatorDragType eDT, sal_Bool bImage = sal_False ); NavDocInfo* GetDocInfo(); @@ -157,7 +167,8 @@ private: class SdNavigatorControllerItem : public SfxControllerItem { public: - SdNavigatorControllerItem( sal_uInt16, SdNavigatorWin*, SfxBindings* ); + SdNavigatorControllerItem( sal_uInt16, SdNavigatorWin*, SfxBindings*, + const SdNavigatorWin::UpdateRequestFunctor& rUpdateRequest); protected: virtual void StateChanged( sal_uInt16 nSId, SfxItemState eState, @@ -165,6 +176,7 @@ protected: private: SdNavigatorWin* pNavigatorWin; + const SdNavigatorWin::UpdateRequestFunctor maUpdateRequest; }; @@ -175,7 +187,8 @@ private: class SdPageNameControllerItem : public SfxControllerItem { public: - SdPageNameControllerItem( sal_uInt16, SdNavigatorWin*, SfxBindings* ); + SdPageNameControllerItem( sal_uInt16, SdNavigatorWin*, SfxBindings*, + const SdNavigatorWin::UpdateRequestFunctor& rUpdateRequest); protected: virtual void StateChanged( sal_uInt16 nSId, SfxItemState eState, @@ -183,6 +196,7 @@ protected: private: SdNavigatorWin* pNavigatorWin; + const SdNavigatorWin::UpdateRequestFunctor maUpdateRequest; }; #endif diff --git a/sd/source/ui/presenter/PresenterHelper.hxx b/sd/source/ui/presenter/PresenterHelper.hxx index 053b1e69d136..c9173b249627 100644 --- a/sd/source/ui/presenter/PresenterHelper.hxx +++ b/sd/source/ui/presenter/PresenterHelper.hxx @@ -39,7 +39,7 @@ namespace { /** Implementation of the XPresenterHelper interface: functionality that can not be implemented in an extension. */ - class PresenterHelper +class PresenterHelper : private ::boost::noncopyable, private ::cppu::BaseMutex, public PresenterHelperInterfaceBase diff --git a/sd/source/ui/sidebar/AllMasterPagesSelector.cxx b/sd/source/ui/sidebar/AllMasterPagesSelector.cxx new file mode 100644 index 000000000000..6e83aa23768b --- /dev/null +++ b/sd/source/ui/sidebar/AllMasterPagesSelector.cxx @@ -0,0 +1,229 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "AllMasterPagesSelector.hxx" +#include "PreviewValueSet.hxx" +#include "ViewShellBase.hxx" +#include "SidebarShellManager.hxx" +#include "MasterPageContainer.hxx" +#include "MasterPageDescriptor.hxx" +#include "app.hrc" +#include "helpids.h" + +#include <tools/link.hxx> +#include <set> + +namespace { + +using namespace sd::sidebar; + +int GetURLPriority (const SharedMasterPageDescriptor& rpDescriptor) +{ + int nPriority (0); + switch (rpDescriptor->GetURLClassification()) + { + case MasterPageDescriptor::URLCLASS_USER: nPriority = 0; break; + case MasterPageDescriptor::URLCLASS_LAYOUT: nPriority = 1; break; + case MasterPageDescriptor::URLCLASS_PRESENTATION: nPriority = 2; break; + case MasterPageDescriptor::URLCLASS_OTHER: nPriority = 3; break; + case MasterPageDescriptor::URLCLASS_UNKNOWN: nPriority = 4; break; + default: + case MasterPageDescriptor::URLCLASS_UNDETERMINED: nPriority = 5; break; + } + return nPriority; +} + + +class MasterPageDescriptorOrder +{ +public: + bool operator() ( + const SharedMasterPageDescriptor& rp1, + const SharedMasterPageDescriptor& rp2) + { + if (rp1->meOrigin == MasterPageContainer::DEFAULT) + return true; + else if (rp2->meOrigin == MasterPageContainer::DEFAULT) + return false; + else if (rp1->GetURLClassification() == rp2->GetURLClassification()) + return rp1->mnTemplateIndex < rp2->mnTemplateIndex; + else + return GetURLPriority(rp1) < GetURLPriority(rp2); + } +}; + +} // end of anonymous namespace + + + +namespace sd { namespace sidebar { + +class AllMasterPagesSelector::SortedMasterPageDescriptorList + : public ::std::set<SharedMasterPageDescriptor,MasterPageDescriptorOrder> +{ +public: + SortedMasterPageDescriptorList (void) {} +}; + + + + +MasterPagesSelector* AllMasterPagesSelector::Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) +{ + SdDrawDocument* pDocument = rViewShellBase.GetDocument(); + if (pDocument == NULL) + return NULL; + + ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer()); + + MasterPagesSelector* pSelector( + new AllMasterPagesSelector ( + pParent, + *pDocument, + rViewShellBase, + pContainer, + rxSidebar)); + pSelector->LateInit(); + pSelector->SetHelpId(HID_SD_TASK_PANE_PREVIEW_ALL); + + return pSelector; +} + + + + +AllMasterPagesSelector::AllMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) + : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar), + mpSortedMasterPages(new SortedMasterPageDescriptorList()) +{ + MasterPagesSelector::Fill(); +} + + + + +AllMasterPagesSelector::~AllMasterPagesSelector (void) +{ +} + + + + +void AllMasterPagesSelector::Fill (ItemList& rItemList) +{ + if (mpSortedMasterPages->empty()) + UpdateMasterPageList(); + UpdatePageSet(rItemList); +} + + + + +void AllMasterPagesSelector::NotifyContainerChangeEvent ( + const MasterPageContainerChangeEvent& rEvent) +{ + switch (rEvent.meEventType) + { + case MasterPageContainerChangeEvent::CHILD_ADDED: + AddItem(rEvent.maChildToken); + MasterPagesSelector::Fill(); + break; + + case MasterPageContainerChangeEvent::INDEX_CHANGED: + case MasterPageContainerChangeEvent::INDEXES_CHANGED: + mpSortedMasterPages->clear(); + MasterPagesSelector::Fill(); + break; + + default: + MasterPagesSelector::NotifyContainerChangeEvent(rEvent); + break; + } +} + + + + +void AllMasterPagesSelector::UpdateMasterPageList (void) +{ + mpSortedMasterPages->clear(); + int nTokenCount = mpContainer->GetTokenCount(); + for (int i=0; i<nTokenCount; i++) + AddItem(mpContainer->GetTokenForIndex(i)); +} + + + + +void AllMasterPagesSelector::AddItem (MasterPageContainer::Token aToken) +{ + switch (mpContainer->GetOriginForToken(aToken)) + { + case MasterPageContainer::DEFAULT: + case MasterPageContainer::TEMPLATE: + // Templates are added only when coming from the + // MasterPageContainerFiller so that they have an id which + // defines their place in the list. Templates (pre) loaded from + // RecentlyUsedMasterPages are ignored (they will be loaded + // later by the MasterPageContainerFiller.) + if (mpContainer->GetTemplateIndexForToken(aToken) >= 0) + mpSortedMasterPages->insert(mpContainer->GetDescriptorForToken(aToken)); + break; + + default: + break; + } +} + + + + +void AllMasterPagesSelector::UpdatePageSet (ItemList& rItemList) +{ + SortedMasterPageDescriptorList::const_iterator iDescriptor; + SortedMasterPageDescriptorList::const_iterator iEnd (mpSortedMasterPages->end()); + for (iDescriptor=mpSortedMasterPages->begin(); iDescriptor!=iEnd; ++iDescriptor) + rItemList.push_back((*iDescriptor)->maToken); +} + + + + +void AllMasterPagesSelector::GetState (SfxItemSet& rItemSet) +{ + // MasterPagesSelector::GetState(rItemSet); + + if (rItemSet.GetItemState(SID_TP_EDIT_MASTER) == SFX_ITEM_AVAILABLE) + rItemSet.DisableItem(SID_TP_EDIT_MASTER); +} + + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/AllMasterPagesSelector.hxx b/sd/source/ui/sidebar/AllMasterPagesSelector.hxx new file mode 100644 index 000000000000..c6e2494b82cb --- /dev/null +++ b/sd/source/ui/sidebar/AllMasterPagesSelector.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_ALL_MASTER_PAGES_SELECTOR_HXX +#define SD_SIDEBAR_PANELS_ALL_MASTER_PAGES_SELECTOR_HXX + +#include "MasterPagesSelector.hxx" + +#include <memory> + +namespace sd { +class TemplateEntry; +} + +namespace sd { namespace sidebar { + + +/** Show a list of all available master pages so that the user can assign + them to the document. +*/ +class AllMasterPagesSelector + : public MasterPagesSelector +{ +public: + static MasterPagesSelector* Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + + /** Scan the set of templates for the ones whose first master pages are + shown by this control and store them in the MasterPageContainer. + */ + virtual void Fill (ItemList& rItemList); + + virtual void GetState (SfxItemSet& rItemSet); + +protected: + virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent); + +private: + /** The list of master pages displayed by this class. + */ + class SortedMasterPageDescriptorList; + ::std::auto_ptr<SortedMasterPageDescriptorList> mpSortedMasterPages; + + AllMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + virtual ~AllMasterPagesSelector (void); + + void AddTemplate (const TemplateEntry& rEntry); + + /** This filter returns <TRUE/> when the master page specified by the + given file name belongs to the set of Impress master pages. + */ + bool FileFilter (const String& sFileName); + + void AddItem (MasterPageContainer::Token aToken); + + /** Add all items in the internal master page list into the given list. + */ + void UpdatePageSet (ItemList& rItemList); + + /** Update the internal list of master pages that are to show in the + control. + */ + void UpdateMasterPageList (void); + + using MasterPagesSelector::Fill; +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx new file mode 100644 index 000000000000..a5fc7ed9b21c --- /dev/null +++ b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx @@ -0,0 +1,352 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "CurrentMasterPagesSelector.hxx" +#include "PreviewValueSet.hxx" +#include "ViewShellBase.hxx" +#include "SidebarShellManager.hxx" +#include "DrawViewShell.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "MasterPageContainer.hxx" +#include "MasterPageDescriptor.hxx" +#include "EventMultiplexer.hxx" +#include "app.hrc" +#include "DrawDocShell.hxx" +#include "res_bmp.hrc" +#include "sdresid.hxx" +#include "helpids.h" + +#include <vcl/image.hxx> +#include <svx/svdmodel.hxx> +#include <sfx2/request.hxx> + +#include <set> + + +using namespace ::com::sun::star; + +namespace sd { namespace sidebar { + +MasterPagesSelector* CurrentMasterPagesSelector::Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) +{ + SdDrawDocument* pDocument = rViewShellBase.GetDocument(); + if (pDocument == NULL) + return NULL; + + ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer()); + + MasterPagesSelector* pSelector( + new CurrentMasterPagesSelector ( + pParent, + *pDocument, + rViewShellBase, + pContainer, + rxSidebar)); + pSelector->LateInit(); + pSelector->SetHelpId( HID_SD_TASK_PANE_PREVIEW_CURRENT ); + + return pSelector; +} + + + + +CurrentMasterPagesSelector::CurrentMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) + : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar) +{ + // For this master page selector only we change the default action for + // left clicks. + mnDefaultClickAction = SID_TP_APPLY_TO_SELECTED_SLIDES; + + Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener)); + rBase.GetEventMultiplexer()->AddEventListener(aLink, + sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE + | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL + | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER + | sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER + | sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED + | sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED + | sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED); +} + + + + +CurrentMasterPagesSelector::~CurrentMasterPagesSelector (void) +{ + if (mrDocument.GetDocSh() != NULL) + { + EndListening(*mrDocument.GetDocSh()); + } + else + { + OSL_ASSERT(mrDocument.GetDocSh() != NULL); + } + + Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener)); + mrBase.GetEventMultiplexer()->RemoveEventListener(aLink); +} + + + + +void CurrentMasterPagesSelector::LateInit (void) +{ + MasterPagesSelector::LateInit(); + MasterPagesSelector::Fill(); + if (mrDocument.GetDocSh() != NULL) + { + StartListening(*mrDocument.GetDocSh()); + } + else + { + OSL_ASSERT(mrDocument.GetDocSh() != NULL); + } +} + + + + +void CurrentMasterPagesSelector::Fill (ItemList& rItemList) +{ + sal_uInt16 nPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD); + SdPage* pMasterPage; + // Remember the names of the master pages that have been inserted to + // avoid double insertion. + ::std::set<String> aMasterPageNames; + for (sal_uInt16 nIndex=0; nIndex<nPageCount; nIndex++) + { + pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD); + if (pMasterPage == NULL) + continue; + + // Use the name of the master page to avoid duplicate entries. + String sName (pMasterPage->GetName()); + if (aMasterPageNames.find(sName)!=aMasterPageNames.end()) + continue; + aMasterPageNames.insert (sName); + + // Look up the master page in the container and, when it is not yet + // in it, insert it. + MasterPageContainer::Token aToken = mpContainer->GetTokenForPageObject(pMasterPage); + if (aToken == MasterPageContainer::NIL_TOKEN) + { + SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor( + MasterPageContainer::MASTERPAGE, + nIndex, + String(), + pMasterPage->GetName(), + String(), + pMasterPage->IsPrecious(), + ::boost::shared_ptr<PageObjectProvider>(new ExistingPageProvider(pMasterPage)), + ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider()))); + aToken = mpContainer->PutMasterPage(pDescriptor); + } + + rItemList.push_back(aToken); + } +} + + + + +ResId CurrentMasterPagesSelector::GetContextMenuResId (void) const +{ + return SdResId(RID_TASKPANE_CURRENT_MASTERPAGESSELECTOR_POPUP); +} + + + + +void CurrentMasterPagesSelector::UpdateSelection (void) +{ + // Iterate over all pages and for the selected ones put the name of + // their master page into a set. + sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PK_STANDARD); + SdPage* pPage; + ::std::set<String> aNames; + sal_uInt16 nIndex; + bool bLoop (true); + for (nIndex=0; nIndex<nPageCount && bLoop; nIndex++) + { + pPage = mrDocument.GetSdPage (nIndex, PK_STANDARD); + if (pPage != NULL && pPage->IsSelected()) + { + if ( ! pPage->TRG_HasMasterPage()) + { + // One of the pages has no master page. This is an + // indicator for that this method is called in the middle of + // a document change and that the model is not in a valid + // state. Therefore we stop update the selection and wait + // for another call to UpdateSelection when the model is + // valid again. + bLoop = false; + } + else + { + SdrPage& rMasterPage (pPage->TRG_GetMasterPage()); + SdPage* pMasterPage = static_cast<SdPage*>(&rMasterPage); + if (pMasterPage != NULL) + aNames.insert (pMasterPage->GetName()); + } + } + } + + // Find the items for the master pages in the set. + sal_uInt16 nItemCount (PreviewValueSet::GetItemCount()); + for (nIndex=1; nIndex<=nItemCount && bLoop; nIndex++) + { + String sName (PreviewValueSet::GetItemText (nIndex)); + if (aNames.find(sName) != aNames.end()) + { + PreviewValueSet::SelectItem (nIndex); + } + } +} + + + + +void CurrentMasterPagesSelector::ExecuteCommand (const sal_Int32 nCommandId) +{ + if (nCommandId == SID_DELETE_MASTER_PAGE) + { + // Check once again that the master page can safely be deleted, + // i.e. is not used. + SdPage* pMasterPage = GetSelectedMasterPage(); + if (pMasterPage != NULL + && mrDocument.GetMasterPageUserCount(pMasterPage) == 0) + { + // Removing the precious flag so that the following call to + // RemoveUnnessesaryMasterPages() will remove this master page. + pMasterPage->SetPrecious(false); + mrDocument.RemoveUnnecessaryMasterPages(pMasterPage, sal_False, sal_True); + } + } + else + MasterPagesSelector::ExecuteCommand(nCommandId); +} + + + + +void CurrentMasterPagesSelector::ProcessPopupMenu (Menu& rMenu) +{ + // Disable the SID_DELTE_MASTER slot when there is only one master page. + if (mrDocument.GetMasterPageUserCount(GetSelectedMasterPage()) > 0) + { + if (rMenu.GetItemPos(SID_DELETE_MASTER_PAGE) != MENU_ITEM_NOTFOUND) + rMenu.EnableItem(SID_DELETE_MASTER_PAGE, sal_False); + } + + ::boost::shared_ptr<DrawViewShell> pDrawViewShell ( + ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell())); + if (pDrawViewShell + && pDrawViewShell->GetEditMode() == EM_MASTERPAGE) + { + if (rMenu.GetItemPos(SID_TP_EDIT_MASTER) != MENU_ITEM_NOTFOUND) + rMenu.EnableItem(SID_TP_EDIT_MASTER, sal_False); + } + + MasterPagesSelector::ProcessPopupMenu(rMenu); +} + + + + + + +IMPL_LINK(CurrentMasterPagesSelector,EventMultiplexerListener, + sd::tools::EventMultiplexerEvent*,pEvent) +{ + if (pEvent != NULL) + { + switch (pEvent->meEventId) + { + case sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE: + case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL: + case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER: + case sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION: + UpdateSelection(); + break; + + case sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER: + // This is tricky. If a master page is removed, moved, or + // added we have to wait until both the notes master page + // and the standard master page have been removed, moved, + // or added. We do this by looking at the number of master + // pages which has to be odd in the consistent state (the + // handout master page is always present). If the number is + // even we ignore the hint. + if (mrBase.GetDocument()->GetMasterPageCount()%2 == 1) + MasterPagesSelector::Fill(); + break; + + case sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED: + case sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED: + case sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED: + InvalidatePreview((const SdPage*)pEvent->mpUserData); + break; + } + } + + return 0; +} + + + + +void CurrentMasterPagesSelector::NotifyHint (SfxBroadcaster&, const SfxHint& rHint) +{ + const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint); + if (pSimpleHint != NULL) + { + if (pSimpleHint->GetId() == SFX_HINT_DOCCHANGED) + { + // Is the edit view visible in the center pane? + ::boost::shared_ptr<DrawViewShell> pDrawViewShell ( + ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell())); + if (pDrawViewShell.get() != NULL) + { + // Is the edit view in master page mode? + if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE) + { + // Mark the currently edited master page as precious. + SdPage* pCurrentMasterPage = pDrawViewShell->getCurrentPage(); + if (pCurrentMasterPage != NULL) + pCurrentMasterPage->SetPrecious(true); + } + } + } + } +} + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/CurrentMasterPagesSelector.hxx b/sd/source/ui/sidebar/CurrentMasterPagesSelector.hxx new file mode 100644 index 000000000000..37b228c9b49f --- /dev/null +++ b/sd/source/ui/sidebar/CurrentMasterPagesSelector.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_CURRENT_MASTER_PAGES_SELECTOR_HXX +#define SD_SIDEBAR_PANELS_CURRENT_MASTER_PAGES_SELECTOR_HXX + +#include "MasterPagesSelector.hxx" +#include <com/sun/star/lang/XComponent.hpp> + + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; + + +namespace sd { namespace tools { class EventMultiplexerEvent; } } + + +namespace sd { namespace sidebar { + + +/** Show the master pages currently used by a SdDrawDocument. +*/ +class CurrentMasterPagesSelector + : public MasterPagesSelector, + public SfxListener +{ +public: + static MasterPagesSelector* Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + + /** Set the selection so that the master page is selected that is + used by the currently selected page of the document in the + center pane. + */ + virtual void UpdateSelection (void); + + /** Copy all master pages that are to be shown into the given list. + */ + virtual void Fill (ItemList& rItemList); + + using MasterPagesSelector::Fill; + +protected: + virtual ResId GetContextMenuResId (void) const; + + virtual void ProcessPopupMenu (Menu& rMenu); + virtual void ExecuteCommand (const sal_Int32 nCommandId); + +private: + cssu::Reference<css::lang::XComponent> mxListener; + + CurrentMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + virtual ~CurrentMasterPagesSelector (void); + + virtual void LateInit (void); + + DECL_LINK(EventMultiplexerListener,sd::tools::EventMultiplexerEvent*); + void NotifyHint (SfxBroadcaster&, const SfxHint& rHint); +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/CustomAnimationPanel.cxx b/sd/source/ui/sidebar/CustomAnimationPanel.cxx new file mode 100644 index 000000000000..04d0009967c2 --- /dev/null +++ b/sd/source/ui/sidebar/CustomAnimationPanel.cxx @@ -0,0 +1,74 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "CustomAnimationPanel.hxx" + +#include "ViewShellBase.hxx" + + +namespace sd { + extern ::Window * createCustomAnimationPanel (::Window* pParent, ViewShellBase& rBase); + extern sal_Int32 getCustomAnimationPanelMinimumHeight (::Window* pParent); +} + + + + +namespace sd { namespace sidebar { + + +CustomAnimationPanel::CustomAnimationPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) + : PanelBase( + pParentWindow, + rViewShellBase) +{ +#ifdef DEBUG + SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:CustomAnimationPanel"))); +#endif +} + + + + +CustomAnimationPanel::~CustomAnimationPanel (void) +{ +} + + + + +::Window* CustomAnimationPanel::CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) +{ + return createCustomAnimationPanel(pParentWindow, rViewShellBase); +} + + + + +css::ui::LayoutSize CustomAnimationPanel::GetHeightForWidth (const sal_Int32 /*nWidth*/) +{ + const sal_Int32 nMinimumHeight(getCustomAnimationPanelMinimumHeight(mpWrappedControl.get())); + return css::ui::LayoutSize(nMinimumHeight,-1, nMinimumHeight); +} + + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/CustomAnimationPanel.hxx b/sd/source/ui/sidebar/CustomAnimationPanel.hxx new file mode 100644 index 000000000000..2fb71c1b4ec6 --- /dev/null +++ b/sd/source/ui/sidebar/CustomAnimationPanel.hxx @@ -0,0 +1,46 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_CUSTOM_ANIMATION_PANEL_HXX +#define SD_SIDEBAR_CUSTOM_ANIMATION_PANEL_HXX + +#include "PanelBase.hxx" + + +namespace sd { namespace sidebar { + +class CustomAnimationPanel + : public PanelBase +{ +public: + CustomAnimationPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); + virtual ~CustomAnimationPanel (void); + + // ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + +protected: + virtual ::Window* CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); +}; + +} } // end of namespace sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/DocumentHelper.cxx b/sd/source/ui/sidebar/DocumentHelper.cxx new file mode 100644 index 000000000000..4cdbb0e3f480 --- /dev/null +++ b/sd/source/ui/sidebar/DocumentHelper.cxx @@ -0,0 +1,570 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "DocumentHelper.hxx" + +#include "drawdoc.hxx" +#include "DrawDocShell.hxx" +#include "sdpage.hxx" +#include "glob.hxx" +#include "unmovss.hxx" +#include "strings.hrc" +#include "sdresid.hxx" +#include "undoback.hxx" +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XDrawPages.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include "stlpool.hxx" +#include <svx/xfillit0.hxx> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +namespace sd { namespace sidebar { + +SdPage* DocumentHelper::CopyMasterPageToLocalDocument ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage) +{ + SdPage* pNewMasterPage = NULL; + + do + { + if (pMasterPage == NULL) + break; + + // Check the presence of the source document. + SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>( + pMasterPage->GetModel()); + if (pSourceDocument == NULL) + break; + + // When the given master page already belongs to the target document + // then there is nothing more to do. + if (pSourceDocument == &rTargetDocument) + { + pNewMasterPage = pMasterPage; + break; + } + + // Test if the master pages of both the slide and its notes page are + // present. This is not the case when we are called during the + // creation of the slide master page because then the notes master + // page is not there. + sal_uInt16 nSourceMasterPageCount = pSourceDocument->GetMasterPageCount(); + if (nSourceMasterPageCount%2 == 0) + // There should be 1 handout page + n slide masters + n notes + // masters = 2*n+1. An even value indicates that a new slide + // master but not yet the notes master has been inserted. + break; + sal_uInt16 nIndex = pMasterPage->GetPageNum(); + if (nSourceMasterPageCount <= nIndex+1) + break; + // Get the slide master page. + if (pMasterPage != static_cast<SdPage*>( + pSourceDocument->GetMasterPage(nIndex))) + break; + // Get the notes master page. + SdPage* pNotesMasterPage = static_cast<SdPage*>( + pSourceDocument->GetMasterPage(nIndex+1)); + if (pNotesMasterPage == NULL) + break; + + + // Check if a master page with the same name as that of the given + // master page already exists. + bool bPageExists (false); + sal_uInt16 nMasterPageCount(rTargetDocument.GetMasterSdPageCount(PK_STANDARD)); + for (sal_uInt16 nMaster=0; nMaster<nMasterPageCount; nMaster++) + { + SdPage* pCandidate = static_cast<SdPage*>( + rTargetDocument.GetMasterSdPage (nMaster, PK_STANDARD)); + if (pMasterPage!=NULL + && pCandidate->GetName().CompareTo(pMasterPage->GetName())==0) + { + bPageExists = true; + pNewMasterPage = pCandidate; + break; + } + } + if (bPageExists) + break; + + // Create a new slide (and its notes page.) + uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier ( + rTargetDocument.getUnoModel(), uno::UNO_QUERY); + if ( ! xSlideSupplier.is()) + break; + uno::Reference<drawing::XDrawPages> xSlides ( + xSlideSupplier->getDrawPages(), uno::UNO_QUERY); + if ( ! xSlides.is()) + break; + xSlides->insertNewByIndex (xSlides->getCount()); + + // Set a layout. + SdPage* pSlide = rTargetDocument.GetSdPage( + rTargetDocument.GetSdPageCount(PK_STANDARD)-1, + PK_STANDARD); + if (pSlide == NULL) + break; + pSlide->SetAutoLayout(AUTOLAYOUT_TITLE, sal_True); + + // Create a copy of the master page and the associated notes + // master page and insert them into our document. + pNewMasterPage = AddMasterPage(rTargetDocument, pMasterPage); + if (pNewMasterPage==NULL) + break; + SdPage* pNewNotesMasterPage + = AddMasterPage(rTargetDocument, pNotesMasterPage); + if (pNewNotesMasterPage==NULL) + break; + + // Make the connection from the new slide to the master page + // (and do the same for the notes page.) + rTargetDocument.SetMasterPage ( + rTargetDocument.GetSdPageCount(PK_STANDARD)-1, + pNewMasterPage->GetName(), + &rTargetDocument, + sal_False, // Connect the new master page with the new slide but + // do not modify other (master) pages. + sal_True); + } + while (false); + + // We are not interested in any automatisms for our modified internal + // document. + rTargetDocument.SetChanged (sal_False); + + return pNewMasterPage; +} + + + + +SdPage* DocumentHelper::GetSlideForMasterPage (SdPage* pMasterPage) +{ + SdPage* pCandidate = NULL; + + SdDrawDocument* pDocument = NULL; + if (pMasterPage != NULL) + pDocument = dynamic_cast<SdDrawDocument*>(pMasterPage->GetModel()); + + // Iterate over all pages and check if it references the given master + // page. + if (pDocument!=NULL && pDocument->GetSdPageCount(PK_STANDARD) > 0) + { + // In most cases a new slide has just been inserted so start with + // the last page. + sal_uInt16 nPageIndex (pDocument->GetSdPageCount(PK_STANDARD)-1); + bool bFound (false); + while ( ! bFound) + { + pCandidate = pDocument->GetSdPage( + nPageIndex, + PK_STANDARD); + if (pCandidate != NULL) + { + if (static_cast<SdPage*>(&pCandidate->TRG_GetMasterPage()) + == pMasterPage) + { + bFound = true; + break; + } + } + + if (nPageIndex == 0) + break; + else + nPageIndex --; + } + + // If no page was found that refernced the given master page reset + // the pointer that is returned. + if ( ! bFound) + pCandidate = NULL; + } + + return pCandidate; +} + + + + +SdPage* DocumentHelper::AddMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage) +{ + SdPage* pClonedMasterPage = NULL; + + if (pMasterPage!=NULL) + { + try + { + // Duplicate the master page. + pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone()); + + // Copy the necessary styles. + SdDrawDocument* pSourceDocument + = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); + if (pSourceDocument != NULL) + ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage); + + // Copy the precious flag. + pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious()); + + // Now that the styles are available we can insert the cloned + // master page. + rTargetDocument.InsertMasterPage (pClonedMasterPage); + } + catch(const uno::Exception&) + { + pClonedMasterPage = NULL; + DBG_UNHANDLED_EXCEPTION(); + } + catch(const ::std::exception&) + { + pClonedMasterPage = NULL; + OSL_TRACE ("caught general exception"); + } + catch(...) + { + pClonedMasterPage = NULL; + OSL_TRACE ("caught general exception"); + } + } + + return pClonedMasterPage; +} + + + + +void DocumentHelper::ProvideStyles ( + SdDrawDocument& rSourceDocument, + SdDrawDocument& rTargetDocument, + SdPage* pPage) +{ + // Get the layout name of the given page. + String sLayoutName (pPage->GetLayoutName()); + sLayoutName.Erase (sLayoutName.SearchAscii (SD_LT_SEPARATOR)); + + // Copy the style sheet from source to target document. + SdStyleSheetPool* pSourceStyleSheetPool = + static_cast<SdStyleSheetPool*>(rSourceDocument.GetStyleSheetPool()); + SdStyleSheetPool* pTargetStyleSheetPool = + static_cast<SdStyleSheetPool*>(rTargetDocument.GetStyleSheetPool()); + SdStyleSheetVector aCreatedStyles; + pTargetStyleSheetPool->CopyLayoutSheets ( + sLayoutName, + *pSourceStyleSheetPool, + aCreatedStyles); + + // Add an undo action for the copied style sheets. + if( !aCreatedStyles.empty() ) + { + ::svl::IUndoManager* pUndoManager = rTargetDocument.GetDocSh()->GetUndoManager(); + if (pUndoManager != NULL) + { + SdMoveStyleSheetsUndoAction* pMovStyles = + new SdMoveStyleSheetsUndoAction ( + &rTargetDocument, + aCreatedStyles, + sal_True); + pUndoManager->AddUndoAction (pMovStyles); + } + } +} + + + + +void DocumentHelper::AssignMasterPageToPageList ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) +{ + if (pMasterPage == NULL || !pMasterPage->IsMasterPage()) + return; + + // Make the layout name by stripping ouf the layout postfix from the + // layout name of the given master page. + OUString sFullLayoutName(pMasterPage->GetLayoutName()); + String sBaseLayoutName (sFullLayoutName); + sBaseLayoutName.Erase (sBaseLayoutName.SearchAscii (SD_LT_SEPARATOR)); + + if (rpPageList->empty()) + return; + + // Create a second list that contains only the valid pointers to + // pages for which an assignment is necessary. + ::std::vector<SdPage*>::const_iterator iPage; + ::std::vector<SdPage*> aCleanedList; + for (iPage=rpPageList->begin(); iPage!=rpPageList->end(); ++iPage) + { + OSL_ASSERT(*iPage!=NULL && (*iPage)->GetModel() == &rTargetDocument); + if (*iPage != NULL && (*iPage)->GetLayoutName() != sFullLayoutName) + { + aCleanedList.push_back(*iPage); + } + } + if (aCleanedList.empty() ) + return; + + ::svl::IUndoManager* pUndoMgr = rTargetDocument.GetDocSh()->GetUndoManager(); + if( pUndoMgr ) + pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String()); + + SdPage* pMasterPageInDocument = ProvideMasterPage(rTargetDocument,pMasterPage,rpPageList); + if (pMasterPageInDocument == NULL) + return; + + // Assign the master pages to the given list of pages. + for (iPage=aCleanedList.begin(); + iPage!=aCleanedList.end(); + ++iPage) + { + AssignMasterPageToPage ( + pMasterPageInDocument, + sBaseLayoutName, + *iPage); + } + + if( pUndoMgr ) + pUndoMgr->LeaveListAction(); +} + + + + +SdPage* DocumentHelper::AddMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + sal_uInt16 nInsertionIndex) +{ + SdPage* pClonedMasterPage = NULL; + + if (pMasterPage!=NULL) + { + // Duplicate the master page. + pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone()); + + // Copy the precious flag. + pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious()); + + // Copy the necessary styles. + SdDrawDocument* pSourceDocument + = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); + if (pSourceDocument != NULL) + { + ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage); + + // Now that the styles are available we can insert the cloned + // master page. + rTargetDocument.InsertMasterPage (pClonedMasterPage, nInsertionIndex); + + // Adapt the size of the new master page to that of the pages in + // the document. + Size aNewSize (rTargetDocument.GetSdPage(0, pMasterPage->GetPageKind())->GetSize()); + Rectangle aBorders ( + pClonedMasterPage->GetLftBorder(), + pClonedMasterPage->GetUppBorder(), + pClonedMasterPage->GetRgtBorder(), + pClonedMasterPage->GetLwrBorder()); + pClonedMasterPage->ScaleObjects(aNewSize, aBorders, sal_True); + pClonedMasterPage->SetSize(aNewSize); + pClonedMasterPage->CreateTitleAndLayout(sal_True); + } + } + + return pClonedMasterPage; +} + + + + +/** In here we have to handle three cases: + 1. pPage is a normal slide. We can use SetMasterPage to assign the + master pages to it. + 2. pPage is a master page that is used by at least one slide. We can + assign the master page to these slides. + 3. pPage is a master page that is currently not used by any slide. + We can delete that page and add copies of the given master pages + instead. + + For points 2 and 3 where one master page A is assigned to another B we have + to keep in mind that the master page that page A has already been + inserted into the target document. +*/ +void DocumentHelper::AssignMasterPageToPage ( + SdPage* pMasterPage, + const String& rsBaseLayoutName, + SdPage* pPage) +{ + // Leave early when the parameters are invalid. + if (pPage == NULL || pMasterPage == NULL) + return; + SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel()); + if (pDocument == NULL) + return; + + if ( ! pPage->IsMasterPage()) + { + // 1. Remove the background object (so that that, if it exists, does + // not override the new master page) and assign the master page to + // the regular slide. + pDocument->GetDocSh()->GetUndoManager()->AddUndoAction( + new SdBackgroundObjUndoAction( + *pDocument, *pPage, pPage->getSdrPageProperties().GetItemSet()), + sal_True); + pPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_NONE)); + + pDocument->SetMasterPage ( + (pPage->GetPageNum()-1)/2, + rsBaseLayoutName, + pDocument, + sal_False, + sal_False); + } + else + { + // Find first slide that uses the master page. + SdPage* pSlide = NULL; + sal_uInt16 nPageCount = pDocument->GetSdPageCount(PK_STANDARD); + for (sal_uInt16 nPage=0; nPage<nPageCount&&pSlide==NULL; nPage++) + { + SdrPage* pCandidate = pDocument->GetSdPage(nPage,PK_STANDARD); + if (pCandidate != NULL + && pCandidate->TRG_HasMasterPage() + && &(pCandidate->TRG_GetMasterPage()) == pPage) + { + pSlide = static_cast<SdPage*>(pCandidate); + } + } + + if (pSlide != NULL) + { + // 2. Assign the given master pages to the first slide that was + // found above that uses the master page. + pDocument->SetMasterPage ( + (pSlide->GetPageNum()-1)/2, + rsBaseLayoutName, + pDocument, + sal_False, + sal_False); + } + else + { + // 3. Replace the master page A by a copy of the given master + // page B. + pDocument->RemoveUnnecessaryMasterPages ( + pPage, sal_False); + } + } +} + + + + +SdPage* DocumentHelper::ProvideMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) +{ + // Make sure that both the master page and its notes master exist + // in the source document. If one is missing then return without + // making any changes. + if (pMasterPage == NULL) + { + // The caller should make sure that the master page is valid. + OSL_ASSERT(pMasterPage != NULL); + return NULL; + } + SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); + if (pSourceDocument == NULL) + return NULL; + SdPage* pNotesMasterPage = static_cast<SdPage*>( + pSourceDocument->GetMasterPage(pMasterPage->GetPageNum()+1)); + if (pNotesMasterPage == NULL) + { + // The model is not in a valid state. Maybe a new master page + // is being (not finished yet) created? Return without making + // any changes. + return NULL; + } + + SdPage* pMasterPageInDocument = NULL; + // Search for a master page with the same name as the given one in + // the target document. + const OUString sMasterPageLayoutName (pMasterPage->GetLayoutName()); + for (sal_uInt16 nIndex=0,nCount=rTargetDocument.GetMasterPageCount(); nIndex<nCount; ++nIndex) + { + SdPage* pCandidate = static_cast<SdPage*>(rTargetDocument.GetMasterPage(nIndex)); + if (pCandidate && sMasterPageLayoutName.equals(pCandidate->GetLayoutName())) + { + // The requested master page does already exist in the + // target document, return it. + return pCandidate; + } + } + + // The given master page does not already belong to the target + // document so we have to create copies and insert them into the + // targer document. + + // Determine the position where the new master pages are inserted. + // By default they are inserted at the end. When we assign to a + // master page then insert after the last of the (selected) pages. + sal_uInt16 nInsertionIndex = rTargetDocument.GetMasterPageCount(); + if (rpPageList->front()->IsMasterPage()) + { + nInsertionIndex = rpPageList->back()->GetPageNum(); + } + + // Clone the master page. + if (pMasterPage->GetModel() != &rTargetDocument) + { + pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex); + if( rTargetDocument.IsUndoEnabled() ) + rTargetDocument.AddUndo( + rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument)); + } + else + pMasterPageInDocument = pMasterPage; + + // Clone the notes master. + if (pNotesMasterPage->GetModel() != &rTargetDocument) + { + SdPage* pClonedNotesMasterPage + = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1); + if( rTargetDocument.IsUndoEnabled() ) + rTargetDocument.AddUndo( + rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage)); + } + + return pMasterPageInDocument; +} + + + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/DocumentHelper.hxx b/sd/source/ui/sidebar/DocumentHelper.hxx new file mode 100644 index 000000000000..b0b1d1550a3f --- /dev/null +++ b/sd/source/ui/sidebar/DocumentHelper.hxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_DCUMENT_HELPER_HXX +#define SD_SIDEBAR_PANELS_DCUMENT_HELPER_HXX + +#include <tools/solar.h> +#include <boost/shared_ptr.hpp> +#include <vector> + +class SdDrawDocument; +class SdPage; +class String; + +namespace sd { namespace sidebar { + +/** A collection of methods supporting the handling of master pages. +*/ +class DocumentHelper +{ +public: + /** Return a copy of the given master page in the given document. + */ + static SdPage* CopyMasterPageToLocalDocument ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage); + + /** Return and, when not yet present, create a slide that uses the given + masster page. + */ + static SdPage* GetSlideForMasterPage (SdPage* pMasterPage); + + /** Copy the styles used by the given page from the source document to + the target document. + */ + static void ProvideStyles ( + SdDrawDocument& rSourceDocument, + SdDrawDocument& rTargetDocument, + SdPage* pPage); + + /** Assign the given master page to the list of pages. + @param rTargetDocument + The document that is the owner of the pages in rPageList. + @param pMasterPage + This master page will usually be a member of the list of all + available master pages as provided by the MasterPageContainer. + @param rPageList + The pages to which to assign the master page. These pages may + be slides or master pages themselves. + */ + static void AssignMasterPageToPageList ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rPageList); + +private: + static SdPage* AddMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage); + static SdPage* AddMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + sal_uInt16 nInsertionIndex); + static SdPage* ProvideMasterPage ( + SdDrawDocument& rTargetDocument, + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList); + + /** Assign the given master page to the given page. + @param pMasterPage + In contrast to AssignMasterPageToPageList() this page is assumed + to be in the target document, i.e. the same document that pPage + is in. The caller will usually call AddMasterPage() to create a + clone of a master page in a another document to create it. + @param rsBaseLayoutName + The layout name of the given master page. It is given so that + it has not to be created on every call. It could be generated + from the given master page, though. + @param pPage + The page to which to assign the master page. It can be a slide + or a master page itself. + */ + static void AssignMasterPageToPage ( + SdPage* pMasterPage, + const String& rsBaseLayoutName, + SdPage* pPage); +}; + + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/IDisposable.hxx b/sd/source/ui/sidebar/IDisposable.hxx new file mode 100644 index 000000000000..d5dfc1d440e7 --- /dev/null +++ b/sd/source/ui/sidebar/IDisposable.hxx @@ -0,0 +1,39 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_DISPOSABLE_INTERFACE_HXX +#define SD_SIDEBAR_DISPOSABLE_INTERFACE_HXX + +#include <tools/gen.hxx> +#include <sal/types.h> + +class Window; + +namespace sd { namespace sidebar { + + +class IDisposable +{ +public: + virtual void Dispose (void) = 0; + virtual ~IDisposable(); +}; + + +} } // end of namespace ::sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/ISidebarReceiver.hxx b/sd/source/ui/sidebar/ISidebarReceiver.hxx new file mode 100644 index 000000000000..3725363da830 --- /dev/null +++ b/sd/source/ui/sidebar/ISidebarReceiver.hxx @@ -0,0 +1,37 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_RECEIVER_INTERFACE_HXX +#define SD_SIDEBAR_RECEIVER_INTERFACE_HXX + +#include <com/sun/star/ui/XSidebar.hpp> + +namespace sd { namespace sidebar { + + +class ISidebarReceiver +{ +public: + virtual void SetSidebar (const ::com::sun::star::uno::Reference< + ::com::sun::star::ui::XSidebar>& rxSidebar) = 0; + virtual ~ISidebarReceiver(); +}; + + +} } // end of namespace ::sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/LayoutMenu.cxx b/sd/source/ui/sidebar/LayoutMenu.cxx new file mode 100644 index 000000000000..5f347439503c --- /dev/null +++ b/sd/source/ui/sidebar/LayoutMenu.cxx @@ -0,0 +1,979 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "LayoutMenu.hxx" + +#include "SidebarShellManager.hxx" +#include "app.hrc" +#include "drawdoc.hxx" +#include "framework/FrameworkHelper.hxx" +#include "glob.hrc" +#include "glob.hxx" +#include "helpids.h" +#include "pres.hxx" +#include "res_bmp.hrc" +#include "sdpage.hxx" +#include "sdresid.hxx" +#include "strings.hrc" +#include "tools/SlotStateListener.hxx" +#include "DrawController.hxx" +#include "DrawDocShell.hxx" +#include "DrawViewShell.hxx" +#include "EventMultiplexer.hxx" +#include "SlideSorterViewShell.hxx" +#include "ViewShellBase.hxx" +#include <sfx2/sidebar/Theme.hxx> + +#include <comphelper/processfactory.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/languageoptions.hxx> +#include <vcl/image.hxx> +#include <vcl/floatwin.hxx> + +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XView.hpp> +#include <com/sun/star/drawing/framework/ResourceId.hpp> + +#include <vector> +#include <memory> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using namespace ::sd::slidesorter; +using ::sd::framework::FrameworkHelper; + +namespace sd { namespace sidebar { + + + +struct snewfoil_value_info +{ + sal_uInt16 mnBmpResId; + sal_uInt16 mnStrResId; + WritingMode meWritingMode; + AutoLayout maAutoLayout; +}; + +static snewfoil_value_info notes[] = +{ + {BMP_FOILN_01, STR_AUTOLAYOUT_NOTES, WritingMode_LR_TB, + AUTOLAYOUT_NOTES}, + {0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE}, +}; + +static snewfoil_value_info handout[] = +{ + {BMP_FOILH_01, STR_AUTOLAYOUT_HANDOUT1, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT1}, + {BMP_FOILH_02, STR_AUTOLAYOUT_HANDOUT2, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT2}, + {BMP_FOILH_03, STR_AUTOLAYOUT_HANDOUT3, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT3}, + {BMP_FOILH_04, STR_AUTOLAYOUT_HANDOUT4, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT4}, + {BMP_FOILH_06, STR_AUTOLAYOUT_HANDOUT6, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT6}, + {BMP_FOILH_09, STR_AUTOLAYOUT_HANDOUT9, WritingMode_LR_TB, + AUTOLAYOUT_HANDOUT9}, + {0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE}, +}; + +static snewfoil_value_info standard[] = +{ + {BMP_LAYOUT_EMPTY, STR_AUTOLAYOUT_NONE, WritingMode_LR_TB, AUTOLAYOUT_NONE}, + {BMP_LAYOUT_HEAD03, STR_AUTOLAYOUT_TITLE, WritingMode_LR_TB, AUTOLAYOUT_TITLE}, + {BMP_LAYOUT_HEAD02, STR_AUTOLAYOUT_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_ENUM}, + {BMP_LAYOUT_HEAD02A, STR_AUTOLAYOUT_2CONTENT, WritingMode_LR_TB, AUTOLAYOUT_2TEXT}, + {BMP_LAYOUT_HEAD01, STR_AUTOLAYOUT_ONLY_TITLE, WritingMode_LR_TB, AUTOLAYOUT_ONLY_TITLE}, + {BMP_LAYOUT_TEXTONLY, STR_AUTOLAYOUT_ONLY_TEXT, WritingMode_LR_TB, AUTOLAYOUT_ONLY_TEXT}, + {BMP_LAYOUT_HEAD03B, STR_AUTOLAYOUT_2CONTENT_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_2OBJTEXT}, + {BMP_LAYOUT_HEAD03C, STR_AUTOLAYOUT_CONTENT_2CONTENT, WritingMode_LR_TB, AUTOLAYOUT_TEXT2OBJ}, + {BMP_LAYOUT_HEAD03A, STR_AUTOLAYOUT_2CONTENT_OVER_CONTENT,WritingMode_LR_TB, AUTOLAYOUT_2OBJOVERTEXT}, + {BMP_LAYOUT_HEAD02B, STR_AUTOLAYOUT_CONTENT_OVER_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_OBJOVERTEXT}, + {BMP_LAYOUT_HEAD04, STR_AUTOLAYOUT_4CONTENT, WritingMode_LR_TB, AUTOLAYOUT_4OBJ}, + {BMP_LAYOUT_HEAD06, STR_AUTOLAYOUT_6CONTENT, WritingMode_LR_TB, AUTOLAYOUT_6CLIPART}, + + // vertical + {BMP_LAYOUT_VERTICAL02, STR_AL_VERT_TITLE_TEXT_CHART, WritingMode_TB_RL,AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART}, + {BMP_LAYOUT_VERTICAL01, STR_AL_VERT_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE}, + {BMP_LAYOUT_HEAD02, STR_AL_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE}, + {BMP_LAYOUT_HEAD02A, STR_AL_TITLE_VERT_OUTLINE_CLIPART, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART}, + {0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE} +}; + + + + +LayoutMenu::LayoutMenu ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) + : ValueSet (pParent, WB_ITEMBORDER), + DragSourceHelper(this), + DropTargetHelper(this), + mrBase(rViewShellBase), + mbUseOwnScrollBar(false), + mnPreferredColumnCount(3), + mxListener(NULL), + mbSelectionUpdatePending(true), + mbIsMainViewChangePending(false), + mxSidebar(rxSidebar), + mbIsDisposed(false) +{ + implConstruct( *mrBase.GetDocument()->GetDocSh() ); + OSL_TRACE("created LayoutMenu at %x", this); + + SetStyle(GetStyle() | WB_ITEMBORDER | WB_FLATVALUESET | WB_TABSTOP); + + SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground)); + SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Paint_PanelBackground)); + +#ifdef DEBUG + SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:LayoutMenu"))); +#endif +} + + + + +void LayoutMenu::implConstruct( DrawDocShell& rDocumentShell ) +{ + OSL_ENSURE( mrBase.GetDocument()->GetDocSh() == &rDocumentShell, + "LayoutMenu::implConstruct: hmm?" ); + // if this fires, then my assumption that the rDocumentShell parameter to our first ctor is superfluous ... + + SetStyle ( + ( GetStyle() & ~(WB_ITEMBORDER) ) + | WB_TABSTOP + | WB_MENUSTYLEVALUESET + | WB_NO_DIRECTSELECT + ); + if (mbUseOwnScrollBar) + SetStyle (GetStyle() | WB_VSCROLL); + SetExtraSpacing(2); + SetSelectHdl (LINK(this, LayoutMenu, ClickHandler)); + InvalidateContent(); + + Link aEventListenerLink (LINK(this,LayoutMenu,EventMultiplexerListener)); + mrBase.GetEventMultiplexer()->AddEventListener(aEventListenerLink, + ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE + | ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION + | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED + | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED + | ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED + | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL + | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER); + + Window::SetHelpId(HID_SD_TASK_PANE_PREVIEW_LAYOUTS); + SetAccessibleName(SdResId(STR_TASKPANEL_LAYOUT_MENU_TITLE)); + + Link aStateChangeLink (LINK(this,LayoutMenu,StateChangeHandler)); + mxListener = new ::sd::tools::SlotStateListener( + aStateChangeLink, + Reference<frame::XDispatchProvider>(mrBase.GetController()->getFrame(), UNO_QUERY), + ".uno:VerticalTextState"); + + SetSizePixel(GetParent()->GetSizePixel()); + Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler)); + GetParent()->AddEventListener(aWindowEventHandlerLink); +} + + + + +LayoutMenu::~LayoutMenu (void) +{ + OSL_TRACE("destroying LayoutMenu at %x", this); + Dispose(); +} + + + + +void LayoutMenu::Dispose (void) +{ + if (mbIsDisposed) + return; + + OSL_TRACE("disposing LayoutMenu at %x", this); + + mbIsDisposed = true; + + Reference<lang::XComponent> xComponent (mxListener, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + + Clear(); + Link aLink (LINK(this,LayoutMenu,EventMultiplexerListener)); + mrBase.GetEventMultiplexer()->RemoveEventListener (aLink); + + Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler)); + GetParent()->RemoveEventListener(aWindowEventHandlerLink); +} + + + + +AutoLayout LayoutMenu::GetSelectedAutoLayout (void) +{ + AutoLayout aResult = AUTOLAYOUT_NONE; + + if ( ! IsNoSelection() && GetSelectItemId()!=0) + { + AutoLayout* pLayout = static_cast<AutoLayout*>(GetItemData(GetSelectItemId())); + if (pLayout != NULL) + aResult = *pLayout; + } + + return aResult; +} + + + + +/** The preferred size depends on the preferred number of columns, the + number of items, and the size of the items. +*/ +Size LayoutMenu::GetPreferredSize (void) +{ + Size aItemSize = CalcItemSizePixel (Size()); + Size aPreferredWindowSize = CalcWindowSizePixel ( + aItemSize, + (sal_uInt16)mnPreferredColumnCount, + (sal_uInt16)CalculateRowCount (aItemSize,mnPreferredColumnCount)); + return aPreferredWindowSize; +} + + + + +sal_Int32 LayoutMenu::GetPreferredWidth (sal_Int32 nHeight) +{ + sal_Int32 nPreferredWidth = 100; + if (GetItemCount() > 0) + { + Image aImage = GetItemImage(GetItemId(0)); + Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel()); + if (nHeight>0 && aItemSize.Height()>0) + { + int nRowCount = nHeight / aItemSize.Height(); + if (nRowCount <= 0) + nRowCount = 1; + int nColumnCount = (GetItemCount() + nRowCount-1) / nRowCount; + nPreferredWidth = nColumnCount * aItemSize.Width(); + } + } + + return nPreferredWidth; +} + + + + +ui::LayoutSize LayoutMenu::GetHeightForWidth (const sal_Int32 nWidth) +{ + sal_Int32 nPreferredHeight = 200; + if ( ! mbUseOwnScrollBar && GetItemCount()>0) + { + Image aImage = GetItemImage(GetItemId(0)); + Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel()); + if (nWidth>0 && aItemSize.Width()>0) + { + aItemSize.Width() += 8; + aItemSize.Height() += 8; + int nColumnCount = nWidth / aItemSize.Width(); + if (nColumnCount <= 0) + nColumnCount = 1; + else if (nColumnCount > 4) + nColumnCount = 4; + int nRowCount = (GetItemCount() + nColumnCount-1) / nColumnCount; + nPreferredHeight = nRowCount * aItemSize.Height(); + } + } + return ui::LayoutSize(nPreferredHeight,nPreferredHeight,nPreferredHeight); +} + + + + +sal_Int32 LayoutMenu::GetMinimumWidth (void) +{ + sal_Int32 nMinimumWidth = 0; + if (GetItemCount()>0) + { + Image aImage = GetItemImage(GetItemId(0)); + Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel()); + nMinimumWidth = aItemSize.Width(); + } + return nMinimumWidth; +} + + + + +void LayoutMenu::UpdateEnabledState (const MasterMode eMode) +{ + bool bIsEnabled (false); + + ::boost::shared_ptr<ViewShell> pMainViewShell (mrBase.GetMainViewShell()); + if (pMainViewShell) + { + switch (pMainViewShell->GetShellType()) + { + case ViewShell::ST_NONE: + case ViewShell::ST_OUTLINE: + case ViewShell::ST_PRESENTATION: + case ViewShell::ST_SIDEBAR: + // The complete task pane is disabled for these values or + // not even visible. Disabling the LayoutMenu would be + // logical but unnecessary. The main disadvantage is that + // after re-enabling it (typically) another panel is + // expanded. + bIsEnabled = true; + break; + + case ViewShell::ST_DRAW: + case ViewShell::ST_IMPRESS: + { + switch (eMode) + { + case MM_UNKNOWN: + { + ::boost::shared_ptr<DrawViewShell> pDrawViewShell ( + ::boost::dynamic_pointer_cast<DrawViewShell>(pMainViewShell)); + if (pDrawViewShell) + bIsEnabled = pDrawViewShell->GetEditMode() != EM_MASTERPAGE; + break; + } + case MM_NORMAL: + bIsEnabled = true; + break; + + case MM_MASTER: + bIsEnabled = false; + break; + } + break; + } + + case ViewShell::ST_HANDOUT: + case ViewShell::ST_NOTES: + case ViewShell::ST_SLIDE_SORTER: + default: + bIsEnabled = true; + break; + } + } + (void)bIsEnabled; //FIXME either this method is a no-op or this should do something +} + + + + +void LayoutMenu::Paint (const Rectangle& rRect) +{ + if (mbSelectionUpdatePending) + { + mbSelectionUpdatePending = false; + UpdateSelection(); + } + ValueSet::Paint (rRect); +} + + + + +void LayoutMenu::Resize (void) +{ + Size aWindowSize = GetOutputSizePixel(); + if (IsVisible() && aWindowSize.Width() > 0) + { + // Calculate the number of rows and columns. + if (GetItemCount() > 0) + { + Image aImage = GetItemImage(GetItemId(0)); + Size aItemSize = CalcItemSizePixel ( + aImage.GetSizePixel()); + aItemSize.Width() += 8; + aItemSize.Height() += 8; + int nColumnCount = aWindowSize.Width() / aItemSize.Width(); + if (nColumnCount < 1) + nColumnCount = 1; + else if (nColumnCount > 4) + nColumnCount = 4; + + int nRowCount = CalculateRowCount (aItemSize, nColumnCount); + + SetColCount ((sal_uInt16)nColumnCount); + SetLineCount ((sal_uInt16)nRowCount); + } + } + + ValueSet::Resize (); +} + + + + +void LayoutMenu::MouseButtonDown (const MouseEvent& rEvent) +{ + // As a preparation for the context menu the item under the mouse is + // selected. + if (rEvent.IsRight()) + { + ReleaseMouse(); + sal_uInt16 nIndex = GetItemId (rEvent.GetPosPixel()); + if (nIndex > 0) + SelectItem(nIndex); + } + + ValueSet::MouseButtonDown (rEvent); +} + + + + +void LayoutMenu::InsertPageWithLayout (AutoLayout aLayout) +{ + ViewShell* pViewShell = mrBase.GetMainViewShell().get(); + if (pViewShell == NULL) + return; + + SfxViewFrame* pViewFrame = mrBase.GetViewFrame(); + if (pViewFrame == NULL) + return; + + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if (pDispatcher == NULL) + return; + + // Call SID_INSERTPAGE with the right arguments. This is because + // the popup menu can not call this slot with arguments directly. + SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout)); + if (aRequest.GetArgs() != NULL) + { + pDispatcher->Execute( + SID_INSERTPAGE, + SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, + *aRequest.GetArgs()); + } + UpdateSelection(); +} + + + + +void LayoutMenu::InvalidateContent (void) +{ + // Throw away the current set and fill the menu anew according to the + // current settings (this includes the support for vertical writing.) + Fill(); + + if (mxSidebar.is()) + mxSidebar->requestLayout(); +} + + + + +int LayoutMenu::CalculateRowCount (const Size&, int nColumnCount) +{ + int nRowCount = 0; + + if (GetItemCount() > 0 && nColumnCount > 0) + { + nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount; + // nRowCount = GetOutputSizePixel().Height() / rItemSize.Height(); + if (nRowCount < 1) + nRowCount = 1; + } + + return nRowCount; +} + + + + +IMPL_LINK_NOARG(LayoutMenu, ClickHandler) +{ + AssignLayoutToSelectedSlides (GetSelectedAutoLayout()); + return 0; +} + + + + +/** The specified layout is assigned to the current page of the view shell + in the center pane. +*/ +void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout) +{ + using namespace ::sd::slidesorter; + using namespace ::sd::slidesorter::controller; + + do + { + // The view shell in the center pane has to be present. + ViewShell* pMainViewShell = mrBase.GetMainViewShell().get(); + if (pMainViewShell == NULL) + break; + + // Determine if the current view is in an invalid master page mode. + // The handout view is always in master page mode and therefore not + // invalid. + bool bMasterPageMode (false); + switch (pMainViewShell->GetShellType()) + { + case ViewShell::ST_NOTES: + case ViewShell::ST_IMPRESS: + { + DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell); + if (pDrawViewShell != NULL) + if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE) + bMasterPageMode = true; + } + default: + break; + } + if (bMasterPageMode) + break; + + // Get a list of all selected slides and call the SID_MODIFYPAGE + // slot for all of them. + ::sd::slidesorter::SharedPageSelection pPageSelection; + + // Get a list of selected pages. + // First we try to obtain this list from a slide sorter. This is + // possible only some of the view shells in the center pane. When + // no valid slide sorter is available then ask the main view shell + // for its current page. + SlideSorterViewShell* pSlideSorter = NULL; + switch (pMainViewShell->GetShellType()) + { + case ViewShell::ST_IMPRESS: + case ViewShell::ST_NOTES: + case ViewShell::ST_SLIDE_SORTER: + pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase); + break; + default: + break; + } + if (pSlideSorter != NULL) + { + // There is a slide sorter visible so get the list of selected pages from it. + pPageSelection = pSlideSorter->GetPageSelection(); + } + + if( (pSlideSorter == NULL) || (pPageSelection.get() == 0) || pPageSelection->empty() ) + { + // No valid slide sorter available. Ask the main view shell for + // its current page. + pPageSelection.reset(new ::sd::slidesorter::SlideSorterViewShell::PageSelection()); + pPageSelection->push_back(pMainViewShell->GetActualPage()); + } + + + if (pPageSelection->empty()) + break; + + ::std::vector<SdPage*>::iterator iPage; + for (iPage=pPageSelection->begin(); iPage!=pPageSelection->end(); ++iPage) + { + if ((*iPage) == NULL) + continue; + + // Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters. + SfxRequest aRequest (mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT); + aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, ((*iPage)->GetPageNum()-1)/2)); + aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout)); + pMainViewShell->ExecuteSlot (aRequest, sal_Bool(sal_False)); + } + } + while(false); +} + + + + +SfxRequest LayoutMenu::CreateRequest ( + sal_uInt16 nSlotId, + AutoLayout aLayout) +{ + SfxRequest aRequest (mrBase.GetViewFrame(), nSlotId); + + do + { + SdrLayerAdmin& rLayerAdmin (mrBase.GetDocument()->GetLayerAdmin()); + sal_uInt8 aBackground (rLayerAdmin.GetLayerID( + String(SdResId(STR_LAYER_BCKGRND)), sal_False)); + sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID( + String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False)); + ViewShell* pViewShell = mrBase.GetMainViewShell().get(); + if (pViewShell == NULL) + break; + SdPage* pPage = pViewShell->GetActualPage(); + if (pPage == NULL) + break; + + SetOfByte aVisibleLayers (pPage->TRG_GetMasterPageVisibleLayers()); + + aRequest.AppendItem( + SfxStringItem (ID_VAL_PAGENAME, String()));//pPage->GetName())); + aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout)); + aRequest.AppendItem( + SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground))); + aRequest.AppendItem( + SfxBoolItem( + ID_VAL_ISPAGEOBJ, + aVisibleLayers.IsSet(aBackgroundObject))); + } + while (false); + + return aRequest; +} + + + + +void LayoutMenu::Fill (void) +{ + SvtLanguageOptions aLanguageOptions; + sal_Bool bVertical = aLanguageOptions.IsVerticalTextEnabled(); + SdDrawDocument* pDocument = mrBase.GetDocument(); + sal_Bool bRightToLeft = (pDocument!=NULL + && pDocument->GetDefaultWritingMode() == WritingMode_RL_TB); + + // Get URL of the view in the center pane. + OUString sCenterPaneViewName; + try + { + Reference<XControllerManager> xControllerManager ( + Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY_THROW); + Reference<XResourceId> xPaneId (ResourceId::create( + ::comphelper::getProcessComponentContext(), + FrameworkHelper::msCenterPaneURL)); + Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId)); + if (xView.is()) + sCenterPaneViewName = xView->getResourceId()->getResourceURL(); + } + catch (RuntimeException&) + {} + + snewfoil_value_info* pInfo = NULL; + if (sCenterPaneViewName.equals(framework::FrameworkHelper::msNotesViewURL)) + { + pInfo = notes; + } + else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msHandoutViewURL)) + { + pInfo = handout; + } + else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msImpressViewURL) + || sCenterPaneViewName.equals(framework::FrameworkHelper::msSlideSorterURL)) + { + pInfo = standard; + } + else + { + pInfo = NULL; + } + + Clear(); + int n = 0; + for (sal_uInt16 i=1; pInfo!=NULL&&pInfo->mnBmpResId!=0; i++,pInfo++) + { + if ((WritingMode_TB_RL != pInfo->meWritingMode) || bVertical) + { + BitmapEx aBmp(SdResId(pInfo->mnBmpResId)); + + if (bRightToLeft && (WritingMode_TB_RL != pInfo->meWritingMode)) + aBmp.Mirror (BMP_MIRROR_HORZ); + + InsertItem (i, aBmp, String (SdResId (pInfo->mnStrResId))); + SetItemData (i, new AutoLayout(pInfo->maAutoLayout)); + n++; + } + } + + mbSelectionUpdatePending = true; +} + + + + +void LayoutMenu::Clear (void) +{ + for (sal_uInt16 nId=1; nId<=GetItemCount(); nId++) + delete static_cast<AutoLayout*>(GetItemData(nId)); + ValueSet::Clear(); +} + + + +void LayoutMenu::StartDrag (sal_Int8 , const Point& ) +{ +} + + + + +sal_Int8 LayoutMenu::AcceptDrop (const AcceptDropEvent& ) +{ + return 0; +} + + + + +sal_Int8 LayoutMenu::ExecuteDrop (const ExecuteDropEvent& ) +{ + return 0; +} + + + + +void LayoutMenu::Command (const CommandEvent& rEvent) +{ + switch (rEvent.GetCommand()) + { + case COMMAND_CONTEXTMENU: + if ( ! SD_MOD()->GetWaterCan()) + { + // Determine the position where to show the menu. + Point aMenuPosition; + if (rEvent.IsMouseEvent()) + { + if (GetItemId(rEvent.GetMousePosPixel()) <= 0) + return; + aMenuPosition = rEvent.GetMousePosPixel(); + } + else + { + if (GetSelectItemId() == (sal_uInt16)-1) + return; + Rectangle aBBox (GetItemRect(GetSelectItemId())); + aMenuPosition = aBBox.Center(); + } + + // Setup the menu. + ::boost::shared_ptr<PopupMenu> pMenu (new PopupMenu(SdResId(RID_TASKPANE_LAYOUTMENU_POPUP))); + FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow()); + if (pMenuWindow != NULL) + pMenuWindow->SetPopupModeFlags( + pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE); + pMenu->SetSelectHdl(LINK(this, LayoutMenu, OnMenuItemSelected)); + + // Disable the SID_INSERTPAGE_LAYOUT_MENU item when + // the document is read-only. + const SfxPoolItem* pItem = NULL; + const SfxItemState aState ( + mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem)); + if (aState == SFX_ITEM_DISABLED) + pMenu->EnableItem(SID_INSERTPAGE_LAYOUT_MENU, sal_False); + + // Show the menu. + pMenu->Execute(this, Rectangle(aMenuPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN); + } + break; + + default: + ValueSet::Command(rEvent); + break; + } +} + + + + +IMPL_LINK_NOARG(LayoutMenu, StateChangeHandler) +{ + InvalidateContent(); + return 0; +} + + + + +IMPL_LINK(LayoutMenu, OnMenuItemSelected, Menu*, pMenu) +{ + if (pMenu == NULL) + { + OSL_ENSURE(pMenu!=NULL, "LayoutMenu::OnMenuItemSelected: illegal menu!"); + return 0; + } + + pMenu->Deactivate(); + const sal_Int32 nIndex (pMenu->GetCurItemId()); + + if (nIndex == SID_TP_APPLY_TO_SELECTED_SLIDES) + { + AssignLayoutToSelectedSlides(GetSelectedAutoLayout()); + } + else if (nIndex == SID_INSERTPAGE_LAYOUT_MENU) + { + // Add arguments to this slot and forward it to the main view + // shell. + InsertPageWithLayout(GetSelectedAutoLayout()); + } + + return 0; +} + + + + +void LayoutMenu::UpdateSelection (void) +{ + bool bItemSelected = false; + + do + { + // Get current page of main view. + ViewShell* pViewShell = mrBase.GetMainViewShell().get(); + if (pViewShell == NULL) + break; + + SdPage* pCurrentPage = pViewShell->getCurrentPage(); + if (pCurrentPage == NULL) + break; + + // Get layout of current page. + AutoLayout aLayout (pCurrentPage->GetAutoLayout()); + if (aLayout<AUTOLAYOUT__START || aLayout>AUTOLAYOUT__END) + break; + + // Find the entry of the menu for to the layout. + sal_uInt16 nItemCount (GetItemCount()); + for (sal_uInt16 nId=1; nId<=nItemCount; nId++) + { + if (*static_cast<AutoLayout*>(GetItemData(nId)) == aLayout) + { + SelectItem(nId); + bItemSelected = true; + break; + } + } + } + while (false); + + if ( ! bItemSelected) + SetNoSelection(); +} + + + + +IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent) +{ + switch (pEvent->meEventId) + { + case ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE: + case ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION: + if ( ! mbSelectionUpdatePending) + UpdateSelection(); + break; + + case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED: + mbIsMainViewChangePending = true; + UpdateEnabledState(MM_UNKNOWN); + break; + + case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED: + HideFocus(); + break; + + case ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED: + if (mbIsMainViewChangePending) + { + mbIsMainViewChangePending = false; + InvalidateContent(); + } + break; + + case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL: + UpdateEnabledState(MM_NORMAL); + break; + + case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER: + UpdateEnabledState(MM_MASTER); + break; + + default: + /* Ignored */ + break; + } + + return 0; +} + + + + +IMPL_LINK(LayoutMenu, WindowEventHandler, VclWindowEvent*, pEvent) +{ + if (pEvent != NULL) + { + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_SHOW: + case VCLEVENT_WINDOW_RESIZE: + SetSizePixel(GetParent()->GetSizePixel()); + return sal_True; + + default: + return sal_False; + } + + const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, pEvent); + if (pSimpleHint != NULL + && pSimpleHint->GetId() == SFX_HINT_DYING) + { + return sal_True; + } + } + + return sal_False; +} + + + + +void LayoutMenu::DataChanged (const DataChangedEvent& rEvent) +{ + Fill(); + ValueSet::DataChanged(rEvent); + SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground)); + SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Paint_PanelBackground)); +} + + + + + +} } // end of namespace ::sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/LayoutMenu.hxx b/sd/source/ui/sidebar/LayoutMenu.hxx new file mode 100644 index 000000000000..eb8025860258 --- /dev/null +++ b/sd/source/ui/sidebar/LayoutMenu.hxx @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_LAYOUT_MENU_HXX +#define SD_SIDEBAR_LAYOUT_MENU_HXX + +#include "IDisposable.hxx" +#include "ISidebarReceiver.hxx" +#include <sfx2/sidebar/ILayoutableWindow.hxx> + +#include <com/sun/star/frame/XStatusListener.hpp> + +#include "glob.hxx" +#include "pres.hxx" + +#include <vcl/ctrl.hxx> +#include <svtools/valueset.hxx> +#include <svtools/transfer.hxx> +#include <sfx2/shell.hxx> + +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/ui/XSidebar.hpp> + + +class SfxModule; + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; + +namespace sd { +class DrawDocShell; +class ViewShellBase; +} + + +namespace sd { namespace tools { +class EventMultiplexerEvent; +} } + + +namespace sd { namespace sidebar { + +class ControlFactory; +class SidebarViewShell; +class SidebarShellManager; + + +class LayoutMenu + : public ValueSet, + public DragSourceHelper, + public DropTargetHelper, + public sfx2::sidebar::ILayoutableWindow +{ +public: + /** Create a new layout menu. Depending on the given flag it + displays its own scroll bar or lets a surrounding window + handle that. + @param i_pParent + the parent node in the control tree + @param i_rPanelViewShell + the view shell of the task pane. + */ + LayoutMenu ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + virtual ~LayoutMenu (void); + + virtual void Dispose (void); + + /** Return a numerical value representing the currently selected + layout. + */ + AutoLayout GetSelectedAutoLayout (void); + + Size GetPreferredSize (void); + sal_Int32 GetPreferredWidth (sal_Int32 nHeight); + sal_Int32 GetMinimumWidth (void); + + // From ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + + // From ::Window + virtual void Paint (const Rectangle& rRect); + virtual void Resize (void); + + /** Show a context menu when the right mouse button is pressed. + */ + virtual void MouseButtonDown (const MouseEvent& rEvent); + + /** The LayoutMenu does not support some main views. In this case the + LayoutMenu is disabled. This state is updated in this method. + @param eMode + On some occasions the edit mode is being switched when this + method is called can not (yet) be reliably detected. Luckily, + in these cases the new value is provided by some broadcaster. + On other occasions the edit mode is not modified and is also not + provided. Therefore the Unknown value. + */ + enum MasterMode { MM_NORMAL, MM_MASTER, MM_UNKNOWN }; + void UpdateEnabledState (const MasterMode eMode); + + /** Call this method when the set of displayed layouts is not up-to-date + anymore. It will re-assemple this set according to the current + settings. + */ + void InvalidateContent (void); + + // DragSourceHelper + virtual void StartDrag (sal_Int8 nAction, const Point& rPosPixel); + + // DropTargetHelper + virtual sal_Int8 AcceptDrop (const AcceptDropEvent& rEvent); + virtual sal_Int8 ExecuteDrop (const ExecuteDropEvent& rEvent); + + /** The context menu is requested over this Command() method. + */ + virtual void Command (const CommandEvent& rEvent); + + /** Call Fill() when switching to or from high contrast mode so that the + correct set of icons is displayed. + */ + virtual void DataChanged (const DataChangedEvent& rEvent); + + using Window::GetWindow; + using ValueSet::StartDrag; + +private: + ViewShellBase& mrBase; + + /** Do we use our own scroll bar or is viewport handling done by + our parent? + */ + bool mbUseOwnScrollBar; + + /** If we are asked for the preferred window size, then use this + many columns for the calculation. + */ + const int mnPreferredColumnCount; + cssu::Reference<css::frame::XStatusListener> mxListener; + bool mbSelectionUpdatePending; + bool mbIsMainViewChangePending; + cssu::Reference<css::ui::XSidebar> mxSidebar; + bool mbIsDisposed; + + /** Calculate the number of displayed rows. This depends on the given + item size, the given number of columns, and the size of the + control. Note that this is not the number of rows managed by the + valueset. This number may be larger. In that case a vertical + scroll bar is displayed. + */ + int CalculateRowCount (const Size& rItemSize, int nColumnCount); + + /** Fill the value set with the layouts that are applicable to the + current main view shell. + */ + void Fill (void); + + /** Remove all items from the value set. + */ + void Clear (void); + + /** Assign the given layout to all selected slides of a slide sorter. + If no slide sorter is active then this call is ignored. The slide + sorter in the center pane is preferred if the choice exists. + */ + void AssignLayoutToSelectedSlides (AutoLayout aLayout); + + /** Insert a new page with the given layout. The page is inserted via + the main view shell, i.e. its SID_INSERTPAGE slot is called. It it + does not support this slot then inserting a new page does not take + place. The new page is inserted after the currently active one (the + one returned by ViewShell::GetActualPage().) + */ + void InsertPageWithLayout (AutoLayout aLayout); + + /** Create a request structure that can be used with the SID_INSERTPAGE + and SID_MODIFYPAGE slots. The parameters are set so that the given + layout is assigned to the current page of the main view shell. + @param nSlotId + Supported slots are SID_INSERTPAGE and SID_MODIFYPAGE. + @param aLayout + Layout of the page to insert or to assign. + */ + SfxRequest CreateRequest ( + sal_uInt16 nSlotId, + AutoLayout aLayout); + + /** Select the layout that is used by the current page. + */ + void UpdateSelection (void); + + // internal ctor + void implConstruct( DrawDocShell& rDocumentShell ); + + /** When clicked then set the current page of the view in the center pane. + */ + DECL_LINK(ClickHandler, void *); + DECL_LINK(RightClickHandler, MouseEvent*); + DECL_LINK(StateChangeHandler, void *); + DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*); + DECL_LINK(WindowEventHandler, VclWindowEvent*); + DECL_LINK(OnMenuItemSelected, Menu*); +}; + +} } // end of namespace ::sd::toolpanel + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainer.cxx b/sd/source/ui/sidebar/MasterPageContainer.cxx new file mode 100644 index 000000000000..582a3fed43e3 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainer.cxx @@ -0,0 +1,1211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPageContainer.hxx" + +#include "MasterPageDescriptor.hxx" +#include "MasterPageContainerFiller.hxx" +#include "MasterPageContainerQueue.hxx" +#include "TemplateScanner.hxx" +#include "tools/AsynchronousTask.hxx" +#include "strings.hrc" +#include <algorithm> +#include <list> +#include <set> + +#include "unomodel.hxx" +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/util/XCloseable.hpp> +#include <comphelper/processfactory.hxx> +#include <sfx2/app.hxx> +#include <svx/svdpage.hxx> +#include "DrawDocShell.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include <svl/itemset.hxx> +#include <svl/eitem.hxx> +#include "sdresid.hxx" +#include "tools/TimerBasedTaskExecution.hxx" +#include "pres.hxx" +#include <osl/mutex.hxx> +#include <boost/weak_ptr.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace { + +typedef ::std::vector<sd::sidebar::SharedMasterPageDescriptor> MasterPageContainerType; + +} // end of anonymous namespace + + +namespace sd { namespace sidebar { + + +/** Inner implementation class of the MasterPageContainer. +*/ +class MasterPageContainer::Implementation + : public SdGlobalResource, + public MasterPageContainerFiller::ContainerAdapter, + public MasterPageContainerQueue::ContainerAdapter +{ +public: + mutable ::osl::Mutex maMutex; + + static ::boost::weak_ptr<Implementation> mpInstance; + MasterPageContainerType maContainer; + + static ::boost::shared_ptr<Implementation> Instance (void); + + void LateInit (void); + void AddChangeListener (const Link& rLink); + void RemoveChangeListener (const Link& rLink); + void UpdatePreviewSizePixel (void); + Size GetPreviewSizePixel (PreviewSize eSize) const; + + bool HasToken (Token aToken) const; + const SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken) const; + SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken); + virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor); + void InvalidatePreview (Token aToken); + Image GetPreviewForToken ( + Token aToken, + PreviewSize ePreviewSize); + PreviewState GetPreviewState (Token aToken) const; + bool RequestPreview (Token aToken); + + Reference<frame::XModel> GetModel (void); + SdDrawDocument* GetDocument (void); + + void FireContainerChange ( + MasterPageContainerChangeEvent::EventType eType, + Token aToken, + bool bNotifyAsynchronously = false); + + virtual bool UpdateDescriptor ( + const SharedMasterPageDescriptor& rpDescriptor, + bool bForcePageObject, + bool bForcePreview, + bool bSendEvents); + + void ReleaseDescriptor (Token aToken); + + /** Called by the MasterPageContainerFiller to notify that all master + pages from template documents have been added. + */ + virtual void FillingDone (void); + +private: + Implementation (void); + virtual ~Implementation (void); + + class Deleter { public: + void operator() (Implementation* pObject) { delete pObject; } + }; + friend class Deleter; + + enum InitializationState { NOT_INITIALIZED, INITIALIZING, INITIALIZED } meInitializationState; + + ::boost::scoped_ptr<MasterPageContainerQueue> mpRequestQueue; + ::com::sun::star::uno::Reference<com::sun::star::frame::XModel> mxModel; + SdDrawDocument* mpDocument; + PreviewRenderer maPreviewRenderer; + /** Remember whether the first page object has already been used to + determine the correct size ratio. + */ + bool mbFirstPageObjectSeen; + + // The widths for the previews contain two pixels for the border that is + // painted arround the preview. + static const int SMALL_PREVIEW_WIDTH = 72 + 2; + static const int LARGE_PREVIEW_WIDTH = 2*72 + 2; + + /** This substition of page preview shows "Preparing preview" and is + shown as long as the actual previews are not being present. + */ + Image maLargePreviewBeingCreated; + Image maSmallPreviewBeingCreated; + + /** This substition of page preview is shown when a preview can not be + created and thus is not available. + */ + Image maLargePreviewNotAvailable; + Image maSmallPreviewNotAvailable; + + ::std::vector<Link> maChangeListeners; + + // We have to remember the tasks for initialization and filling in case + // a MasterPageContainer object is destroyed before these tasks have + // been completed. + ::boost::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask; + + Size maSmallPreviewSizePixel; + Size maLargePreviewSizePixel; + bool mbPageRatioKnown; + + bool mbContainerCleaningPending; + + typedef ::std::pair<MasterPageContainerChangeEvent::EventType,Token> EventData; + DECL_LINK(AsynchronousNotifyCallback, EventData*); + ::sd::DrawDocShell* LoadDocument ( + const String& sFileName, + SfxObjectShellLock& rxDocumentShell); + + Image GetPreviewSubstitution (sal_uInt16 nId, PreviewSize ePreviewSize); + + void CleanContainer (void); +}; + + + + +//===== MasterPageContainer =================================================== + +::boost::weak_ptr<MasterPageContainer::Implementation> + MasterPageContainer::Implementation::mpInstance; +static const MasterPageContainer::Token NIL_TOKEN (-1); + + + + +::boost::shared_ptr<MasterPageContainer::Implementation> + MasterPageContainer::Implementation::Instance (void) +{ + ::boost::shared_ptr<MasterPageContainer::Implementation> pInstance; + + if (Implementation::mpInstance.expired()) + { + ::osl::GetGlobalMutex aMutexFunctor; + ::osl::MutexGuard aGuard (aMutexFunctor()); + if (Implementation::mpInstance.expired()) + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>( + new MasterPageContainer::Implementation(), + MasterPageContainer::Implementation::Deleter()); + SdGlobalResourceContainer::Instance().AddResource(pInstance); + Implementation::mpInstance = pInstance; + } + else + pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>( + Implementation::mpInstance); + } + else + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>( + Implementation::mpInstance); + } + + DBG_ASSERT (pInstance.get()!=NULL, + "MasterPageContainer::Implementation::Instance(): instance is NULL"); + return pInstance; +} + + + + +MasterPageContainer::MasterPageContainer (void) + : mpImpl(Implementation::Instance()), + mePreviewSize(SMALL) +{ + mpImpl->LateInit(); +} + + + + +MasterPageContainer::~MasterPageContainer (void) +{ +} + + + + +void MasterPageContainer::AddChangeListener (const Link& rLink) +{ + mpImpl->AddChangeListener(rLink); +} + + + + +void MasterPageContainer::RemoveChangeListener (const Link& rLink) +{ + mpImpl->RemoveChangeListener(rLink); +} + + + + +void MasterPageContainer::SetPreviewSize (PreviewSize eSize) +{ + mePreviewSize = eSize; + mpImpl->FireContainerChange( + MasterPageContainerChangeEvent::SIZE_CHANGED, + NIL_TOKEN); +} + + + + +MasterPageContainer::PreviewSize MasterPageContainer::GetPreviewSize (void) const +{ + return mePreviewSize; +} + + + + +Size MasterPageContainer::GetPreviewSizePixel (void) const +{ + return mpImpl->GetPreviewSizePixel(mePreviewSize); +} + + + + +MasterPageContainer::Token MasterPageContainer::PutMasterPage ( + const SharedMasterPageDescriptor& rDescriptor) +{ + return mpImpl->PutMasterPage(rDescriptor); +} + + + + +void MasterPageContainer::AcquireToken (Token aToken) +{ + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + { + ++pDescriptor->mnUseCount; + } +} + + + + +void MasterPageContainer::ReleaseToken (Token aToken) +{ + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + { + OSL_ASSERT(pDescriptor->mnUseCount>0); + --pDescriptor->mnUseCount; + if (pDescriptor->mnUseCount <= 0) + { + switch (pDescriptor->meOrigin) + { + case DEFAULT: + case TEMPLATE: + default: + break; + + case MASTERPAGE: + mpImpl->ReleaseDescriptor(aToken); + break; + } + } + } +} + + + + +int MasterPageContainer::GetTokenCount (void) const +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + return mpImpl->maContainer.size(); +} + + + + +bool MasterPageContainer::HasToken (Token aToken) const +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + return mpImpl->HasToken(aToken); +} + + + + +MasterPageContainer::Token MasterPageContainer::GetTokenForIndex (int nIndex) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Token aResult (NIL_TOKEN); + if (HasToken(nIndex)) + aResult = mpImpl->maContainer[nIndex]->maToken; + return aResult; +} + + + + +MasterPageContainer::Token MasterPageContainer::GetTokenForURL ( + const String& sURL) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Token aResult (NIL_TOKEN); + if (sURL.Len() > 0) + { + MasterPageContainerType::iterator iEntry ( + ::std::find_if ( + mpImpl->maContainer.begin(), + mpImpl->maContainer.end(), + MasterPageDescriptor::URLComparator(sURL))); + if (iEntry != mpImpl->maContainer.end()) + aResult = (*iEntry)->maToken; + } + return aResult; +} + + + + +MasterPageContainer::Token MasterPageContainer::GetTokenForStyleName (const String& sStyleName) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Token aResult (NIL_TOKEN); + if (sStyleName.Len() > 0) + { + MasterPageContainerType::iterator iEntry ( + ::std::find_if ( + mpImpl->maContainer.begin(), + mpImpl->maContainer.end(), + MasterPageDescriptor::StyleNameComparator(sStyleName))); + if (iEntry != mpImpl->maContainer.end()) + aResult = (*iEntry)->maToken; + } + return aResult; +} + + + + +MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject ( + const SdPage* pPage) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + Token aResult (NIL_TOKEN); + if (pPage != NULL) + { + MasterPageContainerType::iterator iEntry ( + ::std::find_if ( + mpImpl->maContainer.begin(), + mpImpl->maContainer.end(), + MasterPageDescriptor::PageObjectComparator(pPage))); + if (iEntry != mpImpl->maContainer.end()) + aResult = (*iEntry)->maToken; + } + return aResult; +} + + + + +String MasterPageContainer::GetURLForToken ( + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return pDescriptor->msURL; + else + return String(); +} + + + + +String MasterPageContainer::GetPageNameForToken ( + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return pDescriptor->msPageName; + else + return String(); +} + + + + +String MasterPageContainer::GetStyleNameForToken ( + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return pDescriptor->msStyleName; + else + return String(); +} + + + + +SdPage* MasterPageContainer::GetPageObjectForToken ( + MasterPageContainer::Token aToken, + bool bLoad) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SdPage* pPageObject = NULL; + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + { + pPageObject = pDescriptor->mpMasterPage; + if (pPageObject == NULL) + { + // The page object is not (yet) present. Call + // UpdateDescriptor() to trigger the PageObjectProvider() to + // provide it. + if (bLoad) + mpImpl->GetModel(); + if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true)) + pPageObject = pDescriptor->mpMasterPage; + } + } + return pPageObject; +} + + + + +MasterPageContainer::Origin MasterPageContainer::GetOriginForToken (Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return pDescriptor->meOrigin; + else + return UNKNOWN; +} + + + + +sal_Int32 MasterPageContainer::GetTemplateIndexForToken (Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return pDescriptor->mnTemplateIndex; + else + return -1; +} + + + + +SharedMasterPageDescriptor MasterPageContainer::GetDescriptorForToken ( + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (mpImpl->maMutex); + + return mpImpl->GetDescriptor(aToken); +} + + + +void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken) +{ + mpImpl->InvalidatePreview(aToken); +} + + + + +Image MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken) +{ + return mpImpl->GetPreviewForToken(aToken,mePreviewSize); +} + + + + +MasterPageContainer::PreviewState MasterPageContainer::GetPreviewState (Token aToken) +{ + return mpImpl->GetPreviewState(aToken); +} + + + + +bool MasterPageContainer::RequestPreview (Token aToken) +{ + return mpImpl->RequestPreview(aToken); +} + + + + +//==== Implementation ================================================ + +MasterPageContainer::Implementation::Implementation (void) + : maMutex(), + maContainer(), + meInitializationState(NOT_INITIALIZED), + mpRequestQueue(NULL), + mxModel(NULL), + mpDocument(NULL), + maPreviewRenderer(), + mbFirstPageObjectSeen(false), + maLargePreviewBeingCreated(), + maSmallPreviewBeingCreated(), + maLargePreviewNotAvailable(), + maSmallPreviewNotAvailable(), + maChangeListeners(), + maSmallPreviewSizePixel(), + maLargePreviewSizePixel(), + mbPageRatioKnown(false), + mbContainerCleaningPending(true) + +{ + UpdatePreviewSizePixel(); +} + + + + +MasterPageContainer::Implementation::~Implementation (void) +{ + // When the initializer or filler tasks are still running then we have + // to stop them now in order to prevent them from calling us back. + tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask); + + mpRequestQueue.reset(); + + uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY); + if (xCloseable.is()) + { + try + { + xCloseable->close(true); + } + catch (const ::com::sun::star::util::CloseVetoException&) + { + } + } + mxModel = NULL; +} + + + + +void MasterPageContainer::Implementation::LateInit (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + if (meInitializationState == NOT_INITIALIZED) + { + meInitializationState = INITIALIZING; + + OSL_ASSERT(Instance().get()==this); + mpRequestQueue.reset(MasterPageContainerQueue::Create( + ::boost::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance()))); + + mpFillerTask = ::sd::tools::TimerBasedTaskExecution::Create( + ::boost::shared_ptr<tools::AsynchronousTask>(new MasterPageContainerFiller(*this)), + 5, + 50); + + meInitializationState = INITIALIZED; + } +} + + + + +void MasterPageContainer::Implementation::AddChangeListener (const Link& rLink) +{ + const ::osl::MutexGuard aGuard (maMutex); + + ::std::vector<Link>::iterator iListener ( + ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink)); + if (iListener == maChangeListeners.end()) + maChangeListeners.push_back(rLink); + +} + + + + +void MasterPageContainer::Implementation::RemoveChangeListener (const Link& rLink) +{ + const ::osl::MutexGuard aGuard (maMutex); + + ::std::vector<Link>::iterator iListener ( + ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink)); + if (iListener != maChangeListeners.end()) + maChangeListeners.erase(iListener); +} + + + + +void MasterPageContainer::Implementation::UpdatePreviewSizePixel (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + // The default aspect ratio is 4:3 + int nWidth (4); + int nHeight (3); + + // Search for the first entry with an existing master page. + MasterPageContainerType::const_iterator iDescriptor; + MasterPageContainerType::const_iterator iContainerEnd(maContainer.end()); + for (iDescriptor=maContainer.begin(); iDescriptor!=iContainerEnd; ++iDescriptor) + if (*iDescriptor!=NULL && (*iDescriptor)->mpMasterPage != NULL) + { + Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize()); + OSL_ASSERT(aPageSize.Width() > 0 && aPageSize.Height() > 0); + if (aPageSize.Width() > 0) + nWidth = aPageSize.Width(); + if (aPageSize.Height() > 0) + nHeight = aPageSize.Height(); + mbFirstPageObjectSeen = true; + break; + } + + maSmallPreviewSizePixel.Width() = SMALL_PREVIEW_WIDTH; + maLargePreviewSizePixel.Width() = LARGE_PREVIEW_WIDTH; + + int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2); + int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2); + + if (nNewSmallHeight!=maSmallPreviewSizePixel.Height() + || nNewLargeHeight!=maLargePreviewSizePixel.Height()) + { + maSmallPreviewSizePixel.Height() = nNewSmallHeight; + maLargePreviewSizePixel.Height() = nNewLargeHeight; + FireContainerChange( + MasterPageContainerChangeEvent::SIZE_CHANGED, + NIL_TOKEN); + } +} + + + + +Size MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize) const +{ + if (eSize == SMALL) + return maSmallPreviewSizePixel; + else + return maLargePreviewSizePixel; +} + + + + +IMPL_LINK(MasterPageContainer::Implementation,AsynchronousNotifyCallback, EventData*, pData) +{ + const ::osl::MutexGuard aGuard (maMutex); + + if (pData != NULL) + { + FireContainerChange(pData->first, pData->second, false); + delete pData; + } + + return 0; +} + + + + +MasterPageContainer::Token MasterPageContainer::Implementation::PutMasterPage ( + const SharedMasterPageDescriptor& rpDescriptor) +{ + const ::osl::MutexGuard aGuard (maMutex); + + Token aResult (NIL_TOKEN); + + // Get page object and preview when that is inexpensive. + UpdateDescriptor(rpDescriptor,false,false, false); + + // Look up the new MasterPageDescriptor and either insert it or update + // an already existing one. + MasterPageContainerType::iterator aEntry ( + ::std::find_if ( + maContainer.begin(), + maContainer.end(), + MasterPageDescriptor::AllComparator(rpDescriptor))); + if (aEntry == maContainer.end()) + { + // Insert a new MasterPageDescriptor. + bool bIgnore (rpDescriptor->mpPageObjectProvider.get()==NULL + && rpDescriptor->msURL.isEmpty()); + + if ( ! bIgnore) + { + if (mbContainerCleaningPending) + CleanContainer(); + + aResult = maContainer.size(); + rpDescriptor->SetToken(aResult); + + // Templates are precious, i.e. we lock them so that they will + // not be destroyed when (temporarily) no one references them. + // They will only be deleted when the container is destroyed. + switch (rpDescriptor->meOrigin) + { + case TEMPLATE: + case DEFAULT: + ++rpDescriptor->mnUseCount; + break; + + default: + break; + } + + maContainer.push_back(rpDescriptor); + aEntry = maContainer.end()-1; + + FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED,aResult); + } + } + else + { + // Update an existing MasterPageDescriptor. + aResult = (*aEntry)->maToken; + ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes( + (*aEntry)->Update(*rpDescriptor)); + if (pEventTypes.get()!=NULL && pEventTypes->size()>0) + { + // One or more aspects of the descriptor have changed. Send + // appropriate events to the listeners. + UpdateDescriptor(*aEntry,false,false, true); + + std::vector<MasterPageContainerChangeEvent::EventType>::const_iterator iEventType; + for (iEventType=pEventTypes->begin(); iEventType!=pEventTypes->end(); ++iEventType) + { + FireContainerChange( + *iEventType, + (*aEntry)->maToken, + false); + } + } + } + + return aResult; +} + + + + +bool MasterPageContainer::Implementation::HasToken (Token aToken) const +{ + return aToken>=0 + && (unsigned)aToken<maContainer.size() + && maContainer[aToken].get()!=NULL; +} + + + + +const SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor ( + Token aToken) const +{ + if (aToken>=0 && (unsigned)aToken<maContainer.size()) + return maContainer[aToken]; + else + return SharedMasterPageDescriptor(); +} + + + + +SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken) +{ + if (aToken>=0 && (unsigned)aToken<maContainer.size()) + return maContainer[aToken]; + else + return SharedMasterPageDescriptor(); +} + + + + +void MasterPageContainer::Implementation::InvalidatePreview (Token aToken) +{ + const ::osl::MutexGuard aGuard (maMutex); + + SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken)); + if (pDescriptor.get() != NULL) + { + pDescriptor->maSmallPreview = Image(); + pDescriptor->maLargePreview = Image(); + RequestPreview(aToken); + } +} + + + + +Image MasterPageContainer::Implementation::GetPreviewForToken ( + MasterPageContainer::Token aToken, + PreviewSize ePreviewSize) +{ + const ::osl::MutexGuard aGuard (maMutex); + + Image aPreview; + PreviewState ePreviewState (GetPreviewState(aToken)); + + SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken); + + // When the preview is missing but inexpensively creatable then do that + // now. + if (pDescriptor.get()!=NULL) + { + if (ePreviewState == PS_CREATABLE) + if (UpdateDescriptor(pDescriptor, false,false, true)) + if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0) + ePreviewState = PS_AVAILABLE; + + switch (ePreviewState) + { + case PS_AVAILABLE: + aPreview = pDescriptor->GetPreview(ePreviewSize); + break; + + case PS_PREPARING: + aPreview = GetPreviewSubstitution( + STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION, + ePreviewSize); + break; + + case PS_CREATABLE: + aPreview = GetPreviewSubstitution( + STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION, + ePreviewSize); + break; + + case PS_NOT_AVAILABLE: + aPreview = GetPreviewSubstitution( + STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION, + ePreviewSize); + if (ePreviewSize == SMALL) + pDescriptor->maSmallPreview = aPreview; + else + pDescriptor->maLargePreview = aPreview; + break; + } + } + + return aPreview; +} + + + + +MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState ( + Token aToken) const +{ + const ::osl::MutexGuard aGuard (maMutex); + + PreviewState eState (PS_NOT_AVAILABLE); + + SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + { + if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0) + eState = PS_AVAILABLE; + else if (pDescriptor->mpPreviewProvider.get() != NULL) + { + // The preview does not exist but can be created. When that is + // not expensive then do it at once. + if (mpRequestQueue->HasRequest(aToken)) + eState = PS_PREPARING; + else + eState = PS_CREATABLE; + } + else + eState = PS_NOT_AVAILABLE; + } + + return eState; +} + + + + +bool MasterPageContainer::Implementation::RequestPreview (Token aToken) +{ + SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken); + if (pDescriptor.get() != NULL) + return mpRequestQueue->RequestPreview(pDescriptor); + else + return false; +} + + + + +Reference<frame::XModel> MasterPageContainer::Implementation::GetModel (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + if ( ! mxModel.is()) + { + // Get the desktop a s service factory. + uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create( + ::comphelper::getProcessComponentContext() ); + + // Create a new model. + OUString sModelServiceName ( "com.sun.star.presentation.PresentationDocument"); + mxModel = uno::Reference<frame::XModel>( + ::comphelper::getProcessServiceFactory()->createInstance( + sModelServiceName), + uno::UNO_QUERY); + + // Initialize the model. + uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY); + if (xLoadable.is()) + xLoadable->initNew(); + + // Use its tunnel to get a pointer to its core implementation. + uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY); + if (xUnoTunnel.is()) + { + mpDocument = reinterpret_cast<SdXImpressDocument*>( + xUnoTunnel->getSomething( + SdXImpressDocument::getUnoTunnelId()))->GetDoc(); + } + + // Create a default page. + uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY); + if (xSlideSupplier.is()) + { + uno::Reference<drawing::XDrawPages> xSlides ( + xSlideSupplier->getDrawPages(), uno::UNO_QUERY); + if (xSlides.is()) + { + sal_Int32 nIndex (0); + uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(nIndex)); + uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY); + if (xProperties.is()) + xProperties->setPropertyValue( + "Layout", + makeAny((sal_Int16)AUTOLAYOUT_TITLE)); + } + } + } + return mxModel; +} + + + + +SdDrawDocument* MasterPageContainer::Implementation::GetDocument (void) +{ + GetModel(); + return mpDocument; +} + + + + +Image MasterPageContainer::Implementation::GetPreviewSubstitution ( + sal_uInt16 nId, + PreviewSize ePreviewSize) +{ + const ::osl::MutexGuard aGuard (maMutex); + + Image aPreview; + + switch (nId) + { + case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION: + { + Image& rPreview (ePreviewSize==SMALL + ? maSmallPreviewBeingCreated + : maLargePreviewBeingCreated); + if (rPreview.GetSizePixel().Width() == 0) + { + rPreview = maPreviewRenderer.RenderSubstitution( + ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel, + SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION)); + } + aPreview = rPreview; + } + break; + + case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION: + { + Image& rPreview (ePreviewSize==SMALL + ? maSmallPreviewNotAvailable + : maLargePreviewNotAvailable); + if (rPreview.GetSizePixel().Width() == 0) + { + rPreview = maPreviewRenderer.RenderSubstitution( + ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel, + SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION)); + } + aPreview = rPreview; + } + break; + } + + return aPreview; +} + + + + +void MasterPageContainer::Implementation::CleanContainer (void) +{ + // Remove the empty elements at the end of the container. The empty + // elements in the middle can not be removed because that would + // invalidate the references still held by others. + int nIndex (maContainer.size()-1); + while (nIndex>=0 && maContainer[nIndex].get()==NULL) + --nIndex; + maContainer.resize(++nIndex); +} + + + + +void MasterPageContainer::Implementation::FireContainerChange ( + MasterPageContainerChangeEvent::EventType eType, + Token aToken, + bool bNotifyAsynchronously) +{ + if (bNotifyAsynchronously) + { + Application::PostUserEvent( + LINK(this,Implementation,AsynchronousNotifyCallback), + new EventData(eType,aToken)); + } + else + { + ::std::vector<Link> aCopy(maChangeListeners.begin(),maChangeListeners.end()); + ::std::vector<Link>::iterator iListener; + MasterPageContainerChangeEvent aEvent; + aEvent.meEventType = eType; + aEvent.maChildToken = aToken; + for (iListener=aCopy.begin(); iListener!=aCopy.end(); ++iListener) + iListener->Call(&aEvent); + } +} + + + + +bool MasterPageContainer::Implementation::UpdateDescriptor ( + const SharedMasterPageDescriptor& rpDescriptor, + bool bForcePageObject, + bool bForcePreview, + bool bSendEvents) +{ + const ::osl::MutexGuard aGuard (maMutex); + + // We have to create the page object when the preview provider needs it + // and the caller needs the preview. + bForcePageObject |= (bForcePreview + && rpDescriptor->mpPreviewProvider->NeedsPageObject() + && rpDescriptor->mpMasterPage==NULL); + + // Define a cost threshold so that an update or page object or preview + // that is at least this cost are made at once. Updates with higher cost + // are scheduled for later. + sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0); + + // Update the page object (which may be used for the preview update). + if (bForcePageObject) + GetDocument(); + int nPageObjectModified (rpDescriptor->UpdatePageObject( + (bForcePageObject ? -1 : nCostThreshold), + mpDocument)); + if (nPageObjectModified == 1 && bSendEvents) + FireContainerChange( + MasterPageContainerChangeEvent::DATA_CHANGED, + rpDescriptor->maToken); + if (nPageObjectModified == -1 && bSendEvents) + FireContainerChange( + MasterPageContainerChangeEvent::CHILD_REMOVED, + rpDescriptor->maToken); + if (nPageObjectModified && ! mbFirstPageObjectSeen) + UpdatePreviewSizePixel(); + + // Update the preview. + bool bPreviewModified (rpDescriptor->UpdatePreview( + (bForcePreview ? -1 : nCostThreshold), + maSmallPreviewSizePixel, + maLargePreviewSizePixel, + maPreviewRenderer)); + + if (bPreviewModified && bSendEvents) + FireContainerChange( + MasterPageContainerChangeEvent::PREVIEW_CHANGED, + rpDescriptor->maToken); + + return nPageObjectModified || bPreviewModified; +} + + + + +void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken) +{ + if (aToken>=0 && (unsigned)aToken<maContainer.size()) + { + maContainer[aToken].reset(); + mbContainerCleaningPending = true; + } +} + + + + +void MasterPageContainer::Implementation::FillingDone (void) +{ + mpRequestQueue->ProcessAllRequests(); +} + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainer.hxx b/sd/source/ui/sidebar/MasterPageContainer.hxx new file mode 100644 index 000000000000..b67bf8a48b26 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainer.hxx @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_HXX + +#include "MasterPageContainerProviders.hxx" + +#include <osl/mutex.hxx> +#include <tools/string.hxx> +#include <vcl/image.hxx> +#include <memory> +#include "PreviewRenderer.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <vcl/timer.hxx> +#include "tools/SdGlobalResourceContainer.hxx" + +#include <boost/shared_ptr.hpp> + +class SdPage; + +namespace sd { namespace sidebar { + +class MasterPageDescriptor; + +/** This container manages the master pages used by the MasterPagesSelector + controls. It uses internally a singleton implementation object. + Therefore, all MasterPageContainer object operator on the same set of + master pages. Each MasterPageContainer, however, has its own + PreviewSize value and thus can independantly switch between large and + small previews. + + The container maintains its own document to store master page objects. + + For each master page container stores its URL, preview bitmap, page + name, and, if available, the page object. + + Entries are accessed via a Token, which is mostly a numerical index but + whose values do not necessarily have to be consecutive. +*/ +class MasterPageContainer +{ +public: + typedef int Token; + static const Token NIL_TOKEN = -1; + + MasterPageContainer (void); + virtual ~MasterPageContainer (void); + + void AddChangeListener (const Link& rLink); + void RemoveChangeListener (const Link& rLink); + + enum PreviewSize { SMALL, LARGE }; + /** There are two different preview sizes, a small one and a large one. + Which one is used by the called container can be changed with this + method. + When the preview size is changed then all change listeners are + notified of this. + */ + void SetPreviewSize (PreviewSize eSize); + + /** Returns the preview size. + */ + PreviewSize GetPreviewSize (void) const; + + /** Return the preview size in pixels. + */ + Size GetPreviewSizePixel (void) const; + + enum PreviewState { PS_AVAILABLE, PS_CREATABLE, PS_PREPARING, PS_NOT_AVAILABLE }; + PreviewState GetPreviewState (Token aToken); + + /** This method is typically called for entries in the container for + which GetPreviewState() returns OS_CREATABLE. The creation of the + preview is then scheduled to be executed asynchronously at a later + point in time. When the preview is available the change listeners + will be notified. + */ + bool RequestPreview (Token aToken); + + /** Each entry of the container is either the first page of a template + document or is a master page of an Impress document. + */ + enum Origin { + MASTERPAGE, // Master page of a document. + TEMPLATE, // First page of a template file. + DEFAULT, // Empty master page with default style. + UNKNOWN + }; + + /** Put the master page identified and described by the given parameters + into the container. When there already is a master page with the + given URL, page name, or object pointer (when that is not NULL) then + the existing entry is replaced/updated by the given one. Otherwise + a new entry is inserted. + */ + Token PutMasterPage (const ::boost::shared_ptr<MasterPageDescriptor>& rDescriptor); + void AcquireToken (Token aToken); + void ReleaseToken (Token aToken); + + /** This and the GetTokenForIndex() methods can be used to iterate over + all members of the container. + */ + int GetTokenCount (void) const; + + /** Determine whether the container has a member for the given token. + */ + bool HasToken (Token aToken) const; + + /** Return a token for an index in the range + 0 <= index < GetTokenCount(). + */ + Token GetTokenForIndex (int nIndex); + + Token GetTokenForURL (const String& sURL); + Token GetTokenForStyleName (const String& sStyleName); + Token GetTokenForPageObject (const SdPage* pPage); + + String GetURLForToken (Token aToken); + String GetPageNameForToken (Token aToken); + String GetStyleNameForToken (Token aToken); + SdPage* GetPageObjectForToken (Token aToken, bool bLoad=true); + Origin GetOriginForToken (Token aToken); + sal_Int32 GetTemplateIndexForToken (Token aToken); + ::boost::shared_ptr<MasterPageDescriptor> GetDescriptorForToken (Token aToken); + + void InvalidatePreview (Token aToken); + + /** Return a preview for the specified token. When the preview is not + present then the PreviewProvider associated with the token is + executed only when that is not expensive. It is the responsibility + of the caller to call RequestPreview() to do the same + (asynchronously) for expensive PreviewProviders. + Call GetPreviewState() to find out if that is necessary. + @param aToken + This token specifies for which master page to return the prview. + Tokens are returned for example by the GetTokenFor...() methods. + @return + The returned image is the requested preview or a substitution. + */ + Image GetPreviewForToken (Token aToken); + +private: + class Implementation; + ::boost::shared_ptr<Implementation> mpImpl; + PreviewSize mePreviewSize; + + /** Retrieve the preview of the document specified by the given URL. + */ + static BitmapEx LoadPreviewFromURL (const OUString& aURL); +}; + + + + +/** For some changes to the set of master pages in a MasterPageContainer or + to the data stored for each master page one or more events are sent to + registered listeners. + Each event has an event type and a token that tells the listener where + the change took place. +*/ +class MasterPageContainerChangeEvent +{ +public: + enum EventType { + // A master page was added to the container. + CHILD_ADDED, + // A master page was removed from the container. + CHILD_REMOVED, + // The preview of a master page has changed. + PREVIEW_CHANGED, + // The size of a preview has changed. + SIZE_CHANGED, + // Some of the data stored for a master page has changed. + DATA_CHANGED, + // The TemplateIndex of a master page has changed. + INDEX_CHANGED, + // More than one entries changed their TemplateIndex + INDEXES_CHANGED + } meEventType; + + // Token of the container entry whose data changed or which was added or + // removed. + MasterPageContainer::Token maChildToken; +}; + + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerFiller.cxx b/sd/source/ui/sidebar/MasterPageContainerFiller.cxx new file mode 100644 index 000000000000..cec5047fb05b --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerFiller.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPageContainerFiller.hxx" + +#include "MasterPageDescriptor.hxx" +#include "MasterPageContainerProviders.hxx" +#include "TemplateScanner.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + +namespace sd { namespace sidebar { + +MasterPageContainerFiller::MasterPageContainerFiller (ContainerAdapter& rpAdapter) + : mrContainerAdapter(rpAdapter), + meState(INITIALIZE_TEMPLATE_SCANNER), + mpScannerTask(), + mpLastAddedEntry(NULL), + mnIndex(1) +{ + // Add one entry for the default master page. We use temporarily the + // DefaultPagePreviewProvider to prevent the rendering (and the + // expensive creation) of the default page. It is replaced later on by + // another. + SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor( + MasterPageContainer::DEFAULT, + 0, + String(), + String(), + String(), + false, + ::boost::shared_ptr<PageObjectProvider>(new DefaultPageObjectProvider()), + ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider()))); + mrContainerAdapter.PutMasterPage(pDescriptor); +} + + + + +MasterPageContainerFiller::~MasterPageContainerFiller (void) +{ +} + + + + +void MasterPageContainerFiller::RunNextStep (void) +{ + switch (meState) + { + case INITIALIZE_TEMPLATE_SCANNER: + mpScannerTask.reset(new TemplateScanner()); + meState = SCAN_TEMPLATE; + break; + + case SCAN_TEMPLATE: + meState = ScanTemplate(); + break; + + case ADD_TEMPLATE: + meState = AddTemplate(); + break; + + case DONE: + case ERROR: + default: + break; + } + + // When the state has just been set to DONE or ERROR then tell the + // container that no more templates will be coming and stop the + // scanning. + switch (meState) + { + case DONE: + case ERROR: + if (mpScannerTask.get() != NULL) + { + mrContainerAdapter.FillingDone(); + mpScannerTask.reset(); + } + default: + break; + } +} + + + + +bool MasterPageContainerFiller::HasNextStep (void) +{ + switch (meState) + { + case DONE: + case ERROR: + return false; + + default: + return true; + } +} + + + + +MasterPageContainerFiller::State MasterPageContainerFiller::ScanTemplate (void) +{ + State eState (ERROR); + + if (mpScannerTask.get() != NULL) + { + if (mpScannerTask->HasNextStep()) + { + mpScannerTask->RunNextStep(); + if (mpScannerTask->GetLastAddedEntry() != mpLastAddedEntry) + { + mpLastAddedEntry = mpScannerTask->GetLastAddedEntry(); + if (mpLastAddedEntry != NULL) + eState = ADD_TEMPLATE; + else + eState = SCAN_TEMPLATE; + } + else + eState = SCAN_TEMPLATE; + } + else + eState = DONE; + } + + return eState; +} + + + + +MasterPageContainerFiller::State MasterPageContainerFiller::AddTemplate (void) +{ + if (mpLastAddedEntry != NULL) + { + SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor( + MasterPageContainer::TEMPLATE, + mnIndex, + mpLastAddedEntry->msPath, + mpLastAddedEntry->msTitle, + String(), + false, + ::boost::shared_ptr<PageObjectProvider>( + new TemplatePageObjectProvider(mpLastAddedEntry->msPath)), + ::boost::shared_ptr<PreviewProvider>( + new TemplatePreviewProvider(mpLastAddedEntry->msPath)))); + // For user supplied templates we use a different preview provider: + // The preview in the document shows not only shapes on the master + // page but also shapes on the foreground. This is misleading and + // therefore these previews are discarded and created directly from + // the page objects. + if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER) + pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>( + new PagePreviewProvider()); + + mrContainerAdapter.PutMasterPage(pDescriptor); + ++mnIndex; + } + + return SCAN_TEMPLATE; +} + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerFiller.hxx b/sd/source/ui/sidebar/MasterPageContainerFiller.hxx new file mode 100644 index 000000000000..46b73b07da6c --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerFiller.hxx @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_FILLER_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_FILLER_HXX + +#include "MasterPageContainer.hxx" +#include "MasterPageDescriptor.hxx" +#include "tools/AsynchronousTask.hxx" + +namespace sd { +class TemplateScanner; +class TemplateEntry; +} + +namespace sd { namespace sidebar { + +/** Fill a MasterPageContainer with information about the available master + pages. These are provided by one default page and from the existing + Impress templates. This is done asynchronously. +*/ +class MasterPageContainerFiller + : public ::sd::tools::AsynchronousTask +{ +public: + class ContainerAdapter + { + public: + virtual MasterPageContainer::Token PutMasterPage ( + const SharedMasterPageDescriptor& rpDescriptor) = 0; + /** This method is called when all Impress templates have been added + to the container via the PutMasterPage() method. + */ + virtual void FillingDone (void) = 0; + + protected: + ~ContainerAdapter() {} + }; + + MasterPageContainerFiller (ContainerAdapter& rContainerAdapter); + virtual ~MasterPageContainerFiller (void); + + /** Run the next step of the task. After HasNextStep() returns false + this method should ignore further calls. + */ + virtual void RunNextStep (void); + + /** Return <TRUE/> when there is at least one more step to execute. + When the task has been executed completely then <FALSE/> is + returned. + */ + virtual bool HasNextStep (void); + +private: + ContainerAdapter& mrContainerAdapter; + // Remember what the next step has to do. + enum State { + INITIALIZE_TEMPLATE_SCANNER, + SCAN_TEMPLATE, + ADD_TEMPLATE, + ERROR, + DONE + } meState; + ::std::auto_ptr<TemplateScanner> mpScannerTask; + const TemplateEntry* mpLastAddedEntry; + int mnIndex; + + State ScanTemplate (void); + State AddTemplate (void); +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerProviders.cxx b/sd/source/ui/sidebar/MasterPageContainerProviders.cxx new file mode 100644 index 000000000000..448b8c8d60c7 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerProviders.cxx @@ -0,0 +1,403 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPageContainerProviders.hxx" + +#include "DrawDocShell.hxx" +#include "drawdoc.hxx" +#include "PreviewRenderer.hxx" +#include <comphelper/processfactory.hxx> +#include <sfx2/app.hxx> +#include <sfx2/sfxsids.hrc> +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/image.hxx> +#include <vcl/pngread.hxx> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/StorageFactory.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd { namespace sidebar { + + +//===== PagePreviewProvider =================================================== + +PagePreviewProvider::PagePreviewProvider (void) +{ +} + + + + +Image PagePreviewProvider::operator () ( + int nWidth, + SdPage* pPage, + ::sd::PreviewRenderer& rRenderer) +{ + Image aPreview; + + if (pPage != NULL) + { + // Use the given renderer to create a preview of the given page + // object. + aPreview = rRenderer.RenderPage( + pPage, + nWidth, + OUString(), + false); + } + + return aPreview; +} + + + + +int PagePreviewProvider::GetCostIndex (void) +{ + return 5; +} + + + + +bool PagePreviewProvider::NeedsPageObject (void) +{ + return true; +} + + + + +//===== TemplatePreviewProvider =============================================== + +TemplatePreviewProvider::TemplatePreviewProvider (const OUString& rsURL) + : msURL(rsURL) +{ +} + + + + +Image TemplatePreviewProvider::operator() ( + int nWidth, + SdPage* pPage, + ::sd::PreviewRenderer& rRenderer) +{ + // Unused parameters. + (void)nWidth; + (void)pPage; + (void)rRenderer; + + // Load the thumbnail from a template document. + uno::Reference<io::XInputStream> xIStream; + + uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext()); + try + { + uno::Reference<lang::XSingleServiceFactory> xStorageFactory = embed::StorageFactory::create(xContext); + + uno::Sequence<uno::Any> aArgs (2); + aArgs[0] <<= msURL; + aArgs[1] <<= embed::ElementModes::READ; + uno::Reference<embed::XStorage> xDocStorage ( + xStorageFactory->createInstanceWithArguments(aArgs), + uno::UNO_QUERY); + + try + { + if (xDocStorage.is()) + { + uno::Reference<embed::XStorage> xStorage ( + xDocStorage->openStorageElement( + "Thumbnails", + embed::ElementModes::READ)); + if (xStorage.is()) + { + uno::Reference<io::XStream> xThumbnailCopy ( + xStorage->cloneStreamElement("thumbnail.png")); + if (xThumbnailCopy.is()) + xIStream = xThumbnailCopy->getInputStream(); + } + } + } + catch (const uno::Exception& rException) + { + OSL_TRACE ( + "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s", + OUStringToOString(msURL, + RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(rException.Message, + RTL_TEXTENCODING_UTF8).getStr()); + } + + try + { + // An (older) implementation had a bug - The storage + // name was "Thumbnail" instead of "Thumbnails". The + // old name is still used as fallback but this code can + // be removed soon. + if ( ! xIStream.is()) + { + uno::Reference<embed::XStorage> xStorage ( + xDocStorage->openStorageElement( "Thumbnail", + embed::ElementModes::READ)); + if (xStorage.is()) + { + uno::Reference<io::XStream> xThumbnailCopy ( + xStorage->cloneStreamElement("thumbnail.png")); + if (xThumbnailCopy.is()) + xIStream = xThumbnailCopy->getInputStream(); + } + } + } + catch (const uno::Exception& rException) + { + OSL_TRACE ( + "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s", + OUStringToOString(msURL, + RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(rException.Message, + RTL_TEXTENCODING_UTF8).getStr()); + } + } + catch (const uno::Exception& rException) + { + OSL_TRACE ( + "caught exception while trying to access tuhmbnail of %s: %s", + OUStringToOString(msURL, + RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(rException.Message, + RTL_TEXTENCODING_UTF8).getStr()); + } + + // Extract the image from the stream. + BitmapEx aThumbnail; + if (xIStream.is()) + { + ::std::auto_ptr<SvStream> pStream ( + ::utl::UcbStreamHelper::CreateStream (xIStream)); + ::vcl::PNGReader aReader (*pStream); + aThumbnail = aReader.Read (); + } + + // Note that the preview is returned without scaling it to the desired + // width. This gives the caller the chance to take advantage of a + // possibly larger resolution then was asked for. + return aThumbnail; +} + + + + +int TemplatePreviewProvider::GetCostIndex (void) +{ + return 10; +} + + + + +bool TemplatePreviewProvider::NeedsPageObject (void) +{ + return false; +} + + + + +//===== TemplatePageObjectProvider ============================================= + +TemplatePageObjectProvider::TemplatePageObjectProvider (const OUString& rsURL) + : msURL(rsURL), + mxDocumentShell() +{ +} + + + + +SdPage* TemplatePageObjectProvider::operator() (SdDrawDocument* pContainerDocument) +{ + // Unused parameters. + (void)pContainerDocument; + + SdPage* pPage = NULL; + + mxDocumentShell = NULL; + ::sd::DrawDocShell* pDocumentShell = NULL; + try + { + // Load the template document and return its first page. + pDocumentShell = LoadDocument (msURL); + if (pDocumentShell != NULL) + { + SdDrawDocument* pDocument = pDocumentShell->GetDoc(); + if (pDocument != NULL) + { + pPage = pDocument->GetMasterSdPage(0, PK_STANDARD); + // In order to make the newly loaded master page deletable + // when copied into documents it is marked as no "precious". + // When it is modified then it is marked as "precious". + if (pPage != NULL) + pPage->SetPrecious(false); + } + } + } + catch (const uno::RuntimeException&) + { + DBG_UNHANDLED_EXCEPTION(); + pPage = NULL; + } + + return pPage; +} + + + + +::sd::DrawDocShell* TemplatePageObjectProvider::LoadDocument (const OUString& sFileName) +{ + SfxApplication* pSfxApp = SFX_APP(); + SfxItemSet* pSet = new SfxAllItemSet (pSfxApp->GetPool()); + pSet->Put (SfxBoolItem (SID_TEMPLATE, sal_True)); + pSet->Put (SfxBoolItem (SID_PREVIEW, sal_True)); + if (pSfxApp->LoadTemplate (mxDocumentShell, sFileName, sal_True, pSet)) + { + mxDocumentShell = NULL; + } + SfxObjectShell* pShell = mxDocumentShell; + return PTR_CAST(::sd::DrawDocShell,pShell); +} + + + + +int TemplatePageObjectProvider::GetCostIndex (void) +{ + return 20; +} + + + + +bool TemplatePageObjectProvider::operator== (const PageObjectProvider& rProvider) +{ + const TemplatePageObjectProvider* pTemplatePageObjectProvider + = dynamic_cast<const TemplatePageObjectProvider*>(&rProvider); + if (pTemplatePageObjectProvider != NULL) + return (msURL == pTemplatePageObjectProvider->msURL); + else + return false; +} + + + + +//===== DefaultPageObjectProvider ============================================== + +DefaultPageObjectProvider::DefaultPageObjectProvider (void) +{ +} + + + + +SdPage* DefaultPageObjectProvider::operator () (SdDrawDocument* pContainerDocument) +{ + SdPage* pLocalMasterPage = NULL; + if (pContainerDocument != NULL) + { + sal_Int32 nIndex (0); + SdPage* pLocalSlide = pContainerDocument->GetSdPage((sal_uInt16)nIndex, PK_STANDARD); + if (pLocalSlide!=NULL && pLocalSlide->TRG_HasMasterPage()) + pLocalMasterPage = dynamic_cast<SdPage*>(&pLocalSlide->TRG_GetMasterPage()); + } + + if (pLocalMasterPage == NULL) + { + DBG_ASSERT(false, "can not create master page for slide"); + } + + return pLocalMasterPage; +} + + + + +int DefaultPageObjectProvider::GetCostIndex (void) +{ + return 15; +} + + + + +bool DefaultPageObjectProvider::operator== (const PageObjectProvider& rProvider) +{ + return (dynamic_cast<const DefaultPageObjectProvider*>(&rProvider) != NULL); +} + + + + +//===== ExistingPageProvider ================================================== + +ExistingPageProvider::ExistingPageProvider (SdPage* pPage) + : mpPage(pPage) +{ +} + + + + +SdPage* ExistingPageProvider::operator() (SdDrawDocument* pDocument) +{ + (void)pDocument; // Unused parameter. + + return mpPage; +} + + + + +int ExistingPageProvider::GetCostIndex (void) +{ + return 0; +} + + + + +bool ExistingPageProvider::operator== (const PageObjectProvider& rProvider) +{ + const ExistingPageProvider* pExistingPageProvider + = dynamic_cast<const ExistingPageProvider*>(&rProvider); + if (pExistingPageProvider != NULL) + return (mpPage == pExistingPageProvider->mpPage); + else + return false; +} + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerProviders.hxx b/sd/source/ui/sidebar/MasterPageContainerProviders.hxx new file mode 100644 index 000000000000..18ecbee0c432 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerProviders.hxx @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX + +#include <rtl/ustring.hxx> +#include <sfx2/objsh.hxx> + +class Image; +class SdDrawDocument; +class SdPage; +namespace sd { class PreviewRenderer; } +namespace sd { class DrawDocShell; } + + +namespace sd { namespace sidebar { + + +/** Interface for a provider of page objects. It is used by the + MasterPageDescriptor to create master page objects on demand. +*/ +class PageObjectProvider +{ +public: + /** Return a master page either by returning an already existing one, by + creating a new page, or by loading a document. + @param pDocument + The document of the MasterPageContainer. It may be used to + create new pages. + */ + virtual SdPage* operator() (SdDrawDocument* pDocument) = 0; + + /** An abstract value for the expected cost of providing a master page + object. + @return + A value of 0 represents for the lowest cost, i.e. an almost + immediate return. Positive values stand for higher costs. + Negative values are not supported. + */ + virtual int GetCostIndex (void) = 0; + + virtual bool operator== (const PageObjectProvider& rProvider) = 0; + +protected: + ~PageObjectProvider() {} +}; + + + + +class PreviewProvider +{ +public: + /** Create a preview image in the specified width. + @param nWidth + Requested width of the preview. The calling method can cope + with other sizes as well but the resulting image quality is + better when the returned image has the requested size. + @param pPage + Page object for which a preview is requested. This may be NULL + when the page object is expensive to get and the PreviewProvider + does not need this object (NeedsPageObject() returns false.) + @param rRenderer + This PreviewRenderer may be used by the PreviewProvider to + create a preview image. + */ + virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer) = 0; + + /** Return a value that indicates how expensive the creation of a + preview image is. The higher the returned value the more expensive + is the preview creation. Return 0 when the preview is already + present and can be returned immediately. + */ + virtual int GetCostIndex (void) = 0; + + /** Return whether the page object passed is necessary to create a + preview. + */ + virtual bool NeedsPageObject (void) = 0; + +protected: + ~PreviewProvider() {} +}; + + + + +/** Provide previews of existing page objects by rendering them. +*/ +class PagePreviewProvider : public PreviewProvider +{ +public: + PagePreviewProvider (void); + virtual ~PagePreviewProvider() {} + virtual Image operator () (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer); + virtual int GetCostIndex (void); + virtual bool NeedsPageObject (void); +private: +}; + + + + +/** Provide master page objects for template documents for which only the + URL is given. +*/ +class TemplatePageObjectProvider : public PageObjectProvider +{ +public: + TemplatePageObjectProvider (const OUString& rsURL); + virtual ~TemplatePageObjectProvider (void) {}; + virtual SdPage* operator () (SdDrawDocument* pDocument); + virtual int GetCostIndex (void); + virtual bool operator== (const PageObjectProvider& rProvider); +private: + OUString msURL; + SfxObjectShellLock mxDocumentShell; + ::sd::DrawDocShell* LoadDocument (const OUString& sFileName); +}; + + + + +/** Provide previews for template documents by loading the thumbnails from + the documents. +*/ +class TemplatePreviewProvider : public PreviewProvider +{ +public: + TemplatePreviewProvider (const OUString& rsURL); + virtual ~TemplatePreviewProvider (void) {}; + virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer); + virtual int GetCostIndex (void); + virtual bool NeedsPageObject (void); +private: + OUString msURL; +}; + + + + +/** Create an empty default master page. +*/ +class DefaultPageObjectProvider : public PageObjectProvider +{ +public: + DefaultPageObjectProvider (void); + virtual ~DefaultPageObjectProvider() {} + virtual SdPage* operator () (SdDrawDocument* pDocument); + virtual int GetCostIndex (void); + virtual bool operator== (const PageObjectProvider& rProvider); +}; + + + +/** This implementation of the PageObjectProvider simply returns an already + existing master page object. +*/ +class ExistingPageProvider : public PageObjectProvider +{ +public: + ExistingPageProvider (SdPage* pPage); + virtual ~ExistingPageProvider() {} + virtual SdPage* operator() (SdDrawDocument* pDocument); + virtual int GetCostIndex (void); + virtual bool operator== (const PageObjectProvider& rProvider); +private: + SdPage* mpPage; +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerQueue.cxx b/sd/source/ui/sidebar/MasterPageContainerQueue.cxx new file mode 100644 index 000000000000..36015378092f --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerQueue.cxx @@ -0,0 +1,299 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPageContainerQueue.hxx" + +#include "tools/IdleDetection.hxx" + +#include <set> + +namespace sd { namespace sidebar { + +const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeout (15); +const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeoutWhenNotIdle (100); +const sal_Int32 MasterPageContainerQueue::snMasterPagePriorityBoost (5); +const sal_Int32 MasterPageContainerQueue::snWaitForMoreRequestsPriorityThreshold (-10); +sal_uInt32 MasterPageContainerQueue::snWaitForMoreRequestsCount(15); + +//===== MasterPageContainerQueue::PreviewCreationRequest ====================== + +class MasterPageContainerQueue::PreviewCreationRequest +{ +public: + PreviewCreationRequest (const SharedMasterPageDescriptor& rpDescriptor, int nPriority) + : mpDescriptor(rpDescriptor), + mnPriority(nPriority) + {} + SharedMasterPageDescriptor mpDescriptor; + int mnPriority; + class Compare + { + public: + bool operator() (const PreviewCreationRequest& r1,const PreviewCreationRequest& r2) const + { + if (r1.mnPriority != r2.mnPriority) + { + // Prefer requests with higher priority. + return r1.mnPriority > r2.mnPriority; + } + else + { + // Prefer tokens that have been earlier created (those with lower + // value). + return r1.mpDescriptor->maToken < r2.mpDescriptor->maToken; + } + } + }; + class CompareToken + { + public: + MasterPageContainer::Token maToken; + CompareToken(MasterPageContainer::Token aToken) : maToken(aToken) {} + bool operator() (const PreviewCreationRequest& rRequest) const + { return maToken==rRequest.mpDescriptor->maToken; } + }; +}; + + + + +//===== MasterPageContainerQueue::RequestQueue ================================ + +class MasterPageContainerQueue::RequestQueue + : public ::std::set<PreviewCreationRequest,PreviewCreationRequest::Compare> +{ +public: + RequestQueue (void) {} +}; + + + + +//===== MasterPageContainerQueue ============================================== + +MasterPageContainerQueue* MasterPageContainerQueue::Create ( + const ::boost::weak_ptr<ContainerAdapter>& rpContainer) +{ + MasterPageContainerQueue* pQueue = new MasterPageContainerQueue(rpContainer); + pQueue->LateInit(); + return pQueue; +} + + + + +MasterPageContainerQueue::MasterPageContainerQueue ( + const ::boost::weak_ptr<ContainerAdapter>& rpContainer) + : mpWeakContainer(rpContainer), + mpRequestQueue(new RequestQueue()), + maDelayedPreviewCreationTimer(), + mnRequestsServedCount(0) +{ +} + + + + +MasterPageContainerQueue::~MasterPageContainerQueue (void) +{ + maDelayedPreviewCreationTimer.Stop(); + while ( ! mpRequestQueue->empty()) + mpRequestQueue->erase(mpRequestQueue->begin()); +} + + + + +void MasterPageContainerQueue::LateInit (void) +{ + // Set up the timer for the delayed creation of preview bitmaps. + maDelayedPreviewCreationTimer.SetTimeout (snDelayedCreationTimeout); + Link aLink (LINK(this,MasterPageContainerQueue,DelayedPreviewCreation)); + maDelayedPreviewCreationTimer.SetTimeoutHdl(aLink); +} + + + + +bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor& rpDescriptor) +{ + bool bSuccess (false); + if (rpDescriptor.get() != NULL + && rpDescriptor->maLargePreview.GetSizePixel().Width() == 0) + { + sal_Int32 nPriority (CalculatePriority(rpDescriptor)); + + // Add a new or replace an existing request. + RequestQueue::iterator iRequest (::std::find_if( + mpRequestQueue->begin(), + mpRequestQueue->end(), + PreviewCreationRequest::CompareToken(rpDescriptor->maToken))); + // When a request for the same token exists then the lowest of the + // two priorities is used. + if (iRequest != mpRequestQueue->end()) + if (iRequest->mnPriority < nPriority) + { + mpRequestQueue->erase(iRequest); + iRequest = mpRequestQueue->end(); + } + + // Add a new request when none exists (or has just been erased). + if (iRequest == mpRequestQueue->end()) + { + mpRequestQueue->insert(PreviewCreationRequest(rpDescriptor,nPriority)); + maDelayedPreviewCreationTimer.Start(); + bSuccess = true; + } + } + return bSuccess; +} + + + + +sal_Int32 MasterPageContainerQueue::CalculatePriority ( + const SharedMasterPageDescriptor& rpDescriptor) const +{ + sal_Int32 nPriority; + + // The cost is used as a starting value. + int nCost (0); + if (rpDescriptor->mpPreviewProvider.get() != NULL) + { + nCost = rpDescriptor->mpPreviewProvider->GetCostIndex(); + if (rpDescriptor->mpPreviewProvider->NeedsPageObject()) + if (rpDescriptor->mpPageObjectProvider.get() != NULL) + nCost += rpDescriptor->mpPageObjectProvider->GetCostIndex(); + } + + // Its negative value is used so that requests with a low cost are + // preferred over those with high costs. + nPriority = -nCost; + + // Add a term that introduces an order based on the appearance in the + // AllMasterPagesSelector. + nPriority -= rpDescriptor->maToken / 3; + + // Process requests for the CurrentMasterPagesSelector first. + if (rpDescriptor->meOrigin == MasterPageContainer::MASTERPAGE) + nPriority += snMasterPagePriorityBoost; + + return nPriority; +} + + + + +IMPL_LINK(MasterPageContainerQueue, DelayedPreviewCreation, Timer*, pTimer) +{ + bool bIsShowingFullScreenShow (false); + bool bWaitForMoreRequests (false); + + do + { + if (mpRequestQueue->empty()) + break; + + // First check whether the system is idle. + sal_Int32 nIdleState (tools::IdleDetection::GetIdleState()); + if (nIdleState != tools::IdleDetection::IDET_IDLE) + { + if ((nIdleState&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE) != 0) + bIsShowingFullScreenShow = true; + break; + } + + PreviewCreationRequest aRequest (*mpRequestQueue->begin()); + + // Check if the request should really be processed right now. + // Reasons to not do it are when its cost is high and not many other + // requests have been inserted into the queue that would otherwise + // be processed first. + if (aRequest.mnPriority < snWaitForMoreRequestsPriorityThreshold + && (mnRequestsServedCount+mpRequestQueue->size() < snWaitForMoreRequestsCount)) + { + // Wait for more requests before this one is processed. Note + // that the queue processing is not started anew when this + // method is left. That is done when the next request is + // inserted. + bWaitForMoreRequests = true; + break; + } + + mpRequestQueue->erase(mpRequestQueue->begin()); + + if (aRequest.mpDescriptor.get() != NULL) + { + mnRequestsServedCount += 1; + if ( ! mpWeakContainer.expired()) + { + ::boost::shared_ptr<ContainerAdapter> pContainer (mpWeakContainer); + if (pContainer.get() != NULL) + pContainer->UpdateDescriptor(aRequest.mpDescriptor,false,true,true); + } + } + } + while (false); + + if (mpRequestQueue->size() > 0 && ! bWaitForMoreRequests) + { + int nTimeout (snDelayedCreationTimeout); + if (bIsShowingFullScreenShow) + nTimeout = snDelayedCreationTimeoutWhenNotIdle; + maDelayedPreviewCreationTimer.SetTimeout(nTimeout); + pTimer->Start(); + } + + return 0; +} + + + + +bool MasterPageContainerQueue::HasRequest (MasterPageContainer::Token aToken) const +{ + RequestQueue::iterator iRequest (::std::find_if( + mpRequestQueue->begin(), + mpRequestQueue->end(), + PreviewCreationRequest::CompareToken(aToken))); + return (iRequest != mpRequestQueue->end()); +} + + + + +bool MasterPageContainerQueue::IsEmpty (void) const +{ + return mpRequestQueue->empty(); +} + + + + +void MasterPageContainerQueue::ProcessAllRequests (void) +{ + snWaitForMoreRequestsCount = 0; + if (mpRequestQueue->size() > 0) + maDelayedPreviewCreationTimer.Start(); +} + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageContainerQueue.hxx b/sd/source/ui/sidebar/MasterPageContainerQueue.hxx new file mode 100644 index 000000000000..4df6205f40a3 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageContainerQueue.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_QUEUE_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGE_CONTAINER_QUEUE_HXX + +#include "MasterPageContainer.hxx" +#include "MasterPageDescriptor.hxx" + +#include <boost/scoped_ptr.hpp> +#include <boost/weak_ptr.hpp> + +namespace sd { namespace sidebar { + + +/** The queue stores and processes all requests from a MasterPageContainer + for the creation of previews. + The order of request processing and its timing is controlled by a + heuristic that uses values given with each request and which is + controlled by various parameters that are described below. +*/ +class MasterPageContainerQueue +{ +public: + class ContainerAdapter { + public: + virtual bool UpdateDescriptor ( + const SharedMasterPageDescriptor& rpDescriptor, + bool bForcePageObject, + bool bForcePreview, + bool bSendEvents) = 0; + + protected: + ~ContainerAdapter() {} + }; + + static MasterPageContainerQueue* Create ( + const ::boost::weak_ptr<ContainerAdapter>& rpContainer); + virtual ~MasterPageContainerQueue (void); + + /** This method is typically called for entries in the container for + which GetPreviewState() returns OS_CREATABLE. The creation of the + preview is then scheduled to be executed asynchronously at a later + point in time. When the preview is available the change listeners + will be notified. + */ + bool RequestPreview (const SharedMasterPageDescriptor& rDescriptor); + + /** Return <TRUE/> when there is a request currently in the queue for + the given token. + */ + bool HasRequest (MasterPageContainer::Token aToken) const; + + /** Return <TRUE/> when there is at least one request in the queue. + */ + bool IsEmpty (void) const; + + /** After this call the queue does not wait anymore for requests with + higher priority when only a small number of requests with lower + priority are present. This method should be called when all + templates are inserted into the MasterPageContainer. + */ + void ProcessAllRequests (void); + +private: + ::boost::weak_ptr<ContainerAdapter> mpWeakContainer; + class PreviewCreationRequest; + class RequestQueue; + ::boost::scoped_ptr<RequestQueue> mpRequestQueue; + Timer maDelayedPreviewCreationTimer; + sal_uInt32 mnRequestsServedCount; + + // There are a couple of values that define various aspects of the + // heuristic that defines the order and timing in which requests for + // preview creation are processed. + + /** The time to wait (in milliseconds) between the creation of previews. + */ + static const sal_Int32 snDelayedCreationTimeout; + + /** The time to wait when the system is not idle. + */ + static const sal_Int32 snDelayedCreationTimeoutWhenNotIdle; + + /** Requests for previews of master pages in a document have their + priority increased by this value. + */ + static const sal_Int32 snMasterPagePriorityBoost; + + /** When only requests which a priority lower than this threshold exist + and not many requests have been made yet then wait with processing + them until more requests are present. + */ + static const sal_Int32 snWaitForMoreRequestsPriorityThreshold; + + /** When only requests which a priority lower than a threshold exist + and not more requests than this number have been made or already + processed then wait with processing them until more requests are + present. + */ + static sal_uInt32 snWaitForMoreRequestsCount; + + MasterPageContainerQueue (const ::boost::weak_ptr<ContainerAdapter>& rpContainer); + void LateInit (void); + + /** Calculate the priority that defines the order in which requests + are processed. + */ + sal_Int32 CalculatePriority (const SharedMasterPageDescriptor& rDescriptor) const; + + DECL_LINK(DelayedPreviewCreation, Timer *); +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageDescriptor.cxx b/sd/source/ui/sidebar/MasterPageDescriptor.cxx new file mode 100644 index 000000000000..3e5117f9607f --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageDescriptor.cxx @@ -0,0 +1,415 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPageDescriptor.hxx" + +#include "DocumentHelper.hxx" +#include "sdpage.hxx" +#include <tools/urlobj.hxx> + +namespace sd { namespace sidebar { + + +//===== MasterPageDescriptor ================================================== + +MasterPageDescriptor::MasterPageDescriptor ( + MasterPageContainer::Origin eOrigin, + const sal_Int32 nTemplateIndex, + const String& rsURL, + const String& rsPageName, + const String& rsStyleName, + const bool bIsPrecious, + const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider, + const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider) + : maToken(MasterPageContainer::NIL_TOKEN), + meOrigin(eOrigin), + msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)), + msPageName(rsPageName), + msStyleName(rsStyleName), + mbIsPrecious(bIsPrecious), + mpMasterPage(NULL), + mpSlide(NULL), + maSmallPreview(), + maLargePreview(), + mpPreviewProvider(rpPreviewProvider), + mpPageObjectProvider(rpPageObjectProvider), + mnTemplateIndex(nTemplateIndex), + meURLClassification(URLCLASS_UNDETERMINED), + mnUseCount(0) +{ +} + + + + +MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor) + : maToken(rDescriptor.maToken), + meOrigin(rDescriptor.meOrigin), + msURL(rDescriptor.msURL), + msPageName(rDescriptor.msPageName), + msStyleName(rDescriptor.msStyleName), + mbIsPrecious(rDescriptor.mbIsPrecious), + mpMasterPage(rDescriptor.mpMasterPage), + mpSlide(rDescriptor.mpSlide), + maSmallPreview(rDescriptor.maSmallPreview), + maLargePreview(rDescriptor.maLargePreview), + mpPreviewProvider(rDescriptor.mpPreviewProvider), + mpPageObjectProvider(rDescriptor.mpPageObjectProvider), + mnTemplateIndex(rDescriptor.mnTemplateIndex), + meURLClassification(rDescriptor.meURLClassification), + mnUseCount(rDescriptor.mnUseCount) +{ +} + + + + +MasterPageDescriptor::~MasterPageDescriptor (void) +{ +} + + + + +void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken) +{ + maToken = aToken; +} + + + + +Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize) const +{ + if (eSize == MasterPageContainer::SMALL) + return maSmallPreview; + else + return maLargePreview; +} + + + +SAL_WNODEPRECATED_DECLARATIONS_PUSH +::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > + MasterPageDescriptor::Update ( + const MasterPageDescriptor& rDescriptor) +{ + bool bDataChanged (false); + bool bIndexChanged (false); + bool bPreviewChanged (false); + + if (meOrigin==MasterPageContainer::UNKNOWN + && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN) + { + meOrigin = rDescriptor.meOrigin; + bIndexChanged = true; + } + + if (msURL.isEmpty() && !rDescriptor.msURL.isEmpty()) + { + msURL = rDescriptor.msURL; + bDataChanged = true; + } + + if (msPageName.isEmpty() && !rDescriptor.msPageName.isEmpty()) + { + msPageName = rDescriptor.msPageName; + bDataChanged = true; + } + + if (msStyleName.isEmpty() && !rDescriptor.msStyleName.isEmpty()) + { + msStyleName = rDescriptor.msStyleName; + bDataChanged = true; + } + + if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL) + { + mpPageObjectProvider = rDescriptor.mpPageObjectProvider; + bDataChanged = true; + } + + if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL) + { + mpPreviewProvider = rDescriptor.mpPreviewProvider; + bPreviewChanged = true; + } + + if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0) + { + mnTemplateIndex = rDescriptor.mnTemplateIndex; + bIndexChanged = true; + } + + // Prepare the list of event types that will be returned. + ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult; + if (bDataChanged || bIndexChanged || bPreviewChanged) + { + pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>()); + if (bDataChanged) + pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED); + if (bIndexChanged) + pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED); + if (bPreviewChanged) + pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED); + } + + return pResult; +} +SAL_WNODEPRECATED_DECLARATIONS_POP + + + +int MasterPageDescriptor::UpdatePageObject ( + sal_Int32 nCostThreshold, + SdDrawDocument* pDocument) +{ + int nModified = 0; + + // Update the page object when that is not yet known. + if (mpMasterPage == NULL + && mpPageObjectProvider.get()!=NULL + && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold)) + { + // Note that pDocument may be NULL. + + SdPage* pPage = (*mpPageObjectProvider)(pDocument); + if (meOrigin == MasterPageContainer::MASTERPAGE) + { + mpMasterPage = pPage; + if (mpMasterPage != NULL) + mpMasterPage->SetPrecious(mbIsPrecious); + } + else + { + // Master pages from templates are copied into the local document. + if (pDocument != NULL) + mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage); + mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage); + } + + if (mpMasterPage != NULL) + { + // Update page name and style name. + if (msPageName.isEmpty()) + msPageName = mpMasterPage->GetName(); + msStyleName = mpMasterPage->GetName(); + + // Delete an existing substitution. The next request for a preview + // will create the real one. + maSmallPreview = Image(); + maLargePreview = Image(); + mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider()); + } + else + { + DBG_ASSERT(false, "UpdatePageObject: master page is NULL"); + return -1; + } + + nModified = 1; + } + + return nModified; +} + + + + +bool MasterPageDescriptor::UpdatePreview ( + sal_Int32 nCostThreshold, + const Size& rSmallSize, + const Size& rLargeSize, + ::sd::PreviewRenderer& rRenderer) +{ + bool bModified (false); + + // Update the preview when that is not yet known. + if (maLargePreview.GetSizePixel().Width()==0 + && mpPreviewProvider.get()!=NULL + && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold)) + { + SdPage* pPage = mpSlide; + if (pPage == NULL) + { + pPage = mpMasterPage; + } + maLargePreview = (*mpPreviewProvider)( + rLargeSize.Width(), + pPage, + rRenderer); + if (maLargePreview.GetSizePixel().Width() > 0) + { + // Create the small preview by scaling the large one down. + maSmallPreview = rRenderer.ScaleBitmap( + maLargePreview.GetBitmapEx(), + rSmallSize.Width()); + // The large preview may not have the desired width. Scale it + // accrodingly. + if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width()) + maLargePreview = rRenderer.ScaleBitmap( + maLargePreview.GetBitmapEx(), + rLargeSize.Width()); + bModified = true; + } + } + + return bModified; +} + + + + +MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void) +{ + if (meURLClassification == URLCLASS_UNDETERMINED) + { + if (msURL.isEmpty()) + meURLClassification = URLCLASS_UNKNOWN; + else if (msURL.indexOf("presnt")>=0) + { + meURLClassification = URLCLASS_PRESENTATION; + } + else if (msURL.indexOf("layout")>=0) + { + meURLClassification = URLCLASS_LAYOUT; + } + else if (msURL.indexOf("educate")>=0) + { + meURLClassification = URLCLASS_OTHER; + } + else + { + meURLClassification = URLCLASS_USER; + } + } + + return meURLClassification; +} + + + +//===== URLComparator ========================================================= + +MasterPageDescriptor::URLComparator::URLComparator (const OUString& sURL) + : msURL(sURL) +{ +} + + + + +bool MasterPageDescriptor::URLComparator::operator() ( + const SharedMasterPageDescriptor& rDescriptor) +{ + if (rDescriptor.get() == NULL) + return false; + else + return rDescriptor->msURL.equals(msURL); +} + + + + +// ===== StyleNameComparator ================================================== + +MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const OUString& sStyleName) + : msStyleName(sStyleName) +{ +} + + + + +bool MasterPageDescriptor::StyleNameComparator::operator() ( + const SharedMasterPageDescriptor& rDescriptor) +{ + if (rDescriptor.get() == NULL) + return false; + else + return rDescriptor->msStyleName.equals(msStyleName); +} + + + + +//===== PageObjectComparator ================================================== + +MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject) + : mpMasterPage(pPageObject) +{ +} + + + + +bool MasterPageDescriptor::PageObjectComparator::operator() ( + const SharedMasterPageDescriptor& rDescriptor) +{ + if (rDescriptor.get() == NULL) + return false; + else + return rDescriptor->mpMasterPage==mpMasterPage; +} + + + + +//===== AllComparator ========================================================= + +MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor) + : mpDescriptor(rDescriptor) +{ +} + + + + +bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor) +{ + if (rDescriptor.get() == NULL) + return false; + else + { + // Take URL, page name, style name, and page object into account + // when comparing two descriptors. When two descriptors are + // identical in any of these values then there are thought of as + // equivalent. Only the Origin has to be the same in both + // descriptors. + return + mpDescriptor->meOrigin == rDescriptor->meOrigin + && ( + (!mpDescriptor->msURL.isEmpty() + && mpDescriptor->msURL.equals(rDescriptor->msURL)) + || (!mpDescriptor->msPageName.isEmpty() + && mpDescriptor->msPageName.equals(rDescriptor->msPageName)) + || (!mpDescriptor->msStyleName.isEmpty() + && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName)) + || (mpDescriptor->mpMasterPage!=NULL + && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage) + || (mpDescriptor->mpPageObjectProvider.get()!=NULL + && rDescriptor->mpPageObjectProvider.get()!=NULL + && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider)); + } +} + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPageDescriptor.hxx b/sd/source/ui/sidebar/MasterPageDescriptor.hxx new file mode 100644 index 000000000000..c1ddc2e0329f --- /dev/null +++ b/sd/source/ui/sidebar/MasterPageDescriptor.hxx @@ -0,0 +1,235 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGE_DESCRIPTOR_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGE_DESCRIPTOR_HXX + +#include "MasterPageContainer.hxx" +#include <boost/shared_ptr.hpp> + +namespace sd { namespace sidebar { + +class PageObjectProvider; +class PreviewProvider; + +class MasterPageDescriptor; +typedef ::boost::shared_ptr<MasterPageDescriptor> SharedMasterPageDescriptor; + +/** A collection of data that is stored for every master page in the + MasterpageContainer. +*/ +class MasterPageDescriptor +{ +public: + MasterPageDescriptor ( + MasterPageContainer::Origin eOrigin, + const sal_Int32 nTemplateIndex, + const String& rURL, + const String& rPageName, + const String& rStyleName, + const bool bIsPrecious, + const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider, + const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider); + MasterPageDescriptor (const MasterPageDescriptor& rDescriptor); + ~MasterPageDescriptor (void); + + void SetToken (MasterPageContainer::Token aToken); + + /** Update the called MasterPageDescriptor object with values from the + given one. Only those values are updated that have default values + in the called object and that have non-default values in the given + one. + @return + Returns a list of event types for which event notifications have + to be sent to listeners. The list may be empty or NULL. + */ + ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > + Update ( + const MasterPageDescriptor& rDescriptor); + + /** This convenience method returns either a small or a large preview, + depending on the given size specifier. + Note that the previews are not created when they are not present. + @return + The returned preview may be empty. + */ + Image GetPreview (MasterPageContainer::PreviewSize ePreviewSize) const; + + /** Use the PreviewProvider to get access to a preview of the master + page. + + Note that this is only done, when either bForce is <TRUE/> or + the PreviewProvider::GetCostIndex() returns 0. + + The small preview is created by scaling the large one, not by + calling PreviewProvider::operator() a second time. + + It is the responsibility of the caller to call UpdatePageObject() + before calling this method when the PreviewProvider can only work + when the master page object is present, i.e. its NeedsPageObject() + method returns <TRUE/>. + + @param nCostThreshold + When this is zero or positive then the preview is created only + when the preview provider has a cost equal to or smaller than + this threshold. A negative value forces the preview to be + created, regardless of the cost. + @param rSmallSize + Size of the small preview. + @param rLargeSize + Size of the large preview. + @param rRenderer + A PreviewRenderer object that may be used to create a preview. + @return + When the previews are successfully provided then <TRUE/> is + returned. + */ + bool UpdatePreview ( + sal_Int32 nCostThreshold, + const Size& rSmallSize, + const Size& rLargeSize, + ::sd::PreviewRenderer& rRenderer); + + /** Use the PageObjectProvider to get access to the master page object. + + Note that this is only done, when either bForce is <TRUE/> or the + PreviewProvider::GetCostIndex() returns 0. + + @param nCostThreshold + When this is zero or positive then the page object is created + only when the page object provider has a cost equal to or + smaller than this threshold. A negative value forces the + page object be created, regardless of the cost. + @param pDocument + This document of the MasterPageContainer may be used to create + a page object with or store one in. + @return + When the master page object is successfully provided then + 1 is returned, on no change then a 0 is provided, + on a masterpage-error a -1 is provided. + */ + int UpdatePageObject ( + sal_Int32 nCostThreshold, + SdDrawDocument* pDocument); + + enum URLClassification { + URLCLASS_USER, + URLCLASS_LAYOUT, + URLCLASS_PRESENTATION, + URLCLASS_OTHER, + URLCLASS_UNKNOWN, + URLCLASS_UNDETERMINED + }; + + URLClassification GetURLClassification (void); + + /** The Token under which the MasterPageContainer gives access to the + object. + */ + MasterPageContainer::Token maToken; + + /** A rough specification of the origin of the master page. + */ + MasterPageContainer::Origin meOrigin; + + /** The URL is not empty for master pages loaded from a template + document. + */ + OUString msURL; + + /** Taken from the title of the template file. + */ + OUString msPageName; + + /** Taken from the master page object. + */ + OUString msStyleName; + + const bool mbIsPrecious; + + /** The actual master page. + */ + SdPage* mpMasterPage; + + /** A slide that uses the master page. + */ + SdPage* mpSlide; + + /** A small (the default size) preview of the master page. May be + empty. When this smaller preview is not empty then the larger one + is not empty, too. + */ + Image maSmallPreview; + + /** A large preview of the master page. May be empty. When this larger + preview is not empty then the smaller one is not empty, too. + */ + Image maLargePreview; + + /** The prewview provider. May be empty. May be replaced during the + lifetime of a MasterPageDescriptor object. + */ + ::boost::shared_ptr<PreviewProvider> mpPreviewProvider; + + /** The master page provider. May be empty. May be replaced during + the lifetime of a MasterPageDescriptor object. + */ + ::boost::shared_ptr<PageObjectProvider> mpPageObjectProvider; + + /** This index represents the order in which templates are provided via + the TemplateScanner. It defines the order in which the entries in + the AllMasterPagesSelector are displayed. The default value is -1. + */ + sal_Int32 mnTemplateIndex; + + URLClassification meURLClassification; + + sal_Int32 mnUseCount; + + class URLComparator { public: + OUString msURL; + URLComparator (const OUString& sURL); + bool operator() (const SharedMasterPageDescriptor& rDescriptor); + }; + class StyleNameComparator { public: + OUString msStyleName; + StyleNameComparator (const OUString& sStyleName); + bool operator() (const SharedMasterPageDescriptor& rDescriptor); + }; + class PageObjectComparator { public: + const SdPage* mpMasterPage; + PageObjectComparator (const SdPage* pPageObject); + bool operator() (const SharedMasterPageDescriptor& rDescriptor); + }; + class AllComparator { public: + AllComparator(const SharedMasterPageDescriptor& rDescriptor); + bool operator() (const SharedMasterPageDescriptor& rDescriptor); + private: + SharedMasterPageDescriptor mpDescriptor; + }; + + +}; + + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPagesSelector.cxx b/sd/source/ui/sidebar/MasterPagesSelector.cxx new file mode 100644 index 000000000000..38b9b5cf534c --- /dev/null +++ b/sd/source/ui/sidebar/MasterPagesSelector.cxx @@ -0,0 +1,845 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "MasterPagesSelector.hxx" + +#include "MasterPageContainer.hxx" +#include "DocumentHelper.hxx" +#include "SidebarShellManager.hxx" +#include "pres.hxx" +#include "drawdoc.hxx" +#include "DrawDocShell.hxx" +#include "sdpage.hxx" +#include "glob.hxx" +#include "glob.hrc" +#include "app.hrc" +#include "res_bmp.hrc" +#include "strings.hrc" +#include "DrawViewShell.hxx" +#include "DrawController.hxx" +#include "SlideSorterViewShell.hxx" +#include "PreviewValueSet.hxx" +#include "ViewShellBase.hxx" +#include <sfx2/objface.hxx> +#include "sdresid.hxx" +#include "drawview.hxx" +#include <vcl/image.hxx> +#include <vcl/floatwin.hxx> +#include <svl/languageoptions.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/mnumgr.hxx> +#include <svl/itemset.hxx> +#include <svl/eitem.hxx> +#include <svx/dlgutil.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svxids.hrc> +#include "FrameView.hxx" +#include "stlpool.hxx" +#include "unmovss.hxx" +#include <sfx2/request.hxx> +#include <svl/itempool.hxx> +#include <sfx2/sidebar/Theme.hxx> + + +using namespace ::com::sun::star::text; + + + +namespace sd { namespace sidebar { + + +MasterPagesSelector::MasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) + : PreviewValueSet(pParent), + maMutex(), + mpContainer(rpContainer), + mrDocument(rDocument), + mrBase(rBase), + mnDefaultClickAction(SID_TP_APPLY_TO_ALL_SLIDES), + maPreviewUpdateQueue(), + maCurrentItemList(), + maTokenToValueSetIndex(), + maLockedMasterPages(), + mxSidebar(rxSidebar) +{ + PreviewValueSet::SetSelectHdl ( + LINK(this, MasterPagesSelector, ClickHandler)); + PreviewValueSet::SetRightMouseClickHandler ( + LINK(this, MasterPagesSelector, RightClickHandler)); + PreviewValueSet::SetStyle(PreviewValueSet::GetStyle() | WB_NO_DIRECTSELECT); + PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel()); + PreviewValueSet::Show(); + + SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground)); + SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Paint_PanelBackground)); + + Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener)); + mpContainer->AddChangeListener(aChangeListener); +} + + + + +MasterPagesSelector::~MasterPagesSelector (void) +{ + Clear(); + UpdateLocks(ItemList()); + + Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener)); + mpContainer->RemoveChangeListener(aChangeListener); +} + + + + +void MasterPagesSelector::LateInit (void) +{ +} + + + + +sal_Int32 MasterPagesSelector::GetPreferredWidth (sal_Int32 nHeight) +{ + const ::osl::MutexGuard aGuard (maMutex); + + return PreviewValueSet::GetPreferredWidth (nHeight); +} + + + + +sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth) +{ + const ::osl::MutexGuard aGuard (maMutex); + + return PreviewValueSet::GetPreferredHeight (nWidth); +} + + + + +Size MasterPagesSelector::GetPreferredSize (void) +{ + int nPreferredWidth = GetPreferredWidth( + PreviewValueSet::GetOutputSizePixel().Height()); + int nPreferredHeight = GetPreferredHeight(nPreferredWidth); + return Size (nPreferredWidth, nPreferredHeight); + +} + + + + +void MasterPagesSelector::UpdateLocks (const ItemList& rItemList) +{ + ItemList aNewLockList; + + // In here we first lock the master pages in the given list and then + // release the locks acquired in a previous call to this method. When + // this were done the other way round the lock count of some master + // pages might drop temporarily to 0 and would lead to unnecessary + // deletion and re-creation of MasterPageDescriptor objects. + + // Lock the master pages in the given list. + ItemList::const_iterator iItem; + for (iItem=rItemList.begin(); iItem!=rItemList.end(); ++iItem) + { + mpContainer->AcquireToken(*iItem); + aNewLockList.push_back(*iItem); + } + + // Release the previously locked master pages. + ItemList::const_iterator iPage; + ItemList::const_iterator iEnd (maLockedMasterPages.end()); + for (iPage=maLockedMasterPages.begin(); iPage!=iEnd; ++iPage) + mpContainer->ReleaseToken(*iPage); + + maLockedMasterPages.swap(aNewLockList); +} + + + + +void MasterPagesSelector::Fill (void) +{ + ::std::auto_ptr<ItemList> pItemList (new ItemList()); + + Fill(*pItemList); + + UpdateLocks(*pItemList); + UpdateItemList(pItemList); +} + + + + +ResId MasterPagesSelector::GetContextMenuResId (void) const +{ + return SdResId(RID_TASKPANE_MASTERPAGESSELECTOR_POPUP); +} + + + + +IMPL_LINK_NOARG(MasterPagesSelector, ClickHandler) +{ + // We use the framework to assign the clicked-on master page because we + // so use the same mechanism as the context menu does (where we do not + // have the option to call the assignment method directly.) + ExecuteCommand(mnDefaultClickAction); + + return 0; +} + + + + +IMPL_LINK(MasterPagesSelector, RightClickHandler, MouseEvent*, pEvent) +{ + // Here we only prepare the display of the context menu: the item under + // the mouse is selected. The actual display of the context menu is + // done in ContextMenuCallback which is called indirectly through + // PreviewValueSet::Command(). + PreviewValueSet::GrabFocus (); + PreviewValueSet::ReleaseMouse(); + SfxViewFrame* pViewFrame = mrBase.GetViewFrame(); + if (pViewFrame != NULL) + { + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if (pDispatcher != NULL && pEvent != NULL) + { + sal_uInt16 nIndex = PreviewValueSet::GetItemId (pEvent->GetPosPixel()); + if (nIndex > 0) + PreviewValueSet::SelectItem (nIndex); + } + } + return 0; +} + + + + +void MasterPagesSelector::Command (const CommandEvent& rEvent) +{ + switch (rEvent.GetCommand()) + { + case COMMAND_CONTEXTMENU: + { + // Use the currently selected item and show the popup menu in its + // center. + const sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId(); + if (nIndex > 0) + { + // The position of the upper left corner of the context menu is + // taken either from the mouse position (when the command was sent + // as reaction to a right click) or in the center of the selected + // item (when the command was sent as reaction to Shift+F10.) + Point aPosition (rEvent.GetMousePosPixel()); + if ( ! rEvent.IsMouseEvent()) + { + Rectangle aBBox (PreviewValueSet::GetItemRect(nIndex)); + aPosition = aBBox.Center(); + } + + // Setup the menu. + ::boost::scoped_ptr<PopupMenu> pMenu (new PopupMenu(GetContextMenuResId())); + FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow()); + if (pMenuWindow != NULL) + pMenuWindow->SetPopupModeFlags( + pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE); + pMenu->SetSelectHdl(LINK(this, MasterPagesSelector, OnMenuItemSelected)); + + ProcessPopupMenu(*pMenu); + + // Show the menu. + pMenu->Execute(this, Rectangle(aPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN); + } + break; + } + } +} + + + + +void MasterPagesSelector::ProcessPopupMenu (Menu& rMenu) +{ + // Disable some entries. + if (mpContainer->GetPreviewSize() == MasterPageContainer::SMALL) + rMenu.EnableItem(SID_TP_SHOW_SMALL_PREVIEW, sal_False); + else + rMenu.EnableItem(SID_TP_SHOW_LARGE_PREVIEW, sal_False); +} + + + + +IMPL_LINK(MasterPagesSelector, OnMenuItemSelected, Menu*, pMenu) +{ + if (pMenu == NULL) + { + OSL_ENSURE(pMenu!=NULL, "MasterPagesSelector::OnMenuItemSelected: illegal menu!"); + return 0; + } + + pMenu->Deactivate(); + ExecuteCommand(pMenu->GetCurItemId()); + return 0; +} + + + + +void MasterPagesSelector::ExecuteCommand (const sal_Int32 nCommandId) +{ + switch (nCommandId) + { + case SID_TP_APPLY_TO_ALL_SLIDES: + mrBase.SetBusyState (true); + AssignMasterPageToAllSlides (GetSelectedMasterPage()); + mrBase.SetBusyState (false); + break; + + case SID_TP_APPLY_TO_SELECTED_SLIDES: + mrBase.SetBusyState (true); + AssignMasterPageToSelectedSlides (GetSelectedMasterPage()); + mrBase.SetBusyState (false); + break; + + case SID_TP_USE_FOR_NEW_PRESENTATIONS: + DBG_ASSERT (false, + "Using slides as default for new presentations" + " is not yet implemented"); + break; + + case SID_TP_SHOW_SMALL_PREVIEW: + case SID_TP_SHOW_LARGE_PREVIEW: + { + mrBase.SetBusyState (true); + mpContainer->SetPreviewSize( + nCommandId==SID_TP_SHOW_SMALL_PREVIEW + ? MasterPageContainer::SMALL + : MasterPageContainer::LARGE); + mrBase.SetBusyState (false); + if (mxSidebar.is()) + mxSidebar->requestLayout(); + break; + } + + case SID_TP_EDIT_MASTER: + { + using namespace ::com::sun::star; + uno::Reference<drawing::XDrawPage> xSelectedMaster; + SdPage* pMasterPage = GetSelectedMasterPage(); + assert(pMasterPage); //rhbz#902884 + if (pMasterPage) + xSelectedMaster = uno::Reference<drawing::XDrawPage>(pMasterPage->getUnoPage(), uno::UNO_QUERY); + SfxViewFrame* pViewFrame = mrBase.GetViewFrame(); + if (pViewFrame != NULL && xSelectedMaster.is()) + { + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if (pDispatcher != NULL) + { + sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId(); + pDispatcher->Execute(SID_MASTERPAGE, SFX_CALLMODE_SYNCHRON); + PreviewValueSet::SelectItem (nIndex); + mrBase.GetDrawController().setCurrentPage(xSelectedMaster); + } + } + break; + } + + case SID_CUT: + case SID_COPY: + case SID_PASTE: + // Cut, copy, and paste are not supported and thus are ignored. + break; + } +} + + + + +IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent*, pEvent) +{ + if (pEvent) + NotifyContainerChangeEvent(*pEvent); + return 0; +} + + + + +SdPage* MasterPagesSelector::GetSelectedMasterPage (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + SdPage* pMasterPage = NULL; + sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId(); + UserData* pData = GetUserData(nIndex); + if (pData != NULL) + { + pMasterPage = mpContainer->GetPageObjectForToken(pData->second); + } + return pMasterPage; +} + + + + +/** Assemble a list of all slides of the document and pass it to + AssignMasterPageToPageList(). +*/ +void MasterPagesSelector::AssignMasterPageToAllSlides (SdPage* pMasterPage) +{ + if (pMasterPage == NULL) + return; + + sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PK_STANDARD); + if (nPageCount == 0) + return; + + // Get a list of all pages. As a little optimization we only + // include pages that do not already have the given master page + // assigned. + OUString sFullLayoutName(pMasterPage->GetLayoutName()); + ::sd::slidesorter::SharedPageSelection pPageList ( + new ::sd::slidesorter::SlideSorterViewShell::PageSelection()); + for (sal_uInt16 nPageIndex=0; nPageIndex<nPageCount; nPageIndex++) + { + SdPage* pPage = mrDocument.GetSdPage (nPageIndex, PK_STANDARD); + if (pPage != NULL && pPage->GetLayoutName() != sFullLayoutName) + { + pPageList->push_back (pPage); + } + } + + AssignMasterPageToPageList(pMasterPage, pPageList); +} + + + + +/** Assemble a list of the currently selected slides (selected in a visible + slide sorter) and pass it to AssignMasterPageToPageList(). +*/ +void MasterPagesSelector::AssignMasterPageToSelectedSlides ( + SdPage* pMasterPage) +{ + using namespace ::sd::slidesorter; + using namespace ::sd::slidesorter::controller; + + if (pMasterPage == NULL) + return; + + // Find a visible slide sorter. + SlideSorterViewShell* pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase); + if (pSlideSorter == NULL) + return; + + // Get a list of selected pages. + SharedPageSelection pPageSelection = pSlideSorter->GetPageSelection(); + if (pPageSelection->empty()) + return; + + AssignMasterPageToPageList(pMasterPage, pPageSelection); + + // Restore the previous selection. + pSlideSorter->SetPageSelection(pPageSelection); +} + + + + +void MasterPagesSelector::AssignMasterPageToPageList ( + SdPage* pMasterPage, + const ::sd::slidesorter::SharedPageSelection& rPageList) +{ + DocumentHelper::AssignMasterPageToPageList(mrDocument, pMasterPage, rPageList); +} + + + + +void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent) +{ + const ::osl::MutexGuard aGuard (maMutex); + + switch (rEvent.meEventType) + { + case MasterPageContainerChangeEvent::SIZE_CHANGED: + PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel()); + UpdateAllPreviews(); + break; + + case MasterPageContainerChangeEvent::PREVIEW_CHANGED: + { + int nIndex (GetIndexForToken(rEvent.maChildToken)); + if (nIndex >= 0) + { + PreviewValueSet::SetItemImage ( + (sal_uInt16)nIndex, + mpContainer->GetPreviewForToken(rEvent.maChildToken)); + PreviewValueSet::Invalidate(PreviewValueSet::GetItemRect((sal_uInt16)nIndex)); + } + } + break; + + case MasterPageContainerChangeEvent::DATA_CHANGED: + { + InvalidateItem(rEvent.maChildToken); + Fill(); + } + break; + + case MasterPageContainerChangeEvent::CHILD_REMOVED: + { + int nIndex (GetIndexForToken(rEvent.maChildToken)); + SetItem(nIndex, MasterPageContainer::NIL_TOKEN); + } + + default: + break; + } +} + + + + +MasterPagesSelector::UserData* MasterPagesSelector::CreateUserData ( + int nIndex, + MasterPageContainer::Token aToken) const +{ + return new UserData(nIndex,aToken); +} + + + + +MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const +{ + const ::osl::MutexGuard aGuard (maMutex); + + if (nIndex>0 && static_cast<unsigned int>(nIndex)<=PreviewValueSet::GetItemCount()) + return reinterpret_cast<UserData*>(PreviewValueSet::GetItemData((sal_uInt16)nIndex)); + else + return NULL; +} + + + + +void MasterPagesSelector::SetUserData (int nIndex, UserData* pData) +{ + const ::osl::MutexGuard aGuard (maMutex); + + if (nIndex>0 && static_cast<unsigned int>(nIndex)<=PreviewValueSet::GetItemCount()) + { + UserData* pOldData = GetUserData(nIndex); + if (pOldData!=NULL && pOldData!=pData) + delete pOldData; + PreviewValueSet::SetItemData((sal_uInt16)nIndex, pData); + } +} + + + + +bool MasterPagesSelector::IsResizable (void) +{ + return false; +} + + + + +::Window* MasterPagesSelector::GetWindow (void) +{ + return this; +} + + + + +sal_Int32 MasterPagesSelector::GetMinimumWidth (void) +{ + return mpContainer->GetPreviewSizePixel().Width() + 2*3; +} + + + + +void MasterPagesSelector::UpdateSelection (void) +{ +} + + + + +void MasterPagesSelector::SetItem ( + sal_uInt16 nIndex, + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (maMutex); + + RemoveTokenToIndexEntry(nIndex,aToken); + + if (nIndex > 0) + { + if (aToken != MasterPageContainer::NIL_TOKEN) + { + Image aPreview (mpContainer->GetPreviewForToken(aToken)); + MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken)); + + if (aPreview.GetSizePixel().Width()>0) + { + if (PreviewValueSet::GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND) + { + PreviewValueSet::SetItemImage(nIndex,aPreview); + PreviewValueSet::SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken)); + } + else + { + PreviewValueSet::InsertItem ( + nIndex, + aPreview, + mpContainer->GetPageNameForToken(aToken), + nIndex); + } + SetUserData(nIndex, CreateUserData(nIndex,aToken)); + + AddTokenToIndexEntry(nIndex,aToken); + } + + if (eState == MasterPageContainer::PS_CREATABLE) + mpContainer->RequestPreview(aToken); + } + else + { + PreviewValueSet::RemoveItem(nIndex); + } + } + +} + + + + +void MasterPagesSelector::AddTokenToIndexEntry ( + sal_uInt16 nIndex, + MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (maMutex); + + maTokenToValueSetIndex[aToken] = nIndex; +} + + + + +void MasterPagesSelector::RemoveTokenToIndexEntry ( + sal_uInt16 nIndex, + MasterPageContainer::Token aNewToken) +{ + const ::osl::MutexGuard aGuard (maMutex); + + UserData* pData = GetUserData(nIndex); + if (pData != NULL) + { + // Get the token that the index pointed to previously. + MasterPageContainer::Token aOldToken (pData->second); + + if (aNewToken != aOldToken + && nIndex == GetIndexForToken(aOldToken)) + { + maTokenToValueSetIndex[aOldToken] = 0; + } + } +} + + + + +void MasterPagesSelector::InvalidatePreview (const SdPage* pPage) +{ + const ::osl::MutexGuard aGuard (maMutex); + + for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++) + { + UserData* pData = GetUserData(nIndex); + if (pData != NULL) + { + MasterPageContainer::Token aToken (pData->second); + if (pPage == mpContainer->GetPageObjectForToken(aToken,false)) + { + mpContainer->InvalidatePreview(aToken); + mpContainer->RequestPreview(aToken); + break; + } + } + } +} + +void MasterPagesSelector::UpdateAllPreviews (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++) + { + UserData* pData = GetUserData(nIndex); + if (pData != NULL) + { + MasterPageContainer::Token aToken (pData->second); + PreviewValueSet::SetItemImage( + nIndex, + mpContainer->GetPreviewForToken(aToken)); + if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE) + mpContainer->RequestPreview(aToken); + } + } + PreviewValueSet::Rearrange(true); +} + + + + +void MasterPagesSelector::ClearPageSet (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++) + { + UserData* pData = GetUserData(nIndex); + if (pData != NULL) + delete pData; + } + PreviewValueSet::Clear(); +} + + + + +void MasterPagesSelector::SetHelpId( const OString& aId ) +{ + const ::osl::MutexGuard aGuard (maMutex); + + PreviewValueSet::SetHelpId( aId ); +} + + + + +sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const +{ + const ::osl::MutexGuard aGuard (maMutex); + + TokenToValueSetIndex::const_iterator iIndex (maTokenToValueSetIndex.find(aToken)); + if (iIndex != maTokenToValueSetIndex.end()) + return iIndex->second; + else + return -1; +} + + + + +void MasterPagesSelector::Clear (void) +{ + const ::osl::MutexGuard aGuard (maMutex); + + ClearPageSet(); +} + + + + +void MasterPagesSelector::InvalidateItem (MasterPageContainer::Token aToken) +{ + const ::osl::MutexGuard aGuard (maMutex); + + ItemList::iterator iItem; + for (iItem=maCurrentItemList.begin(); iItem!=maCurrentItemList.end(); ++iItem) + { + if (*iItem == aToken) + { + *iItem = MasterPageContainer::NIL_TOKEN; + break; + } + } +} + + + +SAL_WNODEPRECATED_DECLARATIONS_PUSH +void MasterPagesSelector::UpdateItemList (::std::auto_ptr<ItemList> pNewItemList) +{ + const ::osl::MutexGuard aGuard (maMutex); + + ItemList::const_iterator iNewItem (pNewItemList->begin()); + ItemList::const_iterator iCurrentItem (maCurrentItemList.begin()); + ItemList::const_iterator iNewEnd (pNewItemList->end()); + ItemList::const_iterator iCurrentEnd (maCurrentItemList.end()); + sal_uInt16 nIndex (1); + + // Update existing items. + for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex) + { + if (*iNewItem != *iCurrentItem) + { + SetItem(nIndex,*iNewItem); + } + } + + // Append new items. + for ( ; iNewItem!=iNewEnd; ++iNewItem,++nIndex) + { + SetItem(nIndex,*iNewItem); + } + + // Remove trailing items. + for ( ; iCurrentItem!=iCurrentEnd; ++iCurrentItem,++nIndex) + { + SetItem(nIndex,MasterPageContainer::NIL_TOKEN); + } + + maCurrentItemList.swap(*pNewItemList); + + PreviewValueSet::Rearrange(); + if (mxSidebar.is()) + mxSidebar->requestLayout(); +} +SAL_WNODEPRECATED_DECLARATIONS_POP + + + +css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth (const sal_Int32 nWidth) +{ + const sal_Int32 nHeight (GetPreferredHeight(nWidth)); + return css::ui::LayoutSize(nHeight,nHeight,nHeight); +} + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/MasterPagesSelector.hxx b/sd/source/ui/sidebar/MasterPagesSelector.hxx new file mode 100644 index 000000000000..83e8091a66e7 --- /dev/null +++ b/sd/source/ui/sidebar/MasterPagesSelector.hxx @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_MASTER_PAGES_SELECTOR_HXX +#define SD_SIDEBAR_PANELS_MASTER_PAGES_SELECTOR_HXX + +#include "MasterPageContainer.hxx" +#include "SlideSorterViewShell.hxx" +#include "PreviewValueSet.hxx" +#include "ISidebarReceiver.hxx" +#include <sfx2/sidebar/ILayoutableWindow.hxx> + +#include "pres.hxx" +#include <sfx2/shell.hxx> +#include <vcl/image.hxx> +#include "glob.hxx" +#include <osl/mutex.hxx> +#include <com/sun/star/ui/XSidebar.hpp> + +#include <queue> + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; + +class MouseEvent; +class SdDrawDocument; +class SdPage; + +namespace sd { +class ViewShellBase; +} + +namespace sd { namespace sidebar { + +class PreviewValueSet; +class SidebarShellManager; + + +/** Base class of a menu that lets the user select from a list of + templates or designs that are loaded from files. +*/ +class MasterPagesSelector + : public PreviewValueSet, + public sfx2::sidebar::ILayoutableWindow +{ +public: + MasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + virtual ~MasterPagesSelector (void); + + virtual void LateInit (void); + + /** Return the height that this control needs to show all of its lines. + */ + long GetRequiredHeight (int nWidth) const; + + /** The given master page, either the master page of a slide or a notes + page, is cloned and inserted into mrDocument. The necessary styles + are copied as well. + */ + static SdPage* AddMasterPage ( + SdDrawDocument* pTargetDocument, + SdPage* pMasterPage, + sal_uInt16 nInsertionIndex); + + virtual Size GetPreferredSize (void); + virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeight); + virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth); + virtual bool IsResizable (void); + virtual ::Window* GetWindow (void); + virtual sal_Int32 GetMinimumWidth (void); + + /** Update the selection of previews according to whatever + influences them appart from mouse and keyboard. If, for + example, the current page of the main pane changes, then call + this method at the CurrentMasterPagesSelector to select the + previews of the master pages that are assigned to the new + current page. + + The default implementation of this method ignores the call. This is + used by e.g. the RecentMasterPagesSelector because it does not show + the currently used master pages by default and thus is not + influenced by its changes. + */ + virtual void UpdateSelection (void); + + void FillPageSet (void); + + /** Make the selector empty. This method clear the value set from any + entries. Overload this method to add functionality, especially to + destroy objects set as data items at the value set. + */ + void ClearPageSet (void); + + void SetHelpId( const OString& aId ); + + /** Mark the preview that belongs to the given index as not up-to-date + anymore with respect to page content or preview size. + The implementation of this method will either sunchronously or + asynchronously call UpdatePreview(). + @param nIndex + Index into the value set control that is used for displaying the + previews. + */ + void InvalidatePreview (const SdPage* pPage); + + void UpdateAllPreviews (void); + + // ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + +protected: + mutable ::osl::Mutex maMutex; + ::boost::shared_ptr<MasterPageContainer> mpContainer; + + SdDrawDocument& mrDocument; + bool mbSmallPreviewSize; + ViewShellBase& mrBase; + /** Slot that is executed as default action when the left mouse button is + clicked over a master page. + */ + sal_uInt16 mnDefaultClickAction; + /** Pages with pointers in this queue have their previews updated + eventually. Filled by InvalidatePreview() and operated upon by + UpdatePreviews(). + */ + ::std::queue<sal_uInt16> maPreviewUpdateQueue; + + virtual SdPage* GetSelectedMasterPage (void); + + /** Assign the given master page to all slides of the document. + @param pMasterPage + The master page to assign to all slides. + */ + void AssignMasterPageToAllSlides (SdPage* pMasterPage); + + /** Assign the given master page to all slides that are selected in a + slide sorter that is displayed in the lef or center pane. When both + panes display a slide sorter then the one in the center pane is + used. + */ + void AssignMasterPageToSelectedSlides (SdPage* pMasterPage); + + virtual void AssignMasterPageToPageList ( + SdPage* pMasterPage, + const ::sd::slidesorter::SharedPageSelection& rPageList); + + virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent); + + typedef ::std::pair<int, MasterPageContainer::Token> UserData; + UserData* CreateUserData (int nIndex, MasterPageContainer::Token aToken) const; + UserData* GetUserData (int nIndex) const; + void SetUserData (int nIndex, UserData* pData); + + virtual sal_Int32 GetIndexForToken (MasterPageContainer::Token aToken) const; + typedef ::std::vector<MasterPageContainer::Token> ItemList; + void UpdateItemList (::std::auto_ptr<ItemList> pList); + void Clear (void); + /** Invalidate the specified item so that on the next Fill() this item + is updated. + */ + void InvalidateItem (MasterPageContainer::Token aToken); + + // For every item in the ValueSet we store its associated token. This + // allows a faster access and easier change tracking. + ItemList maCurrentItemList; + typedef ::std::map<MasterPageContainer::Token,sal_Int32> TokenToValueSetIndex; + TokenToValueSetIndex maTokenToValueSetIndex; + + ItemList maLockedMasterPages; + /** Lock master pages in the given list and release locks that where + previously aquired. + */ + void UpdateLocks (const ItemList& rItemList); + + void Fill (void); + virtual void Fill (ItemList& rItemList) = 0; + + /** Give derived classes the oportunity to provide their own context + menu. If they do then they probably have to provide their own + Execute() and GetState() methods as well. + */ + virtual ResId GetContextMenuResId (void) const; + + virtual void Command (const CommandEvent& rEvent); + + virtual void ProcessPopupMenu (Menu& rMenu); + virtual void ExecuteCommand (const sal_Int32 nCommandId); + +private: + cssu::Reference<css::ui::XSidebar> mxSidebar; + + /** The offset between ValueSet index and MasterPageContainer::Token + last seen. This value is used heuristically to speed up the lookup + of an index for a token. + */ + DECL_LINK(ClickHandler, void *); + DECL_LINK(RightClickHandler, MouseEvent*); + DECL_LINK(ContextMenuCallback, CommandEvent*); + DECL_LINK(ContainerChangeListener, MasterPageContainerChangeEvent*); + DECL_LINK(OnMenuItemSelected, Menu*); + + void SetItem ( + sal_uInt16 nIndex, + MasterPageContainer::Token aToken); + void AddTokenToIndexEntry ( + sal_uInt16 nIndex, + MasterPageContainer::Token aToken); + void RemoveTokenToIndexEntry ( + sal_uInt16 nIndex, + MasterPageContainer::Token aToken); +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/NavigatorWrapper.cxx b/sd/source/ui/sidebar/NavigatorWrapper.cxx new file mode 100644 index 000000000000..ad870fc43fe1 --- /dev/null +++ b/sd/source/ui/sidebar/NavigatorWrapper.cxx @@ -0,0 +1,84 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "NavigatorWrapper.hxx" +#include "navigatr.hrc" +#include "ViewShellBase.hxx" + +#include <sfx2/sidebar/Theme.hxx> + +#include <boost/bind.hpp> + + +namespace sd { namespace sidebar { + +NavigatorWrapper::NavigatorWrapper ( + ::Window* pParent, + sd::ViewShellBase& rViewShellBase, + SfxBindings* pBindings) + : Control(pParent, 0), + mrViewShellBase(rViewShellBase), + maNavigator( + this, + NULL, + SdResId(FLT_NAVIGATOR), + pBindings, + ::boost::bind(&NavigatorWrapper::UpdateNavigator, this)) +{ + maNavigator.SetPosSizePixel( + Point(0,0), + GetSizePixel()); + maNavigator.SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground)); + maNavigator.Show(); +} + + + + +NavigatorWrapper::~NavigatorWrapper (void) +{ +} + + + + +void NavigatorWrapper::Resize (void) +{ + maNavigator.SetSizePixel(GetSizePixel()); +} + + + + +css::ui::LayoutSize NavigatorWrapper::GetHeightForWidth (const sal_Int32 nWidth) +{ + (void)nWidth; + + return css::ui::LayoutSize(-1,-1,-1); +} + + + + +void NavigatorWrapper::UpdateNavigator (void) +{ + maNavigator.InitTreeLB(mrViewShellBase.GetDocument()); +} + + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/NavigatorWrapper.hxx b/sd/source/ui/sidebar/NavigatorWrapper.hxx new file mode 100644 index 000000000000..669628d0c073 --- /dev/null +++ b/sd/source/ui/sidebar/NavigatorWrapper.hxx @@ -0,0 +1,68 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_NAVIGATOR_WRAPPER_HXX +#define SD_SIDEBAR_NAVIGATOR_WRAPPER_HXX + +#include <sfx2/sidebar/ILayoutableWindow.hxx> +#include <vcl/ctrl.hxx> +#include "navigatr.hxx" + + +class SfxBindings; +namespace sd { class ViewShellBase; } + +namespace css = ::com::sun::star; + +namespace sd { namespace sidebar { + +/** Present the navigator as control that can be displayed inside the + sidebar. + This wrapper has two main responsibilities: + - Watch for document changes and update the navigator when one + happens. + - Forward size changes from sidebar to navigator. +*/ +class NavigatorWrapper + : public Control, + public sfx2::sidebar::ILayoutableWindow +{ +public: + NavigatorWrapper ( + ::Window* pParent, + sd::ViewShellBase& rViewShellBase, + SfxBindings* pBindings); + + virtual ~NavigatorWrapper (void); + + // Control + virtual void Resize (void); + + // From ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + +private: + ViewShellBase& mrViewShellBase; + SdNavigatorWin maNavigator; + + void UpdateNavigator (void); +}; + + +} } // end of namespace sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/PanelBase.cxx b/sd/source/ui/sidebar/PanelBase.cxx new file mode 100644 index 000000000000..014ee8a4cde3 --- /dev/null +++ b/sd/source/ui/sidebar/PanelBase.cxx @@ -0,0 +1,133 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "TableDesignPanel.hxx" + + + +namespace sd { namespace sidebar { + + +PanelBase::PanelBase ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) + : Control(pParentWindow), + mpWrappedControl(NULL), + mxSidebar(), + mrViewShellBase(rViewShellBase) +{ + OSL_TRACE("created PanelBase at %x for parent %x", this, pParentWindow); + +#ifdef DEBUG + SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:PanelBase"))); +#endif +} + + + + +PanelBase::~PanelBase (void) +{ + OSL_TRACE("deleting wrapped control at %x", mpWrappedControl.get()); + mpWrappedControl.reset(); + OSL_TRACE("deleting PanelBase at %x from parent %x", this, GetParent()); +} + + + + + +void PanelBase::Dispose (void) +{ + OSL_TRACE("PanelBase::DisposeL: deleting wrapped control at %x", mpWrappedControl.get()); + mpWrappedControl.reset(); +} + + + + +css::ui::LayoutSize PanelBase::GetHeightForWidth (const sal_Int32 /*nWidth*/) +{ + sal_Int32 nHeight (0); + if (ProvideWrappedControl()) + nHeight = mpWrappedControl->GetSizePixel().Height(); + return css::ui::LayoutSize(nHeight,nHeight,nHeight); +} + + + + +void PanelBase::Resize (void) +{ + if (ProvideWrappedControl()) + { + Size aNewSize (GetSizePixel()); + mpWrappedControl->SetOutputSizePixel(aNewSize); + } +} + + + + +::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible> PanelBase::CreateAccessibleObject ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& ) +{ + if (ProvideWrappedControl()) + return mpWrappedControl->GetAccessible(); + else + return NULL; +} + + + + +void PanelBase::SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar) +{ + mxSidebar = rxSidebar; + if (mxSidebar.is() && mpWrappedControl!=NULL) + mxSidebar->requestLayout(); +} + + + + +bool PanelBase::ProvideWrappedControl (void) +{ + if ( ! mpWrappedControl) + { + mpWrappedControl.reset(CreateWrappedControl(this, mrViewShellBase)); + OSL_TRACE("created wrapped control at %x for parent PanelBase at %x", mpWrappedControl.get(), this); + if (mpWrappedControl) + mpWrappedControl->Show(); + if (mxSidebar.is()) + mxSidebar->requestLayout(); + } + return mpWrappedControl.get() != NULL; +} + +ISidebarReceiver::~ISidebarReceiver() +{ +} + +IDisposable::~IDisposable() +{ +} + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/PanelBase.hxx b/sd/source/ui/sidebar/PanelBase.hxx new file mode 100644 index 000000000000..242424b6130f --- /dev/null +++ b/sd/source/ui/sidebar/PanelBase.hxx @@ -0,0 +1,86 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_PANELS_PANEL_BASE_HXX +#define SD_SIDEBAR_PANELS_PANEL_BASE_HXX + +#include "IDisposable.hxx" +#include "ISidebarReceiver.hxx" +#include <sfx2/sidebar/ILayoutableWindow.hxx> + +#include <vcl/ctrl.hxx> + +#include <boost/scoped_ptr.hpp> + + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; + +namespace sd { + class ViewShellBase; +} + + + + +namespace sd { namespace sidebar { + + +class PanelBase + : public Control, + public sfx2::sidebar::ILayoutableWindow, + public IDisposable, + public ISidebarReceiver +{ +public: + PanelBase ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); + virtual ~PanelBase (void); + + virtual void Resize (void); + + // IDisposable + virtual void Dispose (void); + + // ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + + // ISidebarReceiver + virtual void SetSidebar (const cssu::Reference<css::ui::XSidebar>& rxSidebar); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject ( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent); + +protected: + ::boost::scoped_ptr< ::Window> mpWrappedControl; + virtual ::Window* CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) = 0; + +private: + cssu::Reference<css::ui::XSidebar> mxSidebar; + ViewShellBase& mrViewShellBase; + + bool ProvideWrappedControl (void); +}; + +} } // end of namespace sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/PanelFactory.cxx b/sd/source/ui/sidebar/PanelFactory.cxx new file mode 100644 index 000000000000..193468a3ff43 --- /dev/null +++ b/sd/source/ui/sidebar/PanelFactory.cxx @@ -0,0 +1,207 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "PanelFactory.hxx" +#include "framework/Pane.hxx" +#include "ViewShellBase.hxx" +#include "DrawController.hxx" +#include "LayoutMenu.hxx" +#include "CurrentMasterPagesSelector.hxx" +#include "RecentMasterPagesSelector.hxx" +#include "AllMasterPagesSelector.hxx" +#include "CustomAnimationPanel.hxx" +#include "SlideTransitionPanel.hxx" +#include "NavigatorWrapper.hxx" + +#include <sfx2/viewfrm.hxx> +#include <sfx2/sidebar/SidebarPanelBase.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <vcl/window.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +using namespace css; +using namespace cssu; +using namespace ::sd::framework; +using ::rtl::OUString; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + +namespace sd { + extern ::Window * createTableDesignPanel (::Window* pParent, ViewShellBase& rBase); +} + +namespace sd { namespace sidebar { + +namespace { + /** Note that these names have to be identical to (the tail of) + the entries in officecfg/registry/data/org/openoffice/Office/Impress.xcu + for the TaskPanelFactory. + */ + const static char* gsResourceNameCustomAnimations = "/CustomAnimations"; + const static char* gsResourceNameLayouts = "/Layouts"; + const static char* gsResourceNameAllMasterPages = "/AllMasterPages"; + const static char* gsResourceNameRecentMasterPages = "/RecentMasterPages"; + const static char* gsResourceNameUsedMasterPages = "/UsedMasterPages"; + const static char* gsResourceNameSlideTransitions = "/SlideTransitions"; + const static char* gsResourceNameTableDesign = "/TableDesign"; + const static char* gsResourceNameNavigator = "/NavigatorPanel"; +} + +Reference<lang::XEventListener> mxControllerDisposeListener; + + + +// ----- Service functions ---------------------------------------------------- + +Reference<XInterface> SAL_CALL PanelFactory_createInstance ( + const Reference<XComponentContext>& rxContext) +{ + return Reference<XInterface>(static_cast<XWeak*>(new PanelFactory(rxContext))); +} + + + + +::rtl::OUString PanelFactory_getImplementationName (void) throw(RuntimeException) +{ + return ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.Draw.framework.PanelFactory")); +} + + + + +Sequence<rtl::OUString> SAL_CALL PanelFactory_getSupportedServiceNames (void) + throw (RuntimeException) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString::createFromAscii("com.sun.star.drawing.framework.PanelFactory")); + return Sequence<rtl::OUString>(&sServiceName, 1); +} + + + + +//----- PanelFactory -------------------------------------------------------- + +PanelFactory::PanelFactory( + const css::uno::Reference<css::uno::XComponentContext>& /*rxContext*/) + : PanelFactoryInterfaceBase(m_aMutex) +{ +} + + + + +PanelFactory::~PanelFactory (void) +{ +} + + + + +void SAL_CALL PanelFactory::disposing (void) +{ +} + + + + +// XUIElementFactory + +Reference<ui::XUIElement> SAL_CALL PanelFactory::createUIElement ( + const ::rtl::OUString& rsUIElementResourceURL, + const ::cssu::Sequence<css::beans::PropertyValue>& rArguments) + throw( + css::container::NoSuchElementException, + css::lang::IllegalArgumentException, + cssu::RuntimeException) +{ + // Process arguments. + const ::comphelper::NamedValueCollection aArguments (rArguments); + Reference<frame::XFrame> xFrame (aArguments.getOrDefault("Frame", Reference<frame::XFrame>())); + Reference<awt::XWindow> xParentWindow (aArguments.getOrDefault("ParentWindow", Reference<awt::XWindow>())); + Reference<ui::XSidebar> xSidebar (aArguments.getOrDefault("Sidebar", Reference<ui::XSidebar>())); + + // Throw exceptions when the arguments are not as expected. + ::Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow); + if ( ! xParentWindow.is() || pParentWindow==NULL) + throw RuntimeException( + A2S("PanelFactory::createUIElement called without ParentWindow"), + NULL); + if ( ! xFrame.is()) + throw RuntimeException( + A2S("PanelFactory::createUIElement called without XFrame"), + NULL); + + // Tunnel through the controller to obtain a ViewShellBase. + ViewShellBase* pBase = NULL; + Reference<lang::XUnoTunnel> xTunnel (xFrame->getController(), UNO_QUERY); + if (xTunnel.is()) + { + ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>( + xTunnel->getSomething(sd::DrawController::getUnoTunnelId())); + if (pController != NULL) + pBase = pController->GetViewShellBase(); + } + if (pBase == NULL) + throw RuntimeException(A2S("can not get ViewShellBase for frame"), NULL); + + // Get bindings from given arguments. + const sal_uInt64 nBindingsValue (aArguments.getOrDefault("SfxBindings", sal_uInt64(0))); + SfxBindings* pBindings = reinterpret_cast<SfxBindings*>(nBindingsValue); + + // Create a framework view. + ::Window* pControl = NULL; + css::ui::LayoutSize aLayoutSize (-1,-1,-1); + +#define EndsWith(s,t) s.endsWithAsciiL(t,strlen(t)) + if (EndsWith(rsUIElementResourceURL, gsResourceNameCustomAnimations)) + pControl = new CustomAnimationPanel(pParentWindow, *pBase); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameLayouts)) + pControl = new LayoutMenu(pParentWindow, *pBase, xSidebar); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameAllMasterPages)) + pControl = AllMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameRecentMasterPages)) + pControl = RecentMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameUsedMasterPages)) + pControl = CurrentMasterPagesSelector::Create(pParentWindow, *pBase, xSidebar); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameSlideTransitions)) + pControl = new SlideTransitionPanel(pParentWindow, *pBase); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameTableDesign)) + pControl = createTableDesignPanel(pParentWindow, *pBase); + else if (EndsWith(rsUIElementResourceURL, gsResourceNameNavigator)) + pControl = new NavigatorWrapper(pParentWindow, *pBase, pBindings); +#undef EndsWith + + if (pControl == NULL) + throw lang::IllegalArgumentException(); + + // Create a wrapper around the control that implements the + // necessary UNO interfaces. + return sfx2::sidebar::SidebarPanelBase::Create( + rsUIElementResourceURL, + xFrame, + pControl, + aLayoutSize); +} + + + + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/PanelFactory.hxx b/sd/source/ui/sidebar/PanelFactory.hxx new file mode 100644 index 000000000000..3cf4c629bc0a --- /dev/null +++ b/sd/source/ui/sidebar/PanelFactory.hxx @@ -0,0 +1,84 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_PANEL_FACTORY_HXX +#define SD_SIDEBAR_PANEL_FACTORY_HXX + +#include <cppuhelper/compbase1.hxx> +#include <cppuhelper/basemutex.hxx> +#include <rtl/ref.hxx> +#include "framework/Pane.hxx" + +#include <com/sun/star/ui/XUIElementFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <map> +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> + + +namespace css = ::com::sun::star; +namespace cssu = ::com::sun::star::uno; + + +namespace sd { + class ViewShellBase; +} + +namespace sd { namespace sidebar { + +namespace +{ + typedef ::cppu::WeakComponentImplHelper1 < + css::ui::XUIElementFactory + > PanelFactoryInterfaceBase; +} + + +class PanelFactory + : private ::boost::noncopyable, + private ::cppu::BaseMutex, + public PanelFactoryInterfaceBase +{ +public: + static ::rtl::OUString SAL_CALL getImplementationName (void); + static cssu::Reference<cssu::XInterface> SAL_CALL createInstance ( + const cssu::Reference<css::lang::XMultiServiceFactory>& rxFactory); + static cssu::Sequence<rtl::OUString> SAL_CALL getSupportedServiceNames (void); + + PanelFactory (const cssu::Reference<cssu::XComponentContext>& rxContext); + virtual ~PanelFactory (void); + + virtual void SAL_CALL disposing (void); + + + // XUIElementFactory + + cssu::Reference<css::ui::XUIElement> SAL_CALL createUIElement ( + const ::rtl::OUString& rsResourceURL, + const ::cssu::Sequence<css::beans::PropertyValue>& rArguments) + throw( + css::container::NoSuchElementException, + css::lang::IllegalArgumentException, + cssu::RuntimeException); +}; + + +} } // end of namespace sd::sidebar + +#endif diff --git a/sd/source/ui/sidebar/PreviewValueSet.cxx b/sd/source/ui/sidebar/PreviewValueSet.cxx new file mode 100644 index 000000000000..ae3d7fbfbd5f --- /dev/null +++ b/sd/source/ui/sidebar/PreviewValueSet.cxx @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "PreviewValueSet.hxx" +#include <vcl/image.hxx> + + +namespace sd { namespace sidebar { + + +PreviewValueSet::PreviewValueSet (::Window* pParent) + : ValueSet (pParent, WB_TABSTOP), + maPreviewSize(10,10), + mnBorderWidth(3), + mnBorderHeight(3), + mnMaxColumnCount(-1) +{ + SetStyle ( + GetStyle() + & ~(WB_ITEMBORDER)// | WB_MENUSTYLEVALUESET) + // | WB_FLATVALUESET); + ); + SetColCount(2); + SetExtraSpacing (2); +} + + + + +PreviewValueSet::~PreviewValueSet (void) +{ +} + + + + +void PreviewValueSet::SetPreviewSize (const Size& rSize) +{ + maPreviewSize = rSize; +} + + + + +void PreviewValueSet::SetRightMouseClickHandler (const Link& rLink) +{ + maRightMouseClickHandler = rLink; +} + + + + +void PreviewValueSet::MouseButtonDown (const MouseEvent& rEvent) +{ + if (rEvent.IsRight()) + maRightMouseClickHandler.Call(reinterpret_cast<void*>( + &const_cast<MouseEvent&>(rEvent))); + else + ValueSet::MouseButtonDown (rEvent); + +} + + + + +void PreviewValueSet::Resize (void) +{ + ValueSet::Resize (); + + Size aWindowSize (GetOutputSizePixel()); + if (aWindowSize.Width()>0 && aWindowSize.Height()>0) + { + Rearrange(); + } +} + + + + +void PreviewValueSet::Rearrange (bool /*bForceRequestResize*/) +{ + sal_uInt16 nNewColumnCount (CalculateColumnCount ( + GetOutputSizePixel().Width())); + sal_uInt16 nNewRowCount (CalculateRowCount (nNewColumnCount)); + + SetColCount(nNewColumnCount); + SetLineCount(nNewRowCount); +} + + + + +sal_uInt16 PreviewValueSet::CalculateColumnCount (int nWidth) const +{ + int nColumnCount = 0; + if (nWidth > 0) + { + nColumnCount = nWidth / (maPreviewSize.Width() + 2*mnBorderWidth); + if (nColumnCount < 1) + nColumnCount = 1; + else if (mnMaxColumnCount>0 && nColumnCount>mnMaxColumnCount) + nColumnCount = mnMaxColumnCount; + } + return (sal_uInt16)nColumnCount; +} + + + + +sal_uInt16 PreviewValueSet::CalculateRowCount (sal_uInt16 nColumnCount) const +{ + int nRowCount = 0; + int nItemCount = GetItemCount(); + if (nColumnCount > 0) + { + nRowCount = (nItemCount+nColumnCount-1) / nColumnCount; + if (nRowCount < 1) + nRowCount = 1; + } + + return (sal_uInt16)nRowCount; +} + + + + +sal_Int32 PreviewValueSet::GetPreferredWidth (sal_Int32 nHeight) +{ + int nPreferredWidth (maPreviewSize.Width() + 2*mnBorderWidth); + + // Get height of each row. + int nItemHeight (maPreviewSize.Height() + 2*mnBorderHeight); + + // Calculate the row- and column count and from the later the preferred + // width. + int nRowCount = nHeight / nItemHeight; + if (nRowCount > 0) + { + int nColumnCount = (GetItemCount()+nRowCount-1) / nRowCount; + if (nColumnCount > 0) + nPreferredWidth = (maPreviewSize.Width() + 2*mnBorderWidth) + * nColumnCount; + } + + return nPreferredWidth; +} + + + + +sal_Int32 PreviewValueSet::GetPreferredHeight (sal_Int32 nWidth) +{ + int nRowCount (CalculateRowCount(CalculateColumnCount(nWidth))); + int nItemHeight (maPreviewSize.Height()); + + return nRowCount * (nItemHeight + 2*mnBorderHeight); +} + + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/PreviewValueSet.hxx b/sd/source/ui/sidebar/PreviewValueSet.hxx new file mode 100644 index 000000000000..86fe8b198136 --- /dev/null +++ b/sd/source/ui/sidebar/PreviewValueSet.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_PREVIEW_VALUE_SET_HXX +#define SD_SIDEBAR_PANELS_PREVIEW_VALUE_SET_HXX + +#include <svtools/valueset.hxx> + + +namespace sd { namespace sidebar { + + +/** Adapt the svtools valueset to the needs of the master page controlls. +*/ +class PreviewValueSet + : public ValueSet +{ +public: + PreviewValueSet (::Window* pParent); + ~PreviewValueSet (void); + + void SetRightMouseClickHandler (const Link& rLink); + virtual void Resize (void); + + void SetPreviewSize (const Size& rSize); + + sal_Int32 GetPreferredWidth (sal_Int32 nHeight); + sal_Int32 GetPreferredHeight (sal_Int32 nWidth); + + /** Set the number of rows and columns according to the current number + of items. Call this method when new items have been inserted. + */ + void Rearrange (bool bForceRequestResize = false); + +protected: + virtual void MouseButtonDown (const MouseEvent& rEvent); + +private: + Link maRightMouseClickHandler; + Size maPreviewSize; + const int mnBorderWidth; + const int mnBorderHeight; + const int mnMaxColumnCount; + + sal_uInt16 CalculateColumnCount (int nWidth) const; + sal_uInt16 CalculateRowCount (sal_uInt16 nColumnCount) const; +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx b/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx new file mode 100644 index 000000000000..f556aff07044 --- /dev/null +++ b/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "RecentMasterPagesSelector.hxx" + +#include "ViewShellBase.hxx" +#include "RecentlyUsedMasterPages.hxx" +#include "MasterPageContainerProviders.hxx" +#include "MasterPageObserver.hxx" +#include "SidebarShellManager.hxx" +#include "sdpage.hxx" +#include "drawdoc.hxx" +#include "app.hrc" +#include "helpids.h" + +#include <vcl/bitmap.hxx> + +namespace sd { namespace sidebar { + + +MasterPagesSelector* RecentMasterPagesSelector::Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) +{ + SdDrawDocument* pDocument = rViewShellBase.GetDocument(); + if (pDocument == NULL) + return NULL; + + ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer()); + + MasterPagesSelector* pSelector( + new RecentMasterPagesSelector ( + pParent, + *pDocument, + rViewShellBase, + pContainer, + rxSidebar)); + pSelector->LateInit(); + pSelector->SetHelpId(HID_SD_TASK_PANE_PREVIEW_RECENT); + + return pSelector; +} + + + + +RecentMasterPagesSelector::RecentMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar) + : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar) +{ +} + + + + +RecentMasterPagesSelector::~RecentMasterPagesSelector (void) +{ + RecentlyUsedMasterPages::Instance().RemoveEventListener ( + LINK(this,RecentMasterPagesSelector,MasterPageListListener)); +} + + + + +void RecentMasterPagesSelector::LateInit (void) +{ + MasterPagesSelector::LateInit(); + + MasterPagesSelector::Fill(); + RecentlyUsedMasterPages::Instance().AddEventListener ( + LINK(this,RecentMasterPagesSelector,MasterPageListListener)); +} + + + + +IMPL_LINK_NOARG(RecentMasterPagesSelector, MasterPageListListener) +{ + MasterPagesSelector::Fill(); + return 0; +} + + + + +void RecentMasterPagesSelector::Fill (ItemList& rItemList) +{ + // Create a set of names of the master pages used by the document. + MasterPageObserver::MasterPageNameSet aCurrentNames; + sal_uInt16 nMasterPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD); + sal_uInt16 nIndex; + for (nIndex=0; nIndex<nMasterPageCount; nIndex++) + { + SdPage* pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD); + if (pMasterPage != NULL) + aCurrentNames.insert (pMasterPage->GetName()); + } + MasterPageObserver::MasterPageNameSet::iterator aI; + + // Insert the recently used master pages that are currently not used. + RecentlyUsedMasterPages& rInstance (RecentlyUsedMasterPages::Instance()); + int nPageCount = rInstance.GetMasterPageCount(); + for (nIndex=0; nIndex<nPageCount; nIndex++) + { + // Add an entry when a) the page is already known to the + // MasterPageContainer, b) the style name is empty, i.e. it has not yet + // been loaded (and thus can not be in use) or otherwise c) the + // style name is not currently in use. + MasterPageContainer::Token aToken (rInstance.GetTokenForIndex(nIndex)); + if (aToken != MasterPageContainer::NIL_TOKEN) + { + String sStyleName (mpContainer->GetStyleNameForToken(aToken)); + if (sStyleName.Len()==0 + || aCurrentNames.find(sStyleName) == aCurrentNames.end()) + { + rItemList.push_back(aToken); + } + } + } +} + + + + +void RecentMasterPagesSelector::AssignMasterPageToPageList ( + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) +{ + sal_uInt16 nSelectedItemId = PreviewValueSet::GetSelectItemId(); + + MasterPagesSelector::AssignMasterPageToPageList(pMasterPage, rpPageList); + + // Restore the selection. + if (PreviewValueSet::GetItemCount() > 0) + { + if (PreviewValueSet::GetItemCount() >= nSelectedItemId) + PreviewValueSet::SelectItem(nSelectedItemId); + else + PreviewValueSet::SelectItem(PreviewValueSet::GetItemCount()); + } +} + + + + +void RecentMasterPagesSelector::ProcessPopupMenu (Menu& rMenu) +{ + if (rMenu.GetItemPos(SID_TP_EDIT_MASTER) != MENU_ITEM_NOTFOUND) + rMenu.EnableItem(SID_TP_EDIT_MASTER, sal_False); +} + + + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx b/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx new file mode 100644 index 000000000000..9c1358191bda --- /dev/null +++ b/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_RECENT_MASTER_PAGES_SELECTOR_HXX +#define SD_SIDEBAR_PANELS_RECENT_MASTER_PAGES_SELECTOR_HXX + +#include "MasterPagesSelector.hxx" + +namespace sd { namespace sidebar { + + +/** Show the recently used master pages (that are not currently used). +*/ +class RecentMasterPagesSelector + : public MasterPagesSelector +{ +public: + static MasterPagesSelector* Create ( + ::Window* pParent, + ViewShellBase& rViewShellBase, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + +protected: + DECL_LINK(MasterPageListListener, void*); + virtual void Fill (ItemList& rItemList); + + using sd::sidebar::MasterPagesSelector::Fill; + + /** Forward this call to the base class but save and restore the + currently selected item. + Assign the given master page to the list of pages. + @param pMasterPage + This master page will usually be a member of the list of all + available master pages as provided by the MasterPageContainer. + @param rPageList + The pages to which to assign the master page. These pages may + be slides or master pages themselves. + */ + virtual void AssignMasterPageToPageList ( + SdPage* pMasterPage, + const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList); + + virtual void ProcessPopupMenu (Menu& rMenu); + +private: + RecentMasterPagesSelector ( + ::Window* pParent, + SdDrawDocument& rDocument, + ViewShellBase& rBase, + const ::boost::shared_ptr<MasterPageContainer>& rpContainer, + const cssu::Reference<css::ui::XSidebar>& rxSidebar); + virtual ~RecentMasterPagesSelector (void); + + virtual void LateInit (void); +}; + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx b/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx new file mode 100644 index 000000000000..be41524594c9 --- /dev/null +++ b/sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx @@ -0,0 +1,479 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "RecentlyUsedMasterPages.hxx" +#include "MasterPageObserver.hxx" +#include "MasterPagesSelector.hxx" +#include "MasterPageDescriptor.hxx" +#include "tools/ConfigurationAccess.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" + +#include <algorithm> +#include <vector> + +#include <comphelper/processfactory.hxx> +#include "unomodel.hxx" +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XDrawPages.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <unotools/confignode.hxx> +#include <osl/doublecheckedlocking.h> +#include <osl/getglobalmutex.hxx> + +using namespace ::std; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + +namespace { + +static const OUString& GetPathToImpressConfigurationRoot (void) +{ + static const OUString sPathToImpressConfigurationRoot ("/org.openoffice.Office.Impress/"); + return sPathToImpressConfigurationRoot; +} +static const OUString& GetPathToSetNode (void) +{ + static const OUString sPathToSetNode("MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages"); + return sPathToSetNode; +} + + +class Descriptor +{ +public: + OUString msURL; + OUString msName; + ::sd::sidebar::MasterPageContainer::Token maToken; + Descriptor (const OUString& rsURL, const OUString& rsName) + : msURL(rsURL), + msName(rsName), + maToken(::sd::sidebar::MasterPageContainer::NIL_TOKEN) + {} + Descriptor (::sd::sidebar::MasterPageContainer::Token aToken, + const OUString& rsURL, const OUString& rsName) + : msURL(rsURL), + msName(rsName), + maToken(aToken) + {} + class TokenComparator + { public: + TokenComparator(::sd::sidebar::MasterPageContainer::Token aToken) + : maToken(aToken) {} + bool operator () (const Descriptor& rDescriptor) + { return maToken==rDescriptor.maToken; } + private: ::sd::sidebar::MasterPageContainer::Token maToken; + }; +}; + +} // end of anonymous namespace + + + + +namespace sd { namespace sidebar { + +class RecentlyUsedMasterPages::MasterPageList : public ::std::vector<Descriptor> +{ +public: + MasterPageList (void) {} +}; + + +RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL; + + +RecentlyUsedMasterPages& RecentlyUsedMasterPages::Instance (void) +{ + if (mpInstance == NULL) + { + ::osl::GetGlobalMutex aMutexFunctor; + ::osl::MutexGuard aGuard (aMutexFunctor()); + if (mpInstance == NULL) + { + RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages(); + pInstance->LateInit(); + SdGlobalResourceContainer::Instance().AddResource ( + ::std::auto_ptr<SdGlobalResource>(pInstance)); + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + mpInstance = pInstance; + } + } + else { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } + + return *mpInstance; +} + + + + +RecentlyUsedMasterPages::RecentlyUsedMasterPages (void) + : maListeners(), + mpMasterPages(new MasterPageList()), + mnMaxListSize(8), + mpContainer(new MasterPageContainer()) +{ +} + + + + +RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void) +{ + Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener)); + mpContainer->RemoveChangeListener(aLink); + + MasterPageObserver::Instance().RemoveEventListener( + LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener)); +} + + + + +void RecentlyUsedMasterPages::LateInit (void) +{ + Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener)); + mpContainer->AddChangeListener(aLink); + + LoadPersistentValues (); + MasterPageObserver::Instance().AddEventListener( + LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener)); +} + + + + +void RecentlyUsedMasterPages::LoadPersistentValues (void) +{ + try + { + tools::ConfigurationAccess aConfiguration ( + GetPathToImpressConfigurationRoot(), + tools::ConfigurationAccess::READ_ONLY); + Reference<container::XNameAccess> xSet ( + aConfiguration.GetConfigurationNode(GetPathToSetNode()), + UNO_QUERY); + if ( ! xSet.is()) + return; + + const OUString sURLMemberName("URL"); + const OUString sNameMemberName("Name"); + OUString sURL; + OUString sName; + + // Read the names and URLs of the master pages. + Sequence<OUString> aKeys (xSet->getElementNames()); + mpMasterPages->clear(); + mpMasterPages->reserve(aKeys.getLength()); + for (int i=0; i<aKeys.getLength(); i++) + { + Reference<container::XNameAccess> xSetItem ( + xSet->getByName(aKeys[i]), UNO_QUERY); + if (xSetItem.is()) + { + Any aURL (xSetItem->getByName(sURLMemberName)); + Any aName (xSetItem->getByName(sNameMemberName)); + aURL >>= sURL; + aName >>= sName; + SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor( + MasterPageContainer::TEMPLATE, + -1, + sURL, + String(), + sName, + false, + ::boost::shared_ptr<PageObjectProvider>( + new TemplatePageObjectProvider(sURL)), + ::boost::shared_ptr<PreviewProvider>( + new TemplatePreviewProvider(sURL)))); + // For user supplied templates we use a different + // preview provider: The preview in the document shows + // not only shapes on the master page but also shapes on + // the foreground. This is misleading and therefore + // these previews are discarded and created directly + // from the page objects. + if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER) + pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>( + new PagePreviewProvider()); + MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor)); + mpMasterPages->push_back(Descriptor(aToken,sURL,sName)); + } + } + + ResolveList(); + } + catch (Exception&) + { + // Ignore exception. + } +} + + + + +void RecentlyUsedMasterPages::SavePersistentValues (void) +{ + try + { + tools::ConfigurationAccess aConfiguration ( + GetPathToImpressConfigurationRoot(), + tools::ConfigurationAccess::READ_WRITE); + Reference<container::XNameContainer> xSet ( + aConfiguration.GetConfigurationNode(GetPathToSetNode()), + UNO_QUERY); + if ( ! xSet.is()) + return; + + // Clear the set. + Sequence<OUString> aKeys (xSet->getElementNames()); + sal_Int32 i; + for (i=0; i<aKeys.getLength(); i++) + xSet->removeByName (aKeys[i]); + + // Fill it with the URLs of this object. + const OUString sURLMemberName("URL"); + const OUString sNameMemberName("Name"); + Any aValue; + Reference<lang::XSingleServiceFactory> xChildFactory ( + xSet, UNO_QUERY); + if ( ! xChildFactory.is()) + return; + MasterPageList::const_iterator iDescriptor; + sal_Int32 nIndex(0); + for (iDescriptor=mpMasterPages->begin(); + iDescriptor!=mpMasterPages->end(); + ++iDescriptor,++nIndex) + { + // Create new child. + OUString sKey ("index_"); + sKey += OUString::valueOf(nIndex); + Reference<container::XNameReplace> xChild( + xChildFactory->createInstance(), UNO_QUERY); + if (xChild.is()) + { + xSet->insertByName (sKey, makeAny(xChild)); + + aValue <<= OUString(iDescriptor->msURL); + xChild->replaceByName (sURLMemberName, aValue); + + aValue <<= OUString(iDescriptor->msName); + xChild->replaceByName (sNameMemberName, aValue); + } + } + + // Write the data back to disk. + aConfiguration.CommitChanges(); + } + catch (Exception&) + { + // Ignore exception. + } +} + + + + +void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener) +{ + if (::std::find ( + maListeners.begin(), + maListeners.end(), + rEventListener) == maListeners.end()) + { + maListeners.push_back (rEventListener); + } +} + + + + +void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener) +{ + maListeners.erase ( + ::std::find ( + maListeners.begin(), + maListeners.end(), + rEventListener)); +} + + + + +int RecentlyUsedMasterPages::GetMasterPageCount (void) const +{ + return mpMasterPages->size(); +} + + + + +MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const +{ + if(nIndex<mpMasterPages->size()) + return (*mpMasterPages)[nIndex].maToken; + else + return MasterPageContainer::NIL_TOKEN; +} + + + + +void RecentlyUsedMasterPages::SendEvent (void) +{ + ::std::vector<Link>::iterator aLink (maListeners.begin()); + ::std::vector<Link>::iterator aEnd (maListeners.end()); + while (aLink!=aEnd) + { + aLink->Call (NULL); + ++aLink; + } +} + + + + +IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener, + MasterPageObserverEvent*, pEvent) +{ + switch (pEvent->meType) + { + case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED: + case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS: + AddMasterPage( + mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName)); + break; + + case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED: + // Do not change the list of recently master pages (the deleted + // page was recently used) but tell the listeners. They may want + // to update their lists. + SendEvent(); + break; + } + return 0; +} + + + + +IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener, + MasterPageContainerChangeEvent*, pEvent) +{ + if (pEvent != NULL) + switch (pEvent->meEventType) + { + case MasterPageContainerChangeEvent::CHILD_ADDED: + case MasterPageContainerChangeEvent::CHILD_REMOVED: + case MasterPageContainerChangeEvent::INDEX_CHANGED: + case MasterPageContainerChangeEvent::INDEXES_CHANGED: + ResolveList(); + break; + + default: + // Ignored. + break; + } + return 0; +} + + + + +void RecentlyUsedMasterPages::AddMasterPage ( + MasterPageContainer::Token aToken, + bool bMakePersistent) +{ + // For the page to be inserted the token has to be valid and the page + // has to have a valid URL. This excludes master pages that do not come + // from template files. + if (aToken != MasterPageContainer::NIL_TOKEN + && mpContainer->GetURLForToken(aToken).Len()>0) + { + + MasterPageList::iterator aIterator ( + ::std::find_if(mpMasterPages->begin(),mpMasterPages->end(), + Descriptor::TokenComparator(aToken))); + if (aIterator != mpMasterPages->end()) + { + // When an entry for the given token already exists then remove + // it now and insert it later at the head of the list. + mpMasterPages->erase (aIterator); + } + + mpMasterPages->insert(mpMasterPages->begin(), + Descriptor( + aToken, + mpContainer->GetURLForToken(aToken), + mpContainer->GetStyleNameForToken(aToken))); + + // Shorten list to maximal size. + while (mpMasterPages->size() > mnMaxListSize) + { + mpMasterPages->pop_back (); + } + + if (bMakePersistent) + SavePersistentValues (); + SendEvent(); + } +} + + + + +void RecentlyUsedMasterPages::ResolveList (void) +{ + bool bNotify (false); + + MasterPageList::iterator iDescriptor; + for (iDescriptor=mpMasterPages->begin(); iDescriptor!=mpMasterPages->end(); ++iDescriptor) + { + if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN) + { + MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL)); + iDescriptor->maToken = aToken; + if (aToken != MasterPageContainer::NIL_TOKEN) + bNotify = true; + } + else + { + if ( ! mpContainer->HasToken(iDescriptor->maToken)) + { + iDescriptor->maToken = MasterPageContainer::NIL_TOKEN; + bNotify = true; + } + } + } + + if (bNotify) + SendEvent(); +} + + +} } // end of namespace sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx b/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx new file mode 100644 index 000000000000..4fb0aa599851 --- /dev/null +++ b/sd/source/ui/sidebar/RecentlyUsedMasterPages.hxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_PANELS_RECENTLY_USED_MASTER_PAGES_HXX +#define SD_SIDEBAR_PANELS_RECENTLY_USED_MASTER_PAGES_HXX + +#include "tools/SdGlobalResourceContainer.hxx" +#include <osl/mutex.hxx> +#include <tools/link.hxx> +#include <vcl/image.hxx> +#include <vector> + +#include "DrawDocShell.hxx" +#include "MasterPageContainer.hxx" +#include <com/sun/star/uno/XInterface.hpp> + +namespace sd { +class MasterPageObserverEvent; +} + + +namespace sd { namespace sidebar { + +/** This singleton holds a list of the most recently used master pages. +*/ +class RecentlyUsedMasterPages + : public SdGlobalResource +{ +public: + /** Return the single instance of this class. + */ + static RecentlyUsedMasterPages& Instance (void); + + void AddEventListener (const Link& rEventListener); + void RemoveEventListener (const Link& rEventListener); + + int GetMasterPageCount (void) const; + MasterPageContainer::Token GetTokenForIndex (sal_uInt32 nIndex) const; + +private: + /** The single instance of this class. It is created on demand when + Instance() is called for the first time. + */ + static RecentlyUsedMasterPages* mpInstance; + + ::std::vector<Link> maListeners; + + class MasterPageList; + ::std::auto_ptr<MasterPageList> mpMasterPages; + unsigned long int mnMaxListSize; + ::boost::shared_ptr<MasterPageContainer> mpContainer; + + RecentlyUsedMasterPages (void); + virtual ~RecentlyUsedMasterPages (void); + + /** Call this method after a new object has been created. + */ + void LateInit (void); + + /// The copy constructor is not implemented. Do not use! + RecentlyUsedMasterPages (const RecentlyUsedMasterPages&); + + /// The assignment operator is not implemented. Do not use! + RecentlyUsedMasterPages& operator= (const RecentlyUsedMasterPages&); + + void SendEvent (void); + DECL_LINK(MasterPageChangeListener, MasterPageObserverEvent*); + DECL_LINK(MasterPageContainerChangeListener, MasterPageContainerChangeEvent*); + + /** Add a descriptor for the specified master page to the end of the + list of most recently used master pages. When the page is already a + member of that list the associated descriptor is moved to the end of + the list to make it the most recently used entry. + @param bMakePersistent + When <TRUE/> is given then the new list of recently used master + pages is written back into the configuration to make it + persistent. Giving <FALSE/> to ommit this is used while loading + the persistent list from the configuration. + */ + void AddMasterPage ( + MasterPageContainer::Token aToken, + bool bMakePersistent = true); + + /** Load the list of recently used master pages from the registry where + it was saved to make it persistent. + */ + void LoadPersistentValues (void); + + /** Save the list of recently used master pages to the registry to make + it presistent. + */ + void SavePersistentValues (void); + + void ResolveList (void); +}; + + + +} } // end of namespace sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/SidebarFocusManager.hxx b/sd/source/ui/sidebar/SidebarFocusManager.hxx new file mode 100644 index 000000000000..4ae747ebe468 --- /dev/null +++ b/sd/source/ui/sidebar/SidebarFocusManager.hxx @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_TOOLPANEL_FOCUS_MANAGER_HXX +#define SD_TOOLPANEL_FOCUS_MANAGER_HXX + +#include <tools/link.hxx> + +#include <memory> + +class KeyCode; +class VclSimpleEvent; +class Window; + +namespace sd { namespace toolpanel { + +/** On certain key presses the focus is moved from one window to another. + For this to work every window that wants its focus managed has to + register or be registered and tell where to put the focus on what key + press. +*/ +class FocusManager +{ +public: + /** Return an instance of the focus manager. + */ + static FocusManager& Instance (void); + + /** Register a link from one window to another so that any time the + specified key is pressed while the source window is focused, the + focus is transferred to the target window. + @param pSource + The window from which the focus will be transferred. + @param pTarget + The window to which the focus will be transferred. + @param rKey + The key for which the focus is transferred from the source + window to the target window. + */ + void RegisterLink ( + ::Window* pSource, + ::Window* pTarget, + const KeyCode& rKey); + + /** Register a link that will move the focus from the source window to + the target window when the source window is focused and KEY_ESCAPE + is pressed. + @param pSource + The window from which the focus will be transferred. + @param pTarget + The window to which the focus will be transferred. + */ + void RegisterUpLink (::Window* pSource, ::Window* pTarget); + + /** Register a link that will move the focus from the source window to + the target window when the source window is focused and KEY_RETURN + is pressed. + @param pSource + The window from which the focus will be transferred. + @param pTarget + The window to which the focus will be transferred. + */ + void RegisterDownLink (::Window* pSource, ::Window* pTarget); + + /** Remove all links from the source window to the target window. When + there are links from the target window to the source window then + these are not touced. + */ + void RemoveLinks ( + ::Window* pSource, + ::Window* pTarget); + + /** Let the focus manager transfer the focus from the specified source + window to a target window that is determined according the the + registered links and the given key code. + When there is no rule for this combination of source window and key + code then the focus stays where it is. + */ + bool TransferFocus (::Window* pSource, const KeyCode& rCode); + +private: + friend struct FocusManagerCreator; + + class LinkMap; + ::std::auto_ptr<LinkMap> mpLinks; + + FocusManager (void); + ~FocusManager (void); + + /** Clear the list of focus transfer links. This removes all window + listeners. + */ + void Clear (void); + + /** Remove all links from or to the given window. + */ + void RemoveLinks (::Window* pWindow); + + /** Unregister as event listener from the given window when there are no + links from this window anymore. + */ + void RemoveUnusedEventListener (::Window* pWindow); + + /** Listen for key events and on KEY_RETURN go down and on + KEY_ESCAPE go up. + */ + DECL_LINK(WindowEventListener, VclSimpleEvent*); +}; + +} } // end of namespace ::sd::toolpanel + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/SidebarShellManager.cxx b/sd/source/ui/sidebar/SidebarShellManager.cxx new file mode 100644 index 000000000000..526389e42a8e --- /dev/null +++ b/sd/source/ui/sidebar/SidebarShellManager.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + + +#include "TaskPaneShellManager.hxx" + +#include "SidebarShellManager.hxx" +#include "ViewShellManager.hxx" +#include <tools/diagnose_ex.h> +#include <vcl/window.hxx> + +#include <algorithm> + +namespace sd { namespace sidebar { + +SidebarShellManager::SidebarShellManager ( + const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager, + const ViewShell& rViewShell) + : mpViewShellManager(rpViewShellManager), + mrViewShell(rViewShell), + maSubShells() +{ +} + + + + +SidebarShellManager::~SidebarShellManager (void) +{ + while ( ! maSubShells.empty()) + RemoveSubShell(maSubShells.begin()->second.mpShell); +} + + + + +SfxShell* SidebarShellManager::CreateShell( ShellId nId, ::Window* , FrameView* ) +{ + SubShells::const_iterator iShell (maSubShells.find(nId)); + if (iShell != maSubShells.end()) + return iShell->second.mpShell; + else + return NULL; +} + + + + +void SidebarShellManager::ReleaseShell (SfxShell* ) +{ + // Nothing to do. +} + +void SidebarShellManager::AddSubShell ( + ShellId nId, + SfxShell* pShell, + ::Window* pWindow) +{ + if (pShell != NULL) + { + maSubShells[nId] = ShellDescriptor(pShell,pWindow); + if (pWindow != NULL) + { + pWindow->AddEventListener(LINK(this,SidebarShellManager,WindowCallback)); + if (pWindow->IsReallyVisible()) + mpViewShellManager->ActivateSubShell(mrViewShell, nId); + } + else + mpViewShellManager->ActivateSubShell(mrViewShell, nId); + } +} + + + + +void SidebarShellManager::RemoveSubShell (const ShellId i_nShellId) +{ + SubShells::iterator pos = maSubShells.find( i_nShellId ); + ENSURE_OR_RETURN_VOID( pos != maSubShells.end(), "no shell for this ID" ); + if ( pos->second.mpWindow != NULL ) + { + pos->second.mpWindow->RemoveEventListener( LINK( this, SidebarShellManager, WindowCallback ) ); + } + mpViewShellManager->DeactivateSubShell( mrViewShell, pos->first ); + maSubShells.erase( pos ); +} + + + + +void SidebarShellManager::RemoveSubShell (const SfxShell* pShell) +{ + if (pShell != NULL) + { + SubShells::iterator iShell; + for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell) + if (iShell->second.mpShell == pShell) + { + if (iShell->second.mpWindow != NULL) + iShell->second.mpWindow->RemoveEventListener( + LINK(this,SidebarShellManager,WindowCallback)); + mpViewShellManager->DeactivateSubShell(mrViewShell,iShell->first); + maSubShells.erase(iShell); + break; + } + } +} + + + + +void SidebarShellManager::MoveToTop (SfxShell* pShell) +{ + SubShells::const_iterator iShell; + for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell) + if (iShell->second.mpShell == pShell) + { + ViewShellManager::UpdateLock aLocker (mpViewShellManager); + mpViewShellManager->MoveSubShellToTop(mrViewShell,iShell->first); + mpViewShellManager->MoveToTop(mrViewShell); + break; + } +} + + + + +IMPL_LINK(SidebarShellManager, WindowCallback, VclWindowEvent*, pEvent) +{ + if (pEvent != NULL) + { + SubShells::const_iterator iShell; + ::Window* pWindow = pEvent->GetWindow(); + for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell) + if (iShell->second.mpWindow == pWindow) + break; + if (iShell != maSubShells.end()) + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_SHOW: + mpViewShellManager->ActivateSubShell(mrViewShell,iShell->first); + break; + + case VCLEVENT_WINDOW_HIDE: + // Do not activate the sub shell. This leads to + // problems with shapes currently being in text edit + // mode: Deactivating the shell leads to leaving the + // text editing mode. + // mpViewShellManager->DeactivateSubShell(mrViewShell,iShell->first); + break; + } + } + + return 0; +} + + +} } // end of namespace ::sd::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/SidebarShellManager.hxx b/sd/source/ui/sidebar/SidebarShellManager.hxx new file mode 100644 index 000000000000..eec84c60620d --- /dev/null +++ b/sd/source/ui/sidebar/SidebarShellManager.hxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef SD_SIDEBAR_SHELL_MANAGER_HXX +#define SD_SIDEBAR_SHELL_MANAGER_HXX + +#include "ShellFactory.hxx" +#include "ViewShellManager.hxx" +#include <tools/link.hxx> +#include <map> + +class FrameView; +class SfxShell; +class VclWindowEvent; +class Window; + +namespace sd { +class ViewShell; +} + +namespace sd { namespace sidebar { + +/** The TaskPaneShellManager implements the ViewShellManager::ShellFactory + interface. However, it does not create or delete shells. It only + gives the ViewShellManager access to the sub shells of the + ToolPanelViewShell. Life time control of the sub shells is managed by + the sub shells themselves. +*/ +class SidebarShellManager + : public ShellFactory<SfxShell> +{ +public: + /** Create a shell manager that manages the stacked shells for the given + view shell. It works together with the given view shell manager. + */ + SidebarShellManager ( + const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager, + const ViewShell& rViewShell); + ~SidebarShellManager (void); + + /** Return the requested sub shell. + @param nId + The id of the requested sub shell. + @return + When there is no sub shell currently registered under the given + id then NULL is returned. + */ + virtual SfxShell* CreateShell ( + ShellId nId, + ::Window* pParentWindow, + FrameView* pFrameView = NULL); + + virtual void ReleaseShell (SfxShell* pShell); + + /** Add a sub shell to the set of sub shells managed by the + TaskPaneShellManager. Only shells added by this method are returned + by CreateShell(). + */ + void AddSubShell (ShellId nId, SfxShell* pShell, ::Window* pWindow); + + /** Remove the given shell from the set of sub shells managed by the + TaskPaneShellManager. Following calls to CreateShell() will return + NULL when this shell is requested. + */ + void RemoveSubShell (const SfxShell* pShell); + /** removes the shell given by its ID from the set of sub shells managed by the + TaskPaneShellManager. Subsequent calls to CreateShell() will return + NULL when this shell is requested. + */ + void RemoveSubShell (const ShellId i_nShellId); + + /** Move the given sub-shell to the top of the local shell stack. + Furthermore move the view shell whose sub-shells this class manages + to the top of the global shell stack. + */ + void MoveToTop (SfxShell* pShell); + + DECL_LINK(WindowCallback,VclWindowEvent*); + +private: + ::boost::shared_ptr<ViewShellManager> mpViewShellManager; + + /// The view shell whose sub-shells this class manages. + const ViewShell& mrViewShell; + + class ShellDescriptor { public: + SfxShell* mpShell; + ::Window* mpWindow; + ShellDescriptor(void) : mpShell(NULL),mpWindow(NULL){} + ShellDescriptor(SfxShell*pShell,::Window*pWindow) : mpShell(pShell),mpWindow(pWindow){} + }; + typedef ::std::map<ShellId,ShellDescriptor> SubShells; + SubShells maSubShells; +}; + +} } // end of namespace ::sd::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/SlideTransitionPanel.cxx b/sd/source/ui/sidebar/SlideTransitionPanel.cxx new file mode 100644 index 000000000000..3b4d994d207b --- /dev/null +++ b/sd/source/ui/sidebar/SlideTransitionPanel.cxx @@ -0,0 +1,71 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include "SlideTransitionPanel.hxx" + +#include "ViewShellBase.hxx" + + +namespace sd { + extern ::Window* createSlideTransitionPanel (::Window* pParent, ViewShellBase& rBase); + extern sal_Int32 getSlideTransitionPanelMinimumHeight (::Window* pParent); +} + + + + +namespace sd { namespace sidebar { + + +SlideTransitionPanel::SlideTransitionPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) + : PanelBase(pParentWindow, rViewShellBase) +{ +#ifdef DEBUG + SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:SlideTransitionPanel"))); +#endif +} + + + + +SlideTransitionPanel::~SlideTransitionPanel (void) +{ +} + + + + +::Window* SlideTransitionPanel::CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) +{ + return createSlideTransitionPanel(pParentWindow, rViewShellBase); +} + + + + +css::ui::LayoutSize SlideTransitionPanel::GetHeightForWidth (const sal_Int32 /*nWidth*/) +{ + const sal_Int32 nMinimumHeight(getSlideTransitionPanelMinimumHeight(mpWrappedControl.get())); + return css::ui::LayoutSize(nMinimumHeight,-1, nMinimumHeight); +} + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/SlideTransitionPanel.hxx b/sd/source/ui/sidebar/SlideTransitionPanel.hxx new file mode 100644 index 000000000000..40094feac70b --- /dev/null +++ b/sd/source/ui/sidebar/SlideTransitionPanel.hxx @@ -0,0 +1,46 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_PANELS_SLIDE_TRANSITION_PANEL_HXX +#define SD_SIDEBAR_PANELS_SLIDE_TRANSITION_PANEL_HXX + +#include "PanelBase.hxx" + +namespace sd { namespace sidebar { + +class SlideTransitionPanel + : public PanelBase +{ +public: + SlideTransitionPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); + virtual ~SlideTransitionPanel (void); + + // ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + +protected: + virtual ::Window* CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); +}; + +} } // end of namespace sd::sidebar + + +#endif diff --git a/sd/source/ui/sidebar/TableDesignPanel.cxx b/sd/source/ui/sidebar/TableDesignPanel.cxx new file mode 100644 index 000000000000..28ceb65cfbbd --- /dev/null +++ b/sd/source/ui/sidebar/TableDesignPanel.cxx @@ -0,0 +1,69 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#include "precompiled_sd.hxx" + +#include "TableDesignPanel.hxx" + +#include "ViewShellBase.hxx" + + +namespace sd { + extern ::Window * createTableDesignPanel (::Window* pParent, ViewShellBase& rBase); +} + + +namespace sd { namespace sidebar { + + +TableDesignPanel::TableDesignPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) + : PanelBase(pParentWindow, rViewShellBase) +{ +#ifdef DEBUG + SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:TableDesignPanel"))); +#endif +} + + + + +TableDesignPanel::~TableDesignPanel (void) +{ +} + + + + +::Window* TableDesignPanel::CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase) +{ + return createTableDesignPanel(pParentWindow, rViewShellBase); +} + + + + +css::ui::LayoutSize TableDesignPanel::GetHeightForWidth (const sal_Int32 nWidth) +{ + //TODO: make the sizes depend on the font size. + return css::ui::LayoutSize(350,-1, 400); +} + +} } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/TableDesignPanel.hxx b/sd/source/ui/sidebar/TableDesignPanel.hxx new file mode 100644 index 000000000000..8a6470b3c77c --- /dev/null +++ b/sd/source/ui/sidebar/TableDesignPanel.hxx @@ -0,0 +1,45 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef SD_SIDEBAR_PANELS_TABLE_DESIGN_PANEL_HXX +#define SD_SIDEBAR_PANELS_TABLE_DESIGN_PANEL_HXX + +#include "PanelBase.hxx" + +namespace sd { namespace sidebar { + +class TableDesignPanel + : public PanelBase +{ +public: + TableDesignPanel ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); + virtual ~TableDesignPanel (void); + + // ILayoutableWindow + virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + +protected: + virtual ::Window* CreateWrappedControl ( + ::Window* pParentWindow, + ViewShellBase& rViewShellBase); +}; + +} } // end of namespace sd::sidebar + +#endif diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index c36b7d3496bc..6b9c69048143 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -191,7 +191,8 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) // in the tool pane. if (mrSlideSorter.GetViewShellBase() != NULL) framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase()) - ->RequestTaskPanel(sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL); + ->RequestSidebarPanel( + sd::framework::FrameworkHelper::msSlideTransitionTaskPanelURL); rRequest.Ignore (); break; } diff --git a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx index 7191956d18b5..43ff8248132e 100644 --- a/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx +++ b/sd/source/ui/slidesorter/shell/SlideSorterViewShell.cxx @@ -46,6 +46,7 @@ #include "sdresid.hxx" #include "AccessibleSlideSorterView.hxx" #include "DrawDocShell.hxx" +#include "DrawViewShell.hxx" #include "FrameView.hxx" #include "SdUnoSlideView.hxx" #include "ViewShellManager.hxx" @@ -57,7 +58,10 @@ #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/request.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> #include <svx/svxids.hrc> +#include <sfx2/sidebar/EnumContext.hxx> +#include <svx/sidebar/ContextChangeEventMultiplexer.hxx> #include <com/sun/star/drawing/framework/XControllerManager.hpp> #include <com/sun/star/drawing/framework/ResourceId.hpp> #include <cppuhelper/bootstrap.hxx> @@ -72,12 +76,14 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::sd::framework::FrameworkHelper; +using ::sfx2::sidebar::EnumContext; namespace sd { namespace slidesorter { SFX_IMPL_INTERFACE(SlideSorterViewShell, SfxShell, SdResId(STR_SLIDESORTERVIEWSHELL)) { + SFX_CHILDWINDOW_REGISTRATION(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); } @@ -215,12 +221,11 @@ SlideSorterViewShell* SlideSorterViewShell::GetSlideSorter (ViewShellBase& rBase { SlideSorterViewShell* pViewShell = NULL; - // Test the center, left, and then the right pane for showing a slide sorter. + // Test the center and left pane for showing a slide sorter. OUString aPaneURLs[] = { FrameworkHelper::msCenterPaneURL, FrameworkHelper::msFullScreenPaneURL, FrameworkHelper::msLeftImpressPaneURL, - FrameworkHelper::msRightPaneURL, OUString()}; try @@ -547,6 +552,50 @@ void SlideSorterViewShell::Activate (sal_Bool bIsMDIActivate) ViewShell::Activate(bIsMDIActivate); if (mbIsArrangeGUIElementsPending) ArrangeGUIElements(); + + // Determine and broadcast the context that belongs to the main view shell. + EnumContext::Context eContext = EnumContext::Context_Unknown; + ::boost::shared_ptr<ViewShell> pMainViewShell (GetViewShellBase().GetMainViewShell()); + ViewShell::ShellType eMainViewShellType ( + pMainViewShell + ? pMainViewShell->GetShellType() + : ViewShell::ST_NONE); + switch (eMainViewShellType) + { + case ViewShell::ST_IMPRESS: + eContext = EnumContext::Context_DrawPage; + if (pMainViewShell->ISA(DrawViewShell)) + { + DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell.get()); + if (pDrawViewShell && (pDrawViewShell->GetEditMode()== EM_MASTERPAGE)) + eContext = EnumContext::Context_MasterPage; + } + break; + + case ViewShell::ST_SLIDE_SORTER: + eContext = EnumContext::Context_SlidesorterPage; + break; + + case ViewShell::ST_NOTES: + eContext = EnumContext::Context_NotesPage; + break; + + default: + break; + } + ContextChangeEventMultiplexer::NotifyContextChange( + &GetViewShellBase(), + eContext); +} + + + + +void SlideSorterViewShell::Deactivate (sal_Bool /*bIsMDIActivate*/) +{ + ContextChangeEventMultiplexer::NotifyContextChange( + &GetViewShellBase(), + EnumContext::Context_Default); } diff --git a/sd/source/ui/table/TableDesignPane.cxx b/sd/source/ui/table/TableDesignPane.cxx index b02617702396..29b278c67b21 100644 --- a/sd/source/ui/table/TableDesignPane.cxx +++ b/sd/source/ui/table/TableDesignPane.cxx @@ -96,7 +96,7 @@ TableDesignPane::TableDesignPane( ::Window* pParent, ViewShellBase& rBase, bool { Window* pControlParent = mbModal ? pParent : this; - mxControls[FL_TABLE_STYLES].reset( new FixedLine( pControlParent, SdResId( FL_TABLE_STYLES + 1 ) ) ); + // mxControls[FL_TABLE_STYLES].reset( new FixedLine( pControlParent, SdResId( FL_TABLE_STYLES + 1 ) ) ); ValueSet* pValueSet = new ValueSet( pControlParent, SdResId( CT_TABLE_STYLES+1 ) ); mxControls[CT_TABLE_STYLES].reset( pValueSet ); @@ -113,7 +113,7 @@ TableDesignPane::TableDesignPane( ::Window* pParent, ViewShellBase& rBase, bool } pValueSet->SetSelectHdl (LINK(this, TableDesignPane, implValueSetHdl)); - mxControls[FL_STYLE_OPTIONS].reset( new FixedLine( pControlParent, SdResId( FL_STYLE_OPTIONS + 1 ) ) ); + // mxControls[FL_STYLE_OPTIONS].reset( new FixedLine( pControlParent, SdResId( FL_STYLE_OPTIONS + 1 ) ) ); sal_uInt16 i; for( i = CB_HEADER_ROW; i <= CB_BANDED_COLUMNS; ++i ) { @@ -123,7 +123,14 @@ TableDesignPane::TableDesignPane( ::Window* pParent, ViewShellBase& rBase, bool } for( i = 0; i < DESIGNPANE_CONTROL_COUNT; i++ ) - mnOrgOffsetY[i] = mxControls[i]->GetPosPixel().Y(); + { + if (mxControls[i]) + mnOrgOffsetY[i] = mxControls[i]->GetPosPixel().Y(); + else if (i > 0) + mnOrgOffsetY[i] = mnOrgOffsetY[i-1]; + else + mnOrgOffsetY[i] = 0; + } // get current controller and initialize listeners try @@ -170,6 +177,60 @@ void TableDesignPane::Resize() updateLayout(); } + + + +LayoutSize TableDesignPane::GetHeightForWidth (const sal_Int32 nWidth) +{ + if ( ! IsVisible() || nWidth<=0) + return LayoutSize(0,0,0); + + // Initialize the height with the offset above and below the value + // set and below the check boxes. + const Point aOffset (LogicToPixel( Point(3,3), MAP_APPFONT)); + sal_Int32 nHeight (3 * aOffset.Y()); + + // Add the height for the check boxes. + nHeight += mnOrgOffsetY[CB_BANDED_COLUMNS] - mnOrgOffsetY[CB_HEADER_ROW] + + mxControls[CB_BANDED_COLUMNS]->GetSizePixel().Height(); + + // Setup minimal and maximal heights that include all check boxes + // and a small or large value set. + const sal_Int32 nMinimalHeight (nHeight+100); + const sal_Int32 nMaximalHeight (nHeight+450); + + // Calculate the number of rows and columns and then add the + // preferred size of the value set. + ValueSet* pValueSet = static_cast< ValueSet* >( mxControls[CT_TABLE_STYLES].get() ); + if (pValueSet->GetItemCount() > 0) + { + Image aImage = pValueSet->GetItemImage(pValueSet->GetItemId(0)); + Size aItemSize = pValueSet->CalcItemSizePixel(aImage.GetSizePixel()); + aItemSize.Width() += 10; + aItemSize.Height() += 10; + + int nColumnCount = (pValueSet->GetSizePixel().Width() - pValueSet->GetScrollWidth()) / aItemSize.Width(); + if (nColumnCount < 1) + nColumnCount = 1; + + int nRowCount = (pValueSet->GetItemCount() + nColumnCount - 1) / nColumnCount; + if (nRowCount < 1) + nRowCount = 1; + + nHeight += nRowCount * aItemSize.Height(); + } + + // Clip the requested height. + if (nHeight<nMinimalHeight) + nHeight = nMinimalHeight; + else if (nHeight>nMaximalHeight) + nHeight = nMaximalHeight; + return LayoutSize(nMinimalHeight, nMaximalHeight, nHeight); +} + + + + // -------------------------------------------------------------------- static SfxBindings* getBindings( ViewShellBase& rBase ) @@ -366,16 +427,19 @@ void TableDesignPane::updateLayout() const long nStylesHeight = aPaneSize.Height() - nOptionsHeight; - // set with of controls to size of pane + // set width of controls to size of pane for( sal_Int32 nId = 0; nId < DESIGNPANE_CONTROL_COUNT; ++nId ) { - Size aSize( mxControls[nId]->GetSizePixel() ); - aSize.Width() = aPaneSize.Width() - aOffset.X() - mxControls[nId]->GetPosPixel().X(); - mxControls[nId]->SetSizePixel( aSize ); - mxControls[nId]->SetPaintTransparent(sal_True); - mxControls[nId]->SetBackground(); + if (mxControls[nId]) + { + Size aSize( mxControls[nId]->GetSizePixel() ); + aSize.Width() = aPaneSize.Width() - aOffset.X() - mxControls[nId]->GetPosPixel().X(); + mxControls[nId]->SetSizePixel( aSize ); + mxControls[nId]->SetPaintTransparent(sal_True); + mxControls[nId]->SetBackground(); + } } - aValueSetSize = Size( pValueSet->GetSizePixel().Width(), nStylesHeight - mxControls[FL_TABLE_STYLES]->GetSizePixel().Height() - mnOrgOffsetY[FL_TABLE_STYLES] ); + aValueSetSize = Size( pValueSet->GetSizePixel().Width(), nStylesHeight ); } else { @@ -437,18 +501,22 @@ void TableDesignPane::updateLayout() // shift show options section down const long nOptionsPos = aPos.Y() + aValueSetSize.Height(); - for( sal_Int32 nId = FL_STYLE_OPTIONS; nId <= CB_BANDED_COLUMNS; ++nId ) + sal_Int32 nMaxY (0); + for( sal_Int32 nId = FL_STYLE_OPTIONS+1; nId <= CB_BANDED_COLUMNS; ++nId ) { - Point aCPos( mxControls[nId]->GetPosPixel() ); - aCPos.X() = ( nId == FL_STYLE_OPTIONS ? 1 : 2 ) * aOffset.X(); - aCPos.Y() = mnOrgOffsetY[nId] + nOptionsPos; - mxControls[nId]->SetPosPixel( aCPos ); + if (mxControls[nId]) + { + Point aCPos( mxControls[nId]->GetPosPixel() ); + aCPos.X() = ( nId == FL_STYLE_OPTIONS ? 1 : 2 ) * aOffset.X(); + aCPos.Y() = mnOrgOffsetY[nId] + nOptionsPos; + mxControls[nId]->SetPosPixel( aCPos ); + const sal_Int32 nBottom (aCPos.Y() + mxControls[nId]->GetSizePixel().Height()); + if (nBottom > nMaxY) + nMaxY = nBottom; + } } } } - - if( !mbModal ) - SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); } // -------------------------------------------------------------------- diff --git a/sd/source/ui/table/TableDesignPane.hxx b/sd/source/ui/table/TableDesignPane.hxx index 021bddc55161..671753f684e0 100644 --- a/sd/source/ui/table/TableDesignPane.hxx +++ b/sd/source/ui/table/TableDesignPane.hxx @@ -22,12 +22,14 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/ui/XUIElement.hpp> +#include <com/sun/star/ui/LayoutSize.hpp> #include <com/sun/star/drawing/XDrawView.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <vcl/dialog.hxx> #include <vcl/fixed.hxx> #include <vcl/button.hxx> +#include <sfx2/sidebar/ILayoutableWindow.hxx> #include <boost/scoped_ptr.hpp> @@ -44,7 +46,7 @@ class ViewShellBase; // -------------------------------------------------------------------- -class TableDesignPane : public Control +class TableDesignPane : public Control, public sfx2::sidebar::ILayoutableWindow { public: TableDesignPane( ::Window* pParent, ViewShellBase& rBase, bool bModal ); @@ -56,6 +58,9 @@ public: // Control virtual void Resize(); + // ILayoutableWindow + virtual ::com::sun::star::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); void ApplyOptions(); diff --git a/sd/source/ui/table/TableDesignPane.src b/sd/source/ui/table/TableDesignPane.src index c36f43a60dac..c058d6370d0e 100644 --- a/sd/source/ui/table/TableDesignPane.src +++ b/sd/source/ui/table/TableDesignPane.src @@ -26,7 +26,7 @@ Control DLG_TABLEDESIGNPANE DialogControl = TRUE; Border = FALSE; - Size = MAP_APPFONT( 264, 160 ); + Size = MAP_APPFONT( 264, 134 ); Text [ en-US ] = "Table Design"; FixedLine FL_STYLE_OPTIONS+1 @@ -39,7 +39,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_HEADER_ROW+1 { - Pos = MAP_APPFONT ( 146, 16 ) ; + Pos = MAP_APPFONT ( 146, 3 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "~Header Row" ; @@ -47,7 +47,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_TOTAL_ROW+1 { - Pos = MAP_APPFONT ( 146, 29 ) ; + Pos = MAP_APPFONT ( 146, 16 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "Tot~al Row" ; @@ -55,7 +55,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_BANDED_ROWS+1 { - Pos = MAP_APPFONT ( 146, 42 ) ; + Pos = MAP_APPFONT ( 146, 29 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "~Banded Rows" ; @@ -63,7 +63,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_FIRST_COLUMN+1 { - Pos = MAP_APPFONT ( 146, 55 ) ; + Pos = MAP_APPFONT ( 146, 42 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "Fi~rst Column" ; @@ -71,7 +71,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_LAST_COLUMN+1 { - Pos = MAP_APPFONT ( 146, 68 ) ; + Pos = MAP_APPFONT ( 146, 55 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "~Last Column" ; @@ -79,7 +79,7 @@ Control DLG_TABLEDESIGNPANE CheckBox CB_BANDED_COLUMNS+1 { - Pos = MAP_APPFONT ( 146, 82 ) ; + Pos = MAP_APPFONT ( 146, 68 ) ; Size = MAP_APPFONT ( 120 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "Ba~nded Columns" ; @@ -95,7 +95,7 @@ Control DLG_TABLEDESIGNPANE Control CT_TABLE_STYLES+1 { - Pos = MAP_APPFONT ( 6, 14 ) ; + Pos = MAP_APPFONT ( 4, 3 ) ; Size = MAP_APPFONT( 120, 143 ); Border = TRUE ; TabStop = TRUE ; diff --git a/sd/source/ui/table/tablefunction.cxx b/sd/source/ui/table/tablefunction.cxx index 950949cdbf6c..77de56c68ab8 100644 --- a/sd/source/ui/table/tablefunction.cxx +++ b/sd/source/ui/table/tablefunction.cxx @@ -197,7 +197,7 @@ void DrawViewShell::FuTable(SfxRequest& rReq) { // Make the slide transition panel visible (expand it) in the // tool pane. - framework::FrameworkHelper::Instance(GetViewShellBase())->RequestTaskPanel( + framework::FrameworkHelper::Instance(GetViewShellBase())->RequestSidebarPanel( framework::FrameworkHelper::msTableDesignPanelURL); } diff --git a/sd/source/ui/table/tableobjectbar.cxx b/sd/source/ui/table/tableobjectbar.cxx index 2291839bc63f..24bb21ca19ac 100644 --- a/sd/source/ui/table/tableobjectbar.cxx +++ b/sd/source/ui/table/tableobjectbar.cxx @@ -26,6 +26,7 @@ #include <sfx2/viewfrm.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/msgpool.hxx> +#include <sfx2/sidebar/EnumContext.hxx> #include <svl/whiter.hxx> #include <svl/itempool.hxx> #include <svx/svdomedia.hxx> @@ -98,6 +99,7 @@ TableObjectBar::TableObjectBar( ViewShell* pSdViewShell, ::sd::View* pSdView ) SetRepeatTarget( mpView ); SetHelpId( SD_IF_SDDRAWTABLEOBJECTBAR ); SetName( String( SdResId( RID_DRAW_TABLE_TOOLBOX ) ) ); + SetContextName(sfx2::sidebar::EnumContext::GetContextName(sfx2::sidebar::EnumContext::Context_Table)); } // ----------------------------------------------------------------------------- @@ -197,6 +199,8 @@ void TableObjectBar::Execute( SfxRequest& rReq ) pBindings->Invalidate( SID_FRAME_LINECOLOR ); pBindings->Invalidate( SID_ATTR_BORDER ); pBindings->Invalidate( SID_ATTR_FILL_STYLE ); + pBindings->Invalidate( SID_ATTR_FILL_TRANSPARENCE ); + pBindings->Invalidate( SID_ATTR_FILL_FLOATTRANSPARENCE ); pBindings->Invalidate( SID_TABLE_MERGE_CELLS ); pBindings->Invalidate( SID_TABLE_SPLIT_CELLS ); pBindings->Invalidate( SID_OPTIMIZE_TABLE ); diff --git a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx index 1d43547aac01..6d5878b899e1 100644 --- a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx +++ b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx @@ -410,7 +410,7 @@ void ToolPanelViewShell_Impl::Setup() else { ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( GetAntiImpl().GetViewShellBase() ) ); - pFrameworkHelper->RequestTaskPanel( aInitialPanel.sPanelResourceURL ); + pFrameworkHelper->RequestSidebarPanel( aInitialPanel.sPanelResourceURL ); // MMeeks } } @@ -804,7 +804,7 @@ void ToolPanelViewShell_Impl::ActivePanelChanged( const ::boost::optional< size_ { // 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 ); + pFrameworkHelper->RequestSidebarPanel( sNewPanelURL ); // MMeeks } else if ( !sOldPanelURL.isEmpty() ) { diff --git a/sd/source/ui/unoidl/facreg.cxx b/sd/source/ui/unoidl/facreg.cxx index d3cdfc9b287b..df50159dc2e7 100644 --- a/sd/source/ui/unoidl/facreg.cxx +++ b/sd/source/ui/unoidl/facreg.cxx @@ -113,13 +113,6 @@ extern OUString BasicViewFactory_getImplementationName(void) throw (uno::Runtime extern uno::Sequence<OUString> SAL_CALL BasicViewFactory_getSupportedServiceNames (void) throw (uno::RuntimeException); -extern uno::Reference<uno::XInterface> SAL_CALL TaskPanelFactory_createInstance( - const uno::Reference<uno::XComponentContext>& rxContext) - throw(uno::Exception); -extern OUString TaskPanelFactory_getImplementationName(void) throw (uno::RuntimeException); -extern uno::Sequence<OUString> SAL_CALL TaskPanelFactory_getSupportedServiceNames (void) - throw (uno::RuntimeException); - extern uno::Reference<uno::XInterface> SAL_CALL ResourceId_createInstance( const uno::Reference<uno::XComponentContext>& rxContext) throw(uno::Exception); @@ -136,14 +129,13 @@ extern uno::Sequence<OUString> SAL_CALL PresentationFactoryProvider_getSupported throw (uno::RuntimeException); } } +namespace sd { namespace sidebar { -namespace sd { namespace toolpanel { - -extern uno::Reference<uno::XInterface> SAL_CALL ToolPanelFactory_createInstance( +extern uno::Reference<uno::XInterface> SAL_CALL PanelFactory_createInstance( const uno::Reference<uno::XComponentContext>& rxContext) throw(uno::Exception); -extern OUString ToolPanelFactory_getImplementationName(void) throw (uno::RuntimeException); -extern uno::Sequence<OUString> SAL_CALL ToolPanelFactory_getSupportedServiceNames (void) +extern OUString PanelFactory_getImplementationName(void) throw (uno::RuntimeException); +extern uno::Sequence<OUString> SAL_CALL PanelFactory_getSupportedServiceNames (void) throw (uno::RuntimeException); } } @@ -205,7 +197,7 @@ using namespace ::sd; using namespace ::sd::framework; using namespace ::sd::presenter; using namespace ::sd::slidesorter; -using namespace ::sd::toolpanel; +using namespace ::sd::sidebar; @@ -228,8 +220,7 @@ enum FactoryId BasicPaneFactoryFactoryId, BasicToolBarFactoryFactoryId, BasicViewFactoryFactoryId, - TaskPanelFactoryFactoryId, - ToolPanelFactoryFactoryId, + PanelFactoryFactoryId, ResourceIdFactoryId, PresentationFactoryProviderFactoryId, SlideRendererFactoryId, @@ -262,8 +253,7 @@ static ::boost::shared_ptr<FactoryMap> spFactoryMap; (*spFactoryMap)[BasicPaneFactory_getImplementationName()] = BasicPaneFactoryFactoryId; (*spFactoryMap)[BasicToolBarFactory_getImplementationName()] = BasicToolBarFactoryFactoryId; (*spFactoryMap)[BasicViewFactory_getImplementationName()] = BasicViewFactoryFactoryId; - (*spFactoryMap)[TaskPanelFactory_getImplementationName()] = TaskPanelFactoryFactoryId; - (*spFactoryMap)[ToolPanelFactory_getImplementationName()] = ToolPanelFactoryFactoryId; + (*spFactoryMap)[sidebar::PanelFactory_getImplementationName()] = PanelFactoryFactoryId; (*spFactoryMap)[ResourceId_getImplementationName()] = ResourceIdFactoryId; (*spFactoryMap)[PresentationFactoryProvider_getImplementationName()] = PresentationFactoryProviderFactoryId; (*spFactoryMap)[SlideRenderer_getImplementationName()] = SlideRendererFactoryId; @@ -386,18 +376,11 @@ SAL_DLLPUBLIC_EXPORT void * SAL_CALL sd_component_getFactory( sd::framework::BasicViewFactory_getSupportedServiceNames()); break; - case TaskPanelFactoryFactoryId: - xComponentFactory = ::cppu::createSingleComponentFactory( - sd::framework::TaskPanelFactory_createInstance, - sd::framework::TaskPanelFactory_getImplementationName(), - sd::framework::TaskPanelFactory_getSupportedServiceNames()); - break; - - case ToolPanelFactoryFactoryId: + case PanelFactoryFactoryId: xComponentFactory = ::cppu::createSingleComponentFactory( - sd::toolpanel::ToolPanelFactory_createInstance, - sd::toolpanel::ToolPanelFactory_getImplementationName(), - sd::toolpanel::ToolPanelFactory_getSupportedServiceNames()); + sd::sidebar::PanelFactory_createInstance, + sd::sidebar::PanelFactory_getImplementationName(), + sd::sidebar::PanelFactory_getSupportedServiceNames()); break; case ResourceIdFactoryId: diff --git a/sd/source/ui/view/ToolBarManager.cxx b/sd/source/ui/view/ToolBarManager.cxx index 578561a3fa27..c5be674a8b3c 100644 --- a/sd/source/ui/view/ToolBarManager.cxx +++ b/sd/source/ui/view/ToolBarManager.cxx @@ -1199,7 +1199,7 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) case ViewShell::ST_NONE: case ViewShell::ST_PRESENTATION: - case ViewShell::ST_TASK_PANE: + case ViewShell::ST_SIDEBAR: default: break; } diff --git a/sd/source/ui/view/ViewShellBase.cxx b/sd/source/ui/view/ViewShellBase.cxx index 09006ed1f38e..3348c198ff76 100644 --- a/sd/source/ui/view/ViewShellBase.cxx +++ b/sd/source/ui/view/ViewShellBase.cxx @@ -54,7 +54,7 @@ #include "PresentationViewShell.hxx" #include "FormShellManager.hxx" #include "ToolBarManager.hxx" -#include "taskpane/PanelId.hxx" +#include "SidebarPanelId.hxx" #include "Window.hxx" #include "framework/ConfigurationController.hxx" #include "DocumentRenderer.hxx" @@ -697,13 +697,6 @@ void ViewShellBase::Execute (SfxRequest& rRequest) framework::FrameworkHelper::msSlideSorterURL); break; - case SID_TASKPANE: - mpImpl->SetPaneVisibility( - rRequest, - framework::FrameworkHelper::msRightPaneURL, - framework::FrameworkHelper::msTaskPaneURL); - break; - case SID_NORMAL_MULTI_PANE_GUI: case SID_SLIDE_SORTER_MULTI_PANE_GUI: case SID_DRAWINGMODE: @@ -1394,11 +1387,6 @@ void ViewShellBase::Implementation::GetSlotState (SfxItemSet& rSet) xContext, FrameworkHelper::msLeftDrawPaneURL); break; - case SID_TASKPANE: - xResourceId = ResourceId::create( - xContext, FrameworkHelper::msRightPaneURL); - break; - case SID_NORMAL_MULTI_PANE_GUI: xResourceId = ResourceId::createWithAnchorURL( xContext, @@ -1497,8 +1485,7 @@ void ViewShellBase::Implementation::ProcessTaskPaneSlot (SfxRequest& rRequest) { // Set the visibility state of the toolpanel and one of its top // level panels. - toolpanel::PanelId nPanelId ( - toolpanel::PID_UNKNOWN); + sidebar::PanelId nPanelId (sidebar::PID_UNKNOWN); bool bPanelIdGiven = false; // Extract the given arguments. @@ -1511,9 +1498,7 @@ void ViewShellBase::Implementation::ProcessTaskPaneSlot (SfxRequest& rRequest) ID_VAL_PANEL_INDEX, sal_False); if (pPanelId != NULL) { - nPanelId = static_cast< - toolpanel::PanelId>( - pPanelId->GetValue()); + nPanelId = static_cast<sidebar::PanelId>(pPanelId->GetValue()); bPanelIdGiven = true; } } @@ -1522,11 +1507,11 @@ void ViewShellBase::Implementation::ProcessTaskPaneSlot (SfxRequest& rRequest) // Ignore the request for some combinations of panels and view // shell types. if (bPanelIdGiven - && ! (nPanelId==toolpanel::PID_LAYOUT + && ! (nPanelId==sidebar::PID_LAYOUT && mrBase.GetMainViewShell()!=NULL && mrBase.GetMainViewShell()->GetShellType()==ViewShell::ST_OUTLINE)) { - framework::FrameworkHelper::Instance(mrBase)->RequestTaskPanel( + framework::FrameworkHelper::Instance(mrBase)->RequestSidebarPanel( framework::FrameworkHelper::msLayoutTaskPanelURL); } } diff --git a/sd/source/ui/view/ViewShellImplementation.cxx b/sd/source/ui/view/ViewShellImplementation.cxx index cea72846ce1d..84c31813b5d8 100644 --- a/sd/source/ui/view/ViewShellImplementation.cxx +++ b/sd/source/ui/view/ViewShellImplementation.cxx @@ -40,7 +40,7 @@ #include "FrameView.hxx" #include "DrawViewShell.hxx" #include "ViewShellHint.hxx" -#include "taskpane/PanelId.hxx" +#include "SidebarPanelId.hxx" #include "framework/FrameworkHelper.hxx" #include <sfx2/bindings.hxx> @@ -126,8 +126,7 @@ void ViewShell::Implementation::ProcessModifyPageSlot ( // Make the layout menu visible in the tool pane. SfxBoolItem aMakeToolPaneVisible (ID_VAL_ISVISIBLE, sal_True); - SfxUInt32Item aPanelId (ID_VAL_PANEL_INDEX, - ::sd::toolpanel::PID_LAYOUT); + SfxUInt32Item aPanelId (ID_VAL_PANEL_INDEX, sidebar::PID_LAYOUT); SfxViewFrame* pFrame = mrViewShell.GetViewFrame(); if (pFrame!=NULL && pFrame->GetDispatcher()!=NULL) { @@ -331,7 +330,7 @@ sal_uInt16 ViewShell::Implementation::GetViewId (void) // Since we have to return a view id for every possible shell type // and there is not (yet) a proper ViewShellBase sub class for the // remaining types we chose the Impress factory as a fall back. - case ViewShell::ST_TASK_PANE: + case ViewShell::ST_SIDEBAR: case ViewShell::ST_NONE: default: return IMPRESS_FACTORY_ID; diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index 109da58163c0..a6393d8a523d 100644 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -53,6 +53,8 @@ public: SfxShell* mpShell; ShellId mnId; ViewShellManager::SharedShellFactory mpFactory; + bool mbIsListenerAddedToWindow; + ShellDescriptor (); ShellDescriptor (SfxShell* pShell, ShellId nId); ShellDescriptor (const ShellDescriptor& rDescriptor); @@ -233,7 +235,7 @@ private: ShellId nShellId, ::Window* pParentWindow, FrameView* pFrameView); - void DestroyViewShell (const ShellDescriptor& rDescriptor); + void DestroyViewShell (ShellDescriptor& rDescriptor); void DestroySubShell ( const SfxShell& rViewShell, const ShellDescriptor& rDescriptor); @@ -511,8 +513,11 @@ void ViewShellManager::Implementation::ActivateViewShell (ViewShell* pViewShell) { ::Window* pWindow = aResult.GetWindow(); if (pWindow != NULL) + { pWindow->AddEventListener( LINK(this, ViewShellManager::Implementation, WindowEventHandler)); + aResult.mbIsListenerAddedToWindow = true; + } else { DBG_ASSERT(false, @@ -1160,6 +1165,23 @@ IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, case VCLEVENT_WINDOW_LOSEFOCUS: break; + + case VCLEVENT_OBJECT_DYING: + // Remember that we do not have to remove the window + // listener for this window. + for (ActiveShellList::iterator + iShell(maActiveViewShells.begin()), + iEnd(maActiveViewShells.end()); + iShell!=iEnd; + ++iShell) + { + if (iShell->GetWindow() == pEventWindow) + { + iShell->mbIsListenerAddedToWindow = false; + break; + } + } + break; } } return sal_True; @@ -1204,15 +1226,19 @@ ShellDescriptor ViewShellManager::Implementation::CreateSubShell ( void ViewShellManager::Implementation::DestroyViewShell ( - const ShellDescriptor& rDescriptor) + ShellDescriptor& rDescriptor) { OSL_ASSERT(rDescriptor.mpShell != NULL); - ::Window* pWindow = rDescriptor.GetWindow(); - if (pWindow != NULL) + if (rDescriptor.mbIsListenerAddedToWindow) { - pWindow->RemoveEventListener( - LINK(this, ViewShellManager::Implementation, WindowEventHandler)); + rDescriptor.mbIsListenerAddedToWindow = false; + ::Window* pWindow = rDescriptor.GetWindow(); + if (pWindow != NULL) + { + pWindow->RemoveEventListener( + LINK(this, ViewShellManager::Implementation, WindowEventHandler)); + } } // Destroy the sub shell factories. @@ -1374,7 +1400,8 @@ namespace { ShellDescriptor::ShellDescriptor (void) : mpShell(NULL), mnId(0), - mpFactory() + mpFactory(), + mbIsListenerAddedToWindow(false) { } @@ -1386,7 +1413,8 @@ ShellDescriptor::ShellDescriptor ( ShellId nId) : mpShell(pShell), mnId(nId), - mpFactory() + mpFactory(), + mbIsListenerAddedToWindow(false) { } @@ -1394,9 +1422,10 @@ ShellDescriptor::ShellDescriptor ( ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor) - : mpShell(rDescriptor.mpShell), - mnId(rDescriptor.mnId), - mpFactory(rDescriptor.mpFactory) + : mpShell(rDescriptor.mpShell), + mnId(rDescriptor.mnId), + mpFactory(rDescriptor.mpFactory), + mbIsListenerAddedToWindow(rDescriptor.mbIsListenerAddedToWindow) { } @@ -1405,9 +1434,13 @@ ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor) ShellDescriptor& ShellDescriptor::operator= (const ShellDescriptor& rDescriptor) { - mpShell = rDescriptor.mpShell; - mnId = rDescriptor.mnId; - mpFactory = rDescriptor.mpFactory; + if (this != &rDescriptor) + { + mpShell = rDescriptor.mpShell; + mnId = rDescriptor.mnId; + mpFactory = rDescriptor.mpFactory; + mbIsListenerAddedToWindow = rDescriptor.mbIsListenerAddedToWindow; + } return *this; } diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx index f285f815ad96..d65fa4320775 100644 --- a/sd/source/ui/view/drtxtob.cxx +++ b/sd/source/ui/view/drtxtob.cxx @@ -30,6 +30,7 @@ #include <editeng/editeng.hxx> #include <editeng/outliner.hxx> #include <editeng/unolingu.hxx> +#include <editeng/kernitem.hxx> #include <vcl/vclenum.hxx> #include <sfx2/app.hxx> #include <svl/whiter.hxx> @@ -128,10 +129,30 @@ TextObjectBar::~TextObjectBar() SetRepeatTarget(NULL); } +void TextObjectBar::GetCharState( SfxItemSet& rSet ) +{ + SfxItemSet aCharAttrSet( mpView->GetDoc().GetPool() ); + mpView->GetAttributes( aCharAttrSet ); + + SfxItemSet aNewAttr( mpViewShell->GetPool(),EE_ITEMS_START,EE_ITEMS_END); + + aNewAttr.Put(aCharAttrSet, sal_False); + rSet.Put(aNewAttr, sal_False); + + SvxKerningItem aKern = ( (const SvxKerningItem&) aCharAttrSet.Get( EE_CHAR_KERNING ) ); + //aKern.SetWhich(SID_ATTR_CHAR_KERNING); + rSet.Put(aKern); + + SfxItemState eState = aCharAttrSet.GetItemState( EE_CHAR_KERNING, sal_True ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_CHAR_KERNING); + } +} + /** * Status of attribute items. */ - void TextObjectBar::GetAttrState( SfxItemSet& rSet ) { SfxWhichIter aIter( rSet ); @@ -155,6 +176,8 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) case SID_ATTR_CHAR_FONTHEIGHT: case SID_ATTR_CHAR_WEIGHT: case SID_ATTR_CHAR_POSTURE: + case SID_ATTR_CHAR_SHADOWED: + case SID_ATTR_CHAR_STRIKEOUT: { sal_uInt16 stretchX = 100; sal_uInt16 stretchY = 100; @@ -452,6 +475,8 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) } // paragraph justification + SvxLRSpaceItem aLR = ( (const SvxLRSpaceItem&) aAttrSet.Get( EE_PARA_LRSPACE ) ); + rSet.Put(aLR); SvxAdjust eAdj = ( (const SvxAdjustItem&) aAttrSet.Get( EE_PARA_JUST ) ).GetAdjust(); switch( eAdj ) { @@ -471,6 +496,13 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) break; } + Invalidate(SID_ATTR_PARA_ADJUST_LEFT); + Invalidate(SID_ATTR_PARA_ADJUST_CENTER); + Invalidate(SID_ATTR_PARA_ADJUST_RIGHT); + Invalidate(SID_ATTR_PARA_ADJUST_BLOCK); + Invalidate(SID_ATTR_PARA_LINESPACE); + Invalidate(SID_ATTR_PARA_ULSPACE); + // paragraph text direction if( bDisableParagraphTextDirection ) { @@ -519,6 +551,17 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) } } + SvxLRSpaceItem aLRSpace = ( (const SvxLRSpaceItem&) aAttrSet.Get( EE_PARA_LRSPACE ) ); + aLRSpace.SetWhich(SID_ATTR_PARA_LRSPACE); + rSet.Put(aLRSpace); + Invalidate(SID_ATTR_PARA_LRSPACE); + //Added by xuxu + SfxItemState eState = aAttrSet.GetItemState( EE_PARA_LRSPACE ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_PARA_LRSPACE); + rSet.InvalidateItem(SID_ATTR_PARA_LRSPACE); + } sal_uInt16 nLineSpace = (sal_uInt16) ( (const SvxLineSpacingItem&) aAttrSet. Get( EE_PARA_SBL ) ).GetPropLineSpace(); switch( nLineSpace ) diff --git a/sd/source/ui/view/drtxtob1.cxx b/sd/source/ui/view/drtxtob1.cxx index 9d5cf273e53e..04137a3ee153 100644 --- a/sd/source/ui/view/drtxtob1.cxx +++ b/sd/source/ui/view/drtxtob1.cxx @@ -228,6 +228,7 @@ void TextObjectBar::Execute( SfxRequest &rReq ) break; case SID_OUTLINE_LEFT: + case SID_ATTR_PARA_LEFT: { if (pOLV) { @@ -243,6 +244,7 @@ void TextObjectBar::Execute( SfxRequest &rReq ) break; case SID_OUTLINE_RIGHT: + case SID_ATTR_PARA_RIGHT: { if (pOLV) { @@ -257,6 +259,22 @@ void TextObjectBar::Execute( SfxRequest &rReq ) } break; + case SID_ATTR_PARA_LRSPACE: + { + sal_uInt16 nSpaceSlot = SID_ATTR_PARA_LRSPACE; + SvxLRSpaceItem aLRSpace = (const SvxLRSpaceItem&)pArgs->Get( + GetPool().GetWhich(nSpaceSlot)); + + SfxItemSet aEditAttr( GetPool(), EE_PARA_LRSPACE, EE_PARA_LRSPACE ); + aLRSpace.SetWhich( EE_PARA_LRSPACE ); + + aEditAttr.Put( aLRSpace ); + mpView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_LRSPACE); + } + break; + case SID_OUTLINE_UP: { if (pOLV) @@ -558,6 +576,71 @@ void TextObjectBar::Execute( SfxRequest &rReq ) rReq.Done( aNewAttr ); pArgs = rReq.GetArgs(); } + else if (nSlot == SID_ATTR_PARA_ADJUST_LEFT || + nSlot == SID_ATTR_PARA_ADJUST_CENTER || + nSlot == SID_ATTR_PARA_ADJUST_RIGHT || + nSlot == SID_ATTR_PARA_ADJUST_BLOCK) + { + switch( nSlot ) + { + case SID_ATTR_PARA_ADJUST_LEFT: + { + aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); + } + break; + case SID_ATTR_PARA_ADJUST_CENTER: + { + aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) ); + } + break; + case SID_ATTR_PARA_ADJUST_RIGHT: + { + aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); + } + break; + case SID_ATTR_PARA_ADJUST_BLOCK: + { + aNewAttr.Put( SvxAdjustItem( SVX_ADJUST_BLOCK, EE_PARA_JUST ) ); + } + break; + } + rReq.Done( aNewAttr ); + pArgs = rReq.GetArgs(); + } + else if(nSlot == SID_ATTR_CHAR_KERNING) + { + aNewAttr.Put(pArgs->Get(pArgs->GetPool()->GetWhich(nSlot))); + rReq.Done( aNewAttr ); + pArgs = rReq.GetArgs(); + } + else if(nSlot == SID_SET_SUPER_SCRIPT ) + { + SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT); + SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) + aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); + + if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT ) + aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); + else + aItem.SetEscapement( SVX_ESCAPEMENT_SUPERSCRIPT ); + aNewAttr.Put( aItem ); + rReq.Done( aNewAttr ); + pArgs = rReq.GetArgs(); + } + else if( nSlot == SID_SET_SUB_SCRIPT ) + { + SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT); + SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) + aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); + + if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT ) + aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); + else + aItem.SetEscapement( SVX_ESCAPEMENT_SUBSCRIPT ); + aNewAttr.Put( aItem ); + rReq.Done( aNewAttr ); + pArgs = rReq.GetArgs(); + } mpView->SetAttributes(*pArgs); diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index de3c663c994f..e5c12ca7dbee 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -83,6 +83,26 @@ #include <vcl/svapp.hxx> #include <vcl/waitobj.hxx> +#include <editeng/escapementitem.hxx> +#include <editeng/kernitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/crossedoutitem.hxx> +#include <editeng/contouritem.hxx> +#include <editeng/shdditem.hxx> +#include <svx/xtable.hxx> +#include <svx/svdobj.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/flstitem.hxx> +#include <editeng/scripttypeitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/brushitem.hxx> + +#include <svl/whiter.hxx> + #include "app.hrc" #include "glob.hrc" #include "strings.hrc" @@ -131,6 +151,7 @@ #include "futransf.hxx" #include "futxtatt.hxx" #include "fuvect.hxx" +#include "futext.hxx" #include "fuzoom.hxx" #include "helpids.h" #include "optsitem.hxx" @@ -237,12 +258,19 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) case SID_ATTR_FILL_HATCH: case SID_ATTR_FILL_BITMAP: case SID_ATTR_FILL_SHADOW: + case SID_ATTR_FILL_TRANSPARENCE: + case SID_ATTR_FILL_FLOATTRANSPARENCE: case SID_ATTR_LINE_STYLE: case SID_ATTR_LINE_DASH: case SID_ATTR_LINE_WIDTH: case SID_ATTR_LINE_COLOR: case SID_ATTR_LINEEND_STYLE: + case SID_ATTR_LINE_START: + case SID_ATTR_LINE_END: + case SID_ATTR_LINE_TRANSPARENCE: + case SID_ATTR_LINE_JOINT: + case SID_ATTR_LINE_CAP: case SID_ATTR_TEXT_FITTOSIZE: { @@ -389,12 +417,17 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) case SID_ATTR_FILL_GRADIENT: case SID_ATTR_FILL_HATCH: case SID_ATTR_FILL_BITMAP: + case SID_ATTR_FILL_TRANSPARENCE: + case SID_ATTR_FILL_FLOATTRANSPARENCE: GetViewFrame()->GetDispatcher()->Execute( SID_ATTRIBUTES_AREA, SFX_CALLMODE_ASYNCHRON ); break; case SID_ATTR_LINE_STYLE: case SID_ATTR_LINE_DASH: case SID_ATTR_LINE_WIDTH: case SID_ATTR_LINE_COLOR: + case SID_ATTR_LINE_TRANSPARENCE: + case SID_ATTR_LINE_JOINT: + case SID_ATTR_LINE_CAP: GetViewFrame()->GetDispatcher()->Execute( SID_ATTRIBUTES_LINE, SFX_CALLMODE_ASYNCHRON ); break; case SID_ATTR_TEXT_FITTOSIZE: @@ -1143,6 +1176,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) } break; + case SID_CHAR_DLG_EFFECT: case SID_CHAR_DLG: // BASIC { SetCurrentFunction( FuChar::Create( this, GetActiveWindow(), mpDrawView, GetDoc(), rReq ) ); @@ -1157,7 +1191,25 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) } break; + case FN_NUM_BULLET_ON: + { + // The value (sal_uInt16)0xFFFF means set bullet on/off. + SfxUInt16Item aItem(FN_SVX_SET_BULLET, (sal_uInt16)0xFFFF); + GetViewFrame()->GetDispatcher()->Execute( FN_SVX_SET_BULLET, SFX_CALLMODE_RECORD, &aItem, 0L ); + } + break; + + case FN_NUM_NUMBERING_ON: + { + // The value (sal_uInt16)0xFFFF means set bullet on/off. + SfxUInt16Item aItem(FN_SVX_SET_NUMBER, (sal_uInt16)0xFFFF); + GetViewFrame()->GetDispatcher()->Execute( FN_SVX_SET_NUMBER, SFX_CALLMODE_RECORD, &aItem, 0L ); + } + break; + case SID_OUTLINE_BULLET: + case FN_SVX_SET_BULLET: + case FN_SVX_SET_NUMBER: { SetCurrentFunction( FuOutlineBullet::Create( this, GetActiveWindow(), mpDrawView, GetDoc(), rReq ) ); Cancel(); @@ -2467,6 +2519,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) break; case SID_HORIZONTAL: // BASIC + case SID_FLIP_HORIZONTAL: { mpDrawView->MirrorAllMarkedHorizontal(); Cancel(); @@ -2475,6 +2528,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) break; case SID_VERTICAL: // BASIC + case SID_FLIP_VERTICAL: { mpDrawView->MirrorAllMarkedVertical(); Cancel(); @@ -2766,7 +2820,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) { // Make the slide transition panel visible (expand it) in the // tool pane. - framework::FrameworkHelper::Instance(GetViewShellBase())->RequestTaskPanel( + framework::FrameworkHelper::Instance(GetViewShellBase())->RequestSidebarPanel( framework::FrameworkHelper::msCustomAnimationTaskPanelURL); Cancel(); @@ -2778,7 +2832,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) { // Make the slide transition panel visible (expand it) in the // tool pane. - framework::FrameworkHelper::Instance(GetViewShellBase())->RequestTaskPanel( + framework::FrameworkHelper::Instance(GetViewShellBase())->RequestSidebarPanel( framework::FrameworkHelper::msSlideTransitionTaskPanelURL); Cancel(); @@ -2945,6 +2999,177 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) } } +void DrawViewShell::ExecChar( SfxRequest &rReq ) +{ + SdDrawDocument* pDoc = GetDoc(); + if (!pDoc || !mpDrawView) + return; + + SfxItemSet aEditAttr( pDoc->GetPool() ); + mpDrawView->GetAttributes( aEditAttr ); + + //modified by wj for sym2_1580, if put old itemset into new set, + //when mpDrawView->SetAttributes(aNewAttr) it will invalidate all the item + // and use old attr to update all the attributes +// SfxItemSet aNewAttr( GetPool(), +// EE_ITEMS_START, EE_ITEMS_END ); +// aNewAttr.Put( aEditAttr, sal_False ); + SfxItemSet aNewAttr( pDoc->GetPool() ); + //modified end + + sal_uInt16 nSId = rReq.GetSlot(); + + MapSlot( nSId ); + + switch ( nSId ) + { + case SID_ATTR_CHAR_FONT: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxFontItem, SID_ATTR_CHAR_FONT , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_FONTHEIGHT: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxFontHeightItem, SID_ATTR_CHAR_FONTHEIGHT , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_WEIGHT: + if( rReq.GetArgs() ) + { + //const SvxWeightItem *pItem = (const SvxWeightItem*) rReq.GetArg( SID_ATTR_CHAR_WEIGHT, sal_False, TYPE(SvxWeightItem) ); + SFX_REQUEST_ARG( rReq, pItem, SvxWeightItem, SID_ATTR_CHAR_WEIGHT , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_POSTURE: + if( rReq.GetArgs() ) + { + //const SvxPostureItem *pItem = (const SvxPostureItem*) rReq.GetArg( SID_ATTR_CHAR_POSTURE, sal_False, TYPE(SvxPostureItem) ); + SFX_REQUEST_ARG( rReq, pItem, SvxPostureItem, SID_ATTR_CHAR_POSTURE , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_UNDERLINE: + if( rReq.GetArgs() ) + { + //<<modify by wj for sym2_1873 + //SFX_REQUEST_ARG( rReq, pItem, SvxTextLineItem, SID_ATTR_CHAR_UNDERLINE , sal_False ); + SFX_REQUEST_ARG( rReq, pItem, SvxUnderlineItem, SID_ATTR_CHAR_UNDERLINE , sal_False ); + //end>> + if (pItem) + { + aNewAttr.Put(*pItem); + } + else + { + FontUnderline eFU = ( (const SvxUnderlineItem&) aEditAttr.Get( EE_CHAR_UNDERLINE ) ).GetLineStyle(); + aNewAttr.Put( SvxUnderlineItem( eFU != UNDERLINE_NONE ?UNDERLINE_NONE : UNDERLINE_SINGLE, EE_CHAR_UNDERLINE ) ); + }//aNewAttr.Put( (const SvxUnderlineItem&)aEditAttr.Get( EE_CHAR_UNDERLINE ) ); + } + break; + case SID_ATTR_CHAR_SHADOWED: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxShadowedItem, SID_ATTR_CHAR_SHADOWED , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_STRIKEOUT: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxCrossedOutItem, SID_ATTR_CHAR_STRIKEOUT , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_COLOR: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxColorItem, SID_ATTR_CHAR_COLOR , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_ATTR_CHAR_KERNING: + if( rReq.GetArgs() ) + { + SFX_REQUEST_ARG( rReq, pItem, SvxKerningItem, SID_ATTR_CHAR_KERNING , sal_False ); + if (pItem) + { + aNewAttr.Put(*pItem); + } + } + break; + case SID_SET_SUB_SCRIPT: + if( rReq.GetArgs() ) + { + SvxEscapementItem aItem( EE_CHAR_ESCAPEMENT ); + SvxEscapement eEsc = (SvxEscapement ) ( (const SvxEscapementItem&) + aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); + if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT ) + aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); + else + aItem.SetEscapement( SVX_ESCAPEMENT_SUBSCRIPT ); + aNewAttr.Put( aItem ); + } + break; + case SID_SET_SUPER_SCRIPT: + if( rReq.GetArgs() ) + { + SvxEscapementItem aItem( EE_CHAR_ESCAPEMENT ); + SvxEscapement eEsc = (SvxEscapement ) ( (const SvxEscapementItem&) + aEditAttr.Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); + if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT ) + aItem.SetEscapement( SVX_ESCAPEMENT_OFF ); + else + aItem.SetEscapement( SVX_ESCAPEMENT_SUPERSCRIPT ); + aNewAttr.Put( aItem ); + } + break; + case SID_SHRINK_FONT_SIZE: + case SID_GROW_FONT_SIZE: + //if (rReq.GetArgs()) + { + const SvxFontListItem* pFonts = dynamic_cast<const SvxFontListItem*>(GetDocSh()->GetItem( SID_ATTR_CHAR_FONTLIST ) ); + const FontList* pFontList = pFonts->GetFontList(); + if( pFontList ) + { + FuText::ChangeFontSize( nSId == SID_GROW_FONT_SIZE, NULL, pFontList, mpView ); + GetViewFrame()->GetBindings().Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); + } + } + default: + ; + } + + mpDrawView->SetAttributes(aNewAttr); + rReq.Done(); + Cancel(); +} + /** This method consists basically of three parts: 1. Process the arguments of the SFX request. 2. Use the model to create a new page or duplicate an existing one. @@ -2968,6 +3193,88 @@ SdPage* DrawViewShell::CreateOrDuplicatePage ( return pNewPage; } +void DrawViewShell::ExecutePropPanelAttr (SfxRequest& rReq) +{ + if(SlideShow::IsRunning( GetViewShellBase() )) + return; + + SdDrawDocument* pDoc = GetDoc(); + if (!pDoc || !mpDrawView) + return; + + sal_uInt16 nSId = rReq.GetSlot(); + SfxItemSet aAttrs( pDoc->GetPool() ); + + switch ( nSId ) + { + case SID_TABLE_VERT_NONE: + case SID_TABLE_VERT_CENTER: + case SID_TABLE_VERT_BOTTOM: + SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_TOP; + if (nSId == SID_TABLE_VERT_CENTER) + eTVA = SDRTEXTVERTADJUST_CENTER; + else if (nSId == SID_TABLE_VERT_BOTTOM) + eTVA = SDRTEXTVERTADJUST_BOTTOM; + + aAttrs.Put( SdrTextVertAdjustItem(eTVA) ); + mpDrawView->SetAttributes(aAttrs); + + break; + } +} + +void DrawViewShell::GetStatePropPanelAttr(SfxItemSet& rSet) +{ + SfxWhichIter aIter( rSet ); + sal_uInt16 nWhich = aIter.FirstWhich(); + + SdDrawDocument* pDoc = GetDoc(); + if (!pDoc || !mpDrawView) + return; + + SfxItemSet aAttrs( pDoc->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + + while ( nWhich ) + { + sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich) + ? GetPool().GetSlotId(nWhich) + : nWhich; + switch ( nSlotId ) + { + case SID_TABLE_VERT_NONE: + case SID_TABLE_VERT_CENTER: + case SID_TABLE_VERT_BOTTOM: + sal_Bool bContour = sal_False; + SfxItemState eConState = aAttrs.GetItemState( SDRATTR_TEXT_CONTOURFRAME ); + if( eConState != SFX_ITEM_DONTCARE ) + { + bContour = ( ( const SdrTextContourFrameItem& )aAttrs.Get( SDRATTR_TEXT_CONTOURFRAME ) ).GetValue(); + } + if (bContour) break; + + SfxItemState eVState = aAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST ); + //SfxItemState eHState = aAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST ); + + //if(SFX_ITEM_DONTCARE != eVState && SFX_ITEM_DONTCARE != eHState) + if(SFX_ITEM_DONTCARE != eVState) + { + SdrTextVertAdjust eTVA = (SdrTextVertAdjust)((const SdrTextVertAdjustItem&)aAttrs.Get(SDRATTR_TEXT_VERTADJUST)).GetValue(); + sal_Bool bSet = (nSlotId == SID_TABLE_VERT_NONE && eTVA == SDRTEXTVERTADJUST_TOP) || + (nSlotId == SID_TABLE_VERT_CENTER && eTVA == SDRTEXTVERTADJUST_CENTER) || + (nSlotId == SID_TABLE_VERT_BOTTOM && eTVA == SDRTEXTVERTADJUST_BOTTOM); + rSet.Put(SfxBoolItem(nSlotId, bSet)); + } + else + { + rSet.Put(SfxBoolItem(nSlotId, sal_False)); + } + break; + } + nWhich = aIter.NextWhich(); + } +} + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/view/drviews3.cxx b/sd/source/ui/view/drviews3.cxx index 3b533be70a3a..04bd60741427 100644 --- a/sd/source/ui/view/drviews3.cxx +++ b/sd/source/ui/view/drviews3.cxx @@ -26,6 +26,7 @@ #include <editeng/lrspitem.hxx> #include <editeng/protitem.hxx> #include <editeng/frmdiritem.hxx> +#include <editeng/adjustitem.hxx> #include <svx/ruler.hxx> #include <editeng/numitem.hxx> #include <svx/rulritem.hxx> @@ -82,7 +83,8 @@ #include <com/sun/star/drawing/framework/XConfigurationController.hpp> #include <com/sun/star/drawing/framework/XConfiguration.hpp> #include <com/sun/star/frame/XFrame.hpp> - +#include <editeng/lspcitem.hxx> +#include <editeng/ulspitem.hxx> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::com::sun::star::frame::XFrame; @@ -647,8 +649,97 @@ void DrawViewShell::ExecRuler(SfxRequest& rReq) break; } + case SID_ATTR_PARA_LINESPACE: + { + sal_uInt16 nSlot = SID_ATTR_PARA_LINESPACE; + SvxLineSpacingItem aParaLineSP = (const SvxLineSpacingItem&)pArgs->Get( + GetPool().GetWhich(nSlot)); + + SfxItemSet aEditAttr( GetPool(), EE_PARA_SBL, EE_PARA_SBL ); + aParaLineSP.SetWhich( EE_PARA_SBL ); + + aEditAttr.Put( aParaLineSP ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_LINESPACE); + } + break; + case SID_ATTR_PARA_ADJUST_LEFT: + { + SvxAdjustItem aItem( SVX_ADJUST_LEFT, EE_PARA_JUST ); + SfxItemSet aEditAttr( GetPool(), EE_PARA_JUST, EE_PARA_JUST ); + + aEditAttr.Put( aItem ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_ADJUST_LEFT); + } + break; + case SID_ATTR_PARA_ADJUST_CENTER: + { + SvxAdjustItem aItem( SVX_ADJUST_CENTER, EE_PARA_JUST ); + SfxItemSet aEditAttr( GetPool(), EE_PARA_JUST, EE_PARA_JUST ); + + aEditAttr.Put( aItem ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_ADJUST_CENTER); + } + break; + case SID_ATTR_PARA_ADJUST_RIGHT: + { + SvxAdjustItem aItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ); + SfxItemSet aEditAttr( GetPool(), EE_PARA_JUST, EE_PARA_JUST ); + + aEditAttr.Put( aItem ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_ADJUST_RIGHT); + } + break; + case SID_ATTR_PARA_ADJUST_BLOCK: + { + SvxAdjustItem aItem( SVX_ADJUST_BLOCK, EE_PARA_JUST ); + SfxItemSet aEditAttr( GetPool(), EE_PARA_JUST, EE_PARA_JUST ); + + aEditAttr.Put( aItem ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_ADJUST_BLOCK); + } + break; + case SID_ATTR_PARA_ULSPACE: + { + sal_uInt16 nSlot = SID_ATTR_PARA_ULSPACE; + SvxULSpaceItem aULSP = (const SvxULSpaceItem&)pArgs->Get( + GetPool().GetWhich(nSlot)); + SfxItemSet aEditAttr( GetPool(), EE_PARA_ULSPACE, EE_PARA_ULSPACE ); + aULSP.SetWhich( EE_PARA_ULSPACE ); + + aEditAttr.Put( aULSP ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_ULSPACE); + } + break; + case SID_ATTR_PARA_LRSPACE: { + sal_uInt16 nSlot = SID_ATTR_PARA_LRSPACE; + SvxLRSpaceItem aLRSpace = (const SvxLRSpaceItem&)pArgs->Get( + GetPool().GetWhich(nSlot)); + + SfxItemSet aEditAttr( GetPool(), EE_PARA_LRSPACE, EE_PARA_LRSPACE ); + aLRSpace.SetWhich( EE_PARA_LRSPACE ); + + aEditAttr.Put( aLRSpace ); + mpDrawView->SetAttributes( aEditAttr ); + + Invalidate(SID_ATTR_PARA_LRSPACE); + break; + } + case SID_ATTR_LRSPACE: + { if( mpDrawView->IsTextEdit() ) { sal_uInt16 nId = SID_ATTR_PARA_LRSPACE; diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx index d3651b09568e..5579fe337118 100644 --- a/sd/source/ui/view/drviews7.cxx +++ b/sd/source/ui/view/drviews7.cxx @@ -203,6 +203,11 @@ IMPL_LINK( DrawViewShell, ClipboardChanged, TransferableDataHelper*, pDataHelper return 0; } +void DrawViewShell::GetDrawAttrState(SfxItemSet& rSet) +{ + SfxItemSet aSet( mpDrawView->GetGeoAttrFromMarked() ); + rSet.Put(aSet,sal_False); +} void DrawViewShell::GetMenuState( SfxItemSet &rSet ) { @@ -503,6 +508,8 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) { rSet.DisableItem( SID_HORIZONTAL ); rSet.DisableItem( SID_VERTICAL ); + rSet.DisableItem( SID_FLIP_HORIZONTAL ); + rSet.DisableItem( SID_FLIP_VERTICAL ); } if( !mpDrawView->IsMirrorAllowed() ) diff --git a/sd/source/ui/view/drviewsa.cxx b/sd/source/ui/view/drviewsa.cxx index 840979562272..cad4da25a7e8 100644 --- a/sd/source/ui/view/drviewsa.cxx +++ b/sd/source/ui/view/drviewsa.cxx @@ -49,6 +49,7 @@ #include <svx/fmshell.hxx> #include <svtools/cliplistener.hxx> #include <svx/float3d.hxx> +#include <svx/sidebar/SelectionAnalyzer.hxx> #include "helpids.h" #include "view/viewoverlaymanager.hxx" @@ -69,10 +70,14 @@ #include "slideshow.hxx" #include "ToolBarManager.hxx" #include "annotationmanager.hxx" +#include "DrawController.hxx" + +#include <boost/bind.hpp> using namespace ::rtl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; +using sfx2::sidebar::EnumContext; namespace sd { @@ -115,22 +120,31 @@ void SAL_CALL ScannerEventListener::disposing( const lang::EventObject& rEventOb DrawViewShell::DrawViewShell( SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow, PageKind ePageKind, FrameView* pFrameViewArgument ) -: ViewShell (pFrame, pParentWindow, rViewShellBase) -, maTabControl(this, pParentWindow) -, mbIsLayerModeActive(false) -, mbIsInSwitchPage(false) + : ViewShell (pFrame, pParentWindow, rViewShellBase) + , maTabControl(this, pParentWindow) + , mbIsLayerModeActive(false) + , mbIsInSwitchPage(false) + , mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler( + ::boost::bind(&DrawViewShell::GetContextForSelection, this), + uno::Reference<frame::XController>(&rViewShellBase.GetDrawController()), + sfx2::sidebar::EnumContext::Context_Default)) { if (pFrameViewArgument != NULL) mpFrameView = pFrameViewArgument; else mpFrameView = new FrameView(GetDoc()); Construct(GetDocSh(), ePageKind); + + mpSelectionChangeHandler->Connect(); + doShow(); } DrawViewShell::~DrawViewShell() { + mpSelectionChangeHandler->Disconnect(); + mpAnnotationManager.reset(); mpViewOverlayManager.reset(); @@ -810,6 +824,22 @@ void DrawViewShell::GetAnnotationState (SfxItemSet& rItemSet ) } +EnumContext::Context DrawViewShell::GetContextForSelection (void) const +{ + if (mpDrawView->GetMarkedObjectList().GetMarkCount() == 1) + if (mpDrawView->GetTextEditObject() != NULL) + if (mpDrawView->GetTextEditOutlinerView() != NULL) + return EnumContext::Context_DrawText; + + // All other cases are handled by the SelectionAnalyzer. + return ::svx::sidebar::SelectionAnalyzer::GetContextForSelection_SD( + mpDrawView->GetMarkedObjectList(), + meEditMode == EM_MASTERPAGE, + mePageKind == PK_HANDOUT, + mePageKind == PK_NOTES); +} + + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/view/drviewsf.cxx b/sd/source/ui/view/drviewsf.cxx index f1e04babdc82..4989cd2a5a07 100644 --- a/sd/source/ui/view/drviewsf.cxx +++ b/sd/source/ui/view/drviewsf.cxx @@ -58,6 +58,16 @@ #include "cfgids.hxx" #include "anminfo.hxx" +#include <editeng/lspcitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/escapementitem.hxx> +#include <editeng/numitem.hxx> +#include <editeng/adjustitem.hxx> +#include <svx/nbdtmgfact.hxx> +#include <svx/nbdtmg.hxx> + +using namespace svx::sidebar; using namespace ::com::sun::star; namespace sd { @@ -277,17 +287,133 @@ void DrawViewShell::GetAttrState( SfxItemSet& rSet ) : nWhich; switch ( nSlotId ) { + case SID_ATTR_PARA_ADJUST_LEFT: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + + SvxAdjustItem aItem= ( (const SvxAdjustItem&) aAttrs.Get( EE_PARA_JUST ) ); + SvxAdjust eAdj = aItem.GetAdjust(); + if ( eAdj == SVX_ADJUST_LEFT) + { + rSet.Put( SfxBoolItem( SID_ATTR_PARA_ADJUST_LEFT, sal_True ) ); + } + + bAttr = sal_True; + + Invalidate(nSlotId); + } + break; + case SID_ATTR_PARA_ADJUST_CENTER: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + + SvxAdjustItem aItem= ( (const SvxAdjustItem&) aAttrs.Get( EE_PARA_JUST ) ); + SvxAdjust eAdj = aItem.GetAdjust(); + if ( eAdj == SVX_ADJUST_CENTER) + { + rSet.Put( SfxBoolItem( SID_ATTR_PARA_ADJUST_CENTER, sal_True ) ); + } + + bAttr = sal_True; + + Invalidate(nSlotId); + } + break; + case SID_ATTR_PARA_ADJUST_RIGHT: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + + SvxAdjustItem aItem= ( (const SvxAdjustItem&) aAttrs.Get( EE_PARA_JUST ) ); + SvxAdjust eAdj = aItem.GetAdjust(); + if ( eAdj == SVX_ADJUST_RIGHT) + { + rSet.Put( SfxBoolItem( SID_ATTR_PARA_ADJUST_RIGHT, sal_True ) ); + } + + bAttr = sal_True; + + Invalidate(nSlotId); + } + break; + case SID_ATTR_PARA_ADJUST_BLOCK: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + + SvxAdjustItem aItem= ( (const SvxAdjustItem&) aAttrs.Get( EE_PARA_JUST ) ); + SvxAdjust eAdj = aItem.GetAdjust(); + if ( eAdj == SVX_ADJUST_BLOCK) + { + rSet.Put( SfxBoolItem( SID_ATTR_PARA_ADJUST_BLOCK, sal_True ) ); + } + + bAttr = sal_True; + + Invalidate(nSlotId); + } + break; + case SID_ATTR_PARA_LRSPACE: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + SvxLRSpaceItem aLRSpace = ( (const SvxLRSpaceItem&) aAttrs.Get( EE_PARA_LRSPACE ) ); + aLRSpace.SetWhich(SID_ATTR_PARA_LRSPACE); + rSet.Put(aLRSpace); + bAttr = sal_True; + Invalidate(SID_ATTR_PARA_LRSPACE); + } + break; + case SID_ATTR_PARA_LINESPACE: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + SvxLineSpacingItem aLineLR = ( (const SvxLineSpacingItem&) aAttrs.Get( EE_PARA_SBL ) ); + rSet.Put(aLineLR); + bAttr = sal_True; + Invalidate(SID_ATTR_PARA_LINESPACE); + } + break; + case SID_ATTR_PARA_ULSPACE: + { + SfxItemSet aAttrs( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aAttrs ); + SvxULSpaceItem aULSP = ( (const SvxULSpaceItem&) aAttrs.Get( EE_PARA_ULSPACE ) ); + aULSP.SetWhich(SID_ATTR_PARA_ULSPACE); + rSet.Put(aULSP); + bAttr = sal_True; + Invalidate(SID_ATTR_PARA_ULSPACE); + } + break; case SID_ATTR_FILL_STYLE: case SID_ATTR_FILL_COLOR: case SID_ATTR_FILL_GRADIENT: case SID_ATTR_FILL_HATCH: case SID_ATTR_FILL_BITMAP: case SID_ATTR_FILL_SHADOW: + case SID_ATTR_FILL_TRANSPARENCE: + case SID_ATTR_FILL_FLOATTRANSPARENCE: case SID_ATTR_LINE_STYLE: case SID_ATTR_LINE_DASH: case SID_ATTR_LINE_WIDTH: case SID_ATTR_LINE_COLOR: + case SID_ATTR_LINE_TRANSPARENCE: + case SID_ATTR_LINE_JOINT: + case SID_ATTR_LINE_CAP: case SID_ATTR_TEXT_FITTOSIZE: + case SID_ATTR_CHAR_FONT: + case SID_ATTR_CHAR_FONTHEIGHT: + case SID_ATTR_CHAR_SHADOWED: + case SID_ATTR_CHAR_POSTURE: + case SID_ATTR_CHAR_UNDERLINE: + case SID_ATTR_CHAR_STRIKEOUT: + case SID_ATTR_CHAR_WEIGHT: + case SID_ATTR_CHAR_COLOR: + case SID_ATTR_CHAR_KERNING: + case SID_SET_SUB_SCRIPT: + case SID_SET_SUPER_SCRIPT: { bAttr = sal_True; } @@ -427,6 +553,118 @@ void DrawViewShell::GetAttrState( SfxItemSet& rSet ) } } break; + case FN_BUL_NUM_RULE_INDEX: + case FN_NUM_NUM_RULE_INDEX: + { + SfxItemSet aEditAttr( GetDoc()->GetPool() ); + mpDrawView->GetAttributes( aEditAttr ); + + SfxItemSet aNewAttr( GetPool(), EE_ITEMS_START, EE_ITEMS_END ); + aNewAttr.Put( aEditAttr, sal_False ); + + + sal_uInt16 nActNumLvl = (sal_uInt16)0xFFFF; + SvxNumRule* pNumRule = NULL; + const SfxPoolItem* pTmpItem=NULL; + sal_uInt16 nNumItemId = SID_ATTR_NUMBERING_RULE; + + //if(SFX_ITEM_SET == aNewAttr.GetItemState(SID_PARAM_CUR_NUM_LEVEL, sal_False, &pTmpItem)) + // nActNumLvl = ((const SfxUInt16Item*)pTmpItem)->GetValue(); + rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX,DEFAULT_NONE)); + rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX,DEFAULT_NONE)); + nActNumLvl = mpDrawView->GetSelectionLevel(); + pTmpItem=GetNumBulletItem(aNewAttr, nNumItemId); + + if (pTmpItem) + pNumRule = new SvxNumRule(*((SvxNumBulletItem*)pTmpItem)->GetNumRule()); + + if ( pNumRule ) + { + sal_uInt16 nMask = 1; + sal_uInt16 nCount = 0; + sal_uInt16 nCurLevel = (sal_uInt16)0xFFFF; + for(sal_uInt16 i = 0; i < pNumRule->GetLevelCount(); i++) + { + if(nActNumLvl & nMask) + { + nCount++; + nCurLevel = i; + } + nMask <<= 1; + } + if ( nCount == 1 ) + { + sal_Bool bBullets = sal_False; + const SvxNumberFormat* pNumFmt = pNumRule->Get(nCurLevel); + if ( pNumFmt ) + { + switch(pNumFmt->GetNumberingType()) + { + case SVX_NUM_CHAR_SPECIAL: + case SVX_NUM_BITMAP: + bBullets = sal_True; + break; + + default: + bBullets = sal_False; + } + + rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX,(sal_uInt16)0xFFFF)); + rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX,(sal_uInt16)0xFFFF)); + if ( bBullets ) + { + NBOTypeMgrBase* pBullets = NBOutlineTypeMgrFact::CreateInstance(eNBOType::MIXBULLETS); + if ( pBullets ) + { + sal_uInt16 nBulIndex = pBullets->GetNBOIndexForNumRule(*pNumRule,nActNumLvl); + rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX,nBulIndex)); + } + }else + { + NBOTypeMgrBase* pNumbering = NBOutlineTypeMgrFact::CreateInstance(eNBOType::NUMBERING); + if ( pNumbering ) + { + sal_uInt16 nBulIndex = pNumbering->GetNBOIndexForNumRule(*pNumRule,nActNumLvl); + rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX,nBulIndex)); + } + } + } + } + } + } + break; + //End + // Added by Li Hui for story 179. + case FN_NUM_BULLET_ON: + case FN_NUM_NUMBERING_ON: + { + sal_Bool bEnable = sal_False; + const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList(); + const sal_uInt32 nMarkCount = rMarkList.GetMarkCount(); + for (sal_uInt32 nIndex = 0; nIndex < nMarkCount; nIndex++) + { + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(rMarkList.GetMark(nIndex)->GetMarkedSdrObj()); + if (pTextObj && pTextObj->GetObjInventor() == SdrInventor) + { + if (pTextObj->GetObjIdentifier() != OBJ_OLE2) + { + bEnable = sal_True; + break; + } + } + } + if (bEnable) + { + rSet.Put(SfxBoolItem(FN_NUM_BULLET_ON, sal_False)); + rSet.Put(SfxBoolItem(FN_NUM_NUMBERING_ON, sal_False)); + } + else + { + rSet.DisableItem(FN_NUM_BULLET_ON); + rSet.DisableItem(FN_NUM_NUMBERING_ON); + } + } + break; } nWhich = aIter.NextWhich(); } @@ -461,9 +699,45 @@ void DrawViewShell::GetAttrState( SfxItemSet& rSet ) nWhich = aNewIter.NextWhich(); } } + + SfxItemState eState = pSet->GetItemState( EE_PARA_LRSPACE ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_PARA_LRSPACE); + rSet.InvalidateItem(SID_ATTR_PARA_LRSPACE); + } + eState = pSet->GetItemState( EE_PARA_SBL ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_PARA_SBL); + rSet.InvalidateItem(SID_ATTR_PARA_LINESPACE); + } + eState = pSet->GetItemState( EE_PARA_ULSPACE ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_PARA_ULSPACE); + rSet.InvalidateItem(SID_ATTR_PARA_ULSPACE); + } + + SvxEscapement eEsc = (SvxEscapement) ( (const SvxEscapementItem&) + pSet->Get( EE_CHAR_ESCAPEMENT ) ).GetEnumValue(); + if( eEsc == SVX_ESCAPEMENT_SUPERSCRIPT ) + { + rSet.Put( SfxBoolItem( SID_SET_SUPER_SCRIPT, sal_True ) ); + } + else if( eEsc == SVX_ESCAPEMENT_SUBSCRIPT ) + { + rSet.Put( SfxBoolItem( SID_SET_SUB_SCRIPT, sal_True ) ); + } + + eState = pSet->GetItemState( EE_CHAR_KERNING, sal_True ); + if ( eState == SFX_ITEM_DONTCARE ) + { + rSet.InvalidateItem(EE_CHAR_KERNING); + rSet.InvalidateItem(SID_ATTR_CHAR_KERNING); + } delete pSet; } - } diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx index 4be97a05403f..61e33f900463 100644 --- a/sd/source/ui/view/drviewsj.cxx +++ b/sd/source/ui/view/drviewsj.cxx @@ -75,6 +75,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_OBJECT_TITLE_DESCRIPTION ) || SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_ATTR_FILL_STYLE ) || + SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_ATTR_FILL_TRANSPARENCE ) || + SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_ATTR_FILL_FLOATTRANSPARENCE ) || SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_CHANGEBEZIER ) || SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_CHANGEPOLYGON ) || SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_LINEEND_POLYGON ) || @@ -166,6 +168,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) { //rSet.DisableItem( SID_ATTRIBUTES_AREA ); // remove again! rSet.DisableItem( SID_ATTR_FILL_STYLE ); + rSet.DisableItem( SID_ATTR_FILL_TRANSPARENCE ); + rSet.DisableItem( SID_ATTR_FILL_FLOATTRANSPARENCE ); } if( (!pObj->ISA( SdrPathObj ) && !aInfoRec.bCanConvToPath) || pObj->ISA( SdrObjGroup ) ) // As long as JOE handles it incorrectly! { // JOE: a group object may can be converted into a PathObj @@ -364,6 +368,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) if( bLine && !bText && !bDrawObj &&!b3dObj) { rSet.DisableItem( SID_ATTR_FILL_STYLE ); + rSet.DisableItem( SID_ATTR_FILL_TRANSPARENCE ); + rSet.DisableItem( SID_ATTR_FILL_FLOATTRANSPARENCE ); } if( !bEdgeObj ) rSet.DisableItem( SID_CONNECTION_DLG ); @@ -482,6 +488,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) rSet.DisableItem( SID_COPYOBJECTS ); rSet.DisableItem( SID_HORIZONTAL ); rSet.DisableItem( SID_VERTICAL ); + rSet.DisableItem( SID_FLIP_HORIZONTAL ); + rSet.DisableItem( SID_FLIP_VERTICAL ); rSet.DisableItem( SID_GROUP ); rSet.DisableItem( SID_UNGROUP ); rSet.DisableItem( SID_NAME_GROUP ); diff --git a/sd/source/ui/view/drvwshrg.cxx b/sd/source/ui/view/drvwshrg.cxx index 384ffa0e803b..abe2d38f8c44 100644 --- a/sd/source/ui/view/drvwshrg.cxx +++ b/sd/source/ui/view/drvwshrg.cxx @@ -28,6 +28,7 @@ #include <svx/imapdlg.hxx> #include <svx/colrctrl.hxx> #include <sfx2/objface.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> #include <svx/f3dchild.hxx> #include <svx/tbxcustomshapes.hxx> @@ -79,6 +80,7 @@ SFX_IMPL_INTERFACE(DrawViewShell, SfxShell, SdResId(STR_DRAWVIEWSHELL)) SFX_CHILDWINDOW_REGISTRATION( ::sd::SpellDialogChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG ); SFX_CHILDWINDOW_REGISTRATION( ::avmedia::MediaPlayer::GetChildWindowId() ); + SFX_CHILDWINDOW_REGISTRATION(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); } @@ -104,6 +106,7 @@ SFX_IMPL_INTERFACE(GraphicViewShell, SfxShell, SdResId(STR_DRAWVIEWSHELL)) //SOH SFX_CHILDWINDOW_REGISTRATION( ::sd::SpellDialogChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG ); SFX_CHILDWINDOW_REGISTRATION( ::avmedia::MediaPlayer::GetChildWindowId() ); + SFX_CHILDWINDOW_REGISTRATION(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); } TYPEINIT1( GraphicViewShell, DrawViewShell ); diff --git a/sd/source/ui/view/outlnvs2.cxx b/sd/source/ui/view/outlnvs2.cxx index 93db7ea6ccfd..87086ac60af3 100644 --- a/sd/source/ui/view/outlnvs2.cxx +++ b/sd/source/ui/view/outlnvs2.cxx @@ -63,6 +63,7 @@ #include "sdabstdlg.hxx" #include "framework/FrameworkHelper.hxx" #include "DrawViewShell.hxx" +#include <boost/scoped_ptr.hpp> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::presentation; @@ -365,12 +366,16 @@ void OutlineViewShell::ShowSlideShow(SfxRequest& rReq) void OutlineViewShell::FuTemporaryModify(SfxRequest &rReq) { - OutlineViewModelChangeGuard aGuard( *pOlView ); - + sal_uInt16 nSId = rReq.GetSlot(); + boost::scoped_ptr< OutlineViewModelChangeGuard > aGuard; + if (nSId != SID_OUTLINE_BULLET && nSId != FN_SVX_SET_BULLET && nSId != FN_SVX_SET_NUMBER) + { + aGuard.reset( new OutlineViewModelChangeGuard(*pOlView) ); + } DeactivateCurrentFunction(); OutlinerView* pOutlinerView = pOlView->GetViewByWindow( GetActiveWindow() ); - sal_uInt16 nSId = rReq.GetSlot(); + //sal_uInt16 nSId = rReq.GetSlot(); switch( nSId ) { @@ -415,6 +420,8 @@ void OutlineViewShell::FuTemporaryModify(SfxRequest &rReq) break; case SID_OUTLINE_BULLET: + case FN_SVX_SET_BULLET: + case FN_SVX_SET_NUMBER: { SetCurrentFunction( FuOutlineBullet::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) ); Cancel(); @@ -429,6 +436,7 @@ void OutlineViewShell::FuTemporaryModify(SfxRequest &rReq) } break; + case SID_CHAR_DLG_EFFECT: case SID_CHAR_DLG: { SetCurrentFunction( FuChar::Create( this, GetActiveWindow(), pOlView, GetDoc(), rReq ) ); diff --git a/sd/source/ui/view/outlnvsh.cxx b/sd/source/ui/view/outlnvsh.cxx index 743a6b22b7a2..494101834ce8 100644 --- a/sd/source/ui/view/outlnvsh.cxx +++ b/sd/source/ui/view/outlnvsh.cxx @@ -46,6 +46,8 @@ #include <editeng/editstat.hxx> #include <svl/itempool.hxx> #include <sfx2/tplpitem.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> +#include <sfx2/sidebar/EnumContext.hxx> #include <svx/svdorect.hxx> #include <sot/formats.hxx> #include <com/sun/star/linguistic2/XThesaurus.hpp> @@ -117,6 +119,7 @@ SFX_IMPL_INTERFACE(OutlineViewShell, SfxShell, SdResId(STR_OUTLINEVIEWSHELL)) SFX_CHILDWINDOW_REGISTRATION( SvxHlinkDlgWrapper::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( ::sd::SpellDialogChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG ); + SFX_CHILDWINDOW_REGISTRATION(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); } @@ -209,6 +212,8 @@ OutlineViewShell::OutlineViewShell ( Construct(GetDocSh()); + SetContextName(sfx2::sidebar::EnumContext::GetContextName(sfx2::sidebar::EnumContext::Context_OutlineText)); + doShow(); } diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx index 06249b80bc2b..ed0579050984 100644 --- a/sd/source/ui/view/sdview.cxx +++ b/sd/source/ui/view/sdview.cxx @@ -43,11 +43,13 @@ #include <svx/dialogs.hrc> #include <sfx2/viewfrm.hxx> +#include <sfx2/sidebar/EnumContext.hxx> #include <svx/svdopage.hxx> #include <toolkit/helper/vclunohelper.hxx> #include <svx/xlndsit.hxx> #include <svx/xlineit0.hxx> #include <svx/xlnclit.hxx> +#include <svx/sidebar/ContextChangeEventMultiplexer.hxx> #include <vcl/virdev.hxx> #include "app.hrc" @@ -70,6 +72,7 @@ #include "undo/undomanager.hxx" #include <svx/sdr/contact/viewobjectcontact.hxx> #include <svx/sdr/contact/viewcontact.hxx> +#include <svx/svdotable.hxx> #include "EventMultiplexer.hxx" #include "ViewShellBase.hxx" #include "ViewShellManager.hxx" @@ -80,6 +83,7 @@ #include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <drawinglayer/primitive2d/groupprimitive2d.hxx> #include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/table/tablecontroller.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <drawinglayer/primitive2d/textprimitive2d.hxx> #include <svx/unoapi.hxx> @@ -89,6 +93,7 @@ using namespace com::sun::star; using namespace com::sun::star::uno; +using namespace sdr::table; namespace sd { TYPEINIT1(View, FmFormView); @@ -690,6 +695,10 @@ sal_Bool View::SdrBeginTextEdit( pGivenOutlinerView, bDontDeleteOutliner, bOnlyOneView, bGrabFocus); + ContextChangeEventMultiplexer::NotifyContextChange( + &GetViewShell()->GetViewShellBase(), + ::sfx2::sidebar::EnumContext::Context_DrawText); + if (bReturn) { ::Outliner* pOL = GetTextEditOutliner(); @@ -705,11 +714,15 @@ sal_Bool View::SdrBeginTextEdit( { aBackground = pObj->GetPage()->GetPageBackgroundColor(pPV); } - pOL->SetBackgroundColor( aBackground ); + if (pOL != NULL) + pOL->SetBackgroundColor( aBackground ); } - pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl)); - pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl)); + if (pOL != NULL) + { + pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl)); + pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl)); + } } return(bReturn); @@ -746,10 +759,16 @@ SdrEndTextEditKind View::SdrEndTextEdit(sal_Bool bDontDeleteReally ) } } - GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(sd::tools::EventMultiplexerEvent::EID_END_TEXT_EDIT, (void*)xObj.get() ); + GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent( + sd::tools::EventMultiplexerEvent::EID_END_TEXT_EDIT, + (void*)xObj.get() ); if( xObj.is() ) { + ContextChangeEventMultiplexer::NotifyContextChange( + &GetViewShell()->GetViewShellBase(), + ::sfx2::sidebar::EnumContext::Context_Default); + SdPage* pPage = dynamic_cast< SdPage* >( xObj->GetPage() ); if( pPage ) pPage->onEndTextEdit( xObj.get() ); @@ -1208,6 +1227,169 @@ void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfos ) } } +sal_Bool View::ShouldToggleOn(sal_Bool bBulletOnOffMode, sal_Bool bNormalBullet) +{ + // If setting bullets/numbering by the dialog, always should toggle on. + if (!bBulletOnOffMode) + return sal_True; + SdrModel* pSdrModel = GetModel(); + if (!pSdrModel) + return sal_False; + + sal_Bool bToggleOn = sal_False; + SdrOutliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, pSdrModel); + sal_uInt32 nMarkCount = GetMarkedObjectCount(); + for (sal_uInt32 nIndex = 0; nIndex < nMarkCount && !bToggleOn; nIndex++) + { + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex)); + if (!pTextObj || pTextObj->IsTextEditActive()) + continue; + if (pTextObj->ISA(SdrTableObj)) + { + SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj); + if (!pTableObj) + continue; + CellPos aStart, aEnd; + SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get()); + if (pTableController) + { + pTableController->getSelectedCells(aStart, aEnd); + } + else + { + aStart = pTableObj->getFirstCell(); + aEnd = pTableObj->getLastCell(); + } + sal_Int32 nColCount = pTableObj->getColumnCount(); + for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow && !bToggleOn; nRow++) + { + for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol && !bToggleOn; nCol++) + { + sal_Int32 nCellIndex = nRow * nColCount + nCol; + SdrText* pText = pTableObj->getText(nCellIndex); + if (!pText || !pText->GetOutlinerParaObject()) + continue; + pOutliner->SetText(*(pText->GetOutlinerParaObject())); + sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus(); + bToggleOn = ((bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1)) ? sal_True : bToggleOn; + pOutliner->Clear(); + } + } + } + else + { + OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); + if (!pParaObj) + continue; + pOutliner->SetText(*pParaObj); + sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus(); + bToggleOn = ((bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1)) ? sal_True : bToggleOn; + pOutliner->Clear(); + } + } + delete pOutliner; + return bToggleOn; +} + +void View::ToggleMarkedObjectsBullets(sal_Bool bBulletOnOffMode, sal_Bool bNormalBullet, sal_Bool bMasterView, SvxNumRule* pNumRule, sal_Bool bForceBulletOnOff) +{ + SdrModel* pSdrModel = GetModel(); + Window* pWindow = dynamic_cast< Window* >(GetFirstOutputDevice()); + if (!pSdrModel || !pWindow) + return; + + sal_Bool bUndoEnabled = pSdrModel->IsUndoEnabled(); + sal_Bool bToggleOn = ShouldToggleOn(bBulletOnOffMode, bNormalBullet); + if ( bForceBulletOnOff ) { + bToggleOn = bBulletOnOffMode; + } + SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*pSdrModel); + SdrOutliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, pSdrModel); + OutlinerView* pOutlinerView = new OutlinerView(pOutliner, pWindow); + + sal_uInt32 nMarkCount = GetMarkedObjectCount(); + for (sal_uInt32 nIndex = 0; nIndex < nMarkCount; nIndex++) + { + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex)); + if (!pTextObj || pTextObj->IsTextEditActive()) + continue; + if (pTextObj->ISA(SdrTableObj)) + { + SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj); + if (!pTableObj) + continue; + CellPos aStart, aEnd; + SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get()); + if (pTableController) + { + pTableController->getSelectedCells(aStart, aEnd); + } + else + { + aStart = pTableObj->getFirstCell(); + aEnd = pTableObj->getLastCell(); + } + sal_Int32 nColCount = pTableObj->getColumnCount(); + for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++) + { + for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++) + { + sal_Int32 nCellIndex = nRow * nColCount + nCol; + SdrText* pText = pTableObj->getText(nCellIndex); + if (!pText || !pText->GetOutlinerParaObject()) + continue; + + pOutliner->SetText(*(pText->GetOutlinerParaObject())); + if (bUndoEnabled) + { + SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nCellIndex)); + pUndoGroup->AddAction(pTxtUndo); + } + pOutlinerView->ToggleAllParagraphsBullets(bBulletOnOffMode, bNormalBullet, bToggleOn, bMasterView, pNumRule); + sal_uInt32 nParaCount = pOutliner->GetParagraphCount(); + pText->SetOutlinerParaObject(pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount)); + pOutliner->Clear(); + } + } + // Broadcast the object change event. + if (!pTextObj->AdjustTextFrameWidthAndHeight()) + { + pTextObj->SetChanged(); + pTextObj->BroadcastObjectChange(); + } + } + else + { + OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); + if (!pParaObj) + continue; + pOutliner->SetText(*pParaObj); + if (bUndoEnabled) + { + SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, 0)); + pUndoGroup->AddAction(pTxtUndo); + } + pOutlinerView->ToggleAllParagraphsBullets(bBulletOnOffMode, bNormalBullet, bToggleOn, bMasterView, pNumRule); + sal_uInt32 nParaCount = pOutliner->GetParagraphCount(); + pTextObj->SetOutlinerParaObject(pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount)); + pOutliner->Clear(); + } + } + + if (pUndoGroup->GetActionCount() > 0 && bUndoEnabled) + { + pSdrModel->BegUndo(); + pSdrModel->AddUndo(pUndoGroup); + pSdrModel->EndUndo(); + } + else + { + delete pUndoGroup; + } + delete pOutliner; + delete pOutlinerView; +} + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 50716b156818..6fe1ba2cded2 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -75,6 +75,11 @@ #include "Window.hxx" #include "fupoor.hxx" +#include <editeng/numitem.hxx> +#include <editeng/eeitem.hxx> +#include <svl/poolitem.hxx> +#include <glob.hrc> + namespace sd { namespace ui { namespace table { extern SfxShell* CreateTableObjectBar( ViewShell& rShell, ::sd::View* pView ); } } } @@ -147,7 +152,8 @@ ViewShell::~ViewShell() { // Keep the content window from accessing in its destructor the // WindowUpdater. - mpContentWindow->SetViewShell(NULL); + if (mpContentWindow) + mpContentWindow->SetViewShell(NULL); delete mpZoomList; @@ -156,6 +162,13 @@ ViewShell::~ViewShell() if (mpImpl->mpSubShellFactory.get() != NULL) GetViewShellBase().GetViewShellManager()->RemoveSubShellFactory( this,mpImpl->mpSubShellFactory); + + if (mpContentWindow) + { + OSL_TRACE("destroying mpContentWindow at %x with parent %x", mpContentWindow.get(), + mpContentWindow->GetParent()); + mpContentWindow.reset(); + } } @@ -729,7 +742,86 @@ void ViewShell::SetupRulers (void) } } +const SfxPoolItem* ViewShell::GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt16& nNumItemId) +{ + const SfxPoolItem* pTmpItem = NULL; + + if(aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem) == SFX_ITEM_SET) + { + return pTmpItem; + } + else + { + nNumItemId = aNewAttr.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); + SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem); + if (eState == SFX_ITEM_SET) + return pTmpItem; + else + { + sal_Bool bOutliner = sal_False; + sal_Bool bTitle = sal_False; + + if( mpView ) + { + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + const sal_uInt32 nCount = rMarkList.GetMarkCount(); + + for(sal_uInt32 nNum = 0; nNum < nCount; nNum++) + { + SdrObject* pObj = rMarkList.GetMark(nNum)->GetMarkedSdrObj(); + if( pObj->GetObjInventor() == SdrInventor ) + { + switch(pObj->GetObjIdentifier()) + { + case OBJ_TITLETEXT: + bTitle = sal_True; + break; + case OBJ_OUTLINETEXT: + bOutliner = sal_True; + break; + } + } + } + } + + const SvxNumBulletItem *pItem = NULL; + if(bOutliner) + { + SfxStyleSheetBasePool* pSSPool = mpView->GetDocSh()->GetStyleSheetPool(); + String aStyleName((SdResId(STR_LAYOUT_OUTLINE))); + aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) ); + SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SD_STYLE_FAMILY_PSEUDO); + if( pFirstStyleSheet ) + pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, sal_False, (const SfxPoolItem**)&pItem); + } + + if( pItem == NULL ) + pItem = (SvxNumBulletItem*) aNewAttr.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET); + + aNewAttr.Put(*pItem, EE_PARA_NUMBULLET); + + if(bTitle && aNewAttr.GetItemState(EE_PARA_NUMBULLET,sal_True) == SFX_ITEM_ON ) + { + SvxNumBulletItem* pBulletItem = (SvxNumBulletItem*)aNewAttr.GetItem(EE_PARA_NUMBULLET,sal_True); + SvxNumRule* pRule = pBulletItem->GetNumRule(); + if(pRule) + { + SvxNumRule aNewRule( *pRule ); + aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, sal_True ); + + SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET ); + aNewAttr.Put(aNewItem); + } + } + SfxItemState eNumState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem); + if (eNumState == SFX_ITEM_SET) + return pTmpItem; + + } + } + return pTmpItem; +} sal_Bool ViewShell::HasRuler (void) @@ -885,9 +977,10 @@ void ViewShell::ArrangeGUIElements (void) { OSL_ASSERT (GetViewShell()!=NULL); - mpContentWindow->SetPosSizePixel( - Point(nLeft,nTop), - Size(nRight-nLeft,nBottom-nTop)); + if (mpContentWindow) + mpContentWindow->SetPosSizePixel( + Point(nLeft,nTop), + Size(nRight-nLeft,nBottom-nTop)); } // Windows in the center and rulers at the left and top side. |