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