[education/rkward] rkward: Some first bits on reworked start page: Listing and opening recent urls works.

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


Git commit 2ebce2193fd5bc910e18f555699d94f3a20fc5b0 by Thomas Friedrichsmeier.
Committed on 18/04/2022 at 21:38.
Pushed by tfry into branch 'master'.

Some first bits on reworked start page: Listing and opening recent urls works.

M  +2    -0    rkward/pages/rkward_welcome.rkh
M  +17   -20   rkward/rkward.cpp
M  +4    -8    rkward/rkward.h
M  +24   -1    rkward/settings/rkrecenturls.cpp
M  +30   -0    rkward/windows/rkhtmlwindow.cpp
M  +1    -1    rkward/windows/rkworkplace.h

https://invent.kde.org/education/rkward/commit/2ebce2193fd5bc910e18f555699d94f3a20fc5b0

diff --git a/rkward/pages/rkward_welcome.rkh b/rkward/pages/rkward_welcome.rkh
index 96b2edc2..59d190c5 100644
--- a/rkward/pages/rkward_welcome.rkh
+++ b/rkward/pages/rkward_welcome.rkh
@@ -8,6 +8,8 @@
 	By default, this page is shown each time RKWard is started (configurable in <link href="rkward://settings/general">Settings->Configure RKWard->General</link>).
 	</summary>
 
