summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core')
-rw-r--r--sc/source/core/data/attarray.cxx7
-rw-r--r--sc/source/core/data/bcaslot.cxx207
-rw-r--r--sc/source/core/data/cell.cxx24
-rw-r--r--sc/source/core/data/column.cxx26
-rw-r--r--sc/source/core/data/column2.cxx19
-rw-r--r--sc/source/core/data/column3.cxx4
-rw-r--r--sc/source/core/data/dociter.cxx39
-rw-r--r--[-rwxr-xr-x]sc/source/core/data/documen2.cxx6
-rw-r--r--sc/source/core/data/documen3.cxx134
-rw-r--r--sc/source/core/data/documen7.cxx6
-rw-r--r--sc/source/core/data/documen9.cxx18
-rw-r--r--sc/source/core/data/document.cxx334
-rwxr-xr-xsc/source/core/data/dpobject.cxx10
-rwxr-xr-xsc/source/core/data/dpoutput.cxx12
-rw-r--r--sc/source/core/data/dptabresmember.cxx831
-rw-r--r--sc/source/core/data/dptabresmember.hxx161
-rw-r--r--[-rwxr-xr-x]sc/source/core/data/drwlayer.cxx34
-rw-r--r--sc/source/core/data/fillinfo.cxx34
-rw-r--r--[-rwxr-xr-x]sc/source/core/data/makefile.mk10
-rw-r--r--sc/source/core/data/olinetab.cxx22
-rw-r--r--sc/source/core/data/segmenttree.cxx582
-rwxr-xr-xsc/source/core/data/sheetevents.cxx141
-rw-r--r--sc/source/core/data/stlsheet.cxx2
-rw-r--r--sc/source/core/data/tabbgcolor.cxx62
-rw-r--r--sc/source/core/data/table1.cxx349
-rw-r--r--sc/source/core/data/table2.cxx699
-rw-r--r--sc/source/core/data/table3.cxx61
-rw-r--r--sc/source/core/data/table5.cxx810
-rw-r--r--sc/source/core/data/tabprotection.cxx37
-rw-r--r--sc/source/core/inc/bcaslot.hxx7
-rw-r--r--sc/source/core/inc/doubleref.hxx3
-rw-r--r--sc/source/core/tool/addincol.cxx5
-rw-r--r--sc/source/core/tool/chartarr.cxx76
-rw-r--r--sc/source/core/tool/compiler.cxx46
-rw-r--r--sc/source/core/tool/detfunc.cxx2
-rw-r--r--sc/source/core/tool/doubleref.cxx5
-rw-r--r--sc/source/core/tool/interpr4.cxx29
37 files changed, 3057 insertions, 1797 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 53df13b4cd62..f3443312bd4e 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -52,7 +52,7 @@
#include "markarr.hxx"
#include "rechead.hxx"
#include "globstr.hrc"
-
+#include "segmenttree.hxx"
#undef DBG_INVALIDATE
#define DBGOUTPUT(s) \
@@ -1727,8 +1727,7 @@ SCsROW ScAttrArray::GetNextUnprotected( SCsROW nRow, BOOL bUp ) const
return nRet;
}
-
-void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset )
+void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
{
SCROW nStart = 0;
SCSIZE nPos = 0;
@@ -1740,7 +1739,7 @@ void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pU
// for (SCROW nRow = nStart; nRow <= nEnd; nRow++)
// pUsed[nRow] = TRUE;
- memset( &pUsed[nStart], TRUE, nEnd-nStart+1 );
+ rUsedRows.setTrue(nStart, nEnd);
if (bReset)
{
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index 48a0e8597e1c..95482b1c624b 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -47,8 +47,10 @@
#define BCA_SLOTS_COL ((MAXCOLCOUNT_DEFINE) / 16)
#if MAXROWCOUNT_DEFINE == 32000
#define BCA_SLOTS_ROW 256
+#define BCA_SLICE 125
#else
-#define BCA_SLOTS_ROW ((MAXROWCOUNT_DEFINE) / 128)
+#define BCA_SLICE 128
+#define BCA_SLOTS_ROW ((MAXROWCOUNT_DEFINE) / BCA_SLICE)
#endif
#define BCA_SLOT_COLS ((MAXCOLCOUNT_DEFINE) / BCA_SLOTS_COL)
#define BCA_SLOT_ROWS ((MAXROWCOUNT_DEFINE) / BCA_SLOTS_ROW)
@@ -59,7 +61,7 @@
#if (BCA_SLOT_ROWS * BCA_SLOTS_ROW) != (MAXROWCOUNT_DEFINE)
#error bad BCA_SLOTS_ROW value!
#endif
-// size of slot array
+// size of slot array if linear
#define BCA_SLOTS_DEFINE (BCA_SLOTS_COL * BCA_SLOTS_ROW)
// Arbitrary 2**31/8, assuming size_t can hold at least 2^31 values and
// sizeof_ptr is at most 8 bytes. You'd probably doom your machine's memory
@@ -67,14 +69,60 @@
#if BCA_SLOTS_DEFINE > 268435456
#error BCA_SLOTS_DEFINE DOOMed!
#endif
-// type safe constant
-const SCSIZE BCA_SLOTS = BCA_SLOTS_DEFINE;
// STATIC DATA -----------------------------------------------------------
TYPEINIT1( ScHint, SfxSimpleHint );
TYPEINIT1( ScAreaChangedHint, SfxHint );
+struct ScSlotData
+{
+ SCROW nStartRow; // first row of this segment
+ SCROW nStopRow; // first row of next segment
+ SCSIZE nSlice; // slice size in this segment
+ SCSIZE nCumulated; // cumulated slots of previous segments
+
+ ScSlotData( SCROW r1, SCROW r2, SCSIZE s, SCSIZE c ) : nStartRow(r1), nStopRow(r2), nSlice(s), nCumulated(c) {}
+};
+typedef ::std::vector< ScSlotData > ScSlotDistribution;
+#if MAXROWCOUNT_DEFINE <= 65536
+// Linear distribution.
+static ScSlotDistribution aSlotDistribution( ScSlotData( 0, MAXROWCOUNT, BCA_SLOT_ROWS, 0));
+static SCSIZE nBcaSlotsRow = BCA_SLOTS_ROW;
+static SCSIZE nBcaSlots = BCA_SLOTS_DEFINE;
+#else
+// Logarithmic or any other distribution.
+// Upper sheet part usually is more populated and referenced and gets fine
+// grained resolution, larger data in larger hunks.
+// Could be further enhanced by also applying a different distribution of
+// column slots.
+static SCSIZE initSlotDistribution( ScSlotDistribution & rSD, SCSIZE & rBSR )
+{
+ SCSIZE nSlots = 0;
+ SCROW nRow1 = 0;
+ SCROW nRow2 = 32*1024;
+ SCSIZE nSlice = 128;
+ // Must be sorted by row1,row2!
+ while (nRow2 <= MAXROWCOUNT)
+ {
+ //fprintf( stderr, "r1,r2,slice,cum: %7zu, %7zu, %7zu, %7zu\n", (size_t)nRow1, (size_t)nRow2, (size_t)nSlice, (size_t)nSlots);
+ // {0,32k,128,0;32k,64k,256,0+256;64k,128k,512,0+256+128;128k,256k,1024,0+256+128+128;256k,512k,2048,...;512k,1M,4096,...}
+ rSD.push_back( ScSlotData( nRow1, nRow2, nSlice, nSlots));
+ nSlots += (nRow2 - nRow1) / nSlice;
+ nRow1 = nRow2;
+ nRow2 *= 2;
+ nSlice *= 2;
+ }
+ //fprintf( stderr, "Slices: %zu, slots per sheet: %zu, memory per referenced sheet: %zu\n", (size_t) nSlots, (size_t) nSlots * BCA_SLOTS_COL, (size_t) nSlots * BCA_SLOTS_COL * sizeof(void*));
+ rBSR = nSlots;
+ return nSlots;
+}
+static ScSlotDistribution aSlotDistribution;
+static SCSIZE nBcaSlotsRow;
+static SCSIZE nBcaSlots = initSlotDistribution( aSlotDistribution, nBcaSlotsRow) * BCA_SLOTS_COL;
+// Ensure that all static variables are initialized with this one call.
+#endif
+
ScBroadcastAreaSlot::ScBroadcastAreaSlot( ScDocument* pDocument,
ScBroadcastAreaSlotMachine* pBASMa ) :
@@ -393,14 +441,14 @@ void ScBroadcastAreaSlot::UpdateInsert( ScBroadcastArea* pArea )
ScBroadcastAreaSlotMachine::TableSlots::TableSlots()
{
- ppSlots = new ScBroadcastAreaSlot* [ BCA_SLOTS ];
- memset( ppSlots, 0 , sizeof( ScBroadcastAreaSlot* ) * BCA_SLOTS );
+ ppSlots = new ScBroadcastAreaSlot* [ nBcaSlots ];
+ memset( ppSlots, 0 , sizeof( ScBroadcastAreaSlot* ) * nBcaSlots );
}
ScBroadcastAreaSlotMachine::TableSlots::~TableSlots()
{
- for ( ScBroadcastAreaSlot** pp = ppSlots + BCA_SLOTS; --pp >= ppSlots; /* nothing */ )
+ for ( ScBroadcastAreaSlot** pp = ppSlots + nBcaSlots; --pp >= ppSlots; /* nothing */ )
{
if (*pp)
delete *pp;
@@ -417,16 +465,16 @@ ScBroadcastAreaSlotMachine::ScBroadcastAreaSlotMachine(
pEOUpdateChain( NULL ),
nInBulkBroadcast( 0 )
{
- for (TableSlotsMap::iterator iTab( aTableSlotsMap.begin());
- iTab != aTableSlotsMap.end(); ++iTab)
- {
- delete (*iTab).second;
- }
}
ScBroadcastAreaSlotMachine::~ScBroadcastAreaSlotMachine()
{
+ for (TableSlotsMap::iterator iTab( aTableSlotsMap.begin());
+ iTab != aTableSlotsMap.end(); ++iTab)
+ {
+ delete (*iTab).second;
+ }
delete pBCAlways;
}
@@ -438,13 +486,21 @@ inline SCSIZE ScBroadcastAreaSlotMachine::ComputeSlotOffset(
SCCOL nCol = rAddress.Col();
if ( !ValidRow(nRow) || !ValidCol(nCol) )
{
- DBG_ASSERT( FALSE, "Row/Col ungueltig!" );
+ DBG_ERRORFILE( "Row/Col invalid, using first slot!" );
return 0;
}
- else
- return
- static_cast<SCSIZE>(nRow) / BCA_SLOT_ROWS +
- static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * BCA_SLOTS_ROW;
+ for (size_t i=0; i < aSlotDistribution.size(); ++i)
+ {
+ if (nRow < aSlotDistribution[i].nStopRow)
+ {
+ const ScSlotData& rSD = aSlotDistribution[i];
+ return rSD.nCumulated +
+ (static_cast<SCSIZE>(nRow - rSD.nStartRow)) / rSD.nSlice +
+ static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * nBcaSlotsRow;
+ }
+ }
+ DBG_ERRORFILE( "No slot found, using last!" );
+ return nBcaSlots - 1;
}
@@ -459,9 +515,28 @@ void ScBroadcastAreaSlotMachine::ComputeAreaPoints( const ScRange& rRange,
}
+inline void ComputeNextSlot( SCSIZE & nOff, SCSIZE & nBreak, ScBroadcastAreaSlot** & pp,
+ SCSIZE & nStart, ScBroadcastAreaSlot** const & ppSlots, SCSIZE const & nRowBreak )
+{
+ if ( nOff < nBreak )
+ {
+ ++nOff;
+ ++pp;
+ }
+ else
+ {
+ nStart += nBcaSlotsRow;
+ nOff = nStart;
+ pp = ppSlots + nOff;
+ nBreak = nOff + nRowBreak;
+ }
+}
+
+
void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange,
SvtListener* pListener )
{
+ //fprintf( stderr, "StartListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab());
if ( rRange == BCA_LISTEN_ALWAYS )
{
if ( !pBCAlways )
@@ -500,18 +575,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange,
}
else
(*pp)->InsertListeningArea( pArea);
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
}
@@ -521,6 +585,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange,
void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange,
SvtListener* pListener )
{
+ //fprintf( stderr, "EndListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab());
if ( rRange == BCA_LISTEN_ALWAYS )
{
DBG_ASSERT( pBCAlways, "ScBroadcastAreaSlotMachine::EndListeningArea: BCA_LISTEN_ALWAYS but none established");
@@ -547,7 +612,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange,
SCSIZE nBreak = nOff + nRowBreak;
ScBroadcastAreaSlot** pp = ppSlots + nOff;
ScBroadcastArea* pArea = NULL;
- if (nOff == 0 && nEnd == BCA_SLOTS-1)
+ if (nOff == 0 && nEnd == nBcaSlots-1)
{
// Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
// happen for insertion and deletion of sheets.
@@ -564,18 +629,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange,
{
if ( *pp )
(*pp)->EndListeningArea( rRange, pListener, pArea );
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
}
@@ -629,18 +683,7 @@ BOOL ScBroadcastAreaSlotMachine::AreaBroadcastInRange( const ScRange& rRange,
{
if ( *pp )
bBroadcasted |= (*pp)->AreaBroadcastInRange( rRange, rHint );
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
return bBroadcasted;
@@ -660,7 +703,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange(
SCSIZE nOff = nStart;
SCSIZE nBreak = nOff + nRowBreak;
ScBroadcastAreaSlot** pp = ppSlots + nOff;
- if (nOff == 0 && nEnd == BCA_SLOTS-1)
+ if (nOff == 0 && nEnd == nBcaSlots-1)
{
// Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
// happen for insertion and deletion of sheets.
@@ -677,18 +720,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange(
{
if ( *pp )
(*pp)->DelBroadcastAreasInRange( rRange );
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
}
@@ -711,7 +743,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
SCSIZE nOff = nStart;
SCSIZE nBreak = nOff + nRowBreak;
ScBroadcastAreaSlot** pp = ppSlots + nOff;
- if (nOff == 0 && nEnd == BCA_SLOTS-1)
+ if (nOff == 0 && nEnd == nBcaSlots-1)
{
// Slightly optimized for 0,0,MAXCOL,MAXROW calls as they
// happen for insertion and deletion of sheets.
@@ -728,18 +760,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
{
if ( *pp )
(*pp)->UpdateRemove( eUpdateRefMode, rRange, nDx, nDy, nDz );
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
}
@@ -771,18 +792,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
{
if (*pp)
(*pp)->UpdateRemoveArea( pArea);
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
@@ -876,18 +886,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas(
if (!*pp)
*pp = new ScBroadcastAreaSlot( pDoc, this );
(*pp)->UpdateInsert( pArea );
- if ( nOff < nBreak )
- {
- ++nOff;
- ++pp;
- }
- else
- {
- nStart += BCA_SLOTS_ROW;
- nOff = nStart;
- pp = ppSlots + nOff;
- nBreak = nOff + nRowBreak;
- }
+ ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index a70a9b86e186..aa492630ab0e 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -277,21 +277,21 @@ void ScBaseCell::StartListeningTo( ScDocument* pDoc )
if ( rRef1.IsColRel() )
{ // ColName
pDoc->StartListeningArea( ScRange (
- 0,
+ rRef1.nCol,
rRef1.nRow,
rRef1.nTab,
- MAXCOL,
- rRef2.nRow,
+ rRef2.nCol,
+ MAXROW,
rRef2.nTab ), pFormCell );
}
else
{ // RowName
pDoc->StartListeningArea( ScRange (
rRef1.nCol,
- 0,
+ rRef1.nRow,
rRef1.nTab,
- rRef2.nCol,
- MAXROW,
+ MAXCOL,
+ rRef2.nRow,
rRef2.nTab ), pFormCell );
}
}
@@ -367,21 +367,21 @@ void ScBaseCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr,
if ( rRef1.IsColRel() )
{ // ColName
pDoc->EndListeningArea( ScRange (
- 0,
+ rRef1.nCol,
rRef1.nRow,
rRef1.nTab,
- MAXCOL,
- rRef2.nRow,
+ rRef2.nCol,
+ MAXROW,
rRef2.nTab ), pFormCell );
}
else
{ // RowName
pDoc->EndListeningArea( ScRange (
rRef1.nCol,
- 0,
+ rRef1.nRow,
rRef1.nTab,
- rRef2.nCol,
- MAXROW,
+ MAXCOL,
+ rRef2.nRow,
rRef2.nTab ), pFormCell );
}
}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 6a5fe824197b..e9fd26ced939 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -600,13 +600,11 @@ const ScStyleSheet* ScColumn::GetAreaStyle( BOOL& rFound, SCROW nRow1, SCROW nRo
return bEqual ? pStyle : NULL;
}
-
-void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset )
+void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
{
- pAttrArray->FindStyleSheet( pStyleSheet, pUsed, bReset );
+ pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset );
}
-
BOOL ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const
{
return pAttrArray->IsStyleSheetUsed( rStyle, bGatherAllStyles );
@@ -893,11 +891,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
SvtBroadcaster* pBC2 = pCell2->ReleaseBroadcaster();
pCell1->TakeBroadcaster( pBC2 );
pCell2->TakeBroadcaster( pBC1 );
-
- ScHint aHint1( SC_HINT_DATACHANGED, aPos1, pCell2 );
- pDocument->Broadcast( aHint1 );
- ScHint aHint2( SC_HINT_DATACHANGED, aPos2, pCell1 );
- pDocument->Broadcast( aHint2 );
}
else
{
@@ -918,7 +911,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
// insert ColEntry at new position
Insert( nRow2, pCell1 );
- pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos1, pDummyCell ) );
}
return;
@@ -999,14 +991,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
Delete( nRow2 ); // deletes pCell2
else if ( pNew2 )
Insert( nRow2, pNew2 ); // deletes pCell2 (if existing), inserts pNew2
-
- // #64122# Bei Formeln hinterher nochmal broadcasten, damit die Formel nicht in irgendwelchen
- // FormulaTrack-Listen landet, ohne die Broadcaster beruecksichtigt zu haben
- // (erst hier, wenn beide Zellen eingefuegt sind)
- if ( pBC1 && pFmlaCell2 )
- pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos1, pNew1 ) );
- if ( pBC2 && pFmlaCell1 )
- pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos2, pNew2 ) );
}
@@ -1402,7 +1386,7 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
// Dies ist die Szenario-Tabelle, die Daten werden hineinkopiert
ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
- SCROW nStart, nEnd;
+ SCROW nStart = -1, nEnd = -1;
const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
while (pPattern)
{
@@ -1433,7 +1417,7 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
// Dies ist die Szenario-Tabelle, die Daten werden in die andere kopiert
ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
- SCROW nStart, nEnd;
+ SCROW nStart = -1, nEnd = -1;
const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
while (pPattern)
{
@@ -1482,7 +1466,7 @@ void ScColumn::MarkScenarioIn( ScMarkData& rDestMark ) const
ScRange aRange( nCol, 0, nTab );
ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
- SCROW nStart, nEnd;
+ SCROW nStart = -1, nEnd = -1;
const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
while (pPattern)
{
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 4c8de67ba271..2adf6d926f0f 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -66,6 +66,7 @@
#include "compiler.hxx" // ScTokenArray GetCodeLen
#include "dbcolect.hxx"
#include "fillinfo.hxx"
+#include "segmenttree.hxx"
#include <math.h>
@@ -760,8 +761,8 @@ void ScColumn::GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight
{
ScAttrIterator aIter( pAttrArray, nStartRow, nEndRow );
- SCROW nStart;
- SCROW nEnd;
+ SCROW nStart = -1;
+ SCROW nEnd = -1;
SCROW nEditPos = 0;
SCROW nNextEnd = 0;
@@ -1407,11 +1408,11 @@ BOOL ScColumn::GetPrevDataPos(SCROW& rRow) const
return bFound;
}
-BOOL ScColumn::GetNextDataPos(SCROW& rRow) const // groesser als rRow
+BOOL ScColumn::GetNextDataPos(SCROW& rRow) const // greater than rRow
{
SCSIZE nIndex;
if (Search( rRow, nIndex ))
- ++nIndex; // naechste Zelle
+ ++nIndex; // next cell
BOOL bMore = ( nIndex < nCount );
if ( bMore )
@@ -1782,7 +1783,7 @@ void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell )
// Mehrfachselektion:
void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
ScFunctionData& rData,
- const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags,
+ ScFlatBoolRowSegments& rHiddenRows,
BOOL bDoExclude, SCROW nExStartRow, SCROW nExEndRow )
{
SCSIZE nIndex;
@@ -1790,7 +1791,8 @@ void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
while (aDataIter.Next( nIndex ))
{
SCROW nRow = pItems[nIndex].nRow;
- if ( !pRowFlags || !( pRowFlags->GetValue(nRow) & CR_HIDDEN ) )
+ bool bRowHidden = rHiddenRows.getValue(nRow);
+ if ( !bRowHidden )
if ( !bDoExclude || nRow < nExStartRow || nRow > nExEndRow )
lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
}
@@ -1798,7 +1800,7 @@ void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark,
// bei bNoMarked die Mehrfachselektion weglassen
void ScColumn::UpdateAreaFunction( ScFunctionData& rData,
- const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags,
+ ScFlatBoolRowSegments& rHiddenRows,
SCROW nStartRow, SCROW nEndRow )
{
SCSIZE nIndex;
@@ -1806,7 +1808,8 @@ void ScColumn::UpdateAreaFunction( ScFunctionData& rData,
while ( nIndex<nCount && pItems[nIndex].nRow<=nEndRow )
{
SCROW nRow = pItems[nIndex].nRow;
- if ( !pRowFlags || !( pRowFlags->GetValue(nRow) & CR_HIDDEN ) )
+ bool bRowHidden = rHiddenRows.getValue(nRow);
+ if ( !bRowHidden )
lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
++nIndex;
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index be7211138c1d..65e896c7f2c4 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1648,8 +1648,8 @@ BOOL ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, B
void ScColumn::RemoveProtected( SCROW nStartRow, SCROW nEndRow )
{
ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow );
- SCROW nTop;
- SCROW nBottom;
+ SCROW nTop = -1;
+ SCROW nBottom = -1;
SCSIZE nIndex;
const ScPatternAttr* pPattern = aAttrIter.Next( nTop, nBottom );
while (pPattern)
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 706783579a24..aa5b011da93b 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -49,6 +49,7 @@
using ::rtl::math::approxEqual;
using ::std::vector;
using ::rtl::OUString;
+using ::std::set;
// STATIC DATA -----------------------------------------------------------
@@ -345,7 +346,7 @@ BOOL ScValueIterator::GetThis(double& rValue, USHORT& rErr)
if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
{
nRow = pCol->pItems[nColRow].nRow + 1;
- if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow-1 ) )
+ if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow-1 ) )
{
ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
++nColRow;
@@ -940,11 +941,6 @@ ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryPar
}
}
-bool ScDBQueryDataIterator::GetThis(Value& rValue)
-{
- return mpData->getCurrent(rValue);
-}
-
bool ScDBQueryDataIterator::GetFirst(Value& rValue)
{
return mpData->getFirst(rValue);
@@ -1071,7 +1067,7 @@ ScBaseCell* ScCellIterator::GetThis()
if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
{
nRow = pCol->pItems[nColRow].nRow;
- if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow ) )
+ if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow ) )
{
ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
@@ -1259,14 +1255,6 @@ ScBaseCell* ScQueryCellIterator::GetNext()
return GetThis();
}
-ULONG ScQueryCellIterator::GetNumberFormat()
-{
- ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
- lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
- nAttrEndRow, pCol->pAttrArray, nRow, pDoc );
- return nNumFormat;
-}
-
void ScQueryCellIterator::AdvanceQueryParamEntryField()
{
SCSIZE nEntries = aParam.GetEntryCount();
@@ -2147,3 +2135,24 @@ const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
return NULL; // is nix mehr
}
+// ============================================================================
+
+SCROW ScRowBreakIterator::NOT_FOUND = -1;
+
+ScRowBreakIterator::ScRowBreakIterator(set<SCROW>& rBreaks) :
+ mrBreaks(rBreaks),
+ maItr(rBreaks.begin()), maEnd(rBreaks.end())
+{
+}
+
+SCROW ScRowBreakIterator::first()
+{
+ maItr = mrBreaks.begin();
+ return maItr == maEnd ? NOT_FOUND : *maItr;
+}
+
+SCROW ScRowBreakIterator::next()
+{
+ ++maItr;
+ return maItr == maEnd ? NOT_FOUND : *maItr;
+}
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index c5922aa88dcc..e8ea10f7cf52 100755..100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -188,11 +188,11 @@ ScDocument::ScDocument( ScDocumentMode eMode,
// bNoSetDirty( TRUE ),
bNoSetDirty( FALSE ),
bInsertingFromOtherDoc( FALSE ),
- bImportingXML( FALSE ),
+ bLoadingMedium( false ),
+ bImportingXML( false ),
bXMLFromWrapper( FALSE ),
bCalcingAfterLoad( FALSE ),
bNoListening( FALSE ),
- bLoadingDone( TRUE ),
bIdleDisabled( FALSE ),
bInLinkUpdate( FALSE ),
bChartListenerCollectionNeedsUpdate( FALSE ),
@@ -897,6 +897,8 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
SetNoListening( TRUE ); // noch nicht bei CopyToTable/Insert
pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
pTab[nNewPos], pOnlyMarked );
+ pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor());
+
SCsTAB nDz;
/* if (nNewPos < nOldPos)
nDz = ((short)nNewPos) - (short)nOldPos + 1;
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 77f59254e049..1861988d78aa 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -83,6 +83,7 @@
#include "tabprotection.hxx"
#include "formulaparserpool.hxx"
#include "clipparam.hxx"
+#include "sheetevents.hxx"
#include <memory>
@@ -285,6 +286,26 @@ void ScDocument::SetScenarioData( SCTAB nTab, const String& rComment,
}
}
+Color ScDocument::GetTabBgColor( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetTabBgColor();
+ return Color(COL_AUTO);
+}
+
+void ScDocument::SetTabBgColor( SCTAB nTab, const Color& rColor )
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->SetTabBgColor(rColor);
+}
+
+bool ScDocument::IsDefaultTabBgColor( SCTAB nTab ) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return pTab[nTab]->GetTabBgColor() == COL_AUTO;
+ return true;
+}
+
void ScDocument::GetScenarioData( SCTAB nTab, String& rComment,
Color& rColor, USHORT& rFlags ) const
{
@@ -478,6 +499,52 @@ ScFormulaParserPool& ScDocument::GetFormulaParserPool() const
return *mxFormulaParserPool;
}
+const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetSheetEvents();
+ return NULL;
+}
+
+void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew )
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ pTab[nTab]->SetSheetEvents( pNew );
+}
+
+bool ScDocument::HasSheetEventScript( sal_Int32 nEvent ) const
+{
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if (pTab[nTab])
+ {
+ const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents();
+ if ( pEvents && pEvents->GetScript( nEvent ) )
+ return true;
+ }
+ return false;
+}
+
+BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const
+{
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetCalcNotification();
+ return FALSE;
+}
+
+void ScDocument::SetCalcNotification( SCTAB nTab )
+{
+ // set only if not set before
+ if (VALIDTAB(nTab) && pTab[nTab] && !pTab[nTab]->GetCalcNotification())
+ pTab[nTab]->SetCalcNotification(TRUE);
+}
+
+void ScDocument::ResetCalcNotifications()
+{
+ for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++)
+ if (pTab[nTab] && pTab[nTab]->GetCalcNotification())
+ pTab[nTab]->SetCalcNotification(FALSE);
+}
+
ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate )
{
ScOutlineTable* pVal = NULL;
@@ -1123,15 +1190,6 @@ BOOL ScDocument::SearchAndReplace(const SvxSearchItem& rSearchItem,
return bFound;
}
-BOOL ScDocument::IsFiltered( SCROW nRow, SCTAB nTab ) const
-{
- if (VALIDTAB(nTab))
- if (pTab[nTab])
- return pTab[nTab]->IsFiltered( nRow );
- DBG_ERROR("Falsche Tabellennummer");
- return 0;
-}
-
// Outline anpassen
BOOL ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow )
@@ -1544,46 +1602,43 @@ ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
SCROW nY1 = 0;
- ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter(
- *(pTable->GetRowFlagsArray()), nY1, MAXROW, CR_HIDDEN, 0,
- *(pTable->GetRowHeightArray()));
bEnd = FALSE;
- while (!bEnd && aIter)
+ for (SCROW i = nY1; i <= MAXROW && !bEnd; ++i)
{
- nY1 = aIter.GetPos();
- nAdd = (long) *aIter;
+ if (pTable->RowHidden(i))
+ continue;
+
+ nY1 = i;
+ nAdd = static_cast<long>(pTable->GetRowHeight(i));
if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
{
nSize += nAdd;
++nY1;
- ++aIter;
}
else
bEnd = TRUE;
}
- if (!aIter)
- nY1 = aIter.GetIterEnd(); // all hidden down to the bottom
+ if (!bEnd)
+ nY1 = MAXROW; // all hidden down to the bottom
nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS);
SCROW nY2 = nY1;
- aIter.NewLimits( nY2, MAXROW);
bEnd = FALSE;
- while (!bEnd && aIter)
+ for (SCROW i = nY2; i <= MAXROW && !bEnd; ++i)
{
- nY2 = aIter.GetPos();
- nAdd = (long) *aIter;
+ nY2 = i;
+ nAdd = static_cast<long>(pTable->GetRowHeight(i));
if (nSize+nAdd < nTwips && nY2<MAXROW)
{
nSize += nAdd;
++nY2;
- ++aIter;
}
else
bEnd = TRUE;
}
- if (!aIter)
- nY2 = aIter.GetIterEnd(); // all hidden down to the bottom
+ if (!bEnd)
+ nY2 = MAXROW; // all hidden down to the bottom
return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
}
@@ -1621,24 +1676,33 @@ void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow )
SCROW nRow = 0;
long nTwips = (long) (rVal / HMM_PER_TWIPS);
long nSnap = 0;
- ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter(
- *(pTable->GetRowFlagsArray()), nRow, MAXROW, CR_HIDDEN, 0,
- *(pTable->GetRowHeightArray()));
- while ( aIter )
+
+ bool bFound = false;
+ for (SCROW i = nRow; i <= MAXROW; ++i)
{
- nRow = aIter.GetPos();
- long nAdd = *aIter;
+ SCROW nLastRow;
+ if (pTable->RowHidden(i, NULL, &nLastRow))
+ {
+ i = nLastRow;
+ continue;
+ }
+
+ nRow = i;
+ long nAdd = pTable->GetRowHeight(i);
if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow )
{
nSnap += nAdd;
++nRow;
- ++aIter;
}
else
+ {
+ bFound = true;
break;
+ }
}
- if (!aIter)
+ if (!bFound)
nRow = MAXROW; // all hidden down to the bottom
+
rVal = (long) ( nSnap * HMM_PER_TWIPS );
rStartRow = nRow;
}
@@ -1796,14 +1860,14 @@ Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow,
for (i=0; i<nStartCol; i++)
aRect.Left() += GetColWidth(i,nTab);
- aRect.Top() += FastGetRowHeight( 0, nStartRow-1, nTab);
+ aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab);
aRect.Right() = aRect.Left();
aRect.Bottom() = aRect.Top();
for (i=nStartCol; i<=nEndCol; i++)
aRect.Right() += GetColWidth(i,nTab);
- aRect.Bottom() += FastGetRowHeight( nStartRow, nEndRow, nTab);
+ aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab);
aRect.Left() = (long)(aRect.Left() * HMM_PER_TWIPS);
aRect.Right() = (long)(aRect.Right() * HMM_PER_TWIPS);
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index ad2ec90379df..97aae44f1a7b 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -52,6 +52,7 @@
#include "scmod.hxx" // SC_MOD
#include "inputopt.hxx" // GetExpandRefs
#include "conditio.hxx"
+#include "sheetevents.hxx"
#include <tools/shl.hxx>
@@ -452,6 +453,8 @@ void ScDocument::TrackFormulas( ULONG nHintId )
if ( pFormulaTrack )
{
erBEEPER();
+ // outside the loop, check if any sheet has a "calculate" event script
+ bool bCalcEvent = HasSheetEventScript( SC_SHEETEVENT_CALCULATE );
SvtBroadcaster* pBC;
ScFormulaCell* pTrack;
ScFormulaCell* pNext;
@@ -465,6 +468,9 @@ void ScDocument::TrackFormulas( ULONG nHintId )
// Repaint fuer bedingte Formate mit relativen Referenzen:
if ( pCondFormList )
pCondFormList->SourceChanged( pTrack->aPos );
+ // for "calculate" event, keep track of which sheets are affected by tracked formulas
+ if ( bCalcEvent )
+ SetCalcNotification( pTrack->aPos.Tab() );
pTrack = pTrack->GetNextTrack();
} while ( pTrack );
pTrack = pFormulaTrack;
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 9da788fca01c..abef7d53c2af 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -67,7 +67,7 @@
#include "charthelper.hxx"
using namespace ::com::sun::star;
-
+#include <stdio.h>
// -----------------------------------------------------------------------
@@ -722,7 +722,19 @@ void ScDocument::UpdateFontCharSet()
}
}
-void ScDocument::SetImportingXML( BOOL bVal )
+void ScDocument::SetLoadingMedium( bool bVal )
+{
+ bLoadingMedium = bVal;
+ for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
+ {
+ if (!pTab[nTab])
+ return;
+
+ pTab[nTab]->SetLoadingMedium(bVal);
+ }
+}
+
+void ScDocument::SetImportingXML( bool bVal )
{
bImportingXML = bVal;
if (pDrawLayer)
@@ -739,6 +751,8 @@ void ScDocument::SetImportingXML( BOOL bVal )
SetLayoutRTL( nTab, TRUE ); // includes mirroring; bImportingXML must be cleared first
}
}
+
+ SetLoadingMedium(bVal);
}
void ScDocument::SetXMLFromWrapper( BOOL bVal )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 7c08c4327183..bef4cbf87396 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -52,6 +52,7 @@
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/script/XVBACompat.hpp>
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
#include "document.hxx"
#include "table.hxx"
@@ -94,8 +95,12 @@
#include "clipparam.hxx"
#include <map>
+#include <limits>
namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::sheet::TablePageBreakData;
+using ::std::set;
struct ScDefaultAttr
{
@@ -125,6 +130,7 @@ void ScDocument::MakeTable( SCTAB nTab,bool _bNeedsNameCheck )
CreateValidTabName( aString ); // keine doppelten
pTab[nTab] = new ScTable(this, nTab, aString);
+ pTab[nTab]->SetLoadingMedium(bLoadingMedium);
++nMaxTableNumber;
}
}
@@ -2009,9 +2015,6 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
while ( nFlagTab < MAXTAB && !ppClipTab[nFlagTab] )
++nFlagTab;
- const ScBitMaskCompressedArray< SCROW, BYTE> & rSourceFlags =
- pCBFCP->pClipDoc->GetRowFlagsArray( nFlagTab);
-
SCROW nSourceRow = rClipStartRow;
SCROW nSourceEnd = 0;
if (pCBFCP->pClipDoc->GetClipParam().maRanges.Count())
@@ -2021,12 +2024,15 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
{
// skip filtered rows
- nSourceRow = rSourceFlags.GetFirstForCondition( nSourceRow, nSourceEnd, CR_FILTERED, 0);
+ nSourceRow = pCBFCP->pClipDoc->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
if ( nSourceRow <= nSourceEnd )
{
// look for more non-filtered rows following
- SCROW nFollow = rSourceFlags.GetBitStateEnd( nSourceRow, CR_FILTERED, 0) - nSourceRow;
+ SCROW nLastRow = nSourceRow;
+ pCBFCP->pClipDoc->RowFiltered(nSourceRow, nFlagTab, NULL, &nLastRow);
+ SCROW nFollow = nLastRow - nSourceRow;
+
if (nFollow > nSourceEnd - nSourceRow)
nFollow = nSourceEnd - nSourceRow;
if (nFollow > nRow2 - nDestRow)
@@ -2434,8 +2440,7 @@ void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered
while ( nCountTab < MAXTAB && !pTab[nCountTab] )
++nCountTab;
- SCROW nResult = GetRowFlagsArray( nCountTab).CountForCondition(
- nStartRow, nEndRow, CR_FILTERED, 0);
+ SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab);
if ( nResult > 0 )
nClipY = nResult - 1;
@@ -2474,8 +2479,13 @@ BOOL ScDocument::HasClipFilteredRows()
if (!rClipRanges.Count())
return false;
- return GetRowFlagsArray( nCountTab).HasCondition( rClipRanges.First()->aStart.Row(),
- rClipRanges.First()->aEnd.Row(), CR_FILTERED, CR_FILTERED);
+ for (ScRange* p = rClipRanges.First(); p; p = rClipRanges.Next())
+ {
+ bool bAnswer = pTab[nCountTab]->HasFilteredRows(p->aStart.Row(), p->aEnd.Row());
+ if (bAnswer)
+ return true;
+ }
+ return false;
}
@@ -3098,6 +3108,11 @@ void ScDocument::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab,
( nStartRow, nEndRow, nNewHeight, 1.0, 1.0 );
}
+void ScDocument::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nNewHeight )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetRowHeightOnly( nStartRow, nEndRow, nNewHeight );
+}
void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual )
{
@@ -3142,10 +3157,10 @@ USHORT ScDocument::GetOriginalHeight( SCROW nRow, SCTAB nTab ) const
}
-USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab ) const
+USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const
{
if ( ValidTab(nTab) && pTab[nTab] )
- return pTab[nTab]->GetRowHeight( nRow );
+ return pTab[nTab]->GetRowHeight( nRow, NULL, NULL, bHiddenAsZero );
DBG_ERROR("Falsche Tabellennummer");
return 0;
}
@@ -3167,11 +3182,9 @@ ULONG ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) con
return 0;
}
-ULONG ScDocument::FastGetRowHeight( SCROW nStartRow, SCROW nEndRow,
- SCTAB nTab ) const
+SCROW ScDocument::GetRowForHeight( SCTAB nTab, ULONG nHeight ) const
{
- return pTab[nTab]->pRowFlags->SumCoupledArrayForCondition( nStartRow,
- nEndRow, CR_HIDDEN, 0, *(pTab[nTab]->pRowHeight));
+ return pTab[nTab]->GetRowForHeight(nHeight);
}
ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
@@ -3192,29 +3205,6 @@ ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
return 0;
}
-
-const ScSummableCompressedArray< SCROW, USHORT> & ScDocument::GetRowHeightArray(
- SCTAB nTab ) const
-{
- const ScSummableCompressedArray< SCROW, USHORT> * pHeight;
- if ( ValidTab(nTab) && pTab[nTab] )
- pHeight = pTab[nTab]->GetRowHeightArray();
- else
- {
- DBG_ERROR("wrong sheet number");
- pHeight = 0;
- }
- if (!pHeight)
- {
- DBG_ERROR("no row heights at sheet");
- static ScSummableCompressedArray< SCROW, USHORT> aDummy( MAXROW,
- ScGlobal::nStdRowHeight);
- pHeight = &aDummy;
- }
- return *pHeight;
-}
-
-
SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const
{
if ( ValidTab(nTab) && pTab[nTab] )
@@ -3397,6 +3387,259 @@ const ScBitMaskCompressedArray< SCROW, BYTE> & ScDocument::GetRowFlagsArray(
return *pFlags;
}
+void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->GetAllRowBreaks(rBreaks, bPage, bManual);
+}
+
+void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->GetAllColBreaks(rBreaks, bPage, bManual);
+}
+
+ScBreakType ScDocument::HasRowBreak(SCROW nRow, SCTAB nTab) const
+{
+ ScBreakType nType = BREAK_NONE;
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return nType;
+
+ if (pTab[nTab]->HasRowPageBreak(nRow))
+ nType |= BREAK_PAGE;
+
+ if (pTab[nTab]->HasRowManualBreak(nRow))
+ nType |= BREAK_MANUAL;
+
+ return nType;
+}
+
+ScBreakType ScDocument::HasColBreak(SCCOL nCol, SCTAB nTab) const
+{
+ ScBreakType nType = BREAK_NONE;
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return nType;
+
+ if (pTab[nTab]->HasColPageBreak(nCol))
+ nType |= BREAK_PAGE;
+
+ if (pTab[nTab]->HasColManualBreak(nCol))
+ nType |= BREAK_MANUAL;
+
+ return nType;
+}
+
+void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return;
+
+ pTab[nTab]->SetRowBreak(nRow, bPage, bManual);
+}
+
+void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return;
+
+ pTab[nTab]->SetColBreak(nCol, bPage, bManual);
+}
+
+void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
+ return;
+
+ pTab[nTab]->RemoveRowBreak(nRow, bPage, bManual);
+}
+
+void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
+{
+ if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
+ return;
+
+ pTab[nTab]->RemoveColBreak(nCol, bPage, bManual);
+}
+
+Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return Sequence<TablePageBreakData>();
+
+ return pTab[nTab]->GetRowBreakData();
+}
+
+bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->RowHidden(nRow, pFirstRow, pLastRow);
+}
+
+bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW& rLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ rLastRow = nRow;
+ return false;
+ }
+
+ return pTab[nTab]->RowHidden(nRow, rLastRow);
+}
+
+
+bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->HasHiddenRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL& rLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ rLastCol = nCol;
+ return false;
+ }
+
+ return pTab[nTab]->ColHidden(nCol, rLastCol);
+}
+
+bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ {
+ if (pFirstCol)
+ *pFirstCol = nCol;
+ if (pLastCol)
+ *pLastCol = nCol;
+ return false;
+ }
+
+ return pTab[nTab]->ColHidden(nCol, pFirstCol, pLastCol);
+}
+
+void ScDocument::SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetRowHidden(nStartRow, nEndRow, bHidden);
+}
+
+void ScDocument::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetColHidden(nStartCol, nEndCol, bHidden);
+}
+
+SCROW ScDocument::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->FirstVisibleRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->LastVisibleRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return 0;
+
+ return pTab[nTab]->CountVisibleRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->RowFiltered(nRow, pFirstRow, pLastRow);
+}
+
+bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->HasFilteredRows(nStartRow, nEndRow);
+}
+
+bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ return pTab[nTab]->ColFiltered(nCol, pFirstCol, pLastCol);
+}
+
+void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetRowFiltered(nStartRow, nEndRow, bFiltered);
+}
+
+void ScDocument::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return;
+
+ pTab[nTab]->SetColFiltered(nStartCol, nEndCol, bFiltered);
+}
+
+SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->FirstNonFilteredRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return ::std::numeric_limits<SCROW>::max();;
+
+ return pTab[nTab]->LastNonFilteredRow(nStartRow, nEndRow);
+}
+
+SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return 0;
+
+ return pTab[nTab]->CountNonFilteredRows(nStartRow, nEndRow);
+}
+
+void ScDocument::SyncColRowFlags()
+{
+ for (SCTAB i = 0; i <= nMaxTableNumber; ++i)
+ {
+ if (!ValidTab(i) || !pTab[i])
+ continue;
+
+ pTab[i]->SyncColRowFlags();
+ }
+}
SCROW ScDocument::GetLastFlaggedRow( SCTAB nTab ) const
{
@@ -3441,7 +3684,7 @@ SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const
SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const
{
- if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->GetRowHeightArray() )
+ if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->mpRowHeights )
{
BYTE nStartFlags = pTab[nTab]->GetRowFlags(nStart);
USHORT nStartHeight = pTab[nTab]->GetOriginalHeight(nStart);
@@ -3451,7 +3694,7 @@ SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCa
SCROW nFlagsEndRow;
SCROW nHeightEndRow;
BYTE nFlags = pTab[nTab]->GetRowFlagsArray()->GetValue( nRow, nIndex, nFlagsEndRow );
- USHORT nHeight = pTab[nTab]->GetRowHeightArray()->GetValue( nRow, nIndex, nHeightEndRow );
+ USHORT nHeight = pTab[nTab]->GetRowHeight(nRow, NULL, &nHeightEndRow);
if (((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
(bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
@@ -4781,6 +5024,11 @@ void ScDocument::SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCRO
pTab[nTab]->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow );
}
+void ScDocument::InvalidatePageBreaks(SCTAB nTab)
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ pTab[nTab]->InvalidatePageBreaks();
+}
void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea )
{
@@ -4960,6 +5208,12 @@ SfxUndoManager* ScDocument::GetUndoManager()
return mpUndoManager;
}
+ScRowBreakIterator* ScDocument::GetRowBreakIterator(SCTAB nTab) const
+{
+ if (ValidTab(nTab) && pTab[nTab])
+ return new ScRowBreakIterator(pTab[nTab]->maRowPageBreaks);
+ return NULL;
+}
void ScDocument::EnableUndo( bool bVal )
{
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 5394605969d0..a2a10329cf68 100755
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -410,7 +410,7 @@ void ScDPObject::CreateOutput()
nNewRow = 0;
ScAddress aStart( aOutRange.aStart );
- aStart.SetRow( (USHORT) nNewRow );
+ aStart.SetRow(nNewRow);
pOutput->SetPosition( aStart );
//! modify aOutRange?
@@ -2434,6 +2434,14 @@ void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
}
}
+ScDPObject* ScDPCollection::GetByName(const String& rName) const
+{
+ for (USHORT i=0; i<nCount; i++)
+ if (static_cast<const ScDPObject*>(pItems[i])->GetName() == rName)
+ return static_cast<ScDPObject*>(pItems[i]);
+ return NULL;
+}
+
String ScDPCollection::CreateNewName( USHORT nMin ) const
{
String aBase = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DataPilot"));
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index 91688c6c0e2a..bdd6fd555b89 100755
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -1185,9 +1185,9 @@ void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionDa
Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
if (xPropSet.is())
{
- sal_Int32 nDataFieldCount = 0;
- Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii("DataFieldCount"));
- if ((any >>= nDataFieldCount) && nDataFieldCount > 0)
+ sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
+ rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
+ if (nDataFieldCount > 0)
aResData.DataFieldIndex = (nRow - nDataStartRow) % nDataFieldCount;
}
@@ -1267,9 +1267,9 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
if (!xPropSet.is())
return false;
- sal_Int32 nDataFieldCount = 0;
- Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii("DataFieldCount"));
- if (!(any >>= nDataFieldCount) || nDataFieldCount == 0)
+ sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
+ rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
+ if (nDataFieldCount == 0)
// No data field is present in this datapilot table.
return false;
diff --git a/sc/source/core/data/dptabresmember.cxx b/sc/source/core/data/dptabresmember.cxx
deleted file mode 100644
index 8c3b7b164bc3..000000000000
--- a/sc/source/core/data/dptabresmember.cxx
+++ /dev/null
@@ -1,831 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright IBM Corporation 2009.
- * Copyright 2009 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: dptabresmember.cxx,v $
- * $Revision: 1.0 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-#include "dptabresmember.hxx"
-// -----------------------------------------------------------------------
-ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData ,
- BOOL bForceSub ) :
- pResultData( pData ),
- aParentDimData( rParentDimData ),
- /* pParentDim( pDim ),
- pParentLevel( pLev ),
- pMemberDesc( pDesc ),*/
- pChildDimension( NULL ),
- pDataRoot( NULL ),
- bHasElements( FALSE ),
- bForceSubTotal( bForceSub ),
- bHasHiddenDetails( FALSE ),
- bInitialized( FALSE ),
- nMemberStep( 1 ),
- bAutoHidden( FALSE )
-{
- // pParentLevel/pMemberDesc is 0 for root members
-}
-
-ScDPNormalResultMember::ScDPNormalResultMember( const ScDPResultData* pData,
- BOOL bForceSub ) :
- pResultData( pData ),
- pChildDimension( NULL ),
- pDataRoot( NULL ),
- bHasElements( FALSE ),
- bForceSubTotal( bForceSub ),
- bHasHiddenDetails( FALSE ),
- bInitialized( FALSE ),
- nMemberStep( 1 ),
- bAutoHidden( FALSE )
-{
-}
-
-ScDPNormalResultMember::~ScDPNormalResultMember()
-{
- delete pChildDimension;
- delete pDataRoot;
-}
-
-String ScDPNormalResultMember::GetName() const
-{
-// Wang Xu Ming -- 2009-6-10
-// DataPilot Migration
- const ScDPMember* pMemberDesc = GetDPMember();
- // End Comments
- if (pMemberDesc)
- return pMemberDesc->GetNameStr();
- else
- return ScGlobal::GetRscString(STR_PIVOT_TOTAL); // root member
-}
-
-void ScDPNormalResultMember::FillItemData( ScDPItemData& rData ) const
-{
-// Wang Xu Ming -- 2009-6-10
-// DataPilot Migration
- const ScDPMember* pMemberDesc = GetDPMember();
-// End Comments
- if (pMemberDesc)
- pMemberDesc->FillItemData( rData );
- else
- rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member
-}
-
-BOOL ScDPNormalResultMember::IsNamedItem( /*const ScDPItemData& r */SCROW nIndex ) const
-{
- //! store ScDPMember pointer instead of ScDPMember ???
- const ScDPMember* pMemberDesc = GetDPMember();
- if (pMemberDesc)
- return ((ScDPMember*)pMemberDesc)->IsNamedItem(/* r*/ nIndex );
- return FALSE;
-}
-
-// Wang Xu Ming -- 2009-5-27
-// DataPilot Migration
-bool ScDPNormalResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const
-{
- return GetEntryStatus( aMembers ) != ENTRY_INVALID;
-}
-// End Comments
-
-ENTRYSTATUS ScDPNormalResultMember::GetEntryStatus( const vector< SCROW >& aMembers ) const
-{
- if ( !IsValid() )
- return ENTRY_INVALID;
-
- const ScDPResultDimension* pChildDim = GetChildDimension();
- if (pChildDim)
- {
- if (aMembers.size() < 2)
- return ENTRY_INVALID;
-
- vector</*ScDPItemData*/SCROW>::const_iterator itr = aMembers.begin();
- vector</*ScDPItemData*/SCROW> aChildMembers(++itr, aMembers.end());
- return pChildDim->GetEntryStatus(aChildMembers);
- }
- else if( bHasHiddenDetails )
- return ENTRY_HASHIDDENDETAIL;
- else
- return ENTRY_VALID;
-}
-
-void ScDPNormalResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev,
- size_t nPos, ScDPInitState& rInitState ,
- BOOL bInitChild /*= TRUE */)
- {
- // with LateInit, initialize only those members that have data
- if ( pResultData->IsLateInit() )
- return;
-
- bInitialized = TRUE;
-
- if (nPos >= ppDim.size() )
- return;
-
- // skip child dimension if details are not shown
- if ( GetDPMember() && !GetDPMember()->getShowDetails() )
- {
- // Wang Xu Ming -- 2009-6-16
- // Show DataLayout dimention
- nMemberStep = 1;
- while ( nPos < ppDim.size() )
- {
- if ( ppDim[nPos] ->getIsDataLayoutDimension() )
- {
- if ( !pChildDimension )
- pChildDimension = new ScDPResultDimension( pResultData );
- pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState , FALSE );
- return;
- }
- else
- { //find next dim
- nPos ++;
- nMemberStep ++;
- }
- }
- // End Comments
- bHasHiddenDetails = TRUE; // only if there is a next dimension
- return;
- }
-
- if ( bInitChild )
- {
- pChildDimension = new ScDPResultDimension( pResultData );
- pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE );
- }
-}
-
-// Wang Xu Ming -- 2009-6-10
-// DataPilot Migration
-void ScDPNormalResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/,
- const vector< SCROW >& pItemData, size_t nPos,
- ScDPInitState& rInitState )
-// End Comments
-{
- // without LateInit, everything has already been initialized
- if ( !pResultData->IsLateInit() )
- return;
-
- bInitialized = TRUE;
-
- if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/)
- // No next dimension. Bail out.
- return;
-
- // skip child dimension if details are not shown
- if ( GetDPMember() && !GetDPMember()->getShowDetails() )
- {
- // Wang Xu Ming -- 2009-6-16
- // DataPilot Migration
- // Show DataLayout dimention
- nMemberStep = 1;
- while ( !rParams.IsEnd( nPos ) )
- {
- if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() )
- {
- if ( !pChildDimension )
- pChildDimension = new ScDPResultDimension( pResultData );
- rParams.SetInitChild( FALSE );
- pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState );
- return;
- }
- else
- { //find next dim
- nPos ++;
- nMemberStep ++;
- }
- }
- // End Comments
- bHasHiddenDetails = TRUE; // only if there is a next dimension
- return;
- }
-
- // LateInitFrom is called several times...
- if ( rParams.GetInitChild() )
- {
- if ( !pChildDimension )
- pChildDimension = new ScDPResultDimension( pResultData );
- pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState );
- }
-}
-
-BOOL ScDPNormalResultMember::IsSubTotalInTitle(long nMeasure) const
-{
- BOOL bRet = FALSE;
- if ( pChildDimension && /*pParentLevel*/GetParentLevel() &&
- /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() )
- {
- long nUserSubStart;
- long nSubTotals = GetSubTotalCount( &nUserSubStart );
- nSubTotals -= nUserSubStart; // visible count
- if ( nSubTotals )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nSubTotals *= pResultData->GetMeasureCount(); // number of subtotals that will be inserted
-
- // only a single subtotal row will be shown in the outline title row
- if ( nSubTotals == 1 )
- bRet = TRUE;
- }
- }
- return bRet;
-}
-
-long ScDPNormalResultMember::GetSize(long nMeasure) const
-{
- if ( !IsVisible() )
- return 0;
- const ScDPLevel* pParentLevel = GetParentLevel();
- long nExtraSpace = 0;
- if ( pParentLevel && pParentLevel->IsAddEmpty() )
- ++nExtraSpace;
-
- if ( pChildDimension )
- {
- // outline layout takes up an extra row for the title only if subtotals aren't shown in that row
- if ( pParentLevel && pParentLevel->IsOutlineLayout() && !IsSubTotalInTitle( nMeasure ) )
- ++nExtraSpace;
-
- long nSize = pChildDimension->GetSize(nMeasure);
- long nUserSubStart;
- long nUserSubCount = GetSubTotalCount( &nUserSubStart );
- nUserSubCount -= nUserSubStart; // for output size, use visible count
- if ( nUserSubCount )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nSize += pResultData->GetMeasureCount() * nUserSubCount;
- else
- nSize += nUserSubCount;
- }
- return nSize + nExtraSpace;
- }
- else
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- return pResultData->GetMeasureCount() + nExtraSpace;
- else
- return 1 + nExtraSpace;
- }
-}
-
-
-BOOL ScDPNormalResultMember::IsVisible() const
-{
- // not initialized -> shouldn't be there at all
- // (allocated only to preserve ordering)
- const ScDPLevel* pParentLevel = GetParentLevel();
- return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized;
-}
-
-BOOL ScDPNormalResultMember::IsValid() const
-{
- // non-Valid members are left out of calculation
-
- // was member set no invisible at the DataPilotSource?
- const ScDPMember* pMemberDesc =GetDPMember();
- if ( pMemberDesc && !pMemberDesc->getIsVisible() )
- return FALSE;
-
- if ( bAutoHidden )
- return FALSE;
-
- return TRUE;
-}
-
-BOOL ScDPNormalResultMember::HasHiddenDetails() const
-{
- // bHasHiddenDetails is set only if the "show details" flag is off,
- // and there was a child dimension to skip
-
- return bHasHiddenDetails;
-}
-
-long ScDPNormalResultMember::GetSubTotalCount( long* pUserSubStart ) const
-{
- if ( pUserSubStart )
- *pUserSubStart = 0; // default
-
- const ScDPLevel* pParentLevel = GetParentLevel();
-
- if ( bForceSubTotal ) // set if needed for root members
- return 1; // grand total is always "automatic"
- else if ( pParentLevel )
- {
- //! direct access via ScDPLevel
-
- uno::Sequence<sheet::GeneralFunction> aSeq = pParentLevel->getSubTotals();
- long nSequence = aSeq.getLength();
- if ( nSequence && aSeq[0] != sheet::GeneralFunction_AUTO )
- {
- // For manual subtotals, always add "automatic" as first function
- // (used for calculation, but not for display, needed for sorting, see lcl_GetForceFunc)
-
- ++nSequence;
- if ( pUserSubStart )
- *pUserSubStart = 1; // visible subtotals start at 1
- }
- return nSequence;
- }
- else
- return 0;
-}
-
-void ScDPNormalResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim,
- const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues )
-{
- SetHasElements();
-
- if (pChildDimension)
- pChildDimension->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues );
-
- if ( !pDataRoot )
- {
- pDataRoot = new ScDPDataMember( pResultData, NULL );
- if ( pDataDim )
- pDataRoot->InitFrom( pDataDim ); // recursive
- }
-
- ScDPSubTotalState aSubState; // initial state
-
- long nUserSubCount = GetSubTotalCount();
-
- // Calculate at least automatic if no subtotals are selected,
- // show only own values if there's no child dimension (innermost).
- if ( !nUserSubCount || !pChildDimension )
- nUserSubCount = 1;
-
- const ScDPLevel* pParentLevel = GetParentLevel();
-
- for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
- {
- // #i68338# if nUserSubCount is 1 (automatic only), don't set nRowSubTotalFunc
- if ( pChildDimension && nUserSubCount > 1 )
- {
- aSubState.nRowSubTotalFunc = nUserPos;
- aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos );
- }
-
- pDataRoot->ProcessData( aDataMembers, aValues, aSubState );
- }
-}
-
-void ScDPNormalResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
- long& rPos, long nMeasure, BOOL bRoot,
- const String* pMemberName,
- const String* pMemberCaption )
-{
- // IsVisible() test is in ScDPResultDimension::FillMemberResults
- // (not on data layout dimension)
-
- long nSize = GetSize(nMeasure);
- sheet::MemberResult* pArray = pSequences->getArray();
- DBG_ASSERT( rPos+nSize <= pSequences->getLength(), "bumm" );
-
- BOOL bIsNumeric = FALSE;
- String aName;
- if ( pMemberName ) // if pMemberName != NULL, use instead of real member name
- aName = *pMemberName;
- else
- {
- ScDPItemData aItemData;
- FillItemData( aItemData );
- aName = aItemData.GetString();
- bIsNumeric = aItemData.IsValue();
- }
- const ScDPDimension* pParentDim = GetParentDim();
- if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) )
- {
- // Numeric group dimensions use numeric entries for proper sorting,
- // but the group titles must be output as text.
- bIsNumeric = FALSE;
- }
-
- String aCaption = aName;
- if ( pMemberCaption ) // use pMemberCaption if != NULL
- aCaption = *pMemberCaption;
- if (!aCaption.Len())
- aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
-
- if ( !bIsNumeric )
- {
- // add a "'" character so a string isn't parsed as value in the output cell
- //! have a separate bit in Flags (MemberResultFlags) instead?
- aCaption.Insert( (sal_Unicode) '\'', 0 );
- }
-
- if ( nSize && !bRoot ) // root is overwritten by first dimension
- {
- pArray[rPos].Name = rtl::OUString(aName);
- pArray[rPos].Caption = rtl::OUString(aCaption);
- pArray[rPos].Flags |= sheet::MemberResultFlags::HASMEMBER;
-
- // set "continue" flag (removed for subtotals later)
- for (long i=1; i<nSize; i++)
- pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE;
- }
-
- const ScDPLevel* pParentLevel = GetParentLevel();
- long nExtraSpace = 0;
- if ( pParentLevel && pParentLevel->IsAddEmpty() )
- ++nExtraSpace;
-
- BOOL bTitleLine = FALSE;
- if ( pParentLevel && pParentLevel->IsOutlineLayout() )
- bTitleLine = TRUE;
-
- // if the subtotals are shown at the top (title row) in outline layout,
- // no extra row for the subtotals is needed
- BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure );
-
- BOOL bHasChild = ( pChildDimension != NULL );
- if (bHasChild)
- {
- if ( bTitleLine ) // in tabular layout the title is on a separate row
- ++rPos; // -> fill child dimension one row below
-
- if (bRoot) // same sequence for root member
- pChildDimension->FillMemberResults( pSequences, rPos, nMeasure );
- else
- // Wang Xu Ming -- 2009-6-16
- // DataPilot Migration
- // for show details
- pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure );
- // End Comments
-
- if ( bTitleLine ) // title row is included in GetSize, so the following
- --rPos; // positions are calculated with the normal values
- }
-
- rPos += nSize;
-
- long nUserSubStart;
- long nUserSubCount = GetSubTotalCount(&nUserSubStart);
- if ( nUserSubCount && pChildDimension && !bSubTotalInTitle )
- {
- long nMemberMeasure = nMeasure;
- long nSubSize = pResultData->GetCountForMeasure(nMeasure);
-
- rPos -= nSubSize * (nUserSubCount - nUserSubStart); // GetSize includes space for SubTotal
- rPos -= nExtraSpace; // GetSize includes the empty line
-
- for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++)
- {
- for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nMemberMeasure = nSubCount;
-
- ScSubTotalFunc eForce = SUBTOTAL_FUNC_NONE;
- if (bHasChild)
- eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
-
- String aSubStr = aName; //! caption?
- aSubStr += ' ';
- aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce);
-
- pArray[rPos].Name = rtl::OUString(aName);
- pArray[rPos].Caption = rtl::OUString(aSubStr);
- pArray[rPos].Flags = ( pArray[rPos].Flags |
- ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL) ) &
- ~sheet::MemberResultFlags::CONTINUE;
-
- if ( nMeasure == SC_DPMEASURE_ALL )
- {
- // data layout dimension is (direct/indirect) child of this.
- // data layout dimension must have name for all entries.
-
- uno::Sequence<sheet::MemberResult>* pLayoutSeq = pSequences;
- if (!bRoot)
- ++pLayoutSeq;
- ScDPResultDimension* pLayoutDim = pChildDimension;
- while ( pLayoutDim && !pLayoutDim->IsDataLayout() )
- {
- pLayoutDim = pLayoutDim->GetFirstChildDimension();
- ++pLayoutSeq;
- }
- if ( pLayoutDim )
- {
- sheet::MemberResult* pLayoutArray = pLayoutSeq->getArray();
- String aDataName = pResultData->GetMeasureDimensionName(nMemberMeasure);
- pLayoutArray[rPos].Name = rtl::OUString(aDataName);
- }
- }
-
- rPos += 1;
- }
- }
-
- rPos += nExtraSpace; // add again (subtracted above)
- }
-}
-
-void ScDPNormalResultMember::FillDataResults( const ScDPResultMember* pRefMember,
- uno::Sequence< uno::Sequence<sheet::DataResult> >& rSequence,
- long& rRow, long nMeasure ) const
-{
- // IsVisible() test is in ScDPResultDimension::FillDataResults
- // (not on data layout dimension)
- const ScDPLevel* pParentLevel = GetParentLevel();
- long nStartRow = rRow;
-
- long nExtraSpace = 0;
- if ( pParentLevel && pParentLevel->IsAddEmpty() )
- ++nExtraSpace;
-
- BOOL bTitleLine = FALSE;
- if ( pParentLevel && pParentLevel->IsOutlineLayout() )
- bTitleLine = TRUE;
-
- BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure );
-
- BOOL bHasChild = ( pChildDimension != NULL );
- if (bHasChild)
- {
- if ( bTitleLine ) // in tabular layout the title is on a separate row
- ++rRow; // -> fill child dimension one row below
-
- pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow
- rRow += (USHORT) GetSize( nMeasure );
-
- if ( bTitleLine ) // title row is included in GetSize, so the following
- --rRow; // positions are calculated with the normal values
- }
-
- long nUserSubStart;
- long nUserSubCount = GetSubTotalCount(&nUserSubStart);
- if ( nUserSubCount || !bHasChild )
- {
- // Calculate at least automatic if no subtotals are selected,
- // show only own values if there's no child dimension (innermost).
- if ( !nUserSubCount || !bHasChild )
- {
- nUserSubCount = 1;
- nUserSubStart = 0;
- }
-
- long nMemberMeasure = nMeasure;
- long nSubSize = pResultData->GetCountForMeasure(nMeasure);
- if (bHasChild)
- {
- rRow -= nSubSize * ( nUserSubCount - nUserSubStart ); // GetSize includes space for SubTotal
- rRow -= nExtraSpace; // GetSize includes the empty line
- }
-
- long nMoveSubTotal = 0;
- if ( bSubTotalInTitle )
- {
- nMoveSubTotal = rRow - nStartRow; // force to first (title) row
- rRow = nStartRow;
- }
-
- if ( pDataRoot )
- {
- ScDPSubTotalState aSubState; // initial state
-
- for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++)
- {
- if ( bHasChild && nUserSubCount > 1 )
- {
- aSubState.nRowSubTotalFunc = nUserPos;
- aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos );
- }
-
- for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nMemberMeasure = nSubCount;
- else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
- nMemberMeasure = SC_DPMEASURE_ALL;
-
- DBG_ASSERT( rRow < rSequence.getLength(), "bumm" );
- uno::Sequence<sheet::DataResult>& rSubSeq = rSequence.getArray()[rRow];
- long nSeqCol = 0;
- pDataRoot->FillDataRow( pRefMember, rSubSeq, nSeqCol, nMemberMeasure, bHasChild, aSubState );
-
- rRow += 1;
- }
- }
- }
- else
- rRow += nSubSize * ( nUserSubCount - nUserSubStart ); // empty rows occur when ShowEmpty is true
-
- // add extra space again if subtracted from GetSize above,
- // add to own size if no children
- rRow += nExtraSpace;
-
- rRow += nMoveSubTotal;
- }
-}
-
-void ScDPNormalResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const
-{
- // IsVisible() test is in ScDPResultDimension::FillDataResults
- // (not on data layout dimension)
-
- BOOL bHasChild = ( pChildDimension != NULL );
-
- long nUserSubCount = GetSubTotalCount();
- // process subtotals even if not shown
-// if ( nUserSubCount || !bHasChild )
- {
- // Calculate at least automatic if no subtotals are selected,
- // show only own values if there's no child dimension (innermost).
- if ( !nUserSubCount || !bHasChild )
- nUserSubCount = 1;
-
- long nMemberMeasure = nMeasure;
- long nSubSize = pResultData->GetCountForMeasure(nMeasure);
-
- if ( pDataRoot )
- {
- ScDPSubTotalState aSubState; // initial state
-
- for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
- {
- if ( bHasChild && nUserSubCount > 1 )
- {
- aSubState.nRowSubTotalFunc = nUserPos;
- aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos );
- }
-
- for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nMemberMeasure = nSubCount;
- else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
- nMemberMeasure = SC_DPMEASURE_ALL;
-
- pDataRoot->UpdateDataRow( pRefMember, nMemberMeasure, bHasChild, aSubState );
- }
- }
- }
- }
-
- if (bHasChild) // child dimension must be processed last, so the column total is known
- {
- pChildDimension->UpdateDataResults( pRefMember, nMeasure );
- }
-}
-
-void ScDPNormalResultMember::SortMembers( ScDPResultMember* pRefMember )
-{
- BOOL bHasChild = ( pChildDimension != NULL );
- if (bHasChild)
- pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension
-
- if ( IsRoot() && pDataRoot )
- {
- // use the row root member to sort columns
- // sub total count is always 1
-
- pDataRoot->SortMembers( pRefMember );
- }
-}
-
-void ScDPNormalResultMember::DoAutoShow( ScDPResultMember* pRefMember )
-{
- BOOL bHasChild = ( pChildDimension != NULL );
- if (bHasChild)
- pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension
-
- if ( IsRoot()&& pDataRoot )
- {
- // use the row root member to sort columns
- // sub total count is always 1
-
- pDataRoot->DoAutoShow( pRefMember );
- }
-}
-
-void ScDPNormalResultMember::ResetResults( BOOL bRoot )
-{
- if (pDataRoot)
- pDataRoot->ResetResults();
-
- if (pChildDimension)
- pChildDimension->ResetResults();
-
-// Wang Xu Ming -- 3/4/2009
-// Dim refresh and filter. SODC_19023
- // if (!bRoot)
- // bHasElements = FALSE;
-// End Comments
-}
-
-void ScDPNormalResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure,
- ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const
-{
- // IsVisible() test is in ScDPResultDimension::FillDataResults
- // (not on data layout dimension)
-
- rTotals.SetInColRoot( IsRoot() );
-
- BOOL bHasChild = ( pChildDimension != NULL );
-
- long nUserSubCount = GetSubTotalCount();
- if ( nUserSubCount || !bHasChild )
- {
- // Calculate at least automatic if no subtotals are selected,
- // show only own values if there's no child dimension (innermost).
- if ( !nUserSubCount || !bHasChild )
- nUserSubCount = 1;
-
- long nMemberMeasure = nMeasure;
- long nSubSize = pResultData->GetCountForMeasure(nMeasure);
-
- if ( pDataRoot )
- {
- ScDPSubTotalState aSubState; // initial state
-
- for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic"
- {
- if ( bHasChild && nUserSubCount > 1 )
- {
- aSubState.nRowSubTotalFunc = nUserPos;
- aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos );
- }
-
- for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ )
- {
- if ( nMeasure == SC_DPMEASURE_ALL )
- nMemberMeasure = nSubCount;
- else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL )
- nMemberMeasure = SC_DPMEASURE_ALL;
-
- pDataRoot->UpdateRunningTotals( pRefMember, nMemberMeasure,
- bHasChild, aSubState, rRunning, rTotals, *this );
- }
- }
- }
- }
-
- if (bHasChild) // child dimension must be processed last, so the column total is known
- {
- pChildDimension->UpdateRunningTotals( pRefMember, nMeasure, rRunning, rTotals );
- }
-}
-
-void ScDPNormalResultMember::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const
-{
- lcl_DumpRow( String::CreateFromAscii("ScDPResultMember"), GetName(), NULL, pDoc, rPos );
- SCROW nStartRow = rPos.Row();
-
- if (pDataRoot)
- pDataRoot->DumpState( pRefMember, pDoc, rPos );
-
- if (pChildDimension)
- pChildDimension->DumpState( pRefMember, pDoc, rPos );
-
- lcl_Indent( pDoc, nStartRow, rPos );
-}
-
-ScDPAggData* ScDPNormalResultMember::GetColTotal( long nMeasure ) const
-{
- return lcl_GetChildTotal( const_cast<ScDPAggData*>(&aColTotal), nMeasure );
-}
-
-void ScDPNormalResultMember::FillVisibilityData(ScDPResultVisibilityData& rData) const
-{
- if (pChildDimension)
- pChildDimension->FillVisibilityData(rData);
-}
-// Wang Xu Ming -- 2009-6-10
-// DataPilot Migration
-SCROW ScDPNormalResultMember::GetDataId( ) const
-{
-// TODO:
- const ScDPMember* pMemberDesc = GetDPMember();
- if (pMemberDesc)
- return pMemberDesc->GetItemDataId();
- return -1;
-}
-
-// -----------------------------------------------------------------------
-ScDPHideDetailsMember:: ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData,
- BOOL bForceSub ):ScDPResultMember(pData,rParentDimData, bForceSub)
-{
- pOrigMember = new ScDPNormalResultMember(pData,rParentDimData, bForceSub);
-
-} \ No newline at end of file
diff --git a/sc/source/core/data/dptabresmember.hxx b/sc/source/core/data/dptabresmember.hxx
deleted file mode 100644
index 72657167d07d..000000000000
--- a/sc/source/core/data/dptabresmember.hxx
+++ /dev/null
@@ -1,161 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright IBM Corporation 2009.
- * Copyright 2009 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: dptabresmember.hxx,v $
- * $Revision: 1.0 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef DPTABRESMEMBER_HXX
-#define DPTABRESMEMBER_HXX
-
-class ScDPNormalResultMember: public ScDPResultMember
-{
-private:
- // Wang Xu Ming -- 2009-6-9
- // DataPilot Migration
- ScDPParentDimData aParentDimData;
- // End Comments
- BOOL bHasElements:1;
- BOOL bForceSubTotal:1;
- BOOL bHasHiddenDetails:1;
- BOOL bInitialized:1;
- BOOL bAutoHidden:1;
- ScDPAggData aColTotal; // to store column totals
-
-// Wang Xu Ming -- 2009-6-9
-// DataPilot Migration
- USHORT nMemberStep; // step to show details
-// End Comments
-public:
- // Wang Xu Ming -- 2009-6-9
- // DataPilot Migration
- ScDPNormalResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData,
- BOOL bForceSub ); //! Ref
- ScDPNormalResultMember( const ScDPResultData* pData, BOOL bForceSub );
- // End Comments
- ~ScDPNormalResultMember();
-
- // Wang Xu Ming -- 2009-6-9
- // DataPilot Migration
- // Add parameter: BOOL bInitChild
- void InitFrom( const ::std::vector<ScDPDimension*>& ppDim,
- const ::std::vector<ScDPLevel*>& ppLev,
- size_t nPos,
- ScDPInitState& rInitState,
- BOOL bInitChild = TRUE );
- // End Comments
- // Wang Xu Ming -- 2009-6-9
- // DataPilot Migration
- void LateInitFrom(
- LateInitParams& rParams,
- const ::std::vector< SCROW >& pItemData,
- size_t nPos,
- ScDPInitState& rInitState);
- // End Comments
-
- String GetName() const;
- void FillItemData( ScDPItemData& rData ) const;
- BOOL IsValid() const;
- BOOL IsVisible() const;
- long GetSize(long nMeasure) const;
- BOOL HasHiddenDetails() const;
- BOOL IsSubTotalInTitle(long nMeasure) const;
-
-// BOOL SubTotalEnabled() const;
- long GetSubTotalCount( long* pUserSubStart = NULL ) const;
-
-// Wang Xu Ming -- 2009-6-9
-// DataPilot Migration
-// Use item index
-// BOOL IsNamedItem( const ScDPItemData& r ) const;
- BOOL IsNamedItem( SCROW nIndex ) const;
-// End Comments
- bool IsValidEntry( const ::std::vector< SCROW >& aMembers ) const;
- ENTRYSTATUS GetEntryStatus( const ::std::vector<SCROW>& aMembers ) const;
-
- void SetHasElements() { bHasElements = TRUE; }
- void SetAutoHidden() { bAutoHidden = TRUE; }
-
- void ProcessData( const ::std::vector<SCROW>& aChildMembers,
- const ScDPResultDimension* pDataDim,
- const ::std::vector<SCROW>& aDataMembers,
- const ::std::vector<ScDPValueData>& aValues );
-
- void FillMemberResults( com::sun::star::uno::Sequence<
- com::sun::star::sheet::MemberResult>* pSequences,
- long& rPos, long nMeasure, BOOL bRoot,
- const String* pMemberName,
- const String* pMemberCaption );
-
- void FillDataResults( const ScDPResultMember* pRefMember,
- com::sun::star::uno::Sequence<
- com::sun::star::uno::Sequence<
- com::sun::star::sheet::DataResult> >& rSequence,
- long& rRow, long nMeasure ) const;
-
- void UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const;
- void UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure,
- ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const;
-
- void SortMembers( ScDPResultMember* pRefMember );
- void DoAutoShow( ScDPResultMember* pRefMember );
-
- void ResetResults( BOOL bRoot );
-
- void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const;
-
- // Wang Xu Ming -- 2009-6-9
- // DataPilot Migration
- const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref
- const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref
- const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref
- inline SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref
- inline BOOL IsRoot() const { return GetParentLevel() == NULL; }
- // End Comments
-
- ScDPAggData* GetColTotal( long nMeasure ) const;
-
- void FillVisibilityData(ScDPResultVisibilityData& rData) const;
-// Wang Xu Ming -- 2009-6-10
-// DataPilot Migration
- SCROW GetDataId( ) const ;
-// End Comments
-};
-
-class ScDPHideDetailsMember: public ScDPResultMember
-{
-private:
- ScDPNormalResultMember * pOrigMember;
-public:
- ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData,
- BOOL bForceSub );
-
-
-};
-
-
-#endif //DPTABRESMEMBER_HXX
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 3d7fc007818b..4df709768279 100755..100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -592,12 +592,14 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool b
{
//! nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden)
+ SCCOL nLastCol;
+ SCROW nLastRow;
if( bValid1 )
{
Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
- if( (pDoc->GetColFlags( nCol1, nTab1 ) & CR_HIDDEN) == 0 )
+ if (!pDoc->ColHidden(nCol1, nTab1, nLastCol))
aPos.X() += pDoc->GetColWidth( nCol1, nTab1 ) / 4;
- if( (pDoc->GetRowFlags( nRow1, nTab1 ) & CR_HIDDEN) == 0 )
+ if (!pDoc->RowHidden(nRow1, nTab1, nLastRow))
aPos.Y() += pDoc->GetRowHeight( nRow1, nTab1 ) / 2;
TwipsToMM( aPos.X() );
TwipsToMM( aPos.Y() );
@@ -629,9 +631,9 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool b
if( bValid2 )
{
Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
- if( (pDoc->GetColFlags( nCol2, nTab2 ) & CR_HIDDEN) == 0 )
+ if (!pDoc->ColHidden(nCol2, nTab2, nLastCol))
aPos.X() += pDoc->GetColWidth( nCol2, nTab2 ) / 4;
- if( (pDoc->GetRowFlags( nRow2, nTab2 ) & CR_HIDDEN) == 0 )
+ if (!pDoc->RowHidden(nRow2, nTab2, nLastRow))
aPos.Y() += pDoc->GetRowHeight( nRow2, nTab2 ) / 2;
TwipsToMM( aPos.X() );
TwipsToMM( aPos.Y() );
@@ -735,8 +737,8 @@ BOOL ScDrawLayer::GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) co
}
if (!bSetVer)
{
- nStartY = pDoc->FastGetRowHeight( 0, rRange.aStart.Row()-1, nTab);
- nEndY = nStartY + pDoc->FastGetRowHeight( rRange.aStart.Row(),
+ nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab);
+ nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(),
rRange.aEnd.Row(), nTab);
nStartY = (long)(nStartY * HMM_PER_TWIPS);
nEndY = (long)(nEndY * HMM_PER_TWIPS);
@@ -817,9 +819,9 @@ BOOL ScDrawLayer::GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) co
{
nStartY = (long) (nStartY / HMM_PER_TWIPS);
nEndY = (long) (nEndY / HMM_PER_TWIPS);
- SCROW nRow = pDoc->FastGetRowForHeight( nTab, nStartY);
+ SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY);
rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0);
- nRow = pDoc->FastGetRowForHeight( nTab, nEndY);
+ nRow = pDoc->GetRowForHeight( nTab, nEndY);
rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW :
(nRow>0 ? (nRow-1) : 0));
}
@@ -1041,9 +1043,9 @@ void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCR
for (SCsCOL s=-1; s>=nDx; s--)
aMove.X() -= pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
if (nDy > 0)
- aMove.Y() += pDoc->FastGetRowHeight( nRow1, nRow1+nDy-1, nTab);
+ aMove.Y() += pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab);
else
- aMove.Y() -= pDoc->FastGetRowHeight( nRow1+nDy, nRow1-1, nTab);
+ aMove.Y() -= pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab);
if ( bNegativePage )
aMove.X() = -aMove.X();
@@ -1115,9 +1117,9 @@ void ScDrawLayer::HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips )
Rectangle aRect;
Point aTopLeft;
- aRect.Top() += pDoc->FastGetRowHeight( 0, nRow-1, nTab);
+ aRect.Top() += pDoc->GetRowHeight( 0, nRow-1, nTab);
aTopLeft.Y() = aRect.Top();
- aRect.Top() += pDoc->FastGetRowHeight(nRow,nTab);
+ aRect.Top() += pDoc->GetRowHeight(nRow, nTab);
aRect.Bottom() = MAXMM;
aRect.Left() = 0;
@@ -1143,14 +1145,14 @@ BOOL ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow )
Rectangle aTestRect;
- aTestRect.Top() += pDoc->FastGetRowHeight( 0, nStartRow-1, nTab);
+ aTestRect.Top() += pDoc->GetRowHeight( 0, nStartRow-1, nTab);
if (nEndRow==MAXROW)
aTestRect.Bottom() = MAXMM;
else
{
aTestRect.Bottom() = aTestRect.Top();
- aTestRect.Bottom() += pDoc->FastGetRowHeight( nStartRow, nEndRow, nTab);
+ aTestRect.Bottom() += pDoc->GetRowHeight( nStartRow, nEndRow, nTab);
TwipsToMM( aTestRect.Bottom() );
}
@@ -1706,7 +1708,7 @@ Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, boo
for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol )
aTopLeft.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
if( rPos.Row() > 0 )
- aTopLeft.Y() += rDoc.FastGetRowHeight( 0, rPos.Row() - 1, rPos.Tab() );
+ aTopLeft.Y() += rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() );
// find bottom-right position of passed cell address
ScAddress aEndPos = rPos;
@@ -1721,7 +1723,7 @@ Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, boo
Point aBotRight = aTopLeft;
for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol )
aBotRight.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
- aBotRight.Y() += rDoc.FastGetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() );
+ aBotRight.Y() += rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() );
// twips -> 1/100 mm
aTopLeft.X() = static_cast< long >( aTopLeft.X() * HMM_PER_TWIPS );
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 05e0d98c9719..8418cb3c3a25 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -52,7 +52,6 @@
#include "conditio.hxx"
#include "stlpool.hxx"
-
// -----------------------------------------------------------------------
const USHORT ROWINFO_MAX = 1024;
@@ -97,11 +96,13 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
rStartY = nY;
BOOL bHOver = pInfo->bHOverlapped;
BOOL bVOver = pInfo->bVOverlapped;
+ SCCOL nLastCol;
+ SCROW nLastRow;
while (bHOver) // nY konstant
{
--rStartX;
- if (rStartX >= (SCsCOL) nX1 && (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0)
+ if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, nLastCol))
{
bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
@@ -123,8 +124,8 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
--nArrY; // lokale Kopie !
if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
- (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0 &&
- (pDoc->GetRowFlags(rStartY,nTab) & CR_HIDDEN) == 0 &&
+ !pDoc->ColHidden(rStartX, nTab, nLastCol) &&
+ !pDoc->RowHidden(rStartY, nTab, nLastRow) &&
(SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
{
bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
@@ -141,8 +142,8 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
const ScMergeAttr* pMerge;
if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
- (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0 &&
- (pDoc->GetRowFlags(rStartY,nTab) & CR_HIDDEN) == 0 &&
+ !pDoc->ColHidden(rStartX, nTab, nLastCol) &&
+ !pDoc->RowHidden(rStartY, nTab, nLastRow) &&
(SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
{
pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
@@ -155,12 +156,6 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
rEndY = rStartY + pMerge->GetRowMerge() - 1;
}
-inline BOOL ScDocument::RowHidden( SCROW nRow, SCTAB nTab )
-{
- return ( pTab[nTab]->pRowFlags->GetValue(nRow) & CR_HIDDEN ) != 0;
-}
-
-
#define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x]
void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
@@ -356,7 +351,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
nX = nArrX-1;
if ( ValidCol(nX) )
{
- if ( (GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) // Spalte nicht versteckt
+ if (!ColHidden(nX, nTab))
{
USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX);
if (!nThisWidth)
@@ -376,7 +371,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
// #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
// will disturb the output
- if ( (GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) // column not hidden
+ // TODO: Optimize this loop.
+ if (!ColHidden(nX, nTab))
{
USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX);
if (!nThisWidth)
@@ -481,7 +477,9 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
do
{
- if ( nArrY==0 || !RowHidden( nCurRow,nTab ) )
+ SCROW nLastHiddenRow = -1;
+ bool bRowHidden = RowHidden(nCurRow, nTab, nLastHiddenRow);
+ if ( nArrY==0 || !bRowHidden )
{
RowInfo* pThisRowInfo = &pRowInfo[nArrY];
if (pBackground != pDefBackground) // Spalten-HG == Standard ?
@@ -551,6 +549,12 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
++nArrY;
}
+ else if (bRowHidden && nLastHiddenRow >= 0)
+ {
+ nCurRow = nLastHiddenRow;
+ if (nCurRow > nThisRow)
+ nCurRow = nThisRow;
+ }
++nCurRow;
}
while (nCurRow <= nThisRow && nCurRow <= nYExtra);
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index cf51e1e543a4..95ce6bcec179 100755..100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -98,9 +98,12 @@ SLOFILES = \
$(SLO)$/patattr.obj \
$(SLO)$/pivot2.obj \
$(SLO)$/poolhelp.obj \
+ $(SLO)$/sheetevents.obj \
+ $(SLO)$/segmenttree.obj \
$(SLO)$/sortparam.obj \
$(SLO)$/stlpool.obj \
$(SLO)$/stlsheet.obj \
+ $(SLO)$/tabbgcolor.obj \
$(SLO)$/table1.obj \
$(SLO)$/table2.obj \
$(SLO)$/table3.obj \
@@ -128,6 +131,7 @@ EXCEPTIONSFILES= \
$(SLO)$/dptabres.obj \
$(SLO)$/dptabdat.obj \
$(SLO)$/global2.obj \
+ $(SLO)$/tabbgcolor.obj \
$(SLO)$/table1.obj \
$(SLO)$/table2.obj \
$(SLO)$/table3.obj \
@@ -148,7 +152,8 @@ EXCEPTIONSFILES= \
$(SLO)$/dbdocutl.obj \
$(SLO)$/dptabsrc.obj \
$(SLO)$/drwlayer.obj \
- $(SLO)$/globalx.obj
+ $(SLO)$/globalx.obj \
+ $(SLO)$/segmenttree.obj
.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
NOOPTFILES= \
@@ -164,7 +169,8 @@ EXCEPTIONSNOOPTFILES= \
.ELSE
EXCEPTIONSFILES+= \
$(SLO)$/cell.obj \
- $(SLO)$/global.obj
+ $(SLO)$/global.obj \
+ $(SLO)$/table5.obj
.ENDIF
# --- Tagets -------------------------------------------------------
diff --git a/sc/source/core/data/olinetab.cxx b/sc/source/core/data/olinetab.cxx
index 55f7ba46b898..af444c4b2123 100644
--- a/sc/source/core/data/olinetab.cxx
+++ b/sc/source/core/data/olinetab.cxx
@@ -41,10 +41,11 @@
#include "global.hxx"
#include "rechead.hxx"
#include "address.hxx"
+#include "table.hxx"
//------------------------------------------------------------------------
-ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, BOOL bNewHidden ) :
+ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
nStart ( nNewStart ),
nSize ( nNewSize ),
bHidden ( bNewHidden ),
@@ -93,12 +94,12 @@ void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
SetSize( nNewSize );
}
-void ScOutlineEntry::SetHidden( BOOL bNewHidden )
+void ScOutlineEntry::SetHidden( bool bNewHidden )
{
bHidden = bNewHidden;
}
-void ScOutlineEntry::SetVisible( BOOL bNewVisible )
+void ScOutlineEntry::SetVisible( bool bNewVisible )
{
bVisible = bNewVisible;
}
@@ -637,10 +638,9 @@ BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize )
return bNeedSave;
}
-BOOL ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos,
- BOOL bShow, const ScBitMaskCompressedArray< SCCOLROW, BYTE>& rHiddenFlags )
+bool ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol )
{
- BOOL bModified = FALSE;
+ bool bModified = false;
ScSubOutlineIterator aIter( this );
ScOutlineEntry* pEntry;
while((pEntry=aIter.GetNext())!=NULL)
@@ -654,18 +654,16 @@ BOOL ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos,
{
// #i12341# hide if all columns/rows are hidden, show if at least one
// is visible
-
- SCCOLROW nEnd = rHiddenFlags.GetBitStateEnd( nEntryStart,
- CR_HIDDEN, CR_HIDDEN);
- BOOL bAllHidden = (nEntryEnd <= nEnd && nEnd <
+ SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
+ bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
::std::numeric_limits<SCCOLROW>::max());
- BOOL bToggle = ( bShow != bAllHidden );
+ bool bToggle = ( bShow != bAllHidden );
if ( bToggle )
{
pEntry->SetHidden( !bShow );
SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
- bModified = TRUE;
+ bModified = true;
}
}
}
diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx
new file mode 100644
index 000000000000..86b53582d1d4
--- /dev/null
+++ b/sc/source/core/data/segmenttree.cxx
@@ -0,0 +1,582 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "segmenttree.hxx"
+
+#include <mdds/flat_segment_tree.hpp>
+
+#include <limits>
+
+using ::std::numeric_limits;
+
+// ============================================================================
+
+template<typename _ValueType, typename _ExtValueType = _ValueType>
+class ScFlatSegmentsImpl
+{
+public:
+ typedef _ValueType ValueType;
+ typedef _ExtValueType ExtValueType;
+
+ struct RangeData
+ {
+ SCCOLROW mnPos1;
+ SCCOLROW mnPos2;
+ ValueType mnValue;
+ };
+
+ ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
+ ScFlatSegmentsImpl(const ScFlatSegmentsImpl& r);
+ ~ScFlatSegmentsImpl();
+
+ void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue);
+ ValueType getValue(SCCOLROW nPos);
+ ExtValueType getSumValue(SCCOLROW nPos1, SCCOLROW nPos2);
+ bool getRangeData(SCCOLROW nPos, RangeData& rData);
+ void removeSegment(SCCOLROW nPos1, SCCOLROW nPos2);
+ void insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary);
+
+ SCROW findLastNotOf(ValueType nValue) const;
+
+ // range iteration
+ bool getFirst(RangeData& rData);
+ bool getNext(RangeData& rData);
+
+ void enableTreeSearch(bool b)
+ {
+ mbTreeSearchEnabled = b;
+ }
+
+ void setInsertFromBack(bool b)
+ {
+ mbInsertFromBack = b;
+ }
+
+private:
+ typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
+ fst_type maSegments;
+ typename fst_type::const_iterator maItr;
+
+ bool mbTreeSearchEnabled:1;
+ bool mbInsertFromBack:1;
+};
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault) :
+ maSegments(0, nMax+1, nDefault),
+ mbTreeSearchEnabled(true),
+ mbInsertFromBack(false)
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType, _ExtValueType>& r) :
+ maSegments(r.maSegments),
+ mbTreeSearchEnabled(r.mbTreeSearchEnabled),
+ mbInsertFromBack(r.mbInsertFromBack)
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl()
+{
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue)
+{
+ if (mbInsertFromBack)
+ maSegments.insert_back(nPos1, nPos2+1, nValue);
+ else
+ maSegments.insert_front(nPos1, nPos2+1, nValue);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ValueType ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getValue(SCCOLROW nPos)
+{
+ ValueType nValue = 0;
+ if (!mbTreeSearchEnabled)
+ {
+ maSegments.search(nPos, nValue);
+ return nValue;
+ }
+
+ if (!maSegments.is_tree_valid())
+ maSegments.build_tree();
+
+ maSegments.search_tree(nPos, nValue);
+ return nValue;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ExtValueType
+ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getSumValue(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ RangeData aData;
+ if (!getRangeData(nPos1, aData))
+ return 0;
+
+ sal_uInt32 nValue = 0;
+
+ SCROW nCurPos = nPos1;
+ SCROW nEndPos = aData.mnPos2;
+ while (nEndPos <= nPos2)
+ {
+ nValue += aData.mnValue * (nEndPos - nCurPos + 1);
+ nCurPos = nEndPos + 1;
+ if (!getRangeData(nCurPos, aData))
+ break;
+
+ nEndPos = aData.mnPos2;
+ }
+ if (nCurPos <= nPos2)
+ {
+ nEndPos = ::std::min(nEndPos, nPos2);
+ nValue += aData.mnValue * (nEndPos - nCurPos + 1);
+ }
+ return nValue;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getRangeData(SCCOLROW nPos, RangeData& rData)
+{
+ ValueType nValue;
+ SCCOLROW nPos1, nPos2;
+
+ if (mbTreeSearchEnabled)
+ {
+ if (!maSegments.is_tree_valid())
+ maSegments.build_tree();
+
+ if (!maSegments.search_tree(nPos, nValue, &nPos1, &nPos2))
+ return false;
+ }
+ else
+ {
+ // Conduct leaf-node only search. Faster when searching between range insertion.
+ if (!maSegments.search(nPos, nValue, &nPos1, &nPos2))
+ return false;
+ }
+
+ rData.mnPos1 = nPos1;
+ rData.mnPos2 = nPos2-1; // end point is not inclusive.
+ rData.mnValue = nValue;
+ return true;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ maSegments.shift_left(nPos1, nPos2);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary)
+{
+ maSegments.shift_right(nPos, nSize, bSkipStartBoundary);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType nValue) const
+{
+ SCCOLROW nPos = numeric_limits<SCCOLROW>::max(); // position not found.
+ typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend();
+ // Note that when searching in reverse direction, we need to skip the first
+ // node, since the right-most leaf node does not store a valid value.
+ for (++itr; itr != itrEnd; ++itr)
+ {
+ if (itr->second != nValue)
+ {
+ nPos = (--itr)->first - 1;
+ break;
+ }
+ }
+ return nPos;
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
+{
+ maItr = maSegments.begin();
+ return getNext(rData);
+}
+
+template<typename _ValueType, typename _ExtValueType>
+bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
+{
+ typename fst_type::const_iterator itrEnd = maSegments.end();
+ if (maItr == itrEnd)
+ return false;
+
+ rData.mnPos1 = maItr->first;
+ rData.mnValue = maItr->second;
+
+ ++maItr;
+ if (maItr == itrEnd)
+ return false;
+
+ rData.mnPos2 = maItr->first - 1;
+ return true;
+}
+
+// ============================================================================
+
+class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
+{
+public:
+ explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault) :
+ ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault)
+ {
+ }
+};
+
+// ----------------------------------------------------------------------------
+
+class ScFlatBoolSegmentsImpl : public ScFlatSegmentsImpl<bool>
+{
+public:
+ explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax) :
+ ScFlatSegmentsImpl<bool>(nMax, false)
+ {
+ }
+
+ void setTrue(SCCOLROW nPos1, SCCOLROW nPos2);
+ void setFalse(SCCOLROW nPos1, SCCOLROW nPos2);
+};
+
+void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ setValue(nPos1, nPos2, true);
+}
+
+void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
+{
+ setValue(nPos1, nPos2, false);
+}
+
+// ============================================================================
+
+ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments& rSegs) :
+ mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mbCurValue(false)
+{
+}
+
+bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos, bool& rVal)
+{
+ if (nPos >= mnCurPos)
+ // It can only go in a forward direction.
+ mnCurPos = nPos;
+
+ if (mnCurPos > mnLastPos)
+ {
+ // position not in the current segment. Update the current value.
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrSegs.getRangeData(mnCurPos, aData))
+ return false;
+
+ mbCurValue = aData.mbValue;
+ mnLastPos = aData.mnRow2;
+ }
+
+ rVal = mbCurValue;
+ return true;
+}
+
+SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
+{
+ return mnLastPos;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
+ mrSegs(rSegs)
+{
+}
+
+bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mrSegs.mpImpl->getFirst(aData))
+ return false;
+
+ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ rRange.mbValue = static_cast<bool>(aData.mnValue);
+ return true;
+}
+
+bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mrSegs.mpImpl->getNext(aData))
+ return false;
+
+ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ rRange.mbValue = static_cast<bool>(aData.mnValue);
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+ mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
+{
+}
+
+ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r) :
+ mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatBoolRowSegments::~ScFlatBoolRowSegments()
+{
+}
+
+void ScFlatBoolRowSegments::setTrue(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->setTrue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatBoolRowSegments::setFalse(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->setFalse(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+bool ScFlatBoolRowSegments::getValue(SCROW nRow)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
+}
+
+bool ScFlatBoolRowSegments::getRangeData(SCROW nRow, RangeData& rData)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
+ return false;
+
+ rData.mbValue = aData.mnValue;
+ rData.mnRow1 = static_cast<SCROW>(aData.mnPos1);
+ rData.mnRow2 = static_cast<SCROW>(aData.mnPos2);
+ return true;
+}
+
+void ScFlatBoolRowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatBoolRowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+SCROW ScFlatBoolRowSegments::findLastNotOf(bool bValue) const
+{
+ return static_cast<SCROW>(mpImpl->findLastNotOf(bValue));
+}
+
+void ScFlatBoolRowSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatBoolRowSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
+// ============================================================================
+
+ScFlatBoolColSegments::ScFlatBoolColSegments() :
+ mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXCOL)))
+{
+}
+
+ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments& r) :
+ mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatBoolColSegments::~ScFlatBoolColSegments()
+{
+}
+
+void ScFlatBoolColSegments::setTrue(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->setTrue(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+void ScFlatBoolColSegments::setFalse(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->setFalse(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+bool ScFlatBoolColSegments::getValue(SCCOL nCol)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nCol));
+}
+
+bool ScFlatBoolColSegments::getRangeData(SCCOL nCol, RangeData& rData)
+{
+ ScFlatBoolSegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nCol), aData))
+ return false;
+
+ rData.mbValue = aData.mnValue;
+ rData.mnCol1 = static_cast<SCCOL>(aData.mnPos1);
+ rData.mnCol2 = static_cast<SCCOL>(aData.mnPos2);
+ return true;
+}
+
+void ScFlatBoolColSegments::removeSegment(SCCOL nCol1, SCCOL nCol2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2));
+}
+
+void ScFlatBoolColSegments::insertSegment(SCCOL nCol, SCCOL nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nCol), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+void ScFlatBoolColSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatBoolColSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
+// ============================================================================
+
+
+// ============================================================================
+
+ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments& rSegs) :
+ mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0)
+{
+}
+
+bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16& rVal)
+{
+ if (nPos >= mnCurPos)
+ // It can only go in a forward direction.
+ mnCurPos = nPos;
+
+ if (mnCurPos > mnLastPos)
+ {
+ // position not in the current segment. Update the current value.
+ ScFlatUInt16RowSegments::RangeData aData;
+ if (!mrSegs.getRangeData(mnCurPos, aData))
+ return false;
+
+ mnCurValue = aData.mnValue;
+ mnLastPos = aData.mnRow2;
+ }
+
+ rVal = mnCurValue;
+ return true;
+}
+
+SCROW ScFlatUInt16RowSegments::ForwardIterator::getLastPos() const
+{
+ return mnLastPos;
+}
+
+// ----------------------------------------------------------------------------
+
+ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(sal_uInt16 nDefault) :
+ mpImpl(new ScFlatUInt16SegmentsImpl(static_cast<SCCOLROW>(MAXROW), nDefault))
+{
+}
+
+ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r) :
+ mpImpl(new ScFlatUInt16SegmentsImpl(*r.mpImpl))
+{
+}
+
+ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments()
+{
+}
+
+void ScFlatUInt16RowSegments::setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue)
+{
+ mpImpl->setValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2), nValue);
+}
+
+sal_uInt16 ScFlatUInt16RowSegments::getValue(SCROW nRow)
+{
+ return mpImpl->getValue(static_cast<SCCOLROW>(nRow));
+}
+
+sal_uInt32 ScFlatUInt16RowSegments::getSumValue(SCROW nRow1, SCROW nRow2)
+{
+ return mpImpl->getSumValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+bool ScFlatUInt16RowSegments::getRangeData(SCROW nRow, RangeData& rData)
+{
+ ScFlatUInt16SegmentsImpl::RangeData aData;
+ if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData))
+ return false;
+
+ rData.mnRow1 = aData.mnPos1;
+ rData.mnRow2 = aData.mnPos2;
+ rData.mnValue = aData.mnValue;
+ return true;
+}
+
+void ScFlatUInt16RowSegments::removeSegment(SCROW nRow1, SCROW nRow2)
+{
+ mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2));
+}
+
+void ScFlatUInt16RowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary)
+{
+ mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary);
+}
+
+SCROW ScFlatUInt16RowSegments::findLastNotOf(sal_uInt16 nValue) const
+{
+ return static_cast<SCROW>(mpImpl->findLastNotOf(nValue));
+}
+
+void ScFlatUInt16RowSegments::enableTreeSearch(bool bEnable)
+{
+ mpImpl->enableTreeSearch(bEnable);
+}
+
+void ScFlatUInt16RowSegments::setInsertFromBack(bool bInsertFromBack)
+{
+ mpImpl->setInsertFromBack(bInsertFromBack);
+}
+
diff --git a/sc/source/core/data/sheetevents.cxx b/sc/source/core/data/sheetevents.cxx
new file mode 100755
index 000000000000..e9e430ef85d9
--- /dev/null
+++ b/sc/source/core/data/sheetevents.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sheetdata.cxx,v $
+ * $Revision: 1.69.32.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/debug.hxx>
+
+#include "sheetevents.hxx"
+
+// -----------------------------------------------------------------------
+
+// static
+rtl::OUString ScSheetEvents::GetEventName(sal_Int32 nEvent)
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return rtl::OUString();
+ }
+
+ static const sal_Char* aEventNames[] =
+ {
+ "OnFocus", // SC_SHEETEVENT_FOCUS
+ "OnUnfocus", // SC_SHEETEVENT_UNFOCUS
+ "OnSelect", // SC_SHEETEVENT_SELECT
+ "OnDoubleClick", // SC_SHEETEVENT_DOUBLECLICK
+ "OnRightClick", // SC_SHEETEVENT_RIGHTCLICK
+ "OnChange", // SC_SHEETEVENT_CHANGE
+ "OnCalculate" // SC_SHEETEVENT_CALCULATE
+ };
+ return rtl::OUString::createFromAscii(aEventNames[nEvent]);
+}
+
+// -----------------------------------------------------------------------
+
+ScSheetEvents::ScSheetEvents() :
+ mpScriptNames(NULL)
+{
+}
+
+ScSheetEvents::~ScSheetEvents()
+{
+ Clear();
+}
+
+void ScSheetEvents::Clear()
+{
+ if (mpScriptNames)
+ {
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ delete mpScriptNames[nEvent];
+ delete[] mpScriptNames;
+ mpScriptNames = NULL;
+ }
+}
+
+ScSheetEvents::ScSheetEvents(const ScSheetEvents& rOther) :
+ mpScriptNames(NULL)
+{
+ *this = rOther;
+}
+
+const ScSheetEvents& ScSheetEvents::operator=(const ScSheetEvents& rOther)
+{
+ Clear();
+ if (rOther.mpScriptNames)
+ {
+ mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT];
+ for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent)
+ if (rOther.mpScriptNames[nEvent])
+ mpScriptNames[nEvent] = new rtl::OUString(*rOther.mpScriptNames[nEvent]);
+ else
+ mpScriptNames[nEvent] = NULL;
+ }
+ return *this;
+}
+
+const rtl::OUString* ScSheetEvents::GetScript(sal_Int32 nEvent) const
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return NULL;
+ }
+
+ if (mpScriptNames)
+ return mpScriptNames[nEvent];
+ return NULL;
+}
+
+void ScSheetEvents::SetScript(sal_Int32 nEvent, const rtl::OUString* pNew)
+{
+ if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT)
+ {
+ DBG_ERRORFILE("invalid event number");
+ return;
+ }
+
+ if (!mpScriptNames)
+ {
+ mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT];
+ for (sal_Int32 nEventIdx=0; nEventIdx<SC_SHEETEVENT_COUNT; ++nEventIdx)
+ mpScriptNames[nEventIdx] = NULL;
+ }
+ delete mpScriptNames[nEvent];
+ if (pNew)
+ mpScriptNames[nEvent] = new rtl::OUString(*pNew);
+ else
+ mpScriptNames[nEvent] = NULL;
+}
+
diff --git a/sc/source/core/data/stlsheet.cxx b/sc/source/core/data/stlsheet.cxx
index 4a4210a7925c..a3319eafd3fd 100644
--- a/sc/source/core/data/stlsheet.cxx
+++ b/sc/source/core/data/stlsheet.cxx
@@ -171,7 +171,7 @@ SfxItemSet& __EXPORT ScStyleSheet::GetItemSet()
// gespeicherte Printer noch nicht geladen ist!
ScDocument* pDoc = ((ScStyleSheetPool&)GetPool()).GetDocument();
- if ( pDoc && pDoc->IsLoadingDone() )
+ if ( pDoc )
{
// Setzen von sinnvollen Default-Werten:
SvxPageItem aPageItem( ATTR_PAGE );
diff --git a/sc/source/core/data/tabbgcolor.cxx b/sc/source/core/data/tabbgcolor.cxx
new file mode 100644
index 000000000000..a3d9eec16d99
--- /dev/null
+++ b/sc/source/core/data/tabbgcolor.cxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tabbgcolor.hxx,v $
+ * $Revision: 1.00 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "tabbgcolor.hxx"
+
+bool ScUndoTabColorInfo::IsDefaultOldTabBgColor() const
+{
+ return maOldTabBgColor == Color(COL_AUTO);
+}
+
+bool ScUndoTabColorInfo::IsDefaultNewTabBgColor() const
+{
+ return maOldTabBgColor == Color(COL_AUTO);
+}
+
+ScUndoTabColorInfo::ScUndoTabColorInfo(SCTAB nTab) :
+ mnTabId(nTab),
+ maOldTabBgColor(COL_AUTO),
+ maNewTabBgColor(COL_AUTO)
+{
+}
+
+ScUndoTabColorInfo::ScUndoTabColorInfo(const ScUndoTabColorInfo& r) :
+ mnTabId(r.mnTabId),
+ maOldTabBgColor(r.maOldTabBgColor),
+ maNewTabBgColor(r.maNewTabBgColor)
+{
+}
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index a8b819072c21..87561abf1513 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -112,6 +112,8 @@
#include "hints.hxx" // fuer Paint-Broadcast
#include "prnsave.hxx"
#include "tabprotection.hxx"
+#include "sheetevents.hxx"
+#include "segmenttree.hxx"
// STATIC DATA -----------------------------------------------------------
@@ -131,14 +133,20 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
nRepeatStartY( SCROW_REPEAT_NONE ),
pTabProtection( NULL ),
pColWidth( NULL ),
- pRowHeight( NULL ),
+ mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ),
pColFlags( NULL ),
pRowFlags( NULL ),
+ mpHiddenCols(new ScFlatBoolColSegments),
+ mpHiddenRows(new ScFlatBoolRowSegments),
+ mpFilteredCols(new ScFlatBoolColSegments),
+ mpFilteredRows(new ScFlatBoolRowSegments),
pOutlineTable( NULL ),
+ pSheetEvents( NULL ),
bTableAreaValid( FALSE ),
bVisible( TRUE ),
bStreamValid( FALSE ),
bPendingRowHeights( FALSE ),
+ bCalcNotification( FALSE ),
nTab( nNewTab ),
nRecalcLvl( 0 ),
pDocument( pDoc ),
@@ -151,8 +159,10 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
nLockCount( 0 ),
pScenarioRanges( NULL ),
aScenarioColor( COL_LIGHTGRAY ),
+ aTabBgColor( COL_AUTO ),
nScenarioFlags( 0 ),
- bActiveScenario( FALSE )
+ bActiveScenario( FALSE ),
+ mbPageBreaksValid(false)
{
if (bColInfo)
@@ -169,7 +179,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
if (bRowInfo)
{
- pRowHeight = new ScSummableCompressedArray< SCROW, USHORT>( MAXROW, ScGlobal::nStdRowHeight);
+ mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight));
pRowFlags = new ScBitMaskCompressedArray< SCROW, BYTE>( MAXROW, 0);
}
@@ -211,8 +221,8 @@ ScTable::~ScTable()
delete[] pColWidth;
delete[] pColFlags;
- delete pRowHeight;
delete pRowFlags;
+ delete pSheetEvents;
delete pOutlineTable;
delete pSearchParam;
delete pSearchText;
@@ -271,6 +281,22 @@ void ScTable::SetLoadingRTL( BOOL bSet )
bLoadingRTL = bSet;
}
+const Color& ScTable::GetTabBgColor() const
+{
+ return aTabBgColor;
+}
+
+void ScTable::SetTabBgColor(const Color& rColor)
+{
+ if (aTabBgColor != rColor)
+ {
+ // The tab color has changed. Set this table 'modified'.
+ aTabBgColor = rColor;
+ if (IsStreamValid())
+ SetStreamValid(false);
+ }
+}
+
void ScTable::SetScenario( BOOL bFlag )
{
bScenario = bFlag;
@@ -969,9 +995,10 @@ BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
// auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
//! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
- if ( pRowFlags && ( pRowFlags->GetValue(nRow) & CR_HIDDEN ) )
+ if (RowHidden(nRow))
return FALSE;
- if ( pColFlags && ( pColFlags[nCol] & CR_HIDDEN ) )
+
+ if (ColHidden(nCol))
return FALSE;
}
@@ -998,8 +1025,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
{
BOOL bUp = ( nMovY < 0 );
nRow = rMark.GetNextMarked( nCol, nRow, bUp );
- while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
- pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
+ while ( VALIDROW(nRow) &&
+ (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
{
// #53697# ausgeblendete ueberspringen (s.o.)
nRow += nMovY;
@@ -1009,7 +1036,7 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
while ( nRow < 0 || nRow > MAXROW )
{
nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
- while ( VALIDCOL(nCol) && pColFlags && (pColFlags[nCol] & CR_HIDDEN) )
+ while ( VALIDCOL(nCol) && ColHidden(nCol) )
nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // #53697# skip hidden rows (see above)
if (nCol < 0)
{
@@ -1028,8 +1055,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
else if (nRow > MAXROW)
nRow = 0;
nRow = rMark.GetNextMarked( nCol, nRow, bUp );
- while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
- pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
+ while ( VALIDROW(nRow) &&
+ (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
{
// #53697# ausgeblendete ueberspringen (s.o.)
nRow += nMovY;
@@ -1420,93 +1447,140 @@ void ScTable::ExtendPrintArea( OutputDevice* pDev,
double nPPTX = aPix1000.X() / 1000.0;
double nPPTY = aPix1000.Y() / 1000.0;
- BOOL bEmpty[MAXCOLCOUNT];
- for (SCCOL i=0; i<=MAXCOL; i++)
- bEmpty[i] = ( aCol[i].GetCellCount() == 0 );
-
- SCSIZE nIndex;
- SCCOL nPrintCol = rEndCol;
- SCSIZE nRowFlagsIndex;
- SCROW nRowFlagsEndRow;
- BYTE nRowFlag = pRowFlags->GetValue( nStartRow, nRowFlagsIndex, nRowFlagsEndRow);
- for (SCROW nRow = nStartRow; nRow<=nEndRow; nRow++)
+ // First, mark those columns that we need to skip i.e. hidden and empty columns.
+
+ ScFlatBoolColSegments aSkipCols;
+ aSkipCols.setInsertFromBack(true); // speed optimazation.
+ aSkipCols.setFalse(0, MAXCOL);
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
{
- if (nRow > nRowFlagsEndRow)
- nRowFlag = pRowFlags->GetNextValue( nRowFlagsIndex, nRowFlagsEndRow);
- if ( ( nRowFlag & CR_HIDDEN ) == 0 )
+ SCCOL nLastCol = i;
+ if (ColHidden(i, NULL, &nLastCol))
+ {
+ // Columns are hidden in this range.
+ aSkipCols.setTrue(i, nLastCol);
+ }
+ else
{
- SCCOL nDataCol = rEndCol;
- while (nDataCol > 0 && ( bEmpty[nDataCol] || !aCol[nDataCol].Search(nRow,nIndex) ) )
- --nDataCol;
- if ( ( pColFlags[nDataCol] & CR_HIDDEN ) == 0 )
+ // These columns are visible. Check for empty columns.
+ for (SCCOL j = i; j <= nLastCol; ++j)
{
- ScBaseCell* pCell = aCol[nDataCol].GetCell(nRow);
- if (pCell)
- {
- CellType eType = pCell->GetCellType();
- if (eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT
- || (eType == CELLTYPE_FORMULA && !((ScFormulaCell*)pCell)->IsValue()) )
- {
- BOOL bFormula = FALSE; //! uebergeben
- long nPixel = pCell->GetTextWidth();
-
- // Breite bereits im Idle-Handler berechnet?
- if ( TEXTWIDTH_DIRTY == nPixel )
- {
- ScNeededSizeOptions aOptions;
- aOptions.bTotalSize = TRUE;
- aOptions.bFormula = bFormula;
- aOptions.bSkipMerged = FALSE;
-
- Fraction aZoom(1,1);
- nPixel = aCol[nDataCol].GetNeededSize( nRow,
- pDev,nPPTX,nPPTY,aZoom,aZoom,
- TRUE, aOptions );
- pCell->SetTextWidth( (USHORT)nPixel );
- }
+ if (aCol[j].GetCellCount() == 0)
+ // empty
+ aSkipCols.setTrue(j,j);
+ }
+ }
+ i = nLastCol;
+ }
- long nTwips = (long) (nPixel / nPPTX);
- long nDocW = GetColWidth( nDataCol );
+ ScFlatBoolColSegments::RangeData aColData;
+ for (SCCOL nCol = rEndCol; nCol >= 0; --nCol)
+ {
+ if (!aSkipCols.getRangeData(nCol, aColData))
+ // Failed to get the data. This should never happen!
+ return;
- long nMissing = nTwips - nDocW;
- if ( nMissing > 0 )
- {
- // look at alignment
-
- const ScPatternAttr* pPattern = GetPattern( nDataCol, nRow );
- const SfxItemSet* pCondSet = NULL;
- if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
- pCondSet = pDocument->GetCondResult( nDataCol, nRow, nTab );
-
- SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
- pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
- if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
- nMissing /= 2; // distributed into both directions
- else
- {
- // STANDARD is LEFT (only text is handled here)
- BOOL bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
- if ( IsLayoutRTL() )
- bRight = !bRight;
- if ( bRight )
- nMissing = 0; // extended only to the left (logical)
- }
- }
+ if (aColData.mbValue)
+ {
+ // Skip these columns.
+ nCol = aColData.mnCol1; // move toward 0.
+ continue;
+ }
- SCCOL nCol = nDataCol;
- while (nMissing > 0 && nCol < MAXCOL)
- {
- ++nCol;
- nMissing -= GetColWidth( nCol );
- }
- if (nCol>nPrintCol)
- nPrintCol = nCol;
- }
- }
+ // These are visible and non-empty columns.
+ for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol)
+ {
+ SCCOL nPrintCol = nDataCol;
+ VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]);
+ ScBaseCell* pCell = aIter.reset(nStartRow);
+ if (!pCell)
+ // No visible cells found in this column. Skip it.
+ continue;
+
+ while (pCell)
+ {
+ SCCOL nNewCol = nDataCol;
+ SCROW nRow = aIter.getRow();
+ if (nRow > nEndRow)
+ // Went past the last row position. Bail out.
+ break;
+
+ MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY);
+ if (nNewCol > nPrintCol)
+ nPrintCol = nNewCol;
+ pCell = aIter.next();
}
+
+ if (nPrintCol > rEndCol)
+ // Make sure we don't shrink the print area.
+ rEndCol = nPrintCol;
+ }
+ nCol = aColData.mnCol1; // move toward 0.
+ }
+}
+
+void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY)
+{
+ ScBaseCell* pCell = aCol[rCol].GetCell(nRow);
+ if (!pCell || !pCell->HasStringData())
+ return;
+
+ bool bFormula = false; //! ueberge
+ long nPixel = pCell->GetTextWidth();
+
+ // Breite bereits im Idle-Handler berechnet?
+ if ( TEXTWIDTH_DIRTY == nPixel )
+ {
+ ScNeededSizeOptions aOptions;
+ aOptions.bTotalSize = TRUE;
+ aOptions.bFormula = bFormula;
+ aOptions.bSkipMerged = FALSE;
+
+ Fraction aZoom(1,1);
+ nPixel = aCol[rCol].GetNeededSize(
+ nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
+ pCell->SetTextWidth( (USHORT)nPixel );
+ }
+
+ long nTwips = (long) (nPixel / nPPTX);
+ long nDocW = GetColWidth( rCol );
+
+ long nMissing = nTwips - nDocW;
+ if ( nMissing > 0 )
+ {
+ // look at alignment
+
+ const ScPatternAttr* pPattern = GetPattern( rCol, nRow );
+ const SfxItemSet* pCondSet = NULL;
+ if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
+ pCondSet = pDocument->GetCondResult( rCol, nRow, nTab );
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
+ if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
+ nMissing /= 2; // distributed into both directions
+ else
+ {
+ // STANDARD is LEFT (only text is handled here)
+ bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
+ if ( IsLayoutRTL() )
+ bRight = !bRight;
+ if ( bRight )
+ nMissing = 0; // extended only to the left (logical)
}
}
- rEndCol = nPrintCol;
+
+ SCCOL nNewCol = rCol;
+ while (nMissing > 0 && nNewCol < MAXCOL)
+ {
+ ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow);
+ if (pNextCell && pNextCell->GetCellType() != CELLTYPE_NOTE)
+ // Cell content in a next column ends display of this string.
+ nMissing = 0;
+ else
+ nMissing -= GetColWidth(++nNewCol);
+ }
+ rCol = nNewCol;
}
void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
@@ -1597,7 +1671,104 @@ void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
UpdatePageBreaks(NULL);
}
+SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1;
+
+ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) :
+ mrRowSegs(rRowSegs),
+ mrColumn(rColumn),
+ mpCell(NULL),
+ mnCurRow(ROW_NOT_FOUND),
+ mnUBound(ROW_NOT_FOUND)
+{
+}
+
+ScTable::VisibleDataCellIterator::~VisibleDataCellIterator()
+{
+}
+ScBaseCell* ScTable::VisibleDataCellIterator::reset(SCROW nRow)
+{
+ if (nRow > MAXROW)
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrRowSegs.getRangeData(nRow, aData))
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+ if (!aData.mbValue)
+ {
+ // specified row is visible. Take it.
+ mnCurRow = nRow;
+ mnUBound = aData.mnRow2;
+ }
+ else
+ {
+ // specified row is not-visible. The first visible row is the start of
+ // the next segment.
+ mnCurRow = aData.mnRow2 + 1;
+ mnUBound = mnCurRow; // get range data on the next iteration.
+ if (mnCurRow > MAXROW)
+ {
+ // Make sure the row doesn't exceed our current limit.
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+ }
+
+ mpCell = mrColumn.GetCell(mnCurRow);
+ if (mpCell)
+ // First visible cell found.
+ return mpCell;
+
+ // Find a first visible cell below this row (if any).
+ return next();
+}
+
+ScBaseCell* ScTable::VisibleDataCellIterator::next()
+{
+ if (mnCurRow == ROW_NOT_FOUND)
+ return NULL;
+
+ while (mrColumn.GetNextDataPos(mnCurRow))
+ {
+ if (mnCurRow > mnUBound)
+ {
+ // We don't know the visibility of this row range. Query it.
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mrRowSegs.getRangeData(mnCurRow, aData))
+ {
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+ }
+
+ if (aData.mbValue)
+ {
+ // This row is invisible. Skip to the last invisible row and
+ // try again.
+ mnCurRow = mnUBound = aData.mnRow2;
+ continue;
+ }
+
+ // This row is visible.
+ mnUBound = aData.mnRow2;
+ }
+
+ mpCell = mrColumn.GetCell(mnCurRow);
+ if (mpCell)
+ return mpCell;
+ }
+ mnCurRow = ROW_NOT_FOUND;
+ return NULL;
+}
+
+SCROW ScTable::VisibleDataCellIterator::getRow() const
+{
+ return mnCurRow;
+}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 69d16df7be58..9bd5b031fde5 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -56,7 +56,9 @@
#include "fillinfo.hxx"
#include "bcaslot.hxx"
#include "postit.hxx"
+#include "sheetevents.hxx"
#include "globstr.hrc"
+#include "segmenttree.hxx"
#include <math.h>
@@ -97,6 +99,27 @@ void ScTable::StartOutlineTable()
}
+void ScTable::SetSheetEvents( const ScSheetEvents* pNew )
+{
+ delete pSheetEvents;
+ if (pNew)
+ pSheetEvents = new ScSheetEvents(*pNew);
+ else
+ pSheetEvents = NULL;
+
+ SetCalcNotification( FALSE ); // discard notifications before the events were set
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
+}
+
+
+void ScTable::SetCalcNotification( BOOL bSet )
+{
+ bCalcNotification = bSet;
+}
+
+
BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize )
{
BOOL bTest = TRUE;
@@ -117,22 +140,28 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
InitializeNoteCaptions();
if (nStartCol==0 && nEndCol==MAXCOL)
{
- if (pRowHeight && pRowFlags)
+ if (mpRowHeights && pRowFlags)
{
- pRowHeight->Insert( nStartRow, nSize);
+ mpRowHeights->insertSegment(nStartRow, nSize, false);
BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize);
// only copy manual size flag, clear all others
if (nNewFlags && (nNewFlags != CR_MANUALSIZE))
pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1,
nNewFlags & CR_MANUALSIZE);
}
+
if (pOutlineTable)
pOutlineTable->InsertRow( nStartRow, nSize );
+
+ mpFilteredRows->insertSegment(nStartRow, nSize, true);
+ mpHiddenRows->insertSegment(nStartRow, nSize, true);
}
for (SCCOL j=nStartCol; j<=nEndCol; j++)
aCol[j].InsertRow( nStartRow, nSize );
DecRecalcLevel( false );
+
+ InvalidatePageBreaks();
}
@@ -143,15 +172,19 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
InitializeNoteCaptions();
if (nStartCol==0 && nEndCol==MAXCOL)
{
- if (pRowHeight && pRowFlags)
- {
- pRowHeight->Remove( nStartRow, nSize);
+ if (pRowFlags)
pRowFlags->Remove( nStartRow, nSize);
- }
+
+ if (mpRowHeights)
+ mpRowHeights->removeSegment(nStartRow, nStartRow+nSize);
+
if (pOutlineTable)
if (pOutlineTable->DeleteRow( nStartRow, nSize ))
if (pUndoOutline)
*pUndoOutline = TRUE;
+
+ mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
+ mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
}
{ // scope for bulk broadcast
@@ -160,6 +193,8 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE
aCol[j].DeleteRow( nStartRow, nSize );
}
DecRecalcLevel();
+
+ InvalidatePageBreaks();
}
@@ -195,6 +230,9 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
}
if (pOutlineTable)
pOutlineTable->InsertCol( nStartCol, nSize );
+
+ mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
+ mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true);
}
@@ -226,6 +264,8 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
}
}
DecRecalcLevel();
+
+ InvalidatePageBreaks();
}
@@ -247,6 +287,10 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
if (pOutlineTable->DeleteCol( nStartCol, nSize ))
if (pUndoOutline)
*pUndoOutline = TRUE;
+
+ SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
+ mpHiddenCols->removeSegment(nStartCol, nRmSize);
+ mpFilteredCols->removeSegment(nStartCol, nRmSize);
}
@@ -268,6 +312,8 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
}
DecRecalcLevel();
+
+ InvalidatePageBreaks();
}
@@ -339,20 +385,21 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// copy widths/heights, and only "hidden", "filtered" and "manual" flags
// also for all preceding columns/rows, to have valid positions for drawing objects
- if (pColFlags && pTable->pColFlags && pColWidth && pTable->pColWidth)
+ if (pColWidth && pTable->pColWidth)
for (i=0; i<=nCol2; i++)
- {
- pTable->pColFlags[i] = pColFlags[i] & CR_HIDDEN;
pTable->pColWidth[i] = pColWidth[i];
- }
- if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight)
+ pTable->CopyColHidden(*this, 0, nCol2);
+ pTable->CopyColFiltered(*this, 0, nCol2);
+
+ if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
{
- pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2,
- (CR_HIDDEN | CR_FILTERED | CR_MANUALSIZE));
- pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2);
+ pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
+ pTable->CopyRowHeight(*this, 0, nRow2, 0);
}
+ pTable->CopyRowHidden(*this, 0, nRow2);
+ pTable->CopyRowFiltered(*this, 0, nRow2);
// ggf. Formeln durch Werte ersetzen
@@ -393,10 +440,10 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
for (i=nCol1; i<=nCol2; i++)
pColWidth[i] = pTable->pColWidth[i-nDx];
- if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight &&
+ if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights &&
pRowFlags && pTable->pRowFlags)
{
- pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy);
+ CopyRowHeight(*pTable, nRow1, nRow2, -nDy);
// Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
for (SCROW j=nRow1; j<=nRow2; j++)
{
@@ -631,8 +678,10 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// Charts muessen beim Ein-/Ausblenden angepasst werden
ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection();
+ bool bFlagChange = false;
+
BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
- BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
+ BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
if (bWidth||bHeight)
{
@@ -641,33 +690,77 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
if (bWidth)
for (SCCOL i=nCol1; i<=nCol2; i++)
{
- BOOL bChange = pCharts &&
- ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN );
+ bool bThisHidden = ColHidden(i);
+ bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden);
+ bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
pDestTab->pColWidth[i] = pColWidth[i];
pDestTab->pColFlags[i] = pColFlags[i];
+ pDestTab->SetColHidden(i, i, bThisHidden);
//! Aenderungen zusammenfassen?
- if (bChange)
+ if (bHiddenChange && pCharts)
pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
+
+ if (bChange)
+ bFlagChange = true;
}
if (bHeight)
{
- pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
- for (SCROW i=nRow1; i<=nRow2; i++)
+ bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2);
+
+ if (bChange)
+ bFlagChange = true;
+
+ pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
+ pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
+
+ // Hidden flags.
+ for (SCROW i = nRow1; i <= nRow2; ++i)
{
- // TODO: might need some performance improvement, block
- // operations instead of single GetValue()/SetValue() calls.
- BYTE nThisRowFlags = pRowFlags->GetValue(i);
- BOOL bChange = pCharts &&
- ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN );
- pDestTab->pRowFlags->SetValue( i, nThisRowFlags );
- //! Aenderungen zusammenfassen?
- if (bChange)
- pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab ));
+ SCROW nThisLastRow, nDestLastRow;
+ bool bThisHidden = RowHidden(i, NULL, &nThisLastRow);
+ bool bDestHidden = pDestTab->RowHidden(i, NULL, &nDestLastRow);
+
+ // If the segment sizes differ, we take the shorter segment of the two.
+ SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow);
+ if (nLastRow >= nRow2)
+ // the last row shouldn't exceed the upper bound the caller specified.
+ nLastRow = nRow2;
+
+ pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
+
+ bool bThisHiddenChange = (bThisHidden != bDestHidden);
+ if (bThisHiddenChange && pCharts)
+ {
+ // Hidden flags differ.
+ pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab));
+ }
+
+ if (bThisHiddenChange)
+ bFlagChange = true;
+
+ // Jump to the last row of the identical flag segment.
+ i = nLastRow;
+ }
+
+ // Filtered flags.
+ for (SCROW i = nRow1; i <= nRow2; ++i)
+ {
+ SCROW nLastRow;
+ bool bFiltered = RowFiltered(i, NULL, &nLastRow);
+ if (nLastRow >= nRow2)
+ // the last row shouldn't exceed the upper bound the caller specified.
+ nLastRow = nRow2;
+ pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
+ i = nLastRow;
}
}
pDestTab->DecRecalcLevel();
}
+
+ if (bFlagChange)
+ pDestTab->InvalidatePageBreaks();
+
pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags
}
}
@@ -681,7 +774,7 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
{
BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
- BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight);
+ BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
if (bWidth||bHeight)
IncRecalcLevel();
@@ -701,8 +794,8 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
for (SCCOL i=nCol1; i<=nCol2; i++)
pDestTab->pColWidth[i] = pColWidth[i];
if (bHeight)
- pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
- DecRecalcLevel();
+ pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0);
+ DecRecalcLevel();
}
}
}
@@ -714,6 +807,16 @@ void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
}
+void ScTable::InvalidateTableArea()
+{
+ bTableAreaValid = FALSE;
+}
+
+void ScTable::InvalidatePageBreaks()
+{
+ mbPageBreaksValid = false;
+}
+
void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
{
DBG_ASSERT( bScenario, "bScenario == FALSE" );
@@ -1093,6 +1196,17 @@ void ScTable::SetRelNameDirty()
}
+void ScTable::SetLoadingMedium(bool bLoading)
+{
+ mpRowHeights->enableTreeSearch(!bLoading);
+
+ // When loading a medium, prefer inserting row heights from the back
+ // position since the row heights are stored and read in ascending order
+ // during import.
+ mpRowHeights->setInsertFromBack(bLoading);
+}
+
+
void ScTable::CalcAll()
{
for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll();
@@ -1240,7 +1354,7 @@ BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
- const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) const
+ const ScPatternAttr* pPattern, const SfxItemSet* pCondSet )
{
// Rueckgabe = neues nArrY
@@ -1273,7 +1387,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
{
- if ( !(pRowFlags->GetValue(nRow) & CR_HIDDEN) )
+ if (!RowHidden(nRow))
{
BOOL bHitOne = TRUE;
if ( nCol > nX2+1 )
@@ -1281,7 +1395,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
// reicht die gedrehte Zelle bis in den sichtbaren Bereich?
SCCOL nTouchedCol = nCol;
- long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor );
+ long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor);
DBG_ASSERT(nWidth <= 0, "Richtung falsch");
while ( nWidth < 0 && nTouchedCol > 0 )
{
@@ -1307,9 +1421,9 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
return nArrY;
}
-void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) const
+void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 )
{
- if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags )
+ if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags )
{
DBG_ERROR( "Spalten-/Zeileninfo fehlt" );
return;
@@ -1322,7 +1436,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC
for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
{
- if ( !(pColFlags[nCol] & CR_HIDDEN) )
+ if (!ColHidden(nCol))
{
SCSIZE nArrY = 0;
ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
@@ -1837,36 +1951,24 @@ void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRem
double nPPTX, double nPPTY,
const Fraction& rZoomX, const Fraction& rZoomY )
{
- BOOL* pUsed = new BOOL[MAXROWCOUNT];
- memset( pUsed, 0, sizeof(BOOL) * (MAXROWCOUNT) );
+ ScFlatBoolRowSegments aUsedRows;
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved);
- SCCOL nCol;
- for (nCol=0; nCol<=MAXCOL; nCol++)
- aCol[nCol].FindStyleSheet( pStyleSheet, pUsed, bRemoved );
-
- BOOL bFound = FALSE;
- SCROW nStart = 0, nEnd = 0;
- for (SCROW i=0; i<=MAXROW; i++)
+ SCROW nRow = 0;
+ while (nRow <= MAXROW)
{
- if (pUsed[i])
- {
- if (!bFound)
- {
- nStart = i;
- bFound = TRUE;
- }
- nEnd = i;
- }
- else if (bFound)
- {
- SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE );
- bFound = FALSE;
- }
- }
- if (bFound)
- SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE );
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!aUsedRows.getRangeData(nRow, aData))
+ // search failed!
+ return;
- delete[] pUsed;
+ SCROW nEndRow = aData.mnRow2;
+ if (aData.mbValue)
+ SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE);
+
+ nRow = nEndRow + 1;
+ }
}
@@ -1948,6 +2050,8 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
pColWidth[nCol] = nNewWidth;
DecRecalcLevel();
+
+ InvalidatePageBreaks();
}
}
else
@@ -1959,7 +2063,7 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
{
- if (VALIDROW(nRow) && pRowHeight)
+ if (VALIDROW(nRow) && mpRowHeights)
{
if (!nNewHeight)
{
@@ -1967,7 +2071,7 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
nNewHeight = ScGlobal::nStdRowHeight;
}
- USHORT nOldHeight = pRowHeight->GetValue(nRow);
+ sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow);
if ( nNewHeight != nOldHeight )
{
IncRecalcLevel();
@@ -1975,8 +2079,10 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
- pRowHeight->SetValue( nRow, nNewHeight);
+ mpRowHeights->setValue(nRow, nRow, nNewHeight);
DecRecalcLevel();
+
+ InvalidatePageBreaks();
}
}
else
@@ -1985,12 +2091,45 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
}
}
+namespace {
+
+/**
+ * Check if the new pixel size is different from the old size between
+ * specified ranges.
+ */
+bool lcl_pixelSizeChanged(
+ ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow,
+ sal_uInt16 nNewHeight, double nPPTY)
+{
+ long nNewPix = static_cast<long>(nNewHeight * nPPTY);
+
+ ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights);
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ sal_uInt16 nHeight;
+ if (!aFwdIter.getValue(nRow, nHeight))
+ break;
+
+ if (nHeight != nNewHeight)
+ {
+ bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY));
+ if (bChanged)
+ return true;
+ }
+
+ // Skip ahead to the last position of the current range.
+ nRow = aFwdIter.getLastPos();
+ }
+ return false;
+}
+
+}
BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
double /* nPPTX */, double nPPTY )
{
BOOL bChanged = FALSE;
- if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight)
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
{
IncRecalcLevel();
InitializeNoteCaptions();
@@ -2000,8 +2139,6 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
nNewHeight = ScGlobal::nStdRowHeight;
}
- long nNewPix = (long) ( nNewHeight * nPPTY );
-
BOOL bSingle = FALSE; // TRUE = process every row for its own
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
@@ -2010,24 +2147,17 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
if (bSingle)
{
- size_t nIndex;
- SCROW nRegionEndRow;
- USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow);
- if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow)
+ ScFlatUInt16RowSegments::RangeData aData;
+ mpRowHeights->getRangeData(nStartRow, aData);
+ if (nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2)
bSingle = FALSE; // no difference in this range
}
if (bSingle)
{
if (nEndRow-nStartRow < 20)
{
- // Whether new pixel size will differ from old pixel size in any row.
- ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
- nStartRow, nEndRow);
- do
- {
- if (*aIter != nNewHeight)
- bChanged = (nNewPix != (long) (*aIter * nPPTY));
- } while (!bChanged && aIter.NextRange());
+ if (!bChanged)
+ bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
/* #i94028# #i94991# If drawing objects are involved, each row
has to be changed for its own, because each call to
@@ -2039,12 +2169,12 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow )
{
pDrawLayer->HeightChanged( nTab, nRow,
- ((long) nNewHeight) - ((long) pRowHeight->GetValue( nRow )));
- pRowHeight->SetValue( nRow, nNewHeight );
+ static_cast<long>(nNewHeight) - static_cast<long>(mpRowHeights->getValue(nRow)));
+ mpRowHeights->setValue(nRow, nRow, nNewHeight);
}
}
else
- pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
}
else
{
@@ -2059,23 +2189,22 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
{
if (pDrawLayer)
{
- unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow);
+ unsigned long nOldHeights = GetRowHeight(nStartRow, nEndRow);
// FIXME: should we test for overflows?
long nHeightDif = (long) (unsigned long) nNewHeight *
(nEndRow - nStartRow + 1) - nOldHeights;
pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif );
}
- // Whether new pixel size will differ from old pixel size in any row.
- ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight,
- nStartRow, nEndRow);
- do
- {
- if (*aIter != nNewHeight)
- bChanged = (nNewPix != (long) (*aIter * nPPTY));
- } while (!bChanged && aIter.NextRange());
- pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
+
+ if (!bChanged)
+ bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY);
+
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
}
DecRecalcLevel();
+
+ if (bChanged)
+ InvalidatePageBreaks();
}
else
{
@@ -2085,6 +2214,16 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig
return bChanged;
}
+void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight )
+{
+ if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights)
+ return;
+
+ if (!nNewHeight)
+ nNewHeight = ScGlobal::nStdRowHeight;
+
+ mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight);
+}
void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
{
@@ -2102,13 +2241,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
}
-USHORT ScTable::GetColWidth( SCCOL nCol ) const
+USHORT ScTable::GetColWidth( SCCOL nCol )
{
DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
if (VALIDCOL(nCol) && pColFlags && pColWidth)
{
- if ( pColFlags[nCol] & CR_HIDDEN )
+ if (ColHidden(nCol))
return 0;
else
return pColWidth[nCol];
@@ -2129,7 +2268,7 @@ USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingest
}
-USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
+USHORT ScTable::GetCommonWidth( SCCOL nEndCol )
{
// get the width that is used in the largest continuous column range (up to nEndCol)
@@ -2141,24 +2280,24 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
USHORT nMaxWidth = 0;
USHORT nMaxCount = 0;
- USHORT nRangeStart = 0;
+ SCCOL nRangeStart = 0;
while ( nRangeStart <= nEndCol )
{
// skip hidden columns
- while ( nRangeStart <= nEndCol && (pColFlags[nRangeStart] & CR_HIDDEN) )
+ while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) )
++nRangeStart;
if ( nRangeStart <= nEndCol )
{
USHORT nThisCount = 0;
USHORT nThisWidth = pColWidth[nRangeStart];
- USHORT nRangeEnd = nRangeStart;
+ SCCOL nRangeEnd = nRangeStart;
while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth )
{
++nThisCount;
++nRangeEnd;
// skip hidden columns
- while ( nRangeEnd <= nEndCol && (pColFlags[nRangeEnd] & CR_HIDDEN) )
+ while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) )
++nRangeEnd;
}
@@ -2176,44 +2315,80 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
}
-USHORT ScTable::GetRowHeight( SCROW nRow ) const
+USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero )
{
DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer");
- if (VALIDROW(nRow) && pRowFlags && pRowHeight)
+ if (VALIDROW(nRow) && mpRowHeights)
{
- if ( pRowFlags->GetValue(nRow) & CR_HIDDEN )
+ if (bHiddenAsZero && RowHidden(nRow))
return 0;
else
- return pRowHeight->GetValue(nRow);
+ {
+ ScFlatUInt16RowSegments::RangeData aData;
+ if (!mpRowHeights->getRangeData(nRow, aData))
+ // TODO: What should we return in case the search fails?
+ return 0;
+
+ if (pStartRow)
+ *pStartRow = aData.mnRow1;
+ if (pEndRow)
+ *pEndRow = aData.mnRow2;
+ return aData.mnValue;
+ }
}
else
return (USHORT) ScGlobal::nStdRowHeight;
}
-ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
+ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow )
{
DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
- if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight)
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
{
- return pRowFlags->SumCoupledArrayForCondition( nStartRow, nEndRow,
- CR_HIDDEN, 0, *pRowHeight);
+ ULONG nHeight = 0;
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow))
+ {
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ nHeight += mpRowHeights->getSumValue(nRow, nLastRow);
+ }
+ nRow = nLastRow + 1;
+ }
+ return nHeight;
}
else
return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight);
}
-ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
+ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale )
{
DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
- if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight)
+ if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights)
{
- return pRowFlags->SumScaledCoupledArrayForCondition( nStartRow,
- nEndRow, CR_HIDDEN, 0, *pRowHeight, fScale);
+ ULONG nHeight = 0;
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow))
+ {
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow);
+ nHeight += static_cast<ULONG>(nThisHeight * fScale);
+ }
+ nRow = nLastRow + 1;
+ }
+ return nHeight;
}
else
return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
@@ -2224,8 +2399,8 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid
{
DBG_ASSERT(VALIDROW(nRow),"wrong row number");
- if (VALIDROW(nRow) && pRowHeight)
- return pRowHeight->GetValue(nRow);
+ if (VALIDROW(nRow) && mpRowHeights)
+ return mpRowHeights->getValue(nRow);
else
return (USHORT) ScGlobal::nStdRowHeight;
}
@@ -2234,28 +2409,26 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid
// Spalten-/Zeilen-Flags
-SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
+SCROW ScTable::GetHiddenRowCount( SCROW nRow )
{
- SCROW nEndRow = nRow;
- if ( pRowFlags )
- {
- nEndRow = pRowFlags->GetBitStateEnd( nRow, CR_HIDDEN, CR_HIDDEN);
- if (ValidRow(nEndRow))
- ++nEndRow;
- else
- nEndRow = nRow;
- }
- return nEndRow - nRow;
+ if (!ValidRow(nRow))
+ return 0;
+
+ SCROW nLastRow = -1;
+ if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow))
+ return 0;
+
+ return nLastRow - nRow + 1;
}
//! ShowRows / DBShowRows zusammenfassen
-void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
+void ScTable::ShowCol(SCCOL nCol, bool bShow)
{
- if (VALIDCOL(nCol) && pColFlags)
+ if (VALIDCOL(nCol))
{
- BOOL bWasVis = ( pColFlags[nCol] & CR_HIDDEN ) == 0;
+ bool bWasVis = !ColHidden(nCol);
if (bWasVis != bShow)
{
IncRecalcLevel();
@@ -2269,11 +2442,8 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
}
- if (bShow)
- pColFlags[nCol] &= ~CR_HIDDEN;
- else
- pColFlags[nCol] |= CR_HIDDEN;
- DecRecalcLevel();
+ SetColHidden(nCol, nCol, !bShow);
+ DecRecalcLevel();
ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
if ( pCharts )
@@ -2287,12 +2457,11 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
}
-void ScTable::ShowRow(SCROW nRow, BOOL bShow)
+void ScTable::ShowRow(SCROW nRow, bool bShow)
{
if (VALIDROW(nRow) && pRowFlags)
{
- BYTE nFlags = pRowFlags->GetValue(nRow);
- BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
+ bool bWasVis = !RowHidden(nRow);
if (bWasVis != bShow)
{
IncRecalcLevel();
@@ -2301,20 +2470,23 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
if (pDrawLayer)
{
if (bShow)
- pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
+ pDrawLayer->HeightChanged(
+ nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow)));
else
- pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
+ pDrawLayer->HeightChanged(
+ nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow)));
}
+ SetRowHidden(nRow, nRow, !bShow);
if (bShow)
- pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED));
- else
- pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN);
- DecRecalcLevel();
+ SetRowFiltered(nRow, nRow, false);
+ DecRecalcLevel();
ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
if ( pCharts )
pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
+
+ InvalidatePageBreaks();
}
}
else
@@ -2324,12 +2496,11 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
}
-void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
+void ScTable::DBShowRow(SCROW nRow, bool bShow)
{
if (VALIDROW(nRow) && pRowFlags)
{
- BYTE nFlags = pRowFlags->GetValue(nRow);
- BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
+ bool bWasVis = !RowHidden(nRow);
IncRecalcLevel();
InitializeNoteCaptions();
if (bWasVis != bShow)
@@ -2338,18 +2509,18 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
if (pDrawLayer)
{
if (bShow)
- pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) );
+ pDrawLayer->HeightChanged(
+ nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow)));
else
- pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) );
+ pDrawLayer->HeightChanged(
+ nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow)));
}
}
// Filter-Flag immer setzen, auch wenn Hidden unveraendert
- if (bShow)
- pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED));
- else
- pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED));
- DecRecalcLevel();
+ SetRowHidden(nRow, nRow, !bShow);
+ SetRowFiltered(nRow, nRow, !bShow);
+ DecRecalcLevel();
if (bWasVis != bShow)
{
@@ -2359,6 +2530,8 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
if (pOutlineTable)
UpdateOutlineRow( nRow, nRow, bShow );
+
+ InvalidatePageBreaks();
}
}
else
@@ -2368,26 +2541,25 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
}
-void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
{
SCROW nStartRow = nRow1;
IncRecalcLevel();
InitializeNoteCaptions();
while (nStartRow <= nRow2)
{
- BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
- SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag);
+ SCROW nEndRow = -1;
+ bool bWasVis = !RowHidden(nStartRow, nEndRow);
if (nEndRow > nRow2)
nEndRow = nRow2;
- BOOL bWasVis = ( nOldFlag == 0 );
BOOL bChanged = ( bWasVis != bShow );
if ( bChanged )
{
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
{
- long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
+ long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow));
if (bShow)
pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
else
@@ -2395,10 +2567,8 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
}
}
- if (bShow)
- pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) );
- else
- pRowFlags->OrValue( nStartRow, nEndRow, (CR_HIDDEN | CR_FILTERED));
+ SetRowHidden(nStartRow, nEndRow, !bShow);
+ SetRowFiltered(nStartRow, nEndRow, !bShow);
if ( bChanged )
{
@@ -2420,26 +2590,25 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
}
-void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
{
SCROW nStartRow = nRow1;
IncRecalcLevel();
InitializeNoteCaptions();
while (nStartRow <= nRow2)
{
- BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN;
- SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag);
+ SCROW nEndRow = -1;
+ bool bWasVis = !RowHidden(nStartRow, nEndRow);
if (nEndRow > nRow2)
nEndRow = nRow2;
- BOOL bWasVis = ( nOldFlag == 0 );
BOOL bChanged = ( bWasVis != bShow );
if ( bChanged )
{
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if (pDrawLayer)
{
- long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow);
+ long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow));
if (bShow)
pDrawLayer->HeightChanged( nTab, nStartRow, nHeight );
else
@@ -2447,16 +2616,17 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
}
}
+ SetRowHidden(nStartRow, nEndRow, !bShow);
if (bShow)
- pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) );
- else
- pRowFlags->OrValue( nStartRow, nEndRow, CR_HIDDEN);
+ SetRowFiltered(nStartRow, nEndRow, false);
if ( bChanged )
{
ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
if ( pCharts )
pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
+
+ InvalidatePageBreaks();
}
nStartRow = nEndRow + 1;
@@ -2465,16 +2635,6 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
}
-BOOL ScTable::IsFiltered(SCROW nRow) const
-{
- if (VALIDROW(nRow) && pRowFlags)
- return ( pRowFlags->GetValue(nRow) & CR_FILTERED ) != 0;
-
- DBG_ERROR("Falsche Zeilennummer oder keine Flags");
- return FALSE;
-}
-
-
void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
{
if (VALIDCOL(nCol) && pColFlags)
@@ -2528,11 +2688,32 @@ BYTE ScTable::GetRowFlags( SCROW nRow ) const
SCROW ScTable::GetLastFlaggedRow() const
{
- if ( !pRowFlags )
- return 0;
+ SCROW nLastFound = 0;
+ if (pRowFlags)
+ {
+ SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
+ if (ValidRow(nRow))
+ nLastFound = nRow;
+ }
+
+ if (!maRowManualBreaks.empty())
+ nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
+
+ if (mpHiddenRows)
+ {
+ SCROW nRow = mpHiddenRows->findLastNotOf(false);
+ if (ValidRow(nRow))
+ nLastFound = ::std::max(nLastFound, nRow);
+ }
+
+ if (mpFilteredRows)
+ {
+ SCROW nRow = mpFilteredRows->findLastNotOf(false);
+ if (ValidRow(nRow))
+ nLastFound = ::std::max(nLastFound, nRow);
+ }
- SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
- return ValidRow(nLastFound) ? nLastFound : 0;
+ return nLastFound;
}
@@ -2543,7 +2724,7 @@ SCCOL ScTable::GetLastChangedCol() const
SCCOL nLastFound = 0;
for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
- if ((pColFlags[nCol] & ~CR_PAGEBREAK) || (pColWidth[nCol] != STD_COL_WIDTH))
+ if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
nLastFound = nCol;
return nLastFound;
@@ -2555,11 +2736,12 @@ SCROW ScTable::GetLastChangedRow() const
if ( !pRowFlags )
return 0;
- SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
- if (!ValidRow(nLastFlags))
- nLastFlags = 0;
+ SCROW nLastFlags = GetLastFlaggedRow();
- SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight);
+ // Find the last row position where the height is NOT the standard row
+ // height.
+ // KOHEI: Test this to make sure it does what it's supposed to.
+ SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight);
if (!ValidRow(nLastHeight))
nLastHeight = 0;
@@ -2572,7 +2754,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
if (pOutlineTable && pColFlags)
{
ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
- return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, aArray );
+ return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true );
}
else
return FALSE;
@@ -2582,7 +2764,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
{
if (pOutlineTable && pRowFlags)
- return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *pRowFlags );
+ return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false );
else
return FALSE;
}
@@ -2590,54 +2772,58 @@ BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
{
- if (pColFlags)
- {
- while ( rX1>0 ? (pColFlags[rX1-1] & CR_HIDDEN) : FALSE )
- --rX1;
- while ( rX2<MAXCOL ? (pColFlags[rX2+1] & CR_HIDDEN) : FALSE )
- ++rX2;
- }
- if (pRowFlags)
+ // Column-wise expansion
+
+ while (rX1 > 0 && ColHidden(rX1-1))
+ --rX1;
+
+ while (rX2 < MAXCOL && ColHidden(rX2+1))
+ ++rX2;
+
+ // Row-wise expansion
+
+ if (rY1 > 0)
{
- if (rY1 > 0)
+ ScFlatBoolRowSegments::RangeData aData;
+ if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
{
- SCROW nStartRow = pRowFlags->GetBitStateStart( rY1-1, CR_HIDDEN, CR_HIDDEN);
+ SCROW nStartRow = aData.mnRow1;
if (ValidRow(nStartRow))
rY1 = nStartRow;
}
- if (rY2 < MAXROW)
- {
- SCROW nEndRow = pRowFlags->GetBitStateEnd( rY2+1, CR_HIDDEN, CR_HIDDEN);
- if (ValidRow(nEndRow))
- rY2 = nEndRow;
- }
+ }
+ if (rY2 < MAXROW)
+ {
+ SCROW nEndRow = -1;
+ if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow))
+ rY2 = nEndRow;
}
}
void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
{
- if (pColFlags)
- {
- while ( rX2>rX1 && (pColFlags[rX2] & CR_HIDDEN) )
- --rX2;
- while ( rX2>rX1 && (pColFlags[rX1] & CR_HIDDEN) )
- ++rX1;
- }
- if (pRowFlags)
+ while ( rX2>rX1 && ColHidden(rX2) )
+ --rX2;
+ while ( rX2>rX1 && ColHidden(rX1) )
+ ++rX1;
+
+ if (rY1 < rY2)
{
- if (rY1 < rY2)
+ ScFlatBoolRowSegments::RangeData aData;
+ if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
{
- SCROW nStartRow = pRowFlags->GetBitStateStart( rY2, CR_HIDDEN, CR_HIDDEN);
+ SCROW nStartRow = aData.mnRow1;
if (ValidRow(nStartRow) && nStartRow >= rY1)
rY2 = nStartRow;
}
- if (rY1 < rY2)
- {
- SCROW nEndRow = pRowFlags->GetBitStateEnd( rY1, CR_HIDDEN, CR_HIDDEN);
- if (ValidRow(nEndRow) && nEndRow <= rY2)
- rY1 = nEndRow;
- }
+ }
+
+ if (rY1 < rY2)
+ {
+ SCROW nEndRow = -1;
+ if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2)
+ rY1 = nEndRow;
}
}
@@ -2799,16 +2985,16 @@ BOOL ScTable::RefVisible(ScFormulaCell* pCell)
if (pCell->HasOneReference(aRef))
{
- if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab() && pRowFlags)
+ if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
{
- // while ((value & CR_FILTERED) == CR_FILTERED)
- // most times will be faster than
- // while ((value & CR_FILTERED) == 0)
- SCROW nEndRow = pRowFlags->GetBitStateEnd( aRef.aStart.Row(),
- CR_FILTERED, CR_FILTERED);
+ SCROW nEndRow;
+ if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
+ // row not filtered.
+ nEndRow = ::std::numeric_limits<SCROW>::max();
+
if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
return TRUE; // at least partly visible
- return FALSE; // completely unvisible
+ return FALSE; // completely invisible
}
}
@@ -2850,18 +3036,17 @@ void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos
}
-ULONG ScTable::GetRowOffset( SCROW nRow ) const
+ULONG ScTable::GetRowOffset( SCROW nRow )
{
ULONG n = 0;
- if ( pRowFlags && pRowHeight )
+ if ( mpHiddenRows && mpRowHeights )
{
if (nRow == 0)
return 0;
else if (nRow == 1)
return GetRowHeight(0);
- n = pRowFlags->SumCoupledArrayForCondition( 0, nRow-1, CR_HIDDEN, 0,
- *pRowHeight);
+ n = GetTotalRowHeight(0, nRow-1);
#ifdef DBG_UTIL
if (n == ::std::numeric_limits<unsigned long>::max())
DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
@@ -2874,18 +3059,42 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const
return n;
}
+SCROW ScTable::GetRowForHeight(ULONG nHeight)
+{
+ sal_uInt32 nSum = 0;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ for (SCROW nRow = 0; nRow <= MAXROW; ++nRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mbValue)
+ {
+ nRow = aData.mnRow2;
+ continue;
+ }
+
+ sal_uInt32 nNew = mpRowHeights->getValue(nRow);
+ nSum += nNew;
+ if (nSum > nHeight)
+ {
+ return nRow < MAXROW ? nRow + 1 : MAXROW;
+ }
+ }
+ return -1;
+}
+
-ULONG ScTable::GetColOffset( SCCOL nCol ) const
+ULONG ScTable::GetColOffset( SCCOL nCol )
{
ULONG n = 0;
- if ( pColFlags && pColWidth )
+ if ( pColWidth )
{
SCCOL i;
- BYTE* pFlags = pColFlags;
- USHORT* pWidth = pColWidth;
- for( i = 0; i < nCol; i++, pFlags++, pWidth++ )
- if( !( *pFlags & CR_HIDDEN ) )
- n += *pWidth;
+ for( i = 0; i < nCol; i++ )
+ if (!ColHidden(i))
+ n += pColWidth[i];
}
else
{
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 7d295b6286a8..bd6a2c92c442 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -208,17 +208,14 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress& rProgress )
{
BOOL bByRow = aSortParam.bByRow;
SCSIZE nCount = pArray->GetCount();
+ SCCOLROW nStart = pArray->GetStart();
ScSortInfo** ppInfo = pArray->GetFirstArray();
- // hngngn.. Win16 legacy? Table has ULONG count but can only be initialized using USHORT :-/
- // FIXME: use std::vector instead, would be better anyway (type safe)
- USHORT nArghl = (nCount > USHRT_MAX ? USHRT_MAX : static_cast<USHORT>(nCount));
- Table aTable( nArghl );
+ ::std::vector<ScSortInfo*> aTable(nCount);
SCSIZE nPos;
for ( nPos = 0; nPos < nCount; nPos++ )
- {
- aTable.Insert( ppInfo[nPos]->nOrg, (void*) ppInfo[nPos] );
- }
- SCCOLROW nDest = pArray->GetStart();
+ aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
+
+ SCCOLROW nDest = nStart;
for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
{
SCCOLROW nOrg = ppInfo[nPos]->nOrg;
@@ -231,9 +228,9 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress& rProgress )
// neue Position des weggeswapten eintragen
ScSortInfo* p = ppInfo[nPos];
p->nOrg = nDest;
- p = (ScSortInfo*) aTable.Replace( nDest, (void*) p );
+ ::std::swap(p, aTable[nDest-nStart]);
p->nOrg = nOrg;
- p = (ScSortInfo*) aTable.Replace( nOrg, (void*) p );
+ ::std::swap(p, aTable[nOrg-nStart]);
DBG_ASSERT( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
}
rProgress.SetStateOnPercent( nPos );
@@ -449,14 +446,17 @@ void ScTable::SwapRow(SCROW nRow1, SCROW nRow2)
}
}
}
- if (bGlobalKeepQuery && pRowFlags)
+ if (bGlobalKeepQuery)
{
- BYTE nRow1Flags = pRowFlags->GetValue(nRow1);
- BYTE nRow2Flags = pRowFlags->GetValue(nRow2);
- BYTE nFlags1 = nRow1Flags & ( CR_HIDDEN | CR_FILTERED );
- BYTE nFlags2 = nRow2Flags & ( CR_HIDDEN | CR_FILTERED );
- pRowFlags->SetValue( nRow1, (nRow1Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags2);
- pRowFlags->SetValue( nRow2, (nRow2Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags1);
+ bool bRow1Hidden = RowHidden(nRow1);
+ bool bRow2Hidden = RowHidden(nRow2);
+ SetRowHidden(nRow1, nRow1, bRow2Hidden);
+ SetRowHidden(nRow2, nRow2, bRow1Hidden);
+
+ bool bRow1Filtered = RowFiltered(nRow1);
+ bool bRow2Filtered = RowFiltered(nRow2);
+ SetRowFiltered(nRow1, nRow1, bRow2Filtered);
+ SetRowFiltered(nRow2, nRow2, bRow1Filtered);
}
}
@@ -616,7 +616,7 @@ void ScTable::RemoveSubTotals( ScSubTotalParam& rParam )
if ( pCell->GetCellType() == CELLTYPE_FORMULA )
if (((ScFormulaCell*)pCell)->IsSubTotal())
{
- SetRowFlags(nRow+1,GetRowFlags(nRow+1)&(~CR_MANUALBREAK));
+ RemoveRowBreak(nRow+1, false, true);
pDocument->DeleteRow( 0,nTab, MAXCOL,nTab, nRow, 1 );
--nEndRow;
aIter = ScColumnIterator( &aCol[nCol],nRow,nEndRow );
@@ -784,9 +784,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
bBlockVis = FALSE;
if ( rParam.bPagebreak && nRow < MAXROW &&
aRowEntry.nSubStartRow != nStartRow && nLevel == 0)
- SetRowFlags( aRowEntry.nSubStartRow,
- GetRowFlags(aRowEntry.nSubStartRow) |
- CR_MANUALBREAK);
+ SetRowBreak(aRowEntry.nSubStartRow, false, true);
if (bSpaceLeft)
{
@@ -839,13 +837,6 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString );
ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, *pStyle );
-/* if (rParam.bPagebreak && nRow < MAXROW)
- {
- BYTE nFlags = GetRowFlags( nRow+1 );
- nFlags |= CR_MANUALBREAK;
- SetRowFlags( nRow+1, nFlags );
- }
-*/
++nRow;
++nEndRow;
aRowEntry.nSubStartRow = nRow;
@@ -859,11 +850,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
}
}
}
- if (!pRowFlags)
- bBlockVis = TRUE;
- else
- if ( (pRowFlags->GetValue(nRow) & CR_FILTERED) == 0 )
- bBlockVis = TRUE;
+ bBlockVis = !RowFiltered(nRow);
}
}
else
@@ -1935,8 +1922,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
SCCOL nCol;
if ( rMark.IsMultiMarked() )
for (nCol=0; nCol<=MAXCOL && !rData.bError; nCol++)
- if ( !pColFlags || !( pColFlags[nCol] & CR_HIDDEN ) )
- aCol[nCol].UpdateSelectionFunction( rMark, rData, pRowFlags,
+ if ( !pColFlags || !ColHidden(nCol) )
+ aCol[nCol].UpdateSelectionFunction( rMark, rData, *mpHiddenRows,
bSingle && ( nCol >= nStartCol && nCol <= nEndCol ),
nStartRow, nEndRow );
@@ -1944,8 +1931,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
if ( bSingle && !rMark.IsMarkNegative() )
for (nCol=nStartCol; nCol<=nEndCol && !rData.bError; nCol++)
- if ( !pColFlags || !( pColFlags[nCol] & CR_HIDDEN ) )
- aCol[nCol].UpdateAreaFunction( rData, pRowFlags, nStartRow, nEndRow );
+ if ( !pColFlags || !ColHidden(nCol) )
+ aCol[nCol].UpdateAreaFunction( rData, *mpHiddenRows, nStartRow, nEndRow );
}
void ScTable::FindConditionalFormat( ULONG nKey, ScRangeList& rList )
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index a3a0153a4b97..2635b5821e4f 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -50,8 +50,15 @@
#include "brdcst.hxx"
#include "tabprotection.hxx"
#include "globstr.hrc"
+#include "segmenttree.hxx"
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+
+#include <algorithm>
+#include <limits>
using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::sheet::TablePageBreakData;
+using ::std::set;
// STATIC DATA -----------------------------------------------------------
@@ -62,8 +69,18 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
{
if ( pDocument->IsImportingXML() )
return;
- if ( !pUserArea && !bPageSizeValid )
- return;
+
+ // pUserArea != NULL -> print area is specified. We need to force-update
+ // the page breaks.
+
+ if (!pUserArea)
+ {
+ if (!bPageSizeValid)
+ return;
+
+ if (mbPageBreaksValid)
+ return;
+ }
SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()->
Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
@@ -76,7 +93,6 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
const SfxPoolItem* pItem;
SCCOL nX;
- SCROW nY;
SCCOL nStartCol = 0;
SCROW nStartRow = 0;
SCCOL nEndCol = MAXCOL;
@@ -96,8 +112,9 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
// bei mehreren Bereichen nichts anzeigen:
for (nX=0; nX<MAXCOL; nX++)
- pColFlags[nX] &= ~CR_PAGEBREAK;
- pRowFlags->AndValue( 0, MAXROW-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
+ RemoveColBreak(nX, true, false);
+
+ RemoveRowPageBreaks(0, MAXROW-1);
return;
}
@@ -143,13 +160,13 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
// Anfang: Breaks loeschen
for (nX=0; nX<nStartCol; nX++)
- pColFlags[nX] &= ~CR_PAGEBREAK;
- pRowFlags->AndValue( 0, nStartRow-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
+ RemoveColBreak(nX, true, false);
+ RemoveRowPageBreaks(0, nStartRow-1);
if (nStartCol > 0)
- pColFlags[nStartCol] |= CR_PAGEBREAK; //! AREABREAK
+ SetColBreak(nStartCol, true, false); // AREABREAK
if (nStartRow > 0)
- pRowFlags->OrValue( nStartRow, CR_PAGEBREAK); //! AREABREAK
+ SetRowBreak(nStartRow, true, false); // AREABREAK
// Mittelteil: Breaks verteilen
@@ -159,15 +176,16 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
for (nX=nStartCol; nX<=nEndCol; nX++)
{
BOOL bStartOfPage = FALSE;
- long nThisX = ( pColFlags[nX] & CR_HIDDEN ) ? 0 : pColWidth[nX];
- if ( (nSizeX+nThisX > nPageSizeX) || ((pColFlags[nX] & CR_MANUALBREAK) && !bSkipColBreaks) )
+ long nThisX = ColHidden(nX) ? 0 : pColWidth[nX];
+ bool bManualBreak = HasColManualBreak(nX);
+ if ( (nSizeX+nThisX > nPageSizeX) || (bManualBreak && !bSkipColBreaks) )
{
- pColFlags[nX] |= CR_PAGEBREAK;
+ SetColBreak(nX, true, false);
nSizeX = 0;
bStartOfPage = TRUE;
}
else if (nX != nStartCol)
- pColFlags[nX] &= ~CR_PAGEBREAK;
+ RemoveColBreak(nX, true, false);
else
bStartOfPage = TRUE;
@@ -175,9 +193,9 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
{
// subtract size of repeat columns from page size
for (SCCOL i=nRepeatStartX; i<=nRepeatEndX; i++)
- nPageSizeX -= ( pColFlags[i] & CR_HIDDEN ) ? 0 : pColWidth[i];
+ nPageSizeX -= ColHidden(i) ? 0 : pColWidth[i];
while (nX<=nRepeatEndX)
- pColFlags[++nX] &= ~CR_PAGEBREAK;
+ RemoveColBreak(++nX, true, false);
bColFound = TRUE;
}
@@ -185,23 +203,40 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
}
// Remove all page breaks in range.
- pRowFlags->AndValue( nStartRow+1, nEndRow, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
+ RemoveRowPageBreaks(nStartRow+1, nEndRow);
+
// And set new page breaks.
BOOL bRepeatRow = ( nRepeatStartY != SCROW_REPEAT_NONE );
BOOL bRowFound = FALSE;
long nSizeY = 0;
- ScCompressedArrayIterator< SCROW, BYTE> aFlagsIter( *pRowFlags, nStartRow, nEndRow);
- ScCompressedArrayIterator< SCROW, USHORT> aHeightIter( *pRowHeight, nStartRow, nEndRow);
- for ( ; aFlagsIter; ++aFlagsIter, ++aHeightIter)
+ ScFlatBoolRowSegments::ForwardIterator aIterHidden(*mpHiddenRows);
+ ScFlatUInt16RowSegments::ForwardIterator aIterHeights(*mpRowHeights);
+ SCROW nNextManualBreak = GetNextManualBreak(nStartRow); // -1 => no more manual breaks
+ for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
{
- nY = aFlagsIter.GetPos();
BOOL bStartOfPage = FALSE;
- BYTE nFlags = *aFlagsIter;
- long nThisY = (nFlags & CR_HIDDEN) ? 0 : *aHeightIter;
- if ( (nSizeY+nThisY > nPageSizeY) || ((nFlags & CR_MANUALBREAK) && !bSkipRowBreaks) )
+ bool bThisRowHidden = false;
+ aIterHidden.getValue(nY, bThisRowHidden);
+ long nThisY = 0;
+ if (!bThisRowHidden)
+ {
+ sal_uInt16 nTmp;
+ aIterHeights.getValue(nY, nTmp);
+ nThisY = static_cast<long>(nTmp);
+ }
+
+ bool bManualBreak = false;
+ if (nNextManualBreak >= 0)
+ {
+ bManualBreak = (nY == nNextManualBreak);
+ if (nY >= nNextManualBreak)
+ // Query the next menual break position.
+ nNextManualBreak = GetNextManualBreak(nY+1);
+ }
+
+ if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipRowBreaks) )
{
- pRowFlags->SetValue( nY, nFlags | CR_PAGEBREAK);
- aFlagsIter.Resync( nY);
+ SetRowBreak(nY, true, false);
nSizeY = 0;
bStartOfPage = TRUE;
}
@@ -213,21 +248,47 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
if ( bStartOfPage && bRepeatRow && nY>nRepeatStartY && !bRowFound )
{
// subtract size of repeat rows from page size
- unsigned long nHeights = pRowFlags->SumCoupledArrayForCondition(
- nRepeatStartY, nRepeatEndY, CR_HIDDEN, 0, *pRowHeight);
+ unsigned long nHeights = GetTotalRowHeight(nRepeatStartY, nRepeatEndY);
#ifdef DBG_UTIL
if (nHeights == ::std::numeric_limits<unsigned long>::max())
DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow");
#endif
nPageSizeY -= nHeights;
if (nY <= nRepeatEndY)
+ RemoveRowPageBreaks(nY, nRepeatEndY);
+ bRowFound = TRUE;
+ }
+
+ if (bThisRowHidden)
+ {
+ // Hidden row range. Skip them unless there is a manual break.
+ SCROW nLastCommon = aIterHidden.getLastPos();
+ if (nNextManualBreak >= 0)
+ nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1);
+ nY = nLastCommon;
+ }
+ else
+ {
+ // Visible row range.
+
+ SCROW nLastHidden = aIterHidden.getLastPos();
+ SCROW nLastHeight = aIterHeights.getLastPos();
+ SCROW nLastCommon = ::std::min(nLastHidden, nLastHeight);
+ if (nNextManualBreak >= 0)
+ nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1);
+
+ if (nLastCommon > nY)
{
- pRowFlags->AndValue( nY, nRepeatEndY, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
- nY = nRepeatEndY + 1;
- aFlagsIter.Resync( nY);
- aHeightIter.Resync( nY);
+ long nMaxMultiple = static_cast<long>(nLastCommon - nY);
+ long nMultiple = (nPageSizeY - nSizeY) / nThisY;
+ if (nMultiple > nMaxMultiple)
+ nMultiple = nMaxMultiple;
+ if (nMultiple > 1)
+ {
+ nSizeY += nThisY * (nMultiple - 1);
+ nY += nMultiple - 1;
+ }
}
- bRowFound = TRUE;
}
nSizeY += nThisY;
@@ -237,26 +298,24 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
if (nEndCol < MAXCOL)
{
- pColFlags[nEndCol+1] |= CR_PAGEBREAK; //! AREABREAK
+ SetColBreak(nEndCol+1, true, false); // AREABREAK
for (nX=nEndCol+2; nX<=MAXCOL; nX++)
- pColFlags[nX] &= ~CR_PAGEBREAK;
+ RemoveColBreak(nX, true, false);
}
if (nEndRow < MAXROW)
{
- pRowFlags->OrValue( nEndRow+1, CR_PAGEBREAK); //! AREABREAK
+ SetRowBreak(nEndRow+1, true, false); // AREABREAK
if (nEndRow+2 <= MAXROW)
- pRowFlags->AndValue( nEndRow+2, MAXROW, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
+ RemoveRowPageBreaks(nEndRow+2, MAXROW);
}
+ mbPageBreaksValid = true;
}
void ScTable::RemoveManualBreaks()
{
- if (pColFlags)
- for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++)
- pColFlags[nCol] &= ~CR_MANUALBREAK;
-
- if (pRowFlags)
- pRowFlags->AndValue( 0, MAXROW, sal::static_int_cast<BYTE>(~CR_MANUALBREAK) );
+ maRowManualBreaks.clear();
+ maColManualBreaks.clear();
+ InvalidatePageBreaks();
if (IsStreamValid())
SetStreamValid(FALSE);
@@ -264,22 +323,673 @@ void ScTable::RemoveManualBreaks()
BOOL ScTable::HasManualBreaks() const
{
- if (pColFlags)
- for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++)
- if ( pColFlags[nCol] & CR_MANUALBREAK )
- return TRUE;
+ return !maRowManualBreaks.empty() || !maColManualBreaks.empty();
+}
+
+void ScTable::GetAllRowBreaks(set<SCROW>& rBreaks, bool bPage, bool bManual) const
+{
+ if (bPage)
+ rBreaks = maRowPageBreaks;
+
+ if (bManual)
+ {
+ using namespace std;
+ copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
+ }
+}
+
+void ScTable::GetAllColBreaks(set<SCCOL>& rBreaks, bool bPage, bool bManual) const
+{
+ if (bPage)
+ rBreaks = maColPageBreaks;
- if (pRowFlags)
- if (ValidRow( pRowFlags->GetLastAnyBitAccess( 0, CR_MANUALBREAK)))
- return TRUE;
+ if (bManual)
+ {
+ using namespace std;
+ copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
+ }
+}
+
+bool ScTable::HasRowPageBreak(SCROW nRow) const
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ return maRowPageBreaks.count(nRow) > 0;
+}
+
+bool ScTable::HasColPageBreak(SCCOL nCol) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return maColPageBreaks.count(nCol) > 0;
+}
+
+bool ScTable::HasRowManualBreak(SCROW nRow) const
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ return maRowManualBreaks.count(nRow) > 0;
+}
- return FALSE;
+bool ScTable::HasColManualBreak(SCCOL nCol) const
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ return (maColManualBreaks.count(nCol) > 0);
+}
+
+SCROW ScTable::GetNextManualBreak(SCROW nRow) const
+{
+ set<SCROW>::const_iterator itr = maRowManualBreaks.lower_bound(nRow);
+ return itr == maRowManualBreaks.end() ? -1 : *itr;
+}
+
+void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow)
+{
+ using namespace std;
+
+ if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
+ return;
+
+ set<SCROW>::iterator low = maRowPageBreaks.lower_bound(nStartRow);
+ set<SCROW>::iterator high = maRowPageBreaks.upper_bound(nEndRow);
+ maRowPageBreaks.erase(low, high);
+}
+
+void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual)
+{
+ if (!ValidRow(nRow))
+ return;
+
+ if (bPage)
+ maRowPageBreaks.erase(nRow);
+
+ if (bManual)
+ {
+ maRowManualBreaks.erase(nRow);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual)
+{
+ if (!ValidCol(nCol))
+ return;
+
+ if (bPage)
+ maColPageBreaks.erase(nCol);
+
+ if (bManual)
+ {
+ maColManualBreaks.erase(nCol);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual)
+{
+ if (!ValidRow(nRow))
+ return;
+
+ if (bPage)
+ maRowPageBreaks.insert(nRow);
+
+ if (bManual)
+ {
+ maRowManualBreaks.insert(nRow);
+ InvalidatePageBreaks();
+ }
+}
+
+void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual)
+{
+ if (!ValidCol(nCol))
+ return;
+
+ if (bPage)
+ maColPageBreaks.insert(nCol);
+
+ if (bManual)
+ {
+ maColManualBreaks.insert(nCol);
+ InvalidatePageBreaks();
+ }
+}
+
+Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
+{
+ using ::std::copy;
+ using ::std::inserter;
+
+ set<SCROW> aRowBreaks = maRowPageBreaks;
+ copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin()));
+
+ set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end();
+ Sequence<TablePageBreakData> aSeq(aRowBreaks.size());
+
+ for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i)
+ {
+ SCROW nRow = *itr;
+ TablePageBreakData aData;
+ aData.Position = nRow;
+ aData.ManualBreak = HasRowManualBreak(nRow);
+ aSeq[i] = aData;
+ }
+
+ return aSeq;
+}
+
+bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidRow(nRow))
+ return true;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // search failed.
+ return true;
+
+ if (pFirstRow)
+ *pFirstRow = aData.mnRow1;
+ if (pLastRow)
+ *pLastRow = aData.mnRow2;
+
+ return aData.mbValue;
+}
+
+
+bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow)
+{
+ rLastRow = nRow;
+ if (!ValidRow(nRow))
+ return true;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // search failed.
+ return true;
+
+ rLastRow = aData.mnRow2;
+ return aData.mbValue;
+}
+
+bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bHidden = RowHidden(nRow, nLastRow);
+ if (bHidden)
+ return true;
+
+ nRow = nLastRow + 1;
+ }
+ return false;
+}
+
+bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol)
+{
+ rLastCol = nCol;
+ if (!ValidCol(nCol))
+ return true;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpHiddenCols->getRangeData(nCol, aData))
+ return true;
+
+ rLastCol = aData.mnCol2;
+ return aData.mbValue;
+}
+
+bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidCol(nCol))
+ return true;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpHiddenCols->getRangeData(nCol, aData))
+ return true;
+
+ if (pFirstCol)
+ *pFirstCol = aData.mnCol1;
+ if (pLastCol)
+ *pLastCol = aData.mnCol2;
+
+ return aData.mbValue;
+}
+
+void ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
+{
+ if (bHidden)
+ mpHiddenRows->setTrue(nStartRow, nEndRow);
+ else
+ mpHiddenRows->setFalse(nStartRow, nEndRow);
+}
+
+void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden)
+{
+ if (bHidden)
+ mpHiddenCols->setTrue(nStartCol, nEndCol);
+ else
+ mpHiddenCols->setFalse(nStartCol, nEndCol);
+}
+
+void ScTable::CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
+{
+ SCCOL nCol = nStartCol;
+ while (nCol <= nEndCol)
+ {
+ SCCOL nLastCol;
+ bool bHidden = rTable.ColHidden(nCol, NULL, &nLastCol);
+ if (nLastCol > nEndCol)
+ nLastCol = nEndCol;
+
+ SetColHidden(nCol, nLastCol, bHidden);
+ nCol = nLastCol + 1;
+ }
+}
+
+void ScTable::CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bHidden = rTable.RowHidden(nRow, nLastRow);
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ SetRowHidden(nRow, nLastRow, bHidden);
+ nRow = nLastRow + 1;
+ }
+}
+
+void ScTable::CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset)
+{
+ SCROW nRow = nStartRow;
+ ScFlatUInt16RowSegments::RangeData aSrcData;
+ while (nRow <= nEndRow)
+ {
+ if (!rSrcTable.mpRowHeights->getRangeData(nRow + nSrcOffset, aSrcData))
+ // Something is wrong !
+ return;
+
+ SCROW nLastRow = aSrcData.mnRow2 - nSrcOffset;
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+
+ mpRowHeights->setValue(nRow, nLastRow, aSrcData.mnValue);
+ nRow = nLastRow + 1;
+ }
+}
+
+SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // visible row found
+ return nRow;
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nEndRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow >= nStartRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // visible row found
+ return nRow;
+
+ nRow = aData.mnRow1 - 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nCount = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ nCount += aData.mnRow2 - nRow + 1;
+
+ nRow = aData.mnRow2 + 1;
+ }
+ return nCount;
+}
+
+sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow)
+{
+ sal_uInt32 nHeight = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpHiddenRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ // visible row range.
+ nHeight += mpRowHeights->getSumValue(nRow, aData.mnRow2);
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return nHeight;
+}
+
+SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol)
+{
+ if (bCol)
+ {
+ SCCOL nCol = static_cast<SCCOL>(nPos);
+ if (ColHidden(nCol))
+ {
+ for (SCCOL i = nCol+1; i <= MAXCOL; ++i)
+ {
+ if (!ColHidden(nCol))
+ return nCol - 1;
+ }
+ }
+ }
+ else
+ {
+ SCROW nRow = static_cast<SCROW>(nPos);
+ SCROW nLastRow;
+ if (RowHidden(nRow, NULL, &nLastRow))
+ return static_cast<SCCOLROW>(nLastRow);
+ }
+ return ::std::numeric_limits<SCCOLROW>::max();
+}
+
+bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ ScFlatBoolRowSegments::RangeData aData;
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // search failed.
+ return false;
+
+ if (pFirstRow)
+ *pFirstRow = aData.mnRow1;
+ if (pLastRow)
+ *pLastRow = aData.mnRow2;
+
+ return aData.mbValue;
+}
+
+bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
+{
+ if (!ValidCol(nCol))
+ return false;
+
+ ScFlatBoolColSegments::RangeData aData;
+ if (!mpFilteredCols->getRangeData(nCol, aData))
+ // search failed.
+ return false;
+
+ if (pFirstCol)
+ *pFirstCol = aData.mnCol1;
+ if (pLastCol)
+ *pLastCol = aData.mnCol2;
+
+ return aData.mbValue;
+}
+
+bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = nRow;
+ bool bFiltered = RowFiltered(nRow, NULL, &nLastRow);
+ if (bFiltered)
+ return true;
+
+ nRow = nLastRow + 1;
+ }
+ return false;
+}
+
+void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
+{
+ SCCOL nCol = nStartCol;
+ while (nCol <= nEndCol)
+ {
+ SCCOL nLastCol;
+ bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol);
+ if (nLastCol > nEndCol)
+ nLastCol = nEndCol;
+
+ SetColFiltered(nCol, nLastCol, bFiltered);
+ nCol = nLastCol + 1;
+ }
+}
+
+void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ while (nRow <= nEndRow)
+ {
+ SCROW nLastRow = -1;
+ bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow);
+ if (nLastRow > nEndRow)
+ nLastRow = nEndRow;
+ SetRowFiltered(nRow, nLastRow, bFiltered);
+ nRow = nLastRow + 1;
+ }
+}
+
+void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
+{
+ if (bFiltered)
+ mpFilteredRows->setTrue(nStartRow, nEndRow);
+ else
+ mpFilteredRows->setFalse(nStartRow, nEndRow);
+}
+
+void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
+{
+ if (bFiltered)
+ mpFilteredCols->setTrue(nStartCol, nEndCol);
+ else
+ mpFilteredCols->setFalse(nStartCol, nEndCol);
+}
+
+SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // non-filtered row found
+ return nRow;
+
+ nRow = aData.mnRow2 + 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nRow = nEndRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow >= nStartRow)
+ {
+ if (!ValidRow(nRow))
+ break;
+
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ // failed to get range data.
+ break;
+
+ if (!aData.mbValue)
+ // non-filtered row found
+ return nRow;
+
+ nRow = aData.mnRow1 - 1;
+ }
+
+ return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow)
+{
+ SCROW nCount = 0;
+ SCROW nRow = nStartRow;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= nEndRow)
+ {
+ if (!mpFilteredRows->getRangeData(nRow, aData))
+ break;
+
+ if (aData.mnRow2 > nEndRow)
+ aData.mnRow2 = nEndRow;
+
+ if (!aData.mbValue)
+ nCount += aData.mnRow2 - nRow + 1;
+
+ nRow = aData.mnRow2 + 1;
+ }
+ return nCount;
+}
+
+namespace {
+
+void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments,
+ BYTE* pColFlags, ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, const BYTE nFlagMask)
+{
+ using ::sal::static_int_cast;
+
+ pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~nFlagMask));
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ pColFlags[i] &= static_int_cast<BYTE>(~nFlagMask);
+
+ {
+ // row hidden flags.
+
+ SCROW nRow = 0;
+ ScFlatBoolRowSegments::RangeData aData;
+ while (nRow <= MAXROW)
+ {
+ if (!rRowSegments.getRangeData(nRow, aData))
+ break;
+
+ if (aData.mbValue)
+ pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(nFlagMask));
+
+ nRow = aData.mnRow2 + 1;
+ }
+ }
+
+ {
+ // column hidden flags.
+
+ SCCOL nCol = 0;
+ ScFlatBoolColSegments::RangeData aData;
+ while (nCol <= MAXCOL)
+ {
+ if (!rColSegments.getRangeData(nCol, aData))
+ break;
+
+ if (aData.mbValue)
+ {
+ for (SCCOL i = nCol; i <= aData.mnCol2; ++i)
+ pColFlags[i] |= nFlagMask;
+ }
+
+ nCol = aData.mnCol2 + 1;
+ }
+ }
+}
+
+}
+
+void ScTable::SyncColRowFlags()
+{
+ using ::sal::static_int_cast;
+
+ // Manual breaks.
+ pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
+
+ if (!maRowManualBreaks.empty())
+ {
+ for (set<SCROW>::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end();
+ itr != itrEnd; ++itr)
+ pRowFlags->OrValue(*itr, static_int_cast<BYTE>(CR_MANUALBREAK));
+ }
+
+ if (!maColManualBreaks.empty())
+ {
+ for (set<SCCOL>::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end();
+ itr != itrEnd; ++itr)
+ pColFlags[*itr] |= CR_MANUALBREAK;
+ }
+
+ // Hidden flags.
+ lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN);
+ lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED);
}
void ScTable::SetPageSize( const Size& rSize )
{
if ( rSize.Width() != 0 && rSize.Height() != 0 )
{
+ if (aPageSizeTwips != rSize)
+ InvalidatePageBreaks();
+
bPageSizeValid = TRUE;
aPageSizeTwips = rSize;
}
diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx
index 5b87fef3151a..2709dd54d1fb 100644
--- a/sc/source/core/data/tabprotection.cxx
+++ b/sc/source/core/data/tabprotection.cxx
@@ -33,6 +33,7 @@
#include "tabprotection.hxx"
#include "tools/debug.hxx"
#include "svl/PasswordHelper.hxx"
+#include <comphelper/docpasswordhelper.hxx>
#include "document.hxx"
#define DEBUG_TAB_PROTECTION 0
@@ -75,40 +76,6 @@ ScPassHashProtectable::~ScPassHashProtectable()
// ============================================================================
-static sal_uInt16 lcl_getXLHashFromChar(const sal_Char* szPassword)
-{
- sal_uInt16 cchPassword = static_cast< sal_uInt16 >( strlen(szPassword) );
- sal_uInt16 wPasswordHash = 0;
- if (!cchPassword)
- return wPasswordHash;
-
- const char* pch = &szPassword[cchPassword];
- while (pch-- != szPassword)
- {
- wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
- ((wPasswordHash << 1) & 0x7fff);
- wPasswordHash ^= *pch;
- }
-
- wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
- ((wPasswordHash << 1) & 0x7fff);
-
- wPasswordHash ^= (0x8000 | ('N' << 8) | 'K');
- wPasswordHash ^= cchPassword;
-
- return wPasswordHash;
-}
-
-static Sequence<sal_Int8> lcl_getXLHash(const String& aPassText)
-{
- const sal_Char* szBuf = OUStringToOString(OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr();
- sal_uInt16 nHash = lcl_getXLHashFromChar(szBuf);
- Sequence<sal_Int8> aHash(2);
- aHash[0] = (nHash >> 8) & 0xFF;
- aHash[1] = nHash & 0xFF;
- return aHash;
-}
-
class ScTableProtectionImpl
{
public:
@@ -146,7 +113,7 @@ Sequence<sal_Int8> ScTableProtectionImpl::hashPassword(const String& aPassText,
switch (eHash)
{
case PASSHASH_XL:
- aHash = lcl_getXLHash(aPassText);
+ aHash = ::comphelper::DocPasswordHelper::GetXLHashAsSequence( aPassText, RTL_TEXTENCODING_UTF8 );
break;
case PASSHASH_OOO:
default:
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
index 1ecbefe4a9b1..13384b033628 100644
--- a/sc/source/core/inc/bcaslot.hxx
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -214,10 +214,6 @@ private:
+---+---+
*/
- /* TODO: When going for 1M rows this will definitely need some change, or
- * with lots of referred sheets even the reservation of NULL pointers would
- * be a memory hog. */
-
class TableSlots
{
public:
@@ -227,7 +223,8 @@ private:
/**
Obtain slot pointer, no check on validity! It is assumed that
- all calls are made with the result of ComputeSlotOfsset()
+ all calls are made with the results of ComputeSlotOffset(),
+ ComputeAreaPoints() and ComputeNextSlot()
*/
inline ScBroadcastAreaSlot* getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); }
diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx
index e7bd2dfa6ae1..10221d942c9c 100644
--- a/sc/source/core/inc/doubleref.hxx
+++ b/sc/source/core/inc/doubleref.hxx
@@ -47,11 +47,10 @@ struct ScQueryParamBase;
class ScDBRangeBase
{
public:
- enum RefType { INTERNAL, EXTERNAL };
+ enum RefType { INTERNAL, EXTERNAL }; // TODO: We may not need this after all... (kohei)
virtual ~ScDBRangeBase() = 0;
- RefType getType() const;
bool fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const;
virtual SCCOL getColSize() const = 0;
diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx
index c0ae60f13841..07b79c11b373 100644
--- a/sc/source/core/tool/addincol.cxx
+++ b/sc/source/core/tool/addincol.cxx
@@ -51,6 +51,7 @@
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/sheet/XCompatibilityNames.hpp>
+#include <com/sun/star/sheet/NoConvergenceException.hpp>
#include "addincol.hxx"
#include "addinhelpid.hxx"
@@ -1582,9 +1583,13 @@ void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs)
if ( rWrapped.TargetException.getValueType().equals(
getCppuType( (lang::IllegalArgumentException*)0 ) ) )
nErrCode = errIllegalArgument;
+ else if ( rWrapped.TargetException.getValueType().equals(
+ getCppuType( (sheet::NoConvergenceException*)0 ) ) )
+ nErrCode = errNoConvergence;
else
nErrCode = errNoValue;
}
+
catch(uno::Exception&)
{
nErrCode = errNoValue;
diff --git a/sc/source/core/tool/chartarr.cxx b/sc/source/core/tool/chartarr.cxx
index 9e4e77b7c1d4..573763141b18 100644
--- a/sc/source/core/tool/chartarr.cxx
+++ b/sc/source/core/tool/chartarr.cxx
@@ -44,6 +44,9 @@
#include "cell.hxx"
#include "docoptio.hxx"
+#include <vector>
+
+using ::std::vector;
// -----------------------------------------------------------------------
@@ -163,11 +166,17 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
SCCOL nStrCol = nCol1; // fuer Beschriftung merken
SCROW nStrRow = nRow1;
- // Beschriftungen auch nach HiddenCols finden
- while ( (pDocument->GetColFlags( nCol1, nTab1) & CR_HIDDEN) != 0 )
- nCol1++;
- nRow1 = pDocument->GetRowFlagsArray( nTab1).GetFirstForCondition( nRow1,
- nRow2, CR_HIDDEN, 0);
+ // Skip hidden columns.
+ // TODO: make use of last column value once implemented.
+ SCCOL nLastCol = -1;
+ while (pDocument->ColHidden(nCol1, nTab1, nLastCol))
+ ++nCol1;
+
+ // Skip hidden rows.
+ SCROW nLastRow = -1;
+ if (pDocument->RowHidden(nRow1, nTab1, nLastRow))
+ nRow1 = nLastRow + 1;
+
// falls alles hidden ist, bleibt die Beschriftung am Anfang
if ( nCol1 <= nCol2 )
{
@@ -181,17 +190,33 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
}
SCSIZE nTotalCols = ( nCol1 <= nCol2 ? nCol2 - nCol1 + 1 : 0 );
- SCCOL* pCols = new SCCOL[nTotalCols > 0 ? nTotalCols : 1];
- SCSIZE nColCount = 0;
+ vector<SCCOL> aCols;
+ aCols.reserve(nTotalCols);
for (SCSIZE i=0; i<nTotalCols; i++)
- if ((pDocument->GetColFlags(sal::static_int_cast<SCCOL>(nCol1+i),nTab1)&CR_HIDDEN)==0)
- pCols[nColCount++] = sal::static_int_cast<SCCOL>(nCol1+i);
+ {
+ SCCOL nThisCol = sal::static_int_cast<SCCOL>(nCol1+i);
+ if (!pDocument->ColHidden(nThisCol, nTab1, nLastCol))
+ aCols.push_back(nThisCol);
+ }
+ SCSIZE nColCount = aCols.size();
SCSIZE nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 );
- SCROW* pRows = new SCROW[nTotalRows > 0 ? nTotalRows : 1];
- SCSIZE nRowCount = (nTotalRows ?
- pDocument->GetRowFlagsArray( nTab1).FillArrayForCondition( nRow1,
- nRow2, CR_HIDDEN, 0, pRows, nTotalRows) : 0);
+ vector<SCROW> aRows;
+ aRows.reserve(nTotalRows);
+ if (nRow1 <= nRow2)
+ {
+ // Get all visible rows between nRow1 and nRow2.
+ SCROW nThisRow = nRow1;
+ while (nThisRow <= nRow2)
+ {
+ if (pDocument->RowHidden(nThisRow, nTab1, nLastRow))
+ nThisRow = nLastRow;
+ else
+ aRows.push_back(nThisRow);
+ ++nThisRow;
+ }
+ }
+ SCSIZE nRowCount = aRows.size();
// May happen at least with more than 32k rows.
if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX)
@@ -205,13 +230,13 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
{
bValidData = FALSE;
nColCount = 1;
- pCols[0] = nStrCol;
+ aCols.push_back(nStrCol);
}
if ( !nRowCount )
{
bValidData = FALSE;
nRowCount = 1;
- pRows[0] = nStrRow;
+ aRows.push_back(nStrRow);
}
//
@@ -234,7 +259,7 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
{
double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen
- pDocument->GetCell( pCols[nCol], pRows[nRow], nTab1, pCell );
+ pDocument->GetCell( aCols[nCol], aRows[nRow], nTab1, pCell );
if (pCell)
{
CellType eType = pCell->GetCellType();
@@ -244,8 +269,8 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
if ( bCalcAsShown && nVal != 0.0 )
{
sal_uInt32 nFormat;
- pDocument->GetNumberFormat( pCols[nCol],
- pRows[nRow], nTab1, nFormat );
+ pDocument->GetNumberFormat( aCols[nCol],
+ aRows[nRow], nTab1, nFormat );
nVal = pDocument->RoundValueAsShown( nVal, nFormat );
}
}
@@ -277,13 +302,13 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
{
String aString, aColStr;
if (HasColHeaders())
- pDocument->GetString( pCols[nCol], nStrRow, nTab1, aString );
+ pDocument->GetString( aCols[nCol], nStrRow, nTab1, aString );
if ( !aString.Len() )
{
aString = ScGlobal::GetRscString(STR_COLUMN);
aString += ' ';
// aString += String::CreateFromInt32( pCols[nCol]+1 );
- ScAddress aPos( pCols[ nCol ], 0, 0 );
+ ScAddress aPos( aCols[ nCol ], 0, 0 );
aPos.Format( aColStr, SCA_VALID_COL, NULL );
aString += aColStr;
}
@@ -303,14 +328,14 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
String aString;
if (HasRowHeaders())
{
- ScAddress aAddr( nStrCol, pRows[nRow], nTab1 );
- pDocument->GetString( nStrCol, pRows[nRow], nTab1, aString );
+ ScAddress aAddr( nStrCol, aRows[nRow], nTab1 );
+ pDocument->GetString( nStrCol, aRows[nRow], nTab1, aString );
}
if ( !aString.Len() )
{
aString = ScGlobal::GetRscString(STR_ROW);
aString += ' ';
- aString += String::CreateFromInt32( pRows[nRow]+1 );
+ aString += String::CreateFromInt32( aRows[nRow]+1 );
}
pMemChart->SetRowText( static_cast<short>(nRow), aString);
@@ -346,11 +371,6 @@ ScMemChart* ScChartArray::CreateMemChartSingle()
// SetExtraStrings( *pMemChart );
}
- // Aufraeumen
-
- delete[] pRows;
- delete[] pCols;
-
return pMemChart;
}
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 5f4b86b7cd18..c28d295275ae 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -121,6 +121,24 @@ enum ScanState
ssStop
};
+// ODFF names that are not written in the current mapping but to be recognized.
+// New names will be written in a future relase, then exchange (!) with the
+// names in formula/source/core/resource/core_resource.src to be able to still
+// read the old names as well.
+struct FunctionName
+{
+ const sal_Char* pName;
+ OpCode eOp;
+};
+static const FunctionName aOdffAliases[] = {
+ // Renamed old names:
+ // XXX none yet.
+ // Renamed new names:
+ { "BINOM.DIST.RANGE", ocB }, // B -> BINOM.DIST.RANGE
+ { "LEGACY.TDIST", ocTDist } // TDIST -> LEGACY.TDIST
+};
+static const size_t nOdffAliases = sizeof(aOdffAliases) / sizeof(aOdffAliases[0]);
+
static const sal_Char* pInternal[ 1 ] = { "TTT" };
using namespace ::com::sun::star::i18n;
@@ -2504,7 +2522,21 @@ BOOL ScCompiler::IsOpCode( const String& rName, bool bInArray )
aToken.SetOpCode(eOp);
pRawToken = aToken.Clone();
}
- else
+ else if (mxSymbols->isODFF())
+ {
+ for (size_t i=0; i<nOdffAliases; ++i)
+ {
+ if (rName.EqualsIgnoreCaseAscii( aOdffAliases[i].pName))
+ {
+ ScRawToken aToken;
+ aToken.SetOpCode( aOdffAliases[i].eOp);
+ pRawToken = aToken.Clone();
+ bFound = TRUE;
+ break; // for
+ }
+ }
+ }
+ if (!bFound)
{
String aIntName;
if (mxSymbols->hasExternals())
@@ -2887,6 +2919,7 @@ BOOL ScCompiler::IsReference( const String& rName )
BOOL ScCompiler::IsMacro( const String& rName )
{
+ String aName( rName);
StarBASIC* pObj = 0;
SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
@@ -2898,7 +2931,14 @@ BOOL ScCompiler::IsMacro( const String& rName )
else
pObj = pSfxApp->GetBasic();
- SbxMethod* pMeth = (SbxMethod*) pObj->Find( rName, SbxCLASS_METHOD );
+ // ODFF recommends to store user-defined functions prefixed with "USER.",
+ // use only unprefixed name if encountered. BASIC doesn't allow '.' in a
+ // function name so a function "USER.FOO" could not exist, and macro check
+ // is assigned the lowest priority in function name check.
+ if (FormulaGrammar::isODFF( GetGrammar()) && aName.EqualsIgnoreCaseAscii( "USER.", 0, 5))
+ aName.Erase( 0, 5);
+
+ SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD );
if( !pMeth )
{
pSfxApp->LeaveBasicCall();
@@ -2913,7 +2953,7 @@ BOOL ScCompiler::IsMacro( const String& rName )
return FALSE;
}
ScRawToken aToken;
- aToken.SetExternal( rName.GetBuffer() );
+ aToken.SetExternal( aName.GetBuffer() );
aToken.eOp = ocMacro;
pRawToken = aToken.Clone();
pSfxApp->LeaveBasicCall();
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 1f257512ae50..e86bb22646c8 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -359,7 +359,7 @@ Point ScDetectiveFunc::GetDrawPos( SCCOL nCol, SCROW nRow, DrawPosMode eMode ) c
for ( SCCOL i = 0; i < nCol; ++i )
aPos.X() += pDoc->GetColWidth( i, nTab );
- aPos.Y() += pDoc->FastGetRowHeight( 0, nRow - 1, nTab );
+ aPos.Y() += pDoc->GetRowHeight( 0, nRow - 1, nTab );
aPos.X() = static_cast< long >( aPos.X() * HMM_PER_TWIPS );
aPos.Y() = static_cast< long >( aPos.Y() * HMM_PER_TWIPS );
diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx
index 5c2d3f575654..740413ea8533 100644
--- a/sc/source/core/tool/doubleref.cxx
+++ b/sc/source/core/tool/doubleref.cxx
@@ -268,11 +268,6 @@ ScDBRangeBase::~ScDBRangeBase()
{
}
-ScDBRangeBase::RefType ScDBRangeBase::getType() const
-{
- return meType;
-}
-
bool ScDBRangeBase::fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const
{
if (!pDBRef)
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 2bf6a5680613..5c326001ff02 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -537,9 +537,14 @@ BOOL ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateDoubleArr" );
-#if SC_ROWLIMIT_MORE_THAN_64K
-#error row limit 64k
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
USHORT nCount = 0;
USHORT* p = (USHORT*) pCellArr;
*p++ = static_cast<USHORT>(nCol1);
@@ -618,9 +623,14 @@ BOOL ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
BYTE* pCellArr)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateStringArr" );
-#if SC_ROWLIMIT_MORE_THAN_64K
-#error row limit 64k
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
USHORT nCount = 0;
USHORT* p = (USHORT*) pCellArr;
*p++ = static_cast<USHORT>(nCol1);
@@ -713,9 +723,14 @@ BOOL ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
BYTE* pCellArr)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateCellArr" );
-#if SC_ROWLIMIT_MORE_THAN_64K
-#error row limit 64k
+
+ // Old Add-Ins are hard limited to USHORT values.
+#if MAXCOLCOUNT_DEFINE > USHRT_MAX
+#error Add check for columns > USHRT_MAX!
#endif
+ if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ return FALSE;
+
USHORT nCount = 0;
USHORT* p = (USHORT*) pCellArr;
*p++ = static_cast<USHORT>(nCol1);
@@ -2125,7 +2140,7 @@ void ScInterpreter::ScExternal()
if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName, nIndex))
{
FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex);
- if (nParamCount == pFuncData->GetParamCount() - 1)
+ if (nParamCount <= MAXFUNCPARAM && nParamCount == pFuncData->GetParamCount() - 1)
{
ParamType eParamType[MAXFUNCPARAM];
void* ppParam[MAXFUNCPARAM];