[rkward-cvs] SF.net SVN: rkward:[2988] trunk/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Thu Sep 2 17:02:26 UTC 2010


Revision: 2988
          http://rkward.svn.sourceforge.net/rkward/?rev=2988&view=rev
Author:   tfry
Date:     2010-09-02 17:02:26 +0000 (Thu, 02 Sep 2010)

Log Message:
-----------
Add functions rk.show.message and rk.show.question for basic user interaction from R code

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/rbackend/rembedinternal.cpp
    trunk/rkward/rkward/rbackend/rinterface.cpp
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2010-09-02 06:22:11 UTC (rev 2987)
+++ trunk/rkward/ChangeLog	2010-09-02 17:02:26 UTC (rev 2988)
@@ -1,5 +1,6 @@
 TODO: Do not use SmartInterface for KDE 4.5 and above
 
+- New functions rk.show.message() and rk.show.question() for user interaction from R code
 - New options for scripting GUI logic in plugins		TODO: document, merge common functionality of common.js and rkcomponentscriptiong.js, error handling
 - The current object of an active data editor can be referenced in plugins		TODO: document
 - Fixed: Placement of several menu items was broken - again - with KDE 4.4 and above

Modified: trunk/rkward/rkward/rbackend/rembedinternal.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.cpp	2010-09-02 06:22:11 UTC (rev 2987)
+++ trunk/rkward/rkward/rbackend/rembedinternal.cpp	2010-09-02 17:02:26 UTC (rev 2988)
@@ -124,6 +124,7 @@
 
 SEXP RKWard_RData_Tag;
 QString *SEXPToStringList (SEXP from_exp, unsigned int *count);
+QString SEXPToString (SEXP from_exp);
 int *SEXPToIntArray (SEXP from_exp, unsigned int *count);
 
 // ############## R Standard callback overrides BEGIN ####################
@@ -138,34 +139,6 @@
 	Rf_error ("Backend dead");	// this jumps us out of the REPL.
 }
 
-void RShowMessage (const char* message) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RShowMessage;
-	args.params["message"] = QVariant (message);
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-}
-
-// TODO: currently used on windows, only!
-/* FROM R_ext/RStartup.h: "Return value here is expected to be 1 for Yes, -1 for No and 0 for Cancel:
-   symbolic constants in graphapp.h" */
-int RAskYesNoCancel (const char* message) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RShowMessage;
-	args.params["message"] = QVariant (message);
-	args.params["askync"] = QVariant (true);
-
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-
-	QString ret = args.params["result"].toString ();
-	if (ret == "yes") return 1;
-	if (ret == "no") return -1;
-	return 0;
-}
-
 int RReadConsole (const char* prompt, unsigned char* buf, int buflen, int hist) {
 	RK_TRACE (RBACKEND);
 
@@ -378,6 +351,50 @@
 	return 1;
 }
 
+/* FROM R_ext/RStartup.h: "Return value here is expected to be 1 for Yes, -1 for No and 0 for Cancel:
+   symbolic constants in graphapp.h" */
+int doDialogHelper (QString caption, QString message, QString button_yes, QString button_no, QString button_cancel) {
+	RK_TRACE (RBACKEND);
+
+	RCallbackArgs args;
+	args.type = RCallbackArgs::RShowMessage;
+	args.params["caption"] = QVariant (caption);
+	args.params["message"] = QVariant (message);
+	args.params["button_yes"] = QVariant (button_yes);
+	args.params["button_no"] = QVariant (button_no);
+	args.params["button_cancel"] = QVariant (button_cancel);
+	
+	REmbedInternal::this_pointer->handleStandardCallback (&args);
+
+	QString ret = args.params["result"].toString ();
+	if (ret == "yes") return 1;
+	if (ret == "no") return -1;
+	return 0;
+}
+
+SEXP doDialog (SEXP caption, SEXP message, SEXP button_yes, SEXP button_no, SEXP button_cancel) {
+	RK_TRACE (RBACKEND);
+
+	int result = doDialogHelper (SEXPToString (caption), SEXPToString (message), SEXPToString (button_yes), SEXPToString (button_no), SEXPToString (button_cancel));
+
+	SEXP ret = Rf_allocVector(INTSXP, 1);
+	INTEGER (ret)[0] = result;
+	return ret;
+}
+
+void RShowMessage (const char* message) {
+	RK_TRACE (RBACKEND);
+
+	doDialogHelper (i18n ("Message from the R backend"), message, "ok", QString (), QString ());
+}
+
+// TODO: currently used on windows, only!
+int RAskYesNoCancel (const char* message) {
+	RK_TRACE (RBACKEND);
+
+	return doDialogHelper (i18n ("Question from the R backend"), message, "yes", "no", "cancel");
+}
+
 void RBusy (int busy) {
 	RK_TRACE (RBACKEND);
 
@@ -519,6 +536,20 @@
 	R_ToplevelExec (processX11EventsWorker, 0);
 }
 
+// converts SEXP to strings, and returns the first string (or QString(), if SEXP contains no strings)
+QString SEXPToString (SEXP from_exp) {
+	RK_TRACE (RBACKEND);
+
+	QString ret;
+
+	unsigned int count;
+	QString *list = SEXPToStringList (from_exp, &count);
+
+	if (count >= 1) ret = list[0];
+	delete [] list;
+	return ret;
+}
+
 QString *SEXPToStringList (SEXP from_exp, unsigned int *count) {
 	RK_TRACE (RBACKEND);
 
@@ -826,6 +857,7 @@
 		{ "rk.copy.no.eval", (DL_FUNC) &doCopyNoEval, 3 },
 		{ "rk.edit.files", (DL_FUNC) &doEditFiles, 3 },
 		{ "rk.show.files", (DL_FUNC) &doShowFiles, 4 },
+		{ "rk.dialog", (DL_FUNC) &doDialog, 5 },
 		{ "rk.update.locale", (DL_FUNC) &doUpdateLocale, 0 },
 		{ "rk.locale.name", (DL_FUNC) &doLocaleName, 0 },
 		{ 0, 0, 0 }

Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp	2010-09-02 06:22:11 UTC (rev 2987)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp	2010-09-02 17:02:26 UTC (rev 2988)
@@ -482,14 +482,35 @@
 	RCallbackArgs::RCallbackType type = args->type;
 
 	if (type == RCallbackArgs::RShowMessage) {
-		if (args->params.value ("askync").toBool ()) {
-			int res = KMessageBox::questionYesNoCancel (0, args->params["message"].toString (), i18n ("Question from the R backend"));
-			if (res == KMessageBox::Yes) args->params["result"] = "yes";
-			else if (res == KMessageBox::No) args->params["result"] = "no";
-			// else: cancel
-		} else {
-			KMessageBox::information (0, args->params["message"].toString (), i18n ("Message from the R backend"));
+		QString caption = args->params["caption"].toString ();
+		QString message = args->params["message"].toString ();
+		QString button_yes = args->params["button_yes"].toString ();;
+		QString button_no = args->params["button_no"].toString ();;
+		QString button_cancel = args->params["button_cancel"].toString ();;
+
+		KGuiItem button_yes_item = KStandardGuiItem::yes ();
+		if (button_yes != "yes") button_yes_item.setText (button_yes);
+		KGuiItem button_no_item = KStandardGuiItem::no ();
+		if (button_no != "no") button_no_item.setText (button_no);
+		KGuiItem button_cancel_item = KStandardGuiItem::cancel ();
+		if (button_cancel != "cancel") button_cancel_item.setText (button_cancel);
+
+		KMessageBox::DialogType dialog_type = KMessageBox::QuestionYesNoCancel;
+		if (button_cancel.isEmpty ()) dialog_type = KMessageBox::QuestionYesNo;
+		if (button_no.isEmpty () && button_cancel.isEmpty ()) {
+			if (button_yes == "ok") button_yes_item = KStandardGuiItem::ok ();
+			dialog_type = KMessageBox::Information;
 		}
+
+		int result = KMessageBox::messageBox (0, dialog_type, message, caption, button_yes_item, button_no_item, button_cancel_item);
+
+		QString result_string;
+		if ((result == KMessageBox::Yes) || (result == KMessageBox::Ok)) result_string = "yes";
+		else if (result == KMessageBox::No) result_string = "no";
+		else if (result == KMessageBox::Cancel) result_string = "cancel";
+		else RK_ASSERT (false);
+
+		args->params["result"] = result_string;
 	} else if (type == RCallbackArgs::RReadLine) {
 		QString result;
 

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2010-09-02 06:22:11 UTC (rev 2987)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2010-09-02 17:02:26 UTC (rev 2988)
@@ -416,3 +416,16 @@
 
 	.rk.do.call ("select.list", params)
 }
+
+"rk.show.message" <- function (message, caption = "Information") {
+	.Call ("rk.dialog", caption, message, "ok", "", "")
+	invisible (TRUE)
+}
+
+# to disable a button, set it to ""
+"rk.show.question" <- function (message, caption = "Question", button.yes = "yes", button.no = "no", button.cancel = "cancel") {
+	res <- .Call ("rk.dialog", caption, message, button.yes, button.no, button.cancel)
+	if (res > 0) return (TRUE)
+	else if (res < 0) return (FALSE)
+	else return (NULL)	# cancelled
+}

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R	2010-09-02 06:22:11 UTC (rev 2987)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public_graphics.R	2010-09-02 17:02:26 UTC (rev 2988)
@@ -521,7 +521,7 @@
 	showPlotInfo <- function (deviceId = dev.cur ())
 	{
 		## TODO: update to either a proper message box, or move to a 'status bar'
-		system (paste ("kdialog --msgbox \"", .get.plot.info.str (deviceId), "\" --title \"Plot properties\" --icon rkward", sep = ""), wait = FALSE)
+		rk.show.message (.get.plot.info.str (deviceId), caption = "Plot properties")
 	}
 	.verify.hist.limits <- function ()
 	{


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list