android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / view / viewshe3.cxx
blobcb76eaf998448c48443951bbb8cd609c4cb64504
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <ViewShell.hxx>
23 #include <ViewShellBase.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <svtools/strings.hrc>
27 #include <svtools/svtresid.hxx>
29 #include <app.hrc>
30 #include <strings.hrc>
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>
42 #include <drawdoc.hxx>
43 #include <sdpage.hxx>
44 #include <DrawDocShell.hxx>
45 #include <sdresid.hxx>
46 #include <unokywds.hxx>
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>
54 using namespace ::com::sun::star;
56 namespace sd {
58 /**
59 * set state (enabled/disabled) of Menu SfxSlots
61 void ViewShell::GetMenuState( SfxItemSet &rSet )
63 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STYLE_FAMILY ) )
65 SfxStyleFamily const nFamily = GetDocSh()->GetStyleFamily();
67 SdrView* pDrView = GetDrawView();
69 if( pDrView->AreObjectsMarked() )
71 SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet();
72 if( pStyleSheet )
74 if (pStyleSheet->GetFamily() == SfxStyleFamily::Page)
75 pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet();
77 if( pStyleSheet )
79 GetDocSh()->SetStyleFamily(pStyleSheet->GetFamily());
84 rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, static_cast<sal_uInt16>(nFamily)));
87 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETUNDOSTRINGS))
89 ImpGetUndoStrings(rSet);
92 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETREDOSTRINGS))
94 ImpGetRedoStrings(rSet);
97 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_UNDO))
99 SfxUndoManager* pUndoManager = ImpGetUndoManager();
100 if(pUndoManager)
102 if(pUndoManager->GetUndoActionCount() != 0)
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())
108 rSet.Put(SfxUInt32Item(SID_UNDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
110 else
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));
119 else
121 rSet.DisableItem(SID_UNDO);
126 if(SfxItemState::DEFAULT != rSet.GetItemState(SID_REDO))
127 return;
129 SfxUndoManager* pUndoManager = ImpGetUndoManager();
130 if(!pUndoManager)
131 return;
133 if(pUndoManager->GetRedoActionCount() != 0)
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())
139 rSet.Put(SfxUInt32Item(SID_REDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
141 else
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));
149 else
151 rSet.DisableItem(SID_REDO);
155 /** This method consists basically of three parts:
156 1. Process the arguments of the SFX request.
157 2. Use the model to create a new page or duplicate an existing one.
158 3. Update the tab control and switch to the new page.
160 SdPage* ViewShell::CreateOrDuplicatePage (
161 SfxRequest& rRequest,
162 PageKind ePageKind,
163 SdPage* pPage,
164 const sal_Int32 nInsertPosition)
166 sal_uInt16 nSId = rRequest.GetSlot();
167 SdDrawDocument* pDocument = GetDoc();
168 SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
169 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
170 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
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();
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);
190 // 1. Process the arguments.
191 const SfxItemSet* pArgs = rRequest.GetArgs();
192 const SfxUInt16Item* pInsertPos = rRequest.GetArg<SfxUInt16Item>(ID_INSERT_POS);
194 if (! pArgs || (pArgs->Count() == 1 && pInsertPos))
196 // AutoLayouts must be ready
197 pDocument->StopWorkStartupDelay();
199 // Use the layouts of the previous page and notes page as template.
200 if (pTemplatePage != nullptr)
202 eStandardLayout = pTemplatePage->GetAutoLayout();
203 if( eStandardLayout == AUTOLAYOUT_TITLE )
204 eStandardLayout = AUTOLAYOUT_TITLE_CONTENT;
206 SdPage* pNotesTemplatePage = static_cast<SdPage*>(pDocument->GetPage(pTemplatePage->GetPageNum()+1));
207 if (pNotesTemplatePage != nullptr)
208 eNotesLayout = pNotesTemplatePage->GetAutoLayout();
211 else if (pArgs->Count() == 1 || pArgs->Count() == 2)
213 pDocument->StopWorkStartupDelay();
214 const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
215 if( pLayout )
217 if (ePageKind == PageKind::Notes)
219 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
221 else
223 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
227 else if (pArgs->Count() == 4 || pArgs->Count() == 5)
229 // AutoLayouts must be ready
230 pDocument->StopWorkStartupDelay();
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");
238 if (CHECK_RANGE (AUTOLAYOUT_START, static_cast<AutoLayout>(pLayout->GetValue ()), AUTOLAYOUT_END))
240 if (ePageKind == PageKind::Notes)
242 aNotesPageName = pPageName->GetValue ();
243 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
245 else
247 aStandardPageName = pPageName->GetValue ();
248 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
251 bIsPageBack = pIsPageBack->GetValue ();
252 bIsPageObj = pIsPageObj->GetValue ();
254 else
256 Cancel();
258 if(HasCurrentFunction( SID_BEZIER_EDIT ) )
259 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
260 #if HAVE_FEATURE_SCRIPTING
261 StarBASIC::FatalError (ERRCODE_BASIC_BAD_PROP_VALUE);
262 #endif
263 rRequest.Ignore ();
264 return nullptr;
267 else
269 Cancel();
271 if(HasCurrentFunction(SID_BEZIER_EDIT) )
272 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
273 #if HAVE_FEATURE_SCRIPTING
274 StarBASIC::FatalError (ERRCODE_BASIC_WRONG_ARGS);
275 #endif
276 rRequest.Ignore ();
277 return nullptr;
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));
290 sal_uInt16 nNewPageIndex = 0xffff;
291 switch (nSId)
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)
306 pDocument->CreateFirstPages();
307 nNewPageIndex = 0;
309 else
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++)
327 pDocument->GetSdPage(i, PageKind::Standard)->SetSelected(
328 i == nNewPageIndex);
329 pDocument->GetSdPage(i, PageKind::Notes)->SetSelected(
330 i == nNewPageIndex);
332 // Move the selected page to the head of the document
333 pDocument->MovePages (sal_uInt16(-1));
334 nNewPageIndex = 0;
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;
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;
362 default:
363 SAL_INFO("sd", "wrong slot id given to CreateOrDuplicatePage");
364 // Try to handle another slot id gracefully.
366 SdPage* pNewPage = nullptr;
367 if(nNewPageIndex != 0xffff)
368 pNewPage = pDocument->GetSdPage(nNewPageIndex, PageKind::Standard);
370 if( bUndo )
372 if( pNewPage )
374 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pNewPage));
375 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pDocument->GetSdPage (nNewPageIndex, PageKind::Notes)));
378 pDrView->EndUndo();
381 return pNewPage;
384 } // end of namespace sd
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */