Warning, file /education/kstars/kstars/kstars.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kstars.h" 0008 0009 #include "config-kstars.h" 0010 #include "version.h" 0011 0012 #include "fov.h" 0013 #include "kactionmenu.h" 0014 #include "kstarsadaptor.h" 0015 #include "kstarsdata.h" 0016 #include "kstarssplash.h" 0017 #include "observinglist.h" 0018 #include "Options.h" 0019 #include "skymap.h" 0020 #include "skyqpainter.h" 0021 #include "texturemanager.h" 0022 #include "dialogs/finddialog.h" 0023 #include "dialogs/exportimagedialog.h" 0024 #include "skycomponents/starblockfactory.h" 0025 #ifdef HAVE_INDI 0026 #include "ekos/manager.h" 0027 #include "indi/drivermanager.h" 0028 #include "indi/guimanager.h" 0029 #include "indi/indilistener.h" 0030 #endif 0031 0032 #ifdef HAVE_CFITSIO 0033 #include "fitsviewer/fitsviewer.h" 0034 #endif 0035 0036 #include <KActionCollection> 0037 #include <KToolBar> 0038 0039 #ifdef Q_OS_WIN 0040 #include <QProcess> 0041 #endif 0042 #include <QStatusBar> 0043 #include <QMenu> 0044 0045 #include <kstars_debug.h> 0046 0047 KStars *KStars::pinstance = nullptr; 0048 bool KStars::Closing = false; 0049 0050 KStars::KStars(bool doSplash, bool clockrun, const QString &startdate) 0051 : KXmlGuiWindow(), StartClockRunning(clockrun), StartDateString(startdate) 0052 { 0053 // FIXME Hack to set RTL direction for Arabic 0054 // This is not a solution. It seems qtbase_ar.qm needs to take care of this? 0055 // qttranslations5-l10n does not contain qtbase_ar.qm 0056 // It seems qtbase_ar.ts does not exist for Qt 5.9 at all and needs to be translated. 0057 // https://wiki.qt.io/Qt_Localization 0058 if (i18n("Sky") == "السماء") 0059 qApp->setLayoutDirection(Qt::RightToLeft); 0060 0061 setWindowTitle(i18nc("@title:window", "KStars")); 0062 0063 // Set thread stack size to 32MB 0064 QThreadPool::globalInstance()->setStackSize(33554432); 0065 0066 // Initialize logging settings 0067 if (Options::disableLogging()) 0068 KSUtils::Logging::Disable(); 0069 else if (Options::logToFile()) 0070 KSUtils::Logging::UseFile(); 0071 else 0072 KSUtils::Logging::UseDefault(); 0073 0074 KSUtils::Logging::SyncFilterRules(); 0075 0076 qCInfo(KSTARS) << "Welcome to KStars" << KSTARS_VERSION << KSTARS_BUILD_RELEASE; 0077 qCInfo(KSTARS) << "Build:" << KSTARS_BUILD_TS; 0078 qCInfo(KSTARS) << "OS:" << QSysInfo::productType(); 0079 qCInfo(KSTARS) << "API:" << QSysInfo::buildAbi(); 0080 qCInfo(KSTARS) << "Arch:" << QSysInfo::currentCpuArchitecture(); 0081 qCInfo(KSTARS) << "Kernel Type:" << QSysInfo::kernelType(); 0082 qCInfo(KSTARS) << "Kernel Version:" << QSysInfo::kernelVersion(); 0083 qCInfo(KSTARS) << "Qt Version:" << QT_VERSION_STR; 0084 0085 new KstarsAdaptor( 0086 this); // NOTE the weird case convention, which cannot be changed as the file is generated by the moc. 0087 0088 #ifdef Q_OS_OSX 0089 0090 QString vlcPlugins = QDir(QCoreApplication::applicationDirPath() + "/../PlugIns/vlc").absolutePath(); 0091 qputenv("VLC_PLUGIN_PATH", vlcPlugins.toLatin1()); 0092 QString phonon_backend_path = QDir(QCoreApplication::applicationDirPath() + 0093 "/../PlugIns/phonon4qt5_backend/phonon_vlc.so").absolutePath(); 0094 qputenv("PHONON_BACKEND", phonon_backend_path.toLatin1()); 0095 0096 QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 0097 QString path = env.value("PATH", ""); 0098 env.insert("PATH", "/usr/bin:/usr/local/bin:\"" + QCoreApplication::applicationDirPath() + "\":" + path); 0099 0100 QProcess dbusCheck; 0101 dbusCheck.setProcessEnvironment(env); 0102 0103 QString pluginsDir = QDir(QCoreApplication::applicationDirPath() + "/../PlugIns").absolutePath(); 0104 QString dbusPlist = pluginsDir + "/dbus/org.freedesktop.dbus-kstars.plist"; 0105 QFile file(dbusPlist); 0106 if (file.open(QIODevice::ReadOnly)) 0107 { 0108 QTextStream in(&file); 0109 QString pListText = in.readAll(); 0110 file.close(); 0111 int programArgsLeft = pListText.indexOf("<key>ProgramArguments</key>"); 0112 int programArgsRight = pListText.indexOf("</array>", programArgsLeft) + 8 - programArgsLeft; 0113 QString currentProgramArgs = pListText.mid(programArgsLeft, programArgsRight); 0114 QString newProgramArguments = "" 0115 "<key>ProgramArguments</key>\n" 0116 " <array>\n" 0117 " <string>" + 0118 QCoreApplication::applicationDirPath() + 0119 "/dbus-daemon</string>\n" 0120 " <string>--nofork</string>\n" 0121 " <string>--config-file=" + 0122 pluginsDir + 0123 "/dbus/kstars.conf</string>\n" 0124 " </array>"; 0125 pListText.replace(currentProgramArgs, newProgramArguments); 0126 if (file.open(QIODevice::WriteOnly)) 0127 { 0128 QTextStream stream(&file); 0129 stream << pListText; 0130 file.close(); 0131 0132 dbusCheck.start("chmod 775 " + dbusPlist); 0133 dbusCheck.waitForFinished(); 0134 dbusCheck.start("launchctl load -w \"" + dbusPlist + "\""); 0135 dbusCheck.waitForFinished(); 0136 qDebug("Starting DBus"); 0137 } 0138 else 0139 { 0140 qDebug("DBus File Write Error"); 0141 } 0142 } 0143 else 0144 { 0145 qDebug("DBus File Read Error"); 0146 } 0147 #endif 0148 0149 QDBusConnection::sessionBus().registerObject("/KStars", this); 0150 QDBusConnection::sessionBus().registerService("org.kde.kstars"); 0151 0152 #ifdef HAVE_CFITSIO 0153 m_GenericFITSViewer.clear(); 0154 #endif 0155 0156 // Set pinstance to yourself 0157 pinstance = this; 0158 0159 connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit())); 0160 0161 //Initialize QActionGroups 0162 projectionGroup = new QActionGroup(this); 0163 cschemeGroup = new QActionGroup(this); 0164 hipsGroup = new QActionGroup(this); 0165 telescopeGroup = new QActionGroup(this); 0166 telescopeGroup->setExclusive(false); 0167 domeGroup = new QActionGroup(this); 0168 domeGroup->setExclusive(false); 0169 0170 0171 m_KStarsData = KStarsData::Create(); 0172 Q_ASSERT(m_KStarsData); 0173 //Set Geographic Location from Options 0174 m_KStarsData->setLocationFromOptions(); 0175 0176 //Initialize Time and Date 0177 bool datetimeSet = false; 0178 if (StartDateString.isEmpty() == false) 0179 { 0180 KStarsDateTime startDate = KStarsDateTime::fromString(StartDateString); 0181 if (startDate.isValid()) 0182 data()->changeDateTime(data()->geo()->LTtoUT(startDate)); 0183 else 0184 data()->changeDateTime(KStarsDateTime::currentDateTimeUtc()); 0185 0186 datetimeSet = true; 0187 } 0188 // JM 2016-11-15: Not need to set it again as it was initialized in the ctor of SimClock 0189 /* 0190 else 0191 data()->changeDateTime( KStarsDateTime::currentDateTimeUtc() ); 0192 */ 0193 0194 // If we are starting paused (--paused is not in the command line) change datetime in data 0195 if (StartClockRunning == false) 0196 { 0197 qCInfo(KSTARS) << "KStars is started in paused state."; 0198 if (datetimeSet == false) 0199 data()->changeDateTime(KStarsDateTime::currentDateTimeUtc()); 0200 } 0201 0202 // Setup splash screen 0203 KStarsSplash *splash = nullptr; 0204 if (doSplash) 0205 { 0206 splash = new KStarsSplash(nullptr); 0207 connect(m_KStarsData, SIGNAL(progressText(QString)), splash, SLOT(setMessage(QString))); 0208 splash->show(); 0209 } 0210 else 0211 { 0212 connect(m_KStarsData, SIGNAL(progressText(QString)), m_KStarsData, SLOT(slotConsoleMessage(QString))); 0213 } 0214 0215 /* 0216 //set up Dark color scheme for application windows 0217 DarkPalette = QPalette(QColor("black"), QColor("black")); 0218 DarkPalette.setColor(QPalette::Inactive, QPalette::WindowText, QColor("red")); 0219 DarkPalette.setColor(QPalette::Normal, QPalette::WindowText, QColor("red")); 0220 DarkPalette.setColor(QPalette::Normal, QPalette::Base, QColor("black")); 0221 DarkPalette.setColor(QPalette::Normal, QPalette::Text, QColor(238, 0, 0)); 0222 DarkPalette.setColor(QPalette::Normal, QPalette::Highlight, QColor(238, 0, 0)); 0223 DarkPalette.setColor(QPalette::Normal, QPalette::HighlightedText, QColor("black")); 0224 DarkPalette.setColor(QPalette::Inactive, QPalette::Text, QColor(238, 0, 0)); 0225 DarkPalette.setColor(QPalette::Inactive, QPalette::Base, QColor(30, 10, 10)); 0226 //store original color scheme 0227 OriginalPalette = QApplication::palette(); 0228 */ 0229 0230 //Initialize data. When initialization is complete, it will run dataInitFinished() 0231 if (!m_KStarsData->initialize()) 0232 return; 0233 delete splash; 0234 datainitFinished(); 0235 } 0236 0237 KStars *KStars::createInstance(bool doSplash, bool clockrun, const QString &startdate) 0238 { 0239 delete pinstance; 0240 // pinstance is set directly in constructor. 0241 new KStars(doSplash, clockrun, startdate); 0242 Q_ASSERT(pinstance && "pinstance must be non NULL"); 0243 return pinstance; 0244 } 0245 0246 KStars::~KStars() 0247 { 0248 releaseResources(); 0249 Q_ASSERT(pinstance); 0250 pinstance = nullptr; 0251 #ifdef PROFILE_COORDINATE_CONVERSION 0252 qDebug() << Q_FUNC_INFO << "Spent " << SkyPoint::cpuTime_EqToHz << " seconds in " << SkyPoint::eqToHzCalls 0253 << " calls to SkyPoint::EquatorialToHorizontal, for an average of " 0254 << 1000. * (SkyPoint::cpuTime_EqToHz / SkyPoint::eqToHzCalls) << " ms per call"; 0255 #endif 0256 0257 #ifdef COUNT_DMS_SINCOS_CALLS 0258 qDebug() << Q_FUNC_INFO << "Constructed " << dms::dms_constructor_calls << " dms objects, of which " << 0259 dms::dms_with_sincos_called 0260 << " had trigonometric functions called on them = " 0261 << (float(dms::dms_with_sincos_called) / float(dms::dms_constructor_calls)) * 100. << "%"; 0262 qDebug() << Q_FUNC_INFO << "Of the " << dms::trig_function_calls << " calls to sin/cos/sincos on dms objects, " 0263 << dms::redundant_trig_function_calls << " were redundant = " 0264 << ((float(dms::redundant_trig_function_calls) / float(dms::trig_function_calls)) * 100.) << "%"; 0265 qDebug() << Q_FUNC_INFO << "We had " << CachingDms::cachingdms_bad_uses << " bad uses of CachingDms in all, compared to " 0266 << CachingDms::cachingdms_constructor_calls << " constructed CachingDms objects = " 0267 << (float(CachingDms::cachingdms_bad_uses) / float(CachingDms::cachingdms_constructor_calls)) * 100. 0268 << "% bad uses"; 0269 #endif 0270 0271 /* BUG 366596: Some KDE applications processes remain as background (zombie) processes after closing 0272 * No solution to this bug so far using Qt 5.8 as of 2016-11-24 0273 * Therefore, the only way to solve this on Windows is to explicitly kill kstars.exe 0274 * Hopefully we do not need this hack once the above bug is resolved. 0275 */ 0276 #ifdef Q_OS_WIN 0277 QProcess::execute("taskkill /im kstars.exe /f"); 0278 #endif 0279 } 0280 0281 void KStars::releaseResources() 0282 { 0283 delete m_KStarsData; 0284 m_KStarsData = nullptr; 0285 delete StarBlockFactory::Instance(); 0286 TextureManager::Release(); 0287 SkyQPainter::releaseImageCache(); 0288 FOVManager::releaseCache(); 0289 0290 #ifdef HAVE_INDI 0291 GUIManager::release(); 0292 Ekos::Manager::release(); 0293 DriverManager::release(); 0294 #endif 0295 0296 #ifdef HAVE_CFITSIO 0297 //if (Options::independentWindowFITS()) 0298 qDeleteAll(m_FITSViewers); 0299 #endif 0300 0301 QSqlDatabase::removeDatabase("userdb"); 0302 QSqlDatabase::removeDatabase("skydb"); 0303 } 0304 0305 void KStars::clearCachedFindDialog() 0306 { 0307 #if 0 0308 if (m_FindDialog) // dialog is cached 0309 { 0310 /** Delete findDialog only if it is not opened */ 0311 if (m_FindDialog->isHidden()) 0312 { 0313 delete m_FindDialog; 0314 m_FindDialog = nullptr; 0315 DialogIsObsolete = false; 0316 } 0317 else 0318 DialogIsObsolete = true; // dialog was opened so it could not deleted 0319 } 0320 #endif 0321 } 0322 0323 void KStars::applyConfig(bool doApplyFocus) 0324 { 0325 if (Options::isTracking()) 0326 { 0327 actionCollection()->action("track_object")->setText(i18n("Stop &Tracking")); 0328 actionCollection() 0329 ->action("track_object") 0330 ->setIcon(QIcon::fromTheme("document-encrypt")); 0331 } 0332 0333 actionCollection() 0334 ->action("coordsys") 0335 ->setText(Options::useAltAz() ? i18n("Switch to Star Globe View (Equatorial &Coordinates)") : 0336 i18n("Switch to Horizonal View (Horizontal &Coordinates)")); 0337 0338 actionCollection()->action("show_time_box")->setChecked(Options::showTimeBox()); 0339 actionCollection()->action("show_location_box")->setChecked(Options::showGeoBox()); 0340 actionCollection()->action("show_focus_box")->setChecked(Options::showFocusBox()); 0341 actionCollection()->action("show_statusBar")->setChecked(Options::showStatusBar()); 0342 actionCollection()->action("show_sbAzAlt")->setChecked(Options::showAltAzField()); 0343 actionCollection()->action("show_sbRADec")->setChecked(Options::showRADecField()); 0344 actionCollection()->action("show_sbJ2000RADec")->setChecked(Options::showJ2000RADecField()); 0345 actionCollection()->action("show_stars")->setChecked(Options::showStars()); 0346 actionCollection()->action("show_deepsky")->setChecked(Options::showDeepSky()); 0347 actionCollection()->action("show_planets")->setChecked(Options::showSolarSystem()); 0348 actionCollection()->action("show_clines")->setChecked(Options::showCLines()); 0349 actionCollection()->action("show_constellationart")->setChecked(Options::showConstellationArt()); 0350 actionCollection()->action("show_cnames")->setChecked(Options::showCNames()); 0351 actionCollection()->action("show_cbounds")->setChecked(Options::showCBounds()); 0352 actionCollection()->action("show_mw")->setChecked(Options::showMilkyWay()); 0353 actionCollection()->action("show_equatorial_grid")->setChecked(Options::showEquatorialGrid()); 0354 actionCollection()->action("show_horizontal_grid")->setChecked(Options::showHorizontalGrid()); 0355 actionCollection()->action("show_horizon")->setChecked(Options::showGround()); 0356 actionCollection()->action("show_flags")->setChecked(Options::showFlags()); 0357 actionCollection()->action("show_supernovae")->setChecked(Options::showSupernovae()); 0358 actionCollection()->action("show_satellites")->setChecked(Options::showSatellites()); 0359 statusBar()->setVisible(Options::showStatusBar()); 0360 0361 //color scheme 0362 m_KStarsData->colorScheme()->loadFromConfig(); 0363 //QApplication::setPalette(Options::darkAppColors() ? DarkPalette : OriginalPalette); 0364 /** 0365 //Note: This uses style sheets to set the dark colors, this should be cross platform. Palettes have a different behavior on OS X and Windows as opposed to Linux. 0366 //It might be a good idea to use stylesheets in the future instead of palettes but this will work for now for OS X. 0367 //This is also in KStarsDbus.cpp. If you change it, change it in BOTH places. 0368 @code 0369 #ifdef Q_OS_OSX 0370 if (Options::darkAppColors()) 0371 qApp->setStyleSheet( 0372 "QWidget { background-color: black; color:red; " 0373 "selection-background-color:rgb(30,30,30);selection-color:white}" 0374 "QToolBar { border:none }" 0375 "QTabBar::tab:selected { background-color:rgb(50,50,50) }" 0376 "QTabBar::tab:!selected { background-color:rgb(30,30,30) }" 0377 "QPushButton { background-color:rgb(50,50,50);border-width:1px; border-style:solid;border-color:black}" 0378 "QPushButton::disabled { background-color:rgb(10,10,10);border-width:1px; " 0379 "border-style:solid;border-color:black }" 0380 "QToolButton:Checked { background-color:rgb(30,30,30); border:none }" 0381 "QComboBox { background-color:rgb(30,30,30); }" 0382 "QComboBox::disabled { background-color:rgb(10,10,10) }" 0383 "QScrollBar::handle { background: rgb(30,30,30) }" 0384 "QSpinBox { border-width: 1px; border-style:solid; border-color:rgb(30,30,30) }" 0385 "QDoubleSpinBox { border-width:1px; border-style:solid; border-color:rgb(30,30,30) }" 0386 "QLineEdit { border-width: 1px; border-style: solid; border-color:rgb(30,30,30) }" 0387 "QCheckBox::indicator:unchecked { background-color:rgb(30,30,30);border-width:1px; " 0388 "border-style:solid;border-color:black }" 0389 "QCheckBox::indicator:checked { background-color:red;border-width:1px; " 0390 "border-style:solid;border-color:black }" 0391 "QRadioButton::indicator:unchecked { background-color:rgb(30,30,30) }" 0392 "QRadioButton::indicator:checked { background-color:red }" 0393 "QRoundProgressBar { alternate-background-color:black }" 0394 "QDateTimeEdit {background-color:rgb(30,30,30); border-width: 1px; border-style:solid; " 0395 "border-color:rgb(30,30,30) }" 0396 "QHeaderView { color:red;background-color:black }" 0397 "QHeaderView::Section { background-color:rgb(30,30,30) }" 0398 "QTableCornerButton::section{ background-color:rgb(30,30,30) }" 0399 ""); 0400 else 0401 qApp->setStyleSheet(""); 0402 #endif 0403 @endcode 0404 **/ 0405 0406 //Set toolbar options from config file 0407 toolBar("kstarsToolBar")->applySettings(KSharedConfig::openConfig()->group("MainToolBar")); 0408 toolBar("viewToolBar")->applySettings(KSharedConfig::openConfig()->group("ViewToolBar")); 0409 0410 //Geographic location 0411 data()->setLocationFromOptions(); 0412 0413 //Focus 0414 if (doApplyFocus) 0415 { 0416 SkyObject *fo = data()->objectNamed(Options::focusObject()); 0417 if (fo && fo != map()->focusObject()) 0418 { 0419 map()->setClickedObject(fo); 0420 map()->setClickedPoint(fo); 0421 map()->slotCenter(); 0422 } 0423 0424 if (!fo) 0425 { 0426 SkyPoint fp(Options::focusRA(), Options::focusDec()); 0427 if (fp.ra().Degrees() != map()->focus()->ra().Degrees() || 0428 fp.dec().Degrees() != map()->focus()->dec().Degrees()) 0429 { 0430 map()->setClickedPoint(&fp); 0431 map()->slotCenter(); 0432 } 0433 } 0434 } 0435 } 0436 0437 void KStars::showImgExportDialog() 0438 { 0439 if (m_ExportImageDialog) 0440 m_ExportImageDialog->show(); 0441 } 0442 0443 void KStars::syncFOVActions() 0444 { 0445 foreach (QAction *action, fovActionMenu->menu()->actions()) 0446 { 0447 if (action->text().isEmpty()) 0448 { 0449 continue; 0450 } 0451 0452 if (Options::fOVNames().contains(action->text().remove(0, 1))) 0453 { 0454 action->setChecked(true); 0455 } 0456 else 0457 { 0458 action->setChecked(false); 0459 } 0460 } 0461 } 0462 0463 void KStars::hideAllFovExceptFirst() 0464 { 0465 // When there is only one visible FOV symbol, we don't need to do anything 0466 // Also, don't do anything if there are no available FOV symbols. 0467 if (data()->visibleFOVs.size() == 1 || data()->availFOVs.isEmpty()) 0468 { 0469 return; 0470 } 0471 else 0472 { 0473 // If there are no visible FOVs, select first available 0474 if (data()->visibleFOVs.isEmpty()) 0475 { 0476 Q_ASSERT(!data()->availFOVs.isEmpty()); 0477 Options::setFOVNames(QStringList(data()->availFOVs.first()->name())); 0478 } 0479 else 0480 { 0481 Options::setFOVNames(QStringList(data()->visibleFOVs.first()->name())); 0482 } 0483 0484 // Sync FOV and update skymap 0485 data()->syncFOV(); 0486 syncFOVActions(); 0487 map()->update(); // SkyMap::forceUpdate() is not required, as FOVs are drawn as overlays 0488 } 0489 } 0490 0491 void KStars::selectNextFov() 0492 { 0493 if (data()->getVisibleFOVs().isEmpty()) 0494 return; 0495 0496 Q_ASSERT(!data() 0497 ->getAvailableFOVs() 0498 .isEmpty()); // The available FOVs had better not be empty if the visible ones are not. 0499 0500 FOV *currentFov = data()->getVisibleFOVs().first(); 0501 int currentIdx = data()->availFOVs.indexOf(currentFov); 0502 0503 // If current FOV is not the available FOV list or there is only 1 FOV available, then return 0504 if (currentIdx == -1 || data()->availFOVs.size() < 2) 0505 { 0506 return; 0507 } 0508 0509 QStringList nextFovName; 0510 if (currentIdx == data()->availFOVs.size() - 1) 0511 { 0512 nextFovName << data()->availFOVs.first()->name(); 0513 } 0514 else 0515 { 0516 nextFovName << data()->availFOVs.at(currentIdx + 1)->name(); 0517 } 0518 0519 Options::setFOVNames(nextFovName); 0520 data()->syncFOV(); 0521 syncFOVActions(); 0522 map()->update(); 0523 } 0524 0525 void KStars::selectPreviousFov() 0526 { 0527 if (data()->getVisibleFOVs().isEmpty()) 0528 return; 0529 0530 Q_ASSERT(!data() 0531 ->getAvailableFOVs() 0532 .isEmpty()); // The available FOVs had better not be empty if the visible ones are not. 0533 0534 FOV *currentFov = data()->getVisibleFOVs().first(); 0535 int currentIdx = data()->availFOVs.indexOf(currentFov); 0536 0537 // If current FOV is not the available FOV list or there is only 1 FOV available, then return 0538 if (currentIdx == -1 || data()->availFOVs.size() < 2) 0539 { 0540 return; 0541 } 0542 0543 QStringList prevFovName; 0544 if (currentIdx == 0) 0545 { 0546 prevFovName << data()->availFOVs.last()->name(); 0547 } 0548 else 0549 { 0550 prevFovName << data()->availFOVs.at(currentIdx - 1)->name(); 0551 } 0552 0553 Options::setFOVNames(prevFovName); 0554 data()->syncFOV(); 0555 syncFOVActions(); 0556 map()->update(); 0557 } 0558 0559 //FIXME Port to QML2 0560 //#if 0 0561 void KStars::showWISettingsUI() 0562 { 0563 slotWISettings(); 0564 } 0565 //#endif 0566 0567 void KStars::updateTime(const bool automaticDSTchange) 0568 { 0569 // Due to frequently use of this function save data and map pointers for speedup. 0570 // Save options and geo() to a pointer would not speedup because most of time options 0571 // and geo will accessed only one time. 0572 KStarsData *Data = data(); 0573 // dms oldLST( Data->lst()->Degrees() ); 0574 0575 Data->updateTime(Data->geo(), automaticDSTchange); 0576 0577 //We do this outside of kstarsdata just to get the coordinates 0578 //displayed in the infobox to update every second. 0579 // if ( !Options::isTracking() && LST()->Degrees() > oldLST.Degrees() ) { 0580 // int nSec = int( 3600.*( LST()->Hours() - oldLST.Hours() ) ); 0581 // Map->focus()->setRA( Map->focus()->ra().Hours() + double( nSec )/3600. ); 0582 // if ( Options::useAltAz() ) Map->focus()->EquatorialToHorizontal( LST(), geo()->lat() ); 0583 // Map->showFocusCoords(); 0584 // } 0585 0586 //If time is accelerated beyond slewTimescale, then the clock's timer is stopped, 0587 //so that it can be ticked manually after each update, in order to make each time 0588 //step exactly equal to the timeScale setting. 0589 //Wrap the call to manualTick() in a singleshot timer so that it doesn't get called until 0590 //the skymap has been completely updated. 0591 if (Data->clock()->isManualMode() && Data->clock()->isActive()) 0592 { 0593 // Jasem 2017-11-13: Time for each update varies. 0594 // Ideally we want to advance the simulation clock by 0595 // the current clock scale (e.g. 1 hour) every 1 second 0596 // of real time. However, the sky map update, depending on calculations and 0597 // drawing of objects, takes variable time to complete. 0598 //QTimer::singleShot(0, Data->clock(), SLOT(manualTick())); 0599 QTimer::singleShot(1000, Data->clock(), SLOT(manualTick())); 0600 } 0601 } 0602 0603 #ifdef HAVE_CFITSIO 0604 const QPointer<FITSViewer> &KStars::createFITSViewer() 0605 { 0606 if (Options::singleWindowCapturedFITS()) 0607 return KStars::Instance()->genericFITSViewer(); 0608 else 0609 { 0610 QPointer<FITSViewer> newFITSViewer = new FITSViewer(Options::independentWindowFITS() ? nullptr : KStars::Instance()); 0611 0612 connect(newFITSViewer.data(), &FITSViewer::destroyed, [ = ]() 0613 { 0614 m_FITSViewers.removeOne(newFITSViewer); 0615 }); 0616 0617 m_FITSViewers.append(newFITSViewer); 0618 return m_FITSViewers.constLast(); 0619 } 0620 } 0621 0622 const QPointer<FITSViewer> &KStars::genericFITSViewer() 0623 { 0624 if (m_GenericFITSViewer.isNull()) 0625 { 0626 m_GenericFITSViewer = new FITSViewer(Options::independentWindowFITS() ? nullptr : this); 0627 //m_GenericFITSViewer->setAttribute(Qt::WA_DeleteOnClose); 0628 m_FITSViewers.append(m_GenericFITSViewer); 0629 } 0630 0631 return m_GenericFITSViewer; 0632 } 0633 0634 //void KStars::addFITSViewer(const QSharedPointer<FITSViewer> &fv) 0635 //{ 0636 // m_FITSViewers.append(fv); 0637 // connect(fv.data(), &FITSViewer::terminated, [ = ]() 0638 // { 0639 // m_FITSViewers.removeOne(fv); 0640 // }); 0641 //} 0642 0643 void KStars::clearAllViewers() 0644 { 0645 for (auto &fv : m_FITSViewers) 0646 fv->close(); 0647 0648 m_FITSViewers.clear(); 0649 } 0650 #endif 0651 0652 void KStars::closeEvent(QCloseEvent *event) 0653 { 0654 KStars::Closing = true; 0655 QWidget::closeEvent(event); 0656 slotAboutToQuit(); 0657 }