File indexing completed on 2024-04-21 03:48:34

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
0005 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
0006 //
0007 
0008 #include <KAboutData>
0009 #include <KConfig>
0010 #include <KConfigGroup>
0011 #include <KCrash>
0012 #include <KLocalizedString>
0013 #include <KSharedConfig>
0014 
0015 #include <QFile>
0016 #include <QCommandLineParser>
0017 #include <QApplication>
0018 #include <QLocale>
0019 #include <QStandardPaths>
0020 #include <QTranslator>
0021 
0022 #include "ControlView.h"
0023 #include "KdeMainWindow.h"
0024 #include "GeoUriParser.h"
0025 #include "MarbleDebug.h"
0026 #include "MapThemeManager.h"
0027 
0028 #include "MarbleTest.h"
0029 
0030 #ifdef STATIC_BUILD
0031  #include <QtPlugin>
0032  Q_IMPORT_PLUGIN(qjpeg)
0033  Q_IMPORT_PLUGIN(qsvg)
0034 #endif
0035 
0036 using namespace Marble;
0037 
0038 
0039 static bool loadTranslation(const QString &localeDirName, QApplication &app)
0040 {
0041     const QString subPath = QLatin1String("locale/") + localeDirName + QLatin1String("/LC_MESSAGES/marble_qt.qm");
0042     const QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath);
0043     if (fullPath.isEmpty()) {
0044         return false;
0045     }
0046 
0047     QTranslator* translator = new QTranslator(&app);
0048     if (!translator->load(fullPath)) {
0049         delete translator;
0050         return false;
0051     }
0052 
0053     app.installTranslator(translator);
0054 
0055     return true;
0056 }
0057 
0058 static void loadLibAndPluginTranslations(QApplication &app)
0059 {
0060     // Quote from ecm_create_qm_loader created code:
0061     // The way Qt translation system handles plural forms makes it necessary to
0062     // have a translation file which contains only plural forms for `en`.
0063     // That's why we load the `en` translation unconditionally, then load the
0064     // translation for the current locale to overload it.
0065     const QString en(QStringLiteral("en"));
0066 
0067     loadTranslation(en, app);
0068 
0069     QLocale locale = QLocale::system();
0070     if (locale.name() != en) {
0071         if (!loadTranslation(locale.name(), app)) {
0072             loadTranslation(locale.bcp47Name(), app);
0073         }
0074     }
0075 }
0076 
0077 
0078 int main ( int argc, char *argv[] )
0079 {
0080     QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
0081 
0082     QApplication app( argc, argv );
0083 
0084     // Load Qt translation system catalog for the plugins and libmarblewidget
0085     loadLibAndPluginTranslations(app);
0086     // Init KF5 translation system
0087     KLocalizedString::setApplicationDomain("marble");
0088 
0089 
0090     KAboutData aboutData( "marble",
0091                           i18n( "Marble Virtual Globe" ),
0092                           ControlView::applicationVersion(),
0093                           i18n( "A World Atlas." ),
0094                           KAboutLicense::LGPL_V2,
0095                           i18n( "(c) 2007-%1", QLatin1String("2016") ),
0096                           QString(),
0097                           "https://marble.kde.org/" );
0098 
0099     // Active Development Team of Marble
0100     aboutData.addAuthor( i18n( "Torsten Rahn" ),
0101                          i18n( "Developer and Original Author" ),
0102                          "rahn@kde.org" );
0103     aboutData.addAuthor( i18n( "Bernhard Beschow" ),
0104                          i18n( "WMS Support, Mobile, Performance" ),
0105                          "bbeschow@cs.tu-berlin.de" );
0106     aboutData.addAuthor( i18n( "Thibaut Gridel" ),
0107                          i18n( "Geodata" ),
0108                          "tgridel@free.fr" );
0109     aboutData.addAuthor( i18n( "Jens-Michael Hoffmann" ),
0110                          i18n( "OpenStreetMap Integration, OSM Namefinder, Download Management" ),
0111                          "jmho@c-xx.com" );
0112     aboutData.addAuthor( i18n( "Florian E&szlig;er" ),
0113                          i18n( "Elevation Profile" ),
0114                          "f.esser@rwth-aachen.de" );
0115     aboutData.addAuthor( i18n( "Wes Hardaker" ),
0116                          i18n( "APRS Plugin" ),
0117                          "marble@hardakers.net" );
0118     aboutData.addAuthor( i18n( "Bastian Holst" ),
0119                          i18n( "Online Services support" ),
0120                          "bastianholst@gmx.de" );
0121     aboutData.addAuthor( i18n( "Guillaume Martres" ),
0122                          i18n( "Satellites" ),
0123                          "smarter@ubuntu.com" );
0124     aboutData.addAuthor( i18n( "Rene Kuettner" ),
0125                          i18n( "Satellites, Eclipses" ),
0126                          "rene@bitkanal.net" );
0127     aboutData.addAuthor( i18n( "Friedrich W. H. Kossebau" ),
0128                          i18n( "Plasma Integration, Bugfixes" ),
0129                          "kossebau@kde.org" );
0130     aboutData.addAuthor( i18n( "Dennis Nienhüser" ),
0131                          i18n( "Routing, Navigation, Mobile" ),
0132                          "nienhueser@kde.org" );
0133     aboutData.addAuthor( i18n( "Niko Sams" ),
0134                          i18n( "Routing, Elevation Profile" ),
0135                          "niko.sams@gmail.com" );
0136     aboutData.addAuthor( i18n( "Patrick Spendrin" ),
0137                          i18n( "Core Developer: KML and Windows support" ),
0138                          "pspendrin@gmail.com" );
0139     aboutData.addAuthor( i18n( "Eckhart Wörner" ),
0140                          i18n( "Bugfixes" ),
0141                          "kde@ewsoftware.de" );
0142     
0143     // Developers:    
0144     
0145     aboutData.addAuthor( i18n( "Inge Wallin" ),
0146                          i18n( "Core Developer and Co-Maintainer" ),
0147                          "inge@lysator.liu.se" );
0148     aboutData.addAuthor( i18n( "Henry de Valence" ),
0149                          i18n( "Core Developer: Marble Runners, World-Clock Plasmoid" ),
0150                          "hdevalence@gmail.com" );
0151     aboutData.addAuthor( i18n( "Pino Toscano" ),
0152                          i18n( "Network plugins" ),
0153                          "pino@kde.org" );
0154     aboutData.addAuthor( i18n( "Harshit Jain" ),
0155                          i18n( "Planet filter" ),
0156                          "sonu.itbhu@googlemail.com" );
0157     aboutData.addAuthor( i18n( "Simon Edwards" ),
0158                          i18n( "Marble Python Bindings" ),
0159                          "simon@simonzone.com" );
0160     aboutData.addAuthor( i18n( "Magnus Valle" ),
0161                          i18n( "Historical Maps" ),
0162                          "" );
0163     aboutData.addAuthor( i18n( "Médéric Boquien" ),
0164                          i18n( "Astronomical Observatories" ),
0165                          "mboquien@free.fr" );
0166 
0167     // ESA Summer of Code in Space
0168     aboutData.addAuthor( i18n( "Rene Kuettner" ),
0169                          i18n( "ESA Summer of Code in Space 2012 Project:"
0170                                 " Visualization of planetary satellites" ),
0171                          "rene@bitkanal.net" );
0172     aboutData.addAuthor( i18n( "Guillaume Martres" ),
0173                          i18n( "ESA Summer of Code in Space 2011 Project:"
0174                                 " Visualization of Satellite Orbits" ),
0175                          "smarter@ubuntu.com" );
0176 
0177     // Google Summer of Code
0178     aboutData.addAuthor( i18n( "Konstantin Oblaukhov" ),
0179                          i18n( "Google Summer of Code 2011 Project:"
0180                                 " OpenStreetMap Vector Rendering" ),
0181                          "oblaukhov.konstantin@gmail.com" );
0182     aboutData.addAuthor( i18n( "Daniel Marth" ),
0183                          i18n( "Google Summer of Code 2011 Project:"
0184                                 " Marble Touch on MeeGo" ),
0185                          "danielmarth@gmx.at" );
0186     aboutData.addAuthor( i18n( "Gaurav Gupta" ),
0187                          i18n( "Google Summer of Code 2010 Project:"
0188                                 " Bookmarks" ),
0189                          "1989.gaurav@gmail.com" );
0190     aboutData.addAuthor( i18n( "Harshit Jain " ),
0191                          i18n( "Google Summer of Code 2010 Project:"
0192                                 " Time Support" ),
0193                          "hjain.itbhu@gmail.com" );
0194     aboutData.addAuthor( i18n( "Siddharth Srivastava" ),
0195                          i18n( "Google Summer of Code 2010 Project:"
0196                                 " Turn-by-turn Navigation" ),
0197                          "akssps011@gmail.com" );
0198     aboutData.addAuthor( i18n( "Andrew Manson" ),
0199                          i18n( "Google Summer of Code 2009 Project:"
0200                                 " OSM Annotation" ),
0201                          "g.real.ate@gmail.com" );
0202     aboutData.addAuthor( i18n( "Bastian Holst" ),
0203                          i18n( "Google Summer of Code 2009 Project:"
0204                                 " Online Services" ),
0205                          "bastianholst@gmx.de" );
0206     aboutData.addAuthor( i18n( "Patrick Spendrin" ),
0207                          i18n( "Google Summer of Code 2008 Project:"
0208                                 " Vector Tiles for Marble" ),
0209                          "pspendrin@gmail.com" );
0210     aboutData.addAuthor( i18n( "Shashank Singh" ),
0211                          i18n( "Google Summer of Code 2008 Project:"
0212                                 " Panoramio / Wikipedia -photo support for Marble" ),
0213                          "shashank.personal@gmail.com" );
0214     aboutData.addAuthor( i18n( "Carlos Licea" ),
0215                          i18n( "Google Summer of Code 2007 Project:"
0216                                 " Equirectangular Projection (\"Flat Map\")" ),
0217                          "carlos.licea@kdemail.net" );
0218     aboutData.addAuthor( i18n( "Andrew Manson" ),
0219                          i18n( "Google Summer of Code 2007 Project:"
0220                                 " GPS Support for Marble" ),
0221                          "g.real.ate@gmail.com" );
0222     aboutData.addAuthor( i18n( "Murad Tagirov" ),
0223                          i18n( "Google Summer of Code 2007 Project:"
0224                                 " KML Support for Marble" ),
0225                          "tmurad@gmail.com" );
0226 
0227     // Developers
0228     aboutData.addAuthor( i18n( "Simon Schmeisser" ),
0229                          i18n( "Development & Patches" ));
0230     aboutData.addAuthor( i18n( "Claudiu Covaci" ),
0231                          i18n( "Development & Patches" ));
0232     aboutData.addAuthor( i18n( "David Roberts" ),
0233                          i18n( "Development & Patches" ));
0234     aboutData.addAuthor( i18n( "Nikolas Zimmermann" ),
0235                          i18n( "Development & Patches" ));
0236     aboutData.addAuthor( i18n( "Jan Becker" ),
0237                          i18n( "Development & Patches" ));
0238     aboutData.addAuthor( i18n( "Stefan Asserhäll" ),
0239                          i18n( "Development & Patches" ));
0240     aboutData.addAuthor( i18n( "Laurent Montel" ),
0241                          i18n( "Development & Patches" ));
0242     aboutData.addAuthor( i18n( "Mayank Madan" ),
0243                          i18n( "Development & Patches" ));
0244     aboutData.addAuthor( i18n( "Prashanth Udupa" ),
0245                          i18n( "Development & Patches" ));
0246     aboutData.addAuthor( i18n( "Anne-Marie Mahfouf" ),
0247                          i18n( "Development & Patches" ));
0248     aboutData.addAuthor( i18n( "Josef Spillner" ),
0249                          i18n( "Development & Patches" ));
0250     aboutData.addAuthor( i18n( "Frerich Raabe" ),
0251                          i18n( "Development & Patches" ));
0252     aboutData.addAuthor( i18n( "Frederik Gladhorn" ),
0253                          i18n( "Development & Patches" ));
0254     aboutData.addAuthor( i18n( "Fredrik Höglund" ),
0255                          i18n( "Development & Patches" ));
0256     aboutData.addAuthor( i18n( "Albert Astals Cid" ),
0257                          i18n( "Development & Patches" ));
0258     aboutData.addAuthor( i18n( "Thomas Zander" ),
0259                          i18n( "Development & Patches" ));
0260     aboutData.addAuthor( i18n( "Joseph Wenninger" ),
0261                          i18n( "Development & Patches" ));
0262     aboutData.addAuthor( i18n( "Kris Thomsen" ),
0263                          i18n( "Development & Patches" ));
0264     aboutData.addAuthor( i18n( "Daniel Molkentin" ),
0265                          i18n( "Development & Patches" ));
0266     aboutData.addAuthor( i18n( "Christophe Leske" ),
0267                          i18n( "Platforms & Distributions" ));
0268     aboutData.addAuthor( i18n( "Sebastian Wiedenroth" ),
0269                          i18n( "Platforms & Distributions" ));
0270     aboutData.addAuthor( i18n( "Tim Sutton" ),
0271                          i18n( "Platforms & Distributions" ));
0272     aboutData.addAuthor( i18n( "Christian Ehrlicher" ),
0273                          i18n( "Platforms & Distributions" ));
0274     aboutData.addAuthor( i18n( "Ralf Habacker" ),
0275                          i18n( "Platforms & Distributions" ));
0276     aboutData.addAuthor( i18n( "Steffen Joeris" ),
0277                          i18n( "Platforms & Distributions" ));
0278     aboutData.addAuthor( i18n( "Marcus Czeslinski" ),
0279                          i18n( "Platforms & Distributions" ));
0280     aboutData.addAuthor( i18n( "Marcus D. Hanwell" ),
0281                          i18n( "Platforms & Distributions" ));
0282     aboutData.addAuthor( i18n( "Chitlesh Goorah" ),
0283                          i18n( "Platforms & Distributions" ));
0284     aboutData.addAuthor( i18n( "Nuno Pinheiro" ),
0285                          i18n( "Artwork" ));
0286     aboutData.addAuthor( i18n( "Torsten Rahn" ),
0287                          i18n( "Artwork" ));
0288 
0289     // Credits
0290     aboutData.addCredit( i18n( "Luis Silva" ),
0291                          i18n( "Various Suggestions & Testing" ));
0292     aboutData.addCredit( i18n( "Stefan Jordan" ),
0293                          i18n( "Various Suggestions & Testing" ));
0294     aboutData.addCredit( i18n( "Robert Scott" ),
0295                          i18n( "Various Suggestions & Testing" ));
0296     aboutData.addCredit( i18n( "Lubos Petrovic" ),
0297                          i18n( "Various Suggestions & Testing" ));
0298     aboutData.addCredit( i18n( "Benoit Sigoure" ),
0299                          i18n( "Various Suggestions & Testing" ));
0300     aboutData.addCredit( i18n( "Martin Konold" ),
0301                          i18n( "Various Suggestions & Testing" ));
0302     aboutData.addCredit( i18n( "Matthias Welwarsky" ),
0303                          i18n( "Various Suggestions & Testing" ));
0304     aboutData.addCredit( i18n( "Rainer Endres" ),
0305                          i18n( "Various Suggestions & Testing" ));
0306     aboutData.addCredit( i18n( "Ralf Gesellensetter" ),
0307                          i18n( "Various Suggestions & Testing" ));
0308     aboutData.addCredit( i18n( "Tim Alder" ),
0309                          i18n( "Various Suggestions & Testing" ));
0310     aboutData.addCredit( i18n( "John Layt" ),
0311                          i18n( "Special thanks for providing an"
0312                                 " important source of inspiration by creating"
0313                                 " Marble's predecessor \"Kartographer\"." ));
0314 
0315     KCrash::setCrashHandler(KCrash::defaultCrashHandler);
0316     KCrash::setDrKonqiEnabled(true);
0317 
0318     KAboutData::setApplicationData(aboutData);
0319     QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("marble")));
0320 
0321     QCommandLineParser parser;
0322     aboutData.setupCommandLine(&parser);
0323 
0324     // Autodetect profiles
0325     MarbleGlobal::Profiles profiles = MarbleGlobal::getInstance()->profiles();
0326 
0327     QCommandLineOption debugOption( "debug-info", i18n( "Enable debug output" ) );
0328     debugOption.setFlags( QCommandLineOption::HiddenFromHelp );
0329     parser.addOption( debugOption );
0330     QCommandLineOption levelOption( "debug-levels", i18n( "Display OSM placemarks according to the level selected" ) );
0331     parser.addOption( levelOption );
0332     QCommandLineOption timeOption( "timedemo", i18n( "Make a time measurement to check performance" ) );
0333     parser.addOption( timeOption );
0334     QCommandLineOption fpsOption( "fps", i18n( "Show frame rate" ) );
0335     parser.addOption( fpsOption );
0336     QCommandLineOption tileOption( "tile-id", i18n( "Show tile IDs" ) );
0337     parser.addOption( tileOption );
0338     QCommandLineOption traceOption( "runtimeTrace", i18n( "Show time spent in each layer" ) );
0339     parser.addOption( traceOption );
0340     QCommandLineOption dataPathOption("marbledatapath", i18n("Use a different directory <directory> which contains map data."), "directory");
0341     parser.addOption( dataPathOption );
0342     QCommandLineOption noSmallScreenOption( "nosmallscreen", i18n( "Do not use the interface optimized for small screens" ) );
0343     QCommandLineOption smallScreenOption( "smallscreen", i18n( "Use the interface optimized for small screens" ) );
0344     parser.addOption( (profiles & MarbleGlobal::SmallScreen) ? noSmallScreenOption : smallScreenOption );
0345     QCommandLineOption noHighResOption( "nohighresolution", i18n( "Do not use the interface optimized for high resolutions" ) );
0346     QCommandLineOption highResOption( "highresolution", i18n( "Use the interface optimized for high resolutions" ) );
0347     parser.addOption( (profiles & MarbleGlobal::HighResolution) ? noHighResOption : highResOption );
0348     QCommandLineOption coordinatesOption("latlon", i18n("Show map at given lat lon <coordinates>"), "coordinates");
0349     parser.addOption( coordinatesOption );
0350     QCommandLineOption geoUriOption("geo-uri", i18n("Show map at given geo <uri>"), "uri");
0351     parser.addOption( geoUriOption );
0352     QCommandLineOption distanceOption("distance", i18n("Set the distance of the observer to the globe (in km)"), "distance");
0353     parser.addOption( distanceOption );
0354     QCommandLineOption mapIdOption("map", i18n("Use map <id> (e.g. \"earth/openstreetmap/openstreetmap.dgml\")"), "id");
0355     parser.addOption( mapIdOption );
0356     parser.addPositionalArgument("file", i18n( "One or more placemark files to be opened") );
0357 
0358     parser.process( app );
0359     aboutData.processCommandLine(&parser);
0360 
0361     // use ecm_create_qm_loader(marblewidget_SRCS marble_qt)
0362     // in the library src/lib/marble/CMakeList.txt to load the second catalog
0363 
0364     if ( parser.isSet( debugOption ) ) {
0365         qCWarning(MARBLE_DEFAULT) << "The '--debug-info' option is no longer supported, use the Qt logging settings.";
0366     }
0367 
0368     if ( parser.isSet( smallScreenOption ) ) {
0369         profiles |= MarbleGlobal::SmallScreen;
0370     }
0371     else {
0372         profiles &= ~MarbleGlobal::SmallScreen;
0373     }
0374 
0375     if ( parser.isSet( highResOption ) ) {
0376         profiles |= MarbleGlobal::HighResolution;
0377     }
0378     else {
0379         profiles &= ~MarbleGlobal::HighResolution;
0380     }
0381 
0382     MarbleGlobal::getInstance()->setProfiles( profiles );
0383 
0384     QString marbleDataPath = parser.value( dataPathOption );
0385     MainWindow *window = new MainWindow(marbleDataPath);
0386     window->show();
0387 
0388     if ( parser.isSet( timeOption ) ) {
0389         window->resize(900, 640);
0390         MarbleTest test(window->marbleWidget());
0391         test.timeDemo();
0392         return 0;
0393     }
0394 
0395     if ( parser.isSet( fpsOption ) ) {
0396         window->marbleControl()->marbleWidget()->setShowFrameRate(true);
0397     }
0398 
0399     if (parser.isSet(levelOption)) {
0400         window->marbleWidget()->setDebugLevelTags(true);
0401     }
0402 
0403     if ( parser.isSet( tileOption ) ) {
0404         window->marbleControl()->marbleWidget()->setShowTileId(true);
0405     }
0406 
0407     const QString map = parser.value( mapIdOption );
0408     if ( !map.isEmpty() ) {
0409         window->marbleWidget()->setMapThemeId(map);
0410     }
0411 
0412     const QString coordinatesString = parser.value( coordinatesOption );
0413     if ( !coordinatesString.isEmpty() ) {
0414         bool success = false;
0415         const GeoDataCoordinates coordinates = GeoDataCoordinates::fromString(coordinatesString, success);
0416         if ( success ) {
0417             const qreal longitude = coordinates.longitude(GeoDataCoordinates::Degree);
0418             const qreal latitude = coordinates.latitude(GeoDataCoordinates::Degree);
0419             window->marbleWidget()->centerOn(longitude, latitude);
0420         }
0421     }
0422 
0423     const QString geoUriString = parser.value( geoUriOption );
0424     if ( !geoUriString.isEmpty() ) {
0425         window->marbleControl()->openGeoUri(geoUriString);
0426     }
0427 
0428     const QString distance = parser.value( distanceOption );
0429     if ( !distance.isEmpty() ) {
0430         bool success = false;
0431         const qreal distanceValue = distance.toDouble(&success);
0432         if ( success )
0433             window->marbleWidget()->setDistance(distanceValue);
0434     }
0435 
0436     // Read the files that are given on the command line.
0437     for( const QString &file: parser.positionalArguments() ) {
0438         // FIXME: Use openUrl( args->url(i) ) instead?
0439         if ( QFile::exists( file ) ) {
0440             window->marbleControl()->addGeoDataFile(file);
0441         }
0442     }
0443 
0444     return app.exec();
0445 }