[education/rkward] rkward: Unify recent urls handling

Thomas Friedrichsmeier null at kde.org
Wed Apr 20 14:02:40 BST 2022


Git commit ddc227f534fdfca5e7e22b6479e3debeeae7be3c by Thomas Friedrichsmeier.
Committed on 16/04/2022 at 21:47.
Pushed by tfry into branch 'master'.

Unify recent urls handling

M  +3    -4    rkward/misc/getfilenamewidget.cpp
M  +2    -3    rkward/rkconsole.cpp
M  +16   -35   rkward/rkward.cpp
M  +1    -6    rkward/rkward.h
M  +1    -0    rkward/settings/CMakeLists.txt
A  +90   -0    rkward/settings/rkrecenturls.cpp     [License: GPL(v2.0+)]
A  +40   -0    rkward/settings/rkrecenturls.h     [License: GPL(v2.0+)]
M  +0    -22   rkward/settings/rksettingsmodulegeneral.cpp
M  +0    -6    rkward/settings/rksettingsmodulegeneral.h
M  +13   -8    rkward/windows/rkcommandeditorwindow.cpp
M  +1    -0    rkward/windows/rkcommandeditorwindow.h
M  +2    -1    rkward/windows/rkhtmlwindow.cpp

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

diff --git a/rkward/misc/getfilenamewidget.cpp b/rkward/misc/getfilenamewidget.cpp
index b896dcbf..838dcfad 100644
--- a/rkward/misc/getfilenamewidget.cpp
+++ b/rkward/misc/getfilenamewidget.cpp
@@ -14,7 +14,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include <kurlrequester.h>
 #include <KLineEdit>
 
-#include "../settings/rksettingsmodulegeneral.h"
+#include "../settings/rkrecenturls.h"
 
 #include "../debug.h"
 
@@ -56,7 +56,7 @@ GetFileNameWidget::GetFileNameWidget (QWidget *parent, FileType mode, bool only_
 		storage_key = initial.section ('>', 0, 0).mid (1);
 		append = initial.section ('>', 1);
 	}
-	QUrl initial_url = RKSettingsModuleGeneral::lastUsedUrlFor (storage_key);  // storage_key == QString () in the default case is intended
+	QUrl initial_url = RKRecentUrls::mostRecentUrl(storage_key);  // storage_key == QString () in the default case is intended
 	if (!append.isEmpty ()) {
 		if (initial_url.isLocalFile ()) {
 			initial_url = QUrl::fromUserInput (append, initial_url.toLocalFile (), QUrl::AssumeLocalFile);
@@ -92,8 +92,7 @@ void GetFileNameWidget::updateLastUsedUrl (const QUrl& url) {
 	RK_TRACE (MISC);
 
 	if (!url.isValid ()) return;
-	if (edit->mode () & KFile::Directory) RKSettingsModuleGeneral::updateLastUsedUrl (storage_key, url);
-	else RKSettingsModuleGeneral::updateLastUsedUrl (storage_key, url.adjusted (QUrl::RemoveFilename));
+	RKRecentUrls::addRecentUrl(storage_key, url);
 }
 
 void GetFileNameWidget::setLocation (const QString &new_location) {
diff --git a/rkward/rkconsole.cpp b/rkward/rkconsole.cpp
index acc3f13d..07133060 100644
--- a/rkward/rkconsole.cpp
+++ b/rkward/rkconsole.cpp
@@ -49,7 +49,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "rbackend/rcommand.h"
 #include "settings/rksettings.h"
 #include "settings/rksettingsmoduleconsole.h"
-#include "settings/rksettingsmodulegeneral.h"
+#include "settings/rkrecenturls.h"
 #include "misc/rkcommonfunctions.h"
 #include "misc/rkstandardicons.h"
 #include "misc/rkstandardactions.h"
@@ -690,9 +690,8 @@ void RKConsole::userLoadHistory (const QUrl &_url) {
 
 	QUrl url = _url;
 	if (url.isEmpty ()) {
-		url = QFileDialog::getOpenFileUrl (this, i18n ("Select command history file to load"), RKSettingsModuleGeneral::lastUsedUrlFor ("rscripts"), i18n ("R history files [*.Rhistory](*.Rhistory);;All files [*](*)"));
+		url = QFileDialog::getOpenFileUrl (this, i18n ("Select command history file to load"), RKRecentUrls::mostRecentUrl(RKRecentUrls::scriptsId()).adjusted(QUrl::RemoveFilename), i18n ("R history files [*.Rhistory](*.Rhistory);;All files [*](*)"));
 		if (url.isEmpty ()) return;
-		RKSettingsModuleGeneral::updateLastUsedUrl ("rscripts", url.adjusted (QUrl::RemoveFilename));
 	}
 
 	QTemporaryFile *tmpfile = 0;
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index e42d9b22..517a99fc 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -47,6 +47,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "settings/rksettingsmoduleoutput.h"
 #include "settings/rksettingsmodulecommandeditor.h"
 #include "settings/rksettingsmodulekateplugins.h"
+#include "settings/rkrecenturls.h"
 #include "rbackend/rkrinterface.h"
 #include "core/robjectlist.h"
 #include "core/renvironmentobject.h"
@@ -130,7 +131,7 @@ RKWardMainWindow::RKWardMainWindow () : KParts::MainWindow ((QWidget *)0, (Qt::W
 	RKWorkplace::mainWorkplace ()->initActions (actionCollection ());
 	setCentralWidget (RKWorkplace::mainWorkplace ());
 	connect (RKWorkplace::mainWorkplace ()->view (), &RKWorkplaceView::captionChanged, this, static_cast<void (RKWardMainWindow::*)(const QString&)>(&RKWardMainWindow::setCaption));
-	connect (RKWorkplace::mainWorkplace (), &RKWorkplace::workspaceUrlChanged, this, &RKWardMainWindow::addWorkspaceUrl);
+	connect (RKWorkplace::mainWorkplace (), &RKWorkplace::workspaceUrlChanged, [this](const QUrl &url) { RKRecentUrls::addRecentUrl(RKRecentUrls::workspaceId(), url); setCaption(QString()); });
 	initStatusBar();
 
 	part_manager = new KParts::PartManager (this);
@@ -501,8 +502,10 @@ void RKWardMainWindow::initActions() {
 	connect (file_open_any, &QAction::triggered, this, &RKWardMainWindow::openAnyFile);
 	file_open_any->setText (i18n ("Open any File..."));
 
-	fileOpenRecent = static_cast<KRecentFilesAction*> (actionCollection ()->addAction (KStandardAction::OpenRecent, "file_open_recenty", this, SLOT(slotOpenCommandEditor(QUrl))));
-	fileOpenRecent->setText (i18n ("Open Recent R Script File"));
+	fileOpenRecent = RKRecentUrls::claimAction(RKRecentUrls::scriptsId());
+	actionCollection ()->addAction("file_open_recenty", fileOpenRecent);
+	connect(fileOpenRecent, &KRecentFilesAction::urlSelected, this, [this](const QUrl &url) { slotOpenCommandEditor(url); });
+	fileOpenRecent->setText(i18n("Open Recent R Script File"));
 
 #if 0
 	// TODO: Fix import dialog and re-enable it: https://mail.kde.org/pipermail/rkward-devel/2015-June/004156.html
@@ -523,7 +526,9 @@ void RKWardMainWindow::initActions() {
 	actionCollection ()->setDefaultShortcut (fileOpenWorkspace, Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_O);
 	fileOpenWorkspace->setWhatsThis(i18n ("Opens an existing document"));
 
-	fileOpenRecentWorkspace = static_cast<KRecentFilesAction*> (actionCollection ()->addAction (KStandardAction::OpenRecent, "file_open_recentx", this, SLOT(askOpenWorkspace(QUrl))));
+	fileOpenRecentWorkspace = RKRecentUrls::claimAction(RKRecentUrls::workspaceId());
+	actionCollection ()->addAction("file_open_recentx", fileOpenRecentWorkspace);
+	connect(fileOpenRecentWorkspace, &KRecentFilesAction::urlSelected, this, &RKWardMainWindow::askOpenWorkspace);
 	fileOpenRecentWorkspace->setText (i18n ("Open Recent Workspace"));
 	fileOpenRecentWorkspace->setWhatsThis(i18n ("Opens a recently used file"));
 
@@ -760,10 +765,8 @@ void RKWardMainWindow::saveOptions () {
 // TODO: WORKAROUND. See corresponding line in readOptions ()
 	cg.writeEntry("Geometry", size ());
 
-	fileOpenRecentWorkspace->saveEntries (config->group ("Recent Files"));
-	fileOpenRecent->saveEntries (config->group ("Recent Command Files"));
-
-	RKSettings::saveSettings (config.data ());
+	RKRecentUrls::saveConfig();
+	RKSettings::saveSettings(config.data());
 
 	config->sync ();
 }
@@ -788,10 +791,6 @@ void RKWardMainWindow::readOptions () {
 
 	RKSettings::loadSettings (config.data ());
 
-	// initialize the recent file list
-	fileOpenRecentWorkspace->loadEntries (config->group ("Recent Files"));
-	fileOpenRecent->setMaxItems (RKSettingsModuleCommandEditor::maxNumRecentFiles ());
-	fileOpenRecent->loadEntries (config->group ("Recent Command Files"));
 	statusBar()->hide();
 }
 
@@ -832,11 +831,10 @@ void RKWardMainWindow::askOpenWorkspace (const QUrl &url) {
 	slotSetStatusBarText(i18n("Opening workspace..."));
 	QUrl lurl = url;
 	if (lurl.isEmpty ()) {
-		lurl = QFileDialog::getOpenFileUrl(this, i18n("Select workspace to open..."), RKSettingsModuleGeneral::lastUsedUrlFor("workspaces"), i18n("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter()));
+		lurl = QFileDialog::getOpenFileUrl(this, i18n("Select workspace to open..."), RKRecentUrls::mostRecentUrl(RKRecentUrls::workspaceId()).adjusted(QUrl::RemoveFilename), i18n("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter()));
 	}
 	if (!lurl.isEmpty ()) {
-		RKSettingsModuleGeneral::updateLastUsedUrl("workspaces", lurl.adjusted(QUrl::RemoveFilename));
-		new RKLoadAgent (url, merge_loads);
+		new RKLoadAgent (lurl, merge_loads);
 	}
 	slotSetStatusReady();
 }
@@ -862,13 +860,6 @@ void RKWardMainWindow::slotFileSaveWorkspaceAs () {
 	RKSaveAgent::saveWorkspaceAs();
 }
 
-void RKWardMainWindow::addWorkspaceUrl (const QUrl &url) {
-	RK_TRACE (APP);
-
-	if (!url.isEmpty ()) fileOpenRecentWorkspace->addUrl (url);
-	setCaption (QString ());	// trigger update of caption
-}
-
 void RKWardMainWindow::updateCWD () {
 	RK_TRACE (APP);
 
@@ -953,16 +944,10 @@ void RKWardMainWindow::slotNewCommandEditor () {
 	slotOpenCommandEditor (QUrl ());
 }
 
-void RKWardMainWindow::addScriptUrl (const QUrl &url) {
-	RK_TRACE (APP);
-
-	if (!url.isEmpty ()) fileOpenRecent->addUrl (url);
-}
-
 void RKWardMainWindow::openAnyFile () {
 	RK_TRACE (APP);
 
-	QFileDialog* dialog = new QFileDialog (0, QString (), RKSettingsModuleGeneral::lastUsedUrlFor ("rscripts").toLocalFile (), QString ("*|All Files (*)\n%1|R Script Files (%1)").arg (RKSettingsModuleCommandEditor::scriptFileFilter ()));
+	QFileDialog* dialog = new QFileDialog (0, QString (), RKRecentUrls::mostRecentUrl(RKRecentUrls::scriptsId()).adjusted(QUrl::RemoveFilename).toLocalFile(), QString ("*|All Files (*)\n%1|R Script Files (%1)").arg (RKSettingsModuleCommandEditor::scriptFileFilter ()));
 	dialog->setFileMode (QFileDialog::ExistingFiles);
 
 // Create a type selection widget, and hack it into the dialog:
@@ -992,13 +977,10 @@ void RKWardMainWindow::openAnyFile () {
 		RKWorkplace::mainWorkplace ()->openAnyUrl (url);
 	} else if (mode == 1) {
 		RKWorkplace::mainWorkplace ()->openScriptEditor (url);
-		RKSettingsModuleGeneral::updateLastUsedUrl ("rscripts", url.adjusted (QUrl::RemoveFilename));
 	} else if (mode == 2) {
 		RKWorkplace::mainWorkplace ()->openScriptEditor (url, QString (), RKCommandEditorFlags::DefaultFlags | RKCommandEditorFlags::ForceRHighlighting);
-		RKSettingsModuleGeneral::updateLastUsedUrl ("rscripts", url.adjusted (QUrl::RemoveFilename));
 	} else if (mode == 3) {
 		askOpenWorkspace(url);
-		RKSettingsModuleGeneral::updateLastUsedUrl ("workspaces", url.adjusted (QUrl::RemoveFilename));
 	}
 }
 
@@ -1011,7 +993,7 @@ void RKWardMainWindow::slotNewOutput() {
 void RKWardMainWindow::slotOpenOutput() {
 	RK_TRACE (APP);
 
-	QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Select RKWard Output file to open..."), RKSettingsModuleGeneral::lastUsedUrlFor("output"), i18n("RKWard Output Files [*.rko](*.rko);;All files [*](*)"));
+	QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Select RKWard Output file to open..."), RKRecentUrls::mostRecentUrl(RKRecentUrls::outputId()).adjusted(QUrl::RemoveFilename), i18n("RKWard Output Files [*.rko](*.rko);;All files [*](*)"));
 	RKWorkplace::mainWorkplace()->openOutputWindow(url);
 }
 
@@ -1025,9 +1007,8 @@ void RKWardMainWindow::slotOpenCommandEditor () {
 	RK_TRACE (APP);
 	KEncodingFileDialog::Result res;
 
-	res = KEncodingFileDialog::getOpenUrlsAndEncoding (QString (), RKSettingsModuleGeneral::lastUsedUrlFor ("rscripts"), QString ("%1|R Script Files (%1)\n*|All Files (*)").arg (RKSettingsModuleCommandEditor::scriptFileFilter ()), this, i18n ("Open script file(s)"));
+	res = KEncodingFileDialog::getOpenUrlsAndEncoding (QString (), RKRecentUrls::mostRecentUrl(RKRecentUrls::scriptsId()).adjusted(QUrl::RemoveFilename), QString ("%1|R Script Files (%1)\n*|All Files (*)").arg (RKSettingsModuleCommandEditor::scriptFileFilter ()), this, i18n ("Open script file(s)"));
 	for (int i = 0; i < res.URLs.size (); ++i) {
-		if (i == 0) RKSettingsModuleGeneral::updateLastUsedUrl ("rscripts", res.URLs[i].adjusted (QUrl::RemoveFilename));
 		slotOpenCommandEditor (res.URLs[i], res.encoding);
 	}
 };
diff --git a/rkward/rkward.h b/rkward/rkward.h
index a52b3995..166618c4 100644
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@ -15,8 +15,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
 class QLabel;
 class QCloseEvent;
 class KActionMenu;
-class RKTopLevelWindowGUI;
 class KRecentFilesAction;
+class RKTopLevelWindowGUI;
 class KSqueezedTextLabel;
 class QAction;
 class KatePluginIntegrationApp;
@@ -99,11 +99,6 @@ public slots:
 /** configures RKward-settings */
 	void slotConfigure ();
 
-/** Add the given url to the list of recent scripts */
-	void addScriptUrl (const QUrl &url);
-/** Add the given url to the list of recent workspaces */
-	void addWorkspaceUrl (const QUrl &url);
-
 	/** Init-procedures to be done after the exec-loop was started */
 	void doPostInit ();
 
diff --git a/rkward/settings/CMakeLists.txt b/rkward/settings/CMakeLists.txt
index 951114dd..d2b1f2c3 100644
--- a/rkward/settings/CMakeLists.txt
+++ b/rkward/settings/CMakeLists.txt
@@ -17,6 +17,7 @@ SET(settings_STAT_SRCS
    rksettingsmoduleconsole.cpp
    rksettingsmodulecommandeditor.cpp
    rksettingsmoduledebug.cpp
+   rkrecenturls.cpp
    )
 
 IF (WIN32 OR USE_BINARY_PACKAGES)
diff --git a/rkward/settings/rkrecenturls.cpp b/rkward/settings/rkrecenturls.cpp
new file mode 100644
index 00000000..f1792b0a
--- /dev/null
+++ b/rkward/settings/rkrecenturls.cpp
@@ -0,0 +1,90 @@
+/*
+rkrecenturls - This file is part of the RKWard project. Created: Sat Apr 16 2022
+SPDX-FileCopyrightText: 2022 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
+SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include "rkrecenturls.h"
+
+#include <QDir>
+
+#include <KSharedConfig>
+#include <KConfigGroup>
+#include <KRecentFilesAction>
+
+#include "rksettingsmodulecommandeditor.h"
+
+#include "../debug.h"
+
+static QString _scripts_id("rscripts");
+QString RKRecentUrls::scriptsId() { return _scripts_id; }
+static QString _workspace_id("workspaces");
+QString RKRecentUrls::workspaceId() { return _workspace_id; }
+static QString _output_id("rkoutput");
+QString RKRecentUrls::outputId() { return _output_id; }
+
+QHash<QString, KRecentFilesAction*> RKRecentUrls::actions;
+
+void RKRecentUrls::addRecentUrl(const QString& id, const QUrl& url) {
+	RK_TRACE(SETTINGS);
+	action(id)->addUrl(url);
+}
+
+QUrl RKRecentUrls::mostRecentUrl(const QString& id) {
+	RK_TRACE(SETTINGS);
+	if (id.isEmpty() && !actions.contains(id)) {
+		return QUrl::fromLocalFile(QDir::currentPath());
+	}
+	return action(id)->urls().value(0);
+}
+
+RKRecentUrls::RKRecentUrls() {
+	RK_TRACE(SETTINGS);
+	// Not currrently used
+}
+
+RKRecentUrls::~RKRecentUrls() {
+	RK_TRACE(SETTINGS);
+}
+
+static KConfigGroup config() {
+	auto config = KSharedConfig::openConfig();
+	return config->group(QStringLiteral("Recent Files"));
+}
+
+void RKRecentUrls::saveConfig() {
+	RK_TRACE(SETTINGS);
+	auto cg = config();
+	for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) {
+		if (it.key().isEmpty()) continue;
+		it.value()->saveEntries(cg.group(it.key()));
+	}
+}
+
+KRecentFilesAction* RKRecentUrls::claimAction(const QString& id) {
+	RK_TRACE(SETTINGS);
+	auto ret = action(id);
+	RK_ASSERT(!ret->parent());
+	return ret;
+}
+
+KRecentFilesAction * RKRecentUrls::action(const QString& id) {
+	RK_TRACE(SETTINGS);
+	if (!actions.contains(id)) {
+		auto cg = config();
+		auto act = new KRecentFilesAction(nullptr);
+		if (!id.isEmpty()) act->loadEntries(cg.group(id));
+		act->setMaxItems(RKSettingsModuleCommandEditor::maxNumRecentFiles());  // TODO: Move setting somewhere else
+		QObject::connect(act, &QObject::destroyed, [id]() { RKRecentUrls::actions.remove(id); });
+		actions.insert(id, act);
+	}
+	return actions[id];
+}
+
+void RKRecentUrls::cleanup() {
+	for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) {
+		(*it)->deleteLater();
+	}
+	actions.clear();
+}
diff --git a/rkward/settings/rkrecenturls.h b/rkward/settings/rkrecenturls.h
new file mode 100644
index 00000000..04d8a772
--- /dev/null
+++ b/rkward/settings/rkrecenturls.h
@@ -0,0 +1,40 @@
+/*
+rkrecenturls - This file is part of the RKWard project. Created: Sat Apr 16 2022
+SPDX-FileCopyrightText: 2022 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
+SPDX-License-Identifier: GPL-2.0-or-later
+*/
+#ifndef RKRECENTURLS_H
+#define RKRECENTURLS_H
+
+#include <QString>
+#include <QHash>
+#include <QUrl>
+#include <QPointer>
+
+class KRecentFilesAction;
+
+/** A wrapper around KRecentFilesAction to have a uniform handling across all the places where we remember the last used urls. */
+class RKRecentUrls {
+public:
+/** @see mostRecentUrl() */
+	static void addRecentUrl(const QString &id, const QUrl &url);
+/** get the url last used for @param id, where id is simply a key string.
+    Urls are saved and restored across sessions, _except_ for the empty key, which will keep track of the last used
+    "generic" url within a session (and defaults to the current working directory, while not set). */
+	static QUrl mostRecentUrl(const QString &id);
+	static QList<QUrl> allRecentUrls(const QString &id);
+	static KRecentFilesAction* claimAction(const QString &id);
+	static void saveConfig();
+	static void cleanup();
+	static QString scriptsId();
+	static QString workspaceId();
+	static QString outputId();
+private:
+	RKRecentUrls();
+	~RKRecentUrls();
+	static QHash<QString, KRecentFilesAction*> actions;
+	static KRecentFilesAction* action(const QString &id);
+};
+
+#endif
diff --git a/rkward/settings/rksettingsmodulegeneral.cpp b/rkward/settings/rksettingsmodulegeneral.cpp
index b450501e..98a266db 100644
--- a/rkward/settings/rksettingsmodulegeneral.cpp
+++ b/rkward/settings/rksettingsmodulegeneral.cpp
@@ -143,28 +143,6 @@ QString RKSettingsModuleGeneral::initialWorkingDirectory () {
 	return initial_dir_specification;
 }
 
-QUrl RKSettingsModuleGeneral::lastUsedUrlFor (const QString& thing) {
-	RK_TRACE (SETTINGS);
-
-	if (thing.isEmpty ()) {
-		if (generic_filedialog_start_url.isEmpty ()) return QUrl::fromLocalFile (QDir::currentPath ());
-		return generic_filedialog_start_url;
-	}
-	KConfigGroup cg (KSharedConfig::openConfig (), "FileDialogUrls");
-	return (cg.readEntry (thing, QUrl ()));
-}
-
-void RKSettingsModuleGeneral::updateLastUsedUrl (const QString& thing, const QUrl& new_path) {
-	RK_TRACE (SETTINGS);
-
-	if (thing.isEmpty ()) {
-		generic_filedialog_start_url = new_path;
-	} else {
-		KConfigGroup cg (KSharedConfig::openConfig (), "FileDialogUrls");
-		cg.writeEntry (thing, new_path);
-	}
-}
-
 QString RKSettingsModuleGeneral::caption() const {
 	RK_TRACE(SETTINGS);
 	return(i18n("General"));
diff --git a/rkward/settings/rksettingsmodulegeneral.h b/rkward/settings/rksettingsmodulegeneral.h
index fa21f67f..8c27c97e 100644
--- a/rkward/settings/rksettingsmodulegeneral.h
+++ b/rkward/settings/rksettingsmodulegeneral.h
@@ -66,12 +66,6 @@ public:
 	static RKMDIFocusPolicy mdiFocusPolicy () { return mdi_focus_policy; }
 	static QString workspaceFilenameFilter () { return ("*.RData *.RDA"); };
 	static QString initialWorkingDirectory ();
-/** get the url last used for @param thing, where thing is simply a key string.
-    Urls are saved and restored across sessions, _except_ for the empty key, which will keep track of the last used
-    "generic" url within a session (and defaults to the current working directory, while not set). */
-	static QUrl lastUsedUrlFor (const QString& thing);
-/** update the url used for @param thing, @see lastUsedUrlFor(). */
-	static void updateLastUsedUrl (const QString& thing, const QUrl& new_path);
 /** if the installation-path of KDE seems to have moved since the last startup, *and* the given path is relative to the
  *  KDE data path, adjust the given path (probably loaded from config), accordingly. @See RKCommonFunctions::getRKWardDataDir()
  *  TODO: similar, but not quite identical functionality in rkworkplace.cpp checkAdjustRestoredUrl(). Might be mergeable. */
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 44ce9ad2..afd30080 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -50,6 +50,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "../rbackend/rkrinterface.h"
 #include "../settings/rksettings.h"
 #include "../settings/rksettingsmodulecommandeditor.h"
+#include "../settings/rkrecenturls.h"
 #include "../rkconsole.h"
 #include "../rkward.h"
 #include "rkhelpsearchwindow.h"
@@ -251,8 +252,8 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl &_url,
 	connect (m_doc, &KTextEditor::Document::documentSavedOrUploaded, this, &RKCommandEditorWindow::documentSaved);
 	layout->addWidget(preview_splitter);
 
-	setGlobalContextProperty ("current_filename", m_doc->url ().url ());
-	connect (m_doc, &KTextEditor::Document::documentUrlChanged, this, [this]() { updateCaption(); setGlobalContextProperty ("current_filename", m_doc->url ().url ()); });
+	setGlobalContextProperty("current_filename", m_doc->url().url());
+	connect (m_doc, &KTextEditor::Document::documentUrlChanged, this, &RKCommandEditorWindow::urlChanged);
 	connect (m_doc, &KTextEditor::Document::modifiedChanged, this, &RKCommandEditorWindow::updateCaption);                // of course most of the time this causes a redundant call to updateCaption. Not if a modification is undone, however.
 #ifdef __GNUC__
 #warning remove this in favor of KTextEditor::Document::restore()
@@ -280,7 +281,7 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl &_url,
 	connect (&autosave_timer, &QTimer::timeout, this, &RKCommandEditorWindow::doAutoSave);
 	connect (&preview_timer, &QTimer::timeout, this, &RKCommandEditorWindow::doRenderPreview);
 
-	updateCaption ();	// initialize
+	urlChanged();	// initialize
 }
 
 RKCommandEditorWindow::~RKCommandEditorWindow () {
@@ -739,18 +740,22 @@ void RKCommandEditorWindow::highlightLine (int linenum) {
 	if (!old_rw) m_doc->setReadWrite (false);
 }
 
-void RKCommandEditorWindow::updateCaption () {
+void RKCommandEditorWindow::urlChanged() {
 	RK_TRACE (COMMANDEDITOR);
+	updateCaption();
+	setGlobalContextProperty("current_filename", url().url());
+	if (!url().isEmpty()) RKRecentUrls::addRecentUrl(RKRecentUrls::scriptsId(), url());
+	action_setwd_to_script->setEnabled (!url().isEmpty ());
+}
+
+
+void RKCommandEditorWindow::updateCaption () {
 	QString name = url ().fileName ();
 	if (name.isEmpty ()) name = url ().toDisplayString ();
 	if (name.isEmpty ()) name = i18n ("Unnamed");
 	if (isModified ()) name.append (i18n (" [modified]"));
 
 	setCaption (name);
-
-	// Well, these do not really belong, here, but need to happen on pretty much the same occasions:
-	action_setwd_to_script->setEnabled (!url ().isEmpty ());
-	RKWardMainWindow::getMain ()->addScriptUrl (url ());
 }
 
 void RKCommandEditorWindow::currentHelpContext (QString *symbol, QString *package) {
diff --git a/rkward/windows/rkcommandeditorwindow.h b/rkward/windows/rkcommandeditorwindow.h
index 70bae000..40c7113d 100644
--- a/rkward/windows/rkcommandeditorwindow.h
+++ b/rkward/windows/rkcommandeditorwindow.h
@@ -161,6 +161,7 @@ private slots:
 /** document was saved. Update preview, if appropriate */
 	void documentSaved ();
 private:
+	void urlChanged();
 	KTextEditor::Cursor saved_scroll_position;
 	KTextEditor::Document *m_doc;
 	KTextEditor::View *m_view;
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index 57cd4ba4..aecac76a 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -39,7 +39,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "rkhelpsearchwindow.h"
 #include "../rkward.h"
 #include "../rkconsole.h"
-#include "../settings/rksettingsmodulegeneral.h"
+#include "../settings/rkrecenturls.h"
 #include "../settings/rksettingsmoduler.h"
 #include "../settings/rksettings.h"
 #include "../settings/rksettingsmoduleoutput.h"
@@ -599,6 +599,7 @@ bool RKHTMLWindow::openURL (const QUrl &url) {
 			}
 
 			current_url = url;	// needs to be set before registering
+			RKRecentUrls::addRecentUrl(RKRecentUrls::outputId(), url);
 			RKOutputWindowManager::self ()->registerWindow (this);
 			dir = RKOutputDirectory::findOutputByWorkPath(url.toLocalFile());
 			part->setOutputDirectoryActionsEnabled(dir != nullptr);



More information about the rkward-tracker mailing list