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