[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