381 lines
13 KiB
C++
381 lines
13 KiB
C++
/* -*- 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 <config_features.h>
|
|
|
|
#include <ViewShellImplementation.hxx>
|
|
|
|
#include <sdpage.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <sdresid.hxx>
|
|
#include <unokywds.hxx>
|
|
#include <strings.hrc>
|
|
#include <app.hrc>
|
|
#include <unmodpg.hxx>
|
|
#include <DrawDocShell.hxx>
|
|
#include <FactoryIds.hxx>
|
|
#include <ViewShellBase.hxx>
|
|
|
|
#include <sfx2/bindings.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/sfxsids.hrc>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/sidebar/Sidebar.hxx>
|
|
#include <svl/intitem.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <svx/imapdlg.hxx>
|
|
#include <basic/sbstar.hxx>
|
|
#include <basic/sberrors.hxx>
|
|
#include <xmloff/autolayout.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <undo/undoobjects.hxx>
|
|
|
|
#include <com/sun/star/drawing/framework/XControllerManager.hpp>
|
|
|
|
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<ToolBarManagerLock> pLock(mpUpdateLockForMouse);
|
|
if (pLock != nullptr)
|
|
{
|
|
// Force the ToolBarManagerLock to be released even when the
|
|
// IsUICaptured() returns <TRUE/>.
|
|
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<SfxStringItem>(ID_VAL_PAGENAME);
|
|
const SfxUInt32Item* pNewAutoLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
|
|
const SfxBoolItem* pBVisible = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEBACK);
|
|
const SfxBoolItem* pBObjsVisible = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEOBJ);
|
|
assert(pNewName && pNewAutoLayout && pBVisible && pBObjsVisible && "must be present");
|
|
AutoLayout aLayout (static_cast<AutoLayout>(pNewAutoLayout->GetValue ()));
|
|
if (aLayout >= AUTOLAYOUT_START
|
|
&& aLayout < AUTOLAYOUT_END)
|
|
{
|
|
aNewName = pNewName->GetValue ();
|
|
aNewAutoLayout = static_cast<AutoLayout>(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<ModifyPageUndoAction>(
|
|
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<const SfxBoolItem&>(pArgs->Get(SID_MODIFYPAGE)).GetValue();
|
|
}
|
|
|
|
pUndoManager->AddUndoAction( std::make_unique<UndoAutoLayoutPosAndSize>( *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<SfxUInt32Item>(ID_VAL_WHATPAGE);
|
|
const SfxUInt32Item* pWhatLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
|
|
|
|
SdDrawDocument* pDocument = mrViewShell.GetDoc();
|
|
if( !pDocument )
|
|
return;
|
|
|
|
SdPage* pPage = nullptr;
|
|
if( pWhatPage )
|
|
{
|
|
pPage = pDocument->GetSdPage(static_cast<sal_uInt16>(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<SvxIMapDlg*>(pChildWindow->GetController().get());
|
|
}
|
|
|
|
//===== ToolBarManagerLock ====================================================
|
|
|
|
class ViewShell::Implementation::ToolBarManagerLock::Deleter { public:
|
|
void operator() (ToolBarManagerLock* pObject) { delete pObject; }
|
|
};
|
|
|
|
std::shared_ptr<ViewShell::Implementation::ToolBarManagerLock>
|
|
ViewShell::Implementation::ToolBarManagerLock::Create (
|
|
const std::shared_ptr<ToolBarManager>& rpManager)
|
|
{
|
|
std::shared_ptr<ToolBarManagerLock> pLock (
|
|
new ViewShell::Implementation::ToolBarManagerLock(rpManager),
|
|
ViewShell::Implementation::ToolBarManagerLock::Deleter());
|
|
pLock->mpSelf = pLock;
|
|
return pLock;
|
|
}
|
|
|
|
ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock (
|
|
const std::shared_ptr<ToolBarManager>& 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: */
|