[Libreoffice-commits] core.git: 2 commits - include/LibreOfficeKit libreofficekit/source sc/source sd/source sfx2/source sw/source

Jan Holesovsky kendy at collabora.com
Fri Apr 8 07:44:38 UTC 2016


 include/LibreOfficeKit/LibreOfficeKitEnums.h |   23 +++++
 libreofficekit/source/gtk/lokdocview.cxx     |    7 +
 sc/source/ui/inc/gridwin.hxx                 |    2 
 sc/source/ui/unoobj/docuno.cxx               |   10 ++
 sd/source/ui/unoidl/unomodel.cxx             |   10 ++
 sfx2/source/control/dispatch.cxx             |  113 ++++++++++++++++++++++++++-
 sw/source/uibase/inc/edtwin.hxx              |    4 
 sw/source/uibase/uno/unotxdoc.cxx            |    9 +-
 8 files changed, 169 insertions(+), 9 deletions(-)

New commits:
commit 788616fe7ce7c56d9dcfccafdd3e1f55036aa8a7
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Apr 8 09:15:55 2016 +0200

    lok context menu: Expose the disabled commands too.
    
    OTOH, don't show choices that don't have the .uno: command, we have no way to
    handle them.
    
    Change-Id: I0df6ffe2049bbf11ba4b8931164be6a3381d3916

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index fb713cd..4b8ff35 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -293,15 +293,22 @@ typedef enum
     /**
      * Context menu structure
      *
-     * Returns the structure of context menu
+     * Returns the structure of context menu.  Contains all the separators &
+     * submenus, example of the returned structure:
      *
      * {
-     *      "menu": [
-     *          {"text": "label text", "type": "command | separator | menu",
-     *      "command | menu": "..." },
-     *          ...
-     *      ]
+     *     "menu": [
+     *         { "text": "label text1", "type": "command", "command": ".uno:Something1", "enabled": "true" },
+     *         { "text": "label text2", "type": "command", "command": ".uno:Something2", "enabled": "false" },
+     *         { "type": "separator" },
+     *         { "text": "label text2", "type": "menu", "menu": [ { ... }, { ... }, ... ] },
+     *         ...
+     *     ]
      * }
+     *
+     * The 'command' can additionally have a checkable status, like:
+     *
+     *     {"text": "label text3", "type": "command", "command": ".uno:Something3", "checktype": "checkmark|radio|auto", "checked": "true|false"}
      */
     LOK_CALLBACK_CONTEXT_MENU,
 
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 7782459..15681da 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -181,57 +181,44 @@ namespace {
                 const OUString aItemText = pMenu->GetItemText(nItemId);
                 Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId);
 
-                if (!pMenu->IsItemEnabled(nItemId))
-                    continue;
-
                 if (!aItemText.isEmpty())
-                    aItemTree.put("text", std::string(aItemText.toUtf8().getStr()));
+                    aItemTree.put("text", aItemText.toUtf8().getStr());
 
                 if (pPopupSubmenu)
                 {
                     boost::property_tree::ptree aSubmenu = fillPopupMenu(pPopupSubmenu);
-                    if (!aSubmenu.empty())
-                    {
-                        aItemTree.put("type", "menu");
-                        aItemTree.push_back(std::make_pair("menu", aSubmenu));
-                    }
-                    else
-                        aItemTree.clear();
+                    if (aSubmenu.empty())
+                        continue;
+
+                    aItemTree.put("type", "menu");
+                    aItemTree.push_back(std::make_pair("menu", aSubmenu));
                 }
                 else
                 {
-                    if (!aCommandURL.isEmpty())
-                    {
-                        aItemTree.put("type", "command");
-                        aItemTree.put("command", std::string(aCommandURL.toUtf8().getStr()));
-                    }
+                    // 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 = false;
+                bool bHasChecks = true;
                 if (aItemBits & MenuItemBits::CHECKABLE)
-                {
                     aItemTree.put("checktype", "checkmark");
-                    bHasChecks = true;
-                }
                 else if (aItemBits & MenuItemBits::RADIOCHECK)
-                {
                     aItemTree.put("checktype", "radio");
-                    bHasChecks = true;
-                }
                 else if (aItemBits & MenuItemBits::AUTOCHECK)
-                {
                     aItemTree.put("checktype", "auto");
-                    bHasChecks = true;
-                }
+                else
+                    bHasChecks = false;
 
                 if (bHasChecks)
-                {
-                    if (pMenu->IsItemChecked(nItemId))
-                        aItemTree.put("checked", "true");
-                    else
-                        aItemTree.put("checked", "false");
-                }
+                    aItemTree.put("checked", pMenu->IsItemChecked(nItemId));
             }
 
             if (!aItemTree.empty())
commit 610db8d5d0500aed2ca6d4da822cf70746b44d49
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu Mar 31 14:47:27 2016 +0530

    lok context menu: Expose context menu
    
    Change-Id: I0968689630e10f838c075e86357eb36a9a220d0d

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 80ed9de..fb713cd 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -289,6 +289,22 @@ typedef enum
      * }
      */
     LOK_CALLBACK_ERROR,
+
+    /**
+     * Context menu structure
+     *
+     * Returns the structure of context menu
+     *
+     * {
+     *      "menu": [
+     *          {"text": "label text", "type": "command | separator | menu",
+     *      "command | menu": "..." },
+     *          ...
+     *      ]
+     * }
+     */
+    LOK_CALLBACK_CONTEXT_MENU,
+
 }
 LibreOfficeKitCallbackType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 155174f..81ccb37 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -336,6 +336,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_DOCUMENT_PASSWORD";
     case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY:
         return "LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY";
+    case LOK_CALLBACK_CONTEXT_MENU:
+        return "LOK_CALLBACK_CONTEXT_MENU";
     }
     return nullptr;
 }
@@ -1141,6 +1143,11 @@ callback (gpointer pData)
         reportError(pDocView, pCallback->m_aPayload);
     }
     break;
+    case LOK_CALLBACK_CONTEXT_MENU:
+    {
+        // TODO: Implement me
+        break;
+    }
     default:
         g_assert(false);
         break;
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index a886253..d4baed7 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -295,7 +295,6 @@ protected:
     virtual void    LoseFocus() override;
 
     virtual void    RequestHelp( const HelpEvent& rEvt ) override;
-    virtual void    Command( const CommandEvent& rCEvt ) override;
 
     virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
     virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
@@ -313,6 +312,7 @@ public:
     rtl::Reference<sdr::overlay::OverlayManager> getOverlayManager();
     void flushOverlayManager();
 
+    virtual void    Command( const CommandEvent& rCEvt ) override;
     virtual void    DataChanged( const DataChangedEvent& rDCEvt ) override;
 
     virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index ead7061..81af766 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -597,13 +597,21 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt
                        Fraction(mnTilePixelHeight * TWIPS_PER_PIXEL, mnTileTwipHeight), true);
 
     // Calc operates in pixels...
-    MouseEvent aEvent(Point(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()), nCount,
+    Point aPos(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY());
+    MouseEvent aEvent(aPos, nCount,
             MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
 
     switch (nType)
     {
     case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
         pGridWindow->MouseButtonDown(aEvent);
+
+        // Invoke the context menu
+        if (nButtons & MOUSE_RIGHT)
+        {
+            const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr);
+            pGridWindow->Command(aCEvt);
+        }
         break;
     case LOK_MOUSEEVENT_MOUSEBUTTONUP:
         pGridWindow->MouseButtonUp(aEvent);
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 546f360..a44f12e 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -2438,16 +2438,24 @@ void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, i
     SolarMutexGuard aGuard;
 
     DrawViewShell* pViewShell = GetViewShell();
+    Window* pWindow = pViewShell->GetActiveWindow();
     if (!pViewShell)
         return;
 
-    MouseEvent aEvent(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)), nCount,
+    Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)));
+    MouseEvent aEvent(aPos, nCount,
             MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
 
     switch (nType)
     {
     case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
         pViewShell->LogicMouseButtonDown(aEvent);
+
+        if (nButtons & MOUSE_RIGHT)
+        {
+            const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr);
+            pViewShell->Command(aCEvt, pWindow);
+        }
         break;
     case LOK_MOUSEEVENT_MOUSEBUTTONUP:
         pViewShell->LogicMouseButtonUp(aEvent);
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index b6e3600..7782459 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -26,11 +26,14 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#include <boost/property_tree/json_parser.hpp>
+
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
 #include <com/sun/star/frame/XLayoutManager.hpp>
 #include <com/sun/star/frame/XPopupMenuController.hpp>
 
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertyvalue.hxx>
@@ -144,6 +147,107 @@ 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);
+                const OUString aCommandURL = pMenu->GetItemCommand(nItemId);
+
+                const OUString aItemText = pMenu->GetItemText(nItemId);
+                Menu* pPopupSubmenu = pMenu->GetPopupMenu(nItemId);
+
+                if (!pMenu->IsItemEnabled(nItemId))
+                    continue;
+
+                if (!aItemText.isEmpty())
+                    aItemTree.put("text", std::string(aItemText.toUtf8().getStr()));
+
+                if (pPopupSubmenu)
+                {
+                    boost::property_tree::ptree aSubmenu = fillPopupMenu(pPopupSubmenu);
+                    if (!aSubmenu.empty())
+                    {
+                        aItemTree.put("type", "menu");
+                        aItemTree.push_back(std::make_pair("menu", aSubmenu));
+                    }
+                    else
+                        aItemTree.clear();
+                }
+                else
+                {
+                    if (!aCommandURL.isEmpty())
+                    {
+                        aItemTree.put("type", "command");
+                        aItemTree.put("command", std::string(aCommandURL.toUtf8().getStr()));
+                    }
+                }
+
+                MenuItemBits aItemBits = pMenu->GetItemBits(nItemId);
+                bool bHasChecks = false;
+                if (aItemBits & MenuItemBits::CHECKABLE)
+                {
+                    aItemTree.put("checktype", "checkmark");
+                    bHasChecks = true;
+                }
+                else if (aItemBits & MenuItemBits::RADIOCHECK)
+                {
+                    aItemTree.put("checktype", "radio");
+                    bHasChecks = true;
+                }
+                else if (aItemBits & MenuItemBits::AUTOCHECK)
+                {
+                    aItemTree.put("checktype", "auto");
+                    bHasChecks = true;
+                }
+
+                if (bHasChecks)
+                {
+                    if (pMenu->IsItemChecked(nItemId))
+                        aItemTree.put("checked", "true");
+                    else
+                        aItemTree.put("checked", "false");
+                }
+            }
+
+            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.
 */
