xref: /aoo42x/main/sc/source/core/data/documen2.cxx (revision 577c0052)
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 "tabprotection.hxx"
91 #include "formulaparserpool.hxx"
92 #include "clipparam.hxx"
93 
94 using namespace com::sun::star;
95 
96 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
97 // dtor plus helpers are convenient.
98 struct ScLookupCacheMapImpl
99 {
100     ScLookupCacheMap aCacheMap;
101     ~ScLookupCacheMapImpl()
102     {
103         freeCaches();
104     }
105     void clear()
106     {
107         freeCaches();
108         // Zap map.
109         ScLookupCacheMap aTmp;
110         aCacheMap.swap( aTmp);
111     }
112 private:
113     void freeCaches()
114     {
115         for (ScLookupCacheMap::iterator it( aCacheMap.begin()); it != aCacheMap.end(); ++it)
116             delete (*it).second;
117     }
118 };
119 
120 // STATIC DATA -----------------------------------------------------------
121 
122 ScDocument::ScDocument( ScDocumentMode	eMode,
123 						SfxObjectShell* pDocShell ) :
124 		xServiceManager( ::comphelper::getProcessServiceFactory() ),
125 		mpUndoManager( NULL ),
126 		pEditEngine( NULL ),
127 		pNoteEngine( NULL ),
128 		pNoteItemPool( NULL ),
129 		pShell( pDocShell ),
130 		pPrinter( NULL ),
131 		pVirtualDevice_100th_mm( NULL ),
132 		pDrawLayer( NULL ),
133 		pColorTable( NULL ),
134 		pCondFormList( NULL ),
135 		pValidationList( NULL ),
136 		pFormatExchangeList( NULL ),
137 		pDPCollection( NULL ),
138 		pLinkManager( NULL ),
139 		pFormulaTree( NULL ),
140 		pEOFormulaTree( NULL ),
141 		pFormulaTrack( NULL ),
142 		pEOFormulaTrack( NULL ),
143 		pOtherObjects( NULL ),
144 		pClipData( NULL ),
145 		pDetOpList(NULL),
146 		pChangeTrack( NULL ),
147 		pUnoBroadcaster( NULL ),
148 		pUnoListenerCalls( NULL ),
149         pUnoRefUndoList( NULL ),
150 		pChangeViewSettings( NULL ),
151 		pScriptTypeData( NULL ),
152         pCacheFieldEditEngine( NULL ),
153         pDocProtection( NULL ),
154         mpClipParam( NULL),
155         pExternalRefMgr( NULL ),
156 		pViewOptions( NULL ),
157 		pDocOptions( NULL ),
158 		pExtDocOptions( NULL ),
159 		pConsolidateDlgData( NULL ),
160         pRecursionHelper( NULL ),
161         pAutoNameCache( NULL ),
162         pLookupCacheMapImpl( NULL ),
163         nUnoObjectId( 0 ),
164         nRangeOverflowType( 0 ),
165 		aCurTextWidthCalcPos(MAXCOL,0,0),
166 		nFormulaCodeInTree(0),
167         nXMLImportedFormulaCount( 0 ),
168 		nInterpretLevel(0),
169 		nMacroInterpretLevel(0),
170 		nInterpreterTableOpLevel(0),
171 		nMaxTableNumber( 0 ),
172 	    nSrcVer( SC_CURRENT_VERSION ),
173 	    nSrcMaxRow( MAXROW ),
174 		nFormulaTrackCount(0),
175 		nHardRecalcState(0),
176 		nVisibleTab( 0 ),
177 		eLinkMode(LM_UNKNOWN),
178 		bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
179 		bAutoCalcShellDisabled( sal_False ),
180 		bForcedFormulaPending( sal_False ),
181 		bCalculatingFormulaTree( sal_False ),
182 		bIsClip( eMode == SCDOCMODE_CLIP ),
183 		bIsUndo( eMode == SCDOCMODE_UNDO ),
184 		bIsVisible( sal_False ),
185 		bIsEmbedded( sal_False ),
186 //		bNoSetDirty( sal_True ),
187 		bNoSetDirty( sal_False ),
188 		bInsertingFromOtherDoc( sal_False ),
189         bLoadingMedium( false ),
190 		bImportingXML( false ),
191         mbImportingMSXML( false ),
192         bXMLFromWrapper( sal_False ),
193 		bCalcingAfterLoad( sal_False ),
194 		bNoListening( sal_False ),
195 		bIdleDisabled( sal_False ),
196 		bInLinkUpdate( sal_False ),
197 		bChartListenerCollectionNeedsUpdate( sal_False ),
198 		bHasForcedFormulas( sal_False ),
199 		bInDtorClear( sal_False ),
200 		bExpandRefs( sal_False ),
201 		bDetectiveDirty( sal_False ),
202 		nMacroCallMode( SC_MACROCALL_ALLOWED ),
203 		bHasMacroFunc( sal_False ),
204 		nVisSpellState( 0 ),
205         nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
206         nAsianKerning(SC_ASIANKERNING_INVALID),
207         bSetDrawDefaults( sal_False ),
208         bPastingDrawFromOtherDoc( sal_False ),
209         nInDdeLinkUpdate( 0 ),
210         bInUnoBroadcast( sal_False ),
211         bInUnoListenerCall( sal_False ),
212         eGrammar( formula::FormulaGrammar::GRAM_NATIVE ),
213         bStyleSheetUsageInvalid( sal_True ),
214         mbUndoEnabled( true ),
215         mbAdjustHeightEnabled( true ),
216         mbExecuteLinkEnabled( true ),
217         mbChangeReadOnlyEnabled( false ),
218         mbStreamValidLocked( false ),
219         mnNamedRangesLockCount( 0 )
220 {
221     SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
222 
223 	eSrcSet = gsl_getSystemTextEncoding();
224 
225 	if ( eMode == SCDOCMODE_DOCUMENT )
226 	{
227 		if ( pDocShell )
228 			pLinkManager = new sfx2::LinkManager( pDocShell );
229 
230 		xPoolHelper = new ScPoolHelper( this );
231 
232 		pTab[0]  = NULL;
233 		pBASM = new ScBroadcastAreaSlotMachine( this );
234 		pChartListenerCollection = new ScChartListenerCollection( this );
235 		pRefreshTimerControl = new ScRefreshTimerControl;
236 	}
237 	else
238 	{
239 		pTab[0]		= NULL;
240 		pBASM		= NULL;
241 		pChartListenerCollection = NULL;
242 		pRefreshTimerControl = NULL;
243 	}
244 
245 	for (SCTAB i=1; i<=MAXTAB; i++)
246 		pTab[i] = NULL;
247 
248 	pRangeName = new ScRangeName( 4, 4, sal_False, this );
249 	pDBCollection = new ScDBCollection( 4, 4, sal_False, this );
250 	pSelectionAttr = NULL;
251 	pChartCollection = new ScChartCollection;
252     apTemporaryChartLock = std::auto_ptr< ScTemporaryChartLock >( new ScTemporaryChartLock(this) );
253 	xColNameRanges = new ScRangePairList;
254 	xRowNameRanges = new ScRangePairList;
255 	ImplCreateOptions();
256 	// languages for a visible document are set by docshell later (from options)
257 	SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
258 
259 	aTrackTimer.SetTimeoutHdl( LINK( this, ScDocument, TrackTimeHdl ) );
260 	aTrackTimer.SetTimeout( 100 );
261 }
262 
263 sfx2::LinkManager*	ScDocument::GetLinkManager()  const
264 {
265     if ( bAutoCalc && !pLinkManager && pShell)
266 	{
267 		pLinkManager = new sfx2::LinkManager( pShell );
268     }
269     return pLinkManager;
270 }
271 
272 
273 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
274 {
275     DBG_ASSERT(
276         eGram == formula::FormulaGrammar::GRAM_ODFF ||
277             eGram == formula::FormulaGrammar::GRAM_PODF,
278             "ScDocument::SetStorageGrammar: wrong storage grammar");
279 
280     eStorageGrammar = eGram;
281 
282     // FIXME: the XML import shouldn't strip brackets, the compiler should
283     // digest them instead, which could also speedup reference recognition
284     // during import.
285 
286     eXmlImportGrammar = formula::FormulaGrammar::mergeToGrammar( eGram,
287             formula::FormulaGrammar::CONV_OOO);
288 }
289 
290 
291 void ScDocument::SetDocVisible( sal_Bool bSet )
292 {
293 	//	called from view ctor - only for a visible document,
294 	//	each new sheet's RTL flag is initialized from the locale
295 	bIsVisible = bSet;
296 }
297 
298 
299 sal_uInt32 ScDocument::GetDocumentID() const
300 {
301     const ScDocument* pThis = this;
302     sal_uInt32 nCrc = rtl_crc32( 0, &pThis, sizeof(ScDocument*) );
303     // the this pointer only might not be sufficient
304     nCrc = rtl_crc32( nCrc, &pShell, sizeof(SfxObjectShell*) );
305     return nCrc;
306 }
307 
308 
309 void ScDocument::StartChangeTracking()
310 {
311 	if (!pChangeTrack)
312 		pChangeTrack = new ScChangeTrack( this );
313 }
314 
315 void ScDocument::EndChangeTracking()
316 {
317 	delete pChangeTrack;
318 	pChangeTrack = NULL;
319 }
320 
321 void ScDocument::SetChangeTrack( ScChangeTrack* pTrack )
322 {
323 	DBG_ASSERT( pTrack->GetDocument() == this, "SetChangeTrack: different documents" );
324 	if ( !pTrack || pTrack == pChangeTrack || pTrack->GetDocument() != this )
325 		return ;
326 	EndChangeTracking();
327 	pChangeTrack = pTrack;
328 }
329 
330 
331 IMPL_LINK( ScDocument, TrackTimeHdl, Timer*, EMPTYARG )
332 {
333 	if ( ScDdeLink::IsInUpdate() )		// nicht verschachteln
334 	{
335 		aTrackTimer.Start();			// spaeter nochmal versuchen
336 	}
337 	else if (pShell)					// ausfuehren
338 	{
339 		TrackFormulas();
340 		pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
341 		ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
342 
343 			//	modified...
344 
345 		if (!pShell->IsModified())
346 		{
347 			pShell->SetModified( sal_True );
348 			SfxBindings* pBindings = GetViewBindings();
349 			if (pBindings)
350 			{
351 				pBindings->Invalidate( SID_SAVEDOC );
352 				pBindings->Invalidate( SID_DOC_MODIFIED );
353 			}
354 		}
355 	}
356 
357 	return 0;
358 }
359 
360 void ScDocument::StartTrackTimer()
361 {
362 	if (!aTrackTimer.IsActive())		// nicht ewig aufschieben
363 		aTrackTimer.Start();
364 }
365 
366 ScDocument::~ScDocument()
367 {
368 	DBG_ASSERT( !bInLinkUpdate, "bInLinkUpdate in dtor" );
369 
370 	bInDtorClear = sal_True;
371 
372 	// first of all disable all refresh timers by deleting the control
373 	if ( pRefreshTimerControl )
374 	{	// To be sure there isn't anything running do it with a protector,
375 		// this ensures also that nothing needs the control anymore.
376 		ScRefreshTimerProtector aProt( GetRefreshTimerControlAddress() );
377 		delete pRefreshTimerControl, pRefreshTimerControl = NULL;
378 	}
379 
380 	// Links aufrauemen
381 
382 	if ( GetLinkManager() )
383 	{
384 		// BaseLinks freigeben
385 		for ( sal_uInt16 n = pLinkManager->GetServers().Count(); n; )
386 			pLinkManager->GetServers()[ --n ]->Closed();
387 
388 		if ( pLinkManager->GetLinks().Count() )
389 			pLinkManager->Remove( 0, pLinkManager->GetLinks().Count() );
390 	}
391 
392     mxFormulaParserPool.reset();
393     // Destroy the external ref mgr instance here because it has a timer
394     // which needs to be stopped before the app closes.
395     pExternalRefMgr.reset();
396 
397 	ScAddInAsync::RemoveDocument( this );
398 	ScAddInListener::RemoveDocument( this );
399     DELETEZ( pChartListenerCollection);   // vor pBASM wg. evtl. Listener!
400     DELETEZ( pLookupCacheMapImpl);  // before pBASM because of listeners
401 	// BroadcastAreas vor allen Zellen zerstoeren um unnoetige
402 	// Einzel-EndListenings der Formelzellen zu vermeiden
403 	delete pBASM;		// BroadcastAreaSlotMachine
404 	pBASM = NULL;
405 
406 	if (pUnoBroadcaster)
407 	{
408 		delete pUnoBroadcaster;		// broadcasted nochmal SFX_HINT_DYING
409 		pUnoBroadcaster = NULL;
410 	}
411 
412     delete pUnoRefUndoList;
413 	delete pUnoListenerCalls;
414 
415     Clear( sal_True );              // sal_True = from destructor (needed for SdrModel::ClearModel)
416 
417 	if (pCondFormList)
418 	{
419 		pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
420 		DELETEZ(pCondFormList);
421 	}
422 	if (pValidationList)
423 	{
424 		pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
425 		DELETEZ(pValidationList);
426 	}
427 	delete pRangeName;
428 	delete pDBCollection;
429 	delete pSelectionAttr;
430     apTemporaryChartLock.reset();
431 	delete pChartCollection;
432 	DeleteDrawLayer();
433 	delete pFormatExchangeList;
434 	delete pPrinter;
435 	ImplDeleteOptions();
436 	delete pConsolidateDlgData;
437 	delete pLinkManager;
438 	delete pClipData;
439 	delete pDetOpList;					// loescht auch die Eintraege
440 	delete pChangeTrack;
441 	delete pEditEngine;
442 	delete pNoteEngine;
443 	SfxItemPool::Free(pNoteItemPool);
444 	delete pChangeViewSettings;			// und weg damit
445 	delete pVirtualDevice_100th_mm;
446 
447     if (pDPCollection)
448     {
449         pDPCollection->FreeAll();
450         RemoveUnusedDPObjectCaches();
451         delete pDPCollection;
452     }
453 
454 	// delete the EditEngine before destroying the xPoolHelper
455 	delete pCacheFieldEditEngine;
456 
457 	if ( xPoolHelper.isValid() && !bIsClip )
458 		xPoolHelper->SourceDocumentGone();
459 	xPoolHelper.unbind();
460 
461 	DeleteColorTable();
462 	delete pScriptTypeData;
463 	delete pOtherObjects;
464     delete pRecursionHelper;
465 
466     DBG_ASSERT( !pAutoNameCache, "AutoNameCache still set in dtor" );
467 }
468 
469 void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
470 {
471 	DBG_ASSERT(bIsClip, "InitClipPtrs und nicht bIsClip");
472 
473 	if (pCondFormList)
474 	{
475 		pCondFormList->DeleteAndDestroy( 0, pCondFormList->Count() );
476 		DELETEZ(pCondFormList);
477 	}
478 	if (pValidationList)
479 	{
480 		pValidationList->DeleteAndDestroy( 0, pValidationList->Count() );
481 		DELETEZ(pValidationList);
482 	}
483 
484 	Clear();
485 
486 	xPoolHelper = pSourceDoc->xPoolHelper;
487 
488 	//	bedingte Formate / Gueltigkeiten
489 	//!	Vorlagen kopieren?
490 	const ScConditionalFormatList* pSourceCond = pSourceDoc->pCondFormList;
491 	if ( pSourceCond )
492 		pCondFormList = new ScConditionalFormatList(this, *pSourceCond);
493 	const ScValidationDataList* pSourceValid = pSourceDoc->pValidationList;
494 	if ( pSourceValid )
495 		pValidationList = new ScValidationDataList(this, *pSourceValid);
496 
497 						// Links in Stream speichern
498 	delete pClipData;
499 	if (pSourceDoc->HasDdeLinks())
500 	{
501 		pClipData = new SvMemoryStream;
502 		pSourceDoc->SaveDdeLinks(*pClipData);
503 	}
504 	else
505 		pClipData = NULL;
506 
507     // Options pointers exist (ImplCreateOptions) for any document.
508     // Must be copied for correct results in OLE objects (#i42666#).
509     SetDocOptions( pSourceDoc->GetDocOptions() );
510     SetViewOptions( pSourceDoc->GetViewOptions() );
511 }
512 
513 SvNumberFormatter* ScDocument::GetFormatTable() const
514 {
515 	return xPoolHelper->GetFormTable();
516 }
517 
518 SfxItemPool* ScDocument::GetEditPool() const
519 {
520 	return xPoolHelper->GetEditPool();
521 }
522 
523 SfxItemPool* ScDocument::GetEnginePool() const
524 {
525 	return xPoolHelper->GetEnginePool();
526 }
527 
528 ScFieldEditEngine& ScDocument::GetEditEngine()
529 {
530 	if ( !pEditEngine )
531 	{
532 		pEditEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
533 		pEditEngine->SetUpdateMode( sal_False );
534 		pEditEngine->EnableUndo( sal_False );
535 		pEditEngine->SetRefMapMode( MAP_100TH_MM );
536         ApplyAsianEditSettings( *pEditEngine );
537 	}
538 	return *pEditEngine;
539 }
540 
541 ScNoteEditEngine& ScDocument::GetNoteEngine()
542 {
543 	if ( !pNoteEngine )
544 	{
545 		pNoteEngine = new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
546 		pNoteEngine->SetUpdateMode( sal_False );
547 		pNoteEngine->EnableUndo( sal_False );
548 		pNoteEngine->SetRefMapMode( MAP_100TH_MM );
549         ApplyAsianEditSettings( *pNoteEngine );
550         const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet();
551         SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() );
552         ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet );
553         pNoteEngine->SetDefaults( pEEItemSet );      // edit engine takes ownership
554 	}
555 	return *pNoteEngine;
556 }
557 
558 void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks )
559 {
560 	if (bIsClip)
561 	{
562 		InitClipPtrs(pSourceDoc);
563 
564 		for (SCTAB i = 0; i <= MAXTAB; i++)
565 			if (pSourceDoc->pTab[i])
566 				if (!pMarks || pMarks->GetTableSelect(i))
567 				{
568 					String aString;
569 					pSourceDoc->pTab[i]->GetName(aString);
570 					pTab[i] = new ScTable(this, i, aString);
571 					pTab[i]->SetLayoutRTL( pSourceDoc->pTab[i]->IsLayoutRTL() );
572 					nMaxTableNumber = i+1;
573 				}
574 	}
575 	else
576 	{
577 		DBG_ERROR("ResetClip");
578 	}
579 }
580 
581 void ScDocument::ResetClip( ScDocument* pSourceDoc, SCTAB nTab )
582 {
583 	if (bIsClip)
584 	{
585 		InitClipPtrs(pSourceDoc);
586 
587 		pTab[nTab] = new ScTable(this, nTab,
588 							String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
589 		if (pSourceDoc->pTab[nTab])
590 			pTab[nTab]->SetLayoutRTL( pSourceDoc->pTab[nTab]->IsLayoutRTL() );
591 		nMaxTableNumber = nTab+1;
592 	}
593 	else
594 	{
595 		DBG_ERROR("ResetClip");
596 	}
597 }
598 
599 void ScDocument::DeleteNumberFormat( const sal_uInt32* /* pDelKeys */, sal_uInt32 /* nCount */ )
600 {
601 /*
602 	for (sal_uLong i = 0; i < nCount; i++)
603 		xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
604 */
605 }
606 
607 void ScDocument::PutCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
608 						  ScBaseCell* pCell, sal_uLong nFormatIndex, sal_Bool bForceTab )
609 {
610 	if (VALIDTAB(nTab))
611 	{
612 		if ( bForceTab && !pTab[nTab] )
613 		{
614 			sal_Bool bExtras = !bIsUndo;		// Spaltenbreiten, Zeilenhoehen, Flags
615 
616 			pTab[nTab] = new ScTable(this, nTab,
617 								String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
618 								bExtras, bExtras);
619 		}
620 
621 		if (pTab[nTab])
622 			pTab[nTab]->PutCell( nCol, nRow, nFormatIndex, pCell );
623 	}
624 }
625 
626 //UNUSED2009-05 void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell,
627 //UNUSED2009-05                             sal_uLong nFormatIndex, sal_Bool bForceTab )
628 //UNUSED2009-05 {
629 //UNUSED2009-05     SCTAB nTab = rPos.Tab();
630 //UNUSED2009-05     if ( bForceTab && !pTab[nTab] )
631 //UNUSED2009-05     {
632 //UNUSED2009-05         sal_Bool bExtras = !bIsUndo;        // Spaltenbreiten, Zeilenhoehen, Flags
633 //UNUSED2009-05
634 //UNUSED2009-05         pTab[nTab] = new ScTable(this, nTab,
635 //UNUSED2009-05                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
636 //UNUSED2009-05                             bExtras, bExtras);
637 //UNUSED2009-05     }
638 //UNUSED2009-05
639 //UNUSED2009-05     if (pTab[nTab])
640 //UNUSED2009-05         pTab[nTab]->PutCell( rPos, nFormatIndex, pCell );
641 //UNUSED2009-05 }
642 
643 sal_Bool ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
644 								sal_Bool bNotes ) const
645 {
646 	if (ValidTab(nTab) && pTab[nTab])
647 	{
648 		sal_Bool bAny = pTab[nTab]->GetPrintArea( rEndCol, rEndRow, bNotes );
649 		if (pDrawLayer)
650 		{
651 			ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
652 			if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
653 			{
654 				if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
655 				if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
656 				bAny = sal_True;
657 			}
658 		}
659 		return bAny;
660 	}
661 
662 	rEndCol = 0;
663 	rEndRow = 0;
664 	return sal_False;
665 }
666 
667 sal_Bool ScDocument::GetPrintAreaHor( SCTAB nTab, SCROW nStartRow, SCROW nEndRow,
668 										SCCOL& rEndCol, sal_Bool bNotes ) const
669 {
670 	if (ValidTab(nTab) && pTab[nTab])
671 	{
672 		sal_Bool bAny = pTab[nTab]->GetPrintAreaHor( nStartRow, nEndRow, rEndCol, bNotes );
673 		if (pDrawLayer)
674 		{
675 			ScRange aDrawRange(0,nStartRow,nTab, MAXCOL,nEndRow,nTab);
676 			if (DrawGetPrintArea( aDrawRange, sal_True, sal_False ))
677 			{
678 				if (aDrawRange.aEnd.Col()>rEndCol) rEndCol=aDrawRange.aEnd.Col();
679 				bAny = sal_True;
680 			}
681 		}
682 		return bAny;
683 	}
684 
685 	rEndCol = 0;
686 	return sal_False;
687 }
688 
689 sal_Bool ScDocument::GetPrintAreaVer( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol,
690 										SCROW& rEndRow, sal_Bool bNotes ) const
691 {
692 	if (ValidTab(nTab) && pTab[nTab])
693 	{
694 		sal_Bool bAny = pTab[nTab]->GetPrintAreaVer( nStartCol, nEndCol, rEndRow, bNotes );
695 		if (pDrawLayer)
696 		{
697 			ScRange aDrawRange(nStartCol,0,nTab, nEndCol,MAXROW,nTab);
698 			if (DrawGetPrintArea( aDrawRange, sal_False, sal_True ))
699 			{
700 				if (aDrawRange.aEnd.Row()>rEndRow) rEndRow=aDrawRange.aEnd.Row();
701 				bAny = sal_True;
702 			}
703 		}
704 		return bAny;
705 	}
706 
707 	rEndRow = 0;
708 	return sal_False;
709 }
710 
711 sal_Bool ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const
712 {
713 	if (ValidTab(nTab) && pTab[nTab])
714 	{
715 		sal_Bool bAny = pTab[nTab]->GetDataStart( rStartCol, rStartRow );
716 		if (pDrawLayer)
717 		{
718 			ScRange aDrawRange(0,0,nTab, MAXCOL,MAXROW,nTab);
719 			if (DrawGetPrintArea( aDrawRange, sal_True, sal_True ))
720 			{
721 				if (aDrawRange.aStart.Col()<rStartCol) rStartCol=aDrawRange.aStart.Col();
722 				if (aDrawRange.aStart.Row()<rStartRow) rStartRow=aDrawRange.aStart.Row();
723 				bAny = sal_True;
724 			}
725 		}
726 		return bAny;
727 	}
728 
729 	rStartCol = 0;
730 	rStartRow = 0;
731 	return sal_False;
732 }
733 
734 sal_Bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
735 {
736 	if (nOldPos == nNewPos) return sal_False;
737 	sal_Bool bValid = sal_False;
738 	if (VALIDTAB(nOldPos))
739 	{
740 		if (pTab[nOldPos])
741 		{
742 			SCTAB nTabCount = GetTableCount();
743 			if (nTabCount > 1)
744 			{
745 				sal_Bool bOldAutoCalc = GetAutoCalc();
746 				SetAutoCalc( sal_False );	// Mehrfachberechnungen vermeiden
747 				SetNoListening( sal_True );
748 				ScProgress* pProgress = new ScProgress( GetDocumentShell(),
749 					ScGlobal::GetRscString(STR_UNDO_MOVE_TAB), GetCodeCount() );
750 				if (nNewPos == SC_TAB_APPEND)
751 					nNewPos = nTabCount-1;
752 
753 				//	Referenz-Updaterei
754 				//!	mit UpdateReference zusammenfassen!
755 
756 				SCsTAB nDz = ((SCsTAB)nNewPos) - (SCsTAB)nOldPos;
757 				ScRange aSourceRange( 0,0,nOldPos, MAXCOL,MAXROW,nOldPos );
758 				pRangeName->UpdateTabRef(nOldPos, 3, nNewPos);
759 				pDBCollection->UpdateMoveTab( nOldPos, nNewPos );
760 				xColNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
761 				xRowNameRanges->UpdateReference( URM_REORDER, this, aSourceRange, 0,0,nDz );
762 				if (pDPCollection)
763 					pDPCollection->UpdateReference( URM_REORDER, aSourceRange, 0,0,nDz );
764 				if (pDetOpList)
765 					pDetOpList->UpdateReference( this, URM_REORDER, aSourceRange, 0,0,nDz );
766 				UpdateChartRef( URM_REORDER,
767 									0,0,nOldPos, MAXCOL,MAXROW,nOldPos, 0,0,nDz );
768 				UpdateRefAreaLinks( URM_REORDER, aSourceRange, 0,0,nDz );
769 				if ( pCondFormList )
770 					pCondFormList->UpdateMoveTab( nOldPos, nNewPos );
771 				if ( pValidationList )
772 					pValidationList->UpdateMoveTab( nOldPos, nNewPos );
773 				if ( pUnoBroadcaster )
774 					pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_REORDER,
775 									aSourceRange, 0,0,nDz ) );
776 
777 				ScTable* pSaveTab = pTab[nOldPos];
778 				SCTAB i;
779 				for (i = nOldPos + 1; i < nTabCount; i++)
780 					pTab[i - 1] = pTab[i];
781 				pTab[i-1] = NULL;
782 				for (i = nTabCount - 1; i > nNewPos; i--)
783 					pTab[i] = pTab[i - 1];
784 				pTab[nNewPos] = pSaveTab;
785 				for (i = 0; i <= MAXTAB; i++)
786 					if (pTab[i])
787 						pTab[i]->UpdateMoveTab( nOldPos, nNewPos, i, *pProgress );
788 				delete pProgress;	// freimachen fuer evtl. andere
789 				for (i = 0; i <= MAXTAB; i++)
790 					if (pTab[i])
791 						pTab[i]->UpdateCompile();
792 				SetNoListening( sal_False );
793 				for (i = 0; i <= MAXTAB; i++)
794 					if (pTab[i])
795 						pTab[i]->StartAllListeners();
796 				// #81844# sheet names of references may not be valid until sheet is moved
797 				pChartListenerCollection->UpdateScheduledSeriesRanges();
798 				SetDirty();
799 				SetAutoCalc( bOldAutoCalc );
800 
801 				if (pDrawLayer)
802 					DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
803 
804 				bValid = sal_True;
805 			}
806 		}
807 	}
808 	return bValid;
809 }
810 
811 sal_Bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked )
812 {
813 	if (SC_TAB_APPEND == nNewPos ) nNewPos = nMaxTableNumber;
814 	String aName;
815 	GetName(nOldPos, aName);
816 
817 	//	vorneweg testen, ob der Prefix als gueltig erkannt wird
818 	//	wenn nicht, nur doppelte vermeiden
819 	sal_Bool bPrefix = ValidTabName( aName );
820 	DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
821 	SCTAB nDummy;
822 
823 	CreateValidTabName(aName);
824 
825 	sal_Bool bValid;
826 	if (bPrefix)
827 		bValid = ( ValidNewTabName(aName) && (nMaxTableNumber <= MAXTAB) );
828 	else
829 		bValid = ( !GetTable( aName, nDummy ) && (nMaxTableNumber <= MAXTAB) );
830 
831 	sal_Bool bOldAutoCalc = GetAutoCalc();
832 	SetAutoCalc( sal_False );	// Mehrfachberechnungen vermeiden
833 	if (bValid)
834 	{
835 		if (nNewPos == nMaxTableNumber)
836 		{
837 			pTab[nMaxTableNumber] = new ScTable(this, nMaxTableNumber, aName);
838 			pRangeName->UpdateTabRef(nNewPos, 4, nOldPos);//. 4 - copy table
839 			++nMaxTableNumber;
840 		}
841 		else
842 		{
843 			if (VALIDTAB(nNewPos) && (nNewPos < nMaxTableNumber))
844 			{
845 				SetNoListening( sal_True );
846 
847 				ScRange aRange( 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB );
848 				xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
849 				xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,1 );
850 				pRangeName->UpdateTabRef(nNewPos, 4, nOldPos);//  4 - copy table
851 				pDBCollection->UpdateReference(
852 									URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
853 				if (pDPCollection)
854 					pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
855 				if (pDetOpList)
856 					pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,1 );
857 				UpdateChartRef( URM_INSDEL, 0,0,nNewPos, MAXCOL,MAXROW,MAXTAB, 0,0,1 );
858 				UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,1 );
859 				if ( pUnoBroadcaster )
860 					pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,1 ) );
861 
862 				SCTAB i;
863 				for (i = 0; i <= MAXTAB; i++)
864 					if (pTab[i] && i != nOldPos)
865 						pTab[i]->UpdateInsertTab(nNewPos);
866 				for (i = nMaxTableNumber; i > nNewPos; i--)
867 					pTab[i] = pTab[i - 1];
868 				if (nNewPos <= nOldPos)
869 					nOldPos++;
870 				pTab[nNewPos] = new ScTable(this, nNewPos, aName);
871 				++nMaxTableNumber;
872 				bValid = sal_True;
873 				for (i = 0; i <= MAXTAB; i++)
874 					if (pTab[i] && i != nOldPos && i != nNewPos)
875 						pTab[i]->UpdateCompile();
876 				SetNoListening( sal_False );
877 				for (i = 0; i <= MAXTAB; i++)
878 					if (pTab[i] && i != nOldPos && i != nNewPos)
879 						pTab[i]->StartAllListeners();
880 
881 				//	update conditional formats after table is inserted
882 				if ( pCondFormList )
883 					pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
884 				if ( pValidationList )
885 					pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,1 );
886 				// #81844# sheet names of references may not be valid until sheet is copied
887 				pChartListenerCollection->UpdateScheduledSeriesRanges();
888 			}
889 			else
890 				bValid = sal_False;
891 		}
892 	}
893 	if (bValid)
894 	{
895 		SetNoListening( sal_True );		// noch nicht bei CopyToTable/Insert
896 		pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
897 										pTab[nNewPos], pOnlyMarked );
898         pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
899 
900 		SCsTAB nDz;
901 /*		if (nNewPos < nOldPos)
902 			nDz = ((short)nNewPos) - (short)nOldPos + 1;
903 		else
904 */			nDz = ((short)nNewPos) - (short)nOldPos;
905 		pTab[nNewPos]->UpdateReference(URM_COPY, 0, 0, nNewPos , MAXCOL, MAXROW,
906 										nNewPos, 0, 0, nDz, NULL);
907 
908 		pTab[nNewPos]->UpdateInsertTabAbs(nNewPos); // alle abs. um eins hoch!!
909 		pTab[nOldPos]->UpdateInsertTab(nNewPos);
910 
911 		pTab[nOldPos]->UpdateCompile();
912 		pTab[nNewPos]->UpdateCompile( sal_True );	// #67996# maybe already compiled in Clone, but used names need recompilation
913 		SetNoListening( sal_False );
914 		pTab[nOldPos]->StartAllListeners();
915 		pTab[nNewPos]->StartAllListeners();
916 		SetDirty();
917 		SetAutoCalc( bOldAutoCalc );
918 
919 		if (pDrawLayer)
920 			DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
921 
922 		pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
923         pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
924 	}
925 	else
926 		SetAutoCalc( bOldAutoCalc );
927 	return bValid;
928 }
929 
930 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource );
931 
932 sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
933 								SCTAB nDestPos, sal_Bool bInsertNew,
934 								sal_Bool bResultsOnly )
935 {
936 	sal_uLong nRetVal = 1;						// 0 => Fehler 1 = ok
937 											// 2 => RefBox, 3 => NameBox
938 											// 4 => beides
939 	sal_Bool bValid = sal_True;
940 	if (bInsertNew)				// neu einfuegen
941 	{
942 		String aName;
943 		pSrcDoc->GetName(nSrcPos, aName);
944 		CreateValidTabName(aName);
945 		bValid = InsertTab(nDestPos, aName);
946 	}
947 	else						// bestehende Tabelle ersetzen
948 	{
949 		if (VALIDTAB(nDestPos) && pTab[nDestPos])
950 		{
951 			pTab[nDestPos]->DeleteArea( 0,0, MAXCOL,MAXROW, IDF_ALL );
952 		}
953 		else
954 			bValid = sal_False;
955 	}
956 
957 	if (bValid)
958 	{
959         sal_Bool bOldAutoCalcSrc = sal_False;
960 		sal_Bool bOldAutoCalc = GetAutoCalc();
961 		SetAutoCalc( sal_False );	// Mehrfachberechnungen vermeiden
962 		SetNoListening( sal_True );
963 		if ( bResultsOnly )
964 		{
965 			bOldAutoCalcSrc = pSrcDoc->GetAutoCalc();
966 			pSrcDoc->SetAutoCalc( sal_True );	// falls was berechnet werden muss
967 		}
968 
969 		{
970             NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
971 
972             nDestPos = Min(nDestPos, (SCTAB)(GetTableCount() - 1));
973             {   // scope for bulk broadcast
974                 ScBulkBroadcast aBulkBroadcast( pBASM);
975                 pSrcDoc->pTab[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
976                         ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
977                         sal_False, pTab[nDestPos] );
978             }
979         }
980 
981         pTab[nDestPos]->SetTabNo(nDestPos);
982         pTab[nDestPos]->SetTabBgColor(pSrcDoc->pTab[nSrcPos]->GetTabBgColor());
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