Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
qt6-after/qt6-migrated-legatus/Lts/Plugins/TakeHomePackageManager/THP2/Thp2Management/CMakeLists.txt
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Exported scripts management for uploading, downloading and removing exported scripts
|
||||
#
|
||||
# $Id: CMakeLists.txt 51804 2020-07-31 04:47:28Z fritsche_h $
|
||||
# $HeadURL: svn://slssvn/TDS/branches/product/iterations/21_03_salted_caramel/Lts/Plugins/TakeHomePackageManager/CMakeLists.txt $
|
||||
# $Author: fritsche_h $
|
||||
#
|
||||
# Created by Mike Wille, SLTE, 2020-03-23
|
||||
#
|
||||
|
||||
SET(src
|
||||
tpm2_gui_plugin.cpp
|
||||
tpm2_gui_plugin.h
|
||||
tpm2_exported_scripts_dialog.cpp
|
||||
tpm2_exported_scripts_dialog.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
QT5_WRAP_UI(src
|
||||
tpm2_exported_scripts_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS Thp2ManagementGuiPlugin MODULE ${src})
|
||||
NGL_TARGET_COMPILE_DEFINITIONS(Thp2ManagementGuiPlugin PRIVATE L=QStringLiteral)
|
||||
NGL_TARGET_LINK_LIBRARIES(Thp2ManagementGuiPlugin
|
||||
Thp2Common
|
||||
Thp2CommonCore
|
||||
Tpm2GuiPluginInterface
|
||||
Qt5::Widgets
|
||||
Qt5::Network
|
||||
Qt5::WebSockets # get live changes from the server
|
||||
NGLLogger
|
||||
LtsWidgets
|
||||
LtsSession
|
||||
LtsDataView
|
||||
nglcompression # tar
|
||||
nglsettings # windoze / OC thp server hostname
|
||||
ngltools # NGL::Connections::eConnection and findProjectConfigFile
|
||||
#AsmDataPluginInterface
|
||||
#ExmDataPluginInterface
|
||||
LtsSessionData
|
||||
#httq
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(Thp2ManagementGuiPlugin)
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "TPM2.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
+973
@@ -0,0 +1,973 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ui_tpm2_exported_scripts_dialog.h"
|
||||
#include "tpm2_exported_scripts_dialog.h"
|
||||
|
||||
#include <Common2/tpm_process_dialog.h>
|
||||
#include <Common2/tpm_file_copy.h>
|
||||
#include <Common2Core/tpm_tools.h>
|
||||
|
||||
#include <nglcompression/nglcomp_compress.h>
|
||||
#include <nglsettings/nglsettings_connections.h>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <LtsWidgets/lts_global_wait_dialog.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QTemporaryFile>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QWebSocket>
|
||||
#include <QLocale>
|
||||
#include <QTimer>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
#ifndef ELOG
|
||||
#define ELOG ERROR_LOG(m_logger)
|
||||
#endif
|
||||
|
||||
using err = std::runtime_error;
|
||||
err error(const QString &msg) { return err(msg.toStdString()); }
|
||||
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
|
||||
Compressor::Compressor()
|
||||
: QObject(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
void Compressor::go(ProcessOverlay *processOverlay, QIODevice &out, const QString &sourceDir, const QString &destRootDir) noexcept(false)
|
||||
{
|
||||
|
||||
auto *compress = new NGL::Compress(nullptr);
|
||||
|
||||
bool firstTime = true;
|
||||
connect(compress, &NGL::Compress::compressInfoEx,
|
||||
this, [processOverlay, &firstTime](qint64 totalFiles, qint64 curFile, qint64 fileSize, qint64 curPos, const QString &curName, const qint64 bytesTotal)
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
processOverlay->setStarted(totalFiles, bytesTotal);
|
||||
processOverlay->setNewFile(curFile, fileSize, curName);
|
||||
processOverlay->setStatus(tr("Compressing files ..."));
|
||||
}
|
||||
|
||||
processOverlay->setFileProgress(curPos, fileSize);
|
||||
});
|
||||
|
||||
QString errorString;
|
||||
connect(compress, &NGL::Compress::error,
|
||||
this, [&errorString](const QString &errStr)
|
||||
{
|
||||
qWarning() << "## COMPRESS ERROR" << errStr;
|
||||
errorString = errStr;
|
||||
});
|
||||
|
||||
connect(this, &Compressor::abort,
|
||||
compress, [&errorString]()
|
||||
{
|
||||
errorString = L("Aborted.");
|
||||
});
|
||||
|
||||
|
||||
compress->compress(&out, sourceDir, destRootDir);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
awaitWithCancelationSignalx(compress, &NGL::Compress::finished, this, &Compressor::abort);
|
||||
}
|
||||
catch(const std::runtime_error &err)
|
||||
{
|
||||
qWarning() << "## aborted" << err.what();
|
||||
compress->abort();
|
||||
compress->waitForFinished();
|
||||
compress->deleteLater();
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
||||
const bool success = compress->waitForFinished();
|
||||
|
||||
compress->deleteLater();
|
||||
|
||||
|
||||
if (!success || !errorString.isEmpty())
|
||||
{
|
||||
throw error(L("compress failed: %1").arg(errorString));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
HttpProcess::HttpProcess(LtsWidgets::LtsDialog *dialog, const QString &statusMessage)
|
||||
: QObject()
|
||||
, m_logger(getLogger("ExportedScriptsDialog.HttpProcess"))
|
||||
, m_process(new ProcessOverlay)
|
||||
, m_nam(new QNetworkAccessManager)
|
||||
{
|
||||
connect(m_process, &ProcessOverlay::signalCancel,
|
||||
this, [this]()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_wasCanceled!!";
|
||||
m_process->setCancelEnabled(false);
|
||||
emit signalCancel();
|
||||
});
|
||||
|
||||
dialog->setOverlay(m_process);
|
||||
m_process->setStatus(statusMessage);
|
||||
}
|
||||
|
||||
|
||||
HttpProcess::~HttpProcess()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "~HttpProcess";
|
||||
m_process->deleteLater();
|
||||
m_nam->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
QUrl ExportedScriptsDialog::forgeUrl(const QString &path, const QString &protocol)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const bool isTabOC = true;
|
||||
#else
|
||||
const bool isTabOC = false;
|
||||
#endif
|
||||
|
||||
const QString hostname(isTabOC
|
||||
? NGL::Settings(NGL::findProjectConfigFile()).getString(L("TabOC"), L("remoteServerHostname"), L("exctds01"))
|
||||
: NGL::Connections::hostName(NGL::Connections::eConnection::FLM_THP_SERVER));
|
||||
|
||||
const QUrl url(QStringLiteral("%1://%2:%3%4").arg(protocol, hostname).arg(NGL::Connections::port(NGL::Connections::eConnection::FLM_THP_SERVER)).arg(path));
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
QNetworkRequest ExportedScriptsDialog::forgeRequest(const QString &path, const QUrlQuery &q, const QString &contentType)
|
||||
{
|
||||
auto url = forgeUrl(path);
|
||||
url.setQuery(q);
|
||||
|
||||
QNetworkRequest r;
|
||||
if (!contentType.isEmpty())
|
||||
r.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, contentType);
|
||||
r.setUrl(url);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int getResponseStatus(QNetworkReply *r) noexcept(false)
|
||||
{
|
||||
bool k = false;
|
||||
const int status = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&k);
|
||||
if (!k)
|
||||
{
|
||||
throw err("Missing http status in http response");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void HttpProcess::waitForAnswer(QNetworkReply *r, const int expectedResponseStatus) noexcept(false)
|
||||
{
|
||||
if (!r->isFinished() && r->bytesAvailable() < 1)
|
||||
{
|
||||
|
||||
|
||||
|
||||
std::unique_ptr<NoticeDummy> dummy(new NoticeDummy);
|
||||
connect(r, &QNetworkReply::finished, dummy.get(), &NoticeDummy::signal, Qt::QueuedConnection);
|
||||
connect(r, &QNetworkReply::readyRead, dummy.get(), &NoticeDummy::signal, Qt::QueuedConnection);
|
||||
|
||||
awaitWithCancelationSignalx(dummy.get(), &NoticeDummy::signal, this, &HttpProcess::signalCancel);
|
||||
}
|
||||
|
||||
|
||||
if (r->error() != QNetworkReply::NetworkError::NoError)
|
||||
{
|
||||
r->deleteLater();
|
||||
throw error(L("network error: %1").arg(r->errorString()));
|
||||
}
|
||||
|
||||
|
||||
const int status = getResponseStatus(r);
|
||||
if (status == expectedResponseStatus)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
r->deleteLater();
|
||||
const QByteArray data(r->readAll());
|
||||
|
||||
ELOG << "server error: data = '" << data << "' http status: " << r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
QJsonParseError parseError;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(data, &parseError));
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
ELOG << "didn't receive a valid json from server at " << parseError.offset << ": " << parseError.errorString() << " - message was: '" << data << "'";
|
||||
throw err("request failed and error msg from server was malformed");
|
||||
}
|
||||
|
||||
const QString errorMsg(doc.object()[QStringLiteral("error")].toString());
|
||||
|
||||
if (errorMsg.isEmpty())
|
||||
ELOG << "server sent empty error";
|
||||
else
|
||||
ELOG << "server sent error: " << errorMsg;
|
||||
|
||||
|
||||
throw error(L("request failed - server said: %1 (http status = %2)").arg(errorMsg).arg(r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()));
|
||||
}
|
||||
|
||||
|
||||
QNetworkReply *HttpProcess::post(const QString &path, QIODevice *data, const QUrlQuery &q, const QString &contentType, const QMap<QString, QString> &additionalHeaders) noexcept(false)
|
||||
{
|
||||
auto req = ExportedScriptsDialog::forgeRequest(path, q, contentType);
|
||||
|
||||
QMapIterator<QString, QString> it(additionalHeaders);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
auto key = it.key();
|
||||
auto val = it.value();
|
||||
req.setRawHeader(key.toUtf8(), val.toUtf8());
|
||||
}
|
||||
|
||||
QNetworkReply *r = m_nam->post(req, data);
|
||||
|
||||
bool firstTime = true;
|
||||
connect(r, &QNetworkReply::uploadProgress,
|
||||
this, [this, &firstTime, path](const qint64 bytes, const qint64 bytesTotal)
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
m_process->setStarted(1, bytesTotal);
|
||||
m_process->setNewFile(1, bytesTotal, path);
|
||||
m_process->setStatus(tr("Uploading ..."));
|
||||
}
|
||||
|
||||
m_process->setFileProgress(bytes, bytesTotal);
|
||||
});
|
||||
|
||||
waitForAnswer(r, 201);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
QNetworkReply *HttpProcess::get(const QString &path, const QUrlQuery &q) noexcept(false)
|
||||
{
|
||||
QNetworkReply *r = m_nam->get(ExportedScriptsDialog::forgeRequest(path, q));
|
||||
|
||||
|
||||
bool firstTime = true;
|
||||
connect(r, &QNetworkReply::downloadProgress,
|
||||
this, [this, &firstTime, path](const qint64 bytes, const qint64 bytesTotal)
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
m_process->setStarted(1, bytesTotal);
|
||||
m_process->setNewFile(1, bytesTotal, path);
|
||||
m_process->setStatus(tr("Downloading ..."));
|
||||
}
|
||||
|
||||
m_process->setFileProgress(bytes, bytesTotal);
|
||||
});
|
||||
|
||||
|
||||
|
||||
waitForAnswer(r, 200);
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
QNetworkReply *HttpProcess::deleteResource(const QString &path, const QUrlQuery &q) noexcept(false)
|
||||
{
|
||||
QNetworkReply *r = m_nam->deleteResource(ExportedScriptsDialog::forgeRequest(path, q));
|
||||
waitForAnswer(r, 200);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
UploadProcess::UploadProcess(LtsWidgets::LtsDialog *dialog)
|
||||
: HttpProcess(dialog, tr("Preparing Script upload ..."))
|
||||
{}
|
||||
|
||||
|
||||
void UploadProcess::upload(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const ExportedScriptInformation &esi) noexcept(false)
|
||||
{
|
||||
UploadProcess up(dialog);
|
||||
up.go(rootFolder, esi);
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<QTemporaryFile> createTempFile() noexcept(false)
|
||||
{
|
||||
std::unique_ptr<QTemporaryFile> tempFile(new QTemporaryFile);
|
||||
if (!tempFile->open())
|
||||
{
|
||||
const QString msg(L("Cannot open temporary file: %1").arg(tempFile->errorString()));
|
||||
throw error(msg);
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
|
||||
void UploadProcess::go(const QString &rootFolder, const ExportedScriptInformation &esi) noexcept(false)
|
||||
{
|
||||
|
||||
const QString dstDir(esi.id());
|
||||
const QString srcDir(scriptLocation(rootFolder, esi.id()));
|
||||
|
||||
|
||||
auto tempFile(createTempFile());
|
||||
|
||||
Compressor compressor;
|
||||
connect(this, &HttpProcess::signalCancel, &compressor, &Compressor::abort);
|
||||
compressor.go(m_process, *tempFile.get(), srcDir, dstDir);
|
||||
|
||||
DEBUG_LOG(m_logger) << "posting file of size " << tempFile->size();
|
||||
tempFile->seek(0);
|
||||
|
||||
QNetworkReply *rep = post(L("/thp2"), tempFile.get(), {}, L("application/octet-stream"), { { L("x-thp-info"), QString::fromUtf8(QJsonDocument(esi.toJson().toObject()).toJson(QJsonDocument::JsonFormat::Compact)) } });
|
||||
rep->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DownloadProcess::DownloadProcess(LtsWidgets::LtsDialog *dialog)
|
||||
: HttpProcess(dialog, tr("Preparing Script download ..."))
|
||||
{}
|
||||
|
||||
|
||||
void DownloadProcess::download(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const QString &scriptId) noexcept(false)
|
||||
{
|
||||
DownloadProcess down(dialog);
|
||||
down.go(dialog, rootFolder, scriptId);
|
||||
}
|
||||
|
||||
|
||||
void DownloadProcess::go(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const QString &scriptId) noexcept(false)
|
||||
{
|
||||
|
||||
auto tempFile = createTempFile();
|
||||
QNetworkReply *rep = get(L("/thp2"), QUrlQuery({{L("scriptId"), scriptId}}));
|
||||
const auto thpInfo(rep->rawHeader(L("x-thp-info").toUtf8()));
|
||||
|
||||
if (thpInfo.isEmpty())
|
||||
{
|
||||
throw err("x-thp-info header missing");
|
||||
}
|
||||
|
||||
const auto esi = ExportedScriptInformation::fromJson(JsonObject::fromJson(thpInfo).object());
|
||||
|
||||
|
||||
connect(rep, &QNetworkReply::readyRead,
|
||||
this, [rep, &tempFile]()
|
||||
{
|
||||
tempFile->write(rep->readAll());
|
||||
});
|
||||
|
||||
if (rep->bytesAvailable() > 0)
|
||||
{
|
||||
tempFile->write(rep->readAll());
|
||||
}
|
||||
|
||||
|
||||
if (!rep->isFinished())
|
||||
{
|
||||
try
|
||||
{
|
||||
awaitWithCancelationSignalx(rep, &QNetworkReply::finished, this, &HttpProcess::signalCancel);
|
||||
}
|
||||
catch(const err &err)
|
||||
{
|
||||
rep->deleteLater();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_process->setStatus(tr("Preparing Script decompression ..."));
|
||||
|
||||
std::unique_ptr<NGL::Compress> compress(new NGL::Compress(nullptr));
|
||||
|
||||
tempFile->seek(0);
|
||||
|
||||
|
||||
QTemporaryDir tmpDir;
|
||||
if (!tmpDir.isValid())
|
||||
{
|
||||
throw error(L("Temp dir creation failed: %1").arg(tmpDir.errorString()));
|
||||
}
|
||||
|
||||
bool firstTime = true;
|
||||
connect(compress.get(), &NGL::Compress::uncompressInfo,
|
||||
this, [this, &firstTime](qint64 size, qint64 pos, const QString &file)
|
||||
{
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
m_process->setStarted(1, size);
|
||||
m_process->setNewFile(1, size, file);
|
||||
m_process->setStatus(tr("Decompressing ..."));
|
||||
}
|
||||
|
||||
m_process->setFileProgress(pos, size);
|
||||
});
|
||||
|
||||
QString errorString;
|
||||
connect(compress.get(), &NGL::Compress::error,
|
||||
this, [&errorString](const QString &errStr)
|
||||
{
|
||||
qWarning() << "## COMPRESS ERROR" << errStr;
|
||||
errorString = errStr;
|
||||
});
|
||||
|
||||
compress->uncompress(tempFile.get(), tmpDir.path());
|
||||
|
||||
try
|
||||
{
|
||||
awaitWithCancelationSignalx(compress.get(), &NGL::Compress::finished, this, &HttpProcess::signalCancel);
|
||||
}
|
||||
catch(const std::runtime_error &err)
|
||||
{
|
||||
qWarning() << "## abort" << err.what();
|
||||
compress->abort();
|
||||
compress->waitForFinished();
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
||||
const bool success = compress->waitForFinished();
|
||||
|
||||
if (!success || !errorString.isEmpty())
|
||||
{
|
||||
throw error(L("uncompress failed: %1").arg(errorString));
|
||||
}
|
||||
|
||||
|
||||
const auto scriptLocationString(scriptLocation(rootFolder, scriptId));
|
||||
if (!QDir(scriptLocationString).removeRecursively())
|
||||
{
|
||||
throw error(L("failed to remove existing script directory at %1").arg(scriptLocationString));
|
||||
}
|
||||
|
||||
|
||||
|
||||
CopyInfoList fileList;
|
||||
fileList += getFilesFromFolder(tmpDir.path() + QDir::separator() + scriptId, scriptLocationString);
|
||||
m_process->hide();
|
||||
dialog->unsetOverlay();
|
||||
m_process->hide();
|
||||
copyFiles(fileList, dialog);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
RemoveProcess::RemoveProcess(LtsWidgets::LtsDialog *dialog)
|
||||
: HttpProcess(dialog, tr("Requesting Script deletion on server ..."))
|
||||
{}
|
||||
|
||||
|
||||
void RemoveProcess::remove(LtsWidgets::LtsDialog *dialog, const QString &scriptId) noexcept(false)
|
||||
{
|
||||
RemoveProcess rm(dialog);
|
||||
rm.go(scriptId);
|
||||
}
|
||||
|
||||
|
||||
void RemoveProcess::go(const QString &scriptId) noexcept(false)
|
||||
{
|
||||
deleteResource(L("/thp2"), {{ L("scriptId"), scriptId }});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ExportedScriptsDialog::ExportedScriptsDialog(LtsSession::LtsSession *session, QWidget *parent) noexcept(false)
|
||||
: LtsWidgets::LtsDialog(parent)
|
||||
, m_model(new ExportedScriptsModel(this))
|
||||
, m_ui(new Ui::ExportedScriptsDialog2)
|
||||
, m_session(session)
|
||||
, m_logger(getLogger("ExportedScriptsDialog2"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &ExportedScriptsDialog::removeScriptLocal);
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false);
|
||||
|
||||
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::signalSelectionChanged, this, &ExportedScriptsDialog::onSelectionChanged);
|
||||
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Script_Editor-Export_Script_Administration"));
|
||||
|
||||
|
||||
if (isOCApp())
|
||||
{
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &ExportedScriptsDialog::downloadScript);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Show, this, &ExportedScriptsDialog::openScript);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &ExportedScriptsDialog::uploadScript);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Import, this, &ExportedScriptsDialog::removeScriptFromServer);
|
||||
}
|
||||
|
||||
|
||||
QWebSocket *sock = new QWebSocket();
|
||||
sock->setParent(this);
|
||||
|
||||
auto openFn = [this, sock]()
|
||||
{
|
||||
setWsConnectionStatus(WsConnectionStatus::Connecting);
|
||||
sock->open(forgeUrl(L("/thp2"), L("ws")));
|
||||
};
|
||||
|
||||
openFn();
|
||||
|
||||
|
||||
connect(sock, &QWebSocket::connected,
|
||||
this, [this]()
|
||||
{
|
||||
setWsConnectionStatus(WsConnectionStatus::Connected);
|
||||
});
|
||||
|
||||
|
||||
connect(sock, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
|
||||
this, [this, sock]()
|
||||
{
|
||||
setWsConnectionStatus(WsConnectionStatus::Error);
|
||||
ELOG << "ws error: " << sock->errorString();
|
||||
}, Qt::QueuedConnection );
|
||||
|
||||
|
||||
connect(sock, &QWebSocket::disconnected,
|
||||
this, [this, sock, openFn]()
|
||||
{
|
||||
WARNING_LOG(m_logger) << "disconnected from ws... reconnecting in 3...";
|
||||
setWsConnectionStatus(WsConnectionStatus::Disconnected);
|
||||
|
||||
QTimer *t = new QTimer(sock);
|
||||
t->setInterval(3000);
|
||||
t->setSingleShot(true);
|
||||
|
||||
connect(t, &QTimer::timeout,
|
||||
sock, [t, openFn]()
|
||||
{
|
||||
openFn();
|
||||
t->deleteLater();
|
||||
});
|
||||
|
||||
t->start();
|
||||
}, Qt::QueuedConnection );
|
||||
|
||||
|
||||
connect(sock, &QWebSocket::textMessageReceived,
|
||||
this, [this](const QString &msg)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "new msg: '" << msg << "'";
|
||||
m_lastServerContent = msg;
|
||||
m_model->setServerContent(msg);
|
||||
onSelectionChanged();
|
||||
});
|
||||
|
||||
|
||||
initModel();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ExportedScriptsDialog::~ExportedScriptsDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
bool ExportedScriptsDialog::isOCApp() const
|
||||
{
|
||||
|
||||
return (m_session->app() == LtsAppDescriptor::App::OC);
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::onSelectionChanged()
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false);
|
||||
|
||||
QTimer::singleShot(500, this, &ExportedScriptsDialog::_onSelectionChanged);
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::_onSelectionChanged()
|
||||
{
|
||||
const QModelIndexList mil(m_ui->ltsDataView->selectedRows());
|
||||
|
||||
const bool isOneSelected = (mil.size() == 1);
|
||||
|
||||
bool enableShow = false;
|
||||
bool enableRemoveLocal = false;
|
||||
bool enableDownload = false;
|
||||
bool enableUpload = false;
|
||||
bool enableRemoveServer = false;
|
||||
|
||||
if (isOneSelected)
|
||||
{
|
||||
const ExportedScriptInformation esi = m_model->getRowData(mil.first().row());
|
||||
|
||||
const bool isOC = isOCApp();
|
||||
const bool onLocal = esi.local;
|
||||
const bool onServer = (esi.uploaded == ExportedScriptInformation::UploadState::ThpAlreadyUploaded);
|
||||
|
||||
enableShow = isOC && onLocal;
|
||||
enableDownload = isOC && onServer;
|
||||
enableUpload = !isOC && onLocal;
|
||||
enableRemoveLocal = onLocal;
|
||||
enableRemoveServer = onServer;
|
||||
}
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(enableShow);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(enableDownload || enableUpload);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(enableRemoveLocal);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(enableRemoveServer);
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Manage exported scripts"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setText(tr("Remove local"));
|
||||
|
||||
Q_ASSERT(m_session != nullptr);
|
||||
|
||||
if (isOCApp())
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Download from Server"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Upload to Server"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setText(tr("Remove from Server"));
|
||||
}
|
||||
|
||||
setWsConnectionStatusLabel();
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::setWsConnectionStatus(WsConnectionStatus status)
|
||||
{
|
||||
m_wsStatus = status;
|
||||
setWsConnectionStatusLabel();
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::setWsConnectionStatusLabel()
|
||||
{
|
||||
QString str;
|
||||
QColor color;
|
||||
|
||||
switch (m_wsStatus)
|
||||
{
|
||||
case WsConnectionStatus::NotConnected:
|
||||
{
|
||||
str = tr("Not connected");
|
||||
color = QColor::fromRgb(100, 100, 100);
|
||||
break;
|
||||
}
|
||||
|
||||
case WsConnectionStatus::Disconnected:
|
||||
{
|
||||
str = tr("Disconnected");
|
||||
color = QColor::fromRgb(200, 55, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WsConnectionStatus::Error:
|
||||
{
|
||||
str = tr("Connection error");
|
||||
color = QColor::fromRgb(200, 55, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case WsConnectionStatus::Connecting:
|
||||
{
|
||||
str = tr("Connecting ...");
|
||||
color = QColor::fromRgb(100, 100, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case WsConnectionStatus::Connected:
|
||||
{
|
||||
str = tr("Connected");
|
||||
color = QColor::fromRgb(50, 200, 50);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_ui->lblWsStatus->setText(QStringLiteral("<font color='%2'>%1</font>").arg(str, color.name()));
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::initModel() noexcept(false)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "(re)initModel !!";
|
||||
|
||||
const QString rootDirectory(localThpDir());
|
||||
|
||||
QDir().mkpath(rootDirectory);
|
||||
try{
|
||||
m_model->init(rootDirectory, true);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Couldn't Load THP(s)"));
|
||||
WARNING_LOG(m_logger)<<" data corrupted path: "<< localThpDir();
|
||||
}
|
||||
|
||||
m_model->setOC(isOCApp());
|
||||
m_ui->ltsDataView->setModel(m_model);
|
||||
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->ltsDataView->hideColumn(ExportedScriptsModel::ColId);
|
||||
#endif
|
||||
|
||||
m_ui->ltsDataView->hideColumn(ExportedScriptsModel::Columns::ColUploadStatus);
|
||||
|
||||
m_model->setServerContent(m_lastServerContent);
|
||||
onSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::uploadScript()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->ltsDataView->selectedRows();
|
||||
if (mil.size() != 1)
|
||||
return;
|
||||
const ExportedScriptInformation esi = m_model->getRowData(mil.first().row());
|
||||
|
||||
if (!esi.local)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
UploadProcess::upload(this, localThpDir(), std::move(esi));
|
||||
|
||||
}
|
||||
catch(const std::runtime_error &err)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Uploaded script FAILED: " << err.what();
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Uploading script failed: %1").arg(QString::fromUtf8(err.what())));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Uploaded script successfully";
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Uploaded script successfully"));
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::downloadScript()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->ltsDataView->selectedRows();
|
||||
if (mil.size() != 1)
|
||||
return;
|
||||
const QModelIndex mi = mil.first();
|
||||
ExportedScriptInformation esi = m_model->getRowData(mi.row());
|
||||
|
||||
if (esi.uploaded != ExportedScriptInformation::UploadState::ThpAlreadyUploaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DownloadProcess::download(this, localThpDir(), esi.id());
|
||||
|
||||
|
||||
for (int row = 0; row < m_model->rowCount(); row++)
|
||||
{
|
||||
const auto rowEsi(m_model->getRowData(row));
|
||||
if (rowEsi.id() != esi.id())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
esi.setLocal(rowEsi.createdAtServer);
|
||||
|
||||
if (!m_model->setRowData(row, esi))
|
||||
{
|
||||
qWarning() << "failed... ignored...";
|
||||
break;
|
||||
}
|
||||
|
||||
m_model->writeScriptsJson();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(const std::runtime_error &err)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Downloading script FAILED: " << err.what();
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Downloading script failed: %1").arg(QString::fromUtf8(err.what())));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "Downloaded script successfully";
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Downloaded script successfully"));
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::removeScriptFromServer()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->ltsDataView->selectedRows();
|
||||
if (mil.size() != 1)
|
||||
return;
|
||||
|
||||
const ExportedScriptInformation esi = m_model->getRowData(mil.first().row());
|
||||
|
||||
if (esi.uploaded != ExportedScriptInformation::UploadState::ThpAlreadyUploaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
RemoveProcess::remove(this, esi.id());
|
||||
|
||||
}
|
||||
catch (const std::runtime_error &err)
|
||||
{
|
||||
ERROR_LOG(m_logger) << err.what();
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Failed to remove script from server!"));
|
||||
return;
|
||||
}
|
||||
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Script was removed from server successfully"));
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::removeScriptLocal()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->ltsDataView->selectedRows();
|
||||
if (mil.size() != 1)
|
||||
return;
|
||||
|
||||
const ExportedScriptInformation esi = m_model->getRowData(mil.first().row());
|
||||
|
||||
if (!esi.local)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto &esi = m_model->getRowData(mil.first().row());
|
||||
const auto scriptId = esi.id();
|
||||
|
||||
if (scriptId.length() < 3)
|
||||
{
|
||||
ELOG << "scriptId is not in format 'n.n' - skipping for safety reasons - scriptId was: " << scriptId;
|
||||
throw err("scriptId.length() < 3");
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_model->removeLocalScript(scriptId);
|
||||
onSelectionChanged();
|
||||
|
||||
|
||||
|
||||
QDir dir(scriptLocation(localThpDir(), scriptId));
|
||||
if (!dir.exists())
|
||||
{
|
||||
ELOG << "script dir doesn't exist - ignoring - path was: " << dir.path();
|
||||
}
|
||||
else if (!dir.removeRecursively())
|
||||
{
|
||||
ELOG << "failed to remove script dir - path was: " << dir.path();
|
||||
throw err("!dir.removeRecursively()");
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error &err)
|
||||
{
|
||||
ERROR_LOG(m_logger) << err.what();
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Failed to remove script locally!"));
|
||||
return;
|
||||
}
|
||||
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Script was locally removed successfully."));
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsDialog::openScript()
|
||||
{
|
||||
const QModelIndexList mil = m_ui->ltsDataView->selectedRows();
|
||||
if (mil.size() != 1)
|
||||
return;
|
||||
const ExportedScriptInformation esi = m_model->getRowData(mil.first().row());
|
||||
|
||||
if (!esi.local)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto path(QDir(scriptHtmlLocation(localThpDir(), esi.id())).path());
|
||||
const auto url(QUrl::fromLocalFile(path));
|
||||
const bool openUrlResult = QDesktopServices::openUrl(url);
|
||||
DEBUG_LOG(m_logger) << "path: " << path << " - url: " << url.toString() << " - success? " << openUrlResult;
|
||||
}
|
||||
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <Common2/tpm_exported_scripts_model.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <QUrlQuery>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExportedScriptsDialog2;
|
||||
}
|
||||
namespace NGL
|
||||
{
|
||||
class Compress;
|
||||
}
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QNetworkRequest;
|
||||
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
class ProcessOverlay;
|
||||
|
||||
|
||||
class Compressor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Compressor();
|
||||
void go(ProcessOverlay *processOverlay, QIODevice &out, const QString &sourceDir, const QString &destRootDir) noexcept(false);
|
||||
|
||||
signals:
|
||||
void abort();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class NoticeDummy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
|
||||
signals:
|
||||
void signal();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class HttpProcess : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HttpProcess(LtsWidgets::LtsDialog *dialog, const QString &statusMessage);
|
||||
virtual ~HttpProcess();
|
||||
|
||||
signals:
|
||||
void signalCancel();
|
||||
|
||||
protected:
|
||||
void waitForAnswer(QNetworkReply *r, const int expectedResponseStatus) noexcept(false);
|
||||
|
||||
QNetworkReply *post(const QString &path, QIODevice *data, const QUrlQuery &q = QUrlQuery(), const QString &contentType = QStringLiteral("application/octet-stream"), const QMap<QString, QString> &additionalHeaders = {}) noexcept(false);
|
||||
QNetworkReply *get(const QString &path, const QUrlQuery &q = QUrlQuery()) noexcept(false);
|
||||
QNetworkReply *deleteResource(const QString &path, const QUrlQuery &q = QUrlQuery()) noexcept(false);
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
ProcessOverlay *m_process;
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_nam;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class UploadProcess : public HttpProcess
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void upload(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const ExportedScriptInformation &esi) noexcept(false);
|
||||
|
||||
private:
|
||||
UploadProcess(LtsWidgets::LtsDialog *dialog);
|
||||
|
||||
protected:
|
||||
void go(const QString &rootFolder, const ExportedScriptInformation &esi) noexcept(false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DownloadProcess : public HttpProcess
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void download(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const QString &scriptId) noexcept(false);
|
||||
|
||||
private:
|
||||
DownloadProcess(LtsWidgets::LtsDialog *dialog);
|
||||
|
||||
protected:
|
||||
void go(LtsWidgets::LtsDialog *dialog, const QString &rootFolder, const QString &scriptId) noexcept(false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RemoveProcess : public HttpProcess
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void remove(LtsWidgets::LtsDialog *dialog, const QString &scriptId) noexcept(false);
|
||||
|
||||
private:
|
||||
RemoveProcess(LtsWidgets::LtsDialog *dialog);
|
||||
|
||||
protected:
|
||||
void go(const QString &scriptId) noexcept(false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ExportedScriptsDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExportedScriptsDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr) noexcept(false);
|
||||
~ExportedScriptsDialog();
|
||||
|
||||
void retranslate() override;
|
||||
static QUrl forgeUrl(const QString &path, const QString &protocol = L("http"));
|
||||
static QNetworkRequest forgeRequest(const QString &path, const QUrlQuery &q, const QString &contentType = QString());
|
||||
|
||||
private slots:
|
||||
void uploadScript();
|
||||
void downloadScript();
|
||||
void removeScriptFromServer();
|
||||
void removeScriptLocal();
|
||||
void openScript();
|
||||
void onSelectionChanged();
|
||||
void _onSelectionChanged();
|
||||
|
||||
private:
|
||||
enum class WsConnectionStatus
|
||||
{
|
||||
NotConnected,
|
||||
Connecting,
|
||||
Disconnected,
|
||||
Error,
|
||||
Connected,
|
||||
};
|
||||
|
||||
void initModel() noexcept(false);
|
||||
void setWsConnectionStatus(WsConnectionStatus status);
|
||||
void setWsConnectionStatusLabel();
|
||||
bool isOCApp() const;
|
||||
|
||||
private:
|
||||
ExportedScriptsModel *m_model;
|
||||
Ui::ExportedScriptsDialog2 *m_ui;
|
||||
LtsSession::LtsSession *m_session;
|
||||
QString m_lastServerContent;
|
||||
WsConnectionStatus m_wsStatus { WsConnectionStatus::NotConnected };
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExportedScriptsDialog2</class>
|
||||
<widget class="QWidget" name="ExportedScriptsDialog2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>834</width>
|
||||
<height>491</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>The following Scripts are already exported. You can remove them from your local hard disk or upload them to the server here.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Server connection status:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblWsStatus">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="ltsDataView" native="true">
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
|
||||
#include "tpm2_gui_plugin.h"
|
||||
#include "tpm2_exported_scripts_dialog.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Tpm"))
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Presentation");
|
||||
}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
if (m_session->app() == LtsAppDescriptor::App::Scripts)
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
else
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eAfterAction;
|
||||
plData.identifier = QLatin1String("PresentationManagement.ScriptDialog.ManageExportedScripts");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:export_documents.svg"));
|
||||
plData.menuText = tr("Manage Exported Scripts");
|
||||
|
||||
plData.createWidgetFunc = [this](QWidget *)
|
||||
{
|
||||
return LtsWidgets::createThrowableDialog<ExportedScriptsDialog>(m_session, nullptr);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <THP2/tpm2_gui_plugin_interface.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:tpm2.man")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("TakeHomePackageManager2"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Exercise;
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface, public ForeignTpm2GuiInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
QString menuGroup() const override;
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Exercise; }
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user