[rkward-cvs] SF.net SVN: rkward-code:[4644] branches/development_branches/ rkward_graphpics_device/rkward/rbackend/rkwarddevice

tfry at users.sf.net tfry at users.sf.net
Fri Mar 29 19:32:47 UTC 2013


Revision: 4644
          http://sourceforge.net/p/rkward/code/4644
Author:   tfry
Date:     2013-03-29 19:32:47 +0000 (Fri, 29 Mar 2013)
Log Message:
-----------
Implement newPageConfirm, don't lock up after errors / interrupts

Modified Paths:
--------------
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_backendtransmitter.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-03-29 19:32:47 UTC (rev 4644)
@@ -25,6 +25,7 @@
 #include <QMouseEvent>
 #include <klocale.h>
 #include <sys/stat.h>
+#include <kdialog.h>
 
 #include "rkgraphicsdevice_protocol_shared.h"
 
@@ -38,6 +39,7 @@
 	RK_TRACE (GRAPHICS_DEVICE);
 
 	interaction_opcode = -1;
+	dialog = 0;
 	if (antialias) painter.setRenderHints (QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
 	view = new QLabel ();
 	view->installEventFilter (this);
@@ -50,6 +52,7 @@
 RKGraphicsDevice::~RKGraphicsDevice () {
 	RK_TRACE (GRAPHICS_DEVICE);
 	painter.end ();
+	stopInteraction ();
 	delete view;
 }
 
@@ -189,12 +192,42 @@
 void RKGraphicsDevice::locator () {
 	RK_TRACE (GRAPHICS_DEVICE);
 
+	RK_ASSERT (interaction_opcode < 0);
 	interaction_opcode = RKDLocator;
 
 	view->setCursor (Qt::CrossCursor);
 	view->setToolTip (i18n ("<h2>Locating point(s)</h2><p>Use left mouse button to select point(s). Any other mouse button to stop.</p>"));
+	view->show ();
+	view->raise ();
 }
 
+void RKGraphicsDevice::confirmNewPage () {
+	RK_TRACE (GRAPHICS_DEVICE);
+
+	RK_ASSERT (interaction_opcode < 0);
+	RK_ASSERT (dialog == 0);
+	interaction_opcode = RKDNewPageConfirm;
+
+	view->show ();
+	view->raise ();
+	dialog = new KDialog (view);
+	dialog->setCaption (i18n ("Ok to show next plot?"));
+	dialog->setButtons (KDialog::Ok | KDialog::Cancel);
+	dialog->setMainWidget (new QLabel (i18n ("<p>Press Enter to see next plot, or click 'Cancel' to abort.</p>"), dialog));
+//	dialog->setWindowModality (Qt::WindowModal);        // not good: Grays out the plot window
+	connect (dialog, SIGNAL (finished (int)), this, SLOT (newPageDialogDone (int)));
+	dialog->show ();
+}
+
+void RKGraphicsDevice::newPageDialogDone (int result) {
+	RK_TRACE (GRAPHICS_DEVICE);
+
+	RK_ASSERT (dialog);
+	emit (newPageConfirmDone (result == KDialog::Accepted));
+	interaction_opcode = -1;
+	stopInteraction ();
+}
+
 bool RKGraphicsDevice::eventFilter (QObject *watched, QEvent *event) {
 	RK_ASSERT (watched == view);
 
@@ -218,7 +251,15 @@
 
 	if (interaction_opcode == RKDLocator) {
 		emit (locatorDone (false, 0.0, 0.0));
+	} else if (interaction_opcode == RKDNewPageConfirm) {
+		RK_ASSERT (dialog);
+		emit (newPageConfirmDone (true));
 	}
+
+	if (dialog) {
+		dialog->deleteLater ();
+		dialog = 0;
+	}
 	view->setCursor (Qt::ArrowCursor);
 	view->setToolTip (QString ());
 	interaction_opcode = -1;

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-03-29 19:32:47 UTC (rev 4644)
@@ -25,6 +25,8 @@
 #include <QPainter>
 #include <QLabel>
 
+class KDialog;
+
 /** This is the class that actually does all the drawing for the RKGraphicsDevice */
 class RKGraphicsDevice : public QObject {
 	Q_OBJECT
@@ -49,13 +51,16 @@
 	void setActive (bool active);
 	void triggerUpdate ();
 	void locator ();
+	void confirmNewPage ();
 public slots:
 	void stopInteraction ();
 signals:
 	void activeChanged (bool);
 	void locatorDone (bool ok, double x, double y);
+	void newPageConfirmDone (bool accepted);
 private slots:
 	void updateNow ();
+	void newPageDialogDone (int result);
 private:
 	bool eventFilter (QObject *watched, QEvent *event);
 
@@ -64,6 +69,7 @@
 	QPainter painter;
 	QLabel *view;
 	QString base_title;
+	KDialog *dialog;
 
 	int interaction_opcode;	/**< Current interactive operation (from RKDOpcodes enum), or -1 is there is no current interactive operation */
 };

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_backendtransmitter.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_backendtransmitter.cpp	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_backendtransmitter.cpp	2013-03-29 19:32:47 UTC (rev 4644)
@@ -74,9 +74,9 @@
 
 	while (alive) {
 		msleep (10);	// it's ok to be lazy. If a request expects a reply, RKGraphicsDataStreamReadGuard will take care of pushing everything, itself. Essentially, this thread's job is simply to make sure we don't lag *too* far behind.
-/*		mutex.lock ();
+		mutex.lock ();
 		connection->waitForBytesWritten (100);
-		mutex.unlock (); */
+		mutex.unlock ();
 	}
 
 	RK_TRACE (GRAPHICS_DEVICE);

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-03-29 19:32:47 UTC (rev 4644)
@@ -174,12 +174,18 @@
 			streamer.instream >> width >> height >> title >> antialias;
 			device = RKGraphicsDevice::newDevice (devnum, width, height, title, antialias);
 			connect (device, SIGNAL (locatorDone(bool,double,double)), this, SLOT (locatorDone(bool,double,double)));
+			connect (device, SIGNAL (newPageConfirmDone(bool)), this, SLOT (newPageConfirmDone(bool)));
 			connect (this, SIGNAL (stopInteraction()), device, SLOT (stopInteraction()));
-		} else if (devnum) {
-			device = RKGraphicsDevice::devices.value (devnum);
+		} else {
+			if (devnum) device = RKGraphicsDevice::devices.value (devnum);
 			if (!device) {
-				RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Received transmission of type %d for unknown device number %d. Skippping.", opcode, devnum);
-				sendDummyReply (opcode);
+				if (opcode == RKDCancel) {
+					RK_DEBUG (GRAPHICS_DEVICE, DL_WARNING, "Graphics operation cancelled");
+					emit (stopInteraction());
+				} else {
+					RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Received transmission of type %d for unknown device number %d. Skippping.", opcode, devnum);
+					sendDummyReply (opcode);
+				}
 				continue;
 			}
 		}
@@ -230,9 +236,9 @@
 		} else if (opcode == RKDClose) {
 			RKGraphicsDevice::closeDevice (devnum);
 		} else if (opcode == RKDActivate) {
-			RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Unhandled operation of type %d for device number %d. Skippping.", opcode, devnum);
+			device->setActive (true);
 		} else if (opcode == RKDDeActivate) {
-			RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Unhandled operation of type %d for device number %d. Skippping.", opcode, devnum);
+			device->setActive (false);
 		} else if (opcode == RKDClip) {
 			QRectF clip;
 			streamer.instream >> clip;
@@ -245,11 +251,8 @@
 			device->locator ();
 #warning TODO keep track of status
 		} else if (opcode == RKDNewPageConfirm) {
-			RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Unhandled operation of type %d for device number %d. Skippping.", opcode, devnum);
-			sendDummyReply (opcode);
-		} else if (opcode == RKDCancel) {
-			RK_DEBUG (GRAPHICS_DEVICE, DL_WARNING, "Graphics operation cancelled");
-			emit (stopInteraction());
+			device->confirmNewPage ();
+#warning TODO keep track of status
 		} else {
 			RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Unhandled operation of type %d for device number %d. Skippping.", opcode, devnum);
 		}
