xref: /trunk/main/sc/source/core/data/documen2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #define _ZFORLIST_DECLARE_TABLE
34 #include "scitems.hxx"
35 #include <editeng/eeitem.hxx>
36 
37 #include <editeng/editeng.hxx>
38 #include <editeng/forbiddencharacterstable.hxx>
39 #include <sfx2/linkmgr.hxx>
40 #include <svx/svdpool.hxx>
41 #include <svx/svdobj.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/objsh.hxx>
44 #include <sfx2/printer.hxx>
45 #include <svl/zforlist.hxx>
46 #include <svl/zformat.hxx>
47 #include <vcl/virdev.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <svl/PasswordHelper.hxx>
50 #include <tools/tenccvt.hxx>
51 #include <tools/list.hxx>
52 #include <rtl/crc.h>
53 #include <basic/basmgr.hxx>
54 
55 #include "document.hxx"
56 #include "table.hxx"
57 #include "attrib.hxx"
58 #include "patattr.hxx"
59 #include "rangenam.hxx"
60 #include "dbcolect.hxx"
61 #include "pivot.hxx"
62 #include "docpool.hxx"
63 #include "stlpool.hxx"
64 #include "stlsheet.hxx"
65 #include "globstr.hrc"
66 #include "chartarr.hxx"
67 #include "chartlock.hxx"
68 #include "rechead.hxx"
69 #include "global.hxx"
70 #include "brdcst.hxx"
71 #include "bcaslot.hxx"
72 #include "adiasync.hxx"
73 #include "addinlis.hxx"
74 #include "chartlis.hxx"
75 #include "markdata.hxx"
76 #include "conditio.hxx"
77 #include "validat.hxx"
78 #include "progress.hxx"
79 #include "detdata.hxx"
80 #include "sc.hrc"               // FID_DATACHANGED
81 #include "ddelink.hxx"
82 #include "chgtrack.hxx"
83 #include "chgviset.hxx"
84 #include "editutil.hxx"
85 #include "hints.hxx"
86 #include "dpobject.hxx"
87 #include "scrdata.hxx"
88 #include "poolhelp.hxx"
89 #include "unoreflist.hxx"
90 #include "listenercalls.hxx"
91 #include "recursionhelper.hxx"
92 #include "lookupcache.hxx"
93 #include "externalrefmgr.hxx"
94 #include "tabprotection.hxx"
95 #include "formulaparserpool.hxx"
96 #include "clipparam.hxx"
97 
98 using namespace com::sun::star;
99 
100 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
101 // dtor plus helpers are convenient.
102 struct ScLookupCacheMapImpl
103 {
104     ScLookupCacheMap aCacheMap;
105     ~ScLookupCacheMapImpl()
106     {
107         freeCaches();
108     }
109     void clear()
110     {
111         freeCaches();
112         // Zap map.
113         ScLookupCacheMap aTmp;
114         aCacheMap.swap( aTmp);
115     }
116 private:
117     void freeCaches()
118     {
119         for (ScLookupCacheMap::iterator it( aCacheMap.begin()); it != aCacheMap.end(); ++it)
120             delete (*it).second;
121     }
122 };
123 
124 // STATIC DATA -----------------------------------------------------------
125 
126 ScDocument::ScDocument( ScDocumentMode  eMode,
127                         SfxObjectShell* pDocShell ) :
128         xServiceManager( ::comphelper::getProcessServiceFactory() ),
129         mpUndoManager( NULL ),
130         pEditEngine( NULL ),
131         pNoteEngine( NULL ),
132         pNoteItemPool( NULL ),
133         pShell( pDocShell ),
134         pPrinter( NULL ),
135         pVirtualDevice_100th_mm( NULL ),
136         pDrawLayer( NULL ),
137         pColorTable( NULL ),
138         pCondFormList( NULL ),
139         pValidationList( NULL ),
140         pFormatExchangeList( NULL ),
141         pDPCollection( NULL ),
142         pLinkManager( NULL ),
143         pFormulaTree( NULL ),
144         pEOFormulaTree( NULL ),
145         pFormulaTrack( NULL ),
146         pEOFormulaTrack( NULL ),
147         pOtherObjects( NULL ),
148         pClipData( NULL ),
149         pDetOpList(NULL),
150         pChangeTrack( NULL ),
151         pUnoBroadcaster( NULL ),
152         pUnoListenerCalls( NULL ),
153         pUnoRefUndoList( NULL ),
154         pChangeViewSettings( NULL ),
155         pScriptTypeData( NULL ),
156         pCacheFieldEditEngine( NULL ),
157         pDocProtection( NULL ),
158         mpClipParam( NULL),
159         pExternalRefMgr( NULL ),
160         pViewOptions( NULL ),
161         pDocOptions( NULL ),
162         pExtDocOptions( NULL ),
163         pConsolidateDlgData( NULL ),
164         pRecursionHelper( NULL ),
165         pAutoNameCache( NULL ),
166         pLookupCacheMapImpl( NULL ),
167         nUnoObjectId( 0 ),
168         nRangeOverflowType( 0 ),
169         aCurTextWidthCalcPos(MAXCOL,0,0),
170         nFormulaCodeInTree(0),
171         nXMLImportedFormulaCount( 0 ),
172         nInterpretLevel(0),
173         nMacroInterpretLevel(0),
174         nInterpreterTableOpLevel(0),
175         nMaxTableNumber( 0 ),
176         nSrcVer( SC_CURRENT_VERSION ),
177         nSrcMaxRow( MAXROW ),
178         nFormulaTrackCount(0),
179         nHardRecalcState(0),
180         nVisibleTab( 0 ),
181         eLinkMode(LM_UNKNOWN),
182         bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
183         bAutoCalcShellDisabled( sal_False ),
184         bForcedFormulaPending( sal_False ),
185         bCalculatingFormulaTree( sal_False ),
186         bIsClip( eMode == SCDOCMODE_CLIP ),
187         bIsUndo( eMode == SCDOCMODE_UNDO ),
188         bIsVisible( sal_False ),
189         bIsEmbedded( sal_False ),
190 //      bNoSetDirty( sal_True ),
191         bNoSetDirty( sal_False ),
192         bInsertingFromOtherDoc( sal_False ),
193         bLoadingMedium( false ),
194         bImportingXML( false ),
195         bXMLFromWrapper( sal_False ),
196         bCalcingAfterLoad( sal_False ),
197         bNoListening( sal_False ),
198         bIdleDisabled( sal_False ),
199         bInLinkUpdate( sal_False ),
200         bChartListenerCollectionNeedsUpdate( sal_False ),
201         bHasForcedFormulas( sal_False ),
202         bInDtorClear( sal_False ),
203         bExpandRefs( sal_False ),
204         bDetectiveDirty( sal_False ),
205         nMacroCallMode( SC_MACROCALL_ALLOWED ),
206         bHasMacroFunc( sal_False ),
207         nVisSpellState( 0 ),
208         nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
209         nAsianKerning(SC_ASIANKERNING_INVALID),
210         bSetDrawDefaults( sal_False ),
211         bPastingDrawFromOtherDoc( sal_False ),
212         nInDdeLinkUpdate( 0 ),
213         bInUnoBroadcast( sal_False ),
214         bInUnoListenerCall( sal_False ),
215         eGrammar( formula::FormulaGrammar::GRAM_NATIVE ),
216         bStyleSheetUsageInvalid( sal_True ),
217         mbUndoEnabled( true ),
218         mbAdjustHeightEnabled( true ),
219         mbExecuteLinkEnabled( true ),
220         mbChangeReadOnlyEnabled( false ),
221         mbStreamValidLocked( false ),
222         mnNamedRangesLockCount( 0 )
223 {
224     SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
225 
226     eSrcSet = gsl_getSystemTextEncoding();
227 
228     if ( eMode == SCDOCMODE_DOCUMENT )
229     {
230         if ( pDocShell )
231             pLinkManager = new sfx2::LinkManager( pDocShell );
232 
233         xPoolHelper = new ScPoolHelper( this );
234 
235         pTab[0]  = NULL;
236         pBASM = new ScBroadcastAreaSlotMachine( this );
237         pChartListenerCollection = new ScChartListenerCollection( this );
238         pRefreshTimerControl = new ScRefreshTimerControl;
239     }
240     else
241     {
242         pTab[0]     = NULL;
243         pBASM       = NULL;
244         pChartListenerCollection = NULL;
245         pRefreshTimerControl = NULL;
246     }
247 
248     for (SCTAB i=1; i<=MAXTAB; i++)
249         pTab[i] = NULL;
250 
251     pRangeName = new ScRangeName( 4, 4, sal_False, this );
252     pDBCollection = new ScDBCollection( 4, 4, sal_False, this );
253     pSelectionAttr = NULL;
254     pChartCollection = new ScChartCollection;
255     apTemporaryChartLock = std::auto_ptr< ScTemporaryChartLock >( new ScTemporaryChartLock(this) );
256     xColNameRanges = new ScRangePairList;
257     xRowNameRanges = new ScRangePairList;
258     ImplCreateOptions();
259     // languages for a visible document are set by docshell later (from options)
260     SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
261 
262     aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
263     aTrackTimer.SetTimeout( 100 );
264 }
265 
266 sfx2::LinkManager*  ScDocument::GetLinkManager()  const
267 {
268     if ( bAutoCalc && !pLinkManager && pShell)
269     {
270         pLinkManager = new sfx2::LinkManager( pShell );
271     }
272     return pLinkManager;
273 }
274 
275 
276 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
277 {
278     DBG_ASSERT(
279         eGram == formula::FormulaGrammar::GRAM_ODFF ||
280             eGram == formula::FormulaGrammar::GRAM_PODF,
281             "ScDocument::SetStorageGrammar: wrong storage grammar");
282 
283     eStorageGrammar = eGram;
284 
285     // FIXME: the XML import shouldn't strip brackets, the compiler should
286     // digest them instead, which could also speedup reference recognition
287     // during import.
288 
289     eXmlImportGrammar = formula::FormulaGrammar::mergeToGrammar( eGram,
290             formula::FormulaGrammar::CONV_OOO);
291 }
292 
293 
294 void ScDocument::SetDocVisible( sal_Bool bSet )
295 {
296     //  called from view ctor - only for a visible document,
297     //  each new sheet's RTL flag is initialized from the locale
298     bIsVisible = bSet;
299 }
300 
301 
302 sal_uInt32 ScDocument::GetDocumentID() const
303 {
304     const ScDocument* pThis = this;
305     sal_uInt32 nCrc = rtl_crc32( 0, &pThis, sizeof(ScDocument*) );
306     // the this pointer only might not be sufficient
307     nCrc = rtl_crc32( nCrc, &pShell, sizeof(SfxObjectShell*) );
308     return nCrc;
309 }
310 
311 
312 void ScDocument::StartChangeTracking()
313 {
314     if (!pChangeTrack)
315         pChangeTrack = new ScChangeTrack( this );
316 }
317 
318 void ScDocument::EndChangeTracking()
319 {
320     delete pChangeTrack;
321     pChangeTrack = NULL;
322 }
323 
324 void ScDocument::SetChangeTrack( ScChangeTrack* pTrack )
325 {
326     DBG_ASSERT( pTrack->GetDocument() == this, "SetChangeTrack: different documents" );
327     if ( !pTrack || pTrack == pChangeTrack || pTrack->GetDocument() != this )
328         return ;
329     EndChangeTracking();
330     pChangeTrack = pTrack;
331 }
332 
333 
334 IMPL_LINK( ScDocument, TrackTimeHdl, Timer*, EMPTYARG )
335 {
336     if ( ScDdeLink::IsInUpdate() )      // nicht verschachteln
337     {
338         aTrackTimer.Start();            // spaeter nochmal versuchen
339     }
340     else if (pShell)                    // ausfuehren
341     {
342         TrackFormulas();
343         pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
344         ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
345 
346             //  modified...
347 
348         if (!pShell->IsModified())
349         {
350             pShell->SetModified( sal_True );
351             SfxBindings* pBindings = GetViewBindings();
352             if (pBindings)
353             {
354                 pBindings->Invalidate( SID_SAVEDOC );
355                 pBindings->Invalidate( SID_DOC_MODIFIED );
356             }
357         }
358     }
359 
360     return 0;
361 }
362 
363 void ScDocument::StartTrackTimer()
364 {
365     if (!aTrackTimer.IsActive())        // nicht ewig aufschieben
366         aTrackTimer.Start();
367 }
368 
369 ScDocument::~ScDocument()
370 {
371     DBG_ASSERT( !bInLinkUpdate, "bInLinkUpdate in dtor" );
372 
373     bInDtorClear = sal_True;
374 
375     // first of all disable all refresh timers by deleting the control
376     if ( pRefreshTimerControl )
377     {   // To be sure there isn't anything running do it with a protector,
378         // this ensures also that nothing needs the control anymore.
379         ScRefreshTimerProtector aProt( GetRefreshTimerControlAddress() );
380         delete pRefreshTimerControl, pRefreshTimerControl = NULL;
381     }
382 
383     // Links aufrauemen
384 
385     if ( GetLinkManager() )
386     {
387         // BaseLinks freigeben
388         for ( sal_uInt16 n = pLinkManager->GetServers().Count(); n; )
389             pLinkManager->GetServers()[ --n ]->Closed();
390 
391         if ( pLinkManager->GetLinks().Count() )
392             pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
393     }
394 
395     mxFormulaParserPool.reset();
396     // Destroy the external ref mgr instance here because it has a timer
397     // which needs to be stopped before the app closes.
398     pExternalRefMgr.reset();
399 
400     ScAddInAsync::RemoveDocument( this );
401     ScAddInListener::RemoveDocument( this );
402     DELETEZ( pChartListenerCollection);   // vor pBASM wg. evtl. Listener!
403     DELETEZ( pLookupCacheMapImpl);  // before pBASM because of listeners
404     // BroadcastAreas vor allen Zellen zerstoeren um unnoetige
405     // Einzel-EndListenings der Formelzellen zu vermeiden
406     delete pBASM;       // BroadcastAreaSlotMachine
407     pBASM = NULL;
408 
409     if (pUnoBroadcaster)
410     {
411         delete pUnoBroadcaster;     // broadcasted nochmal SFX_HINT_DYING
412         pUnoBroadcaster = NULL;
413     }
414 
415     delete pUnoRefUndoList;
416     delete pUnoListenerCalls;
417 
418     Clear( sal_True );              // sal_True = from destructor (needed for SdrModel::ClearModel)
419 
420     if (pCondFormList)
421     {
422         pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
423         DELETEZ(pCondFormList);
424     }
425     if (pValidationList)
426     {
427         pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
428         DELETEZ(pValidationList);
429     }
430     delete pRangeName;
431     delete pDBCollection;
432     delete pSelectionAttr;
433     apTemporaryChartLock.reset();
434     delete pChartCollection;
435     DeleteDrawLayer();
436     delete pFormatExchangeList;
437     delete pPrinter;
438     ImplDeleteOptions();
439     delete pConsolidateDlgData;
440     delete pLinkManager;
441     delete pClipData;
442     delete pDetOpList;                  // loescht auch die Eintraege
443     delete pChangeTrack;
444     delete pEditEngine;
445     delete pNoteEngine;
446     SfxItemPool::Free(pNoteItemPool);
447     delete pChangeViewSettings;         // und weg damit
448     delete pVirtualDevice_100th_mm;
449 
450     if (pDPCollection)
451     {
452         pDPCollection->FreeAll();
453         RemoveUnusedDPObjectCaches();
454         delete pDPCollection;
455     }
456 
457     // delete the EditEngine before destroying the xPoolHelper
458     delete pCacheFieldEditEngine;
459 
460     if ( xPoolHelper.isValid() && !bIsClip )
461         xPoolHelper->SourceDocumentGone();
462     xPoolHelper.unbind();
463 
464     DeleteColorTable();
465     delete pScriptTypeData;
466     delete pOtherObjects;
467     delete pRecursionHelper;
468 
469     DBG_ASSERT( !pAutoNameCache, "AutoNameCache still set in dtor" );
470 }
471 
472 void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
473 {
474     DBG_ASSERT(bIsClip, "InitClipPtrs und nicht bIsClip");
475 
476     if (pCondFormList)
477     {
478         pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
479         DELETEZ(pCondFormList);
480     }
481     if (pValidationList)
482     {
483         pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
484         DELETEZ(pValidationList);
485     }
486 
487     Clear();
488 
489     xPoolHelper = pSourceDoc->xPoolHelper;
490 
491     //  bedingte Formate / Gueltigkeiten
492     //! Vorlagen kopieren?
493     const ScConditionalFormatList* pSourceCond = pSourceDoc->pCondFormList;
494     if ( pSourceCond )
495         pCondFormList = new ScConditionalFormatList(this, *pSourceCond);
496     const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
497     if ( pSourceValid )
498         pValidationList = new ScValidationDataList(this, *pSourceValid);
499 
500                         // Links in Stream speichern
501     delete pClipData;
502     if (pSourceDoc->HasDdeLinks())
503     {
504         pClipData = new SvMemoryStream;
505         pSourceDoc->SaveDdeLinks(*pClipData);
506     }
507     else
508         pClipData = NULL;
509 
510     // Options pointers exist (ImplCreateOptions) for any document.
511     // Must be copied for correct results in OLE objects (#i42666#).
512     SetDocOptions( pSourceDoc->GetDocOptions() );
513     SetViewOptions( pSourceDoc->GetViewOptions() );
514 }
515 
516 SvNumberFormatter* ScDocument::GetFormatTable() const
517 {
518     return xPoolHelper->GetFormTable();
519 }
520 
521 SfxItemPool* ScDocument::GetEditPool() const
522 {
523     return xPoolHelper->GetEditPool();
524 }
525 
526 SfxItemPool* ScDocument::GetEnginePool() const
527 {
528     return xPoolHelper->GetEnginePool();
529 }
530 
531 ScFieldEditEngine& ScDocument::GetEditEngine()
532 {
533     if ( !pEditEngine )
534     {
535         pEditEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
536         pEditEngine->SetUpdateMode( sal_False );
537         pEditEngine->EnableUndo( sal_False );
538         pEditEngine->SetRefMapMode( MAP_100TH_MM );
539         ApplyAsianEditSettings( *pEditEngine );
540     }
541     return *pEditEngine;
542 }
543 
544 ScNoteEditEngine& ScDocument::GetNoteEngine()
545 {
546     if ( !pNoteEngine )
547     {
548         pNoteEngine = new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
549         pNoteEngine->SetUpdateMode( sal_False );
550         pNoteEngine->EnableUndo( sal_False );
551         pNoteEngine->SetRefMapMode( MAP_100TH_MM );
552         ApplyAsianEditSettings( *pNoteEngine );
553         const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet();
554         SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() );
555         ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
556         pNoteEngine->SetDefaults( pEEItemSet );      // edit engine takes ownership
557     }
558     return *pNoteEngine;
559 }
560 
561 void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks )
562 {
563     if (bIsClip)
564     {
565         InitClipPtrs(pSourceDoc);
566 
567         for (SCTAB i = 0; i <= MAXTAB; i++)
568             if (pSourceDoc->pTab[i])
569                 if (!pMarks || pMarks->GetTableSelect(i))
570                 {
571                     String aString;
572                     pSourceDoc->pTab[i]->GetName(aString);
573                     pTab[i] = new ScTable(this, i, aString);
574                     pTab[i]->SetLayoutRTL( pSourceDoc->pTab[i]->IsLayoutRTL() );
575                     nMaxTableNumber = i+1;
576                 }
577     }
578     else
579     {
580         DBG_ERROR("ResetClip");
581     }
582 }
583 
584 void ScDocument::ResetClip( ScDocument* pSourceDoc, SCTAB nTab )
585 {
586     if (bIsClip)
587     {
588         InitClipPtrs(pSourceDoc);
589 
590         pTab[nTab] = new ScTable(this, nTab,
591                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
592         if (pSourceDoc->pTab[nTab])
593             pTab[nTab]->SetLayoutRTL( pSourceDoc->pTab[nTab]->IsLayoutRTL() );
594         nMaxTableNumber = nTab+1;
595     }
596     else
597     {
598         DBG_ERROR("ResetClip");
599     }
600 }
601 
602 void ScDocument::DeleteNumberFormat( const sal_uInt32* /* pDelKeys */, sal_uInt32 /* nCount */ )
603 {
604 /*
605     for (sal_uLong i = 0; i < nCount; i++)
606         xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
607 */
608 }
609 
610 void ScDocument::PutCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
611                           ScBaseCell* pCell, sal_uLong nFormatIndex, sal_Bool bForceTab )
612 {
613     if (VALIDTAB(nTab))
614     {
615         if ( bForceTab && !pTab[nTab] )
616         {
617             sal_Bool bExtras = !bIsUndo;        // Spaltenbreiten, Zeilenhoehen, Flags
618 
619             pTab[nTab] = new ScTable(this, nTab,
620                                 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
621                                 bExtras, bExtras);
622         }
623 
624         if (pTab[nTab])
625             pTab[nTab]->PutCell( nCol, nRow, nFormatIndex, pCell );
626     }
627 }
628 
629 //UNUSED2009-05 void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell,
630 //UNUSED2009-05                             sal_uLong nFormatIndex, sal_Bool bForceTab )
631 //UNUSED2009-05 {
632 //UNUSED2009-05     SCTAB nTab = rPos.Tab();
633 //UNUSED2009-05     if ( bForceTab && !pTab[nTab] )
634 //UNUSED2009-05     {
635 //UNUSED2009-05         sal_Bool bExtras = !bIsUndo;        // Spaltenbreiten, Zeilenhoehen, Flags
636 //UNUSED2009-05
637 //UNUSED2009-05         pTab[nTab] = new ScTable(this, nTab,
638 //UNUSED2009-05                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
639 //UNUSED2009-05                             bExtras, bExtras);
640 //UNUSED2009-05     }
641 //UNUSED2009-05
642 //UNUSED2009-05     if (pTab[nTab])
643 //UNUSED2009-05         pTab[nTab]->PutCell( rPos, nFormatIndex, pCell );
644 //UNUSED2009-05 }
645 
646 sal_Bool ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
647                                 sal_Bool bNotes ) const
648 {
649     if (ValidTab(nTab) && pTab[nTab])
650     {
651         sal_Bool bAny = pTab[nTab]->GetPrintArea( rEndCol, rEndRow, bNotes );
652         if (pDrawLayer)
653         {
654             ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
655             if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
656             {
657                 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
658                 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
659                 bAny = sal_True;
660             }
661         }
662         return bAny;
663     }
664 
665     rEndCol = 0;
666     rEndRow = 0;
667     return sal_False;
668 }
669 
670 sal_Bool ScDocument::GetPrintAreaHor( SCTAB nTab, SCROW nStartRow, SCROW nEndRow,
671                                         SCCOL& rEndCol, sal_Bool bNotes ) const
672 {
673     if (ValidTab(nTab) && pTab[nTab])
674     {
675         sal_Bool bAny = pTab[nTab]->GetPrintAreaHor( nStartRow, nEndRow, rEndCol, bNotes );
676         if (pDrawLayer)
677         {
678             ScRange aDrawRange(0,nStartRow,nTab, MAXCOL,nEndRow,nTab);
679             if (DrawGetPrintArea( aDrawRange, sal_True, sal_False ))
680             {
681                 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
682                 bAny = sal_True;
683             }
684         }
685         return bAny;
686     }
687 
688     rEndCol = 0;
689     return sal_False;
690 }
691 
692 sal_Bool ScDocument::GetPrintAreaVer( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol,
693                                         SCROW& rEndRow, sal_Bool bNotes ) const
694 {
695     if (ValidTab(nTab) && pTab[nTab])
696     {
697         sal_Bool bAny = pTab[nTab]->GetPrintAreaVer( nStartCol, nEndCol, rEndRow, bNotes );
698         if (pDrawLayer)
699         {
700             ScRange aDrawRange(nStartCol,0,nTab, nEndCol,MAXROW,nTab);
701             if (DrawGetPrintArea( aDrawRange, sal_False, sal_True ))
702             {
703                 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
704                 bAny = sal_True;
705             }
706         }
707         return bAny;
708     }
709 
710     rEndRow = 0;
711     return sal_False;
712 }
713 
714 sal_Bool ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const
715 {
716     if (ValidTab(nTab) && pTab[nTab])
717     {
718         sal_Bool bAny = pTab[nTab]->GetDataStart( rStartCol, rStartRow );
719         if (pDrawLayer)
720         {
721             ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
722             if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
723             {
724                 if (aDrawRange.aStart.Col()<rStartCol) rStartCol=aDrawRange.aStart.Col();
725                 if (aDrawRange.aStart.Row()<rStartRow) rStartRow=aDrawRange.aStart.Row();
726                 bAny = sal_True;
727             }
728         }
729         return bAny;
730     }
731 
732     rStartCol = 0;
733     rStartRow = 0;
734     return sal_False;
735 }
736 
737 sal_Bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
738 {
739     if (nOldPos == nNewPos) return sal_False;
740     sal_Bool bValid = sal_False;
741     if (VALIDTAB(nOldPos))
742     {
743         if (pTab[nOldPos])
744         {
745             SCTAB nTabCount = GetTableCount();
746             if (nTabCount > 1)
747             {
748                 sal_Bool bOldAutoCalc = GetAutoCalc();
749                 SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
750                 SetNoListening( sal_True );
751                 ScProgress* pProgress = new ScProgress( GetDocumentShell(),
752                     ScGlobal::GetRscString(STR_UNDO_MOVE_TAB), GetCodeCount() );
753                 if (nNewPos == SC_TAB_APPEND)
754                     nNewPos = nTabCount-1;
755 
756                 //  Referenz-Updaterei
757                 //! mit UpdateReference zusammenfassen!
758 
759                 SCsTAB nDz = ((SCsTAB)nNewPos) - (SCsTAB)nOldPos;
760                 ScRange aSourceRange( 0,0,nOldPos, MAXCOL,MAXROW,nOldPos );
761                 pRangeName->UpdateTabRef(nOldPos, 3, nNewPos);
762                 pDBCollection->UpdateMoveTab( nOldPos, nNewPos );
763                 xColNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
764                 xRowNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
765                 if (pDPCollection)
766                     pDPCollection->UpdateReference( URM_REORDER, aSourceRange, 0,0,nDz );
767                 if (pDetOpList)
768                     pDetOpList->UpdateReference( this, URM_REORDER, aSourceRange, 0,0,nDz );
769                 UpdateChartRef( URM_REORDER,
770                                     0,0,nOldPos, MAXCOL,MAXROW,nOldPos, 0,0,nDz );
771                 UpdateRefAreaLinks( URM_REORDER, aSourceRange, 0,0,nDz );
772                 if ( pCondFormList )
773                     pCondFormList->UpdateMoveTab( nOldPos, nNewPos );
774                 if ( pValidationList )
775                     pValidationList->UpdateMoveTab( nOldPos, nNewPos );
776                 if ( pUnoBroadcaster )
777                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_REORDER,
778                                     aSourceRange, 0,0,nDz ) );
779 
780                 ScTable* pSaveTab = pTab[nOldPos];
781                 SCTAB i;
782                 for (i = nOldPos + 1; i < nTabCount; i++)
783                     pTab[i - 1] = pTab[i];
784                 pTab[i-1] = NULL;
785                 for (i = nTabCount - 1; i > nNewPos; i--)
786                     pTab[i] = pTab[i - 1];
787                 pTab[nNewPos] = pSaveTab;
788                 for (i = 0; i <= MAXTAB; i++)
789                     if (pTab[i])
790                         pTab[i]->UpdateMoveTab( nOldPos, nNewPos, i, *pProgress );
791                 delete pProgress;   // freimachen fuer evtl. andere
792                 for (i = 0; i <= MAXTAB; i++)
793                     if (pTab[i])
794                         pTab[i]->UpdateCompile();
795                 SetNoListening( sal_False );
796                 for (i = 0; i <= MAXTAB; i++)
797                     if (pTab[i])
798                         pTab[i]->StartAllListeners();
799                 // #81844# sheet names of references may not be valid until sheet is moved
800                 pChartListenerCollection->UpdateScheduledSeriesRanges();
801                 SetDirty();
802                 SetAutoCalc( bOldAutoCalc );
803 
804                 if (pDrawLayer)
805                     DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
806 
807                 bValid = sal_True;
808             }
809         }
810     }
811     return bValid;
812 }
813 
814 sal_Bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked )
815 {
816     if (SC_TAB_APPEND == nNewPos ) nNewPos = nMaxTableNumber;
817     String aName;
818     GetName(nOldPos, aName);
819 
820     //  vorneweg testen, ob der Prefix als gueltig erkannt wird
821     //  wenn nicht, nur doppelte vermeiden
822     sal_Bool bPrefix = ValidTabName( aName );
823     DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
824     SCTAB nDummy;
825 
826     CreateValidTabName(aName);
827 
828     sal_Bool bValid;
829     if (bPrefix)
830         bValid = ( ValidNewTabName(aName) && (nMaxTableNumber <= MAXTAB) );
831     else
832         bValid = ( !GetTable( aName, nDummy ) && (nMaxTableNumber <= MAXTAB) );
833 
834     sal_Bool bOldAutoCalc = GetAutoCalc();
835     SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
836     if (bValid)
837     {
838         if (nNewPos == nMaxTableNumber)
839         {
840             pTab[nMaxTableNumber] = new ScTable(this, nMaxTableNumber, aName);
841             ++nMaxTableNumber;
842         }
843         else
844         {
845             if (VALIDTAB(nNewPos) && (nNewPos < nMaxTableNumber))
846             {
847                 SetNoListening( sal_True );
848 
849                 ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
850                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
851                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
852                 pRangeName->UpdateTabRef(nNewPos, 1);
853                 pDBCollection->UpdateReference(
854                                     URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
855                 if (pDPCollection)
856                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
857                 if (pDetOpList)
858                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
859                 UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
860                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
861                 if ( pUnoBroadcaster )
862                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
863 
864                 SCTAB i;
865                 for (i = 0; i <= MAXTAB; i++)
866                     if (pTab[i] && i != nOldPos)
867                         pTab[i]->UpdateInsertTab(nNewPos);
868                 for (i = nMaxTableNumber; i > nNewPos; i--)
869                     pTab[i] = pTab[i - 1];
870                 if (nNewPos <= nOldPos)
871                     nOldPos++;
872                 pTab[nNewPos] = new ScTable(this, nNewPos, aName);
873                 ++nMaxTableNumber;
874                 bValid = sal_True;
875                 for (i = 0; i <= MAXTAB; i++)
876                     if (pTab[i] && i != nOldPos && i != nNewPos)
877                         pTab[i]->UpdateCompile();
878                 SetNoListening( sal_False );
879                 for (i = 0; i <= MAXTAB; i++)
880                     if (pTab[i] && i != nOldPos && i != nNewPos)
881                         pTab[i]->StartAllListeners();
882 
883                 //  update conditional formats after table is inserted
884                 if ( pCondFormList )
885                     pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
886                 if ( pValidationList )
887                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
888                 // #81844# sheet names of references may not be valid until sheet is copied
889                 pChartListenerCollection->UpdateScheduledSeriesRanges();
890             }
891             else
892                 bValid = sal_False;
893         }
894     }
895     if (bValid)
896     {
897         SetNoListening( sal_True );     // noch nicht bei CopyToTable/Insert
898         pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
899                                         pTab[nNewPos], pOnlyMarked );
900         pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
901 
902         SCsTAB nDz;
903 /*      if (nNewPos < nOldPos)
904             nDz = ((short)nNewPos) - (short)nOldPos + 1;
905         else
906 */          nDz = ((short)nNewPos) - (short)nOldPos;
907         pTab[nNewPos]->UpdateReference(URM_COPY, 0, 0, nNewPos , MAXCOL, MAXROW,
908                                         nNewPos, 0, 0, nDz, NULL);
909 
910         pTab[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
911         pTab[nOldPos]->UpdateInsertTab(nNewPos);
912 
913         pTab[nOldPos]->UpdateCompile();
914         pTab[nNewPos]->UpdateCompile( sal_True );   // #67996# maybe already compiled in Clone, but used names need recompilation
915         SetNoListening( sal_False );
916         pTab[nOldPos]->StartAllListeners();
917         pTab[nNewPos]->StartAllListeners();
918         SetDirty();
919         SetAutoCalc( bOldAutoCalc );
920 
921         if (pDrawLayer)
922             DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
923 
924         pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
925         pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
926     }
927     else
928         SetAutoCalc( bOldAutoCalc );
929     return bValid;
930 }
931 
932 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
933 
934 sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
935                                 SCTAB nDestPos, sal_Bool bInsertNew,
936                                 sal_Bool bResultsOnly )
937 {
938     sal_uLong nRetVal = 1;                      // 0 => Fehler 1 = ok
939                                             // 2 => RefBox, 3 => NameBox
940                                             // 4 => beides
941     sal_Bool bValid = sal_True;
942     if (bInsertNew)             // neu einfuegen
943     {
944         String aName;
945         pSrcDoc->GetName(nSrcPos, aName);
946         CreateValidTabName(aName);
947         bValid = InsertTab(nDestPos, aName);
948     }
949     else                        // bestehende Tabelle ersetzen
950     {
951         if (VALIDTAB(nDestPos) && pTab[nDestPos])
952         {
953             pTab[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
954         }
955         else
956             bValid = sal_False;
957     }
958 
959     if (bValid)
960     {
961         sal_Bool bOldAutoCalcSrc = sal_False;
962         sal_Bool bOldAutoCalc = GetAutoCalc();
963         SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
964         SetNoListening( sal_True );
965         if ( bResultsOnly )
966         {
967             bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
968             pSrcDoc->SetAutoCalc( sal_True );   // falls was berechnet werden muss
969         }
970 
971         {
972             NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
973 
974             nDestPos = Min(nDestPos, (SCTAB)(GetTableCount() - 1));
975             {   // scope for bulk broadcast
976                 ScBulkBroadcast aBulkBroadcast( pBASM);
977                 pSrcDoc->pTab[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
978                         ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
979                         sal_False, pTab[nDestPos] );
980             }
981         }
982         pTab[nDestPos]->SetTabNo(nDestPos);
983 
984         if ( !bResultsOnly )
985         {
986             sal_Bool bNamesLost = sal_False;
987             sal_uInt16 nSrcRangeNames = pSrcDoc->pRangeName->GetCount();
988             // array containing range names which might need update of indices
989             ScRangeData** pSrcRangeNames = nSrcRangeNames ? new ScRangeData* [nSrcRangeNames] : NULL;
990             // the index mapping thereof
991             ScRangeData::IndexMap aSrcRangeMap;
992             sal_Bool bRangeNameReplace = sal_False;
993 
994             // find named ranges that are used in the source sheet
995             std::set<sal_uInt16> aUsedNames;
996             pSrcDoc->pTab[nSrcPos]->FindRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aUsedNames );
997 
998             for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)     //! DB-Bereiche Pivot-Bereiche auch !!!
999             {
1000                 ScRangeData* pSrcData = (*pSrcDoc->pRangeName)[i];
1001                 sal_uInt16 nOldIndex = pSrcData->GetIndex();
1002                 bool bInUse = ( aUsedNames.find(nOldIndex) != aUsedNames.end() );
1003                 if (bInUse)
1004                 {
1005                     sal_uInt16 nExisting = 0;
1006                     if ( pRangeName->SearchName( pSrcData->GetName(), nExisting ) )
1007                     {
1008                         // the name exists already in the destination document
1009                         // -> use the existing name, but show a warning
1010                         // (when refreshing links, the existing name is used and the warning not shown)
1011 
1012                         ScRangeData* pExistingData = (*pRangeName)[nExisting];
1013                         sal_uInt16 nExistingIndex = pExistingData->GetIndex();
1014 
1015                         pSrcRangeNames[i] = NULL;       // don't modify the named range
1016                         aSrcRangeMap.insert(
1017                             ScRangeData::IndexMap::value_type(nOldIndex, nExistingIndex));
1018                         bRangeNameReplace = sal_True;
1019                         bNamesLost = sal_True;
1020                     }
1021                     else
1022                     {
1023                         ScRangeData* pData = new ScRangeData( *pSrcData );
1024                         pData->SetDocument(this);
1025                         if ( pRangeName->FindIndex( pData->GetIndex() ) )
1026                             pData->SetIndex(0);     // need new index, done in Insert
1027                         if (!pRangeName->Insert(pData))
1028                         {
1029                             DBG_ERROR("can't insert name");     // shouldn't happen
1030                             delete pData;
1031                         }
1032                         else
1033                         {
1034                             pData->TransferTabRef( nSrcPos, nDestPos );
1035                             pSrcRangeNames[i] = pData;
1036                             sal_uInt16 nNewIndex = pData->GetIndex();
1037                             aSrcRangeMap.insert(
1038                                 ScRangeData::IndexMap::value_type(nOldIndex, nNewIndex));
1039                             if ( !bRangeNameReplace )
1040                                 bRangeNameReplace = ( nOldIndex != nNewIndex );
1041                         }
1042                     }
1043                 }
1044                 else
1045                 {
1046                     pSrcRangeNames[i] = NULL;
1047                     //aSrcRangeMap.SetPair( i, 0, 0 );      // not needed, defaulted
1048                 }
1049             }
1050             if ( bRangeNameReplace )
1051             {
1052                 // first update all inserted named formulas if they contain other
1053                 // range names and used indices changed
1054                 for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)     //! DB-Bereiche Pivot-Bereiche auch
1055                 {
1056                     if ( pSrcRangeNames[i] )
1057                         pSrcRangeNames[i]->ReplaceRangeNamesInUse( aSrcRangeMap );
1058                 }
1059                 // then update the formulas, they might need the just updated range names
1060                 pTab[nDestPos]->ReplaceRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aSrcRangeMap );
1061             }
1062             if ( pSrcRangeNames )
1063                 delete [] pSrcRangeNames;
1064 
1065             SCsTAB nDz = ((SCsTAB)nDestPos) - (SCsTAB)nSrcPos;
1066             pTab[nDestPos]->UpdateReference(URM_COPY, 0, 0, nDestPos,
1067                                                      MAXCOL, MAXROW, nDestPos,
1068                                                      0, 0, nDz, NULL);
1069             // Test for outside absolute references for info box
1070             sal_Bool bIsAbsRef = pSrcDoc->pTab[nSrcPos]->TestTabRefAbs(nSrcPos);
1071             // Readjust self-contained absolute references to this sheet
1072             pTab[nDestPos]->TestTabRefAbs(nSrcPos);
1073             if (bIsAbsRef)
1074             {
1075                 nRetVal += 1;
1076                     // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
1077             }
1078             if (bNamesLost)
1079             {
1080                 nRetVal += 2;
1081                 // message: duplicate names
1082             }
1083             pTab[nDestPos]->CompileAll();
1084         }
1085 
1086         SetNoListening( sal_False );
1087         if ( !bResultsOnly )
1088             pTab[nDestPos]->StartAllListeners();
1089         SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
1090 
1091         if ( bResultsOnly )
1092             pSrcDoc->SetAutoCalc( bOldAutoCalcSrc );
1093         SetAutoCalc( bOldAutoCalc );
1094 
1095         //  Drawing kopieren
1096 
1097         if (bInsertNew)
1098             TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
1099 
1100         pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
1101     }
1102     if (!bValid)
1103         nRetVal = 0;
1104     sal_Bool bVbaEnabled = IsInVBAMode();
1105 
1106     if ( bVbaEnabled  )
1107     {
1108         SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL;
1109         if ( pSrcShell )
1110         {
1111             StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL;
1112             String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
1113             if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 )
1114             {
1115                 aLibName = pSrcShell->GetBasicManager()->GetName();
1116                 pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName );
1117             }
1118 
1119             String sCodeName;
1120             String sSource;
1121             uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
1122             uno::Reference< container::XNameContainer > xLib;
1123             if( xLibContainer.is() )
1124             {
1125                 uno::Any aLibAny = xLibContainer->getByName( aLibName );
1126                 aLibAny >>= xLib;
1127             }
1128 
1129             if( xLib.is() )
1130             {
1131                 String sSrcCodeName;
1132                 pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName );
1133                 rtl::OUString sRTLSource;
1134                 xLib->getByName( sSrcCodeName ) >>= sRTLSource;
1135                 sSource = sRTLSource;
1136             }
1137             VBA_InsertModule( *this, nDestPos, sCodeName, sSource );
1138         }
1139     }
1140 
1141     return nRetVal;
1142 }
1143 
1144 //  ----------------------------------------------------------------------------
1145 
1146 void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError)
1147 {
1148     if (VALIDTAB(nTab))
1149         if (pTab[nTab])
1150             pTab[nTab]->SetError( nCol, nRow, nError );
1151 }
1152 
1153 void ScDocument::EraseNonUsedSharedNames(sal_uInt16 nLevel)
1154 {
1155     for (sal_uInt16 i = 0; i < pRangeName->GetCount(); i++)
1156     {
1157         ScRangeData* pRangeData = (*pRangeName)[i];
1158         if (pRangeData && pRangeData->HasType(RT_SHARED))
1159         {
1160             String aName;
1161             pRangeData->GetName(aName);
1162             aName.Erase(0, 6);                      // !!! vgl. Table4, FillFormula !!
1163             sal_uInt16 nInd = (sal_uInt16) aName.ToInt32();
1164             if (nInd <= nLevel)
1165             {
1166                 sal_uInt16 nIndex = pRangeData->GetIndex();
1167                 sal_Bool bInUse = sal_False;
1168                 for (SCTAB j = 0; !bInUse && (j <= MAXTAB); j++)
1169                 {
1170                     if (pTab[j])
1171                         bInUse = pTab[j]->IsRangeNameInUse(0, 0, MAXCOL-1, MAXROW-1,
1172                                                            nIndex);
1173                 }
1174                 if (!bInUse)
1175                     pRangeName->AtFree(i);
1176             }
1177         }
1178     }
1179 }
1180 
1181 //  ----------------------------------------------------------------------------
1182 
1183 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
1184 {
1185     delete pConsolidateDlgData;
1186 
1187     if ( pData )
1188         pConsolidateDlgData = new ScConsolidateParam( *pData );
1189     else
1190         pConsolidateDlgData = NULL;
1191 }
1192 
1193 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings& rNew)
1194 {
1195     if (pChangeViewSettings==NULL)
1196         pChangeViewSettings = new ScChangeViewSettings;
1197 
1198     DBG_ASSERT( pChangeViewSettings, "Oops. No ChangeViewSettings :-( by!" );
1199 
1200     *pChangeViewSettings=rNew;
1201 }
1202 
1203 //  ----------------------------------------------------------------------------
1204 
1205 ScFieldEditEngine* ScDocument::CreateFieldEditEngine()
1206 {
1207     ScFieldEditEngine* pNewEditEngine = NULL;
1208     if (!pCacheFieldEditEngine)
1209     {
1210         pNewEditEngine = new ScFieldEditEngine( GetEnginePool(),
1211             GetEditPool(), sal_False );
1212     }
1213     else
1214     {
1215         if ( !bImportingXML )
1216         {
1217             // #i66209# previous use might not have restored update mode,
1218             // ensure same state as for a new EditEngine (UpdateMode = sal_True)
1219             if ( !pCacheFieldEditEngine->GetUpdateMode() )
1220                 pCacheFieldEditEngine->SetUpdateMode(sal_True);
1221         }
1222 
1223         pNewEditEngine = pCacheFieldEditEngine;
1224         pCacheFieldEditEngine = NULL;
1225     }
1226     return pNewEditEngine;
1227 }
1228 
1229 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine)
1230 {
1231     if (!pCacheFieldEditEngine && rpEditEngine)
1232     {
1233         pCacheFieldEditEngine = rpEditEngine;
1234         pCacheFieldEditEngine->Clear();
1235     }
1236     else
1237         delete rpEditEngine;
1238     rpEditEngine = NULL;
1239 }
1240 
1241 //  ----------------------------------------------------------------------------
1242 
1243 // static
1244 ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
1245 {
1246     return new ScRecursionHelper;
1247 }
1248 
1249 //  ----------------------------------------------------------------------------
1250 
1251 ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
1252 {
1253     ScLookupCache* pCache = 0;
1254     if (!pLookupCacheMapImpl)
1255         pLookupCacheMapImpl = new ScLookupCacheMapImpl;
1256     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find( rRange));
1257     if (it == pLookupCacheMapImpl->aCacheMap.end())
1258     {
1259         pCache = new ScLookupCache( this, rRange);
1260         AddLookupCache( *pCache);
1261     }
1262     else
1263         pCache = (*it).second;
1264     return *pCache;
1265 }
1266 
1267 void ScDocument::AddLookupCache( ScLookupCache & rCache )
1268 {
1269     if (!pLookupCacheMapImpl->aCacheMap.insert( ::std::pair< const ScRange,
1270                 ScLookupCache*>( rCache.getRange(), &rCache)).second)
1271     {
1272         DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
1273     }
1274     else
1275         StartListeningArea( rCache.getRange(), &rCache);
1276 }
1277 
1278 void ScDocument::RemoveLookupCache( ScLookupCache & rCache )
1279 {
1280     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find(
1281                 rCache.getRange()));
1282     if (it == pLookupCacheMapImpl->aCacheMap.end())
1283     {
1284         DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
1285     }
1286     else
1287     {
1288         ScLookupCache* pCache = (*it).second;
1289         pLookupCacheMapImpl->aCacheMap.erase( it);
1290         EndListeningArea( pCache->getRange(), &rCache);
1291     }
1292 }
1293 
1294 void ScDocument::ClearLookupCaches()
1295 {
1296     if( pLookupCacheMapImpl )
1297         pLookupCacheMapImpl->clear();
1298 }
1299