• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • edu API Reference
  • KDE Home
  • Contact Us
 

kstars

  • extragear
  • edu
  • kstars
  • kstars
  • tools
observinglist.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  observinglist.cpp - K Desktop Planetarium
3  -------------------
4  begin : 29 Nov 2004
5  copyright : (C) 2004-2014 by Jeff Woods, Jason Harris,
6  Prakash Mohan, Akarsh Simha
7  email : [email protected], [email protected],
8  [email protected], [email protected]
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 #include "observinglist.h"
21 
22 #include "config-kstars.h"
23 
24 #include "constellationboundarylines.h"
25 #include "fov.h"
26 #include "imageviewer.h"
27 #include "ksalmanac.h"
28 #include "ksnotification.h"
29 #include "ksdssdownloader.h"
30 #include "kspaths.h"
31 #include "kstars.h"
32 #include "kstarsdata.h"
33 #include "ksutils.h"
34 #include "obslistpopupmenu.h"
35 #include "obslistwizard.h"
36 #include "Options.h"
37 #include "sessionsortfilterproxymodel.h"
38 #include "skymap.h"
39 #include "thumbnailpicker.h"
40 #include "dialogs/detaildialog.h"
41 #include "dialogs/finddialog.h"
42 #include "dialogs/locationdialog.h"
43 #include "oal/execute.h"
44 #include "skycomponents/skymapcomposite.h"
45 #include "skyobjects/starobject.h"
46 #include "tools/altvstime.h"
47 #include "tools/eyepiecefield.h"
48 #include "tools/wutdialog.h"
49 
50 #ifdef HAVE_INDI
51 #include <basedevice.h>
52 #include "indi/indilistener.h"
53 #include "indi/drivermanager.h"
54 #include "indi/driverinfo.h"
55 #include "ekos/manager.h"
56 #endif
57 
58 #include <KPlotting/KPlotAxis>
59 #include <KPlotting/KPlotObject>
60 
61 #include <kstars_debug.h>
62 
63 //
64 // ObservingListUI
65 // ---------------------------------
66 ObservingListUI::ObservingListUI(QWidget *p) : QFrame(p)
67 {
68  setupUi(this);
69 }
70 
71 //
72 // ObservingList
73 // ---------------------------------
74 ObservingList::ObservingList()
75  : QDialog((QWidget *)KStars::Instance()), LogObject(nullptr), m_CurrentObject(nullptr), isModified(false), m_dl(nullptr)
76 {
77 #ifdef Q_OS_OSX
78  setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
79 #endif
80  ui = new ObservingListUI(this);
81  QVBoxLayout *mainLayout = new QVBoxLayout;
82  mainLayout->addWidget(ui);
83  setWindowTitle(i18n("Observation Planner"));
84 
85  setLayout(mainLayout);
86 
87  dt = KStarsDateTime::currentDateTime();
88  setFocusPolicy(Qt::StrongFocus);
89  geo = KStarsData::Instance()->geo();
90  sessionView = false;
91  m_listFileName = QString();
92  pmenu.reset(new ObsListPopupMenu());
93  //Set up the Table Views
94  m_WishListModel.reset(new QStandardItemModel(0, 5, this));
95  m_SessionModel.reset(new QStandardItemModel(0, 5));
96 
97  m_WishListModel->setHorizontalHeaderLabels(
98  QStringList() << i18n("Name") << i18n("Alternate Name") << i18nc("Right Ascension", "RA (J2000)")
99  << i18nc("Declination", "Dec (J2000)") << i18nc("Magnitude", "Mag") << i18n("Type")
100  << i18n("Current Altitude"));
101  m_SessionModel->setHorizontalHeaderLabels(
102  QStringList() << i18n("Name") << i18n("Alternate Name") << i18nc("Right Ascension", "RA (J2000)")
103  << i18nc("Declination", "Dec (J2000)") << i18nc("Magnitude", "Mag") << i18n("Type")
104  << i18nc("Constellation", "Constell.") << i18n("Time") << i18nc("Altitude", "Alt")
105  << i18nc("Azimuth", "Az"));
106 
107  m_WishListSortModel.reset(new QSortFilterProxyModel(this));
108  m_WishListSortModel->setSourceModel(m_WishListModel.get());
109  m_WishListSortModel->setDynamicSortFilter(true);
110  m_WishListSortModel->setSortRole(Qt::UserRole);
111  ui->WishListView->setModel(m_WishListSortModel.get());
112  ui->WishListView->horizontalHeader()->setStretchLastSection(true);
113 
114  ui->WishListView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
115  m_SessionSortModel.reset(new SessionSortFilterProxyModel());
116  m_SessionSortModel->setSourceModel(m_SessionModel.get());
117  m_SessionSortModel->setDynamicSortFilter(true);
118  ui->SessionView->setModel(m_SessionSortModel.get());
119  ui->SessionView->horizontalHeader()->setStretchLastSection(true);
120  ui->SessionView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
121  ksal.reset(new KSAlmanac);
122  ksal->setLocation(geo);
123  ui->avt->setGeoLocation(geo);
124  ui->avt->setSunRiseSetTimes(ksal->getSunRise(), ksal->getSunSet());
125  ui->avt->setLimits(-12.0, 12.0, -90.0, 90.0);
126  ui->avt->axis(KPlotWidget::BottomAxis)->setTickLabelFormat('t');
127  ui->avt->axis(KPlotWidget::BottomAxis)->setLabel(i18n("Local Time"));
128  ui->avt->axis(KPlotWidget::TopAxis)->setTickLabelFormat('t');
129  ui->avt->axis(KPlotWidget::TopAxis)->setTickLabelsShown(true);
130  ui->DateEdit->setDate(dt.date());
131  ui->SetLocation->setText(geo->fullName());
132  ui->ImagePreview->installEventFilter(this);
133  ui->WishListView->viewport()->installEventFilter(this);
134  ui->WishListView->installEventFilter(this);
135  ui->SessionView->viewport()->installEventFilter(this);
136  ui->SessionView->installEventFilter(this);
137  // setDefaultImage();
138  //Connections
139  connect(ui->WishListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotCenterObject()));
140  connect(ui->WishListView->selectionModel(),
141  SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(slotNewSelection()));
142  connect(ui->SessionView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
143  this, SLOT(slotNewSelection()));
144  connect(ui->WUTButton, SIGNAL(clicked()), this, SLOT(slotWUT()));
145  connect(ui->FindButton, SIGNAL(clicked()), this, SLOT(slotFind()));
146  connect(ui->OpenButton, SIGNAL(clicked()), this, SLOT(slotOpenList()));
147  connect(ui->SaveButton, SIGNAL(clicked()), this, SLOT(slotSaveSession()));
148  connect(ui->SaveAsButton, SIGNAL(clicked()), this, SLOT(slotSaveSessionAs()));
149  connect(ui->WizardButton, SIGNAL(clicked()), this, SLOT(slotWizard()));
150  connect(ui->SetLocation, SIGNAL(clicked()), this, SLOT(slotLocation()));
151  connect(ui->Update, SIGNAL(clicked()), this, SLOT(slotUpdate()));
152  connect(ui->DeleteImage, SIGNAL(clicked()), this, SLOT(slotDeleteCurrentImage()));
153  connect(ui->SearchImage, SIGNAL(clicked()), this, SLOT(slotSearchImage()));
154  connect(ui->SetTime, SIGNAL(clicked()), this, SLOT(slotSetTime()));
155  connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotChangeTab(int)));
156  connect(ui->saveImages, SIGNAL(clicked()), this, SLOT(slotSaveAllImages()));
157  connect(ui->DeleteAllImages, SIGNAL(clicked()), this, SLOT(slotDeleteAllImages()));
158  connect(ui->OALExport, SIGNAL(clicked()), this, SLOT(slotOALExport()));
159  connect(ui->clearListB, SIGNAL(clicked()), this, SLOT(slotClearList()));
160  //Add icons to Push Buttons
161  ui->OpenButton->setIcon(QIcon::fromTheme("document-open"));
162  ui->OpenButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
163  ui->SaveButton->setIcon(QIcon::fromTheme("document-save"));
164  ui->SaveButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
165  ui->SaveAsButton->setIcon(
166  QIcon::fromTheme("document-save-as"));
167  ui->SaveAsButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
168  ui->WizardButton->setIcon(QIcon::fromTheme("tools-wizard"));
169  ui->WizardButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
170  noSelection = true;
171  showScope = false;
172  ui->NotesEdit->setEnabled(false);
173  ui->SetTime->setEnabled(false);
174  ui->TimeEdit->setEnabled(false);
175  ui->SearchImage->setEnabled(false);
176  ui->saveImages->setEnabled(false);
177  ui->DeleteImage->setEnabled(false);
178  ui->OALExport->setEnabled(false);
179 
180  m_NoImagePixmap =
181  QPixmap(":/images/noimage.png")
182  .scaled(ui->ImagePreview->width(), ui->ImagePreview->height(), Qt::KeepAspectRatio, Qt::FastTransformation);
183  m_altCostHelper = [this](const SkyPoint & p) -> QStandardItem *
184  {
185  const double inf = std::numeric_limits<double>::infinity();
186  double altCost = 0.;
187  QString itemText;
188  double maxAlt = p.maxAlt(*(geo->lat()));
189  if (Options::obsListDemoteHole() && maxAlt > 90. - Options::obsListHoleSize())
190  maxAlt = 90. - Options::obsListHoleSize();
191  if (maxAlt <= 0.)
192  {
193  altCost = -inf;
194  itemText = i18n("Never rises");
195  }
196  else
197  {
198  altCost = (p.alt().Degrees() / maxAlt) * 100.;
199  if (altCost < 0)
200  itemText = i18nc("Short text to describe that object has not risen yet", "Not risen");
201  else
202  {
203  if (altCost > 100.)
204  {
205  altCost = -inf;
206  itemText = i18nc("Object is in the Dobsonian hole", "In hole");
207  }
208  else
209  itemText = QString::number(altCost, 'f', 0) + '%';
210  }
211  }
212 
213  QStandardItem *altItem = new QStandardItem(itemText);
214  altItem->setData(altCost, Qt::UserRole);
215  // qCDebug(KSTARS) << "Updating altitude for " << p.ra().toHMSString() << " " << p.dec().toDMSString() << " alt = " << p.alt().toDMSString() << " info to " << itemText;
216  return altItem;
217  };
218 
219  // Needed to fix weird bug on Windows that started with Qt 5.9 that makes the title bar
220  // not visible and therefore dialog not movable.
221 #ifdef Q_OS_WIN
222  move(100, 100);
223 #endif
224 }
225 
226 void ObservingList::showEvent(QShowEvent *)
227 {
228  // ONLY run for first ever load
229 
230  if (m_initialWishlistLoad == false)
231  {
232  m_initialWishlistLoad = true;
233 
234  slotLoadWishList(); //Load the wishlist from disk if present
235  m_CurrentObject = nullptr;
236  setSaveImagesButton();
237 
238  slotUpdateAltitudes();
239  m_altitudeUpdater = new QTimer(this);
240  connect(m_altitudeUpdater, SIGNAL(timeout()), this, SLOT(slotUpdateAltitudes()));
241  m_altitudeUpdater->start(120000); // update altitudes every 2 minutes
242  }
243 }
244 
245 //SLOTS
246 
247 void ObservingList::slotAddObject(const SkyObject *_obj, bool session, bool update)
248 {
249  bool addToWishList = true;
250  if (!_obj)
251  _obj = SkyMap::Instance()->clickedObject(); // Eh? Why? Weird default behavior.
252 
253  if (!_obj)
254  {
255  qCWarning(KSTARS) << "Trying to add null object to observing list! Ignoring.";
256  return;
257  }
258 
259  QString finalObjectName = getObjectName(_obj);
260 
261  if (finalObjectName.isEmpty())
262  {
263  KSNotification::sorry(i18n("Unnamed stars are not supported in the observing lists"));
264  return;
265  }
266 
267  //First, make sure object is not already in the list
268  QSharedPointer<SkyObject> obj = findObject(_obj);
269  if (obj)
270  {
271  addToWishList = false;
272  if (!session)
273  {
274  KStars::Instance()->statusBar()->showMessage(
275  i18n("%1 is already in your wishlist.", finalObjectName),
276  0); // FIXME: This message is too inconspicuous if using the Find dialog to add
277  return;
278  }
279  }
280  else
281  {
282  assert(!findObject(_obj, session));
283  qCDebug(KSTARS) << "Cloned object " << finalObjectName << " to add to observing list.";
284  obj = QSharedPointer<SkyObject>(
285  _obj->clone()); // Use a clone in case the original SkyObject is deleted due to change in catalog configuration.
286  }
287 
288  if (session && sessionList().contains(obj))
289  {
290  KStars::Instance()->statusBar()->showMessage(i18n("%1 is already in the session plan.", finalObjectName), 0);
291  return;
292  }
293 
294  // JM: If we are loading observing list from disk, solar system objects magnitudes are not calculated until later
295  // Therefore, we manual invoke updateCoords to force computation of magnitude.
296  if ((obj->type() == SkyObject::COMET || obj->type() == SkyObject::ASTEROID || obj->type() == SkyObject::MOON ||
297  obj->type() == SkyObject::PLANET) &&
298  obj->mag() == 0)
299  {
300  KSNumbers num(dt.djd());
301  CachingDms LST = geo->GSTtoLST(dt.gst());
302  obj->updateCoords(&num, true, geo->lat(), &LST, true);
303  }
304 
305  QString smag = "--";
306  if (-30.0 < obj->mag() && obj->mag() < 90.0)
307  smag = QString::number(obj->mag(), 'f', 2); // The lower limit to avoid display of unrealistic comet magnitudes
308 
309  SkyPoint p = obj->recomputeHorizontalCoords(dt, geo);
310 
311  QList<QStandardItem *> itemList;
312 
313  auto getItemWithUserRole = [](const QString & itemText) -> QStandardItem *
314  {
315  QStandardItem *ret = new QStandardItem(itemText);
316  ret->setData(itemText, Qt::UserRole);
317  return ret;
318  };
319 
320  // Fill itemlist with items that are common to both wishlist additions and session plan additions
321  auto populateItemList = [&getItemWithUserRole, &itemList, &finalObjectName, obj, &p, &smag]()
322  {
323  itemList.clear();
324  QStandardItem *keyItem = getItemWithUserRole(finalObjectName);
325  keyItem->setData(QVariant::fromValue<void *>(static_cast<void *>(obj.data())), Qt::UserRole + 1);
326  itemList
327  << keyItem // NOTE: The rest of the methods assume that the SkyObject pointer is available in the first column!
328  << getItemWithUserRole(obj->translatedLongName()) << getItemWithUserRole(p.ra0().toHMSString())
329  << getItemWithUserRole(p.dec0().toDMSString()) << getItemWithUserRole(smag)
330  << getItemWithUserRole(obj->typeName());
331  };
332 
333  //Insert object in the Wish List
334  if (addToWishList)
335  {
336  m_WishList.append(obj);
337  m_CurrentObject = obj.data();
338 
339  //QString ra, dec;
340  //ra = "";//p.ra().toHMSString();
341  //dec = p.dec().toDMSString();
342 
343  populateItemList();
344  // FIXME: Instead sort by a "clever" observability score, calculated as follows:
345  // - First sort by (max altitude) - (current altitude) rounded off to the nearest
346  // - Weight by declination - latitude (in the northern hemisphere, southern objects get higher precedence)
347  // - Demote objects in the hole
348  SkyPoint p = obj->recomputeHorizontalCoords(KStarsDateTime::currentDateTimeUtc(), geo); // Current => now
349  itemList << m_altCostHelper(p);
350  m_WishListModel->appendRow(itemList);
351 
352  //Note addition in statusbar
353  KStars::Instance()->statusBar()->showMessage(i18n("Added %1 to observing list.", finalObjectName), 0);
354  ui->WishListView->resizeColumnsToContents();
355  if (!update)
356  slotSaveList();
357  }
358  //Insert object in the Session List
359  if (session)
360  {
361  m_SessionList.append(obj);
362  dt.setTime(TimeHash.value(finalObjectName, obj->transitTime(dt, geo)));
363  dms lst(geo->GSTtoLST(dt.gst()));
364  p.EquatorialToHorizontal(&lst, geo->lat());
365 
366  QString alt = "--", az = "--";
367 
368  QStandardItem *BestTime = new QStandardItem();
369  /* QString ra, dec;
370  if(obj->name() == "star" ) {
371  ra = obj->ra0().toHMSString();
372  dec = obj->dec0().toDMSString();
373  BestTime->setData( QString( "--" ), Qt::DisplayRole );
374  }
375  else {*/
376  BestTime->setData(TimeHash.value(finalObjectName, obj->transitTime(dt, geo)), Qt::DisplayRole);
377  alt = p.alt().toDMSString();
378  az = p.az().toDMSString();
379  //}
380  // TODO: Change the rest of the parameters to their appropriate datatypes.
381  populateItemList();
382  itemList << getItemWithUserRole(KSUtils::constNameToAbbrev(
383  KStarsData::Instance()->skyComposite()->constellationBoundary()->constellationName(obj.data())))
384  << BestTime << getItemWithUserRole(alt) << getItemWithUserRole(az);
385 
386  m_SessionModel->appendRow(itemList);
387  //Adding an object should trigger the modified flag
388  isModified = true;
389  ui->SessionView->resizeColumnsToContents();
390  //Note addition in statusbar
391  KStars::Instance()->statusBar()->showMessage(i18n("Added %1 to session list.", finalObjectName), 0);
392  SkyMap::Instance()->forceUpdate();
393  }
394  setSaveImagesButton();
395 }
396 
397 void ObservingList::slotRemoveObject(const SkyObject *_o, bool session, bool update)
398 {
399  if (!update) // EH?!
400  {
401  if (!_o)
402  _o = SkyMap::Instance()->clickedObject();
403  else if (sessionView) //else if is needed as clickedObject should not be removed from the session list.
404  session = true;
405  }
406 
407  // Is the pointer supplied in our own lists?
408  const QList<QSharedPointer<SkyObject>> &list = (session ? sessionList() : obsList());
409  QStandardItemModel *currentModel = (session ? m_SessionModel.get() : m_WishListModel.get());
410 
411  QSharedPointer<SkyObject> o = findObject(_o, session);
412  if (!o)
413  {
414  qWarning() << "Object (name: " << getObjectName(o.data())
415  << ") supplied to ObservingList::slotRemoveObject() was not found in the "
416  << QString(session ? "session" : "observing") << " list!";
417  return;
418  }
419 
420  int k = list.indexOf(o);
421  assert(k >= 0);
422 
423  // Remove from hash
424  ImagePreviewHash.remove(o.data());
425 
426  if (o.data() == LogObject)
427  saveCurrentUserLog();
428 
429  //Remove row from the TableView model
430  // FIXME: Is there no faster way?
431  for (int irow = 0; irow < currentModel->rowCount(); ++irow)
432  {
433  QString name = currentModel->item(irow, 0)->text();
434  if (getObjectName(o.data()) == name)
435  {
436  currentModel->removeRow(irow);
437  break;
438  }
439  }
440 
441  if (!session)
442  {
443  obsList().removeAt(k);
444  ui->avt->removeAllPlotObjects();
445  ui->WishListView->resizeColumnsToContents();
446  if (!update)
447  slotSaveList();
448  }
449  else
450  {
451  if (!update)
452  TimeHash.remove(o->name());
453  sessionList().removeAt(k); //Remove from the session list
454  isModified = true; //Removing an object should trigger the modified flag
455  ui->avt->removeAllPlotObjects();
456  ui->SessionView->resizeColumnsToContents();
457  SkyMap::Instance()->forceUpdate();
458  }
459 }
460 
461 void ObservingList::slotRemoveSelectedObjects()
462 {
463  //Find each object by name in the session list, and remove it
464  //Go backwards so item alignment doesn't get screwed up as rows are removed.
465  for (int irow = getActiveModel()->rowCount() - 1; irow >= 0; --irow)
466  {
467  bool rowSelected;
468  if (sessionView)
469  rowSelected = ui->SessionView->selectionModel()->isRowSelected(irow, QModelIndex());
470  else
471  rowSelected = ui->WishListView->selectionModel()->isRowSelected(irow, QModelIndex());
472 
473  if (rowSelected)
474  {
475  QModelIndex sortIndex, index;
476  sortIndex = getActiveSortModel()->index(irow, 0);
477  index = getActiveSortModel()->mapToSource(sortIndex);
478  SkyObject *o = static_cast<SkyObject *>(index.data(Qt::UserRole + 1).value<void *>());
479  Q_ASSERT(o);
480  slotRemoveObject(o, sessionView);
481  }
482  }
483 
484  if (sessionView)
485  {
486  //we've removed all selected objects, so clear the selection
487  ui->SessionView->selectionModel()->clear();
488  //Update the lists in the Execute window as well
489  KStarsData::Instance()->executeSession()->init();
490  }
491 
492  setSaveImagesButton();
493  ui->ImagePreview->setCursor(Qt::ArrowCursor);
494 }
495 
496 void ObservingList::slotNewSelection()
497 {
498  bool found = false;
499  singleSelection = false;
500  noSelection = false;
501  showScope = false;
502  //ui->ImagePreview->clearPreview();
503  //ui->ImagePreview->setPixmap(QPixmap());
504  ui->ImagePreview->setCursor(Qt::ArrowCursor);
505  QModelIndexList selectedItems;
506  QString newName;
507  QSharedPointer<SkyObject> o;
508  QString labelText;
509  ui->DeleteImage->setEnabled(false);
510 
511  selectedItems =
512  getActiveSortModel()->mapSelectionToSource(getActiveView()->selectionModel()->selection()).indexes();
513 
514  if (selectedItems.size() == getActiveModel()->columnCount())
515  {
516  newName = selectedItems[0].data().toString();
517  singleSelection = true;
518  //Find the selected object in the SessionList,
519  //then break the loop. Now SessionList.current()
520  //points to the new selected object (until now it was the previous object)
521  for (auto &o_temp : getActiveList())
522  {
523  if (getObjectName(o_temp.data()) == newName)
524  {
525  o = o_temp;
526  found = true;
527  break;
528  }
529  }
530  }
531 
532  if (singleSelection)
533  {
534  //Enable buttons
535  ui->ImagePreview->setCursor(Qt::PointingHandCursor);
536 #ifdef HAVE_INDI
537  showScope = true;
538 #endif
539  if (found)
540  {
541  m_CurrentObject = o.data();
542  //QPoint pos(0,0);
543  plot(o.data());
544  //Change the m_currentImageFileName, DSS/SDSS Url to correspond to the new object
545  setCurrentImage(o.data());
546  ui->SearchImage->setEnabled(true);
547  if (newName != i18n("star"))
548  {
549  //Display the current object's user notes in the NotesEdit
550  //First, save the last object's user log to disk, if necessary
551  saveCurrentUserLog(); //uses LogObject, which is still the previous obj.
552  //set LogObject to the new selected object
553  LogObject = currentObject();
554  ui->NotesEdit->setEnabled(true);
555  if (LogObject->userLog().isEmpty())
556  {
557  ui->NotesEdit->setPlainText(
558  i18n("Record here observation logs and/or data on %1.", getObjectName(LogObject)));
559  }
560  else
561  {
562  ui->NotesEdit->setPlainText(LogObject->userLog());
563  }
564  if (sessionView)
565  {
566  ui->TimeEdit->setEnabled(true);
567  ui->SetTime->setEnabled(true);
568  ui->TimeEdit->setTime(TimeHash.value(o->name(), o->transitTime(dt, geo)));
569  }
570  }
571  else //selected object is named "star"
572  {
573  //clear the log text box
574  saveCurrentUserLog();
575  ui->NotesEdit->clear();
576  ui->NotesEdit->setEnabled(false);
577  ui->SearchImage->setEnabled(false);
578  }
579  QString ImagePath = KSPaths::locate(QStandardPaths::GenericDataLocation, m_currentImageFileName);
580  if (!ImagePath.isEmpty())
581  {
582  //If the image is present, show it!
583  KSDssImage ksdi(ImagePath);
584  KSDssImage::Metadata md = ksdi.getMetadata();
585  //ui->ImagePreview->showPreview( QUrl::fromLocalFile( ksdi.getFileName() ) );
586  if (ImagePreviewHash.contains(o.data()) == false)
587  ImagePreviewHash[o.data()] = QPixmap(ksdi.getFileName()).scaledToHeight(ui->ImagePreview->width());
588 
589  //ui->ImagePreview->setPixmap(QPixmap(ksdi.getFileName()).scaledToHeight(ui->ImagePreview->width()));
590  ui->ImagePreview->setPixmap(ImagePreviewHash[o.data()]);
591  if (md.isValid())
592  {
593  ui->dssMetadataLabel->setText(
594  i18n("DSS Image metadata: \n Size: %1\' x %2\' \n Photometric band: %3 \n Version: %4",
595  QString::number(md.width), QString::number(md.height), QString() + md.band, md.version));
596  }
597  else
598  ui->dssMetadataLabel->setText(i18n("No image info available."));
599  ui->ImagePreview->show();
600  ui->DeleteImage->setEnabled(true);
601  }
602  else
603  {
604  setDefaultImage();
605  ui->dssMetadataLabel->setText(
606  i18n("No image available. Click on the placeholder image to download one."));
607  }
608  QString cname =
609  KStarsData::Instance()->skyComposite()->constellationBoundary()->constellationName(o.data());
610  if (o->type() != SkyObject::CONSTELLATION)
611  {
612  labelText = "<b>";
613  if (o->type() == SkyObject::PLANET)
614  labelText += o->translatedName();
615  else
616  labelText += o->name();
617  if (std::isfinite(o->mag()) && o->mag() <= 30.)
618  labelText += ":</b> " + i18nc("%1 magnitude of object, %2 type of sky object (planet, asteroid "
619  "etc), %3 name of a constellation",
620  "%1 mag %2 in %3", o->mag(), o->typeName().toLower(), cname);
621  else
622  labelText +=
623  ":</b> " + i18nc("%1 type of sky object (planet, asteroid etc), %2 name of a constellation",
624  "%1 in %2", o->typeName(), cname);
625  }
626  }
627  else
628  {
629  setDefaultImage();
630  qCWarning(KSTARS) << "Object " << newName << " not found in list.";
631  }
632  ui->quickInfoLabel->setText(labelText);
633  }
634  else
635  {
636  if (selectedItems.isEmpty()) //Nothing selected
637  {
638  //Disable buttons
639  noSelection = true;
640  ui->NotesEdit->setEnabled(false);
641  m_CurrentObject = nullptr;
642  ui->TimeEdit->setEnabled(false);
643  ui->SetTime->setEnabled(false);
644  ui->SearchImage->setEnabled(false);
645  //Clear the user log text box.
646  saveCurrentUserLog();
647  ui->NotesEdit->setPlainText("");
648  //Clear the plot in the AVTPlotwidget
649  ui->avt->removeAllPlotObjects();
650  }
651  else //more than one object selected.
652  {
653  ui->NotesEdit->setEnabled(false);
654  ui->TimeEdit->setEnabled(false);
655  ui->SetTime->setEnabled(false);
656  ui->SearchImage->setEnabled(false);
657  m_CurrentObject = nullptr;
658  //Clear the plot in the AVTPlotwidget
659  ui->avt->removeAllPlotObjects();
660  //Clear the user log text box.
661  saveCurrentUserLog();
662  ui->NotesEdit->setPlainText("");
663  ui->quickInfoLabel->setText(QString());
664  }
665  }
666 }
667 
668 void ObservingList::slotCenterObject()
669 {
670  if (getSelectedItems().size() == 1)
671  {
672  SkyMap::Instance()->setClickedObject(currentObject());
673  SkyMap::Instance()->setClickedPoint(currentObject());
674  SkyMap::Instance()->slotCenter();
675  }
676 }
677 
678 void ObservingList::slotSlewToObject()
679 {
680 #ifdef HAVE_INDI
681 
682  if (INDIListener::Instance()->size() == 0)
683  {
684  KSNotification::sorry(i18n("KStars did not find any active telescopes."));
685  return;
686  }
687 
688  foreach (ISD::GDInterface *gd, INDIListener::Instance()->getDevices())
689  {
690  INDI::BaseDevice *bd = gd->getBaseDevice();
691 
692  if (gd->getType() != KSTARS_TELESCOPE)
693  continue;
694 
695  if (bd == nullptr)
696  continue;
697 
698  if (bd->isConnected() == false)
699  {
700  KSNotification::error(
701  i18n("Telescope %1 is offline. Please connect and retry again.", gd->getDeviceName()));
702  return;
703  }
704 
705  ISD::GDSetCommand SlewCMD(INDI_SWITCH, "ON_COORD_SET", "TRACK", ISS_ON, this);
706 
707  gd->setProperty(&SlewCMD);
708  gd->runCommand(INDI_SEND_COORDS, currentObject());
709 
710  return;
711  }
712 
713  KSNotification::sorry(i18n("KStars did not find any active telescopes."));
714 
715 #endif
716 }
717 
718 void ObservingList::slotAddToEkosScheduler()
719 {
720 #ifdef HAVE_INDI
721  KStars::Instance()->ekosManager()->addObjectToScheduler(currentObject());
722 #endif
723 }
724 
725 //FIXME: This will open multiple Detail windows for each object;
726 //Should have one window whose target object changes with selection
727 void ObservingList::slotDetails()
728 {
729  if (currentObject())
730  {
731  QPointer<DetailDialog> dd =
732  new DetailDialog(currentObject(), KStarsData::Instance()->ut(), geo, KStars::Instance());
733  dd->exec();
734  delete dd;
735  }
736 }
737 
738 void ObservingList::slotWUT()
739 {
740  KStarsDateTime lt = dt;
741  lt.setTime(QTime(8, 0, 0));
742  QPointer<WUTDialog> w = new WUTDialog(KStars::Instance(), sessionView, geo, lt);
743  w->exec();
744  delete w;
745 }
746 
747 void ObservingList::slotAddToSession()
748 {
749  Q_ASSERT(!sessionView);
750  if (getSelectedItems().size())
751  {
752  foreach (const QModelIndex &i, getSelectedItems())
753  {
754  foreach (QSharedPointer<SkyObject> o, obsList())
755  if (getObjectName(o.data()) == i.data().toString())
756  slotAddObject(
757  o.data(),
758  true); // FIXME: Would be good to have a wrapper that accepts QSharedPointer<SkyObject>
759  }
760  }
761 }
762 
763 void ObservingList::slotFind()
764 {
765  if (FindDialog::Instance()->exec() == QDialog::Accepted)
766  {
767  SkyObject *o = FindDialog::Instance()->targetObject();
768  if (o != nullptr)
769  {
770  slotAddObject(o, sessionView);
771  }
772  }
773 }
774 
775 void ObservingList::slotEyepieceView()
776 {
777  KStars::Instance()->slotEyepieceView(currentObject(), getCurrentImagePath());
778 }
779 
780 void ObservingList::slotAVT()
781 {
782  QModelIndexList selectedItems;
783  // TODO: Think and see if there's a more efficient way to do this. I can't seem to think of any, but this code looks like it could be improved. - Akarsh
784  selectedItems =
785  (sessionView ?
786  m_SessionSortModel->mapSelectionToSource(ui->SessionView->selectionModel()->selection()).indexes() :
787  m_WishListSortModel->mapSelectionToSource(ui->WishListView->selectionModel()->selection()).indexes());
788 
789  if (selectedItems.size())
790  {
791  QPointer<AltVsTime> avt = new AltVsTime(KStars::Instance());
792  foreach (const QModelIndex &i, selectedItems)
793  {
794  if (i.column() == 0)
795  {
796  SkyObject *o = static_cast<SkyObject *>(i.data(Qt::UserRole + 1).value<void *>());
797  Q_ASSERT(o);
798  avt->processObject(o);
799  }
800  }
801  avt->exec();
802  delete avt;
803  }
804 }
805 
806 //FIXME: On close, we will need to close any open Details/AVT windows
807 void ObservingList::slotClose()
808 {
809  //Save the current User log text
810  saveCurrentUserLog();
811  ui->avt->removeAllPlotObjects();
812  slotNewSelection();
813  saveCurrentList();
814  hide();
815 }
816 
817 void ObservingList::saveCurrentUserLog()
818 {
819  if (LogObject && !ui->NotesEdit->toPlainText().isEmpty() &&
820  ui->NotesEdit->toPlainText() !=
821  i18n("Record here observation logs and/or data on %1.", getObjectName(LogObject)))
822  {
823  LogObject->saveUserLog(ui->NotesEdit->toPlainText());
824  ui->NotesEdit->clear();
825  LogObject = nullptr;
826  }
827 }
828 
829 void ObservingList::slotOpenList()
830 {
831  QUrl fileURL = QFileDialog::getOpenFileUrl(KStars::Instance(), i18n("Open Observing List"), QUrl(),
832  "KStars Observing List (*.obslist)");
833  QFile f;
834 
835  if (fileURL.isValid())
836  {
837  f.setFileName(fileURL.toLocalFile());
838  //FIXME do we still need to do this?
839  /*
840  if ( ! fileURL.isLocalFile() ) {
841  //Save remote list to a temporary local file
842  QTemporaryFile tmpfile;
843  tmpfile.setAutoRemove(false);
844  tmpfile.open();
845  m_listFileName = tmpfile.fileName();
846  if( KIO::NetAccess::download( fileURL, m_listFileName, this ) )
847  f.setFileName( m_listFileName );
848 
849  } else {
850  m_listFileName = fileURL.toLocalFile();
851  f.setFileName( m_listFileName );
852  }
853  */
854 
855  if (!f.open(QIODevice::ReadOnly))
856  {
857  QString message = i18n("Could not open file %1", f.fileName());
858  KSNotification::sorry(message, i18n("Could Not Open File"));
859  return;
860  }
861  saveCurrentList(); //See if the current list needs to be saved before opening the new one
862  ui->tabWidget->setCurrentIndex(1);
863  slotChangeTab(1);
864 
865  sessionList().clear();
866  TimeHash.clear();
867  m_CurrentObject = nullptr;
868  m_SessionModel->removeRows(0, m_SessionModel->rowCount());
869  SkyMap::Instance()->forceUpdate();
870  //First line is the name of the list. The rest of the file is
871  //object names, one per line. With the TimeHash value if present
872  QTextStream istream(&f);
873  QString input;
874  input = istream.readAll();
875  OAL::Log logObject;
876  logObject.readBegin(input);
877  //Set the New TimeHash
878  TimeHash = logObject.timeHash();
879  geo = logObject.geoLocation();
880  dt = logObject.dateTime();
881  //foreach (SkyObject *o, *(logObject.targetList()))
882  for (auto &o : logObject.targetList())
883  slotAddObject(o.data(), true);
884  //Update the location and user set times from file
885  slotUpdate();
886  //Newly-opened list should not trigger isModified flag
887  isModified = false;
888  f.close();
889  }
890  else if (!fileURL.toLocalFile().isEmpty())
891  {
892  KSNotification::sorry(i18n("The specified file is invalid"));
893  }
894 }
895 
896 void ObservingList::slotClearList()
897 {
898  if ((ui->tabWidget->currentIndex() == 0 && obsList().isEmpty()) ||
899  (ui->tabWidget->currentIndex() == 1 && sessionList().isEmpty()))
900  return;
901 
902  QString message = i18n("Are you sure you want to clear all objects?");
903  if (KMessageBox::questionYesNo(this, message, i18n("Clear all?")) == KMessageBox::Yes)
904  {
905  // Did I forget anything else to remove?
906  ui->avt->removeAllPlotObjects();
907  m_CurrentObject = LogObject = nullptr;
908 
909  if (ui->tabWidget->currentIndex() == 0)
910  {
911  // IMPORTANT: Is this enough or we will have dangling pointers in memory?
912  ImagePreviewHash.clear();
913  obsList().clear();
914  m_WishListModel->setRowCount(0);
915  }
916  else
917  {
918  // IMPORTANT: Is this enough or we will have dangling pointers in memory?
919  sessionList().clear();
920  TimeHash.clear();
921  isModified = true; //Removing an object should trigger the modified flag
922  m_SessionModel->setRowCount(0);
923  SkyMap::Instance()->forceUpdate();
924  }
925  }
926 }
927 
928 void ObservingList::saveCurrentList()
929 {
930  //Before loading a new list, do we need to save the current one?
931  //Assume that if the list is empty, then there's no need to save
932  if (sessionList().size())
933  {
934  if (isModified)
935  {
936  QString message = i18n("Do you want to save the current session?");
937  if (KMessageBox::questionYesNo(this, message, i18n("Save Current session?"), KStandardGuiItem::save(),
938  KStandardGuiItem::discard()) == KMessageBox::Yes)
939  slotSaveSession();
940  }
941  }
942 }
943 
944 void ObservingList::slotSaveSessionAs(bool nativeSave)
945 {
946  if (sessionList().isEmpty())
947  return;
948 
949  QUrl fileURL = QFileDialog::getSaveFileUrl(KStars::Instance(), i18n("Save Observing List"), QUrl(),
950  "KStars Observing List (*.obslist)");
951  if (fileURL.isValid())
952  {
953  m_listFileName = fileURL.toLocalFile();
954  slotSaveSession(nativeSave);
955  }
956 }
957 
958 void ObservingList::slotSaveList()
959 {
960  QFile f;
961  // FIXME: Move wishlist into a database.
962  // TODO: Support multiple wishlists.
963 
964  QString fileContents;
965  QTextStream ostream(
966  &fileContents); // We first write to a QString to prevent truncating the file in case there is a crash.
967  foreach (const QSharedPointer<SkyObject> o, obsList())
968  {
969  if (!o)
970  {
971  qWarning() << "Null entry in observing wishlist! Skipping!";
972  continue;
973  }
974  if (o->name() == "star")
975  {
976  //ostream << o->name() << " " << o->ra0().Hours() << " " << o->dec0().Degrees() << endl;
977  ostream << getObjectName(o.data(), false) << endl;
978  }
979  else if (o->type() == SkyObject::STAR)
980  {
981  Q_ASSERT(dynamic_cast<const StarObject *>(o.data()));
982  const QSharedPointer<StarObject> s = qSharedPointerCast<StarObject>(o);
983  if (s->name() == s->gname())
984  ostream << s->name2() << endl;
985  else
986  ostream << s->name() << endl;
987  }
988  else
989  {
990  ostream << o->name() << endl;
991  }
992  }
993  f.setFileName(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "wishlist.obslist");
994  if (!f.open(QIODevice::WriteOnly))
995  {
996  qWarning() << "Cannot save wish list to file!"; // TODO: This should be presented as a message box to the user
997  return;
998  }
999  QTextStream writeemall(&f);
1000  writeemall << fileContents;
1001  f.close();
1002 }
1003 
1004 void ObservingList::slotLoadWishList()
1005 {
1006  QFile f;
1007  f.setFileName(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "wishlist.obslist");
1008  if (!f.open(QIODevice::ReadOnly))
1009  {
1010  qWarning(KSTARS) << "No WishList Saved yet";
1011  return;
1012  }
1013  QTextStream istream(&f);
1014  QString line;
1015 
1016  QPointer<QProgressDialog> addingObjectsProgress = new QProgressDialog();
1017  addingObjectsProgress->setWindowTitle(i18n("Observing List Wizard"));
1018  addingObjectsProgress->setLabelText(i18n("Please wait while loading objects..."));
1019  addingObjectsProgress->setMaximum(0);
1020  addingObjectsProgress->setMinimum(0);
1021  addingObjectsProgress->show();
1022  while (!istream.atEnd())
1023  {
1024  line = istream.readLine();
1025  //If the object is named "star", add it by coordinates
1026  SkyObject *o;
1027  /*if ( line.startsWith( QLatin1String( "star" ) ) ) {
1028  QStringList fields = line.split( ' ', QString::SkipEmptyParts );
1029  dms ra = dms::fromString( fields[1], false ); //false = hours
1030  dms dc = dms::fromString( fields[2], true ); //true = degrees
1031  SkyPoint p( ra, dc );
1032  double maxrad = 1000.0/Options::zoomFactor();
1033  o = ks->data()->skyComposite()->starNearest( &p, maxrad );
1034  }
1035  else {*/
1036  o = KStarsData::Instance()->objectNamed(line);
1037  //}
1038  //If we haven't identified the object, try interpreting the
1039  //name as a star's genetive name (with ascii letters)
1040  if (!o)
1041  o = KStarsData::Instance()->skyComposite()->findStarByGenetiveName(line);
1042  if (o)
1043  slotAddObject(o, false, true);
1044  if (addingObjectsProgress->wasCanceled())
1045  break;
1046  qApp->processEvents();
1047  }
1048  delete (addingObjectsProgress);
1049  f.close();
1050 }
1051 
1052 void ObservingList::slotSaveSession(bool nativeSave)
1053 {
1054  if (sessionList().isEmpty())
1055  {
1056  KSNotification::error(i18n("Cannot save an empty session list."));
1057  return;
1058  }
1059 
1060  if (m_listFileName.isEmpty())
1061  {
1062  slotSaveSessionAs(nativeSave);
1063  return;
1064  }
1065  QFile f(m_listFileName);
1066  if (!f.open(QIODevice::WriteOnly))
1067  {
1068  QString message = i18n("Could not open file %1. Try a different filename?", f.fileName());
1069  if (KMessageBox::warningYesNo(nullptr, message, i18n("Could Not Open File"), KGuiItem(i18n("Try Different")),
1070  KGuiItem(i18n("Do Not Try"))) == KMessageBox::Yes)
1071  {
1072  m_listFileName.clear();
1073  slotSaveSessionAs(nativeSave);
1074  }
1075  return;
1076  }
1077  QTextStream ostream(&f);
1078  OAL::Log log;
1079  ostream << log.writeLog(nativeSave);
1080  f.close();
1081  isModified = false; //We've saved the session, so reset the modified flag.
1082 }
1083 
1084 void ObservingList::slotWizard()
1085 {
1086  QPointer<ObsListWizard> wizard = new ObsListWizard(KStars::Instance());
1087  if (wizard->exec() == QDialog::Accepted)
1088  {
1089  QPointer<QProgressDialog> addingObjectsProgress = new QProgressDialog();
1090  addingObjectsProgress->setWindowTitle(i18n("Observing List Wizard"));
1091  addingObjectsProgress->setLabelText(i18n("Please wait while adding objects..."));
1092  addingObjectsProgress->setMaximum(wizard->obsList().size());
1093  addingObjectsProgress->setMinimum(0);
1094  addingObjectsProgress->setValue(0);
1095  addingObjectsProgress->show();
1096  int counter = 1;
1097  foreach (SkyObject *o, wizard->obsList())
1098  {
1099  slotAddObject(o);
1100  addingObjectsProgress->setValue(counter++);
1101  if (addingObjectsProgress->wasCanceled())
1102  break;
1103  qApp->processEvents();
1104  }
1105  delete addingObjectsProgress;
1106  }
1107 
1108  delete wizard;
1109 }
1110 
1111 void ObservingList::plot(SkyObject *o)
1112 {
1113  if (!o)
1114  return;
1115  float DayOffset = 0;
1116  if (TimeHash.value(o->name(), o->transitTime(dt, geo)).hour() > 12)
1117  DayOffset = 1;
1118 
1119  QDateTime midnight = QDateTime(dt.date(), QTime());
1120  KStarsDateTime ut = geo->LTtoUT(KStarsDateTime(midnight));
1121  double h1 = geo->GSTtoLST(ut.gst()).Hours();
1122  if (h1 > 12.0)
1123  h1 -= 24.0;
1124 
1125  ui->avt->setSecondaryLimits(h1, h1 + 24.0, -90.0, 90.0);
1126  ksal->setLocation(geo);
1127  ksal->setDate(&ut);
1128  ui->avt->setGeoLocation(geo);
1129  ui->avt->setSunRiseSetTimes(ksal->getSunRise(), ksal->getSunSet());
1130  ui->avt->setDawnDuskTimes(ksal->getDawnAstronomicalTwilight(), ksal->getDuskAstronomicalTwilight());
1131  ui->avt->setMinMaxSunAlt(ksal->getSunMinAlt(), ksal->getSunMaxAlt());
1132  ui->avt->setMoonRiseSetTimes(ksal->getMoonRise(), ksal->getMoonSet());
1133  ui->avt->setMoonIllum(ksal->getMoonIllum());
1134  ui->avt->update();
1135  KPlotObject *po = new KPlotObject(Qt::white, KPlotObject::Lines, 2.0);
1136  for (double h = -12.0; h <= 12.0; h += 0.5)
1137  {
1138  po->addPoint(h, findAltitude(o, (h + DayOffset * 24.0)));
1139  }
1140  ui->avt->removeAllPlotObjects();
1141  ui->avt->addPlotObject(po);
1142 }
1143 
1144 double ObservingList::findAltitude(SkyPoint *p, double hour)
1145 {
1146  // Jasem 2015-09-05 Using correct procedure to find altitude
1147  SkyPoint sp = *p; // make a copy
1148  QDateTime midnight = QDateTime(dt.date(), QTime());
1149  KStarsDateTime ut = geo->LTtoUT(KStarsDateTime(midnight));
1150  KStarsDateTime targetDateTime = ut.addSecs(hour * 3600.0);
1151  dms LST = geo->GSTtoLST(targetDateTime.gst());
1152  sp.EquatorialToHorizontal(&LST, geo->lat());
1153  return sp.alt().Degrees();
1154 }
1155 
1156 void ObservingList::slotChangeTab(int index)
1157 {
1158  noSelection = true;
1159  saveCurrentUserLog();
1160  ui->NotesEdit->setEnabled(false);
1161  ui->TimeEdit->setEnabled(false);
1162  ui->SetTime->setEnabled(false);
1163  ui->SearchImage->setEnabled(false);
1164  ui->DeleteImage->setEnabled(false);
1165  m_CurrentObject = nullptr;
1166  sessionView = index != 0;
1167  setSaveImagesButton();
1168  ui->WizardButton->setEnabled(!sessionView); //wizard adds only to the Wish List
1169  ui->OALExport->setEnabled(sessionView);
1170  //Clear the selection in the Tables
1171  ui->WishListView->clearSelection();
1172  ui->SessionView->clearSelection();
1173  //Clear the user log text box.
1174  saveCurrentUserLog();
1175  ui->NotesEdit->setPlainText("");
1176  ui->avt->removeAllPlotObjects();
1177 }
1178 
1179 void ObservingList::slotLocation()
1180 {
1181  QPointer<LocationDialog> ld = new LocationDialog(this);
1182  if (ld->exec() == QDialog::Accepted)
1183  {
1184  geo = ld->selectedCity();
1185  ui->SetLocation->setText(geo->fullName());
1186  }
1187  delete ld;
1188 }
1189 
1190 void ObservingList::slotUpdate()
1191 {
1192  dt.setDate(ui->DateEdit->date());
1193  ui->avt->removeAllPlotObjects();
1194  //Creating a copy of the lists, we can't use the original lists as they'll keep getting modified as the loop iterates
1195  QList<QSharedPointer<SkyObject>> _obsList = m_WishList, _SessionList = m_SessionList;
1196 
1197  for (QSharedPointer<SkyObject> &o : _obsList)
1198  {
1199  if (o->name() != "star")
1200  {
1201  slotRemoveObject(o.data(), false, true);
1202  slotAddObject(o.data(), false, true);
1203  }
1204  }
1205  for (QSharedPointer<SkyObject> &obj : _SessionList)
1206  {
1207  if (obj->name() != "star")
1208  {
1209  slotRemoveObject(obj.data(), true, true);
1210  slotAddObject(obj.data(), true, true);
1211  }
1212  }
1213  SkyMap::Instance()->forceUpdate();
1214 }
1215 
1216 void ObservingList::slotSetTime()
1217 {
1218  SkyObject *o = currentObject();
1219  slotRemoveObject(o, true);
1220  TimeHash[o->name()] = ui->TimeEdit->time();
1221  slotAddObject(o, true, true);
1222 }
1223 
1224 void ObservingList::slotCustomDSS()
1225 {
1226  ui->SearchImage->setEnabled(false);
1227  //ui->ImagePreview->clearPreview();
1228  ui->ImagePreview->setPixmap(QPixmap());
1229 
1230  KSDssImage::Metadata md;
1231  bool ok = true;
1232 
1233  int width = QInputDialog::getInt(this, i18n("Customized DSS Download"), i18n("Specify image width (arcminutes): "),
1234  15, 15, 75, 1, &ok);
1235  int height = QInputDialog::getInt(this, i18n("Customized DSS Download"),
1236  i18n("Specify image height (arcminutes): "), 15, 15, 75, 1, &ok);
1237  QStringList strList = (QStringList() << "poss2ukstu_blue"
1238  << "poss2ukstu_red"
1239  << "poss2ukstu_ir"
1240  << "poss1_blue"
1241  << "poss1_red"
1242  << "quickv"
1243  << "all");
1244  QString version =
1245  QInputDialog::getItem(this, i18n("Customized DSS Download"), i18n("Specify version: "), strList, 0, false, &ok);
1246 
1247  QUrl srcUrl(KSDssDownloader::getDSSURL(currentObject()->ra0(), currentObject()->dec0(), width, height, "gif",
1248  version, &md));
1249 
1250  delete m_dl;
1251  m_dl = new KSDssDownloader();
1252  connect(m_dl, SIGNAL(downloadComplete(bool)), SLOT(downloadReady(bool)));
1253  m_dl->startSingleDownload(srcUrl, getCurrentImagePath(), md);
1254 }
1255 
1256 void ObservingList::slotGetImage(bool _dss, const SkyObject *o)
1257 {
1258  dss = _dss;
1259  Q_ASSERT(
1260  !o ||
1261  o == currentObject()); // FIXME: Meaningless to operate on m_currentImageFileName unless o == currentObject()!
1262  if (!o)
1263  o = currentObject();
1264  ui->SearchImage->setEnabled(false);
1265  //ui->ImagePreview->clearPreview();
1266  //ui->ImagePreview->setPixmap(QPixmap());
1267  setCurrentImage(o);
1268  QString currentImagePath = getCurrentImagePath();
1269  if (QFile::exists(currentImagePath))
1270  QFile::remove(currentImagePath);
1271  //QUrl url;
1272  dss = true;
1273  qWarning() << "FIXME: Removed support for SDSS. Until reintroduction, we will supply a DSS image";
1274  std::function<void(bool)> slot = std::bind(&ObservingList::downloadReady, this, std::placeholders::_1);
1275  new KSDssDownloader(o, currentImagePath, slot, this);
1276 }
1277 
1278 void ObservingList::downloadReady(bool success)
1279 {
1280  // set downloadJob to 0, but don't delete it - the job will be deleted automatically
1281  // downloadJob = 0;
1282 
1283  delete m_dl;
1284  m_dl = nullptr; // required if we came from slotCustomDSS; does nothing otherwise
1285 
1286  if (!success)
1287  {
1288  KSNotification::sorry(i18n("Failed to download DSS/SDSS image."));
1289  }
1290  else
1291  {
1292  /*
1293  if( QFile( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + QDir::separator() + m_currentImageFileName ).size() > 13000)
1294  //The default image is around 8689 bytes
1295  */
1296  //ui->ImagePreview->showPreview( QUrl::fromLocalFile( getCurrentImagePath() ) );
1297  ui->ImagePreview->setPixmap(QPixmap(getCurrentImagePath()).scaledToHeight(ui->ImagePreview->width()));
1298  saveThumbImage();
1299  ui->ImagePreview->show();
1300  ui->ImagePreview->setCursor(Qt::PointingHandCursor);
1301  ui->DeleteImage->setEnabled(true);
1302  }
1303  /*
1304  // FIXME: Implement a priority order SDSS > DSS in the DSS downloader
1305  else if( ! dss )
1306  slotGetImage( true );
1307  */
1308 }
1309 
1310 void ObservingList::setCurrentImage(const SkyObject *o)
1311 {
1312  QString sanitizedName = o->name().remove(' ').remove('\'').remove('\"').toLower();
1313 
1314  // JM: Always use .png across all platforms. No JPGs at all?
1315  m_currentImageFileName = "image-" + sanitizedName + ".png";
1316 
1317  m_currentThumbImageFileName = "thumb-" + sanitizedName + ".png";
1318 
1319  // Does full image exists in the path?
1320  QString currentImagePath = KSPaths::locate(QStandardPaths::GenericDataLocation, m_currentImageFileName);
1321 
1322  // Let's try to fallback to thumb-* images if they exist
1323  if (currentImagePath.isEmpty())
1324  {
1325  currentImagePath = KSPaths::locate(QStandardPaths::GenericDataLocation, m_currentThumbImageFileName);
1326 
1327  // If thumb image exists, let's use it
1328  if (currentImagePath.isEmpty() == false)
1329  m_currentImageFileName = m_currentThumbImageFileName;
1330  }
1331 
1332  // 2017-04-14: Unnamed stars already unsupported in observing list
1333  /*
1334  if( o->name() == "star" )
1335  {
1336  QString RAString( o->ra0().toHMSString() );
1337  QString DecString( o->dec0().toDMSString() );
1338  m_currentImageFileName = "Image_J" + RAString.remove(' ').remove( ':' ) + DecString.remove(' ').remove( ':' ); // Note: Changed naming convention to standard 2016-08-25 asimha; old images shall have to be re-downloaded.
1339  // Unnecessary complication below:
1340  // QChar decsgn = ( (o->dec0().Degrees() < 0.0 ) ? '-' : '+' );
1341  // m_currentImageFileName = m_currentImageFileName.remove('+').remove('-') + decsgn;
1342  }
1343  */
1344 
1345  // 2017-04-14 JM: If we use .png always, let us use it across all platforms.
1346  /*
1347  QString imagePath = getCurrentImagePath();
1348  if ( QFile::exists( imagePath)) // New convention -- append filename extension so file is usable on Windows etc.
1349  {
1350  QFile::rename( imagePath, imagePath + ".png" );
1351  }
1352  m_currentImageFileName += ".png";
1353  */
1354 }
1355 
1356 QString ObservingList::getCurrentImagePath()
1357 {
1358  QString currentImagePath = KSPaths::locate(QStandardPaths::GenericDataLocation, m_currentImageFileName);
1359  if (QFile::exists(currentImagePath))
1360  {
1361  return currentImagePath;
1362  }
1363  else
1364  return (KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + m_currentImageFileName);
1365 }
1366 
1367 void ObservingList::slotSaveAllImages()
1368 {
1369  ui->SearchImage->setEnabled(false);
1370  ui->DeleteImage->setEnabled(false);
1371  m_CurrentObject = nullptr;
1372  //Clear the selection in the Tables
1373  ui->WishListView->clearSelection();
1374  ui->SessionView->clearSelection();
1375 
1376  foreach (QSharedPointer<SkyObject> o, getActiveList())
1377  {
1378  if (!o)
1379  continue; // FIXME: Why would we have null objects? But appears that we do.
1380  setCurrentImage(o.data());
1381  QString img(getCurrentImagePath());
1382  // QUrl url( ( Options::obsListPreferDSS() ) ? DSSUrl : SDSSUrl ); // FIXME: We have removed SDSS support!
1383  QUrl url(KSDssDownloader::getDSSURL(o.data()));
1384  if (!o->isSolarSystem()) //TODO find a way for adding support for solar system images
1385  saveImage(url, img, o.data());
1386  }
1387 }
1388 
1389 void ObservingList::saveImage(QUrl /*url*/, QString /*filename*/, const SkyObject *o)
1390 {
1391  if (!o)
1392  o = currentObject();
1393  Q_ASSERT(o);
1394  if (!QFile::exists(getCurrentImagePath()))
1395  {
1396  // Call the DSS downloader
1397  slotGetImage(true, o);
1398  }
1399 }
1400 
1401 void ObservingList::slotImageViewer()
1402 {
1403  QPointer<ImageViewer> iv;
1404  QString currentImagePath = getCurrentImagePath();
1405  if (QFile::exists(currentImagePath))
1406  {
1407  QUrl url = QUrl::fromLocalFile(currentImagePath);
1408  iv = new ImageViewer(url);
1409  }
1410 
1411  if (iv)
1412  iv->show();
1413 }
1414 
1415 void ObservingList::slotDeleteAllImages()
1416 {
1417  if (KMessageBox::warningYesNo(nullptr, i18n("This will delete all saved images. Are you sure you want to do this?"),
1418  i18n("Delete All Images")) == KMessageBox::No)
1419  return;
1420  ui->ImagePreview->setCursor(Qt::ArrowCursor);
1421  ui->SearchImage->setEnabled(false);
1422  ui->DeleteImage->setEnabled(false);
1423  m_CurrentObject = nullptr;
1424  //Clear the selection in the Tables
1425  ui->WishListView->clearSelection();
1426  ui->SessionView->clearSelection();
1427  //ui->ImagePreview->clearPreview();
1428  ui->ImagePreview->setPixmap(QPixmap());
1429  QDirIterator iterator(KSPaths::writableLocation(QStandardPaths::GenericDataLocation));
1430  while (iterator.hasNext())
1431  {
1432  // TODO: Probably, there should be a different directory for cached images in the observing list.
1433  if (iterator.fileName().contains("Image") && (!iterator.fileName().contains("dat")) &&
1434  (!iterator.fileName().contains("obslist")))
1435  {
1436  QFile file(iterator.filePath());
1437  file.remove();
1438  }
1439  iterator.next();
1440  }
1441 }
1442 
1443 void ObservingList::setSaveImagesButton()
1444 {
1445  ui->saveImages->setEnabled(!getActiveList().isEmpty());
1446 }
1447 
1448 // FIXME: Is there a reason to implement these as an event filter,
1449 // instead of as a signal-slot connection? Shouldn't we just use slots
1450 // to subscribe to various events from the Table / Session view?
1451 //
1452 // NOTE: ui->ImagePreview is a QLabel, which has no clicked() event or
1453 // public mouseReleaseEvent(), so eventFilter makes sense.
1454 bool ObservingList::eventFilter(QObject *obj, QEvent *event)
1455 {
1456  if (obj == ui->ImagePreview)
1457  {
1458  if (event->type() == QEvent::MouseButtonRelease)
1459  {
1460  if (currentObject())
1461  {
1462  if (!QFile::exists(getCurrentImagePath()))
1463  {
1464  if (!currentObject()->isSolarSystem())
1465  slotGetImage(Options::obsListPreferDSS());
1466  else
1467  slotSearchImage();
1468  }
1469  else
1470  slotImageViewer();
1471  }
1472  return true;
1473  }
1474  }
1475  if (obj == ui->WishListView->viewport() || obj == ui->SessionView->viewport())
1476  {
1477  bool sessionViewEvent = (obj == ui->SessionView->viewport());
1478 
1479  if (event->type() == QEvent::MouseButtonRelease) // Mouse button release event
1480  {
1481  QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
1482  QPoint pos(mouseEvent->globalX(), mouseEvent->globalY());
1483 
1484  if (mouseEvent->button() == Qt::RightButton)
1485  {
1486  if (!noSelection)
1487  {
1488  pmenu->initPopupMenu(sessionViewEvent, !singleSelection, showScope);
1489  pmenu->popup(pos);
1490  }
1491  return true;
1492  }
1493  }
1494  }
1495 
1496  if (obj == ui->WishListView || obj == ui->SessionView)
1497  {
1498  if (event->type() == QEvent::KeyPress)
1499  {
1500  QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
1501  if (keyEvent->key() == Qt::Key_Delete)
1502  {
1503  slotRemoveSelectedObjects();
1504  return true;
1505  }
1506  }
1507  }
1508 
1509  return false;
1510 }
1511 
1512 void ObservingList::slotSearchImage()
1513 {
1514  QPixmap *pm = new QPixmap(":/images/noimage.png");
1515  QPointer<ThumbnailPicker> tp = new ThumbnailPicker(currentObject(), *pm, this, 200, 200, i18n("Image Chooser"));
1516  if (tp->exec() == QDialog::Accepted)
1517  {
1518  QString currentImagePath = getCurrentImagePath();
1519  QFile f(currentImagePath);
1520 
1521  //If a real image was set, save it.
1522  if (tp->imageFound())
1523  {
1524  tp->image()->save(f.fileName(), "PNG");
1525  //ui->ImagePreview->showPreview( QUrl::fromLocalFile( f.fileName() ) );
1526  ui->ImagePreview->setPixmap(QPixmap(f.fileName()).scaledToHeight(ui->ImagePreview->width()));
1527  saveThumbImage();
1528  slotNewSelection();
1529  }
1530  }
1531  delete pm;
1532  delete tp;
1533 }
1534 
1535 void ObservingList::slotDeleteCurrentImage()
1536 {
1537  QFile::remove(getCurrentImagePath());
1538  ImagePreviewHash.remove(m_CurrentObject);
1539  slotNewSelection();
1540 }
1541 
1542 void ObservingList::saveThumbImage()
1543 {
1544  if (!QFile::exists(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + m_currentThumbImageFileName))
1545  {
1546  QImage img(getCurrentImagePath());
1547  img = img.scaled(200, 200, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1548  img.save(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + m_currentThumbImageFileName);
1549  }
1550 }
1551 
1552 QString ObservingList::getTime(const SkyObject *o) const
1553 {
1554  return TimeHash.value(o->name(), QTime(30, 0, 0)).toString("h:mm:ss AP");
1555 }
1556 
1557 QTime ObservingList::scheduledTime(SkyObject *o) const
1558 {
1559  return TimeHash.value(o->name(), o->transitTime(dt, geo));
1560 }
1561 
1562 void ObservingList::setTime(const SkyObject *o, QTime t)
1563 {
1564  TimeHash.insert(o->name(), t);
1565 }
1566 
1567 void ObservingList::slotOALExport()
1568 {
1569  slotSaveSessionAs(false);
1570 }
1571 
1572 void ObservingList::slotAddVisibleObj()
1573 {
1574  KStarsDateTime lt = dt;
1575  lt.setTime(QTime(8, 0, 0));
1576  QPointer<WUTDialog> w = new WUTDialog(KStars::Instance(), sessionView, geo, lt);
1577  w->init();
1578  QModelIndexList selectedItems;
1579  selectedItems =
1580  m_WishListSortModel->mapSelectionToSource(ui->WishListView->selectionModel()->selection()).indexes();
1581  if (selectedItems.size())
1582  {
1583  foreach (const QModelIndex &i, selectedItems)
1584  {
1585  foreach (QSharedPointer<SkyObject> o, obsList())
1586  if (getObjectName(o.data()) == i.data().toString() && w->checkVisibility(o.data()))
1587  slotAddObject(
1588  o.data(),
1589  true); // FIXME: Better if there is a QSharedPointer override for this, although the check will ensure that we don't duplicate.
1590  }
1591  }
1592  delete w;
1593 }
1594 
1595 SkyObject *ObservingList::findObjectByName(QString name)
1596 {
1597  foreach (QSharedPointer<SkyObject> o, sessionList())
1598  {
1599  if (getObjectName(o.data(), false) == name)
1600  return o.data();
1601  }
1602  return nullptr;
1603 }
1604 
1605 void ObservingList::selectObject(const SkyObject *o)
1606 {
1607  ui->tabWidget->setCurrentIndex(1);
1608  ui->SessionView->selectionModel()->clear();
1609  for (int irow = m_SessionModel->rowCount() - 1; irow >= 0; --irow)
1610  {
1611  QModelIndex mSortIndex = m_SessionSortModel->index(irow, 0);
1612  QModelIndex mIndex = m_SessionSortModel->mapToSource(mSortIndex);
1613  int idxrow = mIndex.row();
1614  if (m_SessionModel->item(idxrow, 0)->text() == getObjectName(o))
1615  ui->SessionView->selectRow(idxrow);
1616  slotNewSelection();
1617  }
1618 }
1619 
1620 void ObservingList::setDefaultImage()
1621 {
1622  ui->ImagePreview->setPixmap(m_NoImagePixmap);
1623  ui->ImagePreview->update();
1624 }
1625 
1626 QString ObservingList::getObjectName(const SkyObject *o, bool translated)
1627 {
1628  QString finalObjectName;
1629  if (o->name() == "star")
1630  {
1631  StarObject *s = (StarObject *)o;
1632 
1633  // JM: Enable HD Index stars to be added to the observing list.
1634  if (s->getHDIndex() != 0)
1635  finalObjectName = QString("HD %1").arg(QString::number(s->getHDIndex()));
1636  }
1637  else
1638  finalObjectName = translated ? o->translatedName() : o->name();
1639 
1640  return finalObjectName;
1641 }
1642 
1643 void ObservingList::slotUpdateAltitudes()
1644 {
1645  // FIXME: Update upon gaining visibility, do not update when not visible
1646  KStarsDateTime now = KStarsDateTime::currentDateTimeUtc();
1647  // qCDebug(KSTARS) << "Updating altitudes in observation planner @ JD - J2000 = " << double( now.djd() - J2000 );
1648  for (int irow = m_WishListModel->rowCount() - 1; irow >= 0; --irow)
1649  {
1650  QModelIndex idx = m_WishListSortModel->mapToSource(m_WishListSortModel->index(irow, 0));
1651  SkyObject *o = static_cast<SkyObject *>(idx.data(Qt::UserRole + 1).value<void *>());
1652  Q_ASSERT(o);
1653  SkyPoint p = o->recomputeHorizontalCoords(now, geo);
1654  idx =
1655  m_WishListSortModel->mapToSource(m_WishListSortModel->index(irow, m_WishListSortModel->columnCount() - 1));
1656  QStandardItem *replacement = m_altCostHelper(p);
1657  m_WishListModel->setData(idx, replacement->data(Qt::DisplayRole), Qt::DisplayRole);
1658  m_WishListModel->setData(idx, replacement->data(Qt::UserRole), Qt::UserRole);
1659  delete replacement;
1660  }
1661  emit m_WishListModel->dataChanged(
1662  m_WishListModel->index(0, m_WishListModel->columnCount() - 1),
1663  m_WishListModel->index(m_WishListModel->rowCount() - 1, m_WishListModel->columnCount() - 1));
1664 }
1665 
1666 QSharedPointer<SkyObject> ObservingList::findObject(const SkyObject *o, bool session)
1667 {
1668  const QList<QSharedPointer<SkyObject>> &list = (session ? sessionList() : obsList());
1669  const QString &target = getObjectName(o);
1670  foreach (QSharedPointer<SkyObject> obj, list)
1671  {
1672  if (getObjectName(obj.data()) == target)
1673  return obj;
1674  }
1675  return QSharedPointer<SkyObject>(); // null pointer
1676 }
QDirIterator::next
QString next()
SessionSortFilterProxyModel
Sort best observation times by reimplementing lessThan() to work on the transit times of objects...
Definition: sessionsortfilterproxymodel.h:38
QModelIndex
OAL::Log::targetList
QList< QSharedPointer< SkyObject > > & targetList()
Definition: log.h:60
KSDssImage::getFileName
QString getFileName() const
Definition: ksdssimage.h:106
QEvent
ObservingList::slotSaveAllImages
void slotSaveAllImages()
Downloads the images of all the objects in the session list Note: This downloads the SDSS image...
Definition: observinglist.cpp:1367
QStandardItemModel
QWidget
ObservingList::setSaveImagesButton
void setSaveImagesButton()
decides on whether to enable the SaveImages button or not
Definition: observinglist.cpp:1443
KSNotification::event
void event(const QLatin1String &name, const QString &message, EventType type)
Definition: ksnotification.cpp:78
DetailDialog
DetailDialog is a window showing detailed information for a selected object.
Definition: detaildialog.h:80
KStarsData::objectNamed
SkyObject * objectNamed(const QString &name)
Find object by name.
Definition: kstarsdata.cpp:429
QEvent::type
Type type() const
QWidget::setupUi
void setupUi(QWidget *widget)
imageviewer.h
QWidget::setIcon
void setIcon(const QPixmap &i)
ObservingList::slotAddToEkosScheduler
void slotAddToEkosScheduler()
slotAddToEkosScheduler Add object to Ekos scheduler
Definition: observinglist.cpp:718
indilistener.h
ObservingList::slotAddVisibleObj
void slotAddVisibleObj()
Definition: observinglist.cpp:1572
QInputDialog::getItem
QString getItem(QWidget *parent, const QString &title, const QString &label, const QStringList &items, int current, bool editable, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
ObservingList::slotImageViewer
void slotImageViewer()
Shows the image in a ImageViewer window.
Definition: observinglist.cpp:1401
ObservingList::slotSaveSessionAs
void slotSaveSessionAs(bool nativeSave=true)
save the current observing session plan to disk, specify filename.
Definition: observinglist.cpp:944
SkyObject::translatedName
QString translatedName() const
Definition: skyobject.h:150
QTextStream::readLine
QString readLine(qint64 maxlen)
SkyObject::recomputeHorizontalCoords
SkyPoint recomputeHorizontalCoords(const KStarsDateTime &dt, const GeoLocation *geo) const
Like recomputeCoords, but also calls EquatorialToHorizontal before returning.
Definition: skyobject.cpp:348
ObservingList::getCurrentImagePath
QString getCurrentImagePath()
Returns a path to the current image, or a writable image.
Definition: observinglist.cpp:1356
SkyMap::slotCenter
void slotCenter()
Center the display at the point ClickedPoint.
Definition: skymap.cpp:345
QFile::remove
bool remove()
INDIListener::Instance
static INDIListener * Instance()
Definition: indilistener.cpp:76
ObservingList::slotCustomDSS
void slotCustomDSS()
Present the user with options to get the right DSS image for the job.
Definition: observinglist.cpp:1224
detaildialog.h
KStarsData::executeSession
Execute * executeSession()
Definition: kstarsdata.cpp:1506
QWidget::setFocusPolicy
void setFocusPolicy(Qt::FocusPolicy policy)
QImage::save
bool save(const QString &fileName, const char *format, int quality) const
QAbstractItemModel::removeRow
bool removeRow(int row, const QModelIndex &parent)
SkyObject::PLANET
Definition: skyobject.h:117
ISD::GDInterface::getBaseDevice
virtual INDI::BaseDevice * getBaseDevice()=0
ObservingList::saveImage
void saveImage(QUrl url, QString filename, const SkyObject *o=nullptr)
saves the image synchronously from a given URL into a given file url the url from which the image has...
Definition: observinglist.cpp:1389
FindDialog::Instance
static FindDialog * Instance()
Definition: finddialog.cpp:66
SkyMap::setClickedObject
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition: skymap.cpp:331
ObservingList::downloadReady
void downloadReady(bool success)
Definition: observinglist.cpp:1278
QFile::fileName
QString fileName() const
KStarsData::Instance
static KStarsData * Instance()
Definition: kstarsdata.h:98
dms::Degrees
const double & Degrees() const
Definition: dms.h:152
SkyMapComposite::findStarByGenetiveName
SkyObject * findStarByGenetiveName(const QString name)
Definition: skymapcomposite.cpp:629
ksdssdownloader.h
QPointer
ISD::GDInterface::getDeviceName
virtual const char * getDeviceName()=0
ObservingList::setCurrentImage
void setCurrentImage(const SkyObject *o)
Sets the image parameters for the current object o The passed object for setting the parameters...
Definition: observinglist.cpp:1310
QFile::setFileName
void setFileName(const QString &name)
KSDssImage::Metadata::version
QString version
Used for DSS – Indicates which version of scans to pull.
Definition: ksdssimage.h:76
QWidget::setAttribute
void setAttribute(Qt::WidgetAttribute attribute, bool on)
QVariant::value
T value() const
KSNotification::sorry
void sorry(const QString &message, const QString &title)
Definition: ksnotification.cpp:42
KStars::Instance
static KStars * Instance()
Definition: kstars.h:130
KSDssImage::Metadata
Structure to hold some DSS image metadata.
Definition: ksdssimage.h:46
obslistpopupmenu.h
SkyPoint::EquatorialToHorizontal
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates, given the local sidereal time and the observer's latitude.
Definition: skypoint.cpp:70
ISD::GDSetCommand
Definition: indistd.h:39
ObservingListUI::ObservingListUI
ObservingListUI(QWidget *parent)
Definition: observinglist.cpp:66
KSPaths::writableLocation
static QString writableLocation(QStandardPaths::StandardLocation type)
Definition: kspaths.h:38
SkyMap::forceUpdate
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition: skymap.cpp:1192
QDirIterator::fileName
QString fileName() const
KStarsDateTime::setDate
void setDate(const QDate &d)
Assign the Date according to a QDate object.
Definition: kstarsdatetime.cpp:149
KSNotification::error
void error(const QString &message, const QString &title)
Definition: ksnotification.cpp:32
QPoint
QMouseEvent
kspaths.h
KSAlmanac
A class that implements methods to find sun rise, sun set, twilight begin / end times, moon rise and moon set times.
Definition: ksalmanac.h:40
ObservingList::slotSaveSession
void slotSaveSession(bool nativeSave=true)
save the current session
Definition: observinglist.cpp:1052
KStarsData::geo
GeoLocation * geo()
Definition: kstarsdata.h:215
QFile::exists
bool exists() const
QString::remove
QString & remove(int position, int n)
ObsListPopupMenu
The Popup Menu for the observing list in KStars.
Definition: obslistpopupmenu.h:29
altvstime.h
QTime
QSharedPointer::data
T * data() const
KStars
This is the main window for KStars.
Definition: kstars.h:101
QStandardItem::text
QString text() const
KSDssImage::Metadata::isValid
bool isValid() const
Definition: ksdssimage.h:98
QFile
ObservingList::slotFind
void slotFind()
Open the Find Dialog.
Definition: observinglist.cpp:763
QTextStream
SkyObject::COMET
Definition: skyobject.h:124
ObservingList::slotAddToSession
void slotAddToSession()
Add the object to the Session List.
Definition: observinglist.cpp:747
GeoLocation::lat
const CachingDms * lat() const
Definition: geolocation.h:82
ObservingList::slotSlewToObject
void slotSlewToObject()
slew the telescope to the selected object
Definition: observinglist.cpp:678
QStandardItem::setData
virtual void setData(const QVariant &value, int role)
KStarsDateTime::setTime
void setTime(const QTime &t)
Assign the Time according to a QTime object.
Definition: kstarsdatetime.cpp:166
fov.h
QList::indexOf
int indexOf(const T &value, int from) const
ObservingList::findAltitude
double findAltitude(SkyPoint *p, double hour=0)
Return the altitude of the given SkyObject for the given hour.
Definition: observinglist.cpp:1144
QString::clear
void clear()
QWidget::width
width
KSDssImage::getMetadata
KSDssImage::Metadata getMetadata() const
Definition: ksdssimage.h:105
ObservingList::slotWizard
void slotWizard()
construct a new observing list using the wizard.
Definition: observinglist.cpp:1084
QInputDialog::getInt
int getInt(QWidget *parent, const QString &title, const QString &label, int value, int min, int max, int step, bool *ok, QFlags< Qt::WindowType > flags)
ObservingList::slotOpenList
void slotOpenList()
load an observing list from disk.
Definition: observinglist.cpp:829
ObservingList::setTime
void setTime(const SkyObject *o, QTime t)
Definition: observinglist.cpp:1562
ObservingListUI
Definition: observinglist.h:47
OAL::Log::dateTime
KStarsDateTime dateTime() const
Definition: log.h:114
NaN::f
const float f
Definition: nan.h:35
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString::number
QString number(int n, int base)
driverinfo.h
SkyObject::transitTime
QTime transitTime(const KStarsDateTime &dt, const GeoLocation *geo) const
The same iteration technique described in riseSetTime() is used here.
Definition: skyobject.cpp:258
SkyPoint
The sky coordinates of a point in the sky.
Definition: skypoint.h:56
QTextStream::atEnd
bool atEnd() const
ImageViewer
Image viewer window for KStars.
Definition: imageviewer.h:67
QWidget::setLayout
void setLayout(QLayout *layout)
QObject::installEventFilter
void installEventFilter(QObject *filterObj)
QTimer
QSharedPointer
KStarsDateTime::currentDateTime
static KStarsDateTime currentDateTime()
Definition: kstarsdatetime.cpp:78
ObservingList::slotSearchImage
void slotSearchImage()
Definition: observinglist.cpp:1512
KSDssDownloader
Helps download a DSS image.
Definition: ksdssdownloader.h:45
QShowEvent
QObject
skymapcomposite.h
QMouseEvent::button
Qt::MouseButton button() const
ObservingList::slotClose
void slotClose()
Definition: observinglist.cpp:807
KStars::slotEyepieceView
void slotEyepieceView(SkyPoint *sp, const QString &imagePath=QString())
Show the eyepiece view tool.
Definition: kstarsactions.cpp:1701
locationdialog.h
QString::isEmpty
bool isEmpty() const
QModelIndex::row
int row() const
ObservingList::setDefaultImage
void setDefaultImage()
set the default image in the image preview.
Definition: observinglist.cpp:1620
ObservingList::slotAVT
void slotAVT()
Show the Altitude vs Time for selecteld objects.
Definition: observinglist.cpp:780
QWidget::move
void move(int x, int y)
KSUtils::constNameToAbbrev
QString constNameToAbbrev(const QString &fullName_)
Return the abbreviation of the constellation, given the full name.
Definition: ksutils.cpp:555
ObservingList::slotGetImage
void slotGetImage(bool _dss=false, const SkyObject *o=nullptr)
Downloads the corresponding DSS or SDSS image from the web and displays it.
Definition: observinglist.cpp:1256
QVBoxLayout
KStarsDateTime::addSecs
KStarsDateTime addSecs(double s) const
Definition: kstarsdatetime.cpp:158
StarObject::getHDIndex
int getHDIndex() const
Definition: starobject.h:253
ObservingList::findObject
QSharedPointer< SkyObject > findObject(const SkyObject *o, bool session=false)
Definition: observinglist.cpp:1666
skymap.h
QPixmap::scaled
QPixmap scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
QString
QList
ObservingList::selectObject
void selectObject(const SkyObject *o)
make a selection in the session view
Definition: observinglist.cpp:1605
ObservingList::slotClearList
void slotClearList()
slotClearList Remove all objects from current list
Definition: observinglist.cpp:896
ObservingList::slotDeleteAllImages
void slotDeleteAllImages()
Removes all the save DSS/SDSS images from the disk.
Definition: observinglist.cpp:1415
manager.h
OAL::Log::geoLocation
GeoLocation * geoLocation()
Definition: log.h:115
ObservingList::slotSaveList
void slotSaveList()
save the current observing list to disk.
Definition: observinglist.cpp:958
ObservingList::slotNewSelection
void slotNewSelection()
Tasks needed when changing the selected object Save the user log of the previous selected object...
Definition: observinglist.cpp:496
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
execute.h
KStarsDateTime
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day...
Definition: kstarsdatetime.h:46
SkyObject::MOON
Definition: skyobject.h:127
Options::obsListPreferDSS
static bool obsListPreferDSS()
Get Prefer Digitized Sky Survey imagery in the observing list.
Definition: Options.h:3285
ObservingList::slotSetTime
void slotSetTime()
Takes the time from the QTimeEdit box and sets it as the time parameter in the tableview of the Sessi...
Definition: observinglist.cpp:1216
QStringList
ObservingList::eventFilter
bool eventFilter(QObject *obj, QEvent *event) override
This is the declaration of the event filter function which is installed on the KImageFilePreview and ...
Definition: observinglist.cpp:1454
update
void update(infostruct *, infostruct *, pliststruct *)
QPixmap
KStarsData::skyComposite
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:173
OAL::Log::readBegin
void readBegin(QString input)
Definition: log.cpp:493
QUrl::toLocalFile
QString toLocalFile() const
Options::obsListDemoteHole
static bool obsListDemoteHole()
Get While sorting by percentage altitude in the observing list, demote objects present in the Dobsoni...
Definition: Options.h:3323
ObservingList::saveCurrentUserLog
void saveCurrentUserLog()
Save the user log text to a file.
Definition: observinglist.cpp:817
QDirIterator
QString::toLower
QString toLower() const
QKeyEvent::key
int key() const
dms
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:48
ObservingList::slotUpdateAltitudes
void slotUpdateAltitudes()
Recalculate and update the values of the altitude in the wishlist for the current time...
Definition: observinglist.cpp:1643
QStandardItemModel::item
QStandardItem * item(int row, int column) const
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QUrl
QSortFilterProxyModel
Options::obsListHoleSize
static double obsListHoleSize()
Get This is the angular distance from the zenith, in degrees, below which you can easily point your t...
Definition: Options.h:3342
QFrame
ObservingList::slotWUT
void slotWUT()
Open the WUT dialog.
Definition: observinglist.cpp:738
ObservingList::saveThumbImage
void saveThumbImage()
saves a thumbnail image for the details dialog from the downloaded image
Definition: observinglist.cpp:1542
QFile::close
virtual void close()
QImage
ObservingList::slotChangeTab
void slotChangeTab(int index)
toggle the setEnabled flags according to current view set the m_currentItem to nullptr and clear sele...
Definition: observinglist.cpp:1156
constellationboundarylines.h
KSDssImage::Metadata::height
float height
Height in arcminutes.
Definition: ksdssimage.h:88
SkyMapComposite::constellationBoundary
ConstellationBoundaryLines * constellationBoundary()
Definition: skymapcomposite.h:186
sessionsortfilterproxymodel.h
Options.h
QItemSelection
QKeyEvent
ISD::GDInterface::getType
virtual DeviceFamily getType()=0
QWidget::setWindowFlags
void setWindowFlags(QFlags< Qt::WindowType > type)
KSNumbers
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition: ksnumbers.h:54
ksalmanac.h
QUrl::isValid
bool isValid() const
ObservingList::ObservingList
ObservingList()
Definition: observinglist.cpp:74
SkyObject::clone
virtual SkyObject * clone() const
Create copy of object.
Definition: skyobject.cpp:66
QDateTime::date
QDate date() const
QModelIndex::data
QVariant data(int role) const
KSDssImage::Metadata::width
float width
Width in arcminutes.
Definition: ksdssimage.h:90
ObservingList::showEvent
void showEvent(QShowEvent *) override
Definition: observinglist.cpp:226
ksnotification.h
QMouseEvent::globalX
int globalX() const
QMouseEvent::globalY
int globalY() const
finddialog.h
SkyMap::setClickedPoint
void setClickedPoint(SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition: skymap.cpp:1002
ObservingList::findObjectByName
SkyObject * findObjectByName(QString name)
return the object with the name as the passed QString from the Session List, return null otherwise ...
Definition: observinglist.cpp:1595
thumbnailpicker.h
SkyObject::CONSTELLATION
Definition: skyobject.h:126
NaN::ld
const long double ld
Definition: nan.h:36
ObservingList::scheduledTime
QTime scheduledTime(SkyObject *o) const
Definition: observinglist.cpp:1557
QWidget::setWindowTitle
void setWindowTitle(const QString &)
ObservingList::slotUpdate
void slotUpdate()
Updates the tableviews for the new geolocation and date.
Definition: observinglist.cpp:1190
ISD::GDInterface::setProperty
virtual bool setProperty(QObject *)=0
ObservingList::slotOALExport
void slotOALExport()
Export a target list to the oal compliant format.
Definition: observinglist.cpp:1567
starobject.h
GeoLocation::fullName
QString fullName() const
Definition: geolocation.cpp:58
ObservingList::saveCurrentList
void saveCurrentList()
If the current list has unsaved changes, ask the user about saving it.
Definition: observinglist.cpp:928
QStandardItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const
ObservingList::getTime
QString getTime(const SkyObject *o) const
Definition: observinglist.cpp:1552
OAL::Log::writeLog
QString writeLog(bool native=true)
Definition: log.cpp:62
QModelIndex::column
int column() const
ObservingList::slotRemoveObject
void slotRemoveObject(const SkyObject *o=nullptr, bool session=false, bool update=false)
Remove skyobject from the observing list.
Definition: observinglist.cpp:397
SkyMap::Instance
static SkyMap * Instance()
Definition: skymap.cpp:145
eyepiecefield.h
SkyObject::ASTEROID
Definition: skyobject.h:125
obslistwizard.h
QDialog
KSPaths::locate
static QString locate(QStandardPaths::StandardLocation location, const QString &fileName, QStandardPaths::LocateOptions options=QStandardPaths::LocateFile)
Definition: kspaths.cpp:4
ObservingList::plot
void plot(SkyObject *o)
Plot the SkyObject's Altitude vs Time in the AVTPlotWidget.
Definition: observinglist.cpp:1111
QIcon::fromTheme
QIcon fromTheme(const QString &name, const QIcon &fallback)
kstarsdata.h
QStandardItem
OAL::Log
Definition: log.h:43
ObservingList::slotDetails
void slotDetails()
Show the details window for the selected object.
Definition: observinglist.cpp:727
KStarsDateTime::currentDateTimeUtc
static KStarsDateTime currentDateTimeUtc()
Definition: kstarsdatetime.cpp:87
ObservingList::getObjectName
QString getObjectName(const SkyObject *o, bool translated=true)
get object name.
Definition: observinglist.cpp:1626
SkyPoint::alt
const dms & alt() const
Definition: skypoint.h:215
SkyMap::clickedObject
SkyObject * clickedObject() const
Retrieve the object nearest to a mouse click event.
Definition: skymap.h:244
ConstellationBoundaryLines::constellationName
QString constellationName(SkyPoint *p)
Definition: constellationboundarylines.cpp:277
SkyObject::name
virtual QString name(void) const
Definition: skyobject.h:147
KSTARS_TELESCOPE
Definition: indicommon.h:165
ISD::GDInterface::runCommand
virtual bool runCommand(int command, void *ptr=nullptr)=0
ObservingList::slotRemoveSelectedObjects
void slotRemoveSelectedObjects()
Remove skyobjects which are highlighted in the observing list tool from the observing list...
Definition: observinglist.cpp:461
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
INDI_SEND_COORDS
Definition: indicommon.h:193
QDirIterator::hasNext
bool hasNext() const
ObservingList::slotCenterObject
void slotCenterObject()
center the selected object in the display
Definition: observinglist.cpp:668
ObservingList::slotAddObject
void slotAddObject(const SkyObject *o=nullptr, bool session=false, bool update=false)
add a new object to list o pointer to the object to add to the list session flag toggle adding the ob...
Definition: observinglist.cpp:247
ksutils.h
StarObject
This is a subclass of SkyObject.
Definition: starobject.h:43
ObservingList::slotEyepieceView
void slotEyepieceView()
Show the eyepiece field view.
Definition: observinglist.cpp:775
KStarsDateTime::gst
dms gst() const
Definition: kstarsdatetime.cpp:172
QTextStream::readAll
QString readAll()
OAL::Log::timeHash
QHash< QString, QTime > timeHash() const
Definition: log.h:113
SkyObject::STAR
Definition: skyobject.h:115
SkyObject
Provides all necessary information about an object in the sky: its coordinates, name(s), type, magnitude, and QStringLists of URLs for images and webpages regarding the object.
Definition: skyobject.h:43
QProgressDialog
ObservingList::slotDeleteCurrentImage
void slotDeleteCurrentImage()
Remove the current image.
Definition: observinglist.cpp:1535
ObservingList::slotLoadWishList
void slotLoadWishList()
Load the Wish list from disk.
Definition: observinglist.cpp:1004
QString::data
QChar * data()
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QVariant::toString
QString toString() const
KSDssImage
Provides a class to hold a DSS Image along with its metadata.
Definition: ksdssimage.h:31
kstars.h
ISD::GDInterface
GDInterface is the Generic Device Interface for INDI devices.
Definition: indistd.h:63
QStandardItem::data
virtual QVariant data(int role) const
CachingDms
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:29
QWidget::height
height
QImage::scaled
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
ObservingList::slotLocation
void slotLocation()
Opens the Location dialog to set the GeoLocation for the sessionlist.
Definition: observinglist.cpp:1179
wutdialog.h
QUrl::fromLocalFile
QUrl fromLocalFile(const QString &localFile)
QDateTime
QDirIterator::filePath
QString filePath() const
drivermanager.h
observinglist.h
KSDssImage::Metadata::band
char band
Photometric band (UBVRI...) Use "?" for unknown.
Definition: ksdssimage.h:92
KSDssDownloader::getDSSURL
static QString getDSSURL(const SkyPoint *const p, const QString &version="all", struct KSDssImage::Metadata *md=nullptr)
High-level method to create a URL to obtain a DSS image for a given SkyPoint.
Definition: ksdssdownloader.cpp:60
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Fri Dec 13 2019 02:57:12 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

Skip menu "kstars"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

edu API Reference

Skip menu "edu API Reference"
  •     core
  • kstars

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal