3#include "resources/config.h"
13#include <QStringBuilder>
15#if defined(QT_UTILITIES_GUI_QTWIDGETS)
16#include <QApplication>
17#elif defined(QT_UTILITIES_GUI_QTQUICK)
18#include <QGuiApplication>
20#include <QCoreApplication>
24#include <QStandardPaths>
32inline void initResources()
34 Q_INIT_RESOURCE(qtutilsicons);
37inline void cleanupResources()
39 Q_CLEANUP_RESOURCE(qtutilsicons);
73namespace TranslationFiles {
78static QList<QTranslator *> translators;
126 const auto debugTranslations = qEnvironmentVariableIsSet(
"QT_DEBUG_TRANSLATIONS");
127 for (
const auto &repoName : repositoryNames) {
128 auto *
const qtTranslator =
new QTranslator(QCoreApplication::instance());
129 const auto fileName = QString(repoName % QChar(
'_') % localeName);
133 || qtTranslator->load(fileName,
135#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
136 QLibraryInfo::location(QLibraryInfo::TranslationsPath)
138 QLibraryInfo::path(QLibraryInfo::TranslationsPath)
141 || qtTranslator->load(fileName, path = QStringLiteral(
"../share/qt/translations"))
142 || qtTranslator->load(fileName, path = QStringLiteral(
":/translations"))) {
143 QCoreApplication::installTranslator(qtTranslator);
144 translators.append(qtTranslator);
145 if (debugTranslations) {
146 cerr <<
"Loading translation file for Qt repository \"" << repoName.toLocal8Bit().data() <<
"\" and the locale \""
147 << localeName.toLocal8Bit().data() <<
"\" from \"" << path.toLocal8Bit().data() <<
"\"." << endl;
151 if (localeName.startsWith(QLatin1String(
"en"))) {
155 cerr <<
"Unable to load translation file for Qt repository \"" << repoName.toLocal8Bit().data() <<
"\" and locale "
156 << localeName.toLocal8Bit().data() <<
"." << endl;
185 const auto defaultLocale(QLocale().name());
186 if (defaultLocale != QLatin1String(
"en_US")) {
192void logTranslationEvent(
193 const char *event,
const QString &configName,
const QString &applicationName,
const QString &localeName,
const QString &path = QString())
195 cerr <<
event <<
" translation file for \"" << applicationName.toLocal8Bit().data() <<
"\"";
196 if (!configName.isEmpty()) {
197 cerr <<
" (config \"" << configName.toLocal8Bit().data() <<
"\")";
199 cerr <<
" and locale \"" << localeName.toLocal8Bit().data() <<
'\"';
200 if (!path.isEmpty()) {
201 cerr <<
" from \"" << path.toLocal8Bit().data() <<
'\"';
229 auto *
const appTranslator =
new QTranslator(QCoreApplication::instance());
230 const auto fileName = QString(applicationName % QChar(
'_') % localeName);
231 const auto directoryName = configName.isEmpty() ? applicationName : QString(applicationName % QChar(
'-') % configName);
235 || appTranslator->load(fileName, path = QStringLiteral(
".")) || appTranslator->load(fileName, path = QStringLiteral(
"../") % directoryName)
236 || appTranslator->load(fileName, path = QStringLiteral(
"../../") % directoryName)
237 || appTranslator->load(fileName, path = QStringLiteral(
"./translations"))
238 || appTranslator->load(fileName, path = QStringLiteral(
"../share/") % directoryName % QStringLiteral(
"/translations"))
239 || appTranslator->load(fileName, path = QStringLiteral(APP_INSTALL_PREFIX
"/share/") % directoryName % QStringLiteral(
"/translations"))
240 || appTranslator->load(fileName, path = QStringLiteral(
":/translations"))) {
241 QCoreApplication::installTranslator(appTranslator);
242 translators.append(appTranslator);
243 if (qEnvironmentVariableIsSet(
"QT_DEBUG_TRANSLATIONS")) {
244 logTranslationEvent(
"Loading", configName, applicationName, localeName, path);
247 delete appTranslator;
248 if (localeName.startsWith(QLatin1String(
"en"))) {
252 logTranslationEvent(
"Unable to load", configName, applicationName, localeName);
263 for (
const QString &applicationName : applicationNames) {
276 for (
const QString &applicationName : applicationNames) {
286 for (
auto *
const translator : translators) {
287 QCoreApplication::removeTranslator(translator);
299namespace ApplicationInstances {
301#if defined(QT_UTILITIES_GUI_QTWIDGETS)
307 return qobject_cast<QApplication *>(QCoreApplication::instance()) !=
nullptr;
311#if defined(QT_UTILITIES_GUI_QTWIDGETS) || defined(QT_UTILITIES_GUI_QTQUICK)
317 return qobject_cast<QGuiApplication *>(QCoreApplication::instance()) !=
nullptr;
326 return qobject_cast<QCoreApplication *>(QCoreApplication::instance()) !=
nullptr;
342#if defined(Q_OS_WINDOWS) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
343 if (
const auto qtVersion = QLibraryInfo::version();
344 qtVersion >= QVersionNumber(6, 4, 0) && qtVersion < QVersionNumber(6, 5, 0) && !qEnvironmentVariableIsSet(
"QT_QPA_PLATFORM")) {
345 qputenv(
"QT_QPA_PLATFORM",
"windows:darkmode=1");
350#ifdef QT_FEATURE_fontdialog
351 if (!qEnvironmentVariableIsSet(
"FONTCONFIG_PATH") && QDir(QStringLiteral(
"/etc/fonts")).exists()) {
352 qputenv(
"FONTCONFIG_PATH",
"/etc/fonts");
357#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
358 if (!QCoreApplication::instance()) {
359 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling,
true);
361 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps,
true);
377std::unique_ptr<QSettings>
getSettings(
const QString &organization,
const QString &application)
379 auto settings = std::unique_ptr<QSettings>();
380 const auto portableFileName
381 = application.isEmpty() ? organization + QStringLiteral(
".ini") : organization % QChar(
'/') % application % QStringLiteral(
".ini");
382 if (
const auto portableFileWorkingDir = QFile(portableFileName); portableFileWorkingDir.exists()) {
383 settings = std::make_unique<QSettings>(portableFileWorkingDir.fileName(), QSettings::IniFormat);
384 }
else if (
const auto portableFileNextToApp = QFile(QCoreApplication::applicationDirPath() % QChar(
'/') % portableFileName);
385 portableFileNextToApp.exists()) {
386 settings = std::make_unique<QSettings>(portableFileNextToApp.fileName(), QSettings::IniFormat);
388 settings = std::make_unique<QSettings>(QSettings::IniFormat, QSettings::UserScope, organization, application);
390 if (organization != QCoreApplication::organizationName() || application != QCoreApplication::applicationName()) {
392 = QSettings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName())
394 QFile::rename(oldConfig, settings->fileName()) || QFile::remove(oldConfig);
406 auto errorMessage = QString();
407 switch (settings.status()) {
408 case QSettings::NoError:
410 case QSettings::AccessError:
411 errorMessage = QCoreApplication::translate(
"QtUtilities",
"unable to access file");
413 case QSettings::FormatError:
414 errorMessage = QCoreApplication::translate(
"QtUtilities",
"file has invalid format");
417 errorMessage = QCoreApplication::translate(
"QtUtilities",
"unknown error");
419 return QCoreApplication::translate(
"QtUtilities",
"Unable to sync settings from \"%1\": %2").arg(settings.fileName(), errorMessage);
429 const auto cachePaths = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
430 for (
const auto &cachePath : cachePaths) {
431 const auto cacheDir = QDir(cachePath);
432 const auto subdirs = cacheDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
433 for (
const auto &subdir : subdirs) {
434 if (subdir.startsWith(QLatin1String(
"qtpipelinecache"))) {
435 QFile::remove(cachePath % QChar(
'/') % subdir % QStringLiteral(
"/qqpc_opengl"));
QT_UTILITIES_EXPORT bool hasCoreApp()
Returns whether a QCoreApplication has been instantiated yet.
Functions for using the resources provided by this library.
QT_UTILITIES_EXPORT void init()
Initiates the resources used and provided by this library.
QT_UTILITIES_EXPORT void cleanup()
Frees the resources used and provided by this library.
QT_UTILITIES_EXPORT void loadQtTranslationFile(std::initializer_list< QString > repositoryNames)
Loads and installs the appropriate Qt translation file for the current locale.
QT_UTILITIES_EXPORT void clearTranslationFiles()
Clears all translation files previously loaded via the load-functions in this namespace.
QT_UTILITIES_EXPORT void loadApplicationTranslationFile(const QString &configName, const QString &applicationName)
Loads and installs the appropriate application translation file for the current locale.
QT_UTILITIES_EXPORT QString & additionalTranslationFilePath()
Allows to set an additional search path for translation files.
QT_UTILITIES_EXPORT std::unique_ptr< QSettings > getSettings(const QString &organization, const QString &application=QString())
Returns the settings object for the specified organization and application.
QT_UTILITIES_EXPORT void deletePipelineCacheIfNeeded()
Deletes the Qt Quick pipeline cache on platforms where this is needed to workaround issues with the c...
QT_UTILITIES_EXPORT void setupCommonQtApplicationAttributes()
Sets Qt application attributes which are commonly used within my Qt applications.
QT_UTILITIES_EXPORT QString errorMessageForSettings(const QSettings &settings)
Returns an error message for the specified settings or an empty string if there's no error.