xref: /AOO41X/main/sd/source/core/drawdoc2.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 
28 #include <com/sun/star/embed/XVisualObject.hpp>
29 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
30 #include <vcl/wrkwin.hxx>
31 #include <sfx2/printer.hxx>
32 #include <sfx2/app.hxx>
33 #ifndef SD_OUTLINE_HXX
34 #include "Outliner.hxx"
35 #endif
36 #include <editeng/paperinf.hxx>
37 #include <svx/svdopage.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svx/svdotext.hxx>
40 #include <svx/svdograf.hxx>
41 #include <svx/svdundo.hxx>
42 #include <vcl/svapp.hxx>
43 #include <editeng/eeitem.hxx>
44 #include <editeng/langitem.hxx>
45 #include <svl/itempool.hxx>
46 #include <svx/svdpool.hxx>
47 #include <editeng/flditem.hxx>
48 
49 #include <sfx2/linkmgr.hxx>
50 #include <editeng/editdata.hxx>
51 #include <svx/dialogs.hrc>
52 #include <svx/dialmgr.hxx>                  // SVX_RESSTR
53 
54 #include "eetext.hxx"
55 #include <svx/svditer.hxx>
56 #include <svtools/imapobj.hxx>
57 
58 
59 #include "sdresid.hxx"
60 #include "drawdoc.hxx"
61 #include "sdpage.hxx"
62 #include "pglink.hxx"
63 #include "glob.hrc"
64 #include "glob.hxx"
65 #include "stlpool.hxx"
66 #include "sdiocmpt.hxx"
67 #include "anminfo.hxx"
68 #include "imapinfo.hxx"
69 #include "cusshow.hxx"
70 #include "undo/undomanager.hxx"
71 
72 #include "../ui/inc/DrawDocShell.hxx"
73 #include "../ui/inc/FrameView.hxx"
74 #include "../ui/inc/cfgids.hxx"
75 #include "../ui/inc/strings.hrc"
76 
77 #include "PageListWatcher.hxx"
78 #include <vcl/virdev.hxx>
79 
80 using namespace ::sd;
81 
82 const long PRINT_OFFSET = 30;       // siehe \svx\source\dialog\page.cxx (PB)
83 
84 using namespace com::sun::star;
85 
86 /*************************************************************************
87 |*
88 |* Sucht ein Objekt per Name
89 |*
90 \************************************************************************/
91 
GetObj(const String & rObjName) const92 SdrObject* SdDrawDocument::GetObj(const String& rObjName) const
93 {
94     SdrObject* pObj = NULL;
95     SdrObject* pObjFound = NULL;
96     SdPage* pPage = NULL;
97 
98     /**************************************************************************
99     * Zuerst alle Pages durchsuchen
100     **************************************************************************/
101     sal_uInt16 nPage = 0;
102     const sal_uInt16 nMaxPages = GetPageCount();
103 
104     while (nPage < nMaxPages && !pObjFound)
105     {
106         pPage = (SdPage*) GetPage(nPage);
107         SdrObjListIter aIter(*pPage, IM_DEEPWITHGROUPS);
108 
109         while (aIter.IsMore() && !pObjFound)
110         {
111             pObj = aIter.Next();
112 
113             if( ( rObjName == pObj->GetName() ) ||
114                 ( SdrInventor == pObj->GetObjInventor() &&
115                   OBJ_OLE2 == pObj->GetObjIdentifier() &&
116                   rObjName == static_cast< SdrOle2Obj* >( pObj )->GetPersistName() ) )
117             {
118                 pObjFound = pObj;
119             }
120         }
121 
122         nPage++;
123     }
124 
125     /**************************************************************************
126     * Wenn nicht gefunden, dann alle MasterPages durchsuchen
127     **************************************************************************/
128     nPage = 0;
129     const sal_uInt16 nMaxMasterPages = GetMasterPageCount();
130 
131     while (nPage < nMaxMasterPages && !pObjFound)
132     {
133         pPage = (SdPage*) GetMasterPage(nPage);
134         SdrObjListIter aIter(*pPage, IM_DEEPWITHGROUPS);
135 
136         while (aIter.IsMore() && !pObjFound)
137         {
138             pObj = aIter.Next();
139 
140             if( ( rObjName == pObj->GetName() ) ||
141                 ( SdrInventor == pObj->GetObjInventor() &&
142                   OBJ_OLE2 == pObj->GetObjIdentifier() &&
143                   rObjName == static_cast< SdrOle2Obj* >( pObj )->GetPersistName() ) )
144             {
145                 pObjFound = pObj;
146             }
147         }
148 
149         nPage++;
150     }
151 
152     return (pObjFound);
153 }
154 
155 
156 /*************************************************************************
157 |*
158 |* Sucht die SdPage per Name
159 |*
160 \************************************************************************/
161 
GetPageByName(const String & rPgName,sal_Bool & rbIsMasterPage) const162 sal_uInt16 SdDrawDocument::GetPageByName(const String& rPgName, sal_Bool& rbIsMasterPage) const
163 {
164     SdPage* pPage = NULL;
165     sal_uInt16 nPage = 0;
166     const sal_uInt16 nMaxPages = GetPageCount();
167     sal_uInt16 nPageNum = SDRPAGE_NOTFOUND;
168 
169     rbIsMasterPage = sal_False;
170 
171     // Search all regular pages and all notes pages (handout pages are
172     // ignored.)
173     while (nPage < nMaxPages && nPageNum == SDRPAGE_NOTFOUND)
174     {
175         pPage = const_cast<SdPage*>(static_cast<const SdPage*>(
176             GetPage(nPage)));
177 
178         if (pPage != NULL
179             && pPage->GetPageKind() != PK_HANDOUT
180             && pPage->GetName() == rPgName)
181         {
182             nPageNum = nPage;
183         }
184 
185         nPage++;
186     }
187 
188     // Search all master pages when not found among non-master pages.
189     const sal_uInt16 nMaxMasterPages = GetMasterPageCount();
190     nPage = 0;
191 
192     while (nPage < nMaxMasterPages && nPageNum == SDRPAGE_NOTFOUND)
193     {
194         pPage = const_cast<SdPage*>(static_cast<const SdPage*>(
195             GetMasterPage(nPage)));
196 
197         if (pPage && pPage->GetName() == rPgName)
198         {
199             nPageNum = nPage;
200             rbIsMasterPage = sal_True;
201         }
202 
203         nPage++;
204     }
205 
206     return nPageNum;
207 }
208 
209 
210 /*************************************************************************
211 |*
212 |*
213 |*
214 \************************************************************************/
215 
GetSdPage(sal_uInt16 nPgNum,PageKind ePgKind) const216 SdPage* SdDrawDocument::GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
217 {
218     // #109538#
219     return mpDrawPageListWatcher->GetSdPage(ePgKind, sal_uInt32(nPgNum));
220 }
221 
222 /*************************************************************************
223 |*
224 |*
225 |*
226 \************************************************************************/
227 
GetSdPageCount(PageKind ePgKind) const228 sal_uInt16 SdDrawDocument::GetSdPageCount(PageKind ePgKind) const
229 {
230     // #109538#
231     return (sal_uInt16)mpDrawPageListWatcher->GetSdPageCount(ePgKind);
232 }
233 
234 /*************************************************************************
235 |*
236 |*
237 |*
238 \************************************************************************/
239 
GetMasterSdPage(sal_uInt16 nPgNum,PageKind ePgKind)240 SdPage* SdDrawDocument::GetMasterSdPage(sal_uInt16 nPgNum, PageKind ePgKind)
241 {
242     // #109538#
243     return mpMasterPageListWatcher->GetSdPage(ePgKind, sal_uInt32(nPgNum));
244 }
245 
246 /*************************************************************************
247 |*
248 |*
249 |*
250 \************************************************************************/
251 
GetMasterSdPageCount(PageKind ePgKind) const252 sal_uInt16 SdDrawDocument::GetMasterSdPageCount(PageKind ePgKind) const
253 {
254     // #109538#
255     return (sal_uInt16)mpMasterPageListWatcher->GetSdPageCount(ePgKind);
256 }
257 
258 /*************************************************************************
259 |*
260 |*  die in den Seitenobjekten der Notizseiten eingetragenen
261 |*  Seitennummern anpassen
262 |*
263 \************************************************************************/
264 
UpdatePageObjectsInNotes(sal_uInt16 nStartPos)265 void SdDrawDocument::UpdatePageObjectsInNotes(sal_uInt16 nStartPos)
266 {
267     sal_uInt16  nPageCount  = GetPageCount();
268     SdPage* pPage       = NULL;
269 
270     for (sal_uInt16 nPage = nStartPos; nPage < nPageCount; nPage++)
271     {
272         pPage = (SdPage*)GetPage(nPage);
273 
274         // wenn es eine Notizseite ist, Seitenobjekt suchen
275         // und Nummer korrigieren
276         if (pPage && pPage->GetPageKind() == PK_NOTES)
277         {
278             sal_uLong nObjCount = pPage->GetObjCount();
279             SdrObject* pObj = NULL;
280             for (sal_uLong nObj = 0; nObj < nObjCount; nObj++)
281             {
282                 pObj = pPage->GetObj(nObj);
283                 if (pObj->GetObjIdentifier() == OBJ_PAGE &&
284                     pObj->GetObjInventor() == SdrInventor)
285                 {
286                     // das Seitenobjekt stellt die vorhergende Seite (also
287                     // die Zeichenseite) dar
288                     DBG_ASSERTWARNING(nStartPos, "Notizseitenpos. darf nicht 0 sein");
289 
290                     DBG_ASSERTWARNING(nPage > 1, "Seitenobjekt darf nicht Handzettel darstellen");
291 
292                     if (nStartPos > 0 && nPage > 1)
293                         ((SdrPageObj*)pObj)->SetReferencedPage(GetPage(nPage - 1));
294                 }
295             }
296         }
297     }
298 }
299 
UpdatePageRelativeURLs(const String & rOldName,const String & rNewName)300 void SdDrawDocument::UpdatePageRelativeURLs(const String& rOldName, const String& rNewName)
301 {
302     if (rNewName.Len() == 0)
303         return;
304 
305     SfxItemPool& pPool(GetPool());
306     sal_uInt32 nCount = pPool.GetItemCount2(EE_FEATURE_FIELD);
307     for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
308     {
309         const SfxPoolItem *pItem = pPool.GetItem2(EE_FEATURE_FIELD, nOff);
310         const SvxFieldItem* pFldItem = dynamic_cast< const SvxFieldItem * > (pItem);
311 
312         if(pFldItem)
313         {
314             SvxURLField* pURLField = const_cast< SvxURLField* >( dynamic_cast<const SvxURLField*>( pFldItem->GetField() ) );
315 
316             if(pURLField)
317             {
318                 XubString aURL = pURLField->GetURL();
319 
320                 if (aURL.Len() && (aURL.GetChar(0) == 35) && (aURL.Search(rOldName, 1) == 1))
321                 {
322                     if (aURL.Len() == rOldName.Len() + 1) // standard page name
323                     {
324                         aURL.Erase (1, aURL.Len() - 1);
325                         aURL += rNewName;
326                         pURLField->SetURL(aURL);
327                     }
328                     else
329                     {
330                         const XubString sNotes = SdResId(STR_NOTES);
331                         if (aURL.Len() == rOldName.Len() + 2 + sNotes.Len() && aURL.Search(sNotes, rOldName.Len() + 2) == rOldName.Len() + 2)
332                         {
333                             aURL.Erase (1, aURL.Len() - 1);
334                             aURL += rNewName;
335                             aURL += ' ';
336                             aURL += sNotes;
337                             pURLField->SetURL(aURL);
338                         }
339                     }
340                 }
341             }
342         }
343     }
344 }
345 
UpdatePageRelativeURLs(SdPage * pPage,sal_uInt16 nPos,sal_Int32 nIncrement)346 void SdDrawDocument::UpdatePageRelativeURLs(SdPage* pPage, sal_uInt16 nPos, sal_Int32 nIncrement)
347 {
348     bool bNotes = (pPage->GetPageKind() == PK_NOTES);
349 
350     SfxItemPool& pPool(GetPool());
351     sal_uInt32 nCount = pPool.GetItemCount2(EE_FEATURE_FIELD);
352     for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
353     {
354         const SfxPoolItem *pItem = pPool.GetItem2(EE_FEATURE_FIELD, nOff);
355         const SvxFieldItem* pFldItem;
356 
357         if ((pFldItem = dynamic_cast< const SvxFieldItem * > (pItem)) != 0)
358         {
359             SvxURLField* pURLField = const_cast< SvxURLField* >( dynamic_cast<const SvxURLField*>( pFldItem->GetField() ) );
360 
361             if(pURLField)
362             {
363                 XubString aURL = pURLField->GetURL();
364 
365                 if (aURL.Len() && (aURL.GetChar(0) == 35))
366                 {
367                     XubString aHashSlide('#');
368                     aHashSlide += SdResId(STR_PAGE);
369 
370                     if (aURL.CompareTo(aHashSlide, aHashSlide.Len()) == COMPARE_EQUAL)
371                     {
372                         XubString aURLCopy = aURL;
373                         const XubString sNotes = SdResId(STR_NOTES);
374 
375                         aURLCopy.Erase(0, aHashSlide.Len());
376 
377                         bool bNotesLink = (aURLCopy.Len() >= sNotes.Len() + 3 && aURLCopy.Search(sNotes, aURLCopy.Len() - sNotes.Len()) == aURLCopy.Len() - sNotes.Len());
378 
379                         if (bNotesLink ^ bNotes)
380                             continue; // no compatible link and page
381 
382                         if (bNotes)
383                             aURLCopy.Erase(aURLCopy.Len() - sNotes.Len(), sNotes.Len());
384 
385                         sal_Int32 number = aURLCopy.ToInt32();
386                         sal_uInt16 realPageNumber = (nPos + 1)/ 2;
387 
388                         if ( number >= realPageNumber )
389                         {
390                             // update link page number
391                             number += nIncrement;
392                             aURL.Erase (aHashSlide.Len() + 1, aURL.Len() - aHashSlide.Len() - 1);
393                             aURL += XubString::CreateFromInt32(number);
394                             if (bNotes)
395                             {
396                                 aURL += ' ';
397                                 aURL += sNotes;
398                             }
399                             pURLField->SetURL(aURL);
400                         }
401                     }
402                 }
403             }
404         }
405     }
406 }
407 
408 /*************************************************************************
409 |*
410 |*  Seite verschieben
411 |*
412 \************************************************************************/
413 
MovePage(sal_uInt16 nPgNum,sal_uInt16 nNewPos)414 void SdDrawDocument::MovePage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
415 {
416     // Seite verschieben
417     FmFormModel::MovePage(nPgNum, nNewPos);
418 
419     sal_uInt16 nMin = Min(nPgNum, nNewPos);
420 
421     UpdatePageObjectsInNotes(nMin);
422 }
423 
424 /*************************************************************************
425 |*
426 |*  Seite einfuegen
427 |*
428 \************************************************************************/
429 
InsertPage(SdrPage * pPage,sal_uInt16 nPos)430 void SdDrawDocument::InsertPage(SdrPage* pPage, sal_uInt16 nPos)
431 {
432     bool bLast = (nPos == GetPageCount());
433 
434     FmFormModel::InsertPage(pPage, nPos);
435 
436     ((SdPage*)pPage)->ConnectLink();
437 
438     UpdatePageObjectsInNotes(nPos);
439 
440     if (!bLast)
441         UpdatePageRelativeURLs(static_cast<SdPage*>( pPage ), nPos, 1);
442 
443 }
444 
445 /*************************************************************************
446 |*
447 |*  Seite loeschen
448 |*
449 \************************************************************************/
450 
DeletePage(sal_uInt16 nPgNum)451 void SdDrawDocument::DeletePage(sal_uInt16 nPgNum)
452 {
453     FmFormModel::DeletePage(nPgNum);
454 
455     UpdatePageObjectsInNotes(nPgNum);
456 }
457 
458 /*************************************************************************
459 |*
460 |*  Seite entfernen
461 |*
462 \************************************************************************/
463 
RemovePage(sal_uInt16 nPgNum)464 SdrPage* SdDrawDocument::RemovePage(sal_uInt16 nPgNum)
465 {
466     SdrPage* pPage = FmFormModel::RemovePage(nPgNum);
467 
468     bool bLast = ((nPgNum+1)/2 == (GetPageCount()+1)/2);
469 
470     ((SdPage*)pPage)->DisconnectLink();
471     ReplacePageInCustomShows( dynamic_cast< SdPage* >( pPage ), 0 );
472     UpdatePageObjectsInNotes(nPgNum);
473 
474     if (!bLast)
475         UpdatePageRelativeURLs((SdPage*)pPage, nPgNum, -1);
476 
477     return pPage;
478 }
479 
480 // Warning: This is not called for new master pages created from SdrModel::Merge,
481 // you also have to modify code in SdDrawDocument::Merge!
InsertMasterPage(SdrPage * pPage,sal_uInt16 nPos)482 void SdDrawDocument::InsertMasterPage(SdrPage* pPage, sal_uInt16 nPos )
483 {
484     FmFormModel::InsertMasterPage( pPage, nPos );
485     if( pPage && pPage->IsMasterPage() && (static_cast<SdPage*>(pPage)->GetPageKind() == PK_STANDARD) )
486     {
487         // new master page created, add its style family
488         SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
489         if( pStylePool )
490             pStylePool->AddStyleFamily( static_cast<SdPage*>(pPage) );
491     }
492 }
493 
RemoveMasterPage(sal_uInt16 nPgNum)494 SdrPage* SdDrawDocument::RemoveMasterPage(sal_uInt16 nPgNum)
495 {
496     SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPgNum ));
497     if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PK_STANDARD) )
498     {
499         // master page removed, remove its style family
500         SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
501         if( pStylePool )
502             pStylePool->RemoveStyleFamily( pPage );
503     }
504 
505     return FmFormModel::RemoveMasterPage(nPgNum);
506 }
507 
508 /*************************************************************************
509 |*
510 |* Seiten selektieren
511 |*
512 \************************************************************************/
513 
SetSelected(SdPage * pPage,sal_Bool bSelect)514 void SdDrawDocument::SetSelected(SdPage* pPage, sal_Bool bSelect)
515 {
516     PageKind ePageKind = pPage->GetPageKind();
517 
518     if (ePageKind == PK_STANDARD)
519     {
520         pPage->SetSelected(bSelect);
521 
522         const sal_uInt16 nDestPageNum(pPage->GetPageNum() + 1);
523         SdPage* pNotesPage = 0L;
524 
525         if(nDestPageNum < GetPageCount())
526         {
527             pNotesPage = (SdPage*)GetPage(nDestPageNum);
528         }
529 
530         if (pNotesPage && pNotesPage->GetPageKind() == PK_NOTES)
531         {
532             pNotesPage->SetSelected(bSelect);
533         }
534     }
535     else if (ePageKind == PK_NOTES)
536     {
537         pPage->SetSelected(bSelect);
538         SdPage* pStandardPage = (SdPage*) GetPage( pPage->GetPageNum() - 1 );
539 
540         if (pStandardPage && pStandardPage->GetPageKind() == PK_STANDARD)
541             pStandardPage->SetSelected(bSelect);
542     }
543 }
544 
545 /*************************************************************************
546 |*
547 |* Sofern noch keine Seiten vorhanden sind, werden nun Seiten erzeugt
548 |*
549 \************************************************************************/
550 
CreateFirstPages(SdDrawDocument * pRefDocument)551 void SdDrawDocument::CreateFirstPages( SdDrawDocument* pRefDocument /* = 0 */ )
552 {
553     /**************************************************************************
554     * Wenn noch keine Seite im Model vorhanden ist (Datei-Neu), wird
555     * eine neue Seite eingefuegt
556     **************************************************************************/
557     sal_uInt16 nPageCount = GetPageCount();
558 
559     if (nPageCount <= 1)
560     {
561         // #i57181# Paper size depends on Language, like in Writer
562         Size aDefSize = SvxPaperInfo::GetDefaultPaperSize( MAP_100TH_MM );
563 
564         /**********************************************************************
565         * Handzettel-Seite einfuegen
566         **********************************************************************/
567         sal_Bool bMasterPage;
568         SdPage* pHandoutPage = dynamic_cast< SdPage* >( AllocPage(bMasterPage=sal_False) );
569 
570         SdPage* pRefPage = NULL;
571 
572         if( pRefDocument )
573             pRefPage = pRefDocument->GetSdPage( 0, PK_HANDOUT );
574 
575         if( pRefPage )
576         {
577             pHandoutPage->SetSize(pRefPage->GetSize());
578             pHandoutPage->SetBorder( pRefPage->GetLftBorder(), pRefPage->GetUppBorder(), pRefPage->GetRgtBorder(), pRefPage->GetLwrBorder() );
579         }
580         else
581         {
582             pHandoutPage->SetSize(aDefSize);
583             pHandoutPage->SetBorder(0, 0, 0, 0);
584         }
585 
586         pHandoutPage->SetPageKind(PK_HANDOUT);
587         pHandoutPage->SetName( String (SdResId(STR_HANDOUT) ) );
588         InsertPage(pHandoutPage, 0);
589 
590         /**********************************************************************
591         * MasterPage einfuegen und an der Handzettel-Seite vermerken
592         **********************************************************************/
593         SdPage* pHandoutMPage = (SdPage*) AllocPage(bMasterPage=sal_True);
594         pHandoutMPage->SetSize( pHandoutPage->GetSize() );
595         pHandoutMPage->SetPageKind(PK_HANDOUT);
596         pHandoutMPage->SetBorder( pHandoutPage->GetLftBorder(),
597                                   pHandoutPage->GetUppBorder(),
598                                   pHandoutPage->GetRgtBorder(),
599                                   pHandoutPage->GetLwrBorder() );
600         InsertMasterPage(pHandoutMPage, 0);
601         pHandoutPage->TRG_SetMasterPage( *pHandoutMPage );
602 
603         /**********************************************************************
604         * Seite einfuegen
605         * Sofern nPageCount==1 ist, wurde das Model fuers Clipboad erzeugt.
606         * Eine Standard-Seite ist daher schon vorhanden.
607         **********************************************************************/
608         SdPage* pPage;
609         sal_Bool bClipboard = sal_False;
610 
611         if( pRefDocument )
612             pRefPage = pRefDocument->GetSdPage( 0, PK_STANDARD );
613 
614         if (nPageCount == 0)
615         {
616             pPage = dynamic_cast< SdPage* >( AllocPage(bMasterPage=sal_False) );
617 
618             if( pRefPage )
619             {
620                 pPage->SetSize( pRefPage->GetSize() );
621                 pPage->SetBorder( pRefPage->GetLftBorder(), pRefPage->GetUppBorder(), pRefPage->GetRgtBorder(), pRefPage->GetLwrBorder() );
622             }
623             else if (meDocType == DOCUMENT_TYPE_DRAW)
624             {
625                 // Draw: stets Default-Groesse mit Raendern
626                 pPage->SetSize(aDefSize);
627 
628                 SfxPrinter* pPrinter = mpDocSh->GetPrinter(sal_False);
629                 if (pPrinter && pPrinter->IsValid())
630                 {
631                     Size aOutSize(pPrinter->GetOutputSize());
632                     Point aPageOffset(pPrinter->GetPageOffset());
633                     aPageOffset -= pPrinter->PixelToLogic( Point() );
634                     long nOffset = !aPageOffset.X() && !aPageOffset.X() ? 0 : PRINT_OFFSET;
635 
636                     sal_uLong nTop    = aPageOffset.Y();
637                     sal_uLong nLeft   = aPageOffset.X();
638                     sal_uLong nBottom = Max((long)(aDefSize.Height() - aOutSize.Height() - nTop + nOffset), 0L);
639                     sal_uLong nRight  = Max((long)(aDefSize.Width() - aOutSize.Width() - nLeft + nOffset), 0L);
640 
641                     pPage->SetBorder(nLeft, nTop, nRight, nBottom);
642                 }
643                 else
644                 {
645                     // The printer is not available.  Use a border of 10mm
646                     // on each side instead.
647                     // This has to be kept synchronized with the border
648                     // width set in the
649                     // SvxPageDescPage::PaperSizeSelect_Impl callback.
650                     pPage->SetBorder(1000, 1000, 1000, 1000);
651                 }
652             }
653             else
654             {
655                 // Impress: stets Bildschirmformat, quer
656                 Size aSz( SvxPaperInfo::GetPaperSize(PAPER_SCREEN, MAP_100TH_MM) );
657                 pPage->SetSize( Size( aSz.Height(), aSz.Width() ) );
658                 pPage->SetBorder(0, 0, 0, 0);
659             }
660 
661             InsertPage(pPage, 1);
662         }
663         else
664         {
665             bClipboard = sal_True;
666             pPage = (SdPage*) GetPage(1);
667         }
668 
669         /**********************************************************************
670         * MasterPage einfuegen und an der Seite vermerken
671         **********************************************************************/
672         SdPage* pMPage = (SdPage*) AllocPage(bMasterPage=sal_True);
673         pMPage->SetSize( pPage->GetSize() );
674         pMPage->SetBorder( pPage->GetLftBorder(),
675                            pPage->GetUppBorder(),
676                            pPage->GetRgtBorder(),
677                            pPage->GetLwrBorder() );
678         InsertMasterPage(pMPage, 1);
679         pPage->TRG_SetMasterPage( *pMPage );
680         if( bClipboard )
681             pMPage->SetLayoutName( pPage->GetLayoutName() );
682 
683         /**********************************************************************
684         * Notizen-Seite einfuegen
685         **********************************************************************/
686         SdPage* pNotesPage = (SdPage*) AllocPage(bMasterPage=sal_False);
687 
688         if( pRefDocument )
689             pRefPage = pRefDocument->GetSdPage( 0, PK_NOTES );
690 
691         if( pRefPage )
692         {
693             pNotesPage->SetSize( pRefPage->GetSize() );
694             pNotesPage->SetBorder( pRefPage->GetLftBorder(), pRefPage->GetUppBorder(), pRefPage->GetRgtBorder(), pRefPage->GetLwrBorder() );
695         }
696         else
697         {
698             // Stets Hochformat
699             if (aDefSize.Height() >= aDefSize.Width())
700             {
701                 pNotesPage->SetSize(aDefSize);
702             }
703             else
704             {
705                 pNotesPage->SetSize( Size(aDefSize.Height(), aDefSize.Width()) );
706             }
707 
708             pNotesPage->SetBorder(0, 0, 0, 0);
709         }
710         pNotesPage->SetPageKind(PK_NOTES);
711         InsertPage(pNotesPage, 2);
712         if( bClipboard )
713             pNotesPage->SetLayoutName( pPage->GetLayoutName() );
714 
715         /**********************************************************************
716         * MasterPage einfuegen und an der Notizen-Seite vermerken
717         **********************************************************************/
718         SdPage* pNotesMPage = (SdPage*) AllocPage(bMasterPage=sal_True);
719         pNotesMPage->SetSize( pNotesPage->GetSize() );
720         pNotesMPage->SetPageKind(PK_NOTES);
721         pNotesMPage->SetBorder( pNotesPage->GetLftBorder(),
722                                 pNotesPage->GetUppBorder(),
723                                 pNotesPage->GetRgtBorder(),
724                                 pNotesPage->GetLwrBorder() );
725         InsertMasterPage(pNotesMPage, 2);
726         pNotesPage->TRG_SetMasterPage( *pNotesMPage );
727         if( bClipboard )
728             pNotesMPage->SetLayoutName( pPage->GetLayoutName() );
729 
730 
731         if( !pRefPage && (meDocType != DOCUMENT_TYPE_DRAW) )
732             pPage->SetAutoLayout( AUTOLAYOUT_TITLE, sal_True, sal_True );
733 
734         mpWorkStartupTimer = new Timer();
735         mpWorkStartupTimer->SetTimeoutHdl( LINK(this, SdDrawDocument, WorkStartupHdl) );
736         mpWorkStartupTimer->SetTimeout(2000);
737         mpWorkStartupTimer->Start();
738 
739         SetChanged(sal_False);
740     }
741 }
742 
743 /*************************************************************************
744 |*
745 |* Erzeugt fehlende Notiz und Handzettelseiten (nach PowerPoint-Import)
746 |* Es wird davon ausgegangen, dass mindestens eine Standard-Seite und
747 |* eine Standard-MasterPage vorhanden sind.
748 |*
749 \************************************************************************/
750 
CreateMissingNotesAndHandoutPages()751 sal_Bool SdDrawDocument::CreateMissingNotesAndHandoutPages()
752 {
753     sal_Bool bOK = sal_False;
754     sal_uInt16 nPageCount = GetPageCount();
755 
756     if (nPageCount != 0)
757     {
758         /**********************************************************************
759         * PageKind setzen
760         **********************************************************************/
761         SdPage* pHandoutMPage = (SdPage*) GetMasterPage(0);
762         pHandoutMPage->SetPageKind(PK_HANDOUT);
763 
764         SdPage* pHandoutPage = (SdPage*) GetPage(0);
765         pHandoutPage->SetPageKind(PK_HANDOUT);
766         pHandoutPage->TRG_SetMasterPage( *pHandoutMPage );
767 
768         for (sal_uInt16 i = 1; i < nPageCount; i = i + 2)
769         {
770             SdPage* pPage = (SdPage*) GetPage(i);
771 
772             if(!pPage->TRG_HasMasterPage())
773             {
774                 // Keine MasterPage gesetzt -> erste Standard-MasterPage nehmen
775                 // (Wenn bei PPT keine Standard-Seite vorhanden war)
776                 pPage->TRG_SetMasterPage(*GetMasterPage(1));
777             }
778 
779             SdPage* pNotesPage = (SdPage*) GetPage(i+1);
780             pNotesPage->SetPageKind(PK_NOTES);
781 
782             // Notiz-MasterPages setzen
783             sal_uInt16 nMasterPageAfterPagesMasterPage = (pPage->TRG_GetMasterPage()).GetPageNum() + 1;
784             pNotesPage->TRG_SetMasterPage(*GetMasterPage(nMasterPageAfterPagesMasterPage));
785         }
786 
787         bOK = sal_True;
788         StopWorkStartupDelay();
789         SetChanged(sal_False);
790     }
791 
792     return(bOK);
793 }
794 
795 /*************************************************************************
796 |*
797 |* - selektierte Seiten hinter genannte Seite schieben
798 |*   (nTargetPage = (sal_uInt16)-1  --> vor erste Seite schieben)
799 |* - ergibt sal_True, wenn Seiten verschoben wurden
800 |*
801 \************************************************************************/
802 
MovePages(sal_uInt16 nTargetPage)803 sal_Bool SdDrawDocument::MovePages(sal_uInt16 nTargetPage)
804 {
805     SdPage* pTargetPage        = NULL;
806     SdPage* pPage              = NULL;
807     sal_uInt16  nPage;
808     sal_uInt16  nNoOfPages         = GetSdPageCount(PK_STANDARD);
809     sal_Bool    bSomethingHappened = sal_False;
810 
811     const bool bUndo = IsUndoEnabled();
812 
813     if( bUndo )
814         BegUndo(String(SdResId(STR_UNDO_MOVEPAGES)));
815 
816     // Liste mit selektierten Seiten
817     List    aPageList;
818     for (nPage = 0; nPage < nNoOfPages; nPage++)
819     {
820         pPage = GetSdPage(nPage, PK_STANDARD);
821         if (pPage->IsSelected())
822         {
823             aPageList.Insert(pPage, LIST_APPEND);
824         }
825     }
826 
827     // falls noetig, nach vorne hangeln, bis nicht selektierte Seite gefunden
828     nPage = nTargetPage;
829     if (nPage != (sal_uInt16)-1)
830     {
831         pPage = GetSdPage(nPage, PK_STANDARD);
832         while (nPage > 0 && pPage->IsSelected())
833         {
834             nPage--;
835             pPage = GetSdPage(nPage, PK_STANDARD);
836         }
837 
838         if (pPage->IsSelected())
839         {
840             nPage = (sal_uInt16)-1;
841         }
842     }
843 
844     // vor der ersten Seite einfuegen
845     if (nPage == (sal_uInt16)-1)
846     {
847         while (aPageList.Count() > 0)
848         {
849             aPageList.Last();
850 
851             nPage = ( (SdPage*) aPageList.GetCurObject() )->GetPageNum();
852             if (nPage != 0)
853             {
854                 SdrPage* pPg = GetPage(nPage);
855                 if( bUndo )
856                     AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, 1));
857                 MovePage(nPage, 1);
858                 pPg = GetPage(nPage+1);
859                 if( bUndo )
860                     AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, 2));
861                 MovePage(nPage+1, 2);
862                 bSomethingHappened = sal_True;
863             }
864             aPageList.Remove();
865         }
866     }
867     // hinter <nPage> einfuegen
868     else
869     {
870         pTargetPage = GetSdPage(nPage, PK_STANDARD);
871         nTargetPage = nPage;
872         nTargetPage = 2 * nTargetPage + 1;    // PK_STANDARD --> absolut
873         while (aPageList.Count() > 0)
874         {
875             pPage = (SdPage*)aPageList.GetObject(0);
876             nPage = pPage->GetPageNum();
877             if (nPage > nTargetPage)
878             {
879                 nTargetPage += 2;        // hinter (!) der Seite einfuegen
880 
881                 if (nPage != nTargetPage)
882                 {
883                     SdrPage* pPg = GetPage(nPage);
884                     if( bUndo )
885                         AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, nTargetPage));
886                     MovePage(nPage, nTargetPage);
887                     pPg = GetPage(nPage+1);
888                     if( bUndo )
889                         AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, nTargetPage+1));
890                     MovePage(nPage+1, nTargetPage+1);
891                     bSomethingHappened = sal_True;
892                 }
893             }
894             else
895             {
896                 if (nPage != nTargetPage)
897                 {
898                     SdrPage* pPg = GetPage(nPage+1);
899                     if( bUndo )
900                         AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage+1, nTargetPage+1));
901                     MovePage(nPage+1, nTargetPage+1);
902                     pPg = GetPage(nPage);
903                     if( bUndo )
904                         AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*pPg, nPage, nTargetPage));
905                     MovePage(nPage, nTargetPage);
906                     bSomethingHappened = sal_True;
907                 }
908             }
909             aPageList.Remove((sal_uLong)0);
910             nTargetPage = pPage->GetPageNum();
911         }
912     }
913 
914     if( bUndo )
915         EndUndo();
916 
917     return bSomethingHappened;
918 }
919 
920 
921 /*************************************************************************
922 |*
923 |* Anzahl der Links im sfx2::LinkManager zurueckgeben
924 |*
925 \************************************************************************/
926 
GetLinkCount()927 sal_uLong SdDrawDocument::GetLinkCount()
928 {
929     return ( pLinkManager->GetLinks().Count() );
930 }
931 
932 /*************************************************************************
933 |*
934 |* Language setzen
935 |*
936 \************************************************************************/
937 
SetLanguage(const LanguageType eLang,const sal_uInt16 nId)938 void SdDrawDocument::SetLanguage( const LanguageType eLang, const sal_uInt16 nId )
939 {
940     sal_Bool bChanged = sal_False;
941 
942     if( nId == EE_CHAR_LANGUAGE && meLanguage != eLang )
943     {
944         meLanguage = eLang;
945         bChanged = sal_True;
946     }
947     else if( nId == EE_CHAR_LANGUAGE_CJK && meLanguageCJK != eLang )
948     {
949         meLanguageCJK = eLang;
950         bChanged = sal_True;
951     }
952     else if( nId == EE_CHAR_LANGUAGE_CTL && meLanguageCTL != eLang )
953     {
954         meLanguageCTL = eLang;
955         bChanged = sal_True;
956     }
957 
958     if( bChanged )
959     {
960         GetDrawOutliner().SetDefaultLanguage( Application::GetSettings().GetLanguage() );
961         pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguage() );
962         pItemPool->SetPoolDefaultItem( SvxLanguageItem( eLang, nId ) );
963         SetChanged( bChanged );
964     }
965 }
966 
967 
968 /*************************************************************************
969 |*
970 |* Return language
971 |*
972 \************************************************************************/
973 
GetLanguage(const sal_uInt16 nId) const974 LanguageType SdDrawDocument::GetLanguage( const sal_uInt16 nId ) const
975 {
976     LanguageType eLangType = meLanguage;
977 
978     if( nId == EE_CHAR_LANGUAGE_CJK )
979         eLangType = meLanguageCJK;
980     else if( nId == EE_CHAR_LANGUAGE_CTL )
981         eLangType = meLanguageCTL;
982 
983     return eLangType;
984 }
985 
986 
987 /*************************************************************************
988 |*
989 |* WorkStartup einleiten
990 |*
991 \************************************************************************/
992 
IMPL_LINK(SdDrawDocument,WorkStartupHdl,Timer *,EMPTYARG)993 IMPL_LINK( SdDrawDocument, WorkStartupHdl, Timer *, EMPTYARG )
994 {
995     if( mpDocSh )
996         mpDocSh->SetWaitCursor( sal_True );
997 
998     sal_Bool bChanged = IsChanged();        // merken
999 
1000     // Autolayouts initialisieren
1001     SdPage* pHandoutMPage = GetMasterSdPage(0, PK_HANDOUT);
1002 
1003     if (pHandoutMPage->GetAutoLayout() == AUTOLAYOUT_NONE)
1004     {
1005         // AutoLayout wurde noch nicht umgesetzt -> Initialisieren
1006         pHandoutMPage->SetAutoLayout(AUTOLAYOUT_HANDOUT6, sal_True, sal_True);
1007     }
1008 
1009     SdPage* pPage = GetSdPage(0, PK_STANDARD);
1010 
1011     if (pPage->GetAutoLayout() == AUTOLAYOUT_NONE)
1012     {
1013         // AutoLayout wurde noch nicht umgesetzt -> Initialisieren
1014         pPage->SetAutoLayout(AUTOLAYOUT_NONE, sal_True, sal_True);
1015     }
1016 
1017     SdPage* pNotesPage = GetSdPage(0, PK_NOTES);
1018 
1019     if (pNotesPage->GetAutoLayout() == AUTOLAYOUT_NONE)
1020     {
1021         // AutoLayout wurde noch nicht umgesetzt -> Initialisieren
1022         pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, sal_True, sal_True);
1023     }
1024 
1025     SetChanged(bChanged || sal_False);
1026 
1027     if( mpDocSh )
1028         mpDocSh->SetWaitCursor( sal_False );
1029     return 0;
1030 }
1031 
1032 
1033 /*************************************************************************
1034 |*
1035 |* Wenn der WorkStartupTimer erzeugt worden ist (das erfolgt ausschliesslich
1036 |* in SdDrawViewShell::Consruct() ), so wird der Timer ggf. gestoppt und
1037 |* das WorkStartup eingeleitet
1038 |*
1039 \************************************************************************/
1040 
StopWorkStartupDelay()1041 void SdDrawDocument::StopWorkStartupDelay()
1042 {
1043     if (mpWorkStartupTimer)
1044     {
1045         if ( mpWorkStartupTimer->IsActive() )
1046         {
1047             // Timer war noch nicht abgelaufen -> WorkStartup wird eingeleitet
1048             mpWorkStartupTimer->Stop();
1049             WorkStartupHdl(NULL);
1050         }
1051 
1052         delete mpWorkStartupTimer;
1053         mpWorkStartupTimer = NULL;
1054     }
1055 }
1056 
1057 /*************************************************************************
1058 |*
1059 |* Wenn der WorkStartupTimer erzeugt worden ist (das erfolgt ausschliesslich
1060 |* in SdDrawViewShell::Consruct() ), so wird der Timer ggf. gestoppt und
1061 |* das WorkStartup eingeleitet
1062 |*
1063 \************************************************************************/
1064 
GetAnimationInfo(SdrObject * pObject) const1065 SdAnimationInfo* SdDrawDocument::GetAnimationInfo(SdrObject* pObject) const
1066 {
1067     DBG_ASSERT(pObject, "sd::SdDrawDocument::GetAnimationInfo(), invalid argument!");
1068     if( pObject )
1069         return GetShapeUserData( *pObject, false );
1070     else
1071         return 0;
1072 }
1073 
GetShapeUserData(SdrObject & rObject,bool bCreate)1074 SdAnimationInfo* SdDrawDocument::GetShapeUserData(SdrObject& rObject, bool bCreate /* = false */ )
1075 {
1076     sal_uInt16 nUD          = 0;
1077     sal_uInt16 nUDCount     = rObject.GetUserDataCount();
1078     SdrObjUserData* pUD = 0;
1079     SdAnimationInfo* pRet = 0;
1080 
1081     // gibt es in den User-Daten eine Animationsinformation?
1082     for (nUD = 0; nUD < nUDCount; nUD++)
1083     {
1084         pUD = rObject.GetUserData(nUD);
1085         if((pUD->GetInventor() == SdUDInventor) && (pUD->GetId() == SD_ANIMATIONINFO_ID))
1086         {
1087             pRet = dynamic_cast<SdAnimationInfo*>(pUD);
1088             break;
1089         }
1090     }
1091 
1092     if( (pRet == 0) && bCreate )
1093     {
1094         pRet = new SdAnimationInfo( rObject );
1095         rObject.InsertUserData( pRet);
1096     }
1097 
1098     return pRet;
1099 }
1100 
1101 
1102 /*************************************************************************
1103 |*
1104 |*
1105 |*
1106 \************************************************************************/
1107 
GetIMapInfo(SdrObject * pObject) const1108 SdIMapInfo* SdDrawDocument::GetIMapInfo( SdrObject* pObject ) const
1109 {
1110     DBG_ASSERT(pObject, "ohne Objekt keine IMapInfo");
1111 
1112     SdrObjUserData* pUserData = NULL;
1113     SdIMapInfo*     pIMapInfo = NULL;
1114     sal_uInt16          nCount = pObject->GetUserDataCount();
1115 
1116     // gibt es in den User-Daten eine IMap-Information?
1117     for ( sal_uInt16 i = 0; i < nCount; i++ )
1118     {
1119         pUserData = pObject->GetUserData( i );
1120 
1121         if ( ( pUserData->GetInventor() == SdUDInventor ) && ( pUserData->GetId() == SD_IMAPINFO_ID ) )
1122             pIMapInfo = (SdIMapInfo*) pUserData;
1123     }
1124 
1125     return pIMapInfo;
1126 }
1127 
1128 
1129 /*************************************************************************
1130 |*
1131 |*
1132 |*
1133 \************************************************************************/
1134 
GetHitIMapObject(SdrObject * pObj,const Point & rWinPoint,const::Window &)1135 IMapObject* SdDrawDocument::GetHitIMapObject( SdrObject* pObj,
1136                                               const Point& rWinPoint,
1137                                               const ::Window& /* rCmpWnd */ )
1138 {
1139     SdIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1140     IMapObject* pIMapObj = NULL;
1141 
1142     if ( pIMapInfo )
1143     {
1144         const MapMode       aMap100( MAP_100TH_MM );
1145         Size                aGraphSize;
1146         Point               aRelPoint( rWinPoint );
1147         ImageMap&           rImageMap = (ImageMap&) pIMapInfo->GetImageMap();
1148         const Rectangle&    rRect = pObj->GetLogicRect();
1149         sal_Bool                bObjSupported = sal_False;
1150 
1151         // HitTest ausfuehren
1152         if ( pObj->ISA( SdrGrafObj )  ) // einfaches Grafik-Objekt
1153         {
1154             const SdrGrafObj*   pGrafObj = (const SdrGrafObj*) pObj;
1155             const GeoStat&      rGeo = pGrafObj->GetGeoStat();
1156             SdrGrafObjGeoData*  pGeoData = (SdrGrafObjGeoData*) pGrafObj->GetGeoData();
1157 
1158             // Drehung rueckgaengig
1159             if ( rGeo.nDrehWink )
1160                 RotatePoint( aRelPoint, rRect.TopLeft(), -rGeo.nSin, rGeo.nCos );
1161 
1162             // Spiegelung rueckgaengig
1163             if ( pGeoData->bMirrored )
1164                 aRelPoint.X() = rRect.Right() + rRect.Left() - aRelPoint.X();
1165 
1166             // ggf. Unshear:
1167             if ( rGeo.nShearWink )
1168                 ShearPoint( aRelPoint, rRect.TopLeft(), -rGeo.nTan );
1169 
1170             if ( pGrafObj->GetGrafPrefMapMode().GetMapUnit() == MAP_PIXEL )
1171                 aGraphSize = Application::GetDefaultDevice()->PixelToLogic( pGrafObj->GetGrafPrefSize(), aMap100 );
1172             else
1173                 aGraphSize = OutputDevice::LogicToLogic( pGrafObj->GetGrafPrefSize(),
1174                                                          pGrafObj->GetGrafPrefMapMode(), aMap100 );
1175 
1176             delete pGeoData;
1177             bObjSupported = sal_True;
1178         }
1179         else if ( pObj->ISA( SdrOle2Obj ) ) // OLE-Objekt
1180         {
1181             aGraphSize = ( (SdrOle2Obj*) pObj )->GetOrigObjSize();
1182             bObjSupported = sal_True;
1183         }
1184 
1185         // hat alles geklappt, dann HitTest ausfuehren
1186         if ( bObjSupported )
1187         {
1188             // relativen Mauspunkt berechnen
1189             aRelPoint -= rRect.TopLeft();
1190             pIMapObj = rImageMap.GetHitIMapObject( aGraphSize, rRect.GetSize(), aRelPoint );
1191 
1192             // Deaktivierte Objekte wollen wir nicht
1193             if ( pIMapObj && !pIMapObj->IsActive() )
1194                 pIMapObj = NULL;
1195         }
1196     }
1197 
1198     return pIMapObj;
1199 }
1200 
GetImageMapForObject(SdrObject * pObj)1201 ImageMap* SdDrawDocument::GetImageMapForObject(SdrObject* pObj)
1202 {
1203     SdIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1204     if ( pIMapInfo )
1205     {
1206         return const_cast<ImageMap*>( &(pIMapInfo->GetImageMap()) );
1207     }
1208     return NULL;
1209 }
1210 /** this method enforces that the masterpages are in the currect order,
1211     that is at position 1 is a PK_STANDARD masterpage followed by a
1212     PK_NOTES masterpage and so on. #
1213 */
CheckMasterPages()1214 void SdDrawDocument::CheckMasterPages()
1215 {
1216 //  RemoveMasterPage(2); // code to test the creation of notes pages
1217 
1218     sal_uInt16 nMaxPages = GetMasterPageCount();
1219 
1220     // we need at least a handout master and one master page
1221     if( nMaxPages < 2 )
1222     {
1223         return;
1224     }
1225 
1226     SdPage* pPage = NULL;
1227     SdPage* pNotesPage = NULL;
1228 
1229     sal_uInt16 nPage;
1230 
1231     // first see if the page order is correct
1232     for( nPage = 1; nPage < nMaxPages; nPage++ )
1233     {
1234         pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1235         // if an odd page is not a standard page or an even page is not a notes page
1236         if( ((1 == (nPage & 1)) && (pPage->GetPageKind() != PK_STANDARD) ) ||
1237             ((0 == (nPage & 1)) && (pPage->GetPageKind() != PK_NOTES) ) )
1238             break; // then we have a fatal error
1239     }
1240 
1241     if( nPage < nMaxPages )
1242     {
1243         // there is a fatal error in the master page order,
1244         // we need to repair the document
1245         sal_Bool bChanged = sal_False;
1246 
1247         nPage = 1;
1248         while( nPage < nMaxPages )
1249         {
1250             pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1251             if( pPage->GetPageKind() != PK_STANDARD )
1252             {
1253                 bChanged = sal_True;
1254                 sal_uInt16 nFound = nPage + 1;
1255                 while( nFound < nMaxPages )
1256                 {
1257                     pPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1258                     if( PK_STANDARD == pPage->GetPageKind() )
1259                     {
1260                         MoveMasterPage( nFound, nPage );
1261                         pPage->SetInserted(sal_True);
1262                         break;
1263 
1264                     }
1265 
1266                     nFound++;
1267                 }
1268 
1269                 // if we don't have any more standard pages, were done
1270                 if( nMaxPages == nFound )
1271                     break;
1272             }
1273 
1274             nPage++;
1275 
1276             if( nPage < nMaxPages )
1277                 pNotesPage = static_cast<SdPage*>(GetMasterPage( nPage ));
1278             else
1279                 pNotesPage = NULL;
1280 
1281             if( (NULL == pNotesPage) || (pNotesPage->GetPageKind() != PK_NOTES) || ( pPage->GetLayoutName() != pNotesPage->GetLayoutName() ) )
1282             {
1283                 bChanged = sal_True;
1284 
1285                 sal_uInt16 nFound = nPage + 1;
1286                 while( nFound < nMaxPages )
1287                 {
1288                     pNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1289                     if( (PK_NOTES == pNotesPage->GetPageKind()) && ( pPage->GetLayoutName() == pNotesPage->GetLayoutName() ) )
1290                     {
1291                         MoveMasterPage( nFound, nPage );
1292                         pNotesPage->SetInserted(sal_True);
1293                         break;
1294                     }
1295 
1296                     nFound++;
1297                 }
1298 
1299                 // looks like we lost a notes page
1300                 if( nMaxPages == nFound )
1301                 {
1302                     // so create one
1303 
1304                     // first find a reference notes page for size
1305                     SdPage* pRefNotesPage = NULL;
1306                     nFound = 0;
1307                     while( nFound < nMaxPages )
1308                     {
1309                         pRefNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1310                         if( PK_NOTES == pRefNotesPage->GetPageKind() )
1311                             break;
1312                         nFound++;
1313                     }
1314                     if( nFound == nMaxPages )
1315                         pRefNotesPage = NULL;
1316 
1317                     SdPage* pNewNotesPage = static_cast<SdPage*>(AllocPage(sal_True));
1318                     pNewNotesPage->SetPageKind(PK_NOTES);
1319                     if( pRefNotesPage )
1320                     {
1321                         pNewNotesPage->SetSize( pRefNotesPage->GetSize() );
1322                         pNewNotesPage->SetBorder( pRefNotesPage->GetLftBorder(),
1323                                                 pRefNotesPage->GetUppBorder(),
1324                                                 pRefNotesPage->GetRgtBorder(),
1325                                                 pRefNotesPage->GetLwrBorder() );
1326                     }
1327                     InsertMasterPage(pNewNotesPage,  nPage );
1328                     pNewNotesPage->SetLayoutName( pPage->GetLayoutName() );
1329                     pNewNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, sal_True, sal_True );
1330                     nMaxPages++;
1331                 }
1332             }
1333 
1334             nPage++;
1335         }
1336 
1337         // now remove all remaining and unused non PK_STANDARD slides
1338         while( nPage < nMaxPages )
1339         {
1340             bChanged = sal_True;
1341 
1342             RemoveMasterPage( nPage );
1343             nMaxPages--;
1344         }
1345 
1346         if( bChanged )
1347         {
1348             DBG_ERROR( "master pages where in a wrong order" );
1349             RecalcPageNums( sal_True);
1350         }
1351     }
1352 }
1353 
CreatePage(SdPage * pActualPage,PageKind ePageKind,const String & sStandardPageName,const String & sNotesPageName,AutoLayout eStandardLayout,AutoLayout eNotesLayout,sal_Bool bIsPageBack,sal_Bool bIsPageObj,const sal_Int32 nInsertPosition)1354 sal_uInt16 SdDrawDocument::CreatePage (
1355     SdPage* pActualPage,
1356     PageKind ePageKind,
1357     const String& sStandardPageName,
1358     const String& sNotesPageName,
1359     AutoLayout eStandardLayout,
1360     AutoLayout eNotesLayout,
1361     sal_Bool bIsPageBack,
1362     sal_Bool bIsPageObj,
1363     const sal_Int32 nInsertPosition)
1364 {
1365     SdPage* pPreviousStandardPage;
1366     SdPage* pPreviousNotesPage;
1367     SdPage* pStandardPage;
1368     SdPage* pNotesPage;
1369 
1370     // From the given page determine the standard page and notes page of which
1371     // to take the layout and the position where to insert the new pages.
1372     if (ePageKind == PK_NOTES)
1373     {
1374         pPreviousNotesPage = pActualPage;
1375         sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1376         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1377         eStandardLayout = pPreviousStandardPage->GetAutoLayout();
1378     }
1379     else
1380     {
1381         pPreviousStandardPage = pActualPage;
1382         sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1383         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1384         eNotesLayout = pPreviousNotesPage->GetAutoLayout();
1385     }
1386 
1387     // Create new standard page and set it up.
1388     pStandardPage = (SdPage*) AllocPage(sal_False);
1389 
1390     // #108658#
1391     // Set the size here since else the presobj autolayout
1392     // will be wrong.
1393     pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
1394     pStandardPage->SetBorder( pPreviousStandardPage->GetLftBorder(),
1395                               pPreviousStandardPage->GetUppBorder(),
1396                               pPreviousStandardPage->GetRgtBorder(),
1397                               pPreviousStandardPage->GetLwrBorder() );
1398 
1399     // Use master page of current page.
1400     pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
1401 
1402     // User layout of current standard page.
1403     pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
1404     pStandardPage->SetAutoLayout(eStandardLayout, sal_True);
1405     pStandardPage->setHeaderFooterSettings( pPreviousStandardPage->getHeaderFooterSettings() );
1406 
1407     // transition settings of current page
1408     pStandardPage->setTransitionType( pPreviousStandardPage->getTransitionType() );
1409     pStandardPage->setTransitionSubtype( pPreviousStandardPage->getTransitionSubtype() );
1410     pStandardPage->setTransitionDirection( pPreviousStandardPage->getTransitionDirection() );
1411     pStandardPage->setTransitionFadeColor( pPreviousStandardPage->getTransitionFadeColor() );
1412     pStandardPage->setTransitionDuration( pPreviousStandardPage->getTransitionDuration() );
1413 
1414     // apply previous animation timing
1415     pStandardPage->SetPresChange( pPreviousStandardPage->GetPresChange() );
1416     pStandardPage->SetTime( pPreviousStandardPage->GetTime() );
1417 
1418     // Create new notes page and set it up.
1419     pNotesPage = (SdPage*) AllocPage(sal_False);
1420     pNotesPage->SetPageKind(PK_NOTES);
1421 
1422     // Use master page of current page.
1423     pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
1424 
1425     // Use layout of current notes page.
1426     pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
1427     pNotesPage->SetAutoLayout(eNotesLayout, sal_True);
1428     pNotesPage->setHeaderFooterSettings( pPreviousNotesPage->getHeaderFooterSettings() );
1429 
1430     return InsertPageSet (
1431         pActualPage,
1432         ePageKind,
1433         sStandardPageName,
1434         sNotesPageName,
1435         eStandardLayout,
1436         eNotesLayout,
1437         bIsPageBack,
1438         bIsPageObj,
1439         pStandardPage,
1440         pNotesPage,
1441         nInsertPosition);
1442 }
1443 
1444 
1445 
1446 
DuplicatePage(sal_uInt16 nPageNum)1447 sal_uInt16 SdDrawDocument::DuplicatePage (sal_uInt16 nPageNum)
1448 {
1449     PageKind ePageKind = PK_STANDARD;
1450 
1451     // Get current page.
1452     SdPage* pActualPage = GetSdPage(nPageNum, ePageKind);
1453 
1454     // Get background flags.
1455     SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1456     sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
1457     sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
1458     SetOfByte aVisibleLayers = pActualPage->TRG_GetMasterPageVisibleLayers();
1459 
1460     // Get layout from current page.
1461     AutoLayout eAutoLayout = pActualPage->GetAutoLayout();
1462 
1463     return DuplicatePage (
1464         pActualPage, ePageKind,
1465         // No names for the new slides.
1466         String(), String(),
1467         eAutoLayout, eAutoLayout,
1468         aVisibleLayers.IsSet(aBckgrnd),
1469         aVisibleLayers.IsSet(aBckgrndObj));
1470 }
1471 
1472 
1473 
1474 
DuplicatePage(SdPage * pActualPage,PageKind ePageKind,const String & sStandardPageName,const String & sNotesPageName,AutoLayout eStandardLayout,AutoLayout eNotesLayout,sal_Bool bIsPageBack,sal_Bool bIsPageObj,const sal_Int32 nInsertPosition)1475 sal_uInt16 SdDrawDocument::DuplicatePage (
1476     SdPage* pActualPage,
1477     PageKind ePageKind,
1478     const String& sStandardPageName,
1479     const String& sNotesPageName,
1480     AutoLayout eStandardLayout,
1481     AutoLayout eNotesLayout,
1482     sal_Bool bIsPageBack,
1483     sal_Bool bIsPageObj,
1484     const sal_Int32 nInsertPosition)
1485 {
1486     SdPage* pPreviousStandardPage;
1487     SdPage* pPreviousNotesPage;
1488     SdPage* pStandardPage;
1489     SdPage* pNotesPage;
1490 
1491     // From the given page determine the standard page and the notes page
1492     // of which to make copies.
1493     if (ePageKind == PK_NOTES)
1494     {
1495         pPreviousNotesPage = pActualPage;
1496         sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1497         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1498     }
1499     else
1500     {
1501         pPreviousStandardPage = pActualPage;
1502         sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1503         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1504     }
1505 
1506     // Create duplicates of a standard page and the associated notes page.
1507     pStandardPage = (SdPage*) pPreviousStandardPage->Clone();
1508     pNotesPage = (SdPage*) pPreviousNotesPage->Clone();
1509 
1510     return InsertPageSet (
1511         pActualPage,
1512         ePageKind,
1513         sStandardPageName,
1514         sNotesPageName,
1515         eStandardLayout,
1516         eNotesLayout,
1517         bIsPageBack,
1518         bIsPageObj,
1519         pStandardPage,
1520         pNotesPage,
1521         nInsertPosition);
1522 }
1523 
1524 
1525 
1526 
InsertPageSet(SdPage * pActualPage,PageKind ePageKind,const String & sStandardPageName,const String & sNotesPageName,AutoLayout eStandardLayout,AutoLayout eNotesLayout,sal_Bool bIsPageBack,sal_Bool bIsPageObj,SdPage * pStandardPage,SdPage * pNotesPage,sal_Int32 nInsertPosition)1527 sal_uInt16 SdDrawDocument::InsertPageSet (
1528     SdPage* pActualPage,
1529     PageKind ePageKind,
1530     const String& sStandardPageName,
1531     const String& sNotesPageName,
1532     AutoLayout eStandardLayout,
1533     AutoLayout eNotesLayout,
1534     sal_Bool bIsPageBack,
1535     sal_Bool bIsPageObj,
1536     SdPage* pStandardPage,
1537     SdPage* pNotesPage,
1538     sal_Int32 nInsertPosition)
1539 {
1540     SdPage* pPreviousStandardPage;
1541     SdPage* pPreviousNotesPage;
1542     sal_uInt16 nStandardPageNum;
1543     sal_uInt16 nNotesPageNum;
1544     String aStandardPageName = sStandardPageName;
1545     String aNotesPageName = sNotesPageName;
1546 
1547     // Gather some information about the standard page and the notes page
1548     // that are to be inserted.  This makes sure that there is allways one
1549     // standard page followed by one notes page.
1550     if (ePageKind == PK_NOTES)
1551     {
1552         pPreviousNotesPage = pActualPage;
1553         nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1554         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1555         nStandardPageNum = nNotesPageNum - 1;
1556         eStandardLayout = pPreviousStandardPage->GetAutoLayout();
1557     }
1558     else
1559     {
1560         pPreviousStandardPage = pActualPage;
1561         nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1562         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1563         nNotesPageNum = nStandardPageNum + 1;
1564         aNotesPageName = aStandardPageName;
1565         eNotesLayout = pPreviousNotesPage->GetAutoLayout();
1566     }
1567 
1568     OSL_ASSERT(nNotesPageNum==nStandardPageNum+1);
1569     if (nInsertPosition < 0)
1570         nInsertPosition = nStandardPageNum;
1571 
1572     // Set up and insert the standard page.
1573     SetupNewPage (
1574         pPreviousStandardPage,
1575         pStandardPage,
1576         aStandardPageName,
1577         nInsertPosition,
1578         bIsPageBack,
1579         bIsPageObj);
1580 
1581     // Set up and insert the notes page.
1582     pNotesPage->SetPageKind(PK_NOTES);
1583     SetupNewPage (
1584         pPreviousNotesPage,
1585         pNotesPage,
1586         aNotesPageName,
1587         nInsertPosition+1,
1588         bIsPageBack,
1589         bIsPageObj);
1590 
1591     // Return an index that allows the caller to access the newly inserted
1592     // pages by using GetSdPage().
1593     return pStandardPage->GetPageNum() / 2;
1594 }
1595 
1596 
1597 
1598 
SetupNewPage(SdPage * pPreviousPage,SdPage * pPage,const String & sPageName,sal_uInt16 nInsertionPoint,sal_Bool bIsPageBack,sal_Bool bIsPageObj)1599 void SdDrawDocument::SetupNewPage (
1600     SdPage* pPreviousPage,
1601     SdPage* pPage,
1602     const String& sPageName,
1603     sal_uInt16 nInsertionPoint,
1604     sal_Bool bIsPageBack,
1605     sal_Bool bIsPageObj)
1606 {
1607     if (pPreviousPage != NULL)
1608     {
1609         pPage->SetSize( pPreviousPage->GetSize() );
1610         pPage->SetBorder( pPreviousPage->GetLftBorder(),
1611             pPreviousPage->GetUppBorder(),
1612             pPreviousPage->GetRgtBorder(),
1613             pPreviousPage->GetLwrBorder() );
1614     }
1615     pPage->SetName(sPageName);
1616 
1617     InsertPage(pPage, nInsertionPoint);
1618 
1619     if (pPreviousPage != NULL)
1620     {
1621         SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1622         sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
1623         sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
1624         SetOfByte aVisibleLayers = pPreviousPage->TRG_GetMasterPageVisibleLayers();
1625         aVisibleLayers.Set(aBckgrnd, bIsPageBack);
1626         aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
1627         pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
1628     }
1629 }
1630 
GetUndoManager() const1631 sd::UndoManager* SdDrawDocument::GetUndoManager() const
1632 {
1633     return mpDocSh ? dynamic_cast< sd::UndoManager* >(mpDocSh->GetUndoManager()) : 0;
1634 }
1635 
1636 // eof
1637