1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2004-2007 Torsten Rahn <tackat@kde.org>
4 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5 // SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
6 // SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de>
7 // SPDX-FileCopyrightText: 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
8 // SPDX-FileCopyrightText: 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
9 //
10 
11 // Self
12 #include "MapViewWidget.h"
13 
14 // Marble
15 #include "MarbleDebug.h"
16 #include "MarbleDirs.h"
17 #include "MarbleWidget.h"
18 #include "MarbleModel.h"
19 #include "MapThemeManager.h"
20 #include "MapThemeSortFilterProxyModel.h"
21 #include "GeoSceneDocument.h"
22 #include "GeoSceneHead.h"
23 #include "MapViewItemDelegate.h"
24 #include "CelestialSortFilterProxyModel.h"
25 
26 // Qt
27 #include <QResizeEvent>
28 #include <QFileInfo>
29 #include <QSettings>
30 #include <QMenu>
31 #include <QMessageBox>
32 #include <QStandardItemModel>
33 #include <QGridLayout>
34 #include <QPainter>
35 #include <QToolBar>
36 #include <QToolButton>
37 #include <QDateTime>
38 
39 using namespace Marble;
40 // Ui
41 #include "ui_MapViewWidget.h"
42 
43 namespace Marble
44 {
45 
46 class Q_DECL_HIDDEN MapViewWidget::Private {
47  public:
Private(MapViewWidget * parent)48     Private( MapViewWidget *parent )
49         : q( parent ),
50           m_marbleModel( nullptr ),
51           m_mapSortProxy(),
52           m_celestialListProxy(),
53           m_toolBar( nullptr ),
54           m_globeViewButton( nullptr ),
55           m_mercatorViewButton( nullptr ),
56           m_popupMenuFlat( nullptr ),
57           m_flatViewAction( nullptr ),
58           m_mercatorViewAction( nullptr ),
59           m_celestialBodyAction( nullptr ),
60           m_gnomonicViewAction( nullptr ),
61           m_stereographicViewAction( nullptr ),
62           m_lambertAzimuthalViewAction( nullptr ),
63           m_azimuthalEquidistantViewAction( nullptr ),
64           m_verticalPerspectiveViewAction( nullptr ),
65           m_globeViewAction( nullptr ),
66           m_mapViewDelegate(nullptr)
67     {
68         m_mapSortProxy.setDynamicSortFilter( true );
69         m_celestialListProxy.setDynamicSortFilter( true );
70     }
71 
~Private()72     ~Private()
73     {
74         delete m_mapViewDelegate;
75     }
76 
applyExtendedLayout()77     void applyExtendedLayout()
78     {
79         m_mapViewUi.projectionLabel_2->setVisible(true);
80         m_mapViewUi.celestialBodyLabel->setVisible(true);
81         m_mapViewUi.projectionComboBox->setVisible(true);
82         m_mapViewUi.mapThemeLabel->setVisible(true);
83         m_mapViewUi.line->setVisible(true);
84 
85         m_toolBar->setVisible(false);
86         const int labelId = m_mapViewUi.verticalLayout->indexOf(m_mapViewUi.celestialBodyLabel);
87         m_mapViewUi.verticalLayout->insertWidget(labelId+1, m_mapViewUi.celestialBodyComboBox);
88         m_toolBar->removeAction(m_celestialBodyAction);
89         m_mapViewUi.celestialBodyComboBox->show();
90     }
91 
applyReducedLayout()92     void applyReducedLayout()
93     {
94         m_mapViewUi.projectionLabel_2->setVisible(false);
95         m_mapViewUi.celestialBodyLabel->setVisible(false);
96         m_mapViewUi.projectionComboBox->setVisible(false);
97         m_mapViewUi.mapThemeLabel->setVisible(false);
98         m_mapViewUi.line->setVisible(false);
99 
100         m_toolBar->setVisible(true);
101         m_celestialBodyAction = m_toolBar->addWidget(m_mapViewUi.celestialBodyComboBox);
102         m_mapViewUi.verticalLayout->removeWidget(m_mapViewUi.celestialBodyComboBox);
103         m_mapViewUi.celestialBodyComboBox->show();
104     }
105 
setupToolBar()106     void setupToolBar()
107     {
108         m_toolBar = new QToolBar;
109 
110         m_globeViewButton = new QToolButton;
111         m_globeViewButton->setIcon(QIcon(QStringLiteral(":/icons/map-globe.png")));
112         m_globeViewButton->setToolTip( tr("Globe View") );
113         m_globeViewButton->setCheckable(true);
114         m_globeViewButton->setChecked(false);
115 
116         m_globeViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
117                                              tr( "Spherical view" ),
118                                              m_globeViewButton );
119         m_globeViewAction->setCheckable( true );
120         m_globeViewAction->setChecked( false );
121 
122         m_mercatorViewButton = new QToolButton;
123         m_mercatorViewButton->setIcon(QIcon(QStringLiteral(":/icons/map-mercator.png")));
124         m_mercatorViewButton->setToolTip( tr("Mercator View") );
125         m_mercatorViewButton->setCheckable(true);
126         m_mercatorViewButton->setChecked(false);
127         m_mercatorViewButton->setPopupMode(QToolButton::MenuButtonPopup);
128 
129         m_popupMenuFlat = new QMenu(q);
130 
131         m_mercatorViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-mercator.png")),
132                                               tr("Mercator View"),
133                                               m_popupMenuFlat );
134         m_mercatorViewAction->setCheckable(true);
135         m_mercatorViewAction->setChecked(false);
136 
137         m_flatViewAction = new QAction( QIcon(QStringLiteral(":/icons/map-flat.png")),
138                                         tr("Flat View"),
139                                         m_popupMenuFlat );
140         m_flatViewAction->setCheckable(true);
141         m_flatViewAction->setChecked(false);
142 
143         m_gnomonicViewAction = new QAction( QIcon(QStringLiteral(":/icons/map-gnomonic.png")),
144                                             tr( "Gnomonic view" ),
145                                             m_popupMenuFlat);
146         m_gnomonicViewAction->setCheckable( true );
147         m_gnomonicViewAction->setChecked( false );
148 
149         m_stereographicViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
150                                             tr( "Stereographic view" ),
151                                             m_popupMenuFlat);
152         m_stereographicViewAction->setCheckable( true );
153         m_stereographicViewAction->setChecked( false );
154 
155         m_lambertAzimuthalViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
156                                             tr( "Lambert Azimuthal Equal-Area view" ),
157                                             m_popupMenuFlat);
158         m_lambertAzimuthalViewAction->setCheckable( true );
159         m_lambertAzimuthalViewAction->setChecked( false );
160 
161         m_azimuthalEquidistantViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
162                                             tr( "Azimuthal Equidistant view" ),
163                                             m_popupMenuFlat);
164         m_azimuthalEquidistantViewAction->setCheckable( true );
165         m_azimuthalEquidistantViewAction->setChecked( false );
166 
167         m_verticalPerspectiveViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
168                                             tr( "Perspective Globe view" ),
169                                             m_popupMenuFlat);
170         m_verticalPerspectiveViewAction->setCheckable( true );
171         m_verticalPerspectiveViewAction->setChecked( false );
172 
173 
174         m_popupMenuFlat->addAction(m_mercatorViewAction);
175         m_popupMenuFlat->addAction(m_flatViewAction);
176         m_popupMenuFlat->addAction(m_gnomonicViewAction);
177         m_popupMenuFlat->addAction(m_stereographicViewAction);
178         m_popupMenuFlat->addAction(m_lambertAzimuthalViewAction);
179         m_popupMenuFlat->addAction(m_azimuthalEquidistantViewAction);
180         m_popupMenuFlat->addAction(m_verticalPerspectiveViewAction);
181         m_mercatorViewButton->setMenu(m_popupMenuFlat);
182 
183         m_toolBar->addWidget(m_globeViewButton);
184         m_toolBar->addWidget(m_mercatorViewButton);
185         m_toolBar->addSeparator();
186         m_toolBar->setContentsMargins(0,0,0,0);
187         m_toolBar->setIconSize(QSize(16, 16));
188         m_mapViewUi.toolBarLayout->insertWidget(0, m_toolBar);
189 
190         QObject::connect(m_globeViewButton, SIGNAL(clicked()),
191                          q, SLOT(globeViewRequested()));
192         QObject::connect(m_mercatorViewButton, SIGNAL(clicked()),
193                          q, SLOT(mercatorViewRequested()));
194         QObject::connect(m_mercatorViewAction, SIGNAL(triggered()),
195                          q, SLOT(mercatorViewRequested()));
196         QObject::connect(m_flatViewAction, SIGNAL(triggered()),
197                          q, SLOT(flatViewRequested()));
198         QObject::connect(m_gnomonicViewAction, SIGNAL(triggered()),
199                          q, SLOT(gnomonicViewRequested()));
200         QObject::connect(m_stereographicViewAction, SIGNAL(triggered()),
201                          q, SLOT(stereographicViewRequested()));
202         QObject::connect(m_lambertAzimuthalViewAction, SIGNAL(triggered()),
203                          q, SLOT(lambertAzimuthalViewRequested()));
204         QObject::connect(m_azimuthalEquidistantViewAction, SIGNAL(triggered()),
205                          q, SLOT(azimuthalEquidistantViewRequested()));
206         QObject::connect(m_verticalPerspectiveViewAction, SIGNAL(triggered()),
207                          q, SLOT(verticalPerspectiveViewRequested()));
208         QObject::connect(m_globeViewAction, SIGNAL(triggered()),
209                          q, SLOT(globeViewRequested()));
210 
211         applyReducedLayout();
212     }
213 
updateMapFilter()214     void updateMapFilter()
215     {
216         int currentIndex = m_mapViewUi.celestialBodyComboBox->currentIndex();
217         const QString selectedId = m_celestialListProxy.data( m_celestialListProxy.index( currentIndex, 1 ) ).toString();
218 
219         if ( !selectedId.isEmpty() ) {
220             m_mapSortProxy.setFilterRegExp( QRegExp( selectedId, Qt::CaseInsensitive,QRegExp::FixedString ) );
221         }
222     }
223 
224     void celestialBodySelected( int comboIndex );
225 
226     void projectionSelected( int projectionIndex );
227 
228     void mapThemeSelected( QModelIndex index );
229     void mapThemeSelected( int index );
230 
231     void showContextMenu( const QPoint& pos );
232     void deleteMap();
233     void toggleFavorite();
234     void toggleIconSize();
235 
236     bool isCurrentFavorite() const;
237     QString currentThemeName() const;
238     QString currentThemePath() const;
239     QString favoriteKey(const QModelIndex &index) const;
240 
241     MapViewWidget *const q;
242 
243     Ui::MapViewWidget  m_mapViewUi;
244     MarbleModel      *m_marbleModel;
245 
246     MapThemeSortFilterProxyModel m_mapSortProxy;
247 
248     CelestialSortFilterProxyModel m_celestialListProxy;
249     QSettings m_settings;
250     QToolBar *m_toolBar;
251     QToolButton *m_globeViewButton;
252     QToolButton *m_mercatorViewButton;
253     QMenu *m_popupMenuFlat;
254     QAction *m_flatViewAction;
255     QAction *m_mercatorViewAction;
256     QAction *m_celestialBodyAction;
257     QAction *m_gnomonicViewAction;
258     QAction *m_stereographicViewAction;
259     QAction *m_lambertAzimuthalViewAction;
260     QAction *m_azimuthalEquidistantViewAction;
261     QAction *m_verticalPerspectiveViewAction;
262     QAction *m_globeViewAction;
263     MapViewItemDelegate* m_mapViewDelegate;
264 };
265 
MapViewWidget(QWidget * parent,Qt::WindowFlags f)266 MapViewWidget::MapViewWidget( QWidget *parent, Qt::WindowFlags f )
267     : QWidget( parent, f ),
268       d( new Private( this ) )
269 {
270     d->m_mapViewUi.setupUi( this );
271     layout()->setMargin( 0 );
272 
273     if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
274         QGridLayout* layout = new QGridLayout;
275         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 0 );
276         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 1 );
277         d->m_mapViewUi.line->setVisible( false );
278         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 0 );
279         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 1 );
280         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 3 ), 2, 0 );
281         layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 4 ), 2, 1 );
282         d->m_mapViewUi.verticalLayout->insertLayout( 0, layout );
283         d->m_mapViewUi.mapThemeComboBox->setModel( &d->m_mapSortProxy );
284         d->m_mapViewUi.mapThemeComboBox->setIconSize( QSize( 48, 48 ) );
285         connect( d->m_mapViewUi.mapThemeComboBox, SIGNAL(activated(int)),
286                  this,                            SLOT(mapThemeSelected(int)) );
287         d->m_mapViewUi.marbleThemeSelectView->setVisible( false );
288     }
289     else {
290         d->m_mapViewUi.marbleThemeSelectView->setViewMode( QListView::IconMode );
291         QSize const iconSize = d->m_settings.value(QStringLiteral("MapView/iconSize"), QSize(90, 90)).toSize();
292         d->m_mapViewUi.marbleThemeSelectView->setIconSize( iconSize );
293         delete d->m_mapViewDelegate;
294         d->m_mapViewDelegate = new MapViewItemDelegate(d->m_mapViewUi.marbleThemeSelectView);
295         d->m_mapViewUi.marbleThemeSelectView->setItemDelegate(d->m_mapViewDelegate);
296         d->m_mapViewUi.marbleThemeSelectView->setAlternatingRowColors( true );
297         d->m_mapViewUi.marbleThemeSelectView->setFlow( QListView::LeftToRight );
298         d->m_mapViewUi.marbleThemeSelectView->setWrapping( true );
299         d->m_mapViewUi.marbleThemeSelectView->setResizeMode( QListView::Adjust );
300         d->m_mapViewUi.marbleThemeSelectView->setUniformItemSizes( true );
301         d->m_mapViewUi.marbleThemeSelectView->setMovement( QListView::Static );
302         d->m_mapViewUi.marbleThemeSelectView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
303         d->m_mapViewUi.marbleThemeSelectView->setEditTriggers( QListView::NoEditTriggers );
304         d->m_mapViewUi.marbleThemeSelectView->setSelectionMode( QListView::SingleSelection );
305         d->m_mapViewUi.marbleThemeSelectView->setModel( &d->m_mapSortProxy );
306         connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(pressed(QModelIndex)),
307                  this,                                 SLOT(mapThemeSelected(QModelIndex)) );
308         connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(customContextMenuRequested(QPoint)),
309                  this,                                 SLOT(showContextMenu(QPoint)) );
310 
311         d->m_mapViewUi.mapThemeComboBox->setVisible( false );
312         d->setupToolBar();
313     }
314 
315     connect( d->m_mapViewUi.projectionComboBox,    SIGNAL(activated(int)),
316              this,                                 SLOT(projectionSelected(int)) );
317 
318     d->m_mapViewUi.projectionComboBox->setEnabled( true );
319     d->m_mapViewUi.celestialBodyComboBox->setModel( &d->m_celestialListProxy );
320 
321     connect( d->m_mapViewUi.celestialBodyComboBox, SIGNAL(activated(int)),
322              this,                                 SLOT(celestialBodySelected(int)) );
323 
324     d->m_settings.beginGroup(QStringLiteral("Favorites"));
325     if (!d->m_settings.contains(QStringLiteral("initialized"))) {
326         d->m_settings.setValue(QStringLiteral("initialized"), true);
327         QDateTime currentDateTime = QDateTime::currentDateTime();
328         d->m_settings.setValue(QStringLiteral("Atlas"), currentDateTime);
329         d->m_settings.setValue(QStringLiteral("OpenStreetMap"), currentDateTime);
330         d->m_settings.setValue(QStringLiteral("Satellite View"), currentDateTime);
331     }
332     d->m_settings.endGroup();
333 }
334 
~MapViewWidget()335 MapViewWidget::~MapViewWidget()
336 {
337     delete d;
338 }
339 
setMarbleWidget(MarbleWidget * widget,MapThemeManager * mapThemeManager)340 void MapViewWidget::setMarbleWidget( MarbleWidget *widget, MapThemeManager *mapThemeManager )
341 {
342     d->m_marbleModel = widget->model();
343     d->m_mapSortProxy.setSourceModel( mapThemeManager->mapThemeModel() );
344     d->m_mapSortProxy.sort( 0 );
345     d->m_celestialListProxy.setSourceModel( mapThemeManager->celestialBodiesModel() );
346     d->m_celestialListProxy.sort( 0 );
347 
348     connect( this, SIGNAL(projectionChanged(Projection)),
349              widget, SLOT(setProjection(Projection)) );
350 
351     connect( widget, SIGNAL(themeChanged(QString)),
352              this, SLOT(setMapThemeId(QString)) );
353 
354     connect( widget, SIGNAL(projectionChanged(Projection)),
355              this, SLOT(setProjection(Projection)) );
356 
357     connect( this, SIGNAL(mapThemeIdChanged(QString)),
358              widget, SLOT(setMapThemeId(QString)) );
359 
360     setProjection(widget->projection());
361     setMapThemeId(widget->mapThemeId());
362 }
363 
resizeEvent(QResizeEvent * event)364 void MapViewWidget::resizeEvent(QResizeEvent *event)
365 {
366     if (!d->m_toolBar)
367         return;
368 
369     if (d->m_toolBar->isVisible() && event->size().height() > 400) {
370         d->applyExtendedLayout();
371     } else if (!d->m_toolBar->isVisible() && event->size().height() <= 400) {
372         d->applyReducedLayout();
373     }
374 }
375 
setMapThemeId(const QString & themeId)376 void MapViewWidget::setMapThemeId( const QString &themeId )
377 {
378     const bool smallscreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
379 
380     const int currentRow = smallscreen ? d->m_mapViewUi.mapThemeComboBox->currentIndex() :
381                                          d->m_mapViewUi.marbleThemeSelectView->currentIndex().row();
382     const QString oldThemeId = d->m_mapSortProxy.data( d->m_mapSortProxy.index( currentRow, 0 ), Qt::UserRole + 1 ).toString();
383 
384     // Check if the new selected theme is different from the current one
385     if ( themeId == oldThemeId )
386         return;
387 
388     const QString oldCelestialBodyId = oldThemeId.section(QLatin1Char('/'), 0, 0);
389     const QString celestialBodyId = themeId.section(QLatin1Char('/'), 0, 0);
390 
391     // select celestialBodyId in GUI
392     if ( celestialBodyId != oldCelestialBodyId ) {
393         for ( int row = 0; row < d->m_celestialListProxy.rowCount(); ++row ) {
394             if ( d->m_celestialListProxy.data( d->m_celestialListProxy.index( row, 1 ) ).toString() == celestialBodyId ) {
395                 d->m_mapViewUi.celestialBodyComboBox->setCurrentIndex( row );
396                 break;
397             }
398         }
399 
400         d->updateMapFilter();
401     }
402 
403     // select themeId in GUI
404     for ( int row = 0; row < d->m_mapSortProxy.rowCount(); ++row ) {
405         if( d->m_mapSortProxy.data( d->m_mapSortProxy.index( row, 0 ), Qt::UserRole + 1 ).toString() == themeId ) {
406             if ( smallscreen ) {
407                 d->m_mapViewUi.mapThemeComboBox->setCurrentIndex( row );
408             }
409             else {
410                 const QModelIndex index = d->m_mapSortProxy.index( row, 0 );
411                 d->m_mapViewUi.marbleThemeSelectView->setCurrentIndex( index );
412                 d->m_mapViewUi.marbleThemeSelectView->scrollTo( index );
413             }
414 
415             break;
416         }
417     }
418 }
419 
setProjection(Projection projection)420 void MapViewWidget::setProjection( Projection projection )
421 {
422     if ( (int)projection != d->m_mapViewUi.projectionComboBox->currentIndex() )
423         d->m_mapViewUi.projectionComboBox->setCurrentIndex( (int) projection );
424 
425     if (d->m_toolBar) {
426         switch (projection) {
427         case Marble::Spherical:
428             d->m_globeViewButton->setChecked(true);
429             d->m_globeViewAction->setChecked(true);
430             d->m_mercatorViewButton->setChecked(false);
431             d->m_mercatorViewAction->setChecked(false);
432             d->m_flatViewAction->setChecked(false);
433             d->m_gnomonicViewAction->setChecked(false);
434             d->m_stereographicViewAction->setChecked(false);
435             d->m_lambertAzimuthalViewAction->setChecked(false);
436             d->m_azimuthalEquidistantViewAction->setChecked(false);
437             d->m_verticalPerspectiveViewAction->setChecked(false);
438             break;
439         case Marble::Mercator:
440             d->m_mercatorViewButton->setChecked(true);
441             d->m_mercatorViewAction->setChecked(true);
442             d->m_globeViewButton->setChecked(false);
443             d->m_flatViewAction->setChecked(false);
444             d->m_gnomonicViewAction->setChecked(false);
445             d->m_globeViewAction->setChecked(false);
446             d->m_stereographicViewAction->setChecked(false);
447             d->m_lambertAzimuthalViewAction->setChecked(false);
448             d->m_azimuthalEquidistantViewAction->setChecked(false);
449             d->m_verticalPerspectiveViewAction->setChecked(false);
450             break;
451         case Marble::Equirectangular:
452             d->m_flatViewAction->setChecked(true);
453             d->m_mercatorViewButton->setChecked(true);
454             d->m_globeViewButton->setChecked(false);
455             d->m_mercatorViewAction->setChecked(false);
456             d->m_gnomonicViewAction->setChecked(false);
457             d->m_globeViewAction->setChecked(false);
458             d->m_stereographicViewAction->setChecked(false);
459             d->m_lambertAzimuthalViewAction->setChecked(false);
460             d->m_azimuthalEquidistantViewAction->setChecked(false);
461             d->m_verticalPerspectiveViewAction->setChecked(false);
462             break;
463         case Marble::Gnomonic:
464             d->m_flatViewAction->setChecked(false);
465             d->m_mercatorViewButton->setChecked(true);
466             d->m_globeViewButton->setChecked(false);
467             d->m_mercatorViewAction->setChecked(false);
468             d->m_gnomonicViewAction->setChecked(true);
469             d->m_globeViewAction->setChecked(false);
470             d->m_stereographicViewAction->setChecked(false);
471             d->m_lambertAzimuthalViewAction->setChecked(false);
472             d->m_azimuthalEquidistantViewAction->setChecked(false);
473             d->m_verticalPerspectiveViewAction->setChecked(false);
474             break;
475         case Marble::Stereographic:
476             d->m_flatViewAction->setChecked(false);
477             d->m_mercatorViewButton->setChecked(true);
478             d->m_globeViewButton->setChecked(false);
479             d->m_mercatorViewAction->setChecked(false);
480             d->m_gnomonicViewAction->setChecked(false);
481             d->m_globeViewAction->setChecked(false);
482             d->m_stereographicViewAction->setChecked(true);
483             d->m_lambertAzimuthalViewAction->setChecked(false);
484             d->m_azimuthalEquidistantViewAction->setChecked(false);
485             d->m_verticalPerspectiveViewAction->setChecked(false);
486             break;
487         case Marble::LambertAzimuthal:
488             d->m_flatViewAction->setChecked(false);
489             d->m_mercatorViewButton->setChecked(true);
490             d->m_globeViewButton->setChecked(false);
491             d->m_mercatorViewAction->setChecked(false);
492             d->m_gnomonicViewAction->setChecked(false);
493             d->m_globeViewAction->setChecked(false);
494             d->m_stereographicViewAction->setChecked(false);
495             d->m_lambertAzimuthalViewAction->setChecked(true);
496             d->m_azimuthalEquidistantViewAction->setChecked(false);
497             d->m_verticalPerspectiveViewAction->setChecked(false);
498             break;
499         case Marble::AzimuthalEquidistant:
500             d->m_flatViewAction->setChecked(false);
501             d->m_mercatorViewButton->setChecked(true);
502             d->m_globeViewButton->setChecked(false);
503             d->m_mercatorViewAction->setChecked(false);
504             d->m_gnomonicViewAction->setChecked(false);
505             d->m_globeViewAction->setChecked(false);
506             d->m_stereographicViewAction->setChecked(false);
507             d->m_lambertAzimuthalViewAction->setChecked(false);
508             d->m_azimuthalEquidistantViewAction->setChecked(true);
509             d->m_verticalPerspectiveViewAction->setChecked(false);
510             break;
511         case Marble::VerticalPerspective:
512             d->m_flatViewAction->setChecked(false);
513             d->m_mercatorViewButton->setChecked(true);
514             d->m_globeViewButton->setChecked(false);
515             d->m_mercatorViewAction->setChecked(false);
516             d->m_gnomonicViewAction->setChecked(false);
517             d->m_globeViewAction->setChecked(false);
518             d->m_stereographicViewAction->setChecked(false);
519             d->m_lambertAzimuthalViewAction->setChecked(false);
520             d->m_azimuthalEquidistantViewAction->setChecked(false);
521             d->m_verticalPerspectiveViewAction->setChecked(true);
522             break;
523         }
524     }
525 }
526 
globeViewRequested()527 void MapViewWidget::globeViewRequested()
528 {
529     emit projectionChanged(Marble::Spherical);
530 }
531 
flatViewRequested()532 void MapViewWidget::flatViewRequested()
533 {
534     emit projectionChanged(Marble::Equirectangular);
535 }
536 
mercatorViewRequested()537 void MapViewWidget::mercatorViewRequested()
538 {
539     emit projectionChanged(Marble::Mercator);
540 }
541 
gnomonicViewRequested()542 void MapViewWidget::gnomonicViewRequested()
543 {
544     emit projectionChanged(Marble::Gnomonic);
545 }
546 
stereographicViewRequested()547 void MapViewWidget::stereographicViewRequested()
548 {
549     emit projectionChanged(Marble::Stereographic);
550 }
551 
lambertAzimuthalViewRequested()552 void MapViewWidget::lambertAzimuthalViewRequested()
553 {
554     emit projectionChanged(Marble::LambertAzimuthal);
555 }
556 
azimuthalEquidistantViewRequested()557 void MapViewWidget::azimuthalEquidistantViewRequested()
558 {
559     emit projectionChanged(Marble::AzimuthalEquidistant);
560 }
561 
verticalPerspectiveViewRequested()562 void MapViewWidget::verticalPerspectiveViewRequested()
563 {
564     emit projectionChanged(Marble::VerticalPerspective);
565 }
566 
celestialBodySelected(int comboIndex)567 void MapViewWidget::Private::celestialBodySelected( int comboIndex )
568 {
569     Q_UNUSED( comboIndex )
570 
571     updateMapFilter();
572 
573     bool foundMapTheme = false;
574 
575     QString currentMapThemeId = m_marbleModel->mapThemeId();
576     QString oldPlanetId = m_marbleModel->planetId();
577 
578     int row = m_mapSortProxy.rowCount();
579 
580     for ( int i = 0; i < row; ++i )
581     {
582         QModelIndex index = m_mapSortProxy.index(i,0);
583         QString itMapThemeId = m_mapSortProxy.data(index, Qt::UserRole + 1).toString();
584         if ( currentMapThemeId == itMapThemeId )
585         {
586             foundMapTheme = true;
587             break;
588         }
589     }
590     if ( !foundMapTheme ) {
591         QModelIndex index = m_mapSortProxy.index(0,0);
592         emit q->mapThemeIdChanged( m_mapSortProxy.data( index, Qt::UserRole + 1 ).toString() );
593     }
594 
595     if( oldPlanetId != m_marbleModel->planetId() ) {
596         emit q->celestialBodyChanged( m_marbleModel->planetId() );
597     }
598 }
599 
600 // Relay a signal and convert the parameter from an int to a Projection.
projectionSelected(int projectionIndex)601 void MapViewWidget::Private::projectionSelected( int projectionIndex )
602 {
603     emit q->projectionChanged( (Projection) projectionIndex );
604 }
605 
mapThemeSelected(QModelIndex index)606 void MapViewWidget::Private::mapThemeSelected( QModelIndex index )
607 {
608     mapThemeSelected( index.row() );
609 }
610 
mapThemeSelected(int index)611 void MapViewWidget::Private::mapThemeSelected( int index )
612 {
613     const QModelIndex columnIndex = m_mapSortProxy.index( index, 0 );
614     const QString currentmaptheme = m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
615 
616     mDebug() << Q_FUNC_INFO << currentmaptheme;
617 
618     emit q->mapThemeIdChanged( currentmaptheme );
619 }
620 
currentThemeName() const621 QString MapViewWidget::Private::currentThemeName() const
622 {
623     const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
624     const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0, QModelIndex() );
625 
626     return m_mapSortProxy.data( columnIndex ).toString();
627 }
628 
currentThemePath() const629 QString MapViewWidget::Private::currentThemePath() const
630 {
631     const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
632     const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0 );
633 
634     return m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
635 }
636 
favoriteKey(const QModelIndex & index) const637 QString MapViewWidget::Private::favoriteKey(const QModelIndex &index) const
638 {
639     return QLatin1String("Favorites/") + m_mapSortProxy.data(index).toString();
640 }
641 
showContextMenu(const QPoint & pos)642 void MapViewWidget::Private::showContextMenu( const QPoint& pos )
643 {
644     QMenu menu;
645 
646     QAction* iconSizeAction = menu.addAction( tr( "&Show Large Icons" ), q, SLOT(toggleIconSize()) );
647     iconSizeAction->setCheckable( true );
648     iconSizeAction->setChecked( m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 ) );
649     QAction *favAction = menu.addAction(QIcon(QStringLiteral(":/icons/bookmarks.png")), tr("&Favorite"), q, SLOT(toggleFavorite()));
650     favAction->setCheckable( true );
651     favAction->setChecked( isCurrentFavorite() );
652     menu.addSeparator();
653 
654     menu.addAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), q, SIGNAL(showMapWizard()));
655     if (QFileInfo(MarbleDirs::localPath() + QLatin1String("/maps/") + currentThemePath()).exists()) {
656         menu.addAction( tr( "&Delete Map Theme" ), q, SLOT(deleteMap()) );
657     }
658 }
659 
deleteMap()660 void MapViewWidget::Private::deleteMap()
661 {
662     if(QMessageBox::warning( q,
663                              tr( "Marble" ),
664                              tr( "Are you sure that you want to delete \"%1\"?" ).arg( currentThemeName() ),
665                              QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes )
666     {
667         MapThemeManager::deleteMapTheme( currentThemePath() );
668         emit q->mapThemeDeleted();
669     }
670 }
671 
toggleFavorite()672 void MapViewWidget::Private::toggleFavorite()
673 {
674     QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
675     if( isCurrentFavorite() ) {
676         m_settings.remove(favoriteKey(index));
677     } else {
678         m_settings.setValue(favoriteKey(index), QDateTime::currentDateTime() );
679     }
680     QStandardItemModel* sourceModel = qobject_cast<QStandardItemModel*>(m_mapSortProxy.sourceModel());
681     const QModelIndex sourceIndex = m_mapSortProxy.mapToSource(index);
682     emit sourceModel->dataChanged( sourceIndex, sourceIndex );
683     index = m_mapViewUi.marbleThemeSelectView->currentIndex();
684     m_mapViewUi.marbleThemeSelectView->scrollTo(index);
685 }
686 
toggleIconSize()687 void MapViewWidget::Private::toggleIconSize()
688 {
689     bool const isLarge = m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 );
690     int const size = isLarge ? 52 : 96;
691     m_mapViewUi.marbleThemeSelectView->setIconSize( QSize( size, size ) );
692     m_settings.setValue(QStringLiteral("MapView/iconSize"), m_mapViewUi.marbleThemeSelectView->iconSize() );
693 }
694 
isCurrentFavorite() const695 bool MapViewWidget::Private::isCurrentFavorite() const
696 {
697     const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
698     return m_settings.contains(favoriteKey(index));
699 }
700 
701 }
702 
703 #include "moc_MapViewWidget.cpp"
704