[Libreoffice-commits] online.git: bundled/include common/Protocol.cpp kit/ChildSession.cpp kit/ChildSession.hpp loleaflet/src test/WhiteBoxTests.cpp wsd/ClientSession.cpp

Pranav Kant pranavk at collabora.co.uk
Thu Feb 8 08:47:28 UTC 2018


 bundled/include/LibreOfficeKit/LibreOfficeKit.h      |    5 +
 bundled/include/LibreOfficeKit/LibreOfficeKit.hxx    |   11 ++++
 bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h |   48 +++++++++++++++++--
 common/Protocol.cpp                                  |    2 
 kit/ChildSession.cpp                                 |   27 ++++++++++
 kit/ChildSession.hpp                                 |    1 
 loleaflet/src/map/handler/Map.Keyboard.js            |   15 +++--
 test/WhiteBoxTests.cpp                               |    3 +
 wsd/ClientSession.cpp                                |    1 
 9 files changed, 102 insertions(+), 11 deletions(-)

New commits:
commit ad1da235d3c7ac893fc7c0d0369b4b7b3ed29db6
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu Feb 8 00:00:45 2018 +0530

    IME support
    
    Dialogs still need to be adapted to this. Only works for documents as of
    now.
    
    Change-Id: I0fb1114e279a9e563943f3f65dd5a577523e9841

diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/bundled/include/LibreOfficeKit/LibreOfficeKit.h
index d42bd343..ebc112fb 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.h
@@ -300,6 +300,11 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::setViewLanguage().
     void (*setViewLanguage) (LibreOfficeKitDocument* pThis, int nId, const char* language);
 
+    /// @see lok::Document::postExtTextInputEvent
+    void (*postExtTextInputEvent) (LibreOfficeKitDocument* pThis,
+                                   int nType,
+                                   const char* pText);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
index 310b9cfc..09835608 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -537,6 +537,17 @@ public:
         mpDoc->pClass->setViewLanguage(mpDoc, nId, language);
     }
 
+    /**
+     * Post the text input from external input window, like IME
+     *
+     * @param nType see LibreOfficeKitExtTextInputType
+     * @param pText Text for LOK_EXT_TEXTINPUT
+     */
+    void postExtTextInputEvent(int nType, const char* pText)
+    {
+        mpDoc->pClass->postExtTextInputEvent(mpDoc, nType, pText);
+    }
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
index f14ce4d3..ccbc3b96 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -267,6 +267,11 @@ typedef enum
     /**
      * The size and/or the position of the cell cursor changed.
      *
+     * Payload format: "x, y, width, height, column, row", where the first
+     * 4 numbers are document coordinates, in twips, and the last 2 are table
+     * coordinates starting from 0.
+     * When the cursor is not shown the payload format is the "EMPTY" string.
+     *
      * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
      */
     LOK_CALLBACK_CELL_CURSOR = 17,
@@ -509,11 +514,12 @@ typedef enum
      * The column/row header is no more valid because of a column/row insertion
      * or a similar event. Clients must query a new column/row header set.
      *
-     * The payload says if we are invalidating a row or column header.
+     * The payload says if we are invalidating a row or column header. So,
+     * payload values can be: "row", "column", "all".
      */
     LOK_CALLBACK_INVALIDATE_HEADER = 33,
     /**
-     * The text content of the address field in Calc.
+     * The text content of the address field in Calc. Eg: "A7"
      */
     LOK_CALLBACK_CELL_ADDRESS = 34,
     /**
@@ -534,7 +540,32 @@ typedef enum
      */
     LOK_CALLBACK_RULER_UPDATE = 35,
     /**
-     * Dialog invalidation
+     * Window related callbacks are emitted under this category. It includes
+     * external windows like dialogs, autopopups for now.
+     *
+     * The payload format is:
+     *
+     * {
+     *    "id": "unique integer id of the dialog",
+     *    "action": "<see below>",
+     *    "type": "<see below>"
+     *    "rectangle": "x, y, width, height"
+     * }
+     *
+     * "type" tells the type of the window the action is associated with
+     *  - "dialog" - window is a dialog
+     *  - "child" - window is a floating window (combo boxes, etc.)
+     *
+     * "action" can take following values:
+     * - "created" - window is created in the backend, client can render it now
+     * - "title_changed" - window's title is changed
+     * - "size_changed" - window's size is changed
+     * - "invalidate" - the area as described by "rectangle" is invalidated
+     *    Clients must request the new area
+     * - "cursor_invalidate" - cursor is invalidated. New position is in "rectangle"
+     * - "cursor_visible" - cursor visible status is changed. Status is availabe
+     *    in "visible" field
+     * - "close" - window is closed
      */
     LOK_CALLBACK_WINDOW = 36,
 }
