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