Show UnsavedDocumentsDialog when closing window or quitting application
so user can save and or discard docs more efficiently.
This commit is contained in:
parent
b97adced4c
commit
784ad68758
16 changed files with 544 additions and 164 deletions
112
pglab/querytool/UnsavedDocumentsDialog.cpp
Normal file
112
pglab/querytool/UnsavedDocumentsDialog.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include "UnsavedDocumentsDialog.h"
|
||||
#include <QDialogButtonBox>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <algorithm>
|
||||
|
||||
UnsavedDocumentsDialog::UnsavedDocumentsDialog(const QList<std::shared_ptr<SqlDocument>> &docs, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_docs(docs)
|
||||
, m_list(new QListWidget(this))
|
||||
{
|
||||
setWindowTitle(tr("Unsaved changes"));
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->addWidget(new QLabel(tr("The following documents have unsaved changes. Select the documents to save or discard:"), this));
|
||||
|
||||
for (const auto &doc : m_docs) {
|
||||
QStringList windows;
|
||||
for (const QWidget *editor : doc->editors()) {
|
||||
QString title = editor->window()->windowTitle();
|
||||
if (!windows.contains(title))
|
||||
windows.append(title);
|
||||
}
|
||||
|
||||
auto item = new QListWidgetItem(QString("%1 (%2)").arg(doc->fileName(), windows.join(", ")), m_list);
|
||||
item->setToolTip(doc->fileName());
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
layout->addWidget(m_list);
|
||||
|
||||
auto buttons = new QDialogButtonBox(this);
|
||||
auto save_button = buttons->addButton(tr("Save selected"), QDialogButtonBox::AcceptRole);
|
||||
auto discard_button = buttons->addButton(tr("Discard selected"), QDialogButtonBox::DestructiveRole);
|
||||
buttons->addButton(QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
connect(save_button, &QPushButton::clicked, this, [this]() {
|
||||
m_choice = Choice::Save;
|
||||
accept();
|
||||
});
|
||||
connect(discard_button, &QPushButton::clicked, this, [this]() {
|
||||
m_choice = Choice::Discard;
|
||||
accept();
|
||||
});
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<SqlDocument>> UnsavedDocumentsDialog::checkedDocuments() const
|
||||
{
|
||||
QList<std::shared_ptr<SqlDocument>> result;
|
||||
for (int i = 0; i < m_docs.size(); ++i) {
|
||||
if (m_list->item(i)->checkState() == Qt::Checked)
|
||||
result.append(m_docs[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<SqlDocument>> UnsavedDocumentsDialog::uncheckedDocuments() const
|
||||
{
|
||||
QList<std::shared_ptr<SqlDocument>> result;
|
||||
for (int i = 0; i < m_docs.size(); ++i) {
|
||||
if (m_list->item(i)->checkState() != Qt::Checked)
|
||||
result.append(m_docs[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<SqlDocument>> documentsClosedWith(const QList<std::shared_ptr<SqlDocument>> &docs,
|
||||
const std::function<bool(const QWidget*)> &isClosing)
|
||||
{
|
||||
QList<std::shared_ptr<SqlDocument>> result;
|
||||
for (const auto &doc : docs) {
|
||||
const auto &editors = doc->editors();
|
||||
if (!doc->isModified() || editors.isEmpty())
|
||||
continue;
|
||||
|
||||
bool all_closing = std::all_of(editors.begin(), editors.end(),
|
||||
[&isClosing](const QWidget *editor) { return isClosing(editor); });
|
||||
if (all_closing)
|
||||
result.append(doc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool confirmClose(QWidget *parent, const QList<std::shared_ptr<SqlDocument>> &docs)
|
||||
{
|
||||
auto remaining = docs;
|
||||
while (!remaining.isEmpty()) {
|
||||
UnsavedDocumentsDialog dlg(remaining, parent);
|
||||
if (dlg.exec() != QDialog::Accepted || dlg.choice() == UnsavedDocumentsDialog::Choice::Cancel)
|
||||
return false;
|
||||
|
||||
bool save = dlg.choice() == UnsavedDocumentsDialog::Choice::Save;
|
||||
for (const auto &doc : dlg.checkedDocuments()) {
|
||||
if (save) {
|
||||
if (!doc->save(parent))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
doc->setModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Show the dialog again for the documents the user did not select.
|
||||
remaining = dlg.uncheckedDocuments();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue