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