Browse Source

Merge branch 'legacy-restructure' of LotRO_Legacy/Legacy_v2 into master

Ivan Arkhipov 5 years ago
parent
commit
149dc8099d
43 changed files with 1144 additions and 776 deletions
  1. 2 2
      build_res.pri
  2. 4 8
      src/Legacy-advanced/Legacy-advanced.pro
  3. 1 1
      src/Legacy-advanced/Legacy-advanced_resource.rc
  4. 0 2
      src/Legacy-advanced/object_script.Legacy-advanced.Release
  5. 39 38
      src/Legacy/Legacy.pro
  6. 1 1
      src/Legacy/Legacy_resource.rc
  7. 0 26
      src/Legacy/build_res.pri
  8. 0 15
      src/Legacy/gui/helpwidget.cpp
  9. 0 166
      src/Legacy/gui/settingswidget.cpp
  10. 44 0
      src/Legacy/main.cpp
  11. 14 14
      src/Legacy/models/downloader.cpp
  12. 3 3
      src/Legacy/models/downloader.h
  13. 0 0
      src/Legacy/models/filesystem.cpp
  14. 0 0
      src/Legacy/models/filesystem.h
  15. 507 0
      src/Legacy/models/lotromanager.cpp
  16. 77 0
      src/Legacy/models/lotromanager.h
  17. 13 13
      src/Legacy/object_script.Legacy.Debug
  18. 13 13
      src/Legacy/object_script.Legacy.Release
  19. 0 47
      src/Legacy/src/legacyapp.cpp
  20. 0 47
      src/Legacy/src/legacyapp.h
  21. 0 22
      src/Legacy/src/main.cpp
  22. 14 0
      src/Legacy/widgets/helpwidget.cpp
  23. 1 4
      src/Legacy/widgets/helpwidget.h
  24. 0 0
      src/Legacy/widgets/helpwidget.ui
  25. 65 62
      src/Legacy/widgets/mainwindow.cpp
  26. 16 22
      src/Legacy/widgets/mainwindow.h
  27. 6 9
      src/Legacy/widgets/mainwindow.ui
  28. 0 0
      src/Legacy/widgets/menuentry.cpp
  29. 0 0
      src/Legacy/widgets/menuentry.h
  30. 8 9
      src/Legacy/widgets/newswidget.cpp
  31. 3 6
      src/Legacy/widgets/newswidget.h
  32. 0 0
      src/Legacy/widgets/newswidget.ui
  33. 0 0
      src/Legacy/widgets/rusificationtreeitem.cpp
  34. 0 0
      src/Legacy/widgets/rusificationtreeitem.h
  35. 4 6
      src/Legacy/widgets/rusificationwidget.cpp
  36. 1 4
      src/Legacy/widgets/rusificationwidget.h
  37. 0 0
      src/Legacy/widgets/rusificationwidget.ui
  38. 163 0
      src/Legacy/widgets/settingswidget.cpp
  39. 1 4
      src/Legacy/widgets/settingswidget.h
  40. 0 0
      src/Legacy/widgets/settingswidget.ui
  41. 2 3
      src/Legacy/widgets/statuswidget.cpp
  42. 1 4
      src/Legacy/widgets/statuswidget.h
  43. 141 225
      src/Legacy/widgets/statuswidget.ui

+ 2 - 2
src/Legacy-advanced/build_res.pri → build_res.pri

@@ -9,8 +9,8 @@ exists($$BIN_PATH/res) {
 }
 
 EXT_RES =                                                                   \
-    "$$PWD/resources/backgrounds.qrc            -o $$BIN_PATH/data01.gtr"     \
-    "$$PWD/resources/common.qrc                 -o $$BIN_PATH/data02.gtr"     \
+    "$${PROJECT_ROOT_PATH}/resources/backgrounds.qrc            -o $$BIN_PATH/data01.gtr"     \
+    "$${PROJECT_ROOT_PATH}/resources/common.qrc                 -o $$BIN_PATH/data02.gtr"     \
 
 for (RES, EXT_RES) {
     win32 {

+ 4 - 8
src/Legacy-advanced/Legacy-advanced.pro

@@ -61,11 +61,7 @@ FORMS += \
     widgets\messagedialog.ui \
     widgets\lotroprogresswidget.ui
 
-RESOURCES += \
-    resources\backgrounds.qrc \
-    resources\common.qrc
-
-win32:RC_ICONS = $$PWD/resources/appicon.ico
+win32:RC_ICONS = $${PROJECT_ROOT_PATH}/resources/appicon.ico
 
 INCLUDEPATH += $$PWD/src
 INCLUDEPATH += $$PWD/widgets
@@ -77,8 +73,8 @@ LIBS += -llibzlibstatic
 
 CONFIG(debug, debug|release) {
         RESOURCES += \
-                resources/backgrounds.qrc \
-                resources/common.qrc
+                $${PROJECT_ROOT_PATH}/resources/backgrounds.qrc \
+                $${PROJECT_ROOT_PATH}/resources/common.qrc
 } else {
-        include(build_res.pri)
+        include(../../build_res.pri)
 }

+ 1 - 1
src/Legacy-advanced/Legacy-advanced_resource.rc

@@ -1,6 +1,6 @@
 #include <windows.h>
 
-IDI_ICON1	ICON	DISCARDABLE	"D:\\Programming\\SourceRepos\\Legacy_v2\\src\\Legacy-advanced\\resources\\appicon.ico"
+IDI_ICON1	ICON	DISCARDABLE	"D:\\Programming\\SourceRepos\\Legacy_v2\\resources\\appicon.ico"
 
 VS_VERSION_INFO VERSIONINFO
 	FILEVERSION 0,0,0,0

+ 0 - 2
src/Legacy-advanced/object_script.Legacy-advanced.Release

@@ -1,6 +1,4 @@
 INPUT(
-./..\..\build\release\Legacy-advanced\rcc\qrc_backgrounds.o
-./..\..\build\release\Legacy-advanced\rcc\qrc_common.o
 ./..\..\build\release\Legacy-advanced\obj\main.o
 ./..\..\build\release\Legacy-advanced\obj\downloader.o
 ./..\..\build\release\Legacy-advanced\obj\filesystem.o

+ 39 - 38
src/Legacy/Legacy.pro

@@ -14,49 +14,41 @@ CXXFLAGS += -O2 -fno-stack-limit
 CONFIG += resources_big
 
 SOURCES += \
-    src/main.cpp \
-    gui/mainwindow.cpp \
-    src/menuentry.cpp \
-    src/legacyapp.cpp \
-    src/filesystem.cpp \
-    gui/statuswidget.cpp \
-    gui/rusificationwidget.cpp \
-    gui/settingswidget.cpp \
-    gui/newswidget.cpp \
-    gui/helpwidget.cpp \
-    src/networkdownloader.cpp \
-    src/rusificationtreeitem.cpp
+    main.cpp \
+    models/downloader.cpp \
+    models/filesystem.cpp \
+    models/lotromanager.cpp \
+    widgets/helpwidget.cpp \
+    widgets/mainwindow.cpp \
+    widgets/menuentry.cpp \
+    widgets/newswidget.cpp \
+    widgets/rusificationtreeitem.cpp \
+    widgets/rusificationwidget.cpp \
+    widgets/settingswidget.cpp \
+    widgets/statuswidget.cpp
 
 HEADERS += \
-    gui/mainwindow.h \
-    src/menuentry.h \
-    src/legacyapp.h \
-    src/filesystem.h \
-    gui/statuswidget.h \
-    gui/rusificationwidget.h \
-    gui/settingswidget.h \
-    gui/newswidget.h \
-    gui/helpwidget.h \
-    src/networkdownloader.h \
-    src/rusificationtreeitem.h
+    models/downloader.h \
+    models/filesystem.h \
+    models/lotromanager.h \
+    widgets/helpwidget.h \
+    widgets/mainwindow.h \
+    widgets/menuentry.h \
+    widgets/newswidget.h \
+    widgets/rusificationtreeitem.h \
+    widgets/rusificationwidget.h \
+    widgets/settingswidget.h \
+    widgets/statuswidget.h
 
 FORMS += \
-    gui/mainwindow.ui \
-    gui/statuswidget.ui \
-    gui/rusificationwidget.ui \
-    gui/settingswidget.ui \
-    gui/newswidget.ui \
-    gui/helpwidget.ui
+    widgets/helpwidget.ui \
+    widgets/mainwindow.ui \
+    widgets/newswidget.ui \
+    widgets/rusificationwidget.ui \
+    widgets/settingswidget.ui \
+    widgets/statuswidget.ui
 
-CONFIG(debug, debug|release) {
-	RESOURCES += \
-                resources/backgrounds.qrc \
-                resources/common.qrc
-} else {
-	include(build_res.pri)
-}
-
-win32:RC_ICONS = $$PWD/resources/appicon.ico
+win32:RC_ICONS = $${PROJECT_ROOT_PATH}/resources/appicon.ico
 
 INCLUDEPATH += $$PWD/src
 INCLUDEPATH += $$PWD/gui
@@ -64,3 +56,12 @@ INCLUDEPATH += $$PWD/gui
 LIBS += -llibLotroDat_static
 LIBS += -llibyaml-cpp
 LIBS += -llibzlibstatic
+
+
+CONFIG(debug, debug|release) {
+        RESOURCES += \
+                $${PROJECT_ROOT_PATH}/resources/backgrounds.qrc \
+                $${PROJECT_ROOT_PATH}/resources/common.qrc
+} else {
+        include(../../build_res.pri)
+}

+ 1 - 1
src/Legacy/Legacy_resource.rc

@@ -1,6 +1,6 @@
 #include <windows.h>
 
-IDI_ICON1	ICON	DISCARDABLE	"D:\\Programming\\SourceRepos\\Legacy_v2\\src\\Legacy\\resources\\appicon.ico"
+IDI_ICON1	ICON	DISCARDABLE	"D:\\Programming\\SourceRepos\\Legacy_v2\\resources\\appicon.ico"
 
 VS_VERSION_INFO VERSIONINFO
 	FILEVERSION 0,0,0,0

+ 0 - 26
src/Legacy/build_res.pri

@@ -1,26 +0,0 @@
-message(==========BUILDING EXTERNAL RES============)
-
-guiRes.target = BuildResources
-exists($$BIN_PATH/res) {
-    message("Directory $$BIN_PATH/res already exists")
-} else {
-    message("Directory $$BIN_PATH/res DOES NOT exist")
-    guiRes.commands += $(MKDIR) \"$$BIN_PATH/res\" $$escape_expand(\n\t)
-}
-
-EXT_RES =                                                                   \
-    "$$PWD/resources/backgrounds.qrc            -o $$BIN_PATH/data01.gtr"     \
-    "$$PWD/resources/common.qrc                 -o $$BIN_PATH/data02.gtr"     \
-
-for (RES, EXT_RES) {
-    win32 {
-        message(rcc.exe -binary $${RES})
-        guiRes.commands += rcc.exe -binary $${RES} $$escape_expand(\n\t)
-    }
-    unix {
-        guiRes.commands += rcc -binary $${RES} $$escape_expand(\n\t)
-    }
-}
-
-QMAKE_EXTRA_TARGETS += guiRes
-PRE_TARGETDEPS += BuildResources

+ 0 - 15
src/Legacy/gui/helpwidget.cpp

@@ -1,15 +0,0 @@
-#include "gui\helpwidget.h"
-#include "ui_helpwidget.h"
-
-HelpWidget::HelpWidget(LegacyApp *_app, QWidget *parent) :
-    QWidget(parent),
-    ui(new Ui::HelpWidget),
-    app(_app)
-{
-    ui->setupUi(this);
-}
-
-HelpWidget::~HelpWidget()
-{
-    delete ui;
-}

+ 0 - 166
src/Legacy/gui/settingswidget.cpp

@@ -1,166 +0,0 @@
-#include "gui\settingswidget.h"
-#include "ui_settingswidget.h"
-#include "legacyapp.h"
-#include "filesystem.h"
-
-#include <QDebug>
-#include <QFileDialog>
-#include <QMessageBox>
-
-
-SettingsWidget::SettingsWidget(LegacyApp *_app, QWidget *parent) :
-    QWidget(parent),
-    ui(new Ui::SettingsWidget),
-    app(_app)
-{
-    ui->setupUi(this);
-
-    ui_update_timer.setInterval(500);
-    connect(&ui_update_timer, &QTimer::timeout, this, &SettingsWidget::updateUI);
-    ui_update_timer.start();
-}
-
-SettingsWidget::~SettingsWidget()
-{
-    ui_update_timer.stop();
-    delete ui;
-}
-
-void SettingsWidget::updateUI()
-{
-    if (!qApp)
-        return;
-
-    QString path = app->properties.value("settings/lotro_folder", "(не выбрана)").toString();
-    ui->folder_value_common->setText(path);
-
-    ui->data_protection_checkbox_common->setChecked(app->properties.value("settings/data_protection", 1).toBool());
-    ui->restore_checkbox_common->setChecked(app->properties.value("settings/auto_restore", 1).toBool());
-    ui->download_updates_checkbox_common->setChecked(app->properties.value("settings/download_updates", 1).toBool());
-    ui->expert_tabs_checkbox_common->setChecked(app->properties.value("settings/expert_mode", 0).toBool());
-    ui->restrict_download_speed_checkbox_common->setChecked(app->properties.value("settings/limit_download_speed", 0).toBool());
-    ui->download_restrict_slider->setValue(app->properties.value("settings/download_speed", 64).toInt());
-
-    if (app->properties.value("settings/expert_mode", 0).toBool()) {
-        ui->management_widget->show();
-        ui->data_protection_checkbox_common->show();
-        ui->restore_checkbox_common->show();
-    } else {
-        ui->management_widget->hide();
-        ui->data_protection_checkbox_common->hide();
-        ui->restore_checkbox_common->hide();
-    }
-
-    int locale_index = 0;
-    QString value = app->properties.value("settings/locale", "English").toString();
-
-    if (value == "English")
-        locale_index = 0;
-    if (value == "DE")
-        locale_index = 1;
-    if (value == "FR")
-        locale_index = 2;
-
-    ui->lotro_patch_language_combobox_common->setCurrentIndex(locale_index);
-}
-
-void SettingsWidget::on_download_restrict_slider_valueChanged(int value)
-{
-    if (value >= 1024) {
-        double new_value = double(value) / 1024;
-        ui->download_speed_label_common->setText(QString::number(new_value, 'g', 2) + " Мб/с");
-    } else {
-        ui->download_speed_label_common->setText(QString::number(value) + " Кб/с");
-    }
-    app->properties.setValue("settings/download_speed", value);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_interface_scale_combobox_common_currentIndexChanged(const QString &arg1)
-{
-    int value = arg1.left(arg1.length() - 1).toInt();
-    app->window.changeFontSizeRecursive(value, &app->window);
-    app->window.resize(900 * value / 100, 650 * value / 100);
-    app->properties.setValue("settings/ui_scale", value);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_change_folder_button_clicked()
-{
-    QStringList known_paths = FileSystem::recognizeRegistryLotroPath();
-    QString template_path = known_paths.size() > 0 ? known_paths[0] : "";
-    QString str = QFileDialog::getOpenFileName(0, "Расположение игры", template_path, "LotroLauncher.exe");
-    QString path = str.replace("/LotroLauncher.exe", "").replace("\\", "/").replace("//", "/");
-
-    if (!FileSystem::fileExists(path + "/LotroLauncher.exe")) {
-        QMessageBox error_box("Ошибка!", "Похоже, указана неверная папка с игрой. Не могу найти файл LotroLauncher.exe",
-                              QMessageBox::Critical, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
-
-        return;
-    }
-
-    if (!FileSystem::fileExists(path + "/client_local_English.dat")) {
-        QMessageBox pmbx("Файл данных не найден",
-                         "Файл данных client_local_English.dat не обнаружен в папке с игрой. Запустить лаунчер игры с целью скачать недостающие данные?",
-                         QMessageBox::Warning,
-                         QMessageBox::Yes,
-                         QMessageBox::No,
-                         QMessageBox::NoButton);
-
-        if (pmbx.exec() == QMessageBox::Yes) {
-            // Start LotRO;
-            return;
-        } else {
-            // Set status Файл данных не найден
-        }
-    }
-
-    app->properties.setValue("settings/lotro_folder", path);
-    app->properties.sync();
-    ui->folder_value_common->setText(path);
-}
-
-void SettingsWidget::on_data_protection_checkbox_common_stateChanged(int arg1)
-{
-    app->properties.setValue("settings/data_protection", arg1);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_restore_checkbox_common_stateChanged(int arg1)
-{
-    app->properties.setValue("settings/auto_restore", arg1);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_download_updates_checkbox_common_stateChanged(int arg1)
-{
-    app->properties.setValue("settings/download_updates", arg1);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_expert_tabs_checkbox_common_stateChanged(int arg1)
-{
-    app->properties.setValue("settings/expert_mode", arg1);
-    app->properties.sync();
-}
-
-void SettingsWidget::on_restrict_download_speed_checkbox_common_stateChanged(int arg1)
-{
-    app->properties.setValue("settings/limit_download_speed", arg1);
-    app->properties.sync();
-}
-
-
-void SettingsWidget::on_lotro_patch_language_combobox_common_activated(int index)
-{
-    QString value = "";
-    if (index == 0)
-        value = "English";
-    if (index == 1)
-        value = "DE";
-    if (index == 2)
-        value = "FR";
-
-    app->properties.setValue("settings/locale", value);
-    app->properties.sync();
-}

+ 44 - 0
src/Legacy/main.cpp

@@ -0,0 +1,44 @@
+#include <QApplication>
+#include <QMessageBox>
+#include <QLockFile>
+#include <QDir>
+
+#include "widgets/mainwindow.h"
+
+#include <QTextCodec>
+#include <QDebug>
+#include <QResource>
+#include <QFontDatabase>
+
+int main(int argc, char *argv[])
+{
+    setlocale(LC_ALL,"Russian");
+    QApplication a(argc, argv);
+
+    qDebug() << "Checking if there's another instance of Legacy";
+
+    QLockFile lockFile(QDir::temp().absoluteFilePath("rulotro.lock"));
+    if(!lockFile.tryLock(1)){
+        QMessageBox msgBox;
+        msgBox.setIcon(QMessageBox::Warning);
+        msgBox.setText("Приложение уже запущено.\nРазрешено запускать только один экземпляр приложения.");
+        msgBox.exec();
+        return 1;
+    }
+
+    qDebug() << "Registering resources";
+    QResource::registerResource(QApplication::applicationDirPath() + "/data01.gtr");
+    QResource::registerResource(QApplication::applicationDirPath() + "/data02.gtr");
+
+    QFontDatabase::addApplicationFont(":/assets/fonts/trajan.ttf");
+    QFontDatabase::addApplicationFont(":/assets/fonts/viking.ttf");
+    QFontDatabase::addApplicationFont(":/assets/fonts/title.ttf");
+
+    qDebug() << "Starting main frame initialisation...";
+
+    MainWindow* main_window = new MainWindow(nullptr);
+    main_window->setAttribute(Qt::WA_DeleteOnClose);
+
+    qDebug() << "Finished initialisation, starting application...";
+    return a.exec();
+}

+ 14 - 14
src/Legacy/src/networkdownloader.cpp → src/Legacy/models/downloader.cpp

@@ -1,34 +1,34 @@
-#include "networkdownloader.h"
+#include "downloader.h"
 #include <QEventLoop>
 #include <QApplication>
 #include <QDebug>
 
-NetworkDownloader::NetworkDownloader(QObject *parent) :QObject(parent), busy(false)
+Downloader::Downloader(QObject *parent) :QObject(parent), busy(false)
 {
     connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(onDownloadFinished(QNetworkReply*)));
 }
 
-NetworkDownloader::~NetworkDownloader() {
+Downloader::~Downloader() {
 }
 
-QUrl NetworkDownloader::getUrl()
+QUrl Downloader::getUrl()
 {
     return url;
 }
 
-void NetworkDownloader::setUrl(const QUrl &_url)
+void Downloader::setUrl(const QUrl &_url)
 {
     url = _url;
 }
 
-void NetworkDownloader::waitForDownloaded()
+void Downloader::waitForDownloaded()
 {
     QEventLoop loop;
-    connect(this, &NetworkDownloader::downloadFinished, &loop, &QEventLoop::quit);
+    connect(this, &Downloader::downloadFinished, &loop, &QEventLoop::quit);
     loop.exec();
 }
 
-void NetworkDownloader::start()
+void Downloader::start()
 {
     if (busy) {
         qDebug() << "Cannot download " << url << ", downloader is busy!";
@@ -40,24 +40,24 @@ void NetworkDownloader::start()
     QNetworkRequest request(url);
     m_CurrentReply = m_WebCtrl.get(request);
     m_CurrentReply->setReadBufferSize(download_speed_limit);
-    connect(m_CurrentReply, &QNetworkReply::readyRead, this, &NetworkDownloader::onReadyRead);
-    connect(m_CurrentReply, &QNetworkReply::downloadProgress, this, &NetworkDownloader::progressChanged);
+    connect(m_CurrentReply, &QNetworkReply::readyRead, this, &Downloader::onReadyRead);
+    connect(m_CurrentReply, &QNetworkReply::downloadProgress, this, &Downloader::progressChanged);
 }
 
-void NetworkDownloader::updateDownloadSpeedLimit(int bytes_per_sec)
+void Downloader::updateDownloadSpeedLimit(int bytes_per_sec)
 {
     download_speed_limit = bytes_per_sec;
     if (m_CurrentReply)
         m_CurrentReply->setReadBufferSize(bytes_per_sec);
 }
 
-void NetworkDownloader::stop()
+void Downloader::stop()
 {
     m_CurrentReply->abort();
     busy = false;
 }
 
-void NetworkDownloader::onDownloadFinished(QNetworkReply*) {
+void Downloader::onDownloadFinished(QNetworkReply*) {
     if (m_CurrentReply)
         m_CurrentReply->deleteLater();
 
@@ -65,7 +65,7 @@ void NetworkDownloader::onDownloadFinished(QNetworkReply*) {
     emit downloadFinished();
 }
 
-void NetworkDownloader::onReadyRead()
+void Downloader::onReadyRead()
 {
     QByteArray readdata = m_CurrentReply->readAll();
     if (targetFile && targetFile->isWritable())

+ 3 - 3
src/Legacy/src/networkdownloader.h → src/Legacy/models/downloader.h

@@ -8,13 +8,13 @@
 #include <QFile>
 #include <QByteArray>
 
-class NetworkDownloader : public QObject
+class Downloader : public QObject
 {
     Q_OBJECT
 
 public:
-    explicit NetworkDownloader(QObject *parent = 0);
-    virtual ~NetworkDownloader();
+    explicit Downloader(QObject *parent = 0);
+    virtual ~Downloader();
 
     QUrl getUrl();
     void setUrl(const QUrl& _url);

+ 0 - 0
src/Legacy/src/filesystem.cpp → src/Legacy/models/filesystem.cpp


+ 0 - 0
src/Legacy/src/filesystem.h → src/Legacy/models/filesystem.h


+ 507 - 0
src/Legacy/models/lotromanager.cpp

@@ -0,0 +1,507 @@
+#include "lotromanager.h"
+#include "filesystem.h"
+#include "LotroDat/Subfiles/TextSubFile.h"
+
+#include <QtConcurrent/QtConcurrent>
+#include <QFontDatabase>
+#include <QMessageBox>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+
+Q_DECLARE_METATYPE(LOTRO_DAT::FILE_TYPE)
+Q_DECLARE_METATYPE(LOTRO_DAT::SubfileData)
+
+LotroManager::LotroManager(QSettings* app_settings_, QObject *parent) :
+    QObject(parent), app_settings(app_settings_) {
+
+    qRegisterMetaType<LOTRO_DAT::FILE_TYPE>();
+    qRegisterMetaType<LOTRO_DAT::SubfileData>();
+}
+
+void LotroManager::initialiseDatFile(QString file_path) {
+    emit processStarted("initialiseDatFile", {file_path});
+
+    qDebug() << "Initialising file " << file_path;
+
+    if (!FileSystem::fileExists(file_path)) {
+        emit caughtError(QString("initialiseDatFile"), {QString("Ошибка инициализации"), QString("Файл " + file_path + " несуществует! Невозможно инициализировать файл ресурсов.")});
+        emit processFinished("initialiseDatFile", {QString("Error"), file_path});
+        return;
+    }
+
+    file.Initialise((file_path).toStdString(), 0);
+    emit processFinished("initialiseDatFile", {QString("Success"), file_path});
+}
+
+void LotroManager::deinitialiseDatFile()
+{
+    emit processStarted("deintialiseDatFile", {});
+    qDebug() << "Deinitialising file...";
+    file.Deinitialize();
+    emit processFinished("deinitialiseDatFile", {});
+}
+
+void LotroManager::changeLocale() {
+    qDebug() << "Changing locale of dat file...";
+    // Setting locale, opposite to current
+    auto current_locale = file.GetLocaleManager().GetCurrentLocale();
+    auto new_locale = current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ?
+                LOTRO_DAT::DatLocaleManager::ORIGINAL :
+                LOTRO_DAT::DatLocaleManager::PATCHED;
+
+    QString old_locale_name = (current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
+    QString new_locale_name = (new_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
+    emit processStarted("changeLocale", {old_locale_name, new_locale_name});
+
+
+    auto operation = file.GetLocaleManager().SetLocale(new_locale);
+
+    auto new_current_locale = file.GetLocaleManager().GetCurrentLocale();
+    QString new_current_locale_name = (new_current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
+
+    if (operation.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("changeLocale", {"Success", new_current_locale_name});
+    } else {
+        emit caughtError("changeLocale", {"Ошибка смены локали!", QString("Не удалось сменить локаль игры! Текущая локаль: ") + new_current_locale_name});
+        emit processFinished("changeLocale", {"Error", new_current_locale_name});
+    }
+}
+
+void LotroManager::getLocaleFileContents(long long file_id, int locale) {
+    emit processStarted("getLocaleFileContents", {file_id, locale});
+
+    auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);
+    if (!getfile_op.result) {
+        emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
+        emit processFinished("getLocaleFileContents", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubFile subfile = getfile_op.value;
+
+    auto getrealfile_op = file.GetFileSystem().GetFile(file_id);
+    if (!getfile_op.result) {
+        emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти в словаре файл с id ") + QString::number(file_id)});
+        emit processFinished("getLocaleFileContents", {"Error"});
+        return;
+    }
+
+    if (getrealfile_op.value->FileType() != LOTRO_DAT::TEXT) {
+        emit caughtError("getLocaleFileContents", {"Некорректный формат!", QString("Получение данных локали доступно только для текстовых файлов!")});
+        emit processFinished("getLocaleFileContents", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::TextSubFile text_subfile(subfile);
+
+    auto getfiledata_op = file.GetFileSystem().GetFileData(subfile, 8);
+
+    if (getfile_op.result == LOTRO_DAT::ERROR) {
+        emit caughtError("getLocaleFileContents", {"Ошибка извлечения!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id) + ", locale_id = " + QString::number(locale)});
+        emit processFinished("getLocaleFileContents", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubfileData result = text_subfile.PrepareForExport(getfiledata_op.value);
+    emit localeFileContentsReceived(locale, result);
+    emit processFinished("getLocaleFileContents", {"Success", file_id, locale});
+}
+
+void LotroManager::importFilesFromDatabase(QString database_path) {
+    emit processStarted("importFilesFromDatabase", {database_path});
+
+    if (!FileSystem::fileExists(database_path)) {
+        emit caughtError(QString("importFilesFromDatabase"), {QString("Ошибка импорта!"), QString("Файл " + database_path + " не существует! Невозможно инициализировать базу данных!")});
+        emit processFinished("importFilesFromDatabase", {QString("Error")});
+        return;
+    }
+
+    LOTRO_DAT::Database db;
+    if (!db.InitDatabase(database_path.toStdString())) {
+        emit caughtError("importFilesFromDatabase", {QString("Ошибка импорта!"), QString("Внутренняя ошибка инициализации базы данных!")});
+        emit processFinished("importFilesFromDatabase", {QString("Error")});
+        return;
+    }
+
+    auto patch_operation = file.GetPatcher().PatchAllDatabase(&db);
+
+    if (patch_operation.result == LOTRO_DAT::SUCCESS) {
+        file.GetFileSystem().CommitDirectories();
+        file.GetLocaleManager().CommitLocales();
+        emit processFinished("importFilesFromDatabase", {QString("Success"), patch_operation.value});
+    } else {
+        emit processFinished("importFilesFromDatabase", {QString("Error"), 0});
+    }
+}
+
+void LotroManager::importFile(long long file_id, QString file_path) {
+    emit processStarted("importFile", {file_id, file_path});
+
+    if (!FileSystem::fileExists(file_path)) {
+        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не существует!")});
+        emit processFinished("importFile", {QString("Error")});
+        return;
+    }
+
+    LOTRO_DAT::SubfileData data;
+
+    data.options["fid"] = file_id;
+
+    auto getfile_op = file.GetFileSystem().GetFile(file_id);
+    if (getfile_op.result == LOTRO_DAT::ERROR) {
+        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл с id ") + QString::number(file_id) + QString(" не существует в ресурсах игры! Невозможно импортировать :/")});
+        emit processFinished("importFile", {QString("Error")});
+        return;
+    }
+
+    LOTRO_DAT::SubFile subfile = *(getfile_op.value);
+    data.options["ext"] = subfile.Extension();
+    data.options["cat"] = subfile.category;
+
+    if (subfile.FileType() == LOTRO_DAT::TEXT) {
+        std::basic_ifstream<char16_t> input_stream(file_path.toStdString(), std::ios::in);
+        if (!input_stream.is_open()) {
+            emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Текстовый файл ") + file_path + QString(" не удаётся открыть!")});
+            emit processFinished("importFile", {QString("Error")});
+            return;
+        }
+
+        std::basic_stringstream<char16_t>  strStream;
+        strStream << input_stream.rdbuf();//read the file
+        data.text_data = strStream.str();//str holds the content of the file
+
+        input_stream.close();
+    } else {
+        QFile data_file(file_path);
+        data_file.open(QIODevice::ReadOnly);
+
+        if (!data_file.isOpen()) {
+            emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не удаётся открыть!")});
+            emit processFinished("importFile", {QString("Error")});
+            return;
+        }
+
+        QByteArray contents = data_file.readAll();
+        data.binary_data = LOTRO_DAT::BinaryData(contents.constData(), contents.size());
+    }
+
+
+    auto patchfile_op = file.GetPatcher().PatchFile(data);
+
+    if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
+        file.GetFileSystem().CommitDirectories();
+        file.GetLocaleManager().CommitLocales();
+        emit processFinished("importFile", {QString("Success")});
+    } else {
+        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
+        emit processFinished("importFile", {QString("Error")});
+    }
+    return;
+}
+
+void LotroManager::importTextFragment(long long file_id, long long fragment_id,
+                               QString fragment_contents, QString arguments) {
+    emit processStarted("importTextFragment", {file_id, fragment_id});
+
+    if (fragment_contents.contains("DO_NOT_TOUCH-1!")) {
+        emit caughtError("importTextFragment", {"Ошибка формата!", QString("Текстовые данные содержат указатели на аргументы DO_NOT_TOUCH! с встроенным указанием порядка аргументов (как на сайте) Такого быть не должно! Пользуйтесь порядком перечисления аргументов внизу")});
+        emit processFinished("importTextFragment", {"Error"});
+        return;
+    }
+
+    auto getfile_op = file.GetFileSystem().GetFile(file_id);
+    if (!getfile_op.result) {
+        emit caughtError("importTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
+        emit processFinished("importTextFragment", {"Error"});
+        return;
+    }
+
+    auto subfile = getfile_op.value;
+
+    auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);
+
+    if (getfile_op.result == LOTRO_DAT::ERROR) {
+        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
+        emit processFinished("importTextFragment", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
+    if (data.Empty()) {
+        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
+        emit processFinished("importTextFragment", {"Error"});
+        return;
+    }
+
+    unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
+    if (beginning == std::u16string::npos) {
+        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
+        emit processFinished("importTextFragment", {"Error"});
+        return;
+    }
+
+    unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);
+
+    QString new_fragment = QString::number(fragment_id) + ":::" + arguments + ":::" + fragment_contents;
+    std::u16string new_text =  data.text_data.substr(0, beginning) + new_fragment.toStdU16String() + data.text_data.substr(ending);
+    data.text_data = new_text;
+
+    auto patchfile_op = file.GetPatcher().PatchFile(data);
+
+    if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
+        file.GetFileSystem().CommitDirectories();
+        file.GetLocaleManager().CommitLocales();
+        emit processFinished("importTextFragment", {QString("Success")});
+    } else {
+        emit caughtError("importTextFragment", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
+        emit processFinished("importTextFragment", {QString("Error")});
+    }
+}
+
+void LotroManager::getTextFragment(long long file_id, long long fragment_id) {
+    emit processStarted("getTextFragment", {file_id, fragment_id});
+
+    auto getfile_op = file.GetFileSystem().GetFile(file_id);
+    if (!getfile_op.result) {
+        emit caughtError("getTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
+        emit processFinished("getTextFragment", {"Error"});
+        return;
+    }
+
+    auto subfile = getfile_op.value;
+
+    auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);
+
+    if (getfile_op.result == LOTRO_DAT::ERROR) {
+        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
+        emit processFinished("getTextFragment", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
+    if (data.Empty()) {
+        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
+        emit processFinished("getTextFragment", {"Error"});
+        return;
+    }
+
+    unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
+    if (beginning == std::u16string::npos) {
+        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
+        emit processFinished("getTextFragment", {"Error"});
+        return;
+    }
+
+    unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);
+
+    unsigned size = std::u16string::npos;
+
+    if (ending != std::u16string::npos)
+        size = ending - beginning;
+
+    std::u16string str = data.text_data.substr(beginning, size);
+
+    QStringList splitted_fragment = QString::fromStdU16String(str).split(":::");
+    if (splitted_fragment.size() != 3) {
+        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Получены некорректные данные фрагмента!\nДанные:") + QString::fromStdU16String(str)});
+        emit processFinished("getTextFragment", {"Error"});
+        return;
+    }
+
+    emit textFragmentReceived(splitted_fragment.at(1), splitted_fragment.at(2));
+    emit processFinished("getTextFragment", {"Success"});
+}
+
+void LotroManager::createCoreStatusFile(QString output_filename) {
+    emit processStarted("createCoreStatusFile", {output_filename});
+    auto gatherinfo_op = file.GatherInformation(output_filename.toStdString());
+
+    if (gatherinfo_op.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("createCoreStatusFile", {"Success", output_filename});
+    } else {
+        emit caughtError("createCoreStatusFile", {"Ошибка сбора информации!", QString("Не удаётся создать файл информации ядра")});
+        emit processFinished("createCoreStatusFile", {"Error", output_filename});
+    }
+}
+
+void LotroManager::extractSingleFile(QString output_filename, long long file_id) {
+    emit processStarted("extractSingleFile", {output_filename, file_id});
+    auto extractfile_op = file.GetExporter().ExtractFileById(file_id, output_filename.toStdString());
+    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("extractSingleFile", {"Success", output_filename, file_id});
+    } else {
+        emit caughtError("extractSingleFile", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в файл " + output_filename)});
+        emit processFinished("extractSingleFile", {"Error", output_filename});
+    }
+}
+
+void LotroManager::extractSingleFileToDatabase(QString database_path, long long file_id) {
+    emit processStarted("extractSingleFileToDatabase", {database_path, file_id});
+    LOTRO_DAT::Database db;
+    if (!db.InitDatabase(database_path.toStdString())) {
+        emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
+        emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
+        return;
+    }
+
+    auto extractfile_op = file.GetExporter().ExtractFileById(file_id, &db);
+
+    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("extractSingleFileToDatabase", {"Success", database_path, file_id});
+    } else {
+        emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в базу данных " + database_path)});
+        emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
+    }
+}
+
+void LotroManager::extractGrouppedFiles(QString output_foldername, LOTRO_DAT::FILE_TYPE type) {
+    emit processStarted("extractGrouppedFiles", {output_foldername, type});
+    auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, output_foldername.toStdString());
+    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("extractGrouppedFiles", {"Success", output_foldername, type, extractfile_op.value});
+    } else {
+        emit caughtError("extractGrouppedFiles", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в папку " + output_foldername)});
+        emit processFinished("extractGrouppedFiles", {"Error", output_foldername, type, extractfile_op.value});
+    }
+}
+
+void LotroManager::extractGrouppedFilesToDatabase(QString database_path, LOTRO_DAT::FILE_TYPE type) {
+    emit processStarted(QString("extractGrouppedFilesToDatabase"), {database_path, type});
+    LOTRO_DAT::Database db;
+    if (!db.InitDatabase(database_path.toStdString())) {
+        emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
+        emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path});
+        return;
+    }
+
+    auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, &db);
+    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
+        emit processFinished("extractGrouppedFilesToDatabase", {"Success", database_path, type, extractfile_op.value});
+    } else {
+        emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в базу данных " + database_path)});
+        emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path, extractfile_op.value});
+    }
+}
+
+void LotroManager::getUnactiveCategories() {
+    emit processStarted("getUnactiveCategories", {});
+
+    const std::set<long long>& categories = file.GetLocaleManager().GetInactiveCategories();
+
+    QStringList result;
+    for (long long category : categories) {
+        result << QString::number(category);
+    }
+
+    emit unactiveCategoriesReceived(result);
+    emit processFinished("getUnactiveCategories", {"Success"});
+}
+
+void LotroManager::startGame() {
+    emit processStarted("startGame", {});
+
+    QStringList args;
+    args << "-skiprawdownload" << "-nosplash";
+    if (file.GetLocaleManager().GetCurrentLocale() == LOTRO_DAT::DatLocaleManager::PATCHED)
+        args << "-disablePatch";
+
+    file.Deinitialize();
+
+    if(FileSystem::fileExists(QApplication::applicationDirPath() + "/user.ini")){
+        QSettings login(QApplication::applicationDirPath() + "/user.ini", QSettings::IniFormat );
+        login.beginGroup("Account");
+        QString username = login.value("username", "").toString();
+        QString password = login.value("password", "").toString();
+        login.endGroup();
+        args << "-username" << username << "-password" << password;
+    }
+
+    qDebug() << "Запускаем игру со следующими аргументами: " << args;
+
+    QFile f(app_settings->value("Local", "folder").toString() + "/LotroLauncher.exe");
+    QProcess process;
+
+    if (FileSystem::fileExists(f.fileName())) {
+        if(f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\"");
+        process.startDetached(f.fileName(), args);
+        process.waitForFinished(-1);
+        emit processFinished("startGame", {});
+    } else {
+        emit caughtError("startGame", {"Ошибка запуска игры!", QString("Не удалось найти файл LotroLauncher в папке: ") + app_settings->value("Local", "folder").toString()});
+        emit processFinished("startGame", {"Error"});
+    }
+}
+
+void LotroManager::getLocaleFileInfo(long long file_id, int locale) {
+    emit processStarted("getLocaleFileInfo", {file_id, locale});
+
+    auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);
+    if (!getfile_op.result) {
+        emit caughtError("getLocaleFileInfo", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
+        emit processFinished("getLocaleFileInfo", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubFile subfile = getfile_op.value;
+
+    QString result = "Locale file info:\n "
+                     "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
+                     "unknown1: " + QString::number(subfile.unknown1()) + "\n"
+                     "file_id: " + QString::number(subfile.file_id()) + "\n"
+                     "file_offset: " + QString::number(subfile.file_offset()) + "\n"
+                     "file_size: " + QString::number(subfile.file_size()) + "\n"
+                     "timestamp: " + QString::number(subfile.timestamp()) + "\n"
+                     "version: " + QString::number(subfile.version()) + "\n"
+                     "block_size: " + QString::number(subfile.block_size()) + "\n"
+                     "unknown2: " + QString::number(subfile.file_id()) + "\n"
+                     "category: " + QString::number(subfile.category) + "\n";
+
+    emit localeFileInfoReceived(locale, result);
+    emit processFinished("getLocaleFileInfo", {"Success"});
+}
+
+void LotroManager::getFileInfo(long long file_id) {
+    emit processStarted(QString("getFileInfo"), {file_id});
+
+    auto getfile_op = file.GetFileSystem().GetFile(file_id);
+    if (!getfile_op.result) {
+        emit caughtError("getFileInfo", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
+        emit processFinished("getFileInfo", {"Error"});
+        return;
+    }
+
+    LOTRO_DAT::SubFile subfile = *getfile_op.value;
+
+    QString result = "Locale file info:\n "
+                     "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
+                     "unknown1: " + QString::number(subfile.unknown1()) + "\n"
+                     "file_id: " + QString::number(subfile.file_id()) + "\n"
+                     "file_offset: " + QString::number(subfile.file_offset()) + "\n"
+                     "file_size: " + QString::number(subfile.file_size()) + "\n"
+                     "timestamp: " + QString::number(subfile.timestamp()) + "\n"
+                     "version: " + QString::number(subfile.version()) + "\n"
+                     "block_size: " + QString::number(subfile.block_size()) + "\n"
+                     "unknown2: " + QString::number(subfile.file_id()) + "\n";
+
+    emit fileInfoReceived(result);
+    emit processFinished("getFileInfo", {"Success"});
+}
+
+LOTRO_DAT::DatStatus *LotroManager::getStatusModule()
+{
+    return &file.GetStatusModule();
+}
+
+bool LotroManager::initialised() {
+    return file.Initialized();
+}
+
+int LotroManager::currentLocale() {
+    return file.GetLocaleManager().GetCurrentLocale();
+}
+
+bool LotroManager::notPatched() {
+    return file.GetStatusModule().CheckIfNotPatched();
+}

+ 77 - 0
src/Legacy/models/lotromanager.h

@@ -0,0 +1,77 @@
+#ifndef LEGACYAPP_H
+#define LEGACYAPP_H
+
+#include <QObject>
+#include <QSettings>
+#include <QApplication>
+
+#include <LotroDat/LotroDat.h>
+
+class LotroManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit LotroManager(QSettings* app_settings_, QObject *parent = nullptr);
+
+    bool initialised();
+
+    int currentLocale();
+
+    bool notPatched();
+
+public slots:
+    void initialiseDatFile(QString file_path);
+
+    void deinitialiseDatFile();
+
+    void changeLocale();
+
+    void getLocaleFileContents(long long file_id, int locale);
+
+    void importFilesFromDatabase(QString database_path);
+
+    void importFile(long long file_id, QString file_path);
+
+    void importTextFragment(long long file_id, long long fragment_id, QString fragment_contents, QString arguments);
+
+    void getTextFragment(long long file_id, long long fragment_id);
+
+    void createCoreStatusFile(QString output_filename);
+
+    void extractSingleFile(QString output_filename, long long file_id);
+
+    void extractSingleFileToDatabase(QString database_path, long long file_id);
+
+    void extractGrouppedFiles(QString output_foldername, LOTRO_DAT::FILE_TYPE type);
+
+    void extractGrouppedFilesToDatabase(QString database_path, LOTRO_DAT::FILE_TYPE type);
+
+    void getUnactiveCategories();
+
+    void startGame();
+
+    void getLocaleFileInfo(long long file_id, int locale);
+
+    void getFileInfo(long long file_id);
+
+    LOTRO_DAT::DatStatus *getStatusModule();
+
+signals:
+    // general signals. First argument is process_name, second - processed values
+    void processStarted(QString, QVector<QVariant>);
+    void processFinished(QString, QVector<QVariant>);
+    void processUpdated(QString, QVector<QVariant>);
+    void caughtError(QString, QVector<QVariant>);
+
+    void textFragmentReceived(QString, QString);
+    void unactiveCategoriesReceived(QStringList);
+    void localeFileContentsReceived(int, LOTRO_DAT::SubfileData); // extention, contents
+    void localeFileInfoReceived(int, QString);
+    void fileInfoReceived(QString);
+private:
+    LOTRO_DAT::DatFile file;
+    QSettings* app_settings;
+};
+
+#endif // LEGACYAPP_H

+ 13 - 13
src/Legacy/object_script.Legacy.Debug

@@ -2,26 +2,26 @@ INPUT(
 ./..\..\build\debug\Legacy\rcc\qrc_backgrounds.o
 ./..\..\build\debug\Legacy\rcc\qrc_common.o
 ./..\..\build\debug\Legacy\obj\main.o
+./..\..\build\debug\Legacy\obj\downloader.o
+./..\..\build\debug\Legacy\obj\filesystem.o
+./..\..\build\debug\Legacy\obj\lotromanager.o
+./..\..\build\debug\Legacy\obj\helpwidget.o
 ./..\..\build\debug\Legacy\obj\mainwindow.o
 ./..\..\build\debug\Legacy\obj\menuentry.o
-./..\..\build\debug\Legacy\obj\legacyapp.o
-./..\..\build\debug\Legacy\obj\filesystem.o
-./..\..\build\debug\Legacy\obj\statuswidget.o
-./..\..\build\debug\Legacy\obj\rusificationwidget.o
-./..\..\build\debug\Legacy\obj\settingswidget.o
 ./..\..\build\debug\Legacy\obj\newswidget.o
-./..\..\build\debug\Legacy\obj\helpwidget.o
-./..\..\build\debug\Legacy\obj\networkdownloader.o
 ./..\..\build\debug\Legacy\obj\rusificationtreeitem.o
+./..\..\build\debug\Legacy\obj\rusificationwidget.o
+./..\..\build\debug\Legacy\obj\settingswidget.o
+./..\..\build\debug\Legacy\obj\statuswidget.o
 ./..\..\build\debug\Legacy\obj\legacy_plugin_import.o
+./..\..\build\debug\Legacy\obj\moc_downloader.o
+./..\..\build\debug\Legacy\obj\moc_filesystem.o
+./..\..\build\debug\Legacy\obj\moc_lotromanager.o
+./..\..\build\debug\Legacy\obj\moc_helpwidget.o
 ./..\..\build\debug\Legacy\obj\moc_mainwindow.o
 ./..\..\build\debug\Legacy\obj\moc_menuentry.o
-./..\..\build\debug\Legacy\obj\moc_legacyapp.o
-./..\..\build\debug\Legacy\obj\moc_filesystem.o
-./..\..\build\debug\Legacy\obj\moc_statuswidget.o
+./..\..\build\debug\Legacy\obj\moc_newswidget.o
 ./..\..\build\debug\Legacy\obj\moc_rusificationwidget.o
 ./..\..\build\debug\Legacy\obj\moc_settingswidget.o
-./..\..\build\debug\Legacy\obj\moc_newswidget.o
-./..\..\build\debug\Legacy\obj\moc_helpwidget.o
-./..\..\build\debug\Legacy\obj\moc_networkdownloader.o
+./..\..\build\debug\Legacy\obj\moc_statuswidget.o
 );

+ 13 - 13
src/Legacy/object_script.Legacy.Release

@@ -1,25 +1,25 @@
 INPUT(
 ./..\..\build\release\Legacy\obj\main.o
+./..\..\build\release\Legacy\obj\downloader.o
+./..\..\build\release\Legacy\obj\filesystem.o
+./..\..\build\release\Legacy\obj\lotromanager.o
+./..\..\build\release\Legacy\obj\helpwidget.o
 ./..\..\build\release\Legacy\obj\mainwindow.o
 ./..\..\build\release\Legacy\obj\menuentry.o
-./..\..\build\release\Legacy\obj\legacyapp.o
-./..\..\build\release\Legacy\obj\filesystem.o
-./..\..\build\release\Legacy\obj\statuswidget.o
-./..\..\build\release\Legacy\obj\rusificationwidget.o
-./..\..\build\release\Legacy\obj\settingswidget.o
 ./..\..\build\release\Legacy\obj\newswidget.o
-./..\..\build\release\Legacy\obj\helpwidget.o
-./..\..\build\release\Legacy\obj\networkdownloader.o
 ./..\..\build\release\Legacy\obj\rusificationtreeitem.o
+./..\..\build\release\Legacy\obj\rusificationwidget.o
+./..\..\build\release\Legacy\obj\settingswidget.o
+./..\..\build\release\Legacy\obj\statuswidget.o
 ./..\..\build\release\Legacy\obj\legacy_plugin_import.o
+./..\..\build\release\Legacy\obj\moc_downloader.o
+./..\..\build\release\Legacy\obj\moc_filesystem.o
+./..\..\build\release\Legacy\obj\moc_lotromanager.o
+./..\..\build\release\Legacy\obj\moc_helpwidget.o
 ./..\..\build\release\Legacy\obj\moc_mainwindow.o
 ./..\..\build\release\Legacy\obj\moc_menuentry.o
-./..\..\build\release\Legacy\obj\moc_legacyapp.o
-./..\..\build\release\Legacy\obj\moc_filesystem.o
-./..\..\build\release\Legacy\obj\moc_statuswidget.o
+./..\..\build\release\Legacy\obj\moc_newswidget.o
 ./..\..\build\release\Legacy\obj\moc_rusificationwidget.o
 ./..\..\build\release\Legacy\obj\moc_settingswidget.o
-./..\..\build\release\Legacy\obj\moc_newswidget.o
-./..\..\build\release\Legacy\obj\moc_helpwidget.o
-./..\..\build\release\Legacy\obj\moc_networkdownloader.o
+./..\..\build\release\Legacy\obj\moc_statuswidget.o
 );

+ 0 - 47
src/Legacy/src/legacyapp.cpp

@@ -1,47 +0,0 @@
-#include "legacyapp.h"
-#include "filesystem.h"
-
-#include <QtConcurrent/QtConcurrent>
-#include <QFontDatabase>
-
-LegacyApp::LegacyApp(QObject *parent) : QObject(parent), window(this),
-    client_local_dat(), client_local_dat_busy(false),
-    properties(qApp->applicationDirPath() + "/legacy_v2.ini", QSettings::IniFormat)
-{
-    properties.setIniCodec("UTF-8");
-}
-
-void LegacyApp::Init()
-{
-    QResource::registerResource(QApplication::applicationDirPath() + "/data01.gtr");
-    QResource::registerResource(QApplication::applicationDirPath() + "/data02.gtr");
-
-    QFontDatabase::addApplicationFont(":/assets/fonts/trajan.ttf");
-    QFontDatabase::addApplicationFont(":/assets/fonts/viking.ttf");
-    QFontDatabase::addApplicationFont(":/assets/fonts/title.ttf");
-
-
-    window.Init();
-    StartDatFilesInitialisation();
-}
-
-void LegacyApp::StartDatFilesInitialisation()
-{
-    QString lotro_dir_path = properties.value("settings/lotro_folder", "none").toString();
-    QString locale = properties.value("lotro/locale", "English").toString();
-
-    qDebug() << "Initialising file " << lotro_dir_path + "/client_local_" + locale + ".dat";
-
-    QtConcurrent::run([this, lotro_dir_path, locale](){
-        if (client_local_dat_busy == false) {
-            client_local_dat_busy = true;
-            client_local_dat.Initialise((lotro_dir_path + "/client_local_" + locale + ".dat").toStdString(), 0);
-            client_local_dat_busy = false;
-        }
-    });
-}
-
-void LegacyApp::DownloadFinished()
-{
-    // TODO
-}

+ 0 - 47
src/Legacy/src/legacyapp.h

@@ -1,47 +0,0 @@
-#ifndef LEGACYAPP_H
-#define LEGACYAPP_H
-
-#include <QObject>
-#include <QSettings>
-#include <QApplication>
-
-#include <queue>
-
-#include "mainwindow.h"
-#include <LotroDat/LotroDat.h>
-
-class MainWindow;
-class NetworkDownloader;
-
-class LegacyApp : public QObject
-{
-    Q_OBJECT
-
-public:
-    explicit LegacyApp(QObject *parent = nullptr);
-
-    void Init();
-
-private:
-    void StartDatFilesInitialisation();
-
-signals:
-
-private slots:
-    void DownloadFinished();
-
-
-public:
-    MainWindow window;
-
-    LOTRO_DAT::DatFile client_local_dat;
-    std::queue<QString> patch_databases_queue;
-    bool client_local_dat_busy;
-
-    QSettings properties;
-
-    NetworkDownloader* dowloader;
-    std::queue<std::pair<QString, QString>> download_queue;
-};
-
-#endif // LEGACYAPP_H

+ 0 - 22
src/Legacy/src/main.cpp

@@ -1,22 +0,0 @@
-#include <QApplication>
-#include <QMessageBox>
-#include <QLockFile>
-#include <QDir>
-#include "legacyapp.h"
-
-int main(int argc, char *argv[])
-{
-    QApplication a(argc, argv);
-    QLockFile lockFile(QDir::temp().absoluteFilePath("rulotro.lock"));
-    if(!lockFile.tryLock(1)){
-        QMessageBox msgBox;
-        msgBox.setIcon(QMessageBox::Warning);
-        msgBox.setText("Приложение уже запущено.\nРазрешено запускать только один экземпляр приложения.");
-        msgBox.exec();
-        return 1;
-    }
-
-    LegacyApp app;
-    app.Init();
-    return a.exec();
-}

+ 14 - 0
src/Legacy/widgets/helpwidget.cpp

@@ -0,0 +1,14 @@
+#include "widgets\helpwidget.h"
+#include "ui_helpwidget.h"
+
+HelpWidget::HelpWidget(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::HelpWidget)
+{
+    ui->setupUi(this);
+}
+
+HelpWidget::~HelpWidget()
+{
+    delete ui;
+}

+ 1 - 4
src/Legacy/gui/helpwidget.h → src/Legacy/widgets/helpwidget.h

@@ -3,8 +3,6 @@
 
 #include <QWidget>
 
-class LegacyApp;
-
 namespace Ui {
 class HelpWidget;
 }
@@ -14,12 +12,11 @@ class HelpWidget : public QWidget
     Q_OBJECT
 
 public:
-    explicit HelpWidget(LegacyApp *_app, QWidget *parent = 0);
+    explicit HelpWidget(QWidget *parent = 0);
     ~HelpWidget();
 
 private:
     Ui::HelpWidget *ui;
-    LegacyApp *app;
 };
 
 #endif // HELPWIDGET_H

+ 0 - 0
src/Legacy/gui/helpwidget.ui → src/Legacy/widgets/helpwidget.ui


+ 65 - 62
src/Legacy/gui/mainwindow.cpp → src/Legacy/widgets/mainwindow.cpp

@@ -1,6 +1,5 @@
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
-#include "legacyapp.h"
 
 #include <QBitmap>
 #include <QPainter>
@@ -12,48 +11,54 @@
 #include <QDesktopWidget>
 #include <QtConcurrent/QtConcurrent>
 
-MainWindow::MainWindow(LegacyApp *app, QWidget *parent) :
-    QMainWindow(parent, Qt::Window | Qt::FramelessWindowHint), app(app),
+MainWindow::MainWindow(QWidget *parent) :
+    QMainWindow(parent, Qt::Window | Qt::FramelessWindowHint),
     ui(new Ui::MainWindow), menuHoverWidget(nullptr), menuHoverWidgetAnimation(nullptr)
 {
-}
-
-void MainWindow::Init() {
     ui->setupUi(this);
 
-    status_frame = new StatusWidget(app, this);
-    ui->content_layout->addWidget(status_frame);
-
-    rusification_frame = new RusificationWidget(app, this);
-    ui->content_layout->addWidget(rusification_frame);
+    qDebug() << "Initialising Settings module";
+    QSettings *settings = new QSettings(qApp->applicationDirPath() + "/legacy_v2.ini", QSettings::IniFormat);
 
-    settings_frame = new SettingsWidget(app, this);
-    ui->content_layout->addWidget(settings_frame);
+    status_widget = new StatusWidget(this);
+    rusification_widget = new RusificationWidget(this);
+    settings_widget = new SettingsWidget(this);
+    news_widget = new NewsWidget(this);
+    help_widget = new HelpWidget(this);
 
-    news_frame = new NewsWidget(app, this);
-    ui->content_layout->addWidget(news_frame);
+    ui->content_layout->addWidget(status_widget);
+    ui->content_layout->addWidget(rusification_widget);
+    ui->content_layout->addWidget(settings_widget);
+    ui->content_layout->addWidget(news_widget);
+    ui->content_layout->addWidget(help_widget);
 
-    help_frame = new HelpWidget(app, this);
-    ui->content_layout->addWidget(help_frame);
+    ui->centralWidget->setStyleSheet("");
 
     hideAllContentWidgets();
-    status_frame->show();
+    status_widget->show();
 
+    qDebug() << "Making fonts and making background";
     changeFontSizeRecursive(100, this);
 
     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
-    background = new QPixmap();
-    background->load(":/assets/backgrounds/bg" + QString::number(qrand() % MAX_PIXMAP_ID + 1) + ".png");
-    setupWindowBackgroundAndMask();
+    current_bg_id = qrand() % MAX_PIXMAP_ID + 1;
+    QPixmap background(":/backgrounds/bg" + QString::number(current_bg_id) + ".png");
+    setupWindowBackgroundAndMask(background);
+
     setupMenuHoverWidget();
 
     updateGeometry();
     repaint();
 
+    qDebug() << "Initialising background updates";
     background_update_timer.setInterval(30 * 1000);
     connect(&background_update_timer, &QTimer::timeout, this, &MainWindow::randomChangeBackground);
     background_update_timer.start();
-    ui->centralWidget->setStyleSheet("");
+
+    qDebug() << "Initialising main window connections";
+    makeConnections();
+
+    qDebug() << "Finishing main frame initialisation";
     show();
 }
 
@@ -83,9 +88,10 @@ void MainWindow::resizeEvent(QResizeEvent * event)
 
     ui->content_area->move(width * 25 / 2000, height * 250 / 1296);
     ui->content_area->resize(width * 1950 / 2000, height * 1000 / 1296);
-    setupWindowBackgroundAndMask();
+    setupWindowBackgroundAndMask(current_bg);
 }
 
+
 void MainWindow::randomChangeBackground()
 {
     if (!qApp)
@@ -93,42 +99,33 @@ void MainWindow::randomChangeBackground()
 
     qDebug() << "Starting background update";
 
-    if (fade_animation_timer.isActive()) {
-        qDebug() << "MainWindow::startBackgroundUpdate() - cannot start, because update is still active";
-        return;
-    }
 
-    next_pixmap_opacity = 0;
     int next_pixmap_id = qrand() % MAX_PIXMAP_ID + 1;
-
-    if (!next_pixmap)
-        next_pixmap = new QPixmap();
-
-    next_pixmap->load(":/assets/backgrounds/bg" + QString::number(next_pixmap_id) + ".png");
-    qDebug() << "Next pixmap id" << next_pixmap_id << "!";
-
-    if (next_pixmap->isNull()) {
-        qDebug() << "Incorrect pixmap id " << next_pixmap_id << "!";
-        return;
+    while (next_pixmap_id == current_bg_id) {
+        next_pixmap_id = qrand() % MAX_PIXMAP_ID + 1;
     }
+    qDebug() << "Next background id = " << next_pixmap_id;
+
+    QPixmap *cur_bg = new QPixmap(current_bg.scaled(size()));
+    QPixmap *new_bg= new QPixmap(QPixmap(":/backgrounds/bg" + QString::number(next_pixmap_id) + ".png").scaled(size()));
+    current_bg_id = next_pixmap_id;
 
-    QtConcurrent::run([this](){
-        qDebug() << "Starting background update";
-        while (next_pixmap_opacity < 1 && qApp) {
-            if (!qApp)
-                return;
+    QtConcurrent::run([cur_bg, new_bg, this](){
+        const int iterations_num = 150;
+        const int iteration_sleep = 75;
 
+        for (int i = 0; i < iterations_num && qApp; i++) {
             QPainter painter;
-            painter.begin(background);
-            painter.setOpacity(next_pixmap_opacity);
+            painter.begin(cur_bg);
+            painter.setOpacity(double(10 + i) / double(iterations_num));
             painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
-            painter.drawPixmap(0,0, *next_pixmap);
+            painter.drawPixmap(0,0, *new_bg);
             painter.end();
-
-            setupWindowBackgroundAndMask();
-            next_pixmap_opacity += 0.005;
-            QThread::msleep(50);
+            QMetaObject::invokeMethod(this, "setupWindowBackgroundAndMask", Qt::QueuedConnection, Q_ARG(QPixmap, *cur_bg));
+            QThread::msleep(iteration_sleep);
         }
+        delete cur_bg;
+        delete new_bg;
         qDebug() << "Background update finished";
     });
 }
@@ -142,31 +139,31 @@ MainWindow::~MainWindow()
 void MainWindow::on_menuentry_1_common_clicked()
 {
     hideAllContentWidgets();
-    status_frame->show();
+    status_widget->show();
 }
 
 void MainWindow::on_menuentry_2_common_clicked()
 {
     hideAllContentWidgets();
-    settings_frame->show();
+    settings_widget->show();
 }
 
 void MainWindow::on_menuentry_3_common_clicked()
 {
     hideAllContentWidgets();
-    rusification_frame->show();
+    rusification_widget->show();
 }
 
 void MainWindow::on_menuentry_4_common_clicked()
 {
     hideAllContentWidgets();
-    news_frame->show();
+    news_widget->show();
 }
 
 void MainWindow::on_menuentry_5_common_clicked()
 {
     hideAllContentWidgets();
-    help_frame->show();
+    help_widget->show();
 }
 
 void MainWindow::onHoverMenuentry()
@@ -174,9 +171,11 @@ void MainWindow::onHoverMenuentry()
     moveMenuHoverWidget(MenuEntry::getHoverLabel());
 }
 
-void MainWindow::setupWindowBackgroundAndMask()
+void MainWindow::setupWindowBackgroundAndMask(QPixmap background)
 {
-    current_bg = background->scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+    if (!qApp)
+        return;
+    current_bg = background.scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
     current_mask = current_bg.mask();
     setMask(current_mask);
 
@@ -185,6 +184,10 @@ void MainWindow::setupWindowBackgroundAndMask()
     setPalette(palette);
 }
 
+void MainWindow::makeConnections()
+{
+}
+
 void MainWindow::setupMenuHoverWidget()
 {
     menuHoverWidget = new QWidget(ui->menu_widget);
@@ -241,11 +244,11 @@ void MainWindow::checkMenuIsHovered()
 
 void MainWindow::hideAllContentWidgets()
 {
-    status_frame->hide();
-    rusification_frame->hide();
-    settings_frame->hide();
-    news_frame->hide();
-    help_frame->hide();
+    status_widget->hide();
+    rusification_widget->hide();
+    settings_widget->hide();
+    news_widget->hide();
+    help_widget->hide();
 }
 
 void MainWindow::changeFontSizeRecursive(size_t percent, QWidget *widget)

+ 16 - 22
src/Legacy/gui/mainwindow.h → src/Legacy/widgets/mainwindow.h

@@ -18,18 +18,17 @@ class MainWindow;
 }
 
 class MenuEntry;
-class LegacyApp;
+// class LotroManager;
+// class NetworkUpdater;
+// class PatchDownloader;
+// class NewsDownloader;
 
 class MainWindow : public QMainWindow
 {
     Q_OBJECT
-    struct PixmapObertka{
-        QPixmap* pixmap;
-    };
 
 public:
-    explicit MainWindow(LegacyApp *app = 0, QWidget *parent = 0);
-    void Init();
+    explicit MainWindow(QWidget *parent = 0);
     void changeFontSizeRecursive(size_t percent, QWidget* widget);
     ~MainWindow();
 
@@ -57,8 +56,10 @@ private slots:
 
     void on_minimizeButton_clicked();
 
+    void setupWindowBackgroundAndMask(QPixmap background);
+
 private:
-    void setupWindowBackgroundAndMask();
+    void makeConnections();
 
     void setupMenuHoverWidget();
 
@@ -69,10 +70,14 @@ private:
     void hideAllContentWidgets();
 
 private:
-    LegacyApp *app;
-
     Ui::MainWindow *ui;
 
+    StatusWidget *status_widget;
+    RusificationWidget *rusification_widget;
+    SettingsWidget *settings_widget;
+    NewsWidget *news_widget;
+    HelpWidget *help_widget;
+
     QWidget* menuHoverWidget;
     QPropertyAnimation* menuHoverWidgetAnimation;
     QPropertyAnimation* menuHoverWidgetScaleAnimation;
@@ -80,23 +85,12 @@ private:
 
     QPoint dragPosition;
 
-    StatusWidget *status_frame;
-    RusificationWidget *rusification_frame;
-    SettingsWidget *settings_frame;
-    NewsWidget *news_frame;
-    HelpWidget *help_frame;
-
-    QPixmap *background;
-    QPixmap *next_pixmap {nullptr};
-
+    int current_bg_id;
     QPixmap current_bg;
     QBitmap current_mask;
-
     QTimer background_update_timer;
-    QTimer fade_animation_timer;
-    double next_pixmap_opacity;
 
-    const int MAX_PIXMAP_ID = 9;
+    const int MAX_PIXMAP_ID = 14;
 
     const size_t common_font_size = 15;
     const size_t title_font_size = 17;

+ 6 - 9
src/Legacy/gui/mainwindow.ui → src/Legacy/widgets/mainwindow.ui

@@ -22,9 +22,6 @@
   <property name="autoFillBackground">
    <bool>false</bool>
   </property>
-  <property name="styleSheet">
-   <string notr="true"/>
-  </property>
   <property name="animated">
    <bool>false</bool>
   </property>
@@ -42,7 +39,7 @@
     <bool>false</bool>
    </property>
    <property name="styleSheet">
-    <string notr="true">border-image: url(:/assets/backgrounds/bg1.png);</string>
+    <string notr="true">border-image: url(:/backgrounds/bg1.png);</string>
    </property>
    <widget class="QWidget" name="content_area" native="true">
     <property name="geometry">
@@ -366,9 +363,9 @@
            </size>
           </property>
           <property name="styleSheet">
-           <string notr="true">QPushButton#minimizeButton {border-image: url(:/assets/buttons/minimize.png) 0 0 0 0 stretch stretch; border: 0px;}
+           <string notr="true">QPushButton#minimizeButton {border-image: url(:/buttons/minimize.png) 0 0 0 0 stretch stretch; border: 0px;}
 
-QPushButton#minimizeButton:hover {border-image: url(:/assets/buttons/minimize.png) 0 0 0 0 stretch stretch; border: 1px;}
+QPushButton#minimizeButton:hover {border-image: url(:/buttons/minimize.png) 0 0 0 0 stretch stretch; border: 1px;}
 
 </string>
           </property>
@@ -386,9 +383,9 @@ QPushButton#minimizeButton:hover {border-image: url(:/assets/buttons/minimize.pn
            </size>
           </property>
           <property name="styleSheet">
-           <string notr="true">QPushButton#closeButton { border-image: url(:/assets/buttons/close.png) 0 0 0 0 stretch stretch; }
+           <string notr="true">QPushButton#closeButton { border-image: url(:/buttons/close.png) 0 0 0 0 stretch stretch; }
 
-QPushButton#closeButton:hover { border-image: url(:/assets/buttons/close.png) 0 0 0 0 stretch stretch; border:1px;}</string>
+QPushButton#closeButton:hover { border-image: url(:/buttons/close.png) 0 0 0 0 stretch stretch; border:1px;}</string>
           </property>
           <property name="text">
            <string>Х</string>
@@ -407,7 +404,7 @@ QPushButton#closeButton:hover { border-image: url(:/assets/buttons/close.png) 0
   <customwidget>
    <class>MenuEntry</class>
    <extends>QLabel</extends>
-   <header>menuentry.h</header>
+   <header>widgets/menuentry.h</header>
   </customwidget>
  </customwidgets>
  <resources/>

+ 0 - 0
src/Legacy/src/menuentry.cpp → src/Legacy/widgets/menuentry.cpp


+ 0 - 0
src/Legacy/src/menuentry.h → src/Legacy/widgets/menuentry.h


+ 8 - 9
src/Legacy/gui/newswidget.cpp → src/Legacy/widgets/newswidget.cpp

@@ -1,15 +1,14 @@
-#include "gui\newswidget.h"
+#include "widgets/newswidget.h"
 #include "ui_newswidget.h"
 
-#include "networkdownloader.h"
-#include "legacyapp.h"
+#include "models/downloader.h"
 #include <QtConcurrent/QtConcurrent>
 #include <QLabel>
 
-NewsWidget::NewsWidget(LegacyApp *_app, QWidget *parent) :
+NewsWidget::NewsWidget(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::NewsWidget),
-    app(_app), news_downloader(this)
+    news_downloader(this)
 {
     ui->setupUi(this);
     ui->test_news_piece->hide();
@@ -17,8 +16,8 @@ NewsWidget::NewsWidget(LegacyApp *_app, QWidget *parent) :
     news_downloader.targetBytearray = &news_data;
     news_downloader.setUrl(QUrl("http://translate.lotros.ru/groupware/launcher_news"));
 
-    connect(&news_update_timer, &QTimer::timeout, &news_downloader, &NetworkDownloader::start);
-    connect(&news_downloader, &NetworkDownloader::downloadFinished, this, &NewsWidget::updateNews);
+    connect(&news_update_timer, &QTimer::timeout, &news_downloader, &Downloader::start);
+    connect(&news_downloader, &Downloader::downloadFinished, this, &NewsWidget::updateNews);
     emit news_downloader.start();
     news_update_timer.setInterval(1000 * 60); // 10 minutes;
     news_update_timer.start();
@@ -54,7 +53,7 @@ void NewsWidget::updateNews()
         constructNewsPiece(i, news_title, news_desrc, news_src);
 
         QtConcurrent::run([i, this, img_src](){
-            NetworkDownloader img_dwnld;
+            Downloader img_dwnld;
             QByteArray img;
             img_dwnld.setUrl(QUrl(img_src));
             img_dwnld.targetBytearray = &img;
@@ -147,7 +146,7 @@ void NewsWidget::constructNewsPiece(int piece_id, QString title, QString text, Q
     contentLabel->setSizePolicy(sizePolicy);
 
     news_piece_layout->addWidget(contentLabel, 1, 1, 1, 1);
-    app->window.changeFontSizeRecursive(app->properties.value("settings/ui_scale", 100).toInt(), news_piece);
+//    app->window.changeFontSizeRecursive(app->properties.value("settings/ui_scale", 100).toInt(), news_piece);
 
     ui->news_layout->addWidget(news_piece, piece_id, 0);
 }

+ 3 - 6
src/Legacy/gui/newswidget.h → src/Legacy/widgets/newswidget.h

@@ -3,20 +3,18 @@
 
 #include <QWidget>
 #include <QTimer>
-#include "networkdownloader.h"
+#include "models/downloader.h"
 
 namespace Ui {
 class NewsWidget;
 }
 
-class LegacyApp;
-
 class NewsWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit NewsWidget(LegacyApp *_app, QWidget *parent = 0);
+    explicit NewsWidget(QWidget *parent = 0);
     ~NewsWidget();
 
 public slots:
@@ -28,10 +26,9 @@ private:
 
 private:
     Ui::NewsWidget *ui;
-    LegacyApp *app;
     QTimer news_update_timer;
     QByteArray news_data;
-    NetworkDownloader news_downloader;
+    Downloader news_downloader;
 };
 
 #endif // NEWSWIDGET_H

+ 0 - 0
src/Legacy/gui/newswidget.ui → src/Legacy/widgets/newswidget.ui


+ 0 - 0
src/Legacy/src/rusificationtreeitem.cpp → src/Legacy/widgets/rusificationtreeitem.cpp


+ 0 - 0
src/Legacy/src/rusificationtreeitem.h → src/Legacy/widgets/rusificationtreeitem.h


+ 4 - 6
src/Legacy/gui/rusificationwidget.cpp → src/Legacy/widgets/rusificationwidget.cpp

@@ -1,7 +1,6 @@
-#include "gui\rusificationwidget.h"
+#include "widgets/rusificationwidget.h"
 #include "ui_rusificationwidget.h"
-#include "legacyapp.h"
-#include "rusificationtreeitem.h"
+#include "widgets/rusificationtreeitem.h"
 #include <QDebug>
 
 void doStuffWithEveryItemInMyTree( QTreeWidgetItem *item )
@@ -23,10 +22,9 @@ QTreeWidgetItem* findItemByName(QTreeWidgetItem* item, QString name) {
     return nullptr;
 }
 
-RusificationWidget::RusificationWidget(LegacyApp *_app, QWidget *parent) :
+RusificationWidget::RusificationWidget(QWidget *parent) :
     QWidget(parent),
-    ui(new Ui::RusificationWidget),
-    app(_app)
+    ui(new Ui::RusificationWidget)
 {
     ui->setupUi(this);
     setupTreeWidget();

+ 1 - 4
src/Legacy/gui/rusificationwidget.h → src/Legacy/widgets/rusificationwidget.h

@@ -9,14 +9,12 @@ namespace Ui {
 class RusificationWidget;
 }
 
-class LegacyApp;
-
 class RusificationWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit RusificationWidget(LegacyApp *_app, QWidget *parent = 0);
+    explicit RusificationWidget(QWidget *parent = 0);
 
     ~RusificationWidget();
 
@@ -30,7 +28,6 @@ private slots:
 
 private:
     Ui::RusificationWidget *ui;
-    LegacyApp *app;
     QTimer ui_update_timer;
 };
 

+ 0 - 0
src/Legacy/gui/rusificationwidget.ui → src/Legacy/widgets/rusificationwidget.ui


+ 163 - 0
src/Legacy/widgets/settingswidget.cpp

@@ -0,0 +1,163 @@
+#include "widgets/settingswidget.h"
+#include "ui_settingswidget.h"
+#include "models/filesystem.h"
+
+#include <QDebug>
+#include <QFileDialog>
+#include <QMessageBox>
+
+
+SettingsWidget::SettingsWidget(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::SettingsWidget)
+{
+    ui->setupUi(this);
+    ui_update_timer.setInterval(500);
+    connect(&ui_update_timer, &QTimer::timeout, this, &SettingsWidget::updateUI);
+    ui_update_timer.start();
+}
+
+SettingsWidget::~SettingsWidget()
+{
+    ui_update_timer.stop();
+    delete ui;
+}
+
+void SettingsWidget::updateUI()
+{
+    if (!qApp)
+        return;
+
+//    QString path = app->properties.value("settings/lotro_folder", "(не выбрана)").toString();
+//    ui->folder_value_common->setText(path);
+
+//    ui->data_protection_checkbox_common->setChecked(app->properties.value("settings/data_protection", 1).toBool());
+//    ui->restore_checkbox_common->setChecked(app->properties.value("settings/auto_restore", 1).toBool());
+//    ui->download_updates_checkbox_common->setChecked(app->properties.value("settings/download_updates", 1).toBool());
+//    ui->expert_tabs_checkbox_common->setChecked(app->properties.value("settings/expert_mode", 0).toBool());
+//    ui->restrict_download_speed_checkbox_common->setChecked(app->properties.value("settings/limit_download_speed", 0).toBool());
+//    ui->download_restrict_slider->setValue(app->properties.value("settings/download_speed", 64).toInt());
+
+//    if (app->properties.value("settings/expert_mode", 0).toBool()) {
+//        ui->management_widget->show();
+//        ui->data_protection_checkbox_common->show();
+//        ui->restore_checkbox_common->show();
+//    } else {
+//        ui->management_widget->hide();
+//        ui->data_protection_checkbox_common->hide();
+//        ui->restore_checkbox_common->hide();
+//    }
+
+//    int locale_index = 0;
+//    QString value = app->properties.value("settings/locale", "English").toString();
+
+//    if (value == "English")
+//        locale_index = 0;
+//    if (value == "DE")
+//        locale_index = 1;
+//    if (value == "FR")
+//        locale_index = 2;
+
+//    ui->lotro_patch_language_combobox_common->setCurrentIndex(locale_index);
+}
+
+void SettingsWidget::on_download_restrict_slider_valueChanged(int value)
+{
+//    if (value >= 1024) {
+//        double new_value = double(value) / 1024;
+//        ui->download_speed_label_common->setText(QString::number(new_value, 'g', 2) + " Мб/с");
+//    } else {
+//        ui->download_speed_label_common->setText(QString::number(value) + " Кб/с");
+//    }
+//    app->properties.setValue("settings/download_speed", value);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_interface_scale_combobox_common_currentIndexChanged(const QString &arg1)
+{
+//    int value = arg1.left(arg1.length() - 1).toInt();
+//    app->window.changeFontSizeRecursive(value, &app->window);
+//    app->window.resize(900 * value / 100, 650 * value / 100);
+//    app->properties.setValue("settings/ui_scale", value);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_change_folder_button_clicked()
+{
+//    QStringList known_paths = FileSystem::recognizeRegistryLotroPath();
+//    QString template_path = known_paths.size() > 0 ? known_paths[0] : "";
+//    QString str = QFileDialog::getOpenFileName(0, "Расположение игры", template_path, "LotroLauncher.exe");
+//    QString path = str.replace("/LotroLauncher.exe", "").replace("\\", "/").replace("//", "/");
+
+//    if (!FileSystem::fileExists(path + "/LotroLauncher.exe")) {
+//        QMessageBox error_box("Ошибка!", "Похоже, указана неверная папка с игрой. Не могу найти файл LotroLauncher.exe",
+//                              QMessageBox::Critical, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+
+//        return;
+//    }
+
+//    if (!FileSystem::fileExists(path + "/client_local_English.dat")) {
+//        QMessageBox pmbx("Файл данных не найден",
+//                         "Файл данных client_local_English.dat не обнаружен в папке с игрой. Запустить лаунчер игры с целью скачать недостающие данные?",
+//                         QMessageBox::Warning,
+//                         QMessageBox::Yes,
+//                         QMessageBox::No,
+//                         QMessageBox::NoButton);
+
+//        if (pmbx.exec() == QMessageBox::Yes) {
+//            // Start LotRO;
+//            return;
+//        } else {
+//            // Set status Файл данных не найден
+//        }
+//    }
+
+//    app->properties.setValue("settings/lotro_folder", path);
+//    app->properties.sync();
+//    ui->folder_value_common->setText(path);
+}
+
+void SettingsWidget::on_data_protection_checkbox_common_stateChanged(int arg1)
+{
+//    app->properties.setValue("settings/data_protection", arg1);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_restore_checkbox_common_stateChanged(int arg1)
+{
+//    app->properties.setValue("settings/auto_restore", arg1);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_download_updates_checkbox_common_stateChanged(int arg1)
+{
+//    app->properties.setValue("settings/download_updates", arg1);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_expert_tabs_checkbox_common_stateChanged(int arg1)
+{
+//    app->properties.setValue("settings/expert_mode", arg1);
+//    app->properties.sync();
+}
+
+void SettingsWidget::on_restrict_download_speed_checkbox_common_stateChanged(int arg1)
+{
+//    app->properties.setValue("settings/limit_download_speed", arg1);
+//    app->properties.sync();
+}
+
+
+void SettingsWidget::on_lotro_patch_language_combobox_common_activated(int index)
+{
+//    QString value = "";
+//    if (index == 0)
+//        value = "English";
+//    if (index == 1)
+//        value = "DE";
+//    if (index == 2)
+//        value = "FR";
+//
+//    app->properties.setValue("settings/locale", value);
+//    app->properties.sync();
+}

+ 1 - 4
src/Legacy/gui/settingswidget.h → src/Legacy/widgets/settingswidget.h

@@ -8,14 +8,12 @@ namespace Ui {
 class SettingsWidget;
 }
 
-class LegacyApp;
-
 class SettingsWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit SettingsWidget(LegacyApp *_app, QWidget *parent = 0);
+    explicit SettingsWidget(QWidget *parent = 0);
     ~SettingsWidget();
 
 private slots:
@@ -41,7 +39,6 @@ private slots:
 
 private:
     Ui::SettingsWidget *ui;
-    LegacyApp *app;
     QTimer ui_update_timer;
 };
 

+ 0 - 0
src/Legacy/gui/settingswidget.ui → src/Legacy/widgets/settingswidget.ui


+ 2 - 3
src/Legacy/gui/statuswidget.cpp → src/Legacy/widgets/statuswidget.cpp

@@ -1,10 +1,9 @@
 #include "statuswidget.h"
 #include "ui_statuswidget.h"
 
-StatusWidget::StatusWidget(LegacyApp *_app, QWidget *parent) :
+StatusWidget::StatusWidget(QWidget *parent) :
     QWidget(parent),
-    ui(new Ui::StatusWidget),
-    app(_app)
+    ui(new Ui::StatusWidget)
 {
     ui->setupUi(this);
 }

+ 1 - 4
src/Legacy/gui/statuswidget.h → src/Legacy/widgets/statuswidget.h

@@ -7,19 +7,16 @@ namespace Ui {
 class StatusWidget;
 }
 
-class LegacyApp;
-
 class StatusWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit StatusWidget(LegacyApp *_app, QWidget *parent = 0);
+    explicit StatusWidget(QWidget *parent = 0);
     ~StatusWidget();
 
 private:
     Ui::StatusWidget *ui;
-    LegacyApp *app;
 
     const QColor inWorkColor = QColor(85, 170, 255);
     const QColor readyColor = QColor(0, 170, 0);

+ 141 - 225
src/Legacy/gui/statuswidget.ui → src/Legacy/widgets/statuswidget.ui

@@ -6,58 +6,159 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>860</width>
-    <height>491</height>
+    <width>688</width>
+    <height>456</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout_3" rowstretch="1,0,4">
-   <item row="0" column="1">
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeType">
-      <enum>QSizePolicy::Expanding</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="2" column="1">
-    <spacer name="verticalSpacer_2">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
+  <layout class="QGridLayout" name="gridLayout_3" rowstretch="1,0,0">
+   <item row="2" column="0" colspan="2">
+    <widget class="QWidget" name="widget" native="true">
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="styleSheet">
+         <string notr="true">	border-image: url(:/buttons/progressbar.png);
+</string>
+        </property>
+        <property name="text">
+         <string>&lt;img src=&quot;:/buttons/progressbar_chunk.png&quot; width=&quot;390&quot; height=&quot;20&quot;/&gt;</string>
+        </property>
+        <property name="margin">
+         <number>0</number>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="game_button">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>120</width>
+          <height>45</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>120</width>
+          <height>45</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <family>TRAJAN PRO 3</family>
+          <pointsize>-1</pointsize>
+          <weight>75</weight>
+          <italic>false</italic>
+          <bold>true</bold>
+         </font>
+        </property>
+        <property name="autoFillBackground">
+         <bool>false</bool>
+        </property>
+        <property name="styleSheet">
+         <string notr="true">QPushButton#game_button { 
+	color: white;
+	font: 14px &quot;TRAJAN PRO 3&quot;;
+	font-weight: bold;
+	border-image: url(:/buttons/large-button-active.png) 0 0 0 0 stretch stretch; 
+}
+
+QPushButton#game_button:hover {
+	color: white;
+	border-image: url(:/buttons/large-button-active-pressed.png) 0 0 0 0 stretch stretch; 
+}
+
+QPushButton#game_button:pressed {
+	color: white;
+	border-image: url(:/buttons/large-button-pressed.png) 0 0 0 0 stretch stretch; 
+}
+
+</string>
+        </property>
+        <property name="text">
+         <string notr="true">    ИГРАТЬ    </string>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>0</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="default">
+         <bool>false</bool>
+        </property>
+        <property name="flat">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
    </item>
-   <item row="0" column="2" rowspan="3">
+   <item row="0" column="0" rowspan="2" colspan="2">
     <widget class="QWidget" name="right_column_widget" native="true">
      <layout class="QGridLayout" name="gridLayout_2">
-      <item row="1" column="0">
-       <spacer name="horizontalSpacer_3">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
+      <item row="1" column="1">
+       <widget class="QWidget" name="buttons_widget" native="true">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
         </property>
-        <property name="sizeHint" stdset="0">
+        <property name="minimumSize">
          <size>
-          <width>219</width>
-          <height>20</height>
+          <width>0</width>
+          <height>80</height>
          </size>
         </property>
-       </spacer>
+        <property name="styleSheet">
+         <string notr="true"/>
+        </property>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <property name="spacing">
+          <number>1</number>
+         </property>
+         <property name="leftMargin">
+          <number>1</number>
+         </property>
+         <property name="topMargin">
+          <number>1</number>
+         </property>
+         <property name="rightMargin">
+          <number>1</number>
+         </property>
+         <property name="bottomMargin">
+          <number>1</number>
+         </property>
+        </layout>
+       </widget>
       </item>
       <item row="0" column="0" colspan="2">
        <widget class="QWidget" name="common_status_widget" native="true">
@@ -313,194 +414,9 @@ background-color: rgba(30, 0, 0, 100);</string>
         </layout>
        </widget>
       </item>
-      <item row="1" column="1">
-       <widget class="QWidget" name="buttons_widget" native="true">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>80</height>
-         </size>
-        </property>
-        <property name="styleSheet">
-         <string notr="true">background-color: rgb(0, 0, 84);</string>
-        </property>
-        <layout class="QHBoxLayout" name="horizontalLayout" stretch="1">
-         <property name="spacing">
-          <number>1</number>
-         </property>
-         <property name="leftMargin">
-          <number>1</number>
-         </property>
-         <property name="topMargin">
-          <number>1</number>
-         </property>
-         <property name="rightMargin">
-          <number>1</number>
-         </property>
-         <property name="bottomMargin">
-          <number>1</number>
-         </property>
-         <item>
-          <widget class="QPushButton" name="game_button">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="maximumSize">
-            <size>
-             <width>180</width>
-             <height>16777215</height>
-            </size>
-           </property>
-           <property name="font">
-            <font>
-             <family>Times New Roman</family>
-             <pointsize>-1</pointsize>
-             <weight>75</weight>
-             <italic>false</italic>
-             <bold>true</bold>
-            </font>
-           </property>
-           <property name="autoFillBackground">
-            <bool>false</bool>
-           </property>
-           <property name="styleSheet">
-            <string notr="true">border-image: url(:/assets/buttons/gray-button-hi.png);
-color: rgb(85, 0, 0);
-font: 24px &quot;Times New Roman&quot;;
-font-weight: bold;</string>
-           </property>
-           <property name="text">
-            <string notr="true">    ИГРАТЬ    </string>
-           </property>
-           <property name="iconSize">
-            <size>
-             <width>0</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="default">
-            <bool>false</bool>
-           </property>
-           <property name="flat">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="QWidget" name="left_column_widget" native="true">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <widget class="QWidget" name="status_image_widget" native="true">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="minimumSize">
-         <size>
-          <width>200</width>
-          <height>200</height>
-         </size>
-        </property>
-        <property name="baseSize">
-         <size>
-          <width>200</width>
-          <height>200</height>
-         </size>
-        </property>
-        <property name="styleSheet">
-         <string notr="true">image: url(:/assets/status/info.png);</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QWidget" name="status_label_widget" native="true">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="minimumSize">
-         <size>
-          <width>0</width>
-          <height>40</height>
-         </size>
-        </property>
-        <layout class="QHBoxLayout" name="horizontalLayout_3">
-         <item>
-          <widget class="QLabel" name="status_label_supertitle">
-           <property name="font">
-            <font>
-             <family>Times New Roman</family>
-             <pointsize>28</pointsize>
-             <weight>75</weight>
-             <italic>false</italic>
-             <bold>true</bold>
-            </font>
-           </property>
-           <property name="styleSheet">
-            <string notr="true">color: rgb(85, 170, 255);
-</string>
-           </property>
-           <property name="text">
-            <string>В РАБОТЕ</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignHCenter|Qt::AlignTop</set>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item row="1" column="0">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeType">
-      <enum>QSizePolicy::Fixed</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>40</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
   </layout>
  </widget>
  <resources/>