• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
MapViewWidget.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
9 // Copyright 2007 Inge Wallin <ingwa@kde.org>
10 // Copyright 2007 Thomas Zander <zander@kde.org>
11 // Copyright 2010 Bastian Holst <bastianholst@gmx.de>
12 // Coprright 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
13 // Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
14 //
15 
16 // Self
17 #include "MapViewWidget.h"
18 
19 // Marble
20 #include "MarbleDebug.h"
21 #include "MarbleDirs.h"
22 #include "MarbleWidget.h"
23 #include "MarbleModel.h"
24 #include "MapThemeManager.h"
25 #include "MapThemeSortFilterProxyModel.h"
26 #include "GeoSceneDocument.h"
27 #include "GeoSceneHead.h"
28 
29 // Qt
30 #include <QResizeEvent>
31 #include <QFileInfo>
32 #include <QSettings>
33 #include <QMenu>
34 #include <QMessageBox>
35 #include <QStandardItemModel>
36 #include <QGridLayout>
37 #include <QPainter>
38 #include <QToolBar>
39 #include <QToolButton>
40 #include <QTextDocument>
41 #include <QAbstractTextDocumentLayout>
42 #include <QStyledItemDelegate>
43 
44 using namespace Marble;
45 // Ui
46 #include "ui_MapViewWidget.h"
47 
48 namespace Marble
49 {
50 
51 class MapViewItemDelegate : public QStyledItemDelegate
52 {
53 public:
54  MapViewItemDelegate( QListView* view );
55  void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
56  QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
57 
58 private:
59  static QString text( const QModelIndex &index );
60  QListView* m_view;
61  QIcon m_bookmarkIcon;
62 };
63 
64 class CelestialSortFilterProxyModel : public QSortFilterProxyModel
65 {
66 public:
67  CelestialSortFilterProxyModel()
68  {
69  setupPriorities();
70  setupMoonsList();
71  setupDwarfsList();
72  }
73  ~CelestialSortFilterProxyModel() {}
74 
75  // A small trick to change names for dwarfs and moons
76  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
77  {
78  QVariant var = QSortFilterProxyModel::data(index, role);
79  if (role == Qt::DisplayRole && index.column() == 0) {
80  QString newOne = var.toString();
81  if (newOne == tr("Moon")) {
82  return QString(" " + tr("Moon"));
83  } else if (m_moons.contains(newOne.toLower())) {
84  return QString(" "+newOne+" (" + tr("moon") + ')');
85  } else if (m_dwarfs.contains(newOne.toLower())) {
86  return QString(newOne+ " (" + tr("dwarf planet") + ')');
87  }
88  return newOne;
89  } else {
90  return var;
91  }
92  }
93 
94 private:
95  // TODO: create priority on the model side (Planet Class) by taking the distance to the "home planet/home star" into account
96  void setupPriorities()
97  {
98  // here we will set m_priority for default order
99  int prefix = 100;
100 
101  m_priority["sun"] = prefix;
102  m_priority["mercury"] = prefix--;
103  m_priority["venus"] = prefix--;
104  m_priority["earth"] = prefix--;
105  m_priority["moon"] = prefix--;
106  m_priority["mars"] = prefix--;
107 
108  m_priority["jupiter"] = prefix--;
109  // Moons of Jupiter
110  m_priority["io"] = prefix--;
111  m_priority["europa"] = prefix--;
112  m_priority["ganymede"] = prefix--;
113  m_priority["callisto"] = prefix--;
114 
115  m_priority["saturn"] = prefix--;
116  // Moons of Saturn
117  m_priority["mimas"] = prefix--;
118  m_priority["enceladus"] = prefix--;
119  m_priority["thetys"] = prefix--;
120  m_priority["dione"] = prefix--;
121  m_priority["rhea"] = prefix--;
122  m_priority["titan"] = prefix--;
123  m_priority["iapetus"] = prefix--;
124 
125  m_priority["uranus"] = prefix--;
126  m_priority["neptune"] = prefix--;
127  m_priority["pluto"] = prefix--;
128  m_priority["ceres"] = prefix--;
129  }
130 
131  void setupMoonsList()
132  {
133  m_moons.push_back("moon");
134  m_moons.push_back("europa");
135  m_moons.push_back("ganymede");
136  m_moons.push_back("callisto");
137  m_moons.push_back("mimas");
138  m_moons.push_back("enceladus");
139  m_moons.push_back("thetys");
140  m_moons.push_back("dione");
141  m_moons.push_back("rhea");
142  m_moons.push_back("titan");
143  m_moons.push_back("iapetus");
144  }
145 
146  void setupDwarfsList()
147  {
148  m_dwarfs.push_back("pluto");
149  m_dwarfs.push_back("ceres");
150  }
151 
152 protected:
153  bool lessThan(const QModelIndex &left, const QModelIndex &right) const {
154  const QString nameLeft = sourceModel()->index(left.row(), 1).data().toString();
155  const QString nameRight = sourceModel()->index(right.row(), 1).data().toString();
156  const QString first = nameLeft.toLower();
157  const QString second = nameRight.toLower();
158 
159  // both are in the list
160  if (m_priority.contains(first) && m_priority.contains(second)) {
161  return m_priority[first] > m_priority[second];
162  }
163 
164  // only left in the list
165  if (m_priority.contains(first) && !m_priority.contains(second)) {
166  return true;
167  }
168 
169  // only right in the list
170  if (!m_priority.contains(first) && m_priority.contains(second)) {
171  return false;
172  }
173 
174  return QSortFilterProxyModel::lessThan(left, right);
175  }
176 
177 private:
178  QMap<QString, int> m_priority;
179  QList<QString> m_moons;
180  QList<QString> m_dwarfs;
181 };
182 
183 class MapViewWidget::Private {
184  public:
185  Private( MapViewWidget *parent )
186  : q( parent ),
187  m_marbleModel( 0 ),
188  m_mapSortProxy(),
189  m_celestialListProxy(),
190  m_toolBar( 0 ),
191  m_globeViewButton( 0 ),
192  m_mercatorViewButton( 0 ),
193  m_popupMenu( 0 ),
194  m_flatViewAction( 0 ),
195  m_mercatorViewAction( 0 ),
196  m_celestialBodyAction( 0 )
197  {
198  m_mapSortProxy.setDynamicSortFilter( true );
199  m_celestialListProxy.setDynamicSortFilter( true );
200  }
201 
202  void applyExtendedLayout()
203  {
204  m_mapViewUi.projectionLabel_2->setVisible(true);
205  m_mapViewUi.celestialBodyLabel->setVisible(true);
206  m_mapViewUi.projectionComboBox->setVisible(true);
207  m_mapViewUi.mapThemeLabel->setVisible(true);
208  m_mapViewUi.line->setVisible(true);
209 
210  m_toolBar->setVisible(false);
211  const int labelId = m_mapViewUi.verticalLayout->indexOf(m_mapViewUi.celestialBodyLabel);
212  m_mapViewUi.verticalLayout->insertWidget(labelId+1, m_mapViewUi.celestialBodyComboBox);
213  m_toolBar->removeAction(m_celestialBodyAction);
214  m_mapViewUi.celestialBodyComboBox->show();
215  }
216 
217  void applyReducedLayout()
218  {
219  m_mapViewUi.projectionLabel_2->setVisible(false);
220  m_mapViewUi.celestialBodyLabel->setVisible(false);
221  m_mapViewUi.projectionComboBox->setVisible(false);
222  m_mapViewUi.mapThemeLabel->setVisible(false);
223  m_mapViewUi.line->setVisible(false);
224 
225  m_toolBar->setVisible(true);
226  m_celestialBodyAction = m_toolBar->addWidget(m_mapViewUi.celestialBodyComboBox);
227  m_mapViewUi.verticalLayout->removeWidget(m_mapViewUi.celestialBodyComboBox);
228  m_mapViewUi.celestialBodyComboBox->show();
229  }
230 
231  void setupToolBar()
232  {
233  m_toolBar = new QToolBar;
234 
235  m_globeViewButton = new QToolButton;
236  m_globeViewButton->setIcon( QIcon(":/icons/map-globe.png") );
237  m_globeViewButton->setToolTip( tr("Globe View") );
238  m_globeViewButton->setCheckable(true);
239  m_globeViewButton->setChecked(false);
240 
241  m_mercatorViewButton = new QToolButton;
242  m_mercatorViewButton->setIcon( QIcon(":/icons/map-mercator.png") );
243  m_mercatorViewButton->setToolTip( tr("Mercator View") );
244  m_mercatorViewButton->setCheckable(true);
245  m_mercatorViewButton->setChecked(false);
246  m_mercatorViewButton->setPopupMode(QToolButton::MenuButtonPopup);
247 
248  m_popupMenu = new QMenu;
249 
250  m_mercatorViewAction = new QAction( QIcon(":/icons/map-mercator.png"),
251  tr("Mercator View"),
252  m_popupMenu );
253  m_mercatorViewAction->setCheckable(true);
254  m_mercatorViewAction->setChecked(false);
255 
256  m_flatViewAction = new QAction( QIcon(":/icons/map-flat.png"),
257  tr("Flat View"),
258  m_popupMenu );
259  m_flatViewAction->setCheckable(true);
260  m_flatViewAction->setChecked(false);
261 
262  m_popupMenu->addAction(m_mercatorViewAction);
263  m_popupMenu->addAction(m_flatViewAction);
264  m_mercatorViewButton->setMenu(m_popupMenu);
265 
266  m_toolBar->addWidget(m_globeViewButton);
267  m_toolBar->addWidget(m_mercatorViewButton);
268  m_toolBar->addSeparator();
269  m_toolBar->setContentsMargins(0,0,0,0);
270  m_toolBar->setIconSize(QSize(16, 16));
271  m_mapViewUi.toolBarLayout->insertWidget(0, m_toolBar);
272 
273  QObject::connect(m_globeViewButton, SIGNAL(clicked()),
274  q, SLOT(globeViewRequested()));
275  QObject::connect(m_mercatorViewButton, SIGNAL(clicked()),
276  q, SLOT(mercatorViewRequested()));
277  QObject::connect(m_mercatorViewAction, SIGNAL(triggered()),
278  q, SLOT(mercatorViewRequested()));
279  QObject::connect(m_flatViewAction, SIGNAL(triggered()),
280  q, SLOT(flatViewRequested()));
281 
282  applyReducedLayout();
283  }
284 
285  void updateMapFilter()
286  {
287  int currentIndex = m_mapViewUi.celestialBodyComboBox->currentIndex();
288  const QString selectedId = m_celestialListProxy.data( m_celestialListProxy.index( currentIndex, 1 ) ).toString();
289 
290  if ( !selectedId.isEmpty() ) {
291  m_mapSortProxy.setFilterRegExp( QRegExp( selectedId, Qt::CaseInsensitive,QRegExp::FixedString ) );
292  }
293  }
294 
295  void celestialBodySelected( int comboIndex );
296 
297  void projectionSelected( int projectionIndex );
298 
299  void mapThemeSelected( QModelIndex index );
300  void mapThemeSelected( int index );
301 
302  void showContextMenu( const QPoint& pos );
303  void deleteMap();
304  void toggleFavorite();
305  void toggleIconSize();
306 
307  bool isCurrentFavorite();
308  QString currentThemeName() const;
309  QString currentThemePath() const;
310 
311  MapViewWidget *const q;
312 
313  Ui::MapViewWidget m_mapViewUi;
314  MarbleModel *m_marbleModel;
315 
316  MapThemeSortFilterProxyModel m_mapSortProxy;
317 
318  CelestialSortFilterProxyModel m_celestialListProxy;
319  QSettings m_settings;
320  QToolBar *m_toolBar;
321  QToolButton *m_globeViewButton;
322  QToolButton *m_mercatorViewButton;
323  QMenu *m_popupMenu;
324  QAction *m_flatViewAction;
325  QAction *m_mercatorViewAction;
326  QAction *m_celestialBodyAction;
327 };
328 
329 MapViewWidget::MapViewWidget( QWidget *parent, Qt::WindowFlags f )
330  : QWidget( parent, f ),
331  d( new Private( this ) )
332 {
333  d->m_mapViewUi.setupUi( this );
334  layout()->setMargin( 0 );
335 
336  if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
337  QGridLayout* layout = new QGridLayout;
338  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 0 );
339  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 1 );
340  d->m_mapViewUi.line->setVisible( false );
341  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 0 );
342  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 1 );
343  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 3 ), 2, 0 );
344  layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 4 ), 2, 1 );
345  d->m_mapViewUi.verticalLayout->insertLayout( 0, layout );
346  d->m_mapViewUi.mapThemeComboBox->setModel( &d->m_mapSortProxy );
347  d->m_mapViewUi.mapThemeComboBox->setIconSize( QSize( 48, 48 ) );
348  connect( d->m_mapViewUi.mapThemeComboBox, SIGNAL(activated(int)),
349  this, SLOT(mapThemeSelected(int)) );
350  d->m_mapViewUi.marbleThemeSelectView->setVisible( false );
351  }
352  else {
353  d->m_mapViewUi.marbleThemeSelectView->setViewMode( QListView::IconMode );
354  QSize const iconSize = d->m_settings.value( "MapView/iconSize", QSize( 90, 90 ) ).toSize();
355  d->m_mapViewUi.marbleThemeSelectView->setIconSize( iconSize );
356  d->m_mapViewUi.marbleThemeSelectView->setItemDelegate( new MapViewItemDelegate( d->m_mapViewUi.marbleThemeSelectView ) );
357  d->m_mapViewUi.marbleThemeSelectView->setAlternatingRowColors( true );
358  d->m_mapViewUi.marbleThemeSelectView->setFlow( QListView::LeftToRight );
359  d->m_mapViewUi.marbleThemeSelectView->setWrapping( true );
360  d->m_mapViewUi.marbleThemeSelectView->setResizeMode( QListView::Adjust );
361  d->m_mapViewUi.marbleThemeSelectView->setUniformItemSizes( true );
362  d->m_mapViewUi.marbleThemeSelectView->setMovement( QListView::Static );
363  d->m_mapViewUi.marbleThemeSelectView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
364  d->m_mapViewUi.marbleThemeSelectView->setEditTriggers( QListView::NoEditTriggers );
365  d->m_mapViewUi.marbleThemeSelectView->setSelectionMode( QListView::SingleSelection );
366  d->m_mapViewUi.marbleThemeSelectView->setModel( &d->m_mapSortProxy );
367  connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(pressed(QModelIndex)),
368  this, SLOT(mapThemeSelected(QModelIndex)) );
369  connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(customContextMenuRequested(QPoint)),
370  this, SLOT(showContextMenu(QPoint)) );
371 
372  d->m_mapViewUi.mapThemeComboBox->setVisible( false );
373  d->setupToolBar();
374  }
375 
376  connect( d->m_mapViewUi.projectionComboBox, SIGNAL(activated(int)),
377  this, SLOT(projectionSelected(int)) );
378 
379  d->m_mapViewUi.projectionComboBox->setEnabled( true );
380  d->m_mapViewUi.celestialBodyComboBox->setModel( &d->m_celestialListProxy );
381 
382  connect( d->m_mapViewUi.celestialBodyComboBox, SIGNAL(activated(int)),
383  this, SLOT(celestialBodySelected(int)) );
384 
385  d->m_settings.beginGroup( "Favorites" );
386  if( !d->m_settings.contains( "initialized" ) ) {
387  d->m_settings.setValue( "initialized", true );
388  QDateTime currentDateTime = QDateTime::currentDateTime();
389  d->m_settings.setValue( "Atlas", currentDateTime );
390  d->m_settings.setValue( "OpenStreetMap", currentDateTime );
391  d->m_settings.setValue( "Satellite View", currentDateTime );
392  }
393  d->m_settings.endGroup();
394 }
395 
396 MapViewWidget::~MapViewWidget()
397 {
398  delete d;
399 }
400 
401 void MapViewWidget::setMarbleWidget( MarbleWidget *widget, MapThemeManager *mapThemeManager )
402 {
403  d->m_marbleModel = widget->model();
404  d->m_mapSortProxy.setSourceModel( mapThemeManager->mapThemeModel() );
405  d->m_mapSortProxy.sort( 0 );
406  d->m_celestialListProxy.setSourceModel( mapThemeManager->celestialBodiesModel() );
407  d->m_celestialListProxy.sort( 0 );
408 
409  connect( this, SIGNAL(projectionChanged(Projection)),
410  widget, SLOT(setProjection(Projection)) );
411 
412  connect( widget, SIGNAL(themeChanged(QString)),
413  this, SLOT(setMapThemeId(QString)) );
414 
415  connect( widget, SIGNAL(projectionChanged(Projection)),
416  this, SLOT(setProjection(Projection)) );
417 
418  connect( this, SIGNAL(mapThemeIdChanged(QString)),
419  widget, SLOT(setMapThemeId(QString)) );
420 
421  setProjection(widget->projection());
422  setMapThemeId(widget->mapThemeId());
423 }
424 
425 void MapViewWidget::resizeEvent(QResizeEvent *event)
426 {
427  if (!d->m_toolBar)
428  return;
429 
430  if (d->m_toolBar->isVisible() && event->size().height() > 400) {
431  d->applyExtendedLayout();
432  } else if (!d->m_toolBar->isVisible() && event->size().height() <= 400) {
433  d->applyReducedLayout();
434  }
435 }
436 
437 void MapViewWidget::setMapThemeId( const QString &themeId )
438 {
439  const bool smallscreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
440 
441  const int currentRow = smallscreen ? d->m_mapViewUi.mapThemeComboBox->currentIndex() :
442  d->m_mapViewUi.marbleThemeSelectView->currentIndex().row();
443  const QString oldThemeId = d->m_mapSortProxy.data( d->m_mapSortProxy.index( currentRow, 0 ), Qt::UserRole + 1 ).toString();
444 
445  // Check if the new selected theme is different from the current one
446  if ( themeId == oldThemeId )
447  return;
448 
449  const QString oldCelestialBodyId = oldThemeId.section( '/', 0, 0 );
450  const QString celestialBodyId = themeId.section( '/', 0, 0 );
451 
452  // select celestialBodyId in GUI
453  if ( celestialBodyId != oldCelestialBodyId ) {
454  for ( int row = 0; row < d->m_celestialListProxy.rowCount(); ++row ) {
455  if ( d->m_celestialListProxy.data( d->m_celestialListProxy.index( row, 1 ) ).toString() == celestialBodyId ) {
456  d->m_mapViewUi.celestialBodyComboBox->setCurrentIndex( row );
457  break;
458  }
459  }
460 
461  d->updateMapFilter();
462  }
463 
464  // select themeId in GUI
465  for ( int row = 0; row < d->m_mapSortProxy.rowCount(); ++row ) {
466  if( d->m_mapSortProxy.data( d->m_mapSortProxy.index( row, 0 ), Qt::UserRole + 1 ).toString() == themeId ) {
467  if ( smallscreen ) {
468  d->m_mapViewUi.mapThemeComboBox->setCurrentIndex( row );
469  }
470  else {
471  const QModelIndex index = d->m_mapSortProxy.index( row, 0 );
472  d->m_mapViewUi.marbleThemeSelectView->setCurrentIndex( index );
473  d->m_mapViewUi.marbleThemeSelectView->scrollTo( index );
474  }
475 
476  break;
477  }
478  }
479 }
480 
481 void MapViewWidget::setProjection( Projection projection )
482 {
483  if ( (int)projection != d->m_mapViewUi.projectionComboBox->currentIndex() )
484  d->m_mapViewUi.projectionComboBox->setCurrentIndex( (int) projection );
485 
486  if (d->m_toolBar) {
487  switch (projection) {
488  case Marble::Spherical:
489  d->m_globeViewButton->setChecked(true);
490  d->m_mercatorViewButton->setChecked(false);
491  d->m_mercatorViewAction->setChecked(false);
492  d->m_flatViewAction->setChecked(false);
493  break;
494  case Marble::Mercator:
495  d->m_mercatorViewButton->setChecked(true);
496  d->m_mercatorViewAction->setChecked(true);
497  d->m_globeViewButton->setChecked(false);
498  d->m_flatViewAction->setChecked(false);
499  break;
500  case Marble::Equirectangular:
501  d->m_flatViewAction->setChecked(true);
502  d->m_mercatorViewButton->setChecked(true);
503  d->m_globeViewButton->setChecked(false);
504  d->m_mercatorViewAction->setChecked(false);
505  break;
506  }
507  }
508 }
509 
510 void MapViewWidget::globeViewRequested()
511 {
512  emit projectionChanged(Marble::Spherical);
513 }
514 
515 void MapViewWidget::flatViewRequested()
516 {
517  emit projectionChanged(Marble::Equirectangular);
518 }
519 
520 void MapViewWidget::mercatorViewRequested()
521 {
522  emit projectionChanged(Marble::Mercator);
523 }
524 
525 void MapViewWidget::Private::celestialBodySelected( int comboIndex )
526 {
527  Q_UNUSED( comboIndex )
528 
529  updateMapFilter();
530 
531  bool foundMapTheme = false;
532 
533  QString currentMapThemeId = m_marbleModel->mapThemeId();
534  QString oldPlanetId = m_marbleModel->planetId();
535 
536  int row = m_mapSortProxy.rowCount();
537 
538  for ( int i = 0; i < row; ++i )
539  {
540  QModelIndex index = m_mapSortProxy.index(i,0);
541  QString itMapThemeId = m_mapSortProxy.data(index, Qt::UserRole + 1).toString();
542  if ( currentMapThemeId == itMapThemeId )
543  {
544  foundMapTheme = true;
545  break;
546  }
547  }
548  if ( !foundMapTheme ) {
549  QModelIndex index = m_mapSortProxy.index(0,0);
550  emit q->mapThemeIdChanged( m_mapSortProxy.data( index, Qt::UserRole + 1 ).toString() );
551  }
552 
553  if( oldPlanetId != m_marbleModel->planetId() ) {
554  emit q->celestialBodyChanged( m_marbleModel->planetId() );
555  }
556 }
557 
558 // Relay a signal and convert the parameter from an int to a Projection.
559 void MapViewWidget::Private::projectionSelected( int projectionIndex )
560 {
561  emit q->projectionChanged( (Projection) projectionIndex );
562 }
563 
564 void MapViewWidget::Private::mapThemeSelected( QModelIndex index )
565 {
566  mapThemeSelected( index.row() );
567 }
568 
569 void MapViewWidget::Private::mapThemeSelected( int index )
570 {
571  const QModelIndex columnIndex = m_mapSortProxy.index( index, 0 );
572  const QString currentmaptheme = m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
573 
574  mDebug() << Q_FUNC_INFO << currentmaptheme;
575 
576  emit q->mapThemeIdChanged( currentmaptheme );
577 }
578 
579 QString MapViewWidget::Private::currentThemeName() const
580 {
581  const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
582  const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0, QModelIndex() );
583 
584  return m_mapSortProxy.data( columnIndex ).toString();
585 }
586 
587 QString MapViewWidget::Private::currentThemePath() const
588 {
589  const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
590  const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0 );
591 
592  return m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
593 }
594 
595 void MapViewWidget::Private::showContextMenu( const QPoint& pos )
596 {
597  QMenu menu;
598 
599  QAction* iconSizeAction = menu.addAction( tr( "&Show Large Icons" ), q, SLOT(toggleIconSize()) );
600  iconSizeAction->setCheckable( true );
601  iconSizeAction->setChecked( m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 ) );
602  QAction *favAction = menu.addAction( QIcon( ":/icons/bookmarks.png" ), tr( "&Favorite" ), q, SLOT(toggleFavorite()) );
603  favAction->setCheckable( true );
604  favAction->setChecked( isCurrentFavorite() );
605  menu.addSeparator();
606 
607  menu.addAction( QIcon( ":/icons/create-new-map.png" ), tr("&Create a New Map..."), q, SIGNAL(showMapWizard()) );
608  if( QFileInfo( MarbleDirs::localPath() + "/maps/" + currentThemePath() ).exists() )
609  menu.addAction( tr( "&Delete Map Theme" ), q, SLOT(deleteMap()) );
610  menu.addAction( tr( "&Upload Map..." ), q, SIGNAL(showUploadDialog()) );
611  menu.exec( m_mapViewUi.marbleThemeSelectView->mapToGlobal( pos ) );
612 }
613 
614 void MapViewWidget::Private::deleteMap()
615 {
616  if(QMessageBox::warning( q,
617  tr( "Marble" ),
618  tr( "Are you sure that you want to delete \"%1\"?" ).arg( currentThemeName() ),
619  QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes )
620  {
621  MapThemeManager::deleteMapTheme( currentThemePath() );
622  emit q->mapThemeDeleted();
623  }
624 }
625 
626 void MapViewWidget::Private::toggleFavorite()
627 {
628  const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
629  const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0 );
630 
631  if( isCurrentFavorite() ) {
632  m_settings.beginGroup( "Favorites" );
633  m_settings.remove( m_mapSortProxy.data( columnIndex ).toString() );
634  }
635  else {
636  m_settings.beginGroup( "Favorites" );
637  m_settings.setValue( m_mapSortProxy.data( columnIndex ).toString(), QDateTime::currentDateTime() );
638  }
639  m_settings.endGroup();
640 }
641 
642 void MapViewWidget::Private::toggleIconSize()
643 {
644  bool const isLarge = m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 );
645  int const size = isLarge ? 52 : 96;
646  m_mapViewUi.marbleThemeSelectView->setIconSize( QSize( size, size ) );
647  m_settings.setValue("MapView/iconSize", m_mapViewUi.marbleThemeSelectView->iconSize() );
648 }
649 
650 bool MapViewWidget::Private::isCurrentFavorite()
651 {
652  const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
653  const QModelIndex nameIndex = m_mapSortProxy.index( index.row(), 0 );
654 
655  m_settings.beginGroup( "Favorites" );
656  const bool isFavorite = m_settings.contains( m_mapSortProxy.data( nameIndex ).toString() );
657  m_settings.endGroup();
658 
659  return isFavorite;
660 }
661 
662 MapViewItemDelegate::MapViewItemDelegate( QListView *view ) :
663  m_view( view ), m_bookmarkIcon( ":/icons/bookmarks.png" )
664 {
665  // nothing to do
666 }
667 
668 void MapViewItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
669 {
670  QStyleOptionViewItemV4 styleOption = option;
671  initStyleOption( &styleOption, index );
672  styleOption.text = QString();
673  styleOption.icon = QIcon();
674 
675  bool const selected = styleOption.state & QStyle::State_Selected;
676  bool const active = styleOption.state & QStyle::State_Active;
677  bool const hover = styleOption.state & QStyle::State_MouseOver;
678  QPalette::ColorGroup const colorGroup = active ? QPalette::Active : QPalette::Inactive;
679  if ( selected || hover ) {
680  styleOption.features &= ~QStyleOptionViewItemV2::Alternate;
681  QPalette::ColorRole colorRole = selected ? QPalette::Highlight : QPalette::Midlight;
682  painter->fillRect( styleOption.rect, styleOption.palette.color( colorGroup, colorRole ) );
683  }
684  QStyle* style = styleOption.widget ? styleOption.widget->style() : QApplication::style();
685  style->drawControl( QStyle::CE_ItemViewItem, &styleOption, painter, styleOption.widget );
686 
687  QRect const rect = styleOption.rect;
688  QSize const iconSize = styleOption.decorationSize;
689  QRect const iconRect( rect.topLeft(), iconSize );
690  QIcon const icon = index.data( Qt::DecorationRole ).value<QIcon>();
691  painter->drawPixmap( iconRect, icon.pixmap( iconSize ) );
692 
693  int const padding = 5;
694  QString const name = index.data().toString();
695  const bool isFavorite = QSettings().contains( "Favorites/" + name );
696  QSize const bookmarkSize( 16, 16 );
697  QRect bookmarkRect( iconRect.bottomRight(), bookmarkSize );
698  bookmarkRect.translate( QPoint( -bookmarkSize.width() - padding, -bookmarkSize.height() - padding ) );
699  QIcon::Mode mode = isFavorite ? QIcon::Normal : QIcon::Disabled;
700  painter->drawPixmap( bookmarkRect, m_bookmarkIcon.pixmap( bookmarkSize, mode ) );
701 
702  QTextDocument document;
703  document.setTextWidth( rect.width() - iconSize.width() - padding );
704  document.setDefaultFont( styleOption.font );
705  document.setHtml( text( index ) );
706 
707  QRect textRect = QRect( iconRect.topRight(), QSize( document.textWidth() - padding, rect.height() - padding ) );
708  painter->save();
709  painter->translate( textRect.topLeft() );
710  painter->setClipRect( textRect.translated( -textRect.topLeft() ) );
711  QAbstractTextDocumentLayout::PaintContext paintContext;
712  paintContext.palette = styleOption.palette;
713  QPalette::ColorRole const role = selected && active ? QPalette::HighlightedText : QPalette::Text;
714  paintContext.palette.setColor( QPalette::Text, styleOption.palette.color( colorGroup, role ) );
715  document.documentLayout()->draw( painter, paintContext );
716  painter->restore();
717 }
718 
719 QSize MapViewItemDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
720 {
721  if ( index.column() == 0 ) {
722  QSize const iconSize = option.decorationSize;
723  QTextDocument doc;
724  doc.setDefaultFont( option.font );
725  doc.setTextWidth( m_view->width() - iconSize.width() - 10 );
726  doc.setHtml( text( index ) );
727  return QSize( iconSize.width() + doc.size().width(), iconSize.height() );
728  }
729 
730  return QSize();
731 }
732 
733 QString MapViewItemDelegate::text( const QModelIndex &index )
734 {
735  QString const title = index.data().toString();
736  QString const description = index.data( Qt::UserRole+2 ).toString();
737  return QString("<p><b>%1</b></p>%2").arg( title ).arg( description );
738 }
739 
740 }
741 
742 #include "MapViewWidget.moc"
QWidget::layout
QLayout * layout() const
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
GeoSceneHead.h
Marble::MapThemeManager::mapThemeModel
QStandardItemModel * mapThemeModel()
Provides a model of the locally existing themes.
Definition: MapThemeManager.cpp:319
QSortFilterProxyModel::lessThan
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const
QModelIndex
QResizeEvent
QWidget
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
QSize::width
int width() const
QPainter::fillRect
void fillRect(const QRectF &rectangle, const QBrush &brush)
Marble::MarbleWidget::projection
int projection
Definition: MarbleWidget.h:114
QAction::setChecked
void setChecked(bool)
MarbleModel.h
This file contains the headers for MarbleModel.
QMap< QString, int >
QMenu::addAction
void addAction(QAction *action)
QRect::translate
void translate(int dx, int dy)
QPainter::save
void save()
Marble::MapViewWidget::setMapThemeId
void setMapThemeId(const QString &)
Definition: MapViewWidget.cpp:437
QVariant::value
T value() const
Marble::MapViewWidget::setProjection
void setProjection(Projection projection)
Definition: MapViewWidget.cpp:481
QRect::height
int height() const
Marble::MapViewWidget
Definition: MapViewWidget.h:32
GeoSceneDocument.h
Marble::MarbleDirs::localPath
static QString localPath()
Definition: MarbleDirs.cpp:223
QGridLayout
QPoint
Marble::MapViewWidget::Private
friend class Private
Definition: MapViewWidget.h:81
Marble::MapViewWidget::mapThemeIdChanged
void mapThemeIdChanged(const QString &)
MarbleDebug.h
QAbstractButton::setIcon
void setIcon(const QIcon &icon)
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
Marble::MarbleWidget
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:104
QListView
Marble::Equirectangular
Flat projection ("plate carree")
Definition: MarbleGlobal.h:46
QRegExp
QRect
Marble::Mercator
Mercator projection.
Definition: MarbleGlobal.h:47
QStyleOptionViewItemV2
QStyleOptionViewItem
QStyle
QPainter::drawPixmap
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
Marble::MarbleWidget::model
MarbleModel * model()
Return the model that this view shows.
Definition: MarbleWidget.cpp:289
QSettings::contains
bool contains(const QString &key) const
QPainter
MarbleDirs.h
QString::isEmpty
bool isEmpty() const
QModelIndex::row
int row() const
Marble::MapThemeManager::deleteMapTheme
static void deleteMapTheme(const QString &mapThemeId)
Deletes the map theme with the specified map theme ID.
Definition: MapThemeManager.cpp:163
QWidget::pos
QPoint pos() const
QTextDocument::documentLayout
QAbstractTextDocumentLayout * documentLayout() const
QRect::translated
QRect translated(int dx, int dy) const
QMenu::addSeparator
QAction * addSeparator()
QString
QList< QString >
QLayout::setMargin
void setMargin(int margin)
QMenu::exec
QAction * exec()
QAbstractTextDocumentLayout::PaintContext
QTextDocument::size
size
iconSize
const QSize iconSize(16, 16)
QFileInfo
QString::toLower
QString toLower() const
QToolButton
QTextDocument::setDefaultFont
void setDefaultFont(const QFont &font)
QMenu
QSettings
Marble::MapViewWidget::projectionChanged
void projectionChanged(Projection)
QSize
MapThemeSortFilterProxyModel.h
QSortFilterProxyModel
Marble::MarbleGlobal::SmallScreen
Definition: MarbleGlobal.h:287
QAction::setCheckable
void setCheckable(bool)
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
QPainter::restore
void restore()
QTextDocument::setTextWidth
void setTextWidth(qreal width)
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:97
QAbstractProxyModel::sourceModel
QAbstractItemModel * sourceModel() const
QDateTime::currentDateTime
QDateTime currentDateTime()
Marble::MapThemeManager
The class that handles map themes that are locally available .
Definition: MapThemeManager.h:48
QRect::width
int width() const
Marble::MapViewWidget::setMarbleWidget
void setMarbleWidget(MarbleWidget *widget, MapThemeManager *mapThemeManager)
Set a MarbleWidget associated to this widget.
Definition: MapViewWidget.cpp:401
QPainter::setClipRect
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
QTest::toString
char * toString(const T &value)
QModelIndex::data
QVariant data(int role) const
QApplication::style
QStyle * style()
QTextDocument
QGridLayout::addItem
void addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, QFlags< Qt::AlignmentFlag > alignment)
QStyle::drawControl
virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const =0
QAction
QToolBar
QSize::height
int height() const
Marble::MarbleGlobal::profiles
Profiles profiles() const
Definition: MarbleGlobal.cpp:48
QRect::topLeft
QPoint topLeft() const
QModelIndex::column
int column() const
QPainter::translate
void translate(const QPointF &offset)
Marble::Projection
Projection
This enum is used to choose the projection shown in the view.
Definition: MarbleGlobal.h:44
QTextDocument::setHtml
void setHtml(const QString &html)
QString::section
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
QAbstractTextDocumentLayout::draw
virtual void draw(QPainter *painter, const PaintContext &context)=0
Marble::MarbleWidget::mapThemeId
QString mapThemeId
Definition: MarbleWidget.h:113
MarbleWidget.h
This file contains the headers for MarbleWidget.
QMessageBox::warning
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
Qt::WindowFlags
typedef WindowFlags
QStyleOptionViewItemV4
Marble::Spherical
Spherical projection.
Definition: MarbleGlobal.h:45
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
MapViewWidget.h
Marble::MapViewWidget::resizeEvent
void resizeEvent(QResizeEvent *event)
Definition: MapViewWidget.cpp:425
QString::data
QChar * data()
Marble::MapViewWidget::MapViewWidget
MapViewWidget(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: MapViewWidget.cpp:329
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QVariant::toString
QString toString() const
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:36
Marble::MapThemeManager::celestialBodiesModel
QStandardItemModel * celestialBodiesModel()
Provides a model of all installed planets.
Definition: MapThemeManager.cpp:328
Marble::MapThemeSortFilterProxyModel
Definition: MapThemeSortFilterProxyModel.h:21
MapThemeManager.h
QSortFilterProxyModel::data
virtual QVariant data(const QModelIndex &index, int role) const
QIcon
QDateTime
Marble::MapViewWidget::~MapViewWidget
~MapViewWidget()
Definition: MapViewWidget.cpp:396
QVariant
QStyledItemDelegate
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal