2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2008-12-02 14:09:21 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "saveitemsdialog.h"
|
|
|
|
|
|
2023-01-16 17:20:07 +01:00
|
|
|
#include "../coreplugintr.h"
|
|
|
|
|
#include "../diffservice.h"
|
|
|
|
|
#include "../idocument.h"
|
2015-02-26 13:38:54 +01:00
|
|
|
|
2022-07-28 16:09:45 +02:00
|
|
|
#include <utils/filepath.h>
|
2022-05-31 11:16:44 +02:00
|
|
|
#include <utils/fsengine/fileiconprovider.h>
|
2012-08-23 15:53:58 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2022-07-27 10:27:56 +02:00
|
|
|
#include <utils/layoutbuilder.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-10-05 17:37:00 +02:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
|
|
|
|
|
2022-07-27 10:27:56 +02:00
|
|
|
#include <QCheckBox>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDialogButtonBox>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFileInfo>
|
2022-07-27 10:27:56 +02:00
|
|
|
#include <QLabel>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QPushButton>
|
2022-07-27 10:27:56 +02:00
|
|
|
#include <QTreeWidget>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-14 16:43:51 +01:00
|
|
|
Q_DECLARE_METATYPE(Core::IDocument*)
|
2009-03-24 12:27:58 +01:00
|
|
|
|
2023-01-16 17:20:07 +01:00
|
|
|
namespace Core::Internal {
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-27 10:27:56 +02:00
|
|
|
SaveItemsDialog::SaveItemsDialog(QWidget *parent, const QList<IDocument *> &items)
|
2009-03-24 12:27:58 +01:00
|
|
|
: QDialog(parent)
|
2023-01-16 17:20:07 +01:00
|
|
|
, m_msgLabel(new QLabel(Tr::tr("The following files have unsaved changes:")))
|
2022-07-27 10:27:56 +02:00
|
|
|
, m_treeWidget(new QTreeWidget)
|
2023-01-16 17:20:07 +01:00
|
|
|
, m_saveBeforeBuildCheckBox(new QCheckBox(Tr::tr("Automatically save all files before building")))
|
2022-07-27 10:27:56 +02:00
|
|
|
, m_buttonBox(new QDialogButtonBox)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
resize(457, 200);
|
2023-01-16 17:20:07 +01:00
|
|
|
setWindowTitle(Tr::tr("Save Changes"));
|
2022-07-27 10:27:56 +02:00
|
|
|
|
|
|
|
|
m_treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
|
|
|
m_treeWidget->setTextElideMode(Qt::ElideLeft);
|
|
|
|
|
m_treeWidget->setIndentation(0);
|
|
|
|
|
m_treeWidget->setRootIsDecorated(false);
|
|
|
|
|
m_treeWidget->setUniformRowHeights(true);
|
|
|
|
|
m_treeWidget->setHeaderHidden(true);
|
|
|
|
|
m_treeWidget->setColumnCount(2);
|
2012-08-23 15:53:58 +02:00
|
|
|
|
2012-03-08 11:12:23 +01:00
|
|
|
// QDialogButtonBox's behavior for "destructive" is wrong, the "do not save" should be left-aligned
|
2012-08-23 15:53:58 +02:00
|
|
|
const QDialogButtonBox::ButtonRole discardButtonRole = Utils::HostOsInfo::isMacHost()
|
2022-07-27 10:27:56 +02:00
|
|
|
? QDialogButtonBox::ResetRole
|
|
|
|
|
: QDialogButtonBox::DestructiveRole;
|
2017-11-08 13:21:49 +01:00
|
|
|
if (DiffService::instance()) {
|
2023-01-16 17:20:07 +01:00
|
|
|
m_diffButton = m_buttonBox->addButton(Tr::tr("&Diff"), discardButtonRole);
|
2016-10-05 17:37:00 +02:00
|
|
|
connect(m_diffButton, &QAbstractButton::clicked, this, &SaveItemsDialog::collectFilesToDiff);
|
|
|
|
|
}
|
2022-07-27 10:27:56 +02:00
|
|
|
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Save);
|
2023-01-16 17:20:07 +01:00
|
|
|
QPushButton *discardButton = m_buttonBox->addButton(Tr::tr("Do &Not Save"), discardButtonRole);
|
2022-07-27 10:27:56 +02:00
|
|
|
m_treeWidget->setFocus();
|
|
|
|
|
|
|
|
|
|
m_saveBeforeBuildCheckBox->setVisible(false);
|
|
|
|
|
|
2023-04-25 10:15:07 +02:00
|
|
|
using namespace Layouting;
|
2022-07-27 10:27:56 +02:00
|
|
|
// clang-format off
|
|
|
|
|
Column {
|
|
|
|
|
m_msgLabel,
|
|
|
|
|
m_treeWidget,
|
|
|
|
|
m_saveBeforeBuildCheckBox,
|
|
|
|
|
m_buttonBox
|
|
|
|
|
}.attachTo(this);
|
|
|
|
|
// clang-format on
|
2009-05-06 11:55:21 +02:00
|
|
|
|
2022-05-03 12:56:44 +02:00
|
|
|
for (IDocument *document : items) {
|
2009-03-24 12:27:58 +01:00
|
|
|
QString visibleName;
|
|
|
|
|
QString directory;
|
2021-06-08 12:54:22 +02:00
|
|
|
Utils::FilePath filePath = document->filePath();
|
|
|
|
|
if (filePath.isEmpty()) {
|
2016-01-14 14:45:01 +01:00
|
|
|
visibleName = document->fallbackSaveAsFileName();
|
2009-03-24 12:27:58 +01:00
|
|
|
} else {
|
2021-06-08 12:54:22 +02:00
|
|
|
directory = filePath.absolutePath().toUserOutput();
|
|
|
|
|
visibleName = filePath.fileName();
|
2009-03-24 12:27:58 +01:00
|
|
|
}
|
2022-07-27 10:27:56 +02:00
|
|
|
QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget,
|
|
|
|
|
QStringList()
|
|
|
|
|
<< visibleName
|
|
|
|
|
<< QDir::toNativeSeparators(directory));
|
2021-06-08 12:54:22 +02:00
|
|
|
if (!filePath.isEmpty())
|
2022-05-31 11:16:44 +02:00
|
|
|
item->setIcon(0, Utils::FileIconProvider::icon(filePath));
|
2019-05-27 13:32:20 +02:00
|
|
|
item->setData(0, Qt::UserRole, QVariant::fromValue(document));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-27 10:27:56 +02:00
|
|
|
m_treeWidget->resizeColumnToContents(0);
|
|
|
|
|
m_treeWidget->selectAll();
|
2012-08-23 15:53:58 +02:00
|
|
|
if (Utils::HostOsInfo::isMacHost())
|
2022-07-27 10:27:56 +02:00
|
|
|
m_treeWidget->setAlternatingRowColors(true);
|
2012-03-08 11:12:23 +01:00
|
|
|
adjustButtonWidths();
|
2016-10-05 17:37:00 +02:00
|
|
|
updateButtons();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-27 10:27:56 +02:00
|
|
|
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
|
|
|
connect(m_buttonBox->button(QDialogButtonBox::Save),
|
|
|
|
|
&QAbstractButton::clicked,
|
|
|
|
|
this,
|
|
|
|
|
&SaveItemsDialog::collectItemsToSave);
|
2016-02-02 09:10:54 +02:00
|
|
|
connect(discardButton, &QAbstractButton::clicked, this, &SaveItemsDialog::discardAll);
|
2022-07-27 10:27:56 +02:00
|
|
|
connect(m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &SaveItemsDialog::updateButtons);
|
2022-12-07 15:56:07 +01:00
|
|
|
|
|
|
|
|
m_buttonBox->button(QDialogButtonBox::Save)->setDefault(true);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SaveItemsDialog::setMessage(const QString &msg)
|
|
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
m_msgLabel->setText(msg);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-05 17:37:00 +02:00
|
|
|
void SaveItemsDialog::updateButtons()
|
2009-03-24 12:27:58 +01:00
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
int count = m_treeWidget->selectedItems().count();
|
|
|
|
|
QPushButton *saveButton = m_buttonBox->button(QDialogButtonBox::Save);
|
2016-10-05 17:37:00 +02:00
|
|
|
bool buttonsEnabled = true;
|
2023-01-16 17:20:07 +01:00
|
|
|
QString saveText = Tr::tr("&Save");
|
|
|
|
|
QString diffText = Tr::tr("&Diff && Cancel");
|
2022-07-27 10:27:56 +02:00
|
|
|
if (count == m_treeWidget->topLevelItemCount()) {
|
2023-01-16 17:20:07 +01:00
|
|
|
saveText = Tr::tr("&Save All");
|
|
|
|
|
diffText = Tr::tr("&Diff All && Cancel");
|
2009-03-24 12:27:58 +01:00
|
|
|
} else if (count == 0) {
|
2016-10-05 17:37:00 +02:00
|
|
|
buttonsEnabled = false;
|
2009-03-24 12:27:58 +01:00
|
|
|
} else {
|
2023-01-16 17:20:07 +01:00
|
|
|
saveText = Tr::tr("&Save Selected");
|
|
|
|
|
diffText = Tr::tr("&Diff Selected && Cancel");
|
2016-10-05 17:37:00 +02:00
|
|
|
}
|
|
|
|
|
saveButton->setEnabled(buttonsEnabled);
|
|
|
|
|
saveButton->setText(saveText);
|
|
|
|
|
if (m_diffButton) {
|
|
|
|
|
m_diffButton->setEnabled(buttonsEnabled);
|
|
|
|
|
m_diffButton->setText(diffText);
|
2009-03-24 12:27:58 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-08 11:12:23 +01:00
|
|
|
void SaveItemsDialog::adjustButtonWidths()
|
|
|
|
|
{
|
|
|
|
|
// give save button a size that all texts fit in, so it doesn't get resized
|
|
|
|
|
// Mac: make cancel + save button same size (work around dialog button box issue)
|
|
|
|
|
QStringList possibleTexts;
|
2023-01-16 17:20:07 +01:00
|
|
|
possibleTexts << Tr::tr("Save") << Tr::tr("Save All");
|
2022-07-27 10:27:56 +02:00
|
|
|
if (m_treeWidget->topLevelItemCount() > 1)
|
2023-01-16 17:20:07 +01:00
|
|
|
possibleTexts << Tr::tr("Save Selected");
|
2012-03-08 11:12:23 +01:00
|
|
|
int maxTextWidth = 0;
|
2022-07-27 10:27:56 +02:00
|
|
|
QPushButton *saveButton = m_buttonBox->button(QDialogButtonBox::Save);
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const QString &text : std::as_const(possibleTexts)) {
|
2012-03-08 11:12:23 +01:00
|
|
|
saveButton->setText(text);
|
|
|
|
|
int hint = saveButton->sizeHint().width();
|
|
|
|
|
if (hint > maxTextWidth)
|
|
|
|
|
maxTextWidth = hint;
|
|
|
|
|
}
|
2012-08-23 15:53:58 +02:00
|
|
|
if (Utils::HostOsInfo::isMacHost()) {
|
2022-07-27 10:27:56 +02:00
|
|
|
QPushButton *cancelButton = m_buttonBox->button(QDialogButtonBox::Cancel);
|
2012-08-23 15:53:58 +02:00
|
|
|
int cancelButtonWidth = cancelButton->sizeHint().width();
|
|
|
|
|
if (cancelButtonWidth > maxTextWidth)
|
|
|
|
|
maxTextWidth = cancelButtonWidth;
|
|
|
|
|
cancelButton->setMinimumWidth(maxTextWidth);
|
|
|
|
|
}
|
2012-03-08 11:12:23 +01:00
|
|
|
saveButton->setMinimumWidth(maxTextWidth);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SaveItemsDialog::collectItemsToSave()
|
|
|
|
|
{
|
|
|
|
|
m_itemsToSave.clear();
|
2022-07-27 10:27:56 +02:00
|
|
|
const QList<QTreeWidgetItem *> items = m_treeWidget->selectedItems();
|
2022-05-02 17:25:11 +02:00
|
|
|
for (const QTreeWidgetItem *item : items) {
|
2012-02-14 16:43:51 +01:00
|
|
|
m_itemsToSave.append(item->data(0, Qt::UserRole).value<IDocument*>());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
accept();
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-05 17:37:00 +02:00
|
|
|
void SaveItemsDialog::collectFilesToDiff()
|
|
|
|
|
{
|
|
|
|
|
m_filesToDiff.clear();
|
2022-07-27 10:27:56 +02:00
|
|
|
const QList<QTreeWidgetItem *> items = m_treeWidget->selectedItems();
|
2022-05-02 17:25:11 +02:00
|
|
|
for (const QTreeWidgetItem *item : items) {
|
2018-07-21 21:11:46 +02:00
|
|
|
if (auto doc = item->data(0, Qt::UserRole).value<IDocument*>())
|
2016-10-05 17:37:00 +02:00
|
|
|
m_filesToDiff.append(doc->filePath().toString());
|
|
|
|
|
}
|
|
|
|
|
reject();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void SaveItemsDialog::discardAll()
|
|
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
m_treeWidget->clearSelection();
|
2008-12-02 12:01:29 +01:00
|
|
|
collectItemsToSave();
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-14 16:43:51 +01:00
|
|
|
QList<IDocument*> SaveItemsDialog::itemsToSave() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
return m_itemsToSave;
|
|
|
|
|
}
|
2009-05-06 11:55:21 +02:00
|
|
|
|
2016-10-05 17:37:00 +02:00
|
|
|
QStringList SaveItemsDialog::filesToDiff() const
|
|
|
|
|
{
|
|
|
|
|
return m_filesToDiff;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-06 11:55:21 +02:00
|
|
|
void SaveItemsDialog::setAlwaysSaveMessage(const QString &msg)
|
|
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
m_saveBeforeBuildCheckBox->setText(msg);
|
|
|
|
|
m_saveBeforeBuildCheckBox->setVisible(true);
|
2009-05-06 11:55:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SaveItemsDialog::alwaysSaveChecked()
|
|
|
|
|
{
|
2022-07-27 10:27:56 +02:00
|
|
|
return m_saveBeforeBuildCheckBox->isChecked();
|
2009-05-06 11:55:21 +02:00
|
|
|
}
|
2023-01-16 17:20:07 +01:00
|
|
|
|
|
|
|
|
} // Core::Internal
|