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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Mon Jan 22 23:17:06 UTC 2007


Revision: 1193
          http://svn.sourceforge.net/rkward/?rev=1193&view=rev
Author:   tfry
Date:     2007-01-22 15:17:06 -0800 (Mon, 22 Jan 2007)

Log Message:
-----------
Initial implementation of context sensitive plugins
Example: Open an X11 device window, chose Device->Export
The device number is taken from the context
May not look like much, but should become pretty useful

Modified Paths:
--------------
    trunk/rkward/rkward/plugin/Makefile.am
    trunk/rkward/rkward/plugin/rkcomponent.h
    trunk/rkward/rkward/plugin/rkcomponentmap.cpp
    trunk/rkward/rkward/plugin/rkcomponentmap.h
    trunk/rkward/rkward/plugins/all.pluginmap
    trunk/rkward/rkward/plugins/x11device/export.php
    trunk/rkward/rkward/plugins/x11device/export.xml
    trunk/rkward/rkward/plugins/x11device.pluginmap
    trunk/rkward/rkward/windows/rkwindowcatcher.cpp

Added Paths:
-----------
    trunk/rkward/rkward/plugin/rkcomponentcontext.cpp
    trunk/rkward/rkward/plugin/rkcomponentcontext.h

Modified: trunk/rkward/rkward/plugin/Makefile.am
===================================================================
--- trunk/rkward/rkward/plugin/Makefile.am	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugin/Makefile.am	2007-01-22 23:17:06 UTC (rev 1193)
@@ -4,11 +4,11 @@
 libplugin_a_SOURCES = rkcomponentmap.cpp rkcomponentproperties.cpp rkcomponent.cpp \
 	rkstandardcomponent.cpp rkvarselector.cpp rkvarslot.cpp rkformula.cpp rkradio.cpp \
 	rkcheckbox.cpp rkpluginspinbox.cpp rkinput.cpp rkpluginbrowser.cpp rktext.cpp \
-	rktabpage.cpp rkstandardcomponentgui.cpp rkdropdown.cpp
+	rktabpage.cpp rkstandardcomponentgui.cpp rkdropdown.cpp rkcomponentcontext.cpp
 
 noinst_HEADERS = rkcomponentmap.h rkcomponentproperties.h rkcomponent.h \
 	rkstandardcomponent.h rkvarselector.h rkvarslot.h rkformula.h rkradio.h \
 	rkcheckbox.h rkpluginspinbox.h rkinput.h rkpluginbrowser.h rktext.h \
-	rktabpage.h rkstandardcomponentgui.h rkdropdown.h
+	rktabpage.h rkstandardcomponentgui.h rkdropdown.h rkcomponentcontext.h
 
 

Modified: trunk/rkward/rkward/plugin/rkcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.h	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugin/rkcomponent.h	2007-01-22 23:17:06 UTC (rev 1193)
@@ -2,7 +2,7 @@
                           rkcomponent  -  description
                              -------------------
     begin                : Tue Dec 13 2005
-    copyright            : (C) 2005, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -77,9 +77,9 @@
 	virtual bool isValid () { return true; };
 /** set to required: will only be satisfied if it is valid. Else: always satisfied (but subclasses might override to always be dissatisfied on really bad values. By default RKComponentBase is required at construction */
 	void setRequired (bool require) { required = require; };
-protected:
 /** simple convenience function to add a child to the map of children */
 	void addChild (const QString &id, RKComponentBase *child);
