[rkward-cvs] SF.net SVN: rkward: [2185] branches/KDE4_port/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Nov 7 23:49:48 UTC 2007


Revision: 2185
          http://rkward.svn.sourceforge.net/rkward/?rev=2185&view=rev
Author:   tfry
Date:     2007-11-07 15:49:48 -0800 (Wed, 07 Nov 2007)

Log Message:
-----------
Further work on the basis of the data editor rework

Modified Paths:
--------------
    branches/KDE4_port/rkward/agents/rkeditobjectagent.cpp
    branches/KDE4_port/rkward/core/rcontainerobject.cpp
    branches/KDE4_port/rkward/core/rcontainerobject.h
    branches/KDE4_port/rkward/core/rkmodificationtracker.cpp
    branches/KDE4_port/rkward/core/rkmodificationtracker.h
    branches/KDE4_port/rkward/core/robjectlist.cpp
    branches/KDE4_port/rkward/core/robjectlist.h
    branches/KDE4_port/rkward/dataeditor/rkeditor.h
    branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp
    branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h
    branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp
    branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.h
    branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
    branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
    branches/KDE4_port/rkward/dataeditor/twintable.cpp
    branches/KDE4_port/rkward/dataeditor/twintable.h
    branches/KDE4_port/rkward/misc/rkstandardicons.cpp
    branches/KDE4_port/rkward/misc/rkstandardicons.h
    branches/KDE4_port/rkward/plugin/rkcomponentproperties.cpp
    branches/KDE4_port/rkward/rkward.cpp
    branches/KDE4_port/rkward/robjectviewer.cpp
    branches/KDE4_port/rkward/windows/rkmdiwindow.h
    branches/KDE4_port/rkward/windows/rkworkplace.cpp
    branches/KDE4_port/rkward/windows/rkworkplace.h

Modified: branches/KDE4_port/rkward/agents/rkeditobjectagent.cpp
===================================================================
--- branches/KDE4_port/rkward/agents/rkeditobjectagent.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/agents/rkeditobjectagent.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -52,7 +52,7 @@
 		for (QStringList::const_iterator it = object_names.constBegin (); it != object_names.constEnd (); ++it) {
 			QString object_name = *it;
 			RObject *obj = RObjectList::getObjectList ()->findObject (object_name);
-			if (!(obj && RKWorkplace::mainWorkplace()->editObject (obj, false))) {
+			if (!(obj && RKWorkplace::mainWorkplace()->editObject (obj))) {
 				KMessageBox::information (0, i18n ("The object '%1', could not be opened for editing. Either it does not exist, or RKWard does not support editing this type of object, yet.", object_name), i18n ("Cannot edit '%1'", object_name));
 			}
 		}

Modified: branches/KDE4_port/rkward/core/rcontainerobject.cpp
===================================================================
--- branches/KDE4_port/rkward/core/rcontainerobject.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/rcontainerobject.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -189,9 +189,8 @@
 
 	RK_ASSERT (childmap[from_index] == child);
 	RK_ASSERT (from_index < childmap.size ());
-	RKGlobals::tracker ()->internalRemoveObject (child, true, false);
-	RK_ASSERT (to_index <= childmap.size ());
-	RKGlobals::tracker ()->addObject (child, this, to_index);
+	RK_ASSERT (to_index < childmap.size ());
+	RKGlobals::tracker ()->moveObject (this, child, from_index, to_index);
 }
 
 int RContainerObject::numChildren () const {
@@ -295,10 +294,9 @@
 	}
 }
 
