sc/inc/columnspanset.hxx | 8 +++ sc/inc/fstalgorithm.hxx | 52 ++++++++++++++++++++++++ sc/inc/markdata.hxx | 4 + sc/qa/unit/ucalc.cxx | 50 +++++++++++++++++++++++ sc/qa/unit/ucalc.hxx | 2 sc/source/core/data/columnspanset.cxx | 20 +-------- sc/source/core/data/markdata.cxx | 39 +++++++++++++----- sc/source/ui/inc/undoblk.hxx | 18 ++++---- sc/source/ui/undo/undoblk.cxx | 72 ++++++++++++++++------------------ sc/source/ui/view/viewfun2.cxx | 12 ++--- sc/source/ui/view/viewfunc.cxx | 69 +++++++++++++++++--------------- 11 files changed, 234 insertions(+), 112 deletions(-)
New commits: commit bd9db38e4525474e6a35a91748a34ce473807075 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Wed Feb 5 00:07:21 2014 -0500 Remove use of GetMark*Ranges() from DeleteMulti(). Change-Id: I4a17e5f0f1c81c968c821467f326a1c9b06a85a9 diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx index 1b10216..6dabb13 100644 --- a/sc/source/ui/inc/undoblk.hxx +++ b/sc/source/ui/inc/undoblk.hxx @@ -25,6 +25,7 @@ #include "spellparam.hxx" #include "cellmergeoption.hxx" #include "paramisc.hxx" +#include <columnspanset.hxx> #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> @@ -110,10 +111,12 @@ class ScUndoDeleteMulti: public ScMoveUndo { public: TYPEINFO(); - ScUndoDeleteMulti( ScDocShell* pNewDocShell, - sal_Bool bNewRows, sal_Bool bNeedsRefresh, SCTAB nNewTab, - const SCCOLROW* pRng, SCCOLROW nRngCnt, - ScDocument* pUndoDocument, ScRefUndoData* pRefData ); + + ScUndoDeleteMulti( ScDocShell* pNewDocShell, + bool bNewRows, bool bNeedsRefresh, SCTAB nNewTab, + const std::vector<sc::ColRowSpan>& rSpans, + ScDocument* pUndoDocument, ScRefUndoData* pRefData ); + virtual ~ScUndoDeleteMulti(); virtual void Undo(); @@ -124,11 +127,10 @@ public: virtual OUString GetComment() const; private: - sal_Bool bRows; - sal_Bool bRefresh; + bool mbRows:1; + bool mbRefresh:1; SCTAB nTab; - SCCOLROW* pRanges; - SCCOLROW nRangeCnt; + std::vector<sc::ColRowSpan> maSpans; sal_uLong nStartChangeAction; sal_uLong nEndChangeAction; diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index 5b8643c..a622258 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -554,24 +554,22 @@ bool ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const } // delete cells in multiselection -ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell, - sal_Bool bNewRows, sal_Bool bNeedsRefresh, SCTAB nNewTab, - const SCCOLROW* pRng, SCCOLROW nRngCnt, - ScDocument* pUndoDocument, ScRefUndoData* pRefData ) : +ScUndoDeleteMulti::ScUndoDeleteMulti( + ScDocShell* pNewDocShell, + bool bNewRows, bool bNeedsRefresh, SCTAB nNewTab, + const std::vector<sc::ColRowSpan>& rSpans, + ScDocument* pUndoDocument, ScRefUndoData* pRefData ) : ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ), - bRows( bNewRows ), - bRefresh( bNeedsRefresh ), + mbRows(bNewRows), + mbRefresh(bNeedsRefresh), nTab( nNewTab ), - nRangeCnt( nRngCnt ) + maSpans(rSpans) { - pRanges = new SCCOLROW[ 2 * nRangeCnt ]; - memcpy(pRanges,pRng,nRangeCnt*2*sizeof(SCCOLROW)); SetChangeTrack(); } ScUndoDeleteMulti::~ScUndoDeleteMulti() { - delete [] pRanges; } OUString ScUndoDeleteMulti::GetComment() const @@ -584,20 +582,20 @@ void ScUndoDeleteMulti::DoChange() const SCCOL nStartCol; SCROW nStartRow; sal_uInt16 nPaint; - if (bRows) + if (mbRows) { nStartCol = 0; - nStartRow = static_cast<SCROW>(pRanges[0]); + nStartRow = static_cast<SCROW>(maSpans[0].mnStart); nPaint = PAINT_GRID | PAINT_LEFT; } else { - nStartCol = static_cast<SCCOL>(pRanges[0]); + nStartCol = static_cast<SCCOL>(maSpans[0].mnStart); nStartRow = 0; nPaint = PAINT_GRID | PAINT_TOP; } - if ( bRefresh ) + if (mbRefresh) { ScDocument* pDoc = pDocShell->GetDocument(); SCCOL nEndCol = MAXCOL; @@ -622,17 +620,17 @@ void ScUndoDeleteMulti::SetChangeTrack() { nStartChangeAction = pChangeTrack->GetActionMax() + 1; ScRange aRange( 0, 0, nTab, 0, 0, nTab ); - if ( bRows ) + if (mbRows) aRange.aEnd.SetCol( MAXCOL ); else aRange.aEnd.SetRow( MAXROW ); // delete in reverse - SCCOLROW* pOneRange = &pRanges[2*nRangeCnt]; - for ( SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++ ) + std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend(); + for (; ri != riEnd; ++ri) { - SCCOLROW nEnd = *(--pOneRange); - SCCOLROW nStart = *(--pOneRange); - if ( bRows ) + SCCOLROW nEnd = ri->mnEnd; + SCCOLROW nStart = ri->mnStart; + if (mbRows) { aRange.aStart.SetRow( nStart ); aRange.aEnd.SetRow( nEnd ); @@ -657,27 +655,25 @@ void ScUndoDeleteMulti::Undo() BeginUndo(); ScDocument* pDoc = pDocShell->GetDocument(); - SCCOLROW* pOneRange; - SCCOLROW nRangeNo; // reverse delete -> forward insert - pOneRange = pRanges; - for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + std::vector<sc::ColRowSpan>::const_iterator it = maSpans.begin(), itEnd = maSpans.end(); + for (; it != itEnd; ++it) { - SCCOLROW nStart = *(pOneRange++); - SCCOLROW nEnd = *(pOneRange++); - if (bRows) + SCCOLROW nStart = it->mnStart; + SCCOLROW nEnd = it->mnEnd; + if (mbRows) pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) ); else pDoc->InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) ); } - pOneRange = pRanges; - for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + it = maSpans.begin(); + for (; it != itEnd; ++it) { - SCCOLROW nStart = *(pOneRange++); - SCCOLROW nEnd = *(pOneRange++); - if (bRows) + SCCOLROW nStart = it->mnStart; + SCCOLROW nEnd = it->mnEnd; + if (mbRows) pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false,pDoc ); else pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab, @@ -704,13 +700,13 @@ void ScUndoDeleteMulti::Redo() ScDocument* pDoc = pDocShell->GetDocument(); - // reverese delet - SCCOLROW* pOneRange = &pRanges[2*nRangeCnt]; - for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + // reverese delete + std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend(); + for (; ri != riEnd; ++ri) { - SCCOLROW nEnd = *(--pOneRange); - SCCOLROW nStart = *(--pOneRange); - if (bRows) + SCCOLROW nEnd = ri->mnEnd; + SCCOLROW nStart = ri->mnStart; + if (mbRows) pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) ); else pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) ); diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 982a17c..1404d5b 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1580,27 +1580,29 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered ScViewUtil::UnmarkFiltered( aFuncMark, pDoc ); - if (bRecord && !pDoc->IsUndoEnabled()) + if (!pDoc->IsUndoEnabled()) bRecord = false; - SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT]; - SCCOLROW nRangeCnt = bRows ? aFuncMark.GetMarkRowRanges( pRanges ) : - aFuncMark.GetMarkColumnRanges( pRanges ); - if (nRangeCnt == 0) + + std::vector<sc::ColRowSpan> aSpans; + if (bRows) + aSpans = aFuncMark.GetMarkedRowSpans(); + else + aSpans = aFuncMark.GetMarkedColSpans(); + + if (aSpans.empty()) { - pRanges[0] = pRanges[1] = bRows ? static_cast<SCCOLROW>(GetViewData()->GetCurY()) : static_cast<SCCOLROW>(GetViewData()->GetCurX()); - nRangeCnt = 1; + SCCOLROW nCurPos = bRows ? GetViewData()->GetCurY() : GetViewData()->GetCurX(); + aSpans.push_back(sc::ColRowSpan(nCurPos, nCurPos)); } // test if allowed - SCCOLROW* pOneRange = pRanges; sal_uInt16 nErrorId = 0; bool bNeedRefresh = false; - SCCOLROW nRangeNo; - for (nRangeNo=0; nRangeNo<nRangeCnt && !nErrorId; nRangeNo++) + for (size_t i = 0, n = aSpans.size(); i < n && !nErrorId; ++i) { - SCCOLROW nStart = *(pOneRange++); - SCCOLROW nEnd = *(pOneRange++); + SCCOLROW nStart = aSpans[i].mnStart; + SCCOLROW nEnd = aSpans[i].mnEnd; SCCOL nStartCol, nEndCol; SCROW nStartRow, nEndRow; @@ -1620,7 +1622,7 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) } // cell protection (only needed for first range, as all following cells are moved) - if ( nRangeNo == 0 ) + if (i == 0) { // test to the end of the sheet ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, MAXCOL, MAXROW ); @@ -1654,7 +1656,6 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) if ( nErrorId ) { ErrorMessage( nErrorId ); - delete[] pRanges; return; } @@ -1669,11 +1670,10 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); pUndoDoc->InitUndo( pDoc, nTab, nTab, !bRows, bRows ); // row height - pOneRange = pRanges; - for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + for (size_t i = 0, n = aSpans.size(); i < n; ++i) { - SCCOLROW nStart = *(pOneRange++); - SCCOLROW nEnd = *(pOneRange++); + SCCOLROW nStart = aSpans[i].mnStart; + SCCOLROW nEnd = aSpans[i].mnEnd; if (bRows) pDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false,pUndoDoc ); else @@ -1692,11 +1692,11 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) pDoc->BeginDrawUndo(); } - pOneRange = &pRanges[2*nRangeCnt]; // backwards - for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + std::vector<sc::ColRowSpan>::const_reverse_iterator ri = aSpans.rbegin(), riEnd = aSpans.rend(); + for (; ri != riEnd; ++ri) { - SCCOLROW nEnd = *(--pOneRange); - SCCOLROW nStart = *(--pOneRange); + SCCOLROW nEnd = ri->mnEnd; + SCCOLROW nStart = ri->mnStart; if (bRows) pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart, static_cast<SCSIZE>(nEnd-nStart+1) ); @@ -1706,7 +1706,7 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) if (bNeedRefresh) { - SCCOLROW nFirstStart = pRanges[0]; + SCCOLROW nFirstStart = aSpans[0].mnStart; SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart); SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0; SCCOL nEndCol = MAXCOL; @@ -1719,17 +1719,24 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) if (bRecord) { pDocSh->GetUndoManager()->AddUndoAction( - new ScUndoDeleteMulti( pDocSh, bRows, bNeedRefresh, nTab, pRanges, nRangeCnt, - pUndoDoc, pUndoData ) ); + new ScUndoDeleteMulti( + pDocSh, bRows, bNeedRefresh, nTab, aSpans, pUndoDoc, pUndoData)); } if (!AdjustRowHeight(0, MAXROW)) { if (bRows) - pDocSh->PostPaint( 0,pRanges[0],nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT ); + { + pDocSh->PostPaint( + 0, aSpans[0].mnStart, nTab, + MAXCOL, MAXROW, nTab, (PAINT_GRID | PAINT_LEFT)); + } else - pDocSh->PostPaint( static_cast<SCCOL>(pRanges[0]),0,nTab, - MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_TOP ); + { + pDocSh->PostPaint( + static_cast<SCCOL>(aSpans[0].mnStart), 0, nTab, + MAXCOL, MAXROW, nTab, (PAINT_GRID | PAINT_TOP)); + } } ResetAutoSpell(); @@ -1741,13 +1748,11 @@ void ScViewFunc::DeleteMulti( bool bRows, bool bRecord ) SCCOL nCurX = GetViewData()->GetCurX(); SCROW nCurY = GetViewData()->GetCurY(); if ( bRows ) - nCurY = pRanges[0]; + nCurY = aSpans[0].mnStart; else - nCurX = static_cast<SCCOL>(pRanges[0]); + nCurX = static_cast<SCCOL>(aSpans[0].mnStart); SetCursor( nCurX, nCurY ); - delete[] pRanges; - SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); } commit 21ab2ba866c8bea31cf2832d1c53227963a6010a Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Feb 4 22:37:41 2014 -0500 Actually these methods shouldn't be taking a sheet index. Marked ranges consist of 2-dimensional ranges plus selected sheets. So the selected ranges themselves don't care about sheets. Change-Id: I1c2dfab182282e6b32342b97227b3a7abfaf5179 diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx index 4002e1f..c792b31 100644 --- a/sc/inc/markdata.hxx +++ b/sc/inc/markdata.hxx @@ -110,8 +110,8 @@ public: SCCOLROW GetMarkColumnRanges( SCCOLROW* pRanges ); SCCOLROW GetMarkRowRanges( SCCOLROW* pRanges ); - std::vector<sc::ColRowSpan> GetMarkedRowSpans( SCTAB nTab ) const; - std::vector<sc::ColRowSpan> GetMarkedColSpans( SCTAB nTab ) const; + std::vector<sc::ColRowSpan> GetMarkedRowSpans() const; + std::vector<sc::ColRowSpan> GetMarkedColSpans() const; bool IsColumnMarked( SCCOL nCol ) const; bool IsRowMarked( SCROW nRow ) const; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 33d13f5..a8a349f 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -614,45 +614,45 @@ void Test::testMarkData() ScMarkData aMarkData; // Empty mark. Nothing is selected. - std::vector<sc::ColRowSpan> aSpans = aMarkData.GetMarkedRowSpans(0); + std::vector<sc::ColRowSpan> aSpans = aMarkData.GetMarkedRowSpans(); CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty()); - aSpans = aMarkData.GetMarkedColSpans(0); + aSpans = aMarkData.GetMarkedColSpans(); CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty()); // Select B3:F7. aMarkData.SetMarkArea(ScRange(1,2,0,5,6,0)); - aSpans = aMarkData.GetMarkedRowSpans(0); + aSpans = aMarkData.GetMarkedRowSpans(); CPPUNIT_ASSERT_MESSAGE("There should be one selected row span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd); - aSpans = aMarkData.GetMarkedColSpans(0); + aSpans = aMarkData.GetMarkedColSpans(); CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(1), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); // Select A11:B13. aMarkData.SetMultiMarkArea(ScRange(0,10,0,1,12,0)); - aSpans = aMarkData.GetMarkedRowSpans(0); + aSpans = aMarkData.GetMarkedRowSpans(); CPPUNIT_ASSERT_MESSAGE("There should be 2 selected row spans.", aSpans.size() == 2); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(10), aSpans[1].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[1].mnEnd); - aSpans = aMarkData.GetMarkedColSpans(0); + aSpans = aMarkData.GetMarkedColSpans(); CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); // Select C8:C10. aMarkData.SetMultiMarkArea(ScRange(2,7,0,2,9,0)); - aSpans = aMarkData.GetMarkedRowSpans(0); + aSpans = aMarkData.GetMarkedRowSpans(); CPPUNIT_ASSERT_MESSAGE("There should be one selected row span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[0].mnEnd); - aSpans = aMarkData.GetMarkedColSpans(0); + aSpans = aMarkData.GetMarkedColSpans(); CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index 7f58b68..39ef792 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -551,7 +551,7 @@ SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges ) return nRangeCnt; } -std::vector<sc::ColRowSpan> ScMarkData::GetMarkedRowSpans( SCTAB nTab ) const +std::vector<sc::ColRowSpan> ScMarkData::GetMarkedRowSpans() const { typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType; @@ -562,16 +562,13 @@ std::vector<sc::ColRowSpan> ScMarkData::GetMarkedRowSpans( SCTAB nTab ) const for (size_t i = 0, n = aRanges.size(); i < n; ++i) { const ScRange& r = *aRanges[i]; - if (r.aStart.Tab() != nTab) - continue; - itPos = aSpans.insert(itPos, r.aStart.Row(), r.aEnd.Row()+1, true).first; } return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans); } -std::vector<sc::ColRowSpan> ScMarkData::GetMarkedColSpans( SCTAB nTab ) const +std::vector<sc::ColRowSpan> ScMarkData::GetMarkedColSpans() const { typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType; @@ -582,9 +579,6 @@ std::vector<sc::ColRowSpan> ScMarkData::GetMarkedColSpans( SCTAB nTab ) const for (size_t i = 0, n = aRanges.size(); i < n; ++i) { const ScRange& r = *aRanges[i]; - if (r.aStart.Tab() != nTab) - continue; - itPos = aSpans.insert(itPos, r.aStart.Col(), r.aEnd.Col()+1, true).first; } diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 00e0462..76afd32 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -109,8 +109,7 @@ sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) pMarkData = &GetViewData()->GetMarkData(); ScDocument* pDoc = pDocSh->GetDocument(); - std::vector<sc::ColRowSpan> aMarkedRows = - pMarkData->GetMarkedRowSpans(GetViewData()->GetTabNo()); + std::vector<sc::ColRowSpan> aMarkedRows = pMarkData->GetMarkedRowSpans(); if (aMarkedRows.empty()) { commit b55bd1f51c54f560da3956d54e4dd30ad1422252 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Feb 4 22:14:00 2014 -0500 Implement GetMarkedColSpans() counterpart. Change-Id: Ia2f4828a91ad3c89f7867e0f2e0248f885d3fff7 diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx index 0a5b19f..4002e1f 100644 --- a/sc/inc/markdata.hxx +++ b/sc/inc/markdata.hxx @@ -111,6 +111,7 @@ public: SCCOLROW GetMarkRowRanges( SCCOLROW* pRanges ); std::vector<sc::ColRowSpan> GetMarkedRowSpans( SCTAB nTab ) const; + std::vector<sc::ColRowSpan> GetMarkedColSpans( SCTAB nTab ) const; bool IsColumnMarked( SCCOL nCol ) const; bool IsRowMarked( SCROW nRow ) const; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 8341ef9..33d13f5 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -616,6 +616,8 @@ void Test::testMarkData() // Empty mark. Nothing is selected. std::vector<sc::ColRowSpan> aSpans = aMarkData.GetMarkedRowSpans(0); CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty()); + aSpans = aMarkData.GetMarkedColSpans(0); + CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty()); // Select B3:F7. aMarkData.SetMarkArea(ScRange(1,2,0,5,6,0)); @@ -624,6 +626,11 @@ void Test::testMarkData() CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd); + aSpans = aMarkData.GetMarkedColSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(1), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); + // Select A11:B13. aMarkData.SetMultiMarkArea(ScRange(0,10,0,1,12,0)); aSpans = aMarkData.GetMarkedRowSpans(0); @@ -633,12 +640,22 @@ void Test::testMarkData() CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(10), aSpans[1].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[1].mnEnd); + aSpans = aMarkData.GetMarkedColSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); + // Select C8:C10. aMarkData.SetMultiMarkArea(ScRange(2,7,0,2,9,0)); aSpans = aMarkData.GetMarkedRowSpans(0); CPPUNIT_ASSERT_MESSAGE("There should be one selected row span.", aSpans.size() == 1); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[0].mnEnd); + + aSpans = aMarkData.GetMarkedColSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be one selected column span.", aSpans.size() == 1); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd); } void Test::testInput() diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index 3769377..7f58b68 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -571,6 +571,26 @@ std::vector<sc::ColRowSpan> ScMarkData::GetMarkedRowSpans( SCTAB nTab ) const return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans); } +std::vector<sc::ColRowSpan> ScMarkData::GetMarkedColSpans( SCTAB nTab ) const +{ + typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType; + + ScRangeList aRanges = GetMarkedRanges(); + SpansType aSpans(0, MAXCOL+1, false); + SpansType::const_iterator itPos = aSpans.begin(); + + for (size_t i = 0, n = aRanges.size(); i < n; ++i) + { + const ScRange& r = *aRanges[i]; + if (r.aStart.Tab() != nTab) + continue; + + itPos = aSpans.insert(itPos, r.aStart.Col(), r.aEnd.Col()+1, true).first; + } + + return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans); +} + bool ScMarkData::IsAllMarked( const ScRange& rRange ) const { if ( !bMultiMarked ) commit fc16069d1a8db45b7ecaa01c3ee1af0e904062c2 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Feb 4 21:51:57 2014 -0500 Reimplement ScMarkData::GetMarkedRowSpans() to use flat_segment_tree directly. Change-Id: I90a1d4b3ae2e6aff9a7926b5842bc85ac172683d diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx index 62e96a8..7da9896 100644 --- a/sc/inc/columnspanset.hxx +++ b/sc/inc/columnspanset.hxx @@ -33,6 +33,14 @@ struct RowSpan RowSpan(SCROW nRow1, SCROW nRow2); }; +struct ColRowSpan +{ + SCCOLROW mnStart; + SCCOLROW mnEnd; + + ColRowSpan(SCCOLROW nStart, SCCOLROW nEnd); +}; + /** * Structure that stores segments of boolean flags per column, and perform * custom action on those segments. diff --git a/sc/inc/fstalgorithm.hxx b/sc/inc/fstalgorithm.hxx new file mode 100644 index 0000000..6b3385c --- /dev/null +++ b/sc/inc/fstalgorithm.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef SC_FSTALGORITHM_HXX +#define SC_FSTALGORITHM_HXX + +#include <mdds/flat_segment_tree.hpp> +#include <vector> + +namespace sc { + +/** + * Convert a flat_segment_tree structure whose value type is boolean, into + * an array of ranges that corresponds with the segments that have a 'true' + * value. + */ +template<typename _Key, typename _Span> +std::vector<_Span> toSpanArray( const mdds::flat_segment_tree<_Key,bool>& rTree ) +{ + typedef mdds::flat_segment_tree<_Key,bool> FstType; + + std::vector<_Span> aSpans; + + typename FstType::const_iterator it = rTree.begin(), itEnd = rTree.end(); + _Key nLastPos = it->first; + bool bLastVal = it->second; + for (++it; it != itEnd; ++it) + { + _Key nThisPos = it->first; + bool bThisVal = it->second; + + if (bLastVal) + aSpans.push_back(_Span(nLastPos, nThisPos-1)); + + nLastPos = nThisPos; + bLastVal = bThisVal; + } + + return aSpans; +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx index 943419d..0a5b19f 100644 --- a/sc/inc/markdata.hxx +++ b/sc/inc/markdata.hxx @@ -29,6 +29,7 @@ namespace sc { struct RowSpan; +struct ColRowSpan; } @@ -109,7 +110,7 @@ public: SCCOLROW GetMarkColumnRanges( SCCOLROW* pRanges ); SCCOLROW GetMarkRowRanges( SCCOLROW* pRanges ); - void GetMarkedRowSpans( SCTAB nTab, std::vector<sc::RowSpan>& rSpans ); + std::vector<sc::ColRowSpan> GetMarkedRowSpans( SCTAB nTab ) const; bool IsColumnMarked( SCCOL nCol ) const; bool IsRowMarked( SCROW nRow ) const; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 5811dc0..8341ef9 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -55,6 +55,7 @@ #include "editutil.hxx" #include <asciiopt.hxx> #include <impex.hxx> +#include <columnspanset.hxx> #include "formula/IFunctionDescription.hxx" @@ -608,6 +609,38 @@ void Test::testRangeList() m_pDoc->DeleteTab(0); } +void Test::testMarkData() +{ + ScMarkData aMarkData; + + // Empty mark. Nothing is selected. + std::vector<sc::ColRowSpan> aSpans = aMarkData.GetMarkedRowSpans(0); + CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty()); + + // Select B3:F7. + aMarkData.SetMarkArea(ScRange(1,2,0,5,6,0)); + aSpans = aMarkData.GetMarkedRowSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be one selected row span.", aSpans.size() == 1); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd); + + // Select A11:B13. + aMarkData.SetMultiMarkArea(ScRange(0,10,0,1,12,0)); + aSpans = aMarkData.GetMarkedRowSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be 2 selected row spans.", aSpans.size() == 2); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(10), aSpans[1].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[1].mnEnd); + + // Select C8:C10. + aMarkData.SetMultiMarkArea(ScRange(2,7,0,2,9,0)); + aSpans = aMarkData.GetMarkedRowSpans(0); + CPPUNIT_ASSERT_MESSAGE("There should be one selected row span.", aSpans.size() == 1); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart); + CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[0].mnEnd); +} + void Test::testInput() { OUString aTabName("foo"); diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 48234e5..6bbaad0 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -82,6 +82,7 @@ public: void testCollator(); void testSharedStringPool(); void testRangeList(); + void testMarkData(); void testInput(); void testDocStatistics(); @@ -320,6 +321,7 @@ public: CPPUNIT_TEST(testCollator); CPPUNIT_TEST(testSharedStringPool); CPPUNIT_TEST(testRangeList); + CPPUNIT_TEST(testMarkData); CPPUNIT_TEST(testInput); CPPUNIT_TEST(testDocStatistics); CPPUNIT_TEST(testDataEntries); diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx index efa51b5..1aa57ba 100644 --- a/sc/source/core/data/columnspanset.cxx +++ b/sc/source/core/data/columnspanset.cxx @@ -15,6 +15,7 @@ #include "mtvfunctions.hxx" #include "markdata.hxx" #include "rangelst.hxx" +#include <fstalgorithm.hxx> #include <algorithm> @@ -22,6 +23,8 @@ namespace sc { RowSpan::RowSpan(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {} +ColRowSpan::ColRowSpan(SCCOLROW nStart, SCCOLROW nEnd) : mnStart(nStart), mnEnd(nEnd) {} + ColumnSpanSet::ColumnType::ColumnType(SCROW nStart, SCROW nEnd, bool bInit) : maSpans(nStart, nEnd+1, bInit), miPos(maSpans.begin()) {} @@ -262,22 +265,7 @@ void SingleColumnSpanSet::getRows(std::vector<SCROW> &rRows) const void SingleColumnSpanSet::getSpans(SpansType& rSpans) const { - SpansType aSpans; - ColumnSpansType::const_iterator it = maSpans.begin(), itEnd = maSpans.end(); - SCROW nLastRow = it->first; - bool bLastVal = it->second; - for (++it; it != itEnd; ++it) - { - SCROW nThisRow = it->first; - bool bThisVal = it->second; - - if (bLastVal) - aSpans.push_back(RowSpan(nLastRow, nThisRow-1)); - - nLastRow = nThisRow; - bLastVal = bThisVal; - } - + SpansType aSpans = toSpanArray<SCROW,RowSpan>(maSpans); rSpans.swap(aSpans); } diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index 556df50..3769377 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -21,6 +21,9 @@ #include "markarr.hxx" #include "rangelst.hxx" #include <columnspanset.hxx> +#include <fstalgorithm.hxx> + +#include <mdds/flat_segment_tree.hpp> // STATIC DATA ----------------------------------------------------------- @@ -548,24 +551,24 @@ SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges ) return nRangeCnt; } -void ScMarkData::GetMarkedRowSpans( SCTAB nTab, std::vector<sc::RowSpan>& rSpans ) +std::vector<sc::ColRowSpan> ScMarkData::GetMarkedRowSpans( SCTAB nTab ) const { - std::vector<sc::RowSpan> aSpans; + typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType; - if (bMarked) - MarkToMulti(); + ScRangeList aRanges = GetMarkedRanges(); + SpansType aSpans(0, MAXROW+1, false); + SpansType::const_iterator itPos = aSpans.begin(); - if (!bMultiMarked) + for (size_t i = 0, n = aRanges.size(); i < n; ++i) { - rSpans.swap(aSpans); - return; - } + const ScRange& r = *aRanges[i]; + if (r.aStart.Tab() != nTab) + continue; - sc::SingleColumnSpanSet aMarkedRows; - for (SCCOL nCol = aMultiRange.aStart.Col(); nCol <= aMultiRange.aEnd.Col(); ++nCol) - aMarkedRows.scan(*this, nTab, nCol); + itPos = aSpans.insert(itPos, r.aStart.Row(), r.aEnd.Row()+1, true).first; + } - aMarkedRows.getSpans(rSpans); + return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans); } bool ScMarkData::IsAllMarked( const ScRange& rRange ) const diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 2a0b118..00e0462 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -109,12 +109,13 @@ sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) pMarkData = &GetViewData()->GetMarkData(); ScDocument* pDoc = pDocSh->GetDocument(); - std::vector<sc::RowSpan> aMarkedRows; - pMarkData->GetMarkedRowSpans(GetViewData()->GetTabNo(), aMarkedRows); + std::vector<sc::ColRowSpan> aMarkedRows = + pMarkData->GetMarkedRowSpans(GetViewData()->GetTabNo()); + if (aMarkedRows.empty()) { SCROW nCurRow = GetViewData()->GetCurY(); - aMarkedRows.push_back(sc::RowSpan(nCurRow, nCurRow)); + aMarkedRows.push_back(sc::ColRowSpan(nCurRow, nCurRow)); } double nPPTX = GetViewData()->GetPPTX(); @@ -138,11 +139,11 @@ sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) SCTAB nTab = *itr; bool bChanged = false; SCROW nPaintY = 0; - std::vector<sc::RowSpan>::const_iterator itRows = aMarkedRows.begin(), itRowsEnd = aMarkedRows.end(); + std::vector<sc::ColRowSpan>::const_iterator itRows = aMarkedRows.begin(), itRowsEnd = aMarkedRows.end(); for (; itRows != itRowsEnd; ++itRows) { - SCROW nStartNo = itRows->mnRow1; - SCROW nEndNo = itRows->mnRow2; + SCROW nStartNo = itRows->mnStart; + SCROW nEndNo = itRows->mnEnd; if (pDoc->SetOptimalHeight(aCxt, nStartNo, nEndNo, nTab)) { if (!bChanged) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits