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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Sat Apr 23 10:33:22 UTC 2011


Revision: 3521
          http://rkward.svn.sourceforge.net/rkward/?rev=3521&view=rev
Author:   tfry
Date:     2011-04-23 10:33:22 +0000 (Sat, 23 Apr 2011)

Log Message:
-----------
Add a function rk.sessionInfo() to gather basic info on the setup. Also use this in Help->Report Bug...

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/main.cpp
    trunk/rkward/rkward/misc/rkprogresscontrol.cpp
    trunk/rkward/rkward/misc/rkprogresscontrol.h
    trunk/rkward/rkward/rbackend/rinterface.cpp
    trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkrbackend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
    trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R
    trunk/rkward/rkward/resource.ver
    trunk/rkward/rkward/rkward.cpp
    trunk/rkward/rkward/version.h
    trunk/rkward/rkward/windows/rktoplevelwindowgui.cpp
    trunk/rkward/scripts/set_dist_version.sh

Added Paths:
-----------
    trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.sessionInfo.Rd

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/ChangeLog	2011-04-23 10:33:22 UTC (rev 3521)
@@ -1,3 +1,4 @@
+- Provide a template for bug reports, containing standardized information on the RKWard setup in Help->Report Bug...
 - When loading a (local) workspace, change the working directory to the directory of the workspace (configurable)
 - Include the sidebar position of tool windows when saving / restoring the workplace layout
 - "Pending jobs" tool window is not longer shown in the bottom sidebar by default

Modified: trunk/rkward/rkward/main.cpp
===================================================================
--- trunk/rkward/rkward/main.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/main.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -107,7 +107,7 @@
 	options.add ("debugger <command>", ki18n ("Debugger (enclose any debugger arguments in single quotes ('') together with the command)"), "");
 	options.add ("+[File]", ki18n ("R workspace file to open"), 0);
 
-	KAboutData aboutData("rkward", QByteArray (), ki18n ("RKWard"), VERSION, ki18n ("Frontend to the R statistics language"), KAboutData::License_GPL, ki18n ("(c) 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010"), KLocalizedString (), "http://rkward.sf.net", "rkward-devel at lists.sourceforge.net");
+	KAboutData aboutData("rkward", QByteArray (), ki18n ("RKWard"), RKWARD_VERSION, ki18n ("Frontend to the R statistics language"), KAboutData::License_GPL, ki18n ("(c) 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010"), KLocalizedString (), "http://rkward.sf.net", "rkward-devel at lists.sourceforge.net");
 	aboutData.addAuthor (ki18n ("%1").subs ("Thomas Friedrichsmeier"), ki18n ("Project leader / main developer"));
 	aboutData.addAuthor (ki18n ("%1").subs ("Pierre Ecochard"), ki18n ("C++ coder since 0.2.9"));
 	aboutData.addAuthor (ki18n ("%1").subs ("Stefan Roediger"), ki18n ("Many plugins, suggestions, marketing, translations"));

Modified: trunk/rkward/rkward/misc/rkprogresscontrol.cpp
===================================================================
--- trunk/rkward/rkward/misc/rkprogresscontrol.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/misc/rkprogresscontrol.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -185,7 +185,13 @@
 	if (command == done_command) done ();
 }
 
+QString RKProgressControl::fullCommandOutput() {
+	RK_TRACE (MISC);
 
+	QString ret;
+	foreach (ROutput out, output_log) ret.append (out.output);
+	return ret;
+}
 
 //////////////////////////// RKProgressControlDialog ///////////////////////////////////////////7
 

Modified: trunk/rkward/rkward/misc/rkprogresscontrol.h
===================================================================
--- trunk/rkward/rkward/misc/rkprogresscontrol.h	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/misc/rkprogresscontrol.h	2011-04-23 10:33:22 UTC (rev 3521)
@@ -64,7 +64,8 @@
 		StandardError=IncludeErrorOutput | RaiseOnError | OutputShownByDefault,
 		DetailedError=StandardError | IncludeRegularOutput,
 		StandardProgress=DetailedError | OutputSwitchable | RaiseOnRegularOutput,
-		CancellableProgress=(StandardProgress | AllowCancel | AutoCancelCommands | PreventClose | ShowAtOnce) - (RaiseOnRegularOutput | OutputShownByDefault)
+		CancellableProgress=(StandardProgress | AllowCancel | AutoCancelCommands | PreventClose | ShowAtOnce) - (RaiseOnRegularOutput | OutputShownByDefault),
+		CancellableNoProgress=CancellableProgress - OutputSwitchable
 	};
 
 /** show the dialog modal. This will always show the dialog right away
@@ -78,6 +79,7 @@
 /** add a command to listen to. Warning: You will always first call addRCommand, then submit the command to RInterface, never the other way around. Else there could be a race condition!
 @param done_when_finished If set to true, the done () -slot is auto-called when the given command has completed */
 	void addRCommand (RCommand *command, bool done_when_finished=false);
+	QString fullCommandOutput ();
 signals:
 	void cancelled ();
 public slots:

Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -25,6 +25,7 @@
 #include "../settings/rksettingsmodulegeneral.h"
 #include "../settings/rksettingsmoduleoutput.h"
 #include "../settings/rksettingsmodulegraphics.h"
+#include "../settings/rksettingsmoduledebug.h"
 #include "../core/robjectlist.h"
 #include "../core/renvironmentobject.h"
 #include "../core/rkmodificationtracker.h"
@@ -48,11 +49,13 @@
 #endif // DISABLE_RKWINDOWCATCHER
 
 #include "../rkglobals.h"
+#include "../version.h"
 #include "../debug.h"
 
 #include <kmessagebox.h>
 #include <kfiledialog.h>
 #include <klocale.h>
+#include <ktemporaryfile.h>
 
 #include <qdir.h>
 #include <qtimer.h>
@@ -635,6 +638,20 @@
 			for (int i = 0; i < list.size (); ++i) list[i] = RObject::rQuote (list[i]);
 			issueCommand (".rk.set.reply (c (" + list.join (", ") + "))", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 		}
+	} else if (call == "getSessionInfo") {
+		// Non-translatable on purpose. This is meant for posting to the bug tracker, mostly.
+		QStringList lines;
+		lines.append ("RKWard version: " RKWARD_VERSION);
+		lines.append ("KDE version (runtime): " + QString (KDE::versionString ()));
+		lines.append ("KDE version (compile time): " KDE_VERSION_STRING);
+		lines.append (QString());
+		lines.append ("Debug message file(s) in use (these may contain relevant diagnostic output in case of trouble):");
+		lines.append (RKSettingsModuleDebug::debug_file->fileName ());
+		lines.append (calllist.value (1));
+		lines.append (QString ());
+		lines.append ("R version (compile time): " + calllist.value (2));
+		for (int i = 0; i < lines.size (); ++i) lines[i] = RObject::rQuote (lines[i]);
+		issueCommand (".rk.set.reply (c (" + lines.join (",\n") + "))", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 	} else {
 		issueCommand ("stop (\"Unrecognized call '" + call + "'. Ignoring\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 	}

Modified: trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -61,7 +61,7 @@
 	// handshake
 	connection->write (token.toLocal8Bit ().data ());
 	connection->write ("\n");
-	connection->write (VERSION);
+	connection->write (RKWARD_VERSION);
 	connection->write ("\n");
 
 	QTimer* flush_timer = new QTimer (this);

Modified: trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -105,7 +105,7 @@
 	if (!con->canReadLine ()) con->waitForReadyRead (1000);
 	QString version_c = QString::fromLocal8Bit (con->readLine ());
 	version_c.chop (1);
-	if (version_c != VERSION) handleTransmissionError (i18n ("Version mismatch during handshake with backend process. Frontend is version '%1' while backend is '%2'.\nPlease fix your installation.").arg (VERSION).arg (version_c));
+	if (version_c != RKWARD_VERSION) handleTransmissionError (i18n ("Version mismatch during handshake with backend process. Frontend is version '%1' while backend is '%2'.\nPlease fix your installation.").arg (RKWARD_VERSION).arg (version_c));
 
 	setConnection (con);
 }

Modified: trunk/rkward/rkward/rbackend/rkrbackend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rkrbackend.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -74,6 +74,7 @@
 #include <R_ext/eventloop.h>
 #include <R_ext/Callbacks.h>
 #include <R.h>
+#include <Rversion.h>
 #include <Rinternals.h>
 #include <R_ext/Parse.h>
 #include <Rembedded.h>
@@ -1291,7 +1292,14 @@
 	RK_TRACE (RBACKEND);
 
 	RBackendRequest request (true, RBackendRequest::HistoricalSubstackRequest);
-	request.params["call"] = list;
+	if (list.value (0) == "getSessionInfo") {
+		QStringList dummy = list;
+		dummy.append (RKRBackendProtocolBackend::backendDebugFile ());
+		dummy.append (R_MAJOR "." R_MINOR " " R_STATUS " (" R_YEAR "-" R_MONTH "-" R_DAY " r" R_SVN_REVISION ")");
+		request.params["call"] = dummy;
+	} else {
+		request.params["call"] = list;
+	}
 	handleRequest (&request);
 }
 
@@ -1307,7 +1315,7 @@
 	bool lib_load_fail = false;
 	bool sink_fail = false;
 	if (!runDirectCommand ("library (\"rkward\")\n")) lib_load_fail = true;
-	if (!runDirectCommand (QString ("stopifnot(.rk.app.version==\"%1\")\n").arg (VERSION))) lib_load_fail = true;
+	if (!runDirectCommand (QString ("stopifnot(.rk.app.version==\"%1\")\n").arg (RKWARD_VERSION))) lib_load_fail = true;
 	if (!runDirectCommand (".rk.fix.assignments ()\n")) sink_fail = true;
 
 // error/output sink and help browser

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -202,3 +202,11 @@
 	static_cast<RKRBackendTransmitter*> (RKRBackendTransmitter::instance ())->publicmsleep (delay);
 #endif
 }
+
+QString RKRBackendProtocolBackend::backendDebugFile () {
+#ifdef RKWARD_THREADED
+	return (QString ());
+#else
+	return RK_Debug_File->fileName ();
+#endif
+}

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2011-04-23 10:33:22 UTC (rev 3521)
@@ -26,6 +26,7 @@
 public:
 	static bool inRThread ();
 	static QString dataDir () { return _instance->data_dir; };
+	static QString backendDebugFile ();
 
 	RKRBackendProtocolBackend (const QString &data_dir);
 	~RKRBackendProtocolBackend ();

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION	2011-04-23 10:33:22 UTC (rev 3521)
@@ -1,6 +1,6 @@
 Package: rkward
 Title: Provides some helper functions for the RKWard frontend
-Version: 0.5.5
+Version: 0.5.6
 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/public.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2011-04-23 10:33:22 UTC (rev 3521)
@@ -471,3 +471,8 @@
 	else return (NULL)	# cancelled
 }
 
+"rk.sessionInfo" <- function () {
+	cat (.rk.do.call ("getSessionInfo"), sep="\n")
+	cat ("R runtime session info:\n")
+	print (sessionInfo())
+}

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R	2011-04-23 10:33:22 UTC (rev 3521)
@@ -1 +1 @@
-".rk.app.version" <- "0.5.5.z+0.5.6+test2"
+".rk.app.version" <- "0.5.5.z+0.5.6+test3"

