Kstars

opssatellites.cpp
1 /*
2  SPDX-FileCopyrightText: 2011 Jérôme SONRIER <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "opssatellites.h"
8 
9 #include "kstars.h"
10 #include "kstarsdata.h"
11 #include "Options.h"
12 #include "satellite.h"
13 #include "skymapcomposite.h"
14 #include "skycomponents/satellitescomponent.h"
15 #include "skymap.h"
16 
17 #include <QStandardItemModel>
18 #include <QStatusBar>
19 
20 static const char *satgroup_strings_context = "Satellite group name";
21 
22 SatelliteSortFilterProxyModel::SatelliteSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
23 {
24 }
25 
26 bool SatelliteSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
27 {
28  QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
29 
30  if (sourceModel()->hasChildren(index))
31  {
32  for (int i = 0; i < sourceModel()->rowCount(index); ++i)
33  if (filterAcceptsRow(i, index))
34  return true;
35  return false;
36  }
37 
38  return sourceModel()->data(index).toString().contains(filterRegExp());
39 }
40 
42 {
43  setupUi(this);
44 
45  m_ConfigDialog = KConfigDialog::exists("settings");
46 
47  //Set up the Table Views
48  m_Model = new QStandardItemModel(0, 1, this);
49  m_SortModel = new SatelliteSortFilterProxyModel(this);
50  m_SortModel->setSourceModel(m_Model);
51  SatListTreeView->setModel(m_SortModel);
52  SatListTreeView->setEditTriggers(QTreeView::NoEditTriggers);
53  SatListTreeView->setSortingEnabled(false);
54 
55  // Populate satellites list
56  updateListView();
57 
58  // Signals and slots connections
59  connect(UpdateTLEButton, SIGNAL(clicked()), this, SLOT(slotUpdateTLEs()));
60  connect(kcfg_ShowSatellites, SIGNAL(toggled(bool)), SLOT(slotShowSatellites(bool)));
61  connect(m_ConfigDialog->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(slotApply()));
62  connect(m_ConfigDialog->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(slotApply()));
63  connect(m_ConfigDialog->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), SLOT(slotCancel()));
64  connect(FilterEdit, SIGNAL(textChanged(QString)), this, SLOT(slotFilterReg(QString)));
65  connect(m_Model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
66 
67  #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
68  connect(satelliteButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonPressed), this,
69  [&]() { isDirty = true; });
70  #else
71  connect(satelliteButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::idPressed), this,
72  [&]() { isDirty = true; });
73  #endif
74 
75  isDirty = false;
76 }
77 
78 void OpsSatellites::slotUpdateTLEs()
79 {
80  // Save existing satellites
81  saveSatellitesList();
82 
83  // Get new data files
84  KStarsData::Instance()->skyComposite()->satellites()->updateTLEs();
85 
86  isDirty = true;
87 
88  // Refresh satellites list
89  updateListView();
90 }
91 
92 void OpsSatellites::updateListView()
93 {
94  KStarsData *data = KStarsData::Instance();
95 
96  // Clear satellites list
97  m_Model->clear();
98  SatListTreeView->reset();
99 
100  m_Model->setHorizontalHeaderLabels(QStringList(i18n("Satellite Name")));
101 
102  // Add each groups and satellites in the list
103  foreach (SatelliteGroup *sat_group, data->skyComposite()->satellites()->groups())
104  {
105  QStandardItem *group_item;
106  QStandardItem *sat_item;
107  bool all_sat_checked = true;
108  bool all_sat_unchecked = true;
109 
110  // Add the group
111  group_item = new QStandardItem(i18nc(satgroup_strings_context, sat_group->name().toUtf8()));
112  group_item->setCheckable(true);
113  m_Model->appendRow(group_item);
114 
115  // Add all satellites of the group
116  for (int i = 0; i < sat_group->count(); ++i)
117  {
118  sat_item = new QStandardItem(sat_group->at(i)->name());
119  sat_item->setCheckable(true);
120  if (Options::selectedSatellites().contains(sat_group->at(i)->name()))
121  {
122  sat_item->setCheckState(Qt::Checked);
123  all_sat_unchecked = false;
124  }
125  else
126  all_sat_checked = false;
127  group_item->setChild(i, sat_item);
128  }
129 
130  // If all satellites of the group are selected, select the group
131  if (all_sat_checked)
132  group_item->setCheckState(Qt::Checked);
133  else if (all_sat_unchecked)
134  group_item->setCheckState(Qt::Unchecked);
135  else
136  group_item->setCheckState(Qt::PartiallyChecked);
137  }
138 }
139 
140 void OpsSatellites::saveSatellitesList()
141 {
142  KStarsData *data = KStarsData::Instance();
143  QString sat_name;
144  QStringList selected_satellites;
145  QModelIndex group_index, sat_index;
146  QStandardItem *group_item;
147  QStandardItem *sat_item;
148 
149  // Retrieve each satellite in the list and select it if checkbox is checked
150  for (int i = 0; i < m_Model->rowCount(SatListTreeView->rootIndex()); ++i)
151  {
152  group_index = m_Model->index(i, 0, SatListTreeView->rootIndex());
153  group_item = m_Model->itemFromIndex(group_index);
154 
155  for (int j = 0; j < m_Model->rowCount(group_item->index()); ++j)
156  {
157  sat_index = m_Model->index(j, 0, group_index);
158  sat_item = m_Model->itemFromIndex(sat_index);
159  sat_name = sat_item->data(0).toString();
160 
161  Satellite *sat = data->skyComposite()->satellites()->findSatellite(sat_name);
162  if (sat)
163  {
164  if (sat_item->checkState() == Qt::Checked)
165  {
166  int rc = sat->updatePos();
167  // If position calculation fails, unselect it
168  if (rc == 0)
169  {
170  sat->setSelected(true);
171  selected_satellites.append(sat_name);
172  }
173  else
174  {
176  i18n("%1 position calculation error: %2.", sat->name(), sat->sgp4ErrorString(rc)), 0);
177  sat->setSelected(false);
178  sat_item->setCheckState(Qt::Unchecked);
179  }
180  }
181  else
182  {
183  sat->setSelected(false);
184  }
185  }
186  }
187  }
188 
189  Options::setSelectedSatellites(selected_satellites);
190 }
191 
192 void OpsSatellites::slotApply()
193 {
194  if (isDirty == false)
195  return;
196 
197  isDirty = false;
198 
199  saveSatellitesList();
200 
201  // update time for all objects because they might be not initialized
202  // it's needed when using horizontal coordinates
206 }
207 
208 void OpsSatellites::slotCancel()
209 {
210  // Update satellites list
211  updateListView();
212 }
213 
214 void OpsSatellites::slotShowSatellites(bool on)
215 {
216  isDirty = true;
217  kcfg_ShowVisibleSatellites->setEnabled(on);
218  kcfg_ShowSatellitesLabels->setEnabled(on);
219  kcfg_DrawSatellitesLikeStars->setEnabled(on);
220 }
221 
222 void OpsSatellites::slotFilterReg(const QString &filter)
223 {
224  m_SortModel->setFilterRegExp(QRegExp(filter, Qt::CaseInsensitive, QRegExp::RegExp));
225  m_SortModel->setFilterKeyColumn(-1);
226 
227  isDirty = true;
228 
229  // Expand all categories when the user use filter
230  if (filter.length() > 0)
231  SatListTreeView->expandAll();
232  else
233  SatListTreeView->collapseAll();
234 }
235 
236 void OpsSatellites::slotItemChanged(QStandardItem *item)
237 {
238  if (item->parent() == nullptr && !item->hasChildren())
239  {
240  return;
241  }
242 
243  isDirty = true;
244 
245  QModelIndex sat_index;
246  QStandardItem *sat_item;
247 
248  disconnect(m_Model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
249 
250  // If a group has been (un)checked, (un)check all satellites of the group
251  // else a satellite has been (un)checked, (un)check his group
252  if (item->hasChildren())
253  {
254  for (int i = 0; i < m_Model->rowCount(item->index()); ++i)
255  {
256  sat_index = m_Model->index(i, 0, item->index());
257  sat_item = m_Model->itemFromIndex(sat_index);
258 
259  if (item->checkState() == Qt::Checked)
260  sat_item->setCheckState(Qt::Checked);
261  else
262  sat_item->setCheckState(Qt::Unchecked);
263  }
264  }
265  else
266  {
267  bool all_sat_checked = true;
268  bool all_sat_unchecked = true;
269 
270  for (int i = 0; i < item->parent()->model()->rowCount(item->parent()->index()); ++i)
271  {
272  sat_index = m_Model->index(i, 0, item->parent()->index());
273  sat_item = m_Model->itemFromIndex(sat_index);
274 
275  if (sat_item->checkState() == Qt::Checked)
276  all_sat_unchecked = false;
277  else
278  all_sat_checked = false;
279  }
280 
281  if (all_sat_checked)
282  item->parent()->setCheckState(Qt::Checked);
283  else if (all_sat_unchecked)
285  else
287  }
288 
289  connect(m_Model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
290 }
void append(const T &value)
void updateTime(const bool automaticDSTchange=true)
Update time-dependent data and (possibly) repaint the sky map.
Definition: kstars.cpp:556
CaseInsensitive
Qt::CheckState checkState() const const
int count(const T &value) const const
virtual QString name(void) const
Definition: skyobject.h:145
SkyMap * map() const
Definition: kstars.h:141
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
Definition: kstarsdata.cpp:313
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static KStars * Instance()
Definition: kstars.h:123
void showMessage(const QString &message, int timeout)
QVariant data(int role) const const
OpsSatellites()
Constructor.
QString i18n(const char *text, const TYPE &arg...)
Satellite * findSatellite(QString name)
Search a satellite by name.
QByteArray toUtf8() const const
const T & at(int i) const const
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
QStandardItem * parent() const const
QModelIndex index() const const
static KConfigDialog * exists(const QString &name)
void setChild(int row, int column, QStandardItem *item)
QList< SatelliteGroup * > groups()
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:90
void setupUi(QWidget *widget)
bool hasChildren() const const
QStatusBar * statusBar() const const
void buttonPressed(QAbstractButton *button)
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:166
void updateTLEs()
Download new TLE files.
void idPressed(int id)
QString sgp4ErrorString(int code)
sgp4ErrorString Get error string associated with sgp4 calculation failure
Definition: satellite.cpp:1232
virtual QVariant data(int role) const const
void setSelected(bool selected)
Select or not the satellite.
Definition: satellite.cpp:1304
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KStarsData * data() const
Definition: kstars.h:135
int updatePos()
Update satellite position.
Definition: satellite.cpp:706
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition: skymap.cpp:1176
void setCheckable(bool checkable)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QPushButton * button(QDialogButtonBox::StandardButton which) const
void setCheckState(Qt::CheckState state)
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:12 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.