[education/rkward] rkward: Use small inline status display for previews. Greatly reduces visual noise while updating.

Thomas Friedrichsmeier null at kde.org
Sat Jun 29 13:14:25 BST 2024


Git commit 29e8f75417d3cc15d3eb2ef9202a2bae8105a142 by Thomas Friedrichsmeier.
Committed on 29/06/2024 at 12:14.
Pushed by tfry into branch 'master'.

Use small inline status display for previews. Greatly reduces visual noise while updating.

M  +1    -0    rkward/misc/rkstandardicons.cpp
M  +1    -0    rkward/misc/rkstandardicons.h
M  +104  -31   rkward/misc/rkxmlguipreviewarea.cpp
M  +12   -7    rkward/misc/rkxmlguipreviewarea.h
M  +16   -12   rkward/plugin/rkpreviewbox.cpp
M  +2    -3    rkward/plugin/rkpreviewbox.h
M  +4    -4    rkward/plugin/rkstandardcomponent.cpp
M  +2    -1    rkward/plugin/rkstandardcomponent.h
M  +5    -5    rkward/plugin/rkstandardcomponentgui.cpp
M  +1    -1    rkward/plugin/rkstandardcomponentgui.h
M  +2    -2    rkward/windows/rkcommandeditorwindow.cpp

https://invent.kde.org/education/rkward/-/commit/29e8f75417d3cc15d3eb2ef9202a2bae8105a142

diff --git a/rkward/misc/rkstandardicons.cpp b/rkward/misc/rkstandardicons.cpp
index 37d061e72..28f3748db 100644
--- a/rkward/misc/rkstandardicons.cpp
+++ b/rkward/misc/rkstandardicons.cpp
@@ -95,6 +95,7 @@ void RKStandardIcons::doInitIcons () {
 
 	icons[ActionShowMenu] = loadThemeIcon("application-menu");
 	if (icons[ActionShowMenu].isNull ()) icons[ActionShowMenu] = loadRKWardIcon("menu.svg");  // fallback
+	icons[ActionClose] = loadThemeIcon("window-close");
 
 	// objects
 	icons[ObjectList] = loadRKWardIcon("list.png");
diff --git a/rkward/misc/rkstandardicons.h b/rkward/misc/rkstandardicons.h
index a685b832c..d3beb616c 100644
--- a/rkward/misc/rkstandardicons.h
+++ b/rkward/misc/rkstandardicons.h
@@ -73,6 +73,7 @@ public:
 		ActionUnlock,
 
 		ActionShowMenu,
+		ActionClose,
 
 		ObjectList,
 		ObjectFunction,
diff --git a/rkward/misc/rkxmlguipreviewarea.cpp b/rkward/misc/rkxmlguipreviewarea.cpp
index 779ace79d..ad03db4c7 100644
--- a/rkward/misc/rkxmlguipreviewarea.cpp
+++ b/rkward/misc/rkxmlguipreviewarea.cpp
@@ -15,11 +15,15 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include <QLabel>
 #include <QVBoxLayout>
 #include <QDomElement>
+#include <QPainter>
+#include <QPen>
 
 #include <KXMLGUIFactory>
 #include <KXMLGUIBuilder>
 #include <KToolBar>
 #include <KLocalizedString>
+#include <KColorScheme>
+#include <KMessageWidget>
 
 #include "../windows/rkmdiwindow.h"
 #include "../windows/rkworkplace.h"
@@ -56,7 +60,7 @@ private:
 	QMenuBar *menubar;
 };
 
-RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent) : QWidget (parent) {
+RKXMLGUIPreviewArea::RKXMLGUIPreviewArea(const QString &label, QWidget* parent, RKPreviewManager *manager) : QWidget (parent) {
 	RK_TRACE (PLUGIN);
 
 	current = nullptr;
@@ -78,7 +82,7 @@ RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent)
 	lab->setAlignment(Qt::AlignCenter);
 	QToolButton *tb = new QToolButton();
 	tb->setAutoRaise(true);
-	tb->setIcon(RKStandardIcons::getIcon(RKStandardIcons::ActionDelete));
+	tb->setIcon(RKStandardIcons::getIcon(RKStandardIcons::ActionClose));
 	connect(tb, &QAbstractButton::clicked, this, [this]() { hide(); Q_EMIT previewClosed(this); });
 
 	QToolButton *menu_button = new QToolButton(this);
@@ -90,8 +94,9 @@ RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent)
 	hl->addWidget(menu_button);
 	hl->addStretch();
 	hl->addWidget(lab);
-	hl->addWidget(tb);
+	if (manager) hl->addWidget(manager->inlineStatusWidget());
 	hl->addStretch();
+	hl->addWidget(tb);
 	internal_layout = new QVBoxLayout();
 	vl->addLayout(internal_layout);
 
@@ -177,9 +182,90 @@ void RKXMLGUIPreviewArea::prepareMenu () {
 }
 
 
+
+/** Similar to KMessageWidget, but much smaller margins / spacings */
+class RKPreviewStatusNote : public QFrame {
+friend class RKPreviewManager;
+	RKPreviewStatusNote(RKPreviewManager *manager) :
+	QFrame(),
+	updating(i18nc("very short: Preview is updating", "updating")),
+	error(i18nc("very short: Error while generating preview", "error")),
+	ready(i18nc("very short: Preview is up to date", "ready")),
+	unavailable(i18nc("very short: Preview is not(yet) possible", "n/a")),
+	off(i18nc("very short: Preview is turned off", "off"))
+	{
+		QFontMetrics fm(font());
+		em = fm.horizontalAdvance('w');
+		auto l = new QVBoxLayout(this);
+		l->setContentsMargins(em,0,em,0);
+		lab = new QLabel();
+		l->addWidget(lab, 0, Qt::AlignHCenter);
+		setAutoFillBackground(false);
+		setFixedHeight(fm.height()+4);
+		int maxw = fm.horizontalAdvance(updating);
+		maxw = qMax(maxw, fm.horizontalAdvance(error));
+		maxw = qMax(maxw, fm.horizontalAdvance(ready));
+		maxw = qMax(maxw, fm.horizontalAdvance(unavailable));
+		maxw = qMax(maxw, fm.horizontalAdvance(off));
+		setFixedWidth(maxw+2*em+2);
+
+		connect(manager, &RKPreviewManager::statusChanged, this, [this](RKPreviewManager *m) {
+			if (m->update_pending == RKPreviewManager::NoUpdatePossible) {
+				lab->setText(unavailable);
+				setToolTip(i18n("The preview is current unavailable (you will need to make further selections)."));
+				setColors(QPalette::Disabled, KColorScheme::NegativeBackground, KColorScheme::NegativeText);
+			} else if (m->update_pending == RKPreviewManager::PreviewDisabled) {
+				lab->setText(off);
+				setToolTip(i18n("Preview is turned off."));
+				setColors(QPalette::Disabled, KColorScheme::NormalBackground, KColorScheme::NormalText);
+			} else if (m->updating || (m->update_pending == RKPreviewManager::UpdatePending)) {
+				lab->setText(updating);
+				setToolTip(i18n("Preview is currently being updated."));
+				setColors(QPalette::Active, KColorScheme::ActiveBackground, KColorScheme::ActiveText);
+			} else if (m->current_preview_failed) {
+				lab->setText(error);
+				setToolTip(i18n("The command to generate the preview has failed."));
+				setColors(QPalette::Active, KColorScheme::NegativeBackground, KColorScheme::NegativeText);
+			} else {
+				lab->setText(ready);
+				setToolTip(i18n("Preview is up to date."));
+				setColors(QPalette::Active, KColorScheme::PositiveBackground, KColorScheme::PositiveText);
+			}
+			update();
+		});
+	}
+	void paintEvent(QPaintEvent *event) {
+		QPainter painter(this);
+		painter.setRenderHint(QPainter::Antialiasing);
+		painter.setPen(pen);
+		painter.setBrush(brush);
+		const QRect innerRect = rect().marginsRemoved(QMargins() + 1);
+		painter.drawRoundedRect(innerRect, em, em);
+		QFrame::paintEvent(event);
+	}
+	const QString updating;
+	const QString error;
+	const QString ready;
+	const QString unavailable;
+	const QString off;
+	void setColors(QPalette::ColorGroup group, KColorScheme::BackgroundRole bg, KColorScheme::ForegroundRole fg) {
+		auto scheme = KColorScheme(group);
+		pen = QPen(scheme.foreground(fg).color());
+		brush = QBrush(scheme.background(bg));
+	}
+	QLabel *lab;
+	int em;
+	QBrush brush;
+	QPen pen;
+};
+
+QWidget* RKPreviewManager::inlineStatusWidget() {
+	return new RKPreviewStatusNote(this);
+}
+
 #include "../windows/rkworkplace.h"
 
