Kstars

main.cpp
1 /*
2  SPDX-FileCopyrightText: 2001 Jason Harris <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "ksnumbers.h"
8 #include "kspaths.h"
9 #include "kstars_debug.h"
10 #include "kstarsdata.h"
11 #include "ksnotification.h"
12 #include "kstarsdatetime.h"
13 #include "catalogsdb.h"
14 #if defined(KSTARS_LITE)
15 #include "kstarslite.h"
16 #endif
17 #include "ksutils.h"
18 #include "Options.h"
19 #include "simclock.h"
20 #include "version.h"
21 #if !defined(KSTARS_LITE)
22 #include "kstars.h"
23 #include "skymap.h"
24 #endif
25 
26 #if !defined(KSTARS_LITE)
27 #include <KAboutData>
28 #include <KCrash>
29 #endif
30 #include <KLocalizedString>
31 
32 #include <QApplication>
33 #if !defined(KSTARS_LITE)
34 #include <QCommandLineParser>
35 #include <QCommandLineOption>
36 #endif
37 #include <QDebug>
38 #include <QPixmap>
39 #include <QScreen>
40 #include <QtGlobal>
41 #include <QTranslator>
42 
43 #if defined(Q_OS_LINUX) || defined(Q_OS_OSX)
44 #include <signal.h>
45 #endif
46 
47 #ifndef KSTARS_LITE
48 static const char description[] = I18N_NOOP("Desktop Planetarium");
49 static const char notice[] = I18N_NOOP(
50  "Some images in KStars are for non-commercial use only. See README.images.");
51 #endif
52 
53 #if defined(Q_OS_ANDROID)
54 // __attribute__ is needed because clang-based linking removes the main() symbol from the shared library on Android
55 Q_DECL_EXPORT
56 #endif
57 int main(int argc, char *argv[])
58 {
59 #if defined(Q_OS_LINUX) || defined(Q_OS_OSX)
60  // Ignore SIGPIPE
61  signal(SIGPIPE, SIG_IGN);
62 #endif
63 
64 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
66 #endif
67  QApplication app(argc, argv);
68 
69 #ifdef Q_OS_OSX
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), KAboutLicense::GPL,
107  "2001-" + QString::number(QDate::currentDate().year()) +
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)),
116  "https://edu.kde.org/kstars");
117  aboutData.addAuthor(i18n("Jason Harris"), i18n("Original Author"),
118  "[email protected]", "http://www.30doradus.org");
119  aboutData.addAuthor(i18n("Jasem Mutlaq"), i18n("Current Maintainer"),
120  "[email protected]", "https://www.indilib.org");
121 
122  // Active developers
123  aboutData.addAuthor(i18n("Akarsh Simha"), QString(), "[email protected]",
124  "http://www.ph.utexas.edu/~asimha");
125  aboutData.addAuthor(i18n("Robert Lancaster"),
126  i18n("FITSViewer & Ekos Improvements. KStars OSX Port"),
128  aboutData.addAuthor(i18n("Csaba Kertesz"), QString(), "[email protected]", "");
129  aboutData.addAuthor(i18n("Eric Dejouhanet"), QString(), "[email protected]",
130  i18n("Ekos Scheduler Improvements"));
131  aboutData.addAuthor(i18n("Wolfgang Reissenberger"), QString(),
133  i18n("Ekos Scheduler & Observatory Improvements"));
134  aboutData.addAuthor(i18n("Hy Murveit"), QString(), "[email protected]",
135  i18n("FITS, Focus, Guide Improvements"));
136  aboutData.addAuthor("Valentin Boettcher", QString(), "[email protected]",
137  i18n("Binary Asteroid List, DSO Database & Catalogs"));
138 
139  // Inactive developers
140  aboutData.addAuthor(i18n("Artem Fedoskin"), i18n("KStars Lite"),
142  aboutData.addAuthor(i18n("James Bowlin"), QString(), "[email protected]");
143  aboutData.addAuthor(i18n("Pablo de Vicente"), QString(), "[email protected]");
144  aboutData.addAuthor(i18n("Thomas Kabelmann"), QString(), "[email protected]");
145  aboutData.addAuthor(i18n("Heiko Evermann"), QString(), "[email protected]",
146  "https://www.evermann.de");
147  aboutData.addAuthor(i18n("Carsten Niehaus"), QString(), "[email protected]");
148  aboutData.addAuthor(i18n("Mark Hollomon"), QString(), "[email protected]");
149  aboutData.addAuthor(i18n("Alexey Khudyakov"), QString(), "[email protected]");
150  aboutData.addAuthor(i18n("M&eacute;d&eacute;ric Boquien"), QString(),
152  aboutData.addAuthor(i18n("J&eacute;r&ocirc;me Sonrier"), QString(),
154  aboutData.addAuthor(i18n("Prakash Mohan"), QString(), "[email protected]");
155  aboutData.addAuthor(i18n("Victor Cărbune"), QString(), "[email protected]");
156  aboutData.addAuthor(i18n("Henry de Valence"), QString(), "[email protected]");
157  aboutData.addAuthor(i18n("Samikshan Bairagya"), QString(),
159  aboutData.addAuthor(i18n("Rafał Kułaga"), QString(), "[email protected]");
160  aboutData.addAuthor(i18n("Rishab Arora"), QString(), "[email protected]");
161 
162  // Contributors
163  aboutData.addCredit(
164  i18n("Valery Kharitonov"),
165  i18n("Converted labels containing technical terms to links to documentation"));
166  aboutData.addCredit(i18n("Ana-Maria Constantin"),
167  i18n("Technical documentation on Astronomy and KStars"));
168  aboutData.addCredit(i18n("Andrew Stepanenko"),
169  i18n("Guiding code based on lin_guider"));
170  aboutData.addCredit(i18n("Nuno Pinheiro"), i18n("Artwork"));
171  aboutData.addCredit(
172  i18n("Utkarsh Simha"),
173  i18n("Improvements to observation plan execution, star hopper etc."));
174  aboutData.addCredit(i18n("Daniel Holler"),
175  i18n("Extensive testing and suggestions for Ekos/INDI."));
176  aboutData.addCredit(
177  i18n("Stephane Lucas"),
178  i18n("Extensive testing and suggestions for Ekos Scheduler. KStars OSX Port"));
179  aboutData.addCredit(i18n("Yuri Fabirovsky"),
180  i18n("Splash screen for both regular KStars and KStars Lite."));
181  aboutData.addCredit(i18n("Jamie Smith"), i18n("KStars OSX Port."));
182  aboutData.addCredit(i18n("Patrick Molenaar"), i18n("Bahtinov Focus Assistant."));
183 
185 
186  QCommandLineParser parser;
187  aboutData.setupCommandLine(&parser);
188  parser.setApplicationDescription(aboutData.shortDescription());
189 
190  //parser.addHelpOption(INSERT_DESCRIPTION_HERE);
191  parser.addOption(QCommandLineOption("dump", i18n("Dump sky image to file."), "file"));
192  parser.addOption(QCommandLineOption("script", i18n("Script to execute."), "file"));
193  parser.addOption(QCommandLineOption("width", i18n("Width of sky image."), "value"));
194  parser.addOption(QCommandLineOption("height", i18n("Height of sky image."), "value"));
195  parser.addOption(QCommandLineOption("date", i18n("Date and time."), "string"));
196  parser.addOption(QCommandLineOption("paused", i18n("Start with clock paused.")));
197 
198  // urls to open
199  parser.addPositionalArgument(QStringLiteral("urls"), i18n("FITS file(s) to open."),
200  QStringLiteral("[urls...]"));
201 
202  parser.process(app);
203  aboutData.processCommandLine(&parser);
204 
205  if (parser.isSet("dump"))
206  {
207  qCDebug(KSTARS) << "Dumping sky image";
208 
209  //parse filename and image format
210  const char *format = "PNG";
211  QString fname = parser.value("dump");
212  QString ext = fname.mid(fname.lastIndexOf(".") + 1);
213  if (ext.toLower() == "png")
214  {
215  format = "PNG";
216  }
217  else if (ext.toLower() == "jpg" || ext.toLower() == "jpeg")
218  {
219  format = "JPG";
220  }
221  else if (ext.toLower() == "gif")
222  {
223  format = "GIF";
224  }
225  else if (ext.toLower() == "pnm")
226  {
227  format = "PNM";
228  }
229  else if (ext.toLower() == "bmp")
230  {
231  format = "BMP";
232  }
233  else
234  {
235  qCWarning(KSTARS) << i18n("Could not parse image format of %1; assuming PNG.",
236  fname);
237  }
238 
239  //parse width and height
240  bool ok(false);
241  int w(0), h(0);
242  w = parser.value("width").toInt(&ok);
243  if (ok)
244  h = parser.value("height").toInt(&ok);
245  if (!ok)
246  {
247  qCWarning(KSTARS) << "Unable to parse arguments Width: "
248  << parser.value("width")
249  << " Height: " << parser.value("height");
250  return 1;
251  }
252 
253  KStarsData *dat = KStarsData::Create();
254  QObject::connect(dat, SIGNAL(progressText(QString)), dat,
255  SLOT(slotConsoleMessage(QString)));
256  dat->initialize();
257 
258  //Set Geographic Location
259  dat->setLocationFromOptions();
260 
261  //Set color scheme
262  dat->colorScheme()->loadFromConfig();
263 
264  //set clock now that we have a location:
265  //Check to see if user provided a date/time string. If not, use current CPU time
266  QString datestring = parser.value("date");
267  KStarsDateTime kdt;
268  if (!datestring.isEmpty())
269  {
270  if (datestring.contains("-")) //assume ISODate format
271  {
272  if (datestring.contains(":")) //also includes time
273  {
274  //kdt = QDateTime::fromString( datestring, QDateTime::ISODate );
276  }
277  else //string probably contains date only
278  {
279  //kdt.setDate( QDate::fromString( datestring, Qt::ISODate ) );
280  kdt.setDate(QDate::fromString(datestring, Qt::ISODate));
281  kdt.setTime(QTime(0, 0, 0));
282  }
283  }
284  else //assume Text format for date string
285  {
286  kdt = dat->geo()->LTtoUT(
288  }
289 
290  if (!kdt.isValid())
291  {
292  qCWarning(KSTARS) << i18n(
293  "Supplied date string is invalid: %1. Using CPU date/time instead.",
294  datestring);
295 
297  }
298  }
299  else
300  {
302  }
303  dat->clock()->setUTC(kdt);
304 
305  SkyMap *map = SkyMap::Create();
306  map->resize(w, h);
307  QPixmap sky(w, h);
308 
309  dat->setFullTimeUpdate();
310  dat->updateTime(dat->geo(), map != nullptr);
311 
312  SkyPoint dest(Options::focusRA(), Options::focusDec());
313  map->setDestination(dest);
314  map->destination()->EquatorialToHorizontal(dat->lst(), dat->geo()->lat());
315  map->setFocus(map->destination());
316  map->focus()->EquatorialToHorizontal(dat->lst(), dat->geo()->lat());
317 
318  //Execute the specified script
319  QString scriptfile = parser.value("script");
320  if (!scriptfile.isEmpty())
321  {
322  if (dat->executeScript(scriptfile, map))
323  {
324  std::cout << i18n("Script executed.").toUtf8().data() << std::endl;
325  }
326  else
327  {
328  qCWarning(KSTARS) << i18n("Could not execute script.");
329  }
330  }
331 
332  qApp->processEvents();
333  map->setupProjector();
334  map->exportSkyImage(&sky);
335  qApp->processEvents();
336 
337  if (!sky.save(fname, format))
338  qCWarning(KSTARS) << "Unable to save image: " << fname;
339  else
340  qCDebug(KSTARS) << "Saved to file: %1" << fname;
341 
342  delete map;
343  //delete dat;
344  return 0;
345  }
346 
347  //Try to parse the given date string
348  QString datestring = parser.value("date");
349 
350  if (!datestring.isEmpty() && !KStarsDateTime::fromString(datestring).isValid())
351  {
352  qWarning() << i18n("Using CPU date/time instead.");
353  datestring.clear();
354  }
355 
356 #endif
357 
358  // Create writable data dir if it does not exist
359  QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).mkpath(".");
360  QDir(KSPaths::writableLocation(QStandardPaths::AppConfigLocation)).mkpath(".");
361  QDir(KSPaths::writableLocation(QStandardPaths::CacheLocation)).mkpath(".");
362  QDir(KSPaths::writableLocation(QStandardPaths::TempLocation)).mkpath(qAppName());
363 
364 #ifndef KSTARS_LITE
365  KStars::createInstance(true, !parser.isSet("paused"), datestring);
366 
367  // no session.. just start up normally
368  const QStringList urls = parser.positionalArguments();
369 
370  // take arguments
371  if (!urls.isEmpty())
372  {
373  foreach (const QString &url, urls)
374  {
375  const QUrl u = QUrl::fromUserInput(url, QDir::currentPath());
376 
378  }
379  }
380  QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
381 
382  app.exec();
383 #else
385 
386  app.exec();
387 #endif
388  return 0;
389 }
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
const char * versionString()
QString number(int n, int base)
void updateTime(GeoLocation *geo, const bool automaticDSTchange=true)
Update the Simulation Clock.
Definition: kstarsdata.cpp:234
void setLocationFromOptions()
Set the GeoLocation according to the values stored in the configuration file.
Definition: kstarsdata.cpp:396
void setApplicationDescription(const QString &description)
KCRASH_EXPORT void initialize()
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
static void setApplicationData(const KAboutData &aboutData)
void clear()
AA_EnableHighDpiScaling
CachingDms * lst()
Definition: kstarsdata.h:223
void loadFromConfig()
Read color-scheme data from the Config object.
bool mkdir(const QString &dirName) const const
static KStarsDateTime fromString(const QString &s)
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
static KStarsDateTime currentDateTimeUtc()
QStringList positionalArguments() const const
static void addDomainLocaleDir(const QByteArray &domain, const QString &path)
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
Definition: kstarsdata.cpp:313
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static KStars * Instance()
Definition: kstars.h:125
void setTime(const QTime &t)
Assign the Time according to a QTime object.
bool initialize()
Initialize KStarsData while running splash screen.
Definition: kstarsdata.cpp:131
QString i18n(const char *text, const TYPE &arg...)
const CachingDms * lat() const
Definition: geolocation.h:70
void process(const QStringList &arguments)
QString currentPath()
ColorScheme * colorScheme()
Definition: kstarsdata.h:171
bool isEmpty() const const
GeoLocation * geo()
Definition: kstarsdata.h:229
QByteArray toUtf8() const const
bool mkpath(const QString &dirPath) const const
Q_INVOKABLE SimClock * clock()
Definition: kstarsdata.h:217
QString value(const QString &optionName) const const
int toInt(bool *ok, int base) const const
bool isEmpty() const const
QDate currentDate()
bool executeScript(const QString &name, SkyMap *map)
Execute a script.
Definition: kstarsdata.cpp:912
QDateTime fromString(const QString &string, Qt::DateFormat format)
bool isSet(const QString &name) const const
void setDate(const QDate &d)
Assign the Date according to a QDate object.
QString toLower() const const
Q_SCRIPTABLE Q_NOREPLY void openFITS(const QUrl &imageUrl)
DBUS interface function.
QDate fromString(const QString &string, Qt::DateFormat format)
const QList< QKeySequence > & quit()
void setAttribute(Qt::ApplicationAttribute attribute, bool on)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
Q_SCRIPTABLE Q_NOREPLY void setUTC(const KStarsDateTime &newtime)
DBUS function to set the time of the SimClock.
Definition: simclock.cpp:143
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:52
bool isValid() const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
#define I18N_NOOP(text)
bool addOption(const QCommandLineOption &option)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
static void setApplicationDomain(const char *domain)
QFuture< void > map(Sequence &sequence, MapFunctor function)
QString mid(int position, int n) const const
static KStarsLite * createInstance(bool doSplash, bool clockrunning=true, const QString &startDateString=QString())
Create an instance of this class.
Definition: kstarslite.cpp:217
static KStars * createInstance(bool doSplash, bool clockrunning=true, const QString &startDateString=QString())
Create an instance of this class.
Definition: kstars.cpp:239
QUrl fromUserInput(const QString &userInput)
char * data()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Aug 13 2022 04:01:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.