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