/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace sd { ViewShell::Implementation::Implementation (ViewShell& rViewShell) : mbIsMainViewShell(false), mbIsInitialized(false), mbArrangeActive(false), mrViewShell(rViewShell) { } ViewShell::Implementation::~Implementation() COVERITY_NOEXCEPT_FALSE { if ( ! mpUpdateLockForMouse.expired()) { std::shared_ptr pLock(mpUpdateLockForMouse); if (pLock != nullptr) { // 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(); SdrLayerIDSet aVisibleLayers; bool bHandoutMode = false; SdPage* pHandoutMPage = nullptr; OUString aNewName; AutoLayout aNewAutoLayout; bool bBVisible; bool bBObjsVisible; const SfxItemSet* pArgs = rRequest.GetArgs(); if (pCurrentPage != nullptr && pCurrentPage->TRG_HasMasterPage()) aVisibleLayers = pCurrentPage->TRG_GetMasterPageVisibleLayers(); else aVisibleLayers.SetAll(); do { if (pCurrentPage == nullptr) break; if (!pArgs || pArgs->Count() == 1 || pArgs->Count() == 2 ) { // First make sure that the sidebar is visible mrViewShell.GetDrawView()->SdrEndTextEdit(); mrViewShell.GetDrawView()->UnmarkAll(); if (SfxViewFrame* pViewFrame = mrViewShell.GetViewFrame()) { pViewFrame->ShowChildWindow(SID_SIDEBAR); sfx2::sidebar::Sidebar::TogglePanel( u"SdLayoutsPanel", pViewFrame->GetFrame().GetFrameInterface()); } break; } else if (pArgs->Count() == 4) { const SfxStringItem* pNewName = rRequest.GetArg(ID_VAL_PAGENAME); const SfxUInt32Item* pNewAutoLayout = rRequest.GetArg(ID_VAL_WHATLAYOUT); const SfxBoolItem* pBVisible = rRequest.GetArg(ID_VAL_ISPAGEBACK); const SfxBoolItem* pBObjsVisible = rRequest.GetArg(ID_VAL_ISPAGEOBJ); assert(pNewName && pNewAutoLayout && pBVisible && pBObjsVisible && "must be present"); AutoLayout aLayout (static_cast(pNewAutoLayout->GetValue ())); if (aLayout >= AUTOLAYOUT_START && aLayout < AUTOLAYOUT_END) { aNewName = pNewName->GetValue (); aNewAutoLayout = static_cast(pNewAutoLayout->GetValue ()); bBVisible = pBVisible->GetValue (); bBObjsVisible = pBObjsVisible->GetValue (); } else { #if HAVE_FEATURE_SCRIPTING StarBASIC::FatalError (ERRCODE_BASIC_BAD_PROP_VALUE); #endif rRequest.Ignore (); break; } if (ePageKind == PageKind::Handout) { bHandoutMode = true; pHandoutMPage = pDocument->GetMasterSdPage(0, PageKind::Handout); } } else { #if HAVE_FEATURE_SCRIPTING StarBASIC::FatalError (ERRCODE_BASIC_WRONG_ARGS); #endif rRequest.Ignore (); break; } SdPage* pUndoPage = bHandoutMode ? pHandoutMPage : pCurrentPage; SfxUndoManager* pUndoManager = mrViewShell.GetDocSh()->GetUndoManager(); DBG_ASSERT(pUndoManager, "No UNDO MANAGER ?!?"); if( pUndoManager ) { OUString aComment( SdResId(STR_UNDO_MODIFY_PAGE) ); pUndoManager->EnterListAction(aComment, aComment, 0, mrViewShell.GetViewShellBase().GetViewShellId()); pUndoManager->AddUndoAction( std::make_unique( pDocument, pUndoPage, aNewName, aNewAutoLayout, bBVisible, bBObjsVisible)); // Clear the selection because the selected object may be removed as // a result of the assignment of the layout. mrViewShell.GetDrawView()->UnmarkAll(); if (!bHandoutMode) { if (pCurrentPage->GetName() != aNewName) { pCurrentPage->SetName(aNewName); if (ePageKind == PageKind::Standard) { sal_uInt16 nPage = (pCurrentPage->GetPageNum()-1) / 2; SdPage* pNotesPage = pDocument->GetSdPage(nPage, PageKind::Notes); if (pNotesPage != nullptr) pNotesPage->SetName(aNewName); } } pCurrentPage->SetAutoLayout(aNewAutoLayout, true); SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background); SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects); aVisibleLayers.Set(aBckgrnd, bBVisible); aVisibleLayers.Set(aBckgrndObj, bBObjsVisible); pCurrentPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); } else { pHandoutMPage->SetAutoLayout(aNewAutoLayout, true); } mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); bool bSetModified = true; if (pArgs->Count() == 1) { bSetModified = static_cast(pArgs->Get(SID_MODIFYPAGE)).GetValue(); } pUndoManager->AddUndoAction( std::make_unique( *pUndoPage ) ); pUndoManager->LeaveListAction(); pDocument->SetChanged(bSetModified); } } while (false); mrViewShell.Cancel(); rRequest.Done (); } void ViewShell::Implementation::AssignLayout ( SfxRequest const & rRequest, PageKind ePageKind ) { const SfxUInt32Item* pWhatPage = rRequest.GetArg(ID_VAL_WHATPAGE); const SfxUInt32Item* pWhatLayout = rRequest.GetArg(ID_VAL_WHATLAYOUT); SdDrawDocument* pDocument = mrViewShell.GetDoc(); if( !pDocument ) return; SdPage* pPage = nullptr; if( pWhatPage ) { pPage = pDocument->GetSdPage(static_cast(pWhatPage->GetValue()), ePageKind); } if( pPage == nullptr ) pPage = mrViewShell.getCurrentPage(); if( !pPage ) return; 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()); SdrLayerID aBackground (rLayerAdmin.GetLayerID(sUNO_LayerName_background)); SdrLayerID aBackgroundObject (rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects)); SdrLayerIDSet aVisibleLayers; if( pPage->GetPageKind() == PageKind::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()); } SfxInterfaceId ViewShell::Implementation::GetViewId() const { 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_NOTESPANEL: case ViewShell::ST_SIDEBAR: case ViewShell::ST_NONE: default: return IMPRESS_FACTORY_ID; } } SvxIMapDlg* ViewShell::Implementation::GetImageMapDialog() { SfxViewFrame* pViewFrm = SfxViewFrame::Current(); if (!pViewFrm) return nullptr; SfxChildWindow* pChildWindow = pViewFrm->GetChildWindow( SvxIMapDlgChildWindow::GetChildWindowId()); if (pChildWindow == nullptr) return nullptr; return dynamic_cast(pChildWindow->GetController().get()); } //===== ToolBarManagerLock ==================================================== class ViewShell::Implementation::ToolBarManagerLock::Deleter { public: void operator() (ToolBarManagerLock* pObject) { delete pObject; } }; std::shared_ptr ViewShell::Implementation::ToolBarManagerLock::Create ( const std::shared_ptr& rpManager) { std::shared_ptr pLock ( new ViewShell::Implementation::ToolBarManagerLock(rpManager), ViewShell::Implementation::ToolBarManagerLock::Deleter()); pLock->mpSelf = pLock; return pLock; } ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock ( const std::shared_ptr& rpManager) : mpLock(new ToolBarManager::UpdateLock(rpManager)), maTimer("sd ToolBarManagerLock maTimer") { // Start a timer that will unlock the ToolBarManager update lock when // that is not done explicitly by calling Release(). maTimer.SetInvokeHandler(LINK(this,ToolBarManagerLock,TimeoutCallback)); maTimer.SetTimeout(100); maTimer.Start(); } IMPL_LINK_NOARG(ViewShell::Implementation::ToolBarManagerLock, TimeoutCallback, Timer *, void) { // If possible then release the lock now. Otherwise start the timer // and try again later. if (Application::IsUICaptured()) { maTimer.Start(); } else { mpSelf.reset(); } } 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() { mpLock.reset(); } } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */