[education/rkward/devel/workspace_output] rkward: WIP: Start working on a sane save dialog for everything that may need saving on exit (or project switch)
Thomas Friedrichsmeier
null at kde.org
Sat Oct 10 09:18:45 BST 2020
Git commit a385a01753771c6aff8085ca0972f17e466569b2 by Thomas Friedrichsmeier.
Committed on 29/11/2017 at 11:55.
Pushed by tfry into branch 'devel/workspace_output'.
WIP: Start working on a sane save dialog for everything that may need saving on exit (or project switch)
M +1 -0 rkward/dialogs/CMakeLists.txt
A +114 -0 rkward/dialogs/rksavemodifieddialog.cpp [License: GPL (v2+)]
A +45 -0 rkward/dialogs/rksavemodifieddialog.h [License: GPL (v2+)]
M +11 -5 rkward/windows/rkworkplace.cpp
M +6 -4 rkward/windows/rkworkplace.h
https://invent.kde.org/education/rkward/commit/a385a01753771c6aff8085ca0972f17e466569b2
diff --git a/rkward/dialogs/CMakeLists.txt b/rkward/dialogs/CMakeLists.txt
index 08a8b21d..da6936cc 100644
--- a/rkward/dialogs/CMakeLists.txt
+++ b/rkward/dialogs/CMakeLists.txt
@@ -8,6 +8,7 @@ SET(dialogs_STAT_SRCS
rkselectlistdialog.cpp
rkrecoverdialog.cpp
rkerrordialog.cpp
+ rksavemodifieddialog.cpp
)
ADD_LIBRARY(dialogs STATIC ${dialogs_STAT_SRCS})
diff --git a/rkward/dialogs/rksavemodifieddialog.cpp b/rkward/dialogs/rksavemodifieddialog.cpp
new file mode 100644
index 00000000..3e0fc845
--- /dev/null
+++ b/rkward/dialogs/rksavemodifieddialog.cpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ rksavemodifieddialog - description
+ -------------------
+ begin : Wed Jul 12 2017
+ copyright : (C) 2017 by Thomas Friedrichsmeier
+ email : thomas.friedrichsmeier at kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "rksavemodifieddialog.h"
+
+#include <QTreeWidget>
+#include <QDialogButtonBox>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QHeaderView>
+#include <QLabel>
+#include <QPointer>
+
+#include <klocale.h>
+
+#include "../debug.h"
+
+bool RKSaveModifiedDialog::askSaveModified (QWidget* parent, QList <RKMDIWindow*> windows, bool project) {
+ RK_TRACE (APP);
+
+ QList<RKMDIWindow*> modified_wins;
+ for (int i = 0; i < windows.size (); ++i) {
+ if (windows[i]->isModified ()) {
+ modified_wins.append (windows[i]);
+ }
+ }
+
+ if (project || !modified_wins.isEmpty ()) {
+ RKSaveModifiedDialog dialog (parent, modified_wins, project);
+ dialog.exec ();
+ if (dialog.result () == QDialog::Rejected) return false;
+ }
+
+ return true;
+}
+
+RKSaveModifiedDialog::RKSaveModifiedDialog (QWidget* parent, QList<RKMDIWindow*> modified_wins, bool project) : QDialog (parent) {
+ RK_TRACE (APP);
+
+ setWindowTitle (i18n ("Save modified"));
+
+ QVBoxLayout* v_layout = new QVBoxLayout (this);
+ QLabel *label = new QLabel (i18n ("The following items have been modified. Do you want to save them before closing?"));
+ v_layout->addWidget (label);
+
+ QTreeWidget *tree = new QTreeWidget ();
+ v_layout->addWidget (tree);
+
+ tree->header ()->hide ();
+ if (project) {
+ }
+ if (!modified_wins.isEmpty ()) {
+ QTreeWidgetItem* header = new QTreeWidgetItem (QStringList (i18n ("Scripts")));
+ header->setFirstColumnSpanned (true);
+ header->setFlags (Qt::ItemIsEnabled);
+ QFont f = tree->font ();
+ f.setBold (true);
+ header->setFont (0, f);
+ tree->addTopLevelItem (header);
+ header->setExpanded (true);
+ for (int i = 0; i < modified_wins.size (); ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem (QStringList (modified_wins[i]->fullCaption ()));
+ item->setFirstColumnSpanned (true);
+ header->addChild (item);
+ item->setCheckState (0, Qt::Checked);
+ item->setData (0, Qt::UserRole, QVariant::fromValue (QPointer<RKMDIWindow> (modified_wins[i])));
+ }
+ }
+
+ QDialogButtonBox *buttonbox = new QDialogButtonBox (this);
+ v_layout->addWidget (buttonbox);
+
+ buttonbox->setStandardButtons (QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel);
+ buttonbox->button (QDialogButtonBox::Save)->setDefault (true);
+ buttonbox->button (QDialogButtonBox::Save)->setText (i18nc ("Save the selected items", "Save selected"));
+ buttonbox->button (QDialogButtonBox::Discard)->setText (i18n ("Discard all"));
+ buttonbox->button (QDialogButtonBox::Cancel)->setText (i18n ("Do not close"));
+
+ connect (buttonbox->button (QDialogButtonBox::Save), &QPushButton::clicked, this, &RKSaveModifiedDialog::saveSelected);
+ connect (buttonbox->button (QDialogButtonBox::Discard), &QPushButton::clicked, this, &QDialog::accept);
+ connect (buttonbox->button (QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QDialog::reject);
+
+ setModal (true);
+}
+
+RKSaveModifiedDialog::~RKSaveModifiedDialog () {
+ RK_TRACE (APP);
+}
+
+void RKSaveModifiedDialog::saveWorkplaceChanged () {
+ RK_TRACE (APP);
+// TODO: enable / disable "save with workplace" option for Output windows
+}
+
+void RKSaveModifiedDialog::saveSelected () {
+ RK_TRACE (APP);
+// TODO: get list of selected items from tree, and save them
+// TODO: _when done_:
+// accepted ();
+}
diff --git a/rkward/dialogs/rksavemodifieddialog.h b/rkward/dialogs/rksavemodifieddialog.h
new file mode 100644
index 00000000..9a711bf9
--- /dev/null
+++ b/rkward/dialogs/rksavemodifieddialog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ rksavemodifieddialog - description
+ -------------------
+ begin : Wed Jul 12 2017
+ copyright : (C) 2017 by Thomas Friedrichsmeier
+ email : thomas.friedrichsmeier at kdemail.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef RKSAVEMODIFIEDDIALOG_H
+#define RKSAVEMODIFIEDDIALOG_H
+
+#include <QDialog>
+#include <QList>
+
+#include "../windows/rkmdiwindow.h"
+
+class QTreeWidget;
+
+class RKSaveModifiedDialog : public QDialog {
+ Q_OBJECT
+public:
+/** Provide a combined dialog to ask for saving and modified documents among the given list of windows. Call before closing the app, merging workspaces, etc.
+ * @param windows List of windows to ask about
+ * @param project Whether to also ask about saving project related resources: Outputs, Workplace, Workspace.
+ * @returns true, if the user chose to proceed (with or without saving modications), _and_ saving was successful; false, if the user cancelled the operation, or some saves failed. */
+ static bool askSaveModified (QWidget* parent, QList<RKMDIWindow*> windows, bool project);
+private:
+ RKSaveModifiedDialog (QWidget* parent, QList<RKMDIWindow*> modified_windows, bool project);
+ virtual ~RKSaveModifiedDialog ();
+ QTreeWidget *tree;
+private slots:
+ void saveWorkplaceChanged ();
+ void saveSelected ();
+};
+
+#endif
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 45ee406c..f33be251 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -43,6 +43,7 @@
#include "../core/robjectlist.h"
#include "../dataeditor/rkeditor.h"
#include "../dataeditor/rkeditordataframe.h"
+#include "../dialogs/rksavemodifieddialog.h"
#include "../robjectviewer.h"
#include "../settings/rksettingsmodulegeneral.h"
#include "../settings/rksettingsmodulecommandeditor.h"
@@ -639,20 +640,25 @@ RKWorkplace::RKWorkplaceObjectList RKWorkplace::getObjectList (int type, int sta
return ret;
}
-void RKWorkplace::closeAll (int type, int state) {
+bool RKWorkplace::closeAll (int type, int state) {
RK_TRACE (APP);
- closeWindows (getObjectList (type, state));
+ return closeWindows (windows);
}
-void RKWorkplace::closeWindows (QList<RKMDIWindow*> windows) {
+bool RKWorkplace::closeWindows (QList<RKMDIWindow*> windows) {
RK_TRACE (APP);
RKWardMainWindow::getMain ()->lockGUIRebuild (true);
- for (int i = windows.size () - 1; i >= 0; --i) {
- closeWindow (windows[i]);
+ bool ok = RKSaveModifiedDialog::askSaveModified (this, windows, false);
+ if (ok) {
+ for (int i = windows.size () - 1; i >= 0; --i) {
+ closeWindow (windows[i]);
+ // TODO: Do not ask for saving _again_
+ }
}
RKWardMainWindow::getMain ()->lockGUIRebuild (false);
+ return ok;
}
void RKWorkplace::removeWindow (QObject *object) {
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 73a7e4e5..f43673ab 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -139,12 +139,14 @@ public:
@param window window to close */
void closeWindow (RKMDIWindow *window);
/** Close the given windows, whether they are attached or detached. TODO: Be smart about asking what to save.
- at param windows list windows to close */
- void closeWindows (QList<RKMDIWindow*> windows);
+ at param windows list windows to close
+ at returns false if cancelled by user (user was prompted for saving, and chose cancel) */
+ bool closeWindows (QList<RKMDIWindow*> windows);
/** Closes all windows of the given type(s). Default call (no arguments) closes all windows
@param type: A bitwise OR of RKWorkplaceObjectType
- at param state: A bitwise OR of RKWorkplaceObjectState */
- void closeAll (int type=RKMDIWindow::AnyType, int state=RKMDIWindow::AnyWindowState);
+ at param state: A bitwise OR of RKWorkplaceObjectState
+ at returns false if cancelled by user (user was prompted for saving, and chose cancel) */
+ bool closeAll (int type=RKMDIWindow::AnyType, int state=RKMDIWindow::AnyWindowState);
/** 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
@param chain command chain to place the command in */
More information about the rkward-tracker
mailing list