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