1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <ViewShellImplementation.hxx>
25 #include <drawdoc.hxx>
26 #include <sdresid.hxx>
27 #include <unokywds.hxx>
28 #include <strings.hrc>
30 #include <unmodpg.hxx>
31 #include <DrawDocShell.hxx>
32 #include <FactoryIds.hxx>
33 #include <ViewShellBase.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/request.hxx>
38 #include <sfx2/sfxsids.hrc>
39 #include <sfx2/viewfrm.hxx>
40 #include <sfx2/sidebar/Sidebar.hxx>
41 #include <svl/intitem.hxx>
42 #include <svl/stritem.hxx>
43 #include <svx/imapdlg.hxx>
44 #include <basic/sbstar.hxx>
45 #include <basic/sberrors.hxx>
46 #include <xmloff/autolayout.hxx>
47 #include <vcl/svapp.hxx>
49 #include <undo/undoobjects.hxx>
51 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
55 ViewShell::Implementation::Implementation (ViewShell
& rViewShell
)
56 : mbIsMainViewShell(false),
57 mbIsInitialized(false),
58 mbArrangeActive(false),
59 mrViewShell(rViewShell
)
63 ViewShell::Implementation::~Implementation() COVERITY_NOEXCEPT_FALSE
65 if ( ! mpUpdateLockForMouse
.expired())
67 std::shared_ptr
<ToolBarManagerLock
> pLock(mpUpdateLockForMouse
);
70 // Force the ToolBarManagerLock to be released even when the
71 // IsUICaptured() returns <TRUE/>.
77 void ViewShell::Implementation::ProcessModifyPageSlot (
82 SdDrawDocument
* pDocument
= mrViewShell
.GetDoc();
83 SdrLayerAdmin
& rLayerAdmin
= pDocument
->GetLayerAdmin();
84 SdrLayerIDSet aVisibleLayers
;
85 bool bHandoutMode
= false;
86 SdPage
* pHandoutMPage
= nullptr;
89 AutoLayout aNewAutoLayout
;
93 const SfxItemSet
* pArgs
= rRequest
.GetArgs();
95 if (pCurrentPage
!= nullptr && pCurrentPage
->TRG_HasMasterPage())
96 aVisibleLayers
= pCurrentPage
->TRG_GetMasterPageVisibleLayers();
98 aVisibleLayers
.SetAll();
102 if (pCurrentPage
== nullptr)
105 if (!pArgs
|| pArgs
->Count() == 1 || pArgs
->Count() == 2 )
107 // First make sure that the sidebar is visible
108 mrViewShell
.GetDrawView()->SdrEndTextEdit();
109 mrViewShell
.GetDrawView()->UnmarkAll();
110 if (SfxViewFrame
* pViewFrame
= mrViewShell
.GetViewFrame())
112 pViewFrame
->ShowChildWindow(SID_SIDEBAR
);
113 sfx2::sidebar::Sidebar::TogglePanel(
115 pViewFrame
->GetFrame().GetFrameInterface());
119 else if (pArgs
->Count() == 4)
121 const SfxStringItem
* pNewName
= rRequest
.GetArg
<SfxStringItem
>(ID_VAL_PAGENAME
);
122 const SfxUInt32Item
* pNewAutoLayout
= rRequest
.GetArg
<SfxUInt32Item
>(ID_VAL_WHATLAYOUT
);
123 const SfxBoolItem
* pBVisible
= rRequest
.GetArg
<SfxBoolItem
>(ID_VAL_ISPAGEBACK
);
124 const SfxBoolItem
* pBObjsVisible
= rRequest
.GetArg
<SfxBoolItem
>(ID_VAL_ISPAGEOBJ
);
125 assert(pNewName
&& pNewAutoLayout
&& pBVisible
&& pBObjsVisible
&& "must be present");
126 AutoLayout
aLayout (static_cast<AutoLayout
>(pNewAutoLayout
->GetValue ()));
127 if (aLayout
>= AUTOLAYOUT_START
128 && aLayout
< AUTOLAYOUT_END
)
130 aNewName
= pNewName
->GetValue ();
131 aNewAutoLayout
= static_cast<AutoLayout
>(pNewAutoLayout
->GetValue ());
132 bBVisible
= pBVisible
->GetValue ();
133 bBObjsVisible
= pBObjsVisible
->GetValue ();
137 #if HAVE_FEATURE_SCRIPTING
138 StarBASIC::FatalError (ERRCODE_BASIC_BAD_PROP_VALUE
);
143 if (ePageKind
== PageKind::Handout
)
146 pHandoutMPage
= pDocument
->GetMasterSdPage(0, PageKind::Handout
);
151 #if HAVE_FEATURE_SCRIPTING
152 StarBASIC::FatalError (ERRCODE_BASIC_WRONG_ARGS
);
159 bHandoutMode
? pHandoutMPage
: pCurrentPage
;
161 SfxUndoManager
* pUndoManager
= mrViewShell
.GetDocSh()->GetUndoManager();
162 DBG_ASSERT(pUndoManager
, "No UNDO MANAGER ?!?");
166 OUString
aComment( SdResId(STR_UNDO_MODIFY_PAGE
) );
167 pUndoManager
->EnterListAction(aComment
, aComment
, 0, mrViewShell
.GetViewShellBase().GetViewShellId());
168 pUndoManager
->AddUndoAction(
169 std::make_unique
<ModifyPageUndoAction
>(
170 pDocument
, pUndoPage
, aNewName
, aNewAutoLayout
, bBVisible
, bBObjsVisible
));
172 // Clear the selection because the selected object may be removed as
173 // a result of the assignment of the layout.
174 mrViewShell
.GetDrawView()->UnmarkAll();
178 if (pCurrentPage
->GetName() != aNewName
)
180 pCurrentPage
->SetName(aNewName
);
182 if (ePageKind
== PageKind::Standard
)
184 sal_uInt16 nPage
= (pCurrentPage
->GetPageNum()-1) / 2;
185 SdPage
* pNotesPage
= pDocument
->GetSdPage(nPage
, PageKind::Notes
);
186 if (pNotesPage
!= nullptr)
187 pNotesPage
->SetName(aNewName
);
191 pCurrentPage
->SetAutoLayout(aNewAutoLayout
, true);
193 SdrLayerID aBckgrnd
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background
);
194 SdrLayerID aBckgrndObj
= rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
);
195 aVisibleLayers
.Set(aBckgrnd
, bBVisible
);
196 aVisibleLayers
.Set(aBckgrndObj
, bBObjsVisible
);
197 pCurrentPage
->TRG_SetMasterPageVisibleLayers(aVisibleLayers
);
201 pHandoutMPage
->SetAutoLayout(aNewAutoLayout
, true);
204 mrViewShell
.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE
,
205 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
207 bool bSetModified
= true;
209 if (pArgs
->Count() == 1)
211 bSetModified
= static_cast<const SfxBoolItem
&>(pArgs
->Get(SID_MODIFYPAGE
)).GetValue();
214 pUndoManager
->AddUndoAction( std::make_unique
<UndoAutoLayoutPosAndSize
>( *pUndoPage
) );
215 pUndoManager
->LeaveListAction();
217 pDocument
->SetChanged(bSetModified
);
222 mrViewShell
.Cancel();
226 void ViewShell::Implementation::AssignLayout ( SfxRequest
const & rRequest
, PageKind ePageKind
)
228 const SfxUInt32Item
* pWhatPage
= rRequest
.GetArg
<SfxUInt32Item
>(ID_VAL_WHATPAGE
);
229 const SfxUInt32Item
* pWhatLayout
= rRequest
.GetArg
<SfxUInt32Item
>(ID_VAL_WHATLAYOUT
);
231 SdDrawDocument
* pDocument
= mrViewShell
.GetDoc();
235 SdPage
* pPage
= nullptr;
238 pPage
= pDocument
->GetSdPage(static_cast<sal_uInt16
>(pWhatPage
->GetValue()), ePageKind
);
241 if( pPage
== nullptr )
242 pPage
= mrViewShell
.getCurrentPage();
247 AutoLayout eLayout
= pPage
->GetAutoLayout();
250 eLayout
= static_cast< AutoLayout
>( pWhatLayout
->GetValue() );
252 // Transform the given request into the four argument form that is
253 // understood by ProcessModifyPageSlot().
254 SdrLayerAdmin
& rLayerAdmin (mrViewShell
.GetViewShellBase().GetDocument()->GetLayerAdmin());
255 SdrLayerID
aBackground (rLayerAdmin
.GetLayerID(sUNO_LayerName_background
));
256 SdrLayerID
aBackgroundObject (rLayerAdmin
.GetLayerID(sUNO_LayerName_background_objects
));
258 SdrLayerIDSet aVisibleLayers
;
260 if( pPage
->GetPageKind() == PageKind::Handout
)
261 aVisibleLayers
.SetAll();
263 aVisibleLayers
= pPage
->TRG_GetMasterPageVisibleLayers();
265 SfxRequest
aRequest(mrViewShell
.GetViewShellBase().GetViewFrame(), SID_MODIFYPAGE
);
266 aRequest
.AppendItem(SfxStringItem (ID_VAL_PAGENAME
, pPage
->GetName()));
267 aRequest
.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT
, eLayout
));
268 aRequest
.AppendItem(SfxBoolItem(ID_VAL_ISPAGEBACK
, aVisibleLayers
.IsSet(aBackground
)));
269 aRequest
.AppendItem(SfxBoolItem(ID_VAL_ISPAGEOBJ
, aVisibleLayers
.IsSet(aBackgroundObject
)));
271 // Forward the call with the new arguments.
272 ProcessModifyPageSlot( aRequest
, pPage
, pPage
->GetPageKind());
275 SfxInterfaceId
ViewShell::Implementation::GetViewId() const
277 switch (mrViewShell
.GetShellType())
279 case ViewShell::ST_IMPRESS
:
280 case ViewShell::ST_NOTES
:
281 case ViewShell::ST_HANDOUT
:
282 return IMPRESS_FACTORY_ID
;
284 case ViewShell::ST_DRAW
:
285 return DRAW_FACTORY_ID
;
287 case ViewShell::ST_OUTLINE
:
288 return OUTLINE_FACTORY_ID
;
290 case ViewShell::ST_SLIDE_SORTER
:
291 return SLIDE_SORTER_FACTORY_ID
;
293 case ViewShell::ST_PRESENTATION
:
294 return PRESENTATION_FACTORY_ID
;
296 // Since we have to return a view id for every possible shell type
297 // and there is not (yet) a proper ViewShellBase sub class for the
298 // remaining types we chose the Impress factory as a fall back.
299 case ViewShell::ST_NOTESPANEL
:
300 case ViewShell::ST_SIDEBAR
:
301 case ViewShell::ST_NONE
:
303 return IMPRESS_FACTORY_ID
;
307 SvxIMapDlg
* ViewShell::Implementation::GetImageMapDialog()
309 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
313 SfxChildWindow
* pChildWindow
= pViewFrm
->GetChildWindow(
314 SvxIMapDlgChildWindow::GetChildWindowId());
315 if (pChildWindow
== nullptr)
318 return dynamic_cast<SvxIMapDlg
*>(pChildWindow
->GetController().get());
321 //===== ToolBarManagerLock ====================================================
323 class ViewShell::Implementation::ToolBarManagerLock::Deleter
{ public:
324 void operator() (ToolBarManagerLock
* pObject
) { delete pObject
; }
327 std::shared_ptr
<ViewShell::Implementation::ToolBarManagerLock
>
328 ViewShell::Implementation::ToolBarManagerLock::Create (
329 const std::shared_ptr
<ToolBarManager
>& rpManager
)
331 std::shared_ptr
<ToolBarManagerLock
> pLock (
332 new ViewShell::Implementation::ToolBarManagerLock(rpManager
),
333 ViewShell::Implementation::ToolBarManagerLock::Deleter());
334 pLock
->mpSelf
= pLock
;
338 ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock (
339 const std::shared_ptr
<ToolBarManager
>& rpManager
)
340 : mpLock(new ToolBarManager::UpdateLock(rpManager
)),
341 maTimer("sd ToolBarManagerLock maTimer")
343 // Start a timer that will unlock the ToolBarManager update lock when
344 // that is not done explicitly by calling Release().
345 maTimer
.SetInvokeHandler(LINK(this,ToolBarManagerLock
,TimeoutCallback
));
346 maTimer
.SetTimeout(100);
350 IMPL_LINK_NOARG(ViewShell::Implementation::ToolBarManagerLock
, TimeoutCallback
, Timer
*, void)
352 // If possible then release the lock now. Otherwise start the timer
353 // and try again later.
354 if (Application::IsUICaptured())
364 void ViewShell::Implementation::ToolBarManagerLock::Release (bool bForce
)
366 // If possible then release the lock now. Otherwise try again when the
368 if (bForce
|| ! Application::IsUICaptured())
374 ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock()
379 } // end of namespace sd
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */