[rkward-cvs] SF.net SVN: rkward: [1792] trunk/rkward
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Mon Apr 9 13:45:38 UTC 2007
Revision: 1792
http://svn.sourceforge.net/rkward/?rev=1792&view=rev
Author: tfry
Date: 2007-04-09 06:45:38 -0700 (Mon, 09 Apr 2007)
Log Message:
-----------
Make messages, warnings, and errors from plugin commands go to the output, instead of showing them in a dialog.
Make sure output from sub-commands is also added to the commands higher up in the chain
Modified Paths:
--------------
trunk/rkward/ChangeLog
trunk/rkward/TODO
trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
trunk/rkward/rkward/plugin/rkstandardcomponentgui.h
trunk/rkward/rkward/plugins/plots/pareto.php
trunk/rkward/rkward/rbackend/rinterface.cpp
trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
trunk/rkward/rkward/rbackend/rthread.cpp
trunk/rkward/rkward/rbackend/rthread.h
Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/ChangeLog 2007-04-09 13:45:38 UTC (rev 1792)
@@ -1,3 +1,5 @@
+- Messages, warnings, and errors for plugin commands are shown in the output, instead of in a dialog
+
--- Version 0.4.7 - Apr-XX-2007
- some fixes for GCC 4.3
- fixed: the presence of user objects called "missing", "assign", or "get" would confuse some RKWard internals
Modified: trunk/rkward/TODO
===================================================================
--- trunk/rkward/TODO 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/TODO 2007-04-09 13:45:38 UTC (rev 1792)
@@ -12,6 +12,8 @@
- Find a solution for error handling in plugins
- Do not use a sink in plugins. Rather, all printing code should print to the output file. Everything else will be added below the output.
- Separate plugin output by an <hr> or something (*after* a plugin has run, and *only if* it has produced some sort of output (or warnings/errors))
+ - if there is a substack command, warnings may get attached to the wrong command (as Rf_PrintWarnings() is called for the substack-command, before it is called for the main command)! What to do?! Something like current_toplevel_command? Will this always work, right? Probably not.
+ - Maybe keep a list of *all* still active commands, and append output to all of those
Advertizing:
- start being a bit bolder about RKWard (descriptions, startup notification, etc.)
Modified: trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2007-04-09 13:45:38 UTC (rev 1792)
@@ -32,7 +32,6 @@
#include "../windows/rkworkplace.h"
#include "../windows/rkcommandeditorwindow.h"
#include "../rbackend/rinterface.h"
-#include "../misc/rkerrordialog.h"
#include "../rkward.h"
#include "../settings/rksettingsmoduleplugins.h"
#include "../rkglobals.h"
@@ -45,9 +44,6 @@
toggle_code_button = 0;
- // create an error-dialog
- error_dialog = new RKRErrorDialog (i18n ("The R-backend has reported one or more error(s) while processing the plugin '%1'.\nThis may lead to an incorrect output and is likely due to a bug in the plugin.\nA transcript of the error message(s) is shown below.").arg (component->getFilename ()), i18n ("R-Error"), false);
-
RKStandardComponentGUI::component = component;
RKStandardComponentGUI::code_property = code_property;
connect (code_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (codeChanged (RKComponentPropertyBase *)));
@@ -67,8 +63,6 @@
RKStandardComponentGUI::~RKStandardComponentGUI () {
RK_TRACE (PLUGIN);
-
- delete error_dialog;
}
void RKStandardComponentGUI::createDialog (bool switchable) {
@@ -155,7 +149,7 @@
command.append (code_property->calculate ());
command.append (code_property->printout ());
command.append ("})\n");
- RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate, QString::null, error_dialog));
+ RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate));
}
void RKStandardComponentGUI::cancel () {
Modified: trunk/rkward/rkward/plugin/rkstandardcomponentgui.h
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponentgui.h 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/plugin/rkstandardcomponentgui.h 2007-04-09 13:45:38 UTC (rev 1792)
@@ -68,7 +68,6 @@
class QPushButton;
class QTimer;
class QSplitter;
-class RKRErrorDialog;
/** contains the standard GUI elements for a top-level RKStandardComponent. The base class creates a dialog interface. For a wizard interface use RKStandardComponentWizard. You *must* call createDialog () after construction, since I can't virualize this for reasons I don't understand!
@@ -105,7 +104,6 @@
void closeEvent (QCloseEvent *e);
RKStandardComponent *component;
QTimer *code_update_timer;
- RKRErrorDialog *error_dialog;
// common widgets
QWidget *main_widget;
Modified: trunk/rkward/rkward/plugins/plots/pareto.php
===================================================================
--- trunk/rkward/rkward/plugins/plots/pareto.php 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/plugins/plots/pareto.php 2007-04-09 13:45:38 UTC (rev 1792)
@@ -30,7 +30,7 @@
x <- <? echo ($vars); ?>
if (!is.numeric (x)) {
- rk.print ("Data may not be numeric, but proceeding as requested.\nDid you forget to check the tabulate option?")
+ warning ("Data may not be numeric, but proceeding as requested.\nDid you forget to check the tabulate option?")
}
<? } ?>
Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp 2007-04-09 13:45:38 UTC (rev 1792)
@@ -294,10 +294,6 @@
} else {
issueCommand (".rk.set.reply (\"Too few arguments in call to get.tempfile.name.\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, request->in_chain);
}
- } else if (call == "get.output.html.file") {
- QDir dir (RKSettingsModuleGeneral::filesPath ());
- // TODO: make more generic, get filename sanely
- issueCommand (".rk.set.reply (\"" + dir.filePath ("rk_out.html") + "\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, request->in_chain);
} else if (call == "sync") {
RK_ASSERT (request->call_length >= 2);
Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION 2007-04-09 13:45:38 UTC (rev 1792)
@@ -1,6 +1,6 @@
Package: rkward
Title: Provides some helper functions for the RKWard frontend
-Version: 0.4.7
+Version: 0.4.8
Author: Thomas Friedrichsmeier and the RKWard Team
Description: Most of the functions in here are really only needed for the internal communication between RKWard and R. There are also a few functions, which allow access to RKWard or RKWard specifics. Most is not implemented, yet.
Maintainer: RKWard-devel mailing list <rkward-devel at lists.sourceforge.net>
Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R 2007-04-09 13:45:38 UTC (rev 1792)
@@ -372,6 +372,8 @@
ret
}
+".rk.output.html.file" <- NULL
+
".rk.rkreply" <- NULL
".rk.set.reply" <- function (x) .rk.rkreply <<- x
@@ -422,3 +424,8 @@
.rk.do.call ("wdChange", NULL);
}
formals (setwd) <- formals (base::setwd)
+
+# hidden, as this is not portable to different output formats
+".rk.cat.output" <- function (x) {
+ cat (x, file = rk.get.output.html.file(), append = TRUE)
+}
Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R 2007-04-09 13:45:38 UTC (rev 1792)
@@ -104,9 +104,14 @@
}
"rk.get.output.html.file" <- function () {
- return (.rk.do.call ("get.output.html.file", ""))
+ return (.rk.output.html.file)
}
+"rk.set.output.html.file" <- function (x) {
+ stopifnot (is.character (x))
+ assign (".rk.output.html.file", x, as.environment ("package:rkward"))
+}
+
# renames a named object in a data.frame/list without changing it's position
# TODO: create a generic function instead, that can handle all kinds of renames
"rk.rename.in.container" <- function (x, old_name, new_name, envir=parent.frame()) {
@@ -144,6 +149,9 @@
}
"rk.header" <- function (title, parameters=list ()) {
+ sink (rk.get.output.html.file(), append=TRUE)
+ on.exit (sink ())
+
cat (paste ("<h1>", title, "</h1>\n", sep=""))
if (length (parameters)) {
cat ("<h2>Parameters</h2>\n<ul>")
@@ -160,6 +168,9 @@
}
"rk.results" <- function (x, titles=NULL) {
+ sink (rk.get.output.html.file(), append=TRUE)
+ on.exit (sink ())
+
if (is.list (x)) { # or a data.frame
if (is.null (titles)) {
titles <- names (x)
Modified: trunk/rkward/rkward/rbackend/rthread.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rthread.cpp 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rthread.cpp 2007-04-09 13:45:38 UTC (rev 1792)
@@ -149,6 +149,7 @@
// step 2: actual handling
if (!((command->type () & RCommand::EmptyCommand) || (command->status & RCommand::Canceled))) {
+ all_current_commands.append (command);
RKWardRError error;
int ctype = command->type ();
@@ -157,7 +158,8 @@
RK_DO (qDebug ("running command: %s", ccommand.latin1()), RBACKEND, DL_DEBUG);
if (command->type () & RCommand::DirectToOutput) {
- runCommandInternal (QString ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n").local8Bit (), &error);
+ runCommandInternal (".rk.cat.output (\"<hr>\\n\")", &error, false);
+ RK_ASSERT (!error);
}
MUTEX_UNLOCK;
@@ -205,10 +207,19 @@
} else {
command->status |= RCommand::WasTried;
}
-
- RKWardRError dummy;
+
+ flushOutput ();
if (command->type () & RCommand::DirectToOutput) {
- runCommandInternal ("sink ()\n", &dummy);
+ QString outp = command->fullOutput();
+
+ if (!outp.isEmpty ()) {
+ // all regular output was sink()ed, i.e. all remaining output is a message/warning/error
+ RKWardRError error;
+ runCommandInternal (".rk.cat.output (\"<h2>Messages, warnings, or errors:</h2>\\n\")", &error, false);
+ RK_ASSERT (!error);
+ runCommandInternal ("rk.print.literal (\"" + outp + "\")", &error, false);
+ RK_ASSERT (!error);
+ }
}
if (error) {
@@ -216,8 +227,7 @@
// runCommandInternal (".rk.init.handlers ()\n", &dummy);
}
RK_DO (qDebug ("done running command"), RBACKEND, DL_DEBUG);
-
- flushOutput ();
+ all_current_commands.pop_back();
} else {
if (command->type () & RCommand::QuitCommand) {
killed = true;
@@ -279,23 +289,32 @@
RK_TRACE (RBACKEND);
if (current_command) {
- current_command->output_list.append (current_output);
- if (current_output->type == ROutput::Output) {
- current_command->status |= RCommand::HasOutput;
- } else if (current_output->type == ROutput::Warning) {
- current_command->status |= RCommand::HasWarnings;
- } else if (current_output->type == ROutput::Error) {
- current_command->status |= RCommand::HasError;
+ for (QValueList<RCommand*>::const_iterator it = all_current_commands.constBegin (); it != all_current_commands.constEnd(); ++it) {
+ ROutput *output = current_output;
+ if ((*it) != current_command) { // this output belongs to several commands at once. So we need to copy it.
+ output = new ROutput;
+ output->type = current_output->type;
+ output->output = current_output->output;
+ }
+
+ (*it)->output_list.append (output);
+ if (output->type == ROutput::Output) {
+ (*it)->status |= RCommand::HasOutput;
+ } else if (output->type == ROutput::Warning) {
+ (*it)->status |= RCommand::HasWarnings;
+ } else if (output->type == ROutput::Error) {
+ (*it)->status |= RCommand::HasError;
+ }
+
+ // pass a signal to the main thread for real-time update of output
+ QCustomEvent *event = new QCustomEvent (RCOMMAND_OUTPUT_EVENT);
+ ROutputContainer *outc = new ROutputContainer;
+ outc->output = output;
+ outc->command = *it;
+ event->setData (outc);
+ qApp->postEvent (RKGlobals::rInterface (), event);
}
- // pass a signal to the main thread for real-time update of output
- QCustomEvent *event = new QCustomEvent (RCOMMAND_OUTPUT_EVENT);
- ROutputContainer *outc = new ROutputContainer;
- outc->output = current_output;
- outc->command = current_command;
- event->setData (outc);
- qApp->postEvent (RKGlobals::rInterface (), event);
-
RK_DO (qDebug ("output '%s'", current_output->output.latin1 ()), RBACKEND, DL_DEBUG);
} else {
// running Rcmdr, eh?
@@ -480,11 +499,11 @@
}
}
-// error sink and help browser
+// error/output sink and help browser
runCommandInternal ("options (error=quote (.rk.do.error ()))\n", &error);
if (error) status |= SinkFail;
-/* runCommandInternal (".rk.init.handlers ()\n", &error);
- if (error) status |= SinkFail; */
+ runCommandInternal ("rk.set.output.html.file (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\")\n", &error);
+ if (error) status |= SinkFail;
runCommandInternal ("options (htmlhelp=TRUE); options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")", &error);
if (error) status |= OtherFail;
// TODO: error-handling?
Modified: trunk/rkward/rkward/rbackend/rthread.h
===================================================================
--- trunk/rkward/rkward/rbackend/rthread.h 2007-04-05 16:28:37 UTC (rev 1791)
+++ trunk/rkward/rkward/rbackend/rthread.h 2007-04-09 13:45:38 UTC (rev 1792)
@@ -19,6 +19,7 @@
#include <qthread.h>
#include <qstringlist.h>
+#include <qvaluelist.h>
#include "rcommand.h"
#include "rcommandstack.h"
@@ -187,6 +188,7 @@
QStringList changed_symbol_names;
/** check wether the object list / global environment / individual symbols have changed, and updates them, if needed */
void checkObjectUpdatesNeeded (bool check_list);
+ QValueList<RCommand*> all_current_commands;
};
#endif
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