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