1*02c50d82SAndre Fischer /************************************************************** 2*02c50d82SAndre Fischer * 3*02c50d82SAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 4*02c50d82SAndre Fischer * or more contributor license agreements. See the NOTICE file 5*02c50d82SAndre Fischer * distributed with this work for additional information 6*02c50d82SAndre Fischer * regarding copyright ownership. The ASF licenses this file 7*02c50d82SAndre Fischer * to you under the Apache License, Version 2.0 (the 8*02c50d82SAndre Fischer * "License"); you may not use this file except in compliance 9*02c50d82SAndre Fischer * with the License. You may obtain a copy of the License at 10*02c50d82SAndre Fischer * 11*02c50d82SAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 12*02c50d82SAndre Fischer * 13*02c50d82SAndre Fischer * Unless required by applicable law or agreed to in writing, 14*02c50d82SAndre Fischer * software distributed under the License is distributed on an 15*02c50d82SAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*02c50d82SAndre Fischer * KIND, either express or implied. See the License for the 17*02c50d82SAndre Fischer * specific language governing permissions and limitations 18*02c50d82SAndre Fischer * under the License. 19*02c50d82SAndre Fischer * 20*02c50d82SAndre Fischer *************************************************************/ 21*02c50d82SAndre Fischer 22*02c50d82SAndre Fischer #include "precompiled_sd.hxx" 23*02c50d82SAndre Fischer 24*02c50d82SAndre Fischer #include "DocumentHelper.hxx" 25*02c50d82SAndre Fischer 26*02c50d82SAndre Fischer #include "drawdoc.hxx" 27*02c50d82SAndre Fischer #include "DrawDocShell.hxx" 28*02c50d82SAndre Fischer #include "sdpage.hxx" 29*02c50d82SAndre Fischer #include "glob.hxx" 30*02c50d82SAndre Fischer #include "unmovss.hxx" 31*02c50d82SAndre Fischer #include "strings.hrc" 32*02c50d82SAndre Fischer #include "sdresid.hxx" 33*02c50d82SAndre Fischer #include "undoback.hxx" 34*02c50d82SAndre Fischer #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> 35*02c50d82SAndre Fischer #include <com/sun/star/drawing/XDrawPages.hpp> 36*02c50d82SAndre Fischer #include <com/sun/star/frame/XComponentLoader.hpp> 37*02c50d82SAndre Fischer #include <com/sun/star/container/XIndexAccess.hpp> 38*02c50d82SAndre Fischer #include "stlpool.hxx" 39*02c50d82SAndre Fischer #include <svx/xfillit0.hxx> 40*02c50d82SAndre Fischer #include <tools/diagnose_ex.h> 41*02c50d82SAndre Fischer 42*02c50d82SAndre Fischer using namespace ::com::sun::star; 43*02c50d82SAndre Fischer 44*02c50d82SAndre Fischer namespace sd { namespace sidebar { 45*02c50d82SAndre Fischer 46*02c50d82SAndre Fischer SdPage* DocumentHelper::CopyMasterPageToLocalDocument ( 47*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 48*02c50d82SAndre Fischer SdPage* pMasterPage) 49*02c50d82SAndre Fischer { 50*02c50d82SAndre Fischer SdPage* pNewMasterPage = NULL; 51*02c50d82SAndre Fischer 52*02c50d82SAndre Fischer do 53*02c50d82SAndre Fischer { 54*02c50d82SAndre Fischer if (pMasterPage == NULL) 55*02c50d82SAndre Fischer break; 56*02c50d82SAndre Fischer 57*02c50d82SAndre Fischer // Check the presence of the source document. 58*02c50d82SAndre Fischer SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>( 59*02c50d82SAndre Fischer pMasterPage->GetModel()); 60*02c50d82SAndre Fischer if (pSourceDocument == NULL) 61*02c50d82SAndre Fischer break; 62*02c50d82SAndre Fischer 63*02c50d82SAndre Fischer // When the given master page already belongs to the target document 64*02c50d82SAndre Fischer // then there is nothing more to do. 65*02c50d82SAndre Fischer if (pSourceDocument == &rTargetDocument) 66*02c50d82SAndre Fischer { 67*02c50d82SAndre Fischer pNewMasterPage = pMasterPage; 68*02c50d82SAndre Fischer break; 69*02c50d82SAndre Fischer } 70*02c50d82SAndre Fischer 71*02c50d82SAndre Fischer // Test if the master pages of both the slide and its notes page are 72*02c50d82SAndre Fischer // present. This is not the case when we are called during the 73*02c50d82SAndre Fischer // creation of the slide master page because then the notes master 74*02c50d82SAndre Fischer // page is not there. 75*02c50d82SAndre Fischer sal_uInt16 nSourceMasterPageCount = pSourceDocument->GetMasterPageCount(); 76*02c50d82SAndre Fischer if (nSourceMasterPageCount%2 == 0) 77*02c50d82SAndre Fischer // There should be 1 handout page + n slide masters + n notes 78*02c50d82SAndre Fischer // masters = 2*n+1. An even value indicates that a new slide 79*02c50d82SAndre Fischer // master but not yet the notes master has been inserted. 80*02c50d82SAndre Fischer break; 81*02c50d82SAndre Fischer sal_uInt16 nIndex = pMasterPage->GetPageNum(); 82*02c50d82SAndre Fischer if (nSourceMasterPageCount <= nIndex+1) 83*02c50d82SAndre Fischer break; 84*02c50d82SAndre Fischer // Get the slide master page. 85*02c50d82SAndre Fischer if (pMasterPage != static_cast<SdPage*>( 86*02c50d82SAndre Fischer pSourceDocument->GetMasterPage(nIndex))) 87*02c50d82SAndre Fischer break; 88*02c50d82SAndre Fischer // Get the notes master page. 89*02c50d82SAndre Fischer SdPage* pNotesMasterPage = static_cast<SdPage*>( 90*02c50d82SAndre Fischer pSourceDocument->GetMasterPage(nIndex+1)); 91*02c50d82SAndre Fischer if (pNotesMasterPage == NULL) 92*02c50d82SAndre Fischer break; 93*02c50d82SAndre Fischer 94*02c50d82SAndre Fischer 95*02c50d82SAndre Fischer // Check if a master page with the same name as that of the given 96*02c50d82SAndre Fischer // master page already exists. 97*02c50d82SAndre Fischer bool bPageExists (false); 98*02c50d82SAndre Fischer sal_uInt16 nMasterPageCount(rTargetDocument.GetMasterSdPageCount(PK_STANDARD)); 99*02c50d82SAndre Fischer for (sal_uInt16 nMaster=0; nMaster<nMasterPageCount; nMaster++) 100*02c50d82SAndre Fischer { 101*02c50d82SAndre Fischer SdPage* pCandidate = static_cast<SdPage*>( 102*02c50d82SAndre Fischer rTargetDocument.GetMasterSdPage (nMaster, PK_STANDARD)); 103*02c50d82SAndre Fischer if (pMasterPage!=NULL 104*02c50d82SAndre Fischer && pCandidate->GetName().CompareTo(pMasterPage->GetName())==0) 105*02c50d82SAndre Fischer { 106*02c50d82SAndre Fischer bPageExists = true; 107*02c50d82SAndre Fischer pNewMasterPage = pCandidate; 108*02c50d82SAndre Fischer break; 109*02c50d82SAndre Fischer } 110*02c50d82SAndre Fischer } 111*02c50d82SAndre Fischer if (bPageExists) 112*02c50d82SAndre Fischer break; 113*02c50d82SAndre Fischer 114*02c50d82SAndre Fischer // Create a new slide (and its notes page.) 115*02c50d82SAndre Fischer uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier ( 116*02c50d82SAndre Fischer rTargetDocument.getUnoModel(), uno::UNO_QUERY); 117*02c50d82SAndre Fischer if ( ! xSlideSupplier.is()) 118*02c50d82SAndre Fischer break; 119*02c50d82SAndre Fischer uno::Reference<drawing::XDrawPages> xSlides ( 120*02c50d82SAndre Fischer xSlideSupplier->getDrawPages(), uno::UNO_QUERY); 121*02c50d82SAndre Fischer if ( ! xSlides.is()) 122*02c50d82SAndre Fischer break; 123*02c50d82SAndre Fischer xSlides->insertNewByIndex (xSlides->getCount()); 124*02c50d82SAndre Fischer 125*02c50d82SAndre Fischer // Set a layout. 126*02c50d82SAndre Fischer SdPage* pSlide = rTargetDocument.GetSdPage( 127*02c50d82SAndre Fischer rTargetDocument.GetSdPageCount(PK_STANDARD)-1, 128*02c50d82SAndre Fischer PK_STANDARD); 129*02c50d82SAndre Fischer if (pSlide == NULL) 130*02c50d82SAndre Fischer break; 131*02c50d82SAndre Fischer pSlide->SetAutoLayout(AUTOLAYOUT_TITLE, sal_True); 132*02c50d82SAndre Fischer 133*02c50d82SAndre Fischer // Create a copy of the master page and the associated notes 134*02c50d82SAndre Fischer // master page and insert them into our document. 135*02c50d82SAndre Fischer pNewMasterPage = AddMasterPage(rTargetDocument, pMasterPage); 136*02c50d82SAndre Fischer if (pNewMasterPage==NULL) 137*02c50d82SAndre Fischer break; 138*02c50d82SAndre Fischer SdPage* pNewNotesMasterPage 139*02c50d82SAndre Fischer = AddMasterPage(rTargetDocument, pNotesMasterPage); 140*02c50d82SAndre Fischer if (pNewNotesMasterPage==NULL) 141*02c50d82SAndre Fischer break; 142*02c50d82SAndre Fischer 143*02c50d82SAndre Fischer // Make the connection from the new slide to the master page 144*02c50d82SAndre Fischer // (and do the same for the notes page.) 145*02c50d82SAndre Fischer rTargetDocument.SetMasterPage ( 146*02c50d82SAndre Fischer rTargetDocument.GetSdPageCount(PK_STANDARD)-1, 147*02c50d82SAndre Fischer pNewMasterPage->GetName(), 148*02c50d82SAndre Fischer &rTargetDocument, 149*02c50d82SAndre Fischer sal_False, // Connect the new master page with the new slide but 150*02c50d82SAndre Fischer // do not modify other (master) pages. 151*02c50d82SAndre Fischer sal_True); 152*02c50d82SAndre Fischer } 153*02c50d82SAndre Fischer while (false); 154*02c50d82SAndre Fischer 155*02c50d82SAndre Fischer // We are not interested in any automatisms for our modified internal 156*02c50d82SAndre Fischer // document. 157*02c50d82SAndre Fischer rTargetDocument.SetChanged (sal_False); 158*02c50d82SAndre Fischer 159*02c50d82SAndre Fischer return pNewMasterPage; 160*02c50d82SAndre Fischer } 161*02c50d82SAndre Fischer 162*02c50d82SAndre Fischer 163*02c50d82SAndre Fischer 164*02c50d82SAndre Fischer 165*02c50d82SAndre Fischer SdPage* DocumentHelper::GetSlideForMasterPage (SdPage* pMasterPage) 166*02c50d82SAndre Fischer { 167*02c50d82SAndre Fischer SdPage* pCandidate = NULL; 168*02c50d82SAndre Fischer 169*02c50d82SAndre Fischer SdDrawDocument* pDocument = NULL; 170*02c50d82SAndre Fischer if (pMasterPage != NULL) 171*02c50d82SAndre Fischer pDocument = dynamic_cast<SdDrawDocument*>(pMasterPage->GetModel()); 172*02c50d82SAndre Fischer 173*02c50d82SAndre Fischer // Iterate over all pages and check if it references the given master 174*02c50d82SAndre Fischer // page. 175*02c50d82SAndre Fischer if (pDocument!=NULL && pDocument->GetSdPageCount(PK_STANDARD) > 0) 176*02c50d82SAndre Fischer { 177*02c50d82SAndre Fischer // In most cases a new slide has just been inserted so start with 178*02c50d82SAndre Fischer // the last page. 179*02c50d82SAndre Fischer sal_uInt16 nPageIndex (pDocument->GetSdPageCount(PK_STANDARD)-1); 180*02c50d82SAndre Fischer bool bFound (false); 181*02c50d82SAndre Fischer while ( ! bFound) 182*02c50d82SAndre Fischer { 183*02c50d82SAndre Fischer pCandidate = pDocument->GetSdPage( 184*02c50d82SAndre Fischer nPageIndex, 185*02c50d82SAndre Fischer PK_STANDARD); 186*02c50d82SAndre Fischer if (pCandidate != NULL) 187*02c50d82SAndre Fischer { 188*02c50d82SAndre Fischer if (static_cast<SdPage*>(&pCandidate->TRG_GetMasterPage()) 189*02c50d82SAndre Fischer == pMasterPage) 190*02c50d82SAndre Fischer { 191*02c50d82SAndre Fischer bFound = true; 192*02c50d82SAndre Fischer break; 193*02c50d82SAndre Fischer } 194*02c50d82SAndre Fischer } 195*02c50d82SAndre Fischer 196*02c50d82SAndre Fischer if (nPageIndex == 0) 197*02c50d82SAndre Fischer break; 198*02c50d82SAndre Fischer else 199*02c50d82SAndre Fischer nPageIndex --; 200*02c50d82SAndre Fischer } 201*02c50d82SAndre Fischer 202*02c50d82SAndre Fischer // If no page was found that refernced the given master page reset 203*02c50d82SAndre Fischer // the pointer that is returned. 204*02c50d82SAndre Fischer if ( ! bFound) 205*02c50d82SAndre Fischer pCandidate = NULL; 206*02c50d82SAndre Fischer } 207*02c50d82SAndre Fischer 208*02c50d82SAndre Fischer return pCandidate; 209*02c50d82SAndre Fischer } 210*02c50d82SAndre Fischer 211*02c50d82SAndre Fischer 212*02c50d82SAndre Fischer 213*02c50d82SAndre Fischer 214*02c50d82SAndre Fischer SdPage* DocumentHelper::AddMasterPage ( 215*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 216*02c50d82SAndre Fischer SdPage* pMasterPage) 217*02c50d82SAndre Fischer { 218*02c50d82SAndre Fischer SdPage* pClonedMasterPage = NULL; 219*02c50d82SAndre Fischer 220*02c50d82SAndre Fischer if (pMasterPage!=NULL) 221*02c50d82SAndre Fischer { 222*02c50d82SAndre Fischer try 223*02c50d82SAndre Fischer { 224*02c50d82SAndre Fischer // Duplicate the master page. 225*02c50d82SAndre Fischer pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone()); 226*02c50d82SAndre Fischer 227*02c50d82SAndre Fischer // Copy the necessary styles. 228*02c50d82SAndre Fischer SdDrawDocument* pSourceDocument 229*02c50d82SAndre Fischer = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); 230*02c50d82SAndre Fischer if (pSourceDocument != NULL) 231*02c50d82SAndre Fischer ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage); 232*02c50d82SAndre Fischer 233*02c50d82SAndre Fischer // Copy the precious flag. 234*02c50d82SAndre Fischer pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious()); 235*02c50d82SAndre Fischer 236*02c50d82SAndre Fischer // Now that the styles are available we can insert the cloned 237*02c50d82SAndre Fischer // master page. 238*02c50d82SAndre Fischer rTargetDocument.InsertMasterPage (pClonedMasterPage); 239*02c50d82SAndre Fischer } 240*02c50d82SAndre Fischer catch (uno::Exception& rException) 241*02c50d82SAndre Fischer { 242*02c50d82SAndre Fischer pClonedMasterPage = NULL; 243*02c50d82SAndre Fischer DBG_UNHANDLED_EXCEPTION(); 244*02c50d82SAndre Fischer } 245*02c50d82SAndre Fischer catch (::std::exception rException) 246*02c50d82SAndre Fischer { 247*02c50d82SAndre Fischer pClonedMasterPage = NULL; 248*02c50d82SAndre Fischer OSL_TRACE ("caught general exception"); 249*02c50d82SAndre Fischer } 250*02c50d82SAndre Fischer catch (...) 251*02c50d82SAndre Fischer { 252*02c50d82SAndre Fischer pClonedMasterPage = NULL; 253*02c50d82SAndre Fischer OSL_TRACE ("caught general exception"); 254*02c50d82SAndre Fischer } 255*02c50d82SAndre Fischer } 256*02c50d82SAndre Fischer 257*02c50d82SAndre Fischer return pClonedMasterPage; 258*02c50d82SAndre Fischer } 259*02c50d82SAndre Fischer 260*02c50d82SAndre Fischer 261*02c50d82SAndre Fischer 262*02c50d82SAndre Fischer 263*02c50d82SAndre Fischer void DocumentHelper::ProvideStyles ( 264*02c50d82SAndre Fischer SdDrawDocument& rSourceDocument, 265*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 266*02c50d82SAndre Fischer SdPage* pPage) 267*02c50d82SAndre Fischer { 268*02c50d82SAndre Fischer // Get the layout name of the given page. 269*02c50d82SAndre Fischer String sLayoutName (pPage->GetLayoutName()); 270*02c50d82SAndre Fischer sLayoutName.Erase (sLayoutName.SearchAscii (SD_LT_SEPARATOR)); 271*02c50d82SAndre Fischer 272*02c50d82SAndre Fischer // Copy the style sheet from source to target document. 273*02c50d82SAndre Fischer SdStyleSheetPool* pSourceStyleSheetPool = 274*02c50d82SAndre Fischer static_cast<SdStyleSheetPool*>(rSourceDocument.GetStyleSheetPool()); 275*02c50d82SAndre Fischer SdStyleSheetPool* pTargetStyleSheetPool = 276*02c50d82SAndre Fischer static_cast<SdStyleSheetPool*>(rTargetDocument.GetStyleSheetPool()); 277*02c50d82SAndre Fischer SdStyleSheetVector aCreatedStyles; 278*02c50d82SAndre Fischer pTargetStyleSheetPool->CopyLayoutSheets ( 279*02c50d82SAndre Fischer sLayoutName, 280*02c50d82SAndre Fischer *pSourceStyleSheetPool, 281*02c50d82SAndre Fischer aCreatedStyles); 282*02c50d82SAndre Fischer 283*02c50d82SAndre Fischer // Add an undo action for the copied style sheets. 284*02c50d82SAndre Fischer if( !aCreatedStyles.empty() ) 285*02c50d82SAndre Fischer { 286*02c50d82SAndre Fischer ::svl::IUndoManager* pUndoManager = rTargetDocument.GetDocSh()->GetUndoManager(); 287*02c50d82SAndre Fischer if (pUndoManager != NULL) 288*02c50d82SAndre Fischer { 289*02c50d82SAndre Fischer SdMoveStyleSheetsUndoAction* pMovStyles = 290*02c50d82SAndre Fischer new SdMoveStyleSheetsUndoAction ( 291*02c50d82SAndre Fischer &rTargetDocument, 292*02c50d82SAndre Fischer aCreatedStyles, 293*02c50d82SAndre Fischer sal_True); 294*02c50d82SAndre Fischer pUndoManager->AddUndoAction (pMovStyles); 295*02c50d82SAndre Fischer } 296*02c50d82SAndre Fischer } 297*02c50d82SAndre Fischer } 298*02c50d82SAndre Fischer 299*02c50d82SAndre Fischer 300*02c50d82SAndre Fischer 301*02c50d82SAndre Fischer 302*02c50d82SAndre Fischer void DocumentHelper::AssignMasterPageToPageList ( 303*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 304*02c50d82SAndre Fischer SdPage* pMasterPage, 305*02c50d82SAndre Fischer const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) 306*02c50d82SAndre Fischer { 307*02c50d82SAndre Fischer do 308*02c50d82SAndre Fischer { 309*02c50d82SAndre Fischer if (pMasterPage == NULL && pMasterPage->IsMasterPage()) 310*02c50d82SAndre Fischer break; 311*02c50d82SAndre Fischer 312*02c50d82SAndre Fischer // Make the layout name by stripping ouf the layout postfix from the 313*02c50d82SAndre Fischer // layout name of the given master page. 314*02c50d82SAndre Fischer String sFullLayoutName (pMasterPage->GetLayoutName()); 315*02c50d82SAndre Fischer String sBaseLayoutName (sFullLayoutName); 316*02c50d82SAndre Fischer sBaseLayoutName.Erase (sBaseLayoutName.SearchAscii (SD_LT_SEPARATOR)); 317*02c50d82SAndre Fischer 318*02c50d82SAndre Fischer if (rpPageList->empty()) 319*02c50d82SAndre Fischer break; 320*02c50d82SAndre Fischer 321*02c50d82SAndre Fischer // Create a second list that contains only the valid pointers to 322*02c50d82SAndre Fischer // pages for which an assignment is necessary. 323*02c50d82SAndre Fischer ::std::vector<SdPage*>::const_iterator iPage; 324*02c50d82SAndre Fischer ::std::vector<SdPage*> aCleanedList; 325*02c50d82SAndre Fischer for (iPage=rpPageList->begin(); iPage!=rpPageList->end(); ++iPage) 326*02c50d82SAndre Fischer { 327*02c50d82SAndre Fischer OSL_ASSERT(*iPage!=NULL && (*iPage)->GetModel() == &rTargetDocument); 328*02c50d82SAndre Fischer if (*iPage != NULL 329*02c50d82SAndre Fischer && (*iPage)->GetLayoutName().CompareTo(sFullLayoutName)!=0) 330*02c50d82SAndre Fischer { 331*02c50d82SAndre Fischer aCleanedList.push_back(*iPage); 332*02c50d82SAndre Fischer } 333*02c50d82SAndre Fischer } 334*02c50d82SAndre Fischer if (aCleanedList.empty() ) 335*02c50d82SAndre Fischer break; 336*02c50d82SAndre Fischer 337*02c50d82SAndre Fischer ::svl::IUndoManager* pUndoMgr = rTargetDocument.GetDocSh()->GetUndoManager(); 338*02c50d82SAndre Fischer if( pUndoMgr ) 339*02c50d82SAndre Fischer pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String()); 340*02c50d82SAndre Fischer 341*02c50d82SAndre Fischer SdPage* pMasterPageInDocument = ProvideMasterPage(rTargetDocument,pMasterPage,rpPageList); 342*02c50d82SAndre Fischer if (pMasterPageInDocument == NULL) 343*02c50d82SAndre Fischer break; 344*02c50d82SAndre Fischer 345*02c50d82SAndre Fischer // Assign the master pages to the given list of pages. 346*02c50d82SAndre Fischer for (iPage=aCleanedList.begin(); 347*02c50d82SAndre Fischer iPage!=aCleanedList.end(); 348*02c50d82SAndre Fischer ++iPage) 349*02c50d82SAndre Fischer { 350*02c50d82SAndre Fischer AssignMasterPageToPage ( 351*02c50d82SAndre Fischer pMasterPageInDocument, 352*02c50d82SAndre Fischer sBaseLayoutName, 353*02c50d82SAndre Fischer *iPage); 354*02c50d82SAndre Fischer } 355*02c50d82SAndre Fischer 356*02c50d82SAndre Fischer if( pUndoMgr ) 357*02c50d82SAndre Fischer pUndoMgr->LeaveListAction(); 358*02c50d82SAndre Fischer } 359*02c50d82SAndre Fischer while (false); 360*02c50d82SAndre Fischer } 361*02c50d82SAndre Fischer 362*02c50d82SAndre Fischer 363*02c50d82SAndre Fischer 364*02c50d82SAndre Fischer 365*02c50d82SAndre Fischer SdPage* DocumentHelper::AddMasterPage ( 366*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 367*02c50d82SAndre Fischer SdPage* pMasterPage, 368*02c50d82SAndre Fischer sal_uInt16 nInsertionIndex) 369*02c50d82SAndre Fischer { 370*02c50d82SAndre Fischer SdPage* pClonedMasterPage = NULL; 371*02c50d82SAndre Fischer 372*02c50d82SAndre Fischer if (pMasterPage!=NULL) 373*02c50d82SAndre Fischer { 374*02c50d82SAndre Fischer // Duplicate the master page. 375*02c50d82SAndre Fischer pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone()); 376*02c50d82SAndre Fischer 377*02c50d82SAndre Fischer // Copy the precious flag. 378*02c50d82SAndre Fischer pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious()); 379*02c50d82SAndre Fischer 380*02c50d82SAndre Fischer // Copy the necessary styles. 381*02c50d82SAndre Fischer SdDrawDocument* pSourceDocument 382*02c50d82SAndre Fischer = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); 383*02c50d82SAndre Fischer if (pSourceDocument != NULL) 384*02c50d82SAndre Fischer { 385*02c50d82SAndre Fischer ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage); 386*02c50d82SAndre Fischer 387*02c50d82SAndre Fischer // Now that the styles are available we can insert the cloned 388*02c50d82SAndre Fischer // master page. 389*02c50d82SAndre Fischer rTargetDocument.InsertMasterPage (pClonedMasterPage, nInsertionIndex); 390*02c50d82SAndre Fischer 391*02c50d82SAndre Fischer // Adapt the size of the new master page to that of the pages in 392*02c50d82SAndre Fischer // the document. 393*02c50d82SAndre Fischer Size aNewSize (rTargetDocument.GetSdPage(0, pMasterPage->GetPageKind())->GetSize()); 394*02c50d82SAndre Fischer Rectangle aBorders ( 395*02c50d82SAndre Fischer pClonedMasterPage->GetLftBorder(), 396*02c50d82SAndre Fischer pClonedMasterPage->GetUppBorder(), 397*02c50d82SAndre Fischer pClonedMasterPage->GetRgtBorder(), 398*02c50d82SAndre Fischer pClonedMasterPage->GetLwrBorder()); 399*02c50d82SAndre Fischer pClonedMasterPage->ScaleObjects(aNewSize, aBorders, sal_True); 400*02c50d82SAndre Fischer pClonedMasterPage->SetSize(aNewSize); 401*02c50d82SAndre Fischer pClonedMasterPage->CreateTitleAndLayout(sal_True); 402*02c50d82SAndre Fischer } 403*02c50d82SAndre Fischer } 404*02c50d82SAndre Fischer 405*02c50d82SAndre Fischer return pClonedMasterPage; 406*02c50d82SAndre Fischer } 407*02c50d82SAndre Fischer 408*02c50d82SAndre Fischer 409*02c50d82SAndre Fischer 410*02c50d82SAndre Fischer 411*02c50d82SAndre Fischer /** In here we have to handle three cases: 412*02c50d82SAndre Fischer 1. pPage is a normal slide. We can use SetMasterPage to assign the 413*02c50d82SAndre Fischer master pages to it. 414*02c50d82SAndre Fischer 2. pPage is a master page that is used by at least one slide. We can 415*02c50d82SAndre Fischer assign the master page to these slides. 416*02c50d82SAndre Fischer 3. pPage is a master page that is currently not used by any slide. 417*02c50d82SAndre Fischer We can delete that page and add copies of the given master pages 418*02c50d82SAndre Fischer instead. 419*02c50d82SAndre Fischer 420*02c50d82SAndre Fischer For points 2 and 3 where one master page A is assigned to another B we have 421*02c50d82SAndre Fischer to keep in mind that the master page that page A has already been 422*02c50d82SAndre Fischer inserted into the target document. 423*02c50d82SAndre Fischer */ 424*02c50d82SAndre Fischer void DocumentHelper::AssignMasterPageToPage ( 425*02c50d82SAndre Fischer SdPage* pMasterPage, 426*02c50d82SAndre Fischer const String& rsBaseLayoutName, 427*02c50d82SAndre Fischer SdPage* pPage) 428*02c50d82SAndre Fischer { 429*02c50d82SAndre Fischer // Leave early when the parameters are invalid. 430*02c50d82SAndre Fischer if (pPage == NULL || pMasterPage == NULL) 431*02c50d82SAndre Fischer return; 432*02c50d82SAndre Fischer SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel()); 433*02c50d82SAndre Fischer if (pDocument == NULL) 434*02c50d82SAndre Fischer return; 435*02c50d82SAndre Fischer 436*02c50d82SAndre Fischer if ( ! pPage->IsMasterPage()) 437*02c50d82SAndre Fischer { 438*02c50d82SAndre Fischer // 1. Remove the background object (so that that, if it exists, does 439*02c50d82SAndre Fischer // not override the new master page) and assign the master page to 440*02c50d82SAndre Fischer // the regular slide. 441*02c50d82SAndre Fischer pDocument->GetDocSh()->GetUndoManager()->AddUndoAction( 442*02c50d82SAndre Fischer new SdBackgroundObjUndoAction( 443*02c50d82SAndre Fischer *pDocument, *pPage, pPage->getSdrPageProperties().GetItemSet()), 444*02c50d82SAndre Fischer sal_True); 445*02c50d82SAndre Fischer pPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_NONE)); 446*02c50d82SAndre Fischer 447*02c50d82SAndre Fischer pDocument->SetMasterPage ( 448*02c50d82SAndre Fischer (pPage->GetPageNum()-1)/2, 449*02c50d82SAndre Fischer rsBaseLayoutName, 450*02c50d82SAndre Fischer pDocument, 451*02c50d82SAndre Fischer sal_False, 452*02c50d82SAndre Fischer sal_False); 453*02c50d82SAndre Fischer } 454*02c50d82SAndre Fischer else 455*02c50d82SAndre Fischer { 456*02c50d82SAndre Fischer // Find first slide that uses the master page. 457*02c50d82SAndre Fischer SdPage* pSlide = NULL; 458*02c50d82SAndre Fischer sal_uInt16 nPageCount = pDocument->GetSdPageCount(PK_STANDARD); 459*02c50d82SAndre Fischer for (sal_uInt16 nPage=0; nPage<nPageCount&&pSlide==NULL; nPage++) 460*02c50d82SAndre Fischer { 461*02c50d82SAndre Fischer SdrPage* pCandidate = pDocument->GetSdPage(nPage,PK_STANDARD); 462*02c50d82SAndre Fischer if (pCandidate != NULL 463*02c50d82SAndre Fischer && pCandidate->TRG_HasMasterPage() 464*02c50d82SAndre Fischer && &(pCandidate->TRG_GetMasterPage()) == pPage) 465*02c50d82SAndre Fischer { 466*02c50d82SAndre Fischer pSlide = static_cast<SdPage*>(pCandidate); 467*02c50d82SAndre Fischer } 468*02c50d82SAndre Fischer } 469*02c50d82SAndre Fischer 470*02c50d82SAndre Fischer if (pSlide != NULL) 471*02c50d82SAndre Fischer { 472*02c50d82SAndre Fischer // 2. Assign the given master pages to the first slide that was 473*02c50d82SAndre Fischer // found above that uses the master page. 474*02c50d82SAndre Fischer pDocument->SetMasterPage ( 475*02c50d82SAndre Fischer (pSlide->GetPageNum()-1)/2, 476*02c50d82SAndre Fischer rsBaseLayoutName, 477*02c50d82SAndre Fischer pDocument, 478*02c50d82SAndre Fischer sal_False, 479*02c50d82SAndre Fischer sal_False); 480*02c50d82SAndre Fischer } 481*02c50d82SAndre Fischer else 482*02c50d82SAndre Fischer { 483*02c50d82SAndre Fischer // 3. Replace the master page A by a copy of the given master 484*02c50d82SAndre Fischer // page B. 485*02c50d82SAndre Fischer pDocument->RemoveUnnecessaryMasterPages ( 486*02c50d82SAndre Fischer pPage, sal_False); 487*02c50d82SAndre Fischer } 488*02c50d82SAndre Fischer } 489*02c50d82SAndre Fischer } 490*02c50d82SAndre Fischer 491*02c50d82SAndre Fischer 492*02c50d82SAndre Fischer 493*02c50d82SAndre Fischer 494*02c50d82SAndre Fischer SdPage* DocumentHelper::ProvideMasterPage ( 495*02c50d82SAndre Fischer SdDrawDocument& rTargetDocument, 496*02c50d82SAndre Fischer SdPage* pMasterPage, 497*02c50d82SAndre Fischer const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) 498*02c50d82SAndre Fischer { 499*02c50d82SAndre Fischer // Make sure that both the master page and its notes master exist 500*02c50d82SAndre Fischer // in the source document. If one is missing then return without 501*02c50d82SAndre Fischer // making any changes. 502*02c50d82SAndre Fischer if (pMasterPage == NULL) 503*02c50d82SAndre Fischer { 504*02c50d82SAndre Fischer // The caller should make sure that the master page is valid. 505*02c50d82SAndre Fischer OSL_ASSERT(pMasterPage != NULL); 506*02c50d82SAndre Fischer return NULL; 507*02c50d82SAndre Fischer } 508*02c50d82SAndre Fischer SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); 509*02c50d82SAndre Fischer if (pSourceDocument == NULL) 510*02c50d82SAndre Fischer return NULL; 511*02c50d82SAndre Fischer SdPage* pNotesMasterPage = static_cast<SdPage*>( 512*02c50d82SAndre Fischer pSourceDocument->GetMasterPage(pMasterPage->GetPageNum()+1)); 513*02c50d82SAndre Fischer if (pNotesMasterPage == NULL) 514*02c50d82SAndre Fischer { 515*02c50d82SAndre Fischer // The model is not in a valid state. Maybe a new master page 516*02c50d82SAndre Fischer // is being (not finished yet) created? Return without making 517*02c50d82SAndre Fischer // any changes. 518*02c50d82SAndre Fischer return NULL; 519*02c50d82SAndre Fischer } 520*02c50d82SAndre Fischer 521*02c50d82SAndre Fischer SdPage* pMasterPageInDocument = NULL; 522*02c50d82SAndre Fischer // Search for a master page with the same name as the given one in 523*02c50d82SAndre Fischer // the target document. 524*02c50d82SAndre Fischer const XubString sMasterPageLayoutName (pMasterPage->GetLayoutName()); 525*02c50d82SAndre Fischer for (sal_uInt16 nIndex=0,nCount=rTargetDocument.GetMasterPageCount(); nIndex<nCount; ++nIndex) 526*02c50d82SAndre Fischer { 527*02c50d82SAndre Fischer SdPage* pCandidate = static_cast<SdPage*>(rTargetDocument.GetMasterPage(nIndex)); 528*02c50d82SAndre Fischer if (pCandidate!=NULL 529*02c50d82SAndre Fischer && sMasterPageLayoutName==pCandidate->GetLayoutName()) 530*02c50d82SAndre Fischer { 531*02c50d82SAndre Fischer // The requested master page does already exist in the 532*02c50d82SAndre Fischer // target document, return it. 533*02c50d82SAndre Fischer return pCandidate; 534*02c50d82SAndre Fischer } 535*02c50d82SAndre Fischer } 536*02c50d82SAndre Fischer 537*02c50d82SAndre Fischer // The given master page does not already belong to the target 538*02c50d82SAndre Fischer // document so we have to create copies and insert them into the 539*02c50d82SAndre Fischer // targer document. 540*02c50d82SAndre Fischer 541*02c50d82SAndre Fischer // Determine the position where the new master pages are inserted. 542*02c50d82SAndre Fischer // By default they are inserted at the end. When we assign to a 543*02c50d82SAndre Fischer // master page then insert after the last of the (selected) pages. 544*02c50d82SAndre Fischer sal_uInt16 nInsertionIndex = rTargetDocument.GetMasterPageCount(); 545*02c50d82SAndre Fischer if (rpPageList->front()->IsMasterPage()) 546*02c50d82SAndre Fischer { 547*02c50d82SAndre Fischer nInsertionIndex = rpPageList->back()->GetPageNum(); 548*02c50d82SAndre Fischer } 549*02c50d82SAndre Fischer 550*02c50d82SAndre Fischer // Clone the master page. 551*02c50d82SAndre Fischer if (pMasterPage->GetModel() != &rTargetDocument) 552*02c50d82SAndre Fischer { 553*02c50d82SAndre Fischer pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex); 554*02c50d82SAndre Fischer if( rTargetDocument.IsUndoEnabled() ) 555*02c50d82SAndre Fischer rTargetDocument.AddUndo( 556*02c50d82SAndre Fischer rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument)); 557*02c50d82SAndre Fischer } 558*02c50d82SAndre Fischer else 559*02c50d82SAndre Fischer pMasterPageInDocument = pMasterPage; 560*02c50d82SAndre Fischer 561*02c50d82SAndre Fischer // Clone the notes master. 562*02c50d82SAndre Fischer if (pNotesMasterPage->GetModel() != &rTargetDocument) 563*02c50d82SAndre Fischer { 564*02c50d82SAndre Fischer SdPage* pClonedNotesMasterPage 565*02c50d82SAndre Fischer = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1); 566*02c50d82SAndre Fischer if( rTargetDocument.IsUndoEnabled() ) 567*02c50d82SAndre Fischer rTargetDocument.AddUndo( 568*02c50d82SAndre Fischer rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage)); 569*02c50d82SAndre Fischer } 570*02c50d82SAndre Fischer 571*02c50d82SAndre Fischer return pMasterPageInDocument; 572*02c50d82SAndre Fischer } 573*02c50d82SAndre Fischer 574*02c50d82SAndre Fischer 575*02c50d82SAndre Fischer 576*02c50d82SAndre Fischer 577*02c50d82SAndre Fischer 578*02c50d82SAndre Fischer } } // end of namespace sd::sidebar 579