mirror of
https://github.com/opentx/opentx.git
synced 2025-07-13 11:29:51 +03:00
[Companion] Translation system improvements. (#4676)
* [Companion] I18N: * Introduce new Translations class to centralize all related functionality; * Add ability to search multiple locations for .qm translation binaries (local folders, resources, system paths); * Add ability to reload translations dynamically w/out application restart; * Improve support for loading Qt translations (if available); * [build][i18n] Look for and include pre-built Qt translations with other translation resources; Generate translations.qrc dynamically with rest of build files; Add EN "translation" file (simpler UI string edits and possible abstractions); Rename ZH translation file to be country-specific. * [build] Centralize finding all the Qt bits into root CMakeLists; Make sure QT_QMAKE_EXECUTABLE is defined; Disable dysfunctional simulator installer script generation. * Cosmetics (unused includes). * [Companion] Make language options menu dynamic based on available translations, and always show native language name; Allow changing language of some elements w/out restarting (esp. menus/toolbar buttons); Simplify menus/actions/handlers for themes and icon sizes. * [build] Better way to generate translations.qrc using input file again (previous method was generating new qrc for each reconfig); Make sure common library is linked to other modules which may need it; Remove unused script.
This commit is contained in:
parent
d5560d68f4
commit
dcdbff74b0
15 changed files with 12925 additions and 317 deletions
|
@ -21,6 +21,9 @@ endif()
|
|||
if(POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0058)
|
||||
cmake_policy(SET CMP0058 NEW) # for ninja
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
|
@ -59,6 +62,7 @@ if(WIN32)
|
|||
list(APPEND CMAKE_PREFIX_PATH "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/SDL") # hints for FindSDL
|
||||
endif()
|
||||
|
||||
find_package(Qt5Core)
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
find_package(Qt5LinguistTools)
|
||||
|
@ -66,11 +70,37 @@ find_package(Qt5PrintSupport)
|
|||
find_package(Qt5Multimedia)
|
||||
find_package(Qt5Svg)
|
||||
|
||||
if(Qt5Widgets_FOUND)
|
||||
message(STATUS "Qt Version: ${Qt5Widgets_VERSION}")
|
||||
if(Qt5Core_FOUND)
|
||||
message(STATUS "Qt Version: ${Qt5Core_VERSION}")
|
||||
|
||||
### Get locations of Qt binary executables & libs (libs are for distros, not for linking)
|
||||
# first set up some hints
|
||||
get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
|
||||
get_filename_component(qt_core_path ${QtCore_LOCATION} PATH)
|
||||
if(APPLE)
|
||||
get_filename_component(qt_core_path "${qt_core_path}/.." ABSOLUTE)
|
||||
endif()
|
||||
|
||||
set(QT_LIB_DIR ${qt_core_path} CACHE PATH "Path to Qt libraries (.dll|.framework|.so).")
|
||||
find_path(QT_BIN_DIR NAMES "qmake" "qmake.exe" HINTS "${CMAKE_PREFIX_PATH}/bin" "${qt_core_path}/../bin" "${qt_core_path}" DOC "Path to Qt binaries (qmake, lupdate, etc.).")
|
||||
find_program(QT_QMAKE_EXECUTABLE qmake HINTS "${QT_BIN_DIR}" DOC "Location of qmake program.")
|
||||
find_program(QT_LUPDATE_EXECUTABLE lupdate HINTS "${QT_BIN_DIR}" DOC "Location of Qt's 'lupdate' program for updating translation files.")
|
||||
|
||||
# Try to find Qt translations
|
||||
if(QT_QMAKE_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
|
||||
OUTPUT_VARIABLE qt_translations_hint
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
find_path(QT_TRANSLATIONS_DIR NAMES "qt_en.qm" HINTS "${qt_translations_hint}" DOC "Path to prebuilt Qt translations (qt_*.qm).")
|
||||
|
||||
### Common definitions for the Qt-based apps
|
||||
list(APPEND APP_COMMON_DEFINES -DSIMU)
|
||||
list(APPEND APP_COMMON_DEFINES -DQXT_STATIC)
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_USE_QSTRINGBUILDER) # more efficient QString construction using % operator
|
||||
|
||||
if(APP_CUSTOM_DBG_HANDLER)
|
||||
# provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
|
||||
|
@ -84,6 +114,7 @@ if(Qt5Widgets_FOUND)
|
|||
else()
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0)
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Qt not found! Companion and Simulator builds disabled.")
|
||||
endif()
|
||||
|
@ -97,7 +128,7 @@ if(NOT WIN32)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5Widgets_FOUND OR FOX_FOUND)
|
||||
if(Qt5Core_FOUND OR FOX_FOUND)
|
||||
set(SDL_BUILDING_LIBRARY YES) # this prevents FindSDL from appending SDLmain lib to the results, which we don't want
|
||||
find_package("SDL")
|
||||
if(SDL_FOUND)
|
||||
|
@ -136,6 +167,6 @@ endif()
|
|||
|
||||
add_subdirectory(${RADIO_SRC_DIRECTORY})
|
||||
|
||||
if(Qt5Widgets_FOUND)
|
||||
if(Qt5Core_FOUND)
|
||||
add_subdirectory(${COMPANION_SRC_DIRECTORY})
|
||||
endif()
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# Locate lupdate binary from QT
|
||||
|
||||
# This module defines
|
||||
# LUPDATE_EXECUTABLE, where is QT lupdate
|
||||
# LUPDATE_FOUND, if false, don't try to use lupdate
|
||||
|
||||
FIND_PROGRAM( LUPDATE_EXECUTABLE
|
||||
NAMES
|
||||
lupdate lupdate-qt4
|
||||
)
|
||||
|
||||
# if the program is found then we have it
|
||||
IF( LUPDATE_EXECUTABLE )
|
||||
SET( LUPDATE_FOUND "YES" )
|
||||
ENDIF( LUPDATE_EXECUTABLE )
|
||||
|
||||
MARK_AS_ADVANCED( LUPDATE_EXECUTABLE )
|
|
@ -110,20 +110,52 @@ include_directories(
|
|||
${COMPANION_SRC_DIRECTORY}/storage
|
||||
)
|
||||
|
||||
############# Do macro replacements on input files #############
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY)
|
||||
|
||||
############# Supporting libraries ###############
|
||||
############# Translations ###############
|
||||
|
||||
add_subdirectory(shared)
|
||||
add_subdirectory(modeledit)
|
||||
add_subdirectory(generaledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(thirdparty/qcustomplot)
|
||||
add_subdirectory(thirdparty/qxtcommandoptions)
|
||||
### Generate .qm files and assemble resource (qrc) file.
|
||||
|
||||
# available Companion translations (src/translations/*.ts)
|
||||
set(LANGUAGES cs de en es fi fr it pl sv zh_CN)
|
||||
foreach(language ${LANGUAGES})
|
||||
list(APPEND companion_TS translations/companion_${language}.ts)
|
||||
endforeach(language)
|
||||
# .ts -> .qm
|
||||
qt5_add_translation(companion_QM ${companion_TS})
|
||||
|
||||
# add Qt translations if found
|
||||
if(QT_TRANSLATIONS_DIR)
|
||||
# Some languages have all translations in one qt_*.qm file and others break them up into modules, in which case we need qt_base_*.qm
|
||||
file(GLOB qtbase_QM "${QT_TRANSLATIONS_DIR}/qtbase_*.qm")
|
||||
file(GLOB qt_QM "${QT_TRANSLATIONS_DIR}/qt_??.qm") # don't want to match "qt_help_*.qm"
|
||||
list(APPEND qt_QM "${QT_TRANSLATIONS_DIR}/qt_zh_CN.qm" "${QT_TRANSLATIONS_DIR}/qt_zh_TW.qm") # exceptions not matched by the GLOB
|
||||
else()
|
||||
message(STATUS "QT_TRANSLATIONS_DIR not found, unable to package pre-built Qt translations with application.")
|
||||
endif()
|
||||
|
||||
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc")
|
||||
|
||||
# Dynamically create translations.qrc file (XML) from all collected translation files.
|
||||
foreach(qm_file ${companion_QM} ${qt_QM} ${qtbase_QM})
|
||||
get_filename_component(qm_file_name ${qm_file} NAME)
|
||||
# Add file with full path and file name (w/out path) as alias to be used in actual code
|
||||
set(TRANSLATION_FILES_LIST "${TRANSLATION_FILES_LIST} <file alias=\"${qm_file_name}\">${qm_file}</file>\n")
|
||||
endforeach()
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${TRANSLATIONS_QRC} @ONLY)
|
||||
|
||||
### Add optional "translations" target for updating .ts files
|
||||
if(QT_LUPDATE_EXECUTABLE)
|
||||
add_custom_target(translations
|
||||
WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY}
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS}
|
||||
)
|
||||
else()
|
||||
message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.")
|
||||
endif()
|
||||
|
||||
############# Common lib ###############
|
||||
|
||||
|
@ -134,6 +166,7 @@ set(common_SRCS
|
|||
eeprominterface.cpp
|
||||
helpers.cpp
|
||||
radiodata.cpp
|
||||
translations.cpp
|
||||
firmwares/er9x/er9xeeprom.cpp
|
||||
firmwares/er9x/er9xinterface.cpp
|
||||
firmwares/ersky9x/ersky9xeeprom.cpp
|
||||
|
@ -152,23 +185,29 @@ set(common_MOC_HDRS
|
|||
|
||||
set(common_RESOURCES
|
||||
companion.qrc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/translations.qrc
|
||||
${TRANSLATIONS_QRC}
|
||||
)
|
||||
|
||||
set(LANGUAGES pl de fr es it sv cs fi zh)
|
||||
foreach(language ${LANGUAGES})
|
||||
list(APPEND common_TS translations/companion_${language}.ts)
|
||||
endforeach(language)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
|
||||
qt5_add_translation(common_QM ${common_TS})
|
||||
qt5_add_resources(common_RCC ${common_RESOURCES})
|
||||
add_custom_target(gen_qrc DEPENDS ${common_RCC} ${common_QM})
|
||||
#add_custom_target(gen_qrc DEPENDS ${common_RCC} ${companion_QM})
|
||||
|
||||
add_library(common ${common_SRCS} ${common_RCC})
|
||||
qt5_use_modules(common Core Xml Widgets)
|
||||
target_link_libraries(common PRIVATE simulation)
|
||||
add_dependencies(common gen_qrc)
|
||||
#add_dependencies(common gen_qrc)
|
||||
|
||||
set(CPN_COMMON_LIB common)
|
||||
|
||||
############# Supporting libraries ###############
|
||||
|
||||
add_subdirectory(shared)
|
||||
add_subdirectory(modeledit)
|
||||
add_subdirectory(generaledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(thirdparty/qcustomplot)
|
||||
add_subdirectory(thirdparty/qxtcommandoptions)
|
||||
|
||||
############# Companion ###############
|
||||
|
||||
|
@ -259,15 +298,15 @@ set(companion_UIS
|
|||
)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND companion_SRCS icon.rc)
|
||||
set(icon_RC icon.rc)
|
||||
endif()
|
||||
|
||||
qt5_wrap_ui(companion_SRCS ${companion_UIS})
|
||||
qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})
|
||||
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS})
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${icon_RC})
|
||||
qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
|
||||
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation common qcustomplot shared storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation ${CPN_COMMON_LIB} qcustomplot shared storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
|
||||
PrintTargetReport("${COMPANION_NAME}")
|
||||
|
||||
|
@ -275,25 +314,8 @@ PrintTargetReport("${COMPANION_NAME}")
|
|||
|
||||
set(simu_SRCS simulator.cpp )
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND simu_SRCS icon.rc)
|
||||
endif()
|
||||
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
|
||||
############# Translations ####################
|
||||
|
||||
find_package(Lupdate)
|
||||
if(LUPDATE_FOUND)
|
||||
message(STATUS "Qt lupdate: " ${LUPDATE_EXECUTABLE})
|
||||
add_custom_target(translations
|
||||
WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY}
|
||||
COMMAND ${LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${common_TS}
|
||||
)
|
||||
else()
|
||||
message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.")
|
||||
endif()
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation ${CPN_COMMON_LIB} storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
|
||||
############# Install ####################
|
||||
|
||||
|
@ -335,8 +357,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
|
||||
elseif(WIN32)
|
||||
|
||||
get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
|
||||
get_filename_component(QT_DLL_DIR ${QtCore_LOCATION} PATH)
|
||||
set(QT_DLL_DIR ${QT_LIB_DIR})
|
||||
set(INSTALL_TEMP_QTDLL_FILES Qt5Core Qt5Gui Qt5Widgets Qt5Xml Qt5Network Qt5PrintSupport Qt5Multimedia Qt5Svg)
|
||||
set(INSTALL_TEMP_ICUDLL_FILES icudt54.dll icuin54.dll icuuc54.dll)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
@ -415,7 +436,7 @@ if(WIN32)
|
|||
|
||||
set(SYSDIR "$ENV{windir}/system32")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${COMPANION_NSI_IN_FILE} ${PROJECT_BINARY_DIR}/companion/companion.nsi @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${SIMULATOR_NSI_IN_FILE} ${PROJECT_BINARY_DIR}/companion/simulator.nsi @ONLY)
|
||||
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${SIMULATOR_NSI_IN_FILE} ${PROJECT_BINARY_DIR}/companion/simulator.nsi @ONLY)
|
||||
|
||||
find_program(NSIS_EXE makensis.exe PATHS
|
||||
"C:/Program Files/NSIS"
|
||||
|
@ -428,16 +449,16 @@ if(WIN32)
|
|||
DEPENDS companion simulator opentx-simulators ${PROJECT_BINARY_DIR}/companion/companion.nsi
|
||||
COMMENT "Companion Windows NSIS Installer")
|
||||
|
||||
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/companion/simulator-install.exe
|
||||
COMMAND "${NSIS_EXE}" ARGS ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
DEPENDS simulator ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
COMMENT "Simulator Windows NSIS Installer")
|
||||
# add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/companion/simulator-install.exe
|
||||
# COMMAND "${NSIS_EXE}" ARGS ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
# DEPENDS simulator ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
# COMMENT "Simulator Windows NSIS Installer")
|
||||
|
||||
add_custom_target(installer
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/companion/companion-windows.exe
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/companion/simulator-windows.exe
|
||||
# DEPENDS ${PROJECT_BINARY_DIR}/companion/simulator-windows.exe
|
||||
SOURCES ${PROJECT_BINARY_DIR}/companion/companion.nsi
|
||||
SOURCES ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
# SOURCES ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -507,11 +528,6 @@ IF(APPLE)
|
|||
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")
|
||||
|
||||
# These needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
|
||||
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
||||
|
||||
# Include depencies (adding frameworks, fixing the embbeded libraries)
|
||||
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
|
||||
# technically a hack (that is already is in the Bundle library ...)
|
||||
|
@ -519,7 +535,7 @@ IF(APPLE)
|
|||
include(BundleUtilities)
|
||||
file(GLOB bundle_simulator_libs \"\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS on)
|
||||
fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_tools_path}\" \"${QT_LIBRARY_DIR}\")
|
||||
fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_tools_path}\" \"${QT_LIB_DIR}\")
|
||||
file(RENAME \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\")
|
||||
" COMPONENT Runtime)
|
||||
endif()
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QDir>
|
||||
#include <QSplashScreen>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
|
@ -33,6 +31,7 @@
|
|||
#include "version.h"
|
||||
#include "appdata.h"
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QProxyStyle>
|
||||
|
@ -61,7 +60,6 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
Q_INIT_RESOURCE(companion);
|
||||
Q_INIT_RESOURCE(translations);
|
||||
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
@ -81,17 +79,7 @@ int main(int argc, char *argv[])
|
|||
app.setStyle(new MyProxyStyle);
|
||||
#endif
|
||||
|
||||
QTranslator companionTranslator;
|
||||
companionTranslator.load(":/companion_" + g.locale());
|
||||
QTranslator qtTranslator;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
|
||||
QString qtfile = "qtbase_";
|
||||
#else
|
||||
QString qtfile = "qt_";
|
||||
#endif
|
||||
qtTranslator.load(qtfile + g.locale().left(2), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
app.installTranslator(&companionTranslator);
|
||||
app.installTranslator(&qtTranslator);
|
||||
Translations::installTranslators();
|
||||
|
||||
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
|
|
|
@ -23,9 +23,10 @@ foreach(name ${generaledit_NAMES})
|
|||
set(generaledit_HDRS ${generaledit_HDRS} ${name}.h)
|
||||
set(generaledit_UIS ${generaledit_UIS} ${name}.ui)
|
||||
endforeach()
|
||||
|
||||
|
||||
qt5_wrap_ui(generaledit_SRCS ${generaledit_UIS})
|
||||
qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS})
|
||||
|
||||
add_library(generaledit ${generaledit_SRCS})
|
||||
qt5_use_modules(generaledit Widgets Xml Multimedia)
|
||||
qt5_use_modules(generaledit Widgets Xml Multimedia)
|
||||
target_link_libraries(generaledit PRIVATE ${CPN_COMMON_LIB})
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "radiointerface.h"
|
||||
#include "progressdialog.h"
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
|
||||
#include <QtGui>
|
||||
#include <QNetworkProxyFactory>
|
||||
#include <QFileInfo>
|
||||
|
@ -69,7 +71,16 @@
|
|||
|
||||
MainWindow::MainWindow():
|
||||
downloadDialog_forWait(NULL),
|
||||
checkForUpdatesState(0)
|
||||
checkForUpdatesState(0),
|
||||
fileMenu(NULL),
|
||||
editMenu(NULL),
|
||||
settingsMenu(NULL),
|
||||
burnMenu(NULL),
|
||||
helpMenu(NULL),
|
||||
fileToolBar(NULL),
|
||||
editToolBar(NULL),
|
||||
burnToolBar(NULL),
|
||||
helpToolBar(NULL)
|
||||
{
|
||||
mdiArea = new QMdiArea(this);
|
||||
mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
@ -518,10 +529,37 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::changeEvent(QEvent * e)
|
||||
{
|
||||
QMainWindow::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
retranslateUi();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::retranslateUi()
|
||||
{
|
||||
createActions();
|
||||
createMenus();
|
||||
createToolBars();
|
||||
QMessageBox::information(this, tr("Companion"), tr("Some text will not be translated until the next time you start Companion. Please note that some translations may not be complete."));
|
||||
}
|
||||
|
||||
void MainWindow::setLanguage(const QString & langString)
|
||||
{
|
||||
g.locale(langString);
|
||||
QMessageBox::information(this, tr("Companion"), tr("The selected language will be used the next time you start Companion."));
|
||||
Translations::installTranslators();
|
||||
}
|
||||
|
||||
void MainWindow::onLanguageChanged(QAction * act)
|
||||
{
|
||||
QString lang = act->property("locale").toString();
|
||||
if (!lang.isNull())
|
||||
setLanguage(lang);
|
||||
}
|
||||
|
||||
void MainWindow::setTheme(int index)
|
||||
|
@ -530,20 +568,36 @@ void MainWindow::setTheme(int index)
|
|||
QMessageBox::information(this, tr("Companion"), tr("The new theme will be loaded the next time you start Companion."));
|
||||
}
|
||||
|
||||
void MainWindow::onThemeChanged(QAction * act)
|
||||
{
|
||||
bool ok;
|
||||
int id = act->property("themeId").toInt(&ok);
|
||||
if (ok && id >= 0 && id < 5)
|
||||
setTheme(id);
|
||||
}
|
||||
|
||||
void MainWindow::setIconThemeSize(int index)
|
||||
{
|
||||
g.iconSize(index);
|
||||
QMessageBox::information(this, tr("Companion"), tr("The icon size will be used the next time you start Companion."));
|
||||
}
|
||||
|
||||
void MainWindow::onIconSizeChanged(QAction * act)
|
||||
{
|
||||
bool ok;
|
||||
int id = act->property("sizeId").toInt(&ok);
|
||||
if (ok && id >= 0 && id < 4)
|
||||
setIconThemeSize(id);
|
||||
}
|
||||
|
||||
void MainWindow::newFile()
|
||||
{
|
||||
MdiChild * child = createMdiChild();
|
||||
child->newFile();
|
||||
|
||||
|
||||
if (IS_HORUS(getCurrentBoard())) {
|
||||
child->categoryAdd();
|
||||
}
|
||||
}
|
||||
child->show();
|
||||
}
|
||||
|
||||
|
@ -889,9 +943,6 @@ void MainWindow::updateMenus()
|
|||
compareAct->setEnabled(activeMdiChild());
|
||||
updateRecentFileActions();
|
||||
updateProfilesActions();
|
||||
updateLanguageActions();
|
||||
updateIconSizeActions();
|
||||
updateIconThemeActions();
|
||||
setWindowTitle(tr("OpenTX Companion %1 - Radio: %2 - Profile: %3").arg(VERSION).arg(getCurrentFirmware()->getName()).arg(g.profile[g.id()].name()));
|
||||
}
|
||||
|
||||
|
@ -929,6 +980,7 @@ QAction * MainWindow::addAct(const QString & icon, const QString & sName, const
|
|||
if (slotObj == NULL)
|
||||
slotObj = this;
|
||||
connect(newAction, SIGNAL(triggered()), slotObj, slot);
|
||||
actionsList.append(newAction);
|
||||
return newAction;
|
||||
}
|
||||
|
||||
|
@ -938,33 +990,46 @@ QAction * MainWindow::addAct(const QString & icon, const QString & sName, const
|
|||
return addAct(icon, sName, lName, QKeySequence::UnknownKey, slot);
|
||||
}
|
||||
|
||||
QAction * MainWindow::addAct(QActionGroup *aGroup, const QString & sName, const QString & lName, const char *slot)
|
||||
QAction * MainWindow::addActToGroup(QActionGroup * aGroup, const QString & sName, const QString & lName, const char * propName, const QVariant & propValue, const QVariant & dfltValue)
|
||||
{
|
||||
QAction *action = addAct("", sName, lName, QKeySequence::UnknownKey, slot);
|
||||
action->setCheckable(true);
|
||||
aGroup->addAction(action);
|
||||
return action;
|
||||
QAction * act = aGroup->addAction(sName);
|
||||
act->setStatusTip(lName);
|
||||
act->setCheckable(true);
|
||||
if (propName) {
|
||||
act->setProperty(propName, propValue);
|
||||
if (propValue == dfltValue)
|
||||
act->setChecked(true);
|
||||
}
|
||||
return act;
|
||||
}
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
foreach (QAction * act, actionsList) {
|
||||
if (act)
|
||||
act->deleteLater();
|
||||
}
|
||||
actionsList.clear();
|
||||
|
||||
separatorAct = new QAction(this);
|
||||
separatorAct->setSeparator(true);
|
||||
actionsList.append(separatorAct);
|
||||
|
||||
for (int i = 0; i < MAX_RECENT; ++i) {
|
||||
recentFileActs[i] = new QAction(this);
|
||||
recentFileActs[i]->setVisible(false);
|
||||
connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));
|
||||
actionsList.append(recentFileActs[i]);
|
||||
}
|
||||
updateRecentFileActions();
|
||||
|
||||
QActionGroup *profilesAlignmentGroup = new QActionGroup(this);
|
||||
for (int i=0; i<MAX_PROFILES; i++) {
|
||||
profileActs[i] = new QAction(this);
|
||||
profileActs[i] = new QAction(profilesAlignmentGroup);
|
||||
profileActs[i]->setVisible(false);
|
||||
profileActs[i]->setCheckable(true);
|
||||
profilesAlignmentGroup->addAction(profileActs[i]);
|
||||
connect(profileActs[i], SIGNAL(triggered()), this, SLOT(loadProfile()));
|
||||
actionsList.append(profileActs[i]);
|
||||
}
|
||||
updateProfilesActions();
|
||||
|
||||
|
@ -977,36 +1042,6 @@ void MainWindow::createActions()
|
|||
copyAct = addAct("copy.png", tr("Copy Model"), tr("Copy current model to the clipboard"), QKeySequence::Copy, SLOT(copy()));
|
||||
pasteAct = addAct("paste.png", tr("Paste Model"), tr("Paste model from clipboard"), QKeySequence::Paste, SLOT(paste()));
|
||||
|
||||
QActionGroup *themeAlignGroup = new QActionGroup(this);
|
||||
classicThemeAct = addAct( themeAlignGroup, tr("Classical"), tr("The classic companion9x icon theme"), SLOT(setClassicTheme()));
|
||||
yericoThemeAct = addAct( themeAlignGroup, tr("Yerico"), tr("Yellow round honey sweet icon theme"), SLOT(setYericoTheme()));
|
||||
monoThemeAct = addAct( themeAlignGroup, tr("Monochrome"), tr("A monochrome black icon theme"), SLOT(setMonochromeTheme()));
|
||||
monoWhiteAct = addAct( themeAlignGroup, tr("MonoWhite"), tr("A monochrome white icon theme"), SLOT(setMonoWhiteTheme()));
|
||||
monoBlueAct = addAct( themeAlignGroup, tr("MonoBlue"), tr("A monochrome blue icon theme"), SLOT(setMonoBlueTheme()));
|
||||
|
||||
QActionGroup *iconAlignGroup = new QActionGroup(this);
|
||||
smallIconAct = addAct( iconAlignGroup, tr("Small"), tr("Use small toolbar icons"), SLOT(setSmallIconThemeSize()));
|
||||
normalIconAct = addAct( iconAlignGroup, tr("Normal"), tr("Use normal size toolbar icons"), SLOT(setNormalIconThemeSize()));
|
||||
bigIconAct = addAct( iconAlignGroup, tr("Big"), tr("Use big toolbar icons"), SLOT(setBigIconThemeSize()));
|
||||
hugeIconAct = addAct( iconAlignGroup, tr("Huge"), tr("Use huge toolbar icons"), SLOT(setHugeIconThemeSize()));
|
||||
|
||||
QActionGroup *langAlignGroup = new QActionGroup(this);
|
||||
sysLangAct = addAct( langAlignGroup, tr("System language"), tr("Use system language in menus"), SLOT(setSysLanguage()));
|
||||
czechLangAct = addAct( langAlignGroup, tr("Czech"), tr("Use Czech in menus"), SLOT(setCZLanguage()));
|
||||
germanLangAct = addAct( langAlignGroup, tr("German"), tr("Use German in menus"), SLOT(setDELanguage()));
|
||||
englishLangAct = addAct( langAlignGroup, tr("English"), tr("Use English in menus"), SLOT(setENLanguage()));
|
||||
finnishLangAct = addAct( langAlignGroup, tr("Finnish"), tr("Use Finnish in menus"), SLOT(setFILanguage()));
|
||||
frenchLangAct = addAct( langAlignGroup, tr("French"), tr("Use French in menus"), SLOT(setFRLanguage()));
|
||||
italianLangAct = addAct( langAlignGroup, tr("Italian"), tr("Use Italian in menus"), SLOT(setITLanguage()));
|
||||
// hebrewLangAct = addAct( langAlignGroup, tr("Hebrew"), tr("Use Hebrew in menus"), SLOT(setHELanguage()));
|
||||
polishLangAct = addAct( langAlignGroup, tr("Polish"), tr("Use Polish in menus"), SLOT(setPLLanguage()));
|
||||
// portugueseLangAct = addAct( langAlignGroup, tr("Portuguese"), tr("Use Portuguese in menus"), SLOT(setPTLanguage()));
|
||||
spanishLangAct = addAct( langAlignGroup, tr("Spanish"), tr("Use Spanish in menus"), SLOT(setESLanguage()));
|
||||
swedishLangAct = addAct( langAlignGroup, tr("Swedish"), tr("Use Swedish in menus"), SLOT(setSELanguage()));
|
||||
// russianLangAct = addAct( langAlignGroup, tr("Russian"), tr("Use Russian in menus"), SLOT(setRULanguage()));
|
||||
// dutchLangAct = addAct( langAlignGroup, tr("Dutch"), tr("Use Dutch in menus"), SLOT(setNLLanguage()));
|
||||
chineseLangAct = addAct( langAlignGroup, tr("Chinese"), tr("Use Chinese in menus"), SLOT(setCNLanguage()));
|
||||
|
||||
aboutAct = addAct("information.png", tr("About..."), tr("Show the application's About box"), SLOT(about()));
|
||||
printAct = addAct("print.png", tr("Print..."), tr("Print current model"), QKeySequence::Print, SLOT(print()));
|
||||
simulateAct = addAct("simulate.png", tr("Simulate..."), tr("Simulate current model"), QKeySequence(tr("Alt+S")), SLOT(simulate()));
|
||||
|
@ -1038,23 +1073,42 @@ void MainWindow::createActions()
|
|||
printAct->setEnabled(false);
|
||||
}
|
||||
|
||||
QMenu * MainWindow::createLanguageMenu(QWidget * parent)
|
||||
{
|
||||
QMenu * menu = new QMenu(tr("Set Menu Language"), parent);
|
||||
QActionGroup * actGroup = new QActionGroup(menu);
|
||||
QString lName;
|
||||
|
||||
addActToGroup(actGroup, tr("System language"), tr("Use default system language."), "locale", QString(""), g.locale());
|
||||
foreach (const QString & lang, Translations::getAvailableTranslations()) {
|
||||
QLocale locale(lang);
|
||||
lName = locale.nativeLanguageName();
|
||||
addActToGroup(actGroup, lName.left(1).toUpper() % lName.mid(1), tr("Use %1 language (some translations may not be complete).").arg(lName), "locale", lang, g.locale());
|
||||
}
|
||||
if (!actGroup->checkedAction())
|
||||
actGroup->actions().first()->setChecked(true);
|
||||
|
||||
connect(actGroup, &QActionGroup::triggered, this, &MainWindow::onLanguageChanged);
|
||||
menu->addActions(actGroup->actions());
|
||||
return menu;
|
||||
}
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
QMenu *recentFileMenu = new QMenu(tr("Recent Files"), this);
|
||||
QMenu *languageMenu = new QMenu(tr("Set Menu Language"), this);
|
||||
QMenu *themeMenu = new QMenu(tr("Set Icon Theme"), this);
|
||||
QMenu *iconThemeSizeMenu = new QMenu(tr("Set Icon Size"), this);
|
||||
menuBar()->clear();
|
||||
|
||||
if (fileMenu) {
|
||||
fileMenu->deleteLater();
|
||||
}
|
||||
fileMenu = menuBar()->addMenu(tr("File"));
|
||||
fileMenu->addAction(newAct);
|
||||
fileMenu->addAction(openAct);
|
||||
fileMenu->addAction(saveAct);
|
||||
fileMenu->addAction(saveAsAct);
|
||||
fileMenu->addMenu(recentFileMenu);
|
||||
|
||||
QMenu *recentFileMenu = new QMenu(tr("Recent Files"), fileMenu);
|
||||
recentFileMenu->setIcon(CompanionIcon("recentdocument.png"));
|
||||
for (int i=0; i<MAX_RECENT; ++i) {
|
||||
recentFileMenu->addAction(recentFileActs[i]);
|
||||
}
|
||||
|
||||
fileMenu->addMenu(recentFileMenu);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(logsAct);
|
||||
fileMenu->addAction(fwPrefsAct);
|
||||
|
@ -1066,46 +1120,50 @@ void MainWindow::createMenus()
|
|||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(exitAct);
|
||||
|
||||
if (editMenu) {
|
||||
editMenu->deleteLater();
|
||||
}
|
||||
editMenu = menuBar()->addMenu(tr("Edit"));
|
||||
editMenu->addAction(cutAct);
|
||||
editMenu->addAction(copyAct);
|
||||
editMenu->addAction(pasteAct);
|
||||
|
||||
if (settingsMenu) {
|
||||
settingsMenu->deleteLater();
|
||||
}
|
||||
settingsMenu = menuBar()->addMenu(tr("Settings"));
|
||||
settingsMenu->addMenu(languageMenu);
|
||||
languageMenu->addAction(sysLangAct);
|
||||
languageMenu->addAction(englishLangAct);
|
||||
languageMenu->addAction(czechLangAct);
|
||||
languageMenu->addAction(germanLangAct);
|
||||
languageMenu->addAction(finnishLangAct);
|
||||
languageMenu->addAction(frenchLangAct);
|
||||
languageMenu->addAction(italianLangAct);
|
||||
// languageMenu->addAction(hebrewLangAct);
|
||||
languageMenu->addAction(polishLangAct);
|
||||
// languageMenu->addAction(portugueseLangAct);
|
||||
languageMenu->addAction(spanishLangAct);
|
||||
languageMenu->addAction(swedishLangAct);
|
||||
// languageMenu->addAction(russianLangAct);
|
||||
// languageMenu->addAction(dutchLangAct);
|
||||
languageMenu->addAction(chineseLangAct);
|
||||
|
||||
QMenu *themeMenu = new QMenu(tr("Set Icon Theme"), settingsMenu);
|
||||
QActionGroup * themeGroup = new QActionGroup(themeMenu);
|
||||
addActToGroup(themeGroup, tr("Classical"), tr("The classic companion9x icon theme"), "themeId", 0, g.theme());
|
||||
addActToGroup(themeGroup, tr("Yerico"), tr("Yellow round honey sweet icon theme"), "themeId", 1, g.theme());
|
||||
addActToGroup(themeGroup, tr("Monochrome"), tr("A monochrome black icon theme"), "themeId", 3, g.theme());
|
||||
addActToGroup(themeGroup, tr("MonoBlue"), tr("A monochrome blue icon theme"), "themeId", 4, g.theme());
|
||||
addActToGroup(themeGroup, tr("MonoWhite"), tr("A monochrome white icon theme"), "themeId", 2, g.theme());
|
||||
connect(themeGroup, &QActionGroup::triggered, this, &MainWindow::onThemeChanged);
|
||||
themeMenu->addActions(themeGroup->actions());
|
||||
|
||||
QMenu *iconThemeSizeMenu = new QMenu(tr("Set Icon Size"), settingsMenu);
|
||||
QActionGroup * szGroup = new QActionGroup(iconThemeSizeMenu);
|
||||
addActToGroup(szGroup, tr("Small"), tr("Use small toolbar icons"), "sizeId", 0, g.iconSize());
|
||||
addActToGroup(szGroup, tr("Normal"), tr("Use normal size toolbar icons"), "sizeId", 1, g.iconSize());
|
||||
addActToGroup(szGroup, tr("Big"), tr("Use big toolbar icons"), "sizeId", 2, g.iconSize());
|
||||
addActToGroup(szGroup, tr("Huge"), tr("Use huge toolbar icons"), "sizeId", 3, g.iconSize());
|
||||
connect(szGroup, &QActionGroup::triggered, this, &MainWindow::onIconSizeChanged);
|
||||
iconThemeSizeMenu->addActions(szGroup->actions());
|
||||
|
||||
settingsMenu->addMenu(createLanguageMenu(settingsMenu));
|
||||
settingsMenu->addMenu(themeMenu);
|
||||
themeMenu->addAction(classicThemeAct);
|
||||
themeMenu->addAction(yericoThemeAct);
|
||||
themeMenu->addAction(monoThemeAct);
|
||||
themeMenu->addAction(monoBlueAct);
|
||||
themeMenu->addAction(monoWhiteAct);
|
||||
settingsMenu->addMenu(iconThemeSizeMenu);
|
||||
iconThemeSizeMenu->addAction(smallIconAct);
|
||||
iconThemeSizeMenu->addAction(normalIconAct);
|
||||
iconThemeSizeMenu->addAction(bigIconAct);
|
||||
iconThemeSizeMenu->addAction(hugeIconAct);
|
||||
settingsMenu->addSeparator();
|
||||
settingsMenu->addAction(appPrefsAct);
|
||||
settingsMenu->addMenu(createProfilesMenu());
|
||||
settingsMenu->addAction(editSplashAct);
|
||||
settingsMenu->addAction(burnConfigAct);
|
||||
|
||||
if (burnMenu) {
|
||||
burnMenu->deleteLater();
|
||||
}
|
||||
burnMenu = menuBar()->addMenu(tr("Read/Write"));
|
||||
burnMenu->addAction(writeEepromAct);
|
||||
burnMenu->addAction(readEepromAct);
|
||||
|
@ -1121,7 +1179,10 @@ void MainWindow::createMenus()
|
|||
burnMenu->addAction(burnFusesAct);
|
||||
burnMenu->addAction(burnListAct);
|
||||
}
|
||||
menuBar()->addSeparator();
|
||||
|
||||
if (helpMenu) {
|
||||
helpMenu->deleteLater();
|
||||
}
|
||||
helpMenu = menuBar()->addMenu(tr("Help"));
|
||||
helpMenu->addSeparator();
|
||||
helpMenu->addAction(checkForUpdatesAct);
|
||||
|
@ -1177,6 +1238,12 @@ void MainWindow::createToolBars()
|
|||
size=QSize(24,24);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileToolBar) {
|
||||
removeToolBar(fileToolBar);
|
||||
fileToolBar->deleteLater();
|
||||
}
|
||||
|
||||
fileToolBar = addToolBar(tr("File"));
|
||||
fileToolBar->setIconSize(size);
|
||||
fileToolBar->setObjectName("File");
|
||||
|
@ -1215,6 +1282,11 @@ void MainWindow::createToolBars()
|
|||
fileToolBar->addAction(compareAct);
|
||||
fileToolBar->addAction(sdsyncAct);
|
||||
|
||||
if (editToolBar) {
|
||||
removeToolBar(editToolBar);
|
||||
editToolBar->deleteLater();
|
||||
}
|
||||
|
||||
editToolBar = addToolBar(tr("Edit"));
|
||||
editToolBar->setIconSize(size);
|
||||
editToolBar->setObjectName("Edit");
|
||||
|
@ -1222,6 +1294,11 @@ void MainWindow::createToolBars()
|
|||
editToolBar->addAction(copyAct);
|
||||
editToolBar->addAction(pasteAct);
|
||||
|
||||
if (burnToolBar) {
|
||||
removeToolBar(burnToolBar);
|
||||
burnToolBar->deleteLater();
|
||||
}
|
||||
|
||||
burnToolBar = new QToolBar(tr("Write"));
|
||||
addToolBar( Qt::LeftToolBarArea, burnToolBar );
|
||||
burnToolBar->setIconSize(size);
|
||||
|
@ -1237,6 +1314,11 @@ void MainWindow::createToolBars()
|
|||
burnToolBar->addSeparator();
|
||||
burnToolBar->addAction(burnConfigAct);
|
||||
|
||||
if (helpToolBar) {
|
||||
removeToolBar(helpToolBar);
|
||||
helpToolBar->deleteLater();
|
||||
}
|
||||
|
||||
helpToolBar = addToolBar(tr("Help"));
|
||||
helpToolBar->setIconSize(size);
|
||||
helpToolBar->setObjectName("Help");
|
||||
|
@ -1295,63 +1377,6 @@ void MainWindow::updateRecentFileActions()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateIconSizeActions()
|
||||
{
|
||||
switch (g.iconSize()) {
|
||||
case 0: smallIconAct->setChecked(true); break;
|
||||
case 1: normalIconAct->setChecked(true); break;
|
||||
case 2: bigIconAct->setChecked(true); break;
|
||||
case 3: hugeIconAct->setChecked(true); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateLanguageActions()
|
||||
{
|
||||
QString langId = g.locale();
|
||||
|
||||
if (langId=="")
|
||||
sysLangAct->setChecked(true);
|
||||
else if (langId=="cs_CZ")
|
||||
czechLangAct->setChecked(true);
|
||||
else if (langId=="de_DE")
|
||||
germanLangAct->setChecked(true);
|
||||
else if (langId=="en")
|
||||
englishLangAct->setChecked(true);
|
||||
else if (langId=="fi_FI")
|
||||
finnishLangAct->setChecked(true);
|
||||
else if (langId=="fr_FR")
|
||||
frenchLangAct->setChecked(true);
|
||||
else if (langId=="it_IT")
|
||||
italianLangAct->setChecked(true);
|
||||
// else if (langId=="he_IL")
|
||||
// hebrewLangAct->setChecked(true);
|
||||
else if (langId=="pl_PL")
|
||||
polishLangAct->setChecked(true);
|
||||
// else if (langId=="pt_PT")
|
||||
// portugueseLangAct->setChecked(true);
|
||||
else if (langId=="es_ES")
|
||||
spanishLangAct->setChecked(true);
|
||||
else if (langId=="sv_SE")
|
||||
swedishLangAct->setChecked(true);
|
||||
// else if (langId=="ru_RU")
|
||||
// russianLangAct->setChecked(true);
|
||||
// else if (langId=="nl_NL")
|
||||
// dutchLangAct->setChecked(true);
|
||||
else if (langId=="zh_CN")
|
||||
chineseLangAct->setChecked(true);
|
||||
}
|
||||
|
||||
void MainWindow::updateIconThemeActions()
|
||||
{
|
||||
switch (g.theme()) {
|
||||
case 0: classicThemeAct->setChecked(true); break;
|
||||
case 1: yericoThemeAct->setChecked(true); break;
|
||||
case 2: monoWhiteAct->setChecked(true); break;
|
||||
case 3: monoThemeAct->setChecked(true); break;
|
||||
case 4: monoBlueAct->setChecked(true); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateProfilesActions()
|
||||
{
|
||||
for (int i=0; i<MAX_PROFILES; i++) {
|
||||
|
|
|
@ -52,47 +52,32 @@ class MainWindow : public QMainWindow
|
|||
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
|
||||
signals:
|
||||
void FirmwareChanged();
|
||||
|
||||
protected:
|
||||
QString getCompanionUpdateBaseUrl();
|
||||
QString seekCodeString(const QByteArray & qba, const QString & label);
|
||||
|
||||
protected slots:
|
||||
void dowloadLastFirmwareUpdate();
|
||||
void startFirmwareDownload();
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
void setLanguage(const QString & langString);
|
||||
QString seekCodeString(const QByteArray & qba, const QString & label);
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
virtual void changeEvent(QEvent *e);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
|
||||
private slots:
|
||||
void openDocURL();
|
||||
void retranslateUi();
|
||||
|
||||
void setSysLanguage() { setLanguage(""); };
|
||||
void setCZLanguage() { setLanguage("cs_CZ"); };
|
||||
void setDELanguage() { setLanguage("de_DE"); };
|
||||
void setENLanguage() { setLanguage("en"); };
|
||||
void setFILanguage() { setLanguage("fi_FI"); };
|
||||
void setFRLanguage() { setLanguage("fr_FR"); };
|
||||
void setITLanguage() { setLanguage("it_IT"); };
|
||||
void setPLLanguage() { setLanguage("pl_PL"); };
|
||||
void setESLanguage() { setLanguage("es_ES"); };
|
||||
void setSELanguage() { setLanguage("sv_SE"); };
|
||||
void setCNLanguage() { setLanguage("zh_CN"); };
|
||||
|
||||
void setLanguage(const QString & langString);
|
||||
void onLanguageChanged(QAction * act);
|
||||
void setTheme(int index);
|
||||
void setClassicTheme() {setTheme(0);};
|
||||
void setYericoTheme() {setTheme(1);};
|
||||
void setMonoWhiteTheme() {setTheme(2);};
|
||||
void setMonochromeTheme(){setTheme(3);};
|
||||
void setMonoBlueTheme() {setTheme(4);};
|
||||
|
||||
void onThemeChanged(QAction * act);
|
||||
void setIconThemeSize(int index);
|
||||
void setSmallIconThemeSize() {setIconThemeSize(0);};
|
||||
void setNormalIconThemeSize() {setIconThemeSize(1);};
|
||||
void setBigIconThemeSize() {setIconThemeSize(2);};
|
||||
void setHugeIconThemeSize() {setIconThemeSize(3);};
|
||||
void onIconSizeChanged(QAction * act);
|
||||
|
||||
void checkForUpdates();
|
||||
void checkForFirmwareUpdate();
|
||||
|
@ -138,34 +123,34 @@ class MainWindow : public QMainWindow
|
|||
void fwPrefs();
|
||||
void updateMenus();
|
||||
void createProfile();
|
||||
MdiChild * createMdiChild();
|
||||
void setActiveSubWindow(QWidget *window);
|
||||
QMenu * createRecentFileMenu();
|
||||
QMenu * createProfilesMenu();
|
||||
void autoClose();
|
||||
|
||||
private:
|
||||
void closeUpdatesWaitDialog();
|
||||
void onUpdatesError();
|
||||
void openFile(const QString & fileName, bool updateLastUsedDir = false);
|
||||
|
||||
void createActions();
|
||||
private:
|
||||
QAction * addAct(const QString &, const QString &, const QString &, enum QKeySequence::StandardKey, const char *, QObject *slotObj=NULL);
|
||||
QAction * addAct(const QString &, const QString &, const QString &, const QKeySequence &, const char *, QObject *slotObj=NULL);
|
||||
QAction * addAct(QActionGroup *, const QString &, const QString &, const char *);
|
||||
QAction * addAct(const QString &, const QString &, const QString &, const char *);
|
||||
QAction * addActToGroup(QActionGroup * aGroup, const QString & sName, const QString & lName,
|
||||
const char * propName = 0, const QVariant & propValue = QVariant(), const QVariant & dfltValue = QVariant());
|
||||
|
||||
QMenu * createLanguageMenu(QWidget * parent = Q_NULLPTR);
|
||||
QMenu * createRecentFileMenu();
|
||||
QMenu * createProfilesMenu();
|
||||
|
||||
void createActions();
|
||||
void createMenus();
|
||||
void createToolBars();
|
||||
void createStatusBar();
|
||||
void updateRecentFileActions();
|
||||
void updateProfilesActions();
|
||||
void updateIconSizeActions();
|
||||
void updateLanguageActions();
|
||||
void updateIconThemeActions();
|
||||
void openFile(const QString & fileName, bool updateLastUsedDir = false);
|
||||
|
||||
QString strippedName(const QString & fullFileName);
|
||||
|
||||
MdiChild * createMdiChild();
|
||||
MdiChild * activeMdiChild();
|
||||
QMdiSubWindow * findMdiChild(const QString & fileName);
|
||||
|
||||
|
@ -182,6 +167,8 @@ class MainWindow : public QMainWindow
|
|||
|
||||
QNetworkAccessManager *networkManager;
|
||||
|
||||
QVector<QAction *> actionsList;
|
||||
|
||||
QMenu *fileMenu;
|
||||
QMenu *editMenu;
|
||||
QMenu *settingsMenu;
|
||||
|
@ -226,28 +213,6 @@ class MainWindow : public QMainWindow
|
|||
QAction *recentFileActs[MAX_RECENT];
|
||||
QAction *profileActs[MAX_PROFILES];
|
||||
QAction *createProfileAct;
|
||||
QAction *classicThemeAct;
|
||||
QAction *yericoThemeAct;
|
||||
QAction *monoThemeAct;
|
||||
QAction *monoBlueAct;
|
||||
QAction *monoWhiteAct;
|
||||
QAction *smallIconAct;
|
||||
QAction *normalIconAct;
|
||||
QAction *bigIconAct;
|
||||
QAction *hugeIconAct;
|
||||
|
||||
QAction *sysLangAct;
|
||||
QAction *czechLangAct;
|
||||
QAction *germanLangAct;
|
||||
QAction *englishLangAct;
|
||||
QAction *finnishLangAct;
|
||||
QAction *frenchLangAct;
|
||||
QAction *italianLangAct;
|
||||
QAction *polishLangAct;
|
||||
QAction *spanishLangAct;
|
||||
QAction *swedishLangAct;
|
||||
QAction *chineseLangAct;
|
||||
|
||||
QAction *openDocURLAct;
|
||||
};
|
||||
|
||||
|
|
|
@ -59,3 +59,4 @@ qt5_wrap_cpp(modeledit_SRCS ${modeledit_HDRS})
|
|||
|
||||
add_library(modeledit ${modeledit_SRCS})
|
||||
qt5_use_modules(modeledit Widgets Xml Multimedia)
|
||||
target_link_libraries(modeledit PRIVATE ${CPN_COMMON_LIB})
|
||||
|
|
|
@ -19,13 +19,9 @@
|
|||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QLibraryInfo>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
#include <QTranslator>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
|
@ -41,6 +37,7 @@
|
|||
#include "simulatorstartupdialog.h"
|
||||
#include "storage.h"
|
||||
#include "qxtcommandoptions.h"
|
||||
#include "translations.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace Simulator;
|
||||
|
@ -83,7 +80,6 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
Q_INIT_RESOURCE(companion);
|
||||
Q_INIT_RESOURCE(translations);
|
||||
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
@ -94,17 +90,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
QString resultMsg;
|
||||
|
||||
QTranslator companionTranslator;
|
||||
companionTranslator.load(":/companion_" + g.locale());
|
||||
QTranslator qtTranslator;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
|
||||
QString qtfile = "qtbase_";
|
||||
#else
|
||||
QString qtfile = "qt_";
|
||||
#endif
|
||||
qtTranslator.load(qtfile + g.locale().left(2), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
app.installTranslator(&companionTranslator);
|
||||
app.installTranslator(&qtTranslator);
|
||||
Translations::installTranslators();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
|
|
|
@ -27,4 +27,5 @@ foreach(name ${storage_NAMES})
|
|||
endforeach()
|
||||
|
||||
add_library(storage ${storage_SRCS})
|
||||
target_link_libraries(storage Qt5::Core Qt5::Gui Qt5::Xml Qt5::Widgets)
|
||||
qt5_use_modules(storage Core Xml Widgets)
|
||||
target_link_libraries(storage PRIVATE ${CPN_COMMON_LIB})
|
||||
|
|
168
companion/src/translations.cpp
Normal file
168
companion/src/translations.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "translations.h"
|
||||
#include "appdata.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QLibraryInfo>
|
||||
#include <QTranslator>
|
||||
|
||||
// List of available Companion translations
|
||||
// todo: make dynamic eg. from directory listing
|
||||
// todo: make locale name country-agnostic unless translation is specifically for a country (like zh_CN)
|
||||
QStringList const Translations::getAvailableTranslations()
|
||||
{
|
||||
static QStringList locales;
|
||||
|
||||
if (!locales.size()) {
|
||||
locales << "cs_CZ"
|
||||
<< "de_DE"
|
||||
<< "en"
|
||||
<< "es_ES"
|
||||
<< "fi_FI"
|
||||
<< "fr_FR"
|
||||
//<< "he_IL"
|
||||
<< "it_IT"
|
||||
//<< "nl_NL"
|
||||
<< "pl_PL"
|
||||
//<< "pt_PT"
|
||||
//<< "ru_RU"
|
||||
<< "sv_SE"
|
||||
<< "zh_CN" ;
|
||||
}
|
||||
return locales;
|
||||
}
|
||||
|
||||
QStringList const Translations::getAvailableLanguages()
|
||||
{
|
||||
static QStringList languages;
|
||||
if (!languages.size()) {
|
||||
foreach (const QString & loc, getAvailableTranslations())
|
||||
languages.append(loc.left(2));
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
QStringList const Translations::getTranslationPaths()
|
||||
{
|
||||
// Look for translation files in the following locations, in order of priority
|
||||
QStringList paths;
|
||||
|
||||
// Prefer path set in environment variable, makes it possible to test/replace translations w/out rebuilding.
|
||||
if (qEnvironmentVariableIsSet("OPENTX_APP_TRANSLATIONS_PATH") && QDir(qgetenv("OPENTX_APP_TRANSLATIONS_PATH").constData()).exists()) {
|
||||
paths << qgetenv("OPENTX_APP_TRANSLATIONS_PATH").constData();
|
||||
}
|
||||
// Try application subfolder first, also eg. to test/replace translations quickly.
|
||||
paths << APP_TRANSLATIONS_FILE_PATH;
|
||||
// Then the resource file
|
||||
paths << APP_TRANSLATIONS_RESOURCE_PATH;
|
||||
// Finally the system folder (more likely for Qt translations than Companion ones)
|
||||
paths << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
void Translations::installTranslators()
|
||||
{
|
||||
Q_INIT_RESOURCE(translations);
|
||||
|
||||
static QList<QTranslator *> appTranslators;
|
||||
|
||||
// Determine the locale
|
||||
|
||||
QLocale locale; // defaults to system locale
|
||||
if (!g.locale().isEmpty()) {
|
||||
locale = QLocale(g.locale()); // reverts to "C" locale if invalid
|
||||
if (locale.language() == QLocale::C) {
|
||||
// reset
|
||||
locale = QLocale::system();
|
||||
g.locale("");
|
||||
}
|
||||
}
|
||||
qDebug() << "Locale name:" << locale.name() << "language:" << locale.nativeLanguageName() << "country:" << locale.nativeCountryName();
|
||||
|
||||
// Remove any existing translators, this lets us re-translate w/out restart.
|
||||
foreach (QTranslator * t, appTranslators) {
|
||||
if (t) {
|
||||
QCoreApplication::removeTranslator(t);
|
||||
delete t;
|
||||
}
|
||||
}
|
||||
appTranslators.clear();
|
||||
|
||||
/* Multiple translation files can be installed.
|
||||
* Translations are searched for in the reverse order from which they were installed (last added is searched first).
|
||||
* The search stops as soon as a translation containing a matching string is found.
|
||||
*/
|
||||
|
||||
// Look for translation files in several locations
|
||||
QStringList tryPaths = getTranslationPaths();
|
||||
|
||||
// First try to install Qt translations for common GUI elements.
|
||||
|
||||
QStringList qtFiles = QStringList() << "qt";
|
||||
// After Qt5.3 some translation files are broken up into modules. We only need "qtbase" for now.
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
|
||||
qtFiles << "qtbase";
|
||||
#endif
|
||||
|
||||
foreach (const QString & qtfile, qtFiles) {
|
||||
QTranslator * translator = new QTranslator(qApp);
|
||||
if (tryLoadTranslator(translator, locale, qtfile, tryPaths)) {
|
||||
appTranslators.append(translator);
|
||||
}
|
||||
else {
|
||||
delete translator;
|
||||
//qDebug() << "Could not find Qt translations for:" << locale.name() << "In file:" << qtfile << "Using paths:" << tryPaths;
|
||||
}
|
||||
}
|
||||
|
||||
// Now try to install our custom translations if we support the current locale/language.
|
||||
if (!getAvailableTranslations().contains(locale.name()) && !getAvailableLanguages().contains(locale.name().left(2)))
|
||||
return;
|
||||
|
||||
QTranslator * translator = new QTranslator(qApp);
|
||||
if (tryLoadTranslator(translator, locale, "companion", tryPaths)) {
|
||||
appTranslators.append(translator);
|
||||
}
|
||||
else {
|
||||
delete translator;
|
||||
qWarning() << "Could not find Companion translations for:" << locale.name() << "Using paths:" << tryPaths;
|
||||
}
|
||||
}
|
||||
|
||||
bool Translations::tryLoadTranslator(QTranslator * t, const QLocale & locale, const QString & baseFile, const QStringList & paths)
|
||||
{
|
||||
foreach (const QString & path, paths) {
|
||||
if (t->load(locale, baseFile, "_", path)) {
|
||||
if (QCoreApplication::installTranslator(t)) {
|
||||
qDebug() << "Installed translation file" << baseFile << "from" << path << "for" << locale.name();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Error installing translation file" << baseFile << "for:" << locale.name() << "from:" << path;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
55
companion/src/translations.h
Normal file
55
companion/src/translations.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLATIONS_H
|
||||
#define TRANSLATIONS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
// Where to find translation files?
|
||||
// First any path in environment variable OPENTX_APP_TRANSLATIONS_PATH is used if it exists.
|
||||
|
||||
// Default location for .qm files when NOT compiled into application (this is searched after OPENTX_APP_TRANSLATIONS_PATH).
|
||||
#ifndef APP_TRANSLATIONS_FILE_PATH
|
||||
#define APP_TRANSLATIONS_FILE_PATH QCoreApplication::applicationDirPath() % "/translations"
|
||||
#endif
|
||||
\
|
||||
// Default location for .qm files when compiled into application as a resource (this is searched after APP_TRANSLATIONS_FILE_PATH) .
|
||||
#ifndef APP_TRANSLATIONS_RESOURCE_PATH
|
||||
#define APP_TRANSLATIONS_RESOURCE_PATH ":/translations"
|
||||
#endif
|
||||
|
||||
class QLocale;
|
||||
class QTranslator;
|
||||
|
||||
class Translations
|
||||
{
|
||||
public:
|
||||
static QStringList const getTranslationPaths();
|
||||
static QStringList const getAvailableTranslations();
|
||||
static QStringList const getAvailableLanguages();
|
||||
|
||||
static void installTranslators();
|
||||
|
||||
protected:
|
||||
static bool tryLoadTranslator(QTranslator * t, const QLocale & locale, const QString & baseFile, const QStringList & paths);
|
||||
};
|
||||
|
||||
#endif // TRANSLATIONS_H
|
|
@ -1,13 +1,6 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>companion_cs.qm</file>
|
||||
<file>companion_de.qm</file>
|
||||
<file>companion_es.qm</file>
|
||||
<file>companion_fi.qm</file>
|
||||
<file>companion_fr.qm</file>
|
||||
<file>companion_it.qm</file>
|
||||
<file>companion_pl.qm</file>
|
||||
<file>companion_sv.qm</file>
|
||||
<file>companion_zh.qm</file>
|
||||
</qresource>
|
||||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource prefix="/translations">
|
||||
@TRANSLATION_FILES_LIST@
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
12395
companion/src/translations/companion_en.ts
Normal file
12395
companion/src/translations/companion_en.ts
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue