CMake file generation: Dialog for deselecting generated files

Task-number: QDS-5331
Change-Id: Ib1470069ab444dfd792e40fadc338d6452b727ca
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Tapani Mattila
2021-11-03 11:37:48 +02:00
parent cf72b0064e
commit 533ed33706
7 changed files with 308 additions and 10 deletions

View File

@@ -27,6 +27,7 @@ add_qtc_plugin(QmlDesigner
designmodewidget.cpp designmodewidget.h
documentmanager.cpp documentmanager.h
documentwarningwidget.cpp documentwarningwidget.h
cmakegeneratordialog.h cmakegeneratordialog.cpp
generateresource.cpp generateresource.h
generatecmakelists.cpp generatecmakelists.h
openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui

View File

@@ -0,0 +1,150 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Design Tooling
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "cmakegeneratordialog.h"
#include <QDialogButtonBox>
#include <QPushButton>
#include <QLayout>
#include <QLabel>
#include <QListView>
using namespace Utils;
namespace QmlDesigner {
namespace GenerateCmake {
CmakeGeneratorDialog::CmakeGeneratorDialog(const FilePath &rootDir, const FilePaths &files)
: QDialog()
{
QVBoxLayout *layout = new QVBoxLayout(this);
setLayout(layout);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
auto *okButton = buttons->button(QDialogButtonBox::Ok);
okButton->setDefault(true);
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
model = new CheckableFileListModel(rootDir, files, this);
QListView *list = new QListView(this);
list->setModel(model);
layout->addWidget(list);
layout->addWidget(buttons);
}
FilePaths CmakeGeneratorDialog::getFilePaths()
{
FilePaths paths;
QList<CheckableStandardItem*> items = model->checkedItems();
for (CheckableStandardItem *item: items) {
paths.append(FilePath::fromString(item->text()));
}
return paths;
}
CheckableFileListModel::CheckableFileListModel(const FilePath &rootDir, const FilePaths &files, QObject *parent)
:QStandardItemModel(parent),
rootDir(rootDir)
{
for (const FilePath &file: files) {
appendRow(new CheckableStandardItem(file.toString(), true));
}
}
QList<CheckableStandardItem*> CheckableFileListModel::checkedItems() const
{
QList<QStandardItem*> allItems = findItems(".*", Qt::MatchRegularExpression);
QList<CheckableStandardItem*> checkedItems;
for (QStandardItem *standardItem : allItems) {
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(standardItem);
if (item->isChecked())
checkedItems.append(item);
}
return checkedItems;
}
CheckableStandardItem::CheckableStandardItem(const QString &text, bool checked)
:QStandardItem(text),
checked(checked)
{
setFlags(flags() |= Qt::ItemIsUserCheckable);
}
void CheckableStandardItem::setChecked(bool checked)
{
this->checked = checked;
}
bool CheckableStandardItem::isChecked() const
{
return this->checked;
}
int CheckableStandardItem::type() const
{
return QStandardItem::UserType + 0x74d4f1;
}
QVariant CheckableFileListModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()) {
if (role == Qt::CheckStateRole) {
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(QStandardItemModel::item(index.row()));
return item->isChecked() ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::DisplayRole) {
QVariant data = QStandardItemModel::data(index, role);
QString relativePath = data.toString().remove(rootDir.toString());
return QVariant(relativePath);
}
}
return QStandardItemModel::data(index, role);
}
bool CheckableFileListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::CheckStateRole)
{
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(QStandardItemModel::item(index.row()));
item->setChecked(value.value<bool>());
return true;
}
return QStandardItemModel::setData(index, value, role);
}
}
}

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Design Tooling
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#ifndef CMAKEGENERATORDIALOG_H
#define CMAKEGENERATORDIALOG_H
#include <utils/fileutils.h>
#include <QDialog>
#include <QStandardItemModel>
namespace QmlDesigner {
namespace GenerateCmake {
class CheckableStandardItem : public QStandardItem
{
public:
CheckableStandardItem(const QString &text, bool checked = false);
bool isChecked() const;
void setChecked(bool checked);
int type() const;
private:
bool checked;
};
class CheckableFileListModel : public QStandardItemModel
{
public:
CheckableFileListModel(const Utils::FilePath &rootDir, const Utils::FilePaths &files, QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
QList<CheckableStandardItem*> checkedItems() const;
private:
Utils::FilePath rootDir;
};
class CmakeGeneratorDialog : public QDialog
{
public:
CmakeGeneratorDialog(const Utils::FilePath &rootDir, const Utils::FilePaths &files);
Utils::FilePaths getFilePaths();
private:
CheckableFileListModel *model;
};
}
}
Q_DECLARE_METATYPE(QmlDesigner::GenerateCmake::CheckableStandardItem)
#endif // CMAKEGENERATORDIALOG_H

View File

@@ -24,6 +24,7 @@
****************************************************************************/
#include "generatecmakelists.h"
#include "cmakegeneratordialog.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
@@ -39,6 +40,7 @@
#include <utils/fileutils.h>
#include <QAction>
#include <QtConcurrent>
#include <QRegularExpression>
#include <QStringList>
#include <QTextStream>
@@ -49,6 +51,13 @@ namespace QmlDesigner {
namespace GenerateCmake {
bool operator==(const GeneratableFile &left, const GeneratableFile &right)
{
return (left.filePath == right.filePath && left.content == right.content);
}
QVector<GeneratableFile> queuedFiles;
void generateMenuEntry()
{
Core::ActionContainer *buildMenu =
@@ -67,19 +76,65 @@ void generateMenuEntry()
void onGenerateCmakeLists()
{
queuedFiles.clear();
FilePath rootDir = ProjectExplorer::SessionManager::startupProject()->projectDirectory();
GenerateCmakeLists::generateMainCmake(rootDir);
GenerateEntryPoints::generateMainCpp(rootDir);
GenerateEntryPoints::generateMainQml(rootDir);
if (showConfirmationDialog(rootDir))
writeQueuedFiles();
}
bool writeFile(const FilePath &filePath, const QString &fileContent)
void removeUnconfirmedQueuedFiles(const Utils::FilePaths confirmedFiles)
{
QFile file(filePath.toString());
file.open(QIODevice::WriteOnly);
QTextStream stream(&file);
stream << fileContent;
file.close();
QtConcurrent::blockingFilter(queuedFiles, [confirmedFiles](const GeneratableFile &qf) {
return confirmedFiles.contains(qf.filePath);
});
}
bool showConfirmationDialog(const Utils::FilePath &rootDir)
{
Utils::FilePaths files;
for (GeneratableFile &file: queuedFiles)
files.append(file.filePath);
CmakeGeneratorDialog dialog(rootDir, files);
if (dialog.exec()) {
Utils::FilePaths confirmedFiles = dialog.getFilePaths();
removeUnconfirmedQueuedFiles(confirmedFiles);
return true;
}
return false;
}
bool queueFile(const FilePath &filePath, const QString &fileContent)
{
GeneratableFile file;
file.filePath = filePath;
file.content = fileContent;
queuedFiles.append(file);
return true;
}
bool writeQueuedFiles()
{
for (GeneratableFile &file: queuedFiles)
if (!writeFile(file))
return false;
return true;
}
bool writeFile(const GeneratableFile &file)
{
QFile fileHandle(file.filePath.toString());
fileHandle.open(QIODevice::WriteOnly);
QTextStream stream(&fileHandle);
stream << file.content;
fileHandle.close();
return true;
}
@@ -295,7 +350,7 @@ QStringList getDirectoryTreeResources(const FilePath &dir)
void createCmakeFile(const FilePath &dir, const QString &content)
{
FilePath filePath = dir.pathAppended(CMAKEFILENAME);
GenerateCmake::writeFile(filePath, content);
GenerateCmake::queueFile(filePath, content);
}
bool isFileBlacklisted(const QString &fileName)
@@ -327,7 +382,7 @@ bool generateMainCpp(const FilePath &dir)
templatefile.close();
FilePath filePath = dir.pathAppended(MAIN_CPPFILE_NAME);
return GenerateCmake::writeFile(filePath, content);
return GenerateCmake::queueFile(filePath, content);
}
const char MAIN_QMLFILE_CONTENT[] = "import %1Qml\n\n%2 {\n}\n";
@@ -343,7 +398,7 @@ bool generateMainQml(const FilePath &dir)
if (const auto aspect = runConfiguration->aspect<QmlProjectManager::QmlMainFileAspect>())
mainClass = FilePath::fromString(aspect->mainScript()).baseName();
return GenerateCmake::writeFile(filePath, QString(MAIN_QMLFILE_CONTENT).arg(projectName).arg(mainClass));
return GenerateCmake::queueFile(filePath, QString(MAIN_QMLFILE_CONTENT).arg(projectName).arg(mainClass));
}
}

View File

@@ -31,9 +31,20 @@
namespace QmlDesigner {
namespace GenerateCmake {
struct GeneratableFile {
Utils::FilePath filePath;
QString content;
};
bool operator==(const GeneratableFile &left, const GeneratableFile &right);
void generateMenuEntry();
void onGenerateCmakeLists();
bool writeFile(const Utils::FilePath &filePath, const QString &fileContent);
void removeUnconfirmedQueuedFiles(const Utils::FilePaths confirmedFiles);
bool showConfirmationDialog(const Utils::FilePath &rootDir);
bool queueFile(const Utils::FilePath &filePath, const QString &fileContent);
bool writeFile(const GeneratableFile &file);
bool writeQueuedFiles();
}
namespace GenerateCmakeLists {
void generateMainCmake(const Utils::FilePath &rootDir);

View File

@@ -6,6 +6,7 @@ HEADERS += $$PWD/qmldesignerconstants.h \
$$PWD/editorproxy.h \
$$PWD/generateresource.h \
$$PWD/generatecmakelists.h \
$$PWD/cmakegeneratordialog.h \
$$PWD/settingspage.h \
$$PWD/designmodecontext.h \
$$PWD/documentmanager.h \
@@ -22,6 +23,7 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \
$$PWD/editorproxy.cpp \
$$PWD/generateresource.cpp \
$$PWD/generatecmakelists.cpp \
$$PWD/cmakegeneratordialog.cpp \
$$PWD/settingspage.cpp \
$$PWD/designmodecontext.cpp \
$$PWD/documentmanager.cpp \

View File

@@ -1009,6 +1009,8 @@ Project {
"generateresource.h",
"generatecmakelists.cpp",
"generatecmakelists.h",
"cmakegeneratordialog.cpp",
"cmakegeneratordialog.h",
"designersettings.cpp",
"designersettings.h",
"designmodecontext.cpp",