File indexing completed on 2024-04-28 07:36:44
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ß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 }