387 lines
14 KiB
C++
387 lines
14 KiB
C++
/* -*- 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();
|
|
|
|
const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
|
|
if( rMarkList.GetMarkCount() != 0 )
|
|
{
|
|
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,
|
|
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: */
|