xref: /trunk/main/svx/source/svdraw/svdmodel.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdmodel.hxx>
32 
33 #include <rtl/uuid.h>
34 #include <com/sun/star/lang/XComponent.hpp>
35 #include <osl/endian.h>
36 #include <rtl/logfile.hxx>
37 #include <math.h>
38 #include <tools/urlobj.hxx>
39 #include <unotools/ucbstreamhelper.hxx>
40 
41 #include <tools/string.hxx>
42 #include <svl/whiter.hxx>
43 #include <svx/xit.hxx>
44 #include <svx/xbtmpit.hxx>
45 #include <svx/xlndsit.hxx>
46 #include <svx/xlnedit.hxx>
47 #include <svx/xflgrit.hxx>
48 #include <svx/xflftrit.hxx>
49 #include <svx/xflhtit.hxx>
50 #include <svx/xlnstit.hxx>
51 
52 #include "svx/svditext.hxx"
53 #include <editeng/editeng.hxx>   // Fuer EditEngine::CreatePool()
54 
55 #include <svx/xtable.hxx>
56 
57 #include "svx/svditer.hxx"
58 #include <svx/svdtrans.hxx>
59 #include <svx/svdpage.hxx>
60 #include <svx/svdlayer.hxx>
61 #include <svx/svdundo.hxx>
62 #include <svx/svdpool.hxx>
63 #include <svx/svdobj.hxx>
64 #include <svx/svdotext.hxx>  // fuer ReformatAllTextObjects und CalcFieldValue
65 #include <svx/svdetc.hxx>
66 #include <svx/svdoutl.hxx>
67 #include <svx/svdoole2.hxx>
68 #include "svx/svdglob.hxx"  // Stringcache
69 #include "svx/svdstr.hrc"   // Objektname
70 #include "svdoutlinercache.hxx"
71 
72 #include "svx/xflclit.hxx"
73 #include "svx/xflhtit.hxx"
74 #include "svx/xlnclit.hxx"
75 
76 #include <svl/asiancfg.hxx>
77 #include "editeng/fontitem.hxx"
78 #include <editeng/colritem.hxx>
79 #include <editeng/fhgtitem.hxx>
80 #include <svl/style.hxx>
81 #include <tools/bigint.hxx>
82 #include <editeng/numitem.hxx>
83 #include <editeng/bulitem.hxx>
84 #include <editeng/outlobj.hxx>
85 #include "editeng/forbiddencharacterstable.hxx"
86 #include <svl/zforlist.hxx>
87 #include <comphelper/processfactory.hxx>
88 
89 // #90477#
90 #include <tools/tenccvt.hxx>
91 #include <unotools/syslocale.hxx>
92 
93 // #95114#
94 #include <vcl/svapp.hxx>
95 #include <svx/sdr/properties/properties.hxx>
96 #include <editeng/eeitem.hxx>
97 #include <svl/itemset.hxx>
98 
99 using namespace ::com::sun::star;
100 using namespace ::com::sun::star::uno;
101 using namespace ::com::sun::star::lang;
102 
103 ////////////////////////////////////////////////////////////////////////////////////////////////////
104 
105 struct SdrModelImpl
106 {
107     SfxUndoManager* mpUndoManager;
108     SdrUndoFactory* mpUndoFactory;
109     bool mbAllowShapePropertyChangeListener;
110 };
111 
112 ////////////////////////////////////////////////////////////////////////////////////////////////////
113 
114 DBG_NAME(SdrModel)
115 TYPEINIT1(SdrModel,SfxBroadcaster);
116 void SdrModel::ImpCtor(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* _pEmbeddedHelper,
117     bool bUseExtColorTable, bool bLoadRefCounts)
118 {
119     mpImpl = new SdrModelImpl;
120     mpImpl->mpUndoManager=0;
121     mpImpl->mpUndoFactory=0;
122     mpImpl->mbAllowShapePropertyChangeListener=false;
123     mbInDestruction=false;
124     aObjUnit=SdrEngineDefaults::GetMapFraction();
125     eObjUnit=SdrEngineDefaults::GetMapUnit();
126     eUIUnit=FUNIT_MM;
127     aUIScale=Fraction(1,1);
128     nUIUnitKomma=0;
129     bUIOnlyKomma=sal_False;
130     pLayerAdmin=NULL;
131     pItemPool=pPool;
132     bMyPool=sal_False;
133     m_pEmbeddedHelper=_pEmbeddedHelper;
134     pDrawOutliner=NULL;
135     pHitTestOutliner=NULL;
136     pRefOutDev=NULL;
137     nProgressAkt=0;
138     nProgressMax=0;
139     nProgressOfs=0;
140     pDefaultStyleSheet=NULL;
141     pLinkManager=NULL;
142     pUndoStack=NULL;
143     pRedoStack=NULL;
144     nMaxUndoCount=16;
145     pAktUndoGroup=NULL;
146     nUndoLevel=0;
147     mbUndoEnabled=true;
148     nProgressPercent=0;
149     nLoadVersion=0;
150     bExtColorTable=sal_False;
151     mbChanged = sal_False;
152     bInfoChanged=sal_False;
153     bPagNumsDirty=sal_False;
154     bMPgNumsDirty=sal_False;
155     bPageNotValid=sal_False;
156     bSavePortable=sal_False;
157     bSaveCompressed=sal_False;
158     bSaveNative=sal_False;
159     bSwapGraphics=sal_False;
160     nSwapGraphicsMode=SDR_SWAPGRAPHICSMODE_DEFAULT;
161     bSaveOLEPreview=sal_False;
162     bPasteResize=sal_False;
163     bNoBitmapCaching=sal_False;
164     bReadOnly=sal_False;
165     nStreamCompressMode=COMPRESSMODE_NONE;
166     nStreamNumberFormat=NUMBERFORMAT_INT_BIGENDIAN;
167     nDefaultTabulator=0;
168     pColorTable=NULL;
169     pDashList=NULL;
170     pLineEndList=NULL;
171     pHatchList=NULL;
172     pGradientList=NULL;
173     pBitmapList=NULL;
174     mpNumberFormatter = NULL;
175     bTransparentTextFrames=sal_False;
176     bStarDrawPreviewMode = sal_False;
177     nStarDrawPreviewMasterPageNum = SDRPAGE_NOTFOUND;
178     pModelStorage = NULL;
179     mpForbiddenCharactersTable = NULL;
180     mbModelLocked = sal_False;
181     mpOutlinerCache = NULL;
182     mbKernAsianPunctuation = sal_False;
183     mbAddExtLeading = sal_False;
184     mnHandoutPageCount = 0;
185 
186     SvxAsianConfig aAsian;
187     mnCharCompressType = aAsian.GetCharDistanceCompression();
188 
189 #ifdef OSL_LITENDIAN
190     nStreamNumberFormat=NUMBERFORMAT_INT_LITTLEENDIAN;
191 #endif
192     bExtColorTable=bUseExtColorTable;
193 
194     if ( pPool == NULL )
195     {
196         pItemPool=new SdrItemPool(0L, bLoadRefCounts);
197         // Der Outliner hat keinen eigenen Pool, deshalb den der EditEngine
198         SfxItemPool* pOutlPool=EditEngine::CreatePool( bLoadRefCounts );
199         // OutlinerPool als SecondaryPool des SdrPool
200         pItemPool->SetSecondaryPool(pOutlPool);
201         // Merken, dass ich mir die beiden Pools selbst gemacht habe
202         bMyPool=sal_True;
203     }
204     pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
205 
206 // SJ: #95129# using static SdrEngineDefaults only if default SvxFontHeight item is not available
207     const SfxPoolItem* pPoolItem = pItemPool->GetPoolDefaultItem( EE_CHAR_FONTHEIGHT );
208     if ( pPoolItem )
209         nDefTextHgt = ((SvxFontHeightItem*)pPoolItem)->GetHeight();
210     else
211         nDefTextHgt = SdrEngineDefaults::GetFontHeight();
212 
213     pItemPool->SetPoolDefaultItem( SdrTextWordWrapItem( sal_False ) );
214 
215     SetTextDefaults();
216 
217     pLayerAdmin=new SdrLayerAdmin;
218     pLayerAdmin->SetModel(this);
219     ImpSetUIUnit();
220 
221     // den DrawOutliner OnDemand erzeugen geht noch nicht, weil ich den Pool
222     // sonst nicht kriege (erst ab 302!)
223     pDrawOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
224     ImpSetOutlinerDefaults(pDrawOutliner, sal_True);
225 
226     pHitTestOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
227     ImpSetOutlinerDefaults(pHitTestOutliner, sal_True);
228 
229     ImpCreateTables();
230 }
231 
232 SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
233     maMaPag(1024,32,32),
234     maPages(1024,32,32)
235 {
236 #ifdef TIMELOG
237     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
238 #endif
239 
240     DBG_CTOR(SdrModel,NULL);
241     ImpCtor(pPool,pPers,sal_False, (FASTBOOL)bLoadRefCounts);
242 }
243 
244 SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
245     maMaPag(1024,32,32),
246     maPages(1024,32,32),
247     aTablePath(rPath)
248 {
249 #ifdef TIMELOG
250     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
251 #endif
252 
253     DBG_CTOR(SdrModel,NULL);
254     ImpCtor(pPool,pPers,sal_False, (FASTBOOL)bLoadRefCounts);
255 }
256 
257 SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, FASTBOOL bUseExtColorTable, sal_Bool bLoadRefCounts):
258     maMaPag(1024,32,32),
259     maPages(1024,32,32)
260 {
261 #ifdef TIMELOG
262     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
263 #endif
264 
265     DBG_CTOR(SdrModel,NULL);
266     ImpCtor(pPool,pPers,bUseExtColorTable, (FASTBOOL)bLoadRefCounts);
267 }
268 
269 SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, FASTBOOL bUseExtColorTable, sal_Bool bLoadRefCounts):
270     maMaPag(1024,32,32),
271     maPages(1024,32,32),
272     aTablePath(rPath)
273 {
274 #ifdef TIMELOG
275     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
276 #endif
277 
278     DBG_CTOR(SdrModel,NULL);
279     ImpCtor(pPool,pPers,bUseExtColorTable, (FASTBOOL)bLoadRefCounts);
280 }
281 
282 SdrModel::SdrModel(const SdrModel& /*rSrcModel*/):
283     SfxBroadcaster(),
284     tools::WeakBase< SdrModel >(),
285     maMaPag(1024,32,32),
286     maPages(1024,32,32)
287 {
288 #ifdef TIMELOG
289     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
290 #endif
291 
292     // noch nicht implementiert
293     DBG_ERROR("SdrModel::CopyCtor() ist noch nicht implementiert");
294 }
295 
296 SdrModel::~SdrModel()
297 {
298 #ifdef TIMELOG
299     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::~SdrModel(...)" );
300 #endif
301 
302     DBG_DTOR(SdrModel,NULL);
303 
304     mbInDestruction = true;
305 
306     Broadcast(SdrHint(HINT_MODELCLEARED));
307 
308     delete mpOutlinerCache;
309 
310     ClearUndoBuffer();
311 #ifdef DBG_UTIL
312     if(pAktUndoGroup)
313     {
314         ByteString aStr("Im Dtor des SdrModel steht noch ein offenes Undo rum: \"");
315 
316         aStr += ByteString(pAktUndoGroup->GetComment(), gsl_getSystemTextEncoding());
317         aStr += '\"';
318 
319         DBG_ERROR(aStr.GetBuffer());
320     }
321 #endif
322     if (pAktUndoGroup!=NULL)
323         delete pAktUndoGroup;
324 
325     // #116168#
326     ClearModel(sal_True);
327 
328     delete pLayerAdmin;
329 
330     // Den DrawOutliner erst nach dem ItemPool loeschen, da
331     // der ItemPool Items des DrawOutliners referenziert !!! (<- das war mal)
332     // Wg. Problem bei Malte Reihenfolge wieder umgestellt.
333     // Loeschen des Outliners vor dem loeschen des ItemPools
334     delete pHitTestOutliner;
335     delete pDrawOutliner;
336 
337     // delete StyleSheetPool, derived classes should not do this since
338     // the DrawingEngine may need it in its destrctor (SB)
339     if( mxStyleSheetPool.is() )
340     {
341         Reference< XComponent > xComponent( dynamic_cast< cppu::OWeakObject* >( mxStyleSheetPool.get() ), UNO_QUERY );
342         if( xComponent.is() ) try
343         {
344             xComponent->dispose();
345         }
346         catch( RuntimeException& )
347         {
348         }
349         mxStyleSheetPool.clear();
350     }
351 
352     if (bMyPool)
353     {
354         // Pools loeschen, falls es meine sind
355         SfxItemPool* pOutlPool=pItemPool->GetSecondaryPool();
356         SfxItemPool::Free(pItemPool);
357         // Der OutlinerPool muss nach dem ItemPool plattgemacht werden, da der
358         // ItemPool SetItems enthaelt die ihrerseits Items des OutlinerPools
359         // referenzieren (Joe)
360         SfxItemPool::Free(pOutlPool);
361     }
362 
363     if( mpForbiddenCharactersTable )
364         mpForbiddenCharactersTable->release();
365 
366     // Tabellen, Listen und Paletten loeschen
367     if (!bExtColorTable)
368         delete pColorTable;
369     delete pDashList;
370     delete pLineEndList;
371     delete pHatchList;
372     delete pGradientList;
373     delete pBitmapList;
374 
375     if(mpNumberFormatter)
376         delete mpNumberFormatter;
377 
378     delete mpImpl->mpUndoFactory;
379     delete mpImpl;
380 }
381 
382 bool SdrModel::IsInDestruction() const
383 {
384     return mbInDestruction;
385 }
386 
387 const SvNumberFormatter& SdrModel::GetNumberFormatter() const
388 {
389     if(!mpNumberFormatter)
390     {
391         // use cast here since from outside view this IS a const method
392         ((SdrModel*)this)->mpNumberFormatter = new SvNumberFormatter(
393             ::comphelper::getProcessServiceFactory(), LANGUAGE_SYSTEM);
394     }
395 
396     return *mpNumberFormatter;
397 }
398 
399 // noch nicht implementiert:
400 void SdrModel::operator=(const SdrModel& /*rSrcModel*/)
401 {
402     DBG_ERROR("SdrModel::operator=() ist noch nicht implementiert");
403 }
404 
405 FASTBOOL SdrModel::operator==(const SdrModel& /*rCmpModel*/) const
406 {
407     DBG_ERROR("SdrModel::operator==() ist noch nicht implementiert");
408     return sal_False;
409 }
410 
411 void SdrModel::SetSwapGraphics( FASTBOOL bSwap )
412 {
413     bSwapGraphics = bSwap;
414 }
415 
416 FASTBOOL SdrModel::IsReadOnly() const
417 {
418     return bReadOnly;
419 }
420 
421 void SdrModel::SetReadOnly(FASTBOOL bYes)
422 {
423     bReadOnly=bYes;
424 }
425 
426 ////////////////////////////////////////////////////////////////////////////////////////////////////
427 
428 void SdrModel::SetMaxUndoActionCount(sal_uIntPtr nAnz)
429 {
430     if (nAnz<1) nAnz=1;
431     nMaxUndoCount=nAnz;
432     if (pUndoStack!=NULL) {
433         while (pUndoStack->Count()>nMaxUndoCount) {
434             delete (SfxUndoAction*) pUndoStack->Remove(pUndoStack->Count());
435         }
436     }
437 }
438 
439 void SdrModel::ClearUndoBuffer()
440 {
441     if (pUndoStack!=NULL) {
442         while (pUndoStack->Count()!=0) {
443             delete (SfxUndoAction*) pUndoStack->Remove(pUndoStack->Count()-1);
444         }
445         delete pUndoStack;
446         pUndoStack=NULL;
447     }
448     if (pRedoStack!=NULL) {
449         while (pRedoStack->Count()!=0) {
450             delete (SfxUndoAction*) pRedoStack->Remove(pRedoStack->Count()-1);
451         }
452         delete pRedoStack;
453         pRedoStack=NULL;
454     }
455 }
456 
457 FASTBOOL SdrModel::Undo()
458 {
459     FASTBOOL bRet=sal_False;
460     if( mpImpl->mpUndoManager )
461     {
462         DBG_ERROR("svx::SdrModel::Undo(), method not supported with application undo manager!");
463     }
464     else
465     {
466         SfxUndoAction* pDo=(SfxUndoAction*)GetUndoAction(0);
467         if(pDo!=NULL)
468         {
469             const bool bWasUndoEnabled = mbUndoEnabled;
470             mbUndoEnabled = false;
471             pDo->Undo();
472             if(pRedoStack==NULL)
473                 pRedoStack=new Container(1024,16,16);
474             pRedoStack->Insert(pUndoStack->Remove((sal_uIntPtr)0),(sal_uIntPtr)0);
475             mbUndoEnabled = bWasUndoEnabled;
476         }
477     }
478     return bRet;
479 }
480 
481 FASTBOOL SdrModel::Redo()
482 {
483     FASTBOOL bRet=sal_False;
484     if( mpImpl->mpUndoManager )
485     {
486         DBG_ERROR("svx::SdrModel::Redo(), method not supported with application undo manager!");
487     }
488     else
489     {
490         SfxUndoAction* pDo=(SfxUndoAction*)GetRedoAction(0);
491         if(pDo!=NULL)
492         {
493             const bool bWasUndoEnabled = mbUndoEnabled;
494             mbUndoEnabled = false;
495             pDo->Redo();
496             if(pUndoStack==NULL)
497                 pUndoStack=new Container(1024,16,16);
498             pUndoStack->Insert(pRedoStack->Remove((sal_uIntPtr)0),(sal_uIntPtr)0);
499             mbUndoEnabled = bWasUndoEnabled;
500         }
501     }
502     return bRet;
503 }
504 
505 FASTBOOL SdrModel::Repeat(SfxRepeatTarget& rView)
506 {
507     FASTBOOL bRet=sal_False;
508     if( mpImpl->mpUndoManager )
509     {
510         DBG_ERROR("svx::SdrModel::Redo(), method not supported with application undo manager!");
511     }
512     else
513     {
514         SfxUndoAction* pDo=(SfxUndoAction*)GetUndoAction(0);
515         if(pDo!=NULL)
516         {
517             if(pDo->CanRepeat(rView))
518             {
519                 pDo->Repeat(rView);
520                 bRet=sal_True;
521             }
522         }
523     }
524     return bRet;
525 }
526 
527 void SdrModel::ImpPostUndoAction(SdrUndoAction* pUndo)
528 {
529     DBG_ASSERT( mpImpl->mpUndoManager == 0, "svx::SdrModel::ImpPostUndoAction(), method not supported with application undo manager!" );
530     if( IsUndoEnabled() )
531     {
532         if (aUndoLink.IsSet())
533         {
534             aUndoLink.Call(pUndo);
535         }
536         else
537         {
538             if (pUndoStack==NULL)
539                 pUndoStack=new Container(1024,16,16);
540             pUndoStack->Insert(pUndo,(sal_uIntPtr)0);
541             while (pUndoStack->Count()>nMaxUndoCount)
542             {
543                 delete (SfxUndoAction*)pUndoStack->Remove(pUndoStack->Count()-1);
544             }
545             if (pRedoStack!=NULL)
546                 pRedoStack->Clear();
547         }
548     }
549     else
550     {
551         delete pUndo;
552     }
553 }
554 
555 void SdrModel::BegUndo()
556 {
557     if( mpImpl->mpUndoManager )
558     {
559         const String aEmpty;
560         mpImpl->mpUndoManager->EnterListAction(aEmpty,aEmpty);
561         nUndoLevel++;
562     }
563     else if( IsUndoEnabled() )
564     {
565         if(pAktUndoGroup==NULL)
566         {
567             pAktUndoGroup = new SdrUndoGroup(*this);
568             nUndoLevel=1;
569         }
570         else
571         {
572             nUndoLevel++;
573         }
574     }
575 }
576 
577 void SdrModel::BegUndo(const XubString& rComment)
578 {
579     if( mpImpl->mpUndoManager )
580     {
581         const String aEmpty;
582         mpImpl->mpUndoManager->EnterListAction( rComment, aEmpty );
583         nUndoLevel++;
584     }
585     else if( IsUndoEnabled() )
586     {
587         BegUndo();
588         if (nUndoLevel==1)
589         {
590             pAktUndoGroup->SetComment(rComment);
591         }
592     }
593 }
594 
595 void SdrModel::BegUndo(const XubString& rComment, const XubString& rObjDescr, SdrRepeatFunc eFunc)
596 {
597     if( mpImpl->mpUndoManager )
598     {
599         String aComment(rComment);
600         if( aComment.Len() && rObjDescr.Len() )
601         {
602             String aSearchString(RTL_CONSTASCII_USTRINGPARAM("%1"));
603             aComment.SearchAndReplace(aSearchString, rObjDescr);
604         }
605         const String aEmpty;
606         mpImpl->mpUndoManager->EnterListAction( aComment,aEmpty );
607         nUndoLevel++;
608     }
609     else if( IsUndoEnabled() )
610     {
611         BegUndo();
612         if (nUndoLevel==1)
613         {
614             pAktUndoGroup->SetComment(rComment);
615             pAktUndoGroup->SetObjDescription(rObjDescr);
616             pAktUndoGroup->SetRepeatFunction(eFunc);
617         }
618     }
619 }
620 
621 void SdrModel::BegUndo(SdrUndoGroup* pUndoGrp)
622 {
623     if( mpImpl->mpUndoManager )
624     {
625         DBG_ERROR("svx::SdrModel::BegUndo(), method not supported with application undo manager!" );
626         nUndoLevel++;
627     }
628     else if( IsUndoEnabled() )
629     {
630         if (pAktUndoGroup==NULL)
631         {
632             pAktUndoGroup=pUndoGrp;
633             nUndoLevel=1;
634         }
635         else
636         {
637             delete pUndoGrp;
638             nUndoLevel++;
639         }
640     }
641     else
642     {
643         delete pUndoGrp;
644     }
645 }
646 
647 void SdrModel::EndUndo()
648 {
649     DBG_ASSERT(nUndoLevel!=0,"SdrModel::EndUndo(): UndoLevel is already 0!");
650     if( mpImpl->mpUndoManager )
651     {
652         if( nUndoLevel )
653         {
654             nUndoLevel--;
655             mpImpl->mpUndoManager->LeaveListAction();
656         }
657     }
658     else
659     {
660         if(pAktUndoGroup!=NULL && IsUndoEnabled())
661         {
662             nUndoLevel--;
663             if(nUndoLevel==0)
664             {
665                 if(pAktUndoGroup->GetActionCount()!=0)
666                 {
667                     SdrUndoAction* pUndo=pAktUndoGroup;
668                     pAktUndoGroup=NULL;
669                     ImpPostUndoAction(pUndo);
670                 }
671                 else
672                 {
673                     // was empty
674                     delete pAktUndoGroup;
675                     pAktUndoGroup=NULL;
676                 }
677             }
678         }
679     }
680 }
681 
682 void SdrModel::SetUndoComment(const XubString& rComment)
683 {
684     DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is on level 0!");
685 
686     if( mpImpl->mpUndoManager )
687     {
688         DBG_ERROR("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
689     }
690     else if( IsUndoEnabled() )
691     {
692         if(nUndoLevel==1)
693         {
694             pAktUndoGroup->SetComment(rComment);
695         }
696     }
697 }
698 
699 void SdrModel::SetUndoComment(const XubString& rComment, const XubString& rObjDescr)
700 {
701     DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is 0!");
702     if( mpImpl->mpUndoManager )
703     {
704         DBG_ERROR("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
705     }
706     else
707     {
708         if (nUndoLevel==1)
709         {
710             pAktUndoGroup->SetComment(rComment);
711             pAktUndoGroup->SetObjDescription(rObjDescr);
712         }
713     }
714 }
715 
716 void SdrModel::AddUndo(SdrUndoAction* pUndo)
717 {
718     if( mpImpl->mpUndoManager )
719     {
720         mpImpl->mpUndoManager->AddUndoAction( pUndo );
721     }
722     else if( !IsUndoEnabled() )
723     {
724         delete pUndo;
725     }
726     else
727     {
728         if (pAktUndoGroup!=NULL)
729         {
730             pAktUndoGroup->AddAction(pUndo);
731         }
732         else
733         {
734             ImpPostUndoAction(pUndo);
735         }
736     }
737 }
738 
739 void SdrModel::EnableUndo( bool bEnable )
740 {
741     if( mpImpl->mpUndoManager )
742     {
743         mpImpl->mpUndoManager->EnableUndo( bEnable );
744     }
745     else
746     {
747         mbUndoEnabled = bEnable;
748     }
749 }
750 
751 bool SdrModel::IsUndoEnabled() const
752 {
753     if( mpImpl->mpUndoManager )
754     {
755         return mpImpl->mpUndoManager->IsUndoEnabled();
756     }
757     else
758     {
759         return mbUndoEnabled;
760     }
761 }
762 
763 ////////////////////////////////////////////////////////////////////////////////////////////////////
764 
765 void SdrModel::ImpCreateTables()
766 {
767     // der Writer hat seinen eigenen ColorTable
768     if (!bExtColorTable) pColorTable=new XColorTable(aTablePath,(XOutdevItemPool*)pItemPool);
769     pDashList    =new XDashList    (aTablePath,(XOutdevItemPool*)pItemPool);
770     pLineEndList =new XLineEndList (aTablePath,(XOutdevItemPool*)pItemPool);
771     pHatchList   =new XHatchList   (aTablePath,(XOutdevItemPool*)pItemPool);
772     pGradientList=new XGradientList(aTablePath,(XOutdevItemPool*)pItemPool);
773     pBitmapList  =new XBitmapList  (aTablePath,(XOutdevItemPool*)pItemPool);
774 }
775 
776 // #116168#
777 void SdrModel::ClearModel(sal_Bool bCalledFromDestructor)
778 {
779     if(bCalledFromDestructor)
780     {
781         mbInDestruction = true;
782     }
783 
784     sal_Int32 i;
785     // delete all drawing pages
786     sal_Int32 nAnz=GetPageCount();
787     for (i=nAnz-1; i>=0; i--)
788     {
789         DeletePage( (sal_uInt16)i );
790     }
791     maPages.Clear();
792     // #109538#
793     PageListChanged();
794 
795     // delete all Masterpages
796     nAnz=GetMasterPageCount();
797     for(i=nAnz-1; i>=0; i--)
798     {
799         DeleteMasterPage( (sal_uInt16)i );
800     }
801     maMaPag.Clear();
802     // #109538#
803     MasterPageListChanged();
804 
805     pLayerAdmin->ClearLayer();
806 }
807 
808 SdrModel* SdrModel::AllocModel() const
809 {
810     SdrModel* pModel=new SdrModel;
811     pModel->SetScaleUnit(eObjUnit,aObjUnit);
812     return pModel;
813 }
814 
815 SdrPage* SdrModel::AllocPage(FASTBOOL bMasterPage)
816 {
817     return new SdrPage(*this,bMasterPage);
818 }
819 
820 void SdrModel::SetTextDefaults() const
821 {
822     SetTextDefaults( pItemPool, nDefTextHgt );
823 }
824 
825 void ImpGetDefaultFontsLanguage( SvxFontItem& rLatin, SvxFontItem& rAsian, SvxFontItem& rComplex)
826 {
827     const sal_uInt16 nItemCnt = 3;
828     static struct {
829         sal_uInt16 nFntType, nLanguage;
830     }  aOutTypeArr[ nItemCnt ] = {
831         {  DEFAULTFONT_LATIN_TEXT, LANGUAGE_ENGLISH_US },
832         {  DEFAULTFONT_CJK_TEXT, LANGUAGE_ENGLISH_US },
833         {  DEFAULTFONT_CTL_TEXT, LANGUAGE_ARABIC_SAUDI_ARABIA }
834     };
835     SvxFontItem* aItemArr[ nItemCnt ] = { &rLatin, &rAsian, &rComplex };
836 
837     for( sal_uInt16 n = 0; n < nItemCnt; ++n )
838     {
839         Font aFnt( OutputDevice::GetDefaultFont(
840             aOutTypeArr[ n ].nFntType, aOutTypeArr[ n ].nLanguage,
841             DEFAULTFONT_FLAGS_ONLYONE, 0 ));
842         SvxFontItem* pI = aItemArr[ n ];
843         pI->SetFamily( aFnt.GetFamily());
844         pI->SetFamilyName( aFnt.GetName());
845         pI->SetStyleName( String() );
846         pI->SetPitch( aFnt.GetPitch());
847         pI->SetCharSet( aFnt.GetCharSet() );
848     }
849 }
850 
851 void SdrModel::SetTextDefaults( SfxItemPool* pItemPool, sal_uIntPtr nDefTextHgt )
852 {
853     // #95114# set application-language specific dynamic pool language defaults
854     SvxFontItem aSvxFontItem( EE_CHAR_FONTINFO) ;
855     SvxFontItem aSvxFontItemCJK(EE_CHAR_FONTINFO_CJK);
856     SvxFontItem aSvxFontItemCTL(EE_CHAR_FONTINFO_CTL);
857     sal_uInt16 nLanguage(Application::GetSettings().GetLanguage());
858 
859     // get DEFAULTFONT_LATIN_TEXT and set at pool as dynamic default
860     Font aFont(OutputDevice::GetDefaultFont(DEFAULTFONT_LATIN_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
861     aSvxFontItem.SetFamily(aFont.GetFamily());
862     aSvxFontItem.SetFamilyName(aFont.GetName());
863     aSvxFontItem.SetStyleName(String());
864     aSvxFontItem.SetPitch( aFont.GetPitch());
865     aSvxFontItem.SetCharSet( aFont.GetCharSet() );
866     pItemPool->SetPoolDefaultItem(aSvxFontItem);
867 
868     // get DEFAULTFONT_CJK_TEXT and set at pool as dynamic default
869     Font aFontCJK(OutputDevice::GetDefaultFont(DEFAULTFONT_CJK_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
870     aSvxFontItemCJK.SetFamily( aFontCJK.GetFamily());
871     aSvxFontItemCJK.SetFamilyName(aFontCJK.GetName());
872     aSvxFontItemCJK.SetStyleName(String());
873     aSvxFontItemCJK.SetPitch( aFontCJK.GetPitch());
874     aSvxFontItemCJK.SetCharSet( aFontCJK.GetCharSet());
875     pItemPool->SetPoolDefaultItem(aSvxFontItemCJK);
876 
877     // get DEFAULTFONT_CTL_TEXT and set at pool as dynamic default
878     Font aFontCTL(OutputDevice::GetDefaultFont(DEFAULTFONT_CTL_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
879     aSvxFontItemCTL.SetFamily(aFontCTL.GetFamily());
880     aSvxFontItemCTL.SetFamilyName(aFontCTL.GetName());
881     aSvxFontItemCTL.SetStyleName(String());
882     aSvxFontItemCTL.SetPitch( aFontCTL.GetPitch() );
883     aSvxFontItemCTL.SetCharSet( aFontCTL.GetCharSet());
884     pItemPool->SetPoolDefaultItem(aSvxFontItemCTL);
885 
886     // set dynamic FontHeight defaults
887     pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT ) );
888     pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CJK ) );
889     pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CTL ) );
890 
891     // set FontColor defaults
892     pItemPool->SetPoolDefaultItem( SvxColorItem(SdrEngineDefaults::GetFontColor(), EE_CHAR_COLOR) );
893 }
894 
895 SdrOutliner& SdrModel::GetDrawOutliner(const SdrTextObj* pObj) const
896 {
897     pDrawOutliner->SetTextObj(pObj);
898     return *pDrawOutliner;
899 }
900 
901 boost::shared_ptr< SdrOutliner > SdrModel::CreateDrawOutliner(const SdrTextObj* pObj)
902 {
903     boost::shared_ptr< SdrOutliner > xDrawOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this ) );
904     ImpSetOutlinerDefaults(xDrawOutliner.get(), sal_True);
905     xDrawOutliner->SetTextObj(pObj);
906     return xDrawOutliner;
907 }
908 
909 const SdrTextObj* SdrModel::GetFormattingTextObj() const
910 {
911     if (pDrawOutliner!=NULL) {
912         return pDrawOutliner->GetTextObj();
913     }
914     return NULL;
915 }
916 
917 void SdrModel::ImpSetOutlinerDefaults( SdrOutliner* pOutliner, sal_Bool bInit )
918 {
919     /**************************************************************************
920     * Initialisierung der Outliner fuer Textausgabe und HitTest
921     **************************************************************************/
922     if( bInit )
923     {
924         pOutliner->EraseVirtualDevice();
925         pOutliner->SetUpdateMode(sal_False);
926         pOutliner->SetEditTextObjectPool(pItemPool);
927         pOutliner->SetDefTab(nDefaultTabulator);
928     }
929 
930     pOutliner->SetRefDevice(GetRefDevice());
931     pOutliner->SetForbiddenCharsTable(GetForbiddenCharsTable());
932     pOutliner->SetAsianCompressionMode( mnCharCompressType );
933     pOutliner->SetKernAsianPunctuation( IsKernAsianPunctuation() );
934     pOutliner->SetAddExtLeading( IsAddExtLeading() );
935 
936     if ( !GetRefDevice() )
937     {
938         MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
939         pOutliner->SetRefMapMode(aMapMode);
940     }
941 }
942 
943 void SdrModel::SetRefDevice(OutputDevice* pDev)
944 {
945     pRefOutDev=pDev;
946     ImpSetOutlinerDefaults( pDrawOutliner );
947     ImpSetOutlinerDefaults( pHitTestOutliner );
948     RefDeviceChanged();
949 }
950 
951 void SdrModel::ImpReformatAllTextObjects()
952 {
953     if( isLocked() )
954         return;
955 
956     sal_uInt16 nAnz=GetMasterPageCount();
957     sal_uInt16 nNum;
958     for (nNum=0; nNum<nAnz; nNum++) {
959         GetMasterPage(nNum)->ReformatAllTextObjects();
960     }
961     nAnz=GetPageCount();
962     for (nNum=0; nNum<nAnz; nNum++) {
963         GetPage(nNum)->ReformatAllTextObjects();
964     }
965 }
966 
967 /** #103122#
968     steps over all available pages and sends notify messages to
969     all edge objects that are connected to other objects so that
970     they may reposition itselfs
971 */
972 void SdrModel::ImpReformatAllEdgeObjects()
973 {
974     if( isLocked() )
975         return;
976 
977     sal_uInt16 nAnz=GetMasterPageCount();
978     sal_uInt16 nNum;
979     for (nNum=0; nNum<nAnz; nNum++)
980     {
981         GetMasterPage(nNum)->ReformatAllEdgeObjects();
982     }
983     nAnz=GetPageCount();
984     for (nNum=0; nNum<nAnz; nNum++)
985     {
986         GetPage(nNum)->ReformatAllEdgeObjects();
987     }
988 }
989 
990 SvStream* SdrModel::GetDocumentStream(SdrDocumentStreamInfo& /*rStreamInfo*/) const
991 {
992     return NULL;
993 }
994 
995 // Die Vorlagenattribute der Zeichenobjekte in harte Attribute verwandeln.
996 void SdrModel::BurnInStyleSheetAttributes()
997 {
998     sal_uInt16 nAnz=GetMasterPageCount();
999     sal_uInt16 nNum;
1000     for (nNum=0; nNum<nAnz; nNum++) {
1001         GetMasterPage(nNum)->BurnInStyleSheetAttributes();
1002     }
1003     nAnz=GetPageCount();
1004     for (nNum=0; nNum<nAnz; nNum++) {
1005         GetPage(nNum)->BurnInStyleSheetAttributes();
1006     }
1007 }
1008 
1009 void SdrModel::RefDeviceChanged()
1010 {
1011     Broadcast(SdrHint(HINT_REFDEVICECHG));
1012     ImpReformatAllTextObjects();
1013 }
1014 
1015 void SdrModel::SetDefaultFontHeight(sal_uIntPtr nVal)
1016 {
1017     if (nVal!=nDefTextHgt) {
1018         nDefTextHgt=nVal;
1019         Broadcast(SdrHint(HINT_DEFFONTHGTCHG));
1020         ImpReformatAllTextObjects();
1021     }
1022 }
1023 
1024 void SdrModel::SetDefaultTabulator(sal_uInt16 nVal)
1025 {
1026     if (nDefaultTabulator!=nVal) {
1027         nDefaultTabulator=nVal;
1028         Outliner& rOutliner=GetDrawOutliner();
1029         rOutliner.SetDefTab(nVal);
1030         Broadcast(SdrHint(HINT_DEFAULTTABCHG));
1031         ImpReformatAllTextObjects();
1032     }
1033 }
1034 
1035 void SdrModel::ImpSetUIUnit()
1036 {
1037     if(0 == aUIScale.GetNumerator() || 0 == aUIScale.GetDenominator())
1038     {
1039         aUIScale = Fraction(1,1);
1040     }
1041 
1042     // set start values
1043     nUIUnitKomma = 0;
1044     sal_Int64 nMul(1);
1045     sal_Int64 nDiv(1);
1046 
1047     // normalize on meters resp. inch
1048     switch (eObjUnit)
1049     {
1050         case MAP_100TH_MM   : nUIUnitKomma+=5; break;
1051         case MAP_10TH_MM    : nUIUnitKomma+=4; break;
1052         case MAP_MM         : nUIUnitKomma+=3; break;
1053         case MAP_CM         : nUIUnitKomma+=2; break;
1054         case MAP_1000TH_INCH: nUIUnitKomma+=3; break;
1055         case MAP_100TH_INCH : nUIUnitKomma+=2; break;
1056         case MAP_10TH_INCH  : nUIUnitKomma+=1; break;
1057         case MAP_INCH       : nUIUnitKomma+=0; break;
1058         case MAP_POINT      : nDiv=72;     break;          // 1Pt   = 1/72"
1059         case MAP_TWIP       : nDiv=144; nUIUnitKomma++; break; // 1Twip = 1/1440"
1060         case MAP_PIXEL      : break;
1061         case MAP_SYSFONT    : break;
1062         case MAP_APPFONT    : break;
1063         case MAP_RELATIVE   : break;
1064         default: break;
1065     } // switch
1066 
1067     // 1 mile    =  8 furlong = 63.360" = 1.609.344,0mm
1068     // 1 furlong = 10 chains  =  7.920" =   201.168,0mm
1069     // 1 chain   =  4 poles   =    792" =    20.116,8mm
1070     // 1 pole    =  5 1/2 yd  =    198" =     5.029,2mm
1071     // 1 yd      =  3 ft      =     36" =       914,4mm
1072     // 1 ft      = 12 "       =      1" =       304,8mm
1073     switch (eUIUnit)
1074     {
1075         case FUNIT_NONE   : break;
1076         // Metrisch
1077         case FUNIT_100TH_MM: nUIUnitKomma-=5; break;
1078         case FUNIT_MM     : nUIUnitKomma-=3; break;
1079         case FUNIT_CM     : nUIUnitKomma-=2; break;
1080         case FUNIT_M      : nUIUnitKomma+=0; break;
1081         case FUNIT_KM     : nUIUnitKomma+=3; break;
1082         // Inch
1083         case FUNIT_TWIP   : nMul=144; nUIUnitKomma--;  break;  // 1Twip = 1/1440"
1084         case FUNIT_POINT  : nMul=72;     break;            // 1Pt   = 1/72"
1085         case FUNIT_PICA   : nMul=6;      break;            // 1Pica = 1/6"  ?
1086         case FUNIT_INCH   : break;                         // 1"    = 1"
1087         case FUNIT_FOOT   : nDiv*=12;    break;            // 1Ft   = 12"
1088         case FUNIT_MILE   : nDiv*=6336; nUIUnitKomma++; break; // 1mile = 63360"
1089         // sonstiges
1090         case FUNIT_CUSTOM : break;
1091         case FUNIT_PERCENT: nUIUnitKomma+=2; break;
1092     } // switch
1093 
1094     // check if mapping is from metric to inch and adapt
1095     const bool bMapInch(IsInch(eObjUnit));
1096     const bool bUIMetr(IsMetric(eUIUnit));
1097 
1098     if (bMapInch && bUIMetr)
1099     {
1100         nUIUnitKomma += 4;
1101         nMul *= 254;
1102     }
1103 
1104     // check if mapping is from inch to metric and adapt
1105     const bool bMapMetr(IsMetric(eObjUnit));
1106     const bool bUIInch(IsInch(eUIUnit));
1107 
1108     if (bMapMetr && bUIInch)
1109     {
1110         nUIUnitKomma -= 4;
1111         nDiv *= 254;
1112     }
1113 
1114     // use temporary fraction for reduction (fallback to 32bit here),
1115     // may need to be changed in the future, too
1116     if(1 != nMul || 1 != nDiv)
1117     {
1118         const Fraction aTemp(static_cast< long >(nMul), static_cast< long >(nDiv));
1119         nMul = aTemp.GetNumerator();
1120         nDiv = aTemp.GetDenominator();
1121     }
1122 
1123     // #i89872# take Unit of Measurement into account
1124     if(1 != aUIScale.GetDenominator() || 1 != aUIScale.GetNumerator())
1125     {
1126         // divide by UIScale
1127         nMul *= aUIScale.GetDenominator();
1128         nDiv *= aUIScale.GetNumerator();
1129     }
1130 
1131     // shorten trailing zeroes for dividend
1132     while(0 == (nMul % 10))
1133     {
1134         nUIUnitKomma--;
1135         nMul /= 10;
1136     }
1137 
1138     // shorten trailing zeroes for divisor
1139     while(0 == (nDiv % 10))
1140     {
1141         nUIUnitKomma++;
1142         nDiv /= 10;
1143     }
1144 
1145     // end preparations, set member values
1146     aUIUnitFact = Fraction(sal_Int32(nMul), sal_Int32(nDiv));
1147     bUIOnlyKomma = (nMul == nDiv);
1148     TakeUnitStr(eUIUnit, aUIUnitStr);
1149 }
1150 
1151 void SdrModel::SetScaleUnit(MapUnit eMap, const Fraction& rFrac)
1152 {
1153     if (eObjUnit!=eMap || aObjUnit!=rFrac) {
1154         eObjUnit=eMap;
1155         aObjUnit=rFrac;
1156         pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
1157         ImpSetUIUnit();
1158         ImpSetOutlinerDefaults( pDrawOutliner );
1159         ImpSetOutlinerDefaults( pHitTestOutliner );
1160         ImpReformatAllTextObjects(); // #40424#
1161     }
1162 }
1163 
1164 void SdrModel::SetScaleUnit(MapUnit eMap)
1165 {
1166     if (eObjUnit!=eMap) {
1167         eObjUnit=eMap;
1168         pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
1169         ImpSetUIUnit();
1170         ImpSetOutlinerDefaults( pDrawOutliner );
1171         ImpSetOutlinerDefaults( pHitTestOutliner );
1172         ImpReformatAllTextObjects(); // #40424#
1173     }
1174 }
1175 
1176 void SdrModel::SetScaleFraction(const Fraction& rFrac)
1177 {
1178     if (aObjUnit!=rFrac) {
1179         aObjUnit=rFrac;
1180         ImpSetUIUnit();
1181         ImpSetOutlinerDefaults( pDrawOutliner );
1182         ImpSetOutlinerDefaults( pHitTestOutliner );
1183         ImpReformatAllTextObjects(); // #40424#
1184     }
1185 }
1186 
1187 void SdrModel::SetUIUnit(FieldUnit eUnit)
1188 {
1189     if (eUIUnit!=eUnit) {
1190         eUIUnit=eUnit;
1191         ImpSetUIUnit();
1192         ImpReformatAllTextObjects(); // #40424#
1193     }
1194 }
1195 
1196 void SdrModel::SetUIScale(const Fraction& rScale)
1197 {
1198     if (aUIScale!=rScale) {
1199         aUIScale=rScale;
1200         ImpSetUIUnit();
1201         ImpReformatAllTextObjects(); // #40424#
1202     }
1203 }
1204 
1205 void SdrModel::SetUIUnit(FieldUnit eUnit, const Fraction& rScale)
1206 {
1207     if (eUIUnit!=eUnit || aUIScale!=rScale) {
1208         eUIUnit=eUnit;
1209         aUIScale=rScale;
1210         ImpSetUIUnit();
1211         ImpReformatAllTextObjects(); // #40424#
1212     }
1213 }
1214 
1215 void SdrModel::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
1216 {
1217     switch(eUnit)
1218     {
1219         default:
1220         case FUNIT_NONE   :
1221         case FUNIT_CUSTOM :
1222         {
1223             rStr = String();
1224             break;
1225         }
1226         case FUNIT_100TH_MM:
1227         {
1228             sal_Char aText[] = "/100mm";
1229             rStr = UniString(aText, sizeof(aText-1));
1230             break;
1231         }
1232         case FUNIT_MM     :
1233         {
1234             sal_Char aText[] = "mm";
1235             rStr = UniString(aText, sizeof(aText-1));
1236             break;
1237         }
1238         case FUNIT_CM     :
1239         {
1240             sal_Char aText[] = "cm";
1241             rStr = UniString(aText, sizeof(aText-1));
1242             break;
1243         }
1244         case FUNIT_M      :
1245         {
1246             rStr = String();
1247             rStr += sal_Unicode('m');
1248             break;
1249         }
1250         case FUNIT_KM     :
1251         {
1252             sal_Char aText[] = "km";
1253             rStr = UniString(aText, sizeof(aText-1));
1254             break;
1255         }
1256         case FUNIT_TWIP   :
1257         {
1258             sal_Char aText[] = "twip";
1259             rStr = UniString(aText, sizeof(aText-1));
1260             break;
1261         }
1262         case FUNIT_POINT  :
1263         {
1264             sal_Char aText[] = "pt";
1265             rStr = UniString(aText, sizeof(aText-1));
1266             break;
1267         }
1268         case FUNIT_PICA   :
1269         {
1270             sal_Char aText[] = "pica";
1271             rStr = UniString(aText, sizeof(aText-1));
1272             break;
1273         }
1274         case FUNIT_INCH   :
1275         {
1276             rStr = String();
1277             rStr += sal_Unicode('"');
1278             break;
1279         }
1280         case FUNIT_FOOT   :
1281         {
1282             sal_Char aText[] = "ft";
1283             rStr = UniString(aText, sizeof(aText-1));
1284             break;
1285         }
1286         case FUNIT_MILE   :
1287         {
1288             sal_Char aText[] = "mile(s)";
1289             rStr = UniString(aText, sizeof(aText-1));
1290             break;
1291         }
1292         case FUNIT_PERCENT:
1293         {
1294             rStr = String();
1295             rStr += sal_Unicode('%');
1296             break;
1297         }
1298     }
1299 }
1300 
1301 void SdrModel::TakeMetricStr(long nVal, XubString& rStr, FASTBOOL bNoUnitChars, sal_Int32 nNumDigits) const
1302 {
1303     // #i22167#
1304     // change to double precision usage to not loose decimal places after comma
1305     const bool bNegative(nVal < 0L);
1306     SvtSysLocale aSysLoc;
1307     const LocaleDataWrapper& rLoc(aSysLoc.GetLocaleData());
1308     double fLocalValue(double(nVal) * double(aUIUnitFact));
1309 
1310     if(bNegative)
1311     {
1312         fLocalValue = -fLocalValue;
1313     }
1314 
1315     if( -1 == nNumDigits )
1316     {
1317         nNumDigits = rLoc.getNumDigits();
1318     }
1319 
1320     sal_Int32 nKomma(nUIUnitKomma);
1321 
1322     if(nKomma > nNumDigits)
1323     {
1324         const sal_Int32 nDiff(nKomma - nNumDigits);
1325         const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
1326 
1327         fLocalValue /= fFactor;
1328         nKomma = nNumDigits;
1329     }
1330     else if(nKomma < nNumDigits)
1331     {
1332         const sal_Int32 nDiff(nNumDigits - nKomma);
1333         const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
1334 
1335         fLocalValue *= fFactor;
1336         nKomma = nNumDigits;
1337     }
1338 
1339     rStr = UniString::CreateFromInt32(static_cast<sal_Int32>(fLocalValue + 0.5));
1340 
1341     if(nKomma < 0)
1342     {
1343         // Negatives Komma bedeutet: Nullen dran
1344         sal_Int32 nAnz(-nKomma);
1345 
1346         for(sal_Int32 i=0; i<nAnz; i++)
1347             rStr += sal_Unicode('0');
1348 
1349         nKomma = 0;
1350     }
1351 
1352     // #83257# the second condition needs to be <= since inside this loop
1353     // also the leading zero is inserted.
1354     if(nKomma > 0 && rStr.Len() <= nKomma)
1355     {
1356         // Fuer Komma evtl. vorne Nullen dran
1357         sal_Int32 nAnz(nKomma - rStr.Len());
1358 
1359         if(nAnz >= 0 && rLoc.isNumLeadingZero())
1360             nAnz++;
1361 
1362         for(sal_Int32 i=0; i<nAnz; i++)
1363             rStr.Insert(sal_Unicode('0'), 0);
1364     }
1365 
1366     sal_Unicode cDec( rLoc.getNumDecimalSep().GetChar(0) );
1367 
1368     // KommaChar einfuegen
1369     sal_Int32 nVorKomma(rStr.Len() - nKomma);
1370 
1371     if(nKomma > 0)
1372         rStr.Insert(cDec, (xub_StrLen) nVorKomma);
1373 
1374     if(!rLoc.isNumTrailingZeros())
1375     {
1376         while(rStr.Len() && rStr.GetChar(rStr.Len() - 1) == sal_Unicode('0'))
1377             rStr.Erase(rStr.Len() - 1);
1378 
1379         if(rStr.Len() && rStr.GetChar(rStr.Len() - 1) == cDec)
1380             rStr.Erase(rStr.Len() - 1);
1381     }
1382 
1383     // ggf. Trennpunkte bei jedem Tausender einfuegen
1384     if( nVorKomma > 3 )
1385     {
1386         String aThoSep( rLoc.getNumThousandSep() );
1387         if ( aThoSep.Len() > 0 )
1388         {
1389             sal_Unicode cTho( aThoSep.GetChar(0) );
1390             sal_Int32 i(nVorKomma - 3);
1391 
1392             while(i > 0) // #78311#
1393             {
1394                 rStr.Insert(cTho, (xub_StrLen)i);
1395                 i -= 3;
1396             }
1397         }
1398     }
1399 
1400     if(!rStr.Len())
1401     {
1402         rStr = String();
1403         rStr += sal_Unicode('0');
1404     }
1405 
1406     if(bNegative)
1407     {
1408         rStr.Insert(sal_Unicode('-'), 0);
1409     }
1410 
1411     if(!bNoUnitChars)
1412         rStr += aUIUnitStr;
1413 }
1414 
1415 void SdrModel::TakeWinkStr(long nWink, XubString& rStr, FASTBOOL bNoDegChar) const
1416 {
1417     sal_Bool bNeg(nWink < 0);
1418 
1419     if(bNeg)
1420         nWink = -nWink;
1421 
1422     rStr = UniString::CreateFromInt32(nWink);
1423 
1424     SvtSysLocale aSysLoc;
1425     const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
1426     xub_StrLen nAnz(2);
1427 
1428     if(rLoc.isNumLeadingZero())
1429         nAnz++;
1430 
1431     while(rStr.Len() < nAnz)
1432         rStr.Insert(sal_Unicode('0'), 0);
1433 
1434     rStr.Insert(rLoc.getNumDecimalSep().GetChar(0), rStr.Len() - 2);
1435 
1436     if(bNeg)
1437         rStr.Insert(sal_Unicode('-'), 0);
1438 
1439     if(!bNoDegChar)
1440         rStr += DEGREE_CHAR;
1441 }
1442 
1443 void SdrModel::TakePercentStr(const Fraction& rVal, XubString& rStr, FASTBOOL bNoPercentChar) const
1444 {
1445     sal_Int32 nMul(rVal.GetNumerator());
1446     sal_Int32 nDiv(rVal.GetDenominator());
1447     sal_Bool bNeg(nMul < 0);
1448 
1449     if(nDiv < 0)
1450         bNeg = !bNeg;
1451 
1452     if(nMul < 0)
1453         nMul = -nMul;
1454 
1455     if(nDiv < 0)
1456         nDiv = -nDiv;
1457 
1458     nMul *= 100;
1459     nMul += nDiv/2;
1460     nMul /= nDiv;
1461 
1462     rStr = UniString::CreateFromInt32(nMul);
1463 
1464     if(bNeg)
1465         rStr.Insert(sal_Unicode('-'), 0);
1466 
1467     if(!bNoPercentChar)
1468         rStr += sal_Unicode('%');
1469 }
1470 
1471 void SdrModel::SetChanged(sal_Bool bFlg)
1472 {
1473     mbChanged = bFlg;
1474 }
1475 
1476 void SdrModel::RecalcPageNums(FASTBOOL bMaster)
1477 {
1478     Container& rPL=*(bMaster ? &maMaPag : &maPages);
1479     sal_uInt16 nAnz=sal_uInt16(rPL.Count());
1480     sal_uInt16 i;
1481     for (i=0; i<nAnz; i++) {
1482         SdrPage* pPg=(SdrPage*)(rPL.GetObject(i));
1483         pPg->SetPageNum(i);
1484     }
1485     if (bMaster) bMPgNumsDirty=sal_False;
1486     else bPagNumsDirty=sal_False;
1487 }
1488 
1489 void SdrModel::InsertPage(SdrPage* pPage, sal_uInt16 nPos)
1490 {
1491     sal_uInt16 nAnz=GetPageCount();
1492     if (nPos>nAnz) nPos=nAnz;
1493     maPages.Insert(pPage,nPos);
1494     // #109538#
1495     PageListChanged();
1496     pPage->SetInserted(sal_True);
1497     pPage->SetPageNum(nPos);
1498     pPage->SetModel(this);
1499     if (nPos<nAnz) bPagNumsDirty=sal_True;
1500     SetChanged();
1501     SdrHint aHint(HINT_PAGEORDERCHG);
1502     aHint.SetPage(pPage);
1503     Broadcast(aHint);
1504 }
1505 
1506 void SdrModel::DeletePage(sal_uInt16 nPgNum)
1507 {
1508     SdrPage* pPg=RemovePage(nPgNum);
1509     delete pPg;
1510 }
1511 
1512 SdrPage* SdrModel::RemovePage(sal_uInt16 nPgNum)
1513 {
1514     SdrPage* pPg=(SdrPage*)maPages.Remove(nPgNum);
1515     // #109538#
1516     PageListChanged();
1517     if (pPg!=NULL) {
1518         pPg->SetInserted(sal_False);
1519     }
1520     bPagNumsDirty=sal_True;
1521     SetChanged();
1522     SdrHint aHint(HINT_PAGEORDERCHG);
1523     aHint.SetPage(pPg);
1524     Broadcast(aHint);
1525     return pPg;
1526 }
1527 
1528 void SdrModel::MovePage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
1529 {
1530     SdrPage* pPg=(SdrPage*)maPages.Remove(nPgNum);
1531     // #109538#
1532     PageListChanged();
1533     if (pPg!=NULL) {
1534         pPg->SetInserted(sal_False);
1535         InsertPage(pPg,nNewPos);
1536     }
1537 }
1538 
1539 void SdrModel::InsertMasterPage(SdrPage* pPage, sal_uInt16 nPos)
1540 {
1541     sal_uInt16 nAnz=GetMasterPageCount();
1542     if (nPos>nAnz) nPos=nAnz;
1543     maMaPag.Insert(pPage,nPos);
1544     // #109538#
1545     MasterPageListChanged();
1546     pPage->SetInserted(sal_True);
1547     pPage->SetPageNum(nPos);
1548     pPage->SetModel(this);
1549     if (nPos<nAnz) {
1550         bMPgNumsDirty=sal_True;
1551     }
1552     SetChanged();
1553     SdrHint aHint(HINT_PAGEORDERCHG);
1554     aHint.SetPage(pPage);
1555     Broadcast(aHint);
1556 }
1557 
1558 void SdrModel::DeleteMasterPage(sal_uInt16 nPgNum)
1559 {
1560     SdrPage* pPg=RemoveMasterPage(nPgNum);
1561     if (pPg!=NULL) delete pPg;
1562 }
1563 
1564 SdrPage* SdrModel::RemoveMasterPage(sal_uInt16 nPgNum)
1565 {
1566     SdrPage* pRetPg=(SdrPage*)maMaPag.Remove(nPgNum);
1567     // #109538#
1568     MasterPageListChanged();
1569 
1570     if(pRetPg)
1571     {
1572         // Nun die Verweise der normalen Zeichenseiten auf die entfernte MasterPage loeschen
1573         sal_uInt16 nPageAnz(GetPageCount());
1574 
1575         for(sal_uInt16 np(0); np < nPageAnz; np++)
1576         {
1577             GetPage(np)->TRG_ImpMasterPageRemoved(*pRetPg);
1578         }
1579 
1580         pRetPg->SetInserted(sal_False);
1581     }
1582 
1583     bMPgNumsDirty=sal_True;
1584     SetChanged();
1585     SdrHint aHint(HINT_PAGEORDERCHG);
1586     aHint.SetPage(pRetPg);
1587     Broadcast(aHint);
1588     return pRetPg;
1589 }
1590 
1591 void SdrModel::MoveMasterPage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
1592 {
1593     SdrPage* pPg=(SdrPage*)maMaPag.Remove(nPgNum);
1594     // #109538#
1595     MasterPageListChanged();
1596     if (pPg!=NULL) {
1597         pPg->SetInserted(sal_False);
1598         maMaPag.Insert(pPg,nNewPos);
1599         // #109538#
1600         MasterPageListChanged();
1601     }
1602     bMPgNumsDirty=sal_True;
1603     SetChanged();
1604     SdrHint aHint(HINT_PAGEORDERCHG);
1605     aHint.SetPage(pPg);
1606     Broadcast(aHint);
1607 }
1608 
1609 ////////////////////////////////////////////////////////////////////////////////////////////////////
1610 
1611 FASTBOOL SdrModel::CheckConsistence() const
1612 {
1613     FASTBOOL bRet=sal_True;
1614 #ifdef DBG_UTIL
1615     DBG_CHKTHIS(SdrModel,NULL);
1616 #endif
1617     return bRet;
1618 }
1619 
1620 ////////////////////////////////////////////////////////////////////////////////////////////////////
1621 
1622 // #48289#
1623 void SdrModel::CopyPages(sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1624                          sal_uInt16 nDestPos,
1625                          FASTBOOL bUndo, FASTBOOL bMoveNoCopy)
1626 {
1627     if( bUndo && !IsUndoEnabled() )
1628         bUndo = false;
1629 
1630     if( bUndo )
1631         BegUndo(ImpGetResStr(STR_UndoMergeModel));
1632 
1633     sal_uInt16 nPageAnz=GetPageCount();
1634     sal_uInt16 nMaxPage=nPageAnz;
1635 
1636     if (nMaxPage!=0)
1637         nMaxPage--;
1638     if (nFirstPageNum>nMaxPage)
1639         nFirstPageNum=nMaxPage;
1640     if (nLastPageNum>nMaxPage)
1641         nLastPageNum =nMaxPage;
1642     FASTBOOL bReverse=nLastPageNum<nFirstPageNum;
1643     if (nDestPos>nPageAnz)
1644         nDestPos=nPageAnz;
1645 
1646     // Zunaechst die Zeiger der betroffenen Seiten in einem Array sichern
1647     sal_uInt16 nPageNum=nFirstPageNum;
1648     sal_uInt16 nCopyAnz=((!bReverse)?(nLastPageNum-nFirstPageNum):(nFirstPageNum-nLastPageNum))+1;
1649     SdrPage** pPagePtrs=new SdrPage*[nCopyAnz];
1650     sal_uInt16 nCopyNum;
1651     for(nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
1652     {
1653         pPagePtrs[nCopyNum]=GetPage(nPageNum);
1654         if (bReverse)
1655             nPageNum--;
1656         else
1657             nPageNum++;
1658     }
1659 
1660     // Jetzt die Seiten kopieren
1661     sal_uInt16 nDestNum=nDestPos;
1662     for (nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
1663     {
1664         SdrPage* pPg=pPagePtrs[nCopyNum];
1665         sal_uInt16 nPageNum2=pPg->GetPageNum();
1666         if (!bMoveNoCopy)
1667         {
1668             const SdrPage* pPg1=GetPage(nPageNum2);
1669             pPg=pPg1->Clone();
1670             InsertPage(pPg,nDestNum);
1671             if (bUndo)
1672                 AddUndo(GetSdrUndoFactory().CreateUndoCopyPage(*pPg));
1673             nDestNum++;
1674         }
1675         else
1676         {
1677             // Move ist nicht getestet!
1678             if (nDestNum>nPageNum2)
1679                 nDestNum--;
1680 
1681             if(bUndo)
1682                 AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*GetPage(nPageNum2),nPageNum2,nDestNum));
1683 
1684             pPg=RemovePage(nPageNum2);
1685             InsertPage(pPg,nDestNum);
1686             nDestNum++;
1687         }
1688 
1689         if(bReverse)
1690             nPageNum2--;
1691         else
1692             nPageNum2++;
1693     }
1694 
1695     delete[] pPagePtrs;
1696     if(bUndo)
1697         EndUndo();
1698 }
1699 
1700 void SdrModel::Merge(SdrModel& rSourceModel,
1701                      sal_uInt16 nFirstPageNum, sal_uInt16 nLastPageNum,
1702                      sal_uInt16 nDestPos,
1703                      FASTBOOL bMergeMasterPages, FASTBOOL bAllMasterPages,
1704                      FASTBOOL bUndo, FASTBOOL bTreadSourceAsConst)
1705 {
1706     if (&rSourceModel==this)
1707     { // #48289#
1708         CopyPages(nFirstPageNum,nLastPageNum,nDestPos,bUndo,!bTreadSourceAsConst);
1709         return;
1710     }
1711 
1712     if( bUndo && !IsUndoEnabled() )
1713         bUndo = false;
1714 
1715     if (bUndo)
1716         BegUndo(ImpGetResStr(STR_UndoMergeModel));
1717 
1718     sal_uInt16 nSrcPageAnz=rSourceModel.GetPageCount();
1719     sal_uInt16 nSrcMasterPageAnz=rSourceModel.GetMasterPageCount();
1720     sal_uInt16 nDstMasterPageAnz=GetMasterPageCount();
1721     FASTBOOL bInsPages=(nFirstPageNum<nSrcPageAnz || nLastPageNum<nSrcPageAnz);
1722     sal_uInt16 nMaxSrcPage=nSrcPageAnz; if (nMaxSrcPage!=0) nMaxSrcPage--;
1723     if (nFirstPageNum>nMaxSrcPage) nFirstPageNum=nMaxSrcPage;
1724     if (nLastPageNum>nMaxSrcPage)  nLastPageNum =nMaxSrcPage;
1725     FASTBOOL bReverse=nLastPageNum<nFirstPageNum;
1726 
1727     sal_uInt16*   pMasterMap=NULL;
1728     int* pMasterNeed=NULL;
1729     sal_uInt16    nMasterNeed=0;
1730     if (bMergeMasterPages && nSrcMasterPageAnz!=0) {
1731         // Feststellen, welche MasterPages aus rSrcModel benoetigt werden
1732         pMasterMap=new sal_uInt16[nSrcMasterPageAnz];
1733         pMasterNeed=new int[nSrcMasterPageAnz];
1734         memset(pMasterMap,0xFF,nSrcMasterPageAnz*sizeof(sal_uInt16));
1735         if (bAllMasterPages) {
1736             memset(pMasterNeed,sal_True,nSrcMasterPageAnz*sizeof(FASTBOOL));
1737         } else {
1738             memset(pMasterNeed,sal_False,nSrcMasterPageAnz*sizeof(FASTBOOL));
1739             sal_uInt16 nAnf= bReverse ? nLastPageNum : nFirstPageNum;
1740             sal_uInt16 nEnd= bReverse ? nFirstPageNum : nLastPageNum;
1741             for (sal_uInt16 i=nAnf; i<=nEnd; i++) {
1742                 const SdrPage* pPg=rSourceModel.GetPage(i);
1743                 if(pPg->TRG_HasMasterPage())
1744                 {
1745                     SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
1746                     sal_uInt16 nMPgNum(rMasterPage.GetPageNum());
1747 
1748                     if(nMPgNum < nSrcMasterPageAnz)
1749                     {
1750                         pMasterNeed[nMPgNum] = sal_True;
1751                     }
1752                 }
1753             }
1754         }
1755         // Nun das Mapping der MasterPages bestimmen
1756         sal_uInt16 nAktMaPagNum=nDstMasterPageAnz;
1757         for (sal_uInt16 i=0; i<nSrcMasterPageAnz; i++) {
1758             if (pMasterNeed[i]) {
1759                 pMasterMap[i]=nAktMaPagNum;
1760                 nAktMaPagNum++;
1761                 nMasterNeed++;
1762             }
1763         }
1764     }
1765 
1766     // rueberholen der Masterpages
1767     if (pMasterMap!=NULL && pMasterNeed!=NULL && nMasterNeed!=0) {
1768         for (sal_uInt16 i=nSrcMasterPageAnz; i>0;) {
1769             i--;
1770             if (pMasterNeed[i]) {
1771                 SdrPage* pPg=NULL;
1772                 if (bTreadSourceAsConst) {
1773                     const SdrPage* pPg1=rSourceModel.GetMasterPage(i);
1774                     pPg=pPg1->Clone();
1775                 } else {
1776                     pPg=rSourceModel.RemoveMasterPage(i);
1777                 }
1778                 if (pPg!=NULL) {
1779                     // und alle ans einstige Ende des DstModel reinschieben.
1780                     // nicht InsertMasterPage() verwenden da die Sache
1781                     // inkonsistent ist bis alle drin sind
1782                     maMaPag.Insert(pPg,nDstMasterPageAnz);
1783                     // #109538#
1784                     MasterPageListChanged();
1785                     pPg->SetInserted(sal_True);
1786                     pPg->SetModel(this);
1787                     bMPgNumsDirty=sal_True;
1788                     if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
1789                 } else {
1790                     DBG_ERROR("SdrModel::Merge(): MasterPage im SourceModel nicht gefunden");
1791                 }
1792             }
1793         }
1794     }
1795 
1796     // rueberholen der Zeichenseiten
1797     if (bInsPages) {
1798         sal_uInt16 nSourcePos=nFirstPageNum;
1799         sal_uInt16 nMergeCount=sal_uInt16(Abs((long)((long)nFirstPageNum-nLastPageNum))+1);
1800         if (nDestPos>GetPageCount()) nDestPos=GetPageCount();
1801         while (nMergeCount>0) {
1802             SdrPage* pPg=NULL;
1803             if (bTreadSourceAsConst) {
1804                 const SdrPage* pPg1=rSourceModel.GetPage(nSourcePos);
1805                 pPg=pPg1->Clone();
1806             } else {
1807                 pPg=rSourceModel.RemovePage(nSourcePos);
1808             }
1809             if (pPg!=NULL) {
1810                 InsertPage(pPg,nDestPos);
1811                 if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
1812                 // und nun zu den MasterPageDescriptoren
1813 
1814                 if(pPg->TRG_HasMasterPage())
1815                 {
1816                     SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
1817                     sal_uInt16 nMaPgNum(rMasterPage.GetPageNum());
1818 
1819                     if (bMergeMasterPages)
1820                     {
1821                         sal_uInt16 nNeuNum(0xFFFF);
1822 
1823                         if(pMasterMap)
1824                         {
1825                             nNeuNum = pMasterMap[nMaPgNum];
1826                         }
1827 
1828                         if(nNeuNum != 0xFFFF)
1829                         {
1830                             if(bUndo)
1831                             {
1832                                 AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*pPg));
1833                             }
1834 
1835                             pPg->TRG_SetMasterPage(*GetMasterPage(nNeuNum));
1836                         }
1837                         DBG_ASSERT(nNeuNum!=0xFFFF,"SdrModel::Merge(): Irgendwas ist krumm beim Mappen der MasterPages");
1838                     } else {
1839                         if (nMaPgNum>=nDstMasterPageAnz) {
1840                             // Aha, die ist ausserbalb des urspruenglichen Bereichs der Masterpages des DstModel
1841                             pPg->TRG_ClearMasterPage();
1842                         }
1843                     }
1844                 }
1845 
1846             } else {
1847                 DBG_ERROR("SdrModel::Merge(): Zeichenseite im SourceModel nicht gefunden");
1848             }
1849             nDestPos++;
1850             if (bReverse) nSourcePos--;
1851             else if (bTreadSourceAsConst) nSourcePos++;
1852             nMergeCount--;
1853         }
1854     }
1855 
1856     delete [] pMasterMap;
1857     delete [] pMasterNeed;
1858 
1859     bMPgNumsDirty=sal_True;
1860     bPagNumsDirty=sal_True;
1861 
1862     SetChanged();
1863     // Fehlt: Mergen und Mapping der Layer
1864     // an den Objekten sowie an den MasterPageDescriptoren
1865     if (bUndo) EndUndo();
1866 }
1867 
1868 void SdrModel::SetStarDrawPreviewMode(sal_Bool bPreview)
1869 {
1870     if (!bPreview && bStarDrawPreviewMode && GetPageCount())
1871     {
1872         // Das Zuruecksetzen ist nicht erlaubt, da das Model ev. nicht vollstaendig geladen wurde
1873         DBG_ASSERT(sal_False,"SdrModel::SetStarDrawPreviewMode(): Zuruecksetzen nicht erlaubt, da Model ev. nicht vollstaendig");
1874     }
1875     else
1876     {
1877         bStarDrawPreviewMode = bPreview;
1878     }
1879 }
1880 
1881 uno::Reference< uno::XInterface > SdrModel::getUnoModel()
1882 {
1883     if( !mxUnoModel.is() )
1884         mxUnoModel = createUnoModel();
1885 
1886     return mxUnoModel;
1887 }
1888 
1889 void SdrModel::setUnoModel( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xModel )
1890 {
1891     mxUnoModel = xModel;
1892 }
1893 
1894 uno::Reference< uno::XInterface > SdrModel::createUnoModel()
1895 {
1896     DBG_ERROR( "SdrModel::createUnoModel() - base implementation should not be called!" );
1897     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInt;
1898     return xInt;
1899 }
1900 
1901 void SdrModel::setLock( sal_Bool bLock )
1902 {
1903     if( mbModelLocked != bLock )
1904     {
1905         if( sal_False == bLock )
1906         {
1907             // ReformatAllTextObjects(); #103122# due to a typo in the above if, this code was never
1908             //                           executed, so I remove it until we discover that we need it here
1909             ImpReformatAllEdgeObjects();    // #103122#
1910         }
1911         mbModelLocked = bLock;
1912     }
1913 }
1914 
1915 ////////////////////////////////////////////////////////////////////////////////////////////////////
1916 
1917 void SdrModel::MigrateItemSet( const SfxItemSet* pSourceSet, SfxItemSet* pDestSet, SdrModel* pNewModel )
1918 {
1919     if( pSourceSet && pDestSet && (pSourceSet != pDestSet ) )
1920     {
1921         if( pNewModel == NULL )
1922             pNewModel = this;
1923 
1924         SfxWhichIter aWhichIter(*pSourceSet);
1925         sal_uInt16 nWhich(aWhichIter.FirstWhich());
1926         const SfxPoolItem *pPoolItem;
1927 
1928         while(nWhich)
1929         {
1930             if(SFX_ITEM_SET == pSourceSet->GetItemState(nWhich, sal_False, &pPoolItem))
1931             {
1932                 const SfxPoolItem* pItem = pPoolItem;
1933 
1934                 switch( nWhich )
1935                 {
1936                 case XATTR_FILLBITMAP:
1937                     pItem = ((XFillBitmapItem*)pItem)->checkForUniqueItem( pNewModel );
1938                     break;
1939                 case XATTR_LINEDASH:
1940                     pItem = ((XLineDashItem*)pItem)->checkForUniqueItem( pNewModel );
1941                     break;
1942                 case XATTR_LINESTART:
1943                     pItem = ((XLineStartItem*)pItem)->checkForUniqueItem( pNewModel );
1944                     break;
1945                 case XATTR_LINEEND:
1946                     pItem = ((XLineEndItem*)pItem)->checkForUniqueItem( pNewModel );
1947                     break;
1948                 case XATTR_FILLGRADIENT:
1949                     pItem = ((XFillGradientItem*)pItem)->checkForUniqueItem( pNewModel );
1950                     break;
1951                 case XATTR_FILLFLOATTRANSPARENCE:
1952                     // #85953# allow all kinds of XFillFloatTransparenceItem to be set
1953                     pItem = ((XFillFloatTransparenceItem*)pItem)->checkForUniqueItem( pNewModel );
1954                     break;
1955                 case XATTR_FILLHATCH:
1956                     pItem = ((XFillHatchItem*)pItem)->checkForUniqueItem( pNewModel );
1957                     break;
1958                 }
1959 
1960                 // set item
1961                 if( pItem )
1962                 {
1963                     pDestSet->Put(*pItem);
1964 
1965                     // delete item if it was a generated one
1966                     if( pItem != pPoolItem)
1967                         delete (SfxPoolItem*)pItem;
1968                 }
1969             }
1970             nWhich = aWhichIter.NextWhich();
1971         }
1972     }
1973 }
1974 
1975 ////////////////////////////////////////////////////////////////////////////////////////////////////
1976 
1977 void SdrModel::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
1978 {
1979     if( mpForbiddenCharactersTable )
1980         mpForbiddenCharactersTable->release();
1981 
1982     mpForbiddenCharactersTable = xForbiddenChars.getBodyPtr();
1983 
1984     if( mpForbiddenCharactersTable )
1985         mpForbiddenCharactersTable->acquire();
1986 
1987     ImpSetOutlinerDefaults( pDrawOutliner );
1988     ImpSetOutlinerDefaults( pHitTestOutliner );
1989 }
1990 
1991 vos::ORef<SvxForbiddenCharactersTable> SdrModel::GetForbiddenCharsTable() const
1992 {
1993     return mpForbiddenCharactersTable;
1994 }
1995 
1996 void SdrModel::SetCharCompressType( sal_uInt16 nType )
1997 {
1998     if( nType != mnCharCompressType )
1999     {
2000         mnCharCompressType = nType;
2001         ImpSetOutlinerDefaults( pDrawOutliner );
2002         ImpSetOutlinerDefaults( pHitTestOutliner );
2003     }
2004 }
2005 
2006 void SdrModel::SetKernAsianPunctuation( sal_Bool bEnabled )
2007 {
2008     if( mbKernAsianPunctuation != bEnabled )
2009     {
2010         mbKernAsianPunctuation = bEnabled;
2011         ImpSetOutlinerDefaults( pDrawOutliner );
2012         ImpSetOutlinerDefaults( pHitTestOutliner );
2013     }
2014 }
2015 
2016 void SdrModel::SetAddExtLeading( sal_Bool bEnabled )
2017 {
2018     if( mbAddExtLeading != bEnabled )
2019     {
2020         mbAddExtLeading = bEnabled;
2021         ImpSetOutlinerDefaults( pDrawOutliner );
2022         ImpSetOutlinerDefaults( pHitTestOutliner );
2023     }
2024 }
2025 
2026 void SdrModel::ReformatAllTextObjects()
2027 {
2028     ImpReformatAllTextObjects();
2029 }
2030 
2031 FASTBOOL SdrModel::HasTransparentObjects( sal_Bool bCheckForAlphaChannel ) const
2032 {
2033     FASTBOOL    bRet = sal_False;
2034     sal_uInt16      n, nCount;
2035 
2036     for( n = 0, nCount = GetMasterPageCount(); ( n < nCount ) && !bRet; n++ )
2037         if( GetMasterPage( n )->HasTransparentObjects( bCheckForAlphaChannel ) )
2038             bRet = sal_True;
2039 
2040     if( !bRet )
2041     {
2042         for( n = 0, nCount = GetPageCount(); ( n < nCount ) && !bRet; n++ )
2043             if( GetPage( n )->HasTransparentObjects( bCheckForAlphaChannel ) )
2044                 bRet = sal_True;
2045     }
2046 
2047     return bRet;
2048 }
2049 
2050 SdrOutliner* SdrModel::createOutliner( sal_uInt16 nOutlinerMode )
2051 {
2052     if( NULL == mpOutlinerCache )
2053         mpOutlinerCache = new SdrOutlinerCache(this);
2054 
2055     return mpOutlinerCache->createOutliner( nOutlinerMode );
2056 }
2057 
2058 void SdrModel::disposeOutliner( SdrOutliner* pOutliner )
2059 {
2060     if( mpOutlinerCache )
2061     {
2062         mpOutlinerCache->disposeOutliner( pOutliner );
2063     }
2064     else
2065     {
2066         delete pOutliner;
2067     }
2068 }
2069 
2070 SvxNumType SdrModel::GetPageNumType() const
2071 {
2072     return SVX_ARABIC;
2073 }
2074 
2075 const SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum) const
2076 {
2077     DBG_ASSERT(nPgNum < maPages.Count(), "SdrModel::GetPage: Access out of range (!)");
2078     return (SdrPage*)(maPages.GetObject(nPgNum));
2079 }
2080 
2081 SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum)
2082 {
2083     DBG_ASSERT(nPgNum < maPages.Count(), "SdrModel::GetPage: Access out of range (!)");
2084     return (SdrPage*)(maPages.GetObject(nPgNum));
2085 }
2086 
2087 sal_uInt16 SdrModel::GetPageCount() const
2088 {
2089     return sal_uInt16(maPages.Count());
2090 }
2091 
2092 void SdrModel::PageListChanged()
2093 {
2094 }
2095 
2096 const SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum) const
2097 {
2098     DBG_ASSERT(nPgNum < maMaPag.Count(), "SdrModel::GetMasterPage: Access out of range (!)");
2099     return (SdrPage*)(maMaPag.GetObject(nPgNum));
2100 }
2101 
2102 SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum)
2103 {
2104     DBG_ASSERT(nPgNum < maMaPag.Count(), "SdrModel::GetMasterPage: Access out of range (!)");
2105     return (SdrPage*)(maMaPag.GetObject(nPgNum));
2106 }
2107 
2108 sal_uInt16 SdrModel::GetMasterPageCount() const
2109 {
2110     return sal_uInt16(maMaPag.Count());
2111 }
2112 
2113 void SdrModel::MasterPageListChanged()
2114 {
2115 }
2116 
2117 void SdrModel::SetSdrUndoManager( SfxUndoManager* pUndoManager )
2118 {
2119     mpImpl->mpUndoManager = pUndoManager;
2120 }
2121 
2122 SfxUndoManager* SdrModel::GetSdrUndoManager() const
2123 {
2124     return mpImpl->mpUndoManager;
2125 }
2126 
2127 SdrUndoFactory& SdrModel::GetSdrUndoFactory() const
2128 {
2129     if( !mpImpl->mpUndoFactory )
2130         mpImpl->mpUndoFactory = new SdrUndoFactory;
2131     return *mpImpl->mpUndoFactory;
2132 }
2133 
2134 void SdrModel::SetSdrUndoFactory( SdrUndoFactory* pUndoFactory )
2135 {
2136     if( pUndoFactory && (pUndoFactory != mpImpl->mpUndoFactory) )
2137     {
2138         delete mpImpl->mpUndoFactory;
2139         mpImpl->mpUndoFactory = pUndoFactory;
2140     }
2141 }
2142 
2143 /** cl: added this for OJ to complete his reporting engine, does not work
2144     correctly so only enable it for his model */
2145 bool SdrModel::IsAllowShapePropertyChangeListener() const
2146 {
2147     return mpImpl && mpImpl->mbAllowShapePropertyChangeListener;
2148 }
2149 
2150 void SdrModel::SetAllowShapePropertyChangeListener( bool bAllow )
2151 {
2152     if( mpImpl )
2153     {
2154         mpImpl->mbAllowShapePropertyChangeListener = bAllow;
2155     }
2156 }
2157 
2158 const ::com::sun::star::uno::Sequence< sal_Int8 >& SdrModel::getUnoTunnelImplementationId()
2159 {
2160     static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
2161     if( !pSeq )
2162     {
2163         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
2164         if( !pSeq )
2165         {
2166             static Sequence< sal_Int8 > aSeq( 16 );
2167             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
2168             pSeq = &aSeq;
2169         }
2170     }
2171     return *pSeq;
2172 }
2173 
2174 void SdrModel::SetDrawingLayerPoolDefaults()
2175 {
2176     const String aNullStr;
2177     const Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE);
2178     const Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING);
2179     const XHatch aNullHatch(aNullLineCol);
2180 
2181     pItemPool->SetPoolDefaultItem( XFillColorItem(aNullStr,aNullFillCol) );
2182     pItemPool->SetPoolDefaultItem( XFillHatchItem(pItemPool,aNullHatch) );
2183     pItemPool->SetPoolDefaultItem( XLineColorItem(aNullStr,aNullLineCol) );
2184 }
2185 
2186 ////////////////////////////////////////////////////////////////////////////////////////////////////
2187 
2188 TYPEINIT1(SdrHint,SfxHint);
2189 
2190 SdrHint::SdrHint()
2191 :   mpPage(0L),
2192     mpObj(0L),
2193     mpObjList(0L),
2194     meHint(HINT_UNKNOWN)
2195 {
2196 }
2197 
2198 SdrHint::SdrHint(SdrHintKind eNewHint)
2199 :   mpPage(0L),
2200     mpObj(0L),
2201     mpObjList(0L),
2202     meHint(eNewHint)
2203 {
2204 }
2205 
2206 SdrHint::SdrHint(const SdrObject& rNewObj)
2207 :   mpPage(rNewObj.GetPage()),
2208     mpObj(&rNewObj),
2209     mpObjList(rNewObj.GetObjList()),
2210     meHint(HINT_OBJCHG)
2211 {
2212     maRectangle = rNewObj.GetLastBoundRect();
2213 }
2214 
2215 SdrHint::SdrHint(const SdrObject& rNewObj, const Rectangle& rRect)
2216 :   mpPage(rNewObj.GetPage()),
2217     mpObj(&rNewObj),
2218     mpObjList(rNewObj.GetObjList()),
2219     meHint(HINT_OBJCHG)
2220 {
2221     maRectangle = rRect;
2222 }
2223 
2224 void SdrHint::SetPage(const SdrPage* pNewPage)
2225 {
2226     mpPage = pNewPage;
2227 }
2228 
2229 void SdrHint::SetObjList(const SdrObjList* pNewOL)
2230 {
2231     mpObjList = pNewOL;
2232 }
2233 
2234 void SdrHint::SetObject(const SdrObject* pNewObj)
2235 {
2236     mpObj = pNewObj;
2237 }
2238 
2239 void SdrHint::SetKind(SdrHintKind eNewKind)
2240 {
2241     meHint = eNewKind;
2242 }
2243 
2244 void SdrHint::SetRect(const Rectangle& rNewRect)
2245 {
2246     maRectangle = rNewRect;
2247 }
2248 
2249 const SdrPage* SdrHint::GetPage() const
2250 {
2251     return mpPage;
2252 }
2253 
2254 const SdrObjList* SdrHint::GetObjList() const
2255 {
2256     return mpObjList;
2257 }
2258 
2259 const SdrObject* SdrHint::GetObject() const
2260 {
2261     return mpObj;
2262 }
2263 
2264 SdrHintKind SdrHint::GetKind() const
2265 {
2266     return meHint;
2267 }
2268 
2269 const Rectangle& SdrHint::GetRect() const
2270 {
2271     return maRectangle;
2272 }
2273 
2274 // eof
2275