File indexing completed on 2025-02-16 06:46:11
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 #include "MonavConfigWidget.h" 0007 0008 #include "MonavMapsModel.h" 0009 #include "MonavPlugin.h" 0010 #include "MarbleDirs.h" 0011 #include "MarbleDebug.h" 0012 0013 #include <QFile> 0014 #include <QProcess> 0015 #include <QSignalMapper> 0016 #include <QPushButton> 0017 #include <QShowEvent> 0018 #include <QSortFilterProxyModel> 0019 #include <QMessageBox> 0020 #include <QNetworkAccessManager> 0021 #include <QNetworkReply> 0022 #include <QDomDocument> 0023 0024 namespace Marble 0025 { 0026 0027 class MonavStuffEntry 0028 { 0029 public: 0030 void setPayload( const QString &payload ); 0031 0032 QString payload() const; 0033 0034 void setName( const QString &name ); 0035 0036 QString name() const; 0037 0038 bool isValid() const; 0039 0040 QString continent() const; 0041 0042 QString state() const; 0043 0044 QString region() const; 0045 0046 QString transport() const; 0047 0048 private: 0049 QString m_payload; 0050 0051 QString m_name; 0052 0053 QString m_continent; 0054 0055 QString m_state; 0056 0057 QString m_region; 0058 0059 QString m_transport; 0060 }; 0061 0062 class MonavConfigWidgetPrivate 0063 { 0064 public: 0065 MonavConfigWidget* m_parent; 0066 0067 MonavPlugin* m_plugin; 0068 0069 QNetworkAccessManager m_networkAccessManager; 0070 0071 QNetworkReply* m_currentReply; 0072 0073 QProcess* m_unpackProcess; 0074 0075 QSortFilterProxyModel* m_filteredModel; 0076 0077 MonavMapsModel* m_mapsModel; 0078 0079 bool m_initialized; 0080 0081 QSignalMapper m_removeMapSignalMapper; 0082 0083 QSignalMapper m_upgradeMapSignalMapper; 0084 0085 QVector<MonavStuffEntry> m_remoteMaps; 0086 0087 QMap<QString, QString> m_remoteVersions; 0088 0089 QString m_currentDownload; 0090 0091 QFile m_currentFile; 0092 0093 QString m_transport; 0094 0095 MonavConfigWidgetPrivate( MonavConfigWidget* parent, MonavPlugin* plugin ); 0096 0097 void parseNewStuff( const QByteArray &data ); 0098 0099 bool updateContinents( QComboBox* comboBox ); 0100 0101 bool updateStates( const QString &continent, QComboBox* comboBox ); 0102 0103 bool updateRegions( const QString &continent, const QString &state, QComboBox* comboBox ); 0104 0105 MonavStuffEntry map( const QString &continent, const QString &state, const QString ®ion ) const; 0106 0107 void install(); 0108 0109 void installMap(); 0110 0111 void updateInstalledMapsView(); 0112 0113 void updateInstalledMapsViewButtons(); 0114 0115 void updateTransportPreference(); 0116 0117 static bool canExecute( const QString &executable ); 0118 0119 void setBusy( bool busy, const QString &message = QString() ) const; 0120 0121 private: 0122 static bool fillComboBox( QStringList items, QComboBox* comboBox ); 0123 }; 0124 0125 void MonavStuffEntry::setPayload( const QString &payload ) 0126 { 0127 m_payload = payload; 0128 } 0129 0130 QString MonavStuffEntry::payload() const 0131 { 0132 return m_payload; 0133 } 0134 0135 void MonavStuffEntry::setName( const QString &name ) 0136 { 0137 m_name = name; 0138 QStringList parsed = name.split( QLatin1Char( '/' ) ); 0139 int size = parsed.size(); 0140 m_continent = size > 0 ? parsed.at( 0 ).trimmed() : QString(); 0141 m_state = size > 1 ? parsed.at( 1 ).trimmed() : QString(); 0142 m_region = size > 2 ? parsed.at( 2 ).trimmed() : QString(); 0143 m_transport = "Motorcar"; // No i18n 0144 0145 if ( size > 1 ) { 0146 QString last = parsed.last().trimmed(); 0147 QRegExp regexp("([^(]+)\\(([^)]+)\\)"); 0148 if ( regexp.indexIn( last ) >= 0 ) { 0149 QStringList matches = regexp.capturedTexts(); 0150 if ( matches.size() == 3 ) { 0151 m_transport = matches.at( 2 ).trimmed(); 0152 if ( size > 2 ) { 0153 m_region = matches.at( 1 ).trimmed(); 0154 } else { 0155 m_state = matches.at( 1 ).trimmed(); 0156 } 0157 } 0158 } 0159 } 0160 } 0161 0162 QString MonavStuffEntry::name() const 0163 { 0164 return m_name; 0165 } 0166 0167 QString MonavStuffEntry::continent() const 0168 { 0169 return m_continent; 0170 } 0171 0172 QString MonavStuffEntry::state() const 0173 { 0174 return m_state; 0175 } 0176 0177 QString MonavStuffEntry::region() const 0178 { 0179 return m_region; 0180 } 0181 0182 QString MonavStuffEntry::transport() const 0183 { 0184 return m_transport; 0185 } 0186 0187 bool MonavStuffEntry::isValid() const 0188 { 0189 return !m_continent.isEmpty() && !m_state.isEmpty() && m_payload.startsWith( QLatin1String( "http://" ) ); 0190 } 0191 0192 MonavConfigWidgetPrivate::MonavConfigWidgetPrivate( MonavConfigWidget* parent, MonavPlugin* plugin ) : 0193 m_parent( parent ), m_plugin( plugin ), m_networkAccessManager( nullptr ), 0194 m_currentReply( nullptr ), m_unpackProcess( nullptr ), m_filteredModel( new QSortFilterProxyModel( parent) ), 0195 m_mapsModel( nullptr ), m_initialized( false ) 0196 { 0197 m_filteredModel->setFilterKeyColumn( 1 ); 0198 } 0199 0200 void MonavConfigWidgetPrivate::parseNewStuff( const QByteArray &data ) 0201 { 0202 QDomDocument xml; 0203 if ( !xml.setContent( data ) ) { 0204 mDebug() << "Cannot parse xml file " << data; 0205 return; 0206 } 0207 0208 QDomElement root = xml.documentElement(); 0209 QDomNodeList items = root.elementsByTagName(QStringLiteral("stuff")); 0210 for (int i=0 ; i < items.length(); ++i ) { 0211 MonavStuffEntry item; 0212 QDomNode node = items.item( i ); 0213 0214 QDomNodeList names = node.toElement().elementsByTagName(QStringLiteral("name")); 0215 if ( names.size() == 1 ) { 0216 item.setName( names.at( 0 ).toElement().text() ); 0217 } 0218 0219 QString releaseDate; 0220 QDomNodeList dates = node.toElement().elementsByTagName(QStringLiteral("releasedate")); 0221 if ( dates.size() == 1 ) { 0222 releaseDate = dates.at( 0 ).toElement().text(); 0223 } 0224 0225 QString filename; 0226 QDomNodeList payloads = node.toElement().elementsByTagName(QStringLiteral("payload")); 0227 if ( payloads.size() == 1 ) { 0228 QString payload = payloads.at( 0 ).toElement().text(); 0229 filename = payload.mid(1 + payload.lastIndexOf(QLatin1Char('/'))); 0230 item.setPayload( payload ); 0231 } 0232 0233 if ( item.isValid() ) { 0234 m_remoteMaps.push_back( item ); 0235 if ( !filename.isEmpty() && !releaseDate.isEmpty() ) { 0236 m_remoteVersions[filename] = releaseDate; 0237 } 0238 } 0239 } 0240 0241 m_mapsModel->setInstallableVersions( m_remoteVersions ); 0242 updateInstalledMapsViewButtons(); 0243 } 0244 0245 bool MonavConfigWidgetPrivate::fillComboBox( QStringList items, QComboBox* comboBox ) 0246 { 0247 comboBox->clear(); 0248 std::sort( items.begin(), items.end() ); 0249 comboBox->addItems( items ); 0250 return !items.isEmpty(); 0251 } 0252 0253 bool MonavConfigWidgetPrivate::updateContinents( QComboBox* comboBox ) 0254 { 0255 QSet<QString> continents; 0256 for( const MonavStuffEntry &map: m_remoteMaps ) { 0257 Q_ASSERT( map.isValid() ); 0258 continents << map.continent(); 0259 } 0260 0261 return fillComboBox( continents.values(), comboBox ); 0262 } 0263 0264 bool MonavConfigWidgetPrivate::updateStates( const QString &continent, QComboBox* comboBox ) 0265 { 0266 QSet<QString> states; 0267 for( const MonavStuffEntry &map: m_remoteMaps ) { 0268 Q_ASSERT( map.isValid() ); 0269 if ( map.continent() == continent ) { 0270 states << map.state(); 0271 } 0272 } 0273 0274 return fillComboBox( states.values(), comboBox ); 0275 } 0276 0277 bool MonavConfigWidgetPrivate::updateRegions( const QString &continent, const QString &state, QComboBox* comboBox ) 0278 { 0279 comboBox->clear(); 0280 QMap<QString,QString> regions; 0281 for( const MonavStuffEntry &map: m_remoteMaps ) { 0282 Q_ASSERT( map.isValid() ); 0283 if ( map.continent() == continent && map.state() == state ) { 0284 QString item = "%1 - %2"; 0285 if ( map.region().isEmpty() ) { 0286 item = item.arg( map.state() ); 0287 comboBox->addItem( item.arg( map.transport() ), map.payload() ); 0288 } else { 0289 item = item.arg( map.region(), map.transport() ); 0290 regions.insert( item, map.payload() ); 0291 } 0292 } 0293 } 0294 0295 QMapIterator<QString, QString> iter( regions ); 0296 while ( iter.hasNext() ) { 0297 iter.next(); 0298 comboBox->addItem( iter.key(), iter.value() ); 0299 } 0300 0301 return true; 0302 } 0303 0304 MonavStuffEntry MonavConfigWidgetPrivate::map( const QString &continent, const QString &state, const QString ®ion ) const 0305 { 0306 for( const MonavStuffEntry &entry: m_remoteMaps ) { 0307 if ( continent == entry.continent() && state == entry.state() && region == entry.region() ) { 0308 return entry; 0309 } 0310 } 0311 0312 return MonavStuffEntry(); 0313 } 0314 0315 MonavConfigWidget::MonavConfigWidget( MonavPlugin* plugin ) : 0316 d( new MonavConfigWidgetPrivate( this, plugin ) ) 0317 { 0318 setupUi( this ); 0319 m_statusLabel->setText( plugin->statusMessage() ); 0320 m_statusLabel->setHidden( m_statusLabel->text().isEmpty() ); 0321 d->setBusy( false ); 0322 m_installedMapsListView->setModel( d->m_mapsModel ); 0323 m_configureMapsListView->setModel( d->m_filteredModel ); 0324 m_configureMapsListView->resizeColumnsToContents(); 0325 0326 updateComboBoxes(); 0327 0328 connect( m_continentComboBox, SIGNAL(currentIndexChanged(int)), 0329 this, SLOT(updateStates()) ); 0330 connect( m_transportTypeComboBox, SIGNAL(currentIndexChanged(QString)), 0331 this, SLOT(updateTransportTypeFilter(QString)) ); 0332 connect( m_stateComboBox, SIGNAL(currentIndexChanged(int)), 0333 this, SLOT(updateRegions()) ); 0334 connect( m_installButton, SIGNAL(clicked()), this, SLOT(downloadMap()) ); 0335 connect( m_cancelButton, SIGNAL(clicked()), this, SLOT(cancelOperation()) ); 0336 connect( &d->m_removeMapSignalMapper, SIGNAL(mapped(int)), 0337 this, SLOT(removeMap(int)) ); 0338 connect( &d->m_upgradeMapSignalMapper, SIGNAL(mapped(int)), 0339 this, SLOT(upgradeMap(int)) ); 0340 connect( &d->m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), 0341 this, SLOT(retrieveMapList(QNetworkReply*)) ); 0342 } 0343 0344 MonavConfigWidget::~MonavConfigWidget() 0345 { 0346 delete d; 0347 } 0348 0349 void MonavConfigWidget::loadSettings( const QHash<QString, QVariant> &settings ) 0350 { 0351 d->m_transport = settings[QStringLiteral("transport")].toString(); 0352 d->updateTransportPreference(); 0353 } 0354 0355 void MonavConfigWidgetPrivate::updateTransportPreference() 0356 { 0357 if ( m_parent->m_transportTypeComboBox && m_mapsModel ) { 0358 m_parent->m_transportTypeComboBox->blockSignals( true ); 0359 m_parent->m_transportTypeComboBox->clear(); 0360 QSet<QString> transportTypes; 0361 for( int i=0; i<m_mapsModel->rowCount(); ++i ) { 0362 QModelIndex index = m_mapsModel->index( i, 1 ); 0363 transportTypes << m_mapsModel->data( index ).toString(); 0364 } 0365 m_parent->m_transportTypeComboBox->addItems( transportTypes.values() ); 0366 m_parent->m_transportTypeComboBox->blockSignals( false ); 0367 0368 if ( !m_transport.isEmpty() && m_parent->m_transportTypeComboBox ) { 0369 for ( int i=1; i<m_parent->m_transportTypeComboBox->count(); ++i ) { 0370 if ( m_parent->m_transportTypeComboBox->itemText( i ) == m_transport ) { 0371 m_parent->m_transportTypeComboBox->setCurrentIndex( i ); 0372 return; 0373 } 0374 } 0375 } 0376 } 0377 } 0378 0379 QHash<QString, QVariant> MonavConfigWidget::settings() const 0380 { 0381 QHash<QString, QVariant> settings; 0382 settings.insert(QStringLiteral("transport"), d->m_transport); 0383 return settings; 0384 } 0385 0386 void MonavConfigWidget::retrieveMapList( QNetworkReply *reply ) 0387 { 0388 if ( reply->isReadable() && d->m_currentDownload.isEmpty() ) { 0389 // check if we are redirected 0390 QVariant const redirectionAttribute = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); 0391 if ( !redirectionAttribute.isNull() ) { 0392 d->m_networkAccessManager.get( QNetworkRequest( redirectionAttribute.toUrl() ) ); 0393 } else { 0394 disconnect( &d->m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), 0395 this, SLOT(retrieveMapList(QNetworkReply*)) ); 0396 d->parseNewStuff( reply->readAll() ); 0397 updateComboBoxes(); 0398 } 0399 } 0400 } 0401 0402 void MonavConfigWidget::retrieveData() 0403 { 0404 if ( d->m_currentReply && d->m_currentReply->isReadable() && !d->m_currentDownload.isEmpty() ) { 0405 // check if we are redirected 0406 QVariant const redirectionAttribute = d->m_currentReply->attribute( QNetworkRequest::RedirectionTargetAttribute ); 0407 if ( !redirectionAttribute.isNull() ) { 0408 d->m_currentReply = d->m_networkAccessManager.get( QNetworkRequest( redirectionAttribute.toUrl() ) ); 0409 connect( d->m_currentReply, SIGNAL(readyRead()), 0410 this, SLOT(retrieveData()) ); 0411 connect( d->m_currentReply, SIGNAL(readChannelFinished()), 0412 this, SLOT(retrieveData()) ); 0413 connect( d->m_currentReply, SIGNAL(downloadProgress(qint64,qint64)), 0414 this, SLOT(updateProgressBar(qint64,qint64)) ); 0415 } else { 0416 d->m_currentFile.write( d->m_currentReply->readAll() ); 0417 if ( d->m_currentReply->isFinished() ) { 0418 d->m_currentReply->deleteLater(); 0419 d->m_currentReply = nullptr; 0420 d->m_currentFile.close(); 0421 d->installMap(); 0422 d->m_currentDownload.clear(); 0423 } 0424 } 0425 } 0426 } 0427 0428 void MonavConfigWidget::updateComboBoxes() 0429 { 0430 d->updateContinents( m_continentComboBox ); 0431 updateStates(); 0432 updateRegions(); 0433 } 0434 0435 void MonavConfigWidget::updateStates() 0436 { 0437 bool const haveContinents = m_continentComboBox->currentIndex() >= 0; 0438 if ( haveContinents ) { 0439 QString const continent = m_continentComboBox->currentText(); 0440 if ( d->updateStates( continent, m_stateComboBox ) ) { 0441 updateRegions(); 0442 } 0443 } 0444 } 0445 0446 void MonavConfigWidget::updateRegions() 0447 { 0448 bool haveRegions = false; 0449 if ( m_continentComboBox->currentIndex() >= 0 ) { 0450 if ( m_stateComboBox->currentIndex() >= 0 ) { 0451 QString const continent = m_continentComboBox->currentText(); 0452 QString const state = m_stateComboBox->currentText(); 0453 haveRegions = d->updateRegions( continent, state, m_regionComboBox ); 0454 } 0455 } 0456 0457 m_regionLabel->setVisible( haveRegions ); 0458 m_regionComboBox->setVisible( haveRegions ); 0459 } 0460 0461 void MonavConfigWidget::downloadMap() 0462 { 0463 if ( d->m_currentDownload.isEmpty() && !d->m_currentFile.isOpen() ) { 0464 d->m_currentDownload = m_regionComboBox->itemData( m_regionComboBox->currentIndex() ).toString(); 0465 d->install(); 0466 } 0467 } 0468 0469 void MonavConfigWidget::cancelOperation() 0470 { 0471 if ( !d->m_currentDownload.isEmpty() || d->m_currentFile.isOpen() ) { 0472 d->m_currentReply->abort(); 0473 d->m_currentReply->deleteLater(); 0474 d->m_currentReply = nullptr; 0475 d->m_currentDownload.clear(); 0476 d->setBusy( false ); 0477 d->m_currentFile.close(); 0478 } 0479 } 0480 0481 void MonavConfigWidgetPrivate::install() 0482 { 0483 if ( !m_currentDownload.isEmpty() ) { 0484 int const index = m_currentDownload.lastIndexOf(QLatin1Char('/')); 0485 const QString localFile = MarbleDirs::localPath() + QLatin1String("/maps") + m_currentDownload.mid(index); 0486 m_currentFile.setFileName( localFile ); 0487 if ( m_currentFile.open( QFile::WriteOnly ) ) { 0488 QFileInfo file( m_currentFile ); 0489 QString message = QObject::tr( "Downloading %1" ).arg( file.fileName() ); 0490 setBusy( true, message ); 0491 m_currentReply = m_networkAccessManager.get( QNetworkRequest( QUrl ( m_currentDownload ) ) ); 0492 QObject::connect( m_currentReply, SIGNAL(readyRead()), 0493 m_parent, SLOT(retrieveData()) ); 0494 QObject::connect( m_currentReply, SIGNAL(readChannelFinished()), 0495 m_parent, SLOT(retrieveData()) ); 0496 QObject::connect( m_currentReply, SIGNAL(downloadProgress(qint64,qint64)), 0497 m_parent, SLOT(updateProgressBar(qint64,qint64)) ); 0498 } else { 0499 mDebug() << "Failed to write to " << localFile; 0500 } 0501 } 0502 } 0503 0504 void MonavConfigWidgetPrivate::installMap() 0505 { 0506 if ( m_unpackProcess ) { 0507 m_unpackProcess->close(); 0508 delete m_unpackProcess; 0509 m_unpackProcess = nullptr; 0510 m_parent->m_installButton->setEnabled( true ); 0511 } else if ( m_currentFile.fileName().endsWith( QLatin1String( "tar.gz" ) ) && canExecute( "tar" ) ) { 0512 QFileInfo file( m_currentFile ); 0513 QString message = QObject::tr( "Installing %1" ).arg( file.fileName() ); 0514 setBusy( true, message ); 0515 m_parent->m_progressBar->setMaximum( 0 ); 0516 if ( file.exists() && file.isReadable() ) { 0517 m_unpackProcess = new QProcess; 0518 QObject::connect( m_unpackProcess, SIGNAL(finished(int)), 0519 m_parent, SLOT(mapInstalled(int)) ); 0520 QStringList arguments = QStringList() << "-x" << "-z" << "-f" << file.fileName(); 0521 m_unpackProcess->setWorkingDirectory( file.dir().absolutePath() ); 0522 m_unpackProcess->start( "tar", arguments ); 0523 } 0524 } else { 0525 if ( !m_currentFile.fileName().endsWith( QLatin1String( "tar.gz" ) ) ) { 0526 mDebug() << "Can only handle tar.gz files"; 0527 } else { 0528 mDebug() << "Cannot extract archive: tar executable not found in PATH."; 0529 } 0530 } 0531 } 0532 0533 void MonavConfigWidget::updateProgressBar( qint64 bytesReceived, qint64 bytesTotal ) 0534 { 0535 // Coarse MB resolution for the text to get it short, 0536 // finer Kb resolution for the progress values to see changes easily 0537 m_progressBar->setMaximum( bytesTotal / 1024 ); 0538 m_progressBar->setValue( bytesReceived / 1024 ); 0539 QString progress = "%1/%2 MB"; 0540 m_progressBar->setFormat( progress.arg( bytesReceived / 1024 / 1024 ).arg( bytesTotal / 1024 / 1024 ) ); 0541 } 0542 0543 bool MonavConfigWidgetPrivate::canExecute( const QString &executable ) 0544 { 0545 QString path = QProcessEnvironment::systemEnvironment().value(QStringLiteral("PATH"), QStringLiteral("/usr/local/bin:/usr/bin:/bin")); 0546 for( const QString &dir: path.split( QLatin1Char( ':' ) ) ) { 0547 QFileInfo application( QDir( dir ), executable ); 0548 if ( application.exists() ) { 0549 return true; 0550 } 0551 } 0552 0553 return false; 0554 } 0555 0556 void MonavConfigWidget::mapInstalled( int exitStatus ) 0557 { 0558 d->m_unpackProcess = nullptr; 0559 d->m_currentFile.remove(); 0560 d->setBusy( false ); 0561 0562 if ( exitStatus == 0 ) { 0563 d->m_plugin->reloadMaps(); 0564 d->updateInstalledMapsView(); 0565 monavTabWidget->setCurrentIndex( 0 ); 0566 } else { 0567 mDebug() << "Error when unpacking archive, process exited with status code " << exitStatus; 0568 } 0569 } 0570 0571 void MonavConfigWidget::showEvent ( QShowEvent * event ) 0572 { 0573 // Lazy initialization 0574 RoutingRunnerPlugin::ConfigWidget::showEvent( event ); 0575 if ( !event->spontaneous() && !d->m_initialized ) { 0576 d->m_initialized = true; 0577 d->updateInstalledMapsView(); 0578 QUrl url = QUrl( "http://files.kde.org/marble/newstuff/maps-monav.xml" ); 0579 d->m_networkAccessManager.get( QNetworkRequest( url ) ); 0580 } 0581 } 0582 0583 void MonavConfigWidgetPrivate::updateInstalledMapsView() 0584 { 0585 m_mapsModel = m_plugin->installedMapsModel(); 0586 m_mapsModel->setInstallableVersions( m_remoteVersions ); 0587 m_filteredModel->setSourceModel( m_mapsModel ); 0588 m_parent->m_installedMapsListView->setModel( m_mapsModel ); 0589 0590 m_parent->m_configureMapsListView->setColumnHidden( 1, true ); 0591 m_parent->m_installedMapsListView->setColumnHidden( 2, true ); 0592 m_parent->m_configureMapsListView->setColumnHidden( 3, true ); 0593 m_parent->m_configureMapsListView->setColumnHidden( 4, true ); 0594 m_parent->m_installedMapsListView->setColumnHidden( 5, true ); 0595 0596 m_parent->m_configureMapsListView->horizontalHeader()->setVisible( true ); 0597 m_parent->m_installedMapsListView->horizontalHeader()->setVisible( true ); 0598 m_parent->m_configureMapsListView->resizeColumnsToContents(); 0599 m_parent->m_installedMapsListView->resizeColumnsToContents(); 0600 0601 updateTransportPreference(); 0602 updateInstalledMapsViewButtons(); 0603 } 0604 0605 void MonavConfigWidgetPrivate::updateInstalledMapsViewButtons() 0606 { 0607 m_removeMapSignalMapper.removeMappings( m_parent ); 0608 m_upgradeMapSignalMapper.removeMappings( m_parent ); 0609 for( int i=0; i<m_mapsModel->rowCount(); ++i ) { 0610 { 0611 QPushButton* button = new QPushButton(QIcon(QStringLiteral(":/system-software-update.png")), QString()); 0612 button->setAutoFillBackground( true ); 0613 QModelIndex index = m_mapsModel->index( i, 3 ); 0614 m_parent->m_installedMapsListView->setIndexWidget( index, button ); 0615 m_upgradeMapSignalMapper.setMapping( button, index.row() ); 0616 QObject::connect( button, SIGNAL(clicked()), &m_upgradeMapSignalMapper, SLOT(map()) ); 0617 bool upgradable = m_mapsModel->data( index ).toBool(); 0618 QString canUpgradeText = QObject::tr( "An update is available. Click to install it." ); 0619 QString isLatestText = QObject::tr( "No update available. You are running the latest version." ); 0620 button->setToolTip( upgradable ? canUpgradeText : isLatestText ); 0621 button->setEnabled( upgradable ); 0622 } 0623 { 0624 QPushButton* button = new QPushButton(QIcon(QStringLiteral(":/edit-delete.png")), QString()); 0625 button->setAutoFillBackground( true ); 0626 QModelIndex index = m_mapsModel->index( i, 4 ); 0627 m_parent->m_installedMapsListView->setIndexWidget( index, button ); 0628 m_removeMapSignalMapper.setMapping( button, index.row() ); 0629 QObject::connect( button, SIGNAL(clicked()), &m_removeMapSignalMapper, SLOT(map()) ); 0630 bool const writable = m_mapsModel->data( index ).toBool(); 0631 button->setEnabled( writable ); 0632 } 0633 } 0634 m_parent->m_installedMapsListView->resizeColumnsToContents(); 0635 } 0636 0637 void MonavConfigWidget::updateTransportTypeFilter( const QString &filter ) 0638 { 0639 d->m_filteredModel->setFilterFixedString( filter ); 0640 d->m_transport = filter; 0641 m_configureMapsListView->resizeColumnsToContents(); 0642 } 0643 0644 void MonavConfigWidget::removeMap( int index ) 0645 { 0646 QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel; 0647 QString text = tr( "Are you sure you want to delete this map from the system?" ); 0648 if ( QMessageBox::question( this, tr( "Remove Map" ), text, buttons, QMessageBox::No ) == QMessageBox::Yes ) { 0649 d->m_mapsModel->deleteMapFiles( index ); 0650 d->m_plugin->reloadMaps(); 0651 d->updateInstalledMapsView(); 0652 } 0653 } 0654 0655 void MonavConfigWidget::upgradeMap( int index ) 0656 { 0657 QString payload = d->m_mapsModel->payload( index ); 0658 if ( !payload.isEmpty() ) { 0659 for( const MonavStuffEntry &entry: d->m_remoteMaps ) { 0660 if (entry.payload().endsWith(QLatin1Char('/') + payload)) { 0661 d->m_currentDownload = entry.payload(); 0662 d->install(); 0663 return; 0664 } 0665 } 0666 } 0667 } 0668 0669 void MonavConfigWidgetPrivate::setBusy( bool busy, const QString &message ) const 0670 { 0671 if ( busy ) { 0672 m_parent->m_stackedWidget->removeWidget( m_parent->m_settingsPage ); 0673 m_parent->m_stackedWidget->addWidget( m_parent->m_progressPage ); 0674 } else { 0675 m_parent->m_stackedWidget->removeWidget( m_parent->m_progressPage ); 0676 m_parent->m_stackedWidget->addWidget( m_parent->m_settingsPage ); 0677 } 0678 0679 QString const defaultMessage = QObject::tr( "Nothing to do." ); 0680 m_parent->m_progressLabel->setText( message.isEmpty() ? defaultMessage : message ); 0681 } 0682 0683 } 0684 0685 #include "moc_MonavConfigWidget.cpp"