/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; namespace sd { /** * set state (enabled/disabled) of Menu SfxSlots */ void ViewShell::GetMenuState( SfxItemSet &rSet ) { if( SfxItemState::DEFAULT == rSet.GetItemState( SID_STYLE_FAMILY ) ) { SfxStyleFamily const nFamily = GetDocSh()->GetStyleFamily(); SdrView* pDrView = GetDrawView(); const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList(); if( rMarkList.GetMarkCount() != 0 ) { SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet(); if( pStyleSheet ) { if (pStyleSheet->GetFamily() == SfxStyleFamily::Page) pStyleSheet = static_cast(pStyleSheet)->GetPseudoStyleSheet(); if( pStyleSheet ) { GetDocSh()->SetStyleFamily(pStyleSheet->GetFamily()); } } } rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, static_cast(nFamily))); } if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETUNDOSTRINGS)) { ImpGetUndoStrings(rSet); } if(SfxItemState::DEFAULT == rSet.GetItemState(SID_GETREDOSTRINGS)) { ImpGetRedoStrings(rSet); } if(SfxItemState::DEFAULT == rSet.GetItemState(SID_UNDO)) { SfxUndoManager* pUndoManager = ImpGetUndoManager(); if(pUndoManager) { if(pUndoManager->GetUndoActionCount() != 0) { // If another view created the first undo action, prevent redoing it from this view. const SfxUndoAction* pAction = pUndoManager->GetUndoAction(); if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId()) { rSet.Put(SfxUInt32Item(SID_UNDO, static_cast(SID_REPAIRPACKAGE))); } else { // Set the necessary string like in // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1072 ff. OUString aTmp = SvtResId(STR_UNDO) + pUndoManager->GetUndoActionComment(); rSet.Put(SfxStringItem(SID_UNDO, aTmp)); } } else { rSet.DisableItem(SID_UNDO); } } } if(SfxItemState::DEFAULT != rSet.GetItemState(SID_REDO)) return; SfxUndoManager* pUndoManager = ImpGetUndoManager(); if(!pUndoManager) return; if(pUndoManager->GetRedoActionCount() != 0) { // If another view created the first undo action, prevent redoing it from this view. const SfxUndoAction* pAction = pUndoManager->GetRedoAction(); if (pAction->GetViewShellId() != GetViewShellBase().GetViewShellId()) { rSet.Put(SfxUInt32Item(SID_REDO, static_cast(SID_REPAIRPACKAGE))); } else { // Set the necessary string like in // sfx2/source/view/viewfrm.cxx ver 1.23 ln 1081 ff. OUString aTmp = SvtResId(STR_REDO) + pUndoManager->GetRedoActionComment(); rSet.Put(SfxStringItem(SID_REDO, aTmp)); } } else { rSet.DisableItem(SID_REDO); } } /** This method consists basically of three parts: 1. Process the arguments of the SFX request. 2. Use the model to create a new page or duplicate an existing one. 3. Update the tab control and switch to the new page. */ SdPage* ViewShell::CreateOrDuplicatePage ( SfxRequest& rRequest, PageKind ePageKind, SdPage* pPage, const sal_Int32 nInsertPosition) { sal_uInt16 nSId = rRequest.GetSlot(); SdDrawDocument* pDocument = GetDoc(); SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin(); SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background); SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects); SdrLayerIDSet aVisibleLayers; // Determine the page from which to copy some values, such as layers, // size, master page, to the new page. This is usually the given page. // When the given page is NULL then use the first page of the document. SdPage* pTemplatePage = pPage; if (pTemplatePage == nullptr) pTemplatePage = pDocument->GetSdPage(0, ePageKind); if (pTemplatePage != nullptr && pTemplatePage->TRG_HasMasterPage()) aVisibleLayers = pTemplatePage->TRG_GetMasterPageVisibleLayers(); else aVisibleLayers.SetAll(); OUString aStandardPageName; OUString aNotesPageName; AutoLayout eStandardLayout (AUTOLAYOUT_NONE); AutoLayout eNotesLayout (AUTOLAYOUT_NOTES); bool bIsPageBack = aVisibleLayers.IsSet(aBckgrnd); bool bIsPageObj = aVisibleLayers.IsSet(aBckgrndObj); // 1. Process the arguments. const SfxItemSet* pArgs = rRequest.GetArgs(); const SfxUInt16Item* pInsertPos = rRequest.GetArg(ID_INSERT_POS); if (! pArgs || (pArgs->Count() == 1 && pInsertPos)) { // AutoLayouts must be ready pDocument->StopWorkStartupDelay(); // Use the layouts of the previous page and notes page as template. if (pTemplatePage != nullptr) { eStandardLayout = pTemplatePage->GetAutoLayout(); if( eStandardLayout == AUTOLAYOUT_TITLE ) eStandardLayout = AUTOLAYOUT_TITLE_CONTENT; SdPage* pNotesTemplatePage = static_cast(pDocument->GetPage(pTemplatePage->GetPageNum()+1)); if (pNotesTemplatePage != nullptr) eNotesLayout = pNotesTemplatePage->GetAutoLayout(); } } else if (pArgs->Count() == 1 || pArgs->Count() == 2) { pDocument->StopWorkStartupDelay(); const SfxUInt32Item* pLayout = rRequest.GetArg(ID_VAL_WHATLAYOUT); if( pLayout ) { if (ePageKind == PageKind::Notes) { eNotesLayout = static_cast(pLayout->GetValue ()); } else { eStandardLayout = static_cast(pLayout->GetValue ()); } } } else if (pArgs->Count() == 4 || pArgs->Count() == 5) { // AutoLayouts must be ready pDocument->StopWorkStartupDelay(); const SfxStringItem* pPageName = rRequest.GetArg(ID_VAL_PAGENAME); const SfxUInt32Item* pLayout = rRequest.GetArg(ID_VAL_WHATLAYOUT); const SfxBoolItem* pIsPageBack = rRequest.GetArg(ID_VAL_ISPAGEBACK); const SfxBoolItem* pIsPageObj = rRequest.GetArg(ID_VAL_ISPAGEOBJ); assert(pPageName && pLayout && pIsPageBack && pIsPageObj && "must be present"); if (CHECK_RANGE (AUTOLAYOUT_START, static_cast(pLayout->GetValue ()), AUTOLAYOUT_END)) { if (ePageKind == PageKind::Notes) { aNotesPageName = pPageName->GetValue (); eNotesLayout = static_cast(pLayout->GetValue ()); } else { aStandardPageName = pPageName->GetValue (); eStandardLayout = static_cast(pLayout->GetValue ()); } bIsPageBack = pIsPageBack->GetValue (); bIsPageObj = pIsPageObj->GetValue (); } else { Cancel(); if(HasCurrentFunction( SID_BEZIER_EDIT ) ) GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON); #if HAVE_FEATURE_SCRIPTING StarBASIC::FatalError (ERRCODE_BASIC_BAD_PROP_VALUE); #endif rRequest.Ignore (); return nullptr; } } else { Cancel(); if(HasCurrentFunction(SID_BEZIER_EDIT) ) GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON); #if HAVE_FEATURE_SCRIPTING StarBASIC::FatalError (ERRCODE_BASIC_WRONG_ARGS); #endif rRequest.Ignore (); return nullptr; } // 2. Create a new page or duplicate an existing one. View* pDrView = GetView(); const bool bUndo = pDrView && pDrView->IsUndoEnabled(); if( bUndo && GetDoc()->GetDocumentType() == DocumentType::Draw) pDrView->BegUndo(SdResId(STR_INSERT_PAGE_DRAW)); else if (bUndo) pDrView->BegUndo(SdResId(STR_INSERTPAGE)); sal_uInt16 nNewPageIndex = 0xffff; switch (nSId) { case SID_INSERTPAGE: case SID_INSERTPAGE_QUICK: case SID_INSERT_MASTER_PAGE: // There are three cases. a) pPage is not NULL: we use it as a // template and create a new slide behind it. b) pPage is NULL // but the document is not empty: we use the first slide/notes // page as template, create a new slide after it and move it // then to the head of the document. c) pPage is NULL and the // document is empty: We use CreateFirstPages to create the // first page of the document. if (pPage == nullptr) if (pTemplatePage == nullptr) { pDocument->CreateFirstPages(); nNewPageIndex = 0; } else { // Create a new page with the first page as template and // insert it after the first page. nNewPageIndex = pDocument->CreatePage ( pTemplatePage, ePageKind, aStandardPageName, aNotesPageName, eStandardLayout, eNotesLayout, bIsPageBack, bIsPageObj, nInsertPosition); // Select exactly the new page. sal_uInt16 nPageCount (pDocument->GetSdPageCount(ePageKind)); for (sal_uInt16 i=0; iGetSdPage(i, PageKind::Standard)->SetSelected( i == nNewPageIndex); pDocument->GetSdPage(i, PageKind::Notes)->SetSelected( i == nNewPageIndex); } // Move the selected page to the head of the document pDocument->MovePages (sal_uInt16(-1)); nNewPageIndex = 0; } else nNewPageIndex = pDocument->CreatePage ( pPage, ePageKind, aStandardPageName, aNotesPageName, eStandardLayout, eNotesLayout, bIsPageBack, bIsPageObj, pInsertPos ? (pInsertPos->GetValue()*2)+1 : nInsertPosition); break; case SID_DUPLICATE_PAGE: // Duplication makes no sense when pPage is NULL. if (pPage != nullptr) nNewPageIndex = pDocument->DuplicatePage ( pPage, ePageKind, aStandardPageName, aNotesPageName, bIsPageBack, bIsPageObj, pInsertPos ? (pInsertPos->GetValue()*2)+1 : nInsertPosition); break; default: SAL_INFO("sd", "wrong slot id given to CreateOrDuplicatePage"); // Try to handle another slot id gracefully. } SdPage* pNewPage = nullptr; if(nNewPageIndex != 0xffff) pNewPage = pDocument->GetSdPage(nNewPageIndex, PageKind::Standard); if( bUndo ) { if( pNewPage ) { pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pNewPage)); pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pDocument->GetSdPage (nNewPageIndex, PageKind::Notes))); } pDrView->EndUndo(); } return pNewPage; } } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */