[education/rkward/devel/workspace_output] rkward: Add option to use shared output file by default (much like the old behavior)

Thomas Friedrichsmeier null at kde.org
Wed Mar 9 16:30:27 GMT 2022


Git commit ab8e7dccd7b8c13ffdd52dcb4601135c680b56d7 by Thomas Friedrichsmeier.
Committed on 09/03/2022 at 16:29.
Pushed by tfry into branch 'devel/workspace_output'.

Add option to use shared output file by default (much like the old behavior)

M  +31   -15   rkward/misc/rkoutputdirectory.cpp
M  +2    -2    rkward/rbackend/rpackages/rkward/R/rk.output.R
M  +2    -2    rkward/rbackend/rpackages/rkward/man/RK.Output.Rd
M  +10   -1    rkward/settings/rksettingsmoduleoutput.cpp
M  +4    -1    rkward/settings/rksettingsmoduleoutput.h

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

diff --git a/rkward/misc/rkoutputdirectory.cpp b/rkward/misc/rkoutputdirectory.cpp
index 815c4743..d527bdc2 100644
--- a/rkward/misc/rkoutputdirectory.cpp
+++ b/rkward/misc/rkoutputdirectory.cpp
@@ -25,6 +25,7 @@
 #include <KMessageBox>
 
 #include "../settings/rksettingsmodulegeneral.h"
+#include "../settings/rksettingsmoduleoutput.h"
 #include "../rbackend/rcommand.h"
 #include "../rbackend/rkrinterface.h"
 #include "../windows/rkmdiwindow.h"
@@ -46,11 +47,11 @@ void listDirectoryState(const QString& _dir, QString *list, const QString prefix
 	for (int i = 0; i < entries.size(); ++i) {
 		const QFileInfo fi = entries[i];
 		if (fi.isDir()) {
-			listDirectoryState(fi.absolutePath (), list, prefix + '/' + fi.fileName());
+			listDirectoryState(fi.absolutePath(), list, prefix + '/' + fi.fileName());
 		} else {
-			list->append(fi.fileName () + '\t');
-			list->append(fi.lastModified ().toString ("dd.hh.mm.ss.zzz") + '\t');
-			list->append(QString::number (fi.size()) + '\n');
+			list->append(fi.fileName() + '\t');
+			list->append(fi.lastModified().toString("dd.hh.mm.ss.zzz") + '\t');
+			list->append(QString::number(fi.size()) + '\n');
 		}
 	}
 }
