[education/rkward] rkward/misc: Fix menu quirks due to use of a fully blown KXMLGUIWindow as preview area.

Thomas Friedrichsmeier null at kde.org
Fri Jul 1 23:37:21 BST 2022


Git commit 75d2ff4f468f6807669237cfe344fa8dbd469b9a by Thomas Friedrichsmeier.
Committed on 01/07/2022 at 22:35.
Pushed by tfry into branch 'master'.

Fix menu quirks due to use of a fully blown KXMLGUIWindow as preview area.

CCBUG: 416911
CCBUG: 429900

M  +39   -21   rkward/misc/rkxmlguipreviewarea.cpp
M  +8    -2    rkward/misc/rkxmlguipreviewarea.h

https://invent.kde.org/education/rkward/commit/75d2ff4f468f6807669237cfe344fa8dbd469b9a

diff --git a/rkward/misc/rkxmlguipreviewarea.cpp b/rkward/misc/rkxmlguipreviewarea.cpp
index 55926cb6..70f682b1 100644
--- a/rkward/misc/rkxmlguipreviewarea.cpp
+++ b/rkward/misc/rkxmlguipreviewarea.cpp
@@ -14,6 +14,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include <QWidgetAction>
 #include <QLabel>
 #include <QVBoxLayout>
+#include <QDomElement>
 
 #include <kxmlguifactory.h>
 #include <ktoolbar.h>
@@ -27,25 +28,48 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "../debug.h"
 
-RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent) : KXmlGuiWindow (parent) {
+class RKXMLGUIPreviewBuilder : public KXMLGUIBuilder {
+public:
+	RKXMLGUIPreviewBuilder(QWidget* parent, QMenuBar* menubar) : KXMLGUIBuilder(parent), menubar(menubar) {};
+	QStringList containerTags() const override {
+		QStringList ret;
+		ret << QStringLiteral("menubar") << QStringLiteral("menu");
+		return ret;
+	}
+	QWidget* createContainer(QWidget *parent, int index, const QDomElement &element, QAction *&containerAction) override {
+		QString tagname = element.tagName().toLower();
+		if (tagname == QStringLiteral("menubar")) {
+			return menubar;
+		}
+		// only menus will actually be built, as we effectively disabled toolbars via containerTags(), above
+		return KXMLGUIBuilder::createContainer(parent, index, element, containerAction);
+	}
+	void removeContainer(QWidget *container, QWidget *parent, QDomElement &element, QAction *containerAction) override {
+		if (container == menubar) return; // do not delete this
+		KXMLGUIBuilder::removeContainer(container, parent, element, containerAction);
+	}
+private:
+	QMenuBar *menubar;
+};
+
+RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent) : QWidget (parent) {
 	RK_TRACE (PLUGIN);
 
 	_label = label;
-	wrapper_widget = 0;
-	current = 0;
-	setWindowFlags (Qt::Widget);
-	setMenuBar (new QMenuBar (this));
-	setHelpMenuEnabled (false);
+	wrapper_widget = nullptr;
+	current = nullptr;
+	internal_layout = new QVBoxLayout(this);
+	factory = new KXMLGUIFactory(new RKXMLGUIPreviewBuilder(this, new QMenuBar(this)), this);
 }
 
 RKXMLGUIPreviewArea::~RKXMLGUIPreviewArea () {
 	RK_TRACE (PLUGIN);
 
 	if (current) {
-		removeChildClient (current);
+		factory->removeClient(current);
 		current->setFactory (0);
 	}
-	if (wrapper_widget) wrapper_widget->deleteLater();  // technically, the wrapper widget is the parent of this, not the other way around
+	if (wrapper_widget) wrapper_widget->deleteLater();
 }
 
 void RKXMLGUIPreviewArea::setLabel (const QString& label) {
@@ -92,7 +116,7 @@ QWidget* RKXMLGUIPreviewArea::wrapperWidget () {
 	hl->addWidget (tb);
 	hl->addStretch ();
 
-	vl->addWidget (this);
+	vl->addWidget(this);
 	show ();
 
 	return wrapper_widget;
@@ -100,19 +124,13 @@ QWidget* RKXMLGUIPreviewArea::wrapperWidget () {
 
 void RKXMLGUIPreviewArea::setWindow(RKMDIWindow* window) {
 	if (current) {
-		removeChildClient(current);
-		factory()->removeClient(current);  // _always_ remove before adding, or the previous child will be leaked in the factory
+		factory->removeClient(current);  // _always_ remove before adding, or the previous child will be leaked in the factory
 	}
 	window->setWindowStyleHint("preview");
 	current = window->getPart();
-	insertChildClient(current);
-	setCentralWidget(window);
-	createGUI();
-	menuBar()->hide();
-	QList<KToolBar*> tbars = toolBars();
-	for (int i = 0; i < tbars.size(); ++i) tbars[i]->hide();
-	// avoid shortcut conflicts
-	QList<QAction*> acts = actions();
+	factory->addClient(current);
+	internal_layout->addWidget(window);
+	QList<QAction*> acts = wrapper_widget->actions();
 	for (int i = 0; i < acts.size (); ++i) acts[i]->setShortcutContext(Qt::WidgetWithChildrenShortcut);
 	RKWorkplace::mainWorkplace()->setWindowNotManaged(window);
 }
@@ -120,9 +138,10 @@ void RKXMLGUIPreviewArea::setWindow(RKMDIWindow* window) {
 void RKXMLGUIPreviewArea::prepareMenu () {
 	RK_TRACE (PLUGIN);
 
+	QMenuBar *menubar = findChild<QMenuBar*>(QString(), Qt::FindDirectChildrenOnly);
 	// flatten menu, and try to purge irrelevant actions
 	menu->clear ();
-	QList<QAction*> entries = menuBar ()->actions ();
+	QList<QAction*> entries = menubar->actions ();
 	for (int i = 0; i < entries.size (); ++i) {
 		QMenu *smenu = entries[i]->menu ();
 		if (!smenu) continue;    // Don't think it can happen...
@@ -245,4 +264,3 @@ QString RKPreviewManager::shortStatusLabel() const {
 		return (i18n ("Preview up to date"));
 	}
 }
-
diff --git a/rkward/misc/rkxmlguipreviewarea.h b/rkward/misc/rkxmlguipreviewarea.h
index 62877bfd..e9031d31 100644
--- a/rkward/misc/rkxmlguipreviewarea.h
+++ b/rkward/misc/rkxmlguipreviewarea.h
@@ -8,17 +8,20 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #ifndef RKXMLGUIPREVIEWAREA_H
 #define RKXMLGUIPREVIEWAREA_H
 
-#include <kxmlguiwindow.h>
+#include <kxmlguibuilder.h>
 #include <kparts/part.h>
 
+#include <QWidget>
+#include <QMenuBar>
 #include <QPointer>
+#include <QVBoxLayout>
 
 class QMenu;
 class QToolButton;
 class QLabel;
 class RKMDIWindow;
 
-class RKXMLGUIPreviewArea : public KXmlGuiWindow {
+class RKXMLGUIPreviewArea : public QWidget {
 	Q_OBJECT
 public:
 	RKXMLGUIPreviewArea (const QString &label, QWidget* parent);
@@ -37,7 +40,10 @@ private:
 	QString _label;
 	QLabel *lab;
 	QMenu *menu;
+	QMenuBar *menubar;
 	QPointer<KParts::Part> current;
+	KXMLGUIFactory *factory;
+	QVBoxLayout *internal_layout;
 };
 
 class RCommand;


More information about the rkward-tracker mailing list