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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Mon Feb 14 12:40:34 UTC 2011


Revision: 3434
          http://rkward.svn.sourceforge.net/rkward/?rev=3434&view=rev
Author:   tfry
Date:     2011-02-14 12:40:34 +0000 (Mon, 14 Feb 2011)

Log Message:
-----------
Add functions to save and restore workplace layout to / from a file.
Use this for storing workplace layout, instead of the previous hidden object '.rk.workplace.save'

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/agents/rkloadagent.cpp
    trunk/rkward/rkward/agents/rksaveagent.cpp
    trunk/rkward/rkward/rbackend/rinterface.cpp
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
    trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.get.tempfile.name.Rd
    trunk/rkward/rkward/windows/rkworkplace.cpp
    trunk/rkward/rkward/windows/rkworkplace.h

Added Paths:
-----------
    trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.workplace.Rd

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/ChangeLog	2011-02-14 12:40:34 UTC (rev 3434)
@@ -1,4 +1,6 @@
 --- Version 0.5.5 - XXX-XX-2011
+- Workplace layout is now saved in a separate file, instead of in a hidden object inside the .RData file
+- Added R functions rk.save.workplace() and rk.restore.workplace() to save / restore a set of document windows
 - RKWard now tries to detect, when a workspace has been moved to a new directory, and adjust the paths restored script editor windows, accordingly
 - Fixed: Potential crashes when changing length of a data.frame that is currently opened for editing from R code
 - All pages in the package installation dialog now support sorting and keyboard search

Modified: trunk/rkward/rkward/agents/rkloadagent.cpp
===================================================================
--- trunk/rkward/rkward/agents/rkloadagent.cpp	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/agents/rkloadagent.cpp	2011-02-14 12:40:34 UTC (rev 3434)
@@ -74,7 +74,6 @@
 			RObjectList::getObjectList ()->setWorkspaceURL (KUrl());
 		} else {
 			RKWorkplace::mainWorkplace ()->restoreWorkplace ();
-			RKWorkplace::mainWorkplace ()->clearWorkplaceDescription ();
 		}
 		RKWardMainWindow::getMain ()->slotSetStatusReady ();
 		RKWardMainWindow::getMain ()->setCaption (QString::null);	// trigger update of caption

Modified: trunk/rkward/rkward/agents/rksaveagent.cpp
===================================================================
--- trunk/rkward/rkward/agents/rksaveagent.cpp	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/agents/rksaveagent.cpp	2011-02-14 12:40:34 UTC (rev 3434)
@@ -48,7 +48,6 @@
 	
 	RKWorkplace::mainWorkplace ()->saveWorkplace (save_chain);
 	RKGlobals::rInterface ()->issueCommand (new RCommand ("save.image (\"" + save_url.toLocalFile () + "\")", RCommand::App, QString::null, this), save_chain);
-	RKWorkplace::mainWorkplace ()->clearWorkplaceDescription (save_chain);
 }
 
 RKSaveAgent::~RKSaveAgent () {

Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp	2011-02-14 12:40:34 UTC (rev 3434)
@@ -469,7 +469,7 @@
 
 			issueCommand (".rk.set.reply (\"" + RKCommonFunctions::getUseableRKWardSavefileName (file_prefix, file_extension) + "\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 		} else {
-			issueCommand (".rk.set.reply (\"Too few arguments in call to get.tempfile.name.\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
+			issueCommand ("stop (\"Too few arguments in call to get.tempfile.name.\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 		}
 	} else if (call == "set.output.file") {
 		RK_ASSERT (calllist.count () == 2);
@@ -628,8 +628,22 @@
 		} else {
 			RK_ASSERT (false);
 		}
+	} else if (call == "getWorkspaceUrl") {
+		KUrl url = RObjectList::getObjectList ()->getWorkspaceURL ();
+		if (!url.isEmpty ()) issueCommand (".rk.set.reply (" + RObject::rQuote (url.url ()) + ")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
+	} else if (call == "workplace.layout") {
+		if (calllist.value (1) == "set") {
+			if (calllist.value (2) == "close") RKWorkplace::mainWorkplace ()->closeAll ();
+			QStringList list = calllist.mid (3);
+			RKWorkplace::mainWorkplace ()->restoreWorkplace (list);
+		} else {
+			RK_ASSERT (calllist.value (1) == "get");
+			QStringList list = RKWorkplace::mainWorkplace ()->makeWorkplaceDescription ();
+			for (int i = 0; i < list.size (); ++i) list[i] = RObject::rQuote (list[i]);
+			issueCommand (".rk.set.reply (c (" + list.join (", ") + "))", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
+		}
 	} else {
-		issueCommand (".rk.set.reply (\"Unrecognized call '" + call + "'. Ignoring\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
+		issueCommand ("stop (\"Unrecognized call '" + call + "'. Ignoring\")", RCommand::App | RCommand::Sync, QString::null, 0, 0, in_chain);
 	}
 	
 	closeChain (in_chain);

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/public.R	2011-02-14 12:40:34 UTC (rev 3434)
@@ -110,6 +110,10 @@
 	return (.rk.do.call ("get.tempfile.name", c (prefix, extension)))
 }
 
+"rk.get.workspace.url" <- function () {
+	return (.rk.do.call ("getWorkspaceUrl"))
+}
+
 "rk.get.output.html.file" <- function () {
 	return (.rk.output.html.file)
 }
@@ -129,6 +133,36 @@
 	.rk.do.call ("set.output.file", x);
 }
 
+"rk.save.workplace" <- function (file=NULL) {
+	if (is.null (file)) {
+		file <- rk.get.workspace.url ()
+		if (is.null (file)) file <- rk.get.tempfile.name (prefix="unsaved", extension=".RData")
+		file <- paste (file, "rkworkplace", sep=".")
+	}
+	lines <- .rk.do.call ("workplace.layout", "get")
+	writeLines (lines, file)
+}
+
+"rk.restore.workplace" <- function (file=NULL, close.windows=TRUE) {
+	if (is.null (file)) {
+		if (exists (".rk.workplace.save", envir=globalenv (), inherits=FALSE)) {
+			# For backwards compatibility with workspaces saved by RKWard 0.5.4 and earlier.
+			# TODO: remove in time.
+			lines <- as.character (.GlobalEnv$.rk.workplace.save)
+			rm (list = c (".rk.workplace.save"), envir=globalenv ())
+		} else {
+			file <- rk.get.workspace.url ()
+			if (is.null (file)) file <- rk.get.tempfile.name (prefix="unsaved", extension=".RData")
+			file <- paste (file, "rkworkplace", sep=".")
+		}
+	}
+
+	close <- "close"
+	if (!isTRUE (close.windows)) close <- "noclose"
+	if (!exists ("lines", inherits=FALSE)) lines <- readLines (file)
+	.rk.do.call ("workplace.layout", c ("set", close, lines))
+}
+
 # renames a named object in a data.frame/list without changing it's position
 # TODO: create a generic function instead, that can handle all kinds of renames
 "rk.rename.in.container" <- function (x, old_name, new_name, envir=parent.frame()) {

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.get.tempfile.name.Rd
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.get.tempfile.name.Rd	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.get.tempfile.name.Rd	2011-02-14 12:40:34 UTC (rev 3434)
@@ -1,13 +1,15 @@
 \name{rk.get.tempfile.name}
 
 \alias{rk.get.tempfile.name}
+\alias{rk.get.workspace.url}
 \alias{rk.get.output.html.file}
 \alias{rk.set.output.html.file}
 
-\title{Output file names}
+\title{RKWard file names}
 
 \usage{
 rk.get.tempfile.name(prefix="image", extension=".jpg")
+rk.get.workspace.url()
 rk.get.output.html.file()
 rk.set.output.html.file(x)
 }
@@ -22,10 +24,12 @@
   In RKWard the output is saved as a html file which is located at "~/.rkward" by default. (\bold{TODO}: make this platform free). The name of this html file can be retrieved and set using \code{rk.get.output.html.file} and \code{rk.set.output.html.file}.
 
   \code{rk.get.tempfile.name} returns a non-existing filename inside the directory of the output file. It is mainly used by \link{rk.graph.on} to create filenames suitable for storing images in the output. The filenames of the temporary files are of the form "\code{prefix}\emph{xyz}.\code{extension}". \code{rk.get.tempfile.name} is somewhat misnamed. For truly temporary files, \link{tempfile} is generally more suitable.
+
+  \code{rk.get.workspace.url} returns the url of workspace file which has been loaded in RKWard, or NULL, if no workspace has been loaded. NOTE: This value is note affected by running \code{load} in R, only by loading R workspaces via the RKWard GUI.
 }
 
 \value{
-  \code{rk.get.tempfile.name} and \code{rk.get.output.html.file} returns a string while \code{rk.set.output.html.file} returns \code{NULL}.
+  \code{rk.get.tempfile.name}, \code{rk.get.output.html.file}, and \code{rk.get.workspace.url} return a string while \code{rk.set.output.html.file} returns \code{NULL}.
 }
 
 \author{Thomas Friedrichsmeier \email{rkward-devel at lists.sourceforge.net}}

Added: trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.workplace.Rd
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.workplace.Rd	                        (rev 0)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/man/rk.workplace.Rd	2011-02-14 12:40:34 UTC (rev 3434)
@@ -0,0 +1,45 @@
+\name{RKWard_workplace}
+\alias{rk.save.workplace}
+\alias{rk.restore.workplace}
+
+\title{Save or restore RKWard workplace}
+
+\description{
+}
+
+\usage{
+rk.save.workplace(file=NULL)
+rk.restore.workplace(file=NULL, close.windows=TRUE)
+}
+
+\arguments{
+\item{file}{a character string giving the url of the file to save to, or NULL for automatic selection of a suitable file (see Details).}
+\item{close.windows}{a logical; whether current windows should be closed before restoring.}
+}
+
+\details{
+\code{rk.save.workplace} can be used to save a representation of the RKWard workplace (i.e. which scripts, data edtiors and other windows are shown) to a file. \code{rk.restore.workplace} restores an RKWard workplace as saved by \code{rk.save.workplace}.
+
+If the \code{file} parameter is omitted (or \code{NULL}), a suitable filename is selected automatically. If a workspace has been loaded, this is the URL of the workspace with an appended \code{.rkworkplace}. Otherwise a filename in the RKWard directory, as generated by \link{rk.get.tempfile.name}.
+
+NOTE: Not all types of windows can be saved and restored. Esp. graphics device windows will not be restored (but WILL be closed by \code{rk.restore.workplace()}, if \code{close.windows} is TRUE).
+}
+
+\value{
+Both functions return \code{NULL}.
+}
+
+\seealso{
+\url{rkward://page/rkward_for_r_users}, \link{rk.get.workspace.url}
+}
+
+\author{Thomas Friedrichsmeier \email{rkward-devel at lists.sourceforge.net}}
+
+\examples{
+## Not run
+rk.save.workplace ()
+rk.restore.workplace ()
+## End not run
+}
+
+\keyword{utilities}

Modified: trunk/rkward/rkward/windows/rkworkplace.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkworkplace.cpp	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/windows/rkworkplace.cpp	2011-02-14 12:40:34 UTC (rev 3434)
@@ -51,8 +51,6 @@
 
 #include "../debug.h"
 
-#define RESTORE_WORKPLACE_COMMAND 1
-
 // static
 RKWorkplace *RKWorkplace::main_workplace = 0;
 
@@ -520,18 +518,14 @@
 	RK_TRACE (APP);
 	if (RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace) return;
 
-	QStringList workplace_description = makeWorkplaceDescription ();
-	for (int i=0; i < workplace_description.size (); ++i) workplace_description[i] = RObject::rQuote (workplace_description[i]);
-	QString command = ".rk.workplace.save <- c (" + workplace_description.join (", ") + ')';
-
-	RKGlobals::rInterface ()->issueCommand (command, RCommand::App | RCommand::Sync, i18n ("Save Workplace layout"), 0, 0, chain); 
+	RKGlobals::rInterface ()->issueCommand ("rk.save.workplace()", RCommand::App, i18n ("Save Workplace layout"), 0, 0, chain);
 }
 
 void RKWorkplace::restoreWorkplace (RCommandChain *chain) {
 	RK_TRACE (APP);
 	if (RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace) return;
 
-	RKGlobals::rInterface ()->issueCommand (".rk.workplace.save", RCommand::App | RCommand::Sync | RCommand::GetStringVector, i18n ("Restore Workplace layout"), this, RESTORE_WORKPLACE_COMMAND, chain);
+	RKGlobals::rInterface ()->issueCommand ("rk.restore.workplace()", RCommand::App, i18n ("Restore Workplace layout"), 0, 0, chain);
 }
 
 KUrl checkAdjustRestoredUrl (const QString &_url, const QString old_base) {
@@ -583,20 +577,6 @@
 	}
 }
 
-void RKWorkplace::clearWorkplaceDescription (RCommandChain *chain) {
-	RK_TRACE (APP);
-	if (RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace) return;
-
-	RKGlobals::rInterface ()->issueCommand ("remove (.rk.workplace.save)", RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate, QString::null, 0, 0, chain); 
-}
-
-void RKWorkplace::rCommandDone (RCommand *command) {
-	RK_TRACE (APP);
-
-	RK_ASSERT (command->getFlags () == RESTORE_WORKPLACE_COMMAND);
-	restoreWorkplace (command->getStringVector ());
-}
-
 ///////////////////////// END RKWorkplace ////////////////////////////
 ///////////////////// BEGIN RKMDIWindowHistory ///////////////////////
 

Modified: trunk/rkward/rkward/windows/rkworkplace.h
===================================================================
--- trunk/rkward/rkward/windows/rkworkplace.h	2011-02-13 12:56:37 UTC (rev 3433)
+++ trunk/rkward/rkward/windows/rkworkplace.h	2011-02-14 12:40:34 UTC (rev 3434)
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2007, 2009, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -27,7 +27,6 @@
 #include <kmultitabbar.h>
 
 #include "rkmdiwindow.h"
-#include "../rbackend/rcommandreceiver.h"
 
 class RObject;
 class RCommandChain;
@@ -64,7 +63,7 @@
 
 /** This class (only one instance will probably be around) keeps track of which windows are opened in the workplace, which are detached, etc. Also it is responsible for creating and manipulating those windows.
 It also provides a QWidget (RKWorkplace::view ()), which actually manages the document windows (only those, so far. I.e. this is a half-replacement for KMdi, which will be gone in KDE 4). Currently layout of the document windows is always tabbed. */
-class RKWorkplace : public QWidget, public RCommandReceiver {
+class RKWorkplace : public QWidget {
 	Q_OBJECT
 public:
 /** ctor.
@@ -146,10 +145,6 @@
 /** Like the other restoreWorkplace (), but takes the description as a parameter rather than reading from the R workspace. To be used, when RKSettingsModuleGeneral::workplaceSaveMode () == RKSettingsModuleGeneral::SaveWorkplaceWithSeesion
 @param description workplace description */
 	void restoreWorkplace (const QStringList &description);
-/** Clear the description as set by saveWorkplace () from the R backend. Simply removes the internal object. Since the description is only needed while the workplace is being saved / restored, this should be called shortly after saveWorkplace () and restoreWorkplace ()
-Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace
- at param cahin command chain to place the command in */
-	void clearWorkplaceDescription (RCommandChain *chain=0);
 
 	QStringList makeWorkplaceDescription ();
 
@@ -164,9 +159,6 @@
 /** When windows are attached to the workplace, their QObject::destroyed () signal is connected to this slot. Thereby deleted objects are removed from the workplace automatically */
 	void windowDestroyed (QObject *window);
 	void saveSettings ();
-protected:
-/** handles the result of the command issued in restoreWorkplace. */
-	void rCommandDone (RCommand *command);
 private:
 /** current list of windows. @See getObjectList () */ 
 	RKWorkplaceObjectList windows;


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