bug tdf#120697

add drop down containing formulas in autosum button in calc

Change-Id: I1da8116ba2f6073bec153979282161fbaa286427
Reviewed-on: https://gerrit.libreoffice.org/70058
Tested-by: Jenkins
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index a80f9d2..a091655 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -88,6 +88,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
	sc/uiconfig/scalc/ui/allheaderfooterdialog \
	sc/uiconfig/scalc/ui/analysisofvariancedialog \
	sc/uiconfig/scalc/ui/autoformattable \
	sc/uiconfig/scalc/ui/autosum \
	sc/uiconfig/scalc/ui/cellprotectionpage \
	sc/uiconfig/scalc/ui/changesourcedialog \
	sc/uiconfig/scalc/ui/chardialog \
diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc
index 39873fc..dccedda 100644
--- a/sc/inc/strings.hrc
+++ b/sc/inc/strings.hrc
@@ -177,7 +177,7 @@
#define SCSTR_QHELP_BTNCALC                         NC_("SCSTR_QHELP_BTNCALC", "Function Wizard")
#define SCSTR_QHELP_BTNOK                           NC_("SCSTR_QHELP_BTNOK", "Accept")
#define SCSTR_QHELP_BTNCANCEL                       NC_("SCSTR_QHELP_BTNCANCEL", "Cancel")
#define SCSTR_QHELP_BTNSUM                          NC_("SCSTR_QHELP_BTNSUM", "Sum")
#define SCSTR_QHELP_BTNSUM                          NC_("SCSTR_QHELP_BTNSUM", "Autosum")
#define SCSTR_QHELP_BTNEQUAL                        NC_("SCSTR_QHELP_BTNEQUAL", "Formula")
#define SCSTR_QHELP_EXPAND_FORMULA                  NC_("SCSTR_QHELP_EXPAND_FORMULA", "Expand Formula Bar")
#define SCSTR_QHELP_COLLAPSE_FORMULA                NC_("SCSTR_QHELP_COLLAPSE_FORMULA", "Collapse Formula Bar")
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index e38febf..a54332c 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -62,6 +62,7 @@
#include <rangeutl.hxx>
#include <docfunc.hxx>
#include <funcdesc.hxx>
#include <formula/opcode.hxx>
#include <editeng/fontitem.hxx>
#include <AccessibleEditObject.hxx>
#include <AccessibleText.hxx>
@@ -183,12 +184,13 @@ ScInputWindow::ScInputWindow( vcl::Window* pParent, const SfxBindings* pBind ) :
    InsertWindow    (1, aWndPos.get(), ToolBoxItemBits::NONE, 0);
    InsertSeparator (1);
    InsertItem      (SID_INPUT_FUNCTION, Image(StockImage::Yes, RID_BMP_INPUT_FUNCTION), ToolBoxItemBits::NONE, 2);
    InsertItem      (SID_INPUT_SUM,      Image(StockImage::Yes, RID_BMP_INPUT_SUM), ToolBoxItemBits::NONE, 3);
    InsertItem      (SID_INPUT_SUM,      Image(StockImage::Yes, RID_BMP_INPUT_SUM), ToolBoxItemBits::DROPDOWNONLY, 3);
    InsertItem      (SID_INPUT_EQUAL,    Image(StockImage::Yes, RID_BMP_INPUT_EQUAL), ToolBoxItemBits::NONE, 4);
    InsertItem      (SID_INPUT_CANCEL,   Image(StockImage::Yes, RID_BMP_INPUT_CANCEL), ToolBoxItemBits::NONE, 5);
    InsertItem      (SID_INPUT_OK,       Image(StockImage::Yes, RID_BMP_INPUT_OK), ToolBoxItemBits::NONE, 6);
    InsertSeparator (7);
    InsertWindow    (7, &aTextWindow, ToolBoxItemBits::NONE, 8);
    SetDropdownClickHdl( LINK( this, ScInputWindow, DropdownClickHdl ));

    aWndPos   ->SetQuickHelpText(ScResId(SCSTR_QHELP_POSWND));
    aWndPos   ->SetHelpId       (HID_INSWIN_POS);
@@ -329,45 +331,6 @@ void ScInputWindow::Select()
            aTextWindow.Invalidate(); // Or else the Selection remains
            break;

        case SID_INPUT_SUM:
            {
                ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current()  );
                if ( pViewSh )
                {
                    bool bSubTotal = false;
                    bool bRangeFinder = false;
                    const OUString aFormula = pViewSh->DoAutoSum(bRangeFinder, bSubTotal);
                    if (!aFormula.isEmpty())
                    {
                        SetFuncString( aFormula );
                        if (bRangeFinder && pScMod->IsEditMode())
                        {
                            ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
                            if ( pHdl )
                            {
                                pHdl->InitRangeFinder( aFormula );

                                //! SetSelection at the InputHandler?
                                //! Set bSelIsRef?
                                const sal_Int32 nOpen = aFormula.indexOf('(');
                                const sal_Int32 nLen = aFormula.getLength();
                                if ( nOpen != -1 && nLen > nOpen )
                                {
                                    ESelection aSel( 0, nOpen + (bSubTotal ? 3 : 1), 0, nLen-1 );
                                    EditView* pTableView = pHdl->GetTableView();
                                    if ( pTableView )
                                        pTableView->SetSelection( aSel );
                                    EditView* pTopView = pHdl->GetTopView();
                                    if ( pTopView )
                                        pTopView->SetSelection( aSel );
                                }
                            }
                        }
                    }
                }
            }
            break;

        case SID_INPUT_EQUAL:
        {
            aTextWindow.StartEditEngine();
@@ -902,6 +865,85 @@ void ScInputBarGroup::DecrementVerticalSize()
    }
}

IMPL_LINK( ScInputWindow, MenuHdl, Menu *, pMenu, bool )
{
    OString aCommand = pMenu->GetCurItemIdent();
    if (!aCommand.isEmpty())
    {
        ScModule* pScMod = SC_MOD();
        ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current()  );
        if ( pViewSh )
        {
            bool bSubTotal = false;
            bool bRangeFinder = false;
            OpCode eCode = ocSum;
            if ( aCommand ==  "sum" )
            {
                eCode = ocSum;
            }
            else if ( aCommand == "average" )
            {
                eCode = ocAverage;
            }
            else if ( aCommand == "max" )
            {
                eCode = ocMax;
            }
            else if ( aCommand == "min" )
            {
                eCode = ocMin;
            }
            else if ( aCommand == "count" )
            {
                eCode = ocCount;
            }

            const OUString aFormula = pViewSh->DoAutoSum(bRangeFinder, bSubTotal, eCode);
            if ( !aFormula.isEmpty() )
            {
                SetFuncString( aFormula );
                const sal_Int32 aOpen = aFormula.indexOf('(');
                const sal_Int32 aLen  = aFormula.getLength();
                if (bRangeFinder && pScMod->IsEditMode())
                {
                    ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
                    if ( pHdl )
                    {
                        pHdl->InitRangeFinder( aFormula );

                        //! SetSelection at the InputHandler?
                        //! Set bSelIsRef?
                        if ( aOpen != -1 && aLen > aOpen )
                        {
                            ESelection aSel( 0, aOpen + (bSubTotal ? 3 : 1), 0, aLen-1 );
                            EditView* pTableView = pHdl->GetTableView();
                            if ( pTableView )
                                pTableView->SetSelection( aSel );
                            EditView* pTopView = pHdl->GetTopView();
                            if ( pTopView )
                                pTopView->SetSelection( aSel );
                        }
                    }
                }
            }
        }
    }
    return false;
}

IMPL_LINK_NOARG(ScInputWindow, DropdownClickHdl, ToolBox *, void)
{
    sal_uInt16 nCurID = GetCurItemId();
    EndSelection();
    if (nCurID == SID_INPUT_SUM)
    {
        VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/scalc/ui/autosum.ui", "");
        VclPtr<PopupMenu> aPopMenu(aBuilder.get_menu("menu"));
        aPopMenu->SetSelectHdl(LINK(this, ScInputWindow, MenuHdl));
        aPopMenu->Execute(this, GetItemRect(SID_INPUT_SUM), PopupMenuFlags::NoMouseUpClose);
    }
}

IMPL_LINK_NOARG(ScInputBarGroup, ClickHdl, Button*, void)
{
    vcl::Window* w = GetParent();
diff --git a/sc/source/ui/inc/inputwin.hxx b/sc/source/ui/inc/inputwin.hxx
index 01b9390..8f13b2c 100644
--- a/sc/source/ui/inc/inputwin.hxx
+++ b/sc/source/ui/inc/inputwin.hxx
@@ -30,6 +30,7 @@
#include <vcl/scrbar.hxx>
#include <vcl/window.hxx>
#include <vcl/transfer.hxx>
#include <vcl/menu.hxx>

class EditView;
class ScAccessibleEditLineTextData;
@@ -263,6 +264,9 @@ public:
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
    virtual void    MouseMove( const MouseEvent& rMEvt ) override;

    DECL_LINK( MenuHdl, Menu *, bool );
    DECL_LINK( DropdownClickHdl, ToolBox*, void );

private:
    bool IsPointerAtResizePos();

diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 266d816..a572751 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_SC_SOURCE_UI_INC_TABVWSH_HXX

#include <formula/errorcodes.hxx>
#include <formula/opcode.hxx>
#include <svx/fmshell.hxx>
#include <sfx2/viewsh.hxx>
#include <editeng/svxenum.hxx>
@@ -375,7 +376,7 @@ public:
    bool IsActive() const { return bIsActive; }
    OUString GetFormula(const ScAddress& rAddress);
    bool    UseSubTotal(ScRangeList* pRangeList);
    const   OUString DoAutoSum(bool& rRangeFinder, bool& rSubTotal);
    const   OUString DoAutoSum(bool& rRangeFinder, bool& rSubTotal, const OpCode eCode);

    // ugly hack to call Define Names from Manage Names
    void    SwitchBetweenRefDialogs(SfxModelessDialogController* pDialog);
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index 3d2627e..7719cdd 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -76,10 +76,10 @@ public:

    SvtScriptType   GetSelectionScriptType();

    bool            GetAutoSumArea(ScRangeList& rRangeList);
    void            EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr);
    bool            AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue );
    OUString        GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr );
    bool            GetAutoSumArea( ScRangeList& rRangeList );
    void            EnterAutoSum( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr, const OpCode eCode );
    bool            AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue, const OpCode eCode );
    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 );
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index fdeadf5..4f672a4 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -2647,7 +2647,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
            {
                bool bSubTotal = false;
                bool bRangeFinder = false;
                const OUString aFormula = pTabViewShell->DoAutoSum( bRangeFinder, bSubTotal );
                const OUString aFormula = pTabViewShell->DoAutoSum( bRangeFinder, bSubTotal , ocSum );
                if ( !aFormula.isEmpty() )
                {
                    const sal_Int32 nPar = aFormula.indexOf( '(' );
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 43b4289..5aecdbd 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -657,7 +657,7 @@ bool ScTabViewShell::UseSubTotal(ScRangeList* pRangeList)
    return bSubTotal;
}

const OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal)
const OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal, const OpCode eCode)
{
    OUString aFormula;
    const ScMarkData& rMark = GetViewData().GetMarkData();
@@ -692,7 +692,7 @@ const OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal)
                ScAddress aAddr = aRangeList.back().aEnd;
                aAddr.IncRow();
                const bool bSubTotal( UseSubTotal( &aRangeList ) );
                EnterAutoSum( aRangeList, bSubTotal, aAddr );
                EnterAutoSum( aRangeList, bSubTotal, aAddr, eCode );
            }
        }
        else
@@ -703,14 +703,14 @@ const OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal)
                const ScRange & rRange = aMarkRangeList[i];
                const bool bSetCursor = ( i == nCount - 1 );
                const bool bContinue = ( i != 0 );
                if ( !AutoSum( rRange, bSubTotal, bSetCursor, bContinue ) )
                if ( !AutoSum( rRange, bSubTotal, bSetCursor, bContinue, eCode ) )
                {
                    MarkRange( rRange, false );
                    SetCursor( rRange.aEnd.Col(), rRange.aEnd.Row() );
                    const ScRangeList aRangeList;
                    ScAddress aAddr = rRange.aEnd;
                    aAddr.IncRow();
                    aFormula = GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
                    aFormula = GetAutoSumFormula( aRangeList, bSubTotal, aAddr , eCode);
                    break;
                }
            }
@@ -722,7 +722,7 @@ const OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal)
        rRangeFinder = GetAutoSumArea( aRangeList );
        rSubTotal = UseSubTotal( &aRangeList );
        ScAddress aAddr = GetViewData().GetCurPos();
        aFormula = GetAutoSumFormula( aRangeList, rSubTotal, aAddr );
        aFormula = GetAutoSumFormula( aRangeList, rSubTotal, aAddr , eCode);
    }
    return aFormula;
}
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 623fe1b..96b5704 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -2,7 +2,7 @@
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * This Source eCode Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
@@ -226,7 +226,11 @@ enum ScAutoSum
{
    ScAutoSumNone = 0,
    ScAutoSumData,
    ScAutoSumSum
    ScAutoSumSum,
    ScAutoSumAverage,
    ScAutoSumMax,
    ScAutoSumMin,
    ScAutoSumCount
};

static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
@@ -237,12 +241,28 @@ static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
    {
        if (aCell.meType == CELLTYPE_FORMULA)
        {
            ScAutoSum val = ScAutoSumNone;
            ScTokenArray* pCode = aCell.mpFormula->GetCode();
            if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
            if ( pCode )
            {
                switch( pCode->GetOuterFuncOpCode() )
                {
                    case ocSum     : val = ScAutoSumSum;
                        break;
                    case ocAverage : val = ScAutoSumAverage;
                        break;
                    case ocMax     : val = ScAutoSumMax;
                        break;
                    case ocMin     : val = ScAutoSumMin;
                        break;
                    case ocCount   : val = ScAutoSumCount;
                        break;
                    default        :
                        break;
                }
                if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
                        ScAddress( nCol, nRow, nTab ), eDir ) )
                    return ScAutoSumSum;
                    return val;
            }
        }
        return ScAutoSumData;
@@ -293,7 +313,7 @@ static bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& n
    {
        --nRow;
    }
    return eSkip == ScAutoSumSum && nRow < nTmp;
    return eSkip >= ScAutoSumSum && nRow < nTmp;
}

static bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
@@ -306,7 +326,7 @@ static bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow
    {
        --nCol;
    }
    return eSkip == ScAutoSumSum && nCol < nTmp;
    return eSkip >= ScAutoSumSum && nCol < nTmp;
}