+	<section title="My recent script files" id="recent-scripts" special="recentfiles" category="rscripts" />
+
 	<section title="Introduction to RKWard" id="introduction">
 	RKWard is a GUI frontend and IDE to <link href="http://www.r-project.org">R</link>, a powerful scripting language for statistical computing. It aims to provide useful features both to experienced users of R, wishing to exploit R's scripting capabilities, as well as to users new to R, looking for an easy way to carry out statistical computation tasks.
 
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index 517a99fc..4e4d2bc1 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -490,7 +490,8 @@ void RKWardMainWindow::initActions() {
 	new_output->setIcon(RKStandardIcons::getIcon(RKStandardIcons::WindowOutput));
 	new_output->setWhatsThis(i18n("Creates and activates a new output document"));
 
-	fileOpenScript = actionCollection()->addAction(KStandardAction::Open, "file_open_script", this, SLOT(slotOpenCommandEditor()));
+	fileOpenScript = actionCollection()->addAction(KStandardAction::Open, "file_open_script");
+	connect(fileOpenScript, &QAction::triggered, this, [this]() { slotOpenCommandEditor(); });
 	actionCollection()->setDefaultShortcut(fileOpenScript, Qt::ControlModifier + Qt::AltModifier + Qt::Key_O);
 	fileOpenScript->setText(i18n("Open R Script File..."));
 
@@ -521,7 +522,8 @@ void RKWardMainWindow::initActions() {
 #endif
 #endif
 
-	fileOpenWorkspace = actionCollection ()->addAction (KStandardAction::Open, "file_openx", this, SLOT(slotFileOpenWorkspace()));
+	fileOpenWorkspace = actionCollection()->addAction(KStandardAction::Open, "file_openx");
+	connect(fileOpenWorkspace, &QAction::triggered, this, [this](){ askOpenWorkspace(); });
 	fileOpenWorkspace->setText (i18n ("Open Workspace..."));
 	actionCollection ()->setDefaultShortcut (fileOpenWorkspace, Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_O);
 	fileOpenWorkspace->setWhatsThis(i18n ("Opens an existing document"));
@@ -839,11 +841,6 @@ void RKWardMainWindow::askOpenWorkspace (const QUrl &url) {
 	slotSetStatusReady();
 }
 
-void RKWardMainWindow::slotFileOpenWorkspace () {
-	RK_TRACE (APP);
-	askOpenWorkspace (QUrl ());
-}
-
 void RKWardMainWindow::slotFileLoadLibs () {
 	RK_TRACE (APP);
 	RKLoadLibsDialog *dial = new RKLoadLibsDialog (this, 0);
@@ -990,28 +987,28 @@ void RKWardMainWindow::slotNewOutput() {
 	RKWorkplace::mainWorkplace()->openOutputWindow(QUrl(), true);
 }
 
-void RKWardMainWindow::slotOpenOutput() {
+void RKWardMainWindow::slotOpenOutput(const QUrl &_url) {
 	RK_TRACE (APP);
 
-	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 [*](*)"));
+	QUrl url(_url);
+	if (url.isEmpty()) {
+		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);
 }
 
 void RKWardMainWindow::slotOpenCommandEditor (const QUrl &url, const QString &encoding) {
 	RK_TRACE (APP);
 
-	RKWorkplace::mainWorkplace ()->openScriptEditor (url, encoding);
-}
-
-void RKWardMainWindow::slotOpenCommandEditor () {
-	RK_TRACE (APP);
-	KEncodingFileDialog::Result res;
-
-	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) {
-		slotOpenCommandEditor (res.URLs[i], res.encoding);
+	if (url.isEmpty()) {
+		auto 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) {
+				RKWorkplace::mainWorkplace ()->openScriptEditor(res.URLs[i], res.encoding);
+		}
+	} else {
+		RKWorkplace::mainWorkplace ()->openScriptEditor(url, encoding);
 	}
-};
+}
 
 void RKWardMainWindow::setCaption (const QString &) {
 	RK_TRACE (APP);
diff --git a/rkward/rkward.h b/rkward/rkward.h
index 166618c4..6cc67a0d 100644
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@ -72,11 +72,9 @@ public slots:
 	/** open a workspace. If the current workspace is not empty, ask whether to save first.
     @see setNoAskSave ()
     @see setWorkspaceMightBeModified () */
-	void askOpenWorkspace (const QUrl &url);
+	void askOpenWorkspace (const QUrl &url=QUrl());
 	/** creates a new (empty) data.frame */
 	void slotNewDataFrame ();
-	/** open a file and load it into the document*/
-	void slotFileOpenWorkspace();
 	/** save a document */
 	void slotFileSaveWorkspace();
 	/** save a document by a new filename*/
@@ -104,15 +102,13 @@ public slots:
 
 /** open a new command editor (blank file) */
 	void slotNewCommandEditor();
-/** open a new command editor (ask for file to open) */
-	void slotOpenCommandEditor ();
-/** open a new command editor (load given url) */
-	void slotOpenCommandEditor (const QUrl &url, const QString& encoding = QString ());
+/** open a new command editor (load given url, ask for url to load, if empty) */
+	void slotOpenCommandEditor (const QUrl &url = QUrl(), const QString& encoding = QString());
 
 /** create and show a new output window */
 	void slotNewOutput();
 /** load an output Window (ask for file to open) */
-	void slotOpenOutput();
+	void slotOpenOutput(const QUrl &url=QUrl());
 
 /** close current window (Windows->Close). */
 	void slotCloseWindow ();
diff --git a/rkward/settings/rkrecenturls.cpp b/rkward/settings/rkrecenturls.cpp
index f1792b0a..57425207 100644
--- a/rkward/settings/rkrecenturls.cpp
+++ b/rkward/settings/rkrecenturls.cpp
@@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include <KSharedConfig>
 #include <KConfigGroup>
 #include <KRecentFilesAction>
+#include <kconfigwidgets_version.h>
 
 #include "rksettingsmodulecommandeditor.h"
 
@@ -36,7 +37,29 @@ QUrl RKRecentUrls::mostRecentUrl(const QString& id) {
 	if (id.isEmpty() && !actions.contains(id)) {
 		return QUrl::fromLocalFile(QDir::currentPath());
 	}
-	return action(id)->urls().value(0);
+	auto list = allRecentUrls(id);
+	if (list.isEmpty()) return QUrl::fromLocalFile(QDir::currentPath());
+	return list.first();
+}
+
+QList<QUrl> RKRecentUrls::allRecentUrls(const QString& id) {
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 93, 0)
+	// KRecentFilesAction::urls() returns random order... Let's make an effort for a reasonable sorting.
+	auto unsorted = action(id)->urls();
+	auto list = action(id)->actions();
+	QList<QUrl> ret;
+	for (int i = list.size()-1; i >= 0; --i) {
+		for (int j = 0; j < unsorted.size(); ++j) {
+			if (list[i]->text().contains(unsorted[j].fileName())) {
+				ret.append(unsorted.takeAt(j));
+				break;
+			}
+		}
+	}
+	return ret + unsorted;
+#else
+	return action(id)->urls();
+#endif
 }
 
 RKRecentUrls::RKRecentUrls() {
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index aecac76a..05238f9f 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -572,6 +572,23 @@ bool RKHTMLWindow::handleRKWardURL (const QUrl &url, RKHTMLWindow *window) {
 			QString path = url.path ();
 			if (path.startsWith ('/')) path = path.mid (1);
 			RKSettings::configureSettings(path);
+		} else if (url.host () == "open") {
+			QString path = url.path().mid(1); // skip initial '/'
+			int sep = path.indexOf('/');
+			QString category = path.left(sep);
+			path = path.mid(sep+1);
+			RK_DEBUG(APP, DL_DEBUG, "rkward://open: %s -> %s , %s", qPrintable(url.path()), qPrintable(category), qPrintable(path));
+			QUrl target;
+			if (!path.isEmpty()) target = QUrl::fromUserInput(path);
+			if (category == RKRecentUrls::scriptsId()) {
+				RKWardMainWindow::getMain()->slotOpenCommandEditor(target);
+			} else if (category == RKRecentUrls::workspaceId()) {
+				RKWardMainWindow::getMain()->askOpenWorkspace(target);
+			} else if (category == RKRecentUrls::outputId()) {
+				RKWardMainWindow::getMain()->slotOpenOutput(target);
+			} else {
+				RKWorkplace::mainWorkplace()->openAnyUrl(target);
+			}
 		} else {
 			if (window) window->openRKHPage (url);
 			else RKWorkplace::mainWorkplace ()->openHelpWindow (url);	// will recurse with window set, via openURL()
@@ -1077,6 +1094,19 @@ bool RKHelpRenderer::renderRKHelp (const QUrl &url) {
 		QString shorttitle = help_xml_helper.i18nStringAttribute (*it, "shorttitle", QString (), DL_DEBUG);
 		QString id = help_xml_helper.getStringAttribute (*it, "id", QString (), DL_WARNING);
 		writeHTML (startSection (id, title, shorttitle, &anchors, &anchornames));
+		QString special = help_xml_helper.getStringAttribute(*it, "special", QString(), DL_DEBUG);
+		if (!special.isEmpty()) {
+			if (special == "recentfiles") {
+				writeHTML("<ul>\n");
+				QString category = help_xml_helper.getStringAttribute(*it, "category", QString(), DL_WARNING);
+				auto list = RKRecentUrls::allRecentUrls(category);
+				for (int i = 0; i < list.size(); ++i) {
+					writeHTML(QString("<li><a href=\"rkward://open/%1/%2\">%3</a></li>\n").arg(category, list[i].url(), RKCommonFunctions::escape(list[i].url(QUrl::PreferLocalFile))));
+				}
+				writeHTML(QString("<li><<a href=\"rkward://open/%1/\">%2</a>></li>\n").arg(category, i18n("Choose another file")));
+				writeHTML("</ul>\n");
+			}
+		}
 		writeHTML (renderHelpFragment (*it));
 	}
 
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 4279fa46..3997a6bf 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -77,7 +77,7 @@ struct RKCommandEditorFlags {
 };
 
 /** This class (only one instance will probably be around) keeps track of which windows are opened in the workplace, which are detached, etc. Also it is responsible for creating and manipulating those windows.
-It also provides a QWidget (RKWorkplace::view ()), which actually manages the document windows (only those, so far. I.e. this is a half-replacement for KMdi, which will be gone in KDE 4). Currently layout of the document windows is always tabbed. */
+It also provides a QWidget (RKWorkplace::view ()), which actually manages the document and tool windows. */
 class RKWorkplace : public QWidget {
 	Q_OBJECT
 public:



More information about the rkward-tracker mailing list