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