[rkward-cvs] SF.net SVN: rkward: [1086] trunk/rkward/rkward
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Mon Jan 8 00:52:30 UTC 2007
Revision: 1086
http://svn.sourceforge.net/rkward/?rev=1086&view=rev
Author: tfry
Date: 2007-01-07 16:52:29 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
First (incomplete) go at adding a help system
Modified Paths:
--------------
trunk/rkward/rkward/plugin/rkcomponentmap.cpp
trunk/rkward/rkward/plugin/rkcomponentmap.h
trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
trunk/rkward/rkward/plugin/rkstandardcomponent.h
trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.xml
trunk/rkward/rkward/windows/rkhtmlwindow.cpp
trunk/rkward/rkward/windows/rkhtmlwindow.h
Added Paths:
-----------
trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.rkh
Modified: trunk/rkward/rkward/plugin/rkcomponentmap.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.cpp 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.cpp 2007-01-08 00:52:29 UTC (rev 1086)
@@ -86,6 +86,26 @@
}
//static
+QString RKComponentMap::getComponentId (RKComponentHandle* by_component) {
+ RK_TRACE (PLUGIN);
+
+ return (getMap ()->getComponentIdLocal (by_component));
+}
+
+QString RKComponentMap::getComponentIdLocal (RKComponentHandle* component) {
+ RK_TRACE (PLUGIN);
+
+ for (ComponentMap::iterator it = components.begin (); it != components.end (); ++it) {
+ if (it.data () == component) {
+ return it.key ();
+ }
+ }
+
+ RK_ASSERT (false);
+ return (QString ());
+}
+
+//static
QDomElement RKComponentMap::findOrCreateElement (QDomElement& parent, const QString& tagname, const QString& name, const QString& label, int index) {
RK_TRACE (PLUGIN);
@@ -219,11 +239,12 @@
///########################### END RKComponentMap ###############################
///########################### BEGIN RKComponentHandle ############################
-RKComponentHandle::RKComponentHandle (const QString &filename, RKComponentType type) {
+RKComponentHandle::RKComponentHandle (const QString &filename, const QString &label, RKComponentType type) {
RK_TRACE (PLUGIN);
RKComponentHandle::type = type;
RKComponentHandle::filename = filename;
+ RKComponentHandle::label = label;
}
RKComponentHandle::~RKComponentHandle () {
@@ -233,7 +254,7 @@
//static
RKComponentHandle* RKComponentHandle::createComponentHandle (const QString &filename, RKComponentType type, const QString& id, const QString& label, RKComponentMap *map) {
if (type == (int) Standard) {
- RKStandardComponentHandle *ret = new RKStandardComponentHandle (filename, type);
+ RKStandardComponentHandle *ret = new RKStandardComponentHandle (filename, label, type);
new KAction (label, 0, ret, SLOT (activated ()), map->actionCollection (), id.latin1 ());
return (ret);
}
@@ -258,7 +279,7 @@
#include "rkstandardcomponent.h"
-RKStandardComponentHandle::RKStandardComponentHandle (const QString &filename, RKComponentType type) : QObject (RKWardMainWindow::getMain ()), RKComponentHandle (filename, type) {
+RKStandardComponentHandle::RKStandardComponentHandle (const QString &filename, const QString &label, RKComponentType type) : QObject (RKWardMainWindow::getMain ()), RKComponentHandle (filename, label, type) {
RK_TRACE (PLUGIN);
}
@@ -269,7 +290,7 @@
RKComponent *RKStandardComponentHandle::invoke (RKComponent *parent_component, QWidget *parent_widget) {
RK_TRACE (PLUGIN);
- return (new RKStandardComponent (parent_component, parent_widget, getFilename ()));
+ return (new RKStandardComponent (parent_component, parent_widget, getFilename (), this));
}
void RKStandardComponentHandle::activated () {
Modified: trunk/rkward/rkward/plugin/rkcomponentmap.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.h 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.h 2007-01-08 00:52:29 UTC (rev 1086)
@@ -34,11 +34,12 @@
*/
class RKComponentHandle {
public:
- RKComponentHandle (const QString &filename, RKComponentType type);
+ RKComponentHandle (const QString &filename, const QString &label, RKComponentType type);
virtual ~RKComponentHandle ();
QString getFilename () { return filename; };
+ QString getLabel () { return label; };
RKComponentType getType () { return type; };
bool isPlugin ();
@@ -48,6 +49,7 @@
private:
/** The filename of the description file for this component */
QString filename;
+ QString label;
RKComponentType type;
};
@@ -80,6 +82,7 @@
/** returns the component identified by id */
static RKComponentHandle* getComponentHandle (const QString &id);
+ static QString getComponentId (RKComponentHandle* by_component);
static RKComponentMap *getMap () { return component_map; };
static void initialize ();
private:
@@ -103,6 +106,7 @@
ComponentMap components;
RKComponentHandle* getComponentHandleLocal (const QString &id);
+ QString getComponentIdLocal (RKComponentHandle* component);
int addPluginMapLocal (const QString& plugin_map_file);
void clearLocal ();
@@ -118,7 +122,7 @@
class RKStandardComponentHandle : public QObject, public RKComponentHandle {
Q_OBJECT
public:
- RKStandardComponentHandle (const QString &filename, RKComponentType type);
+ RKStandardComponentHandle (const QString &filename, const QString &label, RKComponentType type);
~RKStandardComponentHandle ();
Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2007-01-08 00:52:29 UTC (rev 1086)
@@ -52,10 +52,11 @@
#include "../debug.h"
-RKStandardComponent::RKStandardComponent (RKComponent *parent_component, QWidget *parent_widget, const QString &filename) : RKComponent (parent_component, parent_widget) {
+RKStandardComponent::RKStandardComponent (RKComponent *parent_component, QWidget *parent_widget, const QString &filename, RKComponentHandle *handle) : RKComponent (parent_component, parent_widget) {
RK_TRACE (PLUGIN);
RKStandardComponent::filename = filename;
+ RKStandardComponent::handle = handle;
backend = 0;
gui = 0;
wizard = 0;
Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.h 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.h 2007-01-08 00:52:29 UTC (rev 1086)
@@ -23,6 +23,7 @@
#include <qdom.h>
class RKStandardComponentGUI;
+class RKComponentHandle;
class RKStandardComponentStack;
class ScriptBackend;
@@ -36,7 +37,7 @@
@param parent_component Parent component (or 0, if this is going to be a top-level component)
@param parent_widget Parent widget (typically 0, if this is going to be a top-level component)
@param filename Filename of the XML-file to construct this component from */
- RKStandardComponent (RKComponent *parent_component, QWidget *parent_widget, const QString &filename);
+ RKStandardComponent (RKComponent *parent_component, QWidget *parent_widget, const QString &filename, RKComponentHandle *handle);
/** destructor */
~RKStandardComponent ();
/** reimplemented to update code on changes*/
@@ -63,6 +64,7 @@
void setCaption (const QString &caption);
/** return the filename of the xml file */
QString getFilename () { return filename; };
+ RKComponentHandle *getHandle () { return handle; };
public slots:
/** this gets called by the script-backend, when it's done. Might enable the
submit button or destruct the plugin. */
@@ -83,6 +85,7 @@
QString filename;
ScriptBackend *backend;
RKStandardComponentGUI *gui;
+ RKComponentHandle *handle;
RKStandardComponentStack *wizard;
/** Avoid updating code-display, etc. until the component is fully created */
bool created;
Modified: trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2007-01-08 00:52:29 UTC (rev 1086)
@@ -19,6 +19,7 @@
#include <klocale.h>
#include <kaction.h>
+#include <kurl.h>
#include <qtimer.h>
#include <qsplitter.h>
@@ -28,6 +29,8 @@
#include <qpushbutton.h>
#include <qlabel.h>
+#include "rkcomponentmap.h"
+#include "../windows/rkworkplace.h"
#include "../windows/rkcommandeditorwindow.h"
#include "../rbackend/rinterface.h"
#include "../misc/rkerrordialog.h"
@@ -159,6 +162,11 @@
void RKStandardComponentGUI::help () {
RK_TRACE (PLUGIN);
+
+ QString id = RKComponentMap::getComponentId (component->getHandle ());
+
+ QString path = QStringList::split ("::", id).join ("/");
+ RKWorkplace::mainWorkplace ()->openHelpWindow (KURL ("rkcomponent:///" + path));
}
void RKStandardComponentGUI::closeEvent (QCloseEvent *e) {
Added: trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.rkh
===================================================================
--- trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.rkh (rev 0)
+++ trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.rkh 2007-01-08 00:52:29 UTC (rev 1086)
@@ -0,0 +1,25 @@
+<!DOCTYPE rkhelp>
+<document>
+ <!-- title can be ommitted, as this is the help page for a plugin
+ <title>alskfa</title>
+ -->
+ <summary>
+ Compute the most common descriptive statistics for one or more numeric vectors
+ </summary>
+ <usage>
+ If there are general usage instruction, not tied to an option, specify them here (see <link href="rkcomponent:///basic_statistics">testtitle</link>)
+
+ Next paragraph
+ Same paragraph
+ </usage>
+ <settings>
+ <setting id="x">Select one or more numeric vectors to analyse</setting>
+ <setting id="mean">Should the mean value be computed?</setting>
+ <setting id="trim">Trim of the mean. See <link href="rhelp:///mean"/></setting>
+ </settings>
+ <related>
+ <link href="rhelp:///mean"/>
+ <link href="rkcomponent:///basic_statistics"/>
+ <link href="rkhelp:///basic_functions"/>
+ </related>
+</document>
Modified: trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.xml
===================================================================
--- trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.xml 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/plugins/descriptive/descriptive_statistics.xml 2007-01-08 00:52:29 UTC (rev 1086)
@@ -2,6 +2,8 @@
<!-- This is a simple example, of how a "plugin" might be configured. -->
<document>
<code file="descriptive_statistics.php" />
+ <help file="descriptive_statistics.rkh" />
+
<dialog label="Descriptive Statistics" >
<tabbook>
<tab label="Variables">
Modified: trunk/rkward/rkward/windows/rkhtmlwindow.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkhtmlwindow.cpp 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/windows/rkhtmlwindow.cpp 2007-01-08 00:52:29 UTC (rev 1086)
@@ -29,11 +29,15 @@
#include <qwidget.h>
#include <qlayout.h>
#include <qtimer.h>
+#include <qdir.h>
#include "../rkglobals.h"
+#include "../khelpdlg.h"
#include "../rkward.h"
#include "../settings/rksettingsmodulegeneral.h"
#include "../misc/rkcommonfunctions.h"
+#include "../misc/xmlhelper.h"
+#include "../plugin/rkcomponentmap.h"
#include "../windows/rkworkplace.h"
#include "../windows/rkworkplaceview.h"
#include "../debug.h"
@@ -99,6 +103,7 @@
url_history.next ();
RK_ASSERT (url_history.current ());
+qDebug ("Error is here");
khtmlpart->openURL (*(url_history.current ()));
updateCaption (*(url_history.current ()));
@@ -111,6 +116,7 @@
url_history.prev ();
RK_ASSERT (url_history.current ());
+qDebug ("Error is here");
khtmlpart->openURL (*(url_history.current ()));
updateCaption (*(url_history.current ()));
@@ -132,6 +138,12 @@
}
khtmlpart->openURL (url);
+ changeURL (url);
+
+ return true;
+}
+
+void RKHTMLWindow::changeURL (const KURL &url) {
updateCaption (url);
if (back && forward) {
@@ -144,8 +156,6 @@
back->setEnabled (url_history.count () > 1);
forward->setEnabled (false);
}
-
- return true;
}
void RKHTMLWindow::updateCaption (const KURL &url) {
@@ -343,4 +353,130 @@
khtmlpart = 0; // in case we try to redelete in a parent class
}
+bool RKHelpWindow::openURL (const KURL &url) {
+ RK_TRACE (APP);
+
+ // TODO: real error handling
+ bool ok = true;
+ qDebug ("here1 %s", url.prettyURL ().latin1 ());
+ if (url.protocol () == "rkcomponent") {
+ ok = renderRKHelp (url);
+ } else if (url.protocol () == "rhelp") {
+ // TODO: find a nice solution to render this in the current window
+ RKGlobals::helpDialog ()->getFunctionHelp (url.path ());
+ } else if (url.protocol () == "rkhelp") {
+ ok = renderRKHelp (url);
+ } else {
+ ok = RKHTMLWindow::openURL (url);
+ }
+
+ if (!ok) {
+ khtmlpart->begin (url);
+ khtmlpart->write ("<html><body><h1>" + i18n ("Page does not exist or is broken") + "</h1></body></html>");
+ khtmlpart->end ();
+ }
+
+ changeURL (url);
+ return ok;
+}
+
+bool RKHelpWindow::renderRKHelp (const KURL &url) {
+ RK_TRACE (APP);
+
+ qDebug ("here2 %s", url.path ().latin1 ());
+ if (url.protocol () == "rkcomponent") {
+ bool success = false;
+ XMLHelper *component_xml = new XMLHelper ();
+ XMLHelper *help_xml = new XMLHelper ();
+
+ while (true) { // dirty hack to streamline exit code: breaking from this while, before success is set to true will cause the XMLHelpers to be deleted, and false returned.
+ QStringList path_segments = QStringList::split ('/', url.path ());
+ if (path_segments.count () > 2) break;
+ if (path_segments.count () < 1) break;
+ if (path_segments.count () == 1) path_segments.push_front ("rkward");
+ RK_ASSERT (path_segments.count () == 2);
+ RKComponentHandle *chandle = RKComponentMap::getComponentHandle (path_segments.join ("::"));
+ if (!chandle) break;
+
+ qDebug ("here3");
+ QDomElement component_doc_element = component_xml->openXMLFile (chandle->getFilename (), DL_ERROR);
+ if (component_doc_element.isNull ()) break;
+ QDomElement element = component_xml->getChildElement (component_doc_element, "help", DL_ERROR);
+ if (element.isNull ()) break;
+ QString help_file_name = component_xml->getStringAttribute (element, "file", QString::null, DL_ERROR);
+ if (help_file_name.isNull ()) break;
+ help_file_name = QFileInfo (chandle->getFilename ()).dir (true).filePath (help_file_name);
+
+ qDebug ("here4");
+ QDomElement help_doc_element = help_xml->openXMLFile (help_file_name, DL_ERROR);
+ if (help_doc_element.isNull ()) break;
+
+ khtmlpart->begin (url);
+ khtmlpart->write ("<html><head><title>" + chandle->getLabel () + "</title></head>\n<body>\n<h1>" + chandle->getLabel () + "</h1>\n");
+
+ qDebug ("here5");
+ element = help_xml->getChildElement (help_doc_element, "summary", DL_WARNING);
+ if (!element.isNull ()) {
+ khtmlpart->write ("<h2>" + i18n ("Summary") + "</h2>\n");
+ khtmlpart->write (renderHelpFragment (element));
+ }
+
+ element = help_xml->getChildElement (help_doc_element, "usage", DL_WARNING);
+ if (!element.isNull ()) {
+ khtmlpart->write ("<h2>" + i18n ("Usage") + "</h2>\n");
+ khtmlpart->write (renderHelpFragment (element));
+ }
+
+ // TODO: handle some generic sections
+
+ // TODO: handle settings section
+
+ // TODO: handle related section
+
+ khtmlpart->end ();
+ success = true;
+ break;
+ }
+
+ delete (component_xml);
+ delete (help_xml);
+ return (success);
+ }
+
+ return false;
+}
+
+QString RKHelpWindow::renderHelpFragment (QDomElement &fragment) {
+ RK_TRACE (APP);
+
+ QDomNodeList link_nodes = fragment.elementsByTagName ("link");
+ for (int i=link_nodes.count (); i >= 0; --i) {
+ QDomElement element = link_nodes.item (i).toElement ();
+ if (element.isNull ()) continue;
+
+ prepareHelpLink (&element);
+ qDebug ("fragment");
+ }
+
+ QString ret;
+ QTextOStream stream (&ret);
+ fragment.save (stream, 0);
+
+ ret.prepend ("<p>");
+ ret.append ("</p>");
+ ret.replace ("\n\n", "</p>\n<p>");
+
+ return ret;
+}
+
+void RKHelpWindow::prepareHelpLink (QDomElement *link_element) {
+ RK_TRACE (APP);
+ qDebug ("link");
+
+ link_element->setTagName ("a");
+ if (link_element->text ().isNull ()) {
+ link_element->appendChild (link_element->ownerDocument ().createTextNode ("TODO: determine link title"));
+ }
+}
+
#include "rkhtmlwindow.moc"
Modified: trunk/rkward/rkward/windows/rkhtmlwindow.h
===================================================================
--- trunk/rkward/rkward/windows/rkhtmlwindow.h 2007-01-07 20:41:34 UTC (rev 1085)
+++ trunk/rkward/rkward/windows/rkhtmlwindow.h 2007-01-08 00:52:29 UTC (rev 1086)
@@ -75,6 +75,8 @@
KHTMLPart * khtmlpart;
/** update caption according to given URL */
virtual void updateCaption (const KURL &url);
+/** called from openURL. Takes care of updating caption, and updating back/forward actions, if available */
+ void changeURL (const KURL &url);
protected:
QPtrList<KURL> url_history;
KAction *back;
@@ -134,6 +136,8 @@
static QDateTime last_refresh_time;
};
+class QDomElement;
+
/**
\brief Show html help files.
@@ -150,6 +154,12 @@
RKHelpWindow (QWidget *parent = 0);
/** destructor */
~RKHelpWindow ();
+/** reimplemented to handle our special protocols component://, rhelp://, and rkhelp:// in addition to the regular protocols */
+ bool openURL (const KURL &url);
+private:
+ bool renderRKHelp (const KURL &url);
+ QString renderHelpFragment (QDomElement &fragment);
+ void prepareHelpLink (QDomElement *link_element);
};
#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