2015-06-18 10:45:38 +02:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file vabstractapplication.cpp
|
|
|
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
|
|
|
** @date 18 6, 2015
|
|
|
|
**
|
|
|
|
** @brief
|
|
|
|
** @copyright
|
2017-10-05 11:20:01 +02:00
|
|
|
** This source code is part of the Valentina project, a pattern making
|
2015-06-18 10:45:38 +02:00
|
|
|
** program, whose allow create and modeling patterns of clothing.
|
|
|
|
** Copyright (C) 2015 Valentina project
|
2020-01-31 07:00:05 +01:00
|
|
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
2015-06-18 10:45:38 +02:00
|
|
|
**
|
|
|
|
** Valentina is free software: you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** Valentina is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
**
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#include "vabstractapplication.h"
|
|
|
|
|
2023-10-28 08:55:21 +02:00
|
|
|
#include "QtConcurrent/qtconcurrentrun.h"
|
|
|
|
#include "compatibility.h"
|
|
|
|
#include "svgfont/vsvgfontdatabase.h"
|
2015-11-18 13:42:25 +01:00
|
|
|
#include <QDir>
|
2023-06-08 12:20:20 +02:00
|
|
|
#include <QFileSystemWatcher>
|
|
|
|
#include <QFuture>
|
2015-09-19 21:58:32 +02:00
|
|
|
#include <QLibraryInfo>
|
2019-04-05 14:42:22 +02:00
|
|
|
#include <QLoggingCategory>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QMessageLogger>
|
2023-06-08 12:20:20 +02:00
|
|
|
#include <QStandardPaths>
|
2015-10-18 21:30:51 +02:00
|
|
|
#include <QTranslator>
|
2018-07-09 09:45:23 +02:00
|
|
|
#include <QUndoStack>
|
2023-06-08 12:20:20 +02:00
|
|
|
#include <QWidget>
|
2015-10-18 21:30:51 +02:00
|
|
|
#include <QtDebug>
|
2015-09-19 21:58:32 +02:00
|
|
|
|
2023-08-13 08:24:01 +02:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
#include "literals.h"
|
|
|
|
#endif
|
|
|
|
|
2023-02-11 15:14:15 +01:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
2023-08-13 08:24:01 +02:00
|
|
|
#include "vtextcodec.h"
|
2023-02-11 15:14:15 +01:00
|
|
|
#else
|
|
|
|
#include <QTextCodec>
|
|
|
|
#endif
|
2023-02-09 16:23:46 +01:00
|
|
|
|
2019-11-26 18:56:40 +01:00
|
|
|
#ifdef Q_OS_UNIX
|
2023-06-08 12:20:20 +02:00
|
|
|
#include <unistd.h>
|
2019-11-26 18:56:40 +01:00
|
|
|
#endif
|
|
|
|
|
2020-07-13 15:11:57 +02:00
|
|
|
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
|
2023-06-08 12:20:20 +02:00
|
|
|
#include "appimage.h"
|
2020-07-13 15:11:57 +02:00
|
|
|
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
|
|
|
|
|
2023-10-07 17:56:39 +02:00
|
|
|
using namespace Qt::Literals::StringLiterals;
|
|
|
|
|
2022-04-22 11:42:46 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
auto FilterLocales(const QStringList &locales) -> QStringList
|
|
|
|
{
|
|
|
|
QStringList filtered;
|
|
|
|
for (const auto &locale : locales)
|
|
|
|
{
|
2023-10-07 17:56:39 +02:00
|
|
|
if (not locale.startsWith("ru"_L1))
|
2022-04-22 11:42:46 +02:00
|
|
|
{
|
|
|
|
filtered.append(locale);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return filtered;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
auto LoadQM(QTranslator *translator, const QString &filename, const QString &locale, const QString &qmDir) -> bool
|
|
|
|
{
|
|
|
|
QStringList languages;
|
|
|
|
if (not locale.isEmpty())
|
|
|
|
{
|
|
|
|
languages.append(locale);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
languages = QLocale().uiLanguages();
|
|
|
|
}
|
|
|
|
|
|
|
|
languages = FilterLocales(languages);
|
|
|
|
|
|
|
|
for (auto &locale : languages)
|
|
|
|
{
|
|
|
|
const bool loaded = translator->load(filename + locale, qmDir);
|
|
|
|
if (loaded)
|
|
|
|
{
|
|
|
|
return loaded;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2023-06-08 12:20:20 +02:00
|
|
|
} // namespace
|
2022-04-22 11:42:46 +02:00
|
|
|
|
2020-11-20 12:18:38 +01:00
|
|
|
const QString VAbstractApplication::warningMessageSignature = QStringLiteral("[PATTERN MESSAGE]");
|
|
|
|
|
2015-06-18 10:45:38 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VAbstractApplication::VAbstractApplication(int &argc, char **argv)
|
2023-06-08 12:20:20 +02:00
|
|
|
: QApplication(argc, argv),
|
|
|
|
undoStack(new QUndoStack(this))
|
2015-10-03 16:03:25 +02:00
|
|
|
{
|
2016-09-20 13:10:42 +02:00
|
|
|
QString rules;
|
2016-09-20 13:27:21 +02:00
|
|
|
|
2016-08-02 12:43:41 +02:00
|
|
|
#if defined(V_NO_ASSERT)
|
2016-07-20 10:48:09 +02:00
|
|
|
// Ignore SSL-related warnings
|
|
|
|
// See issue #528: Error: QSslSocket: cannot resolve SSLv2_client_method.
|
2023-10-07 17:56:39 +02:00
|
|
|
rules += "qt.network.ssl.warning=false\n"_L1;
|
2016-09-20 13:10:42 +02:00
|
|
|
// See issue #568: Certificate checking on Mac OS X.
|
2023-10-07 17:56:39 +02:00
|
|
|
rules += "qt.network.ssl.critical=false\n"
|
|
|
|
"qt.network.ssl.fatal=false\n"_L1;
|
2023-06-08 12:20:20 +02:00
|
|
|
#endif // defined(V_NO_ASSERT)
|
2016-09-20 13:10:42 +02:00
|
|
|
|
2020-01-20 09:14:44 +01:00
|
|
|
#if defined(V_NO_ASSERT)
|
|
|
|
// See issue #992: QXcbConnection: XCB Error.
|
2023-10-07 17:56:39 +02:00
|
|
|
rules += "qt.qpa*=false\n"_L1;
|
|
|
|
rules += "kf5.kio.core*=false\n"_L1;
|
|
|
|
rules += "qt.gui.icc.warning=false\n"_L1;
|
2020-01-20 09:14:44 +01:00
|
|
|
#endif
|
|
|
|
|
2016-09-20 13:10:42 +02:00
|
|
|
if (not rules.isEmpty())
|
|
|
|
{
|
|
|
|
QLoggingCategory::setFilterRules(rules);
|
|
|
|
}
|
2016-09-20 13:27:21 +02:00
|
|
|
|
2023-08-12 11:03:28 +02:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
2016-09-20 13:27:21 +02:00
|
|
|
// Enable support for HiDPI bitmap resources
|
2016-11-04 11:44:57 +01:00
|
|
|
// The attribute is available since Qt 5.1, but by default disabled.
|
|
|
|
// Because on Windows and Mac OS X we always use last version
|
|
|
|
// and Linux users send bug reports probably they related to this attribute
|
|
|
|
// better not enable it before Qt 5.6.
|
|
|
|
//
|
|
|
|
// Related issues:
|
|
|
|
// Issue #584. frequent xcb errors and hangs
|
|
|
|
// https://bitbucket.org/dismine/valentina/issues/584/frequent-xcb-errors-and-hangs
|
|
|
|
// Issue #527. Error: Pasting a wrong formula : every dialog box is "glued" to the screen and can't close file
|
|
|
|
// or Valentina.
|
|
|
|
// https://bitbucket.org/dismine/valentina/issues/527/error-pasting-a-wrong-formula-every-dialog
|
|
|
|
|
2016-09-20 13:27:21 +02:00
|
|
|
setAttribute(Qt::AA_UseHighDpiPixmaps);
|
|
|
|
#endif
|
|
|
|
|
2019-07-01 11:47:06 +02:00
|
|
|
connect(this, &QApplication::aboutToQuit, this, &VAbstractApplication::AboutToQuit);
|
2023-06-27 13:15:21 +02:00
|
|
|
|
|
|
|
m_uptimeTimer.start();
|
2015-10-03 16:03:25 +02:00
|
|
|
}
|
2015-06-18 10:45:38 +02:00
|
|
|
|
2023-02-11 15:14:15 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VAbstractApplication::~VAbstractApplication()
|
|
|
|
{
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
QHashIterator<QStringConverter::Encoding, VTextCodec *> i(m_codecs);
|
|
|
|
while (i.hasNext())
|
|
|
|
{
|
|
|
|
i.next();
|
|
|
|
delete i.value();
|
|
|
|
}
|
|
|
|
#endif
|
2023-06-22 17:30:43 +02:00
|
|
|
delete m_svgFontDatabase;
|
2023-02-11 15:14:15 +01:00
|
|
|
}
|
|
|
|
|
2015-10-22 11:28:17 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2015-11-18 13:42:25 +01:00
|
|
|
/**
|
|
|
|
* @brief translationsPath return path to the root directory that contain QM files.
|
|
|
|
* @param locale used only in Mac OS. If empty return path to the root directory. If not - return path to locale
|
|
|
|
* subdirectory inside an app bundle.
|
|
|
|
* @return path to a directory that contain QM files.
|
|
|
|
*/
|
2022-04-22 11:42:46 +02:00
|
|
|
auto VAbstractApplication::translationsPath(const QString &locale) -> QString
|
2015-11-18 13:42:25 +01:00
|
|
|
{
|
|
|
|
const QString trPath = QStringLiteral("/translations");
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
Q_UNUSED(locale)
|
2017-07-09 08:02:26 +02:00
|
|
|
return QCoreApplication::applicationDirPath() + trPath;
|
2015-11-18 13:42:25 +01:00
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
QString mainPath;
|
|
|
|
if (locale.isEmpty())
|
|
|
|
{
|
2023-10-07 17:56:39 +02:00
|
|
|
mainPath = QCoreApplication::applicationDirPath() + "/../Resources"_L1 + trPath;
|
2015-11-18 13:42:25 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-10-07 17:56:39 +02:00
|
|
|
mainPath = QCoreApplication::applicationDirPath() + "/../Resources"_L1 + trPath + '/'_L1 + locale + ".lproj"_L1;
|
2015-11-18 13:42:25 +01:00
|
|
|
}
|
|
|
|
QDir dirBundle(mainPath);
|
|
|
|
if (dirBundle.exists())
|
|
|
|
{
|
|
|
|
return dirBundle.absolutePath();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-10-25 16:54:51 +02:00
|
|
|
QDir appDir = QDir(qApp->applicationDirPath());
|
|
|
|
appDir.cdUp();
|
|
|
|
appDir.cdUp();
|
|
|
|
appDir.cdUp();
|
|
|
|
QDir dir(appDir.absolutePath() + trPath);
|
2015-11-18 13:42:25 +01:00
|
|
|
if (dir.exists())
|
|
|
|
{
|
|
|
|
return dir.absolutePath();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-11 09:52:53 +02:00
|
|
|
return PKGDATADIR + trPath;
|
2015-11-18 13:42:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else // Unix
|
|
|
|
Q_UNUSED(locale)
|
2017-07-09 08:02:26 +02:00
|
|
|
QDir dir(QCoreApplication::applicationDirPath() + trPath);
|
2015-11-18 13:42:25 +01:00
|
|
|
if (dir.exists())
|
|
|
|
{
|
|
|
|
return dir.absolutePath();
|
|
|
|
}
|
2021-05-21 20:33:17 +02:00
|
|
|
|
2023-02-16 20:24:09 +01:00
|
|
|
#ifdef QBS_BUILD
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
dir.setPath(QCoreApplication::applicationDirPath() + "/../../.." + PKGDATADIR + trPath);
|
|
|
|
#else
|
|
|
|
dir = QDir(QCoreApplication::applicationDirPath() + "/../../.." + PKGDATADIR + trPath);
|
|
|
|
#endif
|
|
|
|
if (dir.exists())
|
|
|
|
{
|
|
|
|
return dir.absolutePath();
|
|
|
|
}
|
|
|
|
#endif // QBS_BUILD
|
|
|
|
|
2020-07-13 15:11:57 +02:00
|
|
|
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
|
2021-05-21 20:33:17 +02:00
|
|
|
/* Fix path to trasnaltions when run inside AppImage. */
|
|
|
|
return AppImageRoot() + PKGDATADIR + trPath;
|
2020-07-13 15:11:57 +02:00
|
|
|
#else
|
2021-05-21 20:33:17 +02:00
|
|
|
return PKGDATADIR + trPath;
|
2020-07-13 15:11:57 +02:00
|
|
|
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
|
2021-05-21 20:33:17 +02:00
|
|
|
#endif // Unix
|
2015-11-18 13:42:25 +01:00
|
|
|
}
|
|
|
|
|
2015-10-22 11:28:17 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::getUndoStack() const -> QUndoStack *
|
2015-10-22 11:28:17 +02:00
|
|
|
{
|
|
|
|
return undoStack;
|
|
|
|
}
|
2018-07-13 15:18:04 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::IsPedantic() const -> bool
|
2018-07-13 15:18:04 +02:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-10-22 11:28:17 +02:00
|
|
|
|
2017-12-10 12:17:04 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
#if defined(Q_OS_WIN)
|
|
|
|
void VAbstractApplication::WinAttachConsole()
|
|
|
|
{
|
|
|
|
/* Windows does not really support dual mode applications.
|
|
|
|
* To see console output we need to attach console.
|
|
|
|
* For case of using pipeline we check std output handler.
|
|
|
|
* Original idea: https://stackoverflow.com/a/41701133/3045403
|
|
|
|
*/
|
|
|
|
auto stdout_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
|
|
|
|
if (stdout_type == FILE_TYPE_UNKNOWN && AttachConsole(ATTACH_PARENT_PROCESS))
|
|
|
|
{
|
2023-03-09 07:13:20 +01:00
|
|
|
#ifdef Q_CC_MSVC
|
2023-03-08 17:45:42 +01:00
|
|
|
FILE *fp = nullptr;
|
|
|
|
freopen_s(&fp, "CONOUT$", "w", stdout);
|
|
|
|
freopen_s(&fp, "CONOUT$", "w", stderr);
|
2023-03-09 07:13:20 +01:00
|
|
|
#else
|
|
|
|
freopen("CONOUT$", "w", stdout);
|
|
|
|
freopen("CONOUT$", "w", stderr);
|
|
|
|
#endif // Q_CC_MSVC
|
2017-12-10 12:17:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2022-09-29 10:59:00 +02:00
|
|
|
void VAbstractApplication::LoadTranslation(QString locale)
|
2015-09-19 21:58:32 +02:00
|
|
|
{
|
2023-10-07 17:56:39 +02:00
|
|
|
if (locale.startsWith("ru"_L1))
|
2022-09-29 10:59:00 +02:00
|
|
|
{
|
|
|
|
locale = QString();
|
|
|
|
}
|
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
if (locale.isEmpty())
|
|
|
|
{
|
2023-06-08 12:20:20 +02:00
|
|
|
qDebug() << "Default locale";
|
2015-09-19 21:58:32 +02:00
|
|
|
}
|
2022-04-22 11:42:46 +02:00
|
|
|
else
|
2022-03-18 11:28:47 +01:00
|
|
|
{
|
2023-06-08 12:20:20 +02:00
|
|
|
qDebug() << "Checked locale:" << locale;
|
2022-03-18 11:28:47 +01:00
|
|
|
}
|
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
ClearTranslation();
|
|
|
|
|
2022-04-22 11:42:46 +02:00
|
|
|
const QString appQmDir = VAbstractApplication::translationsPath(locale);
|
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
qtTranslator = new QTranslator(this);
|
2015-11-17 15:20:36 +01:00
|
|
|
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
2022-04-22 11:42:46 +02:00
|
|
|
const QString qtQmDir = appQmDir;
|
2015-09-19 21:58:32 +02:00
|
|
|
#else
|
2023-02-09 16:23:46 +01:00
|
|
|
const QString qtQmDir = QLibraryPath(QLibraryInfo::TranslationsPath);
|
2015-09-19 21:58:32 +02:00
|
|
|
#endif
|
2022-04-22 11:42:46 +02:00
|
|
|
LoadQM(qtTranslator, QStringLiteral("qt_"), locale, qtQmDir);
|
2015-09-19 21:58:32 +02:00
|
|
|
installTranslator(qtTranslator);
|
|
|
|
|
2023-01-18 13:57:38 +01:00
|
|
|
#if defined(Q_OS_WIN) && !defined(QBS_BUILD)
|
2015-09-19 21:58:32 +02:00
|
|
|
qtxmlTranslator = new QTranslator(this);
|
2022-04-22 11:42:46 +02:00
|
|
|
LoadQM(qtxmlTranslator, QStringLiteral("qtxmlpatterns_"), locale, qtQmDir);
|
2015-09-19 21:58:32 +02:00
|
|
|
installTranslator(qtxmlTranslator);
|
|
|
|
|
2015-11-17 15:27:51 +01:00
|
|
|
qtBaseTranslator = new QTranslator(this);
|
2022-04-22 11:42:46 +02:00
|
|
|
LoadQM(qtBaseTranslator, QStringLiteral("qtbase_"), locale, qtQmDir);
|
2015-11-17 15:27:51 +01:00
|
|
|
installTranslator(qtBaseTranslator);
|
2023-01-18 13:57:38 +01:00
|
|
|
#endif // defined(Q_OS_WIN) && !defined(QBS_BUILD)
|
2015-11-17 15:27:51 +01:00
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
appTranslator = new QTranslator(this);
|
2022-04-22 11:42:46 +02:00
|
|
|
LoadQM(appTranslator, QStringLiteral("valentina_"), locale, appQmDir);
|
2015-09-19 21:58:32 +02:00
|
|
|
installTranslator(appTranslator);
|
|
|
|
|
|
|
|
pmsTranslator = new QTranslator(this);
|
2023-10-13 14:26:19 +02:00
|
|
|
LoadQM(pmsTranslator, QStringLiteral("measurements_") + Settings()->GetPMSystemCode() + '_'_L1, locale, appQmDir);
|
2015-09-19 21:58:32 +02:00
|
|
|
installTranslator(pmsTranslator);
|
|
|
|
|
2023-06-08 12:20:20 +02:00
|
|
|
InitTrVars(); // Very important do it after load QM files.
|
2015-09-19 21:58:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::ClearTranslation()
|
|
|
|
{
|
|
|
|
if (not qtTranslator.isNull())
|
|
|
|
{
|
|
|
|
removeTranslator(qtTranslator);
|
|
|
|
delete qtTranslator;
|
|
|
|
}
|
|
|
|
|
2023-01-18 13:57:38 +01:00
|
|
|
#if defined(Q_OS_WIN) && !defined(QBS_BUILD)
|
2015-09-19 21:58:32 +02:00
|
|
|
if (not qtxmlTranslator.isNull())
|
|
|
|
{
|
|
|
|
removeTranslator(qtxmlTranslator);
|
|
|
|
delete qtxmlTranslator;
|
|
|
|
}
|
|
|
|
|
2015-11-17 15:27:51 +01:00
|
|
|
if (not qtBaseTranslator.isNull())
|
|
|
|
{
|
|
|
|
removeTranslator(qtBaseTranslator);
|
|
|
|
delete qtBaseTranslator;
|
|
|
|
}
|
2023-01-18 13:57:38 +01:00
|
|
|
#endif // defined(Q_OS_WIN) && !defined(QBS_BUILD)
|
2015-11-17 15:27:51 +01:00
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
if (not appTranslator.isNull())
|
|
|
|
{
|
|
|
|
removeTranslator(appTranslator);
|
|
|
|
delete appTranslator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not pmsTranslator.isNull())
|
|
|
|
{
|
|
|
|
removeTranslator(pmsTranslator);
|
|
|
|
delete pmsTranslator;
|
|
|
|
}
|
|
|
|
}
|
2020-11-20 12:18:38 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief ClearMessage helps to clear a message string from standard Qt function.
|
|
|
|
* @param msg the message that contains '"' at the start and at the end
|
|
|
|
* @return cleared string
|
|
|
|
*/
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::ClearMessage(QString msg) -> QString
|
2020-11-20 12:18:38 +01:00
|
|
|
{
|
|
|
|
if (msg.startsWith('"') && msg.endsWith('"'))
|
|
|
|
{
|
|
|
|
msg.remove(0, 1);
|
|
|
|
msg.chop(1);
|
|
|
|
}
|
|
|
|
|
2021-02-17 18:07:55 +01:00
|
|
|
msg.replace("\\\"", "\"");
|
|
|
|
|
2020-11-20 12:18:38 +01:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::IsWarningMessage(const QString &message) const -> bool
|
2020-11-20 12:18:38 +01:00
|
|
|
{
|
|
|
|
return VAbstractApplication::ClearMessage(message).startsWith(warningMessageSignature);
|
|
|
|
}
|
2020-12-17 17:43:15 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::NativeFileDialog(QFileDialog::Options options) const -> QFileDialog::Options
|
2020-12-17 17:43:15 +01:00
|
|
|
{
|
|
|
|
if (settings->IsDontUseNativeDialog())
|
|
|
|
{
|
|
|
|
options |= QFileDialog::DontUseNativeDialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
return options;
|
|
|
|
}
|
2022-08-03 11:17:04 +02:00
|
|
|
|
2023-06-22 17:30:43 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
auto VAbstractApplication::SVGFontDatabase() -> VSvgFontDatabase *
|
|
|
|
{
|
|
|
|
if (m_svgFontDatabase == nullptr)
|
|
|
|
{
|
|
|
|
m_svgFontDatabase = new VSvgFontDatabase();
|
|
|
|
|
|
|
|
RestartSVGFontDatabaseWatcher();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_svgFontDatabase->IsPopulated())
|
|
|
|
{
|
|
|
|
m_svgFontDatabase->PopulateFontDatabase(QString());
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_svgFontDatabase;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::RestartSVGFontDatabaseWatcher()
|
|
|
|
{
|
|
|
|
if (m_svgFontDatabase != nullptr)
|
|
|
|
{
|
|
|
|
delete m_svgFontDatabaseWatcher;
|
|
|
|
m_svgFontDatabaseWatcher =
|
|
|
|
new QFileSystemWatcher({settings->GetPathSVGFonts(), VSvgFontDatabase::SystemSVGFontPath()}, this);
|
|
|
|
connect(m_svgFontDatabaseWatcher, &QFileSystemWatcher::directoryChanged, this,
|
|
|
|
&VAbstractApplication::RepopulateFontDatabase);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-27 13:15:21 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
auto VAbstractApplication::AppUptime() const -> qint64
|
|
|
|
{
|
|
|
|
return m_uptimeTimer.elapsed();
|
|
|
|
}
|
|
|
|
|
2023-10-23 15:57:22 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
auto VAbstractApplication::GetShortcutManager() const -> VAbstractShortcutManager *
|
|
|
|
{
|
|
|
|
return m_shortcutManager;
|
|
|
|
}
|
|
|
|
|
2023-02-11 15:14:15 +01:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec *
|
2023-02-11 15:14:15 +01:00
|
|
|
{
|
|
|
|
if (m_codecs.contains(encoding))
|
|
|
|
{
|
|
|
|
return m_codecs.value(encoding);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::CacheTextCodec(QStringConverter::Encoding encoding, VTextCodec *codec)
|
|
|
|
{
|
|
|
|
if (not m_codecs.contains(encoding))
|
|
|
|
{
|
|
|
|
m_codecs.insert(encoding, codec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-08-03 11:17:04 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::CheckSystemLocale()
|
|
|
|
{
|
|
|
|
const QString defLocale = QLocale::system().name();
|
2023-10-07 17:56:39 +02:00
|
|
|
if (defLocale.startsWith("ru"_L1))
|
2022-08-03 11:17:04 +02:00
|
|
|
{
|
|
|
|
qFatal("Incompatible locale \"%s\"", qPrintable(defLocale));
|
|
|
|
}
|
2022-10-04 13:52:09 +02:00
|
|
|
|
2023-06-08 12:20:20 +02:00
|
|
|
auto CheckLanguage = [](QStandardPaths::StandardLocation type, const QStringList &test)
|
2022-10-04 13:52:09 +02:00
|
|
|
{
|
|
|
|
const QString path = QStandardPaths::locate(type, QString(), QStandardPaths::LocateDirectory);
|
|
|
|
return std::any_of(test.begin(), test.end(), [path](const QString &t) { return path.contains(t); });
|
|
|
|
};
|
|
|
|
|
|
|
|
int match = 0;
|
|
|
|
match += CheckLanguage(QStandardPaths::DesktopLocation, {"Рабочий стол"});
|
|
|
|
match += CheckLanguage(QStandardPaths::DocumentsLocation, {"Мои документы", "Документы"});
|
|
|
|
match += CheckLanguage(QStandardPaths::MusicLocation, {"Моя музыка", "Музыка"});
|
|
|
|
match += CheckLanguage(QStandardPaths::MoviesLocation, {"Мои видео", "Видео"});
|
|
|
|
match += CheckLanguage(QStandardPaths::PicturesLocation, {"Мои рисунки", "Изображения", "Картинки"});
|
|
|
|
match += CheckLanguage(QStandardPaths::DownloadLocation, {"Мои документы", "Загрузки"});
|
|
|
|
|
|
|
|
if (match >= 4)
|
|
|
|
{
|
|
|
|
qFatal("russian language detected");
|
|
|
|
}
|
2022-08-03 11:17:04 +02:00
|
|
|
}
|
2023-06-22 17:30:43 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::SVGFontsPathChanged(const QString &oldPath, const QString &newPath)
|
|
|
|
{
|
|
|
|
if (oldPath != newPath)
|
|
|
|
{
|
|
|
|
if (m_svgFontDatabase != nullptr)
|
|
|
|
{
|
|
|
|
RestartSVGFontDatabaseWatcher();
|
|
|
|
m_svgFontDatabase->InvalidatePath(oldPath);
|
|
|
|
RepopulateFontDatabase(newPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VAbstractApplication::RepopulateFontDatabase(const QString &path)
|
|
|
|
{
|
|
|
|
if (m_svgFontDatabase != nullptr)
|
|
|
|
{
|
|
|
|
QFuture<void> future = QtConcurrent::run([this, path]() { m_svgFontDatabase->PopulateFontDatabase(path); });
|
|
|
|
}
|
|
|
|
}
|
2023-07-24 12:41:42 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays)
|
|
|
|
auto VAbstractApplication::IsOptionSet(int argc, char *argv[], const char *option) -> bool
|
|
|
|
{
|
|
|
|
for (int i = 1; i < argc; ++i)
|
|
|
|
{
|
|
|
|
if (qstrcmp(argv[i], option) == 0) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// See issue #624. https://bitbucket.org/dismine/valentina/issues/624
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays)
|
|
|
|
void VAbstractApplication::InitHighDpiScaling(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
/* For more info see: http://doc.qt.io/qt-5/highdpi.html */
|
2023-10-07 17:56:39 +02:00
|
|
|
if (IsOptionSet(argc, argv, qPrintable("--"_L1 + LONG_OPTION_NO_HDPI_SCALING)))
|
2023-07-24 12:41:42 +02:00
|
|
|
{
|
|
|
|
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
Q_UNUSED(argc);
|
|
|
|
Q_UNUSED(argv);
|
|
|
|
#endif
|
|
|
|
}
|