Kstars

main.cpp
1/*
2 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "kspaths.h"
8#include "kstars_debug.h"
9#include "kstarsdata.h"
10#include "kstarsdatetime.h"
11#if defined(KSTARS_LITE)
12#include "kstarslite.h"
13#endif
14#include "ksutils.h"
15#include "Options.h"
16#include "simclock.h"
17#include "version.h"
18#if !defined(KSTARS_LITE)
19#include "kstars.h"
20#include "skymap.h"
21#endif
22
23#if !defined(KSTARS_LITE)
24#include <KAboutData>
25#include <KCrash>
26#endif
27#include <KLocalizedString>
28
29#if defined(Q_OS_MACOS)
30#include <ksnotification.h>
31#endif
32
33#include <QApplication>
34#if !defined(KSTARS_LITE)
35#include <QCommandLineParser>
36#include <QCommandLineOption>
37#endif
38#include <QDebug>
39#include <QPixmap>
40#include <QScreen>
41#include <QtGlobal>
42#include <QTranslator>
43
44#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
45#include <signal.h>
46#endif
47
48#ifndef KSTARS_LITE
49static const QString description = ki18n("Desktop Planetarium").toString();
50static const QString notice = ki18n(
51 "Some images in KStars are for non-commercial use only. See README.images.").toString();
52#endif
53
54#if defined(Q_OS_ANDROID)
55// __attribute__ is needed because clang-based linking removes the main() symbol from the shared library on Android
56Q_DECL_EXPORT
57#endif
58int main(int argc, char *argv[])
59{
60#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
61 // Ignore SIGPIPE
62 signal(SIGPIPE, SIG_IGN);
63#endif
64
66
67 QApplication app(argc, argv);
68
69#ifdef Q_OS_MACOS
70 //Note, this function will return true on OS X if the data directories are good to go. If not, quit with error code 1!
71 if (!KSUtils::setupMacKStarsIfNeeded())
72 {
73 KSNotification::sorry(i18n("Sorry, without a KStars Data Directory, KStars "
74 "cannot operate. Exiting program now."));
75 return 1;
76 }
77#endif
78 Options::setKStarsFirstRun(false);
79 app.setApplicationVersion(KSTARS_VERSION);
80 /**
81 * enable high dpi support
82 */
83 app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
84
86#if defined(KSTARS_LITE)
87#if defined(__ANDROID__)
89 "kstars", "/data/data/org.kde.kstars.lite/qt-reserved-files/share/kstars/locale");
90#else
91 KLocalizedString::addDomainLocaleDir("kstars", "locale");
92#endif
93#endif
94
95#ifndef KSTARS_LITE
96
97 // Create writable data dir if it does not exist
98 QDir writableDir;
99 writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::GenericDataLocation));
100 writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::TempLocation));
101
104 QString("%1 %2").arg(KSTARS_VERSION).arg(KSTARS_BUILD_RELEASE);
105 KAboutData aboutData(
106 "kstars", i18n("KStars"), versionString, i18n(description.toLatin1()), KAboutLicense::GPL,
108 i18n(" (c), The KStars Team\n\nThe Gaussian Process Guider Algorithm: (c) "
109 "2014-2017 Max Planck Society"),
110 i18nc("Build number followed by copyright notice", "Build: %1\n\n%2\n\n%3",
111 KSTARS_BUILD_TS,
112 KSTARS_BUILD_RELEASE == QLatin1String("Beta") ?
113 "Pre-release beta snapshot. Do not use in production." :
114 "Stable release.",
115 i18n(notice.toLatin1())),
116 "https://edu.kde.org/kstars");
117 aboutData.addAuthor(i18n("Jason Harris"), i18n("Original Author"),
118 "jharris@30doradus.org", "http://www.30doradus.org");
119 aboutData.addAuthor(i18n("Jasem Mutlaq"), i18n("Current Maintainer"),
120 "mutlaqja@ikarustech.com", "https://www.indilib.org");
121
122 // Active developers
123 aboutData.addAuthor(i18n("Akarsh Simha"), QString(), "akarsh@kde.org",
124 "http://www.ph.utexas.edu/~asimha");
125 aboutData.addAuthor(i18n("Robert Lancaster"),
126 i18n("FITSViewer & Ekos Improvements. KStars OSX Port"),
127 "rlancaste@gmail.com");
128 aboutData.addAuthor(i18n("Eric Dejouhanet"), QString(), "eric.dejouhanet@gmail.com",
129 i18n("Ekos Scheduler Improvements"));
130 aboutData.addAuthor(i18n("Wolfgang Reissenberger"), QString(),
131 "sterne-jaeger@t-online.de",
132 i18n("Ekos Scheduler & Observatory Improvements"));
133 aboutData.addAuthor(i18n("Hy Murveit"), QString(), "murveit@gmail.com",
134 i18n("FITS, Focus, Guide Improvements"));
135 aboutData.addAuthor(i18n("John Evans"), QString(), "john.e.evans.email@gmail.com",
136 i18n("Focus algorithms"));
137
138 // Inactive developers
139 aboutData.addAuthor(i18n("Csaba Kertesz"), QString(), "csaba.kertesz@gmail.com", "");
140 aboutData.addAuthor("Valentin Boettcher", QString(), "hiro@protagon.space",
141 i18n("Binary Asteroid List, DSO Database & Catalogs"));
142 aboutData.addAuthor(i18n("Artem Fedoskin"), i18n("KStars Lite"),
143 "afedoskin3@gmail.com");
144 aboutData.addAuthor(i18n("James Bowlin"), QString(), "bowlin@mindspring.com");
145 aboutData.addAuthor(i18n("Pablo de Vicente"), QString(), "pvicentea@wanadoo.es");
146 aboutData.addAuthor(i18n("Thomas Kabelmann"), QString(), "tk78@gmx.de");
147 aboutData.addAuthor(i18n("Heiko Evermann"), QString(), "heiko@evermann.de",
148 "https://www.evermann.de");
149 aboutData.addAuthor(i18n("Carsten Niehaus"), QString(), "cniehaus@gmx.de");
150 aboutData.addAuthor(i18n("Mark Hollomon"), QString(), "mhh@mindspring.com");
151 aboutData.addAuthor(i18n("Alexey Khudyakov"), QString(), "alexey.skladnoy@gmail.com");
152 aboutData.addAuthor(i18n("M&eacute;d&eacute;ric Boquien"), QString(),
153 "mboquien@free.fr");
154 aboutData.addAuthor(i18n("J&eacute;r&ocirc;me Sonrier"), QString(),
155 "jsid@emor3j.fr.eu.org");
156 aboutData.addAuthor(i18n("Prakash Mohan"), QString(), "prakash.mohan@kdemail.net");
157 aboutData.addAuthor(i18n("Victor Cărbune"), QString(), "victor.carbune@kdemail.net");
158 aboutData.addAuthor(i18n("Henry de Valence"), QString(), "hdevalence@gmail.com");
159 aboutData.addAuthor(i18n("Samikshan Bairagya"), QString(),
160 "samikshan.bairagya@kdemail.net");
161 aboutData.addAuthor(i18n("Rafał Kułaga"), QString(), "rl.kulaga@gmail.com");
162 aboutData.addAuthor(i18n("Rishab Arora"), QString(), "ra.rishab@gmail.com");
163
164 // Contributors
165 aboutData.addCredit(
166 i18n("Valery Kharitonov"),
167 i18n("Converted labels containing technical terms to links to documentation"));
168 aboutData.addCredit(i18n("Ana-Maria Constantin"),
169 i18n("Technical documentation on Astronomy and KStars"));
170 aboutData.addCredit(i18n("Andrew Stepanenko"),
171 i18n("Guiding code based on lin_guider"));
172 aboutData.addCredit(i18n("Nuno Pinheiro"), i18n("Artwork"));
173 aboutData.addCredit(
174 i18n("Utkarsh Simha"),
175 i18n("Improvements to observation plan execution, star hopper etc."));
176 aboutData.addCredit(i18n("Daniel Holler"),
177 i18n("Extensive testing and suggestions for Ekos/INDI."));
178 aboutData.addCredit(
179 i18n("Stephane Lucas"),
180 i18n("Extensive testing and suggestions for Ekos Scheduler. KStars OSX Port"));
181 aboutData.addCredit(i18n("Yuri Fabirovsky"),
182 i18n("Splash screen for both regular KStars and KStars Lite."));
183 aboutData.addCredit(i18n("Jamie Smith"), i18n("KStars OSX Port."));
184 aboutData.addCredit(i18n("Patrick Molenaar"), i18n("Bahtinov Focus Assistant."));
185 aboutData.addCredit(i18n("Philipp Auersperg-Castell"), i18n("Supernovae daily updates"));
186 aboutData.addCredit(i18n("Tony Schriber"), i18n("Rotator Dialog improvements"));
187 aboutData.addCredit(i18n("Joseph McGee"), i18n("Sub-exposure calculator based on Dr Robin Glover's work"));
188
190
191 QCommandLineParser parser;
192 aboutData.setupCommandLine(&parser);
193 parser.setApplicationDescription(aboutData.shortDescription());
194
195 //parser.addHelpOption(INSERT_DESCRIPTION_HERE);
196 parser.addOption(QCommandLineOption("dump", i18n("Dump sky image to file."), "file"));
197 parser.addOption(QCommandLineOption("script", i18n("Script to execute."), "file"));
198 parser.addOption(QCommandLineOption("width", i18n("Width of sky image."), "value"));
199 parser.addOption(QCommandLineOption("height", i18n("Height of sky image."), "value"));
200 parser.addOption(QCommandLineOption("date", i18n("Date and time."), "string"));
201 parser.addOption(QCommandLineOption("paused", i18n("Start with clock paused.")));
202
203 // urls to open
204 parser.addPositionalArgument(QStringLiteral("urls"), i18n("FITS file(s) to open."),
205 QStringLiteral("[urls...]"));
206
207 parser.process(app);
208 aboutData.processCommandLine(&parser);
209
210 if (parser.isSet("dump"))
211 {
212 qCDebug(KSTARS) << "Dumping sky image";
213
214 //parse filename and image format
215 const char *format = "PNG";
216 QString fname = parser.value("dump");
217 QString ext = fname.mid(fname.lastIndexOf(".") + 1);
218 if (ext.toLower() == "png")
219 {
220 format = "PNG";
221 }
222 else if (ext.toLower() == "jpg" || ext.toLower() == "jpeg")
223 {
224 format = "JPG";
225 }
226 else if (ext.toLower() == "gif")
227 {
228 format = "GIF";
229 }
230 else if (ext.toLower() == "pnm")
231 {
232 format = "PNM";
233 }
234 else if (ext.toLower() == "bmp")
235 {
236 format = "BMP";
237 }
238 else
239 {
240 qCWarning(KSTARS) << i18n("Could not parse image format of %1; assuming PNG.",
241 fname);
242 }
243
244 //parse width and height
245 bool ok(false);
246 int w(0), h(0);
247 w = parser.value("width").toInt(&ok);
248 if (ok)
249 h = parser.value("height").toInt(&ok);
250 if (!ok)
251 {
252 qCWarning(KSTARS) << "Unable to parse arguments Width: "
253 << parser.value("width")
254 << " Height: " << parser.value("height");
255 return 1;
256 }
257
258 KStarsData *dat = KStarsData::Create();
259 QObject::connect(dat, SIGNAL(progressText(QString)), dat,
260 SLOT(slotConsoleMessage(QString)));
261 dat->initialize();
262
263 //Set Geographic Location
265
266 //Set color scheme
267 dat->colorScheme()->loadFromConfig();
268
269 //set clock now that we have a location:
270 //Check to see if user provided a date/time string. If not, use current CPU time
271 QString datestring = parser.value("date");
272 KStarsDateTime kdt;
273 if (!datestring.isEmpty())
274 {
275 if (datestring.contains("-")) //assume ISODate format
276 {
277 if (datestring.contains(":")) //also includes time
278 {
279 //kdt = QDateTime::fromString( datestring, QDateTime::ISODate );
281 }
282 else //string probably contains date only
283 {
284 //kdt.setDate( QDate::fromString( datestring, Qt::ISODate ) );
285 kdt.setDate(QDate::fromString(datestring, Qt::ISODate));
286 kdt.setTime(QTime(0, 0, 0));
287 }
288 }
289 else //assume Text format for date string
290 {
291 kdt = dat->geo()->LTtoUT(
293 }
294
295 if (!kdt.isValid())
296 {
297 qCWarning(KSTARS) << i18n(
298 "Supplied date string is invalid: %1. Using CPU date/time instead.",
299 datestring);
300
302 }
303 }
304 else
305 {
307 }
308 dat->clock()->setUTC(kdt);
309
310 SkyMap *map = SkyMap::Create();
311 map->resize(w, h);
312 QPixmap sky(w, h);
313
314 dat->setFullTimeUpdate();
315 dat->updateTime(dat->geo(), map != nullptr);
316
317 SkyPoint dest(Options::focusRA(), Options::focusDec());
318 map->setDestination(dest);
319 map->destination()->EquatorialToHorizontal(dat->lst(), dat->geo()->lat());
320 map->setFocus(map->destination());
321 map->focus()->EquatorialToHorizontal(dat->lst(), dat->geo()->lat());
322
323 //Execute the specified script
324 QString scriptfile = parser.value("script");
325 if (!scriptfile.isEmpty())
326 {
327 if (dat->executeScript(scriptfile, map))
328 {
329 std::cout << i18n("Script executed.").toUtf8().data() << std::endl;
330 }
331 else
332 {
333 qCWarning(KSTARS) << i18n("Could not execute script.");
334 }
335 }
336
337 qApp->processEvents();
338 map->setupProjector();
339 map->exportSkyImage(&sky);
340 qApp->processEvents();
341
342 if (!sky.save(fname, format))
343 qCWarning(KSTARS) << "Unable to save image: " << fname;
344 else
345 qCDebug(KSTARS) << "Saved to file: %1" << fname;
346
347 delete map;
348 //delete dat;
349 return 0;
350 }
351
352 //Try to parse the given date string
353 QString datestring = parser.value("date");
354
355 if (!datestring.isEmpty() && !KStarsDateTime::fromString(datestring).isValid())
356 {
357 qWarning() << i18n("Using CPU date/time instead.");
358 datestring.clear();
359 }
360
361#endif
362
363 // Create writable data dir if it does not exist
364 QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).mkpath(".");
365 QDir(KSPaths::writableLocation(QStandardPaths::AppConfigLocation)).mkpath(".");
366 QDir(KSPaths::writableLocation(QStandardPaths::CacheLocation)).mkpath(".");
367 QDir(KSPaths::writableLocation(QStandardPaths::TempLocation)).mkpath(qAppName());
368
369#ifndef KSTARS_LITE
370 KStars::createInstance(true, !parser.isSet("paused"), datestring);
371
372 // no session.. just start up normally
373 const QStringList urls = parser.positionalArguments();
374
375 // take arguments
376 if (!urls.isEmpty())
377 {
378 foreach (const QString &url, urls)
379 {
381
383 }
384 }
385 QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
386
387 app.exec();
388#else
390
391 app.exec();
392#endif
393 return 0;
394}
void loadFromConfig()
Read color-scheme data from the Config object.
const CachingDms * lat() const
Definition geolocation.h:70
static void setApplicationData(const KAboutData &aboutData)
QString toString() const
static void addDomainLocaleDir(const QByteArray &domain, const QString &path)
static void setApplicationDomain(const QByteArray &domain)
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
CachingDms * lst()
Definition kstarsdata.h:226
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
void updateTime(GeoLocation *geo, const bool automaticDSTchange=true)
Update the Simulation Clock.
bool initialize()
Initialize KStarsData while running splash screen.
ColorScheme * colorScheme()
Definition kstarsdata.h:174
bool executeScript(const QString &name, SkyMap *map)
Execute a script.
Q_INVOKABLE SimClock * clock()
Definition kstarsdata.h:220
GeoLocation * geo()
Definition kstarsdata.h:232
void setLocationFromOptions()
Set the GeoLocation according to the values stored in the configuration file.
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static KStarsDateTime fromString(const QString &s)
void setDate(const QDate &d)
Assign the Date according to a QDate object.
static KStarsDateTime currentDateTimeUtc()
void setTime(const QTime &t)
Assign the Time according to a QTime object.
static KStarsLite * createInstance(bool doSplash, bool clockrunning=true, const QString &startDateString=QString())
Create an instance of this class.
static KStars * Instance()
Definition kstars.h:121
Q_SCRIPTABLE Q_NOREPLY void openFITS(const QUrl &imageUrl)
DBUS interface function.
static KStars * createInstance(bool doSplash, bool clockrunning=true, const QString &startDateString=QString())
Create an instance of this class.
Definition kstars.cpp:239
Q_SCRIPTABLE Q_NOREPLY void setUTC(const KStarsDateTime &newtime)
DBUS function to set the time of the SimClock.
Definition simclock.cpp:181
This is the canvas on which the sky is painted.
Definition skymap.h:54
The sky coordinates of a point in the sky.
Definition skypoint.h:45
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KCRASH_EXPORT void initialize()
const QList< QKeySequence > & quit()
const char * versionString()
char * data()
bool addOption(const QCommandLineOption &option)
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
bool isSet(const QCommandLineOption &option) const const
QStringList positionalArguments() const const
void process(const QCoreApplication &app)
void setApplicationDescription(const QString &description)
QString value(const QCommandLineOption &option) const const
void setAttribute(Qt::ApplicationAttribute attribute, bool on)
QDate currentDate()
QDate fromString(QStringView string, QStringView format, QCalendar cal)
int year() const const
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid() const const
QString currentPath()
bool mkdir(const QString &dirName) const const
bool mkpath(const QString &dirPath) const const
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString arg(Args &&... args) const const
void clear()
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
int toInt(bool *ok, int base) const const
QByteArray toLatin1() const const
QString toLower() const const
QByteArray toUtf8() const const
AA_EnableHighDpiScaling
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:41 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.