27 #include <document.hxx>
30 #include <unordered_map>
32 #include <osl/diagnose.h>
34 #include <mdds/flat_segment_tree.hpp>
39 aMultiSel(rSheetLimits),
40 mrSheetLimits(rSheetLimits)
190 OSL_FAIL(
"GetFirstSelected: nothing selected");
199 OSL_FAIL(
"GetLastSelected: nothing selected");
245 SCROW nStartRow, nEndRow;
249 SCROW nCmpStart, nCmpEnd;
250 for (
SCCOL nCol=nStartCol+1; nCol<=nEndCol && bOk; nCol++)
252 || nCmpStart != nStartRow || nCmpEnd != nEndRow )
330 const ScRange& rRange = rList[ 0 ];
336 for (
size_t i=0;
i < nCount;
i++)
349 : aMultiSel(rLimits),
350 mrSheetLimits(rLimits)
354 for (
const ScRange& rRange : rList)
357 if (rList.size() > 1)
364 else if (rList.size() == 1)
366 const ScRange& rRange = rList[ 0 ];
388 for (
SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
397 SCCOL nToCol = nCol+1;
398 for ( ; nToCol <= nEndCol; ++nToCol)
404 ScRange aRange( nCol, 0, nTab, nToCol, 0, nTab );
407 while ( aMultiIter.
Next( nTop, nBottom ) )
411 pList->
Join( aRange );
466 typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType;
470 SpansType::const_iterator itPos = aSpans.begin();
472 for (
size_t i = 0,
n = aRanges.
size();
i <
n; ++
i)
478 return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans);
491 typedef mdds::flat_segment_tree<SCCOLROW, bool> SpansType;
493 SpansType::const_iterator itPos = aSpans.begin();
498 itPos = aSpans.insert(itPos, nStartCol, nEndCol+1,
true).first;
505 for (
SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
508 if (pMultiArray && pMultiArray->
HasMarks())
509 itPos = aSpans.insert(itPos, nCol, nCol+1,
true).first;
517 return sc::toSpanArray<SCCOLROW,sc::ColRowSpan>(aSpans);
523 std::vector<sc::ColRowSpan> aVec;
526 aVec.emplace_back( nStartCol, nEndCol);
530 for (
SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
533 if (pMultiArray && pMultiArray->
HasMarks())
544 aVec.push_back( aSpan);
551 aVec.push_back( aSpan);
557 std::vector<sc::ColRowSpan> aVec;
586 for (
SCCOL nCol=nStartCol; nCol<=nEndCol && bOk; nCol++)
635 std::set<SCTAB> tabMarked;
639 tabMarked.insert(rTab);
641 tabMarked.insert(rTab + 1);
643 maTabMarked.swap(tabMarked);
648 std::set<SCTAB> tabMarked;
652 tabMarked.insert(rTab);
653 else if (rTab > nTab)
654 tabMarked.insert(rTab - 1);
656 maTabMarked.swap(tabMarked);
693 if ( nStartCol < rRangeDest.
aStart.
Col() )
695 if ( nStartRow < rRangeDest.
aStart.
Row() )
697 if ( nEndCol > rRangeDest.
aEnd.
Col() )
699 if ( nEndRow > rRangeDest.
aEnd.
Row() )
710 nStartCol = ( nStartCol == 0 ) ? nStartCol : nStartCol - 1;
712 std::unique_ptr<ScFlatBoolRowSegments> pPrevColMarkedRows;
713 std::unique_ptr<ScFlatBoolRowSegments> pCurColMarkedRows;
714 std::unordered_map<SCROW,ScFlatBoolColSegments> aRowToColSegmentsInTopEnvelope;
715 std::unordered_map<SCROW,ScFlatBoolColSegments> aRowToColSegmentsInBottomEnvelope;
719 bool bPrevColUnMarked =
false;
721 for (
SCCOL nCol=nStartCol; nCol <= nEndCol; nCol++ )
725 if ( !bCurColUnMarked )
731 pPrevColMarkedRows ? *pPrevColMarkedRows
734 pPrevColMarkedRows ? *pPrevColMarkedRows
736 SCROW nTopPrev = 0, nBottomPrev = 0;
737 while ( aMultiIter.
Next( nTop, nBottom ) )
739 pCurColMarkedRows->setTrue( nTop, nBottom );
740 if( bPrevColUnMarked && ( nCol > nStartCol ))
747 else if( nCol > nStartCol )
749 SCROW nTop1 = nTop, nBottom1 = nTop;
750 while( nTop1 <= nBottom && nBottom1 <= nBottom )
752 bool bRangeMarked =
false;
753 const bool bHasValue = aPrevItr.
getValue( nTop1, bRangeMarked );
754 assert(bHasValue); (
void)bHasValue;
763 if( nBottom1 > nBottom )
772 while( nTopPrev <= nBottom && nBottomPrev <= nBottom )
775 const bool bHasValue = aPrevItr1.
getValue( nTopPrev, bRangeMarked );
776 assert(bHasValue); (
void)bHasValue;
780 if( nTopPrev < nTop )
782 if( nBottomPrev >= nTop )
784 nBottomPrev = nTop - 1;
789 nTopPrev = nBottomPrev = (nBottom + 1);
797 nTopPrev = ++nBottomPrev;
801 nTopPrev = nBottomPrev = ( nBottom + 1 );
806 nTopPrev = ++nBottomPrev;
815 auto it = aRowToColSegmentsInTopEnvelope.find(nTop - 1);
816 if (it == aRowToColSegmentsInTopEnvelope.end())
818 it->second.setTrue( nCol, nCol );
825 auto it = aRowToColSegmentsInBottomEnvelope.find(nBottom + 1);
826 if (it == aRowToColSegmentsInBottomEnvelope.end())
828 it->second.setTrue( nCol, nCol );
835 const bool bHasValue = aPrevItr1.
getValue( nTopPrev, bRangeMarked );
836 assert(bHasValue); (
void)bHasValue;
844 nTopPrev = ++nBottomPrev;
849 nTopPrev = ++nBottomPrev;
853 else if( nCol > nStartCol )
855 bPrevColUnMarked =
true;
856 SCROW nTopPrev = 0, nBottomPrev = 0;
857 bool bRangeMarked =
false;
859 pPrevColMarkedRows ? *pPrevColMarkedRows : aNoRowsMarked);
862 const bool bHasValue = aPrevItr.
getValue(nTopPrev, bRangeMarked);
863 assert(bHasValue); (
void)bHasValue;
871 nTopPrev = ++nBottomPrev;
876 nTopPrev = ++nBottomPrev;
880 if ( bCurColUnMarked )
881 pPrevColMarkedRows.reset();
883 pPrevColMarkedRows = std::move( pCurColMarkedRows );
885 for(
auto& rKV : aRowToColSegmentsInTopEnvelope )
887 SCCOL nStart = nStartCol;
889 while( nStart <= nEndCol )
891 if( !rKV.second.getRangeData( nStart, aRange ) )
896 nStart = aRange.
mnCol2 + 1;
899 for(
auto& rKV : aRowToColSegmentsInBottomEnvelope )
901 SCCOL nStart = nStartCol;
903 while( nStart <= nEndCol )
905 if( !rKV.second.getRangeData( nStart, aRange ) )
910 nStart = aRange.
mnCol2 + 1;
917 SCROW nRow1, nRow2, nRow1New, nRow2New;
918 SCCOL nCol1, nCol2, nCol1New, nCol2New;
946 rRange =
ScRange( nCol1New, nRow1New, nTab1, nCol2New, nRow2New, nTab2 );
SCROW GetNextMarked(SCCOL nCol, SCROW nRow, bool bUp) const
May return -1.
void SetMarkArea(SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark)
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
const ScSheetLimits & mrSheetLimits
bool HasOneMark(SCCOL nCol, SCROW &rStartRow, SCROW &rEndRow) const
void SetMultiMarkArea(const ScRange &rRange, bool bMark=true, bool bSetupMulti=false)
void ShiftRows(SCROW nStartRow, sal_Int32 nRowOffset)
bool getValue(SCROW nPos, bool &rVal)
bool setFalse(SCROW nRow1, SCROW nRow2)
std::vector< sc::ColRowSpan > GetMarkedRowSpans() const
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
const ScMarkArray * GetMultiSelArray(SCCOL nCol) const
void MarkFromRangeList(const ScRangeList &rList, bool bReset)
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
bool Next(SCROW &rTop, SCROW &rBottom)
bool HasMarks(SCCOL nCol) const
void DeleteTab(SCTAB nTab)
void IncColIfNotLessThan(const ScDocument &rDoc, SCCOL nStartCol, SCCOL nOffset)
bool GetMark(SCCOL nCol, SCROW nRow) const
This is a rather odd datastructure.
void ShiftCols(SCCOL nStartCol, sal_Int32 nColOffset)
SCTAB GetSelectCount() const
void SetAreaTab(SCTAB nTab)
void push_back(const ScRange &rRange)
bool IsRowMarked(SCROW nRow) const
static void lcl_AddRanges(ScRange &rRangeDest, const ScRange &rNewRange)
void PutInOrder(T &nStart, T &nEnd)
bool IsRowMarked(SCROW nRow) const
void SetMarkArea(const ScRange &rRange)
bool IsColumnMarked(SCCOL nCol) const
void ExtendRangeListTables(ScRangeList *pList) const
void GetSelectionCover(ScRange &rRange)
const SCROW mnMaxRow
Maximum addressable column.
SCROW GetNextMarked(SCCOL nCol, SCROW nRow, bool bUp) const
void SelectTable(SCTAB nTab, bool bNew)
void ShiftCols(const ScDocument &rDoc, SCCOL nStartCol, sal_Int32 nColOffset)
void SelectOneTable(SCTAB nTab)
ScMarkData & operator=(const ScMarkData &rData)
bool HasEqualRowsMarked(SCCOL nCol1, SCCOL nCol2) const
void IncRowIfNotLessThan(const ScDocument &rDoc, SCROW nStartRow, SCROW nOffset)
void InsertTab(SCTAB nTab)
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
ScRangeList aLeftEnvelope
ScRangeList aBottomEnvelope
void Join(const ScRange &, bool bIsInList=false)
void ShiftRows(const ScDocument &rDoc, SCROW nStartRow, sal_Int32 nRowOffset)
MarkedTabsType maTabMarked
SCTAB GetFirstSelected() const
SCTAB GetLastSelected() const
bool IsRowRangeMarked(SCROW nStartRow, SCROW nEndRow) const
ScRangeList GetMarkedRangesForTab(SCTAB nTab) const
Get marked ranges with sheet-tab set to nTab.
bool IsAllMarked(SCCOL nCol, SCROW nStartRow, SCROW nEndRow) const
bool HasAnyMultiMarks() const
SCCOL GetStartOfEqualColumns(SCCOL nLastCol, SCCOL nMinCol=0) const
ScRangeList GetMarkedRanges() const
ScRangeList aRightEnvelope
ScMarkData(const ScSheetLimits &rSheetLimits)
void Set(ScRangeList const &)
optimised init-from-range-list.
bool GetTableSelect(SCTAB nTab) const
void insert(std::vector< ScRange >::iterator aPos, std::vector< ScRange >::const_iterator aSourceBegin, std::vector< ScRange >::const_iterator aSourceEnd)
std::vector< sc::ColRowSpan > GetMarkedColSpans() const
constexpr OUStringLiteral first
std::set< SCTAB > MarkedTabsType
SCCOL GetStartOfEqualColumns(SCCOL nLastCol, SCCOL nMinCol=0) const
const ScMarkArray & GetRowSelArray() const
bool IsAllMarked(const ScRange &rRange) const
bool HasMultiMarks(SCCOL nCol) const
void SetSelectedTabs(const MarkedTabsType &rTabs)