[rkward] rkward/windows: Auto-update Rmd render preview as long as the 'Render Preview' action is active.

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


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

Auto-update Rmd render preview as long as the 'Render Preview' action is active.

M  +30   -18   rkward/windows/rkcommandeditorwindow.cpp
M  +8    -8    rkward/windows/rkcommandeditorwindow.h

https://commits.kde.org/rkward/1e53d0aa5c2f3f3d7066b14fa6817ab511e7de88

diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 85d3404c..95fcfc62 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -175,8 +175,10 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 	if (em_iface) em_iface->setModifiedOnDiskWarning (true);
 	else RK_ASSERT (false);
 	preview = new RKXMLGUIPreviewArea (i18n ("Preview of rendered R Markdown"), this);
+	preview_manager = new RKPreviewManager (this);
+	connect (preview_manager, &RKPreviewManager::statusChanged, [this]() { preview_timer.start (500); });
 	m_view = m_doc->createView (this);
-	RKWorkplace::mainWorkplace()->registerNamedWindow (QString ().sprintf ("%p", this).remove ('%'), this, preview);
+	RKWorkplace::mainWorkplace()->registerNamedWindow (preview_manager->previewId(), this, preview);
 	if (!url.isEmpty ()) {
 		KConfigGroup viewconf (RKWorkplace::mainWorkplace ()->workspaceConfig (), QString ("SkriptViewSettings %1").arg (RKWorkplace::mainWorkplace ()->portableUrl (url)));
 		m_view->readSessionConfig (viewconf);
@@ -196,7 +198,7 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 
 	QHBoxLayout *layout = new QHBoxLayout (this);
 	layout->setContentsMargins (0, 0, 0, 0);
-	preview_splitter = new QSplitter (this);
+	QSplitter* preview_splitter = new QSplitter (this);
 	preview_splitter->addWidget (m_view);
 	QWidget *preview_widget = preview->wrapperWidget ();
 	preview_splitter->addWidget (preview_widget);
@@ -209,7 +211,7 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 #warning remove this in favor of KTextEditor::Document::restore()
 #endif
 	connect (m_doc, &KTextEditor::Document::modifiedChanged, this, &RKCommandEditorWindow::autoSaveHandlerModifiedChanged);
-	connect (m_doc, &KTextEditor::Document::textChanged, this, &RKCommandEditorWindow::autoSaveHandlerTextChanged);
+	connect (m_doc, &KTextEditor::Document::textChanged, this, &RKCommandEditorWindow::textChanged);
 	connect (m_view, &KTextEditor::View::selectionChanged, this, &RKCommandEditorWindow::selectionChanged);
 	// somehow the katepart loses the context menu each time it loses focus
 	connect (m_view, &KTextEditor::View::focusIn, this, &RKCommandEditorWindow::focusIn);
@@ -241,8 +243,8 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 	initBlocks ();
 	RK_ASSERT (smart_iface);
 
-	autosave_timer = new QTimer (this);
-	connect (autosave_timer, &QTimer::timeout, this, &RKCommandEditorWindow::doAutoSave);
+	connect (&autosave_timer, &QTimer::timeout, this, &RKCommandEditorWindow::doAutoSave);
+	connect (&preview_timer, &QTimer::timeout, this, &RKCommandEditorWindow::doRenderPreview);
 
 	updateCaption ();	// initialize
 	QTimer::singleShot (0, this, SLOT (setPopupMenu()));
@@ -329,7 +331,7 @@ void RKCommandEditorWindow::initializeActions (KActionCollection* ac) {
 	action_setwd_to_script->setToolTip (action_setwd_to_script->statusTip ());
 	action_setwd_to_script->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionCDToScript));
 
-	action_render_preview = ac->addAction ("render_preview", this, SLOT (renderPreview()));
+	action_render_preview = ac->addAction ("render_preview", this, SLOT (textChanged()));
 	action_render_preview->setText ("Render Preview");
 	action_render_preview->setCheckable (true);
 	connect (preview, &RKXMLGUIPreviewArea::previewClosed, action_render_preview, &QAction::toggle);
@@ -469,7 +471,7 @@ void RKCommandEditorWindow::autoSaveHandlerModifiedChanged () {
 	RK_TRACE (COMMANDEDITOR);
 
 	if (!isModified ()) {
-		autosave_timer->stop ();
+		autosave_timer.stop ();
 
 		if (RKSettingsModuleCommandEditor::autosaveKeep ()) return;
 		if (!previous_autosave_url.isValid ()) return;
@@ -485,13 +487,23 @@ void RKCommandEditorWindow::autoSaveHandlerModifiedChanged () {
 	}
 }
 
-void RKCommandEditorWindow::autoSaveHandlerTextChanged () {
+void RKCommandEditorWindow::textChanged () {
 	RK_TRACE (COMMANDEDITOR);
 
+	// render preview
+	if (action_render_preview->isChecked ()) {
+		preview_manager->setUpdatePending ();
+		preview_timer.start (500);              // brief delay to buffer keystrokes
+	} else {
+		preview->wrapperWidget ()->hide ();
+		preview_manager->setPreviewDisabled ();
+	}
+
+	// auto save
 	if (!isModified ()) return;		// may happen after load or undo
 	if (!RKSettingsModuleCommandEditor::autosaveEnabled ()) return;
-	if (!autosave_timer->isActive ()) {
-		autosave_timer->start (RKSettingsModuleCommandEditor::autosaveInterval () * 60 * 1000);
+	if (!autosave_timer.isActive ()) {
+		autosave_timer.start (RKSettingsModuleCommandEditor::autosaveInterval () * 60 * 1000);
 	}
 }
 
@@ -553,7 +565,7 @@ void RKCommandEditorWindow::doAutoSave () {
 	alljobs->start ();
 
 	// do not create any more autosaves until the text is changed, again
-	autosave_timer->stop ();
+	autosave_timer.stop ();
 }
 
 void RKCommandEditorWindow::autoSaveHandlerJobFinished (RKJobSequence* seq) {
@@ -778,12 +790,13 @@ void RKCommandEditorWindow::copyLinesToOutput () {
 	RKCommandHighlighter::copyLinesToOutput (m_view, RKCommandHighlighter::RScript);
 }
 
-void RKCommandEditorWindow::renderPreview () {
+void RKCommandEditorWindow::doRenderPreview () {
 	RK_TRACE (COMMANDEDITOR);
 
 	if (action_render_preview->isChecked ()) {
-		QString id = QString ().sprintf ("%p", this).remove ('%');
-		QTemporaryFile save (QDir::tempPath () + QStringLiteral ("/rkward_XXXXXX") + id + QStringLiteral (".Rmd"));
+		if (!preview_manager->needsCommand ()) return;
+
+		QTemporaryFile save (QDir::tempPath () + QStringLiteral ("/rkward_XXXXXX") + preview_manager->previewId () + 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
@@ -793,13 +806,12 @@ void RKCommandEditorWindow::renderPreview () {
 
 		QString command ("require(knitr)\n"
 				"require(markdown)\n"
-				"rk.show.html (knitr::knit2html(%1))");
+				"rk.show.html (knitr::knit2html(%1, quiet=TRUE))");
 		command = command.arg (RObject::rQuote (save.fileName ()));
 
-		RKGlobals::rInterface ()->issueCommand (".rk.with.window.hints ({\n" + command + QStringLiteral ("}, \"\", ") + RObject::rQuote (id) + ')', RCommand::App);
+		RCommand *rcommand = new RCommand (".rk.with.window.hints ({\n" + command + QStringLiteral ("}, \"\", ") + RObject::rQuote (preview_manager->previewId ()) + ')', RCommand::App);
+		preview_manager->setCommand (rcommand);
 		preview->wrapperWidget ()->show ();
-	} else {
-		preview->wrapperWidget ()->hide ();
 	}
 }
 
diff --git a/rkward/windows/rkcommandeditorwindow.h b/rkward/windows/rkcommandeditorwindow.h
index 4869eccf..e1bf9a2b 100644
--- a/rkward/windows/rkcommandeditorwindow.h
+++ b/rkward/windows/rkcommandeditorwindow.h
@@ -125,10 +125,9 @@ private:
 	RKCommandEditorWindow *command_editor;
 };
 
-class QTimer;
 class RKJobSequence;
-class QSplitter;
 class RKXMLGUIPreviewArea;
+class RKPreviewManager;
 
 /**
 	\brief Provides an editor window for R-commands, as well as a text-editor window in general.
@@ -190,8 +189,6 @@ public slots:
 	void runCurrent ();
 /** run the entire script */
 	void runAll ();
-/** Render the (.Rmd) current script */
-	void renderPreview ();
 /** insert line break and run the (previous) line */
 	void enterAndSubmit ();
 	void copyLinesToOutput ();
@@ -220,12 +217,14 @@ private slots:
 /** run a block */
 	void runBlock ();
 	void clearUnusedBlocks ();
+/** handler to control when autosaves should be created, preview should be updated */
+	void textChanged ();
+/** Render the (.Rmd) current script */
+	void doRenderPreview ();
 /** creates an autosave file */
 	void doAutoSave ();
 /** handler to control when autosaves should be created */
 	void autoSaveHandlerModifiedChanged ();
-/** handler to control when autosaves should be created */
-	void autoSaveHandlerTextChanged ();
 /** handle any errors during auto-saving */
 	void autoSaveHandlerJobFinished (RKJobSequence* seq);
 private:
@@ -267,15 +266,16 @@ private:
 	QAction* action_setwd_to_script;
 
 	QUrl previous_autosave_url;
-	QTimer* autosave_timer;
+	QTimer autosave_timer;
 
 	QUrl delete_on_close;
 
 	QString _id;
 	static QMap<QString, KTextEditor::Document*> unnamed_documents;
 
-	QSplitter *preview_splitter;
 	RKXMLGUIPreviewArea *preview;
+	QTimer preview_timer;
+	RKPreviewManager *preview_manager;
 };
 
 /** Simple class to provide HTML highlighting for arbitrary R code. */



More information about the rkward-tracker mailing list