[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 14 commits - desktop/qa desktop/source include/LibreOfficeKit include/svx include/vcl libreofficekit/source sfx2/source svx/sdi sw/inc sw/qa sw/sdi sw/source

Tamás Zolnai (via logerrit) logerrit at kemper.freedesktop.org
Sun May 24 15:58:02 UTC 2020


 desktop/qa/desktop_lib/test_desktop_lib.cxx                           |    3 
 desktop/source/lib/init.cxx                                           |   33 +
 include/LibreOfficeKit/LibreOfficeKit.h                               |    4 
 include/LibreOfficeKit/LibreOfficeKit.hxx                             |   10 
 include/LibreOfficeKit/LibreOfficeKitEnums.h                          |   37 +
 include/svx/svxids.hrc                                                |    3 
 include/vcl/ITiledRenderable.hxx                                      |   11 
 libreofficekit/source/gtk/lokdocview.cxx                              |    2 
 sfx2/source/view/viewsh.cxx                                           |    5 
 svx/sdi/svx.sdi                                                       |   19 
 sw/inc/unotxdoc.hxx                                                   |    3 
 sw/qa/extras/tiledrendering/data/drop_down_form_field.odt             |binary
 sw/qa/extras/tiledrendering/data/drop_down_form_field2.odt            |binary
 sw/qa/extras/tiledrendering/data/drop_down_form_field_noitem.odt      |binary
 sw/qa/extras/tiledrendering/data/drop_down_form_field_noselection.odt |binary
 sw/qa/extras/tiledrendering/tiledrendering.cxx                        |  218 ++++++++++
 sw/sdi/_viewsh.sdi                                                    |    4 
 sw/source/core/crsr/FormFieldButton.cxx                               |    6 
 sw/source/core/crsr/bookmrk.cxx                                       |   87 +++
 sw/source/core/doc/docbm.cxx                                          |    3 
 sw/source/core/inc/bookmrk.hxx                                        |    9 
 sw/source/uibase/uiview/viewtab.cxx                                   |   71 +++
 sw/source/uibase/uno/unotxdoc.cxx                                     |   36 +
 23 files changed, 550 insertions(+), 14 deletions(-)

New commits:
commit f3dbf1a994b719baea659e53d5d5ab9658a4e3d2
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri May 22 11:39:12 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:37:28 2020 +0200

    lok: MSForms: update callback's documentation.
    
    Change-Id: I1bf41986f63a18abada7d268dc610df24b4c1144
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94661
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 50533ce1b373..9a1ca4c2acf6 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -737,7 +737,12 @@ typedef enum
      * {
      *      "action": "show",
      *      "type": "drop-down",
-     *      "textArea": "1418, 3906, 3111, 919"
+     *      "textArea": "1418, 3906, 3111, 919",
+     *      "params": {
+     *           "items": ["January", "February", "July"],
+     *           "selected": "2",
+     *           "placeholder": "No items specified"
+     *      }
      * }
      *
      * or
commit b08ae3878d24d378fb6c4b270091d95163578d2f
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri May 15 10:30:51 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:37:18 2020 +0200

    MSForms: fix rendering of form field button.
    
    It's not enough to check the paint area. because it's
    in logic units, which does not change by zooming.
    
    Change-Id: I9ee51c03e7edc2c70d91d6ef6dbaaae8c2c7beff
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94400
    Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/source/core/crsr/FormFieldButton.cxx b/sw/source/core/crsr/FormFieldButton.cxx
index 162d03f43224..43d8ff6e07e9 100644
--- a/sw/source/core/crsr/FormFieldButton.cxx
+++ b/sw/source/core/crsr/FormFieldButton.cxx
@@ -49,7 +49,11 @@ void FormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
     // Then extend the size with the button area
     aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
 
-    SetPosSizePixel(aBoxPos, aBoxSize);
+    if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel())
+    {
+        SetPosSizePixel(aBoxPos, aBoxSize);
+        Invalidate();
+    }
 }
 
 void FormFieldButton::MouseButtonUp(const MouseEvent&)
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 237b5851edd3..dc36defa200d 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -659,19 +659,11 @@ namespace sw { namespace mark
 
     void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
     {
-        if(m_aPortionPaintArea == rPortionPaintArea &&
-           m_pButton && m_pButton->IsVisible())
-        {
-            SendLOKMessage("show");
-            return;
-        }
-
         m_aPortionPaintArea = rPortionPaintArea;
         if(m_pButton)
         {
             m_pButton->Show();
             m_pButton->CalcPosAndSize(m_aPortionPaintArea);
-            m_pButton->Invalidate();
             SendLOKMessage("show");
         }
     }
commit 38376e56e1b66fa0d279467aab2b4467540c0bf0
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon May 11 13:12:44 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:37:09 2020 +0200

    lok: MSForms: send also the placeholder text.
    
    Change-Id: I5cce5af22f56079e840707cfffb01785d7a15c6a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93960
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index bad279488859..8a46bcdf4494 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -2586,6 +2586,9 @@ void SwTiledRenderingTest::testDropDownFormFieldButton()
 
         OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
         CPPUNIT_ASSERT_EQUAL(OString("1"), sSelected);
+
+        OString sPlaceholder = aTree.get_child("params").get_child("placeholderText").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("No Item specified"), sPlaceholder);
     }
 
     // Move the cursor back so the button becomes hidden.
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index b82bfdfcd694..237b5851edd3 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -45,6 +45,7 @@
 #include <wrtsh.hxx>
 #include <rtl/strbuf.hxx>
 #include <sfx2/lokhelper.hxx>
+#include <strings.hrc>
 
 using namespace ::sw::mark;
 using namespace ::com::sun::star;
@@ -719,7 +720,10 @@ namespace sw { namespace mark
                 {
                     pSelectedItemIter->second >>= nSelection;
                 }
-                sPayload.append("\"selected\": \"" + OString::number(nSelection) + "\"}}");
+                sPayload.append("\"selected\": \"" + OString::number(nSelection) + "\", ");
+
+                // Placeholder text
+                sPayload.append("\"placeholderText\": \"" + OUStringToOString(SwResId(STR_DROP_DOWN_EMPTY_LIST), RTL_TEXTENCODING_UTF8) + "\"}}");
             }
             else
             {
commit 7153ebd3dd1ee0be9f2f2d9c6ca05207cbfeab38
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat May 9 13:35:16 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:37:02 2020 +0200

    lok: MSForms: test & fix two corner cases of drop-down field.
    
    Change-Id: I2c54e2e2a94d15d42b23e04a896211936e9e1852
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93845
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/qa/extras/tiledrendering/data/drop_down_form_field_noitem.odt b/sw/qa/extras/tiledrendering/data/drop_down_form_field_noitem.odt
new file mode 100644
index 000000000000..c0b703320bec
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/drop_down_form_field_noitem.odt differ
diff --git a/sw/qa/extras/tiledrendering/data/drop_down_form_field_noselection.odt b/sw/qa/extras/tiledrendering/data/drop_down_form_field_noselection.odt
new file mode 100644
index 000000000000..0c433c64707b
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/drop_down_form_field_noselection.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 8b80fc4e244d..bad279488859 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -128,6 +128,8 @@ public:
     void testFieldmark();
     void testDropDownFormFieldButton();
     void testDropDownFormFieldButtonEditing();
+    void testDropDownFormFieldButtonNoSelection();
+    void testDropDownFormFieldButtonNoItem();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -194,6 +196,8 @@ public:
     CPPUNIT_TEST(testFieldmark);
     CPPUNIT_TEST(testDropDownFormFieldButton);
     CPPUNIT_TEST(testDropDownFormFieldButtonEditing);
+    CPPUNIT_TEST(testDropDownFormFieldButtonNoSelection);
+    CPPUNIT_TEST(testDropDownFormFieldButtonNoItem);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2658,6 +2662,79 @@ void SwTiledRenderingTest::testDropDownFormFieldButtonEditing()
     }
 }
 
+void SwTiledRenderingTest::testDropDownFormFieldButtonNoSelection()
+{
+    SwXTextDocument* pXTextDocument = createDoc("drop_down_form_field_noselection.odt");
+    pXTextDocument->setClientVisibleArea(tools::Rectangle(0, 0, 10000, 4000));
+
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+
+    // Move the cursor to trigger displaying of the field button.
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+    CPPUNIT_ASSERT(m_aFormFieldButton.isEmpty());
+
+    // Do a tile rendering to trigger the button message with a valid text area
+    size_t nCanvasWidth = 1024;
+    size_t nCanvasHeight = 512;
+    std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+    ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+    pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+    pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+                                                    Fraction(1.0), Point(), aPixmap.data());
+    pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0,
+                              /*nTilePosY=*/0, /*nTileWidth=*/10000, /*nTileHeight=*/4000);
+
+    // None of the items is selected
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("-1"), sSelected);
+    }
+}
+
+void SwTiledRenderingTest::testDropDownFormFieldButtonNoItem()
+{
+    SwXTextDocument* pXTextDocument = createDoc("drop_down_form_field_noitem.odt");
+    pXTextDocument->setClientVisibleArea(tools::Rectangle(0, 0, 10000, 4000));
+
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+
+    // Move the cursor to trigger displaying of the field button.
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+    CPPUNIT_ASSERT(m_aFormFieldButton.isEmpty());
+
+    // Do a tile rendering to trigger the button message with a valid text area
+    size_t nCanvasWidth = 1024;
+    size_t nCanvasHeight = 512;
+    std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+    ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+    pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+    pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+                                                    Fraction(1.0), Point(), aPixmap.data());
+    pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0,
+                              /*nTilePosY=*/0, /*nTileWidth=*/10000, /*nTileHeight=*/4000);
+
+    // There is not item specified for the field
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        boost::property_tree::ptree aItems = aTree.get_child("params").get_child("items");
+        CPPUNIT_ASSERT_EQUAL(size_t(0), aItems.size());
+
+        OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("-1"), sSelected);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 189bff97e1d9..b82bfdfcd694 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -714,12 +714,12 @@ namespace sw { namespace mark
                 // Selected item
                 OUString sResultKey = ODF_FORMDROPDOWN_RESULT;
                 auto pSelectedItemIter = pParameters->find(sResultKey);
+                sal_Int32 nSelection = -1;
                 if (pSelectedItemIter != pParameters->end())
                 {
-                    sal_Int32 nSelection = -1;
                     pSelectedItemIter->second >>= nSelection;
-                    sPayload.append("\"selected\": \"" + OString::number(nSelection) + "\"}}");
                 }
+                sPayload.append("\"selected\": \"" + OString::number(nSelection) + "\"}}");
             }
             else
             {
commit ef80910ea92b9d9650a57d81e99d5a60ab65325a
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 12:25:51 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:55 2020 +0200

    lok: MSForms: add a test case about editing drop down form field.
    
    Change-Id: I926b322d3af3047fc72c6ee9b923bc4435111328
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93661
    Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/qa/extras/tiledrendering/data/drop_down_form_field2.odt b/sw/qa/extras/tiledrendering/data/drop_down_form_field2.odt
new file mode 100644
index 000000000000..7793aff4e91b
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/drop_down_form_field2.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 49d6af851deb..8b80fc4e244d 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -48,6 +48,7 @@
 #include <svx/svxids.hrc>
 #include <flddat.hxx>
 #include <basesh.hxx>
+#include <vcl/ITiledRenderable.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/extras/tiledrendering/data/";
 
@@ -126,6 +127,7 @@ public:
     void testHyperlink();
     void testFieldmark();
     void testDropDownFormFieldButton();
+    void testDropDownFormFieldButtonEditing();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -191,6 +193,7 @@ public:
     CPPUNIT_TEST(testHyperlink);
     CPPUNIT_TEST(testFieldmark);
     CPPUNIT_TEST(testDropDownFormFieldButton);
+    CPPUNIT_TEST(testDropDownFormFieldButtonEditing);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2540,7 +2543,7 @@ void SwTiledRenderingTest::testDropDownFormFieldButton()
     pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
     CPPUNIT_ASSERT(m_aFormFieldButton.isEmpty());
 
-    // Do a tile rendering to trigger the button message with a valide text area
+    // Do a tile rendering to trigger the button message with a valid text area
     size_t nCanvasWidth = 1024;
     size_t nCanvasHeight = 512;
     std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
@@ -2598,6 +2601,63 @@ void SwTiledRenderingTest::testDropDownFormFieldButton()
     }
 }
 
+void SwTiledRenderingTest::testDropDownFormFieldButtonEditing()
+{
+    SwXTextDocument* pXTextDocument = createDoc("drop_down_form_field2.odt");
+    pXTextDocument->setClientVisibleArea(tools::Rectangle(0, 0, 10000, 4000));
+
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+
+    // Move the cursor to trigger displaying of the field button.
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+    CPPUNIT_ASSERT(m_aFormFieldButton.isEmpty());
+
+    // Do a tile rendering to trigger the button message with a valid text area
+    size_t nCanvasWidth = 1024;
+    size_t nCanvasHeight = 512;
+    std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+    ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+    pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+    pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+                                                    Fraction(1.0), Point(), aPixmap.data());
+    pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0,
+                              /*nTilePosY=*/0, /*nTileWidth=*/10000, /*nTileHeight=*/4000);
+
+    // The item with the index '1' is selected by default
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("1"), sSelected);
+    }
+    m_aFormFieldButton = "";
+
+    // Trigger a form field event to select a different item.
+    vcl::ITiledRenderable::StringMap aArguments;
+    aArguments["type"] = "drop-down";
+    aArguments["cmd"] = "selected";
+    aArguments["data"] = "3";
+    pXTextDocument->executeFromFieldEvent(aArguments);
+
+    // Do a tile rendering to trigger the button message.
+    pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0,
+                              /*nTilePosY=*/0, /*nTileWidth=*/10000, /*nTileHeight=*/4000);
+
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("3"), sSelected);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 2e30efa390f6c89962b394d05ad081fe5db8da76
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri May 8 15:26:57 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:47 2020 +0200

    lok: MSForms: send button message also when paint area is not changing.
    
    We can filter out duplicated messages with storing the last
    message.
    Ignoring messages with the same paint area is a problem, if
    we change the drop down field content to a new item with
    the same size.
    
    Change-Id: Ie2e0bab445eb0e6e5b9b25846adbd79af55e7816
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93732
    Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index f88e916c372e..189bff97e1d9 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -660,7 +660,10 @@ namespace sw { namespace mark
     {
         if(m_aPortionPaintArea == rPortionPaintArea &&
            m_pButton && m_pButton->IsVisible())
+        {
+            SendLOKMessage("show");
             return;
+        }
 
         m_aPortionPaintArea = rPortionPaintArea;
         if(m_pButton)
@@ -722,7 +725,10 @@ namespace sw { namespace mark
             {
                 sPayload = "{\"action\": \"hide\", \"type\": \"drop-down\"}";
             }
-            pEditWin->GetView().GetWrtShell().GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_FORM_FIELD_BUTTON, sPayload.toString().getStr());
+            if (sPayload.toString() != m_sLastSentLOKMsg) {
+                m_sLastSentLOKMsg = sPayload.toString();
+                pEditWin->GetView().GetWrtShell().GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_FORM_FIELD_BUTTON, m_sLastSentLOKMsg.getStr());
+            }
         }
     }
 
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 67c0292d1e9f..f0f81bf32c3c 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -304,6 +304,7 @@ namespace sw {
 
         private:
             SwRect m_aPortionPaintArea;
+            OString m_sLastSentLOKMsg;
         };
 
         /// Fieldmark representing a date form field.
commit ba170eab2f0b3472e4504c7153229d0edb42189d
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 17:28:02 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:40 2020 +0200

    lok: MSForms: fix field activation for multiple fields.
    
    First hide hide the button of the previously active field
    and show the new button afterwards.
    
    Change-Id: I6de668f25a18f8c1d3dbf66beb357f089b51ae0b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93664
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index bab44aa4a5f5..5e5063b72f92 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1419,7 +1419,6 @@ namespace sw { namespace mark
             if (m_pLastActiveFieldmark != pFieldBM)
             {
                 FieldmarkWithDropDownButton& rFormField = dynamic_cast<FieldmarkWithDropDownButton&>(*pFieldBM);
-                rFormField.ShowButton(&rEditWin);
                 pNewActiveFieldmark = &rFormField;
             }
             else
@@ -1432,6 +1431,8 @@ namespace sw { namespace mark
         {
             ClearFieldActivation();
             m_pLastActiveFieldmark = pNewActiveFieldmark;
+            if(pNewActiveFieldmark)
+                pNewActiveFieldmark->ShowButton(&rEditWin);
         }
     }
 
commit 06cf3861c39dd9ea28d841484b565c9aabf7dd5f
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 16:57:45 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:29 2020 +0200

    lok: MSForms: fix editing of drop-down field.
    
    When cursor is on the left side of the form field.
    
    Change-Id: I8587c477b6177e9309349afbbfc70979b4338275
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93663
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 8a26bc1c1cb5..8829dc98abbf 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3410,16 +3410,16 @@ void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
                 {
                     --aPos.nContent;
                     pFieldBM = pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
-                    if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
+                }
+                if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
+                {
+                    if (nSelection >= 0)
                     {
-                        if (nSelection >= 0)
-                        {
-                            OUString sKey = ODF_FORMDROPDOWN_RESULT;
-                            (*pFieldBM->GetParameters())[sKey] <<= nSelection;
-                            pFieldBM->Invalidate();
-                            pDocShell->GetWrtShell()->SetModified();
-                            pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
-                        }
+                        OUString sKey = ODF_FORMDROPDOWN_RESULT;
+                        (*pFieldBM->GetParameters())[sKey] <<= nSelection;
+                        pFieldBM->Invalidate();
+                        pDocShell->GetWrtShell()->SetModified();
+                        pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
                     }
                 }
             }
commit b91ed24ffe63b58ae618405ed891d6a46d1f2f70
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 12:45:48 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:18 2020 +0200

    lok: MSForms: disable form field messages on mobile.
    
    Change-Id: I466c457fb0a2cbca3e7480fe8fde9833d9c35b63
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93662
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 0dc8597d51a2..f88e916c372e 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -44,6 +44,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <wrtsh.hxx>
 #include <rtl/strbuf.hxx>
+#include <sfx2/lokhelper.hxx>
 
 using namespace ::sw::mark;
 using namespace ::com::sun::star;
@@ -673,7 +674,7 @@ namespace sw { namespace mark
 
     void DropDownFieldmark::SendLOKMessage(const OString& sAction)
     {
-        if (comphelper::LibreOfficeKit::isActive())
+        if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isMobilePhone(SfxLokHelper::getView()))
         {
             if (!m_pButton)
               return;
commit c1644884489bfbdd29a453449cab062f889c6411
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 12:08:39 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:36:06 2020 +0200

    lok: MSForms: dont send form field button data with empty text area.
    
    Change-Id: I88d793765b58a3c483aad51d1a0e2e9f0159d5f1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93660
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 2dba0378d009..49d6af851deb 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -2538,24 +2538,7 @@ void SwTiledRenderingTest::testDropDownFormFieldButton()
 
     // Move the cursor to trigger displaying of the field button.
     pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
-
-    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
-
-    // First we have a button with an empty text area.
-    {
-        std::stringstream aStream(m_aFormFieldButton.getStr());
-        boost::property_tree::ptree aTree;
-        boost::property_tree::read_json(aStream, aTree);
-
-        OString sAction = aTree.get_child("action").get_value<std::string>().c_str();
-        CPPUNIT_ASSERT_EQUAL(OString("show"), sAction);
-
-        OString sType = aTree.get_child("type").get_value<std::string>().c_str();
-        CPPUNIT_ASSERT_EQUAL(OString("drop-down"), sType);
-
-        OString sTextArea = aTree.get_child("textArea").get_value<std::string>().c_str();
-        CPPUNIT_ASSERT_EQUAL(OString("0, 0, -1, -1"), sTextArea);
-    }
+    CPPUNIT_ASSERT(m_aFormFieldButton.isEmpty());
 
     // Do a tile rendering to trigger the button message with a valide text area
     size_t nCanvasWidth = 1024;
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 1934654d352e..0dc8597d51a2 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -685,6 +685,9 @@ namespace sw { namespace mark
             OStringBuffer sPayload;
             if (sAction == "show")
             {
+                if(m_aPortionPaintArea.IsEmpty())
+                    return;
+
                 sPayload = OStringLiteral("{\"action\": \"show\","
                            " \"type\": \"drop-down\", \"textArea\": \"") +
                            m_aPortionPaintArea.SVRect().toString() + "\",";
commit ee545aa5afb93fd227d43fcbad40fd1efcf14ff5
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed May 6 14:33:10 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:35:34 2020 +0200

    lok: MSForms: Handle event about item selection of a drop-down field.
    
    Change-Id: I095013097348c98361b6614e4ddf1e9029923c7f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93659
    Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 35314f0da0f3..a8a9a9d8b7ea 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2879,10 +2879,11 @@ void DesktopLOKTest::testABI()
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(58), offsetof(struct _LibreOfficeKitDocumentClass, paintWindowForView));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(59), offsetof(struct _LibreOfficeKitDocumentClass, completeFunction));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(60), offsetof(struct _LibreOfficeKitDocumentClass, setWindowTextSelection));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(61), offsetof(struct _LibreOfficeKitDocumentClass, sendFormFieldEvent));
 
     // Extending is fine, update this, and add new assert for the offsetof the
     // new method
-    CPPUNIT_ASSERT_EQUAL(documentClassOffset(61), sizeof(struct _LibreOfficeKitDocumentClass));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(62), sizeof(struct _LibreOfficeKitDocumentClass));
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 6f563d1cf22c..d8f973dc3d83 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1143,6 +1143,10 @@ static void doc_resizeWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowI
                              const int nWidth, const int nHeight);
 
 static void doc_completeFunction(LibreOfficeKitDocument* pThis, int nIndex);
+
+
+static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis,
+                                   const char* pArguments);
 } // extern "C"
 
 namespace {
@@ -1257,6 +1261,8 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
         m_pDocumentClass->createViewWithOptions = doc_createViewWithOptions;
         m_pDocumentClass->completeFunction = doc_completeFunction;
 
+        m_pDocumentClass->sendFormFieldEvent = doc_sendFormFieldEvent;
+
         gDocumentClass = m_pDocumentClass;
     }
     pClass = m_pDocumentClass.get();
@@ -5540,6 +5546,33 @@ static void doc_completeFunction(LibreOfficeKitDocument* pThis, int nIndex)
     pDoc->completeFunction(nIndex);
 }
 
+
+static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pArguments)
+{
+    SolarMutexGuard aGuard;
+
+    // Supported in Writer only
+    if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT)
+            return;
+
+    StringMap aMap(jsonToStringMap(pArguments));
+    ITiledRenderable* pDoc = getTiledRenderable(pThis);
+    if (!pDoc)
+    {
+        SetLastExceptionMsg("Document doesn't support tiled rendering!");
+        return;
+    }
+
+    // Sanity check
+    if (aMap.find("type") == aMap.end() || aMap.find("cmd") == aMap.end())
+    {
+        SetLastExceptionMsg("Wrong arguments for sendFormFieldEvent!");
+        return;
+    }
+
+    pDoc->executeFromFieldEvent(aMap);
+}
+
 static char* lo_getError (LibreOfficeKit *pThis)
 {
     comphelper::ProfileZone aZone("lo_getError");
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 6203c11fb044..309744522004 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -446,6 +446,10 @@ struct _LibreOfficeKitDocumentClass
                                     int nX,
                                     int nY);
 
+    /// @see lok::Document::sendFormFieldEvent
+    void (*sendFormFieldEvent) (LibreOfficeKitDocument* pThis,
+                                const char* pArguments);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index cbb5a1d9d51a..8be29ff1e192 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -780,6 +780,16 @@ public:
         mpDoc->pClass->setWindowTextSelection(mpDoc, nWindowId, bSwap, nX, nY);
     }
 
+    /**
+     * Posts an event for the form field at the cursor position.
+     *
+     * @param pArguments arguments of the event.
+     */
+    void sendFormFieldEvent(const char* pArguments)
+    {
+        mpDoc->pClass->sendFormFieldEvent(mpDoc, pArguments);
+    }
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 163be5f55213..56922096d42b 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -44,6 +44,9 @@ namespace vcl
 class VCL_DLLPUBLIC ITiledRenderable
 {
 public:
+
+    typedef std::map<const OUString, OUString>  StringMap;
+
     virtual ~ITiledRenderable();
 
     /**
@@ -287,6 +290,14 @@ public:
     virtual void completeFunction(int /*nIndex*/)
     {
     }
+
+    /**
+     * Execute a form field event in the document.
+     * E.g. select an item from a drop down field's list.
+     */
+    virtual void executeFromFieldEvent(const StringMap&)
+    {
+    }
 };
 } // namespace vcl
 
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 4952c6fc9dd6..fb9c2fcc926e 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -444,6 +444,9 @@ public:
     /// @see vcl::ITiledRenderable::getPostIts().
     OUString getPostIts() override;
 
+    /// @see vcl::ITiledRenderable::executeFromFieldEvent().
+    virtual void executeFromFieldEvent(const StringMap& aArguments) override;
+
     // css::tiledrendering::XTiledRenderable
     virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
 
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 1d17782a7cb0..8a26bc1c1cb5 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -181,6 +181,7 @@
 #include <fchrfmt.hxx>
 #include <redline.hxx>
 #include <DocumentRedlineManager.hxx>
+#include <xmloff/odffields.hxx>
 
 #define TWIPS_PER_PIXEL 15
 
@@ -3391,6 +3392,41 @@ OUString SwXTextDocument::getPostIts()
     return OUString::fromUtf8(aStream.str().c_str());
 }
 
+void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
+{
+    auto aIter = aArguments.find("type");
+    if (aIter != aArguments.end() && aIter->second == "drop-down")
+    {
+        aIter = aArguments.find("cmd");
+        if (aIter != aArguments.end() && aIter->second == "selected")
+        {
+            aIter = aArguments.find("data");
+            if (aIter != aArguments.end())
+            {
+                sal_Int32 nSelection = aIter->second.toInt32();
+                SwPosition aPos(*pDocShell->GetWrtShell()->GetCursor()->GetPoint());
+                sw::mark::IFieldmark* pFieldBM = pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+                if ( !pFieldBM )
+                {
+                    --aPos.nContent;
+                    pFieldBM = pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+                    if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
+                    {
+                        if (nSelection >= 0)
+                        {
+                            OUString sKey = ODF_FORMDROPDOWN_RESULT;
+                            (*pFieldBM->GetParameters())[sKey] <<= nSelection;
+                            pFieldBM->Invalidate();
+                            pDocShell->GetWrtShell()->SetModified();
+                            pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
 int SwXTextDocument::getPart()
 {
     SolarMutexGuard aGuard;
commit a915465820067bb2fc0089fc642fdcc3161e98a0
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue May 5 14:36:16 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:34:09 2020 +0200

    lok: MSForms: Send also the drop down field params to the client code.
    
    Change-Id: Id42f428b7944d97d1b61a5b60d6e0807cb51cc95
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93658
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index f7d9c5fcf534..2dba0378d009 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -2582,6 +2582,20 @@ void SwTiledRenderingTest::testDropDownFormFieldButton()
 
         OString sTextArea = aTree.get_child("textArea").get_value<std::string>().c_str();
         CPPUNIT_ASSERT_EQUAL(OString("1538, 1418, 1026, 275"), sTextArea);
+
+        boost::property_tree::ptree aItems = aTree.get_child("params").get_child("items");
+        CPPUNIT_ASSERT_EQUAL(size_t(6), aItems.size());
+
+        OStringBuffer aItemList;
+        for (auto &item : aItems)
+        {
+            aItemList.append(item.second.get_value<std::string>().c_str());
+            aItemList.append(";");
+        }
+        CPPUNIT_ASSERT_EQUAL(OString("2019/2020;2020/2021;2021/2022;2022/2023;2023/2024;2024/2025;"), aItemList.toString());
+
+        OString sSelected = aTree.get_child("params").get_child("selected").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("1"), sSelected);
     }
 
     // Move the cursor back so the button becomes hidden.
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index a913e1835e8c..1934654d352e 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -43,6 +43,7 @@
 #include <view.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <wrtsh.hxx>
+#include <rtl/strbuf.hxx>
 
 using namespace ::sw::mark;
 using namespace ::com::sun::star;
@@ -681,18 +682,43 @@ namespace sw { namespace mark
             if (!pEditWin)
                 return;
 
-            OString sPayload;
+            OStringBuffer sPayload;
             if (sAction == "show")
             {
                 sPayload = OStringLiteral("{\"action\": \"show\","
                            " \"type\": \"drop-down\", \"textArea\": \"") +
-                           m_aPortionPaintArea.SVRect().toString() + "\"}";
+                           m_aPortionPaintArea.SVRect().toString() + "\",";
+                // Add field params to the message
+                sPayload.append(" \"params\": { \"items\": [");
+
+                // List items
+                auto pParameters = this->GetParameters();
+                auto pListEntriesIter = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
+                css::uno::Sequence<OUString> vListEntries;
+                if (pListEntriesIter != pParameters->end())
+                {
+                    pListEntriesIter->second >>= vListEntries;
+                    for (const OUString& sItem : std::as_const(vListEntries))
+                        sPayload.append("\"" + OUStringToOString(sItem, RTL_TEXTENCODING_UTF8) + "\", ");
+                    sPayload.setLength(sPayload.getLength() - 2);
+                }
+                sPayload.append("], ");
+
+                // Selected item
+                OUString sResultKey = ODF_FORMDROPDOWN_RESULT;
+                auto pSelectedItemIter = pParameters->find(sResultKey);
+                if (pSelectedItemIter != pParameters->end())
+                {
+                    sal_Int32 nSelection = -1;
+                    pSelectedItemIter->second >>= nSelection;
+                    sPayload.append("\"selected\": \"" + OString::number(nSelection) + "\"}}");
+                }
             }
             else
             {
                 sPayload = "{\"action\": \"hide\", \"type\": \"drop-down\"}";
             }
-            pEditWin->GetView().GetWrtShell().GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_FORM_FIELD_BUTTON, sPayload.getStr());
+            pEditWin->GetView().GetWrtShell().GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_FORM_FIELD_BUTTON, sPayload.toString().getStr());
         }
     }
 
commit 84550e7dd85afdbd90d2ff6b2ff445ca3bcb10a7
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Apr 28 15:51:02 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 17:33:56 2020 +0200

    lok: MSForms: Add callback for form field button.
    
    Show and hide the button and send the button area, where
    it should be displayed.
    
    Change-Id: I5922eb9f5e544483dd4efd12e4218d2e51270632
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93657
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 8291a845f281..50533ce1b373 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -726,6 +726,27 @@ typedef enum
      * Sends the tab stop list for the current of the current cursor position.
      */
     LOK_CALLBACK_TAB_STOP_LIST = 48,
+
+    /**
+     * Sends all informations for displaying form field button for a text based field.
+     *
+     * It contains the position where the frame with the button should be displayed and
+     * also contains all information that the popup window needs.
+     *
+     * The payload example:
+     * {
+     *      "action": "show",
+     *      "type": "drop-down",
+     *      "textArea": "1418, 3906, 3111, 919"
+     * }
+     *
+     * or
+     * {
+     *      "action": "hide",
+     *      "type": "drop-down"
+     * }
+     */
+    LOK_CALLBACK_FORM_FIELD_BUTTON = 49,
 }
 LibreOfficeKitCallbackType;
 
@@ -852,6 +873,8 @@ static inline const char* lokCallbackTypeToString(int nType)
         return "LOK_CALLBACK_CALC_FUNCTION_LIST";
     case LOK_CALLBACK_TAB_STOP_LIST:
         return "LOK_CALLBACK_TAB_STOP_LIST";
+    case LOK_CALLBACK_FORM_FIELD_BUTTON:
+        return "LOK_CALLBACK_FORM_FIELD_BUTTON";
     }
 
     assert(!"Unknown LibreOfficeKitCallbackType type.");
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 54da1a4ef738..88d54e6bf812 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1383,6 +1383,7 @@ callback (gpointer pData)
     case LOK_CALLBACK_JSDIALOG:
     case LOK_CALLBACK_CALC_FUNCTION_LIST:
     case LOK_CALLBACK_TAB_STOP_LIST:
+    case LOK_CALLBACK_FORM_FIELD_BUTTON:
     {
         // TODO: Implement me
         break;
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index bf14212fa289..962d94b46d51 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1462,7 +1462,10 @@ void SfxViewShell::registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCa
 
 void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const
 {
-    if (!comphelper::LibreOfficeKit::isActive() || comphelper::LibreOfficeKit::isTiledPainting())
+    if (!comphelper::LibreOfficeKit::isActive())
+        return;
+
+    if (comphelper::LibreOfficeKit::isTiledPainting() && nType != LOK_CALLBACK_FORM_FIELD_BUTTON)
         return;
 
     if (pImpl->m_bTiledSearching)
diff --git a/sw/qa/extras/tiledrendering/data/drop_down_form_field.odt b/sw/qa/extras/tiledrendering/data/drop_down_form_field.odt
new file mode 100644
index 000000000000..7793aff4e91b
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/drop_down_form_field.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 4dd2a681d42f..f7d9c5fcf534 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -125,6 +125,7 @@ public:
     void testRedlineNotificationDuringSave();
     void testHyperlink();
     void testFieldmark();
+    void testDropDownFormFieldButton();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -189,6 +190,7 @@ public:
     CPPUNIT_TEST(testRedlineNotificationDuringSave);
     CPPUNIT_TEST(testHyperlink);
     CPPUNIT_TEST(testFieldmark);
+    CPPUNIT_TEST(testDropDownFormFieldButton);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -209,6 +211,7 @@ private:
     int m_nTrackedChangeIndex;
     OString m_sHyperlinkText;
     OString m_sHyperlinkLink;
+    OString m_aFormFieldButton;
 };
 
 SwTiledRenderingTest::SwTiledRenderingTest()
@@ -353,6 +356,11 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
         }
     }
     break;
