File indexing completed on 2024-04-28 15:14:00

0001 /***************************************************************************
0002     File                 : LabPlot.cpp
0003     Project              : LabPlot
0004     Description          : main function
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2008 by Stefan Gerlach (stefan.gerlach@uni.kn)
0007     Copyright            : (C) 2008-2016 Alexander Semke (alexander.semke@web.de)
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 #include "MainWin.h"
0030 #include "backend/core/AbstractColumn.h"
0031 #include "backend/lib/macros.h"
0032 
0033 #include <KAboutData>
0034 #include <KColorSchemeManager>
0035 #include <kconfigwidgets_version.h>
0036 #include <KCrash>
0037 #include <KLocalizedString>
0038 #include <KMessageBox>
0039 
0040 #include <QApplication>
0041 #include <QCommandLineParser>
0042 #include <QDir>
0043 #include <QFile>
0044 #include <QSplashScreen>
0045 #include <QStandardPaths>
0046 #include <QModelIndex>
0047 #include <QSysInfo>
0048 #include <QSettings>
0049 
0050 #ifdef _WIN32
0051 #include <windows.h>
0052 #endif
0053 
0054 /*
0055  * collect all system info to show in About dialog
0056  */
0057 const QString getSystemInfo() {
0058     // build type
0059 #ifdef NDEBUG
0060     const QString buildType(i18n("Release build"));
0061 #else
0062     const QString buildType(i18n("Debug build"));
0063 #endif
0064     QLocale locale;
0065     const QString numberSystemInfo{ '('
0066             + i18n("Decimal point ") + '\'' + QString(locale.decimalPoint())
0067             + QLatin1String("\', ")
0068             + i18n("Group separator ") + '\'' + QString(locale.groupSeparator())
0069             + QLatin1String("\')")};
0070 
0071     SET_NUMBER_LOCALE
0072     const QString numberLocaleInfo{ ' '
0073             + i18n("Decimal point ") + '\'' + QString(numberLocale.decimalPoint())
0074             + QLatin1String("\', ")
0075             + i18n("Group separator ") + '\'' + QString(numberLocale.groupSeparator())
0076             + QLatin1String("\', ")
0077             + i18n("Exponential ") + '\'' + QString(numberLocale.exponential())
0078             + QLatin1String("\', ")
0079             + i18n("Zero digit ") + '\'' + QString(numberLocale.zeroDigit())
0080             + QLatin1String("\', ")
0081             + i18n("Percent ") + '\'' + QString(numberLocale.percent())
0082             + QLatin1String("\', ")
0083             + i18n("Positive/Negative sign ") + '\'' + QString(numberLocale.positiveSign()) + '\''
0084             + '/' + '\'' + QString(numberLocale.negativeSign()) + '\'' };
0085 
0086     // get language set in 'switch language'
0087     const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
0088     QSettings languageoverride(configPath + QStringLiteral("/klanguageoverridesrc"), QSettings::IniFormat);
0089     languageoverride.beginGroup(QStringLiteral("Language"));
0090     QString usedLocale = languageoverride.value(qAppName(), "").toString(); // something like "en_US"
0091     if (!usedLocale.isEmpty())
0092         locale = QLocale(usedLocale);
0093     QString usedLanguage = QLocale::languageToString(locale.language()) + ',' + QLocale::countryToString(locale.country());
0094 
0095     return buildType + '\n'
0096 #ifndef REPRODUCIBLE_BUILD
0097         + QString("%1, %2").arg(__DATE__).arg(__TIME__) + '\n'
0098 #endif
0099         + i18n("System: ") + QSysInfo::prettyProductName() + '\n'
0100         + i18n("Locale: ") + usedLanguage + ' ' + numberSystemInfo + '\n'
0101         + i18n("Number settings:") + numberLocaleInfo + QLatin1String(" (") + i18n("Updated on restart") + ')' + '\n'
0102         + i18n("Architecture: ") + QSysInfo::buildAbi() + '\n'
0103         + i18n("Kernel: ") + QSysInfo::kernelType() + ' ' + QSysInfo::kernelVersion() + '\n'
0104         + i18n("C++ Compiler: ") + QString(CXX_COMPILER) + '\n'
0105         + i18n("C++ Compiler Flags: ") + QString(CXX_COMPILER_FLAGS);
0106 }
0107 
0108 int main (int argc, char *argv[]) {
0109     QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
0110     QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
0111     QApplication app(argc, argv);
0112     KLocalizedString::setApplicationDomain("labplot2");
0113     KCrash::initialize();
0114 
0115     QString systemInfo{getSystemInfo()};
0116 
0117     KAboutData aboutData( QStringLiteral("labplot2"), QString("LabPlot"),
0118         LVERSION, i18n("LabPlot2 is a KDE-application for interactive graphing and analysis of scientific data."),
0119         KAboutLicense::GPL, i18n("(c) 2007-2020"), systemInfo, QStringLiteral("https://labplot.kde.org"));
0120     aboutData.addAuthor(i18n("Stefan Gerlach"), i18nc("@info:credit", "Developer"), "stefan.gerlach@uni.kn", nullptr);
0121     aboutData.addAuthor(i18n("Alexander Semke"), i18nc("@info:credit", "Developer"), "alexander.semke@web.de", nullptr);
0122     aboutData.addAuthor(i18n("Fábián Kristóf-Szabolcs"), i18nc("@info:credit", "Developer"), "f-kristof@hotmail.com", nullptr);
0123     aboutData.addAuthor(i18n("Martin Marmsoler"), i18nc("@info:credit", "Developer"), "martin.marmsoler@gmail.com", nullptr);
0124     aboutData.addAuthor(i18n("Andreas Kainz"), i18nc("@info:credit", "Icon designer"), "kainz.a@gmail.com", nullptr);
0125     aboutData.addCredit(i18n("Yuri Chornoivan"), i18nc("@info:credit", "Help on many questions about the KDE-infrastructure and translation related topics"), "yurchor@ukr.net", nullptr);
0126     aboutData.addCredit(i18n("Garvit Khatri"), i18nc("@info:credit", "Porting LabPlot2 to KF5 and Integration with Cantor"), "garvitdelhi@gmail.com", nullptr);
0127     aboutData.addCredit(i18n("Christoph Roick"), i18nc("@info:credit", "Support import of ROOT (CERN) TH1 histograms"), "chrisito@gmx.de", nullptr);
0128     aboutData.setOrganizationDomain(QByteArray("kde.org"));
0129     aboutData.setDesktopFileName(QStringLiteral("org.kde.labplot2"));
0130     KAboutData::setApplicationData(aboutData);
0131 
0132     //TODO: add library information (GSL version, etc.) in about dialog
0133 
0134     QCommandLineParser parser;
0135     parser.addHelpOption();
0136     parser.addVersionOption();
0137 
0138     QCommandLineOption nosplashOption("no-splash", i18n("disable splash screen"));
0139     parser.addOption(nosplashOption);
0140 
0141     QCommandLineOption presenterOption("presenter", i18n("start in the presenter mode"));
0142     parser.addOption(presenterOption);
0143 
0144     parser.addPositionalArgument("+[file]", i18n( "open a project file"));
0145 
0146     aboutData.setupCommandLine(&parser);
0147     parser.process(app);
0148     aboutData.processCommandLine(&parser);
0149 
0150     const QStringList args = parser.positionalArguments();
0151     QString filename;
0152     if (args.count() > 0)
0153         filename = args[0];
0154 
0155     if (!filename.isEmpty() ) {
0156         //determine the absolute file path in order to properly save it in MainWin in "Recent Files"
0157         QDir dir;
0158         filename = dir.absoluteFilePath(filename);
0159 
0160         if ( !QFile::exists(filename)) {
0161             if ( KMessageBox::warningContinueCancel( nullptr,
0162                     i18n(R"(Could not open file '%1'. Click 'Continue' to proceed starting or 'Cancel' to exit the application.)", filename),
0163                     i18n("Failed to Open")) == KMessageBox::Cancel) {
0164                 exit(-1);  //"Cancel" clicked -> exit the application
0165             } else {
0166                 filename.clear(); //Wrong file -> clear the file name and continue
0167             }
0168         }
0169     }
0170 
0171     QSplashScreen* splash = nullptr;
0172     if (!parser.isSet(nosplashOption)) {
0173         const QString& file = QStandardPaths::locate(QStandardPaths::DataLocation, "splash.png");
0174         splash = new QSplashScreen(QPixmap(file));
0175         splash->show();
0176     }
0177 
0178     // needed in order to have the signals triggered by SignallingUndoCommand
0179     //TODO: redesign/remove this
0180     qRegisterMetaType<const AbstractAspect*>("const AbstractAspect*");
0181     qRegisterMetaType<const AbstractColumn*>("const AbstractColumn*");
0182 
0183 #ifdef _WIN32
0184     // enable debugging on console
0185     if (AttachConsole(ATTACH_PARENT_PROCESS)) {
0186         freopen("CONOUT$", "w", stdout);
0187         freopen("CONOUT$", "w", stderr);
0188     }
0189 #endif
0190     DEBUG("DEBUG debugging enabled")
0191     QDEBUG("QDEBUG debugging enabled")
0192 
0193 #ifndef NDEBUG
0194     // debugging paths
0195     QStringList appdatapaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
0196     DEBUG("AppDataLocation paths:")
0197     for (const QString &path: appdatapaths)
0198         DEBUG(" " << STDSTRING(path));
0199     DEBUG("Icon theme search paths:")
0200     for (const QString &path: QIcon::themeSearchPaths())
0201         DEBUG(" " << STDSTRING(path));
0202     DEBUG("Library search paths:")
0203     for (const QString &path: QCoreApplication::libraryPaths())
0204         DEBUG(" " << STDSTRING(path));
0205 #endif
0206 
0207     KConfigGroup group = KSharedConfig::openConfig()->group(QLatin1String("Settings_General"));
0208 #if KCONFIGWIDGETS_VERSION >= QT_VERSION_CHECK(5, 67, 0)    // KColorSchemeManager has a system default option
0209     QString schemeName = group.readEntry("ColorScheme");
0210 #else
0211     KConfigGroup generalGlobalsGroup = KSharedConfig::openConfig(QLatin1String("kdeglobals"))->group("General");
0212     QString defaultSchemeName = generalGlobalsGroup.readEntry("ColorScheme", QStringLiteral("Breeze"));
0213     QString schemeName = group.readEntry("ColorScheme", defaultSchemeName);
0214 #endif
0215     KColorSchemeManager manager;
0216     manager.activateScheme(manager.indexForScheme(schemeName));
0217 
0218     MainWin* window = new MainWin(nullptr, filename);
0219     window->show();
0220 
0221     if (splash) {
0222         splash->finish(window);
0223         delete splash;
0224     }
0225 
0226     if (parser.isSet(presenterOption))
0227         window->showPresenter();
0228 
0229     return app.exec();
0230 }