diff --git a/3rdparty/Qt5QMLPlugin b/3rdparty/Qt5QMLPlugin
index eeefdd7..fd7734e 160000
--- a/3rdparty/Qt5QMLPlugin
+++ b/3rdparty/Qt5QMLPlugin
@@ -1 +1 @@
-Subproject commit eeefdd757e64fae21449d4de3706072385e66b12
+Subproject commit fd7734e79071d0acc1286004dc53db8c9b8c5a1a
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index 4a96338..73e9a56 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -31,7 +31,10 @@ endif()
# Find Qt package
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
-find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick REQUIRED)
+find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick LinguistTools REQUIRED)
+
+# List all ts files to be used in the project
+set(ts_files i18n/${PROJECT_NAME}_zh_CN.ts i18n/${PROJECT_NAME}_en_US.ts)
# Source and QML files
set(sources_files example.cpp)
@@ -56,6 +59,31 @@ list(APPEND source_files ${CMAKE_CURRENT_BINARY_DIR}/${__example_project_version
qt_add_executable(${PROJECT_NAME}
${sources_files})
+# Add i18n files
+set_source_files_properties(${ts_files} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/i18n)
+
+if(QT_VERSION VERSION_LESS 6.0)
+ qt5_create_translation_plus(qm_files ${CMAKE_CURRENT_SOURCE_DIR} ${ts_files})
+ foreach(qm_file ${qm_files})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" r_qm_file ${qm_file})
+ list(APPEND r_qm_files ${r_qm_file})
+ endforeach()
+ qt5_add_resources_plus(${PROJECT_NAME} "${PROJECT_NAME}-translations"
+ PREFIX "/"
+ FILES ${r_qm_files}
+ )
+else()
+ qt6_create_translation(qm_files ${CMAKE_CURRENT_SOURCE_DIR} ${ts_files})
+ foreach(qm_file ${qm_files})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" r_qm_file ${qm_file})
+ list(APPEND r_qm_files ${r_qm_file})
+ endforeach()
+ qt6_add_resources(${PROJECT_NAME} "${PROJECT_NAME}-translations"
+ PREFIX "/"
+ FILES ${r_qm_files}
+ )
+endif()
+
# Windows-specific settings
if (WIN32)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../.cmake/win_app.rc.in ${CMAKE_BINARY_DIR}/win_app.rc)
diff --git a/example/i18n/RibbonUIAPP_en_US.ts b/example/i18n/RibbonUIAPP_en_US.ts
new file mode 100644
index 0000000..25d70b7
--- /dev/null
+++ b/example/i18n/RibbonUIAPP_en_US.ts
@@ -0,0 +1,495 @@
+
+
+
+
+ RibbonMessageListViewExample
+
+
+
+ Message List View Example
+
+
+
+
+
+ Add Message
+
+
+
+
+
+ Clear Message
+
+
+
+
+ SettingsMenuPage
+
+
+
+ Settings
+
+
+
+
+
+ Theme
+
+
+
+
+
+ Current Theme:
+
+
+
+
+
+ Current Style:
+
+
+
+
+
+ Style
+
+
+
+
+
+ Modern
+
+
+
+
+
+ Classic
+
+
+
+
+
+ Text Render
+
+
+
+
+
+ Current Text Render:
+
+
+
+
+
+ TitleBar
+
+
+
+
+
+ Show TitleBar Icon:
+
+
+
+
+
+ Language
+
+
+
+
+
+ Current Language:
+
+
+
+
+ TabBar
+
+
+
+ Basic
+
+
+
+
+
+ Slider
+
+
+
+
+
+ Switch Button
+
+
+
+
+
+ CheckBox
+
+
+
+
+
+ Button
+
+
+
+
+
+ Push Button
+
+
+
+
+
+
+
+ No Menu
+
+
+
+
+
+
+
+
+
+ Menu
+
+
+
+
+
+ Radio Button
+
+
+
+
+
+ Input
+
+
+
+
+
+ Line Edit
+
+
+
+
+
+ Text Edit
+
+
+
+
+
+ Combo Box
+
+
+
+
+
+ Spin Box
+
+
+
+
+
+ Progress
+
+
+
+
+
+ ProgressBar
+
+
+
+
+
+ ProgressRing
+
+
+
+
+
+ Indicator
+
+
+
+
+
+ BusyRing
+
+
+
+
+
+ BusyBar
+
+
+
+
+
+ PageIndicator
+
+
+
+
+
+ Views
+
+
+
+
+
+ MessageListView
+
+
+
+
+
+ Open Message List View
+
+
+
+
+
+ Others
+
+
+
+
+
+ Text
+
+
+
+
+
+ Open Menu
+
+
+
+
+
+ Popup
+
+
+
+
+
+ Open Popup
+
+
+
+
+
+ Open Popup Dialog (Double Choices)
+
+
+
+
+
+ Open Popup Dialog (Triple Choices)
+
+
+
+
+
+ MessageBar
+
+
+
+
+
+ Generate One Message
+
+
+
+
+
+ Clear All Messages
+
+
+
+
+ about
+
+
+
+ About
+
+
+
+
+ example
+
+
+
+ RibbonUI APP
+
+
+
+
+
+ Tab Bar
+
+
+
+
+
+ A tab bar for window, let user choose the controllers.
+
+
+
+
+
+ Tab Bar Buttons
+
+
+
+
+
+ Tool buttons at the top of tab bar.
+
+
+
+
+
+ Sliders
+
+
+
+
+
+ Vertical/Horizental sliders with/without buttons.
+
+
+
+
+
+ Switch Buttons
+
+
+
+
+
+ Switch buttons with/without background color or grabber text.
+
+
+
+
+
+ CheckBoxs
+
+
+
+
+
+ CheckBoxs with colorful background or with/without label text.
+
+
+
+
+
+ Buttons
+
+
+
+
+
+ Buttons with/without background or label text.
+
+
+
+
+
+ Push Buttons
+
+
+
+
+
+ Push buttons with/without sub menu.
+
+
+
+
+
+ Line Edits
+
+
+
+
+
+ Line edits with/without icon.
+
+
+
+
+
+ Bottom Bar
+
+
+
+
+
+ A bottom bar for window.
+
+
+
+
+
+
+ About
+
+
+
+
+
+ Tour
+
+
+
+
+
+ Test Item 2
+
+
+
+
+
+ Test Item 3
+
+
+
+
+ Home
+
+
+
+
+ File
+
+
+
+
+ Search
+
+
+
+
+ Account
+
+
+
+
+ Settings
+
+
+
+
diff --git a/example/i18n/RibbonUIAPP_zh_CN.ts b/example/i18n/RibbonUIAPP_zh_CN.ts
new file mode 100644
index 0000000..f9e5c1d
--- /dev/null
+++ b/example/i18n/RibbonUIAPP_zh_CN.ts
@@ -0,0 +1,495 @@
+
+
+
+
+ RibbonMessageListViewExample
+
+
+
+ Message List View Example
+ Message List View 示例
+
+
+
+
+ Add Message
+ 添加信息
+
+
+
+
+ Clear Message
+ 清除信息
+
+
+
+ SettingsMenuPage
+
+
+
+ Settings
+ 设置
+
+
+
+
+ Theme
+ 主题
+
+
+
+
+ Current Theme:
+ 当前主题:
+
+
+
+
+ Current Style:
+ 当前风格:
+
+
+
+
+ Style
+ 风格
+
+
+
+
+ Modern
+ 现代化
+
+
+
+
+ Classic
+ 经典
+
+
+
+
+ Text Render
+ 文本渲染器
+
+
+
+
+ Current Text Render:
+ 当前文本渲染器:
+
+
+
+
+ TitleBar
+ 标题栏
+
+
+
+
+ Show TitleBar Icon:
+ 显示标题栏图标:
+
+
+
+
+ Language
+ 语言
+
+
+
+
+ Current Language:
+ 当前语言:
+
+
+
+ TabBar
+
+
+
+ Basic
+ 基本
+
+
+
+
+ Slider
+ 滑动条
+
+
+
+
+ Switch Button
+ 开关
+
+
+
+
+ CheckBox
+ 复选框
+
+
+
+
+ Button
+ 按钮
+
+
+
+
+ Push Button
+ 按压按钮
+
+
+
+
+
+
+ No Menu
+ 无菜单
+
+
+
+
+
+
+
+
+ Menu
+ 菜单
+
+
+
+
+ Radio Button
+ 单选按钮
+
+
+
+
+ Input
+ 输入
+
+
+
+
+ Line Edit
+ 行编辑
+
+
+
+
+ Text Edit
+ 文本编辑
+
+
+
+
+ Combo Box
+ 组合框
+
+
+
+
+ Spin Box
+ 调整框
+
+
+
+
+ Progress
+ 进度
+
+
+
+
+ ProgressBar
+ 进度条
+
+
+
+
+ ProgressRing
+ 进度环
+
+
+
+
+ Indicator
+ 指示器
+
+
+
+
+ BusyRing
+ 加载环
+
+
+
+
+ BusyBar
+ 加载条
+
+
+
+
+ PageIndicator
+ 页面指示器
+
+
+
+
+ Views
+ 视图
+
+
+
+
+ MessageListView
+ 消息列表视图
+
+
+
+
+ Open Message List View
+ 打开消息列表视图
+
+
+
+
+ Others
+ 其他
+
+
+
+
+ Text
+ 文本
+
+
+
+
+ Open Menu
+ 打开菜单
+
+
+
+
+ Popup
+ 弹出窗口
+
+
+
+
+ Open Popup
+ 打开弹出窗口
+
+
+
+
+ Open Popup Dialog (Double Choices)
+ 打开弹出窗口(双选择)
+
+
+
+
+ Open Popup Dialog (Triple Choices)
+ 打开弹出窗口(三选择)
+
+
+
+
+ MessageBar
+ 信息栏
+
+
+
+
+ Generate One Message
+ 生成一条信息
+
+
+
+
+ Clear All Messages
+ 清除所有信息
+
+
+
+ about
+
+
+
+ About
+ 关于
+
+
+
+ example
+
+
+
+ RibbonUI APP
+ RibbonUI 应用
+
+
+
+
+ Tab Bar
+ 标签栏
+
+
+
+
+ A tab bar for window, let user choose the controllers.
+ 一个让用户选择工具使用的标签栏。
+
+
+
+
+ Tab Bar Buttons
+ 标签栏按钮
+
+
+
+
+ Tool buttons at the top of tab bar.
+ 在标签栏顶端的工具按钮。
+
+
+
+
+ Sliders
+ 滑动条
+
+
+
+
+ Vertical/Horizental sliders with/without buttons.
+ 含/不含按钮的垂直/水平滑动条。
+
+
+
+
+ Switch Buttons
+ 开关
+
+
+
+
+ Switch buttons with/without background color or grabber text.
+ 有/没有背景颜色或者抓握指示器文本的开关。
+
+
+
+
+ CheckBoxs
+ 复选框
+
+
+
+
+ CheckBoxs with colorful background or with/without label text.
+ 具有多彩背景色彩或标签文本的复选框。
+
+
+
+
+ Buttons
+ 按钮
+
+
+
+
+ Buttons with/without background or label text.
+ 具有/不具有背景或标签文本的按钮。
+
+
+
+
+ Push Buttons
+ 下压按钮
+
+
+
+
+ Push buttons with/without sub menu.
+ 有/没有带菜单的下压按钮。
+
+
+
+
+ Line Edits
+ 行编辑
+
+
+
+
+ Line edits with/without icon.
+ 带/不带图标的行编辑器。
+
+
+
+
+ Bottom Bar
+ 底层工具栏
+
+
+
+
+ A bottom bar for window.
+ 窗口的底层工具栏。
+
+
+
+
+
+ About
+ 关于
+
+
+
+
+ Tour
+ 导览
+
+
+
+
+ Test Item 2
+ 测试项目 1
+
+
+
+
+ Test Item 3
+ 测试项目 1
+
+
+
+ Home
+ 主页
+
+
+
+ File
+ 文件
+
+
+
+ Search
+ 搜索
+
+
+
+ Account
+ 账户
+
+
+
+ Settings
+ 设置
+
+
+
diff --git a/example/qml/Qt5/example.qml b/example/qml/Qt5/example.qml
index 7de2706..abce5be 100644
--- a/example/qml/Qt5/example.qml
+++ b/example/qml/Qt5/example.qml
@@ -12,6 +12,7 @@ RibbonWindow {
title: qsTr("RibbonUI APP")
comfirmedQuit: true
property bool modernStyle: RibbonTheme.modernStyle
+
RibbonMessageBarGroup{
id: msg_bar
implicitWidth: windowItems.width
@@ -142,7 +143,10 @@ RibbonWindow {
blurEnabled: true
targetRect: Qt.rect(windowItems.x + x, windowItems.y + y, width, height)
}
- Component.onCompleted: tour.open()
+ Component.onCompleted: {
+ RibbonUI.autoLoadLanguage = true
+ tour.open()
+ }
TabBar{
id: tab_bar
@@ -157,6 +161,7 @@ RibbonWindow {
pageWidth: (page_slider.value / 100.0) * width
spacing: 0
isMainView: true
+
ColumnLayout{
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 30
@@ -368,42 +373,42 @@ RibbonWindow {
blurTarget: root.windowItems
radius: borderRadius
RibbonBackStageMenuItem{
- menuText: "Home"
+ menuText: qsTr("Home")
menuIcon: RibbonIcons.Home
type: RibbonBackStageView.MenuItemLocation.Head
sourceComponent: t_content
sourceArgs:{'pageName':"Home"}
}
RibbonBackStageMenuItem{
- menuText: "File"
+ menuText: qsTr("File")
menuIcon: RibbonIcons.Document
type: RibbonBackStageView.MenuItemLocation.Head
sourceComponent: t_content
sourceArgs:{'pageName':"File"}
}
RibbonBackStageMenuItem{
- menuText: "Search"
+ menuText: qsTr("Search")
menuIcon: RibbonIcons.Search
type: RibbonBackStageView.MenuItemLocation.Body
sourceComponent: t_content
sourceArgs:{'pageName':"Search"}
}
RibbonBackStageMenuItem{
- menuText: "Account"
+ menuText: qsTr("Account")
menuIcon: RibbonIcons.PersonAccounts
type: RibbonBackStageView.MenuItemLocation.Tail
clickOnly: true
clickFunc: ()=>console.log("Menu Account clicked")
}
RibbonBackStageMenuItem{
- menuText: "About"
+ menuText: qsTr("About")
menuIcon: RibbonIcons.Info
type: RibbonBackStageView.MenuItemLocation.Tail
clickOnly: true
clickFunc: ()=>root.showWindow(Qt.resolvedUrl("about.qml"))
}
RibbonBackStageMenuItem{
- menuText: "Settings"
+ menuText: qsTr("Settings")
menuIcon: RibbonIcons.Settings
type: RibbonBackStageView.MenuItemLocation.Tail
sourceUrl: Qt.resolvedUrl("pages/SettingsMenuPage.qml")
diff --git a/example/qml/Qt5/pages/SettingsMenuPage.qml b/example/qml/Qt5/pages/SettingsMenuPage.qml
index 809f47a..2783520 100644
--- a/example/qml/Qt5/pages/SettingsMenuPage.qml
+++ b/example/qml/Qt5/pages/SettingsMenuPage.qml
@@ -108,5 +108,43 @@ RibbonBackStagePage{
}
}
}
+ RibbonBackStageGroup{
+ Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: lang_combo.height + 40
+ Layout.fillWidth: true
+ groupName: qsTr("Language")
+ ColumnLayout{
+ RowLayout{
+ RibbonText{
+ text: qsTr("Current Language: ")
+ }
+ RibbonComboBox{
+ id: lang_combo
+ model: ListModel {
+ id: model_lang
+ }
+ iconSource: RibbonIcons.LocalLanguage
+ Component.onCompleted: update_state()
+ onActivated: {
+ RibbonLocalization.currentLanguage = currentText
+ }
+ Connections{
+ target: RibbonLocalization
+ function onCurrentLanguageChanged(){
+ lang_combo.update_state()
+ }
+ }
+ function update_state(){
+ model_lang.clear()
+ let langs = RibbonLocalization.languageList()
+ for(let i = 0; i < langs.length; i++){
+ model_lang.append({text:langs[i]})
+ }
+ currentIndex = find(RibbonLocalization.currentLanguage)
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/example/qml/Qt6/example.qml b/example/qml/Qt6/example.qml
index 8dc7a90..3b850b2 100644
--- a/example/qml/Qt6/example.qml
+++ b/example/qml/Qt6/example.qml
@@ -12,6 +12,7 @@ RibbonWindow {
title: qsTr("RibbonUI APP")
comfirmedQuit: true
property bool modernStyle: RibbonTheme.modernStyle
+
RibbonMessageBarGroup{
id: msg_bar
implicitWidth: windowItems.width
@@ -142,7 +143,10 @@ RibbonWindow {
blurEnabled: true
targetRect: Qt.rect(windowItems.x + x, windowItems.y + y, width, height)
}
- Component.onCompleted: tour.open()
+ Component.onCompleted: {
+ RibbonUI.autoLoadLanguage = true
+ tour.open()
+ }
TabBar{
id: tab_bar
@@ -369,42 +373,42 @@ RibbonWindow {
blurTarget: root.windowItems
radius: borderRadius
RibbonBackStageMenuItem{
- menuText: "Home"
+ menuText: qsTr("Home")
menuIcon: RibbonIcons.Home
type: RibbonBackStageView.MenuItemLocation.Head
sourceComponent: t_content
sourceArgs:{'pageName':"Home"}
}
RibbonBackStageMenuItem{
- menuText: "File"
+ menuText: qsTr("File")
menuIcon: RibbonIcons.Document
type: RibbonBackStageView.MenuItemLocation.Head
sourceComponent: t_content
sourceArgs:{'pageName':"File"}
}
RibbonBackStageMenuItem{
- menuText: "Search"
+ menuText: qsTr("Search")
menuIcon: RibbonIcons.Search
type: RibbonBackStageView.MenuItemLocation.Body
sourceComponent: t_content
sourceArgs:{'pageName':"Search"}
}
RibbonBackStageMenuItem{
- menuText: "Account"
+ menuText: qsTr("Account")
menuIcon: RibbonIcons.PersonAccounts
type: RibbonBackStageView.MenuItemLocation.Tail
clickOnly: true
clickFunc: ()=>console.log("Menu Account clicked")
}
RibbonBackStageMenuItem{
- menuText: "About"
+ menuText: qsTr("About")
menuIcon: RibbonIcons.Info
type: RibbonBackStageView.MenuItemLocation.Tail
clickOnly: true
clickFunc: ()=>root.showWindow(Qt.resolvedUrl("about.qml"))
}
RibbonBackStageMenuItem{
- menuText: "Settings"
+ menuText: qsTr("Settings")
menuIcon: RibbonIcons.Settings
type: RibbonBackStageView.MenuItemLocation.Tail
sourceUrl: Qt.resolvedUrl("pages/SettingsMenuPage.qml")
diff --git a/example/qml/Qt6/pages/SettingsMenuPage.qml b/example/qml/Qt6/pages/SettingsMenuPage.qml
index ed330d0..ab273e2 100644
--- a/example/qml/Qt6/pages/SettingsMenuPage.qml
+++ b/example/qml/Qt6/pages/SettingsMenuPage.qml
@@ -108,5 +108,43 @@ RibbonBackStagePage{
}
}
}
+ RibbonBackStageGroup{
+ Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: lang_combo.height + 40
+ Layout.fillWidth: true
+ groupName: qsTr("Language")
+ ColumnLayout{
+ RowLayout{
+ RibbonText{
+ text: qsTr("Current Language: ")
+ }
+ RibbonComboBox{
+ id: lang_combo
+ model: ListModel {
+ id: model_lang
+ }
+ iconSource: RibbonIcons.LocalLanguage
+ Component.onCompleted: update_state()
+ onActivated: {
+ RibbonLocalization.currentLanguage = currentText
+ }
+ Connections{
+ target: RibbonLocalization
+ function onCurrentLanguageChanged(){
+ lang_combo.update_state()
+ }
+ }
+ function update_state(){
+ model_lang.clear()
+ let langs = RibbonLocalization.languageList()
+ for(let i = 0; i < langs.length; i++){
+ model_lang.append({text:langs[i]})
+ }
+ currentIndex = find(RibbonLocalization.currentLanguage)
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/lib_source/CMakeLists.txt b/lib_source/CMakeLists.txt
index 938aa1f..6d1fe9a 100644
--- a/lib_source/CMakeLists.txt
+++ b/lib_source/CMakeLists.txt
@@ -18,7 +18,7 @@ endif()
# Find Qt package
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
-find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick Qml REQUIRED)
+find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick Qml LinguistTools REQUIRED)
# Determine library type and plugin target name based on build type
if (RIBBONUI_BUILD_STATIC_LIB)
@@ -30,6 +30,9 @@ else()
set(PLUGIN_TARGET_NAME ${PROJECT_NAME})
endif()
+# List all ts files to be used in the project
+set(ts_files i18n/${PROJECT_NAME}_zh_CN.ts i18n/${PROJECT_NAME}_en_US.ts)
+
# List of QML files to be included in the project
set(qml_files
RibbonTabBar.qml RibbonTabButton.qml RibbonView.qml
@@ -58,8 +61,11 @@ list(TRANSFORM qml_files PREPEND ${qml_prefix})
# List of source files to be included in the project
set (source_files
- ribbonui.cpp ribbonui.h definitions.h ribbontheme.h ribbontheme.cpp
- platformsupport.h)
+ include/ribbonui.h source/ribbonui.cpp
+ include/definitions.h
+ include/ribbontheme.h source/ribbontheme.cpp
+ include/platformsupport.h
+ include/ribbonlocalization.h source/ribbonlocalization.cpp)
# Configure version header
set(__ribbonui_project_version "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
@@ -70,7 +76,7 @@ list(APPEND source_files ${CMAKE_CURRENT_BINARY_DIR}/${__ribbonui_project_name_l
# Add platform-specific source files for Apple
if(APPLE)
- list(APPEND source_files platformsupport.mm)
+ list(APPEND source_files source/platformsupport.mm)
endif()
# Set properties for QML files
@@ -89,6 +95,31 @@ endif()
# Define the RibbonUI library
qt_add_library(${PROJECT_NAME} ${LIB_TYPE})
+# Add i18n files
+set_source_files_properties(${ts_files} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/i18n)
+
+if(QT_VERSION VERSION_LESS 6.0)
+ qt5_create_translation_plus(qm_files ${CMAKE_CURRENT_SOURCE_DIR} ${ts_files})
+ foreach(qm_file ${qm_files})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" r_qm_file ${qm_file})
+ list(APPEND r_qm_files ${r_qm_file})
+ endforeach()
+ qt5_add_resources_plus(${PROJECT_NAME} "${PROJECT_NAME}-translations"
+ PREFIX "/"
+ FILES ${r_qm_files}
+ )
+else()
+ qt6_create_translation(qm_files ${CMAKE_CURRENT_SOURCE_DIR} ${ts_files})
+ foreach(qm_file ${qm_files})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" r_qm_file ${qm_file})
+ list(APPEND r_qm_files ${r_qm_file})
+ endforeach()
+ qt6_add_resources(${PROJECT_NAME} "${PROJECT_NAME}-translations"
+ PREFIX "/"
+ FILES ${r_qm_files}
+ )
+endif()
+
# Define the QML module for the library
qt_add_qml_module(${PROJECT_NAME}
PLUGIN_TARGET ${PLUGIN_TARGET_NAME}
@@ -130,7 +161,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
# Include directories
target_include_directories(${PROJECT_NAME} PUBLIC
- ${PROJECT_SOURCE_DIR}
+ ${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/3rdparty/qwindowkit/include
)
diff --git a/lib_source/i18n/RibbonUI_en_US.ts b/lib_source/i18n/RibbonUI_en_US.ts
new file mode 100644
index 0000000..3bea03c
--- /dev/null
+++ b/lib_source/i18n/RibbonUI_en_US.ts
@@ -0,0 +1,376 @@
+
+
+
+
+ RibbonBackStageGroup
+
+
+
+ Title
+
+
+
+
+ RibbonBackStagePage
+
+
+
+ Name
+
+
+
+
+ RibbonBackStageView
+
+
+
+ Back
+
+
+
+
+
+ Close
+
+
+
+
+
+ Minimize
+
+
+
+
+
+ Restore
+
+
+
+
+
+ Maximize
+
+
+
+
+ RibbonLineEdit
+
+
+
+ Please input:
+
+
+
+
+
+ Clear
+
+
+
+
+ RibbonMessageBar
+
+
+
+ Link
+
+
+
+
+
+ Close
+
+
+
+
+
+ See More
+
+
+
+
+
+ ActionA
+
+
+
+
+
+ ActionB
+
+
+
+
+
+ ActionA Clicked
+
+
+
+
+
+ ActionB Clicked
+
+
+
+
+ RibbonMessageBarGroup
+
+
+
+ Clear All
+
+
+
+
+
+ Show all messages
+
+
+
+
+
+ Hide all messages
+
+
+
+
+ RibbonPageIndicator
+
+
+
+ Previous
+
+
+
+
+
+ Next
+
+
+
+
+ RibbonProgressBar
+
+
+
+ Loading
+
+
+
+
+ RibbonSwitchButton
+
+
+
+ Open
+
+
+
+
+
+ Close
+
+
+
+
+ RibbonTabBar
+
+
+
+ Settings
+
+
+
+
+
+ Show
+
+
+
+
+
+ Hide
+
+
+
+
+
+ RibbonTabBar: Error loading component:
+
+
+
+
+ RibbonTabGroup
+
+
+
+ Open
+
+
+
+
+
+ 's external
+
+
+
+
+ RibbonTextBoxMenu
+
+
+
+ Cut
+
+
+
+
+
+ Copy
+
+
+
+
+
+ Paste
+
+
+
+
+
+ Select All
+
+
+
+
+ RibbonTextEdit
+
+
+
+ Please input:
+
+
+
+
+
+ Clear
+
+
+
+
+ RibbonTitleBar
+
+
+
+ Close
+
+
+
+
+
+ Minimize
+
+
+
+
+
+ Restore
+
+
+
+
+
+ Maximize
+
+
+
+
+
+ Style
+
+
+
+
+
+ Modern
+
+
+
+
+
+ Classic
+
+
+
+
+
+ Dark Mode
+
+
+
+
+
+ Stay on Top
+
+
+
+
+ RibbonTour
+
+
+
+ Don't auto pop up
+
+
+
+
+
+ Previous
+
+
+
+
+
+ Finish
+
+
+
+
+
+ Next
+
+
+
+
+ RibbonWindow
+
+
+
+ Quit
+
+
+
+
+
+ Minimize
+
+
+
+
+
+ Cancel
+
+
+
+
+
+ Do you want to close this window?
+
+
+
+
+
+ Please note
+
+
+
+
diff --git a/lib_source/i18n/RibbonUI_zh_CN.ts b/lib_source/i18n/RibbonUI_zh_CN.ts
new file mode 100644
index 0000000..5b14fc2
--- /dev/null
+++ b/lib_source/i18n/RibbonUI_zh_CN.ts
@@ -0,0 +1,377 @@
+
+
+
+
+ RibbonBackStageGroup
+
+
+
+ Title
+ 标题
+
+
+
+ RibbonBackStagePage
+
+
+
+ Name
+ 页面名称
+
+
+
+ RibbonBackStageView
+
+
+
+ Back
+ 返回
+
+
+
+
+ Close
+ 关闭
+
+
+
+
+ Minimize
+ 最小化
+
+
+
+
+ Restore
+ 还原
+
+
+
+
+ Maximize
+ 最大化
+
+
+
+ RibbonLineEdit
+
+
+
+ Please input:
+ 请输入:
+
+
+
+
+ Clear
+ 清除
+
+
+
+ RibbonMessageBar
+
+
+
+ Link
+ 外部链接
+
+
+
+
+ Close
+ 关闭
+
+
+
+
+ See More
+ 查看更多
+
+
+
+
+ ActionA
+ 按钮A
+
+
+
+
+ ActionB
+ 按钮B
+
+
+
+
+ ActionA Clicked
+ 按钮A被点击
+
+
+
+
+ ActionB Clicked
+ 按钮B被点击
+
+
+
+ RibbonMessageBarGroup
+
+
+
+ Clear All
+ 清除全部
+
+
+
+
+ Show all messages
+ 显示全部消息
+
+
+
+
+ Hide all messages
+ 隐藏全部消息
+
+
+
+ RibbonPageIndicator
+
+
+
+ Previous
+ 上一个
+
+
+
+
+ Next
+ 下一个
+
+
+
+ RibbonProgressBar
+
+
+
+ Loading
+ 加载中
+
+
+
+ RibbonSwitchButton
+
+
+
+ Open
+ 打开
+
+
+
+
+ Close
+ 关闭
+
+
+
+ RibbonTabBar
+
+
+
+ Settings
+ 设置
+
+
+
+
+ Show
+ 显示
+
+
+
+
+ Hide
+ 隐藏
+
+
+
+
+ RibbonTabBar: Error loading component:
+ RibbonTabBar:加载组件失败:
+
+
+
+ RibbonTabGroup
+
+
+
+ Open
+ 打开
+
+
+
+
+ 's external
+ 的外部链接
+
+
+
+ RibbonTextBoxMenu
+
+
+
+ Cut
+ 剪切
+
+
+
+
+ Copy
+ 拷贝
+
+
+
+
+ Paste
+ 粘贴
+
+
+
+
+ Select All
+ 全选
+
+
+
+
+ RibbonTextEdit
+
+
+
+ Please input:
+ 请输入:
+
+
+
+
+ Clear
+ 清除
+
+
+
+ RibbonTitleBar
+
+
+
+ Close
+ 关闭
+
+
+
+
+ Minimize
+ 最小化
+
+
+
+
+ Restore
+ 还原
+
+
+
+
+ Maximize
+ 最大化
+
+
+
+
+ Style
+ 风格
+
+
+
+
+ Modern
+ 现代化
+
+
+
+
+ Classic
+ 经典
+
+
+
+
+ Dark Mode
+ 暗色模式
+
+
+
+
+ Stay on Top
+ 总是显示在顶层
+
+
+
+ RibbonTour
+
+
+
+ Don't auto pop up
+ 不要自动弹出
+
+
+
+
+ Previous
+ 上一个
+
+
+
+
+ Finish
+ 完成
+
+
+
+
+ Next
+ 下一个
+
+
+
+ RibbonWindow
+
+
+
+ Quit
+ 退出
+
+
+
+
+ Minimize
+ 最小化
+
+
+
+
+ Cancel
+ 取消
+
+
+
+
+ Do you want to close this window?
+ 需要关闭窗口吗?
+
+
+
+
+ Please note
+ 请注意
+
+
+
diff --git a/lib_source/definitions.h b/lib_source/include/definitions.h
similarity index 99%
rename from lib_source/definitions.h
rename to lib_source/include/definitions.h
index abaa789..07f4c52 100644
--- a/lib_source/definitions.h
+++ b/lib_source/include/definitions.h
@@ -2355,8 +2355,8 @@ enum class RibbonIcons_Filled{
Q_ENUM_NS(RibbonIcons_Filled)
QML_NAMED_ELEMENT(RibbonIcons_Filled)
#if (QT_VERSION > QT_VERSION_CHECK(6, 3, 0))
- Q_CLASSINFO("QML.Creatable", "false")
- Q_CLASSINFO("QML.UncreatableReason", "This type is right-valued only.")
+Q_CLASSINFO("QML.Creatable", "false")
+Q_CLASSINFO("QML.UncreatableReason", "This type is right-valued only.")
#elif (QT_VERSION <= QT_VERSION_CHECK(6, 3, 0))
QML_UNCREATABLE("This type is right-valued only.")
#endif
@@ -4718,30 +4718,30 @@ QML_UNCREATABLE("This type is right-valued only.")
#define Q_PROPERTY_RW(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed FINAL) \
-public: \
+ public: \
Q_SIGNAL void M##Changed(); \
void M(TYPE in_##M) \
- { \
+{ \
_##M = in_##M; \
Q_EMIT M##Changed(); \
- } \
+} \
TYPE M() \
- { \
+{ \
return _##M; \
- } \
+} \
\
-private: \
+ private: \
TYPE _##M;
#define Q_PROPERTY_R(TYPE, M) \
Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \
-public: \
+ public: \
Q_SIGNAL void M##Changed(); \
TYPE M() \
- { \
+{ \
return _##M; \
- } \
-private: \
+} \
+ private: \
TYPE _##M;
namespace RibbonPopupDialogType {
diff --git a/lib_source/platformsupport.h b/lib_source/include/platformsupport.h
similarity index 100%
rename from lib_source/platformsupport.h
rename to lib_source/include/platformsupport.h
diff --git a/lib_source/include/ribbonlocalization.h b/lib_source/include/ribbonlocalization.h
new file mode 100644
index 0000000..94e0025
--- /dev/null
+++ b/lib_source/include/ribbonlocalization.h
@@ -0,0 +1,46 @@
+#ifndef RIBBONLOCALIZATION_H
+#define RIBBONLOCALIZATION_H
+
+#include
+#include
+#include
+
+class RibbonLocalization : public QQuickItem
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ QML_NAMED_ELEMENT(RibbonLocalization)
+ Q_PROPERTY(QString currentLanguage READ currentLanguage WRITE setCurrentLanguage NOTIFY currentLanguageChanged FINAL)
+public:
+ typedef QPair LangItem; // example: <"zh_CN", "qrc://i18n/xxx_zh_CN.qm">
+ typedef QMap> Translator; // example: <"main", mainTranslator>
+ typedef QMap ModuleTranslator; // example:
+ static RibbonLocalization* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
+ static RibbonLocalization* instance();
+ Q_INVOKABLE bool registerLanguage(QString langName, QString path, QString moduleName);
+ Q_INVOKABLE bool removeLanguage(QString langName, QString path);
+ Q_INVOKABLE void bindEngine();
+ Q_INVOKABLE QList languageList();
+ QString currentLanguage();
+ bool setCurrentLanguage(QString langName);
+ // Use if you need to directly save/load language from config files
+ Q_INVOKABLE virtual void loadCurrentLanguage(){};
+ virtual bool saveCurrentLanguage(const QString &language){return false;};
+#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
+public:
+#else
+private:
+ Q_DISABLE_COPY_MOVE(RibbonLocalization)
+#endif
+ RibbonLocalization();
+ ~RibbonLocalization();
+private:
+ ModuleTranslator moduleLangList;
+ Translator transList;
+ QString _currentLang;
+signals:
+ void currentLanguageChanged();
+};
+
+#endif // RIBBONLOCALIZATION_H
diff --git a/lib_source/ribbontheme.h b/lib_source/include/ribbontheme.h
similarity index 91%
rename from lib_source/ribbontheme.h
rename to lib_source/include/ribbontheme.h
index 6f847d1..6bdae6b 100644
--- a/lib_source/ribbontheme.h
+++ b/lib_source/include/ribbontheme.h
@@ -11,7 +11,7 @@ class RibbonTheme : public QQuickItem
QML_SINGLETON
QML_NAMED_ELEMENT(RibbonTheme)
- Q_PROPERTY(bool isDarkMode READ isDarkMode() NOTIFY isDarkModeChanged FINAL)
+ Q_PROPERTY(bool isDarkMode READ isDarkMode NOTIFY isDarkModeChanged FINAL)
Q_PROPERTY_RW(RibbonThemeType::ThemeMode,themeMode)
Q_PROPERTY_RW(bool,modernStyle)
Q_PROPERTY_RW(bool,nativeText)
diff --git a/lib_source/ribbonui.h b/lib_source/include/ribbonui.h
similarity index 58%
rename from lib_source/ribbonui.h
rename to lib_source/include/ribbonui.h
index 21525f9..099f039 100644
--- a/lib_source/ribbonui.h
+++ b/lib_source/include/ribbonui.h
@@ -3,6 +3,7 @@
#include
#include "definitions.h"
+#include "ribbonlocalization.h"
class RibbonUI : public QQuickItem
{
@@ -14,11 +15,16 @@ class RibbonUI : public QQuickItem
Q_PROPERTY_R(int, qtVersion)
Q_PROPERTY_R(int, isWin11)
Q_PROPERTY_RW(QVariantMap, windowsSet)
+ Q_PROPERTY(bool autoLoadLanguage READ autoLoadLanguage WRITE setAutoLoadLanguage NOTIFY autoLoadLanguageChanged FINAL)
public:
static RibbonUI* instance();
static RibbonUI* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
RIBBONUI_API static void init();
RIBBONUI_API static void registerTypes(const char *uri);
+ RIBBONUI_API Q_INVOKABLE void setTranslator(RibbonLocalization *translator = RibbonLocalization::instance());
+ Q_INVOKABLE void initTranslator();
+ bool autoLoadLanguage(){return _autoLoadLanguage;};
+ void setAutoLoadLanguage(bool value);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
public:
#else
@@ -26,6 +32,12 @@ private:
Q_DISABLE_COPY_MOVE(RibbonUI)
#endif
explicit RibbonUI(QQuickItem *parent = nullptr);
+private:
+ RibbonLocalization* _translator;
+ bool _autoLoadLanguage = false;
+
+signals:
+ void autoLoadLanguageChanged();
};
#endif // RIBBONUI_H
diff --git a/lib_source/qml/Qt5/RibbonBackStageMenuItem.qml b/lib_source/qml/Qt5/RibbonBackStageMenuItem.qml
index b4411fa..4cc985d 100644
--- a/lib_source/qml/Qt5/RibbonBackStageMenuItem.qml
+++ b/lib_source/qml/Qt5/RibbonBackStageMenuItem.qml
@@ -4,6 +4,7 @@ import RibbonUI 1.1
RibbonObject {
id: control
required property string menuText
+ property int id
property var menuIcon
property var menuIconFilled
required property var type
diff --git a/lib_source/qml/Qt5/RibbonBackStageView.qml b/lib_source/qml/Qt5/RibbonBackStageView.qml
index 54cc7e2..cf34cb6 100644
--- a/lib_source/qml/Qt5/RibbonBackStageView.qml
+++ b/lib_source/qml/Qt5/RibbonBackStageView.qml
@@ -44,6 +44,12 @@ Popup {
if(data_container.resources[index] instanceof RibbonBackStageMenuItem)
{
let item = data_container.resources[index]
+ item.menuTextChanged.connect(function(){
+ item.getPropertiesReady()
+ pageModel[item.id] = item.properties
+ refreshModel()
+ })
+ item.id = pageModel.length
item.getPropertiesReady()
pageModel.push(item.properties)
}
@@ -555,6 +561,11 @@ Popup {
body_menu_list.model.append(item)
}
}
+ menu_bg.currentMenu = 0
+ head_menu_list.currentIndex = 0
+ body_menu_list.currentIndex = 0
+ tail_menu_list.currentIndex = 0
+ content_view.currentIndex = 0
}
function alphaTohex(color, alpha)
diff --git a/lib_source/qml/Qt5/RibbonTabBar.qml b/lib_source/qml/Qt5/RibbonTabBar.qml
index b2f3f3b..3f427fe 100644
--- a/lib_source/qml/Qt5/RibbonTabBar.qml
+++ b/lib_source/qml/Qt5/RibbonTabBar.qml
@@ -225,7 +225,8 @@ Item{
{
let item = stack.contentData[i]
if(item instanceof RibbonTabPage){
- let btn = ribbonTabButton.createObject(bar,{text:qsTr(item.title),index:sign})
+ let btn = ribbonTabButton.createObject(bar,{text:item.title,index:sign})
+ item.titleChanged.connect(function(){btn.text=item.title})
if (sign===0)
{
btn.checked = true
diff --git a/lib_source/qml/Qt5/RibbonTour.qml b/lib_source/qml/Qt5/RibbonTour.qml
index d578016..cf0a7b3 100644
--- a/lib_source/qml/Qt5/RibbonTour.qml
+++ b/lib_source/qml/Qt5/RibbonTour.qml
@@ -154,6 +154,16 @@ Popup {
if(data_container.resources[index] instanceof RibbonTourItem)
{
let item = data_container.resources[index]
+ item.titleChanged.connect(function(){
+ item.getPropertiesReady()
+ targetList[item.id] = item.properties
+ })
+ if(item.text){
+ item.textChanged.connect(function(){
+ targetList[item.id].text = item.text
+ })
+ }
+ item.id = targetList.length
item.getPropertiesReady()
targetList.push(item.properties)
}
@@ -164,7 +174,7 @@ Popup {
Popup{
id: rec
- parent: Overlay.overlay
+ parent: popup.parent
margins: 0
padding: 0
topInset: 0
diff --git a/lib_source/qml/Qt5/RibbonTourItem.qml b/lib_source/qml/Qt5/RibbonTourItem.qml
index df947b0..b5d2c3b 100644
--- a/lib_source/qml/Qt5/RibbonTourItem.qml
+++ b/lib_source/qml/Qt5/RibbonTourItem.qml
@@ -4,6 +4,7 @@ import RibbonUI 1.1
RibbonObject {
id: control
required property string title
+ property int id
property string text
property var target
property var enterFunc
diff --git a/lib_source/qml/Qt5/RibbonWindow.qml b/lib_source/qml/Qt5/RibbonWindow.qml
index 5f4c99b..b071f90 100644
--- a/lib_source/qml/Qt5/RibbonWindow.qml
+++ b/lib_source/qml/Qt5/RibbonWindow.qml
@@ -73,6 +73,8 @@ Window {
{
windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.isDarkMode ? "dark" : "light" : "none")
}
+ RibbonLocalization.bindEngine();
+ RibbonUI.setTranslator(RibbonLocalization)
}
Item{
id: windowItems
diff --git a/lib_source/qml/Qt6/RibbonBackStageMenuItem.qml b/lib_source/qml/Qt6/RibbonBackStageMenuItem.qml
index d19f086..ac50d9f 100644
--- a/lib_source/qml/Qt6/RibbonBackStageMenuItem.qml
+++ b/lib_source/qml/Qt6/RibbonBackStageMenuItem.qml
@@ -4,6 +4,7 @@ import RibbonUI
RibbonObject {
id: control
required property string menuText
+ property int id
property var menuIcon
property var menuIconFilled
required property var type
diff --git a/lib_source/qml/Qt6/RibbonBackStageView.qml b/lib_source/qml/Qt6/RibbonBackStageView.qml
index ae937e8..b829e04 100644
--- a/lib_source/qml/Qt6/RibbonBackStageView.qml
+++ b/lib_source/qml/Qt6/RibbonBackStageView.qml
@@ -44,6 +44,12 @@ Popup {
if(data_container.resources[index] instanceof RibbonBackStageMenuItem)
{
let item = data_container.resources[index]
+ item.menuTextChanged.connect(function(){
+ item.getPropertiesReady()
+ pageModel[item.id] = item.properties
+ refreshModel()
+ })
+ item.id = pageModel.length
item.getPropertiesReady()
pageModel.push(item.properties)
}
@@ -555,5 +561,10 @@ Popup {
body_menu_list.model.append(item)
}
}
+ menu_bg.currentMenu = 0
+ head_menu_list.currentIndex = 0
+ body_menu_list.currentIndex = 0
+ tail_menu_list.currentIndex = 0
+ content_view.currentIndex = 0
}
}
diff --git a/lib_source/qml/Qt6/RibbonTabBar.qml b/lib_source/qml/Qt6/RibbonTabBar.qml
index 49a75d2..2322910 100644
--- a/lib_source/qml/Qt6/RibbonTabBar.qml
+++ b/lib_source/qml/Qt6/RibbonTabBar.qml
@@ -225,7 +225,8 @@ Item{
{
let item = stack.contentData[i]
if(item instanceof RibbonTabPage){
- let btn = ribbonTabButton.createObject(bar,{text:qsTr(item.title),index:sign})
+ let btn = ribbonTabButton.createObject(bar,{text:item.title,index:sign})
+ item.titleChanged.connect(function(){btn.text=item.title})
if (sign===0)
{
btn.checked = true
diff --git a/lib_source/qml/Qt6/RibbonTour.qml b/lib_source/qml/Qt6/RibbonTour.qml
index 37bf484..5311f45 100644
--- a/lib_source/qml/Qt6/RibbonTour.qml
+++ b/lib_source/qml/Qt6/RibbonTour.qml
@@ -57,7 +57,7 @@ Popup {
radius: 7
maskOpacity: blurEnabled ? 0.9 : 1
maskBorderColor: RibbonTheme.modernStyle ?
- RibbonTheme.isDarkMode ? "#7A7A7A" : "#2C59B7" :
+ RibbonTheme.isDarkMode ? "#7A7A7A" : "#2C59B7" :
RibbonTheme.isDarkMode ? "#5C5D5D" : "#B5B4B5"
maskBorderWidth: 1
}
@@ -155,6 +155,16 @@ Popup {
if(data_container.resources[index] instanceof RibbonTourItem)
{
let item = data_container.resources[index]
+ item.titleChanged.connect(function(){
+ item.getPropertiesReady()
+ targetList[item.id] = item.properties
+ })
+ if(item.text){
+ item.textChanged.connect(function(){
+ targetList[item.id].text = item.text
+ })
+ }
+ item.id = targetList.length
item.getPropertiesReady()
targetList.push(item.properties)
}
diff --git a/lib_source/qml/Qt6/RibbonTourItem.qml b/lib_source/qml/Qt6/RibbonTourItem.qml
index 0c92027..10f172f 100644
--- a/lib_source/qml/Qt6/RibbonTourItem.qml
+++ b/lib_source/qml/Qt6/RibbonTourItem.qml
@@ -4,6 +4,7 @@ import RibbonUI
RibbonObject {
id: control
required property string title
+ property int id
property string text
property var target
property var enterFunc
diff --git a/lib_source/qml/Qt6/RibbonWindow.qml b/lib_source/qml/Qt6/RibbonWindow.qml
index a9a115b..6da3a0c 100644
--- a/lib_source/qml/Qt6/RibbonWindow.qml
+++ b/lib_source/qml/Qt6/RibbonWindow.qml
@@ -73,6 +73,8 @@ Window {
{
windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.isDarkMode ? "dark" : "light" : "none")
}
+ RibbonLocalization.bindEngine();
+ RibbonUI.setTranslator(RibbonLocalization)
}
Item{
id: windowItems
diff --git a/lib_source/platformsupport.mm b/lib_source/source/platformsupport.mm
similarity index 100%
rename from lib_source/platformsupport.mm
rename to lib_source/source/platformsupport.mm
diff --git a/lib_source/source/ribbonlocalization.cpp b/lib_source/source/ribbonlocalization.cpp
new file mode 100644
index 0000000..c294483
--- /dev/null
+++ b/lib_source/source/ribbonlocalization.cpp
@@ -0,0 +1,106 @@
+#include "ribbonlocalization.h"
+#include
+#include
+#include
+
+RibbonLocalization::RibbonLocalization() {
+ _currentLang = "en_US";
+}
+
+RibbonLocalization::~RibbonLocalization() {
+ for (auto item : transList)
+ item.clear();
+}
+
+RibbonLocalization* RibbonLocalization::instance(){
+ static QMutex mutex;
+ QMutexLocker locker(&mutex);
+
+ static RibbonLocalization *singleton = nullptr;
+ if (!singleton) {
+ singleton = new RibbonLocalization();
+ }
+ return singleton;
+}
+
+bool RibbonLocalization::registerLanguage(QString langName, QString path, QString moduleName){
+ LangItem temp(langName, path);
+ if(!moduleLangList.contains(temp)){
+ if(!transList.contains(moduleName)){
+ transList.insert(moduleName, QSharedPointer(new QTranslator));
+ if(langName == _currentLang){
+ Q_UNUSED(transList[moduleName].get()->load(path));
+ qApp->installTranslator(transList[moduleName].get());
+ }
+ }
+ moduleLangList.insert(temp, moduleName);
+ return true;
+ }
+ return false;
+}
+
+bool RibbonLocalization::removeLanguage(QString langName, QString path){
+ LangItem temp(langName, path);
+ if(moduleLangList.contains(temp)){
+ if(langName == _currentLang){
+ qApp->removeTranslator(transList[moduleLangList[temp]].get());
+ _currentLang = "en_US";
+ emit currentLanguageChanged();
+ }
+ transList[moduleLangList[temp]].clear();
+ transList.remove(moduleLangList[temp]);
+ moduleLangList.remove(temp);
+ return true;
+ }
+ return false;
+}
+
+QString RibbonLocalization::currentLanguage(){
+ return _currentLang;
+}
+
+bool RibbonLocalization::setCurrentLanguage(QString langName){
+ bool hasChanged = false;
+ QMap isNeeded;
+ for(auto langItem : moduleLangList.keys()){
+ if(langItem.first == langName){
+ isNeeded[moduleLangList[langItem]] = true;
+ Q_UNUSED(transList[moduleLangList[langItem]].get()->load(langItem.second));
+ _currentLang = langName;
+ qApp->installTranslator(transList[moduleLangList[langItem]].get());;
+ hasChanged = true;
+ }
+ else{
+ if(!isNeeded[moduleLangList[langItem]]){
+ qApp->removeTranslator(transList[moduleLangList[langItem]].get());
+ }
+ }
+ }
+ if(hasChanged){
+ saveCurrentLanguage(langName);
+ emit currentLanguageChanged();
+ }
+ return hasChanged;
+}
+
+void RibbonLocalization::bindEngine(){
+ QQmlApplicationEngine * engine = dynamic_cast(qmlEngine(this));
+ Q_ASSERT(engine);
+ if (!engine)
+ return;
+ QObject::connect(this, &RibbonLocalization::currentLanguageChanged, engine, [engine]() -> void {
+ engine->retranslate();
+ });
+}
+
+QList RibbonLocalization::languageList(){
+ QList list;
+ QSet set;
+ for(auto langItem : moduleLangList.keys()){
+ set.insert(langItem.first);
+ }
+ for(auto setItem : set){
+ list.append(setItem);
+ }
+ return list;
+}
diff --git a/lib_source/ribbontheme.cpp b/lib_source/source/ribbontheme.cpp
similarity index 100%
rename from lib_source/ribbontheme.cpp
rename to lib_source/source/ribbontheme.cpp
diff --git a/lib_source/ribbonui.cpp b/lib_source/source/ribbonui.cpp
similarity index 52%
rename from lib_source/ribbonui.cpp
rename to lib_source/source/ribbonui.cpp
index 74b2d7d..a59103a 100644
--- a/lib_source/ribbonui.cpp
+++ b/lib_source/source/ribbonui.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include "ribbonui_version.h"
RibbonUI::RibbonUI(QQuickItem *parent)
@@ -12,6 +13,7 @@ RibbonUI::RibbonUI(QQuickItem *parent)
_version = RIBBONUI_VERSION;
_qtVersion = QString(qVersion()).replace('.',"").toInt();
_isWin11 = QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 22000);
+ _translator = RibbonLocalization::instance();
}
RibbonUI* RibbonUI::instance(){
@@ -45,3 +47,41 @@ void RibbonUI::registerTypes(const char *uri)
Q_UNUSED(uri);
QWK::registerTypes(nullptr);
}
+
+void RibbonUI::setTranslator(RibbonLocalization *translator){
+ _translator = translator;
+ initTranslator();
+}
+
+void RibbonUI::initTranslator(){
+ QDir dir(":/i18n");
+ QStringList filters;
+ filters<<"*.qm";
+ dir.setNameFilters(filters);
+ QStringList matchedFiles = dir.entryList();
+ for(auto file : matchedFiles){
+ QString project, lang;
+ int start = 0;
+ int end = file.indexOf('_');
+
+ if (end > start)
+ project = file.mid(start, end - start);
+
+ start = file.indexOf('_') + 1;
+ end = file.lastIndexOf('.');
+ if (start > 0 && end > start)
+ lang = file.mid(start, end - start);
+
+ if(!lang.isEmpty() && !project.isEmpty()){
+ if(_autoLoadLanguage || (!_autoLoadLanguage && project == "RibbonUI")){
+ _translator->registerLanguage(lang, ":/i18n/" + file, project);
+ continue;
+ }
+ }
+ }
+}
+
+void RibbonUI::setAutoLoadLanguage(bool value){
+ _autoLoadLanguage = value;
+ initTranslator();
+}