File indexing completed on 2022-12-06 18:58:49

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