File indexing completed on 2024-10-13 03:33:01
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2006-2010 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org> 0005 // SPDX-FileCopyrightText: 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0006 // SPDX-FileCopyrightText: 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com> 0007 // SPDX-FileCopyrightText: 2012 Mohammed Nafees <nafees.technocool@gmail.com> 0008 // 0009 0010 #include "QtMainWindow.h" 0011 0012 #include "MarbleDebug.h" 0013 #include <QList> 0014 #include <QSettings> 0015 #include <QUrl> 0016 #include <QCloseEvent> 0017 #include <QVariant> 0018 #include <QVector> 0019 #include <QAction> 0020 #include <QLabel> 0021 #include <QWhatsThis> 0022 #include <QApplication> 0023 #include <QIcon> 0024 #include <QMenuBar> 0025 #include <QStatusBar> 0026 #include <QProgressBar> 0027 #include <QToolBar> 0028 #include <QDesktopServices> 0029 #include <QFileDialog> 0030 #include <QMessageBox> 0031 #include <QPrintDialog> 0032 #include <QPrinter> 0033 #include <QDialogButtonBox> 0034 #include <QClipboard> 0035 #include <QNetworkProxy> 0036 0037 #include "EditBookmarkDialog.h" 0038 #include "BookmarkManagerDialog.h" 0039 #include "CurrentLocationWidget.h" 0040 #include "MapViewWidget.h" 0041 #include "MarbleDirs.h" 0042 #include "MarbleAboutDialog.h" 0043 #include "QtMarbleConfigDialog.h" 0044 #include "SunControlWidget.h" 0045 #include "TimeControlWidget.h" 0046 #include "MarbleLocale.h" 0047 #include "DownloadRegionDialog.h" 0048 #include "ViewportParams.h" 0049 #include "AbstractFloatItem.h" 0050 #include "MarbleModel.h" 0051 #include "MarbleClock.h" 0052 #include "FileManager.h" 0053 #include "HttpDownloadManager.h" 0054 #include "BookmarkManager.h" 0055 #include "NewBookmarkFolderDialog.h" 0056 #include "GeoSceneDocument.h" 0057 #include "GeoSceneHead.h" 0058 #include "GeoSceneMap.h" 0059 #include "GeoDataLookAt.h" 0060 #include "GeoDataCoordinates.h" 0061 #include "GeoDataLatLonAltBox.h" 0062 #include "GeoDataDocument.h" 0063 #include "GeoDataFolder.h" 0064 #include "GeoDataPlacemark.h" 0065 #include "GeoUriParser.h" 0066 #include "routing/RoutingManager.h" 0067 #include "routing/RoutingProfilesModel.h" 0068 #include "routing/RoutingWidget.h" 0069 #include "routing/RouteRequest.h" 0070 #include "ParseRunnerPlugin.h" 0071 #include "PositionTracking.h" 0072 #include "PositionProviderPlugin.h" 0073 #include "PluginManager.h" 0074 #include "MarbleColors.h" 0075 #include "MapThemeDownloadDialog.h" 0076 #include "MapWizard.h" 0077 #include "MarbleWidgetInputHandler.h" 0078 #include "Planet.h" 0079 #include "cloudsync/CloudSyncManager.h" 0080 #include "cloudsync/BookmarkSyncManager.h" 0081 #include "cloudsync/RouteSyncManager.h" 0082 #include "MovieCaptureDialog.h" 0083 #include "DataMigration.h" 0084 #include "TileCoordsPyramid.h" 0085 0086 using namespace Marble; 0087 /* TRANSLATOR Marble::MainWindow */ 0088 0089 MainWindow::MainWindow(const QString& marbleDataPath, const QVariantMap& cmdLineSettings, QWidget *parent) : 0090 QMainWindow(parent), 0091 m_controlView( nullptr ), 0092 m_savedSize( QSize(-1, -1) ), 0093 m_sunControlDialog( nullptr ), 0094 m_timeControlDialog( nullptr ), 0095 m_configDialog( nullptr ), 0096 m_downloadRegionDialog( nullptr ), 0097 m_movieCaptureDialog( nullptr ), 0098 0099 // File Menu 0100 m_fileMenu( nullptr ), 0101 m_viewMenu( nullptr ), 0102 m_helpMenu( nullptr ), 0103 m_settingsMenu( nullptr ), 0104 m_panelMenu( nullptr ), 0105 m_viewSizeMenu( nullptr ), 0106 m_infoBoxesMenu( nullptr ), 0107 m_onlineServicesMenu( nullptr ), 0108 m_bookmarkMenu( nullptr ), 0109 m_openAction( nullptr ), 0110 m_exportMapAction( nullptr ), 0111 m_downloadAction( nullptr ), 0112 m_downloadRegionAction( nullptr ), 0113 m_printPreviewAction( nullptr ), 0114 m_printAction( nullptr ), 0115 m_workOfflineAction( nullptr ), 0116 m_quitAction( nullptr ), 0117 m_mapWizardAction( nullptr ), 0118 0119 // Edit Menu 0120 m_copyMapAction( nullptr ), 0121 m_copyCoordinatesAction( nullptr ), 0122 m_osmEditAction( nullptr ), 0123 m_recordMovieAction( nullptr ), 0124 m_stopRecordingAction( nullptr ), 0125 0126 // View Menu 0127 m_showCloudsAction( nullptr ),\ 0128 m_controlSunAction( nullptr ), 0129 m_controlTimeAction( nullptr ), 0130 m_reloadAction( nullptr ), 0131 0132 // Settings Menu 0133 m_fullScreenAction( nullptr ), 0134 m_statusBarAction( nullptr ), 0135 m_configDialogAction( nullptr ), 0136 m_viewSizeActsGroup( nullptr ), 0137 0138 // Help Menu 0139 m_whatsThisAction( nullptr ), 0140 m_aboutMarbleAction( nullptr ), 0141 m_aboutQtAction( nullptr ), 0142 m_lockFloatItemsAction( nullptr ), 0143 m_handbookAction( nullptr ), 0144 m_forumAction( nullptr ), 0145 0146 // Status Bar 0147 m_positionLabel( nullptr ), 0148 m_distanceLabel( nullptr ), 0149 m_zoomLabel( nullptr ), 0150 m_clockLabel( nullptr ), 0151 m_downloadProgressBar( nullptr ), 0152 m_toggleTileLevelAction( nullptr ), 0153 m_angleDisplayUnitActionGroup( nullptr ), 0154 m_dmsDegreeAction( nullptr ), 0155 m_decimalDegreeAction( nullptr ), 0156 m_utmAction( nullptr ), 0157 0158 //Bookmark Menu 0159 m_addBookmarkAction( nullptr ), 0160 m_setHomeAction( nullptr ), 0161 m_toggleBookmarkDisplayAction( nullptr ), 0162 m_manageBookmarksAction( nullptr ) 0163 { 0164 setUpdatesEnabled( false ); 0165 0166 QString selectedPath = marbleDataPath.isEmpty() ? readMarbleDataPath() : marbleDataPath; 0167 if ( !selectedPath.isEmpty() ) 0168 MarbleDirs::setMarbleDataPath( selectedPath ); 0169 0170 #ifdef Q_OS_WIN 0171 QPointer<DataMigration> migration = new DataMigration(this); 0172 migration->exec(); 0173 #endif 0174 0175 m_controlView = new ControlView( this ); 0176 0177 setWindowIcon(QIcon(QStringLiteral(":/icons/marble.png"))); 0178 setCentralWidget( m_controlView ); 0179 0180 // Initializing config dialog 0181 m_configDialog = new QtMarbleConfigDialog( m_controlView->marbleWidget(), 0182 m_controlView->cloudSyncManager(), 0183 this ); 0184 connect( m_configDialog, SIGNAL(settingsChanged()), 0185 this, SLOT(updateSettings()) ); 0186 connect( m_configDialog, SIGNAL(clearVolatileCacheClicked()), 0187 m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) ); 0188 connect( m_configDialog, SIGNAL(clearPersistentCacheClicked()), 0189 m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) ); 0190 connect( m_configDialog, SIGNAL(syncNowClicked()), 0191 m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) ); 0192 connect(m_configDialog, SIGNAL(syncNowClicked()), 0193 m_configDialog, SLOT(disableSyncNow())); 0194 0195 connect(m_controlView->marbleModel()->fileManager(), &FileManager::fileError, this, 0196 [this](const QString& path, const QString& error) { 0197 QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses 0198 tr("Sorry, unable to open '%1':\n'%2'").arg(path).arg(error), 0199 QMessageBox::Ok); 0200 }); 0201 0202 // Load bookmark file. If it does not exist, a default one will be used. 0203 m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" ); 0204 0205 createActions(); 0206 QList<QAction*> const panelActions = m_controlView->setupDockWidgets( this ); 0207 createMenus( panelActions ); 0208 createStatusBar(); 0209 0210 connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)), 0211 this, SLOT(updateMapEditButtonVisibility(QString)) ); 0212 connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)), 0213 this, SLOT(updateWindowTitle())); 0214 connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)), 0215 this, SLOT(updateCenterFromTheme())); 0216 0217 connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) ); 0218 connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) ); 0219 0220 updateWindowTitle(); 0221 setUpdatesEnabled( true ); 0222 0223 m_position = QCoreApplication::translate( "Marble", NOT_AVAILABLE ); 0224 m_distance = marbleWidget()->distanceString(); 0225 m_zoom = QString::number( marbleWidget()->tileZoomLevel() ); 0226 0227 m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat ); 0228 QMetaObject::invokeMethod(this, 0229 "initObject", Qt::QueuedConnection, 0230 Q_ARG(QVariantMap, cmdLineSettings)); 0231 } 0232 0233 MainWindow::~MainWindow() 0234 { 0235 delete m_movieCaptureDialog; 0236 } 0237 0238 void MainWindow::addGeoDataFile( const QString &fileName ) 0239 { 0240 QFileInfo file( fileName ); 0241 0242 if ( !file.exists() ) 0243 return; 0244 0245 // delay file loading to initObject(), such that restoring view from previous session in readSettings() 0246 // doesn't interfere with focusing on these files 0247 m_commandlineFilePaths << file.absoluteFilePath(); 0248 } 0249 0250 void MainWindow::initObject(const QVariantMap& cmdLineSettings) 0251 { 0252 QCoreApplication::processEvents (); 0253 setupStatusBar(); 0254 readSettings(cmdLineSettings); 0255 0256 for ( const QString &path: m_commandlineFilePaths ) { 0257 m_controlView->marbleModel()->addGeoDataFile( path ); 0258 } 0259 0260 if ( cmdLineSettings.contains( "tour" ) ) { 0261 QString const tour = cmdLineSettings.value( "tour" ).toString(); 0262 m_controlView->openTour( tour ); 0263 } 0264 m_commandlineFilePaths.clear(); 0265 } 0266 0267 void MainWindow::createActions() 0268 { 0269 m_openAction = new QAction(QIcon(QStringLiteral(":/icons/document-open.png")), tr("&Open..."), this); 0270 m_openAction->setShortcut( QKeySequence( "Ctrl+O" ) ); 0271 m_openAction->setStatusTip( tr( "Open a file for viewing on Marble")); 0272 connect( m_openAction, SIGNAL(triggered()), 0273 this, SLOT(openFile()) ); 0274 0275 m_downloadAction = new QAction(QIcon(QStringLiteral(":/icons/get-hot-new-stuff.png")), tr("&Download Maps..."), this); 0276 connect(m_downloadAction, SIGNAL(triggered()), this, SLOT(openMapDialog())); 0277 0278 m_exportMapAction = new QAction(QIcon(QStringLiteral(":/icons/document-save-as.png")), tr("&Export Map..."), this); 0279 m_exportMapAction->setShortcut(QKeySequence("Ctrl+S")); 0280 m_exportMapAction->setStatusTip(tr("Save a screenshot of the map")); 0281 connect(m_exportMapAction, SIGNAL(triggered()), this, SLOT(exportMapScreenShot())); 0282 0283 // Action: Download Region 0284 m_downloadRegionAction = new QAction( tr( "Download &Region..." ), this ); 0285 m_downloadRegionAction->setStatusTip( tr( "Download a map region in different zoom levels for offline usage" ) ); 0286 connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()) ); 0287 0288 m_printAction = new QAction(QIcon(QStringLiteral(":/icons/document-print.png")), tr("&Print..."), this); 0289 m_printAction->setShortcut(tr("Ctrl+P")); 0290 m_printAction->setStatusTip(tr("Print a screenshot of the map")); 0291 connect(m_printAction, SIGNAL(triggered()), this, SLOT(printMapScreenShot())); 0292 0293 m_printPreviewAction = new QAction(QIcon(QStringLiteral(":/icons/document-print-preview.png")), tr("Print Previe&w ..."), this); 0294 m_printPreviewAction->setStatusTip(tr("Print a screenshot of the map")); 0295 connect(m_printPreviewAction, SIGNAL(triggered()), m_controlView, SLOT(printPreview())); 0296 0297 m_quitAction = new QAction(QIcon(QStringLiteral(":/icons/application-exit.png")), tr("&Quit"), this); 0298 m_quitAction->setShortcut(tr("Ctrl+Q")); 0299 m_quitAction->setStatusTip(tr("Quit the Application")); 0300 connect(m_quitAction, SIGNAL(triggered()), this, SLOT(close())); 0301 0302 m_copyMapAction = new QAction(QIcon(QStringLiteral(":/icons/edit-copy.png")), tr("&Copy Map"), this); 0303 m_copyMapAction->setShortcut(QKeySequence("Ctrl+C")); 0304 m_copyMapAction->setStatusTip(tr("Copy a screenshot of the map")); 0305 connect(m_copyMapAction, SIGNAL(triggered()), this, SLOT(copyMap())); 0306 0307 m_osmEditAction = new QAction(QIcon(QStringLiteral(":/icons/edit-map.png")), tr("&Edit Map..."), this ); 0308 m_osmEditAction->setShortcut(QKeySequence( "Ctrl+E" ) ); 0309 m_osmEditAction->setStatusTip(tr( "Edit the current map region in an external editor" ) ); 0310 updateMapEditButtonVisibility( m_controlView->marbleWidget()->mapThemeId() ); 0311 connect( m_osmEditAction, SIGNAL(triggered()), m_controlView, SLOT(launchExternalMapEditor()) ); 0312 0313 m_recordMovieAction = new QAction(tr("&Record Movie"), this); 0314 m_recordMovieAction->setStatusTip(tr("Records a movie of the globe")); 0315 m_recordMovieAction->setShortcut(QKeySequence("Ctrl+Shift+R")); 0316 m_recordMovieAction->setIcon(QIcon(QStringLiteral(":/icons/animator.png"))); 0317 connect(m_recordMovieAction, SIGNAL(triggered()), 0318 this, SLOT(showMovieCaptureDialog())); 0319 0320 m_stopRecordingAction = new QAction( tr("&Stop Recording"), this ); 0321 m_stopRecordingAction->setStatusTip( tr("Stop recording a movie of the globe") ); 0322 m_stopRecordingAction->setShortcut(QKeySequence( "Ctrl+Shift+S" )); 0323 m_stopRecordingAction->setEnabled( false ); 0324 connect( m_stopRecordingAction, SIGNAL(triggered()), 0325 this, SLOT(stopRecording()) ); 0326 0327 m_configDialogAction = new QAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure Marble"), this); 0328 m_configDialogAction->setStatusTip(tr("Show the configuration dialog")); 0329 connect(m_configDialogAction, SIGNAL(triggered()), this, SLOT(editSettings())); 0330 0331 m_copyCoordinatesAction = new QAction(QIcon(QStringLiteral(":/icons/copy-coordinates.png")), tr("C&opy Coordinates"), this); 0332 m_copyCoordinatesAction->setStatusTip(tr("Copy the center coordinates as text")); 0333 connect(m_copyCoordinatesAction, SIGNAL(triggered()), this, SLOT(copyCoordinates())); 0334 0335 m_fullScreenAction = new QAction(QIcon(QStringLiteral(":/icons/view-fullscreen.png")), tr("&Full Screen Mode"), this); 0336 m_fullScreenAction->setShortcut(QKeySequence("Ctrl+Shift+F")); 0337 m_fullScreenAction->setCheckable( true ); 0338 m_fullScreenAction->setStatusTip(tr("Full Screen Mode")); 0339 connect(m_fullScreenAction, SIGNAL(triggered(bool)), this, SLOT(showFullScreen(bool))); 0340 0341 m_statusBarAction = new QAction( tr("&Show Status Bar"), this); 0342 m_statusBarAction->setCheckable( true ); 0343 m_statusBarAction->setStatusTip(tr("Show Status Bar")); 0344 connect(m_statusBarAction, SIGNAL(triggered(bool)), this, SLOT(showStatusBar(bool))); 0345 0346 0347 m_lockFloatItemsAction = new QAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("Lock Position"), this); 0348 m_lockFloatItemsAction->setCheckable( true ); 0349 m_lockFloatItemsAction->setStatusTip(tr("Lock Position of Floating Items")); 0350 connect(m_lockFloatItemsAction, SIGNAL(triggered(bool)), this, SLOT(lockPosition(bool))); 0351 0352 m_showCloudsAction = new QAction(QIcon(QStringLiteral(":/icons/clouds.png")), tr("&Clouds"), this); 0353 m_showCloudsAction->setCheckable( true ); 0354 m_showCloudsAction->setStatusTip(tr("Show Real Time Cloud Cover")); 0355 connect(m_showCloudsAction, SIGNAL(triggered(bool)), this, SLOT(showClouds(bool))); 0356 0357 m_workOfflineAction = new QAction(QIcon(QStringLiteral(":/icons/user-offline.png")), tr("Work Off&line"), this); 0358 m_workOfflineAction->setCheckable( true ); 0359 connect(m_workOfflineAction, SIGNAL(triggered(bool)), this, SLOT(workOffline(bool))); 0360 0361 m_controlTimeAction = new QAction(QIcon(QStringLiteral(":/icons/clock.png")), tr("&Time Control..."), this ); 0362 m_controlTimeAction->setStatusTip( tr( "Configure Time Control " ) ); 0363 connect( m_controlTimeAction, SIGNAL(triggered()), this, SLOT(controlTime()) ); 0364 0365 m_controlSunAction = new QAction( tr( "S&un Control..." ), this ); 0366 m_controlSunAction->setStatusTip( tr( "Configure Sun Control" ) ); 0367 connect( m_controlSunAction, SIGNAL(triggered()), this, SLOT(controlSun()) ); 0368 0369 m_reloadAction = new QAction(QIcon(QStringLiteral(":/icons/view-refresh.png")), tr("&Redisplay"), this); 0370 m_reloadAction->setShortcut(QKeySequence("F5")); 0371 m_reloadAction->setStatusTip(tr("Reload Current Map")); 0372 connect(m_reloadAction, SIGNAL(triggered()), this, SLOT(reload())); 0373 0374 m_handbookAction = new QAction(QIcon(QStringLiteral(":/icons/help-contents.png")), tr("Marble Virtual Globe &Handbook"), this); 0375 m_handbookAction->setShortcut(QKeySequence("F1")); 0376 m_handbookAction->setStatusTip(tr("Show the Handbook for Marble Virtual Globe")); 0377 connect(m_handbookAction, SIGNAL(triggered()), this, SLOT(handbook())); 0378 0379 m_whatsThisAction = new QAction(QIcon(QStringLiteral(":/icons/help-whatsthis.png")), tr("What's &This"), this); 0380 m_whatsThisAction->setShortcut(QKeySequence("Shift+F1")); 0381 m_whatsThisAction->setStatusTip(tr("Show a detailed explanation of the action.")); 0382 connect(m_whatsThisAction, SIGNAL(triggered()), this, SLOT(enterWhatsThis())); 0383 0384 m_forumAction = new QAction( tr("&Community Forum"), this); 0385 m_forumAction->setStatusTip(tr("Visit Marble's Community Forum")); 0386 connect(m_forumAction, SIGNAL(triggered()), this, SLOT(openForum())); 0387 0388 m_aboutMarbleAction = new QAction(QIcon(QStringLiteral(":/icons/marble.png")), tr("&About Marble Virtual Globe"), this); 0389 m_aboutMarbleAction->setStatusTip(tr("Show the application's About Box")); 0390 connect(m_aboutMarbleAction, SIGNAL(triggered()), this, SLOT(aboutMarble())); 0391 0392 m_aboutQtAction = new QAction(tr("About &Qt"), this); 0393 m_aboutQtAction->setStatusTip(tr("Show the Qt library's About box")); 0394 connect(m_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); 0395 0396 //Bookmark Actions 0397 m_addBookmarkAction = new QAction(QIcon(QStringLiteral(":/icons/bookmark-new.png")), tr("Add &Bookmark..."), this); 0398 m_addBookmarkAction->setShortcut(QKeySequence("Ctrl+B")); 0399 m_addBookmarkAction->setStatusTip(tr("Add Bookmark")); 0400 connect( m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(openEditBookmarkDialog()) ); 0401 0402 m_setHomeAction = new QAction(QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Set Home Location"), this); 0403 m_setHomeAction->setStatusTip( tr( "&Set Home Location" ) ); 0404 connect( m_setHomeAction, SIGNAL(triggered()), this, SLOT(setHome()) ); 0405 0406 m_toggleBookmarkDisplayAction = new QAction(tr( "Show &Bookmarks" ), this); 0407 m_toggleBookmarkDisplayAction->setStatusTip( tr( "Toggle display of Bookmarks" ) ); 0408 m_toggleBookmarkDisplayAction->setCheckable( true ); 0409 connect( m_toggleBookmarkDisplayAction, SIGNAL(triggered(bool)), this, SLOT(showBookmarks(bool)) ); 0410 0411 m_manageBookmarksAction = new QAction(QIcon(QStringLiteral(":/icons/bookmarks-organize.png")), tr("&Manage Bookmarks..."), this); 0412 m_manageBookmarksAction->setStatusTip( tr( "Manage Bookmarks" ) ); 0413 connect( m_manageBookmarksAction, SIGNAL(triggered()), this, SLOT(manageBookmarks()) ); 0414 0415 // Map Wizard action 0416 m_mapWizardAction = new QAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), this); 0417 m_mapWizardAction->setStatusTip( tr( "A wizard guides you through the creation of your own map theme." ) ); 0418 connect( m_mapWizardAction, SIGNAL(triggered()), SLOT(showMapWizard()) ); 0419 0420 // Statusbar Actions 0421 m_toggleTileLevelAction = new QAction( tr( "Show Tile Zoom Level" ), statusBar() ); 0422 m_toggleTileLevelAction->setCheckable( true ); 0423 m_toggleTileLevelAction->setChecked( false ); 0424 connect( m_toggleTileLevelAction, SIGNAL(triggered(bool)), 0425 this, SLOT(showZoomLevel(bool)) ); 0426 0427 m_angleDisplayUnitActionGroup = new QActionGroup( statusBar() ); 0428 0429 m_dmsDegreeAction = new QAction( tr( "Degree (DMS)" ), statusBar() ); 0430 m_dmsDegreeAction->setCheckable( true ); 0431 m_dmsDegreeAction->setData( (int)DMSDegree ); 0432 m_angleDisplayUnitActionGroup->addAction(m_dmsDegreeAction); 0433 0434 m_decimalDegreeAction = new QAction( tr( "Degree (Decimal)" ), statusBar() ); 0435 m_decimalDegreeAction->setCheckable( true ); 0436 m_decimalDegreeAction->setData( (int)DecimalDegree ); 0437 m_angleDisplayUnitActionGroup->addAction(m_decimalDegreeAction); 0438 0439 m_utmAction = new QAction( tr( "Universal Transverse Mercator (UTM)" ), statusBar() ); 0440 m_utmAction->setCheckable( true ); 0441 m_utmAction->setData( (int)UTM ); 0442 m_angleDisplayUnitActionGroup->addAction(m_utmAction); 0443 0444 connect( m_angleDisplayUnitActionGroup, SIGNAL(triggered(QAction*)), 0445 this, SLOT(changeAngleDisplayUnit(QAction*)) ); 0446 0447 // View size actions 0448 m_viewSizeActsGroup = ControlView::createViewSizeActionGroup( this ); 0449 connect( m_viewSizeActsGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeViewSize(QAction*)) ); 0450 } 0451 0452 void MainWindow::createMenus( const QList<QAction*> &panelActions ) 0453 { 0454 m_fileMenu = menuBar()->addMenu(tr("&File")); 0455 m_fileMenu->addAction(m_openAction); 0456 m_fileMenu->addAction(m_downloadAction); 0457 m_fileMenu->addAction( m_downloadRegionAction ); 0458 m_fileMenu->addAction( m_mapWizardAction ); 0459 m_fileMenu->addAction(m_exportMapAction); 0460 m_fileMenu->addSeparator(); 0461 m_fileMenu->addAction(m_printAction); 0462 m_fileMenu->addAction(m_printPreviewAction); 0463 m_fileMenu->addSeparator(); 0464 m_fileMenu->addAction(m_workOfflineAction); 0465 m_fileMenu->addAction(m_quitAction); 0466 0467 m_fileMenu = menuBar()->addMenu(tr("&Edit")); 0468 m_fileMenu->addAction(m_copyMapAction); 0469 m_fileMenu->addAction(m_copyCoordinatesAction); 0470 m_fileMenu->addAction( m_osmEditAction ); 0471 m_fileMenu->addSeparator(); 0472 m_fileMenu->addAction(m_recordMovieAction); 0473 m_fileMenu->addAction(m_stopRecordingAction); 0474 0475 m_viewMenu = menuBar()->addMenu(tr("&View")); 0476 m_infoBoxesMenu = new QMenu(tr("&Info Boxes"), this); 0477 m_onlineServicesMenu = new QMenu(tr("&Online Services"), this); 0478 createPluginsMenus(); 0479 0480 m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks")); 0481 createBookmarkMenu(); 0482 connect( m_bookmarkMenu, SIGNAL(aboutToShow()), this, SLOT(createBookmarkMenu()) ); 0483 0484 m_panelMenu = new QMenu(tr("&Panels"), this); 0485 for( QAction* action: panelActions ) { 0486 m_panelMenu->addAction( action ); 0487 } 0488 0489 m_viewSizeMenu = new QMenu(tr("&View Size"), this); 0490 m_viewSizeMenu->addActions( m_viewSizeActsGroup->actions() ); 0491 0492 m_settingsMenu = menuBar()->addMenu(tr("&Settings")); 0493 m_settingsMenu->addMenu( m_panelMenu ); 0494 m_settingsMenu->addAction(m_statusBarAction); 0495 m_settingsMenu->addSeparator(); 0496 m_settingsMenu->addMenu( m_viewSizeMenu ); 0497 m_settingsMenu->addAction(m_fullScreenAction); 0498 m_settingsMenu->addSeparator(); 0499 m_settingsMenu->addAction(m_configDialogAction); 0500 0501 m_helpMenu = menuBar()->addMenu(tr("&Help")); 0502 m_helpMenu->addAction(m_handbookAction); 0503 m_helpMenu->addAction(m_forumAction); 0504 m_helpMenu->addSeparator(); 0505 m_helpMenu->addAction(m_whatsThisAction); 0506 m_helpMenu->addSeparator(); 0507 m_helpMenu->addAction(m_aboutMarbleAction); 0508 m_helpMenu->addAction(m_aboutQtAction); 0509 0510 // FIXME: Discuss if this is the best place to put this 0511 QList<RenderPlugin *> pluginList = m_controlView->marbleWidget()->renderPlugins(); 0512 QList<RenderPlugin *>::const_iterator it = pluginList.constBegin(); 0513 QList<RenderPlugin *>::const_iterator const listEnd = pluginList.constEnd(); 0514 for (; it != listEnd; ++it ) { 0515 connect( (*it), SIGNAL(actionGroupsChanged()), 0516 this, SLOT(createPluginMenus()) ); 0517 } 0518 } 0519 0520 void MainWindow::createPluginsMenus() 0521 { 0522 m_onlineServicesMenu->clear(); 0523 m_infoBoxesMenu->clear(); 0524 m_viewMenu->clear(); 0525 0526 m_viewMenu->addAction(m_reloadAction); 0527 m_viewMenu->addSeparator(); 0528 0529 // Do not create too many menu entries on a MID 0530 // FIXME: Set up another way of switching the plugins on and off. 0531 if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { 0532 return; 0533 } 0534 0535 m_infoBoxesMenu->addAction(m_lockFloatItemsAction); 0536 m_infoBoxesMenu->addSeparator(); 0537 QList<QAction*> themeActions; 0538 0539 QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins(); 0540 QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin(); 0541 QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd(); 0542 for (; i != end; ++i ) { 0543 switch( (*i)->renderType() ) { 0544 case RenderPlugin::TopLevelRenderType: 0545 m_viewMenu->addAction( (*i)->action() ); 0546 break; 0547 case RenderPlugin::PanelRenderType: 0548 m_infoBoxesMenu->addAction( (*i)->action() ); 0549 break; 0550 case RenderPlugin::OnlineRenderType: 0551 m_onlineServicesMenu->addAction( (*i)->action() ); 0552 break; 0553 case RenderPlugin::ThemeRenderType: 0554 themeActions.append( (*i)->action() ); 0555 break; 0556 default: 0557 mDebug() << "No menu entry created for plugin with unknown render type:" << (*i)->nameId(); 0558 break; 0559 } 0560 } 0561 m_viewMenu->addMenu( m_infoBoxesMenu ); 0562 m_viewMenu->addMenu( m_onlineServicesMenu ); 0563 m_viewMenu->addActions( themeActions ); 0564 m_viewMenu->addAction( m_showCloudsAction ); 0565 m_viewMenu->addSeparator(); 0566 m_viewMenu->addAction(m_controlSunAction); 0567 m_viewMenu->addAction(m_controlTimeAction); 0568 } 0569 0570 void MainWindow::createBookmarksListMenu( QMenu *bookmarksListMenu, const GeoDataContainer *container ) 0571 { 0572 //m_bookmarksListMenu->clear(); 0573 0574 QVector<GeoDataPlacemark*> bookmarks = container->placemarkList(); 0575 0576 for ( const GeoDataPlacemark *placemark: bookmarks ) { 0577 QAction *bookmarkAction = new QAction( placemark->name(), this ); 0578 QVariant var; 0579 0580 const GeoDataLookAt* lookAt = placemark->lookAt(); 0581 if ( !lookAt ) { 0582 GeoDataCoordinates coordinates = placemark->coordinate(); 0583 GeoDataLookAt coordinateToLookAt; 0584 coordinateToLookAt.setCoordinates( coordinates ); 0585 coordinateToLookAt.setRange( marbleWidget()->lookAt().range() ); 0586 var.setValue( coordinateToLookAt ); 0587 } else { 0588 var.setValue( *lookAt ); 0589 } 0590 bookmarkAction->setData( var ); 0591 bookmarksListMenu->addAction( bookmarkAction ); 0592 } 0593 0594 } 0595 void MainWindow::createBookmarkMenu() 0596 { 0597 m_bookmarkMenu->clear(); 0598 m_bookmarkMenu->addAction( m_addBookmarkAction ); 0599 m_bookmarkMenu->addAction( m_toggleBookmarkDisplayAction ); 0600 m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->document()->isVisible() ); 0601 m_bookmarkMenu->addAction( m_setHomeAction ); 0602 m_bookmarkMenu->addAction( m_manageBookmarksAction ); 0603 0604 m_bookmarkMenu->addSeparator(); 0605 0606 m_bookmarkMenu->addAction( QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Home"), 0607 m_controlView->marbleWidget(), SLOT(goHome()) ); 0608 createFolderList( m_bookmarkMenu, m_controlView->marbleModel()->bookmarkManager()->document() ); 0609 } 0610 0611 void MainWindow::createFolderList( QMenu *bookmarksListMenu, const GeoDataContainer *container ) 0612 { 0613 QVector<GeoDataFolder*> folders = container->folderList(); 0614 0615 if ( folders.size() == 1 && folders.first()->name() == tr("Default")) { 0616 createBookmarksListMenu( bookmarksListMenu, folders.first() ); 0617 } 0618 else { 0619 for ( const GeoDataFolder *folder: folders ) { 0620 QMenu *subMenu = bookmarksListMenu->addMenu(QIcon(QStringLiteral(":/icons/folder-bookmark.png")), folder->name()); 0621 createFolderList( subMenu, folder ); 0622 connect( subMenu, SIGNAL(triggered(QAction*)), 0623 this, SLOT(lookAtBookmark(QAction*)) ); 0624 } 0625 } 0626 0627 createBookmarksListMenu( bookmarksListMenu, container ); 0628 connect( bookmarksListMenu, SIGNAL(triggered(QAction*)), 0629 this, SLOT(lookAtBookmark(QAction*)) ); 0630 } 0631 0632 0633 void MainWindow::lookAtBookmark( QAction *action) 0634 { 0635 if ( action->data().isNull() ) { 0636 return; 0637 } 0638 0639 GeoDataLookAt temp = qvariant_cast<GeoDataLookAt>( action->data() ) ; 0640 m_controlView->marbleWidget()->flyTo( temp ) ; 0641 mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree) 0642 << " latitude : "<< temp.latitude(GeoDataCoordinates::Degree) 0643 << " distance : " << temp.range(); 0644 0645 0646 } 0647 0648 void MainWindow::manageBookmarks() 0649 { 0650 MarbleModel * const model = m_controlView->marbleModel(); 0651 QPointer<BookmarkManagerDialog> dialog = new BookmarkManagerDialog( model, this ); 0652 dialog->exec(); 0653 delete dialog; 0654 } 0655 0656 void MainWindow::setHome() 0657 { 0658 MarbleWidget *widget = m_controlView->marbleWidget(); 0659 widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() ); 0660 } 0661 0662 void MainWindow::openEditBookmarkDialog() 0663 { 0664 MarbleWidget *widget = m_controlView->marbleWidget(); 0665 QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget ); 0666 dialog->setMarbleWidget( widget ); 0667 dialog->setCoordinates( widget->lookAt().coordinates() ); 0668 dialog->setRange( widget->lookAt().range() ); 0669 dialog->setReverseGeocodeName(); 0670 if ( dialog->exec() == QDialog::Accepted ) { 0671 widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() ); 0672 } 0673 delete dialog; 0674 } 0675 0676 void MainWindow::createPluginMenus() 0677 { 0678 // Remove and delete toolbars if they exist 0679 while( !m_pluginToolbars.isEmpty() ) { 0680 QToolBar* tb = m_pluginToolbars.takeFirst(); 0681 this->removeToolBar(tb); 0682 tb->deleteLater(); 0683 } 0684 0685 // Do not create too many menu entries on a MID 0686 // FIXME: Set up another way of switching the plugins on and off. 0687 if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { 0688 return; 0689 } 0690 0691 //remove and delete old menus if they exist 0692 while( !m_pluginMenus.isEmpty() ) { 0693 m_viewMenu->removeAction( m_pluginMenus.takeFirst() ); 0694 } 0695 0696 QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins(); 0697 QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin(); 0698 QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd(); 0699 0700 for (; i != end; ++i ) { 0701 0702 // menus 0703 const QList<QActionGroup*> *tmp_actionGroups = (*i)->actionGroups(); 0704 if ((*i)->enabled() && tmp_actionGroups && (*i)->nameId() != QLatin1String("annotation")) { 0705 for( QActionGroup *ag: *tmp_actionGroups ) { 0706 if( !ag->actions().isEmpty() ) { 0707 m_pluginMenus.append( m_viewMenu->addSeparator() ); 0708 } 0709 for( QAction *action: ag->actions() ) { 0710 m_viewMenu->addAction( action ); 0711 m_pluginMenus.append( action ); 0712 } 0713 } 0714 } 0715 0716 // toolbars 0717 const QList<QActionGroup*> *tmp_toolbarActionGroups = (*i)->toolbarActionGroups(); 0718 if ( (*i)->enabled() && tmp_toolbarActionGroups ) { 0719 QToolBar* toolbar = new QToolBar(this); 0720 toolbar->setObjectName(QLatin1String("plugin-toolbar-") + (*i)->nameId()); 0721 0722 for( QActionGroup* ag: *tmp_toolbarActionGroups ) { 0723 toolbar->addActions( ag->actions() ); 0724 if ( tmp_toolbarActionGroups->last() != ag ) { 0725 toolbar->addSeparator(); 0726 } 0727 } 0728 0729 m_pluginToolbars.append( toolbar ); 0730 this->addToolBar( toolbar ); 0731 } 0732 } 0733 0734 // FIXME: load the menus once the method has been settled on 0735 } 0736 0737 void MainWindow::createStatusBar() 0738 { 0739 statusBar()->showMessage(tr("Ready")); 0740 statusBar()->hide(); 0741 } 0742 0743 void MainWindow::openMapDialog() 0744 { 0745 QPointer<MapThemeDownloadDialog> dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) ); 0746 dialog->exec(); 0747 delete dialog; 0748 } 0749 0750 void MainWindow::exportMapScreenShot() 0751 { 0752 QString fileName = QFileDialog::getSaveFileName(this, tr("Export Map"), // krazy:exclude=qclasses 0753 QDir::homePath(), 0754 tr("Images (*.jpg *.png)")); 0755 0756 if ( !fileName.isEmpty() ) 0757 { 0758 // Take the case into account where no file format is indicated 0759 const char * format = nullptr; 0760 if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive) 0761 && !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) ) 0762 { 0763 format = "JPG"; 0764 } 0765 0766 QPixmap mapPixmap = m_controlView->mapScreenShot(); 0767 bool success = mapPixmap.save( fileName, format ); 0768 if ( !success ) 0769 { 0770 QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses 0771 tr( "An error occurred while trying to save the file.\n" ), 0772 QMessageBox::Ok); 0773 } 0774 } 0775 } 0776 0777 0778 void MainWindow::showFullScreen( bool isChecked ) 0779 { 0780 if ( isChecked ) { 0781 setWindowState( windowState() | Qt::WindowFullScreen ); // set 0782 } 0783 else { 0784 setWindowState( windowState() & ~Qt::WindowFullScreen ); // reset 0785 } 0786 0787 m_fullScreenAction->setChecked( isChecked ); // Sync state with the GUI 0788 } 0789 0790 void MainWindow::copyCoordinates() 0791 { 0792 qreal lon = m_controlView->marbleWidget()->centerLongitude(); 0793 qreal lat = m_controlView->marbleWidget()->centerLatitude(); 0794 0795 QString positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString(); 0796 QClipboard *clipboard = QApplication::clipboard(); 0797 0798 clipboard->setText( positionString ); 0799 } 0800 0801 void MainWindow::copyMap() 0802 { 0803 QPixmap mapPixmap = m_controlView->mapScreenShot(); 0804 QClipboard *clipboard = QApplication::clipboard(); 0805 0806 clipboard->setPixmap( mapPixmap ); 0807 } 0808 0809 void MainWindow::showStatusBar( bool isChecked ) 0810 { 0811 if ( isChecked ) 0812 { 0813 statusBar()->show(); 0814 } 0815 else 0816 { 0817 statusBar()->hide(); 0818 } 0819 0820 m_statusBarAction->setChecked( isChecked ); // Sync state with the GUI 0821 } 0822 0823 void MainWindow::showClouds( bool isChecked ) 0824 { 0825 m_controlView->marbleWidget()->setShowClouds( isChecked ); 0826 0827 m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI 0828 } 0829 0830 void MainWindow::showBookmarks( bool show ) 0831 { 0832 m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show ); 0833 0834 m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI 0835 } 0836 0837 void MainWindow::workOffline( bool offline ) 0838 { 0839 m_controlView->setWorkOffline( offline ); 0840 0841 m_workOfflineAction->setChecked( offline ); // Sync state with the GUI 0842 } 0843 0844 void MainWindow::lockPosition( bool isChecked ) 0845 { 0846 QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems(); 0847 0848 QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin(); 0849 QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd(); 0850 for (; i != end; ++i ) 0851 { 0852 // Locking one would suffice as it affects all. 0853 // Nevertheless go through all. 0854 (*i)->setPositionLocked(isChecked); 0855 } 0856 } 0857 0858 void MainWindow::controlSun() 0859 { 0860 if (!m_sunControlDialog) { 0861 m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), this ); 0862 connect( m_sunControlDialog, SIGNAL(showSun(bool)), 0863 this, SLOT (showSun(bool)) ); 0864 } 0865 0866 m_sunControlDialog->show(); 0867 m_sunControlDialog->raise(); 0868 m_sunControlDialog->activateWindow(); 0869 } 0870 0871 void MainWindow::controlTime() 0872 { 0873 if ( !m_timeControlDialog ) 0874 { 0875 m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() ); 0876 } 0877 /* m_timeControlDialog is a modeless dialog so that user may adjust time and interact with main application simultaneously.*/ 0878 m_timeControlDialog->show(); 0879 m_timeControlDialog->raise(); 0880 m_timeControlDialog->activateWindow(); 0881 } 0882 0883 0884 void MainWindow::showSun( bool active ) 0885 { 0886 m_controlView->marbleWidget()->setShowSunShading( active ); 0887 } 0888 0889 void MainWindow::reload() 0890 { 0891 m_controlView->marbleWidget()->reloadMap(); 0892 } 0893 0894 void MainWindow::enterWhatsThis() 0895 { 0896 QWhatsThis::enterWhatsThisMode(); 0897 } 0898 0899 void MainWindow::aboutMarble() 0900 { 0901 MarbleAboutDialog dlg(this); 0902 dlg.setApplicationTitle( tr( "Marble Virtual Globe %1" ).arg( ControlView::applicationVersion() ) ); 0903 dlg.exec(); 0904 } 0905 0906 void MainWindow::handbook() 0907 { 0908 const QString code = MarbleLocale::languageCode(); 0909 0910 // docs.kde.org falls back to the English manual if no translated 0911 // documentation is available for the requested language. 0912 QUrl handbookLocation(QLatin1String("https://docs.kde.org/?application=marble&branch=stable5&language=") + code); 0913 0914 if( !QDesktopServices::openUrl( handbookLocation ) ) 0915 qDebug() << "URL not opened"; 0916 } 0917 0918 void MainWindow::openForum() 0919 { 0920 QUrl forumLocation("https://forum.kde.org/viewforum.php?f=217"); 0921 if( !QDesktopServices::openUrl( forumLocation ) ) { 0922 mDebug() << "Failed to open URL " << forumLocation.toString(); 0923 } 0924 } 0925 0926 void MainWindow::showPosition( const QString& position ) 0927 { 0928 m_position = position; 0929 updateStatusBar(); 0930 } 0931 0932 void MainWindow::showDistance( const QString& distance ) 0933 { 0934 m_distance = distance; 0935 updateStatusBar(); 0936 } 0937 0938 void MainWindow::showZoom( int zoom ) 0939 { 0940 m_zoom = QString::number( zoom ); 0941 updateStatusBar(); 0942 } 0943 0944 void MainWindow::showDateTime() 0945 { 0946 m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat ); 0947 updateStatusBar(); 0948 } 0949 0950 void MainWindow::updateStatusBar() 0951 { 0952 if ( m_positionLabel ) 0953 m_positionLabel->setText(tr("Position: %1").arg(m_position)); 0954 0955 if ( m_distanceLabel ) 0956 m_distanceLabel->setText(tr("Altitude: %1").arg(m_distance)); 0957 0958 if ( m_zoomLabel ) 0959 m_zoomLabel->setText(tr("Zoom: %1").arg(m_zoom)); 0960 0961 if ( m_clockLabel ) 0962 m_clockLabel->setText(tr("Time: %1").arg(m_clock)); 0963 0964 switch ( m_configDialog->angleUnit() ) { 0965 case DMSDegree: 0966 m_dmsDegreeAction->setChecked( true ); 0967 break; 0968 case DecimalDegree: 0969 m_decimalDegreeAction->setChecked( true ); 0970 break; 0971 case UTM: 0972 m_utmAction->setChecked( true ); 0973 break; 0974 } 0975 } 0976 0977 void MainWindow::openFile() 0978 { 0979 const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager(); 0980 0981 QStringList allFileExtensions; 0982 QStringList filters; 0983 for ( const ParseRunnerPlugin *plugin: pluginManager->parsingRunnerPlugins() ) { 0984 if (plugin->nameId() == QLatin1String("Cache")) 0985 continue; 0986 0987 const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." ); 0988 const QString filter = plugin->fileFormatDescription() + QLatin1String(" (") + fileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')'); 0989 filters << filter; 0990 allFileExtensions << fileExtensions; 0991 } 0992 0993 allFileExtensions.sort(); // sort since file extensions are visible under Windows 0994 const QString allFileTypes = tr("All Supported Files") + QLatin1String(" (") + allFileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')'); 0995 0996 filters.sort(); 0997 filters.prepend( allFileTypes ); 0998 const QString filter = filters.join( ";;" ); 0999 1000 QStringList fileNames = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_lastFileOpenPath, filter ); 1001 1002 if ( !fileNames.isEmpty() ) { 1003 const QString firstFile = fileNames.first(); 1004 m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath(); 1005 } 1006 1007 for( const QString &fileName: fileNames ) { 1008 m_controlView->marbleModel()->addGeoDataFile( fileName ); 1009 } 1010 } 1011 1012 void MainWindow::setupStatusBar() 1013 { 1014 statusBar()->setSizeGripEnabled( true ); 1015 statusBar()->setContextMenuPolicy( Qt::ActionsContextMenu ); 1016 1017 statusBar()->addAction( m_toggleTileLevelAction ); 1018 1019 QMenu *angleDisplayUnitMenu = new QMenu(this); 1020 angleDisplayUnitMenu->addActions( m_angleDisplayUnitActionGroup->actions() ); 1021 QAction *angleDisplayUnitMenuAction = new QAction( tr("&Angle Display Unit"), statusBar() ); 1022 angleDisplayUnitMenuAction->setMenu( angleDisplayUnitMenu ); 1023 statusBar()->addAction( angleDisplayUnitMenuAction ); 1024 1025 setupDownloadProgressBar(); 1026 1027 m_positionLabel = new QLabel( ); 1028 m_positionLabel->setIndent( 5 ); 1029 // UTM syntax is used in the template string, as it is longer than the lon/lat one 1030 QString templatePositionString = tr("Position: %1").arg(QLatin1String(" 00Z 000000.00 m E, 00000000.00 m N_")); 1031 int maxPositionWidth = fontMetrics().boundingRect(templatePositionString).width() 1032 + 2 * m_positionLabel->margin() + 2 * m_positionLabel->indent(); 1033 m_positionLabel->setFixedWidth( maxPositionWidth ); 1034 statusBar()->addPermanentWidget ( m_positionLabel ); 1035 1036 m_distanceLabel = new QLabel( ); 1037 m_distanceLabel->setIndent( 5 ); 1038 QString templateDistanceString = tr("Altitude: %1").arg(QLatin1String(" 00.000,0 mu")); 1039 int maxDistanceWidth = fontMetrics().boundingRect(templateDistanceString).width() 1040 + 2 * m_distanceLabel->margin() + 2 * m_distanceLabel->indent(); 1041 m_distanceLabel->setFixedWidth( maxDistanceWidth ); 1042 statusBar()->addPermanentWidget ( m_distanceLabel ); 1043 1044 m_zoomLabel = new QLabel( ); 1045 m_zoomLabel->setIndent( 5 ); 1046 QString templateZoomString = tr("Zoom: %1").arg(QLatin1String(" 00")); 1047 int maxZoomWidth = fontMetrics().boundingRect(templateZoomString).width() 1048 + 2 * m_zoomLabel->margin() + 2 * m_zoomLabel->indent(); 1049 m_zoomLabel->setFixedWidth( maxZoomWidth ); 1050 // Not added here, but activated by the user with the context menu 1051 1052 m_clockLabel = new QLabel( ); 1053 m_clockLabel->setIndent( 5 ); 1054 QString templateDateTimeString = tr("Time: %1").arg(QLocale().toString(QDateTime::fromString( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat)); 1055 int maxDateTimeWidth = fontMetrics().boundingRect( templateDateTimeString ).width() 1056 + 2 * m_clockLabel->margin() + 2 * m_clockLabel->indent(); 1057 m_clockLabel->setFixedWidth( maxDateTimeWidth ); 1058 statusBar()->addPermanentWidget ( m_clockLabel ); 1059 1060 connect( marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)), 1061 this, SLOT(showPosition(QString)) ); 1062 connect( marbleWidget(), SIGNAL(distanceChanged(QString)), 1063 this, SLOT(showDistance(QString)) ); 1064 connect( marbleWidget(), SIGNAL(tileLevelChanged(int)), 1065 this, SLOT(showZoom(int)) ); 1066 connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()), 1067 this, SLOT(showDateTime()) ); 1068 1069 updateStatusBar(); 1070 } 1071 1072 void MainWindow::setupDownloadProgressBar() 1073 { 1074 m_downloadProgressBar = new QProgressBar; 1075 m_downloadProgressBar->setVisible( true ); 1076 statusBar()->addPermanentWidget( m_downloadProgressBar ); 1077 1078 HttpDownloadManager * const downloadManager = 1079 m_controlView->marbleModel()->downloadManager(); 1080 Q_ASSERT( downloadManager ); 1081 connect( downloadManager, SIGNAL(progressChanged(int,int)), SLOT(handleProgress(int,int)) ); 1082 connect( downloadManager, SIGNAL(jobRemoved()), SLOT(removeProgressItem()) ); 1083 } 1084 1085 void MainWindow::handleProgress( int active, int queued ){ 1086 m_downloadProgressBar->setUpdatesEnabled( false ); 1087 if ( m_downloadProgressBar->value() < 0 ) { 1088 m_downloadProgressBar->setMaximum( 1 ); 1089 m_downloadProgressBar->setValue( 0 ); 1090 m_downloadProgressBar->setVisible( true ); 1091 } else { 1092 m_downloadProgressBar->setMaximum( qMax<int>( m_downloadProgressBar->maximum(), active + queued ) ); 1093 } 1094 1095 m_downloadProgressBar->setUpdatesEnabled( true ); 1096 } 1097 1098 void MainWindow::removeProgressItem(){ 1099 m_downloadProgressBar->setUpdatesEnabled( false ); 1100 m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 ); 1101 if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) { 1102 m_downloadProgressBar->reset(); 1103 m_downloadProgressBar->setVisible( false ); 1104 } 1105 1106 m_downloadProgressBar->setUpdatesEnabled( true ); 1107 } 1108 1109 void MainWindow::closeEvent( QCloseEvent *event ) 1110 { 1111 writeSettings(); 1112 1113 QCloseEvent newEvent; 1114 QCoreApplication::sendEvent( m_controlView, &newEvent ); 1115 1116 if ( newEvent.isAccepted() ) { 1117 event->accept(); 1118 } else { 1119 event->ignore(); 1120 } 1121 } 1122 1123 QString MainWindow::readMarbleDataPath() 1124 { 1125 QSettings settings; 1126 1127 settings.beginGroup("MarbleWidget"); 1128 const auto marbleDataPath = settings.value("marbleDataPath", "").toString(); 1129 settings.endGroup(); 1130 1131 return marbleDataPath; 1132 } 1133 1134 void MainWindow::readSettings(const QVariantMap& overrideSettings) 1135 { 1136 QSettings settings; 1137 1138 settings.beginGroup("MainWindow"); 1139 resize(settings.value("size", QSize(640, 480)).toSize()); 1140 move(settings.value("pos", QPoint(200, 200)).toPoint()); 1141 showFullScreen(settings.value("fullScreen", false ).toBool()); 1142 showStatusBar(settings.value("statusBar", false ).toBool()); 1143 showZoomLevel(settings.value("showZoomLevel",false).toBool()); 1144 show(); 1145 showClouds(settings.value("showClouds", true ).toBool()); 1146 workOffline(settings.value("workOffline", false ).toBool()); 1147 m_controlView->marbleWidget()->setShowAtmosphere(settings.value("showAtmosphere", true ).toBool()); 1148 m_lastFileOpenPath = settings.value("lastFileOpenDir", QDir::homePath()).toString(); 1149 showBookmarks( settings.value( "showBookmarks", true ).toBool() ); 1150 restoreState( settings.value("windowState").toByteArray() ); 1151 settings.endGroup(); 1152 1153 setUpdatesEnabled(false); 1154 1155 settings.beginGroup("MarbleWidget"); 1156 QString mapThemeId; 1157 const QVariantMap::ConstIterator mapThemeIdIt = overrideSettings.find(QLatin1String("mapTheme")); 1158 if ( mapThemeIdIt != overrideSettings.constEnd() ) { 1159 mapThemeId = mapThemeIdIt.value().toString(); 1160 } else { 1161 mapThemeId = settings.value("mapTheme", m_controlView->defaultMapThemeId() ).toString(); 1162 } 1163 mDebug() << "mapThemeId:" << mapThemeId; 1164 m_controlView->marbleWidget()->setMapThemeId( mapThemeId ); 1165 m_controlView->marbleWidget()->setProjection( 1166 (Projection)(settings.value("projection", Spherical ).toInt()) 1167 ); 1168 1169 // Set home position 1170 m_controlView->marbleModel()->setHome( 1171 settings.value("homeLongitude", 9.4).toDouble(), 1172 settings.value("homeLatitude", 54.8).toDouble(), 1173 settings.value("homeZoom", 1050 ).toInt() 1174 ); 1175 1176 // Center on/Distance 1177 const QVariantMap::ConstIterator distanceIt = overrideSettings.find(QLatin1String("distance")); 1178 const bool isDistanceOverwritten = (distanceIt != overrideSettings.constEnd()); 1179 1180 const QVariantMap::ConstIterator lonLatIt = overrideSettings.find(QLatin1String("lonlat")); 1181 if ( lonLatIt != overrideSettings.constEnd() ) { 1182 const QVariantList lonLat = lonLatIt.value().toList(); 1183 m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() ); 1184 } else { 1185 switch ( m_configDialog->onStartup() ) { 1186 case Marble::LastLocationVisited: 1187 m_controlView->marbleWidget()->centerOn( 1188 settings.value("quitLongitude", 0.0).toDouble(), 1189 settings.value("quitLatitude", 0.0).toDouble() ); 1190 if (! isDistanceOverwritten) { 1191 // set default radius to 1350 (Atlas theme's "sharp" radius) 1192 m_controlView->marbleWidget()->setRadius( settings.value("quitRadius", 1350).toInt() ); 1193 } 1194 break; 1195 case Marble::ShowHomeLocation: 1196 m_controlView->marbleWidget()->goHome(); 1197 break; 1198 default: 1199 break; 1200 } 1201 } 1202 if (isDistanceOverwritten) { 1203 m_controlView->marbleWidget()->setDistance(distanceIt.value().toDouble()); 1204 } 1205 1206 // Geo URI parsing 1207 QString geoUriString = qvariant_cast<QString>( overrideSettings.value("geo-uri", "")); 1208 if ( !geoUriString.isEmpty() ) { 1209 m_controlView->openGeoUri( geoUriString ); 1210 } 1211 1212 bool isLocked = settings.value( "lockFloatItemPositions", false ).toBool(); 1213 m_lockFloatItemsAction->setChecked( isLocked ); 1214 lockPosition(isLocked); 1215 settings.endGroup(); 1216 1217 settings.beginGroup( "Sun" ); 1218 m_controlView->marbleWidget()->setShowSunShading( settings.value( "showSun", false ).toBool() ); 1219 m_controlView->marbleWidget()->setShowCityLights( settings.value( "showCitylights", false ).toBool() ); 1220 m_controlView->marbleWidget()->setLockToSubSolarPoint( settings.value( "lockToSubSolarPoint", false ).toBool() ); 1221 m_controlView->marbleWidget()->setSubSolarPointIconVisible( settings.value( "subSolarPointIconVisible", false ).toBool() ); 1222 settings.endGroup(); 1223 1224 settings.beginGroup( "Time" ); 1225 if( settings.value( "systemTime", "true" ).toBool() == true ) 1226 { 1227 /* nothing to do */ 1228 } 1229 else if( settings.value( "lastSessionTime", "true" ).toBool() == true ) 1230 { 1231 m_controlView->marbleModel()->setClockDateTime( settings.value( "dateTime" ).toDateTime() ); 1232 m_controlView->marbleModel()->setClockSpeed( settings.value( "speedSlider", 1 ).toInt() ); 1233 } 1234 settings.endGroup(); 1235 1236 setUpdatesEnabled(true); 1237 1238 // Load previous route settings 1239 settings.beginGroup( "Routing" ); 1240 { 1241 RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager(); 1242 routingManager->readSettings(); 1243 bool const startupWarning = settings.value( "showGuidanceModeStartupWarning", QVariant( true ) ).toBool(); 1244 routingManager->setShowGuidanceModeStartupWarning( startupWarning ); 1245 routingManager->setLastOpenPath( settings.value( "lastRouteOpenPath", QDir::homePath() ).toString() ); 1246 routingManager->setLastSavePath( settings.value( "lastRouteSavePath", QDir::homePath() ).toString() ); 1247 1248 QColor tempColor; 1249 tempColor = QColor( settings.value( "routeColorStandard", Oxygen::skyBlue4.name() ).toString() ); 1250 tempColor.setAlpha( settings.value( "routeAlphaStandard", 200 ).toInt() ); 1251 routingManager->setRouteColorStandard( tempColor ); 1252 1253 tempColor = QColor( settings.value( "routeColorHighlighted", Oxygen::skyBlue1.name() ).toString() ); 1254 tempColor.setAlpha( settings.value( "routeAlphaHighlighted", 200 ).toInt() ); 1255 routingManager->setRouteColorHighlighted( tempColor ); 1256 1257 tempColor = QColor( settings.value( "routeColorAlternative", Oxygen::aluminumGray4.name() ).toString() ); 1258 tempColor.setAlpha( settings.value( "routeAlphaAlternative", 200 ).toInt() ); 1259 routingManager->setRouteColorAlternative( tempColor ); 1260 } 1261 settings.endGroup(); 1262 1263 1264 settings.beginGroup( "Routing Profile" ); 1265 if ( settings.contains( "Num" ) ) { 1266 QList<RoutingProfile> profiles; 1267 int numProfiles = settings.value( "Num", 0 ).toInt(); 1268 for ( int i = 0; i < numProfiles; ++i ) { 1269 settings.beginGroup( QString( "Profile %0" ).arg(i) ); 1270 QString name = settings.value( "Name", tr( "Unnamed" ) ).toString(); 1271 RoutingProfile profile( name ); 1272 for ( const QString& pluginName: settings.childGroups() ) { 1273 settings.beginGroup( pluginName ); 1274 profile.pluginSettings().insert( pluginName, QHash<QString, QVariant>() ); 1275 for ( const QString& key: settings.childKeys() ) { 1276 if (key != QLatin1String("Enabled")) { 1277 profile.pluginSettings()[ pluginName ].insert( key, settings.value( key ) ); 1278 } 1279 } 1280 settings.endGroup(); 1281 } 1282 profiles << profile; 1283 settings.endGroup(); 1284 } 1285 m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles ); 1286 } else { 1287 m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles(); 1288 } 1289 int const profileIndex = settings.value( "currentIndex", 0 ).toInt(); 1290 if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) { 1291 RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex ); 1292 m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile ); 1293 } 1294 1295 settings.endGroup(); 1296 1297 settings.beginGroup( "Plugins"); 1298 PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); 1299 tracking->readSettings(); 1300 QString positionProvider = settings.value( "activePositionTrackingPlugin", QString() ).toString(); 1301 if ( !positionProvider.isEmpty() ) { 1302 const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager(); 1303 for( const PositionProviderPlugin* plugin: pluginManager->positionProviderPlugins() ) { 1304 if ( plugin->nameId() == positionProvider ) { 1305 PositionProviderPlugin* instance = plugin->newInstance(); 1306 tracking->setPositionProviderPlugin( instance ); 1307 break; 1308 } 1309 } 1310 } 1311 settings.endGroup(); 1312 1313 settings.beginGroup( "Tracking" ); 1314 if ( settings.contains( "autoCenter" ) || settings.contains( "recenterMode" ) ) { 1315 CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget(); 1316 Q_ASSERT( trackingWidget ); 1317 trackingWidget->setRecenterMode( settings.value( "recenterMode", 0 ).toInt() ); 1318 trackingWidget->setAutoZoom( settings.value( "autoZoom", false ).toBool() ); 1319 trackingWidget->setTrackVisible( settings.value( "trackVisible", true ).toBool() ); 1320 trackingWidget->setLastOpenPath( settings.value( "lastTrackOpenPath", QDir::homePath() ).toString() ); 1321 trackingWidget->setLastSavePath( settings.value( "lastTrackSavePath", QDir::homePath() ).toString() ); 1322 } 1323 settings.endGroup(); 1324 1325 // The config dialog has to read settings. 1326 m_configDialog->readSettings(); 1327 1328 settings.beginGroup( "Navigation" ); 1329 m_controlView->setExternalMapEditor( settings.value( "externalMapEditor", "" ).toString() ); 1330 settings.endGroup(); 1331 1332 settings.beginGroup( "CloudSync" ); 1333 CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); 1334 cloudSyncManager->setOwncloudCredentials( settings.value( "owncloudServer", "" ).toString(), 1335 settings.value( "owncloudUsername", "" ).toString(), 1336 settings.value( "owncloudPassword", "" ).toString() ); 1337 cloudSyncManager->setSyncEnabled( settings.value( "enableSync", false ).toBool() ); 1338 cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( settings.value( "syncRoutes", true ).toBool() ); 1339 cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( settings.value( "syncBookmarks", true ).toBool() ); 1340 settings.endGroup(); 1341 } 1342 1343 void MainWindow::writeSettings() 1344 { 1345 QSettings settings; 1346 1347 settings.beginGroup( "MainWindow" ); 1348 settings.setValue( "size", size() ); 1349 settings.setValue( "pos", pos() ); 1350 settings.setValue( "fullScreen", m_fullScreenAction->isChecked() ); 1351 settings.setValue( "statusBar", m_statusBarAction->isChecked() ); 1352 settings.setValue( "showZoomLevel", m_toggleTileLevelAction->isChecked() ); 1353 settings.setValue( "showClouds", m_showCloudsAction->isChecked() ); 1354 settings.setValue( "workOffline", m_workOfflineAction->isChecked() ); 1355 settings.setValue( "showAtmosphere", m_controlView->marbleWidget()->showAtmosphere() ); 1356 settings.setValue( "lastFileOpenDir", m_lastFileOpenPath ); 1357 settings.setValue( "showBookmarks", m_toggleBookmarkDisplayAction->isChecked() ); 1358 settings.setValue( "windowState", saveState() ); 1359 settings.endGroup(); 1360 1361 settings.beginGroup( "MarbleWidget" ); 1362 // Get the 'home' values from the widget and store them in the settings. 1363 qreal homeLon = 0; 1364 qreal homeLat = 0; 1365 int homeZoom = 0; 1366 m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom ); 1367 QString mapTheme = m_controlView->marbleWidget()->mapThemeId(); 1368 int projection = (int)( m_controlView->marbleWidget()->projection() ); 1369 1370 settings.setValue( "homeLongitude", homeLon ); 1371 settings.setValue( "homeLatitude", homeLat ); 1372 settings.setValue( "homeZoom", homeZoom ); 1373 1374 settings.setValue( "mapTheme", mapTheme ); 1375 settings.setValue( "projection", projection ); 1376 1377 // Get the 'quit' values from the widget and store them in the settings. 1378 qreal quitLon = m_controlView->marbleWidget()->centerLongitude(); 1379 qreal quitLat = m_controlView->marbleWidget()->centerLatitude(); 1380 const int quitRadius = m_controlView->marbleWidget()->radius(); 1381 1382 settings.setValue( "quitLongitude", quitLon ); 1383 settings.setValue( "quitLatitude", quitLat ); 1384 settings.setValue( "quitRadius", quitRadius ); 1385 1386 settings.setValue( "lockFloatItemPositions", m_lockFloatItemsAction->isChecked() ); 1387 settings.endGroup(); 1388 1389 settings.beginGroup( "Sun" ); 1390 settings.setValue( "showSun", m_controlView->marbleWidget()->showSunShading() ); 1391 settings.setValue( "showCitylights", m_controlView->marbleWidget()->showCityLights() ); 1392 settings.setValue( "lockToSubSolarPoint", m_controlView->marbleWidget()->isLockedToSubSolarPoint() ); 1393 settings.setValue( "subSolarPointIconVisible", m_controlView->marbleWidget()->isSubSolarPointIconVisible() ); 1394 settings.endGroup(); 1395 1396 settings.beginGroup( "Time" ); 1397 settings.setValue( "dateTime", m_controlView->marbleModel()->clockDateTime() ); 1398 settings.setValue( "speedSlider", m_controlView->marbleModel()->clockSpeed() ); 1399 settings.endGroup(); 1400 1401 settings.beginGroup( "Routing Profile" ); 1402 QList<RoutingProfile> profiles = m_controlView->marbleWidget() 1403 ->model()->routingManager()->profilesModel()->profiles(); 1404 settings.setValue( "Num", profiles.count() ); 1405 for ( int i = 0; i < profiles.count(); ++i ) { 1406 settings.beginGroup( QString( "Profile %0" ).arg(i) ); 1407 const RoutingProfile& profile = profiles.at( i ); 1408 settings.setValue( "Name", profile.name() ); 1409 for ( const QString& pluginName: settings.childGroups() ) { 1410 settings.beginGroup( pluginName ); 1411 settings.remove(QString()); //remove all keys 1412 settings.endGroup(); 1413 } 1414 for ( const QString &key: profile.pluginSettings().keys() ) { 1415 settings.beginGroup( key ); 1416 settings.setValue( "Enabled", true ); 1417 for ( const QString& settingKey: profile.pluginSettings()[ key ].keys() ) { 1418 Q_ASSERT(settingKey != QLatin1String("Enabled")); 1419 settings.setValue( settingKey, profile.pluginSettings()[ key ][ settingKey ] ); 1420 } 1421 settings.endGroup(); 1422 } 1423 settings.endGroup(); 1424 } 1425 RoutingProfile const profile = m_controlView->marbleWidget()->model()->routingManager()->routeRequest()->routingProfile(); 1426 settings.setValue( "currentIndex", profiles.indexOf( profile ) ); 1427 settings.endGroup(); 1428 1429 settings.beginGroup( "Plugins"); 1430 QString positionProvider; 1431 PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); 1432 tracking->writeSettings(); 1433 if ( tracking->positionProviderPlugin() ) { 1434 positionProvider = tracking->positionProviderPlugin()->nameId(); 1435 } 1436 settings.setValue( "activePositionTrackingPlugin", positionProvider ); 1437 settings.endGroup(); 1438 1439 settings.beginGroup( "Tracking" ); 1440 CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget(); 1441 if ( trackingWidget ) { 1442 // Can be null due to lazy initialization 1443 settings.setValue( "recenterMode", trackingWidget->recenterMode() ); 1444 settings.setValue( "autoZoom", trackingWidget->autoZoom() ); 1445 settings.setValue( "trackVisible", trackingWidget->trackVisible() ); 1446 settings.setValue( "lastTrackOpenPath", trackingWidget->lastOpenPath() ); 1447 settings.setValue( "lastTrackSavePath", trackingWidget->lastSavePath() ); 1448 } 1449 settings.endGroup(); 1450 1451 // The config dialog has to write settings. 1452 m_configDialog->writeSettings(); 1453 1454 // Store current route settings 1455 settings.beginGroup( "Routing" ); 1456 { 1457 RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager(); 1458 routingManager->writeSettings(); 1459 settings.setValue( "showGuidanceModeStartupWarning", routingManager->showGuidanceModeStartupWarning() ); 1460 settings.setValue( "lastRouteOpenPath", routingManager->lastOpenPath() ); 1461 settings.setValue( "lastRouteSavePath", routingManager->lastSavePath() ); 1462 settings.setValue( "routeColorStandard", routingManager->routeColorStandard().name() ); 1463 settings.setValue( "routeAlphaStandard", routingManager->routeColorStandard().alpha() ); 1464 settings.setValue( "routeColorHighlighted", routingManager->routeColorHighlighted().name() ); 1465 settings.setValue( "routeAlphaHighlighted", routingManager->routeColorHighlighted().alpha() ); 1466 settings.setValue( "routeColorAlternative", routingManager->routeColorAlternative().name() ); 1467 settings.setValue( "routeAlphaAlternative", routingManager->routeColorAlternative().alpha() ); 1468 } 1469 settings.endGroup(); 1470 1471 settings.beginGroup( "Navigation"); 1472 settings.setValue( "externalMapEditor", m_controlView->externalMapEditor() ); 1473 settings.endGroup(); 1474 } 1475 1476 void MainWindow::editSettings() 1477 { 1478 // Show the settings dialog. 1479 m_configDialog->show(); 1480 m_configDialog->raise(); 1481 m_configDialog->activateWindow(); 1482 } 1483 1484 void MainWindow::updateSettings() 1485 { 1486 mDebug() << "Updating Settings ..."; 1487 1488 // FIXME: Font doesn't get updated instantly. 1489 m_controlView->marbleWidget()->setDefaultFont( m_configDialog->mapFont() ); 1490 1491 m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->stillQuality(), Marble::Still ); 1492 m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->animationQuality(), Marble::Animation ); 1493 1494 m_controlView->marbleWidget()->setDefaultAngleUnit( m_configDialog->angleUnit() ); 1495 MarbleGlobal::getInstance()->locale()->setMeasurementSystem( m_configDialog->measurementSystem() ); 1496 1497 m_distance = m_controlView->marbleWidget()->distanceString(); 1498 updateStatusBar(); 1499 1500 m_controlView->marbleWidget()->setAnimationsEnabled( m_configDialog->animateTargetVoyage() ); 1501 m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( m_configDialog->inertialEarthRotation() ); 1502 m_controlView->marbleWidget()->inputHandler()->setMouseViewRotationEnabled( m_configDialog->mouseViewRotation() ); 1503 if ( !m_configDialog->externalMapEditor().isEmpty() ) { 1504 m_controlView->setExternalMapEditor( m_configDialog->externalMapEditor() ); 1505 } 1506 1507 // Cache 1508 m_controlView->marbleModel()->setPersistentTileCacheLimit( m_configDialog->persistentTileCacheLimit() * 1024 ); 1509 m_controlView->marbleWidget()->setVolatileTileCacheLimit( m_configDialog->volatileTileCacheLimit() * 1024 ); 1510 1511 /* 1512 m_controlView->marbleWidget()->setProxy( m_configDialog->proxyUrl(), m_configDialog->proxyPort(), m_configDialog->user(), m_configDialog->password() ); 1513 */ 1514 1515 CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); 1516 cloudSyncManager->setOwncloudCredentials( m_configDialog->owncloudServer(), 1517 m_configDialog->owncloudUsername(), 1518 m_configDialog->owncloudPassword() ); 1519 cloudSyncManager->setSyncEnabled( m_configDialog->syncEnabled() ); 1520 cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( m_configDialog->syncRoutes() ); 1521 cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( m_configDialog->syncBookmarks() ); 1522 1523 m_controlView->marbleWidget()->update(); 1524 } 1525 1526 void MainWindow::showDownloadRegionDialog() 1527 { 1528 if ( !m_downloadRegionDialog ) { 1529 m_downloadRegionDialog = new DownloadRegionDialog( m_controlView->marbleWidget(), m_controlView ); 1530 // it might be tempting to move the connects to DownloadRegionDialog's "accepted" and 1531 // "applied" signals, be aware that the "hidden" signal might be come before the "accepted" 1532 // signal, leading to a too early disconnect. 1533 connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion())); 1534 connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion())); 1535 } 1536 // FIXME: get allowed range from current map theme 1537 m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 ); 1538 m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod ); 1539 ViewportParams const * const viewport = 1540 m_controlView->marbleWidget()->viewport(); 1541 m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() ); 1542 m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() ); 1543 1544 m_downloadRegionDialog->show(); 1545 m_downloadRegionDialog->raise(); 1546 m_downloadRegionDialog->activateWindow(); 1547 } 1548 1549 void MainWindow::downloadRegion() 1550 { 1551 Q_ASSERT( m_downloadRegionDialog ); 1552 QVector<TileCoordsPyramid> const pyramid = m_downloadRegionDialog->region(); 1553 if ( !pyramid.isEmpty() ) { 1554 m_controlView->marbleWidget()->downloadRegion( pyramid ); 1555 } 1556 } 1557 1558 void MainWindow::printMapScreenShot() 1559 { 1560 #ifndef QT_NO_PRINTER 1561 QPrinter printer( QPrinter::HighResolution ); 1562 QPointer<QPrintDialog> printDialog = new QPrintDialog( &printer, this ); 1563 m_controlView->printMapScreenShot( printDialog ); 1564 delete printDialog; 1565 #endif 1566 } 1567 1568 void MainWindow::updateMapEditButtonVisibility( const QString &mapTheme ) 1569 { 1570 Q_ASSERT( m_osmEditAction ); 1571 QStringList osmThemes = QStringList() 1572 << "earth/openstreetmap/openstreetmap.dgml" 1573 << "earth/hikebikemap/hikebikemap.dgml" 1574 << "earth/opencyclemap/opencyclemap.dgml" 1575 << "earth/public-transport/public-transport.dgml" 1576 << "earth/openseamap/openseamap.dgml" 1577 << "earth/vectorosm/vectorosm.dgml"; 1578 m_osmEditAction->setVisible(osmThemes.contains(mapTheme)); 1579 } 1580 1581 void MainWindow::showMovieCaptureDialog() 1582 { 1583 if (m_movieCaptureDialog == nullptr) { 1584 m_movieCaptureDialog = new MovieCaptureDialog(m_controlView->marbleWidget(), 1585 m_controlView->marbleWidget()); 1586 connect( m_movieCaptureDialog, SIGNAL(started()), this, SLOT(changeRecordingState())); 1587 } 1588 m_movieCaptureDialog->show(); 1589 } 1590 1591 void MainWindow::stopRecording() 1592 { 1593 if ( m_movieCaptureDialog ) { 1594 m_movieCaptureDialog->stopRecording(); 1595 changeRecordingState(); 1596 } 1597 } 1598 1599 void MainWindow::changeRecordingState() 1600 { 1601 m_recordMovieAction->setEnabled( !m_recordMovieAction->isEnabled() ); 1602 m_stopRecordingAction->setEnabled( !m_stopRecordingAction->isEnabled() ); 1603 } 1604 1605 void MainWindow::updateWindowTitle() 1606 { 1607 GeoSceneDocument *theme = m_controlView->marbleModel()->mapTheme(); 1608 setWindowTitle(theme ? theme->head()->name() : QString()); 1609 } 1610 1611 void MainWindow::updateCenterFromTheme() 1612 { 1613 //A scene provider may provide only a subset of the globe, use scene properties read from a dgml as a starting point 1614 GeoSceneDocument * theme = m_controlView->marbleModel()->mapTheme(); 1615 if (theme) { 1616 const GeoSceneMap* map = theme->map(); 1617 if (map) { 1618 const QVariantList coords = map->center(); 1619 if (! coords.empty()) { 1620 if (coords.count() == 2) { 1621 m_controlView->marbleWidget()->centerOn( coords.at(0).toDouble(), coords.at(1).toDouble() ); 1622 } 1623 else if (coords.count() == 4) { 1624 // If the the map theme provides a bounding box that does not contain 1625 // the current view then we center on the bounding box of the map theme. 1626 GeoDataLatLonBox latLonBox(coords.at(0).toDouble(), coords.at(1).toDouble(), 1627 coords.at(2).toDouble(), coords.at(3).toDouble(), GeoDataCoordinates::Degree); 1628 GeoDataLatLonAltBox viewBox = m_controlView->marbleWidget()->viewport()->viewLatLonAltBox(); 1629 if (!latLonBox.contains(viewBox)) { 1630 m_controlView->marbleWidget()->centerOn( latLonBox ); 1631 } 1632 } 1633 else { 1634 mDebug() << QString("DGML theme %1 has invalid number of coordinates").arg(theme->head()->name()); 1635 } 1636 } 1637 } 1638 } 1639 } 1640 1641 void MainWindow::showMapWizard() 1642 { 1643 QPointer<MapWizard> mapWizard = new MapWizard(); 1644 QSettings settings; 1645 1646 settings.beginGroup( "MapWizard" ); 1647 mapWizard->setWmsServers( settings.value( "wmsServers" ).toStringList() ); 1648 mapWizard->setWmtsServers( settings.value( "wmtsServers" ).toStringList() ); 1649 mapWizard->setStaticUrlServers( settings.value( "staticUrlServers" ).toStringList() ); 1650 settings.endGroup(); 1651 1652 mapWizard->exec(); 1653 1654 settings.beginGroup( "MapWizard" ); 1655 settings.setValue( "wmsServers", mapWizard->wmsServers() ); 1656 settings.setValue( "wmtsServers", mapWizard->wmtsServers() ); 1657 settings.setValue( "staticUrlServers", mapWizard->staticUrlServers() ); 1658 settings.endGroup(); 1659 1660 mapWizard->deleteLater(); 1661 } 1662 1663 void MainWindow::showZoomLevel(bool show) 1664 { 1665 if ( show ) { 1666 m_zoomLabel->show(); 1667 statusBar()->insertPermanentWidget( 2, m_zoomLabel ); 1668 } else { 1669 statusBar()->removeWidget( m_zoomLabel ); 1670 } 1671 // update from last modification 1672 m_toggleTileLevelAction->setChecked( show ); 1673 } 1674 1675 void MainWindow::changeAngleDisplayUnit( QAction *action ) 1676 { 1677 m_configDialog->setAngleUnit((Marble::AngleUnit)action->data().toInt()); 1678 } 1679 1680 void MainWindow::fallBackToDefaultTheme() 1681 { 1682 m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() ); 1683 } 1684 1685 void MainWindow::changeViewSize( QAction* action ) 1686 { 1687 if ( action->data().type() == QVariant::Size ) { 1688 if ( m_savedSize.isEmpty() ) { 1689 m_savedSize = m_controlView->size(); 1690 } 1691 m_controlView->setFixedSize( action->data().toSize() ); 1692 adjustSize(); 1693 } else { 1694 m_controlView->setMinimumSize( QSize( 0, 0 ) ); 1695 m_controlView->setMaximumSize( QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ) ); 1696 m_controlView->resize( m_savedSize ); 1697 m_controlView->setMinimumSize( m_savedSize ); 1698 adjustSize(); 1699 m_controlView->setMinimumSize( QSize( 0, 0 ) ); 1700 m_savedSize.setHeight( -1 ); 1701 } 1702 } 1703 #include "moc_QtMainWindow.cpp"