+    case LOK_CALLBACK_FORM_FIELD_BUTTON:
+    {
+        m_aFormFieldButton = OString(pPayload);
+    }
+    break;
     }
 }
 
@@ -2520,6 +2528,79 @@ void SwTiledRenderingTest::testFieldmark()
     createDoc("fieldmark.docx");
 }
 
+void SwTiledRenderingTest::testDropDownFormFieldButton()
+{
+    SwXTextDocument* pXTextDocument = createDoc("drop_down_form_field.odt");
+    pXTextDocument->setClientVisibleArea(tools::Rectangle(0, 0, 10000, 4000));
+
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+
+    // Move the cursor to trigger displaying of the field button.
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+
+    // First we have a button with an empty text area.
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sAction = aTree.get_child("action").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("show"), sAction);
+
+        OString sType = aTree.get_child("type").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("drop-down"), sType);
+
+        OString sTextArea = aTree.get_child("textArea").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("0, 0, -1, -1"), sTextArea);
+    }
+
+    // Do a tile rendering to trigger the button message with a valide text area
+    size_t nCanvasWidth = 1024;
+    size_t nCanvasHeight = 512;
+    std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+    ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+    pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+    pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+                                                    Fraction(1.0), Point(), aPixmap.data());
+    pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0,
+                              /*nTilePosY=*/0, /*nTileWidth=*/10000, /*nTileHeight=*/4000);
+
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sAction = aTree.get_child("action").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("show"), sAction);
+
+        OString sType = aTree.get_child("type").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("drop-down"), sType);
+
+        OString sTextArea = aTree.get_child("textArea").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("1538, 1418, 1026, 275"), sTextArea);
+    }
+
+    // Move the cursor back so the button becomes hidden.
+    pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+
+    CPPUNIT_ASSERT(!m_aFormFieldButton.isEmpty());
+    {
+        std::stringstream aStream(m_aFormFieldButton.getStr());
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        OString sAction = aTree.get_child("action").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("hide"), sAction);
+
+        OString sType = aTree.get_child("type").get_value<std::string>().c_str();
+        CPPUNIT_ASSERT_EQUAL(OString("drop-down"), sType);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index a16713dc295d..a913e1835e8c 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -39,6 +39,10 @@
 #include <DateFormFieldButton.hxx>
 #include <DropDownFormFieldButton.hxx>
 #include <DocumentContentOperationsManager.hxx>
+#include <comphelper/lok.hxx>
+#include <view.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <wrtsh.hxx>
 
 using namespace ::sw::mark;
 using namespace ::com::sun::star;
@@ -623,6 +627,7 @@ namespace sw { namespace mark
 
     DropDownFieldmark::~DropDownFieldmark()
     {
+        SendLOKMessage("hide");
     }
 
     void DropDownFieldmark::ShowButton(SwEditWin* pEditWin)
@@ -633,9 +638,22 @@ namespace sw { namespace mark
                 m_pButton = VclPtr<DropDownFormFieldButton>::Create(pEditWin, *this);
             m_pButton->CalcPosAndSize(m_aPortionPaintArea);
             m_pButton->Show();
+            SendLOKMessage("show");
         }
     }
 
