xref: /aoo41x/main/svx/source/svdraw/svdmodel.cxx (revision 79aad27f)
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