forked from qt-creator/qt-creator
CMake generator: Integrate warnings in confirmation dialog
Task-number: QDS-5856 Change-Id: If95515ee0921598623a024fd7bd8fe8ef3482aa9 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -33,7 +33,7 @@ CheckableFileTreeItem::CheckableFileTreeItem(const FilePath &filePath)
|
||||
:QStandardItem(filePath.toString())
|
||||
{
|
||||
Qt::ItemFlags itemFlags = flags();
|
||||
if (isFile())
|
||||
if (!isDir())
|
||||
itemFlags |= Qt::ItemIsUserCheckable;
|
||||
itemFlags &= ~(Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
||||
setFlags(itemFlags);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "cmakegeneratordialogtreemodel.h"
|
||||
#include "generatecmakelistsconstants.h"
|
||||
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QLayout>
|
||||
@@ -39,8 +41,15 @@ namespace QmlDesigner {
|
||||
namespace GenerateCmake {
|
||||
|
||||
CmakeGeneratorDialog::CmakeGeneratorDialog(const FilePath &rootDir, const FilePaths &files)
|
||||
: QDialog()
|
||||
: QDialog(),
|
||||
m_rootDir(rootDir),
|
||||
m_files(files)
|
||||
{
|
||||
setWindowTitle(QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"Select Files to Generate"));
|
||||
|
||||
m_model = new CMakeGeneratorDialogTreeModel(rootDir, files, this);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
@@ -51,16 +60,20 @@ CmakeGeneratorDialog::CmakeGeneratorDialog(const FilePath &rootDir, const FilePa
|
||||
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
m_model = new CMakeGeneratorDialogTreeModel(rootDir, files, this);
|
||||
connect(m_model, &CMakeGeneratorDialogTreeModel::checkedStateChanged, this, &CmakeGeneratorDialog::refreshNotificationText);
|
||||
|
||||
QTreeView *tree = new QTreeView(this);
|
||||
tree->setModel(m_model);
|
||||
tree->expandAll();
|
||||
tree->setHeaderHidden(true);
|
||||
tree->setItemsExpandable(false);
|
||||
|
||||
layout->addWidget(tree);
|
||||
m_notifications = new QTextEdit(this);
|
||||
m_warningIcon = Utils::Icons::WARNING.pixmap();
|
||||
|
||||
refreshNotificationText();
|
||||
|
||||
layout->addWidget(tree, 2);
|
||||
layout->addWidget(m_notifications, 1);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
|
||||
@@ -76,5 +89,47 @@ FilePaths CmakeGeneratorDialog::getFilePaths()
|
||||
return paths;
|
||||
}
|
||||
|
||||
const QString FILE_CREATE_NOTIFICATION = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"File %1 will be created.\n");
|
||||
const QString FILE_OVERWRITE_NOTIFICATION = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"File %1 will be overwritten.\n");
|
||||
|
||||
void CmakeGeneratorDialog::refreshNotificationText()
|
||||
{
|
||||
QTextDocument *document = m_notifications->document();
|
||||
document->clear();
|
||||
document->addResource(QTextDocument::ImageResource, QUrl("cmakegendialog://warningicon"), m_warningIcon);
|
||||
|
||||
QTextCursor cursor = m_notifications->textCursor();
|
||||
QTextImageFormat iformat;
|
||||
iformat.setName("cmakegendialog://warningicon");
|
||||
|
||||
QList<CheckableFileTreeItem*> nodes = m_model->items();
|
||||
|
||||
for (CheckableFileTreeItem *node : nodes) {
|
||||
if (!m_files.contains(node->toFilePath()))
|
||||
continue;
|
||||
|
||||
if (!node->toFilePath().exists() && node->isChecked()) {
|
||||
QString relativePath = QString(node->toFilePath().toString()).remove(m_rootDir.toString()+'/');
|
||||
cursor.insertText(QString(FILE_CREATE_NOTIFICATION).arg(relativePath));
|
||||
}
|
||||
}
|
||||
|
||||
if (!document->toPlainText().isEmpty())
|
||||
cursor.insertBlock();
|
||||
|
||||
for (CheckableFileTreeItem *node : nodes) {
|
||||
if (!m_files.contains(node->toFilePath()))
|
||||
continue;
|
||||
|
||||
if (node->toFilePath().exists() && node->isChecked()) {
|
||||
QString relativePath = node->toFilePath().relativePath(m_rootDir).toString();
|
||||
cursor.insertImage(iformat);
|
||||
cursor.insertText(QString(FILE_OVERWRITE_NOTIFICATION).arg(relativePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTextEdit>
|
||||
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -39,12 +40,21 @@ namespace GenerateCmake {
|
||||
|
||||
class CmakeGeneratorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CmakeGeneratorDialog(const Utils::FilePath &rootDir, const Utils::FilePaths &files);
|
||||
Utils::FilePaths getFilePaths();
|
||||
|
||||
public slots:
|
||||
void refreshNotificationText();
|
||||
|
||||
private:
|
||||
CMakeGeneratorDialogTreeModel *m_model;
|
||||
QTextEdit *m_notifications;
|
||||
QVariant m_warningIcon;
|
||||
Utils::FilePath m_rootDir;
|
||||
Utils::FilePaths m_files;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "generatecmakelistsconstants.h"
|
||||
#include "checkablefiletreeitem.h"
|
||||
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -51,7 +53,7 @@ QVariant CMakeGeneratorDialogTreeModel::data(const QModelIndex &index, int role)
|
||||
if (index.isValid()) {
|
||||
const CheckableFileTreeItem *node = constNodeForIndex(index);
|
||||
if (role == Qt::CheckStateRole) {
|
||||
if (node->isFile())
|
||||
if (!node->isDir())
|
||||
return node->isChecked() ? Qt::Checked : Qt::Unchecked;
|
||||
return {};
|
||||
}
|
||||
@@ -60,8 +62,20 @@ QVariant CMakeGeneratorDialogTreeModel::data(const QModelIndex &index, int role)
|
||||
return QVariant(fullPath.fileName());
|
||||
}
|
||||
else if (role == Qt::DecorationRole) {
|
||||
if (!node->isFile())
|
||||
if (node->isFile())
|
||||
return Utils::Icons::WARNING.icon();
|
||||
if (node->isDir())
|
||||
return m_icons->icon(QFileIconProvider::Folder);
|
||||
else
|
||||
return Utils::Icons::NEWFILE.icon();
|
||||
}
|
||||
else if (role == Qt::ToolTipRole) {
|
||||
if (node->isFile())
|
||||
return QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"This file already exists and will be overwritten.");
|
||||
if (!node->toFilePath().exists())
|
||||
return QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"This file or folder will be created.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +88,7 @@ bool CMakeGeneratorDialogTreeModel::setData(const QModelIndex &index, const QVar
|
||||
CheckableFileTreeItem *node = nodeForIndex(index);
|
||||
if (role == Qt::CheckStateRole) {
|
||||
node->setChecked(value.value<bool>());
|
||||
emit checkedStateChanged(node);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -81,17 +96,26 @@ bool CMakeGeneratorDialogTreeModel::setData(const QModelIndex &index, const QVar
|
||||
return QStandardItemModel::setData(index, value, role);;
|
||||
}
|
||||
|
||||
const QList<CheckableFileTreeItem*> CMakeGeneratorDialogTreeModel::items() const
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
QList<QStandardItem*> standardItems = findItems("*", Qt::MatchWildcard | Qt::MatchRecursive);
|
||||
#else
|
||||
QList<QStandardItem*> standardItems = findItems(".*", Qt::MatchRegularExpression | Qt::MatchRecursive);
|
||||
#endif
|
||||
QList<CheckableFileTreeItem*> checkableItems;
|
||||
for (QStandardItem *item : standardItems)
|
||||
checkableItems.append(static_cast<CheckableFileTreeItem*>(item));
|
||||
|
||||
return checkableItems;
|
||||
}
|
||||
|
||||
const QList<CheckableFileTreeItem*> CMakeGeneratorDialogTreeModel::checkedItems() const
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
QList<QStandardItem*> allItems = findItems("*", Qt::MatchWildcard);
|
||||
#else
|
||||
QList<QStandardItem*> allItems = findItems(".*", Qt::MatchRegularExpression);
|
||||
#endif
|
||||
QList<CheckableFileTreeItem*> allItems = items();
|
||||
|
||||
QList<CheckableFileTreeItem*> checkedItems;
|
||||
for (QStandardItem *standardItem : allItems) {
|
||||
CheckableFileTreeItem *item = static_cast<CheckableFileTreeItem*>(standardItem);
|
||||
for (CheckableFileTreeItem *item : allItems) {
|
||||
if (item->isChecked())
|
||||
checkedItems.append(item);
|
||||
}
|
||||
@@ -133,6 +157,8 @@ void CMakeGeneratorDialogTreeModel::createNodes(const FilePaths &candidates, QSt
|
||||
if (file.parentDir() == thisDir) {
|
||||
CheckableFileTreeItem *fileNode = new CheckableFileTreeItem(file);
|
||||
fileNode->setChecked(checkedByDefault(file));
|
||||
if (!file.exists())
|
||||
fileNode->setChecked(true);
|
||||
parent->appendRow(fileNode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace GenerateCmake {
|
||||
|
||||
class CMakeGeneratorDialogTreeModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CMakeGeneratorDialogTreeModel(const Utils::FilePath &rootDir,
|
||||
const Utils::FilePaths &files, QObject *parent = nullptr);
|
||||
@@ -46,10 +48,14 @@ public:
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
const QList<CheckableFileTreeItem*> items() const;
|
||||
const QList<CheckableFileTreeItem*> checkedItems() const;
|
||||
const CheckableFileTreeItem* constNodeForIndex(const QModelIndex &index) const;
|
||||
CheckableFileTreeItem* nodeForIndex(const QModelIndex &index);
|
||||
|
||||
signals:
|
||||
void checkedStateChanged(CheckableFileTreeItem *item);
|
||||
|
||||
protected:
|
||||
bool checkedByDefault(const Utils::FilePath &file) const;
|
||||
Utils::FilePath rootDir;
|
||||
|
||||
@@ -166,17 +166,19 @@ void removeUnconfirmedQueuedFiles(const Utils::FilePaths confirmedFiles)
|
||||
|
||||
const QString WARNING_MISSING_STRUCTURE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"The project is not properly structured for automatically generating CMake files.\n\nAborting process.\n\nThe following files or directories are missing:\n\n%1");
|
||||
const QString WARNING_MISSING_STRUCTURE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"The project is not properly structured for automatically generating CMake files.\n\nThe following files or directories are missing and may be created:\n\n%1");
|
||||
//const QString WARNING_MISSING_STRUCTURE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
// "The project is not properly structured for automatically generating CMake files.\n\nThe following files or directories are missing and may be created:\n\n%1");
|
||||
const QString WARNING_TITLE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"Cannot Generate CMake Files");
|
||||
const QString WARNING_TITLE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
"Problems with Generating CMake Files");
|
||||
//const QString WARNING_TITLE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
|
||||
// "Problems with Generating CMake Files");
|
||||
|
||||
void showProjectDirErrorDialog(int error)
|
||||
{
|
||||
bool isFatal = isErrorFatal(error);
|
||||
|
||||
if (isFatal) {
|
||||
QString fatalList;
|
||||
QString nonFatalList;
|
||||
|
||||
if (error & MissingContentDir)
|
||||
fatalList.append(QString(DIRNAME_CONTENT) + "\n");
|
||||
@@ -190,43 +192,9 @@ void showProjectDirErrorDialog(int error)
|
||||
if (error & MissingImportDir)
|
||||
fatalList.append(QString(DIRNAME_IMPORT) + "\n");
|
||||
|
||||
if (error & MissingAssetImportDir)
|
||||
nonFatalList.append(QString(DIRNAME_ASSET) + "\n");
|
||||
if (error & MissingMainCMake)
|
||||
nonFatalList.append(QString(FILENAME_CMAKELISTS) + "\n");
|
||||
if (error & MissingQmlModules)
|
||||
nonFatalList.append(QString(FILENAME_MODULES) + "\n");
|
||||
|
||||
if (error & MissingMainQml)
|
||||
nonFatalList.append(QString(FILENAME_MAINQML) + "\n");
|
||||
|
||||
if (error & MissingMainCpp)
|
||||
nonFatalList.append(QString(DIRNAME_CPP)
|
||||
+ QDir::separator()
|
||||
+ QString(FILENAME_MAINCPP)
|
||||
+ "\n");
|
||||
if (error & MissingMainCppHeader)
|
||||
nonFatalList.append(QString(DIRNAME_CPP)
|
||||
+ QDir::separator()
|
||||
+ QString(FILENAME_MAINCPP_HEADER)
|
||||
+ "\n");
|
||||
if (error & MissingEnvHeader)
|
||||
nonFatalList.append(QString(DIRNAME_CPP)
|
||||
+ QDir::separator()
|
||||
+ QString(FILENAME_ENV_HEADER)
|
||||
+ "\n");
|
||||
|
||||
bool isFatal = isErrorFatal(error);
|
||||
|
||||
if (isFatal) {
|
||||
QMessageBox::critical(nullptr,
|
||||
WARNING_TITLE_FATAL,
|
||||
WARNING_MISSING_STRUCTURE_FATAL.arg(fatalList + nonFatalList));
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(nullptr,
|
||||
WARNING_TITLE_NONFATAL,
|
||||
WARNING_MISSING_STRUCTURE_NONFATAL.arg(nonFatalList));
|
||||
WARNING_MISSING_STRUCTURE_FATAL.arg(fatalList));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +205,8 @@ bool showConfirmationDialog(const Utils::FilePath &rootDir)
|
||||
files.append(file.filePath);
|
||||
|
||||
CmakeGeneratorDialog dialog(rootDir, files);
|
||||
dialog.setMinimumWidth(600);
|
||||
dialog.setMinimumHeight(640);
|
||||
if (dialog.exec()) {
|
||||
Utils::FilePaths confirmedFiles = dialog.getFilePaths();
|
||||
removeUnconfirmedQueuedFiles(confirmedFiles);
|
||||
|
||||
Reference in New Issue
Block a user