[education/rkward/devel/workspace_output] rkward: Implement workspace-save-on-exit with the new save dialog.

Thomas Friedrichsmeier null at kde.org
Wed Oct 28 17:57:13 GMT 2020


Git commit 5d237f4b65a38ff66c7021f50a94d4501103eeec by Thomas Friedrichsmeier.
Committed on 28/10/2020 at 17:55.
Pushed by tfry into branch 'devel/workspace_output'.

Implement workspace-save-on-exit with the new save dialog.

This commit also does away with most of the complexity in the previously over-engineered RKSaveAgent.

M  +32   -75   rkward/agents/rksaveagent.cpp
M  +8    -20   rkward/agents/rksaveagent.h
M  +13   -10   rkward/dialogs/rksavemodifieddialog.cpp
M  +1    -1    rkward/misc/rkoutputdirectory.cpp
M  +13   -31   rkward/rkward.cpp
M  +15   -14   rkward/windows/rkworkplace.cpp
M  +4    -3    rkward/windows/rkworkplace.h

https://invent.kde.org/education/rkward/commit/5d237f4b65a38ff66c7021f50a94d4501103eeec

diff --git a/rkward/agents/rksaveagent.cpp b/rkward/agents/rksaveagent.cpp
index 526e19ee..b9b8e0e3 100644
--- a/rkward/agents/rksaveagent.cpp
+++ b/rkward/agents/rksaveagent.cpp
@@ -2,7 +2,7 @@
                           rksaveagent  -  description
                              -------------------
     begin                : Sun Aug 29 2004
-    copyright            : (C) 2004, 2009, 2010, 2011, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2004-2020 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -23,6 +23,7 @@
 #include <QFileDialog>
 
 #include "../rbackend/rkrinterface.h"
+#include "../misc/rkprogresscontrol.h"
 #include "../core/robjectlist.h"
 #include "../rkglobals.h"
 #include "../rkward.h"
@@ -31,32 +32,6 @@
 
 #include "../debug.h"
 
-RKSaveAgent::RKSaveAgent (QUrl url, bool save_file_as, DoneAction when_done, QUrl load_url) : QObject () {
-	RK_TRACE (APP);
-	save_url = url;
-	RKSaveAgent::when_done = when_done;
-	RKSaveAgent::load_url = load_url;
-	previous_url = RKWorkplace::mainWorkplace ()->workspaceURL ();
-	save_chain = 0;
-	if (save_url.isEmpty () || save_file_as) {
-		if (!askURL ()) {
-			deleteLater();
-			return;
-		}
-	}
-	
-	RKWorkplace::mainWorkplace ()->flushAllData ();
-	save_chain = RKGlobals::rInterface ()->startChain (0);
-	
-	RKWorkplace::mainWorkplace ()->setWorkspaceURL (save_url, true);
-	RKWorkplace::mainWorkplace ()->saveWorkplace (save_chain);
-	RKGlobals::rInterface ()->issueCommand (new RCommand ("save.image (" + RObject::rQuote (save_url.toLocalFile ()) + ')', RCommand::App, QString (), this), save_chain);
-}
-
-RKSaveAgent::~RKSaveAgent () {
-	RK_TRACE (APP);
-}
-
 // We save to several files at once, meaning the standard overwrite check is not quite good enough for us.
 // More importantly, it is entirely broken in KF5 < 5.22.0 (https://bugs.kde.org/show_bug.cgi?id=360666)
 // So check for overwriting ourselves.
@@ -93,56 +68,38 @@ bool checkOverwriteWorkspace (QUrl url, QWidget *parent) {
 	                                                                  KStandardGuiItem::cancel (), QString (), KMessageBox::Options (KMessageBox::Notify | KMessageBox::Dangerous));
 }
 
-bool RKSaveAgent::askURL () {
-	RK_TRACE (APP);
-	save_url = QUrl::fromLocalFile (QFileDialog::getSaveFileName (RKWardMainWindow::getMain (), QString (), save_url.toLocalFile (), i18n ("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter ()), 0, QFileDialog::DontConfirmOverwrite));
-	if (!checkOverwriteWorkspace (save_url, RKWardMainWindow::getMain ())) save_url.clear ();
+bool RKSaveAgent::saveWorkspaceAs(const QUrl& previous_url) {
+	RK_TRACE(APP);
 
-	if (save_url.isEmpty ()) {
-		if (when_done != DoNothing) {
-			if (KMessageBox::warningYesNo (0, i18n ("No filename given. Your data was NOT saved. Do you still want to proceed?")) != KMessageBox::Yes) when_done = DoNothing;
-		}
-		return false;
-	}
-	return true;
-}
+	QUrl save_url = QUrl::fromLocalFile(QFileDialog::getSaveFileName(RKWardMainWindow::getMain(), QString(), previous_url.toLocalFile(), i18n("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter()), 0, QFileDialog::DontConfirmOverwrite));
+	if (save_url.isEmpty()) return false;
+	if (!checkOverwriteWorkspace(save_url, RKWardMainWindow::getMain())) return false;
 
-void RKSaveAgent::rCommandDone (RCommand *command) {
-	RK_TRACE (APP);
-	if (command->hasError ()) {
-		RKWorkplace::mainWorkplace ()->setWorkspaceURL (previous_url);
-
-		int res;
-		if (when_done != DoNothing) {
-			res = KMessageBox::warningYesNoCancel (0, i18n ("Saving to file '%1' failed. What do you want to do?", save_url.path ()), i18n ("Save failed"), KGuiItem (i18n ("Try saving with a different filename")), KGuiItem (i18n ("Saving failed")));
-		} else {
-			res = KMessageBox::warningYesNo (0, i18n ("Saving to file '%1' failed. Do you want to try saving to a different filename?", save_url.path ()));
-		}
-
-		if (res == KMessageBox::Yes) {
-			if (askURL ()) {
-				RKGlobals::rInterface ()->issueCommand (new RCommand ("save.image (\"" + save_url.toLocalFile () + "\")", RCommand::App, QString (), this), save_chain);
-				return;
-			}
-		} else if (res == KMessageBox::No) {
-			done ();
-			return;
-		}
-
-		// else
-		when_done = DoNothing;
-	}
-	done ();
+	return saveWorkspace(save_url);
 }
 
-void RKSaveAgent::done () {
-	RK_TRACE (APP);
-	RKWardMainWindow::getMain ()->setWorkspaceMightBeModified (false);
-	if (save_chain) {
-		RKGlobals::rInterface ()->closeChain (save_chain);
-	}
-	if (when_done == Load) {
-		RKWardMainWindow::getMain ()->askOpenWorkspace (load_url);
-	}
-	deleteLater ();
+bool RKSaveAgent::saveWorkspace(const QUrl& _url) {
+	RK_TRACE(APP);
+
+	QUrl url = _url;
+	if (url.isEmpty()) url = RKWorkplace::mainWorkplace()->workspaceURL();
+	if (url.isEmpty()) return saveWorkspaceAs();
+
+	RKWorkplace::mainWorkplace()->flushAllData();
+	auto save_chain = RKGlobals::rInterface()->startChain(0);
+
+	RKWorkplace::mainWorkplace()->saveWorkplace(url, save_chain);
+	auto command = new RCommand("save.image(" + RObject::rQuote(url.toLocalFile()) + ')', RCommand::App);
+	RKProgressControl control(RKWardMainWindow::getMain(), i18n("Workspace is being saved. <b>Hint:</b>Should this take an unusually long time, on a regular sized workspace, this may be due to other commands still pending completion in the R backend."), i18n("Saving workspace"), RKProgressControl::CancellableNoProgress);
+	control.addRCommand(command, true);
+	bool success = false;
+	QObject::connect(command->notifier(), &RCommandNotifier::commandFinished, [&success, command]() { success = command->succeeded(); });
+	RKGlobals::rInterface()->issueCommand(command, save_chain);
+	control.doModal(false);
+	RKGlobals::rInterface()->closeChain(save_chain);
+
+	if (!success) KMessageBox::error(RKWardMainWindow::getMain(), i18n("Save failed"), i18n("An error occured while trying to save the workspace. You data was <b>not</b> saved."));
+	RKWorkplace::mainWorkplace()->setWorkspaceURL(url, true);
+
+	return success;
 }
diff --git a/rkward/agents/rksaveagent.h b/rkward/agents/rksaveagent.h
index 78533360..4b083a47 100644
--- a/rkward/agents/rksaveagent.h
+++ b/rkward/agents/rksaveagent.h
@@ -2,7 +2,7 @@
                           rksaveagent  -  description
                              -------------------
     begin                : Sun Aug 29 2004
-    copyright            : (C) 2004, 2009, 2011 by Thomas Friedrichsmeier
+    copyright            : (C) 2004-2020 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -20,33 +20,21 @@
 #include "../rbackend/rcommandreceiver.h"
 
 #include <QUrl>
-#include <QObject>
 
 class RCommandChain;
 
 /**
-This class basically provides a mechanism to let the user save a workspace, find out whether saving was successful and - if it was not - to ask for a new filename or the like.
+This class used to have much more (over-)complexity. It could probably be merged into RKWorkplace, today. Used to control workspace saving.
 
 @author Thomas Friedrichsmeier
 */
-class RKSaveAgent : public RCommandReceiver, public QObject {
+class RKSaveAgent {
 public:
-	enum DoneAction { DoNothing=0, Load=1 };
-
-/** creates a new RKSaveAgent. If when_done == Quit, the RKSaveAgent will quit the application as soon as saving was successful (or it asked to by the user). Similarly, if when_done==Load, it will load a new workspace after saving (specify the url in load_url). If url is given (not empty), and not save_file_as, the agent will try to save to the given url, else it will ask the user to specify a url. RKSaveAgent will self destruct when done. */
-	explicit RKSaveAgent (QUrl url, bool save_file_as=false, DoneAction when_done=DoNothing, QUrl load_url=QUrl());
-	
-	~RKSaveAgent ();
-protected:
-	void rCommandDone (RCommand *command) override;
-private:
-	bool askURL ();
-	void done ();
-	RCommandChain *save_chain;
-	QUrl save_url;
-	QUrl load_url;
-	QUrl previous_url;
-	DoneAction when_done;
+/** Save the workspace. If no URL is given use the last known save url. If the workspace has not been saved, previously, ask for url to save to. */
+	static bool saveWorkspace(const QUrl &url=QUrl());
+/** Save the workspace, asking for a (new) file name.
+ @param previous_url If given, specified the default directory and file name. */
+	static bool saveWorkspaceAs(const QUrl &previous_url=QUrl());
 };
 
 #endif
diff --git a/rkward/dialogs/rksavemodifieddialog.cpp b/rkward/dialogs/rksavemodifieddialog.cpp
index 4023400f..50331462 100644
--- a/rkward/dialogs/rksavemodifieddialog.cpp
+++ b/rkward/dialogs/rksavemodifieddialog.cpp
@@ -30,6 +30,7 @@
 #include "../windows/rkworkplace.h"
 #include "../windows/rkhtmlwindow.h"
 #include "../misc/rkoutputdirectory.h"
+#include "../agents/rksaveagent.h"
 
 #include "../debug.h"
 
@@ -81,15 +82,14 @@ RKSaveModifiedDialog::RKSaveModifiedDialog (QWidget* parent, QList<RKMDIWindow*>
 
 	save_project_check = 0;
 	tree->header ()->hide ();
-#warning TODO: remove me
-project = true;
+
 	if (project) {
 		QTreeWidgetItem *header = makeHeaderItem (i18n ("R Workspace (Data and Functions)"), tree);
 		QString url = RKWorkplace::mainWorkplace ()->workspaceURL ().toDisplayString ();
 		if (url.isEmpty ()) {
 			url = i18n ("Not previously saved");
 		}
-		QTreeWidgetItem *save_project_check = new QTreeWidgetItem (QStringList (url));
+		save_project_check = new QTreeWidgetItem (QStringList (url));
 		header->addChild (save_project_check);
 		save_project_check->setCheckState (0, Qt::Checked);
 
@@ -142,7 +142,8 @@ void RKSaveModifiedDialog::saveWorkplaceChanged () {
 // TODO: enable / disable "save with workplace" option for Output windows
 }
 
-void RKSaveModifiedDialog::saveSelected () {
+#include <KMessageBox>
+void RKSaveModifiedDialog::saveSelected() {
 	RK_TRACE (APP);
 
 	bool all_ok = true;
@@ -152,17 +153,19 @@ void RKSaveModifiedDialog::saveSelected () {
 		if (!it.value ()->save ()) all_ok = false; // but we proceed with the others
 	}
 
-	if (save_project_check && save_project_check->checkState (0) == Qt::Checked) {
-#warning TODO
+	if (save_project_check && save_project_check->checkState(0) == Qt::Checked) {
+		if (!RKSaveAgent::saveWorkspace()) all_ok = false;
 	}
 
-	for (auto it = outputdir_checklist.constBegin (); it != outputdir_checklist.constEnd (); ++it) {
+	for (auto it = outputdir_checklist.constBegin(); it != outputdir_checklist.constEnd(); ++it) {
 		if (it.key ()->checkState (0) != Qt::Checked) continue;
 		RKOutputDirectory *dir = RKOutputDirectory::getOutputById(it.value());
-		if (dir) dir->save();
+		if (dir) {
+			if (dir->save().failed()) all_ok = false;
+		}
 		else RK_ASSERT(dir);
 	}
 
-	if (all_ok) accept ();
-	else reject ();
+	if (all_ok) accept();
+	else reject();
 }
diff --git a/rkward/misc/rkoutputdirectory.cpp b/rkward/misc/rkoutputdirectory.cpp
index d357d0ba..b2b1b1a4 100644
--- a/rkward/misc/rkoutputdirectory.cpp
+++ b/rkward/misc/rkoutputdirectory.cpp
@@ -115,7 +115,7 @@ GenericRRequestResult RKOutputDirectory::exportAs (const QString& _dest, RKOutpu
 	if (dest.isEmpty()) {
 		QFileDialog dialog(RKWardMainWindow::getMain(), i18n("Select destination file name"), QFileInfo(save_filename).absolutePath());
 		dialog.setFileMode(QFileDialog::AnyFile);
-		dialog.setNameFilters(QStringList() << i18n("RKWard Output Files (*.rko)") << i18n("All Files (*)"));
+		dialog.setNameFilters(QStringList() << i18n("RKWard Output Files [*.rko](*.rko)") << i18n("All Files [*](*)"));
 		dialog.setAcceptMode(QFileDialog::AcceptSave);
 		dialog.setOption(QFileDialog::DontConfirmOverwrite, true);  // custom handling below
 
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index cf1e655c..7218c398 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -71,6 +71,7 @@
 #include "dialogs/rkimportdialog.h"
 #include "dialogs/rkrecoverdialog.h"
 #include "dialogs/rksetupwizard.h"
+#include "dialogs/rksavemodifieddialog.h"
 #include "agents/rksaveagent.h"
 #include "agents/rkloadagent.h"
 #include "agents/rkquitagent.h"
@@ -791,26 +792,10 @@ bool RKWardMainWindow::doQueryQuit () {
 	if (RKSettingsModuleGeneral::workplaceSaveMode () == RKSettingsModuleGeneral::SaveWorkplaceWithSession) {
 		RKSettingsModuleGeneral::setSavedWorkplace (RKWorkplace::mainWorkplace ()->makeWorkplaceDescription ().join ("\n"), KSharedConfig::openConfig ().data ());
 	}
-
-//	if (!RObjectList::getGlobalEnv ()->isEmpty ()) {
-	int res;
-	res = KMessageBox::questionYesNoCancel (this, i18n ("Quitting RKWard: Do you want to save the workspace?"), i18n ("Save Workspace?"), KStandardGuiItem::save (), KStandardGuiItem::discard (), KGuiItem (i18n ("Do Not Quit")));
-	if (res == KMessageBox::Yes) {
-		new RKSaveAgent (RKWorkplace::mainWorkplace ()->workspaceURL (), false, RKSaveAgent::DoNothing);
-	} else if (res == KMessageBox::Cancel) {
-		slotSetStatusReady ();
-		return false;
-	}
-//	}
-
-	lockGUIRebuild (true);
-	if (!RKWorkplace::mainWorkplace ()->closeAll ()) {
-		// User cancelled closing, when asked to save changes
+	if (!RKWorkplace::mainWorkplace()->closeAll(RKMDIWindow::AnyType, RKMDIWindow::AnyWindowState, true)) {
 		slotSetStatusReady ();
-		lockGUIRebuild (false);
 		return false;
 	}
-//	lockGUIRebuild (false);  // No need to update GUI anymore (and doing so is potentially asking for trouble, anyway)
 
 	return true;
 }
@@ -827,28 +812,25 @@ void RKWardMainWindow::slotNewDataFrame () {
 void RKWardMainWindow::askOpenWorkspace (const QUrl &url) {
 	RK_TRACE (APP);
 
-	if (!no_ask_save && ((!RObjectList::getGlobalEnv ()->isEmpty () && workspace_modified) || !RKGlobals::rInterface ()->backendIsIdle ())) {
+	if (!no_ask_save && ((!RObjectList::getGlobalEnv()->isEmpty() && workspace_modified) || !RKGlobals::rInterface()->backendIsIdle())) {
 		int res;
-		res = KMessageBox::questionYesNoCancel (this, i18n ("Do you want to save the current workspace?"), i18n ("Save Workspace?"));
-		if (res == KMessageBox::Yes) {
-			new RKSaveAgent (RKWorkplace::mainWorkplace ()->workspaceURL (), false, RKSaveAgent::Load, url);
-		} else if (res != KMessageBox::No) { // Cancel
-			return;
-		}
+		res = KMessageBox::questionYesNoCancel (this, i18n("Do you want to save the current workspace?"), i18n("Save Workspace?"));
+		if (res != KMessageBox::No) return;  // Cancel
+		if (!RKSaveAgent::saveWorkspace()) return; // Save failed
 	}
 
-	slotCloseAllEditors ();
+	slotCloseAllEditors();
 
 	slotSetStatusBarText(i18n("Opening workspace..."));
 	QUrl lurl = url;
 	if (lurl.isEmpty ()) {
-		lurl = QFileDialog::getOpenFileUrl (this, i18n("Select workspace to open..."), RKSettingsModuleGeneral::lastUsedUrlFor ("workspaces"), i18n ("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter ()));
+		lurl = QFileDialog::getOpenFileUrl(this, i18n("Select workspace to open..."), RKSettingsModuleGeneral::lastUsedUrlFor("workspaces"), i18n("R Workspace Files [%1](%1);;All files [*](*)", RKSettingsModuleGeneral::workspaceFilenameFilter()));
 	}
 	if (!lurl.isEmpty ()) {
-		RKSettingsModuleGeneral::updateLastUsedUrl ("workspaces", lurl.adjusted (QUrl::RemoveFilename));
-		openWorkspace (lurl);
+		RKSettingsModuleGeneral::updateLastUsedUrl("workspaces", lurl.adjusted(QUrl::RemoveFilename));
+		openWorkspace(lurl);
 	}
-	slotSetStatusReady ();
+	slotSetStatusReady();
 }
 
 void RKWardMainWindow::slotFileOpenWorkspace () {
@@ -864,12 +846,12 @@ void RKWardMainWindow::slotFileLoadLibs () {
 
 void RKWardMainWindow::slotFileSaveWorkspace () {
 	RK_TRACE (APP);
-	new RKSaveAgent (RKWorkplace::mainWorkplace ()->workspaceURL ());
+	RKSaveAgent::saveWorkspace();
 }
 
 void RKWardMainWindow::slotFileSaveWorkspaceAs () {
 	RK_TRACE (APP);
-	new RKSaveAgent (RKWorkplace::mainWorkplace ()->workspaceURL (), true);
+	RKSaveAgent::saveWorkspaceAs();
 }
 
 void RKWardMainWindow::addWorkspaceUrl (const QUrl &url) {
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index c2d804ed..e0289666 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -663,26 +663,25 @@ RKWorkplace::RKWorkplaceObjectList RKWorkplace::getObjectList (int type, int sta
 	return ret;
 }
 
-bool RKWorkplace::closeAll (int type, int state) {
-	RK_TRACE (APP);
+bool RKWorkplace::closeAll(int type, int state, bool ask_close_project) {
+	RK_TRACE(APP);
 
-	return closeWindows (windows);
+	return closeWindows(getObjectList(type, state), ask_close_project);
 }
 
-bool RKWorkplace::closeWindows (QList<RKMDIWindow*> windows) {
-	RK_TRACE (APP);
+bool RKWorkplace::closeWindows(QList<RKMDIWindow*> windows, bool ask_close_project) {
+	RK_TRACE(APP);
 
 	bool allclosed = true;
-	RKWardMainWindow::getMain ()->lockGUIRebuild (true);
+	RKWardMainWindow::getMain()->lockGUIRebuild(true);
 
-	bool ok = RKSaveModifiedDialog::askSaveModified (this, windows, false);
+	bool ok = RKSaveModifiedDialog::askSaveModified(this, windows, ask_close_project);
 	if (ok) {
-		for (int i = windows.size () - 1; i >= 0; --i) {
-			RK_ASSERT(closeWindow (windows[i], RKMDIWindow::NoAskSaveModified));
-			// TODO: Do not ask for saving _again_
+		for (int i = windows.size() - 1; i >= 0; --i) {
+			RK_ASSERT(closeWindow(windows[i], RKMDIWindow::NoAskSaveModified));
 		}
 	}
-	RKWardMainWindow::getMain ()->lockGUIRebuild (false);
+	RKWardMainWindow::getMain()->lockGUIRebuild(false);
 	return ok;
 }
 
@@ -909,13 +908,15 @@ QStringList RKWorkplace::makeWorkplaceDescription () {
 	return workplace_description;
 }
 
-void RKWorkplace::saveWorkplace (RCommandChain *chain) {
+void RKWorkplace::saveWorkplace(const QUrl& for_url, RCommandChain *chain) {
 	RK_TRACE (APP);
 // TODO: This is still a mess. All workplace-related settings, including the workspaceConfig(), should be saved to a single place, and in 
 // standard KConfig format.
-	if (RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace) return;
+	if (RKSettingsModuleGeneral::workplaceSaveMode() != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace) return;
 
-	RKGlobals::rInterface ()->issueCommand ("rk.save.workplace(description=" + RObject::rQuote (makeWorkplaceDescription().join ("\n")) + ')', RCommand::App, i18n ("Save Workplace layout"), 0, 0, chain);
+	QString file_param;
+	if (!for_url.isEmpty()) file_param = QString("file=") + RObject::rQuote(for_url.toLocalFile()) + QStringLiteral(", ");
+	RKGlobals::rInterface()->issueCommand("rk.save.workplace(" + file_param + "description=" + RObject::rQuote (makeWorkplaceDescription().join ("\n")) + ')', RCommand::App, i18n ("Save Workplace layout"), 0, 0, chain);
 }
 
 void RKWorkplace::restoreWorkplace (RCommandChain *chain, bool merge) {
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 0eb26afe..9d76cf1d 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -161,16 +161,17 @@ public:
 /** Close the given windows, whether they are attached or detached.
 @param windows list windows to close
 @returns true, if _all_ windows were actually closed. */
-	bool closeWindows (QList<RKMDIWindow*> windows);
+	bool closeWindows (QList<RKMDIWindow*> windows, bool ask_close_project=false);
 /** Closes all windows of the given type(s). Default call (no arguments) closes all windows
 @param type: A bitwise OR of RKWorkplaceObjectType
 @param state: A bitwise OR of RKWorkplaceObjectState
 @returns false if cancelled by user (user was prompted for saving, and chose cancel) */
-	bool closeAll (int type=RKMDIWindow::AnyType, int state=RKMDIWindow::AnyWindowState);
+	bool closeAll(int type=RKMDIWindow::AnyType, int state=RKMDIWindow::AnyWindowState, bool ask_close_project=false);
 
 /** Write a description of all current windows to the R backend. This can later be read by restoreWorkplace (). Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace
+ at param url the url to use. Can be left null, in which case the current workspace url will be used.
 @param chain command chain to place the command in */
-	void saveWorkplace (RCommandChain *chain=0);
+	void saveWorkplace (const QUrl &for_url=QUrl(), RCommandChain *chain=0);
 /** Load a description of windows from the R backend (created by saveWorkplace ()), and (try to) restore all windows accordingly
 Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsModuleGeneral::SaveWorkplaceWithWorkspace
 @param chain command chain to place the command in */




More information about the rkward-tracker mailing list