@@ -1884,9 +1988,25 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window *pWin, c
     xPopupController->setPopupMenu( xPopupMenu );
     VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( xPopupMenu );
     PopupMenu* pVCLMenu = static_cast< PopupMenu* >( pAwtMenu->GetMenu() );
-    OUString aMenuURL = "private:resource/popupmenu/" + rResName;
-    if ( pVCLMenu && GetFrame()->GetViewShell()->TryContextMenuInterception( *pVCLMenu, aMenuURL, aEvent ) )
-        pVCLMenu->Execute( pWindow, aPos );
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        boost::property_tree::ptree aMenu = fillPopupMenu(pVCLMenu);
+        boost::property_tree::ptree aRoot;
+        aRoot.add_child("menu", aMenu);
+
+        std::stringstream aStream;
+        boost::property_tree::write_json(aStream, aRoot, true);
+        const SfxObjectShell* objSh = xImp->pFrame->GetObjectShell();
+        objSh->libreOfficeKitCallback(LOK_CALLBACK_CONTEXT_MENU, aStream.str().c_str());
+    }
+    else
+    {
+        OUString aMenuURL = "private:resource/popupmenu/" + rResName;
+        if (pVCLMenu && GetFrame()->GetViewShell()->TryContextMenuInterception(*pVCLMenu, aMenuURL, aEvent))
+        {
+            pVCLMenu->Execute(pWindow, aPos);
+        }
+    }
 
     css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY );
     if ( xComponent.is() )
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 58f2a48..96c1d5a 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -197,8 +197,6 @@ protected:
     virtual void    MouseButtonUp(const MouseEvent& rMEvt) override;
     virtual void    RequestHelp(const HelpEvent& rEvt) override;
 
-    virtual void    Command( const CommandEvent& rCEvt ) override;
-
                                 // Drag & Drop Interface
     virtual sal_Int8    AcceptDrop( const AcceptDropEvent& rEvt ) override;
     virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
@@ -295,6 +293,8 @@ public:
     virtual ~SwEditWin();
     virtual void dispose() override;
 
+    virtual void    Command( const CommandEvent& rCEvt ) override;
+
     /// @see OutputDevice::LogicInvalidate().
     void LogicInvalidate(const Rectangle* pRectangle) override;
     /// Same as MouseButtonDown(), but coordinates are in logic unit.
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 2087912e..5a7d252 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3305,12 +3305,19 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int
     SolarMutexGuard aGuard;
 
     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
-    MouseEvent aEvent(Point(nX, nY), nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
+    Point aPos(nX , nY);
+    MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
 
     switch (nType)
     {
     case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
         rEditWin.LogicMouseButtonDown(aEvent);
+
+        if (nButtons & MOUSE_RIGHT)
+        {
+            const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu, true, nullptr);
+            rEditWin.Command(aCEvt);
+        }
         break;
     case LOK_MOUSEEVENT_MOUSEBUTTONUP:
         rEditWin.LogicMouseButtonUp(aEvent);


More information about the Libreoffice-commits mailing list