@@ -551,6 +582,17 @@ LibreOfficeKitKeyEventType;
 
 typedef enum
 {
+    /// cf. SalEvent::ExtTextInput
+    LOK_EXT_TEXTINPUT,
+    /// cf. SalEvent::ExtTextInputPos
+    LOK_EXT_TEXTINPUT_POS,
+    /// cf. SalEvent::EndExtTextInput
+    LOK_EXT_TEXTINPUT_END
+}
+LibreOfficeKitExtTextInputType;
+
+typedef enum
+{
     /// A pressed gesture has started.
     LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
     /// A pressed gesture has finished.
diff --git a/common/Protocol.cpp b/common/Protocol.cpp
index 6ab965e1..9aa4a230 100644
--- a/common/Protocol.cpp
+++ b/common/Protocol.cpp
@@ -134,7 +134,7 @@ namespace LOOLProtocol
 
     bool getTokenString(const std::string& token, const std::string& name, std::string& value)
     {
-        if (token.size() > (name.size() + 1) &&
+        if (token.size() >= (name.size() + 1) &&
             token.compare(0, name.size(), name) == 0 &&
             token[name.size()] == '=')
         {
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 9c09e4ba..efac21b3 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -227,6 +227,7 @@ bool ChildSession::_handleInput(const char *buffer, int length)
                tokens[0] == "paste" ||
                tokens[0] == "insertfile" ||
                tokens[0] == "key" ||
+               tokens[0] == "textinput" ||
                tokens[0] == "windowkey" ||
                tokens[0] == "mouse" ||
                tokens[0] == "windowmouse" ||
@@ -275,6 +276,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
         {
             return keyEvent(buffer, length, tokens, LokEventTargetEnum::Document);
         }
+        else if (tokens[0] == "textinput")
+        {
+            return extTextInputEvent(buffer, length, tokens);
+        }
         else if (tokens[0] == "windowkey")
         {
             return keyEvent(buffer, length, tokens, LokEventTargetEnum::Window);
@@ -763,6 +768,28 @@ bool ChildSession::insertFile(const char* /*buffer*/, int /*length*/, const std:
     return true;
 }
 
+bool ChildSession::extTextInputEvent(const char* /*buffer*/, int /*length*/,
+                                     const std::vector<std::string>& tokens)
+{
+    int type;
+    std::string text;
+    if (tokens.size() < 3 ||
+        !getTokenKeyword(tokens[1], "type",
+                        {{"input", LOK_EXT_TEXTINPUT}, {"end", LOK_EXT_TEXTINPUT_END}},
+                         type) ||
+        !getTokenString(tokens[2], "text", text))
+    {
+        sendTextFrame("error: cmd=" + std::string(tokens[0]) + " kind=syntax");
+        return false;
+    }
+
+    std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
+    getLOKitDocument()->setView(_viewId);
+    getLOKitDocument()->postExtTextInputEvent(type, text.c_str());
+
+    return true;
+}
+
 bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/,
                             const std::vector<std::string>& tokens,
                             const LokEventTargetEnum target)
diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp
index 1c03f550..093ca4e6 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -188,6 +188,7 @@ private:
     bool paste(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool insertFile(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool keyEvent(const char* buffer, int length, const std::vector<std::string>& tokens, const LokEventTargetEnum target);
+    bool extTextInputEvent(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens);
     bool dialogKeyEvent(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool mouseEvent(const char* buffer, int length, const std::vector<std::string>& tokens, const LokEventTargetEnum target);
     bool unoCommand(const char* buffer, int length, const std::vector<std::string>& tokens);
diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js
index 053390a6..a707a710 100644
--- a/loleaflet/src/map/handler/Map.Keyboard.js
+++ b/loleaflet/src/map/handler/Map.Keyboard.js
@@ -294,15 +294,18 @@ L.Map.Keyboard = L.Handler.extend({
 
 		if (e.type === 'compositionstart' || e.type === 'compositionupdate') {
 			this._isComposing = true; // we are starting composing with IME
+			var txt = '';
+			for (var i = 0; i < e.originalEvent.data.length; i++) {
+				txt += e.originalEvent.data[i];
+			}
+			if (txt) {
+				this._map._socket.sendMessage('textinput type=input text=' + txt);
+			}
 		}
 
 		if (e.type === 'compositionend') {
 			this._isComposing = false; // stop of composing with IME
 			// get the composited char codes
-			var compCharCodes = [];
-			for (var i = 0; i < e.originalEvent.data.length; i++) {
-				compCharCodes.push(e.originalEvent.data[i].charCodeAt());
-			}
 			// clear the input now - best to do this ASAP so the input
 			// is clear for the next word
 			this._map._textArea.value = '';
@@ -350,9 +353,7 @@ L.Map.Keyboard = L.Handler.extend({
 				}
 				if (e.type === 'compositionend') {
 					// Set all keycodes to zero
-					for (var idx = 0; i < compCharCodes.length; ++i) {
-						postEventFn.call(eventObject, 'input', compCharCodes[idx], 0);
-					}
+					this._map._socket.sendMessage('textinput type=end text=void');
 				} else {
 					postEventFn.call(eventObject, 'input', charCode, unoKeyCode);
 				}
diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp
index 6099839c..cd4b5ca4 100644
--- a/test/WhiteBoxTests.cpp
+++ b/test/WhiteBoxTests.cpp
@@ -58,6 +58,9 @@ void WhiteBoxTests::testLOOLProtocolFunctions()
     CPPUNIT_ASSERT(LOOLProtocol::getTokenString("bar=hello-sailor", "bar", bar));
     CPPUNIT_ASSERT_EQUAL(std::string("hello-sailor"), bar);
 
+    CPPUNIT_ASSERT(LOOLProtocol::getTokenString("bar=", "bar", bar));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), bar);
+
     int mumble;
     std::map<std::string, int> map { { "hello", 1 }, { "goodbye", 2 }, { "adieu", 3 } };
 
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 1b98b4ec..47e2f631 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -136,6 +136,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
              tokens[0] != "paste" &&
              tokens[0] != "insertfile" &&
              tokens[0] != "key" &&
+             tokens[0] != "textinput" &&
              tokens[0] != "windowkey" &&
              tokens[0] != "mouse" &&
              tokens[0] != "windowmouse" &&


More information about the Libreoffice-commits mailing list