tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / sd / source / ui / view / viewshe3.cxx
blob45b6e99cb0913210822c0cd1d61adbe4c26ca102
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 const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
70 if( rMarkList.GetMarkCount() != 0 )
72 SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet();
73 if( pStyleSheet )
75 if (pStyleSheet->GetFamily() == SfxStyleFamily::Page)
76 pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet();
78 if( pStyleSheet )
80 GetDocSh()->SetStyleFamily(pStyleSheet->GetFamily());
85 rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, static_cast<sal_uInt16>(nFamily)));
88 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETUNDOSTRINGS))
90 ImpGetUndoStrings(rSet);
93 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETREDOSTRINGS))
95 ImpGetRedoStrings(rSet);
98 if(SfxItemState::DEFAULT == rSet.GetItemState(SID_UNDO))
100 SfxUndoManager* pUndoManager = ImpGetUndoManager();
101 if(pUndoManager)
103 if(pUndoManager->GetUndoActionCount() != 0)
105 // If another view created the first undo action, prevent redoing it from this view.
106 const SfxUndoAction* pAction = pUndoManager->GetUndoAction();
107 if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId())
109 rSet.Put(SfxUInt32Item(SID_UNDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
111 else
113 // Set the necessary string like in
114 // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1072 ff.
115 OUString aTmp = SvtResId(STR_UNDO) +
116 pUndoManager->GetUndoActionComment();
117 rSet.Put(SfxStringItem(SID_UNDO, aTmp));
120 else
122 rSet.DisableItem(SID_UNDO);
127 if(SfxItemState::DEFAULT != rSet.GetItemState(SID_REDO))
128 return;
130 SfxUndoManager* pUndoManager = ImpGetUndoManager();
131 if(!pUndoManager)
132 return;
134 if(pUndoManager->GetRedoActionCount() != 0)
136 // If another view created the first undo action, prevent redoing it from this view.
137 const SfxUndoAction* pAction = pUndoManager->GetRedoAction();
138 if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId())
140 rSet.Put(SfxUInt32Item(SID_REDO, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)));
142 else
144 // Set the necessary string like in
145 // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1081 ff.
146 OUString aTmp = SvtResId(STR_REDO) + pUndoManager->GetRedoActionComment();
147 rSet.Put(SfxStringItem(SID_REDO, aTmp));
150 else
152 rSet.DisableItem(SID_REDO);
156 /** This method consists basically of three parts:
157 1. Process the arguments of the SFX request.
158 2. Use the model to create a new page or duplicate an existing one.
159 3. Update the tab control and switch to the new page.
161 SdPage* ViewShell::CreateOrDuplicatePage (
162 SfxRequest& rRequest,
163 PageKind ePageKind,
164 SdPage* pPage,
165 const sal_Int32 nInsertPosition)
167 sal_uInt16 nSId = rRequest.GetSlot();
168 SdDrawDocument* pDocument = GetDoc();
169 SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
170 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
171 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
172 SdrLayerIDSet aVisibleLayers;
173 // Determine the page from which to copy some values, such as layers,
174 // size, master page, to the new page. This is usually the given page.
175 // When the given page is NULL then use the first page of the document.
176 SdPage* pTemplatePage = pPage;
177 if (pTemplatePage == nullptr)
178 pTemplatePage = pDocument->GetSdPage(0, ePageKind);
179 if (pTemplatePage != nullptr && pTemplatePage->TRG_HasMasterPage())
180 aVisibleLayers = pTemplatePage->TRG_GetMasterPageVisibleLayers();
181 else
182 aVisibleLayers.SetAll();
184 OUString aStandardPageName;
185 OUString aNotesPageName;
186 AutoLayout eStandardLayout (AUTOLAYOUT_NONE);
187 AutoLayout eNotesLayout (AUTOLAYOUT_NOTES);
188 bool bIsPageBack = aVisibleLayers.IsSet(aBckgrnd);
189 bool bIsPageObj = aVisibleLayers.IsSet(aBckgrndObj);
191 // 1. Process the arguments.
192 const SfxItemSet* pArgs = rRequest.GetArgs();
193 const SfxUInt16Item* pInsertPos = rRequest.GetArg<SfxUInt16Item>(ID_INSERT_POS);
195 if (! pArgs || (pArgs->Count() == 1 && pInsertPos))
197 // AutoLayouts must be ready
198 pDocument->StopWorkStartupDelay();
200 // Use the layouts of the previous page and notes page as template.
201 if (pTemplatePage != nullptr)
203 eStandardLayout = pTemplatePage->GetAutoLayout();
204 if( eStandardLayout == AUTOLAYOUT_TITLE )
205 eStandardLayout = AUTOLAYOUT_TITLE_CONTENT;
207 SdPage* pNotesTemplatePage = static_cast<SdPage*>(pDocument->GetPage(pTemplatePage->GetPageNum()+1));
208 if (pNotesTemplatePage != nullptr)
209 eNotesLayout = pNotesTemplatePage->GetAutoLayout();
212 else if (pArgs->Count() == 1 || pArgs->Count() == 2)
214 pDocument->StopWorkStartupDelay();
215 const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
216 if( pLayout )
218 if (ePageKind == PageKind::Notes)
220 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
222 else
224 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
228 else if (pArgs->Count() == 4 || pArgs->Count() == 5)
230 // AutoLayouts must be ready
231 pDocument->StopWorkStartupDelay();
233 const SfxStringItem* pPageName = rRequest.GetArg<SfxStringItem>(ID_VAL_PAGENAME);
234 const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT);
235 const SfxBoolItem* pIsPageBack = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEBACK);
236 const SfxBoolItem* pIsPageObj = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEOBJ);
237 assert(pPageName && pLayout && pIsPageBack && pIsPageObj && "must be present");
239 if (CHECK_RANGE (AUTOLAYOUT_START, static_cast<AutoLayout>(pLayout->GetValue ()), AUTOLAYOUT_END))
241 if (ePageKind == PageKind::Notes)
243 aNotesPageName = pPageName->GetValue ();
244 eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ());
246 else
248 aStandardPageName = pPageName->GetValue ();
249 eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ());
252 bIsPageBack = pIsPageBack->GetValue ();
253 bIsPageObj = pIsPageObj->GetValue ();
255 else
257 Cancel();
259 if(HasCurrentFunction( SID_BEZIER_EDIT ) )
260 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
261 #if HAVE_FEATURE_SCRIPTING
262 StarBASIC::FatalError (ERRCODE_BASIC_BAD_PROP_VALUE);
263 #endif
264 rRequest.Ignore ();
265 return nullptr;
268 else
270 Cancel();
272 if(HasCurrentFunction(SID_BEZIER_EDIT) )
273 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
274 #if HAVE_FEATURE_SCRIPTING
275 StarBASIC::FatalError (ERRCODE_BASIC_WRONG_ARGS);
276 #endif
277 rRequest.Ignore ();
278 return nullptr;
281 // 2. Create a new page or duplicate an existing one.
282 View* pDrView = GetView();
283 const bool bUndo = pDrView && pDrView->IsUndoEnabled();
284 if( bUndo && GetDoc()->GetDocumentType() == DocumentType::Draw)
285 pDrView->BegUndo(SdResId(STR_INSERT_PAGE_DRAW));
286 else if (bUndo)
287 pDrView->BegUndo(SdResId(STR_INSERTPAGE));
291 sal_uInt16 nNewPageIndex = 0xffff;
292 switch (nSId)
294 case SID_INSERTPAGE:
295 case SID_INSERTPAGE_QUICK:
296 case SID_INSERT_MASTER_PAGE:
297 // There are three cases. a) pPage is not NULL: we use it as a
298 // template and create a new slide behind it. b) pPage is NULL
299 // but the document is not empty: we use the first slide/notes
300 // page as template, create a new slide after it and move it
301 // then to the head of the document. c) pPage is NULL and the
302 // document is empty: We use CreateFirstPages to create the
303 // first page of the document.
304 if (pPage == nullptr)
305 if (pTemplatePage == nullptr)
307 pDocument->CreateFirstPages();
308 nNewPageIndex = 0;
310 else
312 // Create a new page with the first page as template and
313 // insert it after the first page.
314 nNewPageIndex = pDocument->CreatePage (
315 pTemplatePage,
316 ePageKind,
317 aStandardPageName,
318 aNotesPageName,
319 eStandardLayout,
320 eNotesLayout,
321 bIsPageBack,
322 bIsPageObj,
323 nInsertPosition);
324 // Select exactly the new page.
325 sal_uInt16 nPageCount (pDocument->GetSdPageCount(ePageKind));
326 for (sal_uInt16 i=0; i<nPageCount; i++)
328 pDocument->GetSdPage(i, PageKind::Standard)->SetSelected(
329 i == nNewPageIndex);
330 pDocument->GetSdPage(i, PageKind::Notes)->SetSelected(
331 i == nNewPageIndex);
333 // Move the selected page to the head of the document
334 pDocument->MovePages (sal_uInt16(-1));
335 nNewPageIndex = 0;
337 else
338 nNewPageIndex = pDocument->CreatePage (
339 pPage,
340 ePageKind,
341 aStandardPageName,
342 aNotesPageName,
343 eStandardLayout,
344 eNotesLayout,
345 bIsPageBack,
346 bIsPageObj,
347 pInsertPos ? (pInsertPos->GetValue()*2)+1 : nInsertPosition);
348 break;
350 case SID_DUPLICATE_PAGE:
351 // Duplication makes no sense when pPage is NULL.
352 if (pPage != nullptr)
353 nNewPageIndex = pDocument->DuplicatePage (
354 pPage,
355 ePageKind,
356 aStandardPageName,
357 aNotesPageName,
358 bIsPageBack,
359 bIsPageObj,
360 pInsertPos ? (pInsertPos->GetValue()*2)+1 : nInsertPosition);
361 break;
363 default:
364 SAL_INFO("sd", "wrong slot id given to CreateOrDuplicatePage");
365 // Try to handle another slot id gracefully.
367 SdPage* pNewPage = nullptr;
368 if(nNewPageIndex != 0xffff)
369 pNewPage = pDocument->GetSdPage(nNewPageIndex, PageKind::Standard);
371 if( bUndo )
373 if( pNewPage )
375 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pNewPage));
376 pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pDocument->GetSdPage (nNewPageIndex, PageKind::Notes)));
379 pDrView->EndUndo();
382 return pNewPage;
385 } // end of namespace sd
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */