diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2020-05-05 01:55:37 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2020-06-22 19:08:25 +0200 |
commit | 9faf7b5e7abe39c287f28f83fd14a364e959c881 (patch) | |
tree | 5e9795d64c36d5900d10511e271e220c33a2eb81 /sc | |
parent | 8cd6f7ae48f5795778de512b2867a8ed3374ef12 (diff) |
Introduce ITiledRenderable::getSheetGeometryData()
ITiledRenderable::getSheetGeometryData(bool bColumns, bool bRows,
bool bSizes, bool bHidden,
bool bFiltered, bool bGroups)
and implement it for the Calc derivation (ScModelObj).
The aim is to use it actively in LOOL instead of the interface:
ITiledRenderable::getRowColumnHeaders(const tools::Rectangle& /*rRectangle*/)
This is used by the LOOL to fetch the sheet geometry data for just the
current view-area in the clients, so LOOL queries this everytime some
client's view-area changes.
Like the existing interface, the new one will provide all 'kinds' of
sheet geometry info [col/row sizes(twips), hidden/filtered and
grouping]. But the difference is, it generates data for the whole sheet
(not view-area specific). So the method need not be queried every time
the view area changes in the LOOL clients, and more importantly it
enables the clients to locate any cell at any zoom level without any
further help from the core. This means core needn't send various
client(zoom) specific positioning messages in pixel aligned twips. It
just can send all positioning messages in print twips uniformly to all
clients.
Change-Id: Ib6aee9a0c92746b1576ed244e98cb54b572778c0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96892
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 19 | ||||
-rw-r--r-- | sc/inc/docuno.hxx | 4 | ||||
-rw-r--r-- | sc/inc/olinetab.hxx | 6 | ||||
-rw-r--r-- | sc/inc/segmenttree.hxx | 7 | ||||
-rw-r--r-- | sc/inc/table.hxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/olinetab.cxx | 27 | ||||
-rw-r--r-- | sc/source/core/data/segmenttree.cxx | 59 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 104 | ||||
-rw-r--r-- | sc/source/ui/inc/tabview.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 15 | ||||
-rw-r--r-- | sc/source/ui/view/tabview.cxx | 77 |
12 files changed, 347 insertions, 0 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index a23e14296efe..52946b919f6a 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -258,6 +258,15 @@ enum RangeNameScope SHEET // with two scope on Manage Names dialog. }; +/// Represents the type of sheet geometry data. +enum class SheetGeomType +{ + SIZES, // Column widths or row heights. + HIDDEN, // Hidden columns/rows. + FILTERED, // Filtered columns/rows. + GROUPS // Grouping of columns/rows. +}; + struct ScDocStat { OUString aDocName; @@ -2502,6 +2511,16 @@ public: bool IsInDocShellRecalc() const { return mbDocShellRecalc; } void SetDocShellRecalc(bool bSet) { mbDocShellRecalc = bSet; } + /** + * Serializes the specified sheet's geometry data. + * + * @param nTab is the index of the sheet to operate on. + * @param bColumns - if true it dumps the data for columns, else it does for rows. + * @param eGeomType indicates the type of data to be dumped for rows/columns. + * @return the serialization of the specified sheet's geometry data as an OString. + */ + OString dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType eGeomType); + private: /** diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 78416db9e4b5..6108c7a3e9a4 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -366,6 +366,10 @@ public: /// @see vcl::ITiledRenderable::getRowColumnHeaders(). virtual OUString getRowColumnHeaders(const tools::Rectangle& rRectangle) override; + /// @see vcl::ITiledRenderable::getSheetGeometryData(). + virtual OString getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, + bool bFiltered, bool bGroups) override; + /// @see vcl::ITiledRenderable::getCellCursor(). virtual OString getCellCursor() override; diff --git a/sc/inc/olinetab.hxx b/sc/inc/olinetab.hxx index a25064d86c4e..cdaa74d19a93 100644 --- a/sc/inc/olinetab.hxx +++ b/sc/inc/olinetab.hxx @@ -59,6 +59,8 @@ public: void SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize ); void SetHidden( bool bNewHidden ); void SetVisible( bool bNewVisible ); + + OString dumpAsString() const; }; class ScOutlineCollection @@ -83,6 +85,8 @@ public: bool empty() const; iterator FindStart(SCCOLROW nMinStart); + + OString dumpAsString() const; }; class SC_DLLPUBLIC ScOutlineArray @@ -138,6 +142,8 @@ public: void finalizeImport(const ScTable& rTable); void RemoveAll(); + + OString dumpAsString() const; }; class ScOutlineTable diff --git a/sc/inc/segmenttree.hxx b/sc/inc/segmenttree.hxx index 8414176d125d..23a7ad78b389 100644 --- a/sc/inc/segmenttree.hxx +++ b/sc/inc/segmenttree.hxx @@ -21,6 +21,7 @@ #define INCLUDED_SC_INC_SEGMENTTREE_HXX #include "types.hxx" +#include <rtl/string.hxx> #include <memory> @@ -76,6 +77,8 @@ public: SCROW findLastTrue() const; + OString dumpAsString(); + private: ::std::unique_ptr<ScFlatBoolSegmentsImpl> mpImpl; }; @@ -99,6 +102,8 @@ public: void removeSegment(SCCOL nCol1, SCCOL nCol2); void insertSegment(SCCOL nCol, SCCOL nSize); + OString dumpAsString(); + private: ::std::unique_ptr<ScFlatBoolSegmentsImpl> mpImpl; }; @@ -147,6 +152,8 @@ public: void enableTreeSearch(bool bEnable); + OString dumpAsString(); + private: ::std::unique_ptr<ScFlatUInt16SegmentsImpl> mpImpl; }; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index a7d051663e2a..30c4b174b2ff 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -1078,6 +1078,15 @@ public: SCCOL ClampToAllocatedColumns(SCCOL nCol) const { return std::min(nCol, static_cast<SCCOL>(aCol.size() - 1)); } SCCOL GetAllocatedColumnsCount() const { return aCol.size(); } + /** + * Serializes the sheet's geometry data. + * + * @param bColumns - if true it dumps the data for columns, else it does for rows. + * @param eGeomType indicates the type of data to be dumped for rows/columns. + * @return the serialization of the sheet's geometry data as an OString. + */ + OString dumpSheetGeomData(bool bColumns, SheetGeomType eGeomType); + private: void FillFormulaVertical( @@ -1237,6 +1246,13 @@ private: void EndListeningGroup( sc::EndListeningContext& rCxt, const SCCOL nCol, SCROW nRow ); void SetNeedsListeningGroup( SCCOL nCol, SCROW nRow ); + /// Returns list-of-spans representation of the column-widths/row-heights in twips encoded as an OString. + OString dumpColumnRowSizes(bool bColumns); + /// Returns list-of-spans representation of hidden/filtered states of columns/rows encoded as an OString. + OString dumpHiddenFiltered(bool bColumns, bool bHidden); + /// Returns list-of-spans representation of the column/row groupings encoded as an OString. + OString dumpColumnRowGroups(bool bColumns) const; + /** * Use this to iterate through non-empty visible cells in a single column. */ diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 31d2cb7fed89..ae87f2e75b39 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -968,4 +968,13 @@ void ScDocument::RestoreTabFromCache(SCTAB nTab, SvStream& rStrm) pTab->RestoreFromCache(rStrm); } +OString ScDocument::dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType eGeomType) +{ + ScTable* pTab = FetchTable(nTab); + if (!pTab) + return ""; + + return pTab->dumpSheetGeomData(bColumns, eGeomType); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/olinetab.cxx b/sc/source/core/data/olinetab.cxx index a7e66c8f8d55..84b9c59af3be 100644 --- a/sc/source/core/data/olinetab.cxx +++ b/sc/source/core/data/olinetab.cxx @@ -81,6 +81,13 @@ void ScOutlineEntry::SetVisible( bool bNewVisible ) bVisible = bNewVisible; } +OString ScOutlineEntry::dumpAsString() const +{ + const char* const pSep = ":"; + return OString::number(nStart) + pSep + OString::number(nSize) + + pSep + (bHidden ? "1" : "0") + pSep + (bVisible ? "1" : "0"); +} + ScOutlineCollection::ScOutlineCollection() {} size_t ScOutlineCollection::size() const @@ -134,6 +141,16 @@ ScOutlineCollection::iterator ScOutlineCollection::FindStart(SCCOLROW nMinStart) return m_Entries.lower_bound(nMinStart); } +OString ScOutlineCollection::dumpAsString() const +{ + OString aOutput; + const char* const pGroupEntrySep = ","; + for (const auto& rKeyValuePair : m_Entries) + aOutput += rKeyValuePair.second.dumpAsString() + pGroupEntrySep; + + return aOutput; +} + ScOutlineArray::ScOutlineArray() : nDepth(0) {} @@ -725,6 +742,16 @@ void ScOutlineArray::finalizeImport(const ScTable& rTable) } } +OString ScOutlineArray::dumpAsString() const +{ + OString aOutput; + const char* const pLevelSep = " "; + for (const auto& rCollection : aCollections) + aOutput += rCollection.dumpAsString() + pLevelSep; + + return aOutput; +} + ScOutlineTable::ScOutlineTable() { } diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx index 01f1f9d82416..57600bbe39bd 100644 --- a/sc/source/core/data/segmenttree.cxx +++ b/sc/source/core/data/segmenttree.cxx @@ -412,6 +412,27 @@ SCROW ScFlatBoolRowSegments::findLastTrue() const return mpImpl->findLastTrue(false); } +OString ScFlatBoolRowSegments::dumpAsString() +{ + OString aOutput; + OString aSegment; + RangeData aRange; + SCROW nRow = 0; + while (getRangeData(nRow, aRange)) + { + if (!nRow) + aSegment = OStringLiteral(aRange.mbValue ? "1" : "0") + ":"; + else + aSegment.clear(); + + aSegment += OString::number(aRange.mnRow2) + " "; + aOutput += aSegment; + nRow = aRange.mnRow2 + 1; + } + + return aOutput; +} + ScFlatBoolColSegments::ScFlatBoolColSegments() : mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXCOL))) { @@ -458,6 +479,27 @@ void ScFlatBoolColSegments::insertSegment(SCCOL nCol, SCCOL nSize) mpImpl->insertSegment(static_cast<SCCOLROW>(nCol), static_cast<SCCOLROW>(nSize), true/*bSkipStartBoundary*/); } +OString ScFlatBoolColSegments::dumpAsString() +{ + OString aOutput; + OString aSegment; + RangeData aRange; + SCCOL nCol = 0; + while (getRangeData(nCol, aRange)) + { + if (!nCol) + aSegment = OStringLiteral(aRange.mbValue ? "1" : "0") + ":"; + else + aSegment.clear(); + + aSegment += OString::number(aRange.mnCol2) + " "; + aOutput += aSegment; + nCol = aRange.mnCol2 + 1; + } + + return aOutput; +} + ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments& rSegs) : mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0) { @@ -550,4 +592,21 @@ void ScFlatUInt16RowSegments::setValueIf(SCROW nRow1, SCROW nRow2, sal_uInt16 nV mpImpl->setValueIf(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2), nValue, rPredicate); } +OString ScFlatUInt16RowSegments::dumpAsString() +{ + OString aOutput; + OString aSegment; + RangeData aRange; + SCROW nRow = 0; + while (getRangeData(nRow, aRange)) + { + aSegment = OString::number(aRange.mnValue) + ":" + + OString::number(aRange.mnRow2) + " "; + aOutput += aSegment; + nRow = aRange.mnRow2 + 1; + } + + return aOutput; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 29dd2ddc9041..0a792102feec 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -479,4 +479,108 @@ void ScTable::RestoreFromCache(SvStream& rStrm) } } +OString ScTable::dumpSheetGeomData(bool bColumns, SheetGeomType eGeomType) +{ + switch (eGeomType) + { + case SheetGeomType::SIZES: + // returns a non-empty space separated list of spans with trailing space. + // The format of the span is <size of any row/col in the span in print twips>:<last row/col of the span> + // Example (for columns with three spans if MAXCOL is 1023): "1280:3 1049:50 1280:1023" + return dumpColumnRowSizes(bColumns); + case SheetGeomType::HIDDEN: + // returns a non-empty space separated list of spans with trailing space. + // The format of the span is: + // 1) First span: <1 (span is hidden) / 0 (not hidden)>:<last row/col of the span> + // 2) Rest of the spans: <last row/col of the span> + // The hidden state of the spans after the first can be inferred from the first span's flag as no adjacent + // spans can have the same state by definition of span. + return dumpHiddenFiltered(bColumns, /*bHidden*/ true); + case SheetGeomType::FILTERED: + // has exactly the same format as 'hidden'. + return dumpHiddenFiltered(bColumns, /*bHidden*/ false); + case SheetGeomType::GROUPS: + // returns a space separated list of 'levels' with trailing space. + // A 'level' is a comma separated list of groups(outline entries) with trailing comma. + // format of a group is: + // <start row/col of group>:<number of rows/cols in the group>:<1/0(group is hidden?)>:<1/0(control is visible?)> + return dumpColumnRowGroups(bColumns); + default: + ; + } + + return ""; +} + +OString ScTable::dumpColumnRowSizes(bool bColumns) +{ + // If the data-structures are not available, just report that all + // rows/cols have the default sizes. + static const OString aDefaultForCols + = OString::number(STD_COL_WIDTH) + ":" + OString::number(MAXCOL) + " "; + static const OString aDefaultForRows + = OString::number(ScGlobal::nStdRowHeight) + ":" + OString::number(MAXROW) + " "; + + // ScCompressedArray is a template class and we don't want to impose + // the restriction that its value type should be string serializable, + // instead just operate on the specialized object. + typedef ScCompressedArray<SCCOL, sal_uInt16> ColWidthsType; + auto dumpColWidths = [](const ColWidthsType& rWidths) -> OString { + OString aOutput; + OString aSegment; + SCCOL nStartCol = 0; + const SCCOL nMaxCol = std::min(rWidths.GetLastPos(), MAXCOL); + size_t nDummy = 0; + while (nStartCol <= nMaxCol) + { + SCCOL nEndCol; + sal_uInt16 nWidth = rWidths.GetValue(nStartCol, nDummy, nEndCol); + // The last span nEndCol is always MAXCOL+1 for some reason, and we don't want that. + if (nEndCol > nMaxCol) + nEndCol = nMaxCol; + aSegment = OString::number(nWidth) + ":" + OString::number(nEndCol) + " "; + aOutput += aSegment; + nStartCol = nEndCol + 1; + } + + return aOutput; + }; + + if (bColumns) + return mpColWidth ? dumpColWidths(*mpColWidth) : aDefaultForCols; + + return mpRowHeights ? mpRowHeights->dumpAsString() : aDefaultForRows; +} + +OString ScTable::dumpHiddenFiltered(bool bColumns, bool bHidden) +{ + // defaults to no hidden/filtered row/cols. + static const OString aDefaultForCols = "0:" + OString::number(MAXCOL) + " "; + static const OString aDefaultForRows = "0:" + OString::number(MAXROW) + " "; + + if (bHidden) + { + if (bColumns) + return mpHiddenCols ? mpHiddenCols->dumpAsString() : aDefaultForCols; + + return mpHiddenRows ? mpHiddenRows->dumpAsString() : aDefaultForRows; + } + + if (bColumns) + return mpFilteredCols ? mpFilteredCols->dumpAsString() : aDefaultForCols; + + return mpFilteredRows ? mpFilteredRows->dumpAsString() : aDefaultForRows; +} + +OString ScTable::dumpColumnRowGroups(bool bColumns) const +{ + if (!pOutlineTable) + return ""; + + if (bColumns) + return pOutlineTable->GetColArray().dumpAsString(); + + return pOutlineTable->GetRowArray().dumpAsString(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index 0ee1cfd48819..1116a4fa161a 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -604,6 +604,10 @@ public: void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges ); /// @see ScModelObj::getRowColumnHeaders(). OUString getRowColumnHeaders(const tools::Rectangle& rRectangle); + /// @see ScModelObj::getSheetGeometryData() + OString getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, + bool bFiltered, bool bGroups); + static void OnLOKNoteStateChanged(const ScPostIt* pNote); SCROW GetLOKStartHeaderRow() const { return mnLOKStartHeaderRow; } diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 2671b02c2edc..2365445381cc 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -908,6 +908,21 @@ OUString ScModelObj::getRowColumnHeaders(const tools::Rectangle& rRectangle) return pTabView->getRowColumnHeaders(rRectangle); } +OString ScModelObj::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, + bool bFiltered, bool bGroups) +{ + ScViewData* pViewData = ScDocShell::GetViewData(); + + if (!pViewData) + return ""; + + ScTabView* pTabView = pViewData->GetView(); + if (!pTabView) + return ""; + + return pTabView->getSheetGeometryData(bColumns, bRows, bSizes, bHidden, bFiltered, bGroups); +} + OString ScModelObj::getCellCursor() { SolarMutexGuard aGuard; diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 7cbce3567ccf..4df6a2d60a05 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -49,6 +49,9 @@ #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <sfx2/lokhelper.hxx> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> + #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> #include <algorithm> @@ -2757,4 +2760,78 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) return sRet; } +OString ScTabView::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, + bool bFiltered, bool bGroups) +{ + boost::property_tree::ptree aTree; + aTree.put("commandName", ".uno:SheetGeometryData"); + + auto getJSONString = [](const boost::property_tree::ptree& rTree) { + std::stringstream aStream; + boost::property_tree::write_json(aStream, rTree); + return aStream.str(); + }; + + ScDocument* pDoc = aViewData.GetDocument(); + if (!pDoc) + return getJSONString(aTree).c_str(); + + if ((!bSizes && !bHidden && !bFiltered && !bGroups) || + (!bColumns && !bRows)) + { + return getJSONString(aTree).c_str(); + } + + struct GeomEntry + { + SheetGeomType eType; + const char* pKey; + bool bEnabled; + }; + + const GeomEntry aGeomEntries[] = { + { SheetGeomType::SIZES, "sizes", bSizes }, + { SheetGeomType::HIDDEN, "hidden", bHidden }, + { SheetGeomType::FILTERED, "filtered", bFiltered }, + { SheetGeomType::GROUPS, "groups", bGroups } + }; + + struct DimensionEntry + { + const char* pKey; + bool bDimIsCol; + bool bEnabled; + }; + + const DimensionEntry aDimEntries[] = { + { "columns", true, bColumns }, + { "rows", false, bRows } + }; + + SCTAB nTab = aViewData.GetTabNo(); + + for (const auto& rDimEntry : aDimEntries) + { + if (!rDimEntry.bEnabled) + continue; + + bool bDimIsCol = rDimEntry.bDimIsCol; + + boost::property_tree::ptree aDimTree; + for (const auto& rGeomEntry : aGeomEntries) + { + if (!rGeomEntry.bEnabled) + continue; + + OString aGeomDataEncoding = pDoc->dumpSheetGeomData(nTab, bDimIsCol, rGeomEntry.eType); + // TODO: Investigate if we can avoid the copy of the 'value' string in put(). + aDimTree.put(rGeomEntry.pKey, aGeomDataEncoding.getStr()); + } + + aTree.add_child(rDimEntry.pKey, aDimTree); + } + + return getJSONString(aTree).c_str(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |