File indexing completed on 2024-04-28 03:50:23
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2012 Rene Kuettner <rene@bitkanal.net> 0004 // 0005 0006 #include "SatellitesConfigDialog.h" 0007 0008 #include <QMessageBox> 0009 #include <QInputDialog> 0010 #include <QFileDialog> 0011 #include <QDateTime> 0012 #include <QUrl> 0013 0014 #include "MarbleGlobal.h" 0015 #include "MarbleDebug.h" 0016 #include "SatellitesConfigNodeItem.h" 0017 #include "SatellitesConfigLeafItem.h" 0018 #include "SatellitesConfigModel.h" 0019 0020 #include "ui_SatellitesConfigDialog.h" 0021 0022 namespace Marble { 0023 0024 SatellitesConfigDialog::SatellitesConfigDialog( QWidget *parent ) 0025 : QDialog( parent ) 0026 { 0027 initialize(); 0028 0029 // allow translation for catalog items 0030 // + categories 0031 m_translations["Comets"] = tr( "Comets" ); 0032 m_translations["Moons"] = tr( "Moons" ); 0033 m_translations["Other"] = tr( "Other" ); 0034 m_translations["Spacecrafts"] = tr( "Spacecrafts" ); 0035 m_translations["Spaceprobes"] = tr( "Spaceprobes" ); 0036 // + bodies 0037 m_translations["Moon"] = tr( "Moon" ); 0038 m_translations["Sun"] = tr( "Sun" ); 0039 m_translations["Mercury"] = tr( "Mercury" ); 0040 m_translations["Venus"] = tr( "Venus" ); 0041 m_translations["Earth"] = tr( "Earth" ); 0042 m_translations["Mars"] = tr( "Mars" ); 0043 m_translations["Jupiter"] = tr( "Jupiter" ); 0044 m_translations["Saturn"] = tr( "Saturn" ); 0045 m_translations["Uranus"] = tr( "Uranus" ); 0046 m_translations["Neptune"] = tr( "Neptune" ); 0047 } 0048 0049 SatellitesConfigDialog::~SatellitesConfigDialog() 0050 { 0051 } 0052 0053 void SatellitesConfigDialog::setUserDataSources( const QStringList &sources ) 0054 { 0055 m_userDataSources = sources; 0056 0057 // keep the first item 0058 for( int i = m_configWidget->listDataSources->count(); i > 1; --i ) { 0059 delete m_configWidget->listDataSources->takeItem( i-1 ); 0060 } 0061 0062 m_configWidget->listDataSources->addItems( m_userDataSources ); 0063 } 0064 0065 QStringList SatellitesConfigDialog::userDataSources() const 0066 { 0067 return m_userDataSources; 0068 } 0069 0070 void SatellitesConfigDialog::setUserDataSourceLoaded( const QString &source, 0071 bool loaded ) 0072 { 0073 QList<QListWidgetItem*> list; 0074 list = m_configWidget->listDataSources->findItems( source, 0075 Qt::MatchFixedString ); 0076 if( list.count() > 0 ) { 0077 list[0]->setData( IsLoadedRole, QVariant( loaded ) ); 0078 } 0079 0080 QString date( QDateTime::currentDateTime().toString() ); 0081 m_configWidget->labelLastUpdated->setText( date ); 0082 } 0083 0084 void SatellitesConfigDialog::update() 0085 { 0086 expandTreeView(); 0087 0088 QDialog::update(); 0089 } 0090 0091 SatellitesConfigAbstractItem* 0092 SatellitesConfigDialog::addSatelliteItem( const QString &body, 0093 const QString &category, 0094 const QString &title, 0095 const QString &id, 0096 const QString &url ) 0097 { 0098 QString theTitle = translation( title ); 0099 0100 SatellitesConfigNodeItem *categoryItem; 0101 categoryItem = getSatellitesCategoryItem( body, category, true ); 0102 0103 // exists? 0104 for( int i = 0; i < categoryItem->childrenCount(); ++i ) { 0105 SatellitesConfigAbstractItem *absItem = categoryItem->childAt( i ); 0106 if( ( absItem->data( 0, SatellitesConfigAbstractItem::IdListRole ) == id ) ) { 0107 return absItem; 0108 } 0109 } 0110 0111 // add it 0112 SatellitesConfigLeafItem *newItem; 0113 newItem = new SatellitesConfigLeafItem( theTitle, id ); 0114 if( !url.isNull() && !url.isEmpty() ) { 0115 newItem->setData( 0, SatellitesConfigAbstractItem::UrlListRole, url ); 0116 } 0117 categoryItem->appendChild( newItem ); 0118 return newItem; 0119 } 0120 0121 SatellitesConfigAbstractItem* 0122 SatellitesConfigDialog::addTLESatelliteItem( const QString &category, 0123 const QString &title, 0124 const QString &url ) 0125 { 0126 // TLE items always have their id set to their url and 0127 // are always related to the earth 0128 return addSatelliteItem( "Earth", category, title, url, url ); 0129 } 0130 0131 void SatellitesConfigDialog::setDialogActive( bool active ) 0132 { 0133 m_configWidget->tabWidget->clear(); 0134 0135 if( active ) { 0136 m_configWidget->tabWidget->addTab( m_configWidget->tabSatellites, 0137 tr( "&Satellites" ) ); 0138 m_configWidget->tabWidget->addTab( m_configWidget->tabDataSources, 0139 tr( "&Data Sources" ) ); 0140 } else { 0141 m_configWidget->tabWidget->addTab( m_configWidget->tabDisabled, 0142 tr( "&Activate Plugin" ) ); 0143 } 0144 0145 QDialogButtonBox *bBox = m_configWidget->buttonBox; 0146 bBox->button( QDialogButtonBox::Ok )->setEnabled( active ); 0147 bBox->button( QDialogButtonBox::Reset )->setEnabled( active ); 0148 } 0149 0150 Ui::SatellitesConfigDialog* SatellitesConfigDialog::configWidget() 0151 { 0152 return m_configWidget; 0153 } 0154 0155 void SatellitesConfigDialog::initialize() 0156 { 0157 m_configWidget = new Ui::SatellitesConfigDialog(); 0158 m_configWidget->setupUi( this ); 0159 0160 setupDataSourcesTab(); 0161 0162 setDialogActive( false ); 0163 connect( m_configWidget->buttonDisabled, SIGNAL(clicked()), 0164 this, SIGNAL(activatePluginClicked()) ); 0165 0166 update(); 0167 } 0168 0169 void SatellitesConfigDialog::setupDataSourcesTab() 0170 { 0171 connect( m_configWidget->buttonAddDataSource, 0172 SIGNAL(clicked()), SLOT(addDataSource()) ); 0173 connect( m_configWidget->buttonOpenDataSource, 0174 SIGNAL(clicked()), SLOT(openDataSource()) ); 0175 connect( m_configWidget->buttonRemoveDataSource, 0176 SIGNAL(clicked()), SLOT(removeSelectedDataSource()) ); 0177 connect( m_configWidget->buttonReloadDataSources, 0178 SIGNAL(clicked()), SLOT(reloadDataSources()) ); 0179 0180 connect( m_configWidget->listDataSources, 0181 SIGNAL(itemSelectionChanged()), SLOT(updateButtonState()) ); 0182 } 0183 0184 SatellitesConfigNodeItem* SatellitesConfigDialog::getSatellitesCategoryItem( 0185 const QString &body, 0186 const QString &category, 0187 bool create ) 0188 { 0189 QString theCategory = translation( category ); 0190 0191 SatellitesConfigNodeItem *catalogItem; 0192 catalogItem = getSatellitesBodyItem( body, create ); 0193 0194 if( catalogItem == nullptr ) { 0195 return nullptr; 0196 } 0197 0198 // find category 0199 for( int i = 0; i < catalogItem->childrenCount(); ++i ) { 0200 if( catalogItem->childAt( i )->name() == theCategory ) { 0201 return dynamic_cast<SatellitesConfigNodeItem*>(catalogItem->childAt( i ) ); 0202 } 0203 } 0204 0205 // not found, create? 0206 if( create ) { 0207 SatellitesConfigNodeItem *newItem; 0208 newItem = new SatellitesConfigNodeItem( theCategory ); 0209 catalogItem->appendChild( newItem ); 0210 return newItem; 0211 } 0212 0213 return nullptr; // not found, not created 0214 } 0215 0216 SatellitesConfigNodeItem* SatellitesConfigDialog::getSatellitesBodyItem( 0217 const QString &body, 0218 bool create ) 0219 { 0220 QString theBody = translation( body ); 0221 0222 SatellitesConfigModel *model = dynamic_cast<SatellitesConfigModel*>( m_configWidget->treeView->model() ); 0223 SatellitesConfigNodeItem *rootItem = model->rootItem(); 0224 0225 // try to find it 0226 for( int i = 0; i < rootItem->childrenCount(); ++i ) { 0227 if( rootItem->childAt( i )->name() == theBody ) { 0228 return dynamic_cast<SatellitesConfigNodeItem*>(rootItem->childAt( i ) ); 0229 } 0230 } 0231 0232 // not found, create? 0233 if( create ) { 0234 SatellitesConfigNodeItem *newItem; 0235 newItem = new SatellitesConfigNodeItem( theBody ); 0236 rootItem->appendChild( newItem ); 0237 return newItem; 0238 } 0239 0240 return nullptr; // not found, not created 0241 } 0242 0243 void SatellitesConfigDialog::reloadDataSources() 0244 { 0245 emit dataSourcesReloadRequested(); 0246 } 0247 0248 void SatellitesConfigDialog::addDataSource() 0249 { 0250 QListWidget *list = m_configWidget->listDataSources; 0251 0252 bool ok; 0253 QString text = QInputDialog::getText( this, 0254 tr("Add Data Source"), 0255 tr("URL or File path:"), 0256 QLineEdit::Normal, 0257 "", &ok); 0258 0259 if( ok && !text.isEmpty() ) { 0260 QUrl url = QUrl::fromUserInput( text ); 0261 if( !url.isValid() ) { 0262 mDebug() << "Invalid data source input:" << text; 0263 QMessageBox::critical( this, 0264 tr( "Invalid data source input" ), 0265 tr( "Please enter a valid URL or file path!" ), 0266 QMessageBox::Cancel ); 0267 return; 0268 } 0269 0270 // add item 0271 QListWidgetItem *item = new QListWidgetItem( url.toString(), list ); 0272 item->setFlags( Qt::ItemIsSelectable | 0273 Qt::ItemIsEnabled ); 0274 item->setData( IsLoadedRole, QVariant( false ) ); 0275 0276 mDebug() << "Added satellite data source:" << item->text(); 0277 m_userDataSources << item->text(); 0278 0279 emit userDataSourceAdded( item->text() ); 0280 emit userDataSourcesChanged(); 0281 } 0282 } 0283 0284 void SatellitesConfigDialog::openDataSource() 0285 { 0286 QListWidget *list = m_configWidget->listDataSources; 0287 0288 const QString filter = QString("%1;;%2;;%3").arg( 0289 tr( "All Supported Files (*.txt *.msc)" ), 0290 tr( "Marble Satellite Catalog (*.msc)" ), 0291 tr( "Two Line Element Set (*.txt)" ), 0292 tr( "All Files (*.*)" ) ); 0293 0294 QString filename = QFileDialog::getOpenFileName( this, 0295 tr( "Open Satellite Data File" ), "", filter ); 0296 0297 if( !filename.isNull() ) { 0298 QString url = QUrl::fromLocalFile( filename ).toString(); 0299 0300 if( m_configWidget->listDataSources->findItems( 0301 url, Qt::MatchFixedString ).size() > 0 ) { 0302 mDebug() << "Satellite data source exists:" << url; 0303 return; // already in list 0304 } 0305 0306 QListWidgetItem *item = new QListWidgetItem( url, list ); 0307 item->setFlags( Qt::ItemIsSelectable | 0308 Qt::ItemIsEnabled ); 0309 item->setData( IsLoadedRole, QVariant( false ) ); 0310 0311 mDebug() << "Added satellite data source:" << url; 0312 m_userDataSources << url; 0313 0314 emit userDataSourceAdded( url ); 0315 emit userDataSourcesChanged(); 0316 } 0317 0318 } 0319 0320 void SatellitesConfigDialog::removeSelectedDataSource() 0321 { 0322 int row = m_configWidget->listDataSources->currentRow(); 0323 if( row >= 0 && 0324 QMessageBox::question( this, 0325 tr( "Delete selected data source" ), 0326 tr( "Do you really want to delete the selected data source?" ), 0327 QMessageBox::Yes | QMessageBox::No, 0328 QMessageBox::No ) == QMessageBox::Yes ) { 0329 0330 QListWidgetItem *item; 0331 item = m_configWidget->listDataSources->takeItem( row ); 0332 QString source = item->text(); 0333 0334 mDebug() << "Removing satellite data source:" << source; 0335 m_userDataSources.removeAll( source ); 0336 emit userDataSourceRemoved( source ); 0337 0338 delete item; 0339 0340 emit userDataSourcesChanged(); 0341 } 0342 } 0343 0344 void SatellitesConfigDialog::updateButtonState() 0345 { 0346 m_configWidget->buttonRemoveDataSource->setEnabled( 0347 ( m_configWidget->listDataSources->currentIndex().row() >= 0 ) ); 0348 } 0349 0350 void SatellitesConfigDialog::expandTreeView() 0351 { 0352 QTreeView *treeView = m_configWidget->treeView; 0353 0354 if( !treeView->model() ) { 0355 return; 0356 } 0357 0358 // expand only branches with selected items 0359 treeView->expandAll(); 0360 0361 for ( int i = 0; i < treeView->model()->columnCount(); ++i ) { 0362 treeView->resizeColumnToContents( i ); 0363 } 0364 } 0365 0366 QString SatellitesConfigDialog::translation( const QString &from ) const 0367 { 0368 if( m_translations.contains( from ) ) { 0369 return m_translations.value( from ); 0370 } 0371 0372 return from; 0373 } 0374 0375 } // namespace Marble 0376 0377 #include "moc_SatellitesConfigDialog.cpp" 0378