diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2020-02-12 15:01:19 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2020-05-10 07:38:09 +0200 |
commit | 300bded85303b1821226329d6b985c197e55c68f (patch) | |
tree | 0cfec4211581eee8f88f583f2007aba4983fc97e | |
parent | 247f92b02072d6ded919b844b5064f43118bc0ab (diff) |
lok: formula bar: send whole function list
Change-Id: Ibbd142652f3190387700f820e56c494b61bfa658
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93341
Tested-by: Jenkins
Reviewed-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r-- | sc/source/ui/app/inputhdl.cxx | 77 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh3.cxx | 121 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwshc.cxx | 7 |
3 files changed, 187 insertions, 18 deletions
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index e0073b6e5a80..d3f8aa8ec392 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -1314,6 +1314,10 @@ void ScInputHandler::ShowFuncList( const ::std::vector< OUString > & rFuncStrVec { if (rFuncStrVec.size()) { + auto aPos = pFormulaData->begin(); + sal_uInt32 nCurIndex = std::distance(aPos, miAutoPosFormula); + const sal_uInt32 nSize = pFormulaData->size(); + OUString aFuncNameStr; OUString aDescFuncNameStr; OStringBuffer aPayload; @@ -1340,6 +1344,9 @@ void ScInputHandler::ShowFuncList( const ::std::vector< OUString > & rFuncStrVec if ( !ppFDesc->getFunctionName().isEmpty() ) { aPayload.append("{"); + aPayload.append("\"index\": "); + aPayload.append(OString::number(nCurIndex)); + aPayload.append(", "); aPayload.append("\"signature\": \""); aPayload.append(escapeJSON(ppFDesc->getSignature())); aPayload.append("\", "); @@ -1348,6 +1355,9 @@ void ScInputHandler::ShowFuncList( const ::std::vector< OUString > & rFuncStrVec aPayload.append("\"}, "); } } + ++nCurIndex; + if (nCurIndex == nSize) + nCurIndex = 0; } sal_Int32 nLen = aPayload.getLength(); aPayload[nLen - 2] = ' '; @@ -1510,6 +1520,34 @@ void completeFunction( EditView* pView, const OUString& rInsert, bool& rParInser { ESelection aSel = pView->GetSelection(); + bool bNoInitialLetter = false; + OUString aOld = pView->GetEditEngine()->GetText(0); + // in case we want just insert a function and not completing + if ( comphelper::LibreOfficeKit::isActive() ) + { + ESelection aSelRange = aSel; + --aSelRange.nStartPos; + --aSelRange.nEndPos; + pView->SetSelection(aSelRange); + pView->SelectCurrentWord(); + + if ( aOld == "=" ) + { + bNoInitialLetter = true; + aSelRange.nStartPos = 1; + aSelRange.nEndPos = 1; + pView->SetSelection(aSelRange); + } + else if ( pView->GetSelected().startsWith("()") ) + { + bNoInitialLetter = true; + ++aSelRange.nStartPos; + ++aSelRange.nEndPos; + pView->SetSelection(aSelRange); + } + } + + if(!bNoInitialLetter) { const sal_Int32 nMinLen = std::max(aSel.nEndPos - aSel.nStartPos, sal_Int32(1)); // Since transliteration service is used to test for match, the replaced string could be @@ -1543,7 +1581,6 @@ void completeFunction( EditView* pView, const OUString& rInsert, bool& rParInser // Do not insert parentheses after function names if there already are some // (e.g. if the function name was edited). ESelection aWordSel = pView->GetSelection(); - OUString aOld = pView->GetEditEngine()->GetText(0); // aWordSel.EndPos points one behind string if word at end if (aWordSel.nEndPos < aOld.getLength()) @@ -1602,16 +1639,34 @@ void ScInputHandler::PasteFunctionData() void ScInputHandler::LOKPasteFunctionData( sal_uInt32 nIndex ) { - if (pFormulaData && miAutoPosFormula != pFormulaData->end() && nIndex < pFormulaData->size()) - { - auto aPos = pFormulaData->begin(); - sal_uInt32 nCurIndex = std::distance(aPos, miAutoPosFormula); - nIndex += nCurIndex; - if (nIndex >= pFormulaData->size()) - nIndex -= pFormulaData->size(); - std::advance(aPos, nIndex); - miAutoPosFormula = aPos; - PasteFunctionData(); + if (pActiveViewSh && (pTopView || pTableView)) + { + bool bEdit = false; + OUString aFormula; + EditView* pEditView = pTopView ? pTopView : pTableView; + const EditEngine* pEditEngine = pEditView->GetEditEngine(); + if (pEditEngine) + { + aFormula = pEditEngine->GetText(0); + bEdit = aFormula.getLength() > 1 && (aFormula[0] == '=' || aFormula[0] == '+' || aFormula[0] == '-'); + } + + if ( !bEdit ) + { + OUString aNewFormula('='); + if ( aFormula.startsWith("=") ) + aNewFormula = aFormula; + + InputReplaceSelection( aNewFormula ); + } + + if (pFormulaData && nIndex < pFormulaData->size()) + { + auto aPos = pFormulaData->begin(); + std::advance(aPos, nIndex); + miAutoPosFormula = aPos; + PasteFunctionData(); + } } } diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx index 002261f57d61..9158748a9c98 100644 --- a/sc/source/ui/view/cellsh3.cxx +++ b/sc/source/ui/view/cellsh3.cxx @@ -20,6 +20,7 @@ #include <scitems.hxx> #include <editeng/editview.hxx> #include <editeng/editeng.hxx> +#include <formula/formulahelper.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> @@ -40,6 +41,7 @@ #include <cellsh.hxx> #include <inputhdl.hxx> #include <editable.hxx> +#include <funcdesc.hxx> #include <markdata.hxx> #include <scabstdlg.hxx> #include <columnspanset.hxx> @@ -54,6 +56,103 @@ using sc::HMMToTwips; using sc::TwipsToEvenHMM; +namespace +{ +/// Rid ourselves of unwanted " quoted json characters. +OString escapeJSON(const OUString &aStr) +{ + OUString aEscaped = aStr; + aEscaped = aEscaped.replaceAll("\n", " "); + aEscaped = aEscaped.replaceAll("\"", "'"); + return OUStringToOString(aEscaped, RTL_TEXTENCODING_UTF8); +} + +void lcl_lokGetWholeFunctionList() +{ + const SfxViewShell* pViewShell = SfxViewShell::Current(); + if (comphelper::LibreOfficeKit::isActive() + && pViewShell && pViewShell->isLOKMobilePhone()) + { + const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); + sal_uInt32 nListCount = pFuncList->GetCount(); + std::set<OUString> aFuncNameOrderedSet; + for(sal_uInt32 i = 0; i < nListCount; ++i) + { + const ScFuncDesc* pDesc = pFuncList->GetFunction( i ); + if ( pDesc->mxFuncName ) + { + aFuncNameOrderedSet.insert(*pDesc->mxFuncName); + } + } + ScFunctionMgr* pFuncManager = ScGlobal::GetStarCalcFunctionMgr(); + if (pFuncManager && aFuncNameOrderedSet.size()) + { + OStringBuffer aPayload; + aPayload.append("{ \"wholeList\": true, "); + aPayload.append("\"categories\": [ "); + + formula::FormulaHelper aHelper(pFuncManager); + sal_uInt32 nCategoryCount = pFuncManager->getCount(); + for (sal_uInt32 i = 0; i < nCategoryCount; ++i) + { + OUString sCategoryName = ScFunctionMgr::GetCategoryName(i); + aPayload.append("{"); + aPayload.append("\"name\": \""); + aPayload.append(escapeJSON(sCategoryName)); + aPayload.append("\"}, "); + } + sal_Int32 nLen = aPayload.getLength(); + aPayload[nLen - 2] = ' '; + aPayload[nLen - 1] = ']'; + aPayload.append(", "); + + OUString aDescFuncNameStr; + aPayload.append("\"functions\": [ "); + sal_uInt32 nCurIndex = 0; + for (const OUString& aFuncNameStr : aFuncNameOrderedSet) + { + aDescFuncNameStr = aFuncNameStr + "()"; + sal_Int32 nNextFStart = 0; + const formula::IFunctionDescription* ppFDesc; + ::std::vector< OUString > aArgs; + OUString eqPlusFuncName = "=" + aDescFuncNameStr; + if ( aHelper.GetNextFunc( eqPlusFuncName, false, nNextFStart, nullptr, &ppFDesc, &aArgs ) ) + { + if ( ppFDesc && !ppFDesc->getFunctionName().isEmpty() ) + { + if (ppFDesc->getCategory()) + { + aPayload.append("{"); + aPayload.append("\"index\": "); + aPayload.append(OString::number(nCurIndex)); + aPayload.append(", "); + aPayload.append("\"category\": "); + aPayload.append(OString::number(ppFDesc->getCategory()->getNumber())); + aPayload.append(", "); + aPayload.append("\"signature\": \""); + aPayload.append(escapeJSON(ppFDesc->getSignature())); + aPayload.append("\", "); + aPayload.append("\"description\": \""); + aPayload.append(escapeJSON(ppFDesc->getDescription())); + aPayload.append("\"}, "); + } + } + } + ++nCurIndex; + } + nLen = aPayload.getLength(); + aPayload[nLen - 2] = ' '; + aPayload[nLen - 1] = ']'; + aPayload.append(" }"); + + OString s = aPayload.makeStringAndClear(); + pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CALC_FUNCTION_LIST, s.getStr()); + } + } +} + +} // end namespace + void ScCellShell::Execute( SfxRequest& rReq ) { ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); @@ -314,11 +413,23 @@ void ScCellShell::Execute( SfxRequest& rReq ) case SID_OPENDLG_FUNCTION: { - sal_uInt16 nId = SID_OPENDLG_FUNCTION; - SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame(); - SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId ); - bool bVis = comphelper::LibreOfficeKit::isActive() || pWnd == nullptr; - pScMod->SetRefDialog( nId, bVis ); + const SfxViewShell* pViewShell = SfxViewShell::Current(); + if (comphelper::LibreOfficeKit::isActive() + && pViewShell && pViewShell->isLOKMobilePhone()) + { + // not set the dialog id in the mobile case or we would + // not be able to get cell address pasted in the edit view + // by just tapping on them + lcl_lokGetWholeFunctionList(); + } + else + { + sal_uInt16 nId = SID_OPENDLG_FUNCTION; + SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame(); + SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId ); + bool bVis = comphelper::LibreOfficeKit::isActive() || pWnd == nullptr; + pScMod->SetRefDialog( nId, bVis ); + } rReq.Ignore(); } break; diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index 918437db53cc..afb406b4863a 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -394,8 +394,11 @@ std::shared_ptr<SfxModelessDialogController> ScTabViewShell::CreateRefDialogCont } case SID_OPENDLG_FUNCTION: { - // dialog checks, what is in the cell - xResult = std::make_shared<ScFormulaDlg>(pB, pCW, pParent, &GetViewData(),ScGlobal::GetStarCalcFunctionMgr()); + if (!isLOKMobilePhone()) + { + // dialog checks, what is in the cell + xResult = std::make_shared<ScFormulaDlg>(pB, pCW, pParent, &GetViewData(),ScGlobal::GetStarCalcFunctionMgr()); + } break; } case WID_CONDFRMT_REF: |