Kstars

flagmanager.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Jerome SONRIER <jsid@emor3j.fr.eu.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "flagmanager.h"
8
9#include "config-kstars.h"
10
11#include "kspaths.h"
12#include "ksnotification.h"
13#include "kstars.h"
14#include "kstars_debug.h"
15#include "kstarsdata.h"
16#include "Options.h"
17#include "skymap.h"
18#include "skycomponents/flagcomponent.h"
19#include "skycomponents/skymapcomposite.h"
20
21#ifdef HAVE_INDI
22#include <basedevice.h>
23#include "indi/indilistener.h"
24#include "indi/indistd.h"
25#include "indi/indimount.h"
26#include "indi/driverinfo.h"
27#endif
28
29#include <KMessageBox>
30
31#include <QStandardItemModel>
32#include <QSortFilterProxyModel>
33
34FlagManagerUI::FlagManagerUI(QWidget *p) : QFrame(p)
35{
36 setupUi(this);
37}
38
39FlagManager::FlagManager(QWidget *ks) : QDialog(ks)
40{
41#ifdef Q_OS_MACOS
42 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
43#endif
45 QList<QImage> imageList;
46 QStringList flagNames;
47 int i;
48
49 ui = new FlagManagerUI(this);
50
51 setWindowTitle(i18nc("@title:window", "Flag Manager"));
52
53 QVBoxLayout *mainLayout = new QVBoxLayout;
54 mainLayout->addWidget(ui);
55 setLayout(mainLayout);
56
58 mainLayout->addWidget(buttonBox);
59 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
60
61 m_Ks = KStars::Instance();
62
63 ui->hintLabel->setText(i18n("To add custom icons, just add images in %1. File names must begin with flag. "
64 "For example, the file <i>flagSmall_red_cross.png</i> will be shown as <b>Small red "
65 "cross</b> in the combo box.",
66 KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)));
67 //Set up the Table Views
68 m_Model = new QStandardItemModel(0, 5, this);
69 m_Model->setHorizontalHeaderLabels(QStringList() << i18nc("Right Ascension", "RA") << i18nc("Declination", "Dec")
70 << i18n("Epoch") << i18n("Icon") << i18n("Label"));
71 m_SortModel = new QSortFilterProxyModel(this);
72 m_SortModel->setSourceModel(m_Model);
73 m_SortModel->setDynamicSortFilter(true);
74 ui->flagList->setModel(m_SortModel);
75 ui->flagList->horizontalHeader()->setStretchLastSection(true);
76
77 ui->flagList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
78
79 ui->saveButton->setEnabled(false);
80
81 ui->raBox->setUnits(dmsBox::HOURS);
82
83 //Fill the list
84 imageList = m_Ks->data()->skyComposite()->flags()->imageList();
85 flagNames = m_Ks->data()->skyComposite()->flags()->getNames();
86
87 FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
88 QPixmap pixmap;
89
90 for (i = 0; i < m_Ks->data()->skyComposite()->flags()->size(); ++i)
91 {
92 QStandardItem *labelItem = new QStandardItem(flags->label(i));
93 labelItem->setForeground(QBrush(flags->labelColor(i)));
94
95 itemList << new QStandardItem(flags->pointList().at(i)->ra0().toHMSString())
96 << new QStandardItem(flags->pointList().at(i)->dec0().toDMSString())
97 << new QStandardItem(flags->epoch(i))
98 << new QStandardItem(QIcon(pixmap.fromImage(flags->image(i))), flags->imageName(i)) << labelItem;
99 m_Model->appendRow(itemList);
100 itemList.clear();
101 }
102
103 //Fill the combobox
104 for (i = 0; i < imageList.size(); ++i)
105 {
106 ui->flagCombobox->addItem(QIcon(pixmap.fromImage(flags->imageList(i))), flagNames.at(i), flagNames.at(i));
107 }
108 if (imageList.size() >= 2 && ui->flagCombobox->currentIndex() == 0)
109 ui->flagCombobox->setCurrentIndex(1);
110
111 //Connect buttons
112 connect(ui->addButton, SIGNAL(clicked()), this, SLOT(slotAddFlag()));
113 connect(ui->delButton, SIGNAL(clicked()), this, SLOT(slotDeleteFlag()));
114 connect(ui->CenterButton, SIGNAL(clicked()), this, SLOT(slotCenterFlag()));
115 connect(ui->ScopeButton, SIGNAL(clicked()), this, SLOT(slotCenterTelescope()));
116 connect(ui->flagList, SIGNAL(clicked(QModelIndex)), this, SLOT(slotSetShownFlag(QModelIndex)));
117 connect(ui->flagList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotCenterFlag()));
118
119 connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(slotSaveChanges()));
120}
121
122void FlagManager::setRaDec(const dms &ra, const dms &dec)
123{
124 ui->raBox->show(ra);
125 ui->decBox->show(dec);
126}
127
128void FlagManager::clearFields()
129{
130 ui->raBox->clear();
131 ui->decBox->clear();
132
133 ui->epochBox->setText("2000.0");
134 ui->flagLabel->clear();
135 ui->flagLabel->setFocus();
136
137 //disable "Save Changes" button
138 ui->saveButton->setEnabled(false);
139
140 //unselect item from flagList
141 ui->flagList->clearSelection();
142}
143
144void FlagManager::showFlag(int flagIdx)
145{
146 if (flagIdx < 0 || flagIdx >= m_Model->rowCount())
147 {
148 return;
149 }
150
151 else
152 {
153 ui->raBox->setText(m_Model->data(m_Model->index(flagIdx, 0)).toString());
154 ui->decBox->setText(m_Model->data(m_Model->index(flagIdx, 1)).toString());
155 ui->epochBox->setText(m_Model->data(m_Model->index(flagIdx, 2)).toString());
156
157 //ui->flagCombobox->setCurrentItem( m_Model->data( m_Model->index( flagIdx, 3) ).toString() );
158 ui->flagCombobox->setCurrentText(m_Model->data(m_Model->index(flagIdx, 3)).toString());
159 ui->flagLabel->setText(m_Model->data(m_Model->index(flagIdx, 4)).toString());
160
161 QColor labelColor = m_Model->item(flagIdx, 4)->foreground().color();
162 ui->labelColorcombo->setColor(labelColor);
163 }
164
165 ui->flagList->selectRow(flagIdx);
166 ui->saveButton->setEnabled(true);
167}
168
169bool FlagManager::validatePoint()
170{
171 bool raOk(false), decOk(false);
172 dms ra(ui->raBox->createDms(&raOk));
173 dms dec(ui->decBox->createDms(&decOk));
174
175 QString message;
176
177 //check if ra & dec values were successfully converted
178 if (!raOk || !decOk)
179 {
180 KSNotification::error(i18n("Invalid coordinates."));
181 return false;
182 }
183
184 //make sure values are in valid range
185 if (ra.Hours() < 0.0 || ra.Degrees() > 360.0)
186 message = i18n("The Right Ascension value must be between 0.0 and 24.0.");
187 if (dec.Degrees() < -90.0 || dec.Degrees() > 90.0)
188 message += '\n' + i18n("The Declination value must be between -90.0 and 90.0.");
189 if (!message.isEmpty())
190 {
191 KSNotification::sorry(message, i18n("Invalid Coordinate Data"));
192 return false;
193 }
194
195 //all checks passed
196 return true;
197}
198
199void FlagManager::deleteFlagItem(int flagIdx)
200{
201 if (flagIdx < m_Model->rowCount())
202 {
203 m_Model->removeRow(flagIdx);
204 }
205}
206
208{
209 if (validatePoint() == false)
210 return;
211
212 dms ra(ui->raBox->createDms());
213 dms dec(ui->decBox->createDms());
214
215 insertFlag(true);
216
217 FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
218 //Add flag in FlagComponent
219 SkyPoint flagPoint(ra, dec);
220 flags->add(flagPoint, ui->epochBox->text(), ui->flagCombobox->currentText(), ui->flagLabel->text(),
221 ui->labelColorcombo->color());
222
223 ui->flagList->selectRow(m_Model->rowCount() - 1);
224 ui->saveButton->setEnabled(true);
225
226 flags->saveToFile();
227
228 //Redraw map
229 m_Ks->map()->forceUpdate(false);
230}
231
233{
234 int flag = ui->flagList->currentIndex().row();
235
236 //Remove from FlagComponent
237 m_Ks->data()->skyComposite()->flags()->remove(flag);
238
239 //Remove from list
240 m_Model->removeRow(flag);
241
242 //Clear form fields
243 clearFields();
244
245 //Remove from file
246 m_Ks->data()->skyComposite()->flags()->saveToFile();
247
248 //Redraw map
249 m_Ks->map()->forceUpdate(false);
250}
251
253{
254 if (ui->flagList->currentIndex().isValid())
255 {
256 m_Ks->map()->setClickedObject(nullptr);
257 m_Ks->map()->setClickedPoint(
258 m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
259 m_Ks->map()->slotCenter();
260 }
261}
262
264{
265#ifdef HAVE_INDI
266
267 if (INDIListener::Instance()->size() == 0)
268 {
269 KSNotification::sorry(i18n("No connected mounts found."));
270 return;
271 }
272
273 for (auto oneDevice : INDIListener::devices())
274 {
275 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
276 continue;
277
278 if (oneDevice->isConnected() == false)
279 {
280 KSNotification::error(
281 i18n("Telescope %1 is offline. Please connect and retry again.", oneDevice->getDeviceName()));
282 return;
283 }
284
285 auto mount = oneDevice->getMount();
286 if (!mount)
287 continue;
288
289 mount->Slew(m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
290
291 return;
292 }
293
294 KSNotification::sorry(i18n("No connected mounts found."));
295
296#endif
297}
298
299void FlagManager::slotSaveChanges()
300{
301 int row = ui->flagList->currentIndex().row();
302
303 if (validatePoint() == false)
304 return;
305
306 insertFlag(false, row);
307
308 m_Ks->map()->forceUpdate();
309
310 dms ra(ui->raBox->createDms());
311 dms dec(ui->decBox->createDms());
312
313 SkyPoint flagPoint(ra, dec);
314
315 //Update FlagComponent
316 m_Ks->data()->skyComposite()->flags()->updateFlag(row, flagPoint, ui->epochBox->text(),
317 ui->flagCombobox->currentText(), ui->flagLabel->text(),
318 ui->labelColorcombo->color());
319
320 //Save changes to file
321 m_Ks->data()->skyComposite()->flags()->saveToFile();
322
323 ui->flagList->selectRow(row);
324}
325
326void FlagManager::slotSetShownFlag(QModelIndex idx)
327{
328 showFlag(idx.row());
329}
330
331void FlagManager::insertFlag(bool isNew, int row)
332{
333 dms ra(ui->raBox->createDms());
334 dms dec(ui->decBox->createDms());
335 SkyPoint flagPoint(ra, dec);
336
337 // Add flag in the list
338 QList<QStandardItem *> itemList;
339
340 QStandardItem *labelItem = new QStandardItem(ui->flagLabel->text());
341 labelItem->setForeground(QBrush(ui->labelColorcombo->color()));
342
343 FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
344
345 QPixmap pixmap;
346 itemList << new QStandardItem(flagPoint.ra0().toHMSString()) << new QStandardItem(flagPoint.dec0().toDMSString())
347 << new QStandardItem(ui->epochBox->text())
348 << new QStandardItem(QIcon(pixmap.fromImage(flags->imageList(ui->flagCombobox->currentIndex()))),
349 ui->flagCombobox->currentText())
350 << labelItem;
351
352 if (isNew)
353 {
354 m_Model->appendRow(itemList);
355 }
356
357 else
358 {
359 for (int i = 0; i < m_Model->columnCount(); i++)
360 {
361 m_Model->setItem(row, i, itemList.at(i));
362 }
363 }
364}
Represents a flag on the sky map.
void saveToFile()
Save flags to flags.dat file.
QColor labelColor(int index)
Get label color.
void remove(int index)
Remove a flag.
QList< QImage > imageList()
Get images.
QString label(int index)
Get label.
void add(const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Add a flag.
QString epoch(int index)
Get epoch.
QString imageName(int index)
Get image name.
void updateFlag(int index, const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Update a flag.
QImage image(int index)
Get image.
void slotCenterTelescope()
Center the selected flag in the telescope.
void slotCenterFlag()
Center the selected flag in the display.
void slotAddFlag()
Verify coordinates and add a flag.
void slotDeleteFlag()
Delete a flag.
SkyMapComposite * skyComposite()
Definition kstarsdata.h:168
SkyMap * map() const
Definition kstars.h:139
static KStars * Instance()
Definition kstars.h:121
KStarsData * data() const
Definition kstars.h:133
void setClickedPoint(const SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition skymap.cpp:1021
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition skymap.cpp:366
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition skymap.cpp:1186
void slotCenter()
Center the display at the point ClickedPoint.
Definition skymap.cpp:380
The sky coordinates of a point in the sky.
Definition skypoint.h:45
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
double Hours() const
Definition dms.h:168
const double & Degrees() const
Definition dms.h:141
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
bool removeRow(int row, const QModelIndex &parent)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
const QColor & color() const const
const_reference at(qsizetype i) const const
void clear()
pointer data()
qsizetype size() const const
int row() const const
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
void appendRow(QStandardItem *item)
QBrush foreground() const const
void setForeground(const QBrush &brush)
void appendRow(QStandardItem *item)
virtual int columnCount(const QModelIndex &parent) const const override
virtual QVariant data(const QModelIndex &index, int role) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
QStandardItem * item(int row, int column) const const
virtual int rowCount(const QModelIndex &parent) const const override
void setItem(int row, QStandardItem *item)
bool isEmpty() const const
QTextStream & dec(QTextStream &stream)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const
void setEnabled(bool)
void setFocus()
void show()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:47 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.