add: support live retranslation

This commit is contained in:
Qv2ray-dev 2020-02-08 17:15:27 +08:00
parent e236f47a4a
commit 38d94d73d2
27 changed files with 138 additions and 55 deletions

View File

@ -1 +1 @@
3780 3801

View File

@ -138,7 +138,6 @@ Qv2rayAddSource(base, models, QvConfigIdentifier, hpp)
Qv2rayAddSource(base, models, QvSafeType, hpp) Qv2rayAddSource(base, models, QvSafeType, hpp)
Qv2rayAddSource(base, models, QvRuntimeConfig, hpp) Qv2rayAddSource(base, models, QvRuntimeConfig, hpp)
Qv2rayAddSource(base, models, QvStartupConfig, hpp) Qv2rayAddSource(base, models, QvStartupConfig, hpp)
Qv2rayAddSource(base, messaging, QvGlobalMessageBus, cpp, hpp)
Qv2rayAddSource(common, _, CommandArgs, cpp, hpp) Qv2rayAddSource(common, _, CommandArgs, cpp, hpp)
Qv2rayAddSource(common, _, HTTPRequestHelper, cpp, hpp) Qv2rayAddSource(common, _, HTTPRequestHelper, cpp, hpp)
Qv2rayAddSource(common, _, LogHighlighter, cpp, hpp) Qv2rayAddSource(common, _, LogHighlighter, cpp, hpp)
@ -172,6 +171,7 @@ Qv2rayAddSource(ui, nodemodels, InboundNodeModel, cpp, hpp)
Qv2rayAddSource(ui, nodemodels, OutboundNodeModel, cpp, hpp) Qv2rayAddSource(ui, nodemodels, OutboundNodeModel, cpp, hpp)
Qv2rayAddSource(ui, nodemodels, RuleNodeModel, cpp, hpp) Qv2rayAddSource(ui, nodemodels, RuleNodeModel, cpp, hpp)
Qv2rayAddSource(ui, nodemodels, NodeModelsBase, hpp) Qv2rayAddSource(ui, nodemodels, NodeModelsBase, hpp)
Qv2rayAddSource(ui, messaging, QvMessageBus, cpp, hpp)
Qv2rayAddSource(ui, _, w_ExportConfig, cpp, hpp, ui) Qv2rayAddSource(ui, _, w_ExportConfig, cpp, hpp, ui)
Qv2rayAddSource(ui, _, w_ImportConfig, cpp, hpp, ui) Qv2rayAddSource(ui, _, w_ImportConfig, cpp, hpp, ui)
Qv2rayAddSource(ui, _, w_MainWindow, cpp, hpp, ui) Qv2rayAddSource(ui, _, w_MainWindow, cpp, hpp, ui)

View File

@ -3,7 +3,8 @@
#include "base/models/QvRuntimeConfig.hpp" #include "base/models/QvRuntimeConfig.hpp"
#include "base/models/QvStartupConfig.hpp" #include "base/models/QvStartupConfig.hpp"
#include "base/models/QvConfigModel.hpp" #include "base/models/QvConfigModel.hpp"
#include "base/messaging/QvGlobalMessageBus.hpp"
#include <QTranslator>
// Instantiation for Qv2ray global objects. // Instantiation for Qv2ray global objects.
#ifdef QT_DEBUG #ifdef QT_DEBUG
@ -17,9 +18,9 @@ namespace Qv2ray
// Qv2ray runtime config // Qv2ray runtime config
inline bool isExiting = false; inline bool isExiting = false;
inline QString Qv2rayConfigPath = "/"; inline QString Qv2rayConfigPath = "/";
// Danger, new is used here. Possible memory leak (hope not so much leak)
inline base::QvMessageBusObject messageBus = base::QvMessageBusObject();
inline base::Qv2rayRuntimeConfig RuntimeConfig = base::Qv2rayRuntimeConfig(); inline base::Qv2rayRuntimeConfig RuntimeConfig = base::Qv2rayRuntimeConfig();
inline base::config::Qv2rayConfig GlobalConfig = base::config::Qv2rayConfig(); inline base::config::Qv2rayConfig GlobalConfig = base::config::Qv2rayConfig();
inline base::QvStartupOptions StartupOption = base::QvStartupOptions(); inline base::QvStartupOptions StartupOption = base::QvStartupOptions();
//
inline QTranslator *Qv2rayTranslator;
} }

View File

@ -16,7 +16,6 @@
#include "base/Qv2rayFeatures.hpp" #include "base/Qv2rayFeatures.hpp"
#include "base/JsonHelpers.hpp" #include "base/JsonHelpers.hpp"
#include "base/GlobalInstances.hpp" #include "base/GlobalInstances.hpp"
#include "base/messaging/QvGlobalMessageBus.hpp"
// Code Models // Code Models
#include "base/models/QvSafeType.hpp" #include "base/models/QvSafeType.hpp"
#include "base/models/CoreObjectModels.hpp" #include "base/models/CoreObjectModels.hpp"

View File

@ -280,14 +280,11 @@ int main(int argc, char *argv[])
// Not duplicated. // Not duplicated.
// Install a default translater. From the OS/DE // Install a default translater. From the OS/DE
auto _lang = QLocale::system().name(); auto _lang = QLocale::system().name();
auto _sysTranslator = getTranslator(_lang); Qv2rayTranslator = getTranslator(_lang);
//
if (_lang != "en-US") { // Do not install en-US as it's the default language.
// Do not install en-US as it's the default language. bool _result_ = _qApp.installTranslator(Qv2rayTranslator);
bool _result_ = _qApp.installTranslator(_sysTranslator); LOG(UI, "Installing a tranlator from OS: " + _lang + " -- " + (_result_ ? "OK" : "Failed"))
LOG(UI, "Installing a tranlator from OS: " + _lang + " -- " + (_result_ ? "OK" : "Failed"))
}
// //
LOG("LICENCE", NEWLINE "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE LOG("LICENCE", NEWLINE "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE
"This is free software, and you are welcome to redistribute it" NEWLINE "This is free software, and you are welcome to redistribute it" NEWLINE
@ -353,7 +350,7 @@ int main(int argc, char *argv[])
// Load config object from upgraded config QJsonObject // Load config object from upgraded config QJsonObject
auto confObject = StructFromJsonString<Qv2rayConfig>(JsonToString(conf)); auto confObject = StructFromJsonString<Qv2rayConfig>(JsonToString(conf));
// Remove system translator, for loading custom translations. // Remove system translator, for loading custom translations.
qApp->removeTranslator(_sysTranslator); qApp->removeTranslator(Qv2rayTranslator);
LOG(INIT, "Removed system translations") LOG(INIT, "Removed system translations")
if (confObject.uiConfig.language.isEmpty()) { if (confObject.uiConfig.language.isEmpty()) {
@ -362,7 +359,9 @@ int main(int argc, char *argv[])
confObject.uiConfig.language = "en-US"; confObject.uiConfig.language = "en-US";
} }
if (qApp->installTranslator(getTranslator(confObject.uiConfig.language))) { Qv2rayTranslator = getTranslator(confObject.uiConfig.language);
if (qApp->installTranslator(Qv2rayTranslator)) {
LOG(INIT, "Successfully installed a translator for " + confObject.uiConfig.language) LOG(INIT, "Successfully installed a translator for " + confObject.uiConfig.language)
} else { } else {
// Do not translate these..... // Do not translate these.....

View File

@ -39,7 +39,14 @@ InboundEditor::InboundEditor(INBOUND root, QWidget *parent) :
LoadUIData(); LoadUIData();
} }
QvMessageBusSlotImplDefault(InboundEditor) QvMessageBusSlotImpl(InboundEditor)
{
switch (msg) {
QvMessageBusShowDefault\
QvMessageBusHideDefault\
QvMessageBusRetranslateDefault\
}
}
INBOUND InboundEditor::OpenEditor() INBOUND InboundEditor::OpenEditor()
{ {

View File

@ -5,6 +5,7 @@
#include <QListWidgetItem> #include <QListWidgetItem>
#include "ui_w_InboundEditor.h" #include "ui_w_InboundEditor.h"
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "ui/messaging/QvMessageBus.hpp"
class InboundEditor : public QDialog, private Ui::InboundEditor class InboundEditor : public QDialog, private Ui::InboundEditor
{ {

View File

@ -24,7 +24,14 @@ JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) :
jsonTree->resizeColumnToContents(0); jsonTree->resizeColumnToContents(0);
} }
QvMessageBusSlotImplDefault(JsonEditor) QvMessageBusSlotImpl(JsonEditor)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
QJsonObject JsonEditor::OpenEditor() QJsonObject JsonEditor::OpenEditor()
{ {

View File

@ -5,6 +5,7 @@
#include "common/QJsonModel.hpp" #include "common/QJsonModel.hpp"
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "ui_w_JsonEditor.h" #include "ui_w_JsonEditor.h"
#include "ui/messaging/QvMessageBus.hpp"
class JsonEditor : public QDialog, private Ui::JsonEditor class JsonEditor : public QDialog, private Ui::JsonEditor
{ {

View File

@ -38,7 +38,14 @@ OutboundEditor::OutboundEditor(QWidget *parent)
Result = GenerateConnectionJson(); Result = GenerateConnectionJson();
} }
QvMessageBusSlotImplDefault(OutboundEditor) QvMessageBusSlotImpl(OutboundEditor)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
OutboundEditor::OutboundEditor(OUTBOUND outboundEntry, QWidget *parent) : OutboundEditor(parent) OutboundEditor::OutboundEditor(OUTBOUND outboundEntry, QWidget *parent) : OutboundEditor(parent)
{ {

View File

@ -4,6 +4,7 @@
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "ui_w_OutboundEditor.h" #include "ui_w_OutboundEditor.h"
#include "ui/widgets/StreamSettingsWidget.hpp" #include "ui/widgets/StreamSettingsWidget.hpp"
#include "ui/messaging/QvMessageBus.hpp"
class OutboundEditor : public QDialog, private Ui::OutboundEditor class OutboundEditor : public QDialog, private Ui::OutboundEditor
{ {

View File

@ -121,7 +121,14 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QDialog(pare
isLoading = false; isLoading = false;
} }
QvMessageBusSlotImplDefault(RouteEditor) QvMessageBusSlotImpl(RouteEditor)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
void RouteEditor::onNodeClicked(Node &n) void RouteEditor::onNodeClicked(Node &n)
{ {

View File

@ -17,6 +17,7 @@ using QtNodes::FlowScene;
using QtNodes::ConnectionStyle; using QtNodes::ConnectionStyle;
#include "ui_w_RoutesEditor.h" #include "ui_w_RoutesEditor.h"
#include "ui/messaging/QvMessageBus.hpp"
enum ROUTE_EDIT_MODE { enum ROUTE_EDIT_MODE {
RENAME_INBOUND, RENAME_INBOUND,

View File

@ -1,9 +1,9 @@
#include <QMetaEnum> #include <QMetaEnum>
#include "QvGlobalMessageBus.hpp" #include "QvMessageBus.hpp"
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
namespace Qv2ray::base namespace Qv2ray::ui::messaging
{ {
QvMessageBusObject::QvMessageBusObject() QvMessageBusObject::QvMessageBusObject()
{ {

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
#define QvMessageBusConnect(CLASSNAME) connect(&::Qv2ray::messageBus, &::Qv2ray::base::QvMessageBusObject::QvSendMessage, this, &CLASSNAME::on_QvMessageReceived) #define QvMessageBusConnect(CLASSNAME) connect(&messageBus, &QvMessageBusObject::QvSendMessage, this, &CLASSNAME::on_QvMessageReceived)
#define QvMessageBusSlotHeader void on_QvMessageReceived(::Qv2ray::base::QvMessage msg); #define QvMessageBusSlotHeader void on_QvMessageReceived(QvMessage msg);
#define QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::on_QvMessageReceived(::Qv2ray::base::QvMessage msg) #define QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::on_QvMessageReceived(QvMessage msg)
#define QvMessageBusShowDefault \ #define QvMessageBusShowDefault \
case SHOW_WINDOWS:\ case SHOW_WINDOWS:\
@ -18,20 +18,12 @@
#define QvMessageBusRetranslateDefault \ #define QvMessageBusRetranslateDefault \
case RETRANSLATE:\ case RETRANSLATE:\
this->retranslateUi(this);\ {\
this->retranslateUi(this);\
}\
break; break;
#define QvMessageBusSlotImplDefault(CLASSNAME) \ namespace Qv2ray::ui::messaging
QvMessageBusSlotImpl(CLASSNAME)\
{\
switch (msg) {\
QvMessageBusShowDefault\
QvMessageBusHideDefault\
QvMessageBusRetranslateDefault\
}\
}
namespace Qv2ray::base
{ {
Q_NAMESPACE Q_NAMESPACE
enum QvMessage { enum QvMessage {
@ -59,6 +51,9 @@ namespace Qv2ray::base
private slots: private slots:
void on_QvMessageReceived(QvMessage msg); void on_QvMessageReceived(QvMessage msg);
}; };
// Danger, new is used here. Possible memory leak (hope not so much leak)
inline QvMessageBusObject messageBus = QvMessageBusObject();
} }
using namespace Qv2ray::base; using namespace Qv2ray::ui::messaging;

View File

@ -12,7 +12,14 @@ ConfigExporter::ConfigExporter(QWidget *parent) :
QvMessageBusConnect(ConfigExporter); QvMessageBusConnect(ConfigExporter);
} }
QvMessageBusSlotImplDefault(ConfigExporter) QvMessageBusSlotImpl(ConfigExporter)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
ConfigExporter::~ConfigExporter() ConfigExporter::~ConfigExporter()
{ {

View File

@ -3,6 +3,7 @@
#include "ui_w_ExportConfig.h" #include "ui_w_ExportConfig.h"
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "3rdparty/qzxing/src/QZXing.h" #include "3rdparty/qzxing/src/QZXing.h"
#include "ui/messaging/QvMessageBus.hpp"
class ConfigExporter : public QDialog, private Ui::ExportConfigWindow class ConfigExporter : public QDialog, private Ui::ExportConfigWindow
{ {

View File

@ -28,7 +28,14 @@ ImportConfigWindow::ImportConfigWindow(QWidget *parent)
RESTORE_RUNTIME_CONFIG(screenShotHideQv2ray, hideQv2rayCB->setChecked) RESTORE_RUNTIME_CONFIG(screenShotHideQv2ray, hideQv2rayCB->setChecked)
} }
QvMessageBusSlotImplDefault(ImportConfigWindow) QvMessageBusSlotImpl(ImportConfigWindow)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
ImportConfigWindow::~ImportConfigWindow() ImportConfigWindow::~ImportConfigWindow()
{ {
@ -58,6 +65,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
messageBus.EmitGlobalSignal(QvMessage::HIDE_WINDOWS); messageBus.EmitGlobalSignal(QvMessage::HIDE_WINDOWS);
} }
QApplication::processEvents();
QThread::msleep(static_cast<ulong>(doubleSpinBox->value() * 1000)); QThread::msleep(static_cast<ulong>(doubleSpinBox->value() * 1000));
auto w = new ScreenShotWindow(); auto w = new ScreenShotWindow();
auto pix = w->DoScreenShot(); auto pix = w->DoScreenShot();

View File

@ -5,6 +5,7 @@
#include <QJsonObject> #include <QJsonObject>
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "ui_w_ImportConfig.h" #include "ui_w_ImportConfig.h"
#include "ui/messaging/QvMessageBus.hpp"
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
{ {

View File

@ -79,7 +79,14 @@
MainWindow *MainWindow::mwInstance = nullptr; MainWindow *MainWindow::mwInstance = nullptr;
QvMessageBusSlotImplDefault(MainWindow) QvMessageBusSlotImpl(MainWindow)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
MainWindow::MainWindow(QWidget *parent): MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent), vinstance(), QMainWindow(parent), vinstance(),

View File

@ -18,6 +18,8 @@
#include "components/pac/QvPACHandler.hpp" #include "components/pac/QvPACHandler.hpp"
#include "components/speedchart/speedwidget.hpp" #include "components/speedchart/speedwidget.hpp"
#include "ui/messaging/QvMessageBus.hpp"
enum QvConnectionType { enum QvConnectionType {
CONNECTION_REGULAR = 1, CONNECTION_REGULAR = 1,
CONNECTION_SUBSCRIPTION = 2 CONNECTION_SUBSCRIPTION = 2

View File

@ -20,7 +20,7 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
CurrentConfig() CurrentConfig()
{ {
setupUi(this); setupUi(this);
QvMsgBusSlot(QvMsgBusImplDefault) QvMessageBusConnect(PreferencesWindow);
textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html"))); textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html")));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
// //
@ -187,6 +187,16 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
finishedLoading = true; finishedLoading = true;
} }
QvMessageBusSlotImpl(PreferencesWindow)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
PreferencesWindow::~PreferencesWindow() PreferencesWindow::~PreferencesWindow()
{ {
} }
@ -222,6 +232,19 @@ void PreferencesWindow::on_buttonBox_accepted()
this->show(); this->show();
this->exec(); this->exec();
} else { } else {
if (CurrentConfig.uiConfig.language != GlobalConfig.uiConfig.language) {
qApp->removeTranslator(Qv2rayTranslator);
Qv2rayTranslator = getTranslator(CurrentConfig.uiConfig.language);
// Install translator
if (!qApp->installTranslator(Qv2rayTranslator)) {
LOG(UI, "Failed to translate UI to: " + CurrentConfig.uiConfig.language)
} else {
messageBus.EmitGlobalSignal(QvMessage::RETRANSLATE);
QApplication::processEvents();
}
}
SaveGlobalConfig(CurrentConfig); SaveGlobalConfig(CurrentConfig);
emit s_reload_config(IsConnectionPropertyChanged); emit s_reload_config(IsConnectionPropertyChanged);
} }

View File

@ -3,6 +3,7 @@
#include <QDialog> #include <QDialog>
#include <ui_w_PreferencesWindow.h> #include <ui_w_PreferencesWindow.h>
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "ui/messaging/QvMessageBus.hpp"
class PreferencesWindow : public QDialog, private Ui::PreferencesWindow class PreferencesWindow : public QDialog, private Ui::PreferencesWindow
{ {
@ -14,6 +15,9 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow
signals: signals:
void s_reload_config(bool need_restart); void s_reload_config(bool need_restart);
public slots:
QvMessageBusSlotHeader
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();

View File

@ -160,16 +160,6 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<item>
<property name="text">
<string>zh-CN</string>
</property>
</item>
<item>
<property name="text">
<string>en-US</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">

View File

@ -32,7 +32,8 @@ QImage ScreenShotWindow::DoScreenShot()
LOG(IMPORT, "We currently only support the current screen.") LOG(IMPORT, "We currently only support the current screen.")
// The msleep is the only solution which prevent capturing our windows again. // The msleep is the only solution which prevent capturing our windows again.
// It works on KDE, https://www.qtcentre.org/threads/55708-Get-Desktop-Screenshot-Without-Application-Window-Being-Shown?p=248993#post248993 // It works on KDE, https://www.qtcentre.org/threads/55708-Get-Desktop-Screenshot-Without-Application-Window-Being-Shown?p=248993#post248993
QThread::msleep(250); QThread::msleep(100);
QApplication::processEvents();
// //
auto pos = QCursor::pos(); auto pos = QCursor::pos();
desktopImage = QGuiApplication::screenAt(pos)->grabWindow(0); desktopImage = QGuiApplication::screenAt(pos)->grabWindow(0);

View File

@ -9,7 +9,7 @@ SubscribeEditor::SubscribeEditor(QWidget *parent) :
QDialog(parent) QDialog(parent)
{ {
setupUi(this); setupUi(this);
QvMsgBusSlot(QvMsgBusImplDefault) QvMessageBusConnect(SubscribeEditor);
addSubsButton->setIcon(QICON_R("add.png")); addSubsButton->setIcon(QICON_R("add.png"));
removeSubsButton->setIcon(QICON_R("delete.png")); removeSubsButton->setIcon(QICON_R("delete.png"));
@ -20,6 +20,15 @@ SubscribeEditor::SubscribeEditor(QWidget *parent) :
LoadSubscriptionList(subscriptions); LoadSubscriptionList(subscriptions);
} }
QvMessageBusSlotImpl(SubscribeEditor)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
QPair<QString, CONFIGROOT> SubscribeEditor::GetSelectedConfig() QPair<QString, CONFIGROOT> SubscribeEditor::GetSelectedConfig()
{ {
return currentSelectedConfig; return currentSelectedConfig;

View File

@ -3,8 +3,9 @@
#include <QDialog> #include <QDialog>
#include "base/Qv2rayBase.hpp" #include "base/Qv2rayBase.hpp"
#include "common/HTTPRequestHelper.hpp" #include "common/HTTPRequestHelper.hpp"
#include "ui_w_SubscriptionManager.h" #include "ui_w_SubscriptionManager.h"
#include "ui/messaging/QvMessageBus.hpp"
class SubscribeEditor : public QDialog, private Ui::w_SubscribeEditor class SubscribeEditor : public QDialog, private Ui::w_SubscribeEditor
{ {
Q_OBJECT Q_OBJECT
@ -14,6 +15,9 @@ class SubscribeEditor : public QDialog, private Ui::w_SubscribeEditor
~SubscribeEditor(); ~SubscribeEditor();
QPair<QString, CONFIGROOT> GetSelectedConfig(); QPair<QString, CONFIGROOT> GetSelectedConfig();
public slots:
QvMessageBusSlotHeader
private slots: private slots:
void on_addSubsButton_clicked(); void on_addSubsButton_clicked();