[rkward] rkward: Move some common code (preview header bar) into RKXMLGuiPreviewArea, and implement _basic_ show/hide for Rmd-render previews.

Thomas Friedrichsmeier null at kde.org
Fri Sep 28 21:28:35 BST 2018


Git commit 71e97038997c70de836838ebe72f0d278e738a5b by Thomas Friedrichsmeier.
Committed on 28/09/2018 at 20:16.
Pushed by tfry into branch 'master'.

Move some common code (preview header bar) into RKXMLGuiPreviewArea, and implement _basic_ show/hide for Rmd-render previews.

M  +43   -9    rkward/misc/rkxmlguipreviewarea.cpp
M  +9    -5    rkward/misc/rkxmlguipreviewarea.h
M  +12   -37   rkward/plugin/rkstandardcomponentgui.cpp
M  +3    -3    rkward/plugin/rkstandardcomponentgui.h
M  +25   -18   rkward/windows/rkcommandeditorwindow.cpp

https://commits.kde.org/rkward/71e97038997c70de836838ebe72f0d278e738a5b

diff --git a/rkward/misc/rkxmlguipreviewarea.cpp b/rkward/misc/rkxmlguipreviewarea.cpp
index d9140bc0..1ab4abe6 100644
--- a/rkward/misc/rkxmlguipreviewarea.cpp
+++ b/rkward/misc/rkxmlguipreviewarea.cpp
@@ -23,6 +23,7 @@
 #include <QMenuBar>
 #include <QWidgetAction>
 #include <QLabel>
+#include <QVBoxLayout>
 
 #include <kxmlguifactory.h>
 #include <ktoolbar.h>
@@ -33,14 +34,11 @@
 
 #include "../debug.h"
 
-RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (QWidget* parent) : KXmlGuiWindow (parent) {
+RKXMLGUIPreviewArea::RKXMLGUIPreviewArea (const QString &label, QWidget* parent) : KXmlGuiWindow (parent) {
 	RK_TRACE (PLUGIN);
 
-	menu_button = new QToolButton (this);
-	menu_button->setPopupMode (QToolButton::InstantPopup);
-	menu_button->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionShowMenu));
-	menu_button->setMenu (menu = new QMenu ());
-	connect (menu, &QMenu::aboutToShow, this, &RKXMLGUIPreviewArea::prepareMenu);
+	_label = label;
+	wrapper_widget = 0;
 	current = 0;
 	setWindowFlags (Qt::Widget);
 	setMenuBar (new QMenuBar (this));
@@ -56,8 +54,44 @@ RKXMLGUIPreviewArea::~RKXMLGUIPreviewArea () {
 	}
 }
 
-QWidget* RKXMLGUIPreviewArea::menuButton() const {
-	return menu_button;
+QWidget* RKXMLGUIPreviewArea::wrapperWidget () {
+	if (wrapper_widget) return wrapper_widget;
+
+	wrapper_widget = new QWidget ();
+
+	QVBoxLayout *vl = new QVBoxLayout (wrapper_widget);
+	vl->setContentsMargins (0, 0, 0, 0);
+	QFrame *line = new QFrame (wrapper_widget);
+	line->setFrameShape (QFrame::HLine);
+	vl->addWidget (line);
+	QHBoxLayout *hl = new QHBoxLayout ();
+	vl->addLayout (hl);
+	QLabel *lab = new QLabel (_label, wrapper_widget);
+	QFont fnt (lab->font ());
+	fnt.setBold (true);
+	lab->setFont (fnt);
+	lab->setAlignment (Qt::AlignCenter);
+	QToolButton *tb = new QToolButton (wrapper_widget);
+	tb->setAutoRaise (true);
+	tb->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionDelete));
+	connect (tb, &QAbstractButton::clicked, [this]() { wrapper_widget->hide (); emit (previewClosed(this)); });
+
+	QToolButton *menu_button = new QToolButton (this);
+	menu_button->setPopupMode (QToolButton::InstantPopup);
+	menu_button->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionShowMenu));
+	menu_button->setMenu (menu = new QMenu ());
+	connect (menu, &QMenu::aboutToShow, this, &RKXMLGUIPreviewArea::prepareMenu);
+
+	hl->addWidget (menu_button);
+	hl->addStretch ();
+	hl->addWidget (lab);
+	hl->addWidget (tb);
+	hl->addStretch ();
+
+	vl->addWidget (this);
+	show ();
+
+	return wrapper_widget;
 }
 
 void RKXMLGUIPreviewArea::childEvent (QChildEvent *event) {
@@ -74,7 +108,7 @@ void RKXMLGUIPreviewArea::childEvent (QChildEvent *event) {
 			current = child->getPart ();
 			insertChildClient (current);
 			setCentralWidget (child);
-			createGUI ("rkdummypart.rc");
+			createGUI ("rkwrapper_widgetpart.rc");
 			menuBar ()->hide ();
 			QList<KToolBar*> tbars = toolBars ();
 			for (int i = 0; i < tbars.size (); ++i) tbars[i]->hide ();
diff --git a/rkward/misc/rkxmlguipreviewarea.h b/rkward/misc/rkxmlguipreviewarea.h
index 177a2047..77ba49f2 100644
--- a/rkward/misc/rkxmlguipreviewarea.h
+++ b/rkward/misc/rkxmlguipreviewarea.h
@@ -2,7 +2,7 @@
                           rkxmlguipreviewarea  -  description
                              -------------------
     begin                : Wed Feb 03 2016
-    copyright            : (C) 2016 by Thomas Friedrichsmeier
+    copyright            : (C) 2016-2018 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -29,18 +29,22 @@ class QToolButton;
 class RKXMLGUIPreviewArea : public KXmlGuiWindow {
 	Q_OBJECT
 public:
-	explicit RKXMLGUIPreviewArea (QWidget* parent);
+	RKXMLGUIPreviewArea (const QString &label, QWidget* parent);
 	~RKXMLGUIPreviewArea ();
-
-	QWidget *menuButton () const;
+	/** (initializes, and) returns a wrapper widget that contains this widget along with a caption (see setLabel()), menu button, and close button. */
+	QWidget *wrapperWidget ();
+	QString label () const { return _label; };
 protected:
 	/** build / destroy menu, when child is added removed. Note that we are in the fortunate situation that RKMDIWindow-children only ever get to the
 	 *  preview area via reparenting, i.e. contrary to usual QEvent::ChildAdded semnatics, they are always fully constructed, when added. */
 	void childEvent (QChildEvent *event) override;
 protected slots:
 	void prepareMenu ();
+signals:
+	void previewClosed (RKXMLGUIPreviewArea *preview);
 private:
-	QToolButton *menu_button;
+	QWidget *wrapper_widget;
+	QString _label;
 	QMenu *menu;
 	QPointer<KParts::Part> current;
 };
diff --git a/rkward/plugin/rkstandardcomponentgui.cpp b/rkward/plugin/rkstandardcomponentgui.cpp
index e3ce222f..f7307769 100644
--- a/rkward/plugin/rkstandardcomponentgui.cpp
+++ b/rkward/plugin/rkstandardcomponentgui.cpp
@@ -251,39 +251,16 @@ void RKStandardComponentGUI::finalize () {
 	bool any_vpreview_visible = RKSettingsModulePlugins::showCodeByDefault ();
 	for (int i = 0; i < previews.size (); ++i) {
 		// Add preview to splitter. Also add a title bar to each preview.
-		QWidget *dummy = new QWidget ();
-		QVBoxLayout *vl = new QVBoxLayout (dummy);
-		vl->setContentsMargins (0, 0, 0, 0);
-		QFrame *line = new QFrame (dummy);
-		line->setFrameShape (QFrame::HLine);
-		vl->addWidget (line);
-		QHBoxLayout *hl = new QHBoxLayout ();
-		vl->addLayout (hl);
-		QLabel *lab = new QLabel (i18n ("<b>%1</b>", previews[i].label), dummy);
-		lab->setAlignment (Qt::AlignCenter);
-		QToolButton *tb = new QToolButton (dummy);
-		tb->setAutoRaise (true);
-		tb->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionDelete));
-		tb->setProperty ("preview_area", QVariant::fromValue (dummy));
-		connect (tb, &QAbstractButton::clicked, this, &RKStandardComponentGUI::previewCloseButtonClicked);
-		RKXMLGUIPreviewArea *parea = qobject_cast<RKXMLGUIPreviewArea*> (previews[i].area);
-		if (parea) hl->addWidget (parea->menuButton ());
-		hl->addStretch ();
-		hl->addWidget (lab);
-		hl->addWidget (tb);
-		hl->addStretch ();
-
-		vl->addWidget (previews[i].area);
-		previews[i].area->show ();
-		previews[i].area = dummy;
+		previews[i].widget = previews[i].preview_area->wrapperWidget ();
+		connect (previews[i].preview_area, &RKXMLGUIPreviewArea::previewClosed, this, &RKStandardComponentGUI::previewCloseButtonClicked);
 		connect (previews[i].controller, &RKComponentPropertyBase::valueChanged, this, &RKStandardComponentGUI::previewVisibilityChanged);
-		if (!(previews[i].controller->boolValue ())) dummy->hide ();
+		if (!(previews[i].controller->boolValue ())) previews[i].widget->hide ();
 		else {
 			if (previews[i].position == Qt::Horizontal) any_hpreview_visible = true;
 			else any_vpreview_visible = true;
 		}
-		if (previews[i].position == Qt::Horizontal) hpreview_area->insertWidget (hpreview_area->count () - 1, previews[i].area);
-		else vpreview_area->layout ()->addWidget (previews[i].area);
+		if (previews[i].position == Qt::Horizontal) hpreview_area->insertWidget (hpreview_area->count () - 1, previews[i].widget);
+		else vpreview_area->layout ()->addWidget (previews[i].widget);
 	}
 
 	if (any_hpreview_visible) {
@@ -305,11 +282,11 @@ void RKStandardComponentGUI::finalize () {
 RKXMLGUIPreviewArea* RKStandardComponentGUI::addDockedPreview (RKComponentPropertyBool *controller, const QString& label, const QString &id, bool bottom) {
 	RK_TRACE (PLUGIN);
 
-	RKXMLGUIPreviewArea *area = new RKXMLGUIPreviewArea (0);
+	RKXMLGUIPreviewArea *area = new RKXMLGUIPreviewArea (label, 0);
 	PreviewArea parea;
-	parea.area = area;
+	parea.preview_area = area;
+	parea.widget = area;   // may be replaced by a wrapper in "finalize"
 	parea.controller = controller;
-	parea.label = label;
 	parea.position = bottom ? Qt::Vertical : Qt::Horizontal;
 	previews.insert (0, parea);
 
@@ -398,14 +375,12 @@ void RKStandardComponentGUI::toggleCode () {
 	updateCode ();
 }
 
-void RKStandardComponentGUI::previewCloseButtonClicked () {
+void RKStandardComponentGUI::previewCloseButtonClicked (RKXMLGUIPreviewArea *area) {
 	RK_TRACE (PLUGIN);
 
 	RK_ASSERT (hsplitter);  // is a dialog
-	QWidget *area = qvariant_cast<QWidget*> (sender ()->property ("preview_area"));
-
 	for (int i = 0; i < previews.size (); ++i) {
-		if (area == previews[i].area) {
+		if (area == previews[i].preview_area) {
 			previews[i].controller->setBoolValue (false);
 			if (i == previews.size () - 1) toggle_code_box->setChecked (false);
 			return;
@@ -425,7 +400,7 @@ void RKStandardComponentGUI::previewVisibilityChanged (RKComponentPropertyBase*)
 	bool new_v_visible = false;
 	// which previews are active?
 	for (int i = 0; i < previews.size (); ++i) {
-		previews[i].area->setVisible (previews[i].controller->boolValue ());
+		previews[i].widget->setVisible (previews[i].controller->boolValue ());
 		if (previews[i].controller->boolValue ()) {
 			if (previews[i].position == Qt::Horizontal) new_h_visible = true;
 			else new_v_visible = true;
@@ -568,7 +543,7 @@ void RKStandardComponentWizard::finalize () {
 			QTabWidget *previews_widget = new QTabWidget (last_page);
 			vbox->addWidget (previews_widget);
 			for (int i = 0; i < previews.size (); ++i) {
-				previews_widget->addTab (previews[i].area, previews[i].label);
+				previews_widget->addTab (previews[i].widget, previews[i].preview_area->label ());
 			}
 		}
 	}
diff --git a/rkward/plugin/rkstandardcomponentgui.h b/rkward/plugin/rkstandardcomponentgui.h
index f243c6be..fa210d7b 100644
--- a/rkward/plugin/rkstandardcomponentgui.h
+++ b/rkward/plugin/rkstandardcomponentgui.h
@@ -99,7 +99,7 @@ public slots:
 	void copyCode ();
 private slots:
 	void previewVisibilityChanged (RKComponentPropertyBase*);
-	void previewCloseButtonClicked ();
+	void previewCloseButtonClicked (RKXMLGUIPreviewArea *area);
 	void doPostShowCleanup ();
 private:
 	RKComponentPropertyCode *code_property;
@@ -129,9 +129,9 @@ friend class RKComponentBuilder;
 	bool enslaved;
 
 	struct PreviewArea {
-		QWidget *area;
+		QWidget *widget;
+		RKXMLGUIPreviewArea *preview_area;
 		RKComponentPropertyBool *controller;
-		QString label;
 		Qt::Orientation position;
 	};
 	QList<PreviewArea> previews;
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 94654428..85d3404c 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -174,7 +174,7 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 	KTextEditor::ModificationInterface* em_iface = qobject_cast<KTextEditor::ModificationInterface*> (m_doc);
 	if (em_iface) em_iface->setModifiedOnDiskWarning (true);
 	else RK_ASSERT (false);
-	preview = new RKXMLGUIPreviewArea (this);
+	preview = new RKXMLGUIPreviewArea (i18n ("Preview of rendered R Markdown"), this);
 	m_view = m_doc->createView (this);
 	RKWorkplace::mainWorkplace()->registerNamedWindow (QString ().sprintf ("%p", this).remove ('%'), this, preview);
 	if (!url.isEmpty ()) {
@@ -197,8 +197,10 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 	QHBoxLayout *layout = new QHBoxLayout (this);
 	layout->setContentsMargins (0, 0, 0, 0);
 	preview_splitter = new QSplitter (this);
-	preview_splitter->addWidget (preview);
 	preview_splitter->addWidget (m_view);
+	QWidget *preview_widget = preview->wrapperWidget ();
+	preview_splitter->addWidget (preview_widget);
+	preview_widget->hide ();
 	layout->addWidget(preview_splitter);
 
 	connect (m_doc, &KTextEditor::Document::documentUrlChanged, this, &RKCommandEditorWindow::updateCaption);
@@ -330,6 +332,7 @@ void RKCommandEditorWindow::initializeActions (KActionCollection* ac) {
 	action_render_preview = ac->addAction ("render_preview", this, SLOT (renderPreview()));
 	action_render_preview->setText ("Render Preview");
 	action_render_preview->setCheckable (true);
+	connect (preview, &RKXMLGUIPreviewArea::previewClosed, action_render_preview, &QAction::toggle);
 	
 	file_save = findAction (m_view, "file_save");
 	if (file_save) file_save->setText (i18n ("Save Script..."));
@@ -778,22 +781,26 @@ void RKCommandEditorWindow::copyLinesToOutput () {
 void RKCommandEditorWindow::renderPreview () {
 	RK_TRACE (COMMANDEDITOR);
 
-	QString id = QString ().sprintf ("%p", this).remove ('%');
-	QTemporaryFile save (QDir::tempPath () + QStringLiteral ("/rkward_XXXXXX") + id + QStringLiteral (".Rmd"));
-	RK_ASSERT (save.open ());
-	QTextStream out (&save);
-	out.setCodec ("UTF-8");     // make sure that all characters can be saved, without nagging the user
-	out << m_doc->text ();
-	save.close ();
-	save.setAutoRemove (false);
-
-	QString command ("require(knitr)\n"
-	                 "require(markdown)\n"
-	                 "rk.show.html (knitr::knit2html(%1))");
-	command = command.arg (RObject::rQuote (save.fileName ()));
-
-	RKGlobals::rInterface ()->issueCommand (".rk.with.window.hints ({\n" + command + QStringLiteral ("}, \"\", ") + RObject::rQuote (id) + ')', RCommand::App);
-	preview->show ();
+	if (action_render_preview->isChecked ()) {
+		QString id = QString ().sprintf ("%p", this).remove ('%');
+		QTemporaryFile save (QDir::tempPath () + QStringLiteral ("/rkward_XXXXXX") + id + QStringLiteral (".Rmd"));
+		RK_ASSERT (save.open ());
+		QTextStream out (&save);
+		out.setCodec ("UTF-8");     // make sure that all characters can be saved, without nagging the user
+		out << m_doc->text ();
+		save.close ();
+		save.setAutoRemove (false);
+
+		QString command ("require(knitr)\n"
+				"require(markdown)\n"
+				"rk.show.html (knitr::knit2html(%1))");
+		command = command.arg (RObject::rQuote (save.fileName ()));
+
+		RKGlobals::rInterface ()->issueCommand (".rk.with.window.hints ({\n" + command + QStringLiteral ("}, \"\", ") + RObject::rQuote (id) + ')', RCommand::App);
+		preview->wrapperWidget ()->show ();
+	} else {
+		preview->wrapperWidget ()->hide ();
+	}
 }
 
 void RKCommandEditorWindow::runAll () {



More information about the rkward-tracker mailing list