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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Oct 4 12:23:59 UTC 2006


Revision: 804
          http://svn.sourceforge.net/rkward/?rev=804&view=rev
Author:   tfry
Date:     2006-10-04 05:23:50 -0700 (Wed, 04 Oct 2006)

Log Message:
-----------
Add copying functions to RObjectBrowser, and don't allow editing outside the GlobalEnv
small fix to RContainerObject child list keeping

Modified Paths:
--------------
    trunk/rkward/rkward/core/rcontainerobject.cpp
    trunk/rkward/rkward/core/robject.cpp
    trunk/rkward/rkward/core/robject.h
    trunk/rkward/rkward/core/robjectlist.cpp
    trunk/rkward/rkward/robjectbrowser.cpp
    trunk/rkward/rkward/robjectbrowser.h

Modified: trunk/rkward/rkward/core/rcontainerobject.cpp
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.cpp	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/core/rcontainerobject.cpp	2006-10-04 12:23:50 UTC (rev 804)
@@ -123,6 +123,7 @@
 	RKGlobals::tracker ()->lockUpdates (false);
 	RK_ASSERT (child_object);
 
+	if (child_object) childmap.insert (child_name, child_object);
 	if (child_object) RKGlobals::tracker ()->addObject (child_object, 0);
 	return child_object;
 }
@@ -132,7 +133,7 @@
 	RK_ASSERT (new_children->getDataType () == RData::StructureVector);
 	unsigned int new_child_count = new_children->getDataLength ();
 
-// first find out, which children are now available, copy the old one, create the new ones
+// first find out, which children are now available, copy the old ones, create the new ones
 	RObjectMap new_childmap;
 	for (unsigned int i = 0; i < new_child_count; ++i) {
 		RData *child_data = new_children->getStructureVector ()[i];

Modified: trunk/rkward/rkward/core/robject.cpp
===================================================================
--- trunk/rkward/rkward/core/robject.cpp	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/core/robject.cpp	2006-10-04 12:23:50 UTC (rev 804)
@@ -208,6 +208,10 @@
 
 bool RObject::updateStructure (RData *new_data) {
 	RK_TRACE (OBJECTS);
+	if (new_data->getDataLength () == 0) { // can happen, if the object no longer exists
+		return false;
+	}
+
 	RK_ASSERT (new_data->getDataLength () >= 5);
 	RK_ASSERT (new_data->getDataType () == RData::StructureVector);
 
@@ -496,3 +500,51 @@
 	data = 0;
 }
 
+bool RObject::canEdit () {
+	RK_TRACE (OBJECTS);
+
+	// TODO: find out, if binding is locked:
+	// if (isLocked ()) return false;
+	return (isInGlobalEnv ());
+}
+
+bool RObject::canRead () {
+	RK_TRACE (OBJECTS);
+
+	return (this != RObjectList::getObjectList ());
+}
+
+bool RObject::canRename () {
+	RK_TRACE (OBJECTS);
+
+	// TODO: find out, if binding is locked:
+	// if (isLocked ()) return false;
+	return (isInGlobalEnv ());
+}
+
+bool RObject::canRemove () {
+	RK_TRACE (OBJECTS);
+
+	// TODO: find out, if binding is locked:
+	// if (isLocked ()) return false;
+	return (isInGlobalEnv ());
+}
+
+bool RObject::isInGlobalEnv () {
+	RK_TRACE (OBJECTS);
+
+// could be made recursive instead, but likely it's faster like this
+	RObject *o = this;
+	while (o && (!o->isType (ToplevelEnv))) {
+		o = o->parent;
+	}
+
+	if (!o) {
+		RK_ASSERT (this == RObjectList::getObjectList ());
+		return false;
+	}
+	if (o->isType (GlobalEnv)) {
+		if (o != this) return true;	// the GlobalEnv is not inside the GlobalEnv!
+	}
+	return false;
+}

Modified: trunk/rkward/rkward/core/robject.h
===================================================================
--- trunk/rkward/rkward/core/robject.h	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/core/robject.h	2006-10-04 12:23:50 UTC (rev 804)
@@ -90,14 +90,11 @@
 /** trigger an update of this and all descendent objects */
 	virtual void updateFromR ();
 
-/* Is the object writable? Recurses upwards to find any locked environments/bindings TODO */
-//	virtual bool isWriteAble ();
-//	virtual bool isRemovable ();
-/* @returns 0 if the object is not masked, else the *highest* environment masking the object (i.e. preferentially the .GlobalEnv */
-//	virtual REnvironmentObject *findMaskingEnvironment ();
-/* Is the object inside the global env? Else we better not support writing to it TODO*/
-//	virtual bool isInGlobalEnv ();
-//	virtual REnvironmentObject *parentEnvironment ();
+	bool canEdit ();
+	bool canRead ();
+	bool canRename ();
+	bool canRemove ();
+	bool isInGlobalEnv ();
 
 	void rename (const QString &new_short_name);
 	void remove (bool removed_in_workspace);

Modified: trunk/rkward/rkward/core/robjectlist.cpp
===================================================================
--- trunk/rkward/rkward/core/robjectlist.cpp	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/core/robjectlist.cpp	2006-10-04 12:23:50 UTC (rev 804)
@@ -200,16 +200,14 @@
 
 RObject *RObjectList::createNewChild (const QString &name, RKEditor *creator, bool container, bool data_frame) {
 	RK_TRACE (OBJECTS);
-	RK_ASSERT (childmap.find (".GlobalEnv") != childmap.end ());
 
-	return (static_cast<RContainerObject *> (childmap[".GlobalEnv"])->createNewChild (name, creator, container, data_frame));
+	return (getGlobalEnv ()->createNewChild (name, creator, container, data_frame));
 }
 
 QString RObjectList::validizeName (const QString &child_name) {
 	RK_TRACE (OBJECTS);
-	RK_ASSERT (childmap.find (".GlobalEnv") != childmap.end ());
 
-	return (static_cast<RContainerObject *> (childmap[".GlobalEnv"])->validizeName (child_name));
+	return (getGlobalEnv ()->validizeName (child_name));
 }
 
 bool RObjectList::updateStructure (RData *) {

Modified: trunk/rkward/rkward/robjectbrowser.cpp
===================================================================
--- trunk/rkward/rkward/robjectbrowser.cpp	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/robjectbrowser.cpp	2006-10-04 12:23:50 UTC (rev 804)
@@ -29,7 +29,9 @@
 #include "windows/rkcommandeditorwindow.h"
 #include "rkglobals.h"
 #include "core/robjectlist.h"
+#include "core/renvironmentobject.h"
 #include "core/rkmodificationtracker.h"
+#include "rbackend/rinterface.h"
 #include "misc/rkobjectlistview.h"
 #include "windows/rkworkplace.h"
 #include "dataeditor/rkeditor.h"
@@ -38,6 +40,8 @@
 #include "debug.h"
 
 RObjectBrowser::RObjectBrowser () : QWidget () {
+	RK_TRACE (APP);
+
 	QGridLayout *grid = new QGridLayout (this, 1, 1);
 	QVBoxLayout *vbox = new QVBoxLayout ();
 	grid->addLayout (vbox, 0, 0);
@@ -53,8 +57,10 @@
 	list_view->contextMenu ()->insertItem (i18n ("Edit"), this, SLOT (popupEdit ()), 0, Edit, 0);
 	list_view->contextMenu ()->insertItem (i18n ("View"), this, SLOT (popupView ()), 0, View, 1);
 	list_view->contextMenu ()->insertItem (i18n ("Rename"), this, SLOT (popupRename ()), 0, Rename, 2);
-	list_view->contextMenu ()->insertItem (i18n ("Delete"), this, SLOT (popupDelete ()), 0, Delete, 3);
-	list_view->contextMenu ()->insertSeparator (4);
+	list_view->contextMenu ()->insertItem (i18n ("Copy to new symbol"), this, SLOT (popupCopy ()), 0, Copy, 3);
+	list_view->contextMenu ()->insertItem (i18n ("Copy to .GlobalEnv"), this, SLOT (popupCopyToGlobalEnv ()), 0, CopyToGlobalEnv, 4);
+	list_view->contextMenu ()->insertItem (i18n ("Delete"), this, SLOT (popupDelete ()), 0, Delete, 5);
+	list_view->contextMenu ()->insertSeparator (6);
 	connect (list_view, SIGNAL (aboutToShowContextMenu (RKListViewItem*, bool*)), this, SLOT (contextMenuCallback (RKListViewItem*, bool*)));
 	
 	connect (list_view, SIGNAL (doubleClicked (QListViewItem *, const QPoint &, int )), this, SLOT (slotListDoubleClicked (QListViewItem *, const QPoint &, int)));
@@ -63,32 +69,70 @@
 }
 
 RObjectBrowser::~RObjectBrowser () {
+	RK_TRACE (APP);
 }
 
 void RObjectBrowser::initialize () {
+	RK_TRACE (APP);
+
 	list_view->initialize (true);
 	
 	connect (update_button, SIGNAL (clicked ()), this, SLOT (updateButtonClicked ()));
 }
 
 void RObjectBrowser::updateButtonClicked () {
+	RK_TRACE (APP);
 	RObjectList::getObjectList ()->updateFromR ();
 }
 
 void RObjectBrowser::popupEdit () {
+	RK_TRACE (APP);
 	if (list_view->menuObject ()) RKWorkplace::mainWorkplace ()->editObject (list_view->menuObject ());
 }
 
+void RObjectBrowser::popupCopy () {
+	RK_TRACE (APP);
+
+	bool ok;
+	RObject *object = list_view->menuObject ();
+	QString suggested_name = RObjectList::getGlobalEnv ()->validizeName (object->getShortName ());
+	QString name = KInputDialog::getText (i18n ("Copy object"), i18n ("Enter the name to copy to"), suggested_name, &ok, this);
+
+	if (ok) {
+		QString valid = RObjectList::getGlobalEnv ()->validizeName (name);
+		if (valid != name) KMessageBox::sorry (this, i18n ("The name you specified was already in use or not valid. Renamed to %1").arg (valid), i18n ("Invalid Name"));
+		RObject *copy = RObjectList::getGlobalEnv ()->createNewChild (valid, 0, true, true);
+		RKGlobals::rInterface ()->issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App);
+		copy->updateFromR ();
+	}
+}
+
+void RObjectBrowser::popupCopyToGlobalEnv () {
+	RK_TRACE (APP);
+
+	RObject *object = list_view->menuObject ();
+	QString name = object->getShortName ();
+
+	QString valid = RObjectList::getGlobalEnv ()->validizeName (name);
+	if (valid != name) KMessageBox::sorry (this, i18n ("An object named '%1' already exists in the GlobalEnv. Created the copy as '%2' instead.").arg (name).arg (valid), i18n ("Name already in use"));
+	RObject *copy = RObjectList::getGlobalEnv ()->createNewChild (valid, 0, true, true);
+	RKGlobals::rInterface ()->issueCommand (RObject::rQuote (valid) + " <- " + object->getFullName (), RCommand::App);
+	copy->updateFromR ();
+}
+
 void RObjectBrowser::popupView () {
+	RK_TRACE (APP);
 	RKWorkplace::mainWorkplace ()->flushAllData ();
 	new RObjectViewer (0, list_view->menuObject ());
 }
 
 void RObjectBrowser::popupDelete () {
+	RK_TRACE (APP);
 	RKGlobals::tracker ()->removeObject (list_view->menuObject ());
 }
 
 void RObjectBrowser::popupRename () {
+	RK_TRACE (APP);
 	bool ok;
 	QString name = KInputDialog::getText (i18n ("Rename object"), i18n ("Enter the new name"), list_view->menuObject ()->getShortName (), &ok, this);
 	
@@ -100,26 +144,31 @@
 }
 
 void RObjectBrowser::contextMenuCallback (RKListViewItem *, bool *) {
+	RK_TRACE (APP);
 	RObject *object = list_view->menuObject ();
 	QPopupMenu *menu = list_view->contextMenu ();
 
-	if ((!object) || (object == RObjectList::getObjectList ())) {
+	if (!object) {
 		menu->setItemVisible (Edit, false);
 		menu->setItemVisible (View, false);
 		menu->setItemVisible (Rename, false);
+		menu->setItemVisible (Copy, false);
+		menu->setItemVisible (CopyToGlobalEnv, false);
 		menu->setItemVisible (Delete, false);
 
 		return;
 	}
 
-	menu->setItemVisible (Edit, true);
-	menu->setItemEnabled (Edit, RKWorkplace::mainWorkplace ()->canEditObject (object));
-	menu->setItemVisible (View, true);
-	menu->setItemVisible (Rename, true);
-	menu->setItemVisible (Delete, true);
+	menu->setItemVisible (Edit, object->canEdit () && RKWorkplace::mainWorkplace ()->canEditObject (object));
+	menu->setItemVisible (View, object->canRead ());
+	menu->setItemVisible (Rename, object->canRename ());
+	menu->setItemVisible (Copy, object->canRead () && (!object->isType (RObject::ToplevelEnv)));
+	menu->setItemVisible (CopyToGlobalEnv, object->canRead () && (!object->isInGlobalEnv()) && (!object->isType (RObject::ToplevelEnv)));
+	menu->setItemVisible (Delete, object->canRemove ());
 }
 
 void RObjectBrowser::slotListDoubleClicked (QListViewItem *item, const QPoint &, int) {
+	RK_TRACE (APP);
 	RObject *object = list_view->findItemObject (static_cast<RKListViewItem*> (item));
 	
 	if (!object) return;
@@ -133,4 +182,3 @@
 }
 
 #include "robjectbrowser.moc"
-

Modified: trunk/rkward/rkward/robjectbrowser.h
===================================================================
--- trunk/rkward/rkward/robjectbrowser.h	2006-10-04 10:55:28 UTC (rev 803)
+++ trunk/rkward/rkward/robjectbrowser.h	2006-10-04 12:23:50 UTC (rev 804)
@@ -40,18 +40,21 @@
 
     ~RObjectBrowser ();
 	
-	enum PopupItems { Edit=1, View=2, Rename=3, Delete=4 };
+	enum PopupItems { Edit=1, View=2, Rename=3, Copy=4, CopyToGlobalEnv=5, Delete=6 };
 	
 public slots:
 	void updateButtonClicked ();
 	void contextMenuCallback (RKListViewItem *item, bool *suppress);
 	
 	void popupEdit ();
+	void popupCopy ();
+/** essentially like popupCopy, but does not ask for a name */
+	void popupCopyToGlobalEnv ();
 	void popupView ();
 	void popupDelete ();
 	void popupRename ();
 /** when an object in the list is double clicked, insert its name in the current RKCommandEditor window */
-    void slotListDoubleClicked (QListViewItem *item, const QPoint &pos, int);
+	void slotListDoubleClicked (QListViewItem *item, const QPoint &pos, int);
 private:
 	friend class RKwardApp;
 	void initialize ();


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