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, QvRuntimeConfig, hpp)
Qv2rayAddSource(base, models, QvStartupConfig, hpp)
Qv2rayAddSource(base, messaging, QvGlobalMessageBus, cpp, hpp)
Qv2rayAddSource(common, _, CommandArgs, cpp, hpp)
Qv2rayAddSource(common, _, HTTPRequestHelper, 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, RuleNodeModel, cpp, hpp)
Qv2rayAddSource(ui, nodemodels, NodeModelsBase, hpp)
Qv2rayAddSource(ui, messaging, QvMessageBus, cpp, hpp)
Qv2rayAddSource(ui, _, w_ExportConfig, cpp, hpp, ui)
Qv2rayAddSource(ui, _, w_ImportConfig, cpp, hpp, ui)
Qv2rayAddSource(ui, _, w_MainWindow, cpp, hpp, ui)

View File

@ -3,7 +3,8 @@
#include "base/models/QvRuntimeConfig.hpp"
#include "base/models/QvStartupConfig.hpp"
#include "base/models/QvConfigModel.hpp"
#include "base/messaging/QvGlobalMessageBus.hpp"
#include <QTranslator>
// Instantiation for Qv2ray global objects.
#ifdef QT_DEBUG
@ -17,9 +18,9 @@ namespace Qv2ray
// Qv2ray runtime config
inline bool isExiting = false;
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::config::Qv2rayConfig GlobalConfig = base::config::Qv2rayConfig();
inline base::QvStartupOptions StartupOption = base::QvStartupOptions();
//
inline QTranslator *Qv2rayTranslator;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,10 @@
#pragma once
#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 QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::on_QvMessageReceived(::Qv2ray::base::QvMessage msg)
#define QvMessageBusSlotHeader void on_QvMessageReceived(QvMessage msg);
#define QvMessageBusSlotImpl(CLASSNAME) void CLASSNAME::on_QvMessageReceived(QvMessage msg)
#define QvMessageBusShowDefault \
case SHOW_WINDOWS:\
@ -18,20 +18,12 @@
#define QvMessageBusRetranslateDefault \
case RETRANSLATE:\
{\
this->retranslateUi(this);\
}\
break;
#define QvMessageBusSlotImplDefault(CLASSNAME) \
QvMessageBusSlotImpl(CLASSNAME)\
{\
switch (msg) {\
QvMessageBusShowDefault\
QvMessageBusHideDefault\
QvMessageBusRetranslateDefault\
}\
}
namespace Qv2ray::base
namespace Qv2ray::ui::messaging
{
Q_NAMESPACE
enum QvMessage {
@ -59,6 +51,9 @@ namespace Qv2ray::base
private slots:
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);
}
QvMessageBusSlotImplDefault(ConfigExporter)
QvMessageBusSlotImpl(ConfigExporter)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
ConfigExporter::~ConfigExporter()
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
CurrentConfig()
{
setupUi(this);
QvMsgBusSlot(QvMsgBusImplDefault)
QvMessageBusConnect(PreferencesWindow);
textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html")));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
//
@ -187,6 +187,16 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
finishedLoading = true;
}
QvMessageBusSlotImpl(PreferencesWindow)
{
switch (msg) {
QvMessageBusShowDefault
QvMessageBusHideDefault
QvMessageBusRetranslateDefault
}
}
PreferencesWindow::~PreferencesWindow()
{
}
@ -222,6 +232,19 @@ void PreferencesWindow::on_buttonBox_accepted()
this->show();
this->exec();
} 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);
emit s_reload_config(IsConnectionPropertyChanged);
}

View File

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

View File

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

View File

@ -32,7 +32,8 @@ QImage ScreenShotWindow::DoScreenShot()
LOG(IMPORT, "We currently only support the current screen.")
// 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
QThread::msleep(250);
QThread::msleep(100);
QApplication::processEvents();
//
auto pos = QCursor::pos();
desktopImage = QGuiApplication::screenAt(pos)->grabWindow(0);

View File

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

View File

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