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