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>

Reply via email to