+protected:
 	QDict<RKComponentBase> child_map;
 	bool required;
 /** recursively fetch the current values of all properties present as direct or indirect children of this component. Used to transfer values e.g. when switching interfaces (or to store settings per plugin in the future). Values are placed in the dictionary provided (be sure to create one first!).

Added: trunk/rkward/rkward/plugin/rkcomponentcontext.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentcontext.cpp	                        (rev 0)
+++ trunk/rkward/rkward/plugin/rkcomponentcontext.cpp	2007-01-22 23:17:06 UTC (rev 1193)
@@ -0,0 +1,115 @@
+/***************************************************************************
+                          rkcomponentcontext  -  description
+                             -------------------
+    begin                : Mon Jan 22 2007
+    copyright            : (C) 2007 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "rkcomponentcontext.h"
+
+#include <kaction.h>
+
+#include "../misc/xmlhelper.h"
+
+#include "../debug.h"
+
+RKContextMap::RKContextMap () : RKComponentGUIXML () {
+	RK_TRACE (PLUGIN);
+}
+
+RKContextMap::~RKContextMap () {
+	RK_TRACE (PLUGIN);
+}
+
+int RKContextMap::create (const QDomElement &context_element, const QString &component_namespace) {
+	RK_TRACE (PLUGIN);
+
+	XMLHelper *xml = XMLHelper::getStaticHelper ();
+	QDomElement element = xml->getChildElement (gui_xml.documentElement (), "MenuBar", DL_ERROR);
+	return (createMenus (element, context_element, component_namespace));
+}
+
+RKContextHandler *RKContextMap::makeContextHandler (QObject *parent) {
+	RK_TRACE (PLUGIN);
+
+	RKContextHandler *handler = new RKContextHandler (parent, gui_xml);
+	for (QStringList::const_iterator it = component_ids.constBegin (); it != component_ids.constEnd (); ++it) {
+		RKComponentHandle *handle = RKComponentMap::getComponentHandle (*it);
+		if (handle->isPlugin ()) {
+			handler->addAction (*it, static_cast<RKStandardComponentHandle *> (handle));
+		}
+	}
+	return handler;
+}
+
+void RKContextMap::addedEntry (const QString &id, RKComponentHandle *) {
+	RK_TRACE (PLUGIN);
+
+	component_ids.append (id);
+}
+
+/////////////////// END RKContextMap /////////////////////
+//////////////// BEGIN RKContextHandler //////////////////
+
+RKContextHandler::RKContextHandler (QObject *parent, const QDomDocument &gui_xml) : QObject (parent), RKComponentBase (), KXMLGUIClient () {
+	RK_TRACE (PLUGIN);
+
+	setXMLGUIBuildDocument (gui_xml);
+
+	addChild ("incontext", new RKComponentPropertyBool (this, false, true));
+}
+
+RKContextHandler::~RKContextHandler () {
+	RK_TRACE (PLUGIN);
+}
+
+void RKContextHandler::addAction (const QString &id, RKStandardComponentHandle *handle) {
+	RK_TRACE (PLUGIN);
+
+	action_map.insert (new KAction (handle->getLabel (), 0, this, SLOT (componentActionActivated ()), actionCollection (), id.latin1 ()), handle);
+}
+
+void RKContextHandler::componentActionActivated () {
+	RK_TRACE (PLUGIN);
+
+	// find handle that triggered action
+	RKStandardComponentHandle *handle = 0;
+	const KAction *action = dynamic_cast<const KAction *> (sender ());
+	if (action_map.contains (action)) handle = action_map[action];
+	if (!handle) {
+		RK_ASSERT (false);
+		return;
+	}
+
+	// create component
+	RKComponent *component = handle->invoke (0, 0);
+
+	// set context values
+	for (QDictIterator<RKComponentBase> it (child_map); it.current (); ++it) {
+		if (it.currentKey () != "#noid#") {
+			QString id = it.currentKey ();
+			QString remainder;
+			RKComponentBase *client = component->lookupComponent (id, &remainder);
+
+			RK_ASSERT (it.current ()->isProperty ());
+			if (!(client && remainder.isEmpty () && client->isProperty () && it.current ()->isProperty ())) {
+				RK_DO (qDebug ("Could not set context property %s", id.latin1 ()), PLUGIN, DL_INFO);
+				continue;
+			}
+
+			static_cast<RKComponentPropertyBase *> (client)->connectToGovernor (static_cast<RKComponentPropertyBase *> (it.current ()), QString::null, false);
+		}
+	}
+}
+
+#include "rkcomponentcontext.moc"

Added: trunk/rkward/rkward/plugin/rkcomponentcontext.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentcontext.h	                        (rev 0)
+++ trunk/rkward/rkward/plugin/rkcomponentcontext.h	2007-01-22 23:17:06 UTC (rev 1193)
@@ -0,0 +1,59 @@
+/***************************************************************************
+                          rkcomponentcontext  -  description
+                             -------------------
+    begin                : Mon Jan 22 2007
+    copyright            : (C) 2007 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef RKCOMPONENTCONTEXT_H
+#define RKCOMPONENTCONTEXT_H
+
+#include <qobject.h>
+
+#include "rkcomponentmap.h"
+#include "rkcomponent.h"
+
+class QDomElement;
+class RKContextHandler;
+
+class RKContextMap : public RKComponentGUIXML {
+public:
+	RKContextMap ();
+	~RKContextMap ();
+
+	int create (const QDomElement &context_element, const QString &component_namespace);
+	RKContextHandler *makeContextHandler (QObject *parent);
+protected:
+	void addedEntry (const QString &id, RKComponentHandle * /* handle */);
+private:
+	QStringList component_ids;
+};
+
+
+
+class RKContextHandler : public QObject, public RKComponentBase, public KXMLGUIClient {
+	Q_OBJECT
+friend class RKContextMap;
+protected:
+	RKContextHandler (QObject *parent, const QDomDocument &gui_xml);
+	~RKContextHandler ();
+
+	void addAction (const QString &id, RKStandardComponentHandle *handle);
+private slots:
+	void componentActionActivated ();
+private:
+	typedef QMap<const KAction *, RKStandardComponentHandle *> ActionMap;
+	ActionMap action_map;
+};
+
+#endif

Modified: trunk/rkward/rkward/plugin/rkcomponentmap.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2007-01-22 23:17:06 UTC (rev 1193)
@@ -21,11 +21,107 @@
 
 #include <klocale.h>
 
+#include "rkcomponentcontext.h"
 #include "../misc/xmlhelper.h"
 #include "../debug.h"
 #include "../rkglobals.h"
 #include "../rkward.h"
 
+RKComponentGUIXML::RKComponentGUIXML () {
+	RK_TRACE (PLUGIN);
+
+	clearGUIDescription ();
+}
+
+RKComponentGUIXML::~RKComponentGUIXML () {
+	RK_TRACE (PLUGIN);
+}
+
+void RKComponentGUIXML::clearGUIDescription () {
+	RK_TRACE (PLUGIN);
+
+	gui_xml.setContent (QString ("<!DOCTYPE kpartgui>\n<kpartgui name=\"rkwardcomponents\" version=\"0.3.4\">\n<MenuBar>\n\n</MenuBar>\n</kpartgui>"));
+}
+
+int RKComponentGUIXML::createMenus (QDomElement& parent, const QDomElement& hierarchy_description, const QString& cnamespace) {
+	RK_TRACE (PLUGIN);
+
+	XMLHelper* xml = XMLHelper::getStaticHelper ();
+	XMLChildList list = xml->getChildElements (hierarchy_description, "menu", DL_INFO);
+	int counter = 0;
+	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
+		counter += addSubMenu (parent, (*it), cnamespace);
+	}
+	return counter;
+}
+
+QDomElement RKComponentGUIXML::findOrCreateElement (QDomElement& parent, const QString& tagname, const QString& name, const QString& label, int index) {
+	RK_TRACE (PLUGIN);
+
+	XMLHelper* xml = XMLHelper::getStaticHelper ();
+	XMLChildList list = xml->getChildElements (parent, QString::null, DL_INFO);		// we need to look at all children, so we get the order right
+	QDomElement insert_after_element;
+	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
+		if ((tagname == (*it).tagName ()) && (name == xml->getStringAttribute ((*it), "name", "", DL_ERROR))) {
+			return (*it);
+		} else {
+			if (index >= 0) {
+				if (index > xml->getIntAttribute ((*it), "index", -1, DL_INFO)) {
+					insert_after_element = *it;
+				}
+			}
+		}
+	}
+
+	// element not found. Create a new one instead
+	QDomElement ret = gui_xml.createElement (tagname);
+	ret.setAttribute ("name", name);
+	ret.setAttribute ("index", index);
+	if (!label.isEmpty ()) {
+		QDomElement text = gui_xml.createElement ("text");
+		text.appendChild (gui_xml.createTextNode (label));
+		ret.appendChild (text);
+	}
+	parent.insertAfter (ret, insert_after_element);	// if index_after_element.isNull, this add the new element as the last child of parent!
+
+	return ret;
+}
+
+int RKComponentGUIXML::addSubMenu (QDomElement& parent, const QDomElement& description, const QString& cnamespace) {
+	RK_TRACE (PLUGIN);
+
+	int counter = 0;
+	XMLHelper* xml = XMLHelper::getStaticHelper ();
+
+	// 1: check whether menu already exists, and create new menu otherwise
+	QDomElement menu_element = findOrCreateElement (parent, "Menu", xml->getStringAttribute (description, "id", "none", DL_ERROR), xml->getStringAttribute (description, "label", i18n ("(no label)"), DL_WARNING), xml->getIntAttribute (description, "index", -1, DL_INFO));
+
+	// 2: recurse into submenus (of element to add!)
+	XMLChildList list = xml->getChildElements (description, "menu", DL_INFO);
+	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
+		counter += addSubMenu (menu_element, (*it), cnamespace);
+	}
+
+	// 3: add entries
+	list = xml->getChildElements (description, "entry", DL_INFO);
+	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
+		QString id = cnamespace + xml->getStringAttribute ((*it), "component", "#invalid#", DL_ERROR);
+
+		RKComponentHandle* handle = RKComponentMap::getComponentHandle (id);
+		if ((!handle) || (!handle->isPlugin ())) {
+			RK_DO (qDebug ("No such component found while creating menu-entries or component is not a standalone plugin: \"%s\". No entry created.", id.latin1 ()), PLUGIN, DL_ERROR);
+		} else {
+			findOrCreateElement (menu_element, "Action", id, QString::null, xml->getIntAttribute ((*it), "index", -1, DL_INFO));
+			addedEntry (id, handle);
+			counter++;
+		}
+	}
+	return counter;
+}
+
+/////////////////////////// END RKComponentXMLGUIClient /////////////////////////////////
+////////////////////////////// BEGIN RKComponentMap /////////////////////////////////////
+
 // static members
 RKComponentMap *RKComponentMap::component_map = 0;
 
