From 4b7648924c2d53e3d7a9add27a16704180c1c5f4 Mon Sep 17 00:00:00 2001 From: Diego Iastrubni Date: Fri, 2 Aug 2024 21:37:47 +0300 Subject: [PATCH] Kits: new entity Started working on kits. Basically - the idea is that all tasks (and binaries) will be run under a user editable script, which contains some variables - that would be substitutioned on runtime. --- CMakeLists.txt | 5 +- .../ProjectManager/ProjectManagerGUI.ui | 42 ++++--- .../ProjectManager/ProjectManagerPlg.cpp | 25 ++-- .../ProjectManager/ProjectManagerPlg.h | 3 + .../ProjectManager/kitdefinitionmodel.cpp | 32 ++++++ .../ProjectManager/kitdefinitionmodel.h | 19 +++ src/plugins/ProjectManager/kitdefinitions.cpp | 108 ++++++++++++++++++ src/plugins/ProjectManager/kitdefinitions.h | 17 +++ 8 files changed, 228 insertions(+), 23 deletions(-) create mode 100644 src/plugins/ProjectManager/kitdefinitionmodel.cpp create mode 100644 src/plugins/ProjectManager/kitdefinitionmodel.h create mode 100644 src/plugins/ProjectManager/kitdefinitions.cpp create mode 100644 src/plugins/ProjectManager/kitdefinitions.h diff --git a/CMakeLists.txt b/CMakeLists.txt index beb6f3a..fb81233 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,10 @@ set(qtedit4_sources src/plugins/ProjectManager/output.ui src/plugins/ProjectManager/GenericItems.cpp src/plugins/ProjectManager/GenericItems.h + src/plugins/ProjectManager/kitdefinitions.h + src/plugins/ProjectManager/kitdefinitions.cpp + src/plugins/ProjectManager/kitdefinitionmodel.h + src/plugins/ProjectManager/kitdefinitionmodel.cpp src/main.cpp ) @@ -66,7 +70,6 @@ else() add_executable(qtedit4 ${qtedit4_sources}) endif() -# lib/qmdilib/demos/plugin-demo/plugins/editor target_include_directories(qtedit4 PUBLIC ${qmdilib_SOURCE_DIR}/demos/plugin-demo ${qutepart_SOURCE_DIR}/include diff --git a/src/plugins/ProjectManager/ProjectManagerGUI.ui b/src/plugins/ProjectManager/ProjectManagerGUI.ui index a24358a..87cb15c 100644 --- a/src/plugins/ProjectManager/ProjectManagerGUI.ui +++ b/src/plugins/ProjectManager/ProjectManagerGUI.ui @@ -32,7 +32,7 @@ - + @@ -42,7 +42,7 @@ - Qt::StrongFocus + Qt::FocusPolicy::StrongFocus - @@ -72,12 +72,12 @@ - + - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Maximum + QSizePolicy::Policy::Maximum @@ -87,6 +87,20 @@ + + + + + + + + + ... + + + + + @@ -101,7 +115,7 @@ ... - QToolButton::MenuButtonPopup + QToolButton::ToolButtonPopupMode::MenuButtonPopup true @@ -111,10 +125,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Maximum + QSizePolicy::Policy::Maximum @@ -136,7 +150,7 @@ ... - QToolButton::MenuButtonPopup + QToolButton::ToolButtonPopupMode::MenuButtonPopup true @@ -146,10 +160,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Maximum + QSizePolicy::Policy::Maximum @@ -174,7 +188,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true @@ -197,10 +211,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Maximum + QSizePolicy::Policy::Maximum diff --git a/src/plugins/ProjectManager/ProjectManagerPlg.cpp b/src/plugins/ProjectManager/ProjectManagerPlg.cpp index ed38766..100ddf2 100644 --- a/src/plugins/ProjectManager/ProjectManagerPlg.cpp +++ b/src/plugins/ProjectManager/ProjectManagerPlg.cpp @@ -8,11 +8,13 @@ #include #include #include +#include #include "GenericItems.h" #include "ProjectBuildConfig.h" #include "ProjectManagerPlg.h" #include "ProjectSearch.h" +#include "kitdefinitionmodel.h" #include "pluginmanager.h" #include "qmdihost.h" #include "qmdiserver.h" @@ -186,7 +188,7 @@ void ProjectManagerPlugin::on_client_merged(qmdiHost *host) { connect(gui->filesView, &QAbstractItemView::clicked, this, &ProjectManagerPlugin::onItemClicked); - connect(gui->comboBox, &QComboBox::currentIndexChanged, this, + connect(gui->projectComboBox, &QComboBox::currentIndexChanged, this, &ProjectManagerPlugin::on_newProjectSelected); manager->createNewPanel(Panels::West, tr("Project"), w); @@ -269,8 +271,15 @@ void ProjectManagerPlugin::on_client_merged(qmdiHost *host) { }); manager->addAction(projectSearch); + kitsModel = new KitDefinitionModel(); + gui->kitComboBox->setModel(kitsModel); + + auto dataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + auto kits = findKitDefinitions(dataPath.toStdString()); + kitsModel->setKitDefinitions(kits); + projectModel = new ProjectBuildModel(); - gui->comboBox->setModel(projectModel); + gui->projectComboBox->setModel(projectModel); runAction = new QAction(QIcon::fromTheme("document-save"), tr("&Run"), this); buildAction = new QAction(QIcon::fromTheme("document-save-as"), tr("&Run task"), this); @@ -349,7 +358,7 @@ void ProjectManagerPlugin::saveConfig(QSettings &settings) { } std::shared_ptr ProjectManagerPlugin::getCurrentConfig() const { - auto currentIndex = gui->comboBox->currentIndex(); + auto currentIndex = gui->projectComboBox->currentIndex(); if (currentIndex < 0) { return {}; } @@ -391,7 +400,7 @@ void ProjectManagerPlugin::on_addProject_clicked() { } void ProjectManagerPlugin::on_removeProject_clicked() { - auto index = gui->comboBox->currentIndex(); + auto index = gui->projectComboBox->currentIndex(); if (index < 0) { return; } @@ -430,7 +439,7 @@ void ProjectManagerPlugin::on_newProjectSelected(int index) { updateExecutablesUI(config); } -void ProjectManagerPlugin::do_runExecutable(const ExecutableInfo *selectedTarget) { +void ProjectManagerPlugin::do_runExecutable(const ExecutableInfo *info) { if (runProcess.processId() != 0) { runProcess.kill(); return; @@ -438,9 +447,9 @@ void ProjectManagerPlugin::do_runExecutable(const ExecutableInfo *selectedTarget auto hash = getConfigHash(); auto project = getCurrentConfig(); - auto executablePath = findExecForPlatform(selectedTarget->executables); + auto executablePath = findExecForPlatform(info->executables); auto currentTask = expand(executablePath, hash); - auto workingDirectory = expand(selectedTarget->runDirectory, hash); + auto workingDirectory = expand(info->runDirectory, hash); if (workingDirectory.isEmpty()) { workingDirectory = project->buildDir; } @@ -567,7 +576,7 @@ void ProjectManagerPlugin::on_projectFile_modified(const QString &path) { return; } *inMemoryConfig = *onDiskConfig; - emit on_newProjectSelected(gui->comboBox->currentIndex()); + emit on_newProjectSelected(gui->projectComboBox->currentIndex()); // TODO - new file created is not working yet. qDebug("Config file modified - %s", path.toStdString().data()); diff --git a/src/plugins/ProjectManager/ProjectManagerPlg.h b/src/plugins/ProjectManager/ProjectManagerPlg.h index 34c7529..b35b941 100644 --- a/src/plugins/ProjectManager/ProjectManagerPlg.h +++ b/src/plugins/ProjectManager/ProjectManagerPlg.h @@ -1,6 +1,7 @@ #pragma once #include "iplugin.h" +#include "kitdefinitions.h" #include #include @@ -13,6 +14,7 @@ class ProjectBuildModel; class FoldersModel; class DirectoryModel; class FilterOutProxyModel; +class KitDefinitionModel; struct ProjectBuildConfig; struct TaskInfo; @@ -64,6 +66,7 @@ class ProjectManagerPlugin : public IPlugin { QProcess runProcess; + KitDefinitionModel *kitsModel = nullptr; ProjectBuildModel *projectModel = nullptr; DirectoryModel *directoryModel; FilterOutProxyModel *filesFilterModel; diff --git a/src/plugins/ProjectManager/kitdefinitionmodel.cpp b/src/plugins/ProjectManager/kitdefinitionmodel.cpp new file mode 100644 index 0000000..12ce7b4 --- /dev/null +++ b/src/plugins/ProjectManager/kitdefinitionmodel.cpp @@ -0,0 +1,32 @@ +#include "kitdefinitionmodel.h" + +KitDefinitionModel::KitDefinitionModel(QObject *parent) + : QAbstractListModel(parent) +{} + +void KitDefinitionModel::setKitDefinitions(const std::vector &kits) +{ + kitDefinitions = kits; + // Notify the view that the model data has changed + beginResetModel(); + endResetModel(); +} + +int KitDefinitionModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return kitDefinitions.size(); +} + +QVariant KitDefinitionModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= kitDefinitions.size()) { + return QVariant(); + } + + const auto &kit = kitDefinitions[index.row()]; + if (role == Qt::DisplayRole) { + return QString::fromStdString(kit.name); // Display the name in the combo box + } + return QVariant(); +} diff --git a/src/plugins/ProjectManager/kitdefinitionmodel.h b/src/plugins/ProjectManager/kitdefinitionmodel.h new file mode 100644 index 0000000..aaba486 --- /dev/null +++ b/src/plugins/ProjectManager/kitdefinitionmodel.h @@ -0,0 +1,19 @@ +#pragma once + +#include "kitdefinitions.h" +#include +#include +#include + +class KitDefinitionModel : public QAbstractListModel { + Q_OBJECT + + public: + KitDefinitionModel(QObject *parent = nullptr); + void setKitDefinitions(const std::vector &kits); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + private: + std::vector kitDefinitions; // Store a copy of the vector +}; diff --git a/src/plugins/ProjectManager/kitdefinitions.cpp b/src/plugins/ProjectManager/kitdefinitions.cpp new file mode 100644 index 0000000..1010bee --- /dev/null +++ b/src/plugins/ProjectManager/kitdefinitions.cpp @@ -0,0 +1,108 @@ +#include "kitdefinitions.h" +#include +#include +#include +#include +#include +#include +#include + +static auto getExtensionPrefixMap() -> const std::unordered_map & { + static const std::unordered_map EXTENSION_PREFIX_MAP = { +#ifdef _WIN32 + {".bat", "rem @@ "}, {".ps1", "# @@ "} +#else + {".sh", "# @@ "} +#endif + }; + return EXTENSION_PREFIX_MAP; +} + +static auto trim(std::string_view str) -> std::string { + auto start = str.find_first_not_of(" \t"); + if (start == std::string_view::npos) { + return {}; + } + auto end = str.find_last_not_of(" \t"); + return std::string(str.substr(start, end - start + 1)); +} + +static auto parseKeyValue(std::string_view line) -> std::pair { + auto pos = line.find('='); + if (pos == std::string_view::npos) { + return {"", ""}; + } + auto key = trim(line.substr(0, pos)); + auto value = trim(line.substr(pos + 1)); + return {key, value}; +} + +static auto readFile(const std::filesystem::path &filePath, std::string_view prefix) + -> std::unordered_map { + std::unordered_map keyValueMap; + std::ifstream file(filePath); + if (!file.is_open()) { + std::cerr << "Cannot open file: " << filePath << std::endl; + return keyValueMap; + } + + std::string line; + auto prefixLength = prefix.length(); + while (std::getline(file, line)) { + auto trimmedLine = trim(line); + if (trimmedLine.empty() || trimmedLine.substr(0, prefixLength) != prefix) { + continue; + } + auto remaining = trimmedLine.substr(prefixLength); + auto [key, value] = parseKeyValue(remaining); + keyValueMap[std::move(key)] = std::move(value); + } + return keyValueMap; +} + +auto findKitDefinitions(const std::string_view directoryPath) -> std::vector { + if (!std::filesystem::exists(directoryPath) || !std::filesystem::is_directory(directoryPath)) { + return {}; + } + + auto fileInfoList = std::vector(); + for (const auto &entry : std::filesystem::directory_iterator(directoryPath)) { + if (!entry.is_regular_file()) { + continue; + } + auto validExtensions = getExtensionPrefixMap(); + auto extension = entry.path().extension().string(); + auto it = validExtensions.find(extension); + if (it == validExtensions.end()) { + continue; + } + + auto prefix = it->second; + auto keyValueMap = readFile(entry.path(), prefix); + if (!keyValueMap.empty()) { + auto name = keyValueMap["name"]; + auto author = keyValueMap["author"]; + KitDefinition fileInfo(entry.path().string(), std::move(name), std::move(author)); + fileInfoList.push_back(std::move(fileInfo)); + } + } + return fileInfoList; +} + +/* +// Uncomment for testing + +int main() { + std::string directoryPath = "."; + + auto fileInfoList = findKitDefinitions(directoryPath); + + for (const auto &info : fileInfoList) { + std::cout << "File Path: " << info.filePath << std::endl; + std::cout << "Name: " << info.name << std::endl; + std::cout << "Author: " << info.author << std::endl; + } + + return 0; +} +*/ diff --git a/src/plugins/ProjectManager/kitdefinitions.h b/src/plugins/ProjectManager/kitdefinitions.h new file mode 100644 index 0000000..df27f67 --- /dev/null +++ b/src/plugins/ProjectManager/kitdefinitions.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +struct KitDefinition { + std::string filePath; + std::string name; + std::string author; + + KitDefinition(const std::string &filePath = "", const std::string &name = "", + const std::string &author = "") + : filePath(filePath), name(name), author(author) {} +}; + +auto findKitDefinitions(const std::string_view directoryPath = {}) -> std::vector;