desktop/source/lib/init.cxx                  |    4 -
 include/LibreOfficeKit/LibreOfficeKit.hxx    |   10 +++-
 include/LibreOfficeKit/LibreOfficeKitEnums.h |   23 ++++++++---
 libreofficekit/source/gtk/lokdocview.cxx     |   27 ++++++++++++-
 sw/source/uibase/uno/unotxdoc.cxx            |   56 ++++++++++++++++++---------
 sw/source/uibase/wrtsh/wrtsh3.cxx            |   18 +++++++-
 6 files changed, 106 insertions(+), 32 deletions(-)

New commits:
commit 3e4e9a7776422bbb1ab4d3b54025204787864f02
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon May 23 08:39:34 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue May 24 13:14:45 2022 +0200

    sw content controls, picture: add LOK API
    
    - send a LOK_CALLBACK_CONTENT_CONTROL callback with
      action=change-picture when a file picker should be shown
    
    - extend lok::Document::sendContentControlEvent() to be able to replace
      the placeholder with the selected URL
    
    - update gtktiledviewer to work with these
    
    (cherry picked from commit 9a76be53dfb801b754bf55f9d4b8c5f82991a62f)
    
    Conflicts:
            sw/source/uibase/uno/unotxdoc.cxx
    
    Change-Id: Ifb3750803885fc09fc82905b0cf85b2b8ca06e77
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134850
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index b5f823e492ef..d4e222c8fba9 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -6123,9 +6123,9 @@ static void 
doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const cha
     }
 
     // Sanity check
-    if (aMap.find("type") == aMap.end() || aMap.find("selected") == aMap.end())
+    if (aMap.find("type") == aMap.end())
     {
-        SetLastExceptionMsg("Wrong arguments for sendContentControlEvent");
+        SetLastExceptionMsg("Missing 'type' argument for 
sendContentControlEvent");
         return;
     }
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx 
b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 3140e121151d..827856c3ebeb 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -812,14 +812,18 @@ public:
      *
      * @param pArguments arguments of the event.
      *
-     * Example argument string:
-     *
+     * Examples:
+     * To select the 3rd list item of the drop-down:
      * {
      *     "type": "drop-down",
      *     "selected": "2"
      * }
      *
-     * selects the 3rd list item of the drop-down.
+     * To change a picture place-holder:
+     * {
+     *     "type": "picture",
+     *     "changed": "file:///path/to/test.png"
+     * }
      */
     void sendContentControlEvent(const char* pArguments)
     {
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 1af91bbee22b..c578582d2726 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -799,15 +799,28 @@ typedef enum
     /**
      * Sends all information for displaying metadata for a text based content 
control.
      *
-     * The payload example:
+     * Examples:
+     * Entered a rich text content control:
      * {
-     *      "action": "show",
-     *      "rectangles": "1418, 1694, 720, 551; 10291, 1418, 1099, 275"
+     *     "action": "show",
+     *     "rectangles": "1418, 1694, 720, 551; 10291, 1418, 1099, 275"
      * }
      *
-     * or
+     * Left a rich text content control:
+     * {
+     *     "action": "hide"
+     * }
+     *
+     * Entered a dropdown content control:
+     * {
+     *     "action": "show",
+     *     "rectangles": "...",
+     *     "items": ["red", "green", "blue"]
+     * }
+     *
+     * Clicked on a picture content control's placeholder:
      * {
-     *      "action": "hide"
+     *     "action": "change-picture"
      * }
      */
     LOK_CALLBACK_CONTENT_CONTROL = 55,
diff --git a/libreofficekit/source/gtk/lokdocview.cxx 
b/libreofficekit/source/gtk/lokdocview.cxx
index dfccd9affafb..0c6874660aef 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1399,9 +1399,9 @@ callback (gpointer pData)
 
     case LOK_CALLBACK_CONTENT_CONTROL:
     {
-        std::stringstream aStream(pCallback->m_aPayload);
+        std::stringstream aPayloadStream(pCallback->m_aPayload);
         boost::property_tree::ptree aTree;
-        boost::property_tree::read_json(aStream, aTree);
+        boost::property_tree::read_json(aPayloadStream, aTree);
         auto aAction = aTree.get<std::string>("action");
         if (aAction == "show")
         {
@@ -1412,6 +1412,29 @@ callback (gpointer pData)
         {
             priv->m_aContentControlRectangles.clear();
         }
+        else if (aAction == "change-picture")
+        {
+            GtkWidget* pDialog = gtk_file_chooser_dialog_new(
+                "Open File", 
GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView))),
+                GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel", GTK_RESPONSE_CANCEL, 
"Open",
+                GTK_RESPONSE_ACCEPT, nullptr);
+            gint nRet = gtk_dialog_run(GTK_DIALOG(pDialog));
+            if (nRet == GTK_RESPONSE_ACCEPT)
+            {
+                GtkFileChooser* pChooser = GTK_FILE_CHOOSER(pDialog);
+                char* pFilename = gtk_file_chooser_get_uri(pChooser);
+                boost::property_tree::ptree aValues;
+                aValues.put("type", "picture");
+                aValues.put("changed", pFilename);
+                std::stringstream aStream;
+                boost::property_tree::write_json(aStream, aValues);
+                std::string aJson = aStream.str();
+                lok_doc_view_send_content_control_event(pDocView, 
aJson.c_str());
+
+                g_free(pFilename);
+            }
+            gtk_widget_destroy(pDialog);
+        }
         g_signal_emit(pCallback->m_pDocView, 
doc_view_signals[CONTENT_CONTROL], 0,
                       pCallback->m_aPayload.c_str());
         gtk_widget_queue_draw(GTK_WIDGET(pDocView));
diff --git a/sw/source/uibase/uno/unotxdoc.cxx 
b/sw/source/uibase/uno/unotxdoc.cxx
index 877ebf67cb23..d2622e08b564 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -121,6 +121,7 @@
 #include <comphelper/storagehelper.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <unotools/saveopt.hxx>
+#include <sfx2/dispatch.hxx>
 #include <swruler.hxx>
 #include <docufld.hxx>
 
@@ -3365,24 +3366,6 @@ SwXTextDocument::getSearchResultRectangles(const char* 
pPayload)
 
 void SwXTextDocument::executeContentControlEvent(const StringMap& rArguments)
 {
-    SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
-    const SwPosition* pStart = pWrtShell->GetCursor()->Start();
-    SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
-    if (!pTextNode)
-    {
-        return;
-    }
-
-    SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->nContent.GetIndex(),
-                                                 RES_TXTATR_CONTENTCONTROL, 
SwTextNode::PARENT);
-    if (!pAttr)
-    {
-        return;
-    }
-
-    auto pTextContentControl = 
static_txtattr_cast<SwTextContentControl*>(pAttr);
-    const SwFormatContentControl& rFormatContentControl = 
pTextContentControl->GetContentControl();
-    std::shared_ptr<SwContentControl> pContentControl = 
rFormatContentControl.GetContentControl();
     auto it = rArguments.find("type");
     if (it == rArguments.end())
     {
@@ -3391,6 +3374,24 @@ void SwXTextDocument::executeContentControlEvent(const 
StringMap& rArguments)
 
     if (it->second == "drop-down")
     {
+        SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+        const SwPosition* pStart = pWrtShell->GetCursor()->Start();
+        SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
+        if (!pTextNode)
+        {
+            return;
+        }
+
+        SwTextAttr* pAttr = 
pTextNode->GetTextAttrAt(pStart->nContent.GetIndex(),
+                                                     
RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT);
+        if (!pAttr)
+        {
+            return;
+        }
+
+        auto pTextContentControl = 
static_txtattr_cast<SwTextContentControl*>(pAttr);
+        const SwFormatContentControl& rFormatContentControl = 
pTextContentControl->GetContentControl();
+        std::shared_ptr<SwContentControl> pContentControl = 
rFormatContentControl.GetContentControl();
         if (!pContentControl->HasListItems())
         {
             return;
@@ -3406,6 +3407,25 @@ void SwXTextDocument::executeContentControlEvent(const 
StringMap& rArguments)
         pContentControl->SetSelectedListItem(nSelection);
         pWrtShell->GotoContentControl(rFormatContentControl);
     }
+    else if (it->second == "picture")
+    {
+        it = rArguments.find("changed");
+        if (it == rArguments.end())
+        {
+            return;
+        }
+
+        SwView* pView = m_pDocShell->GetView();
+        if (!pView)
+        {
+            return;
+        }
+
+        // The current placeholder is selected, so this will replace, not 
insert.
+        SfxStringItem aItem(SID_INSERT_GRAPHIC, it->second);
+        pView->GetViewFrame()->GetDispatcher()->ExecuteList(SID_INSERT_GRAPHIC,
+                                                            
SfxCallMode::SYNCHRON, { &aItem });
+    }
 }
 
 int SwXTextDocument::getPart()
diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx 
b/sw/source/uibase/wrtsh/wrtsh3.cxx
index 978f95397b52..fcb123662bcf 100644
--- a/sw/source/uibase/wrtsh/wrtsh3.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh3.cxx
@@ -29,6 +29,9 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <osl/diagnose.h>
 #include <sfx2/dispatch.hxx>
+#include <comphelper/lok.hxx>
+#include <tools/json_writer.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include <swmodule.hxx>
 #include <wrtsh.hxx>
@@ -100,8 +103,19 @@ bool SwWrtShell::GotoContentControl(const 
SwFormatContentControl& rContentContro
         {
             // Replace the placeholder image with a real one.
             GetView().StopShellTimer();
-            
GetView().GetViewFrame()->GetDispatcher()->Execute(SID_CHANGE_PICTURE,
-                                                               
SfxCallMode::SYNCHRON);
+            if (comphelper::LibreOfficeKit::isActive())
+            {
+                tools::JsonWriter aJson;
+                aJson.put("action", "change-picture");
+                std::unique_ptr<char, o3tl::free_delete> 
pJson(aJson.extractData());
+                
GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL,
+                                                              pJson.get());
+            }
+            else
+            {
+                
GetView().GetViewFrame()->GetDispatcher()->Execute(SID_CHANGE_PICTURE,
+                                                                   
SfxCallMode::SYNCHRON);
+            }
             pContentControl->SetShowingPlaceHolder(false);
         }
         return true;

Reply via email to