store/CppunitTest_store.mk | 22 +++ store/Module_store.mk | 4 store/qa/store.cxx | 88 ++++++++++++++ sw/source/ui/misc/contentcontroldlg.cxx | 92 +++++++++++++++ sw/source/ui/misc/contentcontrollistitemdlg.cxx | 2 sw/source/uibase/inc/contentcontroldlg.hxx | 9 + sw/uiconfig/swriter/ui/contentcontroldlg.ui | 42 +++++-- sw/uiconfig/swriter/ui/contentcontrollistitemdlg.ui | 118 +++++++++----------- 8 files changed, 306 insertions(+), 71 deletions(-)
New commits: commit 9d64ab991b378e929c7c62a49bfc9d4016f30a22 Author: Chris Sherlock <chris.sherloc...@gmail.com> AuthorDate: Wed Dec 29 06:38:50 2021 +1100 Commit: Stephan Bergmann <sberg...@redhat.com> CommitDate: Mon May 16 18:23:14 2022 +0200 store: add unit tests Test: - create a file in memory - open a stream - write a byte to the stream - read the byte from the stream Change-Id: I257880bdd9020d2410f183e612a356eb785621ed Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127674 Reviewed-by: Stephan Bergmann <sberg...@redhat.com> Tested-by: Jenkins diff --git a/store/CppunitTest_store.mk b/store/CppunitTest_store.mk new file mode 100644 index 000000000000..e08ebc840c6b --- /dev/null +++ b/store/CppunitTest_store.mk @@ -0,0 +1,22 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; 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/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,store)) + +$(eval $(call gb_CppunitTest_use_libraries,store,\ + sal \ + salhelper \ + store \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,store,\ + store/qa/store \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/store/Module_store.mk b/store/Module_store.mk index 71374e88973e..9eb5ee35aebd 100644 --- a/store/Module_store.mk +++ b/store/Module_store.mk @@ -13,4 +13,8 @@ $(eval $(call gb_Module_add_targets,store,\ Library_store \ )) +$(eval $(call gb_Module_add_check_targets,store,\ + CppunitTest_store \ +)) + # vim:set noet sw=4 ts=4: diff --git a/store/qa/store.cxx b/store/qa/store.cxx new file mode 100644 index 000000000000..69bc3f8f8674 --- /dev/null +++ b/store/qa/store.cxx @@ -0,0 +1,88 @@ +/* -*- 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 <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <store/store.hxx> + +#include <memory> + +namespace +{ +class StoreTest : public CppUnit::TestFixture +{ +public: + void createMemoryStream(); + void createStream(); + void writeAndReadByte(); + + CPPUNIT_TEST_SUITE(StoreTest); + CPPUNIT_TEST(createMemoryStream); + CPPUNIT_TEST(createStream); + CPPUNIT_TEST(writeAndReadByte); + CPPUNIT_TEST_SUITE_END(); +}; + +void StoreTest::createMemoryStream() +{ + store::OStoreFile aFile; + CPPUNIT_ASSERT_EQUAL(store_E_None, aFile.createInMemory()); +} + +void StoreTest::createStream() +{ + store::OStoreFile aFile; + CPPUNIT_ASSERT_EQUAL(store_E_None, aFile.createInMemory()); + + store::OStoreStream aStream; + CPPUNIT_ASSERT_EQUAL(store_E_None, + aStream.create(aFile, "testnode", "testname", storeAccessMode::Create)); + + aFile.close(); +} + +void StoreTest::writeAndReadByte() +{ + store::OStoreFile aFile; + CPPUNIT_ASSERT_EQUAL(store_E_None, aFile.createInMemory()); + + store::OStoreStream aStream; + CPPUNIT_ASSERT_EQUAL(store_E_None, + aStream.create(aFile, "testnode", "testname", storeAccessMode::Create)); + + { + std::unique_ptr<sal_uInt8[]> pWriteBuffer(new sal_uInt8[1]); + pWriteBuffer[0] = 'a'; + + sal_uInt32 writtenBytes; + + CPPUNIT_ASSERT_EQUAL(store_E_None, aStream.writeAt(0, pWriteBuffer.get(), 1, writtenBytes)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(1), writtenBytes); + } + + { + std::unique_ptr<sal_uInt8[]> pReadBuffer(new sal_uInt8[1]); + sal_uInt32 readBytes; + + CPPUNIT_ASSERT_EQUAL(store_E_None, aStream.readAt(0, pReadBuffer.get(), 1, readBytes)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(1), readBytes); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt8>('a'), pReadBuffer[0]); + } + + aFile.close(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(StoreTest); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit a1e2fc012113339564b3414d03a6eaf118ff2713 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon May 16 15:11:52 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 16 18:23:01 2022 +0200 sw content controls, dropdown: edit list items: add modify and delete Modify is really similar to insert, just we pre-fill the list item properties dialog with old data. Also allow moving items up / down, and eliminate a not needed frame in the inner dialog, which would assert when using the gen backend. With this, the content control dialog is quite complete for dropdowns. Change-Id: I26e77dd881f0a0eea44d2a6137f76fd29ab32fc5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134405 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/source/ui/misc/contentcontroldlg.cxx b/sw/source/ui/misc/contentcontroldlg.cxx index 7a066fb80d22..9e5902149720 100644 --- a/sw/source/ui/misc/contentcontroldlg.cxx +++ b/sw/source/ui/misc/contentcontroldlg.cxx @@ -38,14 +38,24 @@ SwContentControlDlg::SwContentControlDlg(weld::Window* pParent, SwWrtShell& rWrt , m_xListItems(m_xBuilder->weld_tree_view("listitems")) , m_xListItemButtons(m_xBuilder->weld_box("listitembuttons")) , m_xInsertBtn(m_xBuilder->weld_button("add")) + , m_xRenameBtn(m_xBuilder->weld_button("modify")) + , m_xDeleteBtn(m_xBuilder->weld_button("remove")) + , m_xMoveUpBtn(m_xBuilder->weld_button("moveup")) + , m_xMoveDownBtn(m_xBuilder->weld_button("movedown")) , m_xOk(m_xBuilder->weld_button("ok")) { m_xOk->connect_clicked(LINK(this, SwContentControlDlg, OkHdl)); // Only 2 items would be visible by default. m_xListItems->set_size_request(-1, m_xListItems->get_height_rows(8)); + // Only the first column would have a non-zero size by default in the SvHeaderTabListBox case. + m_xListItems->set_column_fixed_widths({ 100, 100 }); m_xInsertBtn->connect_clicked(LINK(this, SwContentControlDlg, InsertHdl)); + m_xRenameBtn->connect_clicked(LINK(this, SwContentControlDlg, RenameHdl)); + m_xDeleteBtn->connect_clicked(LINK(this, SwContentControlDlg, DeleteHdl)); + m_xMoveUpBtn->connect_clicked(LINK(this, SwContentControlDlg, MoveUpHdl)); + m_xMoveDownBtn->connect_clicked(LINK(this, SwContentControlDlg, MoveDownHdl)); const SwPosition* pStart = rWrtShell.GetCursor()->Start(); SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode(); @@ -153,4 +163,86 @@ IMPL_LINK_NOARG(SwContentControlDlg, InsertHdl, weld::Button&, void) m_xListItems->set_text(nRow, aItem.m_aValue, 1); } +IMPL_LINK_NOARG(SwContentControlDlg, RenameHdl, weld::Button&, void) +{ + int nRow = m_xListItems->get_selected_index(); + if (nRow < 0) + { + return; + } + + SwContentControlListItem aItem; + aItem.m_aDisplayText = m_xListItems->get_text(nRow, 0); + aItem.m_aValue = m_xListItems->get_text(nRow, 1); + SwAbstractDialogFactory& rFact = swui::GetFactory(); + ScopedVclPtr<VclAbstractDialog> pDlg( + rFact.CreateSwContentControlListItemDlg(m_xDialog.get(), aItem)); + if (!pDlg->Execute()) + { + return; + } + + if (aItem.m_aDisplayText.isEmpty() && aItem.m_aValue.isEmpty()) + { + // Maintain the invariant that value can't be empty. + return; + } + + if (aItem.m_aValue.isEmpty()) + { + aItem.m_aValue = aItem.m_aDisplayText; + } + + m_xListItems->set_text(nRow, aItem.m_aDisplayText, 0); + m_xListItems->set_text(nRow, aItem.m_aValue, 1); +} + +IMPL_LINK_NOARG(SwContentControlDlg, DeleteHdl, weld::Button&, void) +{ + int nRow = m_xListItems->get_selected_index(); + if (nRow < 0) + { + return; + } + + m_xListItems->remove(nRow); +} + +IMPL_LINK_NOARG(SwContentControlDlg, MoveUpHdl, weld::Button&, void) +{ + int nRow = m_xListItems->get_selected_index(); + if (nRow <= 0) + { + return; + } + + SwContentControlListItem aItem; + aItem.m_aDisplayText = m_xListItems->get_text(nRow, 0); + aItem.m_aValue = m_xListItems->get_text(nRow, 1); + m_xListItems->remove(nRow); + --nRow; + m_xListItems->insert_text(nRow, aItem.m_aDisplayText); + m_xListItems->set_text(nRow, aItem.m_aValue, 1); + m_xListItems->select(nRow); +} + +IMPL_LINK_NOARG(SwContentControlDlg, MoveDownHdl, weld::Button&, void) +{ + int nRow = m_xListItems->get_selected_index(); + int nEndPos = m_xListItems->n_children() - 1; + if (nRow < 0 || nRow >= nEndPos) + { + return; + } + + SwContentControlListItem aItem; + aItem.m_aDisplayText = m_xListItems->get_text(nRow, 0); + aItem.m_aValue = m_xListItems->get_text(nRow, 1); + m_xListItems->remove(nRow); + ++nRow; + m_xListItems->insert_text(nRow, aItem.m_aDisplayText); + m_xListItems->set_text(nRow, aItem.m_aValue, 1); + m_xListItems->select(nRow); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/misc/contentcontrollistitemdlg.cxx b/sw/source/ui/misc/contentcontrollistitemdlg.cxx index ca6716b7b770..6ac160aebb10 100644 --- a/sw/source/ui/misc/contentcontrollistitemdlg.cxx +++ b/sw/source/ui/misc/contentcontrollistitemdlg.cxx @@ -33,6 +33,8 @@ SwContentControlListItemDlg::SwContentControlListItemDlg(weld::Widget* pParent, , m_xOk(m_xBuilder->weld_button("ok")) { m_xOk->connect_clicked(LINK(this, SwContentControlListItemDlg, OkHdl)); + m_xDisplayNameED->set_text(rItem.m_aDisplayText); + m_xValueED->set_text(rItem.m_aValue); } IMPL_LINK_NOARG(SwContentControlListItemDlg, OkHdl, weld::Button&, void) diff --git a/sw/source/uibase/inc/contentcontroldlg.hxx b/sw/source/uibase/inc/contentcontroldlg.hxx index 45a6659b4fbf..642c7d078fe5 100644 --- a/sw/source/uibase/inc/contentcontroldlg.hxx +++ b/sw/source/uibase/inc/contentcontroldlg.hxx @@ -40,9 +40,18 @@ class SwContentControlDlg final : public SfxDialogController std::unique_ptr<weld::TreeView> m_xListItems; std::unique_ptr<weld::Box> m_xListItemButtons; std::unique_ptr<weld::Button> m_xInsertBtn; + std::unique_ptr<weld::Button> m_xRenameBtn; + std::unique_ptr<weld::Button> m_xDeleteBtn; + std::unique_ptr<weld::Button> m_xMoveUpBtn; + std::unique_ptr<weld::Button> m_xMoveDownBtn; + std::unique_ptr<weld::Button> m_xOk; DECL_LINK(InsertHdl, weld::Button&, void); + DECL_LINK(RenameHdl, weld::Button&, void); + DECL_LINK(DeleteHdl, weld::Button&, void); + DECL_LINK(MoveUpHdl, weld::Button&, void); + DECL_LINK(MoveDownHdl, weld::Button&, void); DECL_LINK(OkHdl, weld::Button&, void); public: diff --git a/sw/uiconfig/swriter/ui/contentcontroldlg.ui b/sw/uiconfig/swriter/ui/contentcontroldlg.ui index 4a1eb810a75c..815d0f14ef35 100644 --- a/sw/uiconfig/swriter/ui/contentcontroldlg.ui +++ b/sw/uiconfig/swriter/ui/contentcontroldlg.ui @@ -206,13 +206,13 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="pack-type">end</property> + <property name="pack-type">start</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkButton" id="remove"> - <property name="label" translatable="yes" context="contentcontordlg|remove">Remove</property> + <object class="GtkButton" id="modify"> + <property name="label" translatable="yes" context="contentcontordlg|modify">Modify</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">True</property> @@ -220,13 +220,13 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="pack-type">end</property> + <property name="pack-type">start</property> <property name="position">1</property> </packing> </child> <child> - <object class="GtkButton" id="modify"> - <property name="label" translatable="yes" context="contentcontordlg|modify">Modify</property> + <object class="GtkButton" id="remove"> + <property name="label" translatable="yes" context="contentcontordlg|remove">Remove</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">True</property> @@ -234,10 +234,38 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="pack-type">end</property> + <property name="pack-type">start</property> <property name="position">2</property> </packing> </child> + <child> + <object class="GtkButton" id="moveup"> + <property name="label" translatable="yes" context="contentcontordlg|moveup">Move Up</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack-type">start</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton" id="movedown"> + <property name="label" translatable="yes" context="contentcontordlg|movedown">Move Down</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack-type">start</property> + <property name="position">4</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> diff --git a/sw/uiconfig/swriter/ui/contentcontrollistitemdlg.ui b/sw/uiconfig/swriter/ui/contentcontrollistitemdlg.ui index 8d580179be50..d9e6a770038e 100644 --- a/sw/uiconfig/swriter/ui/contentcontrollistitemdlg.ui +++ b/sw/uiconfig/swriter/ui/contentcontrollistitemdlg.ui @@ -73,79 +73,69 @@ </packing> </child> <child> - <object class="GtkFrame" id="frame1"> + <!-- n-columns=2 n-rows=2 --> + <object class="GtkGrid" id="grid1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <property name="margin-start">12</property> + <property name="margin-top">6</property> <child> - <!-- n-columns=2 n-rows=2 --> - <object class="GtkGrid" id="grid1"> + <object class="GtkLabel" id="lbdisplayname"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="label" translatable="yes" context="contentcontrollistitemdlg|lbdisplayname">Display name:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">displayname</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="displayname"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <property name="activates_default">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="lbvalue"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="contentcontrollistitemdlg|lbvalue">Value:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">value</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="value"> + <property name="visible">True</property> + <property name="can_focus">True</property> <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - <property name="margin-start">12</property> - <property name="margin-top">6</property> - <child> - <object class="GtkLabel" id="lbdisplayname"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="contentcontrollistitemdlg|lbdisplayname">Display name:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">displayname</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="displayname"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="truncate-multiline">True</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lbvalue"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="contentcontrollistitemdlg|lbvalue">Value:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">value</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="value"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="truncate-multiline">True</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> + <property name="truncate-multiline">True</property> + <property name="activates_default">True</property> </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> </child> </object> <packing>