[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - desktop/source include/vcl sc/inc sc/source

Dennis Francis (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 22 17:13:00 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 9faf7b5e7abe39c287f28f83fd14a364e959c881
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: Mon Jun 22 19:08:25 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.
    
    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>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 67ce622436ee..b1732dc1bbea 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -4825,6 +4825,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=");
 
@@ -4922,6 +4923,72 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
         else
             return convertOUString(aHeaders);
     }
+    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 4fcf0c9f05e1..e089592e41fa 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -178,6 +178,31 @@ public:
         return OUString();
     }
 
+    /**
+     * 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 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: */


More information about the Libreoffice-commits mailing list