xref: /aoo41x/main/sc/source/core/data/documen9.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 #include <editeng/eeitem.hxx>
35 
36 #include <sot/exchange.hxx>
37 #include <editeng/akrnitem.hxx>
38 #include <editeng/fontitem.hxx>
39 #include <editeng/forbiddencharacterstable.hxx>
40 #include <editeng/langitem.hxx>
41 #include <svx/svdetc.hxx>
42 #include <svx/svditer.hxx>
43 #include <svx/svdocapt.hxx>
44 #include <svx/svdograf.hxx>
45 #include <svx/svdoole2.hxx>
46 #include <svx/svdouno.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdundo.hxx>
49 #include <svx/xtable.hxx>
50 #include <sfx2/objsh.hxx>
51 #include <sfx2/printer.hxx>
52 #include <unotools/saveopt.hxx>
53 #include <unotools/pathoptions.hxx>
54 
55 #include "document.hxx"
56 #include "docoptio.hxx"
57 #include "table.hxx"
58 #include "drwlayer.hxx"
59 #include "markdata.hxx"
60 #include "patattr.hxx"
61 #include "rechead.hxx"
62 #include "poolhelp.hxx"
63 #include "docpool.hxx"
64 #include "detfunc.hxx"		// for UpdateAllComments
65 #include "editutil.hxx"
66 #include "postit.hxx"
67 #include "charthelper.hxx"
68 
69 using namespace ::com::sun::star;
70 #include <stdio.h>
71 // -----------------------------------------------------------------------
72 
73 
74 SfxBroadcaster* ScDocument::GetDrawBroadcaster()
75 {
76 	return pDrawLayer;
77 }
78 
79 void ScDocument::BeginDrawUndo()
80 {
81 	if (pDrawLayer)
82 		pDrawLayer->BeginCalcUndo();
83 }
84 
85 XColorTable* ScDocument::GetColorTable()
86 {
87 	if (pDrawLayer)
88 		return pDrawLayer->GetColorTable();
89 	else
90 	{
91 		if (!pColorTable)
92 		{
93 			SvtPathOptions aPathOpt;
94 			pColorTable = new XColorTable( aPathOpt.GetPalettePath() );
95 		}
96 
97 		return pColorTable;
98 	}
99 }
100 
101 void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos)
102 {
103 	if (pDrawLayer && pSrcDoc->pDrawLayer)
104 	{
105 		SdrPage* pOldPage = pSrcDoc->pDrawLayer->GetPage(static_cast<sal_uInt16>(nSrcPos));
106 		SdrPage* pNewPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestPos));
107 
108 		if (pOldPage && pNewPage)
109 		{
110 			SdrObjListIter aIter( *pOldPage, IM_FLAT );
111 			SdrObject* pOldObject = aIter.Next();
112 			while (pOldObject)
113 			{
114                 // #i112034# do not copy internal objects (detective) and note captions
115                 if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !ScDrawLayer::IsNoteCaption( pOldObject ) )
116                 {
117                     // #116235#
118                     SdrObject* pNewObject = pOldObject->Clone();
119                     // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer );
120                     pNewObject->SetModel(pDrawLayer);
121                     pNewObject->SetPage(pNewPage);
122 
123                     pNewObject->NbcMove(Size(0,0));
124                     pNewPage->InsertObject( pNewObject );
125 
126                     if (pDrawLayer->IsRecording())
127                         pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
128                 }
129 
130 				pOldObject = aIter.Next();
131 			}
132 		}
133 	}
134 
135     //	#71726# make sure the data references of charts are adapted
136 	//	(this must be after InsertObject!)
137     ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pSrcDoc, this, nSrcPos, nDestPos );
138 }
139 
140 void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell )
141 {
142 	if (pDocShell && !pShell)
143 		pShell = pDocShell;
144 
145 //	DBG_ASSERT(pShell,"InitDrawLayer ohne Shell");
146 
147 	if (!pDrawLayer)
148 	{
149 		String aName;
150 		if ( pShell && !pShell->IsLoading() )		// #88438# don't call GetTitle while loading
151 			aName = pShell->GetTitle();
152 		pDrawLayer = new ScDrawLayer( this, aName );
153 		if (GetLinkManager())
154 			pDrawLayer->SetLinkManager( pLinkManager );
155 
156 		//	Drawing pages are accessed by table number, so they must also be present
157 		//	for preceding table numbers, even if the tables aren't allocated
158 		//	(important for clipboard documents).
159 
160 		SCTAB nDrawPages = 0;
161 		SCTAB nTab;
162 		for (nTab=0; nTab<=MAXTAB; nTab++)
163 			if (pTab[nTab])
164 				nDrawPages = nTab + 1;			// needed number of pages
165 
166 		for (nTab=0; nTab<nDrawPages; nTab++)
167 		{
168 			pDrawLayer->ScAddPage( nTab );		// always add page, with or without the table
169 			if (pTab[nTab])
170 			{
171                 String aTabName;
172                 pTab[nTab]->GetName(aTabName);
173                 pDrawLayer->ScRenamePage( nTab, aTabName );
174 
175                 pTab[nTab]->SetDrawPageSize(false,false);     // #54782# set the right size immediately
176 #if 0
177 				sal_uLong nx = (sal_uLong) ((double) (MAXCOL+1) * STD_COL_WIDTH			  * HMM_PER_TWIPS );
178 				sal_uLong ny = (sal_uLong) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
179 				pDrawLayer->SetPageSize( nTab, Size( nx, ny ) );
180 #endif
181 			}
182 		}
183 
184 		pDrawLayer->SetDefaultTabulator( GetDocOptions().GetTabDistance() );
185 
186 		UpdateDrawPrinter();
187         UpdateDrawDefaults();
188 		UpdateDrawLanguages();
189 		if (bImportingXML)
190 			pDrawLayer->EnableAdjust(sal_False);
191 
192 		pDrawLayer->SetForbiddenCharsTable( xForbiddenCharacters );
193 		pDrawLayer->SetCharCompressType( GetAsianCompression() );
194 		pDrawLayer->SetKernAsianPunctuation( GetAsianKerning() );
195 	}
196 }
197 
198 void ScDocument::UpdateDrawLanguages()
199 {
200 	if (pDrawLayer)
201 	{
202 		SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
203 		rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eLanguage, EE_CHAR_LANGUAGE ) );
204 		rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage, EE_CHAR_LANGUAGE_CJK ) );
205 		rDrawPool.SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage, EE_CHAR_LANGUAGE_CTL ) );
206 	}
207 }
208 
209 void ScDocument::UpdateDrawDefaults()
210 {
211     // drawing layer defaults that are set for new documents (if InitNew was called)
212 
213     if ( pDrawLayer && bSetDrawDefaults )
214     {
215         SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
216         rDrawPool.SetPoolDefaultItem( SvxAutoKernItem( sal_True, EE_CHAR_PAIRKERNING ) );
217 		pDrawLayer->SetDrawingLayerPoolDefaults();
218     }
219 }
220 
221 void ScDocument::UpdateDrawPrinter()
222 {
223 	if (pDrawLayer)
224 	{
225 		// use the printer even if IsValid is false
226 		// Application::GetDefaultDevice causes trouble with changing MapModes
227 
228 //		OutputDevice* pRefDev = GetPrinter();
229 //		pRefDev->SetMapMode( MAP_100TH_MM );
230 		pDrawLayer->SetRefDevice(GetRefDevice());
231 	}
232 }
233 
234 sal_Bool ScDocument::IsChart( const SdrObject* pObject )
235 {
236 	// #109985#
237 	// IsChart() implementation moved to svx drawinglayer
238 	if(pObject && OBJ_OLE2 == pObject->GetObjIdentifier())
239 	{
240 		return ((SdrOle2Obj*)pObject)->IsChart();
241 	}
242 
243 	return sal_False;
244 }
245 
246 IMPL_LINK_INLINE_START( ScDocument, GetUserDefinedColor, sal_uInt16 *, pColorIndex )
247 {
248 	return (long) &((GetColorTable()->GetColor(*pColorIndex))->GetColor());
249 }
250 IMPL_LINK_INLINE_END( ScDocument, GetUserDefinedColor, sal_uInt16 *, pColorIndex )
251 
252 void ScDocument::DeleteDrawLayer()
253 {
254 	delete pDrawLayer;
255 }
256 
257 void ScDocument::DeleteColorTable()
258 {
259 	delete pColorTable;
260 }
261 
262 sal_Bool ScDocument::DrawGetPrintArea( ScRange& rRange, sal_Bool bSetHor, sal_Bool bSetVer ) const
263 {
264 	return pDrawLayer->GetPrintArea( rRange, bSetHor, bSetVer );
265 }
266 
267 void ScDocument::DrawMovePage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
268 {
269 	pDrawLayer->ScMovePage(nOldPos,nNewPos);
270 }
271 
272 void ScDocument::DrawCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
273 {
274 	// angelegt wird die Page schon im ScTable ctor
275 	pDrawLayer->ScCopyPage( nOldPos, nNewPos, sal_False );
276 }
277 
278 void ScDocument::DeleteObjectsInArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
279 						const ScMarkData& rMark )
280 {
281 	if (!pDrawLayer)
282 		return;
283 
284 	SCTAB nTabCount = GetTableCount();
285 	for (SCTAB nTab=0; nTab<=nTabCount; nTab++)
286 		if (pTab[nTab] && rMark.GetTableSelect(nTab))
287 			pDrawLayer->DeleteObjectsInArea( nTab, nCol1, nRow1, nCol2, nRow2 );
288 }
289 
290 void ScDocument::DeleteObjectsInSelection( const ScMarkData& rMark )
291 {
292 	if (!pDrawLayer)
293 		return;
294 
295 	pDrawLayer->DeleteObjectsInSelection( rMark );
296 }
297 
298 sal_Bool ScDocument::HasOLEObjectsInArea( const ScRange& rRange, const ScMarkData* pTabMark )
299 {
300 	//	pTabMark is used only for selected tables. If pTabMark is 0, all tables of rRange are used.
301 
302 	if (!pDrawLayer)
303 		return sal_False;
304 
305 	SCTAB nStartTab = 0;
306 	SCTAB nEndTab = MAXTAB;
307 	if ( !pTabMark )
308 	{
309 		nStartTab = rRange.aStart.Tab();
310 		nEndTab = rRange.aEnd.Tab();
311 	}
312 
313 	for (SCTAB nTab = nStartTab; nTab <= nEndTab; nTab++)
314 	{
315 		if ( !pTabMark || pTabMark->GetTableSelect(nTab) )
316 		{
317 			Rectangle aMMRect = GetMMRect( rRange.aStart.Col(), rRange.aStart.Row(),
318 											rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
319 
320 			SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
321 			DBG_ASSERT(pPage,"Page ?");
322 			if (pPage)
323 			{
324 				SdrObjListIter aIter( *pPage, IM_FLAT );
325 				SdrObject* pObject = aIter.Next();
326 				while (pObject)
327 				{
328 					if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
329 							aMMRect.IsInside( pObject->GetCurrentBoundRect() ) )
330 						return sal_True;
331 
332 					pObject = aIter.Next();
333 				}
334 			}
335 		}
336 	}
337 
338 	return sal_False;
339 }
340 
341 
342 void ScDocument::StartAnimations( SCTAB nTab, Window* pWin )
343 {
344 	if (!pDrawLayer)
345 		return;
346 	SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
347 	DBG_ASSERT(pPage,"Page ?");
348 	if (!pPage)
349 		return;
350 
351 	SdrObjListIter aIter( *pPage, IM_FLAT );
352 	SdrObject* pObject = aIter.Next();
353 	while (pObject)
354 	{
355 		if (pObject->ISA(SdrGrafObj))
356 		{
357 			SdrGrafObj* pGrafObj = (SdrGrafObj*)pObject;
358 			if ( pGrafObj->IsAnimated() )
359 			{
360 				const Rectangle& rRect = pGrafObj->GetCurrentBoundRect();
361 				pGrafObj->StartAnimation( pWin, rRect.TopLeft(), rRect.GetSize() );
362 			}
363 		}
364 		pObject = aIter.Next();
365 	}
366 }
367 
368 //UNUSED2008-05  void ScDocument::RefreshNoteFlags()
369 //UNUSED2008-05  {
370 //UNUSED2008-05      if (!pDrawLayer)
371 //UNUSED2008-05          return;
372 //UNUSED2008-05
373 //UNUSED2008-05      sal_Bool bAnyIntObj = sal_False;
374 //UNUSED2008-05      SCTAB nTab;
375 //UNUSED2008-05      ScPostIt aNote(this);
376 //UNUSED2008-05      for (nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
377 //UNUSED2008-05      {
378 //UNUSED2008-05          SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
379 //UNUSED2008-05          DBG_ASSERT(pPage,"Page ?");
380 //UNUSED2008-05          if (pPage)
381 //UNUSED2008-05          {
382 //UNUSED2008-05              SdrObjListIter aIter( *pPage, IM_FLAT );
383 //UNUSED2008-05              SdrObject* pObject = aIter.Next();
384 //UNUSED2008-05              while (pObject)
385 //UNUSED2008-05              {
386 //UNUSED2008-05                  if ( pObject->GetLayer() == SC_LAYER_INTERN )
387 //UNUSED2008-05                  {
388 //UNUSED2008-05                      bAnyIntObj = sal_True;  // for all internal objects, including detective
389 //UNUSED2008-05
390 //UNUSED2008-05                      if ( pObject->ISA( SdrCaptionObj ) )
391 //UNUSED2008-05                      {
392 //UNUSED2008-05                          ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject );
393 //UNUSED2008-05                          if ( pData )
394 //UNUSED2008-05                          {
395 //UNUSED2008-05                              if ( GetNote( pData->aStt.Col(), pData->aStt.Row(), nTab, aNote))
396 //UNUSED2008-05                                  if ( !aNote.IsShown() )
397 //UNUSED2008-05                                  {
398 //UNUSED2008-05                                      aNote.SetShown(sal_True);
399 //UNUSED2008-05                                      SetNote( pData->aStt.Col(), pData->aStt.Row(), nTab, aNote);
400 //UNUSED2008-05                                  }
401 //UNUSED2008-05                          }
402 //UNUSED2008-05                      }
403 //UNUSED2008-05                  }
404 //UNUSED2008-05                  pObject = aIter.Next();
405 //UNUSED2008-05              }
406 //UNUSED2008-05          }
407 //UNUSED2008-05      }
408 //UNUSED2008-05
409 //UNUSED2008-05      if (bAnyIntObj)
410 //UNUSED2008-05      {
411 //UNUSED2008-05          //  update attributes for all note objects and the colors of detective objects
412 //UNUSED2008-05          //  (we don't know with which settings the file was created)
413 //UNUSED2008-05
414 //UNUSED2008-05          ScDetectiveFunc aFunc( this, 0 );
415 //UNUSED2008-05          aFunc.UpdateAllComments();
416 //UNUSED2008-05          aFunc.UpdateAllArrowColors();
417 //UNUSED2008-05      }
418 //UNUSED2008-05  }
419 
420 sal_Bool ScDocument::HasBackgroundDraw( SCTAB nTab, const Rectangle& rMMRect )
421 {
422 	//	Gibt es Objekte auf dem Hintergrund-Layer, die (teilweise) von rMMRect
423 	//	betroffen sind?
424 	//	(fuer Drawing-Optimierung, vor dem Hintergrund braucht dann nicht geloescht
425 	//	 zu werden)
426 
427 	if (!pDrawLayer)
428 		return sal_False;
429 	SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
430 	DBG_ASSERT(pPage,"Page ?");
431 	if (!pPage)
432 		return sal_False;
433 
434 	sal_Bool bFound = sal_False;
435 
436 	SdrObjListIter aIter( *pPage, IM_FLAT );
437 	SdrObject* pObject = aIter.Next();
438 	while (pObject && !bFound)
439 	{
440 		if ( pObject->GetLayer() == SC_LAYER_BACK && pObject->GetCurrentBoundRect().IsOver( rMMRect ) )
441 			bFound = sal_True;
442 		pObject = aIter.Next();
443 	}
444 
445 	return bFound;
446 }
447 
448 sal_Bool ScDocument::HasAnyDraw( SCTAB nTab, const Rectangle& rMMRect )
449 {
450 	//	Gibt es ueberhaupt Objekte, die (teilweise) von rMMRect
451 	//	betroffen sind?
452 	//	(um leere Seiten beim Drucken zu erkennen)
453 
454 	if (!pDrawLayer)
455 		return sal_False;
456 	SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
457 	DBG_ASSERT(pPage,"Page ?");
458 	if (!pPage)
459 		return sal_False;
460 
461 	sal_Bool bFound = sal_False;
462 
463 	SdrObjListIter aIter( *pPage, IM_FLAT );
464 	SdrObject* pObject = aIter.Next();
465 	while (pObject && !bFound)
466 	{
467 		if ( pObject->GetCurrentBoundRect().IsOver( rMMRect ) )
468 			bFound = sal_True;
469 		pObject = aIter.Next();
470 	}
471 
472 	return bFound;
473 }
474 
475 void ScDocument::EnsureGraphicNames()
476 {
477 	if (pDrawLayer)
478 		pDrawLayer->EnsureGraphicNames();
479 }
480 
481 SdrObject* ScDocument::GetObjectAtPoint( SCTAB nTab, const Point& rPos )
482 {
483 	//	fuer Drag&Drop auf Zeichenobjekt
484 
485 	SdrObject* pFound = NULL;
486 	if (pDrawLayer && pTab[nTab])
487 	{
488 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
489 		DBG_ASSERT(pPage,"Page ?");
490 		if (pPage)
491 		{
492 			SdrObjListIter aIter( *pPage, IM_FLAT );
493 			SdrObject* pObject = aIter.Next();
494 			while (pObject)
495 			{
496 				if ( pObject->GetCurrentBoundRect().IsInside(rPos) )
497 				{
498 					//	Intern interessiert gar nicht
499 					//	Objekt vom Back-Layer nur, wenn kein Objekt von anderem Layer getroffen
500 
501 					SdrLayerID nLayer = pObject->GetLayer();
502                     if ( (nLayer != SC_LAYER_INTERN) && (nLayer != SC_LAYER_HIDDEN) )
503 					{
504 						if ( nLayer != SC_LAYER_BACK ||
505 								!pFound || pFound->GetLayer() == SC_LAYER_BACK )
506 						{
507 							pFound = pObject;
508 						}
509 					}
510 				}
511 				//	weitersuchen -> letztes (oberstes) getroffenes Objekt nehmen
512 
513 				pObject = aIter.Next();
514 			}
515 		}
516 	}
517 	return pFound;
518 }
519 
520 sal_Bool ScDocument::IsPrintEmpty( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
521 								SCCOL nEndCol, SCROW nEndRow, sal_Bool bLeftIsEmpty,
522 								ScRange* pLastRange, Rectangle* pLastMM ) const
523 {
524 	if (!IsBlockEmpty( nTab, nStartCol, nStartRow, nEndCol, nEndRow ))
525 		return sal_False;
526 
527 	ScDocument* pThis = (ScDocument*)this;	//! GetMMRect / HasAnyDraw etc. const !!!
528 
529 	Rectangle aMMRect;
530 	if ( pLastRange && pLastMM && nTab == pLastRange->aStart.Tab() &&
531 			nStartRow == pLastRange->aStart.Row() && nEndRow == pLastRange->aEnd.Row() )
532 	{
533 		//	keep vertical part of aMMRect, only update horizontal position
534 		aMMRect = *pLastMM;
535 
536 		long nLeft = 0;
537 		SCCOL i;
538 		for (i=0; i<nStartCol; i++)
539 			nLeft += GetColWidth(i,nTab);
540 		long nRight = nLeft;
541 		for (i=nStartCol; i<=nEndCol; i++)
542 			nRight += GetColWidth(i,nTab);
543 
544 		aMMRect.Left()  = (long)(nLeft  * HMM_PER_TWIPS);
545 		aMMRect.Right() = (long)(nRight * HMM_PER_TWIPS);
546 	}
547 	else
548 		aMMRect = pThis->GetMMRect( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
549 
550 	if ( pLastRange && pLastMM )
551 	{
552 		*pLastRange = ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
553 		*pLastMM = aMMRect;
554 	}
555 
556 	if ( pThis->HasAnyDraw( nTab, aMMRect ))
557 		return sal_False;
558 
559 	if ( nStartCol > 0 && !bLeftIsEmpty )
560 	{
561 		//	aehnlich wie in ScPrintFunc::AdjustPrintArea
562 		//!	ExtendPrintArea erst ab Start-Spalte des Druckbereichs
563 
564 		SCCOL nExtendCol = nStartCol - 1;
565 		SCROW nTmpRow = nEndRow;
566 
567 		pThis->ExtendMerge( 0,nStartRow, nExtendCol,nTmpRow, nTab,
568 							sal_False, sal_True );		// kein Refresh, incl. Attrs
569 
570 		OutputDevice* pDev = pThis->GetPrinter();
571 		pDev->SetMapMode( MAP_PIXEL );				// wichtig fuer GetNeededSize
572 		pThis->ExtendPrintArea( pDev, nTab, 0, nStartRow, nExtendCol, nEndRow );
573 		if ( nExtendCol >= nStartCol )
574 			return sal_False;
575 	}
576 
577 	return sal_True;
578 }
579 
580 void ScDocument::Clear( sal_Bool bFromDestructor )
581 {
582 	for (SCTAB i=0; i<=MAXTAB; i++)
583 		if (pTab[i])
584 		{
585 			delete pTab[i];
586 			pTab[i]=NULL;
587 		}
588 	delete pSelectionAttr;
589 	pSelectionAttr = NULL;
590 
591 	if (pDrawLayer)
592 	{
593 		// #116168#
594 		//pDrawLayer->Clear();
595 		pDrawLayer->ClearModel( bFromDestructor );
596 	}
597 }
598 
599 sal_Bool ScDocument::HasControl( SCTAB nTab, const Rectangle& rMMRect )
600 {
601 	sal_Bool bFound = sal_False;
602 
603 	if (pDrawLayer)
604 	{
605 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
606 		DBG_ASSERT(pPage,"Page ?");
607 		if (pPage)
608 		{
609 			SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
610 			SdrObject* pObject = aIter.Next();
611 			while (pObject && !bFound)
612 			{
613 				if (pObject->ISA(SdrUnoObj))
614 				{
615 					Rectangle aObjRect = pObject->GetLogicRect();
616 					if ( aObjRect.IsOver( rMMRect ) )
617 						bFound = sal_True;
618 				}
619 
620 				pObject = aIter.Next();
621 			}
622 		}
623 	}
624 
625 	return bFound;
626 }
627 
628 void ScDocument::InvalidateControls( Window* pWin, SCTAB nTab, const Rectangle& rMMRect )
629 {
630 	if (pDrawLayer)
631 	{
632 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
633 		DBG_ASSERT(pPage,"Page ?");
634 		if (pPage)
635 		{
636 			SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
637 			SdrObject* pObject = aIter.Next();
638 			while (pObject)
639 			{
640 				if (pObject->ISA(SdrUnoObj))
641 				{
642 					Rectangle aObjRect = pObject->GetLogicRect();
643 					if ( aObjRect.IsOver( rMMRect ) )
644 					{
645 						//	Uno-Controls zeichnen sich immer komplett, ohne Ruecksicht
646 						//	auf ClippingRegions. Darum muss das ganze Objekt neu gepainted
647 						//	werden, damit die Selektion auf der Tabelle nicht uebermalt wird.
648 
649 						//pWin->Invalidate( aObjRect.GetIntersection( rMMRect ) );
650 						pWin->Invalidate( aObjRect );
651 					}
652 				}
653 
654 				pObject = aIter.Next();
655 			}
656 		}
657 	}
658 }
659 
660 sal_Bool ScDocument::HasDetectiveObjects(SCTAB nTab) const
661 {
662 	//	looks for detective objects, annotations don't count
663 	//	(used to adjust scale so detective objects hit their cells better)
664 
665 	sal_Bool bFound = sal_False;
666 
667 	if (pDrawLayer)
668 	{
669 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
670 		DBG_ASSERT(pPage,"Page ?");
671 		if (pPage)
672 		{
673 			SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
674 			SdrObject* pObject = aIter.Next();
675 			while (pObject && !bFound)
676 			{
677 				// anything on the internal layer except captions (annotations)
678                 if ( (pObject->GetLayer() == SC_LAYER_INTERN) && !ScDrawLayer::IsNoteCaption( pObject ) )
679 					bFound = sal_True;
680 
681 				pObject = aIter.Next();
682 			}
683 		}
684 	}
685 
686 	return bFound;
687 }
688 
689 void ScDocument::UpdateFontCharSet()
690 {
691 	//	In alten Versionen (bis incl. 4.0 ohne SP) wurden beim Austausch zwischen
692 	//	Systemen die CharSets in den Font-Attributen nicht angepasst.
693 	//	Das muss fuer Dokumente bis incl SP2 nun nachgeholt werden:
694 	//	Alles, was nicht SYMBOL ist, wird auf den System-CharSet umgesetzt.
695 	//	Bei neuen Dokumenten (Version SC_FONTCHARSET) sollte der CharSet stimmen.
696 
697 	sal_Bool bUpdateOld = ( nSrcVer < SC_FONTCHARSET );
698 
699 	CharSet eSysSet = gsl_getSystemTextEncoding();
700 	if ( eSrcSet != eSysSet || bUpdateOld )
701 	{
702 		sal_uInt32 nCount,i;
703 		SvxFontItem* pItem;
704 
705 		ScDocumentPool* pPool = xPoolHelper->GetDocPool();
706 		nCount = pPool->GetItemCount2(ATTR_FONT);
707 		for (i=0; i<nCount; i++)
708 		{
709 			pItem = (SvxFontItem*)pPool->GetItem2(ATTR_FONT, i);
710 			if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
711 							( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
712                 pItem->SetCharSet(eSysSet);
713 		}
714 
715 		if ( pDrawLayer )
716 		{
717 			SfxItemPool& rDrawPool = pDrawLayer->GetItemPool();
718 			nCount = rDrawPool.GetItemCount2(EE_CHAR_FONTINFO);
719 			for (i=0; i<nCount; i++)
720 			{
721 				pItem = (SvxFontItem*)rDrawPool.GetItem2(EE_CHAR_FONTINFO, i);
722 				if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
723 								( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
724                     pItem->SetCharSet( eSysSet );
725 			}
726 		}
727 	}
728 }
729 
730 void ScDocument::SetLoadingMedium( bool bVal )
731 {
732     bLoadingMedium = bVal;
733     for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
734     {
735         if (!pTab[nTab])
736             return;
737 
738         pTab[nTab]->SetLoadingMedium(bVal);
739     }
740 }
741 
742 void ScDocument::SetImportingXML( bool bVal )
743 {
744 	bImportingXML = bVal;
745 	if (pDrawLayer)
746 		pDrawLayer->EnableAdjust(!bImportingXML);
747 
748     if ( !bVal )
749     {
750         // #i57869# after loading, do the real RTL mirroring for the sheets that have the LoadingRTL flag set
751 
752         for ( SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++ )
753             if ( pTab[nTab]->IsLoadingRTL() )
754             {
755                 pTab[nTab]->SetLoadingRTL( sal_False );
756                 SetLayoutRTL( nTab, sal_True );             // includes mirroring; bImportingXML must be cleared first
757             }
758     }
759 
760     SetLoadingMedium(bVal);
761 }
762 
763 void ScDocument::SetXMLFromWrapper( sal_Bool bVal )
764 {
765     bXMLFromWrapper = bVal;
766 }
767 
768 vos::ORef<SvxForbiddenCharactersTable> ScDocument::GetForbiddenCharacters()
769 {
770 	return xForbiddenCharacters;
771 }
772 
773 void ScDocument::SetForbiddenCharacters( const vos::ORef<SvxForbiddenCharactersTable> xNew )
774 {
775 	xForbiddenCharacters = xNew;
776 	if ( pEditEngine )
777 		pEditEngine->SetForbiddenCharsTable( xForbiddenCharacters );
778 	if ( pDrawLayer )
779 		pDrawLayer->SetForbiddenCharsTable( xForbiddenCharacters );
780 }
781 
782 sal_Bool ScDocument::IsValidAsianCompression() const
783 {
784 	return ( nAsianCompression != SC_ASIANCOMPRESSION_INVALID );
785 }
786 
787 sal_uInt8 ScDocument::GetAsianCompression() const
788 {
789 	if ( nAsianCompression == SC_ASIANCOMPRESSION_INVALID )
790 		return 0;
791 	else
792 		return nAsianCompression;
793 }
794 
795 void ScDocument::SetAsianCompression(sal_uInt8 nNew)
796 {
797 	nAsianCompression = nNew;
798 	if ( pEditEngine )
799 		pEditEngine->SetAsianCompressionMode( nAsianCompression );
800 	if ( pDrawLayer )
801 		pDrawLayer->SetCharCompressType( nAsianCompression );
802 }
803 
804 sal_Bool ScDocument::IsValidAsianKerning() const
805 {
806 	return ( nAsianKerning != SC_ASIANKERNING_INVALID );
807 }
808 
809 sal_Bool ScDocument::GetAsianKerning() const
810 {
811 	if ( nAsianKerning == SC_ASIANKERNING_INVALID )
812 		return sal_False;
813 	else
814 		return (sal_Bool)nAsianKerning;
815 }
816 
817 void ScDocument::SetAsianKerning(sal_Bool bNew)
818 {
819 	nAsianKerning = (sal_uInt8)bNew;
820 	if ( pEditEngine )
821 		pEditEngine->SetKernAsianPunctuation( (sal_Bool)nAsianKerning );
822 	if ( pDrawLayer )
823 		pDrawLayer->SetKernAsianPunctuation( (sal_Bool)nAsianKerning );
824 }
825 
826 void ScDocument::ApplyAsianEditSettings( ScEditEngineDefaulter& rEngine )
827 {
828     rEngine.SetForbiddenCharsTable( xForbiddenCharacters );
829     rEngine.SetAsianCompressionMode( GetAsianCompression() );
830     rEngine.SetKernAsianPunctuation( GetAsianKerning() );
831 }
832 
833