+    void DropDownFieldmark::HideButton()
+    {
+        SendLOKMessage("hide");
+        FieldmarkWithDropDownButton::HideButton();
+    }
+
+    void DropDownFieldmark::RemoveButton()
+    {
+        SendLOKMessage("hide");
+        FieldmarkWithDropDownButton::RemoveButton();
+    }
+
     void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
     {
         if(m_aPortionPaintArea == rPortionPaintArea &&
@@ -648,6 +666,33 @@ namespace sw { namespace mark
             m_pButton->Show();
             m_pButton->CalcPosAndSize(m_aPortionPaintArea);
             m_pButton->Invalidate();
+            SendLOKMessage("show");
+        }
+    }
+
+    void DropDownFieldmark::SendLOKMessage(const OString& sAction)
+    {
+        if (comphelper::LibreOfficeKit::isActive())
+        {
+            if (!m_pButton)
+              return;
+
+            SwEditWin* pEditWin = dynamic_cast<SwEditWin*>(m_pButton->GetParent());
+            if (!pEditWin)
+                return;
+
+            OString sPayload;
+            if (sAction == "show")
+            {
+                sPayload = OStringLiteral("{\"action\": \"show\","
+                           " \"type\": \"drop-down\", \"textArea\": \"") +
+                           m_aPortionPaintArea.SVRect().toString() + "\"}";
+            }
+            else
+            {
+                sPayload = "{\"action\": \"hide\", \"type\": \"drop-down\"}";
+            }
+            pEditWin->GetView().GetWrtShell().GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_FORM_FIELD_BUTTON, sPayload.getStr());
         }
     }
 
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 3960ca4b3d8b..67c0292d1e9f 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -278,8 +278,8 @@ namespace sw {
             virtual ~FieldmarkWithDropDownButton() override;
 
             virtual void ShowButton(SwEditWin* pEditWin) = 0;
-            void HideButton();
-            void RemoveButton();
+            virtual void HideButton();
+            virtual void RemoveButton();
 
         protected:
             VclPtr<FormFieldButton> m_pButton;
@@ -294,10 +294,14 @@ namespace sw {
             virtual ~DropDownFieldmark() override;
 
             virtual void ShowButton(SwEditWin* pEditWin) override;
+            virtual void HideButton() override;
+            virtual void RemoveButton() override;
 
             // This method should be called only by the portion so we can now the portion's painting area
             void SetPortionPaintArea(const SwRect& rPortionPaintArea);
 
+            void SendLOKMessage(const OString& sAction);
+
         private:
             SwRect m_aPortionPaintArea;
         };
commit abb5267522065974888d54328bd3ffeb6bf93076
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Tue Apr 14 07:35:02 2020 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Sun May 24 16:41:36 2020 +0200

    lok: add tabstop changing and callback to send tabstop updates
    
    This adds callback LOK_CALLBACK_TAB_STOP_LIST to send the tabstops
    for the current paragraph.
    In addition it adds .uno:ChangeTabStop action, with which it is
    possible to change just one tabstop identified by the index.
    
    Change-Id: I7762ead12e47288cbb0b0a1c8ffb8e9872cee8e8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92147
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index c621fb8d4f82..8291a845f281 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -720,7 +720,12 @@ typedef enum
      * Send the list of functions whose name starts with the characters entered
      * by the user in the formula input bar.
      */
-    LOK_CALLBACK_CALC_FUNCTION_LIST = 47
+    LOK_CALLBACK_CALC_FUNCTION_LIST = 47,
+
+    /**
+     * Sends the tab stop list for the current of the current cursor position.
+     */
+    LOK_CALLBACK_TAB_STOP_LIST = 48,
 }
 LibreOfficeKitCallbackType;
 
@@ -845,6 +850,8 @@ static inline const char* lokCallbackTypeToString(int nType)
         return "LOK_CALLBACK_JSDIALOG";
     case LOK_CALLBACK_CALC_FUNCTION_LIST:
         return "LOK_CALLBACK_CALC_FUNCTION_LIST";
+    case LOK_CALLBACK_TAB_STOP_LIST:
+        return "LOK_CALLBACK_TAB_STOP_LIST";
     }
 
     assert(!"Unknown LibreOfficeKitCallbackType type.");
diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc
index f7e0e2253566..0fe35ed5cd75 100644
--- a/include/svx/svxids.hrc
+++ b/include/svx/svxids.hrc
@@ -530,6 +530,9 @@ class SvxSetItem;
 #define SID_ATTR_ALIGN_DEGREES                          ( SID_SVX_START + 577 )
 #define SID_ATTR_ALIGN_LOCKPOS                          ( SID_SVX_START + 578 )
 #define SID_ATTR_NUMBERFORMAT_ONE_AREA                  ( SID_SVX_START + 580 )
+#define SID_TABSTOP_ADD_OR_CHANGE                       ( SID_SVX_START + 581 )
+#define SID_TABSTOP_ATTR_INDEX                          ( SID_SVX_START + 582 )
+#define SID_TABSTOP_ATTR_POSITION                       ( SID_SVX_START + 583 )
 
 // CAUTION! Range <587 .. 587> used by EditEngine (!)
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 87675fb0e1c4..54da1a4ef738 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1382,6 +1382,7 @@ callback (gpointer pData)
     case LOK_CALLBACK_TABLE_SELECTED:
     case LOK_CALLBACK_JSDIALOG:
     case LOK_CALLBACK_CALC_FUNCTION_LIST:
+    case LOK_CALLBACK_TAB_STOP_LIST:
     {
         // TODO: Implement me
         break;
diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi
index 0bd2964a6ad8..b5775d98e3d4 100644
--- a/svx/sdi/svx.sdi
+++ b/svx/sdi/svx.sdi
@@ -7207,6 +7207,25 @@ SfxVoidItem RulerChangeState SID_RULER_CHANGE_STATE
     GroupId = ;
 ]
 
