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