[education/rkward] rkward/rbackend: Add rk.select.file() function; not yet documented

Thomas Friedrichsmeier null at kde.org
Fri Sep 8 21:42:25 BST 2023


Git commit 4ed0423c313072a5fbd83ff4b9561e0f56e5950f by Thomas Friedrichsmeier.
Committed on 08/09/2023 at 22:41.
Pushed by tfry into branch 'master'.

Add rk.select.file() function; not yet documented

M  +8    -9    rkward/rbackend/rkrbackend.cpp
M  +2    -3    rkward/rbackend/rkrbackendprotocol_shared.h
M  +32   -8    rkward/rbackend/rkrinterface.cpp
M  +1    -0    rkward/rbackend/rpackages/rkward/NAMESPACE
M  +10   -0    rkward/rbackend/rpackages/rkward/R/rk.KDE_GUI-functions.R

https://invent.kde.org/education/rkward/-/commit/4ed0423c313072a5fbd83ff4b9561e0f56e5950f

diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index 77ebb401a..01dfa9ab9 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -636,19 +636,18 @@ QStringList charPArrayToQStringList (const char** chars, int count) {
 	return ret;
 }
 
-int RChooseFile (int isnew, char *buf, int len) {
+int RChooseFile(int isnew, char *buf, int len) {
 	RK_TRACE (RBACKEND);
 
-	RBackendRequest request (true, RBackendRequest::ChooseFile);
-	request.params["new"] = QVariant ((bool) isnew);
+	QStringList params;
+	params << "choosefile" << QString() /* caption */ << QString() /* initial */ << "*" /* filter */ << (isnew ? "newfile" : "file");
+	auto res = RKRBackend::this_pointer->handlePlainGenericRequest(params, true);
 
-	RKRBackend::this_pointer->handleRequest (&request);
-
-	QByteArray localres = RKRBackend::fromUtf8 (request.params["result"].toString ());
-	qstrncpy ((char *) buf, localres.data (), len);
+	QByteArray localres = RKRBackend::fromUtf8(res.ret.toString());
+	qstrncpy ((char *) buf, localres.data(), len);
 
-// return length of filename (strlen (buf))
-	return (qMin (len - 1, localres.size ()));
+// return length of filename (strlen(buf))
+	return (qMin(len - 1, localres.size()));
 }
 
 /* There are about one million possible entry points to editing / showing files. We try to cover them all, using the
diff --git a/rkward/rbackend/rkrbackendprotocol_shared.h b/rkward/rbackend/rkrbackendprotocol_shared.h
index 9b1780d2f..f452730fc 100644
--- a/rkward/rbackend/rkrbackendprotocol_shared.h
+++ b/rkward/rbackend/rkrbackendprotocol_shared.h
@@ -31,14 +31,13 @@ public:
 		BackendExit,
 		ShowMessage,
 		ShowFiles,
-		ChooseFile,
 		EditFiles,
-		ReadLine,      // 5
+		ReadLine,      // 4
 		CommandOut,                  /**< Request the next command, and notify about the result of the previus. TODO split. */
 		Started,
 		EvalRequest,
 		CallbackRequest,
-		GenericRequestWithSubcommands,   // 10
+		GenericRequestWithSubcommands,   // 9
 		PlainGenericRequest,
 		SetParamsFromBackend,
 		Debugger,
diff --git a/rkward/rbackend/rkrinterface.cpp b/rkward/rbackend/rkrinterface.cpp
index a6dfeb9d0..325ab23d2 100644
--- a/rkward/rbackend/rkrinterface.cpp
+++ b/rkward/rbackend/rkrinterface.cpp
@@ -16,6 +16,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 #include "../settings/rksettingsmoduleoutput.h"
 #include "../settings/rksettingsmodulegraphics.h"
 #include "../settings/rksettingsmoduleplugins.h"
+#include "../settings/rkrecenturls.h"
 #include "../core/robjectlist.h"
 #include "../core/renvironmentobject.h"
 #include "../core/rkmodificationtracker.h"
@@ -624,6 +625,37 @@ GenericRRequestResult RInterface::processPlainGenericRequest(const QStringList &
 		QStringList results = RKSelectListDialog::doSelect (QApplication::activeWindow(), title, choices, preselects, multiple);
 		if (results.isEmpty ()) results.append ("");	// R wants to have it that way
 		return GenericRRequestResult(results);
+	} else if (call == "choosefile") {
+		QFileDialog d(nullptr, calllist.value(1));  // caption
+		QString initial = calllist.value(2);
+		QString cat;
+		if (initial.startsWith('#')) {
+			cat = initial.mid(1);
+			initial = QFileInfo(RKRecentUrls::mostRecentUrl(cat).toLocalFile()).absolutePath();
+		}
+
+		d.setDirectory(initial);
+		QString filter = calllist.value(3);
+		if (!filter.isEmpty()) {
+			if (!filter.contains('(')) filter += '(' + filter + ')';
+			d.setNameFilter(filter);
+		}
+		QString mode = calllist.value(4);
+		if (mode == "file") d.setFileMode(QFileDialog::ExistingFile);
+		else if (mode == "files") d.setFileMode(QFileDialog::ExistingFiles);
+		else if (mode == "dir") d.setFileMode(QFileDialog::Directory);
+		else if (mode == "newfile") {
+			d.setFileMode(QFileDialog::AnyFile);
+			d.setAcceptMode(QFileDialog::AcceptSave);
+		} else RK_ASSERT(false);
+
+		d.exec();
+		auto res = d.selectedFiles();
+		if (!res.isEmpty() && !cat.isEmpty()) {
+			RKRecentUrls::addRecentUrl(cat, QUrl::fromLocalFile(res.value(0)));
+		}
+
+		return GenericRRequestResult(res);
 	} else if (call == "commandHistory") {
 		if (calllist.value (1) == "get") {
 			return GenericRRequestResult(RKConsole::mainConsole()->commandHistory());
@@ -868,14 +900,6 @@ void RInterface::processRBackendRequest (RBackendRequest *request) {
 	} else if ((type == RBackendRequest::ShowFiles) || (type == RBackendRequest::EditFiles)) {
 		ShowEditTextFileAgent::showEditFiles (request);
 		return;		// we are not done, yet!
-	} else if (type == RBackendRequest::ChooseFile) {
-		QString filename;
-		if (request->params["new"].toBool ()) {
-			filename = QFileDialog::getSaveFileName ();
-		} else {
-			filename = QFileDialog::getOpenFileName ();
-		}
-		request->params["result"] = QVariant (filename);
 	} else if (type == RBackendRequest::SetParamsFromBackend) {
 			na_real = request->params["na_real"].toDouble ();
 			na_int = request->params["na_int"].toInt ();
diff --git a/rkward/rbackend/rpackages/rkward/NAMESPACE b/rkward/rbackend/rpackages/rkward/NAMESPACE
index 2fb4c47d5..120820136 100644
--- a/rkward/rbackend/rpackages/rkward/NAMESPACE
+++ b/rkward/rbackend/rpackages/rkward/NAMESPACE
@@ -103,6 +103,7 @@ export(rk.save.workplace)
 export(rk.screen.device)
 export(rk.select.CRAN.mirror)
 export(rk.select.list)
+export(rk.select.file)
 export(rk.sessionInfo)
 export(rk.set.label)
 export(rk.set.output.html.file)
diff --git a/rkward/rbackend/rpackages/rkward/R/rk.KDE_GUI-functions.R b/rkward/rbackend/rpackages/rkward/R/rk.KDE_GUI-functions.R
index f6cfb6571..8df0491cf 100755
--- a/rkward/rbackend/rpackages/rkward/R/rk.KDE_GUI-functions.R
+++ b/rkward/rbackend/rpackages/rkward/R/rk.KDE_GUI-functions.R
@@ -185,3 +185,13 @@
 
 	.rk.do.plain.call ("select.list", params)
 }
+
+# file dialog
+# NOTE: initial specifies initial directory to start at (or file to select).
+#       If this starts with a "#", the last file selected in a dialog with the same initial parameter
+#       will be used, instead. E.g. initial="#images".
+#' @export
+#' @rdname rk.show.messages
+"rk.select.file" <- function(caption = NULL, initial = NULL, filter = '*', mode=c("file", "files", "dir", "newfile")) {
+	.rk.do.plain.call ("choosefile", list(caption, initial, filter, mode[1]))
+}


More information about the rkward-tracker mailing list