1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <editeng/boxitem.hxx>
24 #include <editeng/frmdiritem.hxx>
25 #include "editeng/editobj.hxx"
26 #include <svx/pageitem.hxx>
27 #include <editeng/editeng.hxx>
28 #include <svx/sdrundomanager.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdpage.hxx>
31 #include <svx/svdocapt.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <svl/poolcach.hxx>
36 #include <unotools/saveopt.hxx>
37 #include <svl/zforlist.hxx>
38 #include <unotools/charclass.hxx>
39 #include <unotools/transliterationwrapper.hxx>
40 #include <tools/tenccvt.hxx>
41 #include <tools/urlobj.hxx>
43 #include <com/sun/star/text/WritingMode2.hpp>
44 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
45 #include <com/sun/star/sheet/TablePageBreakData.hpp>
46 #include <com/sun/star/lang/NotInitializedException.hpp>
48 #include "document.hxx"
51 #include "attarray.hxx"
52 #include "markarr.hxx"
53 #include "patattr.hxx"
54 #include "rangenam.hxx"
55 #include "poolhelp.hxx"
56 #include "docpool.hxx"
57 #include "stlpool.hxx"
58 #include "stlsheet.hxx"
59 #include "globstr.hrc"
60 #include "rechead.hxx"
63 #include "chartlis.hxx"
64 #include "rangelst.hxx"
65 #include "markdata.hxx"
66 #include "drwlayer.hxx"
67 #include "conditio.hxx"
68 #include "colorscale.hxx"
69 #include "validat.hxx"
70 #include "prnsave.hxx"
71 #include "chgtrack.hxx"
73 #include "scresid.hxx"
75 #include "detdata.hxx"
76 #include "dpobject.hxx"
77 #include "detfunc.hxx"
79 #include "dociter.hxx"
80 #include "progress.hxx"
81 #include "autonamecache.hxx"
82 #include "bcaslot.hxx"
84 #include "externalrefmgr.hxx"
85 #include "tabprotection.hxx"
86 #include "clipparam.hxx"
87 #include "stlalgorithm.hxx"
88 #include "defaultsoptions.hxx"
89 #include "editutil.hxx"
90 #include "stringutil.hxx"
91 #include "formulaiter.hxx"
92 #include "formulacell.hxx"
93 #include "clipcontext.hxx"
94 #include "listenercontext.hxx"
95 #include "scopetools.hxx"
96 #include "refupdatecontext.hxx"
97 #include "formulagroup.hxx"
99 #include "formula/vectortoken.hxx"
103 #include <boost/scoped_ptr.hpp>
105 #include "mtvelements.hxx"
107 using ::editeng::SvxBorderLine
;
108 using namespace ::com::sun::star
;
110 namespace WritingMode2
= ::com::sun::star::text::WritingMode2
;
111 using ::com::sun::star::uno::Sequence
;
112 using ::com::sun::star::sheet::TablePageBreakData
;
117 std::pair
<SCTAB
,SCTAB
> getMarkedTableRange(const std::vector
<ScTable
*>& rTables
, const ScMarkData
& rMark
)
119 SCTAB nTabStart
= MAXTAB
;
121 SCTAB nMax
= static_cast<SCTAB
>(rTables
.size());
122 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
123 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
128 if (*itr
< nTabStart
)
133 return std::pair
<SCTAB
,SCTAB
>(nTabStart
,nTabEnd
);
140 const ScPatternAttr
* pAttr
;
143 ScDefaultAttr(const ScPatternAttr
* pPatAttr
) : pAttr(pPatAttr
), nFirst(0), nCount(0) {}
146 struct ScLessDefaultAttr
148 bool operator() (const ScDefaultAttr
& rValue1
, const ScDefaultAttr
& rValue2
) const
150 return rValue1
.pAttr
< rValue2
.pAttr
;
154 typedef std::set
<ScDefaultAttr
, ScLessDefaultAttr
> ScDefaultAttrSet
;
156 void ScDocument::MakeTable( SCTAB nTab
,bool _bNeedsNameCheck
)
158 if ( ValidTab(nTab
) && ( nTab
>= static_cast<SCTAB
>(maTabs
.size()) ||!maTabs
[nTab
]) )
161 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
162 OUString aString
= rOpt
.GetInitTabPrefix();
164 aString
+= OUString::number(nTab
+1);
165 if ( _bNeedsNameCheck
)
166 CreateValidTabName( aString
); // no doubles
167 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
169 maTabs
[nTab
] = new ScTable(this, nTab
, aString
);
173 while(nTab
> static_cast<SCTAB
>(maTabs
.size()))
174 maTabs
.push_back(NULL
);
175 maTabs
.push_back( new ScTable(this, nTab
, aString
) );
177 maTabs
[nTab
]->SetLoadingMedium(bLoadingMedium
);
182 bool ScDocument::HasTable( SCTAB nTab
) const
184 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
191 bool ScDocument::GetName( SCTAB nTab
, OUString
& rName
) const
193 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
196 maTabs
[nTab
]->GetName( rName
);
203 OUString
ScDocument::GetCopyTabName( SCTAB nTab
) const
205 if (nTab
< static_cast<SCTAB
>(maTabNames
.size()))
206 return maTabNames
[nTab
];
211 bool ScDocument::SetCodeName( SCTAB nTab
, const OUString
& rName
)
213 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
217 maTabs
[nTab
]->SetCodeName( rName
);
221 OSL_TRACE( "**** can't set code name %s", OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr() );
225 bool ScDocument::GetCodeName( SCTAB nTab
, OUString
& rName
) const
227 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
230 maTabs
[nTab
]->GetCodeName( rName
);
237 bool ScDocument::GetTable( const OUString
& rName
, SCTAB
& rTab
) const
239 OUString aUpperName
= ScGlobal::pCharClass
->uppercase(rName
);
241 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
244 if (aUpperName
.equals(maTabs
[i
]->GetUpperName()))
254 std::vector
<OUString
> ScDocument::GetAllTableNames() const
256 std::vector
<OUString
> aNames
;
257 aNames
.reserve(maTabs
.size());
258 TableContainer::const_iterator it
= maTabs
.begin(), itEnd
= maTabs
.end();
259 for (; it
!= itEnd
; ++it
)
262 const ScTable
& rTab
= **it
;
264 aNames
.push_back(aName
);
270 ScDBData
* ScDocument::GetAnonymousDBData(SCTAB nTab
)
272 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
273 return maTabs
[nTab
]->GetAnonymousDBData();
277 SCTAB
ScDocument::GetTableCount() const
279 return static_cast<SCTAB
>(maTabs
.size());
282 void ScDocument::SetAnonymousDBData(SCTAB nTab
, ScDBData
* pDBData
)
284 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
285 maTabs
[nTab
]->SetAnonymousDBData(pDBData
);
289 bool ScDocument::ValidTabName( const OUString
& rName
)
293 sal_Int32 nLen
= rName
.getLength();
296 // Restrict sheet names to what Excel accepts.
297 /* TODO: We may want to remove this restriction for full ODFF compliance.
298 * Merely loading and calculating ODF documents using these characters in
299 * sheet names is not affected by this, but all sheet name editing and
300 * copying functionality is, maybe falling back to "Sheet4" or similar. */
301 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
303 const sal_Unicode c
= rName
[i
];
313 // these characters are not allowed to match XL's convention.
316 if (i
== 0 || i
== nLen
- 1)
317 // single quote is not allowed at the first or last
318 // character position.
329 bool ScDocument::ValidNewTabName( const OUString
& rName
) const
331 bool bValid
= ValidTabName(rName
);
332 TableContainer::const_iterator it
= maTabs
.begin();
333 for (; it
!= maTabs
.end() && bValid
; ++it
)
337 (*it
)->GetName(aOldName
);
338 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
344 void ScDocument::CreateValidTabName(OUString
& rName
) const
346 if ( !ValidTabName(rName
) )
351 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
352 OUString aStrTable
= rOpt
.GetInitTabPrefix();
356 // First test if the prefix is valid, if so only avoid doubles
357 bool bPrefix
= ValidTabName( aStrTable
);
358 OSL_ENSURE(bPrefix
, "Invalid Table Name");
361 for ( SCTAB i
= static_cast<SCTAB
>(maTabs
.size())+1; !bOk
; i
++ )
364 aBuf
.append(aStrTable
);
365 aBuf
.append(static_cast<sal_Int32
>(i
));
366 rName
= aBuf
.makeStringAndClear();
368 bOk
= ValidNewTabName( rName
);
370 bOk
= !GetTable( rName
, nDummy
);
375 // testing the supplied Name
377 if ( !ValidNewTabName(rName
) )
380 OUStringBuffer aName
;
386 aName
.append(static_cast<sal_Int32
>(i
));
388 while (!ValidNewTabName(aName
.toString()) && (i
< MAXTAB
+1));
389 rName
= aName
.makeStringAndClear();
394 void ScDocument::CreateValidTabNames(std::vector
<OUString
>& aNames
, SCTAB nCount
) const
396 aNames
.clear();//ensure that the vector is empty
399 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
400 OUString aStrTable
= rOpt
.GetInitTabPrefix();
402 OUStringBuffer rName
;
405 // First test if the prefix is valid, if so only avoid doubles
406 bool bPrefix
= ValidTabName( aStrTable
);
407 OSL_ENSURE(bPrefix
, "Invalid Table Name");
409 SCTAB i
= static_cast<SCTAB
>(maTabs
.size())+1;
411 for (SCTAB j
= 0; j
< nCount
; ++j
)
417 rName
.append(static_cast<sal_Int32
>(i
));
419 bOk
= ValidNewTabName( rName
.toString() );
421 bOk
= !GetTable( rName
.toString(), nDummy
);
424 aNames
.push_back(rName
.makeStringAndClear());
428 void ScDocument::AppendTabOnLoad(const OUString
& rName
)
430 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
431 if (!ValidTab(nTabCount
))
432 // max table count reached. No more tables.
435 OUString aName
= rName
;
436 CreateValidTabName(aName
);
437 maTabs
.push_back( new ScTable(this, nTabCount
, aName
) );
440 void ScDocument::SetTabNameOnLoad(SCTAB nTab
, const OUString
& rName
)
442 if (!ValidTab(nTab
) || static_cast<SCTAB
>(maTabs
.size()) <= nTab
)
445 if (!ValidTabName(rName
))
448 maTabs
[nTab
]->SetName(rName
);
451 void ScDocument::InvalidateStreamOnSave()
453 TableContainer::iterator it
= maTabs
.begin(), itEnd
= maTabs
.end();
454 for (; it
!= itEnd
; ++it
)
458 pTab
->SetStreamValid(false);
462 bool ScDocument::InsertTab( SCTAB nPos
, const OUString
& rName
,
463 bool bExternalDocument
)
465 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
466 bool bValid
= ValidTab(nTabCount
);
467 if ( !bExternalDocument
) // else test rName == "'Doc'!Tab" first
468 bValid
= (bValid
&& ValidNewTabName(rName
));
471 if (nPos
== SC_TAB_APPEND
|| nPos
>= nTabCount
)
473 maTabs
.push_back( new ScTable(this, nTabCount
, rName
) );
474 if ( bExternalDocument
)
475 maTabs
[nTabCount
]->SetVisible( false );
479 if (ValidTab(nPos
) && (nPos
< nTabCount
))
481 sc::RefUpdateInsertTabContext
aCxt(nPos
, 1);
483 ScRange
aRange( 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
);
484 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
485 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
487 pRangeName
->UpdateInsertTab(aCxt
);
488 pDBCollection
->UpdateReference(
489 URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
491 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
493 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,1 );
494 UpdateChartRef( URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
495 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,1 );
496 if ( pUnoBroadcaster
)
497 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,1 ) );
500 TableContainer::iterator it
= maTabs
.begin();
501 for (; it
!= maTabs
.end(); ++it
)
503 (*it
)->UpdateInsertTab(aCxt
);
504 maTabs
.push_back(NULL
);
505 for (i
= nTabCount
; i
> nPos
; i
--)
507 maTabs
[i
] = maTabs
[i
- 1];
510 maTabs
[nPos
] = new ScTable(this, nPos
, rName
);
512 // UpdateBroadcastAreas must be called between UpdateInsertTab,
513 // which ends listening, and StartAllListeners, to not modify
514 // areas that are to be inserted by starting listeners.
515 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,1);
517 for (; it
!= maTabs
.end(); ++it
)
519 (*it
)->UpdateCompile();
521 for (; it
!= maTabs
.end(); ++it
)
523 (*it
)->StartAllListeners();
526 pValidationList
->UpdateInsertTab(aCxt
);
528 // sheet names of references are not valid until sheet is inserted
529 if ( pChartListenerCollection
)
530 pChartListenerCollection
->UpdateScheduledSeriesRanges();
546 bool ScDocument::InsertTabs( SCTAB nPos
, const std::vector
<OUString
>& rNames
,
547 bool bExternalDocument
, bool bNamesValid
)
549 SCTAB nNewSheets
= static_cast<SCTAB
>(rNames
.size());
550 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
551 bool bValid
= bNamesValid
|| ValidTab(nTabCount
+nNewSheets
);
552 // if ( !bExternalDocument ) // else test rName == "'Doc'!Tab" first
553 // bValid = (bValid && ValidNewTabName(rNames));
556 if (nPos
== SC_TAB_APPEND
|| nPos
>= nTabCount
)
558 for ( SCTAB i
= 0; i
< nNewSheets
; ++i
)
560 maTabs
.push_back( new ScTable(this, nTabCount
+ i
, rNames
.at(i
)) );
561 if ( bExternalDocument
)
562 maTabs
[nTabCount
+i
]->SetVisible( false );
567 if (ValidTab(nPos
) && (nPos
< nTabCount
))
569 sc::RefUpdateInsertTabContext
aCxt(nPos
, nNewSheets
);
570 ScRange
aRange( 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
);
571 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,nNewSheets
);
572 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,nNewSheets
);
574 pRangeName
->UpdateInsertTab(aCxt
);
575 pDBCollection
->UpdateReference(
576 URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,nNewSheets
);
578 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,nNewSheets
);
580 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,nNewSheets
);
581 UpdateChartRef( URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,nNewSheets
);
582 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0, nNewSheets
);
583 if ( pUnoBroadcaster
)
584 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,nNewSheets
) );
586 TableContainer::iterator it
= maTabs
.begin();
587 for (; it
!= maTabs
.end(); ++it
)
589 (*it
)->UpdateInsertTab(aCxt
);
591 maTabs
.insert(it
+nPos
,nNewSheets
, NULL
);
592 for (SCTAB i
= 0; i
< nNewSheets
; ++i
)
594 maTabs
[nPos
+ i
] = new ScTable(this, nPos
+ i
, rNames
.at(i
));
597 // UpdateBroadcastAreas must be called between UpdateInsertTab,
598 // which ends listening, and StartAllListeners, to not modify
599 // areas that are to be inserted by starting listeners.
600 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,nNewSheets
);
602 for (; it
!= maTabs
.end(); ++it
)
605 (*it
)->UpdateCompile();
608 for (; it
!= maTabs
.end(); ++it
)
610 (*it
)->StartAllListeners();
613 pValidationList
->UpdateInsertTab(aCxt
);
615 // sheet names of references are not valid until sheet is inserted
616 if ( pChartListenerCollection
)
617 pChartListenerCollection
->UpdateScheduledSeriesRanges();
633 bool ScDocument::DeleteTab( SCTAB nTab
)
636 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
640 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
643 sc::AutoCalcSwitch
aACSwitch(*this, false);
644 sc::RefUpdateDeleteTabContext
aCxt(nTab
, 1);
646 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTab
);
647 DelBroadcastAreasInRange( aRange
);
649 // #i8180# remove database ranges etc. that are on the deleted tab
650 // (restored in undo with ScRefUndoData)
652 xColNameRanges
->DeleteOnTab( nTab
);
653 xRowNameRanges
->DeleteOnTab( nTab
);
654 pDBCollection
->DeleteOnTab( nTab
);
656 pDPCollection
->DeleteOnTab( nTab
);
658 pDetOpList
->DeleteOnTab( nTab
);
659 DeleteAreaLinksOnTab( nTab
);
661 // normal reference update
663 aRange
.aEnd
.SetTab( static_cast<SCTAB
>(maTabs
.size())-1 );
664 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
665 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
667 pRangeName
->UpdateDeleteTab(aCxt
);
668 pDBCollection
->UpdateReference(
669 URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
671 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
673 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,-1 );
674 UpdateChartRef( URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
675 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,-1 );
677 pValidationList
->UpdateDeleteTab(aCxt
);
678 if ( pUnoBroadcaster
)
679 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,-1 ) );
681 for (SCTAB i
= 0, n
= static_cast<SCTAB
>(maTabs
.size()); i
< n
; ++i
)
683 maTabs
[i
]->UpdateDeleteTab(aCxt
);
685 TableContainer::iterator it
= maTabs
.begin() + nTab
;
688 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
689 // which ends listening, and StartAllListeners, to not modify
690 // areas that are to be inserted by starting listeners.
691 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,-1);
693 for (; it
!= maTabs
.end(); ++it
)
695 (*it
)->UpdateCompile();
696 // Excel-Filter deletes some Tables while loading, Listeners will
697 // only be triggered after the loading is done.
698 if ( !bInsertingFromOtherDoc
)
701 for (; it
!= maTabs
.end(); ++it
)
703 (*it
)->StartAllListeners();
706 // sheet names of references are not valid until sheet is deleted
707 pChartListenerCollection
->UpdateScheduledSeriesRanges();
717 bool ScDocument::DeleteTabs( SCTAB nTab
, SCTAB nSheets
)
720 if (ValidTab(nTab
) && (nTab
+ nSheets
) < static_cast<SCTAB
>(maTabs
.size()))
724 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
725 if (nTabCount
> nSheets
)
727 sc::AutoCalcSwitch
aACSwitch(*this, false);
728 sc::RefUpdateDeleteTabContext
aCxt(nTab
, nSheets
);
730 for (SCTAB aTab
= 0; aTab
< nSheets
; ++aTab
)
732 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTab
+ aTab
);
733 DelBroadcastAreasInRange( aRange
);
735 // #i8180# remove database ranges etc. that are on the deleted tab
736 // (restored in undo with ScRefUndoData)
738 xColNameRanges
->DeleteOnTab( nTab
+ aTab
);
739 xRowNameRanges
->DeleteOnTab( nTab
+ aTab
);
740 pDBCollection
->DeleteOnTab( nTab
+ aTab
);
742 pDPCollection
->DeleteOnTab( nTab
+ aTab
);
744 pDetOpList
->DeleteOnTab( nTab
+ aTab
);
745 DeleteAreaLinksOnTab( nTab
+ aTab
);
749 pRangeName
->UpdateDeleteTab(aCxt
);
751 // normal reference update
753 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTabCount
- 1 );
754 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1*nSheets
);
755 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1*nSheets
);
756 pDBCollection
->UpdateReference(
757 URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1*nSheets
);
759 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
761 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
762 UpdateChartRef( URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1*nSheets
);
763 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
765 pValidationList
->UpdateDeleteTab(aCxt
);
766 if ( pUnoBroadcaster
)
767 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,-1*nSheets
) );
769 for (SCTAB i
= 0, n
= static_cast<SCTAB
>(maTabs
.size()); i
< n
; ++i
)
771 maTabs
[i
]->UpdateDeleteTab(aCxt
);
773 TableContainer::iterator it
= maTabs
.begin() + nTab
;
774 TableContainer::iterator itEnd
= it
+ nSheets
;
775 std::for_each(it
, itEnd
, ScDeleteObjectByPtr
<ScTable
>());
776 maTabs
.erase(it
, itEnd
);
777 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
778 // which ends listening, and StartAllListeners, to not modify
779 // areas that are to be inserted by starting listeners.
780 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
782 for (; it
!= maTabs
.end(); ++it
)
784 (*it
)->UpdateCompile();
785 // Excel-Filter deletes some Tables while loading, Listeners will
786 // only be triggered after the loading is done.
787 if ( !bInsertingFromOtherDoc
)
790 for (; it
!= maTabs
.end(); ++it
)
792 (*it
)->StartAllListeners();
795 // sheet names of references are not valid until sheet is deleted
796 pChartListenerCollection
->UpdateScheduledSeriesRanges();
806 bool ScDocument::RenameTab( SCTAB nTab
, const OUString
& rName
, bool /* bUpdateRef */,
807 bool bExternalDocument
)
815 if ( bExternalDocument
)
816 bValid
= true; // composed name
818 bValid
= ValidTabName(rName
);
819 for (i
=0; (i
< static_cast<SCTAB
>(maTabs
.size())) && bValid
; i
++)
820 if (maTabs
[i
] && (i
!= nTab
))
823 maTabs
[i
]->GetName(aOldName
);
824 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
828 // #i75258# update charts before renaming, so they can get their live data objects.
829 // Once the charts are live, the sheet can be renamed without problems.
830 if ( pChartListenerCollection
)
831 pChartListenerCollection
->UpdateChartsContainingTab( nTab
);
832 maTabs
[nTab
]->SetName(rName
);
834 // If formulas refer to the renamed sheet, the TokenArray remains valid,
835 // but the XML stream must be re-generated.
836 TableContainer::iterator it
= maTabs
.begin();
837 for (; it
!= maTabs
.end(); ++it
)
838 if ( *it
&& (*it
)->IsStreamValid())
839 (*it
)->SetStreamValid( false );
847 void ScDocument::SetVisible( SCTAB nTab
, bool bVisible
)
849 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
851 maTabs
[nTab
]->SetVisible(bVisible
);
855 bool ScDocument::IsVisible( SCTAB nTab
) const
857 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
859 return maTabs
[nTab
]->IsVisible();
865 bool ScDocument::IsStreamValid( SCTAB nTab
) const
867 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
868 return maTabs
[nTab
]->IsStreamValid();
874 void ScDocument::SetStreamValid( SCTAB nTab
, bool bSet
, bool bIgnoreLock
)
876 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
877 maTabs
[nTab
]->SetStreamValid( bSet
, bIgnoreLock
);
881 void ScDocument::LockStreamValid( bool bLock
)
883 mbStreamValidLocked
= bLock
;
887 bool ScDocument::IsPendingRowHeights( SCTAB nTab
) const
889 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
890 return maTabs
[nTab
]->IsPendingRowHeights();
896 void ScDocument::SetPendingRowHeights( SCTAB nTab
, bool bSet
)
898 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
899 maTabs
[nTab
]->SetPendingRowHeights( bSet
);
903 void ScDocument::SetLayoutRTL( SCTAB nTab
, bool bRTL
)
905 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
909 // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
910 // is applied in SetImportingXML(false). This is so the shapes can be loaded in
913 maTabs
[nTab
]->SetLoadingRTL( bRTL
);
917 maTabs
[nTab
]->SetLayoutRTL( bRTL
); // only sets the flag
918 maTabs
[nTab
]->SetDrawPageSize();
920 // mirror existing objects:
924 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
925 OSL_ENSURE(pPage
,"Page ?");
928 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
929 SdrObject
* pObject
= aIter
.Next();
932 // objects with ScDrawObjData are re-positioned in SetPageSize,
933 // don't mirror again
934 ScDrawObjData
* pData
= ScDrawLayer::GetObjData( pObject
);
936 pDrawLayer
->MirrorRTL( pObject
);
938 pObject
->SetContextWritingMode( bRTL
? WritingMode2::RL_TB
: WritingMode2::LR_TB
);
940 pObject
= aIter
.Next();
948 bool ScDocument::IsLayoutRTL( SCTAB nTab
) const
950 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
951 return maTabs
[nTab
]->IsLayoutRTL();
957 bool ScDocument::IsNegativePage( SCTAB nTab
) const
959 // Negative page area is always used for RTL layout.
960 // The separate method is used to find all RTL handling of drawing objects.
961 return IsLayoutRTL( nTab
);
965 /* ----------------------------------------------------------------------------
968 GetCellArea - Only Data
969 GetTableArea - Data / Attributes
970 GetPrintArea - intended for character objects,
971 sweeps attributes all the way to bottom / right
972 ---------------------------------------------------------------------------- */
975 bool ScDocument::GetCellArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
977 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
979 return maTabs
[nTab
]->GetCellArea( rEndCol
, rEndRow
);
987 bool ScDocument::GetTableArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
989 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
991 return maTabs
[nTab
]->GetTableArea( rEndCol
, rEndRow
);
998 bool ScDocument::ShrinkToDataArea(SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
1000 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
> (maTabs
.size()) || !maTabs
[nTab
])
1005 maTabs
[nTab
]->GetFirstDataPos(nCol1
, nRow1
);
1006 maTabs
[nTab
]->GetLastDataPos(nCol2
, nRow2
);
1008 if (nCol1
> nCol2
|| nRow1
> nRow2
)
1012 // Make sure the area only shrinks, and doesn't grow.
1013 if (rStartCol
< nCol1
)
1015 if (nCol2
< rEndCol
)
1017 if (rStartRow
< nRow1
)
1019 if (nRow2
< rEndRow
)
1022 if (rStartCol
> rEndCol
|| rStartRow
> rEndRow
)
1026 return true; // success!
1029 bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk
, SCTAB nTab
, SCCOL
& rStartCol
,
1030 SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
, bool bColumnsOnly
) const
1032 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
> (maTabs
.size()) || !maTabs
[nTab
])
1037 return maTabs
[nTab
]->ShrinkToUsedDataArea( o_bShrunk
, rStartCol
, rStartRow
, rEndCol
, rEndRow
, bColumnsOnly
);
1040 SCROW
ScDocument::GetLastDataRow( SCTAB nTab
, SCCOL nCol1
, SCCOL nCol2
, SCROW nLastRow
) const
1042 const ScTable
* pTab
= FetchTable(nTab
);
1046 return pTab
->GetLastDataRow(nCol1
, nCol2
, nLastRow
);
1051 void ScDocument::GetDataArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
1052 SCCOL
& rEndCol
, SCROW
& rEndRow
, bool bIncludeOld
, bool bOnlyDown
) const
1054 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
])
1055 maTabs
[nTab
]->GetDataArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
, bIncludeOld
, bOnlyDown
);
1059 void ScDocument::LimitChartArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
1060 SCCOL
& rEndCol
, SCROW
& rEndRow
)
1062 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
1064 maTabs
[nTab
]->LimitChartArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
);
1068 void ScDocument::LimitChartIfAll( ScRangeListRef
& rRangeList
)
1070 ScRangeListRef aNew
= new ScRangeList
;
1071 if (rRangeList
.Is())
1073 for ( size_t i
= 0, nCount
= rRangeList
->size(); i
< nCount
; i
++ )
1075 ScRange
aRange( *(*rRangeList
)[i
] );
1076 if ( ( aRange
.aStart
.Col() == 0 && aRange
.aEnd
.Col() == MAXCOL
) ||
1077 ( aRange
.aStart
.Row() == 0 && aRange
.aEnd
.Row() == MAXROW
) )
1079 SCCOL nStartCol
= aRange
.aStart
.Col();
1080 SCROW nStartRow
= aRange
.aStart
.Row();
1081 SCCOL nEndCol
= aRange
.aEnd
.Col();
1082 SCROW nEndRow
= aRange
.aEnd
.Row();
1083 SCTAB nTab
= aRange
.aStart
.Tab();
1084 if ( nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
])
1085 maTabs
[nTab
]->LimitChartArea(nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1086 aRange
.aStart
.SetCol( nStartCol
);
1087 aRange
.aStart
.SetRow( nStartRow
);
1088 aRange
.aEnd
.SetCol( nEndCol
);
1089 aRange
.aEnd
.SetRow( nEndRow
);
1091 aNew
->Append(aRange
);
1096 OSL_FAIL("LimitChartIfAll: Ref==0");
1102 static void lcl_GetFirstTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
, SCTAB aMaxTab
)
1104 // without ScMarkData, leave start/end unchanged
1107 for (SCTAB nTab
=0; nTab
< aMaxTab
; ++nTab
)
1108 if (pTabMark
->GetTableSelect(nTab
))
1110 // find first range of consecutive selected sheets
1111 rTabRangeStart
= pTabMark
->GetFirstSelected();
1112 while ( nTab
+1 < aMaxTab
&& pTabMark
->GetTableSelect(nTab
+1) )
1114 rTabRangeEnd
= nTab
;
1120 static bool lcl_GetNextTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
, SCTAB aMaxTab
)
1124 // find next range of consecutive selected sheets after rTabRangeEnd
1125 for (SCTAB nTab
=rTabRangeEnd
+1; nTab
< aMaxTab
; ++nTab
)
1126 if (pTabMark
->GetTableSelect(nTab
))
1128 rTabRangeStart
= nTab
;
1129 while ( nTab
+1 < aMaxTab
&& pTabMark
->GetTableSelect(nTab
+1) )
1131 rTabRangeEnd
= nTab
;
1139 bool ScDocument::CanInsertRow( const ScRange
& rRange
) const
1141 SCCOL nStartCol
= rRange
.aStart
.Col();
1142 SCROW nStartRow
= rRange
.aStart
.Row();
1143 SCTAB nStartTab
= rRange
.aStart
.Tab();
1144 SCCOL nEndCol
= rRange
.aEnd
.Col();
1145 SCROW nEndRow
= rRange
.aEnd
.Row();
1146 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1147 PutInOrder( nStartCol
, nEndCol
);
1148 PutInOrder( nStartRow
, nEndRow
);
1149 PutInOrder( nStartTab
, nEndTab
);
1150 SCSIZE nSize
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
1153 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1155 bTest
&= maTabs
[i
]->TestInsertRow( nStartCol
, nEndCol
, nStartRow
, nSize
);
1162 struct StartNeededListenersHandler
: std::unary_function
<ScTable
*, void>
1164 void operator() (ScTable
* p
)
1167 p
->StartNeededListeners();
1171 struct SetDirtyIfPostponedHandler
: std::unary_function
<ScTable
*, void>
1173 void operator() (ScTable
* p
)
1176 p
->SetDirtyIfPostponed();
1180 struct BroadcastRecalcOnRefMoveHandler
: std::unary_function
<ScTable
*, void>
1182 void operator() (ScTable
* p
)
1185 p
->BroadcastRecalcOnRefMove();
1191 bool ScDocument::InsertRow( SCCOL nStartCol
, SCTAB nStartTab
,
1192 SCCOL nEndCol
, SCTAB nEndTab
,
1193 SCROW nStartRow
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1194 const ScMarkData
* pTabMark
)
1198 PutInOrder( nStartCol
, nEndCol
);
1199 PutInOrder( nStartTab
, nEndTab
);
1203 nEndTab
= static_cast<SCTAB
>(maTabs
.size()) -1;
1208 bool bOldAutoCalc
= GetAutoCalc();
1209 SetAutoCalc( false ); // avoid mulitple calculations
1210 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1211 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1212 bTest
&= maTabs
[i
]->TestInsertRow(nStartCol
, nEndCol
, nStartRow
, nSize
);
1215 // UpdateBroadcastAreas have to be called before UpdateReference, so that entries
1216 // aren't shifted that would be rebuild at UpdateReference
1218 // handle chunks of consecutive selected sheets together
1219 SCTAB nTabRangeStart
= nStartTab
;
1220 SCTAB nTabRangeEnd
= nEndTab
;
1221 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1224 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1225 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1226 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, static_cast<SCsROW
>(nSize
), 0 );
1228 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1230 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1232 sc::RefUpdateContext
aCxt(*this);
1233 aCxt
.meMode
= URM_INSDEL
;
1234 aCxt
.maRange
= ScRange(nStartCol
, nStartRow
, nTabRangeStart
, nEndCol
, MAXROW
, nTabRangeEnd
);
1235 aCxt
.mnRowDelta
= nSize
;
1238 UpdateReference(aCxt
, pRefUndoDoc
, false); // without drawing objects
1240 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1242 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1243 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1244 maTabs
[i
]->InsertRow( nStartCol
, nEndCol
, nStartRow
, nSize
);
1246 // UpdateRef for drawing layer must be after inserting,
1247 // when the new row heights are known.
1248 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1249 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1250 maTabs
[i
]->UpdateDrawRef( URM_INSDEL
,
1251 nStartCol
, nStartRow
, nStartTab
, nEndCol
, MAXROW
, nEndTab
,
1252 0, static_cast<SCsROW
>(nSize
), 0 );
1254 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
1255 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
1256 // ein neues Listening faellig, bisherige Listener wurden in
1257 // FormulaCell UpdateReference abgehaengt
1258 StartAllListeners();
1261 { // Listeners have been removed in UpdateReference
1262 TableContainer::iterator it
= maTabs
.begin();
1263 for (; it
!= maTabs
.end(); ++it
)
1265 (*it
)->StartNeededListeners();
1266 // At least all cells using range names pointing relative to the
1267 // moved range must be recalculated, and all cells marked postponed
1269 it
= maTabs
.begin();
1270 for (; it
!= maTabs
.end(); ++it
)
1272 (*it
)->SetDirtyIfPostponed();
1274 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1278 SetAutoCalc( bOldAutoCalc
);
1280 pChartListenerCollection
->UpdateDirtyCharts();
1285 bool ScDocument::InsertRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
1287 return InsertRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
1288 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
1289 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
1294 void ScDocument::DeleteRow( SCCOL nStartCol
, SCTAB nStartTab
,
1295 SCCOL nEndCol
, SCTAB nEndTab
,
1296 SCROW nStartRow
, SCSIZE nSize
,
1297 ScDocument
* pRefUndoDoc
, bool* pUndoOutline
,
1298 const ScMarkData
* pTabMark
)
1302 PutInOrder( nStartCol
, nEndCol
);
1303 PutInOrder( nStartTab
, nEndTab
);
1307 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1310 bool bOldAutoCalc
= GetAutoCalc();
1311 SetAutoCalc( false ); // avoid multiple calculations
1313 // handle chunks of consecutive selected sheets together
1314 SCTAB nTabRangeStart
= nStartTab
;
1315 SCTAB nTabRangeEnd
= nEndTab
;
1316 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1319 if ( ValidRow(nStartRow
+nSize
) )
1321 DelBroadcastAreasInRange( ScRange(
1322 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1323 ScAddress( nEndCol
, nStartRow
+nSize
-1, nTabRangeEnd
) ) );
1324 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1325 ScAddress( nStartCol
, nStartRow
+nSize
, nTabRangeStart
),
1326 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, -(static_cast<SCsROW
>(nSize
)), 0 );
1329 DelBroadcastAreasInRange( ScRange(
1330 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1331 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
) ) );
1333 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1335 sc::RefUpdateContext
aCxt(*this);
1336 if ( ValidRow(nStartRow
+nSize
) )
1338 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1339 aCxt
.meMode
= URM_INSDEL
;
1340 aCxt
.maRange
= ScRange(nStartCol
, nStartRow
+nSize
, nTabRangeStart
, nEndCol
, MAXROW
, nTabRangeEnd
);
1341 aCxt
.mnRowDelta
= -(static_cast<SCROW
>(nSize
));
1344 UpdateReference(aCxt
, pRefUndoDoc
, true, false);
1346 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1350 *pUndoOutline
= false;
1352 for ( i
= nStartTab
; i
<= nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1353 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1354 maTabs
[i
]->DeleteRow(aCxt
.maRegroupCols
, nStartCol
, nEndCol
, nStartRow
, nSize
, pUndoOutline
);
1356 if ( ValidRow(nStartRow
+nSize
) )
1357 { // Listeners have been removed in UpdateReference
1358 TableContainer::iterator it
= maTabs
.begin();
1359 for (; it
!= maTabs
.end(); ++it
)
1361 (*it
)->StartNeededListeners();
1362 // At least all cells using range names pointing relative to the moved
1363 // range must be recalculated, and all cells marked postponed dirty.
1364 it
= maTabs
.begin();
1365 for (; it
!= maTabs
.end(); ++it
)
1367 (*it
)->SetDirtyIfPostponed();
1369 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1372 SetAutoCalc( bOldAutoCalc
);
1373 pChartListenerCollection
->UpdateDirtyCharts();
1377 void ScDocument::DeleteRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, bool* pUndoOutline
)
1379 DeleteRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
1380 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
1381 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
1382 pRefUndoDoc
, pUndoOutline
);
1386 bool ScDocument::CanInsertCol( const ScRange
& rRange
) const
1388 SCCOL nStartCol
= rRange
.aStart
.Col();
1389 SCROW nStartRow
= rRange
.aStart
.Row();
1390 SCTAB nStartTab
= rRange
.aStart
.Tab();
1391 SCCOL nEndCol
= rRange
.aEnd
.Col();
1392 SCROW nEndRow
= rRange
.aEnd
.Row();
1393 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1394 PutInOrder( nStartCol
, nEndCol
);
1395 PutInOrder( nStartRow
, nEndRow
);
1396 PutInOrder( nStartTab
, nEndTab
);
1397 SCSIZE nSize
= static_cast<SCSIZE
>(nEndCol
- nStartCol
+ 1);
1400 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1402 bTest
&= maTabs
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1407 bool ScDocument::InsertCol( SCROW nStartRow
, SCTAB nStartTab
,
1408 SCROW nEndRow
, SCTAB nEndTab
,
1409 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1410 const ScMarkData
* pTabMark
)
1414 PutInOrder( nStartRow
, nEndRow
);
1415 PutInOrder( nStartTab
, nEndTab
);
1419 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1424 bool bOldAutoCalc
= GetAutoCalc();
1425 SetAutoCalc( false ); // avoid multiple calculations
1426 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1427 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1428 bTest
&= maTabs
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1431 // handle chunks of consecutive selected sheets together
1432 SCTAB nTabRangeStart
= nStartTab
;
1433 SCTAB nTabRangeEnd
= nEndTab
;
1434 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1437 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1438 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1439 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), static_cast<SCsCOL
>(nSize
), 0, 0 );
1441 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1443 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1445 sc::RefUpdateContext
aCxt(*this);
1446 aCxt
.meMode
= URM_INSDEL
;
1447 aCxt
.maRange
= ScRange(nStartCol
, nStartRow
, nTabRangeStart
, MAXCOL
, nEndRow
, nTabRangeEnd
);
1448 aCxt
.mnColDelta
= nSize
;
1451 UpdateReference(aCxt
, pRefUndoDoc
, true, false);
1453 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1455 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1456 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1457 maTabs
[i
]->InsertCol(aCxt
.maRegroupCols
, nStartCol
, nStartRow
, nEndRow
, nSize
);
1459 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
1460 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
1461 // ein neues Listening faellig, bisherige Listener wurden in
1462 // FormulaCell UpdateReference abgehaengt
1463 StartAllListeners();
1467 // Listeners have been removed in UpdateReference
1468 std::for_each(maTabs
.begin(), maTabs
.end(), StartNeededListenersHandler());
1469 // At least all cells using range names pointing relative to the
1470 // moved range must be recalculated, and all cells marked postponed
1472 std::for_each(maTabs
.begin(), maTabs
.end(), SetDirtyIfPostponedHandler());
1473 // Cells containing functions such as CELL, COLUMN or ROW may have
1474 // changed their values on relocation. Broadcast them.
1475 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1479 SetAutoCalc( bOldAutoCalc
);
1481 pChartListenerCollection
->UpdateDirtyCharts();
1486 bool ScDocument::InsertCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
1488 return InsertCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1489 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1490 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1495 void ScDocument::DeleteCol(SCROW nStartRow
, SCTAB nStartTab
, SCROW nEndRow
, SCTAB nEndTab
,
1496 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1497 bool* pUndoOutline
, const ScMarkData
* pTabMark
)
1501 PutInOrder( nStartRow
, nEndRow
);
1502 PutInOrder( nStartTab
, nEndTab
);
1506 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1509 sc::AutoCalcSwitch
aACSwitch(*this, false); // avoid multiple calculations
1511 // handle chunks of consecutive selected sheets together
1512 SCTAB nTabRangeStart
= nStartTab
;
1513 SCTAB nTabRangeEnd
= nEndTab
;
1514 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1517 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1519 DelBroadcastAreasInRange( ScRange(
1520 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1521 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
-1), nEndRow
, nTabRangeEnd
) ) );
1522 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1523 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
),
1524 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), -static_cast<SCsCOL
>(nSize
), 0, 0 );
1527 DelBroadcastAreasInRange( ScRange(
1528 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1529 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
) ) );
1531 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1533 sc::RefUpdateContext
aCxt(*this);
1534 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1536 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1537 aCxt
.meMode
= URM_INSDEL
;
1538 aCxt
.maRange
= ScRange(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
, MAXCOL
, nEndRow
, nTabRangeEnd
);
1539 aCxt
.mnColDelta
= -(static_cast<SCCOL
>(nSize
));
1542 UpdateReference(aCxt
, pRefUndoDoc
, true, false);
1544 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1548 *pUndoOutline
= false;
1550 for (i
= nStartTab
; i
<= nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); ++i
)
1552 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1553 maTabs
[i
]->DeleteCol(aCxt
.maRegroupCols
, nStartCol
, nStartRow
, nEndRow
, nSize
, pUndoOutline
);
1556 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1557 {// Listeners have been removed in UpdateReference
1558 TableContainer::iterator it
= maTabs
.begin();
1559 for (; it
!= maTabs
.end(); ++it
)
1561 (*it
)->StartNeededListeners();
1562 // At least all cells using range names pointing relative to the moved
1563 // range must be recalculated, and all cells marked postponed dirty.
1564 it
= maTabs
.begin();
1565 for (; it
!= maTabs
.end(); ++it
)
1567 (*it
)->SetDirtyIfPostponed();
1569 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1572 pChartListenerCollection
->UpdateDirtyCharts();
1576 void ScDocument::DeleteCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, bool* pUndoOutline
)
1578 DeleteCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1579 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1580 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1581 pRefUndoDoc
, pUndoOutline
);
1585 // fuer Area-Links: Zellen einuegen/loeschen, wenn sich der Bereich veraendert
1589 static void lcl_GetInsDelRanges( const ScRange
& rOld
, const ScRange
& rNew
,
1590 ScRange
& rColRange
, bool& rInsCol
, bool& rDelCol
,
1591 ScRange
& rRowRange
, bool& rInsRow
, bool& rDelRow
)
1593 OSL_ENSURE( rOld
.aStart
== rNew
.aStart
, "FitBlock: Beginning is different" );
1595 rInsCol
= rDelCol
= rInsRow
= rDelRow
= false;
1597 SCCOL nStartX
= rOld
.aStart
.Col();
1598 SCROW nStartY
= rOld
.aStart
.Row();
1599 SCCOL nOldEndX
= rOld
.aEnd
.Col();
1600 SCROW nOldEndY
= rOld
.aEnd
.Row();
1601 SCCOL nNewEndX
= rNew
.aEnd
.Col();
1602 SCROW nNewEndY
= rNew
.aEnd
.Row();
1603 SCTAB nTab
= rOld
.aStart
.Tab();
1605 // wenn es mehr Zeilen werden, werden Spalten auf der alten Hoehe eingefuegt/geloescht
1606 bool bGrowY
= ( nNewEndY
> nOldEndY
);
1607 SCROW nColEndY
= bGrowY
? nOldEndY
: nNewEndY
;
1608 SCCOL nRowEndX
= bGrowY
? nNewEndX
: nOldEndX
;
1612 if ( nNewEndX
> nOldEndX
) // Spalten einfuegen
1614 rColRange
= ScRange( nOldEndX
+1, nStartY
, nTab
, nNewEndX
, nColEndY
, nTab
);
1617 else if ( nNewEndX
< nOldEndX
) // Spalten loeschen
1619 rColRange
= ScRange( nNewEndX
+1, nStartY
, nTab
, nOldEndX
, nColEndY
, nTab
);
1625 if ( nNewEndY
> nOldEndY
) // Zeilen einfuegen
1627 rRowRange
= ScRange( nStartX
, nOldEndY
+1, nTab
, nRowEndX
, nNewEndY
, nTab
);
1630 else if ( nNewEndY
< nOldEndY
) // Zeilen loeschen
1632 rRowRange
= ScRange( nStartX
, nNewEndY
+1, nTab
, nRowEndX
, nOldEndY
, nTab
);
1638 bool ScDocument::HasPartOfMerged( const ScRange
& rRange
)
1641 SCTAB nTab
= rRange
.aStart
.Tab();
1643 SCCOL nStartX
= rRange
.aStart
.Col();
1644 SCROW nStartY
= rRange
.aStart
.Row();
1645 SCCOL nEndX
= rRange
.aEnd
.Col();
1646 SCROW nEndY
= rRange
.aEnd
.Row();
1648 if (HasAttrib( nStartX
, nStartY
, nTab
, nEndX
, nEndY
, nTab
,
1649 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
1651 ExtendMerge( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1652 ExtendOverlapped( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1654 bPart
= ( nStartX
!= rRange
.aStart
.Col() || nEndX
!= rRange
.aEnd
.Col() ||
1655 nStartY
!= rRange
.aStart
.Row() || nEndY
!= rRange
.aEnd
.Row() );
1660 size_t ScDocument::GetFormulaHash( const ScAddress
& rPos
) const
1662 SCTAB nTab
= rPos
.Tab();
1663 if (!ValidTab(nTab
) || static_cast<size_t>(nTab
) >= maTabs
.size() || !maTabs
[nTab
])
1666 return maTabs
[nTab
]->GetFormulaHash(rPos
.Col(), rPos
.Row());
1669 ScFormulaVectorState
ScDocument::GetFormulaVectorState( const ScAddress
& rPos
) const
1671 SCTAB nTab
= rPos
.Tab();
1672 if (!ValidTab(nTab
) || static_cast<size_t>(nTab
) >= maTabs
.size() || !maTabs
[nTab
])
1673 return FormulaVectorUnknown
;
1675 return maTabs
[nTab
]->GetFormulaVectorState(rPos
.Col(), rPos
.Row());
1678 formula::FormulaTokenRef
ScDocument::ResolveStaticReference( const ScAddress
& rPos
)
1680 SCTAB nTab
= rPos
.Tab();
1681 if (!TableExists(nTab
))
1682 return formula::FormulaTokenRef();
1684 return maTabs
[nTab
]->ResolveStaticReference(rPos
.Col(), rPos
.Row());
1687 formula::FormulaTokenRef
ScDocument::ResolveStaticReference( const ScRange
& rRange
)
1689 SCTAB nTab
= rRange
.aStart
.Tab();
1690 if (nTab
!= rRange
.aEnd
.Tab() || !TableExists(nTab
))
1691 return formula::FormulaTokenRef();
1693 return maTabs
[nTab
]->ResolveStaticReference(
1694 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
1697 formula::VectorRefArray
ScDocument::FetchVectorRefArray( const ScAddress
& rPos
, SCROW nLength
)
1699 SCTAB nTab
= rPos
.Tab();
1700 if (!TableExists(nTab
))
1701 return formula::VectorRefArray();
1703 return maTabs
[nTab
]->FetchVectorRefArray(rPos
.Col(), rPos
.Row(), rPos
.Row()+nLength
-1);
1706 bool ScDocument::CanFitBlock( const ScRange
& rOld
, const ScRange
& rNew
)
1712 bool bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1713 ScRange aColRange
,aRowRange
;
1714 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1716 if ( bInsCol
&& !CanInsertCol( aColRange
) ) // Zellen am Rand ?
1718 if ( bInsRow
&& !CanInsertRow( aRowRange
) ) // Zellen am Rand ?
1721 if ( bInsCol
|| bDelCol
)
1723 aColRange
.aEnd
.SetCol(MAXCOL
);
1724 if ( HasPartOfMerged(aColRange
) )
1727 if ( bInsRow
|| bDelRow
)
1729 aRowRange
.aEnd
.SetRow(MAXROW
);
1730 if ( HasPartOfMerged(aRowRange
) )
1738 void ScDocument::FitBlock( const ScRange
& rOld
, const ScRange
& rNew
, bool bClear
)
1741 DeleteAreaTab( rOld
, IDF_ALL
);
1743 bool bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1744 ScRange aColRange
,aRowRange
;
1745 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1748 InsertCol( aColRange
); // Spalten zuerst einfuegen
1750 InsertRow( aRowRange
);
1753 DeleteRow( aRowRange
); // Zeilen zuerst loeschen
1755 DeleteCol( aColRange
);
1757 // Referenzen um eingefuegte Zeilen erweitern
1759 if ( bInsCol
|| bInsRow
)
1761 ScRange aGrowSource
= rOld
;
1762 aGrowSource
.aEnd
.SetCol(std::min( rOld
.aEnd
.Col(), rNew
.aEnd
.Col() ));
1763 aGrowSource
.aEnd
.SetRow(std::min( rOld
.aEnd
.Row(), rNew
.aEnd
.Row() ));
1764 SCCOL nGrowX
= bInsCol
? ( rNew
.aEnd
.Col() - rOld
.aEnd
.Col() ) : 0;
1765 SCROW nGrowY
= bInsRow
? ( rNew
.aEnd
.Row() - rOld
.aEnd
.Row() ) : 0;
1766 UpdateGrow( aGrowSource
, nGrowX
, nGrowY
);
1771 void ScDocument::DeleteArea(SCCOL nCol1
, SCROW nRow1
,
1772 SCCOL nCol2
, SCROW nRow2
,
1773 const ScMarkData
& rMark
, sal_uInt16 nDelFlag
)
1775 PutInOrder( nCol1
, nCol2
);
1776 PutInOrder( nRow1
, nRow2
);
1777 bool bOldAutoCalc
= GetAutoCalc();
1778 SetAutoCalc( false ); // avoid multiple calculations
1779 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1781 if ( rMark
.GetTableSelect(i
) || bIsUndo
)
1782 maTabs
[i
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1783 SetAutoCalc( bOldAutoCalc
);
1787 void ScDocument::DeleteAreaTab(SCCOL nCol1
, SCROW nRow1
,
1788 SCCOL nCol2
, SCROW nRow2
,
1789 SCTAB nTab
, sal_uInt16 nDelFlag
)
1791 PutInOrder( nCol1
, nCol2
);
1792 PutInOrder( nRow1
, nRow2
);
1793 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1795 bool bOldAutoCalc
= GetAutoCalc();
1796 SetAutoCalc( false ); // avoid multiple calculations
1797 maTabs
[nTab
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1798 SetAutoCalc( bOldAutoCalc
);
1803 void ScDocument::DeleteAreaTab( const ScRange
& rRange
, sal_uInt16 nDelFlag
)
1805 for ( SCTAB nTab
= rRange
.aStart
.Tab(); nTab
<= rRange
.aEnd
.Tab(); nTab
++ )
1806 DeleteAreaTab( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
1807 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
1812 void ScDocument::InitUndoSelected( ScDocument
* pSrcDoc
, const ScMarkData
& rTabSelection
,
1813 bool bColInfo
, bool bRowInfo
)
1819 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1823 for (SCTAB nTab
= 0; nTab
<= rTabSelection
.GetLastSelected(); nTab
++)
1824 if ( rTabSelection
.GetTableSelect( nTab
) )
1826 ScTable
* pTable
= new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1827 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1828 maTabs
[nTab
] = pTable
;
1830 maTabs
.push_back(pTable
);
1834 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1837 maTabs
.push_back(NULL
);
1842 OSL_FAIL("InitUndo");
1847 void ScDocument::InitUndo( ScDocument
* pSrcDoc
, SCTAB nTab1
, SCTAB nTab2
,
1848 bool bColInfo
, bool bRowInfo
)
1854 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1855 if (pSrcDoc
->pShell
->GetMedium())
1856 maFileURL
= pSrcDoc
->pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
1859 if ( nTab2
>= static_cast<SCTAB
>(maTabs
.size()))
1860 maTabs
.resize(nTab2
+ 1, NULL
);
1861 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1863 ScTable
* pTable
= new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1864 maTabs
[nTab
] = pTable
;
1869 OSL_FAIL("InitUndo");
1874 void ScDocument::AddUndoTab( SCTAB nTab1
, SCTAB nTab2
, bool bColInfo
, bool bRowInfo
)
1879 if (nTab2
>= static_cast<SCTAB
>(maTabs
.size()))
1881 maTabs
.resize(nTab2
+1,NULL
);
1883 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1886 maTabs
[nTab
] = new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1892 OSL_FAIL("InitUndo");
1897 void ScDocument::SetCutMode( bool bVal
)
1900 GetClipParam().mbCutMode
= bVal
;
1903 OSL_FAIL("SetCutMode without bIsClip");
1908 bool ScDocument::IsCutMode()
1911 return GetClipParam().mbCutMode
;
1914 OSL_FAIL("IsCutMode without bIsClip");
1920 void ScDocument::CopyToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1921 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1922 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1923 const ScMarkData
* pMarks
, bool bColRowFlags
)
1925 PutInOrder( nCol1
, nCol2
);
1926 PutInOrder( nRow1
, nRow2
);
1927 PutInOrder( nTab1
, nTab2
);
1928 if( pDestDoc
->aDocName
.isEmpty() )
1929 pDestDoc
->aDocName
= aDocName
;
1930 if (ValidTab(nTab1
) && ValidTab(nTab2
))
1932 sc::CopyToDocContext
aCxt(*pDestDoc
);
1933 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1934 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1935 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
1936 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
1938 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
1939 maTabs
[i
]->CopyToTable(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1940 bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
,
1941 false, bColRowFlags
);
1943 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1948 void ScDocument::UndoToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1949 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1950 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1951 const ScMarkData
* pMarks
)
1953 PutInOrder( nCol1
, nCol2
);
1954 PutInOrder( nRow1
, nRow2
);
1955 PutInOrder( nTab1
, nTab2
);
1956 if (ValidTab(nTab1
) && ValidTab(nTab2
))
1958 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1959 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1961 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, false, pDestDoc
, pMarks
);
1963 sc::CopyToDocContext
aCxt(*pDestDoc
);
1964 OSL_ASSERT( nTab2
< static_cast<SCTAB
>(maTabs
.size()) && nTab2
< static_cast<SCTAB
>(pDestDoc
->maTabs
.size()));
1965 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
1967 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
1968 maTabs
[i
]->UndoToTable(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1969 bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
);
1973 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
, false, pDestDoc
, pMarks
);
1974 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1979 void ScDocument::CopyToDocument(const ScRange
& rRange
,
1980 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1981 const ScMarkData
* pMarks
, bool bColRowFlags
)
1983 ScRange aNewRange
= rRange
;
1984 aNewRange
.Justify();
1986 if( pDestDoc
->aDocName
.isEmpty() )
1987 pDestDoc
->aDocName
= aDocName
;
1988 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1989 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1990 sc::CopyToDocContext
aCxt(*pDestDoc
);
1991 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
1992 for (SCTAB i
= aNewRange
.aStart
.Tab(); i
<= aNewRange
.aEnd
.Tab() && i
< nMinSizeBothTabs
; i
++)
1994 if (!TableExists(i
) || !pDestDoc
->TableExists(i
))
1997 maTabs
[i
]->CopyToTable(aCxt
, aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
1998 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
1999 nFlags
, bOnlyMarked
, pDestDoc
->maTabs
[i
],
2000 pMarks
, false, bColRowFlags
);
2002 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
2006 void ScDocument::UndoToDocument(const ScRange
& rRange
,
2007 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
2008 const ScMarkData
* pMarks
)
2010 sc::AutoCalcSwitch
aAutoCalcSwitch(*this, false);
2012 ScRange aNewRange
= rRange
;
2013 aNewRange
.Justify();
2014 SCTAB nTab1
= aNewRange
.aStart
.Tab();
2015 SCTAB nTab2
= aNewRange
.aEnd
.Tab();
2017 sc::CopyToDocContext
aCxt(*pDestDoc
);
2019 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, false, pDestDoc
, pMarks
);
2021 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
2022 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
2024 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
2025 maTabs
[i
]->UndoToTable(aCxt
, aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
2026 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
2027 nFlags
, bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
);
2030 if (nTab2
< static_cast<SCTAB
>(maTabs
.size()))
2031 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,maTabs
.size(), IDF_FORMULA
, false, pDestDoc
, pMarks
);
2034 // bUseRangeForVBA added for VBA api support to allow content of a specified
2035 // range to be copied ( e.g. don't use marked data but the just the range
2036 // specified by rClipParam
2037 void ScDocument::CopyToClip(const ScClipParam
& rClipParam
,
2038 ScDocument
* pClipDoc
, const ScMarkData
* pMarks
,
2039 bool bAllTabs
, bool bKeepScenarioFlags
, bool bIncludeObjects
, bool bCloneNoteCaptions
, bool bUseRangeForVBA
)
2041 OSL_ENSURE( !bUseRangeForVBA
&& ( bAllTabs
|| pMarks
), "CopyToClip: ScMarkData fails" );
2048 OSL_TRACE("CopyToClip: no ClipDoc");
2049 pClipDoc
= SC_MOD()->GetClipDoc();
2052 if (pShell
->GetMedium())
2054 pClipDoc
->maFileURL
= pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
2055 // for unsaved files use the title name and adjust during save of file
2056 if (pClipDoc
->maFileURL
.isEmpty())
2057 pClipDoc
->maFileURL
= pShell
->GetName();
2061 pClipDoc
->maFileURL
= pShell
->GetName();
2065 for (TableContainer::iterator itr
= maTabs
.begin(); itr
!= maTabs
.end(); ++itr
)
2070 (*itr
)->GetName(aTabName
);
2071 pClipDoc
->maTabNames
.push_back(aTabName
);
2074 pClipDoc
->maTabNames
.push_back(OUString());
2077 pClipDoc
->aDocName
= aDocName
;
2078 pClipDoc
->SetClipParam(rClipParam
);
2079 ScRange aClipRange
= rClipParam
.getWholeRange();
2080 SCTAB nTab
= aClipRange
.aStart
.Tab();
2082 SCTAB nEndTab
= static_cast<SCTAB
>(maTabs
.size());
2084 if ( bUseRangeForVBA
)
2086 pClipDoc
->ResetClip( this, nTab
);
2091 pClipDoc
->ResetClip(this, pMarks
);
2093 sc::CopyToClipContext
aCxt(*pClipDoc
, bKeepScenarioFlags
, bCloneNoteCaptions
);
2094 CopyRangeNamesToClip(pClipDoc
, aClipRange
, pMarks
, bAllTabs
);
2096 for ( ; i
< nEndTab
; ++i
)
2098 if (!maTabs
[i
] || i
>= static_cast<SCTAB
>(pClipDoc
->maTabs
.size()) || !pClipDoc
->maTabs
[i
])
2101 if ( !bUseRangeForVBA
&& ( pMarks
&& !pMarks
->GetTableSelect(i
) ) )
2104 maTabs
[i
]->CopyToClip(aCxt
, rClipParam
.maRanges
, pClipDoc
->maTabs
[i
]);
2106 if (pDrawLayer
&& bIncludeObjects
)
2108 // also copy drawing objects
2109 Rectangle aObjRect
= GetMMRect(
2110 aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(), aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
2111 pDrawLayer
->CopyToClip(pClipDoc
, i
, aObjRect
);
2115 // Make sure to mark overlapped cells.
2116 pClipDoc
->ExtendMerge(aClipRange
, true);
2119 void ScDocument::CopyStaticToDocument(const ScRange
& rSrcRange
, SCTAB nDestTab
, ScDocument
* pDestDoc
)
2124 ScTable
* pSrcTab
= rSrcRange
.aStart
.Tab() < static_cast<SCTAB
>(maTabs
.size()) ? maTabs
[rSrcRange
.aStart
.Tab()] : NULL
;
2125 ScTable
* pDestTab
= nDestTab
< static_cast<SCTAB
>(pDestDoc
->maTabs
.size()) ? pDestDoc
->maTabs
[nDestTab
] : NULL
;
2127 if (!pSrcTab
|| !pDestTab
)
2130 pSrcTab
->CopyStaticToDocument(
2131 rSrcRange
.aStart
.Col(), rSrcRange
.aStart
.Row(), rSrcRange
.aEnd
.Col(), rSrcRange
.aEnd
.Row(), pDestTab
);
2134 void ScDocument::CopyCellToDocument( const ScAddress
& rSrcPos
, const ScAddress
& rDestPos
, ScDocument
& rDestDoc
)
2136 if (!TableExists(rSrcPos
.Tab()) || !rDestDoc
.TableExists(rDestPos
.Tab()))
2139 ScTable
& rSrcTab
= *maTabs
[rSrcPos
.Tab()];
2140 ScTable
& rDestTab
= *rDestDoc
.maTabs
[rDestPos
.Tab()];
2142 rSrcTab
.CopyCellToDocument(rSrcPos
.Col(), rSrcPos
.Row(), rDestPos
.Col(), rDestPos
.Row(), rDestTab
);
2145 void ScDocument::CopyTabToClip(SCCOL nCol1
, SCROW nRow1
,
2146 SCCOL nCol2
, SCROW nRow2
,
2147 SCTAB nTab
, ScDocument
* pClipDoc
)
2151 if (pShell
->GetMedium())
2153 pClipDoc
->maFileURL
= pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
2154 // for unsaved files use the title name and adjust during save of file
2155 if (pClipDoc
->maFileURL
.isEmpty())
2156 pClipDoc
->maFileURL
= pShell
->GetName();
2160 pClipDoc
->maFileURL
= pShell
->GetName();
2164 for (TableContainer::iterator itr
= maTabs
.begin(); itr
!= maTabs
.end(); ++itr
)
2169 (*itr
)->GetName(aTabName
);
2170 pClipDoc
->maTabNames
.push_back(aTabName
);
2173 pClipDoc
->maTabNames
.push_back(OUString());
2176 PutInOrder( nCol1
, nCol2
);
2177 PutInOrder( nRow1
, nRow2
);
2180 OSL_TRACE("CopyTabToClip: no ClipDoc");
2181 pClipDoc
= SC_MOD()->GetClipDoc();
2184 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
2185 pClipDoc
->aDocName
= aDocName
;
2186 rClipParam
.maRanges
.RemoveAll();
2187 rClipParam
.maRanges
.Append(ScRange(nCol1
, nRow1
, 0, nCol2
, nRow2
, 0));
2188 pClipDoc
->ResetClip( this, nTab
);
2190 sc::CopyToClipContext
aCxt(*pClipDoc
, false, true);
2191 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && nTab
< static_cast<SCTAB
>(pClipDoc
->maTabs
.size()))
2192 if (maTabs
[nTab
] && pClipDoc
->maTabs
[nTab
])
2193 maTabs
[nTab
]->CopyToClip(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, pClipDoc
->maTabs
[nTab
]);
2195 pClipDoc
->GetClipParam().mbCutMode
= false;
2200 void ScDocument::TransposeClip( ScDocument
* pTransClip
, sal_uInt16 nFlags
, bool bAsLink
)
2202 OSL_ENSURE( bIsClip
&& pTransClip
&& pTransClip
->bIsClip
,
2203 "TransposeClip with wrong Document" );
2206 // -> pTransClip muss vor dem Original-Dokument geloescht werden!
2208 pTransClip
->ResetClip(this, (ScMarkData
*)NULL
); // alle
2210 // Bereiche uebernehmen
2214 pTransClip
->GetRangeName()->clear();
2215 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
2216 for (; itr
!= itrEnd
; ++itr
)
2218 sal_uInt16 nIndex
= itr
->second
->GetIndex();
2219 ScRangeData
* pData
= new ScRangeData(*itr
->second
);
2220 if (pTransClip
->pRangeName
->insert(pData
))
2221 pData
->SetIndex(nIndex
);
2227 ScRange aClipRange
= GetClipParam().getWholeRange();
2228 if ( ValidRow(aClipRange
.aEnd
.Row()-aClipRange
.aStart
.Row()) )
2230 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2233 OSL_ENSURE( pTransClip
->maTabs
[i
], "TransposeClip: Table not there" );
2234 maTabs
[i
]->TransposeClip( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
2235 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(),
2236 pTransClip
->maTabs
[i
], nFlags
, bAsLink
);
2238 if ( pDrawLayer
&& ( nFlags
& IDF_OBJECTS
) )
2240 // Drawing objects are copied to the new area without transposing.
2241 // CopyFromClip is used to adjust the objects to the transposed block's
2243 // (pDrawLayer in the original clipboard document is set only if there
2244 // are drawing objects to copy)
2246 pTransClip
->InitDrawLayer();
2247 Rectangle aSourceRect
= GetMMRect( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
2248 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
2249 Rectangle aDestRect
= pTransClip
->GetMMRect( 0, 0,
2250 static_cast<SCCOL
>(aClipRange
.aEnd
.Row() - aClipRange
.aStart
.Row()),
2251 static_cast<SCROW
>(aClipRange
.aEnd
.Col() - aClipRange
.aStart
.Col()), i
);
2252 pTransClip
->pDrawLayer
->CopyFromClip( pDrawLayer
, i
, aSourceRect
, ScAddress(0,0,i
), aDestRect
);
2256 pTransClip
->SetClipParam(GetClipParam());
2257 pTransClip
->GetClipParam().transpose();
2261 OSL_TRACE("TransposeClip: Too big");
2264 // Dies passiert erst beim Einfuegen...
2266 GetClipParam().mbCutMode
= false;
2271 void copyUsedNamesToClip(ScRangeName
* pClipRangeName
, ScRangeName
* pRangeName
, const std::set
<sal_uInt16
>& rUsedNames
)
2273 pClipRangeName
->clear();
2274 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
2275 for (; itr
!= itrEnd
; ++itr
) //! DB-Bereiche Pivot-Bereiche auch !!!
2277 sal_uInt16 nIndex
= itr
->second
->GetIndex();
2278 bool bInUse
= (rUsedNames
.count(nIndex
) > 0);
2282 ScRangeData
* pData
= new ScRangeData(*itr
->second
);
2283 if (pClipRangeName
->insert(pData
))
2284 pData
->SetIndex(nIndex
);
2290 void ScDocument::CopyRangeNamesToClip(ScDocument
* pClipDoc
, const ScRange
& rClipRange
, const ScMarkData
* pMarks
, bool bAllTabs
)
2292 if (!pRangeName
|| pRangeName
->empty())
2295 std::set
<sal_uInt16
> aUsedNames
; // indexes of named ranges that are used in the copied cells
2296 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pClipDoc
->maTabs
.size()));
2297 for (SCTAB i
= 0; i
< nMinSizeBothTabs
; ++i
)
2298 if (maTabs
[i
] && pClipDoc
->maTabs
[i
])
2299 if ( bAllTabs
|| !pMarks
|| pMarks
->GetTableSelect(i
) )
2300 maTabs
[i
]->FindRangeNamesInUse(
2301 rClipRange
.aStart
.Col(), rClipRange
.aStart
.Row(),
2302 rClipRange
.aEnd
.Col(), rClipRange
.aEnd
.Row(), aUsedNames
);
2304 copyUsedNamesToClip(pClipDoc
->GetRangeName(), pRangeName
, aUsedNames
);
2307 ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument
* pDoc
, ScDocument
* pSrcDoc
) :
2310 mpDoc
->MergeNumberFormatter(pSrcDoc
);
2313 ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
2315 mpDoc
->pFormatExchangeList
= NULL
;
2318 void ScDocument::CellContentModified()
2320 mpFormulaGroupCxt
.reset();
2323 SvtBroadcaster
* ScDocument::GetBroadcaster( const ScAddress
& rPos
)
2325 ScTable
* pTab
= FetchTable(rPos
.Tab());
2329 return pTab
->GetBroadcaster(rPos
.Col(), rPos
.Row());
2332 const SvtBroadcaster
* ScDocument::GetBroadcaster( const ScAddress
& rPos
) const
2334 const ScTable
* pTab
= FetchTable(rPos
.Tab());
2338 return pTab
->GetBroadcaster(rPos
.Col(), rPos
.Row());
2341 void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition
& rBlockPos
, const ScAddress
& rTopPos
, SCROW nLength
)
2343 ScTable
* pTab
= FetchTable(rTopPos
.Tab());
2344 if (!pTab
|| nLength
<= 0)
2347 pTab
->DeleteBroadcasters(rBlockPos
, rTopPos
.Col(), rTopPos
.Row(), rTopPos
.Row()+nLength
-1);
2350 bool ScDocument::HasBroadcaster( SCTAB nTab
, SCCOL nCol
) const
2352 const ScTable
* pTab
= FetchTable(nTab
);
2356 return pTab
->HasBroadcaster(nCol
);
2359 #if DEBUG_COLUMN_STORAGE
2360 void ScDocument::DumpFormulaGroups( SCTAB nTab
, SCCOL nCol
) const
2362 const ScTable
* pTab
= FetchTable(nTab
);
2366 pTab
->DumpFormulaGroups(nCol
);
2370 bool ScDocument::TableExists( SCTAB nTab
) const
2372 return ValidTab(nTab
) && static_cast<size_t>(nTab
) < maTabs
.size() && maTabs
[nTab
];
2375 ScTable
* ScDocument::FetchTable( SCTAB nTab
)
2377 if (!TableExists(nTab
))
2380 return maTabs
[nTab
];
2383 const ScTable
* ScDocument::FetchTable( SCTAB nTab
) const
2385 if (!TableExists(nTab
))
2388 return maTabs
[nTab
];
2391 void ScDocument::MergeNumberFormatter(ScDocument
* pSrcDoc
)
2393 SvNumberFormatter
* pThisFormatter
= xPoolHelper
->GetFormTable();
2394 SvNumberFormatter
* pOtherFormatter
= pSrcDoc
->xPoolHelper
->GetFormTable();
2395 if (pOtherFormatter
&& pOtherFormatter
!= pThisFormatter
)
2397 SvNumberFormatterIndexTable
* pExchangeList
=
2398 pThisFormatter
->MergeFormatter(*(pOtherFormatter
));
2399 if (!pExchangeList
->empty())
2400 pFormatExchangeList
= pExchangeList
;
2404 ScClipParam
& ScDocument::GetClipParam()
2406 if (!mpClipParam
.get())
2407 mpClipParam
.reset(new ScClipParam
);
2409 return *mpClipParam
;
2412 void ScDocument::SetClipParam(const ScClipParam
& rParam
)
2414 mpClipParam
.reset(new ScClipParam(rParam
));
2417 bool ScDocument::IsClipboardSource() const
2419 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
2420 return pClipDoc
&& pClipDoc
->xPoolHelper
.is() &&
2421 xPoolHelper
->GetDocPool() == pClipDoc
->xPoolHelper
->GetDocPool();
2425 void ScDocument::StartListeningFromClip( SCCOL nCol1
, SCROW nRow1
,
2426 SCCOL nCol2
, SCROW nRow2
,
2427 const ScMarkData
& rMark
, sal_uInt16 nInsFlag
)
2429 if (nInsFlag
& IDF_CONTENTS
)
2431 sc::StartListeningContext
aCxt(*this);
2432 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
2433 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2434 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
2436 maTabs
[*itr
]->StartListeningInArea(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
);
2441 void ScDocument::BroadcastFromClip( SCCOL nCol1
, SCROW nRow1
,
2442 SCCOL nCol2
, SCROW nRow2
,
2443 const ScMarkData
& rMark
, sal_uInt16 nInsFlag
)
2445 if (nInsFlag
& IDF_CONTENTS
)
2447 ScBulkBroadcast
aBulkBroadcast( GetBASM());
2448 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
2449 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2450 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
2452 maTabs
[*itr
]->BroadcastInArea( nCol1
, nRow1
, nCol2
, nRow2
);
2456 bool ScDocument::InitColumnBlockPosition( sc::ColumnBlockPosition
& rBlockPos
, SCTAB nTab
, SCCOL nCol
)
2458 if (!TableExists(nTab
))
2461 return maTabs
[nTab
]->InitColumnBlockPosition(rBlockPos
, nCol
);
2464 void ScDocument::CopyBlockFromClip(
2465 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
2466 const ScMarkData
& rMark
, SCsCOL nDx
, SCsROW nDy
)
2468 TableContainer
& rClipTabs
= rCxt
.getClipDoc()->maTabs
;
2469 SCTAB nTabEnd
= rCxt
.getTabEnd();
2471 for (SCTAB i
= rCxt
.getTabStart(); i
<= nTabEnd
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2473 if (maTabs
[i
] && rMark
.GetTableSelect(i
) )
2475 while (!rClipTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2477 maTabs
[i
]->CopyFromClip(
2478 rCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, rClipTabs
[nClipTab
]);
2480 if (rCxt
.getClipDoc()->pDrawLayer
&& (rCxt
.getInsertFlag() & IDF_OBJECTS
))
2482 // also copy drawing objects
2484 // drawing layer must be created before calling CopyFromClip
2485 // (ScDocShell::MakeDrawLayer also does InitItems etc.)
2486 OSL_ENSURE( pDrawLayer
, "CopyBlockFromClip: No drawing layer" );
2489 // For GetMMRect, the row heights in the target document must already be valid
2490 // (copied in an extra step before pasting, or updated after pasting cells, but
2491 // before pasting objects).
2493 Rectangle aSourceRect
= rCxt
.getClipDoc()->GetMMRect(
2494 nCol1
-nDx
, nRow1
-nDy
, nCol2
-nDx
, nRow2
-nDy
, nClipTab
);
2495 Rectangle aDestRect
= GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, i
);
2496 pDrawLayer
->CopyFromClip(rCxt
.getClipDoc()->pDrawLayer
, nClipTab
, aSourceRect
,
2497 ScAddress( nCol1
, nRow1
, i
), aDestRect
);
2501 nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2504 if (rCxt
.getInsertFlag() & IDF_CONTENTS
)
2507 for (SCTAB i
= rCxt
.getTabStart(); i
<= nTabEnd
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2509 if (maTabs
[i
] && rMark
.GetTableSelect(i
) )
2511 while (!rClipTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2512 SCsTAB nDz
= ((SCsTAB
)i
) - nClipTab
;
2514 // ranges of consecutive selected tables (in clipboard and dest. doc)
2515 // must be handled in one UpdateReference call
2517 while ( i
+ nFollow
< nTabEnd
2518 && rMark
.GetTableSelect( i
+ nFollow
+ 1 )
2519 && nClipTab
+ nFollow
< MAXTAB
2520 && rClipTabs
[(nClipTab
+ nFollow
+ 1) % static_cast<SCTAB
>(rClipTabs
.size())] )
2523 sc::RefUpdateContext
aRefCxt(*this);
2524 aRefCxt
.maRange
= ScRange(nCol1
, nRow1
, i
, nCol2
, nRow2
, i
+nFollow
);
2525 aRefCxt
.mnColDelta
= nDx
;
2526 aRefCxt
.mnRowDelta
= nDy
;
2527 aRefCxt
.mnTabDelta
= nDz
;
2528 if (rCxt
.getClipDoc()->GetClipParam().mbCutMode
)
2530 bool bOldInserting
= IsInsertingFromOtherDoc();
2531 SetInsertingFromOtherDoc( true);
2532 aRefCxt
.meMode
= URM_MOVE
;
2533 UpdateReference(aRefCxt
, rCxt
.getUndoDoc(), false);
2534 SetInsertingFromOtherDoc( bOldInserting
);
2538 aRefCxt
.meMode
= URM_COPY
;
2539 UpdateReference(aRefCxt
, rCxt
.getUndoDoc(), false);
2542 nClipTab
= (nClipTab
+nFollow
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2543 i
= sal::static_int_cast
<SCTAB
>( i
+ nFollow
);
2550 void ScDocument::CopyNonFilteredFromClip(
2551 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
2552 const ScMarkData
& rMark
, SCsCOL nDx
, SCROW
& rClipStartRow
)
2554 // call CopyBlockFromClip for ranges of consecutive non-filtered rows
2555 // nCol1/nRow1 etc. is in target doc
2557 // filtered state is taken from first used table in clipboard (as in GetClipArea)
2559 TableContainer
& rClipTabs
= rCxt
.getClipDoc()->maTabs
;
2560 while ( nFlagTab
< static_cast<SCTAB
>(rClipTabs
.size()) && !rClipTabs
[nFlagTab
] )
2563 SCROW nSourceRow
= rClipStartRow
;
2564 SCROW nSourceEnd
= 0;
2565 if (!rCxt
.getClipDoc()->GetClipParam().maRanges
.empty())
2566 nSourceEnd
= rCxt
.getClipDoc()->GetClipParam().maRanges
.front()->aEnd
.Row();
2567 SCROW nDestRow
= nRow1
;
2569 while ( nSourceRow
<= nSourceEnd
&& nDestRow
<= nRow2
)
2571 // skip filtered rows
2572 nSourceRow
= rCxt
.getClipDoc()->FirstNonFilteredRow(nSourceRow
, nSourceEnd
, nFlagTab
);
2574 if ( nSourceRow
<= nSourceEnd
)
2576 // look for more non-filtered rows following
2577 SCROW nLastRow
= nSourceRow
;
2578 rCxt
.getClipDoc()->RowFiltered(nSourceRow
, nFlagTab
, NULL
, &nLastRow
);
2579 SCROW nFollow
= nLastRow
- nSourceRow
;
2581 if (nFollow
> nSourceEnd
- nSourceRow
)
2582 nFollow
= nSourceEnd
- nSourceRow
;
2583 if (nFollow
> nRow2
- nDestRow
)
2584 nFollow
= nRow2
- nDestRow
;
2586 SCsROW nNewDy
= ((SCsROW
)nDestRow
) - nSourceRow
;
2588 rCxt
, nCol1
, nDestRow
, nCol2
, nDestRow
+ nFollow
, rMark
, nDx
, nNewDy
);
2590 nSourceRow
+= nFollow
+ 1;
2591 nDestRow
+= nFollow
+ 1;
2594 rClipStartRow
= nSourceRow
;
2598 void ScDocument::CopyFromClip( const ScRange
& rDestRange
, const ScMarkData
& rMark
,
2599 sal_uInt16 nInsFlag
,
2600 ScDocument
* pRefUndoDoc
, ScDocument
* pClipDoc
, bool bResetCut
,
2601 bool bAsLink
, bool bIncludeFiltered
, bool bSkipAttrForEmpty
,
2602 const ScRangeList
* pDestRanges
)
2609 OSL_FAIL("CopyFromClip: no ClipDoc");
2610 pClipDoc
= SC_MOD()->GetClipDoc();
2613 if (!pClipDoc
->bIsClip
|| !pClipDoc
->GetTableCount())
2616 bool bOldAutoCalc
= GetAutoCalc();
2617 SetAutoCalc( false ); // avoid multiple recalculations
2619 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2621 SCCOL nAllCol1
= rDestRange
.aStart
.Col();
2622 SCROW nAllRow1
= rDestRange
.aStart
.Row();
2623 SCCOL nAllCol2
= rDestRange
.aEnd
.Col();
2624 SCROW nAllRow2
= rDestRange
.aEnd
.Row();
2628 ScRange aClipRange
= pClipDoc
->GetClipParam().getWholeRange();
2629 for (SCTAB nTab
= 0; nTab
< static_cast<SCTAB
>(pClipDoc
->maTabs
.size()); nTab
++) // find largest merge overlap
2630 if (pClipDoc
->maTabs
[nTab
]) // all sheets of the clipboard content
2632 SCCOL nThisEndX
= aClipRange
.aEnd
.Col();
2633 SCROW nThisEndY
= aClipRange
.aEnd
.Row();
2634 pClipDoc
->ExtendMerge( aClipRange
.aStart
.Col(),
2635 aClipRange
.aStart
.Row(),
2636 nThisEndX
, nThisEndY
, nTab
);
2637 // only extra value from ExtendMerge
2638 nThisEndX
= sal::static_int_cast
<SCCOL
>( nThisEndX
- aClipRange
.aEnd
.Col() );
2639 nThisEndY
= sal::static_int_cast
<SCROW
>( nThisEndY
- aClipRange
.aEnd
.Row() );
2640 if ( nThisEndX
> nXw
)
2642 if ( nThisEndY
> nYw
)
2648 pClipDoc
->GetClipArea( nDestAddX
, nDestAddY
, bIncludeFiltered
);
2649 nXw
= sal::static_int_cast
<SCCOL
>( nXw
+ nDestAddX
);
2650 nYw
= sal::static_int_cast
<SCROW
>( nYw
+ nDestAddY
); // ClipArea, plus ExtendMerge value
2652 /* Decide which contents to delete before copying. Delete all
2653 contents if nInsFlag contains any real content flag.
2654 #i102056# Notes are pasted from clipboard in a second pass,
2655 together with the special flag IDF_ADDNOTES that states to not
2656 overwrite/delete existing cells but to insert the notes into
2657 these cells. In this case, just delete old notes from the
2658 destination area. */
2659 sal_uInt16 nDelFlag
= IDF_NONE
;
2660 if ( (nInsFlag
& (IDF_CONTENTS
| IDF_ADDNOTES
)) == (IDF_NOTE
| IDF_ADDNOTES
) )
2661 nDelFlag
|= IDF_NOTE
;
2662 else if ( nInsFlag
& IDF_CONTENTS
)
2663 nDelFlag
|= IDF_CONTENTS
;
2664 // With bSkipAttrForEmpty, don't remove attributes, copy
2665 // on top of existing attributes instead.
2666 if ( ( nInsFlag
& IDF_ATTRIB
) && !bSkipAttrForEmpty
)
2667 nDelFlag
|= IDF_ATTRIB
;
2669 sc::CopyFromClipContext
aCxt(*this, pRefUndoDoc
, pClipDoc
, nInsFlag
, bAsLink
, bSkipAttrForEmpty
);
2670 std::pair
<SCTAB
,SCTAB
> aTabRanges
= getMarkedTableRange(maTabs
, rMark
);
2671 aCxt
.setTabRange(aTabRanges
.first
, aTabRanges
.second
);
2673 ScRangeList aLocalRangeList
;
2676 aLocalRangeList
.Append( rDestRange
);
2677 pDestRanges
= &aLocalRangeList
;
2680 bInsertingFromOtherDoc
= true; // kein Broadcast/Listener aufbauen bei Insert
2682 SCCOL nClipStartCol
= aClipRange
.aStart
.Col();
2683 SCROW nClipStartRow
= aClipRange
.aStart
.Row();
2684 SCROW nClipEndRow
= aClipRange
.aEnd
.Row();
2685 for ( size_t nRange
= 0; nRange
< pDestRanges
->size(); ++nRange
)
2687 const ScRange
* pRange
= (*pDestRanges
)[nRange
];
2688 SCCOL nCol1
= pRange
->aStart
.Col();
2689 SCROW nRow1
= pRange
->aStart
.Row();
2690 SCCOL nCol2
= pRange
->aEnd
.Col();
2691 SCROW nRow2
= pRange
->aEnd
.Row();
2693 DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, rMark
, nDelFlag
);
2697 SCCOL nC2
= nC1
+ nXw
;
2700 SCROW nR2
= nR1
+ nYw
;
2706 // Pasting is done column-wise, when pasting to a filtered
2707 // area this results in partitioning and we have to
2708 // remember and reset the start row for each column until
2709 // it can be advanced for the next chunk of unfiltered
2711 SCROW nSaveClipStartRow
= nClipStartRow
;
2714 nClipStartRow
= nSaveClipStartRow
;
2715 SCsCOL nDx
= ((SCsCOL
)nC1
) - nClipStartCol
;
2716 SCsROW nDy
= ((SCsROW
)nR1
) - nClipStartRow
;
2717 if ( bIncludeFiltered
)
2720 aCxt
, nC1
, nR1
, nC2
, nR2
, rMark
, nDx
, nDy
);
2721 nClipStartRow
+= nR2
- nR1
+ 1;
2725 CopyNonFilteredFromClip(
2726 aCxt
, nC1
, nR1
, nC2
, nR2
, rMark
, nDx
, nClipStartRow
);
2729 nC2
= std::min((SCCOL
)(nC1
+ nXw
), nCol2
);
2730 } while (nC1
<= nCol2
);
2731 if (nClipStartRow
> nClipEndRow
)
2732 nClipStartRow
= aClipRange
.aStart
.Row();
2738 nR2
= std::min((SCROW
)(nR1
+ nYw
), nRow2
);
2739 } while (nR1
<= nRow2
);
2742 bInsertingFromOtherDoc
= false;
2744 // Listener aufbauen nachdem alles inserted wurde
2745 StartListeningFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2746 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2747 BroadcastFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2749 pClipDoc
->GetClipParam().mbCutMode
= false;
2750 SetAutoCalc( bOldAutoCalc
);
2753 static SCROW
lcl_getLastNonFilteredRow(
2754 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>& rFlags
, SCROW nBegRow
, SCROW nEndRow
,
2757 SCROW nFilteredRow
= rFlags
.GetFirstForCondition(
2758 nBegRow
, nEndRow
, CR_FILTERED
, CR_FILTERED
);
2760 SCROW nRow
= nFilteredRow
- 1;
2761 if (nRow
- nBegRow
+ 1 > nRowCount
)
2762 // make sure the row range stays within the data size.
2763 nRow
= nBegRow
+ nRowCount
- 1;
2768 void ScDocument::CopyMultiRangeFromClip(
2769 const ScAddress
& rDestPos
, const ScMarkData
& rMark
, sal_uInt16 nInsFlag
, ScDocument
* pClipDoc
,
2770 bool bResetCut
, bool bAsLink
, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty
)
2775 if (!pClipDoc
->bIsClip
|| !pClipDoc
->GetTableCount())
2776 // There is nothing in the clip doc to copy.
2779 bool bOldAutoCalc
= GetAutoCalc();
2780 SetAutoCalc( false ); // avoid multiple recalculations
2782 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2784 SCCOL nCol1
= rDestPos
.Col();
2785 SCROW nRow1
= rDestPos
.Row();
2786 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
2788 sc::CopyFromClipContext
aCxt(*this, NULL
, pClipDoc
, nInsFlag
, bAsLink
, bSkipAttrForEmpty
);
2789 std::pair
<SCTAB
,SCTAB
> aTabRanges
= getMarkedTableRange(maTabs
, rMark
);
2790 aCxt
.setTabRange(aTabRanges
.first
, aTabRanges
.second
);
2793 rMark
.GetMarkArea(aDestRange
);
2794 SCROW nLastMarkedRow
= aDestRange
.aEnd
.Row();
2796 bInsertingFromOtherDoc
= true; // kein Broadcast/Listener aufbauen bei Insert
2798 SCROW nBegRow
= nRow1
;
2799 sal_uInt16 nDelFlag
= IDF_CONTENTS
;
2800 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>& rFlags
= GetRowFlagsArray(aCxt
.getTabStart());
2802 for ( size_t i
= 0, n
= rClipParam
.maRanges
.size(); i
< n
; ++i
)
2804 ScRange
* p
= rClipParam
.maRanges
[ i
];
2805 // The begin row must not be filtered.
2807 SCROW nRowCount
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
2809 SCsCOL nDx
= static_cast<SCsCOL
>(nCol1
- p
->aStart
.Col());
2810 SCsROW nDy
= static_cast<SCsROW
>(nBegRow
- p
->aStart
.Row());
2811 SCCOL nCol2
= nCol1
+ p
->aEnd
.Col() - p
->aStart
.Col();
2813 SCROW nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2815 if (!bSkipAttrForEmpty
)
2816 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2818 CopyBlockFromClip(aCxt
, nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
);
2819 nRowCount
-= nEndRow
- nBegRow
+ 1;
2821 while (nRowCount
> 0)
2823 // Get the first non-filtered row.
2824 SCROW nNonFilteredRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2825 if (nNonFilteredRow
> nLastMarkedRow
)
2828 SCROW nRowsSkipped
= nNonFilteredRow
- nEndRow
- 1;
2829 nDy
+= nRowsSkipped
;
2831 nBegRow
= nNonFilteredRow
;
2832 nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2834 if (!bSkipAttrForEmpty
)
2835 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2837 CopyBlockFromClip(aCxt
, nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
);
2838 nRowCount
-= nEndRow
- nBegRow
+ 1;
2841 if (rClipParam
.meDirection
== ScClipParam::Row
)
2842 // Begin row for the next range being pasted.
2843 nBegRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2847 if (rClipParam
.meDirection
== ScClipParam::Column
)
2848 nCol1
+= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
2851 bInsertingFromOtherDoc
= false;
2853 ScRangeList aRanges
;
2854 aRanges
.Append(aDestRange
);
2856 // Listener aufbauen nachdem alles inserted wurde
2857 StartListeningFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2858 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2859 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2860 BroadcastFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2861 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2864 pClipDoc
->GetClipParam().mbCutMode
= false;
2865 SetAutoCalc( bOldAutoCalc
);
2868 void ScDocument::SetClipArea( const ScRange
& rArea
, bool bCut
)
2872 ScClipParam
& rClipParam
= GetClipParam();
2873 rClipParam
.maRanges
.RemoveAll();
2874 rClipParam
.maRanges
.Append(rArea
);
2875 rClipParam
.mbCutMode
= bCut
;
2879 OSL_FAIL("SetClipArea: No Clip");
2884 void ScDocument::GetClipArea(SCCOL
& nClipX
, SCROW
& nClipY
, bool bIncludeFiltered
)
2888 OSL_FAIL("GetClipArea: No Clip");
2892 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2893 if (rClipRanges
.empty())
2894 // No clip range. Bail out.
2897 ScRange
* p
= rClipRanges
.front();
2898 SCCOL nStartCol
= p
->aStart
.Col();
2899 SCCOL nEndCol
= p
->aEnd
.Col();
2900 SCROW nStartRow
= p
->aStart
.Row();
2901 SCROW nEndRow
= p
->aEnd
.Row();
2902 for ( size_t i
= 1, n
= rClipRanges
.size(); i
< n
; ++i
)
2904 p
= rClipRanges
[ i
];
2905 if (p
->aStart
.Col() < nStartCol
)
2906 nStartCol
= p
->aStart
.Col();
2907 if (p
->aStart
.Row() < nStartRow
)
2908 nStartRow
= p
->aStart
.Row();
2909 if (p
->aEnd
.Col() > nEndCol
)
2910 nEndCol
= p
->aEnd
.Col();
2911 if (p
->aEnd
.Row() < nEndRow
)
2912 nEndRow
= p
->aEnd
.Row();
2915 nClipX
= nEndCol
- nStartCol
;
2917 if ( bIncludeFiltered
)
2918 nClipY
= nEndRow
- nStartRow
;
2921 // count non-filtered rows
2922 // count on first used table in clipboard
2923 SCTAB nCountTab
= 0;
2924 while ( nCountTab
< static_cast<SCTAB
>(maTabs
.size()) && !maTabs
[nCountTab
] )
2927 SCROW nResult
= CountNonFilteredRows(nStartRow
, nEndRow
, nCountTab
);
2930 nClipY
= nResult
- 1;
2932 nClipY
= 0; // always return at least 1 row
2937 void ScDocument::GetClipStart(SCCOL
& nClipX
, SCROW
& nClipY
)
2941 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2942 if ( !rClipRanges
.empty() )
2944 nClipX
= rClipRanges
.front()->aStart
.Col();
2945 nClipY
= rClipRanges
.front()->aStart
.Row();
2950 OSL_FAIL("GetClipStart: No Clip");
2955 bool ScDocument::HasClipFilteredRows()
2957 // count on first used table in clipboard
2958 SCTAB nCountTab
= 0;
2959 while ( nCountTab
< static_cast<SCTAB
>(maTabs
.size()) && !maTabs
[nCountTab
] )
2962 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2963 if ( rClipRanges
.empty() )
2966 for ( size_t i
= 0, n
= rClipRanges
.size(); i
< n
; ++i
)
2968 ScRange
* p
= rClipRanges
[ i
];
2969 bool bAnswer
= maTabs
[nCountTab
]->HasFilteredRows(p
->aStart
.Row(), p
->aEnd
.Row());
2977 void ScDocument::MixDocument( const ScRange
& rRange
, sal_uInt16 nFunction
, bool bSkipEmpty
,
2978 ScDocument
* pSrcDoc
)
2980 SCTAB nTab1
= rRange
.aStart
.Tab();
2981 SCTAB nTab2
= rRange
.aEnd
.Tab();
2982 sc::MixDocContext
aCxt(*this);
2983 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pSrcDoc
->maTabs
.size()));
2984 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
2986 ScTable
* pTab
= FetchTable(i
);
2987 const ScTable
* pSrcTab
= pSrcDoc
->FetchTable(i
);
2988 if (!pTab
|| !pSrcTab
)
2992 aCxt
, rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
2993 nFunction
, bSkipEmpty
, pSrcTab
);
2998 void ScDocument::FillTab( const ScRange
& rSrcArea
, const ScMarkData
& rMark
,
2999 sal_uInt16 nFlags
, sal_uInt16 nFunction
,
3000 bool bSkipEmpty
, bool bAsLink
)
3002 sal_uInt16 nDelFlags
= nFlags
;
3003 if (nDelFlags
& IDF_CONTENTS
)
3004 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
3006 SCTAB nSrcTab
= rSrcArea
.aStart
.Tab();
3008 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
3010 SCCOL nStartCol
= rSrcArea
.aStart
.Col();
3011 SCROW nStartRow
= rSrcArea
.aStart
.Row();
3012 SCCOL nEndCol
= rSrcArea
.aEnd
.Col();
3013 SCROW nEndRow
= rSrcArea
.aEnd
.Row();
3014 boost::scoped_ptr
<ScDocument
> pMixDoc
;
3015 bool bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
3017 bool bOldAutoCalc
= GetAutoCalc();
3018 SetAutoCalc( false ); // avoid multiple calculations
3020 sc::CopyToDocContext
aCxt(*this);
3021 sc::MixDocContext
aMixDocCxt(*this);
3023 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
3024 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
3025 for (; itr
!= itrEnd
&& *itr
< nCount
; ++itr
)
3026 if ( *itr
!=nSrcTab
&& maTabs
[*itr
])
3033 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
3034 pMixDoc
->InitUndo( this, i
, i
);
3037 pMixDoc
->AddUndoTab( i
, i
);
3039 // context used for copying content to the temporary mix document.
3040 sc::CopyToDocContext
aMixCxt(*pMixDoc
);
3041 maTabs
[i
]->CopyToTable(aMixCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3042 IDF_CONTENTS
, false, pMixDoc
->maTabs
[i
] );
3044 maTabs
[i
]->DeleteArea( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nDelFlags
);
3045 maTabs
[nSrcTab
]->CopyToTable(aCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3046 nFlags
, false, maTabs
[i
], NULL
, bAsLink
);
3049 maTabs
[i
]->MixData(aMixDocCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3050 nFunction
, bSkipEmpty
, pMixDoc
->maTabs
[i
] );
3053 SetAutoCalc( bOldAutoCalc
);
3057 OSL_FAIL("wrong table");
3062 void ScDocument::FillTabMarked( SCTAB nSrcTab
, const ScMarkData
& rMark
,
3063 sal_uInt16 nFlags
, sal_uInt16 nFunction
,
3064 bool bSkipEmpty
, bool bAsLink
)
3066 sal_uInt16 nDelFlags
= nFlags
;
3067 if (nDelFlags
& IDF_CONTENTS
)
3068 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
3070 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
3072 boost::scoped_ptr
<ScDocument
> pMixDoc
;
3073 bool bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
3075 bool bOldAutoCalc
= GetAutoCalc();
3076 SetAutoCalc( false ); // avoid multiple calculations
3079 rMark
.GetMultiMarkArea( aArea
);
3080 SCCOL nStartCol
= aArea
.aStart
.Col();
3081 SCROW nStartRow
= aArea
.aStart
.Row();
3082 SCCOL nEndCol
= aArea
.aEnd
.Col();
3083 SCROW nEndRow
= aArea
.aEnd
.Row();
3085 sc::CopyToDocContext
aCxt(*this);
3086 sc::MixDocContext
aMixDocCxt(*this);
3087 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
3088 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
3089 for (; itr
!= itrEnd
&& *itr
< nCount
; ++itr
)
3090 if ( *itr
!=nSrcTab
&& maTabs
[*itr
] )
3097 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
3098 pMixDoc
->InitUndo( this, i
, i
);
3101 pMixDoc
->AddUndoTab( i
, i
);
3103 sc::CopyToDocContext
aMixCxt(*pMixDoc
);
3104 maTabs
[i
]->CopyToTable(aMixCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3105 IDF_CONTENTS
, true, pMixDoc
->maTabs
[i
], &rMark
);
3108 maTabs
[i
]->DeleteSelection( nDelFlags
, rMark
);
3109 maTabs
[nSrcTab
]->CopyToTable(aCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3110 nFlags
, true, maTabs
[i
], &rMark
, bAsLink
);
3113 maTabs
[i
]->MixMarked(aMixDocCxt
, rMark
, nFunction
, bSkipEmpty
, pMixDoc
->maTabs
[i
]);
3116 SetAutoCalc( bOldAutoCalc
);
3120 OSL_FAIL("wrong table");
3125 bool ScDocument::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const OUString
& rString
,
3126 ScSetStringParam
* pParam
)
3128 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3129 return maTabs
[nTab
]->SetString( nCol
, nRow
, nTab
, rString
, pParam
);
3134 bool ScDocument::SetString(
3135 const ScAddress
& rPos
, const OUString
& rString
, ScSetStringParam
* pParam
)
3137 return SetString(rPos
.Col(), rPos
.Row(), rPos
.Tab(), rString
, pParam
);
3140 void ScDocument::SetEditText( const ScAddress
& rPos
, EditTextObject
* pEditText
)
3142 if (!TableExists(rPos
.Tab()))
3148 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), pEditText
);
3151 void ScDocument::SetEditText( const ScAddress
& rPos
, const EditTextObject
& rEditText
, const SfxItemPool
* pEditPool
)
3153 if (!TableExists(rPos
.Tab()))
3156 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEditText
, pEditPool
);
3159 void ScDocument::SetEditText( const ScAddress
& rPos
, const OUString
& rStr
)
3161 if (!TableExists(rPos
.Tab()))
3164 ScFieldEditEngine
& rEngine
= GetEditEngine();
3165 rEngine
.SetText(rStr
);
3166 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEngine
.CreateTextObject());
3169 void ScDocument::SetTextCell( const ScAddress
& rPos
, const OUString
& rStr
)
3171 if (!TableExists(rPos
.Tab()))
3174 if (ScStringUtil::isMultiline(rStr
))
3176 ScFieldEditEngine
& rEngine
= GetEditEngine();
3177 rEngine
.SetText(rStr
);
3178 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEngine
.CreateTextObject());
3182 ScSetStringParam aParam
;
3183 aParam
.setTextInput();
3184 maTabs
[rPos
.Tab()]->SetString(rPos
.Col(), rPos
.Row(), rPos
.Tab(), rStr
, &aParam
);
3188 void ScDocument::SetEmptyCell( const ScAddress
& rPos
)
3190 if (!TableExists(rPos
.Tab()))
3193 maTabs
[rPos
.Tab()]->SetEmptyCell(rPos
.Col(), rPos
.Row());
3196 void ScDocument::SetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const double& rVal
)
3198 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
3200 maTabs
[nTab
]->SetValue( nCol
, nRow
, rVal
);
3203 void ScDocument::SetValue( const ScAddress
& rPos
, double fVal
)
3205 if (!TableExists(rPos
.Tab()))
3208 maTabs
[rPos
.Tab()]->SetValue(rPos
.Col(), rPos
.Row(), fVal
);
3211 OUString
ScDocument::GetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3213 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
3216 maTabs
[nTab
]->GetString(nCol
, nRow
, aStr
);
3220 return EMPTY_OUSTRING
;
3223 OUString
ScDocument::GetString( const ScAddress
& rPos
) const
3225 if (!TableExists(rPos
.Tab()))
3226 return EMPTY_OUSTRING
;
3229 maTabs
[rPos
.Tab()]->GetString(rPos
.Col(), rPos
.Row(), aStr
);
3233 double* ScDocument::GetValueCell( const ScAddress
& rPos
)
3235 if (!TableExists(rPos
.Tab()))
3238 return maTabs
[rPos
.Tab()]->GetValueCell(rPos
.Col(), rPos
.Row());
3241 svl::SharedString
ScDocument::GetSharedString( const ScAddress
& rPos
) const
3243 if (!TableExists(rPos
.Tab()))
3244 return svl::SharedString();
3246 return maTabs
[rPos
.Tab()]->GetSharedString(rPos
.Col(), rPos
.Row());
3249 sc::FormulaGroupContext
& ScDocument::GetFormulaGroupContext()
3251 if (!mpFormulaGroupCxt
)
3252 mpFormulaGroupCxt
.reset(new sc::FormulaGroupContext
);
3254 return *mpFormulaGroupCxt
;
3257 void ScDocument::GetInputString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rString
)
3259 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3260 maTabs
[nTab
]->GetInputString( nCol
, nRow
, rString
);
3262 rString
= OUString();
3265 sal_uInt16
ScDocument::GetStringForFormula( const ScAddress
& rPos
, OUString
& rString
)
3267 // Used in formulas (add-in parameters etc), so it must use the same semantics as
3268 // ScInterpreter::GetCellString: always format values as numbers.
3269 // The return value is the error code.
3271 ScRefCellValue aCell
;
3272 aCell
.assign(*this, rPos
);
3273 if (aCell
.isEmpty())
3275 rString
= EMPTY_OUSTRING
;
3279 sal_uInt16 nErr
= 0;
3281 SvNumberFormatter
* pFormatter
= GetFormatTable();
3282 switch (aCell
.meType
)
3284 case CELLTYPE_STRING
:
3286 aStr
= aCell
.getString(this);
3288 case CELLTYPE_FORMULA
:
3290 ScFormulaCell
* pFCell
= aCell
.mpFormula
;
3291 nErr
= pFCell
->GetErrCode();
3292 if (pFCell
->IsValue())
3294 double fVal
= pFCell
->GetValue();
3295 sal_uInt32 nIndex
= pFormatter
->GetStandardFormat(
3296 NUMBERFORMAT_NUMBER
,
3298 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
3301 aStr
= pFCell
->GetString().getString();
3304 case CELLTYPE_VALUE
:
3306 double fVal
= aCell
.mfValue
;
3307 sal_uInt32 nIndex
= pFormatter
->GetStandardFormat(
3308 NUMBERFORMAT_NUMBER
,
3310 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
3322 void ScDocument::GetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, double& rValue
) const
3324 if (TableExists(nTab
))
3325 rValue
= maTabs
[nTab
]->GetValue( nCol
, nRow
);
3330 const EditTextObject
* ScDocument::GetEditText( const ScAddress
& rPos
) const
3332 SCTAB nTab
= rPos
.Tab();
3333 if (!TableExists(nTab
))
3336 return maTabs
[nTab
]->GetEditText(rPos
.Col(), rPos
.Row());
3339 void ScDocument::RemoveEditTextCharAttribs( const ScAddress
& rPos
, const ScPatternAttr
& rAttr
)
3341 if (!TableExists(rPos
.Tab()))
3344 return maTabs
[rPos
.Tab()]->RemoveEditTextCharAttribs(rPos
.Col(), rPos
.Row(), rAttr
);
3347 double ScDocument::GetValue( const ScAddress
& rPos
) const
3349 SCTAB nTab
= rPos
.Tab();
3350 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3351 return maTabs
[nTab
]->GetValue(rPos
.Col(), rPos
.Row());
3355 double ScDocument::GetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3357 ScAddress
aAdr(nCol
, nRow
, nTab
); return GetValue(aAdr
);
3360 void ScDocument::GetNumberFormat( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3361 sal_uInt32
& rFormat
) const
3363 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
3366 rFormat
= maTabs
[nTab
]->GetNumberFormat( nCol
, nRow
);
3372 sal_uInt32
ScDocument::GetNumberFormat( const ScRange
& rRange
) const
3374 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
3375 SCCOL nCol1
= rRange
.aStart
.Col(), nCol2
= rRange
.aEnd
.Col();
3376 SCROW nRow1
= rRange
.aStart
.Row(), nRow2
= rRange
.aEnd
.Row();
3378 if (!ValidTab(nTab1
) || !ValidTab(nTab2
) || !maTabs
[nTab1
] || !maTabs
[nTab2
])
3381 sal_uInt32 nFormat
= 0;
3382 bool bFirstItem
= true;
3383 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
&& nTab
< static_cast<SCTAB
>(maTabs
.size()) ; ++nTab
)
3384 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
3386 sal_uInt32 nThisFormat
= maTabs
[nTab
]->GetNumberFormat(nCol
, nRow1
, nRow2
);
3389 nFormat
= nThisFormat
;
3392 else if (nThisFormat
!= nFormat
)
3399 sal_uInt32
ScDocument::GetNumberFormat( const ScAddress
& rPos
) const
3401 SCTAB nTab
= rPos
.Tab();
3403 return maTabs
[nTab
]->GetNumberFormat( rPos
);
3407 void ScDocument::SetNumberFormat( const ScAddress
& rPos
, sal_uInt32 nNumberFormat
)
3409 if (!TableExists(rPos
.Tab()))
3412 maTabs
[rPos
.Tab()]->SetNumberFormat(rPos
.Col(), rPos
.Row(), nNumberFormat
);
3415 void ScDocument::GetNumberFormatInfo( short& nType
, sal_uLong
& nIndex
,
3416 const ScAddress
& rPos
) const
3418 SCTAB nTab
= rPos
.Tab();
3419 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3421 nIndex
= maTabs
[nTab
]->GetNumberFormat( rPos
);
3422 nType
= GetFormatTable()->GetType( nIndex
);
3426 nType
= NUMBERFORMAT_UNDEFINED
;
3432 void ScDocument::GetFormula( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rFormula
) const
3434 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3435 maTabs
[nTab
]->GetFormula( nCol
, nRow
, rFormula
);
3437 rFormula
= OUString();
3441 const ScTokenArray
* ScDocument::GetFormulaTokens( const ScAddress
& rPos
) const
3443 if (!TableExists(rPos
.Tab()))
3446 return maTabs
[rPos
.Tab()]->GetFormulaTokens(rPos
.Col(), rPos
.Row());
3449 const ScFormulaCell
* ScDocument::GetFormulaCell( const ScAddress
& rPos
) const
3451 if (!TableExists(rPos
.Tab()))
3454 return maTabs
[rPos
.Tab()]->GetFormulaCell(rPos
.Col(), rPos
.Row());
3457 ScFormulaCell
* ScDocument::GetFormulaCell( const ScAddress
& rPos
)
3459 if (!TableExists(rPos
.Tab()))
3462 return maTabs
[rPos
.Tab()]->GetFormulaCell(rPos
.Col(), rPos
.Row());
3465 CellType
ScDocument::GetCellType( const ScAddress
& rPos
) const
3467 SCTAB nTab
= rPos
.Tab();
3468 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3469 return maTabs
[nTab
]->GetCellType( rPos
);
3470 return CELLTYPE_NONE
;
3474 void ScDocument::GetCellType( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3475 CellType
& rCellType
) const
3477 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
3478 rCellType
= maTabs
[nTab
]->GetCellType( nCol
, nRow
);
3480 rCellType
= CELLTYPE_NONE
;
3483 bool ScDocument::HasStringData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3485 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3486 return maTabs
[nTab
]->HasStringData( nCol
, nRow
);
3492 bool ScDocument::HasValueData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3494 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3495 return maTabs
[nTab
]->HasValueData( nCol
, nRow
);
3500 bool ScDocument::HasValueData( const ScAddress
& rPos
) const
3502 return HasValueData(rPos
.Col(), rPos
.Row(), rPos
.Tab());
3505 bool ScDocument::HasStringCells( const ScRange
& rRange
) const
3507 // true, wenn String- oder Editzellen im Bereich
3509 SCCOL nStartCol
= rRange
.aStart
.Col();
3510 SCROW nStartRow
= rRange
.aStart
.Row();
3511 SCTAB nStartTab
= rRange
.aStart
.Tab();
3512 SCCOL nEndCol
= rRange
.aEnd
.Col();
3513 SCROW nEndRow
= rRange
.aEnd
.Row();
3514 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3516 for ( SCTAB nTab
=nStartTab
; nTab
<=nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3517 if ( maTabs
[nTab
] && maTabs
[nTab
]->HasStringCells( nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
3524 bool ScDocument::HasSelectionData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3526 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
3529 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
3530 if( pData
&& pData
->HasSelectionList() )
3533 return HasStringCells( ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
) );
3537 void ScDocument::SetDirty()
3539 bool bOldAutoCalc
= GetAutoCalc();
3540 bAutoCalc
= false; // keine Mehrfachberechnung
3541 { // scope for bulk broadcast
3542 ScBulkBroadcast
aBulkBroadcast( GetBASM());
3543 TableContainer::iterator it
= maTabs
.begin();
3544 for (;it
!= maTabs
.end(); ++it
)
3549 // Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
3550 // wenn alle Formeln dirty sind, werden die Charts aber nicht mehr erwischt
3551 // (#45205#) - darum alle Charts nochmal explizit
3552 if (pChartListenerCollection
)
3553 pChartListenerCollection
->SetDirty();
3555 SetAutoCalc( bOldAutoCalc
);
3559 void ScDocument::SetDirty( const ScRange
& rRange
)
3561 bool bOldAutoCalc
= GetAutoCalc();
3562 bAutoCalc
= false; // keine Mehrfachberechnung
3563 { // scope for bulk broadcast
3564 ScBulkBroadcast
aBulkBroadcast( GetBASM());
3565 SCTAB nTab2
= rRange
.aEnd
.Tab();
3566 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
3567 if (maTabs
[i
]) maTabs
[i
]->SetDirty( rRange
);
3569 SetAutoCalc( bOldAutoCalc
);
3573 void ScDocument::SetTableOpDirty( const ScRange
& rRange
)
3575 bool bOldAutoCalc
= GetAutoCalc();
3576 bAutoCalc
= false; // no multiple recalculation
3577 SCTAB nTab2
= rRange
.aEnd
.Tab();
3578 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
3579 if (maTabs
[i
]) maTabs
[i
]->SetTableOpDirty( rRange
);
3580 SetAutoCalc( bOldAutoCalc
);
3583 void ScDocument::InterpretDirtyCells( const ScRangeList
& rRanges
)
3588 mpFormulaGroupCxt
.reset();
3590 for (size_t nPos
=0, nRangeCount
= rRanges
.size(); nPos
< nRangeCount
; nPos
++)
3592 const ScRange
& rRange
= *rRanges
[nPos
];
3593 for (SCTAB nTab
= rRange
.aStart
.Tab(); nTab
<= rRange
.aEnd
.Tab(); ++nTab
)
3595 ScTable
* pTab
= FetchTable(nTab
);
3599 pTab
->InterpretDirtyCells(
3600 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
3604 mpFormulaGroupCxt
.reset();
3608 void ScDocument::AddTableOpFormulaCell( ScFormulaCell
* pCell
)
3610 if ( !aTableOpList
.empty() )
3612 ScInterpreterTableOpParams
* p
= &aTableOpList
.back();
3613 if ( p
->bCollectNotifications
)
3616 { // refresh pointers only
3617 p
->aNotifiedFormulaCells
.push_back( pCell
);
3620 { // init both, address and pointer
3621 p
->aNotifiedFormulaCells
.push_back( pCell
);
3622 p
->aNotifiedFormulaPos
.push_back( pCell
->aPos
);
3629 void ScDocument::CalcAll()
3631 ClearLookupCaches(); // Ensure we don't deliver zombie data.
3632 sc::AutoCalcSwitch
aSwitch(*this, true);
3633 TableContainer::iterator it
= maTabs
.begin();
3634 for (; it
!= maTabs
.end(); ++it
)
3636 (*it
)->SetDirtyVar();
3637 for (it
= maTabs
.begin(); it
!= maTabs
.end(); ++it
)
3641 mpFormulaGroupCxt
.reset();
3645 void ScDocument::CompileAll()
3647 TableContainer::iterator it
= maTabs
.begin();
3648 for (; it
!= maTabs
.end(); ++it
)
3650 (*it
)->CompileAll();
3655 void ScDocument::CompileXML()
3657 bool bOldAutoCalc
= GetAutoCalc();
3658 SetAutoCalc( false );
3659 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(
3660 STR_PROGRESS_CALCULATING
), GetXMLImportedFormulaCount() );
3662 // set AutoNameCache to speed up automatic name lookup
3663 OSL_ENSURE( !pAutoNameCache
, "AutoNameCache already set" );
3664 pAutoNameCache
= new ScAutoNameCache( this );
3667 pRangeName
->CompileUnresolvedXML();
3669 TableContainer::iterator it
= maTabs
.begin();
3670 for (; it
!= maTabs
.end(); ++it
)
3672 (*it
)->CompileXML( aProgress
);
3674 DELETEZ( pAutoNameCache
); // valid only during CompileXML, where cell contents don't change
3676 if ( pValidationList
)
3677 pValidationList
->CompileXML();
3679 SetAutoCalc( bOldAutoCalc
);
3682 bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode
)
3684 bool bCompiled
= false;
3685 TableContainer::iterator it
= maTabs
.begin(), itEnd
= maTabs
.end();
3686 for (; it
!= itEnd
; ++it
)
3688 ScTable
* pTab
= *it
;
3692 if (pTab
->CompileErrorCells(nErrCode
))
3699 void ScDocument::CalcAfterLoad()
3701 if (bIsClip
) // Excel-Dateien werden aus dem Clipboard in ein Clip-Doc geladen
3702 return; // dann wird erst beim Einfuegen in das richtige Doc berechnet
3704 bCalcingAfterLoad
= true;
3706 TableContainer::iterator it
= maTabs
.begin();
3707 for (; it
!= maTabs
.end(); ++it
)
3709 (*it
)->CalcAfterLoad();
3710 for (it
= maTabs
.begin(); it
!= maTabs
.end(); ++it
)
3712 (*it
)->SetDirtyAfterLoad();
3714 bCalcingAfterLoad
= false;
3716 SetDetectiveDirty(false); // noch keine wirklichen Aenderungen
3718 // #i112436# If formula cells are already dirty, they don't broadcast further changes.
3719 // So the source ranges of charts must be interpreted even if they are not visible,
3720 // similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
3721 if (pChartListenerCollection
)
3723 const ScChartListenerCollection::ListenersType
& rListeners
= pChartListenerCollection
->getListeners();
3724 ScChartListenerCollection::ListenersType::const_iterator it
= rListeners
.begin(), itEnd
= rListeners
.end();
3725 for (; it
!= itEnd
; ++it
)
3727 const ScChartListener
* p
= it
->second
;
3728 InterpretDirtyCells(*p
->GetRangeList());
3734 sal_uInt16
ScDocument::GetErrCode( const ScAddress
& rPos
) const
3736 SCTAB nTab
= rPos
.Tab();
3737 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3738 return maTabs
[nTab
]->GetErrCode( rPos
);
3743 void ScDocument::ResetChanged( const ScRange
& rRange
)
3745 SCTAB nTabSize
= static_cast<SCTAB
>(maTabs
.size());
3746 SCTAB nTab1
= rRange
.aStart
.Tab();
3747 SCTAB nTab2
= rRange
.aEnd
.Tab();
3748 for (SCTAB nTab
= nTab1
; nTab1
<= nTab2
&& nTab
< nTabSize
; ++nTab
)
3750 maTabs
[nTab
]->ResetChanged(rRange
);
3754 // Spaltenbreiten / Zeilenhoehen --------------------------------------
3758 void ScDocument::SetColWidth( SCCOL nCol
, SCTAB nTab
, sal_uInt16 nNewWidth
)
3760 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3761 maTabs
[nTab
]->SetColWidth( nCol
, nNewWidth
);
3764 void ScDocument::SetColWidthOnly( SCCOL nCol
, SCTAB nTab
, sal_uInt16 nNewWidth
)
3766 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3767 maTabs
[nTab
]->SetColWidthOnly( nCol
, nNewWidth
);
3770 void ScDocument::SetRowHeight( SCROW nRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3772 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3773 maTabs
[nTab
]->SetRowHeight( nRow
, nNewHeight
);
3777 void ScDocument::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3779 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3780 maTabs
[nTab
]->SetRowHeightRange
3781 ( nStartRow
, nEndRow
, nNewHeight
, 1.0, 1.0 );
3784 void ScDocument::SetRowHeightOnly( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3786 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3787 maTabs
[nTab
]->SetRowHeightOnly( nStartRow
, nEndRow
, nNewHeight
);
3790 void ScDocument::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bManual
)
3792 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3793 maTabs
[nTab
]->SetManualHeight( nStartRow
, nEndRow
, bManual
);
3797 sal_uInt16
ScDocument::GetColWidth( SCCOL nCol
, SCTAB nTab
, bool bHiddenAsZero
) const
3799 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3800 return maTabs
[nTab
]->GetColWidth( nCol
, bHiddenAsZero
);
3801 OSL_FAIL("wrong table number");
3806 sal_uInt16
ScDocument::GetOriginalWidth( SCCOL nCol
, SCTAB nTab
) const
3808 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3809 return maTabs
[nTab
]->GetOriginalWidth( nCol
);
3810 OSL_FAIL("wrong table number");
3815 sal_uInt16
ScDocument::GetCommonWidth( SCCOL nEndCol
, SCTAB nTab
) const
3817 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3818 return maTabs
[nTab
]->GetCommonWidth( nEndCol
);
3819 OSL_FAIL("Wrong table number");
3824 sal_uInt16
ScDocument::GetOriginalHeight( SCROW nRow
, SCTAB nTab
) const
3826 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3827 return maTabs
[nTab
]->GetOriginalHeight( nRow
);
3828 OSL_FAIL("Wrong table number");
3833 sal_uInt16
ScDocument::GetRowHeight( SCROW nRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3835 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3836 return maTabs
[nTab
]->GetRowHeight( nRow
, NULL
, NULL
, bHiddenAsZero
);
3837 OSL_FAIL("Wrong sheet number");
3842 sal_uInt16
ScDocument::GetRowHeight( SCROW nRow
, SCTAB nTab
, SCROW
* pStartRow
, SCROW
* pEndRow
, bool bHiddenAsZero
) const
3844 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3845 return maTabs
[nTab
]->GetRowHeight( nRow
, pStartRow
, pEndRow
, bHiddenAsZero
);
3846 OSL_FAIL("Wrong sheet number");
3851 sal_uLong
ScDocument::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3853 if (nStartRow
== nEndRow
)
3854 return GetRowHeight( nStartRow
, nTab
, bHiddenAsZero
); // faster for a single row
3856 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3857 if (nStartRow
> nEndRow
)
3860 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3861 return maTabs
[nTab
]->GetRowHeight( nStartRow
, nEndRow
, bHiddenAsZero
);
3863 OSL_FAIL("wrong sheet number");
3867 SCROW
ScDocument::GetRowForHeight( SCTAB nTab
, sal_uLong nHeight
) const
3869 return maTabs
[nTab
]->GetRowForHeight(nHeight
);
3872 sal_uLong
ScDocument::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
,
3873 SCTAB nTab
, double fScale
) const
3875 // faster for a single row
3876 if (nStartRow
== nEndRow
)
3877 return (sal_uLong
) (GetRowHeight( nStartRow
, nTab
) * fScale
);
3879 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3880 if (nStartRow
> nEndRow
)
3883 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3884 return maTabs
[nTab
]->GetScaledRowHeight( nStartRow
, nEndRow
, fScale
);
3886 OSL_FAIL("wrong sheet number");
3890 SCROW
ScDocument::GetHiddenRowCount( SCROW nRow
, SCTAB nTab
) const
3892 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3893 return maTabs
[nTab
]->GetHiddenRowCount( nRow
);
3894 OSL_FAIL("wrong table number");
3899 sal_uLong
ScDocument::GetColOffset( SCCOL nCol
, SCTAB nTab
, bool bHiddenAsZero
) const
3901 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3902 return maTabs
[nTab
]->GetColOffset( nCol
, bHiddenAsZero
);
3903 OSL_FAIL("wrong table number");
3908 sal_uLong
ScDocument::GetRowOffset( SCROW nRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3910 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3911 return maTabs
[nTab
]->GetRowOffset( nRow
, bHiddenAsZero
);
3912 OSL_FAIL("wrong table number");
3917 sal_uInt16
ScDocument::GetOptimalColWidth( SCCOL nCol
, SCTAB nTab
, OutputDevice
* pDev
,
3918 double nPPTX
, double nPPTY
,
3919 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3920 bool bFormula
, const ScMarkData
* pMarkData
,
3921 const ScColWidthParam
* pParam
)
3923 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3924 return maTabs
[nTab
]->GetOptimalColWidth( nCol
, pDev
, nPPTX
, nPPTY
,
3925 rZoomX
, rZoomY
, bFormula
, pMarkData
, pParam
);
3926 OSL_FAIL("wrong table number");
3931 long ScDocument::GetNeededSize( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3933 double nPPTX
, double nPPTY
,
3934 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3935 bool bWidth
, bool bTotalSize
)
3937 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3938 return maTabs
[nTab
]->GetNeededSize
3939 ( nCol
, nRow
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bWidth
, bTotalSize
);
3940 OSL_FAIL("wrong table number");
3945 bool ScDocument::SetOptimalHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nExtra
,
3947 double nPPTX
, double nPPTY
,
3948 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3952 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3953 return maTabs
[nTab
]->SetOptimalHeight( nStartRow
, nEndRow
, nExtra
,
3954 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bShrink
);
3955 OSL_FAIL("wrong table number");
3960 void ScDocument::UpdateAllRowHeights( OutputDevice
* pDev
, double nPPTX
, double nPPTY
,
3961 const Fraction
& rZoomX
, const Fraction
& rZoomY
, const ScMarkData
* pTabMark
)
3963 // one progress across all (selected) sheets
3965 sal_uLong nCellCount
= 0;
3966 for ( SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3967 if ( maTabs
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3968 nCellCount
+= maTabs
[nTab
]->GetWeightedCount();
3970 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING
), nCellCount
);
3972 sal_uLong nProgressStart
= 0;
3973 for ( SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3974 if ( maTabs
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3976 maTabs
[nTab
]->SetOptimalHeightOnly( 0, MAXROW
, 0,
3977 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, false, &aProgress
, nProgressStart
);
3978 maTabs
[nTab
]->SetDrawPageSize(true, true);
3979 nProgressStart
+= maTabs
[nTab
]->GetWeightedCount();
3985 // Spalten-/Zeilen-Flags ----------------------------------------------
3988 void ScDocument::ShowCol(SCCOL nCol
, SCTAB nTab
, bool bShow
)
3990 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3991 maTabs
[nTab
]->ShowCol( nCol
, bShow
);
3995 void ScDocument::ShowRow(SCROW nRow
, SCTAB nTab
, bool bShow
)
3997 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3998 maTabs
[nTab
]->ShowRow( nRow
, bShow
);
4002 void ScDocument::ShowRows(SCROW nRow1
, SCROW nRow2
, SCTAB nTab
, bool bShow
)
4004 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4005 maTabs
[nTab
]->ShowRows( nRow1
, nRow2
, bShow
);
4009 void ScDocument::SetRowFlags( SCROW nRow
, SCTAB nTab
, sal_uInt8 nNewFlags
)
4011 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4012 maTabs
[nTab
]->SetRowFlags( nRow
, nNewFlags
);
4016 void ScDocument::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt8 nNewFlags
)
4018 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4019 maTabs
[nTab
]->SetRowFlags( nStartRow
, nEndRow
, nNewFlags
);
4023 sal_uInt8
ScDocument::GetColFlags( SCCOL nCol
, SCTAB nTab
) const
4025 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4026 return maTabs
[nTab
]->GetColFlags( nCol
);
4027 OSL_FAIL("wrong table number");
4031 sal_uInt8
ScDocument::GetRowFlags( SCROW nRow
, SCTAB nTab
) const
4033 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4034 return maTabs
[nTab
]->GetRowFlags( nRow
);
4035 OSL_FAIL("wrong table number");
4039 const ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> & ScDocument::GetRowFlagsArray(
4042 const ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> * pFlags
;
4043 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4044 pFlags
= maTabs
[nTab
]->GetRowFlagsArray();
4047 OSL_FAIL("wrong sheet number");
4052 OSL_FAIL("no row flags at sheet");
4053 static ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> aDummy( MAXROW
, 0);
4059 void ScDocument::GetAllRowBreaks(set
<SCROW
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
4061 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4063 maTabs
[nTab
]->GetAllRowBreaks(rBreaks
, bPage
, bManual
);
4066 void ScDocument::GetAllColBreaks(set
<SCCOL
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
4068 if (!ValidTab(nTab
) || !maTabs
[nTab
])
4071 maTabs
[nTab
]->GetAllColBreaks(rBreaks
, bPage
, bManual
);
4074 ScBreakType
ScDocument::HasRowBreak(SCROW nRow
, SCTAB nTab
) const
4076 ScBreakType nType
= BREAK_NONE
;
4077 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4080 if (maTabs
[nTab
]->HasRowPageBreak(nRow
))
4081 nType
|= BREAK_PAGE
;
4083 if (maTabs
[nTab
]->HasRowManualBreak(nRow
))
4084 nType
|= BREAK_MANUAL
;
4089 ScBreakType
ScDocument::HasColBreak(SCCOL nCol
, SCTAB nTab
) const
4091 ScBreakType nType
= BREAK_NONE
;
4092 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4095 if (maTabs
[nTab
]->HasColPageBreak(nCol
))
4096 nType
|= BREAK_PAGE
;
4098 if (maTabs
[nTab
]->HasColManualBreak(nCol
))
4099 nType
|= BREAK_MANUAL
;
4104 void ScDocument::SetRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
4106 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4109 maTabs
[nTab
]->SetRowBreak(nRow
, bPage
, bManual
);
4112 void ScDocument::SetColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
4114 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4117 maTabs
[nTab
]->SetColBreak(nCol
, bPage
, bManual
);
4120 void ScDocument::RemoveRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
4122 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4125 maTabs
[nTab
]->RemoveRowBreak(nRow
, bPage
, bManual
);
4128 void ScDocument::RemoveColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
4130 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4133 maTabs
[nTab
]->RemoveColBreak(nCol
, bPage
, bManual
);
4136 Sequence
<TablePageBreakData
> ScDocument::GetRowBreakData(SCTAB nTab
) const
4138 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4139 return Sequence
<TablePageBreakData
>();
4141 return maTabs
[nTab
]->GetRowBreakData();
4144 bool ScDocument::RowHidden(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
4146 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4149 return maTabs
[nTab
]->RowHidden(nRow
, pFirstRow
, pLastRow
);
4152 bool ScDocument::HasHiddenRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4154 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4157 return maTabs
[nTab
]->HasHiddenRows(nStartRow
, nEndRow
);
4160 bool ScDocument::ColHidden(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
4162 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4171 return maTabs
[nTab
]->ColHidden(nCol
, pFirstCol
, pLastCol
);
4174 void ScDocument::SetRowHidden(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bHidden
)
4176 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4179 maTabs
[nTab
]->SetRowHidden(nStartRow
, nEndRow
, bHidden
);
4182 void ScDocument::SetColHidden(SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bHidden
)
4184 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4187 maTabs
[nTab
]->SetColHidden(nStartCol
, nEndCol
, bHidden
);
4190 SCROW
ScDocument::FirstVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4192 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4193 return ::std::numeric_limits
<SCROW
>::max();;
4195 return maTabs
[nTab
]->FirstVisibleRow(nStartRow
, nEndRow
);
4198 SCROW
ScDocument::LastVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4200 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4201 return ::std::numeric_limits
<SCROW
>::max();;
4203 return maTabs
[nTab
]->LastVisibleRow(nStartRow
, nEndRow
);
4206 SCROW
ScDocument::CountVisibleRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4208 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4211 return maTabs
[nTab
]->CountVisibleRows(nStartRow
, nEndRow
);
4214 bool ScDocument::RowFiltered(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
4216 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4219 return maTabs
[nTab
]->RowFiltered(nRow
, pFirstRow
, pLastRow
);
4222 bool ScDocument::HasFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4224 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4227 return maTabs
[nTab
]->HasFilteredRows(nStartRow
, nEndRow
);
4230 bool ScDocument::ColFiltered(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
4232 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4235 return maTabs
[nTab
]->ColFiltered(nCol
, pFirstCol
, pLastCol
);
4238 void ScDocument::SetRowFiltered(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bFiltered
)
4240 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4243 maTabs
[nTab
]->SetRowFiltered(nStartRow
, nEndRow
, bFiltered
);
4247 SCROW
ScDocument::FirstNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4249 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4250 return ::std::numeric_limits
<SCROW
>::max();;
4252 return maTabs
[nTab
]->FirstNonFilteredRow(nStartRow
, nEndRow
);
4255 SCROW
ScDocument::LastNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4257 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4258 return ::std::numeric_limits
<SCROW
>::max();;
4260 return maTabs
[nTab
]->LastNonFilteredRow(nStartRow
, nEndRow
);
4263 SCROW
ScDocument::CountNonFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4265 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4268 return maTabs
[nTab
]->CountNonFilteredRows(nStartRow
, nEndRow
);
4271 bool ScDocument::IsManualRowHeight(SCROW nRow
, SCTAB nTab
) const
4273 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4276 return maTabs
[nTab
]->IsManualRowHeight(nRow
);
4279 void ScDocument::SyncColRowFlags()
4281 TableContainer::iterator it
= maTabs
.begin();
4282 for (; it
!= maTabs
.end(); ++it
)
4285 (*it
)->SyncColRowFlags();
4289 SCROW
ScDocument::GetLastFlaggedRow( SCTAB nTab
) const
4291 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4292 return maTabs
[nTab
]->GetLastFlaggedRow();
4297 SCCOL
ScDocument::GetLastChangedCol( SCTAB nTab
) const
4299 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4300 return maTabs
[nTab
]->GetLastChangedCol();
4304 SCROW
ScDocument::GetLastChangedRow( SCTAB nTab
) const
4306 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4307 return maTabs
[nTab
]->GetLastChangedRow();
4312 SCCOL
ScDocument::GetNextDifferentChangedCol( SCTAB nTab
, SCCOL nStart
) const
4314 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4316 sal_uInt8 nStartFlags
= maTabs
[nTab
]->GetColFlags(nStart
);
4317 sal_uInt16 nStartWidth
= maTabs
[nTab
]->GetOriginalWidth(nStart
);
4318 for (SCCOL nCol
= nStart
+ 1; nCol
<= MAXCOL
; nCol
++)
4320 if (((nStartFlags
& CR_MANUALBREAK
) != (maTabs
[nTab
]->GetColFlags(nCol
) & CR_MANUALBREAK
)) ||
4321 (nStartWidth
!= maTabs
[nTab
]->GetOriginalWidth(nCol
)) ||
4322 ((nStartFlags
& CR_HIDDEN
) != (maTabs
[nTab
]->GetColFlags(nCol
) & CR_HIDDEN
)) )
4330 SCROW
ScDocument::GetNextDifferentChangedRow( SCTAB nTab
, SCROW nStart
, bool bCareManualSize
) const
4332 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4335 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>* pRowFlagsArray
= maTabs
[nTab
]->GetRowFlagsArray();
4336 if (!pRowFlagsArray
)
4339 if (!maTabs
[nTab
]->mpRowHeights
|| !maTabs
[nTab
]->mpHiddenRows
)
4342 size_t nIndex
; // ignored
4344 SCROW nHiddenEndRow
;
4345 SCROW nHeightEndRow
;
4349 sal_uInt8 nStartFlags
= nFlags
= pRowFlagsArray
->GetValue( nStart
, nIndex
, nFlagsEndRow
);
4350 bool bStartHidden
= bHidden
= maTabs
[nTab
]->RowHidden( nStart
, NULL
, &nHiddenEndRow
);
4351 sal_uInt16 nStartHeight
= nHeight
= maTabs
[nTab
]->GetRowHeight( nStart
, NULL
, &nHeightEndRow
, false);
4353 while ((nRow
= std::min( nHiddenEndRow
, std::min( nFlagsEndRow
, nHeightEndRow
)) + 1) <= MAXROW
)
4355 if (nFlagsEndRow
< nRow
)
4356 nFlags
= pRowFlagsArray
->GetValue( nRow
, nIndex
, nFlagsEndRow
);
4357 if (nHiddenEndRow
< nRow
)
4358 bHidden
= maTabs
[nTab
]->RowHidden( nRow
, NULL
, &nHiddenEndRow
);
4359 if (nHeightEndRow
< nRow
)
4360 nHeight
= maTabs
[nTab
]->GetRowHeight( nRow
, NULL
, &nHeightEndRow
, false);
4362 if (((nStartFlags
& CR_MANUALBREAK
) != (nFlags
& CR_MANUALBREAK
)) ||
4363 ((nStartFlags
& CR_MANUALSIZE
) != (nFlags
& CR_MANUALSIZE
)) ||
4364 (bStartHidden
!= bHidden
) ||
4365 (bCareManualSize
&& (nStartFlags
& CR_MANUALSIZE
) && (nStartHeight
!= nHeight
)) ||
4366 (!bCareManualSize
&& ((nStartHeight
!= nHeight
))))
4373 bool ScDocument::GetColDefault( SCTAB nTab
, SCCOL nCol
, SCROW nLastRow
, SCROW
& nDefault
)
4377 ScDocAttrIterator
aDocAttrItr(this, nTab
, nCol
, 0, nCol
, nLastRow
);
4381 const ScPatternAttr
* pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
4382 if (nEndRow
< nLastRow
)
4384 ScDefaultAttrSet aSet
;
4385 ScDefaultAttrSet::iterator aItr
= aSet
.end();
4388 ScDefaultAttr
aAttr(pAttr
);
4389 aItr
= aSet
.find(aAttr
);
4390 if (aItr
== aSet
.end())
4392 aAttr
.nCount
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
4393 aAttr
.nFirst
= nStartRow
;
4398 aAttr
.nCount
= aItr
->nCount
+ static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
4399 aAttr
.nFirst
= aItr
->nFirst
;
4403 pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
4405 ScDefaultAttrSet::iterator aDefaultItr
= aSet
.begin();
4408 while (aItr
!= aSet
.end())
4410 // for entries with equal count, use the one with the lowest start row,
4411 // don't use the random order of pointer comparisons
4412 if ( aItr
->nCount
> aDefaultItr
->nCount
||
4413 ( aItr
->nCount
== aDefaultItr
->nCount
&& aItr
->nFirst
< aDefaultItr
->nFirst
) )
4417 nDefault
= aDefaultItr
->nFirst
;
4425 void ScDocument::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
4427 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4428 maTabs
[nTab
]->StripHidden( rX1
, rY1
, rX2
, rY2
);
4432 void ScDocument::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
4434 if ( ValidTab(nTab
) && maTabs
[nTab
] )
4435 maTabs
[nTab
]->ExtendHidden( rX1
, rY1
, rX2
, rY2
);
4439 // Attribute ----------------------------------------------------------
4442 const SfxPoolItem
* ScDocument::GetAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_uInt16 nWhich
) const
4444 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4446 const SfxPoolItem
* pTemp
= maTabs
[nTab
]->GetAttr( nCol
, nRow
, nWhich
);
4451 OSL_FAIL( "Attribut Null" );
4454 return &xPoolHelper
->GetDocPool()->GetDefaultItem( nWhich
);
4457 const SfxPoolItem
* ScDocument::GetAttr( const ScAddress
& rPos
, sal_uInt16 nWhich
) const
4459 return GetAttr(rPos
.Col(), rPos
.Row(), rPos
.Tab(), nWhich
);
4462 const ScPatternAttr
* ScDocument::GetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4464 if (TableExists(nTab
))
4465 return maTabs
[nTab
]->GetPattern( nCol
, nRow
);
4469 const ScPatternAttr
* ScDocument::GetPattern( const ScAddress
& rPos
) const
4471 if (TableExists(rPos
.Tab()))
4472 return maTabs
[rPos
.Tab()]->GetPattern(rPos
.Col(), rPos
.Row());
4477 const ScPatternAttr
* ScDocument::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4479 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4480 return maTabs
[nTab
]->GetMostUsedPattern( nCol
, nStartRow
, nEndRow
);
4485 void ScDocument::ApplyAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const SfxPoolItem
& rAttr
)
4487 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4488 maTabs
[nTab
]->ApplyAttr( nCol
, nRow
, rAttr
);
4492 void ScDocument::ApplyPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
4494 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4495 maTabs
[nTab
]->ApplyPattern( nCol
, nRow
, rAttr
);
4499 void ScDocument::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
,
4500 SCCOL nEndCol
, SCROW nEndRow
,
4501 const ScMarkData
& rMark
,
4502 const ScPatternAttr
& rAttr
,
4503 ScEditDataArray
* pDataArray
)
4505 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4506 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4507 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4509 maTabs
[*itr
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
, pDataArray
);
4513 void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
4514 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
4516 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4518 maTabs
[nTab
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
);
4521 bool ScDocument::SetAttrEntries(SCCOL nCol
, SCTAB nTab
, ScAttrEntry
* pData
, SCSIZE nSize
)
4523 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4526 return maTabs
[nTab
]->SetAttrEntries(nCol
, pData
, nSize
);
4529 void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
4530 const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
, short nNewType
)
4532 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4533 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4534 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4536 maTabs
[*itr
]->ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
4539 void ScDocument::AddCondFormatData( const ScRangeList
& rRange
, SCTAB nTab
, sal_uInt32 nIndex
)
4541 if(!(static_cast<size_t>(nTab
) < maTabs
.size()))
4547 maTabs
[nTab
]->AddCondFormatData(rRange
, nIndex
);
4550 void ScDocument::RemoveCondFormatData( const ScRangeList
& rRange
, SCTAB nTab
, sal_uInt32 nIndex
)
4552 if(!(static_cast<size_t>(nTab
) < maTabs
.size()))
4558 maTabs
[nTab
]->RemoveCondFormatData(rRange
, nIndex
);
4562 void ScDocument::ApplyStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
4564 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4566 maTabs
[nTab
]->ApplyStyle( nCol
, nRow
, rStyle
);
4570 void ScDocument::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
,
4571 SCCOL nEndCol
, SCROW nEndRow
,
4572 const ScMarkData
& rMark
,
4573 const ScStyleSheet
& rStyle
)
4575 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4576 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4577 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4579 maTabs
[*itr
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
4583 void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
4584 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
4586 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4588 maTabs
[nTab
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
4592 void ScDocument::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
4594 // ApplySelectionStyle needs multi mark
4595 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
4598 rMark
.GetMarkArea( aRange
);
4599 ApplyStyleArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4600 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rStyle
);
4604 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4605 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4606 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4608 maTabs
[*itr
]->ApplySelectionStyle( rStyle
, rMark
);
4613 void ScDocument::ApplySelectionLineStyle( const ScMarkData
& rMark
,
4614 const SvxBorderLine
* pLine
, bool bColorOnly
)
4616 if ( bColorOnly
&& !pLine
)
4619 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4620 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4621 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4623 maTabs
[*itr
]->ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
4627 const ScStyleSheet
* ScDocument::GetStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4629 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4630 return maTabs
[nTab
]->GetStyle(nCol
, nRow
);
4636 const ScStyleSheet
* ScDocument::GetSelectionStyle( const ScMarkData
& rMark
) const
4641 const ScStyleSheet
* pStyle
= NULL
;
4642 const ScStyleSheet
* pNewStyle
;
4644 if ( rMark
.IsMultiMarked() )
4646 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4647 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4648 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4651 pNewStyle
= maTabs
[*itr
]->GetSelectionStyle( rMark
, bFound
);
4654 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
4655 bEqual
= false; // unterschiedliche
4660 if ( rMark
.IsMarked() )
4663 rMark
.GetMarkArea( aRange
);
4664 for (SCTAB i
=aRange
.aStart
.Tab(); i
<=aRange
.aEnd
.Tab() && bEqual
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
4665 if (maTabs
[i
] && rMark
.GetTableSelect(i
))
4667 pNewStyle
= maTabs
[i
]->GetAreaStyle( bFound
,
4668 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4669 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4672 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
4673 bEqual
= false; // unterschiedliche
4679 return bEqual
? pStyle
: NULL
;
4683 void ScDocument::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, bool bRemoved
,
4685 double nPPTX
, double nPPTY
,
4686 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
4688 TableContainer::iterator it
= maTabs
.begin();
4689 for (; it
!= maTabs
.end(); ++it
)
4691 (*it
)->StyleSheetChanged
4692 ( pStyleSheet
, bRemoved
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
);
4694 if ( pStyleSheet
&& pStyleSheet
->GetName() == ScGlobal::GetRscString(STR_STYLENAME_STANDARD
) )
4696 // update attributes for all note objects
4697 ScDetectiveFunc::UpdateAllComments( *this );
4702 bool ScDocument::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, bool bGatherAllStyles
) const
4704 if ( bStyleSheetUsageInvalid
|| rStyle
.GetUsage() == ScStyleSheet::UNKNOWN
)
4706 if ( bGatherAllStyles
)
4708 SfxStyleSheetIterator
aIter( xPoolHelper
->GetStylePool(),
4709 SFX_STYLE_FAMILY_PARA
);
4710 for ( const SfxStyleSheetBase
* pStyle
= aIter
.First(); pStyle
;
4711 pStyle
= aIter
.Next() )
4713 const ScStyleSheet
* pScStyle
= PTR_CAST( ScStyleSheet
, pStyle
);
4715 pScStyle
->SetUsage( ScStyleSheet::NOTUSED
);
4719 bool bIsUsed
= false;
4721 TableContainer::const_iterator it
= maTabs
.begin();
4722 for (; it
!= maTabs
.end(); ++it
)
4725 if ( (*it
)->IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
4727 if ( !bGatherAllStyles
)
4733 if ( bGatherAllStyles
)
4734 bStyleSheetUsageInvalid
= false;
4739 return rStyle
.GetUsage() == ScStyleSheet::USED
;
4743 bool ScDocument::ApplyFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4744 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, sal_Int16 nFlags
)
4746 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4748 return maTabs
[nTab
]->ApplyFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4750 OSL_FAIL("ApplyFlags: wrong table");
4755 bool ScDocument::RemoveFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4756 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, sal_Int16 nFlags
)
4758 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4760 return maTabs
[nTab
]->RemoveFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4762 OSL_FAIL("RemoveFlags: wrong table");
4767 void ScDocument::SetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
,
4770 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4772 maTabs
[nTab
]->SetPattern( nCol
, nRow
, rAttr
, bPutToPool
);
4776 void ScDocument::SetPattern( const ScAddress
& rPos
, const ScPatternAttr
& rAttr
,
4779 SCTAB nTab
= rPos
.Tab();
4780 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
4781 maTabs
[nTab
]->SetPattern( rPos
, rAttr
, bPutToPool
);
4785 ScPatternAttr
* ScDocument::CreateSelectionPattern( const ScMarkData
& rMark
, bool bDeep
)
4787 ScMergePatternState aState
;
4789 if ( rMark
.IsMultiMarked() ) // multi selection
4791 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4792 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4793 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4795 maTabs
[*itr
]->MergeSelectionPattern( aState
, rMark
, bDeep
);
4797 if ( rMark
.IsMarked() ) // simle selection
4800 rMark
.GetMarkArea(aRange
);
4801 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4802 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4803 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4805 maTabs
[*itr
]->MergePatternArea( aState
,
4806 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4807 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), bDeep
);
4810 OSL_ENSURE( aState
.pItemSet
, "SelectionPattern Null" );
4811 if (aState
.pItemSet
)
4812 return new ScPatternAttr( aState
.pItemSet
);
4814 return new ScPatternAttr( GetPool() ); // empty
4818 const ScPatternAttr
* ScDocument::GetSelectionPattern( const ScMarkData
& rMark
, bool bDeep
)
4820 delete pSelectionAttr
;
4821 pSelectionAttr
= CreateSelectionPattern( rMark
, bDeep
);
4822 return pSelectionAttr
;
4826 void ScDocument::GetSelectionFrame( const ScMarkData
& rMark
,
4827 SvxBoxItem
& rLineOuter
,
4828 SvxBoxInfoItem
& rLineInner
)
4830 rLineOuter
.SetLine(NULL
, BOX_LINE_TOP
);
4831 rLineOuter
.SetLine(NULL
, BOX_LINE_BOTTOM
);
4832 rLineOuter
.SetLine(NULL
, BOX_LINE_LEFT
);
4833 rLineOuter
.SetLine(NULL
, BOX_LINE_RIGHT
);
4834 rLineOuter
.SetDistance(0);
4836 rLineInner
.SetLine(NULL
, BOXINFO_LINE_HORI
);
4837 rLineInner
.SetLine(NULL
, BOXINFO_LINE_VERT
);
4838 rLineInner
.SetTable(true);
4839 rLineInner
.SetDist(true);
4840 rLineInner
.SetMinDist(false);
4844 if (rMark
.IsMarked())
4847 rMark
.GetMarkArea(aRange
);
4848 rLineInner
.EnableHor( aRange
.aStart
.Row() != aRange
.aEnd
.Row() );
4849 rLineInner
.EnableVer( aRange
.aStart
.Col() != aRange
.aEnd
.Col() );
4850 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4851 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4852 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4854 maTabs
[*itr
]->MergeBlockFrame( &rLineOuter
, &rLineInner
, aFlags
,
4855 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4856 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4859 // Don't care Status auswerten
4861 rLineInner
.SetValid( VALID_LEFT
, ( aFlags
.nLeft
!= SC_LINE_DONTCARE
) );
4862 rLineInner
.SetValid( VALID_RIGHT
, ( aFlags
.nRight
!= SC_LINE_DONTCARE
) );
4863 rLineInner
.SetValid( VALID_TOP
, ( aFlags
.nTop
!= SC_LINE_DONTCARE
) );
4864 rLineInner
.SetValid( VALID_BOTTOM
, ( aFlags
.nBottom
!= SC_LINE_DONTCARE
) );
4865 rLineInner
.SetValid( VALID_HORI
, ( aFlags
.nHori
!= SC_LINE_DONTCARE
) );
4866 rLineInner
.SetValid( VALID_VERT
, ( aFlags
.nVert
!= SC_LINE_DONTCARE
) );
4870 bool ScDocument::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
4871 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt16 nMask
) const
4873 if ( nMask
& HASATTR_ROTATE
)
4875 // Attribut im Dokument ueberhaupt verwendet?
4876 // (wie in fillinfo)
4878 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4880 bool bAnyItem
= false;
4881 sal_uInt32 nRotCount
= pPool
->GetItemCount2( ATTR_ROTATE_VALUE
);
4882 for (sal_uInt32 nItem
=0; nItem
<nRotCount
; nItem
++)
4884 const SfxPoolItem
* pItem
= pPool
->GetItem2( ATTR_ROTATE_VALUE
, nItem
);
4887 // 90 or 270 degrees is former SvxOrientationItem - only look for other values
4888 // (see ScPatternAttr::GetCellOrientation)
4889 sal_Int32 nAngle
= static_cast<const SfxInt32Item
*>(pItem
)->GetValue();
4890 if ( nAngle
!= 0 && nAngle
!= 9000 && nAngle
!= 27000 )
4898 nMask
&= ~HASATTR_ROTATE
;
4901 if ( nMask
& HASATTR_RTL
)
4903 // first check if right-to left is in the pool at all
4904 // (the same item is used in cell and page format)
4906 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4908 bool bHasRtl
= false;
4909 sal_uInt32 nDirCount
= pPool
->GetItemCount2( ATTR_WRITINGDIR
);
4910 for (sal_uInt32 nItem
=0; nItem
<nDirCount
; nItem
++)
4912 const SfxPoolItem
* pItem
= pPool
->GetItem2( ATTR_WRITINGDIR
, nItem
);
4913 if ( pItem
&& ((const SvxFrameDirectionItem
*)pItem
)->GetValue() == FRMDIR_HORI_RIGHT_TOP
)
4920 nMask
&= ~HASATTR_RTL
;
4926 bool bFound
= false;
4927 for (SCTAB i
=nTab1
; i
<=nTab2
&& !bFound
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
4930 if ( nMask
& HASATTR_RTL
)
4932 if ( GetEditTextDirection(i
) == EE_HTEXTDIR_R2L
) // sheet default
4935 if ( nMask
& HASATTR_RIGHTORCENTER
)
4937 // On a RTL sheet, don't start to look for the default left value
4938 // (which is then logically right), instead always assume true.
4939 // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
4941 if ( IsLayoutRTL(i
) )
4946 bFound
= maTabs
[i
]->HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, nMask
);
4952 bool ScDocument::HasAttrib( const ScRange
& rRange
, sal_uInt16 nMask
) const
4954 return HasAttrib( rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
4955 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
4959 void ScDocument::FindMaxRotCol( SCTAB nTab
, RowInfo
* pRowInfo
, SCSIZE nArrCount
,
4960 SCCOL nX1
, SCCOL nX2
) const
4962 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4963 maTabs
[nTab
]->FindMaxRotCol( pRowInfo
, nArrCount
, nX1
, nX2
);
4966 OSL_FAIL("FindMaxRotCol: wrong table");
4970 void ScDocument::GetBorderLines( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
4971 const SvxBorderLine
** ppLeft
, const SvxBorderLine
** ppTop
,
4972 const SvxBorderLine
** ppRight
, const SvxBorderLine
** ppBottom
) const
4974 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
4976 const SvxBoxItem
* pThisAttr
= (const SvxBoxItem
*) GetEffItem( nCol
, nRow
, nTab
, ATTR_BORDER
);
4977 OSL_ENSURE(pThisAttr
,"where is the attribute?");
4979 const SvxBorderLine
* pLeftLine
= pThisAttr
->GetLeft();
4980 const SvxBorderLine
* pTopLine
= pThisAttr
->GetTop();
4981 const SvxBorderLine
* pRightLine
= pThisAttr
->GetRight();
4982 const SvxBorderLine
* pBottomLine
= pThisAttr
->GetBottom();
4986 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4987 GetEffItem( nCol
-1, nRow
, nTab
, ATTR_BORDER
))->GetRight();
4988 if ( ScHasPriority( pOther
, pLeftLine
) )
4993 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4994 GetEffItem( nCol
, nRow
-1, nTab
, ATTR_BORDER
))->GetBottom();
4995 if ( ScHasPriority( pOther
, pTopLine
) )
4998 if ( nCol
< MAXCOL
)
5000 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
5001 GetEffItem( nCol
+1, nRow
, nTab
, ATTR_BORDER
))->GetLeft();
5002 if ( ScHasPriority( pOther
, pRightLine
) )
5003 pRightLine
= pOther
;
5005 if ( nRow
< MAXROW
)
5007 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
5008 GetEffItem( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
5009 if ( ScHasPriority( pOther
, pBottomLine
) )
5010 pBottomLine
= pOther
;
5014 *ppLeft
= pLeftLine
;
5018 *ppRight
= pRightLine
;
5020 *ppBottom
= pBottomLine
;
5023 bool ScDocument::IsBlockEmpty( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
5024 SCCOL nEndCol
, SCROW nEndRow
, bool bIgnoreNotes
) const
5026 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
5028 return maTabs
[nTab
]->IsBlockEmpty( nStartCol
, nStartRow
, nEndCol
, nEndRow
, bIgnoreNotes
);
5030 OSL_FAIL("wrong table number");
5035 void ScDocument::LockTable(SCTAB nTab
)
5037 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5038 maTabs
[nTab
]->LockTable();
5041 OSL_FAIL("wrong table number");
5046 void ScDocument::UnlockTable(SCTAB nTab
)
5048 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5049 maTabs
[nTab
]->UnlockTable();
5052 OSL_FAIL("wrong table number");
5057 bool ScDocument::IsBlockEditable( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
5058 SCCOL nEndCol
, SCROW nEndRow
,
5059 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
5061 // import into read-only document is possible
5062 if (!bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly())
5064 if ( pOnlyNotBecauseOfMatrix
)
5065 *pOnlyNotBecauseOfMatrix
= false;
5069 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
5071 return maTabs
[nTab
]->IsBlockEditable( nStartCol
, nStartRow
, nEndCol
,
5072 nEndRow
, pOnlyNotBecauseOfMatrix
);
5074 OSL_FAIL("wrong table number");
5075 if ( pOnlyNotBecauseOfMatrix
)
5076 *pOnlyNotBecauseOfMatrix
= false;
5081 bool ScDocument::IsSelectionEditable( const ScMarkData
& rMark
,
5082 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
5084 // import into read-only document is possible
5085 if ( !bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly() )
5087 if ( pOnlyNotBecauseOfMatrix
)
5088 *pOnlyNotBecauseOfMatrix
= false;
5093 rMark
.GetMarkArea(aRange
);
5096 bool bMatrix
= ( pOnlyNotBecauseOfMatrix
!= NULL
);
5097 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5098 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5099 for (; itr
!= itrEnd
&& *itr
< nMax
&& (bOk
|| bMatrix
); ++itr
)
5103 if (rMark
.IsMarked())
5105 if ( !maTabs
[*itr
]->IsBlockEditable( aRange
.aStart
.Col(),
5106 aRange
.aStart
.Row(), aRange
.aEnd
.Col(),
5107 aRange
.aEnd
.Row(), pOnlyNotBecauseOfMatrix
) )
5110 if ( pOnlyNotBecauseOfMatrix
)
5111 bMatrix
= *pOnlyNotBecauseOfMatrix
;
5114 if (rMark
.IsMultiMarked())
5116 if ( !maTabs
[*itr
]->IsSelectionEditable( rMark
, pOnlyNotBecauseOfMatrix
) )
5119 if ( pOnlyNotBecauseOfMatrix
)
5120 bMatrix
= *pOnlyNotBecauseOfMatrix
;
5126 if ( pOnlyNotBecauseOfMatrix
)
5127 *pOnlyNotBecauseOfMatrix
= ( !bOk
&& bMatrix
);
5133 bool ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol
, SCROW nStartRow
,
5134 SCCOL nEndCol
, SCROW nEndRow
,
5135 const ScMarkData
& rMark
) const
5138 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5139 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5140 for (; itr
!= itrEnd
&& *itr
< nMax
&& bOk
; ++itr
)
5142 if (maTabs
[*itr
]->HasBlockMatrixFragment( nStartCol
, nStartRow
, nEndCol
, nEndRow
))
5148 bool ScDocument::GetMatrixFormulaRange( const ScAddress
& rCellPos
, ScRange
& rMatrix
)
5150 // if rCell is part of a matrix formula, return its complete range
5152 ScFormulaCell
* pFCell
= GetFormulaCell(rCellPos
);
5154 // not a formula cell. Bail out.
5157 ScAddress aOrigin
= rCellPos
;
5158 if (!pFCell
->GetMatrixOrigin(aOrigin
))
5159 // Failed to get the address of the matrix origin.
5162 if (aOrigin
!= rCellPos
)
5164 pFCell
= GetFormulaCell(aOrigin
);
5166 // The matrix origin cell is not a formula cell !? Something is up...
5172 pFCell
->GetMatColsRows(nSizeX
, nSizeY
);
5173 if (nSizeX
<= 0 || nSizeY
<= 0)
5175 // GetMatrixEdge computes also dimensions of the matrix
5176 // if not already done (may occur if document is loaded
5177 // from old file format).
5178 // Needs an "invalid" initialized address.
5179 aOrigin
.SetInvalid();
5180 pFCell
->GetMatrixEdge(aOrigin
);
5181 pFCell
->GetMatColsRows(nSizeX
, nSizeY
);
5184 if (nSizeX
<= 0 || nSizeY
<= 0)
5185 // Matrix size is still invalid. Give up.
5188 ScAddress
aEnd( aOrigin
.Col() + nSizeX
- 1,
5189 aOrigin
.Row() + nSizeY
- 1,
5192 rMatrix
.aStart
= aOrigin
;
5193 rMatrix
.aEnd
= aEnd
;
5199 bool ScDocument::ExtendOverlapped( SCCOL
& rStartCol
, SCROW
& rStartRow
,
5200 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
) const
5202 bool bFound
= false;
5203 if ( ValidColRow(rStartCol
,rStartRow
) && ValidColRow(nEndCol
,nEndRow
) && ValidTab(nTab
) )
5205 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5208 SCCOL nOldCol
= rStartCol
;
5209 SCROW nOldRow
= rStartRow
;
5210 for (nCol
=nOldCol
; nCol
<=nEndCol
; nCol
++)
5211 while (((ScMergeFlagAttr
*)GetAttr(nCol
,rStartRow
,nTab
,ATTR_MERGE_FLAG
))->
5217 ScAttrArray
* pAttrArray
= maTabs
[nTab
]->aCol
[nOldCol
].pAttrArray
;
5219 pAttrArray
->Search( nOldRow
, nIndex
);
5220 SCROW nAttrPos
= nOldRow
;
5221 while (nAttrPos
<=nEndRow
)
5223 OSL_ENSURE( nIndex
< pAttrArray
->nCount
, "Wrong index in AttrArray" );
5225 if (((ScMergeFlagAttr
&)pAttrArray
->pData
[nIndex
].pPattern
->
5226 GetItem(ATTR_MERGE_FLAG
)).IsHorOverlapped())
5228 SCROW nLoopEndRow
= std::min( nEndRow
, pAttrArray
->pData
[nIndex
].nRow
);
5229 for (SCROW nAttrRow
= nAttrPos
; nAttrRow
<= nLoopEndRow
; nAttrRow
++)
5231 SCCOL nTempCol
= nOldCol
;
5234 while (((ScMergeFlagAttr
*)GetAttr(nTempCol
,nAttrRow
,nTab
,ATTR_MERGE_FLAG
))
5235 ->IsHorOverlapped());
5236 if (nTempCol
< rStartCol
)
5237 rStartCol
= nTempCol
;
5240 nAttrPos
= pAttrArray
->pData
[nIndex
].nRow
+ 1;
5247 OSL_FAIL("ExtendOverlapped: invalid range");
5254 bool ScDocument::ExtendMergeSel( SCCOL nStartCol
, SCROW nStartRow
,
5255 SCCOL
& rEndCol
, SCROW
& rEndRow
,
5256 const ScMarkData
& rMark
, bool bRefresh
)
5258 // use all selected sheets from rMark
5260 bool bFound
= false;
5261 SCCOL nOldEndCol
= rEndCol
;
5262 SCROW nOldEndRow
= rEndRow
;
5264 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5265 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5266 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5269 SCCOL nThisEndCol
= nOldEndCol
;
5270 SCROW nThisEndRow
= nOldEndRow
;
5271 if ( ExtendMerge( nStartCol
, nStartRow
, nThisEndCol
, nThisEndRow
, *itr
, bRefresh
) )
5273 if ( nThisEndCol
> rEndCol
)
5274 rEndCol
= nThisEndCol
;
5275 if ( nThisEndRow
> rEndRow
)
5276 rEndRow
= nThisEndRow
;
5283 bool ScDocument::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
5284 SCCOL
& rEndCol
, SCROW
& rEndRow
,
5285 SCTAB nTab
, bool bRefresh
)
5287 bool bFound
= false;
5288 if ( ValidColRow(nStartCol
,nStartRow
) && ValidColRow(rEndCol
,rEndRow
) && ValidTab(nTab
) )
5290 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5291 bFound
= maTabs
[nTab
]->ExtendMerge( nStartCol
, nStartRow
, rEndCol
, rEndRow
, bRefresh
);
5294 RefreshAutoFilter( nStartCol
, nStartRow
, rEndCol
, rEndRow
, nTab
);
5298 OSL_FAIL("ExtendMerge: invalid range");
5305 bool ScDocument::ExtendMerge( ScRange
& rRange
, bool bRefresh
)
5307 bool bFound
= false;
5308 SCTAB nStartTab
= rRange
.aStart
.Tab();
5309 SCTAB nEndTab
= rRange
.aEnd
.Tab();
5310 SCCOL nEndCol
= rRange
.aEnd
.Col();
5311 SCROW nEndRow
= rRange
.aEnd
.Row();
5313 PutInOrder( nStartTab
, nEndTab
);
5314 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
5316 SCCOL nExtendCol
= rRange
.aEnd
.Col();
5317 SCROW nExtendRow
= rRange
.aEnd
.Row();
5318 if (ExtendMerge( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
5319 nExtendCol
, nExtendRow
,
5323 if (nExtendCol
> nEndCol
) nEndCol
= nExtendCol
;
5324 if (nExtendRow
> nEndRow
) nEndRow
= nExtendRow
;
5328 rRange
.aEnd
.SetCol(nEndCol
);
5329 rRange
.aEnd
.SetRow(nEndRow
);
5334 bool ScDocument::ExtendTotalMerge( ScRange
& rRange
) const
5336 // Bereich genau dann auf zusammengefasste Zellen erweitern, wenn
5337 // dadurch keine neuen nicht-ueberdeckten Zellen getroffen werden
5340 ScRange aExt
= rRange
;
5341 // ExtendMerge() is non-const, but called withouth refresh.
5342 if (const_cast<ScDocument
*>(this)->ExtendMerge( aExt
, false))
5344 if ( aExt
.aEnd
.Row() > rRange
.aEnd
.Row() )
5346 ScRange aTest
= aExt
;
5347 aTest
.aStart
.SetRow( rRange
.aEnd
.Row() + 1 );
5348 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
5349 aExt
.aEnd
.SetRow(rRange
.aEnd
.Row());
5351 if ( aExt
.aEnd
.Col() > rRange
.aEnd
.Col() )
5353 ScRange aTest
= aExt
;
5354 aTest
.aStart
.SetCol( rRange
.aEnd
.Col() + 1 );
5355 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
5356 aExt
.aEnd
.SetCol(rRange
.aEnd
.Col());
5359 bRet
= ( aExt
.aEnd
!= rRange
.aEnd
);
5365 bool ScDocument::ExtendOverlapped( ScRange
& rRange
) const
5367 bool bFound
= false;
5368 SCTAB nStartTab
= rRange
.aStart
.Tab();
5369 SCTAB nEndTab
= rRange
.aEnd
.Tab();
5370 SCCOL nStartCol
= rRange
.aStart
.Col();
5371 SCROW nStartRow
= rRange
.aStart
.Row();
5373 PutInOrder( nStartTab
, nEndTab
);
5374 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
5376 SCCOL nExtendCol
= rRange
.aStart
.Col();
5377 SCROW nExtendRow
= rRange
.aStart
.Row();
5378 ExtendOverlapped( nExtendCol
, nExtendRow
,
5379 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), nTab
);
5380 if (nExtendCol
< nStartCol
)
5382 nStartCol
= nExtendCol
;
5385 if (nExtendRow
< nStartRow
)
5387 nStartRow
= nExtendRow
;
5392 rRange
.aStart
.SetCol(nStartCol
);
5393 rRange
.aStart
.SetRow(nStartRow
);
5398 bool ScDocument::RefreshAutoFilter( SCCOL nStartCol
, SCROW nStartRow
,
5399 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
5407 // Autofilter loeschen
5409 bool bChange
= RemoveFlagsTab( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
, SC_MF_AUTO
);
5411 // Autofilter setzen
5413 const ScDBData
* pData
= NULL
;
5414 ScDBCollection::NamedDBs
& rDBs
= pDBCollection
->getNamedDBs();
5415 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
5416 for (; itr
!= itrEnd
; ++itr
)
5418 if (itr
->HasAutoFilter())
5420 itr
->GetArea( nDBTab
, nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBEndRow
);
5421 if ( nDBTab
==nTab
&& nDBStartRow
<=nEndRow
&& nDBEndRow
>=nStartRow
&&
5422 nDBStartCol
<=nEndCol
&& nDBEndCol
>=nStartCol
)
5424 if (ApplyFlagsTab( nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBStartRow
,
5425 nDBTab
, SC_MF_AUTO
))
5430 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5431 pData
= maTabs
[nTab
]->GetAnonymousDBData();
5436 if (pData
->HasAutoFilter())
5438 pData
->GetArea( nDBTab
, nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBEndRow
);
5439 if ( nDBTab
==nTab
&& nDBStartRow
<=nEndRow
&& nDBEndRow
>=nStartRow
&&
5440 nDBStartCol
<=nEndCol
&& nDBEndCol
>=nStartCol
)
5442 if (ApplyFlagsTab( nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBStartRow
,
5443 nDBTab
, SC_MF_AUTO
))
5451 void ScDocument::SkipOverlapped( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
) const
5453 while (IsHorOverlapped(rCol
, rRow
, nTab
))
5455 while (IsVerOverlapped(rCol
, rRow
, nTab
))
5459 bool ScDocument::IsHorOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
5461 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
5462 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
5464 return pAttr
->IsHorOverlapped();
5467 OSL_FAIL("Overlapped: Attr==0");
5473 bool ScDocument::IsVerOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
5475 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
5476 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
5478 return pAttr
->IsVerOverlapped();
5481 OSL_FAIL("Overlapped: Attr==0");
5487 void ScDocument::ApplySelectionFrame( const ScMarkData
& rMark
,
5488 const SvxBoxItem
* pLineOuter
,
5489 const SvxBoxInfoItem
* pLineInner
)
5491 ScRangeList aRangeList
;
5492 rMark
.FillRangeListWithMarks( &aRangeList
, false );
5493 size_t nRangeCount
= aRangeList
.size();
5494 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5495 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5496 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5500 for ( size_t j
=0; j
< nRangeCount
; j
++ )
5502 ScRange aRange
= *aRangeList
[ j
];
5503 maTabs
[*itr
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
5504 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
5505 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
5512 void ScDocument::ApplyFrameAreaTab( const ScRange
& rRange
,
5513 const SvxBoxItem
* pLineOuter
,
5514 const SvxBoxInfoItem
* pLineInner
)
5516 SCTAB nStartTab
= rRange
.aStart
.Tab();
5517 SCTAB nEndTab
= rRange
.aStart
.Tab();
5518 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
5520 maTabs
[nTab
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
5521 rRange
.aStart
.Col(), rRange
.aStart
.Row(),
5522 rRange
.aEnd
.Col(), rRange
.aEnd
.Row() );
5526 void ScDocument::ApplySelectionPattern( const ScPatternAttr
& rAttr
, const ScMarkData
& rMark
, ScEditDataArray
* pDataArray
)
5528 const SfxItemSet
* pSet
= &rAttr
.GetItemSet();
5531 for (i
=ATTR_PATTERN_START
; i
<=ATTR_PATTERN_END
&& !bSet
; i
++)
5532 if (pSet
->GetItemState(i
) == SFX_ITEM_SET
)
5537 // ApplySelectionCache needs multi mark
5538 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
5541 rMark
.GetMarkArea( aRange
);
5542 ApplyPatternArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
5543 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rAttr
, pDataArray
);
5547 SfxItemPoolCache
aCache( xPoolHelper
->GetDocPool(), pSet
);
5548 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5549 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5550 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5552 maTabs
[*itr
]->ApplySelectionCache( &aCache
, rMark
, pDataArray
);
5558 void ScDocument::ChangeSelectionIndent( bool bIncrement
, const ScMarkData
& rMark
)
5560 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5561 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5562 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5564 maTabs
[*itr
]->ChangeSelectionIndent( bIncrement
, rMark
);
5568 void ScDocument::ClearSelectionItems( const sal_uInt16
* pWhich
, const ScMarkData
& rMark
)
5570 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5571 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5572 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5574 maTabs
[*itr
]->ClearSelectionItems( pWhich
, rMark
);
5578 void ScDocument::DeleteSelection( sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
5580 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5581 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5582 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5584 maTabs
[*itr
]->DeleteSelection( nDelFlag
, rMark
);
5588 void ScDocument::DeleteSelectionTab( SCTAB nTab
, sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
5590 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5591 maTabs
[nTab
]->DeleteSelection( nDelFlag
, rMark
);
5594 OSL_FAIL("wrong table");
5599 ScPatternAttr
* ScDocument::GetDefPattern() const
5601 return (ScPatternAttr
*) &xPoolHelper
->GetDocPool()->GetDefaultItem(ATTR_PATTERN
);
5605 ScDocumentPool
* ScDocument::GetPool()
5607 return xPoolHelper
->GetDocPool();
5612 ScStyleSheetPool
* ScDocument::GetStyleSheetPool() const
5614 return xPoolHelper
->GetStylePool();
5618 SCSIZE
ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol
, SCROW nStartRow
, SCTAB nStartTab
,
5619 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nEndTab
, ScDirection eDir
)
5621 PutInOrder(nStartCol
, nEndCol
);
5622 PutInOrder(nStartRow
, nEndRow
);
5623 PutInOrder(nStartTab
, nEndTab
);
5624 if (ValidTab(nStartTab
) && nStartTab
< static_cast<SCTAB
>(maTabs
.size()))
5626 if (maTabs
[nStartTab
])
5627 return maTabs
[nStartTab
]->GetEmptyLinesInBlock(nStartCol
, nStartRow
, nEndCol
, nEndRow
, eDir
);
5636 void ScDocument::FindAreaPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, ScMoveDirection eDirection
) const
5638 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5639 maTabs
[nTab
]->FindAreaPos( rCol
, rRow
, eDirection
);
5643 void ScDocument::GetNextPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, SCsCOL nMovX
, SCsROW nMovY
,
5644 bool bMarked
, bool bUnprotected
, const ScMarkData
& rMark
) const
5646 OSL_ENSURE( !nMovX
|| !nMovY
, "GetNextPos: only X or Y" );
5648 ScMarkData aCopyMark
= rMark
;
5649 aCopyMark
.SetMarking(false);
5650 aCopyMark
.MarkToMulti();
5652 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5653 maTabs
[nTab
]->GetNextPos( rCol
, rRow
, nMovX
, nMovY
, bMarked
, bUnprotected
, aCopyMark
);
5657 // Datei-Operationen
5661 void ScDocument::UpdStlShtPtrsFrmNms()
5663 ScPatternAttr::pDoc
= this;
5665 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
5667 sal_uInt32 nCount
= pPool
->GetItemCount2(ATTR_PATTERN
);
5668 ScPatternAttr
* pPattern
;
5669 for (sal_uInt32 i
=0; i
<nCount
; i
++)
5671 pPattern
= (ScPatternAttr
*)pPool
->GetItem2(ATTR_PATTERN
, i
);
5673 pPattern
->UpdateStyleSheet();
5675 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).UpdateStyleSheet();
5679 void ScDocument::StylesToNames()
5681 ScPatternAttr::pDoc
= this;
5683 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
5685 sal_uInt32 nCount
= pPool
->GetItemCount2(ATTR_PATTERN
);
5686 ScPatternAttr
* pPattern
;
5687 for (sal_uInt32 i
=0; i
<nCount
; i
++)
5689 pPattern
= (ScPatternAttr
*)pPool
->GetItem2(ATTR_PATTERN
, i
);
5691 pPattern
->StyleToName();
5693 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).StyleToName();
5697 sal_uLong
ScDocument::GetCellCount() const
5699 sal_uLong nCellCount
= 0L;
5701 TableContainer::const_iterator it
= maTabs
.begin();
5702 for (; it
!= maTabs
.end(); ++it
)
5704 nCellCount
+= (*it
)->GetCellCount();
5709 SCSIZE
ScDocument::GetCellCount(SCTAB nTab
, SCCOL nCol
) const
5711 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
5714 return maTabs
[nTab
]->GetCellCount(nCol
);
5717 sal_uLong
ScDocument::GetCodeCount() const
5719 sal_uLong nCodeCount
= 0;
5721 TableContainer::const_iterator it
= maTabs
.begin();
5722 for (; it
!= maTabs
.end(); ++it
)
5724 nCodeCount
+= (*it
)->GetCodeCount();
5730 void ScDocument::PageStyleModified( SCTAB nTab
, const OUString
& rNewName
)
5732 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5733 maTabs
[nTab
]->PageStyleModified( rNewName
);
5737 void ScDocument::SetPageStyle( SCTAB nTab
, const OUString
& rName
)
5739 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5740 maTabs
[nTab
]->SetPageStyle( rName
);
5744 const OUString
ScDocument::GetPageStyle( SCTAB nTab
) const
5746 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5747 return maTabs
[nTab
]->GetPageStyle();
5753 void ScDocument::SetPageSize( SCTAB nTab
, const Size
& rSize
)
5755 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5756 maTabs
[nTab
]->SetPageSize( rSize
);
5759 Size
ScDocument::GetPageSize( SCTAB nTab
) const
5761 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5762 return maTabs
[nTab
]->GetPageSize();
5764 OSL_FAIL("invalid tab");
5769 void ScDocument::SetRepeatArea( SCTAB nTab
, SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCROW nEndRow
)
5771 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5772 maTabs
[nTab
]->SetRepeatArea( nStartCol
, nEndCol
, nStartRow
, nEndRow
);
5775 void ScDocument::InvalidatePageBreaks(SCTAB nTab
)
5777 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5778 maTabs
[nTab
]->InvalidatePageBreaks();
5781 void ScDocument::UpdatePageBreaks( SCTAB nTab
, const ScRange
* pUserArea
)
5783 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5784 maTabs
[nTab
]->UpdatePageBreaks( pUserArea
);
5787 void ScDocument::RemoveManualBreaks( SCTAB nTab
)
5789 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5790 maTabs
[nTab
]->RemoveManualBreaks();
5793 bool ScDocument::HasManualBreaks( SCTAB nTab
) const
5795 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5796 return maTabs
[nTab
]->HasManualBreaks();
5798 OSL_FAIL("invalid tab");
5803 void ScDocument::GetDocStat( ScDocStat
& rDocStat
)
5805 rDocStat
.nTableCount
= GetTableCount();
5806 rDocStat
.aDocName
= aDocName
;
5807 rDocStat
.nCellCount
= GetCellCount();
5811 bool ScDocument::HasPrintRange()
5813 bool bResult
= false;
5815 TableContainer::iterator it
= maTabs
.begin();
5816 for (; it
!= maTabs
.end() && !bResult
; ++it
)
5818 bResult
= (*it
)->IsPrintEntireSheet() || ((*it
)->GetPrintRangeCount() > 0);
5824 bool ScDocument::IsPrintEntireSheet( SCTAB nTab
) const
5826 return (ValidTab(nTab
) ) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsPrintEntireSheet();
5830 sal_uInt16
ScDocument::GetPrintRangeCount( SCTAB nTab
)
5832 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5833 return maTabs
[nTab
]->GetPrintRangeCount();
5839 const ScRange
* ScDocument::GetPrintRange( SCTAB nTab
, sal_uInt16 nPos
)
5841 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5842 return maTabs
[nTab
]->GetPrintRange(nPos
);
5848 const ScRange
* ScDocument::GetRepeatColRange( SCTAB nTab
)
5850 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5851 return maTabs
[nTab
]->GetRepeatColRange();
5857 const ScRange
* ScDocument::GetRepeatRowRange( SCTAB nTab
)
5859 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5860 return maTabs
[nTab
]->GetRepeatRowRange();
5866 void ScDocument::ClearPrintRanges( SCTAB nTab
)
5868 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5869 maTabs
[nTab
]->ClearPrintRanges();
5873 void ScDocument::AddPrintRange( SCTAB nTab
, const ScRange
& rNew
)
5875 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5876 maTabs
[nTab
]->AddPrintRange( rNew
);
5880 void ScDocument::SetPrintEntireSheet( SCTAB nTab
)
5882 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5883 maTabs
[nTab
]->SetPrintEntireSheet();
5887 void ScDocument::SetRepeatColRange( SCTAB nTab
, const ScRange
* pNew
)
5889 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5890 maTabs
[nTab
]->SetRepeatColRange( pNew
);
5894 void ScDocument::SetRepeatRowRange( SCTAB nTab
, const ScRange
* pNew
)
5896 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5897 maTabs
[nTab
]->SetRepeatRowRange( pNew
);
5901 ScPrintRangeSaver
* ScDocument::CreatePrintRangeSaver() const
5903 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
5904 ScPrintRangeSaver
* pNew
= new ScPrintRangeSaver( nCount
);
5905 for (SCTAB i
=0; i
<nCount
; i
++)
5907 maTabs
[i
]->FillPrintSaver( pNew
->GetTabData(i
) );
5912 void ScDocument::RestorePrintRanges( const ScPrintRangeSaver
& rSaver
)
5914 SCTAB nCount
= rSaver
.GetTabCount();
5915 for (SCTAB i
=0; i
<nCount
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
5917 maTabs
[i
]->RestorePrintRanges( rSaver
.GetTabData(i
) );
5921 bool ScDocument::NeedPageResetAfterTab( SCTAB nTab
) const
5923 // Die Seitennummern-Zaehlung faengt bei einer Tabelle neu an, wenn eine
5924 // andere Vorlage als bei der vorherigen gesetzt ist (nur Namen vergleichen)
5925 // und eine Seitennummer angegeben ist (nicht 0)
5927 if ( nTab
+ 1 < static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
+1] )
5929 OUString aNew
= maTabs
[nTab
+1]->GetPageStyle();
5930 if ( aNew
!= maTabs
[nTab
]->GetPageStyle() )
5932 SfxStyleSheetBase
* pStyle
= xPoolHelper
->GetStylePool()->Find( aNew
, SFX_STYLE_FAMILY_PAGE
);
5935 const SfxItemSet
& rSet
= pStyle
->GetItemSet();
5936 sal_uInt16 nFirst
= ((const SfxUInt16Item
&)rSet
.Get(ATTR_PAGE_FIRSTPAGENO
)).GetValue();
5938 return true; // Seitennummer in neuer Vorlage angegeben
5943 return false; // sonst nicht
5946 SfxUndoManager
* ScDocument::GetUndoManager()
5950 // to support enhanced text edit for draw objects, use an SdrUndoManager
5951 mpUndoManager
= new SdrUndoManager
;
5954 return mpUndoManager
;
5957 ScRowBreakIterator
* ScDocument::GetRowBreakIterator(SCTAB nTab
) const
5959 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5960 return new ScRowBreakIterator(maTabs
[nTab
]->maRowPageBreaks
);
5964 void ScDocument::AddSubTotalCell(ScFormulaCell
* pCell
)
5966 maSubTotalCells
.insert(pCell
);
5969 void ScDocument::RemoveSubTotalCell(ScFormulaCell
* pCell
)
5971 maSubTotalCells
.erase(pCell
);
5976 bool lcl_hasDirtyRange(ScFormulaCell
* pCell
, const ScRange
& rDirtyRange
)
5978 ScDetectiveRefIter
aRefIter(pCell
);
5980 while (aRefIter
.GetNextRef(aRange
))
5982 if (aRange
.Intersects(rDirtyRange
))
5990 void ScDocument::SetSubTotalCellsDirty(const ScRange
& rDirtyRange
)
5992 // to update the list by skipping cells that no longer contain subtotal function.
5993 set
<ScFormulaCell
*> aNewSet
;
5995 bool bOldRecalc
= GetAutoCalc();
5997 set
<ScFormulaCell
*>::iterator itr
= maSubTotalCells
.begin(), itrEnd
= maSubTotalCells
.end();
5998 for (; itr
!= itrEnd
; ++itr
)
6000 ScFormulaCell
* pCell
= *itr
;
6001 if (pCell
->IsSubTotal())
6003 aNewSet
.insert(pCell
);
6004 if (lcl_hasDirtyRange(pCell
, rDirtyRange
))
6009 SetAutoCalc(bOldRecalc
);
6010 maSubTotalCells
.swap(aNewSet
); // update the list.
6013 void ScDocument::MarkSubTotalCells( sc::ColumnSpanSet
& rSet
, const ScRange
& rRange
, bool bVal
) const
6015 for (SCTAB nTab
= rRange
.aStart
.Tab(); nTab
<= rRange
.aEnd
.Tab(); ++nTab
)
6017 const ScTable
* pTab
= FetchTable(nTab
);
6021 pTab
->MarkSubTotalCells(
6022 rSet
, rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), bVal
);
6026 sal_uInt16
ScDocument::GetTextWidth( const ScAddress
& rPos
) const
6028 SCTAB nTab
= rPos
.Tab();
6029 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
6030 return maTabs
[nTab
]->GetTextWidth(rPos
.Col(), rPos
.Row());
6035 sal_uInt8
ScDocument::GetScriptType( const ScAddress
& rPos
) const
6037 SCTAB nTab
= rPos
.Tab();
6038 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
6039 return maTabs
[nTab
]->GetScriptType(rPos
.Col(), rPos
.Row());
6044 void ScDocument::SetScriptType( const ScAddress
& rPos
, sal_uInt8 nType
)
6046 SCTAB nTab
= rPos
.Tab();
6047 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
6048 maTabs
[nTab
]->SetScriptType(rPos
.Col(), rPos
.Row(), nType
);
6051 void ScDocument::EnableUndo( bool bVal
)
6053 // The undo manager increases lock count every time undo is disabled.
6054 // Because of this, we shouldn't disable undo unless it's currently
6055 // enabled, or else re-enabling it may not actually re-enable undo unless
6056 // the lock count becomes zero.
6058 if (bVal
!= GetUndoManager()->IsUndoEnabled())
6060 GetUndoManager()->EnableUndo(bVal
);
6061 if( pDrawLayer
) pDrawLayer
->EnableUndo(bVal
);
6064 mbUndoEnabled
= bVal
;
6067 bool ScDocument::IsUserInteractionEnabled() const
6069 return mbUserInteractionEnabled
;
6072 void ScDocument::EnableUserInteraction( bool bVal
)
6074 mbUserInteractionEnabled
= bVal
;
6077 bool ScDocument::IsInVBAMode() const
6084 uno::Reference
<script::vba::XVBACompatibility
> xVBA(
6085 pShell
->GetBasicContainer(), uno::UNO_QUERY
);
6087 return xVBA
.is() && xVBA
->getVBACompatibilityMode();
6089 catch (const lang::NotInitializedException
&) {}
6094 ScPostIt
* ScDocument::GetNote(const ScAddress
& rPos
)
6096 return GetNote(rPos
.Col(), rPos
.Row(), rPos
.Tab());
6099 ScPostIt
* ScDocument::GetNote(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
6101 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
6102 return maTabs
[nTab
]->aCol
[nCol
].GetCellNote(nRow
);
6108 void ScDocument::SetNote(const ScAddress
& rPos
, ScPostIt
* pNote
)
6110 return SetNote(rPos
.Col(), rPos
.Row(), rPos
.Tab(), pNote
);
6113 void ScDocument::SetNote(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, ScPostIt
* pNote
)
6115 return maTabs
[nTab
]->aCol
[nCol
].SetCellNote(nRow
, pNote
);
6118 bool ScDocument::HasNote(const ScAddress
& rPos
)
6120 return HasNote(rPos
.Col(), rPos
.Row(), rPos
.Tab());
6122 bool ScDocument::HasNote(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
6124 ScPostIt
* pNote
= maTabs
[nTab
]->aCol
[nCol
].GetCellNote(nRow
);
6125 return pNote
!= NULL
;
6127 bool ScDocument::HasColNotes(SCCOL nCol
, SCTAB nTab
)
6129 return maTabs
[nTab
]->aCol
[nCol
].HasCellNotes();
6132 bool ScDocument::HasTabNotes(SCTAB nTab
)
6134 bool hasNotes
= false;
6135 for (SCCOL nCol
=0; nCol
<MAXCOLCOUNT
&& !hasNotes
; ++nCol
)
6136 hasNotes
= HasColNotes(nCol
, nTab
);
6141 ScPostIt
* ScDocument::ReleaseNote(const ScAddress
& rPos
)
6143 return ReleaseNote(rPos
.Col(), rPos
.Row(), rPos
.Tab());
6145 ScPostIt
* ScDocument::ReleaseNote(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
6148 ScPostIt
* pPostIt
= GetNote(nCol
, nRow
, nTab
);
6149 if (pPostIt
!= NULL
)
6150 maTabs
[nTab
]->aCol
[nCol
].DeleteCellNote(nRow
);
6155 ScPostIt
* ScDocument::GetOrCreateNote(const ScAddress
& rPos
)
6158 return GetNote(rPos
);
6160 return CreateNote(rPos
);
6162 ScPostIt
* ScDocument::CreateNote(const ScAddress
& rPos
)
6164 ScPostIt
* pPostIt
= new ScPostIt(*this, rPos
, false);
6165 SetNote(rPos
, pPostIt
);
6169 size_t ScDocument::CountNotes() const
6172 SCTAB nTabCount
= GetTableCount();
6173 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
6175 for (SCCOL nCol
=0; nCol
<MAXCOLCOUNT
; nCol
++)
6176 nCount
+= GetNoteCount(nTab
, nCol
);
6181 size_t ScDocument::GetNoteCount( SCTAB nTab
, SCCOL nCol
) const
6183 const ScTable
* pTab
= FetchTable(nTab
);
6187 return pTab
->GetNoteCount(nCol
);
6190 ScAddress
ScDocument::GetNotePosition( size_t nIndex
) const
6192 for (size_t nTab
= 0; nTab
< maTabs
.size(); ++nTab
)
6194 for (SCCOL nCol
=0; nCol
<MAXCOLCOUNT
; nCol
++)
6196 size_t nColNoteCount
= GetNoteCount(nTab
, nCol
);
6200 if (nIndex
>= nColNoteCount
)
6202 nIndex
-= nColNoteCount
;
6206 SCROW nRow
= GetNotePosition(nTab
, nCol
, nIndex
);
6208 return ScAddress(nCol
, nRow
, nTab
);
6210 OSL_FAIL("note not found");
6211 return ScAddress(ScAddress::INITIALIZE_INVALID
);
6215 OSL_FAIL("note not found");
6216 return ScAddress(ScAddress::INITIALIZE_INVALID
);
6219 SCROW
ScDocument::GetNotePosition( SCTAB nTab
, SCCOL nCol
, size_t nIndex
) const
6221 const ScTable
* pTab
= FetchTable(nTab
);
6225 return pTab
->GetNotePosition(nCol
, nIndex
);
6228 void ScDocument::GetAllNoteEntries( std::vector
<sc::NoteEntry
>& rNotes
) const
6230 for (size_t nTab
= 0; nTab
< maTabs
.size(); ++nTab
)
6232 const ScTable
* pTab
= maTabs
[nTab
];
6236 pTab
->GetAllNoteEntries(rNotes
);
6240 void ScDocument::GetNotesInRange( const ScRangeList
& rRange
, std::vector
<sc::NoteEntry
>& rNotes
) const
6242 for( size_t i
= 0; i
< rRange
.size(); ++i
)
6244 const ScRange
* pRange
= rRange
[i
];
6245 for( SCTAB nTab
= pRange
->aStart
.Tab(); nTab
<= pRange
->aEnd
.Tab(); ++nTab
)
6247 maTabs
[nTab
]->GetNotesInRange( *pRange
, rNotes
);
6252 bool ScDocument::ContainsNotesInRange( const ScRangeList
& rRange
) const
6254 for( size_t i
= 0; i
< rRange
.size(); ++i
)
6256 const ScRange
* pRange
= rRange
[i
];
6257 for( SCTAB nTab
= pRange
->aStart
.Tab(); nTab
< pRange
->aEnd
.Tab(); ++nTab
)
6259 bool bContainsNote
= maTabs
[nTab
]->ContainsNotesInRange( *pRange
);
6268 void ScDocument::SetAutoNameCache( ScAutoNameCache
* pCache
)
6270 delete pAutoNameCache
;
6271 pAutoNameCache
= pCache
;
6274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */