Marble

DownloadRegionDialog.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
4//
5
6#include "DownloadRegionDialog.h"
7
8#include <cmath>
9
10#include <QDialogButtonBox>
11#include <QGroupBox>
12#include <QHBoxLayout>
13#include <QHideEvent>
14#include <QLabel>
15#include <QComboBox>
16#include <QPushButton>
17#include <QButtonGroup>
18#include <QRadioButton>
19#include <QShowEvent>
20#include <QVBoxLayout>
21#include <QSpinBox>
22#include <QScrollArea>
23#include <QSet>
24#include <QStandardItemModel>
25#include <QTimer>
26
27#include "GeoDataLatLonAltBox.h"
28#include "MarbleDebug.h"
29#include "MarbleModel.h"
30#include "MarbleWidget.h"
31#include "LatLonBoxWidget.h"
32#include "TileLayer.h"
33#include "TextureLayer.h"
34#include "VectorTileLayer.h"
35#include "TileId.h"
36#include "TileCoordsPyramid.h"
37#include "TileLevelRangeWidget.h"
38#include "TileLoaderHelper.h"
39#include "routing/RoutingManager.h"
40#include "routing/RoutingModel.h"
41#include "GeoDataCoordinates.h"
42#include "GeoDataLineString.h"
43#include "DownloadRegion.h"
44#include "GeoSceneDocument.h"
45#include "GeoSceneMap.h"
46#include "Route.h"
47
48namespace Marble
49{
50
51int const maxTilesCount = 100000;
52int const minimumRouteOffset = 0;
53int const maximumRouteOffset = 10000;
54int averageTextureTileSize = 13; //The average size of a tile in kilobytes
55int averageVectorTileSize = 30; // The average size of a vector tile in kilobytes
56
57class Q_DECL_HIDDEN DownloadRegionDialog::Private
58{
59public:
60 Private( MarbleWidget *const widget, QDialog * const dialog );
61 QWidget * createSelectionMethodBox();
62 QLayout * createTilesCounter();
63 QWidget * createOkCancelButtonBox();
64
65 bool hasRoute() const;
66 bool hasTextureLayers() const;
67 bool hasVectorLayers() const;
68 QDialog * m_dialog;
69 QLabel * m_layerLabel;
70 QComboBox * m_layerComboBox;
71 QButtonGroup * m_buttonGroup;
72 QRadioButton * m_visibleRegionMethodButton;
73 QRadioButton * m_specifiedRegionMethodButton;
74 LatLonBoxWidget * m_latLonBoxWidget;
75 TileLevelRangeWidget * m_tileLevelRangeWidget;
76 QRadioButton *m_routeDownloadMethodButton;
77 QLabel* m_routeOffsetLabel;
78 QDoubleSpinBox *m_routeOffsetSpinBox;
79 QLabel * m_tilesCountLabel;
80 QLabel * m_tileSizeInfo;
81 QPushButton * m_okButton;
82 QPushButton * m_applyButton;
83 TextureLayer const * m_textureLayer;
84 VectorTileLayer const * m_vectorTileLayer;
85 int m_visibleTileLevel;
86 MarbleModel const*const m_model;
87 MarbleWidget *const m_widget;
88 SelectionMethod m_selectionMethod;
89 GeoDataLatLonAltBox m_visibleRegion;
90 RoutingModel *m_routingModel;
91 DownloadRegion m_downloadRegion;
92 TileType m_tileType;
93};
94
95DownloadRegionDialog::Private::Private( MarbleWidget * const widget,
96 QDialog * const dialog )
97 : m_dialog( dialog ),
98 m_layerLabel( nullptr ),
99 m_layerComboBox( nullptr ),
100 m_buttonGroup(nullptr),
101 m_visibleRegionMethodButton( nullptr ),
102 m_specifiedRegionMethodButton( nullptr ),
103 m_latLonBoxWidget( new LatLonBoxWidget ),
104 m_tileLevelRangeWidget( new TileLevelRangeWidget ),
105 m_routeDownloadMethodButton( nullptr ),
106 m_routeOffsetLabel( nullptr ),
107 m_routeOffsetSpinBox( nullptr ),
108 m_tilesCountLabel( nullptr ),
109 m_tileSizeInfo( nullptr ),
110 m_okButton( nullptr ),
111 m_applyButton( nullptr ),
112 m_textureLayer( widget->textureLayer() ),
113 m_vectorTileLayer( widget->vectorTileLayer() ),
114 m_visibleTileLevel( 0 ),
115 m_model( widget->model() ),
116 m_widget( widget ),
117 m_selectionMethod( VisibleRegionMethod ),
118 m_visibleRegion(),
119 m_routingModel( widget->model()->routingManager()->routingModel() )
120{
121 m_latLonBoxWidget->setEnabled( false );
122 m_latLonBoxWidget->setLatLonBox( m_visibleRegion );
123 m_tileLevelRangeWidget->setDefaultLevel( m_visibleTileLevel );
124 m_downloadRegion.setMarbleModel( widget->model() );
125}
126
127
128
129QWidget * DownloadRegionDialog::Private::createSelectionMethodBox()
130{
131 m_buttonGroup = new QButtonGroup(m_dialog);
132 m_buttonGroup->setExclusive(true);
133 m_visibleRegionMethodButton = new QRadioButton( tr( "Visible region" ) );
134 m_buttonGroup->addButton(m_visibleRegionMethodButton);
135 m_specifiedRegionMethodButton = new QRadioButton( tr( "Specify region" ) );
136 m_buttonGroup->addButton(m_specifiedRegionMethodButton);
137 m_routeDownloadMethodButton = new QRadioButton( tr( "Download Route" ) );
138 m_buttonGroup->addButton(m_routeDownloadMethodButton);
139 m_routeDownloadMethodButton->setToolTip( tr( "Enabled when a route exists" ) );
140 m_routeDownloadMethodButton->setEnabled( hasRoute() );
141 m_routeDownloadMethodButton->setChecked( hasRoute() );
142 m_routeOffsetSpinBox = new QDoubleSpinBox();
143 m_routeOffsetSpinBox->setEnabled( hasRoute() );
144 m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset );
145 int defaultOffset = 500;
146 m_routeOffsetSpinBox->setValue( defaultOffset );
147 m_routeOffsetSpinBox->setSingleStep( 100 );
148 m_routeOffsetSpinBox->setSuffix( " m" );
149 m_routeOffsetSpinBox->setDecimals( 0 );
150 m_routeOffsetSpinBox->setAlignment( Qt::AlignRight );
151
152 m_routeOffsetLabel = new QLabel( tr( "Offset from route:" ) );
153 m_routeOffsetLabel->setAlignment( Qt::AlignHCenter );
154
155 connect( m_buttonGroup, SIGNAL(buttonToggled(QAbstractButton*,bool)),
156 m_dialog, SLOT(toggleSelectionMethod()) );
157 connect( m_routingModel, SIGNAL(modelReset()), m_dialog, SLOT(updateRouteDialog()) );
158 connect( m_routingModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
159 m_dialog, SLOT(updateRouteDialog()) );
160 connect( m_routingModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
161 m_dialog, SLOT(updateRouteDialog()) );
162
163 QHBoxLayout *routeOffsetLayout = new QHBoxLayout;
164 routeOffsetLayout->addWidget( m_routeOffsetLabel );
165 routeOffsetLayout->insertSpacing( 0, 25 );
166 routeOffsetLayout->addWidget( m_routeOffsetSpinBox );
167
168 QVBoxLayout * const routeLayout = new QVBoxLayout;
169 routeLayout->addWidget( m_routeDownloadMethodButton );
170 routeLayout->addLayout( routeOffsetLayout );
171
172 QVBoxLayout * const layout = new QVBoxLayout;
173 layout->addWidget( m_visibleRegionMethodButton );
174 layout->addLayout( routeLayout );
175 layout->addWidget( m_specifiedRegionMethodButton );
176 layout->addWidget( m_latLonBoxWidget );
177
178 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
179 m_specifiedRegionMethodButton->setVisible( !smallScreen );
180 m_latLonBoxWidget->setVisible( !smallScreen );
181
182 if ( smallScreen ) {
183 QWidget * const selectionMethodWidget = new QWidget;
184 selectionMethodWidget->setLayout( layout );
185 return selectionMethodWidget;
186 } else {
187 QGroupBox * const selectionMethodBox = new QGroupBox( tr( "Selection Method" ) );
188 selectionMethodBox->setLayout( layout );
189 return selectionMethodBox;
190 }
191}
192
193QLayout * DownloadRegionDialog::Private::createTilesCounter()
194{
195 QLabel * const description = new QLabel( tr( "Number of tiles to download:" ) );
196 m_tilesCountLabel = new QLabel;
197 m_tileSizeInfo = new QLabel;
198
199 QHBoxLayout * const tilesCountLayout = new QHBoxLayout;
200 tilesCountLayout->addWidget( description );
201 tilesCountLayout->addWidget( m_tilesCountLabel );
202 //tilesCountLayout->insertSpacing( 0, 5 );
203 QVBoxLayout * const layout = new QVBoxLayout;
204 layout->addLayout( tilesCountLayout );
205 layout->addWidget( m_tileSizeInfo );
206 return layout;
207}
208
209QWidget * DownloadRegionDialog::Private::createOkCancelButtonBox()
210{
211 QDialogButtonBox * const buttonBox = new QDialogButtonBox;
212 m_okButton = buttonBox->addButton( QDialogButtonBox::Ok );
213 m_applyButton = buttonBox->addButton( QDialogButtonBox::Apply );
214 if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
215 buttonBox->removeButton( m_applyButton );
216 m_applyButton->setVisible( false );
217 }
219 connect( buttonBox, SIGNAL(accepted()), m_dialog, SLOT(accept()) );
220 connect( buttonBox, SIGNAL(rejected()), m_dialog, SLOT(reject()) );
221 connect( m_applyButton, SIGNAL(clicked()), m_dialog, SIGNAL(applied()) );
222 return buttonBox;
223}
224
225bool DownloadRegionDialog::Private::hasRoute() const
226{
227 return !m_routingModel->route().path().isEmpty();
228}
229
230bool DownloadRegionDialog::Private::hasTextureLayers() const
231{
232 return m_model->mapTheme()->map()->hasTextureLayers();
233}
234
235bool DownloadRegionDialog::Private::hasVectorLayers() const
236{
237 return m_model->mapTheme()->map()->hasVectorLayers();
238}
239
240DownloadRegionDialog::DownloadRegionDialog( MarbleWidget *const widget, QWidget * const parent,
241 Qt::WindowFlags const f )
242 : QDialog( parent, f ),
243 d( new Private( widget, this ))
244{
245 setWindowTitle( tr( "Download Region" ));
246 QVBoxLayout * const layout = new QVBoxLayout;
247 d->m_layerLabel = new QLabel( tr( "Tile type to be downloaded:" ));
248 d->m_layerComboBox = new QComboBox();
249 d->m_layerComboBox->addItem(tr("Texture tiles"));
250 d->m_layerComboBox->addItem(tr("Vector tiles"));
251 d->m_layerComboBox->setToolTip(tr("Allows selection between layer types that are visibly being rendered."));
252 updateTileLayer();
253
254 layout->addWidget( d->m_layerLabel );
255 layout->addWidget( d->m_layerComboBox );
256 layout->addWidget( d->createSelectionMethodBox() );
257 layout->addWidget( d->m_tileLevelRangeWidget );
258 layout->addStretch();
259 layout->addLayout( d->createTilesCounter() );
260
261 if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
262 QWidget* widget = new QWidget( this );
263 widget->setLayout( layout );
264 QScrollArea* scrollArea = new QScrollArea( this );
265 scrollArea->setFrameShape( QFrame::NoFrame );
266 scrollArea->setWidget( widget );
267 QVBoxLayout * const mainLayout = new QVBoxLayout;
268 mainLayout->addWidget( scrollArea );
269 mainLayout->addWidget( d->createOkCancelButtonBox() );
270 setLayout( mainLayout );
271 } else {
272 layout->addWidget( d->createOkCancelButtonBox() );
273 setLayout( layout );
274 }
275
276 connect( d->m_layerComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
277 this, &DownloadRegionDialog::updateTileCount );
278 connect( d->m_latLonBoxWidget, &Marble::LatLonBoxWidget::valueChanged,
279 this, &DownloadRegionDialog::updateTileCount );
280 connect( d->m_tileLevelRangeWidget, &TileLevelRangeWidget::topLevelChanged,
281 this, &DownloadRegionDialog::updateTileCount );
282 connect( d->m_tileLevelRangeWidget, &TileLevelRangeWidget::bottomLevelChanged,
283 this, &DownloadRegionDialog::updateTileCount );
284 connect( d->m_routeOffsetSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
285 this, &DownloadRegionDialog::updateTileCount );
286 connect( d->m_routeOffsetSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
287 this, &DownloadRegionDialog::setOffsetUnit );
288 connect( d->m_model, &MarbleModel::themeChanged,
289 this, &DownloadRegionDialog::delayUpdateTileLayer);
290}
291
292DownloadRegionDialog::~DownloadRegionDialog()
293{
294 delete d;
295}
296
297void DownloadRegionDialog::setAllowedTileLevelRange( int const minimumTileLevel,
298 int const maximumTileLevel )
299{
300 d->m_tileLevelRangeWidget->setAllowedLevelRange( minimumTileLevel, maximumTileLevel );
301}
302
303void DownloadRegionDialog::setVisibleTileLevel( int const tileLevel )
304{
305 d->m_visibleTileLevel = tileLevel;
306 d->m_tileLevelRangeWidget->setDefaultLevel( tileLevel );
307 d->m_downloadRegion.setVisibleTileLevel( tileLevel );
308}
309
310void DownloadRegionDialog::setSelectionMethod( SelectionMethod const selectionMethod )
311{
312 d->m_selectionMethod = selectionMethod;
313 switch ( selectionMethod ) {
314 case VisibleRegionMethod:
315 d->m_visibleRegionMethodButton->setChecked( true );
316 d->m_routeOffsetLabel->setEnabled( false );
317 d->m_routeOffsetSpinBox->setEnabled( false );
318 d->m_latLonBoxWidget->setEnabled( false );
319 setSpecifiedLatLonAltBox( d->m_visibleRegion );
320 break;
321 case SpecifiedRegionMethod:
322 d->m_specifiedRegionMethodButton->setChecked( true );
323 d->m_routeOffsetLabel->setEnabled( false );
324 d->m_routeOffsetSpinBox->setEnabled( false );
325 d->m_latLonBoxWidget->setEnabled( true );
326 break;
327 case RouteDownloadMethod:
328 d->m_routeDownloadMethodButton->setChecked( true );
329 d->m_routeOffsetLabel->setEnabled( true );
330 d->m_routeOffsetSpinBox->setEnabled( true );
331 d->m_latLonBoxWidget->setEnabled( false );
332 }
333
334 updateTileCount();
335}
336
337QVector<TileCoordsPyramid> DownloadRegionDialog::region() const
338{
339 if ( !d->hasTextureLayers() && !d->hasVectorLayers() ) {
341 }
342
343 d->m_visibleTileLevel = (tileType() == TextureTileType && d->m_textureLayer->tileZoomLevel() != -1)
344 ? d->m_textureLayer->tileZoomLevel() : d->m_vectorTileLayer->tileZoomLevel();
345
346 const TileLayer * tileLayer = (tileType() == TextureTileType && d->m_textureLayer->layerCount() > 0)
347 ? dynamic_cast<const TileLayer *>(d->m_textureLayer)
348 : dynamic_cast<const TileLayer *>(d->m_vectorTileLayer);
349
350 d->m_downloadRegion.setTileLevelRange( d->m_tileLevelRangeWidget->topLevel(),
351 d->m_tileLevelRangeWidget->bottomLevel() );
352 d->m_downloadRegion.setVisibleTileLevel( d->m_visibleTileLevel );
353
354 // check whether "visible region" or "lat/lon region" is selection method
355 GeoDataLatLonAltBox downloadRegion;
356 switch ( d->m_selectionMethod ) {
357 case VisibleRegionMethod:
358 downloadRegion = d->m_visibleRegion;
359 break;
360 case SpecifiedRegionMethod:
361 downloadRegion = GeoDataLatLonAltBox( d->m_latLonBoxWidget->latLonBox(), 0, 0 );
362 break;
363 case RouteDownloadMethod:
364 qreal offset = d->m_routeOffsetSpinBox->value();
365 if (d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) {
366 offset *= KM2METER;
367 }
368 const GeoDataLineString waypoints = d->m_model->routingManager()->routingModel()->route().path();
369 return d->m_downloadRegion.fromPath( tileLayer, offset, waypoints );
370 }
371
372 // For Mercator tiles limit the LatLonBox to the valid tile range.
373 if (tileLayer->tileProjection()->type() == GeoSceneAbstractTileProjection::Mercator) {
374 downloadRegion.setNorth(qMin(downloadRegion.north(), +1.4835));
375 downloadRegion.setSouth(qMax(downloadRegion.south(), -1.4835));
376 }
377
378 return d->m_downloadRegion.region( tileLayer, downloadRegion );
379}
380
381TileType DownloadRegionDialog::tileType() const
382{
383 return d->m_layerComboBox->currentIndex() == 0 ? TextureTileType : VectorTileType;
384}
385
386void DownloadRegionDialog::setSpecifiedLatLonAltBox( GeoDataLatLonAltBox const & region )
387{
388 d->m_latLonBoxWidget->setLatLonBox( region );
389}
390
391void DownloadRegionDialog::setVisibleLatLonAltBox( GeoDataLatLonAltBox const & region )
392{
393 d->m_visibleRegion = region;
394
395 // update lat/lon widget only if not active to prevent that users unintentionally loose
396 // entered values
397 if ( d->m_selectionMethod == VisibleRegionMethod ) {
398 setSpecifiedLatLonAltBox( region );
399 }
400 updateTileCount();
401}
402
403void DownloadRegionDialog::updateTileLayer()
404{
405 updateTileType();
406 updateTileCount();
407}
408
409void DownloadRegionDialog::delayUpdateTileLayer()
410{
411 QTimer::singleShot(500, this, &DownloadRegionDialog::updateTileLayer);
412}
413
414void DownloadRegionDialog::hideEvent( QHideEvent * event )
415{
416 disconnect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
417 this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) );
418 disconnect( d->m_widget, SIGNAL(themeChanged(QString)),
419 this, SLOT(delayUpdateTileLayer()) );
420 disconnect( d->m_widget, SIGNAL(propertyValueChanged(QString,bool)),
421 this, SLOT(delayUpdateTileLayer()) );
422
423 emit hidden();
424 event->accept();
425}
426
427void DownloadRegionDialog::showEvent( QShowEvent * event )
428{
429 connect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
430 this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) );
431 connect( d->m_widget, SIGNAL(themeChanged(QString)),
432 this, SLOT(delayUpdateTileLayer()) );
433 connect( d->m_widget, SIGNAL(propertyValueChanged(QString,bool)),
434 this, SLOT(delayUpdateTileLayer()) );
435
436 setVisibleTileLevel(d->m_widget->tileZoomLevel());
437
438 updateTileCount();
439
440 emit shown();
441 event->accept();
442}
443
444void DownloadRegionDialog::toggleSelectionMethod()
445{
446 if( d->m_specifiedRegionMethodButton->isChecked() ) {
447 setSelectionMethod( SpecifiedRegionMethod );
448 }
449 else if( d->m_routeDownloadMethodButton->isChecked() ) {
450 setSelectionMethod( RouteDownloadMethod );
451 }
452 else if( d->m_specifiedRegionMethodButton->isChecked() ) {
453 setSelectionMethod( SpecifiedRegionMethod );
454 }
455}
456
457void DownloadRegionDialog::updateTileType()
458{
459 bool hasVisibleTextureLayers = d->hasTextureLayers() && d->m_textureLayer->layerCount() > 0;
460 bool hasVisibleVectorLayers = d->hasVectorLayers() && d->m_vectorTileLayer->layerCount() > 0;
461
462 QStandardItemModel *model = qobject_cast<QStandardItemModel *>(d->m_layerComboBox->model());
463 Q_ASSERT(model != nullptr);
464 QStandardItem *item = nullptr;
465 item = model->item(0);
466 item->setFlags(hasVisibleTextureLayers ? item->flags() | Qt::ItemIsEnabled
467 : item->flags() & ~Qt::ItemIsEnabled);
468 item = model->item(1);
469 item->setFlags(hasVisibleVectorLayers ? item->flags() | Qt::ItemIsEnabled
470 : item->flags() & ~Qt::ItemIsEnabled);
471
472 bool allTileTypesAvailable = hasVisibleTextureLayers && hasVisibleVectorLayers;
473
474 d->m_layerComboBox->setEnabled(allTileTypesAvailable);
475 if (hasVisibleVectorLayers) {
476 d->m_layerComboBox->setCurrentIndex(1);
477 }
478 else if (hasVisibleTextureLayers && !hasVisibleVectorLayers) {
479 d->m_layerComboBox->setCurrentIndex(0);
480 }
481}
482
483void DownloadRegionDialog::updateTileCount()
484{
485 if ( !isVisible() ) {
486 return;
487 }
488
489 qint64 tilesCount = 0;
490 QString themeId( d->m_model->mapThemeId() );
491 QVector<TileCoordsPyramid> const pyramid = region();
492 Q_ASSERT( !pyramid.isEmpty() );
493 if( pyramid.size() == 1 ) {
494 tilesCount = pyramid[0].tilesCount();
495 }
496 else {
497 for( int level = pyramid[0].bottomLevel(); level>= pyramid[0].topLevel(); --level ) {
498 QSet<TileId> tileIdSet;
499 for( int i = 0; i < pyramid.size(); ++i ) {
500 QRect const coords = pyramid[i].coords( level );
501 int x1, y1, x2, y2;
502 coords.getCoords( &x1, &y1, &x2, &y2 );
503 for ( int x = x1; x <= x2; ++x ) {
504 for ( int y = y1; y <= y2; ++y ) {
505 TileId const tileId( 0, level, x, y );
506 tileIdSet.insert( tileId );
507 }
508 }
509 }
510 tilesCount += tileIdSet.count();
511 }
512 }
513
514 qreal tileDownloadSize = 0;
515
516 if ( tilesCount > maxTilesCount ) {
517 d->m_tileSizeInfo->setToolTip( QString() );
518 //~ singular There is a limit of %n tile to download.
519 //~ plural There is a limit of %n tiles to download.
520 d->m_tileSizeInfo->setText( tr( "There is a limit of %n tile(s) to download.", "",
521 maxTilesCount ) );
522 } else {
523 if (themeId == QLatin1String("earth/openstreetmap/openstreetmap.dgml") ||
524 themeId == QLatin1String("earth/openstreetmap/openseamap.dgml") ||
525 themeId == QLatin1String("earth/vectorosm/vectorosm.dgml") ) {
526
527 tileDownloadSize = tileType() == TextureTileType
528 ? tilesCount * averageTextureTileSize
529 : tilesCount * averageVectorTileSize;
530
531 d->m_tileSizeInfo->setToolTip( tr( "Approximate size of the tiles to be downloaded" ) );
532
533 if( tileDownloadSize > 1024 ) {
534 tileDownloadSize = tileDownloadSize / 1024;
535 d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 MB" ).arg( ceil( tileDownloadSize ) ) );
536 }
537 else {
538 d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 kB" ).arg( tileDownloadSize ) );
539 }
540 }
541 else {
542 d->m_tileSizeInfo->setToolTip( QString() );
543 d->m_tileSizeInfo->clear();
544 }
545 }
546
547 d->m_tilesCountLabel->setText( QString::number( tilesCount ) );
548 bool const tilesCountWithinLimits = tilesCount > 0 && tilesCount <= maxTilesCount;
549 d->m_okButton->setEnabled( tilesCountWithinLimits );
550 d->m_applyButton->setEnabled( tilesCountWithinLimits );
551}
552
553void DownloadRegionDialog::updateRouteDialog()
554{
555 d->m_routeDownloadMethodButton->setEnabled( d->hasRoute() );
556 d->m_routeDownloadMethodButton->setChecked( d->hasRoute() );
557 if( !d->hasRoute() ) {
558 setSelectionMethod( VisibleRegionMethod );
559 }
560}
561
562void DownloadRegionDialog::setOffsetUnit()
563{
564 qreal offset = d->m_routeOffsetSpinBox->value();
565
566 if( offset >= 1100 ) {
567 d->m_routeOffsetSpinBox->setSuffix( " km" );
568 d->m_routeOffsetSpinBox->setRange( minimumRouteOffset * METER2KM, maximumRouteOffset * METER2KM );
569 d->m_routeOffsetSpinBox->setDecimals( 1 );
570 d->m_routeOffsetSpinBox->setValue( offset * METER2KM );
571 d->m_routeOffsetSpinBox->setSingleStep( 0.1 );
572 }
573 else if (offset <= 1 && d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) {
574 d->m_routeOffsetSpinBox->setSuffix( " m" );
575 d->m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset );
576 d->m_routeOffsetSpinBox->setDecimals( 0 );
577 d->m_routeOffsetSpinBox->setValue( offset * KM2METER );
578 d->m_routeOffsetSpinBox->setSingleStep( 100 );
579 }
580}
581
582}
583
584#include "moc_DownloadRegionDialog.cpp"
This file contains the headers for MarbleModel.
This file contains the headers for MarbleWidget.
QStringView level(QStringView ifopt)
Binds a QML item to a specific geodetic location in screen coordinates.
@ TextureTileType
Tiles that consist of bitmap data.
@ VectorTileType
Tiles that consist of vector data.
void addLayout(QLayout *layout, int stretch)
void addStretch(int stretch)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void insertSpacing(int index, int size)
void currentIndexChanged(int index)
QPushButton * addButton(StandardButton button)
void removeButton(QAbstractButton *button)
void valueChanged(double d)
void setFrameShape(Shape)
bool isEmpty() const const
qsizetype size() const const
void getCoords(int *x1, int *y1, int *x2, int *y2) const const
void setWidget(QWidget *widget)
qsizetype count() const const
iterator insert(const T &value)
Qt::ItemFlags flags() const const
void setFlags(Qt::ItemFlags flags)
QStandardItem * item(int row, int column) const const
QString number(double n, char format, int precision)
AlignRight
ItemIsEnabled
typedef WindowFlags
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setLayout(QLayout *layout)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.