[Libreoffice-commits] core.git: Branch 'feature/spellig_popup_SID' - 5 commits - include/sfx2 sfx2/source sw/source

Tamás Zolnai (via logerrit) logerrit at kemper.freedesktop.org
Mon Nov 18 17:56:06 UTC 2019


Rebased ref, commits from common ancestor:
commit 6f09a976422b28ef19f63afa7bb85ecc592f2f34
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Nov 18 14:36:51 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Nov 18 18:54:43 2019 +0100

    SpellingPopup: Replace the tunneled context menu.
    
    Send the menu structure instead using LOK_CALLBACK_CONTEXT_MENU.
    We need to set commands for menu items to make fillPopupMenu()
    method work.
    We also need to check whether there is any selection during execution
    of menu items. In case of LO core execution the suspicious text is
    selected, however in case of LO online, there is no selection.
    
    Change-Id: Id696ee9976d11f6b57e23a3bcc5b483a1d486639

diff --git a/sw/source/uibase/inc/olmenu.hxx b/sw/source/uibase/inc/olmenu.hxx
index 984dfb759872..4b67c9090bce 100644
--- a/sw/source/uibase/inc/olmenu.hxx
+++ b/sw/source/uibase/inc/olmenu.hxx
@@ -126,6 +126,8 @@ public:
 
     ~SwSpellPopup();
 
+    void InitItemCommands(const css::uno::Sequence< OUString >& aSuggestions);
+
     PopupMenu& GetMenu()
     {
         return *m_xPopupMenu.get();
@@ -133,7 +135,6 @@ public:
 
     void Execute( const tools::Rectangle& rPopupPos, vcl::Window* pWin );
     void Execute( sal_uInt16 nId );
-
 };
 
 #endif
diff --git a/sw/source/uibase/lingu/olmenu.cxx b/sw/source/uibase/lingu/olmenu.cxx
index 566fb9b933d6..e09589de550b 100644
--- a/sw/source/uibase/lingu/olmenu.cxx
+++ b/sw/source/uibase/lingu/olmenu.cxx
@@ -422,6 +422,8 @@ SwSpellPopup::SwSpellPopup(
 
     checkRedline();
     m_xPopupMenu->RemoveDisabledEntries( true, true );
+
+    InitItemCommands(aSuggestions);
 }
 
 SwSpellPopup::SwSpellPopup(
@@ -587,10 +589,69 @@ SwSpellPopup::SwSpellPopup(
     {
         m_xPopupMenu->HideItem(MN_EXPLANATION_LINK);
     }
+
+    InitItemCommands(rSuggestions);
 }
 
 SwSpellPopup::~SwSpellPopup() {}
 
+void SwSpellPopup::InitItemCommands(const css::uno::Sequence< OUString >& aSuggestions)
+{
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        m_xPopupMenu->SetItemCommand(MN_SHORT_COMMENT, ".uno:None");
+        m_xPopupMenu->SetItemCommand(m_nSpellDialogId, ".uno:SpellingAndGrammarDialog");
+        if(m_bGrammarResults)
+            m_xPopupMenu->SetItemCommand(m_nIgnoreWordId, ".uno:ApplySpellChecking?ApplyRule:string=IgnoreAll_Grammar");
+        else
+            m_xPopupMenu->SetItemCommand(m_nIgnoreWordId, ".uno:ApplySpellChecking?ApplyRule:string=IgnoreAll_Spelling");
+        if(m_bGrammarResults)
+            m_xPopupMenu->SetItemCommand(MN_IGNORE_SELECTION, ".uno:ApplySpellChecking?ApplyRule:string=Ignore_Grammar");
+        else
+            m_xPopupMenu->SetItemCommand(MN_IGNORE_SELECTION, ".uno:ApplySpellChecking?ApplyRule:string=Ignore_Spelling");
+
+        for(int i = 0; i < aSuggestions.getLength(); ++i)
+        {
+            sal_uInt16 nItemId = MN_SUGGESTION_START + i;
+            OUString sCommandString = OUString(".uno:ApplySpellChecking?ApplyRule:string=Replace_");
+            if(m_bGrammarResults)
+                sCommandString += "Grammar_";
+            else if (m_xSpellAlt.is())
+                sCommandString += "Spelling_";
+            sCommandString += m_xPopupMenu->GetItemText(nItemId);
+            m_xPopupMenu->SetItemCommand(nItemId, sCommandString);
+        }
+
+        PopupMenu *pMenu = m_xPopupMenu->GetPopupMenu(m_nLangSelectionMenuId);
+        if(pMenu)
+        {
+            for (auto item : m_aLangTable_Text)
+            {
+                OUString sCommandString = OUString(".uno:LanguageStatus?Language:string=Current_") + item.second;
+                pMenu->SetItemCommand(item.first, sCommandString);
+            }
+
+            pMenu->SetItemCommand(MN_SET_SELECTION_NONE, ".uno:LanguageStatus?Language:string=Current_LANGUAGE_NONE");
+            pMenu->SetItemCommand(MN_SET_SELECTION_RESET, ".uno:LanguageStatus?Language:string=Current_RESET_LANGUAGES");
+            pMenu->SetItemCommand(MN_SET_SELECTION_MORE, ".uno:FontDialog?Page:string=font");
+        }
+
+        pMenu = m_xPopupMenu->GetPopupMenu(m_nLangParaMenuId);
+        if(pMenu)
+        {
+            for (auto item : m_aLangTable_Paragraph)
+            {
+                OUString sCommandString = OUString(".uno:LanguageStatus?Language:string=Paragraph_") + item.second;
+                pMenu->SetItemCommand(item.first, sCommandString);
+            }
+
+            pMenu->SetItemCommand(MN_SET_PARA_NONE, ".uno:LanguageStatus?Language:string=Paragraph_LANGUAGE_NONE");
+            pMenu->SetItemCommand(MN_SET_PARA_RESET, ".uno:LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES");
+            pMenu->SetItemCommand(MN_SET_PARA_MORE, ".uno:FontDialogForParagraph");
+        }
+    }
+}
+
 void SwSpellPopup::checkRedline()
 {
     // Let SwView::GetState() already has the logic on when to disable the
@@ -727,7 +788,7 @@ void SwSpellPopup::Execute( sal_uInt16 nId )
     }
     else if (nId == MN_IGNORE_SELECTION)
     {
-        SfxStringItem aIgnoreString(FN_PARAM_1, "Ignore");
+        SfxStringItem aIgnoreString(FN_PARAM_1, m_bGrammarResults ? OUString("Ignore_Grammar") : OUString("Ignore_Spelling"));
         m_pSh->GetView().GetViewFrame()->GetDispatcher()->ExecuteList(SID_APPLY_SPELLCHECKING, SfxCallMode::SYNCHRON, { &aIgnoreString });
     }
     else if (nId == m_nIgnoreWordId)
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index 4db7fd030846..30c5607e51b6 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -1441,7 +1441,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
         if (pItem2)
             sApplyText = pItem2->GetValue();
 
-        const OUString sIgnoreString("Ignore");
+        const OUString sIgnorePrefix("Ignore_");
         const OUString sIgnoreAllPrefix("IgnoreAll_");
         const OUString sSpellingRule("Spelling");
         const OUString sGrammarRule("Grammar");
@@ -1449,8 +1449,31 @@ void SwTextShell::Execute(SfxRequest &rReq)
 
         // Ignore the word at the cursor pos
         sal_Int32 nPos = 0;
-        if (sApplyText == sIgnoreString)
+        if (-1 != (nPos = sApplyText.indexOf( sIgnorePrefix )))
         {
+            if(!rWrtSh.HasSelection())
+            {
+                sApplyText = sApplyText.replaceAt(nPos, sIgnorePrefix.getLength(), "");
+                if (-1 != (nPos = sApplyText.indexOf( sGrammarRule )))
+                {
+                    linguistic2::ProofreadingResult aGrammarCheckRes;
+                    sal_Int32 nErrorInResult = -1;
+                    uno::Sequence< OUString > aSuggestions;
+                    sal_Int32 nErrorPosInText = -1;
+                    SwRect aToFill;
+                    bool bCorrectionRes = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
+                    if (!bCorrectionRes)
+                        return;
+                }
+                else
+                {
+                    SwRect aToFill;
+                    uno::Reference< linguistic2::XSpellAlternatives >  xSpellAlt( rWrtSh.GetCorrection(nullptr, aToFill) );
+                    if (!xSpellAlt.is())
+                        return;
+                }
+            }
+
             SwPaM *pPaM = rWrtSh.GetCursor();
             if (pPaM)
                 SwEditShell::IgnoreGrammarErrorAt( *pPaM );
@@ -1513,12 +1536,19 @@ void SwTextShell::Execute(SfxRequest &rReq)
             if(-1 != (nPos = sApplyText.indexOf( sGrammarRule2 )))
             {
                 sApplyText = sApplyText.replaceAt(nPos, sGrammarRule2.getLength(), "");
-                linguistic2::ProofreadingResult aGrammarCheckRes;
-                sal_Int32 nErrorInResult = -1;
-                uno::Sequence< OUString > aSuggestions;
-                sal_Int32 nErrorPosInText = -1;
-                SwRect aToFill;
-                bGrammar = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
+                if(rWrtSh.HasSelection())
+                {
+                    bGrammar = true;
+                }
+                else
+                {
+                    linguistic2::ProofreadingResult aGrammarCheckRes;
+                    sal_Int32 nErrorInResult = -1;
+                    uno::Sequence< OUString > aSuggestions;
+                    sal_Int32 nErrorPosInText = -1;
+                    SwRect aToFill;
+                    bGrammar = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
+                }
             }
             else if (-1 != (nPos = sApplyText.indexOf( sSpellingRule2 )))
             {
diff --git a/sw/source/uibase/uiview/viewling.cxx b/sw/source/uibase/uiview/viewling.cxx
index 3d85fb02edb0..7aae55d310a2 100644
--- a/sw/source/uibase/uiview/viewling.cxx
+++ b/sw/source/uibase/uiview/viewling.cxx
@@ -66,6 +66,8 @@
 #include <strings.hrc>
 #include <hhcwrp.hxx>
 
+#include <boost/property_tree/json_parser.hpp>
+
 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
 #include <com/sun/star/ui/ContextMenuExecuteEvent.hpp>
 #include <com/sun/star/lang/XInitialization.hpp>
@@ -91,6 +93,7 @@
 #include <xmloff/odffields.hxx>
 
 #include <editeng/editerr.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include <memory>
 
@@ -771,9 +774,23 @@ bool SwView::ExecSpellPopup(const Point& rPt)
                     else
                     {
                         if (comphelper::LibreOfficeKit::isActive())
-                            xPopup->GetMenu().SetLOKNotifier(SfxViewShell::Current());
+                        {
+                            if (SfxViewShell* pViewShell = SfxViewShell::Current())
+                            {
+                                boost::property_tree::ptree aMenu = SfxDispatcher::fillPopupMenu(&xPopup->GetMenu());
+                                boost::property_tree::ptree aRoot;
+                                aRoot.add_child("menu", aMenu);
 
-                        xPopup->Execute(aToFill.SVRect(), m_pEditWin);
+                                std::stringstream aStream;
+                                boost::property_tree::write_json(aStream, aRoot, true);
+                                pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_MENU, aStream.str().c_str());
+                            }
+                        }
+                        else
+                        {
+                            boost::property_tree::ptree aMenu = SfxDispatcher::fillPopupMenu(&xPopup->GetMenu());
+                            xPopup->Execute(aToFill.SVRect(), m_pEditWin);
+                        }
                     }
                 }
             }
commit 4704d39e5442252d67eb2f52ce4e9777ac721933
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Nov 18 14:36:25 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Nov 18 14:56:45 2019 +0100

    Dispatch: Make fillPopupMenu() method accessible from other modules.
    
    No functional change.
    
    Change-Id: Ifaa6ff038277ef5702ac38d90c7461d664b0aee4

diff --git a/include/sfx2/dispatch.hxx b/include/sfx2/dispatch.hxx
index 97f5dae19ecf..231d5eee1483 100644
--- a/include/sfx2/dispatch.hxx
+++ b/include/sfx2/dispatch.hxx
@@ -29,6 +29,8 @@
 #include <o3tl/typed_flags_set.hxx>
 #include <o3tl/span.hxx>
 
+#include <boost/property_tree/ptree.hpp>
+#include <vcl/menu.hxx>
 #include <initializer_list>
 
 class SfxSlotServer;
@@ -168,6 +170,8 @@ public:
     SAL_DLLPRIVATE void DoActivate_Impl( bool bMDI );
     SAL_DLLPRIVATE void DoDeactivate_Impl( bool bMDI, SfxViewFrame const * pNew );
     SAL_DLLPRIVATE void InvalidateBindings_Impl(bool);
+
+    static boost::property_tree::ptree fillPopupMenu(Menu* pMenu);
 };
 
 #endif
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 246a10d32ca5..31b34a924446 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -141,103 +141,6 @@ struct SfxDispatcher_Impl
     std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
 };
 
-namespace {
-
-    boost::property_tree::ptree fillPopupMenu(Menu* pMenu)
-    {
-        // Activate this menu first
-        pMenu->HandleMenuActivateEvent(pMenu);
-        pMenu->HandleMenuDeActivateEvent(pMenu);
-
-        boost::property_tree::ptree aTree;
-        // If last item inserted is some valid text
-        bool bIsLastItemText = false;
-        sal_uInt16 nCount = pMenu->GetItemCount();
-        for (sal_uInt16 nPos = 0; nPos < nCount; nPos++)
-        {
-            boost::property_tree::ptree aItemTree;
-            const MenuItemType aItemType = pMenu->GetItemType(nPos);
-
-            if (aItemType == MenuItemType::DONTKNOW)
-                continue;
-
-            if (aItemType == MenuItemType::SEPARATOR)
-            {
-                if (bIsLastItemText)
-                    aItemTree.put("type", "separator");
-                bIsLastItemText = false;
-            }
-            else
-            {
-                const sal_uInt16 nItemId = pMenu->GetItemId(nPos);
-                OUString aCommandURL = pMenu->GetItemCommand(nItemId);
-
-                if (aCommandURL.isEmpty())
-                {
-                    const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot(nItemId);
-                    if (pSlot)
-                        aCommandURL = pSlot->GetCommandString();
-                }
-
-                const OUString aItemText = pMenu->GetItemText(nItemId);
-                Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId);
-
-                if (!aItemText.isEmpty())
-                    aItemTree.put("text", aItemText.toUtf8().getStr());
-
-                if (pPopupSubmenu)
-                {
-                    boost::property_tree::ptree aSubmenu = fillPopupMenu(pPopupSubmenu);
-                    if (aSubmenu.empty())
-                        continue;
-
-                    aItemTree.put("type", "menu");
-                    if (!aCommandURL.isEmpty())
-                        aItemTree.put("command", aCommandURL.toUtf8().getStr());
-                    aItemTree.push_back(std::make_pair("menu", aSubmenu));
-                }
-                else
-                {
-                    // no point in exposing choices that don't have the .uno:
-                    // command
-                    if (aCommandURL.isEmpty())
-                        continue;
-
-                    aItemTree.put("type", "command");
-                    aItemTree.put("command", aCommandURL.toUtf8().getStr());
-                }
-
-                aItemTree.put("enabled", pMenu->IsItemEnabled(nItemId));
-
-                MenuItemBits aItemBits = pMenu->GetItemBits(nItemId);
-                bool bHasChecks = true;
-                if (aItemBits & MenuItemBits::CHECKABLE)
-                    aItemTree.put("checktype", "checkmark");
-                else if (aItemBits & MenuItemBits::RADIOCHECK)
-                    aItemTree.put("checktype", "radio");
-                else if (aItemBits & MenuItemBits::AUTOCHECK)
-                    aItemTree.put("checktype", "auto");
-                else
-                    bHasChecks = false;
-
-                if (bHasChecks)
-                    aItemTree.put("checked", pMenu->IsItemChecked(nItemId));
-            }
-
-            if (!aItemTree.empty())
-            {
-                aTree.push_back(std::make_pair("", aItemTree));
-                if (aItemType != MenuItemType::SEPARATOR)
-                    bIsLastItemText = true;
-            }
-        }
-
-        return aTree;
-    }
-
-} // end anonymous namespace
-
-
 /** This method checks if the stack of the SfxDispatchers is flushed, or if
     push- or pop- commands are pending.
 */
@@ -2073,4 +1976,96 @@ SfxModule* SfxDispatcher::GetModule() const
     }
 }
 
