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 <[email protected]> AuthorDate: Fri May 22 11:39:12 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Fri May 15 10:30:51 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> Reviewed-by: Tamás Zolnai <[email protected]> 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 <[email protected]> AuthorDate: Mon May 11 13:12:44 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Sat May 9 13:35:16 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Thu May 7 12:25:51 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> Reviewed-by: Tamás Zolnai <[email protected]> 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 <[email protected]> AuthorDate: Fri May 8 15:26:57 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> Reviewed-by: Tamás Zolnai <[email protected]> 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 <[email protected]> AuthorDate: Thu May 7 17:28:02 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Thu May 7 16:57:45 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Thu May 7 12:45:48 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Thu May 7 12:08:39 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Wed May 6 14:33:10 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> Reviewed-by: Tamás Zolnai <[email protected]> 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 <[email protected]> AuthorDate: Tue May 5 14:36:16 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Tue Apr 28 15:51:02 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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 <[email protected]> AuthorDate: Tue Apr 14 07:35:02 2020 +0200 Commit: Andras Timar <[email protected]> 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 <[email protected]> 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; } _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
