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