Kstars

flagmanager.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Jerome SONRIER <[email protected]>
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 
34 FlagManagerUI::FlagManagerUI(QWidget *p) : QFrame(p)
35 {
36  setupUi(this);
37 }
38 
39 FlagManager::FlagManager(QWidget *ks) : QDialog(ks)
40 {
41 #ifdef Q_OS_OSX
42  setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
43 #endif
44  QList<QStandardItem *> itemList;
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  //Fill the list
82  imageList = m_Ks->data()->skyComposite()->flags()->imageList();
83  flagNames = m_Ks->data()->skyComposite()->flags()->getNames();
84 
85  FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
86  QPixmap pixmap;
87 
88  for (i = 0; i < m_Ks->data()->skyComposite()->flags()->size(); ++i)
89  {
90  QStandardItem *labelItem = new QStandardItem(flags->label(i));
91  labelItem->setForeground(QBrush(flags->labelColor(i)));
92 
93  itemList << new QStandardItem(flags->pointList().at(i)->ra0().toHMSString())
94  << new QStandardItem(flags->pointList().at(i)->dec0().toDMSString())
95  << new QStandardItem(flags->epoch(i))
96  << new QStandardItem(QIcon(pixmap.fromImage(flags->image(i))), flags->imageName(i)) << labelItem;
97  m_Model->appendRow(itemList);
98  itemList.clear();
99  }
100 
101  //Fill the combobox
102  for (i = 0; i < imageList.size(); ++i)
103  {
104  ui->flagCombobox->addItem(QIcon(pixmap.fromImage(flags->imageList(i))), flagNames.at(i), flagNames.at(i));
105  }
106 
107  //Connect buttons
108  connect(ui->addButton, SIGNAL(clicked()), this, SLOT(slotAddFlag()));
109  connect(ui->delButton, SIGNAL(clicked()), this, SLOT(slotDeleteFlag()));
110  connect(ui->CenterButton, SIGNAL(clicked()), this, SLOT(slotCenterFlag()));
111  connect(ui->ScopeButton, SIGNAL(clicked()), this, SLOT(slotCenterTelescope()));
112  connect(ui->flagList, SIGNAL(clicked(QModelIndex)), this, SLOT(slotSetShownFlag(QModelIndex)));
113  connect(ui->flagList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotCenterFlag()));
114 
115  connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(slotSaveChanges()));
116 }
117 
118 void FlagManager::setRaDec(const dms &ra, const dms &dec)
119 {
120  ui->raBox->show(ra);
121  ui->decBox->show(dec);
122 }
123 
124 void FlagManager::clearFields()
125 {
126  ui->raBox->clear();
127  ui->decBox->clear();
128 
129  ui->epochBox->setText("2000.0");
130  ui->flagLabel->clear();
131  ui->flagLabel->setFocus();
132 
133  //disable "Save Changes" button
134  ui->saveButton->setEnabled(false);
135 
136  //unselect item from flagList
137  ui->flagList->clearSelection();
138 }
139 
140 void FlagManager::showFlag(int flagIdx)
141 {
142  if (flagIdx < 0 || flagIdx >= m_Model->rowCount())
143  {
144  return;
145  }
146 
147  else
148  {
149  ui->raBox->setText(m_Model->data(m_Model->index(flagIdx, 0)).toString());
150  ui->decBox->setText(m_Model->data(m_Model->index(flagIdx, 1)).toString());
151  ui->epochBox->setText(m_Model->data(m_Model->index(flagIdx, 2)).toString());
152 
153  //ui->flagCombobox->setCurrentItem( m_Model->data( m_Model->index( flagIdx, 3) ).toString() );
154  ui->flagCombobox->setCurrentText(m_Model->data(m_Model->index(flagIdx, 3)).toString());
155  ui->flagLabel->setText(m_Model->data(m_Model->index(flagIdx, 4)).toString());
156 
157  QColor labelColor = m_Model->item(flagIdx, 4)->foreground().color();
158  ui->labelColorcombo->setColor(labelColor);
159  }
160 
161  ui->flagList->selectRow(flagIdx);
162  ui->saveButton->setEnabled(true);
163 }
164 
165 bool FlagManager::validatePoint()
166 {
167  bool raOk(false), decOk(false);
168  dms ra(ui->raBox->createDms(&raOk));
169  dms dec(ui->decBox->createDms(&decOk));
170 
172 
173  //check if ra & dec values were successfully converted
174  if (!raOk || !decOk)
175  {
176  KSNotification::error(i18n("Invalid coordinates."));
177  return false;
178  }
179 
180  //make sure values are in valid range
181  if (ra.Hours() < 0.0 || ra.Degrees() > 360.0)
182  message = i18n("The Right Ascension value must be between 0.0 and 24.0.");
183  if (dec.Degrees() < -90.0 || dec.Degrees() > 90.0)
184  message += '\n' + i18n("The Declination value must be between -90.0 and 90.0.");
185  if (!message.isEmpty())
186  {
187  KSNotification::sorry(message, i18n("Invalid Coordinate Data"));
188  return false;
189  }
190 
191  //all checks passed
192  return true;
193 }
194 
195 void FlagManager::deleteFlagItem(int flagIdx)
196 {
197  if (flagIdx < m_Model->rowCount())
198  {
199  m_Model->removeRow(flagIdx);
200  }
201 }
202 
204 {
205  if (validatePoint() == false)
206  return;
207 
208  dms ra(ui->raBox->createDms());
209  dms dec(ui->decBox->createDms());
210 
211  insertFlag(true);
212 
213  FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
214  //Add flag in FlagComponent
215  SkyPoint flagPoint(ra, dec);
216  flags->add(flagPoint, ui->epochBox->text(), ui->flagCombobox->currentText(), ui->flagLabel->text(),
217  ui->labelColorcombo->color());
218 
219  ui->flagList->selectRow(m_Model->rowCount() - 1);
220  ui->saveButton->setEnabled(true);
221 
222  flags->saveToFile();
223 
224  //Redraw map
225  m_Ks->map()->forceUpdate(false);
226 }
227 
229 {
230  int flag = ui->flagList->currentIndex().row();
231 
232  //Remove from FlagComponent
233  m_Ks->data()->skyComposite()->flags()->remove(flag);
234 
235  //Remove from list
236  m_Model->removeRow(flag);
237 
238  //Clear form fields
239  clearFields();
240 
241  //Remove from file
242  m_Ks->data()->skyComposite()->flags()->saveToFile();
243 
244  //Redraw map
245  m_Ks->map()->forceUpdate(false);
246 }
247 
249 {
250  if (ui->flagList->currentIndex().isValid())
251  {
252  m_Ks->map()->setClickedObject(nullptr);
253  m_Ks->map()->setClickedPoint(
254  m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
255  m_Ks->map()->slotCenter();
256  }
257 }
258 
260 {
261 #ifdef HAVE_INDI
262 
263  if (INDIListener::Instance()->size() == 0)
264  {
265  KSNotification::sorry(i18n("No connected mounts found."));
266  return;
267  }
268 
269  for (auto oneDevice : INDIListener::Instance()->getDevices())
270  {
271  if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
272  continue;
273 
274  if (oneDevice->isConnected() == false)
275  {
276  KSNotification::error(
277  i18n("Telescope %1 is offline. Please connect and retry again.", oneDevice->getDeviceName()));
278  return;
279  }
280 
281  auto mount = dynamic_cast<ISD::Mount *>(oneDevice->getConcreteDevice(INDI::BaseDevice::TELESCOPE_INTERFACE));
282  if (!mount)
283  continue;
284 
285  mount->Slew(m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
286 
287  return;
288  }
289 
290  KSNotification::sorry(i18n("No connected mounts found."));
291 
292 #endif
293 }
294 
295 void FlagManager::slotSaveChanges()
296 {
297  int row = ui->flagList->currentIndex().row();
298 
299  if (validatePoint() == false)
300  return;
301 
302  insertFlag(false, row);
303 
304  m_Ks->map()->forceUpdate();
305 
306  dms ra(ui->raBox->createDms());
307  dms dec(ui->decBox->createDms());
308 
309  SkyPoint flagPoint(ra, dec);
310 
311  //Update FlagComponent
312  m_Ks->data()->skyComposite()->flags()->updateFlag(row, flagPoint, ui->epochBox->text(),
313  ui->flagCombobox->currentText(), ui->flagLabel->text(),
314  ui->labelColorcombo->color());
315 
316  //Save changes to file
317  m_Ks->data()->skyComposite()->flags()->saveToFile();
318 
319  ui->flagList->selectRow(row);
320 }
321 
322 void FlagManager::slotSetShownFlag(QModelIndex idx)
323 {
324  showFlag(idx.row());
325 }
326 
327 void FlagManager::insertFlag(bool isNew, int row)
328 {
329  dms ra(ui->raBox->createDms());
330  dms dec(ui->decBox->createDms());
331  SkyPoint flagPoint(ra, dec);
332 
333  // Add flag in the list
334  QList<QStandardItem *> itemList;
335 
336  QStandardItem *labelItem = new QStandardItem(ui->flagLabel->text());
337  labelItem->setForeground(QBrush(ui->labelColorcombo->color()));
338 
339  FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
340 
341  QPixmap pixmap;
342  itemList << new QStandardItem(flagPoint.ra0().toHMSString()) << new QStandardItem(flagPoint.dec0().toDMSString())
343  << new QStandardItem(ui->epochBox->text())
344  << new QStandardItem(QIcon(pixmap.fromImage(flags->imageList(ui->flagCombobox->currentIndex()))),
345  ui->flagCombobox->currentText())
346  << labelItem;
347 
348  if (isNew)
349  {
350  m_Model->appendRow(itemList);
351  }
352 
353  else
354  {
355  for (int i = 0; i < m_Model->columnCount(); i++)
356  {
357  m_Model->setItem(row, i, itemList.at(i));
358  }
359  }
360 }
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void slotDeleteFlag()
Delete a flag.
QImage image(int index)
Get image.
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void slotAddFlag()
Verify coordinates and add a flag.
int size()
Return the numbers of flags.
void setForeground(const QBrush &brush)
QColor labelColor(int index)
Get label color.
QList< QImage > imageList()
Get images.
void slotCenterFlag()
Center the selected flag in the display.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void saveToFile()
Save flags to flags.dat file.
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
static KStars * Instance()
Definition: kstars.h:125
int size() const const
QString i18n(const char *text, const TYPE &arg...)
bool isEmpty() const const
void add(const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Add a flag.
const T & at(int i) const const
QTextStream & dec(QTextStream &stream)
QString epoch(int index)
Get epoch.
void slotCenterTelescope()
Center the selected flag in the telescope.
int row() const const
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
const double & Degrees() const
Definition: dms.h:141
QString label(int index)
Get label.
QString imageName(int index)
Get image name.
void appendRow(const QList< QStandardItem * > &items)
void clear()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
Represents a flag on the sky map. Each flag is composed by a SkyPoint where coordinates are stored,...
Definition: flagcomponent.h:33
QString message
double Hours() const
Definition: dms.h:168
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.