summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2017-11-27 17:50:26 +0100
committerJan Holesovsky <kendy@collabora.com>2017-11-28 22:00:44 +0100
commit6964953c5a86ef02fa9320e1db4d6bd81cee5001 (patch)
tree0ddebfd0de2c37e04329237329da8e8f498b1c82
parentf4c6426d28aea11743881906d8179c220fa73b9f (diff)
lok - calc: outline and group handling
Change-Id: Ibb287468653bc381acf034dcb8531c5faf61aef3 Reviewed-on: https://gerrit.libreoffice.org/45416 Reviewed-by: Jan Holesovsky <kendy@collabora.com> Tested-by: Jan Holesovsky <kendy@collabora.com>
-rw-r--r--desktop/source/lib/init.cxx18
-rw-r--r--include/vcl/ITiledRenderable.hxx13
-rw-r--r--sc/inc/docuno.hxx3
-rw-r--r--sc/source/ui/docshell/olinefun.cxx30
-rw-r--r--sc/source/ui/inc/dbfunc.hxx3
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx10
-rw-r--r--sc/source/ui/undo/undoblk.cxx9
-rw-r--r--sc/source/ui/undo/undoblk2.cxx6
-rw-r--r--sc/source/ui/undo/undodat.cxx10
-rw-r--r--sc/source/ui/unoobj/docuno.cxx13
-rw-r--r--sc/source/ui/view/cellsh1.cxx5
-rw-r--r--sc/source/ui/view/dbfunc3.cxx53
-rw-r--r--sc/source/ui/view/gridwin.cxx12
-rw-r--r--sc/source/ui/view/tabview.cxx208
-rw-r--r--sc/source/ui/view/tabvwshc.cxx38
-rw-r--r--sc/source/ui/view/viewfunc.cxx14
16 files changed, 408 insertions, 37 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 307418fcd55c..fe046459751f 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3009,6 +3009,10 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
int nY = 0;
int nWidth = 0;
int nHeight = 0;
+ bool bColumn = false;
+ int nLevel = -1;
+ int nGroupIndex = -2;
+ bool bHidden = false;
OString aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1);
sal_Int32 nParamIndex = 0;
do
@@ -3034,9 +3038,23 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
nWidth = aValue.toInt32();
else if (aKey == "height")
nHeight = aValue.toInt32();
+ else if (aKey == "columnOutline")
+ bColumn = aValue.toBoolean();
+ else if (aKey == "groupLevel")
+ nLevel = aValue.toInt32();
+ else if (aKey == "groupIndex")
+ nGroupIndex = aValue.toInt32();
+ else if (aKey == "groupHidden")
+ bHidden = aValue.toBoolean();
}
while (nParamIndex >= 0);
+
aRectangle = Rectangle(nX, nY, nX + nWidth, nY + nHeight);
+
+ if (nGroupIndex != -2)
+ {
+ pDoc->setOutlineState(bColumn, nLevel, nGroupIndex, bHidden);
+ }
}
OUString aHeaders = pDoc->getRowColumnHeaders(aRectangle);
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index ae3ba9e76c3c..95676d751244 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -151,6 +151,19 @@ public:
}
/**
+ * Show/Hide a single row/column header outline for Calc dosuments.
+ *
+ * @param bColumn - if we are dealing with a column or row group
+ * @param nLevel - the level to which the group belongs
+ * @param nIndex - the group entry index
+ * @param bHidden - the new group state (collapsed/expanded)
+ */
+ virtual void setOutlineState(bool /*bColumn*/, int /*nLevel*/, int /*nIndex*/, bool /*bHidden*/)
+ {
+ return;
+ }
+
+ /**
* Get position and content of row/column headers of Calc documents.
*
* @param rRectangle - if not empty, then limit the output only to the area of this rectangle
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index 917b211a82a1..e37f11a9ba49 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -409,6 +409,9 @@ public:
/// @see vcl::ITiledRenderable::setClientZoom().
virtual void setClientZoom(int nTilePixelWidth, int nTilePixelHeight, int nTileTwipWidth, int nTileTwipHeight) override;
+ /// @see vcl::ITiledRenderable::setOutlineState().
+ virtual void setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden) override;
+
/// @see vcl::ITiledRenderable::getRowColumnHeaders().
virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override;
diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx
index a96eadf2d964..c2e56231cc74 100644
--- a/sc/source/ui/docshell/olinefun.cxx
+++ b/sc/source/ui/docshell/olinefun.cxx
@@ -27,6 +27,10 @@
#include "globstr.hrc"
#include "sc.hrc"
+#include <tabvwsh.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <comphelper/lok.hxx>
+
static void lcl_InvalidateOutliner( SfxBindings* pBindings )
{
if ( pBindings )
@@ -402,6 +406,10 @@ bool ScOutlineDocFunc::SelectLevel( SCTAB nTab, bool bColumns, sal_uInt16 nLevel
rDocShell.SetDocumentModified();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
+ if ( pViewSh )
+ pViewSh->OnLOKShowHideOutline(bColumns, 0);
+
return true;
}
@@ -462,6 +470,7 @@ bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, bool bRecord )
if (nEnd>nMax) nMax=nEnd;
}
}
+ const SCCOLROW nMinStartCol = nMin;
for ( i=nMin; i<=nMax; i++ )
rDoc.ShowCol( static_cast<SCCOL>(i), nTab, true );
@@ -483,6 +492,7 @@ bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, bool bRecord )
if (nEnd>nMax) nMax=nEnd;
}
}
+ const SCCOLROW nMinStartRow = nMin;
for ( i=nMin; i<=nMax; i++ )
{
// show several rows together, don't show filtered rows
@@ -494,6 +504,7 @@ bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, bool bRecord )
i = nFilterEnd;
}
+
rDoc.SetDrawPageSize(nTab);
rDoc.UpdatePageBreaks( nTab );
@@ -502,6 +513,13 @@ bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, bool bRecord )
bDone = true;
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
+
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
+ if ( pViewSh )
+ {
+ pViewSh->OnLOKShowHideOutline(/*columns: */ true, nMinStartCol - 1);
+ pViewSh->OnLOKShowHideOutline(/*columns: */ false, nMinStartRow - 1);
+ }
}
return bDone;
@@ -681,7 +699,11 @@ bool ScOutlineDocFunc::ShowOutline( SCTAB nTab, bool bColumns, sal_uInt16 nLevel
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
- return true; //! immer ???
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
+ if ( pViewSh )
+ pViewSh->OnLOKShowHideOutline(bColumns, nStart - 1);
+
+ return true; //! always ???
}
bool ScOutlineDocFunc::HideOutline( SCTAB nTab, bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
@@ -740,7 +762,11 @@ bool ScOutlineDocFunc::HideOutline( SCTAB nTab, bool bColumns, sal_uInt16 nLevel
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
- return true; //! immer ???
+ ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
+ if ( pViewSh )
+ pViewSh->OnLOKShowHideOutline(bColumns, nStart - 1);
+
+ return true; //! always ???
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx
index ad71348a1e56..6ec96c6103ec 100644
--- a/sc/source/ui/inc/dbfunc.hxx
+++ b/sc/source/ui/inc/dbfunc.hxx
@@ -103,6 +103,7 @@ public:
void SelectLevel( bool bColumns, sal_uInt16 nLevel,
bool bRecord = true );
+ void SetOutlineState( bool bColumn, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bHidden);
void ShowOutline( bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
bool bRecord = true, bool bPaint = true );
void HideOutline( bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
@@ -115,6 +116,8 @@ public:
void UpdateCharts(bool bAllCharts); // Default: am Cursor
static sal_uInt16 DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, bool bAllCharts );
+
+ void OnLOKShowHideOutline(bool bColumns, SCROW nStartRow);
};
#endif
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 9c304ee164b9..2df115f27226 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -91,6 +91,13 @@ enum ObjectSelectionType
OST_Media
};
+enum HeaderType
+{
+ COLUMN_HEADER,
+ ROW_HEADER,
+ BOTH_HEADERS
+};
+
class SC_DLLPUBLIC ScTabViewShell: public SfxViewShell, public ScDBFunc
{
private:
@@ -398,7 +405,8 @@ public:
void NotifyCursor(SfxViewShell* pViewShell) const override;
css::uno::Reference<css::drawing::XShapes> getSelectedXShapes();
/// Emits a LOK_CALLBACK_INVALIDATE_HEADER for all views whose current tab is equal to nCurrentTabIndex
- static void notifyAllViewsHeaderInvalidation(const OString& rPayload, SCTAB nCurrentTabIndex = -1);
+ static void notifyAllViewsHeaderInvalidation(HeaderType eHeaderType, SCTAB nCurrentTabIndex = -1);
+ static void notifyAllViewsHeaderInvalidation(bool Columns, SCTAB nCurrentTabIndex = -1);
};
#endif
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 6af80db9eb15..97781f21f799 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -279,12 +279,11 @@ void ScUndoInsertCells::DoChange( const bool bUndo )
if (comphelper::LibreOfficeKit::isActive())
{
if (eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER || eCmd == INS_CELLSRIGHT)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("column", pViewShell->GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(COLUMN_HEADER, pViewShell->GetViewData().GetTabNo());
if (eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER || eCmd == INS_CELLSDOWN)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("row", pViewShell->GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(ROW_HEADER, pViewShell->GetViewData().GetTabNo());
}
-
}
}
@@ -541,10 +540,10 @@ void ScUndoDeleteCells::DoChange( const bool bUndo )
if (comphelper::LibreOfficeKit::isActive())
{
if (eCmd == DEL_DELCOLS || eCmd == DEL_CELLSLEFT)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("column", pViewShell->GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(COLUMN_HEADER, pViewShell->GetViewData().GetTabNo());
if (eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("row", pViewShell->GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(ROW_HEADER, pViewShell->GetViewData().GetTabNo());
}
}
diff --git a/sc/source/ui/undo/undoblk2.cxx b/sc/source/ui/undo/undoblk2.cxx
index 8a1247cbca14..50589d7a8ace 100644
--- a/sc/source/ui/undo/undoblk2.cxx
+++ b/sc/source/ui/undo/undoblk2.cxx
@@ -131,11 +131,7 @@ void ScUndoWidthOrHeight::Undo()
if ( nCurrentTab < nStartTab || nCurrentTab > nEndTab )
pViewShell->SetTabNo( nStartTab );
- if (comphelper::LibreOfficeKit::isActive())
- {
- OString aPayload = bWidth ? "column" : "row";
- ScTabViewShell::notifyAllViewsHeaderInvalidation(aPayload, pViewShell->GetViewData().GetTabNo());
- }
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(bWidth, pViewShell->GetViewData().GetTabNo());
}
EndUndo();
diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx
index 1595bf118e74..c17333a2370e 100644
--- a/sc/source/ui/undo/undodat.cxx
+++ b/sc/source/ui/undo/undodat.cxx
@@ -44,6 +44,8 @@
#include "refundo.hxx"
#include "markdata.hxx"
+#include <sfx2/lokhelper.hxx>
+#include <comphelper/lok.hxx>
// Show or hide outline groups
@@ -182,6 +184,8 @@ void ScUndoMakeOutline::Undo()
pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
+ ScTabViewShell::notifyAllViewsHeaderInvalidation( bColumns, nTab );
+
EndUndo();
}
@@ -374,6 +378,10 @@ void ScUndoOutlineBlock::Undo()
pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top);
+
+ pViewShell->OnLOKShowHideOutline(/*columns: */ true, nStartCol - 1);
+ pViewShell->OnLOKShowHideOutline(/*columns: */ false, nStartRow - 1);
+
EndUndo();
}
@@ -463,6 +471,8 @@ void ScUndoRemoveAllOutlines::Undo()
pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(BOTH_HEADERS, nTab);
+
EndUndo();
}
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 473a8dcb17ac..0d5e4f50a159 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -958,6 +958,19 @@ void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int
mnTileTwipHeight = nTileTwipHeight_;
}
+void ScModelObj::setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden)
+{
+ ScViewData* pViewData = ScDocShell::GetViewData();
+
+ if (!pViewData)
+ return;
+
+ ScDBFunc* pFunc = pViewData->GetView();
+
+ if (pFunc)
+ pFunc->SetOutlineState(bColumn, nLevel, nIndex, bHidden);
+}
+
OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle)
{
ScViewData* pViewData = ScDocShell::GetViewData();
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 6c0a2ec22f79..bbce79c3564a 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1169,7 +1169,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
bColumns = true;
else if ( !GetViewData()->SimpleColMarked() && GetViewData()->SimpleRowMarked() )
bColumns = false;
- else
+ else if ( !comphelper::LibreOfficeKit::isActive() ) // TODO: handle this case in LOK too
{
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
@@ -1228,7 +1228,8 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
{
bool bColPoss, bRowPoss;
pTabViewShell->TestRemoveOutline( bColPoss, bRowPoss );
- if ( bColPoss && bRowPoss )
+ // TODO: handle this case in LOK too
+ if ( bColPoss && bRowPoss && !comphelper::LibreOfficeKit::isActive() )
{
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 304a1428d6bb..95e104536d59 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -68,6 +68,9 @@
#include "stringutil.hxx"
#include "tabvwsh.hxx"
+#include <sfx2/lokhelper.hxx>
+#include <comphelper/lok.hxx>
+
#include <list>
#include <memory>
#include <unordered_set>
@@ -99,6 +102,8 @@ void ScDBFunc::MakeOutline( bool bColumns, bool bRecord )
ScDocShell* pDocSh = GetViewData().GetDocShell();
ScOutlineDocFunc aFunc(*pDocSh);
aFunc.MakeOutline( aRange, bColumns, bRecord, false );
+
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(bColumns, GetViewData().GetTabNo());
}
else
ErrorMessage(STR_NOMULTISELECT);
@@ -114,6 +119,8 @@ void ScDBFunc::RemoveOutline( bool bColumns, bool bRecord )
ScDocShell* pDocSh = GetViewData().GetDocShell();
ScOutlineDocFunc aFunc(*pDocSh);
aFunc.RemoveOutline( aRange, bColumns, bRecord, false );
+
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(bColumns, GetViewData().GetTabNo());
}
else
ErrorMessage(STR_NOMULTISELECT);
@@ -187,7 +194,10 @@ void ScDBFunc::RemoveAllOutlines( bool bRecord )
bool bOk = aFunc.RemoveAllOutlines( nTab, bRecord );
if (bOk)
+ {
UpdateScrollBars();
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(BOTH_HEADERS, GetViewData().GetTabNo());
+ }
}
// auto outlines
@@ -224,6 +234,20 @@ void ScDBFunc::SelectLevel( bool bColumns, sal_uInt16 nLevel, bool bRecord )
// show individual outline groups
+void ScDBFunc::SetOutlineState( bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bHidden)
+{
+ const sal_uInt16 nHeadEntry = static_cast< sal_uInt16 >( -1 );
+ if ( nEntry == nHeadEntry)
+ SelectLevel( bColumns, sal::static_int_cast<sal_uInt16>(nLevel) );
+ else
+ {
+ if ( !bHidden )
+ ShowOutline( bColumns, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
+ else
+ HideOutline( bColumns, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
+ }
+}
+
void ScDBFunc::ShowOutline( bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bRecord, bool bPaint )
{
SCTAB nTab = GetViewData().GetTabNo();
@@ -2239,4 +2263,33 @@ void ScDBFunc::RepeatDB( bool bRecord )
ErrorMessage(STR_MSSG_REPEATDB_0);
}
+void ScDBFunc::OnLOKShowHideOutline(bool bColumns, SCCOLROW nStart)
+{
+ if (!comphelper::LibreOfficeKit::isActive())
+ return;
+
+ SCTAB nCurrentTabIndex = GetViewData().GetTabNo();
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while (pViewShell)
+ {
+ ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
+ if (pTabViewShell)
+ {
+ if (bColumns)
+ pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex)->invalidateByIndex(nStart);
+ else
+ pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex)->invalidateByIndex(nStart);
+
+ if (pTabViewShell->getPart() == nCurrentTabIndex)
+ {
+ pTabViewShell->ShowCursor();
+ pTabViewShell->MarkDataChanged();
+ }
+ }
+ pViewShell = SfxViewShell::GetNext(*pViewShell);
+ }
+
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(bColumns, nCurrentTabIndex);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 4a716cf536fb..bfea6b18804c 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5750,8 +5750,18 @@ OString ScGridWindow::getCellCursor(const Fraction& rZoomX, const Fraction& rZoo
double fPPTX = pViewData->GetPPTX();
double fPPTY = pViewData->GetPPTY();
+ // make it a slim cell cursor, but not empty
+ if (nSizeXPix == 0)
+ nSizeXPix = 1;
+
+ if (nSizeYPix == 0)
+ nSizeYPix = 1;
+
+ long nSizeXTw = rtl::math::round(nSizeXPix / fPPTX);
+ long nSizeYTw = rtl::math::round(nSizeYPix / fPPTY);
+
Rectangle aRect(Point(rtl::math::round(aScrPos.getX() / fPPTX), rtl::math::round(aScrPos.getY() / fPPTY)),
- Size(rtl::math::round(nSizeXPix / fPPTX), rtl::math::round(nSizeYPix / fPPTY)));
+ Size(nSizeXTw, nSizeYTw));
pViewData->SetZoom(defaultZoomX, defaultZoomY, true);
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 4aef7be67b16..de425afdd698 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -2560,6 +2560,148 @@ void BoundsProvider<IndexType>::GetIndexTowards(
}
}
+namespace
+{
+
+void lcl_getGroupIndexes(const ScOutlineArray& rArray, SCCOLROW nStart, SCCOLROW nEnd, std::vector<size_t>& rGroupIndexes)
+{
+ rGroupIndexes.clear();
+ const size_t nGroupDepth = rArray.GetDepth();
+ rGroupIndexes.resize(nGroupDepth);
+
+ // Get first group per each level
+ for (size_t nLevel = 0; nLevel < nGroupDepth; ++nLevel)
+ {
+ if (rArray.GetCount(nLevel))
+ {
+ // look for a group inside the [nStartRow+1, nEndRow-1] range
+ size_t nIndex;
+ bool bFound = rArray.GetEntryIndexInRange(nLevel, nStart + 1, nEnd - 1, nIndex);
+ if (bFound)
+ {
+ if (nIndex > 0)
+ {
+ // is there a prevoius group not inside the range
+ // but anyway intersecting it ?
+ const ScOutlineEntry* pPrevEntry = rArray.GetEntry(nLevel, nIndex - 1);
+ if (pPrevEntry && nStart < pPrevEntry->GetEnd())
+ {
+ --nIndex;
+ }
+ }
+ }
+ else
+ {
+ // look for a group which contains nStartRow+1
+ bFound = rArray.GetEntryIndex(nLevel, nStart + 1, nIndex);
+ if (!bFound)
+ {
+ // look for a group which contains nEndRow-1
+ bFound = rArray.GetEntryIndex(nLevel, nEnd - 1, nIndex);
+ }
+ }
+
+ if (bFound)
+ {
+ // skip groups with no visible control
+ bFound = false;
+ while (nIndex < rArray.GetCount(nLevel))
+ {
+ const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
+ if (pEntry && pEntry->IsVisible())
+ {
+ bFound = true;
+ break;
+ }
+ if (pEntry && pEntry->GetStart() > nEnd - 1)
+ {
+ break;
+ }
+ ++nIndex;
+ }
+ }
+
+ rGroupIndexes[nLevel] = bFound ? nIndex : -1;
+ }
+ }
+}
+
+void lcl_createGroupsData(
+ SCCOLROW nHeaderIndex, SCCOLROW nEnd, long nSizePx, long nTotalTwips,
+ const ScOutlineArray& rArray, std::vector<size_t>& rGroupIndexes,
+ std::vector<long>& rGroupStartPositions, OUString& rGroupsBuffer)
+{
+ const size_t nGroupDepth = rArray.GetDepth();
+ // create string data for group controls
+ for (size_t nLevel = nGroupDepth - 1; nLevel != size_t(-1); --nLevel)
+ {
+ size_t nIndex = rGroupIndexes[nLevel];
+ if (nIndex == size_t(-1))
+ continue;
+ const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
+ if (pEntry)
+ {
+ if (nHeaderIndex < pEntry->GetStart())
+ {
+ continue;
+ }
+ else if (nHeaderIndex == pEntry->GetStart())
+ {
+ rGroupStartPositions[nLevel] = nTotalTwips - nSizePx * TWIPS_PER_PIXEL;
+ }
+ else if (nHeaderIndex > pEntry->GetStart() && (nHeaderIndex < nEnd - 1 && nHeaderIndex < pEntry->GetEnd()))
+ {
+ // for handling group started before the current view range
+ if (rGroupStartPositions[nLevel] < 0)
+ rGroupStartPositions[nLevel] *= -TWIPS_PER_PIXEL;
+ break;
+ }
+ if (nHeaderIndex == pEntry->GetEnd() || (nHeaderIndex == nEnd - 1 && rGroupStartPositions[nLevel] != -1))
+ {
+ // nRow is the end row of a group or is the last row and a group started and not yet ended
+ // append a new group control data
+ if (rGroupsBuffer.endsWith("}"))
+ {
+ rGroupsBuffer += ", ";
+ }
+
+ bool bGroupHidden = pEntry->IsHidden();
+
+ OUString aGroupData;
+ aGroupData += "{ \"level\": \"" + OUString::number(nLevel + 1) + "\", ";
+ aGroupData += "\"index\": \"" + OUString::number(nIndex) + "\", ";
+ aGroupData += "\"startPos\": \"" + OUString::number(rGroupStartPositions[nLevel]) + "\", ";
+ aGroupData += "\"endPos\": \"" + OUString::number(nTotalTwips) + "\", ";
+ aGroupData += "\"hidden\": \"" + OUString::number(bGroupHidden) + "\" }";
+
+ rGroupsBuffer += aGroupData;
+
+ // look for the next visible group control at level nLevel
+ bool bFound = false;
+ ++nIndex;
+ while (nIndex < rArray.GetCount(nLevel))
+ {
+ pEntry = rArray.GetEntry(nLevel, nIndex);
+ if (pEntry && pEntry->IsVisible())
+ {
+ bFound = true;
+ break;
+ }
+ if (pEntry && pEntry->GetStart() > nEnd)
+ {
+ break;
+ }
+ ++nIndex;
+ }
+ rGroupIndexes[nLevel] = bFound ? nIndex : -1;
+ rGroupStartPositions[nLevel] = -1;
+ }
+ }
+ }
+}
+
+} // anonymous namespace
+
OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
{
ScDocument* pDoc = aViewData.GetDocument();
@@ -2618,6 +2760,20 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
SAL_INFO("sc.lok.header", "Row Header: visible rows: " << nVisibleRows);
+ // Get row groups
+ // per each level store the index of the first group intersecting
+ // [nStartRow, nEndRow] range
+
+ const ScOutlineTable* pTable = pDoc->GetOutlineTable(nTab);
+ const ScOutlineArray* pRowArray = pTable ? &(pTable->GetRowArray()) : nullptr;
+ size_t nRowGroupDepth = 0;
+ std::vector<size_t> aRowGroupIndexes;
+ if (pTable)
+ {
+ nRowGroupDepth = pRowArray->GetDepth();
+ lcl_getGroupIndexes(*pRowArray, nStartRow, nEndRow, aRowGroupIndexes);
+ }
+
/// 2) if we are approaching current max tiled row, signal a size changed event
/// and invalidate the involved area
@@ -2671,15 +2827,27 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
{
OUString aText = OUString::number(nStartRow + 1);
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
- aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+ aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\", ");
+ aBuffer.append("\"groupLevels\": \"").append(OUString::number(nRowGroupDepth)).append("\" }");
}
+ OUString aRowGroupsBuffer;
+ aRowGroupsBuffer += "\"rowGroups\": [\n";
+ std::vector<long> aRowGroupStartPositions(nRowGroupDepth, -nTotalPixels);
long nPrevSizePx = -1;
for (SCROW nRow = nStartRow + 1; nRow < nEndRow; ++nRow)
{
// nSize will be 0 for hidden rows.
const long nSizePx = lcl_GetRowHeightPx(pDoc, nRow, nTab);
nTotalPixels += nSizePx;
+ const long nTotalTwips = nTotalPixels * TWIPS_PER_PIXEL;
+
+ if (nRowGroupDepth > 0)
+ {
+ lcl_createGroupsData(nRow, nEndRow, nSizePx, nTotalTwips,
+ *pRowArray, aRowGroupIndexes, aRowGroupStartPositions, aRowGroupsBuffer);
+ }
+
if (nRow < nEndRow - 1 && nSizePx == nPrevSizePx)
continue;
nPrevSizePx = nSizePx;
@@ -2687,10 +2855,13 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
aBuffer.append(", ");
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
- aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+ aBuffer.append("\"size\": \"").append(OUString::number(nTotalTwips)).append("\" }");
}
+ aRowGroupsBuffer += "]";
aBuffer.append("]");
+ if (nRowGroupDepth > 0)
+ aBuffer.append(",\n").append(aRowGroupsBuffer);
/// end collecting ROWS
@@ -2731,6 +2902,19 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
nVisibleCols = 10;
+ // Get column groups
+ // per each level store the index of the first group intersecting
+ // [nStartCol, nEndCol] range
+
+ const ScOutlineArray* pColArray = pTable ? &(pTable->GetColArray()) : nullptr;
+ size_t nColGroupDepth = 0;
+ std::vector<size_t> aColGroupIndexes;
+ if (pTable)
+ {
+ nColGroupDepth = pColArray->GetDepth();
+ lcl_getGroupIndexes(*pColArray, nStartCol, nEndCol, aColGroupIndexes);
+ }
+
/// 2) if we are approaching current max tiled column, signal a size changed event
/// and invalidate the involved area
@@ -2782,27 +2966,41 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
{
OUString aText = OUString::number(nStartCol + 1);
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
- aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+ aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\", ");
+ aBuffer.append("\"groupLevels\": \"").append(OUString::number(nColGroupDepth)).append("\" }");
}
+ OUString aColGroupsBuffer;
+ aColGroupsBuffer += "\"columnGroups\": [\n";
+ std::vector<long> aColGroupStartPositions(nColGroupDepth, -nTotalPixels);
nPrevSizePx = -1;
for (SCCOL nCol = nStartCol + 1; nCol < nEndCol; ++nCol)
{
// nSize will be 0 for hidden columns.
const long nSizePx = lcl_GetColWidthPx(pDoc, nCol, nTab);
nTotalPixels += nSizePx;
+ const long nTotalTwips = nTotalPixels * TWIPS_PER_PIXEL;
+
+ if (nColGroupDepth > 0)
+ {
+ lcl_createGroupsData(nCol, nEndCol, nSizePx, nTotalTwips,
+ *pColArray, aColGroupIndexes, aColGroupStartPositions, aColGroupsBuffer);
+ }
+
if (nCol < nEndCol - 1 && nSizePx == nPrevSizePx)
continue;
nPrevSizePx = nSizePx;
-
OUString aText = OUString::number(nCol + 1);
aBuffer.append(", ");
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
- aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+ aBuffer.append("\"size\": \"").append(OUString::number(nTotalTwips)).append("\" }");
}
+ aColGroupsBuffer += "]";
aBuffer.append("]");
+ if (nColGroupDepth > 0)
+ aBuffer.append(",\n").append(aColGroupsBuffer);
/// end collecting COLs
aBuffer.append("\n}");
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 287947424165..fa92b345ff32 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -551,20 +551,44 @@ void ScTabViewShell::NotifyCursor(SfxViewShell* pOtherShell) const
pWin->updateLibreOfficeKitCellCursor(pOtherShell);
}
-void ScTabViewShell::notifyAllViewsHeaderInvalidation(const OString& rPayload, SCTAB nCurrentTabIndex)
+void ScTabViewShell::notifyAllViewsHeaderInvalidation(HeaderType eHeaderType, SCTAB nCurrentTabIndex)
{
- SfxViewShell* pViewShell = SfxViewShell::GetFirst();
- while (pViewShell)
+ if (comphelper::LibreOfficeKit::isActive())
{
- ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
- if (pTabViewShell && (nCurrentTabIndex == -1 || pTabViewShell->getPart() == nCurrentTabIndex))
+ OString aPayload;
+ switch (eHeaderType)
{
- pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_HEADER, rPayload.getStr());
+ case COLUMN_HEADER:
+ aPayload = "column";
+ break;
+ case ROW_HEADER:
+ aPayload = "row";
+ break;
+ case BOTH_HEADERS:
+ default:
+ aPayload = "all";
+ break;
+ }
+
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while (pViewShell)
+ {
+ ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
+ if (pTabViewShell && (nCurrentTabIndex == -1 || pTabViewShell->getPart() == nCurrentTabIndex))
+ {
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_HEADER, aPayload.getStr());
+ }
+ pViewShell = SfxViewShell::GetNext(*pViewShell);
}
- pViewShell = SfxViewShell::GetNext(*pViewShell);
}
}
+void ScTabViewShell::notifyAllViewsHeaderInvalidation(bool bColumns, SCTAB nCurrentTabIndex)
+{
+ HeaderType eHeaderType = bColumns ? COLUMN_HEADER : ROW_HEADER;
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(eHeaderType, nCurrentTabIndex);
+}
+
bool ScTabViewShell::UseSubTotal(ScRangeList* pRangeList)
{
bool bSubTotal = false;
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index b8208b828106..f77419050127 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1621,10 +1621,10 @@ bool ScViewFunc::InsertCells( InsCellCmd eCmd, bool bRecord, bool bPartOfPaste )
if (comphelper::LibreOfficeKit::isActive())
{
if (bInsertCols)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("column", GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(COLUMN_HEADER, GetViewData().GetTabNo());
if (bInsertRows)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("row", GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(ROW_HEADER, GetViewData().GetTabNo());
}
}
return bSuccess;
@@ -1696,10 +1696,10 @@ void ScViewFunc::DeleteCells( DelCellCmd eCmd )
if (comphelper::LibreOfficeKit::isActive())
{
if (eCmd == DEL_DELCOLS)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("column", GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(COLUMN_HEADER, GetViewData().GetTabNo());
if (eCmd == DEL_DELROWS)
- ScTabViewShell::notifyAllViewsHeaderInvalidation("row", GetViewData().GetTabNo());
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(ROW_HEADER, GetViewData().GetTabNo());
}
}
else
@@ -2297,11 +2297,7 @@ void ScViewFunc::SetWidthOrHeight(
}
}
- if (comphelper::LibreOfficeKit::isActive())
- {
- OString aPayload = bWidth ? "column" : "row";
- ScTabViewShell::notifyAllViewsHeaderInvalidation(aPayload, GetViewData().GetTabNo());
- }
+ ScTabViewShell::notifyAllViewsHeaderInvalidation(bWidth, GetViewData().GetTabNo());
}
// column width/row height (via marked range)