/************************************************************************ ** ** @file vabstractapplication.cpp ** @author Roman Telezhynskyi ** @date 18 6, 2015 ** ** @brief ** @copyright ** This source code is part of the Valentina project, a pattern making ** program, whose allow create and modeling patterns of clothing. ** Copyright (C) 2015 Valentina project ** All Rights Reserved. ** ** 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 . ** *************************************************************************/ #include "vabstractapplication.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_UNIX # include #endif #if defined(APPIMAGE) && defined(Q_OS_LINUX) # include "appimage.h" #endif // defined(APPIMAGE) && defined(Q_OS_LINUX) const QString VAbstractApplication::warningMessageSignature = QStringLiteral("[PATTERN MESSAGE]"); //--------------------------------------------------------------------------------------------------------------------- VAbstractApplication::VAbstractApplication(int &argc, char **argv) :QApplication(argc, argv), undoStack(new QUndoStack(this)) { QString rules; #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 1) #if defined(V_NO_ASSERT) // Ignore SSL-related warnings // See issue #528: Error: QSslSocket: cannot resolve SSLv2_client_method. rules += QLatin1String("qt.network.ssl.warning=false\n"); // See issue #568: Certificate checking on Mac OS X. rules += QLatin1String("qt.network.ssl.critical=false\n" "qt.network.ssl.fatal=false\n"); #endif //defined(V_NO_ASSERT) #endif // QT_VERSION >= QT_VERSION_CHECK(5, 4, 1) #if defined(V_NO_ASSERT) // See issue #992: QXcbConnection: XCB Error. rules += QLatin1String("qt.qpa.*=false\n"); #endif // cppcheck-suppress reademptycontainer if (not rules.isEmpty()) { QLoggingCategory::setFilterRules(rules); } #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) // Enable support for HiDPI bitmap resources // 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 setAttribute(Qt::AA_UseHighDpiPixmaps); #endif connect(this, &QApplication::aboutToQuit, this, &VAbstractApplication::AboutToQuit); } //--------------------------------------------------------------------------------------------------------------------- /** * @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. */ QString VAbstractApplication::translationsPath(const QString &locale) const { const QString trPath = QStringLiteral("/translations"); #ifdef Q_OS_WIN Q_UNUSED(locale) return QCoreApplication::applicationDirPath() + trPath; #elif defined(Q_OS_MAC) QString mainPath; if (locale.isEmpty()) { mainPath = QCoreApplication::applicationDirPath() + QLatin1String("/../Resources") + trPath; } else { mainPath = QCoreApplication::applicationDirPath() + QLatin1String("/../Resources") + trPath + QLatin1String("/") + locale + QLatin1String(".lproj"); } QDir dirBundle(mainPath); if (dirBundle.exists()) { return dirBundle.absolutePath(); } else { QDir appDir = QDir(qApp->applicationDirPath()); appDir.cdUp(); appDir.cdUp(); appDir.cdUp(); QDir dir(appDir.absolutePath() + trPath); if (dir.exists()) { return dir.absolutePath(); } else { return PKGDATADIR + trPath; } } #else // Unix Q_UNUSED(locale) QDir dir(QCoreApplication::applicationDirPath() + trPath); if (dir.exists()) { return dir.absolutePath(); } else { #if defined(APPIMAGE) && defined(Q_OS_LINUX) /* Fix path to trasnaltions when run inside AppImage. */ return AppImageRoot() + PKGDATADIR + trPath; #else return PKGDATADIR + trPath; #endif // defined(APPIMAGE) && defined(Q_OS_LINUX) } #endif } //--------------------------------------------------------------------------------------------------------------------- QUndoStack *VAbstractApplication::getUndoStack() const { return undoStack; } //--------------------------------------------------------------------------------------------------------------------- bool VAbstractApplication::IsPedantic() const { return false; } //--------------------------------------------------------------------------------------------------------------------- #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)) { // cppcheck-suppress ignoredReturnValue freopen("CONOUT$", "w", stdout); // cppcheck-suppress ignoredReturnValue freopen("CONOUT$", "w", stderr); } } #endif //--------------------------------------------------------------------------------------------------------------------- void VAbstractApplication::LoadTranslation(const QString &locale) { if (locale.isEmpty()) { qDebug()<<"Locale is empty."; return; } qDebug()<<"Checked locale:"<load("qt_" + locale, translationsPath(locale)); #else qtTranslator->load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); #endif installTranslator(qtTranslator); qtxmlTranslator = new QTranslator(this); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) qtxmlTranslator->load("qtxmlpatterns_" + locale, translationsPath(locale)); #else qtxmlTranslator->load("qtxmlpatterns_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); #endif installTranslator(qtxmlTranslator); qtBaseTranslator = new QTranslator(this); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) qtBaseTranslator->load("qtbase_" + locale, translationsPath(locale)); #else qtBaseTranslator->load("qtbase_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); #endif installTranslator(qtBaseTranslator); appTranslator = new QTranslator(this); appTranslator->load("valentina_" + locale, translationsPath(locale)); installTranslator(appTranslator); const QString system = Settings()->GetPMSystemCode(); pmsTranslator = new QTranslator(this); pmsTranslator->load("measurements_" + system + "_" + locale, translationsPath(locale)); installTranslator(pmsTranslator); InitTrVars();//Very important do it after load QM files. } //--------------------------------------------------------------------------------------------------------------------- void VAbstractApplication::ClearTranslation() { if (not qtTranslator.isNull()) { removeTranslator(qtTranslator); delete qtTranslator; } if (not qtxmlTranslator.isNull()) { removeTranslator(qtxmlTranslator); delete qtxmlTranslator; } if (not qtBaseTranslator.isNull()) { removeTranslator(qtBaseTranslator); delete qtBaseTranslator; } if (not appTranslator.isNull()) { removeTranslator(appTranslator); delete appTranslator; } if (not pmsTranslator.isNull()) { removeTranslator(pmsTranslator); delete pmsTranslator; } } //--------------------------------------------------------------------------------------------------------------------- /** * @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 */ QString VAbstractApplication::ClearMessage(QString msg) { if (msg.startsWith('"') && msg.endsWith('"')) { msg.remove(0, 1); msg.chop(1); } msg.replace("\\\"", "\""); return msg; } //--------------------------------------------------------------------------------------------------------------------- bool VAbstractApplication::IsWarningMessage(const QString &message) const { return VAbstractApplication::ClearMessage(message).startsWith(warningMessageSignature); } //--------------------------------------------------------------------------------------------------------------------- QFileDialog::Options VAbstractApplication::NativeFileDialog(QFileDialog::Options options) const { if (settings->IsDontUseNativeDialog()) { options |= QFileDialog::DontUseNativeDialog; } return options; }