Update ooo320-m1
[ooovba.git] / sd / source / core / drawdoc3.cxx
blob2fe1f33dd308f1dae8b29e415c8b0f9c33edf5bd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawdoc3.cxx,v $
10 * $Revision: 1.53 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include "comphelper/anytostring.hxx"
39 #include "cppuhelper/exc_hlp.hxx"
41 #include <utility>
42 #include <algorithm>
43 #include <vcl/wrkwin.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <sot/storage.hxx>
46 #include <sfx2/app.hxx>
47 #include <svtools/itemset.hxx>
49 #include <unotools/ucbstreamhelper.hxx>
50 #include <sfx2/fcontnr.hxx>
51 #include <svx/svdopath.hxx>
52 #include <svx/svditer.hxx>
53 #include <svtools/style.hxx>
54 #include <svx/linkmgr.hxx>
55 #include <svx/svdpagv.hxx>
56 #include <svx/svdogrp.hxx>
57 #include <svx/svdundo.hxx>
58 #include <vcl/msgbox.hxx>
59 #include <sot/storage.hxx>
60 #include <sot/formats.hxx>
62 #include <set>
64 #include "glob.hrc"
65 #include "drawdoc.hxx"
66 #include "sdpage.hxx"
67 #include "stlpool.hxx"
68 #include "sdresid.hxx"
69 #include "sdiocmpt.hxx"
70 #include "strmname.h"
71 #include "anminfo.hxx"
73 #include "../ui/inc/unmovss.hxx"
74 #include "../ui/inc/unchss.hxx"
75 #include "../ui/inc/unprlout.hxx"
76 #include "../ui/inc/DrawDocShell.hxx"
77 #include "../ui/inc/GraphicDocShell.hxx"
78 #include "../ui/inc/ViewShell.hxx"
79 #include "../ui/inc/View.hxx"
80 #include "../ui/inc/cfgids.hxx"
81 #include "../ui/inc/strings.hrc"
83 using namespace ::com::sun::star;
85 #define POOL_BUFFER_SIZE (USHORT)32768
86 #define BASIC_BUFFER_SIZE (USHORT)8192
87 #define DOCUMENT_BUFFER_SIZE (USHORT)32768
89 /*************************************************************************
91 |* Oeffnet ein Bookmark-Dokument
93 \************************************************************************/
95 SdStorageListener : public BaseImplHelper1 < lang::XEventListener >
97 uno::Reference < embed::XStorage >& xStor;
98 public:
99 SdStorageListener ( uno::Reference < embed::XStorage >& rStor )
100 : xStor( rStor )
103 void disposing ( const lang::EventObject& aEvent ) throw ( uno::RuntimeException );
106 void SdStorageListener::disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException )
108 xStor = NULL;
111 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(SfxMedium& rMedium)
113 BOOL bOK = TRUE;
114 SdDrawDocument* pBookmarkDoc = NULL;
115 String aBookmarkName = rMedium.GetName();
116 const SfxFilter* pFilter = rMedium.GetFilter();
117 if ( !pFilter )
119 rMedium.UseInteractionHandler( TRUE );
120 SFX_APP()->GetFilterMatcher().GuessFilter( rMedium, &pFilter );
123 if ( !pFilter )
125 bOK = FALSE;
127 else if ( maBookmarkFile != aBookmarkName && aBookmarkName.Len() )
129 BOOL bCreateGraphicShell = pFilter->GetServiceName().EqualsAscii( "com.sun.star.drawing.DrawingDocument" );
130 BOOL bCreateImpressShell = pFilter->GetServiceName().EqualsAscii( "com.sun.star.presentation.PresentationDocument" );
131 if ( bCreateGraphicShell || bCreateImpressShell )
133 CloseBookmarkDoc();
135 // Es wird eine DocShell erzeugt, da in dem Dokument OLE-Objekte
136 // enthalten sein koennten (Persist)
137 // Wenn dem nicht so waere, so koennte man auch das Model
138 // direkt laden
139 if ( bCreateGraphicShell )
140 // Draw
141 mxBookmarkDocShRef = new ::sd::GraphicDocShell(SFX_CREATE_MODE_STANDARD, TRUE);
142 else
143 // Impress
144 mxBookmarkDocShRef = new ::sd::DrawDocShell(SFX_CREATE_MODE_STANDARD, TRUE);
146 bOK = mxBookmarkDocShRef->DoLoad(&rMedium);
147 if( bOK )
149 maBookmarkFile = aBookmarkName;
150 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
155 DBG_ASSERT(aBookmarkName.Len(), "Empty document name!");
157 if (!bOK)
159 ErrorBox aErrorBox( NULL, (WinBits)WB_OK, String(SdResId(STR_READ_DATA_ERROR)));
160 aErrorBox.Execute();
162 CloseBookmarkDoc();
163 pBookmarkDoc = NULL;
165 else if (mxBookmarkDocShRef.Is())
167 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
170 return(pBookmarkDoc);
173 /*************************************************************************
175 |* Oeffnet ein Bookmark-Dokument
177 \************************************************************************/
179 SdDrawDocument* SdDrawDocument::OpenBookmarkDoc(const String& rBookmarkFile)
181 SdDrawDocument* pBookmarkDoc = NULL;
183 if (maBookmarkFile != rBookmarkFile && rBookmarkFile.Len())
185 SfxMedium* pMedium = new SfxMedium( rBookmarkFile, STREAM_READ, FALSE );
186 pBookmarkDoc = OpenBookmarkDoc(*pMedium);
188 else if (mxBookmarkDocShRef.Is())
190 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
193 return(pBookmarkDoc);
196 /*************************************************************************
198 |* Fuegt ein Bookmark (Seite oder Objekt) ein
200 \************************************************************************/
202 BOOL SdDrawDocument::InsertBookmark(
203 List* pBookmarkList, // Liste der Namen der einzufuegenden Bookmarks
204 List* pExchangeList, // Liste der zu verwendenen Namen
205 BOOL bLink, // Bookmarks sollen als Verknuepfung eingefuegt werden
206 BOOL bReplace, // Aktuellen Seiten (Standard&Notiz) werden ersetzt
207 USHORT nInsertPos, // Einfuegeposition fuer Seiten
208 BOOL bNoDialogs, // Keine Dialoge anzeigen
209 ::sd::DrawDocShell* pBookmarkDocSh, // Wenn gesetzt, so ist dieses das Source-Dokument
210 BOOL bCopy, // Seiten werden kopiert
211 Point* pObjPos) // Einfuegeposition fuer Objekte
213 BOOL bOK = TRUE;
214 BOOL bInsertPages = FALSE;
216 if (!pBookmarkList)
218 /**********************************************************************
219 * Alle Seiten werden eingefuegt
220 **********************************************************************/
221 bInsertPages = TRUE;
223 else
225 SdDrawDocument* pBookmarkDoc = NULL;
226 String aBookmarkName;
228 if (pBookmarkDocSh)
230 pBookmarkDoc = pBookmarkDocSh->GetDoc();
231 aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
233 else if ( mxBookmarkDocShRef.Is() )
235 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
236 aBookmarkName = maBookmarkFile;
238 else
239 bOK = FALSE;
241 for (USHORT nPos = 0; bOK && ( nPos < pBookmarkList->Count() ) && !bInsertPages; nPos++)
243 /******************************************************************
244 * Gibt es in der Bookmark-Liste einen Seitennamen?
245 ******************************************************************/
246 String aBMPgName (*(String*) pBookmarkList->GetObject(nPos));
247 BOOL bIsMasterPage;
249 if( pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
251 // Seite gefunden
252 bInsertPages = TRUE;
257 if ( bOK && bInsertPages )
259 // Zuerst werden alle Seiten-Bookmarks eingefuegt
260 bOK = InsertBookmarkAsPage(pBookmarkList, pExchangeList, bLink, bReplace,
261 nInsertPos, bNoDialogs, pBookmarkDocSh, bCopy, TRUE, FALSE);
264 if ( bOK && pBookmarkList )
266 // Es werden alle Objekt-Bookmarks eingefuegt
267 bOK = InsertBookmarkAsObject(pBookmarkList, pExchangeList, bLink,
268 pBookmarkDocSh, pObjPos);
271 return bOK;
274 /*************************************************************************
276 |* Fuegt ein Bookmark als Seite ein
278 \************************************************************************/
280 /** Concrete incarnations get called by IterateBookmarkPages, for
281 every page in the bookmark document/list
283 class SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
285 public:
286 virtual ~InsertBookmarkAsPage_PageFunctorBase() = 0;
287 virtual void operator()( SdDrawDocument&, SdPage* ) = 0;
290 SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase::~InsertBookmarkAsPage_PageFunctorBase()
294 void SdDrawDocument::IterateBookmarkPages( SdDrawDocument* pBookmarkDoc, List* pBookmarkList, USHORT nBMSdPageCount,
295 SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase& rPageIterator )
298 // #96029# Refactored copy'n'pasted layout name collection from InsertBookmarkAsPage
300 int nPos, nEndPos;
302 if( !pBookmarkList )
304 // no list? whole source document
305 nEndPos = nBMSdPageCount;
307 else
309 // bookmark list? number of entries
310 nEndPos = pBookmarkList->Count();
313 SdPage* pBMPage;
315 // iterate over number of pages to insert
316 for (nPos = 0; nPos < nEndPos; ++nPos)
318 // the master page associated to the nPos'th page to insert
319 SdPage* pBMMPage = NULL;
321 if( !pBookmarkList )
323 // simply take master page of nPos'th page in source document
324 pBMMPage = (SdPage*)(&(pBookmarkDoc->GetSdPage((USHORT)nPos, PK_STANDARD)->TRG_GetMasterPage()));
326 else
328 // fetch nPos'th entry from bookmark list, and determine master page
329 String aBMPgName (*(String*) pBookmarkList->GetObject(nPos));
330 BOOL bIsMasterPage;
332 USHORT nBMPage = pBookmarkDoc->GetPageByName( aBMPgName, bIsMasterPage );
334 if (nBMPage != SDRPAGE_NOTFOUND)
336 pBMPage = (SdPage*) pBookmarkDoc->GetPage(nBMPage);
338 else
340 pBMPage = NULL;
343 // enforce that bookmarked page is a standard page and not already a master page
344 if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
346 const USHORT nBMSdPage = (nBMPage - 1) / 2;
347 pBMMPage = (SdPage*) (&(pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD)->TRG_GetMasterPage()));
351 // successfully determined valid (bookmarked) page?
352 if( pBMMPage )
354 // yes, call functor
355 rPageIterator( *this, pBMMPage );
360 class InsertBookmarkAsPage_FindDuplicateLayouts : public SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
362 public:
363 InsertBookmarkAsPage_FindDuplicateLayouts( List* pLayoutsToTransfer, SdDrawDocument* pBookmarkDoc,
364 List* pBookmarkList, USHORT nBMSdPageCount ) :
365 mpLayoutsToTransfer(pLayoutsToTransfer), mpBookmarkDoc(pBookmarkDoc),
366 mpBookmarkList(pBookmarkList), mnBMSdPageCount(nBMSdPageCount) {}
367 virtual ~InsertBookmarkAsPage_FindDuplicateLayouts() {};
368 virtual void operator()( SdDrawDocument&, SdPage* );
369 private:
370 List* mpLayoutsToTransfer;
371 SdDrawDocument* mpBookmarkDoc;
372 List* mpBookmarkList;
373 USHORT mnBMSdPageCount;
376 void InsertBookmarkAsPage_FindDuplicateLayouts::operator()( SdDrawDocument& rDoc, SdPage* pBMMPage )
378 // now check for duplicate masterpage and layout names
379 // ===================================================
381 String sFullLayoutName( pBMMPage->GetLayoutName() );
382 String* pLayout = new String(sFullLayoutName);
383 pLayout->Erase( pLayout->SearchAscii( SD_LT_SEPARATOR ));
385 String* pTest = (String*) mpLayoutsToTransfer->First();
386 BOOL bFound = FALSE;
388 while (pTest && !bFound) // found yet?
390 if (*pLayout == *pTest)
391 bFound = TRUE;
392 else
393 pTest = (String*)mpLayoutsToTransfer->Next();
396 const USHORT nMPageCount = rDoc.GetMasterPageCount();
397 for (USHORT nMPage = 0; nMPage < nMPageCount && !bFound; nMPage++)
399 /**************************************************************
400 * Gibt es die Layouts schon im Dokument?
401 **************************************************************/
402 SdPage* pTestPage = (SdPage*) rDoc.GetMasterPage(nMPage);
403 String aTest(pTestPage->GetLayoutName());
404 aTest.Erase( aTest.SearchAscii( SD_LT_SEPARATOR ));
406 if (aTest == *pLayout)
407 bFound = TRUE;
410 if (!bFound)
411 mpLayoutsToTransfer->Insert(pLayout, LIST_APPEND);
412 else
413 delete pLayout;
417 BOOL SdDrawDocument::InsertBookmarkAsPage(
418 List* pBookmarkList,
419 List* pExchangeList, // Liste der zu verwendenen Namen
420 BOOL bLink,
421 BOOL bReplace,
422 USHORT nInsertPos,
423 BOOL bNoDialogs,
424 ::sd::DrawDocShell* pBookmarkDocSh,
425 BOOL bCopy,
426 BOOL bMergeMasterPages,
427 BOOL bPreservePageNames)
429 BOOL bOK = TRUE;
430 BOOL bContinue = TRUE;
431 BOOL bScaleObjects = FALSE;
432 USHORT nReplacedStandardPages = 0;
434 SdDrawDocument* pBookmarkDoc = NULL;
435 String aBookmarkName;
437 if (pBookmarkDocSh)
439 pBookmarkDoc = pBookmarkDocSh->GetDoc();
441 if (pBookmarkDocSh->GetMedium())
443 aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
446 else if ( mxBookmarkDocShRef.Is() )
448 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
449 aBookmarkName = maBookmarkFile;
451 else
453 return FALSE;
456 const USHORT nSdPageCount = GetSdPageCount(PK_STANDARD);
457 const USHORT nBMSdPageCount = pBookmarkDoc->GetSdPageCount(PK_STANDARD);
458 const USHORT nMPageCount = GetMasterPageCount();
460 if (nSdPageCount==0 || nBMSdPageCount==0 || nMPageCount==0)
462 bContinue = bOK = FALSE;
463 return(bContinue);
466 // Store the size and some other properties of the first page and notes
467 // page so that inserted pages can be properly scaled even when inserted
468 // before the first page.
469 // Note that the pointers are used later on as general page pointers.
470 SdPage* pRefPage = GetSdPage(0, PK_STANDARD);
471 Size aSize(pRefPage->GetSize());
472 INT32 nLeft = pRefPage->GetLftBorder();
473 INT32 nRight = pRefPage->GetRgtBorder();
474 INT32 nUpper = pRefPage->GetUppBorder();
475 INT32 nLower = pRefPage->GetLwrBorder();
476 Orientation eOrient = pRefPage->GetOrientation();
478 SdPage* pNPage = GetSdPage(0, PK_NOTES);
479 Size aNSize(GetSdPage(0, PK_NOTES)->GetSize());
480 INT32 nNLeft = pNPage->GetLftBorder();
481 INT32 nNRight = pNPage->GetRgtBorder();
482 INT32 nNUpper = pNPage->GetUppBorder();
483 INT32 nNLower = pNPage->GetLwrBorder();
484 Orientation eNOrient = pRefPage->GetOrientation();
486 // Seitengroesse und -raender an die Werte der letzten
487 // Seiten anpassen?
488 pRefPage = GetSdPage(nSdPageCount - 1, PK_STANDARD);
490 if( bNoDialogs )
492 if( !pBookmarkList )
493 bScaleObjects = pRefPage->IsScaleObjects();
494 else
495 bScaleObjects = TRUE;
497 else
499 SdPage* pBMPage = pBookmarkDoc->GetSdPage(0,PK_STANDARD);
501 if (pBMPage->GetSize() != pRefPage->GetSize() ||
502 pBMPage->GetLftBorder() != pRefPage->GetLftBorder() ||
503 pBMPage->GetRgtBorder() != pRefPage->GetRgtBorder() ||
504 pBMPage->GetUppBorder() != pRefPage->GetUppBorder() ||
505 pBMPage->GetLwrBorder() != pRefPage->GetLwrBorder())
507 String aStr(SdResId(STR_SCALE_OBJECTS));
508 USHORT nBut = QueryBox( NULL, WB_YES_NO_CANCEL, aStr).Execute();
510 bScaleObjects = nBut == RET_YES;
511 bContinue = nBut != RET_CANCEL;
513 if (!bContinue)
515 return(bContinue);
521 /**************************************************************************
522 |* Die benoetigten Praesentations-StyleSheets ermitteln und vor
523 |* den Seiten transferieren, sonst verlieren die Textobjekte
524 |* beim Transfer den Bezug zur Vorlage
525 \*************************************************************************/
526 SfxUndoManager* pUndoMgr = NULL;
527 if( mpDocSh )
529 pUndoMgr = mpDocSh->GetUndoManager();
530 pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_INSERTPAGES)), String());
533 List* pLayoutsToTransfer = new List;
536 // #96029# Refactored copy'n'pasted layout name collection into IterateBookmarkPages
538 InsertBookmarkAsPage_FindDuplicateLayouts aSearchFunctor( pLayoutsToTransfer, pBookmarkDoc,
539 pBookmarkList, nBMSdPageCount );
540 IterateBookmarkPages( pBookmarkDoc, pBookmarkList, nBMSdPageCount, aSearchFunctor );
543 /**************************************************************************
544 * Die tatsaechlich benoetigten Vorlagen kopieren
545 **************************************************************************/
546 SdStyleSheetPool* pBookmarkStyleSheetPool =
547 (SdStyleSheetPool*) pBookmarkDoc->GetStyleSheetPool();
548 String* pLayout = (String*) pLayoutsToTransfer->First();
550 // Wenn Vorlagen kopiert werden muessen, dann muessen auch die
551 // MasterPages kopiert werden!
552 if( pLayout )
553 bMergeMasterPages = TRUE;
555 while (pLayout)
557 SdStyleSheetVector aCreatedStyles;
559 ((SdStyleSheetPool*)GetStyleSheetPool())->CopyLayoutSheets(*pLayout, *pBookmarkStyleSheetPool,aCreatedStyles);
561 if(!aCreatedStyles.empty())
563 if( pUndoMgr )
565 SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, TRUE);
566 pUndoMgr->AddUndoAction(pMovStyles);
570 delete pLayout;
572 pLayout = (String*)pLayoutsToTransfer->Next();
575 delete pLayoutsToTransfer;
577 /**************************************************************************
578 * Dokument einfuegen
579 **************************************************************************/
581 const bool bUndo = IsUndoEnabled();
583 if( bUndo )
584 BegUndo(String(SdResId(STR_UNDO_INSERTPAGES)));
586 if (!pBookmarkList)
588 if (nInsertPos >= GetPageCount())
590 // Seiten werden hinten angefuegt
591 nInsertPos = GetPageCount();
594 USHORT nActualInsertPos = nInsertPos;
596 List aNameList;
597 std::set<USHORT> aRenameSet;
598 USHORT nBMSdPage;
600 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
602 SdPage* pBMPage = pBookmarkDoc->GetSdPage(nBMSdPage, PK_STANDARD);
603 String pName( pBMPage->GetName() );
604 BOOL bIsMasterPage;
606 if (bLink)
608 // Es werden sich die Namen aller Seiten gemerkt
609 aNameList.Insert(new String(pName), nBMSdPage);
612 // #95677# Have to check for duplicate names here, too
613 // #67905# don't change name if source and dest model are the same!
614 if( pBookmarkDoc != this &&
615 GetPageByName(pName, bIsMasterPage ) != SDRPAGE_NOTFOUND )
617 // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
618 aRenameSet.insert(nBMSdPage);
622 Merge(*pBookmarkDoc,
623 1, // Nicht die Handzettelseite
624 0xFFFF, // Aber alle anderen
625 nActualInsertPos, // An Position einfuegen
626 bMergeMasterPages, // MasterPages mitnehmen
627 FALSE, // Aber nur die benoetigten MasterPages
628 TRUE, // Undo-Aktion erzeugen
629 bCopy); // Seiten kopieren (oder mergen)
631 for (nBMSdPage=0; nBMSdPage < nBMSdPageCount; nBMSdPage++)
633 SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
634 SdPage* pNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
635 String* pName = (String*) aNameList.GetObject(nBMSdPage);
637 // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
638 if( aRenameSet.find(nBMSdPage) != aRenameSet.end() )
640 // Seitenname schon vorhanden -> Defaultname
641 // fuer Standard & Notizseite
642 pPage->SetName(String());
643 pNotesPage->SetName(String());
646 if (bLink)
648 // Nun werden die Link-Namen zusammengestellt
649 pPage->SetFileName(aBookmarkName);
650 pPage->SetBookmarkName(*(pName));
651 delete pName;
652 pPage->SetModel(this);
655 nActualInsertPos += 2;
658 else
660 /**********************************************************************
661 * Ausgewaehlte Seiten einfuegen
662 **********************************************************************/
663 SdPage* pBMPage;
665 if (nInsertPos >= GetPageCount())
667 // Seiten werden hinten angefuegt
668 bReplace = FALSE;
669 nInsertPos = GetPageCount();
672 USHORT nActualInsertPos = nInsertPos;
674 for (USHORT nPos = 0; nPos < pBookmarkList->Count(); nPos++)
676 /**************************************************************
677 * Namen der Bookmark-Seiten aus Liste holen
678 **************************************************************/
679 String aPgName(*(String*) pBookmarkList->GetObject(nPos));
680 BOOL bIsMasterPage;
681 USHORT nBMPage = pBookmarkDoc->GetPageByName( aPgName, bIsMasterPage );
683 if (nBMPage != SDRPAGE_NOTFOUND)
685 pBMPage = (SdPage*) pBookmarkDoc->GetPage(nBMPage);
687 else
689 pBMPage = NULL;
692 if (pBMPage && pBMPage->GetPageKind()==PK_STANDARD && !pBMPage->IsMasterPage())
694 /**************************************************************
695 * Es muss eine StandardSeite sein
696 **************************************************************/
697 sal_Bool bMustRename = sal_False;
699 // #95991# delay renaming *after* pages are copied (might destroy source otherwise)
700 // #67905# don't change name if source and dest model are the same!
701 // #96029# avoid renaming if replacing the same page
702 USHORT nPageSameName = GetPageByName(aPgName, bIsMasterPage);
703 if( pBookmarkDoc != this &&
704 nPageSameName != SDRPAGE_NOTFOUND &&
705 ( !bReplace ||
706 nPageSameName != nActualInsertPos ) )
708 bMustRename = sal_True;
711 SdPage* pBookmarkPage = dynamic_cast< SdPage* >( pBookmarkDoc->GetPage(nBMPage) );
712 if (bReplace )
714 ReplacePageInCustomShows( dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ), pBookmarkPage );
717 Merge(*pBookmarkDoc,
718 nBMPage, // Von Seite (Standard)
719 nBMPage+1, // Bis Seite (Notizen)
720 nActualInsertPos, // An Position einfuegen
721 bMergeMasterPages, // MasterPages mitnehmen
722 FALSE, // Aber nur die benoetigten MasterPages
723 TRUE, // Undo-Aktion erzeugen
724 bCopy); // Seiten kopieren (oder mergen)
726 if( bReplace )
728 if( GetPage( nActualInsertPos ) != pBookmarkPage )
730 // bookmark page was not moved but cloned, so update custom shows again
731 ReplacePageInCustomShows( pBookmarkPage, dynamic_cast< SdPage* >( GetPage( nActualInsertPos ) ) );
735 if( bMustRename )
737 // Seitenname schon vorhanden -> Defaultname
738 // fuer Standard & Notizseite
739 SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
740 pPage->SetName(String());
741 SdPage* pNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
742 pNotesPage->SetName(String());
745 if (bLink)
747 SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
748 pPage->SetFileName(aBookmarkName);
749 pPage->SetBookmarkName(aPgName);
750 pPage->SetModel(this);
753 if (bReplace)
755 // Seite & Notizseite ausfuegen
756 const sal_uInt16 nDestPageNum(nActualInsertPos + 2);
757 SdPage* pStandardPage = 0L;
759 if(nDestPageNum < GetPageCount())
761 pStandardPage = (SdPage*)GetPage(nDestPageNum);
764 if (pStandardPage)
766 if( bPreservePageNames )
768 // #96029# Take old slide names for inserted pages
769 SdPage* pPage = (SdPage*) GetPage(nActualInsertPos);
770 pPage->SetName( pStandardPage->GetRealName() );
773 if( bUndo )
774 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage));
776 RemovePage(nDestPageNum);
778 if( !bUndo )
779 delete pStandardPage;
782 SdPage* pNotesPage = 0L;
784 if(nDestPageNum < GetPageCount())
786 pNotesPage = (SdPage*)GetPage(nDestPageNum);
789 if (pNotesPage)
791 if( bPreservePageNames )
793 // #96029# Take old slide names for inserted pages
794 SdPage* pNewNotesPage = (SdPage*) GetPage(nActualInsertPos+1);
795 if( pNewNotesPage )
796 pNewNotesPage->SetName( pStandardPage->GetRealName() );
799 if( bUndo )
800 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
802 RemovePage(nDestPageNum);
804 if( !bUndo )
805 delete pNotesPage;
808 nReplacedStandardPages++;
811 nActualInsertPos += 2;
817 /**************************************************************************
818 |* Dabei sind evtl. zu viele Masterpages ruebergekommen, da die
819 |* DrawingEngine gleiche Praesentationslayouts nicht erkennen kann.
820 |* Ueberzaehlige MasterPages entfernen.
821 \*************************************************************************/
822 USHORT nNewMPageCount = GetMasterPageCount();
824 // rueckwaerts, damit Nummern nicht durcheinander geraten
825 for (USHORT nPage = nNewMPageCount - 1; nPage >= nMPageCount; nPage--)
827 pRefPage = (SdPage*) GetMasterPage(nPage);
828 String aMPLayout(pRefPage->GetLayoutName());
829 PageKind eKind = pRefPage->GetPageKind();
831 // gibt's den schon?
832 for (USHORT nTest = 0; nTest < nMPageCount; nTest++)
834 SdPage* pTest = (SdPage*) GetMasterPage(nTest);
835 String aTest(pTest->GetLayoutName());
837 // #96029# nInsertPos > 2 is always true when inserting into non-empty models
838 if ( nInsertPos > 2 &&
839 aTest == aMPLayout &&
840 eKind == pTest->GetPageKind() )
842 if( bUndo )
843 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage));
845 RemoveMasterPage(nPage);
847 if( !bUndo )
848 delete pRefPage;
849 nNewMPageCount--;
850 break;
855 // #96029# nInsertPos > 2 is always true when inserting into non-empty models
856 if (nInsertPos > 0)
858 USHORT nSdPageStart = (nInsertPos - 1) / 2;
859 USHORT nSdPageEnd = GetSdPageCount(PK_STANDARD) - nSdPageCount +
860 nSdPageStart - 1;
861 const bool bRemoveEmptyPresObj = pBookmarkDoc &&
862 (pBookmarkDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
863 (GetDocumentType() == DOCUMENT_TYPE_DRAW);
865 if( bReplace )
867 nSdPageEnd = nSdPageStart + nReplacedStandardPages - 1;
870 for (USHORT nSdPage = nSdPageStart; nSdPage <= nSdPageEnd; nSdPage++)
872 pRefPage = GetSdPage(nSdPage, PK_STANDARD);
874 if (pExchangeList)
876 // Zuverwendener Name aus Exchange-Liste holen
877 if (pExchangeList->GetCurObject())
879 String aExchangeName (*(String*) pExchangeList->GetCurObject());
880 pRefPage->SetName(aExchangeName);
881 SdrHint aHint(HINT_PAGEORDERCHG);
882 aHint.SetPage(pRefPage);
883 Broadcast(aHint);
884 SdPage* pNewNotesPage = GetSdPage(nSdPage, PK_NOTES);
885 pNewNotesPage->SetName(aExchangeName);
886 aHint.SetPage(pNewNotesPage);
887 Broadcast(aHint);
890 pExchangeList->Next();
893 String aLayout(pRefPage->GetLayoutName());
894 aLayout.Erase(aLayout.SearchAscii( SD_LT_SEPARATOR ));
896 // update layout and referred master page
897 pRefPage->SetPresentationLayout(aLayout);
898 if( bUndo )
899 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
901 if (bScaleObjects)
903 Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
904 pRefPage->ScaleObjects(aSize, aBorderRect, TRUE);
906 pRefPage->SetSize(aSize);
907 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
908 pRefPage->SetOrientation( eOrient );
910 if( bRemoveEmptyPresObj )
911 pRefPage->RemoveEmptyPresentationObjects();
913 pRefPage = GetSdPage(nSdPage, PK_NOTES);
915 // update layout and referred master page
916 pRefPage->SetPresentationLayout(aLayout);
917 if( bUndo )
918 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage ) );
920 if (bScaleObjects)
922 Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
923 pRefPage->ScaleObjects(aNSize, aBorderRect, TRUE);
926 pRefPage->SetSize(aNSize);
927 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
928 pRefPage->SetOrientation( eNOrient );
930 if( bRemoveEmptyPresObj )
931 pRefPage->RemoveEmptyPresentationObjects();
934 for (USHORT nPage = nMPageCount; nPage < nNewMPageCount; nPage++)
936 pRefPage = (SdPage*) GetMasterPage(nPage);
937 if (pRefPage->GetPageKind() == PK_STANDARD)
939 if (bScaleObjects)
941 Rectangle aBorderRect(nLeft, nUpper, nRight, nLower);
942 pRefPage->ScaleObjects(aSize, aBorderRect, TRUE);
944 pRefPage->SetSize(aSize);
945 pRefPage->SetBorder(nLeft, nUpper, nRight, nLower);
946 pRefPage->SetOrientation( eOrient );
948 else // kann nur noch NOTES sein
950 if (bScaleObjects)
952 Rectangle aBorderRect(nNLeft, nNUpper, nNRight, nNLower);
953 pRefPage->ScaleObjects(aNSize, aBorderRect, TRUE);
955 pRefPage->SetSize(aNSize);
956 pRefPage->SetBorder(nNLeft, nNUpper, nNRight, nNLower);
957 pRefPage->SetOrientation( eNOrient );
960 if( bRemoveEmptyPresObj )
961 pRefPage->RemoveEmptyPresentationObjects();
965 // #91146# Make absolutely sure no double masterpages are there
966 RemoveUnnecessaryMasterPages(NULL, TRUE, TRUE);
968 if( bUndo )
969 EndUndo();
970 pUndoMgr->LeaveListAction();
972 return bContinue;
975 /*************************************************************************
977 |* Fuegt ein Bookmark als Objekt ein
979 \************************************************************************/
981 BOOL SdDrawDocument::InsertBookmarkAsObject(
982 List* pBookmarkList,
983 List* pExchangeList, // Liste der zu verwendenen Namen
984 BOOL /* bLink */,
985 ::sd::DrawDocShell* pBookmarkDocSh,
986 Point* pObjPos)
988 BOOL bOK = TRUE;
989 BOOL bOLEObjFound = FALSE;
990 ::sd::View* pBMView = NULL;
992 SdDrawDocument* pBookmarkDoc = NULL;
993 String aBookmarkName;
995 if (pBookmarkDocSh)
997 pBookmarkDoc = pBookmarkDocSh->GetDoc();
999 if (pBookmarkDocSh->GetMedium())
1001 aBookmarkName = pBookmarkDocSh->GetMedium()->GetName();
1004 else if ( mxBookmarkDocShRef.Is() )
1006 pBookmarkDoc = mxBookmarkDocShRef->GetDoc();
1007 aBookmarkName = maBookmarkFile;
1009 else
1011 return FALSE;
1014 if (!pBookmarkList)
1016 pBMView = new ::sd::View(pBookmarkDoc, (OutputDevice*) NULL);
1017 pBMView->EndListening(*pBookmarkDoc);
1018 pBMView->MarkAll();
1020 else
1022 SdrPage* pPage;
1023 SdrPageView* pPV;
1025 for (USHORT nPos = 0; nPos < pBookmarkList->Count(); nPos++)
1027 /******************************************************************
1028 * Namen der Bookmarks aus Liste holen
1029 ******************************************************************/
1030 String aBMName (*(String*) pBookmarkList->GetObject(nPos));
1032 SdrObject* pObj = pBookmarkDoc->GetObj(aBMName);
1034 if (pObj)
1036 // Objekt gefunden
1038 if (pObj->GetObjInventor() == SdrInventor &&
1039 pObj->GetObjIdentifier() == OBJ_OLE2)
1041 bOLEObjFound = TRUE;
1044 if (!pBMView)
1046 // View erstmalig erzeugen
1047 pBMView = new ::sd::View(pBookmarkDoc, (OutputDevice*) NULL);
1048 pBMView->EndListening(*pBookmarkDoc);
1051 pPage = pObj->GetPage();
1053 if (pPage->IsMasterPage())
1055 pPV = pBMView->ShowSdrPage(pBMView->GetModel()->GetMasterPage(pPage->GetPageNum()));
1057 else
1059 pPV = pBMView->GetSdrPageView();
1060 if( !pPV || (pPV->GetPage() != pPage))
1061 pPV = pBMView->ShowSdrPage(pPage);
1064 pBMView->MarkObj(pObj, pPV, FALSE);
1069 if (pBMView)
1071 /**********************************************************************
1072 * Selektierte Objekte einfuegen
1073 **********************************************************************/
1074 ::sd::View* pView = new ::sd::View(this, (OutputDevice*) NULL);
1075 pView->EndListening(*this);
1077 // Seite bestimmen, auf der die Objekte eingefuegt werden sollen
1078 SdrPage* pPage = GetSdPage(0, PK_STANDARD);
1080 if (mpDocSh)
1082 ::sd::ViewShell* pViewSh = mpDocSh->GetViewShell();
1084 if (pViewSh)
1086 // Welche Seite wird denn aktuell angezeigt?
1087 SdrPageView* pPV = pViewSh->GetView()->GetSdrPageView();
1089 if (pPV)
1091 pPage = pPV->GetPage();
1093 else if (pViewSh->GetActualPage())
1095 pPage = pViewSh->GetActualPage();
1100 Point aObjPos;
1102 if (pObjPos)
1104 aObjPos = *pObjPos;
1106 else
1108 aObjPos = Rectangle(Point(), pPage->GetSize()).Center();
1111 ULONG nCountBefore = 0;
1113 if (pExchangeList)
1115 // OrdNums sortieren und Anzahl Objekte vor dem Einfuegen bestimmen
1116 pPage->RecalcObjOrdNums();
1117 nCountBefore = pPage->GetObjCount();
1120 if (bOLEObjFound)
1121 pBMView->GetDoc()->SetAllocDocSh(TRUE);
1123 SdDrawDocument* pTmpDoc = (SdDrawDocument*) pBMView->GetAllMarkedModel();
1124 bOK = pView->Paste(*pTmpDoc, aObjPos, pPage);
1126 if (bOLEObjFound)
1127 pBMView->GetDoc()->SetAllocDocSh(FALSE);
1129 if (!bOLEObjFound)
1130 delete pTmpDoc; // Wird ansonsten von der DocShell zerstoert
1132 delete pView;
1134 List* pList = pBookmarkList;
1136 if (pExchangeList)
1138 // Anzahl Objekte nach dem Einfuegen bestimmen
1139 ULONG nCount = pPage->GetObjCount();
1141 for (ULONG nObj = nCountBefore; nObj < nCount; nObj++)
1143 // Zuverwendener Name aus Exchange-Liste holen
1144 if (pExchangeList->GetCurObject())
1146 String aExchangeName (*(String*) pExchangeList->GetCurObject());
1148 if (pPage->GetObj(nObj))
1150 pPage->GetObj(nObj)->SetName(aExchangeName);
1154 pExchangeList->Next();
1157 pList = pExchangeList;
1161 delete pBMView;
1163 return bOK;
1166 /*************************************************************************
1168 |* Beendet das Einfuegen von Bookmarks
1170 \************************************************************************/
1172 void SdDrawDocument::CloseBookmarkDoc()
1174 if (mxBookmarkDocShRef.Is())
1176 mxBookmarkDocShRef->DoClose();
1179 mxBookmarkDocShRef.Clear();
1180 maBookmarkFile = String();
1183 /*************************************************************************
1185 |* Dokument laden (fuer gelinkte Objekte)
1187 \************************************************************************/
1189 const SdrModel* SdDrawDocument::LoadModel(const String& rFileName)
1191 return ( OpenBookmarkDoc(rFileName) );
1194 /*************************************************************************
1196 |* Dokument schliessen (fuer gelinkte Objekte)
1198 \************************************************************************/
1200 void SdDrawDocument::DisposeLoadedModels()
1202 CloseBookmarkDoc();
1205 /*************************************************************************
1207 |* Ist das Dokument read-only?
1209 \************************************************************************/
1211 FASTBOOL SdDrawDocument::IsReadOnly() const
1213 return FALSE;
1217 /*************************************************************************
1219 |* In anschliessendem AllocModel() wird eine DocShell erzeugt
1220 |* (xAllocedDocShRef). Eine bereits bestehende DocShell wird ggf. geloescht
1222 \************************************************************************/
1224 void SdDrawDocument::SetAllocDocSh(BOOL bAlloc)
1226 mbAllocDocSh = bAlloc;
1228 if(mxAllocedDocShRef.Is())
1230 mxAllocedDocShRef->DoClose();
1233 mxAllocedDocShRef.Clear();
1236 /*************************************************************************
1238 |* Liste der CustomShows zurueckgeben (ggf. zuerst erzeugen)
1240 \************************************************************************/
1242 List* SdDrawDocument::GetCustomShowList(BOOL bCreate)
1244 if (!mpCustomShowList && bCreate)
1246 // Liste erzeugen
1247 mpCustomShowList = new List();
1250 return(mpCustomShowList);
1253 /*************************************************************************
1255 |* Document-Stream herausgeben (fuer load-on-demand Graphiken)
1257 \************************************************************************/
1259 SvStream* SdDrawDocument::GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const
1261 uno::Reference < embed::XStorage > xStor;
1262 if (mpDocSh)
1263 xStor = mpDocSh->GetStorage();
1264 SvStream* pRet = NULL;
1266 if( xStor.is() )
1268 //TODO/MBA: binary format removed, needs testing
1269 if( rStreamInfo.maUserData.Len() &&
1270 ( rStreamInfo.maUserData.GetToken( 0, ':' ) ==
1271 String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
1273 const String aPicturePath( rStreamInfo.maUserData.GetToken( 1, ':' ) );
1275 // graphic from picture stream in picture storage in XML package
1276 if( aPicturePath.GetTokenCount( '/' ) == 2 ) try
1278 const String aPictureStreamName( aPicturePath.GetToken( 1, '/' ) );
1279 const String aPictureStorageName( aPicturePath.GetToken( 0, '/' ) );
1280 if( xStor->isStorageElement( aPictureStorageName ) )
1282 uno::Reference < embed::XStorage > xPictureStorage =
1283 xStor->openStorageElement( aPictureStorageName, embed::ElementModes::READ );
1286 if( xPictureStorage.is() && xPictureStorage->isStreamElement( aPictureStreamName ) )
1288 uno::Reference < io::XStream > xStream = xPictureStorage->openStreamElement( aPictureStreamName, embed::ElementModes::READ );
1289 if( xStream.is() )
1290 pRet = ::utl::UcbStreamHelper::CreateStream( xStream );
1293 catch( container::NoSuchElementException& )
1298 catch( uno::Exception& e )
1300 (void)e;
1301 DBG_ERROR(
1302 (rtl::OString("sd::SdDrawDocument::GetDocumentStream(), "
1303 "exception caught: ") +
1304 rtl::OUStringToOString(
1305 comphelper::anyToString( cppu::getCaughtException() ),
1306 RTL_TEXTENCODING_UTF8 ) +
1307 rtl::OString("\r\nATTENTION: Graphics may get lost now, please inform CL or KA!") ).getStr() );
1310 rStreamInfo.mbDeleteAfterUse = ( pRet != NULL );
1314 #if OSL_DEBUG_LEVEL > 1
1315 if( pRet )
1317 // try to get some information from stream
1318 const ULONG nStartPos = pRet->Tell();
1319 const ULONG nEndPos = pRet->Seek( STREAM_SEEK_TO_END );
1320 const ULONG nStmLen = nEndPos - nStartPos;
1321 sal_uChar aTestByte;
1323 // try to read one byte
1324 if( nStmLen )
1325 *pRet >> aTestByte;
1327 pRet->Seek( nStartPos );
1329 #endif
1331 return pRet;
1335 /*************************************************************************
1337 |* Nicht benutzte MasterPages und Layouts entfernen
1339 \************************************************************************/
1341 void SdDrawDocument::RemoveUnnecessaryMasterPages(SdPage* pMasterPage, BOOL bOnlyDuplicatePages, BOOL bUndo)
1343 ::sd::View* pView = NULL;
1344 SfxUndoManager* pUndoMgr = NULL;
1346 if( bUndo && !IsUndoEnabled() )
1347 bUndo = FALSE;
1349 if (mpDocSh)
1351 pUndoMgr = mpDocSh->GetUndoManager();
1353 if (mpDocSh->GetViewShell())
1354 pView = mpDocSh->GetViewShell()->GetView();
1357 /***********************************************************
1358 * Alle MasterPages pruefen
1359 ***********************************************************/
1360 USHORT nSdMasterPageCount = GetMasterSdPageCount( PK_STANDARD );
1361 for (sal_Int32 nMPage = nSdMasterPageCount - 1; nMPage >= 0; nMPage--)
1363 SdPage* pMaster = pMasterPage;
1364 SdPage* pNotesMaster = NULL;
1366 if (!pMaster)
1368 pMaster = (SdPage*) GetMasterSdPage( (USHORT) nMPage, PK_STANDARD );
1369 pNotesMaster = (SdPage*) GetMasterSdPage( (USHORT) nMPage, PK_NOTES );
1371 else
1373 for ( USHORT nMPg = 0; nMPg < GetMasterPageCount(); nMPg++ )
1375 if ( pMaster == GetMasterPage( nMPg ) )
1377 pNotesMaster = (SdPage*) GetMasterPage( ++nMPg );
1378 break;
1383 DBG_ASSERT( pMaster->GetPageKind() == PK_STANDARD, "wrong page kind" );
1385 if ( pMaster->GetPageKind() == PK_STANDARD &&
1386 GetMasterPageUserCount( pMaster ) == 0 &&
1387 pNotesMaster )
1389 // Do not delete master pages that have their precious flag set.
1390 BOOL bDeleteMaster = !pMaster->IsPrecious();
1391 String aLayoutName = pMaster->GetLayoutName();
1393 if(bOnlyDuplicatePages )
1395 // remove only duplicate pages
1396 bDeleteMaster = FALSE;
1397 for (USHORT i = 0; i < GetMasterSdPageCount( PK_STANDARD ); i++)
1399 SdPage* pMPg = (SdPage*) GetMasterSdPage( i, PK_STANDARD );
1400 if( pMPg != pMaster &&
1401 pMPg->GetLayoutName() == aLayoutName )
1403 // duplicate page found -> remove it
1404 bDeleteMaster = TRUE;
1409 if( bDeleteMaster )
1411 if (pView)
1413 // if MasterPage is visible hide on pageview
1414 SdrPageView* pPgView = pView->GetSdrPageView();
1415 if (pPgView)
1417 SdrPage* pShownPage = pPgView->GetPage();
1418 if( (pShownPage == pMaster) || (pShownPage == pNotesMaster) )
1420 pView->HideSdrPage();
1421 pView->ShowSdrPage( GetSdPage( 0, PK_STANDARD ) );
1426 if( bUndo )
1428 BegUndo();
1429 AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster ) );
1432 RemoveMasterPage( pNotesMaster->GetPageNum() );
1434 if( !bUndo )
1435 delete pNotesMaster;
1437 if( bUndo )
1438 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster));
1440 RemoveMasterPage( pMaster->GetPageNum() );
1442 if( !bUndo )
1443 delete pMaster;
1445 if( bUndo )
1446 EndUndo(); // schon hier, damit sich Joes Actions ZWISCHEN unsere eigenen schieben
1448 // alte Layoutvorlagen loeschen, wenn sie nicht mehr benoetigt werden
1449 BOOL bDeleteOldStyleSheets = TRUE;
1450 for ( USHORT nMPg = 0;
1451 nMPg < GetMasterPageCount() && bDeleteOldStyleSheets;
1452 nMPg++ )
1454 SdPage* pMPg = (SdPage*) GetMasterPage(nMPg);
1455 if (pMPg->GetLayoutName() == aLayoutName)
1457 bDeleteOldStyleSheets = FALSE;
1461 if (bDeleteOldStyleSheets)
1463 SdStyleSheetVector aRemove;
1464 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList( aLayoutName, aRemove );
1466 if( bUndo )
1468 // die Liste gehoert der UndoAction
1469 SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aRemove, false );
1471 if (pUndoMgr)
1472 pUndoMgr->AddUndoAction(pMovStyles);
1475 for( SdStyleSheetVector::iterator iter = aRemove.begin(); iter != aRemove.end(); iter++ )
1476 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->Remove((*iter).get());
1481 if (pMasterPage)
1482 break; // Nur diese eine MasterPage!
1487 /*************************************************************************
1489 |* MasterPage austauschen
1491 |* Entweder erhaelt nSdPageNum eine neue, eigene MasterPage, oder die MasterPage
1492 |* wird komplett ausgetauscht (gilt dann fuer alle Seiten).
1494 |* nSdPageNum : Nummer der Seite, welche die neue MasterPage erhalten soll
1495 |* rLayoutName : LayoutName der neuen MasterPage
1496 |* pSourceDoc : Dokument (Vorlage) aus dem die MasterPage geholt wird
1497 |* bMaster : Die MasterPage von nSdPageNum soll ausgetauscht werden
1498 |* bCheckMasters: Nicht benutzte MasterPages sollen entfernt werden
1500 |* Ist pSourceDoc == NULL, so wird eine leere MasterPage zugewiesen.
1501 |* Ist rLayoutName leer, so wird die erste MasterPage genommen
1502 \************************************************************************/
1504 void SdDrawDocument::SetMasterPage(USHORT nSdPageNum,
1505 const String& rLayoutName,
1506 SdDrawDocument* pSourceDoc,
1507 BOOL bMaster,
1508 BOOL bCheckMasters)
1510 if( mpDocSh )
1511 mpDocSh->SetWaitCursor( TRUE );
1513 SfxUndoManager* pUndoMgr = mpDocSh->GetUndoManager();
1515 const bool bUndo = IsUndoEnabled();
1517 if( bUndo )
1519 pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
1522 SdPage* pSelectedPage = GetSdPage(nSdPageNum, PK_STANDARD);
1523 SdPage* pNotes = (SdPage*) GetPage(pSelectedPage->GetPageNum()+1);
1524 SdPage& rOldMaster = (SdPage&)pSelectedPage->TRG_GetMasterPage();
1525 SdPage& rOldNotesMaster = (SdPage&)pNotes->TRG_GetMasterPage();
1526 SdPage* pMaster = NULL;
1527 SdPage* pNotesMaster = NULL;
1528 SdPage* pPage = NULL;
1529 String aOldPageLayoutName(pSelectedPage->GetLayoutName());
1530 String aOldLayoutName(aOldPageLayoutName);
1531 aOldLayoutName.Erase(aOldLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1533 String aNewLayoutName( rLayoutName );
1535 if (pSourceDoc)
1537 List* pReplList = NULL;
1538 BOOL bLayoutReloaded = FALSE; // Wurde ex. Layout wieder geladen?
1540 /*********************************************************************
1541 |* LayoutName, Page and Notespage
1542 \*********************************************************************/
1543 if (rLayoutName.Len() == 0)
1545 // No LayoutName: take first MasterPage
1546 pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1547 pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1548 aNewLayoutName = pMaster->GetName();
1550 else
1552 String aSearchFor(rLayoutName);
1553 aSearchFor.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1554 aSearchFor.Append( String(SdResId(STR_LAYOUT_OUTLINE))) ;
1556 for (USHORT nMP = 0; nMP < pSourceDoc->GetMasterPageCount(); nMP++)
1558 SdPage* pMP = (SdPage*) pSourceDoc->GetMasterPage(nMP);
1560 if (pMP->GetLayoutName() == aSearchFor)
1562 if (pMP->GetPageKind() == PK_STANDARD)
1563 pMaster = pMP;
1564 if (pMP->GetPageKind() == PK_NOTES)
1565 pNotesMaster = pMP;
1567 if (pMaster && pNotesMaster)
1568 break;
1570 DBG_ASSERT(pMaster, "MasterPage (Standard page) not found");
1571 DBG_ASSERT(pNotesMaster, "MasterPage (Notes page) not found");
1573 // this should not happen, but looking at crashreports, it does
1574 if( (pMaster == NULL) || (pNotesMaster == NULL) )
1576 // so take the first MasterPage
1577 pMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_STANDARD);
1578 pNotesMaster = (SdPage*) pSourceDoc->GetMasterSdPage(0, PK_NOTES);
1579 aNewLayoutName = pMaster->GetName();
1583 // we should never reach this, but one never knows....
1584 if( (pMaster == NULL) || (pNotesMaster == NULL) )
1586 pUndoMgr->LeaveListAction();
1588 if( mpDocSh )
1589 mpDocSh->SetWaitCursor( FALSE );
1591 DBG_ERROR( "SdDrawDocument::SetMasterPage() failed!" );
1593 return;
1596 if (pSourceDoc != this)
1598 const USHORT nMasterPageCount = GetMasterPageCount();
1599 for ( USHORT nMPage = 0; nMPage < nMasterPageCount; nMPage++ )
1601 SdPage* pCheckMaster = (SdPage*)GetMasterPage(nMPage);
1602 if( pCheckMaster->GetName() == aNewLayoutName )
1604 bLayoutReloaded = TRUE;
1605 break;
1609 /*****************************************************************
1610 |* Praesentationsvorlagen korrigieren bzw. neu anlegen
1611 \****************************************************************/
1612 // nur die Praesentationsvorlagen beachten
1613 String aName;
1614 SdStyleSheetPool* pSourceStyleSheetPool = (SdStyleSheetPool*) pSourceDoc->GetStyleSheetPool();
1615 pSourceStyleSheetPool->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1616 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->SetSearchMask(SD_STYLE_FAMILY_MASTERPAGE);
1618 pReplList = new List; // Liste fuer ersetzte StyleSheets
1619 SdStyleSheetVector aCreatedStyles; // Liste fuer erzeugte StyleSheets
1621 SfxStyleSheetBase* pHisSheet = pSourceStyleSheetPool->First();
1623 while (pHisSheet)
1625 aName = pHisSheet->GetName();
1627 if( aName.Search( aNewLayoutName ) == 0 )
1629 SfxStyleSheet* pMySheet = static_cast<SfxStyleSheet*>( mxStyleSheetPool->Find(aName, SD_STYLE_FAMILY_MASTERPAGE) );
1631 if (pMySheet)
1633 // Es ist eine gleichnamige Vorlage vorhanden ist: Inhalte ersetzen
1634 #ifdef DBG_UTIL
1635 BOOL bTest =
1636 #endif
1637 pMySheet->SetName(pHisSheet->GetName());
1638 DBG_ASSERT(bTest, "StyleSheet-Umbenennung fehlgeschlagen");
1639 pMySheet->GetItemSet().ClearItem(0); // alle loeschen
1641 StyleSheetUndoAction* pUndoChStyle = new StyleSheetUndoAction(this,
1642 pMySheet, &pHisSheet->GetItemSet());
1643 pUndoMgr->AddUndoAction(pUndoChStyle);
1644 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1645 pMySheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
1647 else
1649 // create new style
1650 String aHelpFile;
1651 pMySheet = static_cast<SfxStyleSheet*>( &mxStyleSheetPool->Make(aName, SD_STYLE_FAMILY_MASTERPAGE, pHisSheet->GetMask()) );
1652 pMySheet->SetHelpId( aHelpFile, pHisSheet->GetHelpId(aHelpFile) );
1653 pMySheet->GetItemSet().ClearItem(0); // alle loeschen
1654 pMySheet->GetItemSet().Put(pHisSheet->GetItemSet());
1656 aCreatedStyles.push_back( SdStyleSheetRef( static_cast< SdStyleSheet* >( pMySheet ) ) );
1659 StyleReplaceData* pReplData = new StyleReplaceData;
1660 pReplData->nNewFamily = pMySheet->GetFamily();
1661 pReplData->nFamily = pMySheet->GetFamily();
1662 pReplData->aNewName = pMySheet->GetName();
1664 String aTemp(pMySheet->GetName());
1665 USHORT nPos = aTemp.SearchAscii( SD_LT_SEPARATOR );
1666 aTemp.Erase(0, nPos);
1667 aTemp.Insert(aOldLayoutName, 0);
1668 pReplData->aName = aTemp;
1669 pReplList->Insert(pReplData, LIST_APPEND);
1672 pHisSheet = (SfxStyleSheet*) pSourceStyleSheetPool->Next();
1675 // wenn neue Vorlagen erzeugt wurden:
1676 // eventuell bestehende Parent-Verkettung der Itemsets in den
1677 // Vorlagen wieder aufbauen
1678 if(!aCreatedStyles.empty())
1680 StyleReplaceData* pRData = (StyleReplaceData*)pReplList->First();
1682 while (pRData)
1684 SfxStyleSheetBase* pSOld = mxStyleSheetPool->Find(pRData->aName);
1685 SfxStyleSheetBase* pSNew = mxStyleSheetPool->Find(pRData->aNewName);
1687 if (pSOld && pSNew)
1689 const String& rParentOfOld = pSOld->GetParent();
1690 const String& rParentOfNew = pSNew->GetParent();
1692 if (rParentOfOld.Len() > 0 && rParentOfNew.Len() == 0)
1695 for (ULONG i = 0; i < pReplList->Count(); i++)
1697 StyleReplaceData* pRD = (StyleReplaceData*)pReplList->
1698 GetObject(i);
1699 if ((pRD->aName == rParentOfOld) && (pRD->aName != pRD->aNewName))
1701 String aParentOfNew(pRD->aNewName);
1702 pSNew->SetParent(aParentOfNew);
1703 break;
1708 pRData = (StyleReplaceData*) pReplList->Next();
1711 // ab jetzt beim Suchen alle beachten
1712 pSourceStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1713 mxStyleSheetPool->SetSearchMask(SFX_STYLE_FAMILY_ALL);
1716 if( !aCreatedStyles.empty() )
1718 // UndoAction fuer das Erzeugen und Einfuegen vorn StyleSheets
1719 // auf den UndoManager legen
1720 SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction( this, aCreatedStyles, TRUE);
1721 pUndoMgr->AddUndoAction(pMovStyles);
1725 // Layoutnamen auf Basis des Seitenlayoutnamens der Masterpage bilden
1726 String aPageLayoutName(pMaster->GetLayoutName());
1727 String aLayoutName = aPageLayoutName;
1728 aLayoutName.Erase( aLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1730 if (pSourceDoc != this)
1732 // Aus dem Source-Dokument austragen
1733 SdrPage* pTest = NULL;
1734 pTest = pSourceDoc->RemoveMasterPage(pNotesMaster->GetPageNum());
1735 pTest = pSourceDoc->RemoveMasterPage(pMaster->GetPageNum());
1738 /*********************************************************************
1739 |* Neue MasterPages ins Dokument eintragen und den Standard- und
1740 |* Notizseiten das Praesentationslayout ueberbraten
1741 \********************************************************************/
1742 if (pSourceDoc != this)
1744 // Die Masterpages einfuegen:
1745 // Masterpages von neuen Layouts hinten anhaengen; wird ein Layout
1746 // dagegen ersetzt, so muss vor der Position der alten Masterpage
1747 // eingefuegt werden, damit ab jetzt beim Suchen (z. B. SdPage::
1748 // SetPresentationLayout) die neue Masterpage zuerst gefunden wird
1749 USHORT nInsertPos = rOldMaster.GetPageNum();
1750 BegUndo();
1752 if (!bLayoutReloaded)
1753 nInsertPos = 0xFFFF;
1754 InsertMasterPage(pMaster, nInsertPos);
1755 if( bUndo )
1756 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1758 nInsertPos++;
1759 if (!bLayoutReloaded)
1760 nInsertPos = 0xFFFF;
1761 InsertMasterPage(pNotesMaster, nInsertPos);
1762 if( bUndo )
1764 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1766 EndUndo(); // schon hier, damit sich Joes Actions ZWISCHEN unsere eigenen schieben
1770 // Liste mit Seiten fuellen
1771 List* pPageList = new List;
1773 // #98456, this has to be removed according to CL (KA 07/08/2002)
1774 // #109884# but we need them again to restore the styles of the presentation objects while undo
1775 pPageList->Insert(pMaster, LIST_APPEND);
1776 pPageList->Insert(pNotesMaster, LIST_APPEND);
1778 if (bMaster || bLayoutReloaded)
1780 for (USHORT nPage = 1; nPage < GetPageCount(); nPage++)
1782 pPage = (SdPage*) GetPage(nPage);
1783 String aTest = pPage->GetLayoutName();
1784 if (aTest == aOldPageLayoutName)
1786 pPageList->Insert(pPage, LIST_APPEND);
1791 else
1793 pPageList->Insert(pSelectedPage, LIST_APPEND);
1794 pPageList->Insert(pNotes, LIST_APPEND);
1797 pPage = (SdPage*)pPageList->First();
1798 while (pPage)
1800 AutoLayout eAutoLayout = pPage->GetAutoLayout();
1802 if( bUndo )
1804 SdPresentationLayoutUndoAction * pPLUndoAction =
1805 new SdPresentationLayoutUndoAction
1806 (this,
1807 pPage->IsMasterPage() ? aLayoutName : aOldLayoutName,
1808 aLayoutName,
1809 eAutoLayout, eAutoLayout, FALSE, pPage);
1810 pUndoMgr->AddUndoAction(pPLUndoAction);
1812 pPage->SetPresentationLayout(aLayoutName);
1813 pPage->SetAutoLayout(eAutoLayout);
1815 pPage = (SdPage*)pPageList->Next();
1817 delete pPageList;
1819 /*********************************************************************
1820 |* Neue Masterpages angleichen
1821 \********************************************************************/
1822 if (pSourceDoc != this)
1824 // die Masterpages angleichen
1825 Size aSize(rOldMaster.GetSize());
1826 Rectangle aBorderRect(rOldMaster.GetLftBorder(),
1827 rOldMaster.GetUppBorder(),
1828 rOldMaster.GetRgtBorder(),
1829 rOldMaster.GetLwrBorder());
1830 pMaster->ScaleObjects(aSize, aBorderRect, TRUE);
1831 pMaster->SetSize(aSize);
1832 pMaster->SetBorder(rOldMaster.GetLftBorder(),
1833 rOldMaster.GetUppBorder(),
1834 rOldMaster.GetRgtBorder(),
1835 rOldMaster.GetLwrBorder());
1836 pMaster->SetOrientation( rOldMaster.GetOrientation() );
1837 pMaster->SetAutoLayout(pMaster->GetAutoLayout());
1839 aSize = rOldNotesMaster.GetSize();
1840 Rectangle aNotesBorderRect(rOldNotesMaster.GetLftBorder(),
1841 rOldNotesMaster.GetUppBorder(),
1842 rOldNotesMaster.GetRgtBorder(),
1843 rOldNotesMaster.GetLwrBorder());
1844 pNotesMaster->ScaleObjects(aSize, aNotesBorderRect, TRUE);
1845 pNotesMaster->SetSize(aSize);
1846 pNotesMaster->SetBorder(rOldNotesMaster.GetLftBorder(),
1847 rOldNotesMaster.GetUppBorder(),
1848 rOldNotesMaster.GetRgtBorder(),
1849 rOldNotesMaster.GetLwrBorder());
1850 pNotesMaster->SetOrientation( rOldNotesMaster.GetOrientation() );
1851 pNotesMaster->SetAutoLayout(pNotesMaster->GetAutoLayout());
1853 // Liste der ersetzten Vorlagen mit Inhalt loeschen
1854 StyleReplaceData* pReplData = (StyleReplaceData*)pReplList->First();
1855 while (pReplData)
1857 delete pReplData;
1858 pReplData = (StyleReplaceData*)pReplList->Next();
1860 delete pReplList;
1863 if( (pSourceDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) &&
1864 (GetDocumentType() == DOCUMENT_TYPE_DRAW) )
1866 pMaster->RemoveEmptyPresentationObjects();
1867 pNotesMaster->RemoveEmptyPresentationObjects();
1871 else
1873 /*********************************************************************
1874 |* Einen neuen Layoutnamen ausdenken
1875 \********************************************************************/
1876 String aName = String(SdResId(STR_LAYOUT_DEFAULT_NAME));
1877 String aTest;
1878 BOOL bNotANewName = TRUE;
1879 USHORT nCount = 0;
1880 USHORT nMPgCount = GetMasterPageCount();
1882 for (nCount = 0; bNotANewName; nCount++)
1884 // Testnamen bilden
1885 aTest = aName; // Standard, Standard1, Standard2, ...
1886 if (nCount > 0)
1887 aTest += String::CreateFromInt32( nCount );
1889 // gibt's schon eine, die so heisst?
1890 bNotANewName = FALSE;
1891 for (USHORT nMPg = 1; nMPg < nMPgCount; nMPg++)
1893 const SdrPage* pTest = GetMasterPage(nMPg);
1894 String aPageLayoutName(pTest->GetLayoutName());
1895 aPageLayoutName.Erase( aPageLayoutName.SearchAscii( SD_LT_SEPARATOR ));
1897 if (aPageLayoutName == aTest)
1898 bNotANewName = TRUE;
1901 aName = aTest;
1902 String aPageLayoutName(aName);
1903 aPageLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
1904 aPageLayoutName += String(SdResId(STR_LAYOUT_OUTLINE));
1906 /*********************************************************************
1907 |* Neue StyleSheets erzeugen
1908 \********************************************************************/
1909 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutStyleSheets(aName);
1910 SdStyleSheetVector aCreatedStyles;
1911 static_cast<SdStyleSheetPool*>( mxStyleSheetPool.get())->CreateLayoutSheetList(aName, aCreatedStyles);
1913 if( bUndo )
1915 SdMoveStyleSheetsUndoAction* pMovStyles = new SdMoveStyleSheetsUndoAction(this, aCreatedStyles, TRUE);
1916 pUndoMgr->AddUndoAction(pMovStyles);
1919 /*********************************************************************
1920 |* Neue MasterPages erzeugen und ins Dokument eintragen
1921 \********************************************************************/
1923 if( bUndo )
1924 BegUndo();
1926 pMaster = (SdPage*) AllocPage(TRUE);
1927 pMaster->SetSize(pSelectedPage->GetSize());
1928 pMaster->SetBorder(pSelectedPage->GetLftBorder(),
1929 pSelectedPage->GetUppBorder(),
1930 pSelectedPage->GetRgtBorder(),
1931 pSelectedPage->GetLwrBorder() );
1932 pMaster->SetName(aName);
1933 pMaster->SetLayoutName(aPageLayoutName);
1934 InsertMasterPage(pMaster);
1936 if( bUndo )
1937 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster));
1939 pMaster->SetAutoLayout(AUTOLAYOUT_NONE, true, true);
1941 pNotesMaster = (SdPage*) AllocPage(TRUE);
1942 pNotesMaster->SetPageKind(PK_NOTES);
1943 pNotesMaster->SetSize(pNotes->GetSize());
1944 pNotesMaster->SetBorder(pNotes->GetLftBorder(),
1945 pNotes->GetUppBorder(),
1946 pNotes->GetRgtBorder(),
1947 pNotes->GetLwrBorder() );
1948 pNotesMaster->SetName(aName);
1949 pNotesMaster->SetLayoutName(aPageLayoutName);
1950 InsertMasterPage(pNotesMaster);
1952 if( bUndo )
1953 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster));
1955 pNotesMaster->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
1957 if( bUndo )
1958 EndUndo();
1960 /*********************************************************************
1961 |* Liste der betroffenen Standard- und Notizseiten erstellen
1962 \********************************************************************/
1963 List* pPageList = new List;
1964 if (bMaster)
1966 for (USHORT nPage = 1; nPage < GetPageCount(); nPage++)
1968 pPage = (SdPage*) GetPage(nPage);
1969 const String s(pPage->GetLayoutName());
1970 if(s == aOldPageLayoutName)
1972 pPageList->Insert(pPage, LIST_APPEND);
1976 else
1978 pPageList->Insert(pSelectedPage, LIST_APPEND);
1979 pPageList->Insert(pNotes, LIST_APPEND);
1982 /*********************************************************************
1983 |* An den betroffenen Seiten Praesentations- und Autolayout setzen
1984 \********************************************************************/
1985 pPage = (SdPage*)pPageList->First();
1986 while(pPage)
1988 AutoLayout eOldAutoLayout = pPage->GetAutoLayout();
1989 AutoLayout eNewAutoLayout =
1990 pPage->GetPageKind() == PK_STANDARD ? AUTOLAYOUT_NONE : AUTOLAYOUT_NOTES;
1992 if( bUndo )
1994 SdPresentationLayoutUndoAction * pPLUndoAction =
1995 new SdPresentationLayoutUndoAction
1996 (this, aOldLayoutName, aName,
1997 eOldAutoLayout, eNewAutoLayout, TRUE,
1998 pPage);
1999 pUndoMgr->AddUndoAction(pPLUndoAction);
2002 pPage->SetPresentationLayout(aName);
2003 pPage->SetAutoLayout(eNewAutoLayout);
2005 pPage = (SdPage*)pPageList->Next();
2008 // Seitenliste loeschen
2009 delete pPageList;
2012 /*********************************************************************
2013 |* falls die alten Masterpages nicht mehr benoetigt werden,
2014 |* muessen sie und die entsprechenden Praesentationsvorlagen
2015 |* entfernt werden
2016 \********************************************************************/
2017 if (bCheckMasters)
2019 // Alle pruefen
2020 RemoveUnnecessaryMasterPages();
2022 else
2024 // Nur die ausgetauschte MasterPage pruefen
2025 RemoveUnnecessaryMasterPages(&rOldMaster);
2028 if( bUndo )
2029 pUndoMgr->LeaveListAction();
2031 if( mpDocSh )
2032 mpDocSh->SetWaitCursor( FALSE );
2037 void SdDrawDocument::Merge(SdrModel& rSourceModel,
2038 USHORT nFirstPageNum, USHORT nLastPageNum,
2039 USHORT nDestPos,
2040 FASTBOOL bMergeMasterPages, FASTBOOL bAllMasterPages,
2041 FASTBOOL bUndo, FASTBOOL bTreadSourceAsConst)
2043 sal_uInt16 nMasterPageCount = GetMasterPageCount();
2044 SdrModel::Merge( rSourceModel, nFirstPageNum, nLastPageNum, nDestPos, bMergeMasterPages, bAllMasterPages, bUndo, bTreadSourceAsConst );
2046 // add style family for each new master page
2047 for( sal_uInt16 nMaster = nMasterPageCount; nMaster < GetMasterPageCount(); nMaster++ )
2049 SdPage* pPage = static_cast< SdPage* >( GetMasterPage( nMaster ) );
2050 if( pPage && pPage->IsMasterPage() && (pPage->GetPageKind() == PK_STANDARD) )
2052 // new master page created, add its style family
2053 SdStyleSheetPool* pStylePool = (SdStyleSheetPool*) GetStyleSheetPool();
2054 if( pStylePool )
2055 pStylePool->AddStyleFamily( pPage );