@@ -273,7 +276,7 @@
 		ascent = descent = width = 0.1;
 		streamer.outstream << ascent << descent << width;
 	} else if (opcode == RKDNewPageConfirm) {
-		bool ok = false;
+		bool ok = true;
 		streamer.outstream << ok;
 	} else if (opcode == RKDStrWidthUTF8) {
 		double width = 1;
@@ -292,4 +295,11 @@
 	streamer.writeOutBuffer ();
 }
 
+void RKGraphicsDeviceFrontendTransmitter::newPageConfirmDone (bool accepted) {
+	RK_TRACE (GRAPHICS_DEVICE);
+
+	streamer.outstream << accepted;
+	streamer.writeOutBuffer ();
+}
+
 #include "rkgraphicsdevice_frontendtransmitter.moc"

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.h	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.h	2013-03-29 19:32:47 UTC (rev 4644)
@@ -35,6 +35,7 @@
 	void newData ();
 	void newConnection ();
 	void locatorDone (bool ok, double x, double y);
+	void newPageConfirmDone (bool accepted);
 signals:
 	void stopInteraction ();
 private:

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-03-29 19:32:47 UTC (rev 4644)
@@ -77,10 +77,9 @@
 	RKDMode,
 
 	// Synchronous operations
-	RKD_First_Synchronous_Request,
 	RKDStrWidthUTF8,
