lok-freezepanes: Generalize FreezePanes* uno-commands...

to allow an integer parameter as the row/column index of the freeze and
use them to set/get freeze indices (row/column) from the lok clients.
The behaviour of the exisiting freeze/split-panes controls in desktop
Calc is not affected, but new menu/notebookbar options can be added for
freezing on a specific row/column in a follow-up commit.

For now, the freeze-panes are shared between all views for each tab of
the spreadsheet. "Private" freeze-panes support can also be added
without much difficulty (for this we need another uno command for the
private/shared flag, but that can be in a separate commit).

Notes regarding compatibility:

Since Online-Calc has support only for the freeze-panes functionality
presently, any pre-exisiting 'real splits' in the spreadsheet (created
using the native-desktop Calc or alternatives) are converted to
equivalent 'freezes' on import, but on export, such 'freezes' are
re-converted and written as 'real splits'. In case the spreadsheet has
'freezes' on import, they are used/exported as such. In short, the type
of sheet-window splits in the document are preserved.

Change-Id: Ia990616f5cedfb2b5db820770c17ec7e209f0e48
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99347
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Dennis Francis
2020-07-24 15:19:40 +02:00
parent 4948b14eed
commit 7b4802070a
21 changed files with 441 additions and 94 deletions
+3 -1
View File
@@ -2742,7 +2742,9 @@ static void doc_iniUnoCommands ()
OUString(".uno:ParaspaceIncrease"),
OUString(".uno:ParaspaceDecrease"),
OUString(".uno:AcceptTrackedChange"),
OUString(".uno:RejectTrackedChange")
OUString(".uno:RejectTrackedChange"),
OUString(".uno:FreezePanesColumn"),
OUString(".uno:FreezePanesRow")
};
util::URL aCommandURL;
@@ -99,7 +99,7 @@
<value>1</value>
</prop>
</node>
<node oor:name=".uno:FreezePanesFirstColumn" oor:op="replace">
<node oor:name=".uno:FreezePanesColumn" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Freeze First Column</value>
</prop>
@@ -107,7 +107,7 @@
<value>1</value>
</prop>
</node>
<node oor:name=".uno:FreezePanesFirstRow" oor:op="replace">
<node oor:name=".uno:FreezePanesRow" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Freeze First Row</value>
</prop>
+5
View File
@@ -2546,6 +2546,11 @@ public:
*/
OString dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType eGeomType);
SCCOL GetLOKFreezeCol(SCTAB nTab) const;
SCROW GetLOKFreezeRow(SCTAB nTab) const;
bool SetLOKFreezeCol(SCCOL nFreezeCol, SCTAB nTab);
bool SetLOKFreezeRow(SCROW nFreezeRow, SCTAB nTab);
private:
/**
+7
View File
@@ -224,6 +224,8 @@ private:
std::unique_ptr<ScConditionalFormatList> mpCondFormatList;
ScAddress maLOKFreezeCell;
bool bScenario:1;
bool bLayoutRTL:1;
bool bLoadingRTL:1;
@@ -1257,6 +1259,11 @@ private:
/// Returns list-of-spans representation of the column/row groupings encoded as an OString.
OString dumpColumnRowGroups(bool bColumns) const;
SCCOL GetLOKFreezeCol() const;
SCROW GetLOKFreezeRow() const;
bool SetLOKFreezeCol(SCCOL nFreezeCol);
bool SetLOKFreezeRow(SCROW nFreezeRow);
/**
* Use this to iterate through non-empty visible cells in a single column.
*/
+4 -4
View File
@@ -1911,8 +1911,8 @@ SfxVoidItem FreezePanes SID_WINDOW_FIX
GroupId = SfxGroupId::View;
]
SfxVoidItem FreezePanesFirstColumn SID_WINDOW_FIX_COL
()
SfxInt32Item FreezePanesColumn SID_WINDOW_FIX_COL
[
AutoUpdate = FALSE,
FastCall = FALSE,
@@ -1928,8 +1928,8 @@ SfxVoidItem FreezePanesFirstColumn SID_WINDOW_FIX_COL
GroupId = SfxGroupId::View;
]
SfxVoidItem FreezePanesFirstRow SID_WINDOW_FIX_ROW
()
SfxInt32Item FreezePanesRow SID_WINDOW_FIX_ROW
[
AutoUpdate = FALSE,
FastCall = FALSE,
+2 -2
View File
@@ -145,8 +145,8 @@ interface TableEditView
SID_CURRENTDOC [ ExecMethod = Execute; StateMethod = GetState; ]
SID_WINDOW_SPLIT [ ExecMethod = Execute; StateMethod = GetState; ]
SID_WINDOW_FIX [ ExecMethod = Execute; StateMethod = GetState; ]
SID_WINDOW_FIX_ROW [ ExecMethod = Execute; ]
SID_WINDOW_FIX_COL [ ExecMethod = Execute; ]
SID_WINDOW_FIX_ROW [ ExecMethod = Execute; StateMethod = GetState; ]
SID_WINDOW_FIX_COL [ ExecMethod = Execute; StateMethod = GetState; ]
SID_SAVEDOC
[
ExecMethod = ExecuteSave ;
+35
View File
@@ -1034,4 +1034,39 @@ OString ScDocument::dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType e
return pTab->dumpSheetGeomData(bColumns, eGeomType);
}
SCCOL ScDocument::GetLOKFreezeCol(SCTAB nTab) const
{
const ScTable* pTab = FetchTable(nTab);
if (!pTab)
return -1;
return pTab->GetLOKFreezeCol();
}
SCROW ScDocument::GetLOKFreezeRow(SCTAB nTab) const
{
const ScTable* pTab = FetchTable(nTab);
if (!pTab)
return -1;
return pTab->GetLOKFreezeRow();
}
bool ScDocument::SetLOKFreezeCol(SCCOL nFreezeCol, SCTAB nTab)
{
ScTable* pTab = FetchTable(nTab);
if (!pTab)
return false;
return pTab->SetLOKFreezeCol(nFreezeCol);
}
bool ScDocument::SetLOKFreezeRow(SCROW nFreezeRow, SCTAB nTab)
{
ScTable* pTab = FetchTable(nTab);
if (!pTab)
return false;
return pTab->SetLOKFreezeRow(nFreezeRow);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+1
View File
@@ -256,6 +256,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName,
aTabBgColor( COL_AUTO ),
nScenarioFlags(ScScenarioFlags::NONE),
mpCondFormatList( new ScConditionalFormatList() ),
maLOKFreezeCell(-1, -1, nNewTab),
bScenario(false),
bLayoutRTL(false),
bLoadingRTL(false),
+45
View File
@@ -20,6 +20,7 @@
#include <drwlayer.hxx>
#include <compressedarray.hxx>
#include <sal/log.hxx>
#include <tools/stream.hxx>
bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
@@ -583,4 +584,48 @@ OString ScTable::dumpColumnRowGroups(bool bColumns) const
return pOutlineTable->GetRowArray().dumpAsString();
}
SCCOL ScTable::GetLOKFreezeCol() const
{
return maLOKFreezeCell.Col();
}
SCROW ScTable::GetLOKFreezeRow() const
{
return maLOKFreezeCell.Row();
}
bool ScTable::SetLOKFreezeCol(SCCOL nFreezeCol)
{
if (!ValidCol(nFreezeCol))
{
SAL_WARN("sc.core", "ScTable::SetLOKFreezeCol : invalid nFreezeCol = " << nFreezeCol);
return false;
}
if (maLOKFreezeCell.Col() != nFreezeCol)
{
maLOKFreezeCell.SetCol(nFreezeCol);
return true;
}
return false;
}
bool ScTable::SetLOKFreezeRow(SCROW nFreezeRow)
{
if (!ValidRow(nFreezeRow))
{
SAL_WARN("sc.core", "ScTable::SetLOKFreezeRow : invalid nFreezeRow = " << nFreezeRow);
return false;
}
if (maLOKFreezeCell.Row() != nFreezeRow)
{
maLOKFreezeCell.SetRow(nFreezeRow);
return true;
}
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+2 -2
View File
@@ -281,7 +281,7 @@ public:
ScTabView( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
~ScTabView();
enum SplitMethod { SC_SPLIT_METHOD_FIRST_COL, SC_SPLIT_METHOD_FIRST_ROW, SC_SPLIT_METHOD_CURSOR };
enum SplitMethod { SC_SPLIT_METHOD_COL, SC_SPLIT_METHOD_ROW, SC_SPLIT_METHOD_CURSOR };
void MakeDrawLayer();
@@ -569,7 +569,7 @@ public:
Point GetMousePosPixel();
void FreezeSplitters( bool bFreeze, SplitMethod eSplitMethod = SC_SPLIT_METHOD_CURSOR );
void FreezeSplitters( bool bFreeze, SplitMethod eSplitMethod = SC_SPLIT_METHOD_CURSOR, SCCOLROW nFreezeIndex = -1 );
void RemoveSplit();
void SplitAtCursor();
void SplitAtPixel( const Point& rPixel );
+13 -5
View File
@@ -250,7 +250,7 @@ private:
void InitData(ScDocument *pDoc);
void WriteUserDataSequence(
css::uno::Sequence <css::beans::PropertyValue>& rSettings,
const ScViewData& rViewData ) const;
const ScViewData& rViewData, SCTAB nTab ) const;
void ReadUserDataSequence(
const css::uno::Sequence <css::beans::PropertyValue>& rSettings,
@@ -396,8 +396,8 @@ public:
SCCOL MaxCol() const { return pDoc->MaxCol(); }
SCROW MaxRow() const { return pDoc->MaxRow(); }
ScSplitPos GetActivePart() const { return pThisTab->eWhichActive; }
SCCOL GetPosX( ScHSplitPos eWhich ) const;
SCROW GetPosY( ScVSplitPos eWhich ) const;
SCCOL GetPosX( ScHSplitPos eWhich, SCTAB nForTab = -1 ) const;
SCROW GetPosY( ScVSplitPos eWhich, SCTAB nForTab = -1 ) const;
SCCOL GetCurX() const { return pThisTab->nCurX; }
SCROW GetCurY() const { return pThisTab->nCurY; }
SCCOL GetCurXForTab( SCTAB nTabIndex ) const;
@@ -506,7 +506,7 @@ public:
bool GetMergeSizePrintTwips( SCCOL nX, SCROW nY, long& rSizeXTwips, long& rSizeYTwips ) const;
void GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
SCCOL& rPosX, SCROW& rPosY,
bool bTestMerge = true, bool bRepair = false );
bool bTestMerge = true, bool bRepair = false, SCTAB nForTab = -1 );
void GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
SCCOL nPosX, SCROW nPosY, bool& rLeft, bool& rTop );
@@ -601,7 +601,7 @@ public:
void SetActivePart( ScSplitPos eNewActive );
Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
bool bAllowNeg = false ) const;
bool bAllowNeg = false, SCTAB nForTab = -1 ) const;
Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const;
Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const;
/// returns the position (top-left corner) of the requested cell in print twips coordinates.
@@ -654,6 +654,14 @@ public:
bool IsSelCtrlMouseClick() const { return bSelCtrlMouseClick; }
SCCOLROW GetLOKSheetFreezeIndex(bool bIsCol) const;
bool SetLOKSheetFreezeIndex(const SCCOLROW nFreezeIndex, bool bIsCol, SCTAB nForTab = -1);
void DeriveLOKFreezeAllSheets();
void DeriveLOKFreezeIfNeeded(SCTAB nForTab);
void OverrideWithLOKFreeze(ScSplitMode& eExHSplitMode, ScSplitMode& eExVSplitMode,
SCCOL& nExFixPosX, SCROW& nExFixPosY,
long& nExHSplitPos, long& nExVSplitPos, SCTAB nForTab) const;
static inline long ToPixel( sal_uInt16 nTwips, double nFactor );
/** while (rScrY <= nEndPixels && rPosY <= nEndRow) add pixels of row
+17 -14
View File
@@ -1907,8 +1907,11 @@ Point ScTabView::GetMousePosPixel()
return aPos;
}
void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMethod, SCCOLROW nFreezeIndex)
{
if ((eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_ROW) && nFreezeIndex < 0)
nFreezeIndex = 0;
ScSplitMode eOldH = aViewData.GetHSplitMode();
ScSplitMode eOldV = aViewData.GetVSplitMode();
@@ -1929,10 +1932,10 @@ void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
SCROW nPosY = 1;
if (eOldV != SC_SPLIT_NONE || eOldH != SC_SPLIT_NONE)
{
if ( eOldV != SC_SPLIT_NONE && (eSplitMetod == SC_SPLIT_METHOD_FIRST_ROW || eSplitMetod == SC_SPLIT_METHOD_CURSOR))
if ( eOldV != SC_SPLIT_NONE && (eSplitMethod == SC_SPLIT_METHOD_ROW || eSplitMethod == SC_SPLIT_METHOD_CURSOR))
aSplit.setY( aViewData.GetVSplitPos() - aWinStart.Y() );
if ( eOldH != SC_SPLIT_NONE && (eSplitMetod == SC_SPLIT_METHOD_FIRST_COL || eSplitMetod == SC_SPLIT_METHOD_CURSOR))
if ( eOldH != SC_SPLIT_NONE && (eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_CURSOR))
{
long nSplitPos = aViewData.GetHSplitPos();
if ( bLayoutRTL )
@@ -1944,28 +1947,28 @@ void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
bool bLeft;
bool bTop;
aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
if (eSplitMetod == SC_SPLIT_METHOD_FIRST_COL)
nPosX = 1;
if (eSplitMethod == SC_SPLIT_METHOD_COL)
nPosX = static_cast<SCCOL>(nFreezeIndex);
else if (!bLeft)
++nPosX;
if (eSplitMetod == SC_SPLIT_METHOD_FIRST_ROW)
nPosY = 1;
if (eSplitMethod == SC_SPLIT_METHOD_ROW)
nPosY = static_cast<SCROW>(nFreezeIndex);
else if (!bTop)
++nPosY;
}
else
{
switch(eSplitMetod)
switch(eSplitMethod)
{
case SC_SPLIT_METHOD_FIRST_ROW:
case SC_SPLIT_METHOD_ROW:
{
nPosX = 0;
nPosY = 1;
nPosY = static_cast<SCROW>(nFreezeIndex);
}
break;
case SC_SPLIT_METHOD_FIRST_COL:
case SC_SPLIT_METHOD_COL:
{
nPosX = 1;
nPosX = static_cast<SCCOL>(nFreezeIndex);
nPosY = 0;
}
break;
@@ -1983,7 +1986,7 @@ void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
SCCOL nRightPos = nPosX;
if (eSplitMetod == SC_SPLIT_METHOD_FIRST_ROW || eSplitMetod == SC_SPLIT_METHOD_CURSOR)
if (eSplitMethod == SC_SPLIT_METHOD_ROW || eSplitMethod == SC_SPLIT_METHOD_CURSOR)
{
if (eOldV != SC_SPLIT_NONE)
{
@@ -2005,7 +2008,7 @@ void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
aViewData.SetVSplitMode( SC_SPLIT_NONE );
}
if (eSplitMetod == SC_SPLIT_METHOD_FIRST_COL || eSplitMetod == SC_SPLIT_METHOD_CURSOR)
if (eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_CURSOR)
{
if (eOldH != SC_SPLIT_NONE)
{
+37 -10
View File
@@ -50,7 +50,9 @@
#include <svx/zoomslideritem.hxx>
#include <svx/svxdlg.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/string.hxx>
#include <sfx2/lokhelper.hxx>
#include <scabstdlg.hxx>
namespace
@@ -940,18 +942,43 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
break;
case SID_WINDOW_FIX_COL:
{
FreezeSplitters( true, SC_SPLIT_METHOD_FIRST_COL);
rReq.Done();
InvalidateSplit();
}
break;
case SID_WINDOW_FIX_ROW:
{
FreezeSplitters( true, SC_SPLIT_METHOD_FIRST_ROW);
rReq.Done();
InvalidateSplit();
bool bIsCol = (nSlot == SID_WINDOW_FIX_COL);
sal_Int32 nFreezeIndex = 1;
if (const SfxInt32Item* pItem = rReq.GetArg<SfxInt32Item>(nSlot))
{
nFreezeIndex = pItem->GetValue();
if (nFreezeIndex < 0)
nFreezeIndex = 0;
}
if (comphelper::LibreOfficeKit::isActive())
{
ScViewData& rViewData = GetViewData();
SCTAB nThisTab = rViewData.GetTabNo();
bool bChanged = rViewData.SetLOKSheetFreezeIndex(nFreezeIndex, bIsCol);
rReq.Done();
if (bChanged)
{
rBindings.Invalidate(nSlot);
// Invalidate the slot for all views on the same tab of the document.
SfxLokHelper::forEachOtherView(this, [nSlot, nThisTab](ScTabViewShell* pOther) {
ScViewData& rOtherViewData = pOther->GetViewData();
if (rOtherViewData.GetTabNo() != nThisTab)
return;
SfxBindings& rOtherBind = rOtherViewData.GetBindings();
rOtherBind.Invalidate(nSlot);
});
}
}
else
{
FreezeSplitters( true, bIsCol ? SC_SPLIT_METHOD_COL : SC_SPLIT_METHOD_ROW, nFreezeIndex);
rReq.Done();
InvalidateSplit();
}
}
break;
+9
View File
@@ -417,6 +417,15 @@ void ScTabViewShell::GetState( SfxItemSet& rSet )
rViewData.GetVSplitMode() == SC_SPLIT_FIX ));
break;
case SID_WINDOW_FIX_COL:
case SID_WINDOW_FIX_ROW:
{
bool bIsCol = (nWhich == SID_WINDOW_FIX_COL);
sal_Int32 nFreezeIndex = rViewData.GetLOKSheetFreezeIndex(bIsCol);
rSet.Put(SfxInt32Item(nWhich, nFreezeIndex));
}
break;
case FID_CHG_SHOW:
{
if ( pDoc->GetChangeTrack() == nullptr || ( pDocShell && pDocShell->IsDocShared() ) )
+246 -43
View File
@@ -520,29 +520,43 @@ void ScViewDataTable::InitData(ScDocument *pDoc)
aHeightHelper.setDocument(pDoc, false);
}
void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& rViewData) const
void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& rViewData, SCTAB nTab) const
{
rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
beans::PropertyValue* pSettings = rSettings.getArray();
ScSplitMode eExHSplitMode = eHSplitMode;
ScSplitMode eExVSplitMode = eVSplitMode;
SCCOL nExFixPosX = nFixPosX;
SCROW nExFixPosY = nFixPosY;
long nExHSplitPos = nHSplitPos;
long nExVSplitPos = nVSplitPos;
if (comphelper::LibreOfficeKit::isActive())
{
rViewData.OverrideWithLOKFreeze(eExHSplitMode, eExVSplitMode,
nExFixPosX, nExFixPosY,
nExHSplitPos, nExVSplitPos, nTab);
}
pSettings[SC_CURSOR_X].Name = SC_CURSORPOSITIONX;
pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
pSettings[SC_CURSOR_Y].Name = SC_CURSORPOSITIONY;
pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
pSettings[SC_HORIZONTAL_SPLIT_MODE].Name = SC_HORIZONTALSPLITMODE;
pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eHSplitMode);
pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eExHSplitMode);
pSettings[SC_VERTICAL_SPLIT_MODE].Name = SC_VERTICALSPLITMODE;
pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eVSplitMode);
pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eExVSplitMode);
pSettings[SC_HORIZONTAL_SPLIT_POSITION].Name = SC_HORIZONTALSPLITPOSITION;
if (eHSplitMode == SC_SPLIT_FIX)
pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosX);
if (eExHSplitMode == SC_SPLIT_FIX)
pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nExFixPosX);
else
pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nHSplitPos);
pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nExHSplitPos);
pSettings[SC_VERTICAL_SPLIT_POSITION].Name = SC_VERTICALSPLITPOSITION;
if (eVSplitMode == SC_SPLIT_FIX)
pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosY);
if (eExVSplitMode == SC_SPLIT_FIX)
pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nExFixPosY);
else
pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nVSplitPos);
pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nExVSplitPos);
// Prevent writing odd settings that would make crash versions that
// don't apply SanitizeWhichActive() when reading the settings.
// See tdf#117093
@@ -1327,14 +1341,32 @@ void ScViewData::ResetOldCursor()
pThisTab->mbOldCursorValid = false;
}
SCCOL ScViewData::GetPosX( ScHSplitPos eWhich ) const
SCCOL ScViewData::GetPosX( ScHSplitPos eWhich, SCTAB nForTab ) const
{
return comphelper::LibreOfficeKit::isActive() ? 0 : pThisTab->nPosX[eWhich];
if (comphelper::LibreOfficeKit::isActive())
return 0;
if (nForTab == -1)
return pThisTab->nPosX[eWhich];
if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
return -1;
return maTabData[nForTab]->nPosX[eWhich];
}
SCROW ScViewData::GetPosY( ScVSplitPos eWhich ) const
SCROW ScViewData::GetPosY( ScVSplitPos eWhich, SCTAB nForTab ) const
{
return comphelper::LibreOfficeKit::isActive() ? 0 : pThisTab->nPosY[eWhich];
if (comphelper::LibreOfficeKit::isActive())
return 0;
if (nForTab == -1)
return pThisTab->nPosY[eWhich];
if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
return -1;
return maTabData[nForTab]->nPosY[eWhich];
}
SCCOL ScViewData::GetCurXForTab( SCTAB nTabIndex ) const
@@ -2285,7 +2317,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich )
}
Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
bool bAllowNeg ) const
bool bAllowNeg, SCTAB nForTab ) const
{
ScHSplitPos eWhichX = SC_SPLIT_LEFT;
ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
@@ -2309,6 +2341,18 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
break;
}
if (nForTab == -1)
nForTab = nTabNo;
bool bForCurTab = (nForTab == nTabNo);
if (!bForCurTab && (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size()))))
{
SAL_WARN("sc.viewdata", "ScViewData::GetScrPos : invalid nForTab = " << nForTab);
nForTab = nTabNo;
bForCurTab = true;
}
ScViewDataTable* pViewTable = bForCurTab ? pThisTab : maTabData[nForTab].get();
if (pView)
{
const_cast<ScViewData*>(this)->aScrSize.setWidth( pView->GetGridWidth(eWhichX) );
@@ -2319,7 +2363,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
SCCOL nPosX = GetPosX(eWhichX);
SCCOL nPosX = GetPosX(eWhichX, nForTab);
long nScrPosX = 0;
if (bAllowNeg || nWhereX >= nPosX)
@@ -2328,7 +2372,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
if (bIsTiledRendering)
{
OSL_ENSURE(nPosX == 0, "Unsupported case.");
const auto& rNearest = pThisTab->aWidthHelper.getNearestByIndex(nWhereX - 1);
const auto& rNearest = pViewTable->aWidthHelper.getNearestByIndex(nWhereX - 1);
nStartPosX = rNearest.first + 1;
nScrPosX = rNearest.second;
}
@@ -2341,7 +2385,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
nScrPosX = 0x7FFFFFFF;
else
{
nTSize = pDoc->GetColWidth( nX, nTabNo );
nTSize = pDoc->GetColWidth( nX, nForTab );
if (nTSize)
{
long nSizeXPix = ToPixel( nTSize, nPPTX );
@@ -2355,7 +2399,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
for (SCCOL nX = nStartPosX; nX > nWhereX;)
{
--nX;
nTSize = pDoc->GetColWidth( nX, nTabNo );
nTSize = pDoc->GetColWidth( nX, nForTab );
if (nTSize)
{
long nSizeXPix = ToPixel( nTSize, nPPTX );
@@ -2367,7 +2411,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
}
SCROW nPosY = GetPosY(eWhichY);
SCROW nPosY = GetPosY(eWhichY, nForTab);
long nScrPosY = 0;
if (bAllowNeg || nWhereY >= nPosY)
@@ -2376,7 +2420,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
if (bIsTiledRendering)
{
OSL_ENSURE(nPosY == 0, "Unsupported case.");
const auto& rNearest = pThisTab->aHeightHelper.getNearestByIndex(nWhereY - 1);
const auto& rNearest = pViewTable->aHeightHelper.getNearestByIndex(nWhereY - 1);
nStartPosY = rNearest.first + 1;
nScrPosY = rNearest.second;
}
@@ -2389,13 +2433,13 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
nScrPosY = 0x7FFFFFFF;
else if (bAllowNeg || bIsTiledRendering)
{
sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nTabNo, nPPTY );
sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nForTab, nPPTY );
nScrPosY += nSizeYPix;
}
else
{
sal_uLong nMaxHeight = aScrSize.getHeight() - nScrPosY;
sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nTabNo, nPPTY, &nMaxHeight );
sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nForTab, nPPTY, &nMaxHeight );
nScrPosY += nSizeYPix;
}
}
@@ -2405,7 +2449,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
for (SCROW nY = nStartPosY; nY > nWhereY;)
{
--nY;
nTSize = pDoc->GetRowHeight( nY, nTabNo );
nTSize = pDoc->GetRowHeight( nY, nForTab );
if (nTSize)
{
long nSizeYPix = ToPixel( nTSize, nPPTY );
@@ -2415,7 +2459,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
}
}
if ( pDoc->IsLayoutRTL( nTabNo ) )
if ( pDoc->IsLayoutRTL( nForTab ) )
{
// mirror horizontal position
nScrPosX = aScrSize.Width() - 1 - nScrPosX;
@@ -2655,14 +2699,24 @@ bool ScViewData::GetMergeSizePrintTwips(SCCOL nX, SCROW nY, long& rSizeXTwips, l
void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
SCCOL& rPosX, SCROW& rPosY,
bool bTestMerge, bool bRepair )
bool bTestMerge, bool bRepair, SCTAB nForTab )
{
// special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
if (nForTab == -1)
nForTab = nTabNo;
bool bForCurTab = (nForTab == nTabNo);
if (!bForCurTab && (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size()))))
{
SAL_WARN("sc.viewdata", "ScViewData::GetPosFromPixel : invalid nForTab = " << nForTab);
nForTab = nTabNo;
bForCurTab = true;
}
ScHSplitPos eHWhich = WhichH(eWhich);
ScVSplitPos eVWhich = WhichV(eWhich);
if ( pDoc->IsLayoutRTL( nTabNo ) )
if ( pDoc->IsLayoutRTL( nForTab ) )
{
// mirror horizontal position
if (pView)
@@ -2670,8 +2724,8 @@ void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
nClickX = aScrSize.Width() - 1 - nClickX;
}
SCCOL nStartPosX = GetPosX(eHWhich);
SCROW nStartPosY = GetPosY(eVWhich);
SCCOL nStartPosX = GetPosX(eHWhich, nForTab);
SCROW nStartPosY = GetPosY(eVWhich, nForTab);
rPosX = nStartPosX;
rPosY = nStartPosY;
long nScrX = 0;
@@ -2681,7 +2735,7 @@ void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
{
while ( rPosX<=pDoc->MaxCol() && nClickX >= nScrX )
{
nScrX += ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
nScrX += ToPixel( pDoc->GetColWidth( rPosX, nForTab ), nPPTX );
++rPosX;
}
--rPosX;
@@ -2691,19 +2745,19 @@ void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
while ( rPosX>0 && nClickX < nScrX )
{
--rPosX;
nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nForTab ), nPPTX );
}
}
if (nClickY > 0)
AddPixelsWhile( nScrY, nClickY, rPosY, pDoc->MaxRow(), nPPTY, pDoc, nTabNo );
AddPixelsWhile( nScrY, nClickY, rPosY, pDoc->MaxRow(), nPPTY, pDoc, nForTab );
else
{
/* TODO: could need some "SubPixelsWhileBackward" method */
while ( rPosY>0 && nClickY < nScrY )
{
--rPosY;
nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nForTab ), nPPTY );
}
}
@@ -2728,7 +2782,7 @@ void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
if (rPosY<0) rPosY=0;
if (rPosY>pDoc->MaxRow()) rPosY=pDoc->MaxRow();
if (bTestMerge)
if (bTestMerge && bForCurTab)
{
// public method to adapt position
SCCOL nOrigX = rPosX;
@@ -3285,6 +3339,8 @@ void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
if( rDocSett.mfTabBarWidth < 0.0 )
rDocSett.mfTabBarWidth = ScTabView::GetRelTabBarWidth();
bool bLOKActive = comphelper::LibreOfficeKit::isActive();
// sheet settings
for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab )
{
@@ -3293,12 +3349,24 @@ void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
// split mode
ScSplitMode eHSplit = pViewTab->eHSplitMode;
ScSplitMode eVSplit = pViewTab->eVSplitMode;
bool bHSplit = eHSplit != SC_SPLIT_NONE;
bool bVSplit = eVSplit != SC_SPLIT_NONE;
bool bRealSplit = (eHSplit == SC_SPLIT_NORMAL) || (eVSplit == SC_SPLIT_NORMAL);
bool bFrozen = (eHSplit == SC_SPLIT_FIX) || (eVSplit == SC_SPLIT_FIX);
ScSplitMode eExHSplit = pViewTab->eHSplitMode;
ScSplitMode eExVSplit = pViewTab->eVSplitMode;
SCCOL nExFixPosX = pViewTab->nFixPosX;
SCROW nExFixPosY = pViewTab->nFixPosY;
long nExHSplitPos = pViewTab->nHSplitPos;
long nExVSplitPos = pViewTab->nVSplitPos;
if (bLOKActive)
{
OverrideWithLOKFreeze(eExHSplit, eExVSplit,
nExFixPosX, nExFixPosY,
nExHSplitPos, nExVSplitPos, nTab);
}
bool bHSplit = eExHSplit != SC_SPLIT_NONE;
bool bVSplit = eExVSplit != SC_SPLIT_NONE;
bool bRealSplit = (eExHSplit == SC_SPLIT_NORMAL) || (eExVSplit == SC_SPLIT_NORMAL);
bool bFrozen = (eExHSplit == SC_SPLIT_FIX) || (eExVSplit == SC_SPLIT_FIX);
OSL_ENSURE( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
@@ -3308,15 +3376,15 @@ void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
if( bRealSplit )
{
Point& rSplitPos = rTabSett.maSplitPos;
rSplitPos = Point( bHSplit ? pViewTab->nHSplitPos : 0, bVSplit ? pViewTab->nVSplitPos : 0 );
rSplitPos = Point( bHSplit ? nExHSplitPos : 0, bVSplit ? nExVSplitPos : 0 );
rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MapUnit::MapTwip ) );
if( pDocShell )
rSplitPos.setX( static_cast<long>(static_cast<double>(rSplitPos.X()) / pDocShell->GetOutputFactor()) );
}
else if( bFrozen )
{
if( bHSplit ) rTabSett.maFreezePos.SetCol( pViewTab->nFixPosX );
if( bVSplit ) rTabSett.maFreezePos.SetRow( pViewTab->nFixPosY );
if( bHSplit ) rTabSett.maFreezePos.SetCol( nExFixPosX );
if( bVSplit ) rTabSett.maFreezePos.SetRow( nExFixPosY );
}
// first visible cell in top-left and additional panes
@@ -3535,6 +3603,9 @@ void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt )
}
}
if (comphelper::LibreOfficeKit::isActive())
DeriveLOKFreezeAllSheets();
// RecalcPixPos or so - also nMPos - also for ReadUserData ??!?!
}
@@ -3555,7 +3626,7 @@ void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSe
if (maTabData[nTab])
{
uno::Sequence <beans::PropertyValue> aTableViewSettings;
maTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this);
maTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
OUString sTabName;
GetDocument()->GetName( nTab, sTabName );
try
@@ -3807,6 +3878,9 @@ void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>
// #i47426# write view options to document, needed e.g. for Excel export
pDoc->SetViewOptions( *pOptions );
if (comphelper::LibreOfficeKit::isActive())
DeriveLOKFreezeAllSheets();
}
void ScViewData::SetOptions( const ScViewOptions& rOpt )
@@ -4038,4 +4112,133 @@ void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
rPosY = nRow;
}
SCCOLROW ScViewData::GetLOKSheetFreezeIndex(bool bIsCol) const
{
SCCOLROW nFreezeIndex = bIsCol ? pDoc->GetLOKFreezeCol(nTabNo) : pDoc->GetLOKFreezeRow(nTabNo);
return nFreezeIndex >= 0 ? nFreezeIndex : 0;
}
bool ScViewData::SetLOKSheetFreezeIndex(const SCCOLROW nFreezeIndex, bool bIsCol, SCTAB nForTab)
{
if (nForTab == -1)
{
nForTab = nTabNo;
}
else if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
{
SAL_WARN("sc.viewdata", "ScViewData::SetLOKSheetFreezeIndex : invalid nForTab = " << nForTab);
return false;
}
return bIsCol ?
pDoc->SetLOKFreezeCol(static_cast<SCCOL>(nFreezeIndex), nForTab) :
pDoc->SetLOKFreezeRow(static_cast<SCROW>(nFreezeIndex), nForTab);
}
void ScViewData::DeriveLOKFreezeAllSheets()
{
SCTAB nMaxTab = static_cast<SCTAB>(maTabData.size()) - 1;
for (SCTAB nTab = 0; nTab <= nMaxTab; ++nTab)
DeriveLOKFreezeIfNeeded(nTab);
}
void ScViewData::DeriveLOKFreezeIfNeeded(SCTAB nForTab)
{
if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
{
SAL_WARN("sc.viewdata", "ScViewData::DeriveLOKFreezeIfNeeded : invalid nForTab = " << nForTab);
return;
}
ScViewDataTable* pViewTable = maTabData[nForTab].get();
assert(pViewTable);
bool bConvertToFreezeX = false;
bool bConvertToFreezeY = false;
SCCOL nFreezeCol = pDoc->GetLOKFreezeCol(nForTab);
SCROW nFreezeRow = pDoc->GetLOKFreezeRow(nForTab);
if (nFreezeCol == -1)
{
ScSplitMode eSplitMode = pViewTable->eHSplitMode;
if (eSplitMode == SC_SPLIT_FIX)
nFreezeCol = pViewTable->nFixPosX;
else if (eSplitMode == SC_SPLIT_NORMAL)
bConvertToFreezeX = true;
else
nFreezeCol = 0;
}
if (nFreezeRow == -1)
{
ScSplitMode eSplitMode = pViewTable->eVSplitMode;
if (eSplitMode == SC_SPLIT_FIX)
nFreezeRow = pViewTable->nFixPosY;
else if (eSplitMode == SC_SPLIT_NORMAL)
bConvertToFreezeY = true;
else
nFreezeRow = 0;
}
if (bConvertToFreezeX || bConvertToFreezeY)
{
SCCOL nCol;
SCROW nRow;
GetPosFromPixel(bConvertToFreezeX ? pViewTable->nHSplitPos : 0,
bConvertToFreezeY ? pViewTable->nVSplitPos : 0,
SC_SPLIT_BOTTOMLEFT, nCol, nRow,
false /* bTestMerge */, false /* bRepair */,
nForTab);
if (bConvertToFreezeX)
nFreezeCol = nCol;
if (bConvertToFreezeY)
nFreezeRow = nRow;
}
pDoc->SetLOKFreezeCol(nFreezeCol, nForTab);
pDoc->SetLOKFreezeRow(nFreezeRow, nForTab);
}
void ScViewData::OverrideWithLOKFreeze(ScSplitMode& eExHSplitMode, ScSplitMode& eExVSplitMode,
SCCOL& nExFixPosX, SCROW& nExFixPosY,
long& nExHSplitPos, long& nExVSplitPos, SCTAB nForTab) const
{
SCCOL nFreezeCol = pDoc->GetLOKFreezeCol(nForTab);
SCROW nFreezeRow = pDoc->GetLOKFreezeRow(nForTab);
bool bConvertToScrPosX = false;
bool bConvertToScrPosY = false;
if (nFreezeCol >= 0)
{
if (eExHSplitMode == SC_SPLIT_NONE)
eExHSplitMode = SC_SPLIT_FIX;
if (eExHSplitMode == SC_SPLIT_FIX)
nExFixPosX = nFreezeCol;
else
bConvertToScrPosX = true;
}
if (nFreezeRow >= 0)
{
if (eExVSplitMode == SC_SPLIT_NONE)
eExVSplitMode = SC_SPLIT_FIX;
if (eExVSplitMode == SC_SPLIT_FIX)
nExFixPosY = nFreezeRow;
else
bConvertToScrPosY = true;
}
if (bConvertToScrPosX || bConvertToScrPosY)
{
Point aExSplitPos = GetScrPos(nFreezeCol, nFreezeRow, SC_SPLIT_BOTTOMLEFT, true, nForTab);
if (bConvertToScrPosX)
nExHSplitPos = aExSplitPos.X();
if (bConvertToScrPosY)
nExVSplitPos = aExSplitPos.Y();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+2 -2
View File
@@ -168,8 +168,8 @@
<menu:menuitem menu:id=".uno:FreezePanes"/>
<menu:menu menu:id=".uno:FreezeCellsMenu">
<menu:menupopup>
<menu:menuitem menu:id=".uno:FreezePanesFirstColumn"/>
<menu:menuitem menu:id=".uno:FreezePanesFirstRow"/>
<menu:menuitem menu:id=".uno:FreezePanesColumn"/>
<menu:menuitem menu:id=".uno:FreezePanesRow"/>
</menu:menupopup>
</menu:menu>
<menu:menuseparator/>
@@ -28,5 +28,5 @@
<menu:menuitem menu:id=".uno:FillSeries"/>
<menu:menuitem menu:id=".uno:RandomNumberGeneratorDialog"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:FreezePanesFirstColumn"/>
<menu:menuitem menu:id=".uno:FreezePanesColumn"/>
</menu:menupopup>
+2 -2
View File
@@ -8,6 +8,6 @@
*
-->
<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
<menu:menuitem menu:id=".uno:FreezePanesFirstColumn"/>
<menu:menuitem menu:id=".uno:FreezePanesFirstRow"/>
<menu:menuitem menu:id=".uno:FreezePanesColumn"/>
<menu:menuitem menu:id=".uno:FreezePanesRow"/>
</menu:menupopup>
@@ -28,5 +28,5 @@
<menu:menuitem menu:id=".uno:FillSeries"/>
<menu:menuitem menu:id=".uno:RandomNumberGeneratorDialog"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:FreezePanesFirstRow"/>
<menu:menuitem menu:id=".uno:FreezePanesRow"/>
</menu:menupopup>
+4 -4
View File
@@ -10002,10 +10002,10 @@
<property name="toolbar_style">icons</property>
<property name="show_arrow">False</property>
<child>
<object class="GtkToolButton" id="View-FreezePanesFirstColumn">
<object class="GtkToolButton" id="View-FreezePanesColumn">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">.uno:FreezePanesFirstColumn</property>
<property name="action_name">.uno:FreezePanesColumn</property>
</object>
<packing>
<property name="expand">True</property>
@@ -10028,10 +10028,10 @@
<property name="toolbar_style">both-horiz</property>
<property name="show_arrow">False</property>
<child>
<object class="GtkToolButton" id="View-FreezePanesFirstRow">
<object class="GtkToolButton" id="View-FreezePanesRow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">.uno:FreezePanesFirstRow</property>
<property name="action_name">.uno:FreezePanesRow</property>
</object>
<packing>
<property name="expand">True</property>
+3 -1
View File
@@ -1144,7 +1144,9 @@ static void InterceptLOKStateChangeEvent(sal_uInt16 nSID, SfxViewFrame* pViewFra
aEvent.FeatureURL.Path == "StatusSelectionMode" ||
aEvent.FeatureURL.Path == "Signature" ||
aEvent.FeatureURL.Path == "SelectionMode" ||
aEvent.FeatureURL.Path == "StatusBarFunc")
aEvent.FeatureURL.Path == "StatusBarFunc" ||
aEvent.FeatureURL.Path == "FreezePanesColumn" ||
aEvent.FeatureURL.Path == "FreezePanesRow")
{
sal_Int32 aInt32;