1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2006-2010 Torsten Rahn <tackat@kde.org>
4 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5 // SPDX-FileCopyrightText: 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
6 // SPDX-FileCopyrightText: 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
7 // SPDX-FileCopyrightText: 2012 Mohammed Nafees <nafees.technocool@gmail.com>
8 //
9 
10 #include "QtMainWindow.h"
11 
12 #include "MarbleDebug.h"
13 #include <QList>
14 #include <QSettings>
15 #include <QUrl>
16 #include <QCloseEvent>
17 #include <QVariant>
18 #include <QVector>
19 #include <QAction>
20 #include <QLabel>
21 #include <QWhatsThis>
22 #include <QApplication>
23 #include <QIcon>
24 #include <QMenuBar>
25 #include <QStatusBar>
26 #include <QProgressBar>
27 #include <QToolBar>
28 #include <QDesktopServices>
29 #include <QFileDialog>
30 #include <QMessageBox>
31 #include <QPrintDialog>
32 #include <QPrinter>
33 #include <QDialogButtonBox>
34 #include <QClipboard>
35 #include <QNetworkProxy>
36 
37 #include "EditBookmarkDialog.h"
38 #include "BookmarkManagerDialog.h"
39 #include "CurrentLocationWidget.h"
40 #include "MapViewWidget.h"
41 #include "MarbleDirs.h"
42 #include "MarbleAboutDialog.h"
43 #include "QtMarbleConfigDialog.h"
44 #include "SunControlWidget.h"
45 #include "TimeControlWidget.h"
46 #include "MarbleLocale.h"
47 #include "DownloadRegionDialog.h"
48 #include "ViewportParams.h"
49 #include "AbstractFloatItem.h"
50 #include "MarbleModel.h"
51 #include "MarbleClock.h"
52 #include "FileManager.h"
53 #include "HttpDownloadManager.h"
54 #include "BookmarkManager.h"
55 #include "NewBookmarkFolderDialog.h"
56 #include "GeoSceneDocument.h"
57 #include "GeoSceneHead.h"
58 #include "GeoDataLookAt.h"
59 #include "GeoDataCoordinates.h"
60 #include "GeoDataDocument.h"
61 #include "GeoDataFolder.h"
62 #include "GeoDataPlacemark.h"
63 #include "GeoUriParser.h"
64 #include "routing/RoutingManager.h"
65 #include "routing/RoutingProfilesModel.h"
66 #include "routing/RoutingWidget.h"
67 #include "routing/RouteRequest.h"
68 #include "ParseRunnerPlugin.h"
69 #include "PositionTracking.h"
70 #include "PositionProviderPlugin.h"
71 #include "PluginManager.h"
72 #include "MarbleColors.h"
73 #include "MapThemeDownloadDialog.h"
74 #include "MapWizard.h"
75 #include "MarbleWidgetInputHandler.h"
76 #include "Planet.h"
77 #include "cloudsync/CloudSyncManager.h"
78 #include "cloudsync/BookmarkSyncManager.h"
79 #include "cloudsync/RouteSyncManager.h"
80 #include "MovieCaptureDialog.h"
81 #include "DataMigration.h"
82 #include "TileCoordsPyramid.h"
83 
84 using namespace Marble;
85 /* TRANSLATOR Marble::MainWindow */
86 
MainWindow(const QString & marbleDataPath,const QVariantMap & cmdLineSettings,QWidget * parent)87 MainWindow::MainWindow(const QString& marbleDataPath, const QVariantMap& cmdLineSettings, QWidget *parent) :
88         QMainWindow(parent),
89         m_controlView( nullptr ),
90         m_savedSize( QSize(-1, -1) ),
91         m_sunControlDialog( nullptr ),
92         m_timeControlDialog( nullptr ),
93         m_configDialog( nullptr ),
94         m_downloadRegionDialog( nullptr ),
95         m_movieCaptureDialog( nullptr ),
96 
97         // File Menu
98         m_fileMenu( nullptr ),
99         m_viewMenu( nullptr ),
100         m_helpMenu( nullptr ),
101         m_settingsMenu( nullptr ),
102         m_panelMenu( nullptr ),
103         m_viewSizeMenu( nullptr ),
104         m_infoBoxesMenu( nullptr ),
105         m_onlineServicesMenu( nullptr ),
106         m_bookmarkMenu( nullptr ),
107         m_openAction( nullptr ),
108         m_exportMapAction( nullptr ),
109         m_downloadAction( nullptr ),
110         m_downloadRegionAction( nullptr ),
111         m_printPreviewAction( nullptr ),
112         m_printAction( nullptr ),
113         m_workOfflineAction( nullptr ),
114         m_quitAction( nullptr ),
115         m_mapWizardAction( nullptr ),
116 
117         // Edit Menu
118         m_copyMapAction( nullptr ),
119         m_copyCoordinatesAction( nullptr ),
120         m_osmEditAction( nullptr ),
121         m_recordMovieAction( nullptr ),
122         m_stopRecordingAction( nullptr ),
123 
124         // View Menu
125         m_showCloudsAction( nullptr ),\
126         m_controlSunAction( nullptr ),
127         m_controlTimeAction( nullptr ),
128         m_reloadAction( nullptr ),
129 
130         // Settings Menu
131         m_fullScreenAction( nullptr ),
132         m_statusBarAction( nullptr ),
133         m_configDialogAction( nullptr ),
134         m_viewSizeActsGroup( nullptr ),
135 
136         // Help Menu
137         m_whatsThisAction( nullptr ),
138         m_aboutMarbleAction( nullptr ),
139         m_aboutQtAction( nullptr ),
140         m_lockFloatItemsAction( nullptr ),
141         m_handbookAction( nullptr ),
142         m_forumAction( nullptr ),
143 
144         // Status Bar
145         m_positionLabel( nullptr ),
146         m_distanceLabel( nullptr ),
147         m_zoomLabel( nullptr ),
148         m_clockLabel( nullptr ),
149         m_downloadProgressBar( nullptr ),
150         m_toggleTileLevelAction( nullptr ),
151         m_angleDisplayUnitActionGroup( nullptr ),
152         m_dmsDegreeAction( nullptr ),
153         m_decimalDegreeAction( nullptr ),
154         m_utmAction( nullptr ),
155 
156         //Bookmark Menu
157         m_addBookmarkAction( nullptr ),
158         m_setHomeAction( nullptr ),
159         m_toggleBookmarkDisplayAction( nullptr ),
160         m_manageBookmarksAction( nullptr )
161 {
162     setUpdatesEnabled( false );
163 
164     QString selectedPath = marbleDataPath.isEmpty() ? readMarbleDataPath() : marbleDataPath;
165     if ( !selectedPath.isEmpty() )
166         MarbleDirs::setMarbleDataPath( selectedPath );
167 
168 #ifdef Q_OS_WIN
169 	QPointer<DataMigration> migration = new DataMigration(this);
170 	migration->exec();
171 #endif
172 
173     m_controlView = new ControlView( this );
174 
175     setWindowIcon(QIcon(QStringLiteral(":/icons/marble.png")));
176     setCentralWidget( m_controlView );
177 
178     // Initializing config dialog
179     m_configDialog = new QtMarbleConfigDialog( m_controlView->marbleWidget(),
180                                                m_controlView->cloudSyncManager(),
181                                                this );
182     connect( m_configDialog, SIGNAL(settingsChanged()),
183              this, SLOT(updateSettings()) );
184     connect( m_configDialog, SIGNAL(clearVolatileCacheClicked()),
185              m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) );
186     connect( m_configDialog, SIGNAL(clearPersistentCacheClicked()),
187              m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) );
188     connect( m_configDialog, SIGNAL(syncNowClicked()),
189              m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) );
190     connect(m_configDialog, SIGNAL(syncNowClicked()),
191             m_configDialog, SLOT(disableSyncNow()));
192 
193     connect(m_controlView->marbleModel()->fileManager(), &FileManager::fileError, this,
194         [this](const QString& path, const QString& error) {
195             QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses
196                    tr("Sorry, unable to open '%1':\n'%2'").arg(path).arg(error),
197                    QMessageBox::Ok);
198         });
199 
200     // Load bookmark file. If it does not exist, a default one will be used.
201     m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" );
202 
203     createActions();
204     QList<QAction*> const panelActions = m_controlView->setupDockWidgets( this );
205     createMenus( panelActions );
206     createStatusBar();
207 
208     connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
209              this, SLOT(updateMapEditButtonVisibility(QString)) );
210     connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)),
211             this, SLOT(updateWindowTitle()));
212     connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) );
213     connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) );
214 
215     updateWindowTitle();
216     setUpdatesEnabled( true );
217 
218     m_position =  QCoreApplication::translate( "Marble", NOT_AVAILABLE );
219     m_distance = marbleWidget()->distanceString();
220     m_zoom = QString::number( marbleWidget()->tileZoomLevel() );
221 
222     m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
223     QMetaObject::invokeMethod(this,
224                               "initObject", Qt::QueuedConnection,
225                               Q_ARG(QVariantMap, cmdLineSettings));
226 }
227 
~MainWindow()228 MainWindow::~MainWindow()
229 {
230     delete m_movieCaptureDialog;
231 }
232 
addGeoDataFile(const QString & fileName)233 void MainWindow::addGeoDataFile( const QString &fileName )
234 {
235     QFileInfo file( fileName );
236 
237     if ( !file.exists() )
238         return;
239 
240     // delay file loading to initObject(), such that restoring view from previous session in readSettings()
241     // doesn't interfere with focusing on these files
242     m_commandlineFilePaths << file.absoluteFilePath();
243 }
244 
initObject(const QVariantMap & cmdLineSettings)245 void MainWindow::initObject(const QVariantMap& cmdLineSettings)
246 {
247     QCoreApplication::processEvents ();
248     setupStatusBar();
249     readSettings(cmdLineSettings);
250 
251     for ( const QString &path: m_commandlineFilePaths ) {
252         m_controlView->marbleModel()->addGeoDataFile( path );
253     }
254 
255     if ( cmdLineSettings.contains( "tour" ) ) {
256         QString const tour = cmdLineSettings.value( "tour" ).toString();
257         m_controlView->openTour( tour );
258     }
259     m_commandlineFilePaths.clear();
260 }
261 
createActions()262 void MainWindow::createActions()
263  {
264      m_openAction = new QAction(QIcon(QStringLiteral(":/icons/document-open.png")), tr("&Open..."), this);
265      m_openAction->setShortcut( tr( "Ctrl+O" ) );
266      m_openAction->setStatusTip( tr( "Open a file for viewing on Marble"));
267      connect( m_openAction, SIGNAL(triggered()),
268               this, SLOT(openFile()) );
269 
270      m_downloadAction = new QAction(QIcon(QStringLiteral(":/icons/get-hot-new-stuff.png")), tr("&Download Maps..."), this);
271      connect(m_downloadAction, SIGNAL(triggered()), this, SLOT(openMapDialog()));
272 
273      m_exportMapAction = new QAction(QIcon(QStringLiteral(":/icons/document-save-as.png")), tr("&Export Map..."), this);
274      m_exportMapAction->setShortcut(tr("Ctrl+S"));
275      m_exportMapAction->setStatusTip(tr("Save a screenshot of the map"));
276      connect(m_exportMapAction, SIGNAL(triggered()), this, SLOT(exportMapScreenShot()));
277 
278      // Action: Download Region
279      m_downloadRegionAction = new QAction( tr( "Download &Region..." ), this );
280      m_downloadRegionAction->setStatusTip( tr( "Download a map region in different zoom levels for offline usage" ) );
281      connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()) );
282 
283      m_printAction = new QAction(QIcon(QStringLiteral(":/icons/document-print.png")), tr("&Print..."), this);
284      m_printAction->setShortcut(tr("Ctrl+P"));
285      m_printAction->setStatusTip(tr("Print a screenshot of the map"));
286      connect(m_printAction, SIGNAL(triggered()), this, SLOT(printMapScreenShot()));
287 
288      m_printPreviewAction = new QAction(QIcon(QStringLiteral(":/icons/document-print-preview.png")), tr("Print Previe&w ..."), this);
289      m_printPreviewAction->setStatusTip(tr("Print a screenshot of the map"));
290      connect(m_printPreviewAction, SIGNAL(triggered()), m_controlView, SLOT(printPreview()));
291 
292      m_quitAction = new QAction(QIcon(QStringLiteral(":/icons/application-exit.png")), tr("&Quit"), this);
293      m_quitAction->setShortcut(tr("Ctrl+Q"));
294      m_quitAction->setStatusTip(tr("Quit the Application"));
295      connect(m_quitAction, SIGNAL(triggered()), this, SLOT(close()));
296 
297      m_copyMapAction = new QAction(QIcon(QStringLiteral(":/icons/edit-copy.png")), tr("&Copy Map"), this);
298      m_copyMapAction->setShortcut(tr("Ctrl+C"));
299      m_copyMapAction->setStatusTip(tr("Copy a screenshot of the map"));
300      connect(m_copyMapAction, SIGNAL(triggered()), this, SLOT(copyMap()));
301 
302      m_osmEditAction = new QAction(QIcon(QStringLiteral(":/icons/edit-map.png")), tr("&Edit Map..."), this );
303      m_osmEditAction->setShortcut(tr( "Ctrl+E" ) );
304      m_osmEditAction->setStatusTip(tr( "Edit the current map region in an external editor" ) );
305      updateMapEditButtonVisibility( m_controlView->marbleWidget()->mapThemeId() );
306      connect( m_osmEditAction, SIGNAL(triggered()), m_controlView, SLOT(launchExternalMapEditor()) );
307 
308      m_recordMovieAction = new QAction(tr("&Record Movie"), this);
309      m_recordMovieAction->setStatusTip(tr("Records a movie of the globe"));
310      m_recordMovieAction->setShortcut(QKeySequence("Ctrl+Shift+R"));
311      m_recordMovieAction->setIcon(QIcon(QStringLiteral(":/icons/animator.png")));
312      connect(m_recordMovieAction, SIGNAL(triggered()),
313              this, SLOT(showMovieCaptureDialog()));
314 
315      m_stopRecordingAction = new QAction( tr("&Stop Recording"), this );
316      m_stopRecordingAction->setStatusTip( tr("Stop recording a movie of the globe") );
317      m_stopRecordingAction->setShortcut(QKeySequence( "Ctrl+Shift+S" ));
318      m_stopRecordingAction->setEnabled( false );
319      connect( m_stopRecordingAction, SIGNAL(triggered()),
320              this, SLOT(stopRecording()) );
321 
322      m_configDialogAction = new QAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure Marble"), this);
323      m_configDialogAction->setStatusTip(tr("Show the configuration dialog"));
324      connect(m_configDialogAction, SIGNAL(triggered()), this, SLOT(editSettings()));
325 
326      m_copyCoordinatesAction = new QAction(QIcon(QStringLiteral(":/icons/copy-coordinates.png")), tr("C&opy Coordinates"), this);
327      m_copyCoordinatesAction->setStatusTip(tr("Copy the center coordinates as text"));
328      connect(m_copyCoordinatesAction, SIGNAL(triggered()), this, SLOT(copyCoordinates()));
329 
330      m_fullScreenAction = new QAction(QIcon(QStringLiteral(":/icons/view-fullscreen.png")), tr("&Full Screen Mode"), this);
331      m_fullScreenAction->setShortcut(tr("Ctrl+Shift+F"));
332      m_fullScreenAction->setCheckable( true );
333      m_fullScreenAction->setStatusTip(tr("Full Screen Mode"));
334      connect(m_fullScreenAction, SIGNAL(triggered(bool)), this, SLOT(showFullScreen(bool)));
335 
336      m_statusBarAction = new QAction( tr("&Show Status Bar"), this);
337      m_statusBarAction->setCheckable( true );
338      m_statusBarAction->setStatusTip(tr("Show Status Bar"));
339      connect(m_statusBarAction, SIGNAL(triggered(bool)), this, SLOT(showStatusBar(bool)));
340 
341 
342      m_lockFloatItemsAction = new QAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("Lock Position"), this);
343      m_lockFloatItemsAction->setCheckable( true );
344      m_lockFloatItemsAction->setStatusTip(tr("Lock Position of Floating Items"));
345      connect(m_lockFloatItemsAction, SIGNAL(triggered(bool)), this, SLOT(lockPosition(bool)));
346 
347      m_showCloudsAction = new QAction(QIcon(QStringLiteral(":/icons/clouds.png")), tr("&Clouds"), this);
348      m_showCloudsAction->setCheckable( true );
349      m_showCloudsAction->setStatusTip(tr("Show Real Time Cloud Cover"));
350      connect(m_showCloudsAction, SIGNAL(triggered(bool)), this, SLOT(showClouds(bool)));
351 
352      m_workOfflineAction = new QAction(QIcon(QStringLiteral(":/icons/user-offline.png")), tr("Work Off&line"), this);
353      m_workOfflineAction->setCheckable( true );
354      connect(m_workOfflineAction, SIGNAL(triggered(bool)), this, SLOT(workOffline(bool)));
355 
356      m_controlTimeAction = new QAction(QIcon(QStringLiteral(":/icons/clock.png")), tr("&Time Control..."), this );
357      m_controlTimeAction->setStatusTip( tr( "Configure Time Control " ) );
358      connect( m_controlTimeAction, SIGNAL(triggered()), this, SLOT(controlTime()) );
359 
360      m_controlSunAction = new QAction( tr( "S&un Control..." ), this );
361      m_controlSunAction->setStatusTip( tr( "Configure Sun Control" ) );
362      connect( m_controlSunAction, SIGNAL(triggered()), this, SLOT(controlSun()) );
363 
364      m_reloadAction = new QAction(QIcon(QStringLiteral(":/icons/view-refresh.png")), tr("&Redisplay"), this);
365      m_reloadAction->setShortcut(tr("F5"));
366      m_reloadAction->setStatusTip(tr("Reload Current Map"));
367      connect(m_reloadAction, SIGNAL(triggered()), this, SLOT(reload()));
368 
369      m_handbookAction = new QAction(QIcon(QStringLiteral(":/icons/help-contents.png")), tr("Marble Virtual Globe &Handbook"), this);
370      m_handbookAction->setShortcut(tr("F1"));
371      m_handbookAction->setStatusTip(tr("Show the Handbook for Marble Virtual Globe"));
372      connect(m_handbookAction, SIGNAL(triggered()), this, SLOT(handbook()));
373 
374      m_whatsThisAction = new QAction(QIcon(QStringLiteral(":/icons/help-whatsthis.png")), tr("What's &This"), this);
375      m_whatsThisAction->setShortcut(tr("Shift+F1"));
376      m_whatsThisAction->setStatusTip(tr("Show a detailed explanation of the action."));
377      connect(m_whatsThisAction, SIGNAL(triggered()), this, SLOT(enterWhatsThis()));
378 
379      m_forumAction = new QAction( tr("&Community Forum"), this);
380      m_forumAction->setStatusTip(tr("Visit Marble's Community Forum"));
381      connect(m_forumAction, SIGNAL(triggered()), this, SLOT(openForum()));
382 
383      m_aboutMarbleAction = new QAction(QIcon(QStringLiteral(":/icons/marble.png")), tr("&About Marble Virtual Globe"), this);
384      m_aboutMarbleAction->setStatusTip(tr("Show the application's About Box"));
385      connect(m_aboutMarbleAction, SIGNAL(triggered()), this, SLOT(aboutMarble()));
386 
387      m_aboutQtAction = new QAction(tr("About &Qt"), this);
388      m_aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
389      connect(m_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
390 
391      //Bookmark Actions
392      m_addBookmarkAction = new QAction(QIcon(QStringLiteral(":/icons/bookmark-new.png")), tr("Add &Bookmark..."), this);
393      m_addBookmarkAction->setShortcut(tr("Ctrl+B"));
394      m_addBookmarkAction->setStatusTip(tr("Add Bookmark"));
395      connect( m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(openEditBookmarkDialog()) );
396 
397      m_setHomeAction = new QAction(QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Set Home Location"), this);
398      m_setHomeAction->setStatusTip( tr( "&Set Home Location" ) );
399      connect( m_setHomeAction, SIGNAL(triggered()), this, SLOT(setHome()) );
400 
401      m_toggleBookmarkDisplayAction = new QAction(tr( "Show &Bookmarks" ), this);
402      m_toggleBookmarkDisplayAction->setStatusTip( tr( "Toggle display of Bookmarks" ) );
403      m_toggleBookmarkDisplayAction->setCheckable( true );
404      connect( m_toggleBookmarkDisplayAction, SIGNAL(triggered(bool)), this, SLOT(showBookmarks(bool)) );
405 
406      m_manageBookmarksAction = new QAction(QIcon(QStringLiteral(":/icons/bookmarks-organize.png")), tr("&Manage Bookmarks..."), this);
407      m_manageBookmarksAction->setStatusTip( tr( "Manage Bookmarks" ) );
408      connect( m_manageBookmarksAction, SIGNAL(triggered()), this, SLOT(manageBookmarks()) );
409 
410      // Map Wizard action
411      m_mapWizardAction = new QAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), this);
412      m_mapWizardAction->setStatusTip( tr( "A wizard guides you through the creation of your own map theme." ) );
413      connect( m_mapWizardAction, SIGNAL(triggered()), SLOT(showMapWizard()) );
414 
415      // Statusbar Actions
416      m_toggleTileLevelAction = new QAction( tr( "Show Tile Zoom Level" ), statusBar() );
417      m_toggleTileLevelAction->setCheckable( true );
418      m_toggleTileLevelAction->setChecked( false );
419      connect( m_toggleTileLevelAction, SIGNAL(triggered(bool)),
420               this, SLOT(showZoomLevel(bool)) );
421 
422      m_angleDisplayUnitActionGroup = new QActionGroup( statusBar() );
423 
424      m_dmsDegreeAction = new QAction( tr( "Degree (DMS)" ), statusBar() );
425      m_dmsDegreeAction->setCheckable( true );
426      m_dmsDegreeAction->setData( (int)DMSDegree );
427      m_angleDisplayUnitActionGroup->addAction(m_dmsDegreeAction);
428 
429      m_decimalDegreeAction = new QAction( tr( "Degree (Decimal)" ), statusBar() );
430      m_decimalDegreeAction->setCheckable( true );
431      m_decimalDegreeAction->setData( (int)DecimalDegree );
432      m_angleDisplayUnitActionGroup->addAction(m_decimalDegreeAction);
433 
434      m_utmAction = new QAction( tr( "Universal Transverse Mercator (UTM)" ), statusBar() );
435      m_utmAction->setCheckable( true );
436      m_utmAction->setData( (int)UTM );
437      m_angleDisplayUnitActionGroup->addAction(m_utmAction);
438 
439      connect( m_angleDisplayUnitActionGroup, SIGNAL(triggered(QAction*)),
440               this, SLOT(changeAngleDisplayUnit(QAction*)) );
441 
442      // View size actions
443      m_viewSizeActsGroup = ControlView::createViewSizeActionGroup( this );
444      connect( m_viewSizeActsGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeViewSize(QAction*)) );
445 }
446 
createMenus(const QList<QAction * > & panelActions)447 void MainWindow::createMenus( const QList<QAction*> &panelActions )
448 {
449         m_fileMenu = menuBar()->addMenu(tr("&File"));
450         m_fileMenu->addAction(m_openAction);
451         m_fileMenu->addAction(m_downloadAction);
452         m_fileMenu->addAction( m_downloadRegionAction );
453         m_fileMenu->addAction( m_mapWizardAction );
454         m_fileMenu->addAction(m_exportMapAction);
455         m_fileMenu->addSeparator();
456         m_fileMenu->addAction(m_printAction);
457         m_fileMenu->addAction(m_printPreviewAction);
458         m_fileMenu->addSeparator();
459         m_fileMenu->addAction(m_workOfflineAction);
460         m_fileMenu->addAction(m_quitAction);
461 
462         m_fileMenu = menuBar()->addMenu(tr("&Edit"));
463         m_fileMenu->addAction(m_copyMapAction);
464         m_fileMenu->addAction(m_copyCoordinatesAction);
465         m_fileMenu->addAction( m_osmEditAction );
466         m_fileMenu->addSeparator();
467         m_fileMenu->addAction(m_recordMovieAction);
468         m_fileMenu->addAction(m_stopRecordingAction);
469 
470         m_viewMenu = menuBar()->addMenu(tr("&View"));
471         m_infoBoxesMenu = new QMenu(tr("&Info Boxes"), this);
472         m_onlineServicesMenu = new QMenu(tr("&Online Services"), this);
473         createPluginsMenus();
474 
475         m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks"));
476         createBookmarkMenu();
477         connect( m_bookmarkMenu, SIGNAL(aboutToShow()), this, SLOT(createBookmarkMenu()) );
478 
479         m_panelMenu = new QMenu(tr("&Panels"), this);
480         for( QAction* action: panelActions ) {
481             m_panelMenu->addAction( action );
482         }
483 
484         m_viewSizeMenu = new QMenu(tr("&View Size"), this);
485         m_viewSizeMenu->addActions( m_viewSizeActsGroup->actions() );
486 
487         m_settingsMenu = menuBar()->addMenu(tr("&Settings"));
488         m_settingsMenu->addMenu( m_panelMenu );
489         m_settingsMenu->addAction(m_statusBarAction);
490         m_settingsMenu->addSeparator();
491         m_settingsMenu->addMenu( m_viewSizeMenu );
492         m_settingsMenu->addAction(m_fullScreenAction);
493         m_settingsMenu->addSeparator();
494         m_settingsMenu->addAction(m_configDialogAction);
495 
496         m_helpMenu = menuBar()->addMenu(tr("&Help"));
497         m_helpMenu->addAction(m_handbookAction);
498         m_helpMenu->addAction(m_forumAction);
499         m_helpMenu->addSeparator();
500         m_helpMenu->addAction(m_whatsThisAction);
501         m_helpMenu->addSeparator();
502         m_helpMenu->addAction(m_aboutMarbleAction);
503         m_helpMenu->addAction(m_aboutQtAction);
504 
505         // FIXME: Discuss if this is the best place to put this
506         QList<RenderPlugin *> pluginList = m_controlView->marbleWidget()->renderPlugins();
507         QList<RenderPlugin *>::const_iterator it = pluginList.constBegin();
508         QList<RenderPlugin *>::const_iterator const listEnd = pluginList.constEnd();
509         for (; it != listEnd; ++it ) {
510             connect( (*it), SIGNAL(actionGroupsChanged()),
511                      this, SLOT(createPluginMenus()) );
512         }
513 }
514 
createPluginsMenus()515 void MainWindow::createPluginsMenus()
516 {
517     m_onlineServicesMenu->clear();
518     m_infoBoxesMenu->clear();
519     m_viewMenu->clear();
520 
521     m_viewMenu->addAction(m_reloadAction);
522     m_viewMenu->addSeparator();
523 
524     // Do not create too many menu entries on a MID
525     // FIXME: Set up another way of switching the plugins on and off.
526     if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
527         return;
528     }
529 
530     m_infoBoxesMenu->addAction(m_lockFloatItemsAction);
531     m_infoBoxesMenu->addSeparator();
532     QList<QAction*> themeActions;
533 
534     QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
535     QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
536     QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
537     for (; i != end; ++i ) {
538         switch( (*i)->renderType() ) {
539         case RenderPlugin::TopLevelRenderType:
540             m_viewMenu->addAction( (*i)->action() );
541             break;
542         case RenderPlugin::PanelRenderType:
543             m_infoBoxesMenu->addAction( (*i)->action() );
544             break;
545         case RenderPlugin::OnlineRenderType:
546             m_onlineServicesMenu->addAction( (*i)->action() );
547             break;
548         case RenderPlugin::ThemeRenderType:
549             themeActions.append( (*i)->action() );
550             break;
551         default:
552             mDebug() << "No menu entry created for plugin with unknown render type:" << (*i)->nameId();
553             break;
554         }
555     }
556     m_viewMenu->addMenu( m_infoBoxesMenu );
557     m_viewMenu->addMenu( m_onlineServicesMenu );
558     m_viewMenu->addActions( themeActions );
559     m_viewMenu->addAction( m_showCloudsAction );
560     m_viewMenu->addSeparator();
561     m_viewMenu->addAction(m_controlSunAction);
562     m_viewMenu->addAction(m_controlTimeAction);
563 }
564 
createBookmarksListMenu(QMenu * bookmarksListMenu,const GeoDataContainer * container)565 void MainWindow::createBookmarksListMenu( QMenu *bookmarksListMenu, const GeoDataContainer *container )
566 {
567     //m_bookmarksListMenu->clear();
568 
569     QVector<GeoDataPlacemark*> bookmarks = container->placemarkList();
570 
571     for ( const GeoDataPlacemark *placemark: bookmarks ) {
572         QAction *bookmarkAction = new QAction( placemark->name(), this );
573         QVariant var;
574 
575         const GeoDataLookAt* lookAt = placemark->lookAt();
576         if ( !lookAt ) {
577             GeoDataCoordinates coordinates = placemark->coordinate();
578             GeoDataLookAt coordinateToLookAt;
579             coordinateToLookAt.setCoordinates( coordinates );
580             coordinateToLookAt.setRange( marbleWidget()->lookAt().range() );
581             var.setValue( coordinateToLookAt );
582         } else {
583             var.setValue( *lookAt );
584         }
585         bookmarkAction->setData( var );
586         bookmarksListMenu->addAction( bookmarkAction );
587     }
588 
589 }
createBookmarkMenu()590 void MainWindow::createBookmarkMenu()
591 {
592     m_bookmarkMenu->clear();
593     m_bookmarkMenu->addAction( m_addBookmarkAction );
594     m_bookmarkMenu->addAction( m_toggleBookmarkDisplayAction );
595     m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->document()->isVisible() );
596     m_bookmarkMenu->addAction( m_setHomeAction );
597     m_bookmarkMenu->addAction( m_manageBookmarksAction );
598 
599     m_bookmarkMenu->addSeparator();
600 
601     m_bookmarkMenu->addAction( QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Home"),
602                                m_controlView->marbleWidget(), SLOT(goHome()) );
603     createFolderList( m_bookmarkMenu, m_controlView->marbleModel()->bookmarkManager()->document() );
604 }
605 
createFolderList(QMenu * bookmarksListMenu,const GeoDataContainer * container)606 void MainWindow::createFolderList( QMenu *bookmarksListMenu, const GeoDataContainer *container )
607 {
608     QVector<GeoDataFolder*> folders = container->folderList();
609 
610     if ( folders.size() == 1 && folders.first()->name() == tr("Default")) {
611         createBookmarksListMenu( bookmarksListMenu, folders.first() );
612     }
613     else {
614         for ( const GeoDataFolder *folder: folders ) {
615             QMenu *subMenu = bookmarksListMenu->addMenu(QIcon(QStringLiteral(":/icons/folder-bookmark.png")), folder->name());
616             createFolderList( subMenu, folder );
617             connect( subMenu, SIGNAL(triggered(QAction*)),
618                                       this, SLOT(lookAtBookmark(QAction*)) );
619         }
620     }
621 
622     createBookmarksListMenu( bookmarksListMenu, container );
623     connect( bookmarksListMenu, SIGNAL(triggered(QAction*)),
624                               this, SLOT(lookAtBookmark(QAction*)) );
625 }
626 
627 
lookAtBookmark(QAction * action)628 void MainWindow::lookAtBookmark( QAction *action)
629 {
630     if ( action->data().isNull() ) {
631         return;
632     }
633 
634     GeoDataLookAt temp = qvariant_cast<GeoDataLookAt>( action->data() ) ;
635     m_controlView->marbleWidget()->flyTo( temp ) ;
636     mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree)
637              << " latitude :  "<< temp.latitude(GeoDataCoordinates::Degree)
638              << " distance : " << temp.range();
639 
640 
641 }
642 
manageBookmarks()643 void MainWindow::manageBookmarks()
644 {
645     MarbleModel * const model = m_controlView->marbleModel();
646     QPointer<BookmarkManagerDialog> dialog = new BookmarkManagerDialog( model, this );
647     dialog->exec();
648     delete dialog;
649 }
650 
setHome()651 void MainWindow::setHome()
652 {
653     MarbleWidget *widget = m_controlView->marbleWidget();
654     widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() );
655 }
656 
openEditBookmarkDialog()657 void MainWindow::openEditBookmarkDialog()
658 {
659     MarbleWidget *widget = m_controlView->marbleWidget();
660     QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget );
661     dialog->setMarbleWidget( widget );
662     dialog->setCoordinates( widget->lookAt().coordinates() );
663     dialog->setRange( widget->lookAt().range() );
664     dialog->setReverseGeocodeName();
665     if ( dialog->exec() == QDialog::Accepted ) {
666         widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() );
667     }
668     delete dialog;
669 }
670 
createPluginMenus()671 void MainWindow::createPluginMenus()
672 {
673     // Remove and delete toolbars if they exist
674     while( !m_pluginToolbars.isEmpty() ) {
675         QToolBar* tb = m_pluginToolbars.takeFirst();
676         this->removeToolBar(tb);
677         tb->deleteLater();
678     }
679 
680     // Do not create too many menu entries on a MID
681     // FIXME: Set up another way of switching the plugins on and off.
682     if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
683         return;
684     }
685 
686     //remove and delete old menus if they exist
687     while(  !m_pluginMenus.isEmpty() ) {
688         m_viewMenu->removeAction( m_pluginMenus.takeFirst() );
689     }
690 
691     QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
692     QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
693     QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
694 
695     for (; i != end; ++i ) {
696 
697         // menus
698         const QList<QActionGroup*> *tmp_actionGroups = (*i)->actionGroups();
699         if ((*i)->enabled() && tmp_actionGroups && (*i)->nameId() != QLatin1String("annotation")) {
700            for( QActionGroup *ag: *tmp_actionGroups ) {
701                if( !ag->actions().isEmpty() ) {
702                    m_pluginMenus.append( m_viewMenu->addSeparator() );
703                }
704                for( QAction *action: ag->actions() ) {
705                    m_viewMenu->addAction( action );
706                    m_pluginMenus.append( action );
707                }
708            }
709         }
710 
711         // toolbars
712         const QList<QActionGroup*> *tmp_toolbarActionGroups = (*i)->toolbarActionGroups();
713         if ( (*i)->enabled() && tmp_toolbarActionGroups ) {
714             QToolBar* toolbar = new QToolBar(this);
715             toolbar->setObjectName(QLatin1String("plugin-toolbar-") + (*i)->nameId());
716 
717             for( QActionGroup* ag: *tmp_toolbarActionGroups ) {
718                 toolbar->addActions( ag->actions() );
719                 if ( tmp_toolbarActionGroups->last() != ag ) {
720                     toolbar->addSeparator();
721                 }
722             }
723 
724             m_pluginToolbars.append( toolbar );
725             this->addToolBar( toolbar );
726         }
727     }
728 
729 //    FIXME: load the menus once the method has been settled on
730 }
731 
createStatusBar()732 void MainWindow::createStatusBar()
733 {
734     statusBar()->showMessage(tr("Ready"));
735     statusBar()->hide();
736 }
737 
openMapDialog()738 void MainWindow::openMapDialog()
739 {
740     QPointer<MapThemeDownloadDialog> dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) );
741     dialog->exec();
742     delete dialog;
743 }
744 
exportMapScreenShot()745 void MainWindow::exportMapScreenShot()
746 {
747     QString fileName = QFileDialog::getSaveFileName(this, tr("Export Map"), // krazy:exclude=qclasses
748                             QDir::homePath(),
749                             tr("Images (*.jpg *.png)"));
750 
751     if ( !fileName.isEmpty() )
752     {
753         // Take the case into account where no file format is indicated
754         const char * format = nullptr;
755         if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive)
756            && !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) )
757         {
758             format = "JPG";
759         }
760 
761         QPixmap mapPixmap = m_controlView->mapScreenShot();
762         bool success = mapPixmap.save( fileName, format );
763         if ( !success )
764         {
765             QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses
766                    tr( "An error occurred while trying to save the file.\n" ),
767                    QMessageBox::Ok);
768         }
769     }
770 }
771 
772 
showFullScreen(bool isChecked)773 void MainWindow::showFullScreen( bool isChecked )
774 {
775     if ( isChecked ) {
776         setWindowState( windowState() | Qt::WindowFullScreen ); // set
777     }
778     else {
779         setWindowState( windowState() & ~Qt::WindowFullScreen ); // reset
780     }
781 
782     m_fullScreenAction->setChecked( isChecked ); // Sync state with the GUI
783 }
784 
copyCoordinates()785 void MainWindow::copyCoordinates()
786 {
787     qreal lon = m_controlView->marbleWidget()->centerLongitude();
788     qreal lat = m_controlView->marbleWidget()->centerLatitude();
789 
790     QString  positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString();
791     QClipboard  *clipboard = QApplication::clipboard();
792 
793     clipboard->setText( positionString );
794 }
795 
copyMap()796 void MainWindow::copyMap()
797 {
798     QPixmap      mapPixmap = m_controlView->mapScreenShot();
799     QClipboard  *clipboard = QApplication::clipboard();
800 
801     clipboard->setPixmap( mapPixmap );
802 }
803 
showStatusBar(bool isChecked)804 void MainWindow::showStatusBar( bool isChecked )
805 {
806     if ( isChecked )
807     {
808         statusBar()->show();
809     }
810     else
811     {
812         statusBar()->hide();
813     }
814 
815     m_statusBarAction->setChecked( isChecked ); // Sync state with the GUI
816 }
817 
showClouds(bool isChecked)818 void MainWindow::showClouds( bool isChecked )
819 {
820     m_controlView->marbleWidget()->setShowClouds( isChecked );
821 
822     m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI
823 }
824 
showBookmarks(bool show)825 void MainWindow::showBookmarks( bool show )
826 {
827     m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show );
828 
829     m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI
830 }
831 
workOffline(bool offline)832 void MainWindow::workOffline( bool offline )
833 {
834     m_controlView->setWorkOffline( offline );
835 
836     m_workOfflineAction->setChecked( offline ); // Sync state with the GUI
837 }
838 
lockPosition(bool isChecked)839 void MainWindow::lockPosition( bool isChecked )
840 {
841     QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
842 
843     QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
844     QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
845     for (; i != end; ++i )
846     {
847         // Locking one would suffice as it affects all.
848         // Nevertheless go through all.
849         (*i)->setPositionLocked(isChecked);
850     }
851 }
852 
controlSun()853 void MainWindow::controlSun()
854 {
855     if (!m_sunControlDialog) {
856         m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), this );
857         connect( m_sunControlDialog, SIGNAL(showSun(bool)),
858                  this,               SLOT (showSun(bool)) );
859     }
860 
861      m_sunControlDialog->show();
862      m_sunControlDialog->raise();
863      m_sunControlDialog->activateWindow();
864 }
865 
controlTime()866 void MainWindow::controlTime()
867 {
868     if ( !m_timeControlDialog )
869     {
870         m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() );
871     }
872     /* m_timeControlDialog is a modeless dialog so that user may adjust time and interact with main application simultaneously.*/
873     m_timeControlDialog->show();
874     m_timeControlDialog->raise();
875     m_timeControlDialog->activateWindow();
876 }
877 
878 
showSun(bool active)879 void MainWindow::showSun( bool active )
880 {
881     m_controlView->marbleWidget()->setShowSunShading( active );
882 }
883 
reload()884 void MainWindow::reload()
885 {
886     m_controlView->marbleWidget()->reloadMap();
887 }
888 
enterWhatsThis()889 void MainWindow::enterWhatsThis()
890 {
891     QWhatsThis::enterWhatsThisMode();
892 }
893 
aboutMarble()894 void MainWindow::aboutMarble()
895 {
896     MarbleAboutDialog dlg(this);
897     dlg.setApplicationTitle( tr( "Marble Virtual Globe %1" ).arg( ControlView::applicationVersion() ) );
898     dlg.exec();
899 }
900 
handbook()901 void MainWindow::handbook()
902 {
903     const QString code = MarbleLocale::languageCode();
904 
905     // docs.kde.org falls back to the English manual if no translated
906     // documentation is available for the requested language.
907     QUrl handbookLocation(QLatin1String("https://docs.kde.org/?application=marble&branch=stable5&language=") + code);
908 
909     if( !QDesktopServices::openUrl( handbookLocation ) )
910     qDebug() << "URL not opened";
911 }
912 
openForum()913 void MainWindow::openForum()
914 {
915     QUrl forumLocation("https://forum.kde.org/viewforum.php?f=217");
916     if( !QDesktopServices::openUrl( forumLocation ) ) {
917         mDebug() << "Failed to open URL " << forumLocation.toString();
918     }
919 }
920 
showPosition(const QString & position)921 void MainWindow::showPosition( const QString& position )
922 {
923     m_position = position;
924     updateStatusBar();
925 }
926 
showDistance(const QString & distance)927 void MainWindow::showDistance( const QString& distance )
928 {
929     m_distance = distance;
930     updateStatusBar();
931 }
932 
showZoom(int zoom)933 void MainWindow::showZoom( int zoom )
934 {
935     m_zoom = QString::number( zoom );
936     updateStatusBar();
937 }
938 
showDateTime()939 void MainWindow::showDateTime()
940 {
941     m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
942     updateStatusBar();
943 }
944 
updateStatusBar()945 void MainWindow::updateStatusBar()
946 {
947     if ( m_positionLabel )
948         m_positionLabel->setText(tr("Position: %1").arg(m_position));
949 
950     if ( m_distanceLabel )
951         m_distanceLabel->setText(tr("Altitude: %1").arg(m_distance));
952 
953     if ( m_zoomLabel )
954         m_zoomLabel->setText(tr("Zoom: %1").arg(m_zoom));
955 
956     if ( m_clockLabel )
957         m_clockLabel->setText(tr("Time: %1").arg(m_clock));
958 
959     switch ( m_configDialog->angleUnit() ) {
960     case DMSDegree:
961         m_dmsDegreeAction->setChecked( true );
962         break;
963     case DecimalDegree:
964         m_decimalDegreeAction->setChecked( true );
965         break;
966     case UTM:
967         m_utmAction->setChecked( true );
968         break;
969     }
970 }
971 
openFile()972 void MainWindow::openFile()
973 {
974     const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager();
975 
976     QStringList allFileExtensions;
977     QStringList filters;
978     for ( const ParseRunnerPlugin *plugin: pluginManager->parsingRunnerPlugins() ) {
979         if (plugin->nameId() == QLatin1String("Cache"))
980             continue;
981 
982         const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." );
983         const QString filter = plugin->fileFormatDescription() + QLatin1String(" (") + fileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
984         filters << filter;
985         allFileExtensions << fileExtensions;
986     }
987 
988     allFileExtensions.sort();  // sort since file extensions are visible under Windows
989     const QString allFileTypes = tr("All Supported Files") + QLatin1String(" (") + allFileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
990 
991     filters.sort();
992     filters.prepend( allFileTypes );
993     const QString filter = filters.join( ";;" );
994 
995     QStringList fileNames = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_lastFileOpenPath, filter );
996 
997     if ( !fileNames.isEmpty() ) {
998         const QString firstFile = fileNames.first();
999         m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath();
1000     }
1001 
1002     for( const QString &fileName: fileNames ) {
1003         m_controlView->marbleModel()->addGeoDataFile( fileName );
1004     }
1005 }
1006 
setupStatusBar()1007 void MainWindow::setupStatusBar()
1008 {
1009     statusBar()->setSizeGripEnabled( true );
1010     statusBar()->setContextMenuPolicy( Qt::ActionsContextMenu );
1011 
1012     statusBar()->addAction( m_toggleTileLevelAction );
1013 
1014     QMenu *angleDisplayUnitMenu = new QMenu(this);
1015     angleDisplayUnitMenu->addActions( m_angleDisplayUnitActionGroup->actions() );
1016     QAction *angleDisplayUnitMenuAction = new QAction( tr("&Angle Display Unit"), statusBar() );
1017     angleDisplayUnitMenuAction->setMenu( angleDisplayUnitMenu );
1018     statusBar()->addAction( angleDisplayUnitMenuAction );
1019 
1020     setupDownloadProgressBar();
1021 
1022     m_positionLabel = new QLabel( );
1023     m_positionLabel->setIndent( 5 );
1024     // UTM syntax is used in the template string, as it is longer than the lon/lat one
1025     QString templatePositionString = tr("Position: %1").arg(QLatin1String(" 00Z 000000.00 m E, 00000000.00 m N_"));
1026     int maxPositionWidth = fontMetrics().boundingRect(templatePositionString).width()
1027                             + 2 * m_positionLabel->margin() + 2 * m_positionLabel->indent();
1028     m_positionLabel->setFixedWidth( maxPositionWidth );
1029     statusBar()->addPermanentWidget ( m_positionLabel );
1030 
1031     m_distanceLabel = new QLabel( );
1032     m_distanceLabel->setIndent( 5 );
1033     QString templateDistanceString = tr("Altitude: %1").arg(QLatin1String(" 00.000,0 mu"));
1034     int maxDistanceWidth = fontMetrics().boundingRect(templateDistanceString).width()
1035                             + 2 * m_distanceLabel->margin() + 2 * m_distanceLabel->indent();
1036     m_distanceLabel->setFixedWidth( maxDistanceWidth );
1037     statusBar()->addPermanentWidget ( m_distanceLabel );
1038 
1039     m_zoomLabel = new QLabel( );
1040     m_zoomLabel->setIndent( 5 );
1041     QString templateZoomString = tr("Zoom: %1").arg(QLatin1String(" 00"));
1042     int maxZoomWidth = fontMetrics().boundingRect(templateZoomString).width()
1043                             + 2 * m_zoomLabel->margin() + 2 * m_zoomLabel->indent();
1044     m_zoomLabel->setFixedWidth( maxZoomWidth );
1045     // Not added here, but activated by the user with the context menu
1046 
1047     m_clockLabel = new QLabel( );
1048     m_clockLabel->setIndent( 5 );
1049     QString templateDateTimeString = tr("Time: %1").arg(QLocale().toString(QDateTime::fromString( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat));
1050     int maxDateTimeWidth = fontMetrics().boundingRect( templateDateTimeString ).width()
1051                             + 2 * m_clockLabel->margin() + 2 * m_clockLabel->indent();
1052     m_clockLabel->setFixedWidth( maxDateTimeWidth );
1053     statusBar()->addPermanentWidget ( m_clockLabel );
1054 
1055     connect( marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)),
1056               this, SLOT(showPosition(QString)) );
1057     connect( marbleWidget(), SIGNAL(distanceChanged(QString)),
1058               this, SLOT(showDistance(QString)) );
1059     connect( marbleWidget(), SIGNAL(tileLevelChanged(int)),
1060             this, SLOT(showZoom(int)) );
1061     connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()),
1062               this, SLOT(showDateTime()) );
1063 
1064     updateStatusBar();
1065 }
1066 
setupDownloadProgressBar()1067 void MainWindow::setupDownloadProgressBar()
1068 {
1069     m_downloadProgressBar = new QProgressBar;
1070     m_downloadProgressBar->setVisible( true );
1071     statusBar()->addPermanentWidget( m_downloadProgressBar );
1072 
1073     HttpDownloadManager * const downloadManager =
1074         m_controlView->marbleModel()->downloadManager();
1075     Q_ASSERT( downloadManager );
1076     connect( downloadManager, SIGNAL(progressChanged(int,int)), SLOT(handleProgress(int,int)) );
1077     connect( downloadManager, SIGNAL(jobRemoved()), SLOT(removeProgressItem()) );
1078 }
1079 
handleProgress(int active,int queued)1080 void MainWindow::handleProgress( int active, int queued ){
1081     m_downloadProgressBar->setUpdatesEnabled( false );
1082     if ( m_downloadProgressBar->value() < 0 ) {
1083         m_downloadProgressBar->setMaximum( 1 );
1084         m_downloadProgressBar->setValue( 0 );
1085         m_downloadProgressBar->setVisible( true );
1086     } else {
1087         m_downloadProgressBar->setMaximum( qMax<int>( m_downloadProgressBar->maximum(), active + queued ) );
1088     }
1089 
1090     m_downloadProgressBar->setUpdatesEnabled( true );
1091 }
1092 
removeProgressItem()1093 void MainWindow::removeProgressItem(){
1094     m_downloadProgressBar->setUpdatesEnabled( false );
1095     m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 );
1096     if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) {
1097         m_downloadProgressBar->reset();
1098         m_downloadProgressBar->setVisible( false );
1099     }
1100 
1101     m_downloadProgressBar->setUpdatesEnabled( true );
1102 }
1103 
closeEvent(QCloseEvent * event)1104 void MainWindow::closeEvent( QCloseEvent *event )
1105 {
1106     writeSettings();
1107 
1108     QCloseEvent newEvent;
1109     QCoreApplication::sendEvent( m_controlView, &newEvent );
1110 
1111     if ( newEvent.isAccepted() ) {
1112         event->accept();
1113     } else {
1114         event->ignore();
1115     }
1116 }
1117 
readMarbleDataPath()1118 QString MainWindow::readMarbleDataPath()
1119 {
1120      QSettings settings;
1121 
1122      settings.beginGroup("MarbleWidget");
1123      const auto marbleDataPath = settings.value("marbleDataPath", "").toString();
1124      settings.endGroup();
1125 
1126      return marbleDataPath;
1127 }
1128 
readSettings(const QVariantMap & overrideSettings)1129 void MainWindow::readSettings(const QVariantMap& overrideSettings)
1130 {
1131      QSettings settings;
1132 
1133      settings.beginGroup("MainWindow");
1134          resize(settings.value("size", QSize(640, 480)).toSize());
1135          move(settings.value("pos", QPoint(200, 200)).toPoint());
1136          showFullScreen(settings.value("fullScreen", false ).toBool());
1137          showStatusBar(settings.value("statusBar", false ).toBool());
1138          showZoomLevel(settings.value("showZoomLevel",false).toBool());
1139          show();
1140          showClouds(settings.value("showClouds", true ).toBool());
1141          workOffline(settings.value("workOffline", false ).toBool());
1142          m_controlView->marbleWidget()->setShowAtmosphere(settings.value("showAtmosphere", true ).toBool());
1143          m_lastFileOpenPath = settings.value("lastFileOpenDir", QDir::homePath()).toString();
1144          showBookmarks( settings.value( "showBookmarks", true ).toBool() );
1145          restoreState( settings.value("windowState").toByteArray() );
1146      settings.endGroup();
1147 
1148      setUpdatesEnabled(false);
1149 
1150      settings.beginGroup("MarbleWidget");
1151          QString mapThemeId;
1152          const QVariantMap::ConstIterator mapThemeIdIt = overrideSettings.find(QLatin1String("mapTheme"));
1153          if ( mapThemeIdIt != overrideSettings.constEnd() ) {
1154             mapThemeId = mapThemeIdIt.value().toString();
1155          } else {
1156             mapThemeId = settings.value("mapTheme", m_controlView->defaultMapThemeId() ).toString();
1157          }
1158          mDebug() << Q_FUNC_INFO << "mapThemeId:" << mapThemeId;
1159          m_controlView->marbleWidget()->setMapThemeId( mapThemeId );
1160          m_controlView->marbleWidget()->setProjection(
1161             (Projection)(settings.value("projection", Spherical ).toInt())
1162          );
1163 
1164          // Set home position
1165          m_controlView->marbleModel()->setHome(
1166             settings.value("homeLongitude", 9.4).toDouble(),
1167             settings.value("homeLatitude", 54.8).toDouble(),
1168             settings.value("homeZoom", 1050 ).toInt()
1169          );
1170 
1171          // Center on/Distance
1172          const QVariantMap::ConstIterator distanceIt = overrideSettings.find(QLatin1String("distance"));
1173          const bool isDistanceOverwritten = (distanceIt != overrideSettings.constEnd());
1174 
1175          const QVariantMap::ConstIterator lonLatIt = overrideSettings.find(QLatin1String("lonlat"));
1176          if ( lonLatIt != overrideSettings.constEnd() ) {
1177             const QVariantList lonLat = lonLatIt.value().toList();
1178             m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() );
1179          } else {
1180             switch ( m_configDialog->onStartup() ) {
1181             case Marble::LastLocationVisited:
1182                 m_controlView->marbleWidget()->centerOn(
1183                     settings.value("quitLongitude", 0.0).toDouble(),
1184                     settings.value("quitLatitude", 0.0).toDouble() );
1185                 if (! isDistanceOverwritten) {
1186                     // set default radius to 1350 (Atlas theme's "sharp" radius)
1187                     m_controlView->marbleWidget()->setRadius( settings.value("quitRadius", 1350).toInt() );
1188                 }
1189                 break;
1190             case Marble::ShowHomeLocation:
1191                 m_controlView->marbleWidget()->goHome();
1192                 break;
1193             default:
1194                 break;
1195             }
1196          }
1197          if (isDistanceOverwritten) {
1198              m_controlView->marbleWidget()->setDistance(distanceIt.value().toDouble());
1199          }
1200 
1201          // Geo URI parsing
1202          QString geoUriString = qvariant_cast<QString>( overrideSettings.value("geo-uri", ""));
1203          if ( !geoUriString.isEmpty() ) {
1204              m_controlView->openGeoUri( geoUriString );
1205          }
1206 
1207          bool isLocked = settings.value( "lockFloatItemPositions", false ).toBool();
1208          m_lockFloatItemsAction->setChecked( isLocked );
1209          lockPosition(isLocked);
1210      settings.endGroup();
1211 
1212      settings.beginGroup( "Sun" );
1213          m_controlView->marbleWidget()->setShowSunShading( settings.value( "showSun", false ).toBool() );
1214          m_controlView->marbleWidget()->setShowCityLights( settings.value( "showCitylights", false ).toBool() );
1215          m_controlView->marbleWidget()->setLockToSubSolarPoint( settings.value( "lockToSubSolarPoint", false ).toBool() );
1216          m_controlView->marbleWidget()->setSubSolarPointIconVisible( settings.value( "subSolarPointIconVisible", false ).toBool() );
1217      settings.endGroup();
1218 
1219      settings.beginGroup( "Time" );
1220         if( settings.value( "systemTime", "true" ).toBool() == true  )
1221         {
1222             /* nothing to do */
1223         }
1224         else if( settings.value( "lastSessionTime", "true" ).toBool() == true )
1225         {
1226             m_controlView->marbleModel()->setClockDateTime( settings.value( "dateTime" ).toDateTime() );
1227             m_controlView->marbleModel()->setClockSpeed( settings.value( "speedSlider", 1 ).toInt() );
1228         }
1229      settings.endGroup();
1230 
1231      setUpdatesEnabled(true);
1232 
1233      // Load previous route settings
1234      settings.beginGroup( "Routing" );
1235      {
1236          RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager();
1237          routingManager->readSettings();
1238          bool const startupWarning = settings.value( "showGuidanceModeStartupWarning", QVariant( true ) ).toBool();
1239          routingManager->setShowGuidanceModeStartupWarning( startupWarning );
1240          routingManager->setLastOpenPath( settings.value( "lastRouteOpenPath", QDir::homePath() ).toString() );
1241          routingManager->setLastSavePath( settings.value( "lastRouteSavePath", QDir::homePath() ).toString() );
1242 
1243          QColor tempColor;
1244          tempColor = QColor( settings.value( "routeColorStandard", Oxygen::skyBlue4.name() ).toString() );
1245          tempColor.setAlpha( settings.value( "routeAlphaStandard", 200 ).toInt() );
1246          routingManager->setRouteColorStandard( tempColor );
1247 
1248          tempColor = QColor( settings.value( "routeColorHighlighted", Oxygen::skyBlue1.name() ).toString() );
1249          tempColor.setAlpha( settings.value( "routeAlphaHighlighted", 200 ).toInt() );
1250          routingManager->setRouteColorHighlighted( tempColor );
1251 
1252          tempColor = QColor( settings.value( "routeColorAlternative", Oxygen::aluminumGray4.name() ).toString() );
1253          tempColor.setAlpha( settings.value( "routeAlphaAlternative", 200 ).toInt() );
1254          routingManager->setRouteColorAlternative( tempColor );
1255      }
1256      settings.endGroup();
1257 
1258 
1259     settings.beginGroup( "Routing Profile" );
1260     if ( settings.contains( "Num" ) ) {
1261         QList<RoutingProfile> profiles;
1262         int numProfiles = settings.value( "Num", 0 ).toInt();
1263         for ( int i = 0; i < numProfiles; ++i ) {
1264             settings.beginGroup( QString( "Profile %0" ).arg(i) );
1265             QString name = settings.value( "Name", tr( "Unnamed" ) ).toString();
1266             RoutingProfile profile( name );
1267             for ( const QString& pluginName: settings.childGroups() ) {
1268                 settings.beginGroup( pluginName );
1269                 profile.pluginSettings().insert( pluginName, QHash<QString, QVariant>() );
1270                 for ( const QString& key: settings.childKeys() ) {
1271                     if (key != QLatin1String("Enabled")) {
1272                         profile.pluginSettings()[ pluginName ].insert( key, settings.value( key ) );
1273                     }
1274                 }
1275                 settings.endGroup();
1276             }
1277             profiles << profile;
1278             settings.endGroup();
1279         }
1280         m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles );
1281     } else {
1282         m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles();
1283     }
1284     int const profileIndex = settings.value( "currentIndex", 0 ).toInt();
1285     if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) {
1286         RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex );
1287         m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile );
1288     }
1289 
1290     settings.endGroup();
1291 
1292     settings.beginGroup( "Plugins");
1293     PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
1294     tracking->readSettings();
1295     QString positionProvider = settings.value( "activePositionTrackingPlugin", QString() ).toString();
1296     if ( !positionProvider.isEmpty() ) {
1297         const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager();
1298         for( const PositionProviderPlugin* plugin: pluginManager->positionProviderPlugins() ) {
1299             if ( plugin->nameId() == positionProvider ) {
1300                 PositionProviderPlugin* instance = plugin->newInstance();
1301                 tracking->setPositionProviderPlugin( instance );
1302                 break;
1303             }
1304         }
1305     }
1306     settings.endGroup();
1307 
1308     settings.beginGroup( "Tracking" );
1309     if ( settings.contains( "autoCenter" ) || settings.contains( "recenterMode" ) ) {
1310         CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget();
1311         Q_ASSERT( trackingWidget );
1312         trackingWidget->setRecenterMode( settings.value( "recenterMode", 0 ).toInt() );
1313         trackingWidget->setAutoZoom( settings.value( "autoZoom", false ).toBool() );
1314         trackingWidget->setTrackVisible( settings.value( "trackVisible", true ).toBool() );
1315         trackingWidget->setLastOpenPath( settings.value( "lastTrackOpenPath", QDir::homePath() ).toString() );
1316         trackingWidget->setLastSavePath( settings.value( "lastTrackSavePath", QDir::homePath() ).toString() );
1317     }
1318     settings.endGroup();
1319 
1320      // The config dialog has to read settings.
1321      m_configDialog->readSettings();
1322 
1323      settings.beginGroup( "Navigation" );
1324      m_controlView->setExternalMapEditor( settings.value( "externalMapEditor", "" ).toString() );
1325      settings.endGroup();
1326 
1327      settings.beginGroup( "CloudSync" );
1328      CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
1329      cloudSyncManager->setOwncloudCredentials( settings.value( "owncloudServer", "" ).toString(),
1330                                                settings.value( "owncloudUsername", "" ).toString(),
1331                                                settings.value( "owncloudPassword", "" ).toString() );
1332      cloudSyncManager->setSyncEnabled( settings.value( "enableSync", false ).toBool() );
1333      cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( settings.value( "syncRoutes", true ).toBool() );
1334      cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( settings.value( "syncBookmarks", true ).toBool() );
1335      settings.endGroup();
1336 }
1337 
writeSettings()1338 void MainWindow::writeSettings()
1339 {
1340      QSettings settings;
1341 
1342      settings.beginGroup( "MainWindow" );
1343          settings.setValue( "size", size() );
1344          settings.setValue( "pos", pos() );
1345          settings.setValue( "fullScreen", m_fullScreenAction->isChecked() );
1346          settings.setValue( "statusBar", m_statusBarAction->isChecked() );
1347          settings.setValue( "showZoomLevel", m_toggleTileLevelAction->isChecked() );
1348          settings.setValue( "showClouds", m_showCloudsAction->isChecked() );
1349          settings.setValue( "workOffline", m_workOfflineAction->isChecked() );
1350          settings.setValue( "showAtmosphere", m_controlView->marbleWidget()->showAtmosphere() );
1351          settings.setValue( "lastFileOpenDir", m_lastFileOpenPath );
1352          settings.setValue( "showBookmarks", m_toggleBookmarkDisplayAction->isChecked() );
1353          settings.setValue( "windowState", saveState() );
1354      settings.endGroup();
1355 
1356      settings.beginGroup( "MarbleWidget" );
1357          // Get the 'home' values from the widget and store them in the settings.
1358          qreal homeLon = 0;
1359          qreal homeLat = 0;
1360          int homeZoom = 0;
1361          m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom );
1362          QString  mapTheme = m_controlView->marbleWidget()->mapThemeId();
1363          int      projection = (int)( m_controlView->marbleWidget()->projection() );
1364 
1365          settings.setValue( "homeLongitude", homeLon );
1366          settings.setValue( "homeLatitude",  homeLat );
1367          settings.setValue( "homeZoom",      homeZoom );
1368 
1369          settings.setValue( "mapTheme",   mapTheme );
1370          settings.setValue( "projection", projection );
1371 
1372          // Get the 'quit' values from the widget and store them in the settings.
1373          qreal  quitLon = m_controlView->marbleWidget()->centerLongitude();
1374          qreal  quitLat = m_controlView->marbleWidget()->centerLatitude();
1375          const int quitRadius = m_controlView->marbleWidget()->radius();
1376 
1377          settings.setValue( "quitLongitude", quitLon );
1378          settings.setValue( "quitLatitude", quitLat );
1379          settings.setValue( "quitRadius", quitRadius );
1380 
1381          settings.setValue( "lockFloatItemPositions", m_lockFloatItemsAction->isChecked() );
1382      settings.endGroup();
1383 
1384      settings.beginGroup( "Sun" );
1385          settings.setValue( "showSun", m_controlView->marbleWidget()->showSunShading() );
1386          settings.setValue( "showCitylights", m_controlView->marbleWidget()->showCityLights() );
1387          settings.setValue( "lockToSubSolarPoint", m_controlView->marbleWidget()->isLockedToSubSolarPoint() );
1388          settings.setValue( "subSolarPointIconVisible", m_controlView->marbleWidget()->isSubSolarPointIconVisible() );
1389      settings.endGroup();
1390 
1391       settings.beginGroup( "Time" );
1392          settings.setValue( "dateTime", m_controlView->marbleModel()->clockDateTime() );
1393          settings.setValue( "speedSlider", m_controlView->marbleModel()->clockSpeed() );
1394      settings.endGroup();
1395 
1396      settings.beginGroup( "Routing Profile" );
1397      QList<RoutingProfile>  profiles = m_controlView->marbleWidget()
1398                          ->model()->routingManager()->profilesModel()->profiles();
1399      settings.setValue( "Num", profiles.count() );
1400      for ( int i = 0; i < profiles.count(); ++i ) {
1401          settings.beginGroup( QString( "Profile %0" ).arg(i) );
1402          const RoutingProfile& profile = profiles.at( i );
1403          settings.setValue( "Name", profile.name() );
1404          for ( const QString& pluginName: settings.childGroups() ) {
1405              settings.beginGroup( pluginName );
1406              settings.remove(QString()); //remove all keys
1407              settings.endGroup();
1408          }
1409          for ( const QString &key: profile.pluginSettings().keys() ) {
1410              settings.beginGroup( key );
1411              settings.setValue( "Enabled", true );
1412              for ( const QString& settingKey: profile.pluginSettings()[ key ].keys() ) {
1413                  Q_ASSERT(settingKey != QLatin1String("Enabled"));
1414                  settings.setValue( settingKey, profile.pluginSettings()[ key ][ settingKey ] );
1415              }
1416              settings.endGroup();
1417          }
1418          settings.endGroup();
1419      }
1420      RoutingProfile const profile = m_controlView->marbleWidget()->model()->routingManager()->routeRequest()->routingProfile();
1421      settings.setValue( "currentIndex", profiles.indexOf( profile ) );
1422      settings.endGroup();
1423 
1424      settings.beginGroup( "Plugins");
1425      QString positionProvider;
1426      PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
1427      tracking->writeSettings();
1428      if ( tracking->positionProviderPlugin() ) {
1429          positionProvider = tracking->positionProviderPlugin()->nameId();
1430      }
1431      settings.setValue( "activePositionTrackingPlugin", positionProvider );
1432      settings.endGroup();
1433 
1434      settings.beginGroup( "Tracking" );
1435      CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget();
1436      if ( trackingWidget ) {
1437          // Can be null due to lazy initialization
1438          settings.setValue( "recenterMode", trackingWidget->recenterMode() );
1439          settings.setValue( "autoZoom", trackingWidget->autoZoom() );
1440          settings.setValue( "trackVisible", trackingWidget->trackVisible() );
1441          settings.setValue( "lastTrackOpenPath", trackingWidget->lastOpenPath() );
1442          settings.setValue( "lastTrackSavePath", trackingWidget->lastSavePath() );
1443      }
1444      settings.endGroup();
1445 
1446      // The config dialog has to write settings.
1447      m_configDialog->writeSettings();
1448 
1449      // Store current route settings
1450      settings.beginGroup( "Routing" );
1451      {
1452          RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager();
1453          routingManager->writeSettings();
1454          settings.setValue( "showGuidanceModeStartupWarning", routingManager->showGuidanceModeStartupWarning() );
1455          settings.setValue( "lastRouteOpenPath", routingManager->lastOpenPath() );
1456          settings.setValue( "lastRouteSavePath", routingManager->lastSavePath() );
1457          settings.setValue( "routeColorStandard", routingManager->routeColorStandard().name() );
1458          settings.setValue( "routeAlphaStandard", routingManager->routeColorStandard().alpha() );
1459          settings.setValue( "routeColorHighlighted", routingManager->routeColorHighlighted().name() );
1460          settings.setValue( "routeAlphaHighlighted", routingManager->routeColorHighlighted().alpha() );
1461          settings.setValue( "routeColorAlternative", routingManager->routeColorAlternative().name() );
1462          settings.setValue( "routeAlphaAlternative", routingManager->routeColorAlternative().alpha() );
1463      }
1464      settings.endGroup();
1465 
1466      settings.beginGroup( "Navigation");
1467      settings.setValue( "externalMapEditor", m_controlView->externalMapEditor() );
1468      settings.endGroup();
1469 }
1470 
editSettings()1471 void MainWindow::editSettings()
1472 {
1473     // Show the settings dialog.
1474     m_configDialog->show();
1475     m_configDialog->raise();
1476     m_configDialog->activateWindow();
1477 }
1478 
updateSettings()1479 void MainWindow::updateSettings()
1480 {
1481     mDebug() << Q_FUNC_INFO << "Updating Settings ...";
1482 
1483     // FIXME: Font doesn't get updated instantly.
1484     m_controlView->marbleWidget()->setDefaultFont( m_configDialog->mapFont() );
1485 
1486     m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->stillQuality(), Marble::Still );
1487     m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->animationQuality(), Marble::Animation );
1488 
1489     m_controlView->marbleWidget()->setDefaultAngleUnit( m_configDialog->angleUnit() );
1490     MarbleGlobal::getInstance()->locale()->setMeasurementSystem( m_configDialog->measurementSystem() );
1491 
1492     m_distance = m_controlView->marbleWidget()->distanceString();
1493     updateStatusBar();
1494 
1495     m_controlView->marbleWidget()->setAnimationsEnabled( m_configDialog->animateTargetVoyage() );
1496     m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( m_configDialog->inertialEarthRotation() );
1497     m_controlView->marbleWidget()->inputHandler()->setMouseViewRotationEnabled( m_configDialog->mouseViewRotation() );
1498     if ( !m_configDialog->externalMapEditor().isEmpty() ) {
1499         m_controlView->setExternalMapEditor( m_configDialog->externalMapEditor() );
1500     }
1501 
1502     // Cache
1503     m_controlView->marbleModel()->setPersistentTileCacheLimit( m_configDialog->persistentTileCacheLimit() * 1024 );
1504     m_controlView->marbleWidget()->setVolatileTileCacheLimit( m_configDialog->volatileTileCacheLimit() * 1024 );
1505 
1506     /*
1507     m_controlView->marbleWidget()->setProxy( m_configDialog->proxyUrl(), m_configDialog->proxyPort(), m_configDialog->user(), m_configDialog->password() );
1508     */
1509 
1510     CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
1511     cloudSyncManager->setOwncloudCredentials( m_configDialog->owncloudServer(),
1512                                               m_configDialog->owncloudUsername(),
1513                                               m_configDialog->owncloudPassword() );
1514     cloudSyncManager->setSyncEnabled( m_configDialog->syncEnabled() );
1515     cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( m_configDialog->syncRoutes() );
1516     cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( m_configDialog->syncBookmarks() );
1517 
1518     m_controlView->marbleWidget()->update();
1519 }
1520 
showDownloadRegionDialog()1521 void MainWindow::showDownloadRegionDialog()
1522 {
1523     if ( !m_downloadRegionDialog ) {
1524         m_downloadRegionDialog = new DownloadRegionDialog( m_controlView->marbleWidget(), m_controlView );
1525         // it might be tempting to move the connects to DownloadRegionDialog's "accepted" and
1526         // "applied" signals, be aware that the "hidden" signal might be come before the "accepted"
1527         // signal, leading to a too early disconnect.
1528         connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion()));
1529         connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion()));
1530     }
1531     // FIXME: get allowed range from current map theme
1532     m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 );
1533     m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod );
1534     ViewportParams const * const viewport =
1535         m_controlView->marbleWidget()->viewport();
1536     m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() );
1537     m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() );
1538 
1539     m_downloadRegionDialog->show();
1540     m_downloadRegionDialog->raise();
1541     m_downloadRegionDialog->activateWindow();
1542 }
1543 
downloadRegion()1544 void MainWindow::downloadRegion()
1545 {
1546     Q_ASSERT( m_downloadRegionDialog );
1547     QVector<TileCoordsPyramid> const pyramid = m_downloadRegionDialog->region();
1548     if ( !pyramid.isEmpty() ) {
1549         m_controlView->marbleWidget()->downloadRegion( pyramid );
1550     }
1551 }
1552 
printMapScreenShot()1553 void MainWindow::printMapScreenShot()
1554 {
1555 #ifndef QT_NO_PRINTER
1556     QPrinter printer( QPrinter::HighResolution );
1557     QPointer<QPrintDialog> printDialog = new QPrintDialog( &printer, this );
1558     m_controlView->printMapScreenShot( printDialog );
1559     delete printDialog;
1560 #endif
1561 }
1562 
updateMapEditButtonVisibility(const QString & mapTheme)1563 void MainWindow::updateMapEditButtonVisibility( const QString &mapTheme )
1564 {
1565     Q_ASSERT( m_osmEditAction );
1566     QStringList osmThemes = QStringList()
1567             << "earth/openstreetmap/openstreetmap.dgml"
1568             << "earth/hikebikemap/hikebikemap.dgml"
1569             << "earth/opencyclemap/opencyclemap.dgml"
1570             << "earth/public-transport/public-transport.dgml"
1571             << "earth/openseamap/openseamap.dgml"
1572             << "earth/vectorosm/vectorosm.dgml";
1573     m_osmEditAction->setVisible(osmThemes.contains(mapTheme));
1574 }
1575 
showMovieCaptureDialog()1576 void MainWindow::showMovieCaptureDialog()
1577 {
1578     if (m_movieCaptureDialog == nullptr) {
1579         m_movieCaptureDialog = new MovieCaptureDialog(m_controlView->marbleWidget(),
1580                                                       m_controlView->marbleWidget());
1581         connect( m_movieCaptureDialog, SIGNAL(started()), this, SLOT(changeRecordingState()));
1582     }
1583     m_movieCaptureDialog->show();
1584 }
1585 
stopRecording()1586 void MainWindow::stopRecording()
1587 {
1588     if ( m_movieCaptureDialog ) {
1589         m_movieCaptureDialog->stopRecording();
1590         changeRecordingState();
1591     }
1592 }
1593 
changeRecordingState()1594 void MainWindow::changeRecordingState()
1595 {
1596     m_recordMovieAction->setEnabled( !m_recordMovieAction->isEnabled() );
1597     m_stopRecordingAction->setEnabled( !m_stopRecordingAction->isEnabled() );
1598 }
1599 
updateWindowTitle()1600 void MainWindow::updateWindowTitle()
1601 {
1602     GeoSceneDocument *theme = m_controlView->marbleModel()->mapTheme();
1603     setWindowTitle(theme ? theme->head()->name() : QString());
1604 }
1605 
showMapWizard()1606 void MainWindow::showMapWizard()
1607 {
1608     QPointer<MapWizard> mapWizard = new MapWizard();
1609     QSettings settings;
1610 
1611     settings.beginGroup( "MapWizard" );
1612         mapWizard->setWmsServers( settings.value( "wmsServers" ).toStringList() );
1613         mapWizard->setStaticUrlServers( settings.value( "staticUrlServers" ).toStringList() );
1614     settings.endGroup();
1615 
1616     mapWizard->exec();
1617 
1618     settings.beginGroup( "MapWizard" );
1619         settings.setValue( "wmsServers", mapWizard->wmsServers() );
1620         settings.setValue( "staticUrlServers", mapWizard->staticUrlServers() );
1621     settings.endGroup();
1622 
1623     mapWizard->deleteLater();
1624 }
1625 
showZoomLevel(bool show)1626 void MainWindow::showZoomLevel(bool show)
1627 {
1628     if ( show ) {
1629         m_zoomLabel->show();
1630         statusBar()->insertPermanentWidget( 2, m_zoomLabel );
1631     } else {
1632         statusBar()->removeWidget( m_zoomLabel );
1633     }
1634     // update from last modification
1635     m_toggleTileLevelAction->setChecked( show );
1636 }
1637 
changeAngleDisplayUnit(QAction * action)1638 void MainWindow::changeAngleDisplayUnit( QAction *action )
1639 {
1640     m_configDialog->setAngleUnit((Marble::AngleUnit)action->data().toInt());
1641 }
1642 
fallBackToDefaultTheme()1643 void MainWindow::fallBackToDefaultTheme()
1644 {
1645     m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() );
1646 }
1647 
changeViewSize(QAction * action)1648 void MainWindow::changeViewSize( QAction* action )
1649 {
1650     if ( action->data().type() == QVariant::Size ) {
1651         if ( m_savedSize.isEmpty() ) {
1652             m_savedSize = m_controlView->size();
1653         }
1654         m_controlView->setFixedSize( action->data().toSize() );
1655         adjustSize();
1656     } else {
1657         m_controlView->setMinimumSize( QSize( 0, 0 ) );
1658         m_controlView->setMaximumSize( QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ) );
1659         m_controlView->resize( m_savedSize );
1660         m_controlView->setMinimumSize( m_savedSize );
1661         adjustSize();
1662         m_controlView->setMinimumSize( QSize( 0, 0 ) );
1663         m_savedSize.setHeight( -1 );
1664     }
1665 }
1666 
1667 #include "moc_QtMainWindow.cpp"
1668