static ScAutoSum lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
@@ -325,7 +345,7 @@ static ScAutoSum lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rR
    SCCOLROW nExtend = 0;
    ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );

    if ( eSum == ScAutoSumSum )
    if ( eSum >= ScAutoSumSum )
    {
        bool bContinue = false;
        do
@@ -342,7 +362,7 @@ static ScAutoSum lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rR
    else
    {
        while ( nStartRow > aStart.Row() &&
                (eSum = lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumSum )
                (eSum = lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ )) < ScAutoSumSum )
        {
            --nStartRow;
        }
@@ -370,7 +390,7 @@ static ScAutoSum lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRang
    SCCOLROW nExtend = 0;
    ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );

    if ( eSum == ScAutoSumSum )
    if ( eSum >= ScAutoSumSum )
    {
        bool bContinue = false;
        do
@@ -387,7 +407,7 @@ static ScAutoSum lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRang
    else
    {
        while ( nStartCol > aStart.Col() &&
                (eSum = lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumSum )
                (eSum = lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) < ScAutoSumSum )
        {
            --nStartCol;
        }
@@ -399,6 +419,27 @@ static ScAutoSum lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRang
    return eSum;
}

static sal_Int8 GetSubTotal( const OpCode eCode )
{
    sal_Int8 val;
    switch ( eCode )
    {
        case ocSum     : val = 9;
            break;
        case ocAverage : val = 1;
            break;
        case ocMax     : val = 4;
            break;
        case ocMin     : val = 5;
            break;
        case ocCount   : val = 2;
            break;
        default        : val = 9;
    }

    return val;
}

bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
{
    ScDocument* pDoc = GetViewData().GetDocument();
@@ -445,7 +486,7 @@ bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
        if ( bRow )
        {
            nStartRow = nSeekRow;       // nSeekRow might be adjusted via reference
            if ( eSum == ScAutoSumSum )
            if ( eSum >= ScAutoSumSum  && eSum <= ScAutoSumCount )
                nEndRow = nStartRow;        // only sum sums
            else
                nEndRow = nRow - 1;     // maybe extend data area at bottom
@@ -453,7 +494,7 @@ bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
        else
        {
            nStartCol = nSeekCol;       // nSeekCol might be adjusted via reference
            if ( eSum == ScAutoSumSum )
            if ( eSum >= ScAutoSumSum )
                nEndCol = nStartCol;        // only sum sums
            else
                nEndCol = nCol - 1;     // maybe extend data area to the right
@@ -478,7 +519,7 @@ bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
            }
            rRangeList.push_back(
                ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
            if ( eSum == ScAutoSumSum )
            if ( eSum >= ScAutoSumSum )
            {
                if ( bRow )
                {
@@ -505,13 +546,13 @@ bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
    return false;
}

void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr, const OpCode eCode)
{
    OUString aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr );
    OUString aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr , eCode);
    EnterBlock( aFormula, nullptr );
}

bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue , const OpCode eCode)
{
    ScDocument* pDoc = GetViewData().GetDocument();
    const SCTAB nTab = rRange.aStart.Tab();
@@ -667,7 +708,7 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
                    if (++nRowSums == 1)
                        nRowSumsStartCol = aRangeList[0].aStart.Col();
                    const OUString aFormula = GetAutoSumFormula(
                        aRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab));
                        aRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab), eCode);
                    EnterData( nCol, nInsRow, nTab, aFormula );
                }
            }
@@ -703,7 +744,7 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
                {
                    if (++nColSums == 1)
                        nColSumsStartRow = aRangeList[0].aStart.Row();
                    const OUString aFormula = GetAutoSumFormula( aRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab) );
                    const OUString aFormula = GetAutoSumFormula( aRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab), eCode );
                    EnterData( nInsCol, nRow, nTab, aFormula );
                }
            }
@@ -715,10 +756,10 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
    // there is only one, or the data range if more than one. Otherwise use the
    // original selection. All extended by end column/row where the sum is put.
    const ScRange aMarkRange(
            (eSum == ScAutoSumSum ?
            (eSum >= ScAutoSumSum ?
             (nRowSums == 1 ? nRowSumsStartCol : nStartCol) :
             rRange.aStart.Col()),
            (eSum == ScAutoSumSum ?
            (eSum >= ScAutoSumSum ?
             (nColSums == 1 ? nColSumsStartRow : nStartRow) :
             rRange.aStart.Row()),
            nTab, nMarkEndCol, nMarkEndRow, nTab );
@@ -731,18 +772,18 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
    return true;
}

OUString ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr )
OUString ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr , const OpCode eCode)
{
    ScViewData& rViewData = GetViewData();
    ScDocument* pDoc = rViewData.GetDocument();
    std::unique_ptr<ScTokenArray> pArray(new ScTokenArray);

    pArray->AddOpCode(bSubTotal ? ocSubTotal : ocSum);
    pArray->AddOpCode(bSubTotal ? ocSubTotal : eCode);
    pArray->AddOpCode(ocOpen);

    if (bSubTotal)
    {
        pArray->AddDouble(9);
        pArray->AddDouble( GetSubTotal( eCode ) );
        pArray->AddOpCode(ocSep);
    }

diff --git a/sc/uiconfig/scalc/ui/autosum.ui b/sc/uiconfig/scalc/ui/autosum.ui
new file mode 100644
index 0000000..a9cbdbe
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/autosum.ui
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkMenu" id="menu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkMenuItem" id="sum">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="autosum|sum">Sum</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="average">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="autosum|average">Average</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="min">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="autosum|min">Min</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="max">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="autosum|max">Max</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="count">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="autosum|count">Count</property>
        <property name="use_underline">True</property>
      </object>
    </child>
  </object>
</interface>