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"
21 #include <KMessageBox>
26 #include <libraw/libraw.h>
29 #if defined(__APPLE__)
30 #include <sys/sysctl.h>
38 #include <QProcessEnvironment>
39 #include <QLoggingCategory>
41 #ifdef HAVE_STELLARSOLVER
42 #include <stellarsolver.h>
47 bool isHardwareLimited()
70 double dss_default_size = Options::defaultDSSImageSize();
71 double dss_padding = Options::dSSPadding();
74 Q_ASSERT(dss_default_size > 0.0 && dss_padding >= 0.0);
92 width = a * sin(pa) + b * cos(pa);
93 height = a * cos(pa) + b * sin(pa);
97 height += dss_padding;
104 height = width = dss_default_size;
107 if (height < dss_default_size)
108 height = dss_default_size;
109 if (width < dss_default_size)
110 width = dss_default_size;
112 return getDSSURL(p->
ra0(), p->
dec0(), width, height);
115 QString getDSSURL(
const dms &ra,
const dms &dec,
float width,
float height,
118 const QString URLprefix(
"https://archive.stsci.edu/cgi-bin/dss_search?");
120 const double dss_default_size = Options::defaultDSSImageSize();
122 char decsgn = (
dec.Degrees() < 0.0) ?
'-' :
'+';
123 int dd = abs(
dec.degree());
124 int dm = abs(
dec.arcmin());
125 int ds = abs(
dec.arcsec());
128 if (!qIsFinite(height) || height <= 0.0)
129 height = dss_default_size;
130 if (!qIsFinite(width) || width <= 0.0)
131 width = dss_default_size;
139 QString RAString, DecString, SizeString;
144 return (URLprefix + RAString + DecString + SizeString + URLsuffix);
155 static const char *directions[] =
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",
"???")
179 if (index < 0 || index > 16)
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")
746 if (genetive ==
"andromedae")
748 if (genetive ==
"antliae")
750 if (genetive ==
"apodis")
752 if (genetive ==
"aquarii")
754 if (genetive ==
"aquilae")
756 if (genetive ==
"arae")
758 if (genetive ==
"arietis")
760 if (genetive ==
"aurigae")
762 if (genetive ==
"bootis")
764 if (genetive ==
"caeli")
766 if (genetive ==
"camelopardalis")
768 if (genetive ==
"cancri")
770 if (genetive ==
"canum venaticorum")
772 if (genetive ==
"canis majoris")
774 if (genetive ==
"canis minoris")
776 if (genetive ==
"capricorni")
778 if (genetive ==
"carinae")
780 if (genetive ==
"cassiopeiae")
782 if (genetive ==
"centauri")
784 if (genetive ==
"cephei")
786 if (genetive ==
"ceti")
788 if (genetive ==
"chamaeleontis")
790 if (genetive ==
"circini")
792 if (genetive ==
"columbae")
794 if (genetive ==
"comae berenices")
796 if (genetive ==
"coronae austrinae")
798 if (genetive ==
"coronae borealis")
800 if (genetive ==
"corvi")
802 if (genetive ==
"crateris")
804 if (genetive ==
"crucis")
806 if (genetive ==
"cygni")
808 if (genetive ==
"delphini")
810 if (genetive ==
"doradus")
812 if (genetive ==
"draconis")
814 if (genetive ==
"equulei")
816 if (genetive ==
"eridani")
818 if (genetive ==
"fornacis")
820 if (genetive ==
"geminorum")
822 if (genetive ==
"gruis")
824 if (genetive ==
"herculis")
826 if (genetive ==
"horologii")
828 if (genetive ==
"hydrae")
830 if (genetive ==
"hydri")
832 if (genetive ==
"indi")
834 if (genetive ==
"lacertae")
836 if (genetive ==
"leonis")
838 if (genetive ==
"leonis minoris")
840 if (genetive ==
"leporis")
842 if (genetive ==
"librae")
844 if (genetive ==
"lupi")
846 if (genetive ==
"lyncis")
848 if (genetive ==
"lyrae")
850 if (genetive ==
"mensae")
852 if (genetive ==
"microscopii")
854 if (genetive ==
"monocerotis")
856 if (genetive ==
"muscae")
858 if (genetive ==
"normae")
860 if (genetive ==
"octantis")
862 if (genetive ==
"ophiuchi")
864 if (genetive ==
"orionis")
866 if (genetive ==
"pavonis")
868 if (genetive ==
"pegasi")
870 if (genetive ==
"persei")
872 if (genetive ==
"phoenicis")
874 if (genetive ==
"pictoris")
876 if (genetive ==
"piscium")
878 if (genetive ==
"piscis austrini")
880 if (genetive ==
"puppis")
882 if (genetive ==
"pyxidis")
884 if (genetive ==
"reticuli")
886 if (genetive ==
"sagittae")
888 if (genetive ==
"sagittarii")
890 if (genetive ==
"scorpii")
892 if (genetive ==
"sculptoris")
894 if (genetive ==
"scuti")
896 if (genetive ==
"serpentis")
898 if (genetive ==
"sextantis")
900 if (genetive ==
"tauri")
902 if (genetive ==
"telescopii")
904 if (genetive ==
"trianguli")
906 if (genetive ==
"trianguli australis")
908 if (genetive ==
"tucanae")
910 if (genetive ==
"ursae majoris")
912 if (genetive ==
"ursae minoris")
914 if (genetive ==
"velorum")
916 if (genetive ==
"virginis")
918 if (genetive ==
"volantis")
920 if (genetive ==
"vulpeculae")
941 QFile file(_filename);
946 qSetMessagePattern(
"[%{time yyyy-MM-dd h:mm:ss.zzz t} "
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}");
950 qInstallMessageHandler(File);
955 QFile file(_filename);
959 Write(stream, type, context, msg);
965 qSetMessagePattern(
"[%{time yyyy-MM-dd h:mm:ss.zzz t} "
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}");
969 qInstallMessageHandler(Stdout);
976 Write(stream, type, context, msg);
981 qInstallMessageHandler(Stderr);
988 Write(stream, type, context, msg);
991 void Logging::Write(
QTextStream &stream, QtMsgType type,
1017 stream <<
"[" << qSetFieldWidth(30) << context.category << qSetFieldWidth(0)
1019 stream << msg <<
'\n';
1026 qInstallMessageHandler(
nullptr);
1031 qInstallMessageHandler(Disabled);
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)
1113 prefix = appimg + userPrefix;
1114 else if (flat.
isEmpty() ==
false)
1118 else if (snap.
isEmpty() ==
false)
1119 prefix = snap + userPrefix;
1121 if (option ==
"fitsDir")
1125 else if (option ==
"indiServer")
1127 #if defined(INDI_PREFIX)
1128 return QString(INDI_PREFIX
"/bin/indiserver");
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)
1145 return QString(INDI_PREFIX
"/bin/indihub-agent");
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)
1154 return QString(INDI_PREFIX
"/share/indi");
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)
1167 return QString(ASTROMETRY_PREFIX
"/bin/solve-field");
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)
1179 return QString(ASTROMETRY_PREFIX
"/opt/watney/watney-solve");
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)
1190 return QString(SEXTRACTOR_PREFIX
"/bin/sextractor");
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)
1199 return QString(ASTROMETRY_PREFIX
"/bin/wcsinfo");
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)
1211 return QString(ASTROMETRY_PREFIX
"/etc/astrometry.cfg");
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";
1219 prefix.
remove(userPrefix);
1220 return prefix +
"/etc/astrometry.cfg";
1222 else if (option ==
"AstrometryIndexFileLocation")
1224 #if defined(ASTROMETRY_PREFIX)
1225 return QString(ASTROMETRY_PREFIX
"/share/astrometry");
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)
1239 return QString(XPLANET_PREFIX
"/bin/xplanet");
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";
1258 QStringList getAstrometryDefaultIndexFolderPaths()
1264 folderPaths << confDir;
1266 QDir writableDir(confDir);
1267 if (writableDir.exists() ==
false)
1269 if (writableDir.mkdir(confDir) ==
false)
1271 qCCritical(KSTARS) <<
"Failed to create local astrometry directory";
1272 folderPaths.
clear();
1276 #ifdef HAVE_STELLARSOLVER
1277 folderPaths.
append(StellarSolver::getDefaultIndexFolderPaths());
1282 #if defined(Q_OS_OSX)
1284 void copyResourcesFolderFromAppBundle(
QString folder)
1288 QDir folderSourceDir;
1289 if (folder ==
"kstars")
1297 if (folderSourceDir.
exists())
1303 writableDir.
mkdir(folderLocation);
1304 copyRecursively(folderSourceDir.
absolutePath(), folderLocation);
1308 bool setupMacKStarsIfNeeded()
1311 copyResourcesFolderFromAppBundle(
"locale");
1312 copyResourcesFolderFromAppBundle(
"knotifications5");
1313 copyResourcesFolderFromAppBundle(
"sounds");
1316 copyResourcesFolderFromAppBundle(
"kstars");
1317 copyResourcesFolderFromAppBundle(
"kstars/xplanet");
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*");
1338 bool configureAstrometry()
1340 QStringList astrometryDataDirs = getAstrometryDataDirs();
1341 if (astrometryDataDirs.
count() == 0)
1343 QString defaultAstrometryDataDir = getDefaultPath(
"AstrometryIndexFileLocation");
1344 if (astrometryDataDirs.
contains(
"IndexFileLocationNotYetSet"))
1345 replaceIndexFileNotYetSet();
1346 if (
QDir(defaultAstrometryDataDir).exists() ==
false)
1350 i18n(
"The selected Astrometry Index File Location:\n %1 \n does not "
1351 "exist. Do you want to make the directory?",
1352 defaultAstrometryDataDir),
1355 if (
QDir(defaultAstrometryDataDir).
mkdir(defaultAstrometryDataDir))
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."));
1376 bool replaceIndexFileNotYetSet()
1378 QString confPath = KSUtils::getAstrometryConfFilePath();
1380 QFile confFile(confPath);
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."));
1413 QDir sourceDir(sourceFolder);
1415 if (!sourceDir.exists())
1418 QDir destDir(destFolder);
1419 if (!destDir.exists())
1420 destDir.mkdir(destFolder);
1423 for (
int i = 0; i < files.
count(); i++)
1432 for (
int i = 0; i < files.
count(); i++)
1436 copyRecursively(srcName, destName);
1443 QString getAstrometryConfFilePath()
1445 return Options::astrometryConfFile();
1450 QStringList optionsDataDirs = Options::astrometryIndexFolderList();
1452 bool updated =
false;
1455 for (
int dir = 0;
dir < optionsDataDirs.
count();
dir++)
1457 QString optionsDataDirName = optionsDataDirs.
at(dir);
1458 QDir optionsDataDir(optionsDataDirName);
1459 if (optionsDataDir.exists())
1462 if (optionsDataDir.absolutePath() != optionsDataDirName)
1464 optionsDataDirs.
replace(dir, optionsDataDir.absolutePath());
1478 QFile confFile(KSUtils::getAstrometryConfFilePath());
1488 line = in.readLine();
1501 for (
QString astrometryDataDirName : confDataDirs)
1503 QDir astrometryDataDir(astrometryDataDirName);
1505 if (!astrometryDataDir.exists())
1507 QString astrometryDataDirPath = astrometryDataDir.absolutePath();
1508 if (!optionsDataDirs.
contains(astrometryDataDirPath))
1510 optionsDataDirs.
append(astrometryDataDirPath);
1522 Options::setAstrometryIndexFolderList(optionsDataDirs);
1524 return optionsDataDirs;
1527 bool addAstrometryDataDir(
const QString &dataDir)
1533 QString confPath = KSUtils::getAstrometryConfFilePath();
1534 QStringList astrometryDataDirs = getAstrometryDataDirs();
1536 QFile confFile(confPath);
1540 KSNotification::error(
i18n(
"Astrometry Configuration File Read Error."));
1547 bool foundSpot =
false;
1550 line = in.readLine();
1557 for (
QString astrometryDataDir : astrometryDataDirs)
1558 contents +=
"add_path " + astrometryDataDir +
'\n';
1559 contents +=
"add_path " + dataDir +
'\n';
1568 contents += line +
'\n';
1573 for (
QString astrometryDataDir : astrometryDataDirs)
1574 contents +=
"add_path " + astrometryDataDir +
'\n';
1575 contents +=
"add_path " + dataDir +
'\n';
1582 KSNotification::error(
1583 i18n(
"Internal Astrometry Configuration File Write Error."));
1596 bool removeAstrometryDataDir(
const QString &dataDir)
1598 QString confPath = KSUtils::getAstrometryConfFilePath();
1599 QStringList astrometryDataDirs = getAstrometryDataDirs();
1601 QFile confFile(confPath);
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 +
"\",";
1656 filter_string.chop(1);
1657 filter_string +=
"]}";
1659 query +=
"&sb-cdata=" + filter_string;
1663 query +=
"&fields=" + dataFields;
1671 errorMessage =
i18n(
"Unable to find dcraw and cjpeg. Please install the required "
1672 "tools to convert CR2/NEF to JPEG.");
1677 LibRaw RawProcessor;
1680 if ((ret = RawProcessor.open_file(rawImage.
toLatin1().
data())) != LIBRAW_SUCCESS)
1683 RawProcessor.recycle();
1688 if ((ret = RawProcessor.unpack_thumb()) != LIBRAW_SUCCESS)
1690 errorMessage =
i18n(
"Cannot unpack_thumb %1: %2", rawImage, libraw_strerror(ret));
1691 RawProcessor.recycle();
1698 if (LIBRAW_SUCCESS !=
1699 (ret = RawProcessor.dcraw_thumb_writer(output.
toLatin1().
data())))
1701 errorMessage =
i18n(
"Cannot write %s %1: %2", output, libraw_strerror(ret));
1702 RawProcessor.recycle();
1710 double getAvailableRAM()
1712 #if defined(Q_OS_OSX)
1713 int mib[] = { CTL_HW, HW_MEMSIZE };
1715 length =
sizeof(int64_t);
1717 if (sysctl(mib, 2, &RAMcheck, &length, NULL, 0))
1721 #elif defined(Q_OS_LINUX)
1724 <<
"/proc/meminfo");
1729 return (memory.
toLong() * 1024.0);
1730 #elif defined(Q_OS_WIN32)
1731 MEMORYSTATUSEX memory_status;
1732 ZeroMemory(&memory_status,
sizeof(MEMORYSTATUSEX));
1733 memory_status.dwLength =
sizeof(MEMORYSTATUSEX);
1734 if (GlobalMemoryStatusEx(&memory_status))
1736 return memory_status.ullAvailPhys;
1746 JPLParser::JPLParser(
const QString &path)
1748 QFile jpl_file(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++;
1767 MPCParser::MPCParser(
const QString &path)
1769 QFile mpc_file(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};
1785 int bytes_read = gzread(file, buffer, len - 1);
1788 buffer[bytes_read] = 0;
1794 m_data = ast_json.array();
1797 qCritical(KSTARS) <<
"Failed to read MPC comets data file" <<
path;
1800 void 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();
1825 if (sanitized !=
i18n(
"unnamed"))
1828 sanitized = sanitized.
replace(re1,
"_" )
1837 double rangePA(
double pa)
1846 double range360(
double r)
1851 while (res > 359.99)
1856 double rotationToPositionAngle(
double value)
1858 double pa = value + 180;
1866 double positionAngleToRotation(
double value)
1868 double rotation = value - 180;
1869 while (rotation > 180)
1871 while (rotation < -180)