xref: /AOO41X/main/sc/source/core/data/documen2.cxx (revision 611fcdab0900c77ff92ad579f9da6d63d2aca818)
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;
~ScLookupCacheMapImplScLookupCacheMapImpl104     ~ScLookupCacheMapImpl()
105     {
106         freeCaches();
107     }
clearScLookupCacheMapImpl108     void clear()
109     {
110         freeCaches();
111         // Zap map.
112         ScLookupCacheMap aTmp;
113         aCacheMap.swap( aTmp);
114     }
115 private:
freeCachesScLookupCacheMapImpl116     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 
ScDocument(ScDocumentMode eMode,SfxObjectShell * pDocShell)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         {
233             pLinkManager = new sfx2::LinkManager(pDocShell);
234             pLinkManager->SetAutoAskUpdateAllLinks();
235         }
236 
237         xPoolHelper = new ScPoolHelper( this );
238 
239         pTab[0]  = NULL;
240         pBASM = new ScBroadcastAreaSlotMachine( this );
241         pChartListenerCollection = new ScChartListenerCollection( this );
242         pRefreshTimerControl = new ScRefreshTimerControl;
243     }
244     else
245     {
246         pTab[0]     = NULL;
247         pBASM       = NULL;
248         pChartListenerCollection = NULL;
249         pRefreshTimerControl = NULL;
250     }
251 
252     for (SCTAB i=1; i<=MAXTAB; i++)
253         pTab[i] = NULL;
254 
255     pRangeName = new ScRangeName( 4, 4, sal_False, this );
256     pDBCollection = new ScDBCollection( 4, 4, sal_False, this );
257     pSelectionAttr = NULL;
258     pChartCollection = new ScChartCollection;
259     apTemporaryChartLock = std::auto_ptr< ScTemporaryChartLock >( new ScTemporaryChartLock(this) );
260     xColNameRanges = new ScRangePairList;
261     xRowNameRanges = new ScRangePairList;
262     ImplCreateOptions();
263     // languages for a visible document are set by docshell later (from options)
264     SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
265 
266     aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
267     aTrackTimer.SetTimeout( 100 );
268 }
269 
GetLinkManager() const270 sfx2::LinkManager*  ScDocument::GetLinkManager()  const
271 {
272     if ( bAutoCalc && !pLinkManager && pShell)
273     {
274         pLinkManager = new sfx2::LinkManager( pShell );
275         pLinkManager->SetAutoAskUpdateAllLinks();
276     }
277     return pLinkManager;
278 }
279 
280 
SetStorageGrammar(formula::FormulaGrammar::Grammar eGram)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 
SetDocVisible(sal_Bool bSet)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 
GetDocumentID() const307 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 
StartChangeTracking()317 void ScDocument::StartChangeTracking()
318 {
319     if (!pChangeTrack)
320         pChangeTrack = new ScChangeTrack( this );
321 }
322 
EndChangeTracking()323 void ScDocument::EndChangeTracking()
324 {
325     delete pChangeTrack;
326     pChangeTrack = NULL;
327 }
328 
SetChangeTrack(ScChangeTrack * pTrack)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 
IMPL_LINK(ScDocument,TrackTimeHdl,Timer *,EMPTYARG)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 
StartTrackTimer()368 void ScDocument::StartTrackTimer()
369 {
370     if (!aTrackTimer.IsActive())        // nicht ewig aufschieben
371         aTrackTimer.Start();
372 }
373 
~ScDocument()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 
InitClipPtrs(ScDocument * pSourceDoc)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 
GetFormatTable() const520 SvNumberFormatter* ScDocument::GetFormatTable() const
521 {
522     return xPoolHelper->GetFormTable();
523 }
524 
GetEditPool() const525 SfxItemPool* ScDocument::GetEditPool() const
526 {
527     return xPoolHelper->GetEditPool();
528 }
529 
GetEnginePool() const530 SfxItemPool* ScDocument::GetEnginePool() const
531 {
532     return xPoolHelper->GetEnginePool();
533 }
534 
GetEditEngine()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 
GetNoteEngine()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 
ResetClip(ScDocument * pSourceDoc,const ScMarkData * pMarks)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 
ResetClip(ScDocument * pSourceDoc,SCTAB nTab)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 
DeleteNumberFormat(const sal_uInt32 *,sal_uInt32)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 
PutCell(SCCOL nCol,SCROW nRow,SCTAB nTab,ScBaseCell * pCell,sal_uLong nFormatIndex,sal_Bool bForceTab)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 
GetPrintArea(SCTAB nTab,SCCOL & rEndCol,SCROW & rEndRow,sal_Bool bNotes) const650 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 
GetPrintAreaHor(SCTAB nTab,SCROW nStartRow,SCROW nEndRow,SCCOL & rEndCol,sal_Bool bNotes) const674 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 
GetPrintAreaVer(SCTAB nTab,SCCOL nStartCol,SCCOL nEndCol,SCROW & rEndRow,sal_Bool bNotes) const696 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 
GetDataStart(SCTAB nTab,SCCOL & rStartCol,SCROW & rStartRow) const718 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 
MoveTab(SCTAB nOldPos,SCTAB nNewPos)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 
CopyTab(SCTAB nOldPos,SCTAB nNewPos,const ScMarkData * pOnlyMarked)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 
TransferTab(ScDocument * pSrcDoc,SCTAB nSrcPos,SCTAB nDestPos,sal_Bool bInsertNew,sal_Bool bResultsOnly)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 
SetError(SCCOL nCol,SCROW nRow,SCTAB nTab,const sal_uInt16 nError)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 
EraseNonUsedSharedNames(sal_uInt16 nLevel)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 
SetConsolidateDlgData(const ScConsolidateParam * pData)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 
SetChangeViewSettings(const ScChangeViewSettings & rNew)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 
CreateFieldEditEngine()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 
DisposeFieldEditEngine(ScFieldEditEngine * & rpEditEngine)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
CreateRecursionHelperInstance()1251 ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
1252 {
1253     return new ScRecursionHelper;
1254 }
1255 
1256 //  ----------------------------------------------------------------------------
1257 
GetLookupCache(const ScRange & rRange)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 
AddLookupCache(ScLookupCache & rCache)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 
RemoveLookupCache(ScLookupCache & rCache)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 
ClearLookupCaches()1301 void ScDocument::ClearLookupCaches()
1302 {
1303     if( pLookupCacheMapImpl )
1304         pLookupCacheMapImpl->clear();
1305 }
IsCellInChangeTrack(const ScAddress & cell,Color * pColCellBoder)1306 sal_Bool ScDocument::IsCellInChangeTrack(const ScAddress &cell,Color *pColCellBoder)
1307 {
1308     ScChangeTrack* pTrack = GetChangeTrack();
1309     ScChangeViewSettings* pSettings = GetChangeViewSettings();
1310     if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
1311         return sal_False;           // nix da oder abgeschaltet
1312     ScActionColorChanger aColorChanger(*pTrack);
1313     //  Clipping passiert von aussen
1314     //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
1315     const ScChangeAction* pAction = pTrack->GetFirst();
1316     while (pAction)
1317     {
1318         ScChangeActionType eType;
1319         if ( pAction->IsVisible() )
1320         {
1321             eType = pAction->GetType();
1322             const ScBigRange& rBig = pAction->GetBigRange();
1323             if ( rBig.aStart.Tab() == cell.Tab())
1324             {
1325                 ScRange aRange = rBig.MakeRange();
1326                 if ( eType == SC_CAT_DELETE_ROWS )
1327                     aRange.aEnd.SetRow( aRange.aStart.Row() );
1328                 else if ( eType == SC_CAT_DELETE_COLS )
1329                     aRange.aEnd.SetCol( aRange.aStart.Col() );
1330                 if (ScViewUtil::IsActionShown( *pAction, *pSettings, *this ) )
1331                 {
1332                     if (aRange.In(cell))
1333                     {
1334                         if (pColCellBoder != NULL)
1335                         {
1336                             aColorChanger.Update( *pAction );
1337                             Color aColor( aColorChanger.GetColor() );
1338                             *pColCellBoder = aColor;
1339                         }
1340                         return sal_True;
1341                     }
1342                 }
1343             }
1344             if ( eType == SC_CAT_MOVE &&
1345                 ((const ScChangeActionMove*)pAction)->
1346                 GetFromRange().aStart.Tab() == cell.Col() )
1347             {
1348                 ScRange aRange = ((const ScChangeActionMove*)pAction)->
1349                     GetFromRange().MakeRange();
1350                 if (ScViewUtil::IsActionShown( *pAction, *pSettings, *this ) )
1351                 {
1352                     if (aRange.In(cell))
1353                     {
1354                         if (pColCellBoder != NULL)
1355                         {
1356                             aColorChanger.Update( *pAction );
1357                             Color aColor( aColorChanger.GetColor() );
1358                             *pColCellBoder = aColor;
1359                         }
1360                         return sal_True;
1361                     }
1362                 }
1363             }
1364         }
1365         pAction = pAction->GetNext();
1366     }
1367     return sal_False;
1368 }
GetCellChangeTrackNote(const ScAddress & aCellPos,String & aTrackText,sal_Bool & bLeftEdge)1369 void ScDocument::GetCellChangeTrackNote( const ScAddress &aCellPos,String &aTrackText,sal_Bool &bLeftEdge)
1370 {
1371     aTrackText=String();
1372     //  Change-Tracking
1373     ScChangeTrack* pTrack = GetChangeTrack();
1374     ScChangeViewSettings* pSettings = GetChangeViewSettings();
1375     if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
1376     {
1377         const ScChangeAction* pFound = NULL;
1378         const ScChangeAction* pFoundContent = NULL;
1379         const ScChangeAction* pFoundMove = NULL;
1380         long nModified = 0;
1381         const ScChangeAction* pAction = pTrack->GetFirst();
1382         while (pAction)
1383         {
1384             if ( pAction->IsVisible() &&
1385                  ScViewUtil::IsActionShown( *pAction, *pSettings, *this ) )
1386             {
1387                 ScChangeActionType eType = pAction->GetType();
1388                 const ScBigRange& rBig = pAction->GetBigRange();
1389                 if ( rBig.aStart.Tab() == aCellPos.Tab())
1390                 {
1391                     ScRange aRange = rBig.MakeRange();
1392                     if ( eType == SC_CAT_DELETE_ROWS )
1393                         aRange.aEnd.SetRow( aRange.aStart.Row() );
1394                     else if ( eType == SC_CAT_DELETE_COLS )
1395                         aRange.aEnd.SetCol( aRange.aStart.Col() );
1396                     if ( aRange.In( aCellPos ) )
1397                     {
1398                         pFound = pAction;       // der letzte gewinnt
1399                         switch ( eType )
1400                         {
1401                             case SC_CAT_CONTENT :
1402                                 pFoundContent = pAction;
1403                             break;
1404                             case SC_CAT_MOVE :
1405                                 pFoundMove = pAction;
1406                             break;
1407                             default:
1408                                 break;
1409                         }
1410                         ++nModified;
1411                     }
1412                 }
1413                 if ( eType == SC_CAT_MOVE )
1414                 {
1415                     ScRange aRange =
1416                         ((const ScChangeActionMove*)pAction)->
1417                         GetFromRange().MakeRange();
1418                     if ( aRange.In( aCellPos ) )
1419                     {
1420                         pFound = pAction;
1421                         ++nModified;
1422                     }
1423                 }
1424             }
1425             pAction = pAction->GetNext();
1426         }
1427         if ( pFound )
1428         {
1429             if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
1430                 pFound = pFoundContent;     // Content gewinnt
1431             if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
1432                     pFoundMove->GetActionNumber() >
1433                     pFound->GetActionNumber() )
1434                 pFound = pFoundMove;        // Move gewinnt
1435             //  bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
1436             if ( pFound->GetType() == SC_CAT_DELETE_COLS )
1437                 bLeftEdge = sal_True;
1438             DateTime aDT = pFound->GetDateTime();
1439             aTrackText  = pFound->GetUser();
1440             aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
1441             aTrackText += ScGlobal::pLocaleData->getDate(aDT);
1442             aTrackText += ' ';
1443             aTrackText += ScGlobal::pLocaleData->getTime(aDT);
1444             aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ":\n" ));
1445             String aComStr=pFound->GetComment();
1446             if(aComStr.Len()>0)
1447             {
1448                 aTrackText += aComStr;
1449                 aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n( " ));
1450             }
1451             pFound->GetDescription( aTrackText, this );
1452             if(aComStr.Len()>0)
1453             {
1454                 aTrackText +=')';
1455             }
1456         }
1457     }
1458 }
1459