[rkward-cvs] SF.net SVN: rkward-code:[4508] trunk/rkward
tfry at users.sf.net
tfry at users.sf.net
Sat Jan 26 20:44:36 UTC 2013
Revision: 4508
http://sourceforge.net/p/rkward/code/4508
Author: tfry
Date: 2013-01-26 20:44:35 +0000 (Sat, 26 Jan 2013)
Log Message:
-----------
Show pluginmap about info and dependencies in pluginmap selection widget
Modified Paths:
--------------
trunk/rkward/ChangeLog
trunk/rkward/rkward/plugin/rkcomponentmap.h
trunk/rkward/rkward/plugin/rkcomponentmeta.cpp
trunk/rkward/rkward/plugin/rkcomponentmeta.h
trunk/rkward/rkward/settings/rksettingsmoduleplugins.cpp
trunk/rkward/rkward/settings/rksettingsmoduleplugins.h
Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/ChangeLog 2013-01-26 20:44:35 UTC (rev 4508)
@@ -1,12 +1,13 @@
-- Easier activation / de-activation of RKWard plugin maps using checkboxes (Settings->Configure RKWard->Plugins)
+- Add guard against accidental usage of the standard distributed pluginmaps in a later version of RKWard (installed in parallel)
+- Easier (de-)activation of RKWard plugin maps using checkboxes (Settings->Configure RKWard->Plugins)
- Broken or quirky .pluginmap files are reported to the user, and disables completely broken maps, automatically
- Implement basic dependency handling for plugins / pluginmaps
- NOTES: Contrary to existing documentation, <dependencies> is a top level element, not a child element of <about>
- TODO:
- Provide more info (particularly about data) in selection UI
- - Add version barrier to standard pluginmap files to avoid accidental version mixup
- Explicitly document the fact that <include>s can be used for <about> and <dependencies>
- Add possibilities for soft dependencies (i.e. dynamic version check within a plugin)
+ - Think about means for cross-package pluginmap includes
- Added support for the upcoming R 3.0.0 TODO: Check for any more regressions, before release
- Added <switch> logic element to switch between several target properties (or fixed values) based on the value of a condition property
- Sort plugin gains option to sort data.frames by more than one column at a time, and options for type conversion TODO: adjust test(s)
Modified: trunk/rkward/rkward/plugin/rkcomponentmap.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.h 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.h 2013-01-26 20:44:35 UTC (rev 4508)
@@ -45,6 +45,7 @@
#include <qobject.h>
#include <QPair>
#include <QMap>
+#include <QHash>
class RKComponent;
class RKComponentMap;
Modified: trunk/rkward/rkward/plugin/rkcomponentmeta.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmeta.cpp 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/rkward/plugin/rkcomponentmeta.cpp 2013-01-26 20:44:35 UTC (rev 4508)
@@ -20,6 +20,8 @@
#include "../misc/xmlhelper.h"
#include "../rbackend/rksessionvars.h"
+#include <klocale.h>
+
#include "../debug.h"
QLatin1String rkward_min_version_tag ("rkward_min_version");
@@ -31,33 +33,64 @@
RKComponentAboutData::RKComponentAboutData (const QDomElement& e) {
RK_TRACE (PLUGIN);
+ if (e.isNull ()) return;
XMLHelper *xml = XMLHelper::getStaticHelper ();
- QString name = xml->getStringAttribute (e, "name", QString (), DL_ERROR);
- about = new KAboutData (name.toLocal8Bit (), QByteArray (), ki18n ("%1").subs (name), xml->getStringAttribute (e, "version", QString (), DL_WARNING).toLocal8Bit ());
- about->setShortDescription (ki18n ("%1").subs (xml->getStringAttribute (e, "shortinfo", QString (), DL_WARNING)));
- about->setCopyrightStatement (ki18n ("%1").subs (xml->getStringAttribute (e, "copyright", QString (), DL_WARNING)));
- about->setLicenseText (ki18n ("%1").subs (xml->getStringAttribute (e, "license", QString (), DL_WARNING)));
- about->setHomepage (xml->getStringAttribute (e, "url", QString (), DL_WARNING).toLocal8Bit ());
- // NOTE: Misusing catalog name for storing category.
+ name = xml->getStringAttribute (e, "name", QString (), DL_INFO);
+ version = xml->getStringAttribute (e, "version", QString (), DL_INFO);
+ releasedate = xml->getStringAttribute (e, "releasedate", QString (), DL_INFO);
+ shortinfo = xml->getStringAttribute (e, "shortinfo", QString (), DL_INFO);
+ copyright = xml->getStringAttribute (e, "copyright", QString (), DL_INFO);
+ license = xml->getStringAttribute (e, "license", QString (), DL_INFO);
+ url = xml->getStringAttribute (e, "url", QString (), DL_INFO);
category = xml->getStringAttribute (e, "category", i18n ("Unspecified"), DL_INFO);
- // NOTE: ignoring releasedate for now.
- XMLChildList authors = xml->getChildElements (e, "author", DL_INFO);
- for (int i = 0; i < authors.size (); ++i) {
- QDomElement author = authors[i];
- about->addAuthor (ki18n ("%1").subs (xml->getStringAttribute (author, "given", QString (), DL_ERROR) + " " + xml->getStringAttribute (e, "family", QString (), DL_ERROR)),
- ki18n ("%1").subs (xml->getStringAttribute (author, "role", QString (), DL_INFO)), // TODO: translate into human readable
- xml->getStringAttribute (author, "email", QString (), DL_WARNING).toLocal8Bit (),
- xml->getStringAttribute (author, "url", QString (), DL_INFO).toLocal8Bit ()
- );
+ XMLChildList aes = xml->getChildElements (e, "author", DL_INFO);
+ for (int i = 0; i < aes.size (); ++i) {
+ QDomElement ae = aes[i];
+ RKComponentAuthor author;
+ author.name = xml->getStringAttribute (ae, "name", QString (), DL_INFO);
+ if (author.name.isEmpty ()) {
+ author.name = xml->getStringAttribute (ae, "given", QString (), DL_WARNING) + " " + xml->getStringAttribute (ae, "family", QString (), DL_WARNING);
+
+ }
+ if (author.name.isEmpty ()) xml->displayError (&ae, "No author name specified", DL_WARNING);
+ author.roles = xml->getStringAttribute (ae, "role", QString (), DL_INFO);
+ author.email = xml->getStringAttribute (ae, "email", QString (), DL_WARNING);
+ author.url = xml->getStringAttribute (ae, "url", QString (), DL_INFO);
+ authors.append (author);
}
}
-RKComponentAboutData::~RKComponentAboutData() {
+RKComponentAboutData::~RKComponentAboutData () {
RK_TRACE (PLUGIN);
+}
- delete about;
+QString RKComponentAboutData::toHtml () const {
+ RK_TRACE (PLUGIN);
+
+ QString ret = "<p><b>" + name + "</b>";
+ if (!version.isEmpty ()) ret.append (" " + version);
+ if (!releasedate.isEmpty ()) ret.append (" (" + releasedate + ")");
+ if (!shortinfo.isEmpty ()) ret.append (":</p>\n<p>" + shortinfo);
+ ret.append ("</p>\n");
+ if (!url.isEmpty ()) ret.append ("URL: <a href=\"" + url + "\">" + url + "</a></p>\n<p>");
+ if (!copyright.isEmpty ()) ret.append (i18n ("Copyright (c)") + ": " + copyright + "</p>\n<p>");
+ if (!license.isEmpty ()) ret.append (i18n ("License") + ": " + license + "</p>\n<p>");
+
+ if (!authors.isEmpty ()) {
+ ret.append ("<b>" + i18n ("Authors:") + "</b></p>\n<p><ul>");
+ for (int i = 0; i < authors.size (); ++i) {
+ RKComponentAuthor a = authors[i];
+ ret.append ("<li>" + a.name);
+ if (!a.email.isEmpty ()) ret.append (" (" + a.email + ")");
+ if (!a.url.isEmpty ()) ret.append (" (" + a.url + ")");
+ if (!a.roles.isEmpty ()) ret.append ("<br/><i>" + i18nc ("Author roles (contributor, etc.)", "Roles") + "</i>: " + a.roles);
+ }
+ ret.append ("</ul>");
+ }
+ ret.append ("</p>");
+ return ret;
}
@@ -77,8 +110,9 @@
QList <RKComponentDependency> RKComponentDependency::parseDependencies (const QDomElement& e) {
RK_TRACE (PLUGIN);
+ QList<RKComponentDependency> ret;
+ if (e.isNull ()) return ret;
XMLHelper *xml = XMLHelper::getStaticHelper ();
- QList<RKComponentDependency> ret;
RKComponentDependency dep;
// Check for R dependency, first.
@@ -92,14 +126,15 @@
QDomElement dep_e = deps[i];
if (dep_e.tagName () == "package") {
dep.type = RKComponentDependency::RPackage;
- dep.package = xml->getStringAttribute (e, "repository", QString (), DL_INFO);
+ dep.source_info = xml->getStringAttribute (e, "repository", QString (), DL_INFO);
} else if (dep_e.tagName () == "pluginmap") {
dep.type = RKComponentDependency::RKWardPluginmap;
- dep.package = xml->getStringAttribute (e, "url", QString ("http://rkward.sf.net"), DL_WARNING);
+ dep.source_info = xml->getStringAttribute (e, "url", QString ("http://rkward.sf.net"), DL_WARNING);
} else {
RK_DEBUG (PLUGIN, DL_ERROR, "Tag <%s> is not allowed, here.", qPrintable (dep_e.tagName ()));
continue;
}
+ dep.package = xml->getStringAttribute (e, "name", QString (), DL_INFO);
dep.min_version = 0;
dep.max_version = 0xFFFFFFFF;
@@ -113,6 +148,7 @@
dep.type = RKComponentDependency::RKWardVersion;
dep.min_version = 0;
dep.max_version = 0xFFFFFFFF;
+ dep.source_info.clear ();
// Although we ignore it, here, RKWard dependencies may come with a non-numeric suffix
QString suffix_dummy;
if (e.hasAttribute (rkward_min_version_tag)) dep.min_version = RKSessionVars::parseVersionString (e.attribute (rkward_min_version_tag), &suffix_dummy);
@@ -121,3 +157,42 @@
return ret;
}
+
+QString numericVersionToString (quint32 numeric) {
+ QString ret;
+ for (int i = 3; i >= 0; --i) {
+ int ver_part = (numeric >> (i * 8)) & 0x000000FF;
+ ret.append (QString::number (ver_part));
+ if (i > 0) ret.append ('.');
+ }
+ return ret;
+}
+
+QString RKComponentDependency::depsToHtml (const QList <RKComponentDependency>& deps) {
+ RK_TRACE (PLUGIN);
+
+ QString ret;
+ if (deps.isEmpty ()) return ret;
+
+ ret.append ("<ul>");
+ for (int i = 0; i < deps.size (); ++i) {
+ ret.append ("<li>");
+ const RKComponentDependency &dep = deps[i];
+ if (dep.type == RBaseInstallation) {
+ ret.append ("R");
+ } else if (dep.type == RKWardVersion) {
+ ret.append ("RKWard");
+ } else {
+ if (dep.type == RKWardPluginmap) ret.append (i18n ("RKWard plugin map"));
+ else ret.append (i18n ("R package"));
+ ret.append ("\"" + dep.package + "\"");
+ if (!dep.source_info.isEmpty ()) ret.append (" (" + dep.source_info + ")");
+ }
+ if (dep.min_version > 0) ret.append (" >= " + numericVersionToString (dep.min_version));
+ if (dep.max_version < 0xFFFFFFFF) ret.append (" <= " + numericVersionToString (dep.max_version));
+ ret.append ("</li>");
+ }
+ ret.append ("</ul>");
+ return ret;
+}
+
Modified: trunk/rkward/rkward/plugin/rkcomponentmeta.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmeta.h 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/rkward/plugin/rkcomponentmeta.h 2013-01-26 20:44:35 UTC (rev 4508)
@@ -19,10 +19,12 @@
#define RKCOMPONENTMETA_H
#include <QDomElement>
-#include <kaboutdata.h>
+#include <QList>
struct RKComponentDependency {
RKComponentDependency () : type (RBaseInstallation), min_version (0), max_version (0xFFFFFFFF) {};
+ QString toHtml () const;
+ static QString depsToHtml (const QList<RKComponentDependency> &deps);
enum DependencyType {
RBaseInstallation,
RPackage,
@@ -39,12 +41,28 @@
static bool isRKWardVersionCompatible (const QDomElement &e);
};
+struct RKComponentAuthor {
+ QString name;
+ QString email;
+ QString url;
+ QString roles;
+};
+
class RKComponentAboutData {
public:
RKComponentAboutData (const QDomElement &e);
~RKComponentAboutData ();
- KAboutData *about;
+ QString toHtml () const;
+
+ QString name;
+ QString version;
+ QString releasedate;
+ QString shortinfo;
+ QString copyright;
+ QString license;
+ QString url;
QString category;
+ QList<RKComponentAuthor> authors;
};
#endif
Modified: trunk/rkward/rkward/settings/rksettingsmoduleplugins.cpp
===================================================================
--- trunk/rkward/rkward/settings/rksettingsmoduleplugins.cpp 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/rkward/settings/rksettingsmoduleplugins.cpp 2013-01-26 20:44:35 UTC (rev 4508)
@@ -40,6 +40,7 @@
#include "../misc/multistringselector.h"
#include "../misc/rkcommonfunctions.h"
#include "../misc/rkspinbox.h"
+#include "../misc/xmlhelper.h"
#include "../plugin/rkcomponentmap.h"
#include "rksettingsmodulegeneral.h"
@@ -421,6 +422,9 @@
RKSettingsModulePluginsModel::~RKSettingsModulePluginsModel() {
RK_TRACE (SETTINGS);
+ foreach (const PluginMapMetaInfo &inf, plugin_map_dynamic_info) {
+ delete (inf.about);
+ }
}
void RKSettingsModulePluginsModel::init (const RKSettingsModulePlugins::PluginMapList& known_plugin_maps) {
@@ -456,6 +460,15 @@
if (role == Qt::BackgroundRole) {
if (inf.broken_in_this_version) return Qt::red;
if (inf.quirky_in_this_version) return Qt::yellow;
+ return (QVariant ());
+ } else if (role == Qt::ToolTipRole) {
+ const PluginMapMetaInfo &meta = const_cast<RKSettingsModulePluginsModel*> (this)->getPluginMapMetaInfo (inf.filename);
+ QString desc = meta.about->toHtml ();
+ if (!meta.dependencies.isEmpty ()) {
+ desc.append ("<b>" + i18n ("Dependencies") + "</b>");
+ desc.append (RKComponentDependency::depsToHtml (meta.dependencies));
+ }
+ return desc;
}
if (col == COLUMN_CHECKED) {
@@ -563,6 +576,10 @@
if (!plugin_map_dynamic_info.contains (pluginmapfile)) {
// TODO
PluginMapMetaInfo inf;
+ XMLHelper *xml = XMLHelper::getStaticHelper ();
+ QDomElement doc_elem = xml->openXMLFile (pluginmapfile, DL_WARNING);
+ inf.about = new RKComponentAboutData (xml->getChildElement (doc_elem, "about", DL_INFO));
+ inf.dependencies = RKComponentDependency::parseDependencies (xml->getChildElement (doc_elem, "dependencies", DL_INFO));
plugin_map_dynamic_info.insert (pluginmapfile, inf);
}
Modified: trunk/rkward/rkward/settings/rksettingsmoduleplugins.h
===================================================================
--- trunk/rkward/rkward/settings/rksettingsmoduleplugins.h 2013-01-26 20:43:19 UTC (rev 4507)
+++ trunk/rkward/rkward/settings/rksettingsmoduleplugins.h 2013-01-26 20:44:35 UTC (rev 4508)
@@ -115,7 +115,6 @@
struct PluginMapMetaInfo {
RKComponentAboutData *about;
QList<RKComponentDependency> dependencies;
- bool loaded;
};
QHash<QString, PluginMapMetaInfo> plugin_map_dynamic_info;
const PluginMapMetaInfo &getPluginMapMetaInfo (const QString &pluginmapfile);
More information about the rkward-tracker
mailing list