Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / documen2.cxx
blobae9cbd9dbcc6a19d5df4eb761539b8fecbeabf5c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <editeng/editeng.hxx>
24 #include <editeng/forbiddencharacterstable.hxx>
25 #include <osl/thread.h>
26 #include <svx/xtable.hxx>
27 #include <sfx2/linkmgr.hxx>
28 #include <svx/svdpool.hxx>
29 #include <svx/svdobj.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <sfx2/printer.hxx>
34 #include <svl/zforlist.hxx>
35 #include <svl/zformat.hxx>
36 #include <vcl/virdev.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <svl/PasswordHelper.hxx>
39 #include "svl/sharedstringpool.hxx"
40 #include <tools/tenccvt.hxx>
41 #include <tools/urlobj.hxx>
42 #include <rtl/crc.h>
43 #include <basic/basmgr.hxx>
45 #include "document.hxx"
46 #include "table.hxx"
47 #include "attrib.hxx"
48 #include "patattr.hxx"
49 #include "rangenam.hxx"
50 #include "dbdata.hxx"
51 #include "pivot.hxx"
52 #include "docpool.hxx"
53 #include "stlpool.hxx"
54 #include "stlsheet.hxx"
55 #include "globstr.hrc"
56 #include "chartarr.hxx"
57 #include "chartlock.hxx"
58 #include "rechead.hxx"
59 #include "global.hxx"
60 #include "brdcst.hxx"
61 #include "bcaslot.hxx"
62 #include "adiasync.hxx"
63 #include "addinlis.hxx"
64 #include "chartlis.hxx"
65 #include "markdata.hxx"
66 #include "conditio.hxx"
67 #include "colorscale.hxx"
68 #include "validat.hxx"
69 #include "progress.hxx"
70 #include "detdata.hxx"
71 #include "sc.hrc"
72 #include "ddelink.hxx"
73 #include "chgtrack.hxx"
74 #include "chgviset.hxx"
75 #include "editutil.hxx"
76 #include "hints.hxx"
77 #include "dpobject.hxx"
78 #include "scrdata.hxx"
79 #include "poolhelp.hxx"
80 #include "unoreflist.hxx"
81 #include "listenercalls.hxx"
82 #include "recursionhelper.hxx"
83 #include "lookupcache.hxx"
84 #include "externalrefmgr.hxx"
85 #include "tabprotection.hxx"
86 #include "formulaparserpool.hxx"
87 #include "clipparam.hxx"
88 #include "macromgr.hxx"
89 #include "formulacell.hxx"
90 #include "clipcontext.hxx"
91 #include "refupdatecontext.hxx"
92 #include "refreshtimerprotector.hxx"
93 #include "scopetools.hxx"
94 #include "formulagroup.hxx"
95 #include "documentlinkmgr.hxx"
97 using namespace com::sun::star;
99 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
100 // dtor plus helpers are convenient.
101 struct ScLookupCacheMapImpl
103 ScLookupCacheMap aCacheMap;
104 ~ScLookupCacheMapImpl()
106 freeCaches();
108 void clear()
110 freeCaches();
111 // Zap map.
112 ScLookupCacheMap aTmp;
113 aCacheMap.swap( aTmp);
115 private:
116 void freeCaches()
118 for (ScLookupCacheMap::iterator it( aCacheMap.begin()); it != aCacheMap.end(); ++it)
119 delete (*it).second;
123 // STATIC DATA -----------------------------------------------------------
125 ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
126 mpCellStringPool(new svl::SharedStringPool(ScGlobal::pCharClass)),
127 mpFormulaGroupCxt(NULL),
128 mpUndoManager( NULL ),
129 pEditEngine( NULL ),
130 pNoteEngine( NULL ),
131 pShell( pDocShell ),
132 pPrinter( NULL ),
133 pVirtualDevice_100th_mm( NULL ),
134 pDrawLayer( NULL ),
135 pValidationList( NULL ),
136 pFormatExchangeList( NULL ),
137 pRangeName(NULL),
138 pDPCollection( NULL ),
139 pLinkManager( NULL ),
140 pFormulaTree( NULL ),
141 pEOFormulaTree( NULL ),
142 pFormulaTrack( NULL ),
143 pEOFormulaTrack( NULL ),
144 pClipData( NULL ),
145 pDetOpList(NULL),
146 pChangeTrack( NULL ),
147 pUnoBroadcaster( NULL ),
148 pUnoListenerCalls( NULL ),
149 pUnoRefUndoList( NULL ),
150 pChangeViewSettings( NULL ),
151 pScriptTypeData( NULL ),
152 pCacheFieldEditEngine( NULL ),
153 pDocProtection( NULL ),
154 mpClipParam( NULL),
155 pExternalRefMgr( NULL ),
156 mpMacroMgr( NULL ),
157 pViewOptions( NULL ),
158 pDocOptions( NULL ),
159 pExtDocOptions( NULL ),
160 pConsolidateDlgData( NULL ),
161 pRecursionHelper( NULL ),
162 pAutoNameCache( NULL ),
163 pLookupCacheMapImpl( NULL ),
164 pPreviewFont( NULL ),
165 pPreviewCellStyle( NULL ),
166 nUnoObjectId( 0 ),
167 nRangeOverflowType( 0 ),
168 aCurTextWidthCalcPos(MAXCOL,0,0),
169 aTableOpList( 0 ),
170 nFormulaCodeInTree(0),
171 nXMLImportedFormulaCount( 0 ),
172 nInterpretLevel(0),
173 nMacroInterpretLevel(0),
174 nInterpreterTableOpLevel(0),
175 nSrcVer( SC_CURRENT_VERSION ),
176 nSrcMaxRow( MAXROW ),
177 nFormulaTrackCount(0),
178 bHardRecalcState(false),
179 nVisibleTab( 0 ),
180 eLinkMode(LM_UNKNOWN),
181 bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
182 bAutoCalcShellDisabled( false ),
183 bForcedFormulaPending( false ),
184 bCalculatingFormulaTree( false ),
185 bIsClip( eMode == SCDOCMODE_CLIP ),
186 bIsUndo( eMode == SCDOCMODE_UNDO ),
187 bIsVisible( false ),
188 bIsEmbedded( false ),
189 bInsertingFromOtherDoc( false ),
190 bLoadingMedium( false ),
191 bImportingXML( false ),
192 bXMLFromWrapper( false ),
193 bCalcingAfterLoad( false ),
194 bNoListening( false ),
195 mbIdleEnabled(true),
196 bInLinkUpdate( false ),
197 bChartListenerCollectionNeedsUpdate( false ),
198 bHasForcedFormulas( false ),
199 bInDtorClear( false ),
200 bExpandRefs( false ),
201 bDetectiveDirty( false ),
202 nMacroCallMode( SC_MACROCALL_ALLOWED ),
203 bHasMacroFunc( false ),
204 nVisSpellState( 0 ),
205 nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
206 nAsianKerning(SC_ASIANKERNING_INVALID),
207 bPastingDrawFromOtherDoc( false ),
208 nInDdeLinkUpdate( 0 ),
209 bInUnoBroadcast( false ),
210 bInUnoListenerCall( false ),
211 eGrammar( formula::FormulaGrammar::GRAM_NATIVE ),
212 bStyleSheetUsageInvalid( true ),
213 mbUndoEnabled( true ),
214 mbAdjustHeightEnabled( true ),
215 mbExecuteLinkEnabled( true ),
216 mbChangeReadOnlyEnabled( false ),
217 mbStreamValidLocked( false ),
218 mbUserInteractionEnabled(true),
219 mnNamedRangesLockCount(0),
220 mbUseEmbedFonts(false)
222 SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
224 eSrcSet = osl_getThreadTextEncoding();
226 if ( eMode == SCDOCMODE_DOCUMENT )
228 if ( pDocShell )
229 pLinkManager = new sfx2::LinkManager( pDocShell );
231 xPoolHelper = new ScPoolHelper( this );
233 pBASM = new ScBroadcastAreaSlotMachine( this );
234 pChartListenerCollection = new ScChartListenerCollection( this );
235 pRefreshTimerControl = new ScRefreshTimerControl;
237 else
239 pBASM = NULL;
240 pChartListenerCollection = NULL;
241 pRefreshTimerControl = NULL;
243 pDBCollection = new ScDBCollection(this);
244 pSelectionAttr = NULL;
245 pChartCollection = new ScChartCollection;
246 apTemporaryChartLock.reset( new ScTemporaryChartLock(this) );
247 xColNameRanges = new ScRangePairList;
248 xRowNameRanges = new ScRangePairList;
249 ImplCreateOptions();
250 // languages for a visible document are set by docshell later (from options)
251 SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
253 aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
254 aTrackTimer.SetTimeout( 100 );
257 sfx2::LinkManager* ScDocument::GetLinkManager() const
259 if ( bAutoCalc && !pLinkManager && pShell)
261 pLinkManager = new sfx2::LinkManager( pShell );
263 return pLinkManager;
266 sc::DocumentLinkManager& ScDocument::GetDocLinkManager()
268 if (!mpDocLinkMgr)
269 mpDocLinkMgr.reset(new sc::DocumentLinkManager);
270 return *mpDocLinkMgr;
273 const sc::DocumentLinkManager& ScDocument::GetDocLinkManager() const
275 if (!mpDocLinkMgr)
276 mpDocLinkMgr.reset(new sc::DocumentLinkManager);
277 return *mpDocLinkMgr;
280 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
282 OSL_PRECOND(
283 eGram == formula::FormulaGrammar::GRAM_ODFF ||
284 eGram == formula::FormulaGrammar::GRAM_PODF,
285 "ScDocument::SetStorageGrammar: wrong storage grammar");
287 eStorageGrammar = eGram;
289 // FIXME: the XML import shouldn't strip brackets, the compiler should
290 // digest them instead, which could also speedup reference recognition
291 // during import.
293 eXmlImportGrammar = formula::FormulaGrammar::mergeToGrammar( eGram,
294 formula::FormulaGrammar::CONV_OOO);
298 void ScDocument::SetDocVisible( bool bSet )
300 // called from view ctor - only for a visible document,
301 // each new sheet's RTL flag is initialized from the locale
302 bIsVisible = bSet;
306 sal_uInt32 ScDocument::GetDocumentID() const
308 const ScDocument* pThis = this;
309 sal_uInt32 nCrc = rtl_crc32( 0, &pThis, sizeof(ScDocument*) );
310 // the this pointer only might not be sufficient
311 nCrc = rtl_crc32( nCrc, &pShell, sizeof(SfxObjectShell*) );
312 return nCrc;
316 void ScDocument::StartChangeTracking()
318 if (!pChangeTrack)
319 pChangeTrack = new ScChangeTrack( this );
322 void ScDocument::EndChangeTracking()
324 delete pChangeTrack;
325 pChangeTrack = NULL;
328 void ScDocument::SetChangeTrack( ScChangeTrack* pTrack )
330 OSL_ENSURE( pTrack->GetDocument() == this, "SetChangeTrack: different documents" );
331 if ( !pTrack || pTrack == pChangeTrack || pTrack->GetDocument() != this )
332 return ;
333 EndChangeTracking();
334 pChangeTrack = pTrack;
338 IMPL_LINK_NOARG(ScDocument, TrackTimeHdl)
340 if ( ScDdeLink::IsInUpdate() ) // nicht verschachteln
342 aTrackTimer.Start(); // spaeter nochmal versuchen
344 else if (pShell) // ausfuehren
346 TrackFormulas();
347 pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
349 // modified...
351 if (!pShell->IsModified())
353 pShell->SetModified( true );
354 SfxBindings* pBindings = GetViewBindings();
355 if (pBindings)
357 pBindings->Invalidate( SID_SAVEDOC );
358 pBindings->Invalidate( SID_DOC_MODIFIED );
363 return 0;
366 void ScDocument::StartTrackTimer()
368 if (!aTrackTimer.IsActive()) // nicht ewig aufschieben
369 aTrackTimer.Start();
372 ScDocument::~ScDocument()
374 OSL_PRECOND( !bInLinkUpdate, "bInLinkUpdate in dtor" );
376 bInDtorClear = true;
378 // first of all disable all refresh timers by deleting the control
379 if ( pRefreshTimerControl )
380 { // To be sure there isn't anything running do it with a protector,
381 // this ensures also that nothing needs the control anymore.
382 ScRefreshTimerProtector aProt( GetRefreshTimerControlAddress() );
383 delete pRefreshTimerControl, pRefreshTimerControl = NULL;
386 // Links aufrauemen
388 if ( GetLinkManager() )
390 // BaseLinks freigeben
391 ::sfx2::SvLinkSources aTemp(pLinkManager->GetServers());
392 for( ::sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it )
393 (*it)->Closed();
395 if ( pLinkManager->GetLinks().size() )
396 pLinkManager->Remove( 0, pLinkManager->GetLinks().size() );
399 mxFormulaParserPool.reset();
400 // Destroy the external ref mgr instance here because it has a timer
401 // which needs to be stopped before the app closes.
402 pExternalRefMgr.reset();
404 ScAddInAsync::RemoveDocument( this );
405 ScAddInListener::RemoveDocument( this );
406 DELETEZ( pChartListenerCollection); // vor pBASM wg. evtl. Listener!
407 DELETEZ( pLookupCacheMapImpl); // before pBASM because of listeners
408 // BroadcastAreas vor allen Zellen zerstoeren um unnoetige
409 // Einzel-EndListenings der Formelzellen zu vermeiden
410 delete pBASM; // BroadcastAreaSlotMachine
411 pBASM = NULL;
413 delete pUnoBroadcaster; // broadcasted nochmal SFX_HINT_DYING
414 pUnoBroadcaster = NULL;
416 delete pUnoRefUndoList;
417 delete pUnoListenerCalls;
419 Clear( true ); // true = from destructor (needed for SdrModel::ClearModel)
421 if (pValidationList)
423 for( ScValidationDataList::iterator it = pValidationList->begin(); it != pValidationList->end(); ++it )
424 delete *it;
425 pValidationList->clear();
426 DELETEZ(pValidationList);
428 delete pRangeName;
429 delete pDBCollection;
430 delete pSelectionAttr;
431 apTemporaryChartLock.reset();
432 delete pChartCollection;
433 DeleteDrawLayer();
434 delete pFormatExchangeList;
435 delete pPrinter;
436 ImplDeleteOptions();
437 delete pConsolidateDlgData;
438 delete pLinkManager;
439 delete pClipData;
440 delete pDetOpList; // loescht auch die Eintraege
441 delete pChangeTrack;
442 delete pEditEngine;
443 delete pNoteEngine;
444 delete pChangeViewSettings; // und weg damit
445 delete pVirtualDevice_100th_mm;
447 delete pDPCollection;
449 // delete the EditEngine before destroying the xPoolHelper
450 delete pCacheFieldEditEngine;
452 if ( xPoolHelper.is() && !bIsClip )
453 xPoolHelper->SourceDocumentGone();
454 xPoolHelper.clear();
456 delete pScriptTypeData;
457 delete pRecursionHelper;
459 delete pPreviewFont;
460 OSL_POSTCOND( !pAutoNameCache, "AutoNameCache still set in dtor" );
462 mpFormulaGroupCxt.reset();
463 mpCellStringPool.reset();
466 void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
468 OSL_ENSURE(bIsClip, "InitClipPtrs and not bIsClip");
470 if (pValidationList)
472 for(ScValidationDataList::iterator it = pValidationList->begin(); it != pValidationList->end(); ++it )
473 delete *it;
474 pValidationList->clear();
475 DELETEZ(pValidationList);
478 Clear();
480 xPoolHelper = pSourceDoc->xPoolHelper;
482 // bedingte Formate / Gueltigkeiten
483 //! Vorlagen kopieren?
484 const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
485 if ( pSourceValid )
486 pValidationList = new ScValidationDataList(this, *pSourceValid);
488 // Links in Stream speichern
489 delete pClipData;
490 if (pSourceDoc->HasDdeLinks())
492 pClipData = new SvMemoryStream;
493 pSourceDoc->SaveDdeLinks(*pClipData);
495 else
496 pClipData = NULL;
498 // Options pointers exist (ImplCreateOptions) for any document.
499 // Must be copied for correct results in OLE objects (#i42666#).
500 SetDocOptions( pSourceDoc->GetDocOptions() );
501 SetViewOptions( pSourceDoc->GetViewOptions() );
504 SvNumberFormatter* ScDocument::GetFormatTable() const
506 return xPoolHelper->GetFormTable();
509 SvNumberFormatter* ScDocument::CreateFormatTable() const
511 return xPoolHelper->CreateNumberFormatter();
514 SfxItemPool* ScDocument::GetEditPool() const
516 return xPoolHelper->GetEditPool();
519 SfxItemPool* ScDocument::GetEnginePool() const
521 return xPoolHelper->GetEnginePool();
524 ScFieldEditEngine& ScDocument::GetEditEngine()
526 if ( !pEditEngine )
528 pEditEngine = new ScFieldEditEngine(this, GetEnginePool(), GetEditPool());
529 pEditEngine->SetUpdateMode( false );
530 pEditEngine->EnableUndo( false );
531 pEditEngine->SetRefMapMode( MAP_100TH_MM );
532 ApplyAsianEditSettings( *pEditEngine );
534 return *pEditEngine;
537 ScNoteEditEngine& ScDocument::GetNoteEngine()
539 if ( !pNoteEngine )
541 pNoteEngine = new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
542 pNoteEngine->SetUpdateMode( false );
543 pNoteEngine->EnableUndo( false );
544 pNoteEngine->SetRefMapMode( MAP_100TH_MM );
545 ApplyAsianEditSettings( *pNoteEngine );
546 const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet();
547 SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() );
548 ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
549 pNoteEngine->SetDefaults( pEEItemSet ); // edit engine takes ownership
551 return *pNoteEngine;
555 void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks )
557 if (bIsClip)
559 InitClipPtrs(pSourceDoc);
561 for (SCTAB i = 0; i < static_cast<SCTAB>(pSourceDoc->maTabs.size()); i++)
562 if (pSourceDoc->maTabs[i])
563 if (!pMarks || pMarks->GetTableSelect(i))
565 OUString aString;
566 pSourceDoc->maTabs[i]->GetName(aString);
567 if ( i < static_cast<SCTAB>(maTabs.size()) )
569 maTabs[i] = new ScTable(this, i, aString);
572 else
574 if( i > static_cast<SCTAB>(maTabs.size()) )
576 maTabs.resize(i, NULL );
578 maTabs.push_back(new ScTable(this, i, aString));
580 maTabs[i]->SetLayoutRTL( pSourceDoc->maTabs[i]->IsLayoutRTL() );
583 else
585 OSL_FAIL("ResetClip");
589 void ScDocument::ResetClip( ScDocument* pSourceDoc, SCTAB nTab )
591 if (bIsClip)
593 InitClipPtrs(pSourceDoc);
594 if (nTab >= static_cast<SCTAB>(maTabs.size()))
596 maTabs.resize(nTab+1, NULL );
598 maTabs[nTab] = new ScTable(this, nTab,
599 OUString("baeh"));
600 if (nTab < static_cast<SCTAB>(pSourceDoc->maTabs.size()) && pSourceDoc->maTabs[nTab])
601 maTabs[nTab]->SetLayoutRTL( pSourceDoc->maTabs[nTab]->IsLayoutRTL() );
603 else
605 OSL_FAIL("ResetClip");
609 void ScDocument::EnsureTable( SCTAB nTab )
611 bool bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
612 if (static_cast<size_t>(nTab) >= maTabs.size())
613 maTabs.resize(nTab+1, NULL);
615 if (!maTabs[nTab])
616 maTabs[nTab] = new ScTable(this, nTab, "temp", bExtras, bExtras);
619 ScRefCellValue ScDocument::GetRefCellValue( const ScAddress& rPos )
621 if (!TableExists(rPos.Tab()))
622 return ScRefCellValue(); // empty
624 return maTabs[rPos.Tab()]->GetRefCellValue(rPos.Col(), rPos.Row());
627 svl::SharedStringPool& ScDocument::GetSharedStringPool()
629 return *mpCellStringPool;
632 const svl::SharedStringPool& ScDocument::GetSharedStringPool() const
634 return *mpCellStringPool;
637 bool ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
638 bool bNotes ) const
640 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
642 bool bAny = maTabs[nTab]->GetPrintArea( rEndCol, rEndRow, bNotes );
643 if (pDrawLayer)
645 ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
646 if (DrawGetPrintArea( aDrawRange, true, true ))
648 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
649 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
650 bAny = true;
653 return bAny;
656 rEndCol = 0;
657 rEndRow = 0;
658 return false;
661 bool ScDocument::GetPrintAreaHor( SCTAB nTab, SCROW nStartRow, SCROW nEndRow,
662 SCCOL& rEndCol, bool bNotes ) const
664 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
666 bool bAny = maTabs[nTab]->GetPrintAreaHor( nStartRow, nEndRow, rEndCol, bNotes );
667 if (pDrawLayer)
669 ScRange aDrawRange(0,nStartRow,nTab, MAXCOL,nEndRow,nTab);
670 if (DrawGetPrintArea( aDrawRange, true, false ))
672 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
673 bAny = true;
676 return bAny;
679 rEndCol = 0;
680 return false;
683 bool ScDocument::GetPrintAreaVer( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol,
684 SCROW& rEndRow, bool bNotes ) const
686 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
688 bool bAny = maTabs[nTab]->GetPrintAreaVer( nStartCol, nEndCol, rEndRow, bNotes );
689 if (pDrawLayer)
691 ScRange aDrawRange(nStartCol,0,nTab, nEndCol,MAXROW,nTab);
692 if (DrawGetPrintArea( aDrawRange, false, true ))
694 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
695 bAny = true;
698 return bAny;
701 rEndRow = 0;
702 return false;
705 bool ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const
707 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
709 bool bAny = maTabs[nTab]->GetDataStart( rStartCol, rStartRow );
710 if (pDrawLayer)
712 ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
713 if (DrawGetPrintArea( aDrawRange, true, true ))
715 if (aDrawRange.aStart.Col()<rStartCol) rStartCol=aDrawRange.aStart.Col();
716 if (aDrawRange.aStart.Row()<rStartRow) rStartRow=aDrawRange.aStart.Row();
717 bAny = true;
720 return bAny;
723 rStartCol = 0;
724 rStartRow = 0;
725 return false;
728 bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos, ScProgress* pProgress )
730 if (nOldPos == nNewPos)
731 return false;
733 SCTAB nTabCount = static_cast<SCTAB>(maTabs.size());
734 if(nTabCount < 2)
735 return false;
737 bool bValid = false;
738 if (ValidTab(nOldPos) && nOldPos < nTabCount )
740 if (maTabs[nOldPos])
742 sc::AutoCalcSwitch aACSwitch(*this, false);
744 SetNoListening( true );
745 if (nNewPos == SC_TAB_APPEND || nNewPos >= nTabCount)
746 nNewPos = nTabCount-1;
748 // Referenz-Updaterei
749 //! mit UpdateReference zusammenfassen!
751 sc::RefUpdateMoveTabContext aCxt(nOldPos, nNewPos);
753 SCsTAB nDz = ((SCsTAB)nNewPos) - (SCsTAB)nOldPos;
754 ScRange aSourceRange( 0,0,nOldPos, MAXCOL,MAXROW,nOldPos );
755 if (pRangeName)
756 pRangeName->UpdateMoveTab(aCxt);
758 pDBCollection->UpdateMoveTab( nOldPos, nNewPos );
759 xColNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
760 xRowNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
761 if (pDPCollection)
762 pDPCollection->UpdateReference( URM_REORDER, aSourceRange, 0,0,nDz );
763 if (pDetOpList)
764 pDetOpList->UpdateReference( this, URM_REORDER, aSourceRange, 0,0,nDz );
765 UpdateChartRef( URM_REORDER,
766 0,0,nOldPos, MAXCOL,MAXROW,nOldPos, 0,0,nDz );
767 UpdateRefAreaLinks( URM_REORDER, aSourceRange, 0,0,nDz );
768 if ( pValidationList )
769 pValidationList->UpdateMoveTab(aCxt);
770 if ( pUnoBroadcaster )
771 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_REORDER,
772 aSourceRange, 0,0,nDz ) );
774 ScTable* pSaveTab = maTabs[nOldPos];
775 maTabs.erase(maTabs.begin()+nOldPos);
776 maTabs.insert(maTabs.begin()+nNewPos, pSaveTab);
777 TableContainer::iterator it = maTabs.begin();
778 for (SCTAB i = 0; i < nTabCount; i++)
779 if (maTabs[i])
780 maTabs[i]->UpdateMoveTab(aCxt, i, pProgress);
781 it = maTabs.begin();
782 for (; it != maTabs.end(); ++it)
783 if (*it)
784 (*it)->UpdateCompile();
785 SetNoListening( false );
786 it = maTabs.begin();
787 for (; it != maTabs.end(); ++it)
788 if (*it)
789 (*it)->StartAllListeners();
790 // sheet names of references may not be valid until sheet is moved
791 pChartListenerCollection->UpdateScheduledSeriesRanges();
792 SetDirty();
794 if (pDrawLayer)
795 DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
797 bValid = true;
800 return bValid;
803 bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked )
805 if (SC_TAB_APPEND == nNewPos || nNewPos >= static_cast<SCTAB>(maTabs.size()))
806 nNewPos = static_cast<SCTAB>(maTabs.size());
807 OUString aName;
808 GetName(nOldPos, aName);
810 // vorneweg testen, ob der Prefix als gueltig erkannt wird
811 // wenn nicht, nur doppelte vermeiden
812 bool bPrefix = ValidTabName( aName );
813 OSL_ENSURE(bPrefix, "invalid table name");
814 SCTAB nDummy;
816 CreateValidTabName(aName);
818 bool bValid;
819 if (bPrefix)
820 bValid = ValidNewTabName(aName);
821 else
822 bValid = !GetTable( aName, nDummy );
824 sc::AutoCalcSwitch aACSwitch(*this, false);
825 sc::RefUpdateInsertTabContext aCxt(nNewPos, 1);
827 if (bValid)
829 if (nNewPos >= static_cast<SCTAB>(maTabs.size()))
831 nNewPos = static_cast<SCTAB>(maTabs.size());
832 maTabs.push_back(new ScTable(this, nNewPos, aName));
834 else
836 if (ValidTab(nNewPos) && (nNewPos < static_cast<SCTAB>(maTabs.size())))
838 SetNoListening( true );
840 ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
841 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
842 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
843 if (pRangeName)
844 pRangeName->UpdateInsertTab(aCxt);
846 pDBCollection->UpdateReference(
847 URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
848 if (pDPCollection)
849 pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
850 if (pDetOpList)
851 pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
852 UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
853 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
854 if ( pUnoBroadcaster )
855 pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
857 SCTAB i;
858 for (TableContainer::iterator it = maTabs.begin(); it != maTabs.end(); ++it)
859 if (*it && it != (maTabs.begin() + nOldPos))
860 (*it)->UpdateInsertTab(aCxt);
861 maTabs.push_back(NULL);
862 for (i = static_cast<SCTAB>(maTabs.size())-1; i > nNewPos; i--)
863 maTabs[i] = maTabs[i - 1];
864 if (nNewPos <= nOldPos)
865 nOldPos++;
866 maTabs[nNewPos] = new ScTable(this, nNewPos, aName);
867 bValid = true;
868 for (TableContainer::iterator it = maTabs.begin(); it != maTabs.end(); ++it)
869 if (*it && it != maTabs.begin()+nOldPos && it != maTabs.begin() + nNewPos)
870 (*it)->UpdateCompile();
871 SetNoListening( false );
872 for (TableContainer::iterator it = maTabs.begin(); it != maTabs.end(); ++it)
873 if (*it && it != maTabs.begin()+nOldPos && it != maTabs.begin()+nNewPos)
874 (*it)->StartAllListeners();
876 if (pValidationList)
877 pValidationList->UpdateInsertTab(aCxt);
879 // sheet names of references may not be valid until sheet is copied
880 pChartListenerCollection->UpdateScheduledSeriesRanges();
882 else
883 bValid = false;
887 if (bValid)
889 SetNoListening( true ); // noch nicht bei CopyToTable/Insert
890 sc::CopyToDocContext aCopyDocCxt(*this);
891 maTabs[nOldPos]->CopyToTable(aCopyDocCxt, 0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
892 maTabs[nNewPos], pOnlyMarked );
893 maTabs[nNewPos]->SetTabBgColor(maTabs[nOldPos]->GetTabBgColor());
895 SCTAB nDz = nNewPos - nOldPos;
896 sc::RefUpdateContext aRefCxt(*this);
897 aRefCxt.meMode = URM_COPY;
898 aRefCxt.maRange = ScRange(0, 0, nNewPos, MAXCOL, MAXROW, nNewPos);
899 aRefCxt.mnTabDelta = nDz;
900 maTabs[nNewPos]->UpdateReference(aRefCxt, NULL);
902 sc::RefUpdateInsertTabContext aInsTabCxt(nNewPos, 1);
903 maTabs[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
904 maTabs[nOldPos]->UpdateInsertTab(aInsTabCxt);
906 maTabs[nOldPos]->UpdateCompile();
907 maTabs[nNewPos]->UpdateCompile( true ); // maybe already compiled in Clone, but used names need recompilation
908 SetNoListening( false );
909 maTabs[nOldPos]->StartAllListeners();
910 maTabs[nNewPos]->StartAllListeners();
912 ScConditionalFormatList* pNewList = new ScConditionalFormatList(*maTabs[nOldPos]->GetCondFormList());
913 pNewList->UpdateReference(aRefCxt);
914 maTabs[nNewPos]->SetCondFormList( pNewList );
916 SetDirty();
918 if (pDrawLayer)
919 DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
921 if (pDPCollection)
922 pDPCollection->CopyToTab(nOldPos, nNewPos);
924 maTabs[nNewPos]->SetPageStyle( maTabs[nOldPos]->GetPageStyle() );
925 maTabs[nNewPos]->SetPendingRowHeights( maTabs[nOldPos]->IsPendingRowHeights() );
927 // Copy the custom print range if exists.
928 maTabs[nNewPos]->CopyPrintRange(*maTabs[nOldPos]);
930 // Copy the RTL settings
931 maTabs[nNewPos]->SetLayoutRTL(maTabs[nOldPos]->IsLayoutRTL());
932 maTabs[nNewPos]->SetLoadingRTL(maTabs[nOldPos]->IsLoadingRTL());
935 return bValid;
938 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sModuleName, const OUString& sModuleSource );
940 sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
941 SCTAB nDestPos, bool bInsertNew,
942 bool bResultsOnly )
944 sal_uLong nRetVal = 1; // 0 => Fehler 1 = ok
945 // 3 => NameBox
946 // 4 => beides
948 if (pSrcDoc->pShell->GetMedium())
950 pSrcDoc->maFileURL = pSrcDoc->pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
951 // for unsaved files use the title name and adjust during save of file
952 if (pSrcDoc->maFileURL.isEmpty())
953 pSrcDoc->maFileURL = pSrcDoc->pShell->GetName();
955 else
957 pSrcDoc->maFileURL = pSrcDoc->pShell->GetName();
960 bool bValid = true;
961 if (bInsertNew) // neu einfuegen
963 OUString aName;
964 pSrcDoc->GetName(nSrcPos, aName);
965 CreateValidTabName(aName);
966 bValid = InsertTab(nDestPos, aName);
968 // Copy the RTL settings
969 maTabs[nDestPos]->SetLayoutRTL(pSrcDoc->maTabs[nSrcPos]->IsLayoutRTL());
970 maTabs[nDestPos]->SetLoadingRTL(pSrcDoc->maTabs[nSrcPos]->IsLoadingRTL());
972 else // bestehende Tabelle ersetzen
974 if (ValidTab(nDestPos) && nDestPos < static_cast<SCTAB>(maTabs.size()) && maTabs[nDestPos])
976 maTabs[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
978 else
979 bValid = false;
982 if (bValid)
984 bool bOldAutoCalcSrc = false;
985 bool bOldAutoCalc = GetAutoCalc();
986 SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
987 SetNoListening( true );
988 if ( bResultsOnly )
990 bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
991 pSrcDoc->SetAutoCalc( true ); // falls was berechnet werden muss
995 NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
997 sc::CopyToDocContext aCxt(*this);
998 nDestPos = std::min(nDestPos, (SCTAB)(GetTableCount() - 1));
999 { // scope for bulk broadcast
1000 ScBulkBroadcast aBulkBroadcast( pBASM);
1001 pSrcDoc->maTabs[nSrcPos]->CopyToTable(aCxt, 0, 0, MAXCOL, MAXROW,
1002 ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
1003 false, maTabs[nDestPos] );
1004 maTabs[nDestPos]->CopyConditionalFormat(0, 0, MAXCOL, MAXROW,
1005 0, 0, pSrcDoc->maTabs[nSrcPos]);
1008 maTabs[nDestPos]->SetTabNo(nDestPos);
1009 maTabs[nDestPos]->SetTabBgColor(pSrcDoc->maTabs[nSrcPos]->GetTabBgColor());
1011 if ( !bResultsOnly )
1013 sc::RefUpdateContext aRefCxt(*this);
1014 aRefCxt.meMode = URM_COPY;
1015 aRefCxt.maRange = ScRange(0, 0, nDestPos, MAXCOL, MAXROW, nDestPos);
1016 aRefCxt.mnTabDelta = nDestPos - nSrcPos;
1017 maTabs[nDestPos]->UpdateReference(aRefCxt, NULL);
1019 // Readjust self-contained absolute references to this sheet
1020 maTabs[nDestPos]->TestTabRefAbs(nSrcPos);
1021 maTabs[nDestPos]->CompileAll();
1024 SetNoListening( false );
1025 if ( !bResultsOnly )
1026 maTabs[nDestPos]->StartAllListeners();
1027 SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
1029 if ( bResultsOnly )
1030 pSrcDoc->SetAutoCalc( bOldAutoCalcSrc );
1031 SetAutoCalc( bOldAutoCalc );
1033 // Drawing kopieren
1035 if (bInsertNew)
1036 TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
1038 maTabs[nDestPos]->SetPendingRowHeights( pSrcDoc->maTabs[nSrcPos]->IsPendingRowHeights() );
1040 if (!bValid)
1041 nRetVal = 0;
1042 bool bVbaEnabled = IsInVBAMode();
1044 if ( bVbaEnabled )
1046 SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL;
1047 if ( pSrcShell )
1049 OUString aLibName("Standard");
1050 const BasicManager *pBasicManager = pSrcShell->GetBasicManager();
1051 if (pBasicManager && !pBasicManager->GetName().isEmpty())
1053 aLibName = pSrcShell->GetBasicManager()->GetName();
1055 OUString sCodeName;
1056 OUString sSource;
1057 uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
1058 uno::Reference< container::XNameContainer > xLib;
1059 if( xLibContainer.is() )
1061 uno::Any aLibAny = xLibContainer->getByName(aLibName);
1062 aLibAny >>= xLib;
1065 if( xLib.is() )
1067 OUString sSrcCodeName;
1068 pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName );
1069 OUString sRTLSource;
1070 xLib->getByName( sSrcCodeName ) >>= sRTLSource;
1071 sSource = sRTLSource;
1073 VBA_InsertModule( *this, nDestPos, sCodeName, sSource );
1077 return nRetVal;
1080 void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError)
1082 if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
1083 if (maTabs[nTab])
1084 maTabs[nTab]->SetError( nCol, nRow, nError );
1087 void ScDocument::SetFormula(
1088 const ScAddress& rPos, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram )
1090 if (!TableExists(rPos.Tab()))
1091 return;
1093 maTabs[rPos.Tab()]->SetFormula(rPos.Col(), rPos.Row(), rArray, eGram);
1096 void ScDocument::SetFormula(
1097 const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram )
1099 if (!TableExists(rPos.Tab()))
1100 return;
1102 maTabs[rPos.Tab()]->SetFormula(rPos.Col(), rPos.Row(), rFormula, eGram);
1105 ScFormulaCell* ScDocument::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell )
1107 if (!TableExists(rPos.Tab()))
1109 delete pCell;
1110 return NULL;
1113 return maTabs[rPos.Tab()]->SetFormulaCell(rPos.Col(), rPos.Row(), pCell);
1116 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
1118 delete pConsolidateDlgData;
1120 if ( pData )
1121 pConsolidateDlgData = new ScConsolidateParam( *pData );
1122 else
1123 pConsolidateDlgData = NULL;
1126 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings& rNew)
1128 if (pChangeViewSettings==NULL)
1129 pChangeViewSettings = new ScChangeViewSettings;
1131 OSL_ENSURE( pChangeViewSettings, "Oops. No ChangeViewSettings :-( by!" );
1133 *pChangeViewSettings=rNew;
1136 // ----------------------------------------------------------------------------
1138 ScFieldEditEngine* ScDocument::CreateFieldEditEngine()
1140 ScFieldEditEngine* pNewEditEngine = NULL;
1141 if (!pCacheFieldEditEngine)
1143 pNewEditEngine = new ScFieldEditEngine(
1144 this, GetEnginePool(), GetEditPool(), false);
1146 else
1148 if ( !bImportingXML )
1150 // #i66209# previous use might not have restored update mode,
1151 // ensure same state as for a new EditEngine (UpdateMode = true)
1152 if ( !pCacheFieldEditEngine->GetUpdateMode() )
1153 pCacheFieldEditEngine->SetUpdateMode(true);
1156 pNewEditEngine = pCacheFieldEditEngine;
1157 pCacheFieldEditEngine = NULL;
1159 return pNewEditEngine;
1162 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine)
1164 if (!pCacheFieldEditEngine && rpEditEngine)
1166 pCacheFieldEditEngine = rpEditEngine;
1167 pCacheFieldEditEngine->Clear();
1169 else
1170 delete rpEditEngine;
1171 rpEditEngine = NULL;
1174 // ----------------------------------------------------------------------------
1176 ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
1178 return new ScRecursionHelper;
1181 // ----------------------------------------------------------------------------
1183 ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
1185 ScLookupCache* pCache = 0;
1186 if (!pLookupCacheMapImpl)
1187 pLookupCacheMapImpl = new ScLookupCacheMapImpl;
1188 ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find( rRange));
1189 if (it == pLookupCacheMapImpl->aCacheMap.end())
1191 pCache = new ScLookupCache( this, rRange);
1192 AddLookupCache( *pCache);
1194 else
1195 pCache = (*it).second;
1196 return *pCache;
1199 void ScDocument::AddLookupCache( ScLookupCache & rCache )
1201 if (!pLookupCacheMapImpl->aCacheMap.insert( ::std::pair< const ScRange,
1202 ScLookupCache*>( rCache.getRange(), &rCache)).second)
1204 OSL_FAIL( "ScDocument::AddLookupCache: couldn't add to hash map");
1206 else
1207 StartListeningArea( rCache.getRange(), &rCache);
1210 void ScDocument::RemoveLookupCache( ScLookupCache & rCache )
1212 ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find(
1213 rCache.getRange()));
1214 if (it == pLookupCacheMapImpl->aCacheMap.end())
1216 OSL_FAIL( "ScDocument::RemoveLookupCache: range not found in hash map");
1218 else
1220 ScLookupCache* pCache = (*it).second;
1221 pLookupCacheMapImpl->aCacheMap.erase( it);
1222 EndListeningArea( pCache->getRange(), &rCache);
1226 void ScDocument::ClearLookupCaches()
1228 if( pLookupCacheMapImpl )
1229 pLookupCacheMapImpl->clear();
1232 void ScDocument::SetPreviewFont( SfxItemSet* pFont )
1234 delete pPreviewFont;
1235 pPreviewFont = pFont;
1238 const ScMarkData ScDocument::GetPreviewSelection()
1240 return maPreviewSelection;
1243 void ScDocument::SetPreviewSelection( ScMarkData& rSel )
1245 maPreviewSelection = rSel;
1248 SfxItemSet* ScDocument::GetPreviewFont( SCCOL nCol, SCROW nRow, SCTAB nTab )
1250 SfxItemSet* pRet = NULL;
1251 if ( pPreviewFont )
1253 ScMarkData aSel = GetPreviewSelection();
1254 if ( aSel.IsCellMarked( nCol, nRow ) && aSel.GetFirstSelected() == nTab )
1255 pRet = pPreviewFont;
1257 return pRet;
1260 ScStyleSheet* ScDocument::GetPreviewCellStyle( SCCOL nCol, SCROW nRow, SCTAB nTab )
1262 ScStyleSheet* pRet = NULL;
1263 ScMarkData aSel = GetPreviewSelection();
1264 if ( pPreviewCellStyle && aSel.IsCellMarked( nCol, nRow ) && aSel.GetFirstSelected() == nTab )
1265 pRet = pPreviewCellStyle;
1266 return pRet;
1268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */