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
         {

Reply via email to