Kstars

execute.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Prakash Mohan <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "oal/execute.h"
8 
9 #include "kstars.h"
10 #include "kstarsdata.h"
11 #include "ksnotification.h"
12 #include "observinglist.h"
13 #include "dialogs/finddialog.h"
14 #include "dialogs/locationdialog.h"
15 #include "oal/observeradd.h"
16 #include "skycomponents/skymapcomposite.h"
17 #include "skyobjects/starobject.h"
18 
19 #include <QFileDialog>
20 
22 {
23  QWidget *w = new QWidget;
24  ui.setupUi(w);
25 #ifdef Q_OS_OSX
26  setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
27 #endif
28 
29  QVBoxLayout *mainLayout = new QVBoxLayout;
30  mainLayout->addWidget(w);
31  setLayout(mainLayout);
32 
34  mainLayout->addWidget(buttonBox);
35  connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
36 
37  QPushButton *execB = new QPushButton(i18n("End Session"));
38  QPushButton *addObs = new QPushButton(i18n("Manage Observers"));
39  execB->setToolTip(i18n("Save and End the current session"));
40  buttonBox->addButton(execB, QDialogButtonBox::ActionRole);
41  buttonBox->addButton(addObs, QDialogButtonBox::ActionRole);
42  connect(execB, SIGNAL(clicked()), this, SLOT(slotEndSession()));
43  connect(addObs, SIGNAL(clicked()), this, SLOT(slotObserverAdd()));
44 
45  setWindowTitle(i18nc("@title:window", "Execute Session"));
46 
47  //initialize the global logObject
48  logObject = KStarsData::Instance()->logObject();
49 
50  //initialize the lists and parameters
51  init();
52  ui.Target->hide();
53  ui.AddObject->hide();
54  ui.RemoveObject->hide();
55  ui.NextButton->hide();
56  ui.NextButton->setEnabled(false);
57  ui.Slew->setEnabled(false);
58 
59  //make connections
60  connect(ui.NextButton, SIGNAL(clicked()), this, SLOT(slotNext()));
61  connect(ui.Slew, SIGNAL(clicked()), this, SLOT(slotSlew()));
62  connect(ui.Location, SIGNAL(clicked()), this, SLOT(slotLocation()));
63  connect(ui.Target, SIGNAL(currentTextChanged(QString)), this, SLOT(slotSetTarget(QString)));
64  connect(ui.SessionURL, SIGNAL(leftClickedUrl()), this, SLOT(slotShowSession()));
65  connect(ui.ObservationsURL, SIGNAL(leftClickedUrl()), this, SLOT(slotShowTargets()));
66  connect(ui.AddObject, SIGNAL(leftClickedUrl()), this, SLOT(slotAddObject()));
67  connect(ui.RemoveObject, SIGNAL(leftClickedUrl()), this, SLOT(slotRemoveObject()));
68 }
69 
71 {
72  //initialize geo to current location of the ObservingList
73  geo = KStarsData::Instance()->geo();
74  ui.Location->setText(geo->fullName());
75 
76  // JM: Aren't we suppose to take KStars time? The one returned by the OL is the time of the LAST object
77  // in the list which doesn't make sense.
78 
79  /*
80  //set the date time to the dateTime from the OL
81  ui.Begin->setDateTime( ks->observingList()->dateTime() );
82  */
83  ui.Begin->setDateTime(KStarsData::Instance()->geo()->UTtoLT(KStarsData::Instance()->clock()->utc()));
84 
85  KStarsData::Instance()->logObject()->readAll();
86 
87  //load Targets
88  loadTargets();
89 
90  //load Equipment
91  loadEquipment();
92 
93  //load Observers
94  loadObservers();
95 
96  if (logObject->scopeList()->isEmpty() || logObject->observerList()->isEmpty())
97  {
98  ui.hintLabel->show();
99  }
100  else
101  {
102  ui.hintLabel->hide();
103  }
104 
105  //set Current Items
106  loadCurrentItems();
107 }
108 void Execute::loadCurrentItems()
109 {
110  //Set the current target, equipments and observer
111  if (currentTarget)
112  ui.Target->setCurrentRow(findIndexOfTarget(currentTarget->name()), QItemSelectionModel::SelectCurrent);
113  else
114  ui.Target->setCurrentRow(0, QItemSelectionModel::SelectCurrent);
115 
116  if (currentObserver)
117  ui.Observer->setCurrentIndex(ui.Observer->findText(currentObserver->name() + ' ' + currentObserver->surname()));
118  if (currentScope)
119  ui.Scope->setCurrentIndex(ui.Scope->findText(currentScope->name()));
120  if (currentEyepiece)
121  ui.Eyepiece->setCurrentIndex(ui.Eyepiece->findText(currentEyepiece->name()));
122  if (currentLens)
123  ui.Lens->setCurrentIndex(ui.Lens->findText(currentLens->name()));
124  if (currentFilter)
125  ui.Filter->setCurrentIndex(ui.Filter->findText(currentFilter->name()));
126 }
127 
128 int Execute::findIndexOfTarget(QString name)
129 {
130  for (int i = 0; i < ui.Target->count(); i++)
131  if (ui.Target->item(i)->text() == name)
132  return i;
133  return -1;
134 }
135 
137 {
138  switch (ui.stackedWidget->currentIndex())
139  {
140  case 0:
141  {
142  saveSession();
143  break;
144  }
145  case 1:
146  {
147  addTargetNotes();
148  break;
149  }
150  case 2:
151  {
152  addObservation();
153  ui.stackedWidget->setCurrentIndex(1);
154  ui.NextButton->setText(i18n("Next Page >"));
155  QString prevTarget = currentTarget->name();
156  loadTargets();
157  ui.Target->setCurrentRow(findIndexOfTarget(prevTarget), QItemSelectionModel::SelectCurrent);
158  selectNextTarget();
159  break;
160  }
161  }
162 }
163 
165 {
166  OAL::Site *site = logObject->findSiteByName(geo->fullName());
167  if (!site)
168  {
169  while (logObject->findSiteById(i18n("site_") + QString::number(nextSite)))
170  nextSite++;
171  site = new OAL::Site(geo, i18n("site_") + QString::number(nextSite++));
172  logObject->siteList()->append(site);
173  }
174  if (currentSession)
175  {
176  currentSession->setSession(currentSession->id(), site->id(), KStarsDateTime(ui.Begin->dateTime()),
177  KStarsDateTime(ui.Begin->dateTime()), ui.Weather->toPlainText(),
178  ui.Equipment->toPlainText(), ui.Comment->toPlainText(),
179  ui.Language->text());
180  }
181  else
182  {
183  while (logObject->findSessionByName(i18n("session_") + QString::number(nextSession)))
184  nextSession++;
185  currentSession = new OAL::Session(i18n("session_") + QString::number(nextSession++), site->id(),
186  KStarsDateTime(ui.Begin->dateTime()), KStarsDateTime(ui.Begin->dateTime()),
187  ui.Weather->toPlainText(), ui.Equipment->toPlainText(),
188  ui.Comment->toPlainText(), ui.Language->text());
189  logObject->sessionList()->append(currentSession);
190  }
191  ui.stackedWidget->setCurrentIndex(1); //Move to the next page
192  return true;
193 }
194 
196 {
197  QPointer<LocationDialog> ld = new LocationDialog(this);
198  if (ld->exec() == QDialog::Accepted)
199  {
200  geo = ld->selectedCity();
201  ui.Location->setText(geo->fullName());
202  }
203  delete ld;
204 }
205 
207 {
208  ui.Target->clear();
209  sortTargetList();
210 
211  for (auto &o : KStarsData::Instance()->observingList()->sessionList())
212  {
213  ui.Target->addItem(getObjectName(o.data(), false));
214  }
215 }
216 
218 {
219  ui.Scope->clear();
220  ui.Eyepiece->clear();
221  ui.Lens->clear();
222  ui.Filter->clear();
223  foreach (OAL::Scope *s, *(logObject->scopeList()))
224  ui.Scope->addItem(s->name());
225  foreach (OAL::Eyepiece *e, *(logObject->eyepieceList()))
226  ui.Eyepiece->addItem(e->name());
227  foreach (OAL::Lens *l, *(logObject->lensList()))
228  ui.Lens->addItem(l->name());
229  foreach (OAL::Filter *f, *(logObject->filterList()))
230  ui.Filter->addItem(f->name());
231 }
232 
234 {
235  ui.Observer->clear();
236  foreach (OAL::Observer *o, *(logObject->observerList()))
237  ui.Observer->addItem(o->name() + ' ' + o->surname());
238 }
239 
241 {
242  auto timeLessThan = [](QSharedPointer<SkyObject> o1, QSharedPointer<SkyObject> o2)
243  {
244  QTime t1 = KStarsData::Instance()->observingList()->scheduledTime(o1.data());
245  QTime t2 = KStarsData::Instance()->observingList()->scheduledTime(o2.data());
246 
247  if (t1 < QTime(12, 0, 0))
248  t1.setHMS(t1.hour() + 12, t1.minute(), t1.second());
249  else
250  t1.setHMS(t1.hour() - 12, t1.minute(), t1.second());
251  if (t2 < QTime(12, 0, 0))
252  t2.setHMS(t2.hour() + 12, t2.minute(), t2.second());
253  else
254  t2.setHMS(t2.hour() - 12, t2.minute(), t2.second());
255  return (t1 < t2);
256  };
257 
258  std::sort(KStarsData::Instance()->observingList()->sessionList().begin(),
259  KStarsData::Instance()->observingList()->sessionList().end(), timeLessThan);
260 }
261 
263 {
264  if (!ui.Target->count())
265  return;
266  SkyObject *o = KStarsData::Instance()->observingList()->findObjectByName(ui.Target->currentItem()->text());
267  if (o)
268  {
269  currentTarget = o;
270  KStarsData::Instance()->updateUserLog(o->name(), ui.Notes->toPlainText());
271  ui.Notes->clear();
272  loadObservationTab();
273  }
274 }
275 
277 {
278  ui.Time->setTime(KStarsDateTime::currentDateTime().time());
279  ui.stackedWidget->setCurrentIndex(2);
280  ui.NextButton->setText(i18n("Next Target >"));
281 }
282 
284 {
285  slotSetCurrentObjects();
286  while (logObject->findObservationByName(i18n("observation_") + QString::number(nextObservation)))
287  nextObservation++;
288  KStarsDateTime dt = currentSession->begin();
289  dt.setTime(ui.Time->time());
291  i18n("observation_") + QString::number(nextObservation++), currentObserver, currentSession, currentTarget, dt,
292  ui.FaintestStar->value(), ui.Seeing->value(), currentScope, currentEyepiece, currentLens, currentFilter,
293  ui.Description->toPlainText(), ui.Language->text());
294  logObject->observationList()->append(o);
295  ui.Description->clear();
296  return true;
297 }
299 {
300  if (currentSession)
301  {
302  currentSession->setSession(currentSession->id(), currentSession->site(), KStarsDateTime(ui.Begin->dateTime()),
303  KStarsDateTime::currentDateTime(), ui.Weather->toPlainText(),
304  ui.Equipment->toPlainText(), ui.Comment->toPlainText(), ui.Language->text());
305 
306  QUrl fileURL = QFileDialog::getSaveFileUrl(nullptr, i18nc("@title:window", "Save Session"), QUrl(QDir::homePath()), "*.xml");
307 
308  if (fileURL.isEmpty())
309  {
310  // Cancel
311  return;
312  }
313 
314  if (fileURL.isValid())
315  {
316  QFile f(fileURL.toLocalFile());
317  if (!f.open(QIODevice::WriteOnly))
318  {
319  QString message = i18n("Could not open file %1", f.fileName());
320  KSNotification::sorry(message, i18n("Could Not Open File"));
321  return;
322  }
323  QTextStream ostream(&f);
324  ostream << logObject->writeLog(false);
325  f.close();
326  }
327  }
328  hide();
329  ui.stackedWidget->setCurrentIndex(0);
330  logObject->observationList()->clear();
331  logObject->sessionList()->clear();
332  delete currentSession;
333  currentTarget = nullptr;
334  currentSession = nullptr;
335 }
336 void Execute::slotObserverAdd()
337 {
338  QPointer<ObserverAdd> m_observerAdd = new ObserverAdd();
339  m_observerAdd->exec();
340  delete m_observerAdd;
341 }
342 
344 {
345  currentTarget = KStarsData::Instance()->observingList()->findObjectByName(name);
346  if (!currentTarget)
347  {
348  ui.NextButton->setEnabled(false);
349  ui.Slew->setEnabled(false);
350  return;
351  }
352  else
353  {
354  ui.NextButton->setEnabled(true);
355  ui.Slew->setEnabled(true);
356  KStarsData::Instance()->observingList()->selectObject(currentTarget);
357  KStarsData::Instance()->observingList()->slotCenterObject();
358  QString smag = "--";
359  if (-30.0 < currentTarget->mag() && currentTarget->mag() < 90.0)
360  smag = QString::number(currentTarget->mag(), 'g',
361  2); // The lower limit to avoid display of unrealistic comet magnitudes
362  ui.Mag->setText(smag);
363  ui.Type->setText(currentTarget->typeName());
364  ui.SchTime->setText(
365  KStarsData::Instance()->observingList()->scheduledTime(currentTarget).toString("h:mm:ss AP"));
366  SkyPoint p = currentTarget->recomputeCoords(KStarsDateTime::currentDateTime(), geo);
367  dms lst(geo->GSTtoLST(KStarsDateTime::currentDateTime().gst()));
368  p.EquatorialToHorizontal(&lst, geo->lat());
369  ui.RA->setText(p.ra().toHMSString());
370  ui.Dec->setText(p.dec().toDMSString());
371  ui.Alt->setText(p.alt().toDMSString());
372  ui.Az->setText(p.az().toDMSString());
373  ui.Notes->setText(KStarsData::Instance()->getUserData(currentTarget->name()).userLog);
374  }
375 }
376 
377 void Execute::slotSlew()
378 {
379  KStarsData::Instance()->observingList()->slotSlewToObject();
380 }
381 
382 void Execute::selectNextTarget()
383 {
384  int i = findIndexOfTarget(currentTarget->name()) + 1;
385  if (i < ui.Target->count())
386  {
387  ui.Target->selectionModel()->clear();
388  ui.Target->setCurrentRow(i, QItemSelectionModel::SelectCurrent);
389  }
390 }
391 
392 void Execute::slotSetCurrentObjects()
393 {
394  currentScope = logObject->findScopeByName(ui.Scope->currentText());
395  currentEyepiece = logObject->findEyepieceByName(ui.Eyepiece->currentText());
396  currentLens = logObject->findLensByName(ui.Lens->currentText());
397  currentFilter = logObject->findFilterByName(ui.Filter->currentText());
398  currentObserver = logObject->findObserverByName(ui.Observer->currentText());
399 }
400 
401 void Execute::slotShowSession()
402 {
403  ui.Target->hide();
404  ui.stackedWidget->setCurrentIndex(0);
405  ui.NextButton->hide();
406  ui.AddObject->hide();
407  ui.RemoveObject->hide();
408 }
409 
410 void Execute::slotShowTargets()
411 {
412  if (saveSession())
413  {
414  ui.Target->show();
415  ui.AddObject->show();
416  ui.RemoveObject->show();
417  ui.stackedWidget->setCurrentIndex(1);
418  ui.NextButton->show();
419  ui.NextButton->setText(i18n("Next Page >"));
420  }
421 }
422 
423 void Execute::slotAddObject()
424 {
425  if (FindDialog::Instance()->exec() == QDialog::Accepted)
426  {
427  SkyObject *o = FindDialog::Instance()->targetObject();
428  if (o != nullptr)
429  {
430  KStarsData::Instance()->observingList()->slotAddObject(o, true);
431  init();
432  }
433  }
434 }
435 
436 void Execute::slotRemoveObject()
437 {
438  QModelIndex i = ui.Target->currentIndex();
439  SkyObject *obj = nullptr;
440 
441  if (i.isValid())
442  {
443  QString ObjName = i.data().toString();
444 
445  obj = KStarsData::Instance()->skyComposite()->findByName(ObjName);
446  }
447 
448  if (obj != nullptr)
449  {
450  KStarsData::Instance()->observingList()->slotRemoveObject(obj, true);
451  loadTargets();
452  }
453 }
454 
455 QString Execute::getObjectName(const SkyObject *o, bool translated)
456 {
457  QString finalObjectName;
458 
459  if (o->name() == "star")
460  {
461  StarObject *s = (StarObject *)o;
462 
463  // JM: Enable HD Index stars to be added to the observing list.
464  if (s->getHDIndex() != 0)
465  finalObjectName = QString("HD %1").arg(QString::number(s->getHDIndex()));
466  }
467  else
468  finalObjectName = translated ? o->translatedName() : o->name();
469 
470  return finalObjectName;
471 }
void loadObservers()
loads the observer list from the global logObject into the comboBoxes
Definition: execute.cpp:233
const dms & alt() const
Definition: skypoint.h:281
static KStarsDateTime currentDateTime()
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
T * data() const const
void sortTargetList()
Sorts the target list using the scheduled time.
Definition: execute.cpp:240
QString number(int n, int base)
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
QCA_EXPORT void init()
void loadTargets()
Loads the sessionlist from the OL into the target combo box.
Definition: execute.cpp:206
Execute()
Default constructor.
Definition: execute.cpp:21
QString getObjectName(const SkyObject *o, bool translated=true)
get object name.
Definition: execute.cpp:455
virtual QString name(void) const
Definition: skyobject.h:145
void addTargetNotes()
Function to save the user notes set for the current object in the target combo box.
Definition: execute.cpp:262
QString translatedName() const
Definition: skyobject.h:148
void slotSetTarget(const QString &name)
set the currentTarget when the user selection is changed in the target combo box
Definition: execute.cpp:343
QString homePath()
void slotLocation()
Opens the location dialog for setting the current location.
Definition: execute.cpp:195
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition: skypoint.cpp:77
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition: dms.cpp:370
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
int getHDIndex() const
Definition: starobject.h:248
void setTime(const QTime &t)
Assign the Time according to a QTime object.
bool isValid() const const
QVariant data(int role) const const
void loadEquipment()
loads the equipment list from the global logObject into the comboBoxes
Definition: execute.cpp:217
void loadObservationTab()
loads the observation edit page
Definition: execute.cpp:276
SkyObject * findByName(const QString &name, bool exact=true) override
Search the children of this SkyMapComposite for a SkyObject whose name matches the argument.
QString i18n(const char *text, const TYPE &arg...)
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
Definition: dms.cpp:279
const CachingDms & dec() const
Definition: skypoint.h:269
bool isEmpty() const const
subclass of SkyObject specialized for stars.
Definition: starobject.h:32
bool saveSession()
Function to Save the session details.
Definition: execute.cpp:164
QUrl getSaveFileUrl(QWidget *parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes)
GeoLocation * geo()
Definition: kstarsdata.h:229
bool setHMS(int h, int m, int s, int ms)
void slotNext()
Function to handle the UI when the 'next' button is pressed This calls the corresponding functions ba...
Definition: execute.cpp:136
QString toLocalFile() const const
void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
std::pair< bool, QString > updateUserLog(const QString &name, const QString &newLog)
Update the user log of the object with the name to contain newLog (find and replace).
void setupUi(QWidget *widget)
bool isValid() const const
int hour() const const
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:165
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
Definition: lens.h:17
bool addObservation()
Function to add the current observation to the observation list.
Definition: execute.cpp:283
OAL::Log * logObject()
Return log object.
Definition: kstarsdata.h:340
const CachingDms & ra() const
Definition: skypoint.h:263
FIXME: why not just use a QHash?
Definition: observer.h:19
void setToolTip(const QString &)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int second() const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void slotEndSession()
Function to handle the state of current observation, and hiding the execute window.
Definition: execute.cpp:298
Information about an object in the sky.
Definition: skyobject.h:41
int minute() const const
QString message
void init()
This initializes the combo boxes, and sets up the dateTime and geolocation from the OL.
Definition: execute.cpp:70
Definition: site.h:19
QString toString() const const
const dms & az() const
Definition: skypoint.h:275
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:50 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.