[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