/* -*- 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 .
*/
std::vector<OUString>::const_iterator pIter =
find(mrLayoutsToTransfer.begin(), mrLayoutsToTransfer.end(), aLayout);
bool bFound = pIter != mrLayoutsToTransfer.end();
const sal_uInt16 nMPageCount = rDoc.GetMasterPageCount(); for (sal_uInt16 nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
{ // Do the layouts already exist within the document?
SdPage* pTestPage = static_cast<SdPage*>( rDoc.GetMasterPage(nMPage) );
OUString aTest(pTestPage->GetLayoutName());
sal_Int32 nIndex2 = aTest.indexOf( SD_LT_SEPARATOR ); if( nIndex2 != -1 )
aTest = aTest.copy(0, nIndex2);
if (aTest == aLayout && pBMMPage->GetPageKind() == pTestPage->GetPageKind())
{ // Ignore Layouts with "Default" these seem to be special - in the sense that there are lot of assumption all over Impress // about this if (aTest != SdResId(STR_LAYOUT_DEFAULT_NAME) || bMergeMasterPagesOnly)
{ // If we are merging master pages only, or if we are renaming duplicates and the page is not the same, then we need to rename the layout if ( bMergeMasterPagesOnly ||(bRenameDuplicates && !(pTestPage->Equals(*pBMMPage))))
{
OUString aOriginalName = pBMMPage->GetName();
OUString aNewName; // Generate a new name with incremented numeric prefix
aNewName = SdDrawDocument::GenerateNewLayoutName(aOriginalName);
OUString aOldLayoutName = pBMMPage->GetLayoutName();
pBookmarkDoc->RenameLayoutTemplate(aOldLayoutName,aNewName);
aLayout = pBMMPage->GetName(); break;
} else
bFound = true;
}
}
}
if (!bFound)
mrLayoutsToTransfer.push_back(aLayout);
}
// Inserts a bookmark as a page staticvoid lcl_IterateBookmarkPages( SdDrawDocument &rDoc, SdDrawDocument* pBookmarkDoc, const std::vector<OUString> &rBookmarkList, sal_uInt16 nCount,
InsertBookmarkAsPage_FindDuplicateLayouts& rPageIterator, bool bRenameDuplicates, bool bMergeMasterPagesOnly = false)
{
// Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
int nPos, nEndPos;
if( rBookmarkList.empty() )
{ // no list? whole source document
nEndPos = nCount;
} else
{ // bookmark list? number of entries
nEndPos = rBookmarkList.size();
}
SdPage* pBMPage;
// iterate over number of pages to insert for (nPos = 0; nPos < nEndPos; ++nPos)
{ // the master page associated to the nPos'th page to insert
SdPage* pBMMPage = nullptr;
if( rBookmarkList.empty() )
{ // simply take master page of nPos'th page in source document if (bMergeMasterPagesOnly)
pBMMPage = pBookmarkDoc->GetMasterSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard); else
pBMMPage = static_cast<SdPage*>(&(pBookmarkDoc->GetSdPage(static_cast<sal_uInt16>(nPos), PageKind::Standard)->TRG_GetMasterPage()));
} else
{ // fetch nPos'th entry from bookmark list, and determine master page const OUString& aBMPgName(rBookmarkList[nPos]); bool bIsMasterPage;
// enforce that bookmarked page is a standard page and not already a master page if (pBMPage && pBMPage->GetPageKind()==PageKind::Standard && !pBMPage->IsMasterPage())
{ const sal_uInt16 nBMSdPage = (nBMPage - 1) / 2;
pBMMPage = static_cast<SdPage*> (&(pBookmarkDoc->GetSdPage(nBMSdPage, PageKind::Standard)->TRG_GetMasterPage()));
}
}
// Create a DocShell, as OLE objects might be contained in the // document. (Persist) // If that wasn't the case, we could load the model directly. if ( bCreateGraphicShell ) // Draw
mxBookmarkDocShRef = new ::sd::GraphicDocShell(SfxObjectCreateMode::STANDARD); else // Impress
mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
bOK = mxBookmarkDocShRef->DoLoad(pMedium); if( bOK )
{
maBookmarkFile = aBookmarkName;
pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
}
}
}
// Inserts a bookmark (page or object) void SdDrawDocument::InsertBookmark( const std::vector<OUString> &rBookmarkList, // List of names of the bookmarks to be inserted
std::vector<OUString> &rExchangeList, // List of the names to be used bool bLink, // Insert bookmarks as links?
sal_uInt16 nInsertPos, // Insertion position of pages
::sd::DrawDocShell* pBookmarkDocSh, // If set, this is the source document
Point const * pObjPos) // Insertion position of objects
{ bool bOK = true; bool bInsertPages = false;
if (rBookmarkList.empty())
{ // Insert all pages
bInsertPages = true;
} else
{
SdDrawDocument* pBookmarkDoc = nullptr;
if (pBookmarkDocSh)
{
pBookmarkDoc = pBookmarkDocSh->GetDoc();
} elseif ( mxBookmarkDocShRef.is() )
{
pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
} else
bOK = false;
bInsertPages = bOK && std::any_of(rBookmarkList.begin(), rBookmarkList.end(),
[&pBookmarkDoc](const OUString& rBookmark) { // Is there a page name in the bookmark list? bool bIsMasterPage; return pBookmarkDoc->GetPageByName(rBookmark, bIsMasterPage) != SDRPAGE_NOTFOUND;
});
}
bool bCalcObjCount = !rExchangeList.empty();
if ( bOK && bInsertPages )
{ // Insert all page bookmarks
bOK = InsertFileAsPage(rBookmarkList, &rExchangeList,
bLink, nInsertPos, pBookmarkDocSh);
}
if ( bOK && !rBookmarkList.empty() )
{ // Insert all object bookmarks
InsertBookmarkAsObject(rBookmarkList, rExchangeList,
pBookmarkDocSh, pObjPos, bCalcObjCount);
}
}
namespace
{
void
lcl_removeUnusedStyles(SfxStyleSheetBasePool* const pStyleSheetPool, StyleSheetCopyResultVector& rStyles)
{
StyleSheetCopyResultVector aUsedStyles;
aUsedStyles.reserve(rStyles.size()); for (constauto& a : rStyles)
{ if (a.m_xStyleSheet->IsUsed())
aUsedStyles.push_back(a); else
pStyleSheetPool->Remove(a.m_xStyleSheet.get());
}
rStyles = std::move(aUsedStyles);
}
void SdDrawDocument::getPageProperties(PageProperties& mainProps, PageProperties& notesProps , sal_uInt16 nSdPageCount)
{ // Get the properties from the first Standard page.
mainProps.pPage = GetSdPage(0, PageKind::Standard);
mainProps.size = mainProps.pPage->GetSize();
mainProps.left = mainProps.pPage->GetLeftBorder();
mainProps.right = mainProps.pPage->GetRightBorder();
mainProps.upper = mainProps.pPage->GetUpperBorder();
mainProps.lower = mainProps.pPage->GetLowerBorder();
mainProps.orientation = mainProps.pPage->GetOrientation();
// Similarly for the first Notes page.
notesProps.pPage = GetSdPage(0, PageKind::Notes);
notesProps.size = notesProps.pPage->GetSize();
notesProps.left = notesProps.pPage->GetLeftBorder();
notesProps.right = notesProps.pPage->GetRightBorder();
notesProps.upper = notesProps.pPage->GetUpperBorder();
notesProps.lower = notesProps.pPage->GetLowerBorder();
notesProps.orientation = notesProps.pPage->GetOrientation();
// Adapt the main page properties using the last standard page.
mainProps.pPage = GetSdPage(nSdPageCount - 1, PageKind::Standard);
}
bool SdDrawDocument::determineScaleObjects(bool bNoDialogs, const PageNameList& rBookmarkList,
PageInsertionParams& rParams)
{ // In dialog-less mode, decide based on transfer container and page settings. if (bNoDialogs)
{
SdModule* mod = SdModule::get(); // If this is clipboard, then no need to scale objects: // this will make copied masters to differ from the originals, // and thus InsertBookmarkAsPage_FindDuplicateLayouts will // duplicate masters on insert to same document
m_bTransportContainer = (mod->pTransferClip &&
mod->pTransferClip->GetWorkDocument() == this); if (!m_bTransportContainer)
{ if (rBookmarkList.empty())
rParams.bScaleObjects = rParams.mainProps.pPage->IsScaleObjects(); else
rParams.bScaleObjects = true;
}
} else
{ // If not dialog-less, compare the first bookmark page with our reference page.
SdPage* pBMPage = rParams.pBookmarkDoc->GetSdPage(0, PageKind::Standard); if (pBMPage->GetSize() != rParams.mainProps.pPage->GetSize() ||
pBMPage->GetLeftBorder() != rParams.mainProps.pPage->GetLeftBorder() ||
pBMPage->GetRightBorder() != rParams.mainProps.pPage->GetRightBorder() ||
pBMPage->GetUpperBorder() != rParams.mainProps.pPage->GetUpperBorder() ||
pBMPage->GetLowerBorder() != rParams.mainProps.pPage->GetLowerBorder())
{
OUString aStr(SdResId(STR_SCALE_OBJECTS));
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
VclMessageType::Question, VclButtonsType::YesNo,
aStr));
xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
sal_uInt16 nBut = xQueryBox->run();
rParams.bScaleObjects = (nBut == RET_YES); bool bContinue = (nBut != RET_CANCEL); if (!bContinue) return bContinue;
}
} returntrue;
}
void SdDrawDocument::transferLayoutStyles(const SlideLayoutNameList& aLayoutsToTransfer,
SdDrawDocument* pBookmarkDoc,
SfxUndoManager* pUndoMgr,
StyleTransferContext& rStyleContext)
{ // For each layout in the list, copy the layout styles and, if the layout // is from a master page, also copy theme and layout ID.
// Use the style sheet pools from the context
SdStyleSheetPool& rBookmarkStyleSheetPool = *rStyleContext.pSourceStyleSheetPool;
SdStyleSheetPool& rStyleSheetPool = *rStyleContext.pDestStyleSheetPool;
// copy SlideLayout and Theme of the master slide // If the layout belongs to a master page, extract its theme and layout ID.
sal_Int32 nLayout = 20; // blank page - master slide layout ID bool bIsMasterPage = false;
sal_uInt16 nBMPage = pBookmarkDoc->GetPageByName(layoutName, bIsMasterPage); if (bIsMasterPage)
{
uno::Reference< drawing::XDrawPage > xOldPage(pBookmarkDoc->GetMasterPage(nBMPage)->getUnoPage(), uno::UNO_QUERY_THROW);
SdrPage* pMasterPage = SdPage::getImplementation(xOldPage); if (pMasterPage)
{
rStyleContext.aThemes.insert({ layoutName, pMasterPage->getSdrPageProperties().getTheme() });
// Retrieve the SlideLayout property via the property set.
uno::Reference<beans::XPropertySet> xPropSet(xOldPage, uno::UNO_QUERY_THROW); if (xPropSet.is())
{
uno::Any aLayoutID = xPropSet->getPropertyValue(u"SlideLayout"_ustr); if (aLayoutID.hasValue()) {
aLayoutID >>= nLayout;
}
}
}
rStyleContext.aSlideLayouts.insert({ layoutName, nLayout });
}
}
}
void SdDrawDocument::copyStyles(bool bReplace, bool bNoDialogs,
StyleTransferContext& rStyleContext)
{ // Use the style sheet pools from the context
SdStyleSheetPool& rBookmarkStyleSheetPool = *rStyleContext.pSourceStyleSheetPool;
SdStyleSheetPool& rStyleSheetPool = *rStyleContext.pDestStyleSheetPool;
// Depending on whether pages are being replaced and dialog mode, // decide on a renaming string and then copy graphic, cell, and table styles. if (!bReplace && !bNoDialogs)
rStyleContext.aRenameString = "_";
rStyleSheetPool.RenameAndCopyGraphicSheets(rBookmarkStyleSheetPool, rStyleContext.aGraphicStyles, rStyleContext.aRenameString);
rStyleSheetPool.CopyCellSheets(rBookmarkStyleSheetPool, rStyleContext.aCellStyles); // TODO handle undo of table styles too
rStyleSheetPool.CopyTableStyles(rBookmarkStyleSheetPool, rStyleContext.aTableStyles);
}
void SdDrawDocument::insertAllPages(PageInsertionParams& rParams, const InsertBookmarkOptions& rOptions, const DocumentPageCounts& rPageCounts)
{ // Adjust insertion position if needed. if (rParams.nInsertPos >= GetPageCount())
rParams.nInsertPos = GetPageCount();
sal_uInt16 nActualInsertPos = rParams.nInsertPos;
// First, handle master pages. if (rOptions.bMergeMasterPagesOnly)
{ // Insert all master pages from the bookmark document.
sal_uInt16 nMPageCount = rParams.pBookmarkDoc->GetMasterPageCount(); // During the copy process, a vector holds the master page slides: // - default handout page, // - default standard page, // - and default notes page. // // Normally, new master slides are added, so we start targeting from index 3. // If the copied slide matches the existing "Default" name, no new slides are added; // we then start from index 1, skipping the handout.
sal_uInt16 nStart = (nMPageCount % 2) + 2; if (nStart == nMPageCount)
nStart = 1; // Process all master pages. for (sal_uInt16 nMPage = nStart; nMPage < nMPageCount; nMPage++)
{
SdPage* pSBMPage = static_cast<SdPage*>(rParams.pBookmarkDoc->GetMasterPage(nMPage));
// Only process standard pages if (pSBMPage && pSBMPage->GetPageKind() == PageKind::Standard && pSBMPage->IsMasterPage())
{
OUString aLayoutName(pSBMPage->GetName()); if (aLayoutName == SdResId(STR_LAYOUT_DEFAULT_NAME))
{ // Default page -> use default name
aLayoutName = OUString();
}
AddNewMasterPageFromExisting(pSBMPage, rParams.pBookmarkDoc, rParams.bUndo, aLayoutName);
}
} return ;
}
sal_uInt16 nBMSdPage; // Build a name map and a set for pages that need renaming.
std::set<sal_uInt16> aRenameSet;
std::map<sal_uInt16, OUString> aNameMap;
if (rOptions.bLink)
{ // Remember the names of all pages
aNameMap.insert(std::make_pair(nBMSdPage,sName));
}
// Have to check for duplicate names here, too // don't change name if source and dest model are the same! if( rParams.pBookmarkDoc != this &&
GetPageByName(sName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
{ // delay renaming *after* pages are copied (might destroy source otherwise)
aRenameSet.insert(nBMSdPage);
}
}
// Merge the pages from the bookmark document.
Merge(*rParams.pBookmarkDoc,
1, // Not the handout page
SDRPAGE_NOTFOUND, // But all others
nActualInsertPos, // Insert at position ...
rOptions.bMergeMasterPages, // Move master pages? false, // But only the master pages used true, // Create an undo action
rOptions.bCopy); // Copy (or merge) pages?
// After merging, fix names and set link info if needed. for ( nBMSdPage = 0; nBMSdPage < rPageCounts.nSourcePageCount; nBMSdPage++)
{
SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos + 1) );
// delay renaming *after* pages are copied (might destroy source otherwise) if ( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
{ // Page name already in use -> Use default name for default and // notes page
pPage->SetName(OUString());
pNotesPage->SetName(OUString());
} if (rOptions.bLink)
{ // Assemble all link names
pPage->SetFileName(rParams.aBookmarkName);
pPage->SetBookmarkName(aNameMap[nBMSdPage]);
}
nActualInsertPos += 2;
}
}
void SdDrawDocument::insertSelectedPages(const PageNameList& rBookmarkList,
PageInsertionParams& rParams,
InsertBookmarkOptions rOptions)
{ // Adjust insertion position if necessary. if (rParams.nInsertPos >= GetPageCount())
{ // Add pages to the end
rOptions.bReplace = false;
rParams.nInsertPos = GetPageCount();
}
sal_uInt16 nActualInsertPos = rParams.nInsertPos;
// Build a vector of pointers to bookmarked pages.
std::vector<SdPage*> aBookmarkedPages(rBookmarkList.size(), nullptr); for (size_t nPos = 0; nPos < rBookmarkList.size(); ++nPos)
{ const OUString& aPgName(rBookmarkList[nPos]); bool bIsMasterPage = false;
sal_uInt16 nBMPage = rParams.pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage);
if (nBMPage != SDRPAGE_NOTFOUND)
{ if (rOptions.bMergeMasterPagesOnly)
{ // Only the master page
aBookmarkedPages[nPos] = static_cast<SdPage*>(rParams.pBookmarkDoc->GetMasterPage(nBMPage));
} else
{ // The standard page
aBookmarkedPages[nPos] = dynamic_cast<SdPage*>(rParams.pBookmarkDoc->GetPage(nBMPage));
}
}
}
if (rOptions.bMergeMasterPagesOnly)
{ for (size_t nPos = 0; nPos < rBookmarkList.size(); ++nPos)
{
SdPage* pBMPage = aBookmarkedPages[nPos]; if (pBMPage && pBMPage->GetPageKind() == PageKind::Standard && pBMPage->IsMasterPage())
{ // It has to be a default page
AddNewMasterPageFromExisting(pBMPage, rParams.pBookmarkDoc, rParams.bUndo, pBMPage->GetName());
}
} return;
}
// Process each bookmarked page. for ( size_t nPos = 0; nPos < rBookmarkList.size(); ++nPos)
{
SdPage* pBMPage = aBookmarkedPages[nPos];
sal_uInt16 nBMPage = pBMPage!=nullptr ? pBMPage->GetPageNum() : SDRPAGE_NOTFOUND;
if (pBMPage && pBMPage->GetPageKind() == PageKind::Standard && !pBMPage->IsMasterPage())
{ // It has to be a default page bool bMustRename = false; // delay renaming *after* pages are copied (might destroy source otherwise) // don't change name if source and dest model are the same! // avoid renaming if replacing the same page const OUString& aPgName(rBookmarkList[nPos]); bool bIsMasterPage;
sal_uInt16 nPageSameName = GetPageByName(aPgName, bIsMasterPage); if ( rParams.pBookmarkDoc != this &&
nPageSameName != SDRPAGE_NOTFOUND &&
( !rOptions.bReplace || nPageSameName != nActualInsertPos))
{
bMustRename = true;
}
SdPage* pBookmarkPage = pBMPage; if (rOptions.bReplace)
ReplacePageInCustomShows(dynamic_cast<SdPage*>(GetPage(nActualInsertPos)), pBookmarkPage);
Merge(*rParams.pBookmarkDoc,
nBMPage, // From page (default page)
nBMPage+1, // To page (notes page)
nActualInsertPos, // Insert at position
rOptions.bMergeMasterPages, // Move master pages? false, // But only the master pages used true, // Create undo action
rOptions.bCopy); // Copy (or merge) pages?
if (rOptions.bReplace && GetPage(nActualInsertPos) != pBookmarkPage)
{ // bookmark page was not moved but cloned, so update custom shows again
ReplacePageInCustomShows(pBookmarkPage, dynamic_cast<SdPage*>(GetPage(nActualInsertPos)));
} // tdf#39519 - rename page if its name is not unique, e.g., if a slide is copied by // ctrl + drag and drop (DND_ACTION_COPY) if (bMustRename // tdf#164284 - prevent page name change during page move
|| (rParams.pBookmarkDoc->DoesMakePageObjectsNamesUnique()
&& !mpDocSh->IsPageNameUnique(aPgName)))
{ // Page name already in use -> use default name for default and // notes page
SdPage* pPage = static_cast<SdPage*>( GetPage(nActualInsertPos) );
pPage->SetName(OUString());
SdPage* pNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1) );
pNotesPage->SetName(OUString());
}
if (pNotesPage)
{ if (rOptions.bPreservePageNames)
{ // Take old slide names for inserted pages
SdPage* pNewNotesPage = static_cast<SdPage*>( GetPage(nActualInsertPos+1));
if (pNewNotesPage)
{
assert(pStandardPage);
pNewNotesPage->SetName(pStandardPage->GetRealName());
}
}
void SdDrawDocument::removeDuplicateMasterPages(PageInsertionParams& rParams,
DocumentPageCounts& rPageCounts)
{ // Remove duplicate master pages created during the merge. // We might have duplicate master pages now, as the drawing engine does not // recognize duplicates. Remove these now.
rPageCounts.nNewMPageCount = GetMasterPageCount();
// Go backwards, so the numbers don't become messed up for (sal_uInt16 nPage = rPageCounts.nNewMPageCount - 1; nPage >= rPageCounts.nMasterPageCount; nPage--)
{
rParams.mainProps.pPage = static_cast<SdPage*>(GetMasterPage(nPage));
OUString aMPLayout (rParams.mainProps.pPage->GetLayoutName());
PageKind eKind = rParams.mainProps.pPage->GetPageKind(); // Check against the original set of master pages. for (sal_uInt16 nTest = 0; nTest < rPageCounts.nMasterPageCount; nTest++)
{
SdPage* pTest = static_cast<SdPage*>( GetMasterPage(nTest));
OUString aTest(pTest->GetLayoutName());
void SdDrawDocument::updateInsertedPages(PageInsertionParams& rParams, const InsertBookmarkOptions& rOptions, const DocumentPageCounts& rPageCounts,
StyleTransferContext& rStyleContext)
{ // If we are copying master pages only, we don't need to update the pages. if (rOptions.bMergeMasterPagesOnly) return;
// update layout and referred master page
rParams.mainProps.pPage->SetPresentationLayout(aLayout); if (rParams.bUndo)
AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*rParams.mainProps.pPage));
// update layout and referred master page
rParams.notesProps.pPage->SetPresentationLayout(aLayout); if (rParams.bUndo)
AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*rParams.notesProps.pPage));
if (bRemoveEmptyPresObj)
rParams.notesProps.pPage->RemoveEmptyPresentationObjects();
} ///Remove processed elements, to avoid doing hacks in InsertBookmarkAsObject if (rParams.pExchangeList)
rParams.pExchangeList->erase(rParams.pExchangeList->begin(), pExchangeIter);
// Inserts a bookmark as an object bool SdDrawDocument::InsertBookmarkAsObject( const std::vector<OUString> &rBookmarkList, const std::vector<OUString> &rExchangeList, // List of names to use
::sd::DrawDocShell* pBookmarkDocSh,
Point const * pObjPos, bool bCalcObjCount)
{ bool bOK = true; bool bOLEObjFound = false;
std::unique_ptr<::sd::View> pBMView;
for ( constauto& rBookmark : rBookmarkList )
{ // Get names of bookmarks from the list
SdrObject* pObj = pBookmarkDoc->GetObj(rBookmark);
if (pObj)
{ // Found an object if (pObj->GetObjInventor() == SdrInventor::Default &&
pObj->GetObjIdentifier() == SdrObjKind::OLE2)
{
bOLEObjFound = true;
}
if (!pBMView)
{ // Create View for the first time
pBMView.reset(new ::sd::View(*pBookmarkDoc, nullptr));
pBMView->EndListening(*pBookmarkDoc);
}
if (!rExchangeList.empty() || bCalcObjCount)
{ // Sort OrdNums and get the number of objects before inserting
pPage->RecalcObjOrdNums();
nCountBefore = pPage->GetObjCount();
}
if (bOLEObjFound)
pBMView->GetDoc().SetAllocDocSh(true);
if (bOLEObjFound)
pBMView->GetDoc().SetAllocDocSh(false);
if (!bOLEObjFound) delete pTmpDoc; // Would otherwise be destroyed by DocShell
pView.reset();
// Get number of objects after inserting. const size_t nCount = pPage->GetObjCount(); if (nCountBefore < nCount)
{
size_t nObj = nCountBefore; for (constauto& rExchange : rExchangeList)
{ // Get the name to use from the Exchange list if (pPage->GetObj(nObj))
{
pPage->GetObj(nObj)->SetName(rExchange);
}
OUString SdDrawDocument::GenerateNewLayoutName(std::u16string_view rOriginalName)
{ // Generate a new name with incremented numeric prefix
OUString aOriginalName(rOriginalName);
OUString aNewName;
sal_uInt32 nCount = 1;
// Check if name already has a number prefix int nUnderscorePos = aOriginalName.indexOf( "_" ); if (nUnderscorePos > 0)
{ // Try to extract the number part
OUString aPrefix = aOriginalName.copy(0, nUnderscorePos);
// Check if the prefix is a valid number bool bIsNumber = true; for (sal_Int32 i = 0; i < aPrefix.getLength(); ++i)
{ if (!isdigit(aPrefix[i]))
{
bIsNumber = false; break;
}
} if (bIsNumber)
{ // If it is a number, increment it
nCount = aPrefix.toInt32() + 1;
OUString aBaseName = aOriginalName.copy(nUnderscorePos + 1);
aNewName = OUString::number(nCount) + "_" + aBaseName;
} else
{ // Has underscore but not a number, just append "1_"
aNewName = "1_" + aOriginalName;
}
} else
{ // If no number prefix, just append "1_"
aNewName = "1_" + aOriginalName;
}
return aNewName;
}
// Stops the bookmark insertion void SdDrawDocument::CloseBookmarkDoc()
{ if (mxBookmarkDocShRef.is())
{
mxBookmarkDocShRef->DoClose();
}
// Is this document read-only? bool SdDrawDocument::IsReadOnly() const
{ returnfalse;
}
// In the subsequent AllocModel() a DocShell (xAllocedDocShRef) is created. // Any pre-existing DocShell is deleted void SdDrawDocument::SetAllocDocSh(bool bAlloc)
{
mbAllocDocSh = bAlloc;
if ( pMaster->GetPageKind() == PageKind::Standard &&
GetMasterPageUserCount( pMaster ) == 0 &&
pNotesMaster )
{ // Do not delete master pages that have their precious flag set bool bDeleteMaster = !pMaster->IsPrecious();
OUString aLayoutName = pMaster->GetLayoutName();
if(bOnlyDuplicatePages )
{ // remove only duplicate pages
bDeleteMaster = false; for (sal_uInt16 i = 0; i < GetMasterSdPageCount( PageKind::Standard ); i++)
{
SdPage* pMPg = GetMasterSdPage( i, PageKind::Standard ); if( pMPg != pMaster &&
pMPg->GetLayoutName() == aLayoutName )
{ // duplicate page found -> remove it
bDeleteMaster = true;
}
}
}
if( bDeleteMaster )
{ if (pView)
{ // if MasterPage is visible hide on pageview
SdrPageView* pPgView = pView->GetSdrPageView(); if (pPgView)
{
SdrPage* pShownPage = pPgView->GetPage(); if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
{
pView->HideSdrPage();
pView->ShowSdrPage( GetSdPage( 0, PageKind::Standard ) );
}
}
}
if (pMasterPage) break; // Just this one master page!
}
}
/** Exchange master page * * Either the nSdPageNum gets a new, own master page or the master page is * exchanged completely (which then applies to all pages). * * nSdPageNum : page number that the new master page should get. * rLayoutName : LayoutName of the new master page * pSourceDoc : document (template) to get the master page from * bMaster : exchange the master page of nSdPageNum * bCheckMasters: remove unused master pages * * If pSourceDoc == NULL, an empty master page is applied. * If rLayoutName is empty, the first master page is used.
*/ // #i121863# factored out functionality staticbool isMasterPageLayoutNameUnique(const SdDrawDocument& rDoc, std::u16string_view rCandidate)
{ if (rCandidate.empty())
{ returnfalse;
}
if (pMP->GetLayoutName() == aSearchFor)
{ if (pMP->GetPageKind() == PageKind::Standard)
pMaster = pMP; if (pMP->GetPageKind() == PageKind::Notes)
pNotesMaster = pMP;
} if (pMaster && pNotesMaster) break;
}
DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
// this should not happen, but looking at crash reports, it does if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
{ // so take the first MasterPage
pMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Standard);
pNotesMaster = pSourceDoc->GetMasterSdPage(0, PageKind::Notes);
}
}
// we should never reach this, but one never knows... if( (pMaster == nullptr) || (pNotesMaster == nullptr) )
{ if (bUndo)
pUndoMgr->LeaveListAction();
if (pSourceDoc != this)
{ // #i121863# clone masterpages, they are from another model (!)
rtl::Reference<SdPage> pNewNotesMaster(dynamic_cast< SdPage* >(pNotesMaster->CloneSdrPage(*this).get()));
rtl::Reference<SdPage> pNewMaster(dynamic_cast< SdPage* >(pMaster->CloneSdrPage(*this).get()));
// Correct or create presentation templates -- // only worry about presentation templates
OUString aName;
SdStyleSheetPool* pSourceStyleSheetPool = static_cast<SdStyleSheetPool*>( pSourceDoc->GetStyleSheetPool() );
StyleSheetCopyResultVector aCreatedStyles; // List of created stylesheets
SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First(SfxStyleFamily::Page);
while (pHisSheet)
{
aName = pHisSheet->GetName();
// #i121863# search in source styles with original style name from source of // evtl. cloned master (not-cloned, renamed for uniqueness) if( aName.startsWith( aOriginalNewLayoutName ) )
{ // #i121863# build name of evtl. cloned master style to search for if(aOriginalNewLayoutName != aTargetNewLayoutName)
{ const sal_Int32 nPos(aName.indexOf(SD_LT_SEPARATOR));
aName = aTargetNewLayoutName + aName.subView(nPos);
}
if (pMySheet)
{ // A stylesheet of the same name already exists -> overwrite contents bool bTest = pMySheet->SetName(pHisSheet->GetName());
DBG_ASSERT(bTest, "Renaming StyleSheet failed.");
pMySheet->GetItemSet().ClearItem(); // Delete all
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.