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