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