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