framework/CppunitTest_framework_accelerators.mk |   41 +++++++
 framework/Module_framework.mk                   |    1 
 framework/qa/cppunit/accelerators.cxx           |  139 ++++++++++++++++++++++++
 3 files changed, 181 insertions(+)

New commits:
commit 713732b0a2ad91555dcd706d93527dbb9d154015
Author:     Neil Roberts <[email protected]>
AuthorDate: Thu Sep 18 18:59:14 2025 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Wed Sep 24 20:28:13 2025 +0200

    Add a unit test for the accelerator configurations
    
    This is meant to test the problems described in the following commits:
    
    96491f3f842bb911aca62e74d29865c3f36618e8
    7da503470666bbcf2062e60fd4796f7316ac14f8
    
    Change-Id: I2f79e8812de6f70d270eefb01aa7e2940c87166a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191173
    Tested-by: Jenkins
    Tested-by: Xisco Fauli <[email protected]>
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/framework/CppunitTest_framework_accelerators.mk 
b/framework/CppunitTest_framework_accelerators.mk
new file mode 100644
index 000000000000..3df8c3116efb
--- /dev/null
+++ b/framework/CppunitTest_framework_accelerators.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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,framework_accelerators))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,framework_accelerators, \
+    framework/qa/cppunit/accelerators \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,framework_accelerators, \
+       comphelper \
+       cppu \
+       cppuhelper \
+       fwk \
+       sal \
+       subsequenttest \
+       utl \
+       tl \
+       test \
+       unotest \
+))
+
+$(eval $(call 
gb_CppunitTest_use_external,framework_accelerators,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,framework_accelerators))
+
+$(eval $(call gb_CppunitTest_use_ure,framework_accelerators))
+
+$(eval $(call gb_CppunitTest_use_vcl,framework_accelerators))
+
+$(eval $(call gb_CppunitTest_use_rdb,framework_accelerators,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,framework_accelerators))
+
+# vim: set noet sw=4 ts=4:
diff --git a/framework/Module_framework.mk b/framework/Module_framework.mk
index 7521418d3861..1ae995133648 100644
--- a/framework/Module_framework.mk
+++ b/framework/Module_framework.mk
@@ -29,6 +29,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,framework,\
     CppunitTest_framework_dispatch \
     CppunitTest_framework_loadenv \
        CppunitTest_framework_CheckXTitle \
+    CppunitTest_framework_accelerators \
 ))
 
 # Not sure why this is not stable on macOS.
diff --git a/framework/qa/cppunit/accelerators.cxx 
b/framework/qa/cppunit/accelerators.cxx
new file mode 100644
index 000000000000..6f1fd27d0ab8
--- /dev/null
+++ b/framework/qa/cppunit/accelerators.cxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+#include <test/unoapi_test.hxx>
+
+#include <array>
+
+using namespace css;
+
+class AcceleratorsTest : public UnoApiTest
+{
+public:
+    AcceleratorsTest()
+        : UnoApiTest(u"/framework/qa/cppunit/data"_ustr)
+    {
+    }
+
+    void configNotification();
+
+    CPPUNIT_TEST_SUITE(AcceleratorsTest);
+    CPPUNIT_TEST(configNotification);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void AcceleratorsTest::configNotification()
+{
+    uno::Reference<lang::XMultiServiceFactory> xFactory = 
getMultiServiceFactory();
+
+    uno::Reference<ui::XAcceleratorConfiguration> xGlobalAccelCfg(
+        
xFactory->createInstance(u"com.sun.star.ui.GlobalAcceleratorConfiguration"_ustr),
+        uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xGlobalAccelCfg.is());
+
+    // Create two instances of the Writer module accelerator config so
+    // we can test that updates are copied between them
+    std::array<uno::Reference<ui::XAcceleratorConfiguration>, 2> xSwAccelCfgs;
+
+    for (auto& xSwAccelCfg : xSwAccelCfgs)
+    {
+        uno::Sequence<uno::Any> args(1);
+        args.getArray()[0] <<= u"com.sun.star.text.TextDocument"_ustr;
+
+        xSwAccelCfg.set(xFactory->createInstanceWithArguments(
+                            
u"com.sun.star.ui.ModuleAcceleratorConfiguration"_ustr, args),
+                        uno::UNO_QUERY);
+        CPPUNIT_ASSERT(xSwAccelCfg.is());
+    }
+
+    // The two modules configs shouldn’t be the same object, otherwise
+    // the test is not really testing anything
+    CPPUNIT_ASSERT(xSwAccelCfgs[0] != xSwAccelCfgs[1]);
+
+    // Create an instance of another module
+    uno::Sequence<uno::Any> args(1);
+    args.getArray()[0] <<= u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
+    uno::Reference<ui::XAcceleratorConfiguration> xScAccelCfg(
+        xFactory->createInstanceWithArguments(
+            u"com.sun.star.ui.ModuleAcceleratorConfiguration"_ustr, args),
+        uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xScAccelCfg.is());
+
+    awt::KeyEvent aKeyEvent;
+    aKeyEvent.KeyCode = awt::Key::F16;
+
+    // Make sure the key we’re going to test isn’t already defined
+    CPPUNIT_ASSERT_THROW(xGlobalAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    for (const auto& xSwAccelCfg : xSwAccelCfgs)
+    {
+        CPPUNIT_ASSERT_THROW(xSwAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                             css::container::NoSuchElementException);
+    }
+    CPPUNIT_ASSERT_THROW(xScAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+
+    // Set the key event on the module
+    xSwAccelCfgs[0]->setKeyEvent(aKeyEvent, u".uno:Bold"_ustr);
+
+    // Store the changed configuration. This should trigger a change event
+    uno::Reference<ui::XUIConfigurationPersistence> 
xConfPersistence(xSwAccelCfgs[0],
+                                                                     
uno::UNO_QUERY);
+    xConfPersistence->store();
+
+    // The key shouldn’t have been copied to the global configuration
+    CPPUNIT_ASSERT_THROW(xGlobalAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    // Nor the Calc module
+    CPPUNIT_ASSERT_THROW(xScAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+
+    // Make sure the key was copied to all of the Writer module
+    // configurations
+    for (const auto& xSwAccelCfg : xSwAccelCfgs)
+        CPPUNIT_ASSERT_EQUAL(u".uno:Bold"_ustr, 
xSwAccelCfg->getCommandByKeyEvent(aKeyEvent));
+
+    // Modify the key to a different command
+    xSwAccelCfgs[0]->setKeyEvent(aKeyEvent, u".uno:Italic"_ustr);
+    xConfPersistence->store();
+
+    // Check the propagation worked correctly
+    CPPUNIT_ASSERT_THROW(xGlobalAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    CPPUNIT_ASSERT_THROW(xScAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    for (const auto& xSwAccelCfg : xSwAccelCfgs)
+        CPPUNIT_ASSERT_EQUAL(u".uno:Italic"_ustr, 
xSwAccelCfg->getCommandByKeyEvent(aKeyEvent));
+
+    // Remove the key binding
+    xSwAccelCfgs[0]->removeKeyEvent(aKeyEvent);
+    xConfPersistence->store();
+
+    // Now none of the configs should have the key
+    CPPUNIT_ASSERT_THROW(xGlobalAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    CPPUNIT_ASSERT_THROW(xScAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                         css::container::NoSuchElementException);
+    for (const auto& xSwAccelCfg : xSwAccelCfgs)
+    {
+        CPPUNIT_ASSERT_THROW(xSwAccelCfg->getCommandByKeyEvent(aKeyEvent),
+                             css::container::NoSuchElementException);
+    }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AcceleratorsTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to