8#include "config-kstars.h"
9#include "ksnotification.h"
10#include "kstars_debug.h"
12#include "catalogobject.h"
17#include "starobject.h"
18#include "auxiliary/kspaths.h"
26#include <libraw/libraw.h>
30#include <sys/sysctl.h>
38#include <QProcessEnvironment>
39#include <QLoggingCategory>
41#ifdef HAVE_STELLARSOLVER
42#include <stellarsolver.h>
47bool isHardwareLimited()
92 width = a * sin(pa) + b * cos(pa);
93 height = a * cos(pa) + b * sin(pa);
112 return getDSSURL(p->
ra0(), p->
dec0(), width, height);
115QString getDSSURL(
const dms &ra,
const dms &dec,
float width,
float height,
122 char decsgn = (
dec.Degrees() < 0.0) ?
'-' :
'+';
128 if (!qIsFinite(height) || height <= 0.0)
130 if (!qIsFinite(width) || width <= 0.0)
157 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"N"),
158 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"NNE"),
159 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"NE"),
160 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"ENE"),
161 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"E"),
162 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"ESE"),
163 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"SE"),
164 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"SSE"),
165 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"S"),
166 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"SSW"),
167 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"SW"),
168 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"WSW"),
169 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"W"),
170 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"WNW"),
171 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"NW"),
172 I18N_NOOP2(
"Abbreviated cardinal / intercardinal etc. direction",
"NNW"),
173 I18N_NOOP2(
"Unknown cardinal / intercardinal direction",
"???")
176 int index = (int)((angle.
reduce().Degrees() + 11.25) /
182 index = (index == 16 ? 0 : index);
184 return i18nc(
"Abbreviated cardinal / intercardinal etc. direction",
222 return QString(
"Camelopardalis");
226 return QString(
"Canum Venaticorum");
228 return QString(
"Canis Majoris");
230 return QString(
"Canis Minoris");
244 return QString(
"Chamaeleontis");
250 return QString(
"Comae Berenices");
252 return QString(
"Coronae Austrinae");
254 return QString(
"Coronae Borealis");
294 return QString(
"Leonis Minoris");
334 return QString(
"Piscis Austrini");
362 return QString(
"Trianguli Australis");
366 return QString(
"Ursae Majoris");
368 return QString(
"Ursae Minoris");
403 return QString(
"Camelopardalis");
407 return QString(
"Canes Venatici");
431 return QString(
"Coma Berenices");
433 return QString(
"Corona Australis");
435 return QString(
"Corona Borealis");
489 return QString(
"Microscopium");
515 return QString(
"Piscis Austrinus");
543 return QString(
"Triangulum Australe");
564 if (fullName ==
"andromeda")
566 if (fullName ==
"antlia")
568 if (fullName ==
"apus")
570 if (fullName ==
"aquarius")
572 if (fullName ==
"aquila")
574 if (fullName ==
"ara")
576 if (fullName ==
"aries")
578 if (fullName ==
"auriga")
580 if (fullName ==
"bootes")
582 if (fullName ==
"caelum")
584 if (fullName ==
"camelopardalis")
586 if (fullName ==
"cancer")
588 if (fullName ==
"canes venatici")
590 if (fullName ==
"canis major")
592 if (fullName ==
"canis minor")
594 if (fullName ==
"capricornus")
596 if (fullName ==
"carina")
598 if (fullName ==
"cassiopeia")
600 if (fullName ==
"centaurus")
602 if (fullName ==
"cepheus")
604 if (fullName ==
"cetus")
606 if (fullName ==
"chamaeleon")
608 if (fullName ==
"circinus")
610 if (fullName ==
"columba")
612 if (fullName ==
"coma berenices")
614 if (fullName ==
"corona australis")
616 if (fullName ==
"corona borealis")
618 if (fullName ==
"corvus")
620 if (fullName ==
"crater")
622 if (fullName ==
"crux")
624 if (fullName ==
"cygnus")
626 if (fullName ==
"delphinus")
628 if (fullName ==
"doradus")
630 if (fullName ==
"draco")
632 if (fullName ==
"equuleus")
634 if (fullName ==
"eridanus")
636 if (fullName ==
"fornax")
638 if (fullName ==
"gemini")
640 if (fullName ==
"grus")
642 if (fullName ==
"hercules")
644 if (fullName ==
"horologium")
646 if (fullName ==
"hydra")
648 if (fullName ==
"hydrus")
650 if (fullName ==
"indus")
652 if (fullName ==
"lacerta")
654 if (fullName ==
"leo")
656 if (fullName ==
"leo minor")
658 if (fullName ==
"lepus")
660 if (fullName ==
"libra")
662 if (fullName ==
"lupus")
664 if (fullName ==
"lynx")
666 if (fullName ==
"lyra")
668 if (fullName ==
"mensa")
670 if (fullName ==
"microscopium")
672 if (fullName ==
"monoceros")
674 if (fullName ==
"musca")
676 if (fullName ==
"norma")
678 if (fullName ==
"octans")
680 if (fullName ==
"ophiuchus")
682 if (fullName ==
"orion")
684 if (fullName ==
"pavo")
686 if (fullName ==
"pegasus")
688 if (fullName ==
"perseus")
690 if (fullName ==
"phoenix")
692 if (fullName ==
"pictor")
694 if (fullName ==
"pisces")
696 if (fullName ==
"piscis austrinus")
698 if (fullName ==
"puppis")
700 if (fullName ==
"pyxis")
702 if (fullName ==
"reticulum")
704 if (fullName ==
"sagitta")
706 if (fullName ==
"sagittarius")
708 if (fullName ==
"scorpius")
710 if (fullName ==
"sculptor")
712 if (fullName ==
"scutum")
714 if (fullName ==
"serpens")
716 if (fullName ==
"sextans")
718 if (fullName ==
"taurus")
720 if (fullName ==
"telescopium")
722 if (fullName ==
"triangulum")
724 if (fullName ==
"triangulum australe")
726 if (fullName ==
"tucana")
728 if (fullName ==
"ursa major")
730 if (fullName ==
"ursa minor")
732 if (fullName ==
"vela")
734 if (fullName ==
"virgo")
736 if (fullName ==
"volans")
738 if (fullName ==
"vulpecula")
770 if (
genetive ==
"canum venaticorum")
796 if (
genetive ==
"coronae austrinae")
906 if (
genetive ==
"trianguli australis")
929 if (_filename.isEmpty())
941 QFile file(_filename);
947 "%{if-debug}DEBG%{endif}%{if-info}INFO%{endif}%{if-warning}WARN%{"
948 "endif}%{if-critical}CRIT%{endif}%{if-fatal}FATL%{endif}] "
949 "%{if-category}[%{category}]%{endif} - %{message}");
955 QFile file(_filename);
959 Write(stream, type, context, msg);
966 "%{if-debug}DEBG%{endif}%{if-info}INFO%{endif}%{if-warning}WARN%{"
967 "endif}%{if-critical}CRIT%{endif}%{if-fatal}FATL%{endif}] "
968 "%{if-category}[%{category}]%{endif} - %{message}");
976 Write(stream, type, context, msg);
988 Write(stream, type, context, msg);
1017 stream <<
"[" << qSetFieldWidth(30) << context.category << qSetFieldWidth(0)
1019 stream << msg <<
'\n';
1063 rules <<
"org.kde.kstars.ekos.debug"
1064 << (Options::verboseLogging() ?
"true" :
"false");
1065 rules <<
"org.kde.kstars.indi.debug" << (Options::iNDILogging() ?
"true" :
"false");
1066 rules <<
"org.kde.kstars.fits.debug" << (Options::fITSLogging() ?
"true" :
"false");
1067 rules <<
"org.kde.kstars.ekos.capture.debug"
1068 << (Options::captureLogging() ?
"true" :
"false");
1069 rules <<
"org.kde.kstars.ekos.focus.debug"
1070 << (Options::focusLogging() ?
"true" :
"false");
1071 rules <<
"org.kde.kstars.ekos.guide.debug"
1072 << (Options::guideLogging() ?
"true" :
"false");
1073 rules <<
"org.kde.kstars.ekos.align.debug"
1074 << (Options::alignmentLogging() ?
"true" :
"false");
1075 rules <<
"org.kde.kstars.ekos.mount.debug"
1076 << (Options::mountLogging() ?
"true" :
"false");
1077 rules <<
"org.kde.kstars.ekos.scheduler.debug"
1078 << (Options::schedulerLogging() ?
"true" :
"false");
1079 rules <<
"org.kde.kstars.ekos.observatory.debug"
1080 << (Options::observatoryLogging() ?
"true" :
"false");
1081 rules <<
"org.kde.kstars.debug" << (Options::verboseLogging() ?
"true" :
"false");
1084 for (
int i = 0; i <
rules.size(); i += 2)
1112 appimg.isEmpty() ==
false)
1114 else if (flat.
isEmpty() ==
false)
1118 else if (
snap.isEmpty() ==
false)
1121 if (option ==
"fitsDir")
1125 else if (option ==
"indiServer")
1127#if defined(INDI_PREFIX)
1129#elif defined(Q_OS_OSX)
1130 return "/usr/local/bin/indiserver";
1132 return prefix +
"/bin/indiserver";
1134 else if (option ==
"PlaceholderFormat")
1136#if defined(Q_OS_WIN)
1137 return "\\%t\\%T\\%F\\%t_%T_%F";
1139 return "/%t/%T/%F/%t_%T_%F";
1142 else if (option ==
"INDIHubAgent")
1144#if defined(INDI_PREFIX)
1146#elif defined(Q_OS_OSX)
1147 return "/usr/local/bin/indihub-agent";
1149 return prefix +
"/bin/indihub-agent";
1151 else if (option ==
"indiDriversDir")
1153#if defined(INDI_PREFIX)
1155#elif defined(Q_OS_OSX)
1156 return "/usr/local/share/indi";
1157#elif defined(Q_OS_LINUX)
1158 return prefix +
"/share/indi";
1164 else if (option ==
"AstrometrySolverBinary")
1166#if defined(ASTROMETRY_PREFIX)
1168#elif defined(Q_OS_OSX)
1169 return "/usr/local/bin/solve-field";
1170#elif defined(Q_OS_WIN)
1172 "/AppData/Local/cygwin_ansvr/lib/astrometry/bin/solve-field.exe";
1174 return prefix +
"/bin/solve-field";
1176 else if (option ==
"WatneyBinary")
1178#if defined(ASTROMETRY_PREFIX)
1180#elif defined(Q_OS_OSX)
1181 return "/usr/local/bin/watney-solve";
1182#elif defined(Q_OS_WIN)
1183 return "C:/watney/watney-solve.exe";
1185 return prefix +
"/opt/watney/watney-solve";
1187 else if (option ==
"SextractorBinary")
1189#if defined(SEXTRACTOR_PREFIX)
1191#elif defined(Q_OS_OSX)
1192 return "/usr/local/bin/sex";
1194 return prefix +
"/bin/sextractor";
1196 else if (option ==
"AstrometryWCSInfo")
1198#if defined(ASTROMETRY_PREFIX)
1200#elif defined(Q_OS_OSX)
1201 return "/usr/local/bin/wcsinfo";
1202#elif defined(Q_OS_WIN)
1204 "/AppData/Local/cygwin_ansvr/lib/astrometry/bin/wcsinfo.exe";
1206 return prefix +
"/bin/wcsinfo";
1208 else if (option ==
"AstrometryConfFile")
1210#if defined(ASTROMETRY_CONF_IN_PREFIX) && defined(ASTROMETRY_PREFIX)
1212#elif defined(Q_OS_OSX)
1213 return "/usr/local/etc/astrometry.cfg";
1214#elif defined(Q_OS_WIN)
1216 "/AppData/Local/cygwin_ansvr/etc/astrometry/backend.cfg";
1220 return prefix +
"/etc/astrometry.cfg";
1222 else if (option ==
"AstrometryIndexFileLocation")
1224#if defined(ASTROMETRY_PREFIX)
1226#elif defined(Q_OS_OSX)
1230 return prefix +
"/share/astrometry/";
1232 else if (option ==
"AstrometryLogFilepath")
1236 else if (option ==
"XplanetPath")
1238#if defined(XPLANET_PREFIX)
1240#elif defined(Q_OS_OSX)
1241 return "/usr/local/bin/xplanet";
1243 return prefix +
"/bin/xplanet";
1245 else if (option ==
"ASTAP")
1247#if defined(Q_OS_OSX)
1248 return "/Applications/ASTAP.app/Contents/MacOS/astap";
1249#elif defined(Q_OS_WIN)
1250 return "C:/Program Files/astap/astap.exe";
1252 return "/opt/astap/astap";
1271 qCCritical(
KSTARS) <<
"Failed to create local astrometry directory";
1276#ifdef HAVE_STELLARSOLVER
1282#if defined(Q_OS_OSX)
1289 if (folder ==
"kstars")
1319 if (Options::kStarsFirstRun())
1322 Options::setIndiServerIsInternal(
true);
1323 Options::setIndiServer(
"*Internal INDI Server*");
1324 Options::setIndiDriversAreInternal(
true);
1325 Options::setIndiDriversDir(
"*Internal INDI Drivers*");
1326 Options::setXplanetIsInternal(
true);
1327 Options::setXplanetPath(
"*Internal XPlanet*");
1348 if (KMessageBox::warningYesNo(
1350 i18n(
"The selected Astrometry Index File Location:\n %1 \n does not "
1351 "exist. Do you want to make the directory?",
1353 i18n(
"Make Astrometry Index File Directory?")) == KMessageBox::Yes)
1357 KSNotification::info(
1358 i18n(
"The Default Astrometry Index File Location was created."));
1362 KSNotification::sorry(
1363 i18n(
"The Default Astrometry Index File Directory does not exist and "
1364 "was not able to be created."));
1384 KSNotification::error(
i18n(
"Astrometry Configuration File Read Error."));
1392 contents.
replace(
"IndexFileLocationNotYetSet",
1393 getDefaultPath(
"AstrometryIndexFileLocation"));
1397 KSNotification::error(
1398 i18n(
"Internal Astrometry Configuration File Write Error."));
1423 for (
int i = 0; i < files.
count(); i++)
1432 for (
int i = 0; i < files.
count(); i++)
1443QString getAstrometryConfFilePath()
1445 return Options::astrometryConfFile();
1452 bool updated =
false;
1488 line = in.readLine();
1540 KSNotification::error(
i18n(
"Astrometry Configuration File Read Error."));
1550 line = in.readLine();
1559 contents +=
"add_path " +
dataDir +
'\n';
1568 contents += line +
'\n';
1575 contents +=
"add_path " +
dataDir +
'\n';
1582 KSNotification::error(
1583 i18n(
"Internal Astrometry Configuration File Write Error."));
1605 KSNotification::error(
i18n(
"Astrometry Configuration File Read Error."));
1614 line = in.readLine();
1617 contents += line +
'\n';
1624 KSNotification::error(
1625 i18n(
"Internal Astrometry Configuration File Write Error."));
1648 if (filters.size() > 0)
1651 for (
const auto &item : filters)
1653 filter_string +=
"\"" + item.item +
"|" + item.op +
"|" + item.value +
"\",";
1671 errorMessage =
i18n(
"Unable to find dcraw and cjpeg. Please install the required "
1672 "tools to convert CR2/NEF to JPEG.");
1710double getAvailableRAM()
1712#if defined(Q_OS_OSX)
1715 length =
sizeof(int64_t);
1721#elif defined(Q_OS_LINUX)
1724 <<
"/proc/meminfo");
1729 return (
memory.toLong() * 1024.0);
1730#elif defined(Q_OS_WIN32)
1746JPLParser::JPLParser(
const QString &path)
1751 throw std::runtime_error(
"Could not open file.");
1755 const auto &fields =
ast_json[
"fields"].toArray();
1756 m_data =
ast_json[
"data"].toArray();
1760 for (
const auto &field : fields)
1762 m_field_map[field.toString()] = i++;
1767MPCParser::MPCParser(
const QString &path)
1772 throw std::runtime_error(
"Could not open file.");
1780 const uint32_t
len = 32768;
1782 while (!
gzeof(file))
1784 char buffer[
len] = {0};
1800void setGlobalSettings(
const QVariantMap &settings)
1802 for (
auto &key : settings.keys())
1804 auto property = key;
1807 if (property.startsWith(
"kcfg_"))
1809 property.remove(
"kcfg_");
1810 property.replace(0, 1, property.at(0).toLower());
1812 Options::self()->setProperty(property.toLatin1(), settings[key]);
1815 Options::self()->save();
1837double rangePA(
double pa)
1846double range360(
double r)
1851 while (
res > 359.99)
1856double rotationToPositionAngle(
double value)
1858 double pa = value + 180;
1866double positionAngleToRotation(
double value)
1868 double rotation = value - 180;
1869 while (rotation > 180)
1871 while (rotation < -180)
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
static void UseDefault()
Use the default logging mechanism.
static void UseStdout()
Output logs to stdout.
static void SyncFilterRules()
SyncFilterRules Sync QtLogging filter rules from Options.
static void Disable()
Disable logging.
static void UseFile()
Store all logs into the specified file.
static void UseStderr()
Output logs to stderr.
KStars utility functions.
The sky coordinates of a point in the sky.
const CachingDms & ra0() const
const CachingDms & dec0() const
This is a subclass of SkyObject.
An angle, stored as degrees, but expressible in many ways.
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString fullName(const PartType &type)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
KCALUTILS_EXPORT QString errorMessage(const KCalendarCore::Exception &exception)
KIOCORE_EXPORT MkdirJob * mkdir(const QUrl &url, int permissions=-1)
QString path(const QString &relativePath)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QByteArray & append(QByteArrayView data)
const char * constData() const const
QString applicationDirPath()
QDateTime currentDateTime()
QString toString(QStringView format, QCalendar cal) const const
QString absolutePath() const const
QString filePath(const QString &fileName) const const
QString toNativeSeparators(const QString &pathName)
bool copy(const QString &fileName, const QString &newName)
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
void setFileName(const QString &name)
virtual void close() override
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
qsizetype count() const const
void setFilterRules(const QString &rules)
virtual void close() override
QByteArray readAllStandardOutput()
void start(OpenMode mode)
bool waitForFinished(int msecs)
QProcessEnvironment systemEnvironment()
QString value(const QString &name, const QString &defaultValue) const const
QString locate(StandardLocation type, const QString &fileName, LocateOptions options)
QString writableLocation(StandardLocation type)
QString arg(Args &&... args) const const
QString asprintf(const char *cformat,...)
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
bool isNull() const const
QString mid(qsizetype position, qsizetype n) const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toLatin1() const const
QString trimmed() const const
QTextStream & dec(QTextStream &stream)