diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 11ea79a..6ba2e56 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -21,7 +21,14 @@ include_directories(${GPUI_INCLUDE_DIRS}) find_package(Qt5 COMPONENTS Widgets REQUIRED) -add_gpui_executable(main main.cpp) +set(HEADERS +) + +set(SOURCES + main.cpp +) + +add_gpui_executable(main ${SOURCES}) target_link_libraries(main ${GPUI_LIBRARIES}) target_link_libraries(main Qt5::Widgets) diff --git a/src/app/main.cpp b/src/app/main.cpp index 67fb835..0f69f5d 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -18,8 +18,8 @@ ** ***********************************************************************************************************************/ +#include "../gui/commandlineparser.h" #include "../gui/mainwindow.h" - #include "../model/pluginstorage.h" #include @@ -31,13 +31,36 @@ int main(int argc, char ** argv) { // Create window. QApplication app(argc, argv); + gpui::CommandLineParser parser(app); + gpui::CommandLineOptions options; + QString errorMessage; + + gpui::CommandLineParser::CommandLineParseResult parserResult = parser.parseCommandLine(&options, &errorMessage); + + switch (parserResult) + { + case gpui::CommandLineParser::CommandLineError: + printf("%s \n", qPrintable(errorMessage)); + parser.showHelp(); + return 1; + case gpui::CommandLineParser::CommandLineHelpRequested: + parser.showHelp(); + return 0; + case gpui::CommandLineParser::CommandLineVersionRequested: + parser.showVersion(); + return 0; + case gpui::CommandLineParser::CommandLineOk: + default: + break; + } + // NOTE: set app variables which will be used to // construct settings path app.setOrganizationName("BaseALT"); app.setOrganizationDomain("basealt.ru"); app.setApplicationName("GPUI"); - gpui::MainWindow window; + gpui::MainWindow window(options); window.show(); return app.exec(); diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 272263c..058d5c0 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -12,6 +12,8 @@ include_directories( set(HEADERS contentwidget.h + commandlineoptions.h + commandlineparser.h gui.h mainwindow.h mainwindowsettings.h @@ -20,6 +22,7 @@ set(HEADERS ) set(SOURCES + commandlineparser.cpp contentwidget.cpp gui.cpp mainwindow.cpp diff --git a/src/gui/commandlineoptions.h b/src/gui/commandlineoptions.h new file mode 100644 index 0000000..c671973 --- /dev/null +++ b/src/gui/commandlineoptions.h @@ -0,0 +1,36 @@ +/*********************************************************************************************************************** +** +** Copyright (C) 2021 BaseALT Ltd. +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +***********************************************************************************************************************/ + +#ifndef GPUI_COMMAND_LINE_OPTIONS_H +#define GPUI_COMMAND_LINE_OPTIONS_H + +#include +#include + +namespace gpui { + class CommandLineOptions + { + public: + QString policyBundle; + QString path; + }; +} + +#endif // GPUI_COMMAND_LINE_OPTIONS_H diff --git a/src/gui/commandlineparser.cpp b/src/gui/commandlineparser.cpp new file mode 100644 index 0000000..7020edb --- /dev/null +++ b/src/gui/commandlineparser.cpp @@ -0,0 +1,120 @@ +/*********************************************************************************************************************** +** +** Copyright (C) 2021 BaseALT Ltd. +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +***********************************************************************************************************************/ + +#include "commandlineparser.h" + +#include + +#include +#include + +namespace gpui +{ + +class CommandLineParserPrivate +{ +public: + QApplication& application; + std::unique_ptr parser; + + CommandLineParserPrivate(QApplication &application) + : application(application) + { + parser = std::make_unique(); + } +}; + +CommandLineParser::CommandLineParser(QApplication &application) + : d(new CommandLineParserPrivate(application)) +{ + +} + +CommandLineParser::~CommandLineParser() +{ + delete d; +} + +CommandLineParser::CommandLineParseResult CommandLineParser::parseCommandLine(CommandLineOptions *options, QString *errorMessage) +{ + const QCommandLineOption pathOption("p", "The full path of policy to edit.", "path"); + const QCommandLineOption bundleOption("b", "The full path of policy bundle to load.", "path"); + + d->parser->setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + d->parser->addOption(pathOption); + d->parser->addOption(bundleOption); + + const QCommandLineOption helpOption = d->parser->addHelpOption(); + const QCommandLineOption versionOption = d->parser->addVersionOption(); + + if (!d->parser->parse(QCoreApplication::arguments())) + { + *errorMessage = d->parser->errorText(); + return CommandLineError; + } + + if (d->parser->isSet(versionOption)) + { + return CommandLineVersionRequested; + } + + if (d->parser->isSet(helpOption)) + { + return CommandLineHelpRequested; + } + + if (d->parser->isSet(pathOption)) + { + const QString path = d->parser->value(pathOption); + options->path = path; + + if (options->path.isNull() || options->path.isEmpty()) + { + *errorMessage = "Bad policy path: " + path; + return CommandLineError; + } + } + + if (d->parser->isSet(bundleOption)) + { + const QString path = d->parser->value(bundleOption); + options->policyBundle = path; + + if (options->policyBundle.isNull() || options->policyBundle.isEmpty()) + { + *errorMessage = "Bad policy path: " + path; + return CommandLineError; + } + } + + return CommandLineOk; +} + +void CommandLineParser::showHelp() const +{ + d->parser->showHelp(); +} + +void CommandLineParser::showVersion() const +{ + d->parser->showVersion(); +} + +} diff --git a/src/gui/commandlineparser.h b/src/gui/commandlineparser.h new file mode 100644 index 0000000..011648b --- /dev/null +++ b/src/gui/commandlineparser.h @@ -0,0 +1,59 @@ +/*********************************************************************************************************************** +** +** Copyright (C) 2021 BaseALT Ltd. +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +***********************************************************************************************************************/ + +#ifndef GPUI_COMMAND_LINE_PARSER_H +#define GPUI_COMMAND_LINE_PARSER_H + +#include "gui.h" + +#include "../gui/commandlineoptions.h" + +#include +#include + +namespace gpui { + class CommandLineParserPrivate; + + class GPUI_GUI_EXPORT CommandLineParser + { + public: + enum CommandLineParseResult + { + CommandLineOk, + CommandLineError, + CommandLineVersionRequested, + CommandLineHelpRequested + }; + + public: + CommandLineParser(QApplication& application); + ~CommandLineParser(); + + CommandLineParseResult parseCommandLine(CommandLineOptions *options, QString *errorMessage); + + void showHelp() const; + void showVersion() const; + + private: + CommandLineParserPrivate* d; + }; +} + +#endif // GPUI_COMMAND_LINE_PARSER_H diff --git a/src/gui/contentwidget.cpp b/src/gui/contentwidget.cpp index 32d2a74..b5bedc7 100644 --- a/src/gui/contentwidget.cpp +++ b/src/gui/contentwidget.cpp @@ -240,6 +240,8 @@ void ContentWidget::onApplyClicked() { d->commandGroup.execute(); d->commandGroup.clear(); + + savePolicyChanges(); } void ContentWidget::onCancelClicked() diff --git a/src/gui/contentwidget.h b/src/gui/contentwidget.h index 62fe084..0552d3e 100644 --- a/src/gui/contentwidget.h +++ b/src/gui/contentwidget.h @@ -63,6 +63,7 @@ namespace gpui { signals: void modelItemSelected(const QModelIndex& index); + void savePolicyChanges(); private: Ui::ContentWidget *ui; diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index b3e8162..8671d95 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -22,6 +22,8 @@ #include "ui_mainwindow.h" #include "mainwindowsettings.h" +#include "commandlineoptions.h" + #include "contentwidget.h" #include "../model/bundle/policybundle.h" @@ -49,9 +51,11 @@ public: std::shared_ptr userRegistry; std::unique_ptr userRegistrySource; + QString userRegistryPath; std::shared_ptr machineRegistry; std::unique_ptr machineRegistrySource; + QString machineRegistryPath; std::unique_ptr sortModel = nullptr; @@ -81,23 +85,46 @@ void save(const std::string &fileName, std::shared_ptr(); - file.open(fileName, std::ofstream::out | std::ofstream::binary); - - if (file.good()) { - if (!format->write(file, fileData.get())) - { - qWarning() << fileName.c_str() << " " << format->getErrorString().c_str(); - } + if (!format->write(*oss, fileData.get())) + { + qWarning() << fileName.c_str() << " " << format->getErrorString().c_str(); } - file.close(); + oss->flush(); + + qWarning() << "Current string values." << oss->str().c_str(); + + if (QString::fromStdString(fileName).startsWith("smb://")) + { + SmbLocationItemFile smbLocationItemFile(QString::fromStdString(fileName)); + smbLocationItemFile.open(QFile::WriteOnly | QFile::Truncate); + if (!smbLocationItemFile.isOpen()) + { + smbLocationItemFile.open(QFile::NewOnly | QFile::WriteOnly); + } + if (smbLocationItemFile.isOpen() && oss->str().size() > 0) + { + smbLocationItemFile.write(&oss->str().at(0), oss->str().size()); + } + smbLocationItemFile.close(); + } + else + { + QFile registryFile(QString::fromStdString(fileName)); + registryFile.open(QFile::ReadWrite); + if (registryFile.isOpen() && registryFile.isWritable() && oss->str().size() > 0) + { + registryFile.write(&oss->str().at(0), oss->str().size()); + } + registryFile.close(); + } delete format; } -MainWindow::MainWindow(QWidget *parent) +MainWindow::MainWindow(CommandLineOptions &options, QWidget *parent) : QMainWindow(parent) , d(new MainWindowPrivate()) , ui(new Ui::MainWindow()) @@ -118,6 +145,31 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->actionOpenMachineRegistrySource, &QAction::triggered, this, &MainWindow::onMachineRegistrySourceOpen); connect(ui->actionSaveRegistrySource, &QAction::triggered, this, &MainWindow::onRegistrySourceSave); connect(ui->treeView, &QTreeView::clicked, d->contentWidget, &ContentWidget::modelItemSelected); + + if (!options.policyBundle.isEmpty()) + { + loadPolicyBundleFolder(options.policyBundle); + } + + if (!options.path.isEmpty()) + { + d->userRegistryPath = options.path + "/User/Registry.pol"; + d->machineRegistryPath = options.path + "/Machine/Registry.pol"; + + onPolFileOpen(d->userRegistryPath, d->userRegistry, d->userRegistrySource, + [&](model::registry::AbstractRegistrySource* source) + { + d->contentWidget->setUserRegistrySource(source); + }); + + onPolFileOpen(d->machineRegistryPath, d->machineRegistry, d->machineRegistrySource, + [&](model::registry::AbstractRegistrySource* source) + { + d->contentWidget->setMachineRegistrySource(source); + }); + } + + connect(d->contentWidget, &ContentWidget::savePolicyChanges, this, &MainWindow::onRegistrySourceSave); } MainWindow::~MainWindow() @@ -134,16 +186,10 @@ void MainWindow::closeEvent(QCloseEvent *event) QMainWindow::closeEvent(event); } -void MainWindow::onDirectoryOpen() +void gpui::MainWindow::loadPolicyBundleFolder(const QString& path) { - QString directory = QFileDialog::getExistingDirectory( - this, - tr("Open Directory"), - QDir::homePath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - auto bundle = std::make_unique(); - d->model = bundle->loadFolder(directory.toStdString(), "ru-ru"); + d->model = bundle->loadFolder(path.toStdString(), "ru-ru"); d->sortModel = std::make_unique(); d->sortModel->setSourceModel(d->model.get()); @@ -157,6 +203,17 @@ void MainWindow::onDirectoryOpen() d->contentWidget->setSelectionModel(ui->treeView->selectionModel()); } +void MainWindow::onDirectoryOpen() +{ + QString directory = QFileDialog::getExistingDirectory( + this, + tr("Open Directory"), + QDir::homePath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + loadPolicyBundleFolder(directory); +} + void MainWindow::onUserRegistrySourceOpen() { onRegistrySourceOpen(d->userRegistry, d->userRegistrySource, @@ -177,14 +234,30 @@ void MainWindow::onMachineRegistrySourceOpen() void MainWindow::onRegistrySourceSave() { - QString polFileName = QFileDialog::getSaveFileName( - this, - tr("Open Directory"), - QDir::homePath(), - "*.pol"); + if (!d->machineRegistryPath.isEmpty()) + { + qWarning() << "Saving machine registry to: " << d->machineRegistryPath; + save(d->machineRegistryPath.toStdString(), d->machineRegistry); + } + else + { + qWarning() << "Unable to save machine registry path is empty!"; + } - save(polFileName.replace(".pol","Machine.pol").toStdString(), d->machineRegistry); - save(polFileName.replace(".pol","User.pol").toStdString(), d->userRegistry); + if (!d->userRegistryPath.isEmpty()) + { + qWarning() << "Saving user registry to: " << d->userRegistryPath; + save(d->userRegistryPath.toStdString(), d->userRegistry); + } + else + { + qWarning() << "Unable to save user registry path is empty!"; + } +} + +void MainWindow::on_actionExit_triggered() +{ + QApplication::quit(); } void MainWindow::onRegistrySourceOpen(std::shared_ptr& registry, @@ -195,44 +268,61 @@ void MainWindow::onRegistrySourceOpen(std::shared_ptr connect(&browser, &SmbFileBrowser::onPolOpen, this, [&](const QString& path) { - qWarning() << "Path recieved: " << path; - - auto stringvalues = std::make_unique(); - - if (path.startsWith("smb://")) - { - SmbLocationItemFile smbLocationItemFile(path); - smbLocationItemFile.open(QFile::ReadWrite); - stringvalues->resize(smbLocationItemFile.size(), 0); - smbLocationItemFile.read(&stringvalues->at(0), smbLocationItemFile.size()); - } - else - { - QFile registryFile(path); - registryFile.open(QFile::ReadWrite); - stringvalues->resize(registryFile.size(), 0); - registryFile.read(&stringvalues->at(0), registryFile.size()); - } - - auto iss = std::make_unique(*stringvalues); - std::string pluginName("pol"); - - auto reader = std::make_unique(); - auto registryFile = reader->load >(*iss, pluginName); - if (!registryFile) - { - qWarning() << "Unable to load registry file contents."; - return; - } - - registry = registryFile->getRegistry(); - - source = std::make_unique(registry); - - callback(source.get()); + onPolFileOpen(path, registry, source, callback); }); browser.exec(); } +void MainWindow::onPolFileOpen(const QString &path, + std::shared_ptr ®istry, + std::unique_ptr &source, + std::function callback) +{ + qWarning() << "Path recieved: " << path; + + auto stringvalues = std::make_unique(); + + try { + + if (path.startsWith("smb://")) + { + SmbLocationItemFile smbLocationItemFile(path); + smbLocationItemFile.open(QFile::ReadWrite); + stringvalues->resize(smbLocationItemFile.size(), 0); + smbLocationItemFile.read(&stringvalues->at(0), smbLocationItemFile.size()); + smbLocationItemFile.close(); + } + else + { + QFile registryFile(path); + registryFile.open(QFile::ReadWrite); + stringvalues->resize(registryFile.size(), 0); + registryFile.read(&stringvalues->at(0), registryFile.size()); + registryFile.close(); + } + + auto iss = std::make_unique(*stringvalues); + std::string pluginName("pol"); + + auto reader = std::make_unique(); + auto registryFile = reader->load >(*iss, pluginName); + if (!registryFile) + { + qWarning() << "Unable to load registry file contents."; + return; + } + + registry = registryFile->getRegistry(); + + source = std::make_unique(registry); + + callback(source.get()); + } + catch (std::exception& e) + { + qWarning() << "Unable to read file: " << qPrintable(path) << " Error: " << e.what(); + } +} + } diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index 1318e48..86bb88b 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -38,6 +38,7 @@ namespace model { namespace gpui { + class CommandLineOptions; class MainWindowPrivate; class GPUI_GUI_EXPORT MainWindow : public QMainWindow { @@ -45,7 +46,7 @@ namespace gpui { public: // construction and destruction - MainWindow(QWidget *parent = 0); + MainWindow(CommandLineOptions& options, QWidget *parent = 0); ~MainWindow(); protected: @@ -63,10 +64,19 @@ namespace gpui { void onUserRegistrySourceOpen(); void onRegistrySourceSave(); + void on_actionExit_triggered(); + private: void onRegistrySourceOpen(std::shared_ptr& registry, std::unique_ptr& source, std::function callback); + + void onPolFileOpen(const QString& path, + std::shared_ptr& registry, + std::unique_ptr& source, + std::function callback); + + void loadPolicyBundleFolder(const QString& path); }; } diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui index 7926e0d..ebcb801 100644 --- a/src/gui/mainwindow.ui +++ b/src/gui/mainwindow.ui @@ -76,7 +76,6 @@ -