Kstars

kstarsactions.cpp
1/*
2 SPDX-FileCopyrightText: 2002 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7// This file contains function definitions for Actions declared in kstars.h
8
9#include "kstars.h"
10
11#include "imageexporter.h"
12#include "kstarsdata.h"
13#include "kstars_debug.h"
14#include "ksnotification.h"
15#include "kswizard.h"
16#include "Options.h"
17#include "skymap.h"
18#include "texturemanager.h"
19#include "dialogs/exportimagedialog.h"
20#include "dialogs/finddialog.h"
21#include "dialogs/focusdialog.h"
22#include "dialogs/fovdialog.h"
23#include "dialogs/viewsdialog.h"
24#include "dialogs/locationdialog.h"
25#include "dialogs/timedialog.h"
26#include "dialogs/catalogsdbui.h"
27#include "oal/execute.h"
28#include "oal/equipmentwriter.h"
29#include "oal/observeradd.h"
30#include "options/opsadvanced.h"
31#include "options/opscatalog.h"
32#include "options/opscolors.h"
33#include "options/opsguides.h"
34#include "options/opsterrain.h"
35#include "options/opsimageoverlay.h"
36#include "options/opsdeveloper.h"
37#include "options/opssatellites.h"
38#include "options/opssolarsystem.h"
39#include "options/opssupernovae.h"
40#include "printing/printingwizard.h"
41#include "projections/projector.h"
42#include "skycomponents/asteroidscomponent.h"
43#include "skycomponents/cometscomponent.h"
44#include "skycomponents/satellitescomponent.h"
45#include "skycomponents/skymapcomposite.h"
46#include "skycomponents/solarsystemcomposite.h"
47#include "skycomponents/supernovaecomponent.h"
48#include "skycomponents/catalogscomponent.h"
49#include "skycomponents/mosaiccomponent.h"
50#include "skycomponents/imageoverlaycomponent.h"
51#ifdef HAVE_INDI
52#include "skyobjects/mosaictiles.h"
53#include "indi/indidome.h"
54#endif
55#include "tools/altvstime.h"
56#include "tools/astrocalc.h"
57#include "tools/eyepiecefield.h"
58#include "tools/flagmanager.h"
59#include "tools/horizonmanager.h"
60#include "tools/observinglist.h"
61#include "tools/planetviewer.h"
62#include "tools/jmoontool.h"
63#include "tools/scriptbuilder.h"
64#include "tools/skycalendar.h"
65#include "tools/wutdialog.h"
66#include "tools/polarishourangle.h"
67#include "tools/whatsinteresting/wiequipsettings.h"
68#include "tools/whatsinteresting/wilpsettings.h"
69#include "tools/whatsinteresting/wiview.h"
70#include "hips/hipsmanager.h"
71#include "catalogsdb.h"
72#ifdef HAVE_INDI
73#include <basedevice.h>
74//#include "indi/telescopewizardprocess.h"
75#include "indi/opsindi.h"
76#include "indi/drivermanager.h"
77#include "indi/guimanager.h"
78#include "indi/indilistener.h"
79#endif
80
81#ifdef HAVE_CFITSIO
82#include "fitsviewer/fitsviewer.h"
83#include "fitsviewer/opsfits.h"
84#ifdef HAVE_INDI
85#include "ekos/manager.h"
86#include "ekos/scheduler/framingassistantui.h"
87#include "ekos/scheduler/scheduler.h"
88#include "ekos/scheduler/schedulermodulestate.h"
89#include "ekos/opsekos.h"
90#include "ekos/mount/mount.h"
91#endif
92#endif
93
94#include "xplanet/opsxplanet.h"
95
96#ifdef HAVE_NOTIFYCONFIG
97#include <KNotifyConfigWidget>
98#endif
99#include <KActionCollection>
100#include <KActionMenu>
101
102#include <KToggleAction>
103
104#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
105#include <KNSWidgets/dialog.h>
106#else
107#include <kns3/downloaddialog.h>
108#endif
109
110#include <QQuickWindow>
111#include <QQuickView>
112
113#ifdef _WIN32
114#include <windows.h>
115#undef interface
116#endif
117#include <sys/stat.h>
118
119/** ViewToolBar Action. All of the viewToolBar buttons are connected to this slot. **/
120
121void KStars::slotViewToolBar()
122{
124 KConfigDialog *kcd = KConfigDialog::exists("settings");
125
126 if (a == actionCollection()->action("show_stars"))
127 {
128 Options::setShowStars(a->isChecked());
129 if (kcd)
130 {
131 opcatalog->kcfg_ShowStars->setChecked(a->isChecked());
132 }
133 }
134 else if (a == actionCollection()->action("show_deepsky"))
135 {
136 Options::setShowDeepSky(a->isChecked());
137 if (kcd)
138 {
139 opcatalog->kcfg_ShowDeepSky->setChecked(a->isChecked());
140 }
141 }
142 else if (a == actionCollection()->action("show_planets"))
143 {
144 Options::setShowSolarSystem(a->isChecked());
145 if (kcd)
146 {
147 opsolsys->kcfg_ShowSolarSystem->setChecked(a->isChecked());
148 }
149 }
150 else if (a == actionCollection()->action("show_clines"))
151 {
152 Options::setShowCLines(a->isChecked());
153 if (kcd)
154 {
155 opguides->kcfg_ShowCLines->setChecked(a->isChecked());
156 }
157 }
158 else if (a == actionCollection()->action("show_cnames"))
159 {
160 Options::setShowCNames(a->isChecked());
161 if (kcd)
162 {
163 opguides->kcfg_ShowCNames->setChecked(a->isChecked());
164 }
165 }
166 else if (a == actionCollection()->action("show_cbounds"))
167 {
168 Options::setShowCBounds(a->isChecked());
169 if (kcd)
170 {
171 opguides->kcfg_ShowCBounds->setChecked(a->isChecked());
172 }
173 }
174 else if (a == actionCollection()->action("show_constellationart"))
175 {
176 Options::setShowConstellationArt(a->isChecked());
177 if (kcd)
178 {
179 opguides->kcfg_ShowConstellationArt->setChecked(a->isChecked());
180 }
181 }
182 else if (a == actionCollection()->action("show_mw"))
183 {
184 Options::setShowMilkyWay(a->isChecked());
185 if (kcd)
186 {
187 opguides->kcfg_ShowMilkyWay->setChecked(a->isChecked());
188 }
189 }
190 else if (a == actionCollection()->action("show_equatorial_grid"))
191 {
192 // if autoSelectGrid is selected and the user clicked the
193 // show_equatorial_grid button, he probably wants us to disable
194 // the autoSelectGrid and display the equatorial grid.
195 Options::setAutoSelectGrid(false);
196 Options::setShowEquatorialGrid(a->isChecked());
197 if (kcd)
198 {
199 opguides->kcfg_ShowEquatorialGrid->setChecked(a->isChecked());
200 opguides->kcfg_AutoSelectGrid->setChecked(false);
201 }
202 }
203 else if (a == actionCollection()->action("show_horizontal_grid"))
204 {
205 Options::setAutoSelectGrid(false);
206 Options::setShowHorizontalGrid(a->isChecked());
207 if (kcd)
208 {
209 opguides->kcfg_ShowHorizontalGrid->setChecked(a->isChecked());
210 opguides->kcfg_AutoSelectGrid->setChecked(false);
211 }
212 }
213 else if (a == actionCollection()->action("show_horizon"))
214 {
215 Options::setShowGround(a->isChecked());
216 if (!a->isChecked() && Options::useRefraction())
217 {
218 QString caption = i18n("Refraction effects disabled");
219 QString message = i18n("When the horizon is switched off, refraction effects "
220 "are temporarily disabled.");
221
222 KMessageBox::information(this, message, caption, "dag_refract_hide_ground");
223 }
224 if (kcd)
225 {
226 opguides->kcfg_ShowGround->setChecked(a->isChecked());
227 }
228 }
229 else if (a == actionCollection()->action("simulate_daytime"))
230 {
231 Options::setSimulateDaytime(a->isChecked());
232 if (kcd)
233 {
234 opguides->kcfg_SimulateDaytime->setChecked(a->isChecked());
235 }
236 }
237 else if (a == actionCollection()->action("show_flags"))
238 {
239 Options::setShowFlags(a->isChecked());
240 if (kcd)
241 {
242 opguides->kcfg_ShowFlags->setChecked(a->isChecked());
243 }
244 }
245 else if (a == actionCollection()->action("show_satellites"))
246 {
247 Options::setShowSatellites(a->isChecked());
248 if (kcd)
249 {
250 opssatellites->kcfg_ShowSatellites->setChecked(a->isChecked());
251 }
252 }
253 else if (a == actionCollection()->action("show_supernovae"))
254 {
255 Options::setShowSupernovae(a->isChecked());
256 if (kcd)
257 {
258 opssupernovae->kcfg_ShowSupernovae->setChecked(a->isChecked());
259 }
260 }
261
262 // update time for all objects because they might be not initialized
263 // it's needed when using horizontal coordinates
265 updateTime();
266
267 map()->forceUpdate();
268}
269
270void KStars::slotINDIToolBar()
271{
272#ifdef HAVE_INDI
274
275 if (a == actionCollection()->action("show_control_panel"))
276 {
277 if (a->isChecked())
278 {
279 GUIManager::Instance()->raise();
280 GUIManager::Instance()->activateWindow();
281 GUIManager::Instance()->showNormal();
282 }
283 else
284 GUIManager::Instance()->hide();
285 }
286 else if (a == actionCollection()->action("show_ekos"))
287 {
288 if (a->isChecked())
289 {
290 Ekos::Manager::Instance()->raise();
291 Ekos::Manager::Instance()->activateWindow();
292 Ekos::Manager::Instance()->showNormal();
293 }
294 else
295 Ekos::Manager::Instance()->hide();
296 }
297 else if (a == actionCollection()->action("lock_telescope"))
298 {
299 for (auto &oneDevice : INDIListener::devices())
300 {
301 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
302 continue;
303
304 if (oneDevice->isConnected() == false)
305 {
306 KSNotification::error(i18n("Mount %1 is offline. Please connect and retry again.", oneDevice->getDeviceName()));
307 return;
308 }
309
310 auto mount = oneDevice->getMount();
311 if (!mount)
312 continue;
313
314 if (a->isChecked())
315 mount->centerLock();
316 else
317 mount->centerUnlock();
318 return;
319 }
320
321 KSNotification::sorry(i18n("No connected mounts found."));
322 return;
323 }
324 else if (a == actionCollection()->action("show_fits_viewer"))
325 {
326 if (m_FITSViewers.isEmpty())
327 {
328 a->setEnabled(false);
329 return;
330 }
331
332 if (a->isChecked())
333 {
334 for (auto &view : m_FITSViewers)
335 {
336 if (view->tabs().empty() == false)
337 {
338 view->raise();
339 view->activateWindow();
340 view->showNormal();
341 }
342 }
343 }
344 else
345 {
346 for (auto &view : m_FITSViewers)
347 {
348 view->hide();
349 }
350 }
351 }
352 else if (a == actionCollection()->action("show_mount_box"))
353 {
354#ifdef HAVE_CFITSIO
355#ifdef HAVE_INDI
356 Ekos::Manager::Instance()->mountModule()->toggleMountToolBox();
357#endif
358#endif
359 }
360 else if (a == actionCollection()->action("show_sensor_fov"))
361 {
362 Options::setShowSensorFOV(a->isChecked());
363 for (auto &oneFOV : data()->getTransientFOVs())
364 {
365 if (oneFOV->objectName() == "sensor_fov")
366 oneFOV->setProperty("visible", a->isChecked());
367 }
368 }
369 else if (a == actionCollection()->action("show_mosaic_panel"))
370 {
371#ifdef HAVE_INDI
372 Options::setShowMosaicPanel(a->isChecked());
373 // TODO
374 // If scheduler is not running, then we should also show the Mosaic Planner dialog.
375 auto scheduler = Ekos::Manager::Instance()->schedulerModule();
376 if (a->isChecked() && scheduler && scheduler->moduleState()->schedulerState() != Ekos::SCHEDULER_RUNNING)
377 {
378 // Only create if we don't have an instance already
379 if (findChild<Ekos::FramingAssistantUI *>("FramingAssistant") == nullptr)
380 {
381 Ekos::FramingAssistantUI *assistant = new Ekos::FramingAssistantUI();
382 assistant->setAttribute(Qt::WA_DeleteOnClose, true);
383 assistant->show();
384 }
385 }
386#endif
387 }
388
389#endif
390}
391
393{
394 telescopeGroup->setEnabled(enable);
395 if (enable == false)
396 {
397 for (auto &a : telescopeGroup->actions())
398 {
399 a->setChecked(false);
400 }
401 }
402}
403
405{
406 domeGroup->setEnabled(enable);
407 if (enable == false)
408 {
409 for (auto &a : domeGroup->actions())
410 {
411 a->setChecked(false);
412 }
413 }
414}
415
416/** Major Dialog Window Actions **/
417
418void KStars::slotCalculator()
419{
420 if (!m_AstroCalc)
421 m_AstroCalc = new AstroCalc(this);
422 m_AstroCalc->show();
423}
424
426{
427 QPointer<KSWizard> wizard = new KSWizard(this);
428 if (wizard->exec() == QDialog::Accepted)
429 {
430 Options::setRunStartupWizard(false); //don't run on startup next time
431 if (wizard->geo())
432 updateLocationFromWizard(*(wizard->geo()));
433 }
434}
435
436void KStars::updateLocationFromWizard(const GeoLocation &geo)
437{
438 data()->setLocation(geo);
439 // adjust local time to keep UT the same.
440 // create new LT without DST offset
441 KStarsDateTime ltime = data()->geo()->UTtoLT(data()->ut());
442
443 // reset timezonerule to compute next dst change
444 data()->geo()->tzrule()->reset_with_ltime(ltime, data()->geo()->TZ0(),
445 data()->isTimeRunningForward());
446
447 // reset next dst change time
448 data()->setNextDSTChange(data()->geo()->tzrule()->nextDSTChange());
449
450 // reset local sideral time
451 data()->syncLST();
452
453 // Make sure Numbers, Moon, planets, and sky objects are updated immediately
455
456 // If the sky is in Horizontal mode and not tracking, reset focus such that
457 // Alt/Az remain constant.
458 if (!Options::isTracking() && Options::useAltAz())
459 {
460 map()->focus()->HorizontalToEquatorial(data()->lst(), data()->geo()->lat());
461 }
462
463 // recalculate new times and objects
465 updateTime();
466}
467
468void KStars::slotDownload()
469{
470 KSNotification::event(
471 QLatin1String("KnownIssue"),
472 i18n("Due to a known issue in the kde frameworks, "
473 "updating already downloaded items is currently not possible. <br> "
474 "Please uninstall and reinstall them to update."));
475
476 // 2017-07-04: Explicitly load kstars.knsrc from resources file
477#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
478 auto dlg = std::make_unique<KNSWidgets::Dialog>(":/kconfig/kstars.knsrc", this);
479#else
480 auto dlg = std::make_unique<KNS3::DownloadDialog>(":/kconfig/kstars.knsrc", this);
481#endif
482
483 if (!dlg)
484 return;
485
486 dlg->exec();
487
488 // Get the list of all the installed entries.
489 const auto changed_entries = dlg->changedEntries();
490
491 CatalogsDB::DBManager manager{ CatalogsDB::dso_db_path() };
492#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
493 for (const KNSCore::Entry &entry : changed_entries)
494#else
495 for (const KNS3::Entry &entry : changed_entries)
496#endif
497 {
498 if (entry.category() != "dso")
499 continue;
500
501#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
502 const auto id = entry.uniqueId().toInt();
503 if (entry.status() == KNSCore::Entry::Installed)
504#else
505 const auto id = entry.id().toInt();
506 if (entry.status() == KNS3::Entry::Installed)
507#endif
508 for (const QString &name : entry.installedFiles())
509 {
510 if (name.endsWith(CatalogsDB::db_file_extension))
511 {
512 const auto meta{ CatalogsDB::read_catalog_meta_from_file(name) };
513
514 if (!meta.first)
515 {
517 this, i18n("Error"),
518 i18n("The catalog \"%1\" is corrupt.", entry.name()));
519 continue;
520 }
521
522 if (meta.second.id != id)
523 {
525 this, i18n("Error"),
526 i18n("The catalog \"%1\" is corrupt.<br>Expected id=%2 but "
527 "got id=%3",
528 entry.name(), id, meta.second.id));
529 continue;
530 }
531
532 const auto success{ manager.import_catalog(name, true) };
533 if (!success.first)
535 this, i18n("Error"),
536 i18n("Could not import the catalog \"%1\"<br>%2",
537 entry.name(), success.second));
538 }
539 }
540#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
541 if (entry.status() == KNSCore::Entry::Deleted)
542#else
543 if (entry.status() == KNS3::Entry::Deleted)
544#endif
545 {
546 manager.remove_catalog(id);
547 }
548 }
549
551 KStars::Instance()->data()->skyComposite()->reloadDeepSky();
555}
556
557void KStars::slotAVT()
558{
559 if (!m_AltVsTime)
560 m_AltVsTime = new AltVsTime(this);
561 m_AltVsTime->show();
562}
563
564void KStars::slotWUT()
565{
566 if (!m_WUTDialog)
567 m_WUTDialog = new WUTDialog(this);
568 m_WUTDialog->show();
569}
570
571//FIXME Port to QML2
572//#if 0
574{
575 if (!m_WIView)
577 if (m_WIView && !m_wiDock->isVisible())
579
580 if (KConfigDialog::showDialog("wisettings"))
581 {
582 m_WIEquipmentSettings->populateScopeListWidget();
583 return;
584 }
585
586 KConfigDialog *dialog = new KConfigDialog(this, "wisettings", Options::self());
587
588 connect(dialog, SIGNAL(settingsChanged(QString)), this,
590
591 m_WISettings = new WILPSettings(this);
592 m_WIEquipmentSettings = new WIEquipSettings();
593 dialog->addPage(m_WISettings, i18n("Light Pollution Settings"));
594 dialog->addPage(m_WIEquipmentSettings,
595 i18n("Equipment Settings - Equipment Type and Parameters"));
596 dialog->exec();
597 if (m_WIEquipmentSettings)
598 m_WIEquipmentSettings->setAperture(); //Something isn't working with this!
599}
600
602{
603 if (KStars::Closing)
604 return;
605
606 if (!m_WIView)
607 {
608 m_WIView = new WIView(nullptr);
609 m_wiDock = new QDockWidget(this);
610 m_wiDock->setStyleSheet("QDockWidget::title{background-color:black;}");
611 m_wiDock->setObjectName("What's Interesting");
613 QWidget *container = QWidget::createWindowContainer(m_WIView->getWIBaseView());
614 m_wiDock->setWidget(container);
615 m_wiDock->setMinimumWidth(400);
617 connect(m_wiDock, SIGNAL(visibilityChanged(bool)),
618 actionCollection()->action("show_whatsinteresting"),
619 SLOT(setChecked(bool)));
620 m_wiDock->setVisible(true);
621 }
622 else
623 {
624 m_wiDock->setVisible(!m_wiDock->isVisible());
625 }
626}
627
628void KStars::slotCalendar()
629{
630 if (!m_SkyCalendar)
631 m_SkyCalendar = new SkyCalendar(this);
632 m_SkyCalendar->show();
633}
634
635void KStars::slotGlossary()
636{
637 // GlossaryDialog *dlg = new GlossaryDialog( this, true );
638 // QString glossaryfile =data()->stdDirs->findResource( "data", "kstars/glossary.xml" );
639 // QUrl u = glossaryfile;
640 // Glossary *g = new Glossary( u );
641 // g->setName( i18n( "Knowledge" ) );
642 // dlg->addGlossary( g );
643 // dlg->show();
644}
645
646void KStars::slotScriptBuilder()
647{
648 if (!m_ScriptBuilder)
649 m_ScriptBuilder = new ScriptBuilder(this);
650 m_ScriptBuilder->show();
651}
652
653void KStars::slotSolarSystem()
654{
655 if (!m_PlanetViewer)
656 m_PlanetViewer = new PlanetViewer(this);
657 m_PlanetViewer->show();
658}
659
660void KStars::slotJMoonTool()
661{
662 if (!m_JMoonTool)
663 m_JMoonTool = new JMoonTool(this);
664 m_JMoonTool->show();
665}
666
667void KStars::slotMoonPhaseTool()
668{
669 //FIXME Port to KF5
670 //if( ! mpt ) mpt = new MoonPhaseTool( this );
671 //mpt->show();
672}
673
675{
676 if (!m_FlagManager)
677 m_FlagManager = new FlagManager(this);
678 m_FlagManager->show();
679}
680
681#if 0
682void KStars::slotTelescopeWizard()
683{
684#ifdef HAVE_INDI
685#ifndef Q_OS_WIN
686
687 QString indiServerDir = Options::indiServer();
688
689#ifdef Q_OS_MACOS
690 if (Options::indiServerIsInternal())
691 indiServerDir = QCoreApplication::applicationDirPath();
692 else
693 indiServerDir = QFileInfo(Options::indiServer()).dir().path();
694#endif
695
696 QStringList paths;
697 paths << "/usr/bin"
698 << "/usr/local/bin" << indiServerDir;
699
700 if (QStandardPaths::findExecutable("indiserver").isEmpty())
701 {
702 if (QStandardPaths::findExecutable("indiserver", paths).isEmpty())
703 {
704 KSNotification::error(i18n("Unable to find INDI server. Please make sure the package that provides "
705 "the 'indiserver' binary is installed."));
706 return;
707 }
708 }
709#endif
710
711 QPointer<telescopeWizardProcess> twiz = new telescopeWizardProcess(this);
712 twiz->exec();
713 delete twiz;
714#endif
715}
716#endif
717
718void KStars::slotINDIPanel()
719{
720#ifdef HAVE_INDI
721#ifndef Q_OS_WIN
722
723 QString indiServerDir = Options::indiServer();
724
725#ifdef Q_OS_MACOS
726 if (Options::indiServerIsInternal())
727 indiServerDir = QCoreApplication::applicationDirPath();
728 else
729 indiServerDir = QFileInfo(Options::indiServer()).dir().path();
730#endif
731
732 QStringList paths;
733 paths << "/usr/bin"
734 << "/usr/local/bin" << indiServerDir;
735
736 if (QStandardPaths::findExecutable("indiserver").isEmpty())
737 {
738 if (QStandardPaths::findExecutable("indiserver", paths).isEmpty())
739 {
740 KSNotification::error(i18n(
741 "Unable to find INDI server. Please make sure the package that provides "
742 "the 'indiserver' binary is installed."));
743 return;
744 }
745 }
746#endif
747 GUIManager::Instance()->updateStatus(true);
748#endif
749}
750
751void KStars::slotINDIDriver()
752{
753#ifdef HAVE_INDI
754#ifndef Q_OS_WIN
755
757 nullptr,
758 i18n("INDI Device Manager should only be used by advanced technical users. "
759 "It cannot be used with Ekos. Do you still want to open INDI device "
760 "manager?"),
761 i18n("INDI Device Manager"), KStandardGuiItem::cont(),
763 "indi_device_manager_warning") == KMessageBox::Cancel)
764 return;
765
766 QString indiServerDir = Options::indiServer();
767
768#ifdef Q_OS_MACOS
769 if (Options::indiServerIsInternal())
770 indiServerDir = QCoreApplication::applicationDirPath();
771 else
772 indiServerDir = QFileInfo(Options::indiServer()).dir().path();
773#endif
774
775 QStringList paths;
776 paths << "/usr/bin"
777 << "/usr/local/bin" << indiServerDir;
778
779 if (QStandardPaths::findExecutable("indiserver").isEmpty())
780 {
781 if (QStandardPaths::findExecutable("indiserver", paths).isEmpty())
782 {
783 KSNotification::error(i18n(
784 "Unable to find INDI server. Please make sure the package that provides "
785 "the 'indiserver' binary is installed."));
786 return;
787 }
788 }
789#endif
790
791 DriverManager::Instance()->raise();
792 DriverManager::Instance()->activateWindow();
793 DriverManager::Instance()->showNormal();
794
795#endif
796}
797
798void KStars::slotEkos()
799{
800#ifdef HAVE_CFITSIO
801#ifdef HAVE_INDI
802
803#ifndef Q_OS_WIN
804
805 QString indiServerDir = Options::indiServer();
806
807#ifdef Q_OS_MACOS
808 if (Options::indiServerIsInternal())
809 indiServerDir = QCoreApplication::applicationDirPath();
810 else
811 indiServerDir = QFileInfo(Options::indiServer()).dir().path();
812#endif
813
814 QStringList paths;
815 paths << "/usr/bin"
816 << "/usr/local/bin" << indiServerDir;
817
818 if (QStandardPaths::findExecutable("indiserver").isEmpty())
819 {
820 if (QStandardPaths::findExecutable("indiserver", paths).isEmpty())
821 {
822 KSNotification::error(i18n(
823 "Unable to find INDI server. Please make sure the package that provides "
824 "the 'indiserver' binary is installed."));
825 return;
826 }
827 }
828#endif
829
830 if (Ekos::Manager::Instance()->isVisible() &&
831 Ekos::Manager::Instance()->isActiveWindow())
832 {
833 Ekos::Manager::Instance()->hide();
834 }
835 else
836 {
837 Ekos::Manager::Instance()->raise();
838 Ekos::Manager::Instance()->activateWindow();
839 Ekos::Manager::Instance()->showNormal();
840 }
841
842#endif
843#endif
844}
845
846void KStars::slotINDITelescopeTrack()
847{
848#ifdef HAVE_INDI
849 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
850 return;
851
852 for (auto &oneDevice : INDIListener::devices())
853 {
854 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
855 continue;
856
857 auto mount = oneDevice->getMount();
858 if (!mount || mount->isConnected() == false)
859 continue;
860
862
863 if (a != nullptr)
864 {
865 mount->setTrackEnabled(a->isChecked());
866 return;
867 }
868 }
869#endif
870}
871
872void KStars::slotINDITelescopeSlew(bool focused_object)
873{
874#ifdef HAVE_INDI
875 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
876 return;
877
878 for (auto &oneDevice : INDIListener::devices())
879 {
880 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
881 continue;
882
883 auto mount = oneDevice->getMount();
884 if (!mount || mount->isConnected() == false)
885 continue;
886 if (focused_object)
887 {
888 if (m_SkyMap->focusObject() != nullptr)
889 mount->Slew(m_SkyMap->focusObject());
890 }
891 else
892 mount->Slew(m_SkyMap->mousePoint());
893
894 return;
895 }
896#else
897 Q_UNUSED(focused_object)
898#endif
899}
900
901void KStars::slotINDITelescopeSlewMousePointer()
902{
903#ifdef HAVE_INDI
904 slotINDITelescopeSlew(false);
905#endif
906}
907
908void KStars::slotINDITelescopeSync(bool focused_object)
909{
910#ifdef HAVE_INDI
911 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
912 return;
913
914 for (auto &oneDevice : INDIListener::devices())
915 {
916 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
917 continue;
918
919 auto mount = oneDevice->getMount();
920 if (!mount || mount->isConnected() == false)
921 continue;
922
923 if (focused_object)
924 {
925 if (m_SkyMap->focusObject() != nullptr)
926 mount->Sync(m_SkyMap->focusObject());
927 }
928 else
929 mount->Sync(m_SkyMap->mousePoint());
930
931 return;
932 }
933#else
934 Q_UNUSED(focused_object)
935#endif
936}
937
938void KStars::slotINDITelescopeSyncMousePointer()
939{
940#ifdef HAVE_INDI
941 slotINDITelescopeSync(false);
942#endif
943}
944
945void KStars::slotINDITelescopeAbort()
946{
947#ifdef HAVE_INDI
948 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
949 return;
950
951 for (auto &oneDevice : INDIListener::devices())
952 {
953 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
954 continue;
955
956 auto mount = oneDevice->getMount();
957 if (!mount || mount->isConnected() == false)
958 continue;
959
960 mount->abort();
961 return;
962 }
963#endif
964}
965
966void KStars::slotINDITelescopePark()
967{
968#ifdef HAVE_INDI
969 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
970 return;
971
972 for (auto &oneDevice : INDIListener::devices())
973 {
974 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
975 continue;
976
977 auto mount = oneDevice->getMount();
978 if (!mount || mount->isConnected() == false || mount->canPark() == false)
979 continue;
980
981 mount->park();
982 return;
983 }
984#endif
985}
986
987void KStars::slotINDITelescopeUnpark()
988{
989#ifdef HAVE_INDI
990 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
991 return;
992
993 for (auto &oneDevice : INDIListener::devices())
994 {
995 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
996 continue;
997
998 auto mount = oneDevice->getMount();
999 if (!mount || mount->isConnected() == false || mount->canPark() == false)
1000 continue;
1001
1002 mount->unpark();
1003 return;
1004 }
1005#endif
1006}
1007
1008void KStars::slotINDIDomePark()
1009{
1010#ifdef HAVE_INDI
1011 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
1012 return;
1013
1014 for (auto &oneDevice : INDIListener::devices())
1015 {
1016 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::DOME_INTERFACE))
1017 continue;
1018
1019 auto dome = oneDevice->getDome();
1020 if (!dome || dome->isConnected() == false)
1021 continue;
1022 if (dome->canPark())
1023 {
1024 dome->park();
1025 return;
1026 }
1027 }
1028#endif
1029}
1030
1031void KStars::slotINDIDomeUnpark()
1032{
1033#ifdef HAVE_INDI
1034 if (m_KStarsData == nullptr || INDIListener::Instance() == nullptr)
1035 return;
1036
1037 for (auto &oneDevice : INDIListener::devices())
1038 {
1039 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::DOME_INTERFACE))
1040 continue;
1041
1042 auto dome = oneDevice->getDome();
1043 if (!dome || dome->isConnected() == false)
1044 continue;
1045 if (dome->canPark())
1046 {
1047 dome->unpark();
1048 return;
1049 }
1050 }
1051#endif
1052}
1053
1055{
1056 QPointer<LocationDialog> locationdialog = new LocationDialog(this);
1057 if (locationdialog->exec() == QDialog::Accepted)
1058 {
1059 GeoLocation *newLocation = locationdialog->selectedCity();
1060 if (newLocation)
1061 {
1062 // set new location in options
1063 data()->setLocation(*newLocation);
1064
1065 // adjust local time to keep UT the same.
1066 // create new LT without DST offset
1067 KStarsDateTime ltime = newLocation->UTtoLT(data()->ut());
1068
1069 // reset timezonerule to compute next dst change
1070 newLocation->tzrule()->reset_with_ltime(ltime, newLocation->TZ0(),
1071 data()->isTimeRunningForward());
1072
1073 // reset next dst change time
1074 data()->setNextDSTChange(newLocation->tzrule()->nextDSTChange());
1075
1076 // reset local sideral time
1077 data()->syncLST();
1078
1079 // Make sure Numbers, Moon, planets, and sky objects are updated immediately
1081
1082 // If the sky is in Horizontal mode and not tracking, reset focus such that
1083 // Alt/Az remain constant.
1084 if (!Options::isTracking() && Options::useAltAz())
1085 {
1086 map()->focus()->HorizontalToEquatorial(data()->lst(),
1087 data()->geo()->lat());
1088 }
1089
1090 // recalculate new times and objects
1092 updateTime();
1093 }
1094 }
1095 delete locationdialog;
1096}
1097
1098void KStars::slotViewOps()
1099{
1100 // An instance of your dialog could be already created and could be cached,
1101 // in which case you want to display the cached dialog instead of creating
1102 // another one
1103 auto ops = prepareOps();
1104 ops->show();
1105 // Bring to the front.
1106 ops->raise(); // for MacOS
1107 ops->activateWindow(); // for Windows
1108}
1109
1110KConfigDialog *KStars::prepareOps()
1111{
1112 KConfigDialog *dialog = KConfigDialog::exists("settings");
1113 if (nullptr != dialog)
1114 return dialog;
1115
1116 // KConfigDialog didn't find an instance of this dialog, so lets create it :
1117 dialog = new KConfigDialog(this, "settings", Options::self());
1118
1119 // For some reason the dialog does not resize to contents
1120 // so we set initial 'resonable' size here. Any better way to do this?
1121 dialog->resize(800, 600);
1122#ifdef Q_OS_MACOS
1123 dialog->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
1124#endif
1125
1126 connect(dialog, SIGNAL(settingsChanged(QString)), this,
1127 SLOT(slotApplyConfigChanges()));
1128
1129 opcatalog = new OpsCatalog();
1130 opguides = new OpsGuides();
1131 opterrain = new OpsTerrain();
1132 opsImageOverlay = new OpsImageOverlay();
1133 opsdeveloper = new OpsDeveloper();
1134 opsolsys = new OpsSolarSystem();
1135 opssatellites = new OpsSatellites();
1136 opssupernovae = new OpsSupernovae();
1137 opcolors = new OpsColors();
1138 opadvanced = new OpsAdvanced();
1139
1140 KPageWidgetItem *page;
1141
1142 page = dialog->addPage(opcatalog, i18n("Catalogs"), "kstars_catalog");
1143 page->setIcon(QIcon::fromTheme("kstars_catalog"));
1144
1145 page = dialog->addPage(opsolsys, i18n("Solar System"), "kstars_solarsystem");
1146 page->setIcon(QIcon::fromTheme("kstars_solarsystem"));
1147
1148 page = dialog->addPage(opssatellites, i18n("Satellites"), "kstars_satellites");
1149 page->setIcon(QIcon::fromTheme("kstars_satellites"));
1150
1151 page = dialog->addPage(opssupernovae, i18n("Supernovae"), "kstars_supernovae");
1152 page->setIcon(QIcon::fromTheme("kstars_supernovae"));
1153
1154 page = dialog->addPage(opguides, i18n("Guides"), "kstars_guides");
1155 page->setIcon(QIcon::fromTheme("kstars_guides"));
1156
1157 page = dialog->addPage(opterrain, i18n("Terrain"), "kstars_terrain");
1158 page->setIcon(QIcon::fromTheme("kstars_terrain", QIcon(":/icons/kstars_terrain.png")));
1159
1160 page = dialog->addPage(opsImageOverlay, i18n("Image Overlays"), "kstars_imageoverlay");
1161 page->setIcon(QIcon::fromTheme("kstars_imageoverlay", QIcon(":/icons/kstars_imageoverlay.png")));
1162 KStarsData::Instance()->skyComposite()->imageOverlay()->setWidgets(
1163 opsImageOverlay->table(), opsImageOverlay->statusDisplay(), opsImageOverlay->solvePushButton(),
1164 opsImageOverlay->tableTitleBox(), opsImageOverlay->solverProfile());
1165
1166 page = dialog->addPage(opcolors, i18n("Colors"), "kstars_colors");
1167 page->setIcon(QIcon::fromTheme("kstars_colors"));
1168
1169#ifdef HAVE_CFITSIO
1170 opsfits = new OpsFITS();
1171 page = dialog->addPage(opsfits, i18n("FITS"), "kstars_fitsviewer");
1172 page->setIcon(QIcon::fromTheme("kstars_fitsviewer"));
1173#endif
1174
1175#ifdef HAVE_INDI
1176 opsindi = new OpsINDI();
1177 page = dialog->addPage(opsindi, i18n("INDI"), "kstars_indi");
1178 page->setIcon(QIcon::fromTheme("kstars_indi"));
1179#ifdef HAVE_CFITSIO
1180 opsekos = new OpsEkos();
1181 KPageWidgetItem *ekosOption = dialog->addPage(opsekos, i18n("Ekos"), "kstars_ekos");
1182 ekosOption->setIcon(QIcon::fromTheme("kstars_ekos"));
1183 if (Ekos::Manager::Instance())
1184 Ekos::Manager::Instance()->setOptionsWidget(ekosOption, opsekos);
1185#endif
1186
1187#endif
1188
1189 opsxplanet = new OpsXplanet(this);
1190 page = dialog->addPage(opsxplanet, i18n("Xplanet"), "kstars_xplanet");
1191 page->setIcon(QIcon::fromTheme("kstars_xplanet"));
1192
1193 page = dialog->addPage(opadvanced, i18n("Advanced"), "kstars_advanced");
1194 page->setIcon(QIcon::fromTheme("kstars_advanced"));
1195
1196 page = dialog->addPage(opsdeveloper, i18n("Developer"), "kstars_developer");
1197 page->setIcon(QIcon::fromTheme("kstars_developer", QIcon(":/icons/kstars_developer.png")));
1198
1199#ifdef Q_OS_MACOS // This is because KHelpClient doesn't seem to be working right on MacOS
1200 dialog->button(QDialogButtonBox::Help)->disconnect();
1201 connect(dialog->button(QDialogButtonBox::Help), &QPushButton::clicked, this, []()
1202 {
1203 KStars::Instance()->appHelpActivated();
1204 });
1205#endif
1206
1207 return dialog;
1208}
1209
1211{
1212 opterrain->syncOptions();
1213 actionCollection()->action("toggle_terrain")
1214 ->setText(Options::showTerrain() ? i18n("Hide Terrain") : i18n("Show Terrain"));
1215
1216 opsImageOverlay->syncOptions();
1217 actionCollection()->action("toggle_image_overlays")
1218 ->setText(Options::showImageOverlays() ? i18n("Hide Image Overlays") : i18n("Show Image Overlays"));
1219}
1220
1222{
1223 Options::self()->save();
1224
1225 applyConfig();
1226
1227 //data()->setFullTimeUpdate();
1228 //map()->forceUpdate();
1229}
1230
1232{
1233 Options::self()->save();
1234 applyConfig();
1235 m_WIView->updateObservingConditions();
1236 m_WIView->onReloadIconClicked();
1237}
1238
1239void KStars::slotSetTime()
1240{
1241 QPointer<TimeDialog> timedialog = new TimeDialog(data()->lt(), data()->geo(), this);
1242
1243 if (timedialog->exec() == QDialog::Accepted)
1244 {
1245 data()->changeDateTime(data()->geo()->LTtoUT(timedialog->selectedDateTime()));
1246
1247 if (Options::useAltAz())
1248 {
1249 if (map()->focusObject())
1250 {
1252 data()->geo()->lat());
1253 map()->setFocus(map()->focusObject());
1254 }
1255 else
1256 map()->focus()->HorizontalToEquatorial(data()->lst(),
1257 data()->geo()->lat());
1258 }
1259
1260 map()->forceUpdateNow();
1261
1262 //If focusObject has a Planet Trail, clear it and start anew.
1263 KSPlanetBase *planet = dynamic_cast<KSPlanetBase *>(map()->focusObject());
1264 if (planet && planet->hasTrail())
1265 {
1266 planet->clearTrail();
1267 planet->addToTrail();
1268 }
1269 }
1270 delete timedialog;
1271}
1272
1273//Set Time to CPU clock
1275{
1277
1278 if (Options::useAltAz())
1279 {
1280 if (map()->focusObject())
1281 {
1283 data()->geo()->lat());
1284 map()->setFocus(map()->focusObject());
1285 }
1286 else
1287 map()->focus()->HorizontalToEquatorial(data()->lst(), data()->geo()->lat());
1288 }
1289
1290 map()->forceUpdateNow();
1291
1292 //If focusObject has a Planet Trail, clear it and start anew.
1293 KSPlanetBase *planet = dynamic_cast<KSPlanetBase *>(map()->focusObject());
1294 if (planet && planet->hasTrail())
1295 {
1296 planet->clearTrail();
1297 planet->addToTrail();
1298 }
1299}
1300
1301void KStars::slotFind()
1302{
1303 //clearCachedFindDialog();
1304 SkyObject *targetObject = nullptr;
1305 if (FindDialog::Instance()->exec() == QDialog::Accepted &&
1306 (targetObject = FindDialog::Instance()->targetObject()))
1307 {
1308 map()->setClickedObject(targetObject);
1309 map()->setClickedPoint(map()->clickedObject());
1310 map()->slotCenter();
1311 }
1312
1313 // check if data has changed while dialog was open
1314 //if (DialogIsObsolete)
1315 // clearCachedFindDialog();
1316}
1317
1318void KStars::slotOpenFITS()
1319{
1320#ifdef HAVE_CFITSIO
1321 auto fv = createFITSViewer();
1322 fv->openFile();
1323#endif
1324}
1325
1326void KStars::slotBlink()
1327{
1328#ifdef HAVE_CFITSIO
1329 auto fv = createFITSViewer();
1330 fv->blink();
1331#endif
1332}
1333
1334void KStars::slotExportImage()
1335{
1336 //TODO Check this
1337 //For remote files, this returns
1338 //QFileInfo::absolutePath: QFileInfo::absolutePath: Constructed with empty filename
1339 //As of 2014-07-19
1340 //QUrl fileURL = KFileDialog::getSaveUrl( QDir::homePath(), "image/png image/jpeg image/gif image/x-portable-pixmap image/bmp image/svg+xml" );
1341 QUrl fileURL =
1342 QFileDialog::getSaveFileUrl(KStars::Instance(), i18nc("@title:window", "Export Image"), QUrl(),
1343 "Images (*.png *.jpeg *.gif *.bmp *.svg)");
1344
1345 //User cancelled file selection dialog - abort image export
1346 if (fileURL.isEmpty())
1347 {
1348 return;
1349 }
1350
1351 //Warn user if file exists!
1352 if (QFile::exists(fileURL.toLocalFile()))
1353 {
1355 parentWidget(),
1356 i18n("A file named \"%1\" already exists. Overwrite it?", fileURL.fileName()),
1357 i18n("Overwrite File?"), KStandardGuiItem::overwrite());
1358 if (r == KMessageBox::Cancel)
1359 return;
1360 }
1361
1362 // execute image export dialog
1363
1364 // Note: We don't let ExportImageDialog create its own ImageExporter because we want legend settings etc to be remembered between UI use and DBus scripting interface use.
1365 //if ( !m_ImageExporter )
1366 //m_ImageExporter = new ImageExporter( this );
1367
1368 if (!m_ExportImageDialog)
1369 {
1370 m_ExportImageDialog = new ExportImageDialog(
1371 fileURL.toLocalFile(), QSize(map()->width(), map()->height()),
1372 KStarsData::Instance()->imageExporter());
1373 }
1374 else
1375 {
1376 m_ExportImageDialog->setOutputUrl(fileURL.toLocalFile());
1377 m_ExportImageDialog->setOutputSize(QSize(map()->width(), map()->height()));
1378 }
1379
1380 m_ExportImageDialog->show();
1381}
1382
1383void KStars::slotRunScript()
1384{
1387 "*.kstars|" +
1388 i18nc("Filter by file type: KStars Scripts.", "KStars Scripts (*.kstars)"));
1389 QFile f;
1390 //QString fname;
1391
1392 if (fileURL.isValid())
1393 {
1394 if (fileURL.isLocalFile() == false)
1395 {
1396 KSNotification::sorry(i18n("Executing remote scripts is not supported."));
1397 return;
1398 }
1399
1400 f.setFileName(fileURL.toLocalFile());
1401
1402 if (!f.open(QIODevice::ReadOnly))
1403 {
1404 QString message = i18n("Could not open file %1", f.fileName());
1405 KSNotification::sorry(message, i18n("Could Not Open File"));
1406 return;
1407 }
1408
1409 QTextStream istream(&f);
1410 QString line;
1411 bool fileOK(true);
1412
1413 while (!istream.atEnd())
1414 {
1415 line = istream.readLine();
1416 if (line.at(0) != '#' && line.left(9) != "dbus-send")
1417 {
1418 fileOK = false;
1419 break;
1420 }
1421 }
1422
1423 if (!fileOK)
1424 {
1425 int answer;
1427 nullptr,
1428 i18n(
1429 "The selected script contains unrecognized elements, "
1430 "indicating that it was not created using the KStars script builder. "
1431 "This script may not function properly, and it may even contain "
1432 "malicious code. "
1433 "Would you like to execute it anyway?"),
1434 i18n("Script Validation Failed"), KGuiItem(i18n("Run Nevertheless")),
1435 KStandardGuiItem::cancel(), "daExecuteScript");
1436 if (answer == KMessageBox::Cancel)
1437 return;
1438 }
1439
1440 //Add statusbar message that script is running
1441 statusBar()->showMessage(i18n("Running script: %1", fileURL.fileName()));
1442
1443 // 2017-09-19: Jasem
1444 // FIXME This is a hack and does not work on non-Linux systems
1445 // The Script Builder should generate files that can run cross-platform
1446 QProcess p;
1447 QStringList arguments;
1448 p.start(f.fileName(), arguments);
1449 if (!p.waitForStarted())
1450 return;
1451
1452 while (!p.waitForFinished(10))
1453 {
1454 qApp->processEvents(); //otherwise tempfile may get deleted before script completes.
1455 if (p.state() != QProcess::Running)
1456 break;
1457 }
1458
1459 statusBar()->showMessage(i18n("Script finished."), 0);
1460 }
1461}
1462
1463void KStars::slotPrint()
1464{
1465 bool switchColors(false);
1466
1467 //Suggest Chart color scheme
1468 if (data()->colorScheme()->colorNamed("SkyColor") != QColor(255, 255, 255))
1469 {
1470 QString message =
1471 i18n("You can save printer ink by using the \"Star Chart\" "
1472 "color scheme, which uses a white background. Would you like to "
1473 "temporarily switch to the Star Chart color scheme for printing?");
1474
1476 nullptr, message, i18n("Switch to Star Chart Colors?"),
1477 KGuiItem(i18n("Switch Color Scheme")), KGuiItem(i18n("Do Not Switch")), "askAgainPrintColors");
1478
1479 if (answer == KMessageBox::Cancel)
1480 return;
1481 if (answer == KMessageBox::Continue)
1482 switchColors = true;
1483 }
1484
1485 printImage(true, switchColors);
1486}
1487
1488void KStars::slotPrintingWizard()
1489{
1490 if (m_PrintingWizard)
1491 {
1492 delete m_PrintingWizard;
1493 }
1494
1495 m_PrintingWizard = new PrintingWizard(this);
1496 m_PrintingWizard->show();
1497}
1498
1499void KStars::slotToggleTimer()
1500{
1501 if (data()->clock()->isActive())
1502 {
1503 data()->clock()->stop();
1504 updateTime();
1505 }
1506 else
1507 {
1508 if (fabs(data()->clock()->scale()) > Options::slewTimeScale())
1509 data()->clock()->setManualMode(true);
1510 data()->clock()->start();
1511 if (data()->clock()->isManualMode())
1512 map()->forceUpdate();
1513 }
1514
1515 // Update clock state in options
1516 Options::setRunClock(data()->clock()->isActive());
1517}
1518
1519void KStars::slotRealTimeToogled(bool checked)
1520{
1521 KToggleAction *ta = static_cast<KToggleAction*>(actionCollection()->action("clock_realtime"));
1522 if (checked)
1523 {
1524 QAction *a = nullptr;
1525 a = actionCollection()->action("clock_startstop");
1526 if (a)a->setDisabled(true);
1527 a = actionCollection()->action("time_step_forward");
1528 if (a)a->setDisabled(true);
1529 a = actionCollection()->action("time_step_backward");
1530 if (a)a->setDisabled(true);
1531 a = actionCollection()->action("time_to_now");
1532 if (a)a->setDisabled(true);
1533 a = actionCollection()->action("time_dialog");
1534 if (a)a->setDisabled(true);
1535 m_TimeStepBox->setDisabled(true);
1536 if (ta)ta->setChecked(true);
1537 }
1538 else
1539 {
1540 QAction *a = nullptr;
1541 a = actionCollection()->action("clock_startstop");
1542 if (a)a->setDisabled(false);
1543 a = actionCollection()->action("time_step_forward");
1544 if (a)a->setDisabled(false);
1545 a = actionCollection()->action("time_step_backward");
1546 if (a)a->setDisabled(false);
1547 a = actionCollection()->action("time_to_now");
1548 if (a)a->setDisabled(false);
1549 a = actionCollection()->action("time_dialog");
1550 if (a)a->setDisabled(false);
1551 m_TimeStepBox->setDisabled(false);
1552 if (ta)ta->setChecked(false);
1553 }
1554}
1555
1556void KStars::slotStepForward()
1557{
1558 if (data()->clock()->isActive())
1559 data()->clock()->stop();
1560 data()->clock()->manualTick(true);
1561 map()->forceUpdate();
1562}
1563
1564void KStars::slotStepBackward()
1565{
1566 if (data()->clock()->isActive())
1567 data()->clock()->stop();
1568 data()->clock()->manualTick(true, true);
1569 map()->forceUpdate();
1570}
1571
1572//Pointing
1573void KStars::slotPointFocus()
1574{
1575 // In the following cases, we set slewing=true in order to disengage tracking
1576 map()->stopTracking();
1577
1578 if (sender() == actionCollection()->action("zenith"))
1579 map()->setDestinationAltAz(dms(90.0), map()->focus()->az(),
1580 Options::useRefraction());
1581 else if (sender() == actionCollection()->action("north"))
1582 map()->setDestinationAltAz(dms(15.0), dms(0.0001), Options::useRefraction());
1583 else if (sender() == actionCollection()->action("east"))
1584 map()->setDestinationAltAz(dms(15.0), dms(90.0), Options::useRefraction());
1585 else if (sender() == actionCollection()->action("south"))
1586 map()->setDestinationAltAz(dms(15.0), dms(180.0), Options::useRefraction());
1587 else if (sender() == actionCollection()->action("west"))
1588 map()->setDestinationAltAz(dms(15.0), dms(270.0), Options::useRefraction());
1589}
1590
1592{
1593 if (Options::isTracking())
1594 {
1595 Options::setIsTracking(false);
1596 actionCollection()->action("track_object")->setText(i18n("Engage &Tracking"));
1598 ->action("track_object")
1599 ->setIcon(QIcon::fromTheme("document-decrypt"));
1600
1601 KSPlanetBase *planet = dynamic_cast<KSPlanetBase *>(map()->focusObject());
1602 if (planet && data()->temporaryTrail)
1603 {
1604 planet->clearTrail();
1605 data()->temporaryTrail = false;
1606 }
1607
1608 map()->setClickedObject(nullptr);
1609 map()->setFocusObject(nullptr); //no longer tracking focusObject
1610 map()->setFocusPoint(nullptr);
1611 }
1612 else
1613 {
1614 map()->setClickedPoint(map()->focus());
1615 map()->setClickedObject(nullptr);
1616 map()->setFocusObject(nullptr); //no longer tracking focusObject
1617 map()->setFocusPoint(map()->clickedPoint());
1618 Options::setIsTracking(true);
1619 actionCollection()->action("track_object")->setText(i18n("Stop &Tracking"));
1621 ->action("track_object")
1622 ->setIcon(QIcon::fromTheme("document-encrypt"));
1623 }
1624
1625 map()->forceUpdate();
1626}
1627
1628void KStars::slotManualFocus()
1629{
1630 QPointer<FocusDialog> focusDialog = new FocusDialog();
1631
1632 // JM 2019-09-04: Should default to RA/DE always
1633 // if (Options::useAltAz())
1634 // focusDialog->activateAzAltPage();
1635
1636 if (focusDialog->exec() == QDialog::Accepted)
1637 {
1638 //If the requested position is very near the pole, we need to point first
1639 //to an intermediate location just below the pole in order to get the longitudinal
1640 //position (RA/Az) right.
1641
1642 // Do not access (RA0, Dec0) of focusDialog->point() as it can be of unknown epoch.
1643 // (RA, Dec) should be synced to JNow
1644 // -- asimha (2020-07-06)
1645 double realAlt(focusDialog->point()->alt().Degrees());
1646 double realDec(focusDialog->point()->dec().Degrees());
1647 if (Options::useAltAz() && realAlt > 89.0)
1648 {
1649 focusDialog->point()->setAlt(89.0);
1650 focusDialog->point()->HorizontalToEquatorial(data()->lst(),
1651 data()->geo()->lat());
1652 }
1653 if (!Options::useAltAz() && realDec > 89.0)
1654 {
1655 focusDialog->point()->setDec(89.0);
1656 focusDialog->point()->EquatorialToHorizontal(data()->lst(),
1657 data()->geo()->lat());
1658 }
1659
1660 map()->setClickedPoint(focusDialog->point());
1661
1662 if (Options::isTracking())
1663 slotTrack();
1664
1665 map()->slotCenter();
1666
1667 //The slew takes some time to complete, and this often causes the final focus point to be slightly
1668 //offset from the user's requested coordinates (because EquatorialToHorizontal() is called
1669 //throughout the process, which depends on the sidereal time). So we now "polish" the final
1670 //position by resetting the final focus to the focusDialog point.
1671 //
1672 //Also, if the requested position was within 1 degree of the coordinate pole, this will
1673 //automatically correct the final pointing from the intermediate offset position to the final position
1675 if (Options::useAltAz())
1676 {
1677 // N.B. We have applied unrefract() in focusDialog
1678 map()->setDestinationAltAz(focusDialog->point()->alt(),
1679 focusDialog->point()->az(), false);
1680 }
1681 else
1682 {
1683 map()->setDestination(focusDialog->point()->ra(),
1684 focusDialog->point()->dec());
1685 }
1686
1687 //Now, if the requested point was near a pole, we need to reset the Alt/Dec of the focus.
1688 if (Options::useAltAz() && realAlt > 89.0)
1689 map()->focus()->setAlt(realAlt);
1690 if (!Options::useAltAz() && realDec > 89.0)
1691 map()->focus()->setDec(realAlt);
1692
1693 //Don't track if we set Alt/Az coordinates. This way, Alt/Az remain constant.
1694 if (focusDialog->usedAltAz())
1695 map()->stopTracking();
1696 }
1697 delete focusDialog;
1698}
1699
1701{
1702 // Enable/disable actions
1703 actionCollection()->action("zoom_out")->setEnabled(Options::zoomFactor() > MINZOOM);
1704 actionCollection()->action("zoom_in")->setEnabled(Options::zoomFactor() < MAXZOOM);
1705 // Update status bar
1706 map()
1707 ->setupProjector(); // this needs to be run redundantly, so that the FOV returned below is up-to-date.
1708 float fov = map()->projector()->fov();
1709 KLocalizedString fovi18nstring =
1710 ki18nc("approximate field of view", "Approximate FOV: %1 degrees");
1711 if (fov < 1.0)
1712 {
1713 fov = fov * 60.0;
1714 fovi18nstring =
1715 ki18nc("approximate field of view", "Approximate FOV: %1 arcminutes");
1716 }
1717 if (fov < 1.0)
1718 {
1719 fov = fov * 60.0;
1720 fovi18nstring =
1721 ki18nc("approximate field of view", "Approximate FOV: %1 arcseconds");
1722 }
1723 QString fovstring = fovi18nstring.subs(QString::number(fov, 'f', 1)).toString();
1724
1725 statusBar()->showMessage(fovstring, 0);
1726}
1727
1729{
1730 bool ok;
1731 double currentAngle = map()->width() / (Options::zoomFactor() * dms::DegToRad);
1732 double minAngle = map()->width() / (MAXZOOM * dms::DegToRad);
1733 double maxAngle = map()->width() / (MINZOOM * dms::DegToRad);
1734
1735 double angSize = QInputDialog::getDouble(
1736 nullptr,
1737 i18nc("The user should enter an angle for the field-of-view of the display",
1738 "Enter Desired Field-of-View Angle"),
1739 i18n("Enter a field-of-view angle in degrees: "), currentAngle, minAngle,
1740 maxAngle, 1, &ok);
1741
1742 if (ok)
1743 {
1744 map()->setZoomFactor(map()->width() / (angSize * dms::DegToRad));
1745 }
1746}
1747
1748void KStars::slotCoordSys()
1749{
1750 if (Options::useAltAz())
1751 {
1752 Options::setUseAltAz(false);
1753 if (Options::useRefraction())
1754 {
1755 if (map()->focusObject()) //simply update focus to focusObject's position
1756 map()->setFocus(map()->focusObject());
1757 else //need to recompute focus for unrefracted position
1758 {
1759 // FIXME: Changed focus()->alt() to be unrefracted by convention; is this still necessary? -- asimha 2020/07/05
1760 map()->setFocusAltAz(map()->focus()->alt(), map()->focus()->az());
1761 map()->focus()->HorizontalToEquatorial(data()->lst(),
1762 data()->geo()->lat());
1763 }
1764 }
1766 ->action("coordsys")
1767 ->setText(i18n("Switch to Horizontal View (Horizontal &Coordinates)"));
1769 ->action("up_orientation")
1770 ->setText(i18nc("Orientation of the sky map", "North &Up"));
1772 ->action("down_orientation")
1773 ->setText(i18nc("Orientation of the sky map", "North &Down"));
1774 erectObserverCorrectionGroup->setEnabled(false);
1775 }
1776 else
1777 {
1778 Options::setUseAltAz(true);
1779 if (Options::useRefraction())
1780 {
1781 // FIXME: Changed focus()->alt() to be unrefracted by convention; is this still necessary? -- asimha 2020/07/05
1782 map()->setFocusAltAz(map()->focus()->alt(), map()->focus()->az());
1783 }
1785 ->action("coordsys")
1786 ->setText(i18n("Switch to Star Globe View (Equatorial &Coordinates)"));
1788 ->action("up_orientation")
1789 ->setText(i18nc("Orientation of the sky map", "Zenith &Up"));
1791 ->action("down_orientation")
1792 ->setText(i18nc("Orientation of the sky map", "Zenith &Down"));
1793 erectObserverCorrectionGroup->setEnabled(true);
1794 }
1795 actionCollection()->action("view:arbitrary")->setChecked(true);
1796 map()->forceUpdate();
1797}
1798
1799void KStars::slotSkyMapOrientation()
1800{
1801 if (sender() == actionCollection()->action("up_orientation"))
1802 {
1803 Options::setSkyRotation(0.0);
1804 }
1805 else if (sender() == actionCollection()->action("down_orientation"))
1806 {
1807 Options::setSkyRotation(180.0);
1808 }
1809
1810 Options::setMirrorSkyMap(actionCollection()->action("mirror_skymap")->isChecked());
1811 Options::setErectObserverCorrection(
1812 actionCollection()->action("erect_observer_correction_off")->isChecked() ? 0 : (
1813 actionCollection()->action("erect_observer_correction_left")->isChecked() ? 1 : 2));
1814 actionCollection()->action("view:arbitrary")->setChecked(true);
1815 map()->forceUpdate();
1816}
1817
1818void KStars::slotMapProjection()
1819{
1820 if (sender() == actionCollection()->action("project_lambert"))
1821 Options::setProjection(Projector::Lambert);
1822 if (sender() == actionCollection()->action("project_azequidistant"))
1823 Options::setProjection(Projector::AzimuthalEquidistant);
1824 if (sender() == actionCollection()->action("project_orthographic"))
1825 Options::setProjection(Projector::Orthographic);
1826 if (sender() == actionCollection()->action("project_equirectangular"))
1827 Options::setProjection(Projector::Equirectangular);
1828 if (sender() == actionCollection()->action("project_stereographic"))
1829 Options::setProjection(Projector::Stereographic);
1830 if (sender() == actionCollection()->action("project_gnomonic"))
1831 Options::setProjection(Projector::Gnomonic);
1832
1833 //DEBUG
1834 qCDebug(KSTARS) << "Projection system: " << Options::projection();
1835
1836 m_SkyMap->forceUpdate();
1837}
1838
1839//Settings Menu:
1840void KStars::slotColorScheme()
1841{
1843}
1844
1845void KStars::slotTargetSymbol(bool flag)
1846{
1847 qDebug() << Q_FUNC_INFO << QString("slotTargetSymbol: %1 %2").arg(sender()->objectName()).arg(flag);
1848
1849 QStringList names = Options::fOVNames();
1850 if (flag)
1851 {
1852 // Add FOV to list
1853 names.append(sender()->objectName());
1854 }
1855 else
1856 {
1857 // Remove FOV from list
1858 int ix = names.indexOf(sender()->objectName());
1859 if (ix >= 0)
1860 names.removeAt(ix);
1861 }
1862 Options::setFOVNames(names);
1863
1864 // Sync visibleFOVs with fovNames
1865 data()->syncFOV();
1866
1867 map()->forceUpdate();
1868}
1869
1870void KStars::slotApplySkyMapView(const QString &viewName)
1871{
1872
1873 auto view = SkyMapViewManager::viewNamed(viewName);
1874 if (!view)
1875 {
1876 qCWarning(KSTARS) << "View named " << viewName << " not found!";
1877 return;
1878 }
1879
1880 // FIXME: Ugly hack to update the menus correctly...
1881 // we set the opposite coordinate system setting and call slotCoordSys to toggle
1882 Options::setUseAltAz(!view->useAltAz);
1883 slotCoordSys();
1884
1885 Options::setMirrorSkyMap(view->mirror);
1886 actionCollection()->action("mirror_skymap")->setChecked(Options::mirrorSkyMap());
1887
1888 int erectObserverCorrection = 0;
1889 double viewAngle = view->viewAngle;
1890 if (view->erectObserver && view->useAltAz)
1891 {
1892 if (viewAngle > 0.)
1893 {
1894 erectObserverCorrection = 1;
1895 viewAngle -= 90.; // FIXME: Check
1896 }
1897 if (viewAngle < 0.)
1898 {
1899 erectObserverCorrection = 2;
1900 viewAngle += 90.; // FIXME: Check
1901 }
1902 }
1903 if (view->inverted)
1904 {
1905 viewAngle += 180.; // FIXME: Check
1906 }
1907
1908 Options::setErectObserverCorrection(erectObserverCorrection);
1909 Options::setSkyRotation(dms::reduce(viewAngle));
1910 if (!std::isnan(view->fov))
1911 {
1912 Options::setZoomFactor(map()->width() / (3 * view->fov * dms::DegToRad));
1913 }
1914 repopulateOrientation(); // Update the menus
1915 qCDebug(KSTARS) << "Alt/Az: " << Options::useAltAz()
1916 << "Mirror: " << Options::mirrorSkyMap()
1917 << "Rotation: " << Options::skyRotation()
1918 << "Erect Obs: " << Options::erectObserverCorrection()
1919 << "FOV: " << view->fov;
1920 actionCollection()->action(QString("view:%1").arg(viewName))->setChecked(true);
1921 map()->forceUpdate();
1922}
1923
1924void KStars::slotHIPSSource()
1925{
1926 QAction *selectedAction = qobject_cast<QAction *>(sender());
1927 Q_ASSERT(selectedAction != nullptr);
1928
1929 QString selectedSource = selectedAction->text().remove('&');
1930
1931 // selectedSource could be translated, while we need to send only Latin "None"
1932 // to Hips manager.
1933 if (selectedSource == i18n("None"))
1934 HIPSManager::Instance()->setCurrentSource("None");
1935 else
1936 HIPSManager::Instance()->setCurrentSource(selectedSource);
1937
1938 map()->forceUpdate();
1939}
1940
1941void KStars::slotEditViews()
1942{
1943 QPointer<ViewsDialog> viewsDialog = new ViewsDialog(this);
1944 if (viewsDialog->exec() == QDialog::Accepted)
1945 {
1948 }
1949 delete viewsDialog;
1950}
1951
1952void KStars::slotFOVEdit()
1953{
1954 QPointer<FOVDialog> fovdlg = new FOVDialog(this);
1955 if (fovdlg->exec() == QDialog::Accepted)
1956 {
1958 repopulateFOV();
1959 }
1960 delete fovdlg;
1961}
1962
1963void KStars::slotObsList()
1964{
1965 m_KStarsData->observingList()->show();
1966}
1967
1968void KStars::slotEquipmentWriter()
1969{
1970 QPointer<EquipmentWriter> equipmentdlg = new EquipmentWriter();
1971 equipmentdlg->loadEquipment();
1972 equipmentdlg->exec();
1973 delete equipmentdlg;
1974}
1975
1976void KStars::slotObserverManager()
1977{
1978 QPointer<ObserverAdd> m_observerAdd = new ObserverAdd();
1979 m_observerAdd->exec();
1980 delete m_observerAdd;
1981}
1982
1983void KStars::slotHorizonManager()
1984{
1985 if (!m_HorizonManager)
1986 {
1987 m_HorizonManager = new HorizonManager(this);
1988 connect(m_SkyMap, SIGNAL(positionClicked(SkyPoint *)), m_HorizonManager,
1989 SLOT(addSkyPoint(SkyPoint *)));
1990 }
1991
1992 m_HorizonManager->show();
1993}
1994
1995void KStars::slotEyepieceView(SkyPoint *sp, const QString &imagePath)
1996{
1997 if (!m_EyepieceView)
1998 m_EyepieceView = new EyepieceField(this);
1999
2000 // FIXME: Move FOV choice into the Eyepiece View tool itself.
2001 bool ok = true;
2002 const FOV *fov = nullptr;
2003 if (!data()->getAvailableFOVs().isEmpty())
2004 {
2005 // Ask the user to choose from a list of available FOVs.
2006 //int index;
2007 const FOV *f;
2008 QMap<QString, const FOV *> nameToFovMap;
2009 foreach (f, data()->getAvailableFOVs())
2010 {
2011 nameToFovMap.insert(f->name(), f);
2012 }
2013 nameToFovMap.insert(i18n("Attempt to determine from image"), nullptr);
2014 fov = nameToFovMap[QInputDialog::getItem(
2015 this, i18n("Eyepiece View: Choose a field-of-view"),
2016 i18n("FOV to render eyepiece view for:"), nameToFovMap.keys(), 0, false,
2017 &ok)];
2018 }
2019 if (ok)
2020 m_EyepieceView->showEyepieceField(sp, fov, imagePath);
2021}
2022
2023void KStars::slotExecute()
2024{
2025 KStarsData::Instance()->executeSession()->init();
2026 KStarsData::Instance()->executeSession()->show();
2027}
2028
2029void KStars::slotPolarisHourAngle()
2030{
2031 QPointer<PolarisHourAngle> pHourAngle = new PolarisHourAngle(this);
2032 pHourAngle->exec();
2033}
2034
2035// Toggle to and from full screen mode
2036void KStars::slotFullScreen()
2037{
2039 {
2041 ~Qt::WindowFullScreen); // reset
2042 }
2043 else
2044 {
2046 Qt::WindowFullScreen); // set
2047 }
2048}
2049
2050// Toggle showing terrain on the SkyMap.
2051void KStars::slotTerrain()
2052{
2053 Options::setShowTerrain(!Options::showTerrain());
2054 actionCollection()->action("toggle_terrain")
2055 ->setText(Options::showTerrain() ? i18n("Hide Terrain") : i18n("Show Terrain"));
2056 opterrain->syncOptions();
2058}
2059
2060// Toggle showing image overlays on the SkyMap.
2061void KStars::slotImageOverlays()
2062{
2063 Options::setShowImageOverlays(!Options::showImageOverlays());
2064 actionCollection()->action("toggle_image_overlays")
2065 ->setText(Options::showImageOverlays() ? i18n("Hide Image Overlays") : i18n("Show Image Overlays"));
2066 opsImageOverlay->syncOptions();
2068}
2069
2071{
2072 //Exclude object with temporary trail
2073 SkyObject *exOb(nullptr);
2074 if (map()->focusObject() && map()->focusObject()->isSolarSystem() &&
2075 data()->temporaryTrail)
2076 {
2077 exOb = map()->focusObject();
2078 }
2079
2081
2082 map()->forceUpdate();
2083}
2084
2085//toggle display of GUI Items on/off
2086void KStars::slotShowGUIItem(bool show)
2087{
2088 //Toolbars
2089 if (sender() == actionCollection()->action("show_statusBar"))
2090 {
2091 Options::setShowStatusBar(show);
2093 }
2094
2095 if (sender() == actionCollection()->action("show_sbAzAlt"))
2096 {
2097 Options::setShowAltAzField(show);
2098 AltAzField.setHidden(!show);
2099 }
2100
2101 if (sender() == actionCollection()->action("show_sbRADec"))
2102 {
2103 Options::setShowRADecField(show);
2104 RADecField.setHidden(!show);
2105 }
2106
2107 if (sender() == actionCollection()->action("show_sbJ2000RADec"))
2108 {
2109 Options::setShowJ2000RADecField(show);
2110 J2000RADecField.setHidden(!show);
2111 }
2112}
2113void KStars::addColorMenuItem(QString name, const QString &actionName)
2114{
2115 KToggleAction *kta = actionCollection()->add<KToggleAction>(actionName);
2116 const QString filename = QString(actionName).mid(3) + ".colors";
2117 kta->setText(name);
2118 kta->setObjectName(filename);
2119 kta->setActionGroup(cschemeGroup);
2120
2121 colorActionMenu->addAction(kta);
2122
2124 if (actionName.mid(3) ==
2125 cg.readEntry("ColorSchemeFile", "moonless-night.colors").remove(".colors"))
2126 {
2127 kta->setChecked(true);
2128 }
2129
2130 //use mid(3) to exclude the leading "cs_" prefix from the action name
2131 data()->add_color_scheme(filename, name.replace("&", ""));
2132 connect(kta, SIGNAL(toggled(bool)), this, SLOT(slotColorScheme()));
2133}
2134
2136{
2137 qCDebug(KSTARS) << "removing " << actionName;
2138 colorActionMenu->removeAction(actionCollection()->action(actionName));
2139}
2140
2141void KStars::slotAboutToQuit()
2142{
2143 if (m_SkyMap == nullptr)
2144 return;
2145
2146#ifdef HAVE_INDI
2147 DriverManager::Instance()->disconnectClients();
2148 INDIListener::Instance()->disconnect();
2149 GUIManager::Instance()->disconnect();
2150#endif
2151
2152 // Delete skymap. This required to run destructors and save
2153 // current state in the option.
2154 delete m_SkyMap;
2155 m_SkyMap = nullptr;
2156
2157 //Store Window geometry in Options object
2158 Options::setWindowWidth(width());
2159 Options::setWindowHeight(height());
2160
2161 //explicitly save the colorscheme data to the config file
2163
2164 //synch the config file with the Config object
2165 writeConfig();
2166
2167 //Terminate Child Processes if on OS X
2168#ifdef Q_OS_MACOS
2169 QProcess *quit = new QProcess(this);
2170 quit->start("killall kdeinit5");
2171 quit->waitForFinished(1000);
2172 quit->start("killall klauncher");
2173 quit->waitForFinished(1000);
2174 quit->start("killall kioslave");
2175 quit->waitForFinished(1000);
2176 quit->start("killall kio_http_cache_cleaner");
2177 quit->waitForFinished(1000);
2178 delete quit;
2179#endif
2180}
2181
2183{
2184 if (Options::showAltAzField())
2185 {
2186 dms a = p->alt();
2187 if (Options::useAltAz())
2188 a = p->altRefracted();
2189 QString s =
2190 QString("%1, %2").arg(p->az().toDMSString(true), //true: force +/- symbol
2191 a.toDMSString(true)); //true: force +/- symbol
2192 //statusBar()->changeItem( s, 1 );
2193 AltAzField.setText(s);
2194 }
2195 if (Options::showRADecField())
2196 {
2197 KStarsDateTime lastUpdate;
2198 lastUpdate.setDJD(KStarsData::Instance()->updateNum()->getJD());
2199 QString sEpoch = QString::number(lastUpdate.epoch(), 'f', 1);
2200 QString s = QString("%1, %2 (J%3)")
2201 .arg(p->ra().toHMSString(), p->dec().toDMSString(true),
2202 sEpoch); //true: force +/- symbol
2203 //statusBar()->changeItem( s, 2 );
2204 RADecField.setText(s);
2205 }
2206
2207 if (Options::showJ2000RADecField())
2208 {
2209 SkyPoint p0;
2210 //p0 = p->deprecess(KStarsData::Instance()->updateNum()); // deprecess to update RA0/Dec0 from RA/Dec
2211 p0 = p->catalogueCoord(KStarsData::Instance()->updateNum()->julianDay());
2212 QString s = QString("%1, %2 (J2000)")
2213 .arg(p0.ra().toHMSString(),
2214 p0.dec().toDMSString(true)); //true: force +/- symbol
2215 //statusBar()->changeItem( s, 2 );
2216 J2000RADecField.setText(s);
2217 }
2218}
2219
2220void KStars::slotUpdateComets(bool isAutoUpdate)
2221{
2222 data()->skyComposite()->solarSystemComposite()->cometsComponent()->updateDataFile(
2223 isAutoUpdate);
2224}
2225
2226void KStars::slotUpdateAsteroids(bool isAutoUpdate)
2227{
2228 data()->skyComposite()->solarSystemComposite()->asteroidsComponent()->updateDataFile(
2229 isAutoUpdate);
2230}
2231
2232void KStars::slotUpdateSupernovae()
2233{
2234 data()->skyComposite()->supernovaeComponent()->slotTriggerDataFileUpdate();
2235}
2236
2237void KStars::slotUpdateSatellites()
2238{
2239 data()->skyComposite()->satellites()->updateTLEs();
2240}
2241
2242void KStars::slotConfigureNotifications()
2243{
2244#ifdef HAVE_NOTIFYCONFIG
2246#endif
2247}
2249{
2250 auto *ui = new CatalogsDBUI{ this, CatalogsDB::dso_db_path() };
2251 ui->show();
2252 connect(ui, &QDialog::finished, this, [&](const auto)
2253 {
2254 KStars::Instance()->data()->skyComposite()->catalogsComponent()->dropCache();
2255 });
2256}
the Altitude vs.
Definition altvstime.h:41
This is the base class for the KStars astronomical calculator.
Definition astrocalc.h:26
void dropCache()
Clear the internal cache and effectively reload all objects from the database.
A simple UI to manage downloaded and custom Catalogs.
Manages the catalog database and provides an interface to provide an interface to query and modify th...
Definition catalogsdb.h:183
void saveToConfig()
Save color-scheme data to the Config object.
Export sky image dialog.
Renders the view through the eyepiece of various telescope types.
void showEyepieceField(SkyPoint *sp, FOV const *const fov=nullptr, const QString &imagePath=QString())
Show the eyepiece field dialog.
FOVDialog is dialog to select a Field-of-View indicator (or create a new one)
Definition fovdialog.h:38
static bool save()
Write list of FOVs to "fov.dat".
Definition fov.cpp:49
A simple class encapsulating a Field-of-View symbol.
Definition fov.h:28
Flag manager Dialog box to add and remove flags.
Definition flagmanager.h:36
A small dialog for setting the focus coordinates manually.
Definition focusdialog.h:33
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
double TZ0() const
TimeZoneRule * tzrule()
Manages adding/removing and editing regions and points associated with user-customized artificial hor...
Display the positions of Jupiter's moons as a function of time.
Definition jmoontool.h:24
Q_INVOKABLE QAction * action(const QString &name) const
ActionType * add(const QString &name, const QObject *receiver=nullptr, const char *member=nullptr)
void addAction(QAction *action)
KConfigGroup group(const QString &group)
static bool showDialog(const QString &name)
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
static KConfigDialog * exists(const QString &name)
QString readEntry(const char *key, const char *aDefault=nullptr) const
QString toString() const
KLocalizedString subs(const KLocalizedString &a, int fieldWidth=0, QChar fillChar=QLatin1Char(' ')) const
static KNotifyConfigWidget * configure(QWidget *parent=nullptr, const QString &appname=QString())
void setIcon(const QIcon &icon)
A subclass of TrailObject that provides additional information needed for most solar system objects.
The Startup Wizard will be automatically opened when KStars runs for the first time.
Definition kswizard.h:71
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void setNextDSTChange(const KStarsDateTime &dt)
Set the NextDSTChange member.
Definition kstarsdata.h:110
void setLocation(const GeoLocation &l)
Set the GeoLocation according to the argument.
void changeDateTime(const KStarsDateTime &newDate)
Change the current simulation date/time to the KStarsDateTime argument.
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
ColorScheme * colorScheme()
Definition kstarsdata.h:172
void syncLST()
Sync the LST with the simulation clock.
void syncFOV()
Synchronize list of visible FOVs and list of selected FOVs in Options.
Q_INVOKABLE SimClock * clock()
Definition kstarsdata.h:218
GeoLocation * geo()
Definition kstarsdata.h:230
void add_color_scheme(const QString &filename, const QString &name)
Register a color scheme with filename and name.
Definition kstarsdata.h:205
SkyMapComposite * skyComposite()
Definition kstarsdata.h:166
void setSnapNextFocus(bool b=true)
Disable or re-enable the slewing animation for the next Focus change.
Definition kstarsdata.h:283
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
void setDJD(long double jd)
Assign the static_cast<long double> Julian Day value, which includes the time of day encoded in the f...
double epoch() const
This is (approximately) the year expressed as a floating-point value.
static KStarsDateTime currentDateTimeUtc()
void slotSetZoom()
action slot: Allow user to specify a field-of-view angle for the display window in degrees,...
void repopulateViews()
Load Views and repopulate menu.
SkyMap * map() const
Definition kstars.h:141
void applyConfig(bool doApplyFocus=true)
Apply config options throughout the program.
Definition kstars.cpp:311
static KStars * Instance()
Definition kstars.h:123
void slotEyepieceView(SkyPoint *sp, const QString &imagePath=QString())
Show the eyepiece view tool.
void slotToggleWIView()
action slot: toggle What's Interesting window
void slotDSOCatalogGUI()
Show the DSO Catalog Management GUI.
void syncOps()
Sync Options to GUI, if any.
void slotApplyWIConfigChanges()
Apply new settings for WI.
void slotWizard()
action slot: open KStars startup wizard
void slotTrack()
action slot: Toggle whether kstars is tracking current position
void addColorMenuItem(QString name, const QString &actionName)
Add an item to the color-scheme action manu.
KStarsData * data() const
Definition kstars.h:135
void slotGeoLocator()
action slot: open dialog for selecting a new geographic location
void slotSetDomeEnabled(bool enable)
slotSetDomeEnabled call when dome comes online or goes offline.
Q_SCRIPTABLE Q_NOREPLY void writeConfig()
DBUS interface function.
void slotFlagManager()
action slot: open Flag Manager
void slotSetTelescopeEnabled(bool enable)
slotSetTelescopeEnabled call when telescope comes online or goes offline.
Q_SCRIPTABLE Q_NOREPLY void loadColorScheme(const QString &name)
DBUS interface function.
void slotWISettings()
action slot: open What's Interesting settings window
Q_SCRIPTABLE Q_NOREPLY void printImage(bool usePrintDialog, bool useChartColors)
DBUS interface function.
void slotClearAllTrails()
Remove all trails which may have been added to solar system bodies.
void removeColorMenuItem(const QString &actionName)
Remove an item from the color-scheme action manu.
void updateTime(const bool automaticDSTchange=true)
Update time-dependent data and (possibly) repaint the sky map.
Definition kstars.cpp:592
static bool Closing
Set to true when the application is being closed.
Definition kstars.h:859
void slotShowPositionBar(SkyPoint *)
Display position in the status bar.
void slotSetTimeToNow()
action slot: sync kstars clock to system time
void slotApplyConfigChanges()
Apply new settings and redraw skymap.
void slotZoomChanged()
Called when zoom level is changed.
virtual KActionCollection * actionCollection() const
virtual QAction * action(const QDomElement &element) const
Dialog for changing the geographic location of the observer.
Dialog to add new observers.
Definition observeradd.h:19
The Advanced Tab of the Options window.
Definition opsadvanced.h:27
The Catalog page for the Options window.
Definition opscatalog.h:28
The Colors page allows the user to adjust all of the colors used to display the night sky.
Definition opscolors.h:32
The Developer Tab of the Options window.
Enables the user to set remote connection devices and options in addition to online and offline astro...
Definition opsekos.h:22
The FITS Tab of the Options window.
Definition opsfits.h:32
The guide page enables to user to select to turn on and off guide overlays such as constellation line...
Definition opsguides.h:19
Enables the user to change several INDI options including default ports for common devices,...
Definition opsindi.h:23
The terrain page enables to user to manage the options for image overlays.
The Satellites Tab of the Options window.
The Solar System page for the Options window.
The Supernovae Tab of the Options window.
The terrain page enables to user to manage the options for the terrain overlay.
Definition opsterrain.h:20
Display an overhead view of the solar system.
Class representing Printing Wizard for KStars printed documents (currently only finder charts).
double fov() const
Return the FOV of this projection.
Definition projector.cpp:88
void updateTLEs()
Download new TLE files.
A GUI tool for building behavioral DBus scripts for KStars.
void setManualMode(bool on=true)
Sets Manual Mode on/off according to the bool argument.
Definition simclock.cpp:66
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS function to start the SimClock.
Definition simclock.cpp:155
Q_SCRIPTABLE Q_NOREPLY void stop()
DBUS function to stop the SimClock.
Definition simclock.cpp:136
void manualTick(bool force=false, bool backward=false)
Equivalent of tick() for manual mode.
Definition simclock.cpp:112
Draws Rise/Set/Transit curves for major solar system planets for any calendar year.
Definition skycalendar.h:30
static bool save()
Commit the list of views to the database.
static std::optional< SkyMapView > viewNamed(const QString &name)
Get the view with the given name.
void setZoomFactor(double factor)
@ Set zoom factor.
Definition skymap.cpp:1167
SkyPoint * focus()
Retrieve the Focus point; the position on the sky at the center of the skymap.
Definition skymap.h:123
void setupProjector()
Call to set up the projector before a draw cycle.
Definition skymap.cpp:1246
void setClickedPoint(const SkyPoint *f)
Set the ClickedPoint to the skypoint given as an argument.
Definition skymap.cpp:1012
void setClickedObject(SkyObject *o)
Set the ClickedObject pointer to the argument.
Definition skymap.cpp:366
const Projector * projector() const
Get the current projector.
Definition skymap.h:300
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition skymap.cpp:1177
SkyPoint * mousePoint()
Retrieve the mouse pointer position.
Definition skymap.h:227
void setFocusAltAz(const dms &alt, const dms &az)
sets the focus point of the sky map, using its alt/az coordinates
Definition skymap.cpp:972
void setDestination(const SkyPoint &f)
sets the destination point of the sky map.
Definition skymap.cpp:984
void forceUpdateNow()
Convenience function; simply calls forceUpdate(true).
Definition skymap.h:378
void setDestinationAltAz(const dms &alt, const dms &az, bool altIsRefracted)
sets the destination point of the sky map, using its alt/az coordinates.
Definition skymap.cpp:996
void setFocus(SkyPoint *f)
sets the central focus point of the sky map.
Definition skymap.cpp:958
void setFocusObject(SkyObject *o)
Set the FocusObject pointer to the argument.
Definition skymap.cpp:371
void slotCenter()
Center the display at the point ClickedPoint.
Definition skymap.cpp:380
void setFocusPoint(SkyPoint *f)
set the FocusPoint; the position that is to be the next Destination.
Definition skymap.h:204
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
Definition skymap.h:262
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
void setDec(dms d)
Sets Dec, the current Declination.
Definition skypoint.h:169
const CachingDms & ra() const
Definition skypoint.h:263
dms altRefracted() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
const dms & az() const
Definition skypoint.h:275
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition skypoint.h:194
const dms & alt() const
Definition skypoint.h:281
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition skypoint.cpp:143
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition skypoint.cpp:710
void slotTriggerDataFileUpdate()
This initiates updating of the data file.
static void discoverTextureDirs()
Clear the cache and discover the directories to load textures from.
A class for adjusting the Time and Date.
Definition timedialog.h:38
KStarsDateTime nextDSTChange() const
void reset_with_ltime(KStarsDateTime &ltime, const double TZoffset, const bool time_runs_forward, const bool automaticDSTchange=false)
Recalculate next dst change and if DST is active by a given local time with timezone offset and time ...
bool hasTrail() const
Definition trailobject.h:36
void clearTrail()
clear the Trail
void addToTrail(const QString &label=QString())
adds a point to the planet's trail
static void clearTrailsExcept(SkyObject *o)
Remove trail for all objects but one which is passed as parameter.
ViewsDialog is dialog to select a Sky Map View (or create a new one)
Definition viewsdialog.h:49
User interface for "Equipment Type and Parameters" page in WI settings dialog.
void populateScopeListWidget()
Populates scope list widget in UI with list of telescopes from KStars userdb.
void setAperture()
Set aperture to use.
User interface for "Light Pollution Settings" page in WI settings dialog This class deals with light ...
Manages the QML user interface for What's Interesting.
Definition wiview.h:33
void onReloadIconClicked()
public slot - Reload list of visible sky-objects.
Definition wiview.cpp:393
void updateObservingConditions()
Definition wiview.cpp:215
What's up tonight dialog is a window which lists all sky objects that will be visible during the next...
Definition wutdialog.h:40
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition dms.cpp:251
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:287
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:378
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...)
KLocalizedString KI18N_EXPORT ki18nc(const char *context, const char *text)
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT SimpleJob * mount(bool ro, const QByteArray &fstype, const QString &dev, const QString &point, JobFlags flags=DefaultFlags)
GeoCoordinates geo(const QVariant &location)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
QString name(StandardAction id)
KGuiItem overwrite()
KGuiItem cont()
KGuiItem cancel()
void clicked(bool checked)
bool isChecked() const const
void setEnabled(bool)
void setIcon(const QIcon &icon)
void setActionGroup(QActionGroup *group)
void setDisabled(bool b)
void setText(const QString &text)
QList< QAction * > actions() const const
void setEnabled(bool)
QString applicationDirPath()
void finished(int result)
QString homePath()
QString path() const const
void setAllowedAreas(Qt::DockWidgetAreas areas)
void setWidget(QWidget *widget)
bool exists() const const
QUrl getOpenFileUrl(QWidget *parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, Options options, const QStringList &supportedSchemes)
QUrl getSaveFileUrl(QWidget *parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, Options options, const QStringList &supportedSchemes)
QDir dir() const const
QIcon fromTheme(const QString &name)
double getDouble(QWidget *parent, const QString &title, const QString &label, double value, double min, double max, int decimals, bool *ok, Qt::WindowFlags flags, double step)
QString getItem(QWidget *parent, const QString &title, const QString &label, const QStringList &items, int current, bool editable, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
void setText(const QString &)
void append(QList< T > &&value)
void removeAt(qsizetype i)
void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
QStatusBar * statusBar() const const
iterator insert(const Key &key, const T &value)
QList< Key > keys() const const
StandardButton critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
T findChild(const QString &name, Qt::FindChildOptions options) const const
T qobject_cast(QObject *object)
QObject * sender() const const
void setObjectName(QAnyStringView name)
void start(OpenMode mode)
QProcess::ProcessState state() const const
bool waitForFinished(int msecs)
bool waitForStarted(int msecs)
QString findExecutable(const QString &executableName, const QStringList &paths)
void showMessage(const QString &message, int timeout)
QString arg(Args &&... args) const const
const QChar at(qsizetype position) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString left(qsizetype n) const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
qsizetype indexOf(const QRegularExpression &re, qsizetype from) const const
RightDockWidgetArea
WA_DeleteOnClose
WindowFullScreen
QString fileName(ComponentFormattingOptions options) const const
bool isEmpty() const const
bool isLocalFile() const const
bool isValid() const const
QString toLocalFile() const const
QWidget * topLevelWidget() const const
void activateWindow()
QWidget * createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags)
bool isFullScreen() const const
void hide()
void setMinimumWidth(int minw)
QWidget * parentWidget() const const
void raise()
void setAttribute(Qt::WidgetAttribute attribute, bool on)
void setDisabled(bool disable)
void setHidden(bool hidden)
void setWindowState(Qt::WindowStates windowState)
void show()
void showNormal()
void setStyleSheet(const QString &styleSheet)
bool isVisible() const const
Qt::WindowStates windowState() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:15:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.