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