File indexing completed on 2024-04-28 16:30:35

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 /** @file
0007 * This file defines the main of skrooge.
0008 *
0009 * @author Stephane MANKOWSKI / Guillaume DE BURE
0010  */
0011 #include "skgmainpanel.h"
0012 #include "skgdocumentbank.h"
0013 #include "skgtraces.h"
0014 
0015 #include <kaboutdata.h>
0016 #ifdef SKG_DBUS
0017 #include <kdbusservice.h>
0018 #endif
0019 #include <kdelibs4configmigrator.h>
0020 #include <klocalizedstring.h>
0021 
0022 #include <qbitmap.h>
0023 #include <qcommandlineoption.h>
0024 #include <qcommandlineparser.h>
0025 #include <qsplashscreen.h>
0026 #include <QtQuickControls2/qquickstyle.h>
0027 
0028 /**
0029  * To compute the version
0030  */
0031 #define VER1_(x) #x
0032 /**
0033  * To compute the version
0034  */
0035 #define VER_(x) VER1_(x)
0036 /**
0037  * To compute the version
0038  */
0039 #define VER VER_(SKGVERSION)
0040 
0041 void SKGMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
0042 {
0043     Q_UNUSED(context)
0044     switch (type) {
0045     case QtDebugMsg:
0046         SKGTRACEL(1) << "DEBUG: " << msg << SKGENDL;
0047         break;
0048     case QtWarningMsg:
0049         SKGTRACE << "WARNING: " << msg << SKGENDL;
0050         break;
0051     case QtCriticalMsg:
0052         SKGTRACE << "CRITICAL: " << msg << SKGENDL;
0053         break;
0054     case QtFatalMsg:
0055         SKGTRACE << "FATAL: " << msg << SKGENDL;
0056         abort();
0057     default:
0058         SKGTRACE << "INFO: " << msg << SKGENDL;
0059         break;
0060     }
0061 }
0062 
0063 /**
0064  * The main of the application
0065  * @param argc number of arguments
0066  * @param argv arguments
0067  * @return return code
0068  */
0069 int main(int argc, char** argv)
0070 {
0071 #ifdef SKG_WEBENGINE
0072     QApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
0073 #endif
0074 
0075     qInstallMessageHandler(SKGMessageOutput);
0076     if (!SKGServices::getEnvVariable(QStringLiteral("SKGHIGHDPI")).isEmpty()) {
0077         QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
0078         QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
0079     }
0080     QApplication app(argc, argv);
0081     QIcon appIcon = SKGServices::fromTheme(QStringLiteral("skrooge"));
0082     if (!appIcon.isNull()) {
0083         app.setWindowIcon(appIcon);
0084     }
0085 
0086     // Migration kf4 => kf5
0087     Kdelibs4ConfigMigrator migrate(QStringLiteral("skrooge"));
0088     migrate.setConfigFiles(QStringList() << QStringLiteral("skroogerc"));
0089     migrate.migrate();
0090 
0091     // To use CPU instead CPU for QML (needed for printing)
0092     qputenv("QMLSCENE_DEVICE", "softwarecontext");
0093 
0094 #ifdef SKG_WEBENGINE
0095     // DrKonqi
0096     // https://www.dvratil.cz/2018/10/drkonqi-and-qtwebengine/
0097     const auto chromiumFlags = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS");
0098     if (!chromiumFlags.contains("disable-in-process-stack-traces")) {
0099         qputenv("QTWEBENGINE_CHROMIUM_FLAGS", chromiumFlags + " --disable-in-process-stack-traces");
0100     }
0101 #endif
0102     KLocalizedString::setApplicationDomain("skrooge");
0103 
0104     KAboutData about(QStringLiteral("skrooge"),
0105                      i18nc("The name of the application", "Skrooge"),
0106                      QStringLiteral(VER),
0107                      i18nc("The description of the application", "Personal finances management made simple"),
0108                      KAboutLicense::GPL_V3,
0109                      i18nc("Fullname", "(c) 2007-%1 Stephane MANKOWSKI & Guillaume DE BURE", QDate::currentDate().toString(QStringLiteral("yyyy"))),
0110                      QLatin1String(""),
0111                      QStringLiteral("https://skrooge.org"));
0112 
0113     about.addAuthor(i18nc("Fullname", "Stephane MANKOWSKI"), i18nc("A job description", "Architect & Developer"), QStringLiteral("stephane@mankowski.fr"), QLatin1String("")
0114                     , QStringLiteral("miraks")
0115                    );
0116     about.addAuthor(i18nc("Fullname", "Guillaume DE BURE"), i18nc("A job description", "Developer"), QStringLiteral("guillaume.debure@gmail.com"), QLatin1String("")
0117                     , QStringLiteral("willy9")
0118                    );
0119     about.addAuthor(i18nc("Fullname", "Siddharth SHARMA"), i18nc("A job description", "Developer - Google Summer Of Code 2010"), QStringLiteral("siddharth.kde@gmail.com"), QLatin1String("")
0120                     , QStringLiteral("h4xordood")
0121                    );
0122     //about.addAuthor(i18nc("Fullname", "Priscilla DU PREEZ"), i18nc("A job description", "Splash screen photographer"), QLatin1String(""), QLatin1String("")
0123     //                , QStringLiteral("")
0124     //               );
0125     about.setOtherText(i18nc("The description of the application", "The application name is inspired by Charles Dicken's tale <i>A Christmas Carol</i>, where the main character, Ebenezer Scrooge, a grumpy old narrow man, gets visited by three ghosts who change the way he sees the world, in a good way."));
0126     about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
0127     about.setOrganizationDomain("kde.org");
0128     about.setDesktopFileName(QStringLiteral("org.kde.skrooge"));
0129 
0130     about.addCredit(QStringLiteral("vicnet, noidea, rbruce, JesusM, schunka, SylvaiNN, Wolf, Hizoka, neutron68, blep0, BigaAl, steffie, skierpage …"), i18nc("Reason of the about/credit", "Users helping us to improve this application"));
0131 
0132     KAboutData::setApplicationData(about);
0133 
0134     QApplication::setApplicationName(about.componentName());
0135     QApplication::setOrganizationDomain(about.organizationDomain());
0136     QApplication::setApplicationVersion(about.version());
0137 
0138     QCommandLineParser parser;
0139     parser.addPositionalArgument(QStringLiteral("URL"), i18nc("Application argument", "Document to open"));
0140     QCommandLineOption envOption(QStringList() << QStringLiteral("e") << QStringLiteral("env"), i18nc("Application argument", "Display environment variables used by this application."));
0141     parser.addOption(envOption);
0142 
0143     about.setupCommandLine(&parser);
0144     parser.process(app);
0145     about.processCommandLine(&parser);
0146 
0147     if (parser.isSet(envOption)) {
0148         SKGTRACESUITE << parser.helpText() << SKGENDL;
0149         SKGTRACESUITE << i18nc("Help", "Environment variables:") << SKGENDL;
0150         SKGTRACESUITE << i18nc("Help, do not translate x", "  %1: To enable traces. x is the level of traces expected. This enables the debug mode too.", "export SKGTRACE=x") << SKGENDL;
0151         SKGTRACESUITE << i18nc("Help", "  %1: To enable the profiling. This enables the debug mode too.", "export SKGTRACEPERFO=1") << SKGENDL;
0152         SKGTRACESUITE << i18nc("Help do not translate x", "  %1: To dump sql order taking more than x ms.", "export SKGTRACESQL=x") << SKGENDL;
0153         SKGTRACESUITE << i18nc("Help", "  %1: To enable the high DPI mode.", "export SKGHIGHDPI=1") << SKGENDL;
0154         return 0;
0155     }
0156 
0157     // Manage unicity
0158 #ifdef SKG_DBUS
0159     KDBusService service(SKGServices::getEnvVariable(QStringLiteral("SKGNOTUNIQUE")).isEmpty() ? KDBusService::Unique : KDBusService::Multiple);
0160     QObject::connect(&service, &KDBusService::activateRequested, &service, [ = ](const QStringList & arguments, const QString & workingDirectory) {
0161         Q_UNUSED(workingDirectory)
0162         SKGMainPanel::getMainPanel()->processArguments(arguments);
0163     });
0164 #endif
0165 
0166     // Creating a main panel on a bank document
0167     SKGDocumentBank doc;
0168     if (!SKGServices::getEnvVariable(QStringLiteral("SKGTEST")).isEmpty()) {
0169         QTimer::singleShot(5000, Qt::CoarseTimer, &app, &QApplication::quit);
0170     }
0171 
0172     // Build list of arguments
0173     QStringList argument = parser.positionalArguments();
0174 
0175     // Creation splash screen
0176     QSplashScreen* m_splash = nullptr;
0177     KConfigGroup pref = SKGMainPanel::getMainConfigGroup();
0178     if (pref.readEntry("show_splash_screen", true)) {
0179         QString splashPathRelativePath = KAboutData::applicationData().componentName() % "/images/splash.png";
0180         QString splashPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, splashPathRelativePath.toLatin1());
0181         if (!splashPath.isEmpty()) {
0182             QPixmap pix(splashPath);
0183 
0184             m_splash = new QSplashScreen(pix);
0185             if (m_splash != nullptr) {
0186                 m_splash->setMask(pix.createMaskFromColor(Qt::blue));
0187                 m_splash->show();
0188                 m_splash->showMessage(i18nc("Splash screen message", "Loading …"), Qt::AlignLeft, QColor(221, 130, 8));  // krazy:exclude=qmethods
0189             }
0190         } else {
0191             SKGTRACE << "WARNING: Splash screen (" << splashPathRelativePath << ") not found !" << SKGENDL;
0192         }
0193     }
0194 
0195     // First instance
0196     QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
0197     QQuickStyle::setStyle("Breeze");
0198     auto m_widget = new SKGMainPanel(m_splash, &doc);
0199     m_widget->processArguments(argument);
0200     m_widget->setUnifiedTitleAndToolBarOnMac(true);
0201     m_widget->show();
0202 
0203     if (m_splash != nullptr) {
0204         SKGTRACEINFUNC(1)
0205 
0206         m_splash->clearMessage();
0207         m_splash->finish(m_widget);
0208     }
0209 
0210     int rc = QApplication::exec();  // krazy:exclude=crashy
0211 
0212     delete m_splash;
0213 
0214     SKGTraces::dumpProfilingStatistics();
0215     return rc;
0216 }