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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Aug 7 15:55:09 UTC 2009


Revision: 2604
          http://rkward.svn.sourceforge.net/rkward/?rev=2604&view=rev
Author:   tfry
Date:     2009-08-07 15:55:08 +0000 (Fri, 07 Aug 2009)

Log Message:
-----------
Make package unloading slightly safer.
Add action to unload package to object browser context menu.
Fix bug in updating search path after a package is unloaded.

Modified Paths:
--------------
    trunk/rkward/rkward/core/robjectlist.cpp
    trunk/rkward/rkward/core/robjectlist.h
    trunk/rkward/rkward/dialogs/rkloadlibsdialog.cpp
    trunk/rkward/rkward/misc/rkcommonfunctions.h
    trunk/rkward/rkward/windows/robjectbrowser.cpp
    trunk/rkward/rkward/windows/robjectbrowser.h

Modified: trunk/rkward/rkward/core/robjectlist.cpp
===================================================================
--- trunk/rkward/rkward/core/robjectlist.cpp	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/core/robjectlist.cpp	2009-08-07 15:55:08 UTC (rev 2604)
@@ -29,6 +29,7 @@
 #include "renvironmentobject.h"
 #include "../rbackend/rinterface.h"
 #include "rkmodificationtracker.h"
+#include "../misc/rkprogresscontrol.h"
 
 #include "../rkglobals.h"
 
@@ -57,6 +58,33 @@
 	RK_TRACE (OBJECTS);
 }
 
+QStringList RObjectList::detachPackages (const QStringList &packages, RCommandChain *chain, RKProgressControl* control) {
+	RK_TRACE (OBJECTS);
+
+	QStringList remove;
+	QStringList reject;
+	for (int i = 0; i < packages.size(); ++i) {
+		QString shortname = packages[i];
+		shortname.remove ("package:");
+		if (shortname == "base" || shortname == "methods" || shortname == "utils" || shortname == "grDevices" || shortname == "graphics" || shortname == "rkward") {
+			reject.append (i18n ("Did not unload package %1. It is required in RKWard. If you really want to do this, do so on the R Console.", shortname));
+		} else if (!findChildByName (packages[i])) {
+			RK_ASSERT (false);
+			reject.append (i18n ("Package %1 appears not to have been loaded", shortname));
+		} else {
+			remove.append (packages[i]);
+		}
+	}
+	for (int i = 0; i < remove.size (); ++i) {
+		RCommand *command = new RCommand ("detach (" + rQuote (remove[i]) + ")", RCommand::App | RCommand::ObjectListUpdate);
+
+		if (control) control->addRCommand (command);
+		RKGlobals::rInterface()->issueCommand (command, chain);
+	}
+
+	return reject;
+}
+
 void RObjectList::updateFromR (RCommandChain *chain) {
 	RK_TRACE (OBJECTS);
 
@@ -143,7 +171,7 @@
 	}
 
 	// check which envs have been removed or changed position
-	for (int i = childmap.size () - 1; i >= 0; --i) {
+	for (int i = 0; i < childmap.size (); ++i) {	// do *not* cache the childmap.size ()! We may change it in the loop.
 		RObject *obj = childmap[i];
 		int new_pos = newchildmap.indexOf (obj);
 		

Modified: trunk/rkward/rkward/core/robjectlist.h
===================================================================
--- trunk/rkward/rkward/core/robjectlist.h	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/core/robjectlist.h	2009-08-07 15:55:08 UTC (rev 2604)
@@ -31,6 +31,7 @@
 class RCommandChain;
 class RKEditor;
 class REnvironmentObject;
+class RKProgressControl;
 
 /**
 This class is responsible for keeping and updating a list of objects in the R-workspace.
@@ -66,6 +67,10 @@
 
 	static RObjectList *getObjectList () { return object_list; };
 	static REnvironmentObject *getGlobalEnv ();
+
+	/** detach the given list of packages (if the packages are loaded, and safe to remove)
+	@returns a list of error messages (usually empty) */
+	QStringList detachPackages (const QStringList &packages, RCommandChain *chain = 0, RKProgressControl *control = 0);
 public slots:
 	void timeout ();
 signals:

Modified: trunk/rkward/rkward/dialogs/rkloadlibsdialog.cpp
===================================================================
--- trunk/rkward/rkward/dialogs/rkloadlibsdialog.cpp	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/dialogs/rkloadlibsdialog.cpp	2009-08-07 15:55:08 UTC (rev 2604)
@@ -433,22 +433,29 @@
 	for (int i = 0; i < loaded_view->topLevelItemCount (); ++i) {
 		QTreeWidgetItem* loaded = loaded_view->topLevelItem (i);
 		if (!prev_packages.contains (loaded->text (0))) {
-			RCommand *command = new RCommand ("library (\"" + loaded->text (0) + "\")", RCommand::App | RCommand::ObjectListUpdate, QString::null, this, LOAD_PACKAGE_COMMAND);
+			RCommand *command = new RCommand ("library (\"" + loaded->text (0) + "\")", RCommand::App);
 			control->addRCommand (command);
 			RKGlobals::rInterface ()->issueCommand (command, parent->chain);
 		}
 	}
 	
 	// detach packages previously attached
+	QStringList packages_to_remove;
 	for (QStringList::Iterator it = prev_packages.begin (); it != prev_packages.end (); ++it) {
 		QList<QTreeWidgetItem*> loaded = loaded_view->findItems ((*it), Qt::MatchExactly, 0);
-		if (loaded.isEmpty ()) {		// no longer in the list
-			RCommand *command = new RCommand ("detach (package:" + (*it) + ')', RCommand::App | RCommand::ObjectListUpdate, QString (), this, LOAD_PACKAGE_COMMAND);
-			control->addRCommand (command);
-			RKGlobals::rInterface ()->issueCommand (command, parent->chain);
+		if (loaded.isEmpty ()) {	// no longer in the list
+			packages_to_remove.append ("package:" + *it);
 		}
 	}
+	if (!packages_to_remove.isEmpty ()) {
+		QStringList messages = RObjectList::getObjectList ()->detachPackages (packages_to_remove, parent->chain, control);
+		if (!messages.isEmpty ()) KMessageBox::sorry (this, messages.join ("\n"));
+	}
 
+	// find out, when we're done
+	RCommand *command = new RCommand (QString (), RCommand::EmptyCommand, QString (), this, LOAD_PACKAGE_COMMAND);
+	RKGlobals::rInterface ()->issueCommand (command, parent->chain);
+
 	control->doNonModal (true);
 }
 

Modified: trunk/rkward/rkward/misc/rkcommonfunctions.h
===================================================================
--- trunk/rkward/rkward/misc/rkcommonfunctions.h	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/misc/rkcommonfunctions.h	2009-08-07 15:55:08 UTC (rev 2604)
@@ -21,6 +21,7 @@
 class QString;
 class QDomNode;
 class KXMLGUIClient;
+class QWidget;
 
 /** Some common static helper functions that don't really belong to any class in particular. If ever we have more than a dozen or so functions in here,
 we should probably split this file up. Until then, there's no real need.

Modified: trunk/rkward/rkward/windows/robjectbrowser.cpp
===================================================================
--- trunk/rkward/rkward/windows/robjectbrowser.cpp	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/windows/robjectbrowser.cpp	2009-08-07 15:55:08 UTC (rev 2604)
@@ -131,6 +131,8 @@
 	connect (actions[CopyToGlobalEnv], SIGNAL(triggered(bool)), this, SLOT(popupCopyToGlobalEnv()));
 	actions.insert (Delete, new QAction (i18n ("Delete"), this));
 	connect (actions[Delete], SIGNAL(triggered(bool)), this, SLOT(popupDelete()));
+	actions.insert (Unload, new QAction (i18n ("Unload Package"), this));
+	connect (actions[Unload], SIGNAL(triggered(bool)), this, SLOT(popupUnload()));
 
 	QAction* sep = list_view->contextMenu ()->insertSeparator (list_view->contextMenu ()->actions ().value (0));
 	list_view->contextMenu ()->insertActions (sep, actions);
@@ -211,6 +213,18 @@
 	RKGlobals::tracker ()->removeObject (list_view->menuObject ());
 }
 
+void RObjectBrowserInternal::popupUnload () {
+	RK_TRACE (APP);
+
+	RObject *object = list_view->menuObject ();
+	RK_ASSERT (object);
+	RK_ASSERT (object->isType (RObject::PackageEnv));
+
+	QStringList messages = RObjectList::getObjectList ()->detachPackages (QStringList (object->getShortName ()));
+
+	if (!messages.isEmpty ()) KMessageBox::sorry (this, messages.join ("\n"));
+}
+
 void RObjectBrowserInternal::popupRename () {
 	RK_TRACE (APP);
 	bool ok;
@@ -242,6 +256,7 @@
 	actions[Copy]->setVisible (object->canRead () && (!object->isType (RObject::ToplevelEnv)));
 	actions[CopyToGlobalEnv]->setVisible (object->canRead () && (!object->isInGlobalEnv()) && (!object->isType (RObject::ToplevelEnv)));
 	actions[Delete]->setVisible (object->canRemove ());
+	actions[Unload]->setVisible (object->isType (RObject::PackageEnv));
 }
 
 void RObjectBrowserInternal::doubleClicked (const QModelIndex& index) {

Modified: trunk/rkward/rkward/windows/robjectbrowser.h
===================================================================
--- trunk/rkward/rkward/windows/robjectbrowser.h	2009-08-07 13:40:56 UTC (rev 2603)
+++ trunk/rkward/rkward/windows/robjectbrowser.h	2009-08-07 15:55:08 UTC (rev 2604)
@@ -77,6 +77,7 @@
 	void popupCopyToGlobalEnv ();
 	void popupView ();
 	void popupDelete ();
+	void popupUnload ();
 	void popupRename ();
 /** when an object in the list is double clicked, insert its name in the current RKCommandEditor window */
 	void doubleClicked (const QModelIndex &index);
@@ -92,6 +93,7 @@
 		Copy,
 		CopyToGlobalEnv,
 		Delete,
+		Unload,
 		ActionCount
 	};
 	QList<QAction*> actions;


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