Added: trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.sessionInfo.Rd
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.sessionInfo.Rd	                        (rev 0)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.sessionInfo.Rd	2011-04-23 10:33:22 UTC (rev 3521)
@@ -0,0 +1,34 @@
+\name{rk.sessionInfo}
+\alias{rk.sessionInfo}
+
+\title{Print information on the RKWard session}
+
+\usage{
+rk.sessionInfo()
+}
+
+\arguments{
+}
+
+\details{
+Gathers and prints information on the setup of the current RKWard session. In general, you should always include this information when reporting a bug in RKWard.
+
+Typically, when reporting a bug, you should use \code{Help->Report Bug...} from the menu. Internally, this will call \code{rk.sessionInfo()}.
+}
+
+\value{
+Returns the object created by \code{sessionInfo()}, invisibly. Note that this includes only the information on the R portion of the session.
+}
+
+\author{Thomas Friedrichsmeier \email{rkward-devel at lists.sourceforge.net}}
+
+\seealso{
+\code{\link{sessionInfo}}
+}
+
+\examples{
+rk.sessionInfo()
+}
+
+\keyword{utilities}
+\keyword{misc}

Modified: trunk/rkward/rkward/resource.ver
===================================================================
--- trunk/rkward/rkward/resource.ver	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/resource.ver	2011-04-23 10:33:22 UTC (rev 3521)
@@ -1 +1 @@
-0.5.5.z+0.5.6+test2
+0.5.5.z+0.5.6+test3

Modified: trunk/rkward/rkward/rkward.cpp
===================================================================
--- trunk/rkward/rkward/rkward.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/rkward.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -192,7 +192,7 @@
 
 	// Check installation first
 	QFile resource_ver (RKCommonFunctions::getRKWardDataDir () + "resource.ver");
