[education/rkward/devel/workspace_output] /: This issues when viewing outputs that are not yet initialized or about to be closed.

Thomas Friedrichsmeier null at kde.org
Sat Feb 19 21:48:52 GMT 2022


Git commit f475a50f4a199d222cd9369e7cb0768a708d4618 by Thomas Friedrichsmeier.
Committed on 19/02/2022 at 21:48.
Pushed by tfry into branch 'devel/workspace_output'.

This issues when viewing outputs that are not yet initialized or about to be closed.

M  +0    -1    ChangeLog
M  +3    -1    rkward/agents/rkloadagent.cpp
M  +19   -7    rkward/misc/rkoutputdirectory.cpp
M  +4    -2    rkward/misc/rkoutputdirectory.h

https://invent.kde.org/education/rkward/commit/f475a50f4a199d222cd9369e7cb0768a708d4618

diff --git a/ChangeLog b/ChangeLog
index df562e9f..558d2c78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,6 @@ TODOS for autotests:
   - Use options(warn=1), in order to get warnings into the test?
 
 TODOS for output directories:
-  - save outputs to .rkworkplace and restore them (create default output, if there is none)
   - UI
   - migration support (existing old standard output should be converted to "default.rko"; setting, when opening workspace with no attached active output file:
     - create new empty file
diff --git a/rkward/agents/rkloadagent.cpp b/rkward/agents/rkloadagent.cpp
index 6ec76986..bdc6dfac 100644
--- a/rkward/agents/rkloadagent.cpp
+++ b/rkward/agents/rkloadagent.cpp
@@ -27,6 +27,7 @@
 
 #include "../rkglobals.h"
 #include "../core/robjectlist.h"
+#include "../misc/rkoutputdirectory.h"
 #include "../rbackend/rkrinterface.h"
 #include "../rkward.h"
 #include "../windows/rkworkplace.h"
@@ -90,12 +91,13 @@ void RKLoadAgent::rCommandDone (RCommand *command) {
 					RKGlobals::rInterface ()->issueCommand ("setwd (" + RObject::rQuote (RKWorkplace::mainWorkplace ()->workspaceURL ().adjusted (QUrl::RemoveFilename).path ()) + ')', RCommand::App);
 				}
 			}
-			RKGlobals::rInterface ()->issueCommand (QString (), RCommand::EmptyCommand | RCommand::App, QString (), this, WORKSPACE_LOAD_COMPLETE_COMMAND);
 		}