-RKPreviewManager::RKPreviewManager(QObject* parent) : QObject (parent) {
+RKPreviewManager::RKPreviewManager(QObject* parent) : QObject (parent), current_preview_failed(false) {
 	RK_TRACE (PLUGIN);
 
 	update_pending = NoUpdatePending;
@@ -196,11 +282,12 @@ void RKPreviewManager::previewCommandDone (RCommand* command) {
 
 	updating = false;
 	if (update_pending == NoUpdatePossible) {
-		setNoPreviewAvailable ();
+		setNoPreviewAvailable();
 	} else {
-		QString warnings = command->warnings () + command->error ();
-		if (!warnings.isEmpty ()) warnings = QString("<b>%1</b>\n<pre>%2</pre>").arg(i18n("Warnings or Errors:"), warnings.toHtmlEscaped());
-		setStatusMessage (warnings);
+		QString warnings = command->warnings() + command->error();
+		if (!warnings.isEmpty()) warnings = QString("<b>%1</b>\n<pre>%2</pre>").arg(i18n("Warnings or Errors:"), warnings.toHtmlEscaped());
+		updateStatusDisplay(warnings);
+		current_preview_failed = command->failed();
 	}
 }
 
@@ -213,10 +300,10 @@ void RKPreviewManager::setCommand (RCommand* command) {
 	connect (command->notifier(), &RCommandNotifier::commandFinished, this, &RKPreviewManager::previewCommandDone);
 
 	// Send an empty dummy command first. This is to sync up with any commands that should have been run _before_ the preview (e.g. to set up the preview area, so that status labels can be shown)
-	RInterface::whenAllFinished(this, [this]() { setStatusMessage(shortStatusLabel()); });
+	RInterface::whenAllFinished(this, [this]() { updateStatusDisplay(); });
 
 	RInterface::issueCommand (command);
-	setStatusMessage (shortStatusLabel ());
+	updateStatusDisplay();
 }
 
 void RKPreviewManager::setUpdatePending () {
@@ -224,7 +311,7 @@ void RKPreviewManager::setUpdatePending () {
 	RK_TRACE (PLUGIN);
 
 	update_pending = UpdatePending;
-	setStatusMessage (shortStatusLabel ());
+	updateStatusDisplay();
 }
 
 void RKPreviewManager::setNoPreviewAvailable () {
@@ -232,7 +319,7 @@ void RKPreviewManager::setNoPreviewAvailable () {
 	RK_TRACE (PLUGIN);
 
 	update_pending = NoUpdatePossible;
-	setStatusMessage (shortStatusLabel ());
+	updateStatusDisplay();
 }
 
 void RKPreviewManager::setPreviewDisabled () {
@@ -240,28 +327,14 @@ void RKPreviewManager::setPreviewDisabled () {
 	RK_TRACE (PLUGIN);
 
 	update_pending = PreviewDisabled;
-	setStatusMessage (shortStatusLabel ());
+	updateStatusDisplay();
 }
 
-void RKPreviewManager::setStatusMessage (const QString& message) {
+void RKPreviewManager::updateStatusDisplay(const QString &warnings) {
 	RK_TRACE (PLUGIN);
 
-	RKMDIWindow *window = RKWorkplace::mainWorkplace ()->getNamedWindow (id);
-	if (window) window->setStatusMessage (message);
-
-	Q_EMIT statusChanged();
-}
-
-QString RKPreviewManager::shortStatusLabel() const {
-//	RK_TRACE (PLUGIN);
+	RKMDIWindow *window = RKWorkplace::mainWorkplace()->getNamedWindow(id);
+	if (window) window->setStatusMessage(warnings);
 
-	if (update_pending == NoUpdatePossible) {
-		return (i18n ("Preview not (yet) possible"));
-	} else if (update_pending == PreviewDisabled) {
-		return (i18n ("Preview disabled"));
-	} else if (updating || (update_pending == UpdatePending)) {
-		return (i18n ("Preview updating"));
-	} else {
-		return (i18n ("Preview up to date"));
-	}
+	Q_EMIT statusChanged(this);
 }
diff --git a/rkward/misc/rkxmlguipreviewarea.h b/rkward/misc/rkxmlguipreviewarea.h
index e0850965c..c93acaa60 100644
--- a/rkward/misc/rkxmlguipreviewarea.h
+++ b/rkward/misc/rkxmlguipreviewarea.h
@@ -21,12 +21,14 @@ class QLabel;
 class RKMDIWindow;
 class KXMLGUIBuilder;
 class KXMLGUIFactory;
+class RKPreviewStatusNote;
+class RKPreviewManager;
 
 class RKXMLGUIPreviewArea : public QWidget {
 	Q_OBJECT
 public:
-	RKXMLGUIPreviewArea (const QString &label, QWidget* parent);
-	~RKXMLGUIPreviewArea ();
+	RKXMLGUIPreviewArea(const QString &label, QWidget* parent, RKPreviewManager* manager);
+	~RKXMLGUIPreviewArea();
 	QString label() const;
 	void setLabel(const QString &label);
 	void setWindow(RKMDIWindow* window);
@@ -36,6 +38,7 @@ Q_SIGNALS:
 	void previewClosed (RKXMLGUIPreviewArea *preview);
 private:
 	QLabel *lab;
+	RKPreviewStatusNote *statusnote;
 	QMenu *menu;
 	QMenuBar *menubar;
 	QPointer<KParts::Part> current;
@@ -59,15 +62,16 @@ public:
 	/** Start the next preview update, as given by command. You must call needsCommand() first, to check whether the next command is
 	 *  ready to go. */
 	void setCommand (RCommand *command);
-	bool needsCommand () const { return !updating && (update_pending == UpdatePending); };
-	QString previewId () const { return id; };
-	QString shortStatusLabel () const;
+	bool needsCommand() const { return !updating && (update_pending == UpdatePending); };
+	QString previewId() const { return id; };
+	QWidget* inlineStatusWidget();
 Q_SIGNALS:
-	void statusChanged ();
+	void statusChanged(RKPreviewManager *);
 private Q_SLOTS:
 	void previewCommandDone (RCommand *command);
 private:
-	void setStatusMessage (const QString &);
+friend class RKPreviewStatusNote;
+	void updateStatusDisplay(const QString &warnings=QString());
 	enum {
 		NoUpdatePending,
 		NoUpdatePossible,
@@ -75,6 +79,7 @@ private:
 		UpdatePending
 	} update_pending;
 	bool updating;
+	bool current_preview_failed;
 	QString id;
 };
 
diff --git a/rkward/plugin/rkpreviewbox.cpp b/rkward/plugin/rkpreviewbox.cpp
index 9b2dbda95..285b9338f 100644
--- a/rkward/plugin/rkpreviewbox.cpp
+++ b/rkward/plugin/rkpreviewbox.cpp
@@ -8,7 +8,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <qlayout.h>
 #include <qlabel.h>
-#include <qcheckbox.h>
+#include <QGroupBox>
 #include <qtimer.h>
 #include <QTextDocument>
 
@@ -47,14 +47,16 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 	// create checkbox
 	QVBoxLayout *vbox = new QVBoxLayout (this);
 	vbox->setContentsMargins (0, 0, 0, 0);
-	toggle_preview_box = new QCheckBox (xml->i18nStringAttribute (element, "label", i18n ("Preview"), DL_INFO), this);
-	vbox->addWidget (toggle_preview_box);
-	toggle_preview_box->setChecked (preview_active);
-	connect (toggle_preview_box, &QCheckBox::stateChanged, this, &RKPreviewBox::changedStateFromUi);
+	toggle_preview_box = new QGroupBox(xml->i18nStringAttribute(element, "label", i18n ("Preview"), DL_INFO), this);
+	toggle_preview_box->setCheckable(true);
+	toggle_preview_box->setAlignment(Qt::AlignLeft);
+	vbox->addWidget(toggle_preview_box);
+	toggle_preview_box->setChecked(preview_active);
+	connect(toggle_preview_box, &QGroupBox::toggled, this, &RKPreviewBox::changedStateFromUi);
 
 	// status label
-	status_label = RKCommonFunctions::wordWrappedLabel (QString ());
-	vbox->addWidget (status_label);
+	auto box_layout = new QVBoxLayout(toggle_preview_box);
+	box_layout->addWidget(manager->inlineStatusWidget());
 
 	// prepare placement
 	placement_command = ".rk.with.window.hints ({";
@@ -66,7 +68,7 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 	if (placement == DockedPreview) {
 		RKStandardComponent *uicomp = topmostStandardComponent ();
 		if (uicomp) {
-			uicomp->addDockedPreview (state, toggle_preview_box->text (), manager->previewId ());
+			uicomp->addDockedPreview(state, toggle_preview_box->title(), manager);
 
 			if (preview_mode == OutputPreview) {
 				RInterface::issueCommand ("local ({\n"
@@ -158,10 +160,12 @@ void RKPreviewBox::changedStateFromUi () {
 void RKPreviewBox::tryPreview () {
 	RK_TRACE (PLUGIN);
 
-	if (isEnabled () && toggle_preview_box->isChecked ()) update_timer->start (10);
-	else killPreview ();
-
-	status_label->setText (manager->shortStatusLabel ());
+	if (isEnabled() && toggle_preview_box->isChecked()) {
+		update_timer->start(10);
+	} else {
+		killPreview();
+		manager->setPreviewDisabled();
+	}
 }
 
 void RKPreviewBox::tryPreviewNow () {
diff --git a/rkward/plugin/rkpreviewbox.h b/rkward/plugin/rkpreviewbox.h
index d4c2ca3f5..2f0b0a43f 100644
--- a/rkward/plugin/rkpreviewbox.h
+++ b/rkward/plugin/rkpreviewbox.h
@@ -12,7 +12,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "rkcomponentproperties.h"
 
-class QCheckBox;
+class QGroupBox;
 class QDomElement;
 class QLabel;
 class QTimer;
@@ -55,8 +55,7 @@ private:
 		DockedPreview
 	} placement;
 	QTimer *update_timer;
-	QCheckBox *toggle_preview_box;
-	QLabel *status_label;
+	QGroupBox *toggle_preview_box;
 	RKComponentPropertyCode *code_property;
 	QString idprop;
 	QString placement_command;
diff --git a/rkward/plugin/rkstandardcomponent.cpp b/rkward/plugin/rkstandardcomponent.cpp
index 51a98c037..35ce7c697 100644
--- a/rkward/plugin/rkstandardcomponent.cpp
+++ b/rkward/plugin/rkstandardcomponent.cpp
@@ -354,12 +354,12 @@ void RKStandardComponent::buildAndInitialize (const QDomElement &doc_element, co
 	Q_EMIT standardInitializationComplete();
 }
 
-RKXMLGUIPreviewArea* RKStandardComponent::addDockedPreview (RKComponentPropertyBool* controller, const QString& label, const QString &id) {
-	RK_TRACE (PLUGIN);
+RKXMLGUIPreviewArea* RKStandardComponent::addDockedPreview(RKComponentPropertyBool* controller, const QString& label, RKPreviewManager *manager) {
+	RK_TRACE(PLUGIN);
 
-	RK_ASSERT (gui);
+	RK_ASSERT(gui);
 	if (!gui) return nullptr;
-	return gui->addDockedPreview (controller, label, id);
+	return gui->addDockedPreview(controller, label, manager);
 }
 
 RKComponentBase::ComponentStatus RKStandardComponent::recursiveStatus () {
diff --git a/rkward/plugin/rkstandardcomponent.h b/rkward/plugin/rkstandardcomponent.h
index b0ba522b0..358216794 100644
--- a/rkward/plugin/rkstandardcomponent.h
+++ b/rkward/plugin/rkstandardcomponent.h
@@ -21,6 +21,7 @@ class RKStandardComponentStack;
 class ScriptBackend;
 class QTimer;
 class RKXMLGUIPreviewArea;
+class RKPreviewManager;
 
 /** The standard type of component (i.e. stand-alone), previously known as "plugin". This is the type of component described by an XML-file
 
@@ -74,7 +75,7 @@ public:
 /** Return the GUI-scripting handler (creating it, if needed) */
 	RKComponentScriptingProxy* scriptingProxy ();
 
-	RKXMLGUIPreviewArea *addDockedPreview (RKComponentPropertyBool *controller, const QString& label, const QString &id = QString ());
+	RKXMLGUIPreviewArea *addDockedPreview(RKComponentPropertyBool *controller, const QString& label, RKPreviewManager *manager);
 Q_SIGNALS:
 	void standardInitializationComplete ();
 public Q_SLOTS:
diff --git a/rkward/plugin/rkstandardcomponentgui.cpp b/rkward/plugin/rkstandardcomponentgui.cpp
index 79c85f221..9218d7968 100644
--- a/rkward/plugin/rkstandardcomponentgui.cpp
+++ b/rkward/plugin/rkstandardcomponentgui.cpp
@@ -143,7 +143,7 @@ RKStandardComponentGUI::RKStandardComponentGUI (RKStandardComponent *component,
 
 	if (!enslaved) {
 		// code display
-		RKXMLGUIPreviewArea *area = addDockedPreview (&code_display_visibility, i18n ("Code Preview"), QString (), true);
+		RKXMLGUIPreviewArea *area = addDockedPreview(&code_display_visibility, i18n("Code Preview"), nullptr, true);
 		code_display = new RKCommandEditorWindow(nullptr, QUrl(), QString(), RKCommandEditorFlags::DefaultToRHighlighting);
 		code_display->setReadOnly (true);
 		code_display_visibility.setBoolValue (!enslaved && RKSettingsModulePlugins::showCodeByDefault ());
@@ -269,10 +269,10 @@ void RKStandardComponentGUI::finalize () {
 	main_widget->updateGeometry ();
 }
 
-RKXMLGUIPreviewArea* RKStandardComponentGUI::addDockedPreview (RKComponentPropertyBool *controller, const QString& label, const QString &id, bool bottom) {
+RKXMLGUIPreviewArea* RKStandardComponentGUI::addDockedPreview(RKComponentPropertyBool *controller, const QString& label, RKPreviewManager *manager, bool bottom) {
 	RK_TRACE (PLUGIN);
 
-	RKXMLGUIPreviewArea *area = new RKXMLGUIPreviewArea(label, nullptr);
+	RKXMLGUIPreviewArea *area = new RKXMLGUIPreviewArea(label, nullptr, manager);
 	PreviewArea parea;
 	parea.preview_area = area;
 	parea.widget = area;   // may be replaced by a wrapper in "finalize"
@@ -280,8 +280,8 @@ RKXMLGUIPreviewArea* RKStandardComponentGUI::addDockedPreview (RKComponentProper
 	parea.position = bottom ? Qt::Vertical : Qt::Horizontal;
 	previews.insert (0, parea);
 
-	if (!id.isEmpty ()) {
-		RKWorkplace::mainWorkplace ()->registerNamedWindow (id, this, area);
+	if (manager) {
+		RKWorkplace::mainWorkplace()->registerNamedWindow(manager->previewId(), this, area);
 	}
 	return area;
 };
diff --git a/rkward/plugin/rkstandardcomponentgui.h b/rkward/plugin/rkstandardcomponentgui.h
index 8016cb33a..7fe4306aa 100644
--- a/rkward/plugin/rkstandardcomponentgui.h
+++ b/rkward/plugin/rkstandardcomponentgui.h
@@ -75,7 +75,7 @@ public:
 	virtual void updateCode ();
 /** reimplemented from QWidget to take care of showing the code display if needed */
 	void showEvent (QShowEvent *e) override;
-	RKXMLGUIPreviewArea* addDockedPreview (RKComponentPropertyBool *controller, const QString& label, const QString &id=QString (), bool bottom = false);
+	RKXMLGUIPreviewArea* addDockedPreview(RKComponentPropertyBool *controller, const QString& label, RKPreviewManager *manager, bool bottom = false);
 /** Do anything needed after the dialog is created and its contents have been built. Base class adds the preview regions to the splitter */
 	virtual void finalize ();
 public Q_SLOTS:
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index af45cb829..9364890cf 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -185,8 +185,8 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl &_url,
 	if (visible_to_kateplugins) {
 		Q_EMIT RKWardMainWindow::getMain ()->katePluginIntegration ()->mainWindow ()->mainWindow()->viewCreated (m_view);
 	}
-	preview = new RKXMLGUIPreviewArea (QString(), this);
-	preview_manager = new RKPreviewManager (this);
+	preview_manager = new RKPreviewManager(this);
+	preview = new RKXMLGUIPreviewArea(QString(), this, preview_manager);
 	connect (preview_manager, &RKPreviewManager::statusChanged, this, [this]() { preview_timer.start (500); });
 	RKWorkplace::mainWorkplace()->registerNamedWindow (preview_manager->previewId(), this, preview);
 	if (!url.isEmpty ()) {


More information about the rkward-tracker mailing list