@@ -36,7 +132,7 @@
 	component_map = new RKComponentMap ();
 }
 
-RKComponentMap::RKComponentMap () : KXMLGUIClient () {
+RKComponentMap::RKComponentMap () : RKComponentGUIXML (), KXMLGUIClient () {
 	RK_TRACE (PLUGIN);
 }
 
@@ -52,14 +148,14 @@
 	actionCollection ()->clear ();
 	for (ComponentMap::iterator it = components.begin (); it != components.end (); ++it) {
 		delete (it.data ());
+/* TODO: this is not technically correct, as there may be several actions for this id, and we're only deleting one. But practically this should not really be relevant. */
+		delete (actionCollection ()->action (it.key ().latin1 ()));
 	}
 	components.clear ();
 
-	// TODO!
-	QDomDocument doc;
-	doc.setContent (QString ("<!DOCTYPE kpartgui>\n<kpartgui name=\"rkwardcomponents\" version=\"0.3.4\">\n<MenuBar>\n\n</MenuBar>\n</kpartgui>"));
-/*<Menu name=\"file\"><text>&File</text></Menu>\n<Menu name=\"analysis\"><text>&Analysis</text>\n</Menu>*/
-	setXMLGUIBuildDocument (doc);
+	clearGUIDescription ();
+
+	setXMLGUIBuildDocument (gui_xml);
 }
 
 void RKComponentMap::clearAll () {
@@ -68,6 +164,23 @@
 	getMap ()->clearLocal ();
 }
 
+RKContextMap *RKComponentMap::getContext (const QString &id) {
+	RK_TRACE (PLUGIN);
+
+	RKContextMap *context = getMap ()->getContextLocal (id);
+	if (context) return context;
+
+	RK_DO (qDebug ("no such context %s", id.latin1 ()), PLUGIN, DL_WARNING);
+	return (0);
+}
+
+RKContextMap *RKComponentMap::getContextLocal (const QString &id) {
+	RK_TRACE (PLUGIN);
+
+	if (contexts.contains (id)) return (contexts[id]);
+	return 0;
+}
+
 RKComponentHandle* RKComponentMap::getComponentHandle (const QString &id) {
 	RK_TRACE (PLUGIN);
 
@@ -105,71 +218,6 @@
 	return (QString ());
 }
 
-//static
-QDomElement RKComponentMap::findOrCreateElement (QDomElement& parent, const QString& tagname, const QString& name, const QString& label, int index) {
-	RK_TRACE (PLUGIN);
-
-	XMLHelper* xml = XMLHelper::getStaticHelper ();
-	XMLChildList list = xml->getChildElements (parent, QString::null, DL_INFO);		// we need to look at all children, so we get the order right
-	QDomElement insert_after_element;
-	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
-		if ((tagname == (*it).tagName ()) && (name == xml->getStringAttribute ((*it), "name", "", DL_ERROR))) {
-			return (*it);
-		} else {
-			if (index >= 0) {
-				if (index > xml->getIntAttribute ((*it), "index", -1, DL_INFO)) {
-					insert_after_element = *it;
-				}
-			}
-		}
-	}
-
-	// element not found. Create a new one instead
-	QDomElement ret = xmlguiBuildDocument ().createElement (tagname);
-	ret.setAttribute ("name", name);
-	ret.setAttribute ("index", index);
-	if (!label.isEmpty ()) {
-		QDomElement text = xmlguiBuildDocument ().createElement ("text");
-		text.appendChild (xmlguiBuildDocument ().createTextNode (label));
-		ret.appendChild (text);
-	}
-	parent.insertAfter (ret, insert_after_element);	// if index_after_element.isNull, this add the new element as the last child of parent!
-
-	return ret;
-}
-
-int RKComponentMap::addSubMenu (QDomElement& parent, const QDomElement& description, const QString& cnamespace) {
-	RK_TRACE (PLUGIN);
-
-	int counter = 0;
-	XMLHelper* xml = XMLHelper::getStaticHelper ();
-
-	// 1: check whether menu already exists, and create new menu otherwise
-	QDomElement menu_element = findOrCreateElement (parent, "Menu", xml->getStringAttribute (description, "id", "none", DL_ERROR), xml->getStringAttribute (description, "label", i18n ("(no label)"), DL_WARNING), xml->getIntAttribute (description, "index", -1, DL_INFO));
-
-	// 2: recurse into submenus (of element to add!)
-	XMLChildList list = xml->getChildElements (description, "menu", DL_INFO);
-	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
-		counter += addSubMenu (menu_element, (*it), cnamespace);
-	}
-
-	// 3: add entries
-	list = xml->getChildElements (description, "entry", DL_INFO);
-	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
-		QString id = cnamespace + xml->getStringAttribute ((*it), "component", "#invalid#", DL_ERROR);
-
-		RKComponentHandle* handle = components[id];
-
-		if ((!handle) || (!handle->isPlugin ())) {
-			RK_DO (qDebug ("No such component found while creating menu-entries or component is not a standalone plugin: \"%s\". No entry created.", id.latin1 ()), PLUGIN, DL_ERROR);
-		} else {
-			findOrCreateElement (menu_element, "Action", id, QString::null, xml->getIntAttribute ((*it), "index", -1, DL_INFO));
-			counter++;
-		}
-	}
-	return counter;
-}
-
 int RKComponentMap::addPluginMap (const QString& plugin_map_file) {
 	RK_TRACE (PLUGIN);
 
@@ -204,21 +252,24 @@
 		} else if (!QFileInfo (filename).isReadable ()) {
 			RK_DO (qDebug ("Specified file '%s' for component id \"%s\" does not exist or is not readable. Ignoring.", filename.latin1 (), id.latin1 ()), PLUGIN, DL_ERROR);
 		} else {
-			components.insert (id, RKComponentHandle::createComponentHandle (filename, (RKComponentType) type, id, label, this));
+			components.insert (id, RKComponentHandle::createComponentHandle (filename, (RKComponentType) type, label));
 		}
 	}
 
 	// step 2: create / insert into menus
-	QDomElement xmlgui_menubar_elem = xml->getChildElement (xmlguiBuildDocument ().documentElement (), "MenuBar", DL_ERROR);
+	QDomElement xmlgui_menubar_element = xml->getChildElement (gui_xml.documentElement (), "MenuBar", DL_ERROR);
+	int counter = createMenus (xmlgui_menubar_element, xml->getChildElement (document_element, "hierarchy", DL_INFO), cnamespace);
 
