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