xref: /AOO41X/main/sd/source/ui/sidebar/DocumentHelper.cxx (revision 02c50d825b93d3e4e3bd9073db30bd7615e748eb)
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