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