summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-05-15 23:19:46 +0800
committerGitHub <[email protected]>2024-05-15 23:19:46 +0800
commita88318a2a9ca5f28ac330e3046703babe182c2ad (patch)
tree582aa96d4ea046073d40c9367f6d4c7b4efc4d47
parent304943e79b6e2c67d2c010f053d8cd2a42460ddd (diff)
parent81be0de6945e4633693a0f8306f1a95446cf3794 (diff)
Merge pull request #5103 from 1143910315/support-qt-translation
add qt ts files building
-rw-r--r--tests/projects/qt/with_ts/src/demo_zh_CN.ts17
-rw-r--r--tests/projects/qt/with_ts/src/demo_zh_TW.ts17
-rw-r--r--tests/projects/qt/with_ts/src/main.cpp23
-rw-r--r--tests/projects/qt/with_ts/src/mainwindow.cpp13
-rw-r--r--tests/projects/qt/with_ts/src/mainwindow.h22
-rw-r--r--tests/projects/qt/with_ts/src/mainwindow.ui35
-rw-r--r--tests/projects/qt/with_ts/xmake.lua9
-rw-r--r--xmake/plugins/project/vsxmake/vsxmake.lua3
-rw-r--r--xmake/rules/qt/ts/xmake.lua58
-rw-r--r--xmake/rules/qt/xmake.lua16
-rw-r--r--xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/#target#.vcxproj.filters1
-rw-r--r--xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/File.ts(filets)3
-rw-r--r--xmake/scripts/vsxmake/vsproj/templates/vcxproj/#target#.vcxproj1
-rw-r--r--xmake/scripts/vsxmake/vsproj/templates/vcxproj/File.ts(filets)1
14 files changed, 211 insertions, 8 deletions
diff --git a/tests/projects/qt/with_ts/src/demo_zh_CN.ts b/tests/projects/qt/with_ts/src/demo_zh_CN.ts
new file mode 100644
index 000000000..b712a0c4d
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/demo_zh_CN.ts
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="mainwindow.ui" line="14"/>
+ <source>MainWindow</source>
+ <translation>主窗口</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="27"/>
+ <source>PushButton</source>
+ <translation>按钮</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/projects/qt/with_ts/src/demo_zh_TW.ts b/tests/projects/qt/with_ts/src/demo_zh_TW.ts
new file mode 100644
index 000000000..338b5c32e
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/demo_zh_TW.ts
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_TW">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="mainwindow.ui" line="14"/>
+ <source>MainWindow</source>
+ <translation>主視窗</translation>
+ </message>
+ <message>
+ <location filename="mainwindow.ui" line="27"/>
+ <source>PushButton</source>
+ <translation>按鈕</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/projects/qt/with_ts/src/main.cpp b/tests/projects/qt/with_ts/src/main.cpp
new file mode 100644
index 000000000..6da7ba1ea
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/main.cpp
@@ -0,0 +1,23 @@
+#include "mainwindow.h"
+#include <QApplication>
+#include <QLocale>
+#include <QTranslator>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ QTranslator translator;
+ const QStringList uiLanguages = QLocale::system().uiLanguages();
+ for (const QString& locale : uiLanguages) {
+ const QString baseName = "demo_" + QLocale(locale).name();
+ if (translator.load(baseName + ".qm")) {
+ a.installTranslator(&translator);
+ break;
+ }
+ }
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/tests/projects/qt/with_ts/src/mainwindow.cpp b/tests/projects/qt/with_ts/src/mainwindow.cpp
new file mode 100644
index 000000000..ec2cba1ee
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/mainwindow.cpp
@@ -0,0 +1,13 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
diff --git a/tests/projects/qt/with_ts/src/mainwindow.h b/tests/projects/qt/with_ts/src/mainwindow.h
new file mode 100644
index 000000000..8e06f4918
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/mainwindow.h
@@ -0,0 +1,22 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private:
+ Ui::MainWindow *ui;
+};
+
+#endif // MAINWINDOW_H
diff --git a/tests/projects/qt/with_ts/src/mainwindow.ui b/tests/projects/qt/with_ts/src/mainwindow.ui
new file mode 100644
index 000000000..6bbe2c1fc
--- /dev/null
+++ b/tests/projects/qt/with_ts/src/mainwindow.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>90</y>
+ <width>75</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/projects/qt/with_ts/xmake.lua b/tests/projects/qt/with_ts/xmake.lua
new file mode 100644
index 000000000..bc9bdaffc
--- /dev/null
+++ b/tests/projects/qt/with_ts/xmake.lua
@@ -0,0 +1,9 @@
+add_rules("mode.debug", "mode.release")
+
+target("demo")
+ add_rules("qt.widgetapp")
+ add_headerfiles("src/*.h")
+ add_files("src/*.cpp")
+ add_files("src/mainwindow.ui")
+ add_files("src/mainwindow.h")
+ add_files("src/*.ts")
diff --git a/xmake/plugins/project/vsxmake/vsxmake.lua b/xmake/plugins/project/vsxmake/vsxmake.lua
index bae206cee..2b3ded5d6 100644
--- a/xmake/plugins/project/vsxmake/vsxmake.lua
+++ b/xmake/plugins/project/vsxmake/vsxmake.lua
@@ -142,6 +142,9 @@ function _buildparams(info, target, default)
elseif args.fileqrc then -- for qt/.qrc
local files = info._targets[target].sourcefiles
table.insert(r, _filter_files(files, {".qrc"}))
+ elseif args.filets then -- for qt/.ts
+ local files = info._targets[target].sourcefiles
+ table.insert(r, _filter_files(files, {".ts"}))
elseif args.incc then
local files = table.join(info._targets[target].headerfiles or {}, info._targets[target].extrafiles)
table.insert(r, _filter_files(files, nil, {".natvis"}))
diff --git a/xmake/rules/qt/ts/xmake.lua b/xmake/rules/qt/ts/xmake.lua
new file mode 100644
index 000000000..289f1fa60
--- /dev/null
+++ b/xmake/rules/qt/ts/xmake.lua
@@ -0,0 +1,58 @@
+rule("qt.ts")
+ add_deps("qt.env")
+ set_extensions(".ts")
+
+ on_config(function (target)
+ -- get source file
+ local lupdate_argv = {"-no-obsolete"}
+ local sourcefile_ts
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ if sourcebatch.rulename == "qt.ts" then
+ sourcefile_ts = sourcebatch.sourcefiles
+ else
+ if sourcebatch.sourcefiles then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ table.join2(lupdate_argv, path(sourcefile))
+ end
+ end
+ end
+ end
+ if sourcefile_ts then
+ -- get lupdate and lrelease
+ local qt = assert(target:data("qt"), "qt not found!")
+ local lupdate = path.join(qt.bindir, is_host("windows") and "lupdate.exe" or "lupdate")
+ local lrelease = path.join(qt.bindir, is_host("windows") and "lrelease.exe" or "lrelease")
+ if not os.isexec(lupdate) and qt.libexecdir then
+ lupdate = path.join(qt.libexecdir, is_host("windows") and "lupdate.exe" or "lupdate")
+ end
+ if not os.isexec(lrelease) and qt.libexecdir then
+ lrelease = path.join(qt.libexecdir, is_host("windows") and "lrelease.exe" or "lrelease")
+ end
+ if not os.isexec(lupdate) and qt.libexecdir_host then
+ lupdate = path.join(qt.libexecdir_host, is_host("windows") and "lupdate.exe" or "lupdate")
+ end
+ if not os.isexec(lrelease) and qt.libexecdir_host then
+ lrelease = path.join(qt.libexecdir_host, is_host("windows") and "lrelease.exe" or "lrelease")
+ end
+ assert(os.isexec(lupdate), "lupdate not found!")
+ assert(os.isexec(lrelease), "lrelease not found!")
+ for _, tsfile in ipairs(sourcefile_ts) do
+ local tsargv = {}
+ table.join2(tsargv, lupdate_argv)
+ table.join2(tsargv, {"-ts", path(tsfile)})
+ os.vrunv(lupdate, tsargv)
+ end
+ -- save lrelease
+ target:data_set("qt.ts.lrelease", lrelease)
+ end
+ end)
+
+ before_buildcmd_file(function (target, batchcmds, sourcefile_ts, opt)
+ -- get lrelease
+ local lrelease = target:data("qt.ts.lrelease")
+ local outfile = path.join(target:targetdir(), path.basename(sourcefile_ts) .. ".qm")
+ batchcmds:mkdir(target:targetdir())
+ batchcmds:show_progress(opt.progress, "${color.build.object}compiling.qt.ts %s", sourcefile_ts)
+ batchcmds:vrunv(lrelease, {path(sourcefile_ts), "-qm", path(outfile)})
+ batchcmds:add_depfiles(sourcefile_ts)
+ end) \ No newline at end of file
diff --git a/xmake/rules/qt/xmake.lua b/xmake/rules/qt/xmake.lua
index 598a67343..9437b4b47 100644
--- a/xmake/rules/qt/xmake.lua
+++ b/xmake/rules/qt/xmake.lua
@@ -38,7 +38,7 @@ rule("qt._wasm_app")
-- define rule: qt static library
rule("qt.static")
- add_deps("qt.qrc", "qt.ui", "qt.moc")
+ add_deps("qt.qrc", "qt.ui", "qt.moc", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -51,7 +51,7 @@ rule("qt.static")
-- define rule: qt shared library
rule("qt.shared")
- add_deps("qt.qrc", "qt.ui", "qt.moc")
+ add_deps("qt.qrc", "qt.ui", "qt.moc", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -64,7 +64,7 @@ rule("qt.shared")
-- define rule: qt console
rule("qt.console")
- add_deps("qt.qrc", "qt.ui", "qt.moc")
+ add_deps("qt.qrc", "qt.ui", "qt.moc", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -80,7 +80,7 @@ rule("qt.console")
-- define rule: qt widgetapp
rule("qt.widgetapp")
- add_deps("qt.ui", "qt.moc", "qt._wasm_app", "qt.qrc")
+ add_deps("qt.ui", "qt.moc", "qt._wasm_app", "qt.qrc", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -115,7 +115,7 @@ rule("qt.widgetapp")
-- define rule: qt static widgetapp
rule("qt.widgetapp_static")
- add_deps("qt.ui", "qt.moc", "qt._wasm_app", "qt.qrc")
+ add_deps("qt.ui", "qt.moc", "qt._wasm_app", "qt.qrc", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -143,7 +143,7 @@ rule("qt.widgetapp_static")
-- define rule: qt quickapp
rule("qt.quickapp")
- add_deps("qt.qrc", "qt.moc", "qt._wasm_app")
+ add_deps("qt.qrc", "qt.moc", "qt._wasm_app", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -165,7 +165,7 @@ rule("qt.quickapp")
-- define rule: qt static quickapp
rule("qt.quickapp_static")
- add_deps("qt.qrc", "qt.moc", "qt._wasm_app")
+ add_deps("qt.qrc", "qt.moc", "qt._wasm_app", "qt.ts")
-- we must set kind before target.on_load(), may we will use target in on_load()
on_load(function (target)
@@ -189,7 +189,7 @@ rule("qt.quickapp_static")
-- define rule: qt qmlplugin
rule("qt.qmlplugin")
- add_deps("qt.shared", "qt.qmltyperegistrar")
+ add_deps("qt.shared", "qt.qmltyperegistrar", "qt.ts")
on_config(function(target)
import("load")(target, {frameworks = { "QtCore", "QtGui", "QtQuick", "QtQml", "QtNetwork" }})
end)
diff --git a/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/#target#.vcxproj.filters b/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/#target#.vcxproj.filters
index 217e32ed5..998c8af83 100644
--- a/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/#target#.vcxproj.filters
+++ b/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/#target#.vcxproj.filters
@@ -48,6 +48,7 @@
#Import(File.rc)#
#Import(File.ui)#
#Import(File.qrc)#
+#Import(File.ts)#
</ItemGroup>
<Import Condition="Exists('$(MSBuildThisFileDirectory)\Xmake.Custom.files.filters')"
Project="$(MSBuildThisFileDirectory)\Xmake.Custom.files.filters" />
diff --git a/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/File.ts(filets) b/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/File.ts(filets)
new file mode 100644
index 000000000..21c6c4691
--- /dev/null
+++ b/xmake/scripts/vsxmake/vsproj/templates/vcxproj.filters/File.ts(filets)
@@ -0,0 +1,3 @@
+ <QtTranslation Include="#path#">
+ <Filter>#dir#</Filter>
+ </QtTranslation>
diff --git a/xmake/scripts/vsxmake/vsproj/templates/vcxproj/#target#.vcxproj b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/#target#.vcxproj
index 40b594b18..1918f4997 100644
--- a/xmake/scripts/vsxmake/vsproj/templates/vcxproj/#target#.vcxproj
+++ b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/#target#.vcxproj
@@ -48,6 +48,7 @@
#Import(File.rc)#
#Import(File.ui)#
#Import(File.qrc)#
+#Import(File.ts)#
</ItemGroup>
<!-- <ItemGroup>
#Import(ProjectRef)#
diff --git a/xmake/scripts/vsxmake/vsproj/templates/vcxproj/File.ts(filets) b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/File.ts(filets)
new file mode 100644
index 000000000..e2a7615b8
--- /dev/null
+++ b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/File.ts(filets)
@@ -0,0 +1 @@
+ <QtTranslation Include="#path#" />