[Libreoffice-commits] core.git: desktop/source include/vcl sc/inc sc/source

Dennis Francis (via logerrit) logerrit at kemper.freedesktop.org
Sat Jul 4 07:48:13 UTC 2020


 desktop/source/lib/init.cxx         |   67 +++++++++++++++++++++++
 include/vcl/ITiledRenderable.hxx    |   25 ++++++++
 sc/inc/document.hxx                 |   19 ++++++
 sc/inc/docuno.hxx                   |    4 +
 sc/inc/olinetab.hxx                 |    6 ++
 sc/inc/segmenttree.hxx              |    7 ++
 sc/inc/table.hxx                    |   16 +++++
 sc/source/core/data/document10.cxx  |    9 +++
 sc/source/core/data/olinetab.cxx    |   27 +++++++++
 sc/source/core/data/segmenttree.cxx |   59 ++++++++++++++++++++
 sc/source/core/data/table7.cxx      |  104 ++++++++++++++++++++++++++++++++++++
 sc/source/ui/inc/tabview.hxx        |    4 +
 sc/source/ui/unoobj/docuno.cxx      |   15 +++++
 sc/source/ui/view/tabview.cxx       |   77 ++++++++++++++++++++++++++
 14 files changed, 439 insertions(+)

New commits:
commit 777f9cec0985f99451ecb804d5ae139a0be32253
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue May 5 01:55:37 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Sat Jul 4 09:47:30 2020 +0200

    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.
    
    Conflicts:
            sc/source/core/data/segmenttree.cxx
            sc/source/ui/inc/tabview.hxx
            sc/source/ui/unoobj/docuno.cxx
    
    Change-Id: Ib6aee9a0c92746b1576ed244e98cb54b572778c0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96892
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Dennis Francis <dennis.francis at collabora.com>
    (cherry picked from commit 9faf7b5e7abe39c287f28f83fd14a364e959c881)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96963
    Tested-by: Jenkins

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a34565e9d0c1..bc6a0e18ed92 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -4875,6 +4875,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
 
     OString aCommand(pCommand);
     static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
+    static const OString aSheetGeometryData(".uno:SheetGeometryData");
     static const OString aCellCursor(".uno:CellCursor");
     static const OString aFontSubset(".uno:FontSubset&name=");
 
@@ -4970,6 +4971,72 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
         pDoc->getRowColumnHeaders(aRectangle, aJsonWriter);
         return aJsonWriter.extractData();
     }
+    else if (aCommand.startsWith(aSheetGeometryData))
+    {
+        ITiledRenderable* pDoc = getTiledRenderable(pThis);
+        if (!pDoc)
+        {
+            SetLastExceptionMsg("Document doesn't support tiled rendering");
+            return nullptr;
+        }
+
+        bool bColumns = true;
+        bool bRows = true;
+        bool bSizes = true;
+        bool bHidden = true;
+        bool bFiltered = true;
+        bool bGroups = true;
+        if (aCommand.getLength() > aSheetGeometryData.getLength())
+        {
+            bColumns = bRows = bSizes = bHidden = bFiltered = bGroups = false;
+
+            OString aArguments = aCommand.copy(aSheetGeometryData.getLength() + 1);
+            sal_Int32 nParamIndex = 0;
+            do
+            {
+                OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
+                sal_Int32 nIndex = 0;
+                OString aKey;
+                OString aValue;
+                do
+                {
+                    OString aToken = aParamToken.getToken(0, '=', nIndex);
+                    if (!aKey.getLength())
+                        aKey = aToken;
+                    else
+                        aValue = aToken;
+
+                } while (nIndex >= 0);
+
+                bool bEnableFlag = aValue.isEmpty() ||
+                    aValue.equalsIgnoreAsciiCase("true") || aValue.toInt32() > 0;
+                if (!bEnableFlag)
+                    continue;
+
+                if (aKey == "columns")
+                    bColumns = true;
+                else if (aKey == "rows")
+                    bRows = true;
+                else if (aKey == "sizes")
+                    bSizes = true;
+                else if (aKey == "hidden")
+                    bHidden = true;
+                else if (aKey == "filtered")
+                    bFiltered = true;
+                else if (aKey == "groups")
+                    bGroups = true;
+
+            } while (nParamIndex >= 0);
+        }
+
+        OString aGeomDataStr
+            = pDoc->getSheetGeometryData(bColumns, bRows, bSizes, bHidden, bFiltered, bGroups);
+
+        if (aGeomDataStr.isEmpty())
+            return nullptr;
+
+        return convertOString(aGeomDataStr);
+    }
     else if (aCommand.startsWith(aCellCursor))
     {
         ITiledRenderable* pDoc = getTiledRenderable(pThis);
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 7b841844874d..2e8b557505f1 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -177,6 +177,31 @@ public:
     {
     }
 
+    /**
+     * Generates a serialization of the active (Calc document) sheet's geometry data.
+     *
+     * @param bColumns - if true, the column widths/hidden/filtered/groups data
+     *     are included depending on the settings of the flags bSizes, bHidden,
+     *     bFiltered and bGroups.
+     * @param bRows - if true, the row heights/hidden/filtered/groups data
+     *     are included depending on the settings of the flags bSizes, bHidden,
+     *     bFiltered and bGroups.
+     * @bSizes - if true, the column-widths and/or row-heights data (represented as a list of spans)
+     *     are included depending on the settings of the flags bColumns and bRows.
+     * @bHidden - if true, the hidden columns and/or rows data (represented as a list of spans)
+     *     are included depending on the settings of the flags bColumns and bRows.
+     * @bFiltered - if true, the filtered columns and/or rows data (represented as a list of spans)
+     *     are included depending on the settings of the flags bColumns and bRows.
+     * @bGroups - if true, the column grouping and/or row grouping data
+     *     are included depending on the settings of the flags bColumns and bRows.
+     * @return serialization of the active sheet's geometry data as OString.
+     */
+    virtual OString getSheetGeometryData(bool /*bColumns*/, bool /*bRows*/, bool /*bSizes*/,
+                                         bool /*bHidden*/, bool /*bFiltered*/, bool /*bGroups*/)
+    {
+        return "";
+    }
+
     /**
      * Get position and size of cell cursor in Calc - as JSON in the
      * current' views' co-ordinate system.
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0f7415ac846f..619bcbce8d38 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -262,6 +262,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;
@@ -2526,6 +2535,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 de902ebc20e9..3f63b66cf8d7 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -368,6 +368,10 @@ public:
     /// @see vcl::ITiledRenderable::getRowColumnHeaders().
     virtual void getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::JsonWriter& rJsonWriter) 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 void getCellCursor(tools::JsonWriter& rJsonWriter) 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 9d772a0b4b46..f37a3d3facd6 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 12f8bb87bc89..5ffd70c77541 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1081,6 +1081,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(
@@ -1240,6 +1249,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 0aac4ce29025..259d16585918 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -1025,4 +1025,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 254f0f875571..00033438e0f8 100644
--- a/sc/source/core/data/segmenttree.cxx
+++ b/sc/source/core/data/segmenttree.cxx
@@ -416,6 +416,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 = (aRange.mbValue ? OStringLiteral("1") : OStringLiteral("0")) + OStringLiteral(":");
+        else
+            aSegment.clear();
+
+        aSegment += OString::number(aRange.mnRow2) + " ";
+        aOutput += aSegment;
+        nRow = aRange.mnRow2 + 1;
+    }
+
+    return aOutput;
+}
+
 ScFlatBoolColSegments::ScFlatBoolColSegments(SCCOL nMaxCol) :
     mpImpl(new ScFlatBoolSegmentsImpl(nMaxCol))
 {
@@ -462,6 +483,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 = (aRange.mbValue ? OStringLiteral("1") : OStringLiteral("0")) + OStringLiteral(":");
+        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)
 {
@@ -554,4 +596,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 38f1d02e3fd7..28aabb204894 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 a9cf83dfe8c2..f7986b20cf2d 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -593,6 +593,10 @@ public:
     void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges );
     /// @see ScModelObj::getRowColumnHeaders().
     void getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::JsonWriter& rJsonWriter);
+    /// @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 68c48ac8e9de..cd14cf8d0879 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -934,6 +934,21 @@ void ScModelObj::getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::
     pTabView->getRowColumnHeaders(rRectangle, rJsonWriter);
 }
 
+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);
+}
+
 void ScModelObj::getCellCursor(tools::JsonWriter& rJsonWriter)
 {
     SolarMutexGuard aGuard;
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 765ef9a1e1d0..2658db649d40 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -50,6 +50,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>
@@ -2754,4 +2757,78 @@ void ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::J
     }
 }
 
+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: */


More information about the Libreoffice-commits mailing list