55 #include "../ifc/exception/vexceptionobjecterror.h"
56 #include "../ifc/exception/vexceptionbadid.h"
57 #include "../ifc/exception/vexceptionconversionerror.h"
58 #include "../ifc/exception/vexceptionemptyparameter.h"
59 #include "../ifc/exception/vexceptionwrongid.h"
60 #include "../vmisc/logging.h"
61 #include "../vmisc/vsysexits.h"
62 #include "../vmisc/diagnostic.h"
63 #include "../qmuparser/qmuparsererror.h"
67 #include <QFileOpenEvent>
68 #include <QLocalSocket>
70 #include <QTranslator>
72 #include <QLocalServer>
73 #include <QMessageBox>
75 #include <QGridLayout>
76 #include <QSpacerItem>
78 #include <QStandardPaths>
81 QT_WARNING_DISABLE_CLANG(
"-Wmissing-prototypes")
82 QT_WARNING_DISABLE_INTEL(1418)
84 Q_LOGGING_CATEGORY(mApp, "m.application")
88 #include <QCommandLineParser>
96 if ((type == QtDebugMsg) && msg.contains(QStringLiteral(
"::connect")))
101 #if defined(V_NO_ASSERT)
103 if ((type == QtWarningMsg) && msg.contains(QStringLiteral(
"QSslSocket: cannot resolve")))
108 if ((type == QtWarningMsg) && msg.contains(QStringLiteral(
"setGeometry: Unable to set geometry")))
114 #if defined(Q_OS_MAC)
118 if ((type == QtWarningMsg) && msg.contains(QStringLiteral(
"QICNSHandler::read()")))
124 if (msg.contains(QStringLiteral(
"Error receiving trust for a CA certificate")))
133 if ((type == QtDebugMsg) && msg.contains(QStringLiteral(
"QPainter::begin"))
134 && msg.contains(QStringLiteral(
"Paint device returned engine")))
142 if ((type == QtWarningMsg) && msg.contains(QStringLiteral(
"QClipboard::event"))
143 && msg.contains(QStringLiteral(
"Cowardly refusing")))
151 QCoreApplication *instance = QCoreApplication::instance();
152 const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
168 #if QT_VERSION > QT_VERSION_CHECK(5, 4, 2)
181 const bool topWinAllowsPop = (QApplication::activeModalWidget() ==
nullptr) ||
182 !QApplication::activeModalWidget()->inherits(
"QFileDialog");
183 QMessageBox messageBox;
189 messageBox.setIcon(QMessageBox::Warning);
193 messageBox.setIcon(QMessageBox::Critical);
197 messageBox.setIcon(QMessageBox::Critical);
199 #if QT_VERSION > QT_VERSION_CHECK(5, 4, 2)
202 messageBox.setIcon(QMessageBox::Information);
212 if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
214 if (not
qApp->IsTestMode())
218 messageBox.setText(msg);
219 messageBox.setStandardButtons(QMessageBox::Ok);
220 messageBox.setWindowModality(Qt::ApplicationModal);
221 messageBox.setModal(
true);
223 QGuiApplication::setOverrideCursor(Qt::ArrowCursor);
225 messageBox.setWindowFlags(messageBox.windowFlags() & ~Qt::WindowContextHelpButtonHint);
228 QGuiApplication::restoreOverrideCursor();
234 if (QtFatalMsg == type)
241 if (type != QtDebugMsg && type != QtWarningMsg)
252 , localServer(nullptr)
266 setWindowIcon(QIcon(
":/seamlymeicon/64x64/logo.png"));
297 return QApplication::notify(receiver,
event);
301 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Error parsing file. Program will be terminated.")),
307 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Error bad id. Program will be terminated.")),
313 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Error can't convert value. Program will be terminated.")),
319 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Error empty parameter. Program will be terminated.")),
325 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Error wrong id. Program will be terminated.")),
331 qCCritical(mApp,
"%s\n\n%s\n\n%s",
332 qUtf8Printable(
"Unhadled deleting tool. Continue use object after deleting!"),
338 qCCritical(mApp,
"%s\n\n%s\n\n%s", qUtf8Printable(tr(
"Something's wrong!!")),
346 qCCritical(mApp,
"%s", qUtf8Printable(tr(
"Parser error: %1. Program will be terminated.").arg(e.GetMsg())));
349 catch (std::exception &e)
351 qCCritical(mApp,
"%s", qUtf8Printable(tr(
"Exception thrown: %1. Program will be terminated.").arg(e.
what())));
408 qCDebug(mApp,
"Build revision: %s", BUILD_REVISION);
410 qCDebug(mApp,
"Built on %s at %s", __DATE__, __TIME__);
411 qCDebug(mApp,
"Command-line arguments: %s", qUtf8Printable(arguments().join(
", ")));
412 qCDebug(mApp,
"Process ID: %s", qUtf8Printable(QString().setNum(applicationPid())));
416 static const char * GENERIC_ICON_TO_CHECK =
"document-open";
417 if (QIcon::hasThemeIcon(GENERIC_ICON_TO_CHECK) ==
false)
423 QIcon::setThemeName(
"win.icon.theme");
453 case QEvent::FileOpen:
455 QFileOpenEvent *fileOpenEvent =
static_cast<QFileOpenEvent *
>(e);
456 const QString macFileOpen = fileOpenEvent->file();
457 if(not macFileOpen.isEmpty())
468 #if defined(Q_OS_MAC)
469 case QEvent::ApplicationActivate:
473 if (mw && not mw->isMinimized())
481 return VAbstractApplication::event(e);
483 return VAbstractApplication::event(e);
490 QCoreApplication::applicationName(),
this);
497 return qobject_cast<VSeamlyMeSettings *>(
settings);
506 dataBase->setAttribute(Qt::WA_DeleteOnClose,
true);
529 for (
int i=0; i < list.size(); ++i)
531 list.at(i)->RetranslateTable();
538 QCommandLineParser parser;
539 parser.setApplicationDescription(tr(
"Seamly2D's measurements editor."));
540 parser.addHelpOption();
541 parser.addVersionOption();
542 parser.addPositionalArgument(
"filename", tr(
"The measurement file."));
544 QCommandLineOption heightOption(QStringList() <<
"e" <<
"height",
545 tr(
"Open with the base height. Valid values: %1cm.")
547 tr(
"The base height"));
548 parser.addOption(heightOption);
550 QCommandLineOption sizeOption(QStringList() <<
"s" <<
"size",
552 tr(
"The base size"));
553 parser.addOption(sizeOption);
555 QCommandLineOption unitOption(QStringList() <<
"u" <<
"unit",
556 tr(
"Set pattern file unit: cm, mm, inch."),
557 tr(
"The pattern unit"));
558 parser.addOption(unitOption);
560 QCommandLineOption testOption(QStringList() <<
"test",
561 tr(
"Use for unit testing. Run the program and open a file without showing the main window."));
562 parser.addOption(testOption);
565 tr(
"Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). "
566 "Alternatively you can use the %1 environment variable.").arg(
"QT_AUTO_SCREEN_SCALE_FACTOR=0"));
567 parser.addOption(scalingOption);
569 parser.process(arguments);
571 bool flagHeight =
false;
572 bool flagSize =
false;
573 bool flagUnit =
false;
579 if (parser.isSet(heightOption))
581 const QString heightValue = parser.value(heightOption);
585 height = heightValue.toInt();
589 qCCritical(mApp,
"%s\n",
590 qPrintable(tr(
"Invalid base height argument. Must be %1cm.")
596 if (parser.isSet(sizeOption))
598 const QString sizeValue = parser.value(sizeOption);
602 size = sizeValue.toInt();
606 qCCritical(mApp,
"%s\n",
607 qPrintable(tr(
"Invalid base size argument. Must be %1cm.")
614 const QString unitValue = parser.value(unitOption);
615 if (not unitValue.isEmpty())
619 if (units.contains(unitValue))
626 qCCritical(mApp,
"%s\n", qPrintable(tr(
"Invalid base size argument. Must be cm, mm or inch.")));
632 testMode = parser.isSet(testOption);
636 const QString serverName = QCoreApplication::applicationName();
638 socket.connectToServer(serverName);
639 if (socket.waitForConnected(1000))
641 qCDebug(mApp,
"Connected to the server '%s'", qUtf8Printable(serverName));
642 QTextStream stream(&socket);
643 stream << QCoreApplication::arguments().join(
";;");
645 socket.waitForBytesWritten();
650 qCDebug(mApp,
"Can't establish connection to the server '%s'", qUtf8Printable(serverName));
656 qCDebug(mApp,
"Can't begin to listen for incoming connections on name '%s'",
657 qUtf8Printable(serverName));
658 if (
localServer->serverError() == QAbstractSocket::AddressInUseError)
660 QLocalServer::removeServer(serverName);
663 qCWarning(mApp,
"%s",
664 qUtf8Printable(tr(
"Can't begin to listen for incoming connections on name '%1'").arg(serverName)));
672 const QStringList args = parser.positionalArguments();
673 if (args.count() > 0)
677 qCCritical(mApp,
"%s\n", qPrintable(tr(
"Test mode doesn't support Opening several files.")));
681 for (
int i = 0; i < args.size(); ++i)
718 qCCritical(mApp,
"%s\n", qPrintable(tr(
"Please, provide one input file.")));
734 if (not
qApp->IsTestMode())
750 QLocalSocket *socket =
localServer->nextPendingConnection();
755 socket->waitForReadyRead(1000);
756 QTextStream stream(socket);
757 const QString arg = stream.readAll();
758 if (not arg.isEmpty())
QLocalServer * localServer
virtual bool notify(QObject *receiver, QEvent *event) Q_DECL_OVERRIDE
notify Reimplemented from QApplication::notify().
void NewLocalSocketConnection()
virtual bool IsAppInGUIMode() const Q_DECL_OVERRIDE
IsAppInGUIMode little hack that allow to have access to application state from VAbstractApplication c...
virtual void OpenSettings() Q_DECL_OVERRIDE
MApplication(int &argc, char **argv)
QList< TMainWindow * > MainWindows()
virtual ~MApplication() Q_DECL_OVERRIDE
virtual const VTranslateVars * TrVars() Q_DECL_OVERRIDE
virtual void InitTrVars() Q_DECL_OVERRIDE
virtual bool event(QEvent *e) Q_DECL_OVERRIDE
QPointer< MeasurementDatabaseDialog > dataBase
TMainWindow * MainWindow()
VSeamlyMeSettings * SeamlyMeSettings()
QList< QPointer< TMainWindow > > mainWindows
TMainWindow * NewMainWindow()
void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments)
void SetBaseMSize(int size)
bool LoadFile(const QString &path)
void SetBaseMHeight(int height)
VCommonSettings * settings
settings pointer to settings. Help hide constructor creation settings. Make make code more readable.
void loadTranslations(const QString &locale)
static QString GetDefPathMultisizeMeasurements()
static QString GetDefPathTemplate()
static QString GetDefPathIndividualMeasurements()
static QString GetDefPathLabelTemplate()
The VExceptionBadId class for exception bad id.
The VExceptionConversionError class for exception of conversion error.
The VExceptionEmptyParameter class for exception empty parameter.
The VExceptionObjectError class for exception object error.
virtual QString ErrorMessage() const Q_DECL_OVERRIDE
ErrorMessage return main error message.
virtual QString DetailedInformation() const Q_DECL_OVERRIDE
DetailedInformation return detailed information about error.
The VExceptionWrongId class for exception wrong id.
The VException class parent for all exception. Could be use for abstract exception.
virtual const char * what() const Q_DECL_OVERRIDE
static QStringList WholeListSizes(Unit patternUnit)
static QStringList WholeListHeights(Unit patternUnit)
static bool IsGradationSizeValid(const QString &size)
static bool IsGradationHeightValid(const QString &height)
virtual void Retranslate() Q_DECL_OVERRIDE
Error class of the parser.
Unit StrToUnits(const QString &unit)
const QString LONG_OPTION_NO_HDPI_SCALING
QT_WARNING_PUSH QT_WARNING_POP void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
QString buildCompatibilityString()
#define VER_COMPANYDOMAIN_STR
#define VER_COMPANYNAME_STR
const QString APP_VERSION_STR
#define VER_INTERNALNAME_ME_STR
#define translate(context, source)
static const auto V_EX_USAGE
static const auto V_EX_DATAERR
static const auto V_EX_OK
static const auto V_EX_SOFTWARE