File indexing completed on 2024-11-03 06:38:33
0001 /* 0002 SPDX-FileCopyrightText: 2001 Heiko Evermann <heiko@evermann.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "colorscheme.h" 0010 #include "geolocation.h" 0011 #include "ksnumbers.h" 0012 #include "kstarsdatetime.h" 0013 #include "ksuserdb.h" 0014 #include "simclock.h" 0015 #include "skyobjectuserdata.h" 0016 #include <qobject.h> 0017 #ifndef KSTARS_LITE 0018 #include "oal/oal.h" 0019 #include "oal/log.h" 0020 #include "polyfills/qstring_hash.h" 0021 #endif 0022 0023 #include <QList> 0024 #include <QMap> 0025 #include <QKeySequence> 0026 #include <QMutex> 0027 0028 #include <iostream> 0029 #include <memory> 0030 #include <unordered_map> 0031 0032 #define MINZOOM 250. 0033 #define MAXZOOM 5000000. 0034 #define DEFAULTZOOM 2000. 0035 #define DZOOM 1.189207115 // 2^(1/4) 0036 #define AU_KM 1.49605e8 //km in one AU 0037 0038 class QFile; 0039 0040 class Execute; 0041 class FOV; 0042 class ImageExporter; 0043 class SkyMap; 0044 class SkyMapComposite; 0045 class SkyObject; 0046 class ObservingList; 0047 class TimeZoneRule; 0048 0049 #ifdef KSTARS_LITE 0050 //Will go away when details window will be implemented in KStars Lite 0051 struct ADVTreeData 0052 { 0053 QString Name; 0054 QString Link; 0055 int Type; 0056 }; 0057 #else 0058 struct ADVTreeData; 0059 #endif 0060 0061 /** 0062 * @class KStarsData 0063 * KStarsData is the backbone of KStars. It contains all the data used by KStars, 0064 * including the SkyMapComposite that contains all items in the skymap 0065 * (stars, deep-sky objects, planets, constellations, etc). Other kinds of data 0066 * are stored here as well: the geographic locations, the timezone rules, etc. 0067 * 0068 * @author Heiko Evermann 0069 * @version 1.0 0070 */ 0071 class KStarsData : public QObject 0072 { 0073 Q_OBJECT 0074 0075 protected: 0076 /** Constructor. */ 0077 KStarsData(); 0078 0079 public: 0080 // FIXME: It uses temporary trail. There must be way to 0081 // this better. And resumeKey in DBUS code 0082 friend class KStars; 0083 // FIXME: it uses temporary trail and resumeKey 0084 friend class SkyMap; 0085 // FIXME: uses geoList and changes it. 0086 friend class LocationDialog; 0087 friend class LocationDialogLite; 0088 0089 static KStarsData *Create(); 0090 0091 static inline KStarsData *Instance() 0092 { 0093 return pinstance; 0094 } 0095 0096 /** 0097 * Initialize KStarsData while running splash screen. 0098 * @return true on success. 0099 */ 0100 bool initialize(); 0101 0102 /** Destructor. Delete data objects. */ 0103 ~KStarsData() override; 0104 0105 /** 0106 * Set the NextDSTChange member. 0107 * Need this accessor because I could not make KStars::privatedata a friend 0108 * class for some reason...:/ 0109 */ 0110 void setNextDSTChange(const KStarsDateTime &dt) 0111 { 0112 NextDSTChange = dt; 0113 } 0114 0115 /** 0116 * Returns true if time is running forward else false. Used by KStars to prevent 0117 * double calculations of daylight saving change time. 0118 */ 0119 bool isTimeRunningForward() const 0120 { 0121 return TimeRunsForward; 0122 } 0123 0124 /** @return pointer to the localization (KLocale) object */ 0125 //KLocale *getLocale() { return locale; } 0126 0127 /** 0128 * @short Find object by name. 0129 * @param name Object name to find 0130 * @return pointer to SkyObject matching this name 0131 */ 0132 SkyObject *objectNamed(const QString &name); 0133 0134 /** 0135 * The Sky is updated more frequently than the moon, which is updated more frequently 0136 * than the planets. The date of the last update for each category is recorded so we 0137 * know when we need to do it again (see KStars::updateTime()). 0138 * Initializing these to -1000000.0 ensures they will be updated immediately 0139 * on the first call to KStars::updateTime(). 0140 */ 0141 void setFullTimeUpdate(); 0142 0143 /** 0144 * Change the current simulation date/time to the KStarsDateTime argument. 0145 * Specified DateTime is always universal time. 0146 * @param newDate the DateTime to set. 0147 */ 0148 void changeDateTime(const KStarsDateTime &newDate); 0149 0150 /** @return pointer to the current simulation local time */ 0151 const KStarsDateTime <() const 0152 { 0153 return LTime; 0154 } 0155 0156 /** @return reference to the current simulation universal time */ 0157 const KStarsDateTime &ut() const 0158 { 0159 return Clock.utc(); 0160 } 0161 0162 /** Sync the LST with the simulation clock. */ 0163 void syncLST(); 0164 0165 /** @return pointer to SkyComposite */ 0166 SkyMapComposite *skyComposite() 0167 { 0168 return m_SkyComposite.get(); 0169 } 0170 0171 /** @return pointer to the ColorScheme object */ 0172 ColorScheme *colorScheme() 0173 { 0174 return &CScheme; 0175 } 0176 0177 /** @return file name of current color scheme **/ 0178 Q_INVOKABLE QString colorSchemeFileName() { return CScheme.fileName(); } 0179 0180 /** @return file name of the color scheme with the name \p name **/ 0181 QString colorSchemeFileName(const QString &name) 0182 { 0183 return m_color_schemes.count(name) > 0 ? m_color_schemes.at(name) : ""; 0184 } 0185 0186 /** @return file name of the current color scheme **/ 0187 Q_INVOKABLE QString colorSchemeName() 0188 { 0189 return colorSchemeName(CScheme.fileName()); 0190 } 0191 0192 /** @return the name of the color scheme with the name \p name **/ 0193 QString colorSchemeName(const QString &fileName) 0194 { 0195 return m_color_scheme_names.count(fileName) > 0 ? m_color_scheme_names.at(fileName) : ""; 0196 } 0197 0198 /** @return if the color scheme with the name or filename \p scheme is loaded **/ 0199 bool hasColorScheme(const QString &scheme) 0200 { 0201 return m_color_scheme_names.count(scheme) || m_color_schemes.count(scheme); 0202 } 0203 0204 /** Register a color scheme with \p filename and \p name. */ 0205 void add_color_scheme(const QString &filename, const QString &name) 0206 { 0207 m_color_schemes[name] = filename; 0208 m_color_scheme_names[filename] = name; 0209 }; 0210 0211 /** \return a map of color scheme names and filenames */ 0212 const std::map<QString, QString> color_schemes() { return m_color_schemes; }; 0213 0214 /** @return pointer to the KSUserDB object */ 0215 KSUserDB *userdb() { return &m_ksuserdb; } 0216 0217 /** @return pointer to the simulation Clock object */ 0218 Q_INVOKABLE SimClock *clock() 0219 { 0220 return &Clock; 0221 } 0222 0223 /** @return pointer to the local sidereal time: a dms object */ 0224 CachingDms *lst() 0225 { 0226 return &LST; 0227 } 0228 0229 /** @return pointer to the GeoLocation object*/ 0230 GeoLocation *geo() 0231 { 0232 return &m_Geo; 0233 } 0234 0235 /** @return list of all geographic locations */ 0236 QList<GeoLocation *> &getGeoList() 0237 { 0238 return geoList; 0239 } 0240 0241 GeoLocation *locationNamed(const QString &city, const QString &province = QString(), 0242 const QString &country = QString()); 0243 0244 /** 0245 * @brief nearestLocation Return nearest location to the given longitude and latitude coordinates 0246 * @param longitude Longitude (-180 to +180) 0247 * @param latitude Latitude (-90 to +90) 0248 * @return nearest geographical location to the parameters above. 0249 */ 0250 GeoLocation *nearestLocation(double longitude, double latitude); 0251 0252 /** 0253 * Set the GeoLocation according to the argument. 0254 * @param l reference to the new GeoLocation 0255 */ 0256 void setLocation(const GeoLocation &l); 0257 0258 /** Set the GeoLocation according to the values stored in the configuration file. */ 0259 void setLocationFromOptions(); 0260 0261 /** Return map for daylight saving rules. */ 0262 const QMap<QString, TimeZoneRule> &getRulebook() const 0263 { 0264 return Rulebook; 0265 } 0266 0267 /** @return whether the next Focus change will omit the slewing animation. */ 0268 bool snapNextFocus() const 0269 { 0270 return snapToFocus; 0271 } 0272 0273 /** 0274 * Disable or re-enable the slewing animation for the next Focus change. 0275 * @note If the user has turned off all animated slewing, setSnapNextFocus(false) 0276 * will *NOT* enable animation on the next slew. A false argument would only 0277 * be used if you have previously called setSnapNextFocus(true), but then decided 0278 * you didn't want that after all. In other words, it's extremely unlikely you'd 0279 * ever want to use setSnapNextFocus(false). 0280 * @param b when true (the default), the next Focus change will omit the slewing 0281 * animation. 0282 */ 0283 void setSnapNextFocus(bool b = true) 0284 { 0285 snapToFocus = b; 0286 } 0287 0288 /** 0289 * Execute a script. This function actually duplicates the DCOP functionality 0290 * for those cases when invoking DCOP is not practical (i.e., when preparing 0291 * a sky image in command-line dump mode). 0292 * @param name the filename of the script to "execute". 0293 * @param map pointer to the SkyMap object. 0294 * @return true if the script was successfully parsed. 0295 */ 0296 bool executeScript(const QString &name, SkyMap *map); 0297 0298 /** Synchronize list of visible FOVs and list of selected FOVs in Options */ 0299 #ifndef KSTARS_LITE 0300 void syncFOV(); 0301 #endif 0302 0303 /** 0304 * @return the list of visible FOVs 0305 */ 0306 inline const QList<FOV *> getVisibleFOVs() const 0307 { 0308 return visibleFOVs; 0309 } 0310 0311 /** 0312 * @return the list of available FOVs 0313 */ 0314 inline const QList<FOV *> getAvailableFOVs() const 0315 { 0316 return availFOVs; 0317 } 0318 0319 /** 0320 * @brief addTransientFOV Adds a new FOV to the list. 0321 * @param newFOV pointer to FOV object. 0322 */ 0323 inline void addTransientFOV(std::shared_ptr<FOV> newFOV) 0324 { 0325 transientFOVs.append(newFOV); 0326 } 0327 inline void clearTransientFOVs() 0328 { 0329 transientFOVs.clear(); 0330 } 0331 0332 /** 0333 * @return the list of transient FOVs 0334 */ 0335 inline const QList<std::shared_ptr<FOV>> getTransientFOVs() const 0336 { 0337 return transientFOVs; 0338 } 0339 #ifndef KSTARS_LITE 0340 /** Return log object */ 0341 OAL::Log *logObject() 0342 { 0343 return m_LogObject.get(); 0344 } 0345 0346 /** Return ADV Tree */ 0347 QList<ADVTreeData *> avdTree() 0348 { 0349 return ADVtreeList; 0350 } 0351 0352 inline ObservingList *observingList() const 0353 { 0354 return m_ObservingList; 0355 } 0356 0357 ImageExporter *imageExporter(); 0358 0359 Execute *executeSession(); 0360 #endif 0361 /*@short Increments the updateID, forcing a recomputation of star positions as well */ 0362 unsigned int incUpdateID(); 0363 0364 unsigned int updateID() const 0365 { 0366 return m_updateID; 0367 } 0368 unsigned int updateNumID() const 0369 { 0370 return m_updateNumID; 0371 } 0372 KSNumbers *updateNum() 0373 { 0374 return &m_updateNum; 0375 } 0376 void syncUpdateIDs(); 0377 0378 signals: 0379 /** Signal that specifies the text that should be drawn in the KStarsSplash window. */ 0380 void progressText(const QString &text); 0381 0382 /** Should be used to refresh skymap. */ 0383 void skyUpdate(bool); 0384 0385 /** If data changed, emit clearCache signal. */ 0386 void clearCache(); 0387 0388 /** Emitted when geo location changed */ 0389 void geoChanged(); 0390 0391 public slots: 0392 /** @short send a message to the console*/ 0393 void slotConsoleMessage(QString s) 0394 { 0395 std::cout << (const char *)(s.toLocal8Bit()) << std::endl; 0396 } 0397 0398 /** 0399 * Update the Simulation Clock. Update positions of Planets. Update 0400 * Alt/Az coordinates of objects. Update precession. 0401 * emit the skyUpdate() signal so that SkyMap / whatever draws the sky can update itself 0402 * 0403 * This is ugly. 0404 * It _will_ change! 0405 * (JH:)hey, it's much less ugly now...can we lose the comment yet? :p 0406 */ 0407 void updateTime(GeoLocation *geo, const bool automaticDSTchange = true); 0408 0409 /** 0410 * Sets the direction of time and stores it in bool TimeRunForwards. If scale >= 0 0411 * time is running forward else time runs backward. We need this to calculate just 0412 * one daylight saving change time (previous or next DST change). 0413 */ 0414 void setTimeDirection(float scale); 0415 0416 // What follows is mostly a port of Arkashs auxdata stuff to a 0417 // more centralized approach that does not store the data in 0418 // the skyobjects as they are ephemeral in the new DSO implementation 0419 // 0420 // I've tried to reuse as much code as possible and maintain 0421 // compatibility with peoples data. 0422 // 0423 // -- Valentin Boettcher 0424 0425 /** 0426 * Get a reference to the user data of an object with the name \p name. 0427 */ 0428 const SkyObjectUserdata::Data &getUserData(const QString &name); 0429 0430 /** 0431 * Adds a link \p data to the user data for the object with \p 0432 * name, both in memory and on disk. 0433 * 0434 * @returns {success, error_message} 0435 */ 0436 std::pair<bool, QString> addToUserData(const QString &name, 0437 const SkyObjectUserdata::LinkData &data); 0438 0439 /** 0440 * Replace \p data in the user data at \p index for the object with \p 0441 * name, both in memory and on disk. 0442 * 0443 * @returns {success, error_message} 0444 */ 0445 std::pair<bool, QString> editUserData(const QString &name, 0446 const unsigned int index, 0447 const SkyObjectUserdata::LinkData &data); 0448 0449 /** 0450 * Remove data of \p type from the user data at \p index for 0451 * the object with \p name, both in memory and on disk. 0452 * 0453 * @returns {success, error_message} 0454 */ 0455 std::pair<bool, QString> deleteUserData(const QString &name, 0456 const unsigned int index, 0457 SkyObjectUserdata::Type type); 0458 /** 0459 * Update the user log of the object with the \p name to 0460 * contain \p newLog (find and replace). 0461 * 0462 * @returns {success, error_message} 0463 */ 0464 std::pair<bool, QString> updateUserLog(const QString &name, 0465 const QString &newLog); 0466 0467 private: 0468 /** 0469 * Populate list of geographic locations from "citydb.sqlite" database. Also check for custom 0470 * locations file "mycitydb.sqlite" database, but don't require it. Each line in the file 0471 * provides the information required to create one GeoLocation object. 0472 * @short Fill list of geographic locations from file(s) 0473 * @return true if at least one city read successfully. 0474 * @see KStarsData::processCity() 0475 */ 0476 bool readCityData(); 0477 0478 /** Read the data file that contains daylight savings time rules. */ 0479 bool readTimeZoneRulebook(); 0480 0481 //TODO JM: ADV tree should use XML instead 0482 /** 0483 * Read Advanced interface structure to be used later to construct the list view in 0484 * the advanced tab in the Detail Dialog. 0485 * @li KSLABEL designates a top-level parent label 0486 * @li KSINTERFACE designates a common URL interface for several objects 0487 * @li END designates the end of a sub tree structure 0488 * @short read online database lookup structure. 0489 * @return true if data is successfully read. 0490 */ 0491 bool readADVTreeData(); 0492 0493 /** Read INDI hosts from an XML file */ 0494 bool readINDIHosts(); 0495 0496 //TODO JM: Use XML instead; The logger should have more features 0497 // that allow users to enter details about their observation logs 0498 // objects observed, eye pieces, telescope, conditions, mag..etc 0499 /** 0500 * @short read user logs. 0501 * 0502 * Read user logs. The log file is formatted as following: 0503 * @li KSLABEL designates the beginning of a log 0504 * @li KSLogEnd designates the end of a log. 0505 * 0506 * @return true if data is successfully read. 0507 */ 0508 bool readUserLog(); 0509 0510 /** 0511 * Read in URLs to be attached to a named object's right-click popup menu. At this 0512 * point, there is no way to attach URLs to unnamed objects. There are two 0513 * kinds of URLs, each with its own data file: image links and webpage links. In addition, 0514 * there may be user-specific versions with custom URLs. Each line contains 3 fields 0515 * separated by colons (":"). Note that the last field is the URL, and as such it will 0516 * generally contain a colon itself. Only the first two colons encountered are treated 0517 * as field separators. The fields are: 0518 * 0519 * @li Object name. This must be the "primary" name of the object (the name at the top of the popup menu). 0520 * @li Menu text. The string that should appear in the popup menu to activate the link. 0521 * @li URL. 0522 * @short Read in image and information URLs. 0523 * @return true if data files were successfully read. 0524 */ 0525 bool readURLData(const QString &url, 0526 SkyObjectUserdata::Type type = SkyObjectUserdata::Type::website); 0527 0528 /** 0529 * @short open a file containing URL links. 0530 * @param urlfile string representation of the filename to open 0531 * @param file reference to the QFile object which will be opened to this file. 0532 * @return true if file successfully opened. 0533 */ 0534 bool openUrlFile(const QString &urlfile, QFile &file); 0535 0536 /** 0537 * Reset local time to new daylight saving time. Use this function if DST has changed. 0538 * Used by updateTime(). 0539 */ 0540 void resetToNewDST(GeoLocation *geo, const bool automaticDSTchange); 0541 0542 /** 0543 * As KStarsData::getUserData just non-const. 0544 * @warning This method is not thread safe :) so take care of that when you use it. 0545 */ 0546 SkyObjectUserdata::Data &findUserData(const QString &name); 0547 0548 QList<ADVTreeData *> ADVtreeList; 0549 std::unique_ptr<SkyMapComposite> m_SkyComposite; 0550 0551 GeoLocation m_Geo; 0552 SimClock Clock; 0553 KStarsDateTime LTime; 0554 KSUserDB m_ksuserdb; 0555 ColorScheme CScheme; 0556 std::map<QString, QString> m_color_schemes; // name: filename 0557 std::map<QString, QString> m_color_scheme_names; // filename: name 0558 0559 #ifndef KSTARS_LITE 0560 ObservingList* m_ObservingList { nullptr }; 0561 std::unique_ptr<OAL::Log> m_LogObject; 0562 std::unique_ptr<Execute> m_Execute; 0563 std::unique_ptr<ImageExporter> m_ImageExporter; 0564 #endif 0565 0566 //EquipmentWriter *m_equipmentWriter; 0567 0568 bool TimeRunsForward { false }; 0569 bool temporaryTrail { false }; 0570 // FIXME: Used in SkyMap only. Check! 0571 bool snapToFocus { false }; 0572 0573 //KLocale *locale; 0574 0575 CachingDms LST; 0576 0577 QKeySequence resumeKey; 0578 0579 QList<FOV *> availFOVs; // List of all available FOVs 0580 QList<FOV *> visibleFOVs; // List of visible FOVs. Cached from Options::FOVNames 0581 QList<std::shared_ptr<FOV>> transientFOVs; // List of non-permenant transient FOVs. 0582 0583 KStarsDateTime LastNumUpdate, LastSkyUpdate, LastPlanetUpdate, LastMoonUpdate; 0584 KStarsDateTime NextDSTChange; 0585 // FIXME: Used in kstarsdcop.cpp only 0586 KStarsDateTime StoredDate; 0587 0588 QList<GeoLocation *> geoList; 0589 QMap<QString, TimeZoneRule> Rulebook; 0590 0591 quint32 m_preUpdateID, m_updateID; 0592 quint32 m_preUpdateNumID, m_updateNumID; 0593 KSNumbers m_preUpdateNum, m_updateNum; 0594 0595 static KStarsData *pinstance; 0596 0597 std::unordered_map<QString, SkyObjectUserdata::Data> m_user_data; 0598 QMutex m_user_data_mutex; // for m_user_data 0599 };