xref: /aoo42x/main/sd/source/core/drawdoc2.cxx (revision 0deba7fb)
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 
92 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 
162 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 
216 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 
228 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 
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 
252 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 
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 
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 
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 
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 
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 
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 
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!
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 
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 
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 
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 
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 
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 
927 sal_uLong SdDrawDocument::GetLinkCount()
928 {
929 	return ( pLinkManager->GetLinks().Count() );
930 }
931 
932 /*************************************************************************
933 |*
934 |* Language setzen
935 |*
936 \************************************************************************/
937 
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 
974 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 
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 
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 
1065 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 
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 
1108 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 
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 
1201 //IAccessibility2 Implementation 2009-----
1202 ImageMap* SdDrawDocument::GetImageMapForObject(SdrObject* pObj)
1203 {
1204 	SdIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1205 	if ( pIMapInfo )
1206 	{
1207 		return const_cast<ImageMap*>( &(pIMapInfo->GetImageMap()) );
1208 	}
1209 	return NULL;
1210 }
1211 //-----IAccessibility2 Implementation 2009
1212 /** this method enforces that the masterpages are in the currect order,
1213 	that is at position 1 is a PK_STANDARD masterpage followed by a
1214 	PK_NOTES masterpage and so on. #
1215 */
1216 void SdDrawDocument::CheckMasterPages()
1217 {
1218 //	RemoveMasterPage(2); // code to test the creation of notes pages
1219 
1220 	sal_uInt16 nMaxPages = GetMasterPageCount();
1221 
1222 	// we need at least a handout master and one master page
1223 	if( nMaxPages < 2 )
1224 	{
1225 		return;
1226 	}
1227 
1228 	SdPage* pPage = NULL;
1229 	SdPage* pNotesPage = NULL;
1230 
1231 	sal_uInt16 nPage;
1232 
1233 	// first see if the page order is correct
1234 	for( nPage = 1; nPage < nMaxPages; nPage++ )
1235 	{
1236 		pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1237 		// if an odd page is not a standard page or an even page is not a notes page
1238 		if( ((1 == (nPage & 1)) && (pPage->GetPageKind() != PK_STANDARD) ) ||
1239 			((0 == (nPage & 1)) && (pPage->GetPageKind() != PK_NOTES) ) )
1240 			break; // then we have a fatal error
1241 	}
1242 
1243 	if( nPage < nMaxPages )
1244 	{
1245 		// there is a fatal error in the master page order,
1246 		// we need to repair the document
1247 		sal_Bool bChanged = sal_False;
1248 
1249 		nPage = 1;
1250 		while( nPage < nMaxPages )
1251 		{
1252 			pPage = static_cast<SdPage*> (GetMasterPage( nPage ));
1253 			if( pPage->GetPageKind() != PK_STANDARD )
1254 			{
1255 				bChanged = sal_True;
1256 				sal_uInt16 nFound = nPage + 1;
1257 				while( nFound < nMaxPages )
1258 				{
1259 					pPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1260 					if( PK_STANDARD == pPage->GetPageKind() )
1261 					{
1262 						MoveMasterPage( nFound, nPage );
1263 						pPage->SetInserted(sal_True);
1264 						break;
1265 
1266 					}
1267 
1268 					nFound++;
1269 				}
1270 
1271 				// if we don't have any more standard pages, were done
1272 				if( nMaxPages == nFound )
1273 					break;
1274 			}
1275 
1276 			nPage++;
1277 
1278 			if( nPage < nMaxPages )
1279 				pNotesPage = static_cast<SdPage*>(GetMasterPage( nPage ));
1280 			else
1281 				pNotesPage = NULL;
1282 
1283 			if( (NULL == pNotesPage) || (pNotesPage->GetPageKind() != PK_NOTES) || ( pPage->GetLayoutName() != pNotesPage->GetLayoutName() ) )
1284 			{
1285 				bChanged = sal_True;
1286 
1287 				sal_uInt16 nFound = nPage + 1;
1288 				while( nFound < nMaxPages )
1289 				{
1290 					pNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1291 					if( (PK_NOTES == pNotesPage->GetPageKind()) && ( pPage->GetLayoutName() == pNotesPage->GetLayoutName() ) )
1292 					{
1293 						MoveMasterPage( nFound, nPage );
1294 						pNotesPage->SetInserted(sal_True);
1295 						break;
1296 					}
1297 
1298 					nFound++;
1299 				}
1300 
1301 				// looks like we lost a notes page
1302 				if( nMaxPages == nFound )
1303 				{
1304 					// so create one
1305 
1306 					// first find a reference notes page for size
1307 					SdPage* pRefNotesPage = NULL;
1308 					nFound = 0;
1309 					while( nFound < nMaxPages )
1310 					{
1311 						pRefNotesPage = static_cast<SdPage*>(GetMasterPage( nFound ));
1312 						if( PK_NOTES == pRefNotesPage->GetPageKind() )
1313 							break;
1314 						nFound++;
1315 					}
1316 					if( nFound == nMaxPages )
1317 						pRefNotesPage = NULL;
1318 
1319 					SdPage* pNewNotesPage = static_cast<SdPage*>(AllocPage(sal_True));
1320 					pNewNotesPage->SetPageKind(PK_NOTES);
1321 					if( pRefNotesPage )
1322 					{
1323 						pNewNotesPage->SetSize( pRefNotesPage->GetSize() );
1324 						pNewNotesPage->SetBorder( pRefNotesPage->GetLftBorder(),
1325 												pRefNotesPage->GetUppBorder(),
1326 												pRefNotesPage->GetRgtBorder(),
1327 												pRefNotesPage->GetLwrBorder() );
1328 					}
1329 					InsertMasterPage(pNewNotesPage,  nPage );
1330 					pNewNotesPage->SetLayoutName( pPage->GetLayoutName() );
1331 					pNewNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, sal_True, sal_True );
1332 					nMaxPages++;
1333 				}
1334 			}
1335 
1336 			nPage++;
1337 		}
1338 
1339 		// now remove all remaining and unused non PK_STANDARD slides
1340 		while( nPage < nMaxPages )
1341 		{
1342 			bChanged = sal_True;
1343 
1344 			RemoveMasterPage( nPage );
1345 			nMaxPages--;
1346 		}
1347 
1348 		if( bChanged )
1349 		{
1350 			DBG_ERROR( "master pages where in a wrong order" );
1351 			RecalcPageNums( sal_True);
1352 		}
1353 	}
1354 }
1355 
1356 sal_uInt16 SdDrawDocument::CreatePage (
1357     SdPage* pActualPage,
1358     PageKind ePageKind,
1359     const String& sStandardPageName,
1360     const String& sNotesPageName,
1361     AutoLayout eStandardLayout,
1362     AutoLayout eNotesLayout,
1363     sal_Bool bIsPageBack,
1364     sal_Bool bIsPageObj,
1365     const sal_Int32 nInsertPosition)
1366 {
1367     SdPage* pPreviousStandardPage;
1368     SdPage* pPreviousNotesPage;
1369     SdPage* pStandardPage;
1370     SdPage* pNotesPage;
1371 
1372     // From the given page determine the standard page and notes page of which
1373     // to take the layout and the position where to insert the new pages.
1374     if (ePageKind == PK_NOTES)
1375     {
1376         pPreviousNotesPage = pActualPage;
1377         sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1378         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1379         eStandardLayout = pPreviousStandardPage->GetAutoLayout();
1380     }
1381     else
1382     {
1383         pPreviousStandardPage = pActualPage;
1384         sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1385         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1386         eNotesLayout = pPreviousNotesPage->GetAutoLayout();
1387     }
1388 
1389     // Create new standard page and set it up.
1390     pStandardPage = (SdPage*) AllocPage(sal_False);
1391 
1392 	// #108658#
1393 	// Set the size here since else the presobj autolayout
1394 	// will be wrong.
1395 	pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
1396 	pStandardPage->SetBorder( pPreviousStandardPage->GetLftBorder(),
1397 							  pPreviousStandardPage->GetUppBorder(),
1398 							  pPreviousStandardPage->GetRgtBorder(),
1399 							  pPreviousStandardPage->GetLwrBorder() );
1400 
1401     // Use master page of current page.
1402     pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
1403 
1404     // User layout of current standard page.
1405     pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
1406     pStandardPage->SetAutoLayout(eStandardLayout, sal_True);
1407 	pStandardPage->setHeaderFooterSettings( pPreviousStandardPage->getHeaderFooterSettings() );
1408 
1409 	// transition settings of current page
1410 	pStandardPage->setTransitionType( pPreviousStandardPage->getTransitionType() );
1411 	pStandardPage->setTransitionSubtype( pPreviousStandardPage->getTransitionSubtype() );
1412 	pStandardPage->setTransitionDirection( pPreviousStandardPage->getTransitionDirection() );
1413 	pStandardPage->setTransitionFadeColor( pPreviousStandardPage->getTransitionFadeColor() );
1414 	pStandardPage->setTransitionDuration( pPreviousStandardPage->getTransitionDuration() );
1415 
1416 	// apply previous animation timing
1417 	pStandardPage->SetPresChange( pPreviousStandardPage->GetPresChange() );
1418 	pStandardPage->SetTime( pPreviousStandardPage->GetTime() );
1419 
1420     // Create new notes page and set it up.
1421     pNotesPage = (SdPage*) AllocPage(sal_False);
1422 	pNotesPage->SetPageKind(PK_NOTES);
1423 
1424 	// Use master page of current page.
1425     pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
1426 
1427     // Use layout of current notes page.
1428     pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
1429     pNotesPage->SetAutoLayout(eNotesLayout, sal_True);
1430 	pNotesPage->setHeaderFooterSettings( pPreviousNotesPage->getHeaderFooterSettings() );
1431 
1432     return InsertPageSet (
1433         pActualPage,
1434         ePageKind,
1435         sStandardPageName,
1436         sNotesPageName,
1437         eStandardLayout,
1438         eNotesLayout,
1439         bIsPageBack,
1440         bIsPageObj,
1441         pStandardPage,
1442         pNotesPage,
1443         nInsertPosition);
1444 }
1445 
1446 
1447 
1448 
1449 sal_uInt16 SdDrawDocument::DuplicatePage (sal_uInt16 nPageNum)
1450 {
1451     PageKind ePageKind = PK_STANDARD;
1452 
1453     // Get current page.
1454     SdPage* pActualPage = GetSdPage(nPageNum, ePageKind);
1455 
1456     // Get background flags.
1457     SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1458     sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
1459     sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
1460     SetOfByte aVisibleLayers = pActualPage->TRG_GetMasterPageVisibleLayers();
1461 
1462     // Get layout from current page.
1463     AutoLayout eAutoLayout = pActualPage->GetAutoLayout();
1464 
1465     return DuplicatePage (
1466         pActualPage, ePageKind,
1467         // No names for the new slides.
1468         String(), String(),
1469         eAutoLayout, eAutoLayout,
1470         aVisibleLayers.IsSet(aBckgrnd),
1471         aVisibleLayers.IsSet(aBckgrndObj));
1472 }
1473 
1474 
1475 
1476 
1477 sal_uInt16 SdDrawDocument::DuplicatePage (
1478     SdPage* pActualPage,
1479     PageKind ePageKind,
1480     const String& sStandardPageName,
1481     const String& sNotesPageName,
1482     AutoLayout eStandardLayout,
1483     AutoLayout eNotesLayout,
1484     sal_Bool bIsPageBack,
1485     sal_Bool bIsPageObj,
1486     const sal_Int32 nInsertPosition)
1487 {
1488     SdPage* pPreviousStandardPage;
1489     SdPage* pPreviousNotesPage;
1490     SdPage* pStandardPage;
1491     SdPage* pNotesPage;
1492 
1493     // From the given page determine the standard page and the notes page
1494     // of which to make copies.
1495     if (ePageKind == PK_NOTES)
1496     {
1497         pPreviousNotesPage = pActualPage;
1498         sal_uInt16 nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1499         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1500     }
1501     else
1502     {
1503         pPreviousStandardPage = pActualPage;
1504         sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1505         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1506     }
1507 
1508     // Create duplicates of a standard page and the associated notes page.
1509     pStandardPage = (SdPage*) pPreviousStandardPage->Clone();
1510 	pNotesPage = (SdPage*) pPreviousNotesPage->Clone();
1511 
1512 	return InsertPageSet (
1513         pActualPage,
1514         ePageKind,
1515         sStandardPageName,
1516         sNotesPageName,
1517         eStandardLayout,
1518         eNotesLayout,
1519         bIsPageBack,
1520         bIsPageObj,
1521         pStandardPage,
1522         pNotesPage,
1523         nInsertPosition);
1524 }
1525 
1526 
1527 
1528 
1529 sal_uInt16 SdDrawDocument::InsertPageSet (
1530     SdPage* pActualPage,
1531     PageKind ePageKind,
1532     const String& sStandardPageName,
1533     const String& sNotesPageName,
1534     AutoLayout eStandardLayout,
1535     AutoLayout eNotesLayout,
1536     sal_Bool bIsPageBack,
1537     sal_Bool bIsPageObj,
1538     SdPage* pStandardPage,
1539     SdPage* pNotesPage,
1540     sal_Int32 nInsertPosition)
1541 {
1542     SdPage* pPreviousStandardPage;
1543     SdPage* pPreviousNotesPage;
1544     sal_uInt16 nStandardPageNum;
1545     sal_uInt16 nNotesPageNum;
1546     String aStandardPageName = sStandardPageName;
1547     String aNotesPageName = sNotesPageName;
1548 
1549     // Gather some information about the standard page and the notes page
1550     // that are to be inserted.  This makes sure that there is allways one
1551     // standard page followed by one notes page.
1552     if (ePageKind == PK_NOTES)
1553     {
1554         pPreviousNotesPage = pActualPage;
1555         nNotesPageNum = pPreviousNotesPage->GetPageNum() + 2;
1556         pPreviousStandardPage = (SdPage*) GetPage(nNotesPageNum - 3);
1557         nStandardPageNum = nNotesPageNum - 1;
1558         eStandardLayout = pPreviousStandardPage->GetAutoLayout();
1559     }
1560     else
1561     {
1562         pPreviousStandardPage = pActualPage;
1563         nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
1564         pPreviousNotesPage = (SdPage*) GetPage(nStandardPageNum - 1);
1565         nNotesPageNum = nStandardPageNum + 1;
1566         aNotesPageName = aStandardPageName;
1567         eNotesLayout = pPreviousNotesPage->GetAutoLayout();
1568     }
1569 
1570     OSL_ASSERT(nNotesPageNum==nStandardPageNum+1);
1571     if (nInsertPosition < 0)
1572         nInsertPosition = nStandardPageNum;
1573 
1574     // Set up and insert the standard page.
1575     SetupNewPage (
1576         pPreviousStandardPage,
1577         pStandardPage,
1578         aStandardPageName,
1579         nInsertPosition,
1580         bIsPageBack,
1581         bIsPageObj);
1582 
1583     // Set up and insert the notes page.
1584     pNotesPage->SetPageKind(PK_NOTES);
1585     SetupNewPage (
1586         pPreviousNotesPage,
1587         pNotesPage,
1588         aNotesPageName,
1589         nInsertPosition+1,
1590         bIsPageBack,
1591         bIsPageObj);
1592 
1593     // Return an index that allows the caller to access the newly inserted
1594     // pages by using GetSdPage().
1595     return pStandardPage->GetPageNum() / 2;
1596 }
1597 
1598 
1599 
1600 
1601 void SdDrawDocument::SetupNewPage (
1602     SdPage* pPreviousPage,
1603     SdPage* pPage,
1604     const String& sPageName,
1605     sal_uInt16 nInsertionPoint,
1606     sal_Bool bIsPageBack,
1607     sal_Bool bIsPageObj)
1608 {
1609     if (pPreviousPage != NULL)
1610     {
1611         pPage->SetSize( pPreviousPage->GetSize() );
1612         pPage->SetBorder( pPreviousPage->GetLftBorder(),
1613             pPreviousPage->GetUppBorder(),
1614             pPreviousPage->GetRgtBorder(),
1615             pPreviousPage->GetLwrBorder() );
1616     }
1617     pPage->SetName(sPageName);
1618 
1619     InsertPage(pPage, nInsertionPoint);
1620 
1621     if (pPreviousPage != NULL)
1622     {
1623         SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
1624         sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
1625         sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
1626         SetOfByte aVisibleLayers = pPreviousPage->TRG_GetMasterPageVisibleLayers();
1627         aVisibleLayers.Set(aBckgrnd, bIsPageBack);
1628         aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
1629         pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
1630     }
1631 }
1632 
1633 sd::UndoManager* SdDrawDocument::GetUndoManager() const
1634 {
1635 	return mpDocSh ? dynamic_cast< sd::UndoManager* >(mpDocSh->GetUndoManager()) : 0;
1636 }
1637 
1638 // eof
1639