12#include "conjunctions.h"
14#include "geolocation.h"
15#include "ksconjunct.h"
17#include "ksnotification.h"
18#include "kstarsdata.h"
20#include "dialogs/finddialog.h"
21#include "dialogs/locationdialog.h"
22#include "skycomponents/skymapcomposite.h"
23#include "skyobjects/kscomet.h"
24#include "skyobjects/kspluto.h"
25#include "ksplanetbase.h"
28#include <QProgressDialog>
29#include <QStandardItemModel>
30#include <QtConcurrent>
32ConjunctionsTool::ConjunctionsTool(
QWidget *parentSplit) :
QFrame(parentSplit)
43 startDate->setDateTime(dtStart);
44 stopDate->setDateTime(dtStop);
47 LocationButton->setText(geoPlace->fullName());
50 pNames[KSPlanetBase::MERCURY] =
i18n(
"Mercury");
51 pNames[KSPlanetBase::VENUS] =
i18n(
"Venus");
52 pNames[KSPlanetBase::MARS] =
i18n(
"Mars");
53 pNames[KSPlanetBase::JUPITER] =
i18n(
"Jupiter");
54 pNames[KSPlanetBase::SATURN] =
i18n(
"Saturn");
55 pNames[KSPlanetBase::URANUS] =
i18n(
"Uranus");
56 pNames[KSPlanetBase::NEPTUNE] =
i18n(
"Neptune");
58 pNames[KSPlanetBase::SUN] =
i18n(
"Sun");
59 pNames[KSPlanetBase::MOON] =
i18n(
"Moon");
62 maxSeparationBox->setUnits(dmsBox::DEGREES);
63 maxSeparationBox->show(1.0_deg);
69 connect(LocationButton, SIGNAL(clicked()),
this, SLOT(slotLocation()));
70 connect(Obj1FindButton, SIGNAL(clicked()),
this, SLOT(slotFindObject()));
78#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
84 connect(FilterTypeComboBox, SIGNAL(currentIndexChanged(
int)), SLOT(slotFilterType(
int)));
85 connect(ClearButton, SIGNAL(clicked()),
this, SLOT(slotClear()));
86 connect(ExportButton, SIGNAL(clicked()),
this, SLOT(slotExport()));
88 connect(ClearFilterButton, SIGNAL(clicked()), FilterEdit, SLOT(
clear()));
93 setMode(ModeSelector->currentIndex());
96 FilterTypeComboBox->clear();
97 FilterTypeComboBox->addItem(
i18n(
"Single Object"));
98 FilterTypeComboBox->addItem(
i18n(
"Any"));
99 FilterTypeComboBox->addItem(
i18n(
"Stars"));
100 FilterTypeComboBox->addItem(
i18n(
"Solar System"));
101 FilterTypeComboBox->addItem(
i18n(
"Planets"));
102 FilterTypeComboBox->addItem(
i18n(
"Comets"));
103 FilterTypeComboBox->addItem(
i18n(
"Asteroids"));
104 FilterTypeComboBox->addItem(
i18n(
"Open Clusters"));
105 FilterTypeComboBox->addItem(
i18n(
"Globular Clusters"));
106 FilterTypeComboBox->addItem(
i18n(
"Gaseous Nebulae"));
107 FilterTypeComboBox->addItem(
i18n(
"Planetary Nebulae"));
108 FilterTypeComboBox->addItem(
i18n(
"Galaxies"));
110 Obj2ComboBox->clear();
111 for (
int i = 0; i < KSPlanetBase::UNKNOWN_PLANET; ++i)
114 Obj2ComboBox->insertItem(i, pNames[i]);
117 maxSeparationBox->setEnabled(
true);
120 m_Model->setHorizontalHeaderLabels(
QStringList() <<
i18n(
"Conjunction/Opposition") <<
i18n(
"Date & Time (UT)")
121 <<
i18n(
"Object 1") <<
i18n(
"Object 2") <<
i18n(
"Separation"));
123 m_SortModel->setSourceModel(m_Model);
124 OutputList->setModel(m_SortModel);
125 OutputList->setSortingEnabled(
true);
126 OutputList->horizontalHeader()->setStretchLastSection(
true);
128 OutputList->horizontalHeader()->resizeSection(2, 100);
129 OutputList->horizontalHeader()->resizeSection(3, 100);
130 OutputList->horizontalHeader()->resizeSection(4, 120);
135void ConjunctionsTool::slotGoto()
137 int index = m_SortModel->mapToSource(OutputList->currentIndex()).row();
138 long double jd = outputJDList.value(index);
141 KStarsData *data = KStarsData::Instance();
149 map->setClickedPoint(
map->clickedObject());
153void ConjunctionsTool::slotFindObject()
157 if (!FindDialog::Instance()->targetObject())
159 Object1 = SkyObject_s(FindDialog::Instance()->targetObject()->clone());
160 if (Object1 !=
nullptr)
161 Obj1FindButton->setText(Object1->name());
165void ConjunctionsTool::setMode(
int new_mode)
168 if(new_mode == -1 || new_mode > 2)
170 ModeSelector->setCurrentIndex(0);
174 mode =
static_cast<MODE
>(new_mode);
177void ConjunctionsTool::slotLocation()
179 QPointer<LocationDialog> ld(
new LocationDialog(
this));
182 geoPlace = ld->selectedCity();
183 LocationButton->setText(geoPlace->fullName());
188void ConjunctionsTool::slotFilterType(
int)
191 if (FilterTypeComboBox->currentIndex() == 0)
192 Obj1FindButton->setEnabled(
true);
194 Obj1FindButton->setEnabled(
false);
197void ConjunctionsTool::slotClear()
199 m_Model->setRowCount(0);
200 outputJDList.clear();
204void ConjunctionsTool::slotExport()
214 for (i = 0; i < m_Model->rowCount(); ++i)
216 for (j = 0; j < m_Model->columnCount(); ++j)
218 line.
append(m_Model->data(m_Model->index(i, j)).toByteArray());
219 if (j < m_Model->columnCount() - 1)
231void ConjunctionsTool::slotFilterReg(
const QString &filter)
234 m_SortModel->setFilterKeyColumn(-1);
237void ConjunctionsTool::slotCompute(
void)
239 KStarsDateTime dtStart(startDate->dateTime());
240 KStarsDateTime dtStop(stopDate->dateTime());
241 long double startJD = dtStart.djd();
242 long double stopJD = dtStop.djd();
243 bool opposition =
false;
244 if (mode == OPPOSITION)
247 KStarsData *data = KStarsData::Instance();
251 dms maxSeparation(0.0);
253 maxSeparation = maxSeparationBox->createDms(&ok);
257 KSNotification::sorry(
i18n(
"Maximum separation entered is not a valid angle. Use the What's this help feature "
258 "for information on how to enter a valid angle"));
263 if (FilterTypeComboBox->currentIndex() == 0 && Object1 ==
nullptr)
265 KSNotification::sorry(
i18n(
"Please select an object to check conjunctions with, by clicking on the \'Find Object\' button."));
268 Object2.reset(KSPlanetBase::createPlanet(Obj2ComboBox->currentIndex()));
269 if (FilterTypeComboBox->currentIndex() == 0 && Object1->name() == Object2->name())
272 KSNotification::sorry(
i18n(
"Please select two different objects to check conjunctions with."));
278 connect(&ksc, SIGNAL(madeProgress(
int)),
this, SLOT(showProgress(
int)));
281 switch (FilterTypeComboBox->currentIndex())
288 objects += data->
skyComposite()->objectNames(SkyObject::STAR);
289 objects += data->
skyComposite()->objectNames(SkyObject::CATALOG_STAR);
292 objects += data->
skyComposite()->objectNames(SkyObject::PLANET);
293 objects += data->
skyComposite()->objectNames(SkyObject::COMET);
294 objects += data->
skyComposite()->objectNames(SkyObject::ASTEROID);
295 objects += data->
skyComposite()->objectNames(SkyObject::MOON);
296 objects +=
i18n(
"Sun");
298 objects.removeAll(Object2->name());
301 objects += data->
skyComposite()->objectNames(SkyObject::PLANET);
303 objects.removeAll(Object2->name());
306 objects += data->
skyComposite()->objectNames(SkyObject::COMET);
309 objects += data->
skyComposite()->objectNames(SkyObject::ASTEROID);
312 objects = data->
skyComposite()->objectNames(SkyObject::OPEN_CLUSTER);
315 objects = data->
skyComposite()->objectNames(SkyObject::GLOBULAR_CLUSTER);
318 objects = data->
skyComposite()->objectNames(SkyObject::GASEOUS_NEBULA);
321 objects = data->
skyComposite()->objectNames(SkyObject::PLANETARY_NEBULA);
324 objects = data->
skyComposite()->objectNames(SkyObject::GALAXY);
330 if (FilterTypeComboBox->currentIndex() == 1 || FilterTypeComboBox->currentIndex() == 3 ||
331 FilterTypeComboBox->currentIndex() == 6)
333 objects.removeAll(
"Io");
334 objects.removeAll(
"Europa");
335 objects.removeAll(
"Ganymede");
336 objects.removeAll(
"Callisto");
337 objects.removeAll(
"Mimas");
338 objects.removeAll(
"Enceladus");
339 objects.removeAll(
"Tethys");
340 objects.removeAll(
"Dione");
341 objects.removeAll(
"Rhea");
342 objects.removeAll(
"Titan");
343 objects.removeAll(
"Hyperion");
344 objects.removeAll(
"Iapetus");
348 ksc.setObject2(Object2);
349 ksc.setOpposition(opposition);
351 if (FilterTypeComboBox->currentIndex() != 0)
354 QProgressDialog progressDlg(
i18n(
"Compute conjunction..."),
i18n(
"Abort"), 0, objects.count(),
this);
355 progressDlg.setWindowTitle(
i18nc(
"@title:window",
"Conjunction"));
357 progressDlg.setValue(0);
359 for (
auto &
object : objects)
362 if (progressDlg.wasCanceled())
367 progressDlg.setValue(progress);
368 progressDlg.setLabelText(
i18n(
"Compute conjunction between %1 and %2", Object2->name(),
object));
372 ksc.setObject1(Object1);
374 object, Object2->name());
377 progressDlg.setValue(objects.count());
384 ComputeStack->setCurrentIndex(1);
386 ksc.setObject1(Object1);
388 Object1->name(), Object2->name());
389 ComputeStack->setCurrentIndex(0);
398void ConjunctionsTool::showProgress(
int n)
400 progress->setValue(n);
407 QList<QStandardItem *> itemList;
412 QStandardItem *typeItem;
414 if (mode == CONJUNCTION)
415 typeItem =
new QStandardItem(
i18n(
"Conjunction"));
417 typeItem =
new QStandardItem(
i18n(
"Opposition"));
424 <<
new QStandardItem(object2) <<
new QStandardItem(it.value().toDMSString());
425 m_Model->appendRow(itemList);
428 outputJDList.insert(m_index, it.key());
433void ConjunctionsTool::setUpConjunctionOpposition()
void setMaxSeparation(double sep)
setMaxSeparation
QMap< long double, dms > findClosestApproach(long double startJD, long double stopJD, const std::function< void(long double, dms)> &callback={})
Compute the closest approach of two planets in the given range.
void setGeoLocation(GeoLocation *geo)
Sets the geographic location to compute conjunctions at.
KStarsData is the backbone of KStars.
void setLocation(const GeoLocation &l)
Set the GeoLocation according to the argument.
void changeDateTime(const KStarsDateTime &newDate)
Change the current simulation date/time to the KStarsDateTime argument.
SkyMapComposite * skyComposite()
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
void setDJD(long double jd)
Assign the static_cast<long double> Julian Day value, which includes the time of day encoded in the f...
static KStarsDateTime currentDateTime()
static KStars * Instance()
SkyObject * findByName(const QString &name, bool exact=true) override
Search the children of this SkyMapComposite for a SkyObject whose name matches the argument.
virtual SkyObject * clone() const
Create copy of object.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QAction * clear(const QObject *recvr, const char *slot, QObject *parent)
QByteArray & append(QByteArrayView data)
void currentIndexChanged(int index)
QString toString(QStringView format, QCalendar cal) const const
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
void restoreOverrideCursor()
void setOverrideCursor(const QCursor &cursor)
QList< Key > keys() const const
QIcon fromTheme(const QString &name)
const_iterator constBegin() const const
const_iterator constEnd() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< T > run(Function function,...)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)