xref: /AOO41X/main/sc/source/core/data/documen2.cxx (revision 6a6ec68d792bd477e5b23798f42a1a9de0925497)
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         pColorTable( NULL ),
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     DeleteColorTable();
461     delete pScriptTypeData;
462     delete pOtherObjects;
463     delete pRecursionHelper;
464 
465     DBG_ASSERT( !pAutoNameCache, "AutoNameCache still set in dtor" );
466 }
467 
468 void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
469 {
470     DBG_ASSERT(bIsClip, "InitClipPtrs und nicht bIsClip");
471 
472     if (pCondFormList)
473     {
474         pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
475         DELETEZ(pCondFormList);
476     }
477     if (pValidationList)
478     {
479         pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
480         DELETEZ(pValidationList);
481     }
482 
483     Clear();
484 
485     xPoolHelper = pSourceDoc->xPoolHelper;
486 
487     //  bedingte Formate / Gueltigkeiten
488     //! Vorlagen kopieren?
489     const ScConditionalFormatList* pSourceCond = pSourceDoc->pCondFormList;
490     if ( pSourceCond )
491         pCondFormList = new ScConditionalFormatList(this, *pSourceCond);
492     const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
493     if ( pSourceValid )
494         pValidationList = new ScValidationDataList(this, *pSourceValid);
495 
496                         // Links in Stream speichern
497     delete pClipData;
498     if (pSourceDoc->HasDdeLinks())
499     {
500         pClipData = new SvMemoryStream;
501         pSourceDoc->SaveDdeLinks(*pClipData);
502     }
503     else
504         pClipData = NULL;
505 
506     // Options pointers exist (ImplCreateOptions) for any document.
507     // Must be copied for correct results in OLE objects (#i42666#).
508     SetDocOptions( pSourceDoc->GetDocOptions() );
509     SetViewOptions( pSourceDoc->GetViewOptions() );
510 }
511 
512 SvNumberFormatter* ScDocument::GetFormatTable() const
513 {
514     return xPoolHelper->GetFormTable();
515 }
516 
517 SfxItemPool* ScDocument::GetEditPool() const
518 {
519     return xPoolHelper->GetEditPool();
520 }
521 
522 SfxItemPool* ScDocument::GetEnginePool() const
523 {
524     return xPoolHelper->GetEnginePool();
525 }
526 
527 ScFieldEditEngine& ScDocument::GetEditEngine()
528 {
529     if ( !pEditEngine )
530     {
531         pEditEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
532         pEditEngine->SetUpdateMode( sal_False );
533         pEditEngine->EnableUndo( sal_False );
534         pEditEngine->SetRefMapMode( MAP_100TH_MM );
535         ApplyAsianEditSettings( *pEditEngine );
536     }
537     return *pEditEngine;
538 }
539 
540 ScNoteEditEngine& ScDocument::GetNoteEngine()
541 {
542     if ( !pNoteEngine )
543     {
544         pNoteEngine = new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
545         pNoteEngine->SetUpdateMode( sal_False );
546         pNoteEngine->EnableUndo( sal_False );
547         pNoteEngine->SetRefMapMode( MAP_100TH_MM );
548         ApplyAsianEditSettings( *pNoteEngine );
549         const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet();
550         SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() );
551         ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
552         pNoteEngine->SetDefaults( pEEItemSet );      // edit engine takes ownership
553     }
554     return *pNoteEngine;
555 }
556 
557 void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks )
558 {
559     if (bIsClip)
560     {
561         InitClipPtrs(pSourceDoc);
562 
563         for (SCTAB i = 0; i <= MAXTAB; i++)
564             if (pSourceDoc->pTab[i])
565                 if (!pMarks || pMarks->GetTableSelect(i))
566                 {
567                     String aString;
568                     pSourceDoc->pTab[i]->GetName(aString);
569                     pTab[i] = new ScTable(this, i, aString);
570                     pTab[i]->SetLayoutRTL( pSourceDoc->pTab[i]->IsLayoutRTL() );
571                     nMaxTableNumber = i+1;
572                 }
573     }
574     else
575     {
576         DBG_ERROR("ResetClip");
577     }
578 }
579 
580 void ScDocument::ResetClip( ScDocument* pSourceDoc, SCTAB nTab )
581 {
582     if (bIsClip)
583     {
584         InitClipPtrs(pSourceDoc);
585 
586         pTab[nTab] = new ScTable(this, nTab,
587                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
588         if (pSourceDoc->pTab[nTab])
589             pTab[nTab]->SetLayoutRTL( pSourceDoc->pTab[nTab]->IsLayoutRTL() );
590         nMaxTableNumber = nTab+1;
591     }
592     else
593     {
594         DBG_ERROR("ResetClip");
595     }
596 }
597 
598 void ScDocument::DeleteNumberFormat( const sal_uInt32* /* pDelKeys */, sal_uInt32 /* nCount */ )
599 {
600 /*
601     for (sal_uLong i = 0; i < nCount; i++)
602         xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
603 */
604 }
605 
606 void ScDocument::PutCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
607                           ScBaseCell* pCell, sal_uLong nFormatIndex, sal_Bool bForceTab )
608 {
609     if (VALIDTAB(nTab))
610     {
611         if ( bForceTab && !pTab[nTab] )
612         {
613             sal_Bool bExtras = !bIsUndo;        // Spaltenbreiten, Zeilenhoehen, Flags
614 
615             pTab[nTab] = new ScTable(this, nTab,
616                                 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
617                                 bExtras, bExtras);
618         }
619 
620         if (pTab[nTab])
621             pTab[nTab]->PutCell( nCol, nRow, nFormatIndex, pCell );
622     }
623 }
624 
625 //UNUSED2009-05 void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell,
626 //UNUSED2009-05                             sal_uLong nFormatIndex, sal_Bool bForceTab )
627 //UNUSED2009-05 {
628 //UNUSED2009-05     SCTAB nTab = rPos.Tab();
629 //UNUSED2009-05     if ( bForceTab && !pTab[nTab] )
630 //UNUSED2009-05     {
631 //UNUSED2009-05         sal_Bool bExtras = !bIsUndo;        // Spaltenbreiten, Zeilenhoehen, Flags
632 //UNUSED2009-05
633 //UNUSED2009-05         pTab[nTab] = new ScTable(this, nTab,
634 //UNUSED2009-05                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
635 //UNUSED2009-05                             bExtras, bExtras);
636 //UNUSED2009-05     }
637 //UNUSED2009-05
638 //UNUSED2009-05     if (pTab[nTab])
639 //UNUSED2009-05         pTab[nTab]->PutCell( rPos, nFormatIndex, pCell );
640 //UNUSED2009-05 }
641 
642 sal_Bool ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
643                                 sal_Bool bNotes ) const
644 {
645     if (ValidTab(nTab) && pTab[nTab])
646     {
647         sal_Bool bAny = pTab[nTab]->GetPrintArea( rEndCol, rEndRow, bNotes );
648         if (pDrawLayer)
649         {
650             ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
651             if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
652             {
653                 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
654                 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
655                 bAny = sal_True;
656             }
657         }
658         return bAny;
659     }
660 
661     rEndCol = 0;
662     rEndRow = 0;
663     return sal_False;
664 }
665 
666 sal_Bool ScDocument::GetPrintAreaHor( SCTAB nTab, SCROW nStartRow, SCROW nEndRow,
667                                         SCCOL& rEndCol, sal_Bool bNotes ) const
668 {
669     if (ValidTab(nTab) && pTab[nTab])
670     {
671         sal_Bool bAny = pTab[nTab]->GetPrintAreaHor( nStartRow, nEndRow, rEndCol, bNotes );
672         if (pDrawLayer)
673         {
674             ScRange aDrawRange(0,nStartRow,nTab, MAXCOL,nEndRow,nTab);
675             if (DrawGetPrintArea( aDrawRange, sal_True, sal_False ))
676             {
677                 if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
678                 bAny = sal_True;
679             }
680         }
681         return bAny;
682     }
683 
684     rEndCol = 0;
685     return sal_False;
686 }
687 
688 sal_Bool ScDocument::GetPrintAreaVer( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol,
689                                         SCROW& rEndRow, sal_Bool bNotes ) const
690 {
691     if (ValidTab(nTab) && pTab[nTab])
692     {
693         sal_Bool bAny = pTab[nTab]->GetPrintAreaVer( nStartCol, nEndCol, rEndRow, bNotes );
694         if (pDrawLayer)
695         {
696             ScRange aDrawRange(nStartCol,0,nTab, nEndCol,MAXROW,nTab);
697             if (DrawGetPrintArea( aDrawRange, sal_False, sal_True ))
698             {
699                 if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
700                 bAny = sal_True;
701             }
702         }
703         return bAny;
704     }
705 
706     rEndRow = 0;
707     return sal_False;
708 }
709 
710 sal_Bool ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const
711 {
712     if (ValidTab(nTab) && pTab[nTab])
713     {
714         sal_Bool bAny = pTab[nTab]->GetDataStart( rStartCol, rStartRow );
715         if (pDrawLayer)
716         {
717             ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
718             if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
719             {
720                 if (aDrawRange.aStart.Col()<rStartCol) rStartCol=aDrawRange.aStart.Col();
721                 if (aDrawRange.aStart.Row()<rStartRow) rStartRow=aDrawRange.aStart.Row();
722                 bAny = sal_True;
723             }
724         }
725         return bAny;
726     }
727 
728     rStartCol = 0;
729     rStartRow = 0;
730     return sal_False;
731 }
732 
733 sal_Bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
734 {
735     if (nOldPos == nNewPos) return sal_False;
736     sal_Bool bValid = sal_False;
737     if (VALIDTAB(nOldPos))
738     {
739         if (pTab[nOldPos])
740         {
741             SCTAB nTabCount = GetTableCount();
742             if (nTabCount > 1)
743             {
744                 sal_Bool bOldAutoCalc = GetAutoCalc();
745                 SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
746                 SetNoListening( sal_True );
747                 ScProgress* pProgress = new ScProgress( GetDocumentShell(),
748                     ScGlobal::GetRscString(STR_UNDO_MOVE_TAB), GetCodeCount() );
749                 if (nNewPos == SC_TAB_APPEND)
750                     nNewPos = nTabCount-1;
751 
752                 //  Referenz-Updaterei
753                 //! mit UpdateReference zusammenfassen!
754 
755                 SCsTAB nDz = ((SCsTAB)nNewPos) - (SCsTAB)nOldPos;
756                 ScRange aSourceRange( 0,0,nOldPos, MAXCOL,MAXROW,nOldPos );
757                 pRangeName->UpdateTabRef(nOldPos, 3, nNewPos);
758                 pDBCollection->UpdateMoveTab( nOldPos, nNewPos );
759                 xColNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
760                 xRowNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
761                 if (pDPCollection)
762                     pDPCollection->UpdateReference( URM_REORDER, aSourceRange, 0,0,nDz );
763                 if (pDetOpList)
764                     pDetOpList->UpdateReference( this, URM_REORDER, aSourceRange, 0,0,nDz );
765                 UpdateChartRef( URM_REORDER,
766                                     0,0,nOldPos, MAXCOL,MAXROW,nOldPos, 0,0,nDz );
767                 UpdateRefAreaLinks( URM_REORDER, aSourceRange, 0,0,nDz );
768                 if ( pCondFormList )
769                     pCondFormList->UpdateMoveTab( nOldPos, nNewPos );
770                 if ( pValidationList )
771                     pValidationList->UpdateMoveTab( nOldPos, nNewPos );
772                 if ( pUnoBroadcaster )
773                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_REORDER,
774                                     aSourceRange, 0,0,nDz ) );
775 
776                 ScTable* pSaveTab = pTab[nOldPos];
777                 SCTAB i;
778                 for (i = nOldPos + 1; i < nTabCount; i++)
779                     pTab[i - 1] = pTab[i];
780                 pTab[i-1] = NULL;
781                 for (i = nTabCount - 1; i > nNewPos; i--)
782                     pTab[i] = pTab[i - 1];
783                 pTab[nNewPos] = pSaveTab;
784                 for (i = 0; i <= MAXTAB; i++)
785                     if (pTab[i])
786                         pTab[i]->UpdateMoveTab( nOldPos, nNewPos, i, *pProgress );
787                 delete pProgress;   // freimachen fuer evtl. andere
788                 for (i = 0; i <= MAXTAB; i++)
789                     if (pTab[i])
790                         pTab[i]->UpdateCompile();
791                 SetNoListening( sal_False );
792                 for (i = 0; i <= MAXTAB; i++)
793                     if (pTab[i])
794                         pTab[i]->StartAllListeners();
795                 // #81844# sheet names of references may not be valid until sheet is moved
796                 pChartListenerCollection->UpdateScheduledSeriesRanges();
797                 SetDirty();
798                 SetAutoCalc( bOldAutoCalc );
799 
800                 if (pDrawLayer)
801                     DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
802 
803                 bValid = sal_True;
804             }
805         }
806     }
807     return bValid;
808 }
809 
810 sal_Bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked )
811 {
812     if (SC_TAB_APPEND == nNewPos ) nNewPos = nMaxTableNumber;
813     String aName;
814     GetName(nOldPos, aName);
815 
816     //  vorneweg testen, ob der Prefix als gueltig erkannt wird
817     //  wenn nicht, nur doppelte vermeiden
818     sal_Bool bPrefix = ValidTabName( aName );
819     DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
820     SCTAB nDummy;
821 
822     CreateValidTabName(aName);
823 
824     sal_Bool bValid;
825     if (bPrefix)
826         bValid = ( ValidNewTabName(aName) && (nMaxTableNumber <= MAXTAB) );
827     else
828         bValid = ( !GetTable( aName, nDummy ) && (nMaxTableNumber <= MAXTAB) );
829 
830     sal_Bool bOldAutoCalc = GetAutoCalc();
831     SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
832     if (bValid)
833     {
834         if (nNewPos == nMaxTableNumber)
835         {
836             pTab[nMaxTableNumber] = new ScTable(this, nMaxTableNumber, aName);
837             pRangeName->UpdateTabRef(nNewPos, 4, nOldPos);//. 4 - copy table
838             ++nMaxTableNumber;
839         }
840         else
841         {
842             if (VALIDTAB(nNewPos) && (nNewPos < nMaxTableNumber))
843             {
844                 SetNoListening( sal_True );
845 
846                 ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
847                 xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
848                 xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
849                 pRangeName->UpdateTabRef(nNewPos, 4, nOldPos);//  4 - copy table
850                 pDBCollection->UpdateReference(
851                                     URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
852                 if (pDPCollection)
853                     pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
854                 if (pDetOpList)
855                     pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
856                 UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
857                 UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
858                 if ( pUnoBroadcaster )
859                     pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
860 
861                 SCTAB i;
862                 for (i = 0; i <= MAXTAB; i++)
863                     if (pTab[i] && i != nOldPos)
864                         pTab[i]->UpdateInsertTab(nNewPos);
865                 for (i = nMaxTableNumber; i > nNewPos; i--)
866                     pTab[i] = pTab[i - 1];
867                 if (nNewPos <= nOldPos)
868                     nOldPos++;
869                 pTab[nNewPos] = new ScTable(this, nNewPos, aName);
870                 ++nMaxTableNumber;
871                 bValid = sal_True;
872                 for (i = 0; i <= MAXTAB; i++)
873                     if (pTab[i] && i != nOldPos && i != nNewPos)
874                         pTab[i]->UpdateCompile();
875                 SetNoListening( sal_False );
876                 for (i = 0; i <= MAXTAB; i++)
877                     if (pTab[i] && i != nOldPos && i != nNewPos)
878                         pTab[i]->StartAllListeners();
879 
880                 //  update conditional formats after table is inserted
881                 if ( pCondFormList )
882                     pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
883                 if ( pValidationList )
884                     pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
885                 // #81844# sheet names of references may not be valid until sheet is copied
886                 pChartListenerCollection->UpdateScheduledSeriesRanges();
887             }
888             else
889                 bValid = sal_False;
890         }
891     }
892     if (bValid)
893     {
894         SetNoListening( sal_True );     // noch nicht bei CopyToTable/Insert
895         pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
896                                         pTab[nNewPos], pOnlyMarked );
897         pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
898 
899         SCsTAB nDz;
900 /*      if (nNewPos < nOldPos)
901             nDz = ((short)nNewPos) - (short)nOldPos + 1;
902         else
903 */          nDz = ((short)nNewPos) - (short)nOldPos;
904         pTab[nNewPos]->UpdateReference(URM_COPY, 0, 0, nNewPos , MAXCOL, MAXROW,
905                                         nNewPos, 0, 0, nDz, NULL);
906 
907         pTab[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
908         pTab[nOldPos]->UpdateInsertTab(nNewPos);
909 
910         pTab[nOldPos]->UpdateCompile();
911         pTab[nNewPos]->UpdateCompile( sal_True );   // #67996# maybe already compiled in Clone, but used names need recompilation
912         SetNoListening( sal_False );
913         pTab[nOldPos]->StartAllListeners();
914         pTab[nNewPos]->StartAllListeners();
915         SetDirty();
916         SetAutoCalc( bOldAutoCalc );
917 
918         if (pDrawLayer)
919             DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
920 
921         pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
922         pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
923     }
924     else
925         SetAutoCalc( bOldAutoCalc );
926     return bValid;
927 }
928 
929 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
930 
931 sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
932                                 SCTAB nDestPos, sal_Bool bInsertNew,
933                                 sal_Bool bResultsOnly )
934 {
935     sal_uLong nRetVal = 1;                      // 0 => Fehler 1 = ok
936                                             // 2 => RefBox, 3 => NameBox
937                                             // 4 => beides
938     sal_Bool bValid = sal_True;
939     if (bInsertNew)             // neu einfuegen
940     {
941         String aName;
942         pSrcDoc->GetName(nSrcPos, aName);
943         CreateValidTabName(aName);
944         bValid = InsertTab(nDestPos, aName);
945     }
946     else                        // bestehende Tabelle ersetzen
947     {
948         if (VALIDTAB(nDestPos) && pTab[nDestPos])
949         {
950             pTab[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
951         }
952         else
953             bValid = sal_False;
954     }
955 
956     if (bValid)
957     {
958         sal_Bool bOldAutoCalcSrc = sal_False;
959         sal_Bool bOldAutoCalc = GetAutoCalc();
960         SetAutoCalc( sal_False );   // Mehrfachberechnungen vermeiden
961         SetNoListening( sal_True );
962         if ( bResultsOnly )
963         {
964             bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
965             pSrcDoc->SetAutoCalc( sal_True );   // falls was berechnet werden muss
966         }
967 
968         {
969             NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
970 
971             nDestPos = Min(nDestPos, (SCTAB)(GetTableCount() - 1));
972             {   // scope for bulk broadcast
973                 ScBulkBroadcast aBulkBroadcast( pBASM);
974                 pSrcDoc->pTab[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
975                         ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
976                         sal_False, pTab[nDestPos] );
977             }
978         }
979 
980         pTab[nDestPos]->SetTabNo(nDestPos);
981         pTab[nDestPos]->SetTabBgColor(pSrcDoc->pTab[nSrcPos]->GetTabBgColor());
982 
983         if ( !bResultsOnly )
984         {
985             sal_Bool bNamesLost = sal_False;
986             sal_uInt16 nSrcRangeNames = pSrcDoc->pRangeName->GetCount();
987             // array containing range names which might need update of indices
988             ScRangeData** pSrcRangeNames = nSrcRangeNames ? new ScRangeData* [nSrcRangeNames] : NULL;
989             // the index mapping thereof
990             ScRangeData::IndexMap aSrcRangeMap;
991             sal_Bool bRangeNameReplace = sal_False;
992 
993             // find named ranges that are used in the source sheet
994             std::set<sal_uInt16> aUsedNames;
995             pSrcDoc->pTab[nSrcPos]->FindRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aUsedNames );
996 
997             for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)     //! DB-Bereiche Pivot-Bereiche auch !!!
998             {
999                 ScRangeData* pSrcData = (*pSrcDoc->pRangeName)[i];
1000                 sal_uInt16 nOldIndex = pSrcData->GetIndex();
1001                 bool bInUse = ( aUsedNames.find(nOldIndex) != aUsedNames.end() );
1002                 if (bInUse)
1003                 {
1004                     sal_uInt16 nExisting = 0;
1005                     if ( pRangeName->SearchName( pSrcData->GetName(), nExisting ) )
1006                     {
1007                         // the name exists already in the destination document
1008                         // -> use the existing name, but show a warning
1009                         // (when refreshing links, the existing name is used and the warning not shown)
1010 
1011                         ScRangeData* pExistingData = (*pRangeName)[nExisting];
1012                         sal_uInt16 nExistingIndex = pExistingData->GetIndex();
1013 
1014                         pSrcRangeNames[i] = NULL;       // don't modify the named range
1015                         aSrcRangeMap.insert(
1016                             ScRangeData::IndexMap::value_type(nOldIndex, nExistingIndex));
1017                         bRangeNameReplace = sal_True;
1018                         bNamesLost = sal_True;
1019                     }
1020                     else
1021                     {
1022                         ScRangeData* pData = new ScRangeData( *pSrcData );
1023                         pData->SetDocument(this);
1024                         if ( pRangeName->FindIndex( pData->GetIndex() ) )
1025                             pData->SetIndex(0);     // need new index, done in Insert
1026                         if (!pRangeName->Insert(pData))
1027                         {
1028                             DBG_ERROR("can't insert name");     // shouldn't happen
1029                             delete pData;
1030                         }
1031                         else
1032                         {
1033                             pData->TransferTabRef( nSrcPos, nDestPos );
1034                             pSrcRangeNames[i] = pData;
1035                             sal_uInt16 nNewIndex = pData->GetIndex();
1036                             aSrcRangeMap.insert(
1037                                 ScRangeData::IndexMap::value_type(nOldIndex, nNewIndex));
1038                             if ( !bRangeNameReplace )
1039                                 bRangeNameReplace = ( nOldIndex != nNewIndex );
1040                         }
1041                     }
1042                 }
1043                 else
1044                 {
1045                     pSrcRangeNames[i] = NULL;
1046                     //aSrcRangeMap.SetPair( i, 0, 0 );      // not needed, defaulted
1047                 }
1048             }
1049             if ( bRangeNameReplace )
1050             {
1051                 // first update all inserted named formulas if they contain other
1052                 // range names and used indices changed
1053                 for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)     //! DB-Bereiche Pivot-Bereiche auch
1054                 {
1055                     if ( pSrcRangeNames[i] )
1056                         pSrcRangeNames[i]->ReplaceRangeNamesInUse( aSrcRangeMap );
1057                 }
1058                 // then update the formulas, they might need the just updated range names
1059                 pTab[nDestPos]->ReplaceRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aSrcRangeMap );
1060             }
1061             if ( pSrcRangeNames )
1062                 delete [] pSrcRangeNames;
1063 
1064             SCsTAB nDz = ((SCsTAB)nDestPos) - (SCsTAB)nSrcPos;
1065             pTab[nDestPos]->UpdateReference(URM_COPY, 0, 0, nDestPos,
1066                                                      MAXCOL, MAXROW, nDestPos,
1067                                                      0, 0, nDz, NULL);
1068             // Test for outside absolute references for info box
1069             sal_Bool bIsAbsRef = pSrcDoc->pTab[nSrcPos]->TestTabRefAbs(nSrcPos);
1070             // Readjust self-contained absolute references to this sheet
1071             pTab[nDestPos]->TestTabRefAbs(nSrcPos);
1072             if (bIsAbsRef)
1073             {
1074                 nRetVal += 1;
1075                     // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
1076             }
1077             if (bNamesLost)
1078             {
1079                 nRetVal += 2;
1080                 // message: duplicate names
1081             }
1082             pTab[nDestPos]->CompileAll();
1083         }
1084 
1085         SetNoListening( sal_False );
1086         if ( !bResultsOnly )
1087             pTab[nDestPos]->StartAllListeners();
1088         SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
1089 
1090         if ( bResultsOnly )
1091             pSrcDoc->SetAutoCalc( bOldAutoCalcSrc );
1092         SetAutoCalc( bOldAutoCalc );
1093 
1094         //  Drawing kopieren
1095 
1096         if (bInsertNew)
1097             TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
1098 
1099         pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
1100     }
1101     if (!bValid)
1102         nRetVal = 0;
1103     sal_Bool bVbaEnabled = IsInVBAMode();
1104 
1105     if ( bVbaEnabled  )
1106     {
1107         SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL;
1108         if ( pSrcShell )
1109         {
1110             StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL;
1111             String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
1112             if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 )
1113             {
1114                 aLibName = pSrcShell->GetBasicManager()->GetName();
1115                 pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName );
1116             }
1117 
1118             String sCodeName;
1119             String sSource;
1120             uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
1121             uno::Reference< container::XNameContainer > xLib;
1122             if( xLibContainer.is() )
1123             {
1124                 uno::Any aLibAny = xLibContainer->getByName( aLibName );
1125                 aLibAny >>= xLib;
1126             }
1127 
1128             if( xLib.is() )
1129             {
1130                 String sSrcCodeName;
1131                 pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName );
1132                 rtl::OUString sRTLSource;
1133                 xLib->getByName( sSrcCodeName ) >>= sRTLSource;
1134                 sSource = sRTLSource;
1135             }
1136             VBA_InsertModule( *this, nDestPos, sCodeName, sSource );
1137         }
1138     }
1139 
1140     return nRetVal;
1141 }
1142 
1143 //  ----------------------------------------------------------------------------
1144 
1145 void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError)
1146 {
1147     if (VALIDTAB(nTab))
1148         if (pTab[nTab])
1149             pTab[nTab]->SetError( nCol, nRow, nError );
1150 }
1151 
1152 void ScDocument::EraseNonUsedSharedNames(sal_uInt16 nLevel)
1153 {
1154     for (sal_uInt16 i = 0; i < pRangeName->GetCount(); i++)
1155     {
1156         ScRangeData* pRangeData = (*pRangeName)[i];
1157         if (pRangeData && pRangeData->HasType(RT_SHARED))
1158         {
1159             String aName;
1160             pRangeData->GetName(aName);
1161             aName.Erase(0, 6);                      // !!! vgl. Table4, FillFormula !!
1162             sal_uInt16 nInd = (sal_uInt16) aName.ToInt32();
1163             if (nInd <= nLevel)
1164             {
1165                 sal_uInt16 nIndex = pRangeData->GetIndex();
1166                 sal_Bool bInUse = sal_False;
1167                 for (SCTAB j = 0; !bInUse && (j <= MAXTAB); j++)
1168                 {
1169                     if (pTab[j])
1170                         bInUse = pTab[j]->IsRangeNameInUse(0, 0, MAXCOL-1, MAXROW-1,
1171                                                            nIndex);
1172                 }
1173                 if (!bInUse)
1174                     pRangeName->AtFree(i);
1175             }
1176         }
1177     }
1178 }
1179 
1180 //  ----------------------------------------------------------------------------
1181 
1182 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
1183 {
1184     delete pConsolidateDlgData;
1185 
1186     if ( pData )
1187         pConsolidateDlgData = new ScConsolidateParam( *pData );
1188     else
1189         pConsolidateDlgData = NULL;
1190 }
1191 
1192 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings& rNew)
1193 {
1194     if (pChangeViewSettings==NULL)
1195         pChangeViewSettings = new ScChangeViewSettings;
1196 
1197     DBG_ASSERT( pChangeViewSettings, "Oops. No ChangeViewSettings :-( by!" );
1198 
1199     *pChangeViewSettings=rNew;
1200 }
1201 
1202 //  ----------------------------------------------------------------------------
1203 
1204 ScFieldEditEngine* ScDocument::CreateFieldEditEngine()
1205 {
1206     ScFieldEditEngine* pNewEditEngine = NULL;
1207     if (!pCacheFieldEditEngine)
1208     {
1209         pNewEditEngine = new ScFieldEditEngine( GetEnginePool(),
1210             GetEditPool(), sal_False );
1211     }
1212     else
1213     {
1214         if ( !bImportingXML )
1215         {
1216             // #i66209# previous use might not have restored update mode,
1217             // ensure same state as for a new EditEngine (UpdateMode = sal_True)
1218             if ( !pCacheFieldEditEngine->GetUpdateMode() )
1219                 pCacheFieldEditEngine->SetUpdateMode(sal_True);
1220         }
1221 
1222         pNewEditEngine = pCacheFieldEditEngine;
1223         pCacheFieldEditEngine = NULL;
1224     }
1225     return pNewEditEngine;
1226 }
1227 
1228 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine)
1229 {
1230     if (!pCacheFieldEditEngine && rpEditEngine)
1231     {
1232         pCacheFieldEditEngine = rpEditEngine;
1233         pCacheFieldEditEngine->Clear();
1234     }
1235     else
1236         delete rpEditEngine;
1237     rpEditEngine = NULL;
1238 }
1239 
1240 //  ----------------------------------------------------------------------------
1241 
1242 // static
1243 ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
1244 {
1245     return new ScRecursionHelper;
1246 }
1247 
1248 //  ----------------------------------------------------------------------------
1249 
1250 ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
1251 {
1252     ScLookupCache* pCache = 0;
1253     if (!pLookupCacheMapImpl)
1254         pLookupCacheMapImpl = new ScLookupCacheMapImpl;
1255     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find( rRange));
1256     if (it == pLookupCacheMapImpl->aCacheMap.end())
1257     {
1258         pCache = new ScLookupCache( this, rRange);
1259         AddLookupCache( *pCache);
1260     }
1261     else
1262         pCache = (*it).second;
1263     return *pCache;
1264 }
1265 
1266 void ScDocument::AddLookupCache( ScLookupCache & rCache )
1267 {
1268     if (!pLookupCacheMapImpl->aCacheMap.insert( ::std::pair< const ScRange,
1269                 ScLookupCache*>( rCache.getRange(), &rCache)).second)
1270     {
1271         DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
1272     }
1273     else
1274         StartListeningArea( rCache.getRange(), &rCache);
1275 }
1276 
1277 void ScDocument::RemoveLookupCache( ScLookupCache & rCache )
1278 {
1279     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find(
1280                 rCache.getRange()));
1281     if (it == pLookupCacheMapImpl->aCacheMap.end())
1282     {
1283         DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
1284     }
1285     else
1286     {
1287         ScLookupCache* pCache = (*it).second;
1288         pLookupCacheMapImpl->aCacheMap.erase( it);
1289         EndListeningArea( pCache->getRange(), &rCache);
1290     }
1291 }
1292 
1293 void ScDocument::ClearLookupCaches()
1294 {
1295     if( pLookupCacheMapImpl )
1296         pLookupCacheMapImpl->clear();
1297 }
1298