/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" #include "ViewShellImplementation.hxx" #include "sdpage.hxx" #include "drawdoc.hxx" #include "sdresid.hxx" #include "glob.hrc" #include "app.hrc" #include "strings.hrc" #include "strings.hrc" #include "helpids.h" #include "sdattr.hxx" #include "sdabstdlg.hxx" #include "unmodpg.hxx" #include "Window.hxx" #include "optsitem.hxx" #include "DrawDocShell.hxx" #include "DrawController.hxx" #include "FactoryIds.hxx" #include "slideshow.hxx" #include "ViewShellBase.hxx" #include "FrameView.hxx" #include "DrawViewShell.hxx" #include "ViewShellHint.hxx" #include "taskpane/PanelId.hxx" #include "framework/FrameworkHelper.hxx" #include #include #include #include #include #include #include #include "undo/undoobjects.hxx" #include using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::sd::framework::FrameworkHelper; namespace sd { ViewShell::Implementation::Implementation (ViewShell& rViewShell) : mbIsShowingUIControls(false), mbIsMainViewShell(false), mbIsInitialized(false), mbArrangeActive(false), mpSubShellFactory(), mpUpdateLockForMouse(), mrViewShell(rViewShell) { } ViewShell::Implementation::~Implementation (void) { if ( ! mpUpdateLockForMouse.expired()) { ::boost::shared_ptr pLock(mpUpdateLockForMouse); if (pLock.get() != NULL) { // Force the ToolBarManagerLock to be released even when the // IsUICaptured() returns . pLock->Release(true); } } } void ViewShell::Implementation::ProcessModifyPageSlot ( SfxRequest& rRequest, SdPage* pCurrentPage, PageKind ePageKind) { SdDrawDocument* pDocument = mrViewShell.GetDoc(); SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin(); sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False); sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False); SetOfByte aVisibleLayers; sal_Bool bHandoutMode = sal_False; SdPage* pHandoutMPage = NULL; String aNewName; // #95981# String aOldName; AutoLayout aNewAutoLayout; sal_Bool bBVisible; sal_Bool bBObjsVisible; const SfxItemSet* pArgs = rRequest.GetArgs(); if (pCurrentPage != NULL && pCurrentPage->TRG_HasMasterPage()) aVisibleLayers = pCurrentPage->TRG_GetMasterPageVisibleLayers(); else aVisibleLayers.SetAll(); do { if (pCurrentPage == NULL) break; if (!pArgs || pArgs->Count() == 1 || pArgs->Count() == 2 ) { if (pArgs && pArgs->Count() == 2) { // We have been called with a request that contains two // arguments. One was used as preselected layout in a // dialog. We could select that layout in the // layout panel instead. /* SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False); eNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue (); */ } // 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); SfxViewFrame* pFrame = mrViewShell.GetViewFrame(); if (pFrame!=NULL && pFrame->GetDispatcher()!=NULL) { pFrame->GetDispatcher()->Execute ( SID_SHOW_TOOL_PANEL, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aMakeToolPaneVisible, &aPanelId, NULL); } else { DBG_ASSERT(pFrame!=NULL && pFrame->GetDispatcher()!=NULL, "ViewShell::Implementation::ProcessModifyPageSlot(): can not get dispatcher"); } // We have activated a non-modal control in the task pane. // Because it does not return anything we can not do anything // more right now and have to exit here. break; } else if (pArgs->Count() == 4) { SFX_REQUEST_ARG (rRequest, pNewName, SfxStringItem, ID_VAL_PAGENAME, sal_False); SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False); SFX_REQUEST_ARG (rRequest, pBVisible, SfxBoolItem, ID_VAL_ISPAGEBACK, sal_False); SFX_REQUEST_ARG (rRequest, pBObjsVisible, SfxBoolItem, ID_VAL_ISPAGEOBJ, sal_False); AutoLayout aLayout ((AutoLayout)pNewAutoLayout->GetValue ()); if (aLayout >= AUTOLAYOUT__START && aLayout < AUTOLAYOUT__END) { aNewName = pNewName->GetValue (); aNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue (); bBVisible = pBVisible->GetValue (); bBObjsVisible = pBObjsVisible->GetValue (); } else { StarBASIC::FatalError (SbERR_BAD_PROP_VALUE); rRequest.Ignore (); break; } if (ePageKind == PK_HANDOUT) { bHandoutMode = sal_True; pHandoutMPage = pDocument->GetMasterSdPage(0, PK_HANDOUT); } } else { StarBASIC::FatalError (SbERR_WRONG_ARGS); rRequest.Ignore (); break; } SdPage* pUndoPage = bHandoutMode ? pHandoutMPage : pCurrentPage; ::svl::IUndoManager* pUndoManager = mrViewShell.GetDocSh()->GetUndoManager(); DBG_ASSERT(pUndoManager, "No UNDO MANAGER ?!?"); if( pUndoManager ) { String aComment( SdResId(STR_UNDO_MODIFY_PAGE) ); pUndoManager->EnterListAction(aComment, aComment); ModifyPageUndoAction* pAction = new ModifyPageUndoAction( pDocument, pUndoPage, aNewName, aNewAutoLayout, bBVisible, bBObjsVisible); pUndoManager->AddUndoAction(pAction); // Clear the selection because the selectec object may be removed as // a result of the ssignment of the layout. mrViewShell.GetDrawView()->UnmarkAll(); if (!bHandoutMode) { if (pCurrentPage->GetName() != aNewName) { pCurrentPage->SetName(aNewName); if (ePageKind == PK_STANDARD) { sal_uInt16 nPage = (pCurrentPage->GetPageNum()-1) / 2; SdPage* pNotesPage = pDocument->GetSdPage(nPage, PK_NOTES); if (pNotesPage != NULL) pNotesPage->SetName(aNewName); } } pCurrentPage->SetAutoLayout(aNewAutoLayout, sal_True); aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False); aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False); aVisibleLayers.Set(aBckgrnd, bBVisible); aVisibleLayers.Set(aBckgrndObj, bBObjsVisible); pCurrentPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); } else { pHandoutMPage->SetAutoLayout(aNewAutoLayout, sal_True); } mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); sal_Bool bSetModified = sal_True; if (pArgs && pArgs->Count() == 1) { bSetModified = (sal_Bool) ((SfxBoolItem&) pArgs->Get(SID_MODIFYPAGE)).GetValue(); } pUndoManager->AddUndoAction( new UndoAutoLayoutPosAndSize( *pUndoPage ) ); pUndoManager->LeaveListAction(); pDocument->SetChanged(bSetModified); } } while (false); mrViewShell.Cancel(); rRequest.Done (); } void ViewShell::Implementation::AssignLayout ( SfxRequest& rRequest, PageKind ePageKind ) { const SfxUInt32Item* pWhatPage = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATPAGE, sal_False, TYPE(SfxUInt32Item) ) ); const SfxUInt32Item* pWhatLayout = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATLAYOUT, sal_False, TYPE(SfxUInt32Item) ) ); SdDrawDocument* pDocument = mrViewShell.GetDoc(); if( !pDocument ) return; SdPage* pPage = 0; if( pWhatPage ) { pPage = pDocument->GetSdPage(static_cast(pWhatPage->GetValue()), ePageKind); } if( pPage == 0 ) pPage = mrViewShell.getCurrentPage(); if( pPage ) { AutoLayout eLayout = pPage->GetAutoLayout(); if( pWhatLayout ) eLayout = static_cast< AutoLayout >( pWhatLayout->GetValue() ); // Transform the given request into the four argument form that is // understood by ProcessModifyPageSlot(). SdrLayerAdmin& rLayerAdmin (mrViewShell.GetViewShellBase().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)); SetOfByte aVisibleLayers; if( pPage->GetPageKind() == PK_HANDOUT ) aVisibleLayers.SetAll(); else aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); SfxRequest aRequest (mrViewShell.GetViewShellBase().GetViewFrame(), SID_MODIFYPAGE); aRequest.AppendItem(SfxStringItem (ID_VAL_PAGENAME, pPage->GetName())); aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, eLayout)); aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground))); aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEOBJ, aVisibleLayers.IsSet(aBackgroundObject))); // Forward the call with the new arguments. ProcessModifyPageSlot( aRequest, pPage, pPage->GetPageKind()); } } sal_uInt16 ViewShell::Implementation::GetViewId (void) { switch (mrViewShell.GetShellType()) { case ViewShell::ST_IMPRESS: case ViewShell::ST_NOTES: case ViewShell::ST_HANDOUT: return IMPRESS_FACTORY_ID; case ViewShell::ST_DRAW: return DRAW_FACTORY_ID; case ViewShell::ST_OUTLINE: return OUTLINE_FACTORY_ID; case ViewShell::ST_SLIDE_SORTER: return SLIDE_SORTER_FACTORY_ID; case ViewShell::ST_PRESENTATION: return PRESENTATION_FACTORY_ID; // 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_NONE: default: return IMPRESS_FACTORY_ID; } } SvxIMapDlg* ViewShell::Implementation::GetImageMapDialog (void) { SvxIMapDlg* pDialog = NULL; SfxChildWindow* pChildWindow = SfxViewFrame::Current()->GetChildWindow( SvxIMapDlgChildWindow::GetChildWindowId()); if (pChildWindow != NULL) pDialog = dynamic_cast(pChildWindow->GetWindow()); return pDialog; } //===== ToolBarManagerLock ==================================================== class ViewShell::Implementation::ToolBarManagerLock::Deleter { public: void operator() (ToolBarManagerLock* pObject) { delete pObject; } }; ::boost::shared_ptr ViewShell::Implementation::ToolBarManagerLock::Create ( const ::boost::shared_ptr& rpManager) { ::boost::shared_ptr pLock ( new ViewShell::Implementation::ToolBarManagerLock(rpManager), ViewShell::Implementation::ToolBarManagerLock::Deleter()); pLock->mpSelf = pLock; return pLock; } ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock ( const ::boost::shared_ptr& rpManager) : mpLock(new ToolBarManager::UpdateLock(rpManager)), maTimer() { // Start a timer that will unlock the ToolBarManager update lock when // that is not done explicitly by calling Release(). maTimer.SetTimeoutHdl(LINK(this,ToolBarManagerLock,TimeoutCallback)); maTimer.SetTimeout(100); maTimer.Start(); } IMPL_LINK(ViewShell::Implementation::ToolBarManagerLock,TimeoutCallback,Timer*,EMPTYARG) { // If possible then release the lock now. Otherwise start the timer // and try again later. if (Application::IsUICaptured()) { maTimer.Start(); } else { mpSelf.reset(); } return 0; } void ViewShell::Implementation::ToolBarManagerLock::Release (bool bForce) { // If possible then release the lock now. Otherwise try again when the // timer expires. if (bForce || ! Application::IsUICaptured()) { mpSelf.reset(); } } ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock (void) { mpLock.reset(); } } // end of namespace sd