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