-	RKDMetricInfo, // 15
-	RKDLocator,
+	RKDMetricInfo,
+	RKDLocator,    // 15
 	RKDNewPageConfirm,
 
 	// Protocol operations

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-03-29 15:59:21 UTC (rev 4643)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-03-29 19:32:47 UTC (rev 4644)
@@ -35,6 +35,7 @@
 public:
 	RKGraphicsDataStreamReadGuard () {
 		RKGraphicsDeviceBackendTransmitter::mutex.lock ();
+		have_lock = true;
 		QIODevice* connection = RKGraphicsDeviceBackendTransmitter::connection;
 		BEGIN_SUSPEND_INTERRUPTS {
 			while (connection->bytesToWrite ()) {
@@ -47,7 +48,11 @@
 			while (!RKGraphicsDeviceBackendTransmitter::streamer.readInBuffer ()) {
 				RKRBackend::processX11Events ();
 				if (!connection->waitForReadyRead (10)) {
-					if (checkHandleInterrupt (connection)) break;
+					if (checkHandleInterrupt (connection)) {
+						if (have_lock) RKGraphicsDeviceBackendTransmitter::mutex.unlock ();
+						have_lock = false;	// Will d'tor still be called? We don't rely on it.
+						break;
+					}
 					checkHandleError ();
 				}
 			}
@@ -55,7 +60,7 @@
 	}
 
 	~RKGraphicsDataStreamReadGuard () {
-		RKGraphicsDeviceBackendTransmitter::mutex.unlock ();
+		if (have_lock) RKGraphicsDeviceBackendTransmitter::mutex.unlock ();
 	}
 
 private:
@@ -84,10 +89,12 @@
 
 	void checkHandleError () {
 		if (!RKGraphicsDeviceBackendTransmitter::connectionAlive ()) {	// Don't go into endless loop, if e.g. frontend has crashed
-			RKGraphicsDeviceBackendTransmitter::mutex.unlock ();
+			if (have_lock) RKGraphicsDeviceBackendTransmitter::mutex.unlock ();
+			have_lock = false;	// Will d'tor still be called? We don't rely on it.
 			Rf_error ("RKWard Graphics connection has shut down");
 		}
 	}
+	bool have_lock;
 };
 
 /** This class is essentially like QMutexLocker. In addition, the destructor takes care of pushing anything that was written to the protocol buffer during it lifetime to the transmitter. (Does NOT wait for the transmission itself). */
@@ -288,11 +295,12 @@
 		RKGraphicsDataStreamWriteGuard wguard;
 		WRITE_HEADER (RKDNewPageConfirm, dev);
 	}
+	bool ok;
 	{
 		RKGraphicsDataStreamReadGuard rguard;
-		bool ok;
 		RKD_IN_STREAM >> ok;
-		if (ok) return (Rboolean) TRUE;
-		return (Rboolean) FALSE;
 	}
+	if (!ok) Rf_error ("Aborted by user");
+	return (Rboolean) TRUE;
+	// Return value FALSE: Let R ask, instead
 }





More information about the rkward-tracker mailing list