1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: document.cxx,v $
10 * $Revision: 1.90.36.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #define _ZFORLIST_DECLARE_TABLE
37 #include "scitems.hxx"
38 #include <svx/eeitem.hxx>
40 #include <svx/boxitem.hxx>
41 #include <svx/frmdiritem.hxx>
42 #include <svx/pageitem.hxx>
43 #include <svx/editeng.hxx>
44 #include <svx/svditer.hxx>
45 #include <svx/svdpage.hxx>
46 #include <svx/svdocapt.hxx>
47 #include <sfx2/app.hxx>
48 #include <sfx2/objsh.hxx>
49 #include <svtools/poolcach.hxx>
50 #include <svtools/saveopt.hxx>
51 #include <svtools/zforlist.hxx>
52 #include <unotools/charclass.hxx>
53 #include <unotools/transliterationwrapper.hxx>
54 #include <tools/tenccvt.hxx>
56 #include <com/sun/star/text/WritingMode2.hpp>
57 #include <com/sun/star/sheet/TablePageBreakData.hpp>
59 #include "document.hxx"
62 #include "attarray.hxx"
63 #include "markarr.hxx"
64 #include "patattr.hxx"
65 #include "rangenam.hxx"
66 #include "poolhelp.hxx"
67 #include "docpool.hxx"
68 #include "stlpool.hxx"
69 #include "stlsheet.hxx"
70 #include "globstr.hrc"
71 #include "rechead.hxx"
72 #include "dbcolect.hxx"
74 #include "chartlis.hxx"
75 #include "rangelst.hxx"
76 #include "markdata.hxx"
77 #include "drwlayer.hxx"
78 #include "conditio.hxx"
79 #include "validat.hxx"
80 #include "prnsave.hxx"
81 #include "chgtrack.hxx"
83 #include "scresid.hxx"
85 #include "detdata.hxx"
87 #include "dpobject.hxx"
88 #include "detfunc.hxx" // for UpdateAllComments
90 #include "dociter.hxx"
91 #include "progress.hxx"
92 #include "autonamecache.hxx"
93 #include "bcaslot.hxx"
95 #include "externalrefmgr.hxx"
96 #include "tabprotection.hxx"
97 #include "clipparam.hxx"
98 #include <basic/basmgr.hxx>
99 #include <com/sun/star/container/XContainer.hpp>
104 using namespace ::com::sun::star
;
106 namespace WritingMode2
= ::com::sun::star::text::WritingMode2
;
107 using ::com::sun::star::uno::Sequence
;
108 using ::com::sun::star::sheet::TablePageBreakData
;
113 const ScPatternAttr
* pAttr
;
116 ScDefaultAttr(const ScPatternAttr
* pPatAttr
) : pAttr(pPatAttr
), nFirst(0), nCount(0) {}
119 struct ScLessDefaultAttr
121 sal_Bool
operator() (const ScDefaultAttr
& rValue1
, const ScDefaultAttr
& rValue2
) const
123 return rValue1
.pAttr
< rValue2
.pAttr
;
127 typedef std::set
<ScDefaultAttr
, ScLessDefaultAttr
> ScDefaultAttrSet
;
129 void ScDocument::MakeTable( SCTAB nTab
,bool _bNeedsNameCheck
)
131 if ( ValidTab(nTab
) && !pTab
[nTab
] )
133 String aString
= ScGlobal::GetRscString(STR_TABLE_DEF
); //"Tabelle"
134 aString
+= String::CreateFromInt32(nTab
+1);
135 if ( _bNeedsNameCheck
)
136 CreateValidTabName( aString
); // keine doppelten
138 pTab
[nTab
] = new ScTable(this, nTab
, aString
);
144 BOOL
ScDocument::HasTable( SCTAB nTab
) const
154 BOOL
ScDocument::GetName( SCTAB nTab
, String
& rName
) const
159 pTab
[nTab
]->GetName( rName
);
166 BOOL
ScDocument::SetCodeName( SCTAB nTab
, String
& rName
)
172 pTab
[nTab
]->SetCodeName( rName
);
176 OSL_TRACE( "**** can't set code name %s", rtl::OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr() );
180 BOOL
ScDocument::GetCodeName( SCTAB nTab
, String
& rName
) const
185 pTab
[nTab
]->GetCodeName( rName
);
193 BOOL
ScDocument::GetTable( const String
& rName
, SCTAB
& rTab
) const
195 String aUpperName
= rName
;
196 ScGlobal::pCharClass
->toUpper(aUpperName
);
198 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
201 if ( pTab
[i
]->GetUpperName() == aUpperName
)
212 BOOL
ScDocument::ValidTabName( const String
& rName
) const
214 xub_StrLen nLen
= rName
.Len();
219 // Restrict sheet names to what Excel accepts.
220 /* TODO: We may want to remove this restriction for full ODFF compliance.
221 * Merely loading and calculating ODF documents using these characters in
222 * sheet names is not affected by this, but all sheet name editing and
223 * copying functionality is, maybe falling back to "Sheet4" or similar. */
224 for (xub_StrLen i
= 0; i
< nLen
; ++i
)
226 const sal_Unicode c
= rName
.GetChar(i
);
236 // these characters are not allowed to match XL's convention.
239 if (i
== 0 || i
== nLen
- 1)
240 // single quote is not allowed at the first or last
241 // character position.
252 BOOL
ScDocument::ValidNewTabName( const String
& rName
) const
254 BOOL bValid
= ValidTabName(rName
);
255 for (SCTAB i
=0; (i
<=MAXTAB
) && bValid
; i
++)
259 pTab
[i
]->GetName(aOldName
);
260 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
266 void ScDocument::CreateValidTabName(String
& rName
) const
268 if ( !ValidTabName(rName
) )
272 const String
aStrTable( ScResId(SCSTR_TABLE
) );
275 // vorneweg testen, ob der Prefix als gueltig erkannt wird
276 // wenn nicht, nur doppelte vermeiden
277 BOOL bPrefix
= ValidTabName( aStrTable
);
278 DBG_ASSERT(bPrefix
, "ungueltiger Tabellenname");
281 SCTAB nLoops
= 0; // "zur Sicherheit"
282 for ( SCTAB i
= nMaxTableNumber
+1; !bOk
&& nLoops
<= MAXTAB
; i
++ )
285 rName
+= String::CreateFromInt32(i
);
287 bOk
= ValidNewTabName( rName
);
289 bOk
= !GetTable( rName
, nDummy
);
293 DBG_ASSERT(bOk
, "kein gueltiger Tabellenname gefunden");
299 // uebergebenen Namen ueberpruefen
301 if ( !ValidNewTabName(rName
) )
310 aName
+= String::CreateFromInt32(static_cast<sal_Int32
>(i
));
312 while (!ValidNewTabName(aName
) && (i
< MAXTAB
+1));
319 BOOL
ScDocument::InsertTab( SCTAB nPos
, const String
& rName
,
320 BOOL bExternalDocument
)
322 SCTAB nTabCount
= GetTableCount();
323 BOOL bValid
= ValidTab(nTabCount
);
324 if ( !bExternalDocument
) // sonst rName == "'Doc'!Tab", vorher pruefen
325 bValid
= (bValid
&& ValidNewTabName(rName
));
328 if (nPos
== SC_TAB_APPEND
|| nPos
== nTabCount
)
330 pTab
[nTabCount
] = new ScTable(this, nTabCount
, rName
);
331 pTab
[nTabCount
]->SetCodeName( rName
);
333 if ( bExternalDocument
)
334 pTab
[nTabCount
]->SetVisible( FALSE
);
338 if (VALIDTAB(nPos
) && (nPos
< nTabCount
))
340 ScRange
aRange( 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
);
341 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
342 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
343 pRangeName
->UpdateTabRef( nPos
, 1 );
344 pDBCollection
->UpdateReference(
345 URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
347 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
349 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,1 );
350 UpdateChartRef( URM_INSDEL
, 0,0,nPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
351 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,1 );
352 if ( pUnoBroadcaster
)
353 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,1 ) );
356 for (i
= 0; i
<= MAXTAB
; i
++)
358 pTab
[i
]->UpdateInsertTab(nPos
);
360 for (i
= nTabCount
; i
> nPos
; i
--)
362 pTab
[i
] = pTab
[i
- 1];
365 pTab
[nPos
] = new ScTable(this, nPos
, rName
);
366 pTab
[nPos
]->SetCodeName( rName
);
369 // UpdateBroadcastAreas must be called between UpdateInsertTab,
370 // which ends listening, and StartAllListeners, to not modify
371 // areas that are to be inserted by starting listeners.
372 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,1);
373 for (i
= 0; i
<= MAXTAB
; i
++)
375 pTab
[i
]->UpdateCompile();
376 for (i
= 0; i
<= MAXTAB
; i
++)
378 pTab
[i
]->StartAllListeners();
380 // update conditional formats after table is inserted
382 pCondFormList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
383 if ( pValidationList
)
384 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
385 // #81844# sheet names of references are not valid until sheet is inserted
386 if ( pChartListenerCollection
)
387 pChartListenerCollection
->UpdateScheduledSeriesRanges();
389 // Update cells containing external references.
390 if (pExternalRefMgr
.get())
391 pExternalRefMgr
->updateRefInsertTable(nPos
);
404 BOOL
ScDocument::DeleteTab( SCTAB nTab
, ScDocument
* pRefUndoDoc
)
411 SCTAB nTabCount
= GetTableCount();
414 BOOL bOldAutoCalc
= GetAutoCalc();
415 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
416 ScRange
aRange( 0, 0, nTab
, MAXCOL
, MAXROW
, nTab
);
417 DelBroadcastAreasInRange( aRange
);
419 // #i8180# remove database ranges etc. that are on the deleted tab
420 // (restored in undo with ScRefUndoData)
422 xColNameRanges
->DeleteOnTab( nTab
);
423 xRowNameRanges
->DeleteOnTab( nTab
);
424 pDBCollection
->DeleteOnTab( nTab
);
426 pDPCollection
->DeleteOnTab( nTab
);
428 pDetOpList
->DeleteOnTab( nTab
);
429 DeleteAreaLinksOnTab( nTab
);
431 // normal reference update
433 aRange
.aEnd
.SetTab( MAXTAB
);
434 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
435 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,-1 );
436 pRangeName
->UpdateTabRef( nTab
, 2 );
437 pDBCollection
->UpdateReference(
438 URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
440 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
442 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,-1 );
443 UpdateChartRef( URM_INSDEL
, 0,0,nTab
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,-1 );
444 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,-1 );
446 pCondFormList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
447 if ( pValidationList
)
448 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,-1 );
449 if ( pUnoBroadcaster
)
450 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,-1 ) );
453 for (i
=0; i
<=MAXTAB
; i
++)
455 pTab
[i
]->UpdateDeleteTab(nTab
,FALSE
,
456 pRefUndoDoc
? pRefUndoDoc
->pTab
[i
] : 0);
458 for (i
=nTab
+ 1; i
< nTabCount
; i
++)
460 pTab
[i
- 1] = pTab
[i
];
463 pTab
[nTabCount
- 1] = NULL
;
465 // UpdateBroadcastAreas must be called between UpdateDeleteTab,
466 // which ends listening, and StartAllListeners, to not modify
467 // areas that are to be inserted by starting listeners.
468 UpdateBroadcastAreas( URM_INSDEL
, aRange
, 0,0,-1);
469 for (i
= 0; i
<= MAXTAB
; i
++)
471 pTab
[i
]->UpdateCompile();
472 // Excel-Filter loescht einige Tables waehrend des Ladens,
473 // Listener werden erst nach dem Laden aufgesetzt
474 if ( !bInsertingFromOtherDoc
)
476 for (i
= 0; i
<= MAXTAB
; i
++)
478 pTab
[i
]->StartAllListeners();
481 // #81844# sheet names of references are not valid until sheet is deleted
482 pChartListenerCollection
->UpdateScheduledSeriesRanges();
485 // Update cells containing external references.
486 if (pExternalRefMgr
.get())
487 pExternalRefMgr
->updateRefDeleteTable(nTab
);
489 SetAutoCalc( bOldAutoCalc
);
498 BOOL
ScDocument::RenameTab( SCTAB nTab
, const String
& rName
, BOOL
/* bUpdateRef */,
499 BOOL bExternalDocument
)
506 if ( bExternalDocument
)
507 bValid
= TRUE
; // zusammengesetzter Name
509 bValid
= ValidTabName(rName
);
510 for (i
=0; (i
<=MAXTAB
) && bValid
; i
++)
511 if (pTab
[i
] && (i
!= nTab
))
514 pTab
[i
]->GetName(aOldName
);
515 bValid
= !ScGlobal::GetpTransliteration()->isEqual( rName
, aOldName
);
519 // #i75258# update charts before renaming, so they can get their live data objects.
520 // Once the charts are live, the sheet can be renamed without problems.
521 if ( pChartListenerCollection
)
522 pChartListenerCollection
->UpdateChartsContainingTab( nTab
);
523 pTab
[nTab
]->SetName(rName
);
530 void ScDocument::SetVisible( SCTAB nTab
, BOOL bVisible
)
534 pTab
[nTab
]->SetVisible(bVisible
);
538 BOOL
ScDocument::IsVisible( SCTAB nTab
) const
542 return pTab
[nTab
]->IsVisible();
548 BOOL
ScDocument::IsStreamValid( SCTAB nTab
) const
550 if ( ValidTab(nTab
) && pTab
[nTab
] )
551 return pTab
[nTab
]->IsStreamValid();
557 void ScDocument::SetStreamValid( SCTAB nTab
, BOOL bSet
, BOOL bIgnoreLock
)
559 if ( ValidTab(nTab
) && pTab
[nTab
] )
560 pTab
[nTab
]->SetStreamValid( bSet
, bIgnoreLock
);
564 void ScDocument::LockStreamValid( bool bLock
)
566 mbStreamValidLocked
= bLock
;
570 BOOL
ScDocument::IsPendingRowHeights( SCTAB nTab
) const
572 if ( ValidTab(nTab
) && pTab
[nTab
] )
573 return pTab
[nTab
]->IsPendingRowHeights();
579 void ScDocument::SetPendingRowHeights( SCTAB nTab
, BOOL bSet
)
581 if ( ValidTab(nTab
) && pTab
[nTab
] )
582 pTab
[nTab
]->SetPendingRowHeights( bSet
);
586 void ScDocument::SetLayoutRTL( SCTAB nTab
, BOOL bRTL
)
588 if ( ValidTab(nTab
) && pTab
[nTab
] )
592 // #i57869# only set the LoadingRTL flag, the real setting (including mirroring)
593 // is applied in SetImportingXML(FALSE). This is so the shapes can be loaded in
596 pTab
[nTab
]->SetLoadingRTL( bRTL
);
600 pTab
[nTab
]->SetLayoutRTL( bRTL
); // only sets the flag
601 pTab
[nTab
]->SetDrawPageSize();
603 // mirror existing objects:
607 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
608 DBG_ASSERT(pPage
,"Page ?");
611 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
612 SdrObject
* pObject
= aIter
.Next();
615 // objects with ScDrawObjData are re-positioned in SetPageSize,
616 // don't mirror again
617 ScDrawObjData
* pData
= ScDrawLayer::GetObjData( pObject
);
619 pDrawLayer
->MirrorRTL( pObject
);
621 pObject
->SetContextWritingMode( bRTL
? WritingMode2::RL_TB
: WritingMode2::LR_TB
);
623 pObject
= aIter
.Next();
631 BOOL
ScDocument::IsLayoutRTL( SCTAB nTab
) const
633 if ( ValidTab(nTab
) && pTab
[nTab
] )
634 return pTab
[nTab
]->IsLayoutRTL();
640 BOOL
ScDocument::IsNegativePage( SCTAB nTab
) const
642 // Negative page area is always used for RTL layout.
643 // The separate method is used to find all RTL handling of drawing objects.
644 return IsLayoutRTL( nTab
);
648 /* ----------------------------------------------------------------------------
649 benutzten Bereich suchen:
651 GetCellArea - nur Daten
652 GetTableArea - Daten / Attribute
653 GetPrintArea - beruecksichtigt auch Zeichenobjekte,
654 streicht Attribute bis ganz rechts / unten
655 ---------------------------------------------------------------------------- */
658 BOOL
ScDocument::GetCellArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
662 return pTab
[nTab
]->GetCellArea( rEndCol
, rEndRow
);
670 BOOL
ScDocument::GetTableArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
674 return pTab
[nTab
]->GetTableArea( rEndCol
, rEndRow
);
681 bool ScDocument::ShrinkToDataArea(SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
, SCCOL
& rEndCol
, SCROW
& rEndRow
) const
683 if (!ValidTab(nTab
) || !pTab
[nTab
])
688 pTab
[nTab
]->GetFirstDataPos(nCol1
, nRow1
);
689 pTab
[nTab
]->GetLastDataPos(nCol2
, nRow2
);
691 if (nCol1
> nCol2
|| nRow1
> nRow2
)
695 // Make sure the area only shrinks, and doesn't grow.
696 if (rStartCol
< nCol1
)
700 if (rStartRow
< nRow1
)
705 return true; // success!
708 // zusammenhaengender Bereich
710 void ScDocument::GetDataArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
711 SCCOL
& rEndCol
, SCROW
& rEndRow
, BOOL bIncludeOld
) const
715 pTab
[nTab
]->GetDataArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
, bIncludeOld
);
719 void ScDocument::LimitChartArea( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
,
720 SCCOL
& rEndCol
, SCROW
& rEndRow
)
724 pTab
[nTab
]->LimitChartArea( rStartCol
, rStartRow
, rEndCol
, rEndRow
);
728 void ScDocument::LimitChartIfAll( ScRangeListRef
& rRangeList
)
730 ScRangeListRef aNew
= new ScRangeList
;
733 ULONG nCount
= rRangeList
->Count();
734 for (ULONG i
=0; i
<nCount
; i
++)
736 ScRange
aRange(*rRangeList
->GetObject( i
));
737 if ( ( aRange
.aStart
.Col() == 0 && aRange
.aEnd
.Col() == MAXCOL
) ||
738 ( aRange
.aStart
.Row() == 0 && aRange
.aEnd
.Row() == MAXROW
) )
740 SCCOL nStartCol
= aRange
.aStart
.Col();
741 SCROW nStartRow
= aRange
.aStart
.Row();
742 SCCOL nEndCol
= aRange
.aEnd
.Col();
743 SCROW nEndRow
= aRange
.aEnd
.Row();
744 SCTAB nTab
= aRange
.aStart
.Tab();
746 pTab
[nTab
]->LimitChartArea(nStartCol
, nStartRow
, nEndCol
, nEndRow
);
747 aRange
.aStart
.SetCol( nStartCol
);
748 aRange
.aStart
.SetRow( nStartRow
);
749 aRange
.aEnd
.SetCol( nEndCol
);
750 aRange
.aEnd
.SetRow( nEndRow
);
752 aNew
->Append(aRange
);
757 DBG_ERROR("LimitChartIfAll: Ref==0");
763 void lcl_GetFirstTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
)
765 // without ScMarkData, leave start/end unchanged
768 for (SCTAB nTab
=0; nTab
<=MAXTAB
; ++nTab
)
769 if (pTabMark
->GetTableSelect(nTab
))
771 // find first range of consecutive selected sheets
772 rTabRangeStart
= nTab
;
773 while ( nTab
+1 <= MAXTAB
&& pTabMark
->GetTableSelect(nTab
+1) )
781 bool lcl_GetNextTabRange( SCTAB
& rTabRangeStart
, SCTAB
& rTabRangeEnd
, const ScMarkData
* pTabMark
)
785 // find next range of consecutive selected sheets after rTabRangeEnd
786 for (SCTAB nTab
=rTabRangeEnd
+1; nTab
<=MAXTAB
; ++nTab
)
787 if (pTabMark
->GetTableSelect(nTab
))
789 rTabRangeStart
= nTab
;
790 while ( nTab
+1 <= MAXTAB
&& pTabMark
->GetTableSelect(nTab
+1) )
800 BOOL
ScDocument::CanInsertRow( const ScRange
& rRange
) const
802 SCCOL nStartCol
= rRange
.aStart
.Col();
803 SCROW nStartRow
= rRange
.aStart
.Row();
804 SCTAB nStartTab
= rRange
.aStart
.Tab();
805 SCCOL nEndCol
= rRange
.aEnd
.Col();
806 SCROW nEndRow
= rRange
.aEnd
.Row();
807 SCTAB nEndTab
= rRange
.aEnd
.Tab();
808 PutInOrder( nStartCol
, nEndCol
);
809 PutInOrder( nStartRow
, nEndRow
);
810 PutInOrder( nStartTab
, nEndTab
);
811 SCSIZE nSize
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
814 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
; i
++)
816 bTest
&= pTab
[i
]->TestInsertRow( nStartCol
, nEndCol
, nSize
);
822 BOOL
ScDocument::InsertRow( SCCOL nStartCol
, SCTAB nStartTab
,
823 SCCOL nEndCol
, SCTAB nEndTab
,
824 SCROW nStartRow
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
825 const ScMarkData
* pTabMark
)
829 PutInOrder( nStartCol
, nEndCol
);
830 PutInOrder( nStartTab
, nEndTab
);
839 BOOL bOldAutoCalc
= GetAutoCalc();
840 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
841 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
; i
++)
842 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
843 bTest
&= pTab
[i
]->TestInsertRow( nStartCol
, nEndCol
, nSize
);
846 // UpdateBroadcastAreas muss vor UpdateReference gerufen werden, damit nicht
847 // Eintraege verschoben werden, die erst bei UpdateReference neu erzeugt werden
849 // handle chunks of consecutive selected sheets together
850 SCTAB nTabRangeStart
= nStartTab
;
851 SCTAB nTabRangeEnd
= nEndTab
;
852 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
855 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
856 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
857 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, static_cast<SCsROW
>(nSize
), 0 );
859 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
861 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
864 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
, nTabRangeStart
,
865 nEndCol
, MAXROW
, nTabRangeEnd
,
866 0, static_cast<SCsROW
>(nSize
), 0, pRefUndoDoc
, FALSE
); // without drawing objects
868 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
870 for (i
=nStartTab
; i
<=nEndTab
; i
++)
871 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
872 pTab
[i
]->InsertRow( nStartCol
, nEndCol
, nStartRow
, nSize
);
874 // #82991# UpdateRef for drawing layer must be after inserting,
875 // when the new row heights are known.
876 for (i
=nStartTab
; i
<=nEndTab
; i
++)
877 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
878 pTab
[i
]->UpdateDrawRef( URM_INSDEL
,
879 nStartCol
, nStartRow
, nStartTab
, nEndCol
, MAXROW
, nEndTab
,
880 0, static_cast<SCsROW
>(nSize
), 0 );
882 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
883 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
884 // ein neues Listening faellig, bisherige Listener wurden in
885 // FormulaCell UpdateReference abgehaengt
889 { // Listeners have been removed in UpdateReference
890 for (i
=0; i
<=MAXTAB
; i
++)
892 pTab
[i
]->StartNeededListeners();
893 // #69592# at least all cells using range names pointing relative
894 // to the moved range must recalculate
895 for (i
=0; i
<=MAXTAB
; i
++)
897 pTab
[i
]->SetRelNameDirty();
901 SetAutoCalc( bOldAutoCalc
);
903 pChartListenerCollection
->UpdateDirtyCharts();
908 BOOL
ScDocument::InsertRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
910 return InsertRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
911 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
912 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
917 void ScDocument::DeleteRow( SCCOL nStartCol
, SCTAB nStartTab
,
918 SCCOL nEndCol
, SCTAB nEndTab
,
919 SCROW nStartRow
, SCSIZE nSize
,
920 ScDocument
* pRefUndoDoc
, BOOL
* pUndoOutline
,
921 const ScMarkData
* pTabMark
)
925 PutInOrder( nStartCol
, nEndCol
);
926 PutInOrder( nStartTab
, nEndTab
);
933 BOOL bOldAutoCalc
= GetAutoCalc();
934 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
936 // handle chunks of consecutive selected sheets together
937 SCTAB nTabRangeStart
= nStartTab
;
938 SCTAB nTabRangeEnd
= nEndTab
;
939 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
942 if ( ValidRow(nStartRow
+nSize
) )
944 DelBroadcastAreasInRange( ScRange(
945 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
946 ScAddress( nEndCol
, nStartRow
+nSize
-1, nTabRangeEnd
) ) );
947 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
948 ScAddress( nStartCol
, nStartRow
+nSize
, nTabRangeStart
),
949 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
)), 0, -(static_cast<SCsROW
>(nSize
)), 0 );
952 DelBroadcastAreasInRange( ScRange(
953 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
954 ScAddress( nEndCol
, MAXROW
, nTabRangeEnd
) ) );
956 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
958 if ( ValidRow(nStartRow
+nSize
) )
960 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
963 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
+nSize
, nTabRangeStart
,
964 nEndCol
, MAXROW
, nTabRangeEnd
,
965 0, -(static_cast<SCsROW
>(nSize
)), 0, pRefUndoDoc
);
967 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
971 *pUndoOutline
= FALSE
;
973 for ( i
= nStartTab
; i
<= nEndTab
; i
++)
974 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
975 pTab
[i
]->DeleteRow( nStartCol
, nEndCol
, nStartRow
, nSize
, pUndoOutline
);
977 if ( ValidRow(nStartRow
+nSize
) )
978 { // Listeners have been removed in UpdateReference
979 for (i
=0; i
<=MAXTAB
; i
++)
981 pTab
[i
]->StartNeededListeners();
982 // #69592# at least all cells using range names pointing relative to
983 // the moved range must recalculate
984 for (i
=0; i
<=MAXTAB
; i
++)
986 pTab
[i
]->SetRelNameDirty();
989 SetAutoCalc( bOldAutoCalc
);
990 pChartListenerCollection
->UpdateDirtyCharts();
994 void ScDocument::DeleteRow( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, BOOL
* pUndoOutline
)
996 DeleteRow( rRange
.aStart
.Col(), rRange
.aStart
.Tab(),
997 rRange
.aEnd
.Col(), rRange
.aEnd
.Tab(),
998 rRange
.aStart
.Row(), static_cast<SCSIZE
>(rRange
.aEnd
.Row()-rRange
.aStart
.Row()+1),
999 pRefUndoDoc
, pUndoOutline
);
1003 BOOL
ScDocument::CanInsertCol( const ScRange
& rRange
) const
1005 SCCOL nStartCol
= rRange
.aStart
.Col();
1006 SCROW nStartRow
= rRange
.aStart
.Row();
1007 SCTAB nStartTab
= rRange
.aStart
.Tab();
1008 SCCOL nEndCol
= rRange
.aEnd
.Col();
1009 SCROW nEndRow
= rRange
.aEnd
.Row();
1010 SCTAB nEndTab
= rRange
.aEnd
.Tab();
1011 PutInOrder( nStartCol
, nEndCol
);
1012 PutInOrder( nStartRow
, nEndRow
);
1013 PutInOrder( nStartTab
, nEndTab
);
1014 SCSIZE nSize
= static_cast<SCSIZE
>(nEndCol
- nStartCol
+ 1);
1017 for (SCTAB i
=nStartTab
; i
<=nEndTab
&& bTest
; i
++)
1019 bTest
&= pTab
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1025 BOOL
ScDocument::InsertCol( SCROW nStartRow
, SCTAB nStartTab
,
1026 SCROW nEndRow
, SCTAB nEndTab
,
1027 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1028 const ScMarkData
* pTabMark
)
1032 PutInOrder( nStartRow
, nEndRow
);
1033 PutInOrder( nStartTab
, nEndTab
);
1042 BOOL bOldAutoCalc
= GetAutoCalc();
1043 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1044 for ( i
= nStartTab
; i
<= nEndTab
&& bTest
; i
++)
1045 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1046 bTest
&= pTab
[i
]->TestInsertCol( nStartRow
, nEndRow
, nSize
);
1049 // handle chunks of consecutive selected sheets together
1050 SCTAB nTabRangeStart
= nStartTab
;
1051 SCTAB nTabRangeEnd
= nEndTab
;
1052 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
1055 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1056 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1057 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), static_cast<SCsCOL
>(nSize
), 0, 0 );
1059 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
1061 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
1064 UpdateReference( URM_INSDEL
, nStartCol
, nStartRow
, nTabRangeStart
,
1065 MAXCOL
, nEndRow
, nTabRangeEnd
,
1066 static_cast<SCsCOL
>(nSize
), 0, 0, pRefUndoDoc
);
1068 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
1070 for (i
=nStartTab
; i
<=nEndTab
; i
++)
1071 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1072 pTab
[i
]->InsertCol( nStartCol
, nStartRow
, nEndRow
, nSize
);
1074 if ( pChangeTrack
&& pChangeTrack
->IsInDeleteUndo() )
1075 { // durch Restaurierung von Referenzen auf geloeschte Bereiche ist
1076 // ein neues Listening faellig, bisherige Listener wurden in
1077 // FormulaCell UpdateReference abgehaengt
1078 StartAllListeners();
1081 { // Listeners have been removed in UpdateReference
1082 for (i
=0; i
<=MAXTAB
; i
++)
1084 pTab
[i
]->StartNeededListeners();
1085 // #69592# at least all cells using range names pointing relative
1086 // to the moved range must recalculate
1087 for (i
=0; i
<=MAXTAB
; i
++)
1089 pTab
[i
]->SetRelNameDirty();
1093 SetAutoCalc( bOldAutoCalc
);
1095 pChartListenerCollection
->UpdateDirtyCharts();
1100 BOOL
ScDocument::InsertCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
)
1102 return InsertCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1103 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1104 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1109 void ScDocument::DeleteCol(SCROW nStartRow
, SCTAB nStartTab
, SCROW nEndRow
, SCTAB nEndTab
,
1110 SCCOL nStartCol
, SCSIZE nSize
, ScDocument
* pRefUndoDoc
,
1111 BOOL
* pUndoOutline
, const ScMarkData
* pTabMark
)
1115 PutInOrder( nStartRow
, nEndRow
);
1116 PutInOrder( nStartTab
, nEndTab
);
1123 BOOL bOldAutoCalc
= GetAutoCalc();
1124 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1126 // handle chunks of consecutive selected sheets together
1127 SCTAB nTabRangeStart
= nStartTab
;
1128 SCTAB nTabRangeEnd
= nEndTab
;
1129 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
1132 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1134 DelBroadcastAreasInRange( ScRange(
1135 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1136 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
-1), nEndRow
, nTabRangeEnd
) ) );
1137 UpdateBroadcastAreas( URM_INSDEL
, ScRange(
1138 ScAddress( sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
),
1139 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
)), -static_cast<SCsCOL
>(nSize
), 0, 0 );
1142 DelBroadcastAreasInRange( ScRange(
1143 ScAddress( nStartCol
, nStartRow
, nTabRangeStart
),
1144 ScAddress( MAXCOL
, nEndRow
, nTabRangeEnd
) ) );
1146 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
1148 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1150 lcl_GetFirstTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
);
1153 UpdateReference( URM_INSDEL
, sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
), nStartRow
, nTabRangeStart
,
1154 MAXCOL
, nEndRow
, nTabRangeEnd
,
1155 -static_cast<SCsCOL
>(nSize
), 0, 0, pRefUndoDoc
);
1157 while ( lcl_GetNextTabRange( nTabRangeStart
, nTabRangeEnd
, pTabMark
) );
1161 *pUndoOutline
= FALSE
;
1163 for ( i
= nStartTab
; i
<= nEndTab
; i
++)
1164 if (pTab
[i
] && (!pTabMark
|| pTabMark
->GetTableSelect(i
)))
1165 pTab
[i
]->DeleteCol( nStartCol
, nStartRow
, nEndRow
, nSize
, pUndoOutline
);
1167 if ( ValidCol(sal::static_int_cast
<SCCOL
>(nStartCol
+nSize
)) )
1168 { // Listeners have been removed in UpdateReference
1169 for (i
=0; i
<=MAXTAB
; i
++)
1171 pTab
[i
]->StartNeededListeners();
1172 // #69592# at least all cells using range names pointing relative to
1173 // the moved range must recalculate
1174 for (i
=0; i
<=MAXTAB
; i
++)
1176 pTab
[i
]->SetRelNameDirty();
1179 SetAutoCalc( bOldAutoCalc
);
1180 pChartListenerCollection
->UpdateDirtyCharts();
1184 void ScDocument::DeleteCol( const ScRange
& rRange
, ScDocument
* pRefUndoDoc
, BOOL
* pUndoOutline
)
1186 DeleteCol( rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
1187 rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
1188 rRange
.aStart
.Col(), static_cast<SCSIZE
>(rRange
.aEnd
.Col()-rRange
.aStart
.Col()+1),
1189 pRefUndoDoc
, pUndoOutline
);
1193 // fuer Area-Links: Zellen einuegen/loeschen, wenn sich der Bereich veraendert
1197 void lcl_GetInsDelRanges( const ScRange
& rOld
, const ScRange
& rNew
,
1198 ScRange
& rColRange
, BOOL
& rInsCol
, BOOL
& rDelCol
,
1199 ScRange
& rRowRange
, BOOL
& rInsRow
, BOOL
& rDelRow
)
1201 DBG_ASSERT( rOld
.aStart
== rNew
.aStart
, "FitBlock: Anfang unterschiedlich" );
1203 rInsCol
= rDelCol
= rInsRow
= rDelRow
= FALSE
;
1205 SCCOL nStartX
= rOld
.aStart
.Col();
1206 SCROW nStartY
= rOld
.aStart
.Row();
1207 SCCOL nOldEndX
= rOld
.aEnd
.Col();
1208 SCROW nOldEndY
= rOld
.aEnd
.Row();
1209 SCCOL nNewEndX
= rNew
.aEnd
.Col();
1210 SCROW nNewEndY
= rNew
.aEnd
.Row();
1211 SCTAB nTab
= rOld
.aStart
.Tab();
1213 // wenn es mehr Zeilen werden, werden Spalten auf der alten Hoehe eingefuegt/geloescht
1214 BOOL bGrowY
= ( nNewEndY
> nOldEndY
);
1215 SCROW nColEndY
= bGrowY
? nOldEndY
: nNewEndY
;
1216 SCCOL nRowEndX
= bGrowY
? nNewEndX
: nOldEndX
;
1220 if ( nNewEndX
> nOldEndX
) // Spalten einfuegen
1222 rColRange
= ScRange( nOldEndX
+1, nStartY
, nTab
, nNewEndX
, nColEndY
, nTab
);
1225 else if ( nNewEndX
< nOldEndX
) // Spalten loeschen
1227 rColRange
= ScRange( nNewEndX
+1, nStartY
, nTab
, nOldEndX
, nColEndY
, nTab
);
1233 if ( nNewEndY
> nOldEndY
) // Zeilen einfuegen
1235 rRowRange
= ScRange( nStartX
, nOldEndY
+1, nTab
, nRowEndX
, nNewEndY
, nTab
);
1238 else if ( nNewEndY
< nOldEndY
) // Zeilen loeschen
1240 rRowRange
= ScRange( nStartX
, nNewEndY
+1, nTab
, nRowEndX
, nOldEndY
, nTab
);
1246 BOOL
ScDocument::HasPartOfMerged( const ScRange
& rRange
)
1249 SCTAB nTab
= rRange
.aStart
.Tab();
1251 SCCOL nStartX
= rRange
.aStart
.Col();
1252 SCROW nStartY
= rRange
.aStart
.Row();
1253 SCCOL nEndX
= rRange
.aEnd
.Col();
1254 SCROW nEndY
= rRange
.aEnd
.Row();
1256 if (HasAttrib( nStartX
, nStartY
, nTab
, nEndX
, nEndY
, nTab
,
1257 HASATTR_MERGED
| HASATTR_OVERLAPPED
))
1259 ExtendMerge( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1260 ExtendOverlapped( nStartX
, nStartY
, nEndX
, nEndY
, nTab
);
1262 bPart
= ( nStartX
!= rRange
.aStart
.Col() || nEndX
!= rRange
.aEnd
.Col() ||
1263 nStartY
!= rRange
.aStart
.Row() || nEndY
!= rRange
.aEnd
.Row() );
1269 BOOL
ScDocument::CanFitBlock( const ScRange
& rOld
, const ScRange
& rNew
)
1275 BOOL bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1276 ScRange aColRange
,aRowRange
;
1277 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1279 if ( bInsCol
&& !CanInsertCol( aColRange
) ) // Zellen am Rand ?
1281 if ( bInsRow
&& !CanInsertRow( aRowRange
) ) // Zellen am Rand ?
1284 if ( bInsCol
|| bDelCol
)
1286 aColRange
.aEnd
.SetCol(MAXCOL
);
1287 if ( HasPartOfMerged(aColRange
) )
1290 if ( bInsRow
|| bDelRow
)
1292 aRowRange
.aEnd
.SetRow(MAXROW
);
1293 if ( HasPartOfMerged(aRowRange
) )
1301 void ScDocument::FitBlock( const ScRange
& rOld
, const ScRange
& rNew
, BOOL bClear
)
1304 DeleteAreaTab( rOld
, IDF_ALL
);
1306 BOOL bInsCol
,bDelCol
,bInsRow
,bDelRow
;
1307 ScRange aColRange
,aRowRange
;
1308 lcl_GetInsDelRanges( rOld
, rNew
, aColRange
,bInsCol
,bDelCol
, aRowRange
,bInsRow
,bDelRow
);
1311 InsertCol( aColRange
); // Spalten zuerst einfuegen
1313 InsertRow( aRowRange
);
1316 DeleteRow( aRowRange
); // Zeilen zuerst loeschen
1318 DeleteCol( aColRange
);
1320 // Referenzen um eingefuegte Zeilen erweitern
1322 if ( bInsCol
|| bInsRow
)
1324 ScRange aGrowSource
= rOld
;
1325 aGrowSource
.aEnd
.SetCol(Min( rOld
.aEnd
.Col(), rNew
.aEnd
.Col() ));
1326 aGrowSource
.aEnd
.SetRow(Min( rOld
.aEnd
.Row(), rNew
.aEnd
.Row() ));
1327 SCCOL nGrowX
= bInsCol
? ( rNew
.aEnd
.Col() - rOld
.aEnd
.Col() ) : 0;
1328 SCROW nGrowY
= bInsRow
? ( rNew
.aEnd
.Row() - rOld
.aEnd
.Row() ) : 0;
1329 UpdateGrow( aGrowSource
, nGrowX
, nGrowY
);
1334 void ScDocument::DeleteArea(SCCOL nCol1
, SCROW nRow1
,
1335 SCCOL nCol2
, SCROW nRow2
,
1336 const ScMarkData
& rMark
, USHORT nDelFlag
)
1338 PutInOrder( nCol1
, nCol2
);
1339 PutInOrder( nRow1
, nRow2
);
1340 BOOL bOldAutoCalc
= GetAutoCalc();
1341 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1342 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
1344 if ( rMark
.GetTableSelect(i
) || bIsUndo
)
1345 pTab
[i
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1346 SetAutoCalc( bOldAutoCalc
);
1350 void ScDocument::DeleteAreaTab(SCCOL nCol1
, SCROW nRow1
,
1351 SCCOL nCol2
, SCROW nRow2
,
1352 SCTAB nTab
, USHORT nDelFlag
)
1354 PutInOrder( nCol1
, nCol2
);
1355 PutInOrder( nRow1
, nRow2
);
1356 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
1358 BOOL bOldAutoCalc
= GetAutoCalc();
1359 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1360 pTab
[nTab
]->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, nDelFlag
);
1361 SetAutoCalc( bOldAutoCalc
);
1366 void ScDocument::DeleteAreaTab( const ScRange
& rRange
, USHORT nDelFlag
)
1368 for ( SCTAB nTab
= rRange
.aStart
.Tab(); nTab
<= rRange
.aEnd
.Tab(); nTab
++ )
1369 DeleteAreaTab( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
1370 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
1375 void ScDocument::InitUndoSelected( ScDocument
* pSrcDoc
, const ScMarkData
& rTabSelection
,
1376 BOOL bColInfo
, BOOL bRowInfo
)
1382 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1385 for (SCTAB nTab
= 0; nTab
<= MAXTAB
; nTab
++)
1386 if ( rTabSelection
.GetTableSelect( nTab
) )
1388 pTab
[nTab
] = new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1389 nMaxTableNumber
= nTab
+ 1;
1394 DBG_ERROR("InitUndo");
1399 void ScDocument::InitUndo( ScDocument
* pSrcDoc
, SCTAB nTab1
, SCTAB nTab2
,
1400 BOOL bColInfo
, BOOL bRowInfo
)
1406 xPoolHelper
= pSrcDoc
->xPoolHelper
;
1409 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1410 pTab
[nTab
] = new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1412 nMaxTableNumber
= nTab2
+ 1;
1416 DBG_ERROR("InitUndo");
1421 void ScDocument::AddUndoTab( SCTAB nTab1
, SCTAB nTab2
, BOOL bColInfo
, BOOL bRowInfo
)
1426 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; nTab
++)
1428 pTab
[nTab
] = new ScTable(this, nTab
, aString
, bColInfo
, bRowInfo
);
1430 if ( nMaxTableNumber
<= nTab2
)
1431 nMaxTableNumber
= nTab2
+ 1;
1435 DBG_ERROR("InitUndo");
1440 void ScDocument::SetCutMode( BOOL bVal
)
1443 GetClipParam().mbCutMode
= bVal
;
1446 DBG_ERROR("SetCutMode without bIsClip");
1451 BOOL
ScDocument::IsCutMode()
1454 return GetClipParam().mbCutMode
;
1457 DBG_ERROR("IsCutMode ohne bIsClip");
1463 void ScDocument::CopyToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1464 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1465 USHORT nFlags
, BOOL bOnlyMarked
, ScDocument
* pDestDoc
,
1466 const ScMarkData
* pMarks
, BOOL bColRowFlags
)
1468 PutInOrder( nCol1
, nCol2
);
1469 PutInOrder( nRow1
, nRow2
);
1470 PutInOrder( nTab1
, nTab2
);
1471 if( !pDestDoc
->aDocName
.Len() )
1472 pDestDoc
->aDocName
= aDocName
;
1473 if (VALIDTAB(nTab1
) && VALIDTAB(nTab2
))
1475 BOOL bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1476 pDestDoc
->SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1477 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
1479 if (pTab
[i
] && pDestDoc
->pTab
[i
])
1480 pTab
[i
]->CopyToTable( nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1481 bOnlyMarked
, pDestDoc
->pTab
[i
], pMarks
,
1482 FALSE
, bColRowFlags
);
1484 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1489 void ScDocument::UndoToDocument(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1490 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
1491 USHORT nFlags
, BOOL bOnlyMarked
, ScDocument
* pDestDoc
,
1492 const ScMarkData
* pMarks
)
1494 PutInOrder( nCol1
, nCol2
);
1495 PutInOrder( nRow1
, nRow2
);
1496 PutInOrder( nTab1
, nTab2
);
1497 if (VALIDTAB(nTab1
) && VALIDTAB(nTab2
))
1499 BOOL bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1500 pDestDoc
->SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1502 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, FALSE
, pDestDoc
, pMarks
);
1504 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
1506 if (pTab
[i
] && pDestDoc
->pTab
[i
])
1507 pTab
[i
]->UndoToTable(nCol1
, nRow1
, nCol2
, nRow2
, nFlags
,
1508 bOnlyMarked
, pDestDoc
->pTab
[i
], pMarks
);
1512 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
, FALSE
, pDestDoc
, pMarks
);
1513 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1518 void ScDocument::CopyToDocument(const ScRange
& rRange
,
1519 USHORT nFlags
, BOOL bOnlyMarked
, ScDocument
* pDestDoc
,
1520 const ScMarkData
* pMarks
, BOOL bColRowFlags
)
1522 ScRange aNewRange
= rRange
;
1523 aNewRange
.Justify();
1525 if( !pDestDoc
->aDocName
.Len() )
1526 pDestDoc
->aDocName
= aDocName
;
1527 BOOL bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1528 pDestDoc
->SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1529 for (SCTAB i
= aNewRange
.aStart
.Tab(); i
<= aNewRange
.aEnd
.Tab(); i
++)
1530 if (pTab
[i
] && pDestDoc
->pTab
[i
])
1531 pTab
[i
]->CopyToTable(aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
1532 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
1533 nFlags
, bOnlyMarked
, pDestDoc
->pTab
[i
],
1534 pMarks
, FALSE
, bColRowFlags
);
1535 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1539 void ScDocument::UndoToDocument(const ScRange
& rRange
,
1540 USHORT nFlags
, BOOL bOnlyMarked
, ScDocument
* pDestDoc
,
1541 const ScMarkData
* pMarks
)
1543 ScRange aNewRange
= rRange
;
1544 aNewRange
.Justify();
1545 SCTAB nTab1
= aNewRange
.aStart
.Tab();
1546 SCTAB nTab2
= aNewRange
.aEnd
.Tab();
1548 BOOL bOldAutoCalc
= pDestDoc
->GetAutoCalc();
1549 pDestDoc
->SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
1551 CopyToDocument( 0,0,0, MAXCOL
,MAXROW
,nTab1
-1, IDF_FORMULA
, FALSE
, pDestDoc
, pMarks
);
1553 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
1555 if (pTab
[i
] && pDestDoc
->pTab
[i
])
1556 pTab
[i
]->UndoToTable(aNewRange
.aStart
.Col(), aNewRange
.aStart
.Row(),
1557 aNewRange
.aEnd
.Col(), aNewRange
.aEnd
.Row(),
1558 nFlags
, bOnlyMarked
, pDestDoc
->pTab
[i
], pMarks
);
1562 CopyToDocument( 0,0,nTab2
+1, MAXCOL
,MAXROW
,MAXTAB
, IDF_FORMULA
, FALSE
, pDestDoc
, pMarks
);
1563 pDestDoc
->SetAutoCalc( bOldAutoCalc
);
1566 void ScDocument::CopyToClip(const ScClipParam
& rClipParam
,
1567 ScDocument
* pClipDoc
, const ScMarkData
* pMarks
,
1568 bool bAllTabs
, bool bKeepScenarioFlags
, bool bIncludeObjects
, bool bCloneNoteCaptions
)
1570 DBG_ASSERT( bAllTabs
|| pMarks
, "CopyToClip: ScMarkData fehlt" );
1577 DBG_ERROR("CopyToClip: no ClipDoc");
1578 pClipDoc
= SC_MOD()->GetClipDoc();
1581 pClipDoc
->aDocName
= aDocName
;
1582 pClipDoc
->SetClipParam(rClipParam
);
1583 pClipDoc
->ResetClip(this, pMarks
);
1585 ScRange aClipRange
= rClipParam
.getWholeRange();
1586 CopyRangeNamesToClip(pClipDoc
, aClipRange
, pMarks
, bAllTabs
);
1588 for (SCTAB i
= 0; i
<= MAXTAB
; ++i
)
1590 if (!pTab
[i
] || !pClipDoc
->pTab
[i
])
1593 if (pMarks
&& !pMarks
->GetTableSelect(i
))
1596 pTab
[i
]->CopyToClip(rClipParam
.maRanges
, pClipDoc
->pTab
[i
], bKeepScenarioFlags
, bCloneNoteCaptions
);
1598 if (pDrawLayer
&& bIncludeObjects
)
1600 // also copy drawing objects
1601 Rectangle aObjRect
= GetMMRect(
1602 aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(), aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
1603 pDrawLayer
->CopyToClip(pClipDoc
, i
, aObjRect
);
1607 // Make sure to mark overlapped cells.
1608 pClipDoc
->ExtendMerge(aClipRange
, true);
1611 void ScDocument::CopyTabToClip(SCCOL nCol1
, SCROW nRow1
,
1612 SCCOL nCol2
, SCROW nRow2
,
1613 SCTAB nTab
, ScDocument
* pClipDoc
)
1617 PutInOrder( nCol1
, nCol2
);
1618 PutInOrder( nRow1
, nRow2
);
1621 DBG_ERROR("CopyTabToClip: no ClipDoc");
1622 pClipDoc
= SC_MOD()->GetClipDoc();
1625 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
1626 pClipDoc
->aDocName
= aDocName
;
1627 rClipParam
.maRanges
.RemoveAll();
1628 rClipParam
.maRanges
.Append(ScRange(nCol1
, nRow1
, 0, nCol2
, nRow2
, 0));
1629 pClipDoc
->ResetClip( this, nTab
);
1631 if (pTab
[nTab
] && pClipDoc
->pTab
[nTab
])
1632 pTab
[nTab
]->CopyToClip(nCol1
, nRow1
, nCol2
, nRow2
, pClipDoc
->pTab
[nTab
], FALSE
, TRUE
);
1634 pClipDoc
->GetClipParam().mbCutMode
= false;
1639 void ScDocument::TransposeClip( ScDocument
* pTransClip
, USHORT nFlags
, BOOL bAsLink
)
1641 DBG_ASSERT( bIsClip
&& pTransClip
&& pTransClip
->bIsClip
,
1642 "TransposeClip mit falschem Dokument" );
1645 // -> pTransClip muss vor dem Original-Dokument geloescht werden!
1647 pTransClip
->ResetClip(this, (ScMarkData
*)NULL
); // alle
1649 // Bereiche uebernehmen
1651 pTransClip
->pRangeName
->FreeAll();
1652 for (USHORT i
= 0; i
< pRangeName
->GetCount(); i
++) //! DB-Bereiche Pivot-Bereiche auch !!!
1654 USHORT nIndex
= ((ScRangeData
*)((*pRangeName
)[i
]))->GetIndex();
1655 ScRangeData
* pData
= new ScRangeData(*((*pRangeName
)[i
]));
1656 if (!pTransClip
->pRangeName
->Insert(pData
))
1659 pData
->SetIndex(nIndex
);
1664 ScRange aClipRange
= GetClipParam().getWholeRange();
1665 if ( ValidRow(aClipRange
.aEnd
.Row()-aClipRange
.aStart
.Row()) )
1667 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
1670 DBG_ASSERT( pTransClip
->pTab
[i
], "TransposeClip: Tabelle nicht da" );
1671 pTab
[i
]->TransposeClip( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
1672 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(),
1673 pTransClip
->pTab
[i
], nFlags
, bAsLink
);
1675 if ( pDrawLayer
&& ( nFlags
& IDF_OBJECTS
) )
1677 // Drawing objects are copied to the new area without transposing.
1678 // CopyFromClip is used to adjust the objects to the transposed block's
1680 // (pDrawLayer in the original clipboard document is set only if there
1681 // are drawing objects to copy)
1683 pTransClip
->InitDrawLayer();
1684 Rectangle aSourceRect
= GetMMRect( aClipRange
.aStart
.Col(), aClipRange
.aStart
.Row(),
1685 aClipRange
.aEnd
.Col(), aClipRange
.aEnd
.Row(), i
);
1686 Rectangle aDestRect
= pTransClip
->GetMMRect( 0, 0,
1687 static_cast<SCCOL
>(aClipRange
.aEnd
.Row() - aClipRange
.aStart
.Row()),
1688 static_cast<SCROW
>(aClipRange
.aEnd
.Col() - aClipRange
.aStart
.Col()), i
);
1689 pTransClip
->pDrawLayer
->CopyFromClip( pDrawLayer
, i
, aSourceRect
, ScAddress(0,0,i
), aDestRect
);
1693 pTransClip
->SetClipParam(GetClipParam());
1694 pTransClip
->GetClipParam().transpose();
1698 DBG_ERROR("TransposeClip: zu gross");
1701 // Dies passiert erst beim Einfuegen...
1703 GetClipParam().mbCutMode
= false;
1706 void ScDocument::CopyRangeNamesToClip(ScDocument
* pClipDoc
, const ScRange
& rClipRange
, const ScMarkData
* pMarks
, bool bAllTabs
)
1708 std::set
<USHORT
> aUsedNames
; // indexes of named ranges that are used in the copied cells
1709 for (SCTAB i
= 0; i
<= MAXTAB
; ++i
)
1710 if (pTab
[i
] && pClipDoc
->pTab
[i
])
1711 if ( bAllTabs
|| !pMarks
|| pMarks
->GetTableSelect(i
) )
1712 pTab
[i
]->FindRangeNamesInUse(
1713 rClipRange
.aStart
.Col(), rClipRange
.aStart
.Row(),
1714 rClipRange
.aEnd
.Col(), rClipRange
.aEnd
.Row(), aUsedNames
);
1716 pClipDoc
->pRangeName
->FreeAll();
1717 for (USHORT i
= 0; i
< pRangeName
->GetCount(); i
++) //! DB-Bereiche Pivot-Bereiche auch !!!
1719 USHORT nIndex
= ((ScRangeData
*)((*pRangeName
)[i
]))->GetIndex();
1720 bool bInUse
= ( aUsedNames
.find(nIndex
) != aUsedNames
.end() );
1723 ScRangeData
* pData
= new ScRangeData(*((*pRangeName
)[i
]));
1724 if (!pClipDoc
->pRangeName
->Insert(pData
))
1727 pData
->SetIndex(nIndex
);
1732 ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument
* pDoc
, ScDocument
* pSrcDoc
) :
1735 mpDoc
->MergeNumberFormatter(pSrcDoc
);
1738 ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
1740 mpDoc
->pFormatExchangeList
= NULL
;
1743 void ScDocument::MergeNumberFormatter(ScDocument
* pSrcDoc
)
1745 SvNumberFormatter
* pThisFormatter
= xPoolHelper
->GetFormTable();
1746 SvNumberFormatter
* pOtherFormatter
= pSrcDoc
->xPoolHelper
->GetFormTable();
1747 if (pOtherFormatter
&& pOtherFormatter
!= pThisFormatter
)
1749 SvNumberFormatterIndexTable
* pExchangeList
=
1750 pThisFormatter
->MergeFormatter(*(pOtherFormatter
));
1751 if (pExchangeList
->Count() > 0)
1752 pFormatExchangeList
= pExchangeList
;
1756 void ScDocument::CopyRangeNamesFromClip(ScDocument
* pClipDoc
, ScClipRangeNameData
& rRangeNames
)
1758 sal_uInt16 nClipRangeNameCount
= pClipDoc
->pRangeName
->GetCount();
1759 ScClipRangeNameData aClipRangeNames
;
1761 // array containing range names which might need update of indices
1762 aClipRangeNames
.mpRangeNames
.resize(nClipRangeNameCount
, NULL
);
1764 for (sal_uInt16 i
= 0; i
< nClipRangeNameCount
; ++i
) //! DB-Bereiche Pivot-Bereiche auch
1766 /* Copy only if the name doesn't exist in this document.
1767 If it exists we use the already existing name instead,
1768 another possibility could be to create new names if
1770 A proper solution would ask the user how to proceed.
1771 The adjustment of the indices in the formulas is done later.
1773 ScRangeData
* pClipRangeData
= (*pClipDoc
->pRangeName
)[i
];
1775 if ( pRangeName
->SearchName( pClipRangeData
->GetName(), k
) )
1777 aClipRangeNames
.mpRangeNames
[i
] = NULL
; // range name not inserted
1778 USHORT nOldIndex
= pClipRangeData
->GetIndex();
1779 USHORT nNewIndex
= ((*pRangeName
)[k
])->GetIndex();
1780 aClipRangeNames
.insert(nOldIndex
, nNewIndex
);
1781 if ( !aClipRangeNames
.mbReplace
)
1782 aClipRangeNames
.mbReplace
= ( nOldIndex
!= nNewIndex
);
1786 ScRangeData
* pData
= new ScRangeData( *pClipRangeData
);
1787 pData
->SetDocument(this);
1788 if ( pRangeName
->FindIndex( pData
->GetIndex() ) )
1789 pData
->SetIndex(0); // need new index, done in Insert
1790 if ( pRangeName
->Insert( pData
) )
1792 aClipRangeNames
.mpRangeNames
[i
] = pData
;
1793 USHORT nOldIndex
= pClipRangeData
->GetIndex();
1794 USHORT nNewIndex
= pData
->GetIndex();
1795 aClipRangeNames
.insert(nOldIndex
, nNewIndex
);
1796 if ( !aClipRangeNames
.mbReplace
)
1797 aClipRangeNames
.mbReplace
= ( nOldIndex
!= nNewIndex
);
1800 { // must be an overflow
1802 aClipRangeNames
.mpRangeNames
[i
] = NULL
;
1803 aClipRangeNames
.insert(pClipRangeData
->GetIndex(), 0);
1804 aClipRangeNames
.mbReplace
= true;
1808 rRangeNames
= aClipRangeNames
;
1811 void ScDocument::UpdateRangeNamesInFormulas(
1812 ScClipRangeNameData
& rRangeNames
, const ScRangeList
& rDestRanges
, const ScMarkData
& rMark
,
1813 SCCOL nXw
, SCROW nYw
)
1815 // nXw and nYw are the extra width and height of the destination range
1816 // extended due to presence of merged cell(s).
1818 if (!rRangeNames
.mbReplace
)
1821 // first update all inserted named formulas if they contain other
1822 // range names and used indices changed
1823 size_t nRangeNameCount
= rRangeNames
.mpRangeNames
.size();
1824 for (size_t i
= 0; i
< nRangeNameCount
; ++i
) //! DB-Bereiche Pivot-Bereiche auch
1826 if ( rRangeNames
.mpRangeNames
[i
] )
1827 rRangeNames
.mpRangeNames
[i
]->ReplaceRangeNamesInUse(rRangeNames
.maRangeMap
);
1829 // then update the formulas, they might need just the updated range names
1830 for (ULONG nRange
= 0; nRange
< rDestRanges
.Count(); ++nRange
)
1832 const ScRange
* pRange
= rDestRanges
.GetObject( nRange
);
1833 SCCOL nCol1
= pRange
->aStart
.Col();
1834 SCROW nRow1
= pRange
->aStart
.Row();
1835 SCCOL nCol2
= pRange
->aEnd
.Col();
1836 SCROW nRow2
= pRange
->aEnd
.Row();
1840 SCCOL nC2
= nC1
+ nXw
;
1843 SCROW nR2
= nR1
+ nYw
;
1850 for (SCTAB k
= 0; k
<= MAXTAB
; k
++)
1852 if ( pTab
[k
] && rMark
.GetTableSelect(k
) )
1853 pTab
[k
]->ReplaceRangeNamesInUse(nC1
, nR1
,
1854 nC2
, nR2
, rRangeNames
.maRangeMap
);
1857 nC2
= Min((SCCOL
)(nC1
+ nXw
), nCol2
);
1858 } while (nC1
<= nCol2
);
1864 nR2
= Min((SCROW
)(nR1
+ nYw
), nRow2
);
1865 } while (nR1
<= nRow2
);
1869 ScClipParam
& ScDocument::GetClipParam()
1871 if (!mpClipParam
.get())
1872 mpClipParam
.reset(new ScClipParam
);
1874 return *mpClipParam
;
1877 void ScDocument::SetClipParam(const ScClipParam
& rParam
)
1879 mpClipParam
.reset(new ScClipParam(rParam
));
1882 BOOL
ScDocument::IsClipboardSource() const
1884 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
1885 return pClipDoc
&& pClipDoc
->xPoolHelper
.isValid() &&
1886 xPoolHelper
->GetDocPool() == pClipDoc
->xPoolHelper
->GetDocPool();
1890 void ScDocument::StartListeningFromClip( SCCOL nCol1
, SCROW nRow1
,
1891 SCCOL nCol2
, SCROW nRow2
,
1892 const ScMarkData
& rMark
, USHORT nInsFlag
)
1894 if (nInsFlag
& IDF_CONTENTS
)
1896 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
1898 if (rMark
.GetTableSelect(i
))
1899 pTab
[i
]->StartListeningInArea( nCol1
, nRow1
, nCol2
, nRow2
);
1904 void ScDocument::BroadcastFromClip( SCCOL nCol1
, SCROW nRow1
,
1905 SCCOL nCol2
, SCROW nRow2
,
1906 const ScMarkData
& rMark
, USHORT nInsFlag
)
1908 if (nInsFlag
& IDF_CONTENTS
)
1910 ScBulkBroadcast
aBulkBroadcast( GetBASM());
1911 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
1913 if (rMark
.GetTableSelect(i
))
1914 pTab
[i
]->BroadcastInArea( nCol1
, nRow1
, nCol2
, nRow2
);
1919 void ScDocument::CopyBlockFromClip( SCCOL nCol1
, SCROW nRow1
,
1920 SCCOL nCol2
, SCROW nRow2
,
1921 const ScMarkData
& rMark
,
1922 SCsCOL nDx
, SCsROW nDy
,
1923 const ScCopyBlockFromClipParams
* pCBFCP
)
1925 ScTable
** ppClipTab
= pCBFCP
->pClipDoc
->pTab
;
1926 SCTAB nTabEnd
= pCBFCP
->nTabEnd
;
1928 for (SCTAB i
= pCBFCP
->nTabStart
; i
<= nTabEnd
; i
++)
1930 if (pTab
[i
] && rMark
.GetTableSelect(i
) )
1932 while (!ppClipTab
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1934 pTab
[i
]->CopyFromClip( nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
,
1935 pCBFCP
->nInsFlag
, pCBFCP
->bAsLink
, pCBFCP
->bSkipAttrForEmpty
, ppClipTab
[nClipTab
] );
1937 if ( pCBFCP
->pClipDoc
->pDrawLayer
&& ( pCBFCP
->nInsFlag
& IDF_OBJECTS
) )
1939 // also copy drawing objects
1941 // drawing layer must be created before calling CopyFromClip
1942 // (ScDocShell::MakeDrawLayer also does InitItems etc.)
1943 DBG_ASSERT( pDrawLayer
, "CopyBlockFromClip: No drawing layer" );
1946 // For GetMMRect, the row heights in the target document must already be valid
1947 // (copied in an extra step before pasting, or updated after pasting cells, but
1948 // before pasting objects).
1950 Rectangle aSourceRect
= pCBFCP
->pClipDoc
->GetMMRect(
1951 nCol1
-nDx
, nRow1
-nDy
, nCol2
-nDx
, nRow2
-nDy
, nClipTab
);
1952 Rectangle aDestRect
= GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, i
);
1953 pDrawLayer
->CopyFromClip( pCBFCP
->pClipDoc
->pDrawLayer
, nClipTab
, aSourceRect
,
1954 ScAddress( nCol1
, nRow1
, i
), aDestRect
);
1958 nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1961 if ( pCBFCP
->nInsFlag
& IDF_CONTENTS
)
1964 for (SCTAB i
= pCBFCP
->nTabStart
; i
<= nTabEnd
; i
++)
1966 if (pTab
[i
] && rMark
.GetTableSelect(i
) )
1968 while (!ppClipTab
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1969 SCsTAB nDz
= ((SCsTAB
)i
) - nClipTab
;
1971 // #89081# ranges of consecutive selected tables (in clipboard and dest. doc)
1972 // must be handled in one UpdateReference call
1974 while ( i
+ nFollow
< nTabEnd
1975 && rMark
.GetTableSelect( i
+ nFollow
+ 1 )
1976 && nClipTab
+ nFollow
< MAXTAB
1977 && ppClipTab
[nClipTab
+ nFollow
+ 1] )
1980 if ( pCBFCP
->pClipDoc
->GetClipParam().mbCutMode
)
1982 BOOL bOldInserting
= IsInsertingFromOtherDoc();
1983 SetInsertingFromOtherDoc( TRUE
);
1984 UpdateReference( URM_MOVE
,
1985 nCol1
, nRow1
, i
, nCol2
, nRow2
, i
+nFollow
,
1986 nDx
, nDy
, nDz
, pCBFCP
->pRefUndoDoc
);
1987 SetInsertingFromOtherDoc( bOldInserting
);
1990 UpdateReference( URM_COPY
,
1991 nCol1
, nRow1
, i
, nCol2
, nRow2
, i
+nFollow
,
1992 nDx
, nDy
, nDz
, pCBFCP
->pRefUndoDoc
, FALSE
);
1994 nClipTab
= (nClipTab
+nFollow
+1) % (MAXTAB
+1);
1995 i
= sal::static_int_cast
<SCTAB
>( i
+ nFollow
);
2002 void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1
, SCROW nRow1
,
2003 SCCOL nCol2
, SCROW nRow2
,
2004 const ScMarkData
& rMark
,
2005 SCsCOL nDx
, SCsROW
/* nDy */,
2006 const ScCopyBlockFromClipParams
* pCBFCP
,
2007 SCROW
& rClipStartRow
)
2009 // call CopyBlockFromClip for ranges of consecutive non-filtered rows
2010 // nCol1/nRow1 etc. is in target doc
2012 // filtered state is taken from first used table in clipboard (as in GetClipArea)
2014 ScTable
** ppClipTab
= pCBFCP
->pClipDoc
->pTab
;
2015 while ( nFlagTab
< MAXTAB
&& !ppClipTab
[nFlagTab
] )
2018 SCROW nSourceRow
= rClipStartRow
;
2019 SCROW nSourceEnd
= 0;
2020 if (pCBFCP
->pClipDoc
->GetClipParam().maRanges
.Count())
2021 nSourceEnd
= pCBFCP
->pClipDoc
->GetClipParam().maRanges
.First()->aEnd
.Row();
2022 SCROW nDestRow
= nRow1
;
2024 while ( nSourceRow
<= nSourceEnd
&& nDestRow
<= nRow2
)
2026 // skip filtered rows
2027 nSourceRow
= pCBFCP
->pClipDoc
->FirstNonFilteredRow(nSourceRow
, nSourceEnd
, nFlagTab
);
2029 if ( nSourceRow
<= nSourceEnd
)
2031 // look for more non-filtered rows following
2032 SCROW nLastRow
= nSourceRow
;
2033 pCBFCP
->pClipDoc
->RowFiltered(nSourceRow
, nFlagTab
, NULL
, &nLastRow
);
2034 SCROW nFollow
= nLastRow
- nSourceRow
;
2036 if (nFollow
> nSourceEnd
- nSourceRow
)
2037 nFollow
= nSourceEnd
- nSourceRow
;
2038 if (nFollow
> nRow2
- nDestRow
)
2039 nFollow
= nRow2
- nDestRow
;
2041 SCsROW nNewDy
= ((SCsROW
)nDestRow
) - nSourceRow
;
2042 CopyBlockFromClip( nCol1
, nDestRow
, nCol2
, nDestRow
+ nFollow
, rMark
, nDx
, nNewDy
, pCBFCP
);
2044 nSourceRow
+= nFollow
+ 1;
2045 nDestRow
+= nFollow
+ 1;
2048 rClipStartRow
= nSourceRow
;
2052 void ScDocument::CopyFromClip( const ScRange
& rDestRange
, const ScMarkData
& rMark
,
2054 ScDocument
* pRefUndoDoc
, ScDocument
* pClipDoc
, BOOL bResetCut
,
2055 BOOL bAsLink
, BOOL bIncludeFiltered
, BOOL bSkipAttrForEmpty
,
2056 const ScRangeList
* pDestRanges
)
2062 DBG_ERROR("CopyFromClip: no ClipDoc");
2063 pClipDoc
= SC_MOD()->GetClipDoc();
2065 if (pClipDoc
->bIsClip
&& pClipDoc
->GetTableCount())
2067 BOOL bOldAutoCalc
= GetAutoCalc();
2068 SetAutoCalc( FALSE
); // avoid multiple recalculations
2070 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2072 ScClipRangeNameData aClipRangeNames
;
2073 CopyRangeNamesFromClip(pClipDoc
, aClipRangeNames
);
2075 SCCOL nAllCol1
= rDestRange
.aStart
.Col();
2076 SCROW nAllRow1
= rDestRange
.aStart
.Row();
2077 SCCOL nAllCol2
= rDestRange
.aEnd
.Col();
2078 SCROW nAllRow2
= rDestRange
.aEnd
.Row();
2082 ScRange aClipRange
= pClipDoc
->GetClipParam().getWholeRange();
2083 for (SCTAB nTab
= 0; nTab
<= MAXTAB
; nTab
++) // find largest merge overlap
2084 if (pClipDoc
->pTab
[nTab
]) // all sheets of the clipboard content
2086 SCCOL nThisEndX
= aClipRange
.aEnd
.Col();
2087 SCROW nThisEndY
= aClipRange
.aEnd
.Row();
2088 pClipDoc
->ExtendMerge( aClipRange
.aStart
.Col(),
2089 aClipRange
.aStart
.Row(),
2090 nThisEndX
, nThisEndY
, nTab
);
2091 // only extra value from ExtendMerge
2092 nThisEndX
= sal::static_int_cast
<SCCOL
>( nThisEndX
- aClipRange
.aEnd
.Col() );
2093 nThisEndY
= sal::static_int_cast
<SCROW
>( nThisEndY
- aClipRange
.aEnd
.Row() );
2094 if ( nThisEndX
> nXw
)
2096 if ( nThisEndY
> nYw
)
2102 pClipDoc
->GetClipArea( nDestAddX
, nDestAddY
, bIncludeFiltered
);
2103 nXw
= sal::static_int_cast
<SCCOL
>( nXw
+ nDestAddX
);
2104 nYw
= sal::static_int_cast
<SCROW
>( nYw
+ nDestAddY
); // ClipArea, plus ExtendMerge value
2106 /* Decide which contents to delete before copying. Delete all
2107 contents if nInsFlag contains any real content flag.
2108 #i102056# Notes are pasted from clipboard in a second pass,
2109 together with the special flag IDF_ADDNOTES that states to not
2110 overwrite/delete existing cells but to insert the notes into
2111 these cells. In this case, just delete old notes from the
2112 destination area. */
2113 USHORT nDelFlag
= IDF_NONE
;
2114 if ( (nInsFlag
& (IDF_CONTENTS
| IDF_ADDNOTES
)) == (IDF_NOTE
| IDF_ADDNOTES
) )
2115 nDelFlag
|= IDF_NOTE
;
2116 else if ( nInsFlag
& IDF_CONTENTS
)
2117 nDelFlag
|= IDF_CONTENTS
;
2118 // With bSkipAttrForEmpty, don't remove attributes, copy
2119 // on top of existing attributes instead.
2120 if ( ( nInsFlag
& IDF_ATTRIB
) && !bSkipAttrForEmpty
)
2121 nDelFlag
|= IDF_ATTRIB
;
2123 ScCopyBlockFromClipParams aCBFCP
;
2124 aCBFCP
.pRefUndoDoc
= pRefUndoDoc
;
2125 aCBFCP
.pClipDoc
= pClipDoc
;
2126 aCBFCP
.nInsFlag
= nInsFlag
;
2127 aCBFCP
.bAsLink
= bAsLink
;
2128 aCBFCP
.bSkipAttrForEmpty
= bSkipAttrForEmpty
;
2129 aCBFCP
.nTabStart
= MAXTAB
; // wird in der Schleife angepasst
2130 aCBFCP
.nTabEnd
= 0; // wird in der Schleife angepasst
2132 // Inc/DecRecalcLevel einmal aussen, damit nicht fuer jeden Block
2133 // die Draw-Seitengroesse neu berechnet werden muss
2134 //! nur wenn ganze Zeilen/Spalten kopiert werden?
2136 for (SCTAB j
= 0; j
<= MAXTAB
; j
++)
2137 if (pTab
[j
] && rMark
.GetTableSelect(j
))
2139 if ( j
< aCBFCP
.nTabStart
)
2140 aCBFCP
.nTabStart
= j
;
2142 pTab
[j
]->IncRecalcLevel();
2145 ScRangeList aLocalRangeList
;
2148 aLocalRangeList
.Append( rDestRange
);
2149 pDestRanges
= &aLocalRangeList
;
2152 bInsertingFromOtherDoc
= TRUE
; // kein Broadcast/Listener aufbauen bei Insert
2154 // bei mindestens 64 Zeilen wird in ScColumn::CopyFromClip voralloziert
2155 BOOL bDoDouble
= ( nYw
< 64 && nAllRow2
- nAllRow1
> 64);
2156 BOOL bOldDouble
= ScColumn::bDoubleAlloc
;
2158 ScColumn::bDoubleAlloc
= TRUE
;
2160 SCCOL nClipStartCol
= aClipRange
.aStart
.Col();
2161 SCROW nClipStartRow
= aClipRange
.aStart
.Row();
2162 // WaE: commented because unused: SCCOL nClipEndCol = pClipDoc->aClipRange.aEnd.Col();
2163 SCROW nClipEndRow
= aClipRange
.aEnd
.Row();
2164 for (ULONG nRange
= 0; nRange
< pDestRanges
->Count(); ++nRange
)
2166 const ScRange
* pRange
= pDestRanges
->GetObject( nRange
);
2167 SCCOL nCol1
= pRange
->aStart
.Col();
2168 SCROW nRow1
= pRange
->aStart
.Row();
2169 SCCOL nCol2
= pRange
->aEnd
.Col();
2170 SCROW nRow2
= pRange
->aEnd
.Row();
2172 DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
, rMark
, nDelFlag
);
2176 SCCOL nC2
= nC1
+ nXw
;
2179 SCROW nR2
= nR1
+ nYw
;
2185 // Pasting is done column-wise, when pasting to a filtered
2186 // area this results in partitioning and we have to
2187 // remember and reset the start row for each column until
2188 // it can be advanced for the next chunk of unfiltered
2190 SCROW nSaveClipStartRow
= nClipStartRow
;
2193 nClipStartRow
= nSaveClipStartRow
;
2194 SCsCOL nDx
= ((SCsCOL
)nC1
) - nClipStartCol
;
2195 SCsROW nDy
= ((SCsROW
)nR1
) - nClipStartRow
;
2196 if ( bIncludeFiltered
)
2198 CopyBlockFromClip( nC1
, nR1
, nC2
, nR2
, rMark
, nDx
,
2200 nClipStartRow
+= nR2
- nR1
+ 1;
2204 CopyNonFilteredFromClip( nC1
, nR1
, nC2
, nR2
, rMark
,
2205 nDx
, nDy
, &aCBFCP
, nClipStartRow
);
2207 // Not needed for columns, but if it was this would be how to.
2208 //if (nClipStartCol > nClipEndCol)
2209 // nClipStartCol = pClipDoc->aClipRange.aStart.Col();
2211 nC2
= Min((SCCOL
)(nC1
+ nXw
), nCol2
);
2212 } while (nC1
<= nCol2
);
2213 if (nClipStartRow
> nClipEndRow
)
2214 nClipStartRow
= aClipRange
.aStart
.Row();
2220 nR2
= Min((SCROW
)(nR1
+ nYw
), nRow2
);
2221 } while (nR1
<= nRow2
);
2224 ScColumn::bDoubleAlloc
= bOldDouble
;
2226 for (SCTAB k
= 0; k
<= MAXTAB
; k
++)
2227 if (pTab
[k
] && rMark
.GetTableSelect(k
))
2228 pTab
[k
]->DecRecalcLevel();
2230 bInsertingFromOtherDoc
= FALSE
;
2232 UpdateRangeNamesInFormulas(aClipRangeNames
, *pDestRanges
, rMark
, nXw
, nYw
);
2234 // Listener aufbauen nachdem alles inserted wurde
2235 StartListeningFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2236 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2237 BroadcastFromClip( nAllCol1
, nAllRow1
, nAllCol2
, nAllRow2
, rMark
, nInsFlag
);
2239 pClipDoc
->GetClipParam().mbCutMode
= false;
2240 SetAutoCalc( bOldAutoCalc
);
2245 static SCROW
lcl_getLastNonFilteredRow(
2246 const ScBitMaskCompressedArray
<SCROW
, BYTE
>& rFlags
, SCROW nBegRow
, SCROW nEndRow
,
2249 SCROW nFilteredRow
= rFlags
.GetFirstForCondition(
2250 nBegRow
, nEndRow
, CR_FILTERED
, CR_FILTERED
);
2252 SCROW nRow
= nFilteredRow
- 1;
2253 if (nRow
- nBegRow
+ 1 > nRowCount
)
2254 // make sure the row range stays within the data size.
2255 nRow
= nBegRow
+ nRowCount
- 1;
2260 void ScDocument::CopyMultiRangeFromClip(
2261 const ScAddress
& rDestPos
, const ScMarkData
& rMark
, sal_uInt16 nInsFlag
, ScDocument
* pClipDoc
,
2262 bool bResetCut
, bool bAsLink
, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty
)
2267 if (!pClipDoc
->bIsClip
|| !pClipDoc
->GetTableCount())
2268 // There is nothing in the clip doc to copy.
2271 BOOL bOldAutoCalc
= GetAutoCalc();
2272 SetAutoCalc( FALSE
); // avoid multiple recalculations
2274 NumFmtMergeHandler
aNumFmtMergeHdl(this, pClipDoc
);
2276 ScClipRangeNameData aClipRangeNames
;
2277 CopyRangeNamesFromClip(pClipDoc
, aClipRangeNames
);
2279 SCCOL nCol1
= rDestPos
.Col();
2280 SCROW nRow1
= rDestPos
.Row();
2281 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
2283 ScCopyBlockFromClipParams aCBFCP
;
2284 aCBFCP
.pRefUndoDoc
= NULL
;
2285 aCBFCP
.pClipDoc
= pClipDoc
;
2286 aCBFCP
.nInsFlag
= nInsFlag
;
2287 aCBFCP
.bAsLink
= bAsLink
;
2288 aCBFCP
.bSkipAttrForEmpty
= bSkipAttrForEmpty
;
2289 aCBFCP
.nTabStart
= MAXTAB
;
2292 for (SCTAB j
= 0; j
<= MAXTAB
; ++j
)
2294 if (pTab
[j
] && rMark
.GetTableSelect(j
))
2296 if ( j
< aCBFCP
.nTabStart
)
2297 aCBFCP
.nTabStart
= j
;
2299 pTab
[j
]->IncRecalcLevel();
2304 rMark
.GetMarkArea(aDestRange
);
2305 SCROW nLastMarkedRow
= aDestRange
.aEnd
.Row();
2307 bInsertingFromOtherDoc
= TRUE
; // kein Broadcast/Listener aufbauen bei Insert
2309 SCROW nBegRow
= nRow1
;
2310 sal_uInt16 nDelFlag
= IDF_CONTENTS
;
2311 const ScBitMaskCompressedArray
<SCROW
, BYTE
>& rFlags
= GetRowFlagsArray(aCBFCP
.nTabStart
);
2313 for (ScRange
* p
= rClipParam
.maRanges
.First(); p
; p
= rClipParam
.maRanges
.Next())
2315 // The begin row must not be filtered.
2317 SCROW nRowCount
= p
->aEnd
.Row() - p
->aStart
.Row() + 1;
2319 SCsCOL nDx
= static_cast<SCsCOL
>(nCol1
- p
->aStart
.Col());
2320 SCsROW nDy
= static_cast<SCsROW
>(nBegRow
- p
->aStart
.Row());
2321 SCCOL nCol2
= nCol1
+ p
->aEnd
.Col() - p
->aStart
.Col();
2323 SCROW nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2325 if (!bSkipAttrForEmpty
)
2326 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2328 CopyBlockFromClip(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
, &aCBFCP
);
2329 nRowCount
-= nEndRow
- nBegRow
+ 1;
2331 while (nRowCount
> 0)
2333 // Get the first non-filtered row.
2334 SCROW nNonFilteredRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2335 if (nNonFilteredRow
> nLastMarkedRow
)
2338 SCROW nRowsSkipped
= nNonFilteredRow
- nEndRow
- 1;
2339 nDy
+= nRowsSkipped
;
2341 nBegRow
= nNonFilteredRow
;
2342 nEndRow
= lcl_getLastNonFilteredRow(rFlags
, nBegRow
, nLastMarkedRow
, nRowCount
);
2344 if (!bSkipAttrForEmpty
)
2345 DeleteArea(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDelFlag
);
2347 CopyBlockFromClip(nCol1
, nBegRow
, nCol2
, nEndRow
, rMark
, nDx
, nDy
, &aCBFCP
);
2348 nRowCount
-= nEndRow
- nBegRow
+ 1;
2351 if (rClipParam
.meDirection
== ScClipParam::Row
)
2352 // Begin row for the next range being pasted.
2353 nBegRow
= rFlags
.GetFirstForCondition(nEndRow
+1, nLastMarkedRow
, CR_FILTERED
, 0);
2357 if (rClipParam
.meDirection
== ScClipParam::Column
)
2358 nCol1
+= p
->aEnd
.Col() - p
->aStart
.Col() + 1;
2361 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
2362 if (pTab
[i
] && rMark
.GetTableSelect(i
))
2363 pTab
[i
]->DecRecalcLevel();
2365 bInsertingFromOtherDoc
= FALSE
;
2367 ScRangeList aRanges
;
2368 aRanges
.Append(aDestRange
);
2369 SCCOL nCols
= aDestRange
.aEnd
.Col() - aDestRange
.aStart
.Col() + 1;
2370 SCROW nRows
= aDestRange
.aEnd
.Row() - aDestRange
.aStart
.Row() + 1;
2371 UpdateRangeNamesInFormulas(aClipRangeNames
, aRanges
, rMark
, nCols
-1, nRows
-1);
2373 // Listener aufbauen nachdem alles inserted wurde
2374 StartListeningFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2375 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2376 // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
2377 BroadcastFromClip(aDestRange
.aStart
.Col(), aDestRange
.aStart
.Row(),
2378 aDestRange
.aEnd
.Col(), aDestRange
.aEnd
.Row(), rMark
, nInsFlag
);
2381 pClipDoc
->GetClipParam().mbCutMode
= false;
2382 SetAutoCalc( bOldAutoCalc
);
2385 void ScDocument::SetClipArea( const ScRange
& rArea
, BOOL bCut
)
2389 ScClipParam
& rClipParam
= GetClipParam();
2390 rClipParam
.maRanges
.RemoveAll();
2391 rClipParam
.maRanges
.Append(rArea
);
2392 rClipParam
.mbCutMode
= bCut
;
2396 DBG_ERROR("SetClipArea: kein Clip");
2401 void ScDocument::GetClipArea(SCCOL
& nClipX
, SCROW
& nClipY
, BOOL bIncludeFiltered
)
2405 DBG_ERROR("GetClipArea: kein Clip");
2409 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2410 if (!rClipRanges
.Count())
2411 // No clip range. Bail out.
2414 ScRangePtr p
= rClipRanges
.First();
2415 SCCOL nStartCol
= p
->aStart
.Col();
2416 SCCOL nEndCol
= p
->aEnd
.Col();
2417 SCROW nStartRow
= p
->aStart
.Row();
2418 SCROW nEndRow
= p
->aEnd
.Row();
2419 for (p
= rClipRanges
.Next(); p
; p
= rClipRanges
.Next())
2421 if (p
->aStart
.Col() < nStartCol
)
2422 nStartCol
= p
->aStart
.Col();
2423 if (p
->aStart
.Row() < nStartRow
)
2424 nStartRow
= p
->aStart
.Row();
2425 if (p
->aEnd
.Col() > nEndCol
)
2426 nEndCol
= p
->aEnd
.Col();
2427 if (p
->aEnd
.Row() < nEndRow
)
2428 nEndRow
= p
->aEnd
.Row();
2431 nClipX
= nEndCol
- nStartCol
;
2433 if ( bIncludeFiltered
)
2434 nClipY
= nEndRow
- nStartRow
;
2437 // count non-filtered rows
2438 // count on first used table in clipboard
2439 SCTAB nCountTab
= 0;
2440 while ( nCountTab
< MAXTAB
&& !pTab
[nCountTab
] )
2443 SCROW nResult
= CountNonFilteredRows(nStartRow
, nEndRow
, nCountTab
);
2446 nClipY
= nResult
- 1;
2448 nClipY
= 0; // always return at least 1 row
2453 void ScDocument::GetClipStart(SCCOL
& nClipX
, SCROW
& nClipY
)
2457 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2458 if (rClipRanges
.Count())
2460 nClipX
= rClipRanges
.First()->aStart
.Col();
2461 nClipY
= rClipRanges
.First()->aStart
.Row();
2466 DBG_ERROR("GetClipStart: kein Clip");
2471 BOOL
ScDocument::HasClipFilteredRows()
2473 // count on first used table in clipboard
2474 SCTAB nCountTab
= 0;
2475 while ( nCountTab
< MAXTAB
&& !pTab
[nCountTab
] )
2478 ScRangeList
& rClipRanges
= GetClipParam().maRanges
;
2479 if (!rClipRanges
.Count())
2482 for (ScRange
* p
= rClipRanges
.First(); p
; p
= rClipRanges
.Next())
2484 bool bAnswer
= pTab
[nCountTab
]->HasFilteredRows(p
->aStart
.Row(), p
->aEnd
.Row());
2492 void ScDocument::MixDocument( const ScRange
& rRange
, USHORT nFunction
, BOOL bSkipEmpty
,
2493 ScDocument
* pSrcDoc
)
2495 SCTAB nTab1
= rRange
.aStart
.Tab();
2496 SCTAB nTab2
= rRange
.aEnd
.Tab();
2497 for (SCTAB i
= nTab1
; i
<= nTab2
; i
++)
2498 if (pTab
[i
] && pSrcDoc
->pTab
[i
])
2499 pTab
[i
]->MixData( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
2500 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
2501 nFunction
, bSkipEmpty
, pSrcDoc
->pTab
[i
] );
2505 void ScDocument::FillTab( const ScRange
& rSrcArea
, const ScMarkData
& rMark
,
2506 USHORT nFlags
, USHORT nFunction
,
2507 BOOL bSkipEmpty
, BOOL bAsLink
)
2509 USHORT nDelFlags
= nFlags
;
2510 if (nDelFlags
& IDF_CONTENTS
)
2511 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
2513 SCTAB nSrcTab
= rSrcArea
.aStart
.Tab();
2515 if (ValidTab(nSrcTab
) && pTab
[nSrcTab
])
2517 SCCOL nStartCol
= rSrcArea
.aStart
.Col();
2518 SCROW nStartRow
= rSrcArea
.aStart
.Row();
2519 SCCOL nEndCol
= rSrcArea
.aEnd
.Col();
2520 SCROW nEndRow
= rSrcArea
.aEnd
.Row();
2521 ScDocument
* pMixDoc
= NULL
;
2522 BOOL bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
2524 BOOL bOldAutoCalc
= GetAutoCalc();
2525 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
2527 SCTAB nCount
= GetTableCount();
2528 for (SCTAB i
=0; i
<nCount
; i
++)
2529 if ( i
!=nSrcTab
&& pTab
[i
] && rMark
.GetTableSelect(i
) )
2535 pMixDoc
= new ScDocument( SCDOCMODE_UNDO
);
2536 pMixDoc
->InitUndo( this, i
, i
);
2539 pMixDoc
->AddUndoTab( i
, i
);
2540 pTab
[i
]->CopyToTable( nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2541 IDF_CONTENTS
, FALSE
, pMixDoc
->pTab
[i
] );
2543 pTab
[i
]->DeleteArea( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nDelFlags
);
2544 pTab
[nSrcTab
]->CopyToTable( nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2545 nFlags
, FALSE
, pTab
[i
], NULL
, bAsLink
);
2548 pTab
[i
]->MixData( nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2549 nFunction
, bSkipEmpty
, pMixDoc
->pTab
[i
] );
2554 SetAutoCalc( bOldAutoCalc
);
2558 DBG_ERROR("falsche Tabelle");
2563 void ScDocument::FillTabMarked( SCTAB nSrcTab
, const ScMarkData
& rMark
,
2564 USHORT nFlags
, USHORT nFunction
,
2565 BOOL bSkipEmpty
, BOOL bAsLink
)
2567 USHORT nDelFlags
= nFlags
;
2568 if (nDelFlags
& IDF_CONTENTS
)
2569 nDelFlags
|= IDF_CONTENTS
; // immer alle Inhalte oder keine loeschen!
2571 if (ValidTab(nSrcTab
) && pTab
[nSrcTab
])
2573 ScDocument
* pMixDoc
= NULL
;
2574 BOOL bDoMix
= ( bSkipEmpty
|| nFunction
) && ( nFlags
& IDF_CONTENTS
);
2576 BOOL bOldAutoCalc
= GetAutoCalc();
2577 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
2580 rMark
.GetMultiMarkArea( aArea
);
2581 SCCOL nStartCol
= aArea
.aStart
.Col();
2582 SCROW nStartRow
= aArea
.aStart
.Row();
2583 SCCOL nEndCol
= aArea
.aEnd
.Col();
2584 SCROW nEndRow
= aArea
.aEnd
.Row();
2586 SCTAB nCount
= GetTableCount();
2587 for (SCTAB i
=0; i
<nCount
; i
++)
2588 if ( i
!=nSrcTab
&& pTab
[i
] && rMark
.GetTableSelect(i
) )
2594 pMixDoc
= new ScDocument( SCDOCMODE_UNDO
);
2595 pMixDoc
->InitUndo( this, i
, i
);
2598 pMixDoc
->AddUndoTab( i
, i
);
2599 pTab
[i
]->CopyToTable( nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2600 IDF_CONTENTS
, TRUE
, pMixDoc
->pTab
[i
], &rMark
);
2603 pTab
[i
]->DeleteSelection( nDelFlags
, rMark
);
2604 pTab
[nSrcTab
]->CopyToTable( nStartCol
,nStartRow
, nEndCol
,nEndRow
,
2605 nFlags
, TRUE
, pTab
[i
], &rMark
, bAsLink
);
2608 pTab
[i
]->MixMarked( rMark
, nFunction
, bSkipEmpty
, pMixDoc
->pTab
[i
] );
2613 SetAutoCalc( bOldAutoCalc
);
2617 DBG_ERROR("falsche Tabelle");
2622 void ScDocument::PutCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, ScBaseCell
* pCell
, BOOL bForceTab
)
2626 if ( bForceTab
&& !pTab
[nTab
] )
2628 BOOL bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
2630 pTab
[nTab
] = new ScTable(this, nTab
,
2631 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
2637 pTab
[nTab
]->PutCell( nCol
, nRow
, pCell
);
2642 void ScDocument::PutCell( const ScAddress
& rPos
, ScBaseCell
* pCell
, BOOL bForceTab
)
2644 SCTAB nTab
= rPos
.Tab();
2645 if ( bForceTab
&& !pTab
[nTab
] )
2647 BOOL bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
2649 pTab
[nTab
] = new ScTable(this, nTab
,
2650 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
2656 pTab
[nTab
]->PutCell( rPos
, pCell
);
2660 BOOL
ScDocument::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const String
& rString
,
2661 ScSetStringParam
* pParam
)
2663 if ( ValidTab(nTab
) && pTab
[nTab
] )
2664 return pTab
[nTab
]->SetString( nCol
, nRow
, nTab
, rString
, pParam
);
2670 void ScDocument::SetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const double& rVal
)
2674 pTab
[nTab
]->SetValue( nCol
, nRow
, rVal
);
2678 void ScDocument::GetString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rString
)
2680 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2681 pTab
[nTab
]->GetString( nCol
, nRow
, rString
);
2687 void ScDocument::GetInputString( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rString
)
2689 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2690 pTab
[nTab
]->GetInputString( nCol
, nRow
, rString
);
2696 void ScDocument::GetValue( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, double& rValue
)
2698 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2699 rValue
= pTab
[nTab
]->GetValue( nCol
, nRow
);
2705 double ScDocument::GetValue( const ScAddress
& rPos
)
2707 SCTAB nTab
= rPos
.Tab();
2709 return pTab
[nTab
]->GetValue( rPos
);
2714 void ScDocument::GetNumberFormat( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
2715 sal_uInt32
& rFormat
)
2720 rFormat
= pTab
[nTab
]->GetNumberFormat( nCol
, nRow
);
2726 sal_uInt32
ScDocument::GetNumberFormat( const ScRange
& rRange
) const
2728 SCTAB nTab1
= rRange
.aStart
.Tab(), nTab2
= rRange
.aEnd
.Tab();
2729 SCCOL nCol1
= rRange
.aStart
.Col(), nCol2
= rRange
.aEnd
.Col();
2730 SCROW nRow1
= rRange
.aStart
.Row(), nRow2
= rRange
.aEnd
.Row();
2732 if (!ValidTab(nTab1
) || !ValidTab(nTab2
) || !pTab
[nTab1
] || !pTab
[nTab2
])
2735 sal_uInt32 nFormat
= 0;
2736 bool bFirstItem
= true;
2737 for (SCTAB nTab
= nTab1
; nTab
<= nTab2
; ++nTab
)
2738 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
2740 sal_uInt32 nThisFormat
= pTab
[nTab
]->GetNumberFormat(nCol
, nRow1
, nRow2
);
2743 nFormat
= nThisFormat
;
2746 else if (nThisFormat
!= nFormat
)
2753 sal_uInt32
ScDocument::GetNumberFormat( const ScAddress
& rPos
) const
2755 SCTAB nTab
= rPos
.Tab();
2757 return pTab
[nTab
]->GetNumberFormat( rPos
);
2762 void ScDocument::GetNumberFormatInfo( short& nType
, ULONG
& nIndex
,
2763 const ScAddress
& rPos
, const ScBaseCell
* pCell
) const
2765 SCTAB nTab
= rPos
.Tab();
2768 nIndex
= pTab
[nTab
]->GetNumberFormat( rPos
);
2769 if ( (nIndex
% SV_COUNTRY_LANGUAGE_OFFSET
) == 0 && pCell
&&
2770 pCell
->GetCellType() == CELLTYPE_FORMULA
)
2771 static_cast<const ScFormulaCell
*>(pCell
)->GetFormatInfo( nType
, nIndex
);
2773 nType
= GetFormatTable()->GetType( nIndex
);
2777 nType
= NUMBERFORMAT_UNDEFINED
;
2783 void ScDocument::GetFormula( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rFormula
,
2784 BOOL bAsciiExport
) const
2786 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2787 pTab
[nTab
]->GetFormula( nCol
, nRow
, rFormula
, bAsciiExport
);
2793 CellType
ScDocument::GetCellType( const ScAddress
& rPos
) const
2795 SCTAB nTab
= rPos
.Tab();
2797 return pTab
[nTab
]->GetCellType( rPos
);
2798 return CELLTYPE_NONE
;
2802 void ScDocument::GetCellType( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
2803 CellType
& rCellType
) const
2805 if (ValidTab(nTab
) && pTab
[nTab
])
2806 rCellType
= pTab
[nTab
]->GetCellType( nCol
, nRow
);
2808 rCellType
= CELLTYPE_NONE
;
2812 void ScDocument::GetCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
2813 ScBaseCell
*& rpCell
) const
2815 if (ValidTab(nTab
) && pTab
[nTab
])
2816 rpCell
= pTab
[nTab
]->GetCell( nCol
, nRow
);
2819 DBG_ERROR("GetCell ohne Tabelle");
2825 ScBaseCell
* ScDocument::GetCell( const ScAddress
& rPos
) const
2827 SCTAB nTab
= rPos
.Tab();
2828 if (ValidTab(nTab
) && pTab
[nTab
])
2829 return pTab
[nTab
]->GetCell( rPos
);
2831 DBG_ERROR("GetCell ohne Tabelle");
2836 BOOL
ScDocument::HasStringData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
2838 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2839 return pTab
[nTab
]->HasStringData( nCol
, nRow
);
2845 BOOL
ScDocument::HasValueData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
2847 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
2848 return pTab
[nTab
]->HasValueData( nCol
, nRow
);
2854 BOOL
ScDocument::HasStringCells( const ScRange
& rRange
) const
2856 // TRUE, wenn String- oder Editzellen im Bereich
2858 SCCOL nStartCol
= rRange
.aStart
.Col();
2859 SCROW nStartRow
= rRange
.aStart
.Row();
2860 SCTAB nStartTab
= rRange
.aStart
.Tab();
2861 SCCOL nEndCol
= rRange
.aEnd
.Col();
2862 SCROW nEndRow
= rRange
.aEnd
.Row();
2863 SCTAB nEndTab
= rRange
.aEnd
.Tab();
2865 for ( SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++ )
2866 if ( pTab
[nTab
] && pTab
[nTab
]->HasStringCells( nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
2873 BOOL
ScDocument::HasSelectionData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
2875 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
2878 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
2879 if( pData
&& pData
->HasSelectionList() )
2882 return HasStringCells( ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
) );
2886 ScPostIt
* ScDocument::GetNote( const ScAddress
& rPos
)
2888 ScTable
* pTable
= ValidTab( rPos
.Tab() ) ? pTab
[ rPos
.Tab() ] : 0;
2889 return pTable
? pTable
->GetNote( rPos
.Col(), rPos
.Row() ) : 0;
2893 void ScDocument::TakeNote( const ScAddress
& rPos
, ScPostIt
*& rpNote
)
2895 if( ValidTab( rPos
.Tab() ) && pTab
[ rPos
.Tab() ] )
2896 pTab
[ rPos
.Tab() ]->TakeNote( rPos
.Col(), rPos
.Row(), rpNote
);
2902 ScPostIt
* ScDocument::ReleaseNote( const ScAddress
& rPos
)
2904 ScTable
* pTable
= ValidTab( rPos
.Tab() ) ? pTab
[ rPos
.Tab() ] : 0;
2905 return pTable
? pTable
->ReleaseNote( rPos
.Col(), rPos
.Row() ) : 0;
2909 ScPostIt
* ScDocument::GetOrCreateNote( const ScAddress
& rPos
)
2911 ScPostIt
* pNote
= GetNote( rPos
);
2914 pNote
= new ScPostIt( *this, rPos
, false );
2915 TakeNote( rPos
, pNote
);
2921 void ScDocument::DeleteNote( const ScAddress
& rPos
)
2923 if( ValidTab( rPos
.Tab() ) && pTab
[ rPos
.Tab() ] )
2924 pTab
[ rPos
.Tab() ]->DeleteNote( rPos
.Col(), rPos
.Row() );
2928 void ScDocument::InitializeNoteCaptions( SCTAB nTab
, bool bForced
)
2930 if( ValidTab( nTab
) && pTab
[ nTab
] )
2931 pTab
[ nTab
]->InitializeNoteCaptions( bForced
);
2934 void ScDocument::InitializeAllNoteCaptions( bool bForced
)
2936 for( SCTAB nTab
= 0; nTab
< GetTableCount(); ++nTab
)
2937 InitializeNoteCaptions( nTab
, bForced
);
2940 void ScDocument::SetDirty()
2942 BOOL bOldAutoCalc
= GetAutoCalc();
2943 bAutoCalc
= FALSE
; // keine Mehrfachberechnung
2944 { // scope for bulk broadcast
2945 ScBulkBroadcast
aBulkBroadcast( GetBASM());
2946 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
2947 if (pTab
[i
]) pTab
[i
]->SetDirty();
2950 // Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
2951 // wenn alle Formeln dirty sind, werden die Charts aber nicht mehr erwischt
2952 // (#45205#) - darum alle Charts nochmal explizit
2953 if (pChartListenerCollection
)
2954 pChartListenerCollection
->SetDirty();
2956 SetAutoCalc( bOldAutoCalc
);
2960 void ScDocument::SetDirty( const ScRange
& rRange
)
2962 BOOL bOldAutoCalc
= GetAutoCalc();
2963 bAutoCalc
= FALSE
; // keine Mehrfachberechnung
2964 { // scope for bulk broadcast
2965 ScBulkBroadcast
aBulkBroadcast( GetBASM());
2966 SCTAB nTab2
= rRange
.aEnd
.Tab();
2967 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
; i
++)
2968 if (pTab
[i
]) pTab
[i
]->SetDirty( rRange
);
2970 SetAutoCalc( bOldAutoCalc
);
2974 void ScDocument::SetTableOpDirty( const ScRange
& rRange
)
2976 BOOL bOldAutoCalc
= GetAutoCalc();
2977 bAutoCalc
= FALSE
; // no multiple recalculation
2978 SCTAB nTab2
= rRange
.aEnd
.Tab();
2979 for (SCTAB i
=rRange
.aStart
.Tab(); i
<=nTab2
; i
++)
2980 if (pTab
[i
]) pTab
[i
]->SetTableOpDirty( rRange
);
2981 SetAutoCalc( bOldAutoCalc
);
2985 void ScDocument::InterpretDirtyCells( const ScRangeList
& rRanges
)
2987 ULONG nRangeCount
= rRanges
.Count();
2988 for (ULONG nPos
=0; nPos
<nRangeCount
; nPos
++)
2990 ScCellIterator
aIter( this, *rRanges
.GetObject(nPos
) );
2991 ScBaseCell
* pCell
= aIter
.GetFirst();
2994 if (pCell
->GetCellType() == CELLTYPE_FORMULA
)
2996 if ( static_cast<ScFormulaCell
*>(pCell
)->GetDirty() && GetAutoCalc() )
2997 static_cast<ScFormulaCell
*>(pCell
)->Interpret();
2999 pCell
= aIter
.GetNext();
3005 void ScDocument::AddTableOpFormulaCell( ScFormulaCell
* pCell
)
3007 ScInterpreterTableOpParams
* p
= aTableOpList
.Last();
3008 if ( p
&& p
->bCollectNotifications
)
3011 { // refresh pointers only
3012 p
->aNotifiedFormulaCells
.push_back( pCell
);
3015 { // init both, address and pointer
3016 p
->aNotifiedFormulaCells
.push_back( pCell
);
3017 p
->aNotifiedFormulaPos
.push_back( pCell
->aPos
);
3023 void ScDocument::CalcAll()
3025 ClearLookupCaches(); // Ensure we don't deliver zombie data.
3026 BOOL bOldAutoCalc
= GetAutoCalc();
3027 SetAutoCalc( TRUE
);
3029 for (i
=0; i
<=MAXTAB
; i
++)
3030 if (pTab
[i
]) pTab
[i
]->SetDirtyVar();
3031 for (i
=0; i
<=MAXTAB
; i
++)
3032 if (pTab
[i
]) pTab
[i
]->CalcAll();
3034 SetAutoCalc( bOldAutoCalc
);
3038 void ScDocument::CompileAll()
3040 if ( pCondFormList
)
3041 pCondFormList
->CompileAll();
3043 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
3044 if (pTab
[i
]) pTab
[i
]->CompileAll();
3049 void ScDocument::CompileXML()
3051 BOOL bOldAutoCalc
= GetAutoCalc();
3052 SetAutoCalc( FALSE
);
3053 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(
3054 STR_PROGRESS_CALCULATING
), GetXMLImportedFormulaCount() );
3056 // #b6355215# set AutoNameCache to speed up automatic name lookup
3057 DBG_ASSERT( !pAutoNameCache
, "AutoNameCache already set" );
3058 pAutoNameCache
= new ScAutoNameCache( this );
3060 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
3061 if (pTab
[i
]) pTab
[i
]->CompileXML( aProgress
);
3063 DELETEZ( pAutoNameCache
); // valid only during CompileXML, where cell contents don't change
3065 if ( pCondFormList
)
3066 pCondFormList
->CompileXML();
3067 if ( pValidationList
)
3068 pValidationList
->CompileXML();
3071 SetAutoCalc( bOldAutoCalc
);
3075 void ScDocument::CalcAfterLoad()
3079 if (bIsClip
) // Excel-Dateien werden aus dem Clipboard in ein Clip-Doc geladen
3080 return; // dann wird erst beim Einfuegen in das richtige Doc berechnet
3082 bCalcingAfterLoad
= TRUE
;
3083 for ( i
= 0; i
<= MAXTAB
; i
++)
3084 if (pTab
[i
]) pTab
[i
]->CalcAfterLoad();
3085 for (i
=0; i
<=MAXTAB
; i
++)
3086 if (pTab
[i
]) pTab
[i
]->SetDirtyAfterLoad();
3087 bCalcingAfterLoad
= FALSE
;
3089 SetDetectiveDirty(FALSE
); // noch keine wirklichen Aenderungen
3093 USHORT
ScDocument::GetErrCode( const ScAddress
& rPos
) const
3095 SCTAB nTab
= rPos
.Tab();
3097 return pTab
[nTab
]->GetErrCode( rPos
);
3102 void ScDocument::ResetChanged( const ScRange
& rRange
)
3104 SCTAB nStartTab
= rRange
.aStart
.Tab();
3105 SCTAB nEndTab
= rRange
.aEnd
.Tab();
3106 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
3108 pTab
[nTab
]->ResetChanged( rRange
);
3112 // Spaltenbreiten / Zeilenhoehen --------------------------------------
3116 void ScDocument::SetColWidth( SCCOL nCol
, SCTAB nTab
, USHORT nNewWidth
)
3118 if ( ValidTab(nTab
) && pTab
[nTab
] )
3119 pTab
[nTab
]->SetColWidth( nCol
, nNewWidth
);
3123 void ScDocument::SetRowHeight( SCROW nRow
, SCTAB nTab
, USHORT nNewHeight
)
3125 if ( ValidTab(nTab
) && pTab
[nTab
] )
3126 pTab
[nTab
]->SetRowHeight( nRow
, nNewHeight
);
3130 void ScDocument::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, USHORT nNewHeight
)
3132 if ( ValidTab(nTab
) && pTab
[nTab
] )
3133 pTab
[nTab
]->SetRowHeightRange
3134 ( nStartRow
, nEndRow
, nNewHeight
, 1.0, 1.0 );
3138 void ScDocument::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, BOOL bManual
)
3140 if ( ValidTab(nTab
) && pTab
[nTab
] )
3141 pTab
[nTab
]->SetManualHeight( nStartRow
, nEndRow
, bManual
);
3145 USHORT
ScDocument::GetColWidth( SCCOL nCol
, SCTAB nTab
) const
3147 if ( ValidTab(nTab
) && pTab
[nTab
] )
3148 return pTab
[nTab
]->GetColWidth( nCol
);
3149 DBG_ERROR("Falsche Tabellennummer");
3154 USHORT
ScDocument::GetOriginalWidth( SCCOL nCol
, SCTAB nTab
) const
3156 if ( ValidTab(nTab
) && pTab
[nTab
] )
3157 return pTab
[nTab
]->GetOriginalWidth( nCol
);
3158 DBG_ERROR("Falsche Tabellennummer");
3163 USHORT
ScDocument::GetCommonWidth( SCCOL nEndCol
, SCTAB nTab
) const
3165 if ( ValidTab(nTab
) && pTab
[nTab
] )
3166 return pTab
[nTab
]->GetCommonWidth( nEndCol
);
3167 DBG_ERROR("Wrong table number");
3172 USHORT
ScDocument::GetOriginalHeight( SCROW nRow
, SCTAB nTab
) const
3174 if ( ValidTab(nTab
) && pTab
[nTab
] )
3175 return pTab
[nTab
]->GetOriginalHeight( nRow
);
3176 DBG_ERROR("Wrong table number");
3181 USHORT
ScDocument::GetRowHeight( SCROW nRow
, SCTAB nTab
) const
3183 if ( ValidTab(nTab
) && pTab
[nTab
] )
3184 return pTab
[nTab
]->GetRowHeight( nRow
);
3185 DBG_ERROR("Falsche Tabellennummer");
3190 ULONG
ScDocument::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
3192 if (nStartRow
== nEndRow
)
3193 return GetRowHeight( nStartRow
, nTab
); // faster for a single row
3195 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3196 if (nStartRow
> nEndRow
)
3199 if ( ValidTab(nTab
) && pTab
[nTab
] )
3200 return pTab
[nTab
]->GetRowHeight( nStartRow
, nEndRow
);
3202 DBG_ERROR("wrong sheet number");
3206 ULONG
ScDocument::FastGetRowHeight( SCROW nStartRow
, SCROW nEndRow
,
3209 return GetRowHeight(nStartRow
, nEndRow
, nTab
);
3212 ULONG
ScDocument::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
,
3213 SCTAB nTab
, double fScale
) const
3215 // faster for a single row
3216 if (nStartRow
== nEndRow
)
3217 return (ULONG
) (GetRowHeight( nStartRow
, nTab
) * fScale
);
3219 // check bounds because this method replaces former for(i=start;i<=end;++i) loops
3220 if (nStartRow
> nEndRow
)
3223 if ( ValidTab(nTab
) && pTab
[nTab
] )
3224 return pTab
[nTab
]->GetScaledRowHeight( nStartRow
, nEndRow
, fScale
);
3226 DBG_ERROR("wrong sheet number");
3231 const ScSummableCompressedArray
< SCROW
, USHORT
> & ScDocument::GetRowHeightArray(
3234 const ScSummableCompressedArray
< SCROW
, USHORT
> * pHeight
;
3235 if ( ValidTab(nTab
) && pTab
[nTab
] )
3236 pHeight
= pTab
[nTab
]->GetRowHeightArray();
3239 DBG_ERROR("wrong sheet number");
3244 DBG_ERROR("no row heights at sheet");
3245 static ScSummableCompressedArray
< SCROW
, USHORT
> aDummy( MAXROW
,
3246 ScGlobal::nStdRowHeight
);
3253 SCROW
ScDocument::GetHiddenRowCount( SCROW nRow
, SCTAB nTab
) const
3255 if ( ValidTab(nTab
) && pTab
[nTab
] )
3256 return pTab
[nTab
]->GetHiddenRowCount( nRow
);
3257 DBG_ERROR("Falsche Tabellennummer");
3262 ULONG
ScDocument::GetColOffset( SCCOL nCol
, SCTAB nTab
) const
3264 if ( ValidTab(nTab
) && pTab
[nTab
] )
3265 return pTab
[nTab
]->GetColOffset( nCol
);
3266 DBG_ERROR("Falsche Tabellennummer");
3271 ULONG
ScDocument::GetRowOffset( SCROW nRow
, SCTAB nTab
) const
3273 if ( ValidTab(nTab
) && pTab
[nTab
] )
3274 return pTab
[nTab
]->GetRowOffset( nRow
);
3275 DBG_ERROR("Falsche Tabellennummer");
3280 USHORT
ScDocument::GetOptimalColWidth( SCCOL nCol
, SCTAB nTab
, OutputDevice
* pDev
,
3281 double nPPTX
, double nPPTY
,
3282 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3283 BOOL bFormula
, const ScMarkData
* pMarkData
,
3284 BOOL bSimpleTextImport
)
3286 if ( ValidTab(nTab
) && pTab
[nTab
] )
3287 return pTab
[nTab
]->GetOptimalColWidth( nCol
, pDev
, nPPTX
, nPPTY
,
3288 rZoomX
, rZoomY
, bFormula
, pMarkData
, bSimpleTextImport
);
3289 DBG_ERROR("Falsche Tabellennummer");
3294 long ScDocument::GetNeededSize( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
3296 double nPPTX
, double nPPTY
,
3297 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3298 BOOL bWidth
, BOOL bTotalSize
)
3300 if ( ValidTab(nTab
) && pTab
[nTab
] )
3301 return pTab
[nTab
]->GetNeededSize
3302 ( nCol
, nRow
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bWidth
, bTotalSize
);
3303 DBG_ERROR("Falsche Tabellennummer");
3308 BOOL
ScDocument::SetOptimalHeight( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, USHORT nExtra
,
3310 double nPPTX
, double nPPTY
,
3311 const Fraction
& rZoomX
, const Fraction
& rZoomY
,
3315 if ( ValidTab(nTab
) && pTab
[nTab
] )
3316 return pTab
[nTab
]->SetOptimalHeight( nStartRow
, nEndRow
, nExtra
,
3317 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, bShrink
);
3318 DBG_ERROR("Falsche Tabellennummer");
3323 void ScDocument::UpdateAllRowHeights( OutputDevice
* pDev
, double nPPTX
, double nPPTY
,
3324 const Fraction
& rZoomX
, const Fraction
& rZoomY
, const ScMarkData
* pTabMark
)
3326 // one progress across all (selected) sheets
3328 ULONG nCellCount
= 0;
3329 for ( SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++ )
3330 if ( pTab
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3331 nCellCount
+= pTab
[nTab
]->GetWeightedCount();
3333 ScProgress
aProgress( GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING
), nCellCount
);
3335 ULONG nProgressStart
= 0;
3336 for ( SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++ )
3337 if ( pTab
[nTab
] && ( !pTabMark
|| pTabMark
->GetTableSelect(nTab
) ) )
3339 pTab
[nTab
]->SetOptimalHeight( 0, MAXROW
, 0,
3340 pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, FALSE
, &aProgress
, nProgressStart
);
3341 nProgressStart
+= pTab
[nTab
]->GetWeightedCount();
3347 // Spalten-/Zeilen-Flags ----------------------------------------------
3350 void ScDocument::ShowCol(SCCOL nCol
, SCTAB nTab
, BOOL bShow
)
3352 if ( ValidTab(nTab
) && pTab
[nTab
] )
3353 pTab
[nTab
]->ShowCol( nCol
, bShow
);
3357 void ScDocument::ShowRow(SCROW nRow
, SCTAB nTab
, BOOL bShow
)
3359 if ( ValidTab(nTab
) && pTab
[nTab
] )
3360 pTab
[nTab
]->ShowRow( nRow
, bShow
);
3364 void ScDocument::ShowRows(SCROW nRow1
, SCROW nRow2
, SCTAB nTab
, BOOL bShow
)
3366 if ( ValidTab(nTab
) && pTab
[nTab
] )
3367 pTab
[nTab
]->ShowRows( nRow1
, nRow2
, bShow
);
3371 void ScDocument::SetColFlags( SCCOL nCol
, SCTAB nTab
, BYTE nNewFlags
)
3373 if ( ValidTab(nTab
) && pTab
[nTab
] )
3374 pTab
[nTab
]->SetColFlags( nCol
, nNewFlags
);
3378 void ScDocument::SetRowFlags( SCROW nRow
, SCTAB nTab
, BYTE nNewFlags
)
3380 if ( ValidTab(nTab
) && pTab
[nTab
] )
3381 pTab
[nTab
]->SetRowFlags( nRow
, nNewFlags
);
3385 void ScDocument::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, BYTE nNewFlags
)
3387 if ( ValidTab(nTab
) && pTab
[nTab
] )
3388 pTab
[nTab
]->SetRowFlags( nStartRow
, nEndRow
, nNewFlags
);
3392 BYTE
ScDocument::GetColFlags( SCCOL nCol
, SCTAB nTab
) const
3394 if ( ValidTab(nTab
) && pTab
[nTab
] )
3395 return pTab
[nTab
]->GetColFlags( nCol
);
3396 DBG_ERROR("Falsche Tabellennummer");
3400 BYTE
ScDocument::GetRowFlags( SCROW nRow
, SCTAB nTab
) const
3402 if ( ValidTab(nTab
) && pTab
[nTab
] )
3403 return pTab
[nTab
]->GetRowFlags( nRow
);
3404 DBG_ERROR("Falsche Tabellennummer");
3408 ScBitMaskCompressedArray
< SCROW
, BYTE
> & ScDocument::GetRowFlagsArrayModifiable(
3411 return const_cast< ScBitMaskCompressedArray
< SCROW
, BYTE
> & >(
3412 GetRowFlagsArray( nTab
));
3415 const ScBitMaskCompressedArray
< SCROW
, BYTE
> & ScDocument::GetRowFlagsArray(
3418 const ScBitMaskCompressedArray
< SCROW
, BYTE
> * pFlags
;
3419 if ( ValidTab(nTab
) && pTab
[nTab
] )
3420 pFlags
= pTab
[nTab
]->GetRowFlagsArray();
3423 DBG_ERROR("wrong sheet number");
3428 DBG_ERROR("no row flags at sheet");
3429 static ScBitMaskCompressedArray
< SCROW
, BYTE
> aDummy( MAXROW
, 0);
3435 void ScDocument::GetAllRowBreaks(set
<SCROW
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
3437 if (!ValidTab(nTab
) || !pTab
[nTab
])
3440 pTab
[nTab
]->GetAllRowBreaks(rBreaks
, bPage
, bManual
);
3443 void ScDocument::GetAllColBreaks(set
<SCCOL
>& rBreaks
, SCTAB nTab
, bool bPage
, bool bManual
) const
3445 if (!ValidTab(nTab
) || !pTab
[nTab
])
3448 pTab
[nTab
]->GetAllColBreaks(rBreaks
, bPage
, bManual
);
3451 ScBreakType
ScDocument::HasRowBreak(SCROW nRow
, SCTAB nTab
) const
3453 ScBreakType nType
= BREAK_NONE
;
3454 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidRow(nRow
))
3457 if (pTab
[nTab
]->HasRowPageBreak(nRow
))
3458 nType
|= BREAK_PAGE
;
3460 if (pTab
[nTab
]->HasRowManualBreak(nRow
))
3461 nType
|= BREAK_MANUAL
;
3466 ScBreakType
ScDocument::HasColBreak(SCCOL nCol
, SCTAB nTab
) const
3468 ScBreakType nType
= BREAK_NONE
;
3469 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidCol(nCol
))
3472 if (pTab
[nTab
]->HasColPageBreak(nCol
))
3473 nType
|= BREAK_PAGE
;
3475 if (pTab
[nTab
]->HasColManualBreak(nCol
))
3476 nType
|= BREAK_MANUAL
;
3481 void ScDocument::SetRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
3483 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidRow(nRow
))
3486 pTab
[nTab
]->SetRowBreak(nRow
, bPage
, bManual
);
3489 void ScDocument::SetColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
3491 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidCol(nCol
))
3494 pTab
[nTab
]->SetColBreak(nCol
, bPage
, bManual
);
3497 void ScDocument::RemoveRowBreak(SCROW nRow
, SCTAB nTab
, bool bPage
, bool bManual
)
3499 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidRow(nRow
))
3502 pTab
[nTab
]->RemoveRowBreak(nRow
, bPage
, bManual
);
3505 void ScDocument::RemoveColBreak(SCCOL nCol
, SCTAB nTab
, bool bPage
, bool bManual
)
3507 if (!ValidTab(nTab
) || !pTab
[nTab
] || !ValidCol(nCol
))
3510 pTab
[nTab
]->RemoveColBreak(nCol
, bPage
, bManual
);
3513 Sequence
<TablePageBreakData
> ScDocument::GetRowBreakData(SCTAB nTab
) const
3515 if (!ValidTab(nTab
) || !pTab
[nTab
])
3516 return Sequence
<TablePageBreakData
>();
3518 return pTab
[nTab
]->GetRowBreakData();
3521 bool ScDocument::RowHidden(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
)
3523 if (!ValidTab(nTab
) || !pTab
[nTab
])
3526 return pTab
[nTab
]->RowHidden(nRow
, pFirstRow
, pLastRow
);
3529 bool ScDocument::RowHidden(SCROW nRow
, SCTAB nTab
, SCROW
& rLastRow
)
3531 if (!ValidTab(nTab
) || !pTab
[nTab
])
3537 return pTab
[nTab
]->RowHidden(nRow
, rLastRow
);
3541 bool ScDocument::HasHiddenRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3543 if (!ValidTab(nTab
) || !pTab
[nTab
])
3546 return pTab
[nTab
]->HasHiddenRows(nStartRow
, nEndRow
);
3549 bool ScDocument::ColHidden(SCCOL nCol
, SCTAB nTab
, SCCOL
& rLastCol
)
3551 if (!ValidTab(nTab
) || !pTab
[nTab
])
3557 return pTab
[nTab
]->ColHidden(nCol
, rLastCol
);
3560 bool ScDocument::ColHidden(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
)
3562 if (!ValidTab(nTab
) || !pTab
[nTab
])
3571 return pTab
[nTab
]->ColHidden(nCol
, pFirstCol
, pLastCol
);
3574 void ScDocument::SetRowHidden(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bHidden
)
3576 if (!ValidTab(nTab
) || !pTab
[nTab
])
3579 pTab
[nTab
]->SetRowHidden(nStartRow
, nEndRow
, bHidden
);
3582 void ScDocument::SetColHidden(SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bHidden
)
3584 if (!ValidTab(nTab
) || !pTab
[nTab
])
3587 pTab
[nTab
]->SetColHidden(nStartCol
, nEndCol
, bHidden
);
3590 SCROW
ScDocument::FirstVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3592 if (!ValidTab(nTab
) || !pTab
[nTab
])
3593 return ::std::numeric_limits
<SCROW
>::max();;
3595 return pTab
[nTab
]->FirstVisibleRow(nStartRow
, nEndRow
);
3598 SCROW
ScDocument::LastVisibleRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3600 if (!ValidTab(nTab
) || !pTab
[nTab
])
3601 return ::std::numeric_limits
<SCROW
>::max();;
3603 return pTab
[nTab
]->LastVisibleRow(nStartRow
, nEndRow
);
3606 SCROW
ScDocument::CountVisibleRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3608 if (!ValidTab(nTab
) || !pTab
[nTab
])
3611 return pTab
[nTab
]->CountVisibleRows(nStartRow
, nEndRow
);
3614 bool ScDocument::RowFiltered(SCROW nRow
, SCTAB nTab
, SCROW
* pFirstRow
, SCROW
* pLastRow
)
3616 if (!ValidTab(nTab
) || !pTab
[nTab
])
3619 return pTab
[nTab
]->RowFiltered(nRow
, pFirstRow
, pLastRow
);
3622 bool ScDocument::HasFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3624 if (!ValidTab(nTab
) || !pTab
[nTab
])
3627 return pTab
[nTab
]->HasFilteredRows(nStartRow
, nEndRow
);
3630 bool ScDocument::ColFiltered(SCCOL nCol
, SCTAB nTab
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
)
3632 if (!ValidTab(nTab
) || !pTab
[nTab
])
3635 return pTab
[nTab
]->ColFiltered(nCol
, pFirstCol
, pLastCol
);
3638 void ScDocument::SetRowFiltered(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bFiltered
)
3640 if (!ValidTab(nTab
) || !pTab
[nTab
])
3643 pTab
[nTab
]->SetRowFiltered(nStartRow
, nEndRow
, bFiltered
);
3646 void ScDocument::SetColFiltered(SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bFiltered
)
3648 if (!ValidTab(nTab
) || !pTab
[nTab
])
3651 pTab
[nTab
]->SetColFiltered(nStartCol
, nEndCol
, bFiltered
);
3654 SCROW
ScDocument::FirstNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3656 if (!ValidTab(nTab
) || !pTab
[nTab
])
3657 return ::std::numeric_limits
<SCROW
>::max();;
3659 return pTab
[nTab
]->FirstNonFilteredRow(nStartRow
, nEndRow
);
3662 SCROW
ScDocument::LastNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3664 if (!ValidTab(nTab
) || !pTab
[nTab
])
3665 return ::std::numeric_limits
<SCROW
>::max();;
3667 return pTab
[nTab
]->LastNonFilteredRow(nStartRow
, nEndRow
);
3670 SCROW
ScDocument::CountNonFilteredRows(SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
)
3672 if (!ValidTab(nTab
) || !pTab
[nTab
])
3675 return pTab
[nTab
]->CountNonFilteredRows(nStartRow
, nEndRow
);
3678 void ScDocument::SyncColRowFlags()
3680 for (SCTAB i
= 0; i
<= nMaxTableNumber
; ++i
)
3682 if (!ValidTab(i
) || !pTab
[i
])
3685 pTab
[i
]->SyncColRowFlags();
3689 SCROW
ScDocument::GetLastFlaggedRow( SCTAB nTab
) const
3691 if ( ValidTab(nTab
) && pTab
[nTab
] )
3692 return pTab
[nTab
]->GetLastFlaggedRow();
3697 SCCOL
ScDocument::GetLastChangedCol( SCTAB nTab
) const
3699 if ( ValidTab(nTab
) && pTab
[nTab
] )
3700 return pTab
[nTab
]->GetLastChangedCol();
3704 SCROW
ScDocument::GetLastChangedRow( SCTAB nTab
) const
3706 if ( ValidTab(nTab
) && pTab
[nTab
] )
3707 return pTab
[nTab
]->GetLastChangedRow();
3712 SCCOL
ScDocument::GetNextDifferentChangedCol( SCTAB nTab
, SCCOL nStart
) const
3714 if ( ValidTab(nTab
) && pTab
[nTab
] )
3716 BYTE nStartFlags
= pTab
[nTab
]->GetColFlags(nStart
);
3717 USHORT nStartWidth
= pTab
[nTab
]->GetOriginalWidth(nStart
);
3718 for (SCCOL nCol
= nStart
+ 1; nCol
<= MAXCOL
; nCol
++)
3720 if (((nStartFlags
& CR_MANUALBREAK
) != (pTab
[nTab
]->GetColFlags(nCol
) & CR_MANUALBREAK
)) ||
3721 (nStartWidth
!= pTab
[nTab
]->GetOriginalWidth(nCol
)) ||
3722 ((nStartFlags
& CR_HIDDEN
) != (pTab
[nTab
]->GetColFlags(nCol
) & CR_HIDDEN
)) )
3730 SCROW
ScDocument::GetNextDifferentChangedRow( SCTAB nTab
, SCROW nStart
, bool bCareManualSize
) const
3732 if ( ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->GetRowFlagsArray() && pTab
[nTab
]->GetRowHeightArray() )
3734 BYTE nStartFlags
= pTab
[nTab
]->GetRowFlags(nStart
);
3735 USHORT nStartHeight
= pTab
[nTab
]->GetOriginalHeight(nStart
);
3736 for (SCROW nRow
= nStart
+ 1; nRow
<= MAXROW
; nRow
++)
3738 size_t nIndex
; // ignored
3740 SCROW nHeightEndRow
;
3741 BYTE nFlags
= pTab
[nTab
]->GetRowFlagsArray()->GetValue( nRow
, nIndex
, nFlagsEndRow
);
3742 USHORT nHeight
= pTab
[nTab
]->GetRowHeightArray()->GetValue( nRow
, nIndex
, nHeightEndRow
);
3743 if (((nStartFlags
& CR_MANUALBREAK
) != (nFlags
& CR_MANUALBREAK
)) ||
3744 ((nStartFlags
& CR_MANUALSIZE
) != (nFlags
& CR_MANUALSIZE
)) ||
3745 (bCareManualSize
&& (nStartFlags
& CR_MANUALSIZE
) && (nStartHeight
!= nHeight
)) ||
3746 (!bCareManualSize
&& ((nStartHeight
!= nHeight
))))
3749 nRow
= std::min( nFlagsEndRow
, nHeightEndRow
);
3756 BOOL
ScDocument::GetColDefault( SCTAB nTab
, SCCOL nCol
, SCROW nLastRow
, SCROW
& nDefault
)
3760 ScDocAttrIterator
aDocAttrItr(this, nTab
, nCol
, 0, nCol
, nLastRow
);
3764 const ScPatternAttr
* pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
3765 if (nEndRow
< nLastRow
)
3767 ScDefaultAttrSet aSet
;
3768 ScDefaultAttrSet::iterator aItr
= aSet
.end();
3771 ScDefaultAttr
aAttr(pAttr
);
3772 aItr
= aSet
.find(aAttr
);
3773 if (aItr
== aSet
.end())
3775 aAttr
.nCount
= static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
3776 aAttr
.nFirst
= nStartRow
;
3781 aAttr
.nCount
= aItr
->nCount
+ static_cast<SCSIZE
>(nEndRow
- nStartRow
+ 1);
3782 aAttr
.nFirst
= aItr
->nFirst
;
3786 pAttr
= aDocAttrItr
.GetNext(nColumn
, nStartRow
, nEndRow
);
3788 ScDefaultAttrSet::iterator aDefaultItr
= aSet
.begin();
3791 while (aItr
!= aSet
.end())
3793 // for entries with equal count, use the one with the lowest start row,
3794 // don't use the random order of pointer comparisons
3795 if ( aItr
->nCount
> aDefaultItr
->nCount
||
3796 ( aItr
->nCount
== aDefaultItr
->nCount
&& aItr
->nFirst
< aDefaultItr
->nFirst
) )
3800 nDefault
= aDefaultItr
->nFirst
;
3808 BOOL
ScDocument::GetRowDefault( SCTAB
/* nTab */, SCROW
/* nRow */, SCCOL
/* nLastCol */, SCCOL
& /* nDefault */ )
3814 void ScDocument::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
3816 if ( ValidTab(nTab
) && pTab
[nTab
] )
3817 pTab
[nTab
]->StripHidden( rX1
, rY1
, rX2
, rY2
);
3821 void ScDocument::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, SCTAB nTab
)
3823 if ( ValidTab(nTab
) && pTab
[nTab
] )
3824 pTab
[nTab
]->ExtendHidden( rX1
, rY1
, rX2
, rY2
);
3828 // Attribute ----------------------------------------------------------
3831 const SfxPoolItem
* ScDocument::GetAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, USHORT nWhich
) const
3833 if ( ValidTab(nTab
) && pTab
[nTab
] )
3835 const SfxPoolItem
* pTemp
= pTab
[nTab
]->GetAttr( nCol
, nRow
, nWhich
);
3840 DBG_ERROR( "Attribut Null" );
3843 return &xPoolHelper
->GetDocPool()->GetDefaultItem( nWhich
);
3847 const ScPatternAttr
* ScDocument::GetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3849 if ( ValidTab(nTab
) && pTab
[nTab
] )
3850 return pTab
[nTab
]->GetPattern( nCol
, nRow
);
3855 const ScPatternAttr
* ScDocument::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
) const
3857 if ( ValidTab(nTab
) && pTab
[nTab
] )
3858 return pTab
[nTab
]->GetMostUsedPattern( nCol
, nStartRow
, nEndRow
);
3863 void ScDocument::ApplyAttr( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const SfxPoolItem
& rAttr
)
3865 if ( ValidTab(nTab
) && pTab
[nTab
] )
3866 pTab
[nTab
]->ApplyAttr( nCol
, nRow
, rAttr
);
3870 void ScDocument::ApplyPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
3872 if ( ValidTab(nTab
) && pTab
[nTab
] )
3873 pTab
[nTab
]->ApplyPattern( nCol
, nRow
, rAttr
);
3877 void ScDocument::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
,
3878 SCCOL nEndCol
, SCROW nEndRow
,
3879 const ScMarkData
& rMark
,
3880 const ScPatternAttr
& rAttr
,
3881 ScEditDataArray
* pDataArray
)
3883 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
3885 if (rMark
.GetTableSelect(i
))
3886 pTab
[i
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
, pDataArray
);
3890 void ScDocument::ApplyPatternAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
3891 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
)
3895 pTab
[nTab
]->ApplyPatternArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rAttr
);
3898 void ScDocument::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
3899 const ScMarkData
& rMark
, const ScPatternAttr
& rPattern
, short nNewType
)
3901 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
3903 if (rMark
.GetTableSelect(i
))
3904 pTab
[i
]->ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
3908 void ScDocument::ApplyStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
3912 pTab
[nTab
]->ApplyStyle( nCol
, nRow
, rStyle
);
3916 void ScDocument::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
,
3917 SCCOL nEndCol
, SCROW nEndRow
,
3918 const ScMarkData
& rMark
,
3919 const ScStyleSheet
& rStyle
)
3921 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
3923 if (rMark
.GetTableSelect(i
))
3924 pTab
[i
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
3928 void ScDocument::ApplyStyleAreaTab( SCCOL nStartCol
, SCROW nStartRow
,
3929 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, const ScStyleSheet
& rStyle
)
3933 pTab
[nTab
]->ApplyStyleArea( nStartCol
, nStartRow
, nEndCol
, nEndRow
, rStyle
);
3937 void ScDocument::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
3939 // ApplySelectionStyle needs multi mark
3940 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
3943 rMark
.GetMarkArea( aRange
);
3944 ApplyStyleArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
3945 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rStyle
);
3949 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
3950 if ( pTab
[i
] && rMark
.GetTableSelect(i
) )
3951 pTab
[i
]->ApplySelectionStyle( rStyle
, rMark
);
3956 void ScDocument::ApplySelectionLineStyle( const ScMarkData
& rMark
,
3957 const SvxBorderLine
* pLine
, BOOL bColorOnly
)
3959 if ( bColorOnly
&& !pLine
)
3962 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
3964 if (rMark
.GetTableSelect(i
))
3965 pTab
[i
]->ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
3969 const ScStyleSheet
* ScDocument::GetStyle( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
3971 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
3972 return pTab
[nTab
]->GetStyle(nCol
, nRow
);
3978 const ScStyleSheet
* ScDocument::GetSelectionStyle( const ScMarkData
& rMark
) const
3983 const ScStyleSheet
* pStyle
= NULL
;
3984 const ScStyleSheet
* pNewStyle
;
3986 if ( rMark
.IsMultiMarked() )
3987 for (SCTAB i
=0; i
<=MAXTAB
&& bEqual
; i
++)
3988 if (pTab
[i
] && rMark
.GetTableSelect(i
))
3990 pNewStyle
= pTab
[i
]->GetSelectionStyle( rMark
, bFound
);
3993 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
3994 bEqual
= FALSE
; // unterschiedliche
3998 if ( rMark
.IsMarked() )
4001 rMark
.GetMarkArea( aRange
);
4002 for (SCTAB i
=aRange
.aStart
.Tab(); i
<=aRange
.aEnd
.Tab() && bEqual
; i
++)
4003 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4005 pNewStyle
= pTab
[i
]->GetAreaStyle( bFound
,
4006 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4007 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4010 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
4011 bEqual
= FALSE
; // unterschiedliche
4017 return bEqual
? pStyle
: NULL
;
4021 void ScDocument::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, BOOL bRemoved
,
4023 double nPPTX
, double nPPTY
,
4024 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
4026 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
4028 pTab
[i
]->StyleSheetChanged
4029 ( pStyleSheet
, bRemoved
, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
);
4031 if ( pStyleSheet
&& pStyleSheet
->GetName() == ScGlobal::GetRscString(STR_STYLENAME_STANDARD
) )
4033 // update attributes for all note objects
4034 ScDetectiveFunc::UpdateAllComments( *this );
4039 BOOL
ScDocument::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, BOOL bGatherAllStyles
) const
4041 if ( bStyleSheetUsageInvalid
|| rStyle
.GetUsage() == ScStyleSheet::UNKNOWN
)
4043 if ( bGatherAllStyles
)
4045 SfxStyleSheetIterator
aIter( xPoolHelper
->GetStylePool(),
4046 SFX_STYLE_FAMILY_PARA
);
4047 for ( const SfxStyleSheetBase
* pStyle
= aIter
.First(); pStyle
;
4048 pStyle
= aIter
.Next() )
4050 const ScStyleSheet
* pScStyle
= PTR_CAST( ScStyleSheet
, pStyle
);
4052 pScStyle
->SetUsage( ScStyleSheet::NOTUSED
);
4056 BOOL bIsUsed
= FALSE
;
4058 for ( SCTAB i
=0; i
<=MAXTAB
; i
++ )
4062 if ( pTab
[i
]->IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
4064 if ( !bGatherAllStyles
)
4071 if ( bGatherAllStyles
)
4072 bStyleSheetUsageInvalid
= FALSE
;
4077 return rStyle
.GetUsage() == ScStyleSheet::USED
;
4081 BOOL
ScDocument::ApplyFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4082 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, INT16 nFlags
)
4086 return pTab
[nTab
]->ApplyFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4088 DBG_ERROR("ApplyFlags: falsche Tabelle");
4093 BOOL
ScDocument::RemoveFlagsTab( SCCOL nStartCol
, SCROW nStartRow
,
4094 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, INT16 nFlags
)
4098 return pTab
[nTab
]->RemoveFlags( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFlags
);
4100 DBG_ERROR("RemoveFlags: falsche Tabelle");
4105 void ScDocument::SetPattern( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const ScPatternAttr
& rAttr
,
4110 pTab
[nTab
]->SetPattern( nCol
, nRow
, rAttr
, bPutToPool
);
4114 void ScDocument::SetPattern( const ScAddress
& rPos
, const ScPatternAttr
& rAttr
,
4117 SCTAB nTab
= rPos
.Tab();
4119 pTab
[nTab
]->SetPattern( rPos
, rAttr
, bPutToPool
);
4123 ScPatternAttr
* ScDocument::CreateSelectionPattern( const ScMarkData
& rMark
, BOOL bDeep
)
4125 ScMergePatternState aState
;
4127 if ( rMark
.IsMultiMarked() ) // multi selection
4129 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4130 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4131 pTab
[i
]->MergeSelectionPattern( aState
, rMark
, bDeep
);
4133 if ( rMark
.IsMarked() ) // simle selection
4136 rMark
.GetMarkArea(aRange
);
4137 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4138 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4139 pTab
[i
]->MergePatternArea( aState
,
4140 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4141 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), bDeep
);
4144 DBG_ASSERT( aState
.pItemSet
, "SelectionPattern Null" );
4145 if (aState
.pItemSet
)
4146 return new ScPatternAttr( aState
.pItemSet
);
4148 return new ScPatternAttr( GetPool() ); // empty
4152 const ScPatternAttr
* ScDocument::GetSelectionPattern( const ScMarkData
& rMark
, BOOL bDeep
)
4154 delete pSelectionAttr
;
4155 pSelectionAttr
= CreateSelectionPattern( rMark
, bDeep
);
4156 return pSelectionAttr
;
4160 void ScDocument::GetSelectionFrame( const ScMarkData
& rMark
,
4161 SvxBoxItem
& rLineOuter
,
4162 SvxBoxInfoItem
& rLineInner
)
4164 rLineOuter
.SetLine(NULL
, BOX_LINE_TOP
);
4165 rLineOuter
.SetLine(NULL
, BOX_LINE_BOTTOM
);
4166 rLineOuter
.SetLine(NULL
, BOX_LINE_LEFT
);
4167 rLineOuter
.SetLine(NULL
, BOX_LINE_RIGHT
);
4168 rLineOuter
.SetDistance(0);
4170 rLineInner
.SetLine(NULL
, BOXINFO_LINE_HORI
);
4171 rLineInner
.SetLine(NULL
, BOXINFO_LINE_VERT
);
4172 rLineInner
.SetTable(TRUE
);
4173 rLineInner
.SetDist(TRUE
);
4174 rLineInner
.SetMinDist(FALSE
);
4178 if (rMark
.IsMarked())
4181 rMark
.GetMarkArea(aRange
);
4182 rLineInner
.EnableHor( aRange
.aStart
.Row() != aRange
.aEnd
.Row() );
4183 rLineInner
.EnableVer( aRange
.aStart
.Col() != aRange
.aEnd
.Col() );
4184 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4185 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4186 pTab
[i
]->MergeBlockFrame( &rLineOuter
, &rLineInner
, aFlags
,
4187 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4188 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4191 // Don't care Status auswerten
4193 rLineInner
.SetValid( VALID_LEFT
, ( aFlags
.nLeft
!= SC_LINE_DONTCARE
) );
4194 rLineInner
.SetValid( VALID_RIGHT
, ( aFlags
.nRight
!= SC_LINE_DONTCARE
) );
4195 rLineInner
.SetValid( VALID_TOP
, ( aFlags
.nTop
!= SC_LINE_DONTCARE
) );
4196 rLineInner
.SetValid( VALID_BOTTOM
, ( aFlags
.nBottom
!= SC_LINE_DONTCARE
) );
4197 rLineInner
.SetValid( VALID_HORI
, ( aFlags
.nHori
!= SC_LINE_DONTCARE
) );
4198 rLineInner
.SetValid( VALID_VERT
, ( aFlags
.nVert
!= SC_LINE_DONTCARE
) );
4202 BOOL
ScDocument::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
4203 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, USHORT nMask
)
4205 if ( nMask
& HASATTR_ROTATE
)
4207 // Attribut im Dokument ueberhaupt verwendet?
4208 // (wie in fillinfo)
4210 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4212 BOOL bAnyItem
= FALSE
;
4213 USHORT nRotCount
= pPool
->GetItemCount( ATTR_ROTATE_VALUE
);
4214 for (USHORT nItem
=0; nItem
<nRotCount
; nItem
++)
4216 const SfxPoolItem
* pItem
= pPool
->GetItem( ATTR_ROTATE_VALUE
, nItem
);
4219 // 90 or 270 degrees is former SvxOrientationItem - only look for other values
4220 // (see ScPatternAttr::GetCellOrientation)
4221 INT32 nAngle
= static_cast<const SfxInt32Item
*>(pItem
)->GetValue();
4222 if ( nAngle
!= 0 && nAngle
!= 9000 && nAngle
!= 27000 )
4230 nMask
&= ~HASATTR_ROTATE
;
4233 if ( nMask
& HASATTR_RTL
)
4235 // first check if right-to left is in the pool at all
4236 // (the same item is used in cell and page format)
4238 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4240 BOOL bHasRtl
= FALSE
;
4241 USHORT nDirCount
= pPool
->GetItemCount( ATTR_WRITINGDIR
);
4242 for (USHORT nItem
=0; nItem
<nDirCount
; nItem
++)
4244 const SfxPoolItem
* pItem
= pPool
->GetItem( ATTR_WRITINGDIR
, nItem
);
4245 if ( pItem
&& ((const SvxFrameDirectionItem
*)pItem
)->GetValue() == FRMDIR_HORI_RIGHT_TOP
)
4252 nMask
&= ~HASATTR_RTL
;
4258 BOOL bFound
= FALSE
;
4259 for (SCTAB i
=nTab1
; i
<=nTab2
&& !bFound
; i
++)
4262 if ( nMask
& HASATTR_RTL
)
4264 if ( GetEditTextDirection(i
) == EE_HTEXTDIR_R2L
) // sheet default
4267 if ( nMask
& HASATTR_RIGHTORCENTER
)
4269 // On a RTL sheet, don't start to look for the default left value
4270 // (which is then logically right), instead always assume TRUE.
4271 // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets.
4273 if ( IsLayoutRTL(i
) )
4278 bFound
= pTab
[i
]->HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, nMask
);
4284 BOOL
ScDocument::HasAttrib( const ScRange
& rRange
, USHORT nMask
)
4286 return HasAttrib( rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
4287 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
4291 void ScDocument::FindMaxRotCol( SCTAB nTab
, RowInfo
* pRowInfo
, SCSIZE nArrCount
,
4292 SCCOL nX1
, SCCOL nX2
) const
4294 if ( ValidTab(nTab
) && pTab
[nTab
] )
4295 pTab
[nTab
]->FindMaxRotCol( pRowInfo
, nArrCount
, nX1
, nX2
);
4298 DBG_ERRORFILE("FindMaxRotCol: falsche Tabelle");
4302 void ScDocument::GetBorderLines( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
4303 const SvxBorderLine
** ppLeft
, const SvxBorderLine
** ppTop
,
4304 const SvxBorderLine
** ppRight
, const SvxBorderLine
** ppBottom
) const
4306 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
4308 const SvxBoxItem
* pThisAttr
= (const SvxBoxItem
*) GetEffItem( nCol
, nRow
, nTab
, ATTR_BORDER
);
4309 DBG_ASSERT(pThisAttr
,"wo ist das Attribut?");
4311 const SvxBorderLine
* pLeftLine
= pThisAttr
->GetLeft();
4312 const SvxBorderLine
* pTopLine
= pThisAttr
->GetTop();
4313 const SvxBorderLine
* pRightLine
= pThisAttr
->GetRight();
4314 const SvxBorderLine
* pBottomLine
= pThisAttr
->GetBottom();
4318 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4319 GetEffItem( nCol
-1, nRow
, nTab
, ATTR_BORDER
))->GetRight();
4320 if ( ScHasPriority( pOther
, pLeftLine
) )
4325 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4326 GetEffItem( nCol
, nRow
-1, nTab
, ATTR_BORDER
))->GetBottom();
4327 if ( ScHasPriority( pOther
, pTopLine
) )
4330 if ( nCol
< MAXCOL
)
4332 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4333 GetEffItem( nCol
+1, nRow
, nTab
, ATTR_BORDER
))->GetLeft();
4334 if ( ScHasPriority( pOther
, pRightLine
) )
4335 pRightLine
= pOther
;
4337 if ( nRow
< MAXROW
)
4339 const SvxBorderLine
* pOther
= ((const SvxBoxItem
*)
4340 GetEffItem( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
4341 if ( ScHasPriority( pOther
, pBottomLine
) )
4342 pBottomLine
= pOther
;
4346 *ppLeft
= pLeftLine
;
4350 *ppRight
= pRightLine
;
4352 *ppBottom
= pBottomLine
;
4355 BOOL
ScDocument::IsBlockEmpty( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
4356 SCCOL nEndCol
, SCROW nEndRow
, bool bIgnoreNotes
) const
4360 return pTab
[nTab
]->IsBlockEmpty( nStartCol
, nStartRow
, nEndCol
, nEndRow
, bIgnoreNotes
);
4362 DBG_ERROR("Falsche Tabellennummer");
4367 void ScDocument::LockTable(SCTAB nTab
)
4369 if ( ValidTab(nTab
) && pTab
[nTab
] )
4370 pTab
[nTab
]->LockTable();
4373 DBG_ERROR("Falsche Tabellennummer");
4378 void ScDocument::UnlockTable(SCTAB nTab
)
4380 if ( ValidTab(nTab
) && pTab
[nTab
] )
4381 pTab
[nTab
]->UnlockTable();
4384 DBG_ERROR("Falsche Tabellennummer");
4389 BOOL
ScDocument::IsBlockEditable( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
4390 SCCOL nEndCol
, SCROW nEndRow
,
4391 BOOL
* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
4393 // import into read-only document is possible
4394 if ( !bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly() )
4396 if ( pOnlyNotBecauseOfMatrix
)
4397 *pOnlyNotBecauseOfMatrix
= FALSE
;
4403 return pTab
[nTab
]->IsBlockEditable( nStartCol
, nStartRow
, nEndCol
,
4404 nEndRow
, pOnlyNotBecauseOfMatrix
);
4406 DBG_ERROR("Falsche Tabellennummer");
4407 if ( pOnlyNotBecauseOfMatrix
)
4408 *pOnlyNotBecauseOfMatrix
= FALSE
;
4413 BOOL
ScDocument::IsSelectionEditable( const ScMarkData
& rMark
,
4414 BOOL
* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
4416 // import into read-only document is possible
4417 if ( !bImportingXML
&& !mbChangeReadOnlyEnabled
&& pShell
&& pShell
->IsReadOnly() )
4419 if ( pOnlyNotBecauseOfMatrix
)
4420 *pOnlyNotBecauseOfMatrix
= FALSE
;
4425 rMark
.GetMarkArea(aRange
);
4428 BOOL bMatrix
= ( pOnlyNotBecauseOfMatrix
!= NULL
);
4429 for ( SCTAB i
=0; i
<=MAXTAB
&& (bOk
|| bMatrix
); i
++ )
4431 if ( pTab
[i
] && rMark
.GetTableSelect(i
) )
4433 if (rMark
.IsMarked())
4435 if ( !pTab
[i
]->IsBlockEditable( aRange
.aStart
.Col(),
4436 aRange
.aStart
.Row(), aRange
.aEnd
.Col(),
4437 aRange
.aEnd
.Row(), pOnlyNotBecauseOfMatrix
) )
4440 if ( pOnlyNotBecauseOfMatrix
)
4441 bMatrix
= *pOnlyNotBecauseOfMatrix
;
4444 if (rMark
.IsMultiMarked())
4446 if ( !pTab
[i
]->IsSelectionEditable( rMark
, pOnlyNotBecauseOfMatrix
) )
4449 if ( pOnlyNotBecauseOfMatrix
)
4450 bMatrix
= *pOnlyNotBecauseOfMatrix
;
4456 if ( pOnlyNotBecauseOfMatrix
)
4457 *pOnlyNotBecauseOfMatrix
= ( !bOk
&& bMatrix
);
4463 BOOL
ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol
, SCROW nStartRow
,
4464 SCCOL nEndCol
, SCROW nEndRow
,
4465 const ScMarkData
& rMark
) const
4468 for (SCTAB i
=0; i
<=MAXTAB
&& bOk
; i
++)
4470 if (rMark
.GetTableSelect(i
))
4471 if (pTab
[i
]->HasBlockMatrixFragment( nStartCol
, nStartRow
, nEndCol
, nEndRow
))
4478 BOOL
ScDocument::GetMatrixFormulaRange( const ScAddress
& rCellPos
, ScRange
& rMatrix
)
4480 // if rCell is part of a matrix formula, return its complete range
4483 ScBaseCell
* pCell
= GetCell( rCellPos
);
4484 if (pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
)
4486 ScAddress aOrigin
= rCellPos
;
4487 if ( ((ScFormulaCell
*)pCell
)->GetMatrixOrigin( aOrigin
) )
4489 if ( aOrigin
!= rCellPos
)
4490 pCell
= GetCell( aOrigin
);
4491 if (pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
)
4495 ((ScFormulaCell
*)pCell
)->GetMatColsRows(nSizeX
,nSizeY
);
4496 if ( !(nSizeX
> 0 && nSizeY
> 0) )
4498 // GetMatrixEdge computes also dimensions of the matrix
4499 // if not already done (may occur if document is loaded
4500 // from old file format).
4501 // Needs an "invalid" initialized address.
4502 aOrigin
.SetInvalid();
4503 ((ScFormulaCell
*)pCell
)->GetMatrixEdge(aOrigin
);
4504 ((ScFormulaCell
*)pCell
)->GetMatColsRows(nSizeX
,nSizeY
);
4506 if ( nSizeX
> 0 && nSizeY
> 0 )
4508 ScAddress
aEnd( aOrigin
.Col() + nSizeX
- 1,
4509 aOrigin
.Row() + nSizeY
- 1,
4512 rMatrix
.aStart
= aOrigin
;
4513 rMatrix
.aEnd
= aEnd
;
4523 BOOL
ScDocument::ExtendOverlapped( SCCOL
& rStartCol
, SCROW
& rStartRow
,
4524 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
4526 BOOL bFound
= FALSE
;
4527 if ( ValidColRow(rStartCol
,rStartRow
) && ValidColRow(nEndCol
,nEndRow
) && ValidTab(nTab
) )
4532 SCCOL nOldCol
= rStartCol
;
4533 SCROW nOldRow
= rStartRow
;
4534 for (nCol
=nOldCol
; nCol
<=nEndCol
; nCol
++)
4535 while (((ScMergeFlagAttr
*)GetAttr(nCol
,rStartRow
,nTab
,ATTR_MERGE_FLAG
))->
4541 ScAttrArray
* pAttrArray
= pTab
[nTab
]->aCol
[nOldCol
].pAttrArray
;
4543 pAttrArray
->Search( nOldRow
, nIndex
);
4544 SCROW nAttrPos
= nOldRow
;
4545 while (nAttrPos
<=nEndRow
)
4547 DBG_ASSERT( nIndex
< pAttrArray
->nCount
, "Falscher Index im AttrArray" );
4549 if (((ScMergeFlagAttr
&)pAttrArray
->pData
[nIndex
].pPattern
->
4550 GetItem(ATTR_MERGE_FLAG
)).IsHorOverlapped())
4552 SCROW nLoopEndRow
= Min( nEndRow
, pAttrArray
->pData
[nIndex
].nRow
);
4553 for (SCROW nAttrRow
= nAttrPos
; nAttrRow
<= nLoopEndRow
; nAttrRow
++)
4555 SCCOL nTempCol
= nOldCol
;
4558 while (((ScMergeFlagAttr
*)GetAttr(nTempCol
,nAttrRow
,nTab
,ATTR_MERGE_FLAG
))
4559 ->IsHorOverlapped());
4560 if (nTempCol
< rStartCol
)
4561 rStartCol
= nTempCol
;
4564 nAttrPos
= pAttrArray
->pData
[nIndex
].nRow
+ 1;
4571 DBG_ERROR("ExtendOverlapped: falscher Bereich");
4578 BOOL
ScDocument::ExtendMergeSel( SCCOL nStartCol
, SCROW nStartRow
,
4579 SCCOL
& rEndCol
, SCROW
& rEndRow
,
4580 const ScMarkData
& rMark
, BOOL bRefresh
, BOOL bAttrs
)
4582 // use all selected sheets from rMark
4584 BOOL bFound
= FALSE
;
4585 SCCOL nOldEndCol
= rEndCol
;
4586 SCROW nOldEndRow
= rEndRow
;
4588 for (SCTAB nTab
= 0; nTab
<= MAXTAB
; nTab
++)
4589 if ( pTab
[nTab
] && rMark
.GetTableSelect(nTab
) )
4591 SCCOL nThisEndCol
= nOldEndCol
;
4592 SCROW nThisEndRow
= nOldEndRow
;
4593 if ( ExtendMerge( nStartCol
, nStartRow
, nThisEndCol
, nThisEndRow
, nTab
, bRefresh
, bAttrs
) )
4595 if ( nThisEndCol
> rEndCol
)
4596 rEndCol
= nThisEndCol
;
4597 if ( nThisEndRow
> rEndRow
)
4598 rEndRow
= nThisEndRow
;
4605 BOOL
ScDocument::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
4606 SCCOL
& rEndCol
, SCROW
& rEndRow
,
4607 SCTAB nTab
, BOOL bRefresh
, BOOL bAttrs
)
4609 BOOL bFound
= FALSE
;
4610 if ( ValidColRow(nStartCol
,nStartRow
) && ValidColRow(rEndCol
,rEndRow
) && ValidTab(nTab
) )
4613 bFound
= pTab
[nTab
]->ExtendMerge( nStartCol
, nStartRow
, rEndCol
, rEndRow
, bRefresh
, bAttrs
);
4616 RefreshAutoFilter( nStartCol
, nStartRow
, rEndCol
, rEndRow
, nTab
);
4620 DBG_ERROR("ExtendMerge: falscher Bereich");
4627 BOOL
ScDocument::ExtendMerge( ScRange
& rRange
, BOOL bRefresh
, BOOL bAttrs
)
4629 BOOL bFound
= FALSE
;
4630 SCTAB nStartTab
= rRange
.aStart
.Tab();
4631 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4632 SCCOL nEndCol
= rRange
.aEnd
.Col();
4633 SCROW nEndRow
= rRange
.aEnd
.Row();
4635 PutInOrder( nStartTab
, nEndTab
);
4636 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
; nTab
++ )
4638 SCCOL nExtendCol
= rRange
.aEnd
.Col();
4639 SCROW nExtendRow
= rRange
.aEnd
.Row();
4640 if (ExtendMerge( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
4641 nExtendCol
, nExtendRow
,
4642 nTab
, bRefresh
, bAttrs
) )
4645 if (nExtendCol
> nEndCol
) nEndCol
= nExtendCol
;
4646 if (nExtendRow
> nEndRow
) nEndRow
= nExtendRow
;
4650 rRange
.aEnd
.SetCol(nEndCol
);
4651 rRange
.aEnd
.SetRow(nEndRow
);
4656 BOOL
ScDocument::ExtendTotalMerge( ScRange
& rRange
)
4658 // Bereich genau dann auf zusammengefasste Zellen erweitern, wenn
4659 // dadurch keine neuen nicht-ueberdeckten Zellen getroffen werden
4662 ScRange aExt
= rRange
;
4663 if (ExtendMerge(aExt
))
4665 if ( aExt
.aEnd
.Row() > rRange
.aEnd
.Row() )
4667 ScRange aTest
= aExt
;
4668 aTest
.aStart
.SetRow( rRange
.aEnd
.Row() + 1 );
4669 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
4670 aExt
.aEnd
.SetRow(rRange
.aEnd
.Row());
4672 if ( aExt
.aEnd
.Col() > rRange
.aEnd
.Col() )
4674 ScRange aTest
= aExt
;
4675 aTest
.aStart
.SetCol( rRange
.aEnd
.Col() + 1 );
4676 if ( HasAttrib( aTest
, HASATTR_NOTOVERLAPPED
) )
4677 aExt
.aEnd
.SetCol(rRange
.aEnd
.Col());
4680 bRet
= ( aExt
.aEnd
!= rRange
.aEnd
);
4686 BOOL
ScDocument::ExtendOverlapped( ScRange
& rRange
)
4688 BOOL bFound
= FALSE
;
4689 SCTAB nStartTab
= rRange
.aStart
.Tab();
4690 SCTAB nEndTab
= rRange
.aEnd
.Tab();
4691 SCCOL nStartCol
= rRange
.aStart
.Col();
4692 SCROW nStartRow
= rRange
.aStart
.Row();
4694 PutInOrder( nStartTab
, nEndTab
);
4695 for (SCTAB nTab
= nStartTab
; nTab
<= nEndTab
; nTab
++ )
4697 SCCOL nExtendCol
= rRange
.aStart
.Col();
4698 SCROW nExtendRow
= rRange
.aStart
.Row();
4699 ExtendOverlapped( nExtendCol
, nExtendRow
,
4700 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), nTab
);
4701 if (nExtendCol
< nStartCol
)
4703 nStartCol
= nExtendCol
;
4706 if (nExtendRow
< nStartRow
)
4708 nStartRow
= nExtendRow
;
4713 rRange
.aStart
.SetCol(nStartCol
);
4714 rRange
.aStart
.SetRow(nStartRow
);
4719 BOOL
ScDocument::RefreshAutoFilter( SCCOL nStartCol
, SCROW nStartRow
,
4720 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
4722 USHORT nCount
= pDBCollection
->GetCount();
4731 // Autofilter loeschen
4733 BOOL bChange
= RemoveFlagsTab( nStartCol
,nStartRow
, nEndCol
,nEndRow
, nTab
, SC_MF_AUTO
);
4735 // Autofilter setzen
4737 for (i
=0; i
<nCount
; i
++)
4739 pData
= (*pDBCollection
)[i
];
4740 if (pData
->HasAutoFilter())
4742 pData
->GetArea( nDBTab
, nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBEndRow
);
4743 if ( nDBTab
==nTab
&& nDBStartRow
<=nEndRow
&& nDBEndRow
>=nStartRow
&&
4744 nDBStartCol
<=nEndCol
&& nDBEndCol
>=nStartCol
)
4746 if (ApplyFlagsTab( nDBStartCol
,nDBStartRow
, nDBEndCol
,nDBStartRow
,
4747 nDBTab
, SC_MF_AUTO
))
4755 void ScDocument::SkipOverlapped( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
) const
4757 while (IsHorOverlapped(rCol
, rRow
, nTab
))
4759 while (IsVerOverlapped(rCol
, rRow
, nTab
))
4763 BOOL
ScDocument::IsHorOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4765 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
4766 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
4768 return pAttr
->IsHorOverlapped();
4771 DBG_ERROR("Overlapped: Attr==0");
4777 BOOL
ScDocument::IsVerOverlapped( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
4779 const ScMergeFlagAttr
* pAttr
= (const ScMergeFlagAttr
*)
4780 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
);
4782 return pAttr
->IsVerOverlapped();
4785 DBG_ERROR("Overlapped: Attr==0");
4791 void ScDocument::ApplySelectionFrame( const ScMarkData
& rMark
,
4792 const SvxBoxItem
* pLineOuter
,
4793 const SvxBoxInfoItem
* pLineInner
)
4795 ScRangeList aRangeList
;
4796 rMark
.FillRangeListWithMarks( &aRangeList
, FALSE
);
4797 ULONG nRangeCount
= aRangeList
.Count();
4798 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4800 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4802 for (ULONG j
=0; j
<nRangeCount
; j
++)
4804 ScRange aRange
= *aRangeList
.GetObject(j
);
4805 pTab
[i
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
4806 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4807 aRange
.aEnd
.Col(), aRange
.aEnd
.Row() );
4814 void ScDocument::ApplyFrameAreaTab( const ScRange
& rRange
,
4815 const SvxBoxItem
* pLineOuter
,
4816 const SvxBoxInfoItem
* pLineInner
)
4818 SCTAB nStartTab
= rRange
.aStart
.Tab();
4819 SCTAB nEndTab
= rRange
.aStart
.Tab();
4820 for (SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++)
4822 pTab
[nTab
]->ApplyBlockFrame( pLineOuter
, pLineInner
,
4823 rRange
.aStart
.Col(), rRange
.aStart
.Row(),
4824 rRange
.aEnd
.Col(), rRange
.aEnd
.Row() );
4828 void ScDocument::ApplySelectionPattern( const ScPatternAttr
& rAttr
, const ScMarkData
& rMark
, ScEditDataArray
* pDataArray
)
4830 const SfxItemSet
* pSet
= &rAttr
.GetItemSet();
4833 for (i
=ATTR_PATTERN_START
; i
<=ATTR_PATTERN_END
&& !bSet
; i
++)
4834 if (pSet
->GetItemState(i
) == SFX_ITEM_SET
)
4839 // ApplySelectionCache needs multi mark
4840 if ( rMark
.IsMarked() && !rMark
.IsMultiMarked() )
4843 rMark
.GetMarkArea( aRange
);
4844 ApplyPatternArea( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
4845 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), rMark
, rAttr
, pDataArray
);
4849 SfxItemPoolCache
aCache( xPoolHelper
->GetDocPool(), pSet
);
4850 for (SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++)
4852 if (rMark
.GetTableSelect(nTab
))
4853 pTab
[nTab
]->ApplySelectionCache( &aCache
, rMark
, pDataArray
);
4859 void ScDocument::ChangeSelectionIndent( BOOL bIncrement
, const ScMarkData
& rMark
)
4861 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4862 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4863 pTab
[i
]->ChangeSelectionIndent( bIncrement
, rMark
);
4867 void ScDocument::ClearSelectionItems( const USHORT
* pWhich
, const ScMarkData
& rMark
)
4869 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4870 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4871 pTab
[i
]->ClearSelectionItems( pWhich
, rMark
);
4875 void ScDocument::DeleteSelection( USHORT nDelFlag
, const ScMarkData
& rMark
)
4877 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
4878 if (pTab
[i
] && rMark
.GetTableSelect(i
))
4879 pTab
[i
]->DeleteSelection( nDelFlag
, rMark
);
4883 void ScDocument::DeleteSelectionTab( SCTAB nTab
, USHORT nDelFlag
, const ScMarkData
& rMark
)
4885 if (ValidTab(nTab
) && pTab
[nTab
])
4886 pTab
[nTab
]->DeleteSelection( nDelFlag
, rMark
);
4889 DBG_ERROR("Falsche Tabelle");
4894 ScPatternAttr
* ScDocument::GetDefPattern() const
4896 return (ScPatternAttr
*) &xPoolHelper
->GetDocPool()->GetDefaultItem(ATTR_PATTERN
);
4900 ScDocumentPool
* ScDocument::GetPool()
4902 return xPoolHelper
->GetDocPool();
4907 ScStyleSheetPool
* ScDocument::GetStyleSheetPool() const
4909 return xPoolHelper
->GetStylePool();
4913 SCSIZE
ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol
, SCROW nStartRow
, SCTAB nStartTab
,
4914 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nEndTab
, ScDirection eDir
)
4916 PutInOrder(nStartCol
, nEndCol
);
4917 PutInOrder(nStartRow
, nEndRow
);
4918 PutInOrder(nStartTab
, nEndTab
);
4919 if (VALIDTAB(nStartTab
))
4921 if (pTab
[nStartTab
])
4922 return pTab
[nStartTab
]->GetEmptyLinesInBlock(nStartCol
, nStartRow
, nEndCol
, nEndRow
, eDir
);
4931 void ScDocument::FindAreaPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, SCsCOL nMovX
, SCsROW nMovY
)
4933 if (ValidTab(nTab
) && pTab
[nTab
])
4934 pTab
[nTab
]->FindAreaPos( rCol
, rRow
, nMovX
, nMovY
);
4938 void ScDocument::GetNextPos( SCCOL
& rCol
, SCROW
& rRow
, SCTAB nTab
, SCsCOL nMovX
, SCsROW nMovY
,
4939 BOOL bMarked
, BOOL bUnprotected
, const ScMarkData
& rMark
)
4941 DBG_ASSERT( !nMovX
|| !nMovY
, "GetNextPos: nur X oder Y" );
4943 ScMarkData aCopyMark
= rMark
;
4944 aCopyMark
.SetMarking(FALSE
);
4945 aCopyMark
.MarkToMulti();
4947 if (ValidTab(nTab
) && pTab
[nTab
])
4948 pTab
[nTab
]->GetNextPos( rCol
, rRow
, nMovX
, nMovY
, bMarked
, bUnprotected
, aCopyMark
);
4952 // Datei-Operationen
4956 void ScDocument::UpdStlShtPtrsFrmNms()
4958 ScPatternAttr::pDoc
= this;
4960 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4962 USHORT nCount
= pPool
->GetItemCount(ATTR_PATTERN
);
4963 ScPatternAttr
* pPattern
;
4964 for (USHORT i
=0; i
<nCount
; i
++)
4966 pPattern
= (ScPatternAttr
*)pPool
->GetItem(ATTR_PATTERN
, i
);
4968 pPattern
->UpdateStyleSheet();
4970 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).UpdateStyleSheet();
4974 void ScDocument::StylesToNames()
4976 ScPatternAttr::pDoc
= this;
4978 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
4980 USHORT nCount
= pPool
->GetItemCount(ATTR_PATTERN
);
4981 ScPatternAttr
* pPattern
;
4982 for (USHORT i
=0; i
<nCount
; i
++)
4984 pPattern
= (ScPatternAttr
*)pPool
->GetItem(ATTR_PATTERN
, i
);
4986 pPattern
->StyleToName();
4988 ((ScPatternAttr
&)pPool
->GetDefaultItem(ATTR_PATTERN
)).StyleToName();
4992 ULONG
ScDocument::GetCellCount() const
4994 ULONG nCellCount
= 0L;
4996 for ( SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++ )
4998 nCellCount
+= pTab
[nTab
]->GetCellCount();
5004 ULONG
ScDocument::GetCodeCount() const
5006 ULONG nCodeCount
= 0;
5008 for ( SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++ )
5010 nCodeCount
+= pTab
[nTab
]->GetCodeCount();
5016 ULONG
ScDocument::GetWeightedCount() const
5018 ULONG nCellCount
= 0L;
5020 for ( SCTAB nTab
=0; nTab
<=MAXTAB
; nTab
++ )
5022 nCellCount
+= pTab
[nTab
]->GetWeightedCount();
5028 void ScDocument::PageStyleModified( SCTAB nTab
, const String
& rNewName
)
5030 if ( ValidTab(nTab
) && pTab
[nTab
] )
5031 pTab
[nTab
]->PageStyleModified( rNewName
);
5035 void ScDocument::SetPageStyle( SCTAB nTab
, const String
& rName
)
5037 if ( ValidTab(nTab
) && pTab
[nTab
] )
5038 pTab
[nTab
]->SetPageStyle( rName
);
5042 const String
& ScDocument::GetPageStyle( SCTAB nTab
) const
5044 if ( ValidTab(nTab
) && pTab
[nTab
] )
5045 return pTab
[nTab
]->GetPageStyle();
5047 return EMPTY_STRING
;
5051 void ScDocument::SetPageSize( SCTAB nTab
, const Size
& rSize
)
5053 if ( ValidTab(nTab
) && pTab
[nTab
] )
5054 pTab
[nTab
]->SetPageSize( rSize
);
5057 Size
ScDocument::GetPageSize( SCTAB nTab
) const
5059 if ( ValidTab(nTab
) && pTab
[nTab
] )
5060 return pTab
[nTab
]->GetPageSize();
5062 DBG_ERROR("falsche Tab");
5067 void ScDocument::SetRepeatArea( SCTAB nTab
, SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCROW nEndRow
)
5069 if ( ValidTab(nTab
) && pTab
[nTab
] )
5070 pTab
[nTab
]->SetRepeatArea( nStartCol
, nEndCol
, nStartRow
, nEndRow
);
5073 void ScDocument::InvalidatePageBreaks(SCTAB nTab
)
5075 if (ValidTab(nTab
) && pTab
[nTab
])
5076 pTab
[nTab
]->InvalidatePageBreaks();
5079 void ScDocument::UpdatePageBreaks( SCTAB nTab
, const ScRange
* pUserArea
)
5081 if ( ValidTab(nTab
) && pTab
[nTab
] )
5082 pTab
[nTab
]->UpdatePageBreaks( pUserArea
);
5085 void ScDocument::RemoveManualBreaks( SCTAB nTab
)
5087 if ( ValidTab(nTab
) && pTab
[nTab
] )
5088 pTab
[nTab
]->RemoveManualBreaks();
5091 BOOL
ScDocument::HasManualBreaks( SCTAB nTab
) const
5093 if ( ValidTab(nTab
) && pTab
[nTab
] )
5094 return pTab
[nTab
]->HasManualBreaks();
5096 DBG_ERROR("falsche Tab");
5101 void ScDocument::GetDocStat( ScDocStat
& rDocStat
)
5103 rDocStat
.nTableCount
= GetTableCount();
5104 rDocStat
.aDocName
= aDocName
;
5105 rDocStat
.nCellCount
= GetCellCount();
5109 BOOL
ScDocument::HasPrintRange()
5111 BOOL bResult
= FALSE
;
5113 for ( SCTAB i
=0; !bResult
&& i
<nMaxTableNumber
; i
++ )
5115 bResult
= pTab
[i
]->IsPrintEntireSheet() || (pTab
[i
]->GetPrintRangeCount() > 0);
5121 BOOL
ScDocument::IsPrintEntireSheet( SCTAB nTab
) const
5123 return (ValidTab(nTab
) ) && pTab
[nTab
] && pTab
[nTab
]->IsPrintEntireSheet();
5127 USHORT
ScDocument::GetPrintRangeCount( SCTAB nTab
)
5129 if (ValidTab(nTab
) && pTab
[nTab
])
5130 return pTab
[nTab
]->GetPrintRangeCount();
5136 const ScRange
* ScDocument::GetPrintRange( SCTAB nTab
, USHORT nPos
)
5138 if (ValidTab(nTab
) && pTab
[nTab
])
5139 return pTab
[nTab
]->GetPrintRange(nPos
);
5145 const ScRange
* ScDocument::GetRepeatColRange( SCTAB nTab
)
5147 if (ValidTab(nTab
) && pTab
[nTab
])
5148 return pTab
[nTab
]->GetRepeatColRange();
5154 const ScRange
* ScDocument::GetRepeatRowRange( SCTAB nTab
)
5156 if (ValidTab(nTab
) && pTab
[nTab
])
5157 return pTab
[nTab
]->GetRepeatRowRange();
5163 void ScDocument::ClearPrintRanges( SCTAB nTab
)
5165 if (ValidTab(nTab
) && pTab
[nTab
])
5166 pTab
[nTab
]->ClearPrintRanges();
5170 void ScDocument::AddPrintRange( SCTAB nTab
, const ScRange
& rNew
)
5172 if (ValidTab(nTab
) && pTab
[nTab
])
5173 pTab
[nTab
]->AddPrintRange( rNew
);
5177 //UNUSED2009-05 void ScDocument::SetPrintRange( SCTAB nTab, const ScRange& rNew )
5179 //UNUSED2009-05 if (ValidTab(nTab) && pTab[nTab])
5180 //UNUSED2009-05 pTab[nTab]->SetPrintRange( rNew );
5184 void ScDocument::SetPrintEntireSheet( SCTAB nTab
)
5186 if (ValidTab(nTab
) && pTab
[nTab
])
5187 pTab
[nTab
]->SetPrintEntireSheet();
5191 void ScDocument::SetRepeatColRange( SCTAB nTab
, const ScRange
* pNew
)
5193 if (ValidTab(nTab
) && pTab
[nTab
])
5194 pTab
[nTab
]->SetRepeatColRange( pNew
);
5198 void ScDocument::SetRepeatRowRange( SCTAB nTab
, const ScRange
* pNew
)
5200 if (ValidTab(nTab
) && pTab
[nTab
])
5201 pTab
[nTab
]->SetRepeatRowRange( pNew
);
5205 ScPrintRangeSaver
* ScDocument::CreatePrintRangeSaver() const
5207 SCTAB nCount
= GetTableCount();
5208 ScPrintRangeSaver
* pNew
= new ScPrintRangeSaver( nCount
);
5209 for (SCTAB i
=0; i
<nCount
; i
++)
5211 pTab
[i
]->FillPrintSaver( pNew
->GetTabData(i
) );
5216 void ScDocument::RestorePrintRanges( const ScPrintRangeSaver
& rSaver
)
5218 SCTAB nCount
= rSaver
.GetTabCount();
5219 for (SCTAB i
=0; i
<nCount
; i
++)
5221 pTab
[i
]->RestorePrintRanges( rSaver
.GetTabData(i
) );
5225 BOOL
ScDocument::NeedPageResetAfterTab( SCTAB nTab
) const
5227 // Die Seitennummern-Zaehlung faengt bei einer Tabelle neu an, wenn eine
5228 // andere Vorlage als bei der vorherigen gesetzt ist (nur Namen vergleichen)
5229 // und eine Seitennummer angegeben ist (nicht 0)
5231 if ( nTab
< MAXTAB
&& pTab
[nTab
] && pTab
[nTab
+1] )
5233 String aNew
= pTab
[nTab
+1]->GetPageStyle();
5234 if ( aNew
!= pTab
[nTab
]->GetPageStyle() )
5236 SfxStyleSheetBase
* pStyle
= xPoolHelper
->GetStylePool()->Find( aNew
, SFX_STYLE_FAMILY_PAGE
);
5239 const SfxItemSet
& rSet
= pStyle
->GetItemSet();
5240 USHORT nFirst
= ((const SfxUInt16Item
&)rSet
.Get(ATTR_PAGE_FIRSTPAGENO
)).GetValue();
5242 return TRUE
; // Seitennummer in neuer Vorlage angegeben
5247 return FALSE
; // sonst nicht
5250 SfxUndoManager
* ScDocument::GetUndoManager()
5253 mpUndoManager
= new SfxUndoManager
;
5254 return mpUndoManager
;
5258 void ScDocument::EnableUndo( bool bVal
)
5260 GetUndoManager()->EnableUndo(bVal
);
5261 mbUndoEnabled
= bVal
;