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