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/svditer.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svx/svdocapt.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <svl/poolcach.hxx>
35 #include <unotools/saveopt.hxx>
36 #include <svl/zforlist.hxx>
37 #include <unotools/charclass.hxx>
38 #include <unotools/transliterationwrapper.hxx>
39 #include <tools/tenccvt.hxx>
40 #include <tools/urlobj.hxx>
42 #include <com/sun/star/text/WritingMode2.hpp>
43 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
44 #include <com/sun/star/sheet/TablePageBreakData.hpp>
45 #include <com/sun/star/lang/NotInitializedException.hpp>
47 #include "document.hxx"
50 #include "attarray.hxx"
51 #include "markarr.hxx"
52 #include "patattr.hxx"
53 #include "rangenam.hxx"
54 #include "poolhelp.hxx"
55 #include "docpool.hxx"
56 #include "stlpool.hxx"
57 #include "stlsheet.hxx"
58 #include "globstr.hrc"
59 #include "rechead.hxx"
62 #include "chartlis.hxx"
63 #include "rangelst.hxx"
64 #include "markdata.hxx"
65 #include "drwlayer.hxx"
66 #include "conditio.hxx"
67 #include "colorscale.hxx"
68 #include "validat.hxx"
69 #include "prnsave.hxx"
70 #include "chgtrack.hxx"
72 #include "scresid.hxx"
74 #include "detdata.hxx"
76 #include "dpobject.hxx"
77 #include "detfunc.hxx" // for UpdateAllComments
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"
98 #include <boost/scoped_ptr.hpp>
100 using ::editeng::SvxBorderLine
;
101 using namespace ::com::sun::star
;
103 namespace WritingMode2
= ::com::sun::star::text::WritingMode2
;
104 using ::com::sun::star::uno::Sequence
;
105 using ::com::sun::star::sheet::TablePageBreakData
;
110 std::pair
<SCTAB
,SCTAB
> getMarkedTableRange(const std::vector
<ScTable
*>& rTables
, const ScMarkData
& rMark
)
112 SCTAB nTabStart
= MAXTAB
;
114 SCTAB nMax
= static_cast<SCTAB
>(rTables
.size());
115 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
116 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
121 if (*itr
< nTabStart
)
126 return std::pair
<SCTAB
,SCTAB
>(nTabStart
,nTabEnd
);
133 const ScPatternAttr
* pAttr
;
136 ScDefaultAttr(const ScPatternAttr
* pPatAttr
) : pAttr(pPatAttr
), nFirst(0), nCount(0) {}
139 struct ScLessDefaultAttr
141 bool operator() (const ScDefaultAttr
& rValue1
, const ScDefaultAttr
& rValue2
) const
143 return rValue1
.pAttr
< rValue2
.pAttr
;
147 typedef std::set
<ScDefaultAttr
, ScLessDefaultAttr
> ScDefaultAttrSet
;
149 void ScDocument::MakeTable( SCTAB nTab
,bool _bNeedsNameCheck
)
151 if ( ValidTab(nTab
) && ( nTab
>= static_cast<SCTAB
>(maTabs
.size()) ||!maTabs
[nTab
]) )
154 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
155 OUString aString
= rOpt
.GetInitTabPrefix();
157 aString
+= OUString::valueOf(static_cast<sal_Int32
>(nTab
+1));
158 if ( _bNeedsNameCheck
)
159 CreateValidTabName( aString
); // no doubles
160 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
162 maTabs
[nTab
] = new ScTable(this, nTab
, aString
);
166 while(nTab
> static_cast<SCTAB
>(maTabs
.size()))
167 maTabs
.push_back(NULL
);
168 maTabs
.push_back( new ScTable(this, nTab
, aString
) );
170 maTabs
[nTab
]->SetLoadingMedium(bLoadingMedium
);
175 bool ScDocument::HasTable( SCTAB nTab
) const
177 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
184 bool ScDocument::GetName( SCTAB nTab
, OUString
& rName
) const
186 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
189 maTabs
[nTab
]->GetName( rName
);
196 OUString
ScDocument::GetCopyTabName( SCTAB nTab
) const
198 if (nTab
< static_cast<SCTAB
>(maTabNames
.size()))
199 return maTabNames
[nTab
];
204 bool ScDocument::SetCodeName( SCTAB nTab
, const OUString
& rName
)
206 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
210 maTabs
[nTab
]->SetCodeName( rName
);
214 OSL_TRACE( "**** can't set code name %s", OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr() );
218 bool ScDocument::GetCodeName( SCTAB nTab
, OUString
& rName
) const
220 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
223 maTabs
[nTab
]->GetCodeName( rName
);
230 bool ScDocument::GetTable( const OUString
& rName
, SCTAB
& rTab
) const
232 OUString aUpperName
= ScGlobal::pCharClass
->uppercase(rName
);
234 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
237 if (aUpperName
.equals(maTabs
[i
]->GetUpperName()))
247 ScDBData
* ScDocument::GetAnonymousDBData(SCTAB nTab
)
249 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
250 return maTabs
[nTab
]->GetAnonymousDBData();
254 void ScDocument::SetAnonymousDBData(SCTAB nTab
, ScDBData
* pDBData
)
256 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
257 maTabs
[nTab
]->SetAnonymousDBData(pDBData
);
261 bool ScDocument::ValidTabName( const OUString
& rName
)
265 sal_Int32 nLen
= rName
.getLength();
268 // Restrict sheet names to what Excel accepts.
269 /* TODO: We may want to remove this restriction for full ODFF compliance.
270 * Merely loading and calculating ODF documents using these characters in
271 * sheet names is not affected by this, but all sheet name editing and
272 * copying functionality is, maybe falling back to "Sheet4" or similar. */
273 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
275 const sal_Unicode c
= rName
[i
];
285 // these characters are not allowed to match XL's convention.
288 if (i
== 0 || i
== nLen
- 1)
289 // single quote is not allowed at the first or last
290 // character position.
301 bool ScDocument::ValidNewTabName( const OUString
& rName
) const
303 bool bValid
= ValidTabName(rName
);
304 TableContainer::const_iterator it
= maTabs
.begin();
305 for (; it
!= maTabs
.end() && bValid
; ++it
)
309 (*it
)->GetName(aOldName
);
310 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
316 void ScDocument::CreateValidTabName(OUString
& rName
) const
318 if ( !ValidTabName(rName
) )
323 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
324 OUString aStrTable
= rOpt
.GetInitTabPrefix();
328 // First test if the prefix is valid, if so only avoid doubles
329 bool bPrefix
= ValidTabName( aStrTable
);
330 OSL_ENSURE(bPrefix
, "Invalid Table Name");
333 for ( SCTAB i
= static_cast<SCTAB
>(maTabs
.size())+1; !bOk
; i
++ )
336 aBuf
.append(aStrTable
);
337 aBuf
.append(static_cast<sal_Int32
>(i
));
338 rName
= aBuf
.makeStringAndClear();
340 bOk
= ValidNewTabName( rName
);
342 bOk
= !GetTable( rName
, nDummy
);
347 // testing the supplied Name
349 if ( !ValidNewTabName(rName
) )
352 OUStringBuffer aName
;
358 aName
.append(static_cast<sal_Int32
>(i
));
360 while (!ValidNewTabName(aName
.toString()) && (i
< MAXTAB
+1));
361 rName
= aName
.makeStringAndClear();
366 void ScDocument::CreateValidTabNames(std::vector
<OUString
>& aNames
, SCTAB nCount
) const
368 aNames
.clear();//ensure that the vector is empty
371 const ScDefaultsOptions
& rOpt
= SC_MOD()->GetDefaultsOptions();
372 OUString aStrTable
= rOpt
.GetInitTabPrefix();
374 OUStringBuffer rName
;
377 // First test if the prefix is valid, if so only avoid doubles
378 bool bPrefix
= ValidTabName( aStrTable
);
379 OSL_ENSURE(bPrefix
, "Invalid Table Name");
381 SCTAB i
= static_cast<SCTAB
>(maTabs
.size())+1;
383 for (SCTAB j
= 0; j
< nCount
; ++j
)
389 rName
.append(static_cast<sal_Int32
>(i
));
391 bOk
= ValidNewTabName( rName
.toString() );
393 bOk
= !GetTable( rName
.toString(), nDummy
);
396 aNames
.push_back(rName
.makeStringAndClear());
400 void ScDocument::AppendTabOnLoad(const OUString
& rName
)
402 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
403 if (!ValidTab(nTabCount
))
404 // max table count reached. No more tables.
407 OUString aName
= rName
;
408 CreateValidTabName(aName
);
409 maTabs
.push_back( new ScTable(this, nTabCount
, aName
) );
412 void ScDocument::SetTabNameOnLoad(SCTAB nTab
, const OUString
& rName
)
414 if (!ValidTab(nTab
) || static_cast<SCTAB
>(maTabs
.size()) <= nTab
)
417 if (!ValidTabName(rName
))
420 maTabs
[nTab
]->SetName(rName
);
423 void ScDocument::InvalidateStreamOnSave()
425 TableContainer::iterator it
= maTabs
.begin(), itEnd
= maTabs
.end();
426 for (; it
!= itEnd
; ++it
)
430 pTab
->SetStreamValid(false);
434 bool ScDocument::InsertTab( SCTAB nPos
, const OUString
& rName
,
435 bool bExternalDocument
)
437 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
438 bool bValid
= ValidTab(nTabCount
);
439 if ( !bExternalDocument
) // else test rName == "'Doc'!Tab" first
440 bValid
= (bValid
&& ValidNewTabName(rName
));
443 if (nPos
== SC_TAB_APPEND
|| nPos
>= nTabCount
)
445 maTabs
.push_back( new ScTable(this, nTabCount
, rName
) );
446 if ( bExternalDocument
)
447 maTabs
[nTabCount
]->SetVisible( false );
451 if (ValidTab(nPos
) && (nPos
< nTabCount
))
453 ScRange
aRange( 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
);
454 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
455 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
457 pRangeName
->UpdateTabRef( nPos
, 1 );
458 pDBCollection
->UpdateReference(
459 URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
461 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
463 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,1 );
464 UpdateChartRef( URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
465 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,1 );
466 if ( pUnoBroadcaster
)
467 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,1 ) );
470 TableContainer::iterator it
= maTabs
.begin();
471 for (; it
!= maTabs
.end(); ++it
)
473 (*it
)->UpdateInsertTab(nPos
);
474 maTabs
.push_back(NULL
);
475 for (i
= nTabCount
; i
> nPos
; i
--)
477 maTabs
[i
] = maTabs
[i
- 1];
480 maTabs
[nPos
] = new ScTable(this, nPos
, rName
);
482 // UpdateBroadcastAreas must be called between UpdateInsertTab,
483 // which ends listening, and StartAllListeners, to not modify
484 // areas that are to be inserted by starting listeners.
485 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,1);
487 for (; it
!= maTabs
.end(); ++it
)
489 (*it
)->UpdateCompile();
491 for (; it
!= maTabs
.end(); ++it
)
493 (*it
)->StartAllListeners();
495 if ( pValidationList
)
496 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
497 // sheet names of references are not valid until sheet is inserted
498 if ( pChartListenerCollection
)
499 pChartListenerCollection
->UpdateScheduledSeriesRanges();
515 bool ScDocument::InsertTabs( SCTAB nPos
, const std::vector
<OUString
>& rNames
,
516 bool bExternalDocument
, bool bNamesValid
)
518 SCTAB nNewSheets
= static_cast<SCTAB
>(rNames
.size());
519 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
520 bool bValid
= bNamesValid
|| ValidTab(nTabCount
+nNewSheets
);
521 // if ( !bExternalDocument ) // else test rName == "'Doc'!Tab" first
522 // bValid = (bValid && ValidNewTabName(rNames));
525 if (nPos
== SC_TAB_APPEND
|| nPos
>= nTabCount
)
527 for ( SCTAB i
= 0; i
< nNewSheets
; ++i
)
529 maTabs
.push_back( new ScTable(this, nTabCount
+ i
, rNames
.at(i
)) );
530 if ( bExternalDocument
)
531 maTabs
[nTabCount
+i
]->SetVisible( false );
536 if (ValidTab(nPos
) && (nPos
< nTabCount
))
538 ScRange
aRange( 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
);
539 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,nNewSheets
);
540 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,nNewSheets
);
542 pRangeName
->UpdateTabRef( nPos
, 1, 0, nNewSheets
);
543 pDBCollection
->UpdateReference(
544 URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,nNewSheets
);
546 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,nNewSheets
);
548 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,nNewSheets
);
549 UpdateChartRef( URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,nNewSheets
);
550 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0, nNewSheets
);
551 if ( pUnoBroadcaster
)
552 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,nNewSheets
) );
554 TableContainer::iterator it
= maTabs
.begin();
555 for (; it
!= maTabs
.end(); ++it
)
557 (*it
)->UpdateInsertTab(nPos
, nNewSheets
);
559 maTabs
.insert(it
+nPos
,nNewSheets
, NULL
);
560 for (SCTAB i
= 0; i
< nNewSheets
; ++i
)
562 maTabs
[nPos
+ i
] = new ScTable(this, nPos
+ i
, rNames
.at(i
));
565 // UpdateBroadcastAreas must be called between UpdateInsertTab,
566 // which ends listening, and StartAllListeners, to not modify
567 // areas that are to be inserted by starting listeners.
568 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,nNewSheets
);
570 for (; it
!= maTabs
.end(); ++it
)
573 (*it
)->UpdateCompile();
576 for (; it
!= maTabs
.end(); ++it
)
578 (*it
)->StartAllListeners();
580 if ( pValidationList
)
581 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,nNewSheets
);
582 // sheet names of references are not valid until sheet is inserted
583 if ( pChartListenerCollection
)
584 pChartListenerCollection
->UpdateScheduledSeriesRanges();
600 bool ScDocument::DeleteTab( SCTAB nTab
, ScDocument
* pRefUndoDoc
)
603 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
607 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
610 bool bOldAutoCalc
= GetAutoCalc();
611 SetAutoCalc( false ); // avoid multiple calculations
612 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTab
);
613 DelBroadcastAreasInRange( aRange
);
615 // #i8180# remove database ranges etc. that are on the deleted tab
616 // (restored in undo with ScRefUndoData)
618 xColNameRanges
->DeleteOnTab( nTab
);
619 xRowNameRanges
->DeleteOnTab( nTab
);
620 pDBCollection
->DeleteOnTab( nTab
);
622 pDPCollection
->DeleteOnTab( nTab
);
624 pDetOpList
->DeleteOnTab( nTab
);
625 DeleteAreaLinksOnTab( nTab
);
627 // normal reference update
629 aRange
.aEnd
.SetTab( static_cast<SCTAB
>(maTabs
.size())-1 );
630 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
631 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
633 pRangeName
->UpdateTabRef( nTab
, 2 );
634 pDBCollection
->UpdateReference(
635 URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
637 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
639 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,-1 );
640 UpdateChartRef( URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
641 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,-1 );
642 if ( pValidationList
)
643 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
644 if ( pUnoBroadcaster
)
645 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,-1 ) );
647 for (SCTAB i
= 0, n
= static_cast<SCTAB
>(maTabs
.size()); i
< n
; ++i
)
649 maTabs
[i
]->UpdateDeleteTab(
650 nTab
, false, pRefUndoDoc
? pRefUndoDoc
->maTabs
[i
] : 0);
652 TableContainer::iterator it
= maTabs
.begin() + nTab
;
655 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
656 // which ends listening, and StartAllListeners, to not modify
657 // areas that are to be inserted by starting listeners.
658 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,-1);
660 for (; it
!= maTabs
.end(); ++it
)
662 (*it
)->UpdateCompile();
663 // Excel-Filter deletes some Tables while loading, Listeners will
664 // only be triggered after the loading is done.
665 if ( !bInsertingFromOtherDoc
)
668 for (; it
!= maTabs
.end(); ++it
)
670 (*it
)->StartAllListeners();
673 // sheet names of references are not valid until sheet is deleted
674 pChartListenerCollection
->UpdateScheduledSeriesRanges();
676 SetAutoCalc( bOldAutoCalc
);
685 bool ScDocument::DeleteTabs( SCTAB nTab
, SCTAB nSheets
, ScDocument
* pRefUndoDoc
)
688 if (ValidTab(nTab
) && (nTab
+ nSheets
) < static_cast<SCTAB
>(maTabs
.size()))
692 SCTAB nTabCount
= static_cast<SCTAB
>(maTabs
.size());
693 if (nTabCount
> nSheets
)
695 bool bOldAutoCalc
= GetAutoCalc();
696 SetAutoCalc( false ); // avoid multiple calculations
697 for (SCTAB aTab
= 0; aTab
< nSheets
; ++aTab
)
699 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTab
+ aTab
);
700 DelBroadcastAreasInRange( aRange
);
702 // #i8180# remove database ranges etc. that are on the deleted tab
703 // (restored in undo with ScRefUndoData)
705 xColNameRanges
->DeleteOnTab( nTab
+ aTab
);
706 xRowNameRanges
->DeleteOnTab( nTab
+ aTab
);
707 pDBCollection
->DeleteOnTab( nTab
+ aTab
);
709 pDPCollection
->DeleteOnTab( nTab
+ aTab
);
711 pDetOpList
->DeleteOnTab( nTab
+ aTab
);
712 DeleteAreaLinksOnTab( nTab
+ aTab
);
714 pRangeName
->UpdateTabRef( nTab
+ aTab
, 2 );
716 // normal reference update
718 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTabCount
- 1 );
719 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1*nSheets
);
720 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1*nSheets
);
721 pDBCollection
->UpdateReference(
722 URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1*nSheets
);
724 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
726 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
727 UpdateChartRef( URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1*nSheets
);
728 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
729 if ( pValidationList
)
730 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
731 if ( pUnoBroadcaster
)
732 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,-1*nSheets
) );
734 for (SCTAB i
= 0, n
= static_cast<SCTAB
>(maTabs
.size()); i
< n
; ++i
)
736 maTabs
[i
]->UpdateDeleteTab(
737 nTab
, false, pRefUndoDoc
? pRefUndoDoc
->maTabs
[i
] : 0,nSheets
);
739 TableContainer::iterator it
= maTabs
.begin() + nTab
;
740 TableContainer::iterator itEnd
= it
+ nSheets
;
741 std::for_each(it
, itEnd
, ScDeleteObjectByPtr
<ScTable
>());
742 maTabs
.erase(it
, itEnd
);
743 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
744 // which ends listening, and StartAllListeners, to not modify
745 // areas that are to be inserted by starting listeners.
746 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,-1*nSheets
);
748 for (; it
!= maTabs
.end(); ++it
)
750 (*it
)->UpdateCompile();
751 // Excel-Filter deletes some Tables while loading, Listeners will
752 // only be triggered after the loading is done.
753 if ( !bInsertingFromOtherDoc
)
756 for (; it
!= maTabs
.end(); ++it
)
758 (*it
)->StartAllListeners();
761 // sheet names of references are not valid until sheet is deleted
762 pChartListenerCollection
->UpdateScheduledSeriesRanges();
764 SetAutoCalc( bOldAutoCalc
);
773 bool ScDocument::RenameTab( SCTAB nTab
, const OUString
& rName
, bool /* bUpdateRef */,
774 bool bExternalDocument
)
782 if ( bExternalDocument
)
783 bValid
= true; // composed name
785 bValid
= ValidTabName(rName
);
786 for (i
=0; (i
< static_cast<SCTAB
>(maTabs
.size())) && bValid
; i
++)
787 if (maTabs
[i
] && (i
!= nTab
))
790 maTabs
[i
]->GetName(aOldName
);
791 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
795 // #i75258# update charts before renaming, so they can get their live data objects.
796 // Once the charts are live, the sheet can be renamed without problems.
797 if ( pChartListenerCollection
)
798 pChartListenerCollection
->UpdateChartsContainingTab( nTab
);
799 maTabs
[nTab
]->SetName(rName
);
801 // If formulas refer to the renamed sheet, the TokenArray remains valid,
802 // but the XML stream must be re-generated.
803 TableContainer::iterator it
= maTabs
.begin();
804 for (; it
!= maTabs
.end(); ++it
)
805 if ( *it
&& (*it
)->IsStreamValid())
806 (*it
)->SetStreamValid( false );
814 void ScDocument::SetVisible( SCTAB nTab
, bool bVisible
)
816 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
818 maTabs
[nTab
]->SetVisible(bVisible
);
822 bool ScDocument::IsVisible( SCTAB nTab
) const
824 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
826 return maTabs
[nTab
]->IsVisible();
832 bool ScDocument::IsStreamValid( SCTAB nTab
) const
834 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
835 return maTabs
[nTab
]->IsStreamValid();
841 void ScDocument::SetStreamValid( SCTAB nTab
, bool bSet
, bool bIgnoreLock
)
843 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
844 maTabs
[nTab
]->SetStreamValid( bSet
, bIgnoreLock
);
848 void ScDocument::LockStreamValid( bool bLock
)
850 mbStreamValidLocked
= bLock
;
854 bool ScDocument::IsPendingRowHeights( SCTAB nTab
) const
856 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
857 return maTabs
[nTab
]->IsPendingRowHeights();
863 void ScDocument::SetPendingRowHeights( SCTAB nTab
, bool bSet
)
865 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
866 maTabs
[nTab
]->SetPendingRowHeights( bSet
);
870 void ScDocument::SetLayoutRTL( SCTAB nTab
, bool bRTL
)
872 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
876 // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
877 // is applied in SetImportingXML(false). This is so the shapes can be loaded in
880 maTabs
[nTab
]->SetLoadingRTL( bRTL
);
884 maTabs
[nTab
]->SetLayoutRTL( bRTL
); // only sets the flag
885 maTabs
[nTab
]->SetDrawPageSize();
887 // mirror existing objects:
891 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
892 OSL_ENSURE(pPage
,"Page ?");
895 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
896 SdrObject
* pObject
= aIter
.Next();
899 // objects with ScDrawObjData are re-positioned in SetPageSize,
900 // don't mirror again
901 ScDrawObjData
* pData
= ScDrawLayer::GetObjData( pObject
);
903 pDrawLayer
->MirrorRTL( pObject
);
905 pObject
->SetContextWritingMode( bRTL
? WritingMode2::RL_TB
: WritingMode2::LR_TB
);
907 pObject
= aIter
.Next();
915 bool ScDocument::IsLayoutRTL( SCTAB nTab
) const
917 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
] )
918 return maTabs
[nTab
]->IsLayoutRTL();
924 bool ScDocument::IsNegativePage( SCTAB nTab
) const
926 // Negative page area is always used for RTL layout.
927 // The separate method is used to find all RTL handling of drawing objects.
928 return IsLayoutRTL( nTab
);
932 /* ----------------------------------------------------------------------------
935 GetCellArea - Only Data
936 GetTableArea - Data / Attributes
937 GetPrintArea - intended for character objects,
938 sweeps attributes all the way to bottom / right
939 ---------------------------------------------------------------------------- */
942 bool ScDocument::GetCellArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
944 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
946 return maTabs
[nTab
]->GetCellArea( rEndCol
, rEndRow
);
954 bool ScDocument::GetTableArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
956 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
958 return maTabs
[nTab
]->GetTableArea( rEndCol
, rEndRow
);
965 bool ScDocument::ShrinkToDataArea(SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
967 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
> (maTabs
.size()) || !maTabs
[nTab
])
972 maTabs
[nTab
]->GetFirstDataPos(nCol1
, nRow1
);
973 maTabs
[nTab
]->GetLastDataPos(nCol2
, nRow2
);
975 if (nCol1
> nCol2
|| nRow1
> nRow2
)
979 // Make sure the area only shrinks, and doesn't grow.
980 if (rStartCol
< nCol1
)
984 if (rStartRow
< nRow1
)
989 if (rStartCol
> rEndCol
|| rStartRow
> rEndRow
)
993 return true; // success!
996 bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk
, SCTAB nTab
, SCCOL
& rStartCol
,
997 SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
, bool bColumnsOnly
) const
999 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
> (maTabs
.size()) || !maTabs
[nTab
])
1004 return maTabs
[nTab
]->ShrinkToUsedDataArea( o_bShrunk
, rStartCol
, rStartRow
, rEndCol
, rEndRow
, bColumnsOnly
);
1009 void ScDocument::GetDataArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
1010 SCCOL
& rEndCol
, SCROW
& rEndRow
, bool bIncludeOld
, bool bOnlyDown
) const
1012 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
])
1013 maTabs
[nTab
]->GetDataArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
, bIncludeOld
, bOnlyDown
);
1017 void ScDocument::LimitChartArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
1018 SCCOL
& rEndCol
, SCROW
& rEndRow
)
1020 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
> (maTabs
.size()))
1022 maTabs
[nTab
]->LimitChartArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
);
1026 void ScDocument::LimitChartIfAll( ScRangeListRef
& rRangeList
)
1028 ScRangeListRef aNew
= new ScRangeList
;
1029 if (rRangeList
.Is())
1031 for ( size_t i
= 0, nCount
= rRangeList
->size(); i
< nCount
; i
++ )
1033 ScRange
aRange( *(*rRangeList
)[i
] );
1034 if ( ( aRange
.aStart
.Col() == 0 && aRange
.aEnd
.Col() == MAXCOL
) ||
1035 ( aRange
.aStart
.Row() == 0 && aRange
.aEnd
.Row() == MAXROW
) )
1037 SCCOL nStartCol
= aRange
.aStart
.Col();
1038 SCROW nStartRow
= aRange
.aStart
.Row();
1039 SCCOL nEndCol
= aRange
.aEnd
.Col();
1040 SCROW nEndRow
= aRange
.aEnd
.Row();
1041 SCTAB nTab
= aRange
.aStart
.Tab();
1042 if ( nTab
< static_cast<SCTAB
> (maTabs
.size()) && maTabs
[nTab
])
1043 maTabs
[nTab
]->LimitChartArea(nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1044 aRange
.aStart
.SetCol( nStartCol
);
1045 aRange
.aStart
.SetRow( nStartRow
);
1046 aRange
.aEnd
.SetCol( nEndCol
);
1047 aRange
.aEnd
.SetRow( nEndRow
);
1049 aNew
->Append(aRange
);
1054 OSL_FAIL("LimitChartIfAll: Ref==0");
1060 static void lcl_GetFirstTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
, SCTAB aMaxTab
)
1062 // without ScMarkData, leave start/end unchanged
1065 for (SCTAB nTab
=0; nTab
< aMaxTab
; ++nTab
)
1066 if (pTabMark
->GetTableSelect(nTab
))
1068 // find first range of consecutive selected sheets
1069 rTabRangeStart
= pTabMark
->GetFirstSelected();
1070 while ( nTab
+1 < aMaxTab
&& pTabMark
->GetTableSelect(nTab
+1) )
1072 rTabRangeEnd
= nTab
;
1078 static bool lcl_GetNextTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
, SCTAB aMaxTab
)
1082 // find next range of consecutive selected sheets after rTabRangeEnd
1083 for (SCTAB nTab
=rTabRangeEnd
+1; nTab
< aMaxTab
; ++nTab
)
1084 if (pTabMark
->GetTableSelect(nTab
))
1086 rTabRangeStart
= nTab
;
1087 while ( nTab
+1 < aMaxTab
&& pTabMark
->GetTableSelect(nTab
+1) )
1089 rTabRangeEnd
= nTab
;
1097 bool ScDocument::CanInsertRow( const ScRange
& rRange
) const
1099 SCCOL nStartCol
= rRange
.aStart
.Col();
1100 SCROW nStartRow
= rRange
.aStart
.Row();
1101 SCTAB nStartTab
= rRange
.aStart
.Tab();
1102 SCCOL nEndCol
= rRange
.aEnd
.Col();
1103 SCROW nEndRow
= rRange
.aEnd
.Row();
1104 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1105 PutInOrder( nStartCol
, nEndCol
);
1106 PutInOrder( nStartRow
, nEndRow
);
1107 PutInOrder( nStartTab
, nEndTab
);
1108 SCSIZE nSize
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
1111 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1113 bTest
&= maTabs
[i
]->TestInsertRow( nStartCol
, nEndCol
, nSize
);
1120 struct BroadcastRecalcOnRefMoveHandler
: std::unary_function
<ScTable
*, void>
1122 void operator() (ScTable
* p
)
1125 p
->BroadcastRecalcOnRefMove();
1131 bool ScDocument::InsertRow( SCCOL nStartCol
, SCTAB nStartTab
,
1132 SCCOL nEndCol
, SCTAB nEndTab
,
1133 SCROW nStartRow
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1134 const ScMarkData
* pTabMark
)
1138 PutInOrder( nStartCol
, nEndCol
);
1139 PutInOrder( nStartTab
, nEndTab
);
1143 nEndTab
= static_cast<SCTAB
>(maTabs
.size()) -1;
1148 bool bOldAutoCalc
= GetAutoCalc();
1149 SetAutoCalc( false ); // avoid mulitple calculations
1150 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1151 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1152 bTest
&= maTabs
[i
]->TestInsertRow( nStartCol
, nEndCol
, nSize
);
1155 // UpdateBroadcastAreas have to be called before UpdateReference, so that entries
1156 // aren't shifted that would be rebuild at UpdateReference
1158 // handle chunks of consecutive selected sheets together
1159 SCTAB nTabRangeStart
= nStartTab
;
1160 SCTAB nTabRangeEnd
= nEndTab
;
1161 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1164 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1165 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1166 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, static_cast<SCsROW
>(nSize
), 0 );
1168 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1170 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1173 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
, nTabRangeStart
,
1174 nEndCol
, MAXROW
, nTabRangeEnd
,
1175 0, static_cast<SCsROW
>(nSize
), 0, pRefUndoDoc
, false ); // without drawing objects
1177 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1179 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1180 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1181 maTabs
[i
]->InsertRow( nStartCol
, nEndCol
, nStartRow
, nSize
);
1183 // UpdateRef for drawing layer must be after inserting,
1184 // when the new row heights are known.
1185 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1186 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1187 maTabs
[i
]->UpdateDrawRef( URM_INSDEL
,
1188 nStartCol
, nStartRow
, nStartTab
, nEndCol
, MAXROW
, nEndTab
,
1189 0, static_cast<SCsROW
>(nSize
), 0 );
1191 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
1192 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
1193 // ein neues Listening faellig, bisherige Listener wurden in
1194 // FormulaCell UpdateReference abgehaengt
1195 StartAllListeners();
1198 { // Listeners have been removed in UpdateReference
1199 TableContainer::iterator it
= maTabs
.begin();
1200 for (; it
!= maTabs
.end(); ++it
)
1202 (*it
)->StartNeededListeners();
1203 // At least all cells using range names pointing relative to the
1204 // moved range must be recalculated, and all cells marked postponed
1206 it
= maTabs
.begin();
1207 for (; it
!= maTabs
.end(); ++it
)
1209 (*it
)->SetDirtyIfPostponed();
1211 // Cells containing functions such as CELL, COLUMN or ROW may have
1212 // changed their values on relocation. Broadcast them.
1213 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1217 SetAutoCalc( bOldAutoCalc
);
1219 pChartListenerCollection
->UpdateDirtyCharts();
1224 bool ScDocument::InsertRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
1226 return InsertRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
1227 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
1228 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
1233 void ScDocument::DeleteRow( SCCOL nStartCol
, SCTAB nStartTab
,
1234 SCCOL nEndCol
, SCTAB nEndTab
,
1235 SCROW nStartRow
, SCSIZE nSize
,
1236 ScDocument
* pRefUndoDoc
, bool* pUndoOutline
,
1237 const ScMarkData
* pTabMark
)
1241 PutInOrder( nStartCol
, nEndCol
);
1242 PutInOrder( nStartTab
, nEndTab
);
1246 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1249 bool bOldAutoCalc
= GetAutoCalc();
1250 SetAutoCalc( false ); // avoid multiple calculations
1252 // handle chunks of consecutive selected sheets together
1253 SCTAB nTabRangeStart
= nStartTab
;
1254 SCTAB nTabRangeEnd
= nEndTab
;
1255 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1258 if ( ValidRow(nStartRow
+nSize
) )
1260 DelBroadcastAreasInRange( ScRange(
1261 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1262 ScAddress( nEndCol
, nStartRow
+nSize
-1, nTabRangeEnd
) ) );
1263 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1264 ScAddress( nStartCol
, nStartRow
+nSize
, nTabRangeStart
),
1265 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, -(static_cast<SCsROW
>(nSize
)), 0 );
1268 DelBroadcastAreasInRange( ScRange(
1269 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1270 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
) ) );
1272 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1274 if ( ValidRow(nStartRow
+nSize
) )
1276 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1279 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
+nSize
, nTabRangeStart
,
1280 nEndCol
, MAXROW
, nTabRangeEnd
,
1281 0, -(static_cast<SCsROW
>(nSize
)), 0, pRefUndoDoc
, true, false );
1283 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1287 *pUndoOutline
= false;
1289 for ( i
= nStartTab
; i
<= nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1290 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1291 maTabs
[i
]->DeleteRow( nStartCol
, nEndCol
, nStartRow
, nSize
, pUndoOutline
);
1293 if ( ValidRow(nStartRow
+nSize
) )
1294 { // Listeners have been removed in UpdateReference
1295 TableContainer::iterator it
= maTabs
.begin();
1296 for (; it
!= maTabs
.end(); ++it
)
1298 (*it
)->StartNeededListeners();
1299 // At least all cells using range names pointing relative to the moved
1300 // range must be recalculated, and all cells marked postponed dirty.
1301 it
= maTabs
.begin();
1302 for (; it
!= maTabs
.end(); ++it
)
1304 (*it
)->SetDirtyIfPostponed();
1306 // Cells containing functions such as CELL, COLUMN or ROW may have
1307 // changed their values on relocation. Broadcast them.
1308 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1311 SetAutoCalc( bOldAutoCalc
);
1312 pChartListenerCollection
->UpdateDirtyCharts();
1316 void ScDocument::DeleteRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, bool* pUndoOutline
)
1318 DeleteRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
1319 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
1320 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
1321 pRefUndoDoc
, pUndoOutline
);
1325 bool ScDocument::CanInsertCol( const ScRange
& rRange
) const
1327 SCCOL nStartCol
= rRange
.aStart
.Col();
1328 SCROW nStartRow
= rRange
.aStart
.Row();
1329 SCTAB nStartTab
= rRange
.aStart
.Tab();
1330 SCCOL nEndCol
= rRange
.aEnd
.Col();
1331 SCROW nEndRow
= rRange
.aEnd
.Row();
1332 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1333 PutInOrder( nStartCol
, nEndCol
);
1334 PutInOrder( nStartRow
, nEndRow
);
1335 PutInOrder( nStartTab
, nEndTab
);
1336 SCSIZE nSize
= static_cast<SCSIZE
>(nEndCol
- nStartCol
+ 1);
1339 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1341 bTest
&= maTabs
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1347 bool ScDocument::InsertCol( SCROW nStartRow
, SCTAB nStartTab
,
1348 SCROW nEndRow
, SCTAB nEndTab
,
1349 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1350 const ScMarkData
* pTabMark
)
1354 PutInOrder( nStartRow
, nEndRow
);
1355 PutInOrder( nStartTab
, nEndTab
);
1359 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1364 bool bOldAutoCalc
= GetAutoCalc();
1365 SetAutoCalc( false ); // avoid multiple calculations
1366 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1367 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1368 bTest
&= maTabs
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1371 // handle chunks of consecutive selected sheets together
1372 SCTAB nTabRangeStart
= nStartTab
;
1373 SCTAB nTabRangeEnd
= nEndTab
;
1374 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1377 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1378 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1379 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), static_cast<SCsCOL
>(nSize
), 0, 0 );
1381 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1383 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1386 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
, nTabRangeStart
,
1387 MAXCOL
, nEndRow
, nTabRangeEnd
,
1388 static_cast<SCsCOL
>(nSize
), 0, 0, pRefUndoDoc
, true, false );
1390 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1392 for (i
=nStartTab
; i
<=nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1393 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1394 maTabs
[i
]->InsertCol( nStartCol
, nStartRow
, nEndRow
, nSize
);
1396 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
1397 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
1398 // ein neues Listening faellig, bisherige Listener wurden in
1399 // FormulaCell UpdateReference abgehaengt
1400 StartAllListeners();
1403 {// Listeners have been removed in UpdateReference
1404 TableContainer::iterator it
= maTabs
.begin();
1405 for (; it
!= maTabs
.end(); ++it
)
1407 (*it
)->StartNeededListeners();
1408 // At least all cells using range names pointing relative to the
1409 // moved range must be recalculated, and all cells marked postponed
1411 it
= maTabs
.begin();
1412 for (; it
!= maTabs
.end(); ++it
)
1414 (*it
)->SetDirtyIfPostponed();
1416 // Cells containing functions such as CELL, COLUMN or ROW may have
1417 // changed their values on relocation. Broadcast them.
1418 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1422 SetAutoCalc( bOldAutoCalc
);
1424 pChartListenerCollection
->UpdateDirtyCharts();
1429 bool ScDocument::InsertCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
1431 return InsertCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1432 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1433 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1438 void ScDocument::DeleteCol(SCROW nStartRow
, SCTAB nStartTab
, SCROW nEndRow
, SCTAB nEndTab
,
1439 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1440 bool* pUndoOutline
, const ScMarkData
* pTabMark
)
1444 PutInOrder( nStartRow
, nEndRow
);
1445 PutInOrder( nStartTab
, nEndTab
);
1449 nEndTab
= static_cast<SCTAB
>(maTabs
.size())-1;
1452 bool bOldAutoCalc
= GetAutoCalc();
1453 SetAutoCalc( false ); // avoid multiple calculations
1455 // handle chunks of consecutive selected sheets together
1456 SCTAB nTabRangeStart
= nStartTab
;
1457 SCTAB nTabRangeEnd
= nEndTab
;
1458 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1461 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1463 DelBroadcastAreasInRange( ScRange(
1464 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1465 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
-1), nEndRow
, nTabRangeEnd
) ) );
1466 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1467 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
),
1468 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), -static_cast<SCsCOL
>(nSize
), 0, 0 );
1471 DelBroadcastAreasInRange( ScRange(
1472 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1473 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
) ) );
1475 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1477 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1479 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) );
1482 UpdateReference( URM_INSDEL
, sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
,
1483 MAXCOL
, nEndRow
, nTabRangeEnd
,
1484 -static_cast<SCsCOL
>(nSize
), 0, 0, pRefUndoDoc
, true, false );
1486 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
, static_cast<SCTAB
>(maTabs
.size()) ) );
1490 *pUndoOutline
= false;
1492 for ( i
= nStartTab
; i
<= nEndTab
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1493 if (maTabs
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1494 maTabs
[i
]->DeleteCol( nStartCol
, nStartRow
, nEndRow
, nSize
, pUndoOutline
);
1496 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1497 {// Listeners have been removed in UpdateReference
1498 TableContainer::iterator it
= maTabs
.begin();
1499 for (; it
!= maTabs
.end(); ++it
)
1501 (*it
)->StartNeededListeners();
1502 // At least all cells using range names pointing relative to the moved
1503 // range must be recalculated, and all cells marked postponed dirty.
1504 it
= maTabs
.begin();
1505 for (; it
!= maTabs
.end(); ++it
)
1507 (*it
)->SetDirtyIfPostponed();
1509 // Cells containing functions such as CELL, COLUMN or ROW may have
1510 // changed their values on relocation. Broadcast them.
1511 std::for_each(maTabs
.begin(), maTabs
.end(), BroadcastRecalcOnRefMoveHandler());
1514 SetAutoCalc( bOldAutoCalc
);
1515 pChartListenerCollection
->UpdateDirtyCharts();
1519 void ScDocument::DeleteCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, bool* pUndoOutline
)
1521 DeleteCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1522 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1523 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1524 pRefUndoDoc
, pUndoOutline
);
1528 // fuer Area-Links: Zellen einuegen/loeschen, wenn sich der Bereich veraendert
1532 static void lcl_GetInsDelRanges( const ScRange
& rOld
, const ScRange
& rNew
,
1533 ScRange
& rColRange
, bool& rInsCol
, bool& rDelCol
,
1534 ScRange
& rRowRange
, bool& rInsRow
, bool& rDelRow
)
1536 OSL_ENSURE( rOld
.aStart
== rNew
.aStart
, "FitBlock: Beginning is different" );
1538 rInsCol
= rDelCol
= rInsRow
= rDelRow
= false;
1540 SCCOL nStartX
= rOld
.aStart
.Col();
1541 SCROW nStartY
= rOld
.aStart
.Row();
1542 SCCOL nOldEndX
= rOld
.aEnd
.Col();
1543 SCROW nOldEndY
= rOld
.aEnd
.Row();
1544 SCCOL nNewEndX
= rNew
.aEnd
.Col();
1545 SCROW nNewEndY
= rNew
.aEnd
.Row();
1546 SCTAB nTab
= rOld
.aStart
.Tab();
1548 // wenn es mehr Zeilen werden, werden Spalten auf der alten Hoehe eingefuegt/geloescht
1549 bool bGrowY
= ( nNewEndY
> nOldEndY
);
1550 SCROW nColEndY
= bGrowY
? nOldEndY
: nNewEndY
;
1551 SCCOL nRowEndX
= bGrowY
? nNewEndX
: nOldEndX
;
1555 if ( nNewEndX
> nOldEndX
) // Spalten einfuegen
1557 rColRange
= ScRange( nOldEndX
+1, nStartY
, nTab
, nNewEndX
, nColEndY
, nTab
);
1560 else if ( nNewEndX
< nOldEndX
) // Spalten loeschen
1562 rColRange
= ScRange( nNewEndX
+1, nStartY
, nTab
, nOldEndX
, nColEndY
, nTab
);
1568 if ( nNewEndY
> nOldEndY
) // Zeilen einfuegen
1570 rRowRange
= ScRange( nStartX
, nOldEndY
+1, nTab
, nRowEndX
, nNewEndY
, nTab
);
1573 else if ( nNewEndY
< nOldEndY
) // Zeilen loeschen
1575 rRowRange
= ScRange( nStartX
, nNewEndY
+1, nTab
, nRowEndX
, nOldEndY
, nTab
);
1581 bool ScDocument::HasPartOfMerged( const ScRange
& rRange
)
1584 SCTAB nTab
= rRange
.aStart
.Tab();
1586 SCCOL nStartX
= rRange
.aStart
.Col();
1587 SCROW nStartY
= rRange
.aStart
.Row();
1588 SCCOL nEndX
= rRange
.aEnd
.Col();
1589 SCROW nEndY
= rRange
.aEnd
.Row();
1591 if (HasAttrib( nStartX
, nStartY
, nTab
, nEndX
, nEndY
, nTab
,
1592 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
1594 ExtendMerge( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1595 ExtendOverlapped( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1597 bPart
= ( nStartX
!= rRange
.aStart
.Col() || nEndX
!= rRange
.aEnd
.Col() ||
1598 nStartY
!= rRange
.aStart
.Row() || nEndY
!= rRange
.aEnd
.Row() );
1603 size_t ScDocument::GetFormulaHash( const ScAddress
& rPos
) const
1605 SCTAB nTab
= rPos
.Tab();
1606 if (!ValidTab(nTab
) || static_cast<size_t>(nTab
) >= maTabs
.size() || !maTabs
[nTab
])
1609 return maTabs
[nTab
]->GetFormulaHash(rPos
.Col(), rPos
.Row());
1612 ScFormulaVectorState
ScDocument::GetFormulaVectorState( const ScAddress
& rPos
) const
1614 SCTAB nTab
= rPos
.Tab();
1615 if (!ValidTab(nTab
) || static_cast<size_t>(nTab
) >= maTabs
.size() || !maTabs
[nTab
])
1616 return FormulaVectorUnknown
;
1618 return maTabs
[nTab
]->GetFormulaVectorState(rPos
.Col(), rPos
.Row());
1621 formula::FormulaTokenRef
ScDocument::ResolveStaticReference( const ScAddress
& rPos
)
1623 SCTAB nTab
= rPos
.Tab();
1624 if (!TableExists(nTab
))
1625 return formula::FormulaTokenRef();
1627 return maTabs
[nTab
]->ResolveStaticReference(rPos
.Col(), rPos
.Row());
1630 formula::FormulaTokenRef
ScDocument::ResolveStaticReference( const ScRange
& rRange
)
1632 SCTAB nTab
= rRange
.aStart
.Tab();
1633 if (nTab
!= rRange
.aEnd
.Tab() || !TableExists(nTab
))
1634 return formula::FormulaTokenRef();
1636 return maTabs
[nTab
]->ResolveStaticReference(
1637 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
1640 const double* ScDocument::FetchDoubleArray(
1641 sc::FormulaGroupContext
& rCxt
, const ScAddress
& rPos
, SCROW nLength
) const
1643 SCTAB nTab
= rPos
.Tab();
1644 if (!TableExists(nTab
))
1647 return maTabs
[nTab
]->FetchDoubleArray(rCxt
, rPos
.Col(), rPos
.Row(), rPos
.Row()+nLength
-1);
1650 bool ScDocument::CanFitBlock( const ScRange
& rOld
, const ScRange
& rNew
)
1656 bool bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1657 ScRange aColRange
,aRowRange
;
1658 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1660 if ( bInsCol
&& !CanInsertCol( aColRange
) ) // Zellen am Rand ?
1662 if ( bInsRow
&& !CanInsertRow( aRowRange
) ) // Zellen am Rand ?
1665 if ( bInsCol
|| bDelCol
)
1667 aColRange
.aEnd
.SetCol(MAXCOL
);
1668 if ( HasPartOfMerged(aColRange
) )
1671 if ( bInsRow
|| bDelRow
)
1673 aRowRange
.aEnd
.SetRow(MAXROW
);
1674 if ( HasPartOfMerged(aRowRange
) )
1682 void ScDocument::FitBlock( const ScRange
& rOld
, const ScRange
& rNew
, bool bClear
)
1685 DeleteAreaTab( rOld
, IDF_ALL
);
1687 bool bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1688 ScRange aColRange
,aRowRange
;
1689 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1692 InsertCol( aColRange
); // Spalten zuerst einfuegen
1694 InsertRow( aRowRange
);
1697 DeleteRow( aRowRange
); // Zeilen zuerst loeschen
1699 DeleteCol( aColRange
);
1701 // Referenzen um eingefuegte Zeilen erweitern
1703 if ( bInsCol
|| bInsRow
)
1705 ScRange aGrowSource
= rOld
;
1706 aGrowSource
.aEnd
.SetCol(std::min( rOld
.aEnd
.Col(), rNew
.aEnd
.Col() ));
1707 aGrowSource
.aEnd
.SetRow(std::min( rOld
.aEnd
.Row(), rNew
.aEnd
.Row() ));
1708 SCCOL nGrowX
= bInsCol
? ( rNew
.aEnd
.Col() - rOld
.aEnd
.Col() ) : 0;
1709 SCROW nGrowY
= bInsRow
? ( rNew
.aEnd
.Row() - rOld
.aEnd
.Row() ) : 0;
1710 UpdateGrow( aGrowSource
, nGrowX
, nGrowY
);
1715 void ScDocument::DeleteArea(SCCOL nCol1
, SCROW nRow1
,
1716 SCCOL nCol2
, SCROW nRow2
,
1717 const ScMarkData
& rMark
, sal_uInt16 nDelFlag
)
1719 PutInOrder( nCol1
, nCol2
);
1720 PutInOrder( nRow1
, nRow2
);
1721 bool bOldAutoCalc
= GetAutoCalc();
1722 SetAutoCalc( false ); // avoid multiple calculations
1723 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1725 if ( rMark
.GetTableSelect(i
) || bIsUndo
)
1726 maTabs
[i
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1727 SetAutoCalc( bOldAutoCalc
);
1731 void ScDocument::DeleteAreaTab(SCCOL nCol1
, SCROW nRow1
,
1732 SCCOL nCol2
, SCROW nRow2
,
1733 SCTAB nTab
, sal_uInt16 nDelFlag
)
1735 PutInOrder( nCol1
, nCol2
);
1736 PutInOrder( nRow1
, nRow2
);
1737 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1739 bool bOldAutoCalc
= GetAutoCalc();
1740 SetAutoCalc( false ); // avoid multiple calculations
1741 maTabs
[nTab
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1742 SetAutoCalc( bOldAutoCalc
);
1747 void ScDocument::DeleteAreaTab( const ScRange
& rRange
, sal_uInt16 nDelFlag
)
1749 for ( SCTAB nTab
= rRange
.aStart
.Tab(); nTab
<= rRange
.aEnd
.Tab(); nTab
++ )
1750 DeleteAreaTab( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
1751 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
1756 void ScDocument::InitUndoSelected( ScDocument
* pSrcDoc
, const ScMarkData
& rTabSelection
,
1757 bool bColInfo
, bool bRowInfo
)
1763 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1767 for (SCTAB nTab
= 0; nTab
<= rTabSelection
.GetLastSelected(); nTab
++)
1768 if ( rTabSelection
.GetTableSelect( nTab
) )
1770 ScTable
* pTable
= new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1771 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1772 maTabs
[nTab
] = pTable
;
1774 maTabs
.push_back(pTable
);
1778 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1781 maTabs
.push_back(NULL
);
1786 OSL_FAIL("InitUndo");
1791 void ScDocument::InitUndo( ScDocument
* pSrcDoc
, SCTAB nTab1
, SCTAB nTab2
,
1792 bool bColInfo
, bool bRowInfo
)
1798 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1799 if (pSrcDoc
->pShell
->GetMedium())
1800 maFileURL
= pSrcDoc
->pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
1803 if ( nTab2
>= static_cast<SCTAB
>(maTabs
.size()))
1804 maTabs
.resize(nTab2
+ 1, NULL
);
1805 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1807 ScTable
* pTable
= new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1808 maTabs
[nTab
] = pTable
;
1813 OSL_FAIL("InitUndo");
1818 void ScDocument::AddUndoTab( SCTAB nTab1
, SCTAB nTab2
, bool bColInfo
, bool bRowInfo
)
1823 if (nTab2
>= static_cast<SCTAB
>(maTabs
.size()))
1825 maTabs
.resize(nTab2
+1,NULL
);
1827 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1830 maTabs
[nTab
] = new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1836 OSL_FAIL("InitUndo");
1841 void ScDocument::SetCutMode( bool bVal
)
1844 GetClipParam().mbCutMode
= bVal
;
1847 OSL_FAIL("SetCutMode without bIsClip");
1852 bool ScDocument::IsCutMode()
1855 return GetClipParam().mbCutMode
;
1858 OSL_FAIL("IsCutMode without bIsClip");
1864 void ScDocument::CopyToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1865 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1866 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1867 const ScMarkData
* pMarks
, bool bColRowFlags
)
1869 PutInOrder( nCol1
, nCol2
);
1870 PutInOrder( nRow1
, nRow2
);
1871 PutInOrder( nTab1
, nTab2
);
1872 if( pDestDoc
->aDocName
.isEmpty() )
1873 pDestDoc
->aDocName
= aDocName
;
1874 if (ValidTab(nTab1
) && ValidTab(nTab2
))
1876 sc::CopyToDocContext
aCxt(*pDestDoc
);
1877 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1878 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1879 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
1880 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
1882 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
1883 maTabs
[i
]->CopyToTable(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1884 bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
,
1885 false, bColRowFlags
);
1887 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1892 void ScDocument::UndoToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1893 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1894 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1895 const ScMarkData
* pMarks
)
1897 PutInOrder( nCol1
, nCol2
);
1898 PutInOrder( nRow1
, nRow2
);
1899 PutInOrder( nTab1
, nTab2
);
1900 if (ValidTab(nTab1
) && ValidTab(nTab2
))
1902 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1903 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1905 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, false, pDestDoc
, pMarks
);
1907 sc::CopyToDocContext
aCxt(*pDestDoc
);
1908 OSL_ASSERT( nTab2
< static_cast<SCTAB
>(maTabs
.size()) && nTab2
< static_cast<SCTAB
>(pDestDoc
->maTabs
.size()));
1909 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
1911 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
1912 maTabs
[i
]->UndoToTable(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1913 bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
);
1917 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
, false, pDestDoc
, pMarks
);
1918 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1923 void ScDocument::CopyToDocument(const ScRange
& rRange
,
1924 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1925 const ScMarkData
* pMarks
, bool bColRowFlags
)
1927 ScRange aNewRange
= rRange
;
1928 aNewRange
.Justify();
1930 if( pDestDoc
->aDocName
.isEmpty() )
1931 pDestDoc
->aDocName
= aDocName
;
1932 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1933 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1934 sc::CopyToDocContext
aCxt(*pDestDoc
);
1935 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
1936 for (SCTAB i
= aNewRange
.aStart
.Tab(); i
<= aNewRange
.aEnd
.Tab() && i
< nMinSizeBothTabs
; i
++)
1938 if (!TableExists(i
) || !pDestDoc
->TableExists(i
))
1941 maTabs
[i
]->CopyToTable(aCxt
, aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
1942 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
1943 nFlags
, bOnlyMarked
, pDestDoc
->maTabs
[i
],
1944 pMarks
, false, bColRowFlags
);
1946 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1950 void ScDocument::UndoToDocument(const ScRange
& rRange
,
1951 sal_uInt16 nFlags
, bool bOnlyMarked
, ScDocument
* pDestDoc
,
1952 const ScMarkData
* pMarks
)
1954 ScRange aNewRange
= rRange
;
1955 aNewRange
.Justify();
1956 SCTAB nTab1
= aNewRange
.aStart
.Tab();
1957 SCTAB nTab2
= aNewRange
.aEnd
.Tab();
1959 bool bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1960 pDestDoc
->SetAutoCalc( false ); // avoid multiple calculations
1961 sc::CopyToDocContext
aCxt(*pDestDoc
);
1963 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, false, pDestDoc
, pMarks
);
1965 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pDestDoc
->maTabs
.size()));
1966 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
1968 if (maTabs
[i
] && pDestDoc
->maTabs
[i
])
1969 maTabs
[i
]->UndoToTable(aCxt
, aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
1970 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
1971 nFlags
, bOnlyMarked
, pDestDoc
->maTabs
[i
], pMarks
);
1974 if (nTab2
< static_cast<SCTAB
>(maTabs
.size()))
1975 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,maTabs
.size(), IDF_FORMULA
, false, pDestDoc
, pMarks
);
1976 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1979 // bUseRangeForVBA added for VBA api support to allow content of a specified
1980 // range to be copied ( e.g. don't use marked data but the just the range
1981 // specified by rClipParam
1982 void ScDocument::CopyToClip(const ScClipParam
& rClipParam
,
1983 ScDocument
* pClipDoc
, const ScMarkData
* pMarks
,
1984 bool bAllTabs
, bool bKeepScenarioFlags
, bool bIncludeObjects
, bool bCloneNoteCaptions
, bool bUseRangeForVBA
)
1986 OSL_ENSURE( !bUseRangeForVBA
&& ( bAllTabs
|| pMarks
), "CopyToClip: ScMarkData fails" );
1993 OSL_TRACE("CopyToClip: no ClipDoc");
1994 pClipDoc
= SC_MOD()->GetClipDoc();
1997 if (pShell
->GetMedium())
1999 pClipDoc
->maFileURL
= pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
2000 // for unsaved files use the title name and adjust during save of file
2001 if (pClipDoc
->maFileURL
.isEmpty())
2002 pClipDoc
->maFileURL
= pShell
->GetName();
2006 pClipDoc
->maFileURL
= pShell
->GetName();
2010 for (TableContainer::iterator itr
= maTabs
.begin(); itr
!= maTabs
.end(); ++itr
)
2015 (*itr
)->GetName(aTabName
);
2016 pClipDoc
->maTabNames
.push_back(aTabName
);
2019 pClipDoc
->maTabNames
.push_back(OUString());
2022 pClipDoc
->aDocName
= aDocName
;
2023 pClipDoc
->SetClipParam(rClipParam
);
2024 ScRange aClipRange
= rClipParam
.getWholeRange();
2025 SCTAB nTab
= aClipRange
.aStart
.Tab();
2027 SCTAB nEndTab
= static_cast<SCTAB
>(maTabs
.size());
2029 if ( bUseRangeForVBA
)
2031 pClipDoc
->ResetClip( this, nTab
);
2036 pClipDoc
->ResetClip(this, pMarks
);
2038 sc::CopyToClipContext
aCxt(*pClipDoc
, bKeepScenarioFlags
, bCloneNoteCaptions
);
2039 CopyRangeNamesToClip(pClipDoc
, aClipRange
, pMarks
, bAllTabs
);
2041 for ( ; i
< nEndTab
; ++i
)
2043 if (!maTabs
[i
] || i
>= static_cast<SCTAB
>(pClipDoc
->maTabs
.size()) || !pClipDoc
->maTabs
[i
])
2046 if ( !bUseRangeForVBA
&& ( pMarks
&& !pMarks
->GetTableSelect(i
) ) )
2049 maTabs
[i
]->CopyToClip(aCxt
, rClipParam
.maRanges
, pClipDoc
->maTabs
[i
]);
2051 if (pDrawLayer
&& bIncludeObjects
)
2053 // also copy drawing objects
2054 Rectangle aObjRect
= GetMMRect(
2055 aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(), aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
2056 pDrawLayer
->CopyToClip(pClipDoc
, i
, aObjRect
);
2060 // Make sure to mark overlapped cells.
2061 pClipDoc
->ExtendMerge(aClipRange
, true);
2064 void ScDocument::CopyStaticToDocument(const ScRange
& rSrcRange
, SCTAB nDestTab
, ScDocument
* pDestDoc
)
2069 ScTable
* pSrcTab
= rSrcRange
.aStart
.Tab() < static_cast<SCTAB
>(maTabs
.size()) ? maTabs
[rSrcRange
.aStart
.Tab()] : NULL
;
2070 ScTable
* pDestTab
= nDestTab
< static_cast<SCTAB
>(pDestDoc
->maTabs
.size()) ? pDestDoc
->maTabs
[nDestTab
] : NULL
;
2072 if (!pSrcTab
|| !pDestTab
)
2075 pSrcTab
->CopyStaticToDocument(
2076 rSrcRange
.aStart
.Col(), rSrcRange
.aStart
.Row(), rSrcRange
.aEnd
.Col(), rSrcRange
.aEnd
.Row(), pDestTab
);
2079 void ScDocument::CopyCellToDocument( const ScAddress
& rSrcPos
, const ScAddress
& rDestPos
, ScDocument
& rDestDoc
)
2081 if (!TableExists(rSrcPos
.Tab()) || !rDestDoc
.TableExists(rDestPos
.Tab()))
2084 ScTable
& rSrcTab
= *maTabs
[rSrcPos
.Tab()];
2085 ScTable
& rDestTab
= *rDestDoc
.maTabs
[rDestPos
.Tab()];
2087 rSrcTab
.CopyCellToDocument(rSrcPos
.Col(), rSrcPos
.Row(), rDestPos
.Col(), rDestPos
.Row(), rDestTab
);
2090 void ScDocument::CopyTabToClip(SCCOL nCol1
, SCROW nRow1
,
2091 SCCOL nCol2
, SCROW nRow2
,
2092 SCTAB nTab
, ScDocument
* pClipDoc
)
2096 if (pShell
->GetMedium())
2098 pClipDoc
->maFileURL
= pShell
->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI
);
2099 // for unsaved files use the title name and adjust during save of file
2100 if (pClipDoc
->maFileURL
.isEmpty())
2101 pClipDoc
->maFileURL
= pShell
->GetName();
2105 pClipDoc
->maFileURL
= pShell
->GetName();
2109 for (TableContainer::iterator itr
= maTabs
.begin(); itr
!= maTabs
.end(); ++itr
)
2114 (*itr
)->GetName(aTabName
);
2115 pClipDoc
->maTabNames
.push_back(aTabName
);
2118 pClipDoc
->maTabNames
.push_back(OUString());
2121 PutInOrder( nCol1
, nCol2
);
2122 PutInOrder( nRow1
, nRow2
);
2125 OSL_TRACE("CopyTabToClip: no ClipDoc");
2126 pClipDoc
= SC_MOD()->GetClipDoc();
2129 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
2130 pClipDoc
->aDocName
= aDocName
;
2131 rClipParam
.maRanges
.RemoveAll();
2132 rClipParam
.maRanges
.Append(ScRange(nCol1
, nRow1
, 0, nCol2
, nRow2
, 0));
2133 pClipDoc
->ResetClip( this, nTab
);
2135 sc::CopyToClipContext
aCxt(*pClipDoc
, false, true);
2136 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && nTab
< static_cast<SCTAB
>(pClipDoc
->maTabs
.size()))
2137 if (maTabs
[nTab
] && pClipDoc
->maTabs
[nTab
])
2138 maTabs
[nTab
]->CopyToClip(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
, pClipDoc
->maTabs
[nTab
]);
2140 pClipDoc
->GetClipParam().mbCutMode
= false;
2145 void ScDocument::TransposeClip( ScDocument
* pTransClip
, sal_uInt16 nFlags
, bool bAsLink
)
2147 OSL_ENSURE( bIsClip
&& pTransClip
&& pTransClip
->bIsClip
,
2148 "TransposeClip with wrong Document" );
2151 // -> pTransClip muss vor dem Original-Dokument geloescht werden!
2153 pTransClip
->ResetClip(this, (ScMarkData
*)NULL
); // alle
2155 // Bereiche uebernehmen
2159 pTransClip
->GetRangeName()->clear();
2160 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
2161 for (; itr
!= itrEnd
; ++itr
)
2163 sal_uInt16 nIndex
= itr
->second
->GetIndex();
2164 ScRangeData
* pData
= new ScRangeData(*itr
->second
);
2165 if (pTransClip
->pRangeName
->insert(pData
))
2166 pData
->SetIndex(nIndex
);
2172 ScRange aClipRange
= GetClipParam().getWholeRange();
2173 if ( ValidRow(aClipRange
.aEnd
.Row()-aClipRange
.aStart
.Row()) )
2175 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2178 OSL_ENSURE( pTransClip
->maTabs
[i
], "TransposeClip: Table not there" );
2179 maTabs
[i
]->TransposeClip( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
2180 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(),
2181 pTransClip
->maTabs
[i
], nFlags
, bAsLink
);
2183 if ( pDrawLayer
&& ( nFlags
& IDF_OBJECTS
) )
2185 // Drawing objects are copied to the new area without transposing.
2186 // CopyFromClip is used to adjust the objects to the transposed block's
2188 // (pDrawLayer in the original clipboard document is set only if there
2189 // are drawing objects to copy)
2191 pTransClip
->InitDrawLayer();
2192 Rectangle aSourceRect
= GetMMRect( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
2193 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
2194 Rectangle aDestRect
= pTransClip
->GetMMRect( 0, 0,
2195 static_cast<SCCOL
>(aClipRange
.aEnd
.Row() - aClipRange
.aStart
.Row()),
2196 static_cast<SCROW
>(aClipRange
.aEnd
.Col() - aClipRange
.aStart
.Col()), i
);
2197 pTransClip
->pDrawLayer
->CopyFromClip( pDrawLayer
, i
, aSourceRect
, ScAddress(0,0,i
), aDestRect
);
2201 pTransClip
->SetClipParam(GetClipParam());
2202 pTransClip
->GetClipParam().transpose();
2206 OSL_TRACE("TransposeClip: Too big");
2209 // Dies passiert erst beim Einfuegen...
2211 GetClipParam().mbCutMode
= false;
2216 void copyUsedNamesToClip(ScRangeName
* pClipRangeName
, ScRangeName
* pRangeName
, const std::set
<sal_uInt16
>& rUsedNames
)
2218 pClipRangeName
->clear();
2219 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
2220 for (; itr
!= itrEnd
; ++itr
) //! DB-Bereiche Pivot-Bereiche auch !!!
2222 sal_uInt16 nIndex
= itr
->second
->GetIndex();
2223 bool bInUse
= (rUsedNames
.count(nIndex
) > 0);
2227 ScRangeData
* pData
= new ScRangeData(*itr
->second
);
2228 if (pClipRangeName
->insert(pData
))
2229 pData
->SetIndex(nIndex
);
2235 void ScDocument::CopyRangeNamesToClip(ScDocument
* pClipDoc
, const ScRange
& rClipRange
, const ScMarkData
* pMarks
, bool bAllTabs
)
2237 if (!pRangeName
|| pRangeName
->empty())
2240 std::set
<sal_uInt16
> aUsedNames
; // indexes of named ranges that are used in the copied cells
2241 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pClipDoc
->maTabs
.size()));
2242 for (SCTAB i
= 0; i
< nMinSizeBothTabs
; ++i
)
2243 if (maTabs
[i
] && pClipDoc
->maTabs
[i
])
2244 if ( bAllTabs
|| !pMarks
|| pMarks
->GetTableSelect(i
) )
2245 maTabs
[i
]->FindRangeNamesInUse(
2246 rClipRange
.aStart
.Col(), rClipRange
.aStart
.Row(),
2247 rClipRange
.aEnd
.Col(), rClipRange
.aEnd
.Row(), aUsedNames
);
2249 copyUsedNamesToClip(pClipDoc
->GetRangeName(), pRangeName
, aUsedNames
);
2252 ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument
* pDoc
, ScDocument
* pSrcDoc
) :
2255 mpDoc
->MergeNumberFormatter(pSrcDoc
);
2258 ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
2260 mpDoc
->pFormatExchangeList
= NULL
;
2263 SvtBroadcaster
* ScDocument::GetBroadcaster( const ScAddress
& rPos
)
2265 ScTable
* pTab
= FetchTable(rPos
.Tab());
2269 return pTab
->GetBroadcaster(rPos
.Col(), rPos
.Row());
2272 const SvtBroadcaster
* ScDocument::GetBroadcaster( const ScAddress
& rPos
) const
2274 const ScTable
* pTab
= FetchTable(rPos
.Tab());
2278 return pTab
->GetBroadcaster(rPos
.Col(), rPos
.Row());
2281 void ScDocument::DeleteBroadcasters( sc::ColumnBlockPosition
& rBlockPos
, const ScAddress
& rTopPos
, SCROW nLength
)
2283 ScTable
* pTab
= FetchTable(rTopPos
.Tab());
2284 if (!pTab
|| nLength
<= 0)
2287 pTab
->DeleteBroadcasters(rBlockPos
, rTopPos
.Col(), rTopPos
.Row(), rTopPos
.Row()+nLength
-1);
2290 bool ScDocument::HasBroadcaster( SCTAB nTab
, SCCOL nCol
) const
2292 const ScTable
* pTab
= FetchTable(nTab
);
2296 return pTab
->HasBroadcaster(nCol
);
2299 bool ScDocument::TableExists( SCTAB nTab
) const
2301 return ValidTab(nTab
) && static_cast<size_t>(nTab
) < maTabs
.size() && maTabs
[nTab
];
2304 ScTable
* ScDocument::FetchTable( SCTAB nTab
)
2306 if (!TableExists(nTab
))
2309 return maTabs
[nTab
];
2312 const ScTable
* ScDocument::FetchTable( SCTAB nTab
) const
2314 if (!TableExists(nTab
))
2317 return maTabs
[nTab
];
2320 void ScDocument::MergeNumberFormatter(ScDocument
* pSrcDoc
)
2322 SvNumberFormatter
* pThisFormatter
= xPoolHelper
->GetFormTable();
2323 SvNumberFormatter
* pOtherFormatter
= pSrcDoc
->xPoolHelper
->GetFormTable();
2324 if (pOtherFormatter
&& pOtherFormatter
!= pThisFormatter
)
2326 SvNumberFormatterIndexTable
* pExchangeList
=
2327 pThisFormatter
->MergeFormatter(*(pOtherFormatter
));
2328 if (!pExchangeList
->empty())
2329 pFormatExchangeList
= pExchangeList
;
2333 ScClipParam
& ScDocument::GetClipParam()
2335 if (!mpClipParam
.get())
2336 mpClipParam
.reset(new ScClipParam
);
2338 return *mpClipParam
;
2341 void ScDocument::SetClipParam(const ScClipParam
& rParam
)
2343 mpClipParam
.reset(new ScClipParam(rParam
));
2346 bool ScDocument::IsClipboardSource() const
2348 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
2349 return pClipDoc
&& pClipDoc
->xPoolHelper
.is() &&
2350 xPoolHelper
->GetDocPool() == pClipDoc
->xPoolHelper
->GetDocPool();
2354 void ScDocument::StartListeningFromClip( SCCOL nCol1
, SCROW nRow1
,
2355 SCCOL nCol2
, SCROW nRow2
,
2356 const ScMarkData
& rMark
, sal_uInt16 nInsFlag
)
2358 if (nInsFlag
& IDF_CONTENTS
)
2360 sc::StartListeningContext
aCxt(*this);
2361 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
2362 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2363 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
2365 maTabs
[*itr
]->StartListeningInArea(aCxt
, nCol1
, nRow1
, nCol2
, nRow2
);
2370 void ScDocument::BroadcastFromClip( SCCOL nCol1
, SCROW nRow1
,
2371 SCCOL nCol2
, SCROW nRow2
,
2372 const ScMarkData
& rMark
, sal_uInt16 nInsFlag
)
2374 if (nInsFlag
& IDF_CONTENTS
)
2376 ScBulkBroadcast
aBulkBroadcast( GetBASM());
2377 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
2378 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2379 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
2381 maTabs
[*itr
]->BroadcastInArea( nCol1
, nRow1
, nCol2
, nRow2
);
2385 bool ScDocument::InitColumnBlockPosition( sc::ColumnBlockPosition
& rBlockPos
, SCTAB nTab
, SCCOL nCol
)
2387 if (!TableExists(nTab
))
2390 return maTabs
[nTab
]->InitColumnBlockPosition(rBlockPos
, nCol
);
2393 void ScDocument::CopyBlockFromClip(
2394 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
2395 const ScMarkData
& rMark
, SCsCOL nDx
, SCsROW nDy
)
2397 TableContainer
& rClipTabs
= rCxt
.getClipDoc()->maTabs
;
2398 SCTAB nTabEnd
= rCxt
.getTabEnd();
2400 for (SCTAB i
= rCxt
.getTabStart(); i
<= nTabEnd
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2402 if (maTabs
[i
] && rMark
.GetTableSelect(i
) )
2404 while (!rClipTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2406 maTabs
[i
]->CopyFromClip(
2407 rCxt
, nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, rClipTabs
[nClipTab
]);
2409 if (rCxt
.getClipDoc()->pDrawLayer
&& (rCxt
.getInsertFlag() & IDF_OBJECTS
))
2411 // also copy drawing objects
2413 // drawing layer must be created before calling CopyFromClip
2414 // (ScDocShell::MakeDrawLayer also does InitItems etc.)
2415 OSL_ENSURE( pDrawLayer
, "CopyBlockFromClip: No drawing layer" );
2418 // For GetMMRect, the row heights in the target document must already be valid
2419 // (copied in an extra step before pasting, or updated after pasting cells, but
2420 // before pasting objects).
2422 Rectangle aSourceRect
= rCxt
.getClipDoc()->GetMMRect(
2423 nCol1
-nDx
, nRow1
-nDy
, nCol2
-nDx
, nRow2
-nDy
, nClipTab
);
2424 Rectangle aDestRect
= GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, i
);
2425 pDrawLayer
->CopyFromClip(rCxt
.getClipDoc()->pDrawLayer
, nClipTab
, aSourceRect
,
2426 ScAddress( nCol1
, nRow1
, i
), aDestRect
);
2430 nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2433 if (rCxt
.getInsertFlag() & IDF_CONTENTS
)
2436 for (SCTAB i
= rCxt
.getTabStart(); i
<= nTabEnd
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
2438 if (maTabs
[i
] && rMark
.GetTableSelect(i
) )
2440 while (!rClipTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2441 SCsTAB nDz
= ((SCsTAB
)i
) - nClipTab
;
2443 // ranges of consecutive selected tables (in clipboard and dest. doc)
2444 // must be handled in one UpdateReference call
2446 while ( i
+ nFollow
< nTabEnd
2447 && rMark
.GetTableSelect( i
+ nFollow
+ 1 )
2448 && nClipTab
+ nFollow
< MAXTAB
2449 && rClipTabs
[(nClipTab
+ nFollow
+ 1) % static_cast<SCTAB
>(rClipTabs
.size())] )
2452 if (rCxt
.getClipDoc()->GetClipParam().mbCutMode
)
2454 bool bOldInserting
= IsInsertingFromOtherDoc();
2455 SetInsertingFromOtherDoc( true);
2456 UpdateReference( URM_MOVE
,
2457 nCol1
, nRow1
, i
, nCol2
, nRow2
, i
+nFollow
,
2458 nDx
, nDy
, nDz
, rCxt
.getUndoDoc(), false );
2459 SetInsertingFromOtherDoc( bOldInserting
);
2462 UpdateReference( URM_COPY
,
2463 nCol1
, nRow1
, i
, nCol2
, nRow2
, i
+nFollow
,
2464 nDx
, nDy
, nDz
, rCxt
.getUndoDoc(), false );
2466 nClipTab
= (nClipTab
+nFollow
+1) % (static_cast<SCTAB
>(rClipTabs
.size()));
2467 i
= sal::static_int_cast
<SCTAB
>( i
+ nFollow
);
2474 void ScDocument::CopyNonFilteredFromClip(
2475 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
2476 const ScMarkData
& rMark
, SCsCOL nDx
, SCROW
& rClipStartRow
)
2478 // call CopyBlockFromClip for ranges of consecutive non-filtered rows
2479 // nCol1/nRow1 etc. is in target doc
2481 // filtered state is taken from first used table in clipboard (as in GetClipArea)
2483 TableContainer
& rClipTabs
= rCxt
.getClipDoc()->maTabs
;
2484 while ( nFlagTab
< static_cast<SCTAB
>(rClipTabs
.size()) && !rClipTabs
[nFlagTab
] )
2487 SCROW nSourceRow
= rClipStartRow
;
2488 SCROW nSourceEnd
= 0;
2489 if (!rCxt
.getClipDoc()->GetClipParam().maRanges
.empty())
2490 nSourceEnd
= rCxt
.getClipDoc()->GetClipParam().maRanges
.front()->aEnd
.Row();
2491 SCROW nDestRow
= nRow1
;
2493 while ( nSourceRow
<= nSourceEnd
&& nDestRow
<= nRow2
)
2495 // skip filtered rows
2496 nSourceRow
= rCxt
.getClipDoc()->FirstNonFilteredRow(nSourceRow
, nSourceEnd
, nFlagTab
);
2498 if ( nSourceRow
<= nSourceEnd
)
2500 // look for more non-filtered rows following
2501 SCROW nLastRow
= nSourceRow
;
2502 rCxt
.getClipDoc()->RowFiltered(nSourceRow
, nFlagTab
, NULL
, &nLastRow
);
2503 SCROW nFollow
= nLastRow
- nSourceRow
;
2505 if (nFollow
> nSourceEnd
- nSourceRow
)
2506 nFollow
= nSourceEnd
- nSourceRow
;
2507 if (nFollow
> nRow2
- nDestRow
)
2508 nFollow
= nRow2
- nDestRow
;
2510 SCsROW nNewDy
= ((SCsROW
)nDestRow
) - nSourceRow
;
2512 rCxt
, nCol1
, nDestRow
, nCol2
, nDestRow
+ nFollow
, rMark
, nDx
, nNewDy
);
2514 nSourceRow
+= nFollow
+ 1;
2515 nDestRow
+= nFollow
+ 1;
2518 rClipStartRow
= nSourceRow
;
2522 void ScDocument::CopyFromClip( const ScRange
& rDestRange
, const ScMarkData
& rMark
,
2523 sal_uInt16 nInsFlag
,
2524 ScDocument
* pRefUndoDoc
, ScDocument
* pClipDoc
, bool bResetCut
,
2525 bool bAsLink
, bool bIncludeFiltered
, bool bSkipAttrForEmpty
,
2526 const ScRangeList
* pDestRanges
)
2533 OSL_FAIL("CopyFromClip: no ClipDoc");
2534 pClipDoc
= SC_MOD()->GetClipDoc();
2537 if (!pClipDoc
->bIsClip
|| !pClipDoc
->GetTableCount())
2540 bool bOldAutoCalc
= GetAutoCalc();
2541 SetAutoCalc( false ); // avoid multiple recalculations
2543 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2545 SCCOL nAllCol1
= rDestRange
.aStart
.Col();
2546 SCROW nAllRow1
= rDestRange
.aStart
.Row();
2547 SCCOL nAllCol2
= rDestRange
.aEnd
.Col();
2548 SCROW nAllRow2
= rDestRange
.aEnd
.Row();
2552 ScRange aClipRange
= pClipDoc
->GetClipParam().getWholeRange();
2553 for (SCTAB nTab
= 0; nTab
< static_cast<SCTAB
>(pClipDoc
->maTabs
.size()); nTab
++) // find largest merge overlap
2554 if (pClipDoc
->maTabs
[nTab
]) // all sheets of the clipboard content
2556 SCCOL nThisEndX
= aClipRange
.aEnd
.Col();
2557 SCROW nThisEndY
= aClipRange
.aEnd
.Row();
2558 pClipDoc
->ExtendMerge( aClipRange
.aStart
.Col(),
2559 aClipRange
.aStart
.Row(),
2560 nThisEndX
, nThisEndY
, nTab
);
2561 // only extra value from ExtendMerge
2562 nThisEndX
= sal::static_int_cast
<SCCOL
>( nThisEndX
- aClipRange
.aEnd
.Col() );
2563 nThisEndY
= sal::static_int_cast
<SCROW
>( nThisEndY
- aClipRange
.aEnd
.Row() );
2564 if ( nThisEndX
> nXw
)
2566 if ( nThisEndY
> nYw
)
2572 pClipDoc
->GetClipArea( nDestAddX
, nDestAddY
, bIncludeFiltered
);
2573 nXw
= sal::static_int_cast
<SCCOL
>( nXw
+ nDestAddX
);
2574 nYw
= sal::static_int_cast
<SCROW
>( nYw
+ nDestAddY
); // ClipArea, plus ExtendMerge value
2576 /* Decide which contents to delete before copying. Delete all
2577 contents if nInsFlag contains any real content flag.
2578 #i102056# Notes are pasted from clipboard in a second pass,
2579 together with the special flag IDF_ADDNOTES that states to not
2580 overwrite/delete existing cells but to insert the notes into
2581 these cells. In this case, just delete old notes from the
2582 destination area. */
2583 sal_uInt16 nDelFlag
= IDF_NONE
;
2584 if ( (nInsFlag
& (IDF_CONTENTS
| IDF_ADDNOTES
)) == (IDF_NOTE
| IDF_ADDNOTES
) )
2585 nDelFlag
|= IDF_NOTE
;
2586 else if ( nInsFlag
& IDF_CONTENTS
)
2587 nDelFlag
|= IDF_CONTENTS
;
2588 // With bSkipAttrForEmpty, don't remove attributes, copy
2589 // on top of existing attributes instead.
2590 if ( ( nInsFlag
& IDF_ATTRIB
) && !bSkipAttrForEmpty
)
2591 nDelFlag
|= IDF_ATTRIB
;
2593 sc::CopyFromClipContext
aCxt(*this, pRefUndoDoc
, pClipDoc
, nInsFlag
, bAsLink
, bSkipAttrForEmpty
);
2594 std::pair
<SCTAB
,SCTAB
> aTabRanges
= getMarkedTableRange(maTabs
, rMark
);
2595 aCxt
.setTabRange(aTabRanges
.first
, aTabRanges
.second
);
2597 ScRangeList aLocalRangeList
;
2600 aLocalRangeList
.Append( rDestRange
);
2601 pDestRanges
= &aLocalRangeList
;
2604 bInsertingFromOtherDoc
= true; // kein Broadcast/Listener aufbauen bei Insert
2606 SCCOL nClipStartCol
= aClipRange
.aStart
.Col();
2607 SCROW nClipStartRow
= aClipRange
.aStart
.Row();
2608 SCROW nClipEndRow
= aClipRange
.aEnd
.Row();
2609 for ( size_t nRange
= 0; nRange
< pDestRanges
->size(); ++nRange
)
2611 const ScRange
* pRange
= (*pDestRanges
)[nRange
];
2612 SCCOL nCol1
= pRange
->aStart
.Col();
2613 SCROW nRow1
= pRange
->aStart
.Row();
2614 SCCOL nCol2
= pRange
->aEnd
.Col();
2615 SCROW nRow2
= pRange
->aEnd
.Row();
2617 DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, rMark
, nDelFlag
);
2621 SCCOL nC2
= nC1
+ nXw
;
2624 SCROW nR2
= nR1
+ nYw
;
2630 // Pasting is done column-wise, when pasting to a filtered
2631 // area this results in partitioning and we have to
2632 // remember and reset the start row for each column until
2633 // it can be advanced for the next chunk of unfiltered
2635 SCROW nSaveClipStartRow
= nClipStartRow
;
2638 nClipStartRow
= nSaveClipStartRow
;
2639 SCsCOL nDx
= ((SCsCOL
)nC1
) - nClipStartCol
;
2640 SCsROW nDy
= ((SCsROW
)nR1
) - nClipStartRow
;
2641 if ( bIncludeFiltered
)
2644 aCxt
, nC1
, nR1
, nC2
, nR2
, rMark
, nDx
, nDy
);
2645 nClipStartRow
+= nR2
- nR1
+ 1;
2649 CopyNonFilteredFromClip(
2650 aCxt
, nC1
, nR1
, nC2
, nR2
, rMark
, nDx
, nClipStartRow
);
2653 nC2
= std::min((SCCOL
)(nC1
+ nXw
), nCol2
);
2654 } while (nC1
<= nCol2
);
2655 if (nClipStartRow
> nClipEndRow
)
2656 nClipStartRow
= aClipRange
.aStart
.Row();
2662 nR2
= std::min((SCROW
)(nR1
+ nYw
), nRow2
);
2663 } while (nR1
<= nRow2
);
2666 bInsertingFromOtherDoc
= false;
2668 // Listener aufbauen nachdem alles inserted wurde
2669 StartListeningFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2670 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2671 BroadcastFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2673 pClipDoc
->GetClipParam().mbCutMode
= false;
2674 SetAutoCalc( bOldAutoCalc
);
2677 static SCROW
lcl_getLastNonFilteredRow(
2678 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>& rFlags
, SCROW nBegRow
, SCROW nEndRow
,
2681 SCROW nFilteredRow
= rFlags
.GetFirstForCondition(
2682 nBegRow
, nEndRow
, CR_FILTERED
, CR_FILTERED
);
2684 SCROW nRow
= nFilteredRow
- 1;
2685 if (nRow
- nBegRow
+ 1 > nRowCount
)
2686 // make sure the row range stays within the data size.
2687 nRow
= nBegRow
+ nRowCount
- 1;
2692 void ScDocument::CopyMultiRangeFromClip(
2693 const ScAddress
& rDestPos
, const ScMarkData
& rMark
, sal_uInt16 nInsFlag
, ScDocument
* pClipDoc
,
2694 bool bResetCut
, bool bAsLink
, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty
)
2699 if (!pClipDoc
->bIsClip
|| !pClipDoc
->GetTableCount())
2700 // There is nothing in the clip doc to copy.
2703 bool bOldAutoCalc
= GetAutoCalc();
2704 SetAutoCalc( false ); // avoid multiple recalculations
2706 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2708 SCCOL nCol1
= rDestPos
.Col();
2709 SCROW nRow1
= rDestPos
.Row();
2710 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
2712 sc::CopyFromClipContext
aCxt(*this, NULL
, pClipDoc
, nInsFlag
, bAsLink
, bSkipAttrForEmpty
);
2713 std::pair
<SCTAB
,SCTAB
> aTabRanges
= getMarkedTableRange(maTabs
, rMark
);
2714 aCxt
.setTabRange(aTabRanges
.first
, aTabRanges
.second
);
2717 rMark
.GetMarkArea(aDestRange
);
2718 SCROW nLastMarkedRow
= aDestRange
.aEnd
.Row();
2720 bInsertingFromOtherDoc
= true; // kein Broadcast/Listener aufbauen bei Insert
2722 SCROW nBegRow
= nRow1
;
2723 sal_uInt16 nDelFlag
= IDF_CONTENTS
;
2724 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>& rFlags
= GetRowFlagsArray(aCxt
.getTabStart());
2726 for ( size_t i
= 0, n
= rClipParam
.maRanges
.size(); i
< n
; ++i
)
2728 ScRange
* p
= rClipParam
.maRanges
[ i
];
2729 // The begin row must not be filtered.
2731 SCROW nRowCount
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
2733 SCsCOL nDx
= static_cast<SCsCOL
>(nCol1
- p
->aStart
.Col());
2734 SCsROW nDy
= static_cast<SCsROW
>(nBegRow
- p
->aStart
.Row());
2735 SCCOL nCol2
= nCol1
+ p
->aEnd
.Col() - p
->aStart
.Col();
2737 SCROW nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2739 if (!bSkipAttrForEmpty
)
2740 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2742 CopyBlockFromClip(aCxt
, nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
);
2743 nRowCount
-= nEndRow
- nBegRow
+ 1;
2745 while (nRowCount
> 0)
2747 // Get the first non-filtered row.
2748 SCROW nNonFilteredRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2749 if (nNonFilteredRow
> nLastMarkedRow
)
2752 SCROW nRowsSkipped
= nNonFilteredRow
- nEndRow
- 1;
2753 nDy
+= nRowsSkipped
;
2755 nBegRow
= nNonFilteredRow
;
2756 nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2758 if (!bSkipAttrForEmpty
)
2759 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2761 CopyBlockFromClip(aCxt
, nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
);
2762 nRowCount
-= nEndRow
- nBegRow
+ 1;
2765 if (rClipParam
.meDirection
== ScClipParam::Row
)
2766 // Begin row for the next range being pasted.
2767 nBegRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2771 if (rClipParam
.meDirection
== ScClipParam::Column
)
2772 nCol1
+= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
2775 bInsertingFromOtherDoc
= false;
2777 ScRangeList aRanges
;
2778 aRanges
.Append(aDestRange
);
2780 // Listener aufbauen nachdem alles inserted wurde
2781 StartListeningFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2782 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2783 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2784 BroadcastFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2785 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2788 pClipDoc
->GetClipParam().mbCutMode
= false;
2789 SetAutoCalc( bOldAutoCalc
);
2792 void ScDocument::SetClipArea( const ScRange
& rArea
, bool bCut
)
2796 ScClipParam
& rClipParam
= GetClipParam();
2797 rClipParam
.maRanges
.RemoveAll();
2798 rClipParam
.maRanges
.Append(rArea
);
2799 rClipParam
.mbCutMode
= bCut
;
2803 OSL_FAIL("SetClipArea: No Clip");
2808 void ScDocument::GetClipArea(SCCOL
& nClipX
, SCROW
& nClipY
, bool bIncludeFiltered
)
2812 OSL_FAIL("GetClipArea: No Clip");
2816 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2817 if (rClipRanges
.empty())
2818 // No clip range. Bail out.
2821 ScRange
* p
= rClipRanges
.front();
2822 SCCOL nStartCol
= p
->aStart
.Col();
2823 SCCOL nEndCol
= p
->aEnd
.Col();
2824 SCROW nStartRow
= p
->aStart
.Row();
2825 SCROW nEndRow
= p
->aEnd
.Row();
2826 for ( size_t i
= 1, n
= rClipRanges
.size(); i
< n
; ++i
)
2828 p
= rClipRanges
[ i
];
2829 if (p
->aStart
.Col() < nStartCol
)
2830 nStartCol
= p
->aStart
.Col();
2831 if (p
->aStart
.Row() < nStartRow
)
2832 nStartRow
= p
->aStart
.Row();
2833 if (p
->aEnd
.Col() > nEndCol
)
2834 nEndCol
= p
->aEnd
.Col();
2835 if (p
->aEnd
.Row() < nEndRow
)
2836 nEndRow
= p
->aEnd
.Row();
2839 nClipX
= nEndCol
- nStartCol
;
2841 if ( bIncludeFiltered
)
2842 nClipY
= nEndRow
- nStartRow
;
2845 // count non-filtered rows
2846 // count on first used table in clipboard
2847 SCTAB nCountTab
= 0;
2848 while ( nCountTab
< static_cast<SCTAB
>(maTabs
.size()) && !maTabs
[nCountTab
] )
2851 SCROW nResult
= CountNonFilteredRows(nStartRow
, nEndRow
, nCountTab
);
2854 nClipY
= nResult
- 1;
2856 nClipY
= 0; // always return at least 1 row
2861 void ScDocument::GetClipStart(SCCOL
& nClipX
, SCROW
& nClipY
)
2865 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2866 if ( !rClipRanges
.empty() )
2868 nClipX
= rClipRanges
.front()->aStart
.Col();
2869 nClipY
= rClipRanges
.front()->aStart
.Row();
2874 OSL_FAIL("GetClipStart: No Clip");
2879 bool ScDocument::HasClipFilteredRows()
2881 // count on first used table in clipboard
2882 SCTAB nCountTab
= 0;
2883 while ( nCountTab
< static_cast<SCTAB
>(maTabs
.size()) && !maTabs
[nCountTab
] )
2886 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2887 if ( rClipRanges
.empty() )
2890 for ( size_t i
= 0, n
= rClipRanges
.size(); i
< n
; ++i
)
2892 ScRange
* p
= rClipRanges
[ i
];
2893 bool bAnswer
= maTabs
[nCountTab
]->HasFilteredRows(p
->aStart
.Row(), p
->aEnd
.Row());
2901 void ScDocument::MixDocument( const ScRange
& rRange
, sal_uInt16 nFunction
, bool bSkipEmpty
,
2902 ScDocument
* pSrcDoc
)
2904 SCTAB nTab1
= rRange
.aStart
.Tab();
2905 SCTAB nTab2
= rRange
.aEnd
.Tab();
2906 sc::MixDocContext
aCxt(*this);
2907 SCTAB nMinSizeBothTabs
= static_cast<SCTAB
>(std::min(maTabs
.size(), pSrcDoc
->maTabs
.size()));
2908 for (SCTAB i
= nTab1
; i
<= nTab2
&& i
< nMinSizeBothTabs
; i
++)
2910 ScTable
* pTab
= FetchTable(i
);
2911 const ScTable
* pSrcTab
= pSrcDoc
->FetchTable(i
);
2912 if (!pTab
|| !pSrcTab
)
2916 aCxt
, rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
2917 nFunction
, bSkipEmpty
, pSrcTab
);
2922 void ScDocument::FillTab( const ScRange
& rSrcArea
, const ScMarkData
& rMark
,
2923 sal_uInt16 nFlags
, sal_uInt16 nFunction
,
2924 bool bSkipEmpty
, bool bAsLink
)
2926 sal_uInt16 nDelFlags
= nFlags
;
2927 if (nDelFlags
& IDF_CONTENTS
)
2928 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
2930 SCTAB nSrcTab
= rSrcArea
.aStart
.Tab();
2932 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
2934 SCCOL nStartCol
= rSrcArea
.aStart
.Col();
2935 SCROW nStartRow
= rSrcArea
.aStart
.Row();
2936 SCCOL nEndCol
= rSrcArea
.aEnd
.Col();
2937 SCROW nEndRow
= rSrcArea
.aEnd
.Row();
2938 boost::scoped_ptr
<ScDocument
> pMixDoc
;
2939 bool bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
2941 bool bOldAutoCalc
= GetAutoCalc();
2942 SetAutoCalc( false ); // avoid multiple calculations
2944 sc::CopyToDocContext
aCxt(*this);
2945 sc::MixDocContext
aMixDocCxt(*this);
2947 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
2948 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
2949 for (; itr
!= itrEnd
&& *itr
< nCount
; ++itr
)
2950 if ( *itr
!=nSrcTab
&& maTabs
[*itr
])
2957 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
2958 pMixDoc
->InitUndo( this, i
, i
);
2961 pMixDoc
->AddUndoTab( i
, i
);
2963 // context used for copying content to the temporary mix document.
2964 sc::CopyToDocContext
aMixCxt(*pMixDoc
);
2965 maTabs
[i
]->CopyToTable(aMixCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2966 IDF_CONTENTS
, false, pMixDoc
->maTabs
[i
] );
2968 maTabs
[i
]->DeleteArea( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nDelFlags
);
2969 maTabs
[nSrcTab
]->CopyToTable(aCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2970 nFlags
, false, maTabs
[i
], NULL
, bAsLink
);
2973 maTabs
[i
]->MixData(aMixDocCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2974 nFunction
, bSkipEmpty
, pMixDoc
->maTabs
[i
] );
2977 SetAutoCalc( bOldAutoCalc
);
2981 OSL_FAIL("wrong table");
2986 void ScDocument::FillTabMarked( SCTAB nSrcTab
, const ScMarkData
& rMark
,
2987 sal_uInt16 nFlags
, sal_uInt16 nFunction
,
2988 bool bSkipEmpty
, bool bAsLink
)
2990 sal_uInt16 nDelFlags
= nFlags
;
2991 if (nDelFlags
& IDF_CONTENTS
)
2992 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
2994 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
2996 boost::scoped_ptr
<ScDocument
> pMixDoc
;
2997 bool bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
2999 bool bOldAutoCalc
= GetAutoCalc();
3000 SetAutoCalc( false ); // avoid multiple calculations
3003 rMark
.GetMultiMarkArea( aArea
);
3004 SCCOL nStartCol
= aArea
.aStart
.Col();
3005 SCROW nStartRow
= aArea
.aStart
.Row();
3006 SCCOL nEndCol
= aArea
.aEnd
.Col();
3007 SCROW nEndRow
= aArea
.aEnd
.Row();
3009 sc::CopyToDocContext
aCxt(*this);
3010 sc::MixDocContext
aMixDocCxt(*this);
3011 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
3012 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
3013 for (; itr
!= itrEnd
&& *itr
< nCount
; ++itr
)
3014 if ( *itr
!=nSrcTab
&& maTabs
[*itr
] )
3021 pMixDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
3022 pMixDoc
->InitUndo( this, i
, i
);
3025 pMixDoc
->AddUndoTab( i
, i
);
3027 sc::CopyToDocContext
aMixCxt(*pMixDoc
);
3028 maTabs
[i
]->CopyToTable(aMixCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3029 IDF_CONTENTS
, true, pMixDoc
->maTabs
[i
], &rMark
);
3032 maTabs
[i
]->DeleteSelection( nDelFlags
, rMark
);
3033 maTabs
[nSrcTab
]->CopyToTable(aCxt
, nStartCol
,nStartRow
, nEndCol
,nEndRow
,
3034 nFlags
, true, maTabs
[i
], &rMark
, bAsLink
);
3037 maTabs
[i
]->MixMarked(aMixDocCxt
, rMark
, nFunction
, bSkipEmpty
, pMixDoc
->maTabs
[i
]);
3040 SetAutoCalc( bOldAutoCalc
);
3044 OSL_FAIL("wrong table");
3048 void ScDocument::PutCell( const ScAddress
& rPos
, ScBaseCell
* pCell
, bool bForceTab
)
3050 SCTAB nTab
= rPos
.Tab();
3051 if ( bForceTab
&& ( nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
]) )
3053 bool bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
3055 if (nTab
>= static_cast<SCTAB
>(maTabs
.size()))
3056 maTabs
.resize(nTab
+ 1,NULL
);
3057 maTabs
[nTab
] = new ScTable(this, nTab
,
3063 maTabs
[nTab
]->PutCell( rPos
, pCell
);
3067 bool ScDocument::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const OUString
& rString
,
3068 ScSetStringParam
* pParam
)
3070 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3071 return maTabs
[nTab
]->SetString( nCol
, nRow
, nTab
, rString
, pParam
);
3076 bool ScDocument::SetString(
3077 const ScAddress
& rPos
, const OUString
& rString
, ScSetStringParam
* pParam
)
3079 return SetString(rPos
.Col(), rPos
.Row(), rPos
.Tab(), rString
, pParam
);
3082 void ScDocument::SetEditText( const ScAddress
& rPos
, EditTextObject
* pEditText
)
3084 if (!TableExists(rPos
.Tab()))
3090 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), pEditText
);
3093 void ScDocument::SetEditText( const ScAddress
& rPos
, const EditTextObject
& rEditText
, const SfxItemPool
* pEditPool
)
3095 if (!TableExists(rPos
.Tab()))
3098 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEditText
, pEditPool
);
3101 void ScDocument::SetEditText( const ScAddress
& rPos
, const OUString
& rStr
)
3103 if (!TableExists(rPos
.Tab()))
3106 ScFieldEditEngine
& rEngine
= GetEditEngine();
3107 rEngine
.SetText(rStr
);
3108 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEngine
.CreateTextObject());
3111 void ScDocument::SetTextCell( const ScAddress
& rPos
, const OUString
& rStr
)
3113 if (!TableExists(rPos
.Tab()))
3116 if (ScStringUtil::isMultiline(rStr
))
3118 ScFieldEditEngine
& rEngine
= GetEditEngine();
3119 rEngine
.SetText(rStr
);
3120 maTabs
[rPos
.Tab()]->SetEditText(rPos
.Col(), rPos
.Row(), rEngine
.CreateTextObject());
3124 ScSetStringParam aParam
;
3125 aParam
.setTextInput();
3126 maTabs
[rPos
.Tab()]->SetString(rPos
.Col(), rPos
.Row(), rPos
.Tab(), rStr
, &aParam
);
3130 void ScDocument::SetEmptyCell( const ScAddress
& rPos
)
3132 if (!TableExists(rPos
.Tab()))
3135 maTabs
[rPos
.Tab()]->SetEmptyCell(rPos
.Col(), rPos
.Row());
3138 void ScDocument::SetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const double& rVal
)
3140 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
3142 maTabs
[nTab
]->SetValue( nCol
, nRow
, rVal
);
3145 void ScDocument::SetValue( const ScAddress
& rPos
, double fVal
)
3147 if (!TableExists(rPos
.Tab()))
3150 maTabs
[rPos
.Tab()]->SetValue(rPos
.Col(), rPos
.Row(), fVal
);
3153 OUString
ScDocument::GetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3155 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
3158 maTabs
[nTab
]->GetString(nCol
, nRow
, aStr
);
3162 return EMPTY_OUSTRING
;
3165 OUString
ScDocument::GetString( const ScAddress
& rPos
) const
3167 if (!TableExists(rPos
.Tab()))
3168 return EMPTY_OUSTRING
;
3171 maTabs
[rPos
.Tab()]->GetString(rPos
.Col(), rPos
.Row(), aStr
);
3175 const OUString
* ScDocument::GetStringCell( const ScAddress
& rPos
) const
3177 if (!TableExists(rPos
.Tab()))
3180 return maTabs
[rPos
.Tab()]->GetStringCell(rPos
.Col(), rPos
.Row());
3183 double* ScDocument::GetValueCell( const ScAddress
& rPos
)
3185 if (!TableExists(rPos
.Tab()))
3188 return maTabs
[rPos
.Tab()]->GetValueCell(rPos
.Col(), rPos
.Row());
3191 void ScDocument::GetInputString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rString
)
3193 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3194 maTabs
[nTab
]->GetInputString( nCol
, nRow
, rString
);
3196 rString
= OUString();
3199 void ScDocument::GetInputString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rString
)
3202 GetInputString( nCol
, nRow
, nTab
, aString
);
3206 sal_uInt16
ScDocument::GetStringForFormula( const ScAddress
& rPos
, OUString
& rString
)
3208 // Used in formulas (add-in parameters etc), so it must use the same semantics as
3209 // ScInterpreter::GetCellString: always format values as numbers.
3210 // The return value is the error code.
3212 ScRefCellValue aCell
;
3213 aCell
.assign(*this, rPos
);
3214 if (aCell
.isEmpty())
3216 rString
= EMPTY_OUSTRING
;
3220 sal_uInt16 nErr
= 0;
3222 SvNumberFormatter
* pFormatter
= GetFormatTable();
3223 switch (aCell
.meType
)
3225 case CELLTYPE_STRING
:
3227 aStr
= aCell
.getString(this);
3229 case CELLTYPE_FORMULA
:
3231 ScFormulaCell
* pFCell
= aCell
.mpFormula
;
3232 nErr
= pFCell
->GetErrCode();
3233 if (pFCell
->IsValue())
3235 double fVal
= pFCell
->GetValue();
3236 sal_uInt32 nIndex
= pFormatter
->GetStandardFormat(
3237 NUMBERFORMAT_NUMBER
,
3239 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
3242 aStr
= pFCell
->GetString();
3245 case CELLTYPE_VALUE
:
3247 double fVal
= aCell
.mfValue
;
3248 sal_uInt32 nIndex
= pFormatter
->GetStandardFormat(
3249 NUMBERFORMAT_NUMBER
,
3251 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
3263 void ScDocument::GetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, double& rValue
) const
3265 if (TableExists(nTab
))
3266 rValue
= maTabs
[nTab
]->GetValue( nCol
, nRow
);
3271 const EditTextObject
* ScDocument::GetEditText( const ScAddress
& rPos
) const
3273 SCTAB nTab
= rPos
.Tab();
3274 if (!TableExists(nTab
))
3277 return maTabs
[nTab
]->GetEditText(rPos
.Col(), rPos
.Row());
3280 void ScDocument::RemoveEditTextCharAttribs( const ScAddress
& rPos
, const ScPatternAttr
& rAttr
)
3282 if (!TableExists(rPos
.Tab()))
3285 return maTabs
[rPos
.Tab()]->RemoveEditTextCharAttribs(rPos
.Col(), rPos
.Row(), rAttr
);
3288 double ScDocument::GetValue( const ScAddress
& rPos
) const
3290 SCTAB nTab
= rPos
.Tab();
3291 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3292 return maTabs
[nTab
]->GetValue(rPos
.Col(), rPos
.Row());
3297 void ScDocument::GetNumberFormat( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3298 sal_uInt32
& rFormat
) const
3300 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
3303 rFormat
= maTabs
[nTab
]->GetNumberFormat( nCol
, nRow
);
3309 sal_uInt32
ScDocument::GetNumberFormat( const ScRange
& rRange
) const
3311 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
3312 SCCOL nCol1
= rRange
.aStart
.Col(), nCol2
= rRange
.aEnd
.Col();
3313 SCROW nRow1
= rRange
.aStart
.Row(), nRow2
= rRange
.aEnd
.Row();
3315 if (!ValidTab(nTab1
) || !ValidTab(nTab2
) || !maTabs
[nTab1
] || !maTabs
[nTab2
])
3318 sal_uInt32 nFormat
= 0;
3319 bool bFirstItem
= true;
3320 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
&& nTab
< static_cast<SCTAB
>(maTabs
.size()) ; ++nTab
)
3321 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
3323 sal_uInt32 nThisFormat
= maTabs
[nTab
]->GetNumberFormat(nCol
, nRow1
, nRow2
);
3326 nFormat
= nThisFormat
;
3329 else if (nThisFormat
!= nFormat
)
3336 sal_uInt32
ScDocument::GetNumberFormat( const ScAddress
& rPos
) const
3338 SCTAB nTab
= rPos
.Tab();
3340 return maTabs
[nTab
]->GetNumberFormat( rPos
);
3344 void ScDocument::SetNumberFormat( const ScAddress
& rPos
, sal_uInt32 nNumberFormat
)
3346 if (!TableExists(rPos
.Tab()))
3349 maTabs
[rPos
.Tab()]->SetNumberFormat(rPos
.Col(), rPos
.Row(), nNumberFormat
);
3352 void ScDocument::GetNumberFormatInfo( short& nType
, sal_uLong
& nIndex
,
3353 const ScAddress
& rPos
) const
3355 SCTAB nTab
= rPos
.Tab();
3356 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3358 nIndex
= maTabs
[nTab
]->GetNumberFormat( rPos
);
3359 nType
= GetFormatTable()->GetType( nIndex
);
3363 nType
= NUMBERFORMAT_UNDEFINED
;
3369 void ScDocument::GetFormula( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rFormula
) const
3371 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3372 maTabs
[nTab
]->GetFormula( nCol
, nRow
, rFormula
);
3374 rFormula
= OUString();
3378 void ScDocument::GetFormula( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rFormula
) const
3381 GetFormula( nCol
, nRow
, nTab
, aString
);
3385 const ScTokenArray
* ScDocument::GetFormulaTokens( const ScAddress
& rPos
) const
3387 if (!TableExists(rPos
.Tab()))
3390 return maTabs
[rPos
.Tab()]->GetFormulaTokens(rPos
.Col(), rPos
.Row());
3393 const ScFormulaCell
* ScDocument::GetFormulaCell( const ScAddress
& rPos
) const
3395 if (!TableExists(rPos
.Tab()))
3398 return maTabs
[rPos
.Tab()]->GetFormulaCell(rPos
.Col(), rPos
.Row());
3401 ScFormulaCell
* ScDocument::GetFormulaCell( const ScAddress
& rPos
)
3403 if (!TableExists(rPos
.Tab()))
3406 return maTabs
[rPos
.Tab()]->GetFormulaCell(rPos
.Col(), rPos
.Row());
3409 CellType
ScDocument::GetCellType( const ScAddress
& rPos
) const
3411 SCTAB nTab
= rPos
.Tab();
3412 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3413 return maTabs
[nTab
]->GetCellType( rPos
);
3414 return CELLTYPE_NONE
;
3418 void ScDocument::GetCellType( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3419 CellType
& rCellType
) const
3421 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
3422 rCellType
= maTabs
[nTab
]->GetCellType( nCol
, nRow
);
3424 rCellType
= CELLTYPE_NONE
;
3427 bool ScDocument::HasStringData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3429 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3430 return maTabs
[nTab
]->HasStringData( nCol
, nRow
);
3436 bool ScDocument::HasValueData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3438 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3439 return maTabs
[nTab
]->HasValueData( nCol
, nRow
);
3444 bool ScDocument::HasValueData( const ScAddress
& rPos
) const
3446 return HasValueData(rPos
.Col(), rPos
.Row(), rPos
.Tab());
3449 bool ScDocument::HasStringCells( const ScRange
& rRange
) const
3451 // true, wenn String- oder Editzellen im Bereich
3453 SCCOL nStartCol
= rRange
.aStart
.Col();
3454 SCROW nStartRow
= rRange
.aStart
.Row();
3455 SCTAB nStartTab
= rRange
.aStart
.Tab();
3456 SCCOL nEndCol
= rRange
.aEnd
.Col();
3457 SCROW nEndRow
= rRange
.aEnd
.Row();
3458 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3460 for ( SCTAB nTab
=nStartTab
; nTab
<=nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3461 if ( maTabs
[nTab
] && maTabs
[nTab
]->HasStringCells( nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
3468 bool ScDocument::HasSelectionData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3470 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
3473 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
3474 if( pData
&& pData
->HasSelectionList() )
3477 return HasStringCells( ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
) );
3481 void ScDocument::InitializeNoteCaptions( SCTAB nTab
, bool bForced
)
3483 if( ValidTab( nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[ nTab
] )
3484 maTabs
[ nTab
]->InitializeNoteCaptions( bForced
);
3487 void ScDocument::SetDirty()
3489 bool bOldAutoCalc
= GetAutoCalc();
3490 bAutoCalc
= false; // keine Mehrfachberechnung
3491 { // scope for bulk broadcast
3492 ScBulkBroadcast
aBulkBroadcast( GetBASM());
3493 TableContainer::iterator it
= maTabs
.begin();
3494 for (;it
!= maTabs
.end(); ++it
)
3499 // Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
3500 // wenn alle Formeln dirty sind, werden die Charts aber nicht mehr erwischt
3501 // (#45205#) - darum alle Charts nochmal explizit
3502 if (pChartListenerCollection
)
3503 pChartListenerCollection
->SetDirty();
3505 SetAutoCalc( bOldAutoCalc
);
3509 void ScDocument::SetDirty( const ScRange
& rRange
)
3511 bool bOldAutoCalc
= GetAutoCalc();
3512 bAutoCalc
= false; // keine Mehrfachberechnung
3513 { // scope for bulk broadcast
3514 ScBulkBroadcast
aBulkBroadcast( GetBASM());
3515 SCTAB nTab2
= rRange
.aEnd
.Tab();
3516 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
3517 if (maTabs
[i
]) maTabs
[i
]->SetDirty( rRange
);
3519 SetAutoCalc( bOldAutoCalc
);
3523 void ScDocument::SetTableOpDirty( const ScRange
& rRange
)
3525 bool bOldAutoCalc
= GetAutoCalc();
3526 bAutoCalc
= false; // no multiple recalculation
3527 SCTAB nTab2
= rRange
.aEnd
.Tab();
3528 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
3529 if (maTabs
[i
]) maTabs
[i
]->SetTableOpDirty( rRange
);
3530 SetAutoCalc( bOldAutoCalc
);
3534 void ScDocument::InterpretDirtyCells( const ScRangeList
& rRanges
)
3536 for (size_t nPos
=0, nRangeCount
= rRanges
.size(); nPos
< nRangeCount
; nPos
++)
3538 ScCellIterator
aIter( this, *rRanges
[ nPos
] );
3539 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
3541 if (aIter
.getType() != CELLTYPE_FORMULA
)
3544 ScFormulaCell
* p
= aIter
.getFormulaCell();
3545 if (p
->GetDirty() && GetAutoCalc())
3552 void ScDocument::AddTableOpFormulaCell( ScFormulaCell
* pCell
)
3554 if ( !aTableOpList
.empty() )
3556 ScInterpreterTableOpParams
* p
= &aTableOpList
.back();
3557 if ( p
->bCollectNotifications
)
3560 { // refresh pointers only
3561 p
->aNotifiedFormulaCells
.push_back( pCell
);
3564 { // init both, address and pointer
3565 p
->aNotifiedFormulaCells
.push_back( pCell
);
3566 p
->aNotifiedFormulaPos
.push_back( pCell
->aPos
);
3573 void ScDocument::CalcAll()
3575 ClearLookupCaches(); // Ensure we don't deliver zombie data.
3576 bool bOldAutoCalc
= GetAutoCalc();
3577 SetAutoCalc( true );
3578 TableContainer::iterator it
= maTabs
.begin();
3579 for (; it
!= maTabs
.end(); ++it
)
3581 (*it
)->SetDirtyVar();
3582 for (it
= maTabs
.begin(); it
!= maTabs
.end(); ++it
)
3586 SetAutoCalc( bOldAutoCalc
);
3590 void ScDocument::CompileAll()
3592 TableContainer::iterator it
= maTabs
.begin();
3593 for (; it
!= maTabs
.end(); ++it
)
3595 (*it
)->CompileAll();
3600 void ScDocument::CompileXML()
3602 bool bOldAutoCalc
= GetAutoCalc();
3603 SetAutoCalc( false );
3604 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(
3605 STR_PROGRESS_CALCULATING
), GetXMLImportedFormulaCount() );
3607 // set AutoNameCache to speed up automatic name lookup
3608 OSL_ENSURE( !pAutoNameCache
, "AutoNameCache already set" );
3609 pAutoNameCache
= new ScAutoNameCache( this );
3612 pRangeName
->CompileUnresolvedXML();
3614 TableContainer::iterator it
= maTabs
.begin();
3615 for (; it
!= maTabs
.end(); ++it
)
3617 (*it
)->CompileXML( aProgress
);
3619 DELETEZ( pAutoNameCache
); // valid only during CompileXML, where cell contents don't change
3621 if ( pValidationList
)
3622 pValidationList
->CompileXML();
3624 SetAutoCalc( bOldAutoCalc
);
3627 bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode
)
3629 bool bCompiled
= false;
3630 TableContainer::iterator it
= maTabs
.begin(), itEnd
= maTabs
.end();
3631 for (; it
!= itEnd
; ++it
)
3633 ScTable
* pTab
= *it
;
3637 if (pTab
->CompileErrorCells(nErrCode
))
3644 void ScDocument::CalcAfterLoad()
3646 if (bIsClip
) // Excel-Dateien werden aus dem Clipboard in ein Clip-Doc geladen
3647 return; // dann wird erst beim Einfuegen in das richtige Doc berechnet
3649 bCalcingAfterLoad
= true;
3651 TableContainer::iterator it
= maTabs
.begin();
3652 for (; it
!= maTabs
.end(); ++it
)
3654 (*it
)->CalcAfterLoad();
3655 for (it
= maTabs
.begin(); it
!= maTabs
.end(); ++it
)
3657 (*it
)->SetDirtyAfterLoad();
3659 bCalcingAfterLoad
= false;
3661 SetDetectiveDirty(false); // noch keine wirklichen Aenderungen
3663 // #i112436# If formula cells are already dirty, they don't broadcast further changes.
3664 // So the source ranges of charts must be interpreted even if they are not visible,
3665 // similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
3666 if (pChartListenerCollection
)
3668 const ScChartListenerCollection::ListenersType
& rListeners
= pChartListenerCollection
->getListeners();
3669 ScChartListenerCollection::ListenersType::const_iterator it
= rListeners
.begin(), itEnd
= rListeners
.end();
3670 for (; it
!= itEnd
; ++it
)
3672 const ScChartListener
* p
= it
->second
;
3673 InterpretDirtyCells(*p
->GetRangeList());
3679 sal_uInt16
ScDocument::GetErrCode( const ScAddress
& rPos
) const
3681 SCTAB nTab
= rPos
.Tab();
3682 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3683 return maTabs
[nTab
]->GetErrCode( rPos
);
3688 void ScDocument::ResetChanged( const ScRange
& rRange
)
3690 SCTAB nTabSize
= static_cast<SCTAB
>(maTabs
.size());
3691 SCTAB nTab1
= rRange
.aStart
.Tab();
3692 SCTAB nTab2
= rRange
.aEnd
.Tab();
3693 for (SCTAB nTab
= nTab1
; nTab1
<= nTab2
&& nTab
< nTabSize
; ++nTab
)
3695 maTabs
[nTab
]->ResetChanged(rRange
);
3699 // Spaltenbreiten / Zeilenhoehen --------------------------------------
3703 void ScDocument::SetColWidth( SCCOL nCol
, SCTAB nTab
, sal_uInt16 nNewWidth
)
3705 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3706 maTabs
[nTab
]->SetColWidth( nCol
, nNewWidth
);
3709 void ScDocument::SetColWidthOnly( SCCOL nCol
, SCTAB nTab
, sal_uInt16 nNewWidth
)
3711 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3712 maTabs
[nTab
]->SetColWidthOnly( nCol
, nNewWidth
);
3715 void ScDocument::SetRowHeight( SCROW nRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3717 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3718 maTabs
[nTab
]->SetRowHeight( nRow
, nNewHeight
);
3722 void ScDocument::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3724 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3725 maTabs
[nTab
]->SetRowHeightRange
3726 ( nStartRow
, nEndRow
, nNewHeight
, 1.0, 1.0 );
3729 void ScDocument::SetRowHeightOnly( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nNewHeight
)
3731 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3732 maTabs
[nTab
]->SetRowHeightOnly( nStartRow
, nEndRow
, nNewHeight
);
3735 void ScDocument::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bManual
)
3737 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3738 maTabs
[nTab
]->SetManualHeight( nStartRow
, nEndRow
, bManual
);
3742 sal_uInt16
ScDocument::GetColWidth( SCCOL nCol
, SCTAB nTab
, bool bHiddenAsZero
) const
3744 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3745 return maTabs
[nTab
]->GetColWidth( nCol
, bHiddenAsZero
);
3746 OSL_FAIL("wrong table number");
3751 sal_uInt16
ScDocument::GetOriginalWidth( SCCOL nCol
, SCTAB nTab
) const
3753 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3754 return maTabs
[nTab
]->GetOriginalWidth( nCol
);
3755 OSL_FAIL("wrong table number");
3760 sal_uInt16
ScDocument::GetCommonWidth( SCCOL nEndCol
, SCTAB nTab
) const
3762 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3763 return maTabs
[nTab
]->GetCommonWidth( nEndCol
);
3764 OSL_FAIL("Wrong table number");
3769 sal_uInt16
ScDocument::GetOriginalHeight( SCROW nRow
, SCTAB nTab
) const
3771 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3772 return maTabs
[nTab
]->GetOriginalHeight( nRow
);
3773 OSL_FAIL("Wrong table number");
3778 sal_uInt16
ScDocument::GetRowHeight( SCROW nRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3780 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3781 return maTabs
[nTab
]->GetRowHeight( nRow
, NULL
, NULL
, bHiddenAsZero
);
3782 OSL_FAIL("Wrong sheet number");
3787 sal_uInt16
ScDocument::GetRowHeight( SCROW nRow
, SCTAB nTab
, SCROW
* pStartRow
, SCROW
* pEndRow
, bool bHiddenAsZero
) const
3789 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3790 return maTabs
[nTab
]->GetRowHeight( nRow
, pStartRow
, pEndRow
, bHiddenAsZero
);
3791 OSL_FAIL("Wrong sheet number");
3796 sal_uLong
ScDocument::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3798 if (nStartRow
== nEndRow
)
3799 return GetRowHeight( nStartRow
, nTab
, bHiddenAsZero
); // faster for a single row
3801 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3802 if (nStartRow
> nEndRow
)
3805 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3806 return maTabs
[nTab
]->GetRowHeight( nStartRow
, nEndRow
, bHiddenAsZero
);
3808 OSL_FAIL("wrong sheet number");
3812 SCROW
ScDocument::GetRowForHeight( SCTAB nTab
, sal_uLong nHeight
) const
3814 return maTabs
[nTab
]->GetRowForHeight(nHeight
);
3817 sal_uLong
ScDocument::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
,
3818 SCTAB nTab
, double fScale
) const
3820 // faster for a single row
3821 if (nStartRow
== nEndRow
)
3822 return (sal_uLong
) (GetRowHeight( nStartRow
, nTab
) * fScale
);
3824 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3825 if (nStartRow
> nEndRow
)
3828 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3829 return maTabs
[nTab
]->GetScaledRowHeight( nStartRow
, nEndRow
, fScale
);
3831 OSL_FAIL("wrong sheet number");
3835 SCROW
ScDocument::GetHiddenRowCount( SCROW nRow
, SCTAB nTab
) const
3837 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3838 return maTabs
[nTab
]->GetHiddenRowCount( nRow
);
3839 OSL_FAIL("wrong table number");
3844 sal_uLong
ScDocument::GetColOffset( SCCOL nCol
, SCTAB nTab
, bool bHiddenAsZero
) const
3846 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3847 return maTabs
[nTab
]->GetColOffset( nCol
, bHiddenAsZero
);
3848 OSL_FAIL("wrong table number");
3853 sal_uLong
ScDocument::GetRowOffset( SCROW nRow
, SCTAB nTab
, bool bHiddenAsZero
) const
3855 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3856 return maTabs
[nTab
]->GetRowOffset( nRow
, bHiddenAsZero
);
3857 OSL_FAIL("wrong table number");
3862 sal_uInt16
ScDocument::GetOptimalColWidth( SCCOL nCol
, SCTAB nTab
, OutputDevice
* pDev
,
3863 double nPPTX
, double nPPTY
,
3864 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3865 bool bFormula
, const ScMarkData
* pMarkData
,
3866 const ScColWidthParam
* pParam
)
3868 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3869 return maTabs
[nTab
]->GetOptimalColWidth( nCol
, pDev
, nPPTX
, nPPTY
,
3870 rZoomX
, rZoomY
, bFormula
, pMarkData
, pParam
);
3871 OSL_FAIL("wrong table number");
3876 long ScDocument::GetNeededSize( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3878 double nPPTX
, double nPPTY
,
3879 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3880 bool bWidth
, bool bTotalSize
)
3882 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3883 return maTabs
[nTab
]->GetNeededSize
3884 ( nCol
, nRow
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bWidth
, bTotalSize
);
3885 OSL_FAIL("wrong table number");
3890 bool ScDocument::SetOptimalHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt16 nExtra
,
3892 double nPPTX
, double nPPTY
,
3893 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3897 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3898 return maTabs
[nTab
]->SetOptimalHeight( nStartRow
, nEndRow
, nExtra
,
3899 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bShrink
);
3900 OSL_FAIL("wrong table number");
3905 void ScDocument::UpdateAllRowHeights( OutputDevice
* pDev
, double nPPTX
, double nPPTY
,
3906 const Fraction
& rZoomX
, const Fraction
& rZoomY
, const ScMarkData
* pTabMark
)
3908 // one progress across all (selected) sheets
3910 sal_uLong nCellCount
= 0;
3911 for ( SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3912 if ( maTabs
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3913 nCellCount
+= maTabs
[nTab
]->GetWeightedCount();
3915 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING
), nCellCount
);
3917 sal_uLong nProgressStart
= 0;
3918 for ( SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
3919 if ( maTabs
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3921 maTabs
[nTab
]->SetOptimalHeightOnly( 0, MAXROW
, 0,
3922 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, false, &aProgress
, nProgressStart
);
3923 maTabs
[nTab
]->SetDrawPageSize(true, true);
3924 nProgressStart
+= maTabs
[nTab
]->GetWeightedCount();
3930 // Spalten-/Zeilen-Flags ----------------------------------------------
3933 void ScDocument::ShowCol(SCCOL nCol
, SCTAB nTab
, bool bShow
)
3935 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3936 maTabs
[nTab
]->ShowCol( nCol
, bShow
);
3940 void ScDocument::ShowRow(SCROW nRow
, SCTAB nTab
, bool bShow
)
3942 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3943 maTabs
[nTab
]->ShowRow( nRow
, bShow
);
3947 void ScDocument::ShowRows(SCROW nRow1
, SCROW nRow2
, SCTAB nTab
, bool bShow
)
3949 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3950 maTabs
[nTab
]->ShowRows( nRow1
, nRow2
, bShow
);
3954 void ScDocument::SetRowFlags( SCROW nRow
, SCTAB nTab
, sal_uInt8 nNewFlags
)
3956 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3957 maTabs
[nTab
]->SetRowFlags( nRow
, nNewFlags
);
3961 void ScDocument::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, sal_uInt8 nNewFlags
)
3963 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3964 maTabs
[nTab
]->SetRowFlags( nStartRow
, nEndRow
, nNewFlags
);
3968 sal_uInt8
ScDocument::GetColFlags( SCCOL nCol
, SCTAB nTab
) const
3970 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3971 return maTabs
[nTab
]->GetColFlags( nCol
);
3972 OSL_FAIL("wrong table number");
3976 sal_uInt8
ScDocument::GetRowFlags( SCROW nRow
, SCTAB nTab
) const
3978 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3979 return maTabs
[nTab
]->GetRowFlags( nRow
);
3980 OSL_FAIL("wrong table number");
3984 const ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> & ScDocument::GetRowFlagsArray(
3987 const ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> * pFlags
;
3988 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
3989 pFlags
= maTabs
[nTab
]->GetRowFlagsArray();
3992 OSL_FAIL("wrong sheet number");
3997 OSL_FAIL("no row flags at sheet");
3998 static ScBitMaskCompressedArray
< SCROW
, sal_uInt8
> aDummy( MAXROW
, 0);
4004 void ScDocument::GetAllRowBreaks(set
<SCROW
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
4006 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4008 maTabs
[nTab
]->GetAllRowBreaks(rBreaks
, bPage
, bManual
);
4011 void ScDocument::GetAllColBreaks(set
<SCCOL
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
4013 if (!ValidTab(nTab
) || !maTabs
[nTab
])
4016 maTabs
[nTab
]->GetAllColBreaks(rBreaks
, bPage
, bManual
);
4019 ScBreakType
ScDocument::HasRowBreak(SCROW nRow
, SCTAB nTab
) const
4021 ScBreakType nType
= BREAK_NONE
;
4022 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4025 if (maTabs
[nTab
]->HasRowPageBreak(nRow
))
4026 nType
|= BREAK_PAGE
;
4028 if (maTabs
[nTab
]->HasRowManualBreak(nRow
))
4029 nType
|= BREAK_MANUAL
;
4034 ScBreakType
ScDocument::HasColBreak(SCCOL nCol
, SCTAB nTab
) const
4036 ScBreakType nType
= BREAK_NONE
;
4037 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4040 if (maTabs
[nTab
]->HasColPageBreak(nCol
))
4041 nType
|= BREAK_PAGE
;
4043 if (maTabs
[nTab
]->HasColManualBreak(nCol
))
4044 nType
|= BREAK_MANUAL
;
4049 void ScDocument::SetRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
4051 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4054 maTabs
[nTab
]->SetRowBreak(nRow
, bPage
, bManual
);
4057 void ScDocument::SetColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
4059 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4062 maTabs
[nTab
]->SetColBreak(nCol
, bPage
, bManual
);
4065 void ScDocument::RemoveRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
4067 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidRow(nRow
))
4070 maTabs
[nTab
]->RemoveRowBreak(nRow
, bPage
, bManual
);
4073 void ScDocument::RemoveColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
4075 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
] || !ValidCol(nCol
))
4078 maTabs
[nTab
]->RemoveColBreak(nCol
, bPage
, bManual
);
4081 Sequence
<TablePageBreakData
> ScDocument::GetRowBreakData(SCTAB nTab
) const
4083 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4084 return Sequence
<TablePageBreakData
>();
4086 return maTabs
[nTab
]->GetRowBreakData();
4089 bool ScDocument::RowHidden(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
4091 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4094 return maTabs
[nTab
]->RowHidden(nRow
, pFirstRow
, pLastRow
);
4097 bool ScDocument::HasHiddenRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4099 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4102 return maTabs
[nTab
]->HasHiddenRows(nStartRow
, nEndRow
);
4105 bool ScDocument::ColHidden(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
4107 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4116 return maTabs
[nTab
]->ColHidden(nCol
, pFirstCol
, pLastCol
);
4119 void ScDocument::SetRowHidden(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bHidden
)
4121 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4124 maTabs
[nTab
]->SetRowHidden(nStartRow
, nEndRow
, bHidden
);
4127 void ScDocument::SetColHidden(SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bHidden
)
4129 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4132 maTabs
[nTab
]->SetColHidden(nStartCol
, nEndCol
, bHidden
);
4135 SCROW
ScDocument::FirstVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4137 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4138 return ::std::numeric_limits
<SCROW
>::max();;
4140 return maTabs
[nTab
]->FirstVisibleRow(nStartRow
, nEndRow
);
4143 SCROW
ScDocument::LastVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4145 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4146 return ::std::numeric_limits
<SCROW
>::max();;
4148 return maTabs
[nTab
]->LastVisibleRow(nStartRow
, nEndRow
);
4151 SCROW
ScDocument::CountVisibleRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4153 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4156 return maTabs
[nTab
]->CountVisibleRows(nStartRow
, nEndRow
);
4159 bool ScDocument::RowFiltered(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
4161 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4164 return maTabs
[nTab
]->RowFiltered(nRow
, pFirstRow
, pLastRow
);
4167 bool ScDocument::HasFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4169 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4172 return maTabs
[nTab
]->HasFilteredRows(nStartRow
, nEndRow
);
4175 bool ScDocument::ColFiltered(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
4177 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4180 return maTabs
[nTab
]->ColFiltered(nCol
, pFirstCol
, pLastCol
);
4183 void ScDocument::SetRowFiltered(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bFiltered
)
4185 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4188 maTabs
[nTab
]->SetRowFiltered(nStartRow
, nEndRow
, bFiltered
);
4192 SCROW
ScDocument::FirstNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4194 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4195 return ::std::numeric_limits
<SCROW
>::max();;
4197 return maTabs
[nTab
]->FirstNonFilteredRow(nStartRow
, nEndRow
);
4200 SCROW
ScDocument::LastNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4202 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4203 return ::std::numeric_limits
<SCROW
>::max();;
4205 return maTabs
[nTab
]->LastNonFilteredRow(nStartRow
, nEndRow
);
4208 SCROW
ScDocument::CountNonFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4210 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4213 return maTabs
[nTab
]->CountNonFilteredRows(nStartRow
, nEndRow
);
4216 bool ScDocument::IsManualRowHeight(SCROW nRow
, SCTAB nTab
) const
4218 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4221 return maTabs
[nTab
]->IsManualRowHeight(nRow
);
4224 void ScDocument::SyncColRowFlags()
4226 TableContainer::iterator it
= maTabs
.begin();
4227 for (; it
!= maTabs
.end(); ++it
)
4230 (*it
)->SyncColRowFlags();
4234 SCROW
ScDocument::GetLastFlaggedRow( SCTAB nTab
) const
4236 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4237 return maTabs
[nTab
]->GetLastFlaggedRow();
4242 SCCOL
ScDocument::GetLastChangedCol( SCTAB nTab
) const
4244 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4245 return maTabs
[nTab
]->GetLastChangedCol();
4249 SCROW
ScDocument::GetLastChangedRow( SCTAB nTab
) const
4251 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4252 return maTabs
[nTab
]->GetLastChangedRow();
4257 SCCOL
ScDocument::GetNextDifferentChangedCol( SCTAB nTab
, SCCOL nStart
) const
4259 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4261 sal_uInt8 nStartFlags
= maTabs
[nTab
]->GetColFlags(nStart
);
4262 sal_uInt16 nStartWidth
= maTabs
[nTab
]->GetOriginalWidth(nStart
);
4263 for (SCCOL nCol
= nStart
+ 1; nCol
<= MAXCOL
; nCol
++)
4265 if (((nStartFlags
& CR_MANUALBREAK
) != (maTabs
[nTab
]->GetColFlags(nCol
) & CR_MANUALBREAK
)) ||
4266 (nStartWidth
!= maTabs
[nTab
]->GetOriginalWidth(nCol
)) ||
4267 ((nStartFlags
& CR_HIDDEN
) != (maTabs
[nTab
]->GetColFlags(nCol
) & CR_HIDDEN
)) )
4275 SCROW
ScDocument::GetNextDifferentChangedRow( SCTAB nTab
, SCROW nStart
, bool bCareManualSize
) const
4277 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4280 const ScBitMaskCompressedArray
<SCROW
, sal_uInt8
>* pRowFlagsArray
= maTabs
[nTab
]->GetRowFlagsArray();
4281 if (!pRowFlagsArray
)
4284 if (!maTabs
[nTab
]->mpRowHeights
|| !maTabs
[nTab
]->mpHiddenRows
)
4287 size_t nIndex
; // ignored
4289 SCROW nHiddenEndRow
;
4290 SCROW nHeightEndRow
;
4294 sal_uInt8 nStartFlags
= nFlags
= pRowFlagsArray
->GetValue( nStart
, nIndex
, nFlagsEndRow
);
4295 bool bStartHidden
= bHidden
= maTabs
[nTab
]->RowHidden( nStart
, NULL
, &nHiddenEndRow
);
4296 sal_uInt16 nStartHeight
= nHeight
= maTabs
[nTab
]->GetRowHeight( nStart
, NULL
, &nHeightEndRow
, false);
4298 while ((nRow
= std::min( nHiddenEndRow
, std::min( nFlagsEndRow
, nHeightEndRow
)) + 1) <= MAXROW
)
4300 if (nFlagsEndRow
< nRow
)
4301 nFlags
= pRowFlagsArray
->GetValue( nRow
, nIndex
, nFlagsEndRow
);
4302 if (nHiddenEndRow
< nRow
)
4303 bHidden
= maTabs
[nTab
]->RowHidden( nRow
, NULL
, &nHiddenEndRow
);
4304 if (nHeightEndRow
< nRow
)
4305 nHeight
= maTabs
[nTab
]->GetRowHeight( nRow
, NULL
, &nHeightEndRow
, false);
4307 if (((nStartFlags
& CR_MANUALBREAK
) != (nFlags
& CR_MANUALBREAK
)) ||
4308 ((nStartFlags
& CR_MANUALSIZE
) != (nFlags
& CR_MANUALSIZE
)) ||
4309 (bStartHidden
!= bHidden
) ||
4310 (bCareManualSize
&& (nStartFlags
& CR_MANUALSIZE
) && (nStartHeight
!= nHeight
)) ||
4311 (!bCareManualSize
&& ((nStartHeight
!= nHeight
))))
4318 bool ScDocument::GetColDefault( SCTAB nTab
, SCCOL nCol
, SCROW nLastRow
, SCROW
& nDefault
)
4322 ScDocAttrIterator
aDocAttrItr(this, nTab
, nCol
, 0, nCol
, nLastRow
);
4326 const ScPatternAttr
* pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
4327 if (nEndRow
< nLastRow
)
4329 ScDefaultAttrSet aSet
;
4330 ScDefaultAttrSet::iterator aItr
= aSet
.end();
4333 ScDefaultAttr
aAttr(pAttr
);
4334 aItr
= aSet
.find(aAttr
);
4335 if (aItr
== aSet
.end())
4337 aAttr
.nCount
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
4338 aAttr
.nFirst
= nStartRow
;
4343 aAttr
.nCount
= aItr
->nCount
+ static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
4344 aAttr
.nFirst
= aItr
->nFirst
;
4348 pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
4350 ScDefaultAttrSet::iterator aDefaultItr
= aSet
.begin();
4353 while (aItr
!= aSet
.end())
4355 // for entries with equal count, use the one with the lowest start row,
4356 // don't use the random order of pointer comparisons
4357 if ( aItr
->nCount
> aDefaultItr
->nCount
||
4358 ( aItr
->nCount
== aDefaultItr
->nCount
&& aItr
->nFirst
< aDefaultItr
->nFirst
) )
4362 nDefault
= aDefaultItr
->nFirst
;
4370 bool ScDocument::GetRowDefault( SCTAB
/* nTab */, SCROW
/* nRow */, SCCOL
/* nLastCol */, SCCOL
& /* nDefault */ )
4375 void ScDocument::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
4377 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4378 maTabs
[nTab
]->StripHidden( rX1
, rY1
, rX2
, rY2
);
4382 void ScDocument::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
4384 if ( ValidTab(nTab
) && maTabs
[nTab
] )
4385 maTabs
[nTab
]->ExtendHidden( rX1
, rY1
, rX2
, rY2
);
4389 // Attribute ----------------------------------------------------------
4392 const SfxPoolItem
* ScDocument::GetAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_uInt16 nWhich
) const
4394 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4396 const SfxPoolItem
* pTemp
= maTabs
[nTab
]->GetAttr( nCol
, nRow
, nWhich
);
4401 OSL_FAIL( "Attribut Null" );
4404 return &xPoolHelper
->GetDocPool()->GetDefaultItem( nWhich
);
4407 const SfxPoolItem
* ScDocument::GetAttr( const ScAddress
& rPos
, sal_uInt16 nWhich
) const
4409 return GetAttr(rPos
.Col(), rPos
.Row(), rPos
.Tab(), nWhich
);
4412 const ScPatternAttr
* ScDocument::GetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4414 if (TableExists(nTab
))
4415 return maTabs
[nTab
]->GetPattern( nCol
, nRow
);
4419 const ScPatternAttr
* ScDocument::GetPattern( const ScAddress
& rPos
) const
4421 if (TableExists(rPos
.Tab()))
4422 return maTabs
[rPos
.Tab()]->GetPattern(rPos
.Col(), rPos
.Row());
4427 const ScPatternAttr
* ScDocument::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
4429 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4430 return maTabs
[nTab
]->GetMostUsedPattern( nCol
, nStartRow
, nEndRow
);
4435 void ScDocument::ApplyAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const SfxPoolItem
& rAttr
)
4437 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4438 maTabs
[nTab
]->ApplyAttr( nCol
, nRow
, rAttr
);
4442 void ScDocument::ApplyPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
4444 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4445 maTabs
[nTab
]->ApplyPattern( nCol
, nRow
, rAttr
);
4449 void ScDocument::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
,
4450 SCCOL nEndCol
, SCROW nEndRow
,
4451 const ScMarkData
& rMark
,
4452 const ScPatternAttr
& rAttr
,
4453 ScEditDataArray
* pDataArray
)
4455 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4456 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4457 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4459 maTabs
[*itr
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
, pDataArray
);
4463 void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
4464 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
4466 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4468 maTabs
[nTab
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
);
4471 bool ScDocument::SetAttrEntries(SCCOL nCol
, SCTAB nTab
, ScAttrEntry
* pData
, SCSIZE nSize
)
4473 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
4476 return maTabs
[nTab
]->SetAttrEntries(nCol
, pData
, nSize
);
4479 void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
4480 const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
, short nNewType
)
4482 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4483 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4484 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4486 maTabs
[*itr
]->ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
4489 void ScDocument::AddCondFormatData( const ScRangeList
& rRange
, SCTAB nTab
, sal_uInt32 nIndex
)
4491 if(!(static_cast<size_t>(nTab
) < maTabs
.size()))
4497 maTabs
[nTab
]->AddCondFormatData(rRange
, nIndex
);
4500 void ScDocument::RemoveCondFormatData( const ScRangeList
& rRange
, SCTAB nTab
, sal_uInt32 nIndex
)
4502 if(!(static_cast<size_t>(nTab
) < maTabs
.size()))
4508 maTabs
[nTab
]->RemoveCondFormatData(rRange
, nIndex
);
4512 void ScDocument::ApplyStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
4514 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4516 maTabs
[nTab
]->ApplyStyle( nCol
, nRow
, rStyle
);
4520 void ScDocument::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
,
4521 SCCOL nEndCol
, SCROW nEndRow
,
4522 const ScMarkData
& rMark
,
4523 const ScStyleSheet
& rStyle
)
4525 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4526 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4527 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4529 maTabs
[*itr
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
4533 void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
4534 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
4536 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4538 maTabs
[nTab
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
4542 void ScDocument::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
4544 // ApplySelectionStyle needs multi mark
4545 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
4548 rMark
.GetMarkArea( aRange
);
4549 ApplyStyleArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4550 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rStyle
);
4554 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4555 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4556 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4558 maTabs
[*itr
]->ApplySelectionStyle( rStyle
, rMark
);
4563 void ScDocument::ApplySelectionLineStyle( const ScMarkData
& rMark
,
4564 const SvxBorderLine
* pLine
, bool bColorOnly
)
4566 if ( bColorOnly
&& !pLine
)
4569 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4570 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4571 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4573 maTabs
[*itr
]->ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
4577 const ScStyleSheet
* ScDocument::GetStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4579 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4580 return maTabs
[nTab
]->GetStyle(nCol
, nRow
);
4586 const ScStyleSheet
* ScDocument::GetSelectionStyle( const ScMarkData
& rMark
) const
4591 const ScStyleSheet
* pStyle
= NULL
;
4592 const ScStyleSheet
* pNewStyle
;
4594 if ( rMark
.IsMultiMarked() )
4596 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4597 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4598 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4601 pNewStyle
= maTabs
[*itr
]->GetSelectionStyle( rMark
, bFound
);
4604 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
4605 bEqual
= false; // unterschiedliche
4610 if ( rMark
.IsMarked() )
4613 rMark
.GetMarkArea( aRange
);
4614 for (SCTAB i
=aRange
.aStart
.Tab(); i
<=aRange
.aEnd
.Tab() && bEqual
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
4615 if (maTabs
[i
] && rMark
.GetTableSelect(i
))
4617 pNewStyle
= maTabs
[i
]->GetAreaStyle( bFound
,
4618 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4619 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4622 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
4623 bEqual
= false; // unterschiedliche
4629 return bEqual
? pStyle
: NULL
;
4633 void ScDocument::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, bool bRemoved
,
4635 double nPPTX
, double nPPTY
,
4636 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
4638 TableContainer::iterator it
= maTabs
.begin();
4639 for (; it
!= maTabs
.end(); ++it
)
4641 (*it
)->StyleSheetChanged
4642 ( pStyleSheet
, bRemoved
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
);
4644 if ( pStyleSheet
&& pStyleSheet
->GetName() == ScGlobal::GetRscString(STR_STYLENAME_STANDARD
) )
4646 // update attributes for all note objects
4647 ScDetectiveFunc::UpdateAllComments( *this );
4652 bool ScDocument::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, bool bGatherAllStyles
) const
4654 if ( bStyleSheetUsageInvalid
|| rStyle
.GetUsage() == ScStyleSheet::UNKNOWN
)
4656 if ( bGatherAllStyles
)
4658 SfxStyleSheetIterator
aIter( xPoolHelper
->GetStylePool(),
4659 SFX_STYLE_FAMILY_PARA
);
4660 for ( const SfxStyleSheetBase
* pStyle
= aIter
.First(); pStyle
;
4661 pStyle
= aIter
.Next() )
4663 const ScStyleSheet
* pScStyle
= PTR_CAST( ScStyleSheet
, pStyle
);
4665 pScStyle
->SetUsage( ScStyleSheet::NOTUSED
);
4669 bool bIsUsed
= false;
4671 TableContainer::const_iterator it
= maTabs
.begin();
4672 for (; it
!= maTabs
.end(); ++it
)
4675 if ( (*it
)->IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
4677 if ( !bGatherAllStyles
)
4683 if ( bGatherAllStyles
)
4684 bStyleSheetUsageInvalid
= false;
4689 return rStyle
.GetUsage() == ScStyleSheet::USED
;
4693 bool ScDocument::ApplyFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4694 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, sal_Int16 nFlags
)
4696 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4698 return maTabs
[nTab
]->ApplyFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4700 OSL_FAIL("ApplyFlags: wrong table");
4705 bool ScDocument::RemoveFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4706 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, sal_Int16 nFlags
)
4708 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4710 return maTabs
[nTab
]->RemoveFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4712 OSL_FAIL("RemoveFlags: wrong table");
4717 void ScDocument::SetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
,
4720 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4722 maTabs
[nTab
]->SetPattern( nCol
, nRow
, rAttr
, bPutToPool
);
4726 void ScDocument::SetPattern( const ScAddress
& rPos
, const ScPatternAttr
& rAttr
,
4729 SCTAB nTab
= rPos
.Tab();
4730 if ( nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
4731 maTabs
[nTab
]->SetPattern( rPos
, rAttr
, bPutToPool
);
4735 ScPatternAttr
* ScDocument::CreateSelectionPattern( const ScMarkData
& rMark
, bool bDeep
)
4737 ScMergePatternState aState
;
4739 if ( rMark
.IsMultiMarked() ) // multi selection
4741 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4742 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4743 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4745 maTabs
[*itr
]->MergeSelectionPattern( aState
, rMark
, bDeep
);
4747 if ( rMark
.IsMarked() ) // simle selection
4750 rMark
.GetMarkArea(aRange
);
4751 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4752 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4753 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4755 maTabs
[*itr
]->MergePatternArea( aState
,
4756 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4757 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), bDeep
);
4760 OSL_ENSURE( aState
.pItemSet
, "SelectionPattern Null" );
4761 if (aState
.pItemSet
)
4762 return new ScPatternAttr( aState
.pItemSet
);
4764 return new ScPatternAttr( GetPool() ); // empty
4768 const ScPatternAttr
* ScDocument::GetSelectionPattern( const ScMarkData
& rMark
, bool bDeep
)
4770 delete pSelectionAttr
;
4771 pSelectionAttr
= CreateSelectionPattern( rMark
, bDeep
);
4772 return pSelectionAttr
;
4776 void ScDocument::GetSelectionFrame( const ScMarkData
& rMark
,
4777 SvxBoxItem
& rLineOuter
,
4778 SvxBoxInfoItem
& rLineInner
)
4780 rLineOuter
.SetLine(NULL
, BOX_LINE_TOP
);
4781 rLineOuter
.SetLine(NULL
, BOX_LINE_BOTTOM
);
4782 rLineOuter
.SetLine(NULL
, BOX_LINE_LEFT
);
4783 rLineOuter
.SetLine(NULL
, BOX_LINE_RIGHT
);
4784 rLineOuter
.SetDistance(0);
4786 rLineInner
.SetLine(NULL
, BOXINFO_LINE_HORI
);
4787 rLineInner
.SetLine(NULL
, BOXINFO_LINE_VERT
);
4788 rLineInner
.SetTable(true);
4789 rLineInner
.SetDist(true);
4790 rLineInner
.SetMinDist(false);
4794 if (rMark
.IsMarked())
4797 rMark
.GetMarkArea(aRange
);
4798 rLineInner
.EnableHor( aRange
.aStart
.Row() != aRange
.aEnd
.Row() );
4799 rLineInner
.EnableVer( aRange
.aStart
.Col() != aRange
.aEnd
.Col() );
4800 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
4801 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
4802 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
4804 maTabs
[*itr
]->MergeBlockFrame( &rLineOuter
, &rLineInner
, aFlags
,
4805 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4806 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4809 // Don't care Status auswerten
4811 rLineInner
.SetValid( VALID_LEFT
, ( aFlags
.nLeft
!= SC_LINE_DONTCARE
) );
4812 rLineInner
.SetValid( VALID_RIGHT
, ( aFlags
.nRight
!= SC_LINE_DONTCARE
) );
4813 rLineInner
.SetValid( VALID_TOP
, ( aFlags
.nTop
!= SC_LINE_DONTCARE
) );
4814 rLineInner
.SetValid( VALID_BOTTOM
, ( aFlags
.nBottom
!= SC_LINE_DONTCARE
) );
4815 rLineInner
.SetValid( VALID_HORI
, ( aFlags
.nHori
!= SC_LINE_DONTCARE
) );
4816 rLineInner
.SetValid( VALID_VERT
, ( aFlags
.nVert
!= SC_LINE_DONTCARE
) );
4820 bool ScDocument::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
4821 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt16 nMask
) const
4823 if ( nMask
& HASATTR_ROTATE
)
4825 // Attribut im Dokument ueberhaupt verwendet?
4826 // (wie in fillinfo)
4828 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4830 bool bAnyItem
= false;
4831 sal_uInt32 nRotCount
= pPool
->GetItemCount2( ATTR_ROTATE_VALUE
);
4832 for (sal_uInt32 nItem
=0; nItem
<nRotCount
; nItem
++)
4834 const SfxPoolItem
* pItem
= pPool
->GetItem2( ATTR_ROTATE_VALUE
, nItem
);
4837 // 90 or 270 degrees is former SvxOrientationItem - only look for other values
4838 // (see ScPatternAttr::GetCellOrientation)
4839 sal_Int32 nAngle
= static_cast<const SfxInt32Item
*>(pItem
)->GetValue();
4840 if ( nAngle
!= 0 && nAngle
!= 9000 && nAngle
!= 27000 )
4848 nMask
&= ~HASATTR_ROTATE
;
4851 if ( nMask
& HASATTR_RTL
)
4853 // first check if right-to left is in the pool at all
4854 // (the same item is used in cell and page format)
4856 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4858 bool bHasRtl
= false;
4859 sal_uInt32 nDirCount
= pPool
->GetItemCount2( ATTR_WRITINGDIR
);
4860 for (sal_uInt32 nItem
=0; nItem
<nDirCount
; nItem
++)
4862 const SfxPoolItem
* pItem
= pPool
->GetItem2( ATTR_WRITINGDIR
, nItem
);
4863 if ( pItem
&& ((const SvxFrameDirectionItem
*)pItem
)->GetValue() == FRMDIR_HORI_RIGHT_TOP
)
4870 nMask
&= ~HASATTR_RTL
;
4876 bool bFound
= false;
4877 for (SCTAB i
=nTab1
; i
<=nTab2
&& !bFound
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
4880 if ( nMask
& HASATTR_RTL
)
4882 if ( GetEditTextDirection(i
) == EE_HTEXTDIR_R2L
) // sheet default
4885 if ( nMask
& HASATTR_RIGHTORCENTER
)
4887 // On a RTL sheet, don't start to look for the default left value
4888 // (which is then logically right), instead always assume true.
4889 // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
4891 if ( IsLayoutRTL(i
) )
4896 bFound
= maTabs
[i
]->HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, nMask
);
4902 bool ScDocument::HasAttrib( const ScRange
& rRange
, sal_uInt16 nMask
) const
4904 return HasAttrib( rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
4905 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
4909 void ScDocument::FindMaxRotCol( SCTAB nTab
, RowInfo
* pRowInfo
, SCSIZE nArrCount
,
4910 SCCOL nX1
, SCCOL nX2
) const
4912 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4913 maTabs
[nTab
]->FindMaxRotCol( pRowInfo
, nArrCount
, nX1
, nX2
);
4916 OSL_FAIL("FindMaxRotCol: wrong table");
4920 void ScDocument::GetBorderLines( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
4921 const SvxBorderLine
** ppLeft
, const SvxBorderLine
** ppTop
,
4922 const SvxBorderLine
** ppRight
, const SvxBorderLine
** ppBottom
) const
4924 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
4926 const SvxBoxItem
* pThisAttr
= (const SvxBoxItem
*) GetEffItem( nCol
, nRow
, nTab
, ATTR_BORDER
);
4927 OSL_ENSURE(pThisAttr
,"where is the attribute?");
4929 const SvxBorderLine
* pLeftLine
= pThisAttr
->GetLeft();
4930 const SvxBorderLine
* pTopLine
= pThisAttr
->GetTop();
4931 const SvxBorderLine
* pRightLine
= pThisAttr
->GetRight();
4932 const SvxBorderLine
* pBottomLine
= pThisAttr
->GetBottom();
4936 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4937 GetEffItem( nCol
-1, nRow
, nTab
, ATTR_BORDER
))->GetRight();
4938 if ( ScHasPriority( pOther
, pLeftLine
) )
4943 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4944 GetEffItem( nCol
, nRow
-1, nTab
, ATTR_BORDER
))->GetBottom();
4945 if ( ScHasPriority( pOther
, pTopLine
) )
4948 if ( nCol
< MAXCOL
)
4950 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4951 GetEffItem( nCol
+1, nRow
, nTab
, ATTR_BORDER
))->GetLeft();
4952 if ( ScHasPriority( pOther
, pRightLine
) )
4953 pRightLine
= pOther
;
4955 if ( nRow
< MAXROW
)
4957 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4958 GetEffItem( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
4959 if ( ScHasPriority( pOther
, pBottomLine
) )
4960 pBottomLine
= pOther
;
4964 *ppLeft
= pLeftLine
;
4968 *ppRight
= pRightLine
;
4970 *ppBottom
= pBottomLine
;
4973 bool ScDocument::IsBlockEmpty( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
4974 SCCOL nEndCol
, SCROW nEndRow
, bool bIgnoreNotes
) const
4976 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
4978 return maTabs
[nTab
]->IsBlockEmpty( nStartCol
, nStartRow
, nEndCol
, nEndRow
, bIgnoreNotes
);
4980 OSL_FAIL("wrong table number");
4985 void ScDocument::LockTable(SCTAB nTab
)
4987 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4988 maTabs
[nTab
]->LockTable();
4991 OSL_FAIL("wrong table number");
4996 void ScDocument::UnlockTable(SCTAB nTab
)
4998 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
4999 maTabs
[nTab
]->UnlockTable();
5002 OSL_FAIL("wrong table number");
5007 bool ScDocument::IsBlockEditable( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
5008 SCCOL nEndCol
, SCROW nEndRow
,
5009 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
5011 // import into read-only document is possible
5012 if (!bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly())
5014 if ( pOnlyNotBecauseOfMatrix
)
5015 *pOnlyNotBecauseOfMatrix
= false;
5019 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
5021 return maTabs
[nTab
]->IsBlockEditable( nStartCol
, nStartRow
, nEndCol
,
5022 nEndRow
, pOnlyNotBecauseOfMatrix
);
5024 OSL_FAIL("wrong table number");
5025 if ( pOnlyNotBecauseOfMatrix
)
5026 *pOnlyNotBecauseOfMatrix
= false;
5031 bool ScDocument::IsSelectionEditable( const ScMarkData
& rMark
,
5032 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
5034 // import into read-only document is possible
5035 if ( !bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly() )
5037 if ( pOnlyNotBecauseOfMatrix
)
5038 *pOnlyNotBecauseOfMatrix
= false;
5043 rMark
.GetMarkArea(aRange
);
5046 bool bMatrix
= ( pOnlyNotBecauseOfMatrix
!= NULL
);
5047 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5048 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5049 for (; itr
!= itrEnd
&& *itr
< nMax
&& (bOk
|| bMatrix
); ++itr
)
5053 if (rMark
.IsMarked())
5055 if ( !maTabs
[*itr
]->IsBlockEditable( aRange
.aStart
.Col(),
5056 aRange
.aStart
.Row(), aRange
.aEnd
.Col(),
5057 aRange
.aEnd
.Row(), pOnlyNotBecauseOfMatrix
) )
5060 if ( pOnlyNotBecauseOfMatrix
)
5061 bMatrix
= *pOnlyNotBecauseOfMatrix
;
5064 if (rMark
.IsMultiMarked())
5066 if ( !maTabs
[*itr
]->IsSelectionEditable( rMark
, pOnlyNotBecauseOfMatrix
) )
5069 if ( pOnlyNotBecauseOfMatrix
)
5070 bMatrix
= *pOnlyNotBecauseOfMatrix
;
5076 if ( pOnlyNotBecauseOfMatrix
)
5077 *pOnlyNotBecauseOfMatrix
= ( !bOk
&& bMatrix
);
5083 bool ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol
, SCROW nStartRow
,
5084 SCCOL nEndCol
, SCROW nEndRow
,
5085 const ScMarkData
& rMark
) const
5088 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5089 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5090 for (; itr
!= itrEnd
&& *itr
< nMax
&& bOk
; ++itr
)
5092 if (maTabs
[*itr
]->HasBlockMatrixFragment( nStartCol
, nStartRow
, nEndCol
, nEndRow
))
5098 bool ScDocument::GetMatrixFormulaRange( const ScAddress
& rCellPos
, ScRange
& rMatrix
)
5100 // if rCell is part of a matrix formula, return its complete range
5102 ScFormulaCell
* pFCell
= GetFormulaCell(rCellPos
);
5104 // not a formula cell. Bail out.
5107 ScAddress aOrigin
= rCellPos
;
5108 if (!pFCell
->GetMatrixOrigin(aOrigin
))
5109 // Failed to get the address of the matrix origin.
5112 if (aOrigin
!= rCellPos
)
5114 pFCell
= GetFormulaCell(aOrigin
);
5116 // The matrix origin cell is not a formula cell !? Something is up...
5122 pFCell
->GetMatColsRows(nSizeX
, nSizeY
);
5123 if (nSizeX
<= 0 || nSizeY
<= 0)
5125 // GetMatrixEdge computes also dimensions of the matrix
5126 // if not already done (may occur if document is loaded
5127 // from old file format).
5128 // Needs an "invalid" initialized address.
5129 aOrigin
.SetInvalid();
5130 pFCell
->GetMatrixEdge(aOrigin
);
5131 pFCell
->GetMatColsRows(nSizeX
, nSizeY
);
5134 if (nSizeX
<= 0 || nSizeY
<= 0)
5135 // Matrix size is still invalid. Give up.
5138 ScAddress
aEnd( aOrigin
.Col() + nSizeX
- 1,
5139 aOrigin
.Row() + nSizeY
- 1,
5142 rMatrix
.aStart
= aOrigin
;
5143 rMatrix
.aEnd
= aEnd
;
5149 bool ScDocument::ExtendOverlapped( SCCOL
& rStartCol
, SCROW
& rStartRow
,
5150 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
) const
5152 bool bFound
= false;
5153 if ( ValidColRow(rStartCol
,rStartRow
) && ValidColRow(nEndCol
,nEndRow
) && ValidTab(nTab
) )
5155 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5158 SCCOL nOldCol
= rStartCol
;
5159 SCROW nOldRow
= rStartRow
;
5160 for (nCol
=nOldCol
; nCol
<=nEndCol
; nCol
++)
5161 while (((ScMergeFlagAttr
*)GetAttr(nCol
,rStartRow
,nTab
,ATTR_MERGE_FLAG
))->
5167 ScAttrArray
* pAttrArray
= maTabs
[nTab
]->aCol
[nOldCol
].pAttrArray
;
5169 pAttrArray
->Search( nOldRow
, nIndex
);
5170 SCROW nAttrPos
= nOldRow
;
5171 while (nAttrPos
<=nEndRow
)
5173 OSL_ENSURE( nIndex
< pAttrArray
->nCount
, "Wrong index in AttrArray" );
5175 if (((ScMergeFlagAttr
&)pAttrArray
->pData
[nIndex
].pPattern
->
5176 GetItem(ATTR_MERGE_FLAG
)).IsHorOverlapped())
5178 SCROW nLoopEndRow
= std::min( nEndRow
, pAttrArray
->pData
[nIndex
].nRow
);
5179 for (SCROW nAttrRow
= nAttrPos
; nAttrRow
<= nLoopEndRow
; nAttrRow
++)
5181 SCCOL nTempCol
= nOldCol
;
5184 while (((ScMergeFlagAttr
*)GetAttr(nTempCol
,nAttrRow
,nTab
,ATTR_MERGE_FLAG
))
5185 ->IsHorOverlapped());
5186 if (nTempCol
< rStartCol
)
5187 rStartCol
= nTempCol
;
5190 nAttrPos
= pAttrArray
->pData
[nIndex
].nRow
+ 1;
5197 OSL_FAIL("ExtendOverlapped: invalid range");
5204 bool ScDocument::ExtendMergeSel( SCCOL nStartCol
, SCROW nStartRow
,
5205 SCCOL
& rEndCol
, SCROW
& rEndRow
,
5206 const ScMarkData
& rMark
, bool bRefresh
)
5208 // use all selected sheets from rMark
5210 bool bFound
= false;
5211 SCCOL nOldEndCol
= rEndCol
;
5212 SCROW nOldEndRow
= rEndRow
;
5214 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5215 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5216 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5219 SCCOL nThisEndCol
= nOldEndCol
;
5220 SCROW nThisEndRow
= nOldEndRow
;
5221 if ( ExtendMerge( nStartCol
, nStartRow
, nThisEndCol
, nThisEndRow
, *itr
, bRefresh
) )
5223 if ( nThisEndCol
> rEndCol
)
5224 rEndCol
= nThisEndCol
;
5225 if ( nThisEndRow
> rEndRow
)
5226 rEndRow
= nThisEndRow
;
5233 bool ScDocument::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
5234 SCCOL
& rEndCol
, SCROW
& rEndRow
,
5235 SCTAB nTab
, bool bRefresh
)
5237 bool bFound
= false;
5238 if ( ValidColRow(nStartCol
,nStartRow
) && ValidColRow(rEndCol
,rEndRow
) && ValidTab(nTab
) )
5240 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5241 bFound
= maTabs
[nTab
]->ExtendMerge( nStartCol
, nStartRow
, rEndCol
, rEndRow
, bRefresh
);
5244 RefreshAutoFilter( nStartCol
, nStartRow
, rEndCol
, rEndRow
, nTab
);
5248 OSL_FAIL("ExtendMerge: invalid range");
5255 bool ScDocument::ExtendMerge( ScRange
& rRange
, bool bRefresh
)
5257 bool bFound
= false;
5258 SCTAB nStartTab
= rRange
.aStart
.Tab();
5259 SCTAB nEndTab
= rRange
.aEnd
.Tab();
5260 SCCOL nEndCol
= rRange
.aEnd
.Col();
5261 SCROW nEndRow
= rRange
.aEnd
.Row();
5263 PutInOrder( nStartTab
, nEndTab
);
5264 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
5266 SCCOL nExtendCol
= rRange
.aEnd
.Col();
5267 SCROW nExtendRow
= rRange
.aEnd
.Row();
5268 if (ExtendMerge( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
5269 nExtendCol
, nExtendRow
,
5273 if (nExtendCol
> nEndCol
) nEndCol
= nExtendCol
;
5274 if (nExtendRow
> nEndRow
) nEndRow
= nExtendRow
;
5278 rRange
.aEnd
.SetCol(nEndCol
);
5279 rRange
.aEnd
.SetRow(nEndRow
);
5284 bool ScDocument::ExtendTotalMerge( ScRange
& rRange
) const
5286 // Bereich genau dann auf zusammengefasste Zellen erweitern, wenn
5287 // dadurch keine neuen nicht-ueberdeckten Zellen getroffen werden
5290 ScRange aExt
= rRange
;
5291 // ExtendMerge() is non-const, but called withouth refresh.
5292 if (const_cast<ScDocument
*>(this)->ExtendMerge( aExt
, false))
5294 if ( aExt
.aEnd
.Row() > rRange
.aEnd
.Row() )
5296 ScRange aTest
= aExt
;
5297 aTest
.aStart
.SetRow( rRange
.aEnd
.Row() + 1 );
5298 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
5299 aExt
.aEnd
.SetRow(rRange
.aEnd
.Row());
5301 if ( aExt
.aEnd
.Col() > rRange
.aEnd
.Col() )
5303 ScRange aTest
= aExt
;
5304 aTest
.aStart
.SetCol( rRange
.aEnd
.Col() + 1 );
5305 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
5306 aExt
.aEnd
.SetCol(rRange
.aEnd
.Col());
5309 bRet
= ( aExt
.aEnd
!= rRange
.aEnd
);
5315 bool ScDocument::ExtendOverlapped( ScRange
& rRange
) const
5317 bool bFound
= false;
5318 SCTAB nStartTab
= rRange
.aStart
.Tab();
5319 SCTAB nEndTab
= rRange
.aEnd
.Tab();
5320 SCCOL nStartCol
= rRange
.aStart
.Col();
5321 SCROW nStartRow
= rRange
.aStart
.Row();
5323 PutInOrder( nStartTab
, nEndTab
);
5324 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++ )
5326 SCCOL nExtendCol
= rRange
.aStart
.Col();
5327 SCROW nExtendRow
= rRange
.aStart
.Row();
5328 ExtendOverlapped( nExtendCol
, nExtendRow
,
5329 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), nTab
);
5330 if (nExtendCol
< nStartCol
)
5332 nStartCol
= nExtendCol
;
5335 if (nExtendRow
< nStartRow
)
5337 nStartRow
= nExtendRow
;
5342 rRange
.aStart
.SetCol(nStartCol
);
5343 rRange
.aStart
.SetRow(nStartRow
);
5348 bool ScDocument::RefreshAutoFilter( SCCOL nStartCol
, SCROW nStartRow
,
5349 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
5357 // Autofilter loeschen
5359 bool bChange
= RemoveFlagsTab( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
, SC_MF_AUTO
);
5361 // Autofilter setzen
5363 const ScDBData
* pData
= NULL
;
5364 ScDBCollection::NamedDBs
& rDBs
= pDBCollection
->getNamedDBs();
5365 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
5366 for (; itr
!= itrEnd
; ++itr
)
5368 if (itr
->HasAutoFilter())
5370 itr
->GetArea( nDBTab
, nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBEndRow
);
5371 if ( nDBTab
==nTab
&& nDBStartRow
<=nEndRow
&& nDBEndRow
>=nStartRow
&&
5372 nDBStartCol
<=nEndCol
&& nDBEndCol
>=nStartCol
)
5374 if (ApplyFlagsTab( nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBStartRow
,
5375 nDBTab
, SC_MF_AUTO
))
5380 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5381 pData
= maTabs
[nTab
]->GetAnonymousDBData();
5386 if (pData
->HasAutoFilter())
5388 pData
->GetArea( nDBTab
, nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBEndRow
);
5389 if ( nDBTab
==nTab
&& nDBStartRow
<=nEndRow
&& nDBEndRow
>=nStartRow
&&
5390 nDBStartCol
<=nEndCol
&& nDBEndCol
>=nStartCol
)
5392 if (ApplyFlagsTab( nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBStartRow
,
5393 nDBTab
, SC_MF_AUTO
))
5401 void ScDocument::SkipOverlapped( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
) const
5403 while (IsHorOverlapped(rCol
, rRow
, nTab
))
5405 while (IsVerOverlapped(rCol
, rRow
, nTab
))
5409 bool ScDocument::IsHorOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
5411 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
5412 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
5414 return pAttr
->IsHorOverlapped();
5417 OSL_FAIL("Overlapped: Attr==0");
5423 bool ScDocument::IsVerOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
5425 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
5426 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
5428 return pAttr
->IsVerOverlapped();
5431 OSL_FAIL("Overlapped: Attr==0");
5437 void ScDocument::ApplySelectionFrame( const ScMarkData
& rMark
,
5438 const SvxBoxItem
* pLineOuter
,
5439 const SvxBoxInfoItem
* pLineInner
)
5441 ScRangeList aRangeList
;
5442 rMark
.FillRangeListWithMarks( &aRangeList
, false );
5443 size_t nRangeCount
= aRangeList
.size();
5444 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5445 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5446 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5450 for ( size_t j
=0; j
< nRangeCount
; j
++ )
5452 ScRange aRange
= *aRangeList
[ j
];
5453 maTabs
[*itr
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
5454 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
5455 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
5462 void ScDocument::ApplyFrameAreaTab( const ScRange
& rRange
,
5463 const SvxBoxItem
* pLineOuter
,
5464 const SvxBoxInfoItem
* pLineInner
)
5466 SCTAB nStartTab
= rRange
.aStart
.Tab();
5467 SCTAB nEndTab
= rRange
.aStart
.Tab();
5468 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
5470 maTabs
[nTab
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
5471 rRange
.aStart
.Col(), rRange
.aStart
.Row(),
5472 rRange
.aEnd
.Col(), rRange
.aEnd
.Row() );
5476 void ScDocument::ApplySelectionPattern( const ScPatternAttr
& rAttr
, const ScMarkData
& rMark
, ScEditDataArray
* pDataArray
)
5478 const SfxItemSet
* pSet
= &rAttr
.GetItemSet();
5481 for (i
=ATTR_PATTERN_START
; i
<=ATTR_PATTERN_END
&& !bSet
; i
++)
5482 if (pSet
->GetItemState(i
) == SFX_ITEM_SET
)
5487 // ApplySelectionCache needs multi mark
5488 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
5491 rMark
.GetMarkArea( aRange
);
5492 ApplyPatternArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
5493 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rAttr
, pDataArray
);
5497 SfxItemPoolCache
aCache( xPoolHelper
->GetDocPool(), pSet
);
5498 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5499 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5500 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5502 maTabs
[*itr
]->ApplySelectionCache( &aCache
, rMark
, pDataArray
);
5508 void ScDocument::ChangeSelectionIndent( bool bIncrement
, const ScMarkData
& rMark
)
5510 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5511 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5512 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5514 maTabs
[*itr
]->ChangeSelectionIndent( bIncrement
, rMark
);
5518 void ScDocument::ClearSelectionItems( const sal_uInt16
* pWhich
, const ScMarkData
& rMark
)
5520 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5521 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5522 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5524 maTabs
[*itr
]->ClearSelectionItems( pWhich
, rMark
);
5528 void ScDocument::DeleteSelection( sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
5530 SCTAB nMax
= static_cast<SCTAB
>(maTabs
.size());
5531 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
5532 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
5534 maTabs
[*itr
]->DeleteSelection( nDelFlag
, rMark
);
5538 void ScDocument::DeleteSelectionTab( SCTAB nTab
, sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
5540 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5541 maTabs
[nTab
]->DeleteSelection( nDelFlag
, rMark
);
5544 OSL_FAIL("wrong table");
5549 ScPatternAttr
* ScDocument::GetDefPattern() const
5551 return (ScPatternAttr
*) &xPoolHelper
->GetDocPool()->GetDefaultItem(ATTR_PATTERN
);
5555 ScDocumentPool
* ScDocument::GetPool()
5557 return xPoolHelper
->GetDocPool();
5562 ScStyleSheetPool
* ScDocument::GetStyleSheetPool() const
5564 return xPoolHelper
->GetStylePool();
5568 SCSIZE
ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol
, SCROW nStartRow
, SCTAB nStartTab
,
5569 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nEndTab
, ScDirection eDir
)
5571 PutInOrder(nStartCol
, nEndCol
);
5572 PutInOrder(nStartRow
, nEndRow
);
5573 PutInOrder(nStartTab
, nEndTab
);
5574 if (ValidTab(nStartTab
) && nStartTab
< static_cast<SCTAB
>(maTabs
.size()))
5576 if (maTabs
[nStartTab
])
5577 return maTabs
[nStartTab
]->GetEmptyLinesInBlock(nStartCol
, nStartRow
, nEndCol
, nEndRow
, eDir
);
5586 void ScDocument::FindAreaPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, ScMoveDirection eDirection
) const
5588 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5589 maTabs
[nTab
]->FindAreaPos( rCol
, rRow
, eDirection
);
5593 void ScDocument::GetNextPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, SCsCOL nMovX
, SCsROW nMovY
,
5594 bool bMarked
, bool bUnprotected
, const ScMarkData
& rMark
) const
5596 OSL_ENSURE( !nMovX
|| !nMovY
, "GetNextPos: only X or Y" );
5598 ScMarkData aCopyMark
= rMark
;
5599 aCopyMark
.SetMarking(false);
5600 aCopyMark
.MarkToMulti();
5602 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5603 maTabs
[nTab
]->GetNextPos( rCol
, rRow
, nMovX
, nMovY
, bMarked
, bUnprotected
, aCopyMark
);
5607 // Datei-Operationen
5611 void ScDocument::UpdStlShtPtrsFrmNms()
5613 ScPatternAttr::pDoc
= this;
5615 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
5617 sal_uInt32 nCount
= pPool
->GetItemCount2(ATTR_PATTERN
);
5618 ScPatternAttr
* pPattern
;
5619 for (sal_uInt32 i
=0; i
<nCount
; i
++)
5621 pPattern
= (ScPatternAttr
*)pPool
->GetItem2(ATTR_PATTERN
, i
);
5623 pPattern
->UpdateStyleSheet();
5625 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).UpdateStyleSheet();
5629 void ScDocument::StylesToNames()
5631 ScPatternAttr::pDoc
= this;
5633 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
5635 sal_uInt32 nCount
= pPool
->GetItemCount2(ATTR_PATTERN
);
5636 ScPatternAttr
* pPattern
;
5637 for (sal_uInt32 i
=0; i
<nCount
; i
++)
5639 pPattern
= (ScPatternAttr
*)pPool
->GetItem2(ATTR_PATTERN
, i
);
5641 pPattern
->StyleToName();
5643 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).StyleToName();
5647 sal_uLong
ScDocument::GetCellCount() const
5649 sal_uLong nCellCount
= 0L;
5651 TableContainer::const_iterator it
= maTabs
.begin();
5652 for (; it
!= maTabs
.end(); ++it
)
5654 nCellCount
+= (*it
)->GetCellCount();
5659 SCSIZE
ScDocument::GetCellCount(SCTAB nTab
, SCCOL nCol
) const
5661 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
5664 return maTabs
[nTab
]->GetCellCount(nCol
);
5667 sal_uLong
ScDocument::GetCodeCount() const
5669 sal_uLong nCodeCount
= 0;
5671 TableContainer::const_iterator it
= maTabs
.begin();
5672 for (; it
!= maTabs
.end(); ++it
)
5674 nCodeCount
+= (*it
)->GetCodeCount();
5680 void ScDocument::PageStyleModified( SCTAB nTab
, const OUString
& rNewName
)
5682 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5683 maTabs
[nTab
]->PageStyleModified( rNewName
);
5687 void ScDocument::SetPageStyle( SCTAB nTab
, const OUString
& rName
)
5689 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5690 maTabs
[nTab
]->SetPageStyle( rName
);
5694 const OUString
ScDocument::GetPageStyle( SCTAB nTab
) const
5696 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5697 return maTabs
[nTab
]->GetPageStyle();
5703 void ScDocument::SetPageSize( SCTAB nTab
, const Size
& rSize
)
5705 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5706 maTabs
[nTab
]->SetPageSize( rSize
);
5709 Size
ScDocument::GetPageSize( SCTAB nTab
) const
5711 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5712 return maTabs
[nTab
]->GetPageSize();
5714 OSL_FAIL("invalid tab");
5719 void ScDocument::SetRepeatArea( SCTAB nTab
, SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCROW nEndRow
)
5721 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5722 maTabs
[nTab
]->SetRepeatArea( nStartCol
, nEndCol
, nStartRow
, nEndRow
);
5725 void ScDocument::InvalidatePageBreaks(SCTAB nTab
)
5727 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5728 maTabs
[nTab
]->InvalidatePageBreaks();
5731 void ScDocument::UpdatePageBreaks( SCTAB nTab
, const ScRange
* pUserArea
)
5733 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5734 maTabs
[nTab
]->UpdatePageBreaks( pUserArea
);
5737 void ScDocument::RemoveManualBreaks( SCTAB nTab
)
5739 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5740 maTabs
[nTab
]->RemoveManualBreaks();
5743 bool ScDocument::HasManualBreaks( SCTAB nTab
) const
5745 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
5746 return maTabs
[nTab
]->HasManualBreaks();
5748 OSL_FAIL("invalid tab");
5753 void ScDocument::GetDocStat( ScDocStat
& rDocStat
)
5755 rDocStat
.nTableCount
= GetTableCount();
5756 rDocStat
.aDocName
= aDocName
;
5757 rDocStat
.nCellCount
= GetCellCount();
5761 bool ScDocument::HasPrintRange()
5763 bool bResult
= false;
5765 TableContainer::iterator it
= maTabs
.begin();
5766 for (; it
!= maTabs
.end() && !bResult
; ++it
)
5768 bResult
= (*it
)->IsPrintEntireSheet() || ((*it
)->GetPrintRangeCount() > 0);
5774 bool ScDocument::IsPrintEntireSheet( SCTAB nTab
) const
5776 return (ValidTab(nTab
) ) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsPrintEntireSheet();
5780 sal_uInt16
ScDocument::GetPrintRangeCount( SCTAB nTab
)
5782 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5783 return maTabs
[nTab
]->GetPrintRangeCount();
5789 const ScRange
* ScDocument::GetPrintRange( SCTAB nTab
, sal_uInt16 nPos
)
5791 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5792 return maTabs
[nTab
]->GetPrintRange(nPos
);
5798 const ScRange
* ScDocument::GetRepeatColRange( SCTAB nTab
)
5800 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5801 return maTabs
[nTab
]->GetRepeatColRange();
5807 const ScRange
* ScDocument::GetRepeatRowRange( SCTAB nTab
)
5809 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5810 return maTabs
[nTab
]->GetRepeatRowRange();
5816 void ScDocument::ClearPrintRanges( SCTAB nTab
)
5818 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5819 maTabs
[nTab
]->ClearPrintRanges();
5823 void ScDocument::AddPrintRange( SCTAB nTab
, const ScRange
& rNew
)
5825 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5826 maTabs
[nTab
]->AddPrintRange( rNew
);
5830 void ScDocument::SetPrintEntireSheet( SCTAB nTab
)
5832 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5833 maTabs
[nTab
]->SetPrintEntireSheet();
5837 void ScDocument::SetRepeatColRange( SCTAB nTab
, const ScRange
* pNew
)
5839 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5840 maTabs
[nTab
]->SetRepeatColRange( pNew
);
5844 void ScDocument::SetRepeatRowRange( SCTAB nTab
, const ScRange
* pNew
)
5846 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5847 maTabs
[nTab
]->SetRepeatRowRange( pNew
);
5851 ScPrintRangeSaver
* ScDocument::CreatePrintRangeSaver() const
5853 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
5854 ScPrintRangeSaver
* pNew
= new ScPrintRangeSaver( nCount
);
5855 for (SCTAB i
=0; i
<nCount
; i
++)
5857 maTabs
[i
]->FillPrintSaver( pNew
->GetTabData(i
) );
5862 void ScDocument::RestorePrintRanges( const ScPrintRangeSaver
& rSaver
)
5864 SCTAB nCount
= rSaver
.GetTabCount();
5865 for (SCTAB i
=0; i
<nCount
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
5867 maTabs
[i
]->RestorePrintRanges( rSaver
.GetTabData(i
) );
5871 bool ScDocument::NeedPageResetAfterTab( SCTAB nTab
) const
5873 // Die Seitennummern-Zaehlung faengt bei einer Tabelle neu an, wenn eine
5874 // andere Vorlage als bei der vorherigen gesetzt ist (nur Namen vergleichen)
5875 // und eine Seitennummer angegeben ist (nicht 0)
5877 if ( nTab
+ 1 < static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
+1] )
5879 OUString aNew
= maTabs
[nTab
+1]->GetPageStyle();
5880 if ( aNew
!= maTabs
[nTab
]->GetPageStyle() )
5882 SfxStyleSheetBase
* pStyle
= xPoolHelper
->GetStylePool()->Find( aNew
, SFX_STYLE_FAMILY_PAGE
);
5885 const SfxItemSet
& rSet
= pStyle
->GetItemSet();
5886 sal_uInt16 nFirst
= ((const SfxUInt16Item
&)rSet
.Get(ATTR_PAGE_FIRSTPAGENO
)).GetValue();
5888 return true; // Seitennummer in neuer Vorlage angegeben
5893 return false; // sonst nicht
5896 SfxUndoManager
* ScDocument::GetUndoManager()
5899 mpUndoManager
= new SfxUndoManager
;
5900 return mpUndoManager
;
5903 ScRowBreakIterator
* ScDocument::GetRowBreakIterator(SCTAB nTab
) const
5905 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5906 return new ScRowBreakIterator(maTabs
[nTab
]->maRowPageBreaks
);
5910 void ScDocument::AddSubTotalCell(ScFormulaCell
* pCell
)
5912 maSubTotalCells
.insert(pCell
);
5915 void ScDocument::RemoveSubTotalCell(ScFormulaCell
* pCell
)
5917 maSubTotalCells
.erase(pCell
);
5922 bool lcl_hasDirtyRange(ScFormulaCell
* pCell
, const ScRange
& rDirtyRange
)
5924 ScDetectiveRefIter
aRefIter(pCell
);
5926 while (aRefIter
.GetNextRef(aRange
))
5928 if (aRange
.Intersects(rDirtyRange
))
5936 void ScDocument::SetSubTotalCellsDirty(const ScRange
& rDirtyRange
)
5938 // to update the list by skipping cells that no longer contain subtotal function.
5939 set
<ScFormulaCell
*> aNewSet
;
5941 bool bOldRecalc
= GetAutoCalc();
5943 set
<ScFormulaCell
*>::iterator itr
= maSubTotalCells
.begin(), itrEnd
= maSubTotalCells
.end();
5944 for (; itr
!= itrEnd
; ++itr
)
5946 ScFormulaCell
* pCell
= *itr
;
5947 if (pCell
->IsSubTotal())
5949 aNewSet
.insert(pCell
);
5950 if (lcl_hasDirtyRange(pCell
, rDirtyRange
))
5955 SetAutoCalc(bOldRecalc
);
5956 maSubTotalCells
.swap(aNewSet
); // update the list.
5959 sal_uInt16
ScDocument::GetTextWidth( const ScAddress
& rPos
) const
5961 SCTAB nTab
= rPos
.Tab();
5962 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5963 return maTabs
[nTab
]->GetTextWidth(rPos
.Col(), rPos
.Row());
5968 void ScDocument::SetTextWidth( const ScAddress
& rPos
, sal_uInt16 nWidth
)
5970 SCTAB nTab
= rPos
.Tab();
5971 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5972 maTabs
[nTab
]->SetTextWidth(rPos
.Col(), rPos
.Row(), nWidth
);
5975 sal_uInt8
ScDocument::GetScriptType( const ScAddress
& rPos
) const
5977 SCTAB nTab
= rPos
.Tab();
5978 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5979 return maTabs
[nTab
]->GetScriptType(rPos
.Col(), rPos
.Row());
5984 void ScDocument::SetScriptType( const ScAddress
& rPos
, sal_uInt8 nType
)
5986 SCTAB nTab
= rPos
.Tab();
5987 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
5988 maTabs
[nTab
]->SetScriptType(rPos
.Col(), rPos
.Row(), nType
);
5991 void ScDocument::EnableUndo( bool bVal
)
5993 // The undo manager increases lock count every time undo is disabled.
5994 // Because of this, we shouldn't disable undo unless it's currently
5995 // enabled, or else re-enabling it may not actually re-enable undo unless
5996 // the lock count becomes zero.
5998 if (bVal
!= GetUndoManager()->IsUndoEnabled())
6000 GetUndoManager()->EnableUndo(bVal
);
6001 if( pDrawLayer
) pDrawLayer
->EnableUndo(bVal
);
6004 mbUndoEnabled
= bVal
;
6007 bool ScDocument::IsUserInteractionEnabled() const
6009 return mbUserInteractionEnabled
;
6012 void ScDocument::EnableUserInteraction( bool bVal
)
6014 mbUserInteractionEnabled
= bVal
;
6017 bool ScDocument::IsInVBAMode() const
6024 uno::Reference
<script::vba::XVBACompatibility
> xVBA(
6025 pShell
->GetBasicContainer(), uno::UNO_QUERY
);
6027 return xVBA
.is() && xVBA
->getVBACompatibilityMode();
6029 catch (const lang::NotInitializedException
&) {}
6034 ScNotes
* ScDocument::GetNotes(SCTAB nTab
)
6036 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
6037 return maTabs
[nTab
]->GetNotes();
6042 void ScDocument::SetAutoNameCache( ScAutoNameCache
* pCache
)
6044 delete pAutoNameCache
;
6045 pAutoNameCache
= pCache
;
6048 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */