Compare commits

...

60 Commits

Author SHA1 Message Date
Martchus 6016ec4bff Set the desktop file name via `SET_QT_APPLICATION_INFO` 2024-04-08 12:37:39 +02:00
Martchus 4feedbb057 Bump patch version 2024-04-08 12:36:51 +02:00
Martchus ded20b34a6 Add helper to react to darkmode changes 2024-03-31 22:48:22 +02:00
Martchus d20130d770 Update translations 2024-03-31 13:45:35 +02:00
Martchus a7d2611400 Allow re-applying the default icon theme independently of palette
This is useful under Android where the palette is apparently not set to
something matching the darkmode setting but the Qt Quick Material style
nevertheless seems to follow the darkmode setting. So we just want to take
the darkmode setting into account for assigning the appropriate icon theme
and ignore the palette.
2024-03-31 13:42:38 +02:00
Martchus 264386acad Bump minor version 2024-03-31 13:28:49 +02:00
Martchus 8ee322abb7 Deprecate the CMake module `AndroidApk` 2024-03-17 00:42:19 +01:00
Martchus bbd42e167d Adapt default QQC2 style definitions for Qt 6
The casing is important, otherwise this results in the error
`module "material" is not installed`.
2024-03-16 23:17:30 +01:00
Martchus 63ffbc4a6f Avoid warning after `QOperatingSystemVersion::OSType` was moved
This is now `QOperatingSystemVersionBase::OSType` causing a warning about
an implicit conversion. Making an explicit cast to whatever type
`os.type()` actually returns (depends on the Qt version) this warning does
not occur anymore and the code should still compile with any Qt version.
2024-03-15 23:54:17 +01:00
Martchus 600470e609 Bump patch version 2024-03-15 23:50:29 +01:00
Martchus 7a07077daf Apply change of `global.h` template 2024-02-22 19:42:13 +01:00
Martchus 7e7f8a5740 Fix configuring macro for network information plugins
The actual name of these plugins differs from the name of the CMake target.
2024-02-16 17:40:16 +01:00
Martchus 6dd98369b8 Allow configuring network information plugins 2024-02-15 21:51:48 +01:00
Martchus 6e103e09ad Update copyright date 2024-02-15 21:47:03 +01:00
Martchus 5bb21d2ead Bump patch version 2024-02-15 21:46:54 +01:00
Martchus 010f5d8408 No longer enforce Fusion style on Windows 11 as of Qt 6.7
It looks like Qt 6.7 is going to provide a style for Windows 11 that will
fix the mentioned bug.
2023-12-15 15:56:09 +01:00
Martchus a30509a743 Add `ModernWindowsStyle` to list of style plugins
It looks like `WindowsVistaStyle`-plugin is going to be renamed
to `ModernWindowsStyle`-plugin. This plugin is going to provide the old
style `windowsvista` and the new style `windows11`.

I haven't seen any changelogs yet but that's what it looks like so far:
https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/styles/modernwindows?h=6.7
2023-12-15 15:42:21 +01:00
Martchus 02a5617e36 Bump patch version 2023-12-15 15:36:07 +01:00
Martchus 5a7dac58ac Update translations 2023-11-18 22:08:45 +01:00
Martchus adf64a3d0d Apply clang-format 2023-11-18 22:05:36 +01:00
Martchus f52c7b8214 Fix error message when Qt/KF module is not found 2023-11-18 22:04:25 +01:00
Martchus 88310af665 Show a warning if the current Windows version is not supported 2023-11-18 22:03:27 +01:00
Martchus 265d3739c8 Bump patch version 2023-11-18 22:02:16 +01:00
Martchus 0eaa556a66 Update translations 2023-10-29 21:23:28 +01:00
Martchus 671617bf10 Apply cmake-format 2023-10-29 21:23:18 +01:00
Martchus c347bbfe1f Fix compilation against Qt < 6.1 2023-10-29 21:23:01 +01:00
Martchus c43ba340df Allow configuring OpenGL and Wayland support when linking against static Qt 2023-10-27 21:27:05 +02:00
Martchus cfa8347f19 Update translations 2023-10-15 16:57:52 +02:00
Martchus 458d98a279 Allow logging a few useful Qt-related information by setting env variable
Log Qt-related info when the environment variable
QT_UTILITIES_LOG_QT_CONFIG is set.
2023-10-14 20:44:59 +02:00
Martchus dcc6f71f1e Avoid unqualified `std` calls in `qtsettings.cpp` 2023-10-14 20:09:31 +02:00
Martchus a1f50456e8 Use `QLocale::territory()` instead of deprecated `QLocale::country()` 2023-10-14 20:03:37 +02:00
Martchus d546777f8c Make X11 optional 2023-10-11 18:11:07 +02:00
Martchus 91b9eed2d0 Ensure `use_package` is defined when configuring capslock detection 2023-09-19 12:36:44 +02:00
Martchus d47a5a93ed Update translations 2023-09-11 21:27:56 +02:00
Martchus 6bce4c40f2 Improve configuration and code of capslock detection
* Define `X_AVAILABLE` if that's the case so the X11-specific code can
  actually ever be effective
* Make the default for `CAPSLOCK_DETECTION` simply depending on whether it
  can be configured instead of making it platform dependent
* Simplify code and avoid warnings in X11-specific code
2023-09-11 21:27:41 +02:00
Martchus 472e32bfc2 Apply cmake-format 2023-09-11 21:20:43 +02:00
Martchus 56865f3a89 Add one hard-coded fallback search paths for icon themes
The `CMAKE_INSTALL_DATAROOTDIR` variable might be overridden by the project
to point to some custom location (e.g. `share/games` instead of `share`)
but this doesn't mean we will be able to find icons there.

Since icons are almost always under `/usr/share/icons` it makes sense to
add that location as one last hard-coded fallback to avoid having to
specify `BUILTIN_ICON_THEMES_SEARCH_PATH` in that common case.
2023-09-06 17:32:53 +02:00
Martchus 490345b2ca Bump patch version 2023-09-06 17:29:24 +02:00
Martchus b2f76021cc Update patch version 2023-09-05 17:51:57 +02:00
Martchus f5d99397ff Avoid CMake deprecation warning by bumping version 2023-07-23 21:18:51 +02:00
Martchus 856663f89d Update translations 2023-07-04 18:20:05 +02:00
Martchus 4c32a60551 Remove duplicated lookup in `loadApplicationTranslationFile()` 2023-07-03 22:00:42 +02:00
Martchus a6a64aa429 Make warning about missing Qt translations dependent on BUILTIN_TRANSLATIONS_OF_QT 2023-07-03 21:58:18 +02:00
Martchus 0e9637faa2 Fix dynamic retranslation of about dialog
`retranslateUi` must not be used here as it would revert the controls to
the initial state.
2023-07-03 00:49:37 +02:00
Martchus e448ff04fa Apply clang-format 2023-07-03 00:26:25 +02:00
Martchus 710a092458 Update translations 2023-07-03 00:25:57 +02:00
Martchus c7426403e5 Allow configuring notice on localization option page individually
Whether an application can retranslate the UI dynamically likely differs
from whether the other appearance related settings can be applied
dynamically so this needs to be configurable individually.

Additionally, the environment settings can never be applied dynamically so
the notice on that page should always be shown.
2023-07-03 00:21:29 +02:00
Martchus b340ff819c Retranslate certain dialogs/widgets dynamically
This does not cover all details yet.
2023-07-03 00:07:01 +02:00
Martchus 147b08ecf8 Retranslate tab texts in settings dialog dynamically 2023-07-02 23:54:55 +02:00
Martchus 0392b27b97 Add function for assigning a settings category name with retranslation
The function is still experimental as there's likely a better way to
implement this.
2023-07-02 23:54:14 +02:00
Martchus f69ffec06c Allow tracking whether the locale has changed via the `QtSettings` class
This allows an application to reload translations if the default locale has
changed to apply locale changes dynamically.
2023-07-02 23:48:46 +02:00
Martchus f30d020cda Update translations 2023-07-02 17:12:32 +02:00
Martchus dd99862769 Make the settings dialog react to language changes
This covers the settings dialog itself and option pages based on
`UiFileBasedOptionPage`. Other option pages need to react to the
new `OptionPageWidget::retranslationRequired()` signal or handle
the `QEvent::LanguageChange` event which is now propageted to the
page's widget.
2023-07-02 17:12:32 +02:00
Martchus bc3f84e65d Apply clang-format 2023-07-01 23:43:46 +02:00
Martchus 8fd1452174 Allow clearing previously installed translation files 2023-07-01 23:43:27 +02:00
Martchus 8d8585d00d Allow to instantiate built-in option pages individually
Expose conversion from QtSettings to QtSettingsData so one can pass such
an object to the constructor of e.g. QtLanguageOptionPage.
2023-06-26 21:22:42 +02:00
Martchus 3ac8c8e1a4 Update minor version 2023-06-26 21:22:42 +02:00
Martchus 96f10766d4 Enable web view support only by default if Qt WebEngine is present
The web view is only an optional enhancement in my applications so having
the support disabled is rather common. So for a better out-of-the-box
experience when configuring my projects it makes sense not having to
disable web view support explicitly if Qt WebEngine is not installed
anyways.
2023-06-10 18:08:13 +02:00
Martchus defecc45bc Fix showing font dialog 2023-06-09 12:28:26 +02:00
Martchus 0a952a2093 Bump patch version 2023-06-09 12:27:25 +02:00
35 changed files with 619 additions and 229 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# meta data
set(META_PROJECT_NAME qtutilities)
@ -9,8 +9,8 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION
"Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models")
set(META_VERSION_MAJOR 6)
set(META_VERSION_MINOR 12)
set(META_VERSION_PATCH 2)
set(META_VERSION_MINOR 14)
set(META_VERSION_PATCH 1)
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
project(${META_PROJECT_NAME})
@ -116,28 +116,35 @@ set(SCRIPT_FILES scripts/required_icons.sh)
# required to include CMake modules from own project directory
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" "${CMAKE_MODULE_PATH}")
# configure platform specific capslock detection for enterpassworddialog.cpp
if (WIN32
OR (UNIX
AND NOT APPLE
AND NOT ANDROID))
set(ENABLE_CAPSLOCK_DETECTION_BY_DEFAULT ON)
else ()
set(ENABLE_CAPSLOCK_DETECTION_BY_DEFAULT OFF)
# find c++utilities
set(CONFIGURATION_PACKAGE_SUFFIX
""
CACHE STRING "sets the suffix for find_package() calls to packages configured via c++utilities")
set(PACKAGE_NAMESPACE
""
CACHE STRING "sets the namespace (prefix) for find_package() calls to packages configured via c++utilities")
if (PACKAGE_NAMESPACE)
set(PACKAGE_NAMESPACE_PREFIX "${PACKAGE_NAMESPACE}-")
endif ()
option(CAPSLOCK_DETECTION "enables capslock detection" ${ENABLE_CAPSLOCK_DETECTION_BY_DEFAULT})
if (CAPSLOCK_DETECTION)
if (WIN32)
# WinAPI provides functions to provide capslock detection
find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.5.0 REQUIRED)
use_cpp_utilities()
# configure platform specific capslock detection for enterpassworddialog.cpp
if (WIN32)
set(HAVE_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION ON)
else ()
include(3rdParty)
use_package(TARGET_NAME X11::X11 PACKAGE_NAME X11 OPTIONAL)
if (TARGET X11::X11)
set_property(
SOURCE enterpassworddialog/enterpassworddialog.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS X_AVAILABLE)
set(HAVE_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION ON)
else ()
# X11 can provide functions for capslock detection under non-Windows environments
find_package(X11)
if (X11_FOUND)
list(APPEND LIBRARIES ${X11_LIBRARIES})
set(HAVE_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION ON)
endif ()
endif ()
endif ()
option(CAPSLOCK_DETECTION "enables capslock detection" ${HAVE_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION})
if (CAPSLOCK_DETECTION)
if (NOT HAVE_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION)
message(FATAL_ERROR "No backend for capslock detection found (WinAPI or X11 must be provided)")
endif ()
@ -169,19 +176,6 @@ else ()
message(STATUS "D-Bus notifications disabled")
endif ()
# find c++utilities
set(CONFIGURATION_PACKAGE_SUFFIX
""
CACHE STRING "sets the suffix for find_package() calls to packages configured via c++utilities")
set(PACKAGE_NAMESPACE
""
CACHE STRING "sets the namespace (prefix) for find_package() calls to packages configured via c++utilities")
if (PACKAGE_NAMESPACE)
set(PACKAGE_NAMESPACE_PREFIX "${PACKAGE_NAMESPACE}-")
endif ()
find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.5.0 REQUIRED)
use_cpp_utilities()
# include modules to apply configuration
include(BasicConfig)
include(QtGuiConfig)

View File

@ -12,6 +12,6 @@ core, gui, widgets
Some header files also require further Qt modules.
## Copyright notice and license
Copyright © 2015-2023 Marius Kittler
Copyright © 2015-2024 Marius Kittler
All code is licensed under [GPL-2-or-later](LICENSE).

View File

@ -58,7 +58,11 @@ AboutDialog::AboutDialog(QWidget *parent, const QString &applicationName, const
m_ui->creatorLabel->setText(creator);
} else {
// add "developed by " before creator name
m_ui->creatorLabel->setText(tr("developed by %1").arg(creator.isEmpty() ? QApplication::organizationName() : creator));
auto setCreator = [this, creator = std::move(creator)] {
m_ui->creatorLabel->setText(tr("developed by %1").arg(creator.isEmpty() ? QApplication::organizationName() : creator));
};
setCreator();
connect(this, &AboutDialog::retranslationRequired, this, std::move(setCreator));
}
m_ui->versionLabel->setText(version.isEmpty() ? QApplication::applicationVersion() : version);
const auto &deps(dependencyVersions.size() ? dependencyVersions : CppUtilities::applicationInfo.dependencyVersions);
@ -72,10 +76,14 @@ AboutDialog::AboutDialog(QWidget *parent, const QString &applicationName, const
% linkedAgainst.join(QStringLiteral("</li><li>")) % QStringLiteral("</li></ul>"));
}
if (!website.isEmpty() || CppUtilities::applicationInfo.url) {
m_ui->websiteLabel->setText(tr("For updates and bug reports visit the <a href=\"%1\" "
"style=\"text-decoration: underline; color: palette(link);\">project "
"website</a>.")
.arg(!website.isEmpty() ? website : QString::fromUtf8(CppUtilities::applicationInfo.url)));
auto setWebsite = [this, website = std::move(website)] {
m_ui->websiteLabel->setText(tr("For updates and bug reports visit the <a href=\"%1\" "
"style=\"text-decoration: underline; color: palette(link);\">project "
"website</a>.")
.arg(!website.isEmpty() ? website : QString::fromUtf8(CppUtilities::applicationInfo.url)));
};
setWebsite();
connect(this, &AboutDialog::retranslationRequired, this, std::move(setWebsite));
} else {
m_ui->websiteLabel->hide();
}
@ -88,7 +96,9 @@ AboutDialog::AboutDialog(QWidget *parent, const QString &applicationName, const
: new QGraphicsPixmapItem(QPixmap::fromImage(image));
m_iconScene->addItem(item);
m_ui->graphicsView->setScene(m_iconScene);
m_ui->qtVersionLabel->setText(tr("Using <a href=\"qtversion\">Qt %1</a>").arg(QString::fromUtf8(qVersion())));
auto setQtVersion = [this] { m_ui->qtVersionLabel->setText(tr("Using <a href=\"qtversion\">Qt %1</a>").arg(QString::fromUtf8(qVersion()))); };
setQtVersion();
connect(this, &AboutDialog::retranslationRequired, this, std::move(setQtVersion));
connect(m_ui->qtVersionLabel, &QLabel::linkActivated, this, &AboutDialog::linkActivated);
centerWidget(this, parentWidget());
}
@ -125,6 +135,10 @@ bool AboutDialog::event(QEvent *event)
case QEvent::PaletteChange:
setStyleSheet(dialogStyleForPalette(palette()));
break;
case QEvent::LanguageChange:
setWindowTitle(QCoreApplication::translate("QtUtilities::AboutDialog", "About", nullptr));
emit retranslationRequired();
break;
default:;
}
return res;

View File

@ -27,6 +27,9 @@ public:
explicit AboutDialog(QWidget *parent, const QString &website = QString(), const QString &description = QString(), const QImage &image = QImage());
~AboutDialog() override;
Q_SIGNALS:
void retranslationRequired();
protected:
bool event(QEvent *event) override;

View File

@ -1,4 +1,7 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
message(DEPRECATION "Do not use the AndroidApk module anymore. It broke after some minor Qt 5 version. As of Qt 6 the "
"CMake functions that come with Qt itself are sufficient.")
# adds a target to create an Android APK with the help of androiddeployqt if target platform is Android

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# applies Qt specific configuration notes: For GUI applications, QtGuiConfig must be included before. This module must always
# be included before AppTarget/LibraryTarget.
@ -66,10 +66,6 @@ if (IMPORTED_KF_MODULES)
endif ()
# find and use the required Qt/KF modules
set(QT_PACKAGE_PREFIX
"Qt5"
CACHE STRING "specifies the prefix for Qt packages")
string(TOLOWER "${QT_PACKAGE_PREFIX}" QT_PACKAGE_PREFIX_LOWER)
set(QT_LINGUIST_TOOLS_PACKAGE "${QT_PACKAGE_PREFIX}LinguistTools")
set(QT_QMAKE_TARGET "${QT_PACKAGE_PREFIX}::qmake")
foreach (MODULE ${QT_MODULES})
@ -79,9 +75,6 @@ foreach (MODULE ${QT_MODULES})
endif ()
use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE "${MODULE}" ${MODULE_OPTIONS})
endforeach ()
set(KF_PACKAGE_PREFIX
"KF5"
CACHE STRING "specifies the prefix for KDE Frameworks packages")
foreach (MODULE ${KF_MODULES})
unset(MODULE_OPTIONS)
if ("${MODULE}" IN_LIST META_PUBLIC_KF_MODULES)
@ -119,6 +112,12 @@ if (NOT DEFINED TLS_SUPPORT)
endif ()
endif ()
# allow configuring certain features when linking against static Qt
option(OPENGL_SUPPORT "whether to enable native Wayland support (when linking against static Qt)" ON)
option(NATIVE_WAYLAND_SUPPORT "whether to enable native Wayland support (when linking against static Qt)" ON)
option(NATIVE_WAYLAND_EGL_SUPPORT "specifies whether to enable native Wayland-EGL support (when linking against static Qt)"
OFF)
# built-in platform, imageformat and iconengine plugins when linking statically against Qt
if (TARGET "${QT_PACKAGE_PREFIX}::Core")
get_target_property(QT_TARGET_TYPE "${QT_PACKAGE_PREFIX}::Core" TYPE)
@ -184,7 +183,34 @@ if (STATIC_LINKAGE OR QT_TARGET_TYPE STREQUAL STATIC_LIBRARY)
XcbIntegration
ONLY_PLUGINS)
endif ()
if (TARGET "${QT_PACKAGE_PREFIX}::QWaylandIntegrationPlugin")
if (OPENGL_SUPPORT AND TARGET "${QT_PACKAGE_PREFIX}::QXcbEglIntegrationPlugin")
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
PREFIX
"${QT_PACKAGE_PREFIX}"
MODULE
Gui
PLUGINS
XcbEglIntegration
ONLY_PLUGINS)
endif ()
if (OPENGL_SUPPORT AND TARGET "${QT_PACKAGE_PREFIX}::QXcbGlxIntegrationPlugin")
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
PREFIX
"${QT_PACKAGE_PREFIX}"
MODULE
Gui
PLUGINS
XcbGlxIntegration
ONLY_PLUGINS)
endif ()
set(QT_CONFIG_USE_WAYLAND_INTEGRATION NO)
set(QT_CONFIG_WAYLAND_CLIENT_PLUGINS WaylandXdgShellIntegration WaylandWlShellIntegration WaylandIviShellIntegration
WaylandQtShellIntegration)
if (NATIVE_WAYLAND_SUPPORT AND TARGET "${QT_PACKAGE_PREFIX}::QWaylandIntegrationPlugin")
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
@ -195,6 +221,23 @@ if (STATIC_LINKAGE OR QT_TARGET_TYPE STREQUAL STATIC_LIBRARY)
PLUGINS
WaylandIntegration
ONLY_PLUGINS)
set(QT_CONFIG_USE_WAYLAND_INTEGRATION YES)
endif ()
if (NATIVE_WAYLAND_EGL_SUPPORT AND TARGET "${QT_PACKAGE_PREFIX}::QWaylandEglPlatformIntegrationPlugin")
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
PREFIX
"${QT_PACKAGE_PREFIX}"
MODULE
Gui
PLUGINS
WaylandEglPlatformIntegration
ONLY_PLUGINS)
set(QT_CONFIG_USE_WAYLAND_INTEGRATION YES)
list(APPEND QT_CONFIG_WAYLAND_CLIENT_PLUGINS WaylandEglClientBuffer)
endif ()
if (QT_CONFIG_USE_WAYLAND_INTEGRATION)
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
@ -203,10 +246,7 @@ if (STATIC_LINKAGE OR QT_TARGET_TYPE STREQUAL STATIC_LIBRARY)
MODULE
WaylandClient
PLUGINS
WaylandXdgShellIntegration
WaylandWlShellIntegration
WaylandIviShellIntegration
WaylandQtShellIntegration
${QT_CONFIG_WAYLAND_CLIENT_PLUGINS}
ONLY_PLUGINS
PLUGINS_OPTIONAL)
endif ()
@ -240,9 +280,41 @@ if (STATIC_LINKAGE OR QT_TARGET_TYPE STREQUAL STATIC_LIBRARY)
endif ()
endif ()
# enable network information support for projects setting NETWORK_INFORMATION_SUPPORT explicitly
if (NETWORK_INFORMATION_SUPPORT)
set(KNOWN_NETWORK_INFORMATION_PLUGINS
${META_NETWORK_INFORMATION_PLUGINS} NetworkManagerNetworkInformation GlibNetworkInformation NLMNI
AndroidNetworkInformation SCNetworkReachabilityNetworkInformation)
set(USED_NETWORK_INFORMATION_PLUGINS)
foreach (PLUGIN ${KNOWN_NETWORK_INFORMATION_PLUGINS})
if (TARGET "${QT_PACKAGE_PREFIX}::Q${PLUGIN}Plugin")
use_qt_module(
LIBRARIES_VARIABLE
"${QT_PLUGINS_LIBRARIES_VARIABLE}"
PREFIX
"${QT_PACKAGE_PREFIX}"
MODULE
Network
PLUGINS
${PLUGIN}
ONLY_PLUGINS)
if (PLUGIN STREQUAL NLMNI)
set(PLUGIN NetworkListManagerNetworkInformation)
endif ()
list(APPEND USED_NETWORK_INFORMATION_PLUGINS "${PLUGIN}")
endif ()
endforeach ()
# allow importing network information plugins via qtconfig.h
if (USED_NETWORK_INFORMATION_PLUGINS)
list_to_string(" " "\\\n Q_IMPORT_PLUGIN(Q" "BackendFactory)" "${USED_NETWORK_INFORMATION_PLUGINS}"
USED_NETWORK_INFORMATION_PLUGINS_ARRAY)
endif ()
endif ()
# ensure all available widget style plugins are built-in when creating a Qt Widgets application - required since Qt 5.10
# because the styles have been "pluginized" (see commit 4f3249f)
set(KNOWN_WIDGET_STYLE_PLUGINS WindowsVistaStyle MacStyle AndroidStyle)
set(KNOWN_WIDGET_STYLE_PLUGINS ModernWindowsStyle WindowsVistaStyle MacStyle AndroidStyle)
set(USED_WIDGET_STYLE_PLUGINS)
if (Widgets IN_LIST QT_MODULES)
foreach (WIDGET_STYLE_PLUGIN ${KNOWN_WIDGET_STYLE_PLUGINS})
@ -329,6 +401,7 @@ option(BUILTIN_TRANSLATIONS_OF_QT "enables/disables built-in translations of Qt
"${BUILTIN_TRANSLATIONS}")
# determine relevant Qt translation files
string(TOLOWER "${QT_PACKAGE_PREFIX}" QT_PACKAGE_PREFIX_LOWER)
set(QT_TRANSLATION_FILES)
set(QT_TRANSLATION_SEARCH_PATHS)
query_qmake_variable_path(QT_INSTALL_TRANSLATIONS)
@ -379,7 +452,7 @@ if (NOT QT_TRANSLATIONS_FOUND)
endif ()
# emit warning if no Qt translations found but built-in translations are enabled
if (BUILTIN_TRANSLATIONS AND NOT QT_TRANSLATION_FILES)
if (BUILTIN_TRANSLATIONS_OF_QT AND NOT QT_TRANSLATION_FILES)
message(
WARNING
"Unable to find translations of Qt itself so Qt's translation files will not be built-in. Be sure Qt translations (https://code.qt.io/cgit/qt/qttranslations.git) are installed. Was looking under: ${QT_TRANSLATION_SEARCH_PATHS}"
@ -527,6 +600,9 @@ if (REQUIRED_ICONS)
list(APPEND ICON_SEARCH_PATHS "${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons")
list(APPEND ICON_SEARCH_PATHS "/usr/${CMAKE_INSTALL_DATAROOTDIR}/icons") # find icons from regular prefix when
# cross- compiling
list(APPEND ICON_SEARCH_PATHS "/usr/share/icons") # the project might change CMAKE__DATAROOTDIR to something
# custom so let's add one hardcoded fallback
list(REMOVE_DUPLICATES ICON_SEARCH_PATHS)
set(BUILTIN_ICONS_DIR "${CMAKE_CURRENT_BINARY_DIR}/icons")
set(DEFAULT_THEME_INDEX_FILE "${BUILTIN_ICONS_DIR}/default/index.theme")

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the QtGuiConfig module, the BasicConfig module must be included.")

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# determines the JavaScript provider (either Qt Script or Qt Declarative)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# defines helper to link against Qt dynamically or statically
@ -11,6 +11,14 @@ set(QT_LINKAGE_DETERMINED ON)
# include validate_visibility from c++utilities' 3rdParty module
include(3rdParty)
# allow switching the Qt and KDE Frameworks version
set(QT_PACKAGE_PREFIX
"Qt5"
CACHE STRING "specifies the prefix for Qt packages")
set(KF_PACKAGE_PREFIX
"KF5"
CACHE STRING "specifies the prefix for KDE Frameworks packages")
# determine the minimum Qt version
if (NOT META_QT_VERSION)
if (META_QT5_VERSION)
@ -67,7 +75,7 @@ macro (use_qt_module)
find_package("${ARGS_PREFIX}${ARGS_MODULE}" "${META_QT_VERSION}" REQUIRED)
foreach (TARGET ${ARGS_TARGETS})
if (NOT TARGET "${TARGET}")
message(FATAL_ERROR "The ${ARGS_PREFIX}${ARGS_MODULE} does not provide the target ${TARGET}.")
message(FATAL_ERROR "The CMake module ${ARGS_PREFIX}${ARGS_MODULE} does not provide the target ${TARGET}.")
endif ()
if ("${TARGET}" IN_LIST "${ARGS_LIBRARIES_VARIABLE}")
continue()

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
# determines the web view provider (either Qt WebKit or Qt WebEngine)
@ -6,9 +6,19 @@ if (TARGET_CONFIG_DONE)
message(FATAL_ERROR "Can not include QtWebViewProviderConfig module when targets are already configured.")
endif ()
# include required modules
include(QtLinkage)
# check whether Qt WebEngine is present
find_package("${QT_PACKAGE_PREFIX}WebEngineWidgets" "${META_QT_VERSION}")
set(WEBVIEW_PROVIDER_DEFAULT "none")
if ("${${QT_PACKAGE_PREFIX}WebEngineWidgets_FOUND}")
set(WEBVIEW_PROVIDER_DEFAULT "webengine")
endif ()
# configure the specified web view provider
set(WEBVIEW_PROVIDER
"webengine"
"${WEBVIEW_PROVIDER_DEFAULT}"
CACHE STRING "specifies the web view provider: webengine (default), webkit or none")
if (WEBVIEW_PROVIDER STREQUAL "webkit")
set(WEBVIEW_PROVIDER WebKitWidgets)

View File

@ -13,5 +13,6 @@
#define IMPORT_IMAGE_FORMAT_PLUGINS @IMAGE_FORMAT_SUPPORT_ARRAY@
#define IMPORT_WIDGET_STYLE_PLUGINS @WIDGET_STYLE_PLUGINS_ARRAY@
#define IMPORT_TLS_PLUGINS @USED_TLS_PLUGINS_ARRAY@
#define IMPORT_NETWORK_INFORMATION_PLUGINS @USED_NETWORK_INFORMATION_PLUGINS_ARRAY@
@META_CUSTOM_QT_CONFIG@
#endif // @META_PROJECT_VARNAME_UPPER@_QT_CONFIG

View File

@ -12,8 +12,7 @@
#include <QMessageBox>
#include <QStyle>
#ifdef QT_UTILITIES_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION
#if defined(Q_OS_WIN32)
#if defined(QT_UTILITIES_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION) && defined(Q_OS_WIN32)
#include <windows.h>
#elif defined(X_AVAILABLE)
#include <X11/XKBlib.h>
@ -22,7 +21,6 @@
#undef FocusIn
#undef FocusOut
#endif
#endif
namespace QtUtilities {
@ -52,12 +50,7 @@ EnterPasswordDialog::EnterPasswordDialog(QWidget *parent)
m_ui->userNameLineEdit->installEventFilter(this);
m_ui->password1LineEdit->installEventFilter(this);
m_ui->password2LineEdit->installEventFilter(this);
// capslock key detection
#ifdef QT_UTILITIES_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION
m_capslockPressed = isCapslockPressed();
#else
m_capslockPressed = false;
#endif
m_ui->capslockWarningWidget->setVisible(m_capslockPressed);
// draw icon to capslock warning graphics view
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, this);
@ -223,6 +216,9 @@ bool EnterPasswordDialog::event(QEvent *event)
m_ui->capslockWarningWidget->setVisible(m_capslockPressed);
break;
}
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:;
}
return QDialog::event(event);
@ -327,22 +323,17 @@ void EnterPasswordDialog::confirm()
*/
bool EnterPasswordDialog::isCapslockPressed()
{
#ifdef QT_UTILITIES_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION
// platform dependent method of determining if CAPS LOCK is pressed
#if defined(Q_OS_WIN32)
#if defined(QT_UTILITIES_PLATFORM_SPECIFIC_CAPSLOCK_DETECTION) && defined(Q_OS_WIN32)
return GetKeyState(VK_CAPITAL) == 1;
#elif defined(X_AVAILABLE)
Display *d = XOpenDisplay((char *)0);
bool caps_state = false;
auto *const d = XOpenDisplay(nullptr);
auto capsState = false;
if (d) {
unsigned n;
XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
caps_state = (n & 0x01) == 1;
capsState = (n & 0x01) == 1;
}
return caps_state;
#else
return false;
#endif
return capsState;
#else
return false;
#endif

View File

@ -4,6 +4,7 @@
#ifndef QT_UTILITIES_GLOBAL
#define QT_UTILITIES_GLOBAL
#include "qtutilities-definitions.h"
#include <c++utilities/application/global.h>
#ifdef QT_UTILITIES_STATIC

View File

@ -69,4 +69,27 @@ std::optional<bool> isDarkModeEnabled()
return std::nullopt;
}
/*!
* \brief Invokes the specified callback when the color scheme changed.
*
* The first argument of the callback will be whether the color scheme is dark now (Qt::ColorScheme::Dark).
* The callback is invoked immediately by this function unless \a invokeImmediately is set to false.
*
* \remarks Whether dark mode is enabled can only be determined on Qt 6.5 or newer and only on certain
* platforms. If it cannot be determined the \a darkModeChangedCallback is never invoked.
*/
QMetaObject::Connection onDarkModeChanged(std::function<void(bool)> &&darkModeChangedCallback, QObject *context, bool invokeImmediately)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
if (const auto *const styleHints = QGuiApplication::styleHints()) {
if (invokeImmediately) {
darkModeChangedCallback(styleHints->colorScheme() == Qt::ColorScheme::Dark);
}
return QObject::connect(styleHints, &QStyleHints::colorSchemeChanged, context,
[handler = std::move(darkModeChangedCallback)](Qt::ColorScheme colorScheme) { return handler(colorScheme == Qt::ColorScheme::Dark); });
}
#endif
return QMetaObject::Connection();
}
} // namespace QtUtilities

View File

@ -3,10 +3,13 @@
#include "../global.h"
#include <QMetaObject>
#include <QPalette>
#include <functional>
#include <optional>
QT_FORWARD_DECLARE_CLASS(QObject)
QT_FORWARD_DECLARE_CLASS(QString)
namespace QtUtilities {
@ -14,6 +17,8 @@ namespace QtUtilities {
QT_UTILITIES_EXPORT bool openLocalFileOrDir(const QString &path);
QT_UTILITIES_EXPORT bool isPaletteDark(const QPalette &palette = QPalette());
QT_UTILITIES_EXPORT std::optional<bool> isDarkModeEnabled();
QT_UTILITIES_EXPORT QMetaObject::Connection onDarkModeChanged(
std::function<void(bool)> &&darkModeChangedCallback, QObject *context = nullptr, bool invokeImmediately = true);
} // namespace QtUtilities

View File

@ -107,6 +107,17 @@ void PaletteEditor::setPalette(const QPalette &palette, const QPalette &parentPa
setPalette(palette);
}
bool PaletteEditor::event(QEvent *event)
{
switch (event->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:;
}
return QDialog::event(event);
}
void PaletteEditor::handleComputeRadioClicked()
{
if (m_compute) {

View File

@ -39,6 +39,9 @@ public:
void setPalette(const QPalette &palette);
void setPalette(const QPalette &palette, const QPalette &parentPalette);
protected:
bool event(QEvent *event) override;
private Q_SLOTS:
void buildPalette();
void paletteChanged(const QPalette &palette);

View File

@ -24,6 +24,7 @@ IMPORT_IMAGE_FORMAT_PLUGINS
IMPORT_WIDGET_STYLE_PLUGINS
#endif // defined(QT_UTILITIES_GUI_QTWIDGETS) || defined(QT_UTILITIES_GUI_QTQUICK)
IMPORT_TLS_PLUGINS
IMPORT_NETWORK_INFORMATION_PLUGINS
#endif // QT_STATIC
#endif // MISC_UTILS_IMPORT_PLUGIN_H

View File

@ -17,6 +17,12 @@
#include <QGuiApplication>
#endif
#if defined(Q_OS_WINDOWS) && (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
#define QT_UTILITIES_CHECK_WINDOWS_VERSION
#include <QMessageBox>
#include <QOperatingSystemVersion>
#endif
#include <initializer_list>
#include <iostream>
@ -180,5 +186,14 @@ void QtConfigArguments::applySettings(bool preventApplyingDefaultFont) const
if (m_sceneGraphRenderLoopArg.isPresent()) {
qputenv(m_sceneGraphRenderLoopArg.environmentVariable(), QByteArray(m_sceneGraphRenderLoopArg.firstValue()));
}
#ifdef QT_UTILITIES_CHECK_WINDOWS_VERSION
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows10_1809) {
QMessageBox::warning(nullptr, QCoreApplication::applicationName(),
QCoreApplication::translate("QtConfigArguments",
"This application requires Windows 10, version 1809 or newer. The current Windows version is older so the application might not work "
"correctly."));
}
#endif
}
} // namespace CppUtilities

View File

@ -9,6 +9,13 @@
#include <QQuickStyle>
#include <QString>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#if defined(PLATFORM_ANDROID)
#define QT_UTILITIES_DEFAULT_QQC2_STYLE "Material"
#elif defined(PLATFORM_WINDOWS)
#define QT_UTILITIES_DEFAULT_QQC2_STYLE "Universal"
#endif
#else
#if defined(PLATFORM_ANDROID)
#define QT_UTILITIES_DEFAULT_QQC2_STYLE "material"
#elif defined(PLATFORM_WINDOWS)
@ -16,6 +23,8 @@
#endif
#endif
#endif
namespace CppUtilities {
class QT_UTILITIES_EXPORT QtConfigArguments {

View File

@ -68,6 +68,11 @@ void cleanup()
*/
namespace TranslationFiles {
/*!
* \brief The translators installed via the load-functions in this namespace.
*/
static QList<QTranslator *> translators;
/*!
* \brief Allows to set an additional search path for translation files.
* \remarks This path is considered *before* the default directories.
@ -132,6 +137,7 @@ void loadQtTranslationFile(initializer_list<QString> repositoryNames, const QStr
|| qtTranslator->load(fileName, path = QStringLiteral("../share/qt/translations"))
|| qtTranslator->load(fileName, path = QStringLiteral(":/translations"))) {
QCoreApplication::installTranslator(qtTranslator);
translators.append(qtTranslator);
if (debugTranslations) {
cerr << "Loading translation file for Qt repository \"" << repoName.toLocal8Bit().data() << "\" and the locale \""
<< localeName.toLocal8Bit().data() << "\" from \"" << path.toLocal8Bit().data() << "\"." << endl;
@ -223,13 +229,13 @@ void loadApplicationTranslationFile(const QString &configName, const QString &ap
QString path;
if ((!additionalTranslationFilePath().isEmpty() && appTranslator->load(fileName, path = additionalTranslationFilePath()))
|| appTranslator->load(fileName, path = QStringLiteral(".")) || appTranslator->load(fileName, path = QStringLiteral("../") % directoryName)
|| appTranslator->load(fileName, path = QStringLiteral("../") % directoryName)
|| appTranslator->load(fileName, path = QStringLiteral("../../") % directoryName)
|| appTranslator->load(fileName, path = QStringLiteral("./translations"))
|| appTranslator->load(fileName, path = QStringLiteral("../share/") % directoryName % QStringLiteral("/translations"))
|| appTranslator->load(fileName, path = QStringLiteral(APP_INSTALL_PREFIX "/share/") % directoryName % QStringLiteral("/translations"))
|| appTranslator->load(fileName, path = QStringLiteral(":/translations"))) {
QCoreApplication::installTranslator(appTranslator);
translators.append(appTranslator);
if (qEnvironmentVariableIsSet("QT_DEBUG_TRANSLATIONS")) {
logTranslationEvent("Loading", configName, applicationName, localeName, path);
}
@ -267,6 +273,18 @@ void loadApplicationTranslationFile(const QString &configName, const std::initia
loadApplicationTranslationFile(configName, applicationName, localeName);
}
}
/*!
* \brief Clears all translation files previously loaded via the load-functions in this namespace.
*/
void clearTranslationFiles()
{
for (auto *const translator : translators) {
QCoreApplication::removeTranslator(translator);
}
translators.clear();
}
} // namespace TranslationFiles
/*!

View File

@ -16,6 +16,18 @@ QT_FORWARD_DECLARE_CLASS(QSettings)
QT_FORWARD_DECLARE_CLASS(QStringList)
#endif
/*!
* \brief Sets the base name of the desktop entry for this application from buildsystem-provided meta-data.
* \remarks
* - This is done as part of SET_QT_APPLICATION_INFO and thus normally doesn't need to be invoked individually.
* - This macro is still experimental.
*/
#define SET_QT_DESKTOP_FILE_NAME
#if defined(Q_OS_LINUX) && defined(qGuiApp) && defined(APP_ID)
#undef SET_QT_DESKTOP_FILE_NAME
#define SET_QT_DESKTOP_FILE_NAME QGuiApplication::setDesktopFileName(QStringLiteral(APP_ID));
#endif
/*!
* \brief Sets the application meta data in the QCoreApplication singleton and attributes commonly used
* within my applications.
@ -26,6 +38,7 @@ QT_FORWARD_DECLARE_CLASS(QStringList)
QCoreApplication::setOrganizationDomain(QStringLiteral(APP_DOMAIN)); \
QCoreApplication::setApplicationName(QStringLiteral(APP_NAME)); \
QCoreApplication::setApplicationVersion(QStringLiteral(APP_VERSION)); \
SET_QT_DESKTOP_FILE_NAME \
::QtUtilities::setupCommonQtApplicationAttributes()
/*!
@ -53,6 +66,7 @@ QT_UTILITIES_EXPORT void loadApplicationTranslationFile(const QString &configNam
QT_UTILITIES_EXPORT void loadApplicationTranslationFile(const QString &configName, const std::initializer_list<QString> &applicationNames);
QT_UTILITIES_EXPORT void loadApplicationTranslationFile(
const QString &configName, const std::initializer_list<QString> &applicationNames, const QString &localeName);
QT_UTILITIES_EXPORT void clearTranslationFiles();
} // namespace TranslationFiles
namespace ApplicationInstances {

View File

@ -1,6 +1,9 @@
#include "./optioncategory.h"
#include "./optionpage.h"
#include <QCoreApplication>
#include <QEvent>
namespace QtUtilities {
/*!
@ -59,6 +62,20 @@ void OptionCategory::resetAllPages()
}
}
/*!
* \brief Triggers retranslation of all pages.
* \remarks Has no effect if the pages don't react to the LanguageChange event.
*/
void OptionCategory::retranslateAllPages()
{
auto event = QEvent(QEvent::LanguageChange);
for (auto *const page : m_pages) {
if (page->hasBeenShown()) {
QCoreApplication::sendEvent(page->widget(), &event);
}
}
}
/*!
* \brief Returns whether the option category matches the specified \a
* searchKeyWord.

View File

@ -33,6 +33,7 @@ public:
void assignPages(const QList<OptionPage *> &pages);
bool applyAllPages();
void resetAllPages();
void retranslateAllPages();
bool matches(const QString &searchKeyWord) const;
int currentIndex() const;
void setCurrentIndex(int currentIndex);

View File

@ -99,6 +99,9 @@ bool OptionPageWidget::event(QEvent *event)
case QEvent::PaletteChange:
emit paletteChanged();
break;
case QEvent::LanguageChange:
emit retranslationRequired();
break;
default:;
}
return QWidget::event(event);

View File

@ -20,6 +20,7 @@ public:
Q_SIGNALS:
void paletteChanged();
void retranslationRequired();
protected:
bool event(QEvent *) override;
@ -143,11 +144,12 @@ template <class UiClass> UiFileBasedOptionPage<UiClass>::~UiFileBasedOptionPage(
*/
template <class UiClass> QWidget *UiFileBasedOptionPage<UiClass>::setupWidget()
{
QWidget *widget = new OptionPageWidget();
auto *const widget = new OptionPageWidget();
if (!m_ui) {
m_ui.reset(new UiClass);
}
m_ui->setupUi(widget);
QObject::connect(widget, &OptionPageWidget::retranslationRequired, [this, widget] { m_ui->retranslateUi(widget); });
return widget;
}

View File

@ -12,19 +12,25 @@
#include "../misc/desktoputils.h"
#include "resources/config.h"
#include "ui_qtappearanceoptionpage.h"
#include "ui_qtenvoptionpage.h"
#include "ui_qtlanguageoptionpage.h"
#include <c++utilities/application/commandlineutils.h>
#include <QDir>
#include <QFileDialog>
#include <QFontDialog>
#include <QIcon>
#include <QOperatingSystemVersion>
#include <QSettings>
#include <QStringBuilder>
#include <QStyleFactory>
#include <QVersionNumber>
#if defined(Q_OS_WINDOWS) && (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
#if defined(Q_OS_WINDOWS) && (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
#include <QOperatingSystemVersion>
#define QT_UTILITIES_USE_FUSION_ON_WINDOWS_11
#endif
@ -33,8 +39,6 @@
#include <memory>
#include <optional>
using namespace std;
namespace QtUtilities {
struct QtSettingsData {
@ -50,6 +54,7 @@ struct QtSettingsData {
QString iconTheme;
QString initialIconTheme;
QLocale defaultLocale;
QLocale previousLocale;
QString localeName;
QString previousPluginDirectory;
QString additionalPluginDirectory;
@ -63,6 +68,7 @@ struct QtSettingsData {
bool customLocale;
bool isPaletteDark;
bool showNotices;
bool retranslatable;
};
inline QtSettingsData::QtSettingsData()
@ -77,6 +83,7 @@ inline QtSettingsData::QtSettingsData()
, customLocale(false)
, isPaletteDark(false)
, showNotices(true)
, retranslatable(false)
{
}
@ -88,7 +95,7 @@ inline QtSettingsData::QtSettingsData()
* system-default.
*/
QtSettings::QtSettings()
: m_d(make_unique<QtSettingsData>())
: m_d(std::make_unique<QtSettingsData>())
{
}
@ -108,12 +115,28 @@ QtSettings::~QtSettings()
* - Only call this function if the application actually re-applies these settings when the
* settings dialog is applied and when it is generally able to handle widget style and
* palette changes well.
* - The localization option page's notice is handled via setRetranslatable() and the notice
* for the environment page is still always shown (as those settings can never be applied
* at runtime). So this affects only the appearance page at this point.
*/
void QtSettings::disableNotices()
{
m_d->showNotices = false;
}
/*!
* \brief Sets whether the application supports changing the locale settings at runtime.
* \remarks
* Set this to true if the application will retranslate its UI after the locale has changed.
* This requires the application to re-install translators and to re-invoke all ts() and
* translate() function calls. If set to true, the notice that the locale setting takes only
* effect after restarting is not shown anymore.
*/
void QtSettings::setRetranslatable(bool retranslatable)
{
m_d->retranslatable = retranslatable;
}
/*!
* \brief Returns whether a custom font is set.
*/
@ -247,11 +270,11 @@ void QtSettings::apply()
if (m_d->customStyleSheet && !m_d->styleSheetPath.isEmpty()) {
auto file = QFile(m_d->styleSheetPath);
if (!file.open(QFile::ReadOnly)) {
cerr << "Unable to open the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data() << "\"." << endl;
std::cerr << "Unable to open the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data() << "\"." << std::endl;
}
styleSheet.append(file.readAll());
if (file.error() != QFile::NoError) {
cerr << "Unable to read the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data() << "\"." << endl;
std::cerr << "Unable to read the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data() << "\"." << std::endl;
}
}
@ -287,8 +310,8 @@ void QtSettings::apply()
if (auto *const qapp = qobject_cast<QApplication *>(QApplication::instance())) {
qapp->setStyleSheet(styleSheet);
} else {
cerr << "Unable to apply the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data()
<< "\" because no QApplication has been instantiated." << endl;
std::cerr << "Unable to apply the specified stylesheet \"" << m_d->styleSheetPath.toLocal8Bit().data()
<< "\" because no QApplication has been instantiated." << std::endl;
}
if (m_d->customPalette) {
QGuiApplication::setPalette(m_d->palette);
@ -319,7 +342,54 @@ void QtSettings::apply()
}
// apply locale
m_d->previousLocale = QLocale();
QLocale::setDefault(m_d->customLocale ? QLocale(m_d->localeName) : m_d->defaultLocale);
// log some debug information on the first call if env variable set
static auto debugInfoLogged = false;
if (debugInfoLogged) {
return;
}
const auto debugLoggingEnabled = CppUtilities::isEnvVariableSet(PROJECT_VARNAME_UPPER "_LOG_QT_CONFIG");
if (debugLoggingEnabled.has_value() && debugLoggingEnabled.value()) {
if (const auto os = QOperatingSystemVersion::current(); os.type() != static_cast<decltype(os.type())>(QOperatingSystemVersion::Unknown)) {
const auto version = QVersionNumber(os.majorVersion(), os.minorVersion(), os.microVersion());
std::cerr << "OS name and version: " << os.name().toStdString() << ' ' << version.toString().toStdString() << '\n';
}
std::cerr << "Qt version: " << qVersion() << '\n';
std::cerr << "Qt platform (set QT_QPA_PLATFORM to override): " << QGuiApplication::platformName().toStdString() << '\n';
std::cerr << "Qt locale: " << QLocale().name().toStdString() << '\n';
std::cerr << "Qt library paths: " << QCoreApplication::libraryPaths().join(':').toStdString() << '\n';
std::cerr << "Qt theme search paths: " << QIcon::themeSearchPaths().join(':').toStdString() << '\n';
debugInfoLogged = true;
}
}
/*!
* \brief Re-applies default icon theme assuming the palette is dark or not depending on \a isPaletteDark.
*
* Re-assigns the appropriate default icon theme depending on the current palette. Call this function after the
* darkmode setting has changed without the current palette reflecting that but you want the darkmode setting take
* precedence over the palette (e.g. when using Qt Quick Material style under Android). If your application makes
* actually use of the palette and you want the palette take precedence than call \a reevaluatePaletteAndDefaultIconTheme()
* instead.
*
* Note that QtSettings::isPaletteDark() will return \a isPaletteDark after calling this function (even though the current
* palette is not actually reflecting that).
*
* \remarks
* - The default icon theme must have been assigned before using the apply() function.
* - This function has no effect if a custom icon theme is configured.
*/
void QtSettings::reapplyDefaultIconTheme(bool isPaletteDark)
{
if (isPaletteDark == m_d->isPaletteDark) {
return; // no need to do anything if there's no change
}
m_d->isPaletteDark = isPaletteDark;
if (auto iconTheme = QIcon::themeName(); iconTheme == QStringLiteral("default") || iconTheme == QStringLiteral("default-dark")) {
QIcon::setThemeName(m_d->isPaletteDark ? QStringLiteral("default-dark") : QStringLiteral("default"));
}
}
/*!
@ -334,14 +404,7 @@ void QtSettings::apply()
*/
void QtSettings::reevaluatePaletteAndDefaultIconTheme()
{
const auto isPaletteDark = QtUtilities::isPaletteDark();
if (isPaletteDark == m_d->isPaletteDark) {
return; // no need to do anything if there's no change
}
m_d->isPaletteDark = isPaletteDark;
if (auto iconTheme = QIcon::themeName(); iconTheme == QStringLiteral("default") || iconTheme == QStringLiteral("default-dark")) {
QIcon::setThemeName(m_d->isPaletteDark ? QStringLiteral("default-dark") : QStringLiteral("default"));
}
reapplyDefaultIconTheme(QtUtilities::isPaletteDark());
}
/*!
@ -355,6 +418,14 @@ bool QtSettings::isPaletteDark()
return m_d->isPaletteDark;
}
/*!
* \brief Returns whether the last apply() call has changed the default locale.
*/
bool QtSettings::hasLocaleChanged() const
{
return m_d->previousLocale != QLocale();
}
/*!
* \brief Returns a new OptionCatecory containing all Qt related option pages.
* \remarks
@ -434,7 +505,7 @@ QWidget *QtAppearanceOptionPage::setupWidget()
ui()->styleSheetPathSelection->provideCustomFileMode(QFileDialog::ExistingFile);
// setup font selection
QObject::connect(ui()->fontPushButton, &QPushButton::clicked, m_fontDialog, [this] {
QObject::connect(ui()->fontPushButton, &QPushButton::clicked, widget, [this] {
if (!m_fontDialog) {
m_fontDialog = new QFontDialog(this->widget());
m_fontDialog->setCurrentFont(ui()->fontComboBox->font());
@ -491,7 +562,7 @@ QWidget *QtLanguageOptionPage::setupWidget()
{
// call base implementation first, so ui() is available
auto *widget = QtLanguageOptionPageBase::setupWidget();
if (!m_settings.showNotices) {
if (m_settings.retranslatable) {
ui()->label->hide();
}
@ -504,11 +575,16 @@ QWidget *QtLanguageOptionPage::setupWidget()
auto *languageLabel = ui()->languageLabel;
QObject::connect(ui()->localeComboBox, &QComboBox::currentTextChanged, languageLabel, [languageLabel, localeComboBox] {
const QLocale selectedLocale(localeComboBox->currentText());
const QLocale currentLocale;
const auto selectedLocale = QLocale(localeComboBox->currentText());
const auto currentLocale = QLocale();
const auto territory =
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
currentLocale.territoryToString(selectedLocale.territory());
#else
currentLocale.countryToString(selectedLocale.country());
#endif
languageLabel->setText(QCoreApplication::translate("QtGui::QtLanguageOptionPage", "recognized by Qt as") % QStringLiteral(" <i>")
% currentLocale.languageToString(selectedLocale.language()) % QChar(',') % QChar(' ')
% currentLocale.countryToString(selectedLocale.country()) % QStringLiteral("</i>"));
% currentLocale.languageToString(selectedLocale.language()) % QChar(',') % QChar(' ') % territory % QStringLiteral("</i>"));
});
return widget;
}
@ -541,11 +617,18 @@ void QtEnvOptionPage::reset()
QWidget *QtEnvOptionPage::setupWidget()
{
// call base implementation first, so ui() is available
auto *widget = QtEnvOptionPageBase::setupWidget();
if (!m_settings.showNotices) {
ui()->label->hide();
}
return widget;
return QtEnvOptionPageBase::setupWidget();
}
/*!
* \brief Returns a handle to the internal data.
* \remarks
* This is an opaque data structure. It can be used to construct option pages
* like QtLanguageOptionPage.
*/
QtSettings::operator QtSettingsData &() const
{
return *m_d.get();
}
} // namespace QtUtilities

View File

@ -19,7 +19,7 @@ explicit QtAppearanceOptionPage(QtSettingsData &settings, QWidget *parentWidget
private:
DECLARE_SETUP_WIDGETS
QtSettingsData &m_settings;
QtSettingsData & m_settings;
QFontDialog *m_fontDialog;
END_DECLARE_OPTION_PAGE
@ -29,7 +29,7 @@ explicit QtLanguageOptionPage(QtSettingsData &settings, QWidget *parentWidget =
private:
DECLARE_SETUP_WIDGETS
QtSettingsData &m_settings;
QtSettingsData & m_settings;
END_DECLARE_OPTION_PAGE
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE_CUSTOM_CTOR(QtEnvOptionPage)
@ -38,7 +38,7 @@ explicit QtEnvOptionPage(QtSettingsData &settings, QWidget *parentWidget = nullp
private:
DECLARE_SETUP_WIDGETS
QtSettingsData &m_settings;
QtSettingsData & m_settings;
END_DECLARE_OPTION_PAGE
class QT_UTILITIES_EXPORT QtSettings {
@ -47,12 +47,16 @@ public:
~QtSettings();
void disableNotices();
void setRetranslatable(bool retranslatable);
void restore(QSettings &settings);
void save(QSettings &settings) const;
void apply();
void reapplyDefaultIconTheme(bool isPaletteDark);
void reevaluatePaletteAndDefaultIconTheme();
bool isPaletteDark();
bool hasCustomFont() const;
bool hasLocaleChanged() const;
operator QtSettingsData &() const;
OptionCategory *category();

View File

@ -155,6 +155,20 @@ void SettingsDialog::showCategory(OptionCategory *category)
updateTabWidget();
}
/*!
* \brief Allows to set the \a categories display name so that it is retranslated as needed.
* \remarks
* - The specified \a translator is supposed to return the display name to assign to \a category for the current
* locale. The \a translator is called immediately for the initial assignment and on language change events.
* - This function is experimental and might change or be removed completely in the next minor release.
*/
void SettingsDialog::translateCategory(OptionCategory *category, const std::function<QString()> &translator)
{
category->setDisplayName(translator());
connect(this, &SettingsDialog::retranslationRequired, category,
[category, translator = std::move(translator)] { category->setDisplayName(translator()); });
}
/*!
* \brief Enables *single-category mode* to show only the specified \a
* singleCategory.
@ -273,6 +287,18 @@ void SettingsDialog::updateTabWidget()
m_ui->pagesTabWidget->setUpdatesEnabled(true);
}
/*!
* \brief Updates the tab widget's tab texts to apply possible translation changes.
*/
void SettingsDialog::retranslateTabWidget()
{
for (auto index = 0; index < m_ui->pagesTabWidget->count(); ++index) {
const auto *const scrollArea = qobject_cast<const QScrollArea *>(m_ui->pagesTabWidget->widget(index));
const auto *const widget = scrollArea->widget();
m_ui->pagesTabWidget->setTabText(index, widget->windowTitle());
}
}
/*!
* \brief Applies all changes. Calls OptionCategory::applyAllPages() for each category.
* \remarks Pages which have not been shown yet must have not been initialized anyways
@ -337,6 +363,11 @@ bool SettingsDialog::event(QEvent *event)
case QEvent::PaletteChange:
setStyleSheet(dialogStyleForPalette(palette()));
break;
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
retranslateTabWidget();
emit retranslationRequired();
break;
default:;
}
return res;

View File

@ -31,6 +31,7 @@ public:
OptionCategory *category(int categoryIndex) const;
OptionPage *page(int categoryIndex, int pageIndex) const;
void showCategory(OptionCategory *category);
void translateCategory(OptionCategory *category, const std::function<QString()> &translator);
void setSingleCategory(OptionCategory *singleCategory);
QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
void setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopRightCorner);
@ -44,6 +45,7 @@ public Q_SLOTS:
Q_SIGNALS:
void applied();
void resetted();
void retranslationRequired();
protected:
bool event(QEvent *event) override;
@ -52,6 +54,7 @@ protected:
private Q_SLOTS:
void currentCategoryChanged(const QModelIndex &index);
void updateTabWidget();
void retranslateTabWidget();
private:
std::unique_ptr<Ui::SettingsDialog> m_ui;

View File

@ -9,10 +9,18 @@
<translation>Text löschen</translation>
</message>
</context>
<context>
<name>QtConfigArguments</name>
<message>
<location filename="../resources/qtconfigarguments.cpp" line="193"/>
<source>This application requires Windows 10, version 1809 or newer. The current Windows version is older so the application might not work correctly.</source>
<translation>Diese Anwendung benötigt mindestens Windows 10, version 1809 oder neuer. Die momentane Windows-Version ist älter. Deshalb wird die Anwendung möglicherweise nicht richtig funktionieren.</translation>
</message>
</context>
<context>
<name>QtGui::QtLanguageOptionPage</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="509"/>
<location filename="../settingsdialog/qtsettings.cpp" line="586"/>
<source>recognized by Qt as</source>
<translation>von Qt erkannt als</translation>
</message>
@ -20,7 +28,7 @@
<context>
<name>QtGui::QtOptionCategory</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="369"/>
<location filename="../settingsdialog/qtsettings.cpp" line="440"/>
<source>Qt</source>
<translation></translation>
</message>
@ -28,22 +36,22 @@
<context>
<name>QtUtilities</name>
<message>
<location filename="../resources/resources.cpp" line="385"/>
<location filename="../resources/resources.cpp" line="403"/>
<source>unable to access file</source>
<translation>Zugriff auf die Datei ist nicht möglich</translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="388"/>
<location filename="../resources/resources.cpp" line="406"/>
<source>file has invalid format</source>
<translation>Datei hat ungültiges Format</translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="391"/>
<location filename="../resources/resources.cpp" line="409"/>
<source>unknown error</source>
<translation>unbekannter Fehler</translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="393"/>
<location filename="../resources/resources.cpp" line="411"/>
<source>Unable to sync settings from &quot;%1&quot;: %2</source>
<translation>Settings können nicht unter &quot;%1&quot; synchronisiert werden: %2</translation>
</message>
@ -52,6 +60,7 @@
<name>QtUtilities::AboutDialog</name>
<message>
<location filename="../aboutdialog/aboutdialog.ui" line="24"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="139"/>
<source>About</source>
<translation>Über</translation>
</message>
@ -90,22 +99,22 @@
<translation type="vanished">verwendet Qt</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="61"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="62"/>
<source>developed by %1</source>
<translation>entwickelt von %1</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="71"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<source>Linked against:</source>
<translation>Gegen folgende Bibliotheken gelinkt:</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="80"/>
<source>For updates and bug reports visit the &lt;a href=&quot;%1&quot; style=&quot;text-decoration: underline; color: palette(link);&quot;&gt;project website&lt;/a&gt;.</source>
<translation>Für Aktualisierung und Melden von Fehlern besuche die &lt;a href=&quot;%1&quot; style=&quot;text-decoration: underline; color: palette(link);&quot;&gt;Webseite des Projekts&lt;/a&gt;.</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="91"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="99"/>
<source>Using &lt;a href=&quot;qtversion&quot;&gt;Qt %1&lt;/a&gt;</source>
<translation>Verwendet &lt;a href=&quot;qtversion&quot;&gt;Qt %1&lt;/a&gt;</translation>
</message>
@ -115,8 +124,8 @@
<message>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="12"/>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="51"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the password</source>
<translation>Passwort eingeben</translation>
</message>
@ -161,28 +170,28 @@
<translation>Bestätigen</translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the new password</source>
<translation>Neues Passwort festlegen</translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="293"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="289"/>
<source>You didn&apos;t enter a user name.</source>
<translation>Es wurde kein Benutzername eingegeben.</translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="295"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="291"/>
<source>You didn&apos;t enter a password.</source>
<translation>Es wurde kein Passwort eingegeben.</translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="300"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="296"/>
<source>You have to enter the new password twice to ensure you enterd it correct.</source>
<translation>Um sicher zu stellen, dass das neue Passwort richtig eingegeben wurde, muss es zweimal eingegeben werden.</translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="303"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="299"/>
<source>You mistyped the password.</source>
<translation>Erstes und zweites Passwort stimmen nicht überein.</translation>
</message>
@ -225,42 +234,42 @@
<translation>Laden</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="144"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="155"/>
<source>Color palette configuration (*.ini)</source>
<translation>Farbpalettenkonfiguration (*.ini)</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="151"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="162"/>
<source>Unable to load &quot;%1&quot;.</source>
<translation>Fehler beim Laden von &quot;%1&quot;.</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="156"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="167"/>
<source>&quot;%1&quot; does not contain a valid palette.</source>
<translation>&quot;%1&quot; enthält keine gültige Farbpalette.</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="169"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="180"/>
<source>Unable to write &quot;%1&quot;.</source>
<translation>Fehler beim Schreiben von &quot;%1&quot;.</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="177"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="188"/>
<source>Load palette</source>
<translation>Palette laden</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="189"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="200"/>
<source>Error reading palette</source>
<translation>Fehler beim Einlesen der Palette</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="195"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="206"/>
<source>Save palette</source>
<translation>Palette speichern</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="203"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="214"/>
<source>Error writing palette</source>
<translation>Fehler beim Schreiben der Palette</translation>
</message>
@ -268,22 +277,22 @@
<context>
<name>QtUtilities::PaletteModel</name>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="405"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="416"/>
<source>Color Role</source>
<translation>Farbrolle</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="407"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="418"/>
<source>Active</source>
<translation>Aktiv</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="409"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="420"/>
<source>Inactive</source>
<translation>Inaktiv</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="411"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="422"/>
<source>Disabled</source>
<translation>Deaktiviert</translation>
</message>
@ -291,24 +300,24 @@
<context>
<name>QtUtilities::PathSelection</name>
<message>
<location filename="../widgets/pathselection.cpp" line="56"/>
<location filename="../widgets/pathselection.cpp" line="76"/>
<location filename="../widgets/pathselection.cpp" line="87"/>
<location filename="../widgets/pathselection.cpp" line="144"/>
<source>Select ...</source>
<translation>Wählen ...</translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="81"/>
<location filename="../widgets/pathselection.cpp" line="92"/>
<source>Open</source>
<translation>Öffnen</translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="84"/>
<location filename="../widgets/pathselection.cpp" line="95"/>
<source>Explore</source>
<translation>Im Dateibrowser öffnen</translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="120"/>
<location filename="../widgets/pathselection.cpp" line="122"/>
<location filename="../widgets/pathselection.cpp" line="131"/>
<location filename="../widgets/pathselection.cpp" line="133"/>
<source>Select path</source>
<translation>Pfad auswählen</translation>
</message>
@ -498,12 +507,12 @@ Außerdem werden sie vielleicht vom QPA plugin überschrieben und funktionieren
<translation></translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="294"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="320"/>
<source>&lt;p&gt;&lt;b&gt;Errors occurred when applying changes:&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;</source>
<translation>&lt;p&gt;&lt;b&gt;Beim Anwenden der Einstellungen sind Fehler aufgetreten:&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;</translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="299"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="325"/>
<source>unknown error</source>
<translation>unbekannter Fehler</translation>
</message>

View File

@ -9,10 +9,18 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtConfigArguments</name>
<message>
<location filename="../resources/qtconfigarguments.cpp" line="193"/>
<source>This application requires Windows 10, version 1809 or newer. The current Windows version is older so the application might not work correctly.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::QtLanguageOptionPage</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="509"/>
<location filename="../settingsdialog/qtsettings.cpp" line="586"/>
<source>recognized by Qt as</source>
<translation type="unfinished"></translation>
</message>
@ -20,7 +28,7 @@
<context>
<name>QtGui::QtOptionCategory</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="369"/>
<location filename="../settingsdialog/qtsettings.cpp" line="440"/>
<source>Qt</source>
<translation type="unfinished"></translation>
</message>
@ -28,22 +36,22 @@
<context>
<name>QtUtilities</name>
<message>
<location filename="../resources/resources.cpp" line="385"/>
<location filename="../resources/resources.cpp" line="403"/>
<source>unable to access file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="388"/>
<location filename="../resources/resources.cpp" line="406"/>
<source>file has invalid format</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="391"/>
<location filename="../resources/resources.cpp" line="409"/>
<source>unknown error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="393"/>
<location filename="../resources/resources.cpp" line="411"/>
<source>Unable to sync settings from &quot;%1&quot;: %2</source>
<translation type="unfinished"></translation>
</message>
@ -52,6 +60,7 @@
<name>QtUtilities::AboutDialog</name>
<message>
<location filename="../aboutdialog/aboutdialog.ui" line="24"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="139"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
@ -86,22 +95,22 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="61"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="62"/>
<source>developed by %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="71"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<source>Linked against:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="80"/>
<source>For updates and bug reports visit the &lt;a href=&quot;%1&quot; style=&quot;text-decoration: underline; color: palette(link);&quot;&gt;project website&lt;/a&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="91"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="99"/>
<source>Using &lt;a href=&quot;qtversion&quot;&gt;Qt %1&lt;/a&gt;</source>
<translation type="unfinished"></translation>
</message>
@ -111,8 +120,8 @@
<message>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="12"/>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="51"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the password</source>
<translation type="unfinished"></translation>
</message>
@ -157,28 +166,28 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the new password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="293"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="289"/>
<source>You didn&apos;t enter a user name.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="295"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="291"/>
<source>You didn&apos;t enter a password.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="300"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="296"/>
<source>You have to enter the new password twice to ensure you enterd it correct.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="303"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="299"/>
<source>You mistyped the password.</source>
<translation type="unfinished"></translation>
</message>
@ -221,42 +230,42 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="144"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="155"/>
<source>Color palette configuration (*.ini)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="151"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="162"/>
<source>Unable to load &quot;%1&quot;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="156"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="167"/>
<source>&quot;%1&quot; does not contain a valid palette.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="169"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="180"/>
<source>Unable to write &quot;%1&quot;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="177"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="188"/>
<source>Load palette</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="189"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="200"/>
<source>Error reading palette</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="195"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="206"/>
<source>Save palette</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="203"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="214"/>
<source>Error writing palette</source>
<translation type="unfinished"></translation>
</message>
@ -264,22 +273,22 @@
<context>
<name>QtUtilities::PaletteModel</name>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="405"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="416"/>
<source>Color Role</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="407"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="418"/>
<source>Active</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="409"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="420"/>
<source>Inactive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="411"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="422"/>
<source>Disabled</source>
<translation type="unfinished"></translation>
</message>
@ -287,24 +296,24 @@
<context>
<name>QtUtilities::PathSelection</name>
<message>
<location filename="../widgets/pathselection.cpp" line="56"/>
<location filename="../widgets/pathselection.cpp" line="76"/>
<location filename="../widgets/pathselection.cpp" line="87"/>
<location filename="../widgets/pathselection.cpp" line="144"/>
<source>Select ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="81"/>
<location filename="../widgets/pathselection.cpp" line="92"/>
<source>Open</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="84"/>
<location filename="../widgets/pathselection.cpp" line="95"/>
<source>Explore</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="120"/>
<location filename="../widgets/pathselection.cpp" line="122"/>
<location filename="../widgets/pathselection.cpp" line="131"/>
<location filename="../widgets/pathselection.cpp" line="133"/>
<source>Select path</source>
<translation type="unfinished"></translation>
</message>
@ -481,12 +490,12 @@ These settings might be overwritten by your Qt platform integration plugin and h
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="294"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="320"/>
<source>&lt;p&gt;&lt;b&gt;Errors occurred when applying changes:&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="299"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="325"/>
<source>unknown error</source>
<translation type="unfinished"></translation>
</message>

View File

@ -9,10 +9,18 @@
<translation></translation>
</message>
</context>
<context>
<name>QtConfigArguments</name>
<message>
<location filename="../resources/qtconfigarguments.cpp" line="193"/>
<source>This application requires Windows 10, version 1809 or newer. The current Windows version is older so the application might not work correctly.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::QtLanguageOptionPage</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="509"/>
<location filename="../settingsdialog/qtsettings.cpp" line="586"/>
<source>recognized by Qt as</source>
<translation> Qt </translation>
</message>
@ -20,7 +28,7 @@
<context>
<name>QtGui::QtOptionCategory</name>
<message>
<location filename="../settingsdialog/qtsettings.cpp" line="369"/>
<location filename="../settingsdialog/qtsettings.cpp" line="440"/>
<source>Qt</source>
<translation>Qt</translation>
</message>
@ -28,22 +36,22 @@
<context>
<name>QtUtilities</name>
<message>
<location filename="../resources/resources.cpp" line="385"/>
<location filename="../resources/resources.cpp" line="403"/>
<source>unable to access file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="388"/>
<location filename="../resources/resources.cpp" line="406"/>
<source>file has invalid format</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="391"/>
<location filename="../resources/resources.cpp" line="409"/>
<source>unknown error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../resources/resources.cpp" line="393"/>
<location filename="../resources/resources.cpp" line="411"/>
<source>Unable to sync settings from &quot;%1&quot;: %2</source>
<translation type="unfinished"></translation>
</message>
@ -52,6 +60,7 @@
<name>QtUtilities::AboutDialog</name>
<message>
<location filename="../aboutdialog/aboutdialog.ui" line="24"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="139"/>
<source>About</source>
<translation></translation>
</message>
@ -86,22 +95,22 @@
<translation>使 Qt</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="61"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="62"/>
<source>developed by %1</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="71"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<source>Linked against:</source>
<translation></translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="75"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="80"/>
<source>For updates and bug reports visit the &lt;a href=&quot;%1&quot; style=&quot;text-decoration: underline; color: palette(link);&quot;&gt;project website&lt;/a&gt;.</source>
<translation>访&lt;a href=&quot;%1&quot; style=&quot;text-decoration: underline; color: Palette(link);&quot;&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../aboutdialog/aboutdialog.cpp" line="91"/>
<location filename="../aboutdialog/aboutdialog.cpp" line="99"/>
<source>Using &lt;a href=&quot;qtversion&quot;&gt;Qt %1&lt;/a&gt;</source>
<translation>使 &lt;a href=&quot;qtversion&quot;&gt;Qt %1&lt;/a&gt;</translation>
</message>
@ -111,8 +120,8 @@
<message>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="12"/>
<location filename="../enterpassworddialog/enterpassworddialog.ui" line="51"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the password</source>
<translation></translation>
</message>
@ -157,28 +166,28 @@
<translation></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="190"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="205"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="183"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="198"/>
<source>Enter the new password</source>
<translation></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="293"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="289"/>
<source>You didn&apos;t enter a user name.</source>
<translation></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="295"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="291"/>
<source>You didn&apos;t enter a password.</source>
<translation></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="300"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="296"/>
<source>You have to enter the new password twice to ensure you enterd it correct.</source>
<translation></translation>
</message>
<message>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="303"/>
<location filename="../enterpassworddialog/enterpassworddialog.cpp" line="299"/>
<source>You mistyped the password.</source>
<translation></translation>
</message>
@ -221,42 +230,42 @@
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="144"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="155"/>
<source>Color palette configuration (*.ini)</source>
<translation> (*.ini)</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="151"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="162"/>
<source>Unable to load &quot;%1&quot;.</source>
<translation> &quot;%1&quot;</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="156"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="167"/>
<source>&quot;%1&quot; does not contain a valid palette.</source>
<translation>&quot;%1&quot; </translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="169"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="180"/>
<source>Unable to write &quot;%1&quot;.</source>
<translation> &quot;%1&quot;.</translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="177"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="188"/>
<source>Load palette</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="189"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="200"/>
<source>Error reading palette</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="195"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="206"/>
<source>Save palette</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="203"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="214"/>
<source>Error writing palette</source>
<translation></translation>
</message>
@ -264,22 +273,22 @@
<context>
<name>QtUtilities::PaletteModel</name>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="405"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="416"/>
<source>Color Role</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="407"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="418"/>
<source>Active</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="409"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="420"/>
<source>Inactive</source>
<translation></translation>
</message>
<message>
<location filename="../paletteeditor/paletteeditor.cpp" line="411"/>
<location filename="../paletteeditor/paletteeditor.cpp" line="422"/>
<source>Disabled</source>
<translation></translation>
</message>
@ -287,24 +296,24 @@
<context>
<name>QtUtilities::PathSelection</name>
<message>
<location filename="../widgets/pathselection.cpp" line="56"/>
<location filename="../widgets/pathselection.cpp" line="76"/>
<location filename="../widgets/pathselection.cpp" line="87"/>
<location filename="../widgets/pathselection.cpp" line="144"/>
<source>Select ...</source>
<translation> ...</translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="81"/>
<location filename="../widgets/pathselection.cpp" line="92"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="84"/>
<location filename="../widgets/pathselection.cpp" line="95"/>
<source>Explore</source>
<translation></translation>
</message>
<message>
<location filename="../widgets/pathselection.cpp" line="120"/>
<location filename="../widgets/pathselection.cpp" line="122"/>
<location filename="../widgets/pathselection.cpp" line="131"/>
<location filename="../widgets/pathselection.cpp" line="133"/>
<source>Select path</source>
<translation></translation>
</message>
@ -482,12 +491,12 @@ These settings might be overwritten by your Qt platform integration plugin and h
<translation></translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="294"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="320"/>
<source>&lt;p&gt;&lt;b&gt;Errors occurred when applying changes:&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;</source>
<translation>&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;</translation>
</message>
<message>
<location filename="../settingsdialog/settingsdialog.cpp" line="299"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="325"/>
<source>unknown error</source>
<translation></translation>
</message>

View File

@ -53,7 +53,7 @@ PathSelection::PathSelection(QWidget *parent)
m_lineEdit->installEventFilter(this);
m_lineEdit->setCompleter(s_completer);
m_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_button->setText(tr("Select ..."));
setTexts();
auto *const layout = new QHBoxLayout(this);
layout->setSpacing(3);
@ -65,6 +65,17 @@ PathSelection::PathSelection(QWidget *parent)
connect(m_button, &QPushButton::clicked, this, &PathSelection::showFileDialog);
}
bool PathSelection::event(QEvent *event)
{
switch (event->type()) {
case QEvent::LanguageChange:
setTexts();
break;
default:;
}
return QWidget::event(event);
}
bool PathSelection::eventFilter(QObject *obj, QEvent *event)
{
#ifndef QT_NO_CONTEXTMENU
@ -127,4 +138,10 @@ void PathSelection::showFileDialog()
}
}
}
void PathSelection::setTexts()
{
m_button->setText(tr("Select ..."));
}
} // namespace QtUtilities

View File

@ -24,10 +24,12 @@ public:
void provideCustomFileDialog(QFileDialog *customFileDialog);
protected:
bool event(QEvent *event) override;
bool eventFilter(QObject *obj, QEvent *event) override;
private Q_SLOTS:
void showFileDialog();
void setTexts();
private:
ClearLineEdit *m_lineEdit;