xref: /aoo41x/main/sc/source/core/data/documen2.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #define _ZFORLIST_DECLARE_TABLE
34 #include "scitems.hxx"
35 #include <editeng/eeitem.hxx>
36 
37 #include <editeng/editeng.hxx>
38 #include <editeng/forbiddencharacterstable.hxx>
39 #include <sfx2/linkmgr.hxx>
40 #include <svx/svdpool.hxx>
41 #include <svx/svdobj.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/objsh.hxx>
44 #include <sfx2/printer.hxx>
45 #include <svl/zforlist.hxx>
46 #include <svl/zformat.hxx>
47 #include <vcl/virdev.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <svl/PasswordHelper.hxx>
50 #include <tools/tenccvt.hxx>
51 #include <tools/list.hxx>
52 #include <rtl/crc.h>
53 #include <basic/basmgr.hxx>
54 
55 #include "document.hxx"
56 #include "table.hxx"
57 #include "attrib.hxx"
58 #include "patattr.hxx"
59 #include "rangenam.hxx"
60 #include "dbcolect.hxx"
61 #include "pivot.hxx"
62 #include "docpool.hxx"
63 #include "stlpool.hxx"
64 #include "stlsheet.hxx"
65 #include "globstr.hrc"
66 #include "chartarr.hxx"
67 #include "chartlock.hxx"
68 #include "rechead.hxx"
69 #include "global.hxx"
70 #include "brdcst.hxx"
71 #include "bcaslot.hxx"
72 #include "adiasync.hxx"
73 #include "addinlis.hxx"
74 #include "chartlis.hxx"
75 #include "markdata.hxx"
76 #include "conditio.hxx"
77 #include "validat.hxx"
78 #include "progress.hxx"
79 #include "detdata.hxx"
80 #include "sc.hrc"				// FID_DATACHANGED
81 #include "ddelink.hxx"
82 #include "chgtrack.hxx"
83 #include "chgviset.hxx"
84 #include "editutil.hxx"
85 #include "hints.hxx"
86 #include "dpobject.hxx"
87 #include "scrdata.hxx"
88 #include "poolhelp.hxx"
89 #include "unoreflist.hxx"
90 #include "listenercalls.hxx"
91 #include "recursionhelper.hxx"
92 #include "lookupcache.hxx"
93 #include "externalrefmgr.hxx"
94 #include "tabprotection.hxx"
95 #include "formulaparserpool.hxx"
96 #include "clipparam.hxx"
97 
98 using namespace com::sun::star;
99 
100 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
101 // dtor plus helpers are convenient.
102 struct ScLookupCacheMapImpl
103 {
104     ScLookupCacheMap aCacheMap;
105     ~ScLookupCacheMapImpl()
106     {
107         freeCaches();
108     }
109     void clear()
110     {
111         freeCaches();
112         // Zap map.
113         ScLookupCacheMap aTmp;
114         aCacheMap.swap( aTmp);
115     }
116 private:
117     void freeCaches()
118     {
119         for (ScLookupCacheMap::iterator it( aCacheMap.begin()); it != aCacheMap.end(); ++it)
120             delete (*it).second;
121     }
122 };
123 
124 // STATIC DATA -----------------------------------------------------------
125 
126 ScDocument::ScDocument( ScDocumentMode	eMode,
127 						SfxObjectShell* pDocShell ) :
128 		xServiceManager( ::comphelper::getProcessServiceFactory() ),
129 		mpUndoManager( NULL ),
130 		pEditEngine( NULL ),
131 		pNoteEngine( NULL ),
132 		pNoteItemPool( NULL ),
133 		pShell( pDocShell ),
134 		pPrinter( NULL ),
135 		pVirtualDevice_100th_mm( NULL ),
136 		pDrawLayer( NULL ),
137 		pColorTable( NULL ),
138 		pCondFormList( NULL ),
139 		pValidationList( NULL ),
140 		pFormatExchangeList( NULL ),
141 		pDPCollection( NULL ),
142 		pLinkManager( NULL ),
143 		pFormulaTree( NULL ),
144 		pEOFormulaTree( NULL ),
145 		pFormulaTrack( NULL ),
146 		pEOFormulaTrack( NULL ),
147 		pOtherObjects( NULL ),
148 		pClipData( NULL ),
149 		pDetOpList(NULL),
150 		pChangeTrack( NULL ),
151 		pUnoBroadcaster( NULL ),
152 		pUnoListenerCalls( NULL ),
153         pUnoRefUndoList( NULL ),
154 		pChangeViewSettings( NULL ),
155 		pScriptTypeData( NULL ),
156         pCacheFieldEditEngine( NULL ),
157         pDocProtection( NULL ),
158         mpClipParam( NULL),
159         pExternalRefMgr( NULL ),
160 		pViewOptions( NULL ),
161 		pDocOptions( NULL ),
162 		pExtDocOptions( NULL ),
163 		pConsolidateDlgData( NULL ),
164         pRecursionHelper( NULL ),
165         pAutoNameCache( NULL ),
166         pLookupCacheMapImpl( NULL ),
167         nUnoObjectId( 0 ),
168         nRangeOverflowType( 0 ),
169 		aCurTextWidthCalcPos(MAXCOL,0,0),
170 		nFormulaCodeInTree(0),
171         nXMLImportedFormulaCount( 0 ),
172 		nInterpretLevel(0),
173 		nMacroInterpretLevel(0),
174 		nInterpreterTableOpLevel(0),
175 		nMaxTableNumber( 0 ),
176 	    nSrcVer( SC_CURRENT_VERSION ),
177 	    nSrcMaxRow( MAXROW ),
178 		nFormulaTrackCount(0),
179 		nHardRecalcState(0),
180 		nVisibleTab( 0 ),
181 		eLinkMode(LM_UNKNOWN),
182 		bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
183 		bAutoCalcShellDisabled( sal_False ),
184 		bForcedFormulaPending( sal_False ),
185 		bCalculatingFormulaTree( sal_False ),
186 		bIsClip( eMode == SCDOCMODE_CLIP ),
187 		bIsUndo( eMode == SCDOCMODE_UNDO ),
188 		bIsVisible( sal_False ),
189 		bIsEmbedded( sal_False ),
190 //		bNoSetDirty( sal_True ),
191 		bNoSetDirty( sal_False ),
192 		bInsertingFromOtherDoc( sal_False ),
193         bLoadingMedium( false ),
194 		bImportingXML( 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         bSetDrawDefaults( sal_False ),
211         bPastingDrawFromOtherDoc( sal_False ),
212         nInDdeLinkUpdate( 0 ),
213         bInUnoBroadcast( sal_False ),
214         bInUnoListenerCall( sal_False ),
215         eGrammar( formula::FormulaGrammar::GRAM_NATIVE ),
216         bStyleSheetUsageInvalid( sal_True ),
217         mbUndoEnabled( true ),
218         mbAdjustHeightEnabled( true ),
219         mbExecuteLinkEnabled( true ),
220         mbChangeReadOnlyEnabled( false ),
221         mbStreamValidLocked( false ),
222         mnNamedRangesLockCount( 0 )
223 {
224     SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
225 
226 	eSrcSet = gsl_getSystemTextEncoding();
227 
228 	if ( eMode == SCDOCMODE_DOCUMENT )
229 	{
230 		if ( pDocShell )
231 			pLinkManager = new sfx2::LinkManager( pDocShell );
232 
233 		xPoolHelper = new ScPoolHelper( this );
234 
235 		pTab[0]  = NULL;
236 		pBASM = new ScBroadcastAreaSlotMachine( this );
237 		pChartListenerCollection = new ScChartListenerCollection( this );
238 		pRefreshTimerControl = new ScRefreshTimerControl;
239 	}
240 	else
241 	{
242 		pTab[0]		= NULL;
243 		pBASM		= NULL;
244 		pChartListenerCollection = NULL;
245 		pRefreshTimerControl = NULL;
246 	}
247 
248 	for (SCTAB i=1; i<=MAXTAB; i++)
249 		pTab[i] = NULL;
250 
251 	pRangeName = new ScRangeName( 4, 4, sal_False, this );
252 	pDBCollection = new ScDBCollection( 4, 4, sal_False, this );
253 	pSelectionAttr = NULL;
254 	pChartCollection = new ScChartCollection;
255     apTemporaryChartLock = std::auto_ptr< ScTemporaryChartLock >( new ScTemporaryChartLock(this) );
256 	xColNameRanges = new ScRangePairList;
257 	xRowNameRanges = new ScRangePairList;
258 	ImplCreateOptions();
259 	// languages for a visible document are set by docshell later (from options)
260 	SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
261 
262 	aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
263 	aTrackTimer.SetTimeout( 100 );
264 }
265 
266 sfx2::LinkManager*	ScDocument::GetLinkManager()  const
267 {
268     if ( bAutoCalc && !pLinkManager && pShell)
269 	{
270 		pLinkManager = new sfx2::LinkManager( pShell );
271     }
272     return pLinkManager;
273 }
274 
275 
276 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
277 {
278     DBG_ASSERT(
279         eGram == formula::FormulaGrammar::GRAM_ODFF ||
280             eGram == formula::FormulaGrammar::GRAM_PODF,
281             "ScDocument::SetStorageGrammar: wrong storage grammar");
282 
283     eStorageGrammar = eGram;
284 
285     // FIXME: the XML import shouldn't strip brackets, the compiler should
286     // digest them instead, which could also speedup reference recognition
287     // during import.
288 
289     eXmlImportGrammar = formula::FormulaGrammar::mergeToGrammar( eGram,
290             formula::FormulaGrammar::CONV_OOO);
291 }
292 
293 
294 void ScDocument::SetDocVisible( sal_Bool bSet )
295 {
296 	//	called from view ctor - only for a visible document,
297 	//	each new sheet's RTL flag is initialized from the locale
298 	bIsVisible = bSet;
299 }
300 
301 
302 sal_uInt32 ScDocument::GetDocumentID() const
303 {
304     const ScDocument* pThis = this;
305     sal_uInt32 nCrc = rtl_crc32( 0, &pThis, sizeof(ScDocument*) );
306     // the this pointer only might not be sufficient
307     nCrc = rtl_crc32( nCrc, &pShell, sizeof(SfxObjectShell*) );
308     return nCrc;
309 }
310 
311 
312 void ScDocument::StartChangeTracking()
313 {
314 	if (!pChangeTrack)
315 		pChangeTrack = new ScChangeTrack( this );
316 }
317 
318 void ScDocument::EndChangeTracking()
319 {
320 	delete pChangeTrack;
321 	pChangeTrack = NULL;
322 }
323 
324 void ScDocument::SetChangeTrack( ScChangeTrack* pTrack )
325 {
326 	DBG_ASSERT( pTrack->GetDocument() == this, "SetChangeTrack: different documents" );
327 	if ( !pTrack || pTrack == pChangeTrack || pTrack->GetDocument() != this )
328 		return ;
329 	EndChangeTracking();
330 	pChangeTrack = pTrack;
331 }
332 
333 
334 IMPL_LINK( ScDocument, TrackTimeHdl, Timer*, EMPTYARG )
335 {
336 	if ( ScDdeLink::IsInUpdate() )		// nicht verschachteln
337 	{
338 		aTrackTimer.Start();			// spaeter nochmal versuchen
339 	}
340 	else if (pShell)					// ausfuehren
341 	{
342 		TrackFormulas();
343 		pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
344 		ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
345 
346 			//	modified...
347 
348 		if (!pShell->IsModified())
349 		{
350 			pShell->SetModified( sal_True );
351 			SfxBindings* pBindings = GetViewBindings();
352 			if (pBindings)
353 			{
354 				pBindings->Invalidate( SID_SAVEDOC );
355 				pBindings->Invalidate( SID_DOC_MODIFIED );
356 			}
357 		}
358 	}
359 
360 	return 0;
361 }
362 
363 void ScDocument::StartTrackTimer()
364 {
365 	if (!aTrackTimer.IsActive())		// nicht ewig aufschieben
366 		aTrackTimer.Start();
367 }
368 
369 ScDocument::~ScDocument()
370 {
371 	DBG_ASSERT( !bInLinkUpdate, "bInLinkUpdate in dtor" );
372 
373 	bInDtorClear = sal_True;
374 
375 	// first of all disable all refresh timers by deleting the control
376 	if ( pRefreshTimerControl )
377 	{	// To be sure there isn't anything running do it with a protector,
378 		// this ensures also that nothing needs the control anymore.
379 		ScRefreshTimerProtector aProt( GetRefreshTimerControlAddress() );
380 		delete pRefreshTimerControl, pRefreshTimerControl = NULL;
381 	}
382 
383 	// Links aufrauemen
384 
385 	if ( GetLinkManager() )
386 	{
387 		// BaseLinks freigeben
388 		for ( sal_uInt16 n = pLinkManager->GetServers().Count(); n; )
389 			pLinkManager->GetServers()[ --n ]->Closed();
390 
391 		if ( pLinkManager->GetLinks().Count() )
392 			pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
393 	}
394 
395     mxFormulaParserPool.reset();
396     // Destroy the external ref mgr instance here because it has a timer
397     // which needs to be stopped before the app closes.
398     pExternalRefMgr.reset();
399 
400 	ScAddInAsync::RemoveDocument( this );
401 	ScAddInListener::RemoveDocument( this );
402     DELETEZ( pChartListenerCollection);   // vor pBASM wg. evtl. Listener!
403     DELETEZ( pLookupCacheMapImpl);  // before pBASM because of listeners
404 	// BroadcastAreas vor allen Zellen zerstoeren um unnoetige
405 	// Einzel-EndListenings der Formelzellen zu vermeiden
406 	delete pBASM;		// BroadcastAreaSlotMachine
407 	pBASM = NULL;
408 
409 	if (pUnoBroadcaster)
410 	{
411 		delete pUnoBroadcaster;		// broadcasted nochmal SFX_HINT_DYING
412 		pUnoBroadcaster = NULL;
413 	}
414 
415     delete pUnoRefUndoList;
416 	delete pUnoListenerCalls;
417 
418     Clear( sal_True );              // sal_True = from destructor (needed for SdrModel::ClearModel)
419 
420 	if (pCondFormList)
421 	{
422 		pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
423 		DELETEZ(pCondFormList);
424 	}
425 	if (pValidationList)
426 	{
427 		pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
428 		DELETEZ(pValidationList);
429 	}
430 	delete pRangeName;
431 	delete pDBCollection;
432 	delete pSelectionAttr;
433     apTemporaryChartLock.reset();
434 	delete pChartCollection;
435 	DeleteDrawLayer();
436 	delete pFormatExchangeList;
437 	delete pPrinter;
438 	ImplDeleteOptions();
439 	delete pConsolidateDlgData;
440 	delete pLinkManager;
441 	delete pClipData;
442 	delete pDetOpList;					// loescht auch die Eintraege
443 	delete pChangeTrack;
444 	delete pEditEngine;
445 	delete pNoteEngine;
446 	SfxItemPool::Free(pNoteItemPool);
447 	delete pChangeViewSettings;			// und weg damit
448 	delete pVirtualDevice_100th_mm;
449 
450     if (pDPCollection)
451     {
452         pDPCollection->FreeAll();
453         RemoveUnusedDPObjectCaches();
454         delete pDPCollection;
455     }
456 
457 	// delete the EditEngine before destroying the xPoolHelper
458 	delete pCacheFieldEditEngine;
459 
460 	if ( xPoolHelper.isValid() && !bIsClip )
461 		xPoolHelper->SourceDocumentGone();
462 	xPoolHelper.unbind();
463 
464 	DeleteColorTable();
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 			++nMaxTableNumber;
842 		}
843 		else
844 		{
845 			if (VALIDTAB(nNewPos) && (nNewPos < nMaxTableNumber))
846 			{
847 				SetNoListening( sal_True );
848 
849 				ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
850 				xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
851 				xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
852 				pRangeName->UpdateTabRef(nNewPos, 1);
853 				pDBCollection->UpdateReference(
854 									URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
855 				if (pDPCollection)
856 					pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
857 				if (pDetOpList)
858 					pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
859 				UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
860 				UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
861 				if ( pUnoBroadcaster )
862 					pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
863 
864 				SCTAB i;
865 				for (i = 0; i <= MAXTAB; i++)
866 					if (pTab[i] && i != nOldPos)
867 						pTab[i]->UpdateInsertTab(nNewPos);
868 				for (i = nMaxTableNumber; i > nNewPos; i--)
869 					pTab[i] = pTab[i - 1];
870 				if (nNewPos <= nOldPos)
871 					nOldPos++;
872 				pTab[nNewPos] = new ScTable(this, nNewPos, aName);
873 				++nMaxTableNumber;
874 				bValid = sal_True;
875 				for (i = 0; i <= MAXTAB; i++)
876 					if (pTab[i] && i != nOldPos && i != nNewPos)
877 						pTab[i]->UpdateCompile();
878 				SetNoListening( sal_False );
879 				for (i = 0; i <= MAXTAB; i++)
880 					if (pTab[i] && i != nOldPos && i != nNewPos)
881 						pTab[i]->StartAllListeners();
882 
883 				//	update conditional formats after table is inserted
884 				if ( pCondFormList )
885 					pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
886 				if ( pValidationList )
887 					pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
888 				// #81844# sheet names of references may not be valid until sheet is copied
889 				pChartListenerCollection->UpdateScheduledSeriesRanges();
890 			}
891 			else
892 				bValid = sal_False;
893 		}
894 	}
895 	if (bValid)
896 	{
897 		SetNoListening( sal_True );		// noch nicht bei CopyToTable/Insert
898 		pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
899 										pTab[nNewPos], pOnlyMarked );
900         pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
901 
902 		SCsTAB nDz;
903 /*		if (nNewPos < nOldPos)
904 			nDz = ((short)nNewPos) - (short)nOldPos + 1;
905 		else
906 */			nDz = ((short)nNewPos) - (short)nOldPos;
907 		pTab[nNewPos]->UpdateReference(URM_COPY, 0, 0, nNewPos , MAXCOL, MAXROW,
908 										nNewPos, 0, 0, nDz, NULL);
909 
910 		pTab[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
911 		pTab[nOldPos]->UpdateInsertTab(nNewPos);
912 
913 		pTab[nOldPos]->UpdateCompile();
914 		pTab[nNewPos]->UpdateCompile( sal_True );	// #67996# maybe already compiled in Clone, but used names need recompilation
915 		SetNoListening( sal_False );
916 		pTab[nOldPos]->StartAllListeners();
917 		pTab[nNewPos]->StartAllListeners();
918 		SetDirty();
919 		SetAutoCalc( bOldAutoCalc );
920 
921 		if (pDrawLayer)
922 			DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
923 
924 		pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
925         pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
926 	}
927 	else
928 		SetAutoCalc( bOldAutoCalc );
929 	return bValid;
930 }
931 
932 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
933 
934 sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
935 								SCTAB nDestPos, sal_Bool bInsertNew,
936 								sal_Bool bResultsOnly )
937 {
938 	sal_uLong nRetVal = 1;						// 0 => Fehler 1 = ok
939 											// 2 => RefBox, 3 => NameBox
940 											// 4 => beides
941 	sal_Bool bValid = sal_True;
942 	if (bInsertNew)				// neu einfuegen
943 	{
944 		String aName;
945 		pSrcDoc->GetName(nSrcPos, aName);
946 		CreateValidTabName(aName);
947 		bValid = InsertTab(nDestPos, aName);
948 	}
949 	else						// bestehende Tabelle ersetzen
950 	{
951 		if (VALIDTAB(nDestPos) && pTab[nDestPos])
952 		{
953 			pTab[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
954 		}
955 		else
956 			bValid = sal_False;
957 	}
958 
959 	if (bValid)
960 	{
961         sal_Bool bOldAutoCalcSrc = sal_False;
962 		sal_Bool bOldAutoCalc = GetAutoCalc();
963 		SetAutoCalc( sal_False );	// Mehrfachberechnungen vermeiden
964 		SetNoListening( sal_True );
965 		if ( bResultsOnly )
966 		{
967 			bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
968 			pSrcDoc->SetAutoCalc( sal_True );	// falls was berechnet werden muss
969 		}
970 
971 		{
972             NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
973 
974             nDestPos = Min(nDestPos, (SCTAB)(GetTableCount() - 1));
975             {   // scope for bulk broadcast
976                 ScBulkBroadcast aBulkBroadcast( pBASM);
977                 pSrcDoc->pTab[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
978                         ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
979                         sal_False, pTab[nDestPos] );
980             }
981         }
982 		pTab[nDestPos]->SetTabNo(nDestPos);
983 
984 		if ( !bResultsOnly )
985 		{
986             sal_Bool bNamesLost = sal_False;
987 			sal_uInt16 nSrcRangeNames = pSrcDoc->pRangeName->GetCount();
988 			// array containing range names which might need update of indices
989 			ScRangeData** pSrcRangeNames = nSrcRangeNames ? new ScRangeData* [nSrcRangeNames] : NULL;
990 			// the index mapping thereof
991             ScRangeData::IndexMap aSrcRangeMap;
992 			sal_Bool bRangeNameReplace = sal_False;
993 
994             // find named ranges that are used in the source sheet
995             std::set<sal_uInt16> aUsedNames;
996             pSrcDoc->pTab[nSrcPos]->FindRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aUsedNames );
997 
998 			for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)		//! DB-Bereiche Pivot-Bereiche auch !!!
999 			{
1000 				ScRangeData* pSrcData = (*pSrcDoc->pRangeName)[i];
1001 				sal_uInt16 nOldIndex = pSrcData->GetIndex();
1002                 bool bInUse = ( aUsedNames.find(nOldIndex) != aUsedNames.end() );
1003 				if (bInUse)
1004 				{
1005 				    sal_uInt16 nExisting = 0;
1006 				    if ( pRangeName->SearchName( pSrcData->GetName(), nExisting ) )
1007 				    {
1008                         // the name exists already in the destination document
1009                         // -> use the existing name, but show a warning
1010                         // (when refreshing links, the existing name is used and the warning not shown)
1011 
1012 				        ScRangeData* pExistingData = (*pRangeName)[nExisting];
1013 				        sal_uInt16 nExistingIndex = pExistingData->GetIndex();
1014 
1015                         pSrcRangeNames[i] = NULL;       // don't modify the named range
1016                         aSrcRangeMap.insert(
1017                             ScRangeData::IndexMap::value_type(nOldIndex, nExistingIndex));
1018                         bRangeNameReplace = sal_True;
1019                         bNamesLost = sal_True;
1020 				    }
1021 				    else
1022 				    {
1023     					ScRangeData* pData = new ScRangeData( *pSrcData );
1024     					pData->SetDocument(this);
1025     					if ( pRangeName->FindIndex( pData->GetIndex() ) )
1026     						pData->SetIndex(0);		// need new index, done in Insert
1027     					if (!pRangeName->Insert(pData))
1028     					{
1029     					    DBG_ERROR("can't insert name");     // shouldn't happen
1030     						delete pData;
1031     					}
1032     					else
1033     					{
1034     						pData->TransferTabRef( nSrcPos, nDestPos );
1035     						pSrcRangeNames[i] = pData;
1036     						sal_uInt16 nNewIndex = pData->GetIndex();
1037                             aSrcRangeMap.insert(
1038                                 ScRangeData::IndexMap::value_type(nOldIndex, nNewIndex));
1039     						if ( !bRangeNameReplace )
1040     							bRangeNameReplace = ( nOldIndex != nNewIndex );
1041     					}
1042 				    }
1043 				}
1044 				else
1045 				{
1046 					pSrcRangeNames[i] = NULL;
1047 					//aSrcRangeMap.SetPair( i, 0, 0 );		// not needed, defaulted
1048 				}
1049 			}
1050 			if ( bRangeNameReplace )
1051 			{
1052 				// first update all inserted named formulas if they contain other
1053 				// range names and used indices changed
1054 				for (sal_uInt16 i = 0; i < nSrcRangeNames; i++)		//! DB-Bereiche Pivot-Bereiche auch
1055 				{
1056 					if ( pSrcRangeNames[i] )
1057 						pSrcRangeNames[i]->ReplaceRangeNamesInUse( aSrcRangeMap );
1058 				}
1059 				// then update the formulas, they might need the just updated range names
1060 				pTab[nDestPos]->ReplaceRangeNamesInUse( 0, 0, MAXCOL, MAXROW, aSrcRangeMap );
1061 			}
1062 			if ( pSrcRangeNames )
1063 				delete [] pSrcRangeNames;
1064 
1065 			SCsTAB nDz = ((SCsTAB)nDestPos) - (SCsTAB)nSrcPos;
1066 			pTab[nDestPos]->UpdateReference(URM_COPY, 0, 0, nDestPos,
1067 													 MAXCOL, MAXROW, nDestPos,
1068 													 0, 0, nDz, NULL);
1069             // Test for outside absolute references for info box
1070             sal_Bool bIsAbsRef = pSrcDoc->pTab[nSrcPos]->TestTabRefAbs(nSrcPos);
1071             // Readjust self-contained absolute references to this sheet
1072             pTab[nDestPos]->TestTabRefAbs(nSrcPos);
1073 			if (bIsAbsRef)
1074 			{
1075 				nRetVal += 1;
1076                     // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
1077 			}
1078             if (bNamesLost)
1079             {
1080                 nRetVal += 2;
1081                 // message: duplicate names
1082             }
1083 			pTab[nDestPos]->CompileAll();
1084 		}
1085 
1086 		SetNoListening( sal_False );
1087 		if ( !bResultsOnly )
1088 			pTab[nDestPos]->StartAllListeners();
1089         SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
1090 
1091 		if ( bResultsOnly )
1092 			pSrcDoc->SetAutoCalc( bOldAutoCalcSrc );
1093 		SetAutoCalc( bOldAutoCalc );
1094 
1095 		//	Drawing kopieren
1096 
1097 		if (bInsertNew)
1098 			TransferDrawPage( pSrcDoc, nSrcPos, nDestPos );
1099 
1100         pTab[nDestPos]->SetPendingRowHeights( pSrcDoc->pTab[nSrcPos]->IsPendingRowHeights() );
1101 	}
1102 	if (!bValid)
1103 		nRetVal = 0;
1104     sal_Bool bVbaEnabled = IsInVBAMode();
1105 
1106     if ( bVbaEnabled  )
1107     {
1108         SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL;
1109         if ( pSrcShell )
1110         {
1111             StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL;
1112             String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
1113             if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 )
1114             {
1115                 aLibName = pSrcShell->GetBasicManager()->GetName();
1116                 pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName );
1117             }
1118 
1119             String sCodeName;
1120             String sSource;
1121             uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
1122             uno::Reference< container::XNameContainer > xLib;
1123             if( xLibContainer.is() )
1124             {
1125                 uno::Any aLibAny = xLibContainer->getByName( aLibName );
1126                 aLibAny >>= xLib;
1127             }
1128 
1129             if( xLib.is() )
1130             {
1131                 String sSrcCodeName;
1132                 pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName );
1133                 rtl::OUString sRTLSource;
1134                 xLib->getByName( sSrcCodeName ) >>= sRTLSource;
1135                 sSource = sRTLSource;
1136             }
1137             VBA_InsertModule( *this, nDestPos, sCodeName, sSource );
1138         }
1139     }
1140 
1141 	return nRetVal;
1142 }
1143 
1144 //	----------------------------------------------------------------------------
1145 
1146 void ScDocument::SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError)
1147 {
1148 	if (VALIDTAB(nTab))
1149 		if (pTab[nTab])
1150 			pTab[nTab]->SetError( nCol, nRow, nError );
1151 }
1152 
1153 void ScDocument::EraseNonUsedSharedNames(sal_uInt16 nLevel)
1154 {
1155 	for (sal_uInt16 i = 0; i < pRangeName->GetCount(); i++)
1156 	{
1157 		ScRangeData* pRangeData = (*pRangeName)[i];
1158 		if (pRangeData && pRangeData->HasType(RT_SHARED))
1159 		{
1160 			String aName;
1161 			pRangeData->GetName(aName);
1162 			aName.Erase(0, 6);						// !!! vgl. Table4, FillFormula !!
1163 			sal_uInt16 nInd = (sal_uInt16) aName.ToInt32();
1164 			if (nInd <= nLevel)
1165 			{
1166 				sal_uInt16 nIndex = pRangeData->GetIndex();
1167 				sal_Bool bInUse = sal_False;
1168 				for (SCTAB j = 0; !bInUse && (j <= MAXTAB); j++)
1169 				{
1170 					if (pTab[j])
1171 						bInUse = pTab[j]->IsRangeNameInUse(0, 0, MAXCOL-1, MAXROW-1,
1172 														   nIndex);
1173 				}
1174 				if (!bInUse)
1175 					pRangeName->AtFree(i);
1176 			}
1177 		}
1178 	}
1179 }
1180 
1181 //	----------------------------------------------------------------------------
1182 
1183 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
1184 {
1185 	delete pConsolidateDlgData;
1186 
1187 	if ( pData )
1188 		pConsolidateDlgData = new ScConsolidateParam( *pData );
1189 	else
1190 		pConsolidateDlgData = NULL;
1191 }
1192 
1193 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings& rNew)
1194 {
1195 	if (pChangeViewSettings==NULL)
1196 		pChangeViewSettings = new ScChangeViewSettings;
1197 
1198 	DBG_ASSERT( pChangeViewSettings, "Oops. No ChangeViewSettings :-( by!" );
1199 
1200 	*pChangeViewSettings=rNew;
1201 }
1202 
1203 //	----------------------------------------------------------------------------
1204 
1205 ScFieldEditEngine* ScDocument::CreateFieldEditEngine()
1206 {
1207     ScFieldEditEngine* pNewEditEngine = NULL;
1208 	if (!pCacheFieldEditEngine)
1209 	{
1210         pNewEditEngine = new ScFieldEditEngine( GetEnginePool(),
1211 			GetEditPool(), sal_False );
1212 	}
1213 	else
1214 	{
1215         if ( !bImportingXML )
1216         {
1217             // #i66209# previous use might not have restored update mode,
1218             // ensure same state as for a new EditEngine (UpdateMode = sal_True)
1219             if ( !pCacheFieldEditEngine->GetUpdateMode() )
1220                 pCacheFieldEditEngine->SetUpdateMode(sal_True);
1221         }
1222 
1223         pNewEditEngine = pCacheFieldEditEngine;
1224 		pCacheFieldEditEngine = NULL;
1225 	}
1226     return pNewEditEngine;
1227 }
1228 
1229 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine*& rpEditEngine)
1230 {
1231 	if (!pCacheFieldEditEngine && rpEditEngine)
1232 	{
1233 		pCacheFieldEditEngine = rpEditEngine;
1234 		pCacheFieldEditEngine->Clear();
1235 	}
1236 	else
1237 		delete rpEditEngine;
1238 	rpEditEngine = NULL;
1239 }
1240 
1241 //	----------------------------------------------------------------------------
1242 
1243 // static
1244 ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
1245 {
1246     return new ScRecursionHelper;
1247 }
1248 
1249 //	----------------------------------------------------------------------------
1250 
1251 ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
1252 {
1253     ScLookupCache* pCache = 0;
1254     if (!pLookupCacheMapImpl)
1255         pLookupCacheMapImpl = new ScLookupCacheMapImpl;
1256     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find( rRange));
1257     if (it == pLookupCacheMapImpl->aCacheMap.end())
1258     {
1259         pCache = new ScLookupCache( this, rRange);
1260         AddLookupCache( *pCache);
1261     }
1262     else
1263         pCache = (*it).second;
1264     return *pCache;
1265 }
1266 
1267 void ScDocument::AddLookupCache( ScLookupCache & rCache )
1268 {
1269     if (!pLookupCacheMapImpl->aCacheMap.insert( ::std::pair< const ScRange,
1270                 ScLookupCache*>( rCache.getRange(), &rCache)).second)
1271     {
1272         DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
1273     }
1274     else
1275         StartListeningArea( rCache.getRange(), &rCache);
1276 }
1277 
1278 void ScDocument::RemoveLookupCache( ScLookupCache & rCache )
1279 {
1280     ScLookupCacheMap::iterator it( pLookupCacheMapImpl->aCacheMap.find(
1281                 rCache.getRange()));
1282     if (it == pLookupCacheMapImpl->aCacheMap.end())
1283     {
1284         DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
1285     }
1286     else
1287     {
1288         ScLookupCache* pCache = (*it).second;
1289         pLookupCacheMapImpl->aCacheMap.erase( it);
1290         EndListeningArea( pCache->getRange(), &rCache);
1291     }
1292 }
1293 
1294 void ScDocument::ClearLookupCaches()
1295 {
1296     if( pLookupCacheMapImpl )
1297         pLookupCacheMapImpl->clear();
1298 }
1299