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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Apr 6 11:23:53 UTC 2011


Revision: 3506
          http://rkward.svn.sourceforge.net/rkward/?rev=3506&view=rev
Author:   tfry
Date:     2011-04-06 11:23:52 +0000 (Wed, 06 Apr 2011)

Log Message:
-----------
Add an action to interrupt all (current and pending) commands.
The logic to ensure correct cancellation of currently running commands is now in the backend, instead of the frontend.

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/misc/rkstandardicons.cpp
    trunk/rkward/rkward/misc/rkstandardicons.h
    trunk/rkward/rkward/rbackend/rcommandstack.cpp
    trunk/rkward/rkward/rbackend/rcommandstack.h
    trunk/rkward/rkward/rbackend/rinterface.cpp
    trunk/rkward/rkward/rbackend/rinterface.h
    trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkrbackend.cpp
    trunk/rkward/rkward/rbackend/rkrbackend.h
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.h
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R
    trunk/rkward/rkward/resource.ver
    trunk/rkward/rkward/rkconsole.cpp
    trunk/rkward/rkward/rkward.cpp
    trunk/rkward/rkward/rkward.h
    trunk/rkward/rkward/rkwardui.rc
    trunk/rkward/rkward/version.h

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/ChangeLog	2011-04-06 11:23:52 UTC (rev 3506)
@@ -1,3 +1,5 @@
+- Add an action to interrupt all (current and pending) commands
+- Fixed: When saving the workplace while closing the session, the workplace layout would not always be saved correctly
 - File browser context menu gains many more KDE standard actions (KDE 4.3 and above, only)
 - Auxiliary binaries rkward.bin and rkward.rbackend are no longer installed into /usr[/local]/bin/ on Unix
 - Fixed: Object name completion would abort early in the script editor with KDE 4.4

Modified: trunk/rkward/rkward/misc/rkstandardicons.cpp
===================================================================
--- trunk/rkward/rkward/misc/rkstandardicons.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/misc/rkstandardicons.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -70,6 +70,7 @@
 	icons[ActionWindowDuplicate] = KIcon ("window-duplicate.png");
 
 	icons[ActionClear] = KIcon ("edit-clear.png");
+	icons[ActionInterrupt] = KIcon ("media-playback-stop");
 
 	icons[ActionDetachWindow] = KIcon ("view-fullscreen");
 	icons[ActionAttachWindow] = KIcon ("view-restore");

Modified: trunk/rkward/rkward/misc/rkstandardicons.h
===================================================================
--- trunk/rkward/rkward/misc/rkstandardicons.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/misc/rkstandardicons.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -70,6 +70,7 @@
 		ActionWindowDuplicate,
 
 		ActionClear,
+		ActionInterrupt,
 
 		ActionDetachWindow,
 		ActionAttachWindow,

Modified: trunk/rkward/rkward/rbackend/rcommandstack.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rcommandstack.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rcommandstack.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rcommandstack  -  description
                              -------------------
     begin                : Mon Sep 6 2004
-    copyright            : (C) 2004, 2007, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -110,6 +110,24 @@
 	return coc->commandPointer ();
 }
 
+void RCommandStack::addChainCommandsToList (QList<RCommand*> *list, const RCommandChain *chain) const {
+	RK_TRACE (RBACKEND);
+
+	foreach (RCommandBase* coc, chain->commands) {
+		if (coc->chainPointer ()) addChainCommandsToList (list, coc->chainPointer ());
+		else if (coc->commandPointer ()) list->append (coc->commandPointer ());
+		else RK_ASSERT (false);
+	}
+}
+
+QList<RCommand*> RCommandStack::allCommands () const {
+	RK_TRACE (RBACKEND);
+
+	QList<RCommand*> ret;
+	addChainCommandsToList (&ret, current_chain);
+	return ret;
+}
+
 bool RCommandStack::isEmpty () {
 //	RK_TRACE (RBACKEND);
 	return (commands.isEmpty ());

Modified: trunk/rkward/rkward/rbackend/rcommandstack.h
===================================================================
--- trunk/rkward/rkward/rbackend/rcommandstack.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rcommandstack.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rcommandstack  -  description
                              -------------------
     begin                : Mon Sep 6 2004
-    copyright            : (C) 2004, 2007, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -50,6 +50,7 @@
 
 /** see pop() */
 	RCommand* currentCommand ();
+	QList<RCommand*> allCommands () const;
 	RCommandChain* currentChain () { return current_chain; };
 
 /** the regular command stack, i.e. not a callback */
@@ -69,6 +70,7 @@
 /** pointer to any substack. Will only be non-zero, if the substack is active */
 	RCommandStack *sub_stack;
 	void clearFinishedChains ();
+	void addChainCommandsToList (QList<RCommand*> *list, const RCommandChain *chain) const;
 };
 
 #include <QAbstractItemModel>

Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -86,11 +86,9 @@
 
 	new RCommandStackModel (this);
 	RCommandStack::regular_stack = new RCommandStack (0);
-	running_command_canceled = 0;
 	startup_phase2_error = false;
 	command_logfile_mode = NotRecordingCommands;
 	previously_idle = false;
-	previous_command = 0;
 	locked = 0;
 	backend_dead = false;
 
@@ -126,13 +124,12 @@
 	return (idle);
 }
 
-void RInterface::popPreviousCommand () {
+RCommand *RInterface::popPreviousCommand () {
 	RK_TRACE (RBACKEND);
 
-	RK_ASSERT (previous_command == 0);
 	RK_ASSERT (!all_current_commands.isEmpty ());
-	previous_command = all_current_commands.takeLast ();
 	RCommandStack::currentStack ()->pop ();
+	return all_current_commands.takeLast ();
 }
 
 void RInterface::tryNextCommand () {
@@ -153,8 +150,9 @@
 				command->status |= RCommand::Failed;
 
 				// notify ourselves...
-				popPreviousCommand ();
-				handleCommandOut (command->makeProxy ());
+				RCommand* dummy = popPreviousCommand ();
+				RK_ASSERT (dummy == command);
+				handleCommandOut (command);
 				return;
 			}
 
@@ -176,13 +174,10 @@
 	}
 }
 
-void RInterface::handleCommandOut (RCommandProxy *proxy) {
+void RInterface::handleCommandOut (RCommand *command) {
 	RK_TRACE (RBACKEND);
 
-	RK_ASSERT (proxy);
-	RK_ASSERT (previous_command);
-	RCommand* command = previous_command;
-	command->mergeAndDeleteProxy (proxy);
+	RK_ASSERT (command);
 
 	#ifdef RKWARD_DEBUG
 		int dl = DL_WARNING;		// failed application commands are an issue worth reporting, failed user commands are not
@@ -210,15 +205,9 @@
 		out->output = ("--- interrupted ---");
 		command->output_list.append (out);
 		command->newOutput (out);
-		if (running_command_canceled) {
-			RK_ASSERT (command == running_command_canceled);
-			running_command_canceled = 0;
-			locked -= locked & Cancel;
-		}
 	}
 	command->finished ();
 	delete command;
-	previous_command = 0;
 }
 
 void RInterface::doNextCommand (RCommand *command) {
@@ -309,14 +298,19 @@
 	flushOutput (true);
 	if (request->type == RBackendRequest::CommandOut) {
 		RCommandProxy *cproxy = request->takeCommand ();
+		RCommand *command = 0;
 
 		// NOTE: the order of processing is: first try to submit the next command, then handle the old command.
 		// The reason for doing it this way, instead of the reverse, is that this allows the backend thread / process to continue working, concurrently
 		// NOTE: cproxy should only ever be 0 in the very first cycle
-		if (cproxy) popPreviousCommand ();
+		if (cproxy) command = popPreviousCommand ();
 		command_requests.append (request);
 		tryNextCommand ();
-		if (cproxy) handleCommandOut (cproxy);
+		if (cproxy) {
+			RK_ASSERT (command);
+			command->mergeAndDeleteProxy (cproxy);
+			handleCommandOut (command);
+		}
 		tryNextCommand ();
 	} else if (request->type == RBackendRequest::HistoricalSubstackRequest) {
 		processHistoricalSubstackRequest (request);
@@ -416,26 +410,25 @@
 	tryNextCommand ();
 };
 
+void RInterface::cancelAll () {
+	RK_TRACE (RBACKEND);
+
+	QList<RCommand*> all_commands = RCommandStack::regular_stack->allCommands ();
+	foreach (RCommand* command, all_commands) cancelCommand (command);
+}
+
 void RInterface::cancelCommand (RCommand *command) {
 	RK_TRACE (RBACKEND);
-	
+
 	if (!(command->type () & RCommand::Sync)) {
 		command->status |= RCommand::Canceled;
 		if (command->type () && RCommand::Running) {
-#warning This assumption is wrong. Fix command cancellation.
-// In particular, the backend may contain several commands at once. We should tell the backend, exactly which commands to cancel
-			if (running_command_canceled != command) {
-				RK_ASSERT (!running_command_canceled);
-				locked |= Cancel;
-				running_command_canceled = command;
-				RKRBackendProtocolFrontend::instance ()->interruptProcessing ();
-			}
+			RKRBackendProtocolFrontend::instance ()->interruptCommand (command->id ());
 		}
+		RCommandStackModel::getModel ()->itemChange (command);
 	} else {
 		RK_ASSERT (false);
 	}
-
-	RCommandStackModel::getModel ()->itemChange (command);
 }
 
 void RInterface::pauseProcessing (bool pause) {

Modified: trunk/rkward/rkward/rbackend/rinterface.h
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rinterface.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rinterface.h  -  description
                              -------------------
     begin                : Fri Nov 1 2002
-    copyright            : (C) 2002, 2004, 2005, 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2002, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -63,6 +63,8 @@
 /** Ensures that the given command will not be executed, or, if it is already running, interrupts it. Note that commands marked RCommand::Sync can
 not be interrupted. */
 	void cancelCommand (RCommand *command);
+/** Cancels all running or outstanding commands. @See cancelCommand() */
+	void cancelAll ();
 
 /** Pauses process. The current command will continue to run, but no new command will be */
 	void pauseProcessing (bool pause);
@@ -84,8 +86,6 @@
 	RKRBackend *r_thread;
 /** Timer to trigger flushing output */
 	QTimer *flush_timer;
-/** canceling the command that is (or seems to be) currently running is tricky: In order to do so, we need to signal an interrupt to the RThread. We need this pointer to find out, when the command has actually been interrupted, and we can resume processing. */
-	RCommand *running_command_canceled;
 /** Used by the testing framework. see R function rk.record.commands(). */
 	QFile command_logfile;
 	enum {
@@ -99,20 +99,18 @@
 
 /** A list of all commands that have entered, and not yet left, the backend thread */
 	QList<RCommand*> all_current_commands;
-	RCommand* previous_command;
 /** NOTE: processsing R events while waiting for the next command may, conceivably, lead to new requests, which may also wait for sub-commands! Thus we keep a simple stack of requests. */
 	QList<RBackendRequest*> command_requests;
 	RBackendRequest* currentCommandRequest () const { return (command_requests.isEmpty () ? 0 : command_requests.last ()); };
 	void tryNextCommand ();
 	void doNextCommand (RCommand *command);
-	void popPreviousCommand ();
-	void handleCommandOut (RCommandProxy *proxy);
+	RCommand *popPreviousCommand ();
+	void handleCommandOut (RCommand *command);
 	bool previously_idle;
 
 /** @see locked */
 	enum LockType {
-		User=1,		/**< locked on user request */
-		Cancel=2	/**< locked to safely cancel a running command */
+		User=1		/**< locked on user request */
 	};
 
 /** Used for locking the backend, meaning not further commands will be given to the backend. This is used, when the currently running command is to be cancelled. It is used to make sure that the backend thread does not proceed with further commands, before the main thread takes notice. Also it is called, if the RThread is paused on User request. Further, the thread is initially locked so the main thread can check for some conditions before the backend thread may produce

Modified: trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -92,7 +92,7 @@
 
 	// first check for requests which originated in the frontend
 	if (request->type == RBackendRequest::Interrupt) {
-		RKRBackendProtocolBackend::interruptProcessing ();
+		RKRBackend::this_pointer->interruptCommand (request->params.value ("commandid", -1).toInt ());
 	// requests which originated in the backend below this line
 	} else {
 		if (current_sync_requests.isEmpty ()) {

Modified: trunk/rkward/rkward/rbackend/rkrbackend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackend.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -92,7 +92,13 @@
 #	include <Rinterface.h>
 #endif
 
+#ifndef Q_WS_WIN
+#	include <signal.h>		// needed for pthread_kill
+#	include <pthread.h>		// seems to be needed at least on FreeBSD
+#endif
+
 void RK_scheduleIntr () {
+	RK_DO (qDebug ("interrupt scheduled"), RBACKEND, DL_DEBUG);
 	RKRBackend::repl_status.interrupted = true;
 #ifdef Q_WS_WIN
 	UserBreak = 1;
@@ -103,14 +109,42 @@
 
 void RK_doIntr () {
 	RK_scheduleIntr ();
-	RKRBackend::repl_status.interrupted = true;
 	R_CheckUserInterrupt ();
 }
 
 void RKRBackend::scheduleInterrupt () {
-	RK_scheduleIntr ();
+	if (RKRBackendProtocolBackend::inRThread ()) {
+		RK_scheduleIntr ();
+	} else {
+#ifdef Q_WS_WIN
+		RK_scheduleIntr ();		// Thread-safe on windows?!
+#else
+		pthread_kill ((pthread_t) RKRBackendProtocolBackend::instance ()->r_thread_id, SIGUSR1);	// NOTE: SIGUSR1 relays to SIGINT
+#endif
+	}
 }
 
+void RKRBackend::interruptCommand (int command_id) {
+	RK_TRACE (RBACKEND);
+	QMutexLocker lock (&all_current_commands_mutex);
+
+	if (all_current_commands.isEmpty ()) return;
+	if ((command_id == -1) || (all_current_commands.last ()->id == command_id)) {
+		RK_DO (qDebug ("scheduling interrupt for command id %d", command_id), RBACKEND, DL_DEBUG);
+		scheduleInterrupt ();
+	} else {
+		// if the command to cancel is *not* the topmost command, then do not interrupt, yet.
+		foreach (RCommandProxy *candidate, all_current_commands) {
+			if (candidate->id == command_id) {
+				if (!current_commands_to_cancel.contains (candidate)) {
+					RK_DO (qDebug ("scheduling delayed interrupt for command id %d", command_id), RBACKEND, DL_DEBUG);
+					current_commands_to_cancel.append (candidate);
+				}
+			}
+		}
+	}
+}
+
 // some functions we need that are not declared
 LibExtern void Rf_PrintWarnings (void);
 LibExtern void run_Rmainloop (void);
@@ -752,6 +786,7 @@
 		if (!R_interrupts_pending) {
 			RKRBackend::repl_status.interrupted = false;
 			if (RKRBackend::repl_status.user_command_status != RKRBackend::RKReplStatus::ReplIterationKilled) {	// was interrupted only to step out of the repl iteration
+				QMutexLocker lock (&(RKRBackend::this_pointer->all_current_commands_mutex));
 				foreach (RCommandProxy *command, RKRBackend::this_pointer->all_current_commands) command->status |= RCommand::Canceled;
 				RK_DO (qDebug ("interrupted"), RBACKEND, DL_DEBUG);
 			}
@@ -767,6 +802,8 @@
 SEXP doSubstackCall (SEXP call) {
 	RK_TRACE (RBACKEND);
 
+	R_CheckUserInterrupt ();
+
 	QStringList list = RKRSupport::SEXPToStringList (call);
 
 	// handle symbol updates inline
@@ -1165,8 +1202,11 @@
 
 	previous_command = current_command;
 
-	all_current_commands.pop_back();
-	if (!all_current_commands.isEmpty ()) current_command = all_current_commands.last ();
+	{
+		QMutexLocker lock (&all_current_commands_mutex);
+		all_current_commands.pop_back();
+		if (!all_current_commands.isEmpty ()) current_command = all_current_commands.last ();
+	}
 }
 
 RCommandProxy* RKRBackend::handleRequest (RBackendRequest *request, bool mayHandleSubstack) {
@@ -1190,8 +1230,11 @@
 	RCommandProxy* command = request->takeCommand ();
 	if (!command) return 0;
 
-	all_current_commands.append (command);
-	current_command = command;
+	{
+		QMutexLocker lock (&all_current_commands_mutex);
+		all_current_commands.append (command);
+		current_command = command;
+	}
 
 	if (!mayHandleSubstack) return command;
 	
@@ -1202,6 +1245,14 @@
 		command = fetchNextCommand ();
 	};
 
+	{
+		QMutexLocker lock (&all_current_commands_mutex);
+		if (current_commands_to_cancel.contains (current_command)) {
+			RK_DO (qDebug ("will now interrupt parent command"), RBACKEND, DL_DEBUG);
+			scheduleInterrupt ();
+		}
+	}
+
 	return 0;
 }
 

Modified: trunk/rkward/rkward/rbackend/rkrbackend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackend.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -173,6 +173,10 @@
 	bool capturing_messages;
 	QString captured_messages;
 	void printAndClearCapturedMessages ();
+
+	QMutex all_current_commands_mutex;
+	QList<RCommandProxy*> current_commands_to_cancel;
+	void interruptCommand (int command_id);
 protected:
 	RCommandProxy* handleRequest (RBackendRequest *request, bool mayHandleSubstack);
 private:

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -23,10 +23,6 @@
 
 #include <QCoreApplication>
 #include <QThread>
-#ifndef Q_WS_WIN
-#	include <signal.h>		// needed for pthread_kill
-#	include <pthread.h>		// seems to be needed at least on FreeBSD
-#endif
 
 #ifdef RKWARD_THREADED
 #	include "rkrbackendprotocol_frontend.h"
@@ -206,15 +202,3 @@
 	static_cast<RKRBackendTransmitter*> (RKRBackendTransmitter::instance ())->publicmsleep (delay);
 #endif
 }
-
-void RKRBackendProtocolBackend::interruptProcessing () {
-	if (inRThread ()) {
-		RKRBackend::scheduleInterrupt ();
-	} else {
-#ifdef Q_WS_WIN
-		RKRBackend::scheduleInterrupt ();		// Thread-safe on windows?!
-#else
-		pthread_kill ((pthread_t) instance ()->r_thread_id, SIGUSR1);	// NOTE: SIGUSR1 relays to SIGINT
-#endif
-	}
-}

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -36,7 +36,6 @@
 friend class RKRBackendTransmitter;
 	void sendRequest (RBackendRequest *request);
 	static void msleep (int delay);
-	static void interruptProcessing ();
 	static RKRBackendProtocolBackend* instance () { return _instance; };
 	QString data_dir;
 private:

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -88,14 +88,15 @@
 #endif
 }
 
-void RKRBackendProtocolFrontend::interruptProcessing () {
+void RKRBackendProtocolFrontend::interruptCommand (int command_id) {
 	RK_TRACE (RBACKEND);
 
 #ifdef RKWARD_THREADED
 	RK_ASSERT (!RKRBackendProtocolBackend::inRThread ());
-	RKRBackendProtocolBackend::interruptProcessing ();
+	RKRBackendProtocolBackend::interruptCommand (command_id);
 #else
 	RBackendRequest *req = new RBackendRequest (false, RBackendRequest::Interrupt);
+	req->params.insert ("commandid", QVariant (command_id));
 	qApp->postEvent (RKFrontendTransmitter::instance (), new RKRBackendEvent (req));
 #endif
 }

Modified: trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
                           rkrbackendprotocol  -  description
                              -------------------
     begin                : Thu Nov 04 2010
-    copyright            : (C) 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -32,7 +32,7 @@
 
 	static void setRequestCompleted (RBackendRequest *request);
 	ROutputList flushOutput (bool force);
-	void interruptProcessing ();
+	void interruptCommand (int command_id);
 	void terminateBackend ();
 	void setupBackend ();
 	static RKRBackendProtocolFrontend* instance () { return _instance; };

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/ver.R	2011-04-06 11:23:52 UTC (rev 3506)
@@ -1 +1 @@
-".rk.app.version" <- "0.5.5.z+0.5.6+test1"
+".rk.app.version" <- "0.5.5.z+0.5.6+test2"

Modified: trunk/rkward/rkward/resource.ver
===================================================================
--- trunk/rkward/rkward/resource.ver	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/resource.ver	2011-04-06 11:23:52 UTC (rev 3506)
@@ -1 +1 @@
-0.5.5.z+0.5.6+test1
+0.5.5.z+0.5.6+test2

Modified: trunk/rkward/rkward/rkconsole.cpp
===================================================================
--- trunk/rkward/rkward/rkconsole.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rkconsole.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -887,7 +887,7 @@
 	interrupt_command_action = ac->addAction ("interrupt", this, SLOT (resetConsole()));
 	interrupt_command_action->setText (i18n ("Interrupt running command"));
 	interrupt_command_action->setShortcut (Qt::ControlModifier + Qt::Key_C);
-	interrupt_command_action->setIcon (KIcon ("media-playback-stop"));
+	interrupt_command_action->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionInterrupt));
 	interrupt_command_action->setEnabled (false);
 
 	copy_action = ac->addAction ("rkconsole_copy", this, SLOT (copy()));

Modified: trunk/rkward/rkward/rkward.cpp
===================================================================
--- trunk/rkward/rkward/rkward.cpp	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rkward.cpp	2011-04-06 11:23:52 UTC (rev 3506)
@@ -305,12 +305,18 @@
 }
 
 void RKWardMainWindow::slotConfigure () {
+	RK_TRACE (APP);
 	RKSettings::configureSettings (RKSettings::NoPage, this);
 }
 
-void RKWardMainWindow::initActions()
-{  
+void RKWardMainWindow::slotCancelAllCommands () {
 	RK_TRACE (APP);
+	RK_ASSERT (RKGlobals::rInterface ());
+	RKGlobals::rInterface ()->cancelAll ();
+}
+
+void RKWardMainWindow::initActions() {  
+	RK_TRACE (APP);
 	KAction *action;
 
 	// TODO: is there a way to insert actions between standard actions without having to give all standard actions custom ids?
@@ -359,6 +365,11 @@
 	fileQuit = actionCollection ()->addAction (KStandardAction::Quit, "file_quitx", this, SLOT(close()));
 	fileQuit->setStatusTip (i18n ("Quits the application"));
 
+	interrupt_all_commands = actionCollection ()->addAction ("cancel_all_commands", this, SLOT (slotCancelAllCommands()));
+	interrupt_all_commands->setText (i18n ("Interrupt all commands"));
+	interrupt_all_commands->setShortcut (Qt::ShiftModifier + Qt::Key_Escape);
+	interrupt_all_commands->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionInterrupt));
+
 	// These two currently do the same thing
 	action = actionCollection ()->addAction ("load_unload_libs", this, SLOT (slotFileLoadLibs()));
 	action->setText (i18n ("Load / Unload Packages"));
@@ -393,9 +404,6 @@
 	view_menu_dummy = actionCollection ()->addAction ("view_menu_dummy", this);
 	view_menu_dummy->setText (edit_menu_dummy->text ());
 	view_menu_dummy->setEnabled (false);
-	run_menu_dummy = actionCollection ()->addAction ("run_menu_dummy", this);
-	run_menu_dummy->setText (edit_menu_dummy->text ());
-	run_menu_dummy->setEnabled (false);
 
 	// collections for the toolbar:
 	KActionMenu* open_any_action = new KActionMenu (KIcon ("document-open-folder"), i18n ("Open..."), this);
@@ -474,7 +482,6 @@
 
 	updateEmptyMenuIndicator (edit_menu_dummy, dynamic_cast<QMenu*>(guiFactory ()->container ("edit", this)));
 	updateEmptyMenuIndicator (view_menu_dummy, dynamic_cast<QMenu*>(guiFactory ()->container ("view", this)));
-	updateEmptyMenuIndicator (run_menu_dummy, dynamic_cast<QMenu*>(guiFactory ()->container ("run", this)));
 
 	// plug save file actions into the toolbar collections
 	RK_ASSERT (save_any_action);
@@ -739,9 +746,11 @@
 	if (status == Busy) {
 		status_color = QColor (255, 0, 0);
 		statusbar_r_status->setToolTip (i18n ("The <b>R</b> engine is busy."));
+		interrupt_all_commands->setEnabled (true);
 	} else if (status == Idle) {
 		status_color = QColor (0, 255, 0);
 		statusbar_r_status->setToolTip (i18n ("The <b>R</b> engine is idle."));
+		interrupt_all_commands->setEnabled (false);
 	} else {
 		status_color = QColor (255, 255, 0);
 		statusbar_r_status->setToolTip (i18n ("The <b>R</b> engine is being initialized."));

Modified: trunk/rkward/rkward/rkward.h
===================================================================
--- trunk/rkward/rkward/rkward.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rkward.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -2,7 +2,7 @@
 			rkward.h  -  description
 			-------------------
 begin                : Tue Oct 29 20:06:08 CET 2002 
-copyright            : (C) 2002, 2005, 2006, 2007, 2008, 2009, 2010 by Thomas Friedrichsmeier 
+copyright            : (C) 2002, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by Thomas Friedrichsmeier 
 email                : tfry at users.sourceforge.net
 ***************************************************************************/
 
@@ -111,6 +111,7 @@
 	/** Reimplemented from KParts::MainWindow to be more pretty
 	* @param text the text that is displayed in the statusbar
 	*/
+	void slotCancelAllCommands ();
 	void slotSetStatusBarText (const QString &text);
 /** Basically a shortcut to slotSetStatusBarText (QString::null). Needed as a slot without parameters. */
 	void slotSetStatusReady () { slotSetStatusBarText (QString::null); };
@@ -161,6 +162,7 @@
 	KAction* fileSaveWorkspace;
 	KAction* fileSaveWorkspaceAs;
 	KAction* fileQuit;
+	KAction* interrupt_all_commands;
 	KAction* close_all_editors;
 	KAction* new_data_frame;
 	KAction* new_command_editor;
@@ -174,8 +176,6 @@
 	KAction* edit_menu_dummy;
 	/** used so that if the menu is empty, there is a note in it, explaining that fact */
 	KAction* view_menu_dummy;
-	/** used so that if the menu is empty, there is a note in it, explaining that fact */
-	KAction* run_menu_dummy;
 
 	KAction* proxy_export, *proxy_import;
 	KActionMenu* save_any_action;

Modified: trunk/rkward/rkward/rkwardui.rc
===================================================================
--- trunk/rkward/rkward/rkwardui.rc	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/rkwardui.rc	2011-04-06 11:23:52 UTC (rev 3506)
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui>
-<kpartgui name="rkward_main" version="550">
+<kpartgui name="rkward_main" version="560">
 <MenuBar>
 	<!-- The Main Window ui.rc is the only one, where merging happens, reliably. That is, why we need to define
 	     a lot of merge points, here, which can then be used be mdi windows and their children.
@@ -51,10 +51,10 @@
 		<Action name="view_menu_dummy"/>
 	</Menu>
 	<Menu name="run"><text>&Run</text>
-		<Action name="run_menu_dummy"/>
 		<DefineGroup name="prerun_actions_merge" append="prerun_actions_merge"/>
 		<DefineGroup name="run_actions_merge" append="run_actions_merge"/>
 		<DefineGroup name="postrun_actions_merge" append="postrun_actions_merge"/>
+		<Action name="cancel_all_commands"/>
 	</Menu>
 	
 	<Merge name="rkwardcomponents" />

Modified: trunk/rkward/rkward/version.h
===================================================================
--- trunk/rkward/rkward/version.h	2011-04-04 11:04:20 UTC (rev 3505)
+++ trunk/rkward/rkward/version.h	2011-04-06 11:23:52 UTC (rev 3506)
@@ -1,2 +1,2 @@
 /* Version number of package */
-#define VERSION "0.5.5.z+0.5.6+test1"
+#define VERSION "0.5.5.z+0.5.6+test2"


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