-	element = xml->getChildElement (document_element, "hierarchy", DL_INFO);
-	list = xml->getChildElements (element, "menu", DL_INFO);
-	int counter = 0;
-	for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) {
-		counter += addSubMenu (xmlgui_menubar_elem, (*it), cnamespace);
+	// step 3: create and register contexts
+	list = xml->getChildElements (document_element, "context", DL_INFO);
+	for (XMLChildList::const_iterator it=list.constBegin (); it != list.constEnd (); ++it) {
+		QString id = xml->getStringAttribute (*it, "id", QString::null, DL_ERROR);
+		RKContextMap *context = new RKContextMap ();
+		counter += context->create (*it, cnamespace);
+		contexts.insert (id, context);
 	}
 
-	// step 3: included files
+	// step 4: included files
 	QStringList includelist;
 	list = xml->getChildElements (document_element, "include", DL_INFO);
 	for (XMLChildList::const_iterator it=list.constBegin (); it != list.constEnd (); ++it) {
@@ -233,9 +284,18 @@
 		counter += addPluginMap (*it);
 	}
 
+	setXMLGUIBuildDocument (gui_xml);
 	return counter;
 }
 
+void RKComponentMap::addedEntry (const QString &id, RKComponentHandle *handle) {
+	RK_TRACE (PLUGIN);
+
+	if (handle->isPlugin ()) {
+		new KAction (handle->getLabel (), 0, static_cast<RKStandardComponentHandle *>(handle), SLOT (activated ()), actionCollection (), id.latin1 ());
+	}
+}
+
 ///########################### END RKComponentMap ###############################
 ///########################### BEGIN RKComponentHandle ############################
 
@@ -252,10 +312,9 @@
 }
 
 //static 
-RKComponentHandle* RKComponentHandle::createComponentHandle (const QString &filename, RKComponentType type, const QString& id, const QString& label, RKComponentMap *map) {
+RKComponentHandle* RKComponentHandle::createComponentHandle (const QString &filename, RKComponentType type, const QString& label) {
 	if (type == (int) Standard) {
 		RKStandardComponentHandle *ret = new RKStandardComponentHandle (filename, label, type);
-		new KAction (label, 0, ret, SLOT (activated ()), map->actionCollection (), id.latin1 ());
 		return (ret);
 	}
 	// TODO: create an RKPluginHandle instead!

Modified: trunk/rkward/rkward/plugin/rkcomponentmap.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.h	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.h	2007-01-22 23:17:06 UTC (rev 1193)
@@ -28,6 +28,7 @@
 class RKComponent;
 class RKComponentMap;
 class QWidget;
+class KActionCollection;
 /** This simple class keeps the most basic information about a component in RKWard. Most work is done in RKComponentMap.
 
 @author Thomas Friedrichsmeier
@@ -43,10 +44,10 @@
 	RKComponentType getType () { return type; };
 	bool isPlugin ();
 
-	static RKComponentHandle* createComponentHandle (const QString &filename, RKComponentType type, const QString& id, const QString& label, RKComponentMap *map);
+	static RKComponentHandle* createComponentHandle (const QString &filename, RKComponentType type, const QString& label);
 /** invoke the component (standalone or embedded) */
 	virtual RKComponent *invoke (RKComponent *parent_component, QWidget *parent_widget) = 0;
-private:
+protected:
 /** The filename of the description file for this component */
 	QString filename;
 	QString label;
@@ -57,8 +58,43 @@
 #include <kxmlguiclient.h>
 
 class QDomElement;
-class RKMenu;
 
+class RKComponentGUIXML {
+protected:
+	RKComponentGUIXML ();
+	~RKComponentGUIXML ();
+
+	void clearGUIDescription ();
+
+/** build XMLGUI menus
+ at param parent the parent menu (or tag) (in the KXMLGUI)
+ at param hierarchy_description the QDomElement containing the description for the new menu hierarchy
+ at returns number of plugins/menu-entries added successfully */
+	int createMenus (QDomElement& parent, const QDomElement& hierarchy_description, const QString& cnamespace);
+
+/** recurse into a lower menu-level 
+ at param parent the parent menu (in the KXMLGUI)
+ at param description the QDomElement containing the description for the new submenu
+ at returns number of plugins/menu-entries added successfully */
+	int addSubMenu (QDomElement& parent, const QDomElement& description, const QString& cnamespace);
+
+/** helper function: Find a specified element, and return it. If the element could not be found, it is created instead. The first three parameters are used as search parameters (all have to match). The additional two parameters only take effect, if a new element is created.
+ at param parent the QDomElement whose children to search through
+ at param tagname the tagname to look for
+ at param name value of the "name"-attribute to look for
+ at param label the label to assign to the new element (if no existing match could be found)
+ at param index the index position where to insert the new element in the list of children (if no existing match could be found). -1 means insert at the end of the list. */
+	QDomElement findOrCreateElement (QDomElement& parent, const QString& tagname, const QString& name, const QString& label, int index);
+
+/** an entry was added to the menu(s) somewhere. Reimplement, if you want to create a KAction for this */
+	virtual void addedEntry (const QString & /* id */, RKComponentHandle * /* handle */) {};
+
+	QDomDocument gui_xml;
+};
+
+
+class RKContextMap;
+
 /** This class (only a single instance should ever be needed) keeps a list of named components, which can be made accessible via the menu-structure
 or included in other plugins. What this class does is rather simple: It basically maps a two piece name (namespace, component name) to a short description of the component (RKComponentHandle). The most important part of that description is the filename where a more elaborate definition of
 the component can be retrieved.
@@ -67,7 +103,7 @@
 
 @author Thomas Friedrichsmeier
 */
-class RKComponentMap : public KXMLGUIClient {
+class RKComponentMap : public RKComponentGUIXML, public KXMLGUIClient {
 public:
 	RKComponentMap ();
 
@@ -85,21 +121,8 @@
 	static QString getComponentId (RKComponentHandle* by_component);
 	static RKComponentMap *getMap () { return component_map; };
 	static void initialize ();
+	static RKContextMap *getContext (const QString &id);
 private:
-/** recurse into a lower menu-level 
- at param parent the parent menu (in the KXMLGUI)
- at param description the QDomElement containing the description for the new submenu
- at returns number of plugins/menu-entries added successfully */
-	int addSubMenu (QDomElement& parent, const QDomElement& description, const QString& cnamespace);
-
-/** helper function: Find a specified element, and return it. If the element could not be found, it is created instead. The first three parameters are used as search parameters (all have to match). The additional two parameters only take effect, if a new element is created.
- at param parent the QDomElement whose children to search through
- at param tagname the tagname to look for
- at param name value of the "name"-attribute to look for
- at param label the label to assign to the new element (if no existing match could be found)
- at param index the index position where to insert the new element in the list of children (if no existing match could be found). -1 means insert at the end of the list. */
-	QDomElement findOrCreateElement (QDomElement& parent, const QString& tagname, const QString& name, const QString& label, int index);
-
 /** typedef for easy reference to iterator */
 	typedef QMap<QString, RKComponentHandle*> ComponentMap;
 /** the actual map of components */
@@ -107,11 +130,18 @@
 
 	RKComponentHandle* getComponentHandleLocal (const QString &id);
 	QString getComponentIdLocal (RKComponentHandle* component);
+	RKContextMap *getContextLocal (const QString &id);
 	int addPluginMapLocal (const QString& plugin_map_file);
 
 	void clearLocal ();
+	void makeActions ();
 
+	typedef QMap<QString, RKContextMap*> RKComponentContextMap;
+	RKComponentContextMap contexts;
+
 	static RKComponentMap *component_map;
+protected:
+	void addedEntry (const QString &id, RKComponentHandle *handle);
 };
 
 #include <qobject.h>
@@ -128,7 +158,7 @@
 
 	RKComponent *invoke (RKComponent *parent_component, QWidget *parent_widget);
 public slots:
-/** Slot called, when the menu-item for this widget is selected. Responsible for creating the GUI. */
+/** Slot called, when the menu-item for this component is selected. Responsible for creating the GUI. */
 	void activated ();
 };
 

Modified: trunk/rkward/rkward/plugins/all.pluginmap
===================================================================
--- trunk/rkward/rkward/plugins/all.pluginmap	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugins/all.pluginmap	2007-01-22 23:17:06 UTC (rev 1193)
@@ -51,5 +51,6 @@
 
 	<include file="distributions.pluginmap"/>
 	<include file="plots.pluginmap"/>
+	<include file="x11device.pluginmap"/>
 </document>
  

Modified: trunk/rkward/rkward/plugins/x11device/export.php
===================================================================
--- trunk/rkward/rkward/plugins/x11device/export.php	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugins/x11device/export.php	2007-01-22 23:17:06 UTC (rev 1193)
@@ -7,8 +7,9 @@
 <?
 }
 	
-function printout () {
-?>## TODO: need to set the correct device!
+function printout () { ?>
+print ("Device number is <? getRK ("devnum"); ?>")
+print ("In context: <? getRK ("incontext"); ?>")
 <?
 }
 	

Modified: trunk/rkward/rkward/plugins/x11device/export.xml
===================================================================
--- trunk/rkward/rkward/plugins/x11device/export.xml	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugins/x11device/export.xml	2007-01-22 23:17:06 UTC (rev 1193)
@@ -4,6 +4,9 @@
 	<logic>
 		<convert id="formatother" mode="equals" sources="format.string" standard="other" />
 		<connect client="specifiedformat.enabled" governor="formatother" />
+		
+		<external id="devnum"/>
+		<external id="incontext"/>
 	</logic>
 	<dialog label="Export contents of graphics device">
 		<text>This plugin is bogus/unfinished. Do not use!</text>

Modified: trunk/rkward/rkward/plugins/x11device.pluginmap
===================================================================
--- trunk/rkward/rkward/plugins/x11device.pluginmap	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/plugins/x11device.pluginmap	2007-01-22 23:17:06 UTC (rev 1193)
@@ -5,9 +5,9 @@
 		<component type="standard" id="export_x11_device" file="export.xml" label="Export..." />
 	</components>
 
-	<hierarchy>
+	<context id="x11">
 		<menu id="device" label="Device" index="1">
 			<entry component="export_x11_device" />
 		</menu>
-	</hierarchy>
+	</context>
 </document>

Modified: trunk/rkward/rkward/windows/rkwindowcatcher.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2007-01-22 16:27:05 UTC (rev 1192)
+++ trunk/rkward/rkward/windows/rkwindowcatcher.cpp	2007-01-22 23:17:06 UTC (rev 1193)
@@ -2,7 +2,7 @@
                           rwindowcatcher.cpp  -  description
                              -------------------
     begin                : Wed May 4 2005
-    copyright            : (C) 2005, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -83,17 +83,18 @@
 #include "../core/robject.h"
 #include "../misc/rkerrordialog.h"
 #include "../misc/rksaveobjectchooser.h"
+#include "../plugin/rkcomponentcontext.h"
 
 RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window) {
 	RK_TRACE (MISC);
 
+	embedded = window_to_embed;
+	RKCaughtX11Window::device_number = device_number;
+
 	error_dialog = new RKRErrorDialog (i18n ("An error occurred"), i18n ("An error occurred"));
 	part = new RKCaughtX11WindowPart (this);
 	setFocusPolicy (QWidget::ClickFocus);
 
-	embedded = window_to_embed;
-	RKCaughtX11Window::device_number = device_number;
-
 	QVBoxLayout *layout = new QVBoxLayout (this);
 	box_widget = new QVBox (this);
 	layout->addWidget (box_widget);
@@ -294,6 +295,15 @@
 	new KAction (i18n ("Print"), 0, window, SLOT (printDevice ()), actionCollection (), "device_print");
 	new KAction (i18n ("Store as R object..."), 0, window, SLOT (copyDeviceToRObject ()), actionCollection (), "device_copy_to_r_object");
 	new KAction (i18n ("Duplicate"), 0, window, SLOT (duplicateDevice ()), actionCollection (), "device_duplicate");
+
+	// initialize context for plugins
+	RKContextMap *context = RKComponentMap::getContext ("x11");
+	if (!context) return;
+	RKContextHandler *context_handler = context->makeContextHandler (this);
+	insertChildClient (context_handler);
+	RKComponentPropertyInt *devnum_property = new RKComponentPropertyInt (this, false, 0);
+	devnum_property->setIntValue (window->device_number);
+	context_handler->addChild ("devnum", devnum_property);
 }
 
 RKCaughtX11WindowPart::~RKCaughtX11WindowPart () {


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