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