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