formula/source/core/api/token.cxx | 7 +++++++ include/formula/tokenarray.hxx | 1 + sc/source/ui/inc/viewfunc.hxx | 2 +- sc/source/ui/view/cellsh3.cxx | 9 ++++++--- sc/source/ui/view/viewfunc.cxx | 29 +++++++++++++++++++++++++++-- 5 files changed, 42 insertions(+), 6 deletions(-)
New commits: commit dad1d7182eda5f0e155964d32ac03e5cd854eb96 Author: Eike Rathke <er...@redhat.com> AuthorDate: Wed Jun 1 20:52:32 2022 +0200 Commit: Eike Rathke <er...@redhat.com> CommitDate: Thu Jun 2 00:33:15 2022 +0200 Resolves: tdf#149378 Force array input if outer function returns array/matrix So the result will actually display as full matrix, or in the cell range marked prior to input, instead of just the top left element in one cell, without having to close the input with Shift+Ctrl+Enter to force array mode. The previous behaviour can be forced by pre-selecting/marking one cell, which also worked previously when closing as array input. Change-Id: I81c079ce02e0c8d0536617ca6882fb470a352441 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135278 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index abda98f2f86d..87b0fb67ca98 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -512,6 +512,13 @@ FormulaToken* FormulaTokenArray::FirstRPNToken() const return pRPN[0]; } +FormulaToken* FormulaTokenArray::LastRPNToken() const +{ + if (!pRPN || nRPN == 0) + return nullptr; + return pRPN[nRPN - 1]; +} + bool FormulaTokenArray::HasReferences() const { for (auto i: Tokens()) diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx index 6b373ff44e15..cbff6a3e469d 100644 --- a/include/formula/tokenarray.hxx +++ b/include/formula/tokenarray.hxx @@ -337,6 +337,7 @@ public: } FormulaToken* FirstRPNToken() const; + FormulaToken* LastRPNToken() const; bool HasReferences() const; diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 8d012dd27050..0d8d7515441a 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -91,7 +91,7 @@ public: OUString GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr, const OpCode eCode ); void EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString, - const EditTextObject* pData = nullptr ); + const EditTextObject* pData = nullptr, bool bMatrixExpand = false ); void EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextObject& rData, bool bTestSimple = false ); void EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue ); diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx index 2734bc9b3027..a0d08a605058 100644 --- a/sc/source/ui/view/cellsh3.cxx +++ b/sc/source/ui/view/cellsh3.cxx @@ -289,7 +289,8 @@ void ScCellShell::Execute( SfxRequest& rReq ) pTabViewShell->EnterData( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo(), - aStr ); + aStr, nullptr, + true /*bMatrixExpand*/); } else if (pHdl) { @@ -357,7 +358,8 @@ void ScCellShell::Execute( SfxRequest& rReq ) } else if ( !aString.isEmpty() && ( aString[0] == '=' || aString[0] == '+' || aString[0] == '-' ) ) { - pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aString, pData ); + pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), + aString, pData, true /*bMatrixExpand*/); } else { @@ -386,7 +388,8 @@ void ScCellShell::Execute( SfxRequest& rReq ) pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), - aString ); + aString, nullptr, + true /*bMatrixExpand*/); rReq.Done(); } } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 7f69f8b27b66..cd886c976c88 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -39,6 +39,7 @@ #include <vcl/uitest/logger.hxx> #include <vcl/uitest/eventdescription.hxx> #include <osl/diagnose.h> +#include <formula/paramclass.hxx> #include <viewfunc.hxx> #include <tabvwsh.hxx> @@ -363,7 +364,8 @@ namespace // input - undo OK void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString, - const EditTextObject* pData ) + const EditTextObject* pData, + bool bMatrixExpand ) { ScDocument& rDoc = GetViewData().GetDocument(); ScMarkData rMark(GetViewData().GetMarkData()); @@ -520,6 +522,29 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, { pScMod->SetAppOptions(aAppOpt); } + + if (bMatrixExpand) + { + // If the outer function/operator returns an array/matrix then + // enter a matrix formula. ScViewFunc::EnterMatrix() takes care + // of selection/mark of the result dimensions or preselected + // mark. If the user wanted less or a single cell then should + // mark such prior to entering the formula. + const formula::FormulaToken* pToken = pArr->LastRPNToken(); + if (pToken && (formula::FormulaCompiler::IsMatrixFunction( pToken->GetOpCode()) + || pToken->IsInForceArray())) + { + // Discard this (still empty here) Undo action, + // EnterMatrix() will create its own. + if (bRecord) + rFunc.EndListAction(); + + // Use corrected formula string. + EnterMatrix( aFormula, rDoc.GetGrammar()); + + return; + } + } } ScFormulaCell aCell(rDoc, aPos, std::move( pArr ), formula::FormulaGrammar::GRAM_DEFAULT, ScMatrixMode::NONE); @@ -737,7 +762,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, if (bCommon) AdjustRowHeight(nRow,nRow,true); - EnterData(nCol,nRow,nTab,aString); + EnterData( nCol, nRow, nTab, aString, nullptr, true /*bMatrixExpand*/); } else {