+		RKGlobals::rInterface()->issueCommand(QString(), RCommand::EmptyCommand | RCommand::App, QString(), this, WORKSPACE_LOAD_COMPLETE_COMMAND);
 		RKWardMainWindow::getMain ()->setCaption (QString ());	// trigger update of caption
 	} else if (command->getFlags () == WORKSPACE_LOAD_COMPLETE_COMMAND) {
 		RKWardMainWindow::getMain ()->slotSetStatusReady ();
 		RKWardMainWindow::getMain ()->setWorkspaceMightBeModified (false);
+		RKOutputDirectory::getCurrentOutput();  // make sure some output file exists
 
 		delete this;
 		return;
diff --git a/rkward/misc/rkoutputdirectory.cpp b/rkward/misc/rkoutputdirectory.cpp
index 13f587c9..047803e4 100644
--- a/rkward/misc/rkoutputdirectory.cpp
+++ b/rkward/misc/rkoutputdirectory.cpp
@@ -264,18 +264,23 @@ RKOutputDirectory* RKOutputDirectory::createOutputDirectoryInternal() {
 	return d;
 }
 
-GenericRRequestResult RKOutputDirectory::activate(RCommandChain* chain) {
-	RK_TRACE (APP);
-
-	QString index_file = work_dir + "/index.html";
-	RKGlobals::rInterface()->issueCommand(QStringLiteral("rk.set.output.html.file(\"") + RKCommonFunctions::escape(index_file) + QStringLiteral("\")\n"), RCommand::App, QString(), 0, 0, chain);
+RKOutputDirectory::initializeIfNeeded(RCommandChain *chain) {
 	if(!initialized) {
+		RK_TRACE (APP);
 		// when an output directory is first initialized, we don't want that to count as a "modification". Therefore, update the "saved hash" _after_ initialization
 		RCommand *command = new RCommand(QString(), RCommand::App | RCommand::Sync | RCommand::EmptyCommand);
 		connect(command->notifier(), &RCommandNotifier::commandFinished, this, &RKOutputDirectory::updateSavedHash);
 		RKGlobals::rInterface()->issueCommand(command, chain);
 		initialized = true;
 	}
+}
+
+GenericRRequestResult RKOutputDirectory::activate(RCommandChain* chain) {
+	RK_TRACE (APP);
+
+	QString index_file = work_dir + "/index.html";
+	RKGlobals::rInterface()->issueCommand(QStringLiteral("rk.set.output.html.file(\"") + RKCommonFunctions::escape(index_file) + QStringLiteral("\")\n"), RCommand::App, QString(), 0, 0, chain);
+	initializeIfNeeded(chain);
 
 	return GenericRRequestResult(QVariant(index_file));
 }
@@ -322,7 +327,7 @@ bool RKOutputDirectory::isModified() const {
 QString RKOutputDirectory::caption() const {
 	RK_TRACE(APP);
 	if (!save_filename.isEmpty()) return QFileInfo(save_filename).fileName();
-	return i18n("Unsaved output");
+	return i18n("Not previously saved");
 }
 
 GenericRRequestResult RKOutputDirectory::purge(RKOutputDirectory::OverwriteBehavior discard, RCommandChain* chain, bool activate_other) {
@@ -343,6 +348,10 @@ GenericRRequestResult RKOutputDirectory::purge(RKOutputDirectory::OverwriteBehav
 			}
 		}
 	}
+	auto list = RKOutputWindowManager::self()->existingOutputWindows(workPath());
+	for (int i = 0; i < list.size(); ++i) {
+		list[i]->close(RKMDIWindow::NoAskSaveModified);
+	}
 
 	QDir dir(work_dir);
 	dir.removeRecursively();
@@ -422,7 +431,7 @@ RKOutputDirectoryCallResult RKOutputDirectory::getCurrentOutput(RCommandChain* c
 		if (it.value()->filename().isEmpty()) candidate = it.value();
 	}
 
-	if (!candidate) candidate = outputs[0];
+	if (!candidate) candidate = outputs.constBegin().value();
 	RK_ASSERT(candidate);
 	candidate->activate(chain);
 	ret.addMessages(GenericRRequestResult(QVariant(), i18n("Output has been activated, automatically")));
@@ -446,12 +455,15 @@ GenericRRequestResult RKOutputDirectory::view(bool raise) {
 			list[0]->activate();
 		}
 	} else {
+		initializeIfNeeded(chain);
 		RKWorkplace::mainWorkplace()->openOutputWindow(QUrl::fromLocalFile(workPath()));
 	}
 	return GenericRRequestResult(id);
 }
 
 RKOutputDirectoryCallResult RKOutputDirectory::get(const QString &_filename, bool create, RCommandChain *chain) {
+	RK_TRACE(APP);
+
 	RKOutputDirectoryCallResult ret;
 	if (_filename.isEmpty()) {
 		if (create) {
diff --git a/rkward/misc/rkoutputdirectory.h b/rkward/misc/rkoutputdirectory.h
index 9c27c16d..916c5c61 100644
--- a/rkward/misc/rkoutputdirectory.h
+++ b/rkward/misc/rkoutputdirectory.h
@@ -31,8 +31,8 @@ class RKMDIWindow;
 class RCommandChain;
 class RKOutputDirectory;
 
-// convenience struct to avoid defining separate functions for R API and C++ API;
-// this struct encapsulates the relevant results for both
+/** Convenience struct to avoid defining separate functions for R API and C++ API in RKOutputDirectory.
+ *  This struct encapsulates the relevant results for both */
 struct RKOutputDirectoryCallResult : public GenericRRequestResult {
 	RKOutputDirectoryCallResult() : GenericRRequestResult(), _dir(nullptr) {};
 	RKOutputDirectoryCallResult(const GenericRRequestResult &other) : GenericRRequestResult(other), _dir(nullptr) {};
@@ -67,6 +67,7 @@ public:
 	QString caption() const;
 	static GenericRRequestResult handleRCall(const QStringList& params, RCommandChain *chain);
 	static RKOutputDirectory* getOutputById(const QString& id);
+	static RKOutputDirectory* getOutputByWorkPath(const QString& workpath) { return getOutputById(workpath); };
 	static RKOutputDirectory* getOutputBySaveUrl(const QString& dest);
 	static RKOutputDirectory* getOutputByWindow(const RKMDIWindow* window);
 /** Return a list of all current output directories that have been modified. Used for asking for save during shutdown. */
@@ -84,6 +85,7 @@ private:
 	RKOutputDirectory();
 	~RKOutputDirectory();
 	void updateSavedHash();
+	void initializeIfNeeded(RCommandChain *chain);
 
 	QString saved_hash;
 	QDateTime save_timestamp;


More information about the rkward-tracker mailing list