1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawdoc3.cxx,v $
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"
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>
65 #include "drawdoc.hxx"
67 #include "stlpool.hxx"
68 #include "sdresid.hxx"
69 #include "sdiocmpt.hxx"
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;
99 SdStorageListener ( uno::Reference < embed::XStorage >& rStor )
103 void disposing ( const lang::EventObject& aEvent ) throw ( uno::RuntimeException );
106 void SdStorageListener::disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException )
111 SdDrawDocument
* SdDrawDocument::OpenBookmarkDoc(SfxMedium
& rMedium
)
114 SdDrawDocument
* pBookmarkDoc
= NULL
;
115 String aBookmarkName
= rMedium
.GetName();
116 const SfxFilter
* pFilter
= rMedium
.GetFilter();
119 rMedium
.UseInteractionHandler( TRUE
);
120 SFX_APP()->GetFilterMatcher().GuessFilter( rMedium
, &pFilter
);
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
)
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
139 if ( bCreateGraphicShell
)
141 mxBookmarkDocShRef
= new ::sd::GraphicDocShell(SFX_CREATE_MODE_STANDARD
, TRUE
);
144 mxBookmarkDocShRef
= new ::sd::DrawDocShell(SFX_CREATE_MODE_STANDARD
, TRUE
);
146 bOK
= mxBookmarkDocShRef
->DoLoad(&rMedium
);
149 maBookmarkFile
= aBookmarkName
;
150 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
155 DBG_ASSERT(aBookmarkName
.Len(), "Empty document name!");
159 ErrorBox
aErrorBox( NULL
, (WinBits
)WB_OK
, String(SdResId(STR_READ_DATA_ERROR
)));
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
214 BOOL bInsertPages
= FALSE
;
218 /**********************************************************************
219 * Alle Seiten werden eingefuegt
220 **********************************************************************/
225 SdDrawDocument
* pBookmarkDoc
= NULL
;
226 String aBookmarkName
;
230 pBookmarkDoc
= pBookmarkDocSh
->GetDoc();
231 aBookmarkName
= pBookmarkDocSh
->GetMedium()->GetName();
233 else if ( mxBookmarkDocShRef
.Is() )
235 pBookmarkDoc
= mxBookmarkDocShRef
->GetDoc();
236 aBookmarkName
= maBookmarkFile
;
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
));
249 if( pBookmarkDoc
->GetPageByName( aBMPgName
, bIsMasterPage
) != SDRPAGE_NOTFOUND
)
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
);
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
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
304 // no list? whole source document
305 nEndPos
= nBMSdPageCount
;
309 // bookmark list? number of entries
310 nEndPos
= pBookmarkList
->Count();
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
;
323 // simply take master page of nPos'th page in source document
324 pBMMPage
= (SdPage
*)(&(pBookmarkDoc
->GetSdPage((USHORT
)nPos
, PK_STANDARD
)->TRG_GetMasterPage()));
328 // fetch nPos'th entry from bookmark list, and determine master page
329 String
aBMPgName (*(String
*) pBookmarkList
->GetObject(nPos
));
332 USHORT nBMPage
= pBookmarkDoc
->GetPageByName( aBMPgName
, bIsMasterPage
);
334 if (nBMPage
!= SDRPAGE_NOTFOUND
)
336 pBMPage
= (SdPage
*) pBookmarkDoc
->GetPage(nBMPage
);
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?
355 rPageIterator( *this, pBMMPage
);
360 class InsertBookmarkAsPage_FindDuplicateLayouts
: public SdDrawDocument::InsertBookmarkAsPage_PageFunctorBase
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
* );
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();
388 while (pTest
&& !bFound
) // found yet?
390 if (*pLayout
== *pTest
)
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
)
411 mpLayoutsToTransfer
->Insert(pLayout
, LIST_APPEND
);
417 BOOL
SdDrawDocument::InsertBookmarkAsPage(
419 List
* pExchangeList
, // Liste der zu verwendenen Namen
424 ::sd::DrawDocShell
* pBookmarkDocSh
,
426 BOOL bMergeMasterPages
,
427 BOOL bPreservePageNames
)
430 BOOL bContinue
= TRUE
;
431 BOOL bScaleObjects
= FALSE
;
432 USHORT nReplacedStandardPages
= 0;
434 SdDrawDocument
* pBookmarkDoc
= NULL
;
435 String aBookmarkName
;
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
;
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
;
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
488 pRefPage
= GetSdPage(nSdPageCount
- 1, PK_STANDARD
);
493 bScaleObjects
= pRefPage
->IsScaleObjects();
495 bScaleObjects
= TRUE
;
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
;
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
;
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!
553 bMergeMasterPages
= TRUE
;
557 SdStyleSheetVector aCreatedStyles
;
559 ((SdStyleSheetPool
*)GetStyleSheetPool())->CopyLayoutSheets(*pLayout
, *pBookmarkStyleSheetPool
,aCreatedStyles
);
561 if(!aCreatedStyles
.empty())
565 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction(this, aCreatedStyles
, TRUE
);
566 pUndoMgr
->AddUndoAction(pMovStyles
);
572 pLayout
= (String
*)pLayoutsToTransfer
->Next();
575 delete pLayoutsToTransfer
;
577 /**************************************************************************
579 **************************************************************************/
581 const bool bUndo
= IsUndoEnabled();
584 BegUndo(String(SdResId(STR_UNDO_INSERTPAGES
)));
588 if (nInsertPos
>= GetPageCount())
590 // Seiten werden hinten angefuegt
591 nInsertPos
= GetPageCount();
594 USHORT nActualInsertPos
= nInsertPos
;
597 std::set
<USHORT
> aRenameSet
;
600 for (nBMSdPage
=0; nBMSdPage
< nBMSdPageCount
; nBMSdPage
++)
602 SdPage
* pBMPage
= pBookmarkDoc
->GetSdPage(nBMSdPage
, PK_STANDARD
);
603 String
pName( pBMPage
->GetName() );
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
);
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());
648 // Nun werden die Link-Namen zusammengestellt
649 pPage
->SetFileName(aBookmarkName
);
650 pPage
->SetBookmarkName(*(pName
));
652 pPage
->SetModel(this);
655 nActualInsertPos
+= 2;
660 /**********************************************************************
661 * Ausgewaehlte Seiten einfuegen
662 **********************************************************************/
665 if (nInsertPos
>= GetPageCount())
667 // Seiten werden hinten angefuegt
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
));
681 USHORT nBMPage
= pBookmarkDoc
->GetPageByName( aPgName
, bIsMasterPage
);
683 if (nBMPage
!= SDRPAGE_NOTFOUND
)
685 pBMPage
= (SdPage
*) pBookmarkDoc
->GetPage(nBMPage
);
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
&&
706 nPageSameName
!= nActualInsertPos
) )
708 bMustRename
= sal_True
;
711 SdPage
* pBookmarkPage
= dynamic_cast< SdPage
* >( pBookmarkDoc
->GetPage(nBMPage
) );
714 ReplacePageInCustomShows( dynamic_cast< SdPage
* >( GetPage( nActualInsertPos
) ), pBookmarkPage
);
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)
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
) ) );
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());
747 SdPage
* pPage
= (SdPage
*) GetPage(nActualInsertPos
);
748 pPage
->SetFileName(aBookmarkName
);
749 pPage
->SetBookmarkName(aPgName
);
750 pPage
->SetModel(this);
755 // Seite & Notizseite ausfuegen
756 const sal_uInt16
nDestPageNum(nActualInsertPos
+ 2);
757 SdPage
* pStandardPage
= 0L;
759 if(nDestPageNum
< GetPageCount())
761 pStandardPage
= (SdPage
*)GetPage(nDestPageNum
);
766 if( bPreservePageNames
)
768 // #96029# Take old slide names for inserted pages
769 SdPage
* pPage
= (SdPage
*) GetPage(nActualInsertPos
);
770 pPage
->SetName( pStandardPage
->GetRealName() );
774 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pStandardPage
));
776 RemovePage(nDestPageNum
);
779 delete pStandardPage
;
782 SdPage
* pNotesPage
= 0L;
784 if(nDestPageNum
< GetPageCount())
786 pNotesPage
= (SdPage
*)GetPage(nDestPageNum
);
791 if( bPreservePageNames
)
793 // #96029# Take old slide names for inserted pages
794 SdPage
* pNewNotesPage
= (SdPage
*) GetPage(nActualInsertPos
+1);
796 pNewNotesPage
->SetName( pStandardPage
->GetRealName() );
800 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage
));
802 RemovePage(nDestPageNum
);
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();
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() )
843 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pRefPage
));
845 RemoveMasterPage(nPage
);
855 // #96029# nInsertPos > 2 is always true when inserting into non-empty models
858 USHORT nSdPageStart
= (nInsertPos
- 1) / 2;
859 USHORT nSdPageEnd
= GetSdPageCount(PK_STANDARD
) - nSdPageCount
+
861 const bool bRemoveEmptyPresObj
= pBookmarkDoc
&&
862 (pBookmarkDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
) &&
863 (GetDocumentType() == DOCUMENT_TYPE_DRAW
);
867 nSdPageEnd
= nSdPageStart
+ nReplacedStandardPages
- 1;
870 for (USHORT nSdPage
= nSdPageStart
; nSdPage
<= nSdPageEnd
; nSdPage
++)
872 pRefPage
= GetSdPage(nSdPage
, PK_STANDARD
);
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
);
884 SdPage
* pNewNotesPage
= GetSdPage(nSdPage
, PK_NOTES
);
885 pNewNotesPage
->SetName(aExchangeName
);
886 aHint
.SetPage(pNewNotesPage
);
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
);
899 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage
) );
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
);
918 AddUndo( GetSdrUndoFactory().CreateUndoPageChangeMasterPage( *pRefPage
) );
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
)
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
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
);
970 pUndoMgr
->LeaveListAction();
975 /*************************************************************************
977 |* Fuegt ein Bookmark als Objekt ein
979 \************************************************************************/
981 BOOL
SdDrawDocument::InsertBookmarkAsObject(
983 List
* pExchangeList
, // Liste der zu verwendenen Namen
985 ::sd::DrawDocShell
* pBookmarkDocSh
,
989 BOOL bOLEObjFound
= FALSE
;
990 ::sd::View
* pBMView
= NULL
;
992 SdDrawDocument
* pBookmarkDoc
= NULL
;
993 String aBookmarkName
;
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
;
1016 pBMView
= new ::sd::View(pBookmarkDoc
, (OutputDevice
*) NULL
);
1017 pBMView
->EndListening(*pBookmarkDoc
);
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
);
1038 if (pObj
->GetObjInventor() == SdrInventor
&&
1039 pObj
->GetObjIdentifier() == OBJ_OLE2
)
1041 bOLEObjFound
= TRUE
;
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()));
1059 pPV
= pBMView
->GetSdrPageView();
1060 if( !pPV
|| (pPV
->GetPage() != pPage
))
1061 pPV
= pBMView
->ShowSdrPage(pPage
);
1064 pBMView
->MarkObj(pObj
, pPV
, FALSE
);
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
);
1082 ::sd::ViewShell
* pViewSh
= mpDocSh
->GetViewShell();
1086 // Welche Seite wird denn aktuell angezeigt?
1087 SdrPageView
* pPV
= pViewSh
->GetView()->GetSdrPageView();
1091 pPage
= pPV
->GetPage();
1093 else if (pViewSh
->GetActualPage())
1095 pPage
= pViewSh
->GetActualPage();
1108 aObjPos
= Rectangle(Point(), pPage
->GetSize()).Center();
1111 ULONG nCountBefore
= 0;
1115 // OrdNums sortieren und Anzahl Objekte vor dem Einfuegen bestimmen
1116 pPage
->RecalcObjOrdNums();
1117 nCountBefore
= pPage
->GetObjCount();
1121 pBMView
->GetDoc()->SetAllocDocSh(TRUE
);
1123 SdDrawDocument
* pTmpDoc
= (SdDrawDocument
*) pBMView
->GetAllMarkedModel();
1124 bOK
= pView
->Paste(*pTmpDoc
, aObjPos
, pPage
);
1127 pBMView
->GetDoc()->SetAllocDocSh(FALSE
);
1130 delete pTmpDoc
; // Wird ansonsten von der DocShell zerstoert
1134 List
* pList
= pBookmarkList
;
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
;
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()
1205 /*************************************************************************
1207 |* Ist das Dokument read-only?
1209 \************************************************************************/
1211 FASTBOOL
SdDrawDocument::IsReadOnly() const
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
)
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
;
1263 xStor
= mpDocSh
->GetStorage();
1264 SvStream
* pRet
= NULL
;
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
);
1290 pRet
= ::utl::UcbStreamHelper::CreateStream( xStream
);
1293 catch( container::NoSuchElementException
& )
1298 catch( uno::Exception
& e
)
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
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
1327 pRet
->Seek( nStartPos
);
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() )
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
;
1368 pMaster
= (SdPage
*) GetMasterSdPage( (USHORT
) nMPage
, PK_STANDARD
);
1369 pNotesMaster
= (SdPage
*) GetMasterSdPage( (USHORT
) nMPage
, PK_NOTES
);
1373 for ( USHORT nMPg
= 0; nMPg
< GetMasterPageCount(); nMPg
++ )
1375 if ( pMaster
== GetMasterPage( nMPg
) )
1377 pNotesMaster
= (SdPage
*) GetMasterPage( ++nMPg
);
1383 DBG_ASSERT( pMaster
->GetPageKind() == PK_STANDARD
, "wrong page kind" );
1385 if ( pMaster
->GetPageKind() == PK_STANDARD
&&
1386 GetMasterPageUserCount( pMaster
) == 0 &&
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
;
1413 // if MasterPage is visible hide on pageview
1414 SdrPageView
* pPgView
= pView
->GetSdrPageView();
1417 SdrPage
* pShownPage
= pPgView
->GetPage();
1418 if( (pShownPage
== pMaster
) || (pShownPage
== pNotesMaster
) )
1420 pView
->HideSdrPage();
1421 pView
->ShowSdrPage( GetSdPage( 0, PK_STANDARD
) );
1429 AddUndo( GetSdrUndoFactory().CreateUndoDeletePage( *pNotesMaster
) );
1432 RemoveMasterPage( pNotesMaster
->GetPageNum() );
1435 delete pNotesMaster
;
1438 AddUndo(GetSdrUndoFactory().CreateUndoDeletePage(*pMaster
));
1440 RemoveMasterPage( pMaster
->GetPageNum() );
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
;
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
);
1468 // die Liste gehoert der UndoAction
1469 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction( this, aRemove
, false );
1472 pUndoMgr
->AddUndoAction(pMovStyles
);
1475 for( SdStyleSheetVector::iterator iter
= aRemove
.begin(); iter
!= aRemove
.end(); iter
++ )
1476 static_cast<SdStyleSheetPool
*>( mxStyleSheetPool
.get())->Remove((*iter
).get());
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
,
1511 mpDocSh
->SetWaitCursor( TRUE
);
1513 SfxUndoManager
* pUndoMgr
= mpDocSh
->GetUndoManager();
1515 const bool bUndo
= IsUndoEnabled();
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
);
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();
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
)
1564 if (pMP
->GetPageKind() == PK_NOTES
)
1567 if (pMaster
&& pNotesMaster
)
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();
1589 mpDocSh
->SetWaitCursor( FALSE
);
1591 DBG_ERROR( "SdDrawDocument::SetMasterPage() failed!" );
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
;
1609 /*****************************************************************
1610 |* Praesentationsvorlagen korrigieren bzw. neu anlegen
1611 \****************************************************************/
1612 // nur die Praesentationsvorlagen beachten
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();
1625 aName
= pHisSheet
->GetName();
1627 if( aName
.Search( aNewLayoutName
) == 0 )
1629 SfxStyleSheet
* pMySheet
= static_cast<SfxStyleSheet
*>( mxStyleSheetPool
->Find(aName
, SD_STYLE_FAMILY_MASTERPAGE
) );
1633 // Es ist eine gleichnamige Vorlage vorhanden ist: Inhalte ersetzen
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
));
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();
1684 SfxStyleSheetBase
* pSOld
= mxStyleSheetPool
->Find(pRData
->aName
);
1685 SfxStyleSheetBase
* pSNew
= mxStyleSheetPool
->Find(pRData
->aNewName
);
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
->
1699 if ((pRD
->aName
== rParentOfOld
) && (pRD
->aName
!= pRD
->aNewName
))
1701 String
aParentOfNew(pRD
->aNewName
);
1702 pSNew
->SetParent(aParentOfNew
);
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();
1752 if (!bLayoutReloaded
)
1753 nInsertPos
= 0xFFFF;
1754 InsertMasterPage(pMaster
, nInsertPos
);
1756 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pMaster
));
1759 if (!bLayoutReloaded
)
1760 nInsertPos
= 0xFFFF;
1761 InsertMasterPage(pNotesMaster
, nInsertPos
);
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
);
1793 pPageList
->Insert(pSelectedPage
, LIST_APPEND
);
1794 pPageList
->Insert(pNotes
, LIST_APPEND
);
1797 pPage
= (SdPage
*)pPageList
->First();
1800 AutoLayout eAutoLayout
= pPage
->GetAutoLayout();
1804 SdPresentationLayoutUndoAction
* pPLUndoAction
=
1805 new SdPresentationLayoutUndoAction
1807 pPage
->IsMasterPage() ? aLayoutName
: aOldLayoutName
,
1809 eAutoLayout
, eAutoLayout
, FALSE
, pPage
);
1810 pUndoMgr
->AddUndoAction(pPLUndoAction
);
1812 pPage
->SetPresentationLayout(aLayoutName
);
1813 pPage
->SetAutoLayout(eAutoLayout
);
1815 pPage
= (SdPage
*)pPageList
->Next();
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();
1858 pReplData
= (StyleReplaceData
*)pReplList
->Next();
1863 if( (pSourceDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
) &&
1864 (GetDocumentType() == DOCUMENT_TYPE_DRAW
) )
1866 pMaster
->RemoveEmptyPresentationObjects();
1867 pNotesMaster
->RemoveEmptyPresentationObjects();
1873 /*********************************************************************
1874 |* Einen neuen Layoutnamen ausdenken
1875 \********************************************************************/
1876 String aName
= String(SdResId(STR_LAYOUT_DEFAULT_NAME
));
1878 BOOL bNotANewName
= TRUE
;
1880 USHORT nMPgCount
= GetMasterPageCount();
1882 for (nCount
= 0; bNotANewName
; nCount
++)
1885 aTest
= aName
; // Standard, Standard1, Standard2, ...
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
;
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
);
1915 SdMoveStyleSheetsUndoAction
* pMovStyles
= new SdMoveStyleSheetsUndoAction(this, aCreatedStyles
, TRUE
);
1916 pUndoMgr
->AddUndoAction(pMovStyles
);
1919 /*********************************************************************
1920 |* Neue MasterPages erzeugen und ins Dokument eintragen
1921 \********************************************************************/
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
);
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
);
1953 AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pNotesMaster
));
1955 pNotesMaster
->SetAutoLayout(AUTOLAYOUT_NOTES
, true, true);
1960 /*********************************************************************
1961 |* Liste der betroffenen Standard- und Notizseiten erstellen
1962 \********************************************************************/
1963 List
* pPageList
= new List
;
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
);
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();
1988 AutoLayout eOldAutoLayout
= pPage
->GetAutoLayout();
1989 AutoLayout eNewAutoLayout
=
1990 pPage
->GetPageKind() == PK_STANDARD
? AUTOLAYOUT_NONE
: AUTOLAYOUT_NOTES
;
1994 SdPresentationLayoutUndoAction
* pPLUndoAction
=
1995 new SdPresentationLayoutUndoAction
1996 (this, aOldLayoutName
, aName
,
1997 eOldAutoLayout
, eNewAutoLayout
, TRUE
,
1999 pUndoMgr
->AddUndoAction(pPLUndoAction
);
2002 pPage
->SetPresentationLayout(aName
);
2003 pPage
->SetAutoLayout(eNewAutoLayout
);
2005 pPage
= (SdPage
*)pPageList
->Next();
2008 // Seitenliste loeschen
2012 /*********************************************************************
2013 |* falls die alten Masterpages nicht mehr benoetigt werden,
2014 |* muessen sie und die entsprechenden Praesentationsvorlagen
2016 \********************************************************************/
2020 RemoveUnnecessaryMasterPages();
2024 // Nur die ausgetauschte MasterPage pruefen
2025 RemoveUnnecessaryMasterPages(&rOldMaster
);
2029 pUndoMgr
->LeaveListAction();
2032 mpDocSh
->SetWaitCursor( FALSE
);
2037 void SdDrawDocument::Merge(SdrModel
& rSourceModel
,
2038 USHORT nFirstPageNum
, USHORT nLastPageNum
,
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();
2055 pStylePool
->AddStyleFamily( pPage
);