Kstars

kstars.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 "kstars.h"
8
9#include "config-kstars.h"
10#include "version.h"
11
12#include "fov.h"
13#include "kactionmenu.h"
14#include "kstarsadaptor.h"
15#include "kstarsdata.h"
16#include "kstarssplash.h"
17#include "observinglist.h"
18#include "Options.h"
19#include "skymap.h"
20#include "skyqpainter.h"
21#include "texturemanager.h"
22#include "dialogs/finddialog.h"
23#include "dialogs/exportimagedialog.h"
24#include "skycomponents/starblockfactory.h"
25#ifdef HAVE_INDI
26#include "ekos/manager.h"
27#include "indi/drivermanager.h"
28#include "indi/guimanager.h"
29#include "indi/indilistener.h"
30#endif
31
32#ifdef HAVE_CFITSIO
33#include "fitsviewer/fitsviewer.h"
34#endif
35
36#include <KActionCollection>
37#include <KToolBar>
38
39#ifdef Q_OS_WIN
40#include <QProcess>
41#endif
42#include <QStatusBar>
43#include <QMenu>
44
45#include <kstars_debug.h>
46
47KStars *KStars::pinstance = nullptr;
48bool KStars::Closing = false;
49
50KStars::KStars(bool doSplash, bool clockrun, const QString &startdate)
51 : KXmlGuiWindow(), StartClockRunning(clockrun), StartDateString(startdate)
52{
53 // FIXME Hack to set RTL direction for Arabic
54 // This is not a solution. It seems qtbase_ar.qm needs to take care of this?
55 // qttranslations5-l10n does not contain qtbase_ar.qm
56 // It seems qtbase_ar.ts does not exist for Qt 5.9 at all and needs to be translated.
57 // https://wiki.qt.io/Qt_Localization
58 if (i18n("Sky") == "السماء")
60
61 setWindowTitle(i18nc("@title:window", "KStars"));
62
63 // Set thread stack size to 32MB
65
66 // Initialize logging settings
67 if (Options::disableLogging())
69 else if (Options::logToFile())
71 else
73
75
76 qCInfo(KSTARS) << "Welcome to KStars" << KSTARS_VERSION << KSTARS_BUILD_RELEASE;
77 qCInfo(KSTARS) << "Build:" << KSTARS_BUILD_TS;
78 qCInfo(KSTARS) << "OS:" << QSysInfo::productType();
79 qCInfo(KSTARS) << "API:" << QSysInfo::buildAbi();
80 qCInfo(KSTARS) << "Arch:" << QSysInfo::currentCpuArchitecture();
81 qCInfo(KSTARS) << "Kernel Type:" << QSysInfo::kernelType();
82 qCInfo(KSTARS) << "Kernel Version:" << QSysInfo::kernelVersion();
83 qCInfo(KSTARS) << "Qt Version:" << QT_VERSION_STR;
84
85 new KstarsAdaptor(
86 this); // NOTE the weird case convention, which cannot be changed as the file is generated by the moc.
87
88#ifdef Q_OS_MACOS
89
90 QString vlcPlugins = QDir(QCoreApplication::applicationDirPath() + "/../PlugIns/vlc").absolutePath();
91 qputenv("VLC_PLUGIN_PATH", vlcPlugins.toLatin1());
92 QString phonon_backend_path = QDir(QCoreApplication::applicationDirPath() +
93 "/../PlugIns/phonon4qt5_backend/phonon_vlc.so").absolutePath();
94 qputenv("PHONON_BACKEND", phonon_backend_path.toLatin1());
95
97 QString path = env.value("PATH", "");
98 env.insert("PATH", "/usr/bin:/usr/local/bin:\"" + QCoreApplication::applicationDirPath() + "\":" + path);
99
100 qDebug("Trying to Setup DBus");
101
102 QProcess dbusCheck;
103 dbusCheck.setProcessEnvironment(env);
104
105 QString pluginsDir = QDir(QCoreApplication::applicationDirPath() + "/../PlugIns").absolutePath();
106 QString loadDBusPlist = pluginsDir + "/dbus/org.freedesktop.dbus-kstars.plist";
107 QString saveDBusPlist = QDir::homePath() + "/Library/LaunchAgents/org.freedesktop.dbus-kstars.plist";
108 QFile file(loadDBusPlist);
109 if (file.open(QIODevice::ReadOnly))
110 {
111 QTextStream in(&file);
112 QString pListText = in.readAll();
113 file.close();
114 int programArgsLeft = pListText.indexOf("<key>ProgramArguments</key>");
115 int programArgsRight = pListText.indexOf("</array>", programArgsLeft) + 8 - programArgsLeft;
116 QString currentProgramArgs = pListText.mid(programArgsLeft, programArgsRight);
117 QString newProgramArguments = ""
118 "<key>ProgramArguments</key>\n"
119 " <array>\n"
120 " <string>" +
122 "/dbus-daemon</string>\n"
123 " <string>--nofork</string>\n"
124 " <string>--config-file=" +
125 pluginsDir +
126 "/dbus/kstars.conf</string>\n"
127 " </array>";
128 pListText.replace(currentProgramArgs, newProgramArguments);
129 QFile file2(saveDBusPlist);
130 if (file2.open(QIODevice::WriteOnly))
131 {
132 QTextStream stream(&file2);
133 stream << pListText;
134 file2.close();
135
136 if(dbusCheck.execute("chmod", QStringList() << "775" << saveDBusPlist ) != 0)
137 {
138 qDebug() << "Attempted Command: chmod " << QStringList() << "775" << saveDBusPlist;
139 qDebug("Error Code: %d", dbusCheck.exitCode());
140 qDebug() << "Output: \n" << dbusCheck.readAllStandardOutput();
141 exit(1);
142 }
143
144 qDebug("DBus Setup Succeeded. Trying to Start DBus");
145
146 if(dbusCheck.execute("launchctl", QStringList() << "load" << "-w" << saveDBusPlist) != 0)
147 {
148 qDebug() << "Attempted Command: launchctl " << QStringList() << "load" << "-w" << saveDBusPlist;
149 qDebug("Error Code: %d", dbusCheck.exitCode());
150 qDebug() << "Output: \n" << dbusCheck.readAllStandardOutput();
151 exit(1);
152 }
153
154 qDebug("DBus Started");
155
156 }
157 else
158 {
159 qDebug("DBus File Write Error");
160 }
161 }
162 else
163 {
164 qDebug("DBus File Read Error");
165 }
166#endif
167
170
171#ifdef HAVE_CFITSIO
172 m_GenericFITSViewer.clear();
173#endif
174
175 // Set pinstance to yourself
176 pinstance = this;
177
178 connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit()));
179
180 //Initialize QActionGroups
181 projectionGroup = new QActionGroup(this);
182 cschemeGroup = new QActionGroup(this);
183 hipsGroup = new QActionGroup(this);
184 telescopeGroup = new QActionGroup(this);
185 telescopeGroup->setExclusive(false);
186 domeGroup = new QActionGroup(this);
187 domeGroup->setExclusive(false);
188 viewsGroup = new QActionGroup(this);
189 skymapOrientationGroup = new QActionGroup(this);
190 erectObserverCorrectionGroup = new QActionGroup(this);
191
192 m_KStarsData = KStarsData::Create();
193 Q_ASSERT(m_KStarsData);
194 //Set Geographic Location from Options
195 m_KStarsData->setLocationFromOptions();
196
197 //Initialize Time and Date
198 bool datetimeSet = false;
199 if (StartDateString.isEmpty() == false)
200 {
201 KStarsDateTime startDate = KStarsDateTime::fromString(StartDateString);
202 if (startDate.isValid())
203 data()->changeDateTime(data()->geo()->LTtoUT(startDate));
204 else
205 data()->changeDateTime(KStarsDateTime::currentDateTimeUtc());
206
207 datetimeSet = true;
208 }
209 // JM 2016-11-15: Not need to set it again as it was initialized in the ctor of SimClock
210 /*
211 else
212 data()->changeDateTime( KStarsDateTime::currentDateTimeUtc() );
213 */
214
215 // If we are starting paused (--paused is not in the command line) change datetime in data
216 if (StartClockRunning == false)
217 {
218 qCInfo(KSTARS) << "KStars is started in paused state.";
219 if (datetimeSet == false)
220 data()->changeDateTime(KStarsDateTime::currentDateTimeUtc());
221 }
222
223 // Setup splash screen
224 KStarsSplash *splash = nullptr;
225 if (doSplash)
226 {
227 splash = new KStarsSplash(nullptr);
228 connect(m_KStarsData, SIGNAL(progressText(QString)), splash, SLOT(setMessage(QString)));
229 splash->show();
230 }
231 else
232 {
233 connect(m_KStarsData, SIGNAL(progressText(QString)), m_KStarsData, SLOT(slotConsoleMessage(QString)));
234 }
235
236 /*
237 //set up Dark color scheme for application windows
238 DarkPalette = QPalette(QColor("black"), QColor("black"));
239 DarkPalette.setColor(QPalette::Inactive, QPalette::WindowText, QColor("red"));
240 DarkPalette.setColor(QPalette::Normal, QPalette::WindowText, QColor("red"));
241 DarkPalette.setColor(QPalette::Normal, QPalette::Base, QColor("black"));
242 DarkPalette.setColor(QPalette::Normal, QPalette::Text, QColor(238, 0, 0));
243 DarkPalette.setColor(QPalette::Normal, QPalette::Highlight, QColor(238, 0, 0));
244 DarkPalette.setColor(QPalette::Normal, QPalette::HighlightedText, QColor("black"));
245 DarkPalette.setColor(QPalette::Inactive, QPalette::Text, QColor(238, 0, 0));
246 DarkPalette.setColor(QPalette::Inactive, QPalette::Base, QColor(30, 10, 10));
247 //store original color scheme
248 OriginalPalette = QApplication::palette();
249 */
250
251 //Initialize data. When initialization is complete, it will run dataInitFinished()
252 if (!m_KStarsData->initialize())
253 return;
254 delete splash;
255 datainitFinished();
256}
257
258KStars *KStars::createInstance(bool doSplash, bool clockrun, const QString &startdate)
259{
260 delete pinstance;
261 // pinstance is set directly in constructor.
262 new KStars(doSplash, clockrun, startdate);
263 Q_ASSERT(pinstance && "pinstance must be non NULL");
264 return pinstance;
265}
266
268{
270 Q_ASSERT(pinstance);
271 pinstance = nullptr;
272#ifdef PROFILE_COORDINATE_CONVERSION
273 qDebug() << Q_FUNC_INFO << "Spent " << SkyPoint::cpuTime_EqToHz << " seconds in " << SkyPoint::eqToHzCalls
274 << " calls to SkyPoint::EquatorialToHorizontal, for an average of "
275 << 1000. * (SkyPoint::cpuTime_EqToHz / SkyPoint::eqToHzCalls) << " ms per call";
276#endif
277
278#ifdef COUNT_DMS_SINCOS_CALLS
279 qDebug() << Q_FUNC_INFO << "Constructed " << dms::dms_constructor_calls << " dms objects, of which " <<
280 dms::dms_with_sincos_called
281 << " had trigonometric functions called on them = "
282 << (float(dms::dms_with_sincos_called) / float(dms::dms_constructor_calls)) * 100. << "%";
283 qDebug() << Q_FUNC_INFO << "Of the " << dms::trig_function_calls << " calls to sin/cos/sincos on dms objects, "
284 << dms::redundant_trig_function_calls << " were redundant = "
285 << ((float(dms::redundant_trig_function_calls) / float(dms::trig_function_calls)) * 100.) << "%";
286 qDebug() << Q_FUNC_INFO << "We had " << CachingDms::cachingdms_bad_uses << " bad uses of CachingDms in all, compared to "
287 << CachingDms::cachingdms_constructor_calls << " constructed CachingDms objects = "
288 << (float(CachingDms::cachingdms_bad_uses) / float(CachingDms::cachingdms_constructor_calls)) * 100.
289 << "% bad uses";
290#endif
291}
292
294{
295 delete m_KStarsData;
296 m_KStarsData = nullptr;
297 delete StarBlockFactory::Instance();
301
302#ifdef HAVE_INDI
303 GUIManager::release();
304 Ekos::Manager::release();
305 DriverManager::release();
306#endif
307
310}
311
313{
314#if 0
315 if (m_FindDialog) // dialog is cached
316 {
317 /** Delete findDialog only if it is not opened */
318 if (m_FindDialog->isHidden())
319 {
320 delete m_FindDialog;
321 m_FindDialog = nullptr;
322 DialogIsObsolete = false;
323 }
324 else
325 DialogIsObsolete = true; // dialog was opened so it could not deleted
326 }
327#endif
328}
329
330void KStars::applyConfig(bool doApplyFocus)
331{
332 if (Options::isTracking())
333 {
334 actionCollection()->action("track_object")->setText(i18n("Stop &Tracking"));
336 ->action("track_object")
337 ->setIcon(QIcon::fromTheme("document-encrypt"));
338 }
339
341 ->action("coordsys")
342 ->setText(Options::useAltAz() ? i18n("Switch to Star Globe View (Equatorial &Coordinates)") :
343 i18n("Switch to Horizontal View (Horizontal &Coordinates)"));
344
345 actionCollection()->action("show_time_box")->setChecked(Options::showTimeBox());
346 actionCollection()->action("show_location_box")->setChecked(Options::showGeoBox());
347 actionCollection()->action("show_focus_box")->setChecked(Options::showFocusBox());
348 actionCollection()->action("show_statusBar")->setChecked(Options::showStatusBar());
349 actionCollection()->action("show_sbAzAlt")->setChecked(Options::showAltAzField());
350 actionCollection()->action("show_sbRADec")->setChecked(Options::showRADecField());
351 actionCollection()->action("show_sbJ2000RADec")->setChecked(Options::showJ2000RADecField());
352 actionCollection()->action("show_stars")->setChecked(Options::showStars());
353 actionCollection()->action("show_deepsky")->setChecked(Options::showDeepSky());
354 actionCollection()->action("show_planets")->setChecked(Options::showSolarSystem());
355 actionCollection()->action("show_clines")->setChecked(Options::showCLines());
356 actionCollection()->action("show_constellationart")->setChecked(Options::showConstellationArt());
357 actionCollection()->action("show_cnames")->setChecked(Options::showCNames());
358 actionCollection()->action("show_cbounds")->setChecked(Options::showCBounds());
359 actionCollection()->action("show_mw")->setChecked(Options::showMilkyWay());
360 actionCollection()->action("show_equatorial_grid")->setChecked(Options::showEquatorialGrid());
361 actionCollection()->action("show_horizontal_grid")->setChecked(Options::showHorizontalGrid());
362 actionCollection()->action("show_horizon")->setChecked(Options::showGround());
363 actionCollection()->action("simulate_daytime")->setChecked(Options::simulateDaytime());
364 actionCollection()->action("show_flags")->setChecked(Options::showFlags());
365 actionCollection()->action("show_supernovae")->setChecked(Options::showSupernovae());
366 actionCollection()->action("show_satellites")->setChecked(Options::showSatellites());
367 erectObserverCorrectionGroup->setEnabled(Options::useAltAz());
368 actionCollection()->action("erect_observer_correction_off")->setChecked(Options::erectObserverCorrection() == 0);
369 actionCollection()->action("erect_observer_correction_left")->setChecked(Options::erectObserverCorrection() == 1);
370 actionCollection()->action("erect_observer_correction_right")->setChecked(Options::erectObserverCorrection() == 2);
371 actionCollection()->action("mirror_skymap")->setChecked(Options::mirrorSkyMap());
372 statusBar()->setVisible(Options::showStatusBar());
373
374 //color scheme
375 m_KStarsData->colorScheme()->loadFromConfig();
376 //QApplication::setPalette(Options::darkAppColors() ? DarkPalette : OriginalPalette);
377 /**
378 //Note: This uses style sheets to set the dark colors, this should be cross platform. Palettes have a different behavior on OS X and Windows as opposed to Linux.
379 //It might be a good idea to use stylesheets in the future instead of palettes but this will work for now for OS X.
380 //This is also in KStarsDbus.cpp. If you change it, change it in BOTH places.
381 @code
382 #ifdef Q_OS_MACOS
383 if (Options::darkAppColors())
384 qApp->setStyleSheet(
385 "QWidget { background-color: black; color:red; "
386 "selection-background-color:rgb(30,30,30);selection-color:white}"
387 "QToolBar { border:none }"
388 "QTabBar::tab:selected { background-color:rgb(50,50,50) }"
389 "QTabBar::tab:!selected { background-color:rgb(30,30,30) }"
390 "QPushButton { background-color:rgb(50,50,50);border-width:1px; border-style:solid;border-color:black}"
391 "QPushButton::disabled { background-color:rgb(10,10,10);border-width:1px; "
392 "border-style:solid;border-color:black }"
393 "QToolButton:Checked { background-color:rgb(30,30,30); border:none }"
394 "QComboBox { background-color:rgb(30,30,30); }"
395 "QComboBox::disabled { background-color:rgb(10,10,10) }"
396 "QScrollBar::handle { background: rgb(30,30,30) }"
397 "QSpinBox { border-width: 1px; border-style:solid; border-color:rgb(30,30,30) }"
398 "QDoubleSpinBox { border-width:1px; border-style:solid; border-color:rgb(30,30,30) }"
399 "QLineEdit { border-width: 1px; border-style: solid; border-color:rgb(30,30,30) }"
400 "QCheckBox::indicator:unchecked { background-color:rgb(30,30,30);border-width:1px; "
401 "border-style:solid;border-color:black }"
402 "QCheckBox::indicator:checked { background-color:red;border-width:1px; "
403 "border-style:solid;border-color:black }"
404 "QRadioButton::indicator:unchecked { background-color:rgb(30,30,30) }"
405 "QRadioButton::indicator:checked { background-color:red }"
406 "QRoundProgressBar { alternate-background-color:black }"
407 "QDateTimeEdit {background-color:rgb(30,30,30); border-width: 1px; border-style:solid; "
408 "border-color:rgb(30,30,30) }"
409 "QHeaderView { color:red;background-color:black }"
410 "QHeaderView::Section { background-color:rgb(30,30,30) }"
411 "QTableCornerButton::section{ background-color:rgb(30,30,30) }"
412 "");
413 else
414 qApp->setStyleSheet("");
415 #endif
416 @endcode
417 **/
418
419 //Set toolbar options from config file
420 toolBar("kstarsToolBar")->applySettings(KSharedConfig::openConfig()->group("MainToolBar"));
421 toolBar("viewToolBar")->applySettings(KSharedConfig::openConfig()->group("ViewToolBar"));
422
423 //Geographic location
425
426 //Focus
427 if (doApplyFocus)
428 {
429 SkyObject *fo = data()->objectNamed(Options::focusObject());
430 if (fo && fo != map()->focusObject())
431 {
432 map()->setClickedObject(fo);
433 map()->setClickedPoint(fo);
434 map()->slotCenter();
435 }
436
437 if (!fo)
438 {
439 SkyPoint fp(Options::focusRA(), Options::focusDec());
440 if (fp.ra().Degrees() != map()->focus()->ra().Degrees() ||
441 fp.dec().Degrees() != map()->focus()->dec().Degrees())
442 {
443 map()->setClickedPoint(&fp);
444 map()->slotCenter();
445 }
446 }
447 }
448}
449
450void KStars::showImgExportDialog()
451{
452 if (m_ExportImageDialog)
453 m_ExportImageDialog->show();
454}
455
456void KStars::syncFOVActions()
457{
458 foreach (QAction *action, fovActionMenu->menu()->actions())
459 {
460 if (action->text().isEmpty())
461 {
462 continue;
463 }
464
465 if (Options::fOVNames().contains(action->text().remove(0, 1)))
466 {
467 action->setChecked(true);
468 }
469 else
470 {
471 action->setChecked(false);
472 }
473 }
474}
475
476void KStars::hideAllFovExceptFirst()
477{
478 // When there is only one visible FOV symbol, we don't need to do anything
479 // Also, don't do anything if there are no available FOV symbols.
480 if (data()->visibleFOVs.size() == 1 || data()->availFOVs.isEmpty())
481 {
482 return;
483 }
484 else
485 {
486 // If there are no visible FOVs, select first available
487 if (data()->visibleFOVs.isEmpty())
488 {
489 Q_ASSERT(!data()->availFOVs.isEmpty());
490 Options::setFOVNames(QStringList(data()->availFOVs.first()->name()));
491 }
492 else
493 {
494 Options::setFOVNames(QStringList(data()->visibleFOVs.first()->name()));
495 }
496
497 // Sync FOV and update skymap
498 data()->syncFOV();
499 syncFOVActions();
500 map()->update(); // SkyMap::forceUpdate() is not required, as FOVs are drawn as overlays
501 }
502}
503
504void KStars::selectNextFov()
505{
506 if (data()->getVisibleFOVs().isEmpty())
507 return;
508
509 Q_ASSERT(!data()
510 ->getAvailableFOVs()
511 .isEmpty()); // The available FOVs had better not be empty if the visible ones are not.
512
513 FOV *currentFov = data()->getVisibleFOVs().first();
514 int currentIdx = data()->availFOVs.indexOf(currentFov);
515
516 // If current FOV is not the available FOV list or there is only 1 FOV available, then return
517 if (currentIdx == -1 || data()->availFOVs.size() < 2)
518 {
519 return;
520 }
521
522 QStringList nextFovName;
523 if (currentIdx == data()->availFOVs.size() - 1)
524 {
525 nextFovName << data()->availFOVs.first()->name();
526 }
527 else
528 {
529 nextFovName << data()->availFOVs.at(currentIdx + 1)->name();
530 }
531
532 Options::setFOVNames(nextFovName);
533 data()->syncFOV();
534 syncFOVActions();
535 currentFov = data()->getVisibleFOVs().first();
536 zoom(map()->width() / (3 * std::max(currentFov->sizeX(), currentFov->sizeY()) * dms::DegToRad / 60.0));
537 map()->update();
538}
539
540void KStars::selectPreviousFov()
541{
542 if (data()->getVisibleFOVs().isEmpty())
543 return;
544
545 Q_ASSERT(!data()
546 ->getAvailableFOVs()
547 .isEmpty()); // The available FOVs had better not be empty if the visible ones are not.
548
549 FOV *currentFov = data()->getVisibleFOVs().first();
550 int currentIdx = data()->availFOVs.indexOf(currentFov);
551
552 // If current FOV is not the available FOV list or there is only 1 FOV available, then return
553 if (currentIdx == -1 || data()->availFOVs.size() < 2)
554 {
555 return;
556 }
557
558 QStringList prevFovName;
559 if (currentIdx == 0)
560 {
561 prevFovName << data()->availFOVs.last()->name();
562 }
563 else
564 {
565 prevFovName << data()->availFOVs.at(currentIdx - 1)->name();
566 }
567
568 Options::setFOVNames(prevFovName);
569 data()->syncFOV();
570 syncFOVActions();
571
572 currentFov = data()->getVisibleFOVs().first();
573 zoom(map()->width() / (3 * std::max(currentFov->sizeX(), currentFov->sizeY()) * dms::DegToRad / 60.0));
574 map()->update();
575}
576
577void KStars::selectNextView()
578{
579 QList<QAction*> actions = viewsGroup->actions();
580 int currentIndex = actions.indexOf(viewsGroup->checkedAction());
581 int newIndex = currentIndex + 1;
582 if (newIndex == actions.count() - 1)
583 {
584 newIndex++; // Skip "Arbitrary"
585 }
586 actions[newIndex % actions.count()]->activate(QAction::Trigger);
587 map()->slotDisplayFadingText(actions[newIndex % actions.count()]->data().toString());
588}
589
590void KStars::selectPreviousView()
591{
592 QList<QAction*> actions = viewsGroup->actions();
593 int currentIndex = actions.indexOf(viewsGroup->checkedAction());
594 int newIndex = currentIndex - 1;
595 if (currentIndex <= 0)
596 {
597 newIndex = actions.count() - 2; // Skip "Arbitrary"
598 }
599 actions[newIndex]->activate(QAction::Trigger);
600 map()->slotDisplayFadingText(actions[newIndex]->data().toString());
601}
602
603//FIXME Port to QML2
604//#if 0
605void KStars::showWISettingsUI()
606{
608}
609//#endif
610
611void KStars::updateTime(const bool automaticDSTchange)
612{
613 // Due to frequently use of this function save data and map pointers for speedup.
614 // Save options and geo() to a pointer would not speedup because most of time options
615 // and geo will accessed only one time.
616 KStarsData *Data = data();
617 // dms oldLST( Data->lst()->Degrees() );
618
619 Data->updateTime(Data->geo(), automaticDSTchange);
620
621 //We do this outside of kstarsdata just to get the coordinates
622 //displayed in the infobox to update every second.
623 // if ( !Options::isTracking() && LST()->Degrees() > oldLST.Degrees() ) {
624 // int nSec = int( 3600.*( LST()->Hours() - oldLST.Hours() ) );
625 // Map->focus()->setRA( Map->focus()->ra().Hours() + double( nSec )/3600. );
626 // if ( Options::useAltAz() ) Map->focus()->EquatorialToHorizontal( LST(), geo()->lat() );
627 // Map->showFocusCoords();
628 // }
629
630 //If time is accelerated beyond slewTimescale, then the clock's timer is stopped,
631 //so that it can be ticked manually after each update, in order to make each time
632 //step exactly equal to the timeScale setting.
633 //Wrap the call to manualTick() in a singleshot timer so that it doesn't get called until
634 //the skymap has been completely updated.
635 if (Data->clock()->isManualMode() && Data->clock()->isActive())
636 {
637 // Jasem 2017-11-13: Time for each update varies.
638 // Ideally we want to advance the simulation clock by
639 // the current clock scale (e.g. 1 hour) every 1 second
640 // of real time. However, the sky map update, depending on calculations and
641 // drawing of objects, takes variable time to complete.
642 //QTimer::singleShot(0, Data->clock(), SLOT(manualTick()));
643 QTimer::singleShot(1000, Data->clock(), SLOT(manualTick()));
644 }
645}
646
647#ifdef HAVE_CFITSIO
648const QSharedPointer<FITSViewer> &KStars::createFITSViewer()
649{
650 if (Options::singleWindowCapturedFITS())
651 return KStars::Instance()->genericFITSViewer();
652 else
653 {
654 QSharedPointer<FITSViewer> newFITSViewer(new FITSViewer(Options::independentWindowFITS() ? nullptr : KStars::Instance()),
656 m_FITSViewers.append(newFITSViewer);
657 connect(newFITSViewer.get(), &FITSViewer::terminated, this, [this]()
658 {
659 auto rawPointer = dynamic_cast<FITSViewer*>(sender());
660 m_FITSViewers.erase(std::remove_if(m_FITSViewers.begin(), m_FITSViewers.end(), [rawPointer](auto & viewer)
661 {
662 return viewer.get() == rawPointer;
663 }));
664 });
665 return m_FITSViewers.constLast();
666 }
667}
668
669const QSharedPointer<FITSViewer> &KStars::genericFITSViewer()
670{
671 if (m_GenericFITSViewer.isNull())
672 {
673 m_GenericFITSViewer.reset(new FITSViewer(Options::independentWindowFITS() ? nullptr : this), &QObject::deleteLater);
674 connect(m_GenericFITSViewer.get(), &FITSViewer::terminated, this, [this]()
675 {
676 m_FITSViewers.removeOne(m_GenericFITSViewer);
677 m_GenericFITSViewer.clear();
678 });
679 m_FITSViewers.append(m_GenericFITSViewer);
680 }
681
682 return m_GenericFITSViewer;
683}
684
685void KStars::clearAllViewers()
686{
687 for (auto &fv : m_FITSViewers)
688 fv->close();
689
690 m_FITSViewers.clear();
691}
692#endif
693
694void KStars::closeEvent(QCloseEvent *event)
695{
696 KStars::Closing = true;
698 slotAboutToQuit();
699}
Primary window to view monochrome and color FITS images.
Definition fitsviewer.h:54
static void releaseCache()
Release the FOV cache.
Definition fov.cpp:154
Q_INVOKABLE QAction * action(const QString &name) const
KToolBar * toolBar(const QString &name=QString())
bool event(QEvent *event) override
static void UseDefault()
Use the default logging mechanism.
Definition ksutils.cpp:1023
static void SyncFilterRules()
SyncFilterRules Sync QtLogging filter rules from Options.
Definition ksutils.cpp:1035
static void Disable()
Disable logging.
Definition ksutils.cpp:1028
static void UseFile()
Store all logs into the specified file.
Definition ksutils.cpp:926
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
void updateTime(GeoLocation *geo, const bool automaticDSTchange=true)
Update the Simulation Clock.
SkyObject * objectNamed(const QString &name)
Find object by name.
void syncFOV()
Synchronize list of visible FOVs and list of selected FOVs in Options.
Q_INVOKABLE SimClock * clock()
Definition kstarsdata.h:226
GeoLocation * geo()
Definition kstarsdata.h:238
void setLocationFromOptions()
Set the GeoLocation according to the values stored in the configuration file.
const QList< FOV * > getVisibleFOVs() const
Definition kstarsdata.h:314
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static KStarsDateTime fromString(const QString &s)
static KStarsDateTime currentDateTimeUtc()
The KStars Splash Screen.
This is the main window for KStars.
Definition kstars.h:90
SkyMap * map() const
Definition kstars.h:140
void applyConfig(bool doApplyFocus=true)
Apply config options throughout the program.
Definition kstars.cpp:330
static KStars * Instance()
Definition kstars.h:122
~KStars() override
Destructor.
Definition kstars.cpp:267
KStarsData * data() const
Definition kstars.h:134
static KStars * createInstance(bool doSplash, bool clockrunning=true, const QString &startDateString=QString())
Create an instance of this class.
Definition kstars.cpp:258
void clearCachedFindDialog()
Delete FindDialog because ObjNames list has changed in KStarsData due to reloading star data.
Definition kstars.cpp:312
void releaseResources()
Syncs config file.
Definition kstars.cpp:293
void slotWISettings()
action slot: open What's Interesting settings window
void updateTime(const bool automaticDSTchange=true)
Update time-dependent data and (possibly) repaint the sky map.
Definition kstars.cpp:611
static bool Closing
Set to true when the application is being closed.
Definition kstars.h:865
Q_SCRIPTABLE Q_NOREPLY void zoom(double z)
DBUS interface function.
void applySettings(const KConfigGroup &cg)
virtual KActionCollection * actionCollection() const
virtual QAction * action(const QDomElement &element) const
Q_INVOKABLE bool isActive()
Whether the clock is active or not is a bit complicated by the introduction of "manual mode".
Definition simclock.cpp:128
bool isManualMode() const
Manual Mode is a new (04/2002) addition to the SimClock.
Definition simclock.h:69
void setClickedPoint(const SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition skymap.cpp:1052
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition skymap.cpp:399
void slotDisplayFadingText(const QString &text)
Render a fading text label on the screen to flash information.
Definition skymap.cpp:1433
void slotCenter()
Center the display at the point ClickedPoint.
Definition skymap.cpp:413
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:50
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
const CachingDms & ra() const
Definition skypoint.h:263
static void releaseImageCache()
Release the image cache.
static void Release()
Release the instance of TextureManager.
const double & Degrees() const
Definition dms.h:141
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition dms.h:390
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
GeoCoordinates geo(const QVariant &location)
QString path(const QString &relativePath)
void setChecked(bool)
void setIcon(const QIcon &icon)
void setText(const QString &text)
QString applicationDirPath()
bool isValid() const const
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
bool registerService(const QString &serviceName)
QDBusConnection sessionBus()
QString absolutePath() const const
QString homePath()
QIcon fromTheme(const QString &name)
const_reference at(qsizetype i) const const
T & first()
qsizetype indexOf(const AT &value, qsizetype from) const const
T & last()
QStatusBar * statusBar() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
int execute(const QString &program, const QStringList &arguments)
int exitCode() const const
QByteArray readAllStandardOutput()
void setProcessEnvironment(const QProcessEnvironment &environment)
void insert(const QProcessEnvironment &e)
QProcessEnvironment systemEnvironment()
QString value(const QString &name, const QString &defaultValue) const const
void removeDatabase(const QString &connectionName)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
QString mid(qsizetype position, qsizetype n) const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QByteArray toLatin1() const const
QString buildAbi()
QString currentCpuArchitecture()
QString kernelType()
QString kernelVersion()
QString productType()
RightToLeft
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QThreadPool * globalInstance()
void setStackSize(uint stackSize)
QList< QAction * > actions() const const
virtual void closeEvent(QCloseEvent *event)
void setLayoutDirection(Qt::LayoutDirection direction)
void show()
void update()
virtual void setVisible(bool visible)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 11:58:37 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.