https://invent.kde.org/frameworks/kxmlgui/-/merge_requests/190 https://bugs.kde.org/show_bug.cgi?id=475016 From f015fa6006d2e2eea2d2aac11c18219b255722ef Mon Sep 17 00:00:00 2001 From: Mladen Milinkovic Date: Fri, 29 Sep 2023 20:01:49 +0200 Subject: [PATCH] Fix merging of XMLs with multiple ActionProperties tags BUG: 475016 --- a/autotests/kxmlgui_unittest.cpp +++ b/autotests/kxmlgui_unittest.cpp @@ -88,6 +88,26 @@ static void createXmlFile(QFile &file, int version, int flags, const QByteArray file.write("\n"); } +class ShortcutSchemeHandler +{ +public: + ShortcutSchemeHandler(const QString &scheme) + : cgScheme(KSharedConfig::openConfig(), "Shortcut Schemes") + , prevScheme(cgScheme.readEntry("Current Scheme", QStringLiteral("Default"))) + { + cgScheme.writeEntry("Current Scheme", scheme); + } + + ~ShortcutSchemeHandler() + { + cgScheme.writeEntry("Current Scheme", prevScheme); + } + +private: + KConfigGroup cgScheme; + const QString prevScheme; +}; + static void clickApply(KEditToolBar *dialog) { QDialogButtonBox *box = dialog->findChild(); @@ -106,6 +126,15 @@ void KXmlGui_UnitTest::initTestCase() QFile::remove(configFile); KSharedConfig::openConfig()->reparseConfiguration(); } + + // Create "Test" shortcut scheme to eliminate the KF warning + QFile testScheme = QFile(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + QLatin1String("/%1/shortcuts/%2").arg(QCoreApplication::applicationName(), QStringLiteral("Test"))); + if (!testScheme.exists()) { + QVERIFY(QFileInfo(testScheme).dir().mkpath(QStringLiteral("."))); + QVERIFY(testScheme.open(QIODevice::WriteOnly)); + testScheme.write(QByteArray("")); + } } void KXmlGui_UnitTest::testFindVersionNumber_data() @@ -457,6 +486,56 @@ void KXmlGui_UnitTest::testPartMerging() factory.removeClient(&hostClient); } +void KXmlGui_UnitTest::testShortcutSchemeMerging() +{ + TestGuiClient client; + + ShortcutSchemeHandler sss(QStringLiteral("Test")); + + KActionCollection *ac = client.actionCollection(); + + QAction *a = ac->addAction(QStringLiteral("test_action")); + ac->setDefaultShortcut(a, QKeySequence(QStringLiteral("Ctrl+A"))); + + const QByteArray appXml = R"( + + + + &File + + + +)"; + client.createGUI(appXml, false); + + const QByteArray settingsXml = R"( + + + + &File + + + + + + + + + + +)"; + client.mergeXML(settingsXml); + + KMainWindow mainWindow; + KXMLGUIBuilder builder(&mainWindow); + KXMLGUIFactory factory(&builder); + factory.addClient(&client); + + QCOMPARE(a->shortcut(), QKeySequence(QStringLiteral("Ctrl+C"))); + + factory.removeClient(&client); +} + void KXmlGui_UnitTest::testPartMergingSettings() // #252911 { const QByteArray hostXml = --- a/autotests/kxmlgui_unittest.h +++ b/autotests/kxmlgui_unittest.h @@ -23,6 +23,7 @@ private Q_SLOTS: void testVersionHandlerNewVersionUserChanges(); void testPartMerging(); void testPartMergingSettings(); + void testShortcutSchemeMerging(); void testUiStandardsMerging_data(); void testUiStandardsMerging(); void testActionListAndSeparator(); --- a/autotests/testguiclient.h +++ b/autotests/testguiclient.h @@ -42,6 +42,10 @@ public: setXML(QString::fromLatin1(xml), true); } + void mergeXML(const QByteArray &xml) + { + setXML(QString::fromLatin1(xml), true); + } void createActions(const QStringList &actionNames) { KActionCollection *coll = actionCollection(); --- a/src/kxmlguiclient.cpp +++ b/src/kxmlguiclient.cpp @@ -587,6 +587,8 @@ bool KXMLGUIClientPrivate::isEmptyContainer(const QDomElement &base, KActionColl QDomElement KXMLGUIClientPrivate::findMatchingElement(const QDomElement &base, const QDomElement &additive) { + const QString idAttribute(base.tagName() == QLatin1String("ActionProperties") ? QStringLiteral("scheme") : QStringLiteral("name")); + QDomNode n = additive.firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); @@ -604,7 +606,7 @@ QDomElement KXMLGUIClientPrivate::findMatchingElement(const QDomElement &base, c // now see if our tags are equivalent if (equalstr(tag, base.tagName()) // - && e.attribute(QStringLiteral("name")) == base.attribute(QStringLiteral("name"))) { + && e.attribute(idAttribute) == base.attribute(idAttribute)) { return e; } } -- GitLab