+boost::property_tree::ptree SfxDispatcher::fillPopupMenu(Menu* pMenu)
+{
+    // Activate this menu first
+    pMenu->HandleMenuActivateEvent(pMenu);
+    pMenu->HandleMenuDeActivateEvent(pMenu);
+
+    boost::property_tree::ptree aTree;
+    // If last item inserted is some valid text
+    bool bIsLastItemText = false;
+    sal_uInt16 nCount = pMenu->GetItemCount();
+    for (sal_uInt16 nPos = 0; nPos < nCount; nPos++)
+    {
+        boost::property_tree::ptree aItemTree;
+        const MenuItemType aItemType = pMenu->GetItemType(nPos);
+
+        if (aItemType == MenuItemType::DONTKNOW)
+            continue;
+
+        if (aItemType == MenuItemType::SEPARATOR)
+        {
+            if (bIsLastItemText)
+                aItemTree.put("type", "separator");
+            bIsLastItemText = false;
+        }
+        else
+        {
+            const sal_uInt16 nItemId = pMenu->GetItemId(nPos);
+            OUString aCommandURL = pMenu->GetItemCommand(nItemId);
+
+            if (aCommandURL.isEmpty())
+            {
+                const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot(nItemId);
+                if (pSlot)
+                    aCommandURL = pSlot->GetCommandString();
+            }
+
+            const OUString aItemText = pMenu->GetItemText(nItemId);
+            Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId);
+
+            if (!aItemText.isEmpty())
+                aItemTree.put("text", aItemText.toUtf8().getStr());
+
+            if (pPopupSubmenu)
+            {
+                boost::property_tree::ptree aSubmenu = fillPopupMenu(pPopupSubmenu);
+                if (aSubmenu.empty())
+                    continue;
+
+                aItemTree.put("type", "menu");
+                if (!aCommandURL.isEmpty())
+                    aItemTree.put("command", aCommandURL.toUtf8().getStr());
+                aItemTree.push_back(std::make_pair("menu", aSubmenu));
+            }
+            else
+            {
+                // no point in exposing choices that don't have the .uno:
+                // command
+                if (aCommandURL.isEmpty())
+                    continue;
+
+                aItemTree.put("type", "command");
+                aItemTree.put("command", aCommandURL.toUtf8().getStr());
+            }
+
+            aItemTree.put("enabled", pMenu->IsItemEnabled(nItemId));
+
+            MenuItemBits aItemBits = pMenu->GetItemBits(nItemId);
+            bool bHasChecks = true;
+            if (aItemBits & MenuItemBits::CHECKABLE)
+                aItemTree.put("checktype", "checkmark");
+            else if (aItemBits & MenuItemBits::RADIOCHECK)
+                aItemTree.put("checktype", "radio");
+            else if (aItemBits & MenuItemBits::AUTOCHECK)
+                aItemTree.put("checktype", "auto");
+            else
+                bHasChecks = false;
+
+            if (bHasChecks)
+                aItemTree.put("checked", pMenu->IsItemChecked(nItemId));
+        }
+
+        if (!aItemTree.empty())
+        {
+            aTree.push_back(std::make_pair("", aItemTree));
+            if (aItemType != MenuItemType::SEPARATOR)
+                bIsLastItemText = true;
+        }
+    }
+
+    return aTree;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 0549ac69381f7c4bb74e8b828ed8dff3bbfc87cc
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Nov 18 14:33:39 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Nov 18 14:56:44 2019 +0100

    SpellingPopup: lok: Hide unusable items for online
    
    MN_EXPLANATION_LINK is some link, but it's exectued internally,
    which means the the link would be executed on the serves side and
    not on the client's browser.
    m_nCorrectMenuId is a sub menu which allows to specify new autocorrect
    rules. Since m_nAddId is also disabled, I expect that extending
    the dictionaries / autocorrect rule might be a problem for online.
    
    Change-Id: Id6e8ed078f90a4f25a335a3ab5ec0e3056db648d

diff --git a/sw/source/uibase/lingu/olmenu.cxx b/sw/source/uibase/lingu/olmenu.cxx
index e08c5f4a2804..566fb9b933d6 100644
--- a/sw/source/uibase/lingu/olmenu.cxx
+++ b/sw/source/uibase/lingu/olmenu.cxx
@@ -298,11 +298,13 @@ SwSpellPopup::SwSpellPopup(
         vcl::CommandInfoProvider::GetPopupLabelForCommand(".uno:SpellingAndGrammarDialog", aModuleName));
     m_xPopupMenu->SetItemText(m_nCorrectDialogId,
         vcl::CommandInfoProvider::GetPopupLabelForCommand(".uno:AutoCorrectDlg", aModuleName));
+
     if (comphelper::LibreOfficeKit::isActive())
     {
         m_xPopupMenu->HideItem(m_nCorrectDialogId);
         m_xPopupMenu->HideItem(m_nAddId);
         m_xPopupMenu->HideItem(m_nAddMenuId);
+        m_xPopupMenu->HideItem(m_nCorrectMenuId);
     }
     sal_uInt16 nItemPos = m_xPopupMenu->GetItemPos(m_nIgnoreWordId);
     m_xPopupMenu->InsertItem(MN_IGNORE_SELECTION, aIgnoreSelection, MenuItemBits::NONE, OString(), nItemPos);
@@ -580,6 +582,11 @@ SwSpellPopup::SwSpellPopup(
     m_xPopupMenu->RemoveDisabledEntries(true, true);
 
     SvtLinguConfig().SetProperty( UPN_IS_GRAMMAR_INTERACTIVE, uno::makeAny( true ));
+
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        m_xPopupMenu->HideItem(MN_EXPLANATION_LINK);
+    }
 }
 
 SwSpellPopup::~SwSpellPopup() {}
commit 6100ba8f7c4b2877442bcdc0aae96def3b0b440c
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sun Nov 17 14:17:59 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Nov 18 14:56:41 2019 +0100

    SpellingPopup: Convert suggestion menu items to use slot ID.
    
    Change-Id: Icf1f50d04ab5e7ba467d68613f4101a3fe48589b

diff --git a/sw/source/uibase/lingu/olmenu.cxx b/sw/source/uibase/lingu/olmenu.cxx
index f04fb6b71880..e08c5f4a2804 100644
--- a/sw/source/uibase/lingu/olmenu.cxx
+++ b/sw/source/uibase/lingu/olmenu.cxx
@@ -636,26 +636,29 @@ void SwSpellPopup::Execute( sal_uInt16 nId )
     if (/*m_bGrammarResults && */nId == MN_SHORT_COMMENT)
         return;     // nothing to do since it is the error message (short comment)
 
-    if ((MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ||
-        (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END))
+    if (MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END)
     {
-        OUString sNewWord;
-        if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
-        {
-            PopupMenu* pMenu = m_xPopupMenu->GetPopupMenu(m_nCorrectMenuId);
-            assert(pMenu);
-            sNewWord = pMenu->GetItemText(nId);
-        }
-        else
-            sNewWord = m_xPopupMenu->GetItemText(nId);
-
-        if (m_bGrammarResults || m_xSpellAlt.is())
+        OUString sApplyRule("Replace_");
+        if(m_bGrammarResults)
+            sApplyRule += "Grammar_";
+        else if (m_xSpellAlt.is())
+            sApplyRule += "Spelling_";
+        sApplyRule += m_xPopupMenu->GetItemText(nId);
+
+        SfxStringItem aApplyItem(FN_PARAM_1, sApplyRule);
+        m_pSh->GetView().GetViewFrame()->GetDispatcher()->ExecuteList(SID_APPLY_SPELLCHECKING, SfxCallMode::SYNCHRON, { &aApplyItem });
+    }
+    else if(MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
+    {
+        if (m_xSpellAlt.is())
         {
             bool bOldIns = m_pSh->IsInsMode();
             m_pSh->SetInsMode();
 
-            OUString aTmp( sNewWord );
-            OUString aOrig( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() );
+            PopupMenu* pMenu = m_xPopupMenu->GetPopupMenu(m_nCorrectMenuId);
+            assert(pMenu);
+            OUString aTmp( pMenu->GetItemText(nId) );
+            OUString aOrig( m_xSpellAlt->getWord() );
 
             // if original word has a trailing . (likely the end of a sentence)
             // and the replacement text hasn't, then add it to the replacement
@@ -688,11 +691,11 @@ void SwSpellPopup::Execute( sal_uInt16 nId )
             // record only if it's NOT already present in autocorrection
             SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
 
-            OUString aOrigWord( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() ) ;
-            SvxPrepareAutoCorrect( aOrigWord, sNewWord );
+            OUString aOrigWord( m_xSpellAlt->getWord() ) ;
+            OUString aNewWord( pMenu->GetItemText(nId) );
+            SvxPrepareAutoCorrect( aOrigWord, aNewWord );
 
-            if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
-                pACorr->PutText( aOrigWord, sNewWord, m_nCheckedLanguage );
+            pACorr->PutText( aOrigWord, aNewWord, m_nCheckedLanguage );
 
             /* #102505# EndAction/EndUndo moved down since insertion
                of temporary auto correction is now undoable two and
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index bff08a595f18..4db7fd030846 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -128,6 +128,7 @@
 #include <xmloff/odffields.hxx>
 #include <bookmrk.hxx>
 #include <linguistic/misc.hxx>
+#include <editeng/splwrap.hxx>
 
 using namespace ::com::sun::star;
 using namespace com::sun::star::beans;
@@ -1444,7 +1445,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
         const OUString sIgnoreAllPrefix("IgnoreAll_");
         const OUString sSpellingRule("Spelling");
         const OUString sGrammarRule("Grammar");
-        //const OUString aReplacePrefix("Replace_");
+        const OUString aReplacePrefix("Replace_");
 
         // Ignore the word at the cursor pos
         sal_Int32 nPos = 0;
@@ -1500,6 +1501,88 @@ void SwTextShell::Execute(SfxRequest &rReq)
                 }
             }
         }
+        // Replace text with the suggestion
+        else if (-1 != (nPos = sApplyText.indexOf( aReplacePrefix )))
+        {
+            sApplyText = sApplyText.replaceAt(nPos, aReplacePrefix.getLength(), "");
+
+            const OUString sSpellingRule2(sSpellingRule + "_");
+            const OUString sGrammarRule2(sGrammarRule + "_");
+            bool bGrammar = false;
+            uno::Reference< linguistic2::XSpellAlternatives >  xSpellAlt;
+            if(-1 != (nPos = sApplyText.indexOf( sGrammarRule2 )))
+            {
+                sApplyText = sApplyText.replaceAt(nPos, sGrammarRule2.getLength(), "");
+                linguistic2::ProofreadingResult aGrammarCheckRes;
+                sal_Int32 nErrorInResult = -1;
+                uno::Sequence< OUString > aSuggestions;
+                sal_Int32 nErrorPosInText = -1;
+                SwRect aToFill;
+                bGrammar = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
+            }
+            else if (-1 != (nPos = sApplyText.indexOf( sSpellingRule2 )))
+            {
+                sApplyText = sApplyText.replaceAt(nPos, sSpellingRule2.getLength(), "");
+                SwRect aToFill;
+                xSpellAlt.set(rWrtSh.GetCorrection(nullptr, aToFill));
+                bGrammar = false;
+            }
+
+            if (!bGrammar && !xSpellAlt.is())
+                return;
+
+            bool bOldIns = rWrtSh.IsInsMode();
+            rWrtSh.SetInsMode();
+
+            OUString aTmp( sApplyText );
+            OUString aOrig( bGrammar ? OUString() : xSpellAlt->getWord() );
+
+            // if original word has a trailing . (likely the end of a sentence)
+            // and the replacement text hasn't, then add it to the replacement
+            if (!aTmp.isEmpty() && !aOrig.isEmpty() &&
+                aOrig.endsWith(".") && /* !IsAlphaNumeric ??*/
+                !aTmp.endsWith("."))
+            {
+                aTmp += ".";
+            }
+
+            SwRewriter aRewriter;
+
+            aRewriter.AddRule(UndoArg1, rWrtSh.GetCursorDescr());
+            aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
+
+            OUString aTmpStr = SwResId(STR_START_QUOTE) +
+                aTmp + SwResId(STR_END_QUOTE);
+            aRewriter.AddRule(UndoArg3, aTmpStr);
+
+            rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter);
+            rWrtSh.StartAction();
+            rWrtSh.DelLeft();
+
+            rWrtSh.Insert( aTmp );
+
+            /* #102505# EndAction/EndUndo moved down since insertion
+               of temporary auto correction is now undoable two and
+               must reside in the same undo group.*/
+
+            // record only if it's NOT already present in autocorrection
+            SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+            OUString aOrigWord( bGrammar ? OUString() : xSpellAlt->getWord() ) ;
+            OUString aNewWord( sApplyText );
+            SvxPrepareAutoCorrect( aOrigWord, aNewWord );
+
+            if (xSpellAlt.is())
+                pACorr->PutText( aOrigWord, aNewWord, LanguageTag( xSpellAlt->getLocale() ).getLanguageType() );
+
+            /* #102505# EndAction/EndUndo moved down since insertion
+               of temporary auto correction is now undoable two and
+               must reside in the same undo group.*/
+            rWrtSh.EndAction();
+            rWrtSh.EndUndo();
+
+            rWrtSh.SetInsMode( bOldIns );
+        }
     }
     break;
     default:
