[Libreoffice-commits] core.git: Branch 'feature/msforms' - 746 commits - accessibility/inc accessibility/source android/Bootstrap apple_remote/source avmedia/source basctl/inc basctl/source basegfx/IwyuFilter_basegfx.yaml basegfx/source basegfx/test basic/inc basic/qa basic/source binaryurp/source bridges/source canvas/source chart2/qa chart2/source chart2/uiconfig cli_ure/source codemaker/source comphelper/source compilerplugins/clang compilerplugins/Makefile-clang.mk config_host/config_features.h.in config_host.mk.in configmgr/qa configmgr/source configure.ac connectivity/Library_dbpool2.mk connectivity/source cppcanvas/source cppuhelper/qa cppuhelper/source cppu/source cui/inc cui/qa cui/source cui/uiconfig dbaccess/qa dbaccess/source dbaccess/uiconfig desktop/inc desktop/source desktop/uiconfig dictionaries distro-configs/Jenkins distro-configs/LibreOfficeVanillaMacAppStore.conf download.lst drawinglayer/source dtrans/source editeng/inc editeng/qa editeng/source embedserv/source emfio/source extensions/CppunitTest_extensions_test_update.mk extensions/inc extensions/Library_updchk.mk extensions/source extensions/uiconfig external/apr external/cairo external/curl external/freetype external/harfbuzz external/icu external/librevenge external/mdnsresponder external/neon external/redland external/zlib extras/source filter/inc filter/Library_icg.mk filter/qa filter/source filter/uiconfig forms/source formula/inc formula/source fpicker/source framework/inc framework/qa framework/source helpcompiler/inc helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/source icon-themes/breeze icon-themes/colibre icon-themes/colibre_svg icon-themes/elementary icon-themes/karasa_jaga icon-themes/sifr icon-themes/sifr_dark icon-themes/sifr_svg icon-themes/tango idlc/inc idlc/source idl/inc include/basegfx include/basic include/canvas include/comphelper include/connectivity include/cppcanvas include/cppuhelper include/drawinglayer include/editeng include/filter include/ formula include/framework include/IwyuFilter_include.yaml include/linguistic include/o3tl include/oox include/registry include/sal include/sfx2 include/svl include/svtools include/svx include/test include/toolkit include/tools include/ucbhelper include/unotools include/vbahelper include/vcl io/Library_io.mk ios/CustomTarget_iOS_setup.mk io/source ios/UnitTest javaunohelper/Library_juhx.mk javaunohelper/source jurt/com jvmfwk/plugins l10ntools/inc l10ntools/source lingucomponent/source linguistic/source logerrit lotuswordpro/inc lotuswordpro/source Makefile.fetch o3tl/qa offapi/com offapi/type_reference offapi/UnoApi_offapi.mk officecfg/registry oox/inc oox/Library_oox.mk oox/source package/Library_xstor.mk package/source pyuno/source qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests readlicense_oo/license registry/source reportdesign/source RepositoryExternal.mk Repository.mk sal/CppunitTest_sal_comtools.mk sal/Module_sal.mk sal/osl sal/qa sal/textenc sax/Library_expwrap.mk s ax/source scaddins/source sccomp/source sc/CppunitTest_sc_datapilotfieldgroupitemobj.mk sc/CppunitTest_sc_datapilotitemsobj.mk schema/libreoffice sc/inc sc/IwyuFilter_sc.yaml sc/Module_sc.mk scp2/inc scp2/source sc/qa scripting/examples scripting/java scripting/source sc/sdi sc/source sc/uiconfig sc/UITest_pageFormat.mk sc/UITest_range_name.mk sc/UITest_statistics.mk sd/CppunitTest_sd_activex_controls_tests.mk sd/CppunitTest_sd_import_tests.mk sd/CppunitTest_sd_misc_tests.mk sdext/Module_sdext.mk sdext/source sd/inc sd/IwyuFilter_sd.yaml sd/Module_sd.mk sd/qa sd/sdi sd/source sd/uiconfig sd/UIConfig_sdraw.mk sd/xml setup_native/source sfx2/inc sfx2/Library_sfx.mk sfx2/sdi sfx2/source shell/source slideshow/source slideshow/test solenv/bin solenv/clang-format solenv/CompilerTest_compilerplugins_clang.mk solenv/gbuild solenv/sanitizers sot/source starmath/inc starmath/IwyuFilter_starmath.yaml starmath/qa starmath/source starmath/uiconfig stoc/source svgio/CppunitTest_svgio_read.mk svg io/inc svgio/Library_svgio.mk svgio/Module_svgio.mk svgio/qa svgio/source svl/source svtools/inc svtools/qa svtools/source svtools/uiconfig svx/CppunitTest_svx_unit.mk svx/inc svx/qa svx/sdi svx/source svx/uiconfig sw/CppunitTest_sw_ooxmlimport2.mk sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk sysui/desktop test/Library_subsequenttest.mk test/source testtools/source toolkit/CppunitTest_toolkit.mk toolkit/qa toolkit/source tools/Library_tl.mk tools/source ucbhelper/source ucb/Library_ucpexpand1.mk ucb/source unoidl/source unotools/source unoxml/inc unoxml/source uui/source vbahelper/source vcl/CppunitTest_vcl_widget_definition_reader_test.mk vcl/CustomTarget_qt5_moc.mk vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/opengl vcl/osx vcl/Package_theme_definitions.mk vcl/qa vcl/qt5 vcl/quartz vcl/source vcl/uiconfig vcl/unx vcl/win vcl/workben winaccessibility/source wizards/source writerfilter/source writerperfect/inc writerperfe ct/source xmlhelp/source xmloff/inc xmloff/source xmloff/util xmlscript/source xmlsecurity/CppunitTest_xmlsecurity_pdfsigning.mk xmlsecurity/CppunitTest_xmlsecurity_signing.mk xmlsecurity/inc xmlsecurity/qa xmlsecurity/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Fri Mar 8 15:13:56 UTC 2019
Rebased ref, commits from common ancestor:
commit 132587bcf455bf97cd1d49aaf50a6cd750193240
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Mar 7 12:37:00 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:44:05 2019 +0100
MSForms: UITest for drop-down form field's propertis dialog
Also changed the dialog's code a bit to work correctly with
the UI test too.
Change-Id: Idec85746f5ada979518d1fb0e09dc1c8e22ba7c1
diff --git a/sw/qa/uitest/writer_tests/data/drop_down_form_field.doc b/sw/qa/uitest/writer_tests/data/drop_down_form_field.doc
new file mode 100644
index 000000000000..cf94a1fdada1
Binary files /dev/null and b/sw/qa/uitest/writer_tests/data/drop_down_form_field.doc differ
diff --git a/sw/qa/uitest/writer_tests/data/drop_down_form_field.docx b/sw/qa/uitest/writer_tests/data/drop_down_form_field.docx
new file mode 100644
index 000000000000..d039cd2b60d3
Binary files /dev/null and b/sw/qa/uitest/writer_tests/data/drop_down_form_field.docx differ
diff --git a/sw/qa/uitest/writer_tests/data/drop_down_form_field.odt b/sw/qa/uitest/writer_tests/data/drop_down_form_field.odt
new file mode 100644
index 000000000000..f27b1157418c
Binary files /dev/null and b/sw/qa/uitest/writer_tests/data/drop_down_form_field.odt differ
diff --git a/sw/qa/uitest/writer_tests/data/empty_drop_down_form_field.odt b/sw/qa/uitest/writer_tests/data/empty_drop_down_form_field.odt
new file mode 100644
index 000000000000..bd85dc2a902d
Binary files /dev/null and b/sw/qa/uitest/writer_tests/data/empty_drop_down_form_field.odt differ
diff --git a/sw/qa/uitest/writer_tests5/DropDownFormFieldPropertiesDialog.py b/sw/qa/uitest/writer_tests5/DropDownFormFieldPropertiesDialog.py
new file mode 100644
index 000000000000..5628e83992e1
--- /dev/null
+++ b/sw/qa/uitest/writer_tests5/DropDownFormFieldPropertiesDialog.py
@@ -0,0 +1,266 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+from libreoffice.uno.propertyvalue import mkPropertyValues
+import org.libreoffice.unotest
+import pathlib
+import time
+
+def get_url_for_data_file(file_name):
+ return pathlib.Path(org.libreoffice.unotest.makeCopyFromTDOC(file_name)).as_uri()
+
+class dropDownFormFieldDialog(UITestCase):
+
+ def test_add_new_items(self):
+
+ # open a file with an empty form field
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("empty_drop_down_form_field.odt"))
+ document = self.ui_test.get_component()
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+
+ # open the dialog (cursor is at the field)
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemEntry = xDialog.getChild("item_entry")
+ addButton = xDialog.getChild("add_button")
+ itemsList = xDialog.getChild("items_treeview")
+
+ # initial state
+ self.assertEqual(get_state_as_dict(itemEntry)["Text"], "")
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "false")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "0")
+
+ # add some new items
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"1000"}))
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "true")
+ addButton.executeAction("CLICK", tuple())
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "false")
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"2000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"3000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"4000"}))
+ addButton.executeAction("CLICK", tuple())
+
+ # check whether the items are there in the list
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ # check whether items are the same after reopening
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemsList = xDialog.getChild("items_treeview")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.close_doc()
+
+ def test_remove_items(self):
+
+ # open a file with an empty form field
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("empty_drop_down_form_field.odt"))
+ document = self.ui_test.get_component()
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+
+ # open the dialog (cursor is at the field)
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemEntry = xDialog.getChild("item_entry")
+ addButton = xDialog.getChild("add_button")
+ itemsList = xDialog.getChild("items_treeview")
+ removeButton = xDialog.getChild("remove_button")
+
+ # initial state
+ self.assertEqual(get_state_as_dict(itemEntry)["Text"], "")
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "false")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "0")
+ self.assertEqual(get_state_as_dict(removeButton)["Enabled"], "false")
+
+ # add some new items
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"1000"}))
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "true")
+ addButton.executeAction("CLICK", tuple())
+ self.assertEqual(get_state_as_dict(removeButton)["Enabled"], "true")
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"2000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"3000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"4000"}))
+ addButton.executeAction("CLICK", tuple())
+
+ # check whether the items are there in the list
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ # select an item from the list and remove it
+ itemsList.getChild("1").executeAction("SELECT", tuple());
+ removeButton.executeAction("CLICK", tuple())
+
+ # check whether the right item was removed
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "3")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "4000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ # check whether items are the same after reopening
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemsList = xDialog.getChild("items_treeview")
+ removeButton = xDialog.getChild("remove_button")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "3")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "4000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.close_doc()
+
+ def test_move_items(self):
+
+ # open a file with an empty form field
+ writer_doc = self.ui_test.load_file(get_url_for_data_file("empty_drop_down_form_field.odt"))
+ document = self.ui_test.get_component()
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+
+ # open the dialog (cursor is at the field)
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemEntry = xDialog.getChild("item_entry")
+ addButton = xDialog.getChild("add_button")
+ itemsList = xDialog.getChild("items_treeview")
+ upButton = xDialog.getChild("up_button")
+ downButton = xDialog.getChild("down_button")
+
+ # initial state
+ self.assertEqual(get_state_as_dict(itemEntry)["Text"], "")
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "false")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "0")
+ self.assertEqual(get_state_as_dict(upButton)["Enabled"], "false")
+ self.assertEqual(get_state_as_dict(downButton)["Enabled"], "false")
+
+ # add some new items
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"1000"}))
+ self.assertEqual(get_state_as_dict(addButton)["Enabled"], "true")
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"2000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"3000"}))
+ addButton.executeAction("CLICK", tuple())
+ itemEntry.executeAction("TYPE", mkPropertyValues({"TEXT":"4000"}))
+ addButton.executeAction("CLICK", tuple())
+
+ # check whether the items are there in the list
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ # select an item from the list and move it up
+ itemsList.getChild("1").executeAction("SELECT", tuple())
+ self.assertEqual(get_state_as_dict(upButton)["Enabled"], "true")
+ self.assertEqual(get_state_as_dict(downButton)["Enabled"], "true")
+ upButton.executeAction("CLICK", tuple())
+ self.assertEqual(get_state_as_dict(upButton)["Enabled"], "false")
+ self.assertEqual(get_state_as_dict(downButton)["Enabled"], "true")
+
+ # check whether the item was correctly moved
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ # move down the selected item
+ downButton.executeAction("CLICK", tuple())
+ downButton.executeAction("CLICK", tuple())
+ downButton.executeAction("CLICK", tuple())
+ self.assertEqual(get_state_as_dict(upButton)["Enabled"], "true")
+ self.assertEqual(get_state_as_dict(downButton)["Enabled"], "false")
+
+ # check whether the item was correctly moved
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "4000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "2000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ # check whether items are the same after reopening
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemsList = xDialog.getChild("items_treeview")
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "4000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "2000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.close_doc()
+
+ def test_drop_down_after_import(self):
+
+ files = ["drop_down_form_field.odt", "drop_down_form_field.doc", "drop_down_form_field.docx"]
+ for file in files:
+ # open a file with a drop-down for field with items and selection
+ writer_doc = self.ui_test.load_file(get_url_for_data_file(file))
+ document = self.ui_test.get_component()
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+
+ # open the dialog (cursor is at the field)
+ self.ui_test.execute_dialog_through_command(".uno:ControlProperties")
+ xDialog = self.xUITest.getTopFocusWindow()
+
+ itemsList = xDialog.getChild("items_treeview")
+
+ # check whether the items are there in the list
+ self.assertEqual(get_state_as_dict(itemsList)["Children"], "4")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("0"))["Text"], "1000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("1"))["Text"], "2000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("2"))["Text"], "3000")
+ self.assertEqual(get_state_as_dict(itemsList.getChild("3"))["Text"], "4000")
+
+ self.assertEqual(get_state_as_dict(itemsList)["SelectEntryText"], "3000")
+
+ xOKBtn = xDialog.getChild("ok")
+ self.ui_test.close_dialog_through_button(xOKBtn)
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
index 3b30aaf9131a..ccd9829ce5f2 100644
--- a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
+++ b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
@@ -28,7 +28,7 @@ DropDownFormFieldDialog::DropDownFormFieldDialog(weld::Window* pParent,
, m_xListDownButton(m_xBuilder->weld_button("down_button"))
{
m_xListItemEntry->connect_key_press(LINK(this, DropDownFormFieldDialog, KeyPressedHdl));
- m_xListItemEntry->connect_key_release(LINK(this, DropDownFormFieldDialog, KeyReleasedHdl));
+ m_xListItemEntry->connect_changed(LINK(this, DropDownFormFieldDialog, EntryChangedHdl));
m_xListItemsTreeView->set_size_request(m_xListItemEntry->get_preferred_size().Width(),
m_xListItemEntry->get_preferred_size().Height() * 5);
@@ -57,10 +57,9 @@ IMPL_LINK(DropDownFormFieldDialog, KeyPressedHdl, const KeyEvent&, rEvent, bool)
return false;
}
-IMPL_LINK_NOARG(DropDownFormFieldDialog, KeyReleasedHdl, const KeyEvent&, bool)
+IMPL_LINK_NOARG(DropDownFormFieldDialog, EntryChangedHdl, weld::Entry&, void)
{
UpdateButtons();
- return false;
}
IMPL_LINK(DropDownFormFieldDialog, ButtonPushedHdl, weld::Button&, rButton, void)
diff --git a/sw/source/uibase/inc/DropDownFormFieldDialog.hxx b/sw/source/uibase/inc/DropDownFormFieldDialog.hxx
index 3fbb59db0ebc..aee5c5232845 100644
--- a/sw/source/uibase/inc/DropDownFormFieldDialog.hxx
+++ b/sw/source/uibase/inc/DropDownFormFieldDialog.hxx
@@ -41,7 +41,7 @@ private:
DECL_LINK(ListChangedHdl, weld::TreeView&, void);
DECL_LINK(KeyPressedHdl, const KeyEvent&, bool);
- DECL_LINK(KeyReleasedHdl, const KeyEvent&, bool);
+ DECL_LINK(EntryChangedHdl, weld::Entry&, void);
DECL_LINK(ButtonPushedHdl, weld::Button&, void);
void InitControls();
commit 180a6b5edd29fee5abe8b1f8b5a6630895dc613b
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Mar 6 16:58:17 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:44:04 2019 +0100
MSForms: Test insertion of form fields and undo / redo of this insertion.
Change-Id: I526faceab8eb1ce2f16d41ab1bed8cfb1bfcca24
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index dfd8d747f72f..697ec3533b59 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -30,6 +30,7 @@
#include <anchoredobject.hxx>
#include <swtypes.hxx>
#include <fmtornt.hxx>
+#include <xmloff/odffields.hxx>
namespace
{
@@ -89,6 +90,10 @@ public:
CPPUNIT_TEST(testTdf52391);
CPPUNIT_TEST(testTdf101873);
CPPUNIT_TEST(testTableWidth);
+ CPPUNIT_TEST(testTextFormFieldInsertion);
+ CPPUNIT_TEST(testCheckboxFormFieldInsertion);
+ CPPUNIT_TEST(testDropDownFormFieldInsertion);
+ CPPUNIT_TEST(testMixedFormFieldInsertion);
CPPUNIT_TEST_SUITE_END();
private:
@@ -937,6 +942,150 @@ void SwUiWriterTest2::testTableWidth()
getProperty<sal_Int16>(xTables->getByIndex(0), "RelativeWidth"));
}
+void SwUiWriterTest2::testTextFormFieldInsertion()
+{
+ load(DATA_DIRECTORY, "frame_size_export.docx");
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a text form field
+ lcl_dispatchCommand(mxComponent, ".uno:TextFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMTEXT), pFieldmark->GetFieldname());
+
+ // The text form field has the placholder text in it
+ uno::Reference< text::XTextRange > xPara = getParagraph(1);
+ sal_Unicode vEnSpaces[5] = {8194, 8194, 8194, 8194, 8194};
+ CPPUNIT_ASSERT_EQUAL(OUString(vEnSpaces, 5), xPara->getString());
+
+ // Undo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+ xPara.set(getParagraph(1));
+ CPPUNIT_ASSERT(xPara->getString().isEmpty());
+
+ // Redo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+ xPara.set(getParagraph(1));
+ CPPUNIT_ASSERT_EQUAL(OUString(vEnSpaces, 5), xPara->getString());
+}
+
+void SwUiWriterTest2::testCheckboxFormFieldInsertion()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a checkbox form field
+ lcl_dispatchCommand(mxComponent, ".uno:CheckBoxFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMCHECKBOX), pFieldmark->GetFieldname());
+ // The checkbox is not checked by default
+ ::sw::mark::ICheckboxFieldmark* pCheckBox = dynamic_cast< ::sw::mark::ICheckboxFieldmark* >(pFieldmark);
+ CPPUNIT_ASSERT(pCheckBox);
+ CPPUNIT_ASSERT(!pCheckBox->IsChecked());
+
+ // Undo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Redo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+ aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMCHECKBOX), pFieldmark->GetFieldname());
+}
+
+void SwUiWriterTest2::testDropDownFormFieldInsertion()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a drop-down form field
+ lcl_dispatchCommand(mxComponent, ".uno:DropDownFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDROPDOWN), pFieldmark->GetFieldname());
+ // Check drop down field's parameters. By default these params are not set
+ const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
+ auto pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
+ CPPUNIT_ASSERT(pListEntries == pParameters->end());
+ auto pResult = pParameters->find(ODF_FORMDROPDOWN_RESULT);
+ CPPUNIT_ASSERT(pResult == pParameters->end());
+
+ // Undo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Redo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+ aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDROPDOWN), pFieldmark->GetFieldname());
+}
+
+void SwUiWriterTest2::testMixedFormFieldInsertion()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert fields
+ lcl_dispatchCommand(mxComponent, ".uno:TextFormField", {});
+ lcl_dispatchCommand(mxComponent, ".uno:CheckBoxFormField", {});
+ lcl_dispatchCommand(mxComponent, ".uno:DropDownFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMarkAccess->getAllMarksCount());
+
+ // Undo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Redo insertion
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMarkAccess->getAllMarksCount());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 7564f794644c571950b14c15eb71f098545c29d2
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Mar 6 15:48:05 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:44:03 2019 +0100
MSForms: Add some extra comments for the new code
Change-Id: I4b70eb2164032623a12f9e703c660eca1d6768ec
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index 68a97df6c3bc..fd55bc0dc747 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -1225,7 +1225,7 @@ void Test::testDropDownFormField()
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0), vListEntries.getLength());
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(-1), nSelection);
}
- else
+ else // The second one has list and also a selected item
{
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(4), vListEntries.getLength());
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(1), nSelection);
diff --git a/sw/source/core/inc/UndoBookmark.hxx b/sw/source/core/inc/UndoBookmark.hxx
index 7b9dd4fc68e5..3e2017d0721d 100644
--- a/sw/source/core/inc/UndoBookmark.hxx
+++ b/sw/source/core/inc/UndoBookmark.hxx
@@ -98,6 +98,7 @@ private:
virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
};
+/// Handling undo / redo of checkbox and drop-down form field insertion
class SwUndoInsNoTextFieldmark : public SwUndo
{
private:
@@ -110,6 +111,7 @@ public:
virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
};
+/// Handling undo / redo of text form field insertion
class SwUndoInsTextFieldmark : public SwUndo
{
private:
diff --git a/sw/source/core/inc/rolbck.hxx b/sw/source/core/inc/rolbck.hxx
index 3fde226b7acf..2feec7e6d973 100644
--- a/sw/source/core/inc/rolbck.hxx
+++ b/sw/source/core/inc/rolbck.hxx
@@ -262,6 +262,8 @@ class SwHistoryBookmark : public SwHistoryHint
std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndo;
};
+/// History object containing all information used during undo / redo
+/// of checkbox and drop-down form field insertion.
class SwHistoryNoTextFieldmark : public SwHistoryHint
{
public:
@@ -275,6 +277,8 @@ class SwHistoryNoTextFieldmark : public SwHistoryHint
const sal_Int32 m_nContent;
};
+/// History object containing all information used during undo / redo
+/// of text form field insertion.
class SwHistoryTextFieldmark : public SwHistoryHint
{
public:
commit 71b746bc1f5332fa84ce940c88a051a29361b394
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Mar 5 21:07:32 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:43:53 2019 +0100
MSForms: Test legacy form field import / export for the supported formats.
Change-Id: Idbb80d097b21386e7d2673290a318d98b92125d5
diff --git a/sw/qa/extras/globalfilter/data/checkbox_form_field.odt b/sw/qa/extras/globalfilter/data/checkbox_form_field.odt
new file mode 100644
index 000000000000..14c931ed37da
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/checkbox_form_field.odt differ
diff --git a/sw/qa/extras/globalfilter/data/dropdown_form_field.odt b/sw/qa/extras/globalfilter/data/dropdown_form_field.odt
new file mode 100644
index 000000000000..caaa66acda8f
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/dropdown_form_field.odt differ
diff --git a/sw/qa/extras/globalfilter/data/text_form_field.odt b/sw/qa/extras/globalfilter/data/text_form_field.odt
new file mode 100644
index 000000000000..96af26f7708f
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/text_form_field.odt differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index f9a6a60df823..68a97df6c3bc 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -25,6 +25,10 @@
#include <ndindex.hxx>
#include <pam.hxx>
#include <unotools/fltrcfg.hxx>
+#include <xmloff/odffields.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <IMark.hxx>
+#include <bookmrk.hxx>
class Test : public SwModelTestBase
{
@@ -45,6 +49,9 @@ public:
#endif
void testRedlineFlags();
void testBulletAsImage();
+ void testTextFormField();
+ void testCheckBoxFormField();
+ void testDropDownFormField();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testEmbeddedGraphicRoundtrip);
@@ -60,6 +67,9 @@ public:
#endif
CPPUNIT_TEST(testRedlineFlags);
CPPUNIT_TEST(testBulletAsImage);
+ CPPUNIT_TEST(testTextFormField);
+ CPPUNIT_TEST(testCheckBoxFormField);
+ CPPUNIT_TEST(testDropDownFormField);
CPPUNIT_TEST_SUITE_END();
};
@@ -1023,6 +1033,213 @@ void Test::testBulletAsImage()
}
}
+void Test::testTextFormField()
+{
+ const OUString aFilterNames[] = {
+ "writer8",
+ "MS Word 97",
+ "Office Open XML Text",
+ };
+
+ for (const OUString& rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/text_form_field.odt"), "com.sun.star.text.TextDocument");
+
+ const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8();
+
+ // Export the document and import again for a check
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY);
+ xComponent->dispose();
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check the document after round trip
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc);
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+
+ // We have two text form fields
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(2), pMarkAccess->getAllMarksCount());
+
+ // Check whether all fieldmarks are text form fields
+ for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMTEXT), pFieldmark->GetFieldname());
+ }
+
+ // In the first paragraph we have an empty text form field with the placeholder spaces
+ const uno::Reference< text::XTextRange > xPara = getParagraph(1);
+ sal_Unicode vEnSpaces[5] = {8194, 8194, 8194, 8194, 8194};
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), xPara->getString());
+
+ // In the second paragraph we have a set text
+ const uno::Reference< text::XTextRange > xPara2 = getParagraph(2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("xxxxx"), xPara2->getString());
+ }
+}
+
+void Test::testCheckBoxFormField()
+{
+ const OUString aFilterNames[] = {
+ "writer8",
+ "MS Word 97",
+ "Office Open XML Text",
+ };
+
+ for (const OUString& rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/checkbox_form_field.odt"), "com.sun.star.text.TextDocument");
+
+ const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8();
+
+ // Export the document and import again for a check
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY);
+ xComponent->dispose();
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check the document after round trip
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc);
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+
+ // We have two check box form fields
+ if(rFilterName == "Office Open XML Text")
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(4), pMarkAccess->getAllMarksCount());
+ else
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(2), pMarkAccess->getAllMarksCount());
+
+ int nIndex = 0;
+ for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+
+ if(rFilterName == "Office Open XML Text") // OOXML import also generates bookmarks
+ {
+ if(!pFieldmark)
+ continue;
+ }
+
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMCHECKBOX), pFieldmark->GetFieldname());
+ ::sw::mark::ICheckboxFieldmark* pCheckBox = dynamic_cast< ::sw::mark::ICheckboxFieldmark* >(pFieldmark);
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pCheckBox);
+
+ // The first one is unchecked, the other one is checked
+ if(nIndex == 0)
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), !pCheckBox->IsChecked());
+ else
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pCheckBox->IsChecked());
+ ++nIndex;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(2), nIndex);
+ }
+}
+
+void Test::testDropDownFormField()
+{
+ const OUString aFilterNames[] = {
+ "writer8",
+ "MS Word 97",
+ "Office Open XML Text",
+ };
+
+ for (const OUString& rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/dropdown_form_field.odt"), "com.sun.star.text.TextDocument");
+
+ const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8();
+
+ // Export the document and import again for a check
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY);
+ xComponent->dispose();
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check the document after round trip
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc);
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(2), pMarkAccess->getAllMarksCount());
+
+ int nIndex = 0;
+ for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
+
+ if(!pFieldmark)
+ continue;
+
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDROPDOWN), pFieldmark->GetFieldname());
+
+ // Check drop down field's parameters.
+ const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
+ css::uno::Sequence<OUString> vListEntries;
+ sal_Int32 nSelection = -1;
+ auto pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
+ if (pListEntries != pParameters->end())
+ {
+ pListEntries->second >>= vListEntries;
+
+ if(vListEntries.getLength())
+ {
+ auto pResult = pParameters->find(ODF_FORMDROPDOWN_RESULT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= nSelection;
+ }
+ }
+ }
+
+ // The first one is empty
+ if(nIndex == 0)
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0), vListEntries.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(-1), nSelection);
+ }
+ else
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(4), vListEntries.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(1), nSelection);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("1000"), vListEntries[0]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2000"), vListEntries[1]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("3000"), vListEntries[2]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("4000"), vListEntries[3]);
+ }
+ ++nIndex;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(2), nIndex);
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 2f248a996b7c..dfd8d747f72f 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -62,6 +62,10 @@ public:
void testTdf52391();
void testTdf101873();
void testTableWidth();
+ void testTextFormFieldInsertion();
+ void testCheckboxFormFieldInsertion();
+ void testDropDownFormFieldInsertion();
+ void testMixedFormFieldInsertion();
CPPUNIT_TEST_SUITE(SwUiWriterTest2);
CPPUNIT_TEST(testRedlineMoveInsertInDelete);
commit 378f8f973ddf4d0e0c26d914807132534c15a2b4
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Mar 5 19:40:08 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:43:52 2019 +0100
MSForms: Fix handling of drop-down form field after DOC import
In the properties dialog, code expected that the ODF_FORMDROPDOWN_RESULT
is not set in case of an empty list. This caused a crash.
The field popup window code expected that the list is not specified
when it is empty, but DOC import code sets ODF_FORMDROPDOWN_LISTENTRY
even if the list is empty.
Change-Id: If4c86fc5a08cdc578150afaa42ad7e86bdba9150
diff --git a/sw/source/core/crsr/DropDownFormFieldButton.cxx b/sw/source/core/crsr/DropDownFormFieldButton.cxx
index d3a50b653dca..202622022fc1 100644
--- a/sw/source/core/crsr/DropDownFormFieldButton.cxx
+++ b/sw/source/core/crsr/DropDownFormFieldButton.cxx
@@ -53,14 +53,15 @@ SwFieldDialog::SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM, l
OUString sListKey = ODF_FORMDROPDOWN_LISTENTRY;
sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries
= pParameters->find(sListKey);
+ css::uno::Sequence<OUString> vListEntries;
if (pListEntries != pParameters->end())
{
- css::uno::Sequence<OUString> vListEntries;
pListEntries->second >>= vListEntries;
for (OUString const& i : vListEntries)
aListBox->InsertEntry(i);
}
- else
+
+ if(vListEntries.getLength() == 0)
{
aListBox->InsertEntry(SwResId(STR_DROP_DOWN_EMPTY_LIST));
}
diff --git a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
index 09564999d321..3b30aaf9131a 100644
--- a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
+++ b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
@@ -119,7 +119,8 @@ void DropDownFormFieldDialog::InitControls()
{
sal_Int32 nSelection = -1;
pResult->second >>= nSelection;
- m_xListItemsTreeView->select_text(vListEntries[nSelection]);
+ if(vListEntries.getLength() > nSelection)
+ m_xListItemsTreeView->select_text(vListEntries[nSelection]);
}
}
}
commit 6e139d1e872abb017dc7b3397f978d5316edbdd3
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Mar 2 10:22:54 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:43:51 2019 +0100
MSForms: Open Control Properties dialog by double click for drop-down field
Change-Id: I66c0a7bad63d929ae346afe9d328d87dfa2c24ae
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 85d24b1d61c5..6ee65c5fdd7d 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3364,6 +3364,21 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
// table.
rSh.SelTableBox();
}
+
+ SwContentAtPos aContentAtPos(IsAttrAtPos::FormControl);
+ if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) &&
+ aContentAtPos.aFnd.pFieldmark != nullptr)
+ {
+ IFieldmark *pFieldBM = const_cast< IFieldmark* > ( aContentAtPos.aFnd.pFieldmark );
+ if ( pFieldBM->GetFieldname( ) == ODF_FORMDROPDOWN )
+ {
+ RstMBDownFlags();
+ rSh.getIDocumentMarkAccess()->ClearFieldActivation();
+ GetView().GetViewFrame()->GetBindings().Execute(SID_FM_CTL_PROPERTIES);
+ return;
+ }
+ }
+
g_bHoldSelection = true;
return;
}
commit 143c4e4a6bd630de872d30edd24f8f6a4b6f8349
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Mar 4 20:52:38 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 15:43:41 2019 +0100
MSForms: Add a drop-down button for drop-down form field
* Introduce a editing frame with a button for drop-down form field.
** The frame is mouse transparent.
** Pushing the button opens the popup window with the items of the field.
* The button is visible when the cursor is inside the field.
Change-Id: I5c7db138d14380899fee046c95a5afe14cfea213
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 4294c4f1e520..fff03ed1ffb5 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -598,7 +598,7 @@ protected:
SAL_DLLPRIVATE void ImplInvalidate( const vcl::Region* rRegion, InvalidateFlags nFlags );
- SAL_DLLPRIVATE WindowHitTest ImplHitTest( const Point& rFramePos );
+ virtual WindowHitTest ImplHitTest( const Point& rFramePos );
SAL_DLLPRIVATE void ImplSetMouseTransparent( bool bTransparent );
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 939838d3dfc2..1cd8d8cb1613 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -150,6 +150,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
sw/source/core/crsr/crsrsh \
sw/source/core/crsr/crstrvl \
sw/source/core/crsr/crstrvl1 \
+ sw/source/core/crsr/DropDownFormFieldButton \
sw/source/core/crsr/findattr \
sw/source/core/crsr/findcoll \
sw/source/core/crsr/findfmt \
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index cbd523c012b1..d7111112612f 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -27,6 +27,7 @@
class SwPaM;
struct SwPosition;
class SwTextNode;
+class SwCursorShell;
namespace sw { namespace mark {
class SaveBookmark; // FIXME: Ugly: SaveBookmark is a core-internal class, and should not be used in the interface
@@ -258,6 +259,9 @@ class IDocumentMarkAccess
virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
+ virtual void NotifyCursorUpdate(const SwCursorShell& rCursorShell) = 0;
+ virtual void ClearFieldActivation() = 0;
+
// Annotation Marks
virtual const_iterator_t getAnnotationMarksBegin() const = 0;
virtual const_iterator_t getAnnotationMarksEnd() const = 0;
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index c8671f015e91..2093a2d8c14f 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -1328,6 +1328,9 @@
#define STR_MENU_UP NC_("STR_MENU_UP", "~Upwards")
#define STR_MENU_DOWN NC_("STR_MENU_DOWN", "Do~wnwards")
+
+#define STR_DROP_DOWN_EMPTY_LIST NC_("STR_DROP_DOWN_EMPTY_LIST", "No Item specified")
+
/*--------------------------------------------------------------------
Description: Classification strings
--------------------------------------------------------------------*/
diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx
index 66c61eef6dc5..d2fade9a1901 100644
--- a/sw/inc/view.hxx
+++ b/sw/inc/view.hxx
@@ -208,7 +208,6 @@ class SW_DLLPUBLIC SwView: public SfxViewShell
std::unique_ptr<SwPostItMgr> m_pPostItMgr;
SelectionType m_nSelectionType;
- VclPtr<FloatingWindow> m_pFieldPopup;
sal_uInt16 m_nPageCnt;
// current draw mode
@@ -265,8 +264,6 @@ class SW_DLLPUBLIC SwView: public SfxViewShell
DECL_DLLPRIVATE_LINK( TimeoutHdl, Timer*, void );
- DECL_DLLPRIVATE_LINK( FieldPopupModeEndHdl, FloatingWindow*, void );
-
inline long GetXScroll() const;
inline long GetYScroll() const;
SAL_DLLPRIVATE Point AlignToPixel(const Point& rPt) const;
@@ -423,7 +420,6 @@ public:
void SpellError(LanguageType eLang);
bool ExecSpellPopup( const Point& rPt );
- void ExecFieldPopup( const Point& rPt, sw::mark::IFieldmark *fieldBM );
void ExecSmartTagPopup( const Point& rPt );
DECL_LINK( OnlineSpellCallback, SpellCallbackInfo&, void );
diff --git a/sw/source/core/crsr/DropDownFormFieldButton.cxx b/sw/source/core/crsr/DropDownFormFieldButton.cxx
new file mode 100644
index 000000000000..d3a50b653dca
--- /dev/null
+++ b/sw/source/core/crsr/DropDownFormFieldButton.cxx
@@ -0,0 +1,247 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <DropDownFormFieldButton.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <edtwin.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <viewopt.hxx>
+#include <bookmrk.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/event.hxx>
+#include <vcl/lstbox.hxx>
+#include <xmloff/odffields.hxx>
+#include <IMark.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <strings.hrc>
+
+/**
+ * Popup dialog for drop-down form field showing the list items of the field.
+ * The user can select the item using this popup while filling in a form.
+ */
+class SwFieldDialog : public FloatingWindow
+{
+private:
+ VclPtr<ListBox> aListBox;
+ sw::mark::IFieldmark* pFieldmark;
+
+ DECL_LINK(MyListBoxHandler, ListBox&, void);
+
+public:
+ SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM, long nMinListWidth);
+ virtual ~SwFieldDialog() override;
+ virtual void dispose() override;
+};
+
+SwFieldDialog::SwFieldDialog(SwEditWin* parent, sw::mark::IFieldmark* fieldBM, long nMinListWidth)
+ : FloatingWindow(parent, WB_BORDER | WB_SYSTEMWINDOW)
+ , aListBox(VclPtr<ListBox>::Create(this))
+ , pFieldmark(fieldBM)
+{
+ if (fieldBM != nullptr)
+ {
+ const sw::mark::IFieldmark::parameter_map_t* const pParameters = fieldBM->GetParameters();
+
+ OUString sListKey = ODF_FORMDROPDOWN_LISTENTRY;
+ sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries
+ = pParameters->find(sListKey);
+ if (pListEntries != pParameters->end())
+ {
+ css::uno::Sequence<OUString> vListEntries;
+ pListEntries->second >>= vListEntries;
+ for (OUString const& i : vListEntries)
+ aListBox->InsertEntry(i);
+ }
+ else
+ {
+ aListBox->InsertEntry(SwResId(STR_DROP_DOWN_EMPTY_LIST));
+ }
+
+ // Select the current one
+ OUString sResultKey = ODF_FORMDROPDOWN_RESULT;
+ sw::mark::IFieldmark::parameter_map_t::const_iterator pResult
+ = pParameters->find(sResultKey);
+ if (pResult != pParameters->end())
+ {
+ sal_Int32 nSelection = -1;
+ pResult->second >>= nSelection;
+ aListBox->SelectEntryPos(nSelection);
+ }
+ }
+
+ Size lbSize(aListBox->GetOptimalSize());
+ lbSize.AdjustWidth(50);
+ lbSize.AdjustHeight(20);
+ lbSize.setWidth(std::max(lbSize.Width(), nMinListWidth));
+ aListBox->SetSizePixel(lbSize);
+ aListBox->SetSelectHdl(LINK(this, SwFieldDialog, MyListBoxHandler));
+ aListBox->Show();
+
+ SetSizePixel(lbSize);
+}
+
+SwFieldDialog::~SwFieldDialog() { disposeOnce(); }
+
+void SwFieldDialog::dispose()
+{
+ aListBox.disposeAndClear();
+ FloatingWindow::dispose();
+}
+
+IMPL_LINK(SwFieldDialog, MyListBoxHandler, ListBox&, rBox, void)
+{
+ if (!rBox.IsTravelSelect())
+ {
+ OUString sSelection = rBox.GetSelectedEntry();
+ if (sSelection == SwResId(STR_DROP_DOWN_EMPTY_LIST))
+ {
+ EndPopupMode();
+ return;
+ }
+
+ sal_Int32 nSelection = rBox.GetSelectedEntryPos();
+ if (nSelection >= 0)
+ {
+ OUString sKey = ODF_FORMDROPDOWN_RESULT;
+ (*pFieldmark->GetParameters())[sKey] <<= nSelection;
+ pFieldmark->Invalidate();
+ SwView& rView = static_cast<SwEditWin*>(GetParent())->GetView();
+ rView.GetDocShell()->SetModified();
+ }
+
+ EndPopupMode();
+ }
+}
+
+DropDownFormFieldButton::DropDownFormFieldButton(SwEditWin* pEditWin,
+ sw::mark::DropDownFieldmark& rFieldmark)
+ : MenuButton(pEditWin, WB_DIALOGCONTROL)
+ , m_rFieldmark(rFieldmark)
+{
+ assert(GetParent());
+ assert(dynamic_cast<SwEditWin*>(GetParent()));
+}
+
+DropDownFormFieldButton::~DropDownFormFieldButton() { disposeOnce(); }
+
+void DropDownFormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea)
+{
+ assert(GetParent());
+
+ Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos());
+ Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize());
+
+ // First calculate the size of the frame around the field
+ int nPadding = aBoxSize.Height() / 4;
+ aBoxPos.AdjustX(-nPadding);
+ aBoxPos.AdjustY(-nPadding);
+ aBoxSize.AdjustWidth(2 * nPadding);
+ aBoxSize.AdjustHeight(2 * nPadding);
+
+ m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize);
+
+ // Then extend the size with the button area
+ aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height());
+
+ SetPosSizePixel(aBoxPos, aBoxSize);
+}
+
+void DropDownFormFieldButton::MouseButtonUp(const MouseEvent&)
+{
+ assert(GetParent());
+
+ Point aPixPos = GetPosPixel();
+ aPixPos.AdjustY(GetSizePixel().Height());
+
+ m_pFieldPopup = VclPtr<SwFieldDialog>::Create(static_cast<SwEditWin*>(GetParent()),
+ &m_rFieldmark, GetSizePixel().Width());
+ m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl));
+
+ tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0));
+ m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus);
+ Invalidate();
+}
+
+IMPL_LINK_NOARG(DropDownFormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void)
+{
+ m_pFieldPopup.disposeAndClear();
+ m_rFieldmark.Invalidate();
+ Show(false); // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen
+ Invalidate();
+}
+
+basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance)
+{
+ basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor);
+ aHslLine.setZ(aLuminance);
+ return basegfx::utils::hsl2rgb(aHslLine);
+}
+
+void DropDownFormFieldButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ SetMapMode(MapMode(MapUnit::MapPixel));
+
+ //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ Color aLineColor = Color(COL_BLACK);
+ Color aFillColor
+ = Color(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75)));
+
+ // Draw the frame around the field
+ // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame
+ int nPadding = 1;
+ Point aPos (nPadding, nPadding);
+ Size aSize (m_aFieldFramePixel.GetSize().Width() - nPadding, m_aFieldFramePixel.GetSize().Height() - 2 * nPadding);
+ const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize));
+ rRenderContext.SetLineColor(aLineColor);
+ rRenderContext.SetFillColor(COL_TRANSPARENT);
+ rRenderContext.DrawRect(aFrameRect);
+
+ // Draw the button next to the frame
+ Point aButtonPos(aFrameRect.TopLeft());
+ aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - 1);
+ Size aButtonSize(aFrameRect.GetSize());
+ aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding);
+ const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize));
+
+ // Background & border
+ rRenderContext.SetLineColor(aLineColor);
+ rRenderContext.SetFillColor(aFillColor);
+ rRenderContext.DrawRect(aButtonRect);
+
+ // the arrowhead
+ rRenderContext.SetLineColor(aLineColor);
+ rRenderContext.SetFillColor(aLineColor);
+
+ Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2),
+ aButtonPos.Y() + (aButtonSize.Height() / 2));
+ Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10);
+
+ tools::Polygon aPoly(3);
+ aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0);
+ aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1);
+ aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2);
+ rRenderContext.DrawPolygon(aPoly);
+}
+
+WindowHitTest DropDownFormFieldButton::ImplHitTest(const Point& rFramePos)
+{
+ // We need to check whether the position hits the button (the frame should be mouse transparent)
+ WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos);
+ if (aResult != WindowHitTest::Inside)
+ return aResult;
+ else
+ {
+ return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside
+ : WindowHitTest::Transparent;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 4bb6d6780295..2e2a5417d0a0 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -37,6 +37,7 @@
#include <comphelper/random.hxx>
#include <comphelper/anytostring.hxx>
#include <sal/log.hxx>
+#include <edtwin.hxx>
using namespace ::sw::mark;
using namespace ::com::sun::star;
@@ -481,11 +482,13 @@ namespace sw { namespace mark
DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM)
: Fieldmark(rPaM)
+ , m_pButton(nullptr)
{
}
DropDownFieldmark::~DropDownFieldmark()
{
+ m_pButton.disposeAndClear();
}
void DropDownFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
@@ -511,6 +514,44 @@ namespace sw { namespace mark
lcl_RemoveFieldMarks(this, pDoc,
CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
}
+
+ void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
+ {
+ if(m_aPortionPaintArea == rPortionPaintArea &&
+ m_pButton && m_pButton->IsVisible())
+ return;
+
+ m_aPortionPaintArea = rPortionPaintArea;
+ if(m_pButton)
+ {
+ m_pButton->Show();
+ m_pButton->CalcPosAndSize(m_aPortionPaintArea);
+ m_pButton->Invalidate();
+ }
+ }
+
+ void DropDownFieldmark::ShowButton(SwEditWin* pEditWin)
+ {
+ if(pEditWin)
+ {
+ if(!m_pButton)
+ m_pButton = VclPtr<DropDownFormFieldButton>::Create(pEditWin, *this);
+ m_pButton->CalcPosAndSize(m_aPortionPaintArea);
+ m_pButton->Show();
+ }
+ }
+
+ void DropDownFieldmark::HideButton()
+ {
+ if(m_pButton)
+ m_pButton->Show(false);
+ }
+
+ void DropDownFieldmark::RemoveButton()
+ {
+ if(m_pButton)
+ m_pButton.disposeAndClear();
+ }
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index af7a56200564..f04c7a06e1f8 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2009,6 +2009,8 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
if( m_bSVCursorVis )
m_pVisibleCursor->Show(); // show again
+
+ getIDocumentMarkAccess()->NotifyCursorUpdate(*this);
}
void SwCursorShell::RefreshBlockCursor()
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 6014215f9e70..13b1926ee62f 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -54,6 +54,7 @@
#include <viscrs.hxx>
#include <edimp.hxx>
#include <tools/datetimeutils.hxx>
+#include <view.hxx>
using namespace ::sw::mark;
@@ -372,6 +373,7 @@ namespace sw { namespace mark
, m_vFieldmarks()
, m_vAnnotationMarks()
, m_pDoc(&rDoc)
+ , m_pLastActiveFieldmark(nullptr)
{ }
::sw::mark::IMark* MarkManager::makeMark(const SwPaM& rPaM,
@@ -956,6 +958,9 @@ namespace sw { namespace mark
IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
if ( ppFieldmark != m_vFieldmarks.end() )
{
+ if(m_pLastActiveFieldmark == ppFieldmark->get())
+ ClearFieldActivation();
+
m_vFieldmarks.erase(ppFieldmark);
ret.reset(new LazyFieldmarkDeleter(*ppMark, m_pDoc));
}
@@ -1031,6 +1036,7 @@ namespace sw { namespace mark
void MarkManager::clearAllMarks()
{
+ ClearFieldActivation();
m_vFieldmarks.clear();
m_vBookmarks.clear();
@@ -1117,10 +1123,61 @@ namespace sw { namespace mark
SwPaM aPaM = SwPaM(pFieldmark->GetMarkPos());
// Remove the old fieldmark and create a new one with the new type
- deleteFieldmarkAt(*aPaM.GetPoint());
- return makeNoTextFieldBookmark(aPaM, sName, rNewType);
+ if(aPaM.GetPoint()->nContent > 0)
+ {
+ --aPaM.GetPoint()->nContent;
+ SwPosition aNewPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
+ deleteFieldmarkAt(aNewPos);
+ return makeNoTextFieldBookmark(aPaM, sName, rNewType);
+ }
+ return nullptr;
+ }
+
+ void MarkManager::NotifyCursorUpdate(const SwCursorShell& rCursorShell)
+ {
+ SwView* pSwView = dynamic_cast<SwView *>(rCursorShell.GetSfxViewShell());
+ if(!pSwView)
+ return;
+
+ SwEditWin& rEditWin = pSwView->GetEditWin();
+ SwPosition aPos(*rCursorShell.GetCursor()->GetPoint());
+ IFieldmark* pFieldBM = getFieldmarkFor(aPos);
+ DropDownFieldmark* pNewActiveFieldmark = nullptr;
+ if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMDROPDOWN)
+ && aPos.nContent.GetIndex() > 0 )
+ {
+ --aPos.nContent;
+ pFieldBM = getFieldmarkFor(aPos);
+ }
+
+ if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN )
+ {
+ if (m_pLastActiveFieldmark != pFieldBM)
+ {
+ DropDownFieldmark* pDropDownFm = dynamic_cast<DropDownFieldmark*>(pFieldBM);
+ pDropDownFm->ShowButton(&rEditWin);
+ pNewActiveFieldmark = pDropDownFm;
+ }
+ else
+ {
+ pNewActiveFieldmark = m_pLastActiveFieldmark;
+ }
+ }
+
+ if(pNewActiveFieldmark != m_pLastActiveFieldmark)
+ {
+ ClearFieldActivation();
+ m_pLastActiveFieldmark = pNewActiveFieldmark;
+ }
}
+ void MarkManager::ClearFieldActivation()
+ {
+ if(m_pLastActiveFieldmark)
+ m_pLastActiveFieldmark->RemoveButton();
+
+ m_pLastActiveFieldmark = nullptr;
+ }
IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
{
diff --git a/sw/source/core/inc/DropDownFormFieldButton.hxx b/sw/source/core/inc/DropDownFormFieldButton.hxx
new file mode 100644
index 000000000000..abe159860d6f
--- /dev/null
+++ b/sw/source/core/inc/DropDownFormFieldButton.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SW_SOURCE_CORE_TEXT_DROPDOWNFORMEFIELDBUTTO_HXX
+#define INCLUDED_SW_SOURCE_CORE_TEXT_DROPDOWNFORMEFIELDBUTTO_HXX
+
+#include <vcl/menubtn.hxx>
+#include <swrect.hxx>
+
+class SwFieldFormDropDownPortion;
+class SwEditWin;
+class FloatingWindow;
+namespace sw
+{
+namespace mark
+{
+class DropDownFieldmark;
+}
+}
+
+/**
+ * This button is shown when the cursor is in a drop-down form field.
+ * The user can select an item of the field using this button while filling in a form.
+ */
+class DropDownFormFieldButton : public MenuButton
+{
+public:
+ DropDownFormFieldButton(SwEditWin* pEditWin, sw::mark::DropDownFieldmark& rFieldMark);
+ virtual ~DropDownFormFieldButton() override;
+
+ void CalcPosAndSize(const SwRect& rPortionPaintArea);
+
+ virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
+ DECL_DLLPRIVATE_LINK(FieldPopupModeEndHdl, FloatingWindow*, void);
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual WindowHitTest ImplHitTest(const Point& rFramePos) override;
+
+private:
+ tools::Rectangle m_aFieldFramePixel;
+ sw::mark::DropDownFieldmark& m_rFieldmark;
+ VclPtr<FloatingWindow> m_pFieldPopup;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index 71ad5c913d6c..11291f7b881a 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -24,11 +24,16 @@
#include <IDocumentMarkAccess.hxx>
#include <unordered_set>
#include <unordered_map>
+#include <memory>
+
+class SwCursorShell;
namespace sw {
namespace mark {
typedef std::unordered_map<OUString, sal_Int32> MarkBasenameMapUniqueOffset_t;
+ class DropDownFieldmark;
+
class MarkManager
: virtual public IDocumentMarkAccess
{
@@ -88,6 +93,9 @@ namespace sw {
virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
+ virtual void NotifyCursorUpdate(const SwCursorShell& rCursorShell) override;
+ virtual void ClearFieldActivation() override;
+
void dumpAsXml(xmlTextWriterPtr pWriter) const;
// Annotation Marks
@@ -125,6 +133,8 @@ namespace sw {
container_t m_vAnnotationMarks;
SwDoc * const m_pDoc;
+
+ sw::mark::DropDownFieldmark* m_pLastActiveFieldmark;
};
} // namespace mark
}
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 29336abfcc90..c23a99be1be0 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -29,6 +29,8 @@
#include <osl/diagnose.h>
#include <IMark.hxx>
#include <swserv.hxx>
+#include <swrect.hxx>
+#include <DropDownFormFieldButton.hxx>
namespace com {
namespace sun {
@@ -42,6 +44,7 @@ namespace com {
struct SwPosition; // fwd Decl. wg. UI
class SwDoc;
+class SwEditWin;
namespace sw {
namespace mark {
@@ -267,6 +270,17 @@ namespace sw {
virtual ~DropDownFieldmark();
virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override;
virtual void ReleaseDoc(SwDoc* const pDoc) 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 ShowButton(SwEditWin* pEditWin);
+ void HideButton();
+ void RemoveButton();
+
+ private:
+ SwRect m_aPortionPaintArea;
+ VclPtr<DropDownFormFieldButton> m_pButton;
};
}
}
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 2697f3022639..fa56ada86eba 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -908,7 +908,7 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
}
else if (pBM->GetFieldname( ) == ODF_FORMDROPDOWN)
{
- pPor = new SwFieldFormDropDownPortion(sw::mark::ExpandFieldmark(pBM));
+ pPor = new SwFieldFormDropDownPortion(pBM, sw::mark::ExpandFieldmark(pBM));
}
/* we need to check for ODF_FORMTEXT for scenario having FormFields inside FORMTEXT.
* Otherwise file will crash on open.
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index e2a482e870dc..2a52f9b539c7 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -43,6 +43,7 @@
#include <accessibilityoptions.hxx>
#include <editeng/lrspitem.hxx>
#include <unicode/ubidi.h>
+#include <bookmrk.hxx>
using namespace ::com::sun::star;
@@ -1310,7 +1311,20 @@ sal_uInt16 SwCombinedPortion::GetViewWidth( const SwTextSizeInfo &rInf ) const
SwFieldPortion *SwFieldFormDropDownPortion::Clone(const OUString &rExpand) const
{
- return new SwFieldFormDropDownPortion(rExpand);
+ return new SwFieldFormDropDownPortion(m_pFieldMark, rExpand);
+}
+
+void SwFieldFormDropDownPortion::Paint( const SwTextPaintInfo &rInf ) const
+{
+ SwFieldPortion::Paint( rInf );
+
+ ::sw::mark::DropDownFieldmark* pDropDownField = dynamic_cast< ::sw::mark::DropDownFieldmark* >(m_pFieldMark);
+ if(pDropDownField)
+ {
+ SwRect aPaintArea;
+ rInf.CalcRect( *this, &aPaintArea );
+ pDropDownField->SetPortionPaintArea(aPaintArea);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
index 4434f1e8c577..069ab3798060 100644
--- a/sw/source/core/text/porfld.hxx
+++ b/sw/source/core/text/porfld.hxx
@@ -217,12 +217,18 @@ namespace sw { namespace mark {
class SwFieldFormDropDownPortion : public SwFieldPortion
{
public:
- explicit SwFieldFormDropDownPortion(const OUString &rExpand)
+ explicit SwFieldFormDropDownPortion(sw::mark::IFieldmark *pFieldMark, const OUString &rExpand)
: SwFieldPortion(rExpand)
+ , m_pFieldMark(pFieldMark)
{
}
// Field cloner for SplitGlue
virtual SwFieldPortion *Clone( const OUString &rExpand ) const override;
+
+ virtual void Paint( const SwTextPaintInfo &rInf ) const override;
+
+private:
+ sw::mark::IFieldmark* m_pFieldMark;
};
#endif
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 22458d77b710..85d24b1d61c5 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -4627,12 +4627,6 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
rCheckboxFm.SetChecked(!rCheckboxFm.IsChecked());
rCheckboxFm.Invalidate();
rSh.InvalidateWindows( m_rView.GetVisArea() );
- } else if ( fieldBM->GetFieldname() == ODF_FORMDROPDOWN ) {
- m_rView.ExecFieldPopup( aDocPt, fieldBM );
- fieldBM->Invalidate();
- rSh.InvalidateWindows( m_rView.GetVisArea() );
- } else {
- // unknown type..
}
}
}
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index 65484c32e748..c70e84156b97 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -120,6 +120,8 @@
#include <numrule.hxx>
#include <memory>
#include <xmloff/odffields.hxx>
+#include <swabstdlg.hxx>
+#include <bookmrk.hxx>
using namespace ::com::sun::star;
using namespace com::sun::star::beans;
@@ -1382,10 +1384,14 @@ void SwTextShell::Execute(SfxRequest &rReq)
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDropDownFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), pFieldBM));
- pDlg->Execute();
- pFieldBM->Invalidate();
- rWrtSh.InvalidateWindows( rWrtSh.GetView().GetVisArea() );
- rWrtSh.UpdateCursor(); // cursor position might be invalid
+ if (pDlg->Execute() == RET_OK)
+ {
+ pFieldBM->Invalidate();
+ rWrtSh.InvalidateWindows( rWrtSh.GetView().GetVisArea() );
+ rWrtSh.UpdateCursor(); // cursor position might be invalid
+ // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen
+ dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldBM)->HideButton();
+ }
}
else
{
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 63febf29b44a..59fc540e0d35 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -1067,6 +1067,9 @@ SwView::~SwView()
SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", "");
SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY");
+ // Need to remove activated field's button before disposing EditWin.
+ GetWrtShell().getIDocumentMarkAccess()->ClearFieldActivation();
+
GetViewFrame()->GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) );
m_pPostItMgr.reset();
diff --git a/sw/source/uibase/uiview/viewling.cxx b/sw/source/uibase/uiview/viewling.cxx
index 7d6aac2913d9..3ac2ebcadd3e 100644
--- a/sw/source/uibase/uiview/viewling.cxx
+++ b/sw/source/uibase/uiview/viewling.cxx
@@ -825,114 +825,4 @@ void SwView::ExecSmartTagPopup( const Point& rPt )
m_pWrtShell->LockView( bOldViewLock );
}
-class SwFieldDialog : public FloatingWindow
-{
-private:
- VclPtr<ListBox> aListBox;
- IFieldmark *pFieldmark;
-
- DECL_LINK( MyListBoxHandler, ListBox&, void );
-
-public:
- SwFieldDialog( SwEditWin* parent, IFieldmark *fieldBM );
- virtual ~SwFieldDialog() override;
- virtual void dispose() override;
-};
-
-SwFieldDialog::SwFieldDialog( SwEditWin* parent, IFieldmark *fieldBM ) :
- FloatingWindow( parent, WB_BORDER | WB_SYSTEMWINDOW ),
- aListBox(VclPtr<ListBox>::Create(this)),
- pFieldmark( fieldBM )
-{
- if ( fieldBM != nullptr )
- {
- const IFieldmark::parameter_map_t* const pParameters = fieldBM->GetParameters();
-
- OUString sListKey = ODF_FORMDROPDOWN_LISTENTRY;
- IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find( sListKey );
- if(pListEntries != pParameters->end())
- {
- Sequence< OUString > vListEntries;
- pListEntries->second >>= vListEntries;
- for( OUString const & i : vListEntries)
- aListBox->InsertEntry(i);
- }
-
- // Select the current one
- OUString sResultKey = ODF_FORMDROPDOWN_RESULT;
- IFieldmark::parameter_map_t::const_iterator pResult = pParameters->find( sResultKey );
- if ( pResult != pParameters->end() )
- {
- sal_Int32 nSelection = -1;
- pResult->second >>= nSelection;
- aListBox->SelectEntryPos( nSelection );
- }
- }
-
- Size lbSize(aListBox->GetOptimalSize());
- lbSize.AdjustWidth(50 );
- lbSize.AdjustHeight(20 );
- aListBox->SetSizePixel(lbSize);
- aListBox->SetSelectHdl( LINK( this, SwFieldDialog, MyListBoxHandler ) );
- aListBox->Show();
-
- SetSizePixel( lbSize );
-}
-
-SwFieldDialog::~SwFieldDialog()
-{
- disposeOnce();
-}
-
-void SwFieldDialog::dispose()
-{
- aListBox.disposeAndClear();
- FloatingWindow::dispose();
-}
-
-IMPL_LINK( SwFieldDialog, MyListBoxHandler, ListBox&, rBox, void )
-{
- if ( !rBox.IsTravelSelect() )
- {
- sal_Int32 selection = rBox.GetSelectedEntryPos();
- if ( selection >= 0 )
- {
- OUString sKey = ODF_FORMDROPDOWN_RESULT;
- (*pFieldmark->GetParameters())[ sKey ] <<= selection;
- pFieldmark->Invalidate();
- SwView& rView = static_cast<SwEditWin*>( GetParent() )->GetView();
- rView.GetDocShell()->SetModified();
- }
-
- EndPopupMode();
- }
-}
-
-IMPL_LINK_NOARG(SwView, FieldPopupModeEndHdl, FloatingWindow*, void)
-{
- m_pFieldPopup.disposeAndClear();
-}
-
-void SwView::ExecFieldPopup( const Point& rPt, IFieldmark *fieldBM )
-{
- // Don't show popup if there is no list item
- auto pListEntries = fieldBM->GetParameters()->find( ODF_FORMDROPDOWN_LISTENTRY );
- Sequence< OUString > vListEntries;
- if(pListEntries != fieldBM->GetParameters()->end())
- {
- pListEntries->second >>= vListEntries;
- }
-
- if(vListEntries.getLength() == 0)
- return;
-
- const Point aPixPos = GetEditWin().LogicToPixel( rPt );
-
- m_pFieldPopup = VclPtr<SwFieldDialog>::Create( m_pEditWin, fieldBM );
- m_pFieldPopup->SetPopupModeEndHdl( LINK( this, SwView, FieldPopupModeEndHdl ) );
-
- tools::Rectangle aRect( m_pEditWin->OutputToScreenPixel( aPixPos ), Size( 0, 0 ) );
- m_pFieldPopup->StartPopupMode( aRect, FloatWinPopupFlags::Down|FloatWinPopupFlags::GrabFocus );
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 05a35636290161c7a86b88980c0e6b01001bbe86
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Mar 2 08:41:01 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 13:33:49 2019 +0100
MSForms: Introduce a new IFieldMark for drop-down form field
* It was weird anyway that a drop-down form field was represented
as an CheckboxFieldmark.
* It will be useful for later commits, to have a separate field type
for drop-down field.
* Needed to fix-up the API a bit because it was designed to specify
the field type after initialization. I solved it in a way to not break
the API behavior. Hopefully it's not very slow.
Change-Id: I3103e6b1c36289b27b62ab9ca7dfeebc14901c8a
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 823326e2b8ac..cbd523c012b1 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -47,6 +47,7 @@ class IDocumentMarkAccess
ANNOTATIONMARK,
TEXT_FIELDMARK,
CHECKBOX_FIELDMARK,
+ DROPDOWN_FIELDMARK,
NAVIGATOR_REMINDER
};
@@ -255,6 +256,7 @@ class IDocumentMarkAccess
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0;
virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
+ virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
// Annotation Marks
virtual const_iterator_t getAnnotationMarksBegin() const = 0;
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 92bb4c67d786..4bb6d6780295 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -478,6 +478,39 @@ namespace sw { namespace mark
pResult->second >>= bResult;
return bResult;
}
+
+ DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM)
+ : Fieldmark(rPaM)
+ {
+ }
+
+ DropDownFieldmark::~DropDownFieldmark()
+ {
+ }
+
+ void DropDownFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
+ {
+ if (eMode == sw::mark::InsertMode::New)
+ {
+ lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+
+ // For some reason the end mark is moved from 1 by the Insert:
+ // we don't want this for checkboxes
+ SwPosition aNewEndPos = GetMarkEnd();
+ aNewEndPos.nContent--;
+ SetMarkEndPos( aNewEndPos );
+ }
+ else
+ {
+ lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+ }
+ }
+
+ void DropDownFieldmark::ReleaseDoc(SwDoc* const pDoc)
+ {
+ lcl_RemoveFieldMarks(this, pDoc,
+ CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+ }
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index e06908f3438a..6014215f9e70 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -338,6 +338,8 @@ IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
return MarkType::TEXT_FIELDMARK;
else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
return MarkType::CHECKBOX_FIELDMARK;
+ else if(*pMarkTypeInfo == typeid(DropDownFieldmark))
+ return MarkType::DROPDOWN_FIELDMARK;
else if(*pMarkTypeInfo == typeid(NavigatorReminder))
return MarkType::NAVIGATOR_REMINDER;
else
@@ -414,6 +416,9 @@ namespace sw { namespace mark
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
pMark = std::shared_ptr<IMark>(new CheckboxFieldmark(rPaM));
break;
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
+ pMark = std::shared_ptr<IMark>(new DropDownFieldmark(rPaM));
+ break;
case IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER:
pMark = std::shared_ptr<IMark>(new NavigatorReminder(rPaM));
break;
@@ -462,6 +467,7 @@ namespace sw { namespace mark
break;
case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
lcl_InsertMarkSorted(m_vFieldmarks, pMark);
break;
case IDocumentMarkAccess::MarkType::ANNOTATIONMARK:
@@ -522,9 +528,20 @@ namespace sw { namespace mark
bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
m_pDoc->getIDocumentState().SetEnableSetModified(false);
- sw::mark::IMark* pMark = makeMark( rPaM, rName,
- IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
- sw::mark::InsertMode::New);
+ sw::mark::IMark* pMark = nullptr;
+ if(rType == ODF_FORMCHECKBOX)
+ {
+ pMark = makeMark( rPaM, rName,
+ IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
+ else if(rType == ODF_FORMDROPDOWN)
+ {
+ pMark = makeMark( rPaM, rName,
+ IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
+
sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
if (pFieldMark)
pFieldMark->SetFieldname( rType );
@@ -934,6 +951,7 @@ namespace sw { namespace mark
case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
{
IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
if ( ppFieldmark != m_vFieldmarks.end() )
@@ -1077,6 +1095,32 @@ namespace sw { namespace mark
deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
}
+ ::sw::mark::IFieldmark* MarkManager::changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType)
+ {
+ bool bActualChange = false;
+ if(rNewType == ODF_FORMDROPDOWN)
+ {
+ if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
+ bActualChange = true;
+ }
+ else if(rNewType == ODF_FORMCHECKBOX)
+ {
+ if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
+ bActualChange = true;
+ }
+
+ if (!bActualChange)
+ return nullptr;
+
+ // Store attributes needed to create the new fieldmark
+ OUString sName = pFieldmark->GetName();
+ SwPaM aPaM = SwPaM(pFieldmark->GetMarkPos());
+
+ // Remove the old fieldmark and create a new one with the new type
+ deleteFieldmarkAt(*aPaM.GetPoint());
+ return makeNoTextFieldBookmark(aPaM, sName, rNewType);
+ }
+
IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
{
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index cbae235520e8..71ad5c913d6c 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -86,6 +86,7 @@ namespace sw {
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override;
virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
+ virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
void dumpAsXml(xmlTextWriterPtr pWriter) const;
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 9bf1c9d7679c..29336abfcc90 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -245,6 +245,7 @@ namespace sw {
virtual void ReleaseDoc(SwDoc* const pDoc) override;
};
+ /// Fieldmark representing a checkbox form field.
class CheckboxFieldmark
: virtual public ICheckboxFieldmark
, public Fieldmark
@@ -256,6 +257,17 @@ namespace sw {
bool IsChecked() const override;
void SetChecked(bool checked) override;
};
+
+ /// Fieldmark representing a drop-down form field.
+ class DropDownFieldmark
+ : public Fieldmark
+ {
+ public:
+ DropDownFieldmark(const SwPaM& rPaM);
+ virtual ~DropDownFieldmark();
+ virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override;
+ virtual void ReleaseDoc(SwDoc* const pDoc) override;
+ };
}
}
#endif
diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx
index 95763c1b0a09..5c38402ba17c 100644
--- a/sw/source/core/inc/unobookmark.hxx
+++ b/sw/source/core/inc/unobookmark.hxx
@@ -68,6 +68,8 @@ protected:
const ::sw::mark::IMark* GetBookmark() const;
+ IDocumentMarkAccess* GetIDocumentMarkAccess();
+
void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase );
virtual ~SwXBookmark() override;
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 631373f98d99..2697f3022639 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -917,10 +917,6 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
{
pPor = new SwFieldMarkPortion();
}
- else
- {
- assert( false ); // unknown type...
- }
}
}
if( !pPor )
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index 753263a2aa6f..0a53c27c4516 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -134,6 +134,11 @@ const ::sw::mark::IMark* SwXBookmark::GetBookmark() const
return m_pImpl->m_pRegisteredBookmark;
}
+IDocumentMarkAccess* SwXBookmark::GetIDocumentMarkAccess()
+{
+ return m_pImpl->m_pDoc->getIDocumentMarkAccess();
+}
+
SwXBookmark::SwXBookmark(SwDoc *const pDoc)
: m_pImpl( new SwXBookmark::Impl(pDoc) )
{
@@ -620,7 +625,21 @@ void SwXFieldmark::setFieldType(const OUString & fieldType)
dynamic_cast<const IFieldmark*>(GetBookmark()));
if(!pBkm)
throw uno::RuntimeException();
- pBkm->SetFieldname(fieldType);
+ if(fieldType != getFieldType())
+ {
+ if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX)
+ {
+ ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeNonTextFieldmarkType(pBkm, fieldType);
+ if (pNewFieldmark)
+ {
+ registerInMark(*this, pNewFieldmark);
+ return;
+ }
+ }
+
+ // We did not generate a new fieldmark, so set the type ID
+ pBkm->SetFieldname(fieldType);
+ }
}
uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
@@ -654,6 +673,8 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
pXBkmk = new SwXFieldmark(false, &rDoc);
else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark))
pXBkmk = new SwXFieldmark(true, &rDoc);
+ else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark))
+ pXBkmk = new SwXFieldmark(true, &rDoc);
else
pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx b/writerfilter/source/dmapper/FormControlHelper.cxx
index 3088a4a27361..98e7bb0ba319 100644
--- a/writerfilter/source/dmapper/FormControlHelper.cxx
+++ b/writerfilter/source/dmapper/FormControlHelper.cxx
@@ -202,6 +202,20 @@ bool FormControlHelper::createCheckbox(uno::Reference<text::XTextRange> const& x
void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFormField)
{
+ // Set field type first before adding parameters.
+ if (m_pImpl->m_eFieldId == FIELD_FORMTEXT )
+ {
+ xFormField->setFieldType(ODF_FORMTEXT);
+ }
+ else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX )
+ {
+ xFormField->setFieldType(ODF_FORMCHECKBOX);
+ }
+ else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN )
+ {
+ xFormField->setFieldType(ODF_FORMDROPDOWN);
+ }
+
uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters();
uno::Reference<container::XNamed> xNamed( xFormField, uno::UNO_QUERY );
if ( m_pFFData && xNamed.is() && xNameCont.is() )
@@ -223,7 +237,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
if (m_pImpl->m_eFieldId == FIELD_FORMTEXT )
{
- xFormField->setFieldType(ODF_FORMTEXT);
sTmp = m_pFFData->getName();
try
{
@@ -255,7 +268,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
}
else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX )
{
- xFormField->setFieldType(ODF_FORMCHECKBOX);
uno::Reference<beans::XPropertySet> xPropSet(xFormField, uno::UNO_QUERY);
uno::Any aAny;
aAny <<= m_pFFData->getCheckboxChecked();
@@ -264,7 +276,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
}
else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN )
{
- xFormField->setFieldType(ODF_FORMDROPDOWN);
const FFDataHandler::DropDownEntries_t& rEntries = m_pFFData->getDropDownEntries();
if (!rEntries.empty())
{
commit 6ec07e00e19672c747ab7ee80b51f9e1d4ebe1e9
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Feb 20 12:45:44 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 13:33:48 2019 +0100
MSForms: Update cursor position after the drop down form field was changed
Change-Id: I0e9e8a0e9212cdf539caa163f9071bc2f21e4c9f
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index a732b8b8b669..5ba02d648620 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -162,6 +162,10 @@ public:
READONLY = (1 << 3) ///< make visible in spite of Readonly
};
+ SAL_DLLPRIVATE void UpdateCursor(
+ sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE,
+ bool bIdleEnd = false );
+
private:
SwRect m_aCharRect; ///< Char-SRectangle on which the cursor is located
@@ -232,10 +236,6 @@ private:
SwFrame* m_oldColFrame;
- SAL_DLLPRIVATE void UpdateCursor(
- sal_uInt16 eFlags = SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE,
- bool bIdleEnd = false );
-
SAL_DLLPRIVATE void MoveCursorToNum();
SAL_DLLPRIVATE void ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing );
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index 3a222507e9d5..65484c32e748 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -1385,6 +1385,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
pDlg->Execute();
pFieldBM->Invalidate();
rWrtSh.InvalidateWindows( rWrtSh.GetView().GetVisArea() );
+ rWrtSh.UpdateCursor(); // cursor position might be invalid
}
else
{
commit b14d838765eda899bfcc890feb0fef2a1fd76430
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Feb 21 13:40:14 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 13:33:48 2019 +0100
Fix typo
Change-Id: I2b09bf30c3769f6b987409cabf24735647d3c31d
diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx
index fa5d55497f8d..0eebed82220d 100644
--- a/sw/source/ui/config/optcomp.cxx
+++ b/sw/source/ui/config/optcomp.cxx
@@ -60,7 +60,7 @@ SwCompatibilityOptPage::SwCompatibilityOptPage(vcl::Window* pParent, const SfxIt
get(m_pFormattingLB, "format");
get(m_pGlobalOptionsLB, "globaloptions");
get(m_pOptionsLB, "options");
- get(m_pGlobalOptionsCLB, "globaloptioncheckboxs");
+ get(m_pGlobalOptionsCLB, "globaloptioncheckbox");
get(m_pDefaultPB, "default");
for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module) + 1; i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
diff --git a/sw/uiconfig/swriter/ui/optcompatpage.ui b/sw/uiconfig/swriter/ui/optcompatpage.ui
index 8f4a5342c75d..3965324f43bb 100644
--- a/sw/uiconfig/swriter/ui/optcompatpage.ui
+++ b/sw/uiconfig/swriter/ui/optcompatpage.ui
@@ -140,7 +140,7 @@
<property name="can_focus">False</property>
<property name="row_spacing">5</property>
<child>
- <object class="svxcorelo-SvxCheckListBox" id="globaloptioncheckboxs:border">
+ <object class="svxcorelo-SvxCheckListBox" id="globaloptioncheckbox:border">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
commit 2e5450ee85e21a2ad193360d88a82a6eb2d8bdef
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Feb 21 13:39:27 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 13:33:48 2019 +0100
MSForms: Disable legacy field menu slots if the cursor is inside a text field
Insertion of fields inside fields is not an allowed operation.
Change-Id: Icfdbc1add9c828227201b70cd545a83b6dcbc3e6
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index ccf3952aaa97..c172b613339d 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -923,6 +923,12 @@ void SwTextShell::StateField( SfxItemSet &rSet )
case FN_INSERT_FLD_TITLE:
case FN_INSERT_FLD_TOPIC:
case FN_INSERT_DBFIELD:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
case FN_INSERT_TEXT_FORMFIELD:
case FN_INSERT_CHECKBOX_FORMFIELD:
case FN_INSERT_DROPDOWN_FORMFIELD:
@@ -930,6 +936,24 @@ void SwTextShell::StateField( SfxItemSet &rSet )
{
rSet.DisableItem(nWhich);
}
+ else
+ {
+ // Check whether we are in a text form field
+ SwPosition aCursorPos(*rSh.GetCursor()->GetPoint());
+ sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aCursorPos);
+ if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMTEXT)
+ && aCursorPos.nContent.GetIndex() > 0)
+ {
+ SwPosition aPos(aCursorPos);
+ --aPos.nContent;
+ pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+ }
+ if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMTEXT &&
+ (aCursorPos > pFieldBM->GetMarkStart() && aCursorPos < pFieldBM->GetMarkEnd() ))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
break;
}
commit d71b5808343fb48b41d5089b7c42ced31a377e06
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Feb 21 13:38:33 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Mar 8 13:33:48 2019 +0100
MSForms: Implement undo / redo for insertion of legacy form fields
Need to handle undo / redo explicitely for form fields, because
there is no a general working undo / redo mechanism for fieldmarks.
During the insertion of the fieldmark, text insertion also happens which
generates an interfering undo action, so we need to disable undoing
temporary.
Also need to invalidta SID_UNDO slot to make the undo toolbar item updated
after we insert a form field.
Change-Id: I358c2704cb30212a38f8a998888a36f72fa404e5
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 3fb7090e5067..823326e2b8ac 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -254,6 +254,8 @@ class IDocumentMarkAccess
virtual ::sw::mark::IFieldmark* getDropDownFor(const SwPosition& pos) const=0;
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list