-	if (!(resource_ver.open (QIODevice::ReadOnly) && (resource_ver.read (100).trimmed () == VERSION))) {
+	if (!(resource_ver.open (QIODevice::ReadOnly) && (resource_ver.read (100).trimmed () == RKWARD_VERSION))) {
 		KMessageBox::error (this, i18n ("<p>RKWard either could not find its resource files at all, or only an old version of those files. The most likely cause is that the last installation failed to place the files in the correct place. This can lead to all sorts of problems, from single missing features to complete failure to function.</p><p><b>You should quit RKWard, now, and fix your installation</b>. For help with that, see <a href=\"http://p.sf.net/rkward/compiling\">http://p.sf.net/rkward/compiling</a>.</p>"), i18n ("Broken installation"), KMessageBox::Notify | KMessageBox::AllowLink);
 	}
 

Modified: trunk/rkward/rkward/version.h
===================================================================
--- trunk/rkward/rkward/version.h	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/version.h	2011-04-23 10:33:22 UTC (rev 3521)
@@ -1,2 +1,2 @@
 /* Version number of package */
-#define VERSION "0.5.5.z+0.5.6+test2"
+#define RKWARD_VERSION "0.5.5.z+0.5.6+test3"

Modified: trunk/rkward/rkward/windows/rktoplevelwindowgui.cpp
===================================================================
--- trunk/rkward/rkward/windows/rktoplevelwindowgui.cpp	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/rkward/windows/rktoplevelwindowgui.cpp	2011-04-23 10:33:22 UTC (rev 3521)
@@ -38,6 +38,7 @@
 #include "../windows/rkhelpsearchwindow.h"
 #include "../windows/rkmdiwindow.h"
 #include "../misc/rkstandardicons.h"
+#include "../misc/rkprogresscontrol.h"
 #include "../plugin/rkcomponentmap.h"
 #include "../rbackend/rinterface.h"
 #include "../rkglobals.h"
@@ -131,10 +132,40 @@
 void RKTopLevelWindowGUI::reportRKWardBug () {
 	RK_TRACE (APP);
 
-// TOOD: something pretty
-	KMessageBox::information (for_window, i18n ("<p>Please submit your bug reports or wishes at <a href=\"%1\">%1</a> or send email to <a href=\"mailto:%2\">%2</a>.</p>"
-							, QString ("http://sourceforge.net/tracker/?group_id=50231&atid=459007"), QString ("rkward-devel at lists.sourceforge.net")),
-							i18n ("Reporting bugs in RKWard"), QString (), KMessageBox::Notify | KMessageBox::AllowLink);
+	QString report_template = i18n ("---Problem description---\n");
+	report_template.append (i18n ("Please give a brief summary on the problem:\n###Please fill in###\n\n"));
+	report_template.append (i18n ("What - in detail - did you do directly before you encountered this problem?\n###Please fill in###\n\n"));
+	report_template.append (i18n ("When you try to repeat the above, does the problem occur again (no, sometimes, always)?\n###Please fill in###\n\n"));
+	report_template.append (i18n ("If applicable: When doing the same thing in an R session outside of RKWard, do you see the same problem?\n###Please fill in###\n\n"));
+	report_template.append (i18n ("Do you have any further information that might help us to track this problem down? In particular, if applicable, can you provide sample data and sample R code to reproduce this problem?\n###Please fill in###\n\n"));
+
+	RCommand *command = new RCommand ("rk.sessionInfo()", RCommand::App);
+	RKProgressControl *control = new RKProgressControl (this, i18n ("Please stand by while gathering some information on your setup.\nIn case the backend has died or hung up, you may want to press 'Cancel' to skip this step."), i18n ("Gathering setup information"), RKProgressControl::CancellableNoProgress);
+	control->addRCommand (command, true);
+	RKGlobals::rInterface ()->issueCommand (command);
+	bool ok = control->doModal (false);
+
+	report_template.append ("---Session Info---\n");
+	report_template.append (control->fullCommandOutput ());
+	if (!ok) report_template.append ("- not available -");
+	delete control;
+
+	KDialog *dialog = new KDialog (for_window);
+	connect (dialog, SIGNAL (finished(int)), dialog, SLOT (deleteLater()));
+	dialog->setCaption (i18n ("Reporting bugs in RKWard"));
+	dialog->setButtons (KDialog::Ok);
+	KVBox *vbox = new KVBox (dialog);
+	dialog->setMainWidget (vbox);
+	QLabel *label = new QLabel (i18n ("<p><b>Where should I report bugs or wishes?</b></p><p>Please submit your bug reports or wishes at <a href=\"%1\">%1</a> or send email to <a href=\"mailto:%2\">%2</a>.</p>"
+							"<p><b>What information should I provide?</b></p><p>Please copy the information shown below, and fill in the details to the questions.</p>"
+							, QString ("http://sourceforge.net/tracker/?group_id=50231&atid=459007"), QString ("rkward-devel at lists.sourceforge.net")), vbox);
+	label->setWordWrap (true);
+	label->setOpenExternalLinks (true);
+	QTextEdit *details = new QTextEdit (vbox);
+	details->setReadOnly (true);
+	details->setText (report_template);
+
+	dialog->show ();
 }
 
 void RKTopLevelWindowGUI::showAboutApplication () {

Modified: trunk/rkward/scripts/set_dist_version.sh
===================================================================
--- trunk/rkward/scripts/set_dist_version.sh	2011-04-22 12:24:58 UTC (rev 3520)
+++ trunk/rkward/scripts/set_dist_version.sh	2011-04-23 10:33:22 UTC (rev 3521)
@@ -8,6 +8,6 @@
 BASEDIR=`pwd`
 
 echo "/* Version number of package */" > $BASEDIR/rkward/version.h
-echo "#define VERSION \"$VERSION\"" >> $BASEDIR/rkward/version.h
+echo "#define RKWARD_VERSION \"$VERSION\"" >> $BASEDIR/rkward/version.h
 echo "\".rk.app.version\" <- \"$VERSION\"" > $BASEDIR/rkward/rbackend/rpackages/rkward/R/ver.R
 echo "$VERSION" > $BASEDIR/rkward/resource.ver


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