30 #include <QResizeEvent>
34 #include <QMessageBox>
35 #include <QStandardItemModel>
36 #include <QGridLayout>
39 #include <QToolButton>
40 #include <QTextDocument>
41 #include <QAbstractTextDocumentLayout>
42 #include <QStyledItemDelegate>
44 using namespace Marble;
46 #include "ui_MapViewWidget.h"
67 CelestialSortFilterProxyModel()
73 ~CelestialSortFilterProxyModel() {}
79 if (role == Qt::DisplayRole && index.
column() == 0) {
81 if (newOne ==
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") +
')');
96 void setupPriorities()
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--;
108 m_priority[
"jupiter"] = prefix--;
110 m_priority[
"io"] = prefix--;
111 m_priority[
"europa"] = prefix--;
112 m_priority[
"ganymede"] = prefix--;
113 m_priority[
"callisto"] = prefix--;
115 m_priority[
"saturn"] = prefix--;
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--;
125 m_priority[
"uranus"] = prefix--;
126 m_priority[
"neptune"] = prefix--;
127 m_priority[
"pluto"] = prefix--;
128 m_priority[
"ceres"] = prefix--;
131 void setupMoonsList()
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");
146 void setupDwarfsList()
148 m_dwarfs.push_back(
"pluto");
149 m_dwarfs.push_back(
"ceres");
160 if (m_priority.contains(first) && m_priority.contains(second)) {
161 return m_priority[first] > m_priority[second];
165 if (m_priority.contains(first) && !m_priority.contains(second)) {
170 if (!m_priority.contains(first) && m_priority.contains(second)) {
189 m_celestialListProxy(),
191 m_globeViewButton( 0 ),
192 m_mercatorViewButton( 0 ),
194 m_flatViewAction( 0 ),
195 m_mercatorViewAction( 0 ),
196 m_celestialBodyAction( 0 )
198 m_mapSortProxy.setDynamicSortFilter(
true );
199 m_celestialListProxy.setDynamicSortFilter(
true );
202 void applyExtendedLayout()
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);
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();
217 void applyReducedLayout()
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);
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();
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);
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);
248 m_popupMenu =
new QMenu;
250 m_mercatorViewAction =
new QAction(
QIcon(
":/icons/map-mercator.png"),
253 m_mercatorViewAction->setCheckable(
true);
254 m_mercatorViewAction->setChecked(
false);
256 m_flatViewAction =
new QAction(
QIcon(
":/icons/map-flat.png"),
259 m_flatViewAction->setCheckable(
true);
260 m_flatViewAction->setChecked(
false);
262 m_popupMenu->addAction(m_mercatorViewAction);
263 m_popupMenu->addAction(m_flatViewAction);
264 m_mercatorViewButton->setMenu(m_popupMenu);
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);
274 q, SLOT(globeViewRequested()));
276 q, SLOT(mercatorViewRequested()));
278 q, SLOT(mercatorViewRequested()));
280 q, SLOT(flatViewRequested()));
282 applyReducedLayout();
285 void updateMapFilter()
287 int currentIndex = m_mapViewUi.celestialBodyComboBox->currentIndex();
288 const QString selectedId = m_celestialListProxy.
data( m_celestialListProxy.index( currentIndex, 1 ) ).
toString();
291 m_mapSortProxy.setFilterRegExp(
QRegExp( selectedId, Qt::CaseInsensitive,QRegExp::FixedString ) );
295 void celestialBodySelected(
int comboIndex );
297 void projectionSelected(
int projectionIndex );
300 void mapThemeSelected(
int index );
302 void showContextMenu(
const QPoint&
pos );
304 void toggleFavorite();
305 void toggleIconSize();
307 bool isCurrentFavorite();
308 QString currentThemeName()
const;
309 QString currentThemePath()
const;
313 Ui::MapViewWidget m_mapViewUi;
318 CelestialSortFilterProxyModel m_celestialListProxy;
326 QAction *m_celestialBodyAction;
331 d( new Private( this ) )
333 d->m_mapViewUi.setupUi(
this );
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 );
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 );
370 this, SLOT(showContextMenu(
QPoint)) );
372 d->m_mapViewUi.mapThemeComboBox->setVisible(
false );
376 connect( d->m_mapViewUi.projectionComboBox, SIGNAL(activated(
int)),
377 this, SLOT(projectionSelected(
int)) );
379 d->m_mapViewUi.projectionComboBox->setEnabled(
true );
380 d->m_mapViewUi.celestialBodyComboBox->setModel( &d->m_celestialListProxy );
382 connect( d->m_mapViewUi.celestialBodyComboBox, SIGNAL(activated(
int)),
383 this, SLOT(celestialBodySelected(
int)) );
385 d->m_settings.beginGroup(
"Favorites" );
386 if( !d->m_settings.contains(
"initialized" ) ) {
387 d->m_settings.setValue(
"initialized",
true );
389 d->m_settings.setValue(
"Atlas", currentDateTime );
390 d->m_settings.setValue(
"OpenStreetMap", currentDateTime );
391 d->m_settings.setValue(
"Satellite View", currentDateTime );
393 d->m_settings.endGroup();
403 d->m_marbleModel = widget->
model();
404 d->m_mapSortProxy.setSourceModel( mapThemeManager->
mapThemeModel() );
405 d->m_mapSortProxy.sort( 0 );
407 d->m_celestialListProxy.sort( 0 );
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();
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();
446 if ( themeId == oldThemeId )
449 const QString oldCelestialBodyId = oldThemeId.
section(
'/', 0, 0 );
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 );
461 d->updateMapFilter();
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 ) {
468 d->m_mapViewUi.mapThemeComboBox->setCurrentIndex( row );
471 const QModelIndex index = d->m_mapSortProxy.index( row, 0 );
472 d->m_mapViewUi.marbleThemeSelectView->setCurrentIndex( index );
473 d->m_mapViewUi.marbleThemeSelectView->scrollTo( index );
483 if ( (
int)projection != d->m_mapViewUi.projectionComboBox->currentIndex() )
484 d->m_mapViewUi.projectionComboBox->setCurrentIndex( (
int) projection );
487 switch (projection) {
489 d->m_globeViewButton->setChecked(
true);
490 d->m_mercatorViewButton->setChecked(
false);
491 d->m_mercatorViewAction->setChecked(
false);
492 d->m_flatViewAction->setChecked(
false);
495 d->m_mercatorViewButton->setChecked(
true);
496 d->m_mercatorViewAction->setChecked(
true);
497 d->m_globeViewButton->setChecked(
false);
498 d->m_flatViewAction->setChecked(
false);
501 d->m_flatViewAction->setChecked(
true);
502 d->m_mercatorViewButton->setChecked(
true);
503 d->m_globeViewButton->setChecked(
false);
504 d->m_mercatorViewAction->setChecked(
false);
510 void MapViewWidget::globeViewRequested()
515 void MapViewWidget::flatViewRequested()
520 void MapViewWidget::mercatorViewRequested()
525 void MapViewWidget::Private::celestialBodySelected(
int comboIndex )
527 Q_UNUSED( comboIndex )
531 bool foundMapTheme = false;
533 QString currentMapThemeId = m_marbleModel->mapThemeId();
534 QString oldPlanetId = m_marbleModel->planetId();
536 int row = m_mapSortProxy.rowCount();
538 for (
int i = 0; i < row; ++i )
541 QString itMapThemeId = m_mapSortProxy.
data(index, Qt::UserRole + 1).toString();
542 if ( currentMapThemeId == itMapThemeId )
544 foundMapTheme =
true;
548 if ( !foundMapTheme ) {
550 emit q->mapThemeIdChanged( m_mapSortProxy.data( index, Qt::UserRole + 1 ).toString() );
553 if( oldPlanetId != m_marbleModel->planetId() ) {
554 emit q->celestialBodyChanged( m_marbleModel->planetId() );
559 void MapViewWidget::Private::projectionSelected(
int projectionIndex )
561 emit q->projectionChanged( (
Projection) projectionIndex );
564 void MapViewWidget::Private::mapThemeSelected(
QModelIndex index )
566 mapThemeSelected( index.
row() );
569 void MapViewWidget::Private::mapThemeSelected(
int index )
571 const QModelIndex columnIndex = m_mapSortProxy.index( index, 0 );
572 const QString currentmaptheme = m_mapSortProxy.
data( columnIndex, Qt::UserRole + 1 ).toString();
574 mDebug() << Q_FUNC_INFO << currentmaptheme;
576 emit q->mapThemeIdChanged( currentmaptheme );
579 QString MapViewWidget::Private::currentThemeName()
const
581 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
587 QString MapViewWidget::Private::currentThemePath()
const
589 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
590 const QModelIndex columnIndex = m_mapSortProxy.index( index.
row(), 0 );
592 return m_mapSortProxy.
data( columnIndex, Qt::UserRole + 1 ).
toString();
595 void MapViewWidget::Private::showContextMenu(
const QPoint& pos )
599 QAction* iconSizeAction = menu.
addAction( tr(
"&Show Large Icons" ), q, SLOT(toggleIconSize()) );
601 iconSizeAction->
setChecked( m_mapViewUi.marbleThemeSelectView->iconSize() ==
QSize( 96, 96 ) );
602 QAction *favAction = menu.
addAction(
QIcon(
":/icons/bookmarks.png" ), tr(
"&Favorite" ), q, SLOT(toggleFavorite()) );
607 menu.
addAction(
QIcon(
":/icons/create-new-map.png" ), tr(
"&Create a New Map..."), q, SIGNAL(showMapWizard()) );
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 ) );
614 void MapViewWidget::Private::deleteMap()
618 tr(
"Are you sure that you want to delete \"%1\"?" ).arg( currentThemeName() ),
619 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes )
622 emit q->mapThemeDeleted();
626 void MapViewWidget::Private::toggleFavorite()
628 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
629 const QModelIndex columnIndex = m_mapSortProxy.index( index.
row(), 0 );
631 if( isCurrentFavorite() ) {
632 m_settings.beginGroup(
"Favorites" );
633 m_settings.remove( m_mapSortProxy.data( columnIndex ).toString() );
636 m_settings.beginGroup(
"Favorites" );
639 m_settings.endGroup();
642 void MapViewWidget::Private::toggleIconSize()
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() );
650 bool MapViewWidget::Private::isCurrentFavorite()
652 const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
653 const QModelIndex nameIndex = m_mapSortProxy.index( index.
row(), 0 );
655 m_settings.beginGroup(
"Favorites" );
656 const bool isFavorite = m_settings.contains( m_mapSortProxy.data( nameIndex ).toString() );
657 m_settings.endGroup();
662 MapViewItemDelegate::MapViewItemDelegate(
QListView *view ) :
663 m_view( view ), m_bookmarkIcon(
":/icons/bookmarks.png" )
671 initStyleOption( &styleOption, index );
673 styleOption.icon =
QIcon();
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 ) {
681 QPalette::ColorRole colorRole = selected ? QPalette::Highlight : QPalette::Midlight;
682 painter->
fillRect( styleOption.rect, styleOption.palette.color( colorGroup, colorRole ) );
685 style->
drawControl( QStyle::CE_ItemViewItem, &styleOption, painter, styleOption.widget );
687 QRect const rect = styleOption.rect;
691 painter->
drawPixmap( iconRect, icon.pixmap( iconSize ) );
693 int const padding = 5;
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 ) );
705 document.
setHtml( text( index ) );
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 ) );
721 if ( index.
column() == 0 ) {
722 QSize const iconSize = option.decorationSize;
737 return QString(
"<p><b>%1</b></p>%2").
arg( title ).
arg( description );
742 #include "MapViewWidget.moc"
QStandardItemModel * mapThemeModel()
Provides a model of the locally existing themes.
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
void fillRect(const QRectF &rectangle, const QBrush &brush)
This file contains the headers for MarbleModel.
void translate(int dx, int dy)
static QString localPath()
QString tr(const char *sourceText, const char *disambiguation, int n)
Flat projection ("plate carree")
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
bool contains(const QString &key) const
static void deleteMapTheme(const QString &mapThemeId)
Deletes the map theme with the specified map theme ID.
QAbstractTextDocumentLayout * documentLayout() const
QRect translated(int dx, int dy) const
void setMargin(int margin)
const QSize iconSize(16, 16)
void setDefaultFont(const QFont &font)
static MarbleGlobal * getInstance()
void setTextWidth(qreal width)
The data model (not based on QAbstractModel) for a MarbleWidget.
QAbstractItemModel * sourceModel() const
QDateTime currentDateTime()
The class that handles map themes that are locally available .
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
char * toString(const T &value)
QVariant data(int role) const
void addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, QFlags< Qt::AlignmentFlag > alignment)
virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const =0
Profiles profiles() const
void translate(const QPointF &offset)
Projection
This enum is used to choose the projection shown in the view.
void setHtml(const QString &html)
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
virtual void draw(QPainter *painter, const PaintContext &context)=0
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QDebug mDebug()
a function to replace qDebug() in Marble library code
QStandardItemModel * celestialBodiesModel()
Provides a model of all installed planets.
virtual QVariant data(const QModelIndex &index, int role) const