LibreOffice Module sd (master) 1
viewshe3.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_features.h>
21
22#include <ViewShell.hxx>
23#include <ViewShellBase.hxx>
24
25#include <sfx2/viewfrm.hxx>
26#include <svtools/strings.hrc>
27#include <svtools/svtresid.hxx>
28
29#include <app.hrc>
30#include <strings.hrc>
31
32#include <sal/log.hxx>
33#include <sfx2/dispatch.hxx>
34#include <sfx2/bindings.hxx>
35#include <svx/svdundo.hxx>
36#include <svl/intitem.hxx>
37#include <svl/style.hxx>
38#include <svl/stritem.hxx>
39#include <stlsheet.hxx>
40#include <DrawViewShell.hxx>
41
42#include <drawdoc.hxx>
43#include <sdpage.hxx>
44#include <DrawDocShell.hxx>
45#include <sdresid.hxx>
46#include <unokywds.hxx>
47
48#include <svx/svxids.hrc>
49#include <sfx2/request.hxx>
50#include <basic/sbstar.hxx>
51#include <basic/sberrors.hxx>
52#include <xmloff/autolayout.hxx>
53
54using namespace ::com::sun::star;
55
56namespace sd {
57
62{
63 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STYLE_FAMILY ) )
64 {
65 SfxStyleFamily const nFamily = GetDocSh()->GetStyleFamily();
66
67 SdrView* pDrView = GetDrawView();
68
69 if( pDrView->AreObjectsMarked() )
70 {
71 SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet();
72 if( pStyleSheet )
73 {
74 if (pStyleSheet->GetFamily() == SfxStyleFamily::Page)
75 pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet();
76
77 if( pStyleSheet )
78 {
79 GetDocSh()->SetStyleFamily(pStyleSheet->GetFamily());
80 }
81 }
82 }
83
84 rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, static_cast<sal_uInt16>(nFamily)));
85 }
86
87 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETUNDOSTRINGS))
88 {
90 }
91
92 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETREDOSTRINGS))
93 {
95 }
96
97 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_UNDO))
98 {
99 SfxUndoManager* pUndoManager = ImpGetUndoManager();
100 if(pUndoManager)
101 {
102 if(pUndoManager->GetUndoActionCount() != 0)
103 {
104 // If another view created the first undo action, prevent redoing it from this view.
105 const SfxUndoAction* pAction = pUndoManager->GetUndoAction();
106 if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId())
107 {
108 rSet.Put(SfxUInt32Item(SID_UNDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
109 }
110 else
111 {
112 // Set the necessary string like in
113 // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1072 ff.
114 OUString aTmp = SvtResId(STR_UNDO) +
115 pUndoManager->GetUndoActionComment();
116 rSet.Put(SfxStringItem(SID_UNDO, aTmp));
117 }
118 }
119 else
120 {
121 rSet.DisableItem(SID_UNDO);
122 }
123 }
124 }
125
126 if(SfxItemState::DEFAULT != rSet.GetItemState(SID_REDO))
127 return;
128
129 SfxUndoManager* pUndoManager = ImpGetUndoManager();
130 if(!pUndoManager)
131 return;
132
133 if(pUndoManager->GetRedoActionCount() != 0)
134 {
135 // If another view created the first undo action, prevent redoing it from this view.
136 const SfxUndoAction* pAction = pUndoManager->GetRedoAction();
137 if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId())
138 {
139 rSet.Put(SfxUInt32Item(SID_REDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
140 }
141 else
142 {
143 // Set the necessary string like in
144 // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1081 ff.
145 OUString aTmp = SvtResId(STR_REDO) + pUndoManager->GetRedoActionComment();
146 rSet.Put(SfxStringItem(SID_REDO, aTmp));
147 }
148 }
149 else
150 {
151 rSet.DisableItem(SID_REDO);
152 }
153}
154
161 SfxRequest& rRequest,
162 PageKind ePageKind,
163 SdPage* pPage,
164 const sal_Int32 nInsertPosition)
165{
166 sal_uInt16 nSId = rRequest.GetSlot();
167 SdDrawDocument* pDocument = GetDoc();
168 SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
169 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
171 SdrLayerIDSet aVisibleLayers;
172 // Determine the page from which to copy some values, such as layers,
173 // size, master page, to the new page. This is usually the given page.
174 // When the given page is NULL then use the first page of the document.
175 SdPage* pTemplatePage = pPage;
176 if (pTemplatePage == nullptr)
177 pTemplatePage = pDocument->GetSdPage(0, ePageKind);
178 if (pTemplatePage != nullptr && pTemplatePage->TRG_HasMasterPage())
179 aVisibleLayers = pTemplatePage->TRG_GetMasterPageVisibleLayers();
180 else
181 aVisibleLayers.SetAll();
182
183 OUString aStandardPageName;
184 OUString aNotesPageName;
185 AutoLayout eStandardLayout (AUTOLAYOUT_NONE);
186 AutoLayout eNotesLayout (AUTOLAYOUT_NOTES);
187 bool bIsPageBack = aVisibleLayers.IsSet(aBckgrnd);
188 bool bIsPageObj = aVisibleLayers.IsSet(aBckgrndObj);
189
190 // 1. Process the arguments.
191 const SfxItemSet* pArgs = rRequest.GetArgs();
192 const SfxUInt16Item* pInsertPos = rRequest.GetArg<SfxUInt16Item>(ID_INSERT_POS);
193
194 if (! pArgs || (pArgs->Count() == 1 && pInsertPos))
195 {
196 // AutoLayouts must be ready
197 pDocument->StopWorkStartupDelay();
198
199 // Use the layouts of the previous page and notes page as template.
200 if (pTemplatePage != nullptr)
201 {
202 eStandardLayout = pTemplatePage->GetAutoLayout();
203 if( eStandardLayout == AUTOLAYOUT_TITLE )
204 eStandardLayout = AUTOLAYOUT_TITLE_CONTENT;
205
206 SdPage* pNotesTemplatePage = static_cast<SdPage*>(pDocument->GetPage(pTemplatePage->GetPageNum()+1));
207 if (pNotesTemplatePage != nullptr)
208 eNotesLayout = pNotesTemplatePage->GetAutoLayout();
209 }
210 }
211 else if (pArgs->Count() == 1 || pArgs->Count() == 2)
212 {
213 pDocument->StopWorkStartupDelay();
214 const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
215 if( pLayout )
216 {
217 if (ePageKind == PageKind::Notes)
218 {
219 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
220 }
221 else
222 {
223 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
224 }
225 }
226 }
227 else if (pArgs->Count() == 4 || pArgs->Count() == 5)
228 {
229 // AutoLayouts must be ready
230 pDocument->StopWorkStartupDelay();
231
232 const SfxStringItem* pPageName = rRequest.GetArg<SfxStringItem>(ID_VAL_PAGENAME);
233 const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
234 const SfxBoolItem* pIsPageBack = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEBACK);
235 const SfxBoolItem* pIsPageObj = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEOBJ);
236 assert(pPageName && pLayout && pIsPageBack && pIsPageObj && "must be present");
237
238 if (CHECK_RANGE (AUTOLAYOUT_START, static_cast<AutoLayout>(pLayout->GetValue ()), AUTOLAYOUT_END))
239 {
240 if (ePageKind == PageKind::Notes)
241 {
242 aNotesPageName = pPageName->GetValue ();
243 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
244 }
245 else
246 {
247 aStandardPageName = pPageName->GetValue ();
248 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
249 }
250
251 bIsPageBack = pIsPageBack->GetValue ();
252 bIsPageObj = pIsPageObj->GetValue ();
253 }
254 else
255 {
256 Cancel();
257
258 if(HasCurrentFunction( SID_BEZIER_EDIT ) )
259 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
260#if HAVE_FEATURE_SCRIPTING
262#endif
263 rRequest.Ignore ();
264 return nullptr;
265 }
266 }
267 else
268 {
269 Cancel();
270
271 if(HasCurrentFunction(SID_BEZIER_EDIT) )
272 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
273#if HAVE_FEATURE_SCRIPTING
275#endif
276 rRequest.Ignore ();
277 return nullptr;
278 }
279
280 // 2. Create a new page or duplicate an existing one.
281 View* pDrView = GetView();
282 const bool bUndo = pDrView && pDrView->IsUndoEnabled();
283 if( bUndo && GetDoc()->GetDocumentType() == DocumentType::Draw)
284 pDrView->BegUndo(SdResId(STR_INSERT_PAGE_DRAW));
285 else if (bUndo)
286 pDrView->BegUndo(SdResId(STR_INSERTPAGE));
287
288
289
290 sal_uInt16 nNewPageIndex = 0xffff;
291 switch (nSId)
292 {
293 case SID_INSERTPAGE:
294 case SID_INSERTPAGE_QUICK:
295 case SID_INSERT_MASTER_PAGE:
296 // There are three cases. a) pPage is not NULL: we use it as a
297 // template and create a new slide behind it. b) pPage is NULL
298 // but the document is not empty: we use the first slide/notes
299 // page as template, create a new slide after it and move it
300 // then to the head of the document. c) pPage is NULL and the
301 // document is empty: We use CreateFirstPages to create the
302 // first page of the document.
303 if (pPage == nullptr)
304 if (pTemplatePage == nullptr)
305 {
306 pDocument->CreateFirstPages();
307 nNewPageIndex = 0;
308 }
309 else
310 {
311 // Create a new page with the first page as template and
312 // insert it after the first page.
313 nNewPageIndex = pDocument->CreatePage (
314 pTemplatePage,
315 ePageKind,
316 aStandardPageName,
317 aNotesPageName,
318 eStandardLayout,
319 eNotesLayout,
320 bIsPageBack,
321 bIsPageObj,
322 nInsertPosition);
323 // Select exactly the new page.
324 sal_uInt16 nPageCount (pDocument->GetSdPageCount(ePageKind));
325 for (sal_uInt16 i=0; i<nPageCount; i++)
326 {
328 i == nNewPageIndex);
330 i == nNewPageIndex);
331 }
332 // Move the selected page to the head of the document
333 pDocument->MovePages (sal_uInt16(-1));
334 nNewPageIndex = 0;
335 }
336 else
337 nNewPageIndex = pDocument->CreatePage (
338 pPage,
339 ePageKind,
340 aStandardPageName,
341 aNotesPageName,
342 eStandardLayout,
343 eNotesLayout,
344 bIsPageBack,
345 bIsPageObj,
346 nInsertPosition);
347 break;
348
349 case SID_DUPLICATE_PAGE:
350 // Duplication makes no sense when pPage is NULL.
351 if (pPage != nullptr)
352 nNewPageIndex = pDocument->DuplicatePage (
353 pPage,
354 ePageKind,
355 aStandardPageName,
356 aNotesPageName,
357 bIsPageBack,
358 bIsPageObj,
359 pInsertPos ? (pInsertPos->GetValue()*2)+1 : nInsertPosition);
360 break;
361
362 default:
363 SAL_INFO("sd", "wrong slot id given to CreateOrDuplicatePage");
364 // Try to handle another slot id gracefully.
365 }
366 SdPage* pNewPage = nullptr;
367 if(nNewPageIndex != 0xffff)
368 pNewPage = pDocument->GetSdPage(nNewPageIndex, PageKind::Standard);
369
370 if( bUndo )
371 {
372 if( pNewPage )
373 {
374 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pNewPage));
375 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pDocument->GetSdPage (nNewPageIndex, PageKind::Notes)));
376 }
377
378 pDrView->EndUndo();
379 }
380
381 return pNewPage;
382}
383
384} // end of namespace sd
385
386/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define CHECK_RANGE(nMin, nValue, nMax)
AutoLayout
AUTOLAYOUT_TITLE
AUTOLAYOUT_START
AUTOLAYOUT_NONE
AUTOLAYOUT_END
AUTOLAYOUT_NOTES
AUTOLAYOUT_TITLE_CONTENT
sal_uInt16 GetValue() const
sal_uInt32 GetValue() const
const OUString & GetValue() const
void CreateFirstPages(SdDrawDocument const *pRefDocument=nullptr)
if the document does not contain at least one handout, one slide and one notes page with at least one...
Definition: drawdoc2.cxx:493
SAL_DLLPRIVATE sal_uInt16 DuplicatePage(sal_uInt16 nPageNum)
This method acts as a simplified front end for the more complex <member>DuplicatePage()</member> meth...
Definition: drawdoc2.cxx:1215
SdPage * GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
Definition: drawdoc2.cxx:207
void StopWorkStartupDelay()
Definition: drawdoc2.cxx:932
SAL_DLLPRIVATE bool MovePages(sal_uInt16 nTargetPage)
Definition: drawdoc2.cxx:726
SAL_DLLPRIVATE sal_uInt16 CreatePage(SdPage *pCurrentPage, PageKind ePageKind, const OUString &sStandardPageName, const OUString &sNotesPageName, AutoLayout eStandardLayout, AutoLayout eNotesLayout, bool bIsPageBack, bool bIsPageObj, const sal_Int32 nInsertPosition)
Create and insert a set of two new pages: a standard (draw) page and the associated notes page.
Definition: drawdoc2.cxx:1128
sal_uInt16 GetSdPageCount(PageKind ePgKind) const
Definition: drawdoc2.cxx:212
void SetSelected(bool bSel)
Definition: sdpage.hxx:207
AutoLayout GetAutoLayout() const
Definition: sdpage.hxx:190
SfxStyleSheet * GetStyleSheet() const
bool IsUndoEnabled() const
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
void BegUndo()
void EndUndo()
SdrLayerID GetLayerID(const OUString &rName) const
bool IsSet(SdrLayerID a) const
bool AreObjectsMarked() const
SdrUndoFactory & GetSdrUndoFactory() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
const SdrLayerAdmin & GetLayerAdmin() const
sal_uInt16 GetPageNum() const
bool TRG_HasMasterPage() const
const SdrLayerIDSet & TRG_GetMasterPageVisibleLayers() const
virtual std::unique_ptr< SdrUndoAction > CreateUndoNewPage(SdrPage &rPage)
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
sal_uInt16 Count() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void DisableItem(sal_uInt16 nWhich)
sal_uInt16 GetSlot() const
void Ignore()
const SfxItemSet * GetArgs() const
const T * GetArg(sal_uInt16 nSlotId) const
SfxStyleFamily GetFamily() const
virtual ViewShellId GetViewShellId() const
SfxUndoAction * GetRedoAction(size_t nNo=0) const
OUString GetRedoActionComment(size_t nNo=0, bool const i_currentLevel=CurrentLevel) const
OUString GetUndoActionComment(size_t nNo=0, bool const i_currentLevel=CurrentLevel) const
virtual size_t GetRedoActionCount(bool const i_currentLevel=CurrentLevel) const
virtual size_t GetUndoActionCount(bool const i_currentLevel=CurrentLevel) const
SfxUndoAction * GetUndoAction(size_t nNo=0) const
SfxDispatcher * GetDispatcher()
static void FatalError(ErrCode)
void SetStyleFamily(SfxStyleFamily nSF)
SfxStyleFamily GetStyleFamily() const
SD_DLLPUBLIC DrawDocShell * GetDocSh() const
Definition: viewshel.cxx:1407
virtual SfxUndoManager * ImpGetUndoManager() const
Definition: viewshel.cxx:1094
void ImpGetUndoStrings(SfxItemSet &rSet) const
Definition: viewshel.cxx:1129
SdDrawDocument * GetDoc() const
Definition: viewshel.cxx:1412
void GetMenuState(SfxItemSet &rSet)
set state (enabled/disabled) of Menu SfxSlots
Definition: viewshe3.cxx:61
void ImpGetRedoStrings(SfxItemSet &rSet) const
Definition: viewshel.cxx:1156
::sd::View * GetView() const
Definition: ViewShell.hxx:144
virtual SdPage * CreateOrDuplicatePage(SfxRequest &rRequest, PageKind ePageKind, SdPage *pPage, const sal_Int32 nInsertPosition=-1)
Depending on the given request create a new page or duplicate an existing one.
Definition: viewshe3.cxx:160
void Cancel()
this method deactivates the current function.
Definition: viewshel.cxx:1442
SD_DLLPUBLIC ViewShellBase & GetViewShellBase() const
Definition: viewshel.cxx:1397
SD_DLLPUBLIC SfxViewFrame * GetViewFrame() const
Definition: viewshel.cxx:118
bool HasCurrentFunction() const
Definition: ViewShell.hxx:252
SdrView * GetDrawView() const
Definition: ViewShell.hxx:552
#define SAL_INFO(area, stream)
int i
PageKind
Definition: pres.hxx:45
#define ERRCODE_BASIC_BAD_PROP_VALUE
#define ERRCODE_BASIC_WRONG_ARGS
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83
static SfxItemSet & rSet
SfxStyleFamily
SVT_DLLPUBLIC OUString SvtResId(TranslateId aId)
constexpr OUStringLiteral sUNO_LayerName_background_objects
Definition: unokywds.hxx:30
constexpr OUStringLiteral sUNO_LayerName_background
Definition: unokywds.hxx:29