-RObject *RContainerObject::createNewChild (const QString &name, int position, RKEditor *creator, bool container, bool data_frame) {
+RObject *RContainerObject::createPendingChild (const QString &name, int position, bool container, bool data_frame) {
 	RK_TRACE (OBJECTS);
 
-#warning rename to createPendingChild, also in RObjectList
 #warning TODO validize name
 	RObject *ret;
 	if (container) {
@@ -314,7 +312,7 @@
 
 	if ((position < 0) || (position > childmap.size ())) position = childmap.size ();
 
-	RKGlobals::tracker ()->addObject (ret, this, position, creator);
+	RKGlobals::tracker ()->addObject (ret, this, position);
 #warning TODO should we create the object in R, here?
 
 	return ret;
@@ -401,13 +399,16 @@
 
 QString RContainerObject::validizeName (const QString &child_name, bool unique) const {
 	RK_TRACE (OBJECTS);
+
 	QString ret = child_name;
-	ret = ret.replace (QRegExp ("[^a-zA-Z0-9]"), ".");
-	ret = ret.replace (QRegExp ("^\\.*[0-9]+"), ".");
 	if (ret.isEmpty ()) ret = "var";
-	int i=-1;
+	else {
+		ret = ret.replace (QRegExp ("[^a-zA-Z0-9]"), ".");
+		ret = ret.replace (QRegExp ("^\\.*[0-9]+"), ".");
+	}
+	if (!unique) return ret;
 
-	if (!unique) return ret;
+	int i=0;
 	QString postfix;
 	while (findChildByName (ret + postfix)) {
 		postfix.setNum (++i);

Modified: branches/KDE4_port/rkward/core/rcontainerobject.h
===================================================================
--- branches/KDE4_port/rkward/core/rcontainerobject.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/rcontainerobject.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -58,7 +58,7 @@
 	/** creates a new child. Right now only RKVariables (false, false), or data.frames (true, true), or unspecified containers (true, false) can be created.
 	API will likely change. The child is NOT created in the workspace. That's your resonsibility. All this function returns is a new RObject* of the given
 	type and with the name (if necessary) changed to a legal value. TODO: checking for and changing illegal names is not yet implemented */
-	virtual RObject *createNewChild (const QString &name, int position=-1, RKEditor *creator=0, bool container=false, bool data_frame=false);
+	virtual RObject *createPendingChild (const QString &name, int position=-1, bool container=false, bool data_frame=false);
 
 	/** returns true, if there are no children in this container. Note: of course the object list may not be up to date! */
 	bool isEmpty () const { return childmap.isEmpty (); };

Modified: branches/KDE4_port/rkward/core/rkmodificationtracker.cpp
===================================================================
--- branches/KDE4_port/rkward/core/rkmodificationtracker.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/rkmodificationtracker.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -56,6 +56,7 @@
 // TODO: allow more than one editor per object
 // WARNING: This does not work, if a sub-object is being edited!
 	RKEditor *ed = objectEditor (object);
+	RK_ASSERT (object);
 	RK_ASSERT (!((editor) && (!ed)));
 	RK_ASSERT (!(removed_in_workspace && editor));
 
@@ -79,14 +80,6 @@
 		}
 	}
 
-	internalRemoveObject (object, removed_in_workspace, true);
-
-	return true;
-}
-
-void RKModificationTracker::internalRemoveObject (RObject *object, bool removed_in_workspace, bool delete_obj) {
-	RK_TRACE (OBJECTS);
-
 	RK_ASSERT (object);
 	RK_ASSERT (object->getContainer ());
 
@@ -97,28 +90,53 @@
 		beginRemoveRows (object_index, object_row, object_row);
 	}
 
-	if (!updates_locked) sendListenerNotification (RObjectListener::ObjectRemoved, object, 0, 0);
+	if (!updates_locked) sendListenerNotification (RObjectListener::ObjectRemoved, object, 0, 0, 0);
 
-	if (delete_obj) object->remove (removed_in_workspace);
-	else object->getContainer ()->removeChildNoDelete (object);
+	object->remove (removed_in_workspace);
 
 	if (!updates_locked) endRemoveRows ();
+
+	return true;
 }
 
+void RKModificationTracker::moveObject (RContainerObject *parent, RObject* child, int old_index, int new_index) {
+	RK_TRACE (OBJECTS);
+
+	QModelIndex parent_index;
+
+	if (!updates_locked) {
+		parent_index = indexFor (parent->getContainer ());
+		beginRemoveRows (parent_index, old_index, old_index);
+	}
+	RK_ASSERT (parent->findChildByIndex (old_index) == child);
+	parent->removeChildNoDelete (child);
+	if (!updates_locked) {
+		endRemoveRows ();
+
+		beginInsertRows (parent_index, new_index, new_index);
+	}
+	parent->insertChild (child, new_index);
+	RK_ASSERT (parent->findChildByIndex (new_index) == child);
+	if (!updates_locked) {
+		endInsertRows ();
+		sendListenerNotification (RObjectListener::ChildMoved, parent, old_index, new_index, 0);
+	}
+}
+
 void RKModificationTracker::renameObject (RObject *object, const QString &new_name) {
 	RK_TRACE (OBJECTS);
 
 	object->rename (new_name);
 
 	if (!updates_locked) {
-		sendListenerNotification (RObjectListener::MetaChanged, object, 0, 0);
+		sendListenerNotification (RObjectListener::MetaChanged, object, 0, 0, 0);
 
 		QModelIndex object_index = indexFor (object);
 		emit (dataChanged (object_index, object_index));
 	}
 }
 
-void RKModificationTracker::addObject (RObject *object, RContainerObject* parent, int position, RKEditor *editor) {
+void RKModificationTracker::addObject (RObject *object, RContainerObject* parent, int position) {
 	RK_TRACE (OBJECTS);
 
 	if (!updates_locked) {
@@ -129,7 +147,7 @@
 	parent->insertChild (object, position);
 
 	if (!updates_locked) {
-		sendListenerNotification (RObjectListener::ChildAdded, parent, position, 0);
+		sendListenerNotification (RObjectListener::ChildAdded, parent, position, 0, 0);
 		endInsertRows ();
 	}
 }
@@ -138,7 +156,7 @@
 	RK_TRACE (OBJECTS);
 
 	if (!updates_locked) {
-		sendListenerNotification (RObjectListener::MetaChanged, object, 0, 0);
+		sendListenerNotification (RObjectListener::MetaChanged, object, 0, 0, 0);
 
 		QModelIndex object_index = indexFor (object);
 		emit (dataChanged (object_index, object_index));
@@ -149,7 +167,7 @@
 	RK_TRACE (OBJECTS);
 
 	if (!updates_locked) {
-		sendListenerNotification (RObjectListener::DataChanged, object, 0, changes);
+		sendListenerNotification (RObjectListener::DataChanged, object, 0, 0, changes);
 		delete changes;
 
 		QModelIndex object_index = indexFor (object);
@@ -173,7 +191,7 @@
 	if (listener->listenerType () == RObjectListener::DataModel) object->endEdit ();
 }
 
-void RKModificationTracker::sendListenerNotification (RObjectListener::NotificationType type, RObject* o, int index, RObject::ChangeSet* changes) {
+void RKModificationTracker::sendListenerNotification (RObjectListener::NotificationType type, RObject* o, int index, int new_index, RObject::ChangeSet* changes) {
 	RK_TRACE (OBJECTS);
 
 	QList<RObjectListener*> obj_listeners = listeners.values (o);
@@ -185,6 +203,8 @@
 			listener->objectRemoved (o);
 		} else if (type == RObjectListener::ChildAdded) {
 			listener->childAdded (index, o);
+		} else if (type == RObjectListener::ChildMoved) {
+			listener->childMoved (index, new_index, o);
 		} else if (type == RObjectListener::MetaChanged) {
 			listener->objectMetaChanged (o);
 		} else if (type == RObjectListener::DataChanged) {
@@ -328,11 +348,11 @@
 
 ///////////////////// RObjectListener ////////////////////////
 
-RObjectListener::RObjectListener (ListenerType type, int notifications) {
+RObjectListener::RObjectListener (ListenerType type) {
 	RK_TRACE (OBJECTS);
 
 	RObjectListener::type = type;
-	RObjectListener::notifications = notifications;
+	notifications = 0;
 	num_watched_objects = 0;
 }
 
@@ -343,19 +363,23 @@
 }
 
 void RObjectListener::objectRemoved (RObject*) {
-	RK_ASSERT (false);
+	RK_ASSERT (false);	// listeners that receive this notification should have reimplemented this function
 }
 
 void RObjectListener::childAdded (int, RObject*) {
-	RK_ASSERT (false);
+	RK_ASSERT (false);	// listeners that receive this notification should have reimplemented this function
 }
 
+void RObjectListener::childMoved (int, int, RObject*) {
+	RK_ASSERT (false);	// listeners that receive this notification should have reimplemented this function
+}
+
 void RObjectListener::objectMetaChanged (RObject*) {
-	RK_ASSERT (false);
+	RK_ASSERT (false);	// listeners that receive this notification should have reimplemented this function
 }
 
 void RObjectListener::objectDataChanged (RObject*, const RObject::ChangeSet *) {
-	RK_ASSERT (false);
+	RK_ASSERT (false);	// listeners that receive this notification should have reimplemented this function
 }
 
 void RObjectListener::listenForObject (RObject* object) {

Modified: branches/KDE4_port/rkward/core/rkmodificationtracker.h
===================================================================
--- branches/KDE4_port/rkward/core/rkmodificationtracker.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/rkmodificationtracker.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -34,8 +34,9 @@
 	enum NotificationType {
 		ObjectRemoved=1,
 		ChildAdded=2,
-		MetaChanged=4,
-		DataChanged=8
+		ChildMoved=4,	/** < a child has changed its position (index) *within* the parent */
+		MetaChanged=8,
+		DataChanged=16
 	};
 	enum ListenerType {
 		DataModel,	/** < listener is an RKVarEditModel */
@@ -46,7 +47,7 @@
 	ListenerType listenerType () const { return type; };
 	bool wantsNotificationType (NotificationType type) const { return (notifications & type); };
 protected:
-	RObjectListener (ListenerType type, int notifications);
+	RObjectListener (ListenerType type);
 	virtual ~RObjectListener ();
 
 friend class RKModificationTracker;
@@ -54,6 +55,8 @@
 	virtual void objectRemoved (RObject* removed);
 	/** reimplement this, if you are listening for an object with notification type ChildAdded. The default implementation does nothing and raises an assert */
 	virtual void childAdded (int index, RObject* parent);
+	/** reimplement this, if you are listening for an object with notification type ChildMoved. The default implementation does nothing and raises an assert. The child is to be found at new_index at the time the notification is sent. */
+	virtual void childMoved (int old_index, int new_index, RObject* parent);
 	/** reimplement this, if you are listening for an object with notification type MetaChanged. The default implementation does nothing and raises an assert */
 	virtual void objectMetaChanged (RObject* changed);
 	/** reimplement this, if you are listening for an object with notification type DataChanged. The default implementation does nothing and raises an assert */
@@ -111,12 +114,10 @@
 
 	~RKModificationTracker ();
 	
-/** the given object should be removed (either it was removed in the R-workspace, or the user requests removal of the object in an editor or the RObjectList). First, if the object is being edited somewhere, the user will get a chance to object to the removal. If the user does not object, the RKModificationTracker will remove the object and notify all editors/objectlists that the object really was removed. When calling from the RObjectList, you will likely set removed_in_workspace to true, to signal that the object-data is already gone in the workspace. */
+/** the given object should be removed (either it was removed in the R-workspace, or the user requests removal of the object in an editor or the RObjectList). First, if the object is being edited somewhere, the user will get a chance to object to the removal. If the user does not object, the RKModificationTracker will remove the object and notify all interested listeners that the object really was removed. When calling from the RObjectList, you will likely set removed_in_workspace to true, to signal that the object-data is already gone in the workspace. */
 	bool removeObject (RObject *object, RKEditor *editor=0, bool removed_in_workspace=false);
 /** essentially like the above function, but requests a renaming of the object. Will also take care of finding out, whether the name is valid and promting for a different name otherwise. */
 	void renameObject (RObject *object, const QString &new_name);
-/** essentially like the above function(s). All objects editing a parent of the new objects are notified of the addition. */
-	void addObject (RObject *object, RContainerObject* parent, int position, RKEditor *editor=0);
 /** the object's meta data was modified. Tells all editors and lists containing the object to update accordingly. */
 	void objectMetaChanged (RObject *object);
 /** the object's data was modified. Tells all editors and lists containing the object to update accordingly. The ChangeSet given tells which parts of the data have to be updated. The ChangeSet will get deleted by the RKModificationTracker, when done. */
@@ -128,7 +129,7 @@
 private:
 	int updates_locked;
 /** relay change notifications to connected listeners. This is not pretty, since the arguments change their meanings depending on the type of notification, but for now this is ok */
-	void sendListenerNotification (RObjectListener::NotificationType type, RObject* o, int index, RObject::ChangeSet* changes);
+	void sendListenerNotification (RObjectListener::NotificationType type, RObject* o, int index, int new_index, RObject::ChangeSet* changes);
 
 friend class RObjectListener;
 	void addObjectListener (RObject* object, RObjectListener* listener);
@@ -136,8 +137,11 @@
 	QMultiHash<RObject*, RObjectListener*> listeners;
 
 friend class RContainerObject;
-/** uncondiontally remove the given object. Do *not* call this except from RContainerObject::moveChild() or internally from removeObject(). Call removeObject(), instead. */
-	void internalRemoveObject (RObject *object, bool removed_in_workspace, bool delete_obj);
+friend class RObjectList;
+/** essentially like the above function(s). All objects listening for child additions on the parent will be notified */
+	void addObject (RObject *object, RContainerObject* parent, int position);
+/** essentially like the above function(s). All objects listening for child position changed on the parent will be notified */
+	void moveObject (RContainerObject *parent, RObject* child, int old_index, int new_index);
 };
 
 #endif

Modified: branches/KDE4_port/rkward/core/robjectlist.cpp
===================================================================
--- branches/KDE4_port/rkward/core/robjectlist.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/robjectlist.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -209,10 +209,10 @@
 	return 0;
 }
 
-RObject *RObjectList::createNewChild (const QString &name, int position, RKEditor *creator, bool container, bool data_frame) {
+RObject *RObjectList::createPendingChild (const QString &name, int position, bool container, bool data_frame) {
 	RK_TRACE (OBJECTS);
-
-	return (getGlobalEnv ()->createNewChild (name, position, creator, container, data_frame));
+#warning TODO: this is bad style. Callers should call this on getGlobalEnv() directly.
+	return (getGlobalEnv ()->createPendingChild (name, position, container, data_frame));
 }
 
 QString RObjectList::validizeName (const QString &child_name, bool unique) const {

Modified: branches/KDE4_port/rkward/core/robjectlist.h
===================================================================
--- branches/KDE4_port/rkward/core/robjectlist.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/core/robjectlist.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -59,7 +59,7 @@
 	void findObjectsMatching (const QString &partial_name, RObjectSearchMap *current_list, bool name_is_canonified=false) const;
 
 	/** reimplemented from RContainerObject to create the child in the .GlobalEnv */
-	RObject *createNewChild (const QString &name, int position=-1, RKEditor *creator=0, bool container=false, bool data_frame=false);
+	RObject *createPendingChild (const QString &name, int position=-1, bool container=false, bool data_frame=false);
 
 	/** reimplemented from RContainerObject to validize the name in .GlobalEnv */
 	QString validizeName (const QString &child_name, bool unique=true) const;

Modified: branches/KDE4_port/rkward/dataeditor/rkeditor.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditor.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkeditor.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -29,8 +29,9 @@
 class RKDrag;
 
 /**
-Use a a base class for all widgets that can be used to display and edit RObjects of whatever type.
+Use as a base class for all widgets that can be used to display and edit RObjects of whatever type.
 
+// TODO: not sure we really need this any longer
 @author Thomas Friedrichsmeier
 */
 class RKEditor : public RKMDIWindow {
@@ -45,33 +46,14 @@
 /// returns the object that is being edited in this editor
 	RObject *getObject () { return object; };
 	
-/// editing functions:
-	virtual void clearSelected () = 0;
-	virtual RKDrag *makeDrag () = 0;
-	virtual void paste (QByteArray &content) = 0;
 	enum PasteMode {PasteEverywhere, PasteToTable, PasteToSelection};
-	virtual void setPasteMode (PasteMode mode) = 0;
 
-/** Tells the editor to (unconditionally!) remove the object from its list. */
-	virtual void removeObject (RObject *object) = 0;
 /** Tells the editor to restore the given object in the R-workspace from its copy of the data */
 	virtual void restoreObject (RObject *object) = 0;
-/** Tells the editor to (unconditionally!) rename the object (the object already carries the new name, so the editor can read the new name from the object). */
-	virtual void renameObject (RObject *object) = 0;
-/** Tell the editor to (unconditionally) add the given object to its view */
-	virtual void addObject (RObject *object) = 0;
-/** Tell the editor to (unconditionally) update its representation of the object meta data */
-	virtual void updateObjectMeta (RObject *object) = 0;
-/** Tell the editor to (unconditionally) update its representation of the object data (in the range given in the ChangeSet) */
-	virtual void updateObjectData (RObject *object, RObject::ChangeSet *changes) = 0;
 
 	QString getDescription ();
 	bool isModified () { return false; };
 protected:
-friend class RKWorkplace;
-/// opens the given object. Implement in the child-classes
-	virtual void openObject (RObject *object, bool initialize_to_empty) = 0;
-
 	RObject *object;
 };
 

Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -16,6 +16,9 @@
  ***************************************************************************/
 #include "rkeditordataframe.h"
 
+#include <kmessagebox.h>
+#include <klocale.h>
+
 #include "../rbackend/rinterface.h"
 #include "../rkglobals.h"
 #include "twintable.h"
@@ -23,34 +26,69 @@
 #include "twintabledatamember.h"
 #include "twintablemetamember.h"
 #include "../core/robject.h"
+#include "../core/robjectlist.h"
 #include "../core/rkvariable.h"
 #include "../core/rcontainerobject.h"
 #include "../core/rkmodificationtracker.h"
 #include "rkeditordataframepart.h"
 #include "../windows/rkworkplace.h"
+#include "../misc/rkstandardicons.h"
 
 #include "../debug.h"
 
-#define GET_NAMES_COMMAND 1
-#define LOAD_COMPLETE_COMMAND 2
+#define LOAD_COMPLETE_COMMAND 1
 // warning! numbers above GET_DATA_OFFSET are used to determine, which row, the data should go to!
 #define GET_DATA_OFFSET 10
 
-RKEditorDataFrame::RKEditorDataFrame (QWidget *parent, KParts::Part* part) : TwinTable (parent) {
+RKEditorDataFrame::RKEditorDataFrame (RObject* object, QWidget *parent) : TwinTable (parent) {
 	RK_TRACE (EDITOR);
 
-	setPart (part);
+	commonInit ();
+
+	RK_ASSERT (!object->isPending ());
+	openObject (object);
+}
+
+RKEditorDataFrame::RKEditorDataFrame (const QString& new_object_name, QWidget* parent) : TwinTable (parent) {
+	RK_TRACE (EDITOR);
+
+	commonInit ();
+
+	QString valid = RObjectList::getObjectList ()->validizeName (new_object_name);
+	if (valid != new_object_name) KMessageBox::sorry (this, i18n ("The name you specified was already in use or not valid. Renamed to %1", valid), i18n ("Invalid Name"));
+	RObject *object = RObjectList::getObjectList ()->createPendingChild (valid, -1, true, true);
+
+// initialize the new object
+#warning TODO: call model->insertColumns() instead.
+	for (int i=0; i < numTrueCols (); ++i) {
+		RObject *child = static_cast<RContainerObject *> (object)->createPendingChild (static_cast<RContainerObject *> (object)->validizeName (QString ()), i);
+		if (child->isVariable ()) {
+			static_cast<RKVariable*> (child)->setLength (dataview->numTrueRows ());
+		} else {
+			RK_ASSERT (false);
+		}
+	}
+	pushTable (open_chain);
+
+	openObject (object);
+}
+
+void RKEditorDataFrame::commonInit () {
+	RK_TRACE (EDITOR);
+
+	setPart (new RKEditorDataFramePart (parent (), this));
 	initializeActivationSignals ();
 
-	open_chain = 0;
+	setCaption (object->getShortName ());
+	setWindowIcon (RKStandardIcons::iconForWindow (this));
+
+	open_chain = RKGlobals::rInterface ()->startChain (0);
 }
 
 void RKEditorDataFrame::enableEditing (bool on) {
 	if (on) {
 		connect (this, SIGNAL (deleteColumnRequest (int)), this, SLOT (columnDeletionRequested (int)));
 		connect (this, SIGNAL (addedColumn (int)), this, SLOT (columnAdded (int)));
-		connect (this, SIGNAL (dataAddingRow (int)), this, SLOT (aboutToAddRow (int)));
-		connect (this, SIGNAL (dataRemovingRow (int)), this, SLOT (aboutToRemoveRow (int)));
 		varview->setEnabled (true);
 		dataview->setEnabled (true);
 	} else {
@@ -58,8 +96,6 @@
 		dataview->setEnabled (false);
 		disconnect (this, SIGNAL (deleteColumnRequest (int)), this, SLOT (columnDeletionRequested (int)));
 		disconnect (this, SIGNAL (addedColumn (int)), this, SLOT (columnAdded (int)));
-		disconnect (this, SIGNAL (dataAddingRow (int)), this, SLOT (aboutToAddRow (int)));
-		disconnect (this, SIGNAL (dataRemovingRow (int)), this, SLOT (aboutToRemoveRow (int)));
 	}
 }
 
@@ -72,80 +108,29 @@
 	flushEdit ();
 }
 
-void RKEditorDataFrame::openObject (RObject *object, bool initialize_to_empty) {
+void RKEditorDataFrame::openObject (RObject *object) {
 	RK_TRACE (EDITOR);
 	flushEdit ();
 	RKEditor::object = object;
-	if (initialize_to_empty) {
-//		object->setCreatedInEditor (this);
-	} else {
-//		object->setObjectOpened (this, true);
-	}
+	RK_ASSERT (object->isDataFrame ());
 
 	enableEditing (false);
-	open_chain = RKGlobals::rInterface ()->startChain (open_chain);
 
-	if (initialize_to_empty) {
-		for (int i=0; i < numTrueCols (); ++i) {
-			RObject *obj = static_cast<RContainerObject *> (getObject ())->createNewChild (static_cast<RContainerObject *> (getObject ())->validizeName ("var"), i, this);
-			if (obj->isVariable ()) {
-				static_cast<RKVariable*> (obj)->setLength (dataview->numTrueRows ());
-				setColObject (i, static_cast<RKVariable*> (obj));
-//				obj->setCreatedInEditor (this);
-			} else {
-				RK_ASSERT (false);
-			}
-		}
-		pushTable (open_chain);
-	}
-
 	// trigger fetching of the edit data
 	object->markDataDirty ();
 	object->updateFromR (open_chain);
-	// KDE4 TODO: this is no longer needed, as objects can now be addressed by their position in the parent
-	// actually, given the object, we already know the child-names. We don't know their order, however, so we better fetch the name-row again.
-	RCommand *command = new RCommand ("names (" + object->getFullName () + ')', RCommand::Sync | RCommand::GetStringVector, QString::null, this, GET_NAMES_COMMAND);
-	RKGlobals::rInterface ()->issueCommand (command, open_chain);
 
-	// since communication is asynchronous, the rest is done inside
-	// processROutput!
+	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand | RCommand::Sync | RCommand::GetStringVector, QString (), this, LOAD_COMPLETE_COMMAND);
+	RKGlobals::rInterface ()->issueCommand (command, open_chain);
 }
 
 void RKEditorDataFrame::rCommandDone (RCommand *command) {
 	RK_TRACE (EDITOR);
 
-	if (command->getFlags () == GET_NAMES_COMMAND) {
-		int len = command->getDataLength ();
-		while (len < numTrueCols ()) {	// get rid of superficial columns
-			deleteColumn (0);
-		}
-
-		RK_ASSERT (len);
-
-		// set the names and meta-information
-		for (int col = 0; col < len; ++col) {
-			if (numTrueCols () <= col) {
-				insertNewColumn ();
-			}
-			RKVariable *current_child = static_cast<RKVariable *> (static_cast <RContainerObject*> (getObject ())->findChildByName (command->getStringVector ()[col]));
-			RK_ASSERT (current_child);
-			if (current_child->isVariable ()) {
-				if (!getColObject (col)) {		// if we initialized the table to empty, the object may already exist in our map
-					setColObject (col, current_child);
-//					current_child->setObjectOpened (this, true);
-				} else {
-					RK_ASSERT (getColObject (col) == current_child);
-				}
-			} else {
-				RK_ASSERT (false);
-			}
-		}
-
+	if (command->getFlags () == LOAD_COMPLETE_COMMAND) {
 		RKGlobals::rInterface ()->closeChain (open_chain);
-		/* make sure enough rows are displayed. Note: Calling QTable::insertRows, since no data should be juggled around, only the number of visible rows is to be changed. */
-		if (dataview->numTrueRows () < getColObject (0)->getLength ()) {
-			dataview->Q3Table::insertRows (0, getColObject (0)->getLength () - dataview->numTrueRows ());
-		}
+		open_chain = 0;
+
 		enableEditing (true);
 	}
 }
@@ -154,7 +139,7 @@
 	RK_TRACE (EDITOR);
 	flushEdit ();
 	QString command;
-
+#warning TODO: move to model
 	// first push the data-table
 	TwinTableMember *table = dataview;
 	command = getObject ()->getFullName ();
@@ -186,37 +171,6 @@
 	RKGlobals::tracker ()->removeObject (obj);
 }
 
-void RKEditorDataFrame::columnAdded (int col) {
-	RK_TRACE (EDITOR);
-	RObject *obj = static_cast<RContainerObject *> (getObject ())->createNewChild (static_cast<RContainerObject *> (getObject ())->validizeName (QString ()), col, this);
-	RK_ASSERT (obj->isVariable ());
-	RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.column (" + getObject ()->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1) + ")", RCommand::App | RCommand::Sync));
-	static_cast<RKVariable*> (obj)->setLength (dataview->numTrueRows ());
-//	obj->setCreatedInEditor (this);
-
-	// TODO: find a nice way to update the list:
-	RK_ASSERT (col <= (numTrueCols () - 1));
-	for (int i=numTrueCols () - 1; i > col; --i) {
-		setColObject (i, getColObject (i-1));
-	}
-	if (obj->isVariable ()) {
-		setColObject (col, static_cast<RKVariable*> (obj));
-	} else {
-		RK_ASSERT (false);
-	}
-
-}
-
-void RKEditorDataFrame::aboutToAddRow (int row) {
-	RK_TRACE (EDITOR);
-	RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.row (" + getObject ()->getFullName () + ", " + QString ().setNum (row+1) + ')', RCommand::App | RCommand::Sync));
-}
-
-void RKEditorDataFrame::aboutToRemoveRow (int row) {
-	RK_TRACE (EDITOR);
-	RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.delete.row (" + getObject ()->getFullName () + ", " + QString ().setNum (row+1) + ')', RCommand::App | RCommand::Sync));
-}
-
 void RKEditorDataFrame::removeObject (RObject *object) {
 	RK_TRACE (EDITOR);
 	if (object == getObject ()) {
@@ -262,27 +216,6 @@
 	varview->updateCell (NAME_ROW, col);
 }
 
-void RKEditorDataFrame::addObject (RObject *object) {
-	RK_TRACE (EDITOR);
-	
-	enableEditing (false);
-	insertNewColumn ();
-	if (object->isVariable ()) {
-		setColObject (numTrueCols () - 1, static_cast<RKVariable*> (object));
-//		object->setObjectOpened (this, true);
-	} else {
-		RK_ASSERT (false);
-	}
-
-	enableEditing (true);
-	
-	updateObjectMeta (object);
-	RObject::ChangeSet *set = new RObject::ChangeSet;
-	set->from_index = -1;
-	set->to_index = -1;
-	RKGlobals::tracker ()->objectDataChanged (object, set);
-}
-
 void RKEditorDataFrame::updateObjectMeta (RObject *object) {
 	RK_TRACE (EDITOR);
 	if (object == getObject ()) return;	// for now: can't update meta on the table itself

Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -32,13 +32,18 @@
 */
 class RKEditorDataFrame : public TwinTable, public RCommandReceiver {
 	Q_OBJECT
-protected:
-friend class RKEditorDataFramePart;
-/** constructor. Protected as you should not create an RKEditorDataFrame directly. Create an RKEditorDataFramePart instead. */
-	RKEditorDataFrame (QWidget *parent, KParts::Part* part);
+public:
+/** constructor.
+ at param object an existing R object
+ at param parent parent widget */
+	RKEditorDataFrame (RObject* object, QWidget *parent);
+/** This constructor creates a new (empty) data.frame with the given name and then opens it for editing.
+ at param new_object_name name of the new data.frame
+ at param parent parent widget */
+	RKEditorDataFrame (const QString& new_object_name, QWidget *parent);
 /** destructor */
 	~RKEditorDataFrame ();
-public:
+
 	void flushChanges ();
 	
 	//void objectDeleted (RObject *object);
@@ -50,27 +55,23 @@
 	void restoreObject (RObject *object);
 /** Tells the editor to (unconditionally!) rename the object (the object already carries the new name, so the editor can read the new name from the object). */
 	void renameObject (RObject *object);
-/** Tell the editor to (unconditionally) add the given object to its view */
-	void addObject (RObject *object);
 /** Tell the editor to (unconditionally) update its representation of the object meta data */
 	void updateObjectMeta (RObject *object);
 /** Tell the editor to (unconditionally) update its representation of the object data (in the range given in the ChangeSet) */
 	void updateObjectData (RObject *object, RObject::ChangeSet *changes);
 public slots:
 	void columnDeletionRequested (int col);
-	void columnAdded (int col);
-	void aboutToAddRow (int row);
-	void aboutToRemoveRow (int row);
 private:
 /// syncs the whole table.
 	void pushTable (RCommandChain *sync_chain);
+	void commonInit ();
 	RCommandChain *open_chain;
 	void enableEditing (bool on);
 	void updateMetaValue (RObject *obj, int row, int col, bool sync=true);
 
 	void modifyObjectMeta (RObject *object, int column);
 protected:
-	void openObject (RObject *object, bool initialize_to_empty=false);
+	void openObject (RObject *object);
 	void rCommandDone (RCommand *command);
 };
 

Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -2,7 +2,7 @@
                           rkeditordataframepart  -  description
                              -------------------
     begin                : Wed Sep 14 2005
-    copyright            : (C) 2005, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -28,11 +28,11 @@
 #include "../rkward.h"
 #include "../debug.h"
 
-RKEditorDataFramePart::RKEditorDataFramePart (QWidget *parent) : KParts::Part (parent) {
+RKEditorDataFramePart::RKEditorDataFramePart (QObject *parent, RKEditorDataFrame* editor) : KParts::Part (parent) {
 	RK_TRACE (EDITOR);
 	setComponentData (KGlobal::mainComponent ());
  
-	editor = new RKEditorDataFrame (parent, this);
+	RKEditorDataFramePart::editor = editor;
 	setWidget (editor);
 
 	setXMLFile ("rkeditordataframepart.rc");
@@ -84,25 +84,22 @@
 void RKEditorDataFramePart::slotEditPaste() {
 	RK_TRACE (EDITOR);
 	
-	editor->setPasteMode (RKEditor::PasteEverywhere);
-	doPaste ();
+	doPaste (RKEditor::PasteEverywhere);
 }
 
 void RKEditorDataFramePart::slotEditPasteToTable() {
 	RK_TRACE (EDITOR);
 	
-	editor->setPasteMode (RKEditor::PasteToTable);
-	doPaste ();
+	doPaste (RKEditor::PasteToTable);
 }
 
 void RKEditorDataFramePart::slotEditPasteToSelection() {
 	RK_TRACE (EDITOR);
 	
-	editor->setPasteMode (RKEditor::PasteToSelection);
-	doPaste ();
+	doPaste (RKEditor::PasteToSelection);
 }
 
-void RKEditorDataFramePart::doPaste () {
+void RKEditorDataFramePart::doPaste (RKEditor::PasteMode mode) {
 	RK_TRACE (EDITOR);
 
 	RKWardMainWindow::getMain ()->slotSetStatusBarText(i18n("Inserting clipboard contents..."));
@@ -113,11 +110,11 @@
 	if (QApplication::clipboard()->data()->provides ("text/tab-separated-values")) {
 		RK_DO (qDebug ("paste tsv"), EDITOR, DL_DEBUG);
 		QByteArray data = QApplication::clipboard()->data()->encodedData ("text/tab-separated-values");
-		editor->paste (data);
+		editor->paste (data, mode);
 	} else if (QApplication::clipboard()->data()->provides ("text/plain")) {
-		RK_DO (qDebug ("paste plaing"), EDITOR, DL_DEBUG);
+		RK_DO (qDebug ("paste plain text"), EDITOR, DL_DEBUG);
 		QByteArray data = QApplication::clipboard()->data()->encodedData ("text/plain");
-		editor->paste (data);
+		editor->paste (data, mode);
 	}
 
 	RKWardMainWindow::getMain ()->slotSetStatusReady ();

Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -2,7 +2,7 @@
                           rkeditordataframepart  -  description
                              -------------------
     begin                : Wed Sep 14 2005
-    copyright            : (C) 2005 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -20,6 +20,8 @@
 
 #include <kparts/part.h>
 
+#include "rkeditor.h"
+
 class RKEditorDataFrame;
 class KAction;
 
@@ -29,9 +31,11 @@
 */
 class RKEditorDataFramePart : public KParts::Part {
 	Q_OBJECT
-public:
-	explicit RKEditorDataFramePart (QWidget *parent);
-
+protected:
+friend class RKEditorDataFrame;
+/** ctor. Protected, as this should only be created by an RKEditorDataFrame */
+	RKEditorDataFramePart (QObject *parent, RKEditorDataFrame* editor);
+/** dtor */
 	~RKEditorDataFramePart ();
 public slots:
 /** put the marked cells into the clipboard and remove them from the table */
@@ -45,7 +49,7 @@
 /** paste the clipboard into the table, but not beyond selection boundaries	*/
 	void slotEditPasteToSelection();
 /** return a pointer to the underlying editor widget */
-	RKEditorDataFrame *getEditor () { return editor; };
+	RKEditorDataFrame *getEditor () const { return editor; };
 private:
 	QAction* editCut;
 	QAction* editCopy;
@@ -59,7 +63,7 @@
 	void initializeActions ();
 
 /** Does pasting (called from the respective slots) */
-	void doPaste ();
+	void doPaste (RKEditor::PasteMode mode);
 };
 
 #endif

Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -21,16 +21,21 @@
 
 #include "../core/rcontainerobject.h"
 #include "../core/rkmodificationtracker.h"
+#include "../rbackend/rinterface.h"
 #include "../rkglobals.h"
 
 #include "../debug.h"
 
-RKVarEditModel::RKVarEditModel (QObject *parent) : QAbstractTableModel (parent), RObjectListener (RObjectListener::DataModel, RObjectListener::ObjectRemoved) {
+RKVarEditModel::RKVarEditModel (QObject *parent) : QAbstractTableModel (parent), RObjectListener (RObjectListener::DataModel) {
 	RK_TRACE (EDITOR);
 
 	meta_model = 0;
 	trailing_rows = trailing_cols = 0;
 	edit_blocks = 0;
+
+	addNotificationType (RObjectListener::ObjectRemoved);
+#warning TODO: listen for data changes
+#warning TODO: listen for meta changes
 }
 
 RKVarEditModel::~RKVarEditModel () {
@@ -97,8 +102,10 @@
 
 	beginInsertRows (QModelIndex (), row, row+count);
 	for (int i=0; i < objects.size (); ++i) {
+// TODO: this does not emit any data change notifications to other editors
 		objects[i]->insertRows (row, count);
 	}
+	doInsertRowsInBackend (row, count);
 	endInsertRows ();
 
 	return true;
@@ -118,13 +125,29 @@
 
 	beginRemoveRows (QModelIndex (), row, lastrow);
 	for (int i=0; i < objects.size (); ++i) {
+// TODO: this does not emit any data change notifications to other editors
 		objects[i]->removeRows (row, lastrow);
 	}
+	doRemoveRowsInBackend (row, lastrow - row + 1);
 	endRemoveRows ();
 
 	return true;
 }
 
+void RKVarEditModel::doInsertRowsInBackend (int, int) {
+	RK_TRACE (EDITOR);
+
+	// TODO: implement
+	RK_ASSERT (false);
+}
+
+void RKVarEditModel::doRemoveRowsInBackend (int, int) {
+	RK_TRACE (EDITOR);
+
+	// TODO: implement
+	RK_ASSERT (false);
+}
+
 int RKVarEditModel::rowCount (const QModelIndex& parent) const {
 	RK_TRACE (EDITOR);
 
@@ -421,6 +444,7 @@
 	trailing_cols = 1;
 
 	addNotificationType (RObjectListener::ChildAdded);
+	addNotificationType (RObjectListener::ChildMoved);
 	listenForObject (dataframe);
 
 	for (int i = 0; i < dataframe->numChildren (); ++i) {
@@ -440,22 +464,56 @@
 bool RKVarEditDataFrameModel::insertColumns (int column, int count, const QModelIndex& parent) {
 	RK_TRACE (EDITOR);
 
-/*	RObject *obj = static_cast<RContainerObject *> (getObject ())->createNewChild (static_cast<RContainerObject *> (getObject ())->validizeName (QString ()), col, this);
-	RK_ASSERT (obj->isVariable ());
-	RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.column (" + getObject ()->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1) + ")", RCommand::App | RCommand::Sync));
-	static_cast<RKVariable*> (obj)->setLength (dataview->numTrueRows ());
-	obj->setCreatedInEditor (this); */
+	if (parent.isValid ()) {
+		RK_ASSERT (false);
+		return false;
+	}
 
-#warning TODO implement
+	for (int col = column; col < (column + count); ++col) {
+		RObject *obj = dataframe->createPendingChild (dataframe->validizeName (QString ()), col);
+		RK_ASSERT (obj->isVariable ());
+		if (!objects.isEmpty ()) static_cast<RKVariable*> (obj)->setLength (objects[0]->getLength ());
+//		addObject (col, obj);	// the object will be added via RKModificationTracker::addObject -> this::childAdded. That will also take care of calling beginInsertColumns()/endInsertColumns()
+	
+		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.column (" + dataframe->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1) + ")", RCommand::App | RCommand::Sync));
+	}
+
+	return true;
 }
 
 bool RKVarEditDataFrameModel::removeColumns (int column, int count, const QModelIndex& parent) {
 	RK_TRACE (EDITOR);
 
-/*	RKGlobals::tracker ()->removeObject (obj); */
-#warning TODO implement
+	if (parent.isValid ()) {
+		RK_ASSERT (false);
+		return false;
+	}
+
+	while ((column + count) > objects.size ()) --count;
+	for (int i = column + count - 1; i >= column; --i) {	// we start at the end so that the index remains valid
+		RKGlobals::tracker ()->removeObject (objects[i]);
+		// the comment in insertColumns, above: The object will be removed from our list in objectRemoved().
+	}
+	return true;
 }
 
+void RKVarEditDataFrameModel::doInsertRowsInBackend (int row, int count) {
+	RK_TRACE (EDITOR);
+
+	// TODO: most of the time we're only adding one row at a time, still we should have a function to add multiple rows at once.
+	for (int i = row; i < row + count; ++i) {
+		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
+	}
+}
+
+void RKVarEditDataFrameModel::doRemoveRowsInBackend (int row, int count) {
+	RK_TRACE (EDITOR);
+
+	for (int i = row + count - 1; i >= row; --i) {
+		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.delete.row (" + dataframe->getFullName () + ", " + QString::number (i+1) + ')', RCommand::App | RCommand::Sync));
+	}
+}
+
 void RKVarEditDataFrameModel::objectRemoved (RObject* object) {
 	RK_TRACE (EDITOR);
 
@@ -481,6 +539,26 @@
 	}
 }
 
+void RKVarEditDataFrameModel::childMoved (int old_index, int new_index, RObject* parent) {
+	RK_TRACE (EDITOR);
+
+	if (parent == dataframe) {
+		RObject *child = dataframe->findChildByIndex (new_index);	// it's at the new position, already
+		RK_ASSERT (objects.size () > old_index);
+		RK_ASSERT (child == objects[old_index]);
+		// if an object has changed position, there should be at least two objects left. Hence, the objectRemoved-call will never lead to editor destruction
+		RK_ASSERT (objects.size () >= 2);
+		objectRemoved (child);
+
+		RK_ASSERT (child->isVariable ());
+		addObject (new_index, static_cast<RKVariable*> (child));
+	} else {
+		// even though we are listening for the child objects as well, we should see move notifications
+		// only for children of the parent.
+		RK_ASSERT (false);
+	}
+}
+
 void RKVarEditDataFrameModel::doInsertColumn (int index) {
 	RK_TRACE (EDITOR);
 

Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -70,6 +70,9 @@
 	/** insert a new column at index. Default implementation does nothing. To be implemented in subclasses */
 	virtual void doInsertColumn (int index);
 
+	virtual void doInsertRowsInBackend (int row, int count);
+	virtual void doRemoveRowsInBackend (int row, int count);
+
 	int trailing_rows;
 	int trailing_cols;
 
@@ -127,7 +130,12 @@
 	void objectRemoved (RObject* object);
 	/** receives notifications of new objects added to this data.frame */
 	void childAdded (int index, RObject* parent);
+	/** receives notifications of object position changes inside this data.frame */
+	void childMoved (int old_index, int new_index, RObject* parent);
 
+	void doInsertRowsInBackend (int row, int count);
+	void doRemoveRowsInBackend (int row, int count);
+
 	RContainerObject* dataframe;
 };
 

Modified: branches/KDE4_port/rkward/dataeditor/twintable.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintable.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/twintable.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -333,7 +333,7 @@
 	}
 }
 
-void TwinTable::paste (QByteArray &content) {
+void TwinTable::paste (QByteArray &content, RKEditor::PasteMode paste_mode) {
 	RK_TRACE (EDITOR);
 
 	flushEdit ();
@@ -429,11 +429,6 @@
 	table->blankSelected ();
 }
 
-void TwinTable::setPasteMode (RKEditor::PasteMode mode) {
-	RK_TRACE (EDITOR);
-	paste_mode = mode;
-}
-
 void TwinTable::setRow (TwinTableMember* table, int row, int start_col, int end_col, char **data) {
 	RK_TRACE (EDITOR);
 

Modified: branches/KDE4_port/rkward/dataeditor/twintable.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintable.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/dataeditor/twintable.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -60,7 +60,7 @@
 /** Inserts the row at the given position (or at the end for -1) in the given table. Don't try to do this in the varview, yet! */
 	void deleteRow (int where, TwinTableMember *table=0);
 /** Pastes content to the current table */
-	void paste (QByteArray &content);
+	void paste (QByteArray &content, RKEditor::PasteMode paste_mode);
 /** Same as above, but flips the data (i.e. row <-> cols) */
 //	void pasteEncodedFlipped (QByteArray content);
 /** Clear the currently selected cells */
@@ -73,7 +73,6 @@
 /** Returns the number of (true) columns in the tables. See TwinTableMember::numTrueCols () */
 	int numTrueCols ();
 	
-	void setPasteMode (RKEditor::PasteMode mode);
 	TwinTableMetaMember* varview;
 	TwinTableDataMember* dataview;
 /** get the object at the given column (0 if there is no object for the column) */
@@ -100,8 +99,6 @@
 /** position (row or col) the header_menu is operating on */
 	int header_pos;
 
-	RKEditor::PasteMode paste_mode;
-
 	typedef Q3IntDict<RKVariable> ColMap;
 	ColMap col_map;
 protected:	

Modified: branches/KDE4_port/rkward/misc/rkstandardicons.cpp
===================================================================
--- branches/KDE4_port/rkward/misc/rkstandardicons.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/misc/rkstandardicons.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -60,6 +60,7 @@
 
 	// windows
 #warning TODO icons for windows
+	icons[WindowDataFrameEditor] = icons[ObjectDataFrame];
 }
 
 QIcon RKStandardIcons::iconForObject (const RObject* object) {
@@ -94,6 +95,11 @@
 
 QIcon RKStandardIcons::iconForWindow (const RKMDIWindow* window) {
 	// don't trace this
+	if (!window) return QIcon ();
+
+	if (window->isType (RKMDIWindow::DataEditorWindow)) return icons[WindowDataFrameEditor];
+
 #warning TODO
+	RK_ASSERT (false);
 	return QIcon ();
 }

Modified: branches/KDE4_port/rkward/misc/rkstandardicons.h
===================================================================
--- branches/KDE4_port/rkward/misc/rkstandardicons.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/misc/rkstandardicons.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -55,6 +55,8 @@
 		ObjectDataOther,
 		ObjectObjectList,
 
+		WindowDataFrameEditor,
+
 		Last	/**< not really an item, only the count of items available. Do not use. */
 	};
 

Modified: branches/KDE4_port/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- branches/KDE4_port/rkward/plugin/rkcomponentproperties.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/plugin/rkcomponentproperties.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -614,12 +614,15 @@
 #include "../core/rkmodificationtracker.h"
 #include "../misc/rkobjectlistview.h"
 
-RKComponentPropertyRObjects::RKComponentPropertyRObjects (QObject *parent, bool required) : RKComponentPropertyBase (parent, required), RObjectListener (RObjectListener::Other, RObjectListener::ObjectRemoved | RObjectListener::MetaChanged) {
+RKComponentPropertyRObjects::RKComponentPropertyRObjects (QObject *parent, bool required) : RKComponentPropertyBase (parent, required), RObjectListener (RObjectListener::Other) {
 	RK_TRACE (PLUGIN);
 
 // no initial requirements
 	dims = min_length = max_length = min_num_objects = min_num_objects_if_any = max_num_objects = -1;
 	separator = "\n";
+
+	addNotificationType (RObjectListener::ObjectRemoved);
+	addNotificationType (RObjectListener::MetaChanged);
 }
 
 RKComponentPropertyRObjects::~RKComponentPropertyRObjects () {

Modified: branches/KDE4_port/rkward/rkward.cpp
===================================================================
--- branches/KDE4_port/rkward/rkward.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/rkward.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -82,14 +82,14 @@
 #include "agents/showedittextfileagent.h"	// TODO: see below: needed purely for linking!
 #include "dialogs/rkreadlinedialog.h"	// TODO: see below: needed purely for linking!
 #include "windows/detachedwindowcontainer.h"	// TODO: see below: needed purely for linking!
-#include "dataeditor/rkeditordataframepart.h"	// TODO: see below: needed purely for linking!
+#include "dataeditor/rkeditordataframe.h"	// TODO: see below: needed purely for linking!
 #include "agents/rkeditobjectagent.h"	// TODO: see below: needed purely for linking!
 
 // This nevers gets called. It's needed to trick ld into linking correctly. Nothing else.
 void bogusCalls () {
 	ShowEditTextFileAgent::showEditFiles (0);		// TODO: AAAAAAAARGGGH!!!! It won't link without this bogus line!!!
 	RKReadLineDialog::readLine (0, QString(), QString(), 0, 0);	// TODO: see above
-	new RKEditorDataFramePart (0);
+	new RKEditorDataFrame (0, 0);
 	DetachedWindowContainer (0);
 	new RKWorkplaceView (0);
 	new RKEditObjectAgent (QStringList (), 0);
@@ -257,9 +257,7 @@
 		} else if (result->result == StartupDialog::ChoseFile) {
 			slotFileOpenWorkspace ();
 		} else if (result->result == StartupDialog::EmptyTable) {
-			RObject *object = RObjectList::getObjectList ()->createNewChild (i18n ("my.data"), -1, 0, true, true);
-			// usually an explicit call to activateView should not be necessary. Somehow however, here, it is.
-			RKWorkplace::mainWorkplace ()->editObject (object, true);
+			RKWorkplace::mainWorkplace ()->editNewDataFrame (i18n ("my.data"));
 		}
 		delete result;
 	}
@@ -523,13 +521,7 @@
 
 	QString name = KInputDialog::getText (i18n ("New dataset"), i18n ("Enter name for the new dataset"), "my.data", &ok, this);
 
-	if (ok) {
-		QString valid = RObjectList::getObjectList ()->validizeName (name);
-		if (valid != name) KMessageBox::sorry (this, i18n ("The name you specified was already in use or not valid. Renamed to %1", valid), i18n ("Invalid Name"));
-		RObject *object = RObjectList::getObjectList ()->createNewChild (valid, -1, 0, true, true);
-		RKWorkplace::mainWorkplace ()->editObject (object, true);
-	}
-	
+	if (ok) RKWorkplace::mainWorkplace ()->editNewDataFrame (name);
 }
 
 void RKWardMainWindow::fileOpenNoSave (const KUrl &url) {

Modified: branches/KDE4_port/rkward/robjectviewer.cpp
===================================================================
--- branches/KDE4_port/rkward/robjectviewer.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/robjectviewer.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -43,11 +43,13 @@
 #define SUMMARY_COMMAND 1
 #define PRINT_COMMAND 2
 
-RObjectViewer::RObjectViewer (QWidget *parent, RObject *object) : RKMDIWindow (parent, RKMDIWindow::ObjectWindow, false), RObjectListener (RObjectListener::ObjectView, RObjectListener::ObjectRemoved) {
+RObjectViewer::RObjectViewer (QWidget *parent, RObject *object) : RKMDIWindow (parent, RKMDIWindow::ObjectWindow, false), RObjectListener (RObjectListener::ObjectView) {
 // KDE 4: TODO might listen for object meta / data changes as well
 	RK_TRACE (APP);
 	RK_ASSERT (object);
 	_object = object;
+
+	addNotificationType (RObjectListener::ObjectRemoved);
 	listenForObject (_object);
 
 	Q3VBoxLayout *layout = new Q3VBoxLayout (this);

Modified: branches/KDE4_port/rkward/windows/rkmdiwindow.h
===================================================================
--- branches/KDE4_port/rkward/windows/rkmdiwindow.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/windows/rkmdiwindow.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -78,9 +78,11 @@
 	void setCaption (const QString &caption);
 /** Is this window attached (or detached)?
 @returns true if attached, false if detached */
-	bool isAttached () { return (state == Attached); };
+	bool isAttached () const { return (state == Attached); };
 /** Is this a tool window? */
-	bool isToolWindow () { return (type & ToolWindow); };
+	bool isToolWindow () const { return (type & ToolWindow); };
+/** Returns the type of this window */
+	bool isType (Type t) const { return (type & t); };
 /** Activate (raise) this window, regardless of whether it is attached or detached
 @param with_focus Should the window also get keyboard focus? */
 	virtual void activate (bool with_focus=true);

Modified: branches/KDE4_port/rkward/windows/rkworkplace.cpp
===================================================================
--- branches/KDE4_port/rkward/windows/rkworkplace.cpp	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/windows/rkworkplace.cpp	2007-11-07 23:49:48 UTC (rev 2185)
@@ -36,7 +36,6 @@
 #include "../core/robjectlist.h"
 #include "../dataeditor/rkeditor.h"
 #include "../dataeditor/rkeditordataframe.h"
-#include "../dataeditor/rkeditordataframepart.h"
 #include "../robjectviewer.h"
 #include "../settings/rksettingsmoduleoutput.h"
 #include "../settings/rksettingsmodulegeneral.h"
@@ -293,14 +292,31 @@
 	return false;
 }
 
-RKEditor *RKWorkplace::editObject (RObject *object, bool initialize_to_empty) {
+RKEditor* RKWorkplace::editNewDataFrame (const QString &name) {
 	RK_TRACE (APP);
 
+	RKEditorDataFrame* ed = new RKEditorDataFrame (name, 0);
+	addWindow (ed);
+	ed->activate ();
+
+	return ed;
+}
+
+RKEditor *RKWorkplace::editObject (RObject *object) {
+	RK_TRACE (APP);
+
 	RObject *iobj = object;
 	RKEditor *ed = 0;
-	RKEditorDataFramePart *part = 0;
 	RKEditor *existing_editor = RKGlobals::tracker ()->objectEditor (object);
 	if (!existing_editor) {
+		if (!iobj->isDataFrame ()) {
+			if (iobj->isVariable () && iobj->getContainer ()->isDataFrame ()) {
+				iobj = iobj->getContainer ();
+			} else {
+				return 0;
+			}
+		}
+
 		unsigned long size = 1;
 		for (unsigned int i = 0; i < iobj->numDimensions (); ++i) {
 			size *= iobj->getDimension (i);
@@ -311,22 +327,13 @@
 			}
 		}
 
-		part = new RKEditorDataFramePart (0);		// TODO: reverse creation logic, just as in the other classes!
-		ed = part->getEditor ();
-		// TODO: add child objects, too?
-		ed->openObject (iobj, initialize_to_empty);
-
-		ed->setCaption (iobj->getShortName ());		// TODO: move to editor
-		ed->setIcon (SmallIcon ("spreadsheet"));
+		ed = new RKEditorDataFrame (iobj, 0);
 		addWindow (ed);
-		ed->setFocus ();		// somehow we need to call this explicitly
+	} else {
+		ed = existing_editor;
 	}
 
-	if (existing_editor) {		// not strictly an else. existing_editor may be reset inside the above if
-		existing_editor->activate ();
-		ed = existing_editor;
-	}
-	
+	ed->activate ();
 	return ed;
 }
 
@@ -518,7 +525,7 @@
 
 	if (type == "data") {
 		RObject *object = RObjectList::getObjectList ()->findObject (specification);
-		if (object) editObject (object, false);
+		if (object) editObject (object);
 	} else if (type == "script") {
 		openScriptEditor (specification);
 	} else if (type == "output") {

Modified: branches/KDE4_port/rkward/windows/rkworkplace.h
===================================================================
--- branches/KDE4_port/rkward/windows/rkworkplace.h	2007-11-07 19:31:56 UTC (rev 2184)
+++ branches/KDE4_port/rkward/windows/rkworkplace.h	2007-11-07 23:49:48 UTC (rev 2185)
@@ -111,14 +111,16 @@
 	void newX11Window (WId window_to_embed, int device_number);
 	void newObjectViewer (RObject *object);
 
-#warning remove initialize_to_empty param. This should happen for all pending objects, but else never.
 /** @returns true if there is a known editor for this type of object, false otherwise */
 	bool canEditObject (RObject *object);
 /** Creates a new editor of an appropriate type, and loads the given object into the editor
 @param object object to edit
- at param initialize_to_empty Create an empty object (no data). Use with care!
 @returns a pointer to the editor */
-	RKEditor *editObject (RObject *object, bool initialize_to_empty=false);
+	RKEditor* editObject (RObject *object);
+/** Creates a new data.frame with the given name, and loads it in an editor. @see editObject()
+ at param name Name of the data.frame to create
+ at returns a pointer to the editor */
+	RKEditor* editNewDataFrame (const QString& name);
 
 /** tell all DataEditorWindow s to synchronize changes to the R backend
 // TODO: add RCommandChain parameter */


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