Kstars

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

KDE's Doxygen guidelines are available online.