Kstars

opships.cpp
1/*
2 SPDX-FileCopyrightText: 2017 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7
8#include "opships.h"
9
10#include "kstars.h"
11#include "hipsmanager.h"
12#include "Options.h"
13#include "skymap.h"
14#include "auxiliary/ksnotification.h"
15#include "auxiliary/filedownloader.h"
16#include "auxiliary/kspaths.h"
17
18#include <KConfigDialog>
19
20#include <QCheckBox>
21#include <QComboBox>
22#include <QFileDialog>
23#include <QPushButton>
24#include <QStringList>
25
26// Qt version calming
27#include <qtkeepemptyparts.h>
28
29static const QStringList hipsKeys = { "ID", "obs_title", "obs_description", "hips_order", "hips_frame", "hips_tile_width", "hips_tile_format", "hips_service_url", "moc_sky_fraction"};
30
31OpsHIPSDisplay::OpsHIPSDisplay() : QFrame(KStars::Instance())
32{
33 setupUi(this);
34}
35
36OpsHIPSCache::OpsHIPSCache() : QFrame(KStars::Instance())
37{
38 setupUi(this);
39
40 connect(selectDirectoryB, &QPushButton::clicked, this, [this]()
41 {
42 QString dir = QFileDialog::getExistingDirectory(this, i18nc("@title:window", "HiPS Offline Storage"),
43 kcfg_HIPSOfflinePath->text());
44
45 if (dir.isEmpty())
46 return;
47
48 kcfg_HIPSOfflinePath->setText(dir);
49
50 QDir hipsDirectory(dir);
51 auto orders = hipsDirectory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
52 HIPSManager::Instance()->setOfflineLevels(orders);
53 HIPSManager::Instance()->setCurrentSource("DSS Colored");
54 });
55}
56
57OpsHIPS::OpsHIPS() : QFrame(KStars::Instance())
58{
59 setupUi(this);
60
61 //Get a pointer to the KConfigDialog
62 m_ConfigDialog = KConfigDialog::exists("hipssettings");
63
65 QLatin1String("hips_previews/"));
66 QDir dir;
67 dir.mkpath(path);
68
69 connect(refreshSourceB, SIGNAL(clicked()), this, SLOT(slotRefresh()));
70
71 connect(sourcesList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotItemUpdated(QListWidgetItem*)));
72 connect(sourcesList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotItemClicked(QListWidgetItem*)));
73
74 if (sourcesList->count() == 0)
75 slotRefresh();
76}
77
78void OpsHIPS::slotRefresh()
79{
80 downloadJob = new FileDownloader();
81
82 downloadJob->setProgressDialogEnabled(true, i18n("HiPS Update"), i18n("Downloading HiPS sources..."));
83
84 QObject::connect(downloadJob, SIGNAL(downloaded()), this, SLOT(downloadReady()));
85 QObject::connect(downloadJob, SIGNAL(error(QString)), this, SLOT(downloadError(QString)));
86
87 downloadJob->get(
88 QUrl("http://alasky.unistra.fr/MocServer/query?hips_service_url=*&dataproduct_type=!catalog&dataproduct_type=!cube&&moc_sky_fraction=1&get=record"));
89}
90
91void OpsHIPS::downloadReady()
92{
93 sources.clear();
94
95 QTextStream stream(downloadJob->downloadedData());
96
97 QStringList hipsTitles;
98
99 QMap<QString, QString> oneSource;
100 while (stream.atEnd() == false)
101 {
102 QString line = stream.readLine();
103 if (line.isEmpty())
104 {
105 sources.append(oneSource);
106 oneSource.clear();
107 continue;
108 }
109
110 QStringList keyvalue = line.split('=', Qt::KeepEmptyParts);
111 QString key = keyvalue[0].simplified();
112 if (hipsKeys.contains(key) == false)
113 continue;
114 QString value = keyvalue[1].simplified();
115 oneSource[key] = value;
116 if (key == "obs_title")
117 hipsTitles << value;
118 }
119
120 // Get existing database sources
122 KStarsData::Instance()->userdb()->GetAllHIPSSources(dbSources);
123
124 // Get existing database titles
125 QStringList dbTitles;
126 for (QMap<QString, QString> oneSource : dbSources)
127 dbTitles << oneSource["obs_title"];
128
129 // Add all titles to list widget
130 sourcesList->addItems(hipsTitles);
131 QListWidgetItem* item = nullptr;
132
133 // Make sources checkable and check sources that already exist in the database
134 sourcesList->blockSignals(true);
135 for(int i = 0; i < sourcesList->count(); ++i)
136 {
137 item = sourcesList->item(i);
138 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
139 item->setCheckState(dbTitles.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
140
141 if (item->text() == Options::hIPSSource())
142 {
143 item->setSelected(true);
144 sourcesList->scrollToItem(item);
145 slotItemClicked(item);
146 }
147 }
148 sourcesList->blockSignals(false);
149
150 // Delete job later
151 downloadJob->deleteLater();
152}
153
154void OpsHIPS::downloadError(const QString &errorString)
155{
156 KSNotification::error(i18n("Error downloading HiPS sources: %1", errorString));
157 downloadJob->deleteLater();
158}
159
160void OpsHIPS::slotItemUpdated(QListWidgetItem *item)
161{
162 for(QMap<QString, QString> &oneSource : sources)
163 {
164 if (oneSource.value("obs_title") == item->text())
165 {
166 if (item->checkState() == Qt::Checked)
167 KStarsData::Instance()->userdb()->AddHIPSSource(oneSource);
168 else
169 KStarsData::Instance()->userdb()->DeleteHIPSSource(oneSource.value("ID"));
170 break;
171 }
172 }
173}
174
175void OpsHIPS::slotItemClicked(QListWidgetItem *item)
176{
177 for(QMap<QString, QString> &oneSource : sources)
178 {
179 if (oneSource.value("obs_title") == item->text())
180 {
181 sourceDescription->setText(oneSource.value("obs_description"));
182 // Get stored preview, if not found, it will be downloaded.
183 setPreview(oneSource.value("ID"), oneSource.value("hips_service_url"));
184 break;
185 }
186 }
187}
188
189void OpsHIPS::setPreview(const QString &id, const QString &url)
190{
191 uint hash = qHash(id);
192 QString previewName = QString("%1.jpg").arg(hash);
193
194 QString currentPreviewPath = QDir(KSPaths::locate(QStandardPaths::AppLocalDataLocation,
195 QLatin1String("hips_previews"))).filePath(previewName);
196 if (currentPreviewPath.isEmpty() == false)
197 {
198 sourceImage->setPixmap(QPixmap(currentPreviewPath));
199 }
200 else
201 {
202 currentPreviewPath = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath(
203 QLatin1String("hips_previews/") + previewName);
204
205 previewJob = new FileDownloader();
206 connect(previewJob, SIGNAL(downloaded()), this, SLOT(previewReady()));
207
208 previewJob->setDownloadedFileURL(QUrl::fromLocalFile(currentPreviewPath));
209
210 previewJob->get(QUrl(url + QLatin1String("/preview.jpg")));
211 }
212}
213
214void OpsHIPS::previewReady()
215{
216 QString previewFile = previewJob->getDownloadedFileURL().toLocalFile();
217 QFileInfo previewInfo(previewFile);
218 // If less than 1kb then it's junk
219 if (previewInfo.size() < 1024)
220 {
221 sourceImage->setPixmap(QPixmap(":/images/noimage.png"));
222 QFile::remove(previewFile);
223 }
224 else
225 sourceImage->setPixmap(QPixmap(previewFile));
226}
227
static KConfigDialog * exists(const QString &name)
KSUserDB * userdb()
Definition kstarsdata.h:217
This is the main window for KStars.
Definition kstars.h:89
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString path(const QString &relativePath)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KIOCORE_EXPORT QString dir(const QString &fileClass)
KTEXTEDITOR_EXPORT size_t qHash(KTextEditor::Cursor cursor, size_t seed=0) noexcept
void clicked(bool checked)
QString filePath(const QString &fileName) const const
bool remove()
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
void append(QList< T > &&value)
void clear()
Qt::CheckState checkState() const const
Qt::ItemFlags flags() const const
void setCheckState(Qt::CheckState state)
void setFlags(Qt::ItemFlags flags)
void setSelected(bool select)
QString text() const const
void clear()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString arg(Args &&... args) const const
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
ItemIsUserCheckable
KeepEmptyParts
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:41 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.