feat: add command line interface for gpui

This commit is contained in:
august-alt 2021-09-22 19:06:49 +04:00
parent 1ea11666a7
commit 4cdfc7e90a
11 changed files with 415 additions and 65 deletions

View File

@ -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)

View File

@ -18,8 +18,8 @@
**
***********************************************************************************************************************/
#include "../gui/commandlineparser.h"
#include "../gui/mainwindow.h"
#include "../model/pluginstorage.h"
#include <QApplication>
@ -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();

View File

@ -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

View File

@ -0,0 +1,36 @@
/***********************************************************************************************************************
**
** Copyright (C) 2021 BaseALT Ltd. <org@basealt.ru>
**
** 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 <QString>
#include <QUuid>
namespace gpui {
class CommandLineOptions
{
public:
QString policyBundle;
QString path;
};
}
#endif // GPUI_COMMAND_LINE_OPTIONS_H

View File

@ -0,0 +1,120 @@
/***********************************************************************************************************************
**
** Copyright (C) 2021 BaseALT Ltd. <org@basealt.ru>
**
** 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 <memory>
#include <QUuid>
#include <QCommandLineParser>
namespace gpui
{
class CommandLineParserPrivate
{
public:
QApplication& application;
std::unique_ptr<QCommandLineParser> parser;
CommandLineParserPrivate(QApplication &application)
: application(application)
{
parser = std::make_unique<QCommandLineParser>();
}
};
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();
}
}

View File

@ -0,0 +1,59 @@
/***********************************************************************************************************************
**
** Copyright (C) 2021 BaseALT Ltd. <org@basealt.ru>
**
** 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 <QApplication>
#include <QCommandLineParser>
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

View File

@ -240,6 +240,8 @@ void ContentWidget::onApplyClicked()
{
d->commandGroup.execute();
d->commandGroup.clear();
savePolicyChanges();
}
void ContentWidget::onCancelClicked()

View File

@ -63,6 +63,7 @@ namespace gpui {
signals:
void modelItemSelected(const QModelIndex& index);
void savePolicyChanges();
private:
Ui::ContentWidget *ui;

View File

@ -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<model::registry::Registry> userRegistry;
std::unique_ptr<model::registry::AbstractRegistrySource> userRegistrySource;
QString userRegistryPath;
std::shared_ptr<model::registry::Registry> machineRegistry;
std::unique_ptr<model::registry::AbstractRegistrySource> machineRegistrySource;
QString machineRegistryPath;
std::unique_ptr<QSortFilterProxyModel> sortModel = nullptr;
@ -81,23 +85,46 @@ void save(const std::string &fileName, std::shared_ptr<model::registry::Registry
return;
}
std::ofstream file;
auto oss = std::make_unique<std::ostringstream>();
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<model::bundle::PolicyBundle>();
d->model = bundle->loadFolder(directory.toStdString(), "ru-ru");
d->model = bundle->loadFolder(path.toStdString(), "ru-ru");
d->sortModel = std::make_unique<QSortFilterProxyModel>();
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<model::registry::Registry>& registry,
@ -195,44 +268,61 @@ void MainWindow::onRegistrySourceOpen(std::shared_ptr<model::registry::Registry>
connect(&browser, &SmbFileBrowser::onPolOpen, this, [&](const QString& path)
{
qWarning() << "Path recieved: " << path;
auto stringvalues = std::make_unique<std::string>();
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<std::istringstream>(*stringvalues);
std::string pluginName("pol");
auto reader = std::make_unique<io::GenericReader>();
auto registryFile = reader->load<io::RegistryFile, io::RegistryFileFormat<io::RegistryFile> >(*iss, pluginName);
if (!registryFile)
{
qWarning() << "Unable to load registry file contents.";
return;
}
registry = registryFile->getRegistry();
source = std::make_unique<model::registry::PolRegistrySource>(registry);
callback(source.get());
onPolFileOpen(path, registry, source, callback);
});
browser.exec();
}
void MainWindow::onPolFileOpen(const QString &path,
std::shared_ptr<model::registry::Registry> &registry,
std::unique_ptr<model::registry::AbstractRegistrySource> &source,
std::function<void (model::registry::AbstractRegistrySource *)> callback)
{
qWarning() << "Path recieved: " << path;
auto stringvalues = std::make_unique<std::string>();
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<std::istringstream>(*stringvalues);
std::string pluginName("pol");
auto reader = std::make_unique<io::GenericReader>();
auto registryFile = reader->load<io::RegistryFile, io::RegistryFileFormat<io::RegistryFile> >(*iss, pluginName);
if (!registryFile)
{
qWarning() << "Unable to load registry file contents.";
return;
}
registry = registryFile->getRegistry();
source = std::make_unique<model::registry::PolRegistrySource>(registry);
callback(source.get());
}
catch (std::exception& e)
{
qWarning() << "Unable to read file: " << qPrintable(path) << " Error: " << e.what();
}
}
}

View File

@ -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<model::registry::Registry>& registry,
std::unique_ptr<model::registry::AbstractRegistrySource>& source,
std::function<void(model::registry::AbstractRegistrySource* source)> callback);
void onPolFileOpen(const QString& path,
std::shared_ptr<model::registry::Registry>& registry,
std::unique_ptr<model::registry::AbstractRegistrySource>& source,
std::function<void(model::registry::AbstractRegistrySource* source)> callback);
void loadPolicyBundleFolder(const QString& path);
};
}

View File

@ -76,7 +76,6 @@
<addaction name="separator"/>
<addaction name="actionOpenUserRegistrySource"/>
<addaction name="actionOpenMachineRegistrySource"/>
<addaction name="actionSaveRegistrySource"/>
<addaction name="separator"/>
<addaction name="actionOptions"/>
<addaction name="separator"/>