commit c2357aa6cd04242e97e8014cdb981466af7c7e8d
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sun Nov 17 13:33:51 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Mon Nov 18 14:53:00 2019 +0100

    SpellingPopup: Remove m_aSuggestions member variable
    
    We don't need it after the construction. The text is stored by the
    menu item.
    
    Change-Id: I54b0392b4564e76d405824bb297e6f993a24a5fb

diff --git a/sw/source/uibase/inc/olmenu.hxx b/sw/source/uibase/inc/olmenu.hxx
index db80e20e931a..984dfb759872 100644
--- a/sw/source/uibase/inc/olmenu.hxx
+++ b/sw/source/uibase/inc/olmenu.hxx
@@ -96,7 +96,6 @@ class SW_DLLPUBLIC SwSpellPopup
     css::linguistic2::ProofreadingResult m_xGrammarResult;
     sal_Int32 m_nGrammarError;
 
-    css::uno::Sequence< OUString >  m_aSuggestions;
     OUString m_sExplanationLink;
 
     LanguageType                m_nCheckedLanguage;
diff --git a/sw/source/uibase/lingu/olmenu.cxx b/sw/source/uibase/lingu/olmenu.cxx
index 57260b5b4dd7..f04fb6b71880 100644
--- a/sw/source/uibase/lingu/olmenu.cxx
+++ b/sw/source/uibase/lingu/olmenu.cxx
@@ -242,12 +242,13 @@ SwSpellPopup::SwSpellPopup(
     bool bUseImagesInMenus = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus();
 
     m_nCheckedLanguage = LANGUAGE_NONE;
+    css::uno::Sequence< OUString > aSuggestions;
     if (m_xSpellAlt.is())
     {
         m_nCheckedLanguage = LanguageTag( m_xSpellAlt->getLocale() ).getLanguageType();
-        m_aSuggestions = m_xSpellAlt->getAlternatives();
+        aSuggestions = m_xSpellAlt->getAlternatives();
     }
-    sal_Int16 nStringCount = static_cast< sal_Int16 >( m_aSuggestions.getLength() );
+    sal_Int16 nStringCount = static_cast< sal_Int16 >( aSuggestions.getLength() );
 
     SvtLinguConfig aCfg;
 
@@ -275,7 +276,7 @@ SwSpellPopup::SwSpellPopup(
         sal_uInt16 nItemId          = MN_SUGGESTION_START;
         for (sal_uInt16 i = 0; i < nStringCount; ++i)
         {
-            const OUString aEntry = m_aSuggestions[ i ];
+            const OUString aEntry = aSuggestions[ i ];
             m_xPopupMenu->InsertItem(nItemId, aEntry, MenuItemBits::NONE, OString(), i);
             m_xPopupMenu->SetHelpId(nItemId, HID_LINGU_REPLACE);
             if (!aSuggestionImageUrl.isEmpty())
@@ -443,7 +444,6 @@ SwSpellPopup::SwSpellPopup(
     , m_nRedlinePrevId(m_xPopupMenu->GetItemId("prev"))
     , m_pSh(pWrtSh)
     , m_xGrammarResult(rResult)
-    , m_aSuggestions(rSuggestions)
     , m_sExplanationLink()
     , m_bGrammarResults(true)
 {
@@ -480,7 +480,7 @@ SwSpellPopup::SwSpellPopup(
     m_xPopupMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
 
     m_xPopupMenu->InsertSeparator(OString(), nPos++);
-    if ( m_aSuggestions.hasElements() )     // suggestions available...
+    if ( rSuggestions.hasElements() )     // suggestions available...
     {
         Image aImage;
         OUString aSuggestionImageUrl;
@@ -496,7 +496,7 @@ SwSpellPopup::SwSpellPopup(
         }
 
         sal_uInt16 nItemId = MN_SUGGESTION_START;
-        for (const OUString& aEntry : std::as_const(m_aSuggestions))
+        for (const OUString& aEntry : std::as_const(rSuggestions))
         {
             m_xPopupMenu->InsertItem(nItemId, aEntry, MenuItemBits::NONE, OString(), nPos++);
             m_xPopupMenu->SetHelpId(nItemId, HID_LINGU_REPLACE);
@@ -639,15 +639,22 @@ void SwSpellPopup::Execute( sal_uInt16 nId )
     if ((MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ||
         (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END))
     {
-        sal_Int32 nAltIdx = (MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ?
-                nId - MN_SUGGESTION_START : nId - MN_AUTOCORR_START;
-        OSL_ENSURE(nAltIdx < m_aSuggestions.getLength(), "index out of range");
-        if (nAltIdx < m_aSuggestions.getLength() && (m_bGrammarResults || m_xSpellAlt.is()))
+        OUString sNewWord;
+        if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
+        {
+            PopupMenu* pMenu = m_xPopupMenu->GetPopupMenu(m_nCorrectMenuId);
+            assert(pMenu);
+            sNewWord = pMenu->GetItemText(nId);
+        }
+        else
+            sNewWord = m_xPopupMenu->GetItemText(nId);
+
+        if (m_bGrammarResults || m_xSpellAlt.is())
         {
             bool bOldIns = m_pSh->IsInsMode();
             m_pSh->SetInsMode();
 
-            OUString aTmp( m_aSuggestions[ nAltIdx ] );
+            OUString aTmp( sNewWord );
             OUString aOrig( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() );
 
             // if original word has a trailing . (likely the end of a sentence)
@@ -682,11 +689,10 @@ void SwSpellPopup::Execute( sal_uInt16 nId )
             SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
 
             OUString aOrigWord( m_bGrammarResults ? OUString() : m_xSpellAlt->getWord() ) ;
-            OUString aNewWord( m_aSuggestions[ nAltIdx ] );
-            SvxPrepareAutoCorrect( aOrigWord, aNewWord );
+            SvxPrepareAutoCorrect( aOrigWord, sNewWord );
 
             if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
-                pACorr->PutText( aOrigWord, aNewWord, m_nCheckedLanguage );
+                pACorr->PutText( aOrigWord, sNewWord, m_nCheckedLanguage );
 
             /* #102505# EndAction/EndUndo moved down since insertion
                of temporary auto correction is now undoable two and


More information about the Libreoffice-commits mailing list