File indexing completed on 2024-04-21 03:45:04

0001 /*
0002     SPDX-FileCopyrightText: 2002 Jason Harris <jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kstars.h"
0008 
0009 #include "fov.h"
0010 #include "kspaths.h"
0011 #include "kstarsdata.h"
0012 #include "kstars_debug.h"
0013 #include "Options.h"
0014 #include "skymap.h"
0015 #include "texturemanager.h"
0016 #include "projections/projector.h"
0017 #include "skycomponents/skymapcomposite.h"
0018 #include "skyobjects/ksplanetbase.h"
0019 #include "widgets/timespinbox.h"
0020 #include "widgets/timestepbox.h"
0021 #include "widgets/timeunitbox.h"
0022 #include "hips/hipsmanager.h"
0023 #include "auxiliary/thememanager.h"
0024 
0025 #ifdef HAVE_INDI
0026 #include "indi/drivermanager.h"
0027 #include "indi/guimanager.h"
0028 #include "ekos/manager.h"
0029 #endif
0030 
0031 #include <KActionCollection>
0032 #include <KActionMenu>
0033 #include <KTipDialog>
0034 #include <KToggleAction>
0035 #include <KToolBar>
0036 
0037 #include <QMenu>
0038 #include <QStatusBar>
0039 
0040 //This file contains functions that kstars calls at startup (except constructors).
0041 //These functions are declared in kstars.h
0042 
0043 namespace
0044 {
0045 // A lot of QAction is defined there. In order to decrease amount
0046 // of boilerplate code a trick with << operator overloading is used.
0047 // This makes code more concise and readable.
0048 //
0049 // When data type could not used directly. Either because of
0050 // overloading rules or because one data type have different
0051 // semantics its wrapped into struct.
0052 //
0053 // Downside is unfamiliar syntax and really unhelpful error
0054 // messages due to general abuse of << overloading
0055 
0056 // Set QAction text
0057 QAction *operator<<(QAction *ka, QString text)
0058 {
0059     ka->setText(text);
0060     return ka;
0061 }
0062 // Set icon for QAction
0063 QAction *operator<<(QAction *ka, const QIcon &icon)
0064 {
0065     ka->setIcon(icon);
0066     return ka;
0067 }
0068 // Set keyboard shortcut
0069 QAction *operator<<(QAction *ka, const QKeySequence sh)
0070 {
0071     KStars::Instance()->actionCollection()->setDefaultShortcut(ka, sh);
0072     //ka->setShortcut(sh);
0073     return ka;
0074 }
0075 
0076 // Add action to group. AddToGroup struct acts as newtype wrapper
0077 // in order to allow overloading.
0078 struct AddToGroup
0079 {
0080     QActionGroup *grp;
0081     AddToGroup(QActionGroup *g) : grp(g) {}
0082 };
0083 QAction *operator<<(QAction *ka, AddToGroup g)
0084 {
0085     g.grp->addAction(ka);
0086     return ka;
0087 }
0088 
0089 // Set checked property. Checked is newtype wrapper.
0090 struct Checked
0091 {
0092     bool flag;
0093     Checked(bool f) : flag(f) {}
0094 };
0095 QAction *operator<<(QAction *ka, Checked chk)
0096 {
0097     ka->setCheckable(true);
0098     ka->setChecked(chk.flag);
0099     return ka;
0100 }
0101 
0102 // Set tool tip. ToolTip is used as newtype wrapper.
0103 struct ToolTip
0104 {
0105     QString tip;
0106     ToolTip(QString msg) : tip(msg) {}
0107 };
0108 QAction *operator<<(QAction *ka, const ToolTip &tool)
0109 {
0110     ka->setToolTip(tool.tip);
0111     return ka;
0112 }
0113 
0114 // Create new KToggleAction and connect slot to toggled(bool) signal
0115 QAction *newToggleAction(KActionCollection *col, QString name, QString text, QObject *receiver, const char *member)
0116 {
0117     QAction *ka = col->add<KToggleAction>(name) << text;
0118     QObject::connect(ka, SIGNAL(toggled(bool)), receiver, member);
0119     return ka;
0120 }
0121 }
0122 
0123 // Resource file override - used by UI tests
0124 QString KStars::m_KStarsUIResource = "kstarsui.rc";
0125 bool KStars::setResourceFile(QString const rc)
0126 {
0127     if (QFile(rc).exists())
0128     {
0129         m_KStarsUIResource = rc;
0130         return true;
0131     }
0132     else return false;
0133 }
0134 
0135 
0136 void KStars::initActions()
0137 {
0138     // Check if we have this specific Breeze icon. If not, try to set the theme search path and if appropriate, the icon theme rcc file
0139     // in each OS
0140     if (!QIcon::hasThemeIcon(QLatin1String("kstars_flag")))
0141         KSTheme::Manager::instance()->setIconTheme(KSTheme::Manager::BREEZE_DARK_THEME);
0142 
0143     QAction *ka;
0144 
0145     // ==== File menu ================
0146     ka = new QAction(QIcon::fromTheme("favorites"), i18n("Download New Data..."), this);
0147     connect(ka, &QAction::triggered, this, &KStars::slotDownload);
0148     actionCollection()->setDefaultShortcut(ka, QKeySequence(Qt::CTRL + Qt::Key_N));
0149     ka->setWhatsThis(i18n("Downloads new data"));
0150     ka->setToolTip(ka->whatsThis());
0151     ka->setStatusTip(ka->whatsThis());
0152     actionCollection()->addAction(QStringLiteral("get_data"), ka);
0153 
0154 #ifdef HAVE_CFITSIO
0155     actionCollection()->addAction("open_file", this, SLOT(slotOpenFITS()))
0156             << i18n("Open Image(s)...") << QIcon::fromTheme("document-open")
0157             << QKeySequence(Qt::CTRL + Qt::Key_O);
0158 
0159     actionCollection()->addAction("blink_directory", this, SLOT(slotBlink()))
0160             << i18n("Open/Blink Directory") << QIcon::fromTheme("folder-open")
0161             << QKeySequence(Qt::CTRL + Qt::Key_O + Qt::AltModifier);
0162 
0163 #endif
0164     actionCollection()->addAction("export_image", this, SLOT(slotExportImage()))
0165             << i18n("&Save Sky Image...")
0166             << QIcon::fromTheme("document-export-image");
0167 
0168     // 2017-09-17 Jasem: FIXME! Scripting does not work properly under non UNIX systems.
0169     // It must be updated to use DBus session bus from Qt (like scheduler)
0170 #ifndef Q_OS_WIN
0171     actionCollection()->addAction("run_script", this, SLOT(slotRunScript()))
0172             << i18n("&Run Script...") << QIcon::fromTheme("system-run")
0173             << QKeySequence(Qt::CTRL + Qt::Key_R);
0174 #endif
0175     actionCollection()->addAction("printing_wizard", this, SLOT(slotPrintingWizard()))
0176             << i18nc("start Printing Wizard", "Printing &Wizard...");
0177     ka = actionCollection()->addAction(KStandardAction::Print, "print", this, SLOT(slotPrint()));
0178     ka->setIcon(QIcon::fromTheme("document-print"));
0179     //actionCollection()->addAction( KStandardAction::Quit,  "quit",  this, SLOT(close) );
0180     ka = actionCollection()->addAction(KStandardAction::Quit, "quit", qApp, SLOT(closeAllWindows()));
0181     ka->setIcon(QIcon::fromTheme("application-exit"));
0182 
0183     // ==== Time Menu ================
0184     actionCollection()->addAction("time_to_now", this, SLOT(slotSetTimeToNow()))
0185             << i18n("Set Time to &Now") << QKeySequence(Qt::CTRL + Qt::Key_E)
0186             << QIcon::fromTheme("clock");
0187 
0188     actionCollection()->addAction("time_dialog", this, SLOT(slotSetTime()))
0189             << i18nc("set Clock to New Time", "&Set Time...") << QKeySequence(Qt::CTRL + Qt::Key_S)
0190             << QIcon::fromTheme("clock");
0191 
0192     ka = actionCollection()->add<KToggleAction>("clock_startstop")
0193          << i18n("Stop &Clock")
0194          << QIcon::fromTheme("media-playback-pause");
0195     if (!StartClockRunning)
0196         ka->toggle();
0197     QObject::connect(ka, SIGNAL(triggered()), this, SLOT(slotToggleTimer()));
0198 
0199     // If we are started in --paused state make sure the icon reflects that now
0200     if (StartClockRunning == false)
0201     {
0202         QAction *a = actionCollection()->action("clock_startstop");
0203         if (a)
0204             a->setIcon(QIcon::fromTheme("run-build-install-root"));
0205     }
0206 
0207     QObject::connect(data()->clock(), &SimClock::clockToggled, [ = ](bool toggled)
0208     {
0209         QAction *a = actionCollection()->action("clock_startstop");
0210         if (a)
0211         {
0212             a->setChecked(toggled);
0213             // Many users forget to unpause KStars, so we are using run-build-install-root icon which is red
0214             // and stands out from the rest of the icons so users are aware when KStars is paused visually
0215             a->setIcon(toggled ? QIcon::fromTheme("run-build-install-root") : QIcon::fromTheme("media-playback-pause"));
0216             a->setToolTip(toggled ? i18n("Resume Clock") : i18n("Stop Clock"));
0217         }
0218     });
0219     //UpdateTime() if clock is stopped (so hidden objects get drawn)
0220     QObject::connect(data()->clock(), SIGNAL(clockToggled(bool)), this, SLOT(updateTime()));
0221     actionCollection()->addAction("time_step_forward", this, SLOT(slotStepForward()))
0222             << i18n("Advance One Step Forward in Time")
0223             << QIcon::fromTheme("media-skip-forward")
0224             << QKeySequence(Qt::Key_Greater);
0225     actionCollection()->addAction("time_step_backward", this, SLOT(slotStepBackward()))
0226             << i18n("Advance One Step Backward in Time")
0227             << QIcon::fromTheme("media-skip-backward")
0228             << QKeySequence(Qt::Key_Less);
0229 
0230     // ==== Pointing Menu ================
0231     actionCollection()->addAction("zenith", this, SLOT(slotPointFocus())) << i18n("&Zenith") << QKeySequence("Z");
0232     actionCollection()->addAction("north", this, SLOT(slotPointFocus())) << i18n("&North") << QKeySequence("N");
0233     actionCollection()->addAction("east", this, SLOT(slotPointFocus())) << i18n("&East") << QKeySequence("E");
0234     actionCollection()->addAction("south", this, SLOT(slotPointFocus())) << i18n("&South") << QKeySequence("S");
0235     actionCollection()->addAction("west", this, SLOT(slotPointFocus())) << i18n("&West") << QKeySequence("W");
0236 
0237     actionCollection()->addAction("find_object", this, SLOT(slotFind()))
0238             << i18n("&Find Object...") << QIcon::fromTheme("edit-find")
0239             << QKeySequence(Qt::CTRL + Qt::Key_F);
0240     actionCollection()->addAction("track_object", this, SLOT(slotTrack()))
0241             << i18n("Engage &Tracking")
0242             << QIcon::fromTheme("object-locked")
0243             << QKeySequence(Qt::CTRL + Qt::Key_T);
0244     actionCollection()->addAction("manual_focus", this, SLOT(slotManualFocus()))
0245             << i18n("Set Coordinates &Manually...") << QKeySequence(Qt::CTRL + Qt::Key_M);
0246 
0247     QAction *action;
0248 
0249     // ==== View Menu ================
0250     action = actionCollection()->addAction(KStandardAction::ZoomIn, "zoom_in", map(), SLOT(slotZoomIn()));
0251     action->setIcon(QIcon::fromTheme("zoom-in"));
0252 
0253     action = actionCollection()->addAction(KStandardAction::ZoomOut, "zoom_out", map(), SLOT(slotZoomOut()));
0254     action->setIcon(QIcon::fromTheme("zoom-out"));
0255 
0256     actionCollection()->addAction("zoom_default", map(), SLOT(slotZoomDefault()))
0257             << i18n("&Default Zoom") << QIcon::fromTheme("zoom-fit-best")
0258             << QKeySequence(Qt::CTRL + Qt::Key_Z);
0259     actionCollection()->addAction("zoom_set", this, SLOT(slotSetZoom()))
0260             << i18n("&Zoom to Angular Size...")
0261             << QIcon::fromTheme("zoom-original")
0262             << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z);
0263 
0264     action = actionCollection()->addAction(KStandardAction::FullScreen, this, SLOT(slotFullScreen()));
0265     action->setIcon(QIcon::fromTheme("view-fullscreen"));
0266 
0267     actionCollection()->addAction("coordsys", this, SLOT(slotCoordSys()))
0268             << (Options::useAltAz() ? i18n("Switch to Star Globe View (Equatorial &Coordinates)") :
0269                 i18n("Switch to Horizontal View (Horizontal &Coordinates)"))
0270             << QKeySequence("Space");
0271 
0272     actionCollection()->addAction("toggle_terrain", this, SLOT(slotTerrain()))
0273             << (Options::showTerrain() ? i18n("Hide Terrain") :
0274                 i18n("Show Terrain"))
0275             << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T);
0276 
0277     actionCollection()->addAction("toggle_image_overlays", this, SLOT(slotImageOverlays()))
0278             << (Options::showImageOverlays() ? i18n("Hide Image Overlays") :
0279                 i18n("Show Image Overlays"))
0280             << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O);
0281 
0282     actionCollection()->addAction("project_lambert", this, SLOT(slotMapProjection()))
0283             << i18n("&Lambert Azimuthal Equal-area") << QKeySequence("F5") << AddToGroup(projectionGroup)
0284             << Checked(Options::projection() == Projector::Lambert);
0285     actionCollection()->addAction("project_azequidistant", this, SLOT(slotMapProjection()))
0286             << i18n("&Azimuthal Equidistant") << QKeySequence("F6") << AddToGroup(projectionGroup)
0287             << Checked(Options::projection() == Projector::AzimuthalEquidistant);
0288     actionCollection()->addAction("project_orthographic", this, SLOT(slotMapProjection()))
0289             << i18n("&Orthographic") << QKeySequence("F7") << AddToGroup(projectionGroup)
0290             << Checked(Options::projection() == Projector::Orthographic);
0291     actionCollection()->addAction("project_equirectangular", this, SLOT(slotMapProjection()))
0292             << i18n("&Equirectangular") << QKeySequence("F8") << AddToGroup(projectionGroup)
0293             << Checked(Options::projection() == Projector::Equirectangular);
0294     actionCollection()->addAction("project_stereographic", this, SLOT(slotMapProjection()))
0295             << i18n("&Stereographic") << QKeySequence("F9") << AddToGroup(projectionGroup)
0296             << Checked(Options::projection() == Projector::Stereographic);
0297     actionCollection()->addAction("project_gnomonic", this, SLOT(slotMapProjection()))
0298             << i18n("&Gnomonic") << QKeySequence("F10") << AddToGroup(projectionGroup)
0299             << Checked(Options::projection() == Projector::Gnomonic);
0300 
0301     //Settings Menu:
0302     //Info Boxes option actions
0303     QAction *kaBoxes = actionCollection()->add<KToggleAction>("show_boxes")
0304                        << i18nc("Show the information boxes", "Show &Info Boxes") << Checked(Options::showInfoBoxes());
0305     connect(kaBoxes, SIGNAL(toggled(bool)), map(), SLOT(slotToggleInfoboxes(bool)));
0306     kaBoxes->setChecked(Options::showInfoBoxes());
0307 
0308     ka = actionCollection()->add<KToggleAction>("show_time_box")
0309          << i18nc("Show time-related info box", "Show &Time Box");
0310     connect(kaBoxes, SIGNAL(toggled(bool)), ka, SLOT(setEnabled(bool)));
0311     connect(ka, SIGNAL(toggled(bool)), map(), SLOT(slotToggleTimeBox(bool)));
0312     ka->setChecked(Options::showTimeBox());
0313     ka->setEnabled(Options::showInfoBoxes());
0314 
0315     ka = actionCollection()->add<KToggleAction>("show_focus_box")
0316          << i18nc("Show focus-related info box", "Show &Focus Box");
0317     connect(kaBoxes, SIGNAL(toggled(bool)), ka, SLOT(setEnabled(bool)));
0318     connect(ka, SIGNAL(toggled(bool)), map(), SLOT(slotToggleFocusBox(bool)));
0319     ka->setChecked(Options::showFocusBox());
0320     ka->setEnabled(Options::showInfoBoxes());
0321 
0322     ka = actionCollection()->add<KToggleAction>("show_location_box")
0323          << i18nc("Show location-related info box", "Show &Location Box");
0324     connect(kaBoxes, SIGNAL(toggled(bool)), ka, SLOT(setEnabled(bool)));
0325     connect(ka, SIGNAL(toggled(bool)), map(), SLOT(slotToggleGeoBox(bool)));
0326     ka->setChecked(Options::showGeoBox());
0327     ka->setEnabled(Options::showInfoBoxes());
0328 
0329     //Toolbar options
0330     newToggleAction(actionCollection(), "show_mainToolBar", i18n("Show Main Toolbar"), toolBar("kstarsToolBar"),
0331                     SLOT(setVisible(bool)));
0332     newToggleAction(actionCollection(), "show_viewToolBar", i18n("Show View Toolbar"), toolBar("viewToolBar"),
0333                     SLOT(setVisible(bool)));
0334 
0335     //Statusbar view options
0336     newToggleAction(actionCollection(), "show_statusBar", i18n("Show Statusbar"), this, SLOT(slotShowGUIItem(bool)));
0337     newToggleAction(actionCollection(), "show_sbAzAlt", i18n("Show Az/Alt Field"), this, SLOT(slotShowGUIItem(bool)));
0338     newToggleAction(actionCollection(), "show_sbRADec", i18n("Show RA/Dec Field"), this, SLOT(slotShowGUIItem(bool)));
0339     newToggleAction(actionCollection(), "show_sbJ2000RADec", i18n("Show J2000.0 RA/Dec Field"), this,
0340                     SLOT(slotShowGUIItem(bool)));
0341 
0342 
0343     populateThemes();
0344 
0345     //Color scheme actions.  These are added to the "colorschemes" KActionMenu.
0346     colorActionMenu = actionCollection()->add<KActionMenu>("colorschemes");
0347     colorActionMenu->setText(i18n("C&olor Schemes"));
0348     addColorMenuItem(i18n("&Classic"), "cs_classic");
0349     addColorMenuItem(i18n("&Star Chart"), "cs_chart");
0350     addColorMenuItem(i18n("&Night Vision"), "cs_night");
0351     addColorMenuItem(i18n("&Moonless Night"), "cs_moonless-night");
0352 
0353     //Add any user-defined color schemes:
0354     //determine filename in local user KDE directory tree.
0355     QFile file(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "colors.dat"));
0356     if (file.exists() && file.open(QIODevice::ReadOnly))
0357     {
0358         QTextStream stream(&file);
0359         while (!stream.atEnd())
0360         {
0361             QString line       = stream.readLine();
0362             QString schemeName = line.left(line.indexOf(':'));
0363             QString actionname = "cs_" + line.mid(line.indexOf(':') + 1, line.indexOf('.') - line.indexOf(':') - 1);
0364             addColorMenuItem(i18n(schemeName.toLocal8Bit()), actionname.toLocal8Bit());
0365         }
0366         file.close();
0367     }
0368 
0369     //Add FOV Symbol actions
0370     fovActionMenu = actionCollection()->add<KActionMenu>("fovsymbols");
0371     fovActionMenu->setText(i18n("&FOV Symbols"));
0372     fovActionMenu->setDelayed(false);
0373     fovActionMenu->setIcon(QIcon::fromTheme("crosshairs"));
0374     FOVManager::readFOVs();
0375     repopulateFOV();
0376 
0377     //Add HIPS Sources actions
0378     hipsActionMenu = actionCollection()->add<KActionMenu>("hipssources");
0379     hipsActionMenu->setText(i18n("HiPS All Sky Overlay"));
0380     hipsActionMenu->setDelayed(false);
0381     hipsActionMenu->setIcon(QIcon::fromTheme("view-preview"));
0382     HIPSManager::Instance()->readSources();
0383     repopulateHIPS();
0384 
0385     orientationActionMenu = actionCollection()->add<KActionMenu>("skymap_orientation");
0386     orientationActionMenu->setText(i18n("Skymap Orientation"));
0387     orientationActionMenu->setDelayed(false);
0388     orientationActionMenu->setIcon(QIcon::fromTheme("screen-rotate-auto-on"));
0389     repopulateOrientation();
0390 
0391     actionCollection()->addAction("geolocation", this, SLOT(slotGeoLocator()))
0392             << i18nc("Location on Earth", "&Geographic...")
0393             << QIcon::fromTheme("kstars_xplanet")
0394             << QKeySequence(Qt::CTRL + Qt::Key_G);
0395 
0396     // Configure Notifications
0397 #ifdef HAVE_NOTIFYCONFIG
0398     KStandardAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection());
0399 #endif
0400 
0401     // Prepare the options dialog early for modules to connect signals
0402     prepareOps();
0403 
0404     ka = actionCollection()->addAction(KStandardAction::Preferences, "configure", this, SLOT(slotViewOps()));
0405     //I am not sure what icon preferences is supposed to be.
0406     //ka->setIcon( QIcon::fromTheme(""));
0407 
0408     actionCollection()->addAction("startwizard", this, SLOT(slotWizard()))
0409             << i18n("Startup Wizard...")
0410             << QIcon::fromTheme("tools-wizard");
0411 
0412     // Manual data entry
0413     actionCollection()->addAction("dso_catalog_gui", this, SLOT(slotDSOCatalogGUI()))
0414             << i18n("Manage DSO Catalogs");
0415 
0416     // Updates actions
0417     actionCollection()->addAction("update_comets", this, SLOT(slotUpdateComets()))
0418             << i18n("Update Comets Orbital Elements");
0419     actionCollection()->addAction("update_asteroids", this, SLOT(slotUpdateAsteroids()))
0420             << i18n("Update Asteroids Orbital Elements");
0421     actionCollection()->addAction("update_supernovae", this, SLOT(slotUpdateSupernovae()))
0422             << i18n("Update Recent Supernovae Data");
0423     actionCollection()->addAction("update_satellites", this, SLOT(slotUpdateSatellites()))
0424             << i18n("Update Satellites Orbital Elements");
0425 
0426     //Tools Menu:
0427     actionCollection()->addAction("astrocalculator", this, SLOT(slotCalculator()))
0428             << i18n("Calculator")
0429             << QIcon::fromTheme("accessories-calculator")
0430             << QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_C);
0431 
0432     /* FIXME Enable once port to KF5 is complete for moonphasetool
0433      actionCollection()->addAction("moonphasetool", this, SLOT(slotMoonPhaseTool()) )
0434          << i18n("Moon Phase Calendar");
0435     */
0436 
0437     actionCollection()->addAction("obslist", this, SLOT(slotObsList()))
0438             << i18n("Observation Planner") << QKeySequence(Qt::CTRL + Qt::Key_L);
0439 
0440     actionCollection()->addAction("altitude_vs_time", this, SLOT(slotAVT()))
0441             << i18n("Altitude vs. Time") << QKeySequence(Qt::CTRL + Qt::Key_A);
0442 
0443     actionCollection()->addAction("whats_up_tonight", this, SLOT(slotWUT()))
0444             << i18n("What's up Tonight") << QKeySequence(Qt::CTRL + Qt::Key_U);
0445 
0446     //FIXME Port to QML2
0447     //#if 0
0448     actionCollection()->addAction("whats_interesting", this, SLOT(slotToggleWIView()))
0449             << i18n("What's Interesting...") << QKeySequence(Qt::CTRL + Qt::Key_W);
0450     //#endif
0451 
0452     actionCollection()->addAction("XPlanet", map(), SLOT(slotStartXplanetViewer()))
0453             << i18n("XPlanet Solar System Simulator") << QKeySequence(Qt::CTRL + Qt::Key_X);
0454 
0455     actionCollection()->addAction("skycalendar", this, SLOT(slotCalendar())) << i18n("Sky Calendar");
0456 
0457 #ifdef HAVE_INDI
0458     ka = actionCollection()->addAction("ekos", this, SLOT(slotEkos()))
0459          << i18n("Ekos") << QKeySequence(Qt::CTRL + Qt::Key_K);
0460     ka->setShortcutContext(Qt::ApplicationShortcut);
0461 #endif
0462 
0463     //FIXME: implement glossary
0464     //     ka = actionCollection()->addAction("glossary");
0465     //     ka->setText( i18n("Glossary...") );
0466     //     ka->setShortcuts( QKeySequence(Qt::CTRL+Qt::Key_K ) );
0467     //     connect( ka, SIGNAL(triggered()), this, SLOT(slotGlossary()) );
0468 
0469     // 2017-09-17 Jasem: FIXME! Scripting does not work properly under non UNIX systems.
0470     // It must be updated to use DBus session bus from Qt (like scheduler)
0471 #ifndef Q_OS_WIN
0472     actionCollection()->addAction("scriptbuilder", this, SLOT(slotScriptBuilder()))
0473             << i18n("Script Builder") << QKeySequence(Qt::CTRL + Qt::Key_B);
0474 #endif
0475 
0476     actionCollection()->addAction("solarsystem", this, SLOT(slotSolarSystem()))
0477             << i18n("Solar System") << QKeySequence(Qt::CTRL + Qt::Key_Y);
0478 
0479     // Disabled until fixed later
0480     actionCollection()->addAction("jmoontool", this, SLOT(slotJMoonTool()) )
0481             << i18n("Jupiter's Moons")
0482             << QKeySequence(Qt::CTRL + Qt::Key_J );
0483 
0484     actionCollection()->addAction("flagmanager", this, SLOT(slotFlagManager())) << i18n("Flags");
0485 
0486     actionCollection()->addAction("equipmentwriter", this, SLOT(slotEquipmentWriter()))
0487             << i18n("List your &Equipment...") << QIcon::fromTheme("kstars") << QKeySequence(Qt::CTRL + Qt::Key_0);
0488     actionCollection()->addAction("manageobserver", this, SLOT(slotObserverManager()))
0489             << i18n("Manage Observer...") << QIcon::fromTheme("im-user") << QKeySequence(Qt::CTRL + Qt::Key_1);
0490 
0491     //TODO only enable it when finished
0492     actionCollection()->addAction("artificialhorizon", this, SLOT(slotHorizonManager()))
0493             << i18n("Artificial Horizon...");
0494 
0495     // ==== observation menu - execute ================
0496     actionCollection()->addAction("execute", this, SLOT(slotExecute()))
0497             << i18n("Execute the Session Plan...") << QKeySequence(Qt::CTRL + Qt::Key_2);
0498 
0499     // ==== observation menu - polaris hour angle ================
0500     actionCollection()->addAction("polaris_hour_angle", this, SLOT(slotPolarisHourAngle()))
0501             << i18n("Polaris Hour Angle...");
0502 
0503     // ==== devices Menu ================
0504 #ifdef HAVE_INDI
0505 #ifndef Q_OS_WIN
0506 #if 0
0507     actionCollection()->addAction("telescope_wizard", this, SLOT(slotTelescopeWizard()))
0508             << i18n("Telescope Wizard...")
0509             << QIcon::fromTheme("tools-wizard");
0510 #endif
0511 #endif
0512     actionCollection()->addAction("device_manager", this, SLOT(slotINDIDriver()))
0513             << i18n("Device Manager...")
0514             << QIcon::fromTheme("network-server")
0515             << QKeySequence(Qt::SHIFT + Qt::META + Qt::Key_D);
0516     actionCollection()->addAction("custom_drivers", DriverManager::Instance(), SLOT(showCustomDrivers()))
0517             << i18n("Custom Drivers...")
0518             << QIcon::fromTheme("address-book-new");
0519     ka = actionCollection()->addAction("indi_cpl", this, SLOT(slotINDIPanel()))
0520          << i18n("INDI Control Panel...")
0521          << QKeySequence(Qt::CTRL + Qt::Key_I);
0522     ka->setShortcutContext(Qt::ApplicationShortcut);
0523     ka->setEnabled(false);
0524 #else
0525     //FIXME need to disable/hide devices submenu in the tools menu. It is created from the kstarsui.rc file
0526     //but I don't know how to hide/disable it yet. menuBar()->findChildren<QMenu *>() does not return any children that I can
0527     //iterate over. Anyway to resolve this?
0528 #endif
0529 
0530     //Help Menu:
0531     ka = actionCollection()->addAction(KStandardAction::TipofDay, "help_tipofday", this, SLOT(slotTipOfDay()));
0532     ka->setWhatsThis(i18n("Displays the Tip of the Day"));
0533     ka->setIcon(QIcon::fromTheme("help-hint"));
0534     //  KStandardAction::help(this, SLOT(appHelpActivated()), actionCollection(), "help_contents" );
0535 
0536     //Add timestep widget for toolbar
0537     m_TimeStepBox = new TimeStepBox(toolBar("kstarsToolBar"));
0538     // Add a tool tip to TimeStep describing the weird nature of time steps
0539     QString TSBToolTip = i18nc("Tooltip describing the nature of the time step control",
0540                                "Use this to set the rate at which time in the simulation flows.\nFor time step \'X\' "
0541                                "up to 10 minutes, time passes at the rate of \'X\' per second.\nFor time steps larger "
0542                                "than 10 minutes, frames are displayed at an interval of \'X\'.");
0543     m_TimeStepBox->setToolTip(TSBToolTip);
0544     m_TimeStepBox->tsbox()->setToolTip(TSBToolTip);
0545     QWidgetAction *wa = new QWidgetAction(this);
0546     wa->setDefaultWidget(m_TimeStepBox);
0547 
0548     // Add actions for the timestep widget's functions
0549     actionCollection()->addAction("timestep_control", wa) << i18n("Time step control");
0550     const auto unitbox = m_TimeStepBox->unitbox();
0551     ka = actionCollection()->addAction("timestep_increase_units", unitbox->increaseUnitsAction());
0552     actionCollection()->setDefaultShortcut(ka, QKeySequence(Qt::Key_Plus));
0553     ka = actionCollection()->addAction("timestep_decrease_units", unitbox->decreaseUnitsAction());
0554     actionCollection()->setDefaultShortcut(ka, QKeySequence(Qt::Key_Underscore));
0555 
0556     // ==== viewToolBar actions ================
0557     actionCollection()->add<KToggleAction>("show_stars", this, SLOT(slotViewToolBar()))
0558             << i18nc("Toggle Stars in the display", "Stars")
0559             << QIcon::fromTheme("kstars_stars")
0560             << ToolTip(i18n("Toggle stars"));
0561     actionCollection()->add<KToggleAction>("show_deepsky", this, SLOT(slotViewToolBar()))
0562             << i18nc("Toggle Deep Sky Objects in the display", "Deep Sky")
0563             << QIcon::fromTheme("kstars_deepsky")
0564             << ToolTip(i18n("Toggle deep sky objects"));
0565     actionCollection()->add<KToggleAction>("show_planets", this, SLOT(slotViewToolBar()))
0566             << i18nc("Toggle Solar System objects in the display", "Solar System")
0567             << QIcon::fromTheme("kstars_planets")
0568             << ToolTip(i18n("Toggle Solar system objects"));
0569     actionCollection()->add<KToggleAction>("show_clines", this, SLOT(slotViewToolBar()))
0570             << i18nc("Toggle Constellation Lines in the display", "Const. Lines")
0571             << QIcon::fromTheme("kstars_clines")
0572             << ToolTip(i18n("Toggle constellation lines"));
0573     actionCollection()->add<KToggleAction>("show_cnames", this, SLOT(slotViewToolBar()))
0574             << i18nc("Toggle Constellation Names in the display", "Const. Names")
0575             << QIcon::fromTheme("kstars_cnames")
0576             << ToolTip(i18n("Toggle constellation names"));
0577     actionCollection()->add<KToggleAction>("show_cbounds", this, SLOT(slotViewToolBar()))
0578             << i18nc("Toggle Constellation Boundaries in the display", "C. Boundaries")
0579             << QIcon::fromTheme("kstars_cbound")
0580             << ToolTip(i18n("Toggle constellation boundaries"));
0581     actionCollection()->add<KToggleAction>("show_constellationart", this, SLOT(slotViewToolBar()))
0582             << xi18nc("Toggle Constellation Art in the display", "C. Art (BETA)")
0583             << QIcon::fromTheme("kstars_constellationart")
0584             << ToolTip(xi18n("Toggle constellation art (BETA)"));
0585     actionCollection()->add<KToggleAction>("show_mw", this, SLOT(slotViewToolBar()))
0586             << i18nc("Toggle Milky Way in the display", "Milky Way")
0587             << QIcon::fromTheme("kstars_mw")
0588             << ToolTip(i18n("Toggle milky way"));
0589     actionCollection()->add<KToggleAction>("show_equatorial_grid", this, SLOT(slotViewToolBar()))
0590             << i18nc("Toggle Equatorial Coordinate Grid in the display", "Equatorial coord. grid")
0591             << QIcon::fromTheme("kstars_grid")
0592             << ToolTip(i18n("Toggle equatorial coordinate grid"));
0593     actionCollection()->add<KToggleAction>("show_horizontal_grid", this, SLOT(slotViewToolBar()))
0594             << i18nc("Toggle Horizontal Coordinate Grid in the display", "Horizontal coord. grid")
0595             << QIcon::fromTheme("kstars_hgrid")
0596             << ToolTip(i18n("Toggle horizontal coordinate grid"));
0597     actionCollection()->add<KToggleAction>("show_horizon", this, SLOT(slotViewToolBar()))
0598             << i18nc("Toggle the opaque fill of the ground polygon in the display", "Ground")
0599             << QIcon::fromTheme("kstars_horizon")
0600             << ToolTip(i18n("Toggle opaque ground"));
0601     actionCollection()->add<KToggleAction>("show_flags", this, SLOT(slotViewToolBar()))
0602             << i18nc("Toggle flags in the display", "Flags")
0603             << QIcon::fromTheme("kstars_flag")
0604             << ToolTip(i18n("Toggle flags"));
0605     actionCollection()->add<KToggleAction>("show_satellites", this, SLOT(slotViewToolBar()))
0606             << i18nc("Toggle satellites in the display", "Satellites")
0607             << QIcon::fromTheme("kstars_satellites")
0608             << ToolTip(i18n("Toggle satellites"));
0609     actionCollection()->add<KToggleAction>("show_supernovae", this, SLOT(slotViewToolBar()))
0610             << i18nc("Toggle supernovae in the display", "Supernovae")
0611             << QIcon::fromTheme("kstars_supernovae")
0612             << ToolTip(i18n("Toggle supernovae"));
0613     actionCollection()->add<KToggleAction>("show_whatsinteresting", this, SLOT(slotToggleWIView()))
0614             << i18nc("Toggle What's Interesting", "What's Interesting")
0615             << QIcon::fromTheme("view-list-details")
0616             << ToolTip(i18n("Toggle What's Interesting"));
0617 
0618 #ifdef HAVE_INDI
0619     // ==== INDIToolBar actions ================
0620     actionCollection()->add<KToggleAction>("show_ekos", this, SLOT(slotINDIToolBar()))
0621             << i18nc("Toggle Ekos in the display", "Ekos")
0622             << QIcon::fromTheme("kstars_ekos")
0623             << ToolTip(i18n("Toggle Ekos"));
0624     ka = actionCollection()->add<KToggleAction>("show_control_panel", this, SLOT(slotINDIToolBar()))
0625          << i18nc("Toggle the INDI Control Panel in the display", "INDI Control Panel")
0626          << QIcon::fromTheme("kstars_indi")
0627          << ToolTip(i18n("Toggle INDI Control Panel"));
0628     ka->setEnabled(false);
0629     ka = actionCollection()->add<KToggleAction>("show_fits_viewer", this, SLOT(slotINDIToolBar()))
0630          << i18nc("Toggle the FITS Viewer in the display", "FITS Viewer")
0631          << QIcon::fromTheme("kstars_fitsviewer")
0632          << ToolTip(i18n("Toggle FITS Viewer"));
0633     ka->setEnabled(false);
0634 
0635     ka = actionCollection()->add<KToggleAction>("show_sensor_fov", this, SLOT(slotINDIToolBar()))
0636          << i18nc("Toggle the sensor Field of View", "Sensor FOV")
0637          << QIcon::fromTheme("archive-extract")
0638          << ToolTip(i18n("Toggle Sensor FOV"));
0639     ka->setEnabled(false);
0640     ka->setChecked(Options::showSensorFOV());
0641 
0642     ka = actionCollection()->add<KToggleAction>("show_mosaic_panel", this, SLOT(slotINDIToolBar()))
0643          << i18nc("Toggle the Mosaic Panel", "Mosaic Panel")
0644          << QIcon::fromTheme("zoom-draw")
0645          << ToolTip(i18n("Toggle Mosaic Panel"));
0646     ka->setEnabled(true);
0647     ka->setChecked(Options::showMosaicPanel());
0648 
0649     ka = actionCollection()->add<KToggleAction>("show_mount_box", this, SLOT(slotINDIToolBar()))
0650          << i18nc("Toggle the Mount Control Panel", "Mount Control")
0651          << QIcon::fromTheme("draw-text")
0652          << ToolTip(i18n("Toggle Mount Control Panel"));
0653     telescopeGroup->addAction(ka);
0654 
0655     ka = actionCollection()->add<KToggleAction>("lock_telescope", this, SLOT(slotINDIToolBar()))
0656          << i18nc("Toggle the telescope center lock in display", "Center Telescope")
0657          << QIcon::fromTheme("center_telescope", QIcon(":/icons/center_telescope.svg"))
0658          << ToolTip(i18n("Toggle Lock Telescope Center"));
0659     telescopeGroup->addAction(ka);
0660 
0661     ka = actionCollection()->add<KToggleAction>("telescope_track", this, SLOT(slotINDITelescopeTrack()))
0662          << i18n("Toggle Telescope Tracking")
0663          << QIcon::fromTheme("object-locked");
0664     telescopeGroup->addAction(ka);
0665     ka = actionCollection()->addAction("telescope_slew", this, SLOT(slotINDITelescopeSlew()))
0666          << i18n("Slew telescope to the focused object")
0667          << QIcon::fromTheme("object-rotate-right");
0668     telescopeGroup->addAction(ka);
0669     ka = actionCollection()->addAction("telescope_sync", this, SLOT(slotINDITelescopeSync()))
0670          << i18n("Sync telescope to the focused object")
0671          << QIcon::fromTheme("media-record");
0672     telescopeGroup->addAction(ka);
0673     ka = actionCollection()->addAction("telescope_abort", this, SLOT(slotINDITelescopeAbort()))
0674          << i18n("Abort telescope motions")
0675          << QIcon::fromTheme("process-stop");
0676     ka->setShortcutContext(Qt::ApplicationShortcut);
0677     telescopeGroup->addAction(ka);
0678     ka = actionCollection()->addAction("telescope_park", this, SLOT(slotINDITelescopePark()))
0679          << i18n("Park telescope")
0680          << QIcon::fromTheme("flag-red");
0681     telescopeGroup->addAction(ka);
0682     ka = actionCollection()->addAction("telescope_unpark", this, SLOT(slotINDITelescopeUnpark()))
0683          << i18n("Unpark telescope")
0684          << QIcon::fromTheme("flag-green");
0685     ka->setShortcutContext(Qt::ApplicationShortcut);
0686     telescopeGroup->addAction(ka);
0687 
0688     actionCollection()->addAction("telescope_slew_mouse", this, SLOT(slotINDITelescopeSlewMousePointer()))
0689             << i18n("Slew the telescope to the mouse pointer position");
0690 
0691     actionCollection()->addAction("telescope_sync_mouse", this, SLOT(slotINDITelescopeSyncMousePointer()))
0692             << i18n("Sync the telescope to the mouse pointer position");
0693 
0694     // Disable all telescope actions by default
0695     telescopeGroup->setEnabled(false);
0696 
0697     // Dome Actions
0698     ka = actionCollection()->addAction("dome_park", this, SLOT(slotINDIDomePark()))
0699          << i18n("Park dome")
0700          << QIcon::fromTheme("dome-park", QIcon(":/icons/dome-park.svg"));
0701     domeGroup->addAction(ka);
0702     ka = actionCollection()->addAction("dome_unpark", this, SLOT(slotINDIDomeUnpark()))
0703          << i18n("Unpark dome")
0704          << QIcon::fromTheme("dome-unpark", QIcon(":/icons/dome-unpark.svg"));
0705     ka->setShortcutContext(Qt::ApplicationShortcut);
0706     domeGroup->addAction(ka);
0707 
0708     domeGroup->setEnabled(false);
0709 #endif
0710 }
0711 
0712 void KStars::repopulateOrientation()
0713 {
0714     double rot = dms{Options::skyRotation()}.reduce().Degrees();
0715     bool useAltAz = Options::useAltAz();
0716     // TODO: Allow adding preset orientations, e.g. for finder scope, main scope etc.
0717     orientationActionMenu->menu()->clear();
0718     orientationActionMenu->addAction(
0719         actionCollection()->addAction(
0720             "up_orientation", this, SLOT(slotSkyMapOrientation()))
0721         << (useAltAz ? i18nc("Orientation of the sky map", "Zenith &Up") : i18nc("Orientation of the sky map", "North &Up"))
0722         << AddToGroup(skymapOrientationGroup)
0723         << Checked(rot == 0.)
0724         << ToolTip(i18nc("Orientation of the sky map",
0725                          "Select this for erect view of the sky map, where north (in Equatorial Coordinate mode) or zenith (in Horizontal Coordinate mode) is vertically up. This would be the natural choice for an erect image finder scope or naked-eye view.")));
0726 
0727     orientationActionMenu->addAction(
0728         actionCollection()->addAction(
0729             "down_orientation", this, SLOT(slotSkyMapOrientation()))
0730         << (useAltAz ? i18nc("Orientation of the sky map", "Zenith &Down") : i18nc("Orientation of the sky map", "North &Down"))
0731         << AddToGroup(skymapOrientationGroup)
0732         << Checked(rot == 180.)
0733         << ToolTip(i18nc("Orientation of the sky map",
0734                          "Select this for inverted view of the sky map, where north (in Equatorial Coordinate mode) or zenith (in Horizontal Coordinate mode) is vertically down. This would be the natural choice for an inverted image finder scope, refractor/cassegrain without erector prism, or Dobsonian.")));
0735 
0736     orientationActionMenu->addAction(
0737         actionCollection()->addAction(
0738             "arbitrary_orientation", this, SLOT(slotSkyMapOrientation()))
0739         << i18nc("Orientation of the sky map is arbitrary as it has been adjusted by the user", "Arbitrary")
0740         << AddToGroup(skymapOrientationGroup)
0741         << Checked(rot != 180. && rot != 0.)
0742         << ToolTip(i18nc("Orientation of the sky map",
0743                          "This mode is selected automatically if you manually rotated the sky map using Shift + Drag mouse action, to inform you that the orientation is arbitrary")));
0744 
0745 
0746     orientationActionMenu->addSeparator();
0747     QAction *erectObserverAction = newToggleAction(
0748                                        actionCollection(), "erect_observer_correction",
0749                                        i18nc("Orient sky map for an erect observer", "Erect observer correction"),
0750                                        this, SLOT(slotSkyMapOrientation()));
0751     erectObserverAction << ToolTip(i18nc("Orient sky map for an erect observer",
0752                                          "Enable this mode if you are visually using a Newtonian telescope on an altazimuth mount. It will correct the orientation of the sky-map to account for the observer remaining erect as the telescope moves up and down, unlike a camera which would rotate with the telescope. This only makes sense in Horizontal Coordinate mode and is disabled when using Equatorial Coordinates. Typically makes sense to combine this with Zenith Down orientation."));
0753     orientationActionMenu->addAction(erectObserverAction);
0754 }
0755 
0756 void KStars::repopulateFOV()
0757 {
0758     // Read list of all FOVs
0759     //qDeleteAll( data()->availFOVs );
0760     data()->availFOVs = FOVManager::getFOVs();
0761     data()->syncFOV();
0762 
0763     // Iterate through FOVs
0764     fovActionMenu->menu()->clear();
0765     foreach (FOV *fov, data()->availFOVs)
0766     {
0767         KToggleAction *kta = actionCollection()->add<KToggleAction>(fov->name());
0768         kta->setText(fov->name());
0769         if (Options::fOVNames().contains(fov->name()))
0770         {
0771             kta->setChecked(true);
0772         }
0773 
0774         fovActionMenu->addAction(kta);
0775         connect(kta, SIGNAL(toggled(bool)), this, SLOT(slotTargetSymbol(bool)));
0776     }
0777     // Add menu bottom
0778     QAction *ka = actionCollection()->addAction("edit_fov", this, SLOT(slotFOVEdit())) << i18n("Edit FOV Symbols...");
0779     fovActionMenu->addSeparator();
0780     fovActionMenu->addAction(ka);
0781 }
0782 
0783 void KStars::repopulateHIPS()
0784 {
0785     // Iterate through actions
0786     hipsActionMenu->menu()->clear();
0787     // Remove all actions
0788     QList<QAction*> actions = hipsGroup->actions();
0789 
0790     for (auto &action : actions)
0791         hipsGroup->removeAction(action);
0792 
0793     auto ka = actionCollection()->addAction(i18n("None"), this, SLOT(slotHIPSSource()))
0794               << i18n("None") << AddToGroup(hipsGroup)
0795               << Checked(Options::hIPSSource() == "None");
0796 
0797     hipsActionMenu->addAction(ka);
0798     hipsActionMenu->addSeparator();
0799 
0800     for (QMap<QString, QString> source : HIPSManager::Instance()->getHIPSSources())
0801     {
0802         QString title = source.value("obs_title");
0803 
0804         auto newAction = actionCollection()->addAction(title, this, SLOT(slotHIPSSource()))
0805                          << title << AddToGroup(hipsGroup)
0806                          << Checked(Options::hIPSSource() == title);
0807 
0808         newAction->setDisabled(Options::hIPSUseOfflineSource() && title != "DSS Colored");
0809 
0810         hipsActionMenu->addAction(newAction);
0811     }
0812 
0813     // Hips settings
0814     ka = actionCollection()->addAction("hipssettings", HIPSManager::Instance(),
0815                                        SLOT(showSettings())) << i18n("HiPS Settings...");
0816     hipsActionMenu->addSeparator();
0817     hipsActionMenu->addAction(ka);
0818 }
0819 
0820 void KStars::initStatusBar()
0821 {
0822     statusBar()->showMessage(i18n(" Welcome to KStars "));
0823 
0824     QString s = "000d 00m 00s,   +00d 00\' 00\""; //only need this to set the width
0825 
0826     AltAzField.setHidden(!Options::showAltAzField());
0827     AltAzField.setText(s);
0828     statusBar()->insertPermanentWidget(0, &AltAzField);
0829 
0830     RADecField.setHidden(!Options::showRADecField());
0831     RADecField.setText(s);
0832     statusBar()->insertPermanentWidget(1, &RADecField);
0833 
0834     J2000RADecField.setHidden(!Options::showJ2000RADecField());
0835     J2000RADecField.setText(s);
0836     statusBar()->insertPermanentWidget(2, &J2000RADecField);
0837 
0838     if (!Options::showStatusBar())
0839         statusBar()->hide();
0840 }
0841 
0842 void KStars::datainitFinished()
0843 {
0844     //Time-related connections
0845     connect(data()->clock(), &SimClock::timeAdvanced, this, [this]()
0846     {
0847         updateTime();
0848     });
0849     connect(data()->clock(), &SimClock::timeChanged, this, [this]()
0850     {
0851         updateTime();
0852     });
0853 
0854     //Add GUI elements to main window
0855     buildGUI();
0856 
0857     connect(data()->clock(), &SimClock::scaleChanged, map(), &SkyMap::slotClockSlewing);
0858 
0859     connect(data(), &KStarsData::skyUpdate, map(), &SkyMap::forceUpdateNow);
0860     connect(m_TimeStepBox, &TimeStepBox::scaleChanged, data(), &KStarsData::setTimeDirection);
0861     connect(m_TimeStepBox, &TimeStepBox::scaleChanged, data()->clock(), &SimClock::setClockScale);
0862 
0863     //Do not start the clock if "--paused" specified on the cmd line
0864     if (StartClockRunning)
0865     {
0866         // The initial time is set when KStars is first executed
0867         // but until all data is loaded, some time elapsed already so we need to synchronize if no Start Date string
0868         // was supplied to KStars
0869         if (StartDateString.isEmpty())
0870             data()->changeDateTime(KStarsDateTime::currentDateTimeUtc());
0871 
0872         data()->clock()->start();
0873     }
0874 
0875     // Connect cache function for Find dialog
0876     connect(data(), SIGNAL(clearCache()), this, SLOT(clearCachedFindDialog()));
0877 
0878     //Propagate config settings
0879     applyConfig(false);
0880 
0881     //show the window.  must be before kswizard and messageboxes
0882     show();
0883 
0884     //Initialize focus
0885     initFocus();
0886 
0887     data()->setFullTimeUpdate();
0888     updateTime();
0889 
0890     // Initial State
0891     qCDebug(KSTARS) << "Date/Time is:" << data()->clock()->utc().toString();
0892     qCDebug(KSTARS) << "Location:" << data()->geo()->fullName();
0893     qCDebug(KSTARS) << "TZ0:" << data()->geo()->TZ0() << "TZ:" << data()->geo()->TZ();
0894 
0895     KSTheme::Manager::instance()->setCurrentTheme(Options::currentTheme());
0896 
0897     //If this is the first startup, show the wizard
0898     if (Options::runStartupWizard())
0899     {
0900         slotWizard();
0901     }
0902 
0903     //Show TotD
0904     KTipDialog::showTip(this, "kstars/tips");
0905 
0906     // Update comets and asteroids if enabled.
0907     if (Options::orbitalElementsAutoUpdate())
0908     {
0909         slotUpdateComets(true);
0910         slotUpdateAsteroids(true);
0911     }
0912 
0913 #ifdef HAVE_INDI
0914     Ekos::Manager::Instance()->initialize();
0915 #endif
0916 }
0917 
0918 void KStars::initFocus()
0919 {
0920     //Case 1: tracking on an object
0921     if (Options::isTracking() && Options::focusObject() != i18n("nothing"))
0922     {
0923         SkyObject *oFocus;
0924         if (Options::focusObject() == i18n("star"))
0925         {
0926             SkyPoint p(Options::focusRA(), Options::focusDec());
0927             double maxrad = 1.0;
0928 
0929             oFocus = data()->skyComposite()->starNearest(&p, maxrad);
0930         }
0931         else
0932         {
0933             oFocus = data()->objectNamed(Options::focusObject());
0934         }
0935 
0936         if (oFocus)
0937         {
0938             map()->setFocusObject(oFocus);
0939             map()->setClickedObject(oFocus);
0940             map()->setFocusPoint(oFocus);
0941         }
0942         else
0943         {
0944             qWarning() << "Cannot center on " << Options::focusObject() << ": no object found.";
0945         }
0946 
0947         //Case 2: not tracking, and using Alt/Az coords.  Set focus point using
0948         //FocusRA as the Azimuth, and FocusDec as the Altitude
0949     }
0950     else if (!Options::isTracking() && Options::useAltAz())
0951     {
0952         SkyPoint pFocus;
0953         pFocus.setAz(Options::focusRA());
0954         pFocus.setAlt(Options::focusDec());
0955         pFocus.HorizontalToEquatorial(data()->lst(), data()->geo()->lat());
0956         map()->setFocusPoint(&pFocus);
0957 
0958         //Default: set focus point using FocusRA as the RA and
0959         //FocusDec as the Dec
0960     }
0961     else
0962     {
0963         SkyPoint pFocus(Options::focusRA(), Options::focusDec());
0964         pFocus.EquatorialToHorizontal(data()->lst(), data()->geo()->lat());
0965         map()->setFocusPoint(&pFocus);
0966     }
0967     data()->setSnapNextFocus();
0968     map()->setDestination(*map()->focusPoint());
0969     map()->setFocus(map()->destination());
0970 
0971     map()->showFocusCoords();
0972 
0973     //Check whether initial position is below the horizon.
0974     if (Options::useAltAz() && Options::showGround() && map()->focus()->alt().Degrees() <= SkyPoint::altCrit)
0975     {
0976         QString caption = i18n("Initial Position is Below Horizon");
0977         QString message =
0978             i18n("The initial position is below the horizon.\nWould you like to reset to the default position?");
0979         if (KMessageBox::warningYesNo(this, message, caption, KGuiItem(i18n("Reset Position")),
0980                                       KGuiItem(i18n("Do Not Reset")), "dag_start_below_horiz") == KMessageBox::Yes)
0981         {
0982             map()->setClickedObject(nullptr);
0983             map()->setFocusObject(nullptr);
0984             Options::setIsTracking(false);
0985 
0986             data()->setSnapNextFocus(true);
0987 
0988             SkyPoint DefaultFocus;
0989             DefaultFocus.setAz(180.0);
0990             DefaultFocus.setAlt(45.0);
0991             DefaultFocus.HorizontalToEquatorial(data()->lst(), data()->geo()->lat());
0992             map()->setDestination(DefaultFocus);
0993         }
0994     }
0995 
0996     //If there is a focusObject() and it is a SS body, add a temporary Trail
0997     if (map()->focusObject() && map()->focusObject()->isSolarSystem() && Options::useAutoTrail())
0998     {
0999         ((KSPlanetBase *)map()->focusObject())->addToTrail();
1000         data()->temporaryTrail = true;
1001     }
1002 }
1003 
1004 void KStars::buildGUI()
1005 {
1006     //create the texture manager
1007     TextureManager::Create();
1008     //create the skymap
1009     m_SkyMap = SkyMap::Create();
1010     connect(m_SkyMap, SIGNAL(mousePointChanged(SkyPoint*)), SLOT(slotShowPositionBar(SkyPoint*)));
1011     connect(m_SkyMap, SIGNAL(zoomChanged()), SLOT(slotZoomChanged()));
1012     setCentralWidget(m_SkyMap);
1013 
1014     //Initialize menus, toolbars, and statusbars
1015     initStatusBar();
1016     initActions();
1017 
1018     // Setup GUI from the settings file
1019     // UI tests provide the default settings file from the resources explicitly file to render UI properly
1020     setupGUI(StandardWindowOptions(Default), m_KStarsUIResource);
1021 
1022     //get focus of keyboard and mouse actions (for example zoom in with +)
1023     map()->QWidget::setFocus();
1024     resize(Options::windowWidth(), Options::windowHeight());
1025 
1026     // check zoom in/out buttons
1027     if (Options::zoomFactor() >= MAXZOOM)
1028         actionCollection()->action("zoom_in")->setEnabled(false);
1029     if (Options::zoomFactor() <= MINZOOM)
1030         actionCollection()->action("zoom_out")->setEnabled(false);
1031 }
1032 
1033 void KStars::populateThemes()
1034 {
1035     KSTheme::Manager::instance()->setThemeMenuAction(new QMenu(i18n("&Themes"), this));
1036     KSTheme::Manager::instance()->registerThemeActions(this);
1037 
1038     connect(KSTheme::Manager::instance(), SIGNAL(signalThemeChanged()), this, SLOT(slotThemeChanged()));
1039 }
1040 
1041 void KStars::slotThemeChanged()
1042 {
1043     Options::setCurrentTheme(KSTheme::Manager::instance()->currentThemeName());
1044 }