diff options
Diffstat (limited to 'sd/source/ui/view/viewshe3.cxx')
-rw-r--r-- | sd/source/ui/view/viewshe3.cxx | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/sd/source/ui/view/viewshe3.cxx b/sd/source/ui/view/viewshe3.cxx new file mode 100644 index 0000000000..cb76eaf998 --- /dev/null +++ b/sd/source/ui/view/viewshe3.cxx @@ -0,0 +1,386 @@ +/* -*- 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 <config_features.h> + +#include <ViewShell.hxx> +#include <ViewShellBase.hxx> + +#include <sfx2/viewfrm.hxx> +#include <svtools/strings.hrc> +#include <svtools/svtresid.hxx> + +#include <app.hrc> +#include <strings.hrc> + +#include <sal/log.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <svx/svdundo.hxx> +#include <svl/intitem.hxx> +#include <svl/style.hxx> +#include <svl/stritem.hxx> +#include <stlsheet.hxx> +#include <DrawViewShell.hxx> + +#include <drawdoc.hxx> +#include <sdpage.hxx> +#include <DrawDocShell.hxx> +#include <sdresid.hxx> +#include <unokywds.hxx> + +#include <svx/svxids.hrc> +#include <sfx2/request.hxx> +#include <basic/sbstar.hxx> +#include <basic/sberrors.hxx> +#include <xmloff/autolayout.hxx> + +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(); + + if( pDrView->AreObjectsMarked() ) + { + SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet(); + if( pStyleSheet ) + { + if (pStyleSheet->GetFamily() == SfxStyleFamily::Page) + pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet(); + + if( pStyleSheet ) + { + GetDocSh()->SetStyleFamily(pStyleSheet->GetFamily()); + } + } + } + + rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, static_cast<sal_uInt16>(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<sal_uInt32>(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<sal_uInt32>(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<SfxUInt16Item>(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<SdPage*>(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<SfxUInt32Item>(ID_VAL_WHATLAYOUT); + if( pLayout ) + { + if (ePageKind == PageKind::Notes) + { + eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ()); + } + else + { + eStandardLayout = static_cast<AutoLayout>(pLayout->GetValue ()); + } + } + } + else if (pArgs->Count() == 4 || pArgs->Count() == 5) + { + // AutoLayouts must be ready + pDocument->StopWorkStartupDelay(); + + const SfxStringItem* pPageName = rRequest.GetArg<SfxStringItem>(ID_VAL_PAGENAME); + const SfxUInt32Item* pLayout = rRequest.GetArg<SfxUInt32Item>(ID_VAL_WHATLAYOUT); + const SfxBoolItem* pIsPageBack = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEBACK); + const SfxBoolItem* pIsPageObj = rRequest.GetArg<SfxBoolItem>(ID_VAL_ISPAGEOBJ); + assert(pPageName && pLayout && pIsPageBack && pIsPageObj && "must be present"); + + if (CHECK_RANGE (AUTOLAYOUT_START, static_cast<AutoLayout>(pLayout->GetValue ()), AUTOLAYOUT_END)) + { + if (ePageKind == PageKind::Notes) + { + aNotesPageName = pPageName->GetValue (); + eNotesLayout = static_cast<AutoLayout>(pLayout->GetValue ()); + } + else + { + aStandardPageName = pPageName->GetValue (); + eStandardLayout = static_cast<AutoLayout>(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; i<nPageCount; i++) + { + pDocument->GetSdPage(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, + 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: */ |