Marble

MapViewWidget.cpp
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
39using namespace Marble;
40// Ui
41#include "ui_MapViewWidget.h"
42
43namespace Marble
44{
45
46class Q_DECL_HIDDEN MapViewWidget::Private {
47 public:
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
72 ~Private()
73 {
74 delete m_mapViewDelegate;
75 }
76
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
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
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
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
266MapViewWidget::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(activated(QModelIndex)),
309 this, SLOT(mapThemeSelected(QModelIndex)) );
310 connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(customContextMenuRequested(QPoint)),
311 this, SLOT(showContextMenu(QPoint)) );
312
313 d->m_mapViewUi.mapThemeComboBox->setVisible( false );
314 d->setupToolBar();
315 }
316
317 connect( d->m_mapViewUi.projectionComboBox, SIGNAL(activated(int)),
318 this, SLOT(projectionSelected(int)) );
319
320 d->m_mapViewUi.projectionComboBox->setEnabled( true );
321 d->m_mapViewUi.celestialBodyComboBox->setModel( &d->m_celestialListProxy );
322
323 connect( d->m_mapViewUi.celestialBodyComboBox, SIGNAL(activated(int)),
324 this, SLOT(celestialBodySelected(int)) );
325
326 d->m_settings.beginGroup(QStringLiteral("Favorites"));
327 if (!d->m_settings.contains(QStringLiteral("initialized"))) {
328 d->m_settings.setValue(QStringLiteral("initialized"), true);
329 QDateTime currentDateTime = QDateTime::currentDateTime();
330 d->m_settings.setValue(QStringLiteral("Atlas"), currentDateTime);
331 d->m_settings.setValue(QStringLiteral("OpenStreetMap"), currentDateTime);
332 d->m_settings.setValue(QStringLiteral("Satellite View"), currentDateTime);
333 }
334 d->m_settings.endGroup();
335}
336
337MapViewWidget::~MapViewWidget()
338{
339 delete d;
340}
341
342void MapViewWidget::setMarbleWidget( MarbleWidget *widget, MapThemeManager *mapThemeManager )
343{
344 d->m_marbleModel = widget->model();
345 d->m_mapSortProxy.setSourceModel( mapThemeManager->mapThemeModel() );
346 d->m_mapSortProxy.sort( 0 );
347 d->m_celestialListProxy.setSourceModel( mapThemeManager->celestialBodiesModel() );
348 d->m_celestialListProxy.sort( 0 );
349
350 connect( this, SIGNAL(projectionChanged(Projection)),
351 widget, SLOT(setProjection(Projection)) );
352
353 connect( widget, SIGNAL(themeChanged(QString)),
354 this, SLOT(setMapThemeId(QString)) );
355
356 connect( widget, SIGNAL(projectionChanged(Projection)),
357 this, SLOT(setProjection(Projection)) );
358
359 connect( this, SIGNAL(mapThemeIdChanged(QString)),
360 widget, SLOT(setMapThemeId(QString)) );
361
362 setProjection(widget->projection());
363 setMapThemeId(widget->mapThemeId());
364}
365
366void MapViewWidget::resizeEvent(QResizeEvent *event)
367{
368 if (!d->m_toolBar)
369 return;
370
371 if (d->m_toolBar->isVisible() && event->size().height() > 400) {
372 d->applyExtendedLayout();
373 } else if (!d->m_toolBar->isVisible() && event->size().height() <= 400) {
374 d->applyReducedLayout();
375 }
376}
377
378void MapViewWidget::setMapThemeId( const QString &themeId )
379{
380 const bool smallscreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
381
382 const int currentRow = smallscreen ? d->m_mapViewUi.mapThemeComboBox->currentIndex() :
383 d->m_mapViewUi.marbleThemeSelectView->currentIndex().row();
384 const QString oldThemeId = d->m_mapSortProxy.data( d->m_mapSortProxy.index( currentRow, 0 ), Qt::UserRole + 1 ).toString();
385
386 // Check if the new selected theme is different from the current one
387 if ( themeId == oldThemeId )
388 return;
389
390 const QString oldCelestialBodyId = oldThemeId.section(QLatin1Char('/'), 0, 0);
391 const QString celestialBodyId = themeId.section(QLatin1Char('/'), 0, 0);
392
393 // select celestialBodyId in GUI
395 for ( int row = 0; row < d->m_celestialListProxy.rowCount(); ++row ) {
396 if ( d->m_celestialListProxy.data( d->m_celestialListProxy.index( row, 1 ) ).toString() == celestialBodyId ) {
397 d->m_mapViewUi.celestialBodyComboBox->setCurrentIndex( row );
398 break;
399 }
400 }
401
402 d->updateMapFilter();
403 }
404
405 // select themeId in GUI
406 for ( int row = 0; row < d->m_mapSortProxy.rowCount(); ++row ) {
407 if( d->m_mapSortProxy.data( d->m_mapSortProxy.index( row, 0 ), Qt::UserRole + 1 ).toString() == themeId ) {
408 if ( smallscreen ) {
409 d->m_mapViewUi.mapThemeComboBox->setCurrentIndex( row );
410 }
411 else {
412 const QModelIndex index = d->m_mapSortProxy.index( row, 0 );
413 d->m_mapViewUi.marbleThemeSelectView->setCurrentIndex( index );
414 d->m_mapViewUi.marbleThemeSelectView->scrollTo( index );
415 }
416
417 break;
418 }
419 }
420}
421
422void MapViewWidget::setProjection( Projection projection )
423{
424 if ( (int)projection != d->m_mapViewUi.projectionComboBox->currentIndex() )
425 d->m_mapViewUi.projectionComboBox->setCurrentIndex( (int) projection );
426
427 if (d->m_toolBar) {
428 switch (projection) {
430 d->m_globeViewButton->setChecked(true);
431 d->m_globeViewAction->setChecked(true);
432 d->m_mercatorViewButton->setChecked(false);
433 d->m_mercatorViewAction->setChecked(false);
434 d->m_flatViewAction->setChecked(false);
435 d->m_gnomonicViewAction->setChecked(false);
436 d->m_stereographicViewAction->setChecked(false);
437 d->m_lambertAzimuthalViewAction->setChecked(false);
438 d->m_azimuthalEquidistantViewAction->setChecked(false);
439 d->m_verticalPerspectiveViewAction->setChecked(false);
440 break;
441 case Marble::Mercator:
442 d->m_mercatorViewButton->setChecked(true);
443 d->m_mercatorViewAction->setChecked(true);
444 d->m_globeViewButton->setChecked(false);
445 d->m_flatViewAction->setChecked(false);
446 d->m_gnomonicViewAction->setChecked(false);
447 d->m_globeViewAction->setChecked(false);
448 d->m_stereographicViewAction->setChecked(false);
449 d->m_lambertAzimuthalViewAction->setChecked(false);
450 d->m_azimuthalEquidistantViewAction->setChecked(false);
451 d->m_verticalPerspectiveViewAction->setChecked(false);
452 break;
454 d->m_flatViewAction->setChecked(true);
455 d->m_mercatorViewButton->setChecked(true);
456 d->m_globeViewButton->setChecked(false);
457 d->m_mercatorViewAction->setChecked(false);
458 d->m_gnomonicViewAction->setChecked(false);
459 d->m_globeViewAction->setChecked(false);
460 d->m_stereographicViewAction->setChecked(false);
461 d->m_lambertAzimuthalViewAction->setChecked(false);
462 d->m_azimuthalEquidistantViewAction->setChecked(false);
463 d->m_verticalPerspectiveViewAction->setChecked(false);
464 break;
465 case Marble::Gnomonic:
466 d->m_flatViewAction->setChecked(false);
467 d->m_mercatorViewButton->setChecked(true);
468 d->m_globeViewButton->setChecked(false);
469 d->m_mercatorViewAction->setChecked(false);
470 d->m_gnomonicViewAction->setChecked(true);
471 d->m_globeViewAction->setChecked(false);
472 d->m_stereographicViewAction->setChecked(false);
473 d->m_lambertAzimuthalViewAction->setChecked(false);
474 d->m_azimuthalEquidistantViewAction->setChecked(false);
475 d->m_verticalPerspectiveViewAction->setChecked(false);
476 break;
478 d->m_flatViewAction->setChecked(false);
479 d->m_mercatorViewButton->setChecked(true);
480 d->m_globeViewButton->setChecked(false);
481 d->m_mercatorViewAction->setChecked(false);
482 d->m_gnomonicViewAction->setChecked(false);
483 d->m_globeViewAction->setChecked(false);
484 d->m_stereographicViewAction->setChecked(true);
485 d->m_lambertAzimuthalViewAction->setChecked(false);
486 d->m_azimuthalEquidistantViewAction->setChecked(false);
487 d->m_verticalPerspectiveViewAction->setChecked(false);
488 break;
490 d->m_flatViewAction->setChecked(false);
491 d->m_mercatorViewButton->setChecked(true);
492 d->m_globeViewButton->setChecked(false);
493 d->m_mercatorViewAction->setChecked(false);
494 d->m_gnomonicViewAction->setChecked(false);
495 d->m_globeViewAction->setChecked(false);
496 d->m_stereographicViewAction->setChecked(false);
497 d->m_lambertAzimuthalViewAction->setChecked(true);
498 d->m_azimuthalEquidistantViewAction->setChecked(false);
499 d->m_verticalPerspectiveViewAction->setChecked(false);
500 break;
502 d->m_flatViewAction->setChecked(false);
503 d->m_mercatorViewButton->setChecked(true);
504 d->m_globeViewButton->setChecked(false);
505 d->m_mercatorViewAction->setChecked(false);
506 d->m_gnomonicViewAction->setChecked(false);
507 d->m_globeViewAction->setChecked(false);
508 d->m_stereographicViewAction->setChecked(false);
509 d->m_lambertAzimuthalViewAction->setChecked(false);
510 d->m_azimuthalEquidistantViewAction->setChecked(true);
511 d->m_verticalPerspectiveViewAction->setChecked(false);
512 break;
514 d->m_flatViewAction->setChecked(false);
515 d->m_mercatorViewButton->setChecked(true);
516 d->m_globeViewButton->setChecked(false);
517 d->m_mercatorViewAction->setChecked(false);
518 d->m_gnomonicViewAction->setChecked(false);
519 d->m_globeViewAction->setChecked(false);
520 d->m_stereographicViewAction->setChecked(false);
521 d->m_lambertAzimuthalViewAction->setChecked(false);
522 d->m_azimuthalEquidistantViewAction->setChecked(false);
523 d->m_verticalPerspectiveViewAction->setChecked(true);
524 break;
525 }
526 }
527}
528
529void MapViewWidget::globeViewRequested()
530{
531 emit projectionChanged(Marble::Spherical);
532}
533
534void MapViewWidget::flatViewRequested()
535{
536 emit projectionChanged(Marble::Equirectangular);
537}
538
539void MapViewWidget::mercatorViewRequested()
540{
541 emit projectionChanged(Marble::Mercator);
542}
543
544void MapViewWidget::gnomonicViewRequested()
545{
546 emit projectionChanged(Marble::Gnomonic);
547}
548
549void MapViewWidget::stereographicViewRequested()
550{
551 emit projectionChanged(Marble::Stereographic);
552}
553
554void MapViewWidget::lambertAzimuthalViewRequested()
555{
556 emit projectionChanged(Marble::LambertAzimuthal);
557}
558
559void MapViewWidget::azimuthalEquidistantViewRequested()
560{
561 emit projectionChanged(Marble::AzimuthalEquidistant);
562}
563
564void MapViewWidget::verticalPerspectiveViewRequested()
565{
566 emit projectionChanged(Marble::VerticalPerspective);
567}
568
569void MapViewWidget::Private::celestialBodySelected( int comboIndex )
570{
572
573 updateMapFilter();
574
575 bool foundMapTheme = false;
576
577 QString currentMapThemeId = m_marbleModel->mapThemeId();
578 QString oldPlanetId = m_marbleModel->planetId();
579
580 int row = m_mapSortProxy.rowCount();
581
582 for ( int i = 0; i < row; ++i )
583 {
584 QModelIndex index = m_mapSortProxy.index(i,0);
585 QString itMapThemeId = m_mapSortProxy.data(index, Qt::UserRole + 1).toString();
587 {
588 foundMapTheme = true;
589 break;
590 }
591 }
592 if ( !foundMapTheme ) {
593 QModelIndex index = m_mapSortProxy.index(0,0);
594 emit q->mapThemeIdChanged( m_mapSortProxy.data( index, Qt::UserRole + 1 ).toString() );
595 }
596
597 if( oldPlanetId != m_marbleModel->planetId() ) {
598 emit q->celestialBodyChanged( m_marbleModel->planetId() );
599 }
600}
601
602// Relay a signal and convert the parameter from an int to a Projection.
603void MapViewWidget::Private::projectionSelected( int projectionIndex )
604{
605 emit q->projectionChanged( (Projection) projectionIndex );
606}
607
608void MapViewWidget::Private::mapThemeSelected( QModelIndex index )
609{
610 mapThemeSelected( index.row() );
611}
612
613void MapViewWidget::Private::mapThemeSelected( int index )
614{
615 const QModelIndex columnIndex = m_mapSortProxy.index( index, 0 );
616 const QString currentmaptheme = m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
617
618 mDebug() << currentmaptheme;
619
620 emit q->mapThemeIdChanged( currentmaptheme );
621}
622
623QString MapViewWidget::Private::currentThemeName() const
624{
625 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
626 const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0, QModelIndex() );
627
628 return m_mapSortProxy.data( columnIndex ).toString();
629}
630
631QString MapViewWidget::Private::currentThemePath() const
632{
633 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
634 const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0 );
635
636 return m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
637}
638
639QString MapViewWidget::Private::favoriteKey(const QModelIndex &index) const
640{
641 return QLatin1String("Favorites/") + m_mapSortProxy.data(index).toString();
642}
643
644void MapViewWidget::Private::showContextMenu( const QPoint& pos )
645{
646 qDebug();
648 QMenu menu;
649
650 QAction* iconSizeAction = menu.addAction( tr( "&Show Large Icons" ), q, SLOT(toggleIconSize()) );
651 iconSizeAction->setCheckable( true );
652 iconSizeAction->setChecked( m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 ) );
653 QAction *favAction = menu.addAction(QIcon(QStringLiteral(":/icons/bookmarks.png")), tr("&Favorite"), q, SLOT(toggleFavorite()));
654 favAction->setCheckable( true );
655 favAction->setChecked( isCurrentFavorite() );
656 menu.addSeparator();
657
658 menu.addAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), q, SIGNAL(showMapWizard()));
659 if (QFileInfo(MarbleDirs::localPath() + QLatin1String("/maps/") + currentThemePath()).exists()) {
660 menu.addAction( tr( "&Delete Map Theme" ), q, SLOT(deleteMap()) );
661 }
662 menu.exec( m_mapViewUi.marbleThemeSelectView->mapToGlobal( pos ) );
663}
664
665void MapViewWidget::Private::deleteMap()
666{
668 tr( "Marble" ),
669 tr( "Are you sure that you want to delete \"%1\"?" ).arg( currentThemeName() ),
671 {
672 MapThemeManager::deleteMapTheme( currentThemePath() );
673 emit q->mapThemeDeleted();
674 }
675}
676
677void MapViewWidget::Private::toggleFavorite()
678{
679 QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
680 if( isCurrentFavorite() ) {
681 m_settings.remove(favoriteKey(index));
682 } else {
683 m_settings.setValue(favoriteKey(index), QDateTime::currentDateTime() );
684 }
685 QStandardItemModel* sourceModel = qobject_cast<QStandardItemModel*>(m_mapSortProxy.sourceModel());
686 const QModelIndex sourceIndex = m_mapSortProxy.mapToSource(index);
687 emit sourceModel->dataChanged( sourceIndex, sourceIndex );
688 index = m_mapViewUi.marbleThemeSelectView->currentIndex();
689 m_mapViewUi.marbleThemeSelectView->scrollTo(index);
690}
691
692void MapViewWidget::Private::toggleIconSize()
693{
694 bool const isLarge = m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 );
695 int const size = isLarge ? 52 : 96;
696 m_mapViewUi.marbleThemeSelectView->setIconSize( QSize( size, size ) );
697 m_settings.setValue(QStringLiteral("MapView/iconSize"), m_mapViewUi.marbleThemeSelectView->iconSize() );
698}
699
700bool MapViewWidget::Private::isCurrentFavorite() const
701{
702 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
703 return m_settings.contains(favoriteKey(index));
704}
705
706}
707
708#include "moc_MapViewWidget.cpp"
This file contains the headers for MarbleModel.
This file contains the headers for MarbleWidget.
Provides access to all map themes installed locally.
The CelestialSortFilterProxyModel class is a proxy used by both MapViewWidget's listview,...
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
A small trick to change names for dwarfs and moons.
static void deleteMapTheme(const QString &mapThemeId)
Deletes the map theme with the specified map theme ID.
The MapViewItemDelegate class is a delegate class for both the MapViewWidget's listView and MapChange...
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition MarbleModel.h:87
A widget class that displays a view of the earth.
MarbleModel * model()
Return the model that this view shows.
Binds a QML item to a specific geodetic location in screen coordinates.
Projection
This enum is used to choose the projection shown in the view.
@ Mercator
Mercator projection.
@ VerticalPerspective
Vertical perspective projection.
@ AzimuthalEquidistant
Azimuthal Equidistant projection.
@ Gnomonic
Gnomonic projection.
@ LambertAzimuthal
Lambert Azimuthal Equal-Area projection.
@ Equirectangular
Flat projection ("plate carree")
@ Spherical
Spherical projection ("Orthographic")
@ Stereographic
Stereographic projection.
void setChecked(bool)
void setIcon(const QIcon &icon)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
void setChecked(bool)
QDateTime currentDateTime()
virtual void addItem(QLayoutItem *item) override
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
QAction * addSeparator()
QAction * exec()
StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QVariant data(int role) const const
int row() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
virtual QVariant data(const QModelIndex &index, int role) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual int rowCount(const QModelIndex &parent) const const override
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
virtual void sort(int column, Qt::SortOrder order) override
QChar * data()
bool isEmpty() const const
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
CaseInsensitive
UserRole
ScrollBarAlwaysOff
typedef WindowFlags
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const
virtual bool event(QEvent *event) override
void setupUi(QWidget *widget)
bool isVisible() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.