Marble

MarbleWidget.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <[email protected]>
4 // SPDX-FileCopyrightText: 2007 Inge Wallin <[email protected]>
5 // SPDX-FileCopyrightText: 2010-2012 Bernhard Beschow <[email protected]>
6 // SPDX-FileCopyrightText: 2012 Mohammed Nafees <[email protected]>
7 //
8 
9 #include "MarbleWidget.h"
10 
11 #include <qmath.h>
12 #include <QHash>
13 #include <QSettings>
14 #include <QElapsedTimer>
15 #include <QPaintEvent>
16 #include <QPaintEngine>
17 #include <QRegion>
18 #include <QNetworkProxy>
19 #include <QMetaMethod>
20 #include "DataMigration.h"
21 #include "FpsLayer.h"
22 #include "FileManager.h"
23 #include "GeoDataLatLonAltBox.h"
24 #include "GeoDataPlacemark.h"
25 #include "GeoDataLookAt.h"
26 #include "GeoPainter.h"
27 #include "MarbleClock.h"
28 #include "MarbleDebug.h"
29 #include "MarbleDirs.h"
30 #include "MarbleLocale.h"
31 #include "MarbleMap.h"
32 #include "MarbleModel.h"
33 #include "MarbleWidgetInputHandler.h"
34 #include "MarbleWidgetPopupMenu.h"
35 #include "Planet.h"
36 #include "PopupLayer.h"
37 #include "RenderState.h"
38 #include "RenderPlugin.h"
39 #include "SunLocator.h"
40 #include "TileCreatorDialog.h"
41 #include "ViewportParams.h"
42 #include "routing/RoutingLayer.h"
43 #include "MarbleAbstractPresenter.h"
44 #include "StyleBuilder.h"
45 
46 namespace Marble
47 {
48 
49 class MarbleWidget::CustomPaintLayer : public LayerInterface
50 {
51  public:
52  explicit CustomPaintLayer( MarbleWidget *widget )
53  : m_widget( widget )
54  {
55  }
56 
57  QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; }
58 
59  bool render( GeoPainter *painter, ViewportParams *viewport,
60  const QString &renderPos, GeoSceneLayer *layer ) override
61  {
62  Q_UNUSED( viewport );
63  Q_UNUSED( renderPos );
64  Q_UNUSED( layer );
65 
66  painter->setPen( Qt::black );
67  m_widget->customPaint( painter );
68 
69  return true;
70  }
71 
72  qreal zValue() const override { return 1.0e7; }
73 
74  RenderState renderState() const override { return RenderState(QStringLiteral("Custom Widget Paint")); }
75 
76  QString runtimeTrace() const override { return QStringLiteral("MarbleWidget::CustomPaintLayer"); }
77 
78  private:
79  MarbleWidget *const m_widget;
80 };
81 
82 
83 class MarbleWidgetPrivate
84 {
85  public:
86  explicit MarbleWidgetPrivate( MarbleWidget *parent ) :
87  m_widget( parent ),
88  m_model(),
89  m_map( &m_model ),
90  m_presenter( &m_map ),
91  m_inputhandler( nullptr ),
92  m_routingLayer( nullptr ),
93  m_mapInfoDialog( nullptr ),
94  m_customPaintLayer( parent ),
95  m_popupmenu( nullptr ),
96  m_showFrameRate( false )
97  {
98  }
99 
100  ~MarbleWidgetPrivate()
101  {
102  m_map.removeLayer( &m_customPaintLayer );
103  m_map.removeLayer( m_mapInfoDialog );
104  delete m_mapInfoDialog;
105  delete m_popupmenu;
106  }
107 
108  void construct();
109 
110  void updateMapTheme();
111 
112  void setInputHandler();
113  void setInputHandler( MarbleWidgetInputHandler *handler );
114 
115  /**
116  * @brief Update widget flags and cause a full repaint
117  *
118  * The background of the widget only needs to be redrawn in certain cases. This
119  * method sets the widget flags accordingly and triggers a repaint.
120  */
121  void updateSystemBackgroundAttribute();
122 
123  MarbleWidget *const m_widget;
124 
125  MarbleModel m_model;
126  MarbleMap m_map;
127 
128  MarbleAbstractPresenter m_presenter;
129 
130  MarbleWidgetInputHandler *m_inputhandler;
131 
132  RoutingLayer *m_routingLayer;
133  PopupLayer *m_mapInfoDialog;
134  MarbleWidget::CustomPaintLayer m_customPaintLayer;
135 
136  MarbleWidgetPopupMenu *m_popupmenu;
137 
138  bool m_showFrameRate;
139 };
140 
141 
142 
144  : QWidget( parent ),
145  d( new MarbleWidgetPrivate( this ) )
146 {
147 // setAttribute( Qt::WA_PaintOnScreen, true );
148  d->construct();
149 }
150 
151 MarbleWidget::~MarbleWidget()
152 {
153  // Remove and delete an existing InputHandler
154  // initialized in d->construct()
155  setInputHandler( nullptr );
156 
157  delete d;
158 }
159 
160 void MarbleWidgetPrivate::construct()
161 {
162  QPointer<DataMigration> dataMigration = new DataMigration( m_widget );
163  dataMigration->exec();
164  delete dataMigration;
165 
166  // Widget settings
167  m_widget->setMinimumSize( 200, 300 );
168  m_widget->setFocusPolicy( Qt::WheelFocus );
169  m_widget->setFocus( Qt::OtherFocusReason );
170 
171  // Set background: black.
172  m_widget->setPalette( QPalette ( Qt::black ) );
173 
174  // Set whether the black space gets displayed or the earth gets simply
175  // displayed on the widget background.
176  m_widget->setAutoFillBackground( true );
177 
178  // Initialize the map and forward some signals.
179  m_map.setSize( m_widget->width(), m_widget->height() );
180  m_map.setShowFrameRate( false ); // never let the map draw the frame rate,
181  // we do this differently here in the widget
182 
183  m_widget->connect( &m_presenter, SIGNAL(regionSelected(GeoDataLatLonBox)), m_widget, SIGNAL(regionSelected(GeoDataLatLonBox)) );
184 
185  m_widget->connect( &m_presenter, SIGNAL(zoomChanged(int)), m_widget, SIGNAL(zoomChanged(int)) );
186  m_widget->connect( &m_presenter, SIGNAL(distanceChanged(QString)), m_widget, SIGNAL(distanceChanged(QString)) );
187 
188  // forward some signals of m_map
189  m_widget->connect( &m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
190  m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)) );
191  m_widget->connect( &m_map, SIGNAL(projectionChanged(Projection)),
192  m_widget, SIGNAL(projectionChanged(Projection)) );
193  m_widget->connect( &m_map, SIGNAL(tileLevelChanged(int)),
194  m_widget, SIGNAL(tileLevelChanged(int)) );
195  m_widget->connect( &m_map, SIGNAL(framesPerSecond(qreal)),
196  m_widget, SIGNAL(framesPerSecond(qreal)) );
197  m_widget->connect( &m_map, SIGNAL(viewContextChanged(ViewContext)),
198  m_widget, SLOT(setViewContext(ViewContext)) );
199 
200  m_widget->connect( &m_map, SIGNAL(pluginSettingsChanged()),
201  m_widget, SIGNAL(pluginSettingsChanged()) );
202  m_widget->connect( &m_map, SIGNAL(renderPluginInitialized(RenderPlugin*)),
203  m_widget, SIGNAL(renderPluginInitialized(RenderPlugin*)) );
204 
205  // react to some signals of m_map
206  m_widget->connect( &m_map, SIGNAL(themeChanged(QString)),
207  m_widget, SLOT(updateMapTheme()) );
208  m_widget->connect( &m_map, SIGNAL(viewContextChanged(ViewContext)),
209  m_widget, SIGNAL(viewContextChanged(ViewContext)) );
210  m_widget->connect( &m_map, SIGNAL(repaintNeeded(QRegion)),
211  m_widget, SLOT(update()) );
212  m_widget->connect( &m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
213  m_widget, SLOT(updateSystemBackgroundAttribute()) );
214  m_widget->connect( &m_map, SIGNAL(renderStatusChanged(RenderStatus)),
215  m_widget, SIGNAL(renderStatusChanged(RenderStatus)) );
216  m_widget->connect( &m_map, SIGNAL(renderStateChanged(RenderState)),
217  m_widget, SIGNAL(renderStateChanged(RenderState)) );
218 
219  m_widget->connect( m_model.fileManager(), SIGNAL(centeredDocument(GeoDataLatLonBox)),
220  m_widget, SLOT(centerOn(GeoDataLatLonBox)) );
221 
222 
223  // Show a progress dialog when the model calculates new map tiles.
224  m_widget->connect( &m_model, SIGNAL( creatingTilesStart( TileCreator*, const QString&,
225  const QString& ) ),
226  m_widget, SLOT( creatingTilesStart( TileCreator*, const QString&,
227  const QString& ) ) );
228 
229  m_popupmenu = new MarbleWidgetPopupMenu( m_widget, &m_model );
230 
231  m_routingLayer = new RoutingLayer( m_widget, m_widget );
232  m_routingLayer->setPlacemarkModel( nullptr );
233  QObject::connect( m_routingLayer, SIGNAL(repaintNeeded(QRect)),
234  m_widget, SLOT(update()) );
235 
236  m_mapInfoDialog = new PopupLayer( m_widget, m_widget );
237  m_mapInfoDialog->setVisible( false );
238  m_widget->connect( m_mapInfoDialog, SIGNAL(repaintNeeded()), m_widget, SLOT(update()) );
239  m_map.addLayer( m_mapInfoDialog );
240 
241  setInputHandler();
242  m_widget->setMouseTracking( true );
243 
244  m_map.addLayer( &m_customPaintLayer );
245 
246  m_widget->connect( m_inputhandler, SIGNAL(mouseClickGeoPosition(qreal,qreal,GeoDataCoordinates::Unit)),
247  m_widget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
248  m_widget->setHighlightEnabled( true );
249 
250 }
251 
252 void MarbleWidgetPrivate::setInputHandler()
253 {
254  setInputHandler( new MarbleWidgetInputHandler( &m_presenter, m_widget ) );
255 }
256 
257 void MarbleWidgetPrivate::setInputHandler( MarbleWidgetInputHandler *handler )
258 {
259  delete m_inputhandler;
260  m_inputhandler = handler;
261 
262  if ( m_inputhandler )
263  {
264  m_widget->installEventFilter( m_inputhandler );
265 
266  QObject::connect( m_inputhandler, SIGNAL(mouseClickScreenPosition(int,int)),
267  m_widget, SLOT(notifyMouseClick(int,int)) );
268 
269  QObject::connect( m_inputhandler, SIGNAL(mouseMoveGeoPosition(QString)),
270  m_widget, SIGNAL(mouseMoveGeoPosition(QString)) );
271  }
272 }
273 
274 void MarbleWidgetPrivate::updateSystemBackgroundAttribute()
275 {
276  // We only have to repaint the background every time if the earth
277  // doesn't cover the whole image.
278  const bool isOn = m_map.viewport()->mapCoversViewport() && !m_model.mapThemeId().isEmpty();
279  m_widget->setAttribute( Qt::WA_NoSystemBackground, isOn );
280 }
281 
282 // ----------------------------------------------------------------
283 
284 
286 {
287  return &d->m_model;
288 }
289 
290 const MarbleModel *MarbleWidget::model() const
291 {
292  return &d->m_model;
293 }
294 
295 ViewportParams* MarbleWidget::viewport()
296 {
297  return d->m_map.viewport();
298 }
299 
300 const ViewportParams* MarbleWidget::viewport() const
301 {
302  return d->m_map.viewport();
303 }
304 
305 MarbleWidgetPopupMenu *MarbleWidget::popupMenu()
306 {
307  return d->m_popupmenu;
308 }
309 
310 
311 void MarbleWidget::setInputHandler( MarbleWidgetInputHandler *handler )
312 {
313  d->setInputHandler(handler);
314 }
315 
316 MarbleWidgetInputHandler *MarbleWidget::inputHandler() const
317 {
318  return d->m_inputhandler;
319 }
320 
322 {
323  return d->m_map.radius();
324 }
325 
326 void MarbleWidget::setRadius( int radius )
327 {
328  d->m_map.setRadius( radius );
329 }
330 
332 {
333  return d->m_presenter.moveStep();
334 }
335 
336 int MarbleWidget::zoom() const
337 {
338  return d->m_presenter.logzoom();
339 }
340 
341 int MarbleWidget::tileZoomLevel() const
342 {
343  return d->m_map.tileZoomLevel();
344 }
345 
347 {
348  return d->m_map.minimumZoom();
349 }
350 
352 {
353  return d->m_map.maximumZoom();
354 }
355 
356 QVector<const GeoDataFeature*> MarbleWidget::whichFeatureAt( const QPoint &curpos ) const
357 {
358  return d->m_map.whichFeatureAt( curpos );
359 }
360 
362 {
363  return d->m_map.whichItemAt( curpos );
364 }
365 
366 void MarbleWidget::addLayer( LayerInterface *layer )
367 {
368  d->m_map.addLayer( layer );
369 }
370 
371 void MarbleWidget::removeLayer( LayerInterface *layer )
372 {
373  d->m_map.removeLayer( layer );
374 }
375 
376 Marble::TextureLayer* MarbleWidget::textureLayer() const
377 {
378  return d->m_map.textureLayer();
379 }
380 
381 VectorTileLayer *MarbleWidget::vectorTileLayer() const
382 {
383  return d->m_map.vectorTileLayer();
384 }
385 
387 {
388  return grab();
389 }
390 
391 RenderStatus MarbleWidget::renderStatus() const
392 {
393  return d->m_map.renderStatus();
394 }
395 
396 RenderState MarbleWidget::renderState() const
397 {
398  return d->m_map.renderState();
399 }
400 
402 {
403  if ( enabled ) {
404  connect( this, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
405  &d->m_map, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
407  }
408  else {
409  disconnect( this, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
410  &d->m_map, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
411  }
412 }
413 
414 bool MarbleWidget::showOverviewMap() const
415 {
416  return d->m_map.showOverviewMap();
417 }
418 
419 bool MarbleWidget::showScaleBar() const
420 {
421  return d->m_map.showScaleBar();
422 }
423 
424 bool MarbleWidget::showCompass() const
425 {
426  return d->m_map.showCompass();
427 }
428 
429 bool MarbleWidget::showClouds() const
430 {
431  return d->m_map.showClouds();
432 }
433 
434 bool MarbleWidget::showSunShading() const
435 {
436  return d->m_map.showSunShading();
437 }
438 
439 bool MarbleWidget::showCityLights() const
440 {
441  return d->m_map.showCityLights();
442 }
443 
444 bool MarbleWidget::isLockedToSubSolarPoint() const
445 {
446  return d->m_map.isLockedToSubSolarPoint();
447 }
448 
449 bool MarbleWidget::isSubSolarPointIconVisible() const
450 {
451  return d->m_map.isSubSolarPointIconVisible();
452 }
453 
454 bool MarbleWidget::showAtmosphere() const
455 {
456  return d->m_map.showAtmosphere();
457 }
458 
459 bool MarbleWidget::showCrosshairs() const
460 {
461  return d->m_map.showCrosshairs();
462 }
463 
464 bool MarbleWidget::showGrid() const
465 {
466  return d->m_map.showGrid();
467 }
468 
469 bool MarbleWidget::showPlaces() const
470 {
471  return d->m_map.showPlaces();
472 }
473 
474 bool MarbleWidget::showCities() const
475 {
476  return d->m_map.showCities();
477 }
478 
479 bool MarbleWidget::showTerrain() const
480 {
481  return d->m_map.showTerrain();
482 }
483 
484 bool MarbleWidget::showOtherPlaces() const
485 {
486  return d->m_map.showOtherPlaces();
487 }
488 
489 bool MarbleWidget::showRelief() const
490 {
491  return d->m_map.showRelief();
492 }
493 
494 bool MarbleWidget::showIceLayer() const
495 {
496  return d->m_map.showIceLayer();
497 }
498 
499 bool MarbleWidget::showBorders() const
500 {
501  return d->m_map.showBorders();
502 }
503 
504 bool MarbleWidget::showRivers() const
505 {
506  return d->m_map.showRivers();
507 }
508 
509 bool MarbleWidget::showLakes() const
510 {
511  return d->m_map.showLakes();
512 }
513 
515 {
516  return d->m_showFrameRate;
517 }
518 
519 bool MarbleWidget::showBackground() const
520 {
521  return d->m_map.showBackground();
522 }
523 
524 quint64 MarbleWidget::volatileTileCacheLimit() const
525 {
526  return d->m_map.volatileTileCacheLimit();
527 }
528 
529 
530 void MarbleWidget::setZoom( int newZoom, FlyToMode mode )
531 {
532  d->m_inputhandler->stopInertialEarthRotation();
533  d->m_presenter.setZoom( newZoom, mode );
534 }
535 
536 void MarbleWidget::zoomView( int zoom, FlyToMode mode )
537 {
538  d->m_inputhandler->stopInertialEarthRotation();
539  d->m_presenter.zoomView( zoom, mode );
540 }
541 
542 
543 void MarbleWidget::zoomViewBy( int zoomStep, FlyToMode mode )
544 {
545  d->m_inputhandler->stopInertialEarthRotation();
546  d->m_presenter.zoomViewBy( zoomStep, mode );
547 }
548 
549 
551 {
552  d->m_inputhandler->stopInertialEarthRotation();
553  d->m_presenter.zoomIn( mode );
554 }
555 
557 {
558  d->m_inputhandler->stopInertialEarthRotation();
559  d->m_presenter.zoomOut( mode );
560 }
561 
562 void MarbleWidget::rotateBy( const qreal deltaLon, const qreal deltaLat, FlyToMode mode )
563 {
564  d->m_inputhandler->stopInertialEarthRotation();
565  d->m_presenter.rotateBy( deltaLon, deltaLat, mode );
566 }
567 
568 
569 void MarbleWidget::centerOn( const qreal lon, const qreal lat, bool animated )
570 {
571  d->m_inputhandler->stopInertialEarthRotation();
572  d->m_presenter.centerOn( lon, lat, animated );
573 }
574 
575 void MarbleWidget::centerOn( const GeoDataCoordinates &position, bool animated )
576 {
577  d->m_inputhandler->stopInertialEarthRotation();
578  d->m_presenter.centerOn( position, animated );
579 }
580 
581 void MarbleWidget::centerOn( const GeoDataLatLonBox &box, bool animated )
582 {
583  d->m_inputhandler->stopInertialEarthRotation();
584  d->m_presenter.centerOn( box, animated );
585 }
586 
587 void MarbleWidget::centerOn( const GeoDataPlacemark& placemark, bool animated )
588 {
589  d->m_inputhandler->stopInertialEarthRotation();
590  d->m_presenter.centerOn( placemark, animated );
591 }
592 
594 {
595  d->m_inputhandler->stopInertialEarthRotation();
596  d->m_presenter.setCenterLatitude( lat, mode );
597 }
598 
600 {
601  d->m_inputhandler->stopInertialEarthRotation();
602  d->m_presenter.setCenterLongitude( lon, mode );
603 }
604 
605 Projection MarbleWidget::projection() const
606 {
607  return d->m_map.projection();
608 }
609 
610 void MarbleWidget::setProjection( Projection projection )
611 {
612  d->m_map.setProjection( projection );
613 }
614 
615 void MarbleWidget::setProjection( int projection )
616 {
617  setProjection( Projection( qAbs( projection ) % (Mercator+1) ) );
618 }
619 
621 {
622  d->m_inputhandler->stopInertialEarthRotation();
623  d->m_presenter.moveByStep( -1, 0, mode );
624 }
625 
627 {
628  d->m_inputhandler->stopInertialEarthRotation();
629  d->m_presenter.moveByStep( 1, 0, mode );
630 }
631 
633 {
634  d->m_inputhandler->stopInertialEarthRotation();
635  d->m_presenter.moveByStep( 0, -1, mode );
636 }
637 
639 {
640  d->m_inputhandler->stopInertialEarthRotation();
641  d->m_presenter.moveByStep( 0, 1, mode );
642 }
643 
645 {
646  emit mouseMoveGeoPosition( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) );
647 }
648 
650 {
651  setUpdatesEnabled( false );
652  d->m_map.setSize( event->size() );
653  setUpdatesEnabled( true );
654 
656 }
657 
658 void MarbleWidget::connectNotify( const QMetaMethod &signal )
659 {
660  if ( d->m_inputhandler && signal == QMetaMethod::fromSignal( &MarbleWidget::mouseMoveGeoPosition ) ) {
661  d->m_inputhandler->setPositionSignalConnected( true );
662  }
663 }
664 
665 void MarbleWidget::disconnectNotify( const QMetaMethod &signal )
666 {
667  if ( d->m_inputhandler && signal == QMetaMethod::fromSignal( &MarbleWidget::mouseMoveGeoPosition ) ) {
668  d->m_inputhandler->setPositionSignalConnected( false );
669  }
670 }
671 
672 bool MarbleWidget::screenCoordinates( qreal lon, qreal lat,
673  qreal& x, qreal& y ) const
674 {
675  return d->m_map.screenCoordinates( lon, lat, x, y );
676 }
677 
678 bool MarbleWidget::geoCoordinates( int x, int y,
679  qreal& lon, qreal& lat,
680  GeoDataCoordinates::Unit unit ) const
681 {
682  return d->m_map.geoCoordinates( x, y, lon, lat, unit );
683 }
684 
686 {
687  return d->m_map.centerLatitude();
688 }
689 
691 {
692  return d->m_map.centerLongitude();
693 }
694 
696 {
697  return viewport()->mapRegion();
698 }
699 
701 {
702  QElapsedTimer t;
703  t.start();
704 
705  QPaintDevice *paintDevice = this;
706  QImage image;
707  if (!isEnabled())
708  {
709  // If the globe covers fully the screen then we can use the faster
710  // RGB32 as there are no translucent areas involved.
711  QImage::Format imageFormat = ( d->m_map.viewport()->mapCoversViewport() )
714  // Paint to an intermediate image
715  image = QImage( rect().size(), imageFormat );
716  image.fill( Qt::transparent );
717  paintDevice = &image;
718  }
719 
720  {
721  // FIXME: Better way to get the GeoPainter
722  // Create a painter that will do the painting.
723  GeoPainter geoPainter( paintDevice, d->m_map.viewport(), d->m_map.mapQuality() );
724 
725  d->m_map.paint( geoPainter, evt->rect() );
726  }
727 
728  if ( !isEnabled() )
729  {
730  // Draw a grayscale version of the intermediate image
731  QRgb* pixel = reinterpret_cast<QRgb*>( image.scanLine( 0 ));
732  for (int i=0; i<image.width()*image.height(); ++i, ++pixel) {
733  int gray = qGray( *pixel );
734  *pixel = qRgb( gray, gray, gray );
735  }
736 
737  QPainter widgetPainter( this );
738  widgetPainter.drawImage( rect(), image );
739  }
740 
741  if ( d->m_showFrameRate )
742  {
743  QPainter painter( this );
744  FpsLayer fpsPainter( &t );
745  fpsPainter.paint( &painter );
746 
747  const qreal fps = 1000.0 / (qreal)( t.elapsed() + 1 );
748  emit framesPerSecond( fps );
749  }
750 }
751 
753 {
754  Q_UNUSED( painter );
755  /* This is a NOOP in the base class*/
756 }
757 
758 
760 {
761  d->m_inputhandler->stopInertialEarthRotation();
762  d->m_presenter.goHome( mode );
763 }
764 
765 QString MarbleWidget::mapThemeId() const
766 {
767  return d->m_model.mapThemeId();
768 }
769 
770 void MarbleWidget::setMapThemeId( const QString& mapThemeId )
771 {
772  d->m_map.setMapThemeId( mapThemeId );
773 }
774 
775 void MarbleWidgetPrivate::updateMapTheme()
776 {
777  m_map.removeLayer( m_routingLayer );
778 
779  m_widget->setRadius( m_widget->radius() ); // Corrects zoom range, if needed
780 
781  if (m_model.planetId() == QLatin1String("earth")) {
782  m_map.addLayer( m_routingLayer );
783  }
784 
785  emit m_widget->themeChanged( m_map.mapThemeId() );
786 
787  // Now we want a full repaint as the atmosphere might differ
788  m_widget->setAttribute( Qt::WA_NoSystemBackground, false );
789 
790  m_widget->update();
791 }
792 
794 {
795  return d->m_model.mapTheme();
796 }
797 
798 void MarbleWidget::setPropertyValue( const QString& name, bool value )
799 {
800  mDebug() << "In MarbleWidget the property " << name << "was set to " << value;
801  d->m_map.setPropertyValue( name, value );
802 }
803 
805 {
806  d->m_map.setShowOverviewMap( visible );
807 }
808 
809 void MarbleWidget::setShowScaleBar( bool visible )
810 {
811  d->m_map.setShowScaleBar( visible );
812 }
813 
814 void MarbleWidget::setShowCompass( bool visible )
815 {
816  d->m_map.setShowCompass( visible );
817 }
818 
819 void MarbleWidget::setShowClouds( bool visible )
820 {
821  d->m_map.setShowClouds( visible );
822 }
823 
825 {
826  d->m_map.setShowSunShading( visible );
827 }
828 
830 {
831  d->m_map.setShowCityLights( visible );
832 }
833 
835 {
836  if ( d->m_map.isLockedToSubSolarPoint() != visible ) { // Toggling input modifies event filters, so avoid that if not needed
837  d->m_map.setLockToSubSolarPoint( visible );
838  setInputEnabled( !d->m_map.isLockedToSubSolarPoint() );
839  }
840 }
841 
843 {
844  if ( d->m_map.isSubSolarPointIconVisible() != visible ) {
845  d->m_map.setSubSolarPointIconVisible( visible );
846  }
847 
848  QList<RenderPlugin *> pluginList = renderPlugins();
850  QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
851  for (; i != end; ++i ) {
852  if ((*i)->nameId() == QLatin1String("sun")) {
853  (*i)->setVisible( visible );
854  }
855  }
856 }
857 
859 {
860  d->m_map.setShowAtmosphere( visible );
861 }
862 
864 {
865  d->m_map.setShowCrosshairs( visible );
866 }
867 
868 void MarbleWidget::setShowGrid( bool visible )
869 {
870  d->m_map.setShowGrid( visible );
871 }
872 
873 void MarbleWidget::setShowPlaces( bool visible )
874 {
875  d->m_map.setShowPlaces( visible );
876 }
877 
878 void MarbleWidget::setShowCities( bool visible )
879 {
880  d->m_map.setShowCities( visible );
881 }
882 
883 void MarbleWidget::setShowTerrain( bool visible )
884 {
885  d->m_map.setShowTerrain( visible );
886 }
887 
889 {
890  d->m_map.setShowOtherPlaces( visible );
891 }
892 
893 void MarbleWidget::setShowRelief( bool visible )
894 {
895  d->m_map.setShowRelief( visible );
896 }
897 
898 void MarbleWidget::setShowIceLayer( bool visible )
899 {
900  d->m_map.setShowIceLayer( visible );
901 }
902 
903 void MarbleWidget::setShowBorders( bool visible )
904 {
905  d->m_map.setShowBorders( visible );
906 }
907 
908 void MarbleWidget::setShowRivers( bool visible )
909 {
910  d->m_map.setShowRivers( visible );
911 }
912 
913 void MarbleWidget::setShowLakes( bool visible )
914 {
915  d->m_map.setShowLakes( visible );
916 }
917 
918 void MarbleWidget::setShowFrameRate( bool visible )
919 {
920  d->m_showFrameRate = visible;
921 
922  update();
923 }
924 
925 void MarbleWidget::setShowBackground( bool visible )
926 {
927  d->m_map.setShowBackground( visible );
928 }
929 
931 {
932  d->m_map.setShowRuntimeTrace( visible );
933 }
934 
935 bool MarbleWidget::showRuntimeTrace() const
936 {
937  return d->m_map.showRuntimeTrace();
938 }
939 
941 {
942  d->m_map.setShowDebugPolygons( visible );
943 }
944 
945 bool MarbleWidget::showDebugPolygons() const
946 {
947  return d->m_map.showDebugPolygons();
948 }
949 
951 {
952  d->m_map.setShowDebugBatchRender( visible );
953 }
954 
955 bool MarbleWidget::showDebugBatchRender() const
956 {
957  return d->m_map.showDebugBatchRender();
958 }
959 
961 {
962  d->m_map.setShowDebugPlacemarks( visible );
963 }
964 
965 bool MarbleWidget::showDebugPlacemarks() const
966 {
967  return d->m_map.showDebugPlacemarks();
968 }
969 
971 {
972  d->m_map.setLevelTagDebugModeEnabled(visible);
973 }
974 
975 bool MarbleWidget::debugLevelTags() const
976 {
977  return d->m_map.levelTagDebugModeEnabled();
978 }
979 
980 void MarbleWidget::setShowTileId( bool visible )
981 {
982  d->m_map.setShowTileId( visible );
983 }
984 
986 {
987  qreal lon = 0;
988  qreal lat = 0;
989 
990  bool const valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian );
991 
992  if ( valid ) {
993  emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian );
994  }
995 }
996 
997 void MarbleWidget::clearVolatileTileCache()
998 {
999  mDebug() << "About to clear VolatileTileCache";
1000  d->m_map.clearVolatileTileCache();
1001 }
1002 
1004 {
1005  d->m_map.setVolatileTileCacheLimit( kiloBytes );
1006 }
1007 
1008 // This slot will called when the Globe starts to create the tiles.
1009 
1010 void MarbleWidget::creatingTilesStart( TileCreator *creator,
1011  const QString &name,
1012  const QString &description )
1013 {
1014  QPointer<TileCreatorDialog> dialog = new TileCreatorDialog( creator, this );
1015  dialog->setSummary( name, description );
1016  dialog->exec();
1017  delete dialog;
1018 }
1019 
1021 {
1022  return d->m_map.mapQuality( viewContext );
1023 }
1024 
1026 {
1027  d->m_map.setMapQualityForViewContext( quality, viewContext );
1028 }
1029 
1030 ViewContext MarbleWidget::viewContext() const
1031 {
1032  return d->m_map.viewContext();
1033 }
1034 
1036 {
1037  // Inform routing layer about view context change. If not done,
1038  // the routing layer causes severe performance problems when dragging the
1039  // map. So either do not remove this line, or keep a similar call in place
1040  // when you refactor it and test your changes wrt drag performance at
1041  // high zoom level with long routes!
1042  d->m_routingLayer->setViewContext( viewContext );
1043 
1044  d->m_map.setViewContext( viewContext );
1045 }
1046 
1048 {
1049  return d->m_presenter.animationsEnabled();
1050 }
1051 
1053 {
1054  d->m_presenter.setAnimationsEnabled( enabled );
1055 }
1056 
1057 AngleUnit MarbleWidget::defaultAngleUnit() const
1058 {
1059  return d->m_map.defaultAngleUnit();
1060 }
1061 
1062 void MarbleWidget::setDefaultAngleUnit( AngleUnit angleUnit )
1063 {
1064  d->m_map.setDefaultAngleUnit( angleUnit );
1065 }
1066 
1067 QFont MarbleWidget::defaultFont() const
1068 {
1069  return d->m_map.defaultFont();
1070 }
1071 
1072 void MarbleWidget::setDefaultFont( const QFont& font )
1073 {
1074  d->m_map.setDefaultFont( font );
1075 }
1076 
1077 void MarbleWidget::setSelection( const QRect& region )
1078 {
1079  d->m_presenter.setSelection( region );
1080 }
1081 
1083 {
1084  return d->m_presenter.distance();
1085 }
1086 
1087 void MarbleWidget::setDistance( qreal newDistance )
1088 {
1089  d->m_presenter.setDistance( newDistance );
1090 }
1091 
1093 {
1094  return d->m_presenter.distanceString();
1095 }
1096 
1097 void MarbleWidget::setInputEnabled( bool enabled )
1098 {
1099  //if input is set as enabled
1100  if ( enabled )
1101  {
1102  if ( !d->m_inputhandler ) {
1103  d->setInputHandler();
1104  }
1105  else {
1106  installEventFilter( d->m_inputhandler );
1107  }
1108  }
1109 
1110  else // input is disabled
1111  {
1112  mDebug() << "MarbleWidget::disableInput";
1113  removeEventFilter( d->m_inputhandler );
1115  }
1116 }
1117 
1119 {
1120  return d->m_map.renderPlugins();
1121 }
1122 
1124 {
1125  for( RenderPlugin *plugin: renderPlugins() ) {
1126  settings.beginGroup(QLatin1String("plugin_") + plugin->nameId());
1127 
1129 
1130  for ( const QString& key: settings.childKeys() ) {
1131  hash.insert( key, settings.value( key ) );
1132  }
1133 
1134  plugin->setSettings( hash );
1135 
1136  settings.endGroup();
1137  }
1138 }
1139 
1141 {
1142  for( RenderPlugin *plugin: renderPlugins() ) {
1143  settings.beginGroup(QLatin1String("plugin_") + plugin->nameId());
1144 
1145  QHash<QString,QVariant> hash = plugin->settings();
1146 
1148  while( it != hash.end() ) {
1149  settings.setValue( it.key(), it.value() );
1150  ++it;
1151  }
1152 
1153  settings.endGroup();
1154  }
1155 }
1156 
1158 {
1159  return d->m_map.floatItems();
1160 }
1161 
1163 {
1164  return d->m_map.floatItem( nameId );
1165 }
1166 
1168 {
1169  if ( event->type() == QEvent::EnabledChange )
1170  {
1171  setInputEnabled(isEnabled());
1172  }
1173 
1175 }
1176 
1177 void MarbleWidget::flyTo( const GeoDataLookAt &newLookAt, FlyToMode mode )
1178 {
1179  d->m_inputhandler->stopInertialEarthRotation();
1180  d->m_presenter.flyTo( newLookAt, mode );
1181 }
1182 
1184 {
1185  d->m_map.reload();
1186 }
1187 
1188 void MarbleWidget::downloadRegion( QVector<TileCoordsPyramid> const & pyramid )
1189 {
1190  d->m_map.downloadRegion( pyramid );
1191 }
1192 
1193 GeoDataLookAt MarbleWidget::lookAt() const
1194 {
1195  return d->m_presenter.lookAt();
1196 }
1197 
1199 {
1200  return d->m_map.viewport()->focusPoint();
1201 }
1202 
1204 {
1205  d->m_map.viewport()->setFocusPoint( focusPoint );
1206 }
1207 
1209 {
1210  d->m_map.viewport()->resetFocusPoint();
1211 }
1212 
1213 qreal MarbleWidget::radiusFromDistance( qreal distance ) const
1214 {
1215  return d->m_presenter.radiusFromDistance( distance );
1216 }
1217 
1218 qreal MarbleWidget::distanceFromRadius( qreal radius ) const
1219 {
1220  return d->m_presenter.distanceFromRadius( radius );
1221 }
1222 
1223 qreal MarbleWidget::zoomFromDistance( qreal distance ) const
1224 {
1225  return d->m_presenter.zoomFromDistance( distance );
1226 }
1227 
1228 qreal MarbleWidget::distanceFromZoom( qreal zoom ) const
1229 {
1230  return d->m_presenter.distanceFromZoom( zoom );
1231 }
1232 
1233 RoutingLayer* MarbleWidget::routingLayer()
1234 {
1235  return d->m_routingLayer;
1236 }
1237 
1238 PopupLayer *MarbleWidget::popupLayer()
1239 {
1240  return d->m_mapInfoDialog;
1241 }
1242 
1243 const StyleBuilder* MarbleWidget::styleBuilder() const
1244 {
1245  return d->m_map.styleBuilder();
1246 }
1247 
1248 void MarbleWidget::setHeading( qreal heading )
1249 {
1250  d->m_map.setHeading( heading );
1251 }
1252 
1253 qreal MarbleWidget::heading() const
1254 {
1255  return d->m_map.heading();
1256 }
1257 
1259 {
1260  d->m_map.setDebugLevelTag(level);
1261 }
1262 
1263 int MarbleWidget::levelToDebug() const
1264 {
1265  return d->m_map.debugLevelTag();
1266 }
1267 
1268 }
1269 
1270 #include "moc_MarbleWidget.cpp"
void addLayer(LayerInterface *layer)
Add a layer to be included in rendering.
GeoDataLookAt lookAt() const
Return the lookAt.
ViewContext
This enum is used to choose context in which map quality gets used.
Definition: MarbleGlobal.h:66
void removeEventFilter(QObject *obj)
void zoomOut(FlyToMode mode=Automatic)
Zoom out by the amount zoomStep.
qreal radiusFromDistance(qreal distance) const
Return the globe radius (pixel) for the given distance (km)
A 3d point representation.
void setShowCityLights(bool visible)
Set whether city lights instead of night shadow are visible.
void resizeEvent(QResizeEvent *event) override
Reimplementation of the resizeEvent() function in QWidget.
const T value(const Key &key) const const
The abstract class that creates a renderable item.
Definition: RenderPlugin.h:38
void setVolatileTileCacheLimit(quint64 kiloBytes)
Set the limit of the volatile (in RAM) tile cache.
void moveDown(FlyToMode mode=Automatic)
Move down by the moveStep.
void setRadius(int radius)
Set the radius of the globe in pixels.
void setShowIceLayer(bool visible)
Set whether the ice layer is visible.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
int height() const const
int radius() const
Return the radius of the globe in pixels.
void setShowRivers(bool visible)
Set whether the rivers are visible.
void fill(uint pixelValue)
void beginGroup(const QString &prefix)
int minimumZoom() const
Return the minimum zoom value for the current map theme.
QRegion mapRegion() const
Return the projected region which describes the (shape of the) projected surface.
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
void setShowCities(bool visible)
Set whether the city place mark overlay is visible.
MapQuality mapQuality(ViewContext=Still) const
Retrieve the map quality depending on the view context.
QPixmap grab(const QRect &rectangle)
void paintEvent(QPaintEvent *event) override
Reimplementation of the paintEvent() function in QWidget.
void zoomViewBy(int zoomStep, FlyToMode mode=Instant)
Zoom the view by a certain step.
void update()
MarbleModel * model()
Return the model that this view shows.
virtual void resizeEvent(QResizeEvent *event)
QHash::iterator begin()
QList< RenderPlugin * > renderPlugins() const
Returns a list of all RenderPlugins on the widget, this includes float items.
virtual bool event(QEvent *event) override
void setShowClouds(bool visible)
Set whether the cloud cover is visible.
GeoDataCoordinates focusPoint() const
void moveUp(FlyToMode mode=Automatic)
Move up by the moveStep.
QList::const_iterator constBegin() const const
void centerOn(const qreal lon, const qreal lat, bool animated=false)
Center the view on a geographical point.
void creatingTilesStart(TileCreator *creator, const QString &name, const QString &description)
A slot that is called when the model starts to create new tiles.
void setUpdatesEnabled(bool enable)
void zoomIn(FlyToMode mode=Automatic)
Zoom in by the amount zoomStep.
qreal distance() const
Return the current distance.
void setPropertyValue(const QString &name, bool value)
Sets the value of a map theme property.
The abstract class for float item plugins.
void resetFocusPoint()
Invalidate any focus point set with setFocusPoint.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void changeEvent(QEvent *event)
void writePluginSettings(QSettings &settings) const
Writes the plugin settings in the passed QSettings.
void setShowDebugPlacemarks(bool visible)
Set whether to enter the debug mode for placemark drawing.
qreal zoomFromDistance(qreal distance) const
Returns the zoom value (no unit) corresponding to the given camera distance (km)
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
void setLevelToDebug(int level)
Set the level to debug.
void setInputHandler(MarbleWidgetInputHandler *handler)
Set the input handler.
QHash::iterator insert(const Key &key, const T &value)
MarbleWidgetInputHandler * inputHandler() const
Returns the current input handler.
void setMapThemeId(const QString &maptheme)
Set a new map theme.
void changeEvent(QEvent *event) override
Reimplementation of the changeEvent() function in QWidget to react to changes of the enabled state.
void setShowOverviewMap(bool visible)
Set whether the overview map overlay is visible.
void setShowRelief(bool visible)
Set whether the relief is visible.
void readPluginSettings(QSettings &settings)
Reads the plugin settings from the passed QSettings.
OtherFocusReason
QPixmap mapScreenShot()
Return a QPixmap with the current contents of the widget.
void setValue(const QString &key, const QVariant &value)
void setShowTerrain(bool visible)
Set whether the terrain place mark overlay is visible.
void setFocusPoint(const GeoDataCoordinates &focusPoint)
Change the point of focus, overridding any previously set focus point.
qreal centerLongitude() const
Return the longitude of the center point.
void setShowBorders(bool visible)
Set whether the borders visible.
void installEventFilter(QObject *filterObj)
void flyTo(const GeoDataLookAt &lookAt, FlyToMode mode=Automatic)
Change the camera position to the given position.
ArrowCursor
const Key key(const T &value) const const
int maximumZoom() const
Return the minimum zoom value for the current map theme.
MapQuality
This enum is used to choose the map quality shown in the view.
Definition: MarbleGlobal.h:74
void zoomView(int zoom, FlyToMode mode=Instant)
void leaveEvent(QEvent *event) override
Reimplementation of the leaveEvent() function in QWidget.
void setProjection(int projection)
Set the Projection used for the map.
void setCenterLatitude(qreal lat, FlyToMode mode=Instant)
Set the latitude for the center point.
A class that defines a 2D bounding box for geographic data.
QVariant value(const QString &key, const QVariant &defaultValue) const const
bool screenCoordinates(qreal lon, qreal lat, qreal &x, qreal &y) const
Get the screen coordinates corresponding to geographical coordinates in the widget.
void notifyMouseClick(int x, int y)
Used to notify about the position of the mouse click.
QString distanceString() const
Return the current distance string.
UniqueConnection
Binds a QML item to a specific geodetic location in screen coordinates.
void setShowPlaces(bool visible)
Set whether the place mark overlay is visible.
void setShowScaleBar(bool visible)
Set whether the scale bar overlay is visible.
void setShowCompass(bool visible)
Set whether the compass overlay is visible.
qreal distanceFromZoom(qreal zoom) const
Returns the distance (km) corresponding to the given zoom value.
qint64 elapsed() const const
const QRect & rect() const const
FlyToMode
Describes possible flight mode (interpolation between source and target camera positions)
Definition: MarbleGlobal.h:157
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:88
bool showFrameRate() const
Return whether the frame rate gets displayed.
uchar * scanLine(int i)
a class representing a point of interest on the map
qreal moveStep() const
Return how much the map will move if one of the move slots are called.
void setDebugLevelTags(bool visible)
Set whether to render according to OSM indoor level tags.
void setMapQualityForViewContext(MapQuality quality, ViewContext viewContext)
Set the map quality for the specified view context.
void setAnimationsEnabled(bool enabled)
Set whether travels to a point should get animated.
Projection
This enum is used to choose the projection shown in the view.
Definition: MarbleGlobal.h:41
void endGroup()
void rotateBy(const qreal deltaLon, const qreal deltaLat, FlyToMode mode=Instant)
Rotate the view by the two angles phi and theta.
qreal distanceFromRadius(qreal radius) const
Return the distance (km) at the given globe radius (pixel)
void goHome(FlyToMode mode=Automatic)
Center the view on the default start point with the default zoom.
AngleUnit
This enum is used to choose the unit chosen to measure angles.
Definition: MarbleGlobal.h:57
QStringList childKeys() const const
qreal centerLatitude() const
Return the latitude of the center point.
void setHighlightEnabled(bool enabled)
Toggle whether regions are highlighted when user selects them.
void setSubSolarPointIconVisible(bool visible)
Set whether the sun icon is shown in the sub solar point.
void setShowGrid(bool visible)
Set whether the coordinate grid overlay is visible.
void setShowRuntimeTrace(bool visible)
Set whether the runtime tracing for layers gets shown.
AbstractFloatItem * floatItem(const QString &nameId) const
Returns the FloatItem with the given id.
void setViewContext(ViewContext viewContext)
Set the view context (i.e.
void setShowAtmosphere(bool visible)
Set whether the atmospheric glow is visible.
QList::const_iterator constEnd() const const
void setShowTileId(bool visible)
Set whether the is tile is visible NOTE: This is part of the transitional debug API and might be subj...
Unit
enum used constructor to specify the units used
void moveLeft(FlyToMode mode=Automatic)
Move left by the moveStep.
void moveRight(FlyToMode mode=Automatic)
Move right by the moveStep.
void setShowCrosshairs(bool visible)
Set whether the crosshairs are visible.
void removeLayer(LayerInterface *layer)
Remove a layer from being included in rendering.
void reloadMap()
Re-download all visible tiles.
MarbleWidget(QWidget *parent=nullptr)
Construct a new MarbleWidget.
GeoSceneDocument * mapTheme() const
Get the GeoSceneDocument object of the current map theme.
QList< AbstractDataPluginItem * > whichItemAt(const QPoint &curpos) const
Returns all widgets of dataPlugins on the position curpos.
RenderState renderState() const
Detailed render status of the current map view.
void setShowLakes(bool visible)
Set whether the lakes are visible.
QMetaMethod fromSignal(PointerToMemberFunction signal)
virtual void customPaint(GeoPainter *painter)
Enables custom drawing onto the MarbleWidget straight after.
@ Mercator
Mercator projection.
Definition: MarbleGlobal.h:44
A paint layer that serves as a view on a route model.
Definition: RoutingLayer.h:29
void setShowSunShading(bool visible)
Set whether the night shadow is visible.
bool geoCoordinates(int x, int y, qreal &lon, qreal &lat, GeoDataCoordinates::Unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the widget.
void setShowFrameRate(bool visible)
Set whether the frame rate gets shown.
WheelFocus
bool animationsEnabled() const
Retrieve whether travels to a point should get animated.
QList< AbstractFloatItem * > floatItems() const
Returns a list of all FloatItems on the widget.
void setShowDebugPolygons(bool visible)
Set whether to enter the debug mode for polygon node drawing.
void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
void setShowDebugBatchRender(bool visible)
Set whether to enter the debug mode for batch rendering.
void setLockToSubSolarPoint(bool visible)
Set the globe locked to the sub solar point.
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:86
void setCenterLongitude(qreal lon, FlyToMode mode=Instant)
Set the longitude for the center point.
WA_NoSystemBackground
const StyleBuilder * styleBuilder() const
A container for features parsed from the DGML file.
void setDistance(qreal distance)
Set the distance of the observer to the globe in km.
void setZoom(int zoom, FlyToMode mode=Instant)
Zoom the view to a certain zoomlevel.
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
void setCursor(const QCursor &)
QHash::iterator end()
void setShowOtherPlaces(bool visible)
Set whether the other places overlay is visible.
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 04:07:50 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.