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