File indexing completed on 2024-04-21 03:43:59
0001 /* 0002 SPDX-FileCopyrightText: 2017 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 0008 #include "opships.h" 0009 0010 #include "kstars.h" 0011 #include "hipsmanager.h" 0012 #include "Options.h" 0013 #include "skymap.h" 0014 #include "auxiliary/ksnotification.h" 0015 #include "auxiliary/filedownloader.h" 0016 #include "auxiliary/kspaths.h" 0017 0018 #include <KConfigDialog> 0019 0020 #include <QCheckBox> 0021 #include <QComboBox> 0022 #include <QFileDialog> 0023 #include <QPushButton> 0024 #include <QStringList> 0025 0026 // Qt version calming 0027 #include <qtkeepemptyparts.h> 0028 0029 static const QStringList hipsKeys = { "ID", "obs_title", "obs_description", "hips_order", "hips_frame", "hips_tile_width", "hips_tile_format", "hips_service_url", "moc_sky_fraction"}; 0030 0031 OpsHIPSDisplay::OpsHIPSDisplay() : QFrame(KStars::Instance()) 0032 { 0033 setupUi(this); 0034 } 0035 0036 OpsHIPSCache::OpsHIPSCache() : QFrame(KStars::Instance()) 0037 { 0038 setupUi(this); 0039 0040 connect(selectDirectoryB, &QPushButton::clicked, this, [this]() 0041 { 0042 QString dir = QFileDialog::getExistingDirectory(this, i18nc("@title:window", "HiPS Offline Storage"), 0043 kcfg_HIPSOfflinePath->text()); 0044 0045 if (dir.isEmpty()) 0046 return; 0047 0048 kcfg_HIPSOfflinePath->setText(dir); 0049 0050 QDir hipsDirectory(dir); 0051 auto orders = hipsDirectory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); 0052 HIPSManager::Instance()->setOfflineLevels(orders); 0053 HIPSManager::Instance()->setCurrentSource("DSS Colored"); 0054 }); 0055 } 0056 0057 OpsHIPS::OpsHIPS() : QFrame(KStars::Instance()) 0058 { 0059 setupUi(this); 0060 0061 //Get a pointer to the KConfigDialog 0062 m_ConfigDialog = KConfigDialog::exists("hipssettings"); 0063 0064 QString path = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath( 0065 QLatin1String("hips_previews/")); 0066 QDir dir; 0067 dir.mkpath(path); 0068 0069 connect(refreshSourceB, SIGNAL(clicked()), this, SLOT(slotRefresh())); 0070 0071 connect(sourcesList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotItemUpdated(QListWidgetItem*))); 0072 connect(sourcesList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotItemClicked(QListWidgetItem*))); 0073 0074 if (sourcesList->count() == 0) 0075 slotRefresh(); 0076 } 0077 0078 void OpsHIPS::slotRefresh() 0079 { 0080 downloadJob = new FileDownloader(); 0081 0082 downloadJob->setProgressDialogEnabled(true, i18n("HiPS Update"), i18n("Downloading HiPS sources...")); 0083 0084 QObject::connect(downloadJob, SIGNAL(downloaded()), this, SLOT(downloadReady())); 0085 QObject::connect(downloadJob, SIGNAL(error(QString)), this, SLOT(downloadError(QString))); 0086 0087 downloadJob->get( 0088 QUrl("http://alasky.unistra.fr/MocServer/query?hips_service_url=*&dataproduct_type=!catalog&dataproduct_type=!cube&&moc_sky_fraction=1&get=record")); 0089 } 0090 0091 void OpsHIPS::downloadReady() 0092 { 0093 sources.clear(); 0094 0095 QTextStream stream(downloadJob->downloadedData()); 0096 0097 QStringList hipsTitles; 0098 0099 QMap<QString, QString> oneSource; 0100 while (stream.atEnd() == false) 0101 { 0102 QString line = stream.readLine(); 0103 if (line.isEmpty()) 0104 { 0105 sources.append(oneSource); 0106 oneSource.clear(); 0107 continue; 0108 } 0109 0110 QStringList keyvalue = line.split('=', Qt::KeepEmptyParts); 0111 QString key = keyvalue[0].simplified(); 0112 if (hipsKeys.contains(key) == false) 0113 continue; 0114 QString value = keyvalue[1].simplified(); 0115 oneSource[key] = value; 0116 if (key == "obs_title") 0117 hipsTitles << value; 0118 } 0119 0120 // Get existing database sources 0121 QList<QMap<QString, QString>> dbSources; 0122 KStarsData::Instance()->userdb()->GetAllHIPSSources(dbSources); 0123 0124 // Get existing database titles 0125 QStringList dbTitles; 0126 for (QMap<QString, QString> oneSource : dbSources) 0127 dbTitles << oneSource["obs_title"]; 0128 0129 // Add all titles to list widget 0130 sourcesList->addItems(hipsTitles); 0131 QListWidgetItem* item = nullptr; 0132 0133 // Make sources checkable and check sources that already exist in the database 0134 sourcesList->blockSignals(true); 0135 for(int i = 0; i < sourcesList->count(); ++i) 0136 { 0137 item = sourcesList->item(i); 0138 item->setFlags(item->flags() | Qt::ItemIsUserCheckable); 0139 item->setCheckState(dbTitles.contains(item->text()) ? Qt::Checked : Qt::Unchecked); 0140 0141 if (item->text() == Options::hIPSSource()) 0142 { 0143 item->setSelected(true); 0144 sourcesList->scrollToItem(item); 0145 slotItemClicked(item); 0146 } 0147 } 0148 sourcesList->blockSignals(false); 0149 0150 // Delete job later 0151 downloadJob->deleteLater(); 0152 } 0153 0154 void OpsHIPS::downloadError(const QString &errorString) 0155 { 0156 KSNotification::error(i18n("Error downloading HiPS sources: %1", errorString)); 0157 downloadJob->deleteLater(); 0158 } 0159 0160 void OpsHIPS::slotItemUpdated(QListWidgetItem *item) 0161 { 0162 for(QMap<QString, QString> &oneSource : sources) 0163 { 0164 if (oneSource.value("obs_title") == item->text()) 0165 { 0166 if (item->checkState() == Qt::Checked) 0167 KStarsData::Instance()->userdb()->AddHIPSSource(oneSource); 0168 else 0169 KStarsData::Instance()->userdb()->DeleteHIPSSource(oneSource.value("ID")); 0170 break; 0171 } 0172 } 0173 } 0174 0175 void OpsHIPS::slotItemClicked(QListWidgetItem *item) 0176 { 0177 for(QMap<QString, QString> &oneSource : sources) 0178 { 0179 if (oneSource.value("obs_title") == item->text()) 0180 { 0181 sourceDescription->setText(oneSource.value("obs_description")); 0182 // Get stored preview, if not found, it will be downloaded. 0183 setPreview(oneSource.value("ID"), oneSource.value("hips_service_url")); 0184 break; 0185 } 0186 } 0187 } 0188 0189 void OpsHIPS::setPreview(const QString &id, const QString &url) 0190 { 0191 uint hash = qHash(id); 0192 QString previewName = QString("%1.jpg").arg(hash); 0193 0194 QString currentPreviewPath = QDir(KSPaths::locate(QStandardPaths::AppLocalDataLocation, 0195 QLatin1String("hips_previews"))).filePath(previewName); 0196 if (currentPreviewPath.isEmpty() == false) 0197 { 0198 sourceImage->setPixmap(QPixmap(currentPreviewPath)); 0199 } 0200 else 0201 { 0202 currentPreviewPath = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath( 0203 QLatin1String("hips_previews/") + previewName); 0204 0205 previewJob = new FileDownloader(); 0206 connect(previewJob, SIGNAL(downloaded()), this, SLOT(previewReady())); 0207 0208 previewJob->setDownloadedFileURL(QUrl::fromLocalFile(currentPreviewPath)); 0209 0210 previewJob->get(QUrl(url + QLatin1String("/preview.jpg"))); 0211 } 0212 } 0213 0214 void OpsHIPS::previewReady() 0215 { 0216 QString previewFile = previewJob->getDownloadedFileURL().toLocalFile(); 0217 QFileInfo previewInfo(previewFile); 0218 // If less than 1kb then it's junk 0219 if (previewInfo.size() < 1024) 0220 { 0221 sourceImage->setPixmap(QPixmap(":/images/noimage.png")); 0222 QFile::remove(previewFile); 0223 } 0224 else 0225 sourceImage->setPixmap(QPixmap(previewFile)); 0226 } 0227