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 designmodewidget.cpp designmodewidget.h
documentmanager.cpp documentmanager.h documentmanager.cpp documentmanager.h
documentwarningwidget.cpp documentwarningwidget.h documentwarningwidget.cpp documentwarningwidget.h
cmakegeneratordialog.h cmakegeneratordialog.cpp
generateresource.cpp generateresource.h generateresource.cpp generateresource.h
generatecmakelists.cpp generatecmakelists.h generatecmakelists.cpp generatecmakelists.h
openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui 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 "generatecmakelists.h"
#include "cmakegeneratordialog.h"
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
@@ -39,6 +40,7 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QAction> #include <QAction>
#include <QtConcurrent>
#include <QRegularExpression> #include <QRegularExpression>
#include <QStringList> #include <QStringList>
#include <QTextStream> #include <QTextStream>
@@ -49,6 +51,13 @@ namespace QmlDesigner {
namespace GenerateCmake { namespace GenerateCmake {
bool operator==(const GeneratableFile &left, const GeneratableFile &right)
{
return (left.filePath == right.filePath && left.content == right.content);
}
QVector<GeneratableFile> queuedFiles;
void generateMenuEntry() void generateMenuEntry()
{ {
Core::ActionContainer *buildMenu = Core::ActionContainer *buildMenu =
@@ -67,19 +76,65 @@ void generateMenuEntry()
void onGenerateCmakeLists() void onGenerateCmakeLists()
{ {
queuedFiles.clear();
FilePath rootDir = ProjectExplorer::SessionManager::startupProject()->projectDirectory(); FilePath rootDir = ProjectExplorer::SessionManager::startupProject()->projectDirectory();
GenerateCmakeLists::generateMainCmake(rootDir); GenerateCmakeLists::generateMainCmake(rootDir);
GenerateEntryPoints::generateMainCpp(rootDir); GenerateEntryPoints::generateMainCpp(rootDir);
GenerateEntryPoints::generateMainQml(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()); QtConcurrent::blockingFilter(queuedFiles, [confirmedFiles](const GeneratableFile &qf) {
file.open(QIODevice::WriteOnly); return confirmedFiles.contains(qf.filePath);
QTextStream stream(&file); });
stream << fileContent; }
file.close();
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; return true;
} }
@@ -295,7 +350,7 @@ QStringList getDirectoryTreeResources(const FilePath &dir)
void createCmakeFile(const FilePath &dir, const QString &content) void createCmakeFile(const FilePath &dir, const QString &content)
{ {
FilePath filePath = dir.pathAppended(CMAKEFILENAME); FilePath filePath = dir.pathAppended(CMAKEFILENAME);
GenerateCmake::writeFile(filePath, content); GenerateCmake::queueFile(filePath, content);
} }
bool isFileBlacklisted(const QString &fileName) bool isFileBlacklisted(const QString &fileName)
@@ -327,7 +382,7 @@ bool generateMainCpp(const FilePath &dir)
templatefile.close(); templatefile.close();
FilePath filePath = dir.pathAppended(MAIN_CPPFILE_NAME); 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"; 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>()) if (const auto aspect = runConfiguration->aspect<QmlProjectManager::QmlMainFileAspect>())
mainClass = FilePath::fromString(aspect->mainScript()).baseName(); 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 QmlDesigner {
namespace GenerateCmake { namespace GenerateCmake {
struct GeneratableFile {
Utils::FilePath filePath;
QString content;
};
bool operator==(const GeneratableFile &left, const GeneratableFile &right);
void generateMenuEntry(); void generateMenuEntry();
void onGenerateCmakeLists(); 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 { namespace GenerateCmakeLists {
void generateMainCmake(const Utils::FilePath &rootDir); void generateMainCmake(const Utils::FilePath &rootDir);

View File

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

View File

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