+SfxVoidItem ChangeTabStop SID_TABSTOP_ADD_OR_CHANGE
+    (SfxInt32Item Index SID_TABSTOP_ATTR_INDEX,
+     SfxInt32Item Position SID_TABSTOP_ATTR_POSITION)
+[
+    AutoUpdate = FALSE,
+    FastCall = TRUE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+
+    AccelConfig = FALSE,
+    MenuConfig = FALSE,
+    ToolBoxConfig = FALSE,
+    GroupId = ;
+]
+
 SfxVoidItem TableChangeCurrentBorderPosition SID_TABLE_CHANGE_CURRENT_BORDER_POSITION
     (SfxStringItem BorderType SID_TABLE_BORDER_TYPE,
      SfxUInt16Item Index SID_TABLE_BORDER_INDEX,
diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi
index ad97fe844319..419335ae48bb 100644
--- a/sw/sdi/_viewsh.sdi
+++ b/sw/sdi/_viewsh.sdi
@@ -643,6 +643,10 @@ interface BaseTextEditView
         StateMethod = StateTabWin ;
         DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
     ]
+    SID_TABSTOP_ADD_OR_CHANGE // status()
+    [
+        ExecMethod = ExecTabWin;
+    ]
     // from here  Export = FALSE;
     FID_SEARCH_ON // status()
     [
diff --git a/sw/source/uibase/uiview/viewtab.cxx b/sw/source/uibase/uiview/viewtab.cxx
index 448387e2527e..a7d2a2095018 100644
--- a/sw/source/uibase/uiview/viewtab.cxx
+++ b/sw/source/uibase/uiview/viewtab.cxx
@@ -62,6 +62,8 @@
 #include <ndtxt.hxx>
 #include <pam.hxx>
 #include <comphelper/lok.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <boost/property_tree/json_parser.hpp>
 
 #include <IDocumentSettingAccess.hxx>
 
@@ -656,6 +658,49 @@ void SwView::ExecTabWin( SfxRequest const & rReq )
                 rSh.SetAttrItem( aTabStops );
         }
         break;
+    case SID_TABSTOP_ADD_OR_CHANGE:
+        if (pReqArgs)
+        {
+            const auto aIndexItem = static_cast<const SfxInt32Item&>(pReqArgs->Get(SID_TABSTOP_ATTR_INDEX));
+            const auto aPositionItem = static_cast<const SfxInt32Item&>(pReqArgs->Get(SID_TABSTOP_ATTR_POSITION));
+            const sal_Int32 nIndex = aIndexItem.GetValue();
+            const sal_Int32 nPosition = aPositionItem.GetValue();
+
+            SfxItemSet aItemSet(GetPool(), svl::Items<RES_PARATR_TABSTOP, RES_PARATR_TABSTOP>{});
+            rSh.GetCurAttr(aItemSet);
+            SvxTabStopItem aTabStopItem(aItemSet.Get(RES_PARATR_TABSTOP));
+            lcl_EraseDefTabs(aTabStopItem);
+
+            if (nIndex < aTabStopItem.Count())
+            {
+                if (nIndex == -1)
+                {
+                    SvxTabStop aSwTabStop(0, SvxTabAdjust::Default);
+                    aTabStopItem.Insert(aSwTabStop);
+
+                    const SvxTabStopItem& rDefaultTabs = rSh.GetDefault(RES_PARATR_TABSTOP);
+                    MakeDefTabs(GetTabDist(rDefaultTabs), aTabStopItem);
+
+                    SvxTabStop aTabStop(nPosition);
+                    aTabStopItem.Insert(aTabStop);
+                }
+                else
+                {
+                    SvxTabStop aTabStop = aTabStopItem.At(nIndex);
+                    aTabStopItem.Remove(nIndex);
+                    aTabStop.GetTabPos() = nPosition;
+                    aTabStopItem.Insert(aTabStop);
+
+                    SvxTabStop aSwTabStop(0, SvxTabAdjust::Default);
+                    aTabStopItem.Insert(aSwTabStop);
+
+                    const SvxTabStopItem& rDefaultTabs = rSh.GetDefault(RES_PARATR_TABSTOP);
+                    MakeDefTabs(GetTabDist(rDefaultTabs), aTabStopItem);
+                }
+                rSh.SetAttrItem(aTabStopItem);
+            }
+        }
+        break;
 
     case SID_HANGING_INDENT:
     {
@@ -1275,14 +1320,14 @@ void SwView::ExecTabWin( SfxRequest const & rReq )
 // will be submitted to the tab bar.
 void SwView::StateTabWin(SfxItemSet& rSet)
 {
-    SwWrtShell &rSh         = GetWrtShell();
+    SwWrtShell &rSh = GetWrtShell();
 
     const Point* pPt = IsTabColFromDoc() || IsTabRowFromDoc() ? &m_aTabColFromDocPos : nullptr;
     const FrameTypeFlags nFrameType   = rSh.IsObjSelected()
                 ? FrameTypeFlags::DRAWOBJ
                 : rSh.GetFrameType( pPt, true );
 
-    const bool  bFrameSelection = rSh.IsFrameSelected();
+    const bool bFrameSelection = rSh.IsFrameSelected();
     const bool bBrowse = rSh.GetViewOptions()->getBrowseMode();
     // PageOffset/limiter
     const SwRect& rPageRect = rSh.GetAnyCurRect( CurRectType::Page, pPt );
@@ -1505,6 +1550,28 @@ void SwView::StateTabWin(SfxItemSet& rSet)
                 ::lcl_EraseDefTabs(aTabStops);
                 aTabStops.SetWhich(nWhich);
                 rSet.Put(aTabStops);
+
+                if (comphelper::LibreOfficeKit::isActive() && nWhich == RES_PARATR_TABSTOP)
+                {
+                    boost::property_tree::ptree aRootTree;
+                    boost::property_tree::ptree aEntries;
+
+                    for (sal_uInt16 i = 0; i < aTabStops.Count(); ++i)
+                    {
+                        SvxTabStop const & rTabStop = aTabStops[i];
+                        boost::property_tree::ptree aEntry;
+                        aEntry.put("position", convertTwipToMm100(rTabStop.GetTabPos()));
+                        aEntry.put("type", sal_uInt16(rTabStop.GetAdjustment()));
+                        aEntry.put("decimal", OUString(rTabStop.GetDecimal()));
+                        aEntry.put("fill", OUString(rTabStop.GetFill()));
+                        aEntries.push_back(std::make_pair("", aEntry));
+                    }
+                    aRootTree.push_back(std::make_pair("tabstops", aEntries));
+
+                    std::stringstream aStream;
+                    boost::property_tree::write_json(aStream, aRootTree);
+                    rSh.GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TAB_STOP_LIST, aStream.str().c_str());
+                }
             }
             break;
         }


More information about the Libreoffice-commits mailing list