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