@@ -339,7 +340,7 @@ QString RKOutputDirectory::caption() const {
 GenericRRequestResult RKOutputDirectory::purge(RKOutputDirectory::OverwriteBehavior discard, RCommandChain* chain, bool activate_other) {
 	RK_TRACE(APP);
 
-	if (isModifiedAccurate()) {
+	if ((discard != Force) && isModifiedAccurate()) {
 		if (discard == Fail) {
 			return GenericRRequestResult::makeError(i18n("Output has been modified. Not closing it."));
 		}
@@ -422,6 +423,16 @@ RKOutputDirectoryCallResult RKOutputDirectory::getCurrentOutput(RCommandChain* c
 
 	RKOutputDirectoryCallResult ret;
 	if (outputs.isEmpty()) {
+		if (RKSettingsModuleOutput::sharedDefaultOutput()) {
+			QString filename = RKSettingsModuleGeneral::filesPath() + "default.rko";
+			auto ret = get(filename, !QFileInfo(filename).exists(), chain);
+			if (ret.dir()) {
+				ret.dir()->activate(chain);
+				return ret;
+			}
+			// otherwise: fallthrough to below, just in case
+		}
+
 		auto n = createOutputDirectoryInternal();
 		n->activate(chain);
 		ret.addMessages(GenericRRequestResult(QVariant(), i18n("New empty output directory has been created, automatically")));
@@ -505,29 +516,34 @@ RKOutputDirectoryCallResult RKOutputDirectory::get(const QString &_filename, boo
 		QFileInfo fi(_filename);
 		bool file_exists = fi.exists();
 		QString filename = file_exists ? fi.canonicalFilePath() : _filename;
-		RKOutputDirectory *dir = file_exists ? findOutputBySaveUrl(filename) : nullptr;
+		RKOutputDirectory *dir = findOutputBySaveUrl(filename);
 		// NOTE: annoyingly QFileInfo::canonicalFilePath() returns an empty string, if the file does not exist
 		if (create) {
 			if (dir) return GenericRRequestResult::makeError(i18n("Output '1%' is already loaded in this session. Cannot create it.", filename));
 			if (file_exists) return GenericRRequestResult::makeError(i18n("A file named '%1' already exists. Cannot create it.", filename));
 
-			// NOTE: This is a bit of an unusual case: Creating a fresh output with save file name already specified. To avoid issues (esp. around canonicalFilePath()), we make sure to actually save the new output, right away (much like "touch"), instead of only setting the save file name for later usage
-			ret.setDir(createOutputDirectoryInternal());
-			ret.addMessages(dir->save(filename));  // NOTE: save() takes care of normalizing
+			// NOTE: This may seem a bit of an unusual case: Creating a fresh output with save file name already specified.
+			// However, this actually happens, when using a shared default output file.
+			// To avoid issues (esp. around canonicalFilePath()), we make sure to initialize and save the new output, right away (much like "touch"), instead of only setting the save file name for later usage
+			ret.setDir(dir = createOutputDirectoryInternal());
+			dir->save_filename = filename;
+			// this is a bit cumbersome. TODO: create a dedicated function to init an output.
+			RCommand *command = new RCommand(QStringLiteral("local({o <- rk.output(); n <- rk.output(\"") + RKCommonFunctions::escape(filename) + QStringLiteral("\"); n$activate(); n$save(); try(o$activate(), silent=TRUE); o$save() })\n"), RCommand::App);
+			RKGlobals::rInterface()->issueCommand(command, chain);
 		} else {
-			if (!file_exists) return GenericRRequestResult::makeError(i18n("File '%1' does not exist.", filename));
+			if (!(file_exists || dir)) return GenericRRequestResult::makeError(i18n("File '%1' does not exist.", filename));
 
-			ret.setDir(findOutputBySaveUrl(filename));
-			if (!ret.dir()) {
-				auto dir = createOutputDirectoryInternal();
+			if (dir) {
+				ret.setDir(dir);
+			} else {
+				dir = createOutputDirectoryInternal();
 				ret.addMessages(dir->import(filename));
 				if (ret.failed()) {
-					dir->purge(Force);
+					dir->purge(Force, chain, false);
 				} else {
 					ret.setDir(dir);
 				}
 			}
-			// else we have already set the loaded dir as ret.dir()
 		}
 	}
 	return ret;
diff --git a/rkward/rbackend/rpackages/rkward/R/rk.output.R b/rkward/rbackend/rpackages/rkward/R/rk.output.R
index c02323c4..eb519555 100644
--- a/rkward/rbackend/rpackages/rkward/R/rk.output.R
+++ b/rkward/rbackend/rpackages/rkward/R/rk.output.R
@@ -1,8 +1,8 @@
 #' Class and functions for organizing RKWard output.
 #' @name RK.Output
 #'
-#' @description Since version 0.7.5, RKWard supports more than one piece of output. While dealing with only a single output page, there will be no need for the user to call any of
-#'              these functions, directly, as exactly one output is always opened for writing in RKWard (unless rk.set.output.html.file() has been called, explicitly).
+#' @description Since version 0.7.3, RKWard supports more than one output document. While dealing with only a single output page, there will be no need for the user to call any of
+#'              the following functions, directly, as exactly one output is always opened for writing in RKWard (unless rk.set.output.html.file() has been called, explicitly).
 #'              However, these functions allow to manage several distinct output pages, programmatically.
 #'
 #'              The primary entry point is the function \code{rk.output}, which allows to retrieve the current output directly, or to load or create a new one. This will return
diff --git a/rkward/rbackend/rpackages/rkward/man/RK.Output.Rd b/rkward/rbackend/rpackages/rkward/man/RK.Output.Rd
index ed2a2870..389fc833 100644
--- a/rkward/rbackend/rpackages/rkward/man/RK.Output.Rd
+++ b/rkward/rbackend/rpackages/rkward/man/RK.Output.Rd
@@ -34,8 +34,8 @@ to overwrite/discard existing files/modifications will result in an error. If \c
 \item{raise}{Raise the output window, if it is already visble.}
 }
 \description{
-Since version 0.7.5, RKWard supports more than one piece of output. While dealing with only a single output page, there will be no need for the user to call any of
-             these functions, directly, as exactly one output is always opened for writing in RKWard (unless rk.set.output.html.file() has been called, explicitly).
+Since version 0.7.3, RKWard supports more than one output document. While dealing with only a single output page, there will be no need for the user to call any of
+             the following functions, directly, as exactly one output is always opened for writing in RKWard (unless rk.set.output.html.file() has been called, explicitly).
              However, these functions allow to manage several distinct output pages, programmatically.
 
              The primary entry point is the function \code{rk.output}, which allows to retrieve the current output directly, or to load or create a new one. This will return
diff --git a/rkward/settings/rksettingsmoduleoutput.cpp b/rkward/settings/rksettingsmoduleoutput.cpp
index 3486247f..eea2b8ee 100644
--- a/rkward/settings/rksettingsmoduleoutput.cpp
+++ b/rkward/settings/rksettingsmoduleoutput.cpp
@@ -23,7 +23,7 @@
 #include <qlayout.h>
 #include <qlabel.h>
 #include <QGroupBox>
-#include <qcheckbox.h>
+#include <QCheckBox>
 #include <QVBoxLayout>
 #include <QComboBox>
 #include <QSpinBox>
@@ -150,6 +150,7 @@ int RKSettingsModuleOutput::graphics_width;
 int RKSettingsModuleOutput::graphics_height;
 int RKSettingsModuleOutput::graphics_jpg_quality;
 QString RKSettingsModuleOutput::custom_css_file;
+RKConfigValue<bool> RKSettingsModuleOutput::shared_default_output {"Shared default output", false};
 
 RKSettingsModuleOutput::RKSettingsModuleOutput (RKSettings *gui, QWidget *parent) : RKSettingsModule(gui, parent) {
 	RK_TRACE (SETTINGS);
@@ -168,6 +169,11 @@ RKSettingsModuleOutput::RKSettingsModuleOutput (RKSettings *gui, QWidget *parent
 
 	main_vbox->addWidget (group);
 
+	shared_default_output_box = new QCheckBox(i18n("Default output (used, while no other output has been set, explicitly) is shared across workspaces(*)."), this);
+	shared_default_output_box->setChecked(shared_default_output);
+	connect(shared_default_output_box, &QCheckBox::stateChanged, this, &RKSettingsModuleOutput::boxChanged);
+	main_vbox->addWidget(shared_default_output_box);
+
 	custom_css_file_box = new GetFileNameWidget (this, GetFileNameWidget::ExistingFile, true, i18n ("CSS file to use for output (leave empty for default)"), i18n ("Select CSS file"), custom_css_file);
 	connect (custom_css_file_box, &GetFileNameWidget::locationChanged, this, &RKSettingsModuleOutput::boxChanged);
 	RKCommonFunctions::setTips (i18n ("Select a CSS file for custom formatting of the output window. Leave empty to use the default CSS file shipped with RKWard. Note that this setting takes effect, when initializing an output file (e.g. after flushing the output), only."), custom_css_file_box);
@@ -246,6 +252,7 @@ void RKSettingsModuleOutput::applyChanges () {
 
 	auto_show = auto_show_box->isChecked ();
 	auto_raise = auto_raise_box->isChecked ();
+	shared_default_output = shared_default_output_box->isChecked();
 
 	custom_css_file = custom_css_file_box->getLocation ();
 
@@ -279,6 +286,7 @@ void RKSettingsModuleOutput::saveSettings (KConfig *config) {
 	cg.writeEntry ("graphics_height", graphics_height);
 	cg.writeEntry ("graphics_jpg_quality", graphics_jpg_quality);
 	cg.writeEntry ("custom css file", custom_css_file);
+	shared_default_output.saveConfig(cg);
 
 	RKCarbonCopySettings::saveSettings (config);
 }
@@ -294,6 +302,7 @@ void RKSettingsModuleOutput::loadSettings (KConfig *config) {
 	graphics_height = cg.readEntry ("graphics_height", 480);
 	graphics_jpg_quality = cg.readEntry ("graphics_jpg_quality", 75);
 	custom_css_file = cg.readEntry ("custom css file", QString ());
+	shared_default_output.loadConfig(cg);
 
 	RKCarbonCopySettings::loadSettings (config);
 }
diff --git a/rkward/settings/rksettingsmoduleoutput.h b/rkward/settings/rksettingsmoduleoutput.h
index b17dde6c..5a785138 100644
--- a/rkward/settings/rksettingsmoduleoutput.h
+++ b/rkward/settings/rksettingsmoduleoutput.h
@@ -88,9 +88,10 @@ public:
 	static void validateSettingsInteractive (QList<RKSetupWizardItem*>*) {};
 
 	QString caption () override;
-	
+
 	static bool autoShow () { return auto_show; };
 	static bool autoRaise () { return auto_raise; };
+	static bool sharedDefaultOutput() { return shared_default_output; };
 public slots:
 	void boxChanged ();
 private:
@@ -102,6 +103,7 @@ private:
 	QSpinBox *graphics_jpg_quality_box;
 	RKCarbonCopySettings *cc_settings;
 	GetFileNameWidget *custom_css_file_box;
+	QCheckBox* shared_default_output_box;
 
 	static bool auto_show;
 	static bool auto_raise;
@@ -110,6 +112,7 @@ private:
 	static int graphics_height;
 	static int graphics_jpg_quality;
 	static QString custom_css_file;
+	static RKConfigValue<bool> shared_default_output;
 };
 
 #endif


More information about the rkward-tracker mailing list