xref: /trunk/main/sc/source/core/data/documen3.cxx (revision 5b2f55dd)
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 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
30 #include "scitems.hxx"
31 #include <editeng/langitem.hxx>
32 #include <svl/srchitem.hxx>
33 #include <sfx2/linkmgr.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <svl/zforlist.hxx>
37 #include <svl/PasswordHelper.hxx>
38 #include <vcl/svapp.hxx>
39 #include "document.hxx"
40 #include "attrib.hxx"
41 #include "cell.hxx"
42 #include "table.hxx"
43 #include "rangenam.hxx"
44 #include "dbcolect.hxx"
45 #include "pivot.hxx"
46 #include "docpool.hxx"
47 #include "poolhelp.hxx"
48 #include "autoform.hxx"
49 #include "rangelst.hxx"
50 #include "chartarr.hxx"
51 #include "chartlock.hxx"
52 #include "refupdat.hxx"
53 #include "docoptio.hxx"
54 #include "viewopti.hxx"
55 #include "scextopt.hxx"
56 #include "brdcst.hxx"
57 #include "bcaslot.hxx"
58 #include "tablink.hxx"
59 #include "externalrefmgr.hxx"
60 #include "markdata.hxx"
61 #include "validat.hxx"
62 #include "dociter.hxx"
63 #include "detdata.hxx"
64 #include "detfunc.hxx"
65 #include "scmod.hxx"   		// SC_MOD
66 #include "inputopt.hxx" 	// GetExpandRefs
67 #include "chartlis.hxx"
68 #include "sc.hrc"			// SID_LINK
69 #include "hints.hxx"
70 #include "dpobject.hxx"
71 #include "unoguard.hxx"
72 #include "drwlayer.hxx"
73 #include "unoreflist.hxx"
74 #include "listenercalls.hxx"
75 // Wang Xu Ming -- 2009-8-17
76 // DataPilot Migration - Cache&&Performance
77 #include "dpshttab.hxx"
78 #include "dptablecache.hxx"
79 // End Comments
80 #include "tabprotection.hxx"
81 #include "formulaparserpool.hxx"
82 #include "clipparam.hxx"
83 #include "sheetevents.hxx"
84 
85 #include <memory>
86 
87 using namespace com::sun::star;
88 
89 //------------------------------------------------------------------------
90 
GetRangeName()91 ScRangeName* ScDocument::GetRangeName()
92 {
93 	return pRangeName;
94 }
95 
SetRangeName(ScRangeName * pNewRangeName)96 void ScDocument::SetRangeName( ScRangeName* pNewRangeName )
97 {
98 	if (pRangeName == pNewRangeName)
99 		return;
100 
101 	if (pRangeName)
102 		delete pRangeName;
103 	pRangeName = pNewRangeName;
104 }
105 
106 //UNUSED2008-05  ScRangeData* ScDocument::GetRangeAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab,
107 //UNUSED2008-05                                              sal_Bool bStartOnly) const
108 //UNUSED2008-05  {
109 //UNUSED2008-05      if ( pRangeName )
110 //UNUSED2008-05          return pRangeName->GetRangeAtCursor( ScAddress( nCol, nRow, nTab ), bStartOnly );
111 //UNUSED2008-05      else
112 //UNUSED2008-05          return NULL;
113 //UNUSED2008-05  }
114 
GetRangeAtBlock(const ScRange & rBlock,String * pName) const115 ScRangeData* ScDocument::GetRangeAtBlock( const ScRange& rBlock, String* pName ) const
116 {
117 	ScRangeData* pData = NULL;
118 	if ( pRangeName )
119 	{
120 		pData = pRangeName->GetRangeAtBlock( rBlock );
121 		if (pData && pName)
122 			*pName = pData->GetName();
123 	}
124 	return pData;
125 }
126 
GetDBCollection() const127 ScDBCollection* ScDocument::GetDBCollection() const
128 {
129 	return pDBCollection;
130 }
131 
SetDBCollection(ScDBCollection * pNewDBCollection,sal_Bool bRemoveAutoFilter)132 void ScDocument::SetDBCollection( ScDBCollection* pNewDBCollection, sal_Bool bRemoveAutoFilter )
133 {
134 	if ( bRemoveAutoFilter )
135 	{
136 		//	remove auto filter attribute if new db data don't contain auto filter flag
137 		//	start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
138 
139 		if ( pDBCollection )
140 		{
141 			sal_uInt16 nOldCount = pDBCollection->GetCount();
142 			for (sal_uInt16 nOld=0; nOld<nOldCount; nOld++)
143 			{
144 				ScDBData* pOldData = (*pDBCollection)[nOld];
145 				if ( pOldData->HasAutoFilter() )
146 				{
147 					ScRange aOldRange;
148 					pOldData->GetArea( aOldRange );
149 
150 					sal_Bool bFound = sal_False;
151 					sal_uInt16 nNewIndex = 0;
152 					if ( pNewDBCollection &&
153 						pNewDBCollection->SearchName( pOldData->GetName(), nNewIndex ) )
154 					{
155 						ScDBData* pNewData = (*pNewDBCollection)[nNewIndex];
156 						if ( pNewData->HasAutoFilter() )
157 						{
158 							ScRange aNewRange;
159 							pNewData->GetArea( aNewRange );
160 							if ( aOldRange.aStart == aNewRange.aStart )
161 								bFound = sal_True;
162 						}
163 					}
164 
165 					if ( !bFound )
166 					{
167 						aOldRange.aEnd.SetRow( aOldRange.aStart.Row() );
168 						RemoveFlagsTab( aOldRange.aStart.Col(), aOldRange.aStart.Row(),
169 										aOldRange.aEnd.Col(),   aOldRange.aEnd.Row(),
170 										aOldRange.aStart.Tab(), SC_MF_AUTO );
171                         RepaintRange( aOldRange );
172 					}
173 				}
174 			}
175 		}
176 	}
177 
178 	if (pDBCollection)
179 		delete pDBCollection;
180 	pDBCollection = pNewDBCollection;
181 }
182 
GetDBAtCursor(SCCOL nCol,SCROW nRow,SCTAB nTab,sal_Bool bStartOnly) const183 ScDBData* ScDocument::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
184 {
185 	if (pDBCollection)
186 		return pDBCollection->GetDBAtCursor(nCol, nRow, nTab, bStartOnly);
187 	else
188 		return NULL;
189 }
190 
GetDBAtArea(SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2) const191 ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
192 {
193 	if (pDBCollection)
194 		return pDBCollection->GetDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2);
195 	else
196 		return NULL;
197 }
198 
GetFilterDBAtTable(SCTAB nTab) const199 ScDBData* ScDocument::GetFilterDBAtTable(SCTAB nTab) const
200 {
201 	if (pDBCollection)
202 		return pDBCollection->GetFilterDBAtTable(nTab);
203 	else
204 		return NULL;
205 }
206 
GetDPCollection()207 ScDPCollection* ScDocument::GetDPCollection()
208 {
209 	if (!pDPCollection)
210 		pDPCollection = new ScDPCollection(this);
211 	return pDPCollection;
212 }
213 
GetDPAtCursor(SCCOL nCol,SCROW nRow,SCTAB nTab) const214 ScDPObject* ScDocument::GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
215 {
216 	if (!pDPCollection)
217 		return NULL;
218 
219 	sal_uInt16 nCount = pDPCollection->GetCount();
220 	ScAddress aPos( nCol, nRow, nTab );
221 	for (sal_uInt16 i=0; i<nCount; i++)
222 		if ( (*pDPCollection)[i]->GetOutRange().In( aPos ) )
223 			return (*pDPCollection)[i];
224 
225 	return NULL;
226 }
227 
GetDPAtBlock(const ScRange & rBlock) const228 ScDPObject* ScDocument::GetDPAtBlock( const ScRange & rBlock ) const
229 {
230     if (!pDPCollection)
231         return NULL;
232 
233     /* Walk the collection in reverse order to get something of an
234      * approximation of MS Excels 'most recent' effect. */
235     sal_uInt16 i = pDPCollection->GetCount();
236     while ( i-- > 0 )
237         if ( (*pDPCollection)[i]->GetOutRange().In( rBlock ) )
238             return (*pDPCollection)[i];
239 
240     return NULL;
241 }
242 
GetChartCollection() const243 ScChartCollection* ScDocument::GetChartCollection() const
244 {
245 	return pChartCollection;
246 }
247 
StopTemporaryChartLock()248 void ScDocument::StopTemporaryChartLock()
249 {
250     if( apTemporaryChartLock.get() )
251         apTemporaryChartLock->StopLocking();
252 }
253 
SetChartListenerCollection(ScChartListenerCollection * pNewChartListenerCollection,sal_Bool bSetChartRangeLists)254 void ScDocument::SetChartListenerCollection(
255 			ScChartListenerCollection* pNewChartListenerCollection,
256 			sal_Bool bSetChartRangeLists )
257 {
258 	ScChartListenerCollection* pOld = pChartListenerCollection;
259 	pChartListenerCollection = pNewChartListenerCollection;
260 	if ( pChartListenerCollection )
261 	{
262 		if ( pOld )
263 			pChartListenerCollection->SetDiffDirty( *pOld, bSetChartRangeLists );
264 		pChartListenerCollection->StartAllListeners();
265 	}
266 	delete pOld;
267 }
268 
SetScenario(SCTAB nTab,sal_Bool bFlag)269 void ScDocument::SetScenario( SCTAB nTab, sal_Bool bFlag )
270 {
271 	if (ValidTab(nTab) && pTab[nTab])
272 		pTab[nTab]->SetScenario(bFlag);
273 }
274 
IsScenario(SCTAB nTab) const275 sal_Bool ScDocument::IsScenario( SCTAB nTab ) const
276 {
277     return ValidTab(nTab) && pTab[nTab] &&pTab[nTab]->IsScenario();
278 	//if (ValidTab(nTab) && pTab[nTab])
279 	//	return pTab[nTab]->IsScenario();
280 
281 	//return sal_False;
282 }
283 
SetScenarioData(SCTAB nTab,const String & rComment,const Color & rColor,sal_uInt16 nFlags)284 void ScDocument::SetScenarioData( SCTAB nTab, const String& rComment,
285 										const Color& rColor, sal_uInt16 nFlags )
286 {
287 	if (ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
288 	{
289 		pTab[nTab]->SetScenarioComment( rComment );
290 		pTab[nTab]->SetScenarioColor( rColor );
291 		pTab[nTab]->SetScenarioFlags( nFlags );
292 	}
293 }
294 
GetTabBgColor(SCTAB nTab) const295 Color ScDocument::GetTabBgColor( SCTAB nTab ) const
296 {
297     if (ValidTab(nTab) && pTab[nTab])
298         return pTab[nTab]->GetTabBgColor();
299     return Color(COL_AUTO);
300 }
301 
SetTabBgColor(SCTAB nTab,const Color & rColor)302 void ScDocument::SetTabBgColor( SCTAB nTab, const Color& rColor )
303 {
304     if (ValidTab(nTab) && pTab[nTab])
305         pTab[nTab]->SetTabBgColor(rColor);
306 }
307 
IsDefaultTabBgColor(SCTAB nTab) const308 bool ScDocument::IsDefaultTabBgColor( SCTAB nTab ) const
309 {
310     if (ValidTab(nTab) && pTab[nTab])
311         return pTab[nTab]->GetTabBgColor() == COL_AUTO;
312     return true;
313 }
314 
GetScenarioData(SCTAB nTab,String & rComment,Color & rColor,sal_uInt16 & rFlags) const315 void ScDocument::GetScenarioData( SCTAB nTab, String& rComment,
316 										Color& rColor, sal_uInt16& rFlags ) const
317 {
318 	if (ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
319 	{
320 		pTab[nTab]->GetScenarioComment( rComment );
321 		rColor = pTab[nTab]->GetScenarioColor();
322 		rFlags = pTab[nTab]->GetScenarioFlags();
323 	}
324 }
325 
GetScenarioFlags(SCTAB nTab,sal_uInt16 & rFlags) const326 void ScDocument::GetScenarioFlags( SCTAB nTab, sal_uInt16& rFlags ) const
327 {
328     if (VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->IsScenario())
329         rFlags = pTab[nTab]->GetScenarioFlags();
330 }
331 
IsLinked(SCTAB nTab) const332 sal_Bool ScDocument::IsLinked( SCTAB nTab ) const
333 {
334     return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsLinked();
335     // euqivalent to
336 	//if (ValidTab(nTab) && pTab[nTab])
337 	//	return pTab[nTab]->IsLinked();
338 	//return sal_False;
339 }
340 
GetAddressConvention() const341 formula::FormulaGrammar::AddressConvention ScDocument::GetAddressConvention() const
342 {
343     return formula::FormulaGrammar::extractRefConvention(eGrammar);
344 }
345 
GetGrammar() const346 formula::FormulaGrammar::Grammar ScDocument::GetGrammar() const
347 {
348     return eGrammar;
349 }
350 
SetGrammar(formula::FormulaGrammar::Grammar eGram)351 void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram )
352 {
353     eGrammar = eGram;
354 }
355 
GetLinkMode(SCTAB nTab) const356 sal_Bool ScDocument::GetLinkMode( SCTAB nTab ) const
357 {
358 	if (ValidTab(nTab) && pTab[nTab])
359 		return pTab[nTab]->GetLinkMode();
360 	return SC_LINK_NONE;
361 }
362 
GetLinkDoc(SCTAB nTab) const363 const String& ScDocument::GetLinkDoc( SCTAB nTab ) const
364 {
365 	if (ValidTab(nTab) && pTab[nTab])
366 		return pTab[nTab]->GetLinkDoc();
367 	return EMPTY_STRING;
368 }
369 
GetLinkFlt(SCTAB nTab) const370 const String& ScDocument::GetLinkFlt( SCTAB nTab ) const
371 {
372 	if (ValidTab(nTab) && pTab[nTab])
373 		return pTab[nTab]->GetLinkFlt();
374 	return EMPTY_STRING;
375 }
376 
GetLinkOpt(SCTAB nTab) const377 const String& ScDocument::GetLinkOpt( SCTAB nTab ) const
378 {
379 	if (ValidTab(nTab) && pTab[nTab])
380 		return pTab[nTab]->GetLinkOpt();
381 	return EMPTY_STRING;
382 }
383 
GetLinkTab(SCTAB nTab) const384 const String& ScDocument::GetLinkTab( SCTAB nTab ) const
385 {
386 	if (ValidTab(nTab) && pTab[nTab])
387 		return pTab[nTab]->GetLinkTab();
388 	return EMPTY_STRING;
389 }
390 
GetLinkRefreshDelay(SCTAB nTab) const391 sal_uLong ScDocument::GetLinkRefreshDelay( SCTAB nTab ) const
392 {
393 	if (ValidTab(nTab) && pTab[nTab])
394 		return pTab[nTab]->GetLinkRefreshDelay();
395 	return 0;
396 }
397 
SetLink(SCTAB nTab,sal_uInt8 nMode,const String & rDoc,const String & rFilter,const String & rOptions,const String & rTabName,sal_uLong nRefreshDelay)398 void ScDocument::SetLink( SCTAB nTab, sal_uInt8 nMode, const String& rDoc,
399 							const String& rFilter, const String& rOptions,
400 							const String& rTabName, sal_uLong nRefreshDelay )
401 {
402 	if (ValidTab(nTab) && pTab[nTab])
403 		pTab[nTab]->SetLink( nMode, rDoc, rFilter, rOptions, rTabName, nRefreshDelay );
404 }
405 
HasLink(const String & rDoc,const String & rFilter,const String & rOptions) const406 sal_Bool ScDocument::HasLink( const String& rDoc,
407 							const String& rFilter, const String& rOptions ) const
408 {
409 	SCTAB nCount = GetTableCount();
410 	for (SCTAB i=0; i<nCount; i++)
411 		if (pTab[i]->IsLinked()
412 				&& pTab[i]->GetLinkDoc() == rDoc
413 				&& pTab[i]->GetLinkFlt() == rFilter
414 				&& pTab[i]->GetLinkOpt() == rOptions)
415 			return sal_True;
416 
417 	return sal_False;
418 }
419 
LinkExternalTab(SCTAB & rTab,const String & aDocTab,const String & aFileName,const String & aTabName)420 sal_Bool ScDocument::LinkExternalTab( SCTAB& rTab, const String& aDocTab,
421 		const String& aFileName, const String& aTabName )
422 {
423 	if ( IsClipboard() )
424 	{
425 		DBG_ERRORFILE( "LinkExternalTab in Clipboard" );
426 		return sal_False;
427 	}
428 	rTab = 0;
429 	String	aFilterName;		// wird vom Loader gefuellt
430 	String	aOptions;		// Filter-Optionen
431     sal_uInt32 nLinkCnt = pExtDocOptions ? pExtDocOptions->GetDocSettings().mnLinkCnt : 0;
432     ScDocumentLoader aLoader( aFileName, aFilterName, aOptions, nLinkCnt + 1 );
433 	if ( aLoader.IsError() )
434 		return sal_False;
435 	ScDocument* pSrcDoc = aLoader.GetDocument();
436 
437 	//	Tabelle kopieren
438 	SCTAB nSrcTab;
439 	if ( pSrcDoc->GetTable( aTabName, nSrcTab ) )
440 	{
441 		if ( !InsertTab( SC_TAB_APPEND, aDocTab, sal_True ) )
442 		{
443 			DBG_ERRORFILE("can't insert external document table");
444 			return sal_False;
445 		}
446 		rTab = GetTableCount() - 1;
447 		// nicht neu einfuegen, nur Ergebnisse
448 		TransferTab( pSrcDoc, nSrcTab, rTab, sal_False, sal_True );
449 	}
450 	else
451 		return sal_False;
452 
453 	sal_uLong nRefreshDelay = 0;
454 
455 	sal_Bool bWasThere = HasLink( aFileName, aFilterName, aOptions );
456 	SetLink( rTab, SC_LINK_VALUE, aFileName, aFilterName, aOptions, aTabName, nRefreshDelay );
457 	if ( !bWasThere )		// Link pro Quelldokument nur einmal eintragen
458 	{
459 		ScTableLink* pLink = new ScTableLink( pShell, aFileName, aFilterName, aOptions, nRefreshDelay );
460 		pLink->SetInCreate( sal_True );
461 		GetLinkManager()->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName,
462 										&aFilterName );
463 		pLink->Update();
464 		pLink->SetInCreate( sal_False );
465 		SfxBindings* pBindings = GetViewBindings();
466 		if (pBindings)
467 			pBindings->Invalidate( SID_LINKS );
468 	}
469 	return sal_True;
470 }
471 
GetExternalRefManager() const472 ScExternalRefManager* ScDocument::GetExternalRefManager() const
473 {
474     ScDocument* pThis = const_cast<ScDocument*>(this);
475     if (!pExternalRefMgr.get())
476         pThis->pExternalRefMgr.reset( new ScExternalRefManager( pThis));
477 
478     return pExternalRefMgr.get();
479 }
480 
IsInExternalReferenceMarking() const481 bool ScDocument::IsInExternalReferenceMarking() const
482 {
483     return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
484 }
485 
MarkUsedExternalReferences()486 void ScDocument::MarkUsedExternalReferences()
487 {
488     if (!pExternalRefMgr.get())
489         return;
490     if (!pExternalRefMgr->hasExternalData())
491         return;
492     // Charts.
493     bool bAllMarked = pExternalRefMgr->markUsedByLinkListeners();
494     // Formula cells.
495 	bAllMarked = pExternalRefMgr->markUsedExternalRefCells();
496 
497     /* NOTE: Conditional formats and validation objects are marked when
498      * collecting them during export. */
499 }
500 
GetFormulaParserPool() const501 ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
502 {
503     if( !mxFormulaParserPool.get() )
504         mxFormulaParserPool.reset( new ScFormulaParserPool( *this ) );
505     return *mxFormulaParserPool;
506 }
507 
GetSheetEvents(SCTAB nTab) const508 const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const
509 {
510     if (VALIDTAB(nTab) && pTab[nTab])
511         return pTab[nTab]->GetSheetEvents();
512     return NULL;
513 }
514 
SetSheetEvents(SCTAB nTab,const ScSheetEvents * pNew)515 void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew )
516 {
517     if (VALIDTAB(nTab) && pTab[nTab])
518         pTab[nTab]->SetSheetEvents( pNew );
519 }
520 
HasSheetEventScript(SCTAB nTab,sal_Int32 nEvent,bool bWithVbaEvents) const521 bool ScDocument::HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents ) const
522 {
523     if (pTab[nTab])
524     {
525         // check if any event handler script has been configured
526         const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents();
527         if ( pEvents && pEvents->GetScript( nEvent ) )
528             return true;
529         // check if VBA event handlers exist
530         if (bWithVbaEvents && mxVbaEvents.is()) try
531         {
532             uno::Sequence< uno::Any > aArgs( 1 );
533             aArgs[ 0 ] <<= nTab;
534             if (mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ) ||
535                 mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent ), uno::Sequence< uno::Any >() ))
536                 return true;
537         }
538         catch( uno::Exception& )
539         {
540         }
541     }
542     return false;
543 }
544 
HasAnySheetEventScript(sal_Int32 nEvent,bool bWithVbaEvents) const545 bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents ) const
546 {
547     for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
548         if (HasSheetEventScript( nTab, nEvent, bWithVbaEvents ))
549             return true;
550     return false;
551 }
552 
HasAnyCalcNotification() const553 bool ScDocument::HasAnyCalcNotification() const
554 {
555     for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
556         if (pTab[nTab] && pTab[nTab]->GetCalcNotification())
557             return true;
558     return false;
559 }
560 
HasCalcNotification(SCTAB nTab) const561 sal_Bool ScDocument::HasCalcNotification( SCTAB nTab ) const
562 {
563     if (VALIDTAB(nTab) && pTab[nTab])
564         return pTab[nTab]->GetCalcNotification();
565     return sal_False;
566 }
567 
SetCalcNotification(SCTAB nTab)568 void ScDocument::SetCalcNotification( SCTAB nTab )
569 {
570     // set only if not set before
571     if (VALIDTAB(nTab) && pTab[nTab] && !pTab[nTab]->GetCalcNotification())
572         pTab[nTab]->SetCalcNotification(sal_True);
573 }
574 
ResetCalcNotifications()575 void ScDocument::ResetCalcNotifications()
576 {
577     for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
578         if (pTab[nTab] && pTab[nTab]->GetCalcNotification())
579             pTab[nTab]->SetCalcNotification(sal_False);
580 }
581 
GetOutlineTable(SCTAB nTab,sal_Bool bCreate)582 ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, sal_Bool bCreate )
583 {
584 	ScOutlineTable* pVal = NULL;
585 
586 	if (VALIDTAB(nTab))
587 		if (pTab[nTab])
588 		{
589 			pVal = pTab[nTab]->GetOutlineTable();
590 			if (!pVal)
591 				if (bCreate)
592 				{
593 					pTab[nTab]->StartOutlineTable();
594 					pVal = pTab[nTab]->GetOutlineTable();
595 				}
596 		}
597 
598 	return pVal;
599 }
600 
SetOutlineTable(SCTAB nTab,const ScOutlineTable * pNewOutline)601 sal_Bool ScDocument::SetOutlineTable( SCTAB nTab, const ScOutlineTable* pNewOutline )
602 {
603     return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->SetOutlineTable(pNewOutline);
604 	//if (VALIDTAB(nTab))
605 	//	if (pTab[nTab])
606 	//		return pTab[nTab]->SetOutlineTable(pNewOutline);
607 
608 	//return sal_False;
609 }
610 
DoAutoOutline(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,SCTAB nTab)611 void ScDocument::DoAutoOutline( SCCOL nStartCol, SCROW nStartRow,
612 								SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
613 {
614 	if (VALIDTAB(nTab) && pTab[nTab])
615 	    pTab[nTab]->DoAutoOutline( nStartCol, nStartRow, nEndCol, nEndRow );
616 }
617 
TestRemoveSubTotals(SCTAB nTab,const ScSubTotalParam & rParam)618 sal_Bool ScDocument::TestRemoveSubTotals( SCTAB nTab, const ScSubTotalParam& rParam )
619 {
620     return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->TestRemoveSubTotals( rParam );
621 	//if (VALIDTAB(nTab) && pTab[nTab] )
622 	//	return pTab[nTab]->TestRemoveSubTotals( rParam );
623 
624 	//return sal_False;
625 }
626 
RemoveSubTotals(SCTAB nTab,ScSubTotalParam & rParam)627 void ScDocument::RemoveSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
628 {
629 	if ( VALIDTAB(nTab) && pTab[nTab] )
630 		pTab[nTab]->RemoveSubTotals( rParam );
631 }
632 
DoSubTotals(SCTAB nTab,ScSubTotalParam & rParam)633 sal_Bool ScDocument::DoSubTotals( SCTAB nTab, ScSubTotalParam& rParam )
634 {
635     return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->DoSubTotals( rParam );
636 	//if (VALIDTAB(nTab))
637 	//	if (pTab[nTab])
638 	//		return pTab[nTab]->DoSubTotals( rParam );
639 
640 	//return sal_False;
641 }
642 
HasSubTotalCells(const ScRange & rRange)643 sal_Bool ScDocument::HasSubTotalCells( const ScRange& rRange )
644 {
645 	ScCellIterator aIter( this, rRange );
646 	ScBaseCell* pCell = aIter.GetFirst();
647 	while (pCell)
648 	{
649 		if ( pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->IsSubTotal() )
650 			return sal_True;
651 
652 		pCell = aIter.GetNext();
653 	}
654 	return sal_False;	// none found
655 }
656 
657 //	kopiert aus diesem Dokument die Zellen von Positionen, an denen in pPosDoc
658 //	auch Zellen stehen, nach pDestDoc
659 
CopyUpdated(ScDocument * pPosDoc,ScDocument * pDestDoc)660 void ScDocument::CopyUpdated( ScDocument* pPosDoc, ScDocument* pDestDoc )
661 {
662 	SCTAB nCount = GetTableCount();
663 	for (SCTAB nTab=0; nTab<nCount; nTab++)
664 		if (pTab[nTab] && pPosDoc->pTab[nTab] && pDestDoc->pTab[nTab])
665 			pTab[nTab]->CopyUpdated( pPosDoc->pTab[nTab], pDestDoc->pTab[nTab] );
666 }
667 
CopyScenario(SCTAB nSrcTab,SCTAB nDestTab,sal_Bool bNewScenario)668 void ScDocument::CopyScenario( SCTAB nSrcTab, SCTAB nDestTab, sal_Bool bNewScenario )
669 {
670 	if (ValidTab(nSrcTab) && ValidTab(nDestTab) && pTab[nSrcTab] && pTab[nDestTab])
671 	{
672 		//	Flags fuer aktive Szenarios richtig setzen
673 		//	und aktuelle Werte in bisher aktive Szenarios zurueckschreiben
674 
675 		ScRangeList aRanges = *pTab[nSrcTab]->GetScenarioRanges();
676 		const sal_uLong nRangeCount = aRanges.Count();
677 
678 		//	nDestTab ist die Zieltabelle
679 		for ( SCTAB nTab = nDestTab+1;
680 				nTab<=MAXTAB && pTab[nTab] && pTab[nTab]->IsScenario();
681 				nTab++ )
682 		{
683 			if ( pTab[nTab]->IsActiveScenario() )		// auch wenn's dasselbe Szenario ist
684 			{
685 				sal_Bool bTouched = sal_False;
686 				for ( sal_uLong nR=0; nR<nRangeCount && !bTouched; nR++)
687 				{
688 					const ScRange* pRange = aRanges.GetObject(nR);
689 					if ( pTab[nTab]->HasScenarioRange( *pRange ) )
690 						bTouched = sal_True;
691 				}
692 				if (bTouched)
693 				{
694 					pTab[nTab]->SetActiveScenario(sal_False);
695 					if ( pTab[nTab]->GetScenarioFlags() & SC_SCENARIO_TWOWAY )
696 						pTab[nTab]->CopyScenarioFrom( pTab[nDestTab] );
697 				}
698 			}
699 		}
700 
701 		pTab[nSrcTab]->SetActiveScenario(sal_True);		// da kommt's her...
702 		if (!bNewScenario)							// Daten aus dem ausgewaehlten Szenario kopieren
703 		{
704 			sal_Bool bOldAutoCalc = GetAutoCalc();
705 			SetAutoCalc( sal_False );	// Mehrfachberechnungen vermeiden
706 			pTab[nSrcTab]->CopyScenarioTo( pTab[nDestTab] );
707 			SetDirty();
708 			SetAutoCalc( bOldAutoCalc );
709 		}
710 	}
711 }
712 
MarkScenario(SCTAB nSrcTab,SCTAB nDestTab,ScMarkData & rDestMark,sal_Bool bResetMark,sal_uInt16 nNeededBits) const713 void ScDocument::MarkScenario( SCTAB nSrcTab, SCTAB nDestTab, ScMarkData& rDestMark,
714 								sal_Bool bResetMark, sal_uInt16 nNeededBits ) const
715 {
716 	if (bResetMark)
717 		rDestMark.ResetMark();
718 
719 	if (ValidTab(nSrcTab) && pTab[nSrcTab])
720 		pTab[nSrcTab]->MarkScenarioIn( rDestMark, nNeededBits );
721 
722 	rDestMark.SetAreaTab( nDestTab );
723 }
724 
HasScenarioRange(SCTAB nTab,const ScRange & rRange) const725 sal_Bool ScDocument::HasScenarioRange( SCTAB nTab, const ScRange& rRange ) const
726 {
727     return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->HasScenarioRange( rRange );
728 	//if (ValidTab(nTab) && pTab[nTab])
729 	//	return pTab[nTab]->HasScenarioRange( rRange );
730 
731 	//return sal_False;
732 }
733 
GetScenarioRanges(SCTAB nTab) const734 const ScRangeList* ScDocument::GetScenarioRanges( SCTAB nTab ) const
735 {
736 	if (ValidTab(nTab) && pTab[nTab])
737 		return pTab[nTab]->GetScenarioRanges();
738 
739 	return NULL;
740 }
741 
IsActiveScenario(SCTAB nTab) const742 sal_Bool ScDocument::IsActiveScenario( SCTAB nTab ) const
743 {
744     return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->IsActiveScenario(  );
745 	//if (ValidTab(nTab) && pTab[nTab])
746 	//	return pTab[nTab]->IsActiveScenario();
747 
748 	//return sal_False;
749 }
750 
SetActiveScenario(SCTAB nTab,sal_Bool bActive)751 void ScDocument::SetActiveScenario( SCTAB nTab, sal_Bool bActive )
752 {
753 	if (ValidTab(nTab) && pTab[nTab])
754 		pTab[nTab]->SetActiveScenario( bActive );
755 }
756 
TestCopyScenario(SCTAB nSrcTab,SCTAB nDestTab) const757 sal_Bool ScDocument::TestCopyScenario( SCTAB nSrcTab, SCTAB nDestTab ) const
758 {
759 	if (ValidTab(nSrcTab) && ValidTab(nDestTab))
760 		return pTab[nSrcTab]->TestCopyScenarioTo( pTab[nDestTab] );
761 
762 	DBG_ERROR("falsche Tabelle bei TestCopyScenario");
763 	return sal_False;
764 }
765 
AddUnoObject(SfxListener & rObject)766 void ScDocument::AddUnoObject( SfxListener& rObject )
767 {
768 	if (!pUnoBroadcaster)
769 		pUnoBroadcaster = new SfxBroadcaster;
770 
771 	rObject.StartListening( *pUnoBroadcaster );
772 }
773 
RemoveUnoObject(SfxListener & rObject)774 void ScDocument::RemoveUnoObject( SfxListener& rObject )
775 {
776 	if (pUnoBroadcaster)
777 	{
778 		rObject.EndListening( *pUnoBroadcaster );
779 
780 		if ( bInUnoBroadcast )
781 		{
782 			//	#107294# Broadcasts from ScDocument::BroadcastUno are the only way that
783 			//	uno object methods are called without holding a reference.
784 			//
785 			//	If RemoveUnoObject is called from an object dtor in the finalizer thread
786 			//	while the main thread is calling BroadcastUno, the dtor thread must wait
787 			//	(or the object's Notify might try to access a deleted object).
788 			//	The SolarMutex can't be locked here because if a component is called from
789 			//	a VCL event, the main thread has the SolarMutex locked all the time.
790 			//
791 			//	This check is done after calling EndListening, so a later BroadcastUno call
792 			//	won't touch this object.
793 
794 			vos::IMutex& rSolarMutex = Application::GetSolarMutex();
795 			if ( rSolarMutex.tryToAcquire() )
796 			{
797 				//	BroadcastUno is always called with the SolarMutex locked, so if it
798 				//	can be acquired, this is within the same thread (should not happen)
799 				DBG_ERRORFILE( "RemoveUnoObject called from BroadcastUno" );
800 				rSolarMutex.release();
801 			}
802 			else
803 			{
804 				//	let the thread that called BroadcastUno continue
805 				while ( bInUnoBroadcast )
806 				{
807 					vos::OThread::yield();
808 				}
809 			}
810 		}
811 	}
812 	else
813 	{
814 		DBG_ERROR("No Uno broadcaster");
815 	}
816 }
817 
BroadcastUno(const SfxHint & rHint)818 void ScDocument::BroadcastUno( const SfxHint &rHint )
819 {
820 	if (pUnoBroadcaster)
821 	{
822 		bInUnoBroadcast = sal_True;
823 		pUnoBroadcaster->Broadcast( rHint );
824 		bInUnoBroadcast = sal_False;
825 
826 		// During Broadcast notification, Uno objects can add to pUnoListenerCalls.
827 		// The listener calls must be processed after completing the broadcast,
828 		// because they can add or remove objects from pUnoBroadcaster.
829 
830 		if ( pUnoListenerCalls && rHint.ISA( SfxSimpleHint ) &&
831 				((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DATACHANGED &&
832 				!bInUnoListenerCall )
833 		{
834 			// Listener calls may lead to BroadcastUno calls again. The listener calls
835 			// are not nested, instead the calls are collected in the list, and the
836 			// outermost call executes them all.
837 
838             ScChartLockGuard aChartLockGuard(this);
839 			bInUnoListenerCall = sal_True;
840 			pUnoListenerCalls->ExecuteAndClear();
841 			bInUnoListenerCall = sal_False;
842 		}
843 	}
844 }
845 
AddUnoListenerCall(const uno::Reference<util::XModifyListener> & rListener,const lang::EventObject & rEvent)846 void ScDocument::AddUnoListenerCall( const uno::Reference<util::XModifyListener>& rListener,
847 										const lang::EventObject& rEvent )
848 {
849 	DBG_ASSERT( bInUnoBroadcast, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
850 
851 	if ( !pUnoListenerCalls )
852 		pUnoListenerCalls = new ScUnoListenerCalls;
853 	pUnoListenerCalls->Add( rListener, rEvent );
854 }
855 
BeginUnoRefUndo()856 void ScDocument::BeginUnoRefUndo()
857 {
858     DBG_ASSERT( !pUnoRefUndoList, "BeginUnoRefUndo twice" );
859     delete pUnoRefUndoList;
860 
861     pUnoRefUndoList = new ScUnoRefList;
862 }
863 
EndUnoRefUndo()864 ScUnoRefList* ScDocument::EndUnoRefUndo()
865 {
866     ScUnoRefList* pRet = pUnoRefUndoList;
867     pUnoRefUndoList = NULL;
868     return pRet;                // must be deleted by caller!
869 }
870 
AddUnoRefChange(sal_Int64 nId,const ScRangeList & rOldRanges)871 void ScDocument::AddUnoRefChange( sal_Int64 nId, const ScRangeList& rOldRanges )
872 {
873     if ( pUnoRefUndoList )
874         pUnoRefUndoList->Add( nId, rOldRanges );
875 }
876 
GetNewUnoId()877 sal_Int64 ScDocument::GetNewUnoId()
878 {
879     return ++nUnoObjectId;
880 }
881 
UpdateReference(UpdateRefMode eUpdateRefMode,SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,ScDocument * pUndoDoc,sal_Bool bIncludeDraw,bool bUpdateNoteCaptionPos)882 void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode,
883 									SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
884 									SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
885 									SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
886 									ScDocument* pUndoDoc, sal_Bool bIncludeDraw,
887                                     bool bUpdateNoteCaptionPos )
888 {
889 	PutInOrder( nCol1, nCol2 );
890 	PutInOrder( nRow1, nRow2 );
891 	PutInOrder( nTab1, nTab2 );
892 	if (VALIDTAB(nTab1) && VALIDTAB(nTab2))
893 	{
894 		sal_Bool bExpandRefsOld = IsExpandRefs();
895 		if ( eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0 || nDz > 0) )
896 			SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
897 		SCTAB i;
898 		SCTAB iMax;
899 		if ( eUpdateRefMode == URM_COPY )
900 		{
901 			i = nTab1;
902 			iMax = nTab2;
903 		}
904 		else
905 		{
906 			ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
907 			xColNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
908 			xRowNameRanges->UpdateReference( eUpdateRefMode, this, aRange, nDx, nDy, nDz );
909 			pDBCollection->UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
910 			pRangeName->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
911 			if ( pDPCollection )
912 				pDPCollection->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
913 			UpdateChartRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
914 			UpdateRefAreaLinks( eUpdateRefMode, aRange, nDx, nDy, nDz );
915 			if ( pCondFormList )
916 				pCondFormList->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
917 			if ( pValidationList )
918 				pValidationList->UpdateReference( eUpdateRefMode, aRange, nDx, nDy, nDz );
919 			if ( pDetOpList )
920 				pDetOpList->UpdateReference( this, eUpdateRefMode, aRange, nDx, nDy, nDz );
921 			if ( pUnoBroadcaster )
922 				pUnoBroadcaster->Broadcast( ScUpdateRefHint(
923 									eUpdateRefMode, aRange, nDx, nDy, nDz ) );
924 			i = 0;
925 			iMax = MAXTAB;
926 		}
927 		for ( ; i<=iMax; i++)
928 			if (pTab[i])
929 				pTab[i]->UpdateReference(
930 					eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
931 					nDx, nDy, nDz, pUndoDoc, bIncludeDraw, bUpdateNoteCaptionPos );
932 
933 		if ( bIsEmbedded )
934 		{
935             SCCOL theCol1;
936             SCROW theRow1;
937             SCTAB theTab1;
938             SCCOL theCol2;
939             SCROW theRow2;
940             SCTAB theTab2;
941 			theCol1 = aEmbedRange.aStart.Col();
942 			theRow1 = aEmbedRange.aStart.Row();
943 			theTab1 = aEmbedRange.aStart.Tab();
944 			theCol2 = aEmbedRange.aEnd.Col();
945 			theRow2 = aEmbedRange.aEnd.Row();
946 			theTab2 = aEmbedRange.aEnd.Tab();
947 			if ( ScRefUpdate::Update( this, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2,
948 										nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
949 			{
950 				aEmbedRange = ScRange( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
951 			}
952 		}
953 		SetExpandRefs( bExpandRefsOld );
954 
955 		// #30428# after moving, no clipboard move ref-updates are possible
956 		if ( eUpdateRefMode != URM_COPY && IsClipboardSource() )
957 		{
958 			ScDocument* pClipDoc = SC_MOD()->GetClipDoc();
959 			if (pClipDoc)
960 				pClipDoc->GetClipParam().mbCutMode = false;
961 		}
962 	}
963 }
964 
UpdateTranspose(const ScAddress & rDestPos,ScDocument * pClipDoc,const ScMarkData & rMark,ScDocument * pUndoDoc)965 void ScDocument::UpdateTranspose( const ScAddress& rDestPos, ScDocument* pClipDoc,
966 										const ScMarkData& rMark, ScDocument* pUndoDoc )
967 {
968 	DBG_ASSERT(pClipDoc->bIsClip, "UpdateTranspose: kein Clip");
969 
970     ScRange aSource;
971     ScClipParam& rClipParam = GetClipParam();
972     if (rClipParam.maRanges.Count())
973         aSource = *rClipParam.maRanges.First();
974 	ScAddress aDest = rDestPos;
975 
976 	SCTAB nClipTab = 0;
977 	for (SCTAB nDestTab=0; nDestTab<=MAXTAB && pTab[nDestTab]; nDestTab++)
978 		if (rMark.GetTableSelect(nDestTab))
979 		{
980 			while (!pClipDoc->pTab[nClipTab]) nClipTab = (nClipTab+1) % (MAXTAB+1);
981 			aSource.aStart.SetTab( nClipTab );
982 			aSource.aEnd.SetTab( nClipTab );
983 			aDest.SetTab( nDestTab );
984 
985 			//	wie UpdateReference
986 
987 			pRangeName->UpdateTranspose( aSource, aDest );		// vor den Zellen!
988 			for (SCTAB i=0; i<=MAXTAB; i++)
989 				if (pTab[i])
990 					pTab[i]->UpdateTranspose( aSource, aDest, pUndoDoc );
991 
992 			nClipTab = (nClipTab+1) % (MAXTAB+1);
993 		}
994 }
995 
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY)996 void ScDocument::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
997 {
998 	//!	pDBCollection
999 	//!	pPivotCollection
1000 	//!	UpdateChartRef
1001 
1002 	pRangeName->UpdateGrow( rArea, nGrowX, nGrowY );
1003 
1004 	for (SCTAB i=0; i<=MAXTAB && pTab[i]; i++)
1005 		pTab[i]->UpdateGrow( rArea, nGrowX, nGrowY );
1006 }
1007 
Fill(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,const ScMarkData & rMark,sal_uLong nFillCount,FillDir eFillDir,FillCmd eFillCmd,FillDateCmd eFillDateCmd,double nStepValue,double nMaxValue)1008 void ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
1009 						sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
1010 						double nStepValue, double nMaxValue)
1011 {
1012 	PutInOrder( nCol1, nCol2 );
1013 	PutInOrder( nRow1, nRow2 );
1014 	for (SCTAB i=0; i <= MAXTAB; i++)
1015 		if (pTab[i])
1016 			if (rMark.GetTableSelect(i))
1017 				pTab[i]->Fill(nCol1, nRow1, nCol2, nRow2,
1018 								nFillCount, eFillDir, eFillCmd, eFillDateCmd,
1019 								nStepValue, nMaxValue);
1020 }
1021 
GetAutoFillPreview(const ScRange & rSource,SCCOL nEndX,SCROW nEndY)1022 String ScDocument::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
1023 {
1024 	SCTAB nTab = rSource.aStart.Tab();
1025 	if (pTab[nTab])
1026 		return pTab[nTab]->GetAutoFillPreview( rSource, nEndX, nEndY );
1027 
1028 	return EMPTY_STRING;
1029 }
1030 
AutoFormat(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,sal_uInt16 nFormatNo,const ScMarkData & rMark)1031 void ScDocument::AutoFormat( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1032 									sal_uInt16 nFormatNo, const ScMarkData& rMark )
1033 {
1034 	PutInOrder( nStartCol, nEndCol );
1035 	PutInOrder( nStartRow, nEndRow );
1036 	for (SCTAB i=0; i <= MAXTAB; i++)
1037 		if (pTab[i])
1038 			if (rMark.GetTableSelect(i))
1039 				pTab[i]->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo );
1040 }
1041 
GetAutoFormatData(SCTAB nTab,SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,ScAutoFormatData & rData)1042 void ScDocument::GetAutoFormatData(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1043 									ScAutoFormatData& rData)
1044 {
1045 	if (VALIDTAB(nTab))
1046 	{
1047 		if (pTab[nTab])
1048 		{
1049 			PutInOrder(nStartCol, nEndCol);
1050 			PutInOrder(nStartRow, nEndRow);
1051 			pTab[nTab]->GetAutoFormatData(nStartCol, nStartRow, nEndCol, nEndRow, rData);
1052 		}
1053 	}
1054 }
1055 
1056 // static
GetSearchAndReplaceStart(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow)1057 void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem& rSearchItem,
1058 		SCCOL& rCol, SCROW& rRow )
1059 {
1060 	sal_uInt16 nCommand = rSearchItem.GetCommand();
1061 	sal_Bool bReplace = ( nCommand == SVX_SEARCHCMD_REPLACE ||
1062 		nCommand == SVX_SEARCHCMD_REPLACE_ALL );
1063 	if ( rSearchItem.GetBackward() )
1064 	{
1065 		if ( rSearchItem.GetRowDirection() )
1066 		{
1067 			if ( rSearchItem.GetPattern() )
1068 			{
1069 				rCol = MAXCOL;
1070 				rRow = MAXROW+1;
1071 			}
1072 			else if ( bReplace )
1073 			{
1074 				rCol = MAXCOL;
1075 				rRow = MAXROW;
1076 			}
1077 			else
1078 			{
1079 				rCol = MAXCOL+1;
1080 				rRow = MAXROW;
1081 			}
1082 		}
1083 		else
1084 		{
1085 			if ( rSearchItem.GetPattern() )
1086 			{
1087 				rCol = MAXCOL+1;
1088 				rRow = MAXROW;
1089 			}
1090 			else if ( bReplace )
1091 			{
1092 				rCol = MAXCOL;
1093 				rRow = MAXROW;
1094 			}
1095 			else
1096 			{
1097 				rCol = MAXCOL;
1098 				rRow = MAXROW+1;
1099 			}
1100 		}
1101 	}
1102 	else
1103 	{
1104 		if ( rSearchItem.GetRowDirection() )
1105 		{
1106 			if ( rSearchItem.GetPattern() )
1107 			{
1108 				rCol = 0;
1109 				rRow = (SCROW) -1;
1110 			}
1111 			else if ( bReplace )
1112 			{
1113 				rCol = 0;
1114 				rRow = 0;
1115 			}
1116 			else
1117 			{
1118 				rCol = (SCCOL) -1;
1119 				rRow = 0;
1120 			}
1121 		}
1122 		else
1123 		{
1124 			if ( rSearchItem.GetPattern() )
1125 			{
1126 				rCol = (SCCOL) -1;
1127 				rRow = 0;
1128 			}
1129 			else if ( bReplace )
1130 			{
1131 				rCol = 0;
1132 				rRow = 0;
1133 			}
1134 			else
1135 			{
1136 				rCol = 0;
1137 				rRow = (SCROW) -1;
1138 			}
1139 		}
1140 	}
1141 }
1142 
SearchAndReplace(const SvxSearchItem & rSearchItem,SCCOL & rCol,SCROW & rRow,SCTAB & rTab,ScMarkData & rMark,String & rUndoStr,ScDocument * pUndoDoc)1143 sal_Bool ScDocument::SearchAndReplace(const SvxSearchItem& rSearchItem,
1144 								SCCOL& rCol, SCROW& rRow, SCTAB& rTab,
1145 								ScMarkData& rMark,
1146 								String& rUndoStr, ScDocument* pUndoDoc)
1147 {
1148 	//!		getrennte Markierungen pro Tabelle verwalten !!!!!!!!!!!!!
1149 
1150 	rMark.MarkToMulti();
1151 
1152 	sal_Bool bFound = sal_False;
1153 	if (VALIDTAB(rTab))
1154 	{
1155 		SCCOL nCol;
1156 		SCROW nRow;
1157 		SCTAB nTab;
1158 		sal_uInt16 nCommand = rSearchItem.GetCommand();
1159 		if ( nCommand == SVX_SEARCHCMD_FIND_ALL ||
1160 			 nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1161 		{
1162 			for (nTab = 0; nTab <= MAXTAB; nTab++)
1163 				if (pTab[nTab])
1164 				{
1165 					if (rMark.GetTableSelect(nTab))
1166 					{
1167 						nCol = 0;
1168 						nRow = 0;
1169 						bFound |= pTab[nTab]->SearchAndReplace(
1170 									rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
1171 					}
1172 				}
1173 
1174 			//	Markierung wird innen schon komplett gesetzt
1175 		}
1176 		else
1177 		{
1178 			nCol = rCol;
1179 			nRow = rRow;
1180 			if (rSearchItem.GetBackward())
1181 			{
1182 				for (nTab = rTab; ((SCsTAB)nTab >= 0) && !bFound; nTab--)
1183 					if (pTab[nTab])
1184 					{
1185 						if (rMark.GetTableSelect(nTab))
1186 						{
1187 							bFound = pTab[nTab]->SearchAndReplace(
1188 										rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
1189 							if (bFound)
1190 							{
1191 								rCol = nCol;
1192 								rRow = nRow;
1193 								rTab = nTab;
1194 							}
1195 							else
1196 								ScDocument::GetSearchAndReplaceStart(
1197 									rSearchItem, nCol, nRow );
1198 						}
1199 					}
1200 			}
1201 			else
1202 			{
1203 				for (nTab = rTab; (nTab <= MAXTAB) && !bFound; nTab++)
1204 					if (pTab[nTab])
1205 					{
1206 						if (rMark.GetTableSelect(nTab))
1207 						{
1208 							bFound = pTab[nTab]->SearchAndReplace(
1209 										rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc );
1210 							if (bFound)
1211 							{
1212 								rCol = nCol;
1213 								rRow = nRow;
1214 								rTab = nTab;
1215 							}
1216 							else
1217 								ScDocument::GetSearchAndReplaceStart(
1218 									rSearchItem, nCol, nRow );
1219 						}
1220 					}
1221 			}
1222 		}
1223 	}
1224 	return bFound;
1225 }
1226 
1227 //	Outline anpassen
1228 
UpdateOutlineCol(SCCOL nStartCol,SCCOL nEndCol,SCTAB nTab,sal_Bool bShow)1229 sal_Bool ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, sal_Bool bShow )
1230 {
1231 	if ( ValidTab(nTab) && pTab[nTab] )
1232 		return pTab[nTab]->UpdateOutlineCol( nStartCol, nEndCol, bShow );
1233 
1234 	DBG_ERROR("missing tab");
1235 	return sal_False;
1236 }
1237 
UpdateOutlineRow(SCROW nStartRow,SCROW nEndRow,SCTAB nTab,sal_Bool bShow)1238 sal_Bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_Bool bShow )
1239 {
1240 	if ( ValidTab(nTab) && pTab[nTab] )
1241 		return pTab[nTab]->UpdateOutlineRow( nStartRow, nEndRow, bShow );
1242 
1243 	DBG_ERROR("missing tab");
1244 	return sal_False;
1245 }
1246 
Sort(SCTAB nTab,const ScSortParam & rSortParam,sal_Bool bKeepQuery)1247 void ScDocument::Sort(SCTAB nTab, const ScSortParam& rSortParam, sal_Bool bKeepQuery)
1248 {
1249 	if ( ValidTab(nTab) && pTab[nTab] )
1250 	{
1251 		sal_Bool bOldDisableIdle = IsIdleDisabled();
1252 		DisableIdle( sal_True );
1253 		pTab[nTab]->Sort(rSortParam, bKeepQuery);
1254 		DisableIdle( bOldDisableIdle );
1255 	}
1256 }
1257 
Query(SCTAB nTab,const ScQueryParam & rQueryParam,sal_Bool bKeepSub)1258 SCSIZE ScDocument::Query(SCTAB nTab, const ScQueryParam& rQueryParam, sal_Bool bKeepSub)
1259 {
1260 	if ( ValidTab(nTab) && pTab[nTab] )
1261 		return pTab[nTab]->Query((ScQueryParam&)rQueryParam, bKeepSub);
1262 
1263 	DBG_ERROR("missing tab");
1264 	return 0;
1265 }
1266 
1267 
ValidQuery(SCROW nRow,SCTAB nTab,const ScQueryParam & rQueryParam,sal_Bool * pSpecial)1268 sal_Bool ScDocument::ValidQuery( SCROW nRow, SCTAB nTab, const ScQueryParam& rQueryParam, sal_Bool* pSpecial )
1269 {
1270 	if ( ValidTab(nTab) && pTab[nTab] )
1271 		return pTab[nTab]->ValidQuery( nRow, rQueryParam, pSpecial );
1272 
1273 	DBG_ERROR("missing tab");
1274 	return sal_False;
1275 }
1276 
1277 
GetUpperCellString(SCCOL nCol,SCROW nRow,SCTAB nTab,String & rStr)1278 void ScDocument::GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, String& rStr)
1279 {
1280 	if ( ValidTab(nTab) && pTab[nTab] )
1281 		pTab[nTab]->GetUpperCellString( nCol, nRow, rStr );
1282 	else
1283 		rStr.Erase();
1284 }
1285 
CreateQueryParam(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,SCTAB nTab,ScQueryParam & rQueryParam)1286 sal_Bool ScDocument::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScQueryParam& rQueryParam)
1287 {
1288 	if ( ValidTab(nTab) && pTab[nTab] )
1289 		return pTab[nTab]->CreateQueryParam(nCol1, nRow1, nCol2, nRow2, rQueryParam);
1290 
1291 	DBG_ERROR("missing tab");
1292 	return sal_False;
1293 }
1294 
HasAutoFilter(const SCCOL nCurCol,const SCROW nCurRow,const SCTAB nCurTab)1295 sal_Bool ScDocument::HasAutoFilter(
1296     const SCCOL nCurCol,
1297     const SCROW nCurRow,
1298     const SCTAB nCurTab )
1299 {
1300 	ScDBData*		pDBData			= GetDBAtCursor( nCurCol, nCurRow, nCurTab );
1301 	sal_Bool			bHasAutoFilter	= ( pDBData != NULL );
1302 
1303 	if ( pDBData )
1304 	{
1305 		if ( pDBData->HasHeader() )
1306 		{
1307 			SCCOL nCol;
1308 			SCROW nRow;
1309 			sal_Int16  nFlag;
1310 
1311 			ScQueryParam aParam;
1312 			pDBData->GetQueryParam( aParam );
1313 			nRow = aParam.nRow1;
1314 
1315 			for ( nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAutoFilter; nCol++ )
1316 			{
1317 				nFlag = ((ScMergeFlagAttr*)
1318 							GetAttr( nCol, nRow, nCurTab, ATTR_MERGE_FLAG ))->
1319 								GetValue();
1320 
1321 				if ( (nFlag & SC_MF_AUTO) == 0 )
1322 					bHasAutoFilter = sal_False;
1323 			}
1324 		}
1325 		else
1326 			bHasAutoFilter = sal_False;
1327 	}
1328 
1329 	return bHasAutoFilter;
1330 }
1331 
HasColHeader(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,SCTAB nTab)1332 sal_Bool ScDocument::HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1333 									SCTAB nTab )
1334 {
1335     return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1336 	//if (VALIDTAB(nTab))
1337 	//	if (pTab[nTab])
1338 	//		return pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1339 
1340 	//return sal_False;
1341 }
1342 
HasRowHeader(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,SCTAB nTab)1343 sal_Bool ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1344 									SCTAB nTab )
1345 {
1346     return VALIDTAB(nTab) && pTab[nTab] && pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1347 	//if (VALIDTAB(nTab))
1348 	//	if (pTab[nTab])
1349 	//		return pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1350 
1351 	//return sal_False;
1352 }
1353 
1354 //
1355 //	GetFilterEntries - Eintraege fuer AutoFilter-Listbox
1356 //
1357 
GetFilterEntries(SCCOL nCol,SCROW nRow,SCTAB nTab,bool bFilter,TypedScStrCollection & rStrings,bool & rHasDates)1358 sal_Bool ScDocument::GetFilterEntries(
1359     SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, TypedScStrCollection& rStrings, bool& rHasDates)
1360 {
1361 	if ( ValidTab(nTab) && pTab[nTab] && pDBCollection )
1362 	{
1363 		ScDBData* pDBData = pDBCollection->GetDBAtCursor(nCol, nRow, nTab, sal_False);	//!??
1364 		if (pDBData)
1365 		{
1366 			SCTAB nAreaTab;
1367 			SCCOL nStartCol;
1368 			SCROW nStartRow;
1369 			SCCOL nEndCol;
1370 			SCROW nEndRow;
1371 			pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
1372 
1373 		//Add for i85305
1374 			SCCOL nTmpStartCol = nCol;
1375             SCROW nTmpStartRow = nRow;
1376 			SCCOL nTmpEndCol = nCol;
1377             SCROW nTmpEndRow = nRow;
1378 			GetDataArea( nTab, nTmpStartCol, nTmpStartRow, nTmpEndCol, nTmpEndRow, sal_False, false);
1379 			if (nTmpEndRow > nEndRow)
1380 			{
1381 				nEndRow = nTmpEndRow;
1382 				pDBData->SetArea(nAreaTab, nStartCol,nStartRow, nEndCol,nEndRow);
1383 			}
1384 		//End of i85305
1385 
1386 			if (pDBData->HasHeader())
1387 				++nStartRow;
1388 
1389 			ScQueryParam aParam;
1390 			pDBData->GetQueryParam( aParam );
1391 			rStrings.SetCaseSensitive( aParam.bCaseSens );
1392 
1393             // return all filter entries, if a filter condition is connected with a boolean OR
1394             if ( bFilter )
1395             {
1396                 SCSIZE nEntryCount = aParam.GetEntryCount();
1397                 for ( SCSIZE i = 0; i < nEntryCount && aParam.GetEntry(i).bDoQuery; ++i )
1398                 {
1399                     ScQueryEntry& rEntry = aParam.GetEntry(i);
1400                     if ( rEntry.eConnect != SC_AND )
1401                     {
1402                         bFilter = false;
1403                         break;
1404                     }
1405                 }
1406             }
1407 
1408             if ( bFilter )
1409             {
1410                 pTab[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rStrings, rHasDates );
1411             }
1412             else
1413             {
1414                 pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
1415             }
1416 
1417 			return sal_True;
1418 		}
1419 	}
1420 
1421 	return sal_False;
1422 }
1423 
1424 //
1425 //	GetFilterEntriesArea - Eintraege fuer Filter-Dialog
1426 //
1427 
GetFilterEntriesArea(SCCOL nCol,SCROW nStartRow,SCROW nEndRow,SCTAB nTab,TypedScStrCollection & rStrings,bool & rHasDates)1428 sal_Bool ScDocument::GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRow,
1429                                         SCTAB nTab, TypedScStrCollection& rStrings, bool& rHasDates )
1430 {
1431 	if ( ValidTab(nTab) && pTab[nTab] )
1432 	{
1433         pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates );
1434 		return sal_True;
1435 	}
1436 
1437 	return sal_False;
1438 }
1439 
1440 //
1441 //	GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln)
1442 //
1443 
GetDataEntries(SCCOL nCol,SCROW nRow,SCTAB nTab,TypedScStrCollection & rStrings,sal_Bool bLimit)1444 sal_Bool ScDocument::GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab,
1445 									TypedScStrCollection& rStrings, sal_Bool bLimit )
1446 {
1447     if( !bLimit )
1448     {
1449         /*  Try to generate the list from list validation. This part is skipped,
1450             if bLimit==sal_True, because in that case this function is called to get
1451             cell values for auto completion on input. */
1452         sal_uInt32 nValidation = static_cast< const SfxUInt32Item* >( GetAttr( nCol, nRow, nTab, ATTR_VALIDDATA ) )->GetValue();
1453         if( nValidation )
1454         {
1455             const ScValidationData* pData = GetValidationEntry( nValidation );
1456             if( pData && pData->FillSelectionList( rStrings, ScAddress( nCol, nRow, nTab ) ) )
1457                 return sal_True;
1458         }
1459     }
1460 
1461     return ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
1462 	//if (ValidTab(nTab) && pTab[nTab])
1463 	//	return pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
1464 
1465 	//return sal_False;
1466 }
1467 
1468 //
1469 //	GetFormulaEntries - Eintraege fuer Formel-AutoEingabe
1470 //
1471 
1472 //	Funktionen werden als 1 schon vom InputHandler eingefuegt
1473 #define SC_STRTYPE_NAMES		2
1474 #define SC_STRTYPE_DBNAMES		3
1475 #define SC_STRTYPE_HEADERS		4
1476 
GetFormulaEntries(TypedScStrCollection & rStrings)1477 sal_Bool ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings )
1478 {
1479 	sal_uInt16 i;
1480 
1481 	//
1482 	//	Bereichsnamen
1483 	//
1484 
1485 	if ( pRangeName )
1486 	{
1487 		sal_uInt16 nRangeCount = pRangeName->GetCount();
1488 		for ( i=0; i<nRangeCount; i++ )
1489 		{
1490 			ScRangeData* pData = (*pRangeName)[i];
1491 			if (pData)
1492 			{
1493 				TypedStrData* pNew = new TypedStrData( pData->GetName(), 0.0, SC_STRTYPE_NAMES );
1494 				if ( !rStrings.Insert(pNew) )
1495 					delete pNew;
1496 			}
1497 		}
1498 	}
1499 
1500 	//
1501 	//	Datenbank-Bereiche
1502 	//
1503 
1504 	if ( pDBCollection )
1505 	{
1506 		sal_uInt16 nDBCount = pDBCollection->GetCount();
1507 		for ( i=0; i<nDBCount; i++ )
1508 		{
1509 			ScDBData* pData = (*pDBCollection)[i];
1510 			if (pData)
1511 			{
1512 				TypedStrData* pNew = new TypedStrData( pData->GetName(), 0.0, SC_STRTYPE_DBNAMES );
1513 				if ( !rStrings.Insert(pNew) )
1514 					delete pNew;
1515 			}
1516 		}
1517 	}
1518 
1519 	//
1520 	//	Inhalte von Beschriftungsbereichen
1521 	//
1522 
1523 	ScRangePairList* pLists[2];
1524 	pLists[0] = GetColNameRanges();
1525 	pLists[1] = GetRowNameRanges();
1526 	for (sal_uInt16 nListNo=0; nListNo<2; nListNo++)
1527 	{
1528 		ScRangePairList* pList = pLists[nListNo];
1529 		if (pList)
1530 			for ( ScRangePair* pPair = pList->First(); pPair; pPair = pList->Next() )
1531 			{
1532 				ScRange aRange = pPair->GetRange(0);
1533 				ScCellIterator aIter( this, aRange );
1534 				for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
1535 					if ( pCell->HasStringData() )
1536 					{
1537 						String aStr = pCell->GetStringData();
1538 						TypedStrData* pNew = new TypedStrData( aStr, 0.0, SC_STRTYPE_HEADERS );
1539 						if ( !rStrings.Insert(pNew) )
1540 							delete pNew;
1541 					}
1542 			}
1543 	}
1544 
1545 	return sal_True;
1546 }
1547 
1548 
IsEmbedded() const1549 sal_Bool ScDocument::IsEmbedded() const
1550 {
1551 	return bIsEmbedded;
1552 }
1553 
GetEmbedded(ScRange & rRange) const1554 void ScDocument::GetEmbedded( ScRange& rRange ) const
1555 {
1556     rRange = aEmbedRange;
1557 }
1558 
GetEmbeddedRect() const1559 Rectangle ScDocument::GetEmbeddedRect() const						// 1/100 mm
1560 {
1561 	Rectangle aRect;
1562 	ScTable* pTable = pTab[aEmbedRange.aStart.Tab()];
1563 	if (!pTable)
1564 	{
1565 		DBG_ERROR("GetEmbeddedRect ohne Tabelle");
1566 	}
1567 	else
1568 	{
1569 		SCCOL i;
1570 
1571 		for (i=0; i<aEmbedRange.aStart.Col(); i++)
1572 			aRect.Left() += pTable->GetColWidth(i);
1573         aRect.Top() += pTable->GetRowHeight( 0, aEmbedRange.aStart.Row() - 1);
1574 		aRect.Right() = aRect.Left();
1575 		for (i=aEmbedRange.aStart.Col(); i<=aEmbedRange.aEnd.Col(); i++)
1576 			aRect.Right() += pTable->GetColWidth(i);
1577 		aRect.Bottom() = aRect.Top();
1578         aRect.Bottom() += pTable->GetRowHeight( aEmbedRange.aStart.Row(), aEmbedRange.aEnd.Row());
1579 
1580 		aRect.Left()   = (long) ( aRect.Left()   * HMM_PER_TWIPS );
1581 		aRect.Right()  = (long) ( aRect.Right()  * HMM_PER_TWIPS );
1582 		aRect.Top()    = (long) ( aRect.Top()    * HMM_PER_TWIPS );
1583 		aRect.Bottom() = (long) ( aRect.Bottom() * HMM_PER_TWIPS );
1584 	}
1585 	return aRect;
1586 }
1587 
SetEmbedded(const ScRange & rRange)1588 void ScDocument::SetEmbedded( const ScRange& rRange )
1589 {
1590 	bIsEmbedded = sal_True;
1591 	aEmbedRange = rRange;
1592 }
1593 
ResetEmbedded()1594 void ScDocument::ResetEmbedded()
1595 {
1596 	bIsEmbedded = sal_False;
1597 	aEmbedRange = ScRange();
1598 }
1599 
1600 
1601 /** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
1602     while result is less than nStopTwips.
1603     @return sal_True if advanced at least one row.
1604  */
lcl_AddTwipsWhile(long & rTwips,long nStopTwips,SCROW & rPosY,SCROW nEndRow,const ScTable * pTable)1605 bool lcl_AddTwipsWhile( long & rTwips, long nStopTwips, SCROW & rPosY, SCROW nEndRow, const ScTable * pTable )
1606 {
1607     SCROW nRow = rPosY;
1608     bool bAdded = false;
1609     bool bStop = false;
1610     while (rTwips < nStopTwips && nRow <= nEndRow && !bStop)
1611     {
1612         SCROW nHeightEndRow;
1613         sal_uInt16 nHeight = pTable->GetRowHeight( nRow, NULL, &nHeightEndRow);
1614         if (nHeightEndRow > nEndRow)
1615             nHeightEndRow = nEndRow;
1616         if (!nHeight)
1617             nRow = nHeightEndRow + 1;
1618         else
1619         {
1620             SCROW nRows = nHeightEndRow - nRow + 1;
1621             sal_Int64 nAdd = static_cast<sal_Int64>(nHeight) * nRows;
1622             if (nAdd + rTwips >= nStopTwips)
1623             {
1624                 sal_Int64 nDiff = nAdd + rTwips - nStopTwips;
1625                 nRows -= static_cast<SCROW>(nDiff / nHeight);
1626                 nAdd = nHeight * nRows;
1627                 // We're looking for a value that satisfies loop condition.
1628                 if (nAdd + rTwips >= nStopTwips)
1629                 {
1630                     --nRows;
1631                     nAdd -= nHeight;
1632                 }
1633                 bStop = true;
1634             }
1635             rTwips += static_cast<long>(nAdd);
1636             nRow += nRows;
1637         }
1638     }
1639     if (nRow > rPosY)
1640     {
1641         --nRow;
1642         bAdded = true;
1643     }
1644     rPosY = nRow;
1645     return bAdded;
1646 }
1647 
GetRange(SCTAB nTab,const Rectangle & rMMRect)1648 ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
1649 {
1650 	ScTable* pTable = pTab[nTab];
1651 	if (!pTable)
1652 	{
1653 		DBG_ERROR("GetRange ohne Tabelle");
1654 		return ScRange();
1655 	}
1656 
1657 	Rectangle aPosRect = rMMRect;
1658 	if ( IsNegativePage( nTab ) )
1659 		ScDrawLayer::MirrorRectRTL( aPosRect );			// always with positive (LTR) values
1660 
1661 	long nSize;
1662 	long nTwips;
1663 	long nAdd;
1664 	sal_Bool bEnd;
1665 
1666 	nSize = 0;
1667 	nTwips = (long) (aPosRect.Left() / HMM_PER_TWIPS);
1668 
1669 	SCCOL nX1 = 0;
1670 	bEnd = sal_False;
1671 	while (!bEnd)
1672 	{
1673 		nAdd = (long) pTable->GetColWidth(nX1);
1674 		if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
1675 		{
1676 			nSize += nAdd;
1677 			++nX1;
1678 		}
1679 		else
1680 			bEnd = sal_True;
1681 	}
1682 
1683 	nTwips = (long) (aPosRect.Right() / HMM_PER_TWIPS);
1684 
1685 	SCCOL nX2 = nX1;
1686 	bEnd = sal_False;
1687 	while (!bEnd)
1688 	{
1689 		nAdd = (long) pTable->GetColWidth(nX2);
1690 		if (nSize+nAdd < nTwips && nX2<MAXCOL)
1691 		{
1692 			nSize += nAdd;
1693 			++nX2;
1694 		}
1695 		else
1696 			bEnd = sal_True;
1697 	}
1698 
1699 
1700 	nSize = 0;
1701 	nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
1702 
1703 	SCROW nY1 = 0;
1704     // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
1705     if (lcl_AddTwipsWhile( nSize, nTwips+2, nY1, MAXROW, pTable) && nY1 < MAXROW)
1706         ++nY1;  // original loop ended on last matched +1 unless that was MAXROW
1707 
1708 	nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS);
1709 
1710 	SCROW nY2 = nY1;
1711     // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
1712     if (lcl_AddTwipsWhile( nSize, nTwips, nY2, MAXROW, pTable) && nY2 < MAXROW)
1713         ++nY2;  // original loop ended on last matched +1 unless that was MAXROW
1714 
1715 	return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
1716 }
1717 
SetEmbedded(const Rectangle & rRect)1718 void ScDocument::SetEmbedded( const Rectangle& rRect )			// aus VisArea (1/100 mm)
1719 {
1720 	bIsEmbedded = sal_True;
1721 	aEmbedRange = GetRange( nVisibleTab, rRect );
1722 }
1723 
1724 //	VisArea auf Zellgrenzen anpassen
1725 
lcl_SnapHor(ScTable * pTable,long & rVal,SCCOL & rStartCol)1726 void lcl_SnapHor( ScTable* pTable, long& rVal, SCCOL& rStartCol )
1727 {
1728 	SCCOL nCol = 0;
1729 	long nTwips = (long) (rVal / HMM_PER_TWIPS);
1730 	long nSnap = 0;
1731 	while ( nCol<MAXCOL )
1732 	{
1733 		long nAdd = pTable->GetColWidth(nCol);
1734 		if ( nSnap + nAdd/2 < nTwips || nCol < rStartCol )
1735 		{
1736 			nSnap += nAdd;
1737 			++nCol;
1738 		}
1739 		else
1740 			break;
1741 	}
1742 	rVal = (long) ( nSnap * HMM_PER_TWIPS );
1743 	rStartCol = nCol;
1744 }
1745 
lcl_SnapVer(ScTable * pTable,long & rVal,SCROW & rStartRow)1746 void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow )
1747 {
1748 	SCROW nRow = 0;
1749 	long nTwips = (long) (rVal / HMM_PER_TWIPS);
1750 	long nSnap = 0;
1751 
1752     bool bFound = false;
1753     for (SCROW i = nRow; i <= MAXROW; ++i)
1754 	{
1755         SCROW nLastRow;
1756         if (pTable->RowHidden(i, NULL, &nLastRow))
1757         {
1758             i = nLastRow;
1759             continue;
1760         }
1761 
1762         nRow = i;
1763 		long nAdd = pTable->GetRowHeight(i);
1764 		if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow )
1765 		{
1766 			nSnap += nAdd;
1767 			++nRow;
1768 		}
1769 		else
1770         {
1771             bFound = true;
1772 			break;
1773         }
1774 	}
1775     if (!bFound)
1776         nRow = MAXROW;  // all hidden down to the bottom
1777 
1778 	rVal = (long) ( nSnap * HMM_PER_TWIPS );
1779 	rStartRow = nRow;
1780 }
1781 
SnapVisArea(Rectangle & rRect) const1782 void ScDocument::SnapVisArea( Rectangle& rRect ) const
1783 {
1784 	ScTable* pTable = pTab[nVisibleTab];
1785 	if (!pTable)
1786 	{
1787 		DBG_ERROR("SetEmbedded ohne Tabelle");
1788 		return;
1789 	}
1790 
1791     sal_Bool bNegativePage = IsNegativePage( nVisibleTab );
1792     if ( bNegativePage )
1793         ScDrawLayer::MirrorRectRTL( rRect );        // calculate with positive (LTR) values
1794 
1795 	SCCOL nCol = 0;
1796 	lcl_SnapHor( pTable, rRect.Left(), nCol );
1797 	++nCol;											// mindestens eine Spalte
1798 	lcl_SnapHor( pTable, rRect.Right(), nCol );
1799 
1800 	SCROW nRow = 0;
1801 	lcl_SnapVer( pTable, rRect.Top(), nRow );
1802 	++nRow;											// mindestens eine Zeile
1803 	lcl_SnapVer( pTable, rRect.Bottom(), nRow );
1804 
1805     if ( bNegativePage )
1806         ScDrawLayer::MirrorRectRTL( rRect );        // back to real rectangle
1807 }
1808 
GetDocProtection() const1809 ScDocProtection* ScDocument::GetDocProtection() const
1810 {
1811     return pDocProtection.get();
1812 }
1813 
SetDocProtection(const ScDocProtection * pProtect)1814 void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
1815 {
1816     if (pProtect)
1817         pDocProtection.reset(new ScDocProtection(*pProtect));
1818     else
1819         pDocProtection.reset();
1820 }
1821 
IsDocProtected() const1822 sal_Bool ScDocument::IsDocProtected() const
1823 {
1824     return pDocProtection.get() && pDocProtection->isProtected();
1825 }
1826 
IsDocEditable() const1827 sal_Bool ScDocument::IsDocEditable() const
1828 {
1829     // import into read-only document is possible
1830     return !IsDocProtected() && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
1831 }
1832 
IsTabProtected(SCTAB nTab) const1833 sal_Bool ScDocument::IsTabProtected( SCTAB nTab ) const
1834 {
1835 	if (VALIDTAB(nTab) && pTab[nTab])
1836 		return pTab[nTab]->IsProtected();
1837 
1838 	DBG_ERROR("Falsche Tabellennummer");
1839 	return sal_False;
1840 }
1841 
GetTabProtection(SCTAB nTab) const1842 ScTableProtection* ScDocument::GetTabProtection( SCTAB nTab ) const
1843 {
1844     if (VALIDTAB(nTab) && pTab[nTab])
1845         return pTab[nTab]->GetProtection();
1846 
1847     return NULL;
1848 }
1849 
SetTabProtection(SCTAB nTab,const ScTableProtection * pProtect)1850 void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
1851 {
1852     if (!ValidTab(nTab))
1853         return;
1854 
1855     pTab[nTab]->SetProtection(pProtect);
1856 }
1857 
CopyTabProtection(SCTAB nTabSrc,SCTAB nTabDest)1858 void ScDocument::CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest)
1859 {
1860     if (!ValidTab(nTabSrc) || !ValidTab(nTabDest))
1861         return;
1862 
1863     pTab[nTabDest]->SetProtection( pTab[nTabSrc]->GetProtection() );
1864 }
1865 
GetDocOptions() const1866 const ScDocOptions& ScDocument::GetDocOptions() const
1867 {
1868 	DBG_ASSERT( pDocOptions, "No DocOptions! :-(" );
1869 	return *pDocOptions;
1870 }
1871 
SetDocOptions(const ScDocOptions & rOpt)1872 void ScDocument::SetDocOptions( const ScDocOptions& rOpt )
1873 {
1874 	DBG_ASSERT( pDocOptions, "No DocOptions! :-(" );
1875 	*pDocOptions = rOpt;
1876 
1877 	xPoolHelper->SetFormTableOpt(rOpt);
1878 }
1879 
GetViewOptions() const1880 const ScViewOptions& ScDocument::GetViewOptions() const
1881 {
1882 	DBG_ASSERT( pViewOptions, "No ViewOptions! :-(" );
1883 	return *pViewOptions;
1884 }
1885 
SetViewOptions(const ScViewOptions & rOpt)1886 void ScDocument::SetViewOptions( const ScViewOptions& rOpt )
1887 {
1888 	DBG_ASSERT( pViewOptions, "No ViewOptions! :-(" );
1889 	*pViewOptions = rOpt;
1890 }
1891 
GetLanguage(LanguageType & rLatin,LanguageType & rCjk,LanguageType & rCtl) const1892 void ScDocument::GetLanguage( LanguageType& rLatin, LanguageType& rCjk, LanguageType& rCtl ) const
1893 {
1894 	rLatin = eLanguage;
1895 	rCjk = eCjkLanguage;
1896 	rCtl = eCtlLanguage;
1897 }
1898 
SetLanguage(LanguageType eLatin,LanguageType eCjk,LanguageType eCtl)1899 void ScDocument::SetLanguage( LanguageType eLatin, LanguageType eCjk, LanguageType eCtl )
1900 {
1901 	eLanguage = eLatin;
1902 	eCjkLanguage = eCjk;
1903 	eCtlLanguage = eCtl;
1904 	if ( xPoolHelper.isValid() )
1905 	{
1906 		ScDocumentPool* pPool = xPoolHelper->GetDocPool();
1907 		pPool->SetPoolDefaultItem( SvxLanguageItem( eLanguage, ATTR_FONT_LANGUAGE ) );
1908 		pPool->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage, ATTR_CJK_FONT_LANGUAGE ) );
1909 		pPool->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage, ATTR_CTL_FONT_LANGUAGE ) );
1910 	}
1911 
1912 	UpdateDrawLanguages();		// set edit engine defaults in drawing layer pool
1913 }
1914 
GetMMRect(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,SCTAB nTab)1915 Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow,
1916 								SCCOL nEndCol, SCROW nEndRow, SCTAB nTab )
1917 {
1918 	if (!ValidTab(nTab) || !pTab[nTab])
1919 	{
1920 		DBG_ERROR("GetMMRect: falsche Tabelle");
1921 		return Rectangle(0,0,0,0);
1922 	}
1923 
1924 	SCCOL i;
1925 	Rectangle aRect;
1926 
1927 	for (i=0; i<nStartCol; i++)
1928 		aRect.Left() += GetColWidth(i,nTab);
1929     aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab);
1930 
1931 	aRect.Right()  = aRect.Left();
1932 	aRect.Bottom() = aRect.Top();
1933 
1934 	for (i=nStartCol; i<=nEndCol; i++)
1935 		aRect.Right() += GetColWidth(i,nTab);
1936     aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab);
1937 
1938 	aRect.Left()	= (long)(aRect.Left()	* HMM_PER_TWIPS);
1939 	aRect.Right()	= (long)(aRect.Right()	* HMM_PER_TWIPS);
1940 	aRect.Top()		= (long)(aRect.Top()	* HMM_PER_TWIPS);
1941 	aRect.Bottom()	= (long)(aRect.Bottom()	* HMM_PER_TWIPS);
1942 
1943 	if ( IsNegativePage( nTab ) )
1944 		ScDrawLayer::MirrorRectRTL( aRect );
1945 
1946 	return aRect;
1947 }
1948 
SetExtDocOptions(ScExtDocOptions * pNewOptions)1949 void ScDocument::SetExtDocOptions( ScExtDocOptions* pNewOptions )
1950 {
1951 	delete pExtDocOptions;
1952 	pExtDocOptions = pNewOptions;
1953 }
1954 
DoMergeContents(SCTAB nTab,SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow)1955 void ScDocument::DoMergeContents( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
1956 									SCCOL nEndCol, SCROW nEndRow )
1957 {
1958 	String aEmpty;
1959 	String aTotal;
1960 	String aCellStr;
1961 	SCCOL nCol;
1962 	SCROW nRow;
1963 	for (nRow=nStartRow; nRow<=nEndRow; nRow++)
1964 		for (nCol=nStartCol; nCol<=nEndCol; nCol++)
1965 		{
1966 			GetString(nCol,nRow,nTab,aCellStr);
1967 			if (aCellStr.Len())
1968 			{
1969 				if (aTotal.Len())
1970 					aTotal += ' ';
1971 				aTotal += aCellStr;
1972 			}
1973 			if (nCol != nStartCol || nRow != nStartRow)
1974 				SetString(nCol,nRow,nTab,aEmpty);
1975 		}
1976 
1977 	SetString(nStartCol,nStartRow,nTab,aTotal);
1978 }
1979 
DoMerge(SCTAB nTab,SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,bool bDeleteCaptions)1980 void ScDocument::DoMerge( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
1981                                     SCCOL nEndCol, SCROW nEndRow, bool bDeleteCaptions )
1982 {
1983 	ScMergeAttr aAttr( nEndCol-nStartCol+1, nEndRow-nStartRow+1 );
1984 	ApplyAttr( nStartCol, nStartRow, nTab, aAttr );
1985 
1986 	if ( nEndCol > nStartCol )
1987 		ApplyFlagsTab( nStartCol+1, nStartRow, nEndCol, nStartRow, nTab, SC_MF_HOR );
1988 	if ( nEndRow > nStartRow )
1989 		ApplyFlagsTab( nStartCol, nStartRow+1, nStartCol, nEndRow, nTab, SC_MF_VER );
1990 	if ( nEndCol > nStartCol && nEndRow > nStartRow )
1991 		ApplyFlagsTab( nStartCol+1, nStartRow+1, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
1992 
1993     // remove all covered notes (removed captions are collected by drawing undo if active)
1994     sal_uInt16 nDelFlag = IDF_NOTE | (bDeleteCaptions ? 0 : IDF_NOCAPTIONS);
1995     if( nStartCol < nEndCol )
1996         DeleteAreaTab( nStartCol + 1, nStartRow, nEndCol, nStartRow, nTab, nDelFlag );
1997     if( nStartRow < nEndRow )
1998         DeleteAreaTab( nStartCol, nStartRow + 1, nEndCol, nEndRow, nTab, nDelFlag );
1999 }
2000 
RemoveMerge(SCCOL nCol,SCROW nRow,SCTAB nTab)2001 void ScDocument::RemoveMerge( SCCOL nCol, SCROW nRow, SCTAB nTab )
2002 {
2003 	const ScMergeAttr* pAttr = (const ScMergeAttr*)
2004 									GetAttr( nCol, nRow, nTab, ATTR_MERGE );
2005 
2006 	if ( pAttr->GetColMerge() <= 1 && pAttr->GetRowMerge() <= 1 )
2007 		return;
2008 
2009 	SCCOL nEndCol = nCol + pAttr->GetColMerge() - 1;
2010 	SCROW nEndRow = nRow + pAttr->GetRowMerge() - 1;
2011 
2012 	RemoveFlagsTab( nCol, nRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
2013 
2014 	const ScMergeAttr* pDefAttr = (const ScMergeAttr*)
2015 										&xPoolHelper->GetDocPool()->GetDefaultItem( ATTR_MERGE );
2016 	ApplyAttr( nCol, nRow, nTab, *pDefAttr );
2017 }
2018 
ExtendPrintArea(OutputDevice * pDev,SCTAB nTab,SCCOL nStartCol,SCROW nStartRow,SCCOL & rEndCol,SCROW nEndRow)2019 void ScDocument::ExtendPrintArea( OutputDevice* pDev, SCTAB nTab,
2020 					SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
2021 {
2022 	if ( ValidTab(nTab)  && pTab[nTab] )
2023 		pTab[nTab]->ExtendPrintArea( pDev, nStartCol, nStartRow, rEndCol, nEndRow );
2024 }
2025 
IncSizeRecalcLevel(SCTAB nTab)2026 void ScDocument::IncSizeRecalcLevel( SCTAB nTab )
2027 {
2028 	if ( ValidTab(nTab)  && pTab[nTab] )
2029 		pTab[nTab]->IncRecalcLevel();
2030 }
2031 
DecSizeRecalcLevel(SCTAB nTab,bool bUpdateNoteCaptionPos)2032 void ScDocument::DecSizeRecalcLevel( SCTAB nTab, bool bUpdateNoteCaptionPos )
2033 {
2034 	if ( ValidTab(nTab)  && pTab[nTab] )
2035 		pTab[nTab]->DecRecalcLevel( bUpdateNoteCaptionPos );
2036 }
2037 
2038 // Wang Xu Ming -- 2009-8-17
2039 // DataPilot Migration - Cache&&Performance
GetDPObjectCache(long nID)2040 ScDPTableDataCache* ScDocument::GetDPObjectCache( long nID )
2041 {
2042     for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
2043     { //
2044         if ( nID == (*iter)->GetId() )
2045             return *iter;
2046     }
2047     return NULL;
2048 }
2049 
GetUsedDPObjectCache(ScRange rRange)2050 ScDPTableDataCache* ScDocument::GetUsedDPObjectCache ( ScRange rRange )
2051 {
2052     ScDPTableDataCache* pCache = NULL;
2053     sal_uInt16 nCount = GetDPCollection()->GetCount();
2054     for ( short i=nCount-1; i>=0 ; i--)
2055     {
2056         if ( const ScSheetSourceDesc* pUsedSheetDesc = (*pDPCollection)[i]->GetSheetDesc() )
2057             if ( rRange == pUsedSheetDesc->aSourceRange )
2058             {
2059                 long nID = (*pDPCollection)[i]->GetCacheId();
2060                 if ( nID >= 0  )
2061                     pCache= GetDPObjectCache( nID );
2062                 if ( pCache )
2063                     return pCache;
2064             }
2065     }
2066     return pCache;
2067 }
2068 
AddDPObjectCache(ScDPTableDataCache * pData)2069 long ScDocument::AddDPObjectCache( ScDPTableDataCache* pData )
2070 {
2071     if ( pData->GetId() < 0 )
2072     { //create a id for it
2073         pData->SetId( GetNewDPObjectCacheId() );
2074     }
2075     m_listDPObjectsCaches.push_back( pData );
2076     return pData->GetId();
2077 }
2078 
GetNewDPObjectCacheId()2079 long ScDocument::GetNewDPObjectCacheId()
2080 {
2081     long nID = 0;
2082 
2083     bool bFound = false;
2084     std::list<ScDPTableDataCache*>::iterator iter;
2085     do {
2086         for ( iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
2087         { //Get a new Id
2088             if ( nID == (*iter)->GetId() )
2089             {
2090                 nID++;
2091                 bFound = true;
2092                 break;
2093             }
2094         }
2095         if ( iter == m_listDPObjectsCaches.end() )
2096             bFound = false;
2097     } while ( bFound );
2098 
2099     return nID;
2100 }
2101 
RemoveDPObjectCache(long nID)2102 void ScDocument::RemoveDPObjectCache( long nID )
2103 {
2104     for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
2105     {
2106         if ( nID == (*iter)->GetId() )
2107         {
2108             ScDPTableDataCache* pCache = *iter;
2109             m_listDPObjectsCaches.erase( iter );
2110             delete pCache;
2111             break;
2112         }
2113     }
2114 
2115 }
2116 
RemoveUnusedDPObjectCaches()2117 void ScDocument::RemoveUnusedDPObjectCaches()
2118 {
2119     for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); )
2120     {
2121         long  nID = (*iter)->GetId();
2122         sal_uInt16 nCount = GetDPCollection()->GetCount();
2123         sal_uInt16 i ;
2124         for ( i=0; i<nCount; i++)
2125         {
2126             if ( nID ==  (*pDPCollection)[i]->GetCacheId() )
2127                 break;
2128         }
2129         if ( i == nCount )
2130         {
2131             ScDPTableDataCache* pCache = *iter;
2132             iter = m_listDPObjectsCaches.erase( iter );
2133             delete pCache;
2134             continue;
2135         }
2136         ++iter;
2137     }
2138 }
2139 
GetUsedDPObjectCache(std::list<ScDPTableDataCache * > & usedlist)2140 void ScDocument::GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist )
2141 {
2142     for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
2143     {
2144         long  nID = (*iter)->GetId();
2145         sal_uInt16 nCount = GetDPCollection()->GetCount();
2146         sal_uInt16 i=0;
2147         for ( i=0; i<nCount; i++)
2148             if ( nID ==  (*pDPCollection)[i]->GetCacheId() )
2149                 break;
2150         if ( i != nCount )
2151             usedlist.push_back( *iter );
2152     }
2153 }
2154 // End Comments
2155 
GetPatternCount(SCTAB nTab,SCCOL nCol)2156 SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol )
2157 {
2158     if( ValidTab(nTab) && pTab[nTab] )
2159         return pTab[nTab]->GetPatternCount( nCol );
2160     else
2161         return 0;
2162 }
2163 
GetPatternCount(SCTAB nTab,SCCOL nCol,SCROW nRw1,SCROW nRw2)2164 SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol, SCROW nRw1, SCROW nRw2 )
2165 {
2166     if( ValidTab(nTab) && pTab[nTab] )
2167         return pTab[nTab]->GetPatternCount( nCol, nRw1, nRw2 );
2168     else
2169         return 0;
2170 }
2171 
ReservedPatternCount(SCTAB nTab,SCCOL nCol,SCSIZE nReserved)2172 bool ScDocument::ReservedPatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserved )
2173 {
2174     if( ValidTab(nTab) && pTab[nTab] )
2175         return pTab[nTab]->ReservedPatternCount( nCol, nReserved );
2176     else
2177         return false;
2178 }
2179