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  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 
109  //Connect buttons
110  connect(ui->addButton, SIGNAL(clicked()), this, SLOT(slotAddFlag()));
111  connect(ui->delButton, SIGNAL(clicked()), this, SLOT(slotDeleteFlag()));
112  connect(ui->CenterButton, SIGNAL(clicked()), this, SLOT(slotCenterFlag()));
113  connect(ui->ScopeButton, SIGNAL(clicked()), this, SLOT(slotCenterTelescope()));
114  connect(ui->flagList, SIGNAL(clicked(QModelIndex)), this, SLOT(slotSetShownFlag(QModelIndex)));
115  connect(ui->flagList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotCenterFlag()));
116 
117  connect(ui->saveButton, SIGNAL(clicked()), this, SLOT(slotSaveChanges()));
118 }
119 
120 void FlagManager::setRaDec(const dms &ra, const dms &dec)
121 {
122  ui->raBox->show(ra);
123  ui->decBox->show(dec);
124 }
125 
126 void FlagManager::clearFields()
127 {
128  ui->raBox->clear();
129  ui->decBox->clear();
130 
131  ui->epochBox->setText("2000.0");
132  ui->flagLabel->clear();
133  ui->flagLabel->setFocus();
134 
135  //disable "Save Changes" button
136  ui->saveButton->setEnabled(false);
137 
138  //unselect item from flagList
139  ui->flagList->clearSelection();
140 }
141 
142 void FlagManager::showFlag(int flagIdx)
143 {
144  if (flagIdx < 0 || flagIdx >= m_Model->rowCount())
145  {
146  return;
147  }
148 
149  else
150  {
151  ui->raBox->setText(m_Model->data(m_Model->index(flagIdx, 0)).toString());
152  ui->decBox->setText(m_Model->data(m_Model->index(flagIdx, 1)).toString());
153  ui->epochBox->setText(m_Model->data(m_Model->index(flagIdx, 2)).toString());
154 
155  //ui->flagCombobox->setCurrentItem( m_Model->data( m_Model->index( flagIdx, 3) ).toString() );
156  ui->flagCombobox->setCurrentText(m_Model->data(m_Model->index(flagIdx, 3)).toString());
157  ui->flagLabel->setText(m_Model->data(m_Model->index(flagIdx, 4)).toString());
158 
159  QColor labelColor = m_Model->item(flagIdx, 4)->foreground().color();
160  ui->labelColorcombo->setColor(labelColor);
161  }
162 
163  ui->flagList->selectRow(flagIdx);
164  ui->saveButton->setEnabled(true);
165 }
166 
167 bool FlagManager::validatePoint()
168 {
169  bool raOk(false), decOk(false);
170  dms ra(ui->raBox->createDms(&raOk));
171  dms dec(ui->decBox->createDms(&decOk));
172 
174 
175  //check if ra & dec values were successfully converted
176  if (!raOk || !decOk)
177  {
178  KSNotification::error(i18n("Invalid coordinates."));
179  return false;
180  }
181 
182  //make sure values are in valid range
183  if (ra.Hours() < 0.0 || ra.Degrees() > 360.0)
184  message = i18n("The Right Ascension value must be between 0.0 and 24.0.");
185  if (dec.Degrees() < -90.0 || dec.Degrees() > 90.0)
186  message += '\n' + i18n("The Declination value must be between -90.0 and 90.0.");
187  if (!message.isEmpty())
188  {
189  KSNotification::sorry(message, i18n("Invalid Coordinate Data"));
190  return false;
191  }
192 
193  //all checks passed
194  return true;
195 }
196 
197 void FlagManager::deleteFlagItem(int flagIdx)
198 {
199  if (flagIdx < m_Model->rowCount())
200  {
201  m_Model->removeRow(flagIdx);
202  }
203 }
204 
206 {
207  if (validatePoint() == false)
208  return;
209 
210  dms ra(ui->raBox->createDms());
211  dms dec(ui->decBox->createDms());
212 
213  insertFlag(true);
214 
215  FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
216  //Add flag in FlagComponent
217  SkyPoint flagPoint(ra, dec);
218  flags->add(flagPoint, ui->epochBox->text(), ui->flagCombobox->currentText(), ui->flagLabel->text(),
219  ui->labelColorcombo->color());
220 
221  ui->flagList->selectRow(m_Model->rowCount() - 1);
222  ui->saveButton->setEnabled(true);
223 
224  flags->saveToFile();
225 
226  //Redraw map
227  m_Ks->map()->forceUpdate(false);
228 }
229 
231 {
232  int flag = ui->flagList->currentIndex().row();
233 
234  //Remove from FlagComponent
235  m_Ks->data()->skyComposite()->flags()->remove(flag);
236 
237  //Remove from list
238  m_Model->removeRow(flag);
239 
240  //Clear form fields
241  clearFields();
242 
243  //Remove from file
244  m_Ks->data()->skyComposite()->flags()->saveToFile();
245 
246  //Redraw map
247  m_Ks->map()->forceUpdate(false);
248 }
249 
251 {
252  if (ui->flagList->currentIndex().isValid())
253  {
254  m_Ks->map()->setClickedObject(nullptr);
255  m_Ks->map()->setClickedPoint(
256  m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
257  m_Ks->map()->slotCenter();
258  }
259 }
260 
262 {
263 #ifdef HAVE_INDI
264 
265  if (INDIListener::Instance()->size() == 0)
266  {
267  KSNotification::sorry(i18n("No connected mounts found."));
268  return;
269  }
270 
271  for (auto oneDevice : INDIListener::devices())
272  {
273  if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
274  continue;
275 
276  if (oneDevice->isConnected() == false)
277  {
278  KSNotification::error(
279  i18n("Telescope %1 is offline. Please connect and retry again.", oneDevice->getDeviceName()));
280  return;
281  }
282 
283  auto mount = oneDevice->getMount();
284  if (!mount)
285  continue;
286 
287  mount->Slew(m_Ks->data()->skyComposite()->flags()->pointList().at(ui->flagList->currentIndex().row()).get());
288 
289  return;
290  }
291 
292  KSNotification::sorry(i18n("No connected mounts found."));
293 
294 #endif
295 }
296 
297 void FlagManager::slotSaveChanges()
298 {
299  int row = ui->flagList->currentIndex().row();
300 
301  if (validatePoint() == false)
302  return;
303 
304  insertFlag(false, row);
305 
306  m_Ks->map()->forceUpdate();
307 
308  dms ra(ui->raBox->createDms());
309  dms dec(ui->decBox->createDms());
310 
311  SkyPoint flagPoint(ra, dec);
312 
313  //Update FlagComponent
314  m_Ks->data()->skyComposite()->flags()->updateFlag(row, flagPoint, ui->epochBox->text(),
315  ui->flagCombobox->currentText(), ui->flagLabel->text(),
316  ui->labelColorcombo->color());
317 
318  //Save changes to file
319  m_Ks->data()->skyComposite()->flags()->saveToFile();
320 
321  ui->flagList->selectRow(row);
322 }
323 
324 void FlagManager::slotSetShownFlag(QModelIndex idx)
325 {
326  showFlag(idx.row());
327 }
328 
329 void FlagManager::insertFlag(bool isNew, int row)
330 {
331  dms ra(ui->raBox->createDms());
332  dms dec(ui->decBox->createDms());
333  SkyPoint flagPoint(ra, dec);
334 
335  // Add flag in the list
336  QList<QStandardItem *> itemList;
337 
338  QStandardItem *labelItem = new QStandardItem(ui->flagLabel->text());
339  labelItem->setForeground(QBrush(ui->labelColorcombo->color()));
340 
341  FlagComponent *flags = m_Ks->data()->skyComposite()->flags();
342 
343  QPixmap pixmap;
344  itemList << new QStandardItem(flagPoint.ra0().toHMSString()) << new QStandardItem(flagPoint.dec0().toDMSString())
345  << new QStandardItem(ui->epochBox->text())
346  << new QStandardItem(QIcon(pixmap.fromImage(flags->imageList(ui->flagCombobox->currentIndex()))),
347  ui->flagCombobox->currentText())
348  << labelItem;
349 
350  if (isNew)
351  {
352  m_Model->appendRow(itemList);
353  }
354 
355  else
356  {
357  for (int i = 0; i < m_Model->columnCount(); i++)
358  {
359  m_Model->setItem(row, i, itemList.at(i));
360  }
361  }
362 }
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:122
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-2023 The KDE developers.
Generated on Mon Jun 5 2023 03:56:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.