bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdmodel.cxx
bloba184de70556b143b1632cb06c80f9fac5922be47
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/svdmodel.hxx>
23 #include <math.h>
25 #include <osl/endian.h>
26 #include <rtl/logfile.hxx>
27 #include <rtl/strbuf.hxx>
29 #include <com/sun/star/lang/XComponent.hpp>
30 #include <com/sun/star/document/XStorageBasedDocument.hpp>
31 #include <com/sun/star/embed/ElementModes.hpp>
33 #include <unotools/ucbstreamhelper.hxx>
35 #include <tools/string.hxx>
36 #include <svl/whiter.hxx>
37 #include <svx/xit.hxx>
38 #include <svx/xbtmpit.hxx>
39 #include <svx/xlndsit.hxx>
40 #include <svx/xlnedit.hxx>
41 #include <svx/xflgrit.hxx>
42 #include <svx/xflftrit.hxx>
43 #include <svx/xflhtit.hxx>
44 #include <svx/xlnstit.hxx>
46 #include <editeng/editdata.hxx>
47 #include <editeng/editeng.hxx> // for EditEngine::CreatePool()
49 #include <svx/xtable.hxx>
51 #include "svx/svditer.hxx"
52 #include <svx/svdtrans.hxx>
53 #include <svx/svdpage.hxx>
54 #include <svx/svdlayer.hxx>
55 #include <svx/svdundo.hxx>
56 #include <svx/svdpool.hxx>
57 #include <svx/svdobj.hxx>
58 #include <svx/svdotext.hxx> // for ReformatAllTextObjects and CalcFieldValue
59 #include <svx/svdetc.hxx>
60 #include <svx/svdoutl.hxx>
61 #include <svx/svdoole2.hxx>
62 #include "svx/svdglob.hxx" // StringCache
63 #include "svx/svdstr.hrc" // object's name
64 #include "svdoutlinercache.hxx"
66 #include "svx/xflclit.hxx"
67 #include "svx/xflhtit.hxx"
68 #include "svx/xlnclit.hxx"
70 #include "officecfg/Office/Common.hxx"
71 #include "editeng/fontitem.hxx"
72 #include <editeng/colritem.hxx>
73 #include <editeng/fhgtitem.hxx>
74 #include <svl/style.hxx>
75 #include <editeng/numitem.hxx>
76 #include <editeng/bulletitem.hxx>
77 #include <editeng/outlobj.hxx>
78 #include "editeng/forbiddencharacterstable.hxx"
79 #include <svl/zforlist.hxx>
80 #include <comphelper/servicehelper.hxx>
81 #include <comphelper/storagehelper.hxx>
83 #include <tools/tenccvt.hxx>
84 #include <unotools/syslocale.hxx>
86 #include <vcl/svapp.hxx>
87 #include <svx/sdr/properties/properties.hxx>
88 #include <editeng/eeitem.hxx>
89 #include <svl/itemset.hxx>
91 using namespace ::com::sun::star;
92 using namespace ::com::sun::star::uno;
93 using namespace ::com::sun::star::lang;
95 ////////////////////////////////////////////////////////////////////////////////////////////////////
97 struct SdrModelImpl
99 SfxUndoManager* mpUndoManager;
100 SdrUndoFactory* mpUndoFactory;
103 ////////////////////////////////////////////////////////////////////////////////////////////////////
105 DBG_NAME(SdrModel)
106 TYPEINIT1(SdrModel,SfxBroadcaster);
107 void SdrModel::ImpCtor(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* _pEmbeddedHelper,
108 bool bUseExtColorTable, bool bLoadRefCounts)
110 mpImpl = new SdrModelImpl;
111 mpImpl->mpUndoManager=0;
112 mpImpl->mpUndoFactory=0;
113 mbInDestruction = false;
114 aObjUnit=SdrEngineDefaults::GetMapFraction();
115 eObjUnit=SdrEngineDefaults::GetMapUnit();
116 eUIUnit=FUNIT_MM;
117 aUIScale=Fraction(1,1);
118 nUIUnitKomma=0;
119 bUIOnlyKomma=sal_False;
120 pLayerAdmin=NULL;
121 pItemPool=pPool;
122 bMyPool=sal_False;
123 m_pEmbeddedHelper=_pEmbeddedHelper;
124 pDrawOutliner=NULL;
125 pHitTestOutliner=NULL;
126 pRefOutDev=NULL;
127 nProgressAkt=0;
128 nProgressMax=0;
129 nProgressOfs=0;
130 pDefaultStyleSheet=NULL;
131 mpDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj = 0;
132 pLinkManager=NULL;
133 pUndoStack=NULL;
134 pRedoStack=NULL;
135 nMaxUndoCount=16;
136 pAktUndoGroup=NULL;
137 nUndoLevel=0;
138 mbUndoEnabled=true;
139 nProgressPercent=0;
140 nLoadVersion=0;
141 bExtColorTable=sal_False;
142 mbChanged = sal_False;
143 bInfoChanged=sal_False;
144 bPagNumsDirty=sal_False;
145 bMPgNumsDirty=sal_False;
146 bPageNotValid=sal_False;
147 bSavePortable=sal_False;
148 bSaveCompressed=sal_False;
149 bSaveNative=sal_False;
150 bSwapGraphics=sal_False;
151 nSwapGraphicsMode=SDR_SWAPGRAPHICSMODE_DEFAULT;
152 bSaveOLEPreview=sal_False;
153 bPasteResize=sal_False;
154 bNoBitmapCaching=sal_False;
155 bReadOnly=sal_False;
156 nStreamCompressMode=COMPRESSMODE_NONE;
157 nStreamNumberFormat=NUMBERFORMAT_INT_BIGENDIAN;
158 nDefaultTabulator=0;
159 mpNumberFormatter = NULL;
160 bTransparentTextFrames=sal_False;
161 bStarDrawPreviewMode = sal_False;
162 nStarDrawPreviewMasterPageNum = SDRPAGE_NOTFOUND;
163 mpForbiddenCharactersTable = NULL;
164 mbModelLocked = false;
165 mpOutlinerCache = NULL;
166 mbKernAsianPunctuation = sal_False;
167 mbAddExtLeading = sal_False;
168 mnHandoutPageCount = 0;
170 mnCharCompressType =
171 officecfg::Office::Common::AsianLayout::CompressCharacterDistance::
172 get();
174 #ifdef OSL_LITENDIAN
175 nStreamNumberFormat=NUMBERFORMAT_INT_LITTLEENDIAN;
176 #endif
177 bExtColorTable=bUseExtColorTable;
179 if ( pPool == NULL )
181 pItemPool=new SdrItemPool(0L, bLoadRefCounts);
182 // Outliner doesn't have its own Pool, so use the EditEngine's
183 SfxItemPool* pOutlPool=EditEngine::CreatePool( bLoadRefCounts );
184 // OutlinerPool as SecondaryPool of SdrPool
185 pItemPool->SetSecondaryPool(pOutlPool);
186 // remember that I created both pools myself
187 bMyPool=sal_True;
189 pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
191 // using static SdrEngineDefaults only if default SvxFontHeight item is not available
192 const SfxPoolItem* pPoolItem = pItemPool->GetPoolDefaultItem( EE_CHAR_FONTHEIGHT );
193 if ( pPoolItem )
194 nDefTextHgt = ((SvxFontHeightItem*)pPoolItem)->GetHeight();
195 else
196 nDefTextHgt = SdrEngineDefaults::GetFontHeight();
198 pItemPool->SetPoolDefaultItem( SdrTextWordWrapItem( sal_False ) );
200 SetTextDefaults();
201 pLayerAdmin=new SdrLayerAdmin;
202 pLayerAdmin->SetModel(this);
203 ImpSetUIUnit();
205 // can't create DrawOutliner OnDemand, because I can't get the Pool,
206 // then (only from 302 onwards!)
207 pDrawOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
208 ImpSetOutlinerDefaults(pDrawOutliner, sal_True);
210 pHitTestOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
211 ImpSetOutlinerDefaults(pHitTestOutliner, sal_True);
213 ImpCreateTables();
216 SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
217 aReadDate( DateTime::EMPTY ),
218 maMaPag(),
219 maPages()
221 #ifdef TIMELOG
222 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
223 #endif
225 DBG_CTOR(SdrModel,NULL);
226 ImpCtor(pPool, pPers, false, (bool)bLoadRefCounts);
229 SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
230 aReadDate( DateTime::EMPTY ),
231 maMaPag(),
232 maPages(),
233 aTablePath(rPath)
235 #ifdef TIMELOG
236 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
237 #endif
239 DBG_CTOR(SdrModel,NULL);
240 ImpCtor(pPool, pPers, false, (bool)bLoadRefCounts);
243 SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, bool bUseExtColorTable, sal_Bool bLoadRefCounts):
244 aReadDate( DateTime::EMPTY ),
245 maMaPag(),
246 maPages()
248 #ifdef TIMELOG
249 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
250 #endif
252 DBG_CTOR(SdrModel,NULL);
253 ImpCtor(pPool,pPers,bUseExtColorTable, (bool)bLoadRefCounts);
256 SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, bool bUseExtColorTable, sal_Bool bLoadRefCounts):
257 aReadDate( DateTime::EMPTY ),
258 maMaPag(),
259 maPages(),
260 aTablePath(rPath)
262 #ifdef TIMELOG
263 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
264 #endif
266 DBG_CTOR(SdrModel,NULL);
267 ImpCtor(pPool,pPers,bUseExtColorTable, (bool)bLoadRefCounts);
270 SdrModel::SdrModel(const SdrModel& /*rSrcModel*/):
271 SfxBroadcaster(),
272 tools::WeakBase< SdrModel >(),
273 aReadDate( DateTime::EMPTY ),
274 maMaPag(),
275 maPages()
277 #ifdef TIMELOG
278 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
279 #endif
281 // not yet implemented
282 OSL_FAIL("SdrModel::CopyCtor() is not yet implemented.");
285 SdrModel::~SdrModel()
287 #ifdef TIMELOG
288 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::~SdrModel(...)" );
289 #endif
291 DBG_DTOR(SdrModel,NULL);
293 mbInDestruction = true;
295 Broadcast(SdrHint(HINT_MODELCLEARED));
297 delete mpOutlinerCache;
299 ClearUndoBuffer();
300 #ifdef DBG_UTIL
301 if(pAktUndoGroup)
303 OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
304 "In the Dtor of the SdrModel there is an open Undo left: \""));
305 aStr.append(OUStringToOString(pAktUndoGroup->GetComment(), osl_getThreadTextEncoding()))
306 .append('\"');
307 OSL_FAIL(aStr.getStr());
309 #endif
310 delete pAktUndoGroup;
312 ClearModel(sal_True);
314 delete pLayerAdmin;
316 // Delete DrawOutliner only after deleting ItemPool, because ItemPool
317 // references Items of the DrawOutliner!
318 delete pHitTestOutliner;
319 delete pDrawOutliner;
321 // delete StyleSheetPool, derived classes should not do this since
322 // the DrawingEngine may need it in its destructor
323 if( mxStyleSheetPool.is() )
325 Reference< XComponent > xComponent( dynamic_cast< cppu::OWeakObject* >( mxStyleSheetPool.get() ), UNO_QUERY );
326 if( xComponent.is() ) try
328 xComponent->dispose();
330 catch( RuntimeException& )
333 mxStyleSheetPool.clear();
336 if (bMyPool)
338 // delete Pools if they're mine
339 SfxItemPool* pOutlPool=pItemPool->GetSecondaryPool();
340 SfxItemPool::Free(pItemPool);
341 // OutlinerPool has to be deleted after deleting ItemPool, because
342 // ItemPool contains SetItems that themselves reference Items from OutlinerPool.
343 SfxItemPool::Free(pOutlPool);
346 if( mpForbiddenCharactersTable )
347 mpForbiddenCharactersTable->release();
349 delete mpNumberFormatter;
351 delete mpImpl->mpUndoFactory;
352 delete mpImpl;
355 bool SdrModel::IsInDestruction() const
357 return mbInDestruction;
360 // not yet implemented
361 void SdrModel::operator=(const SdrModel&)
363 OSL_FAIL("SdrModel::operator=() is not yet implemented.");
366 bool SdrModel::operator==(const SdrModel&) const
368 OSL_FAIL("SdrModel::operator==() is not yet implemented");
369 return sal_False;
372 void SdrModel::SetSwapGraphics( bool bSwap )
374 bSwapGraphics = bSwap;
377 bool SdrModel::IsReadOnly() const
379 return bReadOnly;
382 void SdrModel::SetReadOnly(bool bYes)
384 bReadOnly=bYes;
387 ////////////////////////////////////////////////////////////////////////////////////////////////////
389 void SdrModel::SetMaxUndoActionCount(sal_uIntPtr nAnz)
391 if (nAnz<1) nAnz=1;
392 nMaxUndoCount=nAnz;
393 if (pUndoStack!=NULL) {
394 while (pUndoStack->size()>nMaxUndoCount) {
395 delete pUndoStack->back();
396 pUndoStack->pop_back();
401 void SdrModel::ClearUndoBuffer()
403 if (pUndoStack!=NULL) {
404 while (!pUndoStack->empty()) {
405 delete pUndoStack->back();
406 pUndoStack->pop_back();
408 delete pUndoStack;
409 pUndoStack=NULL;
411 if (pRedoStack!=NULL) {
412 while (!pRedoStack->empty()) {
413 delete pRedoStack->back();
414 pRedoStack->pop_back();
416 delete pRedoStack;
417 pRedoStack=NULL;
421 bool SdrModel::HasUndoActions() const
423 return pUndoStack && !pUndoStack->empty();
426 bool SdrModel::HasRedoActions() const
428 return pRedoStack && !pRedoStack->empty();
431 bool SdrModel::Undo()
433 bool bRet = false;
434 if( mpImpl->mpUndoManager )
436 OSL_FAIL("svx::SdrModel::Undo(), method not supported with application undo manager!");
438 else
440 SfxUndoAction* pDo = HasUndoActions() ? pUndoStack->front() : NULL;
441 if(pDo!=NULL)
443 const bool bWasUndoEnabled = mbUndoEnabled;
444 mbUndoEnabled = false;
445 pDo->Undo();
446 if(pRedoStack==NULL)
447 pRedoStack=new std::deque<SfxUndoAction*>;
448 SfxUndoAction* p = pUndoStack->front();
449 pUndoStack->pop_front();
450 pRedoStack->push_front(p);
451 mbUndoEnabled = bWasUndoEnabled;
454 return bRet;
457 bool SdrModel::Redo()
459 bool bRet = false;
460 if( mpImpl->mpUndoManager )
462 OSL_FAIL("svx::SdrModel::Redo(), method not supported with application undo manager!");
464 else
466 SfxUndoAction* pDo = HasRedoActions() ? pRedoStack->front() : NULL;
467 if(pDo!=NULL)
469 const bool bWasUndoEnabled = mbUndoEnabled;
470 mbUndoEnabled = false;
471 pDo->Redo();
472 if(pUndoStack==NULL)
473 pUndoStack=new std::deque<SfxUndoAction*>;
474 SfxUndoAction* p = pRedoStack->front();
475 pRedoStack->pop_front();
476 pUndoStack->push_front(p);
477 mbUndoEnabled = bWasUndoEnabled;
480 return bRet;
483 bool SdrModel::Repeat(SfxRepeatTarget& rView)
485 bool bRet = false;
486 if( mpImpl->mpUndoManager )
488 OSL_FAIL("svx::SdrModel::Redo(), method not supported with application undo manager!");
490 else
492 SfxUndoAction* pDo = HasUndoActions() ? pUndoStack->front() : NULL;
493 if(pDo!=NULL)
495 if(pDo->CanRepeat(rView))
497 pDo->Repeat(rView);
498 bRet = true;
502 return bRet;
505 void SdrModel::ImpPostUndoAction(SdrUndoAction* pUndo)
507 DBG_ASSERT( mpImpl->mpUndoManager == 0, "svx::SdrModel::ImpPostUndoAction(), method not supported with application undo manager!" );
508 if( IsUndoEnabled() )
510 if (aUndoLink.IsSet())
512 aUndoLink.Call(pUndo);
514 else
516 if (pUndoStack==NULL)
517 pUndoStack=new std::deque<SfxUndoAction*>;
518 pUndoStack->push_front(pUndo);
519 while (pUndoStack->size()>nMaxUndoCount)
521 delete pUndoStack->back();
522 pUndoStack->pop_back();
524 if (pRedoStack!=NULL)
525 pRedoStack->clear();
528 else
530 delete pUndo;
534 void SdrModel::BegUndo()
536 if( mpImpl->mpUndoManager )
538 const String aEmpty;
539 mpImpl->mpUndoManager->EnterListAction(aEmpty,aEmpty);
540 nUndoLevel++;
542 else if( IsUndoEnabled() )
544 if(pAktUndoGroup==NULL)
546 pAktUndoGroup = new SdrUndoGroup(*this);
547 nUndoLevel=1;
549 else
551 nUndoLevel++;
556 void SdrModel::BegUndo(const XubString& rComment)
558 if( mpImpl->mpUndoManager )
560 const String aEmpty;
561 mpImpl->mpUndoManager->EnterListAction( rComment, aEmpty );
562 nUndoLevel++;
564 else if( IsUndoEnabled() )
566 BegUndo();
567 if (nUndoLevel==1)
569 pAktUndoGroup->SetComment(rComment);
574 void SdrModel::BegUndo(const XubString& rComment, const XubString& rObjDescr, SdrRepeatFunc eFunc)
576 if( mpImpl->mpUndoManager )
578 String aComment(rComment);
579 if( aComment.Len() && rObjDescr.Len() )
581 String aSearchString(RTL_CONSTASCII_USTRINGPARAM("%1"));
582 aComment.SearchAndReplace(aSearchString, rObjDescr);
584 const String aEmpty;
585 mpImpl->mpUndoManager->EnterListAction( aComment,aEmpty );
586 nUndoLevel++;
588 else if( IsUndoEnabled() )
590 BegUndo();
591 if (nUndoLevel==1)
593 pAktUndoGroup->SetComment(rComment);
594 pAktUndoGroup->SetObjDescription(rObjDescr);
595 pAktUndoGroup->SetRepeatFunction(eFunc);
600 void SdrModel::EndUndo()
602 DBG_ASSERT(nUndoLevel!=0,"SdrModel::EndUndo(): UndoLevel is already 0!");
603 if( mpImpl->mpUndoManager )
605 if( nUndoLevel )
607 nUndoLevel--;
608 mpImpl->mpUndoManager->LeaveListAction();
611 else
613 if(pAktUndoGroup!=NULL && IsUndoEnabled())
615 nUndoLevel--;
616 if(nUndoLevel==0)
618 if(pAktUndoGroup->GetActionCount()!=0)
620 SdrUndoAction* pUndo=pAktUndoGroup;
621 pAktUndoGroup=NULL;
622 ImpPostUndoAction(pUndo);
624 else
626 // was empty
627 delete pAktUndoGroup;
628 pAktUndoGroup=NULL;
635 void SdrModel::SetUndoComment(const XubString& rComment)
637 DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is already 0!");
639 if( mpImpl->mpUndoManager )
641 OSL_FAIL("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
643 else if( IsUndoEnabled() )
645 if(nUndoLevel==1)
647 pAktUndoGroup->SetComment(rComment);
652 void SdrModel::SetUndoComment(const XubString& rComment, const XubString& rObjDescr)
654 DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is already 0!");
655 if( mpImpl->mpUndoManager )
657 OSL_FAIL("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
659 else
661 if (nUndoLevel==1)
663 pAktUndoGroup->SetComment(rComment);
664 pAktUndoGroup->SetObjDescription(rObjDescr);
669 void SdrModel::AddUndo(SdrUndoAction* pUndo)
671 if( mpImpl->mpUndoManager )
673 mpImpl->mpUndoManager->AddUndoAction( pUndo );
675 else if( !IsUndoEnabled() )
677 delete pUndo;
679 else
681 if (pAktUndoGroup!=NULL)
683 pAktUndoGroup->AddAction(pUndo);
685 else
687 ImpPostUndoAction(pUndo);
692 void SdrModel::EnableUndo( bool bEnable )
694 if( mpImpl->mpUndoManager )
696 mpImpl->mpUndoManager->EnableUndo( bEnable );
698 else
700 mbUndoEnabled = bEnable;
704 bool SdrModel::IsUndoEnabled() const
706 if( mpImpl->mpUndoManager )
708 return mpImpl->mpUndoManager->IsUndoEnabled();
710 else
712 return mbUndoEnabled;
716 void SdrModel::ImpCreateTables()
718 for( int i = 0; i < XPROPERTY_LIST_COUNT; i++ )
720 if( !bExtColorTable || i != XCOLOR_LIST )
721 maProperties[i] = XPropertyList::CreatePropertyList (
722 (XPropertyListType) i, aTablePath, (XOutdevItemPool*)pItemPool );
726 void SdrModel::ClearModel(sal_Bool bCalledFromDestructor)
728 if(bCalledFromDestructor)
730 mbInDestruction = true;
733 sal_Int32 i;
734 // delete all drawing pages
735 sal_Int32 nAnz=GetPageCount();
736 for (i=nAnz-1; i>=0; i--)
738 DeletePage( (sal_uInt16)i );
740 maPages.clear();
741 PageListChanged();
743 // delete all Masterpages
744 nAnz=GetMasterPageCount();
745 for(i=nAnz-1; i>=0; i--)
747 DeleteMasterPage( (sal_uInt16)i );
749 maMaPag.clear();
750 MasterPageListChanged();
752 pLayerAdmin->ClearLayer();
755 SdrModel* SdrModel::AllocModel() const
757 SdrModel* pModel=new SdrModel;
758 pModel->SetScaleUnit(eObjUnit,aObjUnit);
759 return pModel;
762 SdrPage* SdrModel::AllocPage(bool bMasterPage)
764 return new SdrPage(*this,bMasterPage);
767 void SdrModel::SetTextDefaults() const
769 SetTextDefaults( pItemPool, nDefTextHgt );
772 void SdrModel::SetTextDefaults( SfxItemPool* pItemPool, sal_uIntPtr nDefTextHgt )
774 // set application-language specific dynamic pool language defaults
775 SvxFontItem aSvxFontItem( EE_CHAR_FONTINFO) ;
776 SvxFontItem aSvxFontItemCJK(EE_CHAR_FONTINFO_CJK);
777 SvxFontItem aSvxFontItemCTL(EE_CHAR_FONTINFO_CTL);
778 sal_uInt16 nLanguage(Application::GetSettings().GetLanguageTag().getLanguageType());
780 // get DEFAULTFONT_LATIN_TEXT and set at pool as dynamic default
781 Font aFont(OutputDevice::GetDefaultFont(DEFAULTFONT_LATIN_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
782 aSvxFontItem.SetFamily(aFont.GetFamily());
783 aSvxFontItem.SetFamilyName(aFont.GetName());
784 aSvxFontItem.SetStyleName(String());
785 aSvxFontItem.SetPitch( aFont.GetPitch());
786 aSvxFontItem.SetCharSet( aFont.GetCharSet() );
787 pItemPool->SetPoolDefaultItem(aSvxFontItem);
789 // get DEFAULTFONT_CJK_TEXT and set at pool as dynamic default
790 Font aFontCJK(OutputDevice::GetDefaultFont(DEFAULTFONT_CJK_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
791 aSvxFontItemCJK.SetFamily( aFontCJK.GetFamily());
792 aSvxFontItemCJK.SetFamilyName(aFontCJK.GetName());
793 aSvxFontItemCJK.SetStyleName(String());
794 aSvxFontItemCJK.SetPitch( aFontCJK.GetPitch());
795 aSvxFontItemCJK.SetCharSet( aFontCJK.GetCharSet());
796 pItemPool->SetPoolDefaultItem(aSvxFontItemCJK);
798 // get DEFAULTFONT_CTL_TEXT and set at pool as dynamic default
799 Font aFontCTL(OutputDevice::GetDefaultFont(DEFAULTFONT_CTL_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
800 aSvxFontItemCTL.SetFamily(aFontCTL.GetFamily());
801 aSvxFontItemCTL.SetFamilyName(aFontCTL.GetName());
802 aSvxFontItemCTL.SetStyleName(String());
803 aSvxFontItemCTL.SetPitch( aFontCTL.GetPitch() );
804 aSvxFontItemCTL.SetCharSet( aFontCTL.GetCharSet());
805 pItemPool->SetPoolDefaultItem(aSvxFontItemCTL);
807 // set dynamic FontHeight defaults
808 pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT ) );
809 pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CJK ) );
810 pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CTL ) );
812 // set FontColor defaults
813 pItemPool->SetPoolDefaultItem( SvxColorItem(SdrEngineDefaults::GetFontColor(), EE_CHAR_COLOR) );
816 SdrOutliner& SdrModel::GetDrawOutliner(const SdrTextObj* pObj) const
818 pDrawOutliner->SetTextObj(pObj);
819 return *pDrawOutliner;
822 const SdrTextObj* SdrModel::GetFormattingTextObj() const
824 if (pDrawOutliner!=NULL) {
825 return pDrawOutliner->GetTextObj();
827 return NULL;
830 void SdrModel::ImpSetOutlinerDefaults( SdrOutliner* pOutliner, sal_Bool bInit )
832 /**************************************************************************
833 * Initialization of the Outliners for drawing text and HitTest
834 **************************************************************************/
835 if( bInit )
837 pOutliner->EraseVirtualDevice();
838 pOutliner->SetUpdateMode(sal_False);
839 pOutliner->SetEditTextObjectPool(pItemPool);
840 pOutliner->SetDefTab(nDefaultTabulator);
843 pOutliner->SetRefDevice(GetRefDevice());
844 pOutliner->SetForbiddenCharsTable(GetForbiddenCharsTable());
845 pOutliner->SetAsianCompressionMode( mnCharCompressType );
846 pOutliner->SetKernAsianPunctuation( IsKernAsianPunctuation() );
847 pOutliner->SetAddExtLeading( IsAddExtLeading() );
849 if ( !GetRefDevice() )
851 MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
852 pOutliner->SetRefMapMode(aMapMode);
856 void SdrModel::SetRefDevice(OutputDevice* pDev)
858 pRefOutDev=pDev;
859 ImpSetOutlinerDefaults( pDrawOutliner );
860 ImpSetOutlinerDefaults( pHitTestOutliner );
861 RefDeviceChanged();
864 void SdrModel::ImpReformatAllTextObjects()
866 if( isLocked() )
867 return;
869 sal_uInt16 nAnz=GetMasterPageCount();
870 sal_uInt16 nNum;
871 for (nNum=0; nNum<nAnz; nNum++) {
872 GetMasterPage(nNum)->ReformatAllTextObjects();
874 nAnz=GetPageCount();
875 for (nNum=0; nNum<nAnz; nNum++) {
876 GetPage(nNum)->ReformatAllTextObjects();
880 /* steps over all available pages and sends notify messages to
881 all edge objects that are connected to other objects so that
882 they may reposition themselves
884 void SdrModel::ImpReformatAllEdgeObjects()
886 if( isLocked() )
887 return;
889 sal_uInt16 nAnz=GetMasterPageCount();
890 sal_uInt16 nNum;
891 for (nNum=0; nNum<nAnz; nNum++)
893 GetMasterPage(nNum)->ReformatAllEdgeObjects();
895 nAnz=GetPageCount();
896 for (nNum=0; nNum<nAnz; nNum++)
898 GetPage(nNum)->ReformatAllEdgeObjects();
902 uno::Reference<embed::XStorage> SdrModel::GetDocumentStorage() const
904 uno::Reference<document::XStorageBasedDocument> const xSBD(
905 const_cast<SdrModel*>(this)->getUnoModel(), uno::UNO_QUERY);
906 if (!xSBD.is())
908 SAL_WARN("svx", "no UNO model");
909 return 0;
911 return xSBD->getDocumentStorage();
914 uno::Reference<io::XInputStream>
915 SdrModel::GetDocumentStream( OUString const& rURL,
916 ::comphelper::LifecycleProxy & rProxy) const
918 uno::Reference<embed::XStorage> const xStorage(GetDocumentStorage());
919 if (!xStorage.is())
921 SAL_WARN("svx", "no storage?");
922 return 0;
924 try {
925 uno::Reference<io::XStream> const xStream(
926 ::comphelper::OStorageHelper::GetStreamAtPackageURL(
927 xStorage, rURL, embed::ElementModes::READ, rProxy));
928 return (xStream.is()) ? xStream->getInputStream() : 0;
930 catch (container::NoSuchElementException const&)
932 SAL_INFO("svx", "not found");
934 catch (uno::Exception const& e)
936 SAL_WARN("svx", "exception: '" << e.Message << "'");
938 return 0;
941 // convert template attributes from the string into "hard" attributes
942 void SdrModel::BurnInStyleSheetAttributes()
944 sal_uInt16 nAnz=GetMasterPageCount();
945 sal_uInt16 nNum;
946 for (nNum=0; nNum<nAnz; nNum++) {
947 GetMasterPage(nNum)->BurnInStyleSheetAttributes();
949 nAnz=GetPageCount();
950 for (nNum=0; nNum<nAnz; nNum++) {
951 GetPage(nNum)->BurnInStyleSheetAttributes();
955 void SdrModel::RefDeviceChanged()
957 Broadcast(SdrHint(HINT_REFDEVICECHG));
958 ImpReformatAllTextObjects();
961 void SdrModel::SetDefaultFontHeight(sal_uIntPtr nVal)
963 if (nVal!=nDefTextHgt) {
964 nDefTextHgt=nVal;
965 Broadcast(SdrHint(HINT_DEFFONTHGTCHG));
966 ImpReformatAllTextObjects();
970 void SdrModel::SetDefaultTabulator(sal_uInt16 nVal)
972 if (nDefaultTabulator!=nVal) {
973 nDefaultTabulator=nVal;
974 Outliner& rOutliner=GetDrawOutliner();
975 rOutliner.SetDefTab(nVal);
976 Broadcast(SdrHint(HINT_DEFAULTTABCHG));
977 ImpReformatAllTextObjects();
981 void SdrModel::ImpSetUIUnit()
983 if(0 == aUIScale.GetNumerator() || 0 == aUIScale.GetDenominator())
985 aUIScale = Fraction(1,1);
988 // set start values
989 nUIUnitKomma = 0;
990 sal_Int64 nMul(1);
991 sal_Int64 nDiv(1);
993 // normalize on meters resp. inch
994 switch (eObjUnit)
996 case MAP_100TH_MM : nUIUnitKomma+=5; break;
997 case MAP_10TH_MM : nUIUnitKomma+=4; break;
998 case MAP_MM : nUIUnitKomma+=3; break;
999 case MAP_CM : nUIUnitKomma+=2; break;
1000 case MAP_1000TH_INCH: nUIUnitKomma+=3; break;
1001 case MAP_100TH_INCH : nUIUnitKomma+=2; break;
1002 case MAP_10TH_INCH : nUIUnitKomma+=1; break;
1003 case MAP_INCH : nUIUnitKomma+=0; break;
1004 case MAP_POINT : nDiv=72; break; // 1Pt = 1/72"
1005 case MAP_TWIP : nDiv=144; nUIUnitKomma++; break; // 1Twip = 1/1440"
1006 case MAP_PIXEL : break;
1007 case MAP_SYSFONT : break;
1008 case MAP_APPFONT : break;
1009 case MAP_RELATIVE : break;
1010 default: break;
1011 } // switch
1013 // 1 mile = 8 furlong = 63.360" = 1.609.344,0mm
1014 // 1 furlong = 10 chains = 7.920" = 201.168,0mm
1015 // 1 chain = 4 poles = 792" = 20.116,8mm
1016 // 1 pole = 5 1/2 yd = 198" = 5.029,2mm
1017 // 1 yd = 3 ft = 36" = 914,4mm
1018 // 1 ft = 12 " = 1" = 304,8mm
1019 switch (eUIUnit)
1021 case FUNIT_NONE : break;
1022 // metric
1023 case FUNIT_100TH_MM: nUIUnitKomma-=5; break;
1024 case FUNIT_MM : nUIUnitKomma-=3; break;
1025 case FUNIT_CM : nUIUnitKomma-=2; break;
1026 case FUNIT_M : nUIUnitKomma+=0; break;
1027 case FUNIT_KM : nUIUnitKomma+=3; break;
1028 // Inch
1029 case FUNIT_TWIP : nMul=144; nUIUnitKomma--; break; // 1Twip = 1/1440"
1030 case FUNIT_POINT : nMul=72; break; // 1Pt = 1/72"
1031 case FUNIT_PICA : nMul=6; break; // 1Pica = 1/6"
1032 case FUNIT_INCH : break; // 1" = 1"
1033 case FUNIT_FOOT : nDiv*=12; break; // 1Ft = 12"
1034 case FUNIT_MILE : nDiv*=6336; nUIUnitKomma++; break; // 1mile = 63360"
1035 // other
1036 case FUNIT_CUSTOM : break;
1037 case FUNIT_PERCENT: nUIUnitKomma+=2; break;
1038 // TODO: Add code to handle the following if needed (added to remove warning)
1039 case FUNIT_CHAR : break;
1040 case FUNIT_LINE : break;
1041 } // switch
1043 // check if mapping is from metric to inch and adapt
1044 const bool bMapInch(IsInch(eObjUnit));
1045 const bool bUIMetr(IsMetric(eUIUnit));
1047 if (bMapInch && bUIMetr)
1049 nUIUnitKomma += 4;
1050 nMul *= 254;
1053 // check if mapping is from inch to metric and adapt
1054 const bool bMapMetr(IsMetric(eObjUnit));
1055 const bool bUIInch(IsInch(eUIUnit));
1057 if (bMapMetr && bUIInch)
1059 nUIUnitKomma -= 4;
1060 nDiv *= 254;
1063 // use temporary fraction for reduction (fallback to 32bit here),
1064 // may need to be changed in the future, too
1065 if(1 != nMul || 1 != nDiv)
1067 const Fraction aTemp(static_cast< long >(nMul), static_cast< long >(nDiv));
1068 nMul = aTemp.GetNumerator();
1069 nDiv = aTemp.GetDenominator();
1072 // #i89872# take Unit of Measurement into account
1073 if(1 != aUIScale.GetDenominator() || 1 != aUIScale.GetNumerator())
1075 // divide by UIScale
1076 nMul *= aUIScale.GetDenominator();
1077 nDiv *= aUIScale.GetNumerator();
1080 // shorten trailing zeros for dividend
1081 while(0 == (nMul % 10))
1083 nUIUnitKomma--;
1084 nMul /= 10;
1087 // shorten trailing zeros for divisor
1088 while(0 == (nDiv % 10))
1090 nUIUnitKomma++;
1091 nDiv /= 10;
1094 // end preparations, set member values
1095 aUIUnitFact = Fraction(sal_Int32(nMul), sal_Int32(nDiv));
1096 bUIOnlyKomma = (nMul == nDiv);
1097 TakeUnitStr(eUIUnit, aUIUnitStr);
1100 void SdrModel::SetScaleUnit(MapUnit eMap, const Fraction& rFrac)
1102 if (eObjUnit!=eMap || aObjUnit!=rFrac) {
1103 eObjUnit=eMap;
1104 aObjUnit=rFrac;
1105 pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
1106 ImpSetUIUnit();
1107 ImpSetOutlinerDefaults( pDrawOutliner );
1108 ImpSetOutlinerDefaults( pHitTestOutliner );
1109 ImpReformatAllTextObjects();
1113 void SdrModel::SetScaleUnit(MapUnit eMap)
1115 if (eObjUnit!=eMap) {
1116 eObjUnit=eMap;
1117 pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
1118 ImpSetUIUnit();
1119 ImpSetOutlinerDefaults( pDrawOutliner );
1120 ImpSetOutlinerDefaults( pHitTestOutliner );
1121 ImpReformatAllTextObjects();
1125 void SdrModel::SetScaleFraction(const Fraction& rFrac)
1127 if (aObjUnit!=rFrac) {
1128 aObjUnit=rFrac;
1129 ImpSetUIUnit();
1130 ImpSetOutlinerDefaults( pDrawOutliner );
1131 ImpSetOutlinerDefaults( pHitTestOutliner );
1132 ImpReformatAllTextObjects();
1136 void SdrModel::SetUIUnit(FieldUnit eUnit)
1138 if (eUIUnit!=eUnit) {
1139 eUIUnit=eUnit;
1140 ImpSetUIUnit();
1141 ImpReformatAllTextObjects();
1145 void SdrModel::SetUIScale(const Fraction& rScale)
1147 if (aUIScale!=rScale) {
1148 aUIScale=rScale;
1149 ImpSetUIUnit();
1150 ImpReformatAllTextObjects();
1154 void SdrModel::SetUIUnit(FieldUnit eUnit, const Fraction& rScale)
1156 if (eUIUnit!=eUnit || aUIScale!=rScale) {
1157 eUIUnit=eUnit;
1158 aUIScale=rScale;
1159 ImpSetUIUnit();
1160 ImpReformatAllTextObjects();
1164 void SdrModel::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
1166 switch(eUnit)
1168 default:
1169 case FUNIT_NONE :
1170 case FUNIT_CUSTOM :
1172 rStr = String();
1173 break;
1175 case FUNIT_100TH_MM:
1177 rStr = OUString("/100mm");
1178 break;
1180 case FUNIT_MM :
1182 rStr = OUString("mm");
1183 break;
1185 case FUNIT_CM :
1187 rStr = OUString("cm");
1188 break;
1190 case FUNIT_M :
1192 rStr = String();
1193 rStr += sal_Unicode('m');
1194 break;
1196 case FUNIT_KM :
1198 rStr = OUString("km");
1199 break;
1201 case FUNIT_TWIP :
1203 rStr = OUString("twip");
1204 break;
1206 case FUNIT_POINT :
1208 rStr = OUString("pt");
1209 break;
1211 case FUNIT_PICA :
1213 rStr = OUString("pica");
1214 break;
1216 case FUNIT_INCH :
1218 rStr = String();
1219 rStr += sal_Unicode('"');
1220 break;
1222 case FUNIT_FOOT :
1224 rStr = OUString("ft");
1225 break;
1227 case FUNIT_MILE :
1229 rStr = OUString("mile(s)");
1230 break;
1232 case FUNIT_PERCENT:
1234 rStr = String();
1235 rStr += sal_Unicode('%');
1236 break;
1241 void SdrModel::TakeMetricStr(long nVal, OUString& rStr, bool bNoUnitChars, sal_Int32 nNumDigits) const
1243 // #i22167#
1244 // change to double precision usage to not lose decimal places
1245 const bool bNegative(nVal < 0L);
1246 SvtSysLocale aSysLoc;
1247 const LocaleDataWrapper& rLoc(aSysLoc.GetLocaleData());
1248 double fLocalValue(double(nVal) * double(aUIUnitFact));
1250 if(bNegative)
1252 fLocalValue = -fLocalValue;
1255 if( -1 == nNumDigits )
1257 nNumDigits = rLoc.getNumDigits();
1260 sal_Int32 nKomma(nUIUnitKomma);
1262 if(nKomma > nNumDigits)
1264 const sal_Int32 nDiff(nKomma - nNumDigits);
1265 const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
1267 fLocalValue /= fFactor;
1268 nKomma = nNumDigits;
1270 else if(nKomma < nNumDigits)
1272 const sal_Int32 nDiff(nNumDigits - nKomma);
1273 const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
1275 fLocalValue *= fFactor;
1276 nKomma = nNumDigits;
1279 OUStringBuffer aBuf;
1280 aBuf.append(static_cast<sal_Int32>(fLocalValue + 0.5));
1282 if(nKomma < 0)
1284 // negative nKomma (decimal point) means: add zeros
1285 sal_Int32 nAnz(-nKomma);
1287 for(sal_Int32 i=0; i<nAnz; i++)
1288 aBuf.append(sal_Unicode('0'));
1290 nKomma = 0;
1293 // the second condition needs to be <= since inside this loop
1294 // also the leading zero is inserted.
1295 if (nKomma > 0 && aBuf.getLength() <= nKomma)
1297 // if necessary, add zeros before the decimal point
1298 sal_Int32 nAnz = nKomma - aBuf.getLength();
1300 if(nAnz >= 0 && rLoc.isNumLeadingZero())
1301 nAnz++;
1303 for(sal_Int32 i=0; i<nAnz; i++)
1304 aBuf.insert(0, sal_Unicode('0'));
1307 sal_Unicode cDec( rLoc.getNumDecimalSep()[0] );
1309 // insert KommaChar (decimal point character)
1310 sal_Int32 nVorKomma = aBuf.getLength() - nKomma;
1312 if(nKomma > 0)
1313 aBuf.insert(nVorKomma, cDec);
1315 if(!rLoc.isNumTrailingZeros())
1317 // Remove all trailing zeros.
1318 while (aBuf.getLength() && aBuf[aBuf.getLength()-1] == sal_Unicode('0'))
1319 aBuf.remove(aBuf.getLength()-1, 1);
1321 // Remove decimal if it's the last character.
1322 if (aBuf.getLength() && aBuf[aBuf.getLength()-1] == cDec)
1323 aBuf.remove(aBuf.getLength()-1, 1);
1326 // if necessary, add separators before every third digit
1327 if( nVorKomma > 3 )
1329 String aThoSep( rLoc.getNumThousandSep() );
1330 if ( aThoSep.Len() > 0 )
1332 sal_Unicode cTho( aThoSep.GetChar(0) );
1333 sal_Int32 i(nVorKomma - 3);
1335 while(i > 0)
1337 aBuf.insert(i, cTho);
1338 i -= 3;
1343 if (!aBuf.getLength())
1344 aBuf.append(sal_Unicode('0'));
1346 if(bNegative)
1348 aBuf.insert(0, sal_Unicode('-'));
1351 if(!bNoUnitChars)
1352 aBuf.append(aUIUnitStr);
1354 rStr = aBuf.makeStringAndClear();
1357 void SdrModel::TakeWinkStr(long nWink, OUString& rStr, bool bNoDegChar) const
1359 bool bNeg = nWink < 0;
1361 if(bNeg)
1362 nWink = -nWink;
1364 OUStringBuffer aBuf;
1365 aBuf.append(static_cast<sal_Int32>(nWink));
1367 SvtSysLocale aSysLoc;
1368 const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
1369 sal_Int32 nAnz = 2;
1371 if(rLoc.isNumLeadingZero())
1372 nAnz++;
1374 while(aBuf.getLength() < nAnz)
1375 aBuf.insert(0, sal_Unicode('0'));
1377 aBuf.insert(aBuf.getLength()-2, rLoc.getNumDecimalSep()[0]);
1379 if(bNeg)
1380 aBuf.insert(0, sal_Unicode('-'));
1382 if(!bNoDegChar)
1383 aBuf.append(DEGREE_CHAR);
1385 rStr = aBuf.makeStringAndClear();
1388 void SdrModel::TakePercentStr(const Fraction& rVal, XubString& rStr, bool bNoPercentChar) const
1390 sal_Int32 nMul(rVal.GetNumerator());
1391 sal_Int32 nDiv(rVal.GetDenominator());
1392 bool bNeg(nMul < 0);
1394 if(nDiv < 0)
1395 bNeg = !bNeg;
1397 if(nMul < 0)
1398 nMul = -nMul;
1400 if(nDiv < 0)
1401 nDiv = -nDiv;
1403 nMul *= 100;
1404 nMul += nDiv/2;
1405 nMul /= nDiv;
1407 rStr = OUString::valueOf(nMul);
1409 if(bNeg)
1410 rStr.Insert(sal_Unicode('-'), 0);
1412 if(!bNoPercentChar)
1413 rStr += sal_Unicode('%');
1416 void SdrModel::SetChanged(sal_Bool bFlg)
1418 mbChanged = bFlg;
1421 void SdrModel::RecalcPageNums(bool bMaster)
1423 if(bMaster)
1425 sal_uInt16 nAnz=sal_uInt16(maMaPag.size());
1426 sal_uInt16 i;
1427 for (i=0; i<nAnz; i++) {
1428 SdrPage* pPg=maMaPag[i];
1429 pPg->SetPageNum(i);
1431 bMPgNumsDirty=sal_False;
1433 else
1435 sal_uInt16 nAnz=sal_uInt16(maPages.size());
1436 sal_uInt16 i;
1437 for (i=0; i<nAnz; i++) {
1438 SdrPage* pPg=maPages[i];
1439 pPg->SetPageNum(i);
1441 bPagNumsDirty=sal_False;
1445 void SdrModel::InsertPage(SdrPage* pPage, sal_uInt16 nPos)
1447 sal_uInt16 nAnz=GetPageCount();
1448 if (nPos>nAnz) nPos=nAnz;
1449 maPages.insert(maPages.begin()+nPos,pPage);
1450 PageListChanged();
1451 pPage->SetInserted(sal_True);
1452 pPage->SetPageNum(nPos);
1453 pPage->SetModel(this);
1454 if (nPos<nAnz) bPagNumsDirty=sal_True;
1455 SetChanged();
1456 SdrHint aHint(HINT_PAGEORDERCHG);
1457 aHint.SetPage(pPage);
1458 Broadcast(aHint);
1461 void SdrModel::DeletePage(sal_uInt16 nPgNum)
1463 SdrPage* pPg=RemovePage(nPgNum);
1464 delete pPg;
1467 SdrPage* SdrModel::RemovePage(sal_uInt16 nPgNum)
1469 SdrPage* pPg=maPages[nPgNum];
1470 maPages.erase(maPages.begin()+nPgNum);
1471 PageListChanged();
1472 if (pPg!=NULL) {
1473 pPg->SetInserted(sal_False);
1475 bPagNumsDirty=sal_True;
1476 SetChanged();
1477 SdrHint aHint(HINT_PAGEORDERCHG);
1478 aHint.SetPage(pPg);
1479 Broadcast(aHint);
1480 return pPg;
1483 void SdrModel::MovePage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
1485 SdrPage* pPg=maPages[nPgNum];
1486 if (pPg!=NULL) {
1487 maPages.erase(maPages.begin()+nPgNum); // shortcut to avoid two broadcasts
1488 PageListChanged();
1489 pPg->SetInserted(sal_False);
1490 InsertPage(pPg,nNewPos);
1492 else
1493 RemovePage(nPgNum);
1496 void SdrModel::InsertMasterPage(SdrPage* pPage, sal_uInt16 nPos)
1498 sal_uInt16 nAnz=GetMasterPageCount();
1499 if (nPos>nAnz) nPos=nAnz;
1500 maMaPag.insert(maMaPag.begin()+nPos,pPage);
1501 MasterPageListChanged();
1502 pPage->SetInserted(sal_True);
1503 pPage->SetPageNum(nPos);
1504 pPage->SetModel(this);
1505 if (nPos<nAnz) {
1506 bMPgNumsDirty=sal_True;
1508 SetChanged();
1509 SdrHint aHint(HINT_PAGEORDERCHG);
1510 aHint.SetPage(pPage);
1511 Broadcast(aHint);
1514 void SdrModel::DeleteMasterPage(sal_uInt16 nPgNum)
1516 SdrPage* pPg=RemoveMasterPage(nPgNum);
1517 delete pPg;
1520 SdrPage* SdrModel::RemoveMasterPage(sal_uInt16 nPgNum)
1522 SdrPage* pRetPg=maMaPag[nPgNum];
1523 maMaPag.erase(maMaPag.begin()+nPgNum);
1524 MasterPageListChanged();
1526 if(pRetPg)
1528 // Now delete the links from the normal drawing pages to the deleted master page.
1529 sal_uInt16 nPageAnz(GetPageCount());
1531 for(sal_uInt16 np(0); np < nPageAnz; np++)
1533 GetPage(np)->TRG_ImpMasterPageRemoved(*pRetPg);
1536 pRetPg->SetInserted(sal_False);
1539 bMPgNumsDirty=sal_True;
1540 SetChanged();
1541 SdrHint aHint(HINT_PAGEORDERCHG);
1542 aHint.SetPage(pRetPg);
1543 Broadcast(aHint);
1544 return pRetPg;
1547 void SdrModel::MoveMasterPage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
1549 SdrPage* pPg=maMaPag[nPgNum];
1550 maMaPag.erase(maMaPag.begin()+nPgNum);
1551 MasterPageListChanged();
1552 if (pPg!=NULL) {
1553 pPg->SetInserted(sal_False);
1554 maMaPag.insert(maMaPag.begin()+nNewPos,pPg);
1555 MasterPageListChanged();
1557 bMPgNumsDirty=sal_True;
1558 SetChanged();
1559 SdrHint aHint(HINT_PAGEORDERCHG);
1560 aHint.SetPage(pPg);
1561 Broadcast(aHint);
1564 ////////////////////////////////////////////////////////////////////////////////////////////////////
1566 void SdrModel::CopyPages(sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1567 sal_uInt16 nDestPos,
1568 bool bUndo, bool bMoveNoCopy)
1570 if( bUndo && !IsUndoEnabled() )
1571 bUndo = false;
1573 if( bUndo )
1574 BegUndo(ImpGetResStr(STR_UndoMergeModel));
1576 sal_uInt16 nPageAnz=GetPageCount();
1577 sal_uInt16 nMaxPage=nPageAnz;
1579 if (nMaxPage!=0)
1580 nMaxPage--;
1581 if (nFirstPageNum>nMaxPage)
1582 nFirstPageNum=nMaxPage;
1583 if (nLastPageNum>nMaxPage)
1584 nLastPageNum =nMaxPage;
1585 bool bReverse=nLastPageNum<nFirstPageNum;
1586 if (nDestPos>nPageAnz)
1587 nDestPos=nPageAnz;
1589 // at first, save the pointers of the affected pages in an array
1590 sal_uInt16 nPageNum=nFirstPageNum;
1591 sal_uInt16 nCopyAnz=((!bReverse)?(nLastPageNum-nFirstPageNum):(nFirstPageNum-nLastPageNum))+1;
1592 SdrPage** pPagePtrs=new SdrPage*[nCopyAnz];
1593 sal_uInt16 nCopyNum;
1594 for(nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
1596 pPagePtrs[nCopyNum]=GetPage(nPageNum);
1597 if (bReverse)
1598 nPageNum--;
1599 else
1600 nPageNum++;
1603 // now copy the pages
1604 sal_uInt16 nDestNum=nDestPos;
1605 for (nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
1607 SdrPage* pPg=pPagePtrs[nCopyNum];
1608 sal_uInt16 nPageNum2=pPg->GetPageNum();
1609 if (!bMoveNoCopy)
1611 const SdrPage* pPg1=GetPage(nPageNum2);
1612 pPg=pPg1->Clone();
1613 InsertPage(pPg,nDestNum);
1614 if (bUndo)
1615 AddUndo(GetSdrUndoFactory().CreateUndoCopyPage(*pPg));
1616 nDestNum++;
1618 else
1620 // TODO: Move is untested!
1621 if (nDestNum>nPageNum2)
1622 nDestNum--;
1624 if(bUndo)
1625 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*GetPage(nPageNum2),nPageNum2,nDestNum));
1627 pPg=RemovePage(nPageNum2);
1628 InsertPage(pPg,nDestNum);
1629 nDestNum++;
1632 if(bReverse)
1633 nPageNum2--;
1634 else
1635 nPageNum2++;
1638 delete[] pPagePtrs;
1639 if(bUndo)
1640 EndUndo();
1643 void SdrModel::Merge(SdrModel& rSourceModel,
1644 sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1645 sal_uInt16 nDestPos,
1646 bool bMergeMasterPages, bool bAllMasterPages,
1647 bool bUndo, bool bTreadSourceAsConst)
1649 if (&rSourceModel==this)
1651 CopyPages(nFirstPageNum,nLastPageNum,nDestPos,bUndo,!bTreadSourceAsConst);
1652 return;
1655 if( bUndo && !IsUndoEnabled() )
1656 bUndo = false;
1658 if (bUndo)
1659 BegUndo(ImpGetResStr(STR_UndoMergeModel));
1661 sal_uInt16 nSrcPageAnz=rSourceModel.GetPageCount();
1662 sal_uInt16 nSrcMasterPageAnz=rSourceModel.GetMasterPageCount();
1663 sal_uInt16 nDstMasterPageAnz=GetMasterPageCount();
1664 bool bInsPages=(nFirstPageNum<nSrcPageAnz || nLastPageNum<nSrcPageAnz);
1665 sal_uInt16 nMaxSrcPage=nSrcPageAnz; if (nMaxSrcPage!=0) nMaxSrcPage--;
1666 if (nFirstPageNum>nMaxSrcPage) nFirstPageNum=nMaxSrcPage;
1667 if (nLastPageNum>nMaxSrcPage) nLastPageNum =nMaxSrcPage;
1668 bool bReverse=nLastPageNum<nFirstPageNum;
1670 sal_uInt16* pMasterMap=NULL;
1671 bool* pMasterNeed=NULL;
1672 sal_uInt16 nMasterNeed=0;
1673 if (bMergeMasterPages && nSrcMasterPageAnz!=0) {
1674 // determine which MasterPages from rSrcModel we need
1675 pMasterMap=new sal_uInt16[nSrcMasterPageAnz];
1676 pMasterNeed=new bool[nSrcMasterPageAnz];
1677 memset(pMasterMap,0xFF,nSrcMasterPageAnz*sizeof(sal_uInt16));
1678 if (bAllMasterPages) {
1679 memset(pMasterNeed, true, nSrcMasterPageAnz * sizeof(bool));
1680 } else {
1681 memset(pMasterNeed, false, nSrcMasterPageAnz * sizeof(bool));
1682 sal_uInt16 nAnf= bReverse ? nLastPageNum : nFirstPageNum;
1683 sal_uInt16 nEnd= bReverse ? nFirstPageNum : nLastPageNum;
1684 for (sal_uInt16 i=nAnf; i<=nEnd; i++) {
1685 const SdrPage* pPg=rSourceModel.GetPage(i);
1686 if(pPg->TRG_HasMasterPage())
1688 SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
1689 sal_uInt16 nMPgNum(rMasterPage.GetPageNum());
1691 if(nMPgNum < nSrcMasterPageAnz)
1693 pMasterNeed[nMPgNum] = true;
1698 // now determine the Mapping of the MasterPages
1699 sal_uInt16 nAktMaPagNum=nDstMasterPageAnz;
1700 for (sal_uInt16 i=0; i<nSrcMasterPageAnz; i++) {
1701 if (pMasterNeed[i]) {
1702 pMasterMap[i]=nAktMaPagNum;
1703 nAktMaPagNum++;
1704 nMasterNeed++;
1709 // get the MasterPages
1710 if (pMasterMap!=NULL && pMasterNeed!=NULL && nMasterNeed!=0) {
1711 for (sal_uInt16 i=nSrcMasterPageAnz; i>0;) {
1712 i--;
1713 if (pMasterNeed[i]) {
1714 SdrPage* pPg=NULL;
1715 if (bTreadSourceAsConst) {
1716 const SdrPage* pPg1=rSourceModel.GetMasterPage(i);
1717 pPg=pPg1->Clone();
1718 } else {
1719 pPg=rSourceModel.RemoveMasterPage(i);
1721 if (pPg!=NULL) {
1722 // Now append all of them to the end of the DstModel.
1723 // Don't use InsertMasterPage(), because everything is
1724 // inconsistent until all are in.
1725 maMaPag.insert(maMaPag.begin()+nDstMasterPageAnz, pPg);
1726 MasterPageListChanged();
1727 pPg->SetInserted(sal_True);
1728 pPg->SetModel(this);
1729 bMPgNumsDirty=sal_True;
1730 if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
1731 } else {
1732 OSL_FAIL("SdrModel::Merge(): MasterPage not found in SourceModel.");
1738 // get the drawing pages
1739 if (bInsPages) {
1740 sal_uInt16 nSourcePos=nFirstPageNum;
1741 sal_uInt16 nMergeCount=sal_uInt16(std::abs((long)((long)nFirstPageNum-nLastPageNum))+1);
1742 if (nDestPos>GetPageCount()) nDestPos=GetPageCount();
1743 while (nMergeCount>0) {
1744 SdrPage* pPg=NULL;
1745 if (bTreadSourceAsConst) {
1746 const SdrPage* pPg1=rSourceModel.GetPage(nSourcePos);
1747 pPg=pPg1->Clone();
1748 } else {
1749 pPg=rSourceModel.RemovePage(nSourcePos);
1751 if (pPg!=NULL) {
1752 InsertPage(pPg,nDestPos);
1753 if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
1755 if(pPg->TRG_HasMasterPage())
1757 SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
1758 sal_uInt16 nMaPgNum(rMasterPage.GetPageNum());
1760 if (bMergeMasterPages)
1762 sal_uInt16 nNeuNum(0xFFFF);
1764 if(pMasterMap)
1766 nNeuNum = pMasterMap[nMaPgNum];
1769 if(nNeuNum != 0xFFFF)
1771 if(bUndo)
1773 AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*pPg));
1776 pPg->TRG_SetMasterPage(*GetMasterPage(nNeuNum));
1778 DBG_ASSERT(nNeuNum!=0xFFFF,"SdrModel::Merge(): Something is crooked with the mapping of the MasterPages.");
1779 } else {
1780 if (nMaPgNum>=nDstMasterPageAnz) {
1781 // This is outside of the original area of the MasterPage of the DstModel.
1782 pPg->TRG_ClearMasterPage();
1787 } else {
1788 OSL_FAIL("SdrModel::Merge(): Drawing page not found in SourceModel.");
1790 nDestPos++;
1791 if (bReverse) nSourcePos--;
1792 else if (bTreadSourceAsConst) nSourcePos++;
1793 nMergeCount--;
1797 delete [] pMasterMap;
1798 delete [] pMasterNeed;
1800 bMPgNumsDirty=sal_True;
1801 bPagNumsDirty=sal_True;
1803 SetChanged();
1804 // TODO: Missing: merging and mapping of layers
1805 // at the objects as well as at the MasterPageDescriptors
1806 if (bUndo) EndUndo();
1809 void SdrModel::SetStarDrawPreviewMode(sal_Bool bPreview)
1811 if (!bPreview && bStarDrawPreviewMode && GetPageCount())
1813 // Resetting is not allowed, because the Model might not be loaded completely
1814 DBG_ASSERT(sal_False,"SdrModel::SetStarDrawPreviewMode(): Resetting not allowed, because Model might not be complete.");
1816 else
1818 bStarDrawPreviewMode = bPreview;
1822 uno::Reference< uno::XInterface > SdrModel::getUnoModel()
1824 if( !mxUnoModel.is() )
1825 mxUnoModel = createUnoModel();
1827 return mxUnoModel;
1830 void SdrModel::setUnoModel( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xModel )
1832 mxUnoModel = xModel;
1835 uno::Reference< uno::XInterface > SdrModel::createUnoModel()
1837 OSL_FAIL( "SdrModel::createUnoModel() - base implementation should not be called!" );
1838 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInt;
1839 return xInt;
1842 void SdrModel::setLock( bool bLock )
1844 if( mbModelLocked != bLock )
1846 // #i120437# need to set first, else ImpReformatAllEdgeObjects will do nothing
1847 mbModelLocked = bLock;
1849 if( sal_False == bLock )
1851 ImpReformatAllEdgeObjects();
1856 ////////////////////////////////////////////////////////////////////////////////////////////////////
1858 void SdrModel::MigrateItemSet( const SfxItemSet* pSourceSet, SfxItemSet* pDestSet, SdrModel* pNewModel )
1860 if( pSourceSet && pDestSet && (pSourceSet != pDestSet ) )
1862 if( pNewModel == NULL )
1863 pNewModel = this;
1865 SfxWhichIter aWhichIter(*pSourceSet);
1866 sal_uInt16 nWhich(aWhichIter.FirstWhich());
1867 const SfxPoolItem *pPoolItem;
1869 while(nWhich)
1871 if(SFX_ITEM_SET == pSourceSet->GetItemState(nWhich, sal_False, &pPoolItem))
1873 const SfxPoolItem* pItem = pPoolItem;
1875 switch( nWhich )
1877 case XATTR_FILLBITMAP:
1878 pItem = ((XFillBitmapItem*)pItem)->checkForUniqueItem( pNewModel );
1879 break;
1880 case XATTR_LINEDASH:
1881 pItem = ((XLineDashItem*)pItem)->checkForUniqueItem( pNewModel );
1882 break;
1883 case XATTR_LINESTART:
1884 pItem = ((XLineStartItem*)pItem)->checkForUniqueItem( pNewModel );
1885 break;
1886 case XATTR_LINEEND:
1887 pItem = ((XLineEndItem*)pItem)->checkForUniqueItem( pNewModel );
1888 break;
1889 case XATTR_FILLGRADIENT:
1890 pItem = ((XFillGradientItem*)pItem)->checkForUniqueItem( pNewModel );
1891 break;
1892 case XATTR_FILLFLOATTRANSPARENCE:
1893 // allow all kinds of XFillFloatTransparenceItem to be set
1894 pItem = ((XFillFloatTransparenceItem*)pItem)->checkForUniqueItem( pNewModel );
1895 break;
1896 case XATTR_FILLHATCH:
1897 pItem = ((XFillHatchItem*)pItem)->checkForUniqueItem( pNewModel );
1898 break;
1901 // set item
1902 if( pItem )
1904 pDestSet->Put(*pItem);
1906 // delete item if it was a generated one
1907 if( pItem != pPoolItem)
1908 delete (SfxPoolItem*)pItem;
1911 nWhich = aWhichIter.NextWhich();
1916 ////////////////////////////////////////////////////////////////////////////////////////////////////
1918 void SdrModel::SetForbiddenCharsTable( rtl::Reference<SvxForbiddenCharactersTable> xForbiddenChars )
1920 if( mpForbiddenCharactersTable )
1921 mpForbiddenCharactersTable->release();
1923 mpForbiddenCharactersTable = xForbiddenChars.get();
1925 if( mpForbiddenCharactersTable )
1926 mpForbiddenCharactersTable->acquire();
1928 ImpSetOutlinerDefaults( pDrawOutliner );
1929 ImpSetOutlinerDefaults( pHitTestOutliner );
1932 rtl::Reference<SvxForbiddenCharactersTable> SdrModel::GetForbiddenCharsTable() const
1934 return mpForbiddenCharactersTable;
1937 void SdrModel::SetCharCompressType( sal_uInt16 nType )
1939 if( nType != mnCharCompressType )
1941 mnCharCompressType = nType;
1942 ImpSetOutlinerDefaults( pDrawOutliner );
1943 ImpSetOutlinerDefaults( pHitTestOutliner );
1947 void SdrModel::SetKernAsianPunctuation( sal_Bool bEnabled )
1949 if( mbKernAsianPunctuation != (bool) bEnabled )
1951 mbKernAsianPunctuation = bEnabled;
1952 ImpSetOutlinerDefaults( pDrawOutliner );
1953 ImpSetOutlinerDefaults( pHitTestOutliner );
1957 void SdrModel::SetAddExtLeading( sal_Bool bEnabled )
1959 if( mbAddExtLeading != (bool) bEnabled )
1961 mbAddExtLeading = bEnabled;
1962 ImpSetOutlinerDefaults( pDrawOutliner );
1963 ImpSetOutlinerDefaults( pHitTestOutliner );
1967 void SdrModel::ReformatAllTextObjects()
1969 ImpReformatAllTextObjects();
1972 SdrOutliner* SdrModel::createOutliner( sal_uInt16 nOutlinerMode )
1974 if( NULL == mpOutlinerCache )
1975 mpOutlinerCache = new SdrOutlinerCache(this);
1977 return mpOutlinerCache->createOutliner( nOutlinerMode );
1980 void SdrModel::disposeOutliner( SdrOutliner* pOutliner )
1982 if( mpOutlinerCache )
1984 mpOutlinerCache->disposeOutliner( pOutliner );
1986 else
1988 delete pOutliner;
1992 SvxNumType SdrModel::GetPageNumType() const
1994 return SVX_ARABIC;
1997 const SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum) const
1999 DBG_ASSERT(nPgNum < maPages.size(), "SdrModel::GetPage: Access out of range (!)");
2000 return nPgNum < maPages.size() ? maPages[nPgNum] : NULL;
2003 SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum)
2005 DBG_ASSERT(nPgNum < maPages.size(), "SdrModel::GetPage: Access out of range (!)");
2006 return nPgNum < maPages.size() ? maPages[nPgNum] : NULL;
2009 sal_uInt16 SdrModel::GetPageCount() const
2011 return sal_uInt16(maPages.size());
2014 void SdrModel::PageListChanged()
2018 const SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum) const
2020 DBG_ASSERT(nPgNum < maMaPag.size(), "SdrModel::GetMasterPage: Access out of range (!)");
2021 return maMaPag[nPgNum];
2024 SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum)
2026 DBG_ASSERT(nPgNum < maMaPag.size(), "SdrModel::GetMasterPage: Access out of range (!)");
2027 return maMaPag[nPgNum];
2030 sal_uInt16 SdrModel::GetMasterPageCount() const
2032 return sal_uInt16(maMaPag.size());
2035 void SdrModel::MasterPageListChanged()
2039 void SdrModel::SetSdrUndoManager( SfxUndoManager* pUndoManager )
2041 mpImpl->mpUndoManager = pUndoManager;
2044 SfxUndoManager* SdrModel::GetSdrUndoManager() const
2046 return mpImpl->mpUndoManager;
2049 SdrUndoFactory& SdrModel::GetSdrUndoFactory() const
2051 if( !mpImpl->mpUndoFactory )
2052 mpImpl->mpUndoFactory = new SdrUndoFactory;
2053 return *mpImpl->mpUndoFactory;
2056 void SdrModel::SetSdrUndoFactory( SdrUndoFactory* pUndoFactory )
2058 if( pUndoFactory && (pUndoFactory != mpImpl->mpUndoFactory) )
2060 delete mpImpl->mpUndoFactory;
2061 mpImpl->mpUndoFactory = pUndoFactory;
2065 namespace
2067 class theSdrModelUnoTunnelImplementationId : public rtl::Static< UnoTunnelIdInit, theSdrModelUnoTunnelImplementationId > {};
2070 const ::com::sun::star::uno::Sequence< sal_Int8 >& SdrModel::getUnoTunnelImplementationId()
2072 return theSdrModelUnoTunnelImplementationId::get().getSeq();
2075 void SdrModel::SetDrawingLayerPoolDefaults()
2077 const String aNullStr;
2078 const Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE);
2079 const Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING);
2080 const XHatch aNullHatch(aNullLineCol);
2082 pItemPool->SetPoolDefaultItem( XFillColorItem(aNullStr,aNullFillCol) );
2083 pItemPool->SetPoolDefaultItem( XFillHatchItem(pItemPool,aNullHatch) );
2084 pItemPool->SetPoolDefaultItem( XLineColorItem(aNullStr,aNullLineCol) );
2087 ////////////////////////////////////////////////////////////////////////////////////////////////////
2089 TYPEINIT1(SdrHint,SfxHint);
2091 SdrHint::SdrHint(SdrHintKind eNewHint)
2092 : mpPage(0L),
2093 mpObj(0L),
2094 mpObjList(0L),
2095 meHint(eNewHint)
2099 SdrHint::SdrHint(const SdrObject& rNewObj)
2100 : mpPage(rNewObj.GetPage()),
2101 mpObj(&rNewObj),
2102 mpObjList(rNewObj.GetObjList()),
2103 meHint(HINT_OBJCHG)
2105 maRectangle = rNewObj.GetLastBoundRect();
2108 void SdrHint::SetPage(const SdrPage* pNewPage)
2110 mpPage = pNewPage;
2113 void SdrHint::SetObject(const SdrObject* pNewObj)
2115 mpObj = pNewObj;
2118 void SdrHint::SetKind(SdrHintKind eNewKind)
2120 meHint = eNewKind;
2123 const SdrPage* SdrHint::GetPage() const
2125 return mpPage;
2128 const SdrObject* SdrHint::GetObject() const
2130 return mpObj;
2133 SdrHintKind SdrHint::GetKind() const
2135 return meHint;
2138 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */