File indexing completed on 2024-04-14 14:11:35
0001 /* 0002 SPDX-FileCopyrightText: 2001-2005 Pablo de Vicente <p.devicente@wanadoo.es> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "astrocalc.h" 0008 0009 #include "modcalcjd.h" 0010 #include "modcalcgeodcoord.h" 0011 #include "modcalcgalcoord.h" 0012 #include "modcalcsidtime.h" 0013 #include "modcalcapcoord.h" 0014 #include "modcalcdaylength.h" 0015 #include "modcalcaltaz.h" 0016 #include "modcalcsimple.h" 0017 #include "modcalcplanets.h" 0018 #include "modcalceclipticcoords.h" 0019 #include "modcalcangdist.h" 0020 #include "modcalcvizequinox.h" 0021 #include "modcalcvlsr.h" 0022 #include "conjunctions.h" 0023 #include "eclipsetool.h" 0024 0025 #include <QDialogButtonBox> 0026 #include <QSplitter> 0027 #include <QStackedWidget> 0028 #include <QTextEdit> 0029 #include <QTreeWidget> 0030 #include <QTreeWidgetItem> 0031 0032 AstroCalc::AstroCalc(QWidget *parent) : QDialog(parent) 0033 { 0034 #ifdef Q_OS_OSX 0035 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); 0036 #endif 0037 0038 // List of messages. Maybe there is better place for it... 0039 QString message = i18n("<QT>" 0040 "<H2>KStars Astrocalculator</H2>" 0041 "<P>" 0042 "The KStars Astrocalculator contains several <B>modules</b> " 0043 "which perform a variety of astronomy-related calculations. " 0044 "The modules are organized into several categories: " 0045 "<UL>" 0046 "<LI><B>Time calculators: </B>" 0047 "Convert between time systems, and predict the timing of celestial events</LI>" 0048 "<LI><B>Coordinate converters: </B>" 0049 "Convert between various coordinate systems</LI>" 0050 "<LI><B>Solar system: </B>" 0051 "Predict the position of any planet, from a given location on Earth at a given time</LI>" 0052 "</UL>" 0053 "</QT>"); 0054 QString messageTime = i18n("<QT>" 0055 "Section which includes algorithms for computing time ephemeris" 0056 "<UL><LI>" 0057 "<B>Julian Day:</B> Julian Day/Calendar conversion" 0058 "</LI><LI>" 0059 "<B>Sidereal Time:</B> Sidereal/Universal time conversion" 0060 "</LI><LI>" 0061 "<B>Almanac:</B> Rise/Set/Transit timing and position data " 0062 "for the Sun and Moon" 0063 "</LI><LI>" 0064 "<B>Equinoxes & Solstices:</B> Equinoxes, Solstices and duration of the " 0065 "seasons" 0066 "</LI></UL>" 0067 "</QT>"); 0068 QString messageCoord = i18n("<QT>" 0069 "Section with algorithms for the conversion of " 0070 "different astronomical systems of coordinates" 0071 "<UL><LI>" 0072 "<B>Galactic:</B> Galactic/Equatorial coordinates conversion" 0073 "</LI><LI>" 0074 "<B>Apparent:</B> Computation of current equatorial coordinates" 0075 " from a given epoch" 0076 "</LI><LI>" 0077 "<B>Ecliptic:</B> Ecliptic/Equatorial coordinates conversion" 0078 "</LI><LI>" 0079 "<B>Horizontal:</B> Computation of azimuth and elevation for a " 0080 "given source, time, and location on the Earth" 0081 "</LI><LI>" 0082 "<B>Simple:</B> Conversion between angles in hrs and degrees." 0083 "</LI><LI>" 0084 "<B>Angular Distance:</B> Computation of angular distance between " 0085 "two objects whose positions are given in equatorial coordinates" 0086 "</LI><LI>" 0087 "<B>Geodetic Coords:</B> Geodetic/XYZ coordinate conversion" 0088 "</LI><LI>" 0089 "<B>LSR Velocity:</B> Computation of the heliocentric, geocentric " 0090 "and topocentric radial velocity of a source from its LSR velocity" 0091 "</LI></UL>" 0092 "</QT>"); 0093 QString messageSolar = i18n("<QT>" 0094 "Section with algorithms regarding information " 0095 "on solar system bodies coordinates and times" 0096 "<UL><LI>" 0097 "<B>Planets Coords:</B> Coordinates for the planets, moon and sun " 0098 "at a given time and from a given position on Earth " 0099 "</LI></UL>" 0100 "</QT>"); 0101 0102 QSplitter *split = new QSplitter(this); 0103 0104 QVBoxLayout *mainLayout = new QVBoxLayout; 0105 mainLayout->addWidget(split); 0106 setLayout(mainLayout); 0107 0108 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0109 mainLayout->addWidget(buttonBox); 0110 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0111 0112 setWindowTitle(i18nc("@title:window", "Calculator")); 0113 0114 // Create navigation panel 0115 navigationPanel = new QTreeWidget(split); 0116 navigationPanel->setColumnCount(1); 0117 navigationPanel->setHeaderLabels(QStringList(i18n("Calculator modules"))); 0118 navigationPanel->setSortingEnabled(false); 0119 //FIXME: Would be better to make the navigationPanel fit its contents, 0120 //but I wasn't able to make it work 0121 navigationPanel->setMinimumWidth(200); 0122 0123 acStack = new QStackedWidget(split); 0124 0125 splashScreen = new QTextEdit(message, acStack); 0126 splashScreen->setReadOnly(true); 0127 //FIXME: Minimum size is set to resize calculator to correct size 0128 //when no modules is loaded. This is simply biggest size of 0129 //calculator modules. I think it should be set in more cleverly. 0130 splashScreen->setMinimumSize(640, 550); 0131 acStack->addWidget(splashScreen); 0132 0133 // Load icons 0134 // JM 2016-10-02: Those are missing, disabling the icons for now 0135 /* 0136 QIcon jdIcon = QIcon ("jd.png"); 0137 QIcon geodIcon = QIcon ("geodetic.png"); 0138 QIcon solarIcon = QIcon ("geodetic.png"); 0139 // QIcon sunsetIcon = QIcon ("sunset.png"); // Its usage is commented out. 0140 QIcon timeIcon = QIcon ("sunclock.png");*/ 0141 0142 /* Populate the tree widget and widget stack */ 0143 // Time-related entries 0144 QTreeWidgetItem *timeItem = addTreeTopItem(navigationPanel, i18n("Time Calculators"), messageTime); 0145 //timeItem->setIcon(0,timeIcon); 0146 0147 //addTreeItem<modCalcJD> (timeItem, i18n("Julian Day"))->setIcon(0,jdIcon); 0148 addTreeItem<modCalcJD>(timeItem, i18n("Julian Day")); 0149 addTreeItem<modCalcSidTime>(timeItem, i18n("Sidereal Time")); 0150 addTreeItem<modCalcDayLength>(timeItem, i18n("Almanac")); 0151 addTreeItem<modCalcEquinox>(timeItem, i18n("Equinoxes & Solstices")); 0152 // dayItem->setIcon(0,sunsetIcon); 0153 0154 // Coordinate-related entries 0155 QTreeWidgetItem *coordItem = addTreeTopItem(navigationPanel, i18n("Coordinate Converters"), messageCoord); 0156 addTreeItem<modCalcGalCoord>(coordItem, i18n("Equatorial/Galactic")); 0157 addTreeItem<modCalcApCoord>(coordItem, i18n("Apparent Coordinates")); 0158 addTreeItem<modCalcAltAz>(coordItem, i18n("Horizontal Coordinates")); 0159 addTreeItem<modCalcSimple>(coordItem, i18n("Simple Coordinates")); 0160 addTreeItem<modCalcEclCoords>(coordItem, i18n("Ecliptic Coordinates")); 0161 addTreeItem<modCalcAngDist>(coordItem, i18n("Angular Distance")); 0162 addTreeItem<modCalcGeodCoord>(coordItem, i18n("Geodetic Coordinates")); 0163 addTreeItem<modCalcVlsr>(coordItem, i18n("LSR Velocity")); 0164 0165 // Solar System related entries 0166 QTreeWidgetItem *solarItem = addTreeTopItem(navigationPanel, i18n("Solar System"), messageSolar); 0167 //solarItem->setIcon(0,solarIcon); 0168 addTreeItem<modCalcPlanets>(solarItem, i18n("Planets Coordinates")); 0169 addTreeItem<ConjunctionsTool>(solarItem, i18n("Conjunctions")); 0170 addTreeItem<EclipseTool>(solarItem, i18n("Eclipses")); 0171 0172 acStack->setCurrentWidget(splashScreen); 0173 connect(navigationPanel, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, 0174 SLOT(slotItemSelection(QTreeWidgetItem*))); 0175 } 0176 0177 template <typename T> 0178 QWidget *AstroCalc::addToStack() 0179 { 0180 T *t = new T(acStack); 0181 acStack->addWidget(t); 0182 return t; 0183 } 0184 0185 template <typename T> 0186 QTreeWidgetItem *AstroCalc::addTreeItem(QTreeWidgetItem *parent, const QString &title) 0187 { 0188 QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList(title)); 0189 dispatchTable.insert(item, WidgetThunk(this, &AstroCalc::addToStack<T>)); 0190 return item; 0191 } 0192 0193 QTreeWidgetItem *AstroCalc::addTreeTopItem(QTreeWidget *parent, const QString &title, const QString &html) 0194 { 0195 QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList(title)); 0196 0197 htmlTable.insert(item, html); 0198 return item; 0199 } 0200 0201 void AstroCalc::slotItemSelection(QTreeWidgetItem *item) 0202 { 0203 if (item == nullptr) 0204 return; 0205 // Lookup in HTML table 0206 QMap<QTreeWidgetItem *, QString>::iterator iterHTML = htmlTable.find(item); 0207 if (iterHTML != htmlTable.end()) 0208 { 0209 splashScreen->setHtml(*iterHTML); 0210 acStack->setCurrentWidget(splashScreen); 0211 return; 0212 } 0213 // Lookup in frames table 0214 QMap<QTreeWidgetItem *, WidgetThunk>::iterator iter = dispatchTable.find(item); 0215 if (iter != dispatchTable.end()) 0216 { 0217 acStack->setCurrentWidget(iter->eval()); 0218 } 0219 } 0220 0221 QSize AstroCalc::sizeHint() const 0222 { 0223 return QSize(640, 430); 0224 } 0225 0226 QWidget *AstroCalc::WidgetThunk::eval() 0227 { 0228 if (widget == nullptr) 0229 { 0230 // This is pointer to member function call. 0231 widget = (calc->*func)(); 0232 } 0233 return widget; 0234 }