diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/.gitlab-ci.yml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/.gitlab-ci.yml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/.gitlab-ci.yml 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/.gitlab-ci.yml 2023-12-03 05:23:16.000000000 +0000 @@ -8,7 +8,7 @@ - test #- test-unstable -image: tallfurryman/kstars-ci:0.11 +image: tallfurryman/kstars-ci:0.12 variables: CCACHE_BASEDIR: "$CI_PROJECT_DIR" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/CMakeLists.txt kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/CMakeLists.txt --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/CMakeLists.txt 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/CMakeLists.txt 2023-12-03 05:23:16.000000000 +0000 @@ -3,7 +3,7 @@ PROJECT(kstars CXX C) set (KStars_VERSION_MAJOR 3) set (KStars_VERSION_MINOR 6) -set (KStars_VERSION_REVISION 7) +set (KStars_VERSION_REVISION 8) set (KSTARS_BUILD_RELEASE "Stable") set (CMAKE_CXX_STANDARD 17) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/ChangeLog kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/ChangeLog --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/ChangeLog 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/ChangeLog 2023-12-03 05:23:16.000000000 +0000 @@ -4,6 +4,91 @@ $ git log --date=short --pretty=format:"%h %ad %<(20)%an %<(150,trunc)%s" +3.6.8 (Abberator): + +b92ee12e8 2023-12-01 Jasem Mutlaq INDI drivers sync +e3e305a17 2023-12-01 John Evans Aberration Inspector Handbook Update +9aa0227e2 2023-12-01 John Evans Focus Guide Settle Bug +fd55f8939 2023-12-01 John Evans Scheduler hangs when Focus does not signal Autofocus start failure +a610e357c 2023-12-01 Joseph McGee Fixed a problem that prevented the exposure calculator file download function from finding new camera data files in github. +6bbb21618 2023-12-01 Toni Schriber Revise differential slewing +08c25289f 2023-11-30 Yuri Chornoivan Fix minor typo +323adaebb 2023-11-30 Yuri Chornoivan Fix minor typos +9d32a738e 2023-11-29 Jasem Mutlaq Send INDI status +9da16320f 2023-11-29 Joseph McGee Update handbook Ekos Capture to include docs for Exposure Calculator. Add... +097cc6c70 2023-11-28 Hy Murveit Bugfix in one-pulse dither. Dither pulses were going the wrong way. +a444f38a8 2023-11-28 Jasem Mutlaq Update dependencies and add contributor +ca9e3f73f 2023-11-27 Wolfgang Reissenberger Refactor placeholder matching +a2ac5c25e 2023-11-27 Wolfgang Reissenberger Bug fix reading initial pier and park states +d5235682a 2023-11-27 Wolfgang Reissenberger Bugfix clear gain and offset +482f86e07 2023-11-26 John Evans Focus timer bug fix +04f68ddfe 2023-11-24 Hy Murveit Bugfix: prevent possible ekos crash on indi camera driver crash +98cbe4386 2023-11-22 Antonio Escriban Protect from nullptr in SequenceJob::setISO() +e7a0564ed 2023-11-22 Wolfgang Reissenberger Protect against runtime exceptions when CCD driver crashes +5effccf71 2023-11-21 Hy Murveit Protect from nullptr in abortExposure +309f78b2e 2023-11-21 Yuri Chornoivan Fix minor typo +259ecd612 2023-11-21 Wolfgang Reissenberger Wall source as option, not as single action +a1613642d 2023-11-20 Hy Murveit Reduce latency between captures. +ed71dd8b5 2023-11-20 Jasem Mutlaq Remove problematic header +2d3033641 2023-11-20 Jasem Mutlaq Fix mode +452e5efc8 2023-11-20 Joseph McGee Improvements to the exposure calculator +1a8b29227 2023-11-19 Wolfgang Reissenberger Bug fix for pier side expression +ed6db110f 2023-11-19 Wolfgang Reissenberger Bug fix for creating signature expression +c6e538c7b 2023-11-17 Jasem Mutlaq Add qt5 visualization dependency +9d7eb02ea 2023-11-15 Hy Murveit Bugfix: guide start deviation was not saved properly in esq file. +b0d8db776 2023-11-13 John Evans Aberration Inspector +646b11a19 2023-11-12 Eric Dejouhanet CI: add DataViz lib, shift to builder image 0.12. +75d45b64e 2023-11-11 Hy Murveit Add a new not-default scheduler option to disable greedy scheduling. +0fe13494f 2023-11-11 Wolfgang Reissenberger Setting target name from mount slew +a7b2303f3 2023-11-10 Wolfgang Reissenberger Separating Business Logic from UI in Scheduler | step 2 +70d63fb0b 2023-11-09 John Evans DSLR Focus Movement Bug +a5e14795f 2023-11-09 Hy Murveit Add align logging for some solver failures and clean up error box. +15c5d08df 2023-11-08 Hy Murveit Fix bug in estimating job time, capture delays were misinterpreted. +fa87b9417 2023-11-08 Hy Murveit improve the hfr tooltip in fitsviewer +86d006547 2023-11-02 Yuri Chornoivan Fix minor typo +427a641f2 2023-11-01 Wolfgang Reissenberger Bug fix setting the target when reading an .esq file +cdf527598 2023-11-01 Wolfgang Reissenberger New placeholders for ISO, binning and pure exposure time added. +1732799f0 2023-10-30 Wolfgang Reissenberger Capture target job specific +6765a5104 2023-10-30 Jasem Mutlaq Add HFR to metadata +7301bedde 2023-10-29 Hy Murveit Switch FITSViewer Solver from Angle to Position Angle (PA). +68c8eb8b6 2023-10-28 Jasem Mutlaq Send telescope information for FITS header +f3db4e49b 2023-10-25 Hy Murveit Refactor header files to include only what is necessary-4 +7853caf45 2023-10-25 Brett Gottula Make "Set Coordinates Manually" dialog more intuitive +8012f616a 2023-10-25 Hy Murveit Refactor header files to include only what is necessary-3 +4df3da256 2023-10-24 Hy Murveit Refactor header files to include only what is necessary-2 +2f7ec7c1a 2023-10-24 Hy Murveit Refactor header files to include what is necessary-1 +54d9f1f6f 2023-10-22 Hy Murveit Add John as developer +430b4d6d4 2023-10-24 Wolfgang Reissenberger Separating Business Logic from UI in Scheduler | step 1 +28293212a 2023-10-24 Yuri Chornoivan Fix minor typo +bcf9478ef 2023-10-24 Jasem Mutlaq Make camera and scope-lens fields as required +d07b126fe 2023-10-23 Hy Murveit Update handbook align pages +7baa2b4f5 2023-10-22 Yuri Chornoivan Fix minor typo, enhance formatting for translations +1a7e12b9a 2023-10-21 Hy Murveit fix typo in handbook +a56cdba51 2023-10-21 Yuri Chornoivan Fix minor typos +4c56f06d8 2023-10-21 Yuri Chornoivan Fix XML +e575f8f50 2023-10-20 Hy Murveit Update handbook fitsviewer section and add new fitsviewer solver section. +7669ccff9 2023-10-17 John Evans Focus Analyze Bug +20b2cfe2a 2023-10-15 Jasem Mutlaq Prevent crash that might occur due to driver restart +87b19ad68 2023-10-14 Jasem Mutlaq Double check that camera object exists +3112260b6 2023-10-13 Jasem Mutlaq Only list data length not the whole buffer +2864f9bdb 2023-10-12 Jasem Mutlaq Fix capture calibration error +703825598 2023-10-12 Jasem Mutlaq Add exclusive group since you cannot select mount GOTO and mount park at the same time +4dae801b8 2023-10-11 Jasem Mutlaq Remove flat field source since it does not fit within optical trains model. When a train is selected, we know if dust caps or light sources are avai.. +79c17a4d9 2023-10-10 Jasem Mutlaq Initial work to use calibration pre actions instead of calibration source +966abde62 2023-10-12 Hy Murveit Fitsviewer solver +d88d6a5a0 2023-10-09 Wolfgang Reissenberger Bug fix setting signature when loading capture sequence +b36a78b02 2023-10-08 Jasem Mutlaq Separate connectSettings from connectSyncSettings when there are different non-sync signals involved +cfc274ad1 2023-10-08 Jasem Mutlaq Add separate check for canBin and canSubframe +36f65073b 2023-10-08 Jasem Mutlaq Fix issue where a race conditions on delayed properties might lead to undefined capture or transfer formats. Modify canBin and canSubframe to always.. +96559537e 2023-10-07 Jasem Mutlaq Prevent endless capture retries +4b7384e85 2023-10-07 Jasem Mutlaq Do not use system-wide abort which would crash the whole program +f2d8ea4f2 2023-10-07 Wolfgang Reissenberger Job sequence handling refactored +1960671b3 2023-10-07 Jasem Mutlaq Fix observatory icon as proposed by Steven Roger in #253 +aa59c63d1 2023-10-06 Eric Dejouhanet Clarify temperature regulation and where settings are kept. +42300ee5d 2023-10-05 Toni Schriber Deactivate autodefault property of [Align Option] pushbutton +a5c0639d2 2023-10-05 Toni Schriber Take care of standard range for PA when creating a sequence job +ea77383a0 2023-10-05 Jasem Mutlaq 3.6.8 development cycle + 3.6.7 (OVERLAY): 723c4743f 2023-09-30 Jasem Mutlaq INDI drivers sync diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/README.md kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/README.md --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/README.md 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/README.md 2023-12-03 05:23:16.000000000 +0000 @@ -10,7 +10,7 @@ ## Copyright -Copyright (c) 2001 - 2023 by The KStars Team: +Copyright (c) 2001 - 2024 by The KStars Team: KStars is Free Software, released under the GNU Public License. See COPYING for GPL license information. @@ -20,7 +20,7 @@ On Linux, it is available for most Linux distributions. -Latest stable version is v3.6.4 +Latest stable version is v3.6.8 ## Important URLs and files. @@ -89,12 +89,12 @@ The apt-add-respository command is needed for the apt-get's libstellarsolver-dev. Alternatively, you can skip the apt-add-repository, remove the libstellarsolver-dev from the apt-get, and build & install stellarsolver from https://github.com/rlancaste/stellarsolver. ``` sudo apt-add-repository ppa:mutlaqja/ppa -sudo apt-get -y install build-essential cmake git libstellarsolver-dev libxisf-dev libeigen3-dev libcfitsio-dev zlib1g-dev libindi-dev extra-cmake-modules libkf5plotting-dev libqt5svg5-dev libkf5xmlgui-dev libkf5kio-dev kinit-dev libkf5newstuff-dev libkf5doctools-dev libkf5notifications-dev qtdeclarative5-dev libkf5crash-dev gettext libnova-dev libgsl-dev libraw-dev libkf5notifyconfig-dev wcslib-dev libqt5websockets5-dev xplanet xplanet-images qt5keychain-dev libsecret-1-dev breeze-icon-theme +sudo apt-get -y install build-essential cmake git libstellarsolver-dev libxisf-dev libeigen3-dev libcfitsio-dev zlib1g-dev libindi-dev extra-cmake-modules libkf5plotting-dev libqt5svg5-dev libkf5xmlgui-dev libkf5kio-dev kinit-dev libkf5newstuff-dev libkf5doctools-dev libkf5notifications-dev qtdeclarative5-dev libkf5crash-dev gettext libnova-dev libgsl-dev libraw-dev libkf5notifyconfig-dev wcslib-dev libqt5websockets5-dev xplanet xplanet-images qt5keychain-dev libsecret-1-dev breeze-icon-theme libqt5datavisualization5-dev ``` Fedora ``` -yum install cfitsio-devel eigen3-devel stellarsolver-devel cmake extra-cmake-modules.noarch xisf-devel kf5-kconfig-devel kf5-kdbusaddons-devel kf5-kdoctools-devel kf5-kguiaddons-devel kf5-ki18n-devel kf5-kiconthemes-devel kf5-kinit-devel kf5-kio-devel kf5-kjobwidgets-devel kf5-knewstuff-devel kf5-kplotting-devel kf5-ktexteditor-devel kf5-kwidgetsaddons-devel kf5-kwindowsystem-devel kf5-kxmlgui-devel libindi-devel libindi-static qt5-qtdeclarative-devel qt5-qtmultimedia-devel qt5-qtsvg-devel wcslib-devel xplanet zlib-devel +yum install cfitsio-devel eigen3-devel stellarsolver-devel cmake extra-cmake-modules.noarch xisf-devel kf5-kconfig-devel kf5-kdbusaddons-devel kf5-kdoctools-devel kf5-kguiaddons-devel kf5-ki18n-devel kf5-kiconthemes-devel kf5-kinit-devel kf5-kio-devel kf5-kjobwidgets-devel kf5-knewstuff-devel kf5-kplotting-devel kf5-ktexteditor-devel kf5-kwidgetsaddons-devel kf5-kwindowsystem-devel kf5-kxmlgui-devel libindi-devel libindi-static qt5-qtdeclarative-devel qt5-qtmultimedia-devel qt5-qtdatavis3d-devel qt5-qtsvg-devel wcslib-devel xplanet zlib-devel ``` 3. Compiling @@ -392,6 +392,8 @@ * Hy Murveit * James Bowlin * Jérôme Sonrier +* John Evans +* Joseph McGee * Mark Hollomon * Martin Piskernig * Médéric Boquien diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/capture/test_placeholderpath.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/capture/test_placeholderpath.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/capture/test_placeholderpath.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/capture/test_placeholderpath.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -79,7 +79,7 @@ QString Filter, QString Type, QString Prefix, - QString RawPrefix, + QString TargetName, QString FilterEnabled, QString ExpEnabled, QString TimeStampEnabled, @@ -110,14 +110,15 @@ editXMLEle(ep, Type.toStdString().c_str()); } + if (!TargetName.isEmpty()) + { + ep = addXMLEle(root, "TargetName"); + editXMLEle(ep, TargetName.toStdString().c_str()); + } + if (!Prefix.isEmpty()) { ep = addXMLEle(root, "Prefix"); - if (!RawPrefix.isEmpty()) - { - subEP = addXMLEle(ep, "RawPrefix"); - editXMLEle(subEP, RawPrefix.toStdString().c_str()); - } if (!FilterEnabled.isEmpty()) { subEP = addXMLEle(ep, "FilterEnabled"); @@ -194,7 +195,6 @@ QFETCH(QString, Filter); QFETCH(QString, Type); QFETCH(QString, Prefix); - QFETCH(QString, RawPrefix); QFETCH(QString, FilterEnabled); QFETCH(QString, ExpEnabled); QFETCH(QString, FITSDirectory); @@ -208,7 +208,7 @@ Filter, Type, Prefix, - RawPrefix, + targetName, FilterEnabled, ExpEnabled, "", @@ -216,9 +216,9 @@ PlaceholderFormat, PlaceholderSuffix); - Ekos::SequenceJob job(root); + Ekos::SequenceJob job(root, targetName); auto placeholderPath = Ekos::PlaceholderPath(); - placeholderPath.processJobInfo(&job, targetName); + placeholderPath.processJobInfo(&job); QCOMPARE(job.getSignature(), signature); @@ -556,7 +556,7 @@ Filter, Type, Prefix, - RawPrefix, + targetName, FilterEnabled, ExpEnabled, TimeStampEnabled, @@ -564,15 +564,15 @@ PlaceholderFormat, PlaceholderSuffix); - Ekos::SequenceJob job(root); + Ekos::SequenceJob job(root, targetName); auto placeholderPath = Ekos::PlaceholderPath(seqFilename); bool bm = bool(batch_mode.toInt()); int i = nextSequenceID.toInt(); - QString filename = placeholderPath.generateSequenceFilename(job, targetName, true, bm, i, ".fits", ""); + QString filename = placeholderPath.generateSequenceFilename(job, true, bm, i, ".fits", ""); QVERIFY2(QRegularExpression(result).match(filename).hasMatch(), QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str()); - placeholderPath.setGenerateFilenameSettings(job, targetName); + placeholderPath.setGenerateFilenameSettings(job); filename = placeholderPath.generateOutputFilename(true, bm, i, ".fits", ""); QVERIFY2(QRegularExpression(result).match(filename).hasMatch(), QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str()); @@ -631,13 +631,13 @@ PlaceholderFormat, PlaceholderSuffix); - Ekos::SequenceJob job(root); + Ekos::SequenceJob job(root, ""); auto placeholderPath = Ekos::PlaceholderPath(""); bool bm = false; int i = nextSequenceID.toInt(); - QString filename = placeholderPath.generateSequenceFilename(job, "", true, bm, i, ".fits", "", true); + QString filename = placeholderPath.generateSequenceFilename(job, true, bm, i, ".fits", "", true); QCOMPARE(filename, result); - placeholderPath.setGenerateFilenameSettings(job, ""); + placeholderPath.setGenerateFilenameSettings(job); filename = placeholderPath.generateOutputFilename(true, bm, i, ".fits", "", true); QCOMPARE(filename, result); #endif @@ -719,7 +719,6 @@ QFETCH(QString, Filter); QFETCH(QString, Type); QFETCH(QString, Prefix); - QFETCH(QString, RawPrefix); QFETCH(QString, FilterEnabled); QFETCH(QString, ExpEnabled); QFETCH(QString, TimeStampEnabled); @@ -734,7 +733,7 @@ Filter, Type, Prefix, - RawPrefix, + targetName, FilterEnabled, ExpEnabled, TimeStampEnabled, @@ -742,16 +741,16 @@ PlaceholderFormat, "1"); - Ekos::SequenceJob job(root); + Ekos::SequenceJob job(root, targetName); auto placeholderPath = Ekos::PlaceholderPath(seqFilename); bool bm = true; - placeholderPath.setGenerateFilenameSettings(job, targetName); + placeholderPath.setGenerateFilenameSettings(job); int nextSequenceID; for (int id = 1; id < 4; id++) { - nextSequenceID = placeholderPath.getCompletedFiles(job, targetName); + nextSequenceID = placeholderPath.getCompletedFiles(job); QCOMPARE(nextSequenceID, id - 1); - nextSequenceID = placeholderPath.checkSeqBoundary(job, targetName); + nextSequenceID = placeholderPath.checkSeqBoundary(job); QCOMPARE(nextSequenceID, id); QString filename = placeholderPath.generateOutputFilename(true, bm, id, ".fits", ""); QDir path; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/capture/test_sequencejobstate.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/capture/test_sequencejobstate.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/capture/test_sequencejobstate.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/capture/test_sequencejobstate.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -43,10 +43,9 @@ connect(m_stateMachine, &Ekos::SequenceJobState::setCCDBatchMode, m_adapter, &TestAdapter::setCCDBatchMode); connect(m_adapter, &TestAdapter::newRotatorAngle, m_stateMachine, &Ekos::SequenceJobState::setCurrentRotatorPositionAngle); connect(m_adapter, &TestAdapter::newCCDTemperature, m_stateMachine, &Ekos::SequenceJobState::setCurrentCCDTemperature); - connect(m_adapter, &TestAdapter::newGuiderDrift, m_stateMachine, &Ekos::SequenceJobState::setCurrentGuiderDrift); // start the capture preparation - m_stateMachine->prepareLightFrameCapture(enforce_temperature, false, isPreview); + m_stateMachine->prepareLightFrameCapture(enforce_temperature, isPreview); // The test adapter is simulates the behavior of real devices QTRY_VERIFY_WITH_TIMEOUT(m_adapter->isCapturePreparationComplete, 5000); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/mockmodules.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/mockmodules.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/mockmodules.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/mockmodules.h 2023-12-03 05:23:16.000000000 +0000 @@ -204,9 +204,9 @@ public: MockCapture(); Q_SCRIPTABLE Q_NOREPLY void clearAutoFocusHFR() {} - Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, bool ignoreTarget = false) + Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, QString targetName = "") { - Q_UNUSED(ignoreTarget) + Q_UNUSED(targetName) fprintf(stderr, "%d @@@MockCapture::loadSequenceQueue(%s)\n", __LINE__, fileURL.toLatin1().data()); m_fileURL = fileURL; return true; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/org.kde.mockkstars.MockEkos.MockCapture.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/org.kde.mockkstars.MockEkos.MockCapture.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/org.kde.mockkstars.MockEkos.MockCapture.xml 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/org.kde.mockkstars.MockEkos.MockCapture.xml 2023-12-03 05:23:16.000000000 +0000 @@ -15,7 +15,7 @@ - + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_align.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_align.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_align.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_align.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -14,6 +14,7 @@ #include "mountmodel.h" #include "Options.h" #include "indi/guimanager.h" +#include "ekos/align/align.h" #include "skymapcomposite.h" @@ -400,9 +401,9 @@ Ekos::Scheduler *scheduler = ekos->schedulerModule(); // start ASAP TestEkosSchedulerHelper::StartupCondition startupCondition; - startupCondition.type = SchedulerJob::START_ASAP; + startupCondition.type = Ekos::START_ASAP; TestEkosSchedulerHelper::CompletionCondition completionCondition; - completionCondition.type = SchedulerJob::FINISH_SEQUENCE; + completionCondition.type = Ekos::FINISH_SEQUENCE; // create the capture sequence file const QString sequenceFile = TestEkosSchedulerHelper::getDefaultEsqContent(); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -13,6 +13,7 @@ #include "kstars_ui_tests.h" #include "test_ekos.h" #include "test_ekos_simulator.h" +#include "ekos/capture/capture.h" TestEkosCapture::TestEkosCapture(QObject *parent) : QObject(parent) { @@ -150,7 +151,7 @@ QVERIFY(destination.autoRemove()); // Add five exposures - KTRY_CAPTURE_ADD_LIGHT(0.1, 5, 0, "Red", destination.path()); + KTRY_CAPTURE_ADD_LIGHT(0.1, 5, 0, "Red", "test", destination.path()); // Start capturing and wait for procedure to end (visual icon changing) KTRY_CAPTURE_GADGET(QPushButton, startB); @@ -173,7 +174,7 @@ QVERIFY(destination.autoRemove()); // Add an exposure - KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 0, "Red", destination.path()); + KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 0, "Red", "test", destination.path()); // Start capturing and wait for procedure to end (visual icon changing) KTRY_CAPTURE_GADGET(QPushButton, startB); @@ -184,7 +185,7 @@ // Verify a FITS file was created QTRY_VERIFY_WITH_TIMEOUT(m_CaptureHelper->searchFITS(QDir(destination.path())).count() == 1, 1000); - QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].startsWith("Light_")); + QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].startsWith("test_Light_")); QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].endsWith("001.fits")); // Reset sequence state - this makes a confirmation dialog appear @@ -209,9 +210,9 @@ // Verify an additional FITS file was created - asynchronously eventually QTRY_VERIFY_WITH_TIMEOUT(m_CaptureHelper->searchFITS(QDir(destination.path())).count() == 2, 2000); - QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].startsWith("Light_")); + QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].startsWith("test_Light_")); QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[0].endsWith("001.fits")); - QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[1].startsWith("Light_")); + QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[1].startsWith("test_Light_")); QVERIFY(m_CaptureHelper->searchFITS(QDir(destination.path()))[1].endsWith("002.fits")); // TODO: test storage options @@ -225,11 +226,11 @@ QVERIFY(destination.autoRemove()); // Add a few exposures - KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 0, "Red", destination.path() + "/%T"); - KTRY_CAPTURE_ADD_LIGHT(0.7, 2, 0, "SII", destination.path() + "/%T"); - KTRY_CAPTURE_ADD_LIGHT(0.2, 5, 0, "Green", destination.path() + "/%T"); - KTRY_CAPTURE_ADD_LIGHT(0.9, 2, 0, "Luminance", destination.path() + "/%T"); - KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 1, "H_Alpha", destination.path() + "/%T"); + KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 0, "Red", "test", destination.path() + "/%T"); + KTRY_CAPTURE_ADD_LIGHT(0.7, 2, 0, "SII", "test", destination.path() + "/%T"); + KTRY_CAPTURE_ADD_LIGHT(0.2, 5, 0, "Green", "test", destination.path() + "/%T"); + KTRY_CAPTURE_ADD_LIGHT(0.9, 2, 0, "Luminance", "test", destination.path() + "/%T"); + KTRY_CAPTURE_ADD_LIGHT(0.5, 1, 1, "H_Alpha", "test", destination.path() + "/%T"); QWARN("A sequence of exposures under 1 second will always take 1 second to capture each of them."); //size_t const duration = (500+0)*1+(700+0)*2+(200+0)*5+(900+0)*2+(500+1000)*1; size_t const duration = 1000 * (1 + 2 + 5 + 2 + 1); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -12,7 +12,7 @@ #include "test_ekos.h" #include "Options.h" #include "ekos/auxiliary/opticaltrainmanager.h" - +#include "ekos/capture/capture.h" #include "test_ekos_capture_helper.h" /* ***************************************************************************** @@ -61,7 +61,7 @@ expectedSchedulerStates.enqueue(Ekos::SCHEDULER_IDLE); KTELL("Prepare scheduler captures"); - QVERIFY(prepareScheduledCapture(SchedulerJob::FINISH_REPEAT)); + QVERIFY(prepareScheduledCapture(Ekos::FINISH_REPEAT)); KTELL("Start scheduler job"); KTRY_CLICK(Ekos::Manager::Instance()->schedulerModule(), startB); @@ -79,7 +79,7 @@ void TestEkosCaptureCount::testSchedulerCaptureInfiteLooping() { // prepare captured frames - QVERIFY(prepareScheduledCapture(SchedulerJob::FINISH_LOOP)); + QVERIFY(prepareScheduledCapture(Ekos::FINISH_LOOP)); } /* ********************************************************************************* @@ -271,7 +271,7 @@ return true; } -bool TestEkosCaptureCount::prepareScheduledCapture(SchedulerJob::CompletionCondition completionCondition) +bool TestEkosCaptureCount::prepareScheduledCapture(Ekos::CompletionCondition completionCondition) { QFETCH(double, exptime); QFETCH(QString, sequence); @@ -328,7 +328,7 @@ } bool TestEkosCaptureCount::setupScheduler(QString sequenceFile, QString sequence, QString capturedFramesMap, - SchedulerJob::CompletionCondition completionCondition, + Ekos::CompletionCondition completionCondition, int iterations, bool rememberJobProgress, double exptime) { Ekos::Scheduler *scheduler = Ekos::Manager::Instance()->schedulerModule(); @@ -354,12 +354,12 @@ // set the completion condition switch (completionCondition) { - case SchedulerJob::FINISH_REPEAT: + case Ekos::FINISH_REPEAT: // repeat the job for a fixed amount KTRY_SET_RADIOBUTTON_SUB(scheduler, repeatCompletionR, true); KTRY_SET_SPINBOX_SUB(scheduler, repeatsSpin, iterations); break; - case SchedulerJob::FINISH_LOOP: + case Ekos::FINISH_LOOP: KTRY_SET_RADIOBUTTON_SUB(scheduler, loopCompletionR, true); break; default: @@ -379,7 +379,7 @@ } bool TestEkosCaptureCount::verifySchedulerCounting(QString sequence, QString capturedFramesMap, - SchedulerJob::CompletionCondition completionCondition, + Ekos::CompletionCondition completionCondition, int iterations, bool rememberJobProgress, double exptime) { Ekos::Scheduler *scheduler = Ekos::Manager::Instance()->schedulerModule(); @@ -392,7 +392,7 @@ int total = -1, captured = -1, total_repeat_expected = 0; // check display of expected frames - if (completionCondition == SchedulerJob::FINISH_REPEAT) + if (completionCondition == Ekos::FINISH_REPEAT) { total = displayedCounts.right(displayedCounts.length() - displayedCounts.indexOf("/") - 1).toInt(); total_repeat_expected = totalCount(sequence) * iterations; @@ -420,12 +420,13 @@ captured_expected).toStdString().c_str()); // check estimated duration time (only relevant for repeats - if (completionCondition == SchedulerJob::FINISH_REPEAT) + if (completionCondition == Ekos::FINISH_REPEAT) { - QString estimation = queueTable->item(0, 7)->text(); - QTime estimatedDuration = QTime::fromString(estimation, "HH:mm:ss"); - int duration = estimatedDuration.second() + 60 * estimatedDuration.minute() + 3600 * estimatedDuration.hour(); - KVERIFY2_SUB(std::fabs((total_repeat_expected - captured_expected)*exptime - duration) <= 1, + QTime startTime = QTime::fromString(queueTable->item(0, 4)->text(), "HH:mm"); + QTime endTime = QTime::fromString(queueTable->item(0, 5)->text().right(5), "HH:mm"); + + int duration = startTime.secsTo(endTime); + KVERIFY2_SUB(std::fabs((total_repeat_expected - captured_expected)*exptime - duration) <= 60, QString("Scheduler job table shows %1 seconds expected instead of %2.").arg(duration).arg(( total_repeat_expected - captured_expected)*exptime).toStdString().c_str()); } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_count.h 2023-12-03 05:23:16.000000000 +0000 @@ -38,7 +38,7 @@ * @param completionCondition completion condition for the scheduler * @return true iff preparation was successful */ - bool prepareScheduledCapture(SchedulerJob::CompletionCondition completionCondition); + bool prepareScheduledCapture(Ekos::CompletionCondition completionCondition); /** * @brief Prepare the scheduler for the test. @@ -51,7 +51,7 @@ * @param exptime exposure time (identical for all frames) * @return true iff preparation was successful */ - bool setupScheduler(QString sequenceFile, QString sequence, QString capturedFramesMap, SchedulerJob::CompletionCondition completionCondition, + bool setupScheduler(QString sequenceFile, QString sequence, QString capturedFramesMap, Ekos::CompletionCondition completionCondition, int iterations, bool rememberJobProgress, double exptime); /** @@ -64,7 +64,7 @@ * @param exptime exposure time (identical for all frames) * @return true iff the displayed counts match the specification */ - bool verifySchedulerCounting(QString sequence, QString capturedFramesMap, SchedulerJob::CompletionCondition completionCondition, + bool verifySchedulerCounting(QString sequence, QString capturedFramesMap, Ekos::CompletionCondition completionCondition, int iterations, bool rememberJobProgress, double exptime); /** diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -10,6 +10,8 @@ #include "test_ekos.h" #include "ekos/capture/scriptsmanager.h" +#include "ekos/capture/capture.h" +#include "ekos/scheduler/scheduler.h" #include "Options.h" TestEkosCaptureHelper::TestEkosCaptureHelper(QString guider) : TestEkosHelper(guider) {} @@ -154,10 +156,9 @@ KVERIFY_SUB(value.indexOf(":") > -1); QString filter = value.left(value.indexOf(":")); int count = value.right(value.length() - value.indexOf(":") - 1).toInt(); - Ekos::Manager::Instance()->captureModule()->setTargetName(target); KTRY_SET_LINEEDIT_SUB(Ekos::Manager::Instance()->captureModule(), placeholderFormatT, format); if (count > 0) - KWRAP_SUB(KTRY_CAPTURE_ADD_LIGHT(exptime, count, delay, filter, fitsDirectory)); + KWRAP_SUB(KTRY_CAPTURE_ADD_LIGHT(exptime, count, delay, filter, target, fitsDirectory)); // ensure that no old values are present Ekos::Manager::Instance()->captureModule()->setCapturedFramesMap(calculateSignature(target, filter, fitsDirectory), 0); } @@ -183,34 +184,36 @@ Ekos::Manager::Instance()->schedulerModule()->removeAllJobs(); } -QStringList TestEkosCaptureHelper::getSimpleEsqContent(CaptureSettings settings, QVector jobs) +QStringList TestEkosCaptureHelper::getSimpleEsqContent(CaptureSettings settings, QVector jobs, + ESQVersion version) { - QStringList result = serializeGeneralSettings(settings); + QStringList result = serializeGeneralSettings(settings, version); for (QVector::iterator job_iter = jobs.begin(); job_iter != jobs.end(); job_iter++) - result.append(serializeJob(*job_iter)); + result.append(serializeJob(*job_iter, version)); result.append(""); return result; } -QStringList TestEkosCaptureHelper::getSimpleEsqContent(CaptureSettings settings, QVector jobs) +QStringList TestEkosCaptureHelper::getSimpleEsqContent(CaptureSettings settings, QVector jobs, + ESQVersion version) { - QStringList result = serializeGeneralSettings(settings); + QStringList result = serializeGeneralSettings(settings, version); for (QVector::iterator job_iter = jobs.begin(); job_iter != jobs.end(); job_iter++) - result.append(serializeJob(*job_iter)); + result.append(serializeJob(*job_iter, version)); result.append(""); return result; } -QStringList TestEkosCaptureHelper::serializeGeneralSettings(CaptureSettings settings) +QStringList TestEkosCaptureHelper::serializeGeneralSettings(CaptureSettings settings, ESQVersion version) { QStringList result({"", - "CCD Simulator", + QString("CCD Simulator").arg(esqVersionNames[version]), "CCD Simulator", QString("%1").arg(settings.observer), QString("%2").arg(settings.guideDeviation.enabled ? "true" : "false").arg(settings.guideDeviation.value), @@ -223,7 +226,8 @@ return result; } -QStringList TestEkosCaptureHelper::serializeJob(const TestEkosCaptureHelper::SimpleCaptureLightsJob &job) +QStringList TestEkosCaptureHelper::serializeJob(const TestEkosCaptureHelper::SimpleCaptureLightsJob &job, + ESQVersion version) { QStringList result({"", QString("%1").arg(job.exposureTime), @@ -235,24 +239,47 @@ QString("%1").arg(job.filterName), QString("%1").arg(job.type), QString("%1").arg(job.count), - QString("%1").arg(job.delayMS / 1000), - QString("%1").arg(job.placeholderFormat), - QString("%1").arg(job.formatSuffix), - QString("%1").arg(job.fitsDirectory), - QString("%1").arg(job.uploadMode), - "", - "", - "Manual", - "ADU150001000", - "False", - "False", - "", - ""}); + QString("%1").arg(job.delayMS / 1000)}); + switch (version) + { + case ESQ_VERSION_2_4: + result.append(QString("%1").arg(job.targetName)); + case ESQ_VERSION_2_5: + // no target specified + break; + case ESQ_VERSION_2_6: + result.append(QString("%1").arg(job.targetName)); + break; + } + result.append({QString("%1").arg(job.placeholderFormat), + QString("%1").arg(job.formatSuffix), + QString("%1").arg(job.fitsDirectory), + QString("%1").arg(job.uploadMode), + "", + ""}); + switch (version) + { + case ESQ_VERSION_2_4: + case ESQ_VERSION_2_5: + result.append({"Manual", + "ADU150001000", + "False", + "False", + "", + ""}); + break; + case ESQ_VERSION_2_6: + result.append({QString("%1").arg(0), + "ADU150001000", + "", + ""}); + break; + } return result; } -QStringList TestEkosCaptureHelper::serializeJob(const SimpleCaptureCalibratingJob &job) +QStringList TestEkosCaptureHelper::serializeJob(const SimpleCaptureCalibratingJob &job, ESQVersion version) { QStringList result({"", QString("%1").arg(job.exposureTime), @@ -272,29 +299,43 @@ "", ""}); - if (job.src_manual) - result.append(QString("%1").arg(FlatFieldSourceNames[SOURCE_MANUAL])); - else if (job.src_buildin_light) - result.append(QString("%1").arg(FlatFieldSourceNames[SOURCE_FLATCAP])); - else if (job.src_external_light) - result.append(QString("%1").arg(FlatFieldSourceNames[SOURCE_DARKCAP])); - else if (job.src_wall) - result.append({QString("%1").arg(FlatFieldSourceNames[SOURCE_WALL]), - QString("%1").arg(job.wall_az), - QString("%1").arg(job.wall_alt), - QString("")}); + switch (version) + { + case ESQ_VERSION_2_4: + case ESQ_VERSION_2_5: + if (job.preAction & ACTION_WALL) + { + result.append("Wall"); + result.append(QString("%1").arg(job.wall_az)); + result.append(QString("%1").arg(job.wall_alt)); + result.append(QString("")); + } + else + result.append("Manual"); + + result.append({QString("%1").arg((job.preAction & ACTION_PARK_MOUNT) > 0 ? "True" : "False"), + QString("%1").arg((job.preAction & ACTION_PARK_DOME) > 0 ? "True" : "False")}); + break; + + case ESQ_VERSION_2_6: + result.append(QString("%1").arg(job.preAction)); + if (job.preAction & ACTION_WALL) + result.append({QString("%1").arg(job.wall_az), + QString("%1").arg(job.wall_alt)}); + result.append(""); + break; + } result.append(""); if (job.duration_manual) result.append("Manual"); else if (job.duration_adu) result.append(QString("ADU%1%2").arg(job.adu).arg(job.tolerance)); - result.append(""); - result.append({QString("%1").arg(job.park_mount ? "True" : "False"), - QString("%1").arg(job.park_dome ? "True" : "False"), + + result.append({"", "", - "" - }); + ""}); + return result; } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_helper.h 2023-12-03 05:23:16.000000000 +0000 @@ -75,9 +75,10 @@ * @param count is the number of exposures to execute. * @param delay is the delay after exposure. * @param filter is the filter name to set. + * @param target name of the target. * @param destination is the folder to store fames to. */ -#define KTRY_CAPTURE_CONFIGURE_FRAME(frametype, exposure, count, delay, filter, destination) do { \ +#define KTRY_CAPTURE_CONFIGURE_FRAME(frametype, exposure, count, delay, filter, target, destination) do { \ KTRY_CAPTURE_GADGET(QDoubleSpinBox, captureExposureN); \ captureExposureN->setValue(static_cast(exposure)); \ KTRY_CAPTURE_GADGET(QSpinBox, captureCountN); \ @@ -88,6 +89,8 @@ KTRY_CAPTURE_COMBO_SET(captureTypeS, frametype); \ KTRY_CAPTURE_GADGET(QComboBox, FilterPosCombo); \ KTRY_CAPTURE_COMBO_SET(FilterPosCombo, (filter)); \ + KTRY_CAPTURE_GADGET(QLineEdit, targetNameT); \ + targetNameT->setText(target); \ KTRY_CAPTURE_GADGET(QLineEdit, fileDirectoryT); \ fileDirectoryT->setText(destination); } while(false) @@ -97,12 +100,13 @@ * @param count is the number of exposures to execute. * @param delay is the delay after exposure. * @param filter is the filter name to set. + * @param target name of the target. * @param destination is the folder to store fames to. */ -#define KTRY_CAPTURE_ADD_FRAME(frametype, exposure, count, delay, filter, destination) do { \ +#define KTRY_CAPTURE_ADD_FRAME(frametype, exposure, count, delay, filter, target, destination) do { \ KTRY_CAPTURE_GADGET(QTableWidget, queueTable); \ int const jcount = queueTable->rowCount(); \ - KTRY_CAPTURE_CONFIGURE_FRAME(frametype, exposure, count, delay, filter, destination); \ + KTRY_CAPTURE_CONFIGURE_FRAME(frametype, exposure, count, delay, filter, target, destination); \ KTRY_CAPTURE_CLICK(addToQueueB); \ QTRY_VERIFY_WITH_TIMEOUT(queueTable->rowCount() == (jcount+1), 1000); } while(false); @@ -112,20 +116,22 @@ * @param count is the number of exposures to execute. * @param delay is the delay after exposure. * @param filter is the filter name to set. + * @param target name of the target. * @param destination is the folder to store fames to. */ -#define KTRY_CAPTURE_CONFIGURE_LIGHT(exposure, count, delay, filter, destination) \ - KTRY_CAPTURE_CONFIGURE_FRAME("Light", exposure, count, delay, filter, destination) +#define KTRY_CAPTURE_CONFIGURE_LIGHT(exposure, count, delay, filter, target, destination) \ + KTRY_CAPTURE_CONFIGURE_FRAME("Light", exposure, count, delay, filter, target, destination) /** @brief Helper to add a Light frame to a Capture job. * @param exposure is the exposure duration. * @param count is the number of exposures to execute. * @param delay is the delay after exposure. * @param filter is the filter name to set. + * @param target name of the target. * @param destination is the folder to store fames to. */ -#define KTRY_CAPTURE_ADD_LIGHT(exposure, count, delay, filter, destination) \ - KTRY_CAPTURE_ADD_FRAME("Light", exposure, count, delay, filter, destination) +#define KTRY_CAPTURE_ADD_LIGHT(exposure, count, delay, filter, target, destination) \ + KTRY_CAPTURE_ADD_FRAME("Light", exposure, count, delay, filter, target, destination) /** @brief Helper to configure a Flat frame. @@ -136,7 +142,7 @@ * @param destination is the folder to store fames to. */ #define KTRY_CAPTURE_CONFIGURE_FLAT(exposure, count, delay, filter, destination) \ - KTRY_CAPTURE_CONFIGURE_FRAME("Flat", exposure, count, delay, filter, destination) + KTRY_CAPTURE_CONFIGURE_FRAME("Flat", exposure, count, delay, filter, "", destination) /** @brief Helper to add a flat frame to a Capture job. * @param exposure is the exposure duration. @@ -146,7 +152,7 @@ * @param destination is the folder to store fames to. */ #define KTRY_CAPTURE_ADD_FLAT(exposure, count, delay, filter, destination) \ - KTRY_CAPTURE_ADD_FRAME("Flat", exposure, count, delay, filter, destination) + KTRY_CAPTURE_ADD_FRAME("Flat", exposure, count, delay, filter, "", destination) @@ -165,6 +171,14 @@ double value = 0; }; + typedef enum { + ESQ_VERSION_2_4, + ESQ_VERSION_2_5, + ESQ_VERSION_2_6 + } ESQVersion; + + const QList esqVersionNames = {"2.4", "2.5", "2.6"}; + struct CaptureSettings { QString observer = ""; OptDouble guideDeviation, startGuideDeviation; @@ -175,6 +189,7 @@ struct SimpleCaptureLightsJob { + ESQVersion version = ESQ_VERSION_2_6; int exposureTime = 1.0; int count = 1; int delayMS = 0; // delay in milliseconds @@ -183,6 +198,7 @@ QString filterName = "Luminance"; QString type = "Light"; QString encoding = "FITS"; + QString targetName = "test"; QString fitsDirectory = "/home/pi"; QString placeholderFormat = "/%t/%T/%F/%t_%T_%F_%e_%D"; int formatSuffix = 3; @@ -192,14 +208,14 @@ struct SimpleCaptureCalibratingJob { + ESQVersion version = ESQ_VERSION_2_6; int exposureTime = 1.0; QString type = "Flat"; int count = 1; - bool src_manual = true, src_buildin_light = false, src_external_light = false, src_wall = false; + uint preAction = 0; double wall_az = 90, wall_alt = 0; bool duration_manual = true, duration_adu = false; int adu = 10000, tolerance = 1000; - bool park_mount = false, park_dome = false; }; explicit TestEkosCaptureHelper(QString guider = nullptr); @@ -252,32 +268,34 @@ * @brief getSimpleEsqContent Create a simple lights capture sequence file * @param settings overall settings * @param jobs list of sequence jobs + * @param version file version * @return XML string list */ - QStringList getSimpleEsqContent(CaptureSettings settings, QVector jobs); + QStringList getSimpleEsqContent(CaptureSettings settings, QVector jobs, ESQVersion version = ESQ_VERSION_2_6); /** * @brief getSimpleEsqContent Create a simple flats capture sequence file * @param settings overall settings * @param jobs list of sequence jobs + * @param version file version * @return XML string list */ - QStringList getSimpleEsqContent(CaptureSettings settings, QVector jobs); + QStringList getSimpleEsqContent(CaptureSettings settings, QVector jobs, ESQVersion version = ESQ_VERSION_2_6); /** * @brief serializeGeneralSettings Create the XML representation of the general settings */ - QStringList serializeGeneralSettings(CaptureSettings settings); + QStringList serializeGeneralSettings(CaptureSettings settings, ESQVersion version = ESQ_VERSION_2_6); /** * @brief serializeJob Create the XML representation of a single lights job */ - QStringList serializeJob(const SimpleCaptureLightsJob &job); + QStringList serializeJob(const SimpleCaptureLightsJob &job, ESQVersion version = ESQ_VERSION_2_6); /** * @brief serializeJob Create the XML representation of a single flats job */ - QStringList serializeJob(const SimpleCaptureCalibratingJob &job); + QStringList serializeJob(const SimpleCaptureCalibratingJob &job, ESQVersion version = ESQ_VERSION_2_6); /** * @brief calculateSignature Calculate the signature of a given filter diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -15,6 +15,7 @@ #include "Options.h" #include "skymapcomposite.h" #include "ekos/capture/sequencejobstate.h" +#include "ekos/capture/capture.h" #define SHUTTER_UNKNOWN -1 #define SHUTTER_NO 0 @@ -173,9 +174,9 @@ QVERIFY2(success, "Scripts set up failed!"); // create capture sequences - KTRY_CAPTURE_CONFIGURE_LIGHT(2.0, count, 0.0, "Luminance", imagepath); + KTRY_CAPTURE_CONFIGURE_LIGHT(2.0, count, 0.0, "Luminance", "test", imagepath); KTRY_CAPTURE_CLICK(addToQueueB); - KTRY_CAPTURE_CONFIGURE_LIGHT(2.0, count, 0.0, "Red", imagepath); + KTRY_CAPTURE_CONFIGURE_LIGHT(2.0, count, 0.0, "Red", "test", imagepath); KTRY_CAPTURE_CLICK(addToQueueB); // check if row has been added KTRY_CAPTURE_GADGET(QTableWidget, queueTable); @@ -235,10 +236,10 @@ // add target to path to emulate the behavior of the scheduler QString imagepath = getImageLocation()->path() + "/test"; // build a LRGB sequence - KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Luminance", imagepath); - KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Red", imagepath); - KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Green", imagepath); - KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Blue", imagepath); + KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Luminance", "test", imagepath); + KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Red", "test", imagepath); + KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Green", "test", imagepath); + KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Blue", "test", imagepath); // set a position in the west SkyPoint *target = new SkyPoint(); @@ -294,7 +295,7 @@ // add target to path to emulate the behavior of the scheduler QString imagepath = getImageLocation()->path() + "/test"; // build a simple 5xL sequence - KTRY_CAPTURE_ADD_LIGHT(45.0, 5, 5.0, "Luminance", imagepath); + KTRY_CAPTURE_ADD_LIGHT(45.0, 5, 5.0, "Luminance", "", imagepath); // set Dubhe as target and slew there SkyObject *target = KStars::Instance()->data()->skyComposite()->findByName("Dubhe"); m_CaptureHelper->slewTo(target->ra().Hours(), target->dec().Degrees(), true); @@ -420,7 +421,7 @@ KTRY_SET_CHECKBOX(capture, cameraTemperatureS, true); // build a simple 1xL sequence - KTRY_CAPTURE_ADD_LIGHT(10.0, 5, 5.0, "Luminance", getImageLocation()->path() + "/test"); + KTRY_CAPTURE_ADD_LIGHT(10.0, 5, 5.0, "Luminance", "test", getImageLocation()->path() + " / test"); // expect capturing state m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_CAPTURING); @@ -478,6 +479,7 @@ // default initialization QVERIFY(prepareTestCase()); + QSKIP("Skipping test after UI rework"); // switch to capture module Ekos::Capture *capture = Ekos::Manager::Instance()->captureModule(); @@ -499,7 +501,7 @@ KTRY_SET_CHECKBOX(rotatorDialog, enforceJobPA, true); // build a simple 1xL sequence - KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Luminance", getImageLocation()->path() + "/test"); + KTRY_CAPTURE_ADD_LIGHT(30.0, 1, 5.0, "Luminance", "test", getImageLocation()->path() + "/test"); // expect capturing state m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_CAPTURING); @@ -533,23 +535,20 @@ // switch capture type to flat so that we can set the calibration KTRY_SET_COMBO(capture, captureTypeS, "Flat"); - - // select manual flat method - KTRY_SELECT_FLAT_METHOD(manualSourceC, false, false); // ensure that the filter wheel is configured KTRY_CAPTURE_GADGET(QComboBox, FilterPosCombo); // wait until filter combo box is filled QTRY_VERIFY_WITH_TIMEOUT(FilterPosCombo->count() > 0, 60000); // build a simple 1xL flat sequence - KTRY_CAPTURE_ADD_FRAME("Flat", 1, 1, 0.0, "Luminance", imagepath); + KTRY_CAPTURE_ADD_FRAME("Flat", 1, 1, 0.0, "Luminance", "test", imagepath); // build a simple 1xL light sequence - KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", imagepath); + KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", "test", imagepath); // click OK or Cancel? QFETCH(bool, clickModalOK); QFETCH(bool, clickModal2OK); if (clickModalOK) { - // start the flat/dark/bias sequence + // Expect a capture sequence m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_IMAGE_RECEIVED); m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_IDLE); KTRY_CLICK(capture, startB); @@ -618,15 +617,10 @@ KTRY_SET_COMBO(capture, captureTypeS, frametype); // select internal or external flat light - QFETCH(bool, internalLight); - if (internalLight == true) - KTRY_SELECT_FLAT_METHOD(flatDeviceSourceC, false, false); - else - KTRY_SELECT_FLAT_METHOD(darkDeviceSourceC, false, false); // build a simple 1xL sequence - KTRY_CAPTURE_ADD_FRAME(frametype, 1, 1, 0.0, "Luminance", imagepath); + KTRY_CAPTURE_ADD_FRAME(frametype, 1, 1, 0.0, "Luminance", "test", imagepath); // build a simple 1xL light sequence - KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", imagepath); + KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", "test", imagepath); // start the sequence m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_IMAGE_RECEIVED); @@ -641,7 +635,8 @@ void TestEkosCaptureWorkflow::testDustcapSource() { - // use the Flip Flat in simulator mode + // use the Flip Flat in simulator mode both as light source and as dust cap + m_CaptureHelper->m_DustCapDevice = "Flip Flat"; m_CaptureHelper->m_LightPanelDevice = "Flip Flat"; Ekos::Manager * const ekos = Ekos::Manager::Instance(); @@ -662,8 +657,7 @@ // park SET_INDI_VALUE_SWITCH("Flip Flat", "CAP_PARK", "PARK", true); // turn light off - SET_INDI_VALUE_SWITCH("Flip Flat", "FLAT_LIGHT_CONTROL", "FLAT_LIGHT_OFF", - true); + SET_INDI_VALUE_SWITCH("Flip Flat", "FLAT_LIGHT_CONTROL", "FLAT_LIGHT_OFF", true); // Now all devices should be up and running QTRY_VERIFY_WITH_TIMEOUT(Ekos::Manager::Instance()->indiStatus() == Ekos::Success, 10000); @@ -671,6 +665,9 @@ // init the helper m_CaptureHelper->init(); + // prepare optical trains for testing + m_CaptureHelper->prepareOpticalTrains(); + // receive status updates from all devices m_CaptureHelper->connectModules(); @@ -686,18 +683,12 @@ QTRY_VERIFY_WITH_TIMEOUT(captureTypeS->findText("Flat", Qt::MatchExactly) >= 0, 5000); // select frame type and internal or external flat light - QFETCH(bool, internalLight); QFETCH(QString, frametype); - if (internalLight == true) - KTRY_SELECT_FLAT_METHOD(flatDeviceSourceC, false, false); - else - KTRY_SELECT_FLAT_METHOD(darkDeviceSourceC, false, false); - - // build a simple 1xL flat sequence - KTRY_CAPTURE_ADD_FRAME(frametype, 1, 1, 0.0, "Luminance", imagepath); + // build a simple 1xL sequence + KTRY_CAPTURE_ADD_FRAME(frametype, 1, 1, 0.0, "Luminance", "test", imagepath); // build a simple 1xL light sequence - KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", imagepath); + KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", "test", imagepath); // start the sequence m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_IMAGE_RECEIVED); @@ -733,15 +724,15 @@ // determine frame type QFETCH(QString, frametype); // build a simple 1xL sequence - KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", imagepath); + KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", "test", imagepath); // build a simple 1xL light sequence - KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", imagepath); + KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", "test", imagepath); // switch capture type to flat so that we can set the calibration captureTypeS->setCurrentText("Flat"); // add another sequence to check if wall source may be used twice // select another wall position as flat light source (az=0°, alt=0) KTRY_SELECT_FLAT_WALL(capture, "0", "0"); - KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", imagepath); + KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", "test", imagepath); // start the sequence m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_IMAGE_RECEIVED); @@ -774,47 +765,47 @@ } -void TestEkosCaptureWorkflow::testPreMountAndDomePark() -{ - // use the light panel simulator - m_CaptureHelper->m_LightPanelDevice = "Light Panel Simulator"; - // use the dome simulator - m_CaptureHelper->m_DomeDevice = "Dome Simulator"; - // default initialization - QVERIFY(prepareTestCase()); - - // QSKIP("Observatory refactoring needs to be completed until this test can be activated."); - - // switch to capture module - Ekos::Capture *capture = Ekos::Manager::Instance()->captureModule(); - KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(capture, 1000); - - // use a test directory for flats - QString imagepath = getImageLocation()->path() + "/test"; - - // switch capture type to flat so that we can set the calibration - KTRY_SET_COMBO(capture, captureTypeS, "Flat"); - - // select internal flat light, pre-mount and but not pre-dome park - KTRY_SELECT_FLAT_METHOD(flatDeviceSourceC, true, false); - // determine frame type - QFETCH(QString, frametype); - // build a simple 1xL sequence - KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", imagepath); - - // start the sequence - // m_CaptureHelper->expectedDomeStates.append(ISD::Dome::DOME_PARKED); - m_CaptureHelper->expectedMountStates.append(ISD::Mount::MOUNT_PARKED); - m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_CAPTURING); - m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_COMPLETE); - KTRY_CLICK(capture, startB); - // check if mount has reached the expected position - KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedMountStates, 30000); - // check if dome has reached the expected position - KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedDomeStates, 30000); - // check if one single flat is captured - KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedCaptureStates, 60000); -} +//void TestEkosCaptureWorkflow::testPreMountAndDomePark() +//{ +// // use the light panel simulator +// m_CaptureHelper->m_LightPanelDevice = "Light Panel Simulator"; +// // use the dome simulator +// m_CaptureHelper->m_DomeDevice = "Dome Simulator"; +// // default initialization +// QVERIFY(prepareTestCase()); + +// // QSKIP("Observatory refactoring needs to be completed until this test can be activated."); + +// // switch to capture module +// Ekos::Capture *capture = Ekos::Manager::Instance()->captureModule(); +// KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(capture, 1000); + +// // use a test directory for flats +// QString imagepath = getImageLocation()->path() + "/test"; + +// // switch capture type to flat so that we can set the calibration +// KTRY_SET_COMBO(capture, captureTypeS, "Flat"); + +// // select internal flat light, pre-mount and but not pre-dome park +// KTRY_SELECT_FLAT_METHOD(flatDeviceSourceC, true, false); +// // determine frame type +// QFETCH(QString, frametype); +// // build a simple 1xL sequence +// KTRY_CAPTURE_ADD_FRAME(frametype, 2, 1, 2.0, "Luminance", imagepath); + +// // start the sequence +// // m_CaptureHelper->expectedDomeStates.append(ISD::Dome::DOME_PARKED); +// m_CaptureHelper->expectedMountStates.append(ISD::Mount::MOUNT_PARKED); +// m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_CAPTURING); +// m_CaptureHelper->expectedCaptureStates.append(Ekos::CAPTURE_COMPLETE); +// KTRY_CLICK(capture, startB); +// // check if mount has reached the expected position +// KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedMountStates, 30000); +// // check if dome has reached the expected position +// KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedDomeStates, 30000); +// // check if one single flat is captured +// KVERIFY_EMPTY_QUEUE_WITH_TIMEOUT(m_CaptureHelper->expectedCaptureStates, 60000); +//} void TestEkosCaptureWorkflow::testFlatSyncFocus() { @@ -849,8 +840,6 @@ // switch capture type to flat so that we can set the calibration KTRY_SET_COMBO(capture, captureTypeS, "Flat"); - // select internal flat light - KTRY_SELECT_FLAT_METHOD(flatDeviceSourceC, false, false); // build a simple 5xL sequence KTRY_CAPTURE_CONFIGURE_FLAT(2, 1, 2.0, "Luminance", imagepath); @@ -880,12 +869,10 @@ KTRY_CAPTURE_GADGET(QComboBox, captureTypeS); KTRY_CAPTURE_COMBO_SET(captureTypeS, "Dark"); - // select manual flat method - KTRY_SELECT_FLAT_METHOD(manualSourceC, false, false); // build a simple 1xBlue dark sequence - KTRY_CAPTURE_ADD_FRAME("Dark", 1, 1, 0.0, "Blue", imagepath); + KTRY_CAPTURE_ADD_FRAME("Dark", 1, 1, 0.0, "Blue", "test", imagepath); // build a simple 1xL light sequence - KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", imagepath); + KTRY_CAPTURE_ADD_LIGHT(1, 1, 0.0, "Red", "test", imagepath); // shutter type QFETCH(int, shutter); // click OK or Cancel? @@ -1007,6 +994,7 @@ KTRY_SWITCH_TO_MODULE_WITH_TIMEOUT(capture, 1000); // initialize the capture settings + QFETCH(uint, esqVersion); QFETCH(QString, observer); QFETCH(bool, guideDeviation); QFETCH(bool, startGuideDeviation); @@ -1042,7 +1030,8 @@ TestEkosCaptureHelper::SimpleCaptureLightsJob job; QVector jobs; jobs.append(job); - QStringList content = m_CaptureHelper->getSimpleEsqContent(settings, jobs); + QStringList content = m_CaptureHelper->getSimpleEsqContent(settings, jobs, + static_cast(esqVersion)); QString esqFilename = destination->filePath("test.esq"); qCInfo(KSTARS_EKOS_TEST) << "Sequence file name: " << esqFilename; m_CaptureHelper->writeFile(esqFilename, content); @@ -1090,6 +1079,7 @@ KTRY_SET_COMBO(capture, FilterPosCombo, "Blue"); KTRY_SET_COMBO(capture, captureEncodingS, "FITS"); KTRY_SET_COMBO(capture, captureTypeS, "Dark"); + KTRY_SET_LINEEDIT(capture, targetNameT, "nothing"); KTRY_SET_LINEEDIT(capture, fileDirectoryT, "/home/pi"); KTRY_SET_LINEEDIT(capture, placeholderFormatT, "/%T"); KTRY_SET_SPINBOX(capture, formatSuffixN, 1); @@ -1099,8 +1089,12 @@ // create the job TestEkosCaptureHelper::SimpleCaptureLightsJob job; + QFETCH(uint, esqVersion); + job.version = static_cast(esqVersion); QFETCH(double, exposureTime); job.exposureTime = exposureTime; + QFETCH(QString, targetName); + job.targetName = targetName; QFETCH(int, count); job.count = count; QFETCH(int, delay); @@ -1160,6 +1154,7 @@ QTRY_COMPARE(FilterPosCombo->currentText(), filter); QTRY_COMPARE(captureTypeS->currentText(), type); QTRY_COMPARE(captureEncodingS->currentText(), encoding); + QTRY_COMPARE(targetNameT->text(), esqVersion == TestEkosCaptureHelper::ESQ_VERSION_2_5 ? "Test Target" : targetName); QTRY_COMPARE(fileDirectoryT->text(), fitsDirectory); QTRY_COMPARE(placeholderFormatT->text(), placeholderFormat); QTRY_COMPARE(formatSuffixN->value(), formatSuffix); @@ -1182,21 +1177,17 @@ TestEkosCaptureHelper::CaptureSettings settings = {"Test Observer", {true, 2.0}, {true, 1.0}, {false, 1.5}, {true, 1.0}, {false, 5}, false}; // retrieve test data + QFETCH(uint, esqVersion); QFETCH(double, exposureTime); QFETCH(int, count); QFETCH(QString, type); - QFETCH(bool, src_manual); - QFETCH(bool, src_buildin_light); - QFETCH(bool, src_external_light); - QFETCH(bool, src_wall); + QFETCH(uint, pre_action); QFETCH(double, wall_az); QFETCH(double, wall_alt); QFETCH(bool, duration_manual); QFETCH(bool, duration_adu); QFETCH(int, adu); QFETCH(int, tolerance); - QFETCH(bool, park_mount); - QFETCH(bool, park_dome); // clear the UI settings KTRY_SET_DOUBLESPINBOX(capture, captureExposureN, 5.4); @@ -1205,26 +1196,23 @@ // create the job TestEkosCaptureHelper::SimpleCaptureCalibratingJob job; + job.version = static_cast(esqVersion); job.exposureTime = exposureTime; job.type = type; job.count = count; - job.src_manual = src_manual; - job.src_buildin_light = src_buildin_light; - job.src_external_light = src_external_light; - job.src_wall = src_wall; + job.preAction = pre_action; job.wall_az = wall_az; job.wall_alt = wall_alt; job.duration_manual = duration_manual; job.duration_adu = duration_adu; job.adu = adu; job.tolerance = tolerance; - job.park_mount = park_mount; - job.park_dome = park_dome; QVector jobs; jobs.append(job); // create capture sequence file - QStringList content = m_CaptureHelper->getSimpleEsqContent(settings, jobs); + QStringList content = m_CaptureHelper->getSimpleEsqContent(settings, jobs, + static_cast(esqVersion)); QString esqFilename = destination->filePath("test.esq"); qCInfo(KSTARS_EKOS_TEST) << "Sequence file name: " << esqFilename; m_CaptureHelper->writeFile(esqFilename, content); @@ -1254,35 +1242,27 @@ // ensure that the cancel button is pressed in any case [&]() { - QFETCH(bool, src_manual); - QFETCH(bool, src_buildin_light); - QFETCH(bool, src_external_light); - QFETCH(bool, src_wall); + QFETCH(uint, pre_action); QFETCH(double, wall_az); QFETCH(double, wall_alt); QFETCH(bool, duration_manual); QFETCH(bool, duration_adu); QFETCH(int, adu); QFETCH(int, tolerance); - QFETCH(bool, park_mount); - QFETCH(bool, park_dome); - KTRY_GADGET(calibrationDialog, QRadioButton, manualSourceC); - KTRY_GADGET(calibrationDialog, QRadioButton, flatDeviceSourceC); - KTRY_GADGET(calibrationDialog, QRadioButton, darkDeviceSourceC); - KTRY_GADGET(calibrationDialog, QRadioButton, wallSourceC); + KTRY_GADGET(calibrationDialog, QCheckBox, gotoWallC); + KTRY_GADGET(calibrationDialog, QCheckBox, parkMountC); + KTRY_GADGET(calibrationDialog, QCheckBox, parkDomeC); KTRY_GADGET(calibrationDialog, dmsBox, azBox); KTRY_GADGET(calibrationDialog, dmsBox, altBox); KTRY_GADGET(calibrationDialog, QRadioButton, manualDurationC); KTRY_GADGET(calibrationDialog, QRadioButton, ADUC); KTRY_GADGET(calibrationDialog, QSpinBox, ADUValue); KTRY_GADGET(calibrationDialog, QSpinBox, ADUTolerance); - KTRY_GADGET(calibrationDialog, QCheckBox, parkMountC); - KTRY_GADGET(calibrationDialog, QCheckBox, parkDomeC); - QTRY_COMPARE(manualSourceC->isChecked(), src_manual); - QTRY_COMPARE(flatDeviceSourceC->isChecked(), src_buildin_light); - QTRY_COMPARE(darkDeviceSourceC->isChecked(), src_external_light); - QTRY_COMPARE(wallSourceC->isChecked(), src_wall); - if (src_wall) + QTRY_COMPARE(gotoWallC->isChecked(), (pre_action & ACTION_WALL) > 0); + QTRY_COMPARE(parkMountC->isChecked(), (pre_action & ACTION_PARK_MOUNT) > 0); + QTRY_COMPARE(parkDomeC->isChecked(), (pre_action & ACTION_PARK_DOME) > 0); + + if (pre_action & ACTION_WALL) { dms wallAz, wallAlt; bool azOk = false, altOk = false; @@ -1300,8 +1280,6 @@ QTRY_COMPARE(ADUValue->value(), adu); QTRY_COMPARE(ADUTolerance->value(), tolerance); } - QTRY_COMPARE(parkMountC->isChecked(), park_mount); - QTRY_COMPARE(parkDomeC->isChecked(), park_dome); passed = true; } (); @@ -1355,9 +1333,10 @@ QTest::addColumn("clickModalOK"); /*!< click "OK" on the modal dialog */ QTest::addColumn("clickModal2OK"); /*!< click "OK" on the second modal dialog */ - // both variants: click OK and click Cancel - QTest::newRow("Flat, modal=true") << true << true; - QTest::newRow("Flat, modal=true") << true << false; + // both variants for second click: click OK and click Cancel + QTest::newRow("Flat, modal=true/true") << true << true; + QTest::newRow("Flat, modal=true/false") << true << false; + // first click Cancel QTest::newRow("Flat, modal=false") << false << true; } @@ -1381,12 +1360,11 @@ void TestEkosCaptureWorkflow::testDustcapSource_data() { QTest::addColumn("frametype"); /*!< frame type (Dark or Flat) */ - QTest::addColumn("internalLight"); /*!< use internal or external flat light */ // QTest::newRow("Flat, light=internal") << "Flat" << true; // flat + light source integrated into the light panel - QTest::newRow("Flat, light=external") << "Flat" << false; // flat + external light source used - QTest::newRow("Dark, light=external") << "Dark" << false; // dark + external light source used - QTest::newRow("Bias, light=external") << "Bias" << false; // dark + external light source used + QTest::newRow("Flat, light=internal") << "Flat"; // flat + internal light source used + QTest::newRow("Dark, light=internal") << "Dark"; // dark + external light source turned off + QTest::newRow("Bias, light=internal") << "Bias"; // dark + external light source turned off // QTest::newRow("Dark") << "Dark" << false; // dark } @@ -1400,10 +1378,10 @@ } -void TestEkosCaptureWorkflow::testPreMountAndDomePark_data() -{ - testWallSource_data(); -} +//void TestEkosCaptureWorkflow::testPreMountAndDomePark_data() +//{ +// testWallSource_data(); +//} void TestEkosCaptureWorkflow::testDarkManualCovering_data() { @@ -1430,6 +1408,7 @@ void TestEkosCaptureWorkflow::testLoadEsqFileGeneral_data() { + QTest::addColumn("esqVersion"); /*!< ESQ XML version */ QTest::addColumn("observer"); /*!< Set the observer value */ QTest::addColumn("guideDeviation"); /*!< Enable guide deviation */ QTest::addColumn("startGuideDeviation"); /*!< Enable starting guide deviation */ @@ -1438,18 +1417,28 @@ QTest::addColumn("refocusEveryN"); /*!< Enable focusing after every n capture */ QTest::addColumn("refocusAfterMeridianFlip"); /*!< Enable refocus after a meridian flip */ - QTest::newRow("observer") << "KStars Freak" << false << false << false << false << false << false; - QTest::newRow("guideDeviation") << "KStars Freak" << true << false << false << false << false << false; - QTest::newRow("startGuideDeviation") << "KStars Freak" << false << true << false << false << false << false; - QTest::newRow("inSequenceFocus") << "KStars Freak" << false << false << true << false << false << false; - QTest::newRow("autofocusOnTemperature") << "KStars Freak" << false << false << false << true << false << false; - QTest::newRow("refocusEveryN") << "KStars Freak" << false << false << false << false << true << false; - QTest::newRow("refocusAfterMeridianFlip") << "KStars Freak" << false << false << false << false << false << true; + uint version = TestEkosCaptureHelper::ESQ_VERSION_2_6; + QTest::newRow(QString("observer v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) + << version << "KStars Freak" << false << false << false << false << false << false; + QTest::newRow(QString("guideDeviation v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << version << + "KStars Freak" << true << false << false << false << false << false; + QTest::newRow(QString("startGuideDeviation v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << version + << "KStars Freak" << false << true << false << false << false << false; + QTest::newRow(QString("inSequenceFocus v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << version << + "KStars Freak" << false << false << true << false << false << false; + QTest::newRow(QString("autofocusOnTemperature v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << + version << "KStars Freak" << false << false << false << true << false << false; + QTest::newRow(QString("refocusEveryN v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << version << + "KStars Freak" << false << false << false << false << true << false; + QTest::newRow(QString("refocusAfterMeridianFlip v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << + version << "KStars Freak" << false << false << false << false << false << true; } void TestEkosCaptureWorkflow::testLoadEsqFileBasicJobSettings_data() { + QTest::addColumn("esqVersion"); /*!< ESQ XML version */ QTest::addColumn("exposureTime"); /*!< Exposure time */ + QTest::addColumn("targetName"); /*!< Capture target */ QTest::addColumn("count"); /*!< Number of frames */ QTest::addColumn("delay"); /*!< Delay between captures */ QTest::addColumn("filter"); /*!< Filter name */ @@ -1473,48 +1462,53 @@ int x = 10, y = 10, w = 480, h = 360; int formatSuffix = 4, fileUploadMode = 2; bool cameraCooling = true; + QString target("Test Target"); QString filter("Green"); QString type("Light"); QString encoding("Native"); QString fitsDirectory("/home/astro"); QString placeholderFormat("/%t/%T/%T_%t_%e"); - QTest::newRow(QString("%2x %5 %3 %1s bin=%6x%7 dir=%4").arg(exposureTime).arg(count).arg(filter).arg(fitsDirectory).arg( - type).arg(binX).arg(binY).toLatin1()) - << exposureTime << count << delay << filter << type << encoding << binX << binY << x << y << w << h << fitsDirectory - << placeholderFormat << formatSuffix << cameraTemperature << cameraCooling << fileUploadMode; + for (uint version : + { + TestEkosCaptureHelper::ESQ_VERSION_2_4, TestEkosCaptureHelper::ESQ_VERSION_2_5, TestEkosCaptureHelper::ESQ_VERSION_2_6 + }) + { + QTest::newRow(QString("%2x %5 %3 %1s bin=%6x%7 dir=%4 v=%8").arg(exposureTime).arg(count).arg(filter) + .arg(fitsDirectory).arg(type).arg(binX).arg(binY).arg(m_CaptureHelper->esqVersionNames[version]).toLatin1()) + << version << exposureTime << target << count << delay << filter << type << encoding << binX << binY << x << y << w << h << + fitsDirectory << placeholderFormat << formatSuffix << cameraTemperature << cameraCooling << fileUploadMode; + } } void TestEkosCaptureWorkflow::testLoadEsqFileCalibrationSettings_data() { + QTest::addColumn("esqVersion"); /*!< ESQ XML version */ QTest::addColumn("exposureTime"); /*!< Exposure time */ QTest::addColumn("count"); /*!< Number of frames */ QTest::addColumn("type"); /*!< Frame type (Flat etc.) */ - QTest::addColumn("src_manual"); /*!< Manual flat light */ - QTest::addColumn("src_buildin_light"); /*!< Cap with flat light */ - QTest::addColumn("src_external_light"); /*!< External flat light */ - QTest::addColumn("src_wall"); /*!< Wall as flat light */ + QTest::addColumn("pre_action"); /*!< Calibration Pre-Actions */ QTest::addColumn("wall_az"); /*!< Az position for wall source */ QTest::addColumn("wall_alt"); /*!< Alt position for wall source */ QTest::addColumn("duration_manual"); /*!< Manual exposure time */ QTest::addColumn("duration_adu"); /*!< ADU based exposure */ QTest::addColumn("adu"); /*!< Target ADU */ QTest::addColumn("tolerance"); /*!< ADU tolerance */ - QTest::addColumn("park_mount"); /*!< Park mount before capturing */ - QTest::addColumn("park_dome"); /*!< Park dome before capturing */ - QTest::newRow("Flat src=manual adu=manual") << 1.0 << 2 << "Flat" << true << false << false << false << 180.0 << 85.0 << - true << false - << 12345 << 1234 << false << false; - QTest::newRow("Dark src=buildin adu=automatic") << 1.0 << 2 << "Dark" << false << true << false << false << 180.0 << 85.0 << - false << - true << 12345 << 1234 << false << false; - QTest::newRow("Bias src=external park=mount") << 1.0 << 2 << "Bias" << false << false << true << false << 180.0 << 85.0 << - false << - true << 12345 << 1234 << true << false; - QTest::newRow("Flat src=wall park=mount") << 1.0 << 2 << "Flat" << false << false << false << true << 180.0 << 85.0 << false - << true - << 12345 << 1234 << true << false; + for (uint version : + { + TestEkosCaptureHelper::ESQ_VERSION_2_5, TestEkosCaptureHelper::ESQ_VERSION_2_6 + }) + { + QTest::newRow(QString("Flat pre_action=wall adu=manual v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) + << version << 1.0 << 2 << + "Flat" << static_cast(ACTION_WALL) << 180.0 << 85.0 << true << false << 12345 << 1234; + QTest::newRow(QString("Dark pre_action=none adu=automatic v=%1").arg( + m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << version << 1.0 << 2 << "Dark" << + static_cast(ACTION_NONE) << 180.0 << 85.0 << false << true << 12345 << 1234; + QTest::newRow(QString("Bias pre_action=park_mount v=%1").arg(m_CaptureHelper->esqVersionNames[version]).toLocal8Bit()) << + version << 1.0 << 2 << "Bias" << static_cast(ACTION_PARK_MOUNT) << 180.0 << 85.0 << false << true << 12345 << 1234; + } } /* ********************************************************************************* @@ -1596,6 +1590,8 @@ { // reset counters image_count = 0; + // reset calibration + Options::setCalibrationPreActionIndex(ACTION_NONE); KTRY_OPEN_EKOS(); KVERIFY_EKOS_IS_OPENED(); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_capture_workflow.h 2023-12-03 05:23:16.000000000 +0000 @@ -45,8 +45,8 @@ #define KTRY_SELECT_FLAT_WALL(capture, azimuth, altitude) do { \ QTimer::singleShot(1000, capture, [&]() { \ QDialog *calibrationOptions = Ekos::Manager::Instance()->findChild("calibrationOptions"); \ - KTRY_GADGET(calibrationOptions, QAbstractButton, wallSourceC); \ - wallSourceC->setChecked(true); \ + KTRY_GADGET(calibrationOptions, QAbstractButton, gotoWallC); \ + gotoWallC->setChecked(true); \ KTRY_SET_LINEEDIT(calibrationOptions, azBox, azimuth); \ KTRY_SET_LINEEDIT(calibrationOptions, altBox, altitude); \ KTRY_GADGET(calibrationOptions, QAbstractButton, manualDurationC); \ @@ -221,10 +221,10 @@ /** * @brief Check mount and dome parking before capturing flats. */ - void testPreMountAndDomePark(); + //void testPreMountAndDomePark(); /** @brief Test data for {@see testFlatPreMountAndDomePark()} */ - void testPreMountAndDomePark_data(); + //void testPreMountAndDomePark_data(); /** * @brief Check the flat capture behavior if "same focus" is selectee diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_filterwheel.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_filterwheel.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_filterwheel.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_filterwheel.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -14,6 +14,7 @@ #include "test_ekos_simulator.h" #include "ekos/profileeditor.h" #include "fitsviewer/fitsdata.h" +#include "ekos/capture/capture.h" TestEkosFilterWheel::TestEkosFilterWheel(QObject *parent) : QObject(parent) { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -12,6 +12,11 @@ #include "ekos/profileeditor.h" #include "ekos/guide/internalguide/gmath.h" #include "ekos/auxiliary/opticaltrainmanager.h" +#include "ekos/align/align.h" +#include "ekos/capture/capture.h" +#include "ekos/scheduler/scheduler.h" +#include "ekos/auxiliary/filtermanager.h" +#include "kstarsdata.h" TestEkosHelper::TestEkosHelper(QString guider) { @@ -398,6 +403,7 @@ primaryTrain["focuser"] = m_FocuserDevice == "" ? "-" : m_FocuserDevice; primaryTrain["rotator"] = m_RotatorDevice == "" ? "-" : m_RotatorDevice; primaryTrain["lightbox"] = m_LightPanelDevice == "" ? "-" : m_LightPanelDevice; + primaryTrain["dustcap"] = m_DustCapDevice == "" ? "-" : m_DustCapDevice; KStarsData::Instance()->userdb()->UpdateOpticalTrain(primaryTrain, primaryTrain["id"].toInt()); if (m_GuiderDevice != "") { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_helper.h 2023-12-03 05:23:16.000000000 +0000 @@ -11,12 +11,16 @@ #include "test_ekos_debug.h" #include "test_ekos_simulator.h" #include "ekos/guide/guide.h" +#include "ekos/manager/meridianflipstate.h" #include "indi/indidevice.h" #include "indi/indigroup.h" +#include "indi/indidome.h" #include "indi/indiproperty.h" #include "indi/indielement.h" #include "indi/guimanager.h" +#include "oal/oal.h" +#include "ekos/scheduler/scheduler.h" #include @@ -344,7 +348,10 @@ { \ QList pb = dialog->findChildren(); \ QTest::mouseClick(pb[button_nr], Qt::MouseButton::LeftButton); \ + qCInfo(KSTARS_EKOS_TEST) << "Button clicked:" << button_nr; \ } \ + else \ + qCWarning(KSTARS_EKOS_TEST) << "No active modal widget found!" ; \ }); \ } while (false) @@ -378,6 +385,8 @@ QString m_FocuserDevice = ""; // Flat light panel device QString m_LightPanelDevice = ""; + // Dust cap device + QString m_DustCapDevice = ""; // Dome device QString m_DomeDevice = ""; @@ -682,7 +691,7 @@ * @param focallenght focal length in mm * @return scope object */ - Scope *createScopeIfNecessary(QString model, QString vendor, QString type, double aperture, double focallenght); + OAL::Scope *createScopeIfNecessary(QString model, QString vendor, QString type, double aperture, double focallenght); private: // current mount status diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -21,6 +21,7 @@ #include "ksutils.h" #include "ekos/guide/internalguide/gmath.h" #include "Options.h" +#include "ekos/capture/capture.h" /* ***************************************************************************** * diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -20,6 +20,7 @@ #include "ksutils.h" #include "indicom.h" #include "Options.h" +#include "ekos/capture/capture.h" TestEkosMeridianFlipBase::TestEkosMeridianFlipBase(QObject *parent) : TestEkosMeridianFlipBase::TestEkosMeridianFlipBase("Internal", parent) {} @@ -271,7 +272,7 @@ QFETCH(double, exptime); QFETCH(QString, filters); - KWRAP_SUB(foreach(QString filter, filters.split(",")) KTRY_CAPTURE_ADD_LIGHT(exptime, count, 0, filter, + KWRAP_SUB(foreach(QString filter, filters.split(",")) KTRY_CAPTURE_ADD_LIGHT(exptime, count, 0, filter, "test", destination.path())); QFETCH(bool, guide); @@ -318,7 +319,7 @@ } bool TestEkosMeridianFlipBase::prepareSchedulerTestcase(int secsToMF, bool useAlign, - SchedulerJob::CompletionCondition completionCondition, int iterations) + Ekos::CompletionCondition completionCondition, int iterations) { #if QT_VERSION < QT_VERSION_CHECK(5,9,0) QSKIP("Bypassing fixture test on old Qt"); @@ -363,12 +364,12 @@ // set the completion condition switch (completionCondition) { - case SchedulerJob::FINISH_REPEAT: + case Ekos::FINISH_REPEAT: // repeat the job for a fixed amount KTRY_SET_RADIOBUTTON_SUB(scheduler, repeatCompletionR, true); KTRY_SET_SPINBOX_SUB(scheduler, repeatsSpin, iterations); break; - case SchedulerJob::FINISH_LOOP: + case Ekos::FINISH_LOOP: KTRY_SET_RADIOBUTTON_SUB(scheduler, loopCompletionR, true); break; default: diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_base.h 2023-12-03 05:23:16.000000000 +0000 @@ -111,7 +111,7 @@ * @param iterations number of iterations to be executed (only relevant if completionCondition == FINISH_REPEAT) * @return true iff preparation was successful */ - bool prepareSchedulerTestcase(int secsToMF, bool useAlign, SchedulerJob::CompletionCondition completionCondition, int iterations); + bool prepareSchedulerTestcase(int secsToMF, bool useAlign, Ekos::CompletionCondition completionCondition, int iterations); /** * @brief Prepare test data iterating over all combination of parameters. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_specials.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_specials.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_specials.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_meridianflip_specials.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -12,6 +12,7 @@ #include "kstars_ui_tests.h" #include "Options.h" +#include "ekos/capture/capture.h" TestEkosMeridianFlipSpecials::TestEkosMeridianFlipSpecials(QObject *parent) : TestEkosMeridianFlipBase(parent) { @@ -215,7 +216,7 @@ void TestEkosMeridianFlipSpecials::testSchedulerCaptureMF() { // setup the scheduler - QVERIFY(prepareSchedulerTestcase(15, false, SchedulerJob::FINISH_LOOP, 1)); + QVERIFY(prepareSchedulerTestcase(15, false, Ekos::FINISH_LOOP, 1)); // start the scheduled procedure QVERIFY(startScheduler()); // check if meridian flip runs and completes successfully @@ -227,7 +228,7 @@ void TestEkosMeridianFlipSpecials::testAbortSchedulerRefocusMF() { // setup the scheduler - QVERIFY(prepareSchedulerTestcase(10, false, SchedulerJob::FINISH_LOOP, 1)); + QVERIFY(prepareSchedulerTestcase(10, false, Ekos::FINISH_LOOP, 1)); // update the initial focuser position KTRY_GADGET(Ekos::Manager::Instance()->focusModule(), QLineEdit, absTicksLabel); initialFocusPosition = absTicksLabel->text().toInt(); @@ -302,7 +303,7 @@ Options::setAlignCheckFrequency(1); Options::setAlignCheckThreshold(0.0); // setup the scheduler - QVERIFY(prepareSchedulerTestcase(17, true, SchedulerJob::FINISH_REPEAT, 1)); + QVERIFY(prepareSchedulerTestcase(17, true, Ekos::FINISH_REPEAT, 1)); // start the scheduled procedure QVERIFY(startScheduler()); // make the alignment exposure so long that the flip happens while capturing the frame for alignment @@ -335,7 +336,7 @@ // prepare for alignment tests m_CaptureHelper->prepareAlignmentModule(); // setup the scheduler - QVERIFY(prepareSchedulerTestcase(17, true, SchedulerJob::FINISH_REPEAT, 1)); + QVERIFY(prepareSchedulerTestcase(17, true, Ekos::FINISH_REPEAT, 1)); // start the scheduled procedure QVERIFY(startScheduler()); // check if meridian flip has been started diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_mount.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_mount.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_mount.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_mount.h 2023-12-03 05:23:16.000000000 +0000 @@ -10,6 +10,7 @@ #include "config-kstars.h" #include "test_ekos.h" +#include "ekos/mount/mount.h" #if defined(HAVE_INDI) #include "indicom.h" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -12,6 +12,7 @@ #include "kstars_ui_tests.h" #include "test_ekos.h" #include "test_ekos_simulator.h" +#include "ekos/scheduler/scheduler.h" TestEkosScheduler::TestEkosScheduler(QObject *parent) : QObject(parent) { @@ -78,7 +79,8 @@ << o.dec().toDMSString(); count++; } - else QWARN(QString("Fixture '%1' altitude is '%2' degrees, discarding.").arg(name).arg(so->alt().Degrees()).toStdString().c_str()); + else QWARN(QString("Fixture '%1' altitude is '%2' degrees, discarding.").arg(name).arg( + so->alt().Degrees()).toStdString().c_str()); } } @@ -113,15 +115,19 @@ raBox->setText("1h 2' 3\""); decBox->setText("1° 2' 3\""); - sequenceEdit->setText(QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg(QDir::separator())); // %20 to retain the next '1' + sequenceEdit->setText(QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg( + QDir::separator())); // %20 to retain the next '1' - QEXPECT_FAIL("", "The sequence file editbox cannot be edited directly, and changing its text does not allow to add a job", Continue); + QEXPECT_FAIL("", "The sequence file editbox cannot be edited directly, and changing its text does not allow to add a job", + Continue); QTRY_VERIFY_WITH_TIMEOUT(addToQueueB->isEnabled(), 200); const int count = 20; QStringList seqs; - seqs << QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg(QDir::separator()); // %20 to retain the next '1' - seqs << QString("%1%201x1s_RGBLumRGB.esq").arg(QDir::current().currentPath()).arg(QDir::separator()); // %20 to retain the next '1' + seqs << QString("%1%201x1s_Lum.esq").arg(QDir::current().currentPath()).arg( + QDir::separator()); // %20 to retain the next '1' + seqs << QString("%1%201x1s_RGBLumRGB.esq").arg(QDir::current().currentPath()).arg( + QDir::separator()); // %20 to retain the next '1' KTRY_SCHEDULER_GADGET(QTableWidget, queueTable); @@ -132,11 +138,11 @@ nameEdit->setText(QString("Object-%1").arg(i)); - SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i/10 + (double)count/2, 45.0); + SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); raBox->setText(o.ra().toHMSString()); - QVERIFY(abs(raBox->createDms().Hours() - o.ra().Hours()) <= 15.0/3600.0); + QVERIFY(abs(raBox->createDms().Hours() - o.ra().Hours()) <= 15.0 / 3600.0); decBox->setText(o.dec().toDMSString()); - QVERIFY(abs(decBox->createDms().Degrees() - o.dec().Degrees()) <= 1.0/3600.0); + QVERIFY(abs(decBox->createDms().Degrees() - o.dec().Degrees()) <= 1.0 / 3600.0); sequenceEdit->setText(seqs[i % seqs.count()]); Ekos::Manager::Instance()->schedulerModule()->addObject(&o); @@ -154,7 +160,7 @@ queueTable->selectRow(i % queueTable->rowCount()); QCOMPARE(qPrintable(nameEdit->text()), qPrintable(QString("Object-%1").arg(i))); QCOMPARE(qPrintable(sequenceEdit->text()), qPrintable(seqs[i % seqs.count()])); - SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i/10 + (double)count/2, 45.0); + SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); QCOMPARE(qPrintable(dms::fromString(raBox->text(), false).toHMSString()), qPrintable(o.ra().toHMSString())); QCOMPARE(qPrintable(dms::fromString(decBox->text(), true).toDMSString()), qPrintable(o.dec().toDMSString())); } @@ -172,7 +178,7 @@ QCOMPARE(qPrintable(nameEdit->text()), qPrintable(QString("Object-%1").arg(i))); QCOMPARE(qPrintable(sequenceEdit->text()), qPrintable(seqs[i % seqs.count()])); - SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i/10 + (double)count/2, 45.0); + SkyObject o(SkyObject::TYPE_UNKNOWN, LST.radians() - (double)i / 10 + (double)count / 2, 45.0); QCOMPARE(qPrintable(dms::fromString(raBox->text(), false).toHMSString()), qPrintable(o.ra().toHMSString())); QCOMPARE(qPrintable(dms::fromString(decBox->text(), true).toDMSString()), qPrintable(o.dec().toDMSString())); } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -6,6 +6,7 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #include "test_ekos_scheduler_helper.h" +#include "skyobject.h" TestEkosSchedulerHelper::TestEkosSchedulerHelper(): TestEkosHelper() {} @@ -39,20 +40,20 @@ QString sequence = QString("%1"); QString startupConditionStr; - if (startupCondition.type == SchedulerJob::START_ASAP) + if (startupCondition.type == Ekos::START_ASAP) startupConditionStr = QString("ASAP"); - else if (startupCondition.type == SchedulerJob::START_AT) + else if (startupCondition.type == Ekos::START_AT) startupConditionStr = QString("At").arg( startupCondition.atLocalDateTime.toString(Qt::ISODate)); QString completionConditionStr; - if (completionCondition.type == SchedulerJob::FINISH_SEQUENCE) + if (completionCondition.type == Ekos::FINISH_SEQUENCE) completionConditionStr = QString("Sequence"); - else if (completionCondition.type == SchedulerJob::FINISH_REPEAT) + else if (completionCondition.type == Ekos::FINISH_REPEAT) completionConditionStr = QString("Repeat").arg(completionCondition.repeat); - else if (completionCondition.type == SchedulerJob::FINISH_LOOP) + else if (completionCondition.type == Ekos::FINISH_LOOP) completionConditionStr = QString("Loop"); - else if (completionCondition.type == SchedulerJob::FINISH_AT) + else if (completionCondition.type == Ekos::FINISH_AT) completionConditionStr = QString("At").arg( completionCondition.atLocalDateTime.toString(Qt::ISODate)); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_helper.h 2023-12-03 05:23:16.000000000 +0000 @@ -9,19 +9,20 @@ #pragma once #include "test_ekos_helper.h" +#include "ekos/scheduler/schedulerjob.h" class TestEkosSchedulerHelper : public TestEkosHelper { public: struct StartupCondition { - SchedulerJob::StartupCondition type; + Ekos::StartupCondition type; int culminationOffset; QDateTime atLocalDateTime; // This is in local time, not universal time. }; struct CompletionCondition { - SchedulerJob::CompletionCondition type; + Ekos::CompletionCondition type; int repeat; QDateTime atLocalDateTime; // This is in local time, not universal time. }; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_ops.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_ops.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_ops.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_scheduler_ops.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -12,8 +12,10 @@ #include "test_ekos_scheduler_ops.h" #include "test_ekos_scheduler_helper.h" #include "ekos/scheduler/scheduler.h" +#include "ekos/scheduler/schedulermodulestate.h" #include "ekos/scheduler/schedulerjob.h" #include "ekos/scheduler/greedyscheduler.h" +#include "ekos/scheduler/schedulerprocess.h" #include "skymapcomposite.h" @@ -49,12 +51,12 @@ public: WithInterval(int interval, QSharedPointer &_scheduler) : scheduler(_scheduler) { - keepInterval = scheduler->getUpdateInterval(); - scheduler->setUpdateInterval(interval); + keepInterval = scheduler->moduleState()->updatePeriodMs(); + scheduler->moduleState()->setUpdatePeriodMs(interval); } ~WithInterval() { - scheduler->setUpdateInterval(keepInterval); + scheduler->moduleState()->setUpdatePeriodMs(keepInterval); } private: int keepInterval; @@ -120,13 +122,14 @@ Options::setDitherEnabled(false); // define START_ASAP and FINISH_SEQUENCE as default startup/completion conditions. - m_startupCondition.type = SchedulerJob::START_ASAP; - m_completionCondition.type = SchedulerJob::FINISH_SEQUENCE; + m_startupCondition.type = Ekos::START_ASAP; + m_completionCondition.type = Ekos::FINISH_SEQUENCE; Options::setDawnOffset(0); Options::setDuskOffset(0); Options::setSettingAltitudeCutoff(0); - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); + Options::setGreedyScheduling(true); } void TestEkosSchedulerOps::cleanup() @@ -173,7 +176,7 @@ // the scheduler's iteration period to compensate for that. int TestEkosSchedulerOps::timeTolerance(int seconds) { - const int tolerance = std::max(seconds, 3 * (scheduler->m_UpdatePeriodMs / 1000)); + const int tolerance = std::max(seconds, 3 * (scheduler->moduleState()->updatePeriodMs() / 1000)); return tolerance; } @@ -181,11 +184,11 @@ // work between the scheduler and the mock modules. void TestEkosSchedulerOps::testBasics() { - QVERIFY(scheduler->focusInterface.isNull()); - QVERIFY(scheduler->mountInterface.isNull()); - QVERIFY(scheduler->captureInterface.isNull()); - QVERIFY(scheduler->alignInterface.isNull()); - QVERIFY(scheduler->guideInterface.isNull()); + QVERIFY(scheduler->process()->focusInterface().isNull()); + QVERIFY(scheduler->process()->mountInterface().isNull()); + QVERIFY(scheduler->process()->captureInterface().isNull()); + QVERIFY(scheduler->process()->alignInterface().isNull()); + QVERIFY(scheduler->process()->guideInterface().isNull()); ekos->addModule(QString("Focus")); ekos->addModule(QString("Mount")); @@ -202,15 +205,15 @@ //qApp->processEvents(); QTest::qWait(10 * QWAIT_TIME); - QVERIFY(!scheduler->focusInterface.isNull()); - QVERIFY(!scheduler->mountInterface.isNull()); - QVERIFY(!scheduler->captureInterface.isNull()); - QVERIFY(!scheduler->alignInterface.isNull()); - QVERIFY(!scheduler->guideInterface.isNull()); + QVERIFY(!scheduler->process()->focusInterface().isNull()); + QVERIFY(!scheduler->process()->mountInterface().isNull()); + QVERIFY(!scheduler->process()->captureInterface().isNull()); + QVERIFY(!scheduler->process()->alignInterface().isNull()); + QVERIFY(!scheduler->process()->guideInterface().isNull()); // Verify the mocks can use the DBUS. QVERIFY(!focuser->isReset); - scheduler->focusInterface->call(QDBus::AutoDetect, "resetFrame"); + scheduler->process()->focusInterface()->call(QDBus::AutoDetect, "resetFrame"); //qApp->processEvents(); // this fails, is it because dbus calls are on a separate thread? QTest::qWait(10 * QWAIT_TIME); @@ -219,14 +222,14 @@ // Run the scheduler with nothing setup. Should quickly exit. scheduler->init(); - QVERIFY(scheduler->timerState == Scheduler::RUN_WAKEUP); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); int sleepMs = scheduler->runSchedulerIteration(); - QVERIFY(scheduler->timerState == Scheduler::RUN_SCHEDULER); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); sleepMs = scheduler->runSchedulerIteration(); QVERIFY(sleepMs == 1000); - QVERIFY(scheduler->timerState == Scheduler::RUN_SHUTDOWN); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_SHUTDOWN); sleepMs = scheduler->runSchedulerIteration(); - QVERIFY(scheduler->timerState == Scheduler::RUN_NOTHING); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_NOTHING); } // Runs the scheduler for a number of iterations between 1 and the arg "iterations". @@ -312,8 +315,8 @@ QVERIFY(TestEkosSchedulerHelper::writeSimpleSequenceFiles(esls[i], eslFile, esqs[i], esqFile)); scheduler->load(i == 0, QString("file://%1").arg(eslFile)); - QVERIFY(scheduler->jobs.size() == (i + 1)); - scheduler->jobs[i]->setSequenceFile(QUrl(QString("file://%1").arg(esqFile))); + QVERIFY(scheduler->moduleState()->jobs().size() == (i + 1)); + scheduler->moduleState()->jobs()[i]->setSequenceFile(QUrl(QString("file://%1").arg(esqFile))); fprintf(stderr, "seq file: %s \"%s\"\n", esqFile.toLatin1().data(), QString("file://%1").arg(esqFile).toLatin1().data()); } } @@ -326,7 +329,7 @@ initFiles(dir, esls, esqs); scheduler->evaluateJobs(false); scheduler->init(); - QVERIFY(scheduler->timerState == Scheduler::RUN_WAKEUP); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); } void TestEkosSchedulerOps::startupJob( @@ -352,10 +355,10 @@ KStarsDateTime currentUTime(startUTime); int sleepMs = 0; - QVERIFY(scheduler->timerState == Scheduler::RUN_WAKEUP); + QVERIFY(scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); QVERIFY(iterateScheduler("Wait for RUN_SCHEDULER", 2, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); if (wakeupTime.isValid()) @@ -364,7 +367,7 @@ QVERIFY(iterateScheduler("Wait for RUN_WAKEUP", 10, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_WAKEUP); + return (scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); })); // Verify that it's near the original start time. @@ -374,7 +377,7 @@ QVERIFY(iterateScheduler("Wait for RUN_SCHEDULER", 2, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); // Verify that it wakes up at the right time, after the twilight constraint @@ -385,8 +388,8 @@ { // check if there is a job scheduled bool scheduled_job = false; - foreach (SchedulerJob *sched_job, scheduler->jobs) - if (sched_job->state == SchedulerJob::JOB_SCHEDULED) + foreach (Ekos::SchedulerJob *sched_job, scheduler->moduleState()->jobs()) + if (sched_job->state == Ekos::SchedulerJob::JOB_SCHEDULED) scheduled_job = true; if (scheduled_job) { @@ -399,7 +402,7 @@ QVERIFY(iterateScheduler("Wait for RUN_SCHEDULER", 2, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); } else @@ -414,8 +417,8 @@ bool sentOnce = false, readyOnce = false; QVERIFY(iterateScheduler("Wait for Indi and Ekos", 30, &sleepMs, ¤tUTime, [&]() -> bool { - if ((scheduler->indiState == Scheduler::INDI_READY) && - (scheduler->ekosState == Scheduler::EKOS_READY)) + if ((scheduler->moduleState()->indiState() == Ekos::INDI_READY) && + (scheduler->moduleState()->ekosState() == Ekos::EKOS_READY)) { return true; } @@ -433,8 +436,8 @@ ekos->addModule("Align"); ekos->addModule("Guide"); } - else if (scheduler->mountInterface != nullptr && - scheduler->captureInterface != nullptr && !readyOnce) + else if (scheduler->process()->mountInterface() != nullptr && + scheduler->process()->captureInterface() != nullptr && !readyOnce) { // Can't send the ready messages until the devices are registered. readyOnce = true; @@ -506,10 +509,10 @@ void TestEkosSchedulerOps::printJobs(const QString &label) { fprintf(stderr, "%-30s: ", label.toLatin1().data()); - for (int i = 0; i < scheduler->jobs.size(); ++i) + for (int i = 0; i < scheduler->moduleState()->jobs().size(); ++i) { - fprintf(stderr, "(%d) %s %-15s ", i, scheduler->jobs[i]->getName().toLatin1().data(), - SchedulerJob::jobStatusString(scheduler->jobs[i]->getState()).toLatin1().data()); + fprintf(stderr, "(%d) %s %-15s ", i, scheduler->moduleState()->jobs()[i]->getName().toLatin1().data(), + Ekos::SchedulerJob::jobStatusString(scheduler->moduleState()->jobs()[i]->getState()).toLatin1().data()); } fprintf(stderr, "\n"); } @@ -522,19 +525,19 @@ // wait for the scheduler select the configured job for execution QVERIFY(iterateScheduler("Wait for RUN_SCHEDULER", 2, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); // wait until the scheduler turns to the wakeup mode sleeping until the startup condition is met QVERIFY(iterateScheduler("Wait for RUN_WAKEUP", 10, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_WAKEUP); + return (scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); })); // wait until the scheduler starts the job QVERIFY(iterateScheduler("Wait for RUN_SCHEDULER", 2, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); // check the distance from the expected start time @@ -565,8 +568,8 @@ QVERIFY(iterateScheduler("Wait for Capturing", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->currentJob != nullptr && - scheduler->currentJob->getStage() == SchedulerJob::STAGE_CAPTURING); + return (scheduler->activeJob() != nullptr && + scheduler->activeJob()->getStage() == Ekos::SchedulerJob::STAGE_CAPTURING); })); { @@ -581,7 +584,7 @@ })); QVERIFY(iterateScheduler("Wait for Shutdown", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->shutdownState == Scheduler::SHUTDOWN_COMPLETE); + return (scheduler->moduleState()->shutdownState() == Ekos::SHUTDOWN_COMPLETE); })); // Here the scheduler sends a message to ekosInterface to disconnectDevices, @@ -590,7 +593,7 @@ // This will cause the scheduler to shutdown. QVERIFY(iterateScheduler("Wait for Scheduler Complete", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_NOTHING); + return (scheduler->moduleState()->timerState() == Ekos::RUN_NOTHING); })); } } @@ -680,7 +683,7 @@ { QVERIFY(iterateScheduler("Wait for Job Startup", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_JOBCHECK); + return (scheduler->moduleState()->timerState() == Ekos::RUN_JOBCHECK); })); double delta = KStarsData::Instance()->ut().secsTo(startUTime); @@ -709,7 +712,7 @@ // When scheduler state JOBCHECK changes to RUN_SCHEDULER. QVERIFY(iterateScheduler("Wait for Job Interruption", 1000, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); delta = KStarsData::Instance()->ut().secsTo(interruptUTime); @@ -758,7 +761,7 @@ QVERIFY(iterateScheduler("Wait for Sleep State", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_WAKEUP); + return (scheduler->moduleState()->timerState() == Ekos::RUN_WAKEUP); })); } @@ -767,7 +770,7 @@ // Make sure it wakes up at the proper time. QVERIFY(iterateScheduler("Wait for Wakeup Tomorrow", DEFAULT_ITERATIONS, &sleepMs, ¤tUTime, [&]() -> bool { - return (scheduler->timerState == Scheduler::RUN_SCHEDULER); + return (scheduler->moduleState()->timerState() == Ekos::RUN_SCHEDULER); })); fprintf(stderr, "Times instance %s vs reference %s, diff %lld\n", @@ -782,15 +785,15 @@ bool readyOnce = false; QVERIFY(iterateScheduler("Wait for Job Startup & Unparked", 50, &sleepMs, ¤tUTime, [&]() -> bool { - if (scheduler->mountInterface != nullptr && - scheduler->captureInterface != nullptr && !readyOnce) + if (scheduler->process()->mountInterface() != nullptr && + scheduler->process()->captureInterface() != nullptr && !readyOnce) { // Send a ready signal since the scheduler expects it. readyOnce = true; mount->sendReady(); capture->sendReady(); } - return (scheduler->timerState == Scheduler::RUN_JOBCHECK && + return (scheduler->moduleState()->timerState() == Ekos::RUN_JOBCHECK && mount->parkStatus() == ISD::PARK_UNPARKED); })); } @@ -807,7 +810,7 @@ KStarsDateTime startUTime = jobStartUTime.addSecs(-1 * 3600 - Options::leadTime() * 60); // define culmination offset of 1h as startup condition - m_startupCondition.type = SchedulerJob::START_AT; + m_startupCondition.type = Ekos::START_AT; m_startupCondition.atLocalDateTime = jobStartLocalTime; // initialize the the scheduler @@ -857,7 +860,7 @@ // move forward in 20s steps WithInterval interval(20000, scheduler); // define culmination offset of 1h as startup condition - m_startupCondition.type = SchedulerJob::START_ASAP; + m_startupCondition.type = Ekos::START_ASAP; // initialize the the scheduler QTemporaryDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/test-XXXXXX"); QVector esqVector; @@ -892,7 +895,7 @@ ArtificialHorizon horizon; addHorizonConstraint(&horizon, "r1", true, QVector({100, 120}), QVector({40, 40})); - SchedulerJob::setHorizon(&horizon); + Ekos::SchedulerJob::setHorizon(&horizon); GeoLocation geo(dms(-122, 10), dms(37, 26, 30), "Silicon Valley", "CA", "USA", -8); QVector targetObjects; @@ -911,7 +914,7 @@ // Re-check enforce artificial horizon, but remove the constraint, and the wakeup time also goes back to it's original time. init(); // Reset the scheduler. ArtificialHorizon emptyHorizon; - SchedulerJob::setHorizon(&emptyHorizon); + Ekos::SchedulerJob::setHorizon(&emptyHorizon); runSimpleJob(geo, targetObjects[0], startUTime, originalWakeupTime, /* enforce artificial horizon */ true); // Testing that the artificial horizon constraint will end a job @@ -930,7 +933,7 @@ // cross past 180 and the scheduler will want to restart it before dawn. addHorizonConstraint(&shutdownHorizon, "h", true, QVector({175, 200}), QVector({70, 70})); - SchedulerJob::setHorizon(&shutdownHorizon); + Ekos::SchedulerJob::setHorizon(&shutdownHorizon); // We'll start the scheduler at 3am local time. startUTime = QDateTime(QDate(2021, 6, 14), QTime(10, 0, 0), Qt::UTC); @@ -967,7 +970,7 @@ void TestEkosSchedulerOps::testGreedySchedulerRun() { - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); // This test will iterate the scheduler every 40 simulated seconds (to save testing time). WithInterval interval(40000, scheduler); @@ -980,7 +983,7 @@ ArtificialHorizon shutdownHorizon; addHorizonConstraint(&shutdownHorizon, "h", true, QVector({175, 200}), QVector({70, 70})); - SchedulerJob::setHorizon(&shutdownHorizon); + Ekos::SchedulerJob::setHorizon(&shutdownHorizon); // Start the scheduler about 9pm local const QDateTime startUTime = QDateTime(QDate(2021, 6, 14), QTime(4, 0, 0), Qt::UTC); @@ -1070,7 +1073,7 @@ QFETCH(int, iterations); TestEkosSchedulerHelper::CompletionCondition completionCondition; - completionCondition.type = SchedulerJob::FINISH_REPEAT; + completionCondition.type = Ekos::FINISH_REPEAT; completionCondition.repeat = iterations; startupJob(geo, startUTime, &dir, TestEkosSchedulerHelper::getSchedulerFile(targetObject, m_startupCondition, completionCondition, {true, true, true, true}, @@ -1081,7 +1084,8 @@ QFETCH(bool, scheduled); // verify if the job is scheduled as expected - QVERIFY(scheduler->jobs[0]->getState() == (scheduled ? SchedulerJob::JOB_SCHEDULED : SchedulerJob::JOB_COMPLETE)); + QVERIFY(scheduler->moduleState()->jobs()[0]->getState() == (scheduled ? Ekos::SchedulerJob::JOB_SCHEDULED : + Ekos::SchedulerJob::JOB_COMPLETE)); } void TestEkosSchedulerOps::loadGreedySchedule( @@ -1155,13 +1159,13 @@ // so 10 minutes is approx 5 of these timesteps. constexpr int checkScheduleTolerance = 600; - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); // Setup geo and an artificial horizon. GeoLocation geo(dms(-122, 10), dms(37, 26, 30), "Silicon Valley", "CA", "USA", -8); ArtificialHorizon shutdownHorizon; addHorizonConstraint(&shutdownHorizon, "h", true, QVector({175, 200}), QVector({70, 70})); - SchedulerJob::setHorizon(&shutdownHorizon); + Ekos::SchedulerJob::setHorizon(&shutdownHorizon); // Start the scheduler about 9pm local const QDateTime startUTime = QDateTime(QDate(2021, 6, 14), QTime(4, 0, 0), Qt::UTC); initTimeGeo(geo, startUTime); @@ -1172,14 +1176,14 @@ TestEkosSchedulerHelper::StartupCondition asapStartupCondition, atStartupCondition; TestEkosSchedulerHelper::CompletionCondition finishCompletionCondition, loopCompletionCondition; TestEkosSchedulerHelper::CompletionCondition repeat2CompletionCondition, atCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - atStartupCondition.type = SchedulerJob::START_AT; + asapStartupCondition.type = Ekos::START_ASAP; + atStartupCondition.type = Ekos::START_AT; atStartupCondition.atLocalDateTime = QDateTime(QDate(2021, 6, 14), QTime(1, 0, 0), Qt::LocalTime); - finishCompletionCondition.type = SchedulerJob::FINISH_SEQUENCE; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; - repeat2CompletionCondition.type = SchedulerJob::FINISH_REPEAT; + finishCompletionCondition.type = Ekos::FINISH_SEQUENCE; + loopCompletionCondition.type = Ekos::FINISH_LOOP; + repeat2CompletionCondition.type = Ekos::FINISH_REPEAT; repeat2CompletionCondition.repeat = 2; - atCompletionCondition.type = SchedulerJob::FINISH_AT; + atCompletionCondition.type = Ekos::FINISH_AT; atCompletionCondition.atLocalDateTime = QDateTime(QDate(2021, 6, 14), QTime(3, 30, 0), Qt::LocalTime); // Write the scheduler and sequence files. @@ -1200,6 +1204,17 @@ {"Deneb", "2021/06/14 22:44", "2021/06/15 03:48"}}, scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + // Disable greedy scheduling, and Deneb should NOT run until Altair is done. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/13 23:34", "2021/06/14 03:00"}, + {"Deneb", "2021/06/14 03:01", "2021/06/14 03:53"}, + {"Deneb", "2021/06/14 22:44", "2021/06/15 03:52"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); + // As above, except Altair has completion condition repeat 2. It should run longer. // This makes a mess of things, as Altair can't complete during the first night, running into an artificial horizon constraint. // It also can't start the 2nd night as early as Deneb, so the 2nd night is Deneb, Altair (completing), Deneb, and Deneb finishes the 3rd night. @@ -1216,6 +1231,17 @@ {"Deneb", "2021/06/15 02:30", "2021/06/15 03:53"}}, scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + // Again disable greedy scheduling, and Deneb should NOT run until Altair is done. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/13 23:34", "2021/06/14 03:18"}, + {"Altair", "2021/06/14 23:30", "2021/06/15 02:32"}, + {"Deneb", "2021/06/15 02:33", "2021/06/15 03:53"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); + // Now we're using START_AT 6/14 1am for Altair (but not repeating twice). // Deneb will run until then (1am) the 1st night. Altair will run until it hits the horizon constraint. // Deneb runs through the end of the night, and again the next night until it completes. @@ -1230,6 +1256,17 @@ {"Deneb", "2021/06/14 22:44", "2021/06/15 02:44"}}, scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + // Again disable greedy scheduling, and Deneb should NOT run until Altair is done. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/14 01:00", "2021/06/14 03:21"}, + {"Deneb", "2021/06/14 03:22", "2021/06/14 03:53"}, + {"Deneb", "2021/06/14 22:44", "2021/06/15 03:53"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); + // We again use START_AT 6/14 1am for Altair, but force Deneb to complete by 3:30am on 6/14. // So we get the same first two lines as above, but now Deneb stops on the 3rd line at 3:30. loadGreedySchedule(true, "Altair", atStartupCondition, finishCompletionCondition, dir, schedJob200x60, 30); @@ -1242,7 +1279,17 @@ {"Deneb", "2021/06/14 03:22", "2021/06/14 03:30"}}, scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); - // Finally, we have the same Altair constraints, but this time allow Deneb to run forever. + // Again disable greedy scheduling, and Deneb should NOT run until Altair is done. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/14 01:00", "2021/06/14 03:21"}, + {"Deneb", "2021/06/14 03:22", "2021/06/14 03:30"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); + + // We have the same Altair constraints, but this time allow Deneb to run forever. // It will look like the 3rd test, except Deneb keeps running through the end of the simulated time (2 days). loadGreedySchedule(true, "Altair", atStartupCondition, finishCompletionCondition, dir, schedJob200x60, 30); loadGreedySchedule(false, "Deneb", asapStartupCondition, loopCompletionCondition, dir, schedJob400x60, 30); @@ -1254,6 +1301,41 @@ {"Deneb", "2021/06/14 03:22", "2021/06/14 03:53"}, {"Deneb", "2021/06/14 22:44", "2021/06/15 03:52"}}, scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + + // Again disable greedy scheduling, and Deneb should NOT run until Altair is done. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/14 01:00", "2021/06/14 03:19"}, + {"Deneb", "2021/06/14 03:20", "2021/06/14 03:52"}, + {"Deneb", "2021/06/14 22:44", "2021/06/15 03:52"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); + + // Altair stars asap, Deneb has an at 1am startup and loop finish. + // Altair should start when it's able (about 23:35) but get interrupted by deneb which is higher priority + // because of its startat. Altair will start up again the next evening because Deneb's startat will have expired. + loadGreedySchedule(true, "Altair", asapStartupCondition, finishCompletionCondition, dir, schedJob200x60, 30); + loadGreedySchedule(false, "Deneb", atStartupCondition, loopCompletionCondition, dir, schedJob400x60, 30); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/13 23:34", "2021/06/14 01:00"}, + {"Deneb", "2021/06/14 01:00", "2021/06/14 03:52"}, + {"Altair", "2021/06/14 23:30", "2021/06/15 01:31"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + + // Again disable greedy scheduling. Nothing should change as no jobs were running before higher priority ones. + Options::setGreedyScheduling(false); + scheduler->evaluateJobs(false); + QVERIFY(checkSchedule( + { + {"Altair", "2021/06/13 23:34", "2021/06/14 01:00"}, + {"Deneb", "2021/06/14 01:00", "2021/06/14 03:52"}, + {"Altair", "2021/06/14 23:30", "2021/06/15 01:31"}}, + scheduler->getGreedyScheduler()->getSchedule(), checkScheduleTolerance)); + Options::setGreedyScheduling(true); } void TestEkosSchedulerOps::testGroups() @@ -1262,13 +1344,13 @@ // so 10 minutes is approx 5 of these timesteps. constexpr int checkScheduleTolerance = 600; - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); // Setup geo and an artificial horizon. GeoLocation geo(dms(-122, 10), dms(37, 26, 30), "Silicon Valley", "CA", "USA", -8); ArtificialHorizon shutdownHorizon; addHorizonConstraint(&shutdownHorizon, "h", true, QVector({175, 200}), QVector({70, 70})); - SchedulerJob::setHorizon(&shutdownHorizon); + Ekos::SchedulerJob::setHorizon(&shutdownHorizon); // Start the scheduler about 9pm local const QDateTime startUTime = QDateTime(QDate(2021, 6, 14), QTime(4, 0, 0), Qt::UTC); initTimeGeo(geo, startUTime); @@ -1280,10 +1362,10 @@ TestEkosSchedulerHelper::StartupCondition asapStartupCondition, atStartupCondition; TestEkosSchedulerHelper::CompletionCondition finishCompletionCondition, loopCompletionCondition; TestEkosSchedulerHelper::CompletionCondition repeat2CompletionCondition, atCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - finishCompletionCondition.type = SchedulerJob::FINISH_SEQUENCE; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; - repeat2CompletionCondition.type = SchedulerJob::FINISH_REPEAT; + asapStartupCondition.type = Ekos::START_ASAP; + finishCompletionCondition.type = Ekos::FINISH_SEQUENCE; + loopCompletionCondition.type = Ekos::FINISH_LOOP; + repeat2CompletionCondition.type = Ekos::FINISH_REPEAT; repeat2CompletionCondition.repeat = 2; // Write the scheduler and sequence files. @@ -1294,14 +1376,14 @@ // Given the grouping we should see jobs scheduled about every 30 minutes // orderdc as: J1, J2, J3, J2 (skips the completed J1), J3, J2 (looing forever as J3 is now done). loadGreedySchedule(true, "Altair", asapStartupCondition, finishCompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J1finish"); - scheduler->getJobs().last()->setGroup("group1"); + scheduler->moduleState()->jobs().last()->setName("J1finish"); + scheduler->moduleState()->jobs().last()->setGroup("group1"); loadGreedySchedule(false, "Altair", asapStartupCondition, loopCompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J2loop"); - scheduler->getJobs().last()->setGroup("group1"); + scheduler->moduleState()->jobs().last()->setName("J2loop"); + scheduler->moduleState()->jobs().last()->setGroup("group1"); loadGreedySchedule(false, "Altair", asapStartupCondition, repeat2CompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J3repeat2"); - scheduler->getJobs().last()->setGroup("group1"); + scheduler->moduleState()->jobs().last()->setName("J3repeat2"); + scheduler->moduleState()->jobs().last()->setGroup("group1"); scheduler->evaluateJobs(false); QVERIFY(checkSchedule( @@ -1318,11 +1400,11 @@ // Now do the same thing, but this time disable the group scheduling (by not assigning groups). // This time J1 should run then J2 will just run/repeat forever. loadGreedySchedule(true, "Altair", asapStartupCondition, finishCompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J1finish"); + scheduler->moduleState()->jobs().last()->setName("J1finish"); loadGreedySchedule(false, "Altair", asapStartupCondition, loopCompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J2loop"); + scheduler->moduleState()->jobs().last()->setName("J2loop"); loadGreedySchedule(false, "Altair", asapStartupCondition, repeat2CompletionCondition, dir, schedJob30minutes, 30); - scheduler->getJobs().last()->setName("J3repeat2"); + scheduler->moduleState()->jobs().last()->setName("J3repeat2"); scheduler->evaluateJobs(false); QVERIFY(checkSchedule( @@ -1335,14 +1417,14 @@ void TestEkosSchedulerOps::testGreedyAborts() { - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); // Allow 10 minutes of slop in the schedule. The scheduler simulates every 2 minutes, // so 10 minutes is approx 5 of these timesteps. constexpr int checkScheduleTolerance = 600; - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); - SchedulerJob::setHorizon(nullptr); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); + Ekos::SchedulerJob::setHorizon(nullptr); // Setup geo and an artificial horizon. GeoLocation geo(dms(-122, 10), dms(37, 26, 30), "Silicon Valley", "CA", "USA", -8); @@ -1354,8 +1436,8 @@ auto schedJob200x60 = QVector(1, {200, 60, "Red", "."}); TestEkosSchedulerHelper::StartupCondition asapStartupCondition; TestEkosSchedulerHelper::CompletionCondition loopCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; + asapStartupCondition.type = Ekos::START_ASAP; + loopCompletionCondition.type = Ekos::FINISH_LOOP; QTemporaryDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/test-XXXXXX"); // Parameters related to resheduling aborts and the delay times are in the scheduler .esl file created in loadGreedyScheduler. @@ -1403,18 +1485,18 @@ enforceTwilight, enforceHorizon, errorDelay); // Otherwise time changes below will trigger reschedules and mess up test. - scheduler->state = Ekos::SCHEDULER_RUNNING; + scheduler->moduleState()->setSchedulerState(Ekos::SCHEDULER_RUNNING); // Find the M 104 job and make it aborted at 12:59am KStarsDateTime abortUTime(QDate(2022, 2, 28), QTime(8, 59, 00), Qt::UTC); KStarsData::Instance()->changeDateTime(abortUTime); - SchedulerJob *m104Job = nullptr; - foreach (auto &job, scheduler->jobs) + Ekos::SchedulerJob *m104Job = nullptr; + foreach (auto &job, scheduler->moduleState()->jobs()) if (job->getName() == "M 104") { m104Job = job; - m104Job->setState(SchedulerJob::JOB_ABORTED); + m104Job->setState(Ekos::SchedulerJob::JOB_ABORTED); } QVERIFY(m104Job != nullptr); @@ -1443,21 +1525,21 @@ // And ngc3628 should not be preempted right away, QDateTime localTime(QDate(2022, 2, 28), QTime(1, 00, 00), Qt::LocalTime); - bool keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->jobs, localTime, ngc3628); + bool keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->moduleState()->jobs(), localTime, ngc3628); QVERIFY(keepRunning); // nor in a half-hour. auto newTime = evalUTime.addSecs(1800); KStarsData::Instance()->changeDateTime(newTime); localTime = localTime.addSecs(1800); - keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->jobs, localTime, ngc3628); + keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->moduleState()->jobs(), localTime, ngc3628); QVERIFY(keepRunning); // But if we wait until 2am, m104 should preempt it, newTime = newTime.addSecs(1800); KStarsData::Instance()->changeDateTime(newTime); localTime = localTime.addSecs(1800); - keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->jobs, localTime, ngc3628); + keepRunning = scheduler->getGreedyScheduler()->checkJob(scheduler->moduleState()->jobs(), localTime, ngc3628); QVERIFY(!keepRunning); // and M104 should be scheduled to start running "now" (2am). @@ -1472,7 +1554,7 @@ void TestEkosSchedulerOps::testArtificialCeiling() { constexpr int checkScheduleTolerance = 600; - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); ArtificialHorizon horizon; QVector az1 = {259.0, 260.0, 299.0, 300.0, 330.0, 0.0, 30.0, 70.0, 71.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 259.99}; @@ -1485,7 +1567,7 @@ // Setup geo and an artificial horizon. GeoLocation geo(dms(-75, 40), dms(45, 40), "New York", "NY", "USA", -5); - SchedulerJob::setHorizon(&horizon); + Ekos::SchedulerJob::setHorizon(&horizon); // Start the scheduler about 9pm local const QDateTime startUTime = QDateTime(QDate(2022, 8, 21), QTime(16, 0, 0), Qt::UTC); initTimeGeo(geo, startUTime); @@ -1495,8 +1577,8 @@ TestEkosSchedulerHelper::StartupCondition asapStartupCondition; TestEkosSchedulerHelper::CompletionCondition loopCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; + asapStartupCondition.type = Ekos::START_ASAP; + loopCompletionCondition.type = Ekos::FINISH_LOOP; // Write the scheduler and sequence files. QTemporaryDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/test-XXXXXX"); @@ -1526,8 +1608,8 @@ Options::setSettingAltitudeCutoff(3); Options::setPreDawnTime(0); - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); - SchedulerJob::setHorizon(nullptr); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); + Ekos::SchedulerJob::setHorizon(nullptr); GeoLocation geo(dms(9, 45, 54), dms(49, 6, 22), "Schwaebisch Hall", "Baden-Wuerttemberg", "Germany", +1); const QDateTime time1 = QDateTime(QDate(2022, 3, 7), QTime(21, 28, 55), Qt::UTC); //22:28 local @@ -1544,8 +1626,8 @@ TestEkosSchedulerHelper::StartupCondition asapStartupCondition; TestEkosSchedulerHelper::CompletionCondition loopCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; + asapStartupCondition.type = Ekos::START_ASAP; + loopCompletionCondition.type = Ekos::FINISH_LOOP; QTemporaryDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/test-XXXXXX"); loadGreedySchedule(true, "NGC 2359", asapStartupCondition, loopCompletionCondition, dir, wolfgangJob, 20); @@ -1585,9 +1667,9 @@ // This is fixed, and now, when re-evaluated at 22:28 it should not be preempted. auto greedy = scheduler->getGreedyScheduler(); - SchedulerJob *job2359 = scheduler->getJobs()[0]; + Ekos::SchedulerJob *job2359 = scheduler->moduleState()->jobs()[0]; auto time1Local = (Qt::UTC == time1.timeSpec() ? geo.UTtoLT(KStarsDateTime(time1)) : time1); - QVERIFY(greedy->checkJob(scheduler->getJobs(), time1Local, job2359)); + QVERIFY(greedy->checkJob(scheduler->moduleState()->jobs(), time1Local, job2359)); } // This creates empty/dummy fits files to be discovered inside estimateJobTime, when it @@ -1618,8 +1700,8 @@ Options::setDitherEnabled(true); Options::setDitherFrames(1); - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); - SchedulerJob::setHorizon(nullptr); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); + Ekos::SchedulerJob::setHorizon(nullptr); QTemporaryDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/test-XXXXXX"); GeoLocation geo(dms(9, 45, 54), dms(49, 6, 22), "Schwaebisch Hall", "Baden-Wuerttemberg", "Germany", +1); @@ -1637,10 +1719,10 @@ TestEkosSchedulerHelper::StartupCondition asapStartupCondition; TestEkosSchedulerHelper::CompletionCondition loopCompletionCondition; - asapStartupCondition.type = SchedulerJob::START_ASAP; - loopCompletionCondition.type = SchedulerJob::FINISH_LOOP; + asapStartupCondition.type = Ekos::START_ASAP; + loopCompletionCondition.type = Ekos::FINISH_LOOP; TestEkosSchedulerHelper::CompletionCondition repeat9; - repeat9.type = SchedulerJob::FINISH_REPEAT; + repeat9.type = Ekos::FINISH_REPEAT; repeat9.repeat = 9; makeFitsFiles(QString("%1%2").arg(path, "/NGC_2359/Light/L/NGC_2359_Light_L"), 41); @@ -1729,14 +1811,14 @@ Options::setSettingAltitudeCutoff(3); Options::setPreDawnTime(0); Options::setRememberJobProgress(false); - Options::setSchedulerAlgorithm(Scheduler::ALGORITHM_GREEDY); + Options::setSchedulerAlgorithm(Ekos::ALGORITHM_GREEDY); GeoLocation geo(dms(9, 45, 54), dms(49, 6, 22), "Schwaebisch Hall", "Baden-Wuerttemberg", "Germany", +1); const QDateTime time1 = QDateTime(QDate(2022, 3, 7), QTime(21, 28, 55), Qt::UTC); //22:28 local initTimeGeo(geo, time1); qCInfo(KSTARS_EKOS_TEST) << QString("Calculate schedule with no artificial horizon and 0 min altitude."); - SchedulerJob::setHorizon(nullptr); + Ekos::SchedulerJob::setHorizon(nullptr); scheduler->load(true, QString("file://%1").arg(esl0Path)); const QVector scheduleMinAlt0 = { @@ -1783,7 +1865,7 @@ QVERIFY(checkSchedule(scheduleMinAlt0, scheduler->getGreedyScheduler()->getSchedule(), 300)); qCInfo(KSTARS_EKOS_TEST) << QString("Calculate schedule with no artificial horizon and 30 min altitude."); - SchedulerJob::setHorizon(nullptr); + Ekos::SchedulerJob::setHorizon(nullptr); scheduler->load(true, QString("file://%1").arg(esl30Path)); const QVector scheduleMinAlt30 = { @@ -1847,7 +1929,7 @@ 22.579722, 22.644444, 22.672222})); qCInfo(KSTARS_EKOS_TEST) << QString("Calculate schedule with large artificial horizon."); - SchedulerJob::setHorizon(&largeHorizon); + Ekos::SchedulerJob::setHorizon(&largeHorizon); scheduler->load(true, QString("file://%1").arg(esl30Path)); const QVector scheduleAHMinAlt30 = { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_simulator.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_simulator.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/kstars_ui/test_ekos_simulator.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/kstars_ui/test_ekos_simulator.h 2023-12-03 05:23:16.000000000 +0000 @@ -19,6 +19,7 @@ #include #include "ekos/manager.h" #include "ekos/auxiliary/opticaltrainmanager.h" +#include "ekos/mount/mount.h" #define KTRY_EKOS_SELECT_PROFILE(profile) do { \ QString const p(profile); \ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/scheduler/testschedulerunit.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/scheduler/testschedulerunit.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/Tests/scheduler/testschedulerunit.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/Tests/scheduler/testschedulerunit.cpp 2023-12-03 05:23:16.000000000 +0000 @@ -10,11 +10,14 @@ */ #include "ekos/scheduler/scheduler.h" +#include "ekos/scheduler/schedulerprocess.h" #include "ekos/scheduler/greedyscheduler.h" #include "ekos/scheduler/schedulerjob.h" +#include "ekos/scheduler/schedulermodulestate.h" #include "indi/indiproperty.h" #include "ekos/capture/sequencejob.h" #include "ekos/capture/placeholderpath.h" +#include "geolocation.h" #include "Options.h" #include @@ -45,10 +48,10 @@ void evaluateJobsTest(); private: - void runSetupJob(SchedulerJob &job, + void runSetupJob(Ekos::SchedulerJob &job, GeoLocation *geo, KStarsDateTime *localTime, const QString &name, const dms &ra, const dms &dec, double positionAngle, const QUrl &sequenceUrl, - const QUrl &fitsUrl, SchedulerJob::StartupCondition sCond, const QDateTime &sTime, SchedulerJob::CompletionCondition eCond, + const QUrl &fitsUrl, Ekos::StartupCondition sCond, const QDateTime &sTime, Ekos::CompletionCondition eCond, const QDateTime &eTime, int eReps, double minAlt, double minMoonSep = 0, bool enforceWeather = false, bool enforceTwilight = true, bool enforceArtificialHorizon = true, bool track = true, bool focus = true, bool align = true, bool guide = true); @@ -139,29 +142,29 @@ } // The runSetupJob() utility calls the static function Scheduler::setupJob() with all the args passed in -// and tests to see that the resulting SchedulerJob object has the values that were requested. -void TestSchedulerUnit::runSetupJob( - SchedulerJob &job, GeoLocation *geo, KStarsDateTime *localTime, const QString &name, - const dms &ra, const dms &dec, double positionAngle, const QUrl &sequenceUrl, - const QUrl &fitsUrl, SchedulerJob::StartupCondition sCond, const QDateTime &sTime, - SchedulerJob::CompletionCondition eCond, const QDateTime &eTime, int eReps, - double minAlt, double minMoonSep, bool enforceWeather, bool enforceTwilight, - bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide) +// and tests to see that the resulting Ekos::SchedulerJob object has the values that were requested. +void TestSchedulerUnit::runSetupJob(Ekos::SchedulerJob &job, GeoLocation *geo, KStarsDateTime *localTime, + const QString &name, + const dms &ra, const dms &dec, double positionAngle, const QUrl &sequenceUrl, + const QUrl &fitsUrl, Ekos::StartupCondition sCond, const QDateTime &sTime, + Ekos::CompletionCondition eCond, const QDateTime &eTime, int eReps, + double minAlt, double minMoonSep, bool enforceWeather, bool enforceTwilight, + bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide) { // Setup the time and geo. KStarsDateTime ut = geo->LTtoUT(*localTime); job.setGeo(geo); - Scheduler::setLocalTime(localTime); - QVERIFY(Scheduler::hasLocalTime() && job.hasGeo()); + Ekos::SchedulerModuleState::setLocalTime(localTime); + QVERIFY(Ekos::SchedulerModuleState::hasLocalTime() && job.hasGeo()); QString group = ""; - Scheduler::setupJob(job, name, group, ra, dec, ut.djd(), positionAngle, - sequenceUrl, fitsUrl, - sCond, sTime, - eCond, eTime, eReps, - minAlt, minMoonSep, - enforceWeather, enforceTwilight, enforceArtificialHorizon, - track, focus, align, guide); + Ekos::SchedulerProcess::setupJob(job, name, group, ra, dec, ut.djd(), positionAngle, + sequenceUrl, fitsUrl, + sCond, sTime, + eCond, eTime, eReps, + minAlt, minMoonSep, + enforceWeather, enforceTwilight, enforceArtificialHorizon, + track, focus, align, guide); QVERIFY(name == job.getName()); QVERIFY(ra == job.getTargetCoords().ra0()); QVERIFY(dec == job.getTargetCoords().dec0()); @@ -177,10 +180,10 @@ QVERIFY(sCond == job.getStartupCondition()); switch (sCond) { - case SchedulerJob::START_AT: + case Ekos::START_AT: QVERIFY(sTime == job.getStartupTime()); break; - case SchedulerJob::START_ASAP: + case Ekos::START_ASAP: QVERIFY(QDateTime() == job.getStartupTime()); break; } @@ -188,58 +191,58 @@ QVERIFY(eCond == job.getCompletionCondition()); switch (eCond) { - case SchedulerJob::FINISH_AT: + case Ekos::FINISH_AT: QVERIFY(eTime == job.getCompletionTime()); QVERIFY(0 == job.getRepeatsRequired()); QVERIFY(0 == job.getRepeatsRemaining()); break; - case SchedulerJob::FINISH_REPEAT: + case Ekos::FINISH_REPEAT: QVERIFY(QDateTime() == job.getCompletionTime()); QVERIFY(eReps == job.getRepeatsRequired()); QVERIFY(eReps == job.getRepeatsRemaining()); break; - case SchedulerJob::FINISH_SEQUENCE: + case Ekos::FINISH_SEQUENCE: QVERIFY(QDateTime() == job.getCompletionTime()); QVERIFY(1 == job.getRepeatsRequired()); QVERIFY(1 == job.getRepeatsRemaining()); break; - case SchedulerJob::FINISH_LOOP: + case Ekos::FINISH_LOOP: QVERIFY(QDateTime() == job.getCompletionTime()); QVERIFY(0 == job.getRepeatsRequired()); QVERIFY(0 == job.getRepeatsRemaining()); break; } - SchedulerJob::StepPipeline pipe = job.getStepPipeline(); - QVERIFY((track && (pipe & SchedulerJob::USE_TRACK)) || (!track && !(pipe & SchedulerJob::USE_TRACK))); - QVERIFY((focus && (pipe & SchedulerJob::USE_FOCUS)) || (!focus && !(pipe & SchedulerJob::USE_FOCUS))); - QVERIFY((align && (pipe & SchedulerJob::USE_ALIGN)) || (!align && !(pipe & SchedulerJob::USE_ALIGN))); - QVERIFY((guide && (pipe & SchedulerJob::USE_GUIDE)) || (!guide && !(pipe & SchedulerJob::USE_GUIDE))); + Ekos::SchedulerJob::StepPipeline pipe = job.getStepPipeline(); + QVERIFY((track && (pipe & Ekos::SchedulerJob::USE_TRACK)) || (!track && !(pipe & Ekos::SchedulerJob::USE_TRACK))); + QVERIFY((focus && (pipe & Ekos::SchedulerJob::USE_FOCUS)) || (!focus && !(pipe & Ekos::SchedulerJob::USE_FOCUS))); + QVERIFY((align && (pipe & Ekos::SchedulerJob::USE_ALIGN)) || (!align && !(pipe & Ekos::SchedulerJob::USE_ALIGN))); + QVERIFY((guide && (pipe & Ekos::SchedulerJob::USE_GUIDE)) || (!guide && !(pipe & Ekos::SchedulerJob::USE_GUIDE))); } void TestSchedulerUnit::setupGeoAndTimeTest() { - SchedulerJob job(nullptr); - QVERIFY(!Scheduler::hasLocalTime() && !job.hasGeo()); + Ekos::SchedulerJob job(nullptr); + QVERIFY(!Ekos::SchedulerModuleState::hasLocalTime() && !job.hasGeo()); job.setGeo(&siliconValley); - Scheduler::setLocalTime(&midNight); - QVERIFY(Scheduler::hasLocalTime() && job.hasGeo()); + Ekos::SchedulerModuleState::setLocalTime(&midNight); + QVERIFY(Ekos::SchedulerModuleState::hasLocalTime() && job.hasGeo()); QVERIFY(job.getGeo()->lat() == siliconValley.lat()); QVERIFY(job.getGeo()->lng() == siliconValley.lng()); QVERIFY(job.getLocalTime() == midNight); } -Q_DECLARE_METATYPE(SchedulerJob::StartupCondition); -Q_DECLARE_METATYPE(SchedulerJob::CompletionCondition); +Q_DECLARE_METATYPE(Ekos::StartupCondition); +Q_DECLARE_METATYPE(Ekos::CompletionCondition); // Test Scheduler::setupJob(). -// Calls runSetupJob (which calls SchedulerJob::setupJob(...)) in a few different ways -// to test different kinds of SchedulerJob initializations. +// Calls runSetupJob (which calls Ekos::SchedulerJob::setupJob(...)) in a few different ways +// to test different kinds of Ekos::SchedulerJob initializations. void TestSchedulerUnit::setupJobTest_data() { - QTest::addColumn("START_CONDITION"); + QTest::addColumn("START_CONDITION"); QTest::addColumn("START_TIME"); - QTest::addColumn("END_CONDITION"); + QTest::addColumn("END_CONDITION"); QTest::addColumn("END_TIME"); QTest::addColumn("REPEATS"); QTest::addColumn("ENFORCE_WEATHER"); @@ -251,8 +254,8 @@ QTest::addColumn("GUIDE"); QTest::newRow("ASAP_TO_FINISH") - << SchedulerJob::START_ASAP << QDateTime() // start conditions - << SchedulerJob::FINISH_SEQUENCE << QDateTime() << 1 // end conditions + << Ekos::START_ASAP << QDateTime() // start conditions + << Ekos::FINISH_SEQUENCE << QDateTime() << 1 // end conditions << false // enforce weather << true // enforce twilight << true // enforce artificial horizon @@ -262,9 +265,9 @@ << true; // guide QTest::newRow("START_AT_FINISH_AT") - << SchedulerJob::START_AT // start conditions + << Ekos::START_AT // start conditions << QDateTime(QDate(2021, 4, 17), QTime(0, 1, 0), QTimeZone(-7 * 3600)) - << SchedulerJob::FINISH_AT // end conditions + << Ekos::FINISH_AT // end conditions << QDateTime(QDate(2021, 4, 17), QTime(0, 2, 0), QTimeZone(-7 * 3600)) << 1 << true // enforce weather @@ -276,8 +279,8 @@ << true; // guide QTest::newRow("ASAP_TO_LOOP") - << SchedulerJob::START_ASAP << QDateTime() // start conditions - << SchedulerJob::FINISH_SEQUENCE << QDateTime() << 1 // end conditions + << Ekos::START_ASAP << QDateTime() // start conditions + << Ekos::FINISH_SEQUENCE << QDateTime() << 1 // end conditions << false // enforce weather << false // enforce twilight << true // enforce artificial horizon @@ -289,9 +292,9 @@ void TestSchedulerUnit::setupJobTest() { - QFETCH(SchedulerJob::StartupCondition, START_CONDITION); + QFETCH(Ekos::StartupCondition, START_CONDITION); QFETCH(QDateTime, START_TIME); - QFETCH(SchedulerJob::CompletionCondition, END_CONDITION); + QFETCH(Ekos::CompletionCondition, END_CONDITION); QFETCH(QDateTime, END_TIME); QFETCH(int, REPEATS); QFETCH(bool, ENFORCE_WEATHER); @@ -302,7 +305,7 @@ QFETCH(bool, ALIGN); QFETCH(bool, GUIDE); - SchedulerJob job(nullptr); + Ekos::SchedulerJob job(nullptr); runSetupJob(job, &siliconValley, &midNight, "Job1", midnightRA, testDEC, 5.0, QUrl("1"), QUrl("2"), START_CONDITION, START_TIME, @@ -335,8 +338,8 @@ // A full test for capture sequences should be written in capture testing. void TestSchedulerUnit::loadSequenceQueueTest() { - // Create a new SchedulerJob and pass in a null moon pointer. - SchedulerJob schedJob(nullptr); + // Create a new Ekos::SchedulerJob and pass in a null moon pointer. + Ekos::SchedulerJob schedJob(nullptr); QList jobs; bool hasAutoFocus = false; @@ -366,15 +369,15 @@ { // Some computations use the local time, which is normally taken from KStars::Instance()->lt() // unless this is set. The Instance does not exist when running this unit test. - Scheduler::setLocalTime(&midNight); + Ekos::SchedulerModuleState::setLocalTime(&midNight); // First test, start ASAP and finish when the sequence is done. - SchedulerJob job(nullptr); + Ekos::SchedulerJob job(nullptr); runSetupJob(job, &siliconValley, &midNight, "Job1", midnightRA, testDEC, 5.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_SEQUENCE, QDateTime(), 1, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_SEQUENCE, QDateTime(), 1, 30.0, 5.0, false, false); // Initial map has no previous captures. @@ -391,7 +394,7 @@ // Repeat the above test, but repeat the sequence 1,2,3,4,...,10 times. for (int i = 1; i <= 10; ++i) { - job.setCompletionCondition(SchedulerJob::FINISH_REPEAT); + job.setCompletionCondition(Ekos::FINISH_REPEAT); job.setRepeatsRequired(i); QVERIFY(Scheduler::estimateJobTime(&job, capturedFramesCount, nullptr)); QVERIFY(compareFloat(overhead + i * exposureDuration, job.getEstimatedTime())); @@ -405,13 +408,13 @@ // In this case the scheduler should estimate negative completion time, as the sequence doesn't // end until the user stops it (or it is interrupted by altitude or daylight). The scheduler // doesn't estimate those stopping conditions at this point. - job.setCompletionCondition(SchedulerJob::FINISH_LOOP); + job.setCompletionCondition(Ekos::FINISH_LOOP); QVERIFY(Scheduler::estimateJobTime(&job, capturedFramesCount, nullptr)); QVERIFY(job.getEstimatedTime() < 0); // Test again with a fixed end time. The scheduler estimates the time from "now" until the end time. // Perhaps it should estimate the max of that and the FINISH_SEQUENCE time?? - job.setCompletionCondition(SchedulerJob::FINISH_AT); + job.setCompletionCondition(Ekos::FINISH_AT); KStarsDateTime stopTime(QDateTime(QDate(2021, 4, 17), QTime(1, 0, 0), QTimeZone(-7 * 3600))); job.setCompletionTime(stopTime); QVERIFY(Scheduler::estimateJobTime(&job, capturedFramesCount, nullptr)); @@ -420,24 +423,24 @@ // Test again, similar to above but given a START_AT time as well. // Now it should return the interval between the start and end times. // Again, perhaps that should be max'd with the FINISH_SEQUENCE time? - job.setStartupCondition(SchedulerJob::START_AT); + job.setStartupCondition(Ekos::START_AT); job.setStartupTime(midNight.addSecs(1800)); QVERIFY(Scheduler::estimateJobTime(&job, capturedFramesCount, nullptr)); QVERIFY(midNight.secsTo(stopTime) - 1800 == job.getEstimatedTime()); // Small test of accounting for already completed captures. // 1. Explicitly load the capture jobs - job.setStartupCondition(SchedulerJob::START_ASAP); - job.setCompletionCondition(SchedulerJob::FINISH_SEQUENCE); + job.setStartupCondition(Ekos::START_ASAP); + job.setCompletionCondition(Ekos::FINISH_SEQUENCE); QList jobs; bool hasAutoFocus = false; // The last arg is for logging. Use nullptr for testing. QVERIFY(Scheduler::loadSequenceQueue(seqFile9Filters, &job, jobs, hasAutoFocus, nullptr)); // 2. Get the signiture of the first job SequenceJob *seqJob = jobs[0]; + seqJob->setCoreProperty(Ekos::SequenceJob::SJ_TargetName, job.getName()); auto placeholderPath = Ekos::PlaceholderPath(); - QString signature = placeholderPath.generateSequenceFilename(*seqJob, - job.getName(), true, true, 1, ".fits", "", false, true); + QString signature = placeholderPath.generateSequenceFilename(*seqJob, true, true, 1, ".fits", "", false, true); seqJob->setCoreProperty(SequenceJob::SJ_Signature, signature); QString sig0 = jobs[0]->getSignature(); // 3. The first job has 6 exposures, each of 20s duration. Set it up that 2 are already done. @@ -459,9 +462,9 @@ { auto now = midNight; Ekos::GreedyScheduler scheduler; - Scheduler::setLocalTime(&now); + Ekos::SchedulerModuleState::setLocalTime(&now); // The nullptr is moon pointer. Not currently tested. - SchedulerJob job(nullptr); + Ekos::SchedulerJob job(nullptr); const double _dawn = .25, _dusk = .75; QDateTime const dawn = midNight.addSecs(_dawn * 24.0 * 3600.0); @@ -469,8 +472,8 @@ const bool rescheduleErrors = true; const bool restart = true; const QMap capturedFrames; - QList jobs; - QList jobsToProcess; + QList jobs; + QList jobsToProcess; const double minAltitude = 30.0; // Test 1: Evaluating an empty jobs list should return an empty list. @@ -484,8 +487,8 @@ runSetupJob(job, &siliconValley, &midNight, "Job1", midnightRA, testDEC, 0.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_SEQUENCE, QDateTime(), 1, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_SEQUENCE, QDateTime(), 1, minAltitude); jobs.append(&job); @@ -521,25 +524,25 @@ // Start the scheduler at 8pm but minAltitude won't be reached until after 11pm. // Job repetition takes about 45 minutes plus a little overhead. // Thus, first job, with two repetitions will be scheduled 11:10pm --> 12:43am. - SchedulerJob job1(nullptr); + Ekos::SchedulerJob job1(nullptr); auto localTime8pm = midNight.addSecs(-4 * 3600); runSetupJob(job1, &siliconValley, &localTime8pm, "Job1", midnightRA, testDEC, 0.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_REPEAT, QDateTime(), 2, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_REPEAT, QDateTime(), 2, 80.0); jobs.append(&job1); // The second job has no blocking constraints, hence it will start immediately at 08:00 pm. // Since it lasts about 48 minutes, it should terminate at 08:48 pm and won't be suspended // by the first job. - SchedulerJob job2(nullptr); + Ekos::SchedulerJob job2(nullptr); runSetupJob(job2, &siliconValley, &localTime8pm, "Job2", midnightRA, testDEC, 0.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_SEQUENCE, QDateTime(), 1, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_SEQUENCE, QDateTime(), 1, 30.0); jobs.append(&job2); @@ -572,23 +575,23 @@ // The second job, therefore, should be initially scheduled to start "tomorrow" just after dusk. // Start the scheduler at 8pm but minAltitude won't be reached until ~11:10pm, and job3 estimated conclusion is 6:39am. - SchedulerJob job3(nullptr); - Scheduler::setLocalTime(&localTime8pm); + Ekos::SchedulerJob job3(nullptr); + Ekos::SchedulerModuleState::setLocalTime(&localTime8pm); runSetupJob(job3, &siliconValley, &localTime8pm, "Job1", midnightRA, testDEC, 0.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_REPEAT, QDateTime(), 10, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_REPEAT, QDateTime(), 10, 80.0); jobs.append(&job3); // The second job should be scheduled "tomorrow" starting after dusk - SchedulerJob job4(nullptr); + Ekos::SchedulerJob job4(nullptr); runSetupJob(job4, &siliconValley, &localTime8pm, "Job2", midnightRA, testDEC, 0.0, QUrl(QString("file:%1").arg(seqFile9Filters)), QUrl(""), - SchedulerJob::START_ASAP, QDateTime(), - SchedulerJob::FINISH_SEQUENCE, QDateTime(), 1, + Ekos::START_ASAP, QDateTime(), + Ekos::FINISH_SEQUENCE, QDateTime(), 1, 80.0); jobs.append(&job4); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/changelog kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/changelog --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/changelog 2023-10-14 21:36:52.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/changelog 2023-12-03 05:23:20.000000000 +0000 @@ -1,8 +1,14 @@ -kstars-bleeding (6:3.6.7+202310142136~ubuntu22.04.1) jammy; urgency=low +kstars-bleeding (6:3.6.8+202312030523~ubuntu22.04.1) jammy; urgency=low * Auto build. - -- Jasem Mutlaq Sat, 14 Oct 2023 21:36:52 +0000 + -- Jasem Mutlaq Sun, 03 Dec 2023 05:23:20 +0000 + +kstars-bleeding (6:3.6.8) jammy; urgency=medium + + * 3.6.8 Upstream release. + + -- Jasem Mutlaq Fri, 1 Dec 2023 08:30:00 +0300 kstars-bleeding (6:3.6.7) jammy; urgency=medium diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/control kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/control --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/control 2023-10-14 21:36:52.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/control 2023-12-03 05:23:20.000000000 +0000 @@ -14,6 +14,7 @@ libqt5websockets5-dev, libqt5svg5-dev, libqt5sql5-sqlite, + libqt5datavisualization5-dev, kdoctools-dev | libkf5doctools-dev, libkf5config-dev, libkf5guiaddons-dev, diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/git-build-recipe.manifest kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/git-build-recipe.manifest --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/debian/git-build-recipe.manifest 2023-10-14 21:36:52.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/debian/git-build-recipe.manifest 2023-12-03 05:23:20.000000000 +0000 @@ -1,3 +1,3 @@ -# git-build-recipe format 0.4 deb-version {debversion}+202310142136 -lp:~mutlaqja/kstars-bleeding/+git/kstars-master git-commit:8658825d586a323bd9f350d3fa65f7db0dac3f82 -nest-part packaging lp:~mutlaqja/kstars-bleeding/+git/kstars-master packaging/linux/debian debian git-commit:8658825d586a323bd9f350d3fa65f7db0dac3f82 +# git-build-recipe format 0.4 deb-version {debversion}+202312030523 +lp:~mutlaqja/kstars-bleeding/+git/kstars-master git-commit:b384ceda6ebbbbc92c7b3feeb11f3884f15e3d9b +nest-part packaging lp:~mutlaqja/kstars-bleeding/+git/kstars-master packaging/linux/debian debian git-commit:b384ceda6ebbbbc92c7b3feeb11f3884f15e3d9b Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/aberration_inspector.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/aberration_inspector.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/aberration_inspector_3dgraphic.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/aberration_inspector_3dgraphic.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/aberration_inspector_results.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/aberration_inspector_results.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/aberration_inspector_table.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/aberration_inspector_table.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/aberration_inspector_vcurve.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/aberration_inspector_vcurve.png differ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/config.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/config.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/config.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/config.docbook 2023-12-03 05:23:16.000000000 +0000 @@ -1478,6 +1478,47 @@ + +Developer + +Developer Window + + + + + + Developer Window + + + + +Configure &kstars; window +Developer page +The Developer page provides a few checkboxes that can help +debug issues with &kstars;. There are checkboxes for saving images +in logging directories that might help debug issues. Of course, saving images +can take up disk space and should be used judiciously. + + The images that can be saved are + + + all focus images, + + + all guider images, + + + all align images, and + + + align images where the plate-solving failed. + + + The images are all saved in folders parallel to the main + logging directory. They are in folders named guide, autofocus, align, and align/failed. + + + Customizing the Display Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/developer_page.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/developer_page.png differ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-align.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-align.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-align.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-align.docbook 2023-12-03 05:23:16.000000000 +0000 @@ -21,118 +21,216 @@ - Ekos Alignment Module enables highly accurate GOTOs to within sub-arcseconds accuracy and can measure and correct polar alignment errors. This is possible thanks to the astrometry.net solver. Ekos begins by capturing an image of a star field, feeding that image to astrometry.net solver, and getting the central coordinates (RA, DEC) of the image. The solver essentially performs a pattern recognition against a catalog of millions of stars. Once the coordinates are determined, the true pointing of the telescope is known. + The Ekos Alignment Module enables highly accurate GOTOs and can measure and correct polar alignment errors. This is possible thanks to third-party plate-solving technology. The main plate-solving software used is the StellarSolver package, which itself makes use of the offline (and online) astrometry.net, ASTAP and Watney solvers. Ekos begins by capturing an image of a star field, feeding that image to the chosen solver (e.g. see astrometry.net, StellarSolver or ASTAP), and gets in return the central coordinates (RA, DEC), scale, and orientation of the image. The solver essentially performs pattern recognition against a catalog of millions of stars. Once the coordinates are determined, the true pointing of the telescope is known. - Often, there is a discrepancy between where the telescope thinks it is looking at and where it is truly pointing. The magnitude of this discrepancy can range from a few arcminutes to a couple of degrees. Ekos can then correct the discrepancy by either syncing to the new coordinates, or by slewing the mount to the desired target originally requested. + Often, there is a discrepancy between where the telescope thinks it is looking at and where it is truly pointing. The magnitude of this discrepancy can range from a few arcminutes to a couple of degrees. Ekos can correct the discrepancy by syncing to the new coordinates, and then slewing the mount to the desired target originally requested. - Furthermore, Ekos provides a Polar Alignment Assistant Tool to correct polar alignment errors. It takes three images, slewing between the images, and calculates the offset between the mount axis and polar axis. It feeds back to the user the altitude and azimuth adjustments needed to align these axes. These images are typically taken near the celestial pole (Close to Polaris for Northern Hemisphere) but can work well taken from anywhere, usually starting near the meridian and slewing either East or West. + Ekos also provides a Polar Alignment Assistant Tool to correct polar alignment errors. It takes three images, slewing between the images, and calculates the offset between the mount axis and polar axis. It feeds back to the user the altitude and azimuth adjustments needed to align these axes. These images are typically taken near the celestial pole (close to Polaris for Northern Hemisphere) but can work well taken from anywhere, usually starting near the meridian and slewing either East or West. At a minimum, you need a CCD/Webcam and a telescope that supports Slew & Sync commands. Most popular commercial telescope nowadays support such commands. - - For the Ekos Alignment Module to work, you have an option of either utilizing the online astrometry.net solver, offline, or remote solver: - - - - - Online Solver: The online solver requires no configuration, and depending on your Internet bandwidth, it might take a while to upload and solve the image. - - - - - Offline Solver: The offline solver can be faster and requires no Internet connection. In order to use the offline solver, you must install astrometry.net in addition to the necessary index files. - - - - - Remote Solver: The remote solver is an offline solver the resides on a different machine (for example, you can use Astrometry solver on StellarMate). Captured images are solved on the remote machine. - - - - - Get astrometry.net - - - If you are planning to use Offline astrometry then you need to download astrometry.net application. - - + + Typical use - Astrometry.net is already shipped with StellarMate so there is no need to install it. Index files from 16 arcminutes and above (4206 to 4019) are included with StellarMate. For any additional index files, you need to install them as necessary. To use Astrometry in StellarMate from a remote Ekos on &Linux;/&Windows;/&MacOS;, make sure to select Remote option in Ekos Alignment Module. Furthermore, make sure that the Astrometry driver is selected in your equipment profile. + Using Ekos Alignment Module, aligning your mount using the controller's 1, 2, or 3 star alignment is not strictly necessary, though for some mounts it is recommended to perform a rough 1 or 2 star alignment before using Ekos alignment module. If you are using EQMod, you can start using Ekos alignment module right away. A typical workflow for GOTO alignment involves the following steps: - - - - Ekos Remote Astrometry - - - - - - - Ekos Remote Astrometry - - - - - - &Windows; + - To use astrometry.net under &Windows;, you need to download and install the ANSVR Local Astrometry.net solver. The ANSVR mimics the astrometry.net online server on your local computer; thus the internet not required for any astrometry queries. + Start KStars and Ekos and connect to INDI. + + - After installing the ANSVR server and downloading the appropriate index files for your setup, make sure ANSVR server is up and running and then go to Ekos Alignment options where you can simply change the API URL to use the ANSVR server as illustrated below: + Unpark your mount from its home position (usually the NCP for equatorial mounts). - - - ANSVR Parameters - - - - - - - ANSVR Parameters - - - + + - In Ekos Align module, you must set the solver type to Online so that it uses the local ANSVR server for all astrometry queries. Then you can use the align module as you would normally do. + Slew to a nearby bright star using the slew telescope command in the SkyMap using the Slew the telescope to the mouse-pointer position command. + + - Remember as indicated above that StellarMate already includes astrometry.net. Therefore, if you would like to use StellarMate remotely to solve your images, simply change solver type to Remote and ensure that your equipment profile includes Astrometry driver which can be selected under the Auxiliary dropdown. This is applicable to all operating systems and not just &Windows;. + Select Slew to Target in the Solver Action on the Align page. - - - &MacOS; - Astrometry.net is already included with &kstars; for &MacOS;, so no need to install it. + After slew is complete, click Capture & Solve on the Align page. - - - &Linux; + + + Align will capture an image and try to solve it. If the solver is successful, Ekos will send a sync command to the mount and then slew to the star. The results are displayed in the Solution Results tab along with a bullseye diagram that shows the offset the reported telescope coordinates (&ie; where the telescope thinks it is looking vs. its actual pointing position in the sky as determined by the solver). Align will stop if it is within the desired error tolerance, otherwise it will repeat the Slew/Capture/Solve/Sync process until it is within tolerance. + + + Each time the solver is executed and returns successful results, Ekos can run on the following actions: + + - Astrometry.net is already included with &kstars; bleeding version. But if astrometry is not installed, then you can install it by running the following command under &ubuntu;: + Sync: Syncs the telescope coordinates to the solution coordinates. + + - sudo apt-get install astrometry.net + Slew to Target: Syncs the telescope coordinates to the solution coordinates and then slew to the target. - - + + + Nothing: Just solve the image and display the solution coordinates. + + + + + + + Configure StellarSolver Options + + + StellarSolver Options + + + + + + + StellarSolver Options + + + + + To use the solvers, you must first configure the StellarSolver options. The above page is displayed when clicking on the Options button on the lower right of the Align page, then selecting the StellarSolver Options tab. Start with the Builtin method for solver Source Extraction method so that each solver uses its preferred star-extraction code. For Solving Method we recommend choosing Internal Solver to use StellarSolver's copy of the Astrometry.net code, or choose Local ASTAP if you prefer that. The online astrometry solver is accurate, but can take a long time to solve because of all the data transfer required. For Options Profile, start with the 1-Default profile. + + + There are two other minor options. WCS or World-Coordinate-System is a system for embedding equatorial coordinate information within the image. When you view a solved image, you can hover it and view the coordinate for each pixel. You can also click anywhere in the image and command to the telescope to slew there. It is highly recommended to keep this option on. Overlay overlays captured images unto the sky map of &kstars;. + + + + + Configure StellarSolver External Programs + + + StellarSolver External Programs + + + + + + + StellarSolver External Programs + + + + + This is only required if you choose one of the external programs for your Solving Method. If you choose Internal Solver, then it is not necessary. + + + You will need to make sure the paths are correct for the solver you choose. The top menu item select to load one of the default sets usually configures the boxes correctly. + + + + + Configure StellarSolver Scale and Position + + + StellarSolver Scale and Position + + + + + + + StellarSolver Scale and Position + + + + + This page tells Ekos whether you want to constrain your plate-solving search by scale or position. + Scale can be the image width in degrees (dw), the image width in arc-minutes (aw), or the pixel width in arc-seconds (app). All should work, but arc-seconds per pixel is recommended. Typically you want to use this constraint for faster solving, so we recommend you check this box. The system doesn't require that the scale be exactly right--it allows deviations of 10-20%. However, frequently issues related to solving are due to an inaccurate scale being used. Therefore, if you have plate-solving problems, you may want to uncheck Use Scale until those issues are resolved. This will likely result in longer solving times. Auto-update will automatically fill the scale box with the scale found in the most-recent successful solve. + The RA and DEC positions are usually filled in from the position the telescope thinks it is pointing. Naturally, the system doesn't require an exactly correct positional constraint--afterall the purpose of plate-solving is to find that position. The maximum distance in degrees from the specified position to the actual position is given by the Radius field. Plate-solving will fail if the specified position is further away. Typically you want to enable Use Position for faster solving, so we recommend you check this box. However, frequently issues related to solving are due to using a poor positional estimate (e.g. the telescope is significantly misaligned). Therefore, if you have plate-solving problems, you may want to uncheck Use Position until those issues are resolved. As mentioned, this will result in longer solving times. Auto-update will fill the position box with the position found in the most-recent successful solve. However, a slew will update the position to the position where the telescope thinks it is pointing after the slew. + + + Configure StellarSolver Profiles + + + StellarSolver Profiles + + + + + + + StellarSolver Profiles + + + + + This applies if you are using the (recommended) Internal Solver Solving Method. + + You can choose an Options Profile on the StellarSolver Options tab. Profiles are simply collections of parameters to configure the performance of the star-extraction and plate-solving system inside of StellarSolver. The 1-Default profile is the recommended one to start with. There are a few other possible profiles such as Large Scale Solving, Small Scale Solving, and Single Thread Solving. + In the Align Options Profile Editor tab you can view and edit profiles. There are many parameters, most of which you need not change to solve issues. There are 3 types of parameters. + + + The top section labelled Sextractor Parameters (with column headings Extraction Parameters, Deblending Params, and Photometry Params) are star extraction parameters--that is those that help find stars in your image. + The second section labelled Star Filtering Parameters filters/reduces the number of stars extracted before sending the list to either the plate-solver (when aligning or polar-aligning), or to autofocus or the internal guider (when just a list of stars is needed). + The third section labelled Astrometry Parameters adjusts the performance of plate solving. + + + All the input fields have tooltips that are displayed if you hover your mouse over the input box. + You can make changes to the values and save the profile if you like, or restore the profile's original values. + + + Star-Extraction Parameters + + The column headings are links to the Sextractor manual which is the main source for these parameters. View those links to find details on all the parameters. We will touch upon some of the parameters you might consider adjusting. However, it's probably best not to get into the weeds of modifying most of these values. + + + Thresh Multiple and Thresh Offset relate to how sensitive the system will be to pixel values. The level of the background is multiplied by Thresh Multiple and then Thresh Offset is added to that. If a pixel's value exceeds the result, then it may be used to detect a star. Therefore, lower values (especially for multiple) may cause even dim pixels to be detected as stars. Higher values will reduce the number of stars detected. + Min Area is the minimum area for a star detection--area is in square pixels where all pixels have higher-than-threshold pixel values. If you are detecting small noise spikes as stars, you might want to increase this. If you are not detecting desired smaller real stars, perhaps your Min Area is too high. + Conv FWHM should be adjusted to roughly the seeing in your area in pixels. The image is smoothed by this amount before star detection is initiated. + + + + + Star-Filtering Parameters + + This filtering is done for the sake of speed mostly, as well as for removing clipped stars, or very elliptical objects which might be galaxies. We will touch upon some of the parameters you might consider adjusting. Zero values for these parameters disable the filter. However, once again it's probably best not to get into the weeds of modifying most of these values. + + + Initial Keep and Stars Keep # relates to the number of stars returned by the system. The system will initially run its detection algorithm and find some number of possible detections. It will filter that list, keeping only the Initial Keep brightest stars. It will then run the rest of the filtering, including computing the HFR of all those stars and finally only return a list of Stars Keep # stars. None of the uses (alignment, autofocus, guiding) of StellarSolver require thousands of stars to be able to do their job, and the more stars processed the slower the operation. An initial list of 1000 stars and a few hundred returned stars should be sufficient for most applications. + Max Size and Min Size filter stars by their sizes (pixel diameters), and are similar in usage to Min Area above. + Max Ellipse specifies how elliptical a star can be before being removed. 2 would mean the larger axis could be twice as large as the smaller axis. + Cut Brightest and Cut Dimmest remove the X% brightest or dimmest stars from consideration. Sat Limit removes stars whose pixel values exceed that percentage of the maximum pixel value--to remove saturated stars. + + + + + Plate-Solving Parameters + + These plate-solving parameters mostly relate to computation resources. + + + Search Radius is the distance from the position estimate in degrees that may be searched if Use Position is checked. + Maximum Time is the maximum number of seconds that the plate-solving will run before it times out. + + + + - Download Index Files + Download Index Files + + Index files are required if you choose the Internal Solver or Local Astrometry Solving Method. + For offline (and remote) solvers, index files are necessary for the solver to work. The complete collection of index files is huge (over 30 GB), but you only need to download what is necessary for your equipment setup. Index files are sorted by the Field-Of-View (FOV) range they cover. There are two methods to fetch the necessary index files: The new download support in Align module, and the old manual way. @@ -303,212 +401,149 @@ - - How to Use? - - Ekos Align Module offers multiple functions to aid you in achieving accurate GOTOs. Start with your mount in home position with the telescope tube looking directly at the celestial pole. For users in Northern Hemisphere, point the telescope as close as possible to Polaris. It is not necessary to perform 2 or 3 star alignments, but it can be useful for some mount types. Make sure your camera is focused and stars are resolved. - - - - - Capture & Solve: Capture an image and determine what region in the sky the telescope is exactly looking at. The astrometry results include the equatorial coordinates (RA & DEC) of the center of the captured image in addition to pixel scale and field rotation. Depending on the Solver Action settings, the results can be used to Sync the mount or Sync and then Slew to the target location. For example, suppose you slewed the mount to Vega then used Capture & Solve. If the actual telescope location is different from Vega, it will be first synced to the solved coordinate and then Ekos shall command the mount to slew to Vega. After slew is complete, the Alignment module will repeat Capture & Solve process again until the error between reported and actual position falls below the accuracy thresholds (30 arcseconds by default). - - - - - Load & Slew: Load a FITS or JPEG file, solve it, and then slew to it. - - - - - Polar Alignment Assistant: A simple tool to aid in polar alignment of German Equatorial Mounts. - - - - - - Never solve an image at or near the celestial pole (unless Ekos Polar Alignment Assistant Tool is used). Slew at least 20 degrees away from the celestial pole before solving the first image. Solving very close to the poles will make your mount pointing worse so avoid it. - - - + + Optionally get astrometry.net - - Alignment Settings - - - Astrometry.net Settings - - - - - - - Astrometry.net Settings - - - + + This is only required if you choose the Local Astrometry option for Source Extraction Method which is no longer recommended. + + - Before you begin the alignment process, select the desired CCD & Telescope. You can explore astrometry.net options that are passed to the astrometry.net solver each time an image is captured: + Astrometry.net is already shipped with StellarMate so there is no need to install it. Index files from 16 arcminutes and above (4206 to 4019) are included with StellarMate. For any additional index files, you need to install them as necessary. To use Astrometry in StellarMate from a remote Ekos on &Linux;/&Windows;/&MacOS;, make sure to select Remote option in Ekos Alignment Module. Furthermore, make sure that the Astrometry driver is selected in your equipment profile. - - - - CCD: Select CCD to capture from. - - + + + + Ekos Remote Astrometry + + + + + + + Ekos Remote Astrometry + + + + + + &Windows; - Exposure: Exposure duration in seconds. + To use astrometry.net under &Windows;, you need to download and install the ANSVR Local Astrometry.net solver. The ANSVR mimics the astrometry.net online server on your local computer; thus the internet not required for any astrometry queries. - - - Accuracy: Acceptable difference between reported telescope coordinate and actually solved coordinate. + After installing the ANSVR server and downloading the appropriate index files for your setup, make sure ANSVR server is up and running and then go to Ekos Alignment options where you can simply change the API URL to use the ANSVR server as illustrated below: - - + + + ANSVR Parameters + + + + + + + ANSVR Parameters + + + - Bin X: Set horizontal binning of the CCD. + In Ekos Align module, you must set the solver type to Online so that it uses the local ANSVR server for all astrometry queries. Then you can use the align module as you would normally do. - - - Bin Y: Set vertical binning of the CCD. + Remember as indicated above that StellarMate already includes astrometry.net. Therefore, if you would like to use StellarMate remotely to solve your images, simply change solver type to Remote and ensure that your equipment profile includes Astrometry driver which can be selected under the Auxiliary dropdown. This is applicable to all operating systems and not just &Windows;. + + + &MacOS; - Scope: Set the active telescope in case you have different Primary and Guide scopes. FOV is re-calculated when selecting a different telescope. + Astrometry.net is already included with &kstars; for &MacOS;, so no need to install it. + + + &Linux; - Options: Options that are passed to the astrometry.net solver. Click the edit button to explore the options in detail. + Astrometry.net is already included with &kstars; bleeding version. But if astrometry is not installed, then you can install it by running the following command under &ubuntu;: - - - Solver: Select solver type (Online, Offline, Remote). The remote solver is only available when connecting to a remote device. + sudo apt-get install astrometry.net - - - By default, the solver will search all over the sky to determine the coordinates of the captured image. This can take a lot of time; therefore, in order to speed up the solver, you can restrict it to only search within a specified area in the sky designated by the RA, DEC, and Radius options above. - - - - - Astrometry.net Options + + + + + + How to Use? - Options for offline and online solvers. + Ekos Align Module offers multiple functions to aid you in achieving accurate GOTOs. For some mounts it is useful to start your session with your mount in home position with the telescope tube looking directly at the celestial pole. For users in Northern Hemisphere, point the telescope as close as possible to Polaris. It is not necessary to perform 2 or 3 star alignments, but it can be useful for some mount types. Make sure your camera is focused. - - - Astrometry.net Options - - - - - - - Astrometry.net Options - - - - Most of the options are sufficient by default. If you have astrometry.net installed in a non-standard location, you can change the paths as necessary. + At the top left of the Align page you can find two solver commands, and two actions to take given the solver solution. - WCS: World-Coordinate-System is a system for embedding equatorial coordinate information within the image. Therefore, when you view the image, you can hover it and view the coordinate for each pixel. You can also click anywhere in the image and command to the telescope to slew there. It is highly recommended to keep this option on. - - - - - Verbose: If the solver repeatedly fails to solve, check this option to enable verbose output of the solver to help you identify any problems. - - - - - Overlay: Overlay captured images unto the sky map of &kstars;. + Capture & Solve: Capture an image and determine exactly where in the sky the telescope is pointing. The astrometry results include the equatorial coordinates (RA & DEC) of the center of the captured image and the pixel scale and field rotation. Depending on the Solver Action settings, the results can be used to Sync the mount or Sync and then Slew to the target location. For example, suppose you slewed the mount to Vega then used Capture & Solve. If the actual telescope location is different from Vega, it will be first synced to the solved coordinate and then Ekos shall command the mount to slew to Vega. After slew is complete, the Alignment module will repeat Capture & Solve process again until the error between reported and actual position falls below the accuracy thresholds (30 arcseconds by default). - Upload JPG: When using online astrometry.net, upload all images are JPEGs to save bandwidth as FITS images can be large. + Load & Slew: Load a FITS or JPEG file, solve it, and then slew to it. + + + Never solve an image at or near the celestial pole (unless Ekos Polar Alignment Assistant Tool is used). Slew at least 20 degrees away from the celestial pole before solving the first image. Solving very close to the poles will make your mount pointing worse, so avoid it. + + - - - Solver Options - - Ekos selects and updates the optimal options by default to accelerate the performance of the solver. You may opt to change the options that are passed to the solver in case the default options are not sufficient. - - - - Solver Settings - - - - - - - Solver Settings - - - - - - - Capture & Solve + + + Alignment Settings - Using Ekos Alignment Module, aligning your mount using the controller's 1, 2, or 3 star alignment is not strictly necessary, though for some mounts it is recommended to perform a rough 1 or 2 star alignment before using Ekos alignment module. If you are using EQMod, you can start using Ekos alignment module right away. A typical workflow for GOTO alignment involves the following steps: + Before you begin the alignment process, select the desired optical train. You can explore astrometry.net options that are passed to the astrometry.net solver each time an image is captured: - + - Set your mount to its home position (usually the NCP for equatorial mounts). + Accuracy: Acceptable difference between the desired target position and the solved coordinates from the captured image. If the difference exceeds this many arc-seconds, then the system will continue to capture, solve and slew until the solved position is close enough to the target position. - Select Slew to Target in the Solver Action. + Train: Select the Optical Train which will be used to capture the image to be aligned. It is also used to compute the image scale. - Slew to a nearby bright star. + Exposure: Exposure duration in seconds. - After slew is complete, click Capture & Solve. + Bin: The binning of the image before solving. - - - If the solver is successful, Ekos will sync and then slew to the star. The results are displayed in the Solution Results tab along with a bullseye diagram that shows the offset the reported telescope coordinates (&ie; where the telescope thinks it is looking at) vs. its actual position in the sky as determined by the solver. - - - Each time the solver is executed and returns successful results, Ekos can run on the following actions: - - - Sync: Syncs the telescope coordinates to the solution coordinates. + Gain/ISO: The camera gain or ISO. - Slew to Target: Syncs the telescope coordinates to the solution coordinates and then slew to the target. + Filter/Use Current: The filter to use when capturing the image. Use Current uses whatever filter is currently active. - Nothing: Just solve the image and display the solution coordinates. + Dark: Whether to use the dark-image subtraction scheme before analyzing the captured image. @@ -557,7 +592,7 @@ Before starting the process, point the mount as close as possible to the celestial pole with the counterweights down. If you are living in the Northern Hemisphere, point it as close as possible to Polaris. If Polaris is not visible (⪚ blocked by trees or buildings) you may point elsewhere, preferably near the Meridian. Make sure there is at least 30-60 degrees of sky viewable in an arc East or West of the Meridian from the position you choose. Select the direction of free sky, the number of degrees for each of two slews, the mount slew speed, and whether the mount will be slewing automatically (recommended) or manually. - The tool works by capturing and solving three images. After capturing each, the mount rotates by the fixed amount you entered and another image is captured and solved. If you chose manual, you will need to slew the mount by roughly the angle chosen. + The tool works by capturing and solving three images. After capturing each, the mount rotates by the fixed amount you entered and another image is captured and solved. If you choose manual, you will need to slew the mount by roughly the angle chosen. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-capture.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-capture.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-capture.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-capture.docbook 2023-12-03 05:23:16.000000000 +0000 @@ -485,6 +485,220 @@ Before the calibration capture process is started, you can request Ekos to park the mount and/or dome. Depending on your flat source selection above, Ekos will use the appropriate flat light source before starting flat frames capture. If ADU is specified, Ekos begins by capturing a couple of preview images to establish the curve required to achieve the desired ADU count. Once an appropriate value is calculated, another capture is taken and ADU is recounted until a satisfactory value is achieved. + + Exposure Calculator + + + Exposure calculator + + + + + + + Exposure calculator + + + + + The exposure calculator is an implementation of a calculation process presented by Dr. Robin Glover in 2019. This calculation process seeks to establish a sub-exposure time which considers two sources of noise in an image: camera read noise, and noise from background sky brightness (light pollution). The effects of camera thermal noise on images is not considered in this calculation. (Note: Since his presentation in 2019, Dr. Glover has enhanced his calculation process to incorporate the effects of sensor quantum efficiency, and sensor pixel size. At this time, the KStars implementation lacks those features.) + + + The concept in Dr. Glover's calculation is to provide a sufficiently long exposure so that the effects of camera read-noise are overwhelmed by the signal coming from the target, but not so long an exposure that the effects of light pollution rise to levels which would overwhelm the signal from the target. + + + The implementation of this process does not consider the strength (magnitude or flux) of the intended target, nor does it consider other factors which may cause an astrophotographer to choose an alternate sub-exposure time. These other factors may include: the storage requirements and extended post-processing time for a large number of short exposures, the impacts of external factors that might occur in very long exposures, such as tracking / guiding performance, changes in weather conditions which may disrupt seeing conditions, intrusions from air traffic or passing satellites. + + +Approaches to imaging can vary greatly in the selection of exposure times, and number of sub-exposures used for integration. A well accepted approach for imaging deep-sky objects utilizes long exposures, requires good guiding, good to excellent seeing conditions, and would typically employ filtering to reduce the effects of light pollution. At the other extreme are approaches such as speckle imaging techniques (commonly 'lucky imaging'), which utilize many hundreds to many thousands of extremely short exposures in an attempt to eliminate the effects of light pollution, poor seeing conditions, and poor guiding. Choices made for values of certain inputs to the exposure calculator will vary depending upon which imaging approach is being employed. + + + + Exposure Calculator Inputs + + + + Sky Quality: The Sky Quality selector sets the measurement of the magnitude per square arc-second of the background sky. + The range for Sky Quality is from 22 for the darkest skies, to 16 for the brightest (most light-polluted) skies. The magnitude scale is non-linear; it is a logarithmic scale based on the 5th root of 100. So 5 steps on the scale represent a change in brightness by a factor of 100. (A Sky Quality of 17 is 100 times as bright as a Sky Quality of 22. Each full integer step on the scale is a change by a factor of approximately 2.512.). Wikipedia Sky Brightness +Wikipedia Light Pollution + + All light scattered in the background sky is considered to be light pollution regardless of its source, so the effects of moonlight should be considered as "natural" light pollution. But weather conditions can also impact Sky Quality, as humidity or cloud cover can reflect and scatter any source of light through the atmosphere + + A Sky Quality Meter (SQM) + can provide the most accurate reading of sky quality if used during an imaging session, but an estimated value from sky quality surveys may also be found on the web at sites such as www.lightpollutionmap.info or www.clearoutside.com. But these on-line sources for estimated light pollution generally do not account for the effects of moonlight or local weather conditions. So the values from light pollution web sites should only be considered as a “best case scenario” for a cloudless night during a new moon. + + If a light pollution map value is used for the input value of SQM, but imaging will be performed with a partial moon, then a decrease in the input of the SQM value should be applied in the calculator. Moonlight can be overwhelming; at a location where a light pollution map showed an SQM value of 19.63. An SQM reading was made on a night with a waxing crescent, shortly before half-moon, (moon age 5.4, and KStars moon magnitude = -10). The SQM reading at zenith showed the sky to be much brighter with measured value of 18.48. A reading taken on a night with a waxing gibbous, shortly before a full moon, (moon age 12.4, and KStars moon magnitude = -12). The SQM reading at zenith showed a measured SQM value of 15.95. +The value of Sky Quality has a drastic impact on the calculated exposure because of the logarithmic scale involved. An image taken from a location with heavy light pollution (a low sky quality value), especially when filtering is not applied, may result in a very short exposure time to prevent light pollution from overwhelming the target signal. An image taken from a location with very little light pollution (a high Sky Quality value) may result in an sub-exposure time of several hours. + + + + Focal Ratio: The selector for Focal Ratio set the value from the optical train, which is needed for the evaluation of light gathering capability. + + The value of the focal ratio of the optic has a direct effect on the exposure calculation. A lower focal ratio is considered to be a "faster optic" as it has a greater light gathering capability than an optic with a longer focal ratio. So the exposure calculation will be reduced when a lower focal ratio is used, and increased when a higher focal ratio is used. + + The user might consider making a slight adjustment to the input value of the focal ratio to compensate for the efficiency or for obstructions in the optic. + + For example, two optics of the same focal ratio, a refractor (with no obstruction) and a reflector (with a secondary mirror obstruction) would be treated as equivalent optics in the computations. One way that a user might compensate for this would be to make an adjustment to the focal ratio input value to compensate for the efficiency of the optic. A refractor is generally considered to have an efficiency of about 94%, a reflector is generally considered to have an efficiency of about 78%. +An effective / adjusted focal ratio value for a refractor = Optic Focal Ratio / 0.94 +An effective / adjusted focal ratio value for a reflector = Optic Focal Ratio / 0.78 +These adjustments slightly increase the focal ratio, and therefore slightly reduce the computed light gathering capability considered in the calculation. + + + + Filter Bandwidth: The selector for Filter Bandwidth sets the value for the bandwidth (in nanometers), and should be reduced from the default value of 300 when a filter is included in the optical train. The inclusion of filters in the optic train will greatly effect the exposure calculation. The value ranges from 300, for imaging without any filter, down to 2.8 for an extreme narrow-band filter. + Filters fall generally into two categories: single band, or multi-band. The bandwidth for a single band filter should be relatively easy to determine or estimate. Generally a Red, Green or Blue filter is considered to have a bandwidth of 100 nanometers. Documentation of narrow-band filters will frequently state the bandwidth (usually in the range of 3 to 12 nm). But the bandwidth of multi-band astronomy filters, such as light-pollution filters, or filters specifically designed for use on nebulae may be more difficult to determine as their transmission profiles can be far more complex. + +Even within the bands that filters are intended to pass, filters are not 100% efficient. So a user of the calculator might wish to slightly reduce the value of the filter bandwidth to compensate for this. Example: if a filter is presumed to have a bandwidth of 100 nm but its transmission efficiency is only 92%, then a value of 92 might better represent this filter, and result in a slightly more accurate exposure calculation. + + + The value of the filter bandwidth has an inverse effect on the exposure calculation. An unfiltered exposure would use the max value of 300 for the filter bandwidth (representing visible spectrum of 300 nanometers), and will produce the shortest exposure time calculation. An extreme narrow-band filter, (for example a 3 nanometer bandwidth), will produce the longest exposure time. + + + + Camera: The exposure calculation requires a value for the read noise of the camera. Camera read noise is an electronic noise that occurs at the completion of an exposure as the camera is measuring the analog voltage values of the pixels and converting these measurements into digital values. Read noise is not effected by the length of an exposure. +Camera sensors are one of two types: "Charge Coupled Device" (CCD) or "Complementary Metal-Oxide Semiconductor" (CMOS). For the exposure calculation the main difference between these sensor types is that CCD sensors do not have a variable gain setting that would impact the read noise; so a CCD sensor will have a single constant value for its read noise. A CMOS sensor does have a variable gain (or ISO value), and changes to that setting usually result in a change to the read noise. + The exposure calculator relies upon the selection of a camera data file so that it can access an appropriate read noise value for use in the calculation. The camera selection drop down allows the user to select an appropriate camera data file. For a CCD camera the file will only hold a single read noise value, but for a CMOS camera the file includes a table (or a few tables) of values which relate the gain or ISO value to a read noise value. Do not be confused by "CCD" appearing in the names of many dedicated astrophotography cameras, most of these cameras are using CMOS sensors. + + The camera data files provided in KStars contain values which are transcribed from manufacturers technical documentation. But actual read noise values for a camera may vary from the published data; so a user may which to utilize a tool that can determine the read noise values for their specific camera. Dr. Glover provides a sensor analysis tool in his MS-Windows based product SharpCap SharpCap Sensor Analysis The specific data from such a tool can be used to create a customized camera data file for use with the KStars exposure calculator. + + +Read Mode: Some cameras manufactured by QHY have the capability to function in multiple modes. These modes alter the read noise values, so the camera data files for these cameras include multiple read noise tables. When using one of these multi-mode cameras the Read Mode dropdown will become enabled, and allow the user to select the read mode table that would correspond to the mode in which the camera will be operated for imaging. + + + + Exposure Time Graph: The calculator will present a graph of the potential exposure times determined from the inputs. In the case of CMOS based cameras, this graph will resemble the underlying read noise data from the camera, but is transformed into an exposure time over the range of possible gain or ISO values. In the case of CCD based cameras, the graph will be a simple bar, because the read noise of a CCD sensor is invariable. + + + + + Gain / ISO Selection: For cameras with CMOS sensors, a Gain or ISO value can be selected. A Gain control will appear for cameras that allow a gain selection, and an ISO selection drop down will appear for DSLR cameras. Adjusting the gain / ISO value will move a selection indicator laterally along the exposure time graph to show how the selected gain value will effect the calculated exposure time. +CMOS based cameras tend to have high read noise at low gain / ISO values, and the read noise diminishes as the Gain / ISO value is increased. So a user might be tempted to select a higher gain value in an attempt to reduce the amount of read noise. But the camera full well capacity would typically be highest when gain / ISO values are lowest. A greater full well capacity provides a greater dynamic range in the image. + +Selection of a gain / ISO value would be dependent upon the imaging technique being employed. When a long exposure is desired (as with 'typical' DSO imaging), then a low gain / ISO value would usually be preferred to achieve a greater dynamic range in the image. But if a speckle technique ('lucky imaging') is being used, the exposure times would be so low that reducing read noise becomes critical, in such a case the user would likely prioritize a low read noise in the sub-exposures, and will likely need to select a high gain/ISO value. + +Some cameras may show a smooth progressive curve in the read-noise over the range of gain values, other cameras may have very pronounced steps (and other anomalies) in their read-noise. These pronounced steps are usually the result of electronic mode switching within the camera. In cases where the graph shows a pronounced step, the user may wish to select a gain value which is at the bottom of that step. This may provide a reduced read noise, and result in a shorter exposure without a significant loss in dynamic range when compared to an image shot at a gain selection that is at the top of that step. But caution is needed when selecting a gain near a “step” on the graph. Some posts on forums indicate that the read-noise data provided by manufacturer documentation may not be exact. The actual “switch” in read-noise may be at a slightly higher or lower gain value, so it is recommended to avoid selecting a gain value that is at a step in read noise. + +When using data from camera manufacturer documentation, avoid selecting a gain near a step + + + + + + Avoid selecting gain near a step + + + +Instead, shift the gain selection away from the step + + + + + + Shift gain away from such steps + + + + + + + Noise Increase %: The 'Noise Increase %' selector controls a factor used in Dr Glover's equation. This value will alter the relative balance between the two sources of noise in the sub-exposure. As a general rule, Dr Glover had recommended using a value of 5%, but lowering it to 2% when the computed exposure time is considered to be too short. +The perspective of the "increase" is a relative increase in read-noise compared to noise from light pollution. It may seem counter-intuitive, but raising the value of 'Noise Increase %' will reduce the exposure time, reducing the noise from light pollution (and reducing the target signal), so the 'increase' means a relative increase in the effect of the read noise compared with the pollution noise. Lowering the value of 'Noise Increase %' will increase the exposure time, and will allow more noise from light pollution, (and more target signal), into the exposure. This effectively reduces the relative impact of read-noise. + In this implementation of the calculator, the value for the 'Noise Increase %' can be set to in a very broad range to allow a user a greater range for experimentation. But a user should recognize that large changes to this value can have undesired consequences. Forcing an exposure time down may cause the exposure to carry a relatively heavy burden from read noise, and would reduce the quality of the sub-exposure, (the ratio of exposure time to total noise will fall). As a result a significantly higher number of exposures for integration would be needed to achieve an acceptable level of quality. Forcing an exposure time up to long exposure might cause the exposure to have excessive noise from light pollution. +The value selected for the 'noise increase %' is also one which is dependent upon the imaging technique being employed. When a speckle technique ('lucky imaging') is being employed, the user will likely need to force the exposure time down to an extremely short duration (sub-second exposures are standard with this technique). So the user may need to drastically raise the value of 'noise increase %' to reduce the time of the sub-exposure down to the durations demanded by this technique. + + + + + + + Exposure Calculator Results + + + + Exposure Time (sec): The calculated duration of an exposure. + + + + Pollution Electrons: The calculated number of light pollution electrons per pixel impacting the exposure. + + + + Shot Noise: The calculated noise from light pollution impacting the exposure. + + + + Total Noise: The calculated noise from both light pollution and image sensor read noise impacting the exposure. +Recognize the relationship of exposure time to total noise: The ratio of exposure time to exposure total noise can be thought of as a measurement of a potential quality for the exposure. Short exposures will contain a high amount of noise relative to their exposure time, so a shorter exposure would tend to be of relatively lower quality. Short exposures may still be viable, but a disproportionately higher number of short sub-exposures will be needed for integration to achieve an image of a desired quality. + + + + + + + +Stacking / Image Integration Information + +The value of image stacking is that as images are stacked, the accumulation of exposure time and the data that represents the target signal is increased proportionally with the added number of images being integrated, but the increase in noise is disproportionally lower. As a result, the quality of integrated images can be seen as curve which starts with a good “yield” when the first few sub-exposures are integrated, but this curve has diminishing returns as the number of sub-exposures being integrated is increased. + +Ideally a desired signal to noise ratio (SNR) would be used for the measure of the level of quality of an image, but the exposure calculator does not possess an ability to recognize the strength of the signal from an intended imaging target, so it cannot calculate an estimated signal to noise ratio. So the level of quality to be specified in the stacking calculation is the integration time in seconds divided by the calculated noise in the integrated image, (a “Time/Noise Ratio”). For the purposes of the calculation, the “Time/Noise Ratio” can be considered as a partial analog to a signal to noise ratio. But the user must recognize that a specified time to noise ratio is not an absolute measure of the quality of all integrated images from all targets because a signal strength (magnitude or flux) is not part of this calculation. + + + + + Table: A table provides details for stacking based upon the number of hours planned for imaging. +The table provides a quick reference for finding the approximate number of sub-exposures that might be completed for a given number of hours in a imaging session. But some functions that consume time are not included in this time calculation. For example, USB based cameras typically take some time for data transmission, or if the user has selected automatic dithering, additional time will be consumed in the imaging process, which is not included in this time calculation. +The far right column of the table shows the calculated time/noise ratio of the integrated (stacked) image that would be produced. + + + + Graph: An interactive graph allows the user to visualize the relative change in potential quality for integrated images with various counts of sub-exposures applied in image stacking. This graph can be navigated through the adjustment of the time/noise ratio value; adjusting this value will recompute the quantity of sub-exposures required for the integrated image to achieve that specified time/noise ratio. + +In the selection of a Time/Noise ratio for the calculation of the count of stacked exposures, the user might want consider the incremental change to the potential quality of the image from an additional sub-exposure. To help a user assess the value of increasing the number of sub-exposures for integration; the tool includes a calculation of the slope for the selected point on the time/noise curve (the user interface uses a delta symbol to present this value). This delta value represents the change in potential quality that will result from the addition or subtraction of a single sub-exposure. + +As one should expect, at the low-end of exposure counts (when a low value for the Time/Noise Ratio is input), the delta value will be relatively high, so the addition of one image will provide a relatively large improvement to the integrated image. But as a user increases the value for the Time/Noise Ratio, more images will be included for integration, and the delta value will fall, indicating that there is less to be gained from adding more sub-exposures. + +The default value for the time / noise ratio is set to 80. This value should not be construed in any way as an optimal value; it was simply chosen as a somewhat average value. A user should consider a few factors when adjusting the value of the time / noise ratio: 1) the strength of the target object, 2) the time / noise ratio of the calculated sub-exposure, 3) the limitations of time for imaging and processing, and limitations of storage capacity for the images. + + + +For a strong target, (example, Orion Nebula with magnitude 4), would provide a relatively strong signal. On such a target, the value for the Time/Noise Ratio might be reduced and the computation of sub-exposures, may still produce an image with a very good signal to noise ratio. A much weaker target (example, Thor’s Helmet, magnitude 11), might require a higher time/noise ratio to compensate for the relatively weak target signal. + + + +Depending on the various inputs and imaging conditions, the potential quality of a sub-exposure can vary greatly. In poor sky quality with little or no filtering, the computed sub-exposure time will naturally be short to avoid an overwhelming noise from light pollution, and the exposure time relative to the computed noise will be low (a low time/noise ratio). To achieve a high quality integrated image from low time/noise ratio sub-exposures may require thousands sub-exposures. If the user is concerned about imaging and processing time or storage capacity; then a higher time/noise ratio would needed to reduce the quantity of sub-exposures. Conversely, when input conditions result in a sub-exposure with a long exposure time relative to the computed noise (as with narrow-band imaging), the result is a sub-exposure with a very high time/noise ratio. In such cases the default value of 80, might result in very few sub-exposures for the integration. But the delta value will be quite high, indicating that raising the time-noise ratio will greatly improve the potential quality of the integrated image. + + + +Part of the value of using a Time/Noise ratio as the input for the calculation of the required number of sub-exposures is that it should tend to compensate for the differences in relative noise for sub-exposures of various lengths. A shorter sub-exposure would have a lower time/noise ratio, so it has less capacity to improve a integrated image. Therefore, a disproportionately higher number of short exposures are needed to achieve a given time/noise ratio in an integrated image. + +As an example, consider the calculation of the number of sub-exposures required when two sub-exposures times were compared: a 300 second sub-exposure vs a 30 second sub-exposure. The 300 second sub-exposure had a calculated noise of 22.1, resulting in a sub-exposure time/noise ratio of 13.6. When the 'noise increase %' is raised to force the exposure time down to 30 seconds, we see a calculated noise of 9.47, resulting in a much lower sub-exposure time/noise ratio of 3.2. The 300 second exposure is of significantly higher potential quality than the 30 second exposure. We will demand the default time/noise ratio of 80 for integration in both of these cases. + +For an integration using the 300 second sub-exposures we find that 34 sub-exposures are required to achieve a time/noise ratio of 80. So a total integration time of 2.83 hours is required. + + + + + + + 300 Second sub-exposure + + +For an integration using the 30 second sub-exposures we find that 637 sub-exposures would be required to achieve a time/noise ratio of 80. So a total integration time of 5.31 hours is required with these shorter exposures to achieve the same time/noise ratio in the integrated image. + + + + + + 30 Second sub-exposure + + + + + + + + + Video Tutorials diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-focus.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-focus.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-focus.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-focus.docbook 2023-12-03 05:23:16.000000000 +0000 @@ -321,6 +321,11 @@ run. The Stop button is used to stop the run. + The Inspector button starts an + Aberration Inspector run. + The Stop button is used to stop the run. + + The Capture Image button will take a frame based on the current settings in the Camera & Filter Wheel Group. The Start Framing @@ -2285,4 +2290,404 @@ Currently the solver is used to fit either a parabolic or a hyperbolic curve. + + + Aberration Inspector + + + Aberration Inspector + + + + + + + + Aberration Inspector + + + + + The Aberration Inspector is a tool that makes use of Autofocus to analyze backfocus and sensor tilt in the + connected optical train. + To run Aberration Inspector press the Inspector button on the focus screen located next to the Autofocus button. + See Focuser Group for more details. The following criteria must be met in + order for the tool to work: + + + + The focuser must be an absolute focuser. + + + + The focus algorithm must be Linear 1 Pass. + + + + A mosaic mask must be applied. + + + + Focuser step size needs to be setup. It is the number of microns the focal plane moves for 1 focuser tick. + This is setup in the CFZ parameters tab. See the + CFZ section for more details. + + + + + When the Inspector button is pressed, AutoFocus will run, but in addition, for each datapoint, extra information + is captured for later use by Aberration Inspector. Once Autofocus completes, the Aberration Inspector dialog is + displayed. + + To initially setup to use the tool it is recommended to do the following: + + + + Point to a part of the sky where Autofocus solves well. Typically this would be high in the sky away from + any obstacles. Choose somewhere with lots of stars such as the Milky Way. The reason this is more important + for Aberration Inspector than Autofocus is that focus analysis needs to be performed for each tile in the mosaic. + Therefore, it is important that each tile has enough stars to perform accurate Autofocus. + + + + Run Autofocus a couple of times to ensure it is solving correctly and that you have a good set of + stars in each mosaic tile. Whilst most focus parameters can be used it is recommended to use the + parameters that work best for Autofocus with your equipment. The reason for this is that Aberration + Inspector needs be focus solve each mosaic tile and not just the sensor as a whole. + + + + A mosaic mask must be applied. Some experimentation will be required to set this up optimally for + your equipment. The configuration parameter to adjust is the tile size which is the size of tile as a + percentage of sensor width. The higher the percentage, the bigger each tile, e.g. for a 4:3 sensor using a + tile size of 25% means each tile is 8% of the sensor's area. Using a tile size of 10% means each tile is + 1% of the sensor's area. The bigger the area the more stars will be present and the better the focus + algorithm will solve. However, the purpose of the Aberration Inspector is to provide information + on aberrations (backfocus and tilt) across the sensor, so ideally the information for each tile would be + specific to as small an area as possible. + The sweet spot for tile size is as small a value as possible that still contains enough stars to + solve well in each tile. + + + + The Aberration Inspector can be used in conjunction with a device to adjust tilt and / or backfocus. The + method to do this is an iterative approach, like for example, collimating a telescope. The steps are: + + + + Run the Aberration Inspector and obtain results. + + + + Inspect the results and make sure they are good, e.g. number of stars in each tile is sufficient and + the R² is acceptable for all relevant tiles. + + + + Adjust tilt and / or backfocus using your device, based on Aberration Inspector results. + + + + Re-run Aberration Inspector. It will launch another dialog. Check results as before. + If the tilt and / or backfocus is getting better then the adjustment was made in the correct sense; + if not reverse the sense and retry. Use the feedback from the previous adjustment for the next adjustment. + + + + Repeat the above process until the limit of sensitivity of the equipment is reached. + + Note the amount of adjustment, e.g. how far to turn bolts, and the sense, counterwise or counter-clockwise, + will vary by equipment and must be discovered by the user by trial and error. Always follow the recommendations of + the tilt / backfocus device manufacturer. + + Each time Aberration Inspector is run it lauches a new dialog with the run number appended to the title. + This way several runs can be performed and the results compared. Note, however, that the dialog holds a lot of + data (roughtly 10x the amount of a standard Autofocus run). The system resources associated with this are released + when the dialog is closed. For this reason on lower powered machines, once the tool has been used, it is recommended + to close all Aberration Inspector dialogs before imaging. + + The following sections describe the sections of the Aberration Inspector dialog. + + + Aberration Inspector V-Curve + + + Aberration Inspector V-Curve + + + + + + + + Aberration Inspector V-Curve + + + + + At the top of the dialog are some controls, followed by the V-Curve. The controls are: + + + + Tiles: Three options are available: + + + All: All 9 tiles are displayed. + + + Centre and outer corners: The centre and 4 corner tiles are displayed. + + + Centre and inner diamond: The centre and 4 inner diamond tiles are displayed. + + + + + Labels: Checkbox toggles focus point labels on the V-Curve. + + + CFZ: Checkbox toggles whether the CFZ moustache is displayed on the V-Curve. + + + Optimise Tile Centres: If unchecked, the geometrical centre of the tile is used; + if checked, the centre of the tile is calculated as an average of the star positions within the tile. + Whilst theoretically more accurate to check this option, it is likely to have a significant impact only if the + number of stars is small. + + + Close: Close the Aberration Inspector dialog. + + + + The V-Curve is similar to the V-Curve on the main Focus tab, except each tile is represented by its own curve. + The number of curves is determined by the setting of the Tiles combobox. The x-axis displays + the focuser position and the y-axis the measure (e.g. HFR) used by Autofocus. Each curve has its own colour + and 2 character identifier as displayed in the legend. + + Hover the mouse over a curve minimum to see more information about that curve. + + + + Aberration Inspector Table + + + Aberration Inspector Table + + + + + + + + Aberration Inspector Table + + + + + The table displays information pertinent to each tile as selected by the + Tiles setting. + + A tooltip like graphic is displayed when the mouse is hovered over either of the leftmost 2 columns. + The graphic displays a picture of the sensor scaled to the dimensions of the sensor. Overlayed on the + sensor are the tiles as selected by the Tiles setting. The tiles are scaled + appropriately for the tile settings. Each tile is labelled with the Tile Name and the tile corresponding + to the row that the mouse is hovering over, is highlighted in the colour of that tile. + + The following columns are displayed: + + + + Tile: The 1 or 2 character name of the tile, e.g. TL = Top Left, + C = Centre, etc. + + + Description: Tile Description, e.g. Top Left, Centre, etc. + + + Solution: The focus solution. This matches the solution on the V_Curve. + + + Delta (ticks): This is the delta of the solution for the current table row + from the solution of the Centre tile. The Delta of the Centre row will, of course, be zero. + + + Delta (μm): This is Delta (ticks) converted to microns using the step size + in microns as specified in the CFZ Focus tab. + + + Num Stars: This shows the min / max number of stars detected during the + Autofocus run. Usually, the minimum number would be a far out of focus datapoint and the max number + would be the in focus datapoint. + + + : R-squared of the curve fit for this tile. See + Coefficient of Determination for more details. + + + Exclude: Checkbox to include / exclude this tile in calculations. By + default, if a tile has been curve fitted it will be included; if a tile was not curve fitted then + it will be excluded. In addition, the user may decide that a particular tile may contain poor + quality data, for example the R² is low; or the number of stars is low. In this case the Exclude + can be checked and this row will be excluded from calculations. Note that by excluding some rows, + some calculations may not be performed. If the Centre tile is excluded, no calculations can be + performed. + + Note that whilst its possible to exclude tiles and still get calculated values, if the data + is poor quality then it is recommended to rerun Aberration Inspector rather than persist with poor + quality data. + + + + The recommended approach is to check the table for quality data and once achieved, move onto + analysing the Aberration Inspector Results. + + + + Aberration Inspector Results + + + Aberration Inspector Results + + + + + + + + Aberration Inspector Results + + + + + The calculation results are displayed in this section, based on the data displayed in the table: + + + + Backfocus Δ: This is the value of the Backfocus delta. The nearer to + perfect backfocus, the lower the backfocus delta. Note that the Backfocus delta gives a clue as to + how far out the Backfocus is, in terms of scale and direction, but is not the amount by which the + sensor needs to be moved. The relationship between backfocus Delta and how far to move the sensor + will vary with the equipment used, and needs to be worked out by the user. + + The field gives the sense of the backfocus movement required to improve backfocus: either move + the sensor nearer to the field flattener (telescope) or move it further away. + + + Left-Right Tilt: Gives the Left to Right tilt in microns and as a + percentage. + + + Top-Bottom Tilt: Gives the Top to Bottom tilt in microns and as a + percentage + + + Total Tilt: The diagonal tilt in microns and as a percentage. + + + + The smaller the backfocus delta the nearer the sensor is to perfect backfocus. If the field flattner + does not flatten the field all the way to the edges of the sensor then this will be visible by switching the + Tiles option between "Centre and outer corners" and "Centre and inner diamond". If the backfocus delta results + are consistent when the Tiles option is changed then this indicates that the field flattener is working to the + corners of the sensor. + + There will always be some backfocus delta at least because of noise in the observation data. The important + thing is that when in focus, stars are circular in all parts of the sensor. + + The smaller the tilt percentages, the nearer the sensor is to being flat to the plane of light from the + flattener / telescope. As with backfocus delta, there is always going to be some noise in the data, which will + present as tilt. The important thing is that when in focus the star sizes are consistent across all parts of the + sensor. + + Because of the nature of the backfocus delta and tilt calculations, one will affect the other so it will + probably be better to try and adjust both together, in small increments, rather than trying to perfect one in + isolation, before adjusting the other. + + + + Aberration Inspector 3D Graphic + + + Aberration Inspector 3D Graphic + + + + + + + + Aberration Inspector 3D Graphic + + + + + The 3D graphic displays the sensor tilted as per the + Aberration Inspector Results. To help + visualise the Petzval surface (see Petzval Field Curvature for more details) + of light coming out of the telescope and incident on the sensor the surface is also modelled. The higher the + backfocus error, the more curved the Petzval surface. + + The graphic can be zoomed and rotated using gestures. To zoom use pinch. To rotate use + touch-and-move. + + The graphic has a Simulation Mode that allows backfocus and tilt to be adjusted by the + sliders. The effect on the sensor's tilt and Petzval surface is displayed in the graphic. + + The following options are available for the graphic: + + + + Selection: The following options are available: + + + + None: No selection is possible. + + + + Item: A datapoint may be selected and data values are displayed. + + + + Slice: A 2D slice throught the 3D graphic is displayed. + + + + + + Theme: A number of colour themes are available. + + + + Labels: Checkbox to show / hide tile labels on the graphic. + + + + Sensor: Checkbox to show / hide the sensor. + + + + Petzval Wire: Checkbox to show / hide the Petzval surface as a graphic wire. + + + + Petzval Surface: Checkbox to show / hide the Petzval surface. + + + + Sim Mode: Checkbox to toggle Simulation Mode on / off. When off, the + graphic displays the sensor and Petzval surface based on the calculated results of the Aberration Inspector + run. When on, the sliders for Backfocus, Left-to-Right tilt and Top-to-Bottom tilt are activated, and these can be + dragged by the user to adjust the graphic. Hover the mouse over each slider to see the tooltips describing what + each slider does. + + + + The 3D graphic is not essential to using Aberration Inspector. All relevent information is displayed in the + Table and Results + sections of the dialog. Its purpose is to aid the user in undertanding Aberration Inspector and to orient themselves + with the information the tool provides. + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-scheduler.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-scheduler.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos-scheduler.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos-scheduler.docbook 2023-12-03 05:23:16.000000000 +0000 @@ -73,7 +73,10 @@ The algorithm shows its projected next start times and stop times for all job in the Scheduler table. It also shows its estimate of times jobs will run during the next 48 hours in the log panel at the bottom of the window. See the screenshot of the scheduler window at the top of this section. - The scheduling algorithm described in the above paragraph is known as the Greedy Scheduling algorithm. It is the recommended one to use. In previous versions of Ekos, there was another "Classic scheduling algorithm" which is currently being phased out. That scheme could not preempt running jobs, and thus did not make as much use of the equipment as the Greedy Algorithm. + The scheduling algorithm described in the above paragraph is known as the Greedy Scheduling algorithm. It is the recommended one to use. In previous versions of Ekos, there was another "Classic scheduling algorithm" which is no longer in Ekos. That scheme could not preempt running jobs, and thus did not make as much use of the equipment as the Greedy Algorithm. + + + There is a checkbox option in the scheduler options menu called Use greedy scheduling which defaults to being checked. The system works as described above when it is checked. When it is unchecked the scheduler is prevented from scheduling lower priority jobs when uncompleted higher priority jobs cannot run. This results in less efficient use of the system, but may give you more control over scheduling. Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_astrometry.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_astrometry.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_scheduler_settings.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_scheduler_settings.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_stellarsolver_external.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_stellarsolver_external.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_stellarsolver_options.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_stellarsolver_options.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_stellarsolver_profiles.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_stellarsolver_profiles.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/ekos_stellarsolver_scale.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/ekos_stellarsolver_scale.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposure-calculator-integration-graph.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposure-calculator-integration-graph.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposure-calculator-integration-table.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposure-calculator-integration-table.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposure-calculator.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposure-calculator.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposurecalculation-example_subexp30.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposurecalculation-example_subexp30.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposurecalculation-example_subexp300.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposurecalculation-example_subexp300.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposurecalculation_gain_at_step-avoid.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposurecalculation_gain_at_step-avoid.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/exposurecalculation_gain_at_step-shift.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/exposurecalculation_gain_at_step-shift.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-magnifier.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-magnifier.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-mark-stars.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-mark-stars.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-selection.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-selection.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-solver.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-solver.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-status.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-status.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer-stretch.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer-stretch.png differ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer.docbook 2023-12-03 05:23:17.000000000 +0000 @@ -4,10 +4,9 @@ FITS Viewer -The Flexible Image Transport System (FITS) is the standard format for representing images and data in Astronomy. +FITS, or Flexible Image Transport System, is the standard format for representing images and data in Astronomy. The &kstars; FITS Viewer is a tool to view those images. It is not designed for editing of FITS Images. -The &kstars; FITS Viewer tool is automatically invoked when new images are received from the camera. -It is primarily used to view and examine FITS data. It is not designed for editing of FITS Images. +The FITS Viewer can be automatically invoked for images received from the camera. It can also be invoked directly from the main &kstars; menu. To open a FITS file, select the File Open Image... menu item, or press &Ctrl;O. @@ -16,7 +15,7 @@ The FITS Viewer Tool - + FITS Viewer Tool @@ -24,7 +23,24 @@ -The above diagram illustrates the FITS Viewer work area and window. The tool provides basic functions for image display. FITS data depth is preserved throughout all processing, open, and save functions. While the tool adhere to the FITS standard, it does not support all possible FITS features: +The above diagram illustrates the FITS Viewer main work area and window. There is also a hidden area that can be exposed by moving the mouse over the 6 small dots on the left side (about center of the image vertically) and pressing and holding the mouse, sliding it over to the right a bit. + + + The FITS Viewer Tool with sliding panel open + + + + + + FITS Viewer Tool with sliding panel open + + + + + + Main Controls + +The various controls and displays for the FITS Viewer are shown below. The tool provides basic functions for image display. While the tool adhere to the FITS standard, it does not support all possible FITS features: Support for only one image per file. Support for only 2D and 3D data. 1D data are discarded. @@ -35,7 +51,7 @@ File - Standard Open, Save, and Save As actions. + Standard Open, Save, and Save As. FITS Header: Display FITS header table data. Debayer: Covert RAW image to RGB. @@ -52,6 +68,7 @@ Zoom Controls: Zoom in, Zoom out, standard Zoom. Filters: Auto Stretch, Contrast, High Pass, Rotate, Flip. Mark Stars: Detect and mark stars in the image. + Show Clipping: Display in red which stars have pixels that appear to be clipped. @@ -73,6 +90,8 @@ Flip Vertical. Show Cross Hairs: Toggles crosshairs in the center of the image. Show Pixel Gridlines: Toggles pixel grid. + Mark Stars: Detect and mark stars in the image. + Show Clipping: Display in red which stars have pixels that appear to be clipped. Show Equatorial Gridlines: Toggles Equatorial Grid if FITS contains a valid WCS header. Show Objects in Image: Identifies objects such as stars, galaxies, and nebulae within the image. Center Telescope: Toggle Center Telescope mode. When active and if the image contains a valid WCS header, clicking anywhere in the image triggers the telescope slewing to the clicked point. @@ -85,20 +104,103 @@ Side Panel: The side panel can be opened by dragging the separator to the right. When dragged to the left, the side panel can also be closed. Statistics: Displays image statistics including Minimum, Maximum, Average, and Median values. - Histogram: Displays image histogram with controls to adjust the minimum and maximum values for each channel. Both linear and logarithmic scalings are available to apply to the image. + Plate Solving: A tool plate-solve the loaded image. This is useful to debug plate-solving issues. + Histogram: Displays image histogram with controls to adjust the minimum and maximum values for each channel. Both linear and logarithmic scalings are available to apply to the image. This is somewhat redundant with the below-image histogram and may be removed in the future. FITS Header: Displays a table for FITS header keywords, values, and comments. Recent Images: Displays recently opened images. Clicking on any image will load it. - Image Display Area. Hovering over the image will update the status bar values accordingly. + Image Display Area. + + Mouse: Hovering over the image will update the status bar values accordingly. + Mouse: Hovering over the image will move a cursor in the histogram display below the image, if that histogram is activated. + Control key: Holding down the control key and then moving the mouse will show a magnified portion of the image. + + The Magnifier in the FITS Viewer + + + + + + The magnifier in the FITS Viewer + + + + + Statistics of region of interest + + Provides simple statistics average mean, average standard deviation and average median of the selected region by the user in a tooltip. + + + + FITSViewer + + + + + + + Selection Statistics + + + + + The user can either set the selection region by &Shift;Left Click dragging (when the selection statistics is activated) or by choosing an entry from the drop down menu of the Toggle Selection Rectangle button. In addition to this, the user can translate the region by simple Left Click drag of the mouse. The statistics of the region are shown as a tooltip once the cursor is brought over the selection region. For smaller images, the statistics are updated instantly, and for larger images, the statistics are updated once the user releases the Left Click button after modification of the region. + + + + + Stretching Controls + + The Stretch Controls in the FITS Viewer + + + + + + The Stretch Controls in the FITS Viewer + + + +Near the bottom of the window are controls for stretching the image and displaying its histogram. They are described below from left to right. + + Enable Stretching: On the very left of this display is a button that enables or disables stretching. + Shadow Value: The value below which pixels are displayed as black can be manually entered (scale is 0 to 1.0, even for integer pixel values). + Midtones Value: The midtones value which controls the brightness of the image can be manually entered (scale is 0 to 1.0, even for integer pixel values). + Highlights Value: The value above which pixels are displayed as white can be manually entered (scale is 0 to 1.0, even for integer pixel values). + Show Histogram: A button that displays or hides the image histogram is to the right of the highlights number box. + Auto Stretch: A button (magic wand icon) that will automatically create a pleasing stretch is found on the right. It is disabled if the stretch is already at the automatically computed value. + + + In addition, there are sliders that can be used to adjust the Shadow, Midtones and Highlights values. Adjusting them will change the values displayed. + + + The histogram, if it is enabled, may be zoomed by using the mouse's scroll wheel, and panned by dragging with the mouse. A cursor in the histogram shows the position of the pixel in the image under the mouse. + - Status Bar: From right to left, the following status indicators are available: + Status Bar + + The Status Display in the FITS Viewer + + + + + + The Status Display in the FITS Viewer + + + + From right to left, the following status indicators are available: Loading Indicator: The LED becomes yellow when an image is getting loaded and turns green after loading is successfully done. If there are problems with loading the image, it turns red. - Resolution: Image resolution in pixels. - Cartesian Coordinates: Displays and updates the current mouse position as you hover over the image. It include the X and Y position in addition to the current value. - Equatorial Coordinates: If the image contains a valid WCS header, the J2000 Right Ascension (RA) and declination (DE) values are displayed. - + Resolution: Image resolution in pixels. 4656x3520 in the screenshot above. + Zoom Percentage. 13% above. + Cartesian Coordinates: Displays and updates the current mouse position as you hover over the image. X:769 Y:3508 above. + Pixel Value: Value of the pixel under the mouse. 1,792 above. + Equatorial Coordinates: If the image contains a valid WCS header, the J2000 Right Ascension (RA) and declination (DE) values are displayed. 13h 14' 22" 42 37' 35" above. + Image Stats: Displays the HFR, Eccentricity and number of stars if computed. HFR:1.96 Ecc:0.43 143 stars above. + Clipped Stars: If Show Clipping is activated in the main toolbar, it displays the number of possibly clipped pixels. Clip:403 above. + @@ -129,70 +231,9 @@ Hovering over any option shall display a detailed tooltip that explains its function. + Features - - - - Support for 8, 16, 32, IEEE-32, and IEEE-64 bits formats. - - - - - Support Color FITS images (3D Cubes) and Bayered FITS images. - - - - - Histogram with linear, logarithmic, and square-root scales. - - - - - Brightness/Contrast controls. - - - - - Pan and Zoom. - - - - - Auto levels. - - - - - Statistics. - - - - - Statistics for a region of interest(Rectangle). - - - - - Rectangular and Equatorial Grids (if WCS info is present). - - - - - Detection and highlight of stars. - - - - - FITS header query. - - - - - Undo/Redo. - - - Histogram @@ -231,33 +272,68 @@ - - Statistics of region of interest - - - - FITSViewer - - - - - - - Selection Statistics - - - - - Provides simple statistics average mean, average standard deviation and average median of the selected region by the user in a tooltip. - - - The user can either set the selection region by &Shift;Left Click dragging or by choosing an entry from the drop down menu of the Toggle Selection Rectangle button. In addition to this, the user can translate the region by simple Left Click drag of the mouse. The statistics of the region are shown as a tooltip once the cursor is brought over the selection region. For smaller images, the statistics are updated instantly, and for larger images, the statistics are updated once the user releases the Left Click button after modification of the region. - - - + + FITS Viewer Solver + + + FITS Viewer Solver + + + + + + + FITS Viewer Solver + + + + + The FITS Viewer Solver is used to plate-solve the image loaded in the FITS Viewer's tab. It only works with the internal StellarSolver. You get the RA and DEC coordinates for the center of the image, the image's scale, the angle of rotation, and the number of stars detected in the image. Its main use case is debugging plate-solving issues in Ekos, though the information displayed can be generally useful. The controls and displays are described below. + + + Solve Button. Pressing this button starts plate solving. When the system is plate solving, the button becomes an abort button. + Scale: Checking the Use Scale checkbox constrains the solver to use approximately the pixel or image scale given. The scale is entered in the box and the units for the scale can be chosen from image width in degrees, image width in arc-minutes, and arc-seconds per pixel. When a solve successfully completes, it replaces the value in the box with solution's scale. + Position: Checking the Use Position checkbox constrains the solver to search near the RA and DEC coordinates given. The extent of the search is given by the user in the Radius box in degrees. Note that RA is input in hours-minutes-seconds, e.g. 13h, and DEC is input in degrees-minutes-seconds, e.g. 85. When a solve successfully completes, it replaces the value in the RA and DEC boxes with solution's coordinates. In addition it fills in the Angle field with the solutions angle value in degrees. + Use SkyMap Position: There is a button just below the Use Position checkbox that fills in RA and DEC boxes with the current center of the SkyMap display. + Profile: The Profile menu selects which StellarSolver preset, among those used in the Ekos Align module, should be used for plate solving. This is further discussed below. + Solution: The Solution section will display the number of stars found and the time taken to solve. The solution values for RA, DEC, Scale and Angle are displayed in those boxes above. + Image: For any image where stars were detected, if the Mark Stars button is activated above the image display, then the detected stars are circled in red. + + + FITS Viewer Mark Stars Button + + + + + + + FITS Viewer Mark Stars Button + + + + + + + Using this tool the user can try and debug solving issues as follows. + + + He/she might have the KStars -> Settings -> Developer -> Save Failed Align Images checkbox enabled. + Then a difficult image (for whom alignment failed) could be located and loaded into the fitsviewer. + The image could be inspected to see if there were obvious visual issues. + Clicking Solve in this tool for that image would show how many stars were detected, and the user could then decide if it is a star detection issue and experiment with adjusting the profile or star-detection parameters. + + The user could manually upload the image to astrometry.net to get scale and position values (or just see if it is a problematic image). + + The user could experiment with Use Position and Use Scale, using accurate values for those constraints (or disabling them) to see if those were the problem, or adjust the parameters in the align profile being used. + + + To inspect or modify the profile, the user would open the align tab in Ekos, go to the Options menu, select the StellarSolver Options tab, make sure the right Options profile is selected, and click the pencil to view or edit that profile. + + + Embedded FITS Viewer Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer1.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer1.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/fitsviewer2.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/fitsviewer2.png differ Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/focuser_group.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/focuser_group.png differ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/index.docbook kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/index.docbook --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/doc/index.docbook 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/doc/index.docbook 2023-12-03 05:23:17.000000000 +0000 @@ -161,6 +161,15 @@ +John +Evans + +
john DOT e DOT evans DOT email AT gmail DOT com
+
+Core Developer +
+ + Mark Holloman @@ -216,8 +225,8 @@ &FDLNotice; -2023-08-01 -3.6.6 +2023-12-01 +3.6.8 diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/docker/Dockerfile kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/docker/Dockerfile --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/docker/Dockerfile 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/docker/Dockerfile 2023-12-03 05:23:17.000000000 +0000 @@ -37,6 +37,9 @@ libgsl-dev \ phonon4qt5-backend-vlc \ qt5keychain-dev \ + libqt5sql5-sqlite \ + libqt5datavisualization5-dev \ + qml-module-qtquick-controls \ libsecret-1-dev # Suitable for tests @@ -55,8 +58,6 @@ kded5 \ kinit \ breeze-icon-theme \ - libqt5sql5-sqlite \ - qml-module-qtquick-controls \ gsc gsc-data \ phd2 \ xvfb diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/CMakeLists.txt kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/CMakeLists.txt --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/CMakeLists.txt 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/CMakeLists.txt 2023-12-03 05:23:17.000000000 +0000 @@ -180,6 +180,10 @@ # INDI Hub ekos/indihub.ui ) + # Aberration Inspector + if (Qt5DataVisualization_FOUND) + set(ekosui_SRCS ${ekosui_SRCS} ekos/focus/aberrationinspector.ui) + endif(Qt5DataVisualization_FOUND) set(ekos_SRCS ekos/ekos.cpp @@ -253,6 +257,9 @@ # Scheduler ekos/scheduler/schedulerjob.cpp ekos/scheduler/scheduler.cpp + ekos/scheduler/schedulermodulestate.cpp + ekos/scheduler/schedulerprocess.cpp + ekos/scheduler/schedulertypes.cpp ekos/scheduler/framingassistantui.cpp ekos/scheduler/mosaictilesmanager.cpp ekos/scheduler/mosaictilesmodel.cpp @@ -337,6 +344,13 @@ ekos/ekoslive/node.cpp ekos/ekoslive/nodemanager.cpp ) + # Aberration Inspector + if (Qt5DataVisualization_FOUND) + set(ekos_SRCS ${ekos_SRCS} ekos/focus/aberrationinspector.cpp) + set(ekos_SRCS ${ekos_SRCS} ekos/focus/aberrationinspectorplot.cpp) + set(ekos_SRCS ${ekos_SRCS} ekos/focus/sensorgraphic.cpp) + set(ekos_SRCS ${ekos_SRCS} ekos/focus/abinstablewidget.cpp) + endif(Qt5DataVisualization_FOUND) endif(CFITSIO_FOUND) @@ -400,6 +414,7 @@ set (fitsui_SRCS fitsviewer/fitsheaderdialog.ui fitsviewer/statform.ui + fitsviewer/platesolve.ui fitsviewer/fitsdebayer.ui indi/streamform.ui indi/recordingoptions.ui diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Atik-16200CCD_Mono.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Atik-16200CCD_Mono.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Atik-16200CCD_Mono.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Atik-16200CCD_Mono.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,24 @@ + + + 1 + Atik-16200CCD + MONOCHROME + FIXED + + 0 + + + 0 + Standard + + + -1 + 9 + + + 1 + 9 + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/FLI-16200CCD_Mono.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/FLI-16200CCD_Mono.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/FLI-16200CCD_Mono.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/FLI-16200CCD_Mono.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,24 @@ + + + 1 + Atik-16200CCD + MONOCHROME + FIXED + + 0 + + + 0 + Standard + + + -1 + 10 + + + 1 + 10 + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D5100_(PTP_mode).xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D5100_(PTP_mode).xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D5100_(PTP_mode).xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D5100_(PTP_mode).xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,127 @@ + + + 1 + Nikon DSLR DSC D5100 (PTP mode) + COLOR + ISO_DISCRETE + + 100 + 125 + 160 + 250 + 320 + 400 + 500 + 640 + 800 + 1000 + 1250 + 1600 + 2000 + 2500 + 3200 + 4000 + 5000 + 6400 + 12800 + 25600 + + + 0 + Standard + + + 100 + 3.411 + + + 126 + 3.272 + + + 159 + 3.138 + + + 200 + 3.204 + + + 251 + 3.227 + + + 318 + 3.117 + + + 400 + 2.99 + + + 503 + 2.848 + + + 636 + 2.77 + + + 800 + 2.713 + + + 1006 + 2.713 + + + 1273 + 2.694 + + + 1600 + 2.676 + + + 2011 + 2.713 + + + 2546 + 2.676 + + + 3200 + 2.676 + + + 4022 + 2.694 + + + 5091 + 2.694 + + + 6400 + 2.676 + + + 8045 + 2.694 + + + 10183 + 2.676 + + + 12800 + 2.676 + + + 25600 + 2.676 + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D700_(PTP_mode).xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D700_(PTP_mode).xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D700_(PTP_mode).xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/Nikon_DSLR_DSC_D700_(PTP_mode).xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,127 @@ + + + 1 + Nikon DSLR DSC D700 (PTP mode) + COLOR + ISO_DISCRETE + + 100 + 125 + 160 + 250 + 320 + 400 + 500 + 640 + 800 + 1000 + 1250 + 1600 + 2000 + 2500 + 3200 + 4000 + 5000 + 6400 + 12800 + 25600 + + + 0 + Standard + + + 100 + 15.671 + + + 126 + 15.671 + + + 159 + 15.671 + + + 200 + 15.671 + + + 251 + 15.455 + + + 318 + 15.348 + + + 400 + 8.754 + + + 503 + 8.694 + + + 636 + 8.877 + + + 800 + 5.464 + + + 1006 + 5.657 + + + 1273 + 5.696 + + + 1600 + 5.776 + + + 2011 + 5.736 + + + 2546 + 5.696 + + + 3200 + 5.696 + + + 4022 + 5.696 + + + 5091 + 5.696 + + + 6400 + 5.736 + + + 8045 + 5.736 + + + 10183 + 5.736 + + + 12800 + 5.776 + + + 25600 + 5.776 + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163C.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163C.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163C.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163C.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,78 @@ + + + 1 + QHY CCD 163M + COLOR + NORMAL + + 0 + 500 + + + 0 + Standard + + + 0 + 3.44 + + + 20 + 2.53 + + + 40 + 2.43 + + + 60 + 2.17 + + + 80 + 1.81 + + + 100 + 1.81 + + + 120 + 1.69 + + + 150 + 1.59 + + + 200 + 1.52 + + + 250 + 0.92 + + + 300 + 0.9 + + + 350 + 0.89 + + + 400 + 0.87 + + + 450 + 0.8 + + + 500 + 0.96 + + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163M.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163M.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163M.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_163M.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,78 @@ + + + 1 + QHY CCD 163M + MONOCHROME + NORMAL + + 0 + 500 + + + 0 + Standard + + + 0 + 3.44 + + + 20 + 2.53 + + + 40 + 2.43 + + + 60 + 2.17 + + + 80 + 1.81 + + + 100 + 1.81 + + + 120 + 1.69 + + + 150 + 1.59 + + + 200 + 1.52 + + + 250 + 0.92 + + + 300 + 0.9 + + + 350 + 0.89 + + + 400 + 0.87 + + + 450 + 0.8 + + + 500 + 0.96 + + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_268C.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_268C.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_268C.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_268C.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,953 @@ + + + 1 + QHY CCD 268C + COLOR + NORMAL + + 0 + 285 + + + 0 + Photographic + + + 0 + 7.25 + + + 5 + 7.1 + + + 10 + 6.78 + + + 15 + 6.74 + + + 20 + 6.74 + + + 25 + 2.8 + + + 30 + 2.63 + + + 35 + 2.7 + + + 40 + 2.57 + + + 45 + 2.55 + + + 50 + 2.52 + + + 55 + 2.35 + + + 60 + 2.07 + + + 65 + 2.05 + + + 70 + 2.04 + + + 75 + 2.06 + + + 80 + 2.03 + + + 85 + 2.01 + + + 90 + 2 + + + 95 + 1.99 + + + 100 + 2 + + + 105 + 1.97 + + + 110 + 1.96 + + + 115 + 1.95 + + + 120 + 1.94 + + + 125 + 1.93 + + + 130 + 1.92 + + + 135 + 1.89 + + + 140 + 1.9 + + + 145 + 1.89 + + + 150 + 1.85 + + + 155 + 1.82 + + + 160 + 1.81 + + + 165 + 1.8 + + + 170 + 1.79 + + + 175 + 1.75 + + + 180 + 1.74 + + + 185 + 1.7 + + + 190 + 1.68 + + + 195 + 1.67 + + + 200 + 1.62 + + + 205 + 1.59 + + + 210 + 1.56 + + + 215 + 1.53 + + + 220 + 1.48 + + + 225 + 1.44 + + + 230 + 1.41 + + + 235 + 1.36 + + + 240 + 1.32 + + + 245 + 1.26 + + + 250 + 1.17 + + + 255 + 1.12 + + + 260 + 1.03 + + + 265 + 0.92 + + + 270 + 0.79 + + + 275 + 0.62 + + + 280 + 0.6 + + + 285 + 0.7 + + + 1 + High Gain + + + 5 + 3.6 + + + 10 + 3.58 + + + 15 + 3.64 + + + 20 + 3.63 + + + 25 + 3.63 + + + 30 + 3.58 + + + 35 + 3.49 + + + 40 + 3.39 + + + 45 + 3.43 + + + 50 + 3.53 + + + 55 + 3.43 + + + 60 + 1.69 + + + 65 + 1.69 + + + 70 + 1.67 + + + 75 + 1.67 + + + 80 + 1.63 + + + 85 + 1.6 + + + 90 + 1.57 + + + 95 + 1.53 + + + 100 + 1.25 + + + 105 + 1.22 + + + 110 + 1.22 + + + 115 + 1.21 + + + 120 + 1.2 + + + 125 + 1.2 + + + 130 + 1.19 + + + 135 + 1.18 + + + 140 + 1.17 + + + 145 + 1.15 + + + 150 + 1.14 + + + 155 + 1.14 + + + 160 + 1.13 + + + 165 + 1.12 + + + 170 + 1.11 + + + 175 + 1.09 + + + 180 + 1.09 + + + 185 + 1.08 + + + 190 + 1.06 + + + 195 + 1.06 + + + 200 + 1.03 + + + 205 + 1.01 + + + 210 + 0.98 + + + 215 + 0.99 + + + 220 + 0.96 + + + 225 + 0.97 + + + 230 + 0.92 + + + 235 + 0.93 + + + 240 + 0.87 + + + 245 + 0.87 + + + 250 + 0.8 + + + 255 + 0.79 + + + 260 + 0.8 + + + 265 + 0.7 + + + 270 + 0.71 + + + 275 + 0.7 + + + 280 + 0.69 + + + 285 + 0.69 + + + 2 + Extended Full Well + + + 0 + 7.56 + + + 5 + 7.48 + + + 10 + 7.41 + + + 15 + 7.34 + + + 20 + 7.22 + + + 25 + 7.15 + + + 30 + 7.01 + + + 35 + 6.83 + + + 40 + 6.69 + + + 45 + 6.6 + + + 50 + 6.64 + + + 55 + 6.72 + + + 60 + 6.86 + + + 65 + 6.93 + + + 70 + 6.73 + + + 75 + 6.44 + + + 80 + 6.55 + + + 85 + 6.06 + + + 90 + 6.16 + + + 95 + 5.75 + + + 100 + 5.36 + + + 105 + 5.34 + + + 110 + 5.34 + + + 115 + 5.35 + + + 120 + 5.34 + + + 125 + 5.3 + + + 130 + 5.22 + + + 135 + 5.18 + + + 140 + 5.09 + + + 145 + 5.04 + + + 150 + 4.96 + + + 155 + 4.9 + + + 160 + 4.85 + + + 165 + 4.77 + + + 170 + 4.71 + + + 175 + 4.62 + + + 180 + 4.57 + + + 185 + 4.46 + + + 190 + 4.4 + + + 195 + 4.32 + + + 200 + 4.2 + + + 205 + 4.1 + + + 210 + 4.02 + + + 215 + 3.95 + + + 220 + 3.79 + + + 225 + 3.71 + + + 230 + 3.58 + + + 235 + 3.53 + + + 240 + 3.41 + + + 245 + 3.26 + + + 250 + 3.14 + + + 255 + 3.04 + + + 260 + 2.87 + + + 265 + 2.8 + + + 270 + 2.62 + + + 275 + 2.5 + + + 280 + 2.34 + + + 285 + 2.18 + + + 3 + Extended Full Well 2CMSIT + + + 0 + 5.89 + + + 5 + 5.82 + + + 10 + 5.82 + + + 15 + 5.73 + + + 20 + 5.66 + + + 25 + 5.58 + + + 30 + 5.44 + + + 35 + 5.39 + + + 40 + 5.26 + + + 45 + 5.17 + + + 50 + 5.17 + + + 55 + 5.25 + + + 60 + 5.34 + + + 65 + 5.43 + + + 70 + 5.33 + + + 75 + 5.08 + + + 80 + 5.05 + + + 85 + 4.81 + + + 90 + 4.85 + + + 95 + 4.55 + + + 100 + 4.26 + + + 105 + 4.25 + + + 110 + 4.23 + + + 115 + 4.26 + + + 120 + 4.26 + + + 125 + 4.23 + + + 130 + 4.18 + + + 135 + 4.15 + + + 140 + 4.08 + + + 145 + 4.09 + + + 150 + 4.05 + + + 155 + 4.01 + + + 160 + 3.98 + + + 165 + 3.96 + + + 170 + 3.91 + + + 175 + 3.87 + + + 180 + 3.83 + + + 185 + 3.8 + + + 190 + 3.76 + + + 195 + 3.68 + + + 200 + 3.64 + + + 205 + 3.57 + + + 210 + 3.51 + + + 215 + 3.44 + + + 220 + 3.39 + + + 225 + 3.33 + + + 230 + 3.25 + + + 235 + 3.2 + + + 240 + 3.13 + + + 245 + 3.03 + + + 250 + 2.99 + + + 255 + 2.87 + + + 260 + 2.77 + + + 265 + 2.72 + + + 270 + 2.58 + + + 275 + 2.5 + + + 280 + 2.37 + + + 285 + 2.22 + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_294M.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_294M.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_294M.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_294M.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,57 @@ + + + 1 + QHY CCD 294M + MONOCHROME + NORMAL + + 0 + 3500 + + + 0 + 11M + + 06.34 + 2006.28 + 4006.11 + 6005.9 + 8005.89 + 10005.91 + 14005.19 + 16001.56 + 18001.59 + 20001.58 + 22001.49 + 24001.45 + 26001.44 + 28001.41 + 30001.37 + 32001.3 + 34001.24 + 36001.19 + + 1 + 47M + + 05.34 + 2002.52 + 4002.46 + 6002.4 + 8002.34 + 10002.27 + 14002.17 + 16002.12 + 18002.08 + 20002.04 + 22001.98 + 24001.94 + 26001.89 + 28001.84 + 30001.78 + 32001.72 + 34001.64 + 36001.54 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_461_PH.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_461_PH.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_461_PH.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_461_PH.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,121 @@ + + + 1 + QHY CCD 461 PH + MONOCHROME + NORMAL + + 0 + 100 + + + 0 + Photographic + + 07.42 + 57.38 + 107.03 + 157 + 207.01 + 256.6 + 262.61 + 272.65 + 282.66 + 292.59 + 302.51 + 352.5 + 402.47 + 452.5 + 502.44 + 552.4 + 602.08 + 651.92 + 701.96 + 751.89 + 801.84 + 851.86 + 901.85 + 951.83 + 1001.84 + + 1 + High Gain + + 03.56 + 53.64 + 103.47 + 153.45 + 203.46 + 253.5 + 303.47 + 353.44 + 403.59 + 453.69 + 503.53 + 553.25 + 561.68 + 571.68 + 581.67 + 591.65 + 601.65 + 651.66 + 701.64 + 751.69 + 801.48 + 851.54 + 901.45 + 951.47 + 1001.29 + + 2 + Extended Full Well + + 07.43 + 57.53 + 107.32 + 157.32 + 207.47 + 257.18 + 307.23 + 357.28 + 406.94 + 456.99 + 507.1 + 556.67 + 606.65 + 656.69 + 706.54 + 756.37 + 806.14 + 855.97 + 905.97 + 955.61 + 1005.21 + + 3 + Extended Full Well 2CMS + + 05.7 + 55.41 + 105.56 + 155.58 + 205.59 + 255.41 + 305.4 + 355.41 + 405.37 + 455.3 + 505.42 + 555.13 + 605.15 + 655.2 + 705.07 + 754.96 + 804.78 + 854.74 + 904.75 + 954.29 + 1004.15 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_600_PH.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_600_PH.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_600_PH.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/QHY_CCD_600_PH.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,121 @@ + + + 1 + QHY CCD 600 PH + MONOCHROME + NORMAL + + 0 + 100 + + + 0 + Photographic + + 07.87 + 57.70 + 107.47 + 157.31 + 207.15 + 256.97 + 262.75 + 302.72 + 352.66 + 402.60 + 452.53 + 502.47 + 552.45 + 562.41 + 602.32 + 651.99 + 702.00 + 752.00 + 802.02 + 852.00 + 901.99 + 951.97 + 1001.97 + + 1 + High Gain + + 03.68 + 53.64 + 103.68 + 153.6 + 203.58 + 253.60 + 263.56 + 303.53 + 353.56 + 403.52 + 453.52 + 503.50 + 553.33 + 561.68 + 601.65 + 651.64 + 701.62 + 751.61 + 801.54 + 851.5 + 901.47 + 951.39 + 1001.11 + + 2 + Extended Full Well + + 07.90 + 57.81 + 107.79 + 157.72 + 207.73 + 257.59 + 267.56 + 307.51 + 357.41 + 407.30 + 457.36 + 507.21 + 557.14 + 567.10 + 607.02 + 657.01 + 706.97 + 756.96 + 806.84 + 856.53 + 906.43 + 955.96 + 1005.43 + + 3 + Extended Full Well 2CMS + + 05.94 + 55.88 + 105.96 + 155.99 + 205.95 + 255.88 + 265.86 + 305.81 + 355.63 + 405.48 + 455.47 + 505.62 + 555.70 + 565.62 + 605.53 + 655.43 + 705.76 + 755.40 + 805.33 + 855.34 + 905.22 + 955.14 + 1004.97 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI2600MC_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI2600MC_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI2600MC_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI2600MC_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,28 @@ + + + 1 + ZWO CCD ASI2600MC Pro + COLOR + NORMAL + + 0 + 450 + + + 0 + Standard + + 03.39 + 503.31 + 993.23 + 1001.45 + 1501.4 + 2001.39 + 2501.32 + 3001.28 + 3501.13 + 4001.09 + 4501.16 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MC_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MC_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MC_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MC_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,29 @@ + + + 1 + ZWO CCD ASI294MC Pro + COLOR + NORMAL + + 0 + 390 + + + 0 + Standard + + 07.42 + 506.41 + 1005.93 + 1195.72 + 1201.79 + 1301.72 + 1501.63 + 2001.63 + 2501.43 + 3001.33 + 3501.27 + 3901.32 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MM_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MM_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MM_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI294MM_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,29 @@ + + + 1 + ZWO CCD ASI294MM Pro + MONOCHROME + NORMAL + + 0 + 450 + + + 0 + Standard + + 08.03 + 507.23 + 1006.43 + 1196.21 + 1201.85 + 1501.74 + 2001.58 + 2501.48 + 3001.3 + 3501.28 + 4001.35 + 4501.27 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MC_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MC_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MC_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MC_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,29 @@ + + + 1 + ZWO CCD ASI533MC Pro + COLOR + NORMAL + + 0 + 460 + + + 0 + Standard + + 03.88 + 503.57 + 993.26 + 1001.5 + 1501.43 + 2001.31 + 2501.25 + 3001.18 + 3501.14 + 4001.09 + 4501.13 + 4601.02 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MM_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MM_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MM_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI533MM_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,29 @@ + + + 1 + ZWO CCD ASI533MM Pro + MONOCHROME + NORMAL + + 0 + 460 + + + 0 + Standard + + 03.84 + 503.57 + 993.17 + 1001.5 + 1501.43 + 2001.31 + 2501.25 + 3001.19 + 3501.15 + 4001.1 + 4501.05 + 4601.02 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI6200MC_Pro.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI6200MC_Pro.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI6200MC_Pro.xml 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/cameradata/ZWO_CCD_ASI6200MC_Pro.xml 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,29 @@ + + + 1 + ZWO CCD ASI6200MC + COLOR + NORMAL + + 0 + 460 + + + 0 + Standard + + 03.56 + 503.52 + 993.36 + 1001.53 + 1501.51 + 2001.46 + 2501.46 + 3001.42 + 3501.43 + 4001.33 + 4501.4 + 4601.26 + + + Binary files /tmp/tmpofjp22dn/JkVLJ9t6Ee/kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/icons/sensorgraphic.png and /tmp/tmpofjp22dn/xGxC9KcmZG/kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/icons/sensorgraphic.png differ diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/indidrivers.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/indidrivers.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/indidrivers.xml 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/indidrivers.xml 2023-12-03 05:23:17.000000000 +0000 @@ -11,6 +11,10 @@ shelyak_usis 1.2 + + indi_lx200_10micron + 1.2 + indi_lx200basic 2.1 @@ -29,7 +33,7 @@ indi_lx200_OnStep - 1.20 + 1.22 indi_lx200_OpenAstroTech @@ -263,10 +267,6 @@ indi_skycommander_telescope 1.0 - - indi_lx200_10micron - 1.0 - indi_simulator_telescope 1.0 @@ -487,7 +487,7 @@ indi_siefs_focus - 0.1 + 0.2 indi_lacerta_mfoc_focus @@ -667,7 +667,7 @@ indi_snapcap - 1.2 + 1.3 indi_Excalibur @@ -869,14 +869,6 @@ indi_asi_ccd 2.3 - - indi_asi_single_ccd - 2.3 - - - indi_asi_single_ccd - 2.3 - @@ -913,7 +905,13 @@ indi_oasis_focuser - 1.0 + 1.1 + + + + + indi_oasis_filter_wheel + 1.1 @@ -949,7 +947,27 @@ - + + indi_avalonud_telescope + 2.2 + + + + + indi_avalonud_focuser + 2.2 + + + + + indi_avalonud_aux + 2.2 + + + + + + indi_lx200stargo 1.13 @@ -1376,14 +1394,6 @@ - - - indi_libcamera_ccd - 1.0 - - - - indi_rpi_gpio @@ -1509,6 +1519,10 @@ indi_mallincam_ccd 2.1 + + indi_meadecam_ccd + 2.1 + indi_nncam_ccd 2.1 @@ -1593,3 +1607,11 @@ + + + + indi_libcamera_ccd + 1.0 + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/kstars.qrc kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/kstars.qrc --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/data/kstars.qrc 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/data/kstars.qrc 2023-12-03 05:23:17.000000000 +0000 @@ -68,6 +68,7 @@ icons/indihub_logo.svg icons/StellarSolverIcon.png icons/select_stat.png + icons/sensorgraphic.png kstars.knsrc diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/dialogs/focusdialog.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/dialogs/focusdialog.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/dialogs/focusdialog.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/dialogs/focusdialog.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -113,62 +113,68 @@ void FocusDialog::validatePoint() { bool raOk(false), decOk(false), azOk(false), altOk(false); - - //false means expressed in hours - dms ra(fd->raBox->createDms(&raOk)); - dms dec(fd->decBox->createDms(&decOk)); - QString message; - if (raOk && decOk) + if (fd->fdTab->currentWidget() == fd->rdTab) { - //make sure values are in valid range - if (ra.Hours() < 0.0 || ra.Hours() > 24.0) - message = i18n("The Right Ascension value must be between 0.0 and 24.0."); - if (dec.Degrees() < -90.0 || dec.Degrees() > 90.0) - message += '\n' + i18n("The Declination value must be between -90.0 and 90.0."); - if (!message.isEmpty()) - { - KSNotification::sorry(message, i18n("Invalid Coordinate Data")); - return; - } + //false means expressed in hours + dms ra(fd->raBox->createDms(&raOk)); + dms dec(fd->decBox->createDms(&decOk)); - bool ok { false }; - double epoch0 = KStarsDateTime::stringToEpoch(fd->epochBox->text(), ok); - if (!ok) + if (raOk && decOk) { - KSNotification::sorry(message, i18n("Invalid Epoch format")); - return; - } - long double jd0 = KStarsDateTime::epochToJd(epoch0); + //make sure values are in valid range + if (ra.Hours() < 0.0 || ra.Hours() > 24.0) + message = i18n("The Right Ascension value must be between 0.0 and 24.0."); + if (dec.Degrees() < -90.0 || dec.Degrees() > 90.0) + message += '\n' + i18n("The Declination value must be between -90.0 and 90.0."); + if (!message.isEmpty()) + { + KSNotification::sorry(message, i18n("Invalid Coordinate Data")); + return; + } + + bool ok { false }; + double epoch0 = KStarsDateTime::stringToEpoch(fd->epochBox->text(), ok); + if (!ok) + { + KSNotification::sorry(message, i18n("Invalid Epoch format")); + return; + } + long double jd0 = KStarsDateTime::epochToJd(epoch0); + + // Set RA and Dec to whatever epoch we have been given (may be J2000, JNow or something completely different) + Point->setRA(ra); + Point->setDec(dec); + + if (jd0 != J2000) + { + // Compute and set the J2000 coordinates of Point + Point->catalogueCoord(jd0); + } + else + { + Point->setRA0(ra); + Point->setDec0(dec); + } + + // N.B. At this point (ra, dec) and (ra0, dec0) are both + // J2000.0 values Therefore, we precess again to get the + // values for the present draw epoch into (ra, dec) + Point->apparentCoord(static_cast(J2000), KStarsData::Instance()->updateNum()->julianDay()); + + Point->EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat()); + // At this point, both (RA, Dec) and (Alt, Az) should correspond to current time + // (RA0, Dec0) will be J2000.0 -- asimha - // Set RA and Dec to whatever epoch we have been given (may be J2000, JNow or something completely different) - Point->setRA(ra); - Point->setDec(dec); - - if (jd0 != J2000) - { - // Compute and set the J2000 coordinates of Point - Point->catalogueCoord(jd0); + QDialog::accept(); } else { - Point->setRA0(ra); - Point->setDec0(dec); + QDialog::reject(); } - - // N.B. At this point (ra, dec) and (ra0, dec0) are both - // J2000.0 values Therefore, we precess again to get the - // values for the present draw epoch into (ra, dec) - Point->apparentCoord(static_cast(J2000), KStarsData::Instance()->updateNum()->julianDay()); - - Point->EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat()); - // At this point, both (RA, Dec) and (Alt, Az) should correspond to current time - // (RA0, Dec0) will be J2000.0 -- asimha - - QDialog::accept(); } - else + else // Az/Alt tab is active { dms az(fd->azBox->createDms(&azOk)); dms alt(fd->altBox->createDms(&altOk)); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/align.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/align.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/align.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/align.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -31,22 +31,29 @@ // Auxiliary #include "auxiliary/QProgressIndicator.h" #include "auxiliary/ksmessagebox.h" +#include "ekos/auxiliary/darkprocessor.h" +#include "ekos/auxiliary/filtermanager.h" #include "ekos/auxiliary/stellarsolverprofileeditor.h" #include "ekos/auxiliary/profilesettings.h" #include "ekos/auxiliary/opticaltrainmanager.h" #include "ekos/auxiliary/opticaltrainsettings.h" #include "ksnotification.h" #include "kspaths.h" +#include "ksuserdb.h" #include "fov.h" #include "kstars.h" #include "kstarsdata.h" #include "skymapcomposite.h" +#include "ekos/auxiliary/solverutils.h" +#include "ekos/auxiliary/rotatorutils.h" // INDI #include "ekos/manager.h" +#include "indi/indidome.h" #include "indi/clientmanager.h" #include "indi/driverinfo.h" #include "indi/indifilterwheel.h" +#include "indi/indirotator.h" #include "profileinfo.h" // System Includes @@ -1937,6 +1944,8 @@ m_StellarSolver->setSSLogLevel(SSolver::LOG_OFF); } + SolverUtils::patchMultiAlgorithm(m_StellarSolver.get()); + // Start solving process m_StellarSolver->start(); } @@ -1949,6 +1958,18 @@ remoteParser->startSolver(m_ImageData->filename(), generateRemoteArgs(m_ImageData), false); } + // In these cases, the error box is not used, and we don't want it polluted + // from some previous operation. + if (matchPAHStage(PAA::PAH_FIRST_CAPTURE) || + matchPAHStage(PAA::PAH_SECOND_CAPTURE) || + matchPAHStage(PAA::PAH_THIRD_CAPTURE) || + matchPAHStage(PAA::PAH_FIRST_SOLVE) || + matchPAHStage(PAA::PAH_SECOND_SOLVE) || + matchPAHStage(PAA::PAH_THIRD_SOLVE) || + nothingR->isChecked() || + syncR->isChecked()) + errOut->clear(); + // Kick off timer solverTimer.start(); @@ -1961,9 +1982,18 @@ disconnect(m_StellarSolver.get(), &StellarSolver::ready, this, &Align::solverComplete); if(!m_StellarSolver->solvingDone() || m_StellarSolver->failed()) { - // If processed, we retruned. Otherwise, it is a fail - if (CHECK_PAH(processSolverFailure())) - return; + if (matchPAHStage(PAA::PAH_FIRST_CAPTURE) || + matchPAHStage(PAA::PAH_SECOND_CAPTURE) || + matchPAHStage(PAA::PAH_THIRD_CAPTURE) || + matchPAHStage(PAA::PAH_FIRST_SOLVE) || + matchPAHStage(PAA::PAH_SECOND_SOLVE) || + matchPAHStage(PAA::PAH_THIRD_SOLVE)) + { + if (CHECK_PAH(processSolverFailure())) + return; + else + setState(ALIGN_ABORTED); + } solverFailed(); return; } @@ -2277,13 +2307,18 @@ QString name = "failed_align_frame_" + now.toString("yyyy-MM-dd-HH-mm-ss") + extraFilenameInfo + ".fits"; QString filename = path + QStringLiteral("/") + name; if (m_ImageData) + { m_ImageData->saveImage(filename); + appendLogText(i18n("Saving failed solver image to %1", filename)); + } + } if (state != ALIGN_ABORTED) { // Try to solve with scale turned off, if not turned off already if (Options::astrometryUseImageScale() && useBlindScale == BLIND_IDLE) { + appendLogText(i18n("Solver failed. Retrying without scale constraint.")); useBlindScale = BLIND_ENGAGNED; setAlignTableResult(ALIGN_RESULT_FAILED); captureAndSolve(); @@ -2293,6 +2328,7 @@ // Try to solve with the position turned off, if not turned off already if (Options::astrometryUsePosition() && useBlindPosition == BLIND_IDLE) { + appendLogText(i18n("Solver failed. Retrying without position constraint.")); useBlindPosition = BLIND_ENGAGNED; setAlignTableResult(ALIGN_RESULT_FAILED); captureAndSolve(); @@ -2594,8 +2630,8 @@ { appendLogText(i18n("Mount is synced to solution coordinates.")); - if (checkIfRotationRequired()) - return; + /* if (checkIfRotationRequired()) + return; */ KSNotification::event(QLatin1String("AlignSuccessful"), i18n("Astrometry alignment completed successfully"), KSNotification::Align); @@ -2631,19 +2667,6 @@ m_CaptureTimer.start(alignSettlingTime->value()); return; } - else if (differentialSlewingActivated) - { - appendLogText(i18n("Differential slewing complete.")); - - if (checkIfRotationRequired()) - return; - - KSNotification::event(QLatin1String("AlignSuccessful"), i18n("Astrometry alignment completed successfully"), - KSNotification::Align); - setState(ALIGN_COMPLETE); - emit newStatus(state); - solverIterations = 0; - } else if (m_CurrentGotoMode == GOTO_SLEW || (m_MountModel && m_MountModel->isRunning())) { if (targetAccuracyNotMet) @@ -2896,12 +2919,8 @@ { dms m_TargetDiffRA = m_AlignCoord.ra().deltaAngle(m_TargetCoord.ra()); dms m_TargetDiffDE = m_AlignCoord.dec().deltaAngle(m_TargetCoord.dec()); - m_TargetCoord.setRA(m_TargetCoord.ra() - m_TargetDiffRA); m_TargetCoord.setDec(m_TargetCoord.dec() - m_TargetDiffDE); - - differentialSlewingActivated = true; - qCDebug(KSTARS_EKOS_ALIGN) << "Using differential slewing. Setting Target Coordinates to RA:" << m_TargetCoord.ra().toHMSString() << "DE:" << m_TargetCoord.dec().toDMSString(); @@ -2909,10 +2928,8 @@ } else Sync(); - return; } - Slew(); } @@ -3736,7 +3753,9 @@ matchPAHStage(PAA::PAH_THIRD_CAPTURE) || matchPAHStage(PAA::PAH_FIRST_SOLVE) || matchPAHStage(PAA::PAH_SECOND_SOLVE) || - matchPAHStage(PAA::PAH_THIRD_SOLVE)) + matchPAHStage(PAA::PAH_THIRD_SOLVE) || + nothingR->isChecked() || + syncR->isChecked()) return; m_TargetDiffRA = (m_AlignCoord.ra().deltaAngle(m_TargetCoord.ra())).Degrees() * 3600; m_TargetDiffDE = (m_AlignCoord.dec().deltaAngle(m_TargetCoord.dec())).Degrees() * 3600; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/align.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/align.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/align.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/align.h 2023-12-03 05:23:17.000000000 +0000 @@ -9,16 +9,12 @@ #pragma once -#include "ekos/auxiliary/filtermanager.h" #include "ui_align.h" #include "ekos/ekos.h" #include "indi/indicamera.h" #include "indi/indistd.h" #include "indi/indimount.h" -#include "indi/indidome.h" -#include "ksuserdb.h" -#include "ekos/auxiliary/darkprocessor.h" -#include "ekos/auxiliary/rotatorutils.h" +#include "skypoint.h" #include #include @@ -45,6 +41,8 @@ namespace Ekos { class AstrometryParser; +class DarkProcessor; +class FilterManager; class RemoteAstrometryParser; class OpsAstrometry; class OpsAlign; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/manualrotator.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/manualrotator.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/manualrotator.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/manualrotator.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,12 +8,12 @@ #include "ui_manualrotator.h" #include "ekos/ekos.h" -#include "align.h" - namespace Ekos { +class Align; + class ManualRotator : public QDialog, public Ui::ManualRotator { Q_OBJECT diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/mountmodel.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/mountmodel.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/mountmodel.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/mountmodel.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -16,6 +16,7 @@ #include "starobject.h" #include "skymapcomposite.h" #include "skyobject.h" +#include "starobject.h" #include "dialogs/finddialog.h" #include "QProgressIndicator.h" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/mountmodel.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/mountmodel.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/mountmodel.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/mountmodel.h 2023-12-03 05:23:17.000000000 +0000 @@ -9,13 +9,14 @@ #include "ui_mountmodel.h" #include "ekos/ekos.h" -#include "starobject.h" +#include "skypoint.h" #include #include class QProgressIndicator; class SkyObject; +class StarObject; namespace Ekos { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/opsastrometry.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/opsastrometry.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/opsastrometry.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/opsastrometry.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,7 +8,6 @@ #pragma once #include "ui_opsastrometry.h" -#include "parameters.h" #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -8,6 +8,7 @@ #include "polaralignmentassistant.h" #include "align.h" +#include "alignview.h" #include "kstars.h" #include "kstarsdata.h" #include "ksmessagebox.h" @@ -565,6 +566,7 @@ m_PAHStage == PAH_THIRD_SOLVE) && ++m_PAHRetrySolveCounter < 4) { + emit newLog(i18n("PAA: Solver failed, retrying.")); emit captureAndSolve(); return true; } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/align/polaralignmentassistant.h 2023-12-03 05:23:17.000000000 +0000 @@ -11,10 +11,10 @@ #include "ekos/ekos.h" #include "ekos/guide/internalguide/starcorrespondence.h" #include "polaralign.h" -#include "alignview.h" #include "align.h" #include "indi/indimount.h" +class AlignView; class QProgressIndicator; class SolverUtils; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/analyze/analyze.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/analyze/analyze.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/analyze/analyze.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/analyze/analyze.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -20,7 +20,9 @@ #include "fitsviewer/fitsviewer.h" #include "ksmessagebox.h" #include "kstars.h" +#include "kstarsdata.h" #include "Options.h" +#include "qcustomplot.h" #include #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/analyze/analyze.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/analyze/analyze.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/analyze/analyze.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/analyze/analyze.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,15 +8,16 @@ #define ANALYZE_H #include -#include "qcustomplot.h" #include "ekos/ekos.h" #include "ekos/mount/mount.h" #include "indi/indimount.h" #include "yaxistool.h" #include "ui_analyze.h" +#include "ekos/manager/meridianflipstate.h" class FITSViewer; class OffsetDateTimeTicker; +class QCustomPlot; namespace Ekos { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/opticaltrains.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/opticaltrains.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/opticaltrains.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/opticaltrains.ui 2023-12-03 05:23:17.000000000 +0000 @@ -146,10 +146,10 @@ - <html><head/><body><p>Select the scope or lens used in the optical train.</p><p>To add, edit, or delete optical elements, tap the <span style=" font-weight:600;">Telescope &amp; Lens</span> button.</p></body></html> + <html><head/><body><p>Select the scope or lens used in the optical train. This is a required selection in all trains.</p><p>To add, edit, or delete optical elements, tap the <span style=" font-weight:600;">Telescope &amp; Lens</span> button.</p></body></html> - Scope/Lense: + <html><head/><body><p>Scope/Lens: <span style=" color:#ff0000;">*</span></p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -182,10 +182,10 @@ - <html><head/><body><p>Select the imaging camera for this optical train.</p></body></html> + <html><head/><body><p>Select the imaging camera for this optical train. This is a required selection in all trains.</p></body></html> - Camera: + <html><head/><body><p>Camera: <span style=" color:#ff0000;">*</span></p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -11,8 +11,9 @@ #include #include -SolverUtils::SolverUtils(const SSolver::Parameters ¶meters, double timeoutSeconds) : m_Parameters(parameters), - m_TimeoutMilliseconds(timeoutSeconds * 1000.0) +SolverUtils::SolverUtils(const SSolver::Parameters ¶meters, double timeoutSeconds, + SSolver::ProcessType type) : + m_Parameters(parameters), m_TimeoutMilliseconds(timeoutSeconds * 1000.0), m_Type(type) { connect(&m_Watcher, &QFutureWatcher::finished, this, &SolverUtils::executeSolver, Qt::UniqueConnection); connect(&m_SolverTimer, &QTimer::timeout, this, &SolverUtils::solverTimeout, Qt::UniqueConnection); @@ -72,7 +73,7 @@ { if (m_StellarSolver->isRunning()) m_StellarSolver->abort(); - m_StellarSolver->setProperty("ProcessType", SSolver::SOLVE); + m_StellarSolver->setProperty("ProcessType", m_Type); m_StellarSolver->loadNewImageBuffer(m_ImageData->getStatistics(), m_ImageData->getImageBuffer()); m_StellarSolver->setProperty("ExtractorType", Options::solveSextractorType()); m_StellarSolver->setProperty("SolverType", Options::solverType()); @@ -142,6 +143,8 @@ // LOG_ALL is crashy now m_StellarSolver->setLogLevel(SSolver::LOG_NONE); m_StellarSolver->setSSLogLevel(SSolver::LOG_OFF); + + patchMultiAlgorithm(m_StellarSolver.get()); } void SolverUtils::runSolver(const QSharedPointer &data) @@ -180,12 +183,19 @@ const double elapsed = (QDateTime::currentMSecsSinceEpoch() - m_StartTime) / 1000.0; m_SolverTimer.stop(); - FITSImage::Solution solution; - bool success = m_StellarSolver->solvingDone() && !m_StellarSolver->failed(); - if (success) - solution = m_StellarSolver->getSolution(); - emit done(false, success, solution, elapsed); - + if (m_Type == SSolver::SOLVE) + { + FITSImage::Solution solution; + const bool success = m_StellarSolver->solvingDone() && !m_StellarSolver->failed(); + if (success) + solution = m_StellarSolver->getSolution(); + emit done(false, success, solution, elapsed); + } + else + { + const bool success = m_StellarSolver->extractionDone() && !m_StellarSolver->failed(); + emit done(false, success, FITSImage::Solution(), elapsed); + } if (!m_TemporaryFilename.isEmpty()) QFile::remove(m_TemporaryFilename); m_TemporaryFilename.clear(); @@ -204,3 +214,15 @@ QFile::remove(m_TemporaryFilename); m_TemporaryFilename.clear(); } + +// We don't trust StellarSolver's mutli-processing algorithm MULTI_DEPTHS which is used +// with multiAlgorithm==MULTI_AUTO && use_scale && !use_position. +void SolverUtils::patchMultiAlgorithm(StellarSolver *solver) +{ + if (solver && solver->property("UseScale").toBool() && !solver->property("UsePosition").toBool()) + { + auto currentParameters = solver->getCurrentParameters(); + currentParameters.multiAlgorithm = NOT_MULTI; + solver->setParameters(currentParameters); + } +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/auxiliary/solverutils.h 2023-12-03 05:23:17.000000000 +0000 @@ -30,7 +30,8 @@ Q_OBJECT public: - SolverUtils(const SSolver::Parameters ¶meters, double timeoutSeconds = 15); + SolverUtils(const SSolver::Parameters ¶meters, double timeoutSeconds = 15, + SSolver::ProcessType type = SSolver::SOLVE); ~SolverUtils(); void runSolver(const QSharedPointer &data); @@ -43,6 +44,28 @@ void setHealpix(int indexToUse = -1, int healpixToUse = -1); void getSolutionHealpix(int *indexUsed, int *healpixUsed) const; + const FITSImage::Background &getBackground() const + { + // Better leak than crash. Warn? + if (!m_StellarSolver) return *new FITSImage::Background(); + return m_StellarSolver->getBackground(); + } + const QList &getStarList() const + { + // Better leak than crash. Warn? + if (!m_StellarSolver) return *new QList(); + return m_StellarSolver->getStarList(); + } + int getNumStarsFound() const + { + if (!m_StellarSolver) return 0; + return m_StellarSolver->getNumStarsFound(); + }; + + // We don't trust StellarSolver's mutli-processing algorithm MULTI_DEPTHS which is used + // with multiAlgorithm==MULTI_AUTO && use_scale && !use_position. This disables that. + static void patchMultiAlgorithm(StellarSolver *solver); + signals: void done(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds); void newLog(const QString &logText); @@ -76,6 +99,7 @@ double m_raDegrees { 0.0 }; double m_decDegrees { 0.0 }; + SSolver::ProcessType m_Type = SSolver::SOLVE; std::mutex deleteSolverMutex; }; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/calibrationoptions.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/calibrationoptions.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/calibrationoptions.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/calibrationoptions.ui 2023-12-03 05:23:17.000000000 +0000 @@ -6,80 +6,65 @@ 0 0 - 434 - 235 + 575 + 160 Calibration Options + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + - Specify the source the flat field evenly illuminated light source + <html><head/><body><p>Select which actions to perform before a Bias/Dark/Flat frame is captured.</p></body></html> - Flat Source + Calibration Pre-Actions - - - - Light source triggered by the user manually - - - Manual - - - true - - - flatSourceGroup - - - - - - - For dark and bias frames, close the dust cap before proceeding. For flat frames, close the dust cap and turn on the light source. - - - Dust Cover with Built-in Flat Light - - - flatSourceGroup - - - - - - - For dark and bias frames, close the dust cap before proceeding. For flat frames, open the dust cap and turn on the light source. - - - Dust Cover with External Flat Light - - - flatSourceGroup - - - + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + - + Slew mount to the specified Azimuth/Altitude coordinates before taking flat field images - Wall + Goto Wall - - flatSourceGroup - @@ -113,19 +98,17 @@ - - - false - - - Use Dawn and Dusk light + + + Park Mount + + + + - Dawn/Dusk + Park Dome - - flatSourceGroup - @@ -150,6 +133,21 @@ Flat Duration + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + @@ -241,20 +239,6 @@ - - - Park Mount - - - - - - - Park Dome - - - - Qt::Horizontal @@ -275,16 +259,15 @@ - manualSourceC - flatDeviceSourceC - darkDeviceSourceC - wallSourceC + gotoWallC azBox altBox - dawnDuskFlatsC + parkMountC + parkDomeC manualDurationC ADUC ADUValue + ADUTolerance @@ -322,7 +305,6 @@ - diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -6,7 +6,11 @@ #include "capture.h" +#include "captureprocess.h" +#include "capturemodulestate.h" +#include "capturedeviceadaptor.h" #include "captureadaptor.h" +#include "refocusstate.h" #include "kstars.h" #include "kstarsdata.h" #include "Options.h" @@ -23,9 +27,13 @@ #include "fitsviewer/fitsdata.h" #include "indi/driverinfo.h" #include "indi/indifilterwheel.h" +#include "indi/indicamera.h" +#include "indi/indirotator.h" #include "oal/observeradd.h" #include "ekos/guide/guide.h" #include "exposurecalculator/exposurecalculatordialog.h" +#include "dslrinfodialog.h" +#include "ekos/auxiliary/rotatorutils.h" #include #include @@ -35,7 +43,7 @@ // Current Sequence File Format: -#define SQ_FORMAT_VERSION 2.5 +#define SQ_FORMAT_VERSION 2.6 // We accept file formats with version back to: #define SQ_COMPAT_VERSION 2.0 @@ -462,7 +470,6 @@ &CaptureProcess::captureStarted); connect(m_captureModuleState.data(), &CaptureModuleState::newLog, this, &Capture::appendLogText); connect(m_captureModuleState.data(), &CaptureModuleState::newStatus, this, &Capture::newStatus); - connect(m_captureModuleState.data(), &CaptureModuleState::newTargetName, this, &Capture::newTargetName); connect(m_captureModuleState.data(), &CaptureModuleState::sequenceChanged, this, &Capture::sequenceChanged); connect(m_captureModuleState.data(), &CaptureModuleState::checkFocus, this, &Capture::checkFocus); connect(m_captureModuleState.data(), &CaptureModuleState::runAutoFocus, this, &Capture::runAutoFocus); @@ -497,6 +504,7 @@ }); connect(m_captureProcess.data(), &CaptureProcess::jobPrepared, this, &Capture::jobPrepared); connect(m_captureProcess.data(), &CaptureProcess::captureImageStarted, this, &Capture::captureImageStarted); + connect(m_captureProcess.data(), &CaptureProcess::captureTarget, this, &Capture::setTargetName); connect(m_captureProcess.data(), &CaptureProcess::downloadingFrame, this, [this]() { captureStatusWidget->setStatus(i18n("Downloading..."), Qt::yellow); @@ -561,7 +569,6 @@ &Capture::generatePreviewFilename); connect(targetNameT, &QLineEdit::textEdited, this, [ = ]() { - state()->setTargetName(targetNameT->text()); generatePreviewFilename(); qCDebug(KSTARS_EKOS_CAPTURE) << "Changed target to" << targetNameT->text() << "because of user edit"; }); @@ -630,6 +637,11 @@ emit settingsUpdated(getPresetSettings()); } +bool Capture::setDome(ISD::Dome *device) +{ + return m_captureProcess->setDome(device); +} + void Capture::setRotator(QString name) { ISD::Rotator *Rotator = devices()->rotator(); @@ -906,6 +918,8 @@ { if (captureGainN->value() != GainSpinSpecialValue) setGain(captureGainN->value()); + else + setGain(-1); }); } else @@ -944,6 +958,8 @@ { if (captureOffsetN->value() != OffsetSpinSpecialValue) setOffset(captureOffsetN->value()); + else + setOffset(-1); }); } else @@ -1941,7 +1957,7 @@ loadSequenceQueue(fileURL.toLocalFile()); } -bool Capture::loadSequenceQueue(const QString &fileURL, bool ignoreTarget) +bool Capture::loadSequenceQueue(const QString &fileURL, QString targetName) { QFile sFile(fileURL); if (!sFile.open(QIODevice::ReadOnly)) @@ -1954,7 +1970,7 @@ state()->clearCapturedFramesMap(); clearSequenceQueue(); - const bool result = process()->loadSequenceQueue(fileURL, ignoreTarget); + const bool result = process()->loadSequenceQueue(fileURL, targetName); // cancel if loading fails if (result == false) return result; @@ -2105,6 +2121,7 @@ captureTypeS->setCurrentIndex(job->getFrameType()); captureCountN->setValue(job->getCoreProperty(SequenceJob::SJ_Count).toInt()); captureDelayN->setValue(job->getCoreProperty(SequenceJob::SJ_Delay).toInt() / 1000); + targetNameT->setText(job->getCoreProperty(SequenceJob::SJ_TargetName).toString()); fileDirectoryT->setText(job->getCoreProperty(SequenceJob::SJ_LocalDirectory).toString()); fileUploadModeS->setCurrentIndex(job->getUploadMode()); fileRemoteDirT->setEnabled(fileUploadModeS->currentIndex() != 0); @@ -2126,12 +2143,10 @@ calibrationB->setEnabled(job->getFrameType() != FRAME_LIGHT); generateDarkFlatsB->setEnabled(job->getFrameType() != FRAME_LIGHT); state()->setFlatFieldDuration(job->getFlatFieldDuration()); - state()->setFlatFieldSource(job->getFlatFieldSource()); + state()->setCalibrationPreAction(job->getCalibrationPreAction()); state()->setTargetADU(job->getCoreProperty(SequenceJob::SJ_TargetADU).toDouble()); state()->setTargetADUTolerance(job->getCoreProperty(SequenceJob::SJ_TargetADUTolerance).toDouble()); state()->setWallCoord(job->getWallCoord()); - state()->setPreMountPark(job->getPreMountPark()); - state()->setPreDomePark(job->getPreDomePark()); // Script options state()->setScripts(job->getScripts()); @@ -2154,6 +2169,9 @@ else captureOffsetN->setValue(OffsetSpinSpecialValue); + // update place holder typ + generatePreviewFilename(); + if (m_RotatorControlPanel) // only if rotator is registered { if (job->getTargetRotation() != Ekos::INVALID_VALUE) @@ -2359,45 +2377,20 @@ Ui_calibrationOptions calibrationOptions; calibrationOptions.setupUi(&calibrationDialog); - if (devices()->mount()) - { - calibrationOptions.parkMountC->setEnabled(devices()->mount()->canPark()); - calibrationOptions.parkMountC->setChecked(state()->preMountPark()); - } - else - calibrationOptions.parkMountC->setEnabled(false); - - if (devices()->dome()) - { - calibrationOptions.parkDomeC->setEnabled(devices()->dome()->canPark()); - calibrationOptions.parkDomeC->setChecked(state()->preDomePark()); - } - else - calibrationOptions.parkDomeC->setEnabled(false); - - switch (state()->flatFieldSource()) - { - case SOURCE_MANUAL: - calibrationOptions.manualSourceC->setChecked(true); - break; - - case SOURCE_FLATCAP: - calibrationOptions.flatDeviceSourceC->setChecked(true); - break; - - case SOURCE_DARKCAP: - calibrationOptions.darkDeviceSourceC->setChecked(true); - break; - - case SOURCE_WALL: - calibrationOptions.wallSourceC->setChecked(true); - calibrationOptions.azBox->setText(state()->wallCoord().az().toDMSString()); - calibrationOptions.altBox->setText(state()->wallCoord().alt().toDMSString()); - break; + calibrationOptions.parkMountC->setEnabled(devices()->mount() && devices()->mount()->canPark()); + calibrationOptions.parkDomeC->setEnabled(devices()->dome() && devices()->dome()->canPark()); - case SOURCE_DAWN_DUSK: - calibrationOptions.dawnDuskFlatsC->setChecked(true); - break; + calibrationOptions.parkMountC->setChecked(false); + calibrationOptions.parkDomeC->setChecked(false); + calibrationOptions.gotoWallC->setChecked(false); + + calibrationOptions.parkMountC->setChecked(state()->calibrationPreAction() & ACTION_PARK_MOUNT); + calibrationOptions.parkDomeC->setChecked(state()->calibrationPreAction() & ACTION_PARK_DOME); + if (state()->calibrationPreAction() & ACTION_WALL) + { + calibrationOptions.gotoWallC->setChecked(true); + calibrationOptions.azBox->setText(state()->wallCoord().az().toDMSString()); + calibrationOptions.altBox->setText(state()->wallCoord().alt().toDMSString()); } switch (state()->flatFieldDuration()) @@ -2413,15 +2406,26 @@ break; } + // avoid combination of ACTION_WALL and ACTION_PARK_MOUNT + connect(calibrationOptions.gotoWallC, &QCheckBox::clicked, [&](bool checked) + { + if (checked) + calibrationOptions.parkMountC->setChecked(false); + }); + connect(calibrationOptions.parkMountC, &QCheckBox::clicked, [&](bool checked) + { + if (checked) + calibrationOptions.gotoWallC->setChecked(false); + }); + if (calibrationDialog.exec() == QDialog::Accepted) { - if (calibrationOptions.manualSourceC->isChecked()) - state()->setFlatFieldSource(SOURCE_MANUAL); - else if (calibrationOptions.flatDeviceSourceC->isChecked()) - state()->setFlatFieldSource(SOURCE_FLATCAP); - else if (calibrationOptions.darkDeviceSourceC->isChecked()) - state()->setFlatFieldSource(SOURCE_DARKCAP); - else if (calibrationOptions.wallSourceC->isChecked()) + state()->setCalibrationPreAction(ACTION_NONE); + if (calibrationOptions.parkMountC->isChecked()) + state()->setCalibrationPreAction(state()->calibrationPreAction() | ACTION_PARK_MOUNT); + if (calibrationOptions.parkDomeC->isChecked()) + state()->setCalibrationPreAction(state()->calibrationPreAction() | ACTION_PARK_DOME); + if (calibrationOptions.gotoWallC->isChecked()) { dms wallAz, wallAlt; bool azOk = false, altOk = false; @@ -2431,18 +2435,16 @@ if (azOk && altOk) { - state()->setFlatFieldSource(SOURCE_WALL); + state()->setCalibrationPreAction((state()->calibrationPreAction() & ~ACTION_PARK_MOUNT) | ACTION_WALL); state()->wallCoord().setAz(wallAz); state()->wallCoord().setAlt(wallAlt); } else { - calibrationOptions.manualSourceC->setChecked(true); + calibrationOptions.gotoWallC->setChecked(false); KSNotification::error(i18n("Wall coordinates are invalid.")); } } - else - state()->setFlatFieldSource(SOURCE_DAWN_DUSK); if (calibrationOptions.manualDurationC->isChecked()) state()->setFlatFieldDuration(DURATION_MANUAL); @@ -2453,12 +2455,9 @@ state()->setTargetADUTolerance(calibrationOptions.ADUTolerance->value()); } - state()->setPreMountPark(calibrationOptions.parkMountC->isChecked()); - state()->setPreDomePark(calibrationOptions.parkDomeC->isChecked()); - state()->setDirty(true); - Options::setCalibrationFlatSourceIndex(state()->flatFieldSource()); + Options::setCalibrationPreActionIndex(state()->calibrationPreAction()); Options::setCalibrationFlatDurationIndex(state()->flatFieldDuration()); Options::setCalibrationWallAz(state()->wallCoord().az().Degrees()); Options::setCalibrationWallAlt(state()->wallCoord().alt().Degrees()); @@ -3259,13 +3258,10 @@ job->setCoreProperty(SequenceJob::SJ_Encoding, captureEncodingS->currentText()); if (captureISOS) - job->setCoreProperty(SequenceJob::SJ_ISOIndex, captureISOS->currentIndex()); - - if (getGain() >= 0) - job->setCoreProperty(SequenceJob::SJ_Gain, getGain()); + job->setISO(captureISOS->currentIndex()); - if (getOffset() >= 0) - job->setCoreProperty(SequenceJob::SJ_Offset, getOffset()); + job->setCoreProperty(SequenceJob::SJ_Gain, getGain()); + job->setCoreProperty(SequenceJob::SJ_Offset, getOffset()); if (cameraTemperatureN->isEnabled()) { @@ -3276,9 +3272,7 @@ job->setUploadMode(static_cast(fileUploadModeS->currentIndex())); job->setScripts(state()->scripts()); job->setFlatFieldDuration(state()->flatFieldDuration()); - job->setFlatFieldSource(state()->flatFieldSource()); - job->setPreMountPark(state()->preMountPark()); - job->setPreDomePark(state()->preDomePark()); + job->setCalibrationPreAction(state()->calibrationPreAction()); job->setWallCoord(state()->wallCoord()); job->setCoreProperty(SequenceJob::SJ_TargetADU, state()->targetADU()); job->setCoreProperty(SequenceJob::SJ_TargetADUTolerance, state()->targetADUTolerance()); @@ -3307,19 +3301,19 @@ captureFrameHN->value())); job->setCoreProperty(SequenceJob::SJ_RemoteDirectory, fileRemoteDirT->text()); job->setCoreProperty(SequenceJob::SJ_LocalDirectory, fileDirectoryT->text()); + job->setCoreProperty(SequenceJob::SJ_TargetName, targetNameT->text()); job->setCoreProperty(SequenceJob::SJ_PlaceholderFormat, placeholderFormatT->text()); job->setCoreProperty(SequenceJob::SJ_PlaceholderSuffix, formatSuffixN->value()); auto placeholderPath = PlaceholderPath(); - placeholderPath.addJob(job, state()->targetName()); + placeholderPath.addJob(job, placeholderFormatT->text()); - QString signature = placeholderPath.generateSequenceFilename(*job, state()->targetName(), + QString signature = placeholderPath.generateSequenceFilename(*job, filenamePreview != REMOTE_PREVIEW, true, 1, ".fits", "", false, true); job->setCoreProperty(SequenceJob::SJ_Signature, signature); auto remoteUpload = placeholderPath.generateSequenceFilename(*job, - state()->targetName(), false, true, 1, @@ -3497,7 +3491,7 @@ extension = ".xisf"; else extension = ".[NATIVE]"; - previewText = m_placeholderPath.generateSequenceFilename(*m_job, targetNameT->text(), previewType == LOCAL_PREVIEW, true, 1, + previewText = m_placeholderPath.generateSequenceFilename(*m_job, previewType == LOCAL_PREVIEW, true, 1, extension, "", false); previewText = QDir::toNativeSeparators(previewText); // we do not use it any more @@ -3539,4 +3533,97 @@ anExposureCalculatorDialog->show(); } +bool Capture::hasCoolerControl() +{ + return process()->hasCoolerControl(); +} + +bool Capture::setCoolerControl(bool enable) +{ + return process()->setCoolerControl(enable); +} + +void Capture::removeDevice(const QSharedPointer &device) +{ + process()->removeDevice(device); +} + +void Capture::start() +{ + process()->startNextPendingJob(); +} + +void Capture::stop(CaptureState targetState) +{ + process()->stopCapturing(targetState); +} + +void Capture::toggleVideo(bool enabled) +{ + process()->toggleVideo(enabled); +} + +void Capture::setTargetName(const QString &newTargetName) +{ + // target is changed only if no job is running + if (activeJob() == nullptr) + { + // set the target name in the currently selected job + targetNameT->setText(newTargetName); + auto rows = queueTable->selectionModel()->selectedRows(); + if(rows.count() > 0) + { + // take the first one, since we are in single selection mode + int pos = rows.constFirst().row(); + + if (state()->allJobs().size() > pos) + state()->allJobs().at(pos)->setCoreProperty(SequenceJob::SJ_TargetName, newTargetName); + } + + emit captureTarget(newTargetName); + } +} + +QString Capture::getTargetName() +{ + if (activeJob()) + return activeJob()->getCoreProperty(SequenceJob::SJ_TargetName).toString(); + else + return ""; +} + +void Capture::restartCamera(const QString &name) +{ + process()->restartCamera(name); +} + +void Capture::capturePreview() +{ + process()->capturePreview(); +} + +void Capture::startFraming() +{ + process()->capturePreview(true); +} + +double Capture::getGain() +{ + return devices()->cameraGain(customPropertiesDialog->getCustomProperties()); +} + +double Capture::getOffset() +{ + return devices()->cameraOffset(customPropertiesDialog->getCustomProperties()); +} + +void Capture::setHFR(double newHFR, int) +{ + state()->getRefocusState()->setFocusHFR(newHFR); +} + +ISD::Camera *Capture::activeCamera() +{ + return m_captureDeviceAdaptor->getActiveCamera(); +} } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,23 +7,16 @@ #pragma once #include "ui_capture.h" -#include "captureprocess.h" -#include "capturemodulestate.h" -#include "capturedeviceadaptor.h" + #include "sequencejob.h" -// #include "ekos/manager.h" #include "ekos/manager/meridianflipstate.h" #include "customproperties.h" #include "ekos/ekos.h" -#include "ekos/mount/mount.h" #include "indi/indicamera.h" #include "indi/indidustcap.h" #include "indi/indidome.h" #include "indi/indilightbox.h" #include "indi/indimount.h" -#include "ekos/auxiliary/darkprocessor.h" -#include "ekos/auxiliary/rotatorutils.h" -#include "dslrinfodialog.h" #include "ui_limits.h" #include @@ -32,6 +25,7 @@ #include +class DSLRInfo; class QProgressIndicator; class QTableWidgetItem; class KDirWatch; @@ -71,7 +65,9 @@ namespace Ekos { -class SequenceJob; +class CaptureDeviceAdaptor; +class CaptureModuleState; +class CaptureProcess; /** *@class Capture @@ -162,9 +158,9 @@ /** DBUS interface function. * Loads the Ekos Sequence Queue file in the Sequence Queue. Jobs are appended to existing jobs. * @param fileURL full URL of the filename - * @param ignoreTarget ignore target defined in the sequence queue file (necessary for using the target of the scheduler) + * @param targetName override the target in the sequence queue file (necessary for using the target of the scheduler) */ - Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, bool ignoreTarget = false); + Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, QString targetName = ""); /** DBUS interface function. * Saves the Sequence Queue to the Ekos Sequence Queue file. @@ -189,19 +185,13 @@ /** DBUS interface function. * Does the CCD has a cooler control (On/Off) ? */ - Q_SCRIPTABLE bool hasCoolerControl() - { - return process()->hasCoolerControl(); - } + Q_SCRIPTABLE bool hasCoolerControl(); /** DBUS interface function. * Set the CCD cooler ON/OFF * */ - Q_SCRIPTABLE bool setCoolerControl(bool enable) - { - return process()->setCoolerControl(enable); - } + Q_SCRIPTABLE bool setCoolerControl(bool enable); /** DBUS interface function. * @return Returns the percentage of completed captures in all active jobs @@ -387,12 +377,16 @@ void setRotator(QString name); /** + * @brief setDome Set dome device + * @param device pointer to dome device + * @return true if successfull, false otherewise. + */ + bool setDome(ISD::Dome *device); + + /** * @brief Generic method for removing any connected device. */ - void removeDevice(const QSharedPointer &device) - { - process()->removeDevice(device); - } + void removeDevice(const QSharedPointer &device); /** * @brief registerNewModule Register an Ekos module as it arrives via DBus @@ -564,10 +558,7 @@ * If no, the user is asked whether the jobs should be reset. If the user declines, * starting is aborted. */ - Q_SCRIPTABLE Q_NOREPLY void start() - { - process()->startNextPendingJob(); - } + Q_SCRIPTABLE Q_NOREPLY void start(); /** DBUS interface function. * Stops currently running jobs: @@ -578,10 +569,7 @@ * CAPTURE_SUSPEND: capture suspended and waiting to be restarted * @param targetState status of the job after stop */ - Q_SCRIPTABLE Q_NOREPLY void stop(CaptureState targetState = CAPTURE_IDLE) - { - process()->stopCapturing(targetState); - }; + Q_SCRIPTABLE Q_NOREPLY void stop(CaptureState targetState = CAPTURE_IDLE); /** DBUS interface function. * Aborts all jobs and mark current state as ABORTED. It simply calls stop(CAPTURE_ABORTED) @@ -620,10 +608,7 @@ * Toggle video streaming if supported by the device. * @param enabled Set to true to start video streaming, false to stop it if active. */ - Q_SCRIPTABLE Q_NOREPLY void toggleVideo(bool enabled) - { - process()->toggleVideo(enabled); - }; + Q_SCRIPTABLE Q_NOREPLY void toggleVideo(bool enabled); /** DBus interface function @@ -631,22 +616,14 @@ * @param name Name of camera to restart. If a driver defined multiple cameras, they would be removed and added again * after driver restart. */ - Q_SCRIPTABLE Q_NOREPLY void restartCamera(const QString &name) - { - process()->restartCamera(name); - }; + Q_SCRIPTABLE Q_NOREPLY void restartCamera(const QString &name); /** DBus interface function * @brief Set the name of the target to be captured. */ - Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &newTargetName) - { - state()->setTargetName(newTargetName); - }; - Q_SCRIPTABLE QString getTargetName() - { - return state()->targetName(); - } + Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &newTargetName); + + Q_SCRIPTABLE QString getTargetName(); /** DBus interface function * @brief Set the observer name. @@ -682,18 +659,12 @@ /** * @brief capturePreview Capture a single preview image */ - void capturePreview() - { - process()->capturePreview(); - } + void capturePreview(); /** * @brief startFraming Like captureOne but repeating. */ - void startFraming() - { - process()->capturePreview(true); - } + void startFraming(); /** * @brief generateDarkFlats Generate a list of dark flat jobs from available flat frames. @@ -883,10 +854,7 @@ /** * @brief setHFR Receive the measured HFR value of the latest frame */ - void setHFR(double newHFR, int) - { - state()->getRefocusState()->setFocusHFR(newHFR); - } + void setHFR(double newHFR, int); // Filter void setFilterStatus(FilterState filterState); @@ -982,6 +950,7 @@ void adaptiveFocus(); void suspendGuiding(); void resumeGuiding(); + void captureTarget(QString targetName); void newImage(SequenceJob *job, const QSharedPointer &data); void newExposureProgress(SequenceJob *job); void newDownloadProgress(double); @@ -1085,10 +1054,7 @@ return state()->getActiveJob(); } // Shortcut to the active camera held in the device adaptor - ISD::Camera *activeCamera() - { - return m_captureDeviceAdaptor->getActiveCamera(); - } + ISD::Camera *activeCamera(); // Filename preview void generatePreviewFilename(); @@ -1181,16 +1147,10 @@ // This sets and gets the custom properties target gain // it does not access the ccd gain property void setGain(double value); - double getGain() - { - return process()->getGain(customPropertiesDialog->getCustomProperties()); - } + double getGain(); void setOffset(double value); - double getOffset() - { - return process()->getOffset(customPropertiesDialog->getCustomProperties()); - } + double getOffset(); /** * @brief processCCDNumber Process number properties arriving from CCD. Currently, only CCD and Guider frames are processed. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capture.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capture.ui 2023-12-03 05:23:17.000000000 +0000 @@ -1091,7 +1091,7 @@ - <html><head/><body><p>Format is used to define the image file names by the use of placeholder tags.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %f</span> or <span style=" font-weight:704;">%filename</span>: The name of the .esq file, without extension.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %D</span> or <span style=" font-weight:704;">%Datetime</span>: The current time and date <span style=" font-weight:704;">when the file is saved.</span></li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %T</span> or <span style=" font-weight:704;">%Type</span>: The frame type eg: 'Light', 'Bias', 'Dark', 'Flat'...</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %e</span> or <span style=" font-weight:704;">%exposure</span>: The exposure duration in seconds.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %F</span> or <span style=" font-weight:704;">%Filter</span>: The active filter name.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %t</span> or <span style=" font-weight:704;">%target</span>: The Target name.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%C</span> or <span style=" font-weight:600;">%temperature</span>: The camera temperature of capturing.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%G</span> or <span style=" font-weight:600;">%gain</span>: The gain configured for capturing.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%O</span> or <span style=" font-weight:600;">%offset</span>: The offset configured for capturing.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%P</span> or <span style=" font-weight:600;">%pierside</span>: The current mount's pier side.</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %s*</span> or <span style=" font-weight:704;">%sequence</span>: The image sequence identifier where * is the number of digits used (1-9). <span style=" font-weight:704;">This tag is mandatory and must be the last element in the format.</span></li></ul><p>Arbitrary text may also be included within the Format string, <span style=" font-weight:704;">except the % and \ characters.</span> The / path character can be used to define arbitrary directories.</p><p>Notes:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tags are case sensitive in both their short and long forms.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Only use the %Datetime tag in the filename portion of the format, not in the path definition.</li></ul></body></html> + <html><head/><body><p>Format is used to define the image file names by the use of placeholder tags.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %f</span> or <span style=" font-weight:704;">%filename</span>: The name of the .esq file, without extension.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %D</span> or <span style=" font-weight:704;">%Datetime</span>: The current time and date <span style=" font-weight:704;">when the file is saved.</span></li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %T</span> or <span style=" font-weight:704;">%Type</span>: The frame type eg: 'Light', 'Bias', 'Dark', 'Flat'...</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %e</span> or <span style=" font-weight:704;">%exposure</span>: The exposure duration in seconds, with '_secs' as suffix.</li><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %E</span> or <span style=" font-weight:704;">%exp</span>: The exposure duration in seconds as plain number, without any unit as suffix.</li></ul><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %F</span> or <span style=" font-weight:704;">%Filter</span>: The active filter name.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %t</span> or <span style=" font-weight:704;">%target</span>: The Target name.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%C</span> or <span style=" font-weight:600;">%temperature</span>: The camera temperature of capturing.</li><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%B</span> or <span style=" font-weight:600;">%bin</span>: The binning configured for capturing.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%G</span> or <span style=" font-weight:600;">%gain</span>: The gain configured for capturing.</li></ul><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%O</span> or <span style=" font-weight:600;">%offset</span>: The offset configured for capturing.</li><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%I</span> or <span style=" font-weight:600;">%iso</span>: The ISO value (DSLRs only).</li></ul><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder <span style=" font-weight:600;">%P</span> or <span style=" font-weight:600;">%pierside</span>: The current mount's pier side.</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Placeholder<span style=" font-weight:704;"> %s*</span> or <span style=" font-weight:704;">%sequence</span>: The image sequence identifier where * is the number of digits used (1-9). <span style=" font-weight:704;">This tag is mandatory and must be the last element in the format.</span></li></ul><p>Arbitrary text may also be included within the Format string, <span style=" font-weight:704;">except the % and \ characters.</span> The / path character can be used to define arbitrary directories.</p><p>Notes:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tags are case sensitive in both their short and long forms.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Only use the %Datetime tag in the filename portion of the format, not in the path definition.</li></ul></body></html> Format: diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -7,8 +7,10 @@ #include "capturecountswidget.h" #include "Options.h" -#include "ekos/ekos.h" #include "ekos/manager.h" +#include "ekos/scheduler/scheduler.h" +#include "ekos/capture/capture.h" +#include "ekos/capture/sequencejob.h" using Ekos::SequenceJob; @@ -78,8 +80,8 @@ sequenceCountDown.setHMS(0, 0, 0); // do not change overall remaining time if scheduler is in endless loop - if (schedulerProcess == nullptr || schedulerProcess->getCurrentJob() == nullptr || - schedulerProcess->getCurrentJob()->getCompletionCondition() != SchedulerJob::FINISH_LOOP) + if (schedulerProcess == nullptr || schedulerProcess->activeJob() == nullptr || + schedulerProcess->activeJob()->getCompletionCondition() != Ekos::FINISH_LOOP) { overallRemainingTime->setText(overallCountDown.toString("hh:mm:ss")); gr_overallRemainingTime->setText(overallRemainingTime->text()); @@ -184,17 +186,17 @@ } - if (schedulerProcess != nullptr && schedulerProcess->getCurrentJob() != nullptr) + if (schedulerProcess != nullptr && schedulerProcess->activeJob() != nullptr) { total_label = schedulerProcess->getCurrentJobName(); // FIXME: accessing the completed count might be one too low due to concurrency of updating the count and this loop - total_completed = schedulerProcess->getCurrentJob()->getCompletedCount(); - total_count = schedulerProcess->getCurrentJob()->getSequenceCount(); - infinite_loop = (schedulerProcess->getCurrentJob()->getCompletionCondition() == SchedulerJob::FINISH_LOOP); + total_completed = schedulerProcess->activeJob()->getCompletedCount(); + total_count = schedulerProcess->activeJob()->getSequenceCount(); + infinite_loop = (schedulerProcess->activeJob()->getCompletionCondition() == Ekos::FINISH_LOOP); if (total_count > 0) total_percentage = (100 * total_completed) / total_count; - if (schedulerProcess->getCurrentJob()->getEstimatedTime() > 0) - total_remaining_time = int(schedulerProcess->getCurrentJob()->getEstimatedTime()); + if (schedulerProcess->activeJob()->getEstimatedTime() > 0) + total_remaining_time = int(schedulerProcess->activeJob()->getEstimatedTime()); } else { @@ -233,7 +235,7 @@ gr_overallLabel->setText(overallLabel->text()); // update job remaining time if run from the scheduler - bool show_job_progress = (schedulerProcess != nullptr && schedulerProcess->getCurrentJob() != nullptr); + bool show_job_progress = (schedulerProcess != nullptr && schedulerProcess->activeJob() != nullptr); jobLabel->setVisible(show_job_progress); jobRemainingTime->setVisible(show_job_progress); if (show_job_progress) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturecountswidget.h 2023-12-03 05:23:17.000000000 +0000 @@ -12,9 +12,14 @@ #include #include "ui_capturecountswidget.h" -#include "ekos/scheduler/scheduler.h" -#include "ekos/capture/capture.h" -#include "ekos/capture/sequencejob.h" +#include "ekos/ekos.h" + +namespace Ekos +{ +class Capture; +class SequenceJob; +class Scheduler; +} class CaptureCountsWidget : public QWidget, public Ui::CaptureCountsWidget { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -10,6 +10,14 @@ #include "Options.h" #include "indi/indistd.h" #include "ekos_capture_debug.h" +#include "sequencejobstate.h" + +#include "indi/indicamera.h" +#include "indi/indidustcap.h" +#include "indi/indidome.h" +#include "indi/indilightbox.h" +#include "indi/indimount.h" +#include "indi/indirotator.h" namespace Ekos { @@ -123,6 +131,10 @@ connect(device, &ISD::Mount::pierSideChanged, this, &CaptureDeviceAdaptor::pierSideChanged); connect(device, &ISD::Mount::newParkStatus, this, &CaptureDeviceAdaptor::scopeParkStatusChanged); connectMount(currentSequenceJobState.data()); + + // update mount states + emit pierSideChanged(device->pierSide()); + emit scopeParkStatusChanged(device->parkStatus()); } m_ActiveMount = device; @@ -443,6 +455,77 @@ m_ActiveChip->abortExposure(); } +double CaptureDeviceAdaptor::cameraGain(QMap > propertyMap) +{ + if (getActiveCamera()) + { + // derive attributes from active camera + if (getActiveCamera()->getProperty("CCD_GAIN")) + return propertyMap["CCD_GAIN"].value("GAIN", -1).toDouble(); + else if (getActiveCamera()->getProperty("CCD_CONTROLS")) + return propertyMap["CCD_CONTROLS"].value("Gain", -1).toDouble(); + } + else // no active camera set, e.g. whien used from the scheduler + { + // if camera is unknown, use the custom property that is set + if (propertyMap.keys().contains("CCD_GAIN")) + return propertyMap["CCD_GAIN"].value("GAIN", -1).toDouble(); + else if(propertyMap.keys().contains("CCD_CONTROLS")) + return propertyMap["CCD_CONTROLS"].value("Gain", -1).toDouble(); + } + + // none found + return -1; + +} + +double CaptureDeviceAdaptor::cameraGain() +{ + double value = -1; + if (getActiveCamera() != nullptr) + getActiveCamera()->getGain(&value); + + return value; +} + +double CaptureDeviceAdaptor::cameraOffset(QMap > propertyMap) +{ + if (getActiveCamera()) + { + if (getActiveCamera()->getProperty("CCD_OFFSET")) + return propertyMap["CCD_OFFSET"].value("OFFSET", -1).toDouble(); + else if (getActiveCamera()->getProperty("CCD_CONTROLS")) + return propertyMap["CCD_CONTROLS"].value("Offset", -1).toDouble(); + } + else + { + // if camera is unknown, use the custom property that is set + if (propertyMap.keys().contains("CCD_OFFSET")) + return propertyMap["CCD_OFFSET"].value("OFFSET", -1).toDouble(); + else if(propertyMap.keys().contains("CCD_CONTROLS")) + return propertyMap["CCD_CONTROLS"].value("Offset", -1).toDouble(); + } + return -1; +} + +double CaptureDeviceAdaptor::cameraOffset() +{ + double value = -1; + if (getActiveCamera() != nullptr) + getActiveCamera()->getOffset(&value); + + return value; +} + +double CaptureDeviceAdaptor::cameraTemperature() +{ + double value = -1; + if (getActiveCamera() != nullptr) + getActiveCamera()->getTemperature(&value); + + return value; +} + void CaptureDeviceAdaptor::setFilterPosition(int targetFilterPosition, FilterManager::FilterPolicy policy) { if (m_FilterManager.isNull() == false && m_ActiveFilterWheel != nullptr) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturedeviceadaptor.h 2023-12-03 05:23:17.000000000 +0000 @@ -10,18 +10,25 @@ #include "ekos/ekos.h" #include "indi/indicommon.h" #include "indiapi.h" -#include "indi/indicamera.h" -#include "indi/indidustcap.h" + #include "indi/indidome.h" -#include "indi/indilightbox.h" +#include "indi/indicamerachip.h" +#include "indi/indidustcap.h" #include "indi/indimount.h" -#include "indi/indirotator.h" + #include "ekos/auxiliary/filtermanager.h" -#include "sequencejobstate.h" +namespace { +class Camera; +class LightBox; +class Rotator; +} namespace Ekos { + +class SequenceJobState; + class CaptureDeviceAdaptor: public QObject { Q_OBJECT @@ -165,6 +172,34 @@ */ void abortFastExposure(); + /** + * @brief getGain Retrieve the gain value from the custom property value. Depending + * on the camera, it is either stored as GAIN property value of CCD_GAIN or as + * Gain property value from CCD_CONTROLS. + */ + double cameraGain(QMap > propertyMap); + + /** + * @brief cameraGain Retrieve the gain value from the active camera + */ + double cameraGain(); + + /** + * @brief getOffset Retrieve the offset value from the custom property value. Depending + * on the camera, it is either stored as OFFSET property value of CCD_OFFSET or as + * Offset property value from CCD_CONTROLS. + */ + double cameraOffset(QMap > propertyMap); + /** + * @brief cameraOffset Retrieve the offset value from the active camera + */ + double cameraOffset(); + + /** + * @brief cameraTemperature Retrieve the current chip temperature from the active camera + */ + double cameraTemperature(); + ////////////////////////////////////////////////////////////////////// // Filter wheel commands ////////////////////////////////////////////////////////////////////// diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -7,6 +7,8 @@ #include "capturemodulestate.h" #include "ekos/manager/meridianflipstate.h" #include "ekos/capture/sequencejob.h" +#include "ekos/capture/refocusstate.h" +#include "fitsviewer/fitsdata.h" #include "ksnotification.h" #include @@ -24,7 +26,7 @@ getGuideDeviationTimer().setInterval(GD_TIMER_TIMEOUT); connect(&m_guideDeviationTimer, &QTimer::timeout, this, &CaptureModuleState::checkGuideDeviationTimeout); - setFlatFieldSource(static_cast(Options::calibrationFlatSourceIndex())); + setCalibrationPreAction(Options::calibrationPreActionIndex()); setFlatFieldDuration(static_cast(Options::calibrationFlatDurationIndex())); wallCoord().setAz(Options::calibrationWallAz()); wallCoord().setAlt(Options::calibrationWallAlt()); @@ -157,7 +159,8 @@ // Only emit status if it changed if (m_CaptureState != value) { - qCDebug(KSTARS_EKOS_CAPTURE()) << "Capture State changes from" << getCaptureStatusString(m_CaptureState) << "to" << getCaptureStatusString(value); + qCDebug(KSTARS_EKOS_CAPTURE()) << "Capture State changes from" << getCaptureStatusString( + m_CaptureState) << "to" << getCaptureStatusString(value); m_CaptureState = value; getMeridianFlipState()->setCaptureState(m_CaptureState); emit newStatus(m_CaptureState); @@ -287,15 +290,6 @@ Qt::UniqueConnection); } -void CaptureModuleState::setTargetName(const QString &value) -{ - if (isCaptureRunning() == false) - { - m_TargetName = value; - emit newTargetName(value); - } -} - void CaptureModuleState::setObserverName(const QString &value) { m_ObserverName = value; @@ -458,7 +452,7 @@ // If active job is taking flat field image at a wall source // then do not flip. - if (m_activeJob && m_activeJob->getFrameType() == FRAME_FLAT && m_activeJob->getFlatFieldSource() == SOURCE_WALL) + if (m_activeJob && m_activeJob->getFrameType() == FRAME_FLAT && m_activeJob->getCalibrationPreAction() & ACTION_WALL) return false; if (getMeridianFlipState()->getMeridianFlipStage() != MeridianFlipState::MF_REQUESTED) @@ -581,6 +575,8 @@ void CaptureModuleState::updateAdaptiveFocusState(bool success) { + m_refocusState->setAdaptiveFocusDone(true); + // Always process the adaptive focus state change, incl if a MF has also just started if (success) qCDebug(KSTARS_EKOS_CAPTURE) << "Adaptive focus completed successfully"; @@ -1166,14 +1162,12 @@ { QJsonObject settings = { - {"source", flatFieldSource()}, + {"preAction", static_cast(calibrationPreAction())}, {"duration", flatFieldDuration()}, {"az", wallCoord().az().Degrees()}, {"al", wallCoord().alt().Degrees()}, {"adu", targetADU()}, {"tolerance", targetADUTolerance()}, - {"parkMount", preMountPark()}, - {"parkDome", preDomePark()}, }; return settings; @@ -1181,23 +1175,19 @@ void CaptureModuleState::setCalibrationSettings(const QJsonObject &settings) { - const int source = settings["source"].toInt(flatFieldSource()); + const int preAction = settings["preAction"].toInt(calibrationPreAction()); const int duration = settings["duration"].toInt(flatFieldDuration()); const double az = settings["az"].toDouble(wallCoord().az().Degrees()); const double al = settings["al"].toDouble(wallCoord().alt().Degrees()); const int adu = settings["adu"].toInt(static_cast(std::round(targetADU()))); const int tolerance = settings["tolerance"].toInt(static_cast(std::round(targetADUTolerance()))); - const bool parkMount = settings["parkMount"].toBool(preMountPark()); - const bool parkDome = settings["parkDome"].toBool(preDomePark()); - setFlatFieldSource(static_cast(source)); + setCalibrationPreAction(static_cast(preAction)); setFlatFieldDuration(static_cast(duration)); wallCoord().setAz(az); wallCoord().setAlt(al); setTargetADU(adu); setTargetADUTolerance(tolerance); - setPreMountPark(parkMount); - setPreDomePark(parkDome); } bool CaptureModuleState::setDarkFlatExposure(SequenceJob *job) @@ -1245,7 +1235,7 @@ return; auto placeholderPath = PlaceholderPath(sequenceURL.toLocalFile()); - setNextSequenceID(placeholderPath.checkSeqBoundary(*getActiveJob(), targetName())); + setNextSequenceID(placeholderPath.checkSeqBoundary(*getActiveJob())); } bool CaptureModuleState::isModelinDSLRInfo(const QString &model) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturemodulestate.h 2023-12-03 05:23:17.000000000 +0000 @@ -19,19 +19,20 @@ #include "indi/indidome.h" #include "ekos/manager/meridianflipstate.h" -#include "ekos/capture/refocusstate.h" #include "ekos/auxiliary/filtermanager.h" #include "ekos/scheduler/schedulerjob.h" -#include "fitsviewer/fitsdata.h" // Wait 3-minutes as maximum beyond exposure // value. #define CAPTURE_TIMEOUT_THRESHOLD 180000 +class FITSData; + namespace Ekos { class SequenceJob; +class RefocusState; class CaptureModuleState: public QObject { @@ -43,7 +44,6 @@ ACTION_FILTER, /* Change the filter and wait until the correct filter is set. */ ACTION_TEMPERATURE, /* Set the camera chip target temperature and wait until the target temperature has been reached. */ ACTION_ROTATOR, /* Set the camera rotator target angle and wait until the target angle has been reached. */ - ACTION_GUIDER_DRIFT, /* Wait until the guiding deviation is below the configured threshold. */ ACTION_PREPARE_LIGHTSOURCE, /* Setup the selected flat lights source. */ ACTION_MOUNT_PARK, /* Park the mount. */ ACTION_DOME_PARK, /* Park the dome. */ @@ -328,24 +328,6 @@ m_lightBoxLightEnabled = value; } - bool preMountPark() const - { - return m_preMountPark; - } - void setPreMountPark(bool value) - { - m_preMountPark = value; - } - - bool preDomePark() const - { - return m_preDomePark; - } - void setPreDomePark(bool value) - { - m_preDomePark = value; - } - CapState getDustCapState() const { return m_dustCapState; @@ -399,12 +381,6 @@ return m_refocusState; } - const QString &targetName() const - { - return m_TargetName; - } - void setTargetName(const QString &value); - const QString &observerName() const { return m_ObserverName; @@ -946,13 +922,13 @@ m_flatFieldDuration = value; } - FlatFieldSource flatFieldSource() const + uint32_t calibrationPreAction() const { - return m_flatFieldSource; + return m_CalibrationPreAction; } - void setFlatFieldSource(FlatFieldSource value) + void setCalibrationPreAction(uint32_t value) { - m_flatFieldSource = value; + m_CalibrationPreAction = value; } QList > &DSLRInfos() @@ -977,8 +953,6 @@ void executeActiveJob(); void updatePrepareState(CaptureState state); void captureStarted(CAPTUREResult rc); - // new target to be captured - void newTargetName(QString name); // mount meridian flip status update event void newMeridianFlipStage(MeridianFlipState::MFStage status); // meridian flip started @@ -1079,8 +1053,6 @@ int m_nextSequenceID { 0 }; // how to continue after pausing ContinueAction m_ContinueAction { CONTINUE_ACTION_NONE }; - // name of the capture target - QString m_TargetName; // name of the observer QString m_ObserverName; // ignore already captured files @@ -1099,10 +1071,8 @@ double m_TargetADUTolerance { 1000 }; double m_targetADU { 0 }; SkyPoint m_wallCoord; - bool m_preMountPark { false }; - bool m_preDomePark { false }; FlatFieldDuration m_flatFieldDuration { DURATION_MANUAL }; - FlatFieldSource m_flatFieldSource { SOURCE_MANUAL }; + uint32_t m_CalibrationPreAction { ACTION_NONE }; bool m_lightBoxLightEnabled { false }; // Allowed camera exposure times DoubleRange m_ExposureRange; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -10,7 +10,13 @@ #include #include "ksutils.h" #include "ksmessagebox.h" +#include "ekos/mount/mount.h" #include "Options.h" +#include "capture.h" +#include "sequencejob.h" +#include "fitsviewer/fitsdata.h" +#include "fitsviewer/summaryfitsview.h" +#include "ekos/scheduler/scheduler.h" using Ekos::SequenceJob; @@ -37,6 +43,7 @@ &CaptureCountsWidget::updateDownloadProgress); connect(captureModule, &Ekos::Capture::newExposureProgress, captureCountsWidget, &CaptureCountsWidget::updateExposureProgress); + connect(captureModule, &Ekos::Capture::captureTarget, this, &CapturePreviewWidget::setTargetName); } } @@ -49,10 +56,7 @@ void CapturePreviewWidget::shareMountModule(Ekos::Mount *module) { mountModule = module; - connect(mountModule, &Ekos::Mount::newTargetName, this, [this](const QString & name) - { - m_mountTarget = name; - }); + connect(mountModule, &Ekos::Mount::newTargetName, this, &CapturePreviewWidget::setTargetName); } void CapturePreviewWidget::updateJobProgress(Ekos::SequenceJob *job, const QSharedPointer &data) @@ -68,8 +72,8 @@ m_currentFrame.frameType = job->getFrameType(); if (job->getFrameType() == FRAME_LIGHT) { - if (schedulerModule != nullptr && schedulerModule->getCurrentJob() != nullptr) - m_currentFrame.target = schedulerModule->getCurrentJob()->getName(); + if (schedulerModule != nullptr && schedulerModule->activeJob() != nullptr) + m_currentFrame.target = schedulerModule->activeJob()->getName(); else m_currentFrame.target = m_mountTarget; } @@ -256,3 +260,13 @@ // forward to sub widget captureCountsWidget->updateCaptureCountDown(delta); } + +void CapturePreviewWidget::setTargetName(QString name) +{ + targetLabel->setVisible(!name.isEmpty()); + mountTarget->setVisible(!name.isEmpty()); + mountTarget->setText(name); + m_mountTarget = name; + m_currentFrame.target = name; +} + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/capturepreviewwidget.h 2023-12-03 05:23:17.000000000 +0000 @@ -10,15 +10,20 @@ #include "ui_capturepreviewwidget.h" #include "captureprocessoverlay.h" -#include "capture.h" -#include "sequencejob.h" -#include "fitsviewer/fitsdata.h" -#include "fitsviewer/summaryfitsview.h" -#include "ekos/scheduler/scheduler.h" - #include #include +class FITSData; +class SummaryFITSView; + +namespace Ekos +{ +class Capture; +class Mount; +class Scheduler; +class SequenceJob; +} + class CapturePreviewWidget : public QWidget, public Ui::CapturePreviewWidget { Q_OBJECT @@ -65,7 +70,10 @@ */ void reset(); -signals: + /** + * @brief set the target name + */ + void setTargetName(QString name); public slots: /** @@ -104,5 +112,4 @@ // move to trash or delete finally bool m_permanentlyDelete {false}; - }; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocess.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocess.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocess.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocess.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -4,13 +4,19 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #include "captureprocess.h" +#include "capturedeviceadaptor.h" +#include "refocusstate.h" #include "sequencejob.h" #include "ekos/manager.h" #include "ekos/auxiliary/darklibrary.h" +#include "ekos/auxiliary/darkprocessor.h" #include "ekos/auxiliary/opticaltrainmanager.h" #include "ekos/auxiliary/profilesettings.h" #include "ekos/guide/guide.h" #include "indi/indilistener.h" +#include "indi/indirotator.h" +#include "indi/blobmanager.h" +#include "indi/indilightbox.h" #include "ksmessagebox.h" #include "ksnotification.h" @@ -21,7 +27,7 @@ #endif // Current Sequence File Format: -#define SQ_FORMAT_VERSION 2.5 +#define SQ_FORMAT_VERSION 2.6 // We accept file formats with version back to: #define SQ_COMPAT_VERSION 2.0 @@ -86,7 +92,7 @@ return false; devices()->mount()->disconnect(this); - connect(devices()->mount(), &ISD::Mount::newTargetName, state().data(), &CaptureModuleState::setTargetName); + connect(devices()->mount(), &ISD::Mount::newTargetName, this, &CaptureProcess::captureTarget); updateTelescopeInfo(); return true; @@ -143,6 +149,16 @@ return true; } +bool CaptureProcess::setDome(ISD::Dome *device) +{ + if (devices()->dome() == device) + return false; + + devices()->setDome(device); + + return true; +} + bool CaptureProcess::setCamera(ISD::Camera *device) { if (devices()->getActiveCamera() == device) @@ -632,8 +648,10 @@ QList FITSHeaders; if (Options::defaultObserver().isEmpty() == false) FITSHeaders.append(FITSData::Record("Observer", Options::defaultObserver(), "Observer")); - if (state()->targetName().isEmpty() == false) - FITSHeaders.append(FITSData::Record("Object", state()->targetName(), "Object")); + if (activeJob()->getCoreProperty(SequenceJob::SJ_TargetName) != "") + FITSHeaders.append(FITSData::Record("Object", activeJob()->getCoreProperty(SequenceJob::SJ_TargetName).toString(), + "Object")); + FITSHeaders.append(FITSData::Record("TELESCOP", m_Scope, "Telescope")); if (!FITSHeaders.isEmpty()) activeCamera()->setFITSHeaders(FITSHeaders); @@ -656,7 +674,7 @@ { auto placeholderPath = PlaceholderPath(); // Make sure to update Full Prefix as exposure value was changed - placeholderPath.processJobInfo(activeJob(), state()->targetName()); + placeholderPath.processJobInfo(activeJob()); state()->setNextSequenceID(1); } @@ -690,10 +708,12 @@ void CaptureProcess::refreshOpticalTrain(QString name) { - auto mount = OpticalTrainManager::Instance()->getMount(name); setMount(mount); + auto scope = OpticalTrainManager::Instance()->getScope(name); + setScope(scope["name"].toString()); + auto camera = OpticalTrainManager::Instance()->getCamera(name); setCamera(camera); @@ -888,7 +908,7 @@ } // set state to capture preparation - state()->setCaptureState(CAPTURE_PROGRESS); + state()->setCaptureState(CAPTURE_CALIBRATING); // JM 2020-12-06: Check if we need to execute pre-capture script first. if (runCaptureScript(SCRIPT_PRE_CAPTURE) == IPS_BUSY) @@ -1295,7 +1315,7 @@ return; // Bail out if we have no CCD anymore - if (activeCamera()->isConnected() == false) + if (!activeCamera() || !activeCamera()->isConnected()) { emit newLog(i18n("Error: Lost connection to CCD.")); emit stopCapture(CAPTURE_ABORTED); @@ -1381,7 +1401,7 @@ state()->setStartingCapture(true); auto placeholderPath = PlaceholderPath(state()->sequenceURL().toLocalFile()); - placeholderPath.setGenerateFilenameSettings(*activeJob(), state()->targetName()); + placeholderPath.setGenerateFilenameSettings(*activeJob()); activeCamera()->setPlaceholderPath(placeholderPath); // now hand over the control of capturing to the sequence job. As soon as capturing // has started, the sequence job will report the result with the captureStarted() event @@ -1397,6 +1417,7 @@ activeCamera()->setFastExposureEnabled(true); } + emit captureTarget(activeJob()->getCoreProperty(SequenceJob::SJ_TargetName).toString()); emit captureImageStarted(); } @@ -2029,7 +2050,7 @@ activeCamera()->setUploadMode(activeJob()->getUploadMode()); auto placeholderPath = PlaceholderPath(); // Make sure to update Full Prefix as exposure value was changed - placeholderPath.processJobInfo(activeJob(), state()->targetName()); + placeholderPath.processJobInfo(activeJob()); // Mark calibration as complete activeJob()->setCalibrationStage(SequenceJobState::CAL_CALIBRATION_COMPLETE); @@ -2246,7 +2267,7 @@ } } -bool CaptureProcess::loadSequenceQueue(const QString &fileURL, bool ignoreTarget) +bool CaptureProcess::loadSequenceQueue(const QString &fileURL, QString targetName) { QFile sFile(fileURL); if (!sFile.open(QIODevice::ReadOnly)) @@ -2341,7 +2362,7 @@ } else { - SequenceJob *job = loadSequenceJob(ep, ignoreTarget); + SequenceJob *job = new SequenceJob(devices(), state(), SequenceJob::JOBTYPE_BATCH, ep, targetName); emit addJob(job); } } @@ -2361,271 +2382,6 @@ return true; } -SequenceJob *CaptureProcess::loadSequenceJob(XMLEle *root, bool ignoreTarget) -{ - SequenceJob *job = new SequenceJob(devices(), state(), SequenceJob::JOBTYPE_BATCH); - XMLEle * ep; - XMLEle * subEP; - /* remove enforceJobPA - if (m_RotatorControlPanel) - m_RotatorControlPanel->setRotationEnforced(false); - */ - bool isDarkFlat = false; - state()->scripts().clear(); - QLocale cLocale = QLocale::c(); - - for (ep = nextXMLEle(root, 1); ep != nullptr; ep = nextXMLEle(root, 0)) - { - if (!strcmp(tagXMLEle(ep), "Exposure")) - job->setCoreProperty(SequenceJob::SJ_Exposure, cLocale.toDouble(pcdataXMLEle(ep))); - else if (!strcmp(tagXMLEle(ep), "Format")) - job->setCoreProperty(SequenceJob::SJ_Format, pcdataXMLEle(ep)); - else if (!strcmp(tagXMLEle(ep), "Encoding")) - { - job->setCoreProperty(SequenceJob::SJ_Encoding, pcdataXMLEle(ep)); - } - else if (!strcmp(tagXMLEle(ep), "Binning")) - { - QPoint binning(1, 1); - subEP = findXMLEle(ep, "X"); - if (subEP) - binning.setX(cLocale.toInt(pcdataXMLEle(subEP))); - subEP = findXMLEle(ep, "Y"); - if (subEP) - binning.setY(cLocale.toInt(pcdataXMLEle(subEP))); - - job->setCoreProperty(SequenceJob::SJ_Binning, binning); - } - else if (!strcmp(tagXMLEle(ep), "Frame")) - { - QRect roi(0, 0, 0, 0); - subEP = findXMLEle(ep, "X"); - if (subEP) - roi.setX(cLocale.toInt(pcdataXMLEle(subEP))); - subEP = findXMLEle(ep, "Y"); - if (subEP) - roi.setY(cLocale.toInt(pcdataXMLEle(subEP))); - subEP = findXMLEle(ep, "W"); - if (subEP) - roi.setWidth(cLocale.toInt(pcdataXMLEle(subEP))); - subEP = findXMLEle(ep, "H"); - if (subEP) - roi.setHeight(cLocale.toInt(pcdataXMLEle(subEP))); - - job->setCoreProperty(SequenceJob::SJ_ROI, roi); - } - else if (!strcmp(tagXMLEle(ep), "Temperature")) - { - job->setTargetTemperature(cLocale.toDouble(pcdataXMLEle(ep))); - - // If force attribute exist, we change cameraTemperatureS, otherwise do nothing. - if (!strcmp(findXMLAttValu(ep, "force"), "true")) - job->setCoreProperty(SequenceJob::SJ_EnforceTemperature, true); - else if (!strcmp(findXMLAttValu(ep, "force"), "false")) - job->setCoreProperty(SequenceJob::SJ_EnforceTemperature, false); - } - else if (!strcmp(tagXMLEle(ep), "Filter")) - { - const auto name = pcdataXMLEle(ep); - const auto index = std::max(1, filterLabels().indexOf(name) + 1); - job->setTargetFilter(index, name); - } - else if (!strcmp(tagXMLEle(ep), "Type")) - { - int index = frameTypes().indexOf(pcdataXMLEle(ep)); - job->setFrameType(static_cast(qMax(0, index))); - } - else if (!strcmp(tagXMLEle(ep), "Prefix")) - { - // RawPrefix is outdated and will be ignored - subEP = findXMLEle(ep, "RawPrefix"); - if (subEP && ignoreTarget == false) - { - if (strcmp(pcdataXMLEle(subEP), "") != 0) - qWarning(KSTARS_EKOS_CAPTURE) << QString("Sequence job raw prefix %1 ignored.").arg(pcdataXMLEle(subEP)); - } - bool filterEnabled = false, expEnabled = false, tsEnabled = false; - subEP = findXMLEle(ep, "FilterEnabled"); - if (subEP) - filterEnabled = !strcmp("1", pcdataXMLEle(subEP)); - subEP = findXMLEle(ep, "ExpEnabled"); - if (subEP) - expEnabled = !strcmp("1", pcdataXMLEle(subEP)); - subEP = findXMLEle(ep, "TimeStampEnabled"); - if (subEP) - tsEnabled = !strcmp("1", pcdataXMLEle(subEP)); - // build default format - job->setCoreProperty(SequenceJob::SJ_PlaceholderFormat, - PlaceholderPath::defaultFormat(filterEnabled, expEnabled, tsEnabled)); - } - else if (!strcmp(tagXMLEle(ep), "Count")) - { - job->setCoreProperty(SequenceJob::SJ_Count, cLocale.toInt(pcdataXMLEle(ep))); - } - else if (!strcmp(tagXMLEle(ep), "Delay")) - { - job->setCoreProperty(SequenceJob::SJ_Delay, cLocale.toInt(pcdataXMLEle(ep)) * 1000); - } - else if (!strcmp(tagXMLEle(ep), "PostCaptureScript")) - { - state()->scripts()[SCRIPT_POST_CAPTURE] = pcdataXMLEle(ep); - } - else if (!strcmp(tagXMLEle(ep), "PreCaptureScript")) - { - state()->scripts()[SCRIPT_PRE_CAPTURE] = pcdataXMLEle(ep); - } - else if (!strcmp(tagXMLEle(ep), "PostJobScript")) - { - state()->scripts()[SCRIPT_POST_JOB] = pcdataXMLEle(ep); - } - else if (!strcmp(tagXMLEle(ep), "PreJobScript")) - { - state()->scripts()[SCRIPT_PRE_JOB] = pcdataXMLEle(ep); - } - else if (!strcmp(tagXMLEle(ep), "FITSDirectory")) - { - job->setCoreProperty(SequenceJob::SJ_LocalDirectory, pcdataXMLEle(ep)); - } - else if (!strcmp(tagXMLEle(ep), "PlaceholderFormat")) - { - job->setCoreProperty(SequenceJob::SJ_PlaceholderFormat, pcdataXMLEle(ep)); - } - else if (!strcmp(tagXMLEle(ep), "PlaceholderSuffix")) - { - job->setCoreProperty(SequenceJob::SJ_PlaceholderSuffix, cLocale.toUInt(pcdataXMLEle(ep))); - } - else if (!strcmp(tagXMLEle(ep), "RemoteDirectory")) - { - job->setCoreProperty(SequenceJob::SJ_RemoteDirectory, pcdataXMLEle(ep)); - } - else if (!strcmp(tagXMLEle(ep), "UploadMode")) - { - job->setUploadMode(static_cast(cLocale.toInt(pcdataXMLEle(ep)))); - } - else if (!strcmp(tagXMLEle(ep), "ISOIndex")) - { - job->setCoreProperty(SequenceJob::SJ_ISOIndex, cLocale.toInt(pcdataXMLEle(ep))); - } - else if (!strcmp(tagXMLEle(ep), "Rotation")) - { - job->setTargetRotation(cLocale.toDouble(pcdataXMLEle(ep))); - } - else if (!strcmp(tagXMLEle(ep), "Properties")) - { - QMap> propertyMap; - - for (subEP = nextXMLEle(ep, 1); subEP != nullptr; subEP = nextXMLEle(ep, 0)) - { - QMap elements; - XMLEle * oneElement = nullptr; - for (oneElement = nextXMLEle(subEP, 1); oneElement != nullptr; oneElement = nextXMLEle(subEP, 0)) - { - const char * name = findXMLAttValu(oneElement, "name"); - bool ok = false; - // String - auto xmlValue = pcdataXMLEle(oneElement); - // Try to load it as double - auto value = cLocale.toDouble(xmlValue, &ok); - if (ok) - elements[name] = value; - else - elements[name] = xmlValue; - } - - const char * name = findXMLAttValu(subEP, "name"); - propertyMap[name] = elements; - } - - job->setCustomProperties(propertyMap); - // read the gain and offset values from the custom properties - job->setCoreProperty(SequenceJob::SJ_Gain, getGain(propertyMap)); - job->setCoreProperty(SequenceJob::SJ_Offset, getOffset(propertyMap)); - } - else if (!strcmp(tagXMLEle(ep), "Calibration")) - { - subEP = findXMLEle(ep, "FlatSource"); - if (subEP) - { - XMLEle * typeEP = findXMLEle(subEP, "Type"); - if (typeEP) - { - if (!strcmp(pcdataXMLEle(typeEP), "Manual")) - job->setFlatFieldSource(SOURCE_MANUAL); - else if (!strcmp(pcdataXMLEle(typeEP), "FlatCap")) - job->setFlatFieldSource(SOURCE_FLATCAP); - else if (!strcmp(pcdataXMLEle(typeEP), "DarkCap")) - job->setFlatFieldSource(SOURCE_DARKCAP); - else if (!strcmp(pcdataXMLEle(typeEP), "Wall")) - { - XMLEle * azEP = findXMLEle(subEP, "Az"); - XMLEle * altEP = findXMLEle(subEP, "Alt"); - - if (azEP && altEP) - { - job->setFlatFieldSource(SOURCE_WALL); - SkyPoint wallCoord; - wallCoord.setAz(cLocale.toDouble(pcdataXMLEle(azEP))); - wallCoord.setAlt(cLocale.toDouble(pcdataXMLEle(altEP))); - job->setWallCoord(wallCoord); - } - } - else - job->setFlatFieldSource(SOURCE_DAWN_DUSK); - } - } - - subEP = findXMLEle(ep, "FlatDuration"); - if (subEP) - { - const char * dark = findXMLAttValu(subEP, "dark"); - isDarkFlat = !strcmp(dark, "true"); - - XMLEle * typeEP = findXMLEle(subEP, "Type"); - if (typeEP) - { - if (!strcmp(pcdataXMLEle(typeEP), "Manual")) - job->setFlatFieldDuration(DURATION_MANUAL); - } - - XMLEle * aduEP = findXMLEle(subEP, "Value"); - if (aduEP) - { - job->setFlatFieldDuration(DURATION_ADU); - job->setCoreProperty(SequenceJob::SJ_TargetADU, QVariant(cLocale.toDouble(pcdataXMLEle(aduEP)))); - } - - aduEP = findXMLEle(subEP, "Tolerance"); - if (aduEP) - { - job->setCoreProperty(SequenceJob::SJ_TargetADUTolerance, QVariant(cLocale.toDouble(pcdataXMLEle(aduEP)))); - } - } - - subEP = findXMLEle(ep, "PreMountPark"); - if (subEP) - job->setPreMountPark(!strcmp(pcdataXMLEle(subEP), "True")); - - subEP = findXMLEle(ep, "PreDomePark"); - if (subEP) - job->setPreDomePark(!strcmp(pcdataXMLEle(subEP), "True")); - } - } - - if(isDarkFlat) - job->setJobType(SequenceJob::JOBTYPE_DARKFLAT); - - // copy general state attributes - // TODO: does this really make sense? This is a general setting - sterne-jaeger@openfuture.de, 2023-09-21 - job->setCoreProperty(SequenceJob::SJ_EnforceStartGuiderDrift, Options::enforceStartGuiderDrift()); - job->setTargetStartGuiderDrift(Options::startGuideDeviation()); - - // create signature with current target - auto placeholderPath = Ekos::PlaceholderPath(); - placeholderPath.processJobInfo(job, state()->targetName()); - - return job; -} - bool CaptureProcess::saveSequenceQueue(const QString &path) { QFile file; @@ -2649,7 +2405,7 @@ outstream << "" << state()->observerName() << "" << Qt::endl; outstream << "" << cLocale.toString(Options::guideDeviation()) << "" << Qt::endl; - outstream << "" + outstream << "" << cLocale.toString(Options::startGuideDeviation()) << "" << Qt::endl; // Issue a warning when autofocus is enabled but Ekos options prevent HFR value from being written if (Options::enforceAutofocusHFR() && !Options::saveHFRToFile()) @@ -2696,6 +2452,8 @@ // ms to seconds outstream << "" << cLocale.toString(job->getCoreProperty(SequenceJob::SJ_Delay).toInt() / 1000.0) << "" << Qt::endl; + if (job->getCoreProperty(SequenceJob::SJ_TargetName) != "") + outstream << "" << job->getCoreProperty(SequenceJob::SJ_TargetName).toString() << "" << Qt::endl; if (job->getScript(SCRIPT_PRE_CAPTURE).isEmpty() == false) outstream << "" << job->getScript(SCRIPT_PRE_CAPTURE) << "" << Qt::endl; if (job->getScript(SCRIPT_POST_CAPTURE).isEmpty() == false) @@ -2747,14 +2505,14 @@ outstream << "
" << Qt::endl; outstream << "" << Qt::endl; - outstream << "" << Qt::endl; - outstream << QString("%1").arg(FlatFieldSourceNames[job->getFlatFieldSource()]) << Qt::endl; - if (job->getFlatFieldSource() == SOURCE_WALL) + outstream << "" << Qt::endl; + outstream << QString("%1").arg(job->getCalibrationPreAction()) << Qt::endl; + if (job->getCalibrationPreAction() & ACTION_WALL) { outstream << "" << cLocale.toString(job->getWallCoord().az().Degrees()) << "" << Qt::endl; outstream << "" << cLocale.toString(job->getWallCoord().alt().Degrees()) << "" << Qt::endl; } - outstream << "" << Qt::endl; + outstream << "" << Qt::endl; outstream << "" << Qt::endl; @@ -2769,13 +2527,7 @@ "" << Qt::endl; } outstream << "" << Qt::endl; - - outstream << "" << (job->getPreMountPark() ? "True" : "False") << - "" << Qt::endl; - outstream << "" << (job->getPreDomePark() ? "True" : "False") << - "" << Qt::endl; outstream << "" << Qt::endl; - outstream << "" << Qt::endl; } @@ -3033,69 +2785,76 @@ return devices()->getFilterManager()->getFilterLabels(); } -double CaptureProcess::getGain(QMap > propertyMap) -{ - if (!devices()->getActiveCamera()) - return -1; - - if (devices()->getActiveCamera()->getProperty("CCD_GAIN")) - { - return propertyMap["CCD_GAIN"].value("GAIN", -1).toDouble(); - } - else if (devices()->getActiveCamera()->getProperty("CCD_CONTROLS")) - { - return propertyMap["CCD_CONTROLS"].value("Gain", -1).toDouble(); - } - - return -1; -} - void CaptureProcess::updateGain(double value, QMap > &propertyMap) { if (devices()->getActiveCamera()->getProperty("CCD_GAIN")) { - QMap ccdGain; - ccdGain["GAIN"] = value; - propertyMap["CCD_GAIN"] = ccdGain; + if (value >= 0) + { + QMap ccdGain; + ccdGain["GAIN"] = value; + propertyMap["CCD_GAIN"] = ccdGain; + } + else + { + propertyMap["CCD_GAIN"].remove("GAIN"); + if (propertyMap["CCD_GAIN"].size() == 0) + propertyMap.remove("CCD_GAIN"); + } } else if (devices()->getActiveCamera()->getProperty("CCD_CONTROLS")) { - QMap ccdGain = propertyMap["CCD_CONTROLS"]; - ccdGain["Gain"] = value; - propertyMap["CCD_CONTROLS"] = ccdGain; + if (value >= 0) + { + QMap ccdGain = propertyMap["CCD_CONTROLS"]; + ccdGain["Gain"] = value; + propertyMap["CCD_CONTROLS"] = ccdGain; + } + else + { + propertyMap["CCD_CONTROLS"].remove("Gain"); + if (propertyMap["CCD_CONTROLS"].size() == 0) + propertyMap.remove("CCD_CONTROLS"); + } } } -double CaptureProcess::getOffset(QMap > propertyMap) +void CaptureProcess::updateOffset(double value, QMap > &propertyMap) { - if (!devices()->getActiveCamera()) - return -1; - if (devices()->getActiveCamera()->getProperty("CCD_OFFSET")) { - return propertyMap["CCD_OFFSET"].value("OFFSET", -1).toDouble(); + if (value >= 0) + { + QMap ccdOffset; + ccdOffset["OFFSET"] = value; + propertyMap["CCD_OFFSET"] = ccdOffset; + } + else + { + propertyMap["CCD_OFFSET"].remove("OFFSET"); + if (propertyMap["CCD_OFFSET"].size() == 0) + propertyMap.remove("CCD_OFFSET"); + } } else if (devices()->getActiveCamera()->getProperty("CCD_CONTROLS")) { - return propertyMap["CCD_CONTROLS"].value("Offset", -1).toDouble(); + if (value >= 0) + { + QMap ccdOffset = propertyMap["CCD_CONTROLS"]; + ccdOffset["Offset"] = value; + propertyMap["CCD_CONTROLS"] = ccdOffset; + } + else + { + propertyMap["CCD_CONTROLS"].remove("Offset"); + if (propertyMap["CCD_CONTROLS"].size() == 0) + propertyMap.remove("CCD_CONTROLS"); + } } - - return -1; } -void CaptureProcess::updateOffset(double value, QMap > &propertyMap) +ISD::Camera *CaptureProcess::activeCamera() { - if (devices()->getActiveCamera()->getProperty("CCD_OFFSET")) - { - QMap ccdOffset; - ccdOffset["OFFSET"] = value; - propertyMap["CCD_OFFSET"] = ccdOffset; - } - else if (devices()->getActiveCamera()->getProperty("CCD_CONTROLS")) - { - QMap ccdOffset = propertyMap["CCD_CONTROLS"]; - ccdOffset["Offset"] = value; - propertyMap["CCD_CONTROLS"] = ccdOffset; - } + return devices()->getActiveCamera(); } } // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocess.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocess.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocess.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocess.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,16 +7,18 @@ #pragma once #include "capturemodulestate.h" -#include "capturedeviceadaptor.h" #include "sequencejob.h" #include "indiapi.h" -#include "ekos/auxiliary/darkprocessor.h" #include namespace Ekos { + +class CaptureDeviceAdaptor; +class DarkProcessor; + /** * @class CaptureProcess * @brief The CaptureProcess class holds the entire business logic to control capturing execution. @@ -147,12 +149,29 @@ bool setLightBox(ISD::LightBox *device); /** + * @brief setDome Connect to the given dome device + * @param device point to dome INDI device + * @return True if added successfully, false if duplicate or failed to add. + */ + bool setDome(ISD::Dome *device); + + /** * @brief setCamera Connect to the given camera device (and deconnect * the old one if existing) * @param device pointer to camera INDI device. * @return True if added successfully, false if duplicate or failed to add. */ bool setCamera(ISD::Camera *device); + + /** + * @brief setScope Set active train telescope name + * @param name Name of scope + */ + void setScope(const QString &name) + { + m_Scope = name; + } + /** * @brief Connect or disconnect the camera device * @param connection flag if connect (=true) or disconnect (=false) @@ -570,16 +589,9 @@ /** * Loads the Ekos Sequence Queue file in the Sequence Queue. Jobs are appended to existing jobs. * @param fileURL full URL of the filename - * @param ignoreTarget ignore target defined in the sequence queue file (necessary for using the target of the scheduler) + * @param targetName override the target defined in the sequence queue file (necessary for using the target of the scheduler) */ - bool loadSequenceQueue(const QString &fileURL, bool ignoreTarget = false); - - /** - * @brief loadSequenceJob Create a single job from an XML definition. - * @param root XML root holding the job definition - * @param ignoreTarget true iff the target from the XML should be ignored - */ - SequenceJob *loadSequenceJob(XMLEle *root, bool ignoreTarget = false); + bool loadSequenceQueue(const QString &fileURL, QString targetName = ""); /** * Saves the Sequence Queue to the Ekos Sequence Queue file. @@ -649,19 +661,17 @@ QStringList filterLabels(); /** - * @brief getGain Retrieve the gain value from the custom property value. Depending + * @brief getGain Update the gain value from the custom property value. Depending * on the camera, it is either stored as GAIN property value of CCD_GAIN or as * Gain property value from CCD_CONTROLS. */ - double getGain(QMap > propertyMap); void updateGain(double value, QMap > &propertyMap); /** - * @brief getOffset Retrieve the offset value from the custom property value. Depending + * @brief getOffset Update the offset value from the custom property value. Depending * on the camera, it is either stored as OFFSET property value of CCD_OFFSET or as * Offset property value from CCD_CONTROLS. */ - double getOffset(QMap > propertyMap); void updateOffset(double value, QMap > &propertyMap); @@ -687,6 +697,7 @@ void jobExecutionPreparationStarted(); void jobPrepared(SequenceJob *job); void captureImageStarted(); + void captureTarget(QString targetName); void captureRunning(); void newExposureProgress(SequenceJob *job); void newDownloadProgress(double downloadTimeLeft); @@ -719,6 +730,7 @@ // Pre-/post capture script process QProcess m_CaptureScript; + QString m_Scope; // Flat field automation QVector ExpRaw, ADURaw; ADUAlgorithm targetADUAlgorithm { ADU_LEAST_SQUARES }; @@ -751,10 +763,7 @@ /** * @brief activeCamera Shortcut to the active camera held in the device adaptor */ - ISD::Camera *activeCamera() - { - return devices()->getActiveCamera(); - } + ISD::Camera *activeCamera(); /** * @brief resetAllJobs Iterate over all jobs and reset them. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -5,7 +5,6 @@ */ #include "captureprocessoverlay.h" - #include "QTime" #include "QFileInfo" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/captureprocessoverlay.h 2023-12-03 05:23:17.000000000 +0000 @@ -9,10 +9,11 @@ #include "ui_captureprocessoverlay.h" #include "indi/indicommon.h" -#include "fitsviewer/fitsdata.h" #include +class FITSData; + class CaptureProcessOverlay : public QWidget, public Ui::CaptureProcessOverlay { Q_OBJECT diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/calculatedgainsubexposuretime.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/calculatedgainsubexposuretime.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/calculatedgainsubexposuretime.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/calculatedgainsubexposuretime.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,8 +6,11 @@ #pragma once -#include +#ifndef CALCULATEDGAINSUBEXPOSURETIME_H +#define CALCULATEDGAINSUBEXPOSURETIME_H +#include +QT_BEGIN_NAMESPACE namespace OptimalExposure { @@ -30,3 +33,6 @@ }; } +QT_END_NAMESPACE + +#endif // CALCULATEDGAINSUBEXPOSURETIME_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameradatafileutilitydialog.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameradatafileutilitydialog.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameradatafileutilitydialog.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameradatafileutilitydialog.h 2023-12-03 05:23:17.000000000 +0000 @@ -1,10 +1,5 @@ -/* - SPDX-FileCopyrightText: 2023 Joseph McGee - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#pragma once +#ifndef CAMERADATAFILEUTILITYDIALOG_H +#define CAMERADATAFILEUTILITYDIALOG_H #include @@ -24,3 +19,4 @@ Ui::CameraDataFileUtilityDialog *ui; }; +#endif // CAMERADATAFILEUTILITYDIALOG_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameraexposureenvelope.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameraexposureenvelope.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameraexposureenvelope.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameraexposureenvelope.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,10 +6,13 @@ #pragma once +#ifndef CAMERAEXPOSUREENVELOPE_H +#define CAMERAEXPOSUREENVELOPE_H #include #include #include "calculatedgainsubexposuretime.h" +QT_BEGIN_NAMESPACE namespace OptimalExposure { class CameraExposureEnvelope @@ -34,3 +37,6 @@ }; } +QT_END_NAMESPACE + +#endif // CAMERAEXPOSUREENVELOPE_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadmode.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadmode.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadmode.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadmode.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,10 +6,14 @@ #pragma once +#ifndef CameraGainReadMode_H +#define CameraGainReadMode_H + #include #include #include "cameragainreadnoise.h" +QT_BEGIN_NAMESPACE namespace OptimalExposure { class CameraGainReadMode @@ -34,3 +38,5 @@ QVector CameraGainReadNoiseVector; }; } +QT_END_NAMESPACE +#endif // CameraGainReadMode_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadnoise.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadnoise.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadnoise.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/cameragainreadnoise.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,8 +6,11 @@ #pragma once -#include +#ifndef CAMERAGAINREADNOISE_H +#define CAMERAGAINREADNOISE_H +#include +QT_BEGIN_NAMESPACE namespace OptimalExposure { @@ -29,9 +32,10 @@ }; -} - +} +QT_END_NAMESPACE +#endif // CAMERAGAINREADNOISE_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -5,22 +5,20 @@ */ -#include "fileutilitycameradata.h" -#include "optimalsubexposurecalculator.h" -#include "optimalexposuredetail.h" -#include "kstars.h" -#include "fileutilitycameradatadialog.h" -#include "exposurecalculatordialog.h" -#include "ui_exposurecalculatordialog.h" - #include #include #include #include #include +#include "fileutilitycameradata.h" +#include "optimalsubexposurecalculator.h" +#include "optimalexposuredetail.h" #include #include #include +#include "fileutilitycameradatadialog.h" +#include "exposurecalculatordialog.h" +#include "./ui_exposurecalculatordialog.h" #include #include @@ -35,61 +33,48 @@ * */ -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// +OptimalExposure::OptimalExposureDetail +aSubExposureDetail; // Added during refactoring to simplify and better support the noise graph + ExposureCalculatorDialog::ExposureCalculatorDialog(QWidget *parent, double aPreferredSkyQualityValue, double aPreferredFocalRatioValue, const QString &aPreferredCameraId) : QDialog(parent), - ui(new Ui::ExposureCalculatorDialog), aPreferredSkyQualityValue(aPreferredSkyQualityValue), aPreferredFocalRatioValue(aPreferredFocalRatioValue), - aPreferredCameraId(aPreferredCameraId) + aPreferredCameraId(aPreferredCameraId), + ui(new Ui::ExposureCalculatorDialog) { ui->setupUi(this); - // The download function is disabled in the initial release - // if(!OptimalExposure::FileUtilityCameraData::isExposureCalculatorCameraDataAvailable()) - // { - // if(QDir().mkpath(OptimalExposure::FileUtilityCameraData::cameraApplicationDataRepository)) - // { - - // // This could be used to build a set of camera files from code - // // OptimalExposure::FileUtilityCameraData::buildCameraDataFile(); + ui->exposureDiffLabel->setText(QString("\u0394=")); - // // Instead find data for the active camera in the remote repository - // FileUtilityCameraDataDialog aCameraDownloadDialog(this, aPreferredCameraId); - - // aCameraDownloadDialog.setWindowModality(Qt::WindowModal); - - // aCameraDownloadDialog.exec(); + QStringList availableCameraFiles = OptimalExposure::FileUtilityCameraData::getAvailableCameraFilesList(); + if(availableCameraFiles.length() == 0) + { + // qCWarning(KSTARS_EKOS_CAPTURE) << "Exposure Calculator - No Camera data available, closing dialog"; + // QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); + qCWarning(KSTARS_EKOS_CAPTURE) << "Exposure Calculator - No Camera data available, opening camera data download dialog"; + FileUtilityCameraDataDialog aCameraDownloadDialog(this, aPreferredCameraId); + aCameraDownloadDialog.setWindowModality(Qt::WindowModal); + aCameraDownloadDialog.exec(); + // QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); + // Look again for files... + availableCameraFiles = OptimalExposure::FileUtilityCameraData::getAvailableCameraFilesList(); - // } - // else - // { - // qCCritical(KSTARS_EKOS_CAPTURE) << "Exposure calculator will fail without camera data!"; - // } - // } + } - QStringList availableCameraFiles = OptimalExposure::FileUtilityCameraData::getAvailableCameraFilesList(); if(availableCameraFiles.length() > 0) { - ui->imagingCameraSelector->clear(); refreshCameraSelector(ui, availableCameraFiles, aPreferredCameraId); ui->exposureCalculatorFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setVisible(false); - ui->gainSelectionNormalFrame->setEnabled(false); - ui->gainSelectionNormalFrame->setVisible(false); - ui->gainSelectionFixedFrame->setEnabled(false); - ui->gainSelectionFixedFrame->setVisible(false); + hideGainSelectionWidgets(); ui->gainSelector->setMinimum(0); ui->gainSelector->setMaximum(100); @@ -108,8 +93,8 @@ // was coded ui->userSkyQuality->setValue(20.0); ui->userSkyQuality->setValue(aPreferredSkyQualityValue); - ui->noiseTolerance->setMinimum(0.05); - ui->noiseTolerance->setMaximum(25.00); + ui->noiseTolerance->setMinimum(0.02); + ui->noiseTolerance->setMaximum(200.00); ui->noiseTolerance->setSingleStep(0.25); ui->noiseTolerance->setValue(5.0); @@ -145,7 +130,7 @@ */ - // Set up plot colors to be night friendly + // Set up plot colors of Sub Exposure (night friendly) ui->qCustomPlotSubExposure->setBackground(QBrush(Qt::black)); ui->qCustomPlotSubExposure->xAxis->setBasePen(QPen(Qt::white, 1)); ui->qCustomPlotSubExposure->yAxis->setBasePen(QPen(Qt::white, 1)); @@ -167,6 +152,37 @@ ui->qCustomPlotSubExposure->addGraph(); + + // Set up plot colors of Integrated Image Noise (night friendly) + ui->qCustomPlotIntegrationNoise->setBackground(QBrush(Qt::black)); + ui->qCustomPlotIntegrationNoise->xAxis->setBasePen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->yAxis->setBasePen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->xAxis->setTickPen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->yAxis->setTickPen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->xAxis->setSubTickPen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->yAxis->setSubTickPen(QPen(Qt::white, 1)); + ui->qCustomPlotIntegrationNoise->xAxis->setTickLabelColor(Qt::white); + ui->qCustomPlotIntegrationNoise->yAxis->setTickLabelColor(Qt::white); + ui->qCustomPlotIntegrationNoise->xAxis->setLabelColor(Qt::white); + ui->qCustomPlotIntegrationNoise->yAxis->setLabelColor(Qt::white); + + ui->qCustomPlotIntegrationNoise->xAxis->grid()->setPen(QPen(Qt::darkGray)); + ui->qCustomPlotIntegrationNoise->yAxis->grid()->setPen(QPen(Qt::darkGray)); + + ui->qCustomPlotIntegrationNoise->addGraph(ui->qCustomPlotIntegrationNoise->xAxis, ui->qCustomPlotIntegrationNoise->yAxis); + ui->qCustomPlotIntegrationNoise->graph(0)->setPen(QPen(Qt::yellow)); + ui->qCustomPlotIntegrationNoise->graph(0)->setName("Integration Time to Noise Ratio"); + ui->qCustomPlotIntegrationNoise->xAxis->setLabel("Stacked Exposures"); + ui->qCustomPlotIntegrationNoise->yAxis->setLabel("Noise Ratio"); + + // ui->qCustomPlotIntegrationNoise->addGraph(ui->qCustomPlotIntegrationNoise->xAxis, ui->qCustomPlotIntegrationNoise->yAxis); + // ui->qCustomPlotIntegrationNoise->graph(1)->setPen(QPen(Qt::green)); + // ui->qCustomPlotIntegrationNoise->graph(1)->setName("Integration to Noise Ratio"); + // ui->qCustomPlotIntegrationNoise->yAxis2->setLabel("Noise Ratio"); + + + + connect(ui->imagingCameraSelector, static_cast(&QComboBox::currentIndexChanged), this, &ExposureCalculatorDialog::applyInitialInputs); @@ -188,34 +204,35 @@ connect(ui->noiseTolerance, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ExposureCalculatorDialog::handleUserAdjustment); - connect(ui->isoDiscreteSelector, static_cast(&QComboBox::currentIndexChanged), this, + connect(ui->gainISODiscreteSelector, static_cast(&QComboBox::currentIndexChanged), this, &ExposureCalculatorDialog::handleUserAdjustment); - + connect(ui->targetNoiseRatio, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &ExposureCalculatorDialog::handleStackCalculation); // Hide the gain selector frames (until a camera is selected) - - ui->gainSelectionFixedFrame->setEnabled(false); - ui->gainSelectionFixedFrame->setVisible(false); - ui->gainSelectionNormalFrame->setEnabled(false); - ui->gainSelectionNormalFrame->setVisible(false); - ui->gainSelectionISODiscreteFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setVisible(false); + hideGainSelectionWidgets(); applyInitialInputs(); } - else - { - qCWarning(KSTARS_EKOS_CAPTURE) << "Exposure Calculator - No Camera data available, closing dialog"; - QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); - } - + /* + else + { + // qCWarning(KSTARS_EKOS_CAPTURE) << "Exposure Calculator - No Camera data available, closing dialog"; + // QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); + qCWarning(KSTARS_EKOS_CAPTURE) << "Exposure Calculator - No Camera data available, opening camera data download dialog"; + FileUtilityCameraDataDialog aCameraDownloadDialog(this, aPreferredCameraId); + aCameraDownloadDialog.setWindowModality(Qt::WindowModal); + aCameraDownloadDialog.exec(); + QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); + } + */ } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + + + int ExposureCalculatorDialog::getGainSelection(OptimalExposure::GainSelectionType aGainSelectionType) { int aSelectedGain = 0; @@ -229,12 +246,12 @@ case OptimalExposure::GAIN_SELECTION_TYPE_ISO_DISCRETE: // qCInfo(KSTARS_EKOS_CAPTURE) << " iso selector text: " << ui->isoDiscreteSelector->currentText(); - aSelectedGain = ui->isoDiscreteSelector->currentText().toInt(); + aSelectedGain = ui->gainISODiscreteSelector->currentText().toInt(); break; case OptimalExposure::GAIN_SELECTION_TYPE_FIXED: - // // qCInfo(KSTARS_EKOS_CAPTURE) << "Fixed read-noise cameras still under development"; - aSelectedGain = 9; + // qCInfo(KSTARS_EKOS_CAPTURE) << "Fixed read-noise camera gain set to 0"; + aSelectedGain = 0; // Fixed noise cameras have read noise data at 0 gain. break; } @@ -242,9 +259,7 @@ return(aSelectedGain); } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + QString skyQualityToBortleClassNumber(double anSQMValue) { @@ -288,20 +303,20 @@ QColor aSkyBrightnessColor; int aHueDegree, aSaturation, aValue; - if (anSQMValue < 18.32) // White Zone + if(anSQMValue < 18.32) // White Zone { aHueDegree = 40; aSaturation = 0; // Saturation must move from aValue = 254; // Value must move from 254 to 240 } - else if (anSQMValue < 18.44) // From White Zone at 18.32 transitioning to Red Zone at 18.44 + else if(anSQMValue < 18.44) // From White Zone at 18.32 transitioning to Red Zone at 18.44 { aHueDegree = 0; // Hue is Red, // Saturation must transition from 0 to 255 as SQM moves from 18.32 to 18.44 aSaturation = (int)(255 * ((anSQMValue - (double)18.32) / (18.44 - 18.32))); aValue = 254; } - else if (anSQMValue < 21.82 ) + else if(anSQMValue < 21.82 ) { // In the color range transitions hue of Bortle can be approximated with a polynomial aHueDegree = 17.351411032 * pow(anSQMValue, 4) @@ -310,13 +325,13 @@ - 549664.28976 * anSQMValue + 2736244.0733; - if (aHueDegree < 0) aHueDegree = 0; + if(aHueDegree < 0) aHueDegree = 0; aSaturation = 255; aValue = 240; } - else if (anSQMValue < 21.92) // Transition from Blue to Dark Gray between 21.82 and 21.92 + else if(anSQMValue < 21.92) // Transition from Blue to Dark Gray between 21.82 and 21.92 { aHueDegree = 240; // Saturation must transition from 255 to 0 @@ -325,7 +340,7 @@ aValue = (int)(100 + (1400 * (21.92 - anSQMValue))); } - else if (anSQMValue < 21.99) // Dark gray zone + else if(anSQMValue < 21.99) // Dark gray zone { aHueDegree = 240; aSaturation = 0; @@ -338,14 +353,16 @@ aValue = 0; } + // qCInfo(KSTARS_EKOS_CAPTURE) << "Sky Quality Color Hue: " << aHueDegree; + // qCInfo(KSTARS_EKOS_CAPTURE) << "Sky Quality Color Saturation: " << aSaturation; + // qCInfo(KSTARS_EKOS_CAPTURE) << "Sky Quality Color Value: " << aValue; + aSkyBrightnessColor.setHsv(aHueDegree, aSaturation, aValue); return(aSkyBrightnessColor); } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + void refreshSkyQualityPresentation(Ui::ExposureCalculatorDialog *ui, double aSkyQualityValue) { @@ -364,9 +381,7 @@ } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + void ExposureCalculatorDialog::handleUserAdjustment() { @@ -404,12 +419,61 @@ } } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// -void ExposureCalculatorDialog::applyInitialInputs() +void ExposureCalculatorDialog::hideGainSelectionWidgets() +{ + ui->gainSelectionFrame->setEnabled(false); + ui->gainSelectionFrame->setVisible(false); + + ui->gainSpinnerLabel->setVisible(false); + ui->gainSelector->setVisible(false); + ui->gainSelector->setEnabled(false); + + ui->gainISOSelectorLabel->setVisible(false); + ui->gainISODiscreteSelector->setVisible(false); + ui->gainISODiscreteSelector->setEnabled(false); + + ui->gainSelectionFixedLabel->setVisible(false); + + /* + ui->gainSelectionISODiscreteFrame->setEnabled(false); + ui->gainSelectionISODiscreteFrame->setVisible(false); + ui->gainSelectionFixedFrame->setEnabled(false); + ui->gainSelectionFixedFrame->setVisible(false); + */ +} + + +void ExposureCalculatorDialog::showGainSelectionNormalWidgets() { + ui->gainSpinnerLabel->setVisible(true); + ui->gainSelector->setEnabled(true); + ui->gainSelector->setVisible(true); + + ui->gainSelectionFrame->setEnabled(true); + ui->gainSelectionFrame->setVisible(true); +} +void ExposureCalculatorDialog::showGainSelectionISODiscreteWidgets() +{ + ui->gainISOSelectorLabel->setVisible(true); + ui->gainISODiscreteSelector->setEnabled(true); + ui->gainISODiscreteSelector->setVisible(true); + + ui->gainSelectionFrame->setEnabled(true); + ui->gainSelectionFrame->setVisible(true); +} + +void ExposureCalculatorDialog::showGainSelectionFixedWidgets() +{ + ui->gainSelectionFixedLabel->setVisible(true); + + ui->gainSelectionFrame->setEnabled(true); + ui->gainSelectionFrame->setVisible(true); +} + + +void ExposureCalculatorDialog::applyInitialInputs() +{ ui->exposureCalculatorFrame->setEnabled(false); // QString aSelectedImagingCameraName = ui->imagingCameraSelector->itemText(ui->imagingCameraSelector->currentIndex()); @@ -443,9 +507,81 @@ } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + +void plotIntegratedNoise(Ui::ExposureCalculatorDialog *ui, + OptimalExposure::OptimalExposureDetail *subExposureDetail) +{ + + ui->qCustomPlotIntegrationNoise->graph()->data()->clear(); + + double aCoefficient = (subExposureDetail->getSubExposureTime() / subExposureDetail->getExposureTotalNoise()); + /* + qCInfo(KSTARS_EKOS_CAPTURE) << "Noise Ratio Function: Noise Ratio = " << aCoefficient << " * Sqrt(Exposure Count)"; + + qCInfo(KSTARS_EKOS_CAPTURE) << "Differential of Noise Ratio Function: = " << aCoefficient << " / (2 * Sqrt(Exposure Count)"; + + qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Count Function (for desired Noise Ratio):" + << "Exposure Count = (Noise Ratio / " << aCoefficient << ") ^2 = pow(Noise Ratio / " << aCoefficient << ", 2)"; + */ + double aTargetNoiseRatio = ui->targetNoiseRatio->value(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Target Noise Ratio: " << aTargetNoiseRatio; + + int aRequiredExposureCount = std::max(1, (int)(pow((aTargetNoiseRatio / aCoefficient), 2))); + ui->exposureCount->setText(QString::number(aRequiredExposureCount)); + + double aDifferential = aCoefficient / (2 * sqrt(aRequiredExposureCount)); + ui->exposureCountDifferential->setText(QString::number(aDifferential, 'f', 2)); + + + ui->qCustomPlotIntegrationNoise->graph()->data()->clear(); + + // ui->qCustomPlotIntegrationNoise + // ui->qCustomPlotIntegrationNoise->graph(0)->setData(ExposureCount, noise); + + QVector xValue((aRequiredExposureCount * 2) + 1), yValue((aRequiredExposureCount * 2) + 1); + for (int exposureCount = 1; exposureCount < (aRequiredExposureCount * 2) + 1; exposureCount++) + { + xValue[exposureCount] = exposureCount; + yValue[exposureCount] = aCoefficient * pow(exposureCount, 0.5); + } + + ui->qCustomPlotIntegrationNoise->graph(0)->setData(xValue, yValue); + + ui->qCustomPlotIntegrationNoise->xAxis->setRange(0, aRequiredExposureCount * 2); + ui->qCustomPlotIntegrationNoise->yAxis->setRange(0, yValue[yValue.size() - 1]); + + // Also add a graph with a vertical line to show the computed integration + ui->qCustomPlotIntegrationNoise->addGraph(); + + QVector selectedIntegrationSizeX(2), selectedIntegrationSizeY(2); + selectedIntegrationSizeX[0] = aRequiredExposureCount; + selectedIntegrationSizeY[0] = 0; + selectedIntegrationSizeX[1] = aRequiredExposureCount; + selectedIntegrationSizeY[1] = aTargetNoiseRatio; + ui->qCustomPlotIntegrationNoise->graph(1)->setData(selectedIntegrationSizeX, selectedIntegrationSizeY); + + QPen penSelectedIntegrationSize; + penSelectedIntegrationSize.setWidth(1); + // penSelectedIntegrationSize.setColor(QColor(180, 0, 0)); + // On the black background need more contrast + penSelectedIntegrationSize.setColor(QColor(240, 0, 0)); + + ui->qCustomPlotIntegrationNoise->graph(1)->setPen(penSelectedIntegrationSize); + + ui->qCustomPlotIntegrationNoise->graph(1)->setScatterStyle(QCPScatterStyle::ssCircle); + + ui->qCustomPlotIntegrationNoise->graph()->rescaleAxes(true); + ui->qCustomPlotIntegrationNoise->replot(); + +} + +// Slot for adjustments made to desired noise ratio that require a refresh of the NR graph +void ExposureCalculatorDialog::handleStackCalculation() +{ + plotIntegratedNoise(ui, &aSubExposureDetail); +} + + void plotSubExposureEnvelope(Ui::ExposureCalculatorDialog *ui, OptimalExposure::OptimalSubExposureCalculator *anOptimalSubExposureCalculator, OptimalExposure::OptimalExposureDetail *subExposureDetail) @@ -453,6 +589,11 @@ OptimalExposure::CameraExposureEnvelope aCameraExposureEnvelope = anOptimalSubExposureCalculator->calculateCameraExposureEnvelope(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a set of: " << aCameraExposureEnvelope.getASubExposureVector().size(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a minimum Exposure Time of " << aCameraExposureEnvelope.getExposureTimeMin(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a maximum Exposure Time of " << aCameraExposureEnvelope.getExposureTimeMax(); + + // anOptimalSubExposureCalculator->getImagingCameraData() // Reset the graph axis (But maybe this was not necessary, ui->qCustomPlotSubExposure->xAxis->setRange(anOptimalSubExposureCalculator->getImagingCameraData().getGainMin(), @@ -475,11 +616,9 @@ ui->qCustomPlotSubExposure->graph(0)->setData(gain, exposuretime); - // Also add a graph with a vertical line to show the selected gain... ui->qCustomPlotSubExposure->addGraph(); - QVector selectedExposureX(2), selectedExposureY(2); selectedExposureX[0] = subExposureDetail->getSelectedGain(); selectedExposureY[0] = 0; @@ -490,14 +629,14 @@ QPen penExposureEnvelope; penExposureEnvelope.setWidth(1); // penExposureEnvelope.setColor(QColor(0, 180, 180)); - // On the black background need more contrtast + // On the black background need more contrast penExposureEnvelope.setColor(QColor(0, 220, 220)); ui->qCustomPlotSubExposure->graph(0)->setPen(penExposureEnvelope); QPen penSelectedExposure; penSelectedExposure.setWidth(1); // penSelectedExposure.setColor(QColor(180, 0, 0)); - // On the black background need more contrtast + // On the black background need more contrast penSelectedExposure.setColor(QColor(240, 0, 0)); ui->qCustomPlotSubExposure->graph(1)->setPen(penSelectedExposure); @@ -515,16 +654,49 @@ } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// void ExposureCalculatorDialog::initializeSubExposureCalculator(double aNoiseTolerance, double aSkyQualityValue, double aFocalRatioValue, double aFilterCompensationValue, QString aSelectedImagingCameraName) { + // qCInfo(KSTARS_EKOS_CAPTURE) << "initializeSubExposureComputer"; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taNoiseTolerance: " << aNoiseTolerance; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taSkyQualityValue: " << aSkyQualityValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taFocalRatioValue: " << aFocalRatioValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taFilterCompensation: " << aFilterCompensationValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taSelectedImagingCamera: " << aSelectedImagingCameraName; + + // QVector *aGainSelectionRange = new QVector(); + + // QVector *aCameraGainReadNoiseVector + // = new QVector(); + + // QVector *aCameraGainReadModeVector + // = new QVector(); + + // // Initialize with some default values before attempting to load from file + + // anImagingCameraData = new OptimalExposure::ImagingCameraData(aSelectedImagingCameraName, OptimalExposure::SENSORTYPE_COLOR, + // OptimalExposure::GAIN_SELECTION_TYPE_NORMAL, *aGainSelectionRange, *aCameraGainReadModeVector); + anImagingCameraData = new OptimalExposure::ImagingCameraData(); // Load camera data from file OptimalExposure::FileUtilityCameraData::readCameraDataFile(aSelectedImagingCameraName, anImagingCameraData); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Loaded Imaging Camera Data for " + anImagingCameraData->getCameraId(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Gain Selection Type " + QString::number(anImagingCameraData->getGainSelectionType()); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Read Mode Vector Size " + QString::number( + // anImagingCameraData->getCameraGainReadModeVector().size()); + + switch(anImagingCameraData->getSensorType()) + { + case OptimalExposure::SENSORTYPE_COLOR: + ui->SensorType->setText("Color"); + break; + case OptimalExposure::SENSORTYPE_MONOCHROME: + ui->SensorType->setText("Mono"); + break; + } + ui->cameraReadModeSelector->clear(); foreach(OptimalExposure::CameraGainReadMode aReadMode, anImagingCameraData->getCameraGainReadModeVector()) { @@ -541,56 +713,45 @@ ui->cameraReadModeSelector->setEnabled(false); } + + // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Gain Read-Noise Vector Size " + // + QString::number(anImagingCameraData->getCameraGainReadNoiseVector().size()); + + + switch( anImagingCameraData->getGainSelectionType() ) { case OptimalExposure::GAIN_SELECTION_TYPE_FIXED: // qCInfo(KSTARS_EKOS_CAPTURE) << "Gain Selection Type: GAIN_SELECTION_TYPE_FIXED"; - - ui->gainSelectionISODiscreteFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setVisible(false); - ui->gainSelectionNormalFrame->setEnabled(false); - ui->gainSelectionNormalFrame->setVisible(false); - ui->gainSelectionFixedFrame->setEnabled(true); - ui->gainSelectionFixedFrame->setVisible(true); + hideGainSelectionWidgets(); + showGainSelectionFixedWidgets(); break; case OptimalExposure::GAIN_SELECTION_TYPE_ISO_DISCRETE: // qCInfo(KSTARS_EKOS_CAPTURE) << "Gain Selection Type: GAIN_SELECTION_TYPE_ISO_DISCRETE"; - ui->gainSelectionFixedFrame->setEnabled(false); - ui->gainSelectionFixedFrame->setVisible(false); - ui->gainSelectionNormalFrame->setEnabled(false); - ui->gainSelectionNormalFrame->setVisible(false); - ui->gainSelectionISODiscreteFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setVisible(false); - - // qCInfo(KSTARS_EKOS_CAPTURE) << "ui->isoDiscreteSelector->isEnabled(): " << ui->isoDiscreteSelector->isEnabled(); - // qCInfo(KSTARS_EKOS_CAPTURE) << "ui->noiseTolerance->isEnabled(): " << ui->noiseTolerance->isEnabled(); + hideGainSelectionWidgets(); - ui->isoDiscreteSelector->clear(); + ui->gainISODiscreteSelector->clear(); // Load the ISO Combo from the camera data foreach(int isoSetting, anImagingCameraData->getGainSelectionRange()) { - ui->isoDiscreteSelector->addItem(QString::number(isoSetting)); + ui->gainISODiscreteSelector->addItem(QString::number(isoSetting)); } - ui->isoDiscreteSelector->setCurrentIndex(0); + ui->gainISODiscreteSelector->setCurrentIndex(0); // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Data Gain min " + QString::number(anImagingCameraData->getGainMin()); // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Data Gain max " + QString::number(anImagingCameraData->getGainMax()); - ui->gainSelectionISODiscreteFrame->setEnabled(true); - ui->gainSelectionISODiscreteFrame->setVisible(true); + showGainSelectionISODiscreteWidgets(); break; case OptimalExposure::GAIN_SELECTION_TYPE_NORMAL: // qCInfo(KSTARS_EKOS_CAPTURE) << "Gain Selection Type: GAIN_SELECTION_TYPE_NORMAL"; - ui->gainSelectionFixedFrame->setEnabled(false); - ui->gainSelectionFixedFrame->setVisible(false); - ui->gainSelectionISODiscreteFrame->setEnabled(false); - ui->gainSelectionISODiscreteFrame->setVisible(false); - ui->gainSelectionNormalFrame->setEnabled(true); - ui->gainSelectionNormalFrame->setVisible(true); + + hideGainSelectionWidgets(); + showGainSelectionNormalWidgets(); // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Data Gain min " + QString::number(anImagingCameraData->getGainMin()); // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Data Gain max " + QString::number(anImagingCameraData->getGainMax()); break; @@ -600,11 +761,69 @@ anOptimalSubExposureCalculator = new OptimalExposure::OptimalSubExposureCalculator(aNoiseTolerance, aSkyQualityValue, aFocalRatioValue, aFilterCompensationValue, *anImagingCameraData); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Calculating... "; + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Noise Tolerance " << anOptimalSubExposureCalculator->getANoiseTolerance(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Sky Quality " << anOptimalSubExposureCalculator->getASkyQuality(); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Focal Ratio " << anOptimalSubExposureCalculator->getAFocalRatio(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Filter Compensation Value (ignored): " << anOptimalSubExposureCalculator->getAFilterCompensation(); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Camera Gain Min " << anOptimalSubExposureCalculator->getImagingCameraData().getGainMin(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Camera Gain Max " << anOptimalSubExposureCalculator->getImagingCameraData().getGainMax(); + } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + +void refreshStackTable(Ui::ExposureCalculatorDialog *ui, + OptimalExposure::OptimalExposureDetail *subExposureDetail) +{ + QTableWidget *resultStackTable = ui->exposureStackResult; + + int stackSummarySize = subExposureDetail->getStackSummary().size(); + resultStackTable->setRowCount(stackSummarySize); + + for(int stackSummaryIndex = 0; stackSummaryIndex < stackSummarySize; stackSummaryIndex++) + { + OptimalExposure::OptimalExposureStack anOptimalExposureStack = subExposureDetail->getStackSummary()[stackSummaryIndex]; + + resultStackTable->setItem(stackSummaryIndex, 0, + new QTableWidgetItem(QString::number(anOptimalExposureStack.getPlannedTime()))); + resultStackTable->item(stackSummaryIndex, 0)->setTextAlignment(Qt::AlignCenter); + + resultStackTable->setItem(stackSummaryIndex, 1, + new QTableWidgetItem(QString::number(anOptimalExposureStack.getExposureCount()))); + resultStackTable->item(stackSummaryIndex, 1)->setTextAlignment(Qt::AlignRight); + + resultStackTable->setItem(stackSummaryIndex, 2, + new QTableWidgetItem(QString::number(anOptimalExposureStack.getStackTime()))); + resultStackTable->item(stackSummaryIndex, 2)->setTextAlignment(Qt::AlignRight); + + resultStackTable->setItem(stackSummaryIndex, 3, + new QTableWidgetItem(QString::number(anOptimalExposureStack.getStackTotalNoise(), 'f', 2))); + resultStackTable->item(stackSummaryIndex, 3)->setTextAlignment(Qt::AlignRight); + + double ratio = anOptimalExposureStack.getStackTime() / anOptimalExposureStack.getStackTotalNoise(); + resultStackTable->setItem(stackSummaryIndex, 4, new QTableWidgetItem(QString::number(ratio, 'f', 2))); + resultStackTable->item(stackSummaryIndex, 4)->setTextAlignment(Qt::AlignRight); + + resultStackTable->setRowHeight(stackSummaryIndex, 22); + /* + qCInfo(KSTARS_EKOS_CAPTURE) << "Stack info: Hours: " << anOptimalExposureStack.getPlannedTime() + << " Exposure Count: " << anOptimalExposureStack.getExposureCount() + << " Stack Time: " << anOptimalExposureStack.getStackTime() + << " Stack Total Noise: " << anOptimalExposureStack.getStackTotalNoise(); + */ + + /* + 2023-10 Add plot of the ratio of Total Noise to Stack Integration Time into new plot widget qCustomPlotIntegrationNoise + */ + + } + resultStackTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + +} + + void ExposureCalculatorDialog::calculateSubExposure(double aNoiseTolerance, double aSkyQualityValue, double aFocalRatioValue, double aFilterCompensationValue, int aSelectedReadMode, int aSelectedGainValue) { @@ -616,15 +835,44 @@ anOptimalSubExposureCalculator->setASelectedCameraReadMode(aSelectedReadMode); anOptimalSubExposureCalculator->setASelectedGain(aSelectedGainValue); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "initializeSubExposureComputer"; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taNoiseTolerance: " << aNoiseTolerance; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taSkyQualityValue: " << aSkyQualityValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taFocalRatioValue: " << aFocalRatioValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taFilterCompensation: (ignored) " << aFilterCompensationValue; + // qCInfo(KSTARS_EKOS_CAPTURE) << "\taSelectedGainValue: " << aSelectedGainValue; + anOptimalSubExposureCalculator->setAFilterCompensation(aFilterCompensationValue); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Calculating... "; + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Noise Tolerance " << anOptimalSubExposureCalculator->getANoiseTolerance(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Sky Quality " << anOptimalSubExposureCalculator->getASkyQuality(); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Focal Ratio " << anOptimalSubExposureCalculator->getAFocalRatio(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Filter Compensation Value (ignored): " << anOptimalSubExposureCalculator->getAFilterCompensation(); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Camera Gain Min " << anOptimalSubExposureCalculator->getImagingCameraData().getGainMin(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "A Camera Gain Max " << anOptimalSubExposureCalculator->getImagingCameraData().getGainMax(); + + OptimalExposure::CameraExposureEnvelope aCameraExposureEnvelope = anOptimalSubExposureCalculator->calculateCameraExposureEnvelope(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a set of: " << aCameraExposureEnvelope.getASubExposureVector().size(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a minimum Exposure Time of " << aCameraExposureEnvelope.getExposureTimeMin(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Envelope has a maximum Exposure Time of " << aCameraExposureEnvelope.getExposureTimeMax(); - OptimalExposure::OptimalExposureDetail subExposureDetail = anOptimalSubExposureCalculator->calculateSubExposureDetail( - aSelectedGainValue); + + //OptimalExposure::OptimalExposureDetail subExposureDetail = anOptimalSubExposureCalculator->calculateSubExposureDetail( + // aSelectedGainValue); + + + aSubExposureDetail = anOptimalSubExposureCalculator->calculateSubExposureDetail(); // Get the exposure details into the ui - plotSubExposureEnvelope(ui, anOptimalSubExposureCalculator, &subExposureDetail); + //ui->exposureCalculatonResult. + + plotSubExposureEnvelope(ui, anOptimalSubExposureCalculator, &aSubExposureDetail); + if(ui->gainSelector->isEnabled()) { // realignGainSlider(); @@ -632,58 +880,48 @@ ui->gainSelector->setMinimum(anOptimalSubExposureCalculator->getImagingCameraData().getGainMin()); } - ui->subExposureTime->setText(QString::number(subExposureDetail.getSubExposureTime(), 'f', 2)); - ui->subPollutionElectrons->setText(QString::number(subExposureDetail.getExposurePollutionElectrons(), 'f', 0)); - ui->subShotNoise->setText(QString::number(subExposureDetail.getExposureShotNoise(), 'f', 2)); - ui->subTotalNoise->setText(QString::number(subExposureDetail.getExposureTotalNoise(), 'f', 2)); + ui->subExposureTime->setText(QString::number(aSubExposureDetail.getSubExposureTime(), 'f', 2)); + ui->subPollutionElectrons->setText(QString::number(aSubExposureDetail.getExposurePollutionElectrons(), 'f', 0)); + ui->subShotNoise->setText(QString::number(aSubExposureDetail.getExposureShotNoise(), 'f', 2)); + ui->subTotalNoise->setText(QString::number(aSubExposureDetail.getExposureTotalNoise(), 'f', 2)); + + + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Pollution Electrons: " << subExposureDetail.getExposurePollutionElectrons(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Shot Noise: " << subExposureDetail.getExposureShotNoise(); + // qCInfo(KSTARS_EKOS_CAPTURE) << "Exposure Total Noise: " << subExposureDetail.getExposureTotalNoise(); + QTableWidget *resultStackTable = ui->exposureStackResult; resultStackTable->setColumnCount(5); resultStackTable->verticalHeader()->setVisible(false); QStringList stackDetailHeaders; - stackDetailHeaders << "Planned Hours" << "Exposure Count" << "Stack Time" << "Stack Noise" << "Ratio"; + stackDetailHeaders << "Planned Hours" << "Exposure Count" << "Stack Time" << "Noise" << "Ratio"; resultStackTable->setHorizontalHeaderLabels(stackDetailHeaders); resultStackTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter | (Qt::Alignment)Qt::TextWordWrap); resultStackTable->horizontalHeader()->setFixedHeight(32); - int stackSummarySize = subExposureDetail.getStackSummary().size(); - resultStackTable->setRowCount(stackSummarySize); - - for(int stackSummaryIndex = 0; stackSummaryIndex < stackSummarySize; stackSummaryIndex++) - { - OptimalExposure::OptimalExposureStack anOptimalExposureStack = subExposureDetail.getStackSummary()[stackSummaryIndex]; - - resultStackTable->setItem(stackSummaryIndex, 0, - new QTableWidgetItem(QString::number(anOptimalExposureStack.getPlannedTime()))); - resultStackTable->item(stackSummaryIndex, 0)->setTextAlignment(Qt::AlignCenter); + resultStackTable->horizontalHeaderItem(1)->setToolTip("Sub-exposure count in stacked image"); + resultStackTable->horizontalHeaderItem(2)->setToolTip("Integration time of stacked image (seconds)"); + resultStackTable->horizontalHeaderItem(3)->setToolTip("Total Noise in Stacked Image"); + resultStackTable->horizontalHeaderItem(4)->setToolTip("Integration time to noise ratio (potential quality)"); + + /* + double initializedTargetNoiseRatio = ceil((100.0 * aSubExposureDetail.getSubExposureTime()) / + aSubExposureDetail.getExposureTotalNoise()) / 10.0; - resultStackTable->setItem(stackSummaryIndex, 1, - new QTableWidgetItem(QString::number(anOptimalExposureStack.getExposureCount()))); - resultStackTable->item(stackSummaryIndex, 1)->setTextAlignment(Qt::AlignRight); + // Reinitialize the time/noise input in the stack calculator to produce a stack of 100 images. + ui->targetNoiseRatio->setValue(initializedTargetNoiseRatio); - resultStackTable->setItem(stackSummaryIndex, 2, - new QTableWidgetItem(QString::number(anOptimalExposureStack.getStackTime()))); - resultStackTable->item(stackSummaryIndex, 2)->setTextAlignment(Qt::AlignRight); + */ + refreshStackTable(ui, &aSubExposureDetail); - resultStackTable->setItem(stackSummaryIndex, 3, - new QTableWidgetItem(QString::number(anOptimalExposureStack.getStackTotalNoise(), 'f', 2))); - resultStackTable->item(stackSummaryIndex, 3)->setTextAlignment(Qt::AlignRight); + plotIntegratedNoise(ui, &aSubExposureDetail); - double ratio = anOptimalExposureStack.getStackTime() / anOptimalExposureStack.getStackTotalNoise(); - resultStackTable->setItem(stackSummaryIndex, 4, new QTableWidgetItem(QString::number(ratio, 'f', 2))); - resultStackTable->item(stackSummaryIndex, 4)->setTextAlignment(Qt::AlignRight); - - resultStackTable->setRowHeight(stackSummaryIndex, 22); +} - } - resultStackTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); -} -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// void ExposureCalculatorDialog::refreshCameraSelector(Ui::ExposureCalculatorDialog *ui, QStringList availableCameraFileNames, const QString aPreferredCameraId) { @@ -695,9 +933,19 @@ int preferredIndex = 0; ui->imagingCameraSelector->clear(); - for(auto &filename : availableCameraFileNames) + /* + * 2023-10-05 Added sorting to the filelist, but the full path is included in this + * list, and since camera data can come from either the applicaton folder, or a user local folder + * the sort result can produce two groupings of sorted camera ids. + * In Linux, files from the user local folder will appear first in the QCombo. + */ + availableCameraFileNames.sort(); + + foreach(QString filename, availableCameraFileNames) { - auto aCameraId = OptimalExposure::FileUtilityCameraData::cameraDataFileNameToCameraId(filename); + QString aCameraId = OptimalExposure::FileUtilityCameraData::cameraDataFileNameToCameraId(filename); + + // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Filename: " << filename << " Camera Id:" << aCameraId; ui->imagingCameraSelector->addItem(aCameraId, filename); if(aPreferredCameraId != nullptr && aPreferredCameraId.length() > 0) @@ -711,25 +959,20 @@ } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// + ExposureCalculatorDialog::~ExposureCalculatorDialog() { delete ui; } -/////////////////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////////////////// void ExposureCalculatorDialog::on_downloadCameraB_clicked() { // User may want to add more camera files. - FileUtilityCameraDataDialog aCameraDownloadDialog(KStars::Instance(), aPreferredCameraId); + FileUtilityCameraDataDialog aCameraDownloadDialog(this, aPreferredCameraId); aCameraDownloadDialog.setWindowModality(Qt::WindowModal); aCameraDownloadDialog.exec(); - // This refresh is causing an error because the combobox->clear is + // Using refresh is causing an error because the combobox->clear is // making the selection change. Need to resolve this. // but for now, if a user adds more cameras they will be available // in the exposure calculator on the next start. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,6 +6,9 @@ #pragma once +#ifndef EXPOSURECALCULATORDIALOG_H +#define EXPOSURECALCULATORDIALOG_H + #include #include "optimalsubexposurecalculator.h" @@ -20,19 +23,19 @@ { Q_OBJECT - public: + public: + // ExposureCalculatorDialog(QWidget *parent = nullptr); ExposureCalculatorDialog(QWidget *parent = nullptr, double aPreferredSkyQualityValue = 20.0, double aPreferredFocalRatioValue = 5.0, - const QString &aPreferredCameraId = QString()); + const QString &aPreferredCameraId = ""); ~ExposureCalculatorDialog(); public slots: - // This method is acting as a "fill-in" for initiating the calculator with data from KStars ekos/indi - void applyInitialInputs(); - // Change to gain, does not change exposure envelope, but does require recalculation of shot - void handleUserAdjustment(); + void applyInitialInputs(); // This method is acting as a "fill-in" for initiating the calculator with data from KStars ekos/indi + void handleUserAdjustment(); // Change to gain, does not change exposure envelope, but does require recalculation of shot + void handleStackCalculation(); private slots: void on_downloadCameraB_clicked(); @@ -58,4 +61,11 @@ void refreshCameraSelector(Ui::ExposureCalculatorDialog *ui, QStringList availableCameraFileNames, const QString aPreferredCameraId); + void hideGainSelectionWidgets(); + void showGainSelectionFixedWidgets(); + void showGainSelectionNormalWidgets(); + void showGainSelectionISODiscreteWidgets(); + + }; +#endif // EXPOSURECALCULATORDIALOG_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/exposurecalculatordialog.ui 2023-12-03 05:23:17.000000000 +0000 @@ -7,531 +7,938 @@ 0 0 438 - 608 + 713 + + + 0 + 0 + + 438 - 608 + 713 - 438 - 608 + 16777215 + 16777215 Sub-Exposure Calculator - - - true - - - - 10 - 10 - 421 - 591 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 340 - 340 - 71 - 27 - - - - Adjust the balance of the two noise sources - - - - - - 204 - 340 - 131 - 27 - - - - Noise Increase (%) - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 10 - 130 - 401 - 201 - - - - Potential exposure time graph - - - - - - 10 - 446 - 401 - 131 - - - - - - - 10 - 10 - 91 - 27 - - - - Sky Quality - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - 100 - 10 - 82 - 27 - - - - Adjust the quality of the sky - - - 3 - - - - - - 230 - 40 - 111 - 27 - - - - Filter Bandwidth: - - - - - - 10 - 335 - 171 - 32 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 10 - 3 - 41 - 27 - - - - Gain - - - - - - 60 - 3 - 101 - 27 - - - - - - - - 10 - 335 - 171 - 32 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 60 - 3 - 101 - 27 - - - - - - - 10 - 3 - 41 - 27 - - - - ISO - - - - - - - 10 - 335 - 171 - 32 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 10 - 3 - 141 - 27 - + + + + + true + + + + + + true - - Read noise constant + + + 0 + 0 + - - Qt::AlignCenter + + QFrame::StyledPanel - - - - - - 370 - 10 - 27 - 27 - - - - Bortle Zone Color - - - - - - 100 - 40 - 82 - 27 - - - - - - - 10 - 40 - 71 - 27 - - - - Focal Ratio - - - - - - 100 - 70 - 308 - 27 - - - - - - - 10 - 70 - 51 - 27 - - - - Camera - - - - - - 230 - 10 - 81 - 27 - - - - Bortle Class: - - - - - - 343 - 40 - 65 - 27 - - - - Apply a compensation for an optical filter - - - 1 - - - - - - 320 - 10 - 41 - 27 - - - - Bortle class value - - - 9 - - - Qt::AlignCenter - - - - - - 100 - 100 - 308 - 27 - - - - Select read mode on cameras with multiple read modes. - - - - - - 10 - 100 - 81 - 27 - - - - Read Mode - - - - - - 10 - 370 - 399 - 71 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 0 - 9 - 391 - 51 - + + QFrame::Raised - - - 6 - - - 1 - - - 1 - - - + + + - Exposure Time (sec) + Sky Quality + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true - - - - QFrame::StyledPanel + + + + Focal Ratio + + + + + + + + 126 + 0 + - + Filter Bandwidth - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 + 0 + + + + + 72 + 0 + + + + Alter the bias of the noise sources - - + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + - Shot Noise + Camera - - - - Noise in the sub-exposure from light pollution + + + + + 107 + 0 + + + + Bortle Class + + + + + + + + 0 + 0 + + + + + 180 + 32 + + + + QFrame::StyledPanel + + QFrame::Raised + + + + + 10 + 3 + 72 + 27 + + + + + 72 + 27 + + + + + 10 + + + + Gain + + + + + + 90 + 3 + 81 + 27 + + + + + 0 + 0 + + + + + 81 + 27 + + + + Select Camera Sensor Gain + + + + + + 90 + 3 + 81 + 27 + + + + + 0 + 0 + + + + Select DSLR ISO Value + + + + + + 10 + 3 + 72 + 27 + + + + + 72 + 27 + + + + ISO + + + + + + 10 + 3 + 151 + 27 + + + + + 0 + 0 + + + + Read noise constant + + + Qt::AlignCenter + + + gainISODiscreteSelector + gainSelectionFixedLabel + gainSpinnerLabel + gainSelector + gainISOSelectorLabel + + + + QFrame::StyledPanel + + QFrame::Raised + + + + 2 + + + 2 + + + + + 6 + + + 1 + + + 1 + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Noise in the sub-exposure from light pollution + + + QFrame::StyledPanel + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Total Noise + + + + + + + Pollution Electrons + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Total noise in the sub-exposure (light pollution + read-noise) + + + QFrame::StyledPanel + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Shot Noise + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Estimated light pollution electrons in the sub-exposure. + + + QFrame::StyledPanel + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Duration of Sub-exposure + + + QFrame::StyledPanel + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Exposure Time (sec) + + + + + + + + + + + + + 62 + 0 + + - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - + + + + true + + + + 0 + 0 + + + + + 32 + 16777215 + + + + Download additional camera data files + - Pollution Electrons + + + + + false - - + + + + + 0 + 0 + + + + + 28 + 28 + + + + + 28 + 28 + + - Calculated count of light pollution electrons in the sub-exposure. + Bortle Zone Color - - QFrame::StyledPanel + + + + + + + 40 + 0 + + + + + 40 + 40 + + + + Bortle class value - + 9 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Select read mode on cameras with multiple read modes. + + + + + + + + 0 + 0 + + + + + 80 + 27 + + + + Adjust the quality of the sky + + + 3 + + + + + - Total Noise + Read Mode + + + + + + + + 0 + 0 + + + + + 48 + 27 + + + + + 16777215 + 16777215 + + + + Apply a compensation for an optical filter + + + 1 - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Total noise in the sub-exposure (light pollution + read-noise) + Camera Data Selection - - QFrame::StyledPanel + + + + + + + 0 + 0 + + + + + 80 + 27 + + + + + + + + + 0 + 0 + + + + + 0 + 180 + + + + Potential exposure time graph + + + + + + + + 0 + 0 + + + + + 122 + 27 + - + Noise Increase % - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + 0 + 192 + + + + 1 + + + + Table + + + + + + + 380 + 140 + + + + + + + + + Graph + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Slope of time to noise ratio curve at current exposure count + + + + + + + + + + + 0 + 0 + + + + + 67 + 0 + + + + Exposures + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Calculated exposure count for integration + + + -- + + + + + + + + 0 + 0 + + + + + 378 + 100 + + + + Integration Time to Noise Ratio + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + Time/Noise Ratio + + + + + + + + 0 + 0 + + + + + 19 + 0 + + + + dy = + + + + + + + + 68 + 0 + + + + Integration time to noise ratio (potential quality) + + + 1 + + + 2000.000000000000000 + + + 80.000000000000000 + + + + + + + + qCustomPlotSubExposure + gainSelectionFrame + noiseTolerance + SQMLabel + userSkyQuality + skyQualityColor + indiFocalRatio + indiFocalRationLabel + imagingCameraSelector + indiCameraLabel + bortleScaleValue + cameraReadModeSelector + indiCameraReadMode + calculationResult + downloadCameraB + horizontalSpacer + horizontalSpacer_2 + horizontalSpacer_5 + SensorType + filterBandwidth + allowableNoiseLabel + label + bortleScaleLabel + tabWidget - - - - false - - - - 70 - 70 - 27 - 27 - - - - (Future Release) Download additional camera data files - - - + - - - + + @@ -541,6 +948,20 @@ 1 + + userSkyQuality + indiFocalRatio + filterBandwidth + imagingCameraSelector + cameraReadModeSelector + gainSelector + gainISODiscreteSelector + noiseTolerance + targetNoiseRatio + tabWidget + exposureStackResult + downloadCameraB + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -4,7 +4,8 @@ SPDX-License-Identifier: GPL-2.0-or-later */ - +#include +#include #include #include #include @@ -19,33 +20,35 @@ #include #include #include - #include "fileutilitycameradata.h" -#include "fileutilitycameradatadialog.h" #include "imagingcameradata.h" #include "cameragainreadnoise.h" - +#include "exposurecalculatordialog.h" #include +#include #include +/* + * Direct access to files on KDE/kstars git repository: + */ QString const OptimalExposure::FileUtilityCameraData::cameraDataRemoteRepositoryList - = "https://api.github.com/repos/Stingray65/ExposureCalculatorCameraData/git/trees/main?recursive=1"; + = "https://api.github.com/repos/KDE/kstars/git/trees/master:kstars%2Fdata%2Fcameradata"; QString const OptimalExposure::FileUtilityCameraData::cameraDataRemoteRepository - = "https://raw.githubusercontent.com/Stingray65/ExposureCalculatorCameraData/main/github_repo_cameradata_v1/exposure_calculator/"; + = "https://raw.githubusercontent.com/KDE/kstars/master/kstars/data/cameradata/"; QString const OptimalExposure::FileUtilityCameraData::cameraApplicationDataRepository = KSPaths::locate(QStandardPaths::AppDataLocation, QString("cameradata/"), QStandardPaths::LocateDirectory); QString const OptimalExposure::FileUtilityCameraData::cameraLocalDataRepository - = KSPaths::locate(QStandardPaths::AppLocalDataLocation, QString("cameradata/"), QStandardPaths::LocateDirectory); - + = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("kstars/cameradata/"); QStringList OptimalExposure::FileUtilityCameraData::getAvailableCameraFilesList() { QStringList cameraDataFiles; QStringList dirs; + dirs << KSPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("kstars/cameradata"), QStandardPaths::LocateDirectory); @@ -59,6 +62,7 @@ cameraDataFiles.append(it.next()); } } + return(cameraDataFiles); } @@ -97,20 +101,24 @@ QDialog *aDialog) { - // Could not find an easy way to read a file listing from a folder in github. - // So relying upon git tree, but this approach requires parsing a large tree - // string for just the xml file names. - FileUtilityCameraDataDialog *activeDialog = static_cast (aDialog); - activeDialog->setANetworkAccessManager(new QNetworkAccessManager(activeDialog)); + qCInfo(KSTARS_EKOS_CAPTURE) << "cameraDataRemoteRepositoryList: " << + OptimalExposure::FileUtilityCameraData::cameraDataRemoteRepositoryList; + qCInfo(KSTARS_EKOS_CAPTURE) << "cameraDataRemoteRepository: " << + OptimalExposure::FileUtilityCameraData::cameraDataRemoteRepository; + // qCInfo(KSTARS_EKOS_CAPTURE) << "cameraApplicationDataRepository: " << OptimalExposure::FileUtilityCameraData::cameraApplicationDataRepository; + qCInfo(KSTARS_EKOS_CAPTURE) << "cameraLocalDataRepository: " << + OptimalExposure::FileUtilityCameraData::cameraLocalDataRepository; + // Using git tree to access camera file list, this approach requires parsing the tree + // string collect the xml (camera data) file names. + FileUtilityCameraDataDialog *activeDialog = static_cast (aDialog); + activeDialog->setANetworkAccessManager(new QNetworkAccessManager(activeDialog)); QString aCameraDataRemoteFolderURL = OptimalExposure::FileUtilityCameraData::cameraDataRemoteRepositoryList; qCInfo(KSTARS_EKOS_CAPTURE) << "Attempting access of camera data file repository " << aCameraDataRemoteFolderURL; - - QNetworkRequest activeRequest = QNetworkRequest(QUrl(aCameraDataRemoteFolderURL)); activeDialog->setRequest(&activeRequest); activeDialog->setReply(activeDialog->getANetworkAccessManager()->get(activeRequest)); @@ -124,12 +132,6 @@ }); QVector *availableCameraDataFiles = new QVector(); - // Could just hard-code a few for testing - // availableCameraDataFiles.append("ZWO_CCD_ASI071MC_Pro.xml"); - // availableCameraDataFiles.append("ZWO_CCD_ASI178MC.xml"); - // availableCameraDataFiles.append("QHY_CCD_268M.xml"); - - activeDialog->connect(activeReply, &QNetworkReply::finished, activeDialog, @@ -143,30 +145,39 @@ return; } - // Need to parse the reply here + // Parse out the filenames from the tree std::string responseDataStr = activeReply->readAll().toStdString(); - std::size_t index = 0; + // qCInfo(KSTARS_EKOS_CAPTURE) << "Camera Data File Github Tree:\n" << QString::fromStdString(responseDataStr); + + std::string startdelimiter = "["; + std::string stopdelimiter = "]"; + std::string treeStr = responseDataStr.substr(responseDataStr.find(startdelimiter) + 1, responseDataStr.find(stopdelimiter) - responseDataStr.find(startdelimiter)); + + std::vector tokens; + std::stringstream responseDataStream(treeStr); - std::string prefixStr = "/exposure_calculator/"; - std::string fileExtStr = ".xml"; + std::string intermediate; - std::size_t filePrefixIndex = responseDataStr.find(prefixStr, index); - while(filePrefixIndex != -1) + while(getline(responseDataStream, intermediate, ',')) { - std::size_t fileNameIndex = filePrefixIndex + prefixStr.length(); + tokens.push_back(intermediate); + } - std::size_t fileExtStrIndex = responseDataStr.find(fileExtStr, fileNameIndex); - std::size_t fileFullNameLength = fileExtStrIndex + fileExtStr.length() - fileNameIndex; + // Find the camera file name + for(int i = 0; i < tokens.size(); i++) + { + if(tokens[i].find("path") != std::string::npos) + { - std::string aCameraDataFileStr = responseDataStr.substr(fileNameIndex, fileFullNameLength); - QString aCameraDataFile = QString::fromStdString(aCameraDataFileStr); + std::string aCameraDataFileStr = tokens[i].substr(9, tokens[i].length() - 14); + // std::cout << aCameraDataFileStr << '\n'; - availableCameraDataFiles->append(aCameraDataFile); + QString aCameraDataFile = QString::fromStdString(aCameraDataFileStr); - index = fileNameIndex + aCameraDataFile.length(); - filePrefixIndex = responseDataStr.find(prefixStr, index); + availableCameraDataFiles->append(aCameraDataFile); + } } activeDialog->setAvailableCameraDataFiles(*availableCameraDataFiles); activeDialog->refreshCameraList(); @@ -218,6 +229,11 @@ QString aCameraDataLocalFileName = OptimalExposure::FileUtilityCameraData::cameraLocalDataRepository + cameraDataFileName; + //QString aCameraDataLocalFileName = KSPaths::locate(QStandardPaths::AppLocalDataLocation, + // QString("cameradata/%1").arg(cameraDataFileName)); + + + qCInfo(KSTARS_EKOS_CAPTURE) << "Attempting Download Camera Data from " << aCameraDataDownloadURL << "\n\tto " << aCameraDataLocalFileName; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradata.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,16 +6,21 @@ #pragma once +#ifndef FILEUTILITYCAMERADATA_H +#define FILEUTILITYCAMERADATA_H + #include #include #include #include #include #include -#include #include "imagingcameradata.h" +#include "cameragainreadnoise.h" +#include "fileutilitycameradatadialog.h" #include +QT_BEGIN_NAMESPACE namespace OptimalExposure { class FileUtilityCameraData @@ -44,3 +49,6 @@ QString static const cameraDataRemoteRepository; }; } + +QT_END_NAMESPACE +#endif // FILEUTILITYCAMERADATA_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -7,17 +7,16 @@ #include #include #include -#include "fileutilitycameradatadialog.h" -#include "ui_fileutilitycameradatadialog.h" - +#include "fileutilitycameradata.h" +#include "./ui_fileutilitycameradatadialog.h" #include FileUtilityCameraDataDialog::FileUtilityCameraDataDialog( QWidget *parent, const QString &aPreferredCameraId) : QDialog(parent), - ui(new Ui::FileUtilityCameraDataDialog), - aPreferredCameraId(aPreferredCameraId) + aPreferredCameraId(aPreferredCameraId), + ui(new Ui::FileUtilityCameraDataDialog) { ui->setupUi(this); @@ -25,6 +24,9 @@ connect(ui->downloadB, &QPushButton::clicked, this, &FileUtilityCameraDataDialog::startCameraDownload); + // ui->buttonBox-> + // ui->buttonBox->Cancel + ui->availableRemoteCameraList->clear(); ui->availableRemoteCameraList->setSelectionMode(QAbstractItemView::ExtendedSelection); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,13 +6,18 @@ #pragma once +#ifndef FILEUTILITYCAMERADATADIALOG_H +#define FILEUTILITYCAMERADATADIALOG_H + #include "fileutilitycameradata.h" #include +QT_BEGIN_NAMESPACE namespace Ui { class FileUtilityCameraDataDialog; } +QT_END_NAMESPACE class FileUtilityCameraDataDialog : public QDialog { @@ -58,3 +63,4 @@ int downloadFileCounter; }; +#endif // FILEUTILITYCAMERADATADIALOG_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui 2023-12-03 05:23:17.000000000 +0000 @@ -10,11 +10,11 @@ 0 0 320 - 290 + 292 - + 0 0 @@ -27,78 +27,95 @@ - 320 - 290 + 16777215 + 16777215 Camera Data Download - - - - 220 - 250 - 91 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - - - - 10 - 32 - 301 - 211 - - - - - - - 10 - 10 - 291 - 17 - - - - Select all cameras you wish to use: - - - - - - 128 - 253 - 91 - 26 - - - - Download - - - - - - 20 - 256 - 51 - 22 - - - - - - + + true + + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Download + + + + + + + Qt::Horizontal + + + + 93 + 20 + + + + + + + + + 0 + 0 + + + + + 100 + 3 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel + + + + + + + Select all cameras you wish to use: + + + + + + + + 60 + 0 + + + + + + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/genericfilterdata.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/genericfilterdata.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/genericfilterdata.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/genericfilterdata.h 2023-12-03 05:23:17.000000000 +0000 @@ -1,13 +1,8 @@ -/* - SPDX-FileCopyrightText: 2023 Joseph McGee - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#pragma once - +#ifndef GENERICFILTERDATA_H +#define GENERICFILTERDATA_H #include +QT_BEGIN_NAMESPACE namespace OptimalExposure { @@ -32,4 +27,4 @@ }; } - +#endif // GENERICFILTERDATA_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/imagingcameradata.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/imagingcameradata.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/imagingcameradata.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/imagingcameradata.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,10 +6,15 @@ #pragma once +#ifndef IMAGINGCAMERADATA_H +#define IMAGINGCAMERADATA_H + #include #include #include "cameragainreadmode.h" +#include "cameragainreadnoise.h" +QT_BEGIN_NAMESPACE namespace OptimalExposure { @@ -66,5 +71,5 @@ }; } - - +QT_END_NAMESPACE +#endif // IMAGINGCAMERADATA_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposuredetail.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposuredetail.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposuredetail.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposuredetail.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,6 +6,8 @@ #pragma once +#ifndef OPTIMALEXPOSUREDETAIL_H +#define OPTIMALEXPOSUREDETAIL_H #include #include #include "optimalexposurestack.h" @@ -45,3 +47,4 @@ } QT_END_NAMESPACE +#endif // OPTIMALEXPOSUREDETAIL_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposurestack.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposurestack.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposurestack.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalexposurestack.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,8 +6,11 @@ #pragma once +#ifndef OPTIMALEXPOSURESTACK_H +#define OPTIMALEXPOSURESTACK_H #include +QT_BEGIN_NAMESPACE namespace OptimalExposure { class OptimalExposureStack @@ -32,3 +35,8 @@ double stackTotalNoise; }; } +QT_END_NAMESPACE + + + +#endif // OPTIMALEXPOSURESTACK_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -11,7 +11,6 @@ #include "calculatedgainsubexposuretime.h" #include "cameraexposureenvelope.h" #include "optimalexposuredetail.h" - #include namespace OptimalExposure @@ -216,6 +215,7 @@ double OptimalSubExposureCalculator::calculateCFactor(double aNoiseTolerance) { // cFactor = 1/( (((100+allowableNoiseIncreasePercent)/100)^2) -1) + return((double) (1 / ( pow((((double)100 + (double) aNoiseTolerance) / (double)100), (double)2) - 1))); } @@ -225,6 +225,16 @@ // Conversion curve fitted from Dr Glover data double base = std::stod("1.25286030612621E+27"); double power = (double) -19.3234809465887; + + // New version of Dr Glover's function calculates the Electron rate at thet pixel level + // and requires pixel size in microns and QE of sensor. + // double baseV2 = 1009110388.7838 + // Calculation of an initial electron rate will + // use a new fitted curve based upon a 1.0 micon pixel and 100% QE + // curve appears to be f(sqm) = 1009110388.7838 exp (-0.921471189594521 * sqm) + // + + return(base * pow(skyQuality, power)); } @@ -237,29 +247,32 @@ */ double lightPollutionElectronBaseRate = OptimalSubExposureCalculator::calculateLightPollutionElectronBaseRate(aSkyQuality); - //qCInfo(KSTARS_EKOS_CAPTURE) << "Calculating CameraExposureEnvelope..."; - // << "Using Sky Quality: " << aSkyQuality; - // << "\tConverted to lightPollutionElectronBaseRate: " << lightPollutionElectronBaseRate; - // << "Using an Optical Focal Ratio: " << aFocalRatio; - + /* + qCInfo(KSTARS_EKOS_CAPTURE) << "Calculating CameraExposureEnvelope..." + << "Using Sky Quality: " << aSkyQuality + << "\nConverted to lightPollutionElectronBaseRate: " << lightPollutionElectronBaseRate + << "Using an Optical Focal Ratio: " << aFocalRatio; + */ double lightPollutionForOpticFocalRatio = calculateLightPolutionForOpticFocalRatio(lightPollutionElectronBaseRate, aFocalRatio, aFilterCompensation); - //qCInfo(KSTARS_EKOS_CAPTURE) - // << "\tResulting in an Light Pollution Rate for the Optic of: " - // << lightPollutionForOpticFocalRatio; - + /* + qCInfo(KSTARS_EKOS_CAPTURE) + << "\tResulting in an Light Pollution Rate for the Optic of: " + << lightPollutionForOpticFocalRatio; + */ // qCDebug(KSTARS_EKOS_CAPTURE) << "Using a camera Id: " << anImagingCameraData.getCameraId(); OptimalExposure::CameraGainReadMode aSelectedReadMode = anImagingCameraData.getCameraGainReadModeVector()[aSelectedCameraReadMode]; - // qCInfo(KSTARS_EKOS_CAPTURE) << "\t with camera read mode: " - // << aSelectedReadMode.getCameraGainReadModeName(); - // << "\tWith a read-noise table of : " - // << aSelectedReadMode.getCameraGainReadNoiseVector().size() << " values"; - + /* + qCInfo(KSTARS_EKOS_CAPTURE) << "\t with camera read mode: " + << aSelectedReadMode.getCameraGainReadModeName() + << "\tWith a read-noise table of : " + << aSelectedReadMode.getCameraGainReadNoiseVector().size() << " values"; + */ // qCInfo(KSTARS_EKOS_CAPTURE) << "Using a Noise Tolerance of: " << aNoiseTolerance; double cFactor = calculateCFactor(aNoiseTolerance); - // qCDebug(KSTARS_EKOS_CAPTURE) << "Calculated CFactor is: " << cFactor; + // qCInfo(KSTARS_EKOS_CAPTURE) << "Calculated CFactor is: " << cFactor; QVector aSubExposureTimeVector = calculateGainSubExposureVector(cFactor, lightPollutionForOpticFocalRatio); @@ -285,7 +298,8 @@ return(aCameraExposureEnvelope); } -OptimalExposure::OptimalExposureDetail OptimalSubExposureCalculator::calculateSubExposureDetail(int aSelectedGainValue) +// OptimalExposure::OptimalExposureDetail OptimalSubExposureCalculator::calculateSubExposureDetail(int aSelectedGainValue) +OptimalExposure::OptimalExposureDetail OptimalSubExposureCalculator::calculateSubExposureDetail() { /* This method calculates some details for a sub-exposure. It will interpolate between @@ -295,6 +309,7 @@ // qCDebug(KSTARS_EKOS_CAPTURE) << "aSelectedGainValue: " << aSelectedGainValue; + int aSelectedGain = getASelectedGain(); // Look for a matching gain from the camera gain read-noise table, or identify a bracket for interpolation. // Interpolation may result in slight errors when the read-noise data is curve. (there's probably a better way to code this) @@ -308,19 +323,21 @@ QVector aCameraGainReadNoiseVector = aSelectedReadMode.getCameraGainReadNoiseVector(); + + for(int readNoiseIndex = 0; readNoiseIndex < aSelectedReadMode.getCameraGainReadNoiseVector().size(); readNoiseIndex++) { if(!matched) { CameraGainReadNoise aCameraGainReadNoise = aSelectedReadMode.getCameraGainReadNoiseVector()[readNoiseIndex]; - if(aCameraGainReadNoise.getGain() == aSelectedGainValue) + if(aCameraGainReadNoise.getGain() == aSelectedGain) { matched = true; // qCInfo(KSTARS_EKOS_CAPTURE) << " matched a camera gain "; aReadNoise = aCameraGainReadNoise.getReadNoise(); break; } - if(aCameraGainReadNoise.getGain() < aSelectedGainValue) + if(aCameraGainReadNoise.getGain() < aSelectedGain) { lowerReadNoiseIndex = readNoiseIndex; } @@ -343,9 +360,9 @@ // interpolate a read-noise value double m = (anUpperIndexCameraReadNoise.getReadNoise() - aLowerIndexCameraReadNoise.getReadNoise()) / (anUpperIndexCameraReadNoise.getGain() - aLowerIndexCameraReadNoise.getGain()); - aReadNoise = aLowerIndexCameraReadNoise.getReadNoise() + (m * (aSelectedGainValue - aLowerIndexCameraReadNoise.getGain())); + aReadNoise = aLowerIndexCameraReadNoise.getReadNoise() + (m * (aSelectedGain - aLowerIndexCameraReadNoise.getGain())); // qCInfo(KSTARS_EKOS_CAPTURE) - // << "The camera read-noise for the selected gain value is interpolated to: " << aReadNoise; + // << "The camera read-noise for the selected gain value is interpolated to: " << aReadNoise; } else { @@ -361,7 +378,6 @@ // << "The camera read-noise for the selected gain value was matched: " << aReadNoise; } - double anOptimalSubExposure = 0.0; double lightPollutionElectronBaseRate = OptimalSubExposureCalculator::calculateLightPollutionElectronBaseRate(aSkyQuality); @@ -410,10 +426,20 @@ OptimalExposureStack *anOptimalExposureStack = new OptimalExposureStack(sessionHours, anExposureCount, aStackTime, aStackTotalNoise); + + /* + qCInfo(KSTARS_EKOS_CAPTURE) << sessionHours << "\t" << anExposureCount + << "\t" << aStackTime << "\t" << aStackTotalNoise + << "\t" << aStackTime / aStackTotalNoise; + + // << aSelectedGainValue << " is " << anOptimalSubExposure << " seconds"; + */ aStackSummary.push_back(*anOptimalExposureStack); + + } - OptimalExposureDetail anOptimalExposureDetail = OptimalExposureDetail(aSelectedGainValue, anOptimalSubExposure, + OptimalExposureDetail anOptimalExposureDetail = OptimalExposureDetail(getASelectedGain(), anOptimalSubExposure, anExposurePollutionElectrons, anExposureShotNoise, anExposureTotalNoise, aStackSummary); return(anOptimalExposureDetail); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/exposurecalculator/optimalsubexposurecalculator.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,6 +6,8 @@ #pragma once +#ifndef OPTIMALSUBEXPOSURECALCULATOR_H +#define OPTIMALSUBEXPOSURECALCULATOR_H #include #include #include "imagingcameradata.h" @@ -13,6 +15,7 @@ #include "cameraexposureenvelope.h" #include "optimalexposuredetail.h" +QT_BEGIN_NAMESPACE namespace OptimalExposure { @@ -25,7 +28,8 @@ ImagingCameraData &aCalculationImagingCameraData); CameraExposureEnvelope calculateCameraExposureEnvelope(); - OptimalExposureDetail calculateSubExposureDetail(int aSelectedGainValue); + // OptimalExposureDetail calculateSubExposureDetail(int aSelectedGainValue); + OptimalExposureDetail calculateSubExposureDetail(); double getANoiseTolerance(); void setANoiseTolerance(double newNoiseTolerance); @@ -71,3 +75,6 @@ }; } +QT_END_NAMESPACE + +#endif // OPTIMALSUBEXPOSURECALCULATOR_H diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -56,9 +56,9 @@ return tempFormat; } -void PlaceholderPath::processJobInfo(SequenceJob *job, const QString &targetName) +void PlaceholderPath::processJobInfo(SequenceJob *job) { - QString jobTargetName = targetName; + QString jobTargetName = job->getCoreProperty(SequenceJob::SJ_TargetName).toString(); auto frameType = getFrameType(job->getFrameType()); auto filterType = job->getCoreProperty(SequenceJob::SJ_Filter).toString(); auto exposure = job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(); @@ -68,7 +68,7 @@ frameType = "DarkFlat"; // Sanitize name - QString tempTargetName = KSUtils::sanitize(targetName); + QString tempTargetName = KSUtils::sanitize(jobTargetName); // Because scheduler sets the target name in capture module // it would be the same as the raw prefix @@ -118,7 +118,7 @@ job->setCoreProperty(SequenceJob::SJ_FullPrefix, imagePrefix); - QString signature = generateSequenceFilename(*job, jobTargetName, true, true, 1, ".fits", "", false, true); + QString signature = generateSequenceFilename(*job, true, true, 1, ".fits", "", false, true); job->setCoreProperty(SequenceJob::SJ_Signature, signature); } @@ -208,29 +208,16 @@ } QString PlaceholderPath::generateSequenceFilename(const SequenceJob &job, - const QString &targetName, bool local, const bool batch_mode, const int nextSequenceID, const QString &extension, const QString &filename, const bool glob, - const bool gettingSignature) const + const bool gettingSignature) { QMap pathPropertyMap; - pathPropertyMap[PP_TARGETNAME] = QVariant(targetName); - pathPropertyMap[PP_FILTER] = job.getCoreProperty(SequenceJob::SJ_Filter); - pathPropertyMap[PP_DARKFLAT] = job.jobType() == SequenceJob::JOBTYPE_DARKFLAT; - pathPropertyMap[PP_DIRECTORY] = job.getCoreProperty(local ? SequenceJob::SJ_LocalDirectory : - SequenceJob::SJ_RemoteDirectory); - pathPropertyMap[PP_FORMAT] = job.getCoreProperty(SequenceJob::SJ_PlaceholderFormat); - pathPropertyMap[PP_SUFFIX] = job.getCoreProperty(SequenceJob::SJ_PlaceholderSuffix); - pathPropertyMap[PP_EXPOSURE] = job.getCoreProperty(SequenceJob::SJ_Exposure); - pathPropertyMap[PP_FRAMETYPE] = QVariant(job.getFrameType()); - pathPropertyMap[PP_TEMPERATURE] = QVariant(job.getTargetTemperature()); - pathPropertyMap[PP_GAIN] = job.getCoreProperty(SequenceJob::SJ_Gain); - pathPropertyMap[PP_OFFSET] = job.getCoreProperty(SequenceJob::SJ_Offset); - pathPropertyMap[PP_PIERSIDE] = QVariant(job.getPierSide()); + setGenerateFilenameSettings(job, pathPropertyMap, local); return generateFilenameInternal(pathPropertyMap, local, batch_mode, nextSequenceID, extension, filename, glob, gettingSignature); @@ -244,6 +231,73 @@ gettingSignature); } +QString PlaceholderPath::generateReplacement(const QMap &pathPropertyMap, PathProperty property, + bool usePattern) const +{ + if (usePattern) + { + switch (propertyType(property)) + { + case PP_TYPE_UINT: + case PP_TYPE_DOUBLE: + return "-?\\d+"; + case PP_TYPE_BOOL: + return "(true|false)"; + case PP_TYPE_POINT: + return "\\d+x\\d+"; + default: + if (property == PP_PIERSIDE) + return "(East|West|Unknown)"; + else + return "\\w+"; + } + } + else if (pathPropertyMap[property].isValid()) + { + switch (propertyType(property)) + { + case PP_TYPE_DOUBLE: + return QString::number(pathPropertyMap[property].toDouble(), 'd', 0); + case PP_TYPE_UINT: + return QString::number(pathPropertyMap[property].toUInt()); + case PP_TYPE_POINT: + return QString("%1x%2").arg(pathPropertyMap[PP_BIN].toPoint().x()).arg(pathPropertyMap[PP_BIN].toPoint().y()); + case PP_TYPE_STRING: + if (property == PP_PIERSIDE) + { + switch (static_cast(pathPropertyMap[property].toInt())) + { + case ISD::Mount::PIER_EAST: + return "East"; + case ISD::Mount::PIER_WEST: + return "West"; + default: + return "Unknown"; + } + } + else + return pathPropertyMap[property].toString(); + default: + return pathPropertyMap[property].toString(); + } + } + else + { + switch (propertyType(property)) + { + case PP_TYPE_DOUBLE: + case PP_TYPE_UINT: + return "-1"; + case PP_TYPE_POINT: + return "0x0"; + case PP_TYPE_BOOL: + return "false"; + default: + return "Unknown"; + } + } +} + QString PlaceholderPath::generateFilenameInternal(const QMap &pathPropertyMap, const bool local, const bool batch_mode, @@ -282,12 +336,10 @@ #endif QRegularExpressionMatch match; QRegularExpression - // This is the original regex with %p & %d tags - disabled for now to simply - // re("(?\\%(?(filename|f|Datetime|D|Type|T|exposure|e|Filter|F|target|t|temperature|C|gain|G|offset|O|pierside|P|sequence|s|directory|d|path|p))(?\\d+)?)(?[_/])?"); #if defined(Q_OS_WIN) - re("(?\\%(?(filename|f|Datetime|D|Type|T|exposure|e|Filter|F|target|t|temperature|C|gain|G|offset|O|pierside|P|sequence|s))(?\\d+)?)(?[_\\\\])?"); + re("(?\\%(?(filename|f|Datetime|D|Type|T|exposure|e|exp|E|Filter|F|target|t|temperature|C|bin|B|gain|G|offset|O|iso|I|pierside|P|sequence|s))(?\\d+)?)(?[_\\\\])?"); #else - re("(?\\%(?(filename|f|Datetime|D|Type|T|exposure|e|Filter|F|target|t|temperature|C|gain|G|offset|O|pierside|P|sequence|s))(?\\d+)?)(?[_/])?"); + re("(?\\%(?(filename|f|Datetime|D|Type|T|exposure|e|exp|E|Filter|F|target|t|temperature|C|bin|B|gain|G|offset|O|iso|I|pierside|P|sequence|s))(?\\d+)?)(?[_/])?"); #endif while ((i = tempFormat.indexOf(re, i, &match)) != -1) @@ -315,17 +367,21 @@ else replacement = getFrameType(frameType); } - else if ((match.captured("name") == "exposure") || (match.captured("name") == "e")) + else if ((match.captured("name") == "exposure") || (match.captured("name") == "e") || + (match.captured("name") == "exp") || (match.captured("name") == "E")) { double fractpart, intpart; double exposure = pathPropertyMap[PP_EXPOSURE].toDouble(); fractpart = std::modf(exposure, &intpart); if (fractpart == 0) - replacement = QString::number(exposure, 'd', 0) + QString("_secs"); + replacement = QString::number(exposure, 'd', 0); else if (exposure >= 1e-3) - replacement = QString::number(exposure, 'f', 3) + QString("_secs"); + replacement = QString::number(exposure, 'f', 3); else - replacement = QString::number(exposure, 'f', 6) + QString("_secs"); + replacement = QString::number(exposure, 'f', 6); + // append _secs for placeholders "exposure" and "e" + if ((match.captured("name") == "exposure") || (match.captured("name") == "e")) + replacement += QString("_secs"); } else if ((match.captured("name") == "Filter") || (match.captured("name") == "F")) { @@ -343,37 +399,35 @@ { replacement = targetNameSanitized; } - else if (((match.captured("name") == "temperature") || (match.captured("name") == "C")) - && pathPropertyMap[PP_TEMPERATURE].isValid()) + else if (((match.captured("name") == "temperature") || (match.captured("name") == "C"))) { - replacement = QString::number(pathPropertyMap[PP_TEMPERATURE].toDouble(), 'd', 0) + QString("C"); + replacement = generateReplacement(pathPropertyMap, PP_TEMPERATURE, + (glob || gettingSignature) && pathPropertyMap[PP_TEMPERATURE].isValid() == false); } - else if (((match.captured("name") == "gain") || (match.captured("name") == "G")) - && pathPropertyMap[PP_GAIN].isValid()) + else if (((match.captured("name") == "bin") || (match.captured("name") == "B"))) { - replacement = QString::number(pathPropertyMap[PP_GAIN].toDouble(), 'd', 0); + replacement = generateReplacement(pathPropertyMap, PP_BIN, + (glob || gettingSignature) && pathPropertyMap[PP_BIN].isValid() == false); } - else if (((match.captured("name") == "offset") || (match.captured("name") == "O")) - && pathPropertyMap[PP_OFFSET].isValid()) + else if (((match.captured("name") == "gain") || (match.captured("name") == "G"))) { - replacement = QString::number(pathPropertyMap[PP_OFFSET].toDouble(), 'd', 0); + replacement = generateReplacement(pathPropertyMap, PP_GAIN, + (glob || gettingSignature) && pathPropertyMap[PP_GAIN].isValid() == false); } - else if (((match.captured("name") == "pierside") || (match.captured("name") == "P")) - && pathPropertyMap[PP_PIERSIDE].isValid()) + else if (((match.captured("name") == "offset") || (match.captured("name") == "O"))) { - switch (static_cast(pathPropertyMap[PP_PIERSIDE].toInt())) - { - case ISD::Mount::PIER_EAST: - replacement = "East"; - break; - case ISD::Mount::PIER_WEST: - replacement = "West"; - break; - case ISD::Mount::PIER_UNKNOWN: - replacement = "Unknown"; - break; - } - + replacement = generateReplacement(pathPropertyMap, PP_OFFSET, + (glob || gettingSignature) && pathPropertyMap[PP_OFFSET].isValid() == false); + } + else if (((match.captured("name") == "iso") || (match.captured("name") == "I")) + && pathPropertyMap[PP_ISO].isValid()) + { + replacement = generateReplacement(pathPropertyMap, PP_ISO, + (glob || gettingSignature) && pathPropertyMap[PP_ISO].isValid() == false); + } + else if (((match.captured("name") == "pierside") || (match.captured("name") == "P"))) + { + replacement = generateReplacement(pathPropertyMap, PP_PIERSIDE, glob || gettingSignature); } // Disable for now %d & %p tags to simplfy // else if ((match.captured("name") == "directory") || (match.captured("name") == "d") || @@ -420,20 +474,43 @@ return tempFilename; } -void PlaceholderPath::setGenerateFilenameSettings(const SequenceJob &job, const QString &targetName) +void PlaceholderPath::setGenerateFilenameSettings(const SequenceJob &job, QMap &pathPropertyMap, + bool local) { - setPathProperty(PP_TARGETNAME, QVariant(targetName)); - setPathProperty(PP_FRAMETYPE, QVariant(job.getFrameType())); - setPathProperty(PP_FILTER, job.getCoreProperty(SequenceJob::SJ_Filter)); - setPathProperty(PP_EXPOSURE, job.getCoreProperty(SequenceJob::SJ_Exposure)); - setPathProperty(PP_DIRECTORY, job.getCoreProperty(SequenceJob::SJ_LocalDirectory)); - setPathProperty(PP_FORMAT, job.getCoreProperty(SequenceJob::SJ_PlaceholderFormat)); - setPathProperty(PP_SUFFIX, job.getCoreProperty(SequenceJob::SJ_PlaceholderSuffix)); - setPathProperty(PP_DARKFLAT, job.jobType() == SequenceJob::JOBTYPE_DARKFLAT); - setPathProperty(PP_TEMPERATURE, QVariant(job.getTargetTemperature())); - setPathProperty(PP_GAIN, job.getCoreProperty(SequenceJob::SJ_Gain)); - setPathProperty(PP_OFFSET, job.getCoreProperty(SequenceJob::SJ_Offset)); - setPathProperty(PP_PIERSIDE, QVariant(job.getPierSide())); + setPathProperty(pathPropertyMap, PP_TARGETNAME, job.getCoreProperty(SequenceJob::SJ_TargetName)); + setPathProperty(pathPropertyMap, PP_FRAMETYPE, QVariant(job.getFrameType())); + setPathProperty(pathPropertyMap, PP_FILTER, job.getCoreProperty(SequenceJob::SJ_Filter)); + setPathProperty(pathPropertyMap, PP_EXPOSURE, job.getCoreProperty(SequenceJob::SJ_Exposure)); + setPathProperty(pathPropertyMap, PP_DIRECTORY, + job.getCoreProperty(local ? SequenceJob::SJ_LocalDirectory : SequenceJob::SJ_RemoteDirectory)); + setPathProperty(pathPropertyMap, PP_FORMAT, job.getCoreProperty(SequenceJob::SJ_PlaceholderFormat)); + setPathProperty(pathPropertyMap, PP_SUFFIX, job.getCoreProperty(SequenceJob::SJ_PlaceholderSuffix)); + setPathProperty(pathPropertyMap, PP_DARKFLAT, job.jobType() == SequenceJob::JOBTYPE_DARKFLAT); + setPathProperty(pathPropertyMap, PP_BIN, job.getCoreProperty(SequenceJob::SJ_Binning)); + setPathProperty(pathPropertyMap, PP_PIERSIDE, QVariant(job.getPierSide())); + setPathProperty(pathPropertyMap, PP_ISO, job.getCoreProperty(SequenceJob::SJ_ISO)); + + // handle optional parameters + if (job.getCoreProperty(SequenceJob::SJ_EnforceTemperature).toBool()) + setPathProperty(pathPropertyMap, PP_TEMPERATURE, QVariant(job.getTargetTemperature())); + else if (job.currentTemperature() != Ekos::INVALID_VALUE) + setPathProperty(pathPropertyMap, PP_TEMPERATURE, QVariant(job.currentTemperature())); + else + pathPropertyMap.remove(PP_TEMPERATURE); + + if (job.getCoreProperty(SequenceJob::SequenceJob::SJ_Gain).toInt() >= 0) + setPathProperty(pathPropertyMap, PP_GAIN, job.getCoreProperty(SequenceJob::SJ_Gain)); + else if (job.currentGain() >= 0) + setPathProperty(pathPropertyMap, PP_GAIN, job.currentGain()); + else + pathPropertyMap.remove(PP_GAIN); + + if (job.getCoreProperty(SequenceJob::SequenceJob::SJ_Offset).toInt() >= 0) + setPathProperty(pathPropertyMap, PP_OFFSET, job.getCoreProperty(SequenceJob::SJ_Offset)); + else if (job.currentOffset() >= 0) + setPathProperty(pathPropertyMap, PP_OFFSET, job.currentOffset()); + else + pathPropertyMap.remove(PP_OFFSET); } QStringList PlaceholderPath::remainingPlaceholders(const QString &filename) @@ -455,9 +532,9 @@ return placeholders; } -QList PlaceholderPath::getCompletedFileIds(const SequenceJob &job, const QString &targetName) +QList PlaceholderPath::getCompletedFileIds(const SequenceJob &job) { - QString path = generateSequenceFilename(job, targetName, true, true, 0, ".*", "", true); + QString path = generateSequenceFilename(job, true, true, 0, ".*", "", true); auto sanitizedPath = path; // This is needed for Windows as the regular expression confuses path search @@ -491,20 +568,53 @@ return ids; } -int PlaceholderPath::getCompletedFiles(const SequenceJob &job, const QString &targetName) +int PlaceholderPath::getCompletedFiles(const SequenceJob &job) { - return getCompletedFileIds(job, targetName).length(); + return getCompletedFileIds(job).length(); } -int PlaceholderPath::checkSeqBoundary(const SequenceJob &job, const QString &targetName) +int PlaceholderPath::checkSeqBoundary(const SequenceJob &job) { - auto ids = getCompletedFileIds(job, targetName); + auto ids = getCompletedFileIds(job); if (ids.length() > 0) return *std::max_element(ids.begin(), ids.end()) + 1; else return 1; } +PlaceholderPath::PathPropertyType PlaceholderPath::propertyType(PathProperty property) +{ + switch (property) + { + case PP_FORMAT: + case PP_DIRECTORY: + case PP_TARGETNAME: + case PP_FILTER: + case PP_PIERSIDE: + return PP_TYPE_STRING; + + case PP_DARKFLAT: + return PP_TYPE_BOOL; + + case PP_SUFFIX: + case PP_FRAMETYPE: + case PP_ISO: + return PP_TYPE_UINT; + + case PP_EXPOSURE: + case PP_GAIN: + case PP_OFFSET: + case PP_TEMPERATURE: + return PP_TYPE_DOUBLE; + + case PP_BIN: + return PP_TYPE_POINT; + + default: + return PP_TYPE_NONE; + } +} + // An "emergency" method--the code should not be overwriting files, // however, if we've detected an overwrite, we generate a new filename // by looking for numbers at its end (before its extension) and incrementing diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/placeholderpath.h 2023-12-03 05:23:17.000000000 +0000 @@ -32,12 +32,24 @@ PP_DARKFLAT, // bool PP_EXPOSURE, // double PP_FILTER, // QString + PP_BIN, // Point PP_GAIN, // double + PP_ISO, // uint PP_OFFSET, // double PP_PIERSIDE, // ISD::Mount::PierSide (int) PP_TEMPERATURE // double } PathProperty; + typedef enum + { + PP_TYPE_NONE, + PP_TYPE_STRING, + PP_TYPE_BOOL, + PP_TYPE_UINT, + PP_TYPE_DOUBLE, + PP_TYPE_POINT + } PathPropertyType; + PlaceholderPath(const QString &seqFilename); PlaceholderPath(); ~PlaceholderPath(); @@ -45,9 +57,8 @@ /** * @brief processJobInfo loads the placeHolderPath with properties from the SequenceJob * @param sequence job to be processed - * @param targetname name of the celestial target */ - void processJobInfo(SequenceJob *job, const QString &targetName); + void processJobInfo(SequenceJob *job); /** * @brief addjob creates the directory suffix for the SequenceJob @@ -78,9 +89,9 @@ * * This overload of the function supports calls from the capture class */ - QString generateSequenceFilename(const SequenceJob &job, const QString &targetName, bool local, const bool batch_mode, + QString generateSequenceFilename(const SequenceJob &job, bool local, const bool batch_mode, const int nextSequenceID, const QString &extension, const QString &filename, - const bool glob = false, const bool gettingSignature = false) const; + const bool glob = false, const bool gettingSignature = false); /** * @brief generateFilename performs the data for tag substituion in the filename @@ -101,9 +112,11 @@ /** * @brief setGenerateFilenameSettings loads the placeHolderPath with settings from the passed job * @param sequence job to be processed - * @param targetName name of the target to be captured */ - void setGenerateFilenameSettings(const SequenceJob &job, const QString &targetName); + void setGenerateFilenameSettings(const SequenceJob &job) + { + setGenerateFilenameSettings(job, m_PathPropertyMap, true); + } /** * @brief remainingPlaceholders finds placeholder tags in filename @@ -115,26 +128,28 @@ /** * @brief remainingPlaceholders provides a list of already existing fileIDs from passed sequence job * @param sequence job to be processed - * @param targetName name of the celestial target * @return a QStringList of the existing fileIDs */ - QList getCompletedFileIds(const SequenceJob &job, const QString &targetName); + QList getCompletedFileIds(const SequenceJob &job); /** * @brief getCompletedFiles provides the number of existing fileIDs * @param sequence job to be processed - * @param targetName name of the celestial target * @return number of existing fileIDs */ - int getCompletedFiles(const SequenceJob &job, const QString &targetName); + int getCompletedFiles(const SequenceJob &job); /** * @brief checkSeqBoundary provides the ID to use for the next file * @param sequence job to be processed - * @param targetName name of the celestial target * @return number for the next fileIDs */ - int checkSeqBoundary(const SequenceJob &job, const QString &targetName); + int checkSeqBoundary(const SequenceJob &job); + + /** + * @brief Property type definitions + */ + static PathPropertyType propertyType(PathProperty property); /** * @brief defaultFormat provides a default format string @@ -171,6 +186,20 @@ QString generateFilenameInternal(const QMap &pathPropertyMap, const bool local, const bool batch_mode, const int nextSequenceID, const QString &extension, const QString &filename, const bool glob = false, const bool gettingSignature = false) const; + /** + * @brief setGenerateFilenameSettings Generate property map from job settings + * @param job sequence job holding the attributes + * @param pathPropertyMap property map to be filled + * @param local set true if local file directory should be used + */ + void setGenerateFilenameSettings(const SequenceJob &job, QMap &pathPropertyMap, bool local); + + /** + * @brief generateReplacement Generate the replacement for the given property. if usePattern + * is true, a pattern for the given type is used instead of a fixed value. + */ + QString generateReplacement(const QMap &pathPropertyMap, PathProperty property, bool usePattern = false) const; + QString getFrameType(CCDFrameType frameType) const { if (m_frameTypes.contains(frameType)) @@ -186,9 +215,9 @@ { return m_PathPropertyMap[prop]; } - void setPathProperty(PathProperty prop, QVariant value) + void setPathProperty(QMap &pathPropertyMap, PathProperty prop, QVariant value) { - m_PathPropertyMap[prop] = value; + pathPropertyMap[prop] = value; } QMap m_frameTypes; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -14,9 +14,15 @@ #include "fov.h" #include "kstarsdata.h" #include "ekos/manager.h" +#include "indi/indirotator.h" #include #include #include +#include "capture.h" +#include "ekos/align/align.h" +#include "ekos/capture/capturedeviceadaptor.h" +#include "ekos/align/opsalign.h" +#include "ekos/auxiliary/rotatorutils.h" #include "ekos_capture_debug.h" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/rotatorsettings.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,12 +8,15 @@ #pragma once #include "ui_rotatorsettings.h" -#include "ekos/capture/capturedeviceadaptor.h" -#include "ekos/align/opsalign.h" #include "indi/indimount.h" #include "qloggingcategory.h" #include +namespace Ekos +{ +class CaptureDeviceAdaptor; +} + class RotatorSettings : public QDialog, public Ui::RotatorDialog { Q_OBJECT diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejob.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejob.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejob.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejob.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -8,6 +8,8 @@ #include #include +#include "capturedeviceadaptor.h" +#include "skyobjects/skypoint.h" #define MF_TIMER_TIMEOUT 90000 #define MF_RA_DIFF_LIMIT 4 @@ -25,9 +27,36 @@ } -void SequenceJob::init(SequenceJobType jobType) +/** + * @brief SequenceJob::SequenceJob Construct job from XML source + * @param root pointer to valid job stored in XML format. + */ +SequenceJob::SequenceJob(XMLEle * root, QString targetName) +{ + // set own unconnected state machine + QSharedPointer sharedState; + sharedState.reset(new CaptureModuleState); + state.reset(new SequenceJobState(sharedState)); + // set simple device adaptor + devices.reset(new CaptureDeviceAdaptor()); + + init(SequenceJob::JOBTYPE_BATCH, root, sharedState, targetName); +} + +SequenceJob::SequenceJob(const QSharedPointer cp, + const QSharedPointer sharedState, SequenceJobType jobType, XMLEle *root, + QString targetName) +{ + devices = cp; + init(jobType, root, sharedState, targetName); +} + +void Ekos::SequenceJob::init(SequenceJobType jobType, XMLEle *root, QSharedPointer sharedState, + QString targetName) { setJobType(jobType); + // initialize the state machine + state.reset(new SequenceJobState(sharedState)); // Set default property values m_CoreProperties[SJ_Exposure] = -1; m_CoreProperties[SJ_Gain] = -1; @@ -40,175 +69,287 @@ m_CoreProperties[SJ_EnforceTemperature] = false; m_CoreProperties[SJ_GuiderActive] = false; m_CoreProperties[SJ_Encoding] = "FITS"; -} - -SequenceJob::SequenceJob(const QSharedPointer cp, - const QSharedPointer sharedState, SequenceJobType jobType) -{ - init(jobType); - devices = cp; - // initialize the state machine - state.reset(new SequenceJobState(sharedState)); // signal forwarding between this and the state machine - connect(this, &SequenceJob::updateGuiderDrift, state.data(), &SequenceJobState::setCurrentGuiderDrift); connect(state.data(), &SequenceJobState::prepareState, this, &SequenceJob::prepareState); connect(state.data(), &SequenceJobState::prepareComplete, this, &SequenceJob::processPrepareComplete); connect(state.data(), &SequenceJobState::abortCapture, this, &SequenceJob::processAbortCapture); connect(state.data(), &SequenceJobState::newLog, this, &SequenceJob::newLog); // start capturing as soon as the capture initialization is complete connect(state.data(), &SequenceJobState::initCaptureComplete, this, &SequenceJob::capture); -} -/** - * @brief SequenceJob::SequenceJob Construct job from XML source - * @param root pointer to valid job stored in XML format. - */ -SequenceJob::SequenceJob(XMLEle *root) -{ - init(SequenceJob::JOBTYPE_BATCH); - XMLEle *ep = nullptr; - XMLEle *subEP = nullptr; + // finish if XML document empty + if (root == nullptr) + return; - // set own unconnected state machine - QSharedPointer sharedState; - sharedState.reset(new CaptureModuleState); - state.reset(new SequenceJobState(sharedState)); + // targetName overrides values from the XML document + if (targetName != "") + setCoreProperty(SequenceJob::SJ_TargetName, targetName); - // We expect all data read from the XML to be in the C locale - QLocale::c(). + bool isDarkFlat = false; + sharedState->scripts().clear(); QLocale cLocale = QLocale::c(); - - const QMap frameTypes = - { - { "Light", FRAME_LIGHT }, { "Dark", FRAME_DARK }, { "Bias", FRAME_BIAS }, { "Flat", FRAME_FLAT } - }; - - setFrameType(FRAME_NONE); - setCoreProperty(SJ_Exposure, 0); - /* Reset light frame presence flag before enumerating */ - // JM 2018-09-14: If last sequence job is not LIGHT - // then scheduler job light frame is set to whatever last sequence job is - // so if it was non-LIGHT, this value is set to false which is wrong. - //if (nullptr != schedJob) - // schedJob->setLightFramesRequired(false); - + XMLEle * ep; + XMLEle * subEP; for (ep = nextXMLEle(root, 1); ep != nullptr; ep = nextXMLEle(root, 0)) { if (!strcmp(tagXMLEle(ep), "Exposure")) - { - setCoreProperty(SJ_Exposure, atof(pcdataXMLEle(ep))); - } + setCoreProperty(SequenceJob::SJ_Exposure, cLocale.toDouble(pcdataXMLEle(ep))); else if (!strcmp(tagXMLEle(ep), "Format")) + setCoreProperty(SequenceJob::SJ_Format, pcdataXMLEle(ep)); + else if (!strcmp(tagXMLEle(ep), "Encoding")) { - setCoreProperty(SJ_Format, pcdataXMLEle(ep)); + setCoreProperty(SequenceJob::SJ_Encoding, pcdataXMLEle(ep)); } - else if (!strcmp(tagXMLEle(ep), "PlaceholderFormat")) + else if (!strcmp(tagXMLEle(ep), "Binning")) { - setCoreProperty(SJ_PlaceholderFormat, pcdataXMLEle(ep)); + QPoint binning(1, 1); + subEP = findXMLEle(ep, "X"); + if (subEP) + binning.setX(cLocale.toInt(pcdataXMLEle(subEP))); + subEP = findXMLEle(ep, "Y"); + if (subEP) + binning.setY(cLocale.toInt(pcdataXMLEle(subEP))); + + setCoreProperty(SequenceJob::SJ_Binning, binning); } - else if (!strcmp(tagXMLEle(ep), "PlaceholderSuffix")) + else if (!strcmp(tagXMLEle(ep), "Frame")) { - setCoreProperty(SJ_PlaceholderSuffix, pcdataXMLEle(ep)); + QRect roi(0, 0, 0, 0); + subEP = findXMLEle(ep, "X"); + if (subEP) + roi.setX(cLocale.toInt(pcdataXMLEle(subEP))); + subEP = findXMLEle(ep, "Y"); + if (subEP) + roi.setY(cLocale.toInt(pcdataXMLEle(subEP))); + subEP = findXMLEle(ep, "W"); + if (subEP) + roi.setWidth(cLocale.toInt(pcdataXMLEle(subEP))); + subEP = findXMLEle(ep, "H"); + if (subEP) + roi.setHeight(cLocale.toInt(pcdataXMLEle(subEP))); + + setCoreProperty(SequenceJob::SJ_ROI, roi); } - else if (!strcmp(tagXMLEle(ep), "Encoding")) + else if (!strcmp(tagXMLEle(ep), "Temperature")) { - setCoreProperty(SJ_Encoding, pcdataXMLEle(ep)); + setTargetTemperature(cLocale.toDouble(pcdataXMLEle(ep))); + + // If force attribute exist, we change cameraTemperatureS, otherwise do nothing. + if (!strcmp(findXMLAttValu(ep, "force"), "true")) + setCoreProperty(SequenceJob::SJ_EnforceTemperature, true); + else if (!strcmp(findXMLAttValu(ep, "force"), "false")) + setCoreProperty(SequenceJob::SJ_EnforceTemperature, false); } else if (!strcmp(tagXMLEle(ep), "Filter")) { - setCoreProperty(SJ_Filter, QString(pcdataXMLEle(ep))); + const auto name = pcdataXMLEle(ep); + const auto index = std::max(1, filterLabels().indexOf(name) + 1); + setTargetFilter(index, name); } else if (!strcmp(tagXMLEle(ep), "Type")) { - /* Record frame type and mark presence of light frames for this sequence */ - QString frameTypeStr = QString(pcdataXMLEle(ep)); - if (frameTypes.contains(frameTypeStr)) - { - setFrameType(frameTypes[frameTypeStr]); - } - //if (FRAME_LIGHT == frameType && nullptr != schedJob) - //schedJob->setLightFramesRequired(true); + int index = frameTypes().indexOf(pcdataXMLEle(ep)); + setFrameType(static_cast(qMax(0, index))); + } + else if (!strcmp(tagXMLEle(ep), "TargetName")) + { + auto jobTarget = pcdataXMLEle(ep); + + if (targetName == "") + // use the target from the XML document + setCoreProperty(SequenceJob::SJ_TargetName, jobTarget); + else if (strcmp(jobTarget, "") != 0) + // issue a warning that target from the XML document is ignored + qWarning(KSTARS_EKOS_CAPTURE) << QString("Sequence job target name %1 ignored.").arg(jobTarget); } else if (!strcmp(tagXMLEle(ep), "Prefix")) { + // RawPrefix is outdated and will be ignored + subEP = findXMLEle(ep, "RawPrefix"); + if (subEP) + { + auto jobTarget = pcdataXMLEle(subEP); + + if (targetName == "") + // use the target from the XML document + setCoreProperty(SequenceJob::SJ_TargetName, jobTarget); + else if (strcmp(jobTarget, "") != 0) + // issue a warning that target from the XML document is ignored + qWarning(KSTARS_EKOS_CAPTURE) << QString("Sequence job raw prefix %1 ignored.").arg(jobTarget); + } bool filterEnabled = false, expEnabled = false, tsEnabled = false; subEP = findXMLEle(ep, "FilterEnabled"); if (subEP) filterEnabled = !strcmp("1", pcdataXMLEle(subEP)); - subEP = findXMLEle(ep, "ExpEnabled"); if (subEP) expEnabled = !strcmp("1", pcdataXMLEle(subEP)); - subEP = findXMLEle(ep, "TimeStampEnabled"); if (subEP) tsEnabled = !strcmp("1", pcdataXMLEle(subEP)); - // build default format - setCoreProperty(SJ_PlaceholderFormat, PlaceholderPath::defaultFormat(filterEnabled, expEnabled, tsEnabled)); + setCoreProperty(SequenceJob::SJ_PlaceholderFormat, + PlaceholderPath::defaultFormat(filterEnabled, expEnabled, tsEnabled)); } else if (!strcmp(tagXMLEle(ep), "Count")) { - setCoreProperty(SJ_Count, atoi(pcdataXMLEle(ep))); + setCoreProperty(SequenceJob::SJ_Count, cLocale.toInt(pcdataXMLEle(ep))); } else if (!strcmp(tagXMLEle(ep), "Delay")) { - setCoreProperty(SJ_Delay, atoi(pcdataXMLEle(ep))); + setCoreProperty(SequenceJob::SJ_Delay, cLocale.toInt(pcdataXMLEle(ep)) * 1000); + } + else if (!strcmp(tagXMLEle(ep), "PostCaptureScript")) + { + sharedState->scripts()[SCRIPT_POST_CAPTURE] = pcdataXMLEle(ep); + } + else if (!strcmp(tagXMLEle(ep), "PreCaptureScript")) + { + sharedState->scripts()[SCRIPT_PRE_CAPTURE] = pcdataXMLEle(ep); + } + else if (!strcmp(tagXMLEle(ep), "PostJobScript")) + { + sharedState->scripts()[SCRIPT_POST_JOB] = pcdataXMLEle(ep); + } + else if (!strcmp(tagXMLEle(ep), "PreJobScript")) + { + sharedState->scripts()[SCRIPT_PRE_JOB] = pcdataXMLEle(ep); } else if (!strcmp(tagXMLEle(ep), "FITSDirectory")) { - setCoreProperty(SJ_LocalDirectory, (pcdataXMLEle(ep))); + setCoreProperty(SequenceJob::SJ_LocalDirectory, pcdataXMLEle(ep)); + } + else if (!strcmp(tagXMLEle(ep), "PlaceholderFormat")) + { + setCoreProperty(SequenceJob::SJ_PlaceholderFormat, pcdataXMLEle(ep)); + } + else if (!strcmp(tagXMLEle(ep), "PlaceholderSuffix")) + { + setCoreProperty(SequenceJob::SJ_PlaceholderSuffix, cLocale.toUInt(pcdataXMLEle(ep))); } else if (!strcmp(tagXMLEle(ep), "RemoteDirectory")) { - setCoreProperty(SJ_RemoteDirectory, (pcdataXMLEle(ep))); + setCoreProperty(SequenceJob::SJ_RemoteDirectory, pcdataXMLEle(ep)); } else if (!strcmp(tagXMLEle(ep), "UploadMode")) { - setUploadMode(static_cast(atoi(pcdataXMLEle(ep)))); + setUploadMode(static_cast(cLocale.toInt(pcdataXMLEle(ep)))); + } + else if (!strcmp(tagXMLEle(ep), "ISOIndex")) + { + setISO(cLocale.toInt(pcdataXMLEle(ep))); + } + else if (!strcmp(tagXMLEle(ep), "Rotation")) + { + setTargetRotation(cLocale.toDouble(pcdataXMLEle(ep))); + } + else if (!strcmp(tagXMLEle(ep), "Properties")) + { + QMap> propertyMap; + + for (subEP = nextXMLEle(ep, 1); subEP != nullptr; subEP = nextXMLEle(ep, 0)) + { + QMap elements; + XMLEle * oneElement = nullptr; + for (oneElement = nextXMLEle(subEP, 1); oneElement != nullptr; oneElement = nextXMLEle(subEP, 0)) + { + const char * name = findXMLAttValu(oneElement, "name"); + bool ok = false; + // String + auto xmlValue = pcdataXMLEle(oneElement); + // Try to load it as double + auto value = cLocale.toDouble(xmlValue, &ok); + if (ok) + elements[name] = value; + else + elements[name] = xmlValue; + } + + const char * name = findXMLAttValu(subEP, "name"); + propertyMap[name] = elements; + } + + setCustomProperties(propertyMap); + // read the gain and offset values from the custom properties + setCoreProperty(SequenceJob::SJ_Gain, devices->cameraGain(propertyMap)); + setCoreProperty(SequenceJob::SJ_Offset, devices->cameraOffset(propertyMap)); } else if (!strcmp(tagXMLEle(ep), "Calibration")) { + // SQ_FORMAT_VERSION >= 2.7 + subEP = findXMLEle(ep, "PreAction"); + if (subEP) + { + XMLEle * typeEP = findXMLEle(subEP, "Type"); + if (typeEP) + { + setCalibrationPreAction(cLocale.toUInt(pcdataXMLEle(typeEP))); + if (getCalibrationPreAction() & ACTION_WALL) + { + XMLEle * azEP = findXMLEle(subEP, "Az"); + XMLEle * altEP = findXMLEle(subEP, "Alt"); + + if (azEP && altEP) + { + setCalibrationPreAction((getCalibrationPreAction() & ~ACTION_PARK_MOUNT) | ACTION_WALL); + SkyPoint wallCoord; + wallCoord.setAz(cLocale.toDouble(pcdataXMLEle(azEP))); + wallCoord.setAlt(cLocale.toDouble(pcdataXMLEle(altEP))); + setWallCoord(wallCoord); + } + else + { + qCWarning(KSTARS_EKOS_CAPTURE) << "Wall position coordinates missing, disabling slew to wall position action."; + setCalibrationPreAction((getCalibrationPreAction() & ~ACTION_WALL) | ACTION_NONE); + } + } + } + } + + // SQ_FORMAT_VERSION < 2.7 subEP = findXMLEle(ep, "FlatSource"); if (subEP) { XMLEle * typeEP = findXMLEle(subEP, "Type"); if (typeEP) { - if (!strcmp(pcdataXMLEle(typeEP), "Manual")) - setFlatFieldSource(SOURCE_MANUAL); - else if (!strcmp(pcdataXMLEle(typeEP), "FlatCap")) - setFlatFieldSource(SOURCE_FLATCAP); - else if (!strcmp(pcdataXMLEle(typeEP), "DarkCap")) - setFlatFieldSource(SOURCE_DARKCAP); - else if (!strcmp(pcdataXMLEle(typeEP), "Wall")) + // default + setCalibrationPreAction(ACTION_NONE); + if (!strcmp(pcdataXMLEle(typeEP), "Wall")) { XMLEle * azEP = findXMLEle(subEP, "Az"); XMLEle * altEP = findXMLEle(subEP, "Alt"); if (azEP && altEP) { - setFlatFieldSource(SOURCE_WALL); + setCalibrationPreAction((getCalibrationPreAction() & ~ACTION_PARK_MOUNT) | ACTION_WALL); SkyPoint wallCoord; - wallCoord.setAz(dms::fromString(pcdataXMLEle(azEP), true)); - wallCoord.setAlt(dms::fromString(pcdataXMLEle(altEP), true)); + wallCoord.setAz(cLocale.toDouble(pcdataXMLEle(azEP))); + wallCoord.setAlt(cLocale.toDouble(pcdataXMLEle(altEP))); setWallCoord(wallCoord); } } - else - setFlatFieldSource(SOURCE_DAWN_DUSK); } } + // SQ_FORMAT_VERSION < 2.7 + subEP = findXMLEle(ep, "PreMountPark"); + if (subEP && !strcmp(pcdataXMLEle(subEP), "True")) + setCalibrationPreAction(getCalibrationPreAction() | ACTION_PARK_MOUNT); + + // SQ_FORMAT_VERSION < 2.7 + subEP = findXMLEle(ep, "PreDomePark"); + if (subEP && !strcmp(pcdataXMLEle(subEP), "True")) + setCalibrationPreAction(getCalibrationPreAction() | ACTION_PARK_DOME); + subEP = findXMLEle(ep, "FlatDuration"); if (subEP) { const char * dark = findXMLAttValu(subEP, "dark"); - if (!strcmp(dark, "true")) - setJobType(JOBTYPE_DARKFLAT); + isDarkFlat = !strcmp(dark, "true"); XMLEle * typeEP = findXMLEle(subEP, "Type"); - if (typeEP) { if (!strcmp(pcdataXMLEle(typeEP), "Manual")) @@ -219,29 +360,28 @@ if (aduEP) { setFlatFieldDuration(DURATION_ADU); - setCoreProperty(SJ_TargetADU, cLocale.toDouble(pcdataXMLEle(aduEP))); + setCoreProperty(SequenceJob::SJ_TargetADU, QVariant(cLocale.toDouble(pcdataXMLEle(aduEP)))); } aduEP = findXMLEle(subEP, "Tolerance"); if (aduEP) { - setCoreProperty(SJ_TargetADUTolerance, cLocale.toDouble(pcdataXMLEle(aduEP))); + setCoreProperty(SequenceJob::SJ_TargetADUTolerance, QVariant(cLocale.toDouble(pcdataXMLEle(aduEP)))); } } - - subEP = findXMLEle(ep, "PreMountPark"); - if (subEP) - { - setPreMountPark(!strcmp(pcdataXMLEle(subEP), "True")); - } - - subEP = findXMLEle(ep, "PreDomePark"); - if (subEP) - { - setPreDomePark(!strcmp(pcdataXMLEle(subEP), "True")); - } } } + if(isDarkFlat) + setJobType(SequenceJob::JOBTYPE_DARKFLAT); + + // copy general state attributes + // TODO: does this really make sense? This is a general setting - sterne-jaeger@openfuture.de, 2023-09-21 + setCoreProperty(SequenceJob::SJ_EnforceStartGuiderDrift, Options::enforceStartGuiderDrift()); + setTargetStartGuiderDrift(Options::startGuideDeviation()); + + // create signature with current target + auto placeholderPath = Ekos::PlaceholderPath(); + placeholderPath.processJobInfo(this); } void SequenceJob::resetStatus(JOBStatus status) @@ -308,6 +448,36 @@ state->reset(in_status); } +void SequenceJob::setISO(int index) +{ + if (devices->getActiveChip()) + { + setCoreProperty(SequenceJob::SJ_ISOIndex, index); + const auto isolist = devices->getActiveChip()->getISOList(); + if (isolist.count() > index && index >= 0) + setCoreProperty(SequenceJob::SJ_ISO, isolist[index]); + } +} + +QStringList SequenceJob::frameTypes() +{ + if (!devices->getActiveCamera()) + return QStringList({"Light", "Bias", "Dark", "Flat"}); + + ISD::CameraChip *tChip = devices->getActiveCamera()->getChip(ISD::CameraChip::PRIMARY_CCD); + + return tChip->getFrameTypes(); +} + +QStringList SequenceJob::filterLabels() +{ + if (devices->getFilterManager().isNull()) + return QStringList(); + + return devices->getFilterManager()->getFilterLabels(); + +} + void SequenceJob::connectDeviceAdaptor() { devices->setCurrentSequenceJobState(state); @@ -568,14 +738,14 @@ } // Setter: Set flat field source -void SequenceJob::setFlatFieldSource(FlatFieldSource value) +void SequenceJob::setCalibrationPreAction(uint32_t value) { - state->flatFieldSource = value; + state->m_CalibrationPreAction = value; } -// Getter: Get flat field source -FlatFieldSource SequenceJob::getFlatFieldSource() const +// Getter: Get calibration pre action +uint32_t SequenceJob::getCalibrationPreAction() const { - return state->flatFieldSource; + return state->m_CalibrationPreAction; } void SequenceJob::setWallCoord(const SkyPoint &value) @@ -618,26 +788,41 @@ setDustCap(devices->dustCap()); } -void SequenceJob::setLightBox(ISD::LightBox *lightBox) +void SequenceJob::setLightBox(ISD::LightBox * lightBox) { state->m_CaptureModuleState->hasLightBox = (lightBox != nullptr); } -void SequenceJob::setDustCap(ISD::DustCap *dustCap) +void SequenceJob::setDustCap(ISD::DustCap * dustCap) { state->m_CaptureModuleState->hasDustCap = (dustCap != nullptr); } -void SequenceJob::addMount(ISD::Mount *scope) +void SequenceJob::addMount(ISD::Mount * scope) { state->m_CaptureModuleState->hasTelescope = (scope != nullptr); } -void SequenceJob::setDome(ISD::Dome *dome) +void SequenceJob::setDome(ISD::Dome * dome) { state->m_CaptureModuleState->hasDome = (dome != nullptr); } +double SequenceJob::currentTemperature() const +{ + return devices->cameraTemperature(); +} + +double SequenceJob::currentGain() const +{ + return devices->cameraGain(); +} + +double SequenceJob::currentOffset() const +{ + return devices->cameraOffset(); +} + void SequenceJob::prepareCapture() { // simply forward it to the state machine @@ -645,7 +830,6 @@ { case FRAME_LIGHT: state->prepareLightFrameCapture(getCoreProperty(SJ_EnforceTemperature).toBool(), - getCoreProperty(SJ_EnforceStartGuiderDrift).toBool() && getCoreProperty(SJ_GuiderActive).toBool(), jobType() == SequenceJob::JOBTYPE_PREVIEW); break; case FRAME_FLAT: @@ -700,17 +884,6 @@ } break; - case SJ_GuiderActive: - // Inform the state machine if guiding is running. This is necessary during the preparation phase - // where the state machine might wait for guide deviations if enforcing initial guiding drift is selected. - // If guiding aborts after the preparation has started, the state machine might wait infinitely for an - // updated guide drift. - if (m_CoreProperties[SJ_GuiderActive] != value) - { - state->setEnforceInitialGuidingDrift(value.toBool() && - m_CoreProperties[SJ_EnforceStartGuiderDrift].toBool()); - } - break; default: break; } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejob.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejob.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejob.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejob.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,15 +7,14 @@ #pragma once #include "sequencejobstate.h" -#include "capturedeviceadaptor.h" #include "indi/indistd.h" #include "indi/indicamera.h" -#include "ekos/auxiliary/filtermanager.h" -#include "skyobjects/skypoint.h" +////#include "ekos/auxiliary/filtermanager.h" #include -class SchedulerJob; +class SkyPoint; + /** * @class SequenceJob * @short Sequence Job is a container for the details required to capture a series of images. @@ -25,6 +24,9 @@ */ namespace Ekos { + +class CaptureDeviceAdaptor; + class SequenceJob : public QObject { Q_OBJECT @@ -60,6 +62,8 @@ SJ_Count, // Int SJ_Delay, + // QString + SJ_ISO, // Int SJ_ISOIndex, // Double @@ -67,6 +71,8 @@ // Double SJ_Offset, // QString + SJ_TargetName, + //QString SJ_LocalDirectory, // QString SJ_PlaceholderFormat, @@ -98,8 +104,8 @@ //////////////////////////////////////////////////////////////////////// /// Constructors //////////////////////////////////////////////////////////////////////// - SequenceJob(const QSharedPointer cp, const QSharedPointer sharedState, SequenceJobType jobType); - SequenceJob(XMLEle *root); + SequenceJob(const QSharedPointer cp, const QSharedPointer sharedState, SequenceJobType jobType, XMLEle *root = nullptr, QString targetName = ""); + SequenceJob(XMLEle *root, QString targetName); ~SequenceJob() = default; //////////////////////////////////////////////////////////////////////// @@ -211,6 +217,10 @@ { m_Scripts[type] = value; } + + // helper function setting both ISO index and ISO value + void setISO(int index); + // Custom Properties const QMap > getCustomProperties() const { @@ -227,9 +237,9 @@ ISD::Camera::UploadMode getUploadMode() const; // Setter: Set flat field source - void setFlatFieldSource(FlatFieldSource value); + void setCalibrationPreAction(uint32_t value); // Getter: Get flat field source - FlatFieldSource getFlatFieldSource() const; + uint32_t getCalibrationPreAction() const; // Setter: Set Wall SkyPoint Azimuth coords void setWallCoord(const SkyPoint &value); @@ -328,24 +338,6 @@ state->targetPositionAngle = value; } - bool getPreMountPark() const - { - return state->preMountPark; - } - void setPreMountPark(bool value) - { - state->preMountPark = value; - } - - bool getPreDomePark() const - { - return state->preDomePark; - } - void setPreDomePark(bool value) - { - state->preDomePark = value; - } - SequenceJobState::CalibrationStage getCalibrationStage() const { return state->calibrationStage; @@ -397,6 +389,11 @@ */ IPState checkFlatFramePendingTasksCompleted(); + // current values + double currentTemperature() const; + double currentGain() const; + double currentOffset() const; + signals: // All preparations necessary for capturing are completed void prepareComplete(bool success = true); @@ -414,8 +411,10 @@ void updateGuiderDrift(double deviation_rms); private: - // Initialisation inside of the constructors - void init (SequenceJobType jobType); + /** + * @brief init Initialize the sequence job from its XML representation + */ + void init(SequenceJobType jobType, XMLEle *root, QSharedPointer sharedState, QString targetName); // job type (batch, preview, ...) SequenceJobType m_jobType; @@ -450,10 +449,22 @@ bool m_JobProgressIgnored {false}; ////////////////////////////////////////////////////////////// + /// Device access + ////////////////////////////////////////////////////////////// + + /** + * @brief frameTypes Retrieve the frame types from the active camera's primary chip. + */ + QStringList frameTypes(); + /** + * @brief filterLabels list of currently available filter labels + */ + QStringList filterLabels(); + + ////////////////////////////////////////////////////////////// /// State machines encapsulating the state of this capture sequence job ////////////////////////////////////////////////////////////// QSharedPointer devices; QSharedPointer state; - }; } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -9,6 +9,7 @@ #include "Options.h" #include "kstarsdata.h" #include "indicom.h" +#include "ekos/auxiliary/rotatorutils.h" namespace Ekos { @@ -32,10 +33,10 @@ wpScopeStatus = WP_NONE; } -void SequenceJobState::prepareLightFrameCapture(bool enforceCCDTemp, bool enforceInitialGuidingDrift, bool isPreview) +void SequenceJobState::prepareLightFrameCapture(bool enforceCCDTemp, bool isPreview) { // precondition: do not start while already being busy and conditions haven't changed - if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature && enforceInitialGuidingDrift == m_enforceInitialGuiding) + if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature) return; // initialize the states @@ -53,11 +54,6 @@ // Check if we need to update rotator (only skip if the value is initialized and within the limits) prepareRotatorCheck(); - // Check if we need to wait for guiding being initially below the target value - m_enforceInitialGuiding = enforceInitialGuidingDrift; - if (enforceInitialGuidingDrift && !isPreview) - prepareActions[CaptureModuleState::ACTION_GUIDER_DRIFT] = false; - // Hint: Filter changes are actually done in SequenceJob::capture(); // preparation started @@ -167,18 +163,10 @@ return; // 1. Check if the selected flats light source is ready - if (checkFlatsLightCoverReady() != IPS_OK) - return; - - // 2. Light source ready, now check if we need to perform mount prepark - if (checkPreMountParkReady() != IPS_OK) + if (checkFlatsCoverReady() != IPS_OK) return; - // 3. Check if we need to perform dome prepark - if (checkPreDomeParkReady() != IPS_OK) - return; - - // 4. If we used AUTOFOCUS before for a specific frame (e.g. Lum) + // 2. If we used AUTOFOCUS before for a specific frame (e.g. Lum) // then the absolute focus position for Lum is recorded in the filter manager // when we take flats again, we always go back to the same focus position as the light frames to ensure // near identical focus for both frames. @@ -202,15 +190,7 @@ if (checkDarksCoverReady() != IPS_OK) return; - // 2. Light source ready, now check if we need to perform mount prepark - if (checkPreMountParkReady() != IPS_OK) - return; - - // 3. Check if we need to perform dome prepark - if (checkPreDomeParkReady() != IPS_OK) - return; - - // avoid doubled events + // 2. avoid doubled events if (m_PreparationState == PREP_BUSY) { m_PreparationState = PREP_COMPLETED; @@ -253,8 +233,7 @@ // reset the initialization state for (CaptureModuleState::PrepareActions action : { - CaptureModuleState::ACTION_FILTER, CaptureModuleState::ACTION_ROTATOR, CaptureModuleState::ACTION_TEMPERATURE, - CaptureModuleState::ACTION_GUIDER_DRIFT + CaptureModuleState::ACTION_FILTER, CaptureModuleState::ACTION_ROTATOR, CaptureModuleState::ACTION_TEMPERATURE }) setInitialized(action, false); } @@ -332,67 +311,77 @@ } } -IPState SequenceJobState::checkFlatsLightCoverReady() +IPState SequenceJobState::checkCalibrationPreActionsReady() { IPState result = IPS_OK; - switch (flatFieldSource) + if (m_CalibrationPreAction & ACTION_WALL) + result = checkWallPositionReady(FRAME_FLAT); + + if (result != IPS_OK) + return result; + + if (m_CalibrationPreAction & ACTION_PARK_MOUNT) + result = checkPreMountParkReady(); + + if (result != IPS_OK) + return result; + + if (m_CalibrationPreAction & ACTION_PARK_DOME) + result = checkPreDomeParkReady(); + + return result; +} + +IPState SequenceJobState::checkFlatsCoverReady() +{ + auto result = checkCalibrationPreActionsReady(); + if (result == IPS_OK) { - case SOURCE_MANUAL: - result = checkManualCoverReady(true); - break; - case SOURCE_DAWN_DUSK: - // Not implemented. - result = IPS_ALERT; - break; - case SOURCE_FLATCAP: - result = checkFlatCapReady(); - break; - case SOURCE_WALL: - result = checkWallPositionReady(FRAME_FLAT); - break; - case SOURCE_DARKCAP: - result = checkDustCapReady(FRAME_FLAT); - break; + if (m_CaptureModuleState->hasDustCap && m_CaptureModuleState->hasLightBox) + return checkDustCapReady(FRAME_FLAT); + // In case we have a wall action then we are facing a flat light source and we can immediately continue to next step + else if (m_CalibrationPreAction & ACTION_WALL) + return IPS_OK; + else + { + // In case we ONLY have a lightbox then we need to ensure it's toggled correctly first + if (m_CaptureModuleState->hasLightBox) + return checkDustCapReady(FRAME_FLAT); + + return checkManualCoverReady(true); + } } + return result; } IPState SequenceJobState::checkDarksCoverReady() { - IPState result = IPS_OK; - - // 1. check if the CCD has a shutter - result = checkHasShutter(); - if (result != IPS_OK) - return result; + IPState result = checkCalibrationPreActionsReady();; - // 2. check if the selected cover is ready for darks - switch (flatFieldSource) + if (result == IPS_OK) { - // All these are manual when it comes to dark frames - case SOURCE_MANUAL: - case SOURCE_DAWN_DUSK: - // For cameras without a shutter, we need to ask the user to cover the telescope - // if the telescope is not already covered. - result = checkManualCoverReady(false); - break; - case SOURCE_FLATCAP: - case SOURCE_DARKCAP: - result = checkDustCapReady(FRAME_DARK); - break; - - case SOURCE_WALL: - result = checkWallPositionReady(FRAME_DARK); - break; + // 1. check if the CCD has a shutter + result = checkHasShutter(); + if (result != IPS_OK) + return result; + + if (m_CaptureModuleState->hasDustCap) + return checkDustCapReady(FRAME_DARK); + // In case we have a wall action then we are facing a designated location and we can immediately continue to next step + else if (m_CalibrationPreAction & ACTION_WALL) + return IPS_OK; + else + return checkManualCoverReady(false); } return result; } -IPState SequenceJobState::checkManualCoverReady(bool light) +IPState SequenceJobState::checkManualCoverReady(bool lightSourceRequired) { // Manual mode we need to cover mount with evenly illuminated field. - if (light && m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANUAL_COVER_CLOSED_LIGHT) + if (lightSourceRequired && m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANUAL_COVER_CLOSED_LIGHT) { if (coverQueryState == CAL_CHECK_CONFIRMATION) return IPS_BUSY; @@ -404,7 +393,7 @@ return IPS_BUSY; } - else if (!light && m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANUAL_COVER_CLOSED_DARK && + else if (!lightSourceRequired && m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANUAL_COVER_CLOSED_DARK && m_CaptureModuleState->shutterStatus == CaptureModuleState::SHUTTER_NO) { if (coverQueryState == CAL_CHECK_CONFIRMATION) @@ -420,41 +409,6 @@ return IPS_OK; } -IPState SequenceJobState::checkFlatCapReady() -{ - // flat light is on - if (m_CaptureModuleState->getLightBoxLightState() == CaptureModuleState::CAP_LIGHT_ON) - return IPS_OK; - // turning on flat light running - if (m_CaptureModuleState->getLightBoxLightState() == CaptureModuleState::CAP_LIGHT_BUSY || - m_CaptureModuleState->getDustCapState() == CaptureModuleState::CAP_PARKING) - return IPS_BUSY; - // error occured - if (m_CaptureModuleState->getDustCapState() == CaptureModuleState::CAP_ERROR) - return IPS_ALERT; - - // #1 if using the dust cap, first park the dust cap - if (m_CaptureModuleState->hasDustCap && m_CaptureModuleState->getDustCapState() != CaptureModuleState::CAP_PARKED) - { - m_CaptureModuleState->setDustCapState(CaptureModuleState::CAP_PARKING); - emit parkDustCap(true); - emit newLog(i18n("Parking dust cap...")); - return IPS_BUSY; - } - - // #2 Then we check if we need to turn on light box, if any - if (m_CaptureModuleState->hasLightBox && m_CaptureModuleState->getLightBoxLightState() != CaptureModuleState::CAP_LIGHT_ON) - { - m_CaptureModuleState->setLightBoxLightState(CaptureModuleState::CAP_LIGHT_BUSY); - emit setLightBoxLight(true); - emit newLog(i18n("Turn light box light on...")); - return IPS_BUSY; - } - - // nothing more to do - return IPS_OK; -} - IPState SequenceJobState::checkDustCapReady(CCDFrameType frameType) { // turning on flat light running @@ -466,20 +420,21 @@ if (m_CaptureModuleState->getDustCapState() == CaptureModuleState::CAP_ERROR) return IPS_ALERT; - bool captureFlats = (frameType == FRAME_FLAT); + auto captureLights = (frameType == FRAME_LIGHT); // for flats open the cap and close it otherwise - CaptureModuleState::CapState targetCapState = captureFlats ? CaptureModuleState::CAP_IDLE : CaptureModuleState::CAP_PARKED; + CaptureModuleState::CapState targetCapState = captureLights ? CaptureModuleState::CAP_IDLE : CaptureModuleState::CAP_PARKED; // If cap is parked, unpark it since dark cap uses external light source. if (m_CaptureModuleState->hasDustCap && m_CaptureModuleState->getDustCapState() != targetCapState) { - m_CaptureModuleState->setDustCapState(captureFlats ? CaptureModuleState::CAP_UNPARKING : CaptureModuleState::CAP_PARKING); - emit parkDustCap(!captureFlats); - emit newLog(captureFlats ? i18n("Unparking dust cap...") : i18n("Parking dust cap...")); + m_CaptureModuleState->setDustCapState(captureLights ? CaptureModuleState::CAP_UNPARKING : CaptureModuleState::CAP_PARKING); + emit parkDustCap(!captureLights); + emit newLog(captureLights ? i18n("Unparking dust cap...") : i18n("Parking dust cap...")); return IPS_BUSY; } - CaptureModuleState::LightState targetLightBoxStatus = (frameType == FRAME_FLAT) ? CaptureModuleState::CAP_LIGHT_ON : + auto captureFlats = (frameType == FRAME_FLAT); + CaptureModuleState::LightState targetLightBoxStatus = captureFlats ? CaptureModuleState::CAP_LIGHT_ON : CaptureModuleState::CAP_LIGHT_OFF; if (m_CaptureModuleState->hasLightBox && m_CaptureModuleState->getLightBoxLightState() != targetLightBoxStatus) @@ -504,7 +459,8 @@ KStarsData::Instance()->geo()->lat()); wpScopeStatus = WP_SLEWING; emit slewTelescope(wallCoord); - emit newLog(i18n("Mount slewing to wall position...")); + emit newLog(i18n("Mount slewing to wall position (az =%1 alt =%2)", + wallCoord.alt().toDMSString(), wallCoord.az().toDMSString())); return IPS_BUSY; } // wait until actions completed @@ -519,7 +475,7 @@ return IPS_BUSY; } else if (wpScopeStatus == WP_TRACKING_OFF) - emit newLog(i18n("Slew to wall position complete, stop tracking.")); + emit newLog(i18n("Slew to wall position complete, tracking stopped.")); // wall position reached, check if we have a light box to turn on for flats and off otherwise bool captureFlats = (frametype == FRAME_FLAT); @@ -543,7 +499,7 @@ IPState SequenceJobState::checkPreMountParkReady() { - if (preMountPark && m_CaptureModuleState->hasTelescope && flatFieldSource != SOURCE_WALL) + if (m_CaptureModuleState->hasTelescope) { if (m_CaptureModuleState->getScopeParkState() == ISD::PARK_ERROR) { @@ -567,7 +523,7 @@ IPState SequenceJobState::checkPreDomeParkReady() { - if (preDomePark && m_CaptureModuleState->hasDome) + if (m_CaptureModuleState->hasDome) { if (m_CaptureModuleState->getDomeState() == ISD::Dome::DOME_ERROR) { @@ -626,59 +582,50 @@ IPState SequenceJobState::checkLightFrameScopeCoverOpen() { - switch (flatFieldSource) + // Account for light box only (no dust cap) + if (m_CaptureModuleState->hasLightBox && m_CaptureModuleState->getLightBoxLightState() != CaptureModuleState::CAP_LIGHT_OFF) { - // All these are considered MANUAL when it comes to light frames - case SOURCE_MANUAL: - case SOURCE_DAWN_DUSK: - case SOURCE_WALL: - // If telescopes were MANUALLY covered before - // we need to manually uncover them. - if (m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANAUL_COVER_OPEN) - { - // If we already asked for confirmation and waiting for it - // let us see if the confirmation is fulfilled - // otherwise we return. - if (coverQueryState == CAL_CHECK_CONFIRMATION) - return IPS_BUSY; - - emit askManualScopeOpen(m_CaptureModuleState->m_ManualCoverState == CaptureModuleState::MANUAL_COVER_CLOSED_LIGHT); - - return IPS_BUSY; - } - break; - case SOURCE_FLATCAP: - case SOURCE_DARKCAP: - // if no state update happened, wait. - if (m_CaptureModuleState->getLightBoxLightState() == CaptureModuleState::CAP_LIGHT_BUSY || - m_CaptureModuleState->getDustCapState() == CaptureModuleState::CAP_UNPARKING) - return IPS_BUSY; - - // Account for light box only (no dust cap) - if (m_CaptureModuleState->hasLightBox && m_CaptureModuleState->getLightBoxLightState() != CaptureModuleState::CAP_LIGHT_OFF) - { - m_CaptureModuleState->setLightBoxLightState(CaptureModuleState::CAP_LIGHT_BUSY); - emit setLightBoxLight(false); - emit newLog(i18n("Turn light box light off...")); - return IPS_BUSY; - } - - if (m_CaptureModuleState->hasDustCap == false) - { - emit newLog("Skipping flat/dark cap since it is not connected."); - return IPS_OK; - } + if (m_CaptureModuleState->getLightBoxLightState() != CaptureModuleState::CAP_LIGHT_BUSY) + { + m_CaptureModuleState->setLightBoxLightState(CaptureModuleState::CAP_LIGHT_BUSY); + emit setLightBoxLight(false); + emit newLog(i18n("Turn light box light off...")); + } + return IPS_BUSY; + } - // If cap is parked, we need to unpark it - if (m_CaptureModuleState->getDustCapState() != CaptureModuleState::CAP_IDLE) + // If we have a dust cap, then we must unpark + if (m_CaptureModuleState->hasDustCap) + { + if (m_CaptureModuleState->getDustCapState() != CaptureModuleState::CAP_IDLE) + { + if (m_CaptureModuleState->getDustCapState() != CaptureModuleState::CAP_UNPARKING) { m_CaptureModuleState->setDustCapState(CaptureModuleState::CAP_UNPARKING); emit parkDustCap(false); emit newLog(i18n("Unparking dust cap...")); - return IPS_BUSY; } - break; + return IPS_BUSY; + } + + return IPS_OK; } + + // If telescopes were MANUALLY covered before + // we need to manually uncover them. + if (m_CaptureModuleState->m_ManualCoverState != CaptureModuleState::MANAUL_COVER_OPEN) + { + // If we already asked for confirmation and waiting for it + // let us see if the confirmation is fulfilled + // otherwise we return. + if (coverQueryState == CAL_CHECK_CONFIRMATION) + return IPS_BUSY; + + emit askManualScopeOpen(m_CaptureModuleState->m_ManualCoverState == CaptureModuleState::MANUAL_COVER_CLOSED_LIGHT); + + return IPS_BUSY; + } + // scope cover open (or no scope cover) return IPS_OK; } @@ -776,15 +723,6 @@ } } -void SequenceJobState::setCurrentGuiderDrift(double value) -{ - setInitialized(CaptureModuleState::ACTION_GUIDER_DRIFT, true); - if (value <= targetStartGuiderDrift) - prepareActions[CaptureModuleState::ACTION_GUIDER_DRIFT] = true; - - checkAllActionsReady(); -} - void SequenceJobState::setFocusStatus(FocusState state) { switch (state) @@ -921,15 +859,6 @@ // re-run checks checkAllActionsReady(); } - -void SequenceJobState::setEnforceInitialGuidingDrift(bool enforceInitialGuidingDrift) -{ - m_enforceInitialGuiding = enforceInitialGuidingDrift; - // update the preparation action - prepareActions[CaptureModuleState::ACTION_GUIDER_DRIFT] = !enforceInitialGuidingDrift || m_isPreview; - // re-run checks - checkAllActionsReady(); -} SequenceJobState::PreparationState SequenceJobState::getPreparationState() const { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/capture/sequencejobstate.h 2023-12-03 05:23:17.000000000 +0000 @@ -11,7 +11,6 @@ #include "capturemodulestate.h" #include "ekos/auxiliary/filtermanager.h" #include "fitsviewer/fitscommon.h" -#include "ekos/auxiliary/rotatorutils.h" #include #include @@ -108,10 +107,9 @@ /** * @brief Trigger all peparation actions before a capture may be started. * @param enforceCCDTemp flag if the CCD temperature should be set to the target value. - * @param enforceInitialGuidingDrift flag if the initial guiding drift must be below the target value. * @param isPreview flag if the captures are in the preview mode */ - void prepareLightFrameCapture(bool enforceCCDTemp, bool enforceInitialGuidingDrift, bool isPreview); + void prepareLightFrameCapture(bool enforceCCDTemp, bool isPreview); /** * @brief Initiate tasks required so that capturing of flats may start. @@ -145,11 +143,6 @@ bool initCapture(CCDFrameType frameType, bool isPreview, bool isAutofocusReady, FITSMode mode); /** - * @brief Set the flag if a maximal initial guiding deviation is required - */ - void setEnforceInitialGuidingDrift(bool enforceInitialGuidingDrift); - - /** * @brief The current capture sequence job status */ JOBStatus getStatus() @@ -198,10 +191,6 @@ targetTemperature = value; } /** - * @brief Update the current guiding deviation. - */ - void setCurrentGuiderDrift(double value); - /** * @brief Set the target guiding deviation when capture starts */ void setTargetStartGuiderDrift(double value) @@ -329,8 +318,6 @@ bool m_isPreview { false }; // should a certain temperature should be enforced? bool m_enforceTemperature { false }; - // should the a certain maximal initial guiding drift should be enforced? - bool m_enforceInitialGuiding { false }; // flag if auto focus has been completed for the selected filter bool autoFocusReady; // Capturing mode, necessary for the display in the FITS viewer @@ -341,15 +328,11 @@ // status of the focuser synchronisation FlatSyncStatus flatSyncStatus { FS_NONE }; // light source for flat capturing - FlatFieldSource flatFieldSource { SOURCE_MANUAL }; + uint32_t m_CalibrationPreAction { ACTION_NONE }; // wall coordinates for capturing flats with the wall as light source SkyPoint wallCoord; // telescope status for flats using the wall position ScopeWallPositionStatus wpScopeStatus { WP_NONE }; - // flag if the mount should be parking before capturing - bool preMountPark; - // flag if the dome should be parking before capturing - bool preDomePark; // //////////////////////////////////////////////////////////////////// // capture preparation state @@ -410,11 +393,17 @@ // //////////////////////////////////////////////////////////////////// /** - * @brief Check if the selected flats light source is ready. + * @brief checkCalibrationPreActionsReady Check if we completed all the required pre-calibration actions + * @return IPS_OK if completed, IPS_BUSY if in progress, and IPS_ALERT if trouble. + */ + IPState checkCalibrationPreActionsReady(); + + /** + * @brief Check if the cover and light for flats is ready * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the * process should be aborted. */ - IPState checkFlatsLightCoverReady(); + IPState checkFlatsCoverReady(); /** * @brief Check if the selected dark covers is ready. @@ -424,19 +413,11 @@ IPState checkDarksCoverReady(); /** - * @brief Ask the user to place a flat screen onto the telescope + * @brief Ask the user to place a flat screen onto the telescope if a light source is required. * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the * process should be aborted. */ - IPState checkManualCoverReady(bool light); - - /** - * @brief Check if the telescope cap with internal light source is ready - * for capturing flats. - * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the - * process should be aborted. - */ - IPState checkFlatCapReady(); + IPState checkManualCoverReady(bool lightSourceRequired); /** * @brief Check if the telescope dust cap is ready for capturing flats or darks. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/cloud.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/cloud.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/cloud.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/cloud.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -13,6 +13,7 @@ #include "ekos_debug.h" #include "version.h" #include "../fitsviewer/fpack.h" +#include "Options.h" #include #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/commands.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/commands.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/commands.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/commands.h 2023-12-03 05:23:17.000000000 +0000 @@ -20,6 +20,7 @@ GET_DRIVERS, GET_DEVICES, NEW_CONNECTION_STATE, + NEW_INDI_STATE, NEW_MOUNT_STATE, NEW_CAMERA_STATE, NEW_CAPTURE_STATE, @@ -254,6 +255,7 @@ {GET_DRIVERS, "get_drivers"}, {GET_DEVICES, "get_devices"}, {NEW_CONNECTION_STATE, "new_connection_state"}, + {NEW_INDI_STATE, "new_indi_state"}, {NEW_MOUNT_STATE, "new_mount_state"}, {NEW_CAMERA_STATE, "new_camera_state"}, {NEW_CAPTURE_STATE, "new_capture_state"}, diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/media.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/media.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/media.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/media.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -13,8 +13,10 @@ #include "fitsviewer/fitsdata.h" #include "indi/indilistener.h" #include "hips/hipsfinder.h" +#include "kstarsdata.h" #include "ekos/auxiliary/darklibrary.h" #include "ekos/guide/guide.h" +#include "ekos/align/align.h" #include "kspaths.h" #include "Options.h" @@ -367,6 +369,7 @@ {"midtones", stretchParameters.grey_red.midtones}, {"highlights", stretchParameters.grey_red.highlights}, {"hasWCS", imageData->hasWCS()}, + {"hfr", imageData->getHFR()}, {"ext", ext} }; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/message.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/message.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/message.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/message.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -16,7 +16,10 @@ #include "ekos/auxiliary/filtermanager.h" #include "ekos/auxiliary/opticaltrainmanager.h" #include "ekos/auxiliary/profilesettings.h" +#include "ekos/capture/capture.h" #include "ekos/guide/guide.h" +#include "ekos/mount/mount.h" +#include "ekos/scheduler/scheduler.h" #include "kstars.h" #include "kstarsdata.h" #include "ekos_debug.h" @@ -1236,6 +1239,19 @@ } /////////////////////////////////////////////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////////////////////////////////////////////// +void Message::setINDIStatus(Ekos::CommunicationStatus status) +{ + QJsonObject connectionState = + { + {"status", status}, + }; + + sendResponse(commands[NEW_INDI_STATE], connectionState); +} + +/////////////////////////////////////////////////////////////////////////////////////////// /// /////////////////////////////////////////////////////////////////////////////////////////// void Message::processOptionsCommands(const QString &command, const QJsonObject &payload) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/message.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/message.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/ekoslive/message.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/ekoslive/message.h 2023-12-03 05:23:17.000000000 +0000 @@ -65,6 +65,9 @@ // Ekos void setEkosStatingStatus(Ekos::CommunicationStatus status); + // INDI + void setINDIStatus(Ekos::CommunicationStatus status); + // Alignment void setAlignStatus(Ekos::AlignState newState); void setAlignSolution(const QVariantMap &solution); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,1362 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "aberrationinspector.h" +#include "aberrationinspectorplot.h" +#include "sensorgraphic.h" +#include +#include "kstars.h" +#include "Options.h" +#include + +const float RADIANS2DEGREES = 360.0f / (2.0f * M_PI); + +namespace Ekos +{ + +AberrationInspector::AberrationInspector(const abInsData &data, const QVector &positions, + const QVector> &measures, const QVector> &weights, + const QVector> &numStars, const QVector &tileCenterOffsets) : + m_data(data), m_positions(positions), m_measures(measures), m_weights(weights), + m_numStars(numStars), m_tileOffsets(tileCenterOffsets) +{ +#ifdef Q_OS_OSX + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); +#endif + + // 1. Setup the GUI + setupUi(this); + setupGUI(); + + // 2. Initialise the widget + initAberrationInspector(); + + // 3. Curve fit the data for each tile and update Aberration Inspector with results + fitCurves(); + + // 4. Initialise the 3D graphic + initGraphic(); + + // 5. Restore persisted settings + loadSettings(); + + // 6. connect signals to persist changes to user settings + connectSettings(); + + // Display data appropriate to the tile selection + setTileSelection(static_cast(abInsTileSelection->currentIndex())); +} + +AberrationInspector::~AberrationInspector() +{ +} + +void AberrationInspector::setupGUI() +{ + // Set the title. Use run number to differentiate runs + this->setWindowTitle(i18n("Aberration Inspector - Run %1", m_data.run)); + + // Connect up button callbacks + connect(aberrationInspectorButtonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, this, [this]() + { + this->done(QDialog::Accepted); + }); + + connect(abInsTileSelection, static_cast(&QComboBox::currentIndexChanged), this, [&](int index) + { + setTileSelection(static_cast(index)); + }); + + connect(abInsShowLabels, &QCheckBox::toggled, this, [&](bool setting) + { + setShowLabels(setting); + }); + + connect(abInsShowCFZ, &QCheckBox::toggled, this, [&](bool setting) + { + setShowCFZ(setting); + }); + + connect(abInsOptCentres, &QCheckBox::toggled, this, [&](bool setting) + { + setOptCentres(setting); + }); + + // Create a plot widget and add to the top of the dialog + m_plot = new AberrationInspectorPlot(this); + abInsPlotLayout->addWidget(m_plot); + + // Setup the results table + QStringList Headers { i18n("Tile"), i18n("Description"), i18n("Solution"), i18n("Delta (ticks)"), i18n("Delta (μm)"), i18n("Num Stars"), i18n("R²"), i18n("Exclude")}; + abInsTable->setColumnCount(Headers.count()); + abInsTable->setHorizontalHeaderLabels(Headers); + + // Setup tooltips on column headers + abInsTable->horizontalHeaderItem(0)->setToolTip(i18n("Tile")); + abInsTable->horizontalHeaderItem(1)->setToolTip(i18n("Description")); + abInsTable->horizontalHeaderItem(2)->setToolTip(i18n("Focuser Solution")); + abInsTable->horizontalHeaderItem(3)->setToolTip(i18n("Delta from central tile in ticks")); + abInsTable->horizontalHeaderItem(4)->setToolTip(i18n("Delta from central tile in micrometers")); + abInsTable->horizontalHeaderItem(5)->setToolTip(i18n("Min / max number of stars detected in the focus run")); + abInsTable->horizontalHeaderItem(6)->setToolTip(i18n("R²")); + abInsTable->horizontalHeaderItem(7)->setToolTip(i18n("Check to exclude row from calculations")); + + // Prevent editing of table widget (except the exclude checkboxes) unless in production support mode + QAbstractItemView::EditTrigger editTrigger = ABINS_DEBUG ? QAbstractItemView::DoubleClicked : + QAbstractItemView::NoEditTriggers; + abInsTable->setEditTriggers(editTrigger); + + // Connect up table widget events: cellEntered when mouse moves over a cell + connect(abInsTable, &AbInsTableWidget::cellEntered, this, &AberrationInspector::newMousePos); + // leaveTableEvent is signalled when the mouse is moved away from "table". + connect(abInsTable, &AbInsTableWidget::leaveTableEvent, this, &AberrationInspector::leaveTableEvent); + + // Setup a SensorGraphic minimal window that acts like a visual tooltip + sensorGraphic = new SensorGraphic(abInsTable, m_data.sensorWidth, m_data.sensorHeight, m_data.tileWidth); +} + +// Mouse over table row, col. Show the sensor graphic +void AberrationInspector::newMousePos(int row, int column) +{ + if (column <= 1) + { + QTableWidgetItem *tile = abInsTable->item(row, 0); + for (int i = 0; i < NUM_TILES; i++) + { + if (TILE_NAME[i] == tile->text()) + { + // Set the highlight row + sensorGraphic->setHighlight(i); + // Move the graphic to the mouse position + sensorGraphic->move(QCursor::pos()); + // If the graphic is hidden then show it; if details have changed then repaint it + if (m_HighlightedRow != -1 && m_HighlightedRow != i) + sensorGraphic->repaint(); + else + sensorGraphic->show(); + m_HighlightedRow = row; + return; + } + } + } + m_HighlightedRow = -1; + sensorGraphic->hide(); +} + +// Called when table widget gets a mouse leave event; hide the sensor graphic +void AberrationInspector::leaveTableEvent() +{ + m_HighlightedRow = -1; + if (sensorGraphic) + sensorGraphic->hide(); +} + +// Called when the "Exclude" checkbox state is changed by the user +void AberrationInspector::onStateChanged(int state) +{ + Q_UNUSED(state); + + // Get the row and state of the checkbox + QCheckBox* cb = qobject_cast(QObject::sender()); + int row = cb->property("row").toInt(); + bool checked = cb->isChecked(); + + // Set the exclude flag for the excluded tile + setExcludeTile(row, checked, static_cast(abInsTileSelection->currentIndex())); + // Rerun the calcs so the newly changed exclude flag is taken into account + setTileSelection(static_cast(abInsTileSelection->currentIndex())); +} + +// Called when table cell has been changed +// This is a production support debug feature that is contolled by ABINS_DEBUG flag +// For normal use table editing is disabled and this function not called. +void AberrationInspector::onCellChanged(int row, int column) +{ + if (column != 3) + return; + + // Get the new value + QTableWidgetItem *item = abInsTable->item(row, column); + int value = item->text().toInt(); + + int tile = getTileFromRow(static_cast(abInsTileSelection->currentIndex()), row); + + if (tile >= 0 && tile < NUM_TILES) + { + m_minimum[tile] = value + m_minimum[TILE_CM]; + // Rerun the calcs so the newly changed exclude flag is taken into account + setTileSelection(static_cast(abInsTileSelection->currentIndex())); + } +} + +int AberrationInspector::getTileFromRow(TileSelection tileSelection, int row) +{ + int tile = -1; + + if (row < 0 || row >= NUM_TILES) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid row %2").arg(__FUNCTION__).arg(row); + return tile; + } + + switch(tileSelection) + { + case TileSelection::TILES_ALL: + // Use all tiles + tile = row; + break; + + case TileSelection::TILES_OUTER_CORNERS: + // Use tiles 0, 2, 4, 6, 8 + tile = row * 2; + break; + + case TileSelection::TILES_INNER_DIAMOND: + // Use tiles 1, 3, 4, 5, 7 + if (row < 2) + tile = (row * 2) + 1; + else if (row == 2) + tile = 4; + else + tile = (row * 2) - 1; + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called but TileSelection invalid").arg(__FUNCTION__); + break; + } + return tile; +} + +void AberrationInspector::setExcludeTile(int row, bool checked, TileSelection tileSelection) +{ + if (row < 0 || row >= NUM_TILES) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid row %2").arg(__FUNCTION__).arg(row); + return; + } + + int tile = getTileFromRow(tileSelection, row); + if (tile >= 0 && tile < NUM_TILES) + m_excludeTile[tile] = checked; +} + +void AberrationInspector::connectSettings() +{ + // All Combo Boxes + for (auto &oneWidget : findChildren()) + connect(oneWidget, QOverload::of(&QComboBox::activated), this, &Ekos::AberrationInspector::syncSettings); + + // All Checkboxes, except Sim mode checkbox - this should be defaulted to off when Aberratio Inspector starts + for (auto &oneWidget : findChildren()) + if (oneWidget != abInsSimMode) + connect(oneWidget, &QCheckBox::toggled, this, &Ekos::AberrationInspector::syncSettings); + + // All Splitters + for (auto &oneWidget : findChildren()) + connect(oneWidget, &QSplitter::splitterMoved, this, &Ekos::AberrationInspector::syncSettings); +} + +void AberrationInspector::loadSettings() +{ + QString key; + QVariant value; + + // All Combo Boxes + for (auto &oneWidget : findChildren()) + { + key = oneWidget->objectName(); + value = Options::self()->property(key.toLatin1()); + if (value.isValid()) + oneWidget->setCurrentText(value.toString()); + else + qCDebug(KSTARS_EKOS_FOCUS) << "ComboBox Option" << key << "not found!"; + } + + // All Checkboxes + for (auto &oneWidget : findChildren()) + { + key = oneWidget->objectName(); + if (key == abInsSimMode->objectName() || key == "") + // Sim mode setting isn't persisted as it is always off on Aberration Inspector start. + // Also the table widget has a column of checkboxes whose value is data dependent so these aren't persisted + continue; + + value = Options::self()->property(key.toLatin1()); + if (value.isValid()) + oneWidget->setChecked(value.toBool()); + else + qCDebug(KSTARS_EKOS_FOCUS) << "Checkbox Option" << key << "not found!"; + } + + // All Splitters + for (auto &oneWidget : findChildren()) + { + key = oneWidget->objectName(); + value = Options::self()->property(key.toLatin1()); + if (value.isValid()) + { + // Convert the saved QString to a QByteArray using Base64 + auto valueBA = QByteArray::fromBase64(value.toString().toUtf8()); + oneWidget->restoreState(valueBA); + } + else + qCDebug(KSTARS_EKOS_FOCUS) << "Splitter Option" << key << "not found!"; + } +} + +void AberrationInspector::syncSettings() +{ + QComboBox *cbox = nullptr; + QCheckBox *cb = nullptr; + QSplitter *s = nullptr; + + QString key; + QVariant value; + + if ( (cbox = qobject_cast(sender()))) + { + key = cbox->objectName(); + value = cbox->currentText(); + } + else if ( (cb = qobject_cast(sender()))) + { + key = cb->objectName(); + value = cb->isChecked(); + } + else if ( (s = qobject_cast(sender()))) + { + key = s->objectName(); + // Convert from the QByteArray to QString using Base64 + value = QString::fromUtf8(s->saveState().toBase64()); + } + + // Save changed setting + Options::self()->setProperty(key.toLatin1(), value); + Options::self()->save(); +} + +// Setup display widgets to match tileSelection +void AberrationInspector::setTileSelection(TileSelection tileSelection) +{ + // Setup array of tiles to use, based on user selection + setupTiles(tileSelection); + // Redraw the v-curves based on user selection + m_plot->redrawCurve(m_useTile); + // Update the table widget based on user selection + updateTable(); + // Update the results based on user selection + analyseResults(); + // Update the 3D graphic based on user selection + updateGraphic(tileSelection); + // resize table widget based on contents + tableResize(); + // Updates changes to the v-curves + m_plot->replot(); +} + +void AberrationInspector::setupTiles(TileSelection tileSelection) +{ + switch(tileSelection) + { + case TileSelection::TILES_ALL: + // Use all tiles + for (int i = 0; i < NUM_TILES; i++) + m_useTile[i] = true; + break; + + case TileSelection::TILES_OUTER_CORNERS: + // Use tiles TL, TR, CM, BL, BR + m_useTile[TILE_TL] = m_useTile[TILE_TR] = m_useTile[TILE_CM] = m_useTile[TILE_BL] = m_useTile[TILE_BR] = true; + m_useTile[TILE_TM] = m_useTile[TILE_CL] = m_useTile[TILE_CR] = m_useTile[TILE_BM] = false; + break; + + case TileSelection::TILES_INNER_DIAMOND: + // Use tiles TM, CL, CM, CR, BM + m_useTile[TILE_TL] = m_useTile[TILE_TR] = m_useTile[TILE_BL] = m_useTile[TILE_BR] = false; + m_useTile[TILE_TM] = m_useTile[TILE_CL] = m_useTile[TILE_CM] = m_useTile[TILE_CR] = m_useTile[TILE_BM] = true; + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile selection %2").arg(__FUNCTION__).arg(tileSelection); + break; + } +} + +void AberrationInspector::setShowLabels(bool setting) +{ + m_plot->setShowLabels(setting); + m_plot->replot(); +} + +void AberrationInspector::setShowCFZ(bool setting) +{ + m_plot->setShowCFZ(setting); + m_plot->replot(); +} + +// Rerun calculations to take the Optimise Tile Centres setting into account +void AberrationInspector::setOptCentres(bool setting) +{ + Q_UNUSED(setting); + setTileSelection(static_cast(abInsTileSelection->currentIndex())); +} + +void AberrationInspector::initAberrationInspector() +{ + // Initialise the plot widget + m_plot->init(m_data.yAxisLabel, m_data.starUnits, m_data.useWeights, abInsShowLabels->isChecked(), + abInsShowCFZ->isChecked()); +} + +// Resize the dialog to the data +void AberrationInspector::tableResize() +{ + // Resize the table columns to fit the data on display in it. + abInsTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + abInsTable->verticalHeader()->resizeSections(QHeaderView::ResizeToContents); +} + +// Run curve fitting on the collected data for each tile, updating other widgets as we go +void AberrationInspector::fitCurves() +{ + curveFitting.reset(new CurveFitting()); + + const double expected = 0.0; + int minPos, maxPos; + + QVector outliers; + for (int i = 0; i < m_positions.count(); i++) + { + outliers.append(false); + if (i == 0) + minPos = maxPos = m_positions[i]; + else + { + minPos = std::min(minPos, m_positions[i]); + maxPos = std::max(maxPos, m_positions[i]); + } + } + + for (int tile = 0; tile < m_measures.count(); tile++) + { + curveFitting->fitCurve(CurveFitting::FittingGoal::BEST, m_positions, m_measures[tile], m_weights[tile], outliers, + m_data.curveFit, m_data.useWeights, m_data.optDir); + + double position = 0.0; + double measure = 0.0; + double R2 = 0.0; + bool foundFit = curveFitting->findMinMax(expected, static_cast(minPos), static_cast(maxPos), &position, + &measure, m_data.curveFit, m_data.optDir); + if (foundFit) + R2 = curveFitting->calculateR2(m_data.curveFit); + + position = round(position); + m_minimum.append(position); + m_minMeasure.append(measure); + m_fit.append(foundFit); + m_R2.append(R2); + + // Add the datapoints to the plot for the current tile + // JEE Need to sort out what to do with outliers... for now ignore them + QVector outliers; + for (int i = 0; i < m_measures[tile].count(); i++) + { + outliers.append(false); + } + + m_plot->addData(m_positions, m_measures[tile], m_weights[tile], outliers); + // Fit the curve - note this needs curveFitting with the parameters for the current solution + m_plot->drawCurve(tile, curveFitting.get(), position, measure, foundFit, R2); + // Draw solutions on the plot + m_plot->drawMaxMin(tile, position, measure); + // Draw the CFZ for the central tile + if (tile == TILE_CM) + m_plot->drawCFZ(position, measure, m_data.cfzSteps); + } +} + +// Update the results table +void AberrationInspector::updateTable() +{ + // Disconnect the cell changed callback to stop it firing whilst the table is updated + disconnect(abInsTable, &AbInsTableWidget::cellChanged, this, &AberrationInspector::onCellChanged); + + if (abInsTileSelection->currentIndex() == TILES_ALL) + abInsTable->setRowCount(NUM_TILES); + else + abInsTable->setRowCount(5); + + int rowCounter = -1; + for (int i = 0; i < NUM_TILES; i++) + { + if (!m_useTile[i]) + continue; + + ++rowCounter; + + QTableWidgetItem *tile = new QTableWidgetItem(TILE_NAME[i]); + tile->setForeground(QColor(TILE_COLOUR[i])); + abInsTable->setItem(rowCounter, 0, tile); + + QTableWidgetItem *description = new QTableWidgetItem(TILE_LONGNAME[i]); + abInsTable->setItem(rowCounter, 1, description); + + QTableWidgetItem *solution = new QTableWidgetItem(QString::number(m_minimum[i])); + solution->setTextAlignment(Qt::AlignRight); + abInsTable->setItem(rowCounter, 2, solution); + + int ticks = m_minimum[i] - m_minimum[TILE_CM]; + QTableWidgetItem *deltaTicks = new QTableWidgetItem(QString::number(ticks)); + deltaTicks->setTextAlignment(Qt::AlignRight); + abInsTable->setItem(rowCounter, 3, deltaTicks); + + int microns = ticks * m_data.focuserStepMicrons; + QTableWidgetItem *deltaMicrons = new QTableWidgetItem(QString::number(microns)); + deltaMicrons->setTextAlignment(Qt::AlignRight); + abInsTable->setItem(rowCounter, 4, deltaMicrons); + + int minNumStars = *std::min_element(m_numStars[i].constBegin(), m_numStars[i].constEnd()); + int maxNumStars = *std::max_element(m_numStars[i].constBegin(), m_numStars[i].constEnd()); + QTableWidgetItem *numStars = new QTableWidgetItem(QString("%1 / %2").arg(minNumStars).arg(maxNumStars)); + numStars->setTextAlignment(Qt::AlignRight); + abInsTable->setItem(rowCounter, 5, numStars); + + QTableWidgetItem *R2 = new QTableWidgetItem(QString("%1").arg(m_R2[i], 0, 'f', 2)); + R2->setTextAlignment(Qt::AlignRight); + abInsTable->setItem(rowCounter, 6, R2); + + QWidget *checkBoxWidget = new QWidget(abInsTable); + QCheckBox *checkBox = new QCheckBox(); + // Set the checkbox based on whether curve fitting worked + checkBox->setChecked(!m_fit[i] || m_excludeTile[i]); + checkBox->setEnabled(m_fit[i]); + // Add a property to identify the row when the user changes the check state. + checkBox->setProperty("row", rowCounter); + // In order to centre the widget, we need to insert it into a layout and align that + QHBoxLayout *layoutCheckBox = new QHBoxLayout(checkBoxWidget); + layoutCheckBox->addWidget(checkBox); + layoutCheckBox->setAlignment(Qt::AlignCenter); + + abInsTable->setCellWidget(rowCounter, 7, checkBoxWidget); + // The tableWidget cellChanged event doesn't fire when the checkbox state is changed. + // Seems like the only way to get the event is to connect up directly to the checkbox + connect(checkBox, &QCheckBox::stateChanged, this, &AberrationInspector::onStateChanged); + } + connect(abInsTable, &AbInsTableWidget::cellChanged, this, &AberrationInspector::onCellChanged); + + // Update the sensor graphic with the current tile selection + sensorGraphic->setTiles(m_useTile); +} + +// Analyse the results for backfocus delta and tilt based on tile selection. +void AberrationInspector::analyseResults() +{ + // Backfocus + // +result = move sensor nearer field flattener + // -result = move sensor further from field flattener + bool backfocusOK = calcBackfocusDelta(static_cast(abInsTileSelection->currentIndex()), m_backfocus); + + // Update backfocus screen widgets + if (!backfocusOK) + backfocus->setText(i18n("N/A")); + else + { + QString side = ""; + if (m_backfocus < -0.9) + side = i18n("Move sensor nearer flattener"); + else if (m_backfocus > 0.9) + side = i18n("Move sensor away from flattener"); + backfocus->setText(QString("%1μm. %2").arg(m_backfocus, 0, 'f', 0).arg(side)); + } + + // Tilt + bool tiltOK = calcTilt(); + + // Update tilt screen widgets + if (!tiltOK) + { + lrTilt->setText(i18n("N/A")); + tbTilt->setText(i18n("N/A")); + totalTilt->setText(i18n("N/A")); + } + else + { + lrTilt->setText(QString("%1μm / %2%").arg(m_LRMicrons, 0, 'f', 0).arg(m_LRTilt, 0, 'f', 2)); + tbTilt->setText(QString("%1μm / %2%").arg(m_TBMicrons, 0, 'f', 0).arg(m_TBTilt, 0, 'f', 2)); + totalTilt->setText(QString("%1μm / %2%").arg(m_diagonalMicrons, 0, 'f', 0) + .arg(m_diagonalTilt, 0, 'f', 2)); + } + + // Set m_resultsOK dependent on whether calcs were successful or not + m_resultsOK = backfocusOK && tiltOK; +} + +// Calculate the backfocus in microns +// Note that the tile positions are at different distances from the sensor centre so we need to weight +// values by the distance to tile centre. Also, we only include tiles for which curve fitting worked +// and for which the user hasn't elected to exclude +bool AberrationInspector::calcBackfocusDelta(TileSelection tileSelection, double &backfocusDelta) +{ + backfocusDelta = 0.0; + + // Firstly check that we have a valid central tile - we can't do anything without that + if (!m_fit[TILE_CM] || m_excludeTile[TILE_CM]) + return false; + + double dist = 0.0, sum = 0.0, counter = 0.0; + + switch(tileSelection) + { + case TileSelection::TILES_ALL: + // Use all useable tiles weighted by their distance from the centre + for (int i = 0; i < NUM_TILES; i++) + { + if (i == TILE_CM) + continue; + + if (m_fit[i] && !m_excludeTile[i]) + { + dist = getXYTileCentre(static_cast(i)).length(); + sum += m_minimum[i] * dist; + counter += dist; + } + } + if (counter == 0) + // No valid tiles so can't complete the calc + return false; + break; + + case TileSelection::TILES_OUTER_CORNERS: + // All tiles are diagonal from centre... so no need to weight the calc + // Use tiles 0, 2, 6, 8 + if (m_fit[0] && !m_excludeTile[0]) + { + sum += m_minimum[0]; + counter++; + } + if (m_fit[2] && !m_excludeTile[2]) + { + sum += m_minimum[2]; + counter++; + } + if (m_fit[6] && !m_excludeTile[6]) + { + sum += m_minimum[6]; + counter++; + } + if (m_fit[8] && !m_excludeTile[8]) + { + sum += m_minimum[8]; + counter++; + } + + if (counter == 0) + // No valid tiles so can't complete the calc + return false; + break; + + case TileSelection::TILES_INNER_DIAMOND: + // Tiles are different distances from centre... so need to weight the calc + // Use tiles 1, 3, 5, 7 + if (m_fit[TILE_TM] && !m_excludeTile[TILE_TM]) + { + dist = getXYTileCentre(TILE_TM).length(); + sum += m_minimum[TILE_TM] * dist; + counter += dist; + } + if (m_fit[TILE_CL] && !m_excludeTile[TILE_CL]) + { + dist = getXYTileCentre(TILE_CL).length(); + sum += m_minimum[TILE_CL] * dist; + counter += dist; + } + if (m_fit[TILE_CR] && !m_excludeTile[TILE_CR]) + { + dist = getXYTileCentre(TILE_CR).length(); + sum += m_minimum[TILE_CR] * dist; + counter += dist; + } + if (m_fit[TILE_BM] && !m_excludeTile[TILE_BM]) + { + dist = getXYTileCentre(TILE_BM).length(); + sum += m_minimum[TILE_BM] * dist; + counter += dist; + } + + if (counter == 0) + // No valid tiles so can't complete the calc + return false; + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile selection %2").arg(__FUNCTION__).arg(tileSelection); + return false; + break; + } + backfocusDelta = (m_minimum[TILE_CM] - (sum / counter)) * m_data.focuserStepMicrons; + return true; +} + +bool AberrationInspector::calcTilt() +{ + // Firstly check that we have a valid central tile - we can't do anything without that + if (!m_fit[TILE_CM] || m_excludeTile[TILE_CM]) + return false; + + // Calculate the deltas relative to the centre tile in microns + m_deltas.clear(); + for (int tile = 0; tile < NUM_TILES; tile++) + m_deltas.append((m_minimum[TILE_CM] - m_minimum[tile]) * m_data.focuserStepMicrons); + + // Calculate the average tile position for left, right, top and bottom. If any of these cannot be + // calculated then fail the whole calculation. + double avLeft, avRight, avTop, avBottom; + int tilesL[3] = { 0, 3, 6 }; + if (!avTiles(tilesL, avLeft)) + return false; + int tilesR[3] = { 2, 5, 8 }; + if (!avTiles(tilesR, avRight)) + return false; + int tilesT[3] = { 0, 1, 2 }; + if (!avTiles(tilesT, avTop)) + return false; + int tilesB[3] = { 6, 7, 8 }; + if(!avTiles(tilesB, avBottom)) + return false; + + m_LRMicrons = avLeft - avRight; + m_TBMicrons = avTop - avBottom; + m_diagonalMicrons = std::hypot(m_LRMicrons, m_TBMicrons); + + // Calculate the sensor spans in microns + const double LRSpan = (m_data.sensorWidth - m_data.tileWidth) * m_data.pixelSize; + const double TBSpan = (m_data.sensorHeight - m_data.tileWidth) * m_data.pixelSize; + + // Calculate the tilt as a % slope + m_LRTilt = m_LRMicrons / LRSpan * 100.0; + m_TBTilt = m_TBMicrons / TBSpan * 100.0; + m_diagonalTilt = std::hypot(m_LRTilt, m_TBTilt); + return true; +} + +// Averages upto 3 passed in tile values. +bool AberrationInspector::avTiles(int tiles[3], double &average) +{ + double sum = 0.0; + int counter = 0; + for (int i = 0; i < 3; i++) + { + if (m_useTile[tiles[i]] && m_fit[tiles[i]] && !m_excludeTile[tiles[i]]) + { + sum += m_deltas[tiles[i]]; + counter++; + } + } + if (counter > 0) + average = sum / counter; + return (counter > 0); +} + +// Initialise the 3D graphic +void AberrationInspector::initGraphic() +{ + // Create a 3D Surface widget and add to the dialog + m_graphic = new Q3DSurface(); + QWidget *container = QWidget::createWindowContainer(m_graphic); + + // abInsHSplitter is created in the .ui file but, by default, doesn't work - don't know why + // Workaround is to create a new QSplitter object and use that. + abInsHSplitter = new QSplitter(abInsVSplitter); + abInsHSplitter->setObjectName(QString::fromUtf8("abInsHSplitter")); + abInsHSplitter->addWidget(tableAndResultsWidget); + abInsHSplitter->addWidget(widget); + hLayout->insertWidget(0, container, 1); + auto value = Options::abInsHSplitter(); + // Convert the saved QString to a QByteArray using Base64 + auto valueBA = QByteArray::fromBase64(value.toUtf8()); + abInsHSplitter->restoreState(valueBA); + connect(abInsHSplitter, &QSplitter::splitterMoved, this, &Ekos::AberrationInspector::syncSettings); + + connect(abInsSelection, static_cast(&QComboBox::currentIndexChanged), this, [&](int index) + { + if (index == 0) + m_graphic->setSelectionMode(QAbstract3DGraph::SelectionNone); + else if (index == 1) + m_graphic->setSelectionMode(QAbstract3DGraph::SelectionItem); + else if (index == 2) + m_graphic->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn | QAbstract3DGraph::SelectionSlice | + QAbstract3DGraph::SelectionMultiSeries); + }); + + connect(abInsTheme, static_cast(&QComboBox::currentIndexChanged), this, [&](int index) + { + m_graphic->activeTheme()->setType(Q3DTheme::Theme(index)); + }); + + connect(abInsLabels, &QCheckBox::toggled, this, [&](bool setting) + { + m_graphicLabels = setting; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); + }); + + connect(abInsSensor, &QCheckBox::toggled, this, [&](bool setting) + { + m_graphicSensor = setting; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); + }); + + connect(abInsPetzvalWire, &QCheckBox::toggled, this, [&](bool setting) + { + m_graphicPetzvalWire = setting; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); + }); + connect(abInsPetzvalSurface, &QCheckBox::toggled, this, [&](bool setting) + { + m_graphicPetzvalSurface = setting; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); + }); + + // Simulation on/off + connect(abInsSimMode, &QCheckBox::toggled, this, &AberrationInspector::simModeToggled); + + m_sensor = new QSurface3DSeries; + m_sensorProxy = new QSurfaceDataProxy(); + m_sensor->setDataProxy(m_sensorProxy); + m_graphic->addSeries(m_sensor); + + m_petzval = new QSurface3DSeries; + m_petzvalProxy = new QSurfaceDataProxy(); + m_petzval->setDataProxy(m_petzvalProxy); + m_graphic->addSeries(m_petzval); + + m_graphic->axisX()->setTitle("X Axis (μm) - Sensor Left to Right"); + m_graphic->axisY()->setTitle("Y Axis (μm) - Sensor Top to Bottom"); + m_graphic->axisZ()->setTitle("Z Axis (μm) - Axis of Telescope"); + + m_graphic->axisX()->setLabelFormat("%.0f"); + m_graphic->axisY()->setLabelFormat("%.0f"); + m_graphic->axisZ()->setLabelFormat("%.0f"); + + m_graphic->axisX()->setTitleVisible(true); + m_graphic->axisY()->setTitleVisible(true); + m_graphic->axisZ()->setTitleVisible(true); + + m_graphic->activeTheme()->setType(Q3DTheme::ThemePrimaryColors); + + // Set projection and shadows + m_graphic->setOrthoProjection(false); + m_graphic->setShadowQuality(QAbstract3DGraph::ShadowQualityNone); + // Balance the z-axis with the x-y plane. Without this the z-axis is crushed to a very small scale + m_graphic->setHorizontalAspectRatio(2.0); +} + +// Simulation on/off switch toggled +void AberrationInspector::simModeToggled(bool setting) +{ + m_simMode = setting; + abInsBackfocusSlider->setEnabled(setting); + abInsTiltLRSlider->setEnabled(setting); + abInsTiltTBSlider->setEnabled(setting); + if (!m_simMode) + { + // Reset the sliders + abInsBackfocusSlider->setRange(0, 10); + abInsBackfocusSlider->setValue(0); + abInsTiltLRSlider->setRange(0, 10); + abInsTiltLRSlider->setValue(0); + abInsTiltTBSlider->setRange(0, 10); + abInsTiltTBSlider->setValue(0); + + // Reset the curve fitting object in case Sim mode has caused any problems. This will ensure the graphic + // can always return to its original state after using sim mode. + curveFitting.reset(new CurveFitting()); + } + else + { + // Disconnect slider signals which initialising sliders + disconnect(abInsBackfocusSlider, &QSlider::valueChanged, this, &AberrationInspector::simBackfocusChanged); + disconnect(abInsTiltLRSlider, &QSlider::valueChanged, this, &AberrationInspector::simLRTiltChanged); + disconnect(abInsTiltTBSlider, &QSlider::valueChanged, this, &AberrationInspector::simTBTiltChanged); + + // Setup backfocus slider. + int range = 10; + abInsBackfocusSlider->setRange(-range, range); + int sign = m_backfocus < 0.0 ? -1 : 1; + abInsBackfocusSlider->setValue(sign * 5); + abInsBackfocusSlider->setTickInterval(1); + m_simBackfocus = m_backfocus; + + // Setup Left-to-Right tilt slider. + abInsTiltLRSlider->setRange(-range, range); + sign = m_LRTilt < 0.0 ? -1 : 1; + abInsTiltLRSlider->setValue(sign * 5); + abInsTiltLRSlider->setTickInterval(1); + m_simLRTilt = m_LRTilt; + + // Setup Top-to-Bottom tilt slider + abInsTiltTBSlider->setRange(-range, range); + sign = m_TBTilt < 0.0 ? -1 : 1; + abInsTiltTBSlider->setValue(sign * 5); + abInsTiltTBSlider->setTickInterval(1); + m_simTBTilt = m_TBTilt; + + // Now that the sliders have been initialised, connect up signals + connect(abInsBackfocusSlider, &QSlider::valueChanged, this, &AberrationInspector::simBackfocusChanged); + connect(abInsTiltLRSlider, &QSlider::valueChanged, this, &AberrationInspector::simLRTiltChanged); + connect(abInsTiltTBSlider, &QSlider::valueChanged, this, &AberrationInspector::simTBTiltChanged); + } + updateGraphic(static_cast(abInsTileSelection->currentIndex())); +} + +// Update the 3D graphic based on user selections +void AberrationInspector::updateGraphic(TileSelection tileSelection) +{ + // If we don't have good results then don't display the 3D graphic + bool ok = m_resultsOK; + + if (ok) + // Display thw sensor + ok = processSensor(); + + if (ok) + { + // Add labels to the sensor + processSensorLabels(); + + // Draw the Petzval surface (from the field flattener + ok = processPetzval(tileSelection); + } + + if (ok) + { + // Setup axes + m_graphic->axisX()->setRange(-m_maxX, m_maxX); + m_graphic->axisY()->setRange(-m_maxY, m_maxY); + m_graphic->axisZ()->setRange(m_minZ * 1.1, m_maxZ * 1.1); + + // Display / don't display the sensor + m_graphicSensor ? m_graphic->addSeries(m_sensor) : m_graphic->removeSeries(m_sensor); + + // Display Petzval curve + QSurface3DSeries::DrawFlags petzvalDrawMode { 0 }; + if (m_graphicPetzvalWire) + petzvalDrawMode = petzvalDrawMode | QSurface3DSeries::DrawWireframe; + if (m_graphicPetzvalSurface) + petzvalDrawMode = petzvalDrawMode | QSurface3DSeries::DrawSurface; + + if (petzvalDrawMode) + { + m_petzval->setDrawMode(petzvalDrawMode); + m_graphic->addSeries(m_petzval); + } + else + m_graphic->removeSeries(m_petzval); + } + + // Display / don't display the graphic + ok ? m_graphic->show() : m_graphic->hide(); +} + +// Draw the sensor on the graphic +bool AberrationInspector::processSensor() +{ + // If we are in Sim mode we have previously solved the equation for the plane. All movements in + // Sim mode are rotations. + // If we are not in Sim mode then resolve, e.g. when tile selection changes + if (!m_simMode) + { + // Fit a plane to the datapoints for the selected tiles. Fit is unweighted + CurveFitting::DataPoint3DT plane; + plane.useWeights = false; + for (int tile = 0; tile < NUM_TILES; tile++) + { + if (m_useTile[tile]) + { + QVector3D tileCentre = QVector3D(getXYTileCentre(static_cast(tile)), + getBSDelta(static_cast(tile))); + plane.push_back(tileCentre.x(), tileCentre.y(), tileCentre.z()); + // Update the graph range to accomodate the data + m_maxX = std::max(m_maxX, tileCentre.x()); + m_maxY = std::max(m_maxY, tileCentre.y()); + m_maxZ = std::max(m_maxZ, tileCentre.z()); + m_minZ = std::min(m_minZ, tileCentre.z()); + } + } + curveFitting->fitCurve3D(plane, CurveFitting::FOCUS_PLANE); + double R2 = curveFitting->calculateR2(CurveFitting::FOCUS_PLANE); + // JEE need to think about how to handle failure to solve versus boundary condition of R2=0 + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 sensor plane solved R2=%2").arg(__FUNCTION__).arg(R2); + } + + // We've successfully solved the plane of the sensor so load the sensor vertices in the 3D Surface + // getSensorVertex will perform the necessary rotations + QSurfaceDataArray *data = new QSurfaceDataArray; + QSurfaceDataRow *dataRow1 = new QSurfaceDataRow; + QSurfaceDataRow *dataRow2 = new QSurfaceDataRow; + *dataRow1 << getSensorVertex(TILE_TL) << getSensorVertex(TILE_TR); + *dataRow2 << getSensorVertex(TILE_BL) << getSensorVertex(TILE_BR); + *data << dataRow1 << dataRow2; + m_sensorProxy->resetArray(data); + m_sensor->setDrawMode(QSurface3DSeries::DrawSurface); + return true; +} + +void AberrationInspector::processSensorLabels() +{ + // Now sort out the labels on the sensor + for (int tile = 0; tile < NUM_TILES; tile++) + { + if (m_label[tile] == nullptr) + m_label[tile] = new QCustom3DLabel(); + else + { + m_graphic->removeCustomItem(m_label[tile]); + m_label[tile] = new QCustom3DLabel(); + } + m_label[tile]->setText(TILE_NAME[tile]); + m_label[tile]->setTextColor(TILE_COLOUR[tile]); + QVector3D pos = getLabelCentre(static_cast(tile)); + m_label[tile]->setPosition(pos); + + m_maxX = std::max(m_maxX, pos.x()); + m_maxY = std::max(m_maxY, pos.y()); + m_maxZ = std::max(m_maxZ, pos.z()); + m_minZ = std::min(m_minZ, pos.z()); + + QFont font = m_label[tile]->font(); + font.setPointSize(500); + m_label[tile]->setFont(font); + m_label[tile]->setFacingCamera(true); + } + + for (int tile = 0; tile < NUM_TILES; tile++) + { + if (m_useTile[tile] && m_graphicLabels) + m_graphic->addCustomItem(m_label[tile]); + } +} + +// Draw the Petzval surface on the graphic. Assume a parabolid surface +// z = x^2/a^2 + y^2/b^2. Assume symmetry where a = b +// a^2 = (x^2 + y^2) / z +// +// We know that at the measured datapoints (tile centres) the z value = backfocus +// This is complicated by sensor tilt, but the previously calculated backfocus is an average value +// So we can use this to calculate "a" in the above equation +// Note that there are 2 solutions: one giving positive z, the other negative +bool AberrationInspector::processPetzval(TileSelection tileSelection) +{ + float a = 1.0; + double sum = 0.0; + double backfocus = m_simMode ? m_simBackfocus : m_backfocus; + double sign = (backfocus < 0.0) ? -1.0 : 1.0; + backfocus = std::abs(backfocus); + switch (tileSelection) + { + case TileSelection::TILES_ALL: + // Use all tiles + for (int i = 0; i < NUM_TILES; i++) + { + if (i == TILE_CM) + continue; + sum += getXYTileCentre(static_cast(i)).lengthSquared(); + } + a = sqrt(sum / (8 * backfocus)); + break; + + case TileSelection::TILES_OUTER_CORNERS: + // Use tiles 0, 2, 6, 8 + sum += getXYTileCentre(TILE_TL).lengthSquared() + + getXYTileCentre(TILE_TR).lengthSquared() + + getXYTileCentre(TILE_BL).lengthSquared() + + getXYTileCentre(TILE_BR).lengthSquared(); + a = sqrt(sum / (4 * backfocus)); + break; + + case TileSelection::TILES_INNER_DIAMOND: + // Use tiles 1, 3, 5, 7 + sum += getXYTileCentre(TILE_TM).lengthSquared() + + getXYTileCentre(TILE_CL).lengthSquared() + + getXYTileCentre(TILE_CR).lengthSquared() + + getXYTileCentre(TILE_BM).lengthSquared(); + a = sqrt(sum / (4 * backfocus)); + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile selection %2").arg(__FUNCTION__).arg(tileSelection); + return false; + } + + // Now we have the Petzval equation load a data array of 21 x 21 points + auto *dataArray = new QSurfaceDataArray; + float x_step = m_data.sensorWidth * m_data.pixelSize * 2.0 / 21.0; + float y_step = m_data.sensorHeight * m_data.pixelSize * 2.0 / 21.0; + + m_maxX = std::max(m_maxX, static_cast(m_data.sensorWidth)); + m_maxY = std::max(m_maxY, static_cast(m_data.sensorHeight)); + + // Seems like the x values in the data row need to be increasing / descreasing for the dataProxy to work + for (int j = -10; j < 11; j++) + { + auto *newRow = new QSurfaceDataRow; + float y = y_step * j; + for (int i = -10; i < 11; i++) + { + float x = x_step * i; + float z = sign * (pow(x / a, 2.0) + pow(y / a, 2.0)); + newRow->append(QSurfaceDataItem({x, y, z})); + if (i == 10 && j == 10) + { + m_maxZ = std::max(m_maxZ, z); + m_minZ = std::min(m_minZ, z); + } + } + dataArray->append(newRow); + } + m_petzvalProxy->resetArray(dataArray); + return true; +} + +// Returns the X, Y centre of the tile in microns +QVector2D AberrationInspector::getXYTileCentre(tileID tile) +{ + const double halfSW = m_data.sensorWidth * m_data.pixelSize / 2.0; + const double halfSH = m_data.sensorHeight * m_data.pixelSize / 2.0; + const double halfTS = m_data.tileWidth * m_data.pixelSize / 2.0; + + // Focus calculates the average star position in each tile and passes this to Aberration Inspector as + // an x, y offset from the center of the tile. If stars are homogenously distributed then the offset would + // be 0, 0. If they aren't, then offset represents how much to add to the tile centre. + // A user option (abInsOptCentres) specifies whether to use the offsets. + double xOffset = 0.0; + double yOffset = 0.0; + if (abInsOptCentres->isChecked()) + { + xOffset = m_tileOffsets[tile].x() * m_data.pixelSize; + yOffset = m_tileOffsets[tile].y() * m_data.pixelSize; + } + + switch (tile) + { + case TILE_TL: + return QVector2D(-(halfSW - halfTS) + xOffset, halfSH - halfTS + yOffset); + break; + + case TILE_TM: + return QVector2D(xOffset, halfSH - halfTS + yOffset); + break; + + case TILE_TR: + return QVector2D(halfSW - halfTS + xOffset, halfSH - halfTS + yOffset); + break; + + case TILE_CL: + return QVector2D(-(halfSW - halfTS) + xOffset, yOffset); + break; + + case TILE_CM: + return QVector2D(xOffset, yOffset); + break; + + case TILE_CR: + return QVector2D(halfSW - halfTS + xOffset, yOffset); + break; + + case TILE_BL: + return QVector2D(-(halfSW - halfTS) + xOffset, -(halfSH - halfTS) + yOffset); + break; + + case TILE_BM: + return QVector2D(xOffset, -(halfSH - halfTS) + yOffset); + break; + + case TILE_BR: + return QVector2D(halfSW - halfTS + xOffset, -(halfSH - halfTS) + yOffset); + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile %2").arg(__FUNCTION__).arg(tile); + return QVector2D(0.0, 0.0); + break; + } +} + +// Position the labels just outside the sensor so they are always visible +QVector3D AberrationInspector::getLabelCentre(tileID tile) +{ + const double halfSW = m_data.sensorWidth * m_data.pixelSize / 2.0; + const double halfSH = m_data.sensorHeight * m_data.pixelSize / 2.0; + const double halfTS = m_data.tileWidth * m_data.pixelSize / 2.0; + + QVector3D point; + point.setZ(0.0); + + switch (tile) + { + case TILE_TL: + point.setX(-halfSW - halfTS); + point.setY(halfSH + halfTS); + break; + + case TILE_TM: + point.setX(0.0); + point.setY(halfSH + halfTS); + break; + + case TILE_TR: + point.setX(halfSW + halfTS); + point.setY(halfSH + halfTS); + break; + + case TILE_CL: + point.setX(-halfSW - halfTS); + point.setY(0.0); + break; + + case TILE_CM: + point.setX(0.0); + point.setY(0.0); + break; + + case TILE_CR: + point.setX(halfSW + halfTS); + point.setY(0.0); + break; + + case TILE_BL: + point.setX(-halfSW - halfTS); + point.setY(-halfSH - halfTS); + break; + + case TILE_BM: + point.setX(0.0); + point.setY(-halfSH - halfTS); + break; + + case TILE_BR: + point.setX(halfSW + halfTS); + point.setY(-halfSH - halfTS); + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile %2").arg(__FUNCTION__).arg(tile); + point.setX(0.0); + point.setY(0.0); + break; + } + // We have the coordinates of the point, so now rotate it... + return rotatePoint(point); +} + +// Returns the vertex of the sensor +// x, y are the sensor corner +// z is calculated from the curve fit of the sensor to a plane +QVector3D AberrationInspector::getSensorVertex(tileID tile) +{ + const double halfSW = m_data.sensorWidth * m_data.pixelSize / 2.0; + const double halfSH = m_data.sensorHeight * m_data.pixelSize / 2.0; + + QVector3D point; + point.setZ(0.0); + + switch (tile) + { + case TILE_TL: + point.setX(-halfSW); + point.setY(halfSH); + break; + + case TILE_TR: + point.setX(halfSW); + point.setY(halfSH); + break; + + case TILE_BL: + point.setX(-halfSW); + point.setY(-halfSH); + break; + + case TILE_BR: + point.setX(halfSW); + point.setY(-halfSH); + break; + + default: + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 called with invalid tile %2").arg(__FUNCTION__).arg(tile); + point.setX(0.0); + point.setY(0.0); + break; + } + // We have the coordinates of the point, so now rotate it... + return rotatePoint(point); +} + +// Calculate the backfocus subtracted delta of the passed in tile versus the central tile +// This is really just a translation of the datapoints by the backfocus delta +double AberrationInspector::getBSDelta(tileID tile) +{ + if (tile == TILE_CM) + return 0.0; + else + return m_deltas[tile] - m_backfocus; +} + +// Rotate the passed in 3D point based on: +// Sim mode: use the sim slider values for Left-to-Right and Top-to-Bottom tilt +// !Sim mode: use the Left-to-Right and Top-to-Bottom tilt calculated from the focus position deltas +// +// Qt provides the QQuaternion class, although the documentation is very basic. +// More info: https://en.wikipedia.org/wiki/Quaternion +// The QQuaternion class provides a way to do 3D rotations. This is simpler than doing all the 3D +// multiplication manually, although the results would be the same. +// Be careful that multiplication is NOT commutative! +// +// Left-to-Right tilt is a rotation about the y-axis +// Top-to-bottom tilt is a rotation about the x-axis +// +QVector3D AberrationInspector::rotatePoint(QVector3D point) +{ + float LtoRAngle, TtoBAngle; + + if (m_simMode) + { + LtoRAngle = std::asin(m_simLRTilt / 100.0); + TtoBAngle = std::asin(m_simTBTilt / 100.0); + } + else + { + LtoRAngle = std::asin(m_LRTilt / 100.0); + TtoBAngle = std::asin(m_TBTilt / 100.0); + } + QQuaternion xRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, TtoBAngle * RADIANS2DEGREES); + QQuaternion yRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, LtoRAngle * RADIANS2DEGREES); + QQuaternion totalRotation = yRotation * xRotation; + return totalRotation.rotatedVector(point); +} + +// Backfocus simulation slider has changed +void AberrationInspector::simBackfocusChanged(int value) +{ + m_simBackfocus = abs(m_backfocus) * static_cast(value) / 5.0; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); +} + +// Left-to-Right tilt simulation slider has changed +void AberrationInspector::simLRTiltChanged(int value) +{ + m_simLRTilt = abs(m_LRTilt) * static_cast(value) / 5.0; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); +} + +// Top-to-Bottom tilt simulation slider has changed +void AberrationInspector::simTBTiltChanged(int value) +{ + m_simTBTilt = abs(m_TBTilt) * static_cast(value) / 5.0; + updateGraphic(static_cast(abInsTileSelection->currentIndex())); +} + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,388 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include +#include + +#include "curvefit.h" +#include "ui_aberrationinspector.h" +#include "aberrationinspectorutils.h" + +// The AberrationInspector class manages the Aberration Inspector dialog. +// Settings are managed in a global way, rather than per Optical Train which would be overkill. The approach is the same as Focus +// using loadSettings, connectSettings & syncSettings. +// +// Aberration Inspector uses focus position of different parts of the sensor to examine backfocus and tilt. A single Autofocus run can +// be used as the basis for the analysis. +// +// Note, Aberration Inspector assumes all focus differences between different tiles on the sensor are due to Backfocus and sensor tilt. +// In reality many other aberrations (e.g. collimation, coma, etc.) could contribute to focus differences but are assumed to be negligible. +// If other aberrations are significant then the analysis output of Aberration Inspector is likely to be invalid. +// +// Aberration Inspector can have 2 use cases: +// 1. Analysis mode. Run the inspector and look at the output. +// 2. Use the tool to help with adjustment of Backfocus and / or tilt with a device such as a PhotonCage or Octopi. In this mode, use of the +// tool will be iterative. Run the tool, look at the output, make an adjustment for Backfocus and / or tilt, rerun the tool and compare +// the new output. Make a further adjustment and repeat until happy with the output. For this reason, each time Aberration Inspector is +// run, a new Aberration Inspector Dialog (with incrementing Run number) is launched allowing comparision of results. +// +// To invoke Aberration Inspector: +// 1. Setup focus to give the consistently good focus results. Point to a part of the sky with lots of stars. +// 2. Set the Mosaic Mask on and set it up so that there are sufficient stars in each tile. This is important as each tile +// will be focused solved individually so there needs to be enough stars in each tile. Increase the tile size to get each tile to cover +// more of the sensor and therefore contain more stars; but don't overdo it as the bigger the tile the less accurate the results. +// 3. Run Autofocus manually by pressing the Auto Focus button. Note, Aberration Inspector is not run when Focus is run in a sequence. +// 4. Autofocus will run normally but will collect data for Aberration Inspector for each datapoint. If the Focus run isn't good then +// discard and retry. If basic Autofocus isn't good then Aberration Inspector will not be good. +// 5. When Autofocus completes, the Aberration Inspector dialog is launched. +// 6. To run Aberration Inspector again, simply rerun Autofocus. +// +// The Aberration Inspector dialog has 4 components: +// 1. The v-curves. A curve is drawn for each tile dependent on the user setting of TileSelection. So either 5 or 9 curves are drawn. +// Like Focus, the v-curve shows measure (e.g. HFR) on the y-axis versus focuser position on the x-axis +// 2. A table of results from the v-curves. A row is displayed per tile showing v-curve solution and delta from central tile +// 3. Analysis of results table. Here the deltas between the solve position for the central tile is compared with other tiles and used +// to produce numbers for: +// Backfocus - The idea is that if backfocus is perfect then the average of tile deltas from the centre will be zero. +// Tilt - Differences in tile deltas when backfocus is compensated for, are due to tilt. The analyse works on 2 axes of tilt, +// Left-to-Right and Top-to-Bottom. +// 4. 3D Graphic. This helps to orient the user and explain the results. 2 Surfaces can be displayed: +// Sensor - The sensor is drawn as a 3D plane to scale, with the tilt shown on the z-axis. Top, bottom, left and right are labelled. +// Petzval Surface - This is light surface that comes out of the telescope and hits the sensor. The surface is drawn as a simple, +// circularly symmetrical paraboloid. In reality, the light surface coming out of the field flattener may be much more +// complex. +// With the 3D graphic, it is possible to enter simulation mode, and adjust the Backfocus and tilt and see the effect on the Sensor and +// Petzval surface. +// + +using namespace QtDataVisualization; + +namespace Ekos +{ + +class SensorGraphic; +class AberrationInspectorPlot; + +class AberrationInspector : public QDialog, public Ui::aberrationInspectorDialog +{ + Q_OBJECT + + public: + + typedef enum { TILES_ALL, TILES_OUTER_CORNERS, TILES_INNER_DIAMOND } TileSelection; + typedef struct + { + int run; + CurveFitting::CurveFit curveFit; + bool useWeights; + CurveFitting::OptimisationDirection optDir; + int sensorWidth; + int sensorHeight; + double pixelSize; + int tileWidth; + double focuserStepMicrons; + QString yAxisLabel; + double starUnits; + double cfzSteps; + bool isPositionBased; + } abInsData; + + /** + * @brief create an AberrationInspector with the associated data + * @param data is a structure describing the curve fitting methods + * @param positions datapoints + * @param measures datapoints for each tile + * @param weights datapoints for each tile + */ + AberrationInspector(const abInsData &data, const QVector &positions, const QVector> &measures, + const QVector> &weights, const QVector> &numStars, + const QVector &tileCenterOffset); + ~AberrationInspector(); + + private slots: + /** + * @brief mouse moved into table event. Used to show sensor graphic widget + * @param row + * @param column + */ + void newMousePos(int row, int column); + + /** + * @brief mouse left the table. Used to hide the sensor graphic widget + */ + void leaveTableEvent(); + + /** + * @brief checkbox state changed event + * @param new state + */ + void onStateChanged(int state); + + /** + * @brief table cell changed + * @param new state + */ + void onCellChanged(int row, int column); + + private: + /** + * @brief setup elements of the GUI + */ + void setupGUI(); + + /** + * @brief connect settings in order to persist changes + */ + void connectSettings(); + + /** + * @brief load persisted settings + */ + void loadSettings(); + + /** + * @brief persist settings + */ + void syncSettings(); + + /** + * @brief initialise Aberration Inspector + */ + void initAberrationInspector(); + + /** + * @brief fit v-curves for each tile and update other widgets with results + */ + void fitCurves(); + + /** + * @brief initialise the 3D graphic + */ + void initGraphic(); + + /** + * @brief setTileSelection combobox + * @param tileSelection + */ + void setTileSelection(TileSelection tileSelection); + + /** + * @brief setup an array of tiles to use / don't use + * @param tileSelection + */ + void setupTiles(TileSelection tileSelection); + + /** + * @brief update table widget as per user selection + */ + void updateTable(); + + /** + * @brief analyse and display the results for backfocus and tilt + */ + void analyseResults(); + + /** + * @brief 3D graphic sim mode toggled by user + * @param sim mode on / off + */ + void simModeToggled(bool setting); + + /** + * @brief update 3D graphic based on user selection + * @param tileSelection + */ + void updateGraphic(TileSelection tileSelection); + + /** + * @brief draw Sensor on 3D graphic + * @return success + */ + bool processSensor(); + + /** + * @brief draw Sensor Labels on 3D graphic + */ + void processSensorLabels(); + + /** + * @brief draw Petzval surface (light cone from flattener) on 3D graphic + * @param tileSelection + * @return success + */ + bool processPetzval(TileSelection tileSelection); + + /** + * @brief show / hide v-curve solution labels + * @param show / hide setting + */ + void setShowLabels(bool setting); + + /** + * @brief show / hide CFZ + * @param show / hide setting + */ + void setShowCFZ(bool setting); + + /** + * @brief Optimise tile centres based on weighted star position + * @param setting + */ + void setOptCentres(bool setting); + + /** + * @brief resize table based on contents + */ + void tableResize(); + + /** + * @brief calculate backfocus based on user selection + * @param tileSelection + * @param calculated backfocusDelta + * @return success = true + */ + bool calcBackfocusDelta(TileSelection tileSelection, double &backfocusDelta); + + /** + * @brief calculate tilt based on user selection + * @return success = true + */ + bool calcTilt(); + + /** + * @brief calculates average of 3 tile values + * @param tiles to average + * @param retured tile average + * @return success = true + */ + bool avTiles(int tiles[3], double &average); + + /** + * @brief set exclude tiles vector + * @param row + * @param checked + * @param tile selection + */ + void setExcludeTile(int row, bool checked, TileSelection tileSelection); + + /** + * @brief get tile from table row + * @param tileSelection + * @param row + * @return tile + */ + int getTileFromRow(TileSelection tileSelection, int row); + + /** + * @brief get the X,Y centre of the tile + * @param tile + * @return 2D vector of tile centre + */ + QVector2D getXYTileCentre(tileID tile); + + /** + * @brief get the label position for the passed in tile + * @param tile + * @return 3D vector of label position + */ + QVector3D getLabelCentre(tileID tile); + + /** + * @brief get the sensor vertex nearest the passed in tile + * @param tile + * @return 3D vector of sensor vertex + */ + QVector3D getSensorVertex(tileID tile); + + /** + * @brief get backspace adapted delta the passed in tile + * @param tile + * @return backspace adapted delta + */ + double getBSDelta(tileID tile); + QVector3D rotatePoint(QVector3D point); + + /** + * @brief simulation of backfocus changed + * @param value of slider + */ + void simBackfocusChanged(int value); + + /** + * @brief simulation of L-R tilt changed + * @param value of slider + */ + void simLRTiltChanged(int value); + + /** + * @brief simulation of T-B tilt changed + * @param value of slider + */ + void simTBTiltChanged(int value); + + abInsData m_data; + QVector m_positions; + QVector> m_measures; + QVector> m_weights; + QVector> m_numStars; + QVector m_tileOffsets; + + // Which tiles to use + bool m_useTile[NUM_TILES] = { false, false, false, false, false, false, false, false, false }; + bool m_excludeTile[NUM_TILES] = { false, false, false, false, false, false, false, false, false }; + + // Table + SensorGraphic *sensorGraphic { nullptr }; + int m_HighlightedRow { -1 }; + + // Curve fitting + std::unique_ptr curveFitting; + QVector m_minimum; + QVector m_minMeasure; + QVector m_fit; + QVector m_R2; + + // Analysis - the folowing members are in microns + double m_backfocus = 0.0; + QVector m_deltas; + double m_LRMicrons = 0.0; + double m_TBMicrons = 0.0; + double m_diagonalMicrons = 0.0; + // Tilts are in % slope + double m_LRTilt = 0.0; + double m_TBTilt = 0.0; + double m_diagonalTilt = 0.0; + bool m_resultsOK = false; + + // Graphic simulation variables + bool m_simMode { false }; + double m_simBackfocus { 0 }; + double m_simLRTilt { 0 }; + double m_simTBTilt { 0 }; + float m_maxX { 0.0 }; + float m_maxY { 0.0 }; + float m_minZ { 0.0 }; + float m_maxZ { 0.0 }; + + // Plot widget + AberrationInspectorPlot *m_plot; + + // Graphic + Q3DSurface *m_graphic = nullptr; + QSurface3DSeries *m_sensor = nullptr; + QSurface3DSeries *m_petzval = nullptr; + QSurfaceDataProxy *m_sensorProxy = nullptr; + QSurfaceDataProxy *m_petzvalProxy = nullptr; + QCustom3DLabel *m_label[NUM_TILES] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + bool m_graphicLabels { true }; + bool m_graphicSensor { true }; + bool m_graphicPetzvalWire { true }; + bool m_graphicPetzvalSurface { false }; +}; + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.ui 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspector.ui 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,577 @@ + + + aberrationInspectorDialog + + + Qt::NonModal + + + + 0 + 0 + 897 + 666 + + + + + 0 + 0 + + + + Aberration Inspector + + + true + + + false + + + + + + QLayout::SetDefaultConstraint + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Check to show labels on the graph.</p></body></html> + + + Labels + + + + + + + + 0 + 0 + + + + Tiles: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Select the Mosaic tile combination to use for Analysis:</p><p>- All displays all 9 tiles.</p><p>- Centre and outer corners.</p><p>- Centre and inner diamond.<br/></p></body></html> + + + 1 + + + + All + + + + + Centre and outer corners + + + + + Centre and inner diamond + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Check to show the Critical Focus Zone on the graph.</p></body></html> + + + CFZ + + + false + + + + + + + Optimise Tile Centres + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Close + + + + + + + + + Qt::Vertical + + + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + true + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::SelectedClicked + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + false + + + 5 + + + 6 + + + + + + + + + + + + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + Top-Bottom Tilt: + + + + + + + + 0 + 0 + + + + Total Tilt: + + + + + + + true + + + + + + + <html><head/><body><p>Backfocus delta is the difference in focus position between the sensor centre and the average of the centre corners.</p></body></html> + + + true + + + + + + + + 0 + 0 + + + + Backfocus Δ: + + + + + + + + 0 + 0 + + + + Left-Right Tilt: + + + + + + + true + + + + + + + true + + + + + + + + + + + 0 + 0 + + + + + + + + + Selection: + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Selection mode of the 3D Graphic:</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- None.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Item selects the nearest datapoint.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- Slice produces a 2D slice through the graphic.</p></body></html> + + + None + + + + None + + + + + Item + + + + + Slice + + + + + + + + Theme: + + + + + + + <html><head/><body><p>Select the colour theme of the 3D Graphic.</p></body></html> + + + 1 + + + + Qt + + + + + Primary Colors + + + + + Digia + + + + + Stone Moss + + + + + Army Blue + + + + + Retro + + + + + Ebony + + + + + Isabelle + + + + + + + + <html><head/><body><p>Check to display mosaic tile sensor labels.</p></body></html> + + + Labels + + + true + + + + + + + <html><head/><body><p>Check to display the Sensor.</p></body></html> + + + Sensor + + + true + + + + + + + <html><head/><body><p>Check to display the Petzval surface mesh.</p></body></html> + + + Petzval Wire + + + true + + + + + + + <html><head/><body><p>Check to display the Petzval surface.</p></body></html> + + + Petzval Surface + + + + + + + + + + + + + <html><head/><body><p>Check to set 3D Graphic in Simulation Mode</p></body></html> + + + Sim Mode + + + + + + + false + + + <html><head/><body><p>Backfocus slider</p></body></html> + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 1 + + + + + + + false + + + <html><head/><body><p>Left-to-Right Tilt Slider</p></body></html> + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 1 + + + + + + + false + + + <html><head/><body><p>Top-to-Bottom Tilt Slider</p></body></html> + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 1 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + AbInsTableWidget + QTableWidget +
ekos/focus/abinstablewidget.h
+
+
+ + abInsTileSelection + abInsShowLabels + abInsShowCFZ + totalTilt + tbTilt + backfocus + lrTilt + + + +
diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,334 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "aberrationinspectorplot.h" +#include "curvefit.h" +#include "klocalizedstring.h" + +namespace Ekos +{ + +#define DEFAULT_BASIC_FONT_SIZE 10 + +AberrationInspectorPlot::AberrationInspectorPlot(QWidget *parent) : QCustomPlot (parent) +{ + setBackground(QBrush(Qt::black)); + + xAxis->setBasePen(QPen(Qt::white, 1)); + yAxis->setBasePen(QPen(Qt::white, 1)); + + xAxis->setTickPen(QPen(Qt::white, 1)); + yAxis->setTickPen(QPen(Qt::white, 1)); + + xAxis->setSubTickPen(QPen(Qt::white, 1)); + yAxis->setSubTickPen(QPen(Qt::white, 1)); + + xAxis->setTickLabelColor(Qt::white); + yAxis->setTickLabelColor(Qt::white); + + xAxis->setLabelColor(Qt::white); + yAxis->setLabelColor(Qt::white); + + xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine)); + yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine)); + xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine)); + yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine)); + xAxis->grid()->setZeroLinePen(Qt::NoPen); + yAxis->grid()->setZeroLinePen(Qt::NoPen); + + setInteractions(QCP::iRangeZoom); + setInteraction(QCP::iRangeDrag, true); + + QVector shapes; + shapes << QCPScatterStyle::ssCross; + shapes << QCPScatterStyle::ssPlus; + shapes << QCPScatterStyle::ssCircle; + shapes << QCPScatterStyle::ssSquare; + shapes << QCPScatterStyle::ssDisc; + shapes << QCPScatterStyle::ssDiamond; + shapes << QCPScatterStyle::ssStar; + shapes << QCPScatterStyle::ssTriangle; + shapes << QCPScatterStyle::ssTriangleInverted; + + this->setAutoAddPlottableToLegend(true); + for (int i = 0; i < NUM_TILES; i++) + { + m_graph[i] = addGraph(); + m_graph[i]->setLineStyle(QCPGraph::lsLine); + m_graph[i]->setPen(QPen(QColor(TILE_COLOUR[i]), 2, Qt::SolidLine)); + m_graph[i]->setScatterStyle(shapes[i]); + m_graph[i]->setName(TILE_NAME[i]); + + // Store the auto generated legends array for later manipulation + m_legendItems[i] = this->legend->item(i); + } + + this->setAutoAddPlottableToLegend(false); + for (int i = 0; i < NUM_TILES; i++) + { + // Add focus point graphs + focusPoint[i] = addGraph(); + focusPoint[i]->setLineStyle(QCPGraph::lsImpulse); + focusPoint[i]->setPen(QPen(QColor(TILE_COLOUR[i]), 2, Qt::SolidLine)); + focusPoint[i]->setScatterStyle(QCPScatterStyle(shapes[i], TILE_COLOUR[i], TILE_COLOUR[i], 10)); + } + + // determine font size + if (parent != nullptr) + setBasicFontSize(parent->font().pointSize()); + else + setBasicFontSize(DEFAULT_BASIC_FONT_SIZE); + + connect(this, &QCustomPlot::mouseMove, [this](QMouseEvent * event) + { + double key = xAxis->pixelToCoord(event->localPos().x()); + if (xAxis->range().contains(key)) + { + QCPGraph *graph = qobject_cast(plottableAt(event->pos(), false)); + + if (graph) + { + for (int i = 0; i < NUM_TILES; i++) + { + if (graph == focusPoint[i]) + { + if (focusPoint[i]->visible()) + { + int positionKey = focusPoint[i]->findBegin(key); + double focusPosition = focusPoint[i]->dataMainKey(positionKey); + double focusMeasure = focusPoint[i]->dataMainValue(positionKey); + QToolTip::showText( + event->globalPos(), + i18nc("Graphics tooltip; %2 is tile code; %3 is tile name, %4 is Focus Position; %5 is Focus Measure;", + "" + "" + "" + "" + "" + "
Tile: %2 (%3)
Pos: %4
Val: %5
", + TILE_COLOUR[i], + TILE_NAME[i], TILE_LONGNAME[i], + QString::number(focusPosition, 'f', 0), + QString::number(focusMeasure, 'g', 3))); + } + break; + } + } + } + } + }); +} + +void AberrationInspectorPlot::init(QString yAxisLabel, double starUnits, bool useWeights, bool showLabels, bool showCFZ) +{ + Q_UNUSED(useWeights); + + yAxis->setLabel(yAxisLabel); + m_starUnits = starUnits; + m_showLabels = showLabels; + m_showCFZ = showCFZ; + for (int i = 0; i < NUM_TILES; i++) + { + m_graph[i]->data()->clear(); + focusPoint[i]->data().clear(); + focusPoint[i]->setData(QVector {}, QVector {}); + } + // Displat the legend + this->legend->setVisible(true); +} + +void AberrationInspectorPlot::setAxes(const int tile) +{ + if (tile == -1) + { + // Recalculate axes based on current setting of member variables + const double xborder = (m_maxPosition - m_minPosition) / 10.0; + xAxis->setRange(m_minPosition - xborder, m_maxPosition + xborder); + + const double yborder = (m_maxMeasure - m_minMeasure) / 10.0; + yAxis->setRange(m_minMeasure - yborder, m_maxMeasure + yborder); + return; + } + // x-range - since its the same for each curve only do it once + if (tile == 0) + { + if (m_positions.empty()) + return; + + m_minPosition = *std::min_element(m_positions.constBegin(), m_positions.constEnd()); + m_maxPosition = *std::max_element(m_positions.constBegin(), m_positions.constEnd()); + const double border = (m_maxPosition - m_minPosition) / 10.0; + xAxis->setRange(m_minPosition - border, m_maxPosition + border); + } + + // y range + if (m_measures[tile].empty()) + return; + + if (tile == 0) + { + m_minMeasure = *std::min_element(m_measures[tile].constBegin(), m_measures[tile].constEnd()); + m_maxMeasure = *std::max_element(m_measures[tile].constBegin(), m_measures[tile].constEnd()); + } + else + { + m_minMeasure = std::min(m_minMeasure, *std::min_element(m_measures[tile].constBegin(), m_measures[tile].constEnd())); + m_maxMeasure = std::max(m_maxMeasure, *std::max_element(m_measures[tile].constBegin(), m_measures[tile].constEnd())); + } + const double border = (m_maxMeasure - m_minMeasure) / 10.0; + yAxis->setRange(m_minMeasure - border, m_maxMeasure + border); +} + +void AberrationInspectorPlot::addData(QVector positions, QVector measures, QVector weights, + QVector outliers) +{ + Q_UNUSED(weights); + Q_UNUSED(outliers); + if (m_positions.count() == 0) + m_positions.append(positions); + + // Convert the incoming measures (e.g. pixels) to display measures (e.g. arc-secs) + QVector displayMeasures; + for (int i = 0; i < measures.count(); i++) + displayMeasures.push_back(getDisplayMeasure(measures[i])); + m_measures.append(displayMeasures); + + setAxes(m_measures.count() - 1); +} + +void AberrationInspectorPlot::drawMaxMin(int tile, double solutionPosition, double solutionMeasure) +{ + // Do nothing for invalid positions + if (solutionPosition <= 0) + return; + + double displayMeasure = getDisplayMeasure(solutionMeasure); + m_minMeasure = std::min(m_minMeasure, displayMeasure); + m_maxMeasure = std::max(m_maxMeasure, displayMeasure); + + focusPoint[tile]->addData(solutionPosition, displayMeasure); + m_labelItems[tile] = new QCPItemText(this); + m_labelItems[tile]->setPositionAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + m_labelItems[tile]->setColor(TILE_COLOUR[tile]); + m_labelItems[tile]->setBrush(Qt::white); + m_labelItems[tile]->setPen(Qt::NoPen); + m_labelItems[tile]->setFont(QFont(font().family(), (int) std::round(0.8 * basicFontSize()))); + m_labelItems[tile]->position->setType(QCPItemPosition::ptPlotCoords); + m_labelItems[tile]->setText(QString::number(solutionPosition, 'f', 0)); + m_labelItems[tile]->position->setCoords(solutionPosition, displayMeasure * 0.8); + m_labelItems[tile]->setVisible(m_showLabels); +} + +void AberrationInspectorPlot::drawCFZ(double solutionPosition, double solutionMeasure, int cfzSteps) +{ + // Do nothing for invalid positions + if (solutionPosition <= 0 || solutionMeasure <= 0) + return; + + if (!m_CFZ) + m_CFZ = new QCPItemBracket(this); + + m_CFZ->left->setType(QCPItemPosition::ptPlotCoords); + m_CFZ->right->setType(QCPItemPosition::ptPlotCoords); + + double y = m_minMeasure * 0.95; + + m_CFZ->left->setCoords(solutionPosition + cfzSteps / 2.0, y); + m_CFZ->right->setCoords(solutionPosition - cfzSteps / 2.0, y); + m_CFZ->setLength(15); + m_CFZ->setAntialiased(false); + m_CFZ->setPen(QPen(QColor(Qt::yellow))); + m_CFZ->setVisible(m_showCFZ); +} + +void AberrationInspectorPlot::setShowCFZ(bool setting) +{ + m_showCFZ = setting; + if (m_CFZ) + m_CFZ->setVisible(setting); +} + +void AberrationInspectorPlot::setShowLabels(bool setting) +{ + m_showLabels = setting; + for (int tile = 0; tile < NUM_TILES; tile++) + { + if (m_labelItems[tile]) + m_labelItems[tile]->setVisible(setting); + } +} + +void AberrationInspectorPlot::drawCurve(int tile, Ekos::CurveFitting *curveFit, int maxmin, double measure, bool fit, + double R2) +{ + Q_UNUSED(fit); + Q_UNUSED(R2); + + if (curveFit == nullptr) + return; + + if (!fit) + return; + + // Extend max/mins if appropriate + m_minPosition = std::min(m_minPosition, maxmin); + m_maxPosition = std::max(m_maxPosition, maxmin); + m_minMeasure = std::min(m_minMeasure, measure); + m_maxMeasure = std::max(m_maxMeasure, measure); + setAxes(-1); + + if (m_graph[tile] != nullptr) + { + m_graph[tile]->data()->clear(); + QCPRange range = xAxis->range(); + double interval = range.size() / 40.0; + + for(double x = range.lower; x < range.upper; x += interval) + { + double y = getDisplayMeasure(curveFit->f(x)); + m_graph[tile]->addData(x, y); + } + } +} + +// Show only the graph elements relevant to the passed in useTile array +void AberrationInspectorPlot::redrawCurve(bool useTile[NUM_TILES]) +{ + for (int i = 0; i < NUM_TILES; i++) + { + // Show / hide the appropriate curves + if (m_graph[i]) + m_graph[i]->setVisible(useTile[i]); + + // Only display legend entries for displayed graphs + this->legend->item(i)->setVisible(useTile[i]); + + // Show / hide the focus point and text labels appopriate to the selected curves + if (focusPoint[i]) + focusPoint[i]->setVisible(useTile[i]); + if (m_labelItems[i]) + m_labelItems[i]->setVisible(useTile[i] && m_showLabels); + } +} + +void AberrationInspectorPlot::setBasicFontSize(int basicFontSize) +{ + m_basicFontSize = basicFontSize; + + // Axis Labels Settings + yAxis->setLabelFont(QFont(font().family(), basicFontSize)); + xAxis->setTickLabelFont(QFont(font().family(), (int) std::round(0.9 * basicFontSize))); + yAxis->setTickLabelFont(QFont(font().family(), (int) std::round(0.9 * basicFontSize))); +} + +// Internally calculations are done in units of pixels for HFR and FWHM +// If user preference is arcsecs then convert measures for display purposes. +double AberrationInspectorPlot::getDisplayMeasure(const double measure) +{ + return measure * m_starUnits; +} + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorplot.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,155 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "aberrationinspectorutils.h" +#include "qcustomplot.h" + +// AberrationInspectorPlot manages the QCustomPlot graph of focus position vs measure for the 9 mosaic tiles +// Each tile has its own curve. The legend shows which curve refers to which tile. The maximum or minimum of each +// curve is also displayed. The tooltip of each max / min gives more info. Optionally, a label describing the max / min +// can be displayed; and the CFZ can be displayed around the centre tile max / min. +// +namespace Ekos +{ + +class CurveFitting; + +class AberrationInspectorPlot : public QCustomPlot +{ + public: + /** + * @brief create an AberrationInspectorPlot graph + * @param parent widget + */ + AberrationInspectorPlot(QWidget *parent = nullptr); + + /** + * @brief add all data for all datapoints for all curves + * @param position focuser position + * @param measure for the associated position + * @param weight for the associated measure + * @param outlier or not + */ + void addData(QVector position, QVector measure, QVector weight, QVector outlier); + + /** + * @brief Add the max / min solution to the plot + * @param tile number + * @param solution position + * @param solution value + */ + void drawMaxMin(int tile, double solutionPosition, double solutionValue); + + /** + * @brief Draw the Critical Focus Zone centred on solution + * @param solution position + * @param solution measure + * @param CFZ size in steps + */ + void drawCFZ(double solutionPosition, double solutionMeasure, int cfzSteps); + + /** + * @brief Draw the curve + * @param tile + * @param curveFit pointer to generate data points + * @param maxmin is the curve max or min + * @param measure of the curve, e.g. HFR + * @param fit is whether a curve fit was achieved + * @param R2 of the curve fit + */ + void drawCurve(int tile, Ekos::CurveFitting *curveFit, int maxmin, double measure, bool fit, double R2); + + /** + * @brief Refresh the entire graph + * @param useTile array indicating which tiles to show/hide + */ + void redrawCurve(bool useTile[NUM_TILES]); + + /** + * @brief Initialize the plot + * @param yAxisLabel is the label to display + * @param starUnits the units multiplier to display the pixel data + * @param useWeights whether or not weights have been used + * @param show labels on the plot + * @param show CFZ on the plot + */ + void init(QString yAxisLabel, double starUnits, bool useWeights, bool showLabels, bool showCFZ); + + /** + * @brief show / hide labels on plot + * @return setting + */ + void setShowLabels(bool setting); + + /** + * @brief show / hide CFZ on plot + * @return setting + */ + void setShowCFZ(bool setting); + + private: + /** + * @brief return font size + * @return font size + */ + int basicFontSize() const + { + return m_basicFontSize; + } + + /** + * @brief set font size + * @param font size + */ + void setBasicFontSize(int fontSize); + + /** + * @brief Setup the axes based on the data + * @param tile to process + */ + void setAxes(const int tile); + + /** + * @brief Convert input measure to output display measure + * @param measure to convert + * @return converted measure + */ + double getDisplayMeasure(const double measure); + + QVector m_positions; + QVector> m_measures; + + // Legend items for the plot + QCPAbstractLegendItem *m_legendItems[NUM_TILES] { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + + // Text items highlighting the max / min of each curve + bool m_showLabels = false; + QCPItemText *m_labelItems[NUM_TILES] { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + + // CFZ + bool m_showCFZ = false; + QCPItemBracket *m_CFZ = nullptr; + + // V curves + QCPGraph *m_graph[NUM_TILES] { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + // Focus points plotted as graphs + QCPGraph *focusPoint[NUM_TILES] { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + + // basic font size from which all others are derived + int m_basicFontSize = 10; + // Units multiplier for star measure value + double m_starUnits = 1.0; + + // Max / Mins used to set the graph axes + int m_minPosition = -1; + int m_maxPosition = -1; + double m_minMeasure = -1.0; + double m_maxMeasure = -1.0; +}; + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorutils.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorutils.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorutils.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/aberrationinspectorutils.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,41 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +// This header file includes constants used by several Aberration Inspector classes + +namespace Ekos +{ + +// tileID defines the 9 tiles in the mosaic +typedef enum +{ + TILE_TL = 0, + TILE_TM, + TILE_TR, + TILE_CL, + TILE_CM, + TILE_CR, + TILE_BL, + TILE_BM, + TILE_BR, + // Add a max for array indexing + NUM_TILES +} tileID; + +// Tile names and colours +static const QString TILE_NAME[NUM_TILES] = {"TL", "T", "TR", "L", "C", "R", "BL", "B", "BR"}; +static const QString TILE_LONGNAME[NUM_TILES] = {"Top Left", "Top", "Top Right", "Left", "Centre", "Right", "Bottom Left", "Bottom", "Bottom Right"}; +static const QString TILE_COLOUR[NUM_TILES] = {"red", "cyan", "green", "magenta", "blue", "grey", "darkGreen", "darkCyan", "darkRed"}; + +// Debug flag +// false - production mode +// true - used for production support to enable table widget to be editable to simulate other user's data +constexpr bool ABINS_DEBUG { false }; +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,23 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "abinstablewidget.h" + +AbInsTableWidget::AbInsTableWidget(QWidget *parent) : QTableWidget(parent) +{ + this->setMouseTracking(true); +} + +AbInsTableWidget::~AbInsTableWidget() +{ +} + +void AbInsTableWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event); + // signal when the mouse cursor leaves the custom table widget + emit leaveTableEvent(); +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/abinstablewidget.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,42 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +// AbInsTableWidget is a subclass of table widget. +// It has been created for use in AberrationInspector in order to be able to access leaveEvent which is not +// possible in the QTableWidget implementation. +// +// This header file is linked into QT Designer using the Promote widget approach so that AbInsTableWidget rather than +// QTableWidget is used. +// +class AbInsTableWidget : public QTableWidget +{ + Q_OBJECT + + public: + + /** + * @brief Create an AbInsTableWidget + * @param parent widget + */ + AbInsTableWidget(QWidget *parent = 0); + ~AbInsTableWidget(); + + /** + * @brief event when mouse leaves the boundary of the widget + * @param event + */ + void leaveEvent(QEvent * event) override; + + signals: + /** + * @brief signal mouse left the widget boundary + */ + void leaveTableEvent(); +}; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/curvefit.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/curvefit.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/curvefit.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/curvefit.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -5,14 +5,15 @@ // Constants used to identify the number of parameters used for different curve types constexpr int NUM_HYPERBOLA_PARAMS = 4; constexpr int NUM_PARABOLA_PARAMS = 3; -//constexpr int NUM_GAUSSIAN_PARAMS = 7; constexpr int NUM_GAUSSIAN_PARAMS = 7; +constexpr int NUM_PLANE_PARAMS = 3; // Parameters for the solver // MAX_ITERATIONS is used to limit the number of iterations for the solver. // A value needs to be entered that allows a solution to be found without iterating unnecessarily // There is a relationship with the tolerance parameters that follow. constexpr int MAX_ITERATIONS_CURVE = 5000; constexpr int MAX_ITERATIONS_STARS = 1000; +constexpr int MAX_ITERATIONS_PLANE = 5000; // The next 3 parameters are used as tolerance for convergence // convergence is achieved if for each datapoint i // dx_i < INEPSABS + (INEPSREL * x_i) @@ -69,7 +70,9 @@ // not to disturb historic code the original solution will be called Quadratic. It uses a linear least-squares // model, not LM. The LM solver has been applied to a hyperbolic and a parabolic curve. // -// In addition, the solver has been applied to a 3D Gaussian in order to fit star profiles and calculate FWHM +// In addition, the solver has been applied to: +// 1. 3D Gaussian in order to fit star profiles and calculate FWHM. +// 2. 3D Plane surface used by Aberration Inspector. // // Hyperbola // --------- @@ -129,7 +132,7 @@ // -------- // Generalised equation for a 2D gaussian. // Equation z = f(x,y) = b + a.exp-(A((x-x0)^2) + 2B(x-x0)(y-y0) + 2C((y-y0)^2)) - +// // with parameters // b = background // a = Peak Intensity @@ -195,6 +198,32 @@ // // ddf/dCdC = (y-y0)^4.a.phi // +// 3D Plane +// Generalised equation for a 3D plane going through the origin. +// Equation z = f(x,y) = -(A.x + B.y) / C +// Jacobian J = {df/dA, df/dB, df/dC} +// df/dA = -x / C +// df/dB = -y / C +// df/dC = (A.x + B.y) / C^2 +// +// 2nd derivatives +// {ddf/dAdA,ddf/dAdB,ddf/dAdC} +// {ddf/dBdA,ddf/dBdB,ddf/dBdC} +// {ddf/dCdA,ddf/dCdB,ddf/dCdC} +// +// The matrix is symmetric, as ddf/dParm1dParm2 = ddf/dParm2dParm1 so we only need to differentiate +// one half (above or below the diagonal) of the matrix elements. +// +// ddf/dAdA = 0 +// ddf/dAdB = 0 +// ddf/dAdC = x / C^2 +// +// ddf/dBdB = 0 +// ddf/dBdC = y / C^2 +// +// ddf/dCdC = -2.(A.x + B.y) / C^3 +// +// // Convergence // ----------- // There following are key parameters that drive the LM solver. Currently these settings are coded into @@ -267,7 +296,6 @@ // Hyperbola equation double yi = hypfx(DataPoints->dps[i].x, a, b, c, d); - // TODO: Need to understand this a bit more gsl_vector_set(outResultVec, i, (yi - DataPoints->dps[i].y)); } @@ -385,7 +413,6 @@ // Parabola equation double yi = parfx(DataPoint->dps[i].x, a, b, c); - // TODO: Need to understand this a bit more gsl_vector_set(outResultVec, i, (yi - DataPoint->dps[i].y)); } @@ -483,7 +510,7 @@ // df/dC = -(y-y0)^2.a.phi int gauJxy(const gsl_vector * X, void * inParams, gsl_matrix * J) { - CurveFitting::DataPointT * DataPoint = ((struct CurveFitting::DataPointT *)inParams); + CurveFitting::DataPoint3DT * DataPoint = ((struct CurveFitting::DataPoint3DT *)inParams); // Get current coefficients const double a = gsl_vector_get (X, A_IDX); @@ -558,7 +585,7 @@ // int gauFxyxy(const gsl_vector* X, const gsl_vector* v, void* inParams, gsl_vector* fvv) { - CurveFitting::DataPointT * DataPoint = ((struct CurveFitting::DataPointT *)inParams); + CurveFitting::DataPoint3DT * DataPoint = ((struct CurveFitting::DataPoint3DT *)inParams); // Get current coefficients const double a = gsl_vector_get (X, A_IDX); @@ -628,6 +655,104 @@ return GSL_SUCCESS; } + +// Function to calculate f(x,y) for a 2-D plane. +// f(x,y) = (A.x + B.y) / -C +double plafxy(double x, double y, double A, double B, double C) +{ + return -(A * x + B * y) / C; +} + +// Calculates f(x,y) for each data point in the gaussian. +int plaFxy(const gsl_vector * X, void * inParams, gsl_vector * outResultVec) +{ + CurveFitting::DataPoint3DT * DataPoint = ((struct CurveFitting::DataPoint3DT *)inParams); + + double A = gsl_vector_get (X, A_IDX); + double B = gsl_vector_get (X, B_IDX); + double C = gsl_vector_get (X, C_IDX); + + for(int i = 0; i < DataPoint->dps.size(); ++i) + { + // Plane equation + double zi = plafxy(DataPoint->dps[i].x, DataPoint->dps[i].y, A, B, C); + gsl_vector_set(outResultVec, i, (zi - DataPoint->dps[i].z)); + } + + return GSL_SUCCESS; +} + +// Calculates the Jacobian (derivative) matrix for the plane +// Jacobian J = {df/dA, df/dB, df/dC} +// df/dA = -x / C +// df/dB = -y / C +// df/dC = (A.x + B.y) / C^2 +int plaJxy(const gsl_vector * X, void * inParams, gsl_matrix * J) +{ + CurveFitting::DataPoint3DT * DataPoint = ((struct CurveFitting::DataPoint3DT *)inParams); + + // Get current coefficients + const double A = gsl_vector_get (X, A_IDX); + const double B = gsl_vector_get (X, B_IDX); + const double C = gsl_vector_get (X, C_IDX); + + for(int i = 0; i < DataPoint->dps.size(); ++i) + { + // Calculate the Jacobian Matrix + const double x = DataPoint->dps[i].x; + const double y = DataPoint->dps[i].y; + + gsl_matrix_set(J, i, A_IDX, -x / C); + gsl_matrix_set(J, i, B_IDX, -y / C); + gsl_matrix_set(J, i, C_IDX, (A * x + B * y) / (C * C)); + } + + return GSL_SUCCESS; +} + +// Calculates the second directional derivative vector for the plane equation +// The matrix is symmetric, as ddf/dParm1dParm2 = ddf/dParm2dParm1 so we only need to differentiate +// one half (above or below the diagonal) of the matrix elements. +// +// ddf/dAdA = 0 +// ddf/dAdB = 0 +// ddf/dAdC = x / C^2 + +// ddf/dBdB = 0 +// ddf/dBdC = y / C^2 +// +// ddf/dCdC = -2.(A.x + B.y) / C^3 +// +int plaFxyxy(const gsl_vector* X, const gsl_vector* v, void* inParams, gsl_vector* fvv) +{ + CurveFitting::DataPoint3DT * DataPoint = ((struct CurveFitting::DataPoint3DT *)inParams); + + // Get current coefficients + const double A = gsl_vector_get (X, A_IDX); + const double B = gsl_vector_get (X, B_IDX); + const double C = gsl_vector_get (X, C_IDX); + + const double vA = gsl_vector_get(v, A_IDX); + const double vB = gsl_vector_get(v, B_IDX); + const double vC = gsl_vector_get(v, C_IDX); + + for(int i = 0; i < DataPoint->dps.size(); ++i) + { + double x = DataPoint->dps[i].x; + double y = DataPoint->dps[i].y; + double C2 = C * C; + double C3 = C * C2; + double dAdC = x / C2; + double dBdC = y / C2; + double dCdC = -2 * (A * x + B * y) / C3; + + double sum = 2 * (vA * vC * dAdC) + 2 * (vB * vC * dBdC) + vC * vC * dCdC; + + gsl_vector_set(fvv, i, sum); + } + + return GSL_SUCCESS; +} } // namespace CurveFitting::CurveFitting() @@ -687,6 +812,35 @@ m_FirstSolverRun = false; } +void CurveFitting::fitCurve3D(const DataPoint3DT data, const CurveFit curveFit) +{ + if (data.useWeights) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("CurveFitting::fitCurve3D called with useWeights = true. Not currently supported"); + m_FirstSolverRun = true; + return; + } + + m_useWeights = data.useWeights; + m_CurveType = curveFit; + m_dataPoints = data; + + switch (m_CurveType) + { + case FOCUS_PLANE : + m_coefficients = plane_fit(data); + break; + default : + // Something went wrong, log an error and reset state so solver starts from scratch if called again + qCDebug(KSTARS_EKOS_FOCUS) << QString("CurveFitting::fitCurve3D called with curveFit=%1").arg(curveFit); + m_FirstSolverRun = true; + return; + } + m_LastCoefficients = m_coefficients; + m_LastCurveType = m_CurveType; + m_FirstSolverRun = false; +} + double CurveFitting::curveFunction(double x, void *params) { CurveFitting *instance = static_cast(params); @@ -723,6 +877,8 @@ if (m_CurveType == FOCUS_GAUSSIAN && m_coefficients.size() == NUM_GAUSSIAN_PARAMS) z = gaufxy(x, y, m_coefficients[A_IDX], m_coefficients[B_IDX], m_coefficients[C_IDX], m_coefficients[D_IDX], m_coefficients[E_IDX], m_coefficients[F_IDX], m_coefficients[G_IDX]); + else if (m_CurveType == FOCUS_PLANE && m_coefficients.size() == NUM_PLANE_PARAMS) + z = plafxy(x, y, m_coefficients[A_IDX], m_coefficients[B_IDX], m_coefficients[C_IDX]); else qCDebug(KSTARS_EKOS_FOCUS) << QString("Error: CurveFitting::f3D called with m_CurveType = %1 m_coefficients.size = %2") .arg(m_CurveType).arg(m_coefficients.size()); @@ -1574,6 +1730,194 @@ *ftol = 1e-5; } +// Curve fit a 3D plane +QVector CurveFitting::plane_fit(const DataPoint3DT data) +{ + QVector vc; + + // Set the gsl error handler off as it aborts the program on error. + auto const oldErrorHandler = gsl_set_error_handler_off(); + + // Setup variables to be used by the solver + gsl_multifit_nlinear_parameters params = gsl_multifit_nlinear_default_parameters(); + gsl_multifit_nlinear_workspace* w = gsl_multifit_nlinear_alloc (gsl_multifit_nlinear_trust, ¶ms, data.dps.size(), + NUM_PLANE_PARAMS); + gsl_multifit_nlinear_fdf fdf; + int numIters; + double xtol, gtol, ftol; + + // Fill in function info + fdf.f = plaFxy; + fdf.df = plaJxy; + fdf.fvv = plaFxyxy; + fdf.n = data.dps.size(); + fdf.p = NUM_PLANE_PARAMS; + fdf.params = (void *) &data; + + // Allocate the guess vector + gsl_vector * guess = gsl_vector_alloc(NUM_PLANE_PARAMS); + // Allocate weights vector + auto weights = gsl_vector_alloc(data.dps.size()); + + // Setup a timer to see how long the solve takes + QElapsedTimer timer; + timer.start(); + + // Setup for multiple solve attempts. + for (int attempt = 0; attempt < 5; attempt++) + { + // Make initial guesses + plaMakeGuess(attempt, guess); + + // If using weights load up the GSL vector + if (data.useWeights) + { + QVectorIterator dp(data.dps); + int i = 0; + while (dp.hasNext()) + gsl_vector_set(weights, i++, dp.next().weight); + + gsl_multifit_nlinear_winit(guess, weights, &fdf, w); + } + else + gsl_multifit_nlinear_init(guess, &fdf, w); + + // This is the callback used by the LM solver to allow some introspection of each iteration + // Useful for debugging but clogs up the log + // To activate, uncomment the callback lambda and change the call to gsl_multifit_nlinear_driver + /*auto callback = [](const size_t iter, void* _params, const gsl_multifit_nlinear_workspace * w) + { + gsl_vector *f = gsl_multifit_nlinear_residual(w); + gsl_vector *x = gsl_multifit_nlinear_position(w); + double rcond; + + // compute reciprocal condition number of J(x) + gsl_multifit_nlinear_rcond(&rcond, w); + + // ratio of accel component to velocity component + double avratio = gsl_multifit_nlinear_avratio(w); + + qCDebug(KSTARS_EKOS_FOCUS) << + QString("iter %1: A = %2, B = %3, C = %4" + "rcond(J) = %5, avratio = %6, |f(x)| = %7") + .arg(iter) + .arg(gsl_vector_get(x, A_IDX)) + .arg(gsl_vector_get(x, B_IDX)) + .arg(gsl_vector_get(x, C_IDX)) + //.arg(1.0 / rcond) + .arg(rcond) + .arg(avratio) + .arg(gsl_blas_dnrm2(f)); + };*/ + + plaSetupParams(¶ms, &numIters, &xtol, >ol, &ftol); + + qCDebug(KSTARS_EKOS_FOCUS) << QString("Starting LM solver, fit=plane, solver=%1, scale=%2, trs=%3, iters=%4, xtol=%5," + "gtol=%6, ftol=%7") + .arg(params.solver->name).arg(params.scale->name).arg(params.trs->name).arg(numIters) + .arg(xtol).arg(gtol).arg(ftol); + + int info = 0; + int status = gsl_multifit_nlinear_driver(numIters, xtol, gtol, ftol, NULL, NULL, &info, w); + + if (status != 0) + { + qCDebug(KSTARS_EKOS_FOCUS) << + QString("LM solver (Plane): Failed after %1ms iters=%2 [attempt=%3] with status=%4 [%5] and info=%6 [%7]") + .arg(timer.elapsed()).arg(gsl_multifit_nlinear_niter(w)).arg(attempt + 1).arg(status).arg(gsl_strerror(status)) + .arg(info).arg(gsl_strerror(info)); + if (status != GSL_EMAXITER || info != GSL_ENOPROG || gsl_multifit_nlinear_niter(w) > 1) + break; + } + else + { + // All good so store the results - parameters A, B, C + auto solution = gsl_multifit_nlinear_position(w); + for (int j = 0; j < NUM_PLANE_PARAMS; j++) + vc.push_back(gsl_vector_get(solution, j)); + + qCDebug(KSTARS_EKOS_FOCUS) << QString("LM Solver (Plane): Solution found after %1ms %2 iters (%3). A=%4, B=%5, C=%6") + .arg(timer.elapsed()).arg(gsl_multifit_nlinear_niter(w)).arg(getLMReasonCode(info)) + .arg(vc[A_IDX]).arg(vc[B_IDX]).arg(vc[C_IDX]); + break; + } + } + + // Free GSL memory + gsl_multifit_nlinear_free(w); + gsl_vector_free(guess); + gsl_vector_free(weights); + + // Restore old GSL error handler + gsl_set_error_handler(oldErrorHandler); + + return vc; +} + +// Initialise parameters before starting the solver. Its important to start with a guess as near to the solution as possible +void CurveFitting::plaMakeGuess(const int attempt, gsl_vector * guess) +{ + double A, B, C; + // If we are retrying then perturb the initial conditions. The hope is that by doing this the solver + // will be nudged to find a solution this time + const double perturbation = 1.0 + pow(-1, attempt) * (attempt * 0.1); + + if (!m_FirstSolverRun && (m_LastCurveType == FOCUS_PLANE) && (m_LastCoefficients.size() == NUM_PLANE_PARAMS) && attempt < 3) + { + // Last run of the solver was a Plane and that solution was good, so use that solution + A = m_LastCoefficients[A_IDX] * perturbation; + B = m_LastCoefficients[B_IDX] * perturbation; + C = m_LastCoefficients[C_IDX] * perturbation; + } + else + { + A = perturbation; + B = perturbation; + C = perturbation; + } + + qCDebug(KSTARS_EKOS_FOCUS) << QString("LM Solver (Plane): Guess perturbation=%1, A=%2, B=%3, C=%4") + .arg(perturbation).arg(A).arg(B).arg(C); + + gsl_vector_set(guess, A_IDX, A); + gsl_vector_set(guess, B_IDX, B); + gsl_vector_set(guess, C_IDX, C); +} + +// Setup the parameters for plane curve fitting +void CurveFitting::plaSetupParams(gsl_multifit_nlinear_parameters *params, int *numIters, double *xtol, double *gtol, + double *ftol) +{ + // Trust region subproblem + // - gsl_multifit_nlinear_trs_lm is the Levenberg-Marquardt algorithm without acceleration + // - gsl_multifit_nlinear_trs_lmaccel is the Levenberg-Marquardt algorithm with acceleration + // - gsl_multilarge_nlinear_trs_dogleg is the dogleg algorithm + // - gsl_multifit_nlinear_trs_ddogleg is the double dogleg algorithm + // - gsl_multifit_nlinear_trs_subspace2D is the 2D subspace algorithm + params->trs = gsl_multifit_nlinear_trs_lm; + + // avmax is the max allowed ratio of 2nd order term (acceleration, a) to the 1st order term (velocity, v) + // GSL defaults to 0.75 + // params->avmax = 0.75; + + // Scale + // - gsl_multifit_nlinear_scale_more uses. More strategy. Good for problems with parameters with widely different scales + // - gsl_multifit_nlinear_scale_levenberg. Levensberg strategy. Can be good but not scale invariant. + // - gsl_multifit_nlinear_scale_marquardt. Marquardt strategy. Considered inferior to More and Levensberg + params->scale = gsl_multifit_nlinear_scale_more; + + // Solver + // - gsl_multifit_nlinear_solver_qr produces reliable results but needs more iterations than Cholesky + // - gsl_multifit_nlinear_solver_cholesky fast but not as stable as QR + // - gsl_multifit_nlinear_solver_mcholesky modified Cholesky more stable than Cholesky + params->solver = gsl_multifit_nlinear_solver_qr; + + *numIters = MAX_ITERATIONS_PLANE; + *xtol = 1e-5; + *gtol = INEPSGTOL; + *ftol = 1e-5; +} + bool CurveFitting::findMinMax(double expected, double minPosition, double maxPosition, double *position, double *value, CurveFit curveFit, const OptimisationDirection optDir) { @@ -1772,7 +2116,7 @@ double FWHMy = 2 * pow(2 * log(2) * sigmay2, 0.5); double FWHM = (FWHMx + FWHMy) / 2.0; - if (FWHM < 0.0) + if (isnan(FWHM) || FWHM < 0.0) { qCDebug(KSTARS_EKOS_FOCUS) << QString("Error in CurveFitting::getGaussianParams FWHM=%1").arg(FWHM); return false; @@ -1859,6 +2203,27 @@ dataPoints.push_back(static_cast (m_dataPoints.dps[i].z)); } + // Do the actual R2 calculation + R2 = calcR2(dataPoints, curvePoints, m_scale, m_dataPoints.useWeights); + break; + + case FOCUS_PLANE : + // Calculate R2 for the plane + if (m_coefficients.size() != NUM_PLANE_PARAMS) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("Error in CurveFitting::calculateR2 plane coefficients.size()=").arg( + m_coefficients.size()); + break; + } + + for (i = 0; i < m_dataPoints.dps.size(); i++) + { + // Load up the curvePoints vector + curvePoints.push_back(plafxy(m_dataPoints.dps[i].x, m_dataPoints.dps[i].y, m_coefficients[A_IDX], + m_coefficients[B_IDX], m_coefficients[C_IDX])); + dataPoints.push_back(static_cast (m_dataPoints.dps[i].z)); + } + // Do the actual R2 calculation R2 = calcR2(dataPoints, curvePoints, m_scale, m_dataPoints.useWeights); break; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/curvefit.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/curvefit.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/curvefit.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/curvefit.h 2023-12-03 05:23:17.000000000 +0000 @@ -18,7 +18,9 @@ // solver as provided the Gnu Science Library (GSL). See the comments at the start of curvefit.cpp // for more details. // -// 2 curves, hyperbola and parabola are provided. +// Several curves are provided: +// For lines: hyperbola, parabola +// For surfaces: gaussian, plane // For compatibility with existing Ekos functionality a Quadratic option using the exising Ekos linear // least squares solver (again provided by GSL) is supported. The Quadratic and Parabola curves are // the same thing mathematically but Parabola uses the non-linear least squares LM solver whilst Quadratic @@ -31,7 +33,7 @@ class CurveFitting { public: - typedef enum { FOCUS_QUADRATIC, FOCUS_HYPERBOLA, FOCUS_PARABOLA, FOCUS_GAUSSIAN } CurveFit; + typedef enum { FOCUS_QUADRATIC, FOCUS_HYPERBOLA, FOCUS_PARABOLA, FOCUS_GAUSSIAN, FOCUS_PLANE } CurveFit; typedef enum { OPTIMISATION_MINIMISE, OPTIMISATION_MAXIMISE } OptimisationDirection; typedef enum { STANDARD, BEST, BEST_RETRY } FittingGoal; @@ -62,7 +64,7 @@ { double x; // x position double y; // y position - int z; // value + double z; // value double weight; // the measurement weight, e.g. inverse variance }; @@ -75,7 +77,7 @@ Mathematics::RobustStatistics::SCALE_VARIANCE; // How to compute weights // Helper function to operate on the data structure - void push_back(double x, double y, int z, double weight = 1) + void push_back(double x, double y, double z, double weight = 1) { dps.push_back({x, y, z, weight}); } @@ -109,10 +111,10 @@ const QVector &weights, const QVector &outliers, const CurveFit curveFit, const bool useWeights, const OptimisationDirection optDir); - // fitCurve3D 3-Dimensional version of fitCurve. + // fitCurve3D 3-Dimensional version of fitCurve // Data is passed in in imageBuffer - a 2D array of width x height // Approx star information is passed in to seed the LM solver initial parameters. - // Start and end define the x,y coordinates of a box around the star start is top left corner, end is bottom right + // Start and end define the x,y coordinates of a box around the star, start is top left corner, end is bottom right template void fitCurve3D(const T *imageBuffer, const int imageWidth, const QPair start, const QPair end, const StarParams &starParams, const CurveFit curveFit, const bool useWeights) @@ -168,6 +170,9 @@ m_FirstSolverRun = false; } + // Alternative form of fitCurve3D used on non-image data + void fitCurve3D(const DataPoint3DT data, const CurveFit curveFit); + // Returns the minimum position and value in the pointers for the solved curve. // Returns false if the curve couldn't be solved bool findMinMax(double expected, double minPosition, double maxPosition, double *position, double *value, CurveFit curveFit, @@ -223,6 +228,7 @@ const QVector data_weights, bool useWeights, const OptimisationDirection optDir); QVector gaussian_fit(DataPoint3DT data, const StarParams &starParams); + QVector plane_fit(const DataPoint3DT data); bool minimumQuadratic(double expected, double minPosition, double maxPosition, double *position, double *value); bool minMaxHyperbola(double expected, double minPosition, double maxPosition, double *position, double *value, @@ -243,6 +249,8 @@ double *ftol); void gauMakeGuess(const int attempt, const StarParams &starParams, gsl_vector * guess); void gauSetupParams(gsl_multifit_nlinear_parameters *params, int *numIters, double *xtol, double *gtol, double *ftol); + void plaMakeGuess(const int attempt, gsl_vector * guess); + void plaSetupParams(gsl_multifit_nlinear_parameters *params, int *numIters, double *xtol, double *gtol, double *ftol); // Get the reason code from the passed in info QString getLMReasonCode(int info); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -9,10 +9,12 @@ #include "focusadaptor.h" #include "focusalgorithms.h" #include "focusfwhm.h" -#include "polynomialfit.h" +#include "aberrationinspector.h" +#include "aberrationinspectorutils.h" #include "kstars.h" #include "kstarsdata.h" #include "Options.h" +#include "stellarsolver.h" // Modules #include "ekos/guide/guide.h" @@ -24,14 +26,17 @@ // Ekos Auxiliary #include "ekos/auxiliary/darklibrary.h" +#include "ekos/auxiliary/darkprocessor.h" #include "ekos/auxiliary/profilesettings.h" #include "ekos/auxiliary/opticaltrainmanager.h" #include "ekos/auxiliary/opticaltrainsettings.h" #include "ekos/auxiliary/filtermanager.h" +#include "ekos/auxiliary/stellarsolverprofileeditor.h" // FITS #include "fitsviewer/fitsdata.h" #include "fitsviewer/fitsview.h" +#include "fitsviewer/fitsviewer.h" // Devices #include "indi/indifilterwheel.h" @@ -528,6 +533,10 @@ bool Focus::findTemperatureElement(const QSharedPointer &device) { + // protect for nullptr + if (device.isNull()) + return false; + auto temperatureProperty = device->getProperty("FOCUS_TEMPERATURE"); if (!temperatureProperty) temperatureProperty = device->getProperty("CCD_TEMPERATURE"); @@ -713,6 +722,11 @@ absMotionMin = 0; } + qCDebug(KSTARS_EKOS_FOCUS) << "Focuser properties:" + << " CanAbsMove = " << (canAbsMove ? "yes" : "no" ) + << " CanRelMove = " << (canRelMove ? "yes" : "no" ) + << " CanTimerMove = " << (canTimerMove ? "yes" : "no" ); + m_FocusType = (canRelMove || canAbsMove || canTimerMove) ? FOCUS_AUTO : FOCUS_MANUAL; profilePlot->setFocusAuto(m_FocusType == FOCUS_AUTO); @@ -1121,6 +1135,13 @@ } #endif +// Run Aberration Inspector +void Focus::startAbIns() +{ + m_abInsOn = canAbInsStart(); + start(); +} + void Focus::start() { if (m_Focuser == nullptr) @@ -1147,21 +1168,51 @@ if (inAutoFocus) { + // If Autofocus is already running, just ignore this request. This condition should not happen + // There is no point signalling Autofocus failure as that will trigger actions based on the + // currently running Autofocus failing (whilst it is still running). appendLogText(i18n("Autofocus is already running, discarding start request.")); return; } else if (inAdjustFocus) { + if (++AFStartRetries < MAXIMUM_RESET_ITERATIONS) + { + // Its possible that a start request can be triggered whilst an Adjust Focus is completing + // This was reported by a user. The conditions require align resetting a filter and an offset + // on the filter needing to be applied. So retry 3 times (10s interval) and fail if still a problem + appendLogText(i18n("Autofocus start request - Waiting 10sec for AdjustFocus to complete.")); + QTimer::singleShot(10 * 1000, this, [this]() + { + start(); + }); + return; + } + appendLogText(i18n("Discarding Autofocus start request - AdjustFocus in progress.")); + completeFocusProcedure(Ekos::FOCUS_ABORTED); return; } else if (inAdaptiveFocus) { + // Protective code added as per the above else if. This scenario is unlikely + if (++AFStartRetries < MAXIMUM_RESET_ITERATIONS) + { + appendLogText(i18n("Autofocus start request - Waiting 10sec for AdaptiveFocus to complete.")); + QTimer::singleShot(10 * 1000, this, [this]() + { + start(); + }); + return; + } + appendLogText(i18n("Discarding Autofocus start request - AdaptiveFocus in progress.")); + completeFocusProcedure(Ekos::FOCUS_ABORTED); return; } - else inAutoFocus = true; + inAutoFocus = true; + AFStartRetries = 0; m_LastFocusDirection = FOCUS_NONE; waitStarSelectTimer.stop(); @@ -1228,6 +1279,7 @@ FWHMOut->setText(""); qCInfo(KSTARS_EKOS_FOCUS) << "Starting Autofocus on" << focuserLabel->text() + << " Position:" << currentPosition << " Filter:" << filter() << " Exp:" << focusExposure->value() << " Bin:" << focusBinning->currentText() @@ -1474,7 +1526,7 @@ } } -int Focus::adjustLinearPosition(int position, int newPosition, int overscan) +int Focus::adjustLinearPosition(int position, int newPosition, int overscan, bool updateDir) { if (overscan > 0 && newPosition > position) { @@ -1486,6 +1538,7 @@ adjustment = static_cast(absMotionMax) - newPosition; focuserAdditionalMovement = adjustment; + focuserAdditionalMovementUpdateDir = updateDir; return newPosition + adjustment; } @@ -1565,6 +1618,7 @@ inAdaptiveFocus = false; inBuildOffsets = false; focuserAdditionalMovement = 0; + focuserAdditionalMovementUpdateDir = true; inFocusLoop = false; captureInProgress = false; isVShapeSolution = false; @@ -1572,6 +1626,8 @@ minimumRequiredHFR = INVALID_STAR_MEASURE; noStarCount = 0; starMeasureFrames.clear(); + m_abInsOn = false; + AFStartRetries = 0; // Check if CCD was not removed due to crash or other reasons. if (m_Camera) @@ -1788,7 +1844,7 @@ // Routine to manage focus movements. All moves are now subject to overscan // + amount indicates a movement out; - amount indictaes a movement in -bool Focus::changeFocus(int amount) +bool Focus::changeFocus(int amount, bool updateDir) { // Retry capture if we stay at the same position // Allow 1 step of tolerance--Have seen stalls with amount==1. @@ -1812,7 +1868,8 @@ return false; } - const int newPosition = adjustLinearPosition(currentPosition, currentPosition + amount, focusAFOverscan->value()); + const int newPosition = adjustLinearPosition(currentPosition, currentPosition + amount, focusAFOverscan->value(), + updateDir); if (newPosition == currentPosition) return true; @@ -1820,6 +1877,9 @@ const int absNewAmount = abs(newAmount); const bool focusingOut = newAmount > 0; const QString dirStr = focusingOut ? i18n("outward") : i18n("inward"); + // update the m_LastFocusDirection unless in Iterative / Polynomial which controls this variable itself. + if (updateDir) + m_LastFocusDirection = (focusingOut) ? FOCUS_OUT : FOCUS_IN; if (focusingOut) m_Focuser->focusOut(); @@ -1929,6 +1989,7 @@ checkMosaicMaskLimits(); m_currentImageMask = newMaskType; + startAbInsB->setEnabled(canAbInsStart()); } void Focus::syncImageMaskSelection() @@ -2065,7 +2126,7 @@ } else if (m_StarMeasure == FOCUS_STAR_FWHM) { - getFWHM(¤tFWHM, ¤tWeight); + getFWHM(m_ImageData->getStarCenters(), ¤tFWHM, ¤tWeight); currentMeasure = currentFWHM; } else if (m_StarMeasure == FOCUS_STAR_FOURIER_POWER) @@ -2089,7 +2150,7 @@ } // The image has been processed for star centroids and HFRs so now process it for star FWHMs -void Focus::getFWHM(double *FWHM, double *weight) +void Focus::getFWHM(const QList &stars, double *FWHM, double *weight) { *FWHM = INVALID_STAR_MEASURE; *weight = 0.0; @@ -2099,35 +2160,36 @@ switch (m_ImageData->getStatistics().dataType) { case TBYTE: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TSHORT: // Don't think short is used as its recorded as unsigned short - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TUSHORT: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, + weight); break; case TLONG: // Don't think long is used as its recorded as unsigned long - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TULONG: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TFLOAT: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TLONGLONG: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; case TDOUBLE: - focusFWHM->processFWHM(reinterpret_cast(imageBuffer), m_ImageData, starFitting, FWHM, weight); + focusFWHM->processFWHM(reinterpret_cast(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight); break; default: @@ -2138,7 +2200,7 @@ } // The image has been processed for star centroids and HFRs so now process it for star FWHMs -void Focus::getFourierPower(double *fourierPower, double *weight) +void Focus::getFourierPower(double *fourierPower, double *weight, const int mosaicTile) { *fourierPower = INVALID_STAR_MEASURE; *weight = 1.0; @@ -2149,43 +2211,42 @@ { case TBYTE: focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, - m_FocusView->imageMask(), - fourierPower, weight); + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TSHORT: // Don't think short is used as its recorded as unsigned short - focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, m_FocusView->imageMask(), - fourierPower, weight); + focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TUSHORT: focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, - m_FocusView->imageMask(), fourierPower, weight); + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TLONG: // Don't think long is used as its recorded as unsigned long - focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, m_FocusView->imageMask(), - fourierPower, weight); + focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TULONG: focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, - m_FocusView->imageMask(), fourierPower, weight); + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TFLOAT: - focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, m_FocusView->imageMask(), - fourierPower, weight); + focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TLONGLONG: focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, - m_FocusView->imageMask(), fourierPower, weight); + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; case TDOUBLE: - focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, m_FocusView->imageMask(), - fourierPower, weight); + focusFourierPower->processFourierPower(reinterpret_cast(imageBuffer), m_ImageData, + m_FocusView->imageMask(), mosaicTile, fourierPower, weight); break; default: @@ -2365,6 +2426,10 @@ { if (plot) emit redrawHFRPlot(polynomialFit.get(), currentPosition, currentHFR); + + // Update the plot_position and plot_value vectors (used by Analyze) + updatePlotPosition(); + appendLogText(i18np("Focus procedure completed after %1 iteration.", "Focus procedure completed after %1 iterations.", plot_position.count())); @@ -2442,12 +2507,12 @@ if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot) emit drawPolynomial(polynomialFit.get(), isVShapeSolution, true); + // Enforce settling duration. Note stop resets m_GuidingSuspended + int const settleTime = m_GuidingSuspended ? guideSettleTime->value() : 0; + // Reset the autofocus flags stop(completionState); - // Enforce settling duration - int const settleTime = m_GuidingSuspended ? guideSettleTime->value() : 0; - if (settleTime > 0) appendLogText(i18n("Settling for %1s...", settleTime)); @@ -2573,6 +2638,91 @@ m_FocusView->updateFrame(); setHFRComplete(); + + if (m_abInsOn) + calculateAbInsData(); +} + +void Focus::calculateAbInsData() +{ + ImageMosaicMask *mosaicmask = dynamic_cast(m_FocusView->imageMask().get()); + const QVector tiles = mosaicmask->tiles(); + auto stars = m_ImageData->getStarCenters(); + QVector> tileStars(NUM_TILES); + + for (int star = 0; star < stars.count(); star++) + { + const int x = stars[star]->x; + const int y = stars[star]->y; + for (int tile = 0; tile < NUM_TILES; tile++) + { + QRect thisTile = tiles[tile]; + if (thisTile.contains(x, y)) + { + tileStars[tile].append(stars[star]); + break; + } + } + } + + // Get the measure for each tile + for (int tile = 0; tile < tileStars.count(); tile++) + { + double measure, weight; + + if (m_StarMeasure == FOCUS_STAR_NUM_STARS) + { + measure = tileStars[tile].count(); + weight = 1.0; + } + else if (m_StarMeasure == FOCUS_STAR_FWHM) + { + getFWHM(tileStars[tile], &measure, &weight); + } + else if (m_StarMeasure == FOCUS_STAR_FOURIER_POWER) + { + getFourierPower(&measure, &weight, tile); + } + else + { + // HFR or HFR_adj + std::vector HFRs; + + for (int star = 0; star < tileStars[tile].count(); star++) + { + HFRs.push_back(tileStars[tile][star]->HFR); + } + measure = Mathematics::RobustStatistics::ComputeLocation(Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, HFRs, 2); + weight = calculateStarWeight(focusUseWeights->isChecked(), HFRs); + } + + m_abInsMeasure[tile].append(measure); + m_abInsWeight[tile].append(weight); + m_abInsNumStars[tile].append(tileStars[tile].count()); + + if (!linearFocuser->isInFirstPass()) + { + // This is the last datapoint so calculate average star position in the tile from the tile center + // FOCUS_STAR_FOURIER_POWER doesn't use stars directly so no need to calculate offset. The other + // measures all use stars: FOCUS_STAR_NUM_STARS, FOCUS_STAR_FWHM, FOCUS_STAR_HFR, FOCUS_STAR_HFR_ADJ + int xAv = 0, yAv = 0; + if (m_StarMeasure != FOCUS_STAR_FOURIER_POWER) + { + QPoint tileCenter = tiles[tile].center(); + int xSum = 0.0, ySum = 0.0; + for (int star = 0; star < tileStars[tile].count(); star++) + { + xSum += tileStars[tile][star]->x - tileCenter.x(); + ySum += tileStars[tile][star]->y - tileCenter.y(); + } + + xAv = (tileStars[tile].count() <= 0) ? 0 : xSum / tileStars[tile].count(); + yAv = (tileStars[tile].count() <= 0) ? 0 : ySum / tileStars[tile].count(); + } + m_abInsTileCenterOffset.append(QPoint(xAv, yAv)); + } + } + m_abInsPosition.append(currentPosition); } void Focus::setCaptureComplete() @@ -2903,6 +3053,23 @@ plot_position.clear(); plot_value.clear(); isVShapeSolution = false; + m_abInsPosition.clear(); + m_abInsTileCenterOffset.clear(); + if (m_abInsMeasure.count() != NUM_TILES) + { + m_abInsMeasure.resize(NUM_TILES); + m_abInsWeight.resize(NUM_TILES); + m_abInsNumStars.resize(NUM_TILES); + } + else + { + for (int i = 0; i < m_abInsMeasure.count(); i++) + { + m_abInsMeasure[i].clear(); + m_abInsWeight[i].clear(); + m_abInsNumStars[i].clear(); + } + } emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits), m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, focusUseWeights->isChecked(), @@ -3110,6 +3277,41 @@ } } +void Focus::startAberrationInspector() +{ + // Fill in the data structure to be passed to the Aberration Inspector + AberrationInspector::abInsData data; + + ImageMosaicMask *mosaicmask = dynamic_cast(m_FocusView->imageMask().get()); + if (!mosaicmask) + { + appendLogText(i18n("Unable to launch Aberration Inspector run %1...", m_abInsRun)); + return; + } + + + data.run = ++m_abInsRun; + data.curveFit = m_CurveFit; + data.useWeights = focusUseWeights->isChecked(); + data.optDir = m_OptDir; + data.sensorWidth = m_CcdWidth; + data.sensorHeight = m_CcdHeight; + data.pixelSize = m_CcdPixelSizeX; + data.tileWidth = mosaicmask->tiles()[0].width(); + data.focuserStepMicrons = focusCFZStepSize->value(); + data.yAxisLabel = getyAxisLabel(m_StarMeasure); + data.starUnits = getStarUnits(m_StarMeasure, m_StarUnits); + data.cfzSteps = m_cfzSteps; + data.isPositionBased = isPositionBased(); + + // Launch the Aberration Inspector. + appendLogText(i18n("Launching Aberration Inspector run %1...", m_abInsRun)); + QPointer abIns(new AberrationInspector(data, m_abInsPosition, m_abInsMeasure, m_abInsWeight, + m_abInsNumStars, m_abInsTileCenterOffset)); + abIns->setAttribute(Qt::WA_DeleteOnClose); + abIns->show(); +} + void Focus::autoFocusLinear() { if (!autoFocusChecks()) @@ -3128,16 +3330,18 @@ } } - addPlotPosition(currentPosition, currentMeasure, false); - // Only use the relativeHFR algorithm if full field is enabled with one capture/measurement. bool useFocusStarsHFR = focusUseFullField->isChecked() && focusFramesCount->value() == 1; auto focusStars = useFocusStarsHFR || (m_FocusAlgorithm == FOCUS_LINEAR1PASS) ? &(m_ImageData->getStarCenters()) : nullptr; linearRequestedPosition = linearFocuser->newMeasurement(currentPosition, currentMeasure, currentWeight, focusStars); if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser->isDone() && linearFocuser->solution() != -1) + { // Linear 1 Pass is done, graph is drawn, so just move to the focus position, and update the graph. plotLinearFinalUpdates(); + if (m_abInsOn) + startAberrationInspector(); + } else // Update the graph with the next datapoint, draw the curve, etc. plotLinearFocus(); @@ -3262,7 +3466,7 @@ } m_LastFocusDirection = (pulseDuration > 0) ? FOCUS_OUT : FOCUS_IN; - if (!changeFocus(pulseDuration)) + if (!changeFocus(pulseDuration, false)) completeFocusProcedure(Ekos::FOCUS_ABORTED); break; @@ -3525,7 +3729,7 @@ } m_LastFocusDirection = (lastDelta > 0) ? FOCUS_OUT : FOCUS_IN; - if (!changeFocus(lastDelta)) + if (!changeFocus(lastDelta, false)) completeFocusProcedure(Ekos::FOCUS_ABORTED); break; @@ -3540,6 +3744,28 @@ emit newHFRPlotPosition(static_cast(pos), value, 1.0, false, pulseDuration); } +// Synchronises the plot_position and plot_value vectors with the data used by linearFocuser +// This keeps the 2 sets of data in sync for the Linear and Linear1Pass algorithms. +// For Iterative and Polynomial these vectors are built during the focusing cycle so nothing to do here +void Focus::updatePlotPosition() +{ + if (m_FocusAlgorithm == FOCUS_LINEAR1PASS || m_FocusAlgorithm == FOCUS_LINEAR) + { + QVector weights; + QVector positions; + linearFocuser->getMeasurements(&positions, &plot_value, &weights); + plot_position.clear(); + for (int i = 0; i < positions.count(); i++) + plot_position.append(positions[i]); + if (m_FocusAlgorithm == FOCUS_LINEAR1PASS) + { + // For L1P add in the solution datapoint. Linear already has this included. + plot_position.append(linearFocuser->solution()); + plot_value.append(linearFocuser->solutionValue()); + } + } +} + void Focus::autoFocusRel() { static int noStarCount = 0; @@ -3588,7 +3814,7 @@ lastHFR = currentHFR; minHFR = 1e6; m_LastFocusDirection = FOCUS_IN; - changeFocus(-pulseDuration); + changeFocus(-pulseDuration, false); break; case FOCUS_IN: @@ -3603,7 +3829,7 @@ minHFR = currentHFR; lastHFR = currentHFR; - changeFocus(m_LastFocusDirection == FOCUS_IN ? -pulseDuration : pulseDuration); + changeFocus(m_LastFocusDirection == FOCUS_IN ? -pulseDuration : pulseDuration, false); HFRInc = 0; } else @@ -3616,7 +3842,7 @@ pulseDuration *= 0.75; - if (!changeFocus(m_LastFocusDirection == FOCUS_IN ? pulseDuration : -pulseDuration)) + if (!changeFocus(m_LastFocusDirection == FOCUS_IN ? pulseDuration : -pulseDuration, false)) completeFocusProcedure(Ekos::FOCUS_ABORTED); // HFR getting worse so reverse direction @@ -3640,7 +3866,7 @@ focuserAdditionalMovement = 0; qCDebug(KSTARS_EKOS_FOCUS) << QString("Undoing overscan extension. Moving back in by %1").arg(temp); - if (!focusIn(temp)) + if (!changeFocus(-temp, focuserAdditionalMovementUpdateDir)) { appendLogText(i18n("Focuser error, check INDI panel.")); completeFocusProcedure(Ekos::FOCUS_ABORTED); @@ -3658,6 +3884,11 @@ appendLogText(i18n("Focuser error, check INDI panel.")); completeFocusProcedure(Ekos::FOCUS_ABORTED); } + else + qCDebug(KSTARS_EKOS_FOCUS) << + QString("autoFocusProcessPositionChange called with state %1 (%2), focuserAdditionalMovement=%3, inAutoFocus=%4, captureInProgress=%5, currentPosition=%6") + .arg(state).arg(pstateStr(state)).arg(focuserAdditionalMovement).arg(inAutoFocus).arg(captureInProgress) + .arg(currentPosition); } void Focus::updateProperty(INDI::Property prop) @@ -3703,7 +3934,11 @@ // Therefore we ignore it if both value and state are the same as last time. // HACK: This would shortcut the autofocus procedure reset, see completeFocusProcedure for the small hack if (currentPosition == newPosition && currentPositionState == nvp->s) + { + qCDebug(KSTARS_EKOS_FOCUS) << "Focuser position " << currentPosition << " and state:" + << pstateStr(currentPositionState) << " unchanged"; return; + } currentPositionState = nvp->s; @@ -3723,7 +3958,7 @@ { // We had something back from the focuser but we're not done yet, so // restart motion timer in case focuser gets stuck. - qCDebug(KSTARS_EKOS_FOCUS) << "Restarting focus motion timer..."; + qCDebug(KSTARS_EKOS_FOCUS) << "Restarting focus motion timer, state " << pstateStr(nvp->s); m_FocusMotionTimer.start(); } } @@ -3862,8 +4097,8 @@ { currentPosition += pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1); qCDebug(KSTARS_EKOS_FOCUS) - << QString("Rel Focuser position changed by %1 to %2") - .arg(pos->value).arg(currentPosition); + << QString("Rel Focuser position moved %1 by %2 to %3") + .arg((m_LastFocusDirection == FOCUS_IN) ? "in" : "out").arg(pos->value).arg(currentPosition); absTicksLabel->setText(QString::number(static_cast(currentPosition))); emit absolutePositionChanged(currentPosition); } @@ -3947,9 +4182,29 @@ { currentPosition += pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1); qCDebug(KSTARS_EKOS_FOCUS) - << QString("Timer Focuser position changed by %1 to %2") - .arg(pos->value).arg(currentPosition); + << QString("Timer Focuser position moved %1 by %2 to %3") + .arg((m_LastFocusDirection == FOCUS_IN) ? "in" : "out").arg(pos->value).arg(currentPosition); + } + + if (inAdjustFocus && nvp->s == IPS_OK) + { + if (focuserAdditionalMovement == 0) + { + inAdjustFocus = false; + emit focusPositionAdjusted(); + return; + } + } + + if (inAdaptiveFocus && nvp->s == IPS_OK) + { + if (focuserAdditionalMovement == 0) + { + adaptiveFocusAdmin(true, true, true); + return; + } } + autoFocusProcessPositionChange(nvp->s); } else if (nvp->s == IPS_ALERT) @@ -4035,6 +4290,7 @@ if (inFocusLoop) { startFocusB->setEnabled(false); + startAbInsB->setEnabled(false); startLoopB->setEnabled(false); stopFocusB->setEnabled(true); captureB->setEnabled(false); @@ -4094,6 +4350,7 @@ focusInB->setEnabled(true); startFocusB->setEnabled(m_FocusType == FOCUS_AUTO); + startAbInsB->setEnabled(canAbInsStart()); stopFocusB->setEnabled(!enableCaptureButtons); startGotoB->setEnabled(canAbsMove); stopGotoB->setEnabled(true); @@ -4104,12 +4361,22 @@ focusInB->setEnabled(false); startFocusB->setEnabled(false); + startAbInsB->setEnabled(false); stopFocusB->setEnabled(false); startGotoB->setEnabled(false); stopGotoB->setEnabled(false); } } +// Return whether the Aberration Inspector Start button should be enabled. The pre-requisties are: +// - Absolute position focuser +// - Mosaic Mask is on +// - Algorithm is LINEAR 1 PASS +bool Focus::canAbInsStart() +{ + return canAbsMove && m_FocusAlgorithm == FOCUS_LINEAR1PASS && m_currentImageMask == FOCUS_MASK_MOSAIC; +} + // Disable input widgets during an Autofocus run. Keep a record so after the AF run, widgets can be re-enabled void Focus::AFDisable(QWidget * widget, const bool children) { @@ -4555,6 +4822,7 @@ case ISD::Mount::MOUNT_MOVING: captureB->setEnabled(false); startFocusB->setEnabled(false); + startAbInsB->setEnabled(false); startLoopB->setEnabled(false); // If mount is moved while we have a star selected and subframed @@ -4599,6 +4867,10 @@ { if (oneSource->getDeviceName() == name) { + // clear reference to avoid runtime exception in checkTemperatureSource() + if (m_LastSourceDeviceAutofocusTemperature && m_LastSourceDeviceAutofocusTemperature->getDeviceName() == name) + m_LastSourceDeviceAutofocusTemperature.reset(nullptr); + m_TemperatureSources.removeAll(oneSource); QTimer::singleShot(1000, this, [this, name]() { @@ -5237,8 +5509,9 @@ captureTimeout.setSingleShot(true); connect(&captureTimeout, &QTimer::timeout, this, &Ekos::Focus::processCaptureTimeout); - // Start/Stop focus + // Start/Stop focus and the Aberration Inspector connect(startFocusB, &QPushButton::clicked, this, &Ekos::Focus::start); + connect(startAbInsB, &QPushButton::clicked, this, &Ekos::Focus::startAbIns); connect(stopFocusB, &QPushButton::clicked, this, &Ekos::Focus::abort); // Focus IN/OUT @@ -5524,6 +5797,9 @@ focusGaussianKernelSize->show(); } + // Aberration Inspector button + startAbInsB->setEnabled(canAbInsStart()); + // Settings tab changes // Disable adaptive focus focusAdaptive->setChecked(false); @@ -5643,6 +5919,9 @@ focusGaussianKernelSize->show(); } + // Aberration Inspector button + startAbInsB->setEnabled(canAbInsStart()); + // Settings tab changes // Disable adaptive focus focusAdaptive->setChecked(false); @@ -5757,6 +6036,9 @@ focusGaussianKernelSize->show(); } + // Aberration Inspector button + startAbInsB->setEnabled(canAbInsStart()); + // Settings tab changes // Disable adaptive focus focusAdaptive->setChecked(false); @@ -5878,9 +6160,12 @@ focusGaussianKernelSize->show(); } + // Aberration Inspector button + startAbInsB->setEnabled(canAbInsStart()); + // Settings tab changes - // Enable adaptive focus - adaptiveFocusGroup->setEnabled(true); + // Enable adaptive focus for Absolute focusers + adaptiveFocusGroup->setEnabled(canAbsMove); // Mechanics tab changes // Firstly max Single Step is not used by Linear 1 Pass @@ -6761,12 +7046,21 @@ // Get the pixel size of the active camera for later calculations auto nvp = camera->getNumber("CCD_INFO"); if (!nvp) + { m_CcdPixelSizeX = 0.0; + m_CcdWidth = m_CcdHeight = 0; + } else { auto np = nvp->findWidgetByName("CCD_PIXEL_SIZE_X"); if (np) m_CcdPixelSizeX = np->getValue(); + np = nvp->findWidgetByName("CCD_MAX_X"); + if (np) + m_CcdWidth = np->getValue(); + np = nvp->findWidgetByName("CCD_MAX_Y"); + if (np) + m_CcdHeight = np->getValue(); } } setCamera(camera); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.h 2023-12-03 05:23:17.000000000 +0000 @@ -1,4 +1,3 @@ - /* SPDX-FileCopyrightText: 2012 Jasem Mutlaq @@ -7,16 +6,11 @@ #pragma once -#include "ekos/auxiliary/filtermanager.h" #include "ui_focus.h" -#include "focusprofileplot.h" -#include "focusfwhm.h" #include "focusfourierpower.h" #include "ekos/ekos.h" -#include "ekos/auxiliary/stellarsolverprofileeditor.h" -#include "ekos/auxiliary/darkprocessor.h" -#include "ekos/mount/mount.h" -#include "fitsviewer/fitsviewer.h" +#include "parameters.h" + #include "indi/indicamera.h" #include "indi/indifocuser.h" #include "indi/indistd.h" @@ -25,11 +19,20 @@ #include +class FocusProfilePlot; +class FITSData; +class FITSView; +class FitsViewer; + namespace Ekos { +class DarkProcessor; +class FilterManager; class FocusAlgorithmInterface; +class FocusFWHM; class PolynomialFit; +class StellarSolverProfileEditor; /** * @class Focus @@ -443,7 +446,7 @@ */ void adaptiveFocus(); -protected: + protected: void addPlotPosition(int pos, double hfr, bool plot = true); private slots: @@ -473,6 +476,7 @@ void starDetectionFinished(); void setCurrentMeasure(); + void startAbIns(); signals: void newLog(const QString &text); @@ -667,6 +671,9 @@ // Linear final updates to the curve void plotLinearFinalUpdates(); + // Launch the Aberation Inspector popup + void startAberrationInspector(); + // Get the curve fitting goal based on how the algorithm is progressing CurveFitting::FittingGoal getGoal(int numSteps); @@ -678,10 +685,20 @@ return (canAbsMove || canRelMove || (m_FocusAlgorithm == FOCUS_LINEAR) || (m_FocusAlgorithm == FOCUS_LINEAR1PASS)); } void resetButtons(); + + /** + * @brief returns whether the Aberration Inspector can be used or not + * @return can / cant be started + */ + bool canAbInsStart(); void stop(FocusState completionState = FOCUS_ABORTED); void initView(); + /** @brief Sets the plot vectors for Analyze after Autofocus. Used by Linear and Linear1Pass + */ + void updatePlotPosition(); + /** * @brief prepareCapture Set common settings for capture for focus module * @param targetChip target Chip @@ -730,7 +747,7 @@ void focusAdvisorHelp(); // Move the focuser in (negative) or out (positive amount). - bool changeFocus(int amount); + bool changeFocus(int amount, bool updateDir = true); // Start up capture, or occasionally move focuser again, after current focus-move accomplished. void autoFocusProcessPositionChange(IPState state); @@ -741,13 +758,14 @@ // and set focuserAdditionalMovement to the extra motion, so that after this motion completes // we will then scan back in (back to the originally requested position). This "overscan dance" is done // to reduce backlash on such movement changes and so that we've always focused in before capture. - int adjustLinearPosition(int position, int newPosition, int overscan); + int adjustLinearPosition(int position, int newPosition, int overscan, bool updateDir); // Process the image to get star FWHMs - void getFWHM(double *FWHM, double *weight); + void getFWHM(const QList &stars, double *FWHM, double *weight); // Process the image to get the Fourier Transform Power - void getFourierPower(double *fourierPower, double *weight); + // If tile = -1 use the whole image; if mosaicTile is specified use just that + void getFourierPower(double *fourierPower, double *weight, const int mosaicTile = -1); /** * @brief syncTrackingBoxPosition Sync the tracking box to the current selected star center @@ -990,6 +1008,8 @@ double R2 = 0; // Counter to retry the auto focus run if the R2Limit has not been reached int R2Retries = 0; + // Counter to retry starting auto focus if the focuser is still active + int AFStartRetries = 0; /// Autofocus log file info. QStringList m_LogText; @@ -1100,6 +1120,7 @@ // Linear focuser. std::unique_ptr linearFocuser; int focuserAdditionalMovement { 0 }; + bool focuserAdditionalMovementUpdateDir { true }; int linearRequestedPosition { 0 }; bool hasDeviation { false }; @@ -1143,6 +1164,8 @@ double m_FocalRatio = 0.0f; double m_Reducer = 0.0f; double m_CcdPixelSizeX = 0.0f; + int m_CcdWidth = 0; + int m_CcdHeight = 0; QString m_ScopeType; // CFZ @@ -1178,5 +1201,15 @@ double FAFocusMaxTravel = 0; int FAFocusCaptureTimeout = 30; int FAFocusMotionTimeout = 30; + + // Aberration Inspector + void calculateAbInsData(); + bool m_abInsOn = false; + int m_abInsRun = 0; + QVector m_abInsPosition; + QVector> m_abInsMeasure; + QVector> m_abInsWeight; + QVector> m_abInsNumStars; + QVector m_abInsTileCenterOffset; }; } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focus.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focus.ui 2023-12-03 05:23:17.000000000 +0000 @@ -6,8 +6,8 @@ 0 0 - 886 - 547 + 891 + 663 @@ -41,7 +41,7 @@ Qt::Horizontal - + 1 @@ -125,7 +125,7 @@ - + 0 0 @@ -149,52 +149,37 @@ 3 - - + + false - - - 0 - 0 - - - 0 - 32 + 24 + 24 - Desired absolute focus position + Start framing - - - - - - false + + - + + + ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus + + - 0 - 32 + 24 + 24 - - Current absolute focuser position - - - QLineEdit[readOnly="true"] { color: gray } - - - true - - - + + false @@ -205,7 +190,7 @@ - Focus In + Focus Out @@ -214,7 +199,7 @@ - + ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus @@ -225,20 +210,36 @@ - - + + + + false + - 266 - 0 + 24 + 24 - - true + + Capture image + + + + + + + ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus + + + + 24 + 24 + - + false @@ -292,23 +293,6 @@ - - - - Focuser: - - - - - - - Start: - - - startFocusB - - - @@ -319,8 +303,8 @@ - - + + false @@ -331,86 +315,89 @@ - Focus Out - - - + Go to an absolute focus position - + ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus - 24 - 24 + 28 + 28 - - - - false - + + - 24 - 24 + 266 + 32 - - Go to an absolute focus position + + true + + + + - - - - - ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus + Start: - - - 28 - 28 - + + startFocusB - + false - 24 - 24 + 0 + 32 - Start framing + Stop Auto Focus process - + Stop - - - ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus + + + + + + false - + - 24 - 24 + 0 + 32 + + Current absolute focuser position + + + QLineEdit[readOnly="true"] { color: gray } + + + true + - - + + false @@ -421,13 +408,16 @@ - Capture image + Focus In + + + - + ../../../../../../../../../../Projects2/kstars/kstars/ekos/focus../../../../../../../../../../Projects2/kstars/kstars/ekos/focus @@ -438,8 +428,15 @@ + + + + Focuser: + + + - + false @@ -450,10 +447,32 @@ - Stop Auto Focus process + <html><head/><body><p>Run Aberration Inspector (Auto Focus will run first to collect data).</p><p>Note: Mosaic Mask must be set to activate this button.</p><p>This is an experimental feature.</p></body></html> - Stop + Inspector + + + + + + + false + + + + 0 + 0 + + + + + 0 + 32 + + + + Desired absolute focus position @@ -463,7 +482,7 @@ - + 0 0 @@ -3796,6 +3815,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -3876,7 +3908,7 @@ - + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -71,6 +71,14 @@ return -1; } + bool isInFirstPass() const override + { + if (params.focusAlgorithm == Focus::FOCUS_LINEAR || params.focusAlgorithm == Focus::FOCUS_LINEAR1PASS) + return inFirstPass; + else + return true; + } + QString getTextStatus(double R2 = 0) const override; private: diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusalgorithms.h 2023-12-03 05:23:17.000000000 +0000 @@ -155,6 +155,9 @@ virtual QString getTextStatus(double R2 = 0) const = 0; + // For Linear and L1P returns whether focuser is inFirstPass, other algos return true + virtual bool isInFirstPass() const = 0; + // For testing. virtual FocusAlgorithmInterface *Copy() = 0; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusfourierpower.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusfourierpower.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusfourierpower.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusfourierpower.h 2023-12-03 05:23:17.000000000 +0000 @@ -11,6 +11,7 @@ #include "fitsviewer/fitsview.h" #include "fitsviewer/fitsdata.h" #include "auxiliary/imagemask.h" +#include "aberrationinspectorutils.h" #include "curvefit.h" #include "../ekos.h" #include @@ -60,56 +61,147 @@ ~FocusFourierPower(); template - void processFourierPower(const T imageBuffer, const QSharedPointer &imageData, - QSharedPointer mask, double *fourierPower, double *weight) + void processFourierPower(const T &imageBuffer, const QSharedPointer &imageData, + const QSharedPointer &mask, const int &tile, double *fourierPower, double *weight) { // Initialise outputs *fourierPower = INVALID_STAR_MEASURE; *weight = 1.0; + // Check mask & tile inputs + ImageMosaicMask *mosaicMask = nullptr; + if (tile >= 0) + { + if (mask) + { + if (tile >= NUM_TILES) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 Fourier Transform called with invalid mosaic tile %2").arg(__FUNCTION__) + .arg(tile); + return; + } + + mosaicMask = dynamic_cast(mask.get()); + if (!mosaicMask) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 Fourier Transform called with invalid 2 mosaic tile %2").arg(__FUNCTION__) + .arg(tile); + return; + } + } + else + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 Fourier Transform called for mosaic tile but no mask").arg(__FUNCTION__); + return; + } + } + + // Dimensions on area to perform Fourier Transform on; whole sensor or just tile auto stats = imageData->getStatistics(); - const auto width = stats.width; - const auto height = stats.height; - const auto N = width * height; - double *image = new double[2 * N]; + unsigned int width, height; + if (tile < 0) + { + width = stats.width; + height = stats.height; + } + else + { + // Calculating for a single (square) mosaic tile + width = mosaicMask->tiles()[tile].width(); + height = width; + } - // Set the gsl error handler off as it aborts the program on error. - auto const oldErrorHandler = gsl_set_error_handler_off(); + // Allocate memory for the Fourier Transform + unsigned long N = width * height; + double *image = new(std::nothrow) double[2 * N]; + if (!image) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 Unable to allocate memory to perform Fourier Transforms").arg(__FUNCTION__); + return; + } - /* alloc memory for complex wavetables, and workspace */ + /* Allocate memory for GSL complex wavetables, and workspace */ gsl_fft_complex_wavetable *rowWT = gsl_fft_complex_wavetable_alloc(width); gsl_fft_complex_workspace *rowWS = gsl_fft_complex_workspace_alloc(width); gsl_fft_complex_wavetable *colWT = gsl_fft_complex_wavetable_alloc(height); gsl_fft_complex_workspace *colWS = gsl_fft_complex_workspace_alloc(height); + if (!rowWT || !rowWS || !colWT || !colWS) + { + qCDebug(KSTARS_EKOS_FOCUS) << QString("%1 Unable to allocate memory2 to perform Fourier Transforms").arg(__FUNCTION__); + delete[] image; + return; + } + + // Set the gsl error handler off as it aborts the program on error. + auto const oldErrorHandler = gsl_set_error_handler_off(); // Convert the image to complex double datatype as required by GSL FFT // The real part is just the background subtracted pixel value clipped to zero // The imaginary part is zero. - auto skyBackground = imageData->getSkyBackground(); auto bg = skyBackground.mean + 3.0 * skyBackground.sigma; - uint16_t posX = 0, posY = 0; - for (long i = 0; i < N; i++) + // Load the "image" buffer from the passed in image data. As the loop is quite large I've created 3 loops + // each with minimal work inside. This makes the overall code larger but avoids repeated tests within the loop + if (tile < 0) { - if (mask.isNull() || mask->active() == false || mask->isVisible(posX, posY)) - image[i * 2] = std::max(0.0, (double) imageBuffer[i] - bg); + // Setup image for whole sensor + if (mask.isNull() || mask->active() == false) + { + // No active mask + for (unsigned long i = 0; i < N; i++) + { + image[i * 2] = std::max(0.0, (double) imageBuffer[i] - bg); + image[i * 2 + 1] = 0.0; + } + } else - image[i * 2] = 0.0; + { + // There is an active mask on the sensor so honour these settings + unsigned int posX = 0, posY = 0; + for (unsigned long i = 0; i < N; i++) + { + if (mask->isVisible(posX, posY)) + image[i * 2] = std::max(0.0, (double) imageBuffer[i] - bg); + else + image[i * 2] = 0.0; + + image[i * 2 + 1] = 0.0; + + if (++posX == stats.width) + { + posX = 0; + posY++; + } + } + } + } + else + { + // A mosaic tile has been specified so we know we are dealing with a mosaic mask + unsigned int posX = mosaicMask->tiles()[tile].topLeft().x(); + unsigned int posY = mosaicMask->tiles()[tile].topLeft().y(); - // Imaginary value is always zero - image[i * 2 + 1] = 0.0; + unsigned long offset = posY * stats.width + posX; + const unsigned int widthLimit = posX + width; - if (++posX == width) + // Perform calc for a specific tile of a mosaic mask + for (unsigned long i = 0; i < N; i++) { - posX = 0; - posY++; + image[i * 2] = std::max(0.0, (double) imageBuffer[offset + i] - bg); + image[i * 2 + 1] = 0.0; + + if (++posX == widthLimit) + { + posX = mosaicMask->tiles()[tile].topLeft().x(); + offset += stats.width - width; + } } } // Perform FFT on all the rows int status = 0; - for (int j = 0; j < height; j++) + for (unsigned int j = 0; j < height; j++) { status = gsl_fft_complex_forward(&image[j * 2 * width], 1, width, rowWT, rowWS); if (status != 0) @@ -123,7 +215,7 @@ if (status == 0) { // Perform FFT on all the cols - for (int i = 0; i < width; i++) + for (unsigned int i = 0; i < width; i++) { status = gsl_fft_complex_forward(&image[2 * i], width, height, colWT, colWS); if (status != 0) @@ -138,17 +230,22 @@ if (status == 0) { double power = 0.0; - for (long i = 0; i < N; i++) + for (unsigned long i = 0; i < N; i++) power += pow(image[i * 2], 2.0) + pow(image[i * 2 + 1], 2.0); power /= pow(N, 2.0); - qCDebug(KSTARS_EKOS_FOCUS) << "FFT power=" << power; + if (tile < 0) + qCDebug(KSTARS_EKOS_FOCUS) << QString("FFT power sensor %1x%2 = %3").arg(stats.width).arg(stats.height).arg(power); + else + qCDebug(KSTARS_EKOS_FOCUS) << QString("FFT power tile %1 %2x%3 = %4").arg(tile).arg(stats.width).arg(stats.height).arg( + power); *fourierPower = power; } - /* free memory */ + // free memory + delete[] image; gsl_fft_complex_wavetable_free(rowWT); gsl_fft_complex_workspace_free(rowWS); gsl_fft_complex_wavetable_free(colWT); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusfwhm.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusfwhm.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/focusfwhm.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/focusfwhm.h 2023-12-03 05:23:17.000000000 +0000 @@ -28,13 +28,13 @@ ~FocusFWHM(); template - void processFWHM(const T imageBuffer, const QSharedPointer &imageData, std::unique_ptr &starFitting, + void processFWHM(const T &imageBuffer, const QList &focusStars, const QSharedPointer &imageData, + std::unique_ptr &starFitting, double *FWHM, double *weight) { CurveFitting::StarParams starParams, starParams2; std::vector FWHMs, R2s; - auto focusStars = imageData->getStarCenters(); auto skyBackground = imageData->getSkyBackground(); auto stats = imageData->getStatistics(); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,112 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "sensorgraphic.h" +#include +#include +#include + +namespace Ekos +{ + +SensorGraphic::SensorGraphic(const QWidget *parent, const int SW, const int SH, const int tileSize) : + m_Parent(parent), m_SW(SW), m_SH(SH), m_tileSize(tileSize) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowTransparentForInput | Qt::WindowStaysOnTopHint); + + // Scale the Picture to 100 pixels in the largest dimension + m_SW = std::max(100, m_SW); + m_SH = std::max(100, m_SH); + double scaling = static_cast(std::max(m_SW, m_SH)) / 100.0; + m_SW /= scaling; + m_SH /= scaling; + m_tileSize /= scaling; + + // Check if the picture resource exists + QFileInfo check_file(m_picturePath); + if (check_file.exists() || check_file.isFile()) + { + m_PW = m_SW * 1.35; + m_PH = m_SH * 1.4; + } + else + { + m_PW = m_SW; + m_PH = m_SH; + m_picturePath = ""; + } + resize(m_PW, m_PH); +} + +SensorGraphic::~SensorGraphic() +{ +} + +void SensorGraphic::paintEvent(QPaintEvent *) +{ + // Draw the picture with the correct width / height aspect + QRectF sensor(0.0, 0.0, m_PW, m_PH); + QPainter painter(this); + // Check if the picture resource exists; if so use it otherwise draw a black box + if (m_picturePath.isEmpty()) + painter.fillRect(sensor, "black"); + else + painter.drawImage(sensor, QImage(m_picturePath)); + + // Setup the 9 rectangular tiles of the mosaic relative to sensor (later we will adjust this relative to the picture) + QRectF tiles[NUM_TILES]; + tiles[0].setRect(0, 0, m_tileSize, m_tileSize); + tiles[1].setRect((m_SW - m_tileSize) / 2, 0, m_tileSize, m_tileSize); + tiles[2].setRect(m_SW - m_tileSize, 0, m_tileSize, m_tileSize); + tiles[3].setRect(0, (m_SH - m_tileSize) / 2, m_tileSize, m_tileSize); + tiles[4].setRect((m_SW - m_tileSize) / 2, (m_SH - m_tileSize) / 2, m_tileSize, m_tileSize); + tiles[5].setRect(m_SW - m_tileSize, (m_SH - m_tileSize) / 2, m_tileSize, m_tileSize); + tiles[6].setRect(0, m_SH - m_tileSize, m_tileSize, m_tileSize); + tiles[7].setRect((m_SW - m_tileSize) / 2, m_SH - m_tileSize, m_tileSize, m_tileSize); + tiles[8].setRect(m_SW - m_tileSize, m_SH - m_tileSize, m_tileSize, m_tileSize); + + // Setup an offset point to translate from sensor coordinates to picture coordinates + QPointF offset = QPointF((m_PW - m_SW) / 2, (m_PH - m_SH) / 2); + + // Loop through each mosaic tile painting it appropriately + for (int i = 0; i < NUM_TILES; i++) + { + // If not interested in this tile do nothing + if (!m_useTile[i]) + continue; + + // Translate from sensor coordinates to picture coordinates + tiles[i].translate(offset); + + // Paint the tile grey to start with + painter.fillRect(tiles[i], "white"); + + if (i == m_Highlight) + { + painter.setPen(TILE_COLOUR[m_Highlight]); + painter.drawRect(tiles[i]); + } + else + painter.setPen("black"); + + painter.drawText(tiles[i], Qt::AlignCenter, TILE_NAME[i]); + } +} + +void SensorGraphic::setHighlight(int highlight) +{ + m_Highlight = highlight; +} + +void SensorGraphic::setTiles(bool useTiles[NUM_TILES]) +{ + for (int i = 0; i < NUM_TILES; i++) + m_useTile[i] = useTiles[i]; +} + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/focus/sensorgraphic.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,74 @@ +/* + SPDX-FileCopyrightText: 2023 John Evans + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "aberrationinspectorutils.h" +#include + +// The SensorGraphic class renders a graphic of a camera sensor with the mosaic tiles drawn on it. +// The tiles occupy the correct proportion and position of the sensor. +// Each tile is labelled appropriately, e.g. T = top, TL = top left. +// There is a highlight method where a single tile is highlighted in its appropriate colour. +// +// SensorGraphic behaves like a tooltip. Tooltips seem to only allow text. This class creates a popup window. +// It is a subclass of QWidget where the paintEvent method has been reimplemented. +// +namespace Ekos +{ + +class SensorGraphic : public QWidget +{ + public: + /** + * @brief create a SensorGraphic with the associated dimensions + * @param parent widget + * @param sensor width (pixels) + * @param sensor height (pixels) + * @param tile size + */ + SensorGraphic(const QWidget *parent, const int SW, const int SH, const int tileSize); + ~SensorGraphic(); + + /** + * @brief set the tile to highlight + * @param highlight + */ + void setHighlight(int highlight); + + /** + * @brief set the tiles to use + * @param useTile array + */ + void setTiles(bool useTile[NUM_TILES]); + + protected: + /** + * @brief implemented paintEvent + * @param paint event + */ + void paintEvent(QPaintEvent *) override; + + private: + const QWidget * m_Parent; + int m_Highlight { 0 }; + + // Picture variables + int m_PW { 0 }; + int m_PH { 0 }; + + // Sensor variables + int m_SW { 0 }; + int m_SH { 0 }; + int m_tileSize { 0 }; + + // Path to picture resource + QString m_picturePath { ":/icons/sensorgraphic.png" }; + + bool m_useTile[NUM_TILES] = { true, true, true, true, true, true, true, true, true }; +}; + +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -13,6 +13,7 @@ #include "ekos/manager.h" #include "fitsviewer/fitsdata.h" #include "ekos/guide/guide.h" +#include "fitsviewer/fitsview.h" #include #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/externalguide/phd2.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,7 +7,6 @@ #pragma once #include "../guideinterface.h" -#include "fitsviewer/fitsview.h" #include #include @@ -15,6 +14,7 @@ #include #include +class FITSView; class QTcpSocket; namespace Ekos diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guide.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guide.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guide.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guide.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -30,6 +30,9 @@ #include "internalguide/internalguider.h" #include "guideview.h" #include "guidegraph.h" +#include "guidestatewidget.h" +#include "manualpulse.h" +#include "ekos/auxiliary/darkprocessor.h" #include @@ -793,6 +796,22 @@ m_Camera->setEncodingFormat("FITS"); } +void Guide::abortExposure() +{ + if (m_Camera && guiderType == GUIDE_INTERNAL) + { + captureTimeout.stop(); + m_PulseTimer.stop(); + ISD::CameraChip *targetChip = + m_Camera->getChip(useGuideHead ? ISD::CameraChip::GUIDE_CCD : ISD::CameraChip::PRIMARY_CCD); + if (targetChip->isCapturing()) + { + qCDebug(KSTARS_EKOS_GUIDE) << "Aborting guide capture"; + targetChip->abortExposure(); + } + } +} + bool Guide::abort() { if (m_Camera && guiderType == GUIDE_INTERNAL) @@ -1300,7 +1319,7 @@ ditherLabel->setText("Dither"); ditherLabel->setFont(QFont(font().family(), 10)); - if (guiderType == GUIDE_INTERNAL) + if (guiderType == GUIDE_INTERNAL && !Options::ditherWithOnePulse()) { if (m_State != GUIDE_GUIDING) capture(); @@ -1932,6 +1951,7 @@ connect(m_GuiderInstance, &Ekos::GuideInterface::newAxisSigma, this, &Ekos::Guide::setAxisSigma); connect(m_GuiderInstance, &Ekos::GuideInterface::newSNR, this, &Ekos::Guide::setSNR); connect(m_GuiderInstance, &Ekos::GuideInterface::guideInfo, this, &Ekos::Guide::guideInfo); + connect(m_GuiderInstance, &Ekos::GuideInterface::abortExposure, this, &Ekos::Guide::abortExposure); driftGraph->connectGuider(m_GuiderInstance); targetPlot->connectGuider(m_GuiderInstance); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guide.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guide.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guide.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guide.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,12 +8,9 @@ #include "ui_guide.h" #include "guideinterface.h" -#include "guidestatewidget.h" #include "ekos/ekos.h" #include "indi/indicamera.h" #include "indi/indimount.h" -#include "manualpulse.h" -#include "ekos/auxiliary/darkprocessor.h" #include #include @@ -37,6 +34,9 @@ class InternalGuider; class PHD2; class LinGuider; +class GuideStateWidget; +class ManualPulse; +class DarkProcessor; /** * @class Guide @@ -316,6 +316,9 @@ */ void processData(const QSharedPointer &data); + // Aborts the current exposure, if one is ongoing. + void abortExposure(); + // This Function will allow PHD2 to update the exposure values to the recommended ones. QString setRecommendedExposureValues(QList values); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -9,6 +9,7 @@ #include "klocalizedstring.h" #include "ksnotification.h" #include "kstarsdata.h" +#include "guideinterface.h" #include "Options.h" // Qt version calming diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guidedriftgraph.h 2023-12-03 05:23:17.000000000 +0000 @@ -13,8 +13,11 @@ #include "qcustomplot.h" #include "guidegraph.h" -#include "guideinterface.h" +namespace Ekos +{ +class GuideInterface; +} class GuideDriftGraph : public QCustomPlot { Q_OBJECT diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guideinterface.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guideinterface.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/guideinterface.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/guideinterface.h 2023-12-03 05:23:17.000000000 +0000 @@ -87,6 +87,7 @@ double snr, double skyBg, int numStars); void guideEquipmentUpdated(); void guideInfo(const QString &); + void abortExposure(); protected: Ekos::GuideState state { GUIDE_IDLE }; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -3,6 +3,8 @@ #include "gmath.h" #include "ekos_guide_debug.h" #include "gmath.h" +#include "guidelog.h" + #include "Options.h" namespace Ekos diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/calibrationprocess.h 2023-12-03 05:23:17.000000000 +0000 @@ -8,10 +8,8 @@ #pragma once -#include "fitsviewer/fitsdata.h" #include "indi/indicommon.h" #include "../guideinterface.h" -#include "guidelog.h" #include "calibration.h" #include @@ -24,6 +22,7 @@ class QVector3D; class GuideView; class Edge; +class GuideLog; namespace Ekos { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -16,6 +16,8 @@ #include "ekos_guide_debug.h" #include "ekos/auxiliary/stellarsolverprofileeditor.h" #include "guidealgorithms.h" +#include "guidelog.h" +#include "../guideview.h" #include #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/gmath.h 2023-12-03 05:23:17.000000000 +0000 @@ -17,12 +17,10 @@ #include #include #include +#include #include #include -#include "guidelog.h" -#include "starcorrespondence.h" -#include "fitsviewer/fitssepdetector.h" #include "guidestars.h" #include "calibration.h" @@ -30,6 +28,7 @@ class FITSData; class Edge; +class GuideLog; // For now also copied in guidealgorithms.cpp #define SMART_THRESHOLD 0 diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -15,6 +15,7 @@ #include "ekos_guide_debug.h" #include "ekos/auxiliary/stellarsolverprofileeditor.h" #include "Options.h" +#include "fitsviewer/fitsdata.h" #define SMART_THRESHOLD 0 #define SEP_THRESHOLD 1 diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidealgorithms.h 2023-12-03 05:23:17.000000000 +0000 @@ -12,8 +12,8 @@ #include "vect.h" #include #include -#include "fitsviewer/fitsdata.h" +class FITSData; class Edge; // Traditional guiding functions for star detection. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -8,6 +8,8 @@ #include "ekos_guide_debug.h" #include "../guideview.h" +#include "fitsviewer/fitsdata.h" +#include "fitsviewer/fitssepdetector.h" #include "Options.h" #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/guidestars.h 2023-12-03 05:23:17.000000000 +0000 @@ -10,13 +10,12 @@ #include #include -#include "fitsviewer/fitsdata.h" -#include "fitsviewer/fitssepdetector.h" #include "starcorrespondence.h" #include "vect.h" -#include "../guideview.h" #include "calibration.h" +class GuideView; + namespace SSolver { class Parameters; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -17,6 +17,8 @@ #include "guidealgorithms.h" #include "ksnotification.h" #include "ekos/auxiliary/stellarsolverprofileeditor.h" +#include "fitsviewer/fitsdata.h" +#include "../guideview.h" #include @@ -277,6 +279,9 @@ bool InternalGuider::dither(double pixels) { + if (Options::ditherWithOnePulse() ) + return onePulseDither(pixels); + double ret_x, ret_y; pmath->getTargetPosition(&ret_x, &ret_y); @@ -421,6 +426,103 @@ return true; } +bool InternalGuider::onePulseDither(double pixels) +{ + qCDebug(KSTARS_EKOS_GUIDE) << "OnePulseDither(" << "pixels" << ")"; + + // Cancel any current guide exposures. + emit abortExposure(); + + double ret_x, ret_y; + pmath->getTargetPosition(&ret_x, &ret_y); + + auto seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::default_random_engine generator(seed); + std::uniform_real_distribution angleMagnitude(0, 360); + + double angle = angleMagnitude(generator) * dms::DegToRad; + double diff_x = pixels * cos(angle); + double diff_y = pixels * sin(angle); + + if (pmath->getCalibration().declinationSwapEnabled()) + diff_y *= -1; + + if (m_DitherOrigin.x() == 0 && m_DitherOrigin.y() == 0) + { + m_DitherOrigin = QVector3D(ret_x, ret_y, 0); + } + double totalXOffset = ret_x - m_DitherOrigin.x(); + double totalYOffset = ret_y - m_DitherOrigin.y(); + + // If we've dithered too far, and diff_x or diff_y is pushing us even further away, then change its direction. + // Note: it is possible that we've dithered too far, but diff_x/y is pointing in the right direction. + // Don't change it in that 2nd case. + if (((diff_x + totalXOffset > MAX_DITHER_TRAVEL) && (diff_x > 0)) || + ((diff_x + totalXOffset < -MAX_DITHER_TRAVEL) && (diff_x < 0))) + { + qCDebug(KSTARS_EKOS_GUIDE) + << QString("OPD: Dithering target off by too much in X (abs(%1 + %2) > %3), adjust diff_x from %4 to %5") + .arg(diff_x).arg(totalXOffset).arg(MAX_DITHER_TRAVEL).arg(diff_x).arg(diff_x * -1.5); + diff_x *= -1.5; + } + if (((diff_y + totalYOffset > MAX_DITHER_TRAVEL) && (diff_y > 0)) || + ((diff_y + totalYOffset < -MAX_DITHER_TRAVEL) && (diff_y < 0))) + { + qCDebug(KSTARS_EKOS_GUIDE) + << QString("OPD: Dithering target off by too much in Y (abs(%1 + %2) > %3), adjust diff_y from %4 to %5") + .arg(diff_y).arg(totalYOffset).arg(MAX_DITHER_TRAVEL).arg(diff_y).arg(diff_y * -1.5); + diff_y *= -1.5; + } + + m_DitherTargetPosition = GuiderUtils::Vector(ret_x, ret_y, 0) + GuiderUtils::Vector(diff_x, diff_y, 0); + + qCDebug(KSTARS_EKOS_GUIDE) + << QString("OPD: Dithering by %1 pixels. Target: %2,%3 Current: %4,%5 Move: %6,%7 Wander: %8,%9") + .arg(pixels, 3, 'f', 1) + .arg(m_DitherTargetPosition.x, 5, 'f', 1).arg(m_DitherTargetPosition.y, 5, 'f', 1) + .arg(ret_x, 5, 'f', 1).arg(ret_y, 5, 'f', 1) + .arg(diff_x, 4, 'f', 1).arg(diff_y, 4, 'f', 1) + .arg(totalXOffset + diff_x, 5, 'f', 1).arg(totalYOffset + diff_y, 5, 'f', 1); + guideLog.ditherInfo(diff_x, diff_y, m_DitherTargetPosition.x, m_DitherTargetPosition.y); + + pmath->setTargetPosition(m_DitherTargetPosition.x, m_DitherTargetPosition.y); + + if (Options::gPGEnabled()) + // This is the offset in image coordinates, but needs to be converted to RA. + pmath->getGPG().startDithering(diff_x, diff_y, pmath->getCalibration()); + + state = GUIDE_DITHERING; + emit newStatus(state); + + const GuiderUtils::Vector xyMove(diff_x, diff_y, 0); + const GuiderUtils::Vector raDecMove = pmath->getCalibration().rotateToRaDec(xyMove); + double raPulse = fabs(raDecMove.x * pmath->getCalibration().raPulseMillisecondsPerArcsecond()); + double decPulse = fabs(raDecMove.y * pmath->getCalibration().decPulseMillisecondsPerArcsecond()); + auto raDir = raDecMove.x > 0 ? RA_INC_DIR : RA_DEC_DIR; + auto decDir = raDecMove.y > 0 ? DEC_DEC_DIR : DEC_INC_DIR; + + m_isFirstFrame = true; + + // Send pulse if we have one active direction at least. + QString raDirString = raDir == RA_DEC_DIR ? "RA_DEC" : "RA_INC"; + QString decDirString = decDir == DEC_INC_DIR ? "DEC_INC" : "DEC_DEC"; + + qCDebug(KSTARS_EKOS_GUIDE) << "OnePulseDither RA: " << raPulse << "ms" << raDirString << " DEC: " << decPulse << "ms " << + decDirString; + emit newMultiPulse(raDir, raPulse, decDir, decPulse, StartCaptureAfterPulses); + + double totalMSecs = 1000.0 * Options::ditherSettle() + std::max(raPulse, decPulse); + + state = GUIDE_DITHERING_SETTLE; + guideLog.settleStartedInfo(); + emit newStatus(state); + + if (Options::gPGEnabled()) + pmath->getGPG().ditheringSettled(true); + + QTimer::singleShot(totalMSecs, this, SLOT(setDitherSettled())); + return true; +} bool InternalGuider::abortDither() { @@ -767,7 +869,7 @@ pmath->setAlgorithmIndex(index); } -bool InternalGuider::getReticleParameters(double *x, double *y) +bool InternalGuider::getReticleParameters(double * x, double * y) { return pmath->getTargetPosition(x, y); } @@ -800,7 +902,7 @@ return true; } -void InternalGuider::emitAxisPulse(const cproc_out_params *out) +void InternalGuider::emitAxisPulse(const cproc_out_params * out) { double raPulse = out->pulse_length[GUIDE_RA]; double dePulse = out->pulse_length[GUIDE_DEC]; @@ -977,7 +1079,7 @@ } } -bool InternalGuider::isPoorGuiding(const cproc_out_params* out) +bool InternalGuider::isPoorGuiding(const cproc_out_params * out) { double delta_rms = std::hypot(out->delta[GUIDE_RA], out->delta[GUIDE_DEC]); if (delta_rms > Options::guideMaxDeltaRMS()) @@ -1191,7 +1293,7 @@ return rc; } -void InternalGuider::fillGuideInfo(GuideLog::GuideInfo *info) +void InternalGuider::fillGuideInfo(GuideLog::GuideInfo * info) { // NOTE: just using the X values, phd2logview assumes x & y the same. // pixel scale in arc-sec / pixel. The 2nd and 3rd values seem redundent, but are diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/internalguide/internalguider.h 2023-12-03 05:23:17.000000000 +0000 @@ -9,7 +9,6 @@ #pragma once #include "matr.h" -#include "fitsviewer/fitsdata.h" #include "indi/indicommon.h" #include "../guideinterface.h" #include "guidelog.h" @@ -25,7 +24,7 @@ #include class QVector3D; - +class FITSData; class cgmath; class GuideView; class Edge; @@ -140,6 +139,7 @@ bool processGuiding(); void startDarkGuiding(); bool abortDither(); + bool onePulseDither(double pixels); void reset(); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/manualpulse.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/manualpulse.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/manualpulse.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/manualpulse.h 2023-12-03 05:23:17.000000000 +0000 @@ -6,9 +6,10 @@ #pragma once -#include "ekos/guide/guideinterface.h" #include "ui_manualpulse.h" #include "indi/indicommon.h" +#include "skypoint.h" +#include "ekos/guide/guideinterface.h" #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsdither.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsdither.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsdither.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsdither.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -9,7 +9,6 @@ #include "Options.h" #include "kstars.h" #include "auxiliary/ksnotification.h" -#include "internalguide/internalguider.h" #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsdither.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsdither.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsdither.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsdither.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,9 +7,6 @@ #pragma once #include "ui_opsdither.h" -#include "guide.h" -#include "ksutils.h" -#include "kspaths.h" class KConfigDialog; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsguide.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsguide.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsguide.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsguide.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -10,6 +10,8 @@ #include "kstars.h" #include "auxiliary/ksnotification.h" #include "internalguide/internalguider.h" +#include "ekos/auxiliary/stellarsolverprofileeditor.h" +#include "kspaths.h" #include diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsguide.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsguide.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/guide/opsguide.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/guide/opsguide.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,16 +7,18 @@ #pragma once #include "ui_opsguide.h" + #include "guide.h" #include "stellarsolver.h" -#include "ksutils.h" -#include "kspaths.h" -#include "ekos/auxiliary/stellarsolverprofileeditor.h" +#include "parameters.h" class KConfigDialog; namespace Ekos { + +class StellarSolverProfileEditor; + /** * @class OpsGuide * diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/manager.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/manager.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/manager.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/manager.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -28,6 +28,7 @@ #include "auxiliary/ksmessagebox.h" #include "auxiliary/profilesettings.h" #include "capture/sequencejob.h" +#include "capture/captureprocess.h" #include "fitsviewer/fitsview.h" #include "fitsviewer/fitsdata.h" #include "indi/clientmanager.h" @@ -40,7 +41,9 @@ #include "indi/indiwebmanager.h" #include "indi/indigps.h" #include "indi/indiguider.h" +#include "indi/indirotator.h" #include "mount/meridianflipstatuswidget.h" +#include "ekos/auxiliary/rotatorutils.h" #include "ekoslive/ekosliveclient.h" #include "ekoslive/message.h" @@ -164,6 +167,7 @@ }); connect(this, &Manager::ekosStatusChanged, ekosLiveClient.get()->message(), &EkosLive::Message::setEkosStatingStatus); + connect(this, &Manager::indiStatusChanged, ekosLiveClient.get()->message(), &EkosLive::Message::setINDIStatus); connect(ekosLiveClient.get()->message(), &EkosLive::Message::connected, this, [&]() { ekosLiveB->setIcon(QIcon(":/icons/cloud-online.svg")); @@ -1626,6 +1630,8 @@ auto dome = device->getDome(); if (dome) { + if (captureProcess) + captureProcess->setDome(dome); if (observatoryProcess) observatoryProcess->setDome(dome); } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/mount/mount.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/mount/mount.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/mount/mount.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/mount/mount.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -29,6 +29,8 @@ #include "ekos/auxiliary/opticaltrainmanager.h" #include "ekos/auxiliary/profilesettings.h" #include "ekos/auxiliary/opticaltrainsettings.h" +#include "ekos/manager/meridianflipstate.h" +#include "ekos/align/polaralignmentassistant.h" #include "kstars.h" #include "skymapcomposite.h" @@ -2067,4 +2069,8 @@ disconnect(mf_state.get(), &MeridianFlipState::slewTelescope, nullptr, nullptr); } +double Mount::initialHA() +{ + return mf_state->initialPositionHA(); +} } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/mount/mount.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/mount/mount.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/mount/mount.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/mount/mount.h 2023-12-03 05:23:17.000000000 +0000 @@ -13,8 +13,6 @@ #include "indi/indistd.h" #include "indi/indifocuser.h" #include "indi/indimount.h" -#include "ekos/manager/meridianflipstate.h" -#include "ekos/align/polaralignmentassistant.h" class QQuickView; class QQuickItem; @@ -29,6 +27,7 @@ */ class OpticalTrainManager; +class MeridianFlipState; class Mount : public QWidget, public Ui::Mount { @@ -277,10 +276,7 @@ * This is used to manage the meridian flip for mounts which do not report pier side. * only one attempt to flip is done. */ - Q_SCRIPTABLE double initialHA() - { - return mf_state->initialPositionHA(); - } + Q_SCRIPTABLE double initialHA(); /** DBUS interface function. * Aborts the mount motion diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/opsekos.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/opsekos.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/opsekos.ui 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/opsekos.ui 2023-12-03 05:23:17.000000000 +0000 @@ -406,6 +406,19 @@ + + + + <html><head/><body><p>When checked the scheduler tries to run lower priority jobs when no higher priority job can run. Recommended.</p></body></html> + + + Use greedy scheduling + + + true + + + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/framingassistantui.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/framingassistantui.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/framingassistantui.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/framingassistantui.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -15,6 +15,7 @@ #include "scheduler.h" #include "skymap.h" #include "ekos/manager.h" +#include "ekos/mount/mount.h" #include "skymapcomposite.h" #include "ksparser.h" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -12,6 +12,7 @@ #include "scheduler.h" #include "ekos/ekos.h" #include "ui_scheduler.h" +#include "schedulerjob.h" #define TEST_PRINT if (false) fprintf @@ -141,7 +142,7 @@ { switch (job->getCompletionCondition()) { - case SchedulerJob::FINISH_AT: + case FINISH_AT: /* If planned finishing time has passed, the job is set to IDLE waiting for a next chance to run */ if (job->getCompletionTime().isValid() && job->getCompletionTime() < now) { @@ -150,7 +151,7 @@ } break; - case SchedulerJob::FINISH_REPEAT: + case FINISH_REPEAT: // In case of a repeating jobs, let's make sure we have more runs left to go // If we don't, re-estimate imaging time for the scheduler job before concluding if (job->getRepeatsRemaining() == 0) @@ -290,7 +291,7 @@ constexpr int MAX_INTERRUPT_SECS = 30; // Don't interrupt START_AT jobs unless they can no longer run, or they're interrupted by another START_AT. - bool currentJobIsStartAt = (currentJob && currentJob->getFileStartupCondition() == SchedulerJob::START_AT && + bool currentJobIsStartAt = (currentJob && currentJob->getFileStartupCondition() == START_AT && currentJob->getFileStartupTime().isValid()); QDateTime nextStart; SchedulerJob *nextJob = nullptr; @@ -323,7 +324,7 @@ if (nextInterruption) *nextInterruption = QDateTime(); interruptStr = ""; } - else + else if (Options::greedyScheduling()) { // Allow this job to be scheduled if it can run this many seconds // before running into a higher priority job. @@ -374,7 +375,7 @@ if (atJob == nextJob) continue; const QDateTime atTime = atJob->getFileStartupTime(); - if (atJob->getFileStartupCondition() == SchedulerJob::START_AT && atTime.isValid()) + if (atJob->getFileStartupCondition() == START_AT && atTime.isValid()) { if (!allowJob(atJob, rescheduleAbortsImmediate, rescheduleAbortsQueue, rescheduleErrors)) continue; @@ -423,7 +424,7 @@ // - the selected job is a repeating job and // - another group member is runnable now and // - that group mnember is behind the selected job's iteration. - if (nextJob && !nextJob->getGroup().isEmpty() && nextJob->getCompletedIterations() > 0) + if (nextJob && !nextJob->getGroup().isEmpty() && Options::greedyScheduling() && nextJob->getCompletedIterations() > 0) { // Iterate through the jobs list, first finding the selected job, the looking at all jobs after that. bool foundSelectedJob = false; @@ -588,7 +589,7 @@ foreach (SchedulerJob *job, simJobs) { if (job != selectedJob && - job->getStartupCondition() == SchedulerJob::START_AT && + job->getStartupCondition() == START_AT && jobStartTime.secsTo(job->getStartupTime()) > 0 && (job->getState() == SchedulerJob::JOB_EVALUATION || job->getState() == SchedulerJob::JOB_SCHEDULED)) @@ -643,9 +644,9 @@ // This if clause handles the simulation of scheduler repeat groups // which applies to scheduler jobs with repeat-style completion conditions. if (!selectedJob->getGroup().isEmpty() && - (selectedJob->getCompletionCondition() == SchedulerJob::FINISH_LOOP || - selectedJob->getCompletionCondition() == SchedulerJob::FINISH_REPEAT || - selectedJob->getCompletionCondition() == SchedulerJob::FINISH_AT)) + (selectedJob->getCompletionCondition() == FINISH_LOOP || + selectedJob->getCompletionCondition() == FINISH_REPEAT || + selectedJob->getCompletionCondition() == FINISH_AT)) { if (originalIteration.find(selectedJob) == originalIteration.end()) originalIteration[selectedJob] = selectedJob->getCompletedIterations(); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/greedyscheduler.h 2023-12-03 05:23:17.000000000 +0000 @@ -9,14 +9,15 @@ #include #include #include +#include #include #include -#include "schedulerjob.h" namespace Ekos { class Scheduler; +class SchedulerJob; class GreedyScheduler : public QObject { diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -18,6 +18,8 @@ #include "Options.h" #include "scheduleradaptor.h" #include "schedulerjob.h" +#include "schedulerprocess.h" +#include "schedulermodulestate.h" #include "skymapcomposite.h" #include "skycomponents/mosaiccomponent.h" #include "skyobjects/mosaictiles.h" @@ -28,6 +30,8 @@ #include "ekos/capture/placeholderpath.h" #include "skyobjects/starobject.h" #include "greedyscheduler.h" +#include "ekos/auxiliary/solverutils.h" +#include "ekos/auxiliary/stellarsolverprofile.h" #include #include @@ -40,7 +44,6 @@ #include #define BAD_SCORE -1000 -#define MAX_FAILURE_ATTEMPTS 5 #define RESTART_GUIDING_DELAY_MS 5000 #define DEFAULT_MIN_ALTITUDE 15 @@ -71,140 +74,6 @@ // Functions to make human-readable debug messages for the various enums. -QString timerStr(Scheduler::SchedulerTimerState state) -{ - switch (state) - { - case Scheduler::RUN_WAKEUP: - return QString("RUN_WAKEUP"); - case Scheduler::RUN_SCHEDULER: - return QString("RUN_SCHEDULER"); - case Scheduler::RUN_JOBCHECK: - return QString("RUN_JOBCHECK"); - case Scheduler::RUN_SHUTDOWN: - return QString("RUN_SHUTDOWN"); - case Scheduler::RUN_NOTHING: - return QString("RUN_NOTHING"); - } - return QString("????"); -} - -QString ekosStateString(Scheduler::EkosState state) -{ - switch(state) - { - case Scheduler::EKOS_IDLE: - return "Ekos is idle"; - case Scheduler::EKOS_STARTING: - return "Starting Ekos"; - case Scheduler::EKOS_STOPPING: - return "Stopping Ekos"; - case Scheduler::EKOS_READY: - return "Ekos is ready"; - } - return QString("????"); -} - -QString indiStateString(Scheduler::INDIState state) -{ - switch(state) - { - case Scheduler::INDI_IDLE: - return "INDI is idle"; - case Scheduler::INDI_PROPERTY_CHECK: - return "Checking INDI properties"; - case Scheduler::INDI_CONNECTING: - return "Connecting to INDI"; - case Scheduler::INDI_DISCONNECTING: - return "Disconnecting to INDI"; - case Scheduler::INDI_READY: - return "INDIis ready"; - } - return QString("????"); -} - -QString startupStateString(Scheduler::StartupState state) -{ - switch(state) - { - case Scheduler::STARTUP_IDLE: - return "Startup is idle"; - case Scheduler::STARTUP_SCRIPT: - return "Startup running script"; - case Scheduler::STARTUP_UNPARK_DOME: - return "Startup unpark dome"; - case Scheduler::STARTUP_UNPARKING_DOME: - return "Startup unparking dome"; - case Scheduler::STARTUP_UNPARK_MOUNT: - return "Startup unpark mount"; - case Scheduler::STARTUP_UNPARKING_MOUNT: - return "Startup unparking mount"; - case Scheduler::STARTUP_UNPARK_CAP: - return "Startup remove cap"; - case Scheduler::STARTUP_UNPARKING_CAP: - return "Starup removing cap"; - case Scheduler::STARTUP_ERROR: - return "Startup error"; - case Scheduler::STARTUP_COMPLETE: - return "Startup is complete"; - } - return QString("????"); -} - -QString shutdownStateString(Scheduler::ShutdownState state) -{ - switch(state) - { - case Scheduler::SHUTDOWN_IDLE: - return "Shutdown is idle"; - case Scheduler::SHUTDOWN_PARK_CAP: - return "Shutdown remove cap"; - case Scheduler::SHUTDOWN_PARKING_CAP: - return "Shutdown removing cap"; - case Scheduler::SHUTDOWN_PARK_MOUNT: - return "Shutdown park mount"; - case Scheduler::SHUTDOWN_PARKING_MOUNT: - return "Shutdown parking mount"; - case Scheduler::SHUTDOWN_PARK_DOME: - return "Shutdown park dome"; - case Scheduler::SHUTDOWN_PARKING_DOME: - return "Shutdown parking dome"; - case Scheduler::SHUTDOWN_SCRIPT: - return "Shutdown script"; - case Scheduler::SHUTDOWN_SCRIPT_RUNNING: - return "Shutdown script running"; - case Scheduler::SHUTDOWN_ERROR: - return "Shutdown error"; - case Scheduler::SHUTDOWN_COMPLETE: - return "Shutdown complete"; - } - return QString("????"); -} - -QString parkWaitStateString(Scheduler::ParkWaitStatus state) -{ - switch(state) - { - case Scheduler::PARKWAIT_IDLE: - return "Park idle"; - case Scheduler::PARKWAIT_PARK: - return "Park"; - case Scheduler::PARKWAIT_PARKING: - return "Parking"; - case Scheduler::PARKWAIT_PARKED: - return "Parked"; - case Scheduler::PARKWAIT_UNPARK: - return "Unpark"; - case Scheduler::PARKWAIT_UNPARKING: - return "Unparking"; - case Scheduler::PARKWAIT_UNPARKED: - return "Unparked"; - case Scheduler::PARKWAIT_ERROR: - return "Park error"; - } - return QString("????"); -} - QString commStatusString(Ekos::CommunicationStatus state) { switch(state) @@ -248,54 +117,44 @@ TEST_PRINT(stderr, "%s", QString("%1 %2 %3%4 %5 %6 %7 %8 %9\n") .arg(label) - .arg(timerStr(timerState)) - .arg(schedulerStateString(state)) - .arg((timerState == Scheduler::RUN_JOBCHECK && currentJob != nullptr) ? - QString("(%1 %2)").arg(SchedulerJob::jobStatusString(currentJob->getState())) - .arg(SchedulerJob::jobStageString(currentJob->getStage())) : "") - .arg(ekosStateString(ekosState)) - .arg(indiStateString(indiState)) - .arg(startupStateString(startupState)) - .arg(shutdownStateString(shutdownState)) - .arg(parkWaitStateString(parkWaitState)).toLatin1().data()); + .arg(timerStr(moduleState()->timerState())) + .arg(schedulerStateString(moduleState()->schedulerState())) + .arg((moduleState()->timerState() == RUN_JOBCHECK && activeJob() != nullptr) ? + QString("(%1 %2)").arg(SchedulerJob::jobStatusString(activeJob()->getState())) + .arg(SchedulerJob::jobStageString(activeJob()->getStage())) : "") + .arg(ekosStateString(moduleState()->ekosState())) + .arg(indiStateString(moduleState()->indiState())) + .arg(startupStateString(moduleState()->startupState())) + .arg(shutdownStateString(moduleState()->shutdownState())) + .arg(parkWaitStateString(moduleState()->parkWaitState())).toLatin1().data()); } QDateTime Scheduler::Dawn, Scheduler::Dusk, Scheduler::preDawnDateTime; -// Allows for unit testing of static Scheduler methods, -// as can't call KStarsData::Instance() during unit testing. -KStarsDateTime *Scheduler::storedLocalTime = nullptr; -KStarsDateTime Scheduler::getLocalTime() -{ - if (hasLocalTime()) - return *storedLocalTime; - return KStarsData::Instance()->geo()->UTtoLT(KStarsData::Instance()->clock()->utc()); -} - // This is the initial conditions that need to be set before starting. void Scheduler::init() { // This is needed to get wakeupScheduler() to call start() and startup, // instead of assuming it is already initialized (if preemptiveShutdown was not set). // The time itself is not used. - enablePreemptiveShutdown(getLocalTime()); + moduleState()->enablePreemptiveShutdown(SchedulerModuleState::getLocalTime()); - iterationSetup = false; - setupNextIteration(RUN_WAKEUP, 10); + moduleState()->setIterationSetup(false); + moduleState()->setupNextIteration(RUN_WAKEUP, 10); } // Setup the main loop and start. void Scheduler::start() { - foreach (auto j, jobs) + foreach (auto j, moduleState()->jobs()) j->enableGraphicsUpdates(false); // New scheduler session shouldn't inherit ABORT or ERROR states from the last one. - foreach (auto j, jobs) + foreach (auto j, moduleState()->jobs()) j->setState(SchedulerJob::JOB_IDLE); init(); - foreach (auto j, jobs) + foreach (auto j, moduleState()->jobs()) j->enableGraphicsUpdates(true); iterate(); @@ -309,34 +168,34 @@ if (msSleep < 0) return; - connect(&iterationTimer, &QTimer::timeout, this, &Scheduler::iterate, Qt::UniqueConnection); - iterationTimer.setSingleShot(true); - iterationTimer.start(msSleep); + connect(&moduleState()->iterationTimer(), &QTimer::timeout, this, &Scheduler::iterate, Qt::UniqueConnection); + moduleState()->iterationTimer().setSingleShot(true); + moduleState()->iterationTimer().start(msSleep); } bool Scheduler::currentlySleeping() { - return iterationTimer.isActive() && timerState == RUN_WAKEUP; + return moduleState()->iterationTimer().isActive() && moduleState()->timerState() == RUN_WAKEUP; } int Scheduler::runSchedulerIteration() { qint64 now = QDateTime::currentMSecsSinceEpoch(); - if (startMSecs == 0) - startMSecs = now; + if (moduleState()->startMSecs() == 0) + moduleState()->setStartMSecs(now); printStates(QString("\nrunScheduler Iteration %1 @ %2") - .arg(++schedulerIteration) - .arg((now - startMSecs) / 1000.0, 1, 'f', 3)); + .arg(moduleState()->increaseSchedulerIteration()) + .arg((now - moduleState()->startMSecs()) / 1000.0, 1, 'f', 3)); - SchedulerTimerState keepTimerState = timerState; + SchedulerTimerState keepTimerState = moduleState()->timerState(); // TODO: At some point we should require that timerState and timerInterval // be explicitly set in all iterations. Not there yet, would require too much // refactoring of the scheduler. When we get there, we'd exectute the following here: // timerState = RUN_NOTHING; // don't like this comment, it should always set a state and interval! // timerInterval = -1; - iterationSetup = false; + moduleState()->setIterationSetup(false); switch (keepTimerState) { case RUN_WAKEUP: @@ -352,54 +211,21 @@ checkShutdownState(); break; case RUN_NOTHING: - timerInterval = -1; + moduleState()->setTimerInterval(-1); break; } - if (!iterationSetup) + if (!moduleState()->iterationSetup()) { // See the above TODO. // Since iterations aren't yet always set up, we repeat the current // iteration type if one wasn't set up in the current iteration. // qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler iteration never set up."; - timerInterval = m_UpdatePeriodMs; + moduleState()->setTimerInterval(moduleState()->updatePeriodMs()); TEST_PRINT(stderr, "Scheduler iteration never set up--repeating %s with %d...\n", - timerStr(timerState).toLatin1().data(), timerInterval); - } - printStates(QString("End iteration, sleep %1: ").arg(timerInterval)); - return timerInterval; -} -void Scheduler::setupNextIteration(SchedulerTimerState nextState) -{ - setupNextIteration(nextState, m_UpdatePeriodMs); -} - -void Scheduler::setupNextIteration(SchedulerTimerState nextState, int milliseconds) -{ - if (iterationSetup) - { - qCDebug(KSTARS_EKOS_SCHEDULER) - << QString("Multiple setupNextIteration calls: current %1 %2, previous %3 %4") - .arg(nextState).arg(milliseconds).arg(timerState).arg(timerInterval); - TEST_PRINT(stderr, "Multiple setupNextIteration calls: current %s %d, previous %s %d.\n", - timerStr(nextState).toLatin1().data(), milliseconds, - timerStr(timerState).toLatin1().data(), timerInterval); - } - timerState = nextState; - // check if setup is called from a thread outside of the iteration timer thread - if (iterationTimer.isActive()) - { - // restart the timer to ensure the correct startup delay - int remaining = iterationTimer.remainingTime(); - iterationTimer.stop(); - timerInterval = std::max(0, milliseconds - remaining); - iterationTimer.start(timerInterval); - } - else - { - // setup called from inside the iteration timer thread - timerInterval = milliseconds; + timerStr(moduleState()->timerState()).toLatin1().data(), moduleState()->timerInterval()); } - iterationSetup = true; + printStates(QString("End iteration, sleep %1: ").arg(moduleState()->timerInterval())); + return moduleState()->timerInterval(); } Scheduler::Scheduler() @@ -424,10 +250,13 @@ qRegisterMetaType("Ekos::SchedulerState"); qDBusRegisterMetaType(); + m_moduleState.reset(new SchedulerModuleState()); + m_process = new SchedulerProcess(moduleState()); + dirPath = QUrl::fromLocalFile(QDir::homePath()); // Get current KStars time and set seconds to zero - QDateTime currentDateTime = getLocalTime(); + QDateTime currentDateTime = SchedulerModuleState::getLocalTime(); QTime currentTime = currentDateTime.time(); currentTime.setHMS(currentTime.hour(), currentTime.minute(), 0); currentDateTime.setTime(currentTime); @@ -443,11 +272,11 @@ QDBusConnection::sessionBus().unregisterObject(schedulerPathString); if (!QDBusConnection::sessionBus().registerObject(schedulerPathString, this)) qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Scheduler failed to register with dbus"); - ekosInterface = new QDBusInterface(kstarsInterfaceString, ekosPathStr, ekosInterfaceStr, - QDBusConnection::sessionBus(), this); + process()->setEkosInterface(new QDBusInterface(kstarsInterfaceString, ekosPathStr, ekosInterfaceStr, + QDBusConnection::sessionBus(), this)); - indiInterface = new QDBusInterface(kstarsInterfaceString, INDIPathString, INDIInterfaceString, - QDBusConnection::sessionBus(), this); + process()->setIndiInterface(new QDBusInterface(kstarsInterfaceString, INDIPathString, INDIInterfaceString, + QDBusConnection::sessionBus(), this)); // Example of connecting DBus signals //connect(ekosInterface, SIGNAL(indiStatusChanged(Ekos::CommunicationStatus)), this, SLOT(setINDICommunicationStatus(Ekos::CommunicationStatus))); @@ -541,8 +370,8 @@ repeatSequenceCB->setChecked(Options::schedulerRepeatSequences()); executionSequenceLimit->setValue(Options::schedulerExecutionSequencesLimit()); - connect(startupB, &QPushButton::clicked, this, &Scheduler::runStartupProcedure); - connect(shutdownB, &QPushButton::clicked, this, &Scheduler::runShutdownProcedure); + connect(startupB, &QPushButton::clicked, process(), &SchedulerProcess::runStartupProcedure); + connect(shutdownB, &QPushButton::clicked, process(), &SchedulerProcess::runShutdownProcedure); connect(selectObjectB, &QPushButton::clicked, this, &Scheduler::selectObject); connect(selectFITSB, &QPushButton::clicked, this, &Scheduler::selectFITS); @@ -600,17 +429,28 @@ connect(KStarsData::Instance()->clock(), &SimClock::scaleChanged, this, &Scheduler::simClockScaleChanged); connect(KStarsData::Instance()->clock(), &SimClock::timeChanged, this, &Scheduler::simClockTimeChanged); + // Connect to the state machine + connect(moduleState().data(), &SchedulerModuleState::ekosStateChanged, this, &Scheduler::ekosStateChanged); + connect(moduleState().data(), &SchedulerModuleState::indiStateChanged, this, &Scheduler::indiStateChanged); + connect(moduleState().data(), &SchedulerModuleState::startupStateChanged, this, &Scheduler::startupStateChanged); + connect(moduleState().data(), &SchedulerModuleState::shutdownStateChanged, this, &Scheduler::shutdownStateChanged); + connect(moduleState().data(), &SchedulerModuleState::parkWaitStateChanged, this, &Scheduler::parkWaitStateChanged); + connect(moduleState().data(), &SchedulerModuleState::profilesChanged, this, &Scheduler::updateProfiles); + connect(moduleState().data(), &SchedulerModuleState::currentProfileChanged, this, [&]() + { + schedulerProfileCombo->setCurrentText(moduleState()->currentProfile()); + }); + // Connect to process engine + connect(process().data(), &SchedulerProcess::newLog, this, &Scheduler::appendLogText); + connect(process().data(), &SchedulerProcess::stopScheduler, this, &Scheduler::stop); + connect(process().data(), &SchedulerProcess::stopCurrentJobAction, this, &Scheduler::stopCurrentJobAction); + connect(process().data(), &SchedulerProcess::findNextJob, this, &Scheduler::findNextJob); + connect(process().data(), &SchedulerProcess::getNextAction, this, &Scheduler::getNextAction); // Connect geographical location - when it is available //connect(KStarsData::Instance()..., &LocationDialog::locationChanged..., this, &Scheduler::simClockTimeChanged); - // Restore values for scheduler checkboxes. - parkDomeCheck->setChecked(Options::schedulerParkDome()); - parkMountCheck->setChecked(Options::schedulerParkMount()); - capCheck->setChecked(Options::schedulerCloseDustCover()); - warmCCDCheck->setChecked(Options::schedulerWarmCCD()); - unparkDomeCheck->setChecked(Options::schedulerUnparkDome()); - unparkMountCheck->setChecked(Options::schedulerUnparkMount()); - uncapCheck->setChecked(Options::schedulerOpenDustCover()); + // Restore values for general settings. + syncGUIToGeneralSettings(); trackStepCheck->setChecked(Options::schedulerTrackStep()); focusStepCheck->setChecked(Options::schedulerFocusStep()); guideStepCheck->setChecked(Options::schedulerGuideStep()); @@ -705,11 +545,6 @@ Options::setSchedulerExecutionSequencesLimit(executionSequenceLimit->value()); }); - // restore default values for error handling strategy - setErrorHandlingStrategy(static_cast(Options::errorHandlingStrategy())); - errorHandlingRescheduleErrorsCB->setChecked(Options::rescheduleErrors()); - errorHandlingDelaySB->setValue(Options::errorHandlingStrategyDelay()); - // save new default values for error handling strategy connect(errorHandlingRescheduleErrorsCB, &QPushButton::clicked, [](bool checked) @@ -720,7 +555,9 @@ (&QButtonGroup::buttonClicked), [this](QAbstractButton * button) { Q_UNUSED(button) - Options::setErrorHandlingStrategy(getErrorHandlingStrategy()); + ErrorHandlingStrategy strategy = getErrorHandlingStrategy(); + Options::setErrorHandlingStrategy(strategy); + errorHandlingDelaySB->setEnabled(strategy != ERROR_DONT_RESTART); }); connect(errorHandlingDelaySB, static_cast(&QSpinBox::valueChanged), [](int value) { @@ -751,14 +588,14 @@ calculateDawnDusk(); updateNightTime(); - loadProfiles(); + process()->loadProfiles(); watchJobChanges(true); } QString Scheduler::getCurrentJobName() { - return (currentJob != nullptr ? currentJob->getName() : ""); + return (activeJob() != nullptr ? activeJob()->getName() : ""); } void Scheduler::watchJobChanges(bool enable) @@ -909,7 +746,7 @@ m_LogText.removeLast(); m_LogText.prepend(i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", - getLocalTime().toString("yyyy-MM-ddThh:mm:ss"), text)); + SchedulerModuleState::getLocalTime().toString("yyyy-MM-ddThh:mm:ss"), text)); qCInfo(KSTARS_EKOS_SCHEDULER) << text; @@ -929,7 +766,7 @@ repeatSequenceCB->setEnabled(Options::rememberJobProgress() == false); executionSequenceLimit->setEnabled(Options::rememberJobProgress() == false); - if (SCHEDULER_RUNNING != state) + if (SCHEDULER_RUNNING != moduleState()->schedulerState()) { evaluateJobs(true); } @@ -1103,30 +940,32 @@ void Scheduler::selectStartupScript() { - startupScriptURL = QFileDialog::getOpenFileUrl(Ekos::Manager::Instance(), i18nc("@title:window", "Select Startup Script"), - dirPath, - i18n("Script (*)")); - if (startupScriptURL.isEmpty()) + moduleState()->setStartupScriptURL(QFileDialog::getOpenFileUrl(Ekos::Manager::Instance(), i18nc("@title:window", + "Select Startup Script"), + dirPath, + i18n("Script (*)"))); + if (moduleState()->startupScriptURL().isEmpty()) return; - dirPath = QUrl(startupScriptURL.url(QUrl::RemoveFilename)); + dirPath = QUrl(moduleState()->startupScriptURL().url(QUrl::RemoveFilename)); - mDirty = true; - startupScript->setText(startupScriptURL.toLocalFile()); + moduleState()->setDirty(true); + startupScript->setText(moduleState()->startupScriptURL().toLocalFile()); } void Scheduler::selectShutdownScript() { - shutdownScriptURL = QFileDialog::getOpenFileUrl(Ekos::Manager::Instance(), i18nc("@title:window", "Select Shutdown Script"), - dirPath, - i18n("Script (*)")); - if (shutdownScriptURL.isEmpty()) + moduleState()->setShutdownScriptURL(QFileDialog::getOpenFileUrl(Ekos::Manager::Instance(), i18nc("@title:window", + "Select Shutdown Script"), + dirPath, + i18n("Script (*)"))); + if (moduleState()->shutdownScriptURL().isEmpty()) return; - dirPath = QUrl(shutdownScriptURL.url(QUrl::RemoveFilename)); + dirPath = QUrl(moduleState()->shutdownScriptURL().url(QUrl::RemoveFilename)); - mDirty = true; - shutdownScript->setText(shutdownScriptURL.toLocalFile()); + moduleState()->setDirty(true); + shutdownScript->setText(moduleState()->shutdownScriptURL().toLocalFile()); } void Scheduler::addJob() @@ -1147,77 +986,9 @@ emit jobsUpdated(getJSONJobs()); } -void Scheduler::setupJob( - SchedulerJob &job, const QString &name, const QString &group, const dms &ra, const dms &dec, double djd, double rotation, - const QUrl &sequenceUrl, const QUrl &fitsUrl, SchedulerJob::StartupCondition startup, const QDateTime &startupTime, - SchedulerJob::CompletionCondition completion, const QDateTime &completionTime, int completionRepeats, - double minimumAltitude, double minimumMoonSeparation, bool enforceWeather, bool enforceTwilight, - bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide) -{ - /* Configure or reconfigure the observation job */ - - job.setName(name); - job.setGroup(group); - // djd should be ut.djd - job.setTargetCoords(ra, dec, djd); - job.setPositionAngle(rotation); - - /* Consider sequence file is new, and clear captured frames map */ - job.setCapturedFramesMap(SchedulerJob::CapturedFramesMap()); - job.setSequenceFile(sequenceUrl); - job.setFITSFile(fitsUrl); - // #1 Startup conditions - - job.setStartupCondition(startup); - if (startup == SchedulerJob::START_AT) - { - job.setStartupTime(startupTime); - } - /* Store the original startup condition */ - job.setFileStartupCondition(job.getStartupCondition()); - job.setFileStartupTime(job.getStartupTime()); - - // #2 Constraints - - job.setMinAltitude(minimumAltitude); - job.setMinMoonSeparation(minimumMoonSeparation); - - // Check enforce weather constraints - job.setEnforceWeather(enforceWeather); - // twilight constraints - job.setEnforceTwilight(enforceTwilight); - job.setEnforceArtificialHorizon(enforceArtificialHorizon); - - job.setCompletionCondition(completion); - if (completion == SchedulerJob::FINISH_AT) - job.setCompletionTime(completionTime); - else if (completion == SchedulerJob::FINISH_REPEAT) - { - job.setRepeatsRequired(completionRepeats); - job.setRepeatsRemaining(completionRepeats); - } - // Job steps - job.setStepPipeline(SchedulerJob::USE_NONE); - if (track) - job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_TRACK)); - if (focus) - job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_FOCUS)); - if (align) - job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_ALIGN)); - if (guide) - job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_GUIDE)); - - /* Store the original startup condition */ - job.setFileStartupCondition(job.getStartupCondition()); - job.setFileStartupTime(job.getStartupTime()); - - /* Reset job state to evaluate the changes */ - job.reset(); -} - void Scheduler::saveJob() { - if (state == SCHEDULER_RUNNING) + if (moduleState()->schedulerState() == SCHEDULER_RUNNING) { appendLogText(i18n("Warning: You cannot add or modify a job while the scheduler is running.")); return; @@ -1278,13 +1049,13 @@ qCWarning(KSTARS_EKOS_SCHEDULER) << "BUG: the observation job under edit does not match the selected row in the job table."; /* Use the job in the row currently edited */ - job = jobs.at(currentRow); + job = moduleState()->jobs().at(currentRow); } else { /* Instantiate a new job, insert it in the job list and add a row in the table for it just after the row currently selected. */ job = new SchedulerJob(); - jobs.insert(currentRow, job); + moduleState()->mutlableJobs().insert(currentRow, job); queueTable->insertRow(currentRow); } @@ -1298,17 +1069,17 @@ // Get several job values depending on the state of the UI. - SchedulerJob::StartupCondition startCondition = SchedulerJob::START_AT; + StartupCondition startCondition = START_AT; if (asapConditionR->isChecked()) - startCondition = SchedulerJob::START_ASAP; + startCondition = START_ASAP; - SchedulerJob::CompletionCondition stopCondition = SchedulerJob::FINISH_AT; + CompletionCondition stopCondition = FINISH_AT; if (sequenceCompletionR->isChecked()) - stopCondition = SchedulerJob::FINISH_SEQUENCE; + stopCondition = FINISH_SEQUENCE; else if (repeatCompletionR->isChecked()) - stopCondition = SchedulerJob::FINISH_REPEAT; + stopCondition = FINISH_REPEAT; else if (loopCompletionR->isChecked()) - stopCondition = SchedulerJob::FINISH_LOOP; + stopCondition = FINISH_LOOP; double altConstraint = SchedulerJob::UNDEFINED_ALTITUDE; if (altConstraintCheck->isChecked()) @@ -1320,32 +1091,30 @@ // The reason for this kitchen-sink function is to separate the UI from the // job setup, to allow for testing. - setupJob( - *job, nameEdit->text(), groupEdit->text(), ra, dec, - KStarsData::Instance()->ut().djd(), - positionAngleSpin->value(), sequenceURL, fitsURL, - - startCondition, startupTimeEdit->dateTime(), - stopCondition, completionTimeEdit->dateTime(), repeatsSpin->value(), - - altConstraint, - moonConstraint, - weatherCheck->isChecked(), - twilightCheck->isChecked(), - artificialHorizonCheck->isChecked(), - - trackStepCheck->isChecked(), - focusStepCheck->isChecked(), - alignStepCheck->isChecked(), - guideStepCheck->isChecked() - ); + process()->setupJob(*job, nameEdit->text(), groupEdit->text(), ra, dec, + KStarsData::Instance()->ut().djd(), + positionAngleSpin->value(), sequenceURL, fitsURL, + + startCondition, startupTimeEdit->dateTime(), + stopCondition, completionTimeEdit->dateTime(), repeatsSpin->value(), + + altConstraint, + moonConstraint, + weatherCheck->isChecked(), + twilightCheck->isChecked(), + artificialHorizonCheck->isChecked(), + + trackStepCheck->isChecked(), + focusStepCheck->isChecked(), + alignStepCheck->isChecked(), + guideStepCheck->isChecked()); /* Verifications */ // Warn user if a duplicated job is in the list - same target, same sequence // FIXME: Those duplicated jobs are not necessarily processed in the order they appear in the list! int numWarnings = 0; - foreach (SchedulerJob *a_job, jobs) + foreach (SchedulerJob *a_job, moduleState()->jobs()) { if (a_job == job) { @@ -1426,7 +1195,7 @@ watchJobChanges(true); - if (SCHEDULER_LOADING != state) + if (SCHEDULER_LOADING != moduleState()->schedulerState()) { evaluateJobs(true); } @@ -1455,11 +1224,11 @@ switch (job->getFileStartupCondition()) { - case SchedulerJob::START_ASAP: + case START_ASAP: asapConditionR->setChecked(true); break; - case SchedulerJob::START_AT: + case START_AT: startupTimeConditionR->setChecked(true); startupTimeEdit->setDateTime(job->getStartupTime()); break; @@ -1499,20 +1268,20 @@ switch (job->getCompletionCondition()) { - case SchedulerJob::FINISH_SEQUENCE: + case FINISH_SEQUENCE: sequenceCompletionR->setChecked(true); break; - case SchedulerJob::FINISH_REPEAT: + case FINISH_REPEAT: repeatCompletionR->setChecked(true); repeatsSpin->setValue(job->getRepeatsRequired()); break; - case SchedulerJob::FINISH_LOOP: + case FINISH_LOOP: loopCompletionR->setChecked(true); break; - case SchedulerJob::FINISH_AT: + case FINISH_AT: timeCompletionR->setChecked(true); completionTimeEdit->setDateTime(job->getCompletionTime()); break; @@ -1523,13 +1292,39 @@ setJobManipulation(true, true); } +void Scheduler::syncGUIToGeneralSettings() +{ + parkDomeCheck->setChecked(Options::schedulerParkDome()); + parkMountCheck->setChecked(Options::schedulerParkMount()); + capCheck->setChecked(Options::schedulerCloseDustCover()); + warmCCDCheck->setChecked(Options::schedulerWarmCCD()); + unparkDomeCheck->setChecked(Options::schedulerUnparkDome()); + unparkMountCheck->setChecked(Options::schedulerUnparkMount()); + uncapCheck->setChecked(Options::schedulerOpenDustCover()); + setErrorHandlingStrategy(static_cast(Options::errorHandlingStrategy())); + errorHandlingDelaySB->setValue(Options::errorHandlingStrategyDelay()); + errorHandlingRescheduleErrorsCB->setChecked(Options::rescheduleErrors()); + startupScript->setText(moduleState()->startupScriptURL().toString(QUrl::PreferLocalFile)); + shutdownScript->setText(moduleState()->shutdownScriptURL().toString(QUrl::PreferLocalFile)); + + if (process()->captureInterface() != nullptr) + { + QVariant hasCoolerControl = process()->captureInterface()->property("coolerControl"); + if (hasCoolerControl.isValid()) + { + warmCCDCheck->setEnabled(hasCoolerControl.toBool()); + moduleState()->setCaptureReady(true); + } + } +} + void Scheduler::updateNightTime(SchedulerJob const *job) { if (job == nullptr) { int const currentRow = queueTable->currentRow(); if (0 < currentRow) - job = jobs.at(currentRow); + job = moduleState()->jobs().at(currentRow); } QDateTime const dawn = job ? job->getDawnAstronomicalTwilight() : Dawn; @@ -1544,13 +1339,13 @@ if (jobUnderEdit == i.row()) return; - if (state == SCHEDULER_RUNNING) + if (moduleState()->schedulerState() == SCHEDULER_RUNNING) { appendLogText(i18n("Warning: you cannot add or modify a job while the scheduler is running.")); return; } - SchedulerJob * const job = jobs.at(i.row()); + SchedulerJob * const job = moduleState()->jobs().at(i.row()); if (job == nullptr) return; @@ -1583,13 +1378,13 @@ Q_UNUSED(previous) // prevent selection when not idle - if (state != SCHEDULER_IDLE) + if (moduleState()->schedulerState() != SCHEDULER_IDLE) return; - if (current.row() < 0 || (current.row() + 1) > jobs.size()) + if (current.row() < 0 || (current.row() + 1) > moduleState()->jobs().size()) return; - SchedulerJob * const job = jobs.at(current.row()); + SchedulerJob * const job = moduleState()->jobs().at(current.row()); if (job != nullptr) { @@ -1624,7 +1419,7 @@ void Scheduler::setJobManipulation(bool can_reorder, bool can_delete) { - bool can_edit = (state == SCHEDULER_IDLE); + bool can_edit = (moduleState()->schedulerState() == SCHEDULER_IDLE); if (can_reorder) { @@ -1644,26 +1439,26 @@ bool Scheduler::reorderJobs(QList reordered_sublist) { /* Add jobs not reordered at the end of the list, in initial order */ - foreach (SchedulerJob* job, jobs) + foreach (SchedulerJob* job, moduleState()->jobs()) if (!reordered_sublist.contains(job)) reordered_sublist.append(job); - if (jobs != reordered_sublist) + if (moduleState()->jobs() != reordered_sublist) { /* Remember job currently selected */ int const selectedRow = queueTable->currentRow(); - SchedulerJob * const selectedJob = 0 <= selectedRow ? jobs.at(selectedRow) : nullptr; + SchedulerJob * const selectedJob = 0 <= selectedRow ? moduleState()->jobs().at(selectedRow) : nullptr; /* Reassign list */ - jobs = reordered_sublist; + moduleState()->setJobs(reordered_sublist); /* Reassign status cells for all jobs, and reset them */ - for (int row = 0; row < jobs.size(); row++) + for (int row = 0; row < moduleState()->jobs().size(); row++) setJobStatusCells(row); /* Reselect previously selected job */ if (nullptr != selectedJob) - queueTable->selectRow(jobs.indexOf(selectedJob)); + queueTable->selectRow(moduleState()->jobs().indexOf(selectedJob)); return true; } @@ -1682,9 +1477,9 @@ /* Swap jobs in the list */ #if QT_VERSION >= QT_VERSION_CHECK(5,13,0) - jobs.swapItemsAt(currentRow, destinationRow); + moduleState()->mutlableJobs().swapItemsAt(currentRow, destinationRow); #else - jobs.swap(currentRow, destinationRow); + moduleState()->jobs().swap(currentRow, destinationRow); #endif /* Reassign status cells */ @@ -1696,11 +1491,11 @@ setJobManipulation(true, true); /* Jobs are now sorted, so reset all later jobs */ - for (int row = destinationRow; row < jobs.size(); row++) - jobs.at(row)->reset(); + for (int row = destinationRow; row < moduleState()->jobs().size(); row++) + moduleState()->jobs().at(row)->reset(); /* Make list modified and evaluate jobs */ - mDirty = true; + moduleState()->setDirty(true); evaluateJobs(true); } @@ -1716,9 +1511,9 @@ /* Swap jobs in the list */ #if QT_VERSION >= QT_VERSION_CHECK(5,13,0) - jobs.swapItemsAt(currentRow, destinationRow); + moduleState()->mutlableJobs().swapItemsAt(currentRow, destinationRow); #else - jobs.swap(currentRow, destinationRow); + moduleState()->mutlableJobs().swap(currentRow, destinationRow); #endif /* Reassign status cells */ @@ -1730,26 +1525,26 @@ setJobManipulation(true, true); /* Jobs are now sorted, so reset all later jobs */ - for (int row = currentRow; row < jobs.size(); row++) - jobs.at(row)->reset(); + for (int row = currentRow; row < moduleState()->jobs().size(); row++) + moduleState()->jobs().at(row)->reset(); /* Make list modified and evaluate jobs */ - mDirty = true; + moduleState()->setDirty(true); evaluateJobs(true); } void Scheduler::updateTable() { - foreach (SchedulerJob* job, jobs) + foreach (SchedulerJob* job, moduleState()->jobs()) job->updateJobCells(); } void Scheduler::setJobStatusCells(int row) { - if (row < 0 || jobs.size() <= row) + if (row < 0 || moduleState()->jobs().size() <= row) return; - SchedulerJob * const job = jobs.at(row); + SchedulerJob * const job = moduleState()->jobs().at(row); job->setNameCell(queueTable->item(row, static_cast(SCHEDCOL_NAME))); job->setStatusCell(queueTable->item(row, static_cast(SCHEDCOL_STATUS))); @@ -1766,7 +1561,7 @@ if (jobUnderEdit < 0) return; - SchedulerJob * const job = jobs.at(jobUnderEdit); + SchedulerJob * const job = moduleState()->jobs().at(jobUnderEdit); Q_ASSERT_X(job != nullptr, __FUNCTION__, "Edited job must be valid"); qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Job '%1' at row #%2 is not longer edited.").arg(job->getName()).arg( @@ -1798,7 +1593,7 @@ return; /* Grab the job currently selected */ - SchedulerJob * const job = jobs.at(currentRow); + SchedulerJob * const job = moduleState()->jobs().at(currentRow); qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Job '%1' at row #%2 is being deleted.").arg(job->getName()).arg(currentRow + 1); /* Remove the job from the table */ @@ -1830,10 +1625,10 @@ resetJobEdit(); /* And remove the job object */ - jobs.removeOne(job); + moduleState()->mutlableJobs().removeOne(job); delete (job); - mDirty = true; + moduleState()->setDirty(true); evaluateJobs(true); emit jobsUpdated(getJSONJobs()); updateTable(); @@ -1846,9 +1641,9 @@ } void Scheduler::toggleScheduler() { - if (state == SCHEDULER_RUNNING) + if (moduleState()->schedulerState() == SCHEDULER_RUNNING) { - disablePreemptiveShutdown(); + moduleState()->disablePreemptiveShutdown(); stop(); } else @@ -1857,19 +1652,19 @@ void Scheduler::stop() { - if (state != SCHEDULER_RUNNING) + if (moduleState()->schedulerState() != SCHEDULER_RUNNING) return; qCInfo(KSTARS_EKOS_SCHEDULER) << "Scheduler is stopping..."; // Stop running job and abort all others // in case of soft shutdown we skip this - if (!preemptiveShutdown()) + if (!moduleState()->preemptiveShutdown()) { bool wasAborted = false; - for (auto &oneJob : jobs) + for (auto &oneJob : moduleState()->jobs()) { - if (oneJob == currentJob) + if (oneJob == activeJob()) stopCurrentJobAction(); if (oneJob->getState() <= SchedulerJob::JOB_BUSY) @@ -1886,81 +1681,74 @@ } TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_NOTHING).toLatin1().data()); - setupNextIteration(RUN_NOTHING); - cancelGuidingTimer(); + moduleState()->setupNextIteration(RUN_NOTHING); + moduleState()->cancelGuidingTimer(); - state = SCHEDULER_IDLE; - emit newStatus(state); - setEkosState(EKOS_IDLE); - setIndiState(INDI_IDLE); + moduleState()->setSchedulerState(SCHEDULER_IDLE); + emit newStatus(moduleState()->schedulerState()); + moduleState()->setEkosState(EKOS_IDLE); + moduleState()->setIndiState(INDI_IDLE); - setParkWaitState(PARKWAIT_IDLE); + moduleState()->setParkWaitState(PARKWAIT_IDLE); // Only reset startup state to idle if the startup procedure was interrupted before it had the chance to complete. // Or if we're doing a soft shutdown - if (startupState != STARTUP_COMPLETE || preemptiveShutdown()) + if (moduleState()->startupState() != STARTUP_COMPLETE || moduleState()->preemptiveShutdown()) { - if (startupState == STARTUP_SCRIPT) + if (moduleState()->startupState() == STARTUP_SCRIPT) { - scriptProcess.disconnect(); - scriptProcess.terminate(); + process()->scriptProcess().disconnect(); + process()->scriptProcess().terminate(); } - setStartupState(STARTUP_IDLE); + moduleState()->setStartupState(STARTUP_IDLE); } // Reset startup state to unparking phase (dome -> mount -> cap) // We do not want to run the startup script again but unparking should be checked // whenever the scheduler is running again. - else if (startupState == STARTUP_COMPLETE) + else if (moduleState()->startupState() == STARTUP_COMPLETE) { if (unparkDomeCheck->isChecked()) - setStartupState(STARTUP_UNPARK_DOME); + moduleState()->setStartupState(STARTUP_UNPARK_DOME); else if (unparkMountCheck->isChecked()) - setStartupState(STARTUP_UNPARK_MOUNT); + moduleState()->setStartupState(STARTUP_UNPARK_MOUNT); else if (uncapCheck->isChecked()) - setStartupState(STARTUP_UNPARK_CAP); + moduleState()->setStartupState(STARTUP_UNPARK_CAP); } - setShutdownState(SHUTDOWN_IDLE); + moduleState()->setShutdownState(SHUTDOWN_IDLE); setCurrentJob(nullptr); - captureBatch = 0; - indiConnectFailureCount = 0; - ekosConnectFailureCount = 0; - focusFailureCount = 0; - guideFailureCount = 0; - alignFailureCount = 0; - captureFailureCount = 0; - loadAndSlewProgress = false; - autofocusCompleted = false; + moduleState()->resetFailureCounters(); + moduleState()->setAutofocusCompleted(false); startupB->setEnabled(true); shutdownB->setEnabled(true); // If soft shutdown, we return for now - if (preemptiveShutdown()) + if (moduleState()->preemptiveShutdown()) { sleepLabel->setToolTip(i18n("Scheduler is in shutdown until next job is ready")); sleepLabel->show(); - QDateTime const now = getLocalTime(); - int const nextObservationTime = now.secsTo(getPreemptiveShutdownWakeupTime()); - setupNextIteration(RUN_WAKEUP, - std::lround(((nextObservationTime + 1) * 1000) - / KStarsData::Instance()->clock()->scale())); + QDateTime const now = SchedulerModuleState::getLocalTime(); + int const nextObservationTime = now.secsTo(moduleState()->preemptiveShutdownWakeupTime()); + moduleState()->setupNextIteration(RUN_WAKEUP, + std::lround(((nextObservationTime + 1) * 1000) + / KStarsData::Instance()->clock()->scale())); return; } // Clear target name in capture interface upon stopping - if (captureInterface.isNull() == false) + if (process()->captureInterface().isNull() == false) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:setProperty", "targetName=\"\""); - captureInterface->setProperty("targetName", QString()); + process()->captureInterface()->setProperty("targetName", QString()); } - if (scriptProcess.state() == QProcess::Running) - scriptProcess.terminate(); + if (process()->scriptProcess().state() == QProcess::Running) + process()->scriptProcess().terminate(); sleepLabel->hide(); pi->stopAnimation(); @@ -1980,22 +1768,22 @@ void Scheduler::execute() { - switch (state) + switch (moduleState()->schedulerState()) { case SCHEDULER_IDLE: /* FIXME: Manage the non-validity of the startup script earlier, and make it a warning only when the scheduler starts */ - startupScriptURL = QUrl::fromUserInput(startupScript->text()); - if (!startupScript->text().isEmpty() && !startupScriptURL.isValid()) + if (!moduleState()->startupScriptURL().isEmpty() && ! moduleState()->startupScriptURL().isValid()) { - appendLogText(i18n("Warning: startup script URL %1 is not valid.", startupScript->text())); + appendLogText(i18n("Warning: startup script URL %1 is not valid.", + moduleState()->startupScriptURL().toString(QUrl::PreferLocalFile))); return; } /* FIXME: Manage the non-validity of the shutdown script earlier, and make it a warning only when the scheduler starts */ - shutdownScriptURL = QUrl::fromUserInput(shutdownScript->text()); - if (!shutdownScript->text().isEmpty() && !shutdownScriptURL.isValid()) + if (!moduleState()->shutdownScriptURL().isEmpty() && !moduleState()->shutdownScriptURL().isValid()) { - appendLogText(i18n("Warning: shutdown script URL %1 is not valid.", shutdownScript->text())); + appendLogText(i18n("Warning: shutdown script URL %1 is not valid.", + moduleState()->shutdownScriptURL().toString(QUrl::PreferLocalFile))); return; } @@ -2019,10 +1807,10 @@ startupB->setEnabled(false); shutdownB->setEnabled(false); - state = SCHEDULER_RUNNING; - emit newStatus(state); + moduleState()->setSchedulerState(SCHEDULER_RUNNING); + emit newStatus(moduleState()->schedulerState()); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); appendLogText(i18n("Scheduler started.")); qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler started."; @@ -2039,10 +1827,10 @@ /* Edit-related buttons are still disabled */ /* The end-user cannot update the schedule, don't re-evaluate jobs. Timer schedulerTimer is already running. */ - state = SCHEDULER_RUNNING; - emit newStatus(state); + moduleState()->setSchedulerState(SCHEDULER_RUNNING); + emit newStatus(moduleState()->schedulerState()); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); appendLogText(i18n("Scheduler resuming.")); qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler resuming."; @@ -2055,8 +1843,8 @@ void Scheduler::pause() { - state = SCHEDULER_PAUSED; - emit newStatus(state); + moduleState()->setSchedulerState(SCHEDULER_PAUSED); + emit newStatus(moduleState()->schedulerState()); appendLogText(i18n("Scheduler pause planned...")); pauseB->setEnabled(false); @@ -2069,26 +1857,26 @@ pauseB->setCheckable(true); pauseB->setChecked(true); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_NOTHING).toLatin1().data()); - setupNextIteration(RUN_NOTHING); + moduleState()->setupNextIteration(RUN_NOTHING); appendLogText(i18n("Scheduler paused.")); } void Scheduler::setCurrentJob(SchedulerJob *job) { /* Reset job widgets */ - if (currentJob) + if (activeJob()) { - currentJob->setStageLabel(nullptr); + activeJob()->setStageLabel(nullptr); } /* Set current job */ - currentJob = job; + moduleState()->setActiveJob(job); /* Reassign job widgets, or reset to defaults */ - if (currentJob) + if (activeJob()) { - currentJob->setStageLabel(jobStatus); - queueTable->selectRow(jobs.indexOf(currentJob)); + activeJob()->setStageLabel(jobStatus); + queueTable->selectRow(moduleState()->jobs().indexOf(activeJob())); } else { @@ -2109,11 +1897,11 @@ void Scheduler::evaluateJobs(bool evaluateOnly) { - for (auto job : jobs) + for (auto job : moduleState()->jobs()) job->clearCache(); /* Don't evaluate if list is empty */ - if (jobs.isEmpty()) + if (moduleState()->jobs().isEmpty()) return; /* Start by refreshing the number of captures already present - unneeded if not remembering job progress */ if (Options::rememberJobProgress()) @@ -2124,7 +1912,9 @@ QList jobsToProcess; syncGreedyParams(); - jobsToProcess = m_GreedyScheduler->scheduleJobs(jobs, getLocalTime(), m_CapturedFramesCount, this); + jobsToProcess = m_GreedyScheduler->scheduleJobs(moduleState()->jobs(), SchedulerModuleState::getLocalTime(), + moduleState()->capturedFramesCount(), + this); processJobs(jobsToProcess, evaluateOnly); emit jobsUpdated(getJSONJobs()); } @@ -2132,9 +1922,9 @@ void Scheduler::processJobs(QList sortedJobs, bool jobEvaluationOnly) { /* Apply sorting to queue table, and mark it for saving if it changes */ - mDirty = reorderJobs(sortedJobs) | mDirty; + moduleState()->setDirty(reorderJobs(sortedJobs) || moduleState()->dirty()); - if (jobEvaluationOnly || state != SCHEDULER_RUNNING) + if (jobEvaluationOnly || moduleState()->schedulerState() != SCHEDULER_RUNNING) { qCInfo(KSTARS_EKOS_SCHEDULER) << "Ekos finished evaluating jobs, no job selection required."; return; @@ -2193,21 +1983,21 @@ { sleepLabel->hide(); - if (preemptiveShutdown()) + if (moduleState()->preemptiveShutdown()) { - disablePreemptiveShutdown(); + moduleState()->disablePreemptiveShutdown(); appendLogText(i18n("Scheduler is awake.")); execute(); } else { - if (state == SCHEDULER_RUNNING) + if (moduleState()->schedulerState() == SCHEDULER_RUNNING) appendLogText(i18n("Scheduler is awake. Jobs shall be started when ready...")); else appendLogText(i18n("Scheduler is awake. Jobs shall be started when scheduler is resumed.")); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } } @@ -2225,34 +2015,34 @@ return false; // Don't execute the current job if it is already busy - if (currentJob == job && SchedulerJob::JOB_BUSY == currentJob->getState()) + if (activeJob() == job && SchedulerJob::JOB_BUSY == activeJob()->getState()) return false; setCurrentJob(job); - int index = jobs.indexOf(job); + int index = moduleState()->jobs().indexOf(job); if (index >= 0) queueTable->selectRow(index); // If we already started, we check when the next object is scheduled at. // If it is more than 30 minutes in the future, we park the mount if that is supported // and we unpark when it is due to start. - //int const nextObservationTime = now.secsTo(currentJob->getStartupTime()); + //int const nextObservationTime = now.secsTo(getActiveJob()->getStartupTime()); // If the time to wait is greater than the lead time (5 minutes by default) // then we sleep, otherwise we wait. It's the same thing, just different labels. - if (shouldSchedulerSleep(currentJob)) + if (shouldSchedulerSleep(activeJob())) return false; // If job schedule isn't now, wait - continuing to execute would cancel a parking attempt - else if (0 < getLocalTime().secsTo(currentJob->getStartupTime())) + else if (0 < SchedulerModuleState::getLocalTime().secsTo(activeJob()->getStartupTime())) return false; // From this point job can be executed now - if (job->getCompletionCondition() == SchedulerJob::FINISH_SEQUENCE && Options::rememberJobProgress()) + if (job->getCompletionCondition() == FINISH_SEQUENCE && Options::rememberJobProgress()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s%s\n", __LINE__, "captureInterface:setProperty", "targetName=", job->getName().toLatin1().data()); - captureInterface->setProperty("targetName", job->getName()); + process()->captureInterface()->setProperty("targetName", job->getName()); } calculateDawnDusk(); @@ -2260,674 +2050,61 @@ // Reset autofocus so that focus step is applied properly when checked // When the focus step is not checked, the capture module will eventually run focus periodically - autofocusCompleted = false; + moduleState()->setAutofocusCompleted(false); - qCInfo(KSTARS_EKOS_SCHEDULER) << "Executing Job " << currentJob->getName(); + qCInfo(KSTARS_EKOS_SCHEDULER) << "Executing Job " << activeJob()->getName(); - currentJob->setState(SchedulerJob::JOB_BUSY); + activeJob()->setState(SchedulerJob::JOB_BUSY); emit jobsUpdated(getJSONJobs()); KSNotification::event(QLatin1String("EkosSchedulerJobStart"), - i18n("Ekos job started (%1)", currentJob->getName()), KSNotification::Scheduler); + i18n("Ekos job started (%1)", activeJob()->getName()), KSNotification::Scheduler); // No need to continue evaluating jobs as we already have one. TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_JOBCHECK).toLatin1().data()); - setupNextIteration(RUN_JOBCHECK); + moduleState()->setupNextIteration(RUN_JOBCHECK); return true; } -bool Scheduler::checkEkosState() -{ - if (state == SCHEDULER_PAUSED) - return false; - - switch (ekosState) - { - case EKOS_IDLE: - { - if (m_EkosCommunicationStatus == Ekos::Success) - { - setEkosState(EKOS_READY); - return true; - } - else - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "start"); - ekosInterface->call(QDBus::AutoDetect, "start"); - setEkosState(EKOS_STARTING); - startCurrentOperationTimer(); - - qCInfo(KSTARS_EKOS_SCHEDULER) << "Ekos communication status is" << m_EkosCommunicationStatus << "Starting Ekos..."; - - return false; - } - } - - case EKOS_STARTING: - { - if (m_EkosCommunicationStatus == Ekos::Success) - { - appendLogText(i18n("Ekos started.")); - ekosConnectFailureCount = 0; - setEkosState(EKOS_READY); - return true; - } - else if (m_EkosCommunicationStatus == Ekos::Error) - { - if (ekosConnectFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Starting Ekos failed. Retrying...")); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "start"); - ekosInterface->call(QDBus::AutoDetect, "start"); - return false; - } - - appendLogText(i18n("Starting Ekos failed.")); - stop(); - return false; - } - else if (m_EkosCommunicationStatus == Ekos::Idle) - return false; - // If a minute passed, give up - else if (getCurrentOperationMsec() > (60 * 1000)) - { - if (ekosConnectFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Starting Ekos timed out. Retrying...")); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "stop"); - ekosInterface->call(QDBus::AutoDetect, "stop"); - QTimer::singleShot(1000, this, [&]() - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "start"); - ekosInterface->call(QDBus::AutoDetect, "start"); - startCurrentOperationTimer(); - }); - return false; - } - - appendLogText(i18n("Starting Ekos timed out.")); - stop(); - return false; - } - } - break; - - case EKOS_STOPPING: - { - if (m_EkosCommunicationStatus == Ekos::Idle) - { - appendLogText(i18n("Ekos stopped.")); - setEkosState(EKOS_IDLE); - return true; - } - } - break; - - case EKOS_READY: - return true; - } - return false; -} - -bool Scheduler::isINDIConnected() -{ - return (m_INDICommunicationStatus == Ekos::Success); -} - -bool Scheduler::checkINDIState() -{ - if (state == SCHEDULER_PAUSED) - return false; - - //qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking INDI State" << indiState; - - switch (indiState) - { - case INDI_IDLE: - { - if (m_INDICommunicationStatus == Ekos::Success) - { - setIndiState(INDI_PROPERTY_CHECK); - indiConnectFailureCount = 0; - qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking INDI Properties..."; - } - else - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Connecting INDI devices..."; - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "connectDevices"); - ekosInterface->call(QDBus::AutoDetect, "connectDevices"); - setIndiState(INDI_CONNECTING); - - startCurrentOperationTimer(); - } - } - break; - - case INDI_CONNECTING: - { - if (m_INDICommunicationStatus == Ekos::Success) - { - appendLogText(i18n("INDI devices connected.")); - setIndiState(INDI_PROPERTY_CHECK); - } - else if (m_INDICommunicationStatus == Ekos::Error) - { - if (indiConnectFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("One or more INDI devices failed to connect. Retrying...")); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "connectDevices"); - ekosInterface->call(QDBus::AutoDetect, "connectDevices"); - } - else - { - appendLogText(i18n("One or more INDI devices failed to connect. Check INDI control panel for details.")); - stop(); - } - } - // If 30 seconds passed, we retry - else if (getCurrentOperationMsec() > (30 * 1000)) - { - if (indiConnectFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("One or more INDI devices timed out. Retrying...")); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "ekosInterface", "connectDevices"); - ekosInterface->call(QDBus::AutoDetect, "connectDevices"); - startCurrentOperationTimer(); - } - else - { - appendLogText(i18n("One or more INDI devices timed out. Check INDI control panel for details.")); - stop(); - } - } - } - break; - - case INDI_DISCONNECTING: - { - if (m_INDICommunicationStatus == Ekos::Idle) - { - appendLogText(i18n("INDI devices disconnected.")); - setIndiState(INDI_IDLE); - return true; - } - } - break; - - case INDI_PROPERTY_CHECK: - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking INDI properties."; - // If dome unparking is required then we wait for dome interface - if (unparkDomeCheck->isChecked() && m_DomeReady == false) - { - if (getCurrentOperationMsec() > (30 * 1000)) - { - startCurrentOperationTimer(); - appendLogText(i18n("Warning: dome device not ready after timeout, attempting to recover...")); - disconnectINDI(); - stopEkos(); - } - - appendLogText(i18n("Dome unpark required but dome is not yet ready.")); - return false; - } - - // If mount unparking is required then we wait for mount interface - if (unparkMountCheck->isChecked() && m_MountReady == false) - { - if (getCurrentOperationMsec() > (30 * 1000)) - { - startCurrentOperationTimer(); - appendLogText(i18n("Warning: mount device not ready after timeout, attempting to recover...")); - disconnectINDI(); - stopEkos(); - } - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount unpark required but mount is not yet ready."; - return false; - } - - // If cap unparking is required then we wait for cap interface - if (uncapCheck->isChecked() && m_CapReady == false) - { - if (getCurrentOperationMsec() > (30 * 1000)) - { - startCurrentOperationTimer(); - appendLogText(i18n("Warning: cap device not ready after timeout, attempting to recover...")); - disconnectINDI(); - stopEkos(); - } - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Cap unpark required but cap is not yet ready."; - return false; - } - - // capture interface is required at all times to proceed. - if (captureInterface.isNull()) - return false; - - if (m_CaptureReady == false) - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:property", "coolerControl"); - QVariant hasCoolerControl = captureInterface->property("coolerControl"); - TEST_PRINT(stderr, " @@@dbus received %s\n", - !hasCoolerControl.isValid() ? "invalid" : (hasCoolerControl.toBool() ? "T" : "F")); - if (hasCoolerControl.isValid()) - { - warmCCDCheck->setEnabled(hasCoolerControl.toBool()); - m_CaptureReady = true; - } - else - qCWarning(KSTARS_EKOS_SCHEDULER) << "Capture module is not ready yet..."; - } - - setIndiState(INDI_READY); - indiConnectFailureCount = 0; - return true; - } - - case INDI_READY: - return true; - } - - return false; -} - -bool Scheduler::checkStartupState() -{ - if (state == SCHEDULER_PAUSED) - return false; - - qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Checking Startup State (%1)...").arg(startupState); - - switch (startupState) - { - case STARTUP_IDLE: - { - KSNotification::event(QLatin1String("ObservatoryStartup"), i18n("Observatory is in the startup process"), - KSNotification::Scheduler); - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Startup Idle. Starting startup process..."; - - // If Ekos is already started, we skip the script and move on to dome unpark step - // unless we do not have light frames, then we skip all - //QDBusReply isEkosStarted; - //isEkosStarted = ekosInterface->call(QDBus::AutoDetect, "getEkosStartingStatus"); - //if (isEkosStarted.value() == Ekos::Success) - if (m_EkosCommunicationStatus == Ekos::Success) - { - if (startupScriptURL.isEmpty() == false) - appendLogText(i18n("Ekos is already started, skipping startup script...")); - - if (!currentJob || currentJob->getLightFramesRequired()) - setStartupState(STARTUP_UNPARK_DOME); - else - setStartupState(STARTUP_COMPLETE); - return true; - } - - if (schedulerProfileCombo->currentText() != i18n("Default")) - { - QList profile; - profile.append(schedulerProfileCombo->currentText()); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "ekosInterface:callWithArgs", "setProfile"); - ekosInterface->callWithArgumentList(QDBus::AutoDetect, "setProfile", profile); - } - - if (startupScriptURL.isEmpty() == false) - { - setStartupState(STARTUP_SCRIPT); - executeScript(startupScriptURL.toString(QUrl::PreferLocalFile)); - return false; - } - - setStartupState(STARTUP_UNPARK_DOME); - return false; - } - - case STARTUP_SCRIPT: - return false; - - case STARTUP_UNPARK_DOME: - // If there is no job in case of manual startup procedure, - // or if the job requires light frames, let's proceed with - // unparking the dome, otherwise startup process is complete. - if (currentJob == nullptr || currentJob->getLightFramesRequired()) - { - if (unparkDomeCheck->isEnabled() && unparkDomeCheck->isChecked()) - unParkDome(); - else - setStartupState(STARTUP_UNPARK_MOUNT); - } - else - { - setStartupState(STARTUP_COMPLETE); - return true; - } - - break; - - case STARTUP_UNPARKING_DOME: - checkDomeParkingStatus(); - break; - - case STARTUP_UNPARK_MOUNT: - if (unparkMountCheck->isEnabled() && unparkMountCheck->isChecked()) - unParkMount(); - else - setStartupState(STARTUP_UNPARK_CAP); - break; - - case STARTUP_UNPARKING_MOUNT: - checkMountParkingStatus(); - break; - - case STARTUP_UNPARK_CAP: - if (uncapCheck->isEnabled() && uncapCheck->isChecked()) - unParkCap(); - else - setStartupState(STARTUP_COMPLETE); - break; - - case STARTUP_UNPARKING_CAP: - checkCapParkingStatus(); - break; - - case STARTUP_COMPLETE: - return true; - - case STARTUP_ERROR: - stop(); - return true; - } - - return false; -} - bool Scheduler::checkShutdownState() { - if (state == SCHEDULER_PAUSED) - return false; - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking shutdown state..."; - - switch (shutdownState) - { - case SHUTDOWN_IDLE: - KSNotification::event(QLatin1String("ObservatoryShutdown"), i18n("Observatory is in the shutdown process"), - KSNotification::Scheduler); - - qCInfo(KSTARS_EKOS_SCHEDULER) << "Starting shutdown process..."; - - // weatherTimer.stop(); - // weatherTimer.disconnect(); - weatherLabel->hide(); - - setCurrentJob(nullptr); - - TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SHUTDOWN).toLatin1().data()); - setupNextIteration(RUN_SHUTDOWN); - - if (warmCCDCheck->isEnabled() && warmCCDCheck->isChecked()) - { - appendLogText(i18n("Warming up CCD...")); - - // Turn it off - //QVariant arg(false); - //captureInterface->call(QDBus::AutoDetect, "setCoolerControl", arg); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s%s\n", __LINE__, "captureInterface:setProperty", "coolerControl=", "false"); - captureInterface->setProperty("coolerControl", false); - } - - // The following steps require a connection to the INDI server - if (isINDIConnected()) - { - if (capCheck->isEnabled() && capCheck->isChecked()) - { - setShutdownState(SHUTDOWN_PARK_CAP); - return false; - } - - if (parkMountCheck->isEnabled() && parkMountCheck->isChecked()) - { - setShutdownState(SHUTDOWN_PARK_MOUNT); - return false; - } - - if (parkDomeCheck->isEnabled() && parkDomeCheck->isChecked()) - { - setShutdownState(SHUTDOWN_PARK_DOME); - return false; - } - } - else appendLogText(i18n("Warning: Bypassing parking procedures, no INDI connection.")); - - if (shutdownScriptURL.isEmpty() == false) - { - setShutdownState(SHUTDOWN_SCRIPT); - return false; - } - - setShutdownState(SHUTDOWN_COMPLETE); - return true; - - case SHUTDOWN_PARK_CAP: - if (!isINDIConnected()) - { - qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; - setShutdownState(SHUTDOWN_SCRIPT); - } - else if (capCheck->isEnabled() && capCheck->isChecked()) - parkCap(); - else - setShutdownState(SHUTDOWN_PARK_MOUNT); - break; - - case SHUTDOWN_PARKING_CAP: - checkCapParkingStatus(); - break; - - case SHUTDOWN_PARK_MOUNT: - if (!isINDIConnected()) - { - qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; - setShutdownState(SHUTDOWN_SCRIPT); - } - else if (parkMountCheck->isEnabled() && parkMountCheck->isChecked()) - parkMount(); - else - setShutdownState(SHUTDOWN_PARK_DOME); - break; - - case SHUTDOWN_PARKING_MOUNT: - checkMountParkingStatus(); - break; - - case SHUTDOWN_PARK_DOME: - if (!isINDIConnected()) - { - qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; - setShutdownState(SHUTDOWN_SCRIPT); - } - else if (parkDomeCheck->isEnabled() && parkDomeCheck->isChecked()) - parkDome(); - else - setShutdownState(SHUTDOWN_SCRIPT); - break; - - case SHUTDOWN_PARKING_DOME: - checkDomeParkingStatus(); - break; - - case SHUTDOWN_SCRIPT: - if (shutdownScriptURL.isEmpty() == false) - { - // Need to stop Ekos now before executing script if it happens to stop INDI - if (ekosState != EKOS_IDLE && Options::shutdownScriptTerminatesINDI()) - { - stopEkos(); - return false; - } - - setShutdownState(SHUTDOWN_SCRIPT_RUNNING); - executeScript(shutdownScriptURL.toString(QUrl::PreferLocalFile)); - } - else - setShutdownState(SHUTDOWN_COMPLETE); - break; - - case SHUTDOWN_SCRIPT_RUNNING: - return false; - - case SHUTDOWN_COMPLETE: - return completeShutdown(); - - case SHUTDOWN_ERROR: - stop(); - return true; - } - - return false; -} - -bool Scheduler::checkParkWaitState() -{ - if (state == SCHEDULER_PAUSED) + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) return false; - if (parkWaitState == PARKWAIT_IDLE) - return true; - - // qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking Park Wait State..."; - - switch (parkWaitState) - { - case PARKWAIT_PARK: - parkMount(); - break; - - case PARKWAIT_PARKING: - checkMountParkingStatus(); - break; - - case PARKWAIT_UNPARK: - unParkMount(); - break; - - case PARKWAIT_UNPARKING: - checkMountParkingStatus(); - break; - - case PARKWAIT_IDLE: - case PARKWAIT_PARKED: - case PARKWAIT_UNPARKED: - return true; - - case PARKWAIT_ERROR: - appendLogText(i18n("park/unpark wait procedure failed, aborting...")); - stop(); - return true; - - } - - return false; -} - -void Scheduler::executeScript(const QString &filename) -{ - appendLogText(i18n("Executing script %1...", filename)); - - connect(&scriptProcess, &QProcess::readyReadStandardOutput, this, &Scheduler::readProcessOutput); - - connect(&scriptProcess, static_cast(&QProcess::finished), - this, [this](int exitCode, QProcess::ExitStatus) - { - checkProcessExit(exitCode); - }); - - QStringList arguments; - scriptProcess.start(filename, arguments); -} - -void Scheduler::readProcessOutput() -{ - appendLogText(scriptProcess.readAllStandardOutput().simplified()); -} - -void Scheduler::checkProcessExit(int exitCode) -{ - scriptProcess.disconnect(); - - if (exitCode == 0) + if (moduleState()->shutdownState() == SHUTDOWN_IDLE) { - if (startupState == STARTUP_SCRIPT) - setStartupState(STARTUP_UNPARK_DOME); - else if (shutdownState == SHUTDOWN_SCRIPT_RUNNING) - setShutdownState(SHUTDOWN_COMPLETE); + KSNotification::event(QLatin1String("ObservatoryShutdown"), i18n("Observatory is in the shutdown process"), + KSNotification::Scheduler); - return; - } + qCInfo(KSTARS_EKOS_SCHEDULER) << "Starting shutdown process..."; - if (startupState == STARTUP_SCRIPT) - { - appendLogText(i18n("Startup script failed, aborting...")); - setStartupState(STARTUP_ERROR); - } - else if (shutdownState == SHUTDOWN_SCRIPT_RUNNING) - { - appendLogText(i18n("Shutdown script failed, aborting...")); - setShutdownState(SHUTDOWN_ERROR); - } -} + // weatherTimer.stop(); + // weatherTimer.disconnect(); + weatherLabel->hide(); -bool Scheduler::completeShutdown() -{ - // If INDI is not done disconnecting, try again later - if (indiState == INDI_DISCONNECTING && checkINDIState() == false) - return false; + setCurrentJob(nullptr); - // Disconnect INDI if required first - if (indiState != INDI_IDLE && Options::stopEkosAfterShutdown()) - { - disconnectINDI(); - return false; - } + TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SHUTDOWN).toLatin1().data()); + moduleState()->setupNextIteration(RUN_SHUTDOWN); - // If Ekos is not done stopping, try again later - if (ekosState == EKOS_STOPPING && checkEkosState() == false) - return false; - - // Stop Ekos if required. - if (ekosState != EKOS_IDLE && Options::stopEkosAfterShutdown()) - { - stopEkos(); - return false; } - if (shutdownState == SHUTDOWN_COMPLETE) - appendLogText(i18n("Shutdown complete.")); - else - appendLogText(i18n("Shutdown procedure failed, aborting...")); - - // Stop Scheduler - stop(); - - return true; + return process()->checkShutdownState(); } bool Scheduler::checkStatus() { - for (auto job : jobs) + for (auto job : moduleState()->jobs()) job->updateJobCells(); - if (state == SCHEDULER_PAUSED) + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) { - if (currentJob == nullptr) + if (activeJob() == nullptr) { setPaused(); return false; } - switch (currentJob->getState()) + switch (activeJob()->getState()) { case SchedulerJob::JOB_BUSY: // do nothing @@ -2943,19 +2120,20 @@ } // #1 If no current job selected, let's check if we need to shutdown or evaluate jobs - if (currentJob == nullptr) + if (activeJob() == nullptr) { // #2.1 If shutdown is already complete or in error, we need to stop - if (shutdownState == SHUTDOWN_COMPLETE || shutdownState == SHUTDOWN_ERROR) + if (moduleState()->shutdownState() == SHUTDOWN_COMPLETE + || moduleState()->shutdownState() == SHUTDOWN_ERROR) { - return completeShutdown(); + return process()->completeShutdown(); } // #2.2 Check if shutdown is in progress - if (shutdownState > SHUTDOWN_IDLE) + if (moduleState()->shutdownState() > SHUTDOWN_IDLE) { // If Ekos is not done stopping, try again later - if (ekosState == EKOS_STOPPING && checkEkosState() == false) + if (moduleState()->ekosState() == EKOS_STOPPING && process()->checkEkosState() == false) return false; checkShutdownState(); @@ -2963,21 +2141,21 @@ } // #2.3 Check if park wait procedure is in progress - if (checkParkWaitState() == false) + if (process()->checkParkWaitState() == false) return false; // #2.4 If not in shutdown state, evaluate the jobs evaluateJobs(false); // #2.5 check if all jobs have completed and repeat is set - if (nullptr == currentJob && checkRepeatSequence()) + if (nullptr == activeJob() && checkRepeatSequence()) { // Reset all jobs resetJobs(); // Re-evaluate all jobs to check whether there is at least one that might be executed evaluateJobs(false); // if there is an executable job, restart; - if (currentJob) + if (activeJob()) { sequenceExecutionCounter++; appendLogText(i18n("Starting job sequence iteration #%1", sequenceExecutionCounter)); @@ -2986,17 +2164,17 @@ } // #2.6 If there is no current job after evaluation, shutdown - if (nullptr == currentJob) + if (nullptr == activeJob()) { checkShutdownState(); return false; } } // JM 2018-12-07: Check if we need to sleep - else if (shouldSchedulerSleep(currentJob) == false) + else if (shouldSchedulerSleep(activeJob()) == false) { // #3 Check if startup procedure has failed. - if (startupState == STARTUP_ERROR) + if (moduleState()->startupState() == STARTUP_ERROR) { // Stop Scheduler stop(); @@ -3004,33 +2182,37 @@ } // #4 Check if startup procedure Phase #1 is complete (Startup script) - if ((startupState == STARTUP_IDLE && checkStartupState() == false) || startupState == STARTUP_SCRIPT) + if ((moduleState()->startupState() == STARTUP_IDLE + && process()->checkStartupState() == false) + || moduleState()->startupState() == STARTUP_SCRIPT) return false; // #5 Check if Ekos is started - if (checkEkosState() == false) + if (process()->checkEkosState() == false) return false; // #6 Check if INDI devices are connected. - if (checkINDIState() == false) + if (process()->checkINDIState() == false) return false; // #6.1 Check if park wait procedure is in progress - in the case we're waiting for a distant job - if (checkParkWaitState() == false) + if (process()->checkParkWaitState() == false) return false; // #7 Check if startup procedure Phase #2 is complete (Unparking phase) - if (startupState > STARTUP_SCRIPT && startupState < STARTUP_ERROR && checkStartupState() == false) + if (moduleState()->startupState() > STARTUP_SCRIPT + && moduleState()->startupState() < STARTUP_ERROR + && process()->checkStartupState() == false) return false; // #8 Check it it already completed (should only happen starting a paused job) // Find the next job in this case, otherwise execute the current one - if (currentJob && currentJob->getState() == SchedulerJob::JOB_COMPLETE) + if (activeJob() && activeJob()->getState() == SchedulerJob::JOB_COMPLETE) findNextJob(); // N.B. We explicitly do not check for return result here because regardless of execution result // we do not have any pending tasks further down. - executeJob(currentJob); + executeJob(activeJob()); } return true; @@ -3038,24 +2220,25 @@ void Scheduler::checkJobStage() { - Q_ASSERT_X(currentJob, __FUNCTION__, "Actual current job is required to check job stage"); - if (!currentJob) + Q_ASSERT_X(activeJob(), __FUNCTION__, "Actual current job is required to check job stage"); + if (!activeJob()) return; if (checkJobStageCounter == 0) { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking job stage for" << currentJob->getName() << "startup" << - currentJob->getStartupCondition() << currentJob->getStartupTime().toString(currentJob->getDateTimeDisplayFormat()) << - "state" << currentJob->getState(); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking job stage for" << activeJob()->getName() << "startup" << + activeJob()->getStartupCondition() << activeJob()->getStartupTime().toString( + activeJob()->getDateTimeDisplayFormat()) << + "state" << activeJob()->getState(); if (checkJobStageCounter++ == 30) checkJobStageCounter = 0; } syncGreedyParams(); - if (!m_GreedyScheduler->checkJob(jobs, getLocalTime(), currentJob)) + if (!m_GreedyScheduler->checkJob(moduleState()->jobs(), SchedulerModuleState::getLocalTime(), activeJob())) { - currentJob->setState(SchedulerJob::JOB_IDLE); + activeJob()->setState(SchedulerJob::JOB_IDLE); stopCurrentJobAction(); findNextJob(); return; @@ -3065,7 +2248,7 @@ void Scheduler::checkJobStageEplogue() { - if (!currentJob) + if (!activeJob()) return; // #5 Check system status to improve robustness @@ -3074,122 +2257,122 @@ return; // #5b Check the guiding timer, and possibly restart guiding. - processGuidingTimer(); + process()->processGuidingTimer(); // #6 Check each stage is processing properly // FIXME: Vanishing property should trigger a call to its event callback - if (!currentJob) return; - switch (currentJob->getStage()) + if (!activeJob()) return; + switch (activeJob()->getStage()) { case SchedulerJob::STAGE_IDLE: // Job is just starting. - emit jobStarted(currentJob->getName()); + emit jobStarted(activeJob()->getName()); getNextAction(); break; case SchedulerJob::STAGE_ALIGNING: // Let's make sure align module does not become unresponsive - if (getCurrentOperationMsec() > static_cast(ALIGN_INACTIVITY_TIMEOUT)) + if (moduleState()->getCurrentOperationMsec() > static_cast(ALIGN_INACTIVITY_TIMEOUT)) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "alignInterface:property", "status"); - QVariant const status = alignInterface->property("status"); + QVariant const status = process()->alignInterface()->property("status"); TEST_PRINT(stderr, " @@@dbus received %d\n", !status.isValid() ? -1 : status.toInt()); Ekos::AlignState alignStatus = static_cast(status.toInt()); if (alignStatus == Ekos::ALIGN_IDLE) { - if (alignFailureCount++ < MAX_FAILURE_ATTEMPTS) + if (moduleState()->increaseAlignFailureCount()) { qCDebug(KSTARS_EKOS_SCHEDULER) << "Align module timed out. Restarting request..."; - startAstrometry(); + process()->startAstrometry(); } else { - appendLogText(i18n("Warning: job '%1' alignment procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); + appendLogText(i18n("Warning: job '%1' alignment procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); findNextJob(); } } else - startCurrentOperationTimer(); + moduleState()->startCurrentOperationTimer(); } break; case SchedulerJob::STAGE_CAPTURING: // Let's make sure capture module does not become unresponsive - if (getCurrentOperationMsec() > static_cast(CAPTURE_INACTIVITY_TIMEOUT)) + if (moduleState()->getCurrentOperationMsec() > static_cast(CAPTURE_INACTIVITY_TIMEOUT)) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:property", "status"); - QVariant const status = captureInterface->property("status"); + QVariant const status = process()->captureInterface()->property("status"); TEST_PRINT(stderr, " @@@dbus received %d\n", !status.isValid() ? -1 : status.toInt()); Ekos::CaptureState captureStatus = static_cast(status.toInt()); if (captureStatus == Ekos::CAPTURE_IDLE) { - if (captureFailureCount++ < MAX_FAILURE_ATTEMPTS) + if (moduleState()->increaseCaptureFailureCount()) { qCDebug(KSTARS_EKOS_SCHEDULER) << "capture module timed out. Restarting request..."; - startCapture(); + process()->startCapture(); } else { - appendLogText(i18n("Warning: job '%1' capture procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); + appendLogText(i18n("Warning: job '%1' capture procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); findNextJob(); } } - else startCurrentOperationTimer(); + else moduleState()->startCurrentOperationTimer(); } break; case SchedulerJob::STAGE_FOCUSING: // Let's make sure focus module does not become unresponsive - if (getCurrentOperationMsec() > static_cast(FOCUS_INACTIVITY_TIMEOUT)) + if (moduleState()->getCurrentOperationMsec() > static_cast(FOCUS_INACTIVITY_TIMEOUT)) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "focusInterface:property", "status"); - QVariant const status = focusInterface->property("status"); + QVariant const status = process()->focusInterface()->property("status"); TEST_PRINT(stderr, " @@@dbus received %d\n", !status.isValid() ? -1 : status.toInt()); Ekos::FocusState focusStatus = static_cast(status.toInt()); if (focusStatus == Ekos::FOCUS_IDLE || focusStatus == Ekos::FOCUS_WAITING) { - if (focusFailureCount++ < MAX_FAILURE_ATTEMPTS) + if (moduleState()->increaseFocusFailureCount()) { qCDebug(KSTARS_EKOS_SCHEDULER) << "Focus module timed out. Restarting request..."; - startFocusing(); + process()->startFocusing(); } else { - appendLogText(i18n("Warning: job '%1' focusing procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); + appendLogText(i18n("Warning: job '%1' focusing procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); findNextJob(); } } - else startCurrentOperationTimer(); + else moduleState()->startCurrentOperationTimer(); } break; case SchedulerJob::STAGE_GUIDING: // Let's make sure guide module does not become unresponsive - if (getCurrentOperationMsec() > GUIDE_INACTIVITY_TIMEOUT) + if (moduleState()->getCurrentOperationMsec() > GUIDE_INACTIVITY_TIMEOUT) { - GuideState guideStatus = getGuidingStatus(); + GuideState guideStatus = process()->getGuidingStatus(); if (guideStatus == Ekos::GUIDE_IDLE || guideStatus == Ekos::GUIDE_CONNECTED || guideStatus == Ekos::GUIDE_DISCONNECTED) { - if (guideFailureCount++ < MAX_FAILURE_ATTEMPTS) + if (moduleState()->increaseGuideFailureCount()) { qCDebug(KSTARS_EKOS_SCHEDULER) << "guide module timed out. Restarting request..."; - startGuiding(); + process()->startGuiding(); } else { - appendLogText(i18n("Warning: job '%1' guiding procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); + appendLogText(i18n("Warning: job '%1' guiding procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); findNextJob(); } } - else startCurrentOperationTimer(); + else moduleState()->startCurrentOperationTimer(); } break; @@ -3198,7 +2381,7 @@ // While slewing or re-slewing, check slew status can still be obtained { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "status"); - QVariant const slewStatus = mountInterface->property("status"); + QVariant const slewStatus = process()->mountInterface()->property("status"); TEST_PRINT(stderr, " @@@dbus received %d\n", !slewStatus.isValid() ? -1 : slewStatus.toInt()); if (slewStatus.isValid()) @@ -3206,13 +2389,13 @@ // Send the slew status periodically to avoid the situation where the mount is already at location and does not send any event // FIXME: in that case, filter TRACKING events only? ISD::Mount::Status const status = static_cast(slewStatus.toInt()); - setMountStatus(status); + process()->setMountStatus(status); } else { - appendLogText(i18n("Warning: job '%1' lost connection to the mount, attempting to reconnect.", currentJob->getName())); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); + appendLogText(i18n("Warning: job '%1' lost connection to the mount, attempting to reconnect.", activeJob()->getName())); + if (!process()->manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); return; } } @@ -3221,18 +2404,18 @@ case SchedulerJob::STAGE_SLEW_COMPLETE: case SchedulerJob::STAGE_RESLEWING_COMPLETE: // When done slewing or re-slewing and we use a dome, only shift to the next action when the dome is done moving - if (m_DomeReady) + if (moduleState()->domeReady()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "isMoving"); - QVariant const isDomeMoving = domeInterface->property("isMoving"); + QVariant const isDomeMoving = process()->domeInterface()->property("isMoving"); TEST_PRINT(stderr, " @@@dbus received %s\n", !isDomeMoving.isValid() ? "invalid" : (isDomeMoving.value() ? "T" : "F")); if (!isDomeMoving.isValid()) { - appendLogText(i18n("Warning: job '%1' lost connection to the dome, attempting to reconnect.", currentJob->getName())); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); + appendLogText(i18n("Warning: job '%1' lost connection to the dome, attempting to reconnect.", activeJob()->getName())); + if (!process()->manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); return; } @@ -3251,93 +2434,93 @@ { qCDebug(KSTARS_EKOS_SCHEDULER) << "Get next action..."; - switch (currentJob->getStage()) + switch (activeJob()->getStage()) { case SchedulerJob::STAGE_IDLE: - if (currentJob->getLightFramesRequired()) + if (activeJob()->getLightFramesRequired()) { - if (currentJob->getStepPipeline() & SchedulerJob::USE_TRACK) - startSlew(); - else if (currentJob->getStepPipeline() & SchedulerJob::USE_FOCUS && autofocusCompleted == false) - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "startFocusing on 3485"; - startFocusing(); - } - else if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN) - startAstrometry(); - else if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) - if (getGuidingStatus() == GUIDE_GUIDING) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_TRACK) + process()->startSlew(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_FOCUS && moduleState()->autofocusCompleted() == false) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "process()->startFocusing on 3485"; + process()->startFocusing(); + } + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN) + process()->startAstrometry(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) + if (process()->getGuidingStatus() == GUIDE_GUIDING) { appendLogText(i18n("Guiding already running, directly start capturing.")); - startCapture(); + process()->startCapture(); } else - startGuiding(); + process()->startGuiding(); else - startCapture(); + process()->startCapture(); } else { - if (currentJob->getStepPipeline()) + if (activeJob()->getStepPipeline()) appendLogText( i18n("Job '%1' is proceeding directly to capture stage because only calibration frames are pending.", - currentJob->getName())); - startCapture(); + activeJob()->getName())); + process()->startCapture(); } break; case SchedulerJob::STAGE_SLEW_COMPLETE: - if (currentJob->getStepPipeline() & SchedulerJob::USE_FOCUS && autofocusCompleted == false) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_FOCUS && moduleState()->autofocusCompleted() == false) { - qCDebug(KSTARS_EKOS_SCHEDULER) << "startFocusing on 3514"; - startFocusing(); + qCDebug(KSTARS_EKOS_SCHEDULER) << "process()->startFocusing on 3514"; + process()->startFocusing(); } - else if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN) - startAstrometry(); - else if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) - startGuiding(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN) + process()->startAstrometry(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) + process()->startGuiding(); else - startCapture(); + process()->startCapture(); break; case SchedulerJob::STAGE_FOCUS_COMPLETE: - if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN) - startAstrometry(); - else if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) - startGuiding(); + if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN) + process()->startAstrometry(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) + process()->startGuiding(); else - startCapture(); + process()->startCapture(); break; case SchedulerJob::STAGE_ALIGN_COMPLETE: - currentJob->setStage(SchedulerJob::STAGE_RESLEWING); + activeJob()->setStage(SchedulerJob::STAGE_RESLEWING); break; case SchedulerJob::STAGE_RESLEWING_COMPLETE: // If we have in-sequence-focus in the sequence file then we perform post alignment focusing so that the focus // frame is ready for the capture module in-sequence-focus procedure. - if ((currentJob->getStepPipeline() & SchedulerJob::USE_FOCUS) && currentJob->getInSequenceFocus()) + if ((activeJob()->getStepPipeline() & SchedulerJob::USE_FOCUS) && activeJob()->getInSequenceFocus()) // Post alignment re-focusing { - qCDebug(KSTARS_EKOS_SCHEDULER) << "startFocusing on 3544"; - startFocusing(); + qCDebug(KSTARS_EKOS_SCHEDULER) << "process()->startFocusing on 3544"; + process()->startFocusing(); } - else if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) - startGuiding(); + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) + process()->startGuiding(); else - startCapture(); + process()->startCapture(); break; case SchedulerJob::STAGE_POSTALIGN_FOCUSING_COMPLETE: - if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) - startGuiding(); + if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) + process()->startGuiding(); else - startCapture(); + process()->startCapture(); break; case SchedulerJob::STAGE_GUIDING_COMPLETE: - startCapture(); + process()->startCapture(); break; default: @@ -3347,36 +2530,36 @@ void Scheduler::stopCurrentJobAction() { - if (nullptr != currentJob) + if (nullptr != activeJob()) { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Job '" << currentJob->getName() << "' is stopping current action..." << - currentJob->getStage(); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Job '" << activeJob()->getName() << "' is stopping current action..." << + activeJob()->getStage(); - switch (currentJob->getStage()) + switch (activeJob()->getStage()) { case SchedulerJob::STAGE_IDLE: break; case SchedulerJob::STAGE_SLEWING: TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "abort"); - mountInterface->call(QDBus::AutoDetect, "abort"); + process()->mountInterface()->call(QDBus::AutoDetect, "abort"); break; case SchedulerJob::STAGE_FOCUSING: TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "focusInterface:call", "abort"); - focusInterface->call(QDBus::AutoDetect, "abort"); + process()->focusInterface()->call(QDBus::AutoDetect, "abort"); break; case SchedulerJob::STAGE_ALIGNING: TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "alignInterface:call", "abort"); - alignInterface->call(QDBus::AutoDetect, "abort"); + process()->alignInterface()->call(QDBus::AutoDetect, "abort"); break; // N.B. Need to use BlockWithGui as proposed by Wolfgang // to ensure capture is properly aborted before taking any further actions. case SchedulerJob::STAGE_CAPTURING: TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:call", "abort"); - captureInterface->call(QDBus::BlockWithGui, "abort"); + process()->captureInterface()->call(QDBus::BlockWithGui, "abort"); break; default: @@ -3384,64 +2567,11 @@ } /* Reset interrupted job stage */ - currentJob->setStage(SchedulerJob::STAGE_IDLE); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); } /* Guiding being a parallel process, check to stop it */ - stopGuiding(); -} - -bool Scheduler::manageConnectionLoss() -{ - if (SCHEDULER_RUNNING != state) - return false; - - // Don't manage loss if Ekos is actually down in the state machine - switch (ekosState) - { - case EKOS_IDLE: - case EKOS_STOPPING: - return false; - - default: - break; - } - - // Don't manage loss if INDI is actually down in the state machine - switch (indiState) - { - case INDI_IDLE: - case INDI_DISCONNECTING: - return false; - - default: - break; - } - - // If Ekos is assumed to be up, check its state - //QDBusReply const isEkosStarted = ekosInterface->call(QDBus::AutoDetect, "getEkosStartingStatus"); - if (m_EkosCommunicationStatus == Ekos::Success) - { - qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Ekos is currently connected, checking INDI before mitigating connection loss."); - - // If INDI is assumed to be up, check its state - if (isINDIConnected()) - { - // If both Ekos and INDI are assumed up, and are actually up, no mitigation needed, this is a DBus interface error - qCDebug(KSTARS_EKOS_SCHEDULER) << QString("INDI is currently connected, no connection loss mitigation needed."); - return false; - } - } - - // Stop actions of the current job - stopCurrentJobAction(); - - // Acknowledge INDI and Ekos disconnections - disconnectINDI(); - stopEkos(); - - // Let the Scheduler attempt to connect INDI again - return true; + process()->stopGuiding(); } void Scheduler::load(bool clearQueue, const QString &filename) @@ -3482,8 +2612,8 @@ while (queueTable->rowCount() > 0) queueTable->removeRow(0); - qDeleteAll(jobs); - jobs.clear(); + qDeleteAll(moduleState()->jobs()); + moduleState()->mutlableJobs().clear(); } bool Scheduler::loadScheduler(const QString &fileURL) @@ -3494,8 +2624,8 @@ bool Scheduler::appendEkosScheduleList(const QString &fileURL) { - SchedulerState const old_state = state; - state = SCHEDULER_LOADING; + SchedulerState const old_state = moduleState()->schedulerState(); + moduleState()->setSchedulerState(SCHEDULER_LOADING); QFile sFile; sFile.setFileName(fileURL); @@ -3504,7 +2634,7 @@ { QString message = i18n("Unable to open file %1", fileURL); KSNotification::sorry(message, i18n("Could Not Open File")); - state = old_state; + moduleState()->setSchedulerState(old_state); return false; } @@ -3537,7 +2667,7 @@ } else if (!strcmp(tag, "Profile")) { - schedulerProfileCombo->setCurrentText(pcdataXMLEle(ep)); + moduleState()->setCurrentProfile(pcdataXMLEle(ep)); } else if (!strcmp(tag, "SchedulerAlgorithm")) { @@ -3545,23 +2675,23 @@ } else if (!strcmp(tag, "ErrorHandlingStrategy")) { - setErrorHandlingStrategy(static_cast(cLocale.toInt(findXMLAttValu(ep, "value")))); + Options::setErrorHandlingStrategy(static_cast(cLocale.toInt(findXMLAttValu(ep, + "value")))); subEP = findXMLEle(ep, "delay"); if (subEP) { - errorHandlingDelaySB->setValue(cLocale.toInt(pcdataXMLEle(subEP))); + Options::setErrorHandlingStrategyDelay(cLocale.toInt(pcdataXMLEle(subEP))); } subEP = findXMLEle(ep, "RescheduleErrors"); - errorHandlingRescheduleErrorsCB->setChecked(subEP != nullptr); + Options::setRescheduleErrors(subEP != nullptr); } else if (!strcmp(tag, "StartupProcedure")) { XMLEle *procedure; - startupScript->clear(); - unparkDomeCheck->setChecked(false); - unparkMountCheck->setChecked(false); - uncapCheck->setChecked(false); + Options::setSchedulerUnparkDome(false); + Options::setSchedulerUnparkMount(false); + Options::setSchedulerOpenDustCover(false); for (procedure = nextXMLEle(ep, 1); procedure != nullptr; procedure = nextXMLEle(ep, 0)) { @@ -3569,25 +2699,23 @@ if (!strcmp(proc, "StartupScript")) { - startupScript->setText(findXMLAttValu(procedure, "value")); - startupScriptURL = QUrl::fromUserInput(startupScript->text()); + moduleState()->setStartupScriptURL(QUrl::fromUserInput(findXMLAttValu(procedure, "value"))); } else if (!strcmp(proc, "UnparkDome")) - unparkDomeCheck->setChecked(true); + Options::setSchedulerUnparkDome(true); else if (!strcmp(proc, "UnparkMount")) - unparkMountCheck->setChecked(true); + Options::setSchedulerUnparkMount(true); else if (!strcmp(proc, "UnparkCap")) - uncapCheck->setChecked(true); + Options::setSchedulerOpenDustCover(true); } } else if (!strcmp(tag, "ShutdownProcedure")) { XMLEle *procedure; - shutdownScript->clear(); - warmCCDCheck->setChecked(false); - parkDomeCheck->setChecked(false); - parkMountCheck->setChecked(false); - capCheck->setChecked(false); + Options::setSchedulerWarmCCD(false); + Options::setSchedulerParkDome(false); + Options::setSchedulerParkMount(false); + Options::setSchedulerCloseDustCover(false); for (procedure = nextXMLEle(ep, 1); procedure != nullptr; procedure = nextXMLEle(ep, 0)) { @@ -3595,40 +2723,40 @@ if (!strcmp(proc, "ShutdownScript")) { - shutdownScript->setText(findXMLAttValu(procedure, "value")); - shutdownScriptURL = QUrl::fromUserInput(shutdownScript->text()); + moduleState()->setShutdownScriptURL(QUrl::fromUserInput(findXMLAttValu(procedure, "value"))); } + else if (!strcmp(proc, "WarmCCD")) + Options::setSchedulerWarmCCD(true); else if (!strcmp(proc, "ParkDome")) - parkDomeCheck->setChecked(true); + Options::setSchedulerParkDome(true); else if (!strcmp(proc, "ParkMount")) - parkMountCheck->setChecked(true); + Options::setSchedulerParkMount(true); else if (!strcmp(proc, "ParkCap")) - capCheck->setChecked(true); - else if (!strcmp(proc, "WarmCCD")) - warmCCDCheck->setChecked(true); + Options::setSchedulerCloseDustCover(true); } } } delXMLEle(root); + syncGUIToGeneralSettings(); } else if (errmsg[0]) { appendLogText(QString(errmsg)); delLilXML(xmlParser); - state = old_state; + moduleState()->setSchedulerState(old_state); return false; } } schedulerURL = QUrl::fromLocalFile(fileURL); //mosaicB->setEnabled(true); - mDirty = false; + moduleState()->setDirty(false); delLilXML(xmlParser); // update save button tool tip queueSaveB->setToolTip("Save schedule to " + schedulerURL.fileName()); - state = old_state; + moduleState()->setSchedulerState(old_state); return true; } @@ -3794,7 +2922,7 @@ schedulerURL.clear(); // If no changes made, return. - if (mDirty == false && !schedulerURL.isEmpty()) + if (moduleState()->dirty() == false && !schedulerURL.isEmpty()) return; if (schedulerURL.isEmpty()) @@ -3833,356 +2961,6 @@ } } -bool Scheduler::saveScheduler(const QUrl &fileURL) -{ - QFile file; - file.setFileName(fileURL.toLocalFile()); - - if (!file.open(QIODevice::WriteOnly)) - { - QString message = i18n("Unable to write to file %1", fileURL.toLocalFile()); - KSNotification::sorry(message, i18n("Could Not Open File")); - return false; - } - - QTextStream outstream(&file); - - // We serialize sequence data to XML using the C locale - QLocale cLocale = QLocale::c(); - - outstream << "" << Qt::endl; - outstream << "" << Qt::endl; - // ensure to escape special XML characters - outstream << "" << QString(entityXML(strdup(schedulerProfileCombo->currentText().toStdString().c_str()))) << - "" << Qt::endl; - - auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles(); - bool useMosaicInfo = !tiles->sequenceFile().isEmpty(); - - if (useMosaicInfo) - { - outstream << "" << Qt::endl; - outstream << "" << tiles->targetName() << "" << Qt::endl; - outstream << "" << tiles->group() << "" << Qt::endl; - - QString ccArg, ccValue = tiles->completionCondition(&ccArg); - if (ccValue == "FinishSequence") - outstream << "" << Qt::endl; - else if (ccValue == "FinishLoop") - outstream << "" << Qt::endl; - else if (ccValue == "FinishRepeat") - outstream << "" << ccArg << "" << Qt::endl; - - outstream << "" << tiles->sequenceFile() << "" << Qt::endl; - outstream << "" << tiles->outputDirectory() << "" << Qt::endl; - - outstream << "" << tiles->focusEveryN() << "" << Qt::endl; - outstream << "" << tiles->alignEveryN() << "" << Qt::endl; - if (tiles->isTrackChecked()) - outstream << "" << Qt::endl; - if (tiles->isFocusChecked()) - outstream << "" << Qt::endl; - if (tiles->isAlignChecked()) - outstream << "" << Qt::endl; - if (tiles->isGuideChecked()) - outstream << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->overlap()) << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->ra0().Hours()) << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->dec0().Degrees()) << "" << Qt::endl; - outstream << "" << tiles->gridSize().width() << "" << Qt::endl; - outstream << "" << tiles->gridSize().height() << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->mosaicFOV().width()) << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->mosaicFOV().height()) << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->cameraFOV().width()) << "" << Qt::endl; - outstream << "" << cLocale.toString(tiles->cameraFOV().height()) << "" << Qt::endl; - outstream << "" << Qt::endl; - } - - int index = 0; - for (auto &job : jobs) - { - outstream << "" << Qt::endl; - - // ensure to escape special XML characters - outstream << "" << QString(entityXML(strdup(job->getName().toStdString().c_str()))) << "" << Qt::endl; - outstream << "" << QString(entityXML(strdup(job->getGroup().toStdString().c_str()))) << "" << Qt::endl; - outstream << "" << Qt::endl; - outstream << "" << cLocale.toString(job->getTargetCoords().ra0().Hours()) << "" << Qt::endl; - outstream << "" << cLocale.toString(job->getTargetCoords().dec0().Degrees()) << "" << Qt::endl; - outstream << "" << Qt::endl; - - if (job->getFITSFile().isValid() && job->getFITSFile().isEmpty() == false) - outstream << "" << job->getFITSFile().toLocalFile() << "" << Qt::endl; - else - outstream << "" << job->getPositionAngle() << "" << Qt::endl; - - outstream << "" << job->getSequenceFile().toLocalFile() << "" << Qt::endl; - - if (useMosaicInfo && index < tiles->tiles().size()) - { - auto oneTile = tiles->tiles().at(index++); - outstream << "" << Qt::endl; - outstream << "" << cLocale.toString(oneTile->center.x()) << "" << Qt::endl; - outstream << "" << cLocale.toString(oneTile->center.y()) << "" << Qt::endl; - outstream << "" << cLocale.toString(oneTile->rotation) << "" << Qt::endl; - outstream << "" << Qt::endl; - } - - outstream << "" << Qt::endl; - if (job->getFileStartupCondition() == SchedulerJob::START_ASAP) - outstream << "ASAP" << Qt::endl; - else if (job->getFileStartupCondition() == SchedulerJob::START_AT) - outstream << "At" - << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - if (job->hasMinAltitude()) - outstream << "MinimumAltitude" << - Qt::endl; - if (job->getMinMoonSeparation() > 0) - outstream << "MoonSeparation" - << Qt::endl; - if (job->getEnforceWeather()) - outstream << "EnforceWeather" << Qt::endl; - if (job->getEnforceTwilight()) - outstream << "EnforceTwilight" << Qt::endl; - if (job->getEnforceArtificialHorizon()) - outstream << "EnforceArtificialHorizon" << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - if (job->getCompletionCondition() == SchedulerJob::FINISH_SEQUENCE) - outstream << "Sequence" << Qt::endl; - else if (job->getCompletionCondition() == SchedulerJob::FINISH_REPEAT) - outstream << "Repeat" << Qt::endl; - else if (job->getCompletionCondition() == SchedulerJob::FINISH_LOOP) - outstream << "Loop" << Qt::endl; - else if (job->getCompletionCondition() == SchedulerJob::FINISH_AT) - outstream << "At" - << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - if (job->getStepPipeline() & SchedulerJob::USE_TRACK) - outstream << "Track" << Qt::endl; - if (job->getStepPipeline() & SchedulerJob::USE_FOCUS) - outstream << "Focus" << Qt::endl; - if (job->getStepPipeline() & SchedulerJob::USE_ALIGN) - outstream << "Align" << Qt::endl; - if (job->getStepPipeline() & SchedulerJob::USE_GUIDE) - outstream << "Guide" << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - } - - outstream << "" << Qt::endl; - outstream << "" << Qt::endl; - if (errorHandlingRescheduleErrorsCB->isChecked()) - outstream << "" << Qt::endl; - outstream << "" << errorHandlingDelaySB->value() << "" << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - if (startupScript->text().isEmpty() == false) - outstream << "StartupScript" << Qt::endl; - if (unparkDomeCheck->isChecked()) - outstream << "UnparkDome" << Qt::endl; - if (unparkMountCheck->isChecked()) - outstream << "UnparkMount" << Qt::endl; - if (uncapCheck->isChecked()) - outstream << "UnparkCap" << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - if (warmCCDCheck->isChecked()) - outstream << "WarmCCD" << Qt::endl; - if (capCheck->isChecked()) - outstream << "ParkCap" << Qt::endl; - if (parkMountCheck->isChecked()) - outstream << "ParkMount" << Qt::endl; - if (parkDomeCheck->isChecked()) - outstream << "ParkDome" << Qt::endl; - if (shutdownScript->text().isEmpty() == false) - outstream << "ShutdownScript" << Qt::endl; - outstream << "" << Qt::endl; - - outstream << "" << Qt::endl; - - appendLogText(i18n("Scheduler list saved to %1", fileURL.toLocalFile())); - file.close(); - mDirty = false; - return true; -} - -void Scheduler::startSlew() -{ - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, "Job starting slewing must be valid"); - - // If the mount was parked by a pause or the end-user, unpark - if (isMountParked()) - { - setParkWaitState(PARKWAIT_UNPARK); - return; - } - - if (Options::resetMountModelBeforeJob()) - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "resetModel"); - mountInterface->call(QDBus::AutoDetect, "resetModel"); - } - - SkyPoint target = currentJob->getTargetCoords(); - QList telescopeSlew; - telescopeSlew.append(target.ra().Hours()); - telescopeSlew.append(target.dec().Degrees()); - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s%s,%s\n", __LINE__, "mountInterface:callWithArgs", "slew: ", - target.ra().toHMSString().toLatin1().data(), target.dec().toDMSString().toLatin1().data()); - QDBusReply const slewModeReply = mountInterface->callWithArgumentList(QDBus::AutoDetect, "slew", telescopeSlew); - TEST_PRINT(stderr, " @@@dbus received %s\n", slewModeReply.error().type() == QDBusError::NoError ? "no error" : "error"); - - if (slewModeReply.error().type() != QDBusError::NoError) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' slew request received DBUS error: %2").arg( - currentJob->getName(), QDBusError::errorString(slewModeReply.error().type())); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); - } - else - { - currentJob->setStage(SchedulerJob::STAGE_SLEWING); - appendLogText(i18n("Job '%1' is slewing to target.", currentJob->getName())); - } -} - -void Scheduler::startFocusing() -{ - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, "Job starting focusing must be valid"); - - // 2017-09-30 Jasem: We're skipping post align focusing now as it can be performed - // when first focus request is made in capture module - if (currentJob->getStage() == SchedulerJob::STAGE_RESLEWING_COMPLETE || - currentJob->getStage() == SchedulerJob::STAGE_POSTALIGN_FOCUSING) - { - // Clear the HFR limit value set in the capture module - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "captureInterface", "clearAutoFocusHFR"); - captureInterface->call(QDBus::AutoDetect, "clearAutoFocusHFR"); - // Reset Focus frame so that next frame take a full-resolution capture first. - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "resetFrame"); - focusInterface->call(QDBus::AutoDetect, "resetFrame"); - currentJob->setStage(SchedulerJob::STAGE_POSTALIGN_FOCUSING_COMPLETE); - getNextAction(); - return; - } - - // Check if autofocus is supported - QDBusReply focusModeReply; - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "canAutoFocus"); - focusModeReply = focusInterface->call(QDBus::AutoDetect, "canAutoFocus"); - - if (focusModeReply.error().type() != QDBusError::NoError) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' canAutoFocus request received DBUS error: %2").arg( - currentJob->getName(), QDBusError::errorString(focusModeReply.error().type())); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - - if (focusModeReply.value() == false) - { - appendLogText(i18n("Warning: job '%1' is unable to proceed with autofocus, not supported.", currentJob->getName())); - currentJob->setStepPipeline( - static_cast(currentJob->getStepPipeline() & ~SchedulerJob::USE_FOCUS)); - currentJob->setStage(SchedulerJob::STAGE_FOCUS_COMPLETE); - getNextAction(); - return; - } - - // Clear the HFR limit value set in the capture module - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "captureInterface", "clearAutoFocusHFR"); - captureInterface->call(QDBus::AutoDetect, "clearAutoFocusHFR"); - - QDBusMessage reply; - - // We always need to reset frame first - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "resetFrame"); - if ((reply = focusInterface->call(QDBus::AutoDetect, "resetFrame")).type() == QDBusMessage::ErrorMessage) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' resetFrame request received DBUS error: %2").arg( - currentJob->getName(), reply.errorMessage()); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - - - // If we have a LIGHT filter set, let's set it. - if (!currentJob->getInitialFilter().isEmpty()) - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "focusInterface:setProperty"); - focusInterface->setProperty("filter", currentJob->getInitialFilter()); - } - - // Set autostar if full field option is false - if (Options::focusUseFullField() == false) - { - QList autoStar; - autoStar.append(true); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "setAutoStarEnabled"); - if ((reply = focusInterface->callWithArgumentList(QDBus::AutoDetect, "setAutoStarEnabled", autoStar)).type() == - QDBusMessage::ErrorMessage) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' setAutoFocusStar request received DBUS error: %1").arg( - currentJob->getName(), reply.errorMessage()); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - } - - // Start auto-focus - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "focusInterface", "start"); - if ((reply = focusInterface->call(QDBus::AutoDetect, "start")).type() == QDBusMessage::ErrorMessage) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' startFocus request received DBUS error: %2").arg( - currentJob->getName(), reply.errorMessage()); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - - /*if (currentJob->getStage() == SchedulerJob::STAGE_RESLEWING_COMPLETE || - currentJob->getStage() == SchedulerJob::STAGE_POSTALIGN_FOCUSING) - { - currentJob->setStage(SchedulerJob::STAGE_POSTALIGN_FOCUSING); - appendLogText(i18n("Post-alignment focusing for %1 ...", currentJob->getName())); - } - else - { - currentJob->setStage(SchedulerJob::STAGE_FOCUSING); - appendLogText(i18n("Focusing %1 ...", currentJob->getName())); - }*/ - - currentJob->setStage(SchedulerJob::STAGE_FOCUSING); - appendLogText(i18n("Job '%1' is focusing.", currentJob->getName())); - startCurrentOperationTimer(); -} - bool Scheduler::canCountCaptures(const SchedulerJob &job) { QList seqjobs; @@ -4205,51 +2983,54 @@ // Similarly, if jobs are aborted they may (a) restart right away, (b) restart after a delay, (c) be ended. void Scheduler::findNextJob() { - if (state == SCHEDULER_PAUSED) + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) { // everything finished, we can pause setPaused(); return; } - Q_ASSERT_X(currentJob->getState() == SchedulerJob::JOB_ERROR || - currentJob->getState() == SchedulerJob::JOB_ABORTED || - currentJob->getState() == SchedulerJob::JOB_COMPLETE || - currentJob->getState() == SchedulerJob::JOB_IDLE, + Q_ASSERT_X(activeJob()->getState() == SchedulerJob::JOB_ERROR || + activeJob()->getState() == SchedulerJob::JOB_ABORTED || + activeJob()->getState() == SchedulerJob::JOB_COMPLETE || + activeJob()->getState() == SchedulerJob::JOB_IDLE, __FUNCTION__, "Finding next job requires current to be in error, aborted, idle or complete"); // Reset failed count - alignFailureCount = guideFailureCount = focusFailureCount = captureFailureCount = 0; + moduleState()->resetAlignFailureCount(); + moduleState()->resetGuideFailureCount(); + moduleState()->resetFocusFailureCount(); + moduleState()->resetCaptureFailureCount(); - if (currentJob->getState() == SchedulerJob::JOB_ERROR || currentJob->getState() == SchedulerJob::JOB_ABORTED) + if (activeJob()->getState() == SchedulerJob::JOB_ERROR || activeJob()->getState() == SchedulerJob::JOB_ABORTED) { - emit jobEnded(currentJob->getName(), currentJob->getStopReason()); - captureBatch = 0; + emit jobEnded(activeJob()->getName(), activeJob()->getStopReason()); + moduleState()->resetCaptureBatch(); // Stop Guiding if it was used - stopGuiding(); + process()->stopGuiding(); - if (currentJob->getState() == SchedulerJob::JOB_ERROR) - appendLogText(i18n("Job '%1' is terminated due to errors.", currentJob->getName())); + if (activeJob()->getState() == SchedulerJob::JOB_ERROR) + appendLogText(i18n("Job '%1' is terminated due to errors.", activeJob()->getName())); else - appendLogText(i18n("Job '%1' is aborted.", currentJob->getName())); + appendLogText(i18n("Job '%1' is aborted.", activeJob()->getName())); // Always reset job stage - currentJob->setStage(SchedulerJob::STAGE_IDLE); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); // restart aborted jobs immediately, if error handling strategy is set to "restart immediately" if (errorHandlingRestartImmediatelyButton->isChecked() && - (currentJob->getState() == SchedulerJob::JOB_ABORTED || - (currentJob->getState() == SchedulerJob::JOB_ERROR && errorHandlingRescheduleErrorsCB->isChecked()))) + (activeJob()->getState() == SchedulerJob::JOB_ABORTED || + (activeJob()->getState() == SchedulerJob::JOB_ERROR && errorHandlingRescheduleErrorsCB->isChecked()))) { // reset the state so that it will be restarted - currentJob->setState(SchedulerJob::JOB_SCHEDULED); + activeJob()->setState(SchedulerJob::JOB_SCHEDULED); - appendLogText(i18n("Waiting %1 seconds to restart job '%2'.", errorHandlingDelaySB->value(), currentJob->getName())); + appendLogText(i18n("Waiting %1 seconds to restart job '%2'.", errorHandlingDelaySB->value(), activeJob()->getName())); // wait the given delay until the jobs will be evaluated again TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_WAKEUP).toLatin1().data()); - setupNextIteration(RUN_WAKEUP, std::lround((errorHandlingDelaySB->value() * 1000) / - KStarsData::Instance()->clock()->scale())); + moduleState()->setupNextIteration(RUN_WAKEUP, std::lround((errorHandlingDelaySB->value() * 1000) / + KStarsData::Instance()->clock()->scale())); sleepLabel->setToolTip(i18n("Scheduler waits for a retry.")); sleepLabel->show(); return; @@ -4258,558 +3039,267 @@ // otherwise start re-evaluation setCurrentJob(nullptr); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } - else if (currentJob->getState() == SchedulerJob::JOB_IDLE) + else if (activeJob()->getState() == SchedulerJob::JOB_IDLE) { - emit jobEnded(currentJob->getName(), currentJob->getStopReason()); + emit jobEnded(activeJob()->getName(), activeJob()->getStopReason()); // job constraints no longer valid, start re-evaluation setCurrentJob(nullptr); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } // Job is complete, so check completion criteria to optimize processing // In any case, we're done whether the job completed successfully or not. - else if (currentJob->getCompletionCondition() == SchedulerJob::FINISH_SEQUENCE) + else if (activeJob()->getCompletionCondition() == FINISH_SEQUENCE) { - emit jobEnded(currentJob->getName(), currentJob->getStopReason()); + emit jobEnded(activeJob()->getName(), activeJob()->getStopReason()); /* If we remember job progress, mark the job idle as well as all its duplicates for re-evaluation */ if (Options::rememberJobProgress()) { - foreach(SchedulerJob *a_job, jobs) - if (a_job == currentJob || a_job->isDuplicateOf(currentJob)) + foreach(SchedulerJob *a_job, moduleState()->jobs()) + if (a_job == activeJob() || a_job->isDuplicateOf(activeJob())) a_job->setState(SchedulerJob::JOB_IDLE); } - captureBatch = 0; + moduleState()->resetCaptureBatch(); // Stop Guiding if it was used - stopGuiding(); + process()->stopGuiding(); - appendLogText(i18n("Job '%1' is complete.", currentJob->getName())); + appendLogText(i18n("Job '%1' is complete.", activeJob()->getName())); // Always reset job stage - currentJob->setStage(SchedulerJob::STAGE_IDLE); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); // If saving remotely, then can't tell later that the job has been completed. // Set it complete now. - if (!canCountCaptures(*currentJob)) - currentJob->setState(SchedulerJob::JOB_COMPLETE); + if (!canCountCaptures(*activeJob())) + activeJob()->setState(SchedulerJob::JOB_COMPLETE); setCurrentJob(nullptr); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } - else if (currentJob->getCompletionCondition() == SchedulerJob::FINISH_REPEAT && - (currentJob->getRepeatsRemaining() <= 1)) + else if (activeJob()->getCompletionCondition() == FINISH_REPEAT && + (activeJob()->getRepeatsRemaining() <= 1)) { /* If the job is about to repeat, decrease its repeat count and reset its start time */ - if (currentJob->getRepeatsRemaining() > 0) + if (activeJob()->getRepeatsRemaining() > 0) { // If we can remember job progress, this is done in estimateJobTime() if (!Options::rememberJobProgress()) { - currentJob->setRepeatsRemaining(currentJob->getRepeatsRemaining() - 1); - currentJob->setCompletedIterations(currentJob->getCompletedIterations() + 1); + activeJob()->setRepeatsRemaining(activeJob()->getRepeatsRemaining() - 1); + activeJob()->setCompletedIterations(activeJob()->getCompletedIterations() + 1); } - currentJob->setStartupTime(QDateTime()); + activeJob()->setStartupTime(QDateTime()); } /* Mark the job idle as well as all its duplicates for re-evaluation */ - foreach(SchedulerJob *a_job, jobs) - if (a_job == currentJob || a_job->isDuplicateOf(currentJob)) + foreach(SchedulerJob *a_job, moduleState()->jobs()) + if (a_job == activeJob() || a_job->isDuplicateOf(activeJob())) a_job->setState(SchedulerJob::JOB_IDLE); /* Re-evaluate all jobs, without selecting a new job */ evaluateJobs(true); /* If current job is actually complete because of previous duplicates, prepare for next job */ - if (currentJob == nullptr || currentJob->getRepeatsRemaining() == 0) + if (activeJob() == nullptr || activeJob()->getRepeatsRemaining() == 0) { stopCurrentJobAction(); - if (currentJob != nullptr) + if (activeJob() != nullptr) { - emit jobEnded(currentJob->getName(), currentJob->getStopReason()); + emit jobEnded(activeJob()->getName(), activeJob()->getStopReason()); appendLogText(i18np("Job '%1' is complete after #%2 batch.", "Job '%1' is complete after #%2 batches.", - currentJob->getName(), currentJob->getRepeatsRequired())); - if (!canCountCaptures(*currentJob)) - currentJob->setState(SchedulerJob::JOB_COMPLETE); + activeJob()->getName(), activeJob()->getRepeatsRequired())); + if (!canCountCaptures(*activeJob())) + activeJob()->setState(SchedulerJob::JOB_COMPLETE); setCurrentJob(nullptr); } TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } /* If job requires more work, continue current observation */ else { /* FIXME: raise priority to allow other jobs to schedule in-between */ - if (executeJob(currentJob) == false) + if (executeJob(activeJob()) == false) return; /* JM 2020-08-23: If user opts to force realign instead of for each job then we force this FIRST */ - if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) { - stopGuiding(); - currentJob->setStage(SchedulerJob::STAGE_ALIGNING); - startAstrometry(); + process()->stopGuiding(); + activeJob()->setStage(SchedulerJob::STAGE_ALIGNING); + process()->startAstrometry(); } /* If we are guiding, continue capturing */ - else if ( (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) ) + else if ( (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) ) { - currentJob->setStage(SchedulerJob::STAGE_CAPTURING); - startCapture(); + activeJob()->setStage(SchedulerJob::STAGE_CAPTURING); + process()->startCapture(); } /* If we are not guiding, but using alignment, realign */ - else if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN) + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN) { - currentJob->setStage(SchedulerJob::STAGE_ALIGNING); - startAstrometry(); + activeJob()->setStage(SchedulerJob::STAGE_ALIGNING); + process()->startAstrometry(); } /* Else if we are neither guiding nor using alignment, slew back to target */ - else if (currentJob->getStepPipeline() & SchedulerJob::USE_TRACK) + else if (activeJob()->getStepPipeline() & SchedulerJob::USE_TRACK) { - currentJob->setStage(SchedulerJob::STAGE_SLEWING); - startSlew(); + activeJob()->setStage(SchedulerJob::STAGE_SLEWING); + process()->startSlew(); } /* Else just start capturing */ else { - currentJob->setStage(SchedulerJob::STAGE_CAPTURING); - startCapture(); + activeJob()->setStage(SchedulerJob::STAGE_CAPTURING); + process()->startCapture(); } appendLogText(i18np("Job '%1' is repeating, #%2 batch remaining.", "Job '%1' is repeating, #%2 batches remaining.", - currentJob->getName(), currentJob->getRepeatsRemaining())); - /* currentJob remains the same */ + activeJob()->getName(), activeJob()->getRepeatsRemaining())); + /* getActiveJob() remains the same */ TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_JOBCHECK).toLatin1().data()); - setupNextIteration(RUN_JOBCHECK); + moduleState()->setupNextIteration(RUN_JOBCHECK); } } - else if ((currentJob->getCompletionCondition() == SchedulerJob::FINISH_LOOP) || - (currentJob->getCompletionCondition() == SchedulerJob::FINISH_REPEAT && - currentJob->getRepeatsRemaining() > 0)) + else if ((activeJob()->getCompletionCondition() == FINISH_LOOP) || + (activeJob()->getCompletionCondition() == FINISH_REPEAT && + activeJob()->getRepeatsRemaining() > 0)) { /* If the job is about to repeat, decrease its repeat count and reset its start time */ - if ((currentJob->getCompletionCondition() == SchedulerJob::FINISH_REPEAT) && - (currentJob->getRepeatsRemaining() > 1)) + if ((activeJob()->getCompletionCondition() == FINISH_REPEAT) && + (activeJob()->getRepeatsRemaining() > 1)) { // If we can remember job progress, this is done in estimateJobTime() if (!Options::rememberJobProgress()) { - currentJob->setRepeatsRemaining(currentJob->getRepeatsRemaining() - 1); - currentJob->setCompletedIterations(currentJob->getCompletedIterations() + 1); + activeJob()->setRepeatsRemaining(activeJob()->getRepeatsRemaining() - 1); + activeJob()->setCompletedIterations(activeJob()->getCompletedIterations() + 1); } - currentJob->setStartupTime(QDateTime()); + activeJob()->setStartupTime(QDateTime()); } - if (executeJob(currentJob) == false) + if (executeJob(activeJob()) == false) return; - if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) { - stopGuiding(); - currentJob->setStage(SchedulerJob::STAGE_ALIGNING); - startAstrometry(); + process()->stopGuiding(); + activeJob()->setStage(SchedulerJob::STAGE_ALIGNING); + process()->startAstrometry(); } else { - currentJob->setStage(SchedulerJob::STAGE_CAPTURING); - startCapture(); + activeJob()->setStage(SchedulerJob::STAGE_CAPTURING); + process()->startCapture(); } - captureBatch++; + moduleState()->increaseCaptureBatch(); - if (currentJob->getCompletionCondition() == SchedulerJob::FINISH_REPEAT ) + if (activeJob()->getCompletionCondition() == FINISH_REPEAT ) appendLogText(i18np("Job '%1' is repeating, #%2 batch remaining.", "Job '%1' is repeating, #%2 batches remaining.", - currentJob->getName(), currentJob->getRepeatsRemaining())); + activeJob()->getName(), activeJob()->getRepeatsRemaining())); else - appendLogText(i18n("Job '%1' is repeating, looping indefinitely.", currentJob->getName())); + appendLogText(i18n("Job '%1' is repeating, looping indefinitely.", activeJob()->getName())); - /* currentJob remains the same */ + /* getActiveJob() remains the same */ TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_JOBCHECK).toLatin1().data()); - setupNextIteration(RUN_JOBCHECK); + moduleState()->setupNextIteration(RUN_JOBCHECK); } - else if (currentJob->getCompletionCondition() == SchedulerJob::FINISH_AT) + else if (activeJob()->getCompletionCondition() == FINISH_AT) { - if (getLocalTime().secsTo(currentJob->getCompletionTime()) <= 0) + if (SchedulerModuleState::getLocalTime().secsTo(activeJob()->getCompletionTime()) <= 0) { - emit jobEnded(currentJob->getName(), currentJob->getStopReason()); + emit jobEnded(activeJob()->getName(), activeJob()->getStopReason()); /* Mark the job idle as well as all its duplicates for re-evaluation */ - foreach(SchedulerJob *a_job, jobs) - if (a_job == currentJob || a_job->isDuplicateOf(currentJob)) + foreach(SchedulerJob *a_job, moduleState()->jobs()) + if (a_job == activeJob() || a_job->isDuplicateOf(activeJob())) a_job->setState(SchedulerJob::JOB_IDLE); stopCurrentJobAction(); - captureBatch = 0; + moduleState()->resetCaptureBatch(); appendLogText(i18np("Job '%1' stopping, reached completion time with #%2 batch done.", "Job '%1' stopping, reached completion time with #%2 batches done.", - currentJob->getName(), captureBatch + 1)); + activeJob()->getName(), moduleState()->captureBatch() + 1)); // Always reset job stage - currentJob->setStage(SchedulerJob::STAGE_IDLE); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); setCurrentJob(nullptr); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } else { - if (executeJob(currentJob) == false) + if (executeJob(activeJob()) == false) return; - if (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN && Options::forceAlignmentBeforeJob()) { - stopGuiding(); - currentJob->setStage(SchedulerJob::STAGE_ALIGNING); - startAstrometry(); + process()->stopGuiding(); + activeJob()->setStage(SchedulerJob::STAGE_ALIGNING); + process()->startAstrometry(); } else { - currentJob->setStage(SchedulerJob::STAGE_CAPTURING); - startCapture(); + activeJob()->setStage(SchedulerJob::STAGE_CAPTURING); + process()->startCapture(); } - captureBatch++; + moduleState()->increaseCaptureBatch(); appendLogText(i18np("Job '%1' completed #%2 batch before completion time, restarted.", "Job '%1' completed #%2 batches before completion time, restarted.", - currentJob->getName(), captureBatch)); - /* currentJob remains the same */ + activeJob()->getName(), moduleState()->captureBatch())); + /* getActiveJob() remains the same */ TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_JOBCHECK).toLatin1().data()); - setupNextIteration(RUN_JOBCHECK); + moduleState()->setupNextIteration(RUN_JOBCHECK); } } else { /* Unexpected situation, mitigate by resetting the job and restarting the scheduler timer */ - qCDebug(KSTARS_EKOS_SCHEDULER) << "BUGBUG! Job '" << currentJob->getName() << "' timer elapsed, but no action to be taken."; + qCDebug(KSTARS_EKOS_SCHEDULER) << "BUGBUG! Job '" << activeJob()->getName() << + "' timer elapsed, but no action to be taken."; // Always reset job stage - currentJob->setStage(SchedulerJob::STAGE_IDLE); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); setCurrentJob(nullptr); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); - } -} - -void Scheduler::startAstrometry() -{ - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, "Job starting aligning must be valid"); - - QDBusMessage reply; - setSolverAction(Align::GOTO_SLEW); - - // Always turn update coords on - //QVariant arg(true); - //alignInterface->call(QDBus::AutoDetect, "setUpdateCoords", arg); - - // Reset the solver speedup (using the last successful index file and healpix for the - // pointing check) when re-aligning. - m_IndexToUse = -1; - m_HealpixToUse = -1; - - // If FITS file is specified, then we use load and slew - if (currentJob->getFITSFile().isEmpty() == false) - { - auto path = currentJob->getFITSFile().toString(QUrl::PreferLocalFile); - // check if the file exists - if (QFile::exists(path) == false) - { - appendLogText(i18n("Warning: job '%1' target FITS file does not exist.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - return; - } - - QList solveArgs; - solveArgs.append(path); - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "alignInterface", "loadAndSlew"); - if ((reply = alignInterface->callWithArgumentList(QDBus::AutoDetect, "loadAndSlew", solveArgs)).type() == - QDBusMessage::ErrorMessage) - { - appendLogText(i18n("Warning: job '%1' loadAndSlew request received DBUS error: %2", - currentJob->getName(), reply.errorMessage())); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - else if (reply.arguments().first().toBool() == false) - { - appendLogText(i18n("Warning: job '%1' loadAndSlew request failed.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); - findNextJob(); - return; - } - - loadAndSlewProgress = true; - appendLogText(i18n("Job '%1' is plate solving %2.", currentJob->getName(), currentJob->getFITSFile().fileName())); - } - else - { - // JM 2020.08.20: Send J2000 TargetCoords to Align module so that we always resort back to the - // target original targets even if we drifted away due to any reason like guiding calibration failures. - const SkyPoint targetCoords = currentJob->getTargetCoords(); - QList targetArgs, rotationArgs; - targetArgs << targetCoords.ra0().Hours() << targetCoords.dec0().Degrees(); - rotationArgs << currentJob->getPositionAngle(); - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "alignInterface", "setTargetCoords"); - if ((reply = alignInterface->callWithArgumentList(QDBus::AutoDetect, "setTargetCoords", - targetArgs)).type() == QDBusMessage::ErrorMessage) - { - appendLogText(i18n("Warning: job '%1' setTargetCoords request received DBUS error: %2", - currentJob->getName(), reply.errorMessage())); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - - // Only send if it has valid value. - if (currentJob->getPositionAngle() >= -180) - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "alignInterface", "setTargetPositionAngle"); - if ((reply = alignInterface->callWithArgumentList(QDBus::AutoDetect, "setTargetPositionAngle", - rotationArgs)).type() == QDBusMessage::ErrorMessage) - { - appendLogText(i18n("Warning: job '%1' setTargetPositionAngle request received DBUS error: %2").arg( - currentJob->getName(), reply.errorMessage())); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): sending %s\n", __LINE__, "alignInterface", "captureAndSolve"); - if ((reply = alignInterface->call(QDBus::AutoDetect, "captureAndSolve")).type() == QDBusMessage::ErrorMessage) - { - appendLogText(i18n("Warning: job '%1' captureAndSolve request received DBUS error: %2").arg( - currentJob->getName(), reply.errorMessage())); - if (!manageConnectionLoss()) - { - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - return; - } - else if (reply.arguments().first().toBool() == false) - { - appendLogText(i18n("Warning: job '%1' captureAndSolve request failed.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); - findNextJob(); - return; - } - - appendLogText(i18n("Job '%1' is capturing and plate solving.", currentJob->getName())); + moduleState()->setupNextIteration(RUN_SCHEDULER); } - - /* FIXME: not supposed to modify the job */ - currentJob->setStage(SchedulerJob::STAGE_ALIGNING); - startCurrentOperationTimer(); -} - -void Scheduler::startGuiding(bool resetCalibration) -{ - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, "Job starting guiding must be valid"); - - // avoid starting the guider twice - if (resetCalibration == false && getGuidingStatus() == GUIDE_GUIDING) - { - appendLogText(i18n("Guiding already running for %1 ...", currentJob->getName())); - currentJob->setStage(SchedulerJob::STAGE_GUIDING); - startCurrentOperationTimer(); - return; - } - - // Connect Guider - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:call", "connectGuider"); - guideInterface->call(QDBus::AutoDetect, "connectGuider"); - - // Set Auto Star to true - QVariant arg(true); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:call", "setAutoStarEnabled"); - guideInterface->call(QDBus::AutoDetect, "setAutoStarEnabled", arg); - - // Only reset calibration on trouble - // and if we are allowed to reset calibration (true by default) - if (resetCalibration && Options::resetGuideCalibration()) - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:call", "clearCalibration"); - guideInterface->call(QDBus::AutoDetect, "clearCalibration"); - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:call", "guide"); - guideInterface->call(QDBus::AutoDetect, "guide"); - - currentJob->setStage(SchedulerJob::STAGE_GUIDING); - - appendLogText(i18n("Starting guiding procedure for %1 ...", currentJob->getName())); - - startCurrentOperationTimer(); -} - -void Scheduler::startCapture(bool restart) -{ - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, "Job starting capturing must be valid"); - - // ensure that guiding is running before we start capturing - if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE && getGuidingStatus() != GUIDE_GUIDING) - { - // guiding should run, but it doesn't. So start guiding first - currentJob->setStage(SchedulerJob::STAGE_GUIDING); - startGuiding(); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s%s\n", __LINE__, "captureInterface:setProperty", "targetName=", - currentJob->getName().toLatin1().data()); - captureInterface->setProperty("targetName", currentJob->getName()); - - QString url = currentJob->getSequenceFile().toLocalFile(); - - if (restart == false) - { - QList dbusargs; - dbusargs.append(url); - // ignore targets from sequence queue file - QVariant ignoreTarget(true); - dbusargs.append(ignoreTarget); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:callWithArgs", "loadSequenceQueue"); - QDBusReply const captureReply = captureInterface->callWithArgumentList(QDBus::AutoDetect, "loadSequenceQueue", - dbusargs); - if (captureReply.error().type() != QDBusError::NoError) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << - QString("Warning: job '%1' loadSequenceQueue request received DBUS error: %1").arg(currentJob->getName()).arg( - captureReply.error().message()); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); - return; - } - // Check if loading sequence fails for whatever reason - else if (captureReply.value() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << - QString("Warning: job '%1' loadSequenceQueue request failed").arg(currentJob->getName()); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); - return; - } - } - - - SchedulerJob::CapturedFramesMap fMap = currentJob->getCapturedFramesMap(); - - for (auto &e : fMap.keys()) - { - QList dbusargs; - QDBusMessage reply; - - dbusargs.append(e); - dbusargs.append(fMap.value(e)); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:callWithArgs", "setCapturedFramesMap"); - if ((reply = captureInterface->callWithArgumentList(QDBus::AutoDetect, "setCapturedFramesMap", dbusargs)).type() == - QDBusMessage::ErrorMessage) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << - QString("Warning: job '%1' setCapturedFramesCount request received DBUS error: %1").arg(currentJob->getName()).arg( - reply.errorMessage()); - if (!manageConnectionLoss()) - currentJob->setState(SchedulerJob::JOB_ERROR); - return; - } - } - - // Start capture process - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:call", "start"); - captureInterface->call(QDBus::AutoDetect, "start"); - - currentJob->setStage(SchedulerJob::STAGE_CAPTURING); - - KSNotification::event(QLatin1String("EkosScheduledImagingStart"), - i18n("Ekos job (%1) - Capture started", currentJob->getName()), KSNotification::Scheduler); - - if (captureBatch > 0) - appendLogText(i18n("Job '%1' capture is in progress (batch #%2)...", currentJob->getName(), captureBatch + 1)); - else - appendLogText(i18n("Job '%1' capture is in progress...", currentJob->getName())); - - startCurrentOperationTimer(); -} - -void Scheduler::stopGuiding() -{ - if (!guideInterface) - return; - - // Tell guider to abort if the current job requires guiding - end-user may enable guiding manually before observation - if (nullptr != currentJob && (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE)) - { - qCInfo(KSTARS_EKOS_SCHEDULER) << QString("Job '%1' is stopping guiding...").arg(currentJob->getName()); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:call", "abort"); - guideInterface->call(QDBus::AutoDetect, "abort"); - guideFailureCount = 0; - } - - // In any case, stop the automatic guider restart - if (isGuidingTimerActive()) - cancelGuidingTimer(); -} - -void Scheduler::setSolverAction(Align::GotoMode mode) -{ - QVariant gotoMode(static_cast(mode)); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "alignInterface:call", "setSolverAction"); - alignInterface->call(QDBus::AutoDetect, "setSolverAction", gotoMode); -} - -void Scheduler::disconnectINDI() -{ - qCInfo(KSTARS_EKOS_SCHEDULER) << "Disconnecting INDI..."; - setIndiState(INDI_DISCONNECTING); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "ekosInterface:call", "disconnectDevices"); - ekosInterface->call(QDBus::AutoDetect, "disconnectDevices"); -} - -void Scheduler::stopEkos() -{ - qCInfo(KSTARS_EKOS_SCHEDULER) << "Stopping Ekos..."; - setEkosState(EKOS_STOPPING); - ekosConnectFailureCount = 0; - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "ekosInterface:call", "stop"); - ekosInterface->call(QDBus::AutoDetect, "stop"); - m_MountReady = m_CapReady = m_CaptureReady = m_DomeReady = false; } void Scheduler::setDirty() { - mDirty = true; + moduleState()->setDirty(true); if (sender() == startupProcedureButtonGroup || sender() == shutdownProcedureGroup) return; - if (0 <= jobUnderEdit && state != SCHEDULER_RUNNING && 0 <= queueTable->currentRow()) + // update state + if (sender() == startupScript) + moduleState()->setStartupScriptURL(QUrl::fromUserInput(startupScript->text())); + else if (sender() == shutdownScript) + moduleState()->setShutdownScriptURL(QUrl::fromUserInput(shutdownScript->text())); + + if (0 <= jobUnderEdit && moduleState()->schedulerState() != SCHEDULER_RUNNING && 0 <= queueTable->currentRow()) { // Now that jobs are sorted, reset jobs that are later than the edited one for re-evaluation - for (int row = jobUnderEdit; row < jobs.size(); row++) - jobs.at(row)->reset(); + for (int row = jobUnderEdit; row < moduleState()->jobs().size(); row++) + moduleState()->jobs().at(row)->reset(); saveJob(); } @@ -4838,8 +3328,8 @@ QMap expected; switch (oneJob->getCompletionCondition()) { - case SchedulerJob::FINISH_SEQUENCE: - case SchedulerJob::FINISH_REPEAT: + case FINISH_SEQUENCE: + case FINISH_REPEAT: // Step 1: determine expected frames calculateExpectedCapturesMap(seqjobs, expected); // Step 2: compare with already captured frames @@ -4902,7 +3392,7 @@ } // If this condition is FINISH_REPEAT, and we've already completed enough iterations // Then set the currentIteratiion as 1 more than required. No need to go higher. - if (schedJob.getCompletionCondition() == SchedulerJob::FINISH_REPEAT + if (schedJob.getCompletionCondition() == FINISH_REPEAT && minIterationsCompleted >= schedJob.getRepeatsRequired()) currentIteration = schedJob.getRepeatsRequired() + 1; else @@ -4938,7 +3428,7 @@ capture_map[key] = 0; // collect all captured frames counts - if (schedJob.getCompletionCondition() == SchedulerJob::FINISH_LOOP) + if (schedJob.getCompletionCondition() == FINISH_LOOP) totalCompletedCount += capturedFramesCount[key]; else totalCompletedCount += std::min(capturedFramesCount[key], @@ -4955,17 +3445,18 @@ /* FIXME: Capture storage cache is refreshed too often, feature requires rework. */ /* Check if one job is idle or requires evaluation - if so, force refresh */ - forced |= std::any_of(jobs.begin(), jobs.end(), [](SchedulerJob * oneJob) -> bool + forced |= std::any_of(moduleState()->jobs().begin(), + moduleState()->jobs().end(), [](SchedulerJob * oneJob) -> bool { SchedulerJob::JOBStatus const state = oneJob->getState(); return state == SchedulerJob::JOB_IDLE || state == SchedulerJob::JOB_EVALUATION;}); /* If update is forced, clear the frame map */ if (forced) - m_CapturedFramesCount.clear(); + moduleState()->capturedFramesCount().clear(); /* Enumerate SchedulerJobs to count captures that are already stored */ - for (SchedulerJob *oneJob : jobs) + for (SchedulerJob *oneJob : moduleState()->jobs()) { QList seqjobs; bool hasAutoFocus = false; @@ -4997,8 +3488,9 @@ continue; /* If signature was processed during an earlier run, use the earlier count */ - QMap::const_iterator const earlierRunIterator = m_CapturedFramesCount.constFind(signature); - if (m_CapturedFramesCount.constEnd() != earlierRunIterator) + QMap::const_iterator const earlierRunIterator = moduleState()->capturedFramesCount().constFind( + signature); + if (moduleState()->capturedFramesCount().constEnd() != earlierRunIterator) { newFramesCount[signature] = earlierRunIterator.value(); continue; @@ -5012,12 +3504,12 @@ updateLightFramesRequired(oneJob, seqjobs, newFramesCount); } - m_CapturedFramesCount = newFramesCount; + moduleState()->setCapturedFramesCount(newFramesCount); { qCDebug(KSTARS_EKOS_SCHEDULER) << "Frame map summary:"; - QMap::const_iterator it = m_CapturedFramesCount.constBegin(); - for (; it != m_CapturedFramesCount.constEnd(); it++) + QMap::const_iterator it = moduleState()->capturedFramesCount().constBegin(); + for (; it != moduleState()->capturedFramesCount().constEnd(); it++) qCDebug(KSTARS_EKOS_SCHEDULER) << " " << it.key() << ':' << it.value(); } } @@ -5100,7 +3592,7 @@ capturesLeftThisRepeat = 0; } - if (rememberJobProgress && schedJob->getCompletionCondition() != SchedulerJob::FINISH_LOOP) + if (rememberJobProgress && schedJob->getCompletionCondition() != FINISH_LOOP) { /* Enumerate sequence jobs associated to this scheduler job, and assign them a completed count. * @@ -5187,11 +3679,11 @@ } /* If captures are not complete, we have imaging time left */ - if (!areJobCapturesComplete || schedJob->getCompletionCondition() == SchedulerJob::FINISH_LOOP) + if (!areJobCapturesComplete || schedJob->getCompletionCondition() == FINISH_LOOP) { unsigned int const captures_to_go = captures_required - captures_completed; const double secsPerCapture = (seqJob->getCoreProperty(SequenceJob::SJ_Exposure).toDouble() + - seqJob->getCoreProperty(SequenceJob::SJ_Delay).toInt()); + (seqJob->getCoreProperty(SequenceJob::SJ_Delay).toInt() / 1000.0)); totalImagingTime += fabs(secsPerCapture * captures_to_go); imagingTimePerRepeat += fabs(secsPerCapture * seqJob->getCoreProperty(SequenceJob::SJ_Count).toInt()); imagingTimeLeftThisRepeat += fabs(secsPerCapture * capturesLeftThisRepeat); @@ -5238,7 +3730,7 @@ // FIXME: Move those ifs away to the caller in order to avoid estimating in those situations! // We can't estimate times that do not finish when sequence is done - if (schedJob->getCompletionCondition() == SchedulerJob::FINISH_LOOP) + if (schedJob->getCompletionCondition() == FINISH_LOOP) { // We can't know estimated time if it is looping indefinitely schedJob->setEstimatedTime(-2); @@ -5247,8 +3739,8 @@ .arg(schedJob->getName()); } // If we know startup and finish times, we can estimate time right away - else if (schedJob->getStartupCondition() == SchedulerJob::START_AT && - schedJob->getCompletionCondition() == SchedulerJob::FINISH_AT) + else if (schedJob->getStartupCondition() == START_AT && + schedJob->getCompletionCondition() == FINISH_AT) { // FIXME: SchedulerJob is probably doing this already qint64 const diff = schedJob->getStartupTime().secsTo(schedJob->getCompletionTime()); @@ -5259,10 +3751,10 @@ .arg(dms(diff * 15.0 / 3600.0f).toHMSString()); } // If we know finish time only, we can roughly estimate the time considering the job starts now - else if (schedJob->getStartupCondition() != SchedulerJob::START_AT && - schedJob->getCompletionCondition() == SchedulerJob::FINISH_AT) + else if (schedJob->getStartupCondition() != START_AT && + schedJob->getCompletionCondition() == FINISH_AT) { - qint64 const diff = getLocalTime().secsTo(schedJob->getCompletionTime()); + qint64 const diff = SchedulerModuleState::getLocalTime().secsTo(schedJob->getCompletionTime()); schedJob->setEstimatedTime(diff); qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Job '%1' has no startup time but fixed completion time, will run for %2 if started now.") @@ -5331,717 +3823,6 @@ return imagingTime; } -void Scheduler::parkMount() -{ - if (mountInterface.isNull()) - { - appendLogText(i18n("Mount park requested but no mounts detected.")); - setShutdownState(SHUTDOWN_ERROR); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "parkStatus"); - QVariant parkingStatus = mountInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - switch (status) - { - case ISD::PARK_PARKED: - if (shutdownState == SHUTDOWN_PARK_MOUNT) - setShutdownState(SHUTDOWN_PARK_DOME); - - setParkWaitState(PARKWAIT_PARKED); - appendLogText(i18n("Mount already parked.")); - break; - - case ISD::PARK_UNPARKING: - //case Mount::UNPARKING_BUSY: - /* FIXME: Handle the situation where we request parking but an unparking procedure is running. */ - - // case Mount::PARKING_IDLE: - // case Mount::UNPARKING_OK: - case ISD::PARK_ERROR: - case ISD::PARK_UNKNOWN: - case ISD::PARK_UNPARKED: - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "park"); - QDBusReply const mountReply = mountInterface->call(QDBus::AutoDetect, "park"); - - if (mountReply.error().type() != QDBusError::NoError) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount park request received DBUS error: %1").arg( - QDBusError::errorString(mountReply.error().type())); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - else startCurrentOperationTimer(); - } - - // Fall through - case ISD::PARK_PARKING: - //case Mount::PARKING_BUSY: - if (shutdownState == SHUTDOWN_PARK_MOUNT) - setShutdownState(SHUTDOWN_PARKING_MOUNT); - - setParkWaitState(PARKWAIT_PARKING); - appendLogText(i18n("Parking mount in progress...")); - break; - - // All cases covered above so no need for default - //default: - // qCWarning(KSTARS_EKOS_SCHEDULER) << QString("BUG: Parking state %1 not managed while parking mount.").arg(mountReply.value()); - } -} - -void Scheduler::unParkMount() -{ - if (mountInterface.isNull()) - { - appendLogText(i18n("Mount unpark requested but no mounts detected.")); - setStartupState(STARTUP_ERROR); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "parkStatus"); - QVariant parkingStatus = mountInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - switch (status) - { - //case Mount::UNPARKING_OK: - case ISD::PARK_UNPARKED: - if (startupState == STARTUP_UNPARK_MOUNT) - setStartupState(STARTUP_UNPARK_CAP); - - setParkWaitState(PARKWAIT_UNPARKED); - appendLogText(i18n("Mount already unparked.")); - break; - - //case Mount::PARKING_BUSY: - case ISD::PARK_PARKING: - /* FIXME: Handle the situation where we request unparking but a parking procedure is running. */ - - // case Mount::PARKING_IDLE: - // case Mount::PARKING_OK: - // case Mount::PARKING_ERROR: - case ISD::PARK_ERROR: - case ISD::PARK_UNKNOWN: - case ISD::PARK_PARKED: - { - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "unpark"); - QDBusReply const mountReply = mountInterface->call(QDBus::AutoDetect, "unpark"); - - if (mountReply.error().type() != QDBusError::NoError) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount unpark request received DBUS error: %1").arg( - QDBusError::errorString(mountReply.error().type())); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - else startCurrentOperationTimer(); - } - - // Fall through - //case Mount::UNPARKING_BUSY: - case ISD::PARK_UNPARKING: - if (startupState == STARTUP_UNPARK_MOUNT) - setStartupState(STARTUP_UNPARKING_MOUNT); - - setParkWaitState(PARKWAIT_UNPARKING); - qCInfo(KSTARS_EKOS_SCHEDULER) << "Unparking mount in progress..."; - break; - - // All cases covered above - //default: - // qCWarning(KSTARS_EKOS_SCHEDULER) << QString("BUG: Parking state %1 not managed while unparking mount.").arg(mountReply.value()); - } -} - -void Scheduler::checkMountParkingStatus() -{ - if (mountInterface.isNull()) - return; - - static int parkingFailureCount = 0; - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "parkStatus"); - QVariant parkingStatus = mountInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - switch (status) - { - //case Mount::PARKING_OK: - case ISD::PARK_PARKED: - // If we are starting up, we will unpark the mount in checkParkWaitState soon - // If we are shutting down and mount is parked, proceed to next step - if (shutdownState == SHUTDOWN_PARKING_MOUNT) - setShutdownState(SHUTDOWN_PARK_DOME); - - // Update parking engine state - if (parkWaitState == PARKWAIT_PARKING) - setParkWaitState(PARKWAIT_PARKED); - - appendLogText(i18n("Mount parked.")); - parkingFailureCount = 0; - break; - - //case Mount::UNPARKING_OK: - case ISD::PARK_UNPARKED: - // If we are starting up and mount is unparked, proceed to next step - // If we are shutting down, we will park the mount in checkParkWaitState soon - if (startupState == STARTUP_UNPARKING_MOUNT) - setStartupState(STARTUP_UNPARK_CAP); - - // Update parking engine state - if (parkWaitState == PARKWAIT_UNPARKING) - setParkWaitState(PARKWAIT_UNPARKED); - - appendLogText(i18n("Mount unparked.")); - parkingFailureCount = 0; - break; - - // FIXME: Create an option for the parking/unparking timeout. - - //case Mount::UNPARKING_BUSY: - case ISD::PARK_UNPARKING: - if (getCurrentOperationMsec() > (60 * 1000)) - { - if (++parkingFailureCount < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Warning: mount unpark operation timed out on attempt %1/%2. Restarting operation...", - parkingFailureCount, MAX_FAILURE_ATTEMPTS)); - unParkMount(); - } - else - { - appendLogText(i18n("Warning: mount unpark operation timed out on last attempt.")); - setParkWaitState(PARKWAIT_ERROR); - } - } - else qCInfo(KSTARS_EKOS_SCHEDULER) << "Unparking mount in progress..."; - - break; - - //case Mount::PARKING_BUSY: - case ISD::PARK_PARKING: - if (getCurrentOperationMsec() > (60 * 1000)) - { - if (++parkingFailureCount < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Warning: mount park operation timed out on attempt %1/%2. Restarting operation...", parkingFailureCount, - MAX_FAILURE_ATTEMPTS)); - parkMount(); - } - else - { - appendLogText(i18n("Warning: mount park operation timed out on last attempt.")); - setParkWaitState(PARKWAIT_ERROR); - } - } - else qCInfo(KSTARS_EKOS_SCHEDULER) << "Parking mount in progress..."; - - break; - - //case Mount::PARKING_ERROR: - case ISD::PARK_ERROR: - if (startupState == STARTUP_UNPARKING_MOUNT) - { - appendLogText(i18n("Mount unparking error.")); - setStartupState(STARTUP_ERROR); - parkingFailureCount = 0; - } - else if (shutdownState == SHUTDOWN_PARKING_MOUNT) - { - if (++parkingFailureCount < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Warning: mount park operation failed on attempt %1/%2. Restarting operation...", parkingFailureCount, - MAX_FAILURE_ATTEMPTS)); - parkMount(); - } - else - { - appendLogText(i18n("Mount parking error.")); - setShutdownState(SHUTDOWN_ERROR); - parkingFailureCount = 0; - } - - } - else if (parkWaitState == PARKWAIT_PARKING) - { - appendLogText(i18n("Mount parking error.")); - setParkWaitState(PARKWAIT_ERROR); - parkingFailureCount = 0; - } - else if (parkWaitState == PARKWAIT_UNPARKING) - { - appendLogText(i18n("Mount unparking error.")); - setParkWaitState(PARKWAIT_ERROR); - parkingFailureCount = 0; - } - break; - - //case Mount::PARKING_IDLE: - // FIXME Does this work as intended? check! - case ISD::PARK_UNKNOWN: - // Last parking action did not result in an action, so proceed to next step - if (shutdownState == SHUTDOWN_PARKING_MOUNT) - setShutdownState(SHUTDOWN_PARK_DOME); - - // Last unparking action did not result in an action, so proceed to next step - if (startupState == STARTUP_UNPARKING_MOUNT) - setStartupState(STARTUP_UNPARK_CAP); - - // Update parking engine state - if (parkWaitState == PARKWAIT_PARKING) - setParkWaitState(PARKWAIT_PARKED); - else if (parkWaitState == PARKWAIT_UNPARKING) - setParkWaitState(PARKWAIT_UNPARKED); - - parkingFailureCount = 0; - break; - - // All cases covered above - //default: - // qCWarning(KSTARS_EKOS_SCHEDULER) << QString("BUG: Parking state %1 not managed while checking progress.").arg(mountReply.value()); - } -} - -bool Scheduler::isMountParked() -{ - if (mountInterface.isNull()) - return false; - // First check if the mount is able to park - if it isn't, getParkingStatus will reply PARKING_ERROR and status won't be clear - //QDBusReply const parkCapableReply = mountInterface->call(QDBus::AutoDetect, "canPark"); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "canPark"); - QVariant canPark = mountInterface->property("canPark"); - TEST_PRINT(stderr, " @@@dbus received %s\n", !canPark.isValid() ? "invalid" : (canPark.toBool() ? "T" : "F")); - - if (canPark.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount canPark request received DBUS error: %1").arg( - mountInterface->lastError().type()); - manageConnectionLoss(); - return false; - } - else if (canPark.toBool() == true) - { - // If it is able to park, obtain its current status - //QDBusReply const mountReply = mountInterface->call(QDBus::AutoDetect, "getParkingStatus"); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "parkStatus"); - QVariant parkingStatus = mountInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parking status property is invalid %1.").arg( - mountInterface->lastError().type()); - manageConnectionLoss(); - return false; - } - - // Deduce state of mount - see getParkingStatus in mount.cpp - switch (static_cast(parkingStatus.toInt())) - { - // case Mount::PARKING_OK: // INDI switch ok, and parked - // case Mount::PARKING_IDLE: // INDI switch idle, and parked - case ISD::PARK_PARKED: - return true; - - // case Mount::UNPARKING_OK: // INDI switch idle or ok, and unparked - // case Mount::PARKING_ERROR: // INDI switch error - // case Mount::PARKING_BUSY: // INDI switch busy - // case Mount::UNPARKING_BUSY: // INDI switch busy - default: - return false; - } - } - // If the mount is not able to park, consider it not parked - return false; -} - -void Scheduler::parkDome() -{ - // If there is no dome, mark error - if (domeInterface.isNull()) - { - appendLogText(i18n("Dome park requested but no domes detected.")); - setShutdownState(SHUTDOWN_ERROR); - return; - } - - //QDBusReply const domeReply = domeInterface->call(QDBus::AutoDetect, "getParkingStatus"); - //Dome::ParkingStatus status = static_cast(domeReply.value()); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "parkStatus"); - QVariant parkingStatus = domeInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - if (status != ISD::PARK_PARKED) - { - setShutdownState(SHUTDOWN_PARKING_DOME); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:call", "park"); - domeInterface->call(QDBus::AutoDetect, "park"); - appendLogText(i18n("Parking dome...")); - - startCurrentOperationTimer(); - } - else - { - appendLogText(i18n("Dome already parked.")); - setShutdownState(SHUTDOWN_SCRIPT); - } -} - -void Scheduler::unParkDome() -{ - // If there is no dome, mark error - if (domeInterface.isNull()) - { - appendLogText(i18n("Dome unpark requested but no domes detected.")); - setStartupState(STARTUP_ERROR); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "parkStatus"); - QVariant parkingStatus = domeInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - if (static_cast(parkingStatus.toInt()) != ISD::PARK_UNPARKED) - { - setStartupState(STARTUP_UNPARKING_DOME); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:call", "unpark"); - domeInterface->call(QDBus::AutoDetect, "unpark"); - appendLogText(i18n("Unparking dome...")); - - startCurrentOperationTimer(); - } - else - { - appendLogText(i18n("Dome already unparked.")); - setStartupState(STARTUP_UNPARK_MOUNT); - } -} - -void Scheduler::checkDomeParkingStatus() -{ - if (domeInterface.isNull()) - return; - - /* FIXME: move this elsewhere */ - static int parkingFailureCount = 0; - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "parkStatus"); - QVariant parkingStatus = domeInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - setParkWaitState(PARKWAIT_ERROR); - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - switch (status) - { - case ISD::PARK_PARKED: - if (shutdownState == SHUTDOWN_PARKING_DOME) - { - appendLogText(i18n("Dome parked.")); - - setShutdownState(SHUTDOWN_SCRIPT); - } - parkingFailureCount = 0; - break; - - case ISD::PARK_UNPARKED: - if (startupState == STARTUP_UNPARKING_DOME) - { - setStartupState(STARTUP_UNPARK_MOUNT); - appendLogText(i18n("Dome unparked.")); - } - parkingFailureCount = 0; - break; - - case ISD::PARK_PARKING: - case ISD::PARK_UNPARKING: - // TODO make the timeouts configurable by the user - if (getCurrentOperationMsec() > (120 * 1000)) - { - if (parkingFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Operation timeout. Restarting operation...")); - if (status == ISD::PARK_PARKING) - parkDome(); - else - unParkDome(); - break; - } - } - break; - - case ISD::PARK_ERROR: - if (shutdownState == SHUTDOWN_PARKING_DOME) - { - if (parkingFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Dome parking failed. Restarting operation...")); - parkDome(); - } - else - { - appendLogText(i18n("Dome parking error.")); - setShutdownState(SHUTDOWN_ERROR); - parkingFailureCount = 0; - } - } - else if (startupState == STARTUP_UNPARKING_DOME) - { - if (parkingFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Dome unparking failed. Restarting operation...")); - unParkDome(); - } - else - { - appendLogText(i18n("Dome unparking error.")); - setStartupState(STARTUP_ERROR); - parkingFailureCount = 0; - } - } - break; - - default: - break; - } -} - -bool Scheduler::isDomeParked() -{ - if (domeInterface.isNull()) - return false; - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "parkStatus"); - QVariant parkingStatus = domeInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - return status == ISD::PARK_PARKED; -} - -void Scheduler::parkCap() -{ - if (capInterface.isNull()) - { - appendLogText(i18n("Dust cover park requested but no dust covers detected.")); - setShutdownState(SHUTDOWN_ERROR); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "dustCapInterface:property", "parkStatus"); - QVariant parkingStatus = capInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - if (status != ISD::PARK_PARKED) - { - setShutdownState(SHUTDOWN_PARKING_CAP); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "distCapInterface:call", "park"); - capInterface->call(QDBus::AutoDetect, "park"); - appendLogText(i18n("Parking Cap...")); - - startCurrentOperationTimer(); - } - else - { - appendLogText(i18n("Cap already parked.")); - setShutdownState(SHUTDOWN_PARK_MOUNT); - } -} - -void Scheduler::unParkCap() -{ - if (capInterface.isNull()) - { - appendLogText(i18n("Dust cover unpark requested but no dust covers detected.")); - setStartupState(STARTUP_ERROR); - return; - } - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "dustCapInterface:property", "parkStatus"); - QVariant parkingStatus = capInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( - mountInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - if (status != ISD::PARK_UNPARKED) - { - setStartupState(STARTUP_UNPARKING_CAP); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "dustCapInterface:call", "unpark"); - capInterface->call(QDBus::AutoDetect, "unpark"); - appendLogText(i18n("Unparking cap...")); - - startCurrentOperationTimer(); - } - else - { - appendLogText(i18n("Cap already unparked.")); - setStartupState(STARTUP_COMPLETE); - } -} - -void Scheduler::checkCapParkingStatus() -{ - if (capInterface.isNull()) - return; - - /* FIXME: move this elsewhere */ - static int parkingFailureCount = 0; - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "dustCapInterface:property", "parkStatus"); - QVariant parkingStatus = capInterface->property("parkStatus"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !parkingStatus.isValid() ? -1 : parkingStatus.toInt()); - - if (parkingStatus.isValid() == false) - { - qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( - capInterface->lastError().type()); - if (!manageConnectionLoss()) - parkingStatus = ISD::PARK_ERROR; - } - - ISD::ParkStatus status = static_cast(parkingStatus.toInt()); - - switch (status) - { - case ISD::PARK_PARKED: - if (shutdownState == SHUTDOWN_PARKING_CAP) - { - appendLogText(i18n("Cap parked.")); - setShutdownState(SHUTDOWN_PARK_MOUNT); - } - parkingFailureCount = 0; - break; - - case ISD::PARK_UNPARKED: - if (startupState == STARTUP_UNPARKING_CAP) - { - setStartupState(STARTUP_COMPLETE); - appendLogText(i18n("Cap unparked.")); - } - parkingFailureCount = 0; - break; - - case ISD::PARK_PARKING: - case ISD::PARK_UNPARKING: - // TODO make the timeouts configurable by the user - if (getCurrentOperationMsec() > (60 * 1000)) - { - if (parkingFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Operation timeout. Restarting operation...")); - if (status == ISD::PARK_PARKING) - parkCap(); - else - unParkCap(); - break; - } - } - break; - - case ISD::PARK_ERROR: - if (shutdownState == SHUTDOWN_PARKING_CAP) - { - appendLogText(i18n("Cap parking error.")); - setShutdownState(SHUTDOWN_ERROR); - } - else if (startupState == STARTUP_UNPARKING_CAP) - { - appendLogText(i18n("Cap unparking error.")); - setStartupState(STARTUP_ERROR); - } - parkingFailureCount = 0; - break; - - default: - break; - } -} - void Scheduler::startJobEvaluation() { // Reset all jobs @@ -6061,7 +3842,7 @@ setCurrentJob(nullptr); // Reset ALL scheduler jobs to IDLE and force-reset their completed count - no effect when progress is kept - for (SchedulerJob * job : jobs) + for (SchedulerJob * job : moduleState()->jobs()) { job->reset(); job->setCompletedCount(0); @@ -6074,7 +3855,7 @@ void Scheduler::sortJobsPerAltitude() { // We require a first job to sort, so bail out if list is empty - if (jobs.isEmpty()) + if (moduleState()->jobs().isEmpty()) return; // Don't reset current job @@ -6084,14 +3865,14 @@ // Sort by startup time, using the first job time as reference for altitude calculations using namespace std::placeholders; - QList sortedJobs = jobs; + QList sortedJobs = moduleState()->jobs(); std::stable_sort(sortedJobs.begin() + 1, sortedJobs.end(), - std::bind(SchedulerJob::decreasingAltitudeOrder, _1, _2, jobs.first()->getStartupTime())); + std::bind(SchedulerJob::decreasingAltitudeOrder, _1, _2, moduleState()->jobs().first()->getStartupTime())); // If order changed, reset and re-evaluate if (reorderJobs(sortedJobs)) { - for (SchedulerJob * job : jobs) + for (SchedulerJob * job : moduleState()->jobs()) job->reset(); evaluateJobs(true); @@ -6102,10 +3883,10 @@ { disconnect(this, &Scheduler::weatherChanged, this, &Scheduler::resumeCheckStatus); TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_SCHEDULER).toLatin1().data()); - setupNextIteration(RUN_SCHEDULER); + moduleState()->setupNextIteration(RUN_SCHEDULER); } -Scheduler::ErrorHandlingStrategy Scheduler::getErrorHandlingStrategy() +ErrorHandlingStrategy Scheduler::getErrorHandlingStrategy() { // The UI holds the state if (errorHandlingRestartQueueButton->isChecked()) @@ -6114,10 +3895,9 @@ return ERROR_RESTART_IMMEDIATELY; else return ERROR_DONT_RESTART; - } -void Scheduler::setErrorHandlingStrategy(Scheduler::ErrorHandlingStrategy strategy) +void Scheduler::setErrorHandlingStrategy(ErrorHandlingStrategy strategy) { errorHandlingDelaySB->setEnabled(strategy != ERROR_DONT_RESTART); @@ -6233,11 +4013,11 @@ void Scheduler::resetAllJobs() { - if (state == SCHEDULER_RUNNING) + if (moduleState()->schedulerState() == SCHEDULER_RUNNING) return; // Reset capture count of all jobs before re-evaluating - foreach (SchedulerJob *job, jobs) + foreach (SchedulerJob *job, moduleState()->jobs()) job->setCompletedCount(0); // Evaluate all jobs, this refreshes storage and resets job states @@ -6260,192 +4040,14 @@ } } -void Scheduler::checkStartupProcedure() -{ - if (checkStartupState() == false) - QTimer::singleShot(1000, this, SLOT(checkStartupProcedure())); - else - { - if (startupState == STARTUP_COMPLETE) - appendLogText(i18n("Manual startup procedure completed successfully.")); - else if (startupState == STARTUP_ERROR) - appendLogText(i18n("Manual startup procedure terminated due to errors.")); - - startupB->setIcon( - QIcon::fromTheme("media-playback-start")); - } -} - -void Scheduler::runStartupProcedure() -{ - if (startupState == STARTUP_IDLE || startupState == STARTUP_ERROR || startupState == STARTUP_COMPLETE) - { - connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this]() - { - KSMessageBox::Instance()->disconnect(this); - - appendLogText(i18n("Warning: executing startup procedure manually...")); - startupB->setIcon( - QIcon::fromTheme("media-playback-stop")); - setStartupState(STARTUP_IDLE); - checkStartupState(); - QTimer::singleShot(1000, this, SLOT(checkStartupProcedure())); - - }); - - KSMessageBox::Instance()->questionYesNo(i18n("Are you sure you want to execute the startup procedure manually?")); - } - else - { - switch (startupState) - { - case STARTUP_IDLE: - break; - - case STARTUP_SCRIPT: - scriptProcess.terminate(); - break; - - case STARTUP_UNPARK_DOME: - break; - - case STARTUP_UNPARKING_DOME: - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:call", "abort"); - domeInterface->call(QDBus::AutoDetect, "abort"); - break; - - case STARTUP_UNPARK_MOUNT: - break; - - case STARTUP_UNPARKING_MOUNT: - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "abort"); - mountInterface->call(QDBus::AutoDetect, "abort"); - break; - - case STARTUP_UNPARK_CAP: - break; - - case STARTUP_UNPARKING_CAP: - break; - - case STARTUP_COMPLETE: - break; - - case STARTUP_ERROR: - break; - } - - setStartupState(STARTUP_IDLE); - - appendLogText(i18n("Startup procedure terminated.")); - } -} - -void Scheduler::checkShutdownProcedure() -{ - // If shutdown procedure is not finished yet, let's check again in 1 second. - if (checkShutdownState() == false) - QTimer::singleShot(1000, this, SLOT(checkShutdownProcedure())); - else - { - if (shutdownState == SHUTDOWN_COMPLETE) - { - appendLogText(i18n("Manual shutdown procedure completed successfully.")); - // Stop Ekos - if (Options::stopEkosAfterShutdown()) - stopEkos(); - } - else if (shutdownState == SHUTDOWN_ERROR) - appendLogText(i18n("Manual shutdown procedure terminated due to errors.")); - - setShutdownState(SHUTDOWN_IDLE); - shutdownB->setIcon( - QIcon::fromTheme("media-playback-start")); - } -} - -void Scheduler::runShutdownProcedure() -{ - if (shutdownState == SHUTDOWN_IDLE || shutdownState == SHUTDOWN_ERROR || shutdownState == SHUTDOWN_COMPLETE) - { - connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this]() - { - KSMessageBox::Instance()->disconnect(this); - appendLogText(i18n("Warning: executing shutdown procedure manually...")); - shutdownB->setIcon( - QIcon::fromTheme("media-playback-stop")); - setShutdownState(SHUTDOWN_IDLE); - checkShutdownState(); - QTimer::singleShot(1000, this, SLOT(checkShutdownProcedure())); - }); - - KSMessageBox::Instance()->questionYesNo(i18n("Are you sure you want to execute the shutdown procedure manually?")); - } - else - { - switch (shutdownState) - { - case SHUTDOWN_IDLE: - break; - - case SHUTDOWN_SCRIPT: - break; - - case SHUTDOWN_SCRIPT_RUNNING: - scriptProcess.terminate(); - break; - - case SHUTDOWN_PARK_DOME: - break; - - case SHUTDOWN_PARKING_DOME: - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:call", "abort"); - domeInterface->call(QDBus::AutoDetect, "abort"); - break; - case SHUTDOWN_PARK_MOUNT: - break; - - case SHUTDOWN_PARKING_MOUNT: - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "abort"); - mountInterface->call(QDBus::AutoDetect, "abort"); - break; - - case SHUTDOWN_PARK_CAP: - break; - - case SHUTDOWN_PARKING_CAP: - break; - - case SHUTDOWN_COMPLETE: - break; - - case SHUTDOWN_ERROR: - break; - } - - setShutdownState(SHUTDOWN_IDLE); - - appendLogText(i18n("Shutdown procedure terminated.")); - } -} - -void Scheduler::loadProfiles() +void Scheduler::updateProfiles() { - QString currentProfile = schedulerProfileCombo->currentText(); - - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "ekosInterface:call", "getProfiles"); - QDBusReply profiles = ekosInterface->call(QDBus::AutoDetect, "getProfiles"); - - if (profiles.error().type() == QDBusError::NoError) - { - schedulerProfileCombo->blockSignals(true); - schedulerProfileCombo->clear(); - schedulerProfileCombo->addItem(i18n("Default")); - schedulerProfileCombo->addItems(profiles); - schedulerProfileCombo->setCurrentText(currentProfile); - schedulerProfileCombo->blockSignals(false); - } + schedulerProfileCombo->blockSignals(true); + schedulerProfileCombo->clear(); + schedulerProfileCombo->addItems(moduleState()->profiles()); + schedulerProfileCombo->setCurrentText(moduleState()->currentProfile()); + schedulerProfileCombo->blockSignals(false); } bool Scheduler::loadSequenceQueue(const QString &fileURL, SchedulerJob *schedJob, QList &jobs, @@ -6507,12 +4109,12 @@ SequenceJob * Scheduler::processJobInfo(XMLEle *root, SchedulerJob *schedJob) { - SequenceJob *job = new SequenceJob(root); + SequenceJob *job = new SequenceJob(root, schedJob->getName()); if (FRAME_LIGHT == job->getFrameType() && nullptr != schedJob) schedJob->setLightFramesRequired(true); auto placeholderPath = Ekos::PlaceholderPath(); - placeholderPath.processJobInfo(job, schedJob->getName()); + placeholderPath.processJobInfo(job); return job; } @@ -6575,7 +4177,7 @@ TEST_PRINT(stderr, "sch%d @@@dbus(%s): %d\n", __LINE__, "ekosInterface:indiStatusChanged", status); qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler INDI status is" << status; - m_INDICommunicationStatus = status; + moduleState()->setIndiCommunicationStatus(status); } void Scheduler::setEkosCommunicationStatus(Ekos::CommunicationStatus status) @@ -6583,7 +4185,7 @@ TEST_PRINT(stderr, "sch%d @@@dbus(%s): %d\n", __LINE__, "ekosInterface:ekosStatusChanged", status); qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler Ekos status is" << status; - m_EkosCommunicationStatus = status; + moduleState()->setEkosCommunicationStatus(status); } void Scheduler::simClockScaleChanged(float newScale) @@ -6591,13 +4193,13 @@ if (currentlySleeping()) { QTime const remainingTimeMs = QTime::fromMSecsSinceStartOfDay(std::lround(static_cast - (iterationTimer.remainingTime()) + (moduleState()->iterationTimer().remainingTime()) * KStarsData::Instance()->clock()->scale() / newScale)); appendLogText(i18n("Sleeping for %1 on simulation clock update until next observation job is ready...", remainingTimeMs.toString("hh:mm:ss"))); - iterationTimer.stop(); - iterationTimer.start(remainingTimeMs.msecsSinceStartOfDay()); + moduleState()->iterationTimer().stop(); + moduleState()->iterationTimer().start(remainingTimeMs.msecsSinceStartOfDay()); } } @@ -6607,7 +4209,7 @@ updateNightTime(); // If the Scheduler is not running, reset all jobs and re-evaluate from a new current start point - if (SCHEDULER_RUNNING != state) + if (SCHEDULER_RUNNING != moduleState()->schedulerState()) { startJobEvaluation(); } @@ -6621,16 +4223,17 @@ { QList dbusargs; dbusargs.append(INDI::BaseDevice::DOME_INTERFACE); - QDBusReply paths = indiInterface->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", dbusargs); + QDBusReply paths = process()->indiInterface()->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", + dbusargs); if (paths.error().type() == QDBusError::NoError) { // Select last device in case a restarted caused multiple instances in the tree setDomePathString(paths.value().last()); - delete domeInterface; - domeInterface = new QDBusInterface(kstarsInterfaceString, domePathString, domeInterfaceString, - QDBusConnection::sessionBus(), this); - connect(domeInterface, SIGNAL(ready()), this, SLOT(syncProperties())); - checkInterfaceReady(domeInterface); + delete process()->domeInterface(); + process()->setDomeInterface(new QDBusInterface(kstarsInterfaceString, domePathString, domeInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->domeInterface(), SIGNAL(ready()), this, SLOT(syncProperties())); + checkInterfaceReady(process()->domeInterface()); } } @@ -6638,17 +4241,19 @@ { QList dbusargs; dbusargs.append(INDI::BaseDevice::WEATHER_INTERFACE); - QDBusReply paths = indiInterface->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", dbusargs); + QDBusReply paths = process()->indiInterface()->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", + dbusargs); if (paths.error().type() == QDBusError::NoError) { // Select last device in case a restarted caused multiple instances in the tree setWeatherPathString(paths.value().last()); - delete weatherInterface; - weatherInterface = new QDBusInterface(kstarsInterfaceString, weatherPathString, weatherInterfaceString, - QDBusConnection::sessionBus(), this); - connect(weatherInterface, SIGNAL(ready()), this, SLOT(syncProperties())); - connect(weatherInterface, SIGNAL(newStatus(ISD::Weather::Status)), this, SLOT(setWeatherStatus(ISD::Weather::Status))); - checkInterfaceReady(weatherInterface); + delete process()->weatherInterface(); + process()->setWeatherInterface(new QDBusInterface(kstarsInterfaceString, weatherPathString, weatherInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->weatherInterface(), SIGNAL(ready()), this, SLOT(syncProperties())); + connect(process()->weatherInterface(), SIGNAL(newStatus(ISD::Weather::Status)), this, + SLOT(setWeatherStatus(ISD::Weather::Status))); + checkInterfaceReady(process()->weatherInterface()); } } @@ -6656,16 +4261,17 @@ { QList dbusargs; dbusargs.append(INDI::BaseDevice::DUSTCAP_INTERFACE); - QDBusReply paths = indiInterface->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", dbusargs); + QDBusReply paths = process()->indiInterface()->callWithArgumentList(QDBus::AutoDetect, "getDevicesPaths", + dbusargs); if (paths.error().type() == QDBusError::NoError) { // Select last device in case a restarted caused multiple instances in the tree setDustCapPathString(paths.value().last()); - delete capInterface; - capInterface = new QDBusInterface(kstarsInterfaceString, dustCapPathString, dustCapInterfaceString, - QDBusConnection::sessionBus(), this); - connect(capInterface, SIGNAL(ready()), this, SLOT(syncProperties())); - checkInterfaceReady(capInterface); + delete process()->capInterface(); + process()->setCapInterface(new QDBusInterface(kstarsInterfaceString, dustCapPathString, dustCapInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->capInterface(), SIGNAL(ready()), this, SLOT(syncProperties())); + checkInterfaceReady(process()->capInterface()); } } } @@ -6676,52 +4282,54 @@ if (name == "Focus") { - delete focusInterface; - focusInterface = new QDBusInterface(kstarsInterfaceString, focusPathString, focusInterfaceString, - QDBusConnection::sessionBus(), this); - connect(focusInterface, SIGNAL(newStatus(Ekos::FocusState)), this, SLOT(setFocusStatus(Ekos::FocusState)), - Qt::UniqueConnection); + delete process()->focusInterface(); + process()->setFocusInterface(new QDBusInterface(kstarsInterfaceString, focusPathString, focusInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->focusInterface(), SIGNAL(newStatus(Ekos::FocusState)), this, + SLOT(setFocusStatus(Ekos::FocusState)), Qt::UniqueConnection); } else if (name == "Capture") { - delete captureInterface; - captureInterface = new QDBusInterface(kstarsInterfaceString, capturePathString, captureInterfaceString, - QDBusConnection::sessionBus(), this); - - connect(captureInterface, SIGNAL(ready()), this, SLOT(syncProperties())); - connect(captureInterface, SIGNAL(newStatus(Ekos::CaptureState)), this, SLOT(setCaptureStatus(Ekos::CaptureState)), + delete process()->captureInterface(); + process()->setCaptureInterface(new QDBusInterface(kstarsInterfaceString, capturePathString, captureInterfaceString, + QDBusConnection::sessionBus(), this)); + + connect(process()->captureInterface(), SIGNAL(ready()), this, SLOT(syncProperties())); + connect(process()->captureInterface(), SIGNAL(newStatus(Ekos::CaptureState)), this, + SLOT(setCaptureStatus(Ekos::CaptureState)), Qt::UniqueConnection); - connect(captureInterface, SIGNAL(captureComplete(QVariantMap)), this, SLOT(setCaptureComplete(QVariantMap)), + connect(process()->captureInterface(), SIGNAL(captureComplete(QVariantMap)), this, SLOT(setCaptureComplete(QVariantMap)), Qt::UniqueConnection); - checkInterfaceReady(captureInterface); + checkInterfaceReady(process()->captureInterface()); } else if (name == "Mount") { - delete mountInterface; - mountInterface = new QDBusInterface(kstarsInterfaceString, mountPathString, mountInterfaceString, - QDBusConnection::sessionBus(), this); - - connect(mountInterface, SIGNAL(ready()), this, SLOT(syncProperties())); - connect(mountInterface, SIGNAL(newStatus(ISD::Mount::Status)), this, SLOT(setMountStatus(ISD::Mount::Status)), + delete process()->mountInterface(); + process()->setMountInterface(new QDBusInterface(kstarsInterfaceString, mountPathString, mountInterfaceString, + QDBusConnection::sessionBus(), this)); + + connect(process()->mountInterface(), SIGNAL(ready()), this, SLOT(syncProperties())); + connect(process()->mountInterface(), SIGNAL(newStatus(ISD::Mount::Status)), process(), + SLOT(process()->setMountStatus(ISD::Mount::Status)), Qt::UniqueConnection); - checkInterfaceReady(mountInterface); + checkInterfaceReady(process()->mountInterface()); } else if (name == "Align") { - delete alignInterface; - alignInterface = new QDBusInterface(kstarsInterfaceString, alignPathString, alignInterfaceString, - QDBusConnection::sessionBus(), this); - connect(alignInterface, SIGNAL(newStatus(Ekos::AlignState)), this, SLOT(setAlignStatus(Ekos::AlignState)), + delete process()->alignInterface(); + process()->setAlignInterface(new QDBusInterface(kstarsInterfaceString, alignPathString, alignInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->alignInterface(), SIGNAL(newStatus(Ekos::AlignState)), this, SLOT(setAlignStatus(Ekos::AlignState)), Qt::UniqueConnection); } else if (name == "Guide") { - delete guideInterface; - guideInterface = new QDBusInterface(kstarsInterfaceString, guidePathString, guideInterfaceString, - QDBusConnection::sessionBus(), this); - connect(guideInterface, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setGuideStatus(Ekos::GuideState)), - Qt::UniqueConnection); + delete process()->guideInterface(); + process()->setGuideInterface(new QDBusInterface(kstarsInterfaceString, guidePathString, guideInterfaceString, + QDBusConnection::sessionBus(), this)); + connect(process()->guideInterface(), SIGNAL(newStatus(Ekos::GuideState)), this, + SLOT(setGuideStatus(Ekos::GuideState)), Qt::UniqueConnection); } } @@ -6729,27 +4337,27 @@ { QDBusInterface *iface = qobject_cast(sender()); - if (iface == mountInterface) + if (iface == process()->mountInterface()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:property", "canPark"); - QVariant canMountPark = mountInterface->property("canPark"); + QVariant canMountPark = process()->mountInterface()->property("canPark"); TEST_PRINT(stderr, " @@@dbus received %s\n", !canMountPark.isValid() ? "invalid" : (canMountPark.toBool() ? "T" : "F")); unparkMountCheck->setEnabled(canMountPark.toBool()); parkMountCheck->setEnabled(canMountPark.toBool()); - m_MountReady = true; + moduleState()->setMountReady(true); } - else if (iface == capInterface) + else if (iface == process()->capInterface()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "dustCapInterface:property", "canPark"); - QVariant canCapPark = capInterface->property("canPark"); + QVariant canCapPark = process()->capInterface()->property("canPark"); TEST_PRINT(stderr, " @@@dbus received %s\n", !canCapPark.isValid() ? "invalid" : (canCapPark.toBool() ? "T" : "F")); if (canCapPark.isValid()) { capCheck->setEnabled(canCapPark.toBool()); uncapCheck->setEnabled(canCapPark.toBool()); - m_CapReady = true; + moduleState()->setCapReady(true); } else { @@ -6757,17 +4365,17 @@ uncapCheck->setEnabled(false); } } - else if (iface == domeInterface) + else if (iface == process()->domeInterface()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "domeInterface:property", "canPark"); - QVariant canDomePark = domeInterface->property("canPark"); + QVariant canDomePark = process()->domeInterface()->property("canPark"); TEST_PRINT(stderr, " @@@dbus received %s\n", !canDomePark.isValid() ? "invalid" : (canDomePark.toBool() ? "T" : "F")); if (canDomePark.isValid()) { parkDomeCheck->setEnabled(canDomePark.toBool()); unparkDomeCheck->setEnabled(canDomePark.toBool()); - m_DomeReady = true; + moduleState()->setDomeReady(true); } else { @@ -6775,9 +4383,9 @@ unparkDomeCheck->setEnabled(false); } } - else if (iface == weatherInterface) + else if (iface == process()->weatherInterface()) { - QVariant status = weatherInterface->property("status"); + QVariant status = process()->weatherInterface()->property("status"); if (status.isValid()) { weatherCheck->setEnabled(true); @@ -6786,37 +4394,37 @@ else weatherCheck->setEnabled(false); } - else if (iface == captureInterface) + else if (iface == process()->captureInterface()) { TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "captureInterface:property", "coolerControl"); - QVariant hasCoolerControl = captureInterface->property("coolerControl"); + QVariant hasCoolerControl = process()->captureInterface()->property("coolerControl"); TEST_PRINT(stderr, " @@@dbus received %s\n", !hasCoolerControl.isValid() ? "invalid" : (hasCoolerControl.toBool() ? "T" : "F")); warmCCDCheck->setEnabled(hasCoolerControl.toBool()); - m_CaptureReady = true; + moduleState()->setCaptureReady(true); } } void Scheduler::checkInterfaceReady(QDBusInterface *iface) { - if (iface == mountInterface) + if (iface == process()->mountInterface()) { - QVariant canMountPark = mountInterface->property("canPark"); + QVariant canMountPark = process()->mountInterface()->property("canPark"); if (canMountPark.isValid()) { unparkMountCheck->setEnabled(canMountPark.toBool()); parkMountCheck->setEnabled(canMountPark.toBool()); - m_MountReady = true; + moduleState()->setMountReady(true); } } - else if (iface == capInterface) + else if (iface == process()->capInterface()) { - QVariant canCapPark = capInterface->property("canPark"); + QVariant canCapPark = process()->capInterface()->property("canPark"); if (canCapPark.isValid()) { capCheck->setEnabled(canCapPark.toBool()); uncapCheck->setEnabled(canCapPark.toBool()); - m_CapReady = true; + moduleState()->setCapReady(true); } else { @@ -6824,9 +4432,9 @@ uncapCheck->setEnabled(false); } } - else if (iface == weatherInterface) + else if (iface == process()->weatherInterface()) { - QVariant status = weatherInterface->property("status"); + QVariant status = process()->weatherInterface()->property("status"); if (status.isValid()) { weatherCheck->setEnabled(true); @@ -6835,239 +4443,100 @@ else weatherCheck->setEnabled(false); } - else if (iface == domeInterface) + else if (iface == process()->domeInterface()) { - QVariant canDomePark = domeInterface->property("canPark"); + QVariant canDomePark = process()->domeInterface()->property("canPark"); if (canDomePark.isValid()) { unparkDomeCheck->setEnabled(canDomePark.toBool()); parkDomeCheck->setEnabled(canDomePark.toBool()); - m_DomeReady = true; + moduleState()->setDomeReady(true); } } - else if (iface == captureInterface) + else if (iface == process()->captureInterface()) { - QVariant hasCoolerControl = captureInterface->property("coolerControl"); + QVariant hasCoolerControl = process()->captureInterface()->property("coolerControl"); if (hasCoolerControl.isValid()) { warmCCDCheck->setEnabled(hasCoolerControl.toBool()); - m_CaptureReady = true; + moduleState()->setCaptureReady(true); } } } -void Scheduler::setAlignStatus(Ekos::AlignState status) +void Scheduler::setAlignStatus(AlignState status) { - TEST_PRINT(stderr, "sch%d @@@setAlignStatus(%d)%s\n", __LINE__, static_cast(status), (state == SCHEDULER_PAUSED - || currentJob == nullptr) ? "IGNORED" : "OK"); - - if (state == SCHEDULER_PAUSED || currentJob == nullptr) - return; - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Align State" << Ekos::getAlignStatusString(status); - - /* If current job is scheduled and has not started yet, wait */ - if (SchedulerJob::JOB_SCHEDULED == currentJob->getState()) - { - QDateTime const now = getLocalTime(); - if (now < currentJob->getStartupTime()) - return; - } - - if (currentJob->getStage() == SchedulerJob::STAGE_ALIGNING) - { - // Is solver complete? - if (status == Ekos::ALIGN_COMPLETE) - { - appendLogText(i18n("Job '%1' alignment is complete.", currentJob->getName())); - alignFailureCount = 0; - - currentJob->setStage(SchedulerJob::STAGE_ALIGN_COMPLETE); - - // If we solved a FITS file, let's use its center coords as our target. - if (currentJob->getFITSFile().isEmpty() == false) - { - QDBusReply> solutionReply = alignInterface->call("getTargetCoords"); - if (solutionReply.isValid()) - { - QList const values = solutionReply.value(); - currentJob->setTargetCoords(dms(values[0] * 15.0), dms(values[1]), KStarsData::Instance()->ut().djd()); - } - } - getNextAction(); - } - else if (status == Ekos::ALIGN_FAILED || status == Ekos::ALIGN_ABORTED) - { - appendLogText(i18n("Warning: job '%1' alignment failed.", currentJob->getName())); - - if (alignFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - if (Options::resetMountModelOnAlignFail() && MAX_FAILURE_ATTEMPTS - 1 < alignFailureCount) - { - appendLogText(i18n("Warning: job '%1' forcing mount model reset after failing alignment #%2.", currentJob->getName(), - alignFailureCount)); - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "mountInterface:call", "resetModel"); - mountInterface->call(QDBus::AutoDetect, "resetModel"); - } - appendLogText(i18n("Restarting %1 alignment procedure...", currentJob->getName())); - startAstrometry(); - } - else - { - appendLogText(i18n("Warning: job '%1' alignment procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); - - findNextJob(); - } - } - } + process()->setAlignStatus(status); } -void Scheduler::setGuideStatus(Ekos::GuideState status) +void Scheduler::setGuideStatus(GuideState status) { - TEST_PRINT(stderr, "sch%d @@@setGuideStatus(%d)%s\n", __LINE__, static_cast(status), (state == SCHEDULER_PAUSED - || currentJob == nullptr) ? "IGNORED" : "OK"); - if (state == SCHEDULER_PAUSED || currentJob == nullptr) - return; - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Guide State" << Ekos::getGuideStatusString(status); - - /* If current job is scheduled and has not started yet, wait */ - if (SchedulerJob::JOB_SCHEDULED == currentJob->getState()) - { - QDateTime const now = getLocalTime(); - if (now < currentJob->getStartupTime()) - return; - } - - if (currentJob->getStage() == SchedulerJob::STAGE_GUIDING) - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Calibration & Guide stage..."; - - // If calibration stage complete? - if (status == Ekos::GUIDE_GUIDING) - { - appendLogText(i18n("Job '%1' guiding is in progress.", currentJob->getName())); - guideFailureCount = 0; - // if guiding recovered while we are waiting, abort the restart - cancelGuidingTimer(); - - currentJob->setStage(SchedulerJob::STAGE_GUIDING_COMPLETE); - getNextAction(); - } - else if (status == Ekos::GUIDE_CALIBRATION_ERROR || - status == Ekos::GUIDE_ABORTED) - { - if (status == Ekos::GUIDE_ABORTED) - appendLogText(i18n("Warning: job '%1' guiding failed.", currentJob->getName())); - else - appendLogText(i18n("Warning: job '%1' calibration failed.", currentJob->getName())); - - // if the timer for restarting the guiding is already running, we do nothing and - // wait for the action triggered by the timer. This way we avoid that a small guiding problem - // abort the scheduler job - - if (isGuidingTimerActive()) - return; - - if (guideFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - if (status == Ekos::GUIDE_CALIBRATION_ERROR && - Options::realignAfterCalibrationFailure()) - { - appendLogText(i18n("Restarting %1 alignment procedure...", currentJob->getName())); - startAstrometry(); - } - else - { - appendLogText(i18n("Job '%1' is guiding, guiding procedure will be restarted in %2 seconds.", currentJob->getName(), - (RESTART_GUIDING_DELAY_MS * guideFailureCount) / 1000)); - startGuidingTimer(RESTART_GUIDING_DELAY_MS * guideFailureCount); - } - } - else - { - appendLogText(i18n("Warning: job '%1' guiding procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); - - findNextJob(); - } - } - } -} - -GuideState Scheduler::getGuidingStatus() -{ - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "guideInterface:property", "status"); - QVariant guideStatus = guideInterface->property("status"); - TEST_PRINT(stderr, " @@@dbus received %d\n", !guideStatus.isValid() ? -1 : guideStatus.toInt()); - Ekos::GuideState gStatus = static_cast(guideStatus.toInt()); - - return gStatus; + process()->setGuideStatus(status); } void Scheduler::setCaptureStatus(Ekos::CaptureState status) { TEST_PRINT(stderr, "sch%d @@@setCaptureStatus(%d) %s\n", __LINE__, static_cast(status), - (currentJob == nullptr) ? "IGNORED" : "OK"); - if (currentJob == nullptr) + (activeJob() == nullptr) ? "IGNORED" : "OK"); + if (activeJob() == nullptr) return; qCDebug(KSTARS_EKOS_SCHEDULER) << "Capture State" << Ekos::getCaptureStatusString(status); /* If current job is scheduled and has not started yet, wait */ - if (SchedulerJob::JOB_SCHEDULED == currentJob->getState()) + if (SchedulerJob::JOB_SCHEDULED == activeJob()->getState()) { - QDateTime const now = getLocalTime(); - if (now < currentJob->getStartupTime()) + QDateTime const now = SchedulerModuleState::getLocalTime(); + if (now < activeJob()->getStartupTime()) return; } - if (currentJob->getStage() == SchedulerJob::STAGE_CAPTURING) + if (activeJob()->getStage() == SchedulerJob::STAGE_CAPTURING) { - if (status == Ekos::CAPTURE_PROGRESS && (currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN)) + if (status == Ekos::CAPTURE_PROGRESS && (activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN)) { // JM 2021.09.20 // Re-set target coords in align module // When capture starts, alignment module automatically rests target coords to mount coords. // However, we want to keep align module target synced with the scheduler target and not // the mount coord - const SkyPoint targetCoords = currentJob->getTargetCoords(); + const SkyPoint targetCoords = activeJob()->getTargetCoords(); QList targetArgs; targetArgs << targetCoords.ra0().Hours() << targetCoords.dec0().Degrees(); - alignInterface->callWithArgumentList(QDBus::AutoDetect, "setTargetCoords", targetArgs); + process()->alignInterface()->callWithArgumentList(QDBus::AutoDetect, "setTargetCoords", targetArgs); } else if (status == Ekos::CAPTURE_ABORTED) { - appendLogText(i18n("Warning: job '%1' failed to capture target.", currentJob->getName())); + appendLogText(i18n("Warning: job '%1' failed to capture target.", activeJob()->getName())); - if (captureFailureCount++ < MAX_FAILURE_ATTEMPTS) + if (moduleState()->increaseCaptureFailureCount()) { // If capture failed due to guiding error, let's try to restart that - if (currentJob->getStepPipeline() & SchedulerJob::USE_GUIDE) + if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE) { // Check if it is guiding related. - Ekos::GuideState gStatus = getGuidingStatus(); + Ekos::GuideState gStatus = process()->getGuidingStatus(); if (gStatus == Ekos::GUIDE_ABORTED || gStatus == Ekos::GUIDE_CALIBRATION_ERROR || gStatus == GUIDE_DITHERING_ERROR) { - appendLogText(i18n("Job '%1' is capturing, is restarting its guiding procedure (attempt #%2 of %3).", currentJob->getName(), - captureFailureCount, MAX_FAILURE_ATTEMPTS)); - startGuiding(true); + appendLogText(i18n("Job '%1' is capturing, is restarting its guiding procedure (attempt #%2 of %3).", + activeJob()->getName(), + moduleState()->captureFailureCount(), moduleState()->maxFailureAttempts())); + process()->startGuiding(true); return; } } /* FIXME: it's not clear whether it is actually possible to continue capturing when capture fails this way */ - appendLogText(i18n("Warning: job '%1' failed its capture procedure, restarting capture.", currentJob->getName())); - startCapture(true); + appendLogText(i18n("Warning: job '%1' failed its capture procedure, restarting capture.", activeJob()->getName())); + process()->startCapture(true); } else { /* FIXME: it's not clear whether this situation can be recovered at all */ - appendLogText(i18n("Warning: job '%1' failed its capture procedure, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); + appendLogText(i18n("Warning: job '%1' failed its capture procedure, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); findNextJob(); } @@ -7075,9 +4544,9 @@ else if (status == Ekos::CAPTURE_COMPLETE) { KSNotification::event(QLatin1String("EkosScheduledImagingFinished"), - i18n("Ekos job (%1) - Capture finished", currentJob->getName()), KSNotification::Scheduler); + i18n("Ekos job (%1) - Capture finished", activeJob()->getName()), KSNotification::Scheduler); - currentJob->setState(SchedulerJob::JOB_COMPLETE); + activeJob()->setState(SchedulerJob::JOB_COMPLETE); findNextJob(); } else if (status == Ekos::CAPTURE_IMAGE_RECEIVED) @@ -7088,142 +4557,26 @@ { updateCompletedJobsCount(true); - for (const auto &job : jobs) - estimateJobTime(job, m_CapturedFramesCount, this); + for (const auto &job : moduleState()->jobs()) + estimateJobTime(job, moduleState()->capturedFramesCount(), this); } // Else if we don't remember the progress on jobs, increase the completed count for the current job only - no cross-checks else - currentJob->setCompletedCount(currentJob->getCompletedCount() + 1); + activeJob()->setCompletedCount(activeJob()->getCompletedCount() + 1); - captureFailureCount = 0; + moduleState()->resetCaptureFailureCount(); } } } -void Scheduler::setFocusStatus(Ekos::FocusState status) +void Scheduler::setFocusStatus(FocusState status) { - TEST_PRINT(stderr, "sch%d @@@setFocusStatus(%d)%s\n", __LINE__, static_cast(status), (state == SCHEDULER_PAUSED - || currentJob == nullptr) ? "IGNORED" : "OK"); - if (state == SCHEDULER_PAUSED || currentJob == nullptr) - return; - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Focus State" << Ekos::getFocusStatusString(status); - - /* If current job is scheduled and has not started yet, wait */ - if (SchedulerJob::JOB_SCHEDULED == currentJob->getState()) - { - QDateTime const now = getLocalTime(); - if (now < currentJob->getStartupTime()) - return; - } - - if (currentJob->getStage() == SchedulerJob::STAGE_FOCUSING) - { - // Is focus complete? - if (status == Ekos::FOCUS_COMPLETE) - { - appendLogText(i18n("Job '%1' focusing is complete.", currentJob->getName())); - - autofocusCompleted = true; - - currentJob->setStage(SchedulerJob::STAGE_FOCUS_COMPLETE); - - getNextAction(); - } - else if (status == Ekos::FOCUS_FAILED || status == Ekos::FOCUS_ABORTED) - { - appendLogText(i18n("Warning: job '%1' focusing failed.", currentJob->getName())); - - if (focusFailureCount++ < MAX_FAILURE_ATTEMPTS) - { - appendLogText(i18n("Job '%1' is restarting its focusing procedure.", currentJob->getName())); - // Reset frame to original size. - TEST_PRINT(stderr, "sch%d @@@dbus(%s): %s\n", __LINE__, "focusInterface:call", "resetFrame"); - focusInterface->call(QDBus::AutoDetect, "resetFrame"); - // Restart focusing - qCDebug(KSTARS_EKOS_SCHEDULER) << "startFocusing on 6883"; - startFocusing(); - } - else - { - appendLogText(i18n("Warning: job '%1' focusing procedure failed, marking aborted.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ABORTED); - - findNextJob(); - } - } - } + process()->setFocusStatus(status); } void Scheduler::setMountStatus(ISD::Mount::Status status) { - TEST_PRINT(stderr, "sch%d @@@setMountStatus(%d)%s\n", __LINE__, static_cast(status), (state == SCHEDULER_PAUSED - || currentJob == nullptr) ? "IGNORED" : "OK"); - if (state == SCHEDULER_PAUSED || currentJob == nullptr) - return; - - qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount State changed to" << status; - - /* If current job is scheduled and has not started yet, wait */ - if (SchedulerJob::JOB_SCHEDULED == currentJob->getState()) - if (static_cast(getLocalTime()) < currentJob->getStartupTime()) - return; - - switch (currentJob->getStage()) - { - case SchedulerJob::STAGE_SLEWING: - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Slewing stage..."; - - if (status == ISD::Mount::MOUNT_TRACKING) - { - appendLogText(i18n("Job '%1' slew is complete.", currentJob->getName())); - currentJob->setStage(SchedulerJob::STAGE_SLEW_COMPLETE); - /* getNextAction is deferred to checkJobStage for dome support */ - } - else if (status == ISD::Mount::MOUNT_ERROR) - { - appendLogText(i18n("Warning: job '%1' slew failed, marking terminated due to errors.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - else if (status == ISD::Mount::MOUNT_IDLE) - { - appendLogText(i18n("Warning: job '%1' found not slewing, restarting.", currentJob->getName())); - currentJob->setStage(SchedulerJob::STAGE_IDLE); - getNextAction(); - } - } - break; - - case SchedulerJob::STAGE_RESLEWING: - { - qCDebug(KSTARS_EKOS_SCHEDULER) << "Re-slewing stage..."; - - if (status == ISD::Mount::MOUNT_TRACKING) - { - appendLogText(i18n("Job '%1' repositioning is complete.", currentJob->getName())); - currentJob->setStage(SchedulerJob::STAGE_RESLEWING_COMPLETE); - /* getNextAction is deferred to checkJobStage for dome support */ - } - else if (status == ISD::Mount::MOUNT_ERROR) - { - appendLogText(i18n("Warning: job '%1' repositioning failed, marking terminated due to errors.", currentJob->getName())); - currentJob->setState(SchedulerJob::JOB_ERROR); - findNextJob(); - } - else if (status == ISD::Mount::MOUNT_IDLE) - { - appendLogText(i18n("Warning: job '%1' found not repositioning, restarting.", currentJob->getName())); - currentJob->setStage(SchedulerJob::STAGE_IDLE); - getNextAction(); - } - } - break; - - default: - break; - } + process()->setMountStatus(status); } void Scheduler::setWeatherStatus(ISD::Weather::Status status) @@ -7250,17 +4603,17 @@ break; } - if (newStatus != weatherStatus) + if (newStatus != moduleState()->weatherStatus()) { - weatherStatus = newStatus; + moduleState()->setWeatherStatus(newStatus); qCDebug(KSTARS_EKOS_SCHEDULER) << statusString; - if (weatherStatus == ISD::Weather::WEATHER_OK) + if (moduleState()->weatherStatus() == ISD::Weather::WEATHER_OK) weatherLabel->setPixmap( QIcon::fromTheme("security-high") .pixmap(QSize(32, 32))); - else if (weatherStatus == ISD::Weather::WEATHER_WARNING) + else if (moduleState()->weatherStatus() == ISD::Weather::WEATHER_WARNING) { weatherLabel->setPixmap( QIcon::fromTheme("security-medium") @@ -7268,7 +4621,7 @@ KSNotification::event(QLatin1String("WeatherWarning"), i18n("Weather conditions in warning zone"), KSNotification::Scheduler, KSNotification::Warn); } - else if (weatherStatus == ISD::Weather::WEATHER_ALERT) + else if (moduleState()->weatherStatus() == ISD::Weather::WEATHER_ALERT) { weatherLabel->setPixmap( QIcon::fromTheme("security-low") @@ -7286,46 +4639,47 @@ appendLogText(statusString); - emit weatherChanged(weatherStatus); + emit weatherChanged(moduleState()->weatherStatus()); } // Shutdown scheduler if it was started and not already in shutdown // and if weather checkbox is checked. - if (weatherCheck->isChecked() && weatherStatus == ISD::Weather::WEATHER_ALERT && state != Ekos::SCHEDULER_IDLE - && state != Ekos::SCHEDULER_SHUTDOWN) + if (weatherCheck->isChecked() && moduleState()->weatherStatus() == ISD::Weather::WEATHER_ALERT + && moduleState()->schedulerState() != Ekos::SCHEDULER_IDLE + && moduleState()->schedulerState() != Ekos::SCHEDULER_SHUTDOWN) { appendLogText(i18n("Starting shutdown procedure due to severe weather.")); - if (currentJob) + if (activeJob()) { - currentJob->setState(SchedulerJob::JOB_ABORTED); + activeJob()->setState(SchedulerJob::JOB_ABORTED); stopCurrentJobAction(); } checkShutdownState(); } } -bool Scheduler::shouldSchedulerSleep(SchedulerJob *currentJob) +bool Scheduler::shouldSchedulerSleep(SchedulerJob *job) { - Q_ASSERT_X(nullptr != currentJob, __FUNCTION__, + Q_ASSERT_X(nullptr != job, __FUNCTION__, "There must be a valid current job for Scheduler to test sleep requirement"); - if (currentJob->getLightFramesRequired() == false) + if (job->getLightFramesRequired() == false) return false; - QDateTime const now = getLocalTime(); - int const nextObservationTime = now.secsTo(currentJob->getStartupTime()); + QDateTime const now = SchedulerModuleState::getLocalTime(); + int const nextObservationTime = now.secsTo(job->getStartupTime()); // If start up procedure is complete and the user selected pre-emptive shutdown, let us check if the next observation time exceed // the pre-emptive shutdown time in hours (default 2). If it exceeds that, we perform complete shutdown until next job is ready - if (startupState == STARTUP_COMPLETE && + if (moduleState()->startupState() == STARTUP_COMPLETE && Options::preemptiveShutdown() && nextObservationTime > (Options::preemptiveShutdownTime() * 3600)) { appendLogText(i18n( "Job '%1' scheduled for execution at %2. " "Observatory scheduled for shutdown until next job is ready.", - currentJob->getName(), currentJob->getStartupTime().toString(currentJob->getDateTimeDisplayFormat()))); - enablePreemptiveShutdown(currentJob->getStartupTime()); + job->getName(), job->getStartupTime().toString(job->getDateTimeDisplayFormat()))); + moduleState()->enablePreemptiveShutdown(job->getStartupTime()); weatherCheck->setEnabled(false); weatherLabel->hide(); checkShutdownState(); @@ -7338,24 +4692,24 @@ // This is also only performed if next job is due more than the default lead time (5 minutes). // If job is due sooner than that is not worth parking and we simply go into sleep or wait modes. else if (nextObservationTime > Options::leadTime() * 60 && - startupState == STARTUP_COMPLETE && - parkWaitState == PARKWAIT_IDLE && - (currentJob->getStepPipeline() & SchedulerJob::USE_TRACK) && + moduleState()->startupState() == STARTUP_COMPLETE && + moduleState()->parkWaitState() == PARKWAIT_IDLE && + (job->getStepPipeline() & SchedulerJob::USE_TRACK) && parkMountCheck->isEnabled() && parkMountCheck->isChecked()) { appendLogText(i18n( "Job '%1' scheduled for execution at %2. " "Parking the mount until the job is ready.", - currentJob->getName(), currentJob->getStartupTime().toString())); + job->getName(), job->getStartupTime().toString())); - setParkWaitState(PARKWAIT_PARK); + moduleState()->setParkWaitState(PARKWAIT_PARK); return false; } else if (nextObservationTime > Options::leadTime() * 60) { - appendLogText(i18n("Sleeping until observation job %1 is ready at %2...", currentJob->getName(), + appendLogText(i18n("Sleeping until observation job %1 is ready at %2...", job->getName(), now.addSecs(nextObservationTime + 1).toString())); sleepLabel->setToolTip(i18n("Scheduler is in sleep mode")); sleepLabel->show(); @@ -7366,7 +4720,7 @@ dms delay(static_cast(nextObservationTime * 15.0 / 3600.0)); appendLogText(i18n( "Warning: Job '%1' is %2 away from now, you may want to enable Preemptive Shutdown.", - currentJob->getName(), delay.toHMSString())); + job->getName(), delay.toHMSString())); } /* FIXME: stop tracking now */ @@ -7375,7 +4729,8 @@ // FIXME: Implement waking up periodically before job is due for weather check. // int const nextWakeup = nextObservationTime < 60 ? nextObservationTime : 60; TEST_PRINT(stderr, "%d Setting %s\n", __LINE__, timerStr(RUN_WAKEUP).toLatin1().data()); - setupNextIteration(RUN_WAKEUP, std::lround(((nextObservationTime + 1) * 1000) / KStarsData::Instance()->clock()->scale())); + moduleState()->setupNextIteration(RUN_WAKEUP, + std::lround(((nextObservationTime + 1) * 1000) / KStarsData::Instance()->clock()->scale())); return true; } @@ -7383,76 +4738,10 @@ return false; } -// TODO. It would be better to make this a class and give each operation its own timer. -// TODO. These should be disabled once no longer relevant. -// These are implement with a KStarsDateTime instead of a QTimer type class -// so that the simulated clock can be used. -void Scheduler::startCurrentOperationTimer() -{ - currentOperationTimeStarted = true; - currentOperationTime = KStarsData::Instance()->ut(); -} - -// Returns milliseconds since startCurrentOperationTImer() was called. -qint64 Scheduler::getCurrentOperationMsec() -{ - if (!currentOperationTimeStarted) return 0; - return currentOperationTime.msecsTo(KStarsData::Instance()->ut()); -} - -// Operations on the guiding timer, which can restart guiding after failure. -void Scheduler::startGuidingTimer(int milliseconds) -{ - restartGuidingInterval = milliseconds; - restartGuidingTime = KStarsData::Instance()->ut(); -} - -void Scheduler::cancelGuidingTimer() -{ - restartGuidingInterval = -1; - restartGuidingTime = KStarsDateTime(); -} - -bool Scheduler::isGuidingTimerActive() -{ - return (restartGuidingInterval > 0 && - restartGuidingTime.msecsTo(KStarsData::Instance()->ut()) >= 0); -} - -void Scheduler::processGuidingTimer() -{ - if ((restartGuidingInterval > 0) && - (restartGuidingTime.msecsTo(KStarsData::Instance()->ut()) > restartGuidingInterval)) - { - cancelGuidingTimer(); - startGuiding(true); - } -} - -void Scheduler::enablePreemptiveShutdown(const QDateTime &wakeupTime) -{ - preemptiveShutdownWakeupTime = wakeupTime; -} - -void Scheduler::disablePreemptiveShutdown() -{ - preemptiveShutdownWakeupTime = QDateTime(); -} - -QDateTime Scheduler::getPreemptiveShutdownWakeupTime() -{ - return preemptiveShutdownWakeupTime; -} - -bool Scheduler::preemptiveShutdown() -{ - return preemptiveShutdownWakeupTime.isValid(); -} - void Scheduler::setCaptureComplete(const QVariantMap &metadata) { - if (currentJob && - currentJob->getStepPipeline() & SchedulerJob::USE_ALIGN && + if (activeJob() && + activeJob()->getStepPipeline() & SchedulerJob::USE_ALIGN && metadata["type"].toInt() == FRAME_LIGHT && Options::alignCheckFrequency() > 0 && ++m_SolverIteration >= Options::alignCheckFrequency()) @@ -7493,9 +4782,9 @@ } m_Solver->useScale(Options::astrometryUseImageScale(), lowScale, highScale); - m_Solver->usePosition(Options::astrometryUsePosition(), currentJob->getTargetCoords().ra().Degrees(), - currentJob->getTargetCoords().dec().Degrees()); - m_Solver->setHealpix(m_IndexToUse, m_HealpixToUse); + m_Solver->usePosition(Options::astrometryUsePosition(), activeJob()->getTargetCoords().ra().Degrees(), + activeJob()->getTargetCoords().dec().Degrees()); + m_Solver->setHealpix(moduleState()->indexToUse(), moduleState()->healpixToUse()); m_Solver->runSolver(filename); } } @@ -7505,23 +4794,26 @@ { disconnect(m_Solver.get(), &SolverUtils::done, this, &Ekos::Scheduler::solverDone); - if (!currentJob) + if (!activeJob()) return; QString healpixString = ""; - if (m_IndexToUse != -1 || m_HealpixToUse != -1) - healpixString = QString("Healpix %1 Index %2").arg(m_HealpixToUse).arg(m_IndexToUse); + if (moduleState()->indexToUse() != -1 || moduleState()->healpixToUse() != -1) + healpixString = QString("Healpix %1 Index %2").arg(moduleState()->healpixToUse()).arg(moduleState()->indexToUse()); if (timedOut || !success) { // Don't use the previous index and healpix next time we solve. - m_IndexToUse = -1; - m_HealpixToUse = -1; + moduleState()->setIndexToUse(-1); + moduleState()->setHealpixToUse(-1); } else { + int index, healpix; // Get the index and healpix from the successful solve. - m_Solver->getSolutionHealpix(&m_IndexToUse, &m_HealpixToUse); + m_Solver->getSolutionHealpix(&index, &healpix); + moduleState()->setIndexToUse(index); + moduleState()->setHealpixToUse(healpix); } if (timedOut) @@ -7533,7 +4825,7 @@ const double ra = solution.ra; const double dec = solution.dec; - const auto target = currentJob->getTargetCoords(); + const auto target = activeJob()->getTargetCoords(); SkyPoint alignCoord; alignCoord.setRA0(ra / 15.0); @@ -7565,7 +4857,7 @@ appendLogText(i18n("Captured frame is %1 arcminutes away from target, re-aligning...", QString::number(diffTotal / 60.0, 'f', 1))); stopCurrentJobAction(); - startAstrometry(); + process()->startAstrometry(); } } } @@ -7574,7 +4866,7 @@ { QJsonArray jobArray; - for (const auto &oneJob : getJobs()) + for (const auto &oneJob : moduleState()->jobs()) jobArray.append(oneJob->toJson()); return jobArray; @@ -7819,7 +5111,7 @@ QJsonObject schedulerSettings = { {"algorithm", ALGORITHM_GREEDY}, - {"state", state}, + {"state", moduleState()->schedulerState()}, {"trackStepCheck", trackStepCheck->isChecked()}, {"focusStepCheck", focusStepCheck->isChecked()}, {"alignStepCheck", alignStepCheck->isChecked()}, @@ -7845,30 +5137,63 @@ return assistant->importMosaic(payload); } -void Scheduler::setStartupState(StartupState state) +void Scheduler::startupStateChanged(StartupState state) { - startupState = state; jobStatus->setText(startupStateString(state)); + + switch (moduleState()->startupState()) + { + case STARTUP_IDLE: + startupB->setIcon(QIcon::fromTheme("media-playback-start")); + break; + case STARTUP_COMPLETE: + startupB->setIcon(QIcon::fromTheme("media-playback-start")); + appendLogText(i18n("Manual startup procedure completed successfully.")); + break; + case STARTUP_ERROR: + startupB->setIcon(QIcon::fromTheme("media-playback-start")); + appendLogText(i18n("Manual startup procedure terminated due to errors.")); + break; + default: + // in all other cases startup is running + startupB->setIcon(QIcon::fromTheme("media-playback-stop")); + break; + } } -void Scheduler::setShutdownState(ShutdownState state) +void Scheduler::shutdownStateChanged(ShutdownState state) { - shutdownState = state; jobStatus->setText(shutdownStateString(state)); + if (state == SHUTDOWN_COMPLETE || state == SHUTDOWN_IDLE + || state == SHUTDOWN_ERROR) + shutdownB->setIcon(QIcon::fromTheme("media-playback-start")); + else + shutdownB->setIcon(QIcon::fromTheme("media-playback-stop")); } -void Scheduler::setEkosState(EkosState state) +void Scheduler::ekosStateChanged(EkosState state) { - ekosState = state; jobStatus->setText(ekosStateString(state)); } -void Scheduler::setIndiState(INDIState state) +void Scheduler::indiStateChanged(INDIState state) { - indiState = state; jobStatus->setText(indiStateString(state)); } -void Scheduler::setParkWaitState(ParkWaitStatus state) +void Scheduler::parkWaitStateChanged(ParkWaitState state) { - parkWaitState = state; jobStatus->setText(parkWaitStateString(state)); } +SchedulerJob *Scheduler::activeJob() +{ + return moduleState()->activeJob(); +} + +Ekos::SchedulerState Scheduler::status() +{ + return moduleState()->schedulerState(); +} + +bool Scheduler::saveScheduler(const QUrl &fileURL) +{ + return process()->saveScheduler(fileURL); +} } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/scheduler.h 2023-12-03 05:23:17.000000000 +0000 @@ -10,14 +10,13 @@ #pragma once #include "ui_scheduler.h" +#include "schedulertypes.h" #include "ekos/align/align.h" #include "indi/indiweather.h" -#include "ekos/auxiliary/solverutils.h" #include "schedulerjob.h" #include -#include #include #include #include @@ -28,11 +27,10 @@ class QProgressIndicator; class GeoLocation; -class SchedulerJob; class SkyObject; class KConfigDialog; class TestSchedulerUnit; - +class SolverUtils; class TestEkosSchedulerOps; namespace Ekos @@ -40,6 +38,8 @@ class SequenceJob; class GreedyScheduler; +class SchedulerProcess; +class SchedulerModuleState; /** * @brief The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs. @@ -54,61 +54,7 @@ Q_PROPERTY(QStringList logText READ logText NOTIFY newLog) Q_PROPERTY(QString profile READ profile WRITE setProfile) - public: - typedef enum { EKOS_IDLE, EKOS_STARTING, EKOS_STOPPING, EKOS_READY } EkosState; - typedef enum { INDI_IDLE, INDI_CONNECTING, INDI_DISCONNECTING, INDI_PROPERTY_CHECK, INDI_READY } INDIState; - typedef enum - { - STARTUP_IDLE, - STARTUP_SCRIPT, - STARTUP_UNPARK_DOME, - STARTUP_UNPARKING_DOME, - STARTUP_UNPARK_MOUNT, - STARTUP_UNPARKING_MOUNT, - STARTUP_UNPARK_CAP, - STARTUP_UNPARKING_CAP, - STARTUP_ERROR, - STARTUP_COMPLETE - } StartupState; - typedef enum - { - SHUTDOWN_IDLE, - SHUTDOWN_PARK_CAP, - SHUTDOWN_PARKING_CAP, - SHUTDOWN_PARK_MOUNT, - SHUTDOWN_PARKING_MOUNT, - SHUTDOWN_PARK_DOME, - SHUTDOWN_PARKING_DOME, - SHUTDOWN_SCRIPT, - SHUTDOWN_SCRIPT_RUNNING, - SHUTDOWN_ERROR, - SHUTDOWN_COMPLETE - } ShutdownState; - typedef enum - { - PARKWAIT_IDLE, - PARKWAIT_PARK, - PARKWAIT_PARKING, - PARKWAIT_PARKED, - PARKWAIT_UNPARK, - PARKWAIT_UNPARKING, - PARKWAIT_UNPARKED, - PARKWAIT_ERROR - } ParkWaitStatus; - - /** @brief options what should happen if an error or abort occurs */ - typedef enum - { - ERROR_DONT_RESTART, - ERROR_RESTART_AFTER_TERMINATION, - ERROR_RESTART_IMMEDIATELY - } ErrorHandlingStrategy; - - /** @brief Algorithms, in the same order as UI. */ - typedef enum - { - ALGORITHM_GREEDY = 1 - } SchedulerAlgorithm; +public: /** @brief Columns, in the same order as UI. */ typedef enum @@ -121,16 +67,6 @@ SCHEDCOL_ENDTIME, } SchedulerColumns; - /** @brief IterationTypes, the different types of scheduler iterations that are run. */ - typedef enum - { - RUN_WAKEUP = 0, - RUN_SCHEDULER, - RUN_JOBCHECK, - RUN_SHUTDOWN, - RUN_NOTHING - } SchedulerTimerState; - /** @brief Constructor, the starndard scheduler constructor. */ Scheduler(); /** @brief DebugConstructor, a constructor used in testing with a mock ekos. */ @@ -139,10 +75,9 @@ ~Scheduler() = default; QString getCurrentJobName(); - SchedulerJob *getCurrentJob() - { - return currentJob; - } + + // shortcut + SchedulerJob *activeJob(); void appendLogText(const QString &); QStringList logText() @@ -159,28 +94,6 @@ void addObject(SkyObject *object); /** - * @brief startSlew DBus call for initiating slew - */ - void startSlew(); - - /** - * @brief startFocusing DBus call for feeding ekos the specified settings and initiating focus operation - */ - void startFocusing(); - - /** - * @brief startAstrometry initiation of the capture and solve operation. We change the job state - * after solver is started - */ - void startAstrometry(); - - /** - * @brief startGuiding After ekos is fed the calibration options, we start the guiding process - * @param resetCalibration By default calibration is not reset until it is explicitly requested - */ - void startGuiding(bool resetCalibration = false); - - /** * @brief startCapture The current job file name is solved to an url which is fed to ekos. We then start the capture process * @param restart Set to true if the goal to restart an existing sequence. The only difference is that when a sequence is restarted, sequence file * is not loaded from disk again since that results in erasing all the history of the capture process. @@ -193,27 +106,6 @@ void getNextAction(); /** - * @brief disconnectINDI disconnect all INDI devices from server. - */ - void disconnectINDI(); - - /** - * @brief stopEkos shutdown Ekos completely - */ - void stopEkos(); - - /** - * @brief stopGuiding After guiding is done we need to stop the process - */ - void stopGuiding(); - - /** - * @brief setSolverAction set the GOTO mode for the solver - * @param mode 0 For Sync, 1 for SlewToTarget, 2 for Nothing - */ - void setSolverAction(Align::GotoMode mode); - - /** * @brief importMosaic Import mosaic into planner and generate jobs for the scheduler. * @param payload metadata for the mosaic information. * @note Only Telescopius.com mosaic format is now supported. @@ -264,10 +156,7 @@ */ Q_SCRIPTABLE void sortJobsPerAltitude(); - Ekos::SchedulerState status() - { - return state; - } + Ekos::SchedulerState status(); void setProfile(const QString &profile) { @@ -295,17 +184,6 @@ // e.g. SchedulerPlanner or SchedulerJobEval /** - * @brief setupJob Massive initialization of a SchedulerJob for testing and exectution - * @param job Target - */ - static void setupJob(SchedulerJob &job, const QString &name, const QString &group, const dms &ra, - const dms &dec, double djd, double rotation, const QUrl &sequenceUrl, const QUrl &fitsUrl, - SchedulerJob::StartupCondition startup, const QDateTime &startupTime, - SchedulerJob::CompletionCondition completion, const QDateTime &completionTime, int completionRepeats, - double minimumAltitude, double minimumMoonSeparation, bool enforceWeather, bool enforceTwilight, - bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide); - - /** * @brief estimateJobTime Estimates the time the job takes to complete based on the sequence file and what modules to utilize during the observation run. * @param job target job * @param capturedFramesCount a map of what's been captured already @@ -327,31 +205,9 @@ static bool loadSequenceQueue(const QString &fileURL, SchedulerJob *schedJob, QList &jobs, bool &hasAutoFocus, Scheduler *scheduler); - /** @brief Setter used in testing to fix the local time. Otherwise getter gets from KStars instance. */ - /** @{ */ - static KStarsDateTime getLocalTime(); - static void setLocalTime(KStarsDateTime *time) - { - storedLocalTime = time; - } - static bool hasLocalTime() - { - return storedLocalTime != nullptr; - } - /** @} */ - // Scheduler Settings void setSettings(const QJsonObject &settings); - void setUpdateInterval(int ms) - { - m_UpdatePeriodMs = ms; - } - int getUpdateInterval() - { - return m_UpdatePeriodMs; - } - // Primary Settings void setPrimarySettings(const QJsonObject &settings); @@ -396,11 +252,6 @@ */ void saveJob(); - const QList &getJobs() const - { - return jobs; - } - QJsonArray getJSONJobs(); void toggleScheduler(); @@ -429,8 +280,13 @@ */ void updateTable(); - - private: + // the state machine + QSharedPointer moduleState() const + { + return m_moduleState; + } + +private: /** * @brief processJobInfo a utility used by loadSequenceQueue() to help it read a capture sequence file * @param root the filename @@ -457,13 +313,12 @@ // a separate Scheduler-related class. /*@{*/ - - private: /** @internal Safeguard flag to avoid registering signals from widgets multiple times. */ bool jobChangesAreWatched { false }; - protected: +protected: + /** @internal Enables signal watch on SchedulerJob form values in order to apply changes to current job. * @param enable is the toggle flag, true to watch for changes, false to ignore them. */ @@ -477,13 +332,12 @@ void setDirty(); /** @} */ - protected: /** @internal Associate job table cells on a row to the corresponding SchedulerJob. * @param row is an integer indexing the row to associate cells from, and also the index of the job in the job list.. */ void setJobStatusCells(int row); - protected slots: +protected slots: /** * @brief registerNewModule Register an Ekos module as it arrives via DBus @@ -567,6 +421,11 @@ void syncGUIToJob(SchedulerJob *job); /** + * @brief syncGUIToGeneralSettings set all UI fields that are not job specific + */ + void syncGUIToGeneralSettings(); + + /** * @brief jobSelectionChanged Update UI state when the job list is clicked once. */ void clickQueueTable(QModelIndex index); @@ -600,7 +459,6 @@ */ bool shouldSchedulerSleep(SchedulerJob *currentJob); - bool completeShutdown(); void pause(); void setPaused(); void save(); @@ -651,23 +509,6 @@ void stopCurrentJobAction(); /** - * @brief manageConnectionLoss Mitigate loss of connection with the INDI server. - * @return true if connection to Ekos/INDI should be attempted again, false if not mitigation is available or needed. - */ - bool manageConnectionLoss(); - - /** - * @brief readProcessOutput read running script process output and display it in Ekos - */ - void readProcessOutput(); - - /** - * @brief checkProcessExit Check script process exist status. This is called when the process exists either normally or abnormally. - * @param exitCode exit code from the script process. Depending on the exist code, the status of startup/shutdown procedure is set accordingly. - */ - void checkProcessExit(int exitCode); - - /** * @brief resumeCheckStatus If the scheduler primary loop was suspended due to weather or sleep event, resume it again. */ void resumeCheckStatus(); @@ -692,12 +533,6 @@ */ void checkTwilightWarning(bool enabled); - void runStartupProcedure(); - void checkStartupProcedure(); - - void runShutdownProcedure(); - void checkShutdownProcedure(); - void setINDICommunicationStatus(Ekos::CommunicationStatus status); void setEkosCommunicationStatus(Ekos::CommunicationStatus status); @@ -722,7 +557,7 @@ */ void setCaptureComplete(const QVariantMap &metadata); - signals: +signals: void newLog(const QString &text); void newStatus(Ekos::SchedulerState state); void weatherChanged(ISD::Weather::Status state); @@ -735,7 +570,7 @@ void jobEnded(const QString &jobName, const QString &endReason); void jobsUpdated(QJsonArray jobsList); - private: +private: /** * @brief evaluateJobs evaluates the current state of each objects and gives each one a score based on the constraints. * Given that score, the scheduler will decide which is the best job that needs to be executed. @@ -756,105 +591,18 @@ */ bool executeJob(SchedulerJob *job); - void executeScript(const QString &filename); - /** * @brief calculateDawnDusk Get dawn and dusk times for today */ static void calculateDawnDusk(); /** - * @brief checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and running - * @return True if Ekos is running, false if Ekos start up is in progress. - */ - bool checkEkosState(); - - /** - * @brief isINDIConnected Determines the status of the INDI connection. - * @return True if INDI connection is up and usable, else false. - */ - bool isINDIConnected(); - - /** - * @brief checkINDIState Check INDI startup stages and take whatever action necessary to get INDI devices connected. - * @return True if INDI devices are connected, false if it is under progress. - */ - bool checkINDIState(); - - /** - * @brief checkStartupState Check startup procedure stages and make sure all stages are complete. - * @return True if startup is complete, false otherwise. - */ - bool checkStartupState(); - - /** * @brief checkShutdownState Check shutdown procedure stages and make sure all stages are complete. * @return */ bool checkShutdownState(); /** - * @brief checkParkWaitState Check park wait state. - * @return If parking/unparking in progress, return false. If parking/unparking complete, return true. - */ - bool checkParkWaitState(); - - /** - * @brief parkMount Park mount - */ - void parkMount(); - - /** - * @brief unParkMount Unpark mount - */ - void unParkMount(); - - /** - * @return True if mount is parked - */ - bool isMountParked(); - - /** - * @brief parkDome Park dome - */ - void parkDome(); - - /** - * @brief unParkDome Unpark dome - */ - void unParkDome(); - - /** - * @return True if dome is parked - */ - bool isDomeParked(); - - /** - * @brief parkCap Close dust cover - */ - void parkCap(); - - /** - * @brief unCap Open dust cover - */ - void unParkCap(); - - /** - * @brief checkMountParkingStatus check mount parking status and updating corresponding states accordingly. - */ - void checkMountParkingStatus(); - - /** - * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly. - */ - void checkDomeParkingStatus(); - - /** - * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly. - */ - void checkCapParkingStatus(); - - /** * @brief processJobInfo Process the job information from a scheduler file and populate jobs accordingly * @param root XML root element of JOB * @return true on success, false on failure. @@ -872,8 +620,10 @@ */ void processFITSSelection(); - void loadProfiles(); - + /** + * @brief updateProfiles React upon changed profiles and update the UI + */ + void updateProfiles(); /** @@ -919,20 +669,6 @@ int getCompletedFiles(const QString &path); - // retrieve the guiding status - GuideState getGuidingStatus(); - - // Returns milliseconds since startCurrentOperationTImer() was called. - qint64 getCurrentOperationMsec(); - // Starts the above operation timer. - void startCurrentOperationTimer(); - - // Controls for the guiding timer, which restarts guiding after failure. - void cancelGuidingTimer(); - bool isGuidingTimerActive(); - void startGuidingTimer(int milliseconds); - void processGuidingTimer(); - // Returns true if the job is storing its captures on the same machine as the scheduler. bool canCountCaptures(const SchedulerJob &job); @@ -950,17 +686,6 @@ int sequenceExecutionCounter = 1; Ekos::Scheduler *ui { nullptr }; - //DBus interfaces - QPointer indiInterface { nullptr }; - QPointer focusInterface { nullptr }; - QPointer ekosInterface { nullptr }; - QPointer captureInterface { nullptr }; - QPointer mountInterface { nullptr }; - QPointer alignInterface { nullptr }; - QPointer guideInterface { nullptr }; - QPointer domeInterface { nullptr }; - QPointer weatherInterface { nullptr }; - QPointer capInterface { nullptr }; // Interface strings for the dbus. Changeable for mocks when testing. Private so only tests can change. QString schedulerPathString { "/KStars/Ekos/Scheduler" }; @@ -1071,34 +796,30 @@ dustCapPathString = interface; } - // Scheduler and job state and stages - void setStartupState(StartupState state); - void setShutdownState(ShutdownState state); - void setEkosState(EkosState state); - void setIndiState(INDIState state); - void setParkWaitState(ParkWaitStatus state); - SchedulerState state { SCHEDULER_IDLE }; - EkosState ekosState { EKOS_IDLE }; - INDIState indiState { INDI_IDLE }; - StartupState startupState { STARTUP_IDLE }; - ShutdownState shutdownState { SHUTDOWN_IDLE }; - ParkWaitStatus parkWaitState { PARKWAIT_IDLE }; - Ekos::CommunicationStatus m_EkosCommunicationStatus { Ekos::Idle }; - Ekos::CommunicationStatus m_INDICommunicationStatus { Ekos::Idle }; - /// List of all jobs as entered by the user or file - QList jobs; - /// Active job - SchedulerJob *currentJob { nullptr }; + // the state machine holding all states + QSharedPointer m_moduleState; + // process engine implementing all process steps + QPointer m_process; + QPointer process() + { + return m_process; + } + + // react upon changes of EKOS and INDI state + void ekosStateChanged(EkosState state); + void indiStateChanged(INDIState state); + + // react upon state changes + void startupStateChanged(StartupState state); + void shutdownStateChanged(ShutdownState state); + void parkWaitStateChanged(ParkWaitState state); + /// URL to store the scheduler file QUrl schedulerURL; /// URL for Ekos Sequence QUrl sequenceURL; /// FITS URL to solve QUrl fitsURL; - /// Startup script URL - QUrl startupScriptURL; - /// Shutdown script URL - QUrl shutdownScriptURL; /// Store all log strings QStringList m_LogText; /// Busy indicator widget @@ -1107,73 +828,20 @@ int jobUnderEdit { -1 }; /// Pointer to Geographic location GeoLocation *geo { nullptr }; - /// How many repeated job batches did we complete thus far? - uint16_t captureBatch { 0 }; - /// Startup and Shutdown scripts process - QProcess scriptProcess; /// Store next dawn to calculate dark skies range static QDateTime Dawn; /// Store next dusk to calculate dark skies range static QDateTime Dusk; /// Pre-dawn is where we stop all jobs, it is a user-configurable value before Dawn. static QDateTime preDawnDateTime; - /// Was job modified and needs saving? - bool mDirty { false }; - /// Keep watch of weather status - ISD::Weather::Status weatherStatus { ISD::Weather::WEATHER_IDLE }; - /// Keep track of how many times we didn't receive weather updates - uint8_t noWeatherCounter { 0 }; - - // Utilities to control the preemptiveShutdown feature. - // Is the scheduler shutting down until later when it will resume a job? - void enablePreemptiveShutdown(const QDateTime &wakeupTime); - void disablePreemptiveShutdown(); - QDateTime getPreemptiveShutdownWakeupTime(); - bool preemptiveShutdown(); - // The various preemptiveShutdown states are controlled by this one variable. - QDateTime preemptiveShutdownWakeupTime; - - /// Keep track of Load & Slew operation - bool loadAndSlewProgress { false }; - /// Check if initial autofocus is completed and do not run autofocus until there is a change is telescope position/alignment. - bool autofocusCompleted { false }; - /// Keep track of INDI connection failures - uint8_t indiConnectFailureCount { 0 }; - /// Keep track of Ekos connection failures - uint8_t ekosConnectFailureCount { 0 }; - /// Keep track of Ekos focus module failures - uint8_t focusFailureCount { 0 }; - /// Keep track of Ekos guide module failures - uint8_t guideFailureCount { 0 }; - /// Keep track of Ekos align module failures - uint8_t alignFailureCount { 0 }; - /// Keep track of Ekos capture module failures - uint8_t captureFailureCount { 0 }; + /// Counter to keep debug logging in check uint8_t checkJobStageCounter { 0 }; /// Call checkWeather when weatherTimer time expires. It is equal to the UpdatePeriod time in INDI::Weather device. //QTimer weatherTimer; - /// Delay for restarting the guider - /// used by cancelGuidingTimer(), isGuidingTimerActive(), startGuidingTimer - /// and processGuidingTimer. - int restartGuidingInterval { -1 }; - KStarsDateTime restartGuidingTime; - - /// Generic time to track timeout of current operation in progress. - /// Used by startCurrentOperationTimer() and getCurrentOperationMsec(). - KStarsDateTime currentOperationTime; - bool currentOperationTimeStarted { false }; - QUrl dirPath; - QMap m_CapturedFramesCount; - - bool m_MountReady { false }; - bool m_CaptureReady { false }; - bool m_DomeReady { false }; - bool m_CapReady { false }; - // When a module is commanded to perform an action, wait this many milliseconds // before check its state again. If State is still IDLE, then it either didn't received the command // or there is another problem. @@ -1194,14 +862,6 @@ // Run a single scheduler iteration. int runSchedulerIteration(); - // This is the time between typical scheduler iterations. - // The time can be modified for testing. - int m_UpdatePeriodMs = 1000; - - // Setup the parameters for the next scheduler iteration. - // When milliseconds is not passed in, it uses m_UpdatePeriodMs. - void setupNextIteration(SchedulerTimerState nextState); - void setupNextIteration(SchedulerTimerState nextState, int milliseconds); // True if the scheduler is between iterations and delaying longer than the typical update period. bool currentlySleeping(); // Used by the constructor in testing mainly so a mock ekos could be used. @@ -1210,32 +870,11 @@ void printStates(const QString &label); - // The type of scheduler iteration that should be run next. - SchedulerTimerState timerState { RUN_NOTHING }; - // Variable keeping the number of millisconds the scheduler should wait - // after the current scheduler iteration. - int timerInterval { -1 }; - // Whether the scheduler has been setup for the next iteration, - // that is, whether timerInterval and timerState have been set this iteration. - bool iterationSetup { false }; - // The timer used to wakeup the scheduler between iterations. - QTimer iterationTimer; - // Counter for how many scheduler iterations have been processed. - int schedulerIteration { 0 }; - // The time when the scheduler first started running iterations. - qint64 startMSecs { 0 }; - /// Target coordinates for pointing check QSharedPointer m_Solver; // Used when solving position every nth capture. uint32_t m_SolverIteration {0}; - // Restricts (the internal solver) to using the index and healpix - // from the previous solve, if that solve was successful, when - // doing the pointing check. -1 means no restriction. - int m_IndexToUse { -1 }; - int m_HealpixToUse { -1 }; - void syncGreedyParams(); QPointer m_GreedyScheduler; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -12,7 +12,9 @@ #include "skymapcomposite.h" #include "Options.h" #include "scheduler.h" +#include "schedulermodulestate.h" #include "ksalmanac.h" +#include "ksmoon.h" #include @@ -23,6 +25,8 @@ #define BAD_SCORE -1000 #define MIN_ALTITUDE 15.0 +namespace Ekos +{ bool SchedulerJob::m_UpdateGraphics = true; GeoLocation *SchedulerJob::storedGeo = nullptr; @@ -91,19 +95,7 @@ return QString("????"); } -QString SchedulerJob::startupConditionString(SchedulerJob::StartupCondition condition) -{ - switch(condition) - { - case START_ASAP: - return "ASAP"; - case START_AT: - return "AT"; - } - return QString("????"); -} - -QString SchedulerJob::jobStartupConditionString(SchedulerJob::StartupCondition condition) const +QString SchedulerJob::jobStartupConditionString(StartupCondition condition) const { switch(condition) { @@ -115,23 +107,7 @@ return QString("????"); } -QString SchedulerJob::completionConditionString(SchedulerJob::CompletionCondition condition) -{ - switch(condition) - { - case FINISH_SEQUENCE: - return "FINISH"; - case FINISH_REPEAT: - return "REPEAT"; - case FINISH_LOOP: - return "LOOP"; - case FINISH_AT: - return "AT"; - } - return QString("????"); -} - -QString SchedulerJob::jobCompletionConditionString(SchedulerJob::CompletionCondition condition) const +QString SchedulerJob::jobCompletionConditionString(CompletionCondition condition) const { switch(condition) { @@ -180,7 +156,7 @@ KStarsDateTime SchedulerJob::getLocalTime() { - return Ekos::Scheduler::getLocalTime(); + return Ekos::SchedulerModuleState::getLocalTime(); } GeoLocation const *SchedulerJob::getGeo() @@ -1349,7 +1325,7 @@ // We do not consider job state here. It is the responsibility of the caller // to filter for that, if desired. - if (!runningJob && SchedulerJob::START_AT == getFileStartupCondition()) + if (!runningJob && START_AT == getFileStartupCondition()) { int secondsFromNow = ltWhen.secsTo(getFileStartupTime()); if (secondsFromNow < -500) @@ -1394,7 +1370,7 @@ // We do not consider job state here. It is the responsibility of the caller // to filter for that, if desired. - if (SchedulerJob::START_AT == getFileStartupCondition()) + if (START_AT == getFileStartupCondition()) { if (getFileStartupTime().secsTo(ltStart) < -120) { @@ -1449,3 +1425,4 @@ {"altitude", altitudeCell ? altitudeCell->text() : "--"}, }; } +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerjob.h 2023-12-03 05:23:17.000000000 +0000 @@ -7,10 +7,10 @@ #pragma once #include "skypoint.h" +#include "schedulertypes.h" #include #include -#include "ksmoon.h" #include "kstarsdatetime.h" #include @@ -22,6 +22,8 @@ class TestEkosSchedulerOps; class dms; +namespace Ekos +{ class SchedulerJob { public: @@ -62,22 +64,6 @@ STAGE_COMPLETE } JOBStage; - /** @brief Conditions under which a SchedulerJob may start. */ - typedef enum - { - START_ASAP = 0, - START_AT = 2 - } StartupCondition; - - /** @brief Conditions under which a SchedulerJob may complete. */ - typedef enum - { - FINISH_SEQUENCE, - FINISH_REPEAT, - FINISH_LOOP, - FINISH_AT - } CompletionCondition; - /** @brief Actions that may be processed when running a SchedulerJob. * FIXME: StepPipeLine is actually a mask, change this into a bitfield. */ @@ -627,10 +613,8 @@ // Convenience debugging methods. static QString jobStatusString(JOBStatus status); static QString jobStageString(JOBStage stage); - static QString startupConditionString(SchedulerJob::StartupCondition condition); - QString jobStartupConditionString(SchedulerJob::StartupCondition condition) const; - static QString completionConditionString(SchedulerJob::CompletionCondition condition); - QString jobCompletionConditionString(SchedulerJob::CompletionCondition condition) const; + QString jobStartupConditionString(StartupCondition condition) const; + QString jobCompletionConditionString(CompletionCondition condition) const; static void enableGraphicsUpdates(bool update) { @@ -808,3 +792,4 @@ static GeoLocation *storedGeo; static ArtificialHorizon *storedHorizon; }; +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,244 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "schedulermodulestate.h" +#include +#include "schedulerprocess.h" +#include "schedulerjob.h" +#include "kstarsdata.h" + +#define MAX_FAILURE_ATTEMPTS 5 + +namespace Ekos +{ +SchedulerModuleState::SchedulerModuleState() {} + +void SchedulerModuleState::setCurrentProfile(const QString &newName, bool signal) +{ + bool changed = (newName != m_currentProfile); + + if (m_profiles.contains(newName)) + m_currentProfile = newName; + else + { + changed = (m_currentProfile != m_profiles.first()); + m_currentProfile = m_profiles.first(); + } + // update the UI + if (signal && changed) + emit currentProfileChanged(); +} + +void SchedulerModuleState::updateProfiles(const QStringList &newProfiles) +{ + QString selected = currentProfile(); + // Default profile is always the first one + QStringList allProfiles(i18n("Default")); + allProfiles.append(newProfiles); + + m_profiles = allProfiles; + // ensure that the selected profile still exists + setCurrentProfile(selected, false); + emit profilesChanged(); +} + +void SchedulerModuleState::setStartupState(StartupState state) +{ + if (m_startupState != state) + { + m_startupState = state; + emit startupStateChanged(state); + } +} + +void SchedulerModuleState::setShutdownState(ShutdownState state) +{ + if (m_shutdownState != state) + { + m_shutdownState = state; + emit shutdownStateChanged(state); + } +} + +void SchedulerModuleState::setParkWaitState(ParkWaitState state) +{ + if (m_parkWaitState != state) + { + m_parkWaitState = state; + emit parkWaitStateChanged(state); + } +} + +void SchedulerModuleState::enablePreemptiveShutdown(const QDateTime &wakeupTime) +{ + m_preemptiveShutdownWakeupTime = wakeupTime; +} + +void SchedulerModuleState::disablePreemptiveShutdown() +{ + m_preemptiveShutdownWakeupTime = QDateTime(); +} + +const QDateTime &SchedulerModuleState::preemptiveShutdownWakeupTime() const +{ + return m_preemptiveShutdownWakeupTime; +} + +bool SchedulerModuleState::preemptiveShutdown() const +{ + return m_preemptiveShutdownWakeupTime.isValid(); +} + +void SchedulerModuleState::setEkosState(EkosState state) +{ + if (m_ekosState != state) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "EKOS state changed from" << m_ekosState << "to" << state; + m_ekosState = state; + emit ekosStateChanged(state); + } +} + +bool SchedulerModuleState::increaseEkosConnectFailureCount() +{ + return (++m_ekosConnectFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseParkingCapFailureCount() +{ + return (++m_parkingCapFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseParkingMountFailureCount() +{ + return (++m_parkingMountFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseParkingDomeFailureCount() +{ + return (++m_parkingDomeFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +void SchedulerModuleState::resetFailureCounters() +{ + resetIndiConnectFailureCount(); + resetEkosConnectFailureCount(); + resetFocusFailureCount(); + resetGuideFailureCount(); + resetAlignFailureCount(); + resetCaptureFailureCount(); +} + +bool SchedulerModuleState::increaseIndiConnectFailureCount() +{ + return (++m_indiConnectFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseCaptureFailureCount() +{ + return (++m_captureFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseFocusFailureCount() +{ + return (++m_focusFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseGuideFailureCount() +{ + return (++m_guideFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +bool SchedulerModuleState::increaseAlignFailureCount() +{ + return (++m_alignFailureCount <= MAX_FAILURE_ATTEMPTS); +} + +void SchedulerModuleState::setIndiState(INDIState state) +{ + if (m_indiState != state) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "INDI state changed from" << m_indiState << "to" << state; + m_indiState = state; + emit indiStateChanged(state); + } +} + +qint64 SchedulerModuleState::getCurrentOperationMsec() const +{ + if (!currentOperationTimeStarted) return 0; + return currentOperationTime.msecsTo(KStarsData::Instance()->ut()); +} + +void SchedulerModuleState::startCurrentOperationTimer() +{ + currentOperationTimeStarted = true; + currentOperationTime = KStarsData::Instance()->ut(); +} + +void SchedulerModuleState::cancelGuidingTimer() +{ + m_restartGuidingInterval = -1; + m_restartGuidingTime = KStarsDateTime(); +} + +bool SchedulerModuleState::isGuidingTimerActive() +{ + return (m_restartGuidingInterval > 0 && + m_restartGuidingTime.msecsTo(KStarsData::Instance()->ut()) >= 0); +} + +void SchedulerModuleState::startGuidingTimer(int milliseconds) +{ + m_restartGuidingInterval = milliseconds; + m_restartGuidingTime = KStarsData::Instance()->ut(); +} + +// Allows for unit testing of static Scheduler methods, +// as can't call KStarsData::Instance() during unit testing. +KStarsDateTime *SchedulerModuleState::storedLocalTime = nullptr; +KStarsDateTime SchedulerModuleState::getLocalTime() +{ + if (hasLocalTime()) + return *storedLocalTime; + return KStarsData::Instance()->geo()->UTtoLT(KStarsData::Instance()->clock()->utc()); +} + +void SchedulerModuleState::setupNextIteration(SchedulerTimerState nextState) +{ + setupNextIteration(nextState, m_UpdatePeriodMs); +} + +void SchedulerModuleState::setupNextIteration(SchedulerTimerState nextState, int milliseconds) +{ + if (iterationSetup()) + { + qCDebug(KSTARS_EKOS_SCHEDULER) + << QString("Multiple setupNextIteration calls: current %1 %2, previous %3 %4") + .arg(nextState).arg(milliseconds).arg(timerState()).arg(timerInterval()); + } + setTimerState(nextState); + // check if setup is called from a thread outside of the iteration timer thread + if (iterationTimer().isActive()) + { + // restart the timer to ensure the correct startup delay + int remaining = iterationTimer().remainingTime(); + iterationTimer().stop(); + setTimerInterval(std::max(0, milliseconds - remaining)); + iterationTimer().start(timerInterval()); + } + else + { + // setup called from inside the iteration timer thread + setTimerInterval(milliseconds); + } + setIterationSetup(true); +} + +uint SchedulerModuleState::maxFailureAttempts() +{ + return MAX_FAILURE_ATTEMPTS; +} +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulermodulestate.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,618 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include +#include +#include "ekos/ekos.h" +#include "indi/indiweather.h" +#include "kstarsdatetime.h" +#include "schedulertypes.h" +#include +#include + +class SchedulerJob; + +namespace Ekos +{ + +class SchedulerProcess; + +/** + * @class SchedulerState + * @brief The SchedulerState class holds all attributes defining the scheduler's state. + */ +class SchedulerModuleState : public QObject +{ + Q_OBJECT + +public: + + + SchedulerModuleState(); + + // //////////////////////////////////////////////////////////////////// + // profiles and scheduler jobs + // //////////////////////////////////////////////////////////////////// + + const QString ¤tProfile() const + { + return m_currentProfile; + } + /** + * @brief setCurrentProfile Set the current profile name. + * @param newName new current profile name + * @param signal send an update efent if true + */ + void setCurrentProfile(const QString &newName, bool signal = true); + + const QStringList &profiles() const + { + return m_profiles; + } + void updateProfiles(const QStringList &newProfiles); + + SchedulerJob *activeJob() const + { + return m_activeJob; + } + void setActiveJob(SchedulerJob *newActiveJob) + { + m_activeJob = newActiveJob; + } + + QList &mutlableJobs() + { + return m_jobs; + } + const QList &jobs() const + { + return m_jobs; + } + +void setJobs(QList &newJobs) + { + m_jobs = newJobs; + } + + // //////////////////////////////////////////////////////////////////// + // state attributes accessors + // //////////////////////////////////////////////////////////////////// + + bool dirty() const + { + return m_dirty; + } + void setDirty(bool value) + { + m_dirty = value; + } + + // (coarse grained) execution state of the scheduler + const SchedulerState &schedulerState() const + { + return m_schedulerState; + } + void setSchedulerState(const SchedulerState &newState) + { + m_schedulerState = newState; + } + + const StartupState &startupState() const + { + return m_startupState; + } + void setStartupState(StartupState state); + + const QUrl &startupScriptURL() const + { + return m_startupScriptURL; + } + void setStartupScriptURL(const QUrl &newURL) + { + m_startupScriptURL = newURL; + } + + const ShutdownState &shutdownState() const + { + return m_shutdownState; + } + void setShutdownState(ShutdownState state); + + const QUrl &shutdownScriptURL() const + { + return m_shutdownScriptURL; + } + void setShutdownScriptURL(const QUrl &newShutdownScriptURL) + { + m_shutdownScriptURL = newShutdownScriptURL; + } + + const ParkWaitState &parkWaitState() const + { + return m_parkWaitState; + } + void setParkWaitState(ParkWaitState state); + + + // //////////////////////////////////////////////////////////////////// + // Controls for the preemptive shutdown feature. + // //////////////////////////////////////////////////////////////////// + // Is the scheduler shutting down until later when it will resume a job? + void enablePreemptiveShutdown(const QDateTime &wakeupTime); + void disablePreemptiveShutdown(); + const QDateTime &preemptiveShutdownWakeupTime() const; + bool preemptiveShutdown() const; + + + // //////////////////////////////////////////////////////////////////// + // overall EKOS state + // //////////////////////////////////////////////////////////////////// + EkosState ekosState() const + { + return m_ekosState; + } + void setEkosState(EkosState state); + // last communication result with EKOS + CommunicationStatus ekosCommunicationStatus() const + { + return m_EkosCommunicationStatus; + } + void setEkosCommunicationStatus(CommunicationStatus newEkosCommunicationStatus) + { + m_EkosCommunicationStatus = newEkosCommunicationStatus; + } + // counter for failed EKOS connection attempts + void resetEkosConnectFailureCount(uint8_t newEkosConnectFailureCount = 0) + { + m_ekosConnectFailureCount = newEkosConnectFailureCount; + } + bool increaseEkosConnectFailureCount(); + + void resetParkingCapFailureCount(uint8_t value = 0) + { + m_parkingCapFailureCount = value; + } + bool increaseParkingCapFailureCount(); + void resetParkingMountFailureCount(uint8_t value = 0) + { + m_parkingMountFailureCount = value; + } + bool increaseParkingMountFailureCount(); + uint8_t parkingMountFailureCount() const + { + return m_parkingMountFailureCount; + } + void resetParkingDomeFailureCount(uint8_t value = 0) + { + m_parkingDomeFailureCount = value; + } + bool increaseParkingDomeFailureCount(); + + int indexToUse() const + { + return m_IndexToUse; + } + void setIndexToUse(int newIndexToUse) + { + m_IndexToUse = newIndexToUse; + } + + int healpixToUse() const + { + return m_HealpixToUse; + } + void setHealpixToUse(int newHealpixToUse) + { + m_HealpixToUse = newHealpixToUse; + } + + QMap &capturedFramesCount() + { + return m_CapturedFramesCount; + } + + void setCapturedFramesCount(const QMap &newCapturedFramesCount) + { + m_CapturedFramesCount = newCapturedFramesCount; + } + + /** + * @brief resetFailureCounters Reset all failure counters + */ + void resetFailureCounters(); + + // //////////////////////////////////////////////////////////////////// + // overall INDI state + // //////////////////////////////////////////////////////////////////// + INDIState indiState() const + { + return m_indiState; + } + void setIndiState(INDIState state); + // last communication result with INDI + CommunicationStatus indiCommunicationStatus() const + { + return m_INDICommunicationStatus; + } + void setIndiCommunicationStatus(CommunicationStatus newINDICommunicationStatus) + { + m_INDICommunicationStatus = newINDICommunicationStatus; + } + // counters for failed INDI connection attempts + void resetIndiConnectFailureCount(uint8_t newIndiConnectFailureCount = 0) + { + m_indiConnectFailureCount = newIndiConnectFailureCount; + } + bool increaseIndiConnectFailureCount(); + /** + * @brief isINDIConnected Determines the status of the INDI connection. + * @return True if INDI connection is up and usable, else false. + */ + bool isINDIConnected() const + { + return (indiCommunicationStatus() == Ekos::Success); + } + // //////////////////////////////////////////////////////////////////// + // device states + // //////////////////////////////////////////////////////////////////// + bool mountReady() const + { + return m_MountReady; + } + void setMountReady(bool readiness) + { + m_MountReady = readiness; + } + bool captureReady() const + { + return m_CaptureReady; + } + void setCaptureReady(bool readiness) + { + m_CaptureReady = readiness; + } + bool domeReady() const + { + return m_DomeReady; + } + void setDomeReady(bool readiness) + { + m_DomeReady = readiness; + } + bool capReady() const + { + return m_CapReady; + } + void setCapReady(bool readiness) + { + m_CapReady = readiness; + } + + uint16_t captureBatch() const + { + return m_captureBatch; + } + void resetCaptureBatch() + { + m_captureBatch = 0; + } + uint16_t increaseCaptureBatch() + { + return m_captureBatch++; + } + + uint8_t captureFailureCount() const + { + return m_captureFailureCount; + } + void resetCaptureFailureCount() + { + m_captureFailureCount = 0; + } + bool increaseCaptureFailureCount(); + + uint8_t focusFailureCount() const + { + return m_focusFailureCount; + } + void resetFocusFailureCount() + { + m_focusFailureCount = 0; + } + bool increaseFocusFailureCount(); + + bool autofocusCompleted() const + { + return m_autofocusCompleted; + } + void setAutofocusCompleted(bool value) + { + m_autofocusCompleted = value; + } + + uint8_t guideFailureCount() const + { + return m_guideFailureCount; + } + void resetGuideFailureCount() + { + m_guideFailureCount = 0; + } + bool increaseGuideFailureCount(); + + uint8_t alignFailureCount() const + { + return m_alignFailureCount; + } + void resetAlignFailureCount() + { + m_alignFailureCount = 0; + } + bool increaseAlignFailureCount(); + + int restartGuidingInterval() const + { + return m_restartGuidingInterval; + } + + const KStarsDateTime &restartGuidingTime() const + { + return m_restartGuidingTime; + } + + ISD::Weather::Status weatherStatus() const + { + return m_weatherStatus; + } + void setWeatherStatus(ISD::Weather::Status newWeatherStatus) + { + m_weatherStatus = newWeatherStatus; + } + + // //////////////////////////////////////////////////////////////////// + // Timers and time + // //////////////////////////////////////////////////////////////////// + // Returns milliseconds since startCurrentOperationTImer() was called. + qint64 getCurrentOperationMsec() const; + // Starts the above operation timer. + // TODO. It would be better to make this a class and give each operation its own timer. + // TODO. These should be disabled once no longer relevant. + // These are implement with a KStarsDateTime instead of a QTimer type class + // so that the simulated clock can be used. + void startCurrentOperationTimer(); + + // Controls for the guiding timer, which restarts guiding after failure. + void cancelGuidingTimer(); + bool isGuidingTimerActive(); + void startGuidingTimer(int milliseconds); + + /** @brief Setter used in testing to fix the local time. Otherwise getter gets from KStars instance. */ + /** @{ */ + static KStarsDateTime getLocalTime(); + static void setLocalTime(KStarsDateTime *time) + { + storedLocalTime = time; + } + static bool hasLocalTime() + { + return storedLocalTime != nullptr; + } + /** @} */ + + // //////////////////////////////////////////////////////////////////// + // Scheduler iterations + // //////////////////////////////////////////////////////////////////// + + // Setup the parameters for the next scheduler iteration. + // When milliseconds is not passed in, it uses m_UpdatePeriodMs. + void setupNextIteration(SchedulerTimerState nextState); + void setupNextIteration(SchedulerTimerState nextState, int milliseconds); + + SchedulerTimerState timerState() const + { + return m_timerState; + } + + void setTimerState(SchedulerTimerState newTimerState) + { + m_timerState = newTimerState; + } + + QTimer &iterationTimer() + { + return m_iterationTimer; + } + + bool iterationSetup() const + { + return m_iterationSetup; + } + void setIterationSetup(bool setup) + { + m_iterationSetup = setup; + } + + qint64 startMSecs() const + { + return m_startMSecs; + } + void setStartMSecs(qint64 value) + { + m_startMSecs = value; + } + int increaseSchedulerIteration() + { + return ++m_schedulerIteration; + } + void resetSchedulerIteration() + { + m_schedulerIteration = 0; + } + + int timerInterval() const + { + return m_timerInterval; + } + void setTimerInterval(int value) + { + m_timerInterval = value; + } + + void setUpdatePeriodMs(int ms) + { + m_UpdatePeriodMs = ms; + } + int updatePeriodMs() const + { + return m_UpdatePeriodMs; + } + + static uint maxFailureAttempts(); + +signals: + // //////////////////////////////////////////////////////////////////// + // communication with the UI + // //////////////////////////////////////////////////////////////////// + // State change of EKOS + void ekosStateChanged(EkosState state); + // State change of INDI + void indiStateChanged(INDIState state); + // startup state + void startupStateChanged(StartupState state); + // shutdown state + void shutdownStateChanged(ShutdownState state); + // parking state + void parkWaitStateChanged(ParkWaitState state); + // profiles updated + void profilesChanged(); + // current profile changed + void currentProfileChanged(); + +private: + // //////////////////////////////////////////////////////////////////// + // Scheduler jobs + // //////////////////////////////////////////////////////////////////// + // List of all jobs as entered by the user or file + QList m_jobs; + // Active job + SchedulerJob *m_activeJob { nullptr }; + + // //////////////////////////////////////////////////////////////////// + // state attributes + // //////////////////////////////////////////////////////////////////// + // coarse grained state describing the general execution state + SchedulerState m_schedulerState { SCHEDULER_IDLE }; + // states of the scheduler startup + StartupState m_startupState { STARTUP_IDLE }; + // Startup script URL + QUrl m_startupScriptURL; + // states of the scheduler shutdown + ShutdownState m_shutdownState { SHUTDOWN_IDLE }; + // Shutdown script URL + QUrl m_shutdownScriptURL; + // states of parking + ParkWaitState m_parkWaitState { PARKWAIT_IDLE }; + // current profile + QString m_currentProfile; + // all profiles + QStringList m_profiles; + // Was job modified and needs saving? + bool m_dirty { false }; + + // EKOS state describing whether EKOS is running (remember that the scheduler + // does not need EKOS running). + EkosState m_ekosState { EKOS_IDLE }; + // Execution state of INDI + INDIState m_indiState { INDI_IDLE }; + // Last communication result with EKOS and INDI + CommunicationStatus m_EkosCommunicationStatus { Ekos::Idle }; + CommunicationStatus m_INDICommunicationStatus { Ekos::Idle }; + + // device readiness + bool m_MountReady { false }; + bool m_CaptureReady { false }; + bool m_DomeReady { false }; + bool m_CapReady { false }; + + // Restricts (the internal solver) to using the index and healpix + // from the previous solve, if that solve was successful, when + // doing the pointing check. -1 means no restriction. + int m_IndexToUse { -1 }; + int m_HealpixToUse { -1 }; + + // Check if initial autofocus is completed and do not run autofocus until + // there is a change is telescope position/alignment. + bool m_autofocusCompleted { false }; + + // Keep watch of weather status + ISD::Weather::Status m_weatherStatus { ISD::Weather::WEATHER_IDLE }; + + // //////////////////////////////////////////////////////////////////// + // counters + // //////////////////////////////////////////////////////////////////// + // Keep track of INDI connection failures + uint8_t m_indiConnectFailureCount { 0 }; + // Keep track of Ekos connection failures + uint8_t m_ekosConnectFailureCount { 0 }; + // failures parking dust cap + uint8_t m_parkingCapFailureCount { 0 }; + // failures parking mount + uint8_t m_parkingMountFailureCount { 0 }; + // failures parking dome + uint8_t m_parkingDomeFailureCount { 0 }; + // How many repeated job batches did we complete thus far? + uint16_t m_captureBatch { 0 }; + // Keep track of Ekos capture module failures + uint8_t m_captureFailureCount { 0 }; + // Keep track of Ekos focus module failures + uint8_t m_focusFailureCount { 0 }; + // Keep track of Ekos guide module failures + uint8_t m_guideFailureCount { 0 }; + // Keep track of Ekos align module failures + uint8_t m_alignFailureCount { 0 }; + // frames count for all signatures + QMap m_CapturedFramesCount; + + // //////////////////////////////////////////////////////////////////// + // Scheduler iterations + // //////////////////////////////////////////////////////////////////// + + // The type of scheduler iteration that should be run next. + SchedulerTimerState m_timerState { RUN_NOTHING }; + // Variable keeping the number of millisconds the scheduler should wait + // after the current scheduler iteration. + int m_timerInterval { -1 }; + // Whether the scheduler has been setup for the next iteration, + // that is, whether timerInterval and timerState have been set this iteration. + bool m_iterationSetup { false }; + // The timer used to wakeup the scheduler between iterations. + QTimer m_iterationTimer; + // Counter for how many scheduler iterations have been processed. + int m_schedulerIteration { 0 }; + // The time when the scheduler first started running iterations. + qint64 m_startMSecs { 0 }; + // This is the time between typical scheduler iterations. + // The time can be modified for testing. + int m_UpdatePeriodMs = 1000; + + // //////////////////////////////////////////////////////////////////// + // timers + // //////////////////////////////////////////////////////////////////// + // Generic time to track timeout of current operation in progress. + // Used by startCurrentOperationTimer() and getCurrentOperationMsec(). + KStarsDateTime currentOperationTime; + bool currentOperationTimeStarted { false }; + // Delay for restarting the guider + int m_restartGuidingInterval { -1 }; + KStarsDateTime m_restartGuidingTime; + // Used in testing, instead of KStars::Instance() resources + static KStarsDateTime *storedLocalTime; + // The various preemptiveShutdown states are controlled by this one variable. + QDateTime m_preemptiveShutdownWakeupTime; +}; +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,2516 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "schedulerprocess.h" +#include "schedulermodulestate.h" +#include "schedulerjob.h" +#include "Options.h" +#include "ksmessagebox.h" +#include "ksnotification.h" +#include "kstarsdata.h" +#include "indi/indistd.h" +#include "skymapcomposite.h" +#include "mosaiccomponent.h" +#include "mosaictiles.h" +#include + +#include + +#define RESTART_GUIDING_DELAY_MS 5000 + +// This is a temporary debugging printout introduced while gaining experience developing +// the unit tests in test_ekos_scheduler_ops.cpp. +// All these printouts should be eventually removed. + +namespace Ekos +{ +SchedulerProcess::SchedulerProcess(QSharedPointer state) +{ + m_moduleState = state; +} + +void SchedulerProcess::startSlew() +{ + Q_ASSERT_X(nullptr != activeJob(), __FUNCTION__, "Job starting slewing must be valid"); + + // If the mount was parked by a pause or the end-user, unpark + if (isMountParked()) + { + moduleState()->setParkWaitState(PARKWAIT_UNPARK); + return; + } + + if (Options::resetMountModelBeforeJob()) + { + mountInterface()->call(QDBus::AutoDetect, "resetModel"); + } + + SkyPoint target = activeJob()->getTargetCoords(); + QList telescopeSlew; + telescopeSlew.append(target.ra().Hours()); + telescopeSlew.append(target.dec().Degrees()); + + QDBusReply const slewModeReply = mountInterface()->callWithArgumentList(QDBus::AutoDetect, "slew", + telescopeSlew); + + if (slewModeReply.error().type() != QDBusError::NoError) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' slew request received DBUS error: %2").arg( + activeJob()->getName(), QDBusError::errorString(slewModeReply.error().type())); + if (!manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); + } + else + { + activeJob()->setStage(SchedulerJob::STAGE_SLEWING); + emit newLog(i18n("Job '%1' is slewing to target.", activeJob()->getName())); + } +} + +void SchedulerProcess::startFocusing() +{ + Q_ASSERT_X(nullptr != activeJob(), __FUNCTION__, "Job starting focusing must be valid"); + + // 2017-09-30 Jasem: We're skipping post align focusing now as it can be performed + // when first focus request is made in capture module + if (activeJob()->getStage() == SchedulerJob::STAGE_RESLEWING_COMPLETE || + activeJob()->getStage() == SchedulerJob::STAGE_POSTALIGN_FOCUSING) + { + // Clear the HFR limit value set in the capture module + captureInterface()->call(QDBus::AutoDetect, "clearAutoFocusHFR"); + // Reset Focus frame so that next frame take a full-resolution capture first. + focusInterface()->call(QDBus::AutoDetect, "resetFrame"); + activeJob()->setStage(SchedulerJob::STAGE_POSTALIGN_FOCUSING_COMPLETE); + emit getNextAction(); + return; + } + + // Check if autofocus is supported + QDBusReply focusModeReply; + focusModeReply = focusInterface()->call(QDBus::AutoDetect, "canAutoFocus"); + + if (focusModeReply.error().type() != QDBusError::NoError) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' canAutoFocus request received DBUS error: %2").arg( + activeJob()->getName(), QDBusError::errorString(focusModeReply.error().type())); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + + if (focusModeReply.value() == false) + { + emit newLog(i18n("Warning: job '%1' is unable to proceed with autofocus, not supported.", activeJob()->getName())); + activeJob()->setStepPipeline( + static_cast(activeJob()->getStepPipeline() & ~SchedulerJob::USE_FOCUS)); + activeJob()->setStage(SchedulerJob::STAGE_FOCUS_COMPLETE); + emit getNextAction(); + return; + } + + // Clear the HFR limit value set in the capture module + captureInterface()->call(QDBus::AutoDetect, "clearAutoFocusHFR"); + + QDBusMessage reply; + + // We always need to reset frame first + if ((reply = focusInterface()->call(QDBus::AutoDetect, "resetFrame")).type() == QDBusMessage::ErrorMessage) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' resetFrame request received DBUS error: %2").arg( + activeJob()->getName(), reply.errorMessage()); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + + + // If we have a LIGHT filter set, let's set it. + if (!activeJob()->getInitialFilter().isEmpty()) + { + focusInterface()->setProperty("filter", activeJob()->getInitialFilter()); + } + + // Set autostar if full field option is false + if (Options::focusUseFullField() == false) + { + QList autoStar; + autoStar.append(true); + if ((reply = focusInterface()->callWithArgumentList(QDBus::AutoDetect, "setAutoStarEnabled", autoStar)).type() == + QDBusMessage::ErrorMessage) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' setAutoFocusStar request received DBUS error: %1").arg( + activeJob()->getName(), reply.errorMessage()); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + } + + // Start auto-focus + if ((reply = focusInterface()->call(QDBus::AutoDetect, "start")).type() == QDBusMessage::ErrorMessage) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: job '%1' startFocus request received DBUS error: %2").arg( + activeJob()->getName(), reply.errorMessage()); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + + activeJob()->setStage(SchedulerJob::STAGE_FOCUSING); + emit newLog(i18n("Job '%1' is focusing.", activeJob()->getName())); + moduleState()->startCurrentOperationTimer(); +} + +void SchedulerProcess::startAstrometry() +{ + Q_ASSERT_X(nullptr != activeJob(), __FUNCTION__, "Job starting aligning must be valid"); + + QDBusMessage reply; + setSolverAction(Align::GOTO_SLEW); + + // Always turn update coords on + //QVariant arg(true); + //alignInterface->call(QDBus::AutoDetect, "setUpdateCoords", arg); + + // Reset the solver speedup (using the last successful index file and healpix for the + // pointing check) when re-aligning. + moduleState()->setIndexToUse(-1); + moduleState()->setHealpixToUse(-1); + + // If FITS file is specified, then we use load and slew + if (activeJob()->getFITSFile().isEmpty() == false) + { + auto path = activeJob()->getFITSFile().toString(QUrl::PreferLocalFile); + // check if the file exists + if (QFile::exists(path) == false) + { + emit newLog(i18n("Warning: job '%1' target FITS file does not exist.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + return; + } + + QList solveArgs; + solveArgs.append(path); + + if ((reply = alignInterface()->callWithArgumentList(QDBus::AutoDetect, "loadAndSlew", solveArgs)).type() == + QDBusMessage::ErrorMessage) + { + emit newLog(i18n("Warning: job '%1' loadAndSlew request received DBUS error: %2", + activeJob()->getName(), reply.errorMessage())); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + else if (reply.arguments().first().toBool() == false) + { + emit newLog(i18n("Warning: job '%1' loadAndSlew request failed.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); + emit findNextJob(); + return; + } + + emit newLog(i18n("Job '%1' is plate solving %2.", activeJob()->getName(), activeJob()->getFITSFile().fileName())); + } + else + { + // JM 2020.08.20: Send J2000 TargetCoords to Align module so that we always resort back to the + // target original targets even if we drifted away due to any reason like guiding calibration failures. + const SkyPoint targetCoords = activeJob()->getTargetCoords(); + QList targetArgs, rotationArgs; + targetArgs << targetCoords.ra0().Hours() << targetCoords.dec0().Degrees(); + rotationArgs << activeJob()->getPositionAngle(); + + if ((reply = alignInterface()->callWithArgumentList(QDBus::AutoDetect, "setTargetCoords", + targetArgs)).type() == QDBusMessage::ErrorMessage) + { + emit newLog(i18n("Warning: job '%1' setTargetCoords request received DBUS error: %2", + activeJob()->getName(), reply.errorMessage())); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + + // Only send if it has valid value. + if (activeJob()->getPositionAngle() >= -180) + { + if ((reply = alignInterface()->callWithArgumentList(QDBus::AutoDetect, "setTargetPositionAngle", + rotationArgs)).type() == QDBusMessage::ErrorMessage) + { + emit newLog(i18n("Warning: job '%1' setTargetPositionAngle request received DBUS error: %2").arg( + activeJob()->getName(), reply.errorMessage())); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + } + + if ((reply = alignInterface()->call(QDBus::AutoDetect, "captureAndSolve")).type() == QDBusMessage::ErrorMessage) + { + emit newLog(i18n("Warning: job '%1' captureAndSolve request received DBUS error: %2").arg( + activeJob()->getName(), reply.errorMessage())); + if (!manageConnectionLoss()) + { + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + return; + } + else if (reply.arguments().first().toBool() == false) + { + emit newLog(i18n("Warning: job '%1' captureAndSolve request failed.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); + emit findNextJob(); + return; + } + + emit newLog(i18n("Job '%1' is capturing and plate solving.", activeJob()->getName())); + } + + /* FIXME: not supposed to modify the job */ + activeJob()->setStage(SchedulerJob::STAGE_ALIGNING); + moduleState()->startCurrentOperationTimer(); +} + +void SchedulerProcess::startGuiding(bool resetCalibration) +{ + Q_ASSERT_X(nullptr != activeJob(), __FUNCTION__, "Job starting guiding must be valid"); + + // avoid starting the guider twice + if (resetCalibration == false && getGuidingStatus() == GUIDE_GUIDING) + { + activeJob()->setStage(SchedulerJob::STAGE_GUIDING_COMPLETE); + emit newLog(i18n("Guiding already running for %1, starting next scheduler action...", activeJob()->getName())); + emit getNextAction(); + moduleState()->startCurrentOperationTimer(); + return; + } + + // Connect Guider + guideInterface()->call(QDBus::AutoDetect, "connectGuider"); + + // Set Auto Star to true + QVariant arg(true); + guideInterface()->call(QDBus::AutoDetect, "setAutoStarEnabled", arg); + + // Only reset calibration on trouble + // and if we are allowed to reset calibration (true by default) + if (resetCalibration && Options::resetGuideCalibration()) + { + guideInterface()->call(QDBus::AutoDetect, "clearCalibration"); + } + + guideInterface()->call(QDBus::AutoDetect, "guide"); + + activeJob()->setStage(SchedulerJob::STAGE_GUIDING); + + emit newLog(i18n("Starting guiding procedure for %1 ...", activeJob()->getName())); + + moduleState()->startCurrentOperationTimer(); +} + +void SchedulerProcess::stopGuiding() +{ + if (!guideInterface()) + return; + + // Tell guider to abort if the current job requires guiding - end-user may enable guiding manually before observation + if (nullptr != activeJob() && (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE)) + { + qCInfo(KSTARS_EKOS_SCHEDULER) << QString("Job '%1' is stopping guiding...").arg(activeJob()->getName()); + guideInterface()->call(QDBus::AutoDetect, "abort"); + moduleState()->resetGuideFailureCount(); + } + + // In any case, stop the automatic guider restart + if (moduleState()->isGuidingTimerActive()) + moduleState()->cancelGuidingTimer(); +} + +void SchedulerProcess::processGuidingTimer() +{ + if ((moduleState()->restartGuidingInterval() > 0) && + (moduleState()->restartGuidingTime().msecsTo(KStarsData::Instance()->ut()) > moduleState()->restartGuidingInterval())) + { + moduleState()->cancelGuidingTimer(); + startGuiding(true); + } +} + +void SchedulerProcess::startCapture(bool restart) +{ + Q_ASSERT_X(nullptr != activeJob(), __FUNCTION__, "Job starting capturing must be valid"); + + // ensure that guiding is running before we start capturing + if (activeJob()->getStepPipeline() & SchedulerJob::USE_GUIDE && getGuidingStatus() != GUIDE_GUIDING) + { + // guiding should run, but it doesn't. So start guiding first + activeJob()->setStage(SchedulerJob::STAGE_GUIDING); + startGuiding(); + return; + } + + captureInterface()->setProperty("targetName", activeJob()->getName()); + + QString url = activeJob()->getSequenceFile().toLocalFile(); + + if (restart == false) + { + QList dbusargs; + dbusargs.append(url); + // override targets from sequence queue file + QVariant targetName(activeJob()->getName()); + dbusargs.append(targetName); + QDBusReply const captureReply = captureInterface()->callWithArgumentList(QDBus::AutoDetect, + "loadSequenceQueue", + dbusargs); + if (captureReply.error().type() != QDBusError::NoError) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << + QString("Warning: job '%1' loadSequenceQueue request received DBUS error: %1").arg(activeJob()->getName()).arg( + captureReply.error().message()); + if (!manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); + return; + } + // Check if loading sequence fails for whatever reason + else if (captureReply.value() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << + QString("Warning: job '%1' loadSequenceQueue request failed").arg(activeJob()->getName()); + if (!manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); + return; + } + } + + + SchedulerJob::CapturedFramesMap fMap = activeJob()->getCapturedFramesMap(); + + for (auto &e : fMap.keys()) + { + QList dbusargs; + QDBusMessage reply; + + dbusargs.append(e); + dbusargs.append(fMap.value(e)); + if ((reply = captureInterface()->callWithArgumentList(QDBus::AutoDetect, "setCapturedFramesMap", + dbusargs)).type() == + QDBusMessage::ErrorMessage) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << + QString("Warning: job '%1' setCapturedFramesCount request received DBUS error: %1").arg(activeJob()->getName()).arg( + reply.errorMessage()); + if (!manageConnectionLoss()) + activeJob()->setState(SchedulerJob::JOB_ERROR); + return; + } + } + + // Start capture process + captureInterface()->call(QDBus::AutoDetect, "start"); + + activeJob()->setStage(SchedulerJob::STAGE_CAPTURING); + + KSNotification::event(QLatin1String("EkosScheduledImagingStart"), + i18n("Ekos job (%1) - Capture started", activeJob()->getName()), KSNotification::Scheduler); + + if (moduleState()->captureBatch() > 0) + emit newLog(i18n("Job '%1' capture is in progress (batch #%2)...", activeJob()->getName(), + moduleState()->captureBatch() + 1)); + else + emit newLog(i18n("Job '%1' capture is in progress...", activeJob()->getName())); + + moduleState()->startCurrentOperationTimer(); +} + +void SchedulerProcess::setSolverAction(Align::GotoMode mode) +{ + QVariant gotoMode(static_cast(mode)); + alignInterface()->call(QDBus::AutoDetect, "setSolverAction", gotoMode); +} + +void SchedulerProcess::loadProfiles() +{ + qCDebug(KSTARS_EKOS_SCHEDULER) << "Loading profiles"; + QDBusReply profiles = ekosInterface()->call(QDBus::AutoDetect, "getProfiles"); + + if (profiles.error().type() == QDBusError::NoError) + moduleState()->updateProfiles(profiles); +} + +void SchedulerProcess::executeScript(const QString &filename) +{ + emit newLog(i18n("Executing script %1...", filename)); + + connect(&scriptProcess(), &QProcess::readyReadStandardOutput, this, &SchedulerProcess::readProcessOutput); + + connect(&scriptProcess(), static_cast(&QProcess::finished), + this, [this](int exitCode, QProcess::ExitStatus) + { + checkProcessExit(exitCode); + }); + + QStringList arguments; + scriptProcess().start(filename, arguments); +} + +bool SchedulerProcess::checkEkosState() +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) + return false; + + switch (moduleState()->ekosState()) + { + case EKOS_IDLE: + { + if (moduleState()->ekosCommunicationStatus() == Ekos::Success) + { + moduleState()->setEkosState(EKOS_READY); + return true; + } + else + { + ekosInterface()->call(QDBus::AutoDetect, "start"); + moduleState()->setEkosState(EKOS_STARTING); + moduleState()->startCurrentOperationTimer(); + + qCInfo(KSTARS_EKOS_SCHEDULER) << "Ekos communication status is" << moduleState()->ekosCommunicationStatus() << + "Starting Ekos..."; + + return false; + } + } + + case EKOS_STARTING: + { + if (moduleState()->ekosCommunicationStatus() == Ekos::Success) + { + emit newLog(i18n("Ekos started.")); + moduleState()->resetEkosConnectFailureCount(); + moduleState()->setEkosState(EKOS_READY); + return true; + } + else if (moduleState()->ekosCommunicationStatus() == Ekos::Error) + { + if (moduleState()->increaseEkosConnectFailureCount()) + { + emit newLog(i18n("Starting Ekos failed. Retrying...")); + ekosInterface()->call(QDBus::AutoDetect, "start"); + return false; + } + + emit newLog(i18n("Starting Ekos failed.")); + emit stopScheduler(); + return false; + } + else if (moduleState()->ekosCommunicationStatus() == Ekos::Idle) + return false; + // If a minute passed, give up + else if (moduleState()->getCurrentOperationMsec() > (60 * 1000)) + { + if (moduleState()->increaseEkosConnectFailureCount()) + { + emit newLog(i18n("Starting Ekos timed out. Retrying...")); + ekosInterface()->call(QDBus::AutoDetect, "stop"); + QTimer::singleShot(1000, this, [&]() + { + ekosInterface()->call(QDBus::AutoDetect, "start"); + moduleState()->startCurrentOperationTimer(); + }); + return false; + } + + emit newLog(i18n("Starting Ekos timed out.")); + emit stopScheduler(); + return false; + } + } + break; + + case EKOS_STOPPING: + { + if (moduleState()->ekosCommunicationStatus() == Ekos::Idle) + { + emit newLog(i18n("Ekos stopped.")); + moduleState()->setEkosState(EKOS_IDLE); + return true; + } + } + break; + + case EKOS_READY: + return true; + } + return false; +} + +bool SchedulerProcess::checkINDIState() +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) + return false; + + switch (moduleState()->indiState()) + { + case INDI_IDLE: + { + if (moduleState()->indiCommunicationStatus() == Ekos::Success) + { + moduleState()->setIndiState(INDI_PROPERTY_CHECK); + moduleState()->resetIndiConnectFailureCount(); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking INDI Properties..."; + } + else + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Connecting INDI devices..."; + ekosInterface()->call(QDBus::AutoDetect, "connectDevices"); + moduleState()->setIndiState(INDI_CONNECTING); + + moduleState()->startCurrentOperationTimer(); + } + } + break; + + case INDI_CONNECTING: + { + if (moduleState()->indiCommunicationStatus() == Ekos::Success) + { + emit newLog(i18n("INDI devices connected.")); + moduleState()->setIndiState(INDI_PROPERTY_CHECK); + } + else if (moduleState()->indiCommunicationStatus() == Ekos::Error) + { + if (moduleState()->increaseIndiConnectFailureCount() <= moduleState()->maxFailureAttempts()) + { + emit newLog(i18n("One or more INDI devices failed to connect. Retrying...")); + ekosInterface()->call(QDBus::AutoDetect, "connectDevices"); + } + else + { + emit newLog(i18n("One or more INDI devices failed to connect. Check INDI control panel for details.")); + emit stopScheduler(); + } + } + // If 30 seconds passed, we retry + else if (moduleState()->getCurrentOperationMsec() > (30 * 1000)) + { + if (moduleState()->increaseIndiConnectFailureCount() <= moduleState()->maxFailureAttempts()) + { + emit newLog(i18n("One or more INDI devices timed out. Retrying...")); + ekosInterface()->call(QDBus::AutoDetect, "connectDevices"); + moduleState()->startCurrentOperationTimer(); + } + else + { + emit newLog(i18n("One or more INDI devices timed out. Check INDI control panel for details.")); + emit stopScheduler(); + } + } + } + break; + + case INDI_DISCONNECTING: + { + if (moduleState()->indiCommunicationStatus() == Ekos::Idle) + { + emit newLog(i18n("INDI devices disconnected.")); + moduleState()->setIndiState(INDI_IDLE); + return true; + } + } + break; + + case INDI_PROPERTY_CHECK: + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking INDI properties."; + // If dome unparking is required then we wait for dome interface + if (Options::schedulerUnparkDome() && moduleState()->domeReady() == false) + { + if (moduleState()->getCurrentOperationMsec() > (30 * 1000)) + { + moduleState()->startCurrentOperationTimer(); + emit newLog(i18n("Warning: dome device not ready after timeout, attempting to recover...")); + disconnectINDI(); + stopEkos(); + } + + emit newLog(i18n("Dome unpark required but dome is not yet ready.")); + return false; + } + + // If mount unparking is required then we wait for mount interface + if (Options::schedulerUnparkMount() && moduleState()->mountReady() == false) + { + if (moduleState()->getCurrentOperationMsec() > (30 * 1000)) + { + moduleState()->startCurrentOperationTimer(); + emit newLog(i18n("Warning: mount device not ready after timeout, attempting to recover...")); + disconnectINDI(); + stopEkos(); + } + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount unpark required but mount is not yet ready."; + return false; + } + + // If cap unparking is required then we wait for cap interface + if (Options::schedulerOpenDustCover() && moduleState()->capReady() == false) + { + if (moduleState()->getCurrentOperationMsec() > (30 * 1000)) + { + moduleState()->startCurrentOperationTimer(); + emit newLog(i18n("Warning: cap device not ready after timeout, attempting to recover...")); + disconnectINDI(); + stopEkos(); + } + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Cap unpark required but cap is not yet ready."; + return false; + } + + // capture interface is required at all times to proceed. + if (captureInterface().isNull()) + return false; + + if (moduleState()->captureReady() == false) + { + QVariant hasCoolerControl = captureInterface()->property("coolerControl"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Cooler control" << (!hasCoolerControl.isValid() ? "invalid" : + (hasCoolerControl.toBool() ? "True" : "Faklse")); + if (hasCoolerControl.isValid()) + moduleState()->setCaptureReady(true); + else + qCWarning(KSTARS_EKOS_SCHEDULER) << "Capture module is not ready yet..."; + } + + moduleState()->setIndiState(INDI_READY); + moduleState()->resetIndiConnectFailureCount(); + return true; + } + + case INDI_READY: + return true; + } + + return false; +} + +bool SchedulerProcess::completeShutdown() +{ + // If INDI is not done disconnecting, try again later + if (moduleState()->indiState() == INDI_DISCONNECTING + && checkINDIState() == false) + return false; + + // Disconnect INDI if required first + if (moduleState()->indiState() != INDI_IDLE && Options::stopEkosAfterShutdown()) + { + disconnectINDI(); + return false; + } + + // If Ekos is not done stopping, try again later + if (moduleState()->ekosState() == EKOS_STOPPING && checkEkosState() == false) + return false; + + // Stop Ekos if required. + if (moduleState()->ekosState() != EKOS_IDLE && Options::stopEkosAfterShutdown()) + { + stopEkos(); + return false; + } + + if (moduleState()->shutdownState() == SHUTDOWN_COMPLETE) + emit newLog(i18n("Shutdown complete.")); + else + emit newLog(i18n("Shutdown procedure failed, aborting...")); + + // Stop Scheduler + emit stopScheduler(); + + return true; +} + +void SchedulerProcess::disconnectINDI() +{ + qCInfo(KSTARS_EKOS_SCHEDULER) << "Disconnecting INDI..."; + moduleState()->setIndiState(INDI_DISCONNECTING); + ekosInterface()->call(QDBus::AutoDetect, "disconnectDevices"); +} + +void SchedulerProcess::stopEkos() +{ + qCInfo(KSTARS_EKOS_SCHEDULER) << "Stopping Ekos..."; + moduleState()->setEkosState(EKOS_STOPPING); + moduleState()->resetEkosConnectFailureCount(); + ekosInterface()->call(QDBus::AutoDetect, "stop"); + moduleState()->setMountReady(false); + moduleState()->setCaptureReady(false); + moduleState()->setDomeReady(false); + moduleState()->setCapReady(false); +} + +bool SchedulerProcess::manageConnectionLoss() +{ + if (SCHEDULER_RUNNING != moduleState()->schedulerState()) + return false; + + // Don't manage loss if Ekos is actually down in the state machine + switch (moduleState()->ekosState()) + { + case EKOS_IDLE: + case EKOS_STOPPING: + return false; + + default: + break; + } + + // Don't manage loss if INDI is actually down in the state machine + switch (moduleState()->indiState()) + { + case INDI_IDLE: + case INDI_DISCONNECTING: + return false; + + default: + break; + } + + // If Ekos is assumed to be up, check its state + //QDBusReply const isEkosStarted = ekosInterface->call(QDBus::AutoDetect, "getEkosStartingStatus"); + if (moduleState()->ekosCommunicationStatus() == Ekos::Success) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Ekos is currently connected, checking INDI before mitigating connection loss."); + + // If INDI is assumed to be up, check its state + if (moduleState()->isINDIConnected()) + { + // If both Ekos and INDI are assumed up, and are actually up, no mitigation needed, this is a DBus interface error + qCDebug(KSTARS_EKOS_SCHEDULER) << QString("INDI is currently connected, no connection loss mitigation needed."); + return false; + } + } + + // Stop actions of the current job + emit stopCurrentJobAction(); + + // Acknowledge INDI and Ekos disconnections + disconnectINDI(); + stopEkos(); + + // Let the Scheduler attempt to connect INDI again + return true; + +} + +void SchedulerProcess::checkCapParkingStatus() +{ + if (capInterface().isNull()) + return; + + QVariant parkingStatus = capInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( + capInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + switch (status) + { + case ISD::PARK_PARKED: + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_CAP) + { + emit newLog(i18n("Cap parked.")); + moduleState()->setShutdownState(SHUTDOWN_PARK_MOUNT); + } + moduleState()->resetParkingCapFailureCount(); + break; + + case ISD::PARK_UNPARKED: + if (moduleState()->startupState() == STARTUP_UNPARKING_CAP) + { + moduleState()->setStartupState(STARTUP_COMPLETE); + emit newLog(i18n("Cap unparked.")); + } + moduleState()->resetParkingCapFailureCount(); + break; + + case ISD::PARK_PARKING: + case ISD::PARK_UNPARKING: + // TODO make the timeouts configurable by the user + if (moduleState()->getCurrentOperationMsec() > (60 * 1000)) + { + if (moduleState()->increaseParkingCapFailureCount()) + { + emit newLog(i18n("Operation timeout. Restarting operation...")); + if (status == ISD::PARK_PARKING) + parkCap(); + else + unParkCap(); + break; + } + } + break; + + case ISD::PARK_ERROR: + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_CAP) + { + emit newLog(i18n("Cap parking error.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + } + else if (moduleState()->startupState() == STARTUP_UNPARKING_CAP) + { + emit newLog(i18n("Cap unparking error.")); + moduleState()->setStartupState(STARTUP_ERROR); + } + moduleState()->resetParkingCapFailureCount(); + break; + + default: + break; + } +} + +void SchedulerProcess::checkMountParkingStatus() +{ + if (mountInterface().isNull()) + return; + + QVariant parkingStatus = mountInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + switch (status) + { + //case Mount::PARKING_OK: + case ISD::PARK_PARKED: + // If we are starting up, we will unpark the mount in checkParkWaitState soon + // If we are shutting down and mount is parked, proceed to next step + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_MOUNT) + moduleState()->setShutdownState(SHUTDOWN_PARK_DOME); + + // Update parking engine state + if (moduleState()->parkWaitState() == PARKWAIT_PARKING) + moduleState()->setParkWaitState(PARKWAIT_PARKED); + + emit newLog(i18n("Mount parked.")); + moduleState()->resetParkingMountFailureCount(); + break; + + //case Mount::UNPARKING_OK: + case ISD::PARK_UNPARKED: + // If we are starting up and mount is unparked, proceed to next step + // If we are shutting down, we will park the mount in checkParkWaitState soon + if (moduleState()->startupState() == STARTUP_UNPARKING_MOUNT) + moduleState()->setStartupState(STARTUP_UNPARK_CAP); + + // Update parking engine state + if (moduleState()->parkWaitState() == PARKWAIT_UNPARKING) + moduleState()->setParkWaitState(PARKWAIT_UNPARKED); + + emit newLog(i18n("Mount unparked.")); + moduleState()->resetParkingMountFailureCount(); + break; + + // FIXME: Create an option for the parking/unparking timeout. + + //case Mount::UNPARKING_BUSY: + case ISD::PARK_UNPARKING: + if (moduleState()->getCurrentOperationMsec() > (60 * 1000)) + { + if (moduleState()->increaseParkingMountFailureCount()) + { + emit newLog(i18n("Warning: mount unpark operation timed out on attempt %1/%2. Restarting operation...", + moduleState()->parkingMountFailureCount(), moduleState()->maxFailureAttempts())); + unParkMount(); + } + else + { + emit newLog(i18n("Warning: mount unpark operation timed out on last attempt.")); + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + } + else qCInfo(KSTARS_EKOS_SCHEDULER) << "Unparking mount in progress..."; + + break; + + //case Mount::PARKING_BUSY: + case ISD::PARK_PARKING: + if (moduleState()->getCurrentOperationMsec() > (60 * 1000)) + { + if (moduleState()->increaseParkingMountFailureCount()) + { + emit newLog(i18n("Warning: mount park operation timed out on attempt %1/%2. Restarting operation...", + moduleState()->parkingMountFailureCount(), + moduleState()->maxFailureAttempts())); + parkMount(); + } + else + { + emit newLog(i18n("Warning: mount park operation timed out on last attempt.")); + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + } + else qCInfo(KSTARS_EKOS_SCHEDULER) << "Parking mount in progress..."; + + break; + + //case Mount::PARKING_ERROR: + case ISD::PARK_ERROR: + if (moduleState()->startupState() == STARTUP_UNPARKING_MOUNT) + { + emit newLog(i18n("Mount unparking error.")); + moduleState()->setStartupState(STARTUP_ERROR); + moduleState()->resetParkingMountFailureCount(); + } + else if (moduleState()->shutdownState() == SHUTDOWN_PARKING_MOUNT) + { + if (moduleState()->increaseParkingMountFailureCount()) + { + emit newLog(i18n("Warning: mount park operation failed on attempt %1/%2. Restarting operation...", + moduleState()->parkingMountFailureCount(), + moduleState()->maxFailureAttempts())); + parkMount(); + } + else + { + emit newLog(i18n("Mount parking error.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + moduleState()->resetParkingMountFailureCount(); + } + + } + else if (moduleState()->parkWaitState() == PARKWAIT_PARKING) + { + emit newLog(i18n("Mount parking error.")); + moduleState()->setParkWaitState(PARKWAIT_ERROR); + moduleState()->resetParkingMountFailureCount(); + } + else if (moduleState()->parkWaitState() == PARKWAIT_UNPARKING) + { + emit newLog(i18n("Mount unparking error.")); + moduleState()->setParkWaitState(PARKWAIT_ERROR); + moduleState()->resetParkingMountFailureCount(); + } + break; + + //case Mount::PARKING_IDLE: + // FIXME Does this work as intended? check! + case ISD::PARK_UNKNOWN: + // Last parking action did not result in an action, so proceed to next step + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_MOUNT) + moduleState()->setShutdownState(SHUTDOWN_PARK_DOME); + + // Last unparking action did not result in an action, so proceed to next step + if (moduleState()->startupState() == STARTUP_UNPARKING_MOUNT) + moduleState()->setStartupState(STARTUP_UNPARK_CAP); + + // Update parking engine state + if (moduleState()->parkWaitState() == PARKWAIT_PARKING) + moduleState()->setParkWaitState(PARKWAIT_PARKED); + else if (moduleState()->parkWaitState() == PARKWAIT_UNPARKING) + moduleState()->setParkWaitState(PARKWAIT_UNPARKED); + + moduleState()->resetParkingMountFailureCount(); + break; + } +} + +void SchedulerProcess::checkDomeParkingStatus() +{ + if (domeInterface().isNull()) + return; + + QVariant parkingStatus = domeInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Dome parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + switch (status) + { + case ISD::PARK_PARKED: + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_DOME) + { + emit newLog(i18n("Dome parked.")); + + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + } + moduleState()->resetParkingDomeFailureCount(); + break; + + case ISD::PARK_UNPARKED: + if (moduleState()->startupState() == STARTUP_UNPARKING_DOME) + { + moduleState()->setStartupState(STARTUP_UNPARK_MOUNT); + emit newLog(i18n("Dome unparked.")); + } + moduleState()->resetParkingDomeFailureCount(); + break; + + case ISD::PARK_PARKING: + case ISD::PARK_UNPARKING: + // TODO make the timeouts configurable by the user + if (moduleState()->getCurrentOperationMsec() > (120 * 1000)) + { + if (moduleState()->increaseParkingDomeFailureCount()) + { + emit newLog(i18n("Operation timeout. Restarting operation...")); + if (status == ISD::PARK_PARKING) + parkDome(); + else + unParkDome(); + break; + } + } + break; + + case ISD::PARK_ERROR: + if (moduleState()->shutdownState() == SHUTDOWN_PARKING_DOME) + { + if (moduleState()->increaseParkingDomeFailureCount()) + { + emit newLog(i18n("Dome parking failed. Restarting operation...")); + parkDome(); + } + else + { + emit newLog(i18n("Dome parking error.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + moduleState()->resetParkingDomeFailureCount(); + } + } + else if (moduleState()->startupState() == STARTUP_UNPARKING_DOME) + { + if (moduleState()->increaseParkingDomeFailureCount()) + { + emit newLog(i18n("Dome unparking failed. Restarting operation...")); + unParkDome(); + } + else + { + emit newLog(i18n("Dome unparking error.")); + moduleState()->setStartupState(STARTUP_ERROR); + moduleState()->resetParkingDomeFailureCount(); + } + } + break; + + default: + break; + } +} + +bool SchedulerProcess::checkStartupState() +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) + return false; + + qCDebug(KSTARS_EKOS_SCHEDULER) << QString("Checking Startup State (%1)...").arg(moduleState()->startupState()); + + switch (moduleState()->startupState()) + { + case STARTUP_IDLE: + { + KSNotification::event(QLatin1String("ObservatoryStartup"), i18n("Observatory is in the startup process"), + KSNotification::Scheduler); + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Startup Idle. Starting startup process..."; + + // If Ekos is already started, we skip the script and move on to dome unpark step + // unless we do not have light frames, then we skip all + //QDBusReply isEkosStarted; + //isEkosStarted = ekosInterface->call(QDBus::AutoDetect, "getEkosStartingStatus"); + //if (isEkosStarted.value() == Ekos::Success) + if (moduleState()->ekosCommunicationStatus() == Ekos::Success) + { + if (moduleState()->startupScriptURL().isEmpty() == false) + emit newLog(i18n("Ekos is already started, skipping startup script...")); + + if (!activeJob() || activeJob()->getLightFramesRequired()) + moduleState()->setStartupState(STARTUP_UNPARK_DOME); + else + moduleState()->setStartupState(STARTUP_COMPLETE); + return true; + } + + if (moduleState()->currentProfile() != i18n("Default")) + { + QList profile; + profile.append(moduleState()->currentProfile()); + ekosInterface()->callWithArgumentList(QDBus::AutoDetect, "setProfile", profile); + } + + if (moduleState()->startupScriptURL().isEmpty() == false) + { + moduleState()->setStartupState(STARTUP_SCRIPT); + executeScript(moduleState()->startupScriptURL().toString(QUrl::PreferLocalFile)); + return false; + } + + moduleState()->setStartupState(STARTUP_UNPARK_DOME); + return false; + } + + case STARTUP_SCRIPT: + return false; + + case STARTUP_UNPARK_DOME: + // If there is no job in case of manual startup procedure, + // or if the job requires light frames, let's proceed with + // unparking the dome, otherwise startup process is complete. + if (activeJob() == nullptr || activeJob()->getLightFramesRequired()) + { + if (Options::schedulerUnparkDome()) + unParkDome(); + else + moduleState()->setStartupState(STARTUP_UNPARK_MOUNT); + } + else + { + moduleState()->setStartupState(STARTUP_COMPLETE); + return true; + } + + break; + + case STARTUP_UNPARKING_DOME: + checkDomeParkingStatus(); + break; + + case STARTUP_UNPARK_MOUNT: + if (Options::schedulerUnparkMount()) + unParkMount(); + else + moduleState()->setStartupState(STARTUP_UNPARK_CAP); + break; + + case STARTUP_UNPARKING_MOUNT: + checkMountParkingStatus(); + break; + + case STARTUP_UNPARK_CAP: + if (Options::schedulerOpenDustCover()) + unParkCap(); + else + moduleState()->setStartupState(STARTUP_COMPLETE); + break; + + case STARTUP_UNPARKING_CAP: + checkCapParkingStatus(); + break; + + case STARTUP_COMPLETE: + return true; + + case STARTUP_ERROR: + emit stopScheduler(); + return true; + } + + return false; +} + +bool SchedulerProcess::checkShutdownState() +{ + qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking shutdown state..."; + + switch (moduleState()->shutdownState()) + { + case SHUTDOWN_IDLE: + + if (Options::schedulerWarmCCD()) + { + emit newLog(i18n("Warming up CCD...")); + + // Turn it off + //QVariant arg(false); + //captureInterface->call(QDBus::AutoDetect, "setCoolerControl", arg); + if (captureInterface()) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Setting coolerControl=false"; + captureInterface()->setProperty("coolerControl", false); + } + } + + // The following steps require a connection to the INDI server + if (moduleState()->isINDIConnected()) + { + if (Options::schedulerCloseDustCover()) + { + moduleState()->setShutdownState(SHUTDOWN_PARK_CAP); + return false; + } + + if (Options::schedulerParkMount()) + { + moduleState()->setShutdownState(SHUTDOWN_PARK_MOUNT); + return false; + } + + if (Options::schedulerParkDome()) + { + moduleState()->setShutdownState(SHUTDOWN_PARK_DOME); + return false; + } + } + else emit newLog(i18n("Warning: Bypassing parking procedures, no INDI connection.")); + + if (moduleState()->shutdownScriptURL().isEmpty() == false) + { + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + return false; + } + + moduleState()->setShutdownState(SHUTDOWN_COMPLETE); + return true; + + case SHUTDOWN_PARK_CAP: + if (!moduleState()->isINDIConnected()) + { + qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + } + else if (Options::schedulerCloseDustCover()) + parkCap(); + else + moduleState()->setShutdownState(SHUTDOWN_PARK_MOUNT); + break; + + case SHUTDOWN_PARKING_CAP: + checkCapParkingStatus(); + break; + + case SHUTDOWN_PARK_MOUNT: + if (!moduleState()->isINDIConnected()) + { + qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + } + else if (Options::schedulerParkMount()) + parkMount(); + else + moduleState()->setShutdownState(SHUTDOWN_PARK_DOME); + break; + + case SHUTDOWN_PARKING_MOUNT: + checkMountParkingStatus(); + break; + + case SHUTDOWN_PARK_DOME: + if (!moduleState()->isINDIConnected()) + { + qCInfo(KSTARS_EKOS_SCHEDULER) << "Bypassing shutdown step 'park cap', no INDI connection."; + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + } + else if (Options::schedulerParkDome()) + parkDome(); + else + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + break; + + case SHUTDOWN_PARKING_DOME: + checkDomeParkingStatus(); + break; + + case SHUTDOWN_SCRIPT: + if (moduleState()->shutdownScriptURL().isEmpty() == false) + { + // Need to stop Ekos now before executing script if it happens to stop INDI + if (moduleState()->ekosState() != EKOS_IDLE && Options::shutdownScriptTerminatesINDI()) + { + stopEkos(); + return false; + } + + moduleState()->setShutdownState(SHUTDOWN_SCRIPT_RUNNING); + executeScript(moduleState()->shutdownScriptURL().toString(QUrl::PreferLocalFile)); + } + else + moduleState()->setShutdownState(SHUTDOWN_COMPLETE); + break; + + case SHUTDOWN_SCRIPT_RUNNING: + return false; + + case SHUTDOWN_COMPLETE: + return completeShutdown(); + + case SHUTDOWN_ERROR: + emit stopScheduler(); + return true; + } + + return false; +} + +bool SchedulerProcess::checkParkWaitState() +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED) + return false; + + if (moduleState()->parkWaitState() == PARKWAIT_IDLE) + return true; + + // qCDebug(KSTARS_EKOS_SCHEDULER) << "Checking Park Wait State..."; + + switch (moduleState()->parkWaitState()) + { + case PARKWAIT_PARK: + parkMount(); + break; + + case PARKWAIT_PARKING: + checkMountParkingStatus(); + break; + + case PARKWAIT_UNPARK: + unParkMount(); + break; + + case PARKWAIT_UNPARKING: + checkMountParkingStatus(); + break; + + case PARKWAIT_IDLE: + case PARKWAIT_PARKED: + case PARKWAIT_UNPARKED: + return true; + + case PARKWAIT_ERROR: + emit newLog(i18n("park/unpark wait procedure failed, aborting...")); + emit stopScheduler(); + return true; + + } + + return false; +} + +void SchedulerProcess::runStartupProcedure() +{ + if (moduleState()->startupState() == STARTUP_IDLE + || moduleState()->startupState() == STARTUP_ERROR + || moduleState()->startupState() == STARTUP_COMPLETE) + { + connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this]() + { + KSMessageBox::Instance()->disconnect(this); + + emit newLog(i18n("Warning: executing startup procedure manually...")); + moduleState()->setStartupState(STARTUP_IDLE); + checkStartupState(); + QTimer::singleShot(1000, this, SLOT(checkStartupProcedure())); + + }); + + KSMessageBox::Instance()->questionYesNo(i18n("Are you sure you want to execute the startup procedure manually?")); + } + else + { + switch (moduleState()->startupState()) + { + case STARTUP_IDLE: + break; + + case STARTUP_SCRIPT: + scriptProcess().terminate(); + break; + + case STARTUP_UNPARK_DOME: + break; + + case STARTUP_UNPARKING_DOME: + qCDebug(KSTARS_EKOS_SCHEDULER) << "Aborting unparking dome..."; + domeInterface()->call(QDBus::AutoDetect, "abort"); + break; + + case STARTUP_UNPARK_MOUNT: + break; + + case STARTUP_UNPARKING_MOUNT: + qCDebug(KSTARS_EKOS_SCHEDULER) << "Aborting unparking mount..."; + mountInterface()->call(QDBus::AutoDetect, "abort"); + break; + + case STARTUP_UNPARK_CAP: + break; + + case STARTUP_UNPARKING_CAP: + break; + + case STARTUP_COMPLETE: + break; + + case STARTUP_ERROR: + break; + } + + moduleState()->setStartupState(STARTUP_IDLE); + + emit newLog(i18n("Startup procedure terminated.")); + } + +} + +void SchedulerProcess::runShutdownProcedure() +{ + if (moduleState()->shutdownState() == SHUTDOWN_IDLE + || moduleState()->shutdownState() == SHUTDOWN_ERROR + || moduleState()->shutdownState() == SHUTDOWN_COMPLETE) + { + connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this]() + { + KSMessageBox::Instance()->disconnect(this); + emit newLog(i18n("Warning: executing shutdown procedure manually...")); + moduleState()->setShutdownState(SHUTDOWN_IDLE); + checkShutdownState(); + QTimer::singleShot(1000, this, SLOT(checkShutdownProcedure())); + }); + + KSMessageBox::Instance()->questionYesNo(i18n("Are you sure you want to execute the shutdown procedure manually?")); + } + else + { + switch (moduleState()->shutdownState()) + { + case SHUTDOWN_IDLE: + break; + + case SHUTDOWN_SCRIPT: + break; + + case SHUTDOWN_SCRIPT_RUNNING: + scriptProcess().terminate(); + break; + + case SHUTDOWN_PARK_DOME: + break; + + case SHUTDOWN_PARKING_DOME: + qCDebug(KSTARS_EKOS_SCHEDULER) << "Aborting parking dome..."; + domeInterface()->call(QDBus::AutoDetect, "abort"); + break; + + case SHUTDOWN_PARK_MOUNT: + break; + + case SHUTDOWN_PARKING_MOUNT: + qCDebug(KSTARS_EKOS_SCHEDULER) << "Aborting parking mount..."; + mountInterface()->call(QDBus::AutoDetect, "abort"); + break; + + case SHUTDOWN_PARK_CAP: + case SHUTDOWN_PARKING_CAP: + break; + + case SHUTDOWN_COMPLETE: + break; + + case SHUTDOWN_ERROR: + break; + } + + moduleState()->setShutdownState(SHUTDOWN_IDLE); + + emit newLog(i18n("Shutdown procedure terminated.")); + } +} + +bool SchedulerProcess::saveScheduler(const QUrl &fileURL) +{ + QFile file; + file.setFileName(fileURL.toLocalFile()); + + if (!file.open(QIODevice::WriteOnly)) + { + QString message = i18n("Unable to write to file %1", fileURL.toLocalFile()); + KSNotification::sorry(message, i18n("Could Not Open File")); + return false; + } + + QTextStream outstream(&file); + + // We serialize sequence data to XML using the C locale + QLocale cLocale = QLocale::c(); + + outstream << "" << Qt::endl; + outstream << "" << Qt::endl; + // ensure to escape special XML characters + outstream << "" << QString(entityXML(strdup(moduleState()->currentProfile().toStdString().c_str()))) << + "" << Qt::endl; + + auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles(); + bool useMosaicInfo = !tiles->sequenceFile().isEmpty(); + + if (useMosaicInfo) + { + outstream << "" << Qt::endl; + outstream << "" << tiles->targetName() << "" << Qt::endl; + outstream << "" << tiles->group() << "" << Qt::endl; + + QString ccArg, ccValue = tiles->completionCondition(&ccArg); + if (ccValue == "FinishSequence") + outstream << "" << Qt::endl; + else if (ccValue == "FinishLoop") + outstream << "" << Qt::endl; + else if (ccValue == "FinishRepeat") + outstream << "" << ccArg << "" << Qt::endl; + + outstream << "" << tiles->sequenceFile() << "" << Qt::endl; + outstream << "" << tiles->outputDirectory() << "" << Qt::endl; + + outstream << "" << tiles->focusEveryN() << "" << Qt::endl; + outstream << "" << tiles->alignEveryN() << "" << Qt::endl; + if (tiles->isTrackChecked()) + outstream << "" << Qt::endl; + if (tiles->isFocusChecked()) + outstream << "" << Qt::endl; + if (tiles->isAlignChecked()) + outstream << "" << Qt::endl; + if (tiles->isGuideChecked()) + outstream << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->overlap()) << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->ra0().Hours()) << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->dec0().Degrees()) << "" << Qt::endl; + outstream << "" << tiles->gridSize().width() << "" << Qt::endl; + outstream << "" << tiles->gridSize().height() << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->mosaicFOV().width()) << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->mosaicFOV().height()) << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->cameraFOV().width()) << "" << Qt::endl; + outstream << "" << cLocale.toString(tiles->cameraFOV().height()) << "" << Qt::endl; + outstream << "" << Qt::endl; + } + + int index = 0; + for (auto &job : moduleState()->jobs()) + { + outstream << "" << Qt::endl; + + // ensure to escape special XML characters + outstream << "" << QString(entityXML(strdup(job->getName().toStdString().c_str()))) << "" << Qt::endl; + outstream << "" << QString(entityXML(strdup(job->getGroup().toStdString().c_str()))) << "" << Qt::endl; + outstream << "" << Qt::endl; + outstream << "" << cLocale.toString(job->getTargetCoords().ra0().Hours()) << "" << Qt::endl; + outstream << "" << cLocale.toString(job->getTargetCoords().dec0().Degrees()) << "" << Qt::endl; + outstream << "" << Qt::endl; + + if (job->getFITSFile().isValid() && job->getFITSFile().isEmpty() == false) + outstream << "" << job->getFITSFile().toLocalFile() << "" << Qt::endl; + else + outstream << "" << job->getPositionAngle() << "" << Qt::endl; + + outstream << "" << job->getSequenceFile().toLocalFile() << "" << Qt::endl; + + if (useMosaicInfo && index < tiles->tiles().size()) + { + auto oneTile = tiles->tiles().at(index++); + outstream << "" << Qt::endl; + outstream << "" << cLocale.toString(oneTile->center.x()) << "" << Qt::endl; + outstream << "" << cLocale.toString(oneTile->center.y()) << "" << Qt::endl; + outstream << "" << cLocale.toString(oneTile->rotation) << "" << Qt::endl; + outstream << "" << Qt::endl; + } + + outstream << "" << Qt::endl; + if (job->getFileStartupCondition() == START_ASAP) + outstream << "ASAP" << Qt::endl; + else if (job->getFileStartupCondition() == START_AT) + outstream << "At" + << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + if (job->hasMinAltitude()) + outstream << "MinimumAltitude" << + Qt::endl; + if (job->getMinMoonSeparation() > 0) + outstream << "MoonSeparation" + << Qt::endl; + if (job->getEnforceWeather()) + outstream << "EnforceWeather" << Qt::endl; + if (job->getEnforceTwilight()) + outstream << "EnforceTwilight" << Qt::endl; + if (job->getEnforceArtificialHorizon()) + outstream << "EnforceArtificialHorizon" << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + if (job->getCompletionCondition() == FINISH_SEQUENCE) + outstream << "Sequence" << Qt::endl; + else if (job->getCompletionCondition() == FINISH_REPEAT) + outstream << "Repeat" << Qt::endl; + else if (job->getCompletionCondition() == FINISH_LOOP) + outstream << "Loop" << Qt::endl; + else if (job->getCompletionCondition() == FINISH_AT) + outstream << "At" + << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + if (job->getStepPipeline() & SchedulerJob::USE_TRACK) + outstream << "Track" << Qt::endl; + if (job->getStepPipeline() & SchedulerJob::USE_FOCUS) + outstream << "Focus" << Qt::endl; + if (job->getStepPipeline() & SchedulerJob::USE_ALIGN) + outstream << "Align" << Qt::endl; + if (job->getStepPipeline() & SchedulerJob::USE_GUIDE) + outstream << "Guide" << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + } + + outstream << "" << Qt::endl; + outstream << "" << Qt::endl; + if (Options::rescheduleErrors()) + outstream << "" << Qt::endl; + outstream << "" << Options::errorHandlingStrategyDelay() << "" << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + if (moduleState()->startupScriptURL().isEmpty() == false) + outstream << "StartupScript" << Qt::endl; + if (Options::schedulerUnparkDome()) + outstream << "UnparkDome" << Qt::endl; + if (Options::schedulerUnparkMount()) + outstream << "UnparkMount" << Qt::endl; + if (Options::schedulerOpenDustCover()) + outstream << "UnparkCap" << Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + if (Options::schedulerWarmCCD()) + outstream << "WarmCCD" << Qt::endl; + if (Options::schedulerCloseDustCover()) + outstream << "ParkCap" << Qt::endl; + if (Options::schedulerParkMount()) + outstream << "ParkMount" << Qt::endl; + if (Options::schedulerParkDome()) + outstream << "ParkDome" << Qt::endl; + if (moduleState()->shutdownScriptURL().isEmpty() == false) + outstream << "ShutdownScript" << + Qt::endl; + outstream << "" << Qt::endl; + + outstream << "" << Qt::endl; + + emit newLog(i18n("Scheduler list saved to %1", fileURL.toLocalFile())); + file.close(); + moduleState()->setDirty(false); + return true; +} + +void SchedulerProcess::setAlignStatus(AlignState status) +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED || activeJob() == nullptr) + return; + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Align State" << Ekos::getAlignStatusString(status); + + /* If current job is scheduled and has not started yet, wait */ + if (SchedulerJob::JOB_SCHEDULED == activeJob()->getState()) + { + QDateTime const now = SchedulerModuleState::getLocalTime(); + if (now < activeJob()->getStartupTime()) + return; + } + + if (activeJob()->getStage() == SchedulerJob::STAGE_ALIGNING) + { + // Is solver complete? + if (status == Ekos::ALIGN_COMPLETE) + { + emit newLog(i18n("Job '%1' alignment is complete.", activeJob()->getName())); + moduleState()->resetAlignFailureCount(); + + activeJob()->setStage(SchedulerJob::STAGE_ALIGN_COMPLETE); + + // If we solved a FITS file, let's use its center coords as our target. + if (activeJob()->getFITSFile().isEmpty() == false) + { + QDBusReply> solutionReply = alignInterface()->call("getTargetCoords"); + if (solutionReply.isValid()) + { + QList const values = solutionReply.value(); + activeJob()->setTargetCoords(dms(values[0] * 15.0), dms(values[1]), KStarsData::Instance()->ut().djd()); + } + } + emit getNextAction(); + } + else if (status == Ekos::ALIGN_FAILED || status == Ekos::ALIGN_ABORTED) + { + emit newLog(i18n("Warning: job '%1' alignment failed.", activeJob()->getName())); + + if (moduleState()->increaseAlignFailureCount()) + { + if (Options::resetMountModelOnAlignFail() && moduleState()->maxFailureAttempts() - 1 < moduleState()->alignFailureCount()) + { + emit newLog(i18n("Warning: job '%1' forcing mount model reset after failing alignment #%2.", activeJob()->getName(), + moduleState()->alignFailureCount())); + mountInterface()->call(QDBus::AutoDetect, "resetModel"); + } + emit newLog(i18n("Restarting %1 alignment procedure...", activeJob()->getName())); + startAstrometry(); + } + else + { + emit newLog(i18n("Warning: job '%1' alignment procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); + + emit findNextJob(); + } + } + } +} + +void SchedulerProcess::setGuideStatus(GuideState status) +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED || activeJob() == nullptr) + return; + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Guide State" << Ekos::getGuideStatusString(status); + + /* If current job is scheduled and has not started yet, wait */ + if (SchedulerJob::JOB_SCHEDULED == activeJob()->getState()) + { + QDateTime const now = SchedulerModuleState::getLocalTime(); + if (now < activeJob()->getStartupTime()) + return; + } + + if (activeJob()->getStage() == SchedulerJob::STAGE_GUIDING) + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Calibration & Guide stage..."; + + // If calibration stage complete? + if (status == Ekos::GUIDE_GUIDING) + { + emit newLog(i18n("Job '%1' guiding is in progress.", activeJob()->getName())); + moduleState()->resetGuideFailureCount(); + // if guiding recovered while we are waiting, abort the restart + moduleState()->cancelGuidingTimer(); + + activeJob()->setStage(SchedulerJob::STAGE_GUIDING_COMPLETE); + emit getNextAction(); + } + else if (status == Ekos::GUIDE_CALIBRATION_ERROR || + status == Ekos::GUIDE_ABORTED) + { + if (status == Ekos::GUIDE_ABORTED) + emit newLog(i18n("Warning: job '%1' guiding failed.", activeJob()->getName())); + else + emit newLog(i18n("Warning: job '%1' calibration failed.", activeJob()->getName())); + + // if the timer for restarting the guiding is already running, we do nothing and + // wait for the action triggered by the timer. This way we avoid that a small guiding problem + // abort the scheduler job + + if (moduleState()->isGuidingTimerActive()) + return; + + if (moduleState()->increaseGuideFailureCount()) + { + if (status == Ekos::GUIDE_CALIBRATION_ERROR && + Options::realignAfterCalibrationFailure()) + { + emit newLog(i18n("Restarting %1 alignment procedure...", activeJob()->getName())); + startAstrometry(); + } + else + { + emit newLog(i18n("Job '%1' is guiding, guiding procedure will be restarted in %2 seconds.", activeJob()->getName(), + (RESTART_GUIDING_DELAY_MS * moduleState()->guideFailureCount()) / 1000)); + moduleState()->startGuidingTimer(RESTART_GUIDING_DELAY_MS * moduleState()->guideFailureCount()); + } + } + else + { + emit newLog(i18n("Warning: job '%1' guiding procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); + + emit findNextJob(); + } + } + } +} + +void SchedulerProcess::setFocusStatus(FocusState status) +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED || activeJob() == nullptr) + return; + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Focus State" << Ekos::getFocusStatusString(status); + + /* If current job is scheduled and has not started yet, wait */ + if (SchedulerJob::JOB_SCHEDULED == activeJob()->getState()) + { + QDateTime const now = SchedulerModuleState::getLocalTime(); + if (now < activeJob()->getStartupTime()) + return; + } + + if (activeJob()->getStage() == SchedulerJob::STAGE_FOCUSING) + { + // Is focus complete? + if (status == Ekos::FOCUS_COMPLETE) + { + emit newLog(i18n("Job '%1' focusing is complete.", activeJob()->getName())); + + moduleState()->setAutofocusCompleted(true); + + activeJob()->setStage(SchedulerJob::STAGE_FOCUS_COMPLETE); + + emit getNextAction(); + } + else if (status == Ekos::FOCUS_FAILED || status == Ekos::FOCUS_ABORTED) + { + emit newLog(i18n("Warning: job '%1' focusing failed.", activeJob()->getName())); + + if (moduleState()->increaseFocusFailureCount()) + { + emit newLog(i18n("Job '%1' is restarting its focusing procedure.", activeJob()->getName())); + // Reset frame to original size. + focusInterface()->call(QDBus::AutoDetect, "resetFrame"); + // Restart focusing + qCDebug(KSTARS_EKOS_SCHEDULER) << "startFocusing on 6883"; + startFocusing(); + } + else + { + emit newLog(i18n("Warning: job '%1' focusing procedure failed, marking aborted.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ABORTED); + + emit findNextJob(); + } + } + } +} + +void SchedulerProcess::setMountStatus(ISD::Mount::Status status) +{ + if (moduleState()->schedulerState() == SCHEDULER_PAUSED || activeJob() == nullptr) + return; + + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount State changed to" << status; + + /* If current job is scheduled and has not started yet, wait */ + if (SchedulerJob::JOB_SCHEDULED == activeJob()->getState()) + if (static_cast(SchedulerModuleState::getLocalTime()) < activeJob()->getStartupTime()) + return; + + switch (activeJob()->getStage()) + { + case SchedulerJob::STAGE_SLEWING: + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Slewing stage..."; + + if (status == ISD::Mount::MOUNT_TRACKING) + { + emit newLog(i18n("Job '%1' slew is complete.", activeJob()->getName())); + activeJob()->setStage(SchedulerJob::STAGE_SLEW_COMPLETE); + /* getNextAction is deferred to checkJobStage for dome support */ + } + else if (status == ISD::Mount::MOUNT_ERROR) + { + emit newLog(i18n("Warning: job '%1' slew failed, marking terminated due to errors.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + else if (status == ISD::Mount::MOUNT_IDLE) + { + emit newLog(i18n("Warning: job '%1' found not slewing, restarting.", activeJob()->getName())); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); + emit getNextAction(); + } + } + break; + + case SchedulerJob::STAGE_RESLEWING: + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Re-slewing stage..."; + + if (status == ISD::Mount::MOUNT_TRACKING) + { + emit newLog(i18n("Job '%1' repositioning is complete.", activeJob()->getName())); + activeJob()->setStage(SchedulerJob::STAGE_RESLEWING_COMPLETE); + /* getNextAction is deferred to checkJobStage for dome support */ + } + else if (status == ISD::Mount::MOUNT_ERROR) + { + emit newLog(i18n("Warning: job '%1' repositioning failed, marking terminated due to errors.", activeJob()->getName())); + activeJob()->setState(SchedulerJob::JOB_ERROR); + emit findNextJob(); + } + else if (status == ISD::Mount::MOUNT_IDLE) + { + emit newLog(i18n("Warning: job '%1' found not repositioning, restarting.", activeJob()->getName())); + activeJob()->setStage(SchedulerJob::STAGE_IDLE); + emit getNextAction(); + } + } + break; + + default: + break; + } +} + +void SchedulerProcess::checkStartupProcedure() +{ + if (checkStartupState() == false) + QTimer::singleShot(1000, this, SLOT(checkStartupProcedure())); +} + +void SchedulerProcess::checkShutdownProcedure() +{ + if (checkShutdownState()) + { + // shutdown completed + if (moduleState()->shutdownState() == SHUTDOWN_COMPLETE) + { + emit newLog(i18n("Manual shutdown procedure completed successfully.")); + // Stop Ekos + if (Options::stopEkosAfterShutdown()) + stopEkos(); + } + else if (moduleState()->shutdownState() == SHUTDOWN_ERROR) + emit newLog(i18n("Manual shutdown procedure terminated due to errors.")); + + moduleState()->setShutdownState(SHUTDOWN_IDLE); + } + else + // If shutdown procedure is not finished yet, let's check again in 1 second. + QTimer::singleShot(1000, this, SLOT(checkShutdownProcedure())); + +} + + +void SchedulerProcess::parkCap() +{ + if (capInterface().isNull()) + { + emit newLog(i18n("Dust cover park requested but no dust covers detected.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + return; + } + + QVariant parkingStatus = capInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Cap parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + if (status != ISD::PARK_PARKED) + { + moduleState()->setShutdownState(SHUTDOWN_PARKING_CAP); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Parking dust cap..."; + capInterface()->call(QDBus::AutoDetect, "park"); + emit newLog(i18n("Parking Cap...")); + + moduleState()->startCurrentOperationTimer(); + } + else + { + emit newLog(i18n("Cap already parked.")); + moduleState()->setShutdownState(SHUTDOWN_PARK_MOUNT); + } +} + +void SchedulerProcess::unParkCap() +{ + if (capInterface().isNull()) + { + emit newLog(i18n("Dust cover unpark requested but no dust covers detected.")); + moduleState()->setStartupState(STARTUP_ERROR); + return; + } + + QVariant parkingStatus = capInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Cap parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: cap parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + if (status != ISD::PARK_UNPARKED) + { + moduleState()->setStartupState(STARTUP_UNPARKING_CAP); + capInterface()->call(QDBus::AutoDetect, "unpark"); + emit newLog(i18n("Unparking cap...")); + + moduleState()->startCurrentOperationTimer(); + } + else + { + emit newLog(i18n("Cap already unparked.")); + moduleState()->setStartupState(STARTUP_COMPLETE); + } +} + +void SchedulerProcess::parkMount() +{ + if (mountInterface().isNull()) + { + emit newLog(i18n("Mount park requested but no mounts detected.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + return; + } + + QVariant parkingStatus = mountInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + switch (status) + { + case ISD::PARK_PARKED: + if (moduleState()->shutdownState() == SHUTDOWN_PARK_MOUNT) + moduleState()->setShutdownState(SHUTDOWN_PARK_DOME); + + moduleState()->setParkWaitState(PARKWAIT_PARKED); + emit newLog(i18n("Mount already parked.")); + break; + + case ISD::PARK_UNPARKING: + //case Mount::UNPARKING_BUSY: + /* FIXME: Handle the situation where we request parking but an unparking procedure is running. */ + + // case Mount::PARKING_IDLE: + // case Mount::UNPARKING_OK: + case ISD::PARK_ERROR: + case ISD::PARK_UNKNOWN: + case ISD::PARK_UNPARKED: + { + qCDebug(KSTARS_EKOS_SCHEDULER) << "Parking mount..."; + QDBusReply const mountReply = mountInterface()->call(QDBus::AutoDetect, "park"); + + if (mountReply.error().type() != QDBusError::NoError) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount park request received DBUS error: %1").arg( + QDBusError::errorString(mountReply.error().type())); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + else moduleState()->startCurrentOperationTimer(); + } + + // Fall through + case ISD::PARK_PARKING: + //case Mount::PARKING_BUSY: + if (moduleState()->shutdownState() == SHUTDOWN_PARK_MOUNT) + moduleState()->setShutdownState(SHUTDOWN_PARKING_MOUNT); + + moduleState()->setParkWaitState(PARKWAIT_PARKING); + emit newLog(i18n("Parking mount in progress...")); + break; + + // All cases covered above so no need for default + //default: + // qCWarning(KSTARS_EKOS_SCHEDULER) << QString("BUG: Parking state %1 not managed while parking mount.").arg(mountReply.value()); + } + +} + +void SchedulerProcess::unParkMount() +{ + if (mountInterface().isNull()) + { + emit newLog(i18n("Mount unpark requested but no mounts detected.")); + moduleState()->setStartupState(STARTUP_ERROR); + return; + } + + QVariant parkingStatus = mountInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + switch (status) + { + //case Mount::UNPARKING_OK: + case ISD::PARK_UNPARKED: + if (moduleState()->startupState() == STARTUP_UNPARK_MOUNT) + moduleState()->setStartupState(STARTUP_UNPARK_CAP); + + moduleState()->setParkWaitState(PARKWAIT_UNPARKED); + emit newLog(i18n("Mount already unparked.")); + break; + + //case Mount::PARKING_BUSY: + case ISD::PARK_PARKING: + /* FIXME: Handle the situation where we request unparking but a parking procedure is running. */ + + // case Mount::PARKING_IDLE: + // case Mount::PARKING_OK: + // case Mount::PARKING_ERROR: + case ISD::PARK_ERROR: + case ISD::PARK_UNKNOWN: + case ISD::PARK_PARKED: + { + QDBusReply const mountReply = mountInterface()->call(QDBus::AutoDetect, "unpark"); + + if (mountReply.error().type() != QDBusError::NoError) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount unpark request received DBUS error: %1").arg( + QDBusError::errorString(mountReply.error().type())); + if (!manageConnectionLoss()) + moduleState()->setParkWaitState(PARKWAIT_ERROR); + } + else moduleState()->startCurrentOperationTimer(); + } + + // Fall through + //case Mount::UNPARKING_BUSY: + case ISD::PARK_UNPARKING: + if (moduleState()->startupState() == STARTUP_UNPARK_MOUNT) + moduleState()->setStartupState(STARTUP_UNPARKING_MOUNT); + + moduleState()->setParkWaitState(PARKWAIT_UNPARKING); + qCInfo(KSTARS_EKOS_SCHEDULER) << "Unparking mount in progress..."; + break; + + // All cases covered above + //default: + // qCWarning(KSTARS_EKOS_SCHEDULER) << QString("BUG: Parking state %1 not managed while unparking mount.").arg(mountReply.value()); + } +} + +bool SchedulerProcess::isMountParked() +{ + if (mountInterface().isNull()) + return false; + // First check if the mount is able to park - if it isn't, getParkingStatus will reply PARKING_ERROR and status won't be clear + //QDBusReply const parkCapableReply = mountInterface->call(QDBus::AutoDetect, "canPark"); + QVariant canPark = mountInterface()->property("canPark"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount can park:" << (!canPark.isValid() ? "invalid" : (canPark.toBool() ? "T" : "F")); + + if (canPark.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount canPark request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + manageConnectionLoss(); + return false; + } + else if (canPark.toBool() == true) + { + // If it is able to park, obtain its current status + //QDBusReply const mountReply = mountInterface->call(QDBus::AutoDetect, "getParkingStatus"); + QVariant parkingStatus = mountInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Mount parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: mount parking status property is invalid %1.").arg( + mountInterface()->lastError().type()); + manageConnectionLoss(); + return false; + } + + // Deduce state of mount - see getParkingStatus in mount.cpp + switch (static_cast(parkingStatus.toInt())) + { + // case Mount::PARKING_OK: // INDI switch ok, and parked + // case Mount::PARKING_IDLE: // INDI switch idle, and parked + case ISD::PARK_PARKED: + return true; + + // case Mount::UNPARKING_OK: // INDI switch idle or ok, and unparked + // case Mount::PARKING_ERROR: // INDI switch error + // case Mount::PARKING_BUSY: // INDI switch busy + // case Mount::UNPARKING_BUSY: // INDI switch busy + default: + return false; + } + } + // If the mount is not able to park, consider it not parked + return false; +} + +void SchedulerProcess::parkDome() +{ + // If there is no dome, mark error + if (domeInterface().isNull()) + { + emit newLog(i18n("Dome park requested but no domes detected.")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + return; + } + + //QDBusReply const domeReply = domeInterface->call(QDBus::AutoDetect, "getParkingStatus"); + //Dome::ParkingStatus status = static_cast(domeReply.value()); + QVariant parkingStatus = domeInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Dome parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + if (status != ISD::PARK_PARKED) + { + moduleState()->setShutdownState(SHUTDOWN_PARKING_DOME); + domeInterface()->call(QDBus::AutoDetect, "park"); + emit newLog(i18n("Parking dome...")); + + moduleState()->startCurrentOperationTimer(); + } + else + { + emit newLog(i18n("Dome already parked.")); + moduleState()->setShutdownState(SHUTDOWN_SCRIPT); + } +} + +void SchedulerProcess::unParkDome() +{ + // If there is no dome, mark error + if (domeInterface().isNull()) + { + emit newLog(i18n("Dome unpark requested but no domes detected.")); + moduleState()->setStartupState(STARTUP_ERROR); + return; + } + + QVariant parkingStatus = domeInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Dome parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + if (static_cast(parkingStatus.toInt()) != ISD::PARK_UNPARKED) + { + moduleState()->setStartupState(STARTUP_UNPARKING_DOME); + domeInterface()->call(QDBus::AutoDetect, "unpark"); + emit newLog(i18n("Unparking dome...")); + + moduleState()->startCurrentOperationTimer(); + } + else + { + emit newLog(i18n("Dome already unparked.")); + moduleState()->setStartupState(STARTUP_UNPARK_MOUNT); + } +} + +GuideState SchedulerProcess::getGuidingStatus() +{ + QVariant guideStatus = guideInterface()->property("status"); + Ekos::GuideState gStatus = static_cast(guideStatus.toInt()); + + return gStatus; +} + +bool SchedulerProcess::isDomeParked() +{ + if (domeInterface().isNull()) + return false; + + QVariant parkingStatus = domeInterface()->property("parkStatus"); + qCDebug(KSTARS_EKOS_SCHEDULER) << "Dome parking status" << (!parkingStatus.isValid() ? -1 : parkingStatus.toInt()); + + if (parkingStatus.isValid() == false) + { + qCCritical(KSTARS_EKOS_SCHEDULER) << QString("Warning: dome parkStatus request received DBUS error: %1").arg( + mountInterface()->lastError().type()); + if (!manageConnectionLoss()) + parkingStatus = ISD::PARK_ERROR; + } + + ISD::ParkStatus status = static_cast(parkingStatus.toInt()); + + return status == ISD::PARK_PARKED; +} + +void SchedulerProcess::setupJob(SchedulerJob &job, const QString &name, const QString &group, const dms &ra, const dms &dec, + double djd, double rotation, const QUrl &sequenceUrl, const QUrl &fitsUrl, StartupCondition startup, + const QDateTime &startupTime, CompletionCondition completion, const QDateTime &completionTime, int completionRepeats, + double minimumAltitude, double minimumMoonSeparation, bool enforceWeather, bool enforceTwilight, + bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide) +{ + /* Configure or reconfigure the observation job */ + + job.setName(name); + job.setGroup(group); + // djd should be ut.djd + job.setTargetCoords(ra, dec, djd); + job.setPositionAngle(rotation); + + /* Consider sequence file is new, and clear captured frames map */ + job.setCapturedFramesMap(SchedulerJob::CapturedFramesMap()); + job.setSequenceFile(sequenceUrl); + job.setFITSFile(fitsUrl); + // #1 Startup conditions + + job.setStartupCondition(startup); + if (startup == START_AT) + { + job.setStartupTime(startupTime); + } + /* Store the original startup condition */ + job.setFileStartupCondition(job.getStartupCondition()); + job.setFileStartupTime(job.getStartupTime()); + + // #2 Constraints + + job.setMinAltitude(minimumAltitude); + job.setMinMoonSeparation(minimumMoonSeparation); + + // Check enforce weather constraints + job.setEnforceWeather(enforceWeather); + // twilight constraints + job.setEnforceTwilight(enforceTwilight); + job.setEnforceArtificialHorizon(enforceArtificialHorizon); + + job.setCompletionCondition(completion); + if (completion == FINISH_AT) + job.setCompletionTime(completionTime); + else if (completion == FINISH_REPEAT) + { + job.setRepeatsRequired(completionRepeats); + job.setRepeatsRemaining(completionRepeats); + } + // Job steps + job.setStepPipeline(SchedulerJob::USE_NONE); + if (track) + job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_TRACK)); + if (focus) + job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_FOCUS)); + if (align) + job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_ALIGN)); + if (guide) + job.setStepPipeline(static_cast(job.getStepPipeline() | SchedulerJob::USE_GUIDE)); + + /* Store the original startup condition */ + job.setFileStartupCondition(job.getStartupCondition()); + job.setFileStartupTime(job.getStartupTime()); + + /* Reset job state to evaluate the changes */ + job.reset(); + +} + +void SchedulerProcess::checkProcessExit(int exitCode) +{ + scriptProcess().disconnect(); + + if (exitCode == 0) + { + if (moduleState()->startupState() == STARTUP_SCRIPT) + moduleState()->setStartupState(STARTUP_UNPARK_DOME); + else if (moduleState()->shutdownState() == SHUTDOWN_SCRIPT_RUNNING) + moduleState()->setShutdownState(SHUTDOWN_COMPLETE); + + return; + } + + if (moduleState()->startupState() == STARTUP_SCRIPT) + { + emit newLog(i18n("Startup script failed, aborting...")); + moduleState()->setStartupState(STARTUP_ERROR); + } + else if (moduleState()->shutdownState() == SHUTDOWN_SCRIPT_RUNNING) + { + emit newLog(i18n("Shutdown script failed, aborting...")); + moduleState()->setShutdownState(SHUTDOWN_ERROR); + } + +} + +void SchedulerProcess::readProcessOutput() +{ + emit newLog(scriptProcess().readAllStandardOutput().simplified()); +} + +SchedulerJob *SchedulerProcess::activeJob() +{ + return moduleState()->activeJob(); +} + +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulerprocess.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,412 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "schedulertypes.h" +#include "ekos/align/align.h" +#include "indi/indiweather.h" +#include "dms.h" + +#include +#include +#include +#include + +namespace Ekos +{ + +class SchedulerJob; +class SchedulerModuleState; + +/** + * @class SchedulerProcess + * @brief The SchedulerProcess class holds the entire business logic for controlling the + * execution of the EKOS scheduler. + */ +class SchedulerProcess : public QObject +{ + Q_OBJECT + +public: + SchedulerProcess(QSharedPointer state); + + // //////////////////////////////////////////////////////////////////// + // process steps + // //////////////////////////////////////////////////////////////////// + + /** + * @brief startSlew DBus call for initiating slew + */ + void startSlew(); + + /** + * @brief startFocusing DBus call for feeding ekos the specified settings and initiating focus operation + */ + void startFocusing(); + + /** + * @brief startAstrometry initiation of the capture and solve operation. We change the job state + * after solver is started + */ + void startAstrometry(); + + /** + * @brief startGuiding After ekos is fed the calibration options, we start the guiding process + * @param resetCalibration By default calibration is not reset until it is explicitly requested + */ + void startGuiding(bool resetCalibration = false); + + /** + * @brief stopGuiding After guiding is done we need to stop the process + */ + void stopGuiding(); + + /** + * @brief processGuidingTimer Check the guiding timer, and possibly restart guiding. + */ + void processGuidingTimer(); + + /** + * @brief startCapture The current job file name is solved to an url which is fed to ekos. We then start the capture process + * @param restart Set to true if the goal to restart an existing sequence. The only difference is that when a sequence is restarted, sequence file + * is not loaded from disk again since that results in erasing all the history of the capture process. + */ + void startCapture(bool restart = false); + + /** + * @brief updateCompletedJobsCount For each scheduler job, examine sequence job storage and count captures. + * @param forced forces recounting captures unconditionally if true, else only IDLE, EVALUATION or new jobs are examined. + */ + void updateCompletedJobsCount(bool forced = false); + + /** + * @brief setSolverAction set the GOTO mode for the solver + * @param mode 0 For Sync, 1 for SlewToTarget, 2 for Nothing + */ + void setSolverAction(Align::GotoMode mode); + + /** + * @brief loadProfiles Load the existing EKOS profiles + */ + void loadProfiles(); + + /** + * @brief checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and running + * @return True if Ekos is running, false if Ekos start up is in progress. + */ + bool checkEkosState(); + + /** + * @brief checkINDIState Check INDI startup stages and take whatever action necessary to get INDI devices connected. + * @return True if INDI devices are connected, false if it is under progress. + */ + bool checkINDIState(); + + /** + * @brief completeShutdown Try to complete the scheduler shutdown + * @return false iff some further action is required + */ + bool completeShutdown(); + + /** + * @brief disconnectINDI disconnect all INDI devices from server. + */ + void disconnectINDI(); + + /** + * @brief manageConnectionLoss Mitigate loss of connection with the INDI server. + * @return true if connection to Ekos/INDI should be attempted again, false if not mitigation is available or needed. + */ + bool manageConnectionLoss(); + + /** + * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly. + */ + void checkCapParkingStatus(); + + /** + * @brief checkStartupState Check startup procedure stages and make sure all stages are complete. + * @return True if startup is complete, false otherwise. + */ + bool checkStartupState(); + /** + * @brief checkShutdownState Check shutdown procedure stages and make sure all stages are complete. + * @return + */ + bool checkShutdownState(); + + /** + * @brief checkParkWaitState Check park wait state. + * @return If parking/unparking in progress, return false. If parking/unparking complete, return true. + */ + bool checkParkWaitState(); + + /** + * @brief runStartupProcedure Execute the startup of the scheduler itself to be prepared + * for running scheduler jobs. + */ + void runStartupProcedure(); + + /** + * @brief runShutdownProcedure Shutdown the scheduler itself and EKOS (if configured to do so). + */ + void runShutdownProcedure(); + + /** + * @brief saveScheduler Save scheduler jobs to a file + * @param path path of a file + * @return true on success, false on failure. + */ + bool saveScheduler(const QUrl &fileURL); + + // //////////////////////////////////////////////////////////////////// + // device handling + // //////////////////////////////////////////////////////////////////// + void setAlignStatus(Ekos::AlignState status); + void setGuideStatus(Ekos::GuideState status); + void setCaptureStatus(Ekos::CaptureState status); + void setFocusStatus(Ekos::FocusState status); + void setMountStatus(ISD::Mount::Status status); + void setWeatherStatus(ISD::Weather::Status status); + + /** + * @return True if mount is parked + */ + bool isMountParked(); + /** + * @return True if dome is parked + */ + bool isDomeParked(); + + // //////////////////////////////////////////////////////////////////// + // state machine + // //////////////////////////////////////////////////////////////////// + QSharedPointer m_moduleState; + QSharedPointer moduleState() const + { + return m_moduleState; + } + + // //////////////////////////////////////////////////////////////////// + // DBUS interfaces to devices + // //////////////////////////////////////////////////////////////////// + QPointer ekosInterface() const + { + return m_ekosInterface; + } + void setEkosInterface(QPointer newInterface) + { + m_ekosInterface = newInterface; + } + QPointer indiInterface() const + { + return m_indiInterface; + } + void setIndiInterface(QPointer newInterface) + { + m_indiInterface = newInterface; + } + QPointer focusInterface() const + { + return m_focusInterface; + } + void setFocusInterface(QPointer newInterface) + { + m_focusInterface = newInterface; + } + QPointer captureInterface() const + { + return m_captureInterface; + } + void setCaptureInterface(QPointer newInterface) + { + m_captureInterface = newInterface; + } + QPointer mountInterface() const + { + return m_mountInterface; + } + void setMountInterface(QPointer newInterface) + { + m_mountInterface = newInterface; + } + QPointer alignInterface() const + { + return m_alignInterface; + } + void setAlignInterface(QPointer newInterface) + { + m_alignInterface = newInterface; + } + QPointer guideInterface() const + { + return m_guideInterface; + } + void setGuideInterface(QPointer newInterface) + { + m_guideInterface = newInterface; + } + QPointer domeInterface() const + { + return m_domeInterface; + } + void setDomeInterface(QPointer newInterface) + { + m_domeInterface = newInterface; + } + QPointer weatherInterface() const + { + return m_weatherInterface; + } + void setWeatherInterface(QPointer newInterface) + { + m_weatherInterface = newInterface; + } + QPointer capInterface() const + { + return m_capInterface; + } + void setCapInterface(QPointer newInterface) + { + m_capInterface = newInterface; + } + // //////////////////////////////////////////////////////////////////// + // helper functions + // //////////////////////////////////////////////////////////////////// + + /** + * @brief setupJob Initialize a job with all fields accessible from the UI. + */ + static void setupJob(SchedulerJob &job, const QString &name, const QString &group, const dms &ra, const dms &dec, + double djd, double rotation, const QUrl &sequenceUrl, const QUrl &fitsUrl, StartupCondition startup, + const QDateTime &startupTime, CompletionCondition completion, const QDateTime &completionTime, int completionRepeats, + double minimumAltitude, double minimumMoonSeparation, bool enforceWeather, bool enforceTwilight, + bool enforceArtificialHorizon, bool track, bool focus, bool align, bool guide); + + /** + * @brief getGuidingStatus Retrieve the guiding status. + */ + GuideState getGuidingStatus(); + + QProcess &scriptProcess() + { + return m_scriptProcess; + } + +signals: + // new log text for the module log window + void newLog(const QString &text); + // controls for scheduler execution + void stopScheduler(); + void stopCurrentJobAction(); + void findNextJob(); + void getNextAction(); + +private: + // DBus interfaces to devices + QPointer m_ekosInterface { nullptr }; + QPointer m_indiInterface { nullptr }; + QPointer m_focusInterface { nullptr }; + QPointer m_captureInterface { nullptr }; + QPointer m_mountInterface { nullptr }; + QPointer m_alignInterface { nullptr }; + QPointer m_guideInterface { nullptr }; + QPointer m_domeInterface { nullptr }; + QPointer m_weatherInterface { nullptr }; + QPointer m_capInterface { nullptr }; + + // Startup and Shutdown scripts process + QProcess m_scriptProcess; + // //////////////////////////////////////////////////////////////////// + // process steps + // //////////////////////////////////////////////////////////////////// + + /** + * @brief executeScript Execute pre- or post job script + */ + void executeScript(const QString &filename); + + /** + * @brief stopEkos shutdown Ekos completely + */ + void stopEkos(); + + /** + * @brief checkMountParkingStatus check mount parking status and updating corresponding states accordingly. + */ + void checkMountParkingStatus(); + + /** + * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly. + */ + void checkDomeParkingStatus(); + + // //////////////////////////////////////////////////////////////////// + // device handling + // //////////////////////////////////////////////////////////////////// + /** + * @brief parkCap Close dust cover + */ + void parkCap(); + + /** + * @brief unCap Open dust cover + */ + void unParkCap(); + + /** + * @brief parkMount Park mount + */ + void parkMount(); + + /** + * @brief unParkMount Unpark mount + */ + void unParkMount(); + + /** + * @brief parkDome Park dome + */ + void parkDome(); + + /** + * @brief unParkDome Unpark dome + */ + void unParkDome(); + + // //////////////////////////////////////////////////////////////////// + // helper functions + // //////////////////////////////////////////////////////////////////// + + /** + * @brief checkStartupProcedure restart regularly {@see #checkStartupState()} until completed + */ + void checkStartupProcedure(); + + /** + * @brief checkShutdownProcedure Check regularly if the shutdown has completed (see + * {@see #checkShutdownState()}) and stop EKOS if the corresponding configuration flag is set. + */ + void checkShutdownProcedure(); + + /** + * @brief checkProcessExit Check script process exist status. This is called when the process exists either normally or abnormally. + * @param exitCode exit code from the script process. Depending on the exist code, the status of startup/shutdown procedure is set accordingly. + */ + void checkProcessExit(int exitCode); + + /** + * @brief readProcessOutput read running script process output and display it in Ekos + */ + void readProcessOutput(); + + /** + * @brief activeJob Shortcut to the active job held in the state machine + */ + SchedulerJob *activeJob(); +}; +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,176 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "schedulertypes.h" + +namespace Ekos +{ +// Functions to make human-readable debug messages for the various enums. + +QString ekosStateString(EkosState state) +{ + switch(state) + { + case EKOS_IDLE: + return "Ekos is idle"; + case EKOS_STARTING: + return "Starting Ekos"; + case EKOS_STOPPING: + return "Stopping Ekos"; + case EKOS_READY: + return "Ekos is ready"; + } + return QString("????"); +} + +QString indiStateString(INDIState state) +{ + switch(state) + { + case INDI_IDLE: + return "INDI is idle"; + case INDI_PROPERTY_CHECK: + return "Checking INDI properties"; + case INDI_CONNECTING: + return "Connecting to INDI"; + case INDI_DISCONNECTING: + return "Disconnecting to INDI"; + case INDI_READY: + return "INDIis ready"; + } + return QString("????"); +} + +QString startupStateString(StartupState state) +{ + switch(state) + { + case STARTUP_IDLE: + return "Startup is idle"; + case STARTUP_SCRIPT: + return "Startup running script"; + case STARTUP_UNPARK_DOME: + return "Startup unpark dome"; + case STARTUP_UNPARKING_DOME: + return "Startup unparking dome"; + case STARTUP_UNPARK_MOUNT: + return "Startup unpark mount"; + case STARTUP_UNPARKING_MOUNT: + return "Startup unparking mount"; + case STARTUP_UNPARK_CAP: + return "Startup remove cap"; + case STARTUP_UNPARKING_CAP: + return "Starup removing cap"; + case STARTUP_ERROR: + return "Startup error"; + case STARTUP_COMPLETE: + return "Startup is complete"; + } + return QString("????"); +} + +QString shutdownStateString(ShutdownState state) +{ + switch(state) + { + case SHUTDOWN_IDLE: + return "Shutdown is idle"; + case SHUTDOWN_PARK_CAP: + return "Shutdown remove cap"; + case SHUTDOWN_PARKING_CAP: + return "Shutdown removing cap"; + case SHUTDOWN_PARK_MOUNT: + return "Shutdown park mount"; + case SHUTDOWN_PARKING_MOUNT: + return "Shutdown parking mount"; + case SHUTDOWN_PARK_DOME: + return "Shutdown park dome"; + case SHUTDOWN_PARKING_DOME: + return "Shutdown parking dome"; + case SHUTDOWN_SCRIPT: + return "Shutdown script"; + case SHUTDOWN_SCRIPT_RUNNING: + return "Shutdown script running"; + case SHUTDOWN_ERROR: + return "Shutdown error"; + case SHUTDOWN_COMPLETE: + return "Shutdown complete"; + } + return QString("????"); +} + +QString parkWaitStateString(ParkWaitState state) +{ + switch(state) + { + case PARKWAIT_IDLE: + return "Park idle"; + case PARKWAIT_PARK: + return "Park"; + case PARKWAIT_PARKING: + return "Parking"; + case PARKWAIT_PARKED: + return "Parked"; + case PARKWAIT_UNPARK: + return "Unpark"; + case PARKWAIT_UNPARKING: + return "Unparking"; + case PARKWAIT_UNPARKED: + return "Unparked"; + case PARKWAIT_ERROR: + return "Park error"; + } + return QString("????"); +} + +QString timerStr(SchedulerTimerState state) +{ + switch (state) + { + case RUN_WAKEUP: + return QString("RUN_WAKEUP"); + case RUN_SCHEDULER: + return QString("RUN_SCHEDULER"); + case RUN_JOBCHECK: + return QString("RUN_JOBCHECK"); + case RUN_SHUTDOWN: + return QString("RUN_SHUTDOWN"); + case RUN_NOTHING: + return QString("RUN_NOTHING"); + } + return QString("????"); +} + +QString startupConditionString(StartupCondition condition) +{ + switch(condition) + { + case START_ASAP: + return "ASAP"; + case START_AT: + return "AT"; + } + return QString("????"); +} + +QString completionConditionString(CompletionCondition condition) +{ + switch(condition) + { + case FINISH_SEQUENCE: + return "FINISH"; + case FINISH_REPEAT: + return "REPEAT"; + case FINISH_LOOP: + return "LOOP"; + case FINISH_AT: + return "AT"; + } + return QString("????"); +} + + +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.h 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/ekos/scheduler/schedulertypes.h 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,108 @@ +/* + SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include "QString" + +namespace Ekos +{ +typedef enum +{ + STARTUP_IDLE, + STARTUP_SCRIPT, + STARTUP_UNPARK_DOME, + STARTUP_UNPARKING_DOME, + STARTUP_UNPARK_MOUNT, + STARTUP_UNPARKING_MOUNT, + STARTUP_UNPARK_CAP, + STARTUP_UNPARKING_CAP, + STARTUP_ERROR, + STARTUP_COMPLETE +} StartupState; +typedef enum +{ + SHUTDOWN_IDLE, + SHUTDOWN_PARK_CAP, + SHUTDOWN_PARKING_CAP, + SHUTDOWN_PARK_MOUNT, + SHUTDOWN_PARKING_MOUNT, + SHUTDOWN_PARK_DOME, + SHUTDOWN_PARKING_DOME, + SHUTDOWN_SCRIPT, + SHUTDOWN_SCRIPT_RUNNING, + SHUTDOWN_ERROR, + SHUTDOWN_COMPLETE +} ShutdownState; +typedef enum +{ + PARKWAIT_IDLE, + PARKWAIT_PARK, + PARKWAIT_PARKING, + PARKWAIT_PARKED, + PARKWAIT_UNPARK, + PARKWAIT_UNPARKING, + PARKWAIT_UNPARKED, + PARKWAIT_ERROR +} ParkWaitState; +// overall states of EKOS +typedef enum { EKOS_IDLE, EKOS_STARTING, EKOS_STOPPING, EKOS_READY } EkosState; +// overall states of INDI +typedef enum { INDI_IDLE, INDI_CONNECTING, INDI_DISCONNECTING, INDI_PROPERTY_CHECK, INDI_READY } INDIState; + +/** @brief options what should happen if an error or abort occurs */ +typedef enum +{ + ERROR_DONT_RESTART, + ERROR_RESTART_AFTER_TERMINATION, + ERROR_RESTART_IMMEDIATELY +} ErrorHandlingStrategy; + +/** @brief Algorithms, in the same order as UI. */ +typedef enum +{ + ALGORITHM_GREEDY = 1 +} SchedulerAlgorithm; + + +/** @brief Conditions under which a SchedulerJob may start. */ +typedef enum +{ + START_ASAP = 0, + START_AT = 2 +} StartupCondition; + +/** @brief Conditions under which a SchedulerJob may complete. */ +typedef enum +{ + FINISH_SEQUENCE, + FINISH_REPEAT, + FINISH_LOOP, + FINISH_AT +} CompletionCondition; + +/** @brief IterationTypes, the different types of scheduler iterations that are run. */ +typedef enum +{ + RUN_WAKEUP = 0, + RUN_SCHEDULER, + RUN_JOBCHECK, + RUN_SHUTDOWN, + RUN_NOTHING +} SchedulerTimerState; + +// Functions to make human-readable debug messages for the various enums. + +QString ekosStateString(EkosState state); +QString indiStateString(INDIState state); +QString startupStateString(StartupState state); +QString shutdownStateString(ShutdownState state); +QString parkWaitStateString(ParkWaitState state); +QString timerStr(SchedulerTimerState state); +QString startupConditionString(StartupCondition condition); +QString completionConditionString(CompletionCondition condition); + +} // Ekos namespace diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitsdata.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitsdata.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitsdata.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitsdata.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -2238,15 +2238,17 @@ return cacheHFR; } -double FITSData::getHFR(int x, int y) +double FITSData::getHFR(int x, int y, double scale) { if (starCenters.empty()) return -1; for (int i = 0; i < starCenters.count(); i++) { - if (std::fabs(starCenters[i]->x - x) <= starCenters[i]->width / 2 && - std::fabs(starCenters[i]->y - y) <= starCenters[i]->width / 2) + const int maxDist = std::max(2, static_cast(0.5 + 2 * starCenters[i]->width / scale)); + const int dx = std::fabs(starCenters[i]->x - x); + const int dy = std::fabs(starCenters[i]->y - y); + if (dx <= maxDist && dy <= maxDist) { m_SelectedHFRStar = *starCenters[i]; return starCenters[i]->HFR; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitsdata.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitsdata.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitsdata.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitsdata.h 2023-12-03 05:23:17.000000000 +0000 @@ -338,7 +338,7 @@ double getEccentricity(); double getHFR(HFRType type = HFR_AVERAGE); - double getHFR(int x, int y); + double getHFR(int x, int y, double scale = 1.0); //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitslabel.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitslabel.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitslabel.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitslabel.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -277,14 +277,25 @@ QToolTip::hideText(); } - double HFR = view->imageData()->getHFR(x, y); + double HFR = view->imageData()->getHFR(x + 1, y + 1, scale); if (HFR > 0) - QToolTip::showText(e->globalPos(), QToolTip::text() + '\n' + i18nc("Half Flux Radius", "HFR: %1", QString::number(HFR, 'g', - 3)), this); - - //setCursor(Qt::CrossCursor); + { + QString tip = QToolTip::text(); + // Don't i18n away HFR: because the RegExp below checks for HFR: to make sure there aren't duplicate strings added. + QString hfrStr = QString("HFR: %1").arg(HFR, 4, 'f', 2); + if (tip.isEmpty() || tip == hfrStr) + QToolTip::showText(e->globalPos(), hfrStr, this); + else + { + QRegExp hfrRegEx("HFR\\: \\d+\\.\\d\\d"); + if (tip.contains(hfrRegEx)) + QToolTip::showText(e->globalPos(), tip.replace(hfrRegEx, hfrStr), this); + else + QToolTip::showText(e->globalPos(), QToolTip::text() + '\n' + hfrStr, this); + } + } e->accept(); } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitstab.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitstab.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitstab.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitstab.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -6,6 +6,7 @@ #include "fitstab.h" +#include "auxiliary/kspaths.h" #include "fitsdata.h" #include "fitshistogrameditor.h" #include "fitshistogramcommand.h" @@ -17,10 +18,11 @@ #include "ui_fitsheaderdialog.h" #include "ui_statform.h" #include "fitsstretchui.h" - +#include "skymap.h" #include #include #include +#include "ekos/auxiliary/stellarsolverprofile.h" #include @@ -32,6 +34,7 @@ undoStack->clear(); connect(undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(modifyFITSState(bool))); + m_PlateSolveWidget = new QDialog(this); statWidget = new QDialog(this); fitsHeaderDialog = new QDialog(this); m_HistogramEditor = new FITSHistogramEditor(this); @@ -106,6 +109,9 @@ fitsTools = new QToolBox(); stat.setupUi(statWidget); + m_PlateSolveUI.setupUi(m_PlateSolveWidget); + + connect(m_PlateSolveUI.SolveButton, &QPushButton::clicked, this, &FITSTab::extractImage); for (int i = 0; i <= STAT_STDDEV; i++) { @@ -122,6 +128,9 @@ fitsTools->addItem(statWidget, i18n("Statistics")); + fitsTools->addItem(m_PlateSolveWidget, i18n("Plate Solving")); + initSolverUI(); + fitsTools->addItem(m_HistogramEditor, i18n("Histogram")); header.setupUi(fitsHeaderDialog); @@ -537,3 +546,281 @@ if (stretchUI) stretchUI->setStretchValues(shadows, midtones, highlights); } + +namespace +{ +const QList getSSolverParametersList() +{ + const QString savedOptionsProfiles = QDir(KSPaths::writableLocation( + QStandardPaths::AppLocalDataLocation)).filePath("SavedAlignProfiles.ini"); + + return QFile(savedOptionsProfiles).exists() ? + StellarSolver::loadSavedOptionsProfiles(savedOptionsProfiles) : + Ekos::getDefaultAlignOptionsProfiles(); +} +} // namespace + +void FITSTab::setupSolver(bool extractOnly) +{ + auto parameters = getSSolverParametersList().at(m_PlateSolveUI.kcfg_FitsSolverProfile->currentIndex()); + parameters.search_radius = m_PlateSolveUI.kcfg_FitsSolverRadius->value(); + if (extractOnly) + { + m_Solver.reset(new SolverUtils(parameters, parameters.solverTimeLimit, SSolver::EXTRACT), &QObject::deleteLater); + connect(m_Solver.get(), &SolverUtils::done, this, &FITSTab::extractorDone, Qt::UniqueConnection); + } + else + { + m_Solver.reset(new SolverUtils(parameters, parameters.solverTimeLimit, SSolver::SOLVE), &QObject::deleteLater); + connect(m_Solver.get(), &SolverUtils::done, this, &FITSTab::solverDone, Qt::UniqueConnection); + } + + const int imageWidth = m_View->imageData()->width(); + const int imageHeight = m_View->imageData()->height(); + if (m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked() && imageWidth != 0 && imageHeight != 0) + { + const double scale = m_PlateSolveUI.kcfg_FitsSolverScale->value(); + double lowScale = scale * 0.8; + double highScale = scale * 1.2; + + // solver utils uses arcsecs per pixel only + const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex(); + if (units == SSolver::DEG_WIDTH) + { + lowScale = (lowScale * 3600) / std::max(imageWidth, imageHeight); + highScale = (highScale * 3600) / std::min(imageWidth, imageHeight); + } + else if (units == SSolver::ARCMIN_WIDTH) + { + lowScale = (lowScale * 60) / std::max(imageWidth, imageHeight); + highScale = (highScale * 60) / std::min(imageWidth, imageHeight); + } + + m_Solver->useScale(m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked(), lowScale, highScale); + } + else m_Solver->useScale(false, 0, 0); + + if (m_PlateSolveUI.kcfg_FitsSolverUsePosition->isChecked()) + { + bool ok; + const dms ra = m_PlateSolveUI.FitsSolverEstRA->createDms(&ok); + bool ok2; + const dms dec = m_PlateSolveUI.FitsSolverEstDec->createDms(&ok2); + if (ok && ok2) + m_Solver->usePosition(true, ra.Degrees(), dec.Degrees()); + else + m_Solver->usePosition(false, 0, 0); + } + else m_Solver->usePosition(false, 0, 0); +} + +// If it is currently solving an image, then cancel the solve. +// Otherwise start solving. +void FITSTab::extractImage() +{ + if (m_Solver.get() && m_Solver->isRunning()) + { + m_PlateSolveUI.SolveButton->setText(i18n("Aborting...")); + m_Solver->abort(); + return; + } + m_PlateSolveUI.SolveButton->setText(i18n("Cancel")); + + setupSolver(true); + + m_PlateSolveUI.FitsSolverAngle->setText(""); + m_PlateSolveUI.Solution1->setText(i18n("Extracting...")); + m_PlateSolveUI.Solution2->setText(""); + + m_Solver->runSolver(m_View->imageData()); +} + +void FITSTab::solveImage() +{ + if (m_Solver.get() && m_Solver->isRunning()) + { + m_PlateSolveUI.SolveButton->setText(i18n("Aborting...")); + m_Solver->abort(); + return; + } + m_PlateSolveUI.SolveButton->setText(i18n("Cancel")); + + setupSolver(false); + + m_PlateSolveUI.Solution2->setText(i18n("Solving...")); + + m_Solver->runSolver(m_View->imageData()); +} + +void FITSTab::extractorDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds) +{ + Q_UNUSED(solution); + disconnect(m_Solver.get(), &SolverUtils::done, this, &FITSTab::extractorDone); + m_PlateSolveUI.Solution2->setText(""); + + if (timedOut) + { + const QString result = i18n("Extractor timed out: %1s", QString("%L1").arg(elapsedSeconds, 0, 'f', 1)); + m_PlateSolveUI.Solution1->setText(result); + + // Can't run the solver. Just reset. + m_PlateSolveUI.SolveButton->setText("Solve"); + return; + } + else if (!success) + { + const QString result = i18n("Extractor failed: %1s", QString("%L1").arg(elapsedSeconds, 0, 'f', 1)); + m_PlateSolveUI.Solution1->setText(result); + + // Can't run the solver. Just reset. + m_PlateSolveUI.SolveButton->setText(i18n("Solve")); + return; + } + else + { + const QString starStr = i18n("Extracted %1 stars (%2 unfiltered) in %3s", + m_Solver->getNumStarsFound(), + m_Solver->getBackground().num_stars_detected, + QString("%1").arg(elapsedSeconds, 0, 'f', 1)); + m_PlateSolveUI.Solution1->setText(starStr); + + // Set the stars in the FITSData object so the user can view them. + const QList &starList = m_Solver->getStarList(); + QList starCenters; + starCenters.reserve(starList.size()); + for (int i = 0; i < starList.size(); i++) + { + const auto &star = starList[i]; + Edge *oneEdge = new Edge(); + oneEdge->x = star.x; + oneEdge->y = star.y; + oneEdge->val = star.peak; + oneEdge->sum = star.flux; + oneEdge->HFR = star.HFR; + oneEdge->width = star.a; + oneEdge->numPixels = star.numPixels; + if (star.a > 0) + // See page 63 to find the ellipticity equation for SEP. + // http://astroa.physics.metu.edu.tr/MANUALS/sextractor/Guide2source_extractor.pdf + oneEdge->ellipticity = 1 - star.b / star.a; + else + oneEdge->ellipticity = 0; + + starCenters.append(oneEdge); + } + m_View->imageData()->setStarCenters(starCenters); + + // Now run the solver. + solveImage(); + } +} + +void FITSTab::solverDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds) +{ + disconnect(m_Solver.get(), &SolverUtils::done, this, &FITSTab::solverDone); + m_PlateSolveUI.SolveButton->setText("Solve"); + + if (m_Solver->isRunning()) + qCDebug(KSTARS_FITS) << "solverDone called, but it is still running."; + + if (timedOut) + { + const QString result = i18n("Solver timed out: %1s", QString("%L1").arg(elapsedSeconds, 0, 'f', 1)); + m_PlateSolveUI.Solution2->setText(result); + } + else if (!success) + { + const QString result = i18n("Solver failed: %1s", QString("%L1").arg(elapsedSeconds, 0, 'f', 1)); + m_PlateSolveUI.Solution2->setText(result); + } + else + { + const bool eastToTheRight = solution.parity == FITSImage::POSITIVE ? false : true; + m_View->imageData()->injectWCS(solution.orientation, solution.ra, solution.dec, solution.pixscale, eastToTheRight); + m_View->imageData()->loadWCS(); + + const QString result = QString("Solved in %1s").arg(elapsedSeconds, 0, 'f', 1); + const double solverPA = KSUtils::rotationToPositionAngle(solution.orientation); + m_PlateSolveUI.FitsSolverAngle->setText(QString("%1º").arg(solverPA, 0, 'f', 2)); + + // Set the scale widget to the current result + const int imageWidth = m_View->imageData()->width(); + const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex(); + if (units == SSolver::DEG_WIDTH) + m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 3600.0); + else if (units == SSolver::ARCMIN_WIDTH) + m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 60.0); + else + m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale); + + // Set the ra and dec widgets to the current result + m_PlateSolveUI.FitsSolverEstRA->show(dms(solution.ra)); + m_PlateSolveUI.FitsSolverEstDec->show(dms(solution.dec)); + + m_PlateSolveUI.Solution2->setText(result); + } +} + +void FITSTab::initSolverUI() +{ + // Init the profiles combo box. + const QList optionsList = getSSolverParametersList(); + m_PlateSolveUI.kcfg_FitsSolverProfile->clear(); + for(auto ¶m : optionsList) + m_PlateSolveUI.kcfg_FitsSolverProfile->addItem(param.listName); + + // Restore the stored options. + m_PlateSolveUI.kcfg_FitsSolverProfile->setCurrentIndex(Options::fitsSolverProfile()); + + m_PlateSolveUI.kcfg_FitsSolverUseScale->setChecked(Options::fitsSolverUseScale()); + m_PlateSolveUI.kcfg_FitsSolverScale->setValue(Options::fitsSolverScale()); + m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->setCurrentIndex(Options::fitsSolverImageScaleUnits()); + + m_PlateSolveUI.kcfg_FitsSolverUsePosition->setChecked(Options::fitsSolverUsePosition()); + m_PlateSolveUI.kcfg_FitsSolverRadius->setValue(Options::fitsSolverRadius()); + + m_PlateSolveUI.FitsSolverEstRA->setUnits(dmsBox::HOURS); + m_PlateSolveUI.FitsSolverEstDec->setUnits(dmsBox::DEGREES); + + // Save the values of user controls when the user changes them. + connect(m_PlateSolveUI.kcfg_FitsSolverProfile, QOverload::of(&QComboBox::activated), [](int index) + { + Options::setFitsSolverProfile(index); + }); + connect(m_PlateSolveUI.kcfg_FitsSolverUseScale, &QCheckBox::stateChanged, this, [](int state) + { + Options::setFitsSolverUseScale(state); + }); + connect(m_PlateSolveUI.kcfg_FitsSolverScale, QOverload::of(&QDoubleSpinBox::valueChanged), [](double value) + { + Options::setFitsSolverScale(value); + }); + connect(m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits, QOverload::of(&QComboBox::activated), [](int index) + { + Options::setFitsSolverImageScaleUnits(index); + }); + + connect(m_PlateSolveUI.kcfg_FitsSolverUsePosition, &QCheckBox::stateChanged, this, [](int state) + { + Options::setFitsSolverUsePosition(state); + }); + + connect(m_PlateSolveUI.kcfg_FitsSolverRadius, QOverload::of(&QDoubleSpinBox::valueChanged), this, [](double value) + { + Options::setFitsSolverRadius(value); + }); + connect(m_PlateSolveUI.UpdatePosition, &QPushButton::clicked, this, [&]() + { + const auto center = SkyMap::Instance()->getCenterPoint(); + m_PlateSolveUI.FitsSolverEstRA->show(center.ra()); + m_PlateSolveUI.FitsSolverEstDec->show(center.dec()); + }); + + // Warn if the user is not using the internal StellarSolver solver. + const SSolver::SolverType type = static_cast(Options::solverType()); + if(type != SSolver::SOLVER_STELLARSOLVER) + { + m_PlateSolveUI.Solution2->setText(i18n("Warning! This tool only supports the internal StellarSolver solver.")); + m_PlateSolveUI.Solution1->setText(i18n("Change to that in the Ekos Align options menu.")); + } +} diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitstab.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitstab.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/fitstab.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/fitstab.h 2023-12-03 05:23:17.000000000 +0000 @@ -15,12 +15,14 @@ #include #include "ui_fitsheaderdialog.h" #include "ui_statform.h" +#include "ui_platesolve.h" #include #include #include #include #include #include +#include "ekos/auxiliary/solverutils.h" class FITSHistogramEditor; class FITSView; @@ -115,12 +117,15 @@ void ZoomOut(); void ZoomDefault(); void evaluateStats(); + void extractImage(); + void solveImage(); protected: virtual void closeEvent(QCloseEvent *ev) override; private: bool setupView(FITSMode mode, FITSScale filter); void processData(); + void imageSolved(bool success); /** Ask user whether he wants to save changes and save if he do. */ @@ -134,6 +139,9 @@ /// The Statistics Panel QPointer statWidget; Ui::statForm stat; + /// The Plate Solving UI + QPointer m_PlateSolveWidget; + Ui::PlateSolveUI m_PlateSolveUI; /// FITS Histogram QPointer m_HistogramEditor; QPointer viewer; @@ -154,6 +162,13 @@ std::unique_ptr stretchUI; + // Used for solving an image. + void setupSolver(bool extractOnly = false); + void solverDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds); + void extractorDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds); + void initSolverUI(); + QSharedPointer m_Solver; + signals: void debayerToggled(bool); void newStatus(const QString &msg, FITSBar id); diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/platesolve.ui kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/platesolve.ui --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/fitsviewer/platesolve.ui 1970-01-01 00:00:00.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/fitsviewer/platesolve.ui 2023-12-03 05:23:17.000000000 +0000 @@ -0,0 +1,444 @@ + + + PlateSolveUI + + + + 0 + 0 + 435 + 405 + + + + Plate Solving + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + + + + + 80 + 16777215 + + + + Plate solve the image using the parameters below. + + + Solve + + + + + + + Set image scale to speed up solver as it does not have to search index files of different image scales. + + + Use Scale + + + false + + + + + + + Set image scale to speed up solver as it does not have to search index files of different image scales. + + + 3 + + + 0.000000000000000 + + + 999.000000000000000 + + + 30.000000000000000 + + + + + + + + 0 + 0 + + + + + 120 + 16777215 + + + + <p>The units of the imager scale bounds. + + + 2 + + + + image width º + + + + + image width ' + + + + + arcsec/pixel + + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + Use the given position to speed up astrometry solver as it does not have to search in other areas of the sky. + + + Use Position + + + false + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + Set the approximate RA/DEC positions using the center position of the SkyMap. + + + + + + + + + + The RA of the Estimated Telescope/Image Field Position in hh:mm:ss notation + + + RA + + + + + + + true + + + + 0 + 0 + + + + + 120 + 16777215 + + + + The RA of the Estimated Telescope/Image Field Position in hh:mm:ss notation + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + The DEC of the Estimated Telescope/Image Field Position in dd:mm:ss notation + + + DEC + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + + 120 + 16777215 + + + + The DEC of the Estimated Telescope/Image Field Position in dd:mm:ss notation + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + The Search Radius for the Estimated Telescope/Image Field Position in degrees. + + + Radius + + + + + + + + 70 + 16777215 + + + + The Search Radius for the Estimated Telescope/Image Field Position in degrees. + + + 1.000000000000000 + + + 360.000000000000000 + + + 30.000000000000000 + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + The solved image position angle, East of North (degrees). + + + PA + + + + + + + + 70 + 16777215 + + + + The solved image position angle, East of North (degrees). + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + + 0 + 0 + + + + Selects the Options Profile (from Align) to use for Plate Solving + + + Profile + + + + + + + + 0 + 0 + + + + Selects the Options Profile (from Align) to use for Plate Solving + + + -1 + + + + + + + Qt::Horizontal + + + + -1 + -1 + + + + + + + + + + + Solution + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + -1 + -1 + + + + + + + + + dmsBox + QLineEdit +
widgets/dmsbox.h
+ 1 +
+
+ + +
diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/indicamerachip.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/indicamerachip.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/indicamerachip.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/indicamerachip.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -408,6 +408,7 @@ bool CameraChip::abortExposure() { + if (!m_Camera) return false; ISwitchVectorProperty *abortProp = nullptr; switch (m_Type) @@ -524,6 +525,7 @@ bool CameraChip::isCapturing() { + if (!m_Camera) return false; INumberVectorProperty *expProp = nullptr; switch (m_Type) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/indicommon.h kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/indicommon.h --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/indicommon.h 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/indicommon.h 2023-12-03 05:23:17.000000000 +0000 @@ -158,16 +158,12 @@ typedef enum { SINGLE_BIN, DOUBLE_BIN, TRIPLE_BIN, QUADRAPLE_BIN } CCDBinType; -typedef enum { SOURCE_MANUAL, SOURCE_FLATCAP, SOURCE_WALL, SOURCE_DAWN_DUSK, SOURCE_DARKCAP } FlatFieldSource; - -const QMap FlatFieldSourceNames = -{ - {SOURCE_MANUAL, "Manual"}, - {SOURCE_FLATCAP, "FlatCap"}, - {SOURCE_WALL, "Wall"}, - {SOURCE_DAWN_DUSK, "DawnDusk"}, - {SOURCE_DARKCAP, "DarkCap"} -}; +typedef enum { + ACTION_NONE = 1 << 0, + ACTION_WALL = 1 << 1, + ACTION_PARK_MOUNT = 1 << 2, + ACTION_PARK_DOME = 1 << 3, +} CalibrationPreActions; typedef enum { DURATION_MANUAL, DURATION_ADU } FlatFieldDuration; diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/servermanager.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/servermanager.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/indi/servermanager.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/indi/servermanager.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -287,8 +287,6 @@ { QTextStream out(&indiFIFO); - m_ManagedDrivers.removeOne(driver); - qCDebug(KSTARS_INDI) << "Stopping INDI Driver " << driver->getExecutable(); if (driver->getUniqueLabel().isEmpty() == false) @@ -300,6 +298,8 @@ driver->setServerState(false); driver->setPort(driver->getUserPort()); + m_ManagedDrivers.removeOne(driver); + emit driverStopped(driver); } diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstars.kcfg kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstars.kcfg --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstars.kcfg 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstars.kcfg 2023-12-03 05:23:17.000000000 +0000 @@ -1522,6 +1522,30 @@ 0 + + + 0 + + + + false + + + + false + + + + 1.0 + + + + 2 + + + + 30 + @@ -1790,8 +1814,8 @@ Maximum difference between measured and target ADU values to deem the value as acceptable. 1000 - - + + 0 @@ -2188,6 +2212,52 @@ false + + Which set of tiles to use in Aberration Inspector. + Centre and outer corners + + + + false + + + + false + + + + false + + + + + + + + + Aberration Inspector 3D graphic selection mode. + None + + + Aberration Inspector 3D graphic theme. + Primary Colors + + + + true + + + + true + + + + true + + + + false + @@ -2789,6 +2859,10 @@ true + + + true + 5 diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstars.notifyrc kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstars.notifyrc --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstars.notifyrc 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstars.notifyrc 2023-12-03 05:23:17.000000000 +0000 @@ -1727,7 +1727,7 @@ Comment=INDI Server Message (it must be enabled in INDI section of Settings) Comment[ar]=رسالة خادوم INDI (يجب تفعيلها من قسم INDI في الإعدادات) Comment[ca]=Missatge del servidor INDI (ha d'estar activat a la secció INDI de l'arranjament) -Comment[ca@valencia]=Missatge del servidor INDI (ha d'estar activat a la secció INDI de la configuració) +Comment[ca@valencia]=Missatge del servidor INDI (ha d'estar activat en la secció INDI de la configuració) Comment[de]=INDI-Servermeldungen müssen im Abschnitt INDI im Einrichtungsdialog aktiviert werden Comment[en_GB]=INDI Server Message (it must be enabled in INDI section of Settings) Comment[eo]=INDI Servila Mesaĝo (ĝi devas esti ebligita en INDI-sekcio de Agordoj) diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstarsactions.cpp kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstarsactions.cpp --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/kstarsactions.cpp 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/kstarsactions.cpp 2023-12-03 05:23:17.000000000 +0000 @@ -49,6 +49,7 @@ #include "skycomponents/imageoverlaycomponent.h" #ifdef HAVE_INDI #include "skyobjects/mosaictiles.h" +#include "indi/indidome.h" #endif #include "tools/altvstime.h" #include "tools/astrocalc.h" @@ -82,7 +83,9 @@ #ifdef HAVE_INDI #include "ekos/manager.h" #include "ekos/scheduler/framingassistantui.h" +#include "ekos/scheduler/scheduler.h" #include "ekos/opsekos.h" +#include "ekos/mount/mount.h" #endif #endif @@ -333,7 +336,11 @@ } else if (a == actionCollection()->action("show_mount_box")) { +#ifdef HAVE_CFITSIO +#ifdef HAVE_INDI Ekos::Manager::Instance()->mountModule()->toggleMountToolBox(); +#endif +#endif } else if (a == actionCollection()->action("show_sensor_fov")) { @@ -346,6 +353,7 @@ } else if (a == actionCollection()->action("show_mosaic_panel")) { +#ifdef HAVE_INDI Options::setShowMosaicPanel(a->isChecked()); // TODO // If scheduler is not running, then we should also show the Mosaic Planner dialog. @@ -360,6 +368,7 @@ assistant->show(); } } +#endif } #endif diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/org.kde.kstars.Ekos.Capture.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/org.kde.kstars.Ekos.Capture.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/kstars/org.kde.kstars.Ekos.Capture.xml 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/kstars/org.kde.kstars.Ekos.Capture.xml 2023-12-03 05:23:17.000000000 +0000 @@ -41,7 +41,7 @@ - + diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/org.kde.kf5auth.kstars.actions kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/org.kde.kf5auth.kstars.actions --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/org.kde.kf5auth.kstars.actions 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/org.kde.kf5auth.kstars.actions 2023-12-03 05:23:17.000000000 +0000 @@ -2,7 +2,7 @@ Name=Save Astrometry Index File to a write protected directory Name[ar]=حفظ ملفّ فهرسة فلكيّ في دليل محميّ ضدّ الكتابة Name[ca]=Desa el fitxer d'índex d'astrometria en un directori protegit contra escriptura -Name[ca@valencia]=Guarda el fitxer d'índex de l'astrometria en un directori protegit contra escriptura +Name[ca@valencia]=Guarda el fitxer d'índex de l'astrometria a un directori protegit contra escriptura Name[en_GB]=Save Astrometry Index File to a write protected directory Name[eo]=Konservi Astrometrian Indeksan Dosieron en skribprotektan dosierujon Name[es]=Guardar el archivo de índice de Astrometry en un directorio protegido contra escritura @@ -25,7 +25,7 @@ Description=KStars is attempting to save an Astrometry Index File to a directory owned by root Description[ar]=يحاول «نجوم‌ك» حفظ ملفّ فهرسة فلكيّ في دليل يملكه الجذر Description[ca]=El KStars està intentant desar un fitxer d'índex d'astrometria en un directori propietat de l'administrador -Description[ca@valencia]=KStars està intentant guardar un fitxer d'índex de l'astrometria en un directori propietat de l'administrador +Description[ca@valencia]=KStars està intentant guardar un fitxer d'índex de l'astrometria a un directori propietat de l'administrador Description[en_GB]=KStars is attempting to save an Astrometry Index File to a directory owned by root Description[eo]=KStars provas konservi Astrometrian Indeksan dosieron al dosierujo posedata de radiko Description[es]=KStars está intentando guardar un archivo de índice de Astrometry en un directorio propiedad del administrador diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/org.kde.kstars.appdata.xml kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/org.kde.kstars.appdata.xml --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/org.kde.kstars.appdata.xml 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/org.kde.kstars.appdata.xml 2023-12-03 05:23:17.000000000 +0000 @@ -87,7 +87,7 @@

KStars es un software astronómico de licencia libre, de código abierto y multiplataforma, creado por KDE.

KStars on KDE loodud vaba litsentsiga avatud lähtekoodiga platvormiülene astronoomiatarkvara.

KStars lizentzia askeko, sorburu irekiko, plataforma-anitzerako KDEk egindako astronomia softwarea da.

-

KStar est un logiciel d'astronomie sous licence libre, « Open Source » et multiplateforme de KDE.

+

KStars est un logiciel d'astronomie sous licence libre, « Open Source » et multi-plate-forme de KDE.

KStars é un software de astronomía libre, de código aberto e compatíbel con múltiple plataformas creado por KDE.

KStars adalah Software Astronomi yang terlisensi secara bebas, sumber terbuka, lintas platform oleh KDE.

KStars è un software di astronomia multi-piattaforma con licenza gratuita ed open source della comunità KDE.

@@ -314,7 +314,7 @@
  • Allalaaditavad kataloogid, sealhulgas Messieri pildid, Abelli planetaarudukogud, Sharplessi kataloog, Lyndsi tumedate udukogude kataloog
  • Jaitsi daitezkeen katalogoak, haien artean Messier Irudiak, Abell Planeten Nebulosa, Sharpless Katalogoa, Lynds Nebulosa Iluna katalogoa
  • Ladattavia luetteloita kuten Messier-kuvat, planetaaristen sumujen Abell-luettelo, Sharpless-luettelo ja pimeiden sumujen Lynds-luettelo
  • -
  • Les catalogues pouvant être téléchargés contiennent des images du catalogue de Messier, les nébuleuses planétaires de du catalogues d'Abell, le catalogue Sharpless et le catalogue de nébuleuses Lynds Dark.
  • +
  • Les catalogues pouvant être téléchargés contiennent des images du catalogue de Messier, les nébuleuses planétaires de du catalogues « Abell » , « Sharpless » ainsi que le catalogue de nébuleuses « Lynds Dark ».
  • Catálogos dispoñíbeis para descarga entre os que hai imaxes de Messier, as nebulosas planetarias Abell, o catálogo Sharpless ou o catálogo de nebulosa escura de Lynds.
  • Katalog yang bisa diunduh termasuk Messier Images, Abell Planetary Nebulae, Sharpless Catalog, Lynds Dark Nebula Catalog
  • Altri cataloghi scaricabili, che includono le immagini Messier, le nebulose planetarie di Abell, il catalogo Sharpless e il catalogo delle nebulose oscure di Lynds
  • diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/packaging/linux/debian/changelog kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/packaging/linux/debian/changelog --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/packaging/linux/debian/changelog 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/packaging/linux/debian/changelog 2023-12-03 05:23:17.000000000 +0000 @@ -1,3 +1,9 @@ +kstars-bleeding (6:3.6.8) jammy; urgency=medium + + * 3.6.8 Upstream release. + + -- Jasem Mutlaq Fri, 1 Dec 2023 08:30:00 +0300 + kstars-bleeding (6:3.6.7) jammy; urgency=medium * 3.6.7 Upstream release. diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/packaging/linux/debian/control kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/packaging/linux/debian/control --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/packaging/linux/debian/control 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/packaging/linux/debian/control 2023-12-03 05:23:17.000000000 +0000 @@ -14,6 +14,7 @@ libqt5websockets5-dev, libqt5svg5-dev, libqt5sql5-sqlite, + libqt5datavisualization5-dev, kdoctools-dev | libkf5doctools-dev, libkf5config-dev, libkf5guiaddons-dev, diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/af/kstars.po kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/af/kstars.po --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/af/kstars.po 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/af/kstars.po 2023-12-03 05:23:17.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: kstars VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" -"POT-Creation-Date: 2023-09-29 00:39+0000\n" +"POT-Creation-Date: 2023-11-30 00:38+0000\n" "PO-Revision-Date: 2002-11-07 11:31+0200\n" "Last-Translator: WEB-Translator \n" "Language-Team: AFRIKAANS \n" @@ -178,7 +178,7 @@ #: auxiliary/colorscheme.cpp:59 data/qml/whatisinteresting/wiview.qml:241 #: data/qml/whatisinteresting/wiview.qml:253 dialogs/finddialog.cpp:48 -#: kstarsactions.cpp:1108 kstarslite/dialogs/finddialoglite.cpp:37 +#: kstarsactions.cpp:1117 kstarslite/dialogs/finddialoglite.cpp:37 #: kstarslite/qml/modules/TopMenu.qml:178 #, fuzzy, kde-format, kde-kuit-format msgid "Satellites" @@ -191,7 +191,7 @@ #: auxiliary/colorscheme.cpp:61 data/qml/whatisinteresting/wiview.qml:526 #: data/qml/whatisinteresting/wiview.qml:538 dialogs/finddialog.cpp:47 -#: kstarsactions.cpp:1111 kstarslite/dialogs/finddialoglite.cpp:36 +#: kstarsactions.cpp:1120 kstarslite/dialogs/finddialoglite.cpp:36 #: kstarslite/qml/modules/TopMenu.qml:169 #, fuzzy, kde-format, kde-kuit-format #| msgid "Horizon" @@ -227,7 +227,7 @@ msgid "DEC Guide Error" msgstr "niks" -#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:94 +#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:101 #, kde-format msgid "Solver FOV" msgstr "" @@ -394,9 +394,9 @@ #. i18n: ectx: property (text), widget (QPushButton, AddScope) #. i18n: ectx: property (text), widget (QPushButton, AddDSLRLens) #. i18n: ectx: property (text), widget (QPushButton, SavePreset) -#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:383 -#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2499 -#: ekos/scheduler/scheduler.cpp:3822 +#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:384 +#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2028 +#: ekos/scheduler/scheduler.cpp:2950 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:88 #: kstarslite/qml/dialogs/helpers/LocationEdit.qml:375 #: oal/equipmentwriter.ui:291 oal/equipmentwriter.ui:702 @@ -422,7 +422,7 @@ #. i18n: ectx: property (text), widget (QPushButton, downloadB) #: auxiliary/imageviewer.cpp:195 -#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:86 +#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:59 #, fuzzy, kde-format msgid "Download" msgstr "Laaiïng van K-sterre..." @@ -449,15 +449,15 @@ msgid "Save Image" msgstr "Stoor Beeld" -#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3835 -#: ekos/guide/guidedriftgraph.cpp:465 kstarsactions.cpp:1326 +#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3873 +#: ekos/guide/guidedriftgraph.cpp:466 kstarsactions.cpp:1335 #: printing/pwizprint.cpp:77 tools/scriptbuilder.cpp:879 #, kde-format msgid "A file named \"%1\" already exists. Overwrite it?" msgstr "" -#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3838 -#: ekos/guide/guidedriftgraph.cpp:468 kstarsactions.cpp:1327 +#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3876 +#: ekos/guide/guidedriftgraph.cpp:469 kstarsactions.cpp:1336 #: printing/pwizprint.cpp:78 tools/scriptbuilder.cpp:882 #, kde-format msgid "Overwrite File?" @@ -519,7 +519,7 @@ #: dialogs/catalogdetails.cpp:213 dialogs/catalogsdbui.cpp:153 #: dialogs/catalogsdbui.cpp:189 dialogs/catalogsdbui.cpp:210 #: dialogs/catalogsdbui.cpp:230 dialogs/catalogsdbui.cpp:248 -#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:780 +#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:782 #, fuzzy, kde-format msgid "Warning" msgstr "Trinidad" @@ -531,6 +531,7 @@ #. i18n: ectx: property (text), widget (QPushButton, cancelB) #: auxiliary/ksmessagebox.h:38 ekos/align/manualrotator.ui:135 +#: fitsviewer/fitstab.cpp:627 fitsviewer/fitstab.cpp:646 #: indi/telescopewizardprocess.cpp:219 indi/telescopewizardprocess.cpp:226 #: kstarslite/qml/dialogs/FindDialog.qml:107 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:105 @@ -544,18 +545,18 @@ #. i18n: ectx: property (text), widget (QTableWidget, solutionTable) #: auxiliary/ksmessagebox.h:39 auxiliary/ksnotification.h:42 -#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:139 -#: ekos/capture/sequencejob.cpp:21 ekos/manager.cpp:1068 ekos/manager.cpp:1083 -#: ekos/manager.cpp:1113 ekos/scheduler/schedulerjob.cpp:620 +#: ekos/analyze/analyze.cpp:139 ekos/analyze/analyze.cpp:141 +#: ekos/capture/sequencejob.cpp:23 ekos/manager.cpp:1072 ekos/manager.cpp:1087 +#: ekos/manager.cpp:1117 ekos/scheduler/schedulerjob.cpp:596 #: fitsviewer/solveInfo.ui:86 indi/indidome.cpp:22 indi/indidustcap.cpp:18 -#: indi/indimount.cpp:33 kstarsactions.cpp:480 kstarsactions.cpp:488 -#: kstarsactions.cpp:498 skycomponents/imageoverlaycomponent.cpp:519 +#: indi/indimount.cpp:33 kstarsactions.cpp:489 kstarsactions.cpp:497 +#: kstarsactions.cpp:507 skycomponents/imageoverlaycomponent.cpp:519 #, kde-format msgid "Error" msgstr "" #: auxiliary/ksmessagebox.h:40 auxiliary/ksnotification.h:43 -#: ekos/scheduler/framingassistantui.cpp:767 +#: ekos/scheduler/framingassistantui.cpp:769 #, kde-format msgid "Sorry" msgstr "" @@ -761,10 +762,10 @@ msgid "Cannot write %s %1: %2" msgstr "" -#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:179 -#: ekos/scheduler/framingassistantui.cpp:194 -#: ekos/scheduler/framingassistantui.cpp:853 -#: ekos/scheduler/framingassistantui.cpp:872 skyobjects/ksplanetbase.h:60 +#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:180 +#: ekos/scheduler/framingassistantui.cpp:195 +#: ekos/scheduler/framingassistantui.cpp:855 +#: ekos/scheduler/framingassistantui.cpp:874 skyobjects/ksplanetbase.h:60 #: skyobjects/skyobject.h:24 #, kde-format msgid "unnamed" @@ -1007,7 +1008,7 @@ #: data/qml/whatisinteresting/wiview.qml:176 #: data/qml/whatisinteresting/wiview.qml:188 dialogs/detaildialog.cpp:216 #: dialogs/detaildialog.cpp:232 dialogs/detaildialog.cpp:255 -#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:153 +#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:129 #: printing/detailstable.cpp:145 printing/detailstable.cpp:162 #: printing/detailstable.cpp:173 printing/detailstable.cpp:186 #: printing/pwizobjectselection.cpp:124 skycomponents/skymapcomposite.cpp:606 @@ -1424,7 +1425,7 @@ #: ekos/guide/opsdither.ui:126 ekos/guide/opsgpg.ui:139 #: ekos/guide/opsgpg.ui:306 ekos/guide/opsgpg.ui:383 ekos/guide/opsgpg.ui:456 #: ekos/guide/opsgpg.ui:539 ekos/guide/opsguide.ui:308 -#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:585 ekos/opsekos.ui:678 +#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:598 ekos/opsekos.ui:691 #, fuzzy, kde-format #| msgctxt "seconds" #| msgid "secs" @@ -1934,16 +1935,16 @@ #. i18n: ectx: property (text), widget (QLabel, idlingStateLabel) #. i18n: ectx: property (text), widget (QLabel, guideStatus) #. i18n: ectx: property (text), widget (QLabel, jobStatus) -#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:27 -#: ekos/analyze/analyze.cpp:125 ekos/analyze/analyze.cpp:144 -#: ekos/analyze/analyze.cpp:2851 ekos/auxiliary/buildfilteroffsets.cpp:153 +#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:28 +#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/buildfilteroffsets.cpp:153 #: ekos/auxiliary/darklibrary.cpp:46 ekos/auxiliary/ledstatuswidget.cpp:19 -#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:21 +#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:23 #: ekos/ekos.h:20 ekos/ekos.h:71 ekos/ekos.h:118 ekos/ekos.h:138 #: ekos/ekos.h:161 ekos/ekos.h:187 ekos/guide/guidestatewidget.ui:38 -#: ekos/manager.cpp:572 ekos/manager/guidemanager.cpp:135 +#: ekos/manager.cpp:576 ekos/manager/guidemanager.cpp:135 #: ekos/manager/guidemanager.ui:117 ekos/scheduler/scheduler.ui:1252 -#: ekos/scheduler/schedulerjob.cpp:613 ekos/scheduler/schedulerjob.cpp:637 +#: ekos/scheduler/schedulerjob.cpp:589 ekos/scheduler/schedulerjob.cpp:613 #: indi/indidome.cpp:20 indi/indidustcap.cpp:17 indi/indimount.cpp:31 #, kde-format, kde-kuit-format msgid "Idle" @@ -2279,8 +2280,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, magUnknown) -#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:621 -#: ekos/scheduler/schedulerjob.cpp:652 fitsviewer/fitscommon.h:16 +#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:597 +#: ekos/scheduler/schedulerjob.cpp:628 fitsviewer/fitscommon.h:16 #: fitsviewer/fitshistogram.cpp:781 fitsviewer/fitshistogramcommand.cpp:267 #: indi/indigroup.cpp:30 skycomponents/constellationboundarylines.cpp:275 #, fuzzy, kde-format @@ -2517,12 +2518,12 @@ "Die Url is nie geldige. Sal jy hou van na open 'n blaaier venster\n" "na Die Google soektog masjien?" -#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3846 -#: ekos/align/mountmodel.cpp:264 ekos/align/mountmodel.cpp:390 -#: ekos/analyze/analyze.cpp:1170 ekos/capture/capture.cpp:2078 -#: ekos/capture/capture.cpp:2508 ekos/guide/guidedriftgraph.cpp:476 -#: ekos/scheduler/scheduler.cpp:3463 ekos/scheduler/scheduler.cpp:3832 -#: fitsviewer/fitstab.cpp:495 tools/scriptbuilder.cpp:832 +#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3884 +#: ekos/align/mountmodel.cpp:265 ekos/align/mountmodel.cpp:391 +#: ekos/analyze/analyze.cpp:1172 ekos/capture/capture.cpp:1951 +#: ekos/capture/capture.cpp:2037 ekos/guide/guidedriftgraph.cpp:477 +#: ekos/scheduler/scheduler.cpp:2593 ekos/scheduler/scheduler.cpp:2960 +#: fitsviewer/fitstab.cpp:504 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:930 #, kde-format msgid "Invalid URL" @@ -2632,8 +2633,8 @@ #. i18n: ectx: property (text), item, widget (QComboBox, schedulerProfileCombo) #: dialogs/catalogcoloreditor.cpp:109 #: ekos/auxiliary/stellarsolverprofileeditor.ui:441 -#: ekos/scheduler/scheduler.cpp:2569 ekos/scheduler/scheduler.cpp:6444 -#: ekos/scheduler/scheduler.ui:250 skycomponents/flagcomponent.cpp:33 +#: ekos/scheduler/scheduler.ui:250 ekos/scheduler/schedulermodulestate.cpp:38 +#: ekos/scheduler/schedulerprocess.cpp:1183 skycomponents/flagcomponent.cpp:33 #, fuzzy, kde-format msgid "Default" msgstr "Verstek" @@ -2815,7 +2816,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QPushButton, preview_button) -#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:258 +#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:260 #: fitsviewer/fitsviewer.cpp:607 indi/indicamera.cpp:926 #, fuzzy, kde-format msgid "Preview" @@ -3058,11 +3059,13 @@ #. i18n: ectx: property (text), widget (QLabel, l_01) #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_6) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRALabel) #: dialogs/catalogobjectlistmodel.cpp:67 ekos/align/align.ui:911 #: ekos/align/opsastrometry.ui:409 ekos/guide/guide.ui:424 #: ekos/guide/opscalibration.ui:235 ekos/guide/opsguide.ui:138 #: ekos/mount/mount.ui:144 ekos/scheduler/scheduler.ui:468 -#: fitsviewer/solveInfo.ui:66 skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:177 fitsviewer/solveInfo.ui:66 +#: skycomponents/imageoverlaycomponent.cpp:62 #, fuzzy, kde-format msgid "RA" msgstr "Alt:" @@ -3263,7 +3266,7 @@ msgstr "Manlik" #. i18n: ectx: property (text), widget (QPushButton, colorButton) -#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1126 +#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1135 #, fuzzy, kde-format msgid "Colors" msgstr "Kleur Skemas" @@ -3569,12 +3572,12 @@ msgid "Could not add the link." msgstr "Kon nie uitvee die lêer: %1" -#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1153 +#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1162 #, fuzzy, kde-format msgid "Advanced" msgstr "Ada" -#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:507 +#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:509 #: kstarslite/qml/dialogs/DetailsDialog.qml:55 #: kstarslite/qml/dialogs/DetailsDialog.qml:453 #, fuzzy, kde-format, kde-kuit-format @@ -3605,7 +3608,7 @@ msgid "Are you sure you want to remove the %1 link?" msgstr "" -#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1495 +#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1512 #: indi/indidriver.cpp:897 #, fuzzy, kde-format, kde-kuit-format msgid "Delete Confirmation" @@ -3624,7 +3627,7 @@ msgstr "Kon nie uitvee die lêer: %1" #: dialogs/detaildialog.cpp:1108 dialogs/detaildialog.cpp:1140 -#: kstarsactions.cpp:303 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 +#: kstarsactions.cpp:306 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 #: tools/observinglist.cpp:687 tools/observinglist.cpp:709 #: tools/whatsinteresting/wiview.cpp:339 tools/whatsinteresting/wiview.cpp:364 #, fuzzy, kde-format @@ -3632,8 +3635,8 @@ msgid "No connected mounts found." msgstr "Nee voorwerp genaamd %1 gevind." -#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:436 -#: kstarsactions.cpp:288 tools/observinglist.cpp:698 +#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:447 +#: kstarsactions.cpp:291 tools/observinglist.cpp:698 #: tools/whatsinteresting/wiview.cpp:350 #, kde-format msgid "Mount %1 is offline. Please connect and retry again." @@ -3723,18 +3726,20 @@ #. i18n: ectx: property (text), widget (QLabel, masterMean) #. i18n: ectx: property (text), widget (QLabel, masterMedian) #. i18n: ectx: property (text), widget (QLabel, masterDeviation) +#. i18n: ectx: property (text), widget (QLabel, exposureCount) #. i18n: ectx: property (text), widget (QLabel, l_FOV) #. i18n: ectx: property (text), widget (QLabel, l_Reducer) #. i18n: ectx: property (text), widget (QLabel, avgFPS) #. i18n: ectx: property (text), widget (QLineEdit, f_LockedFilter) -#: dialogs/details_data.ui:390 ekos/align/align.cpp:922 +#: dialogs/details_data.ui:390 ekos/align/align.cpp:929 #: ekos/analyze/analyze.ui:74 ekos/auxiliary/darklibrary.cpp:1054 #: ekos/auxiliary/darklibrary.ui:276 ekos/auxiliary/darklibrary.ui:424 #: ekos/auxiliary/darklibrary.ui:693 ekos/auxiliary/darklibrary.ui:713 #: ekos/auxiliary/darklibrary.ui:733 ekos/auxiliary/darklibrary.ui:753 #: ekos/auxiliary/darklibrary.ui:773 ekos/auxiliary/darklibrary.ui:793 -#: ekos/capture/capture.cpp:876 ekos/capture/capture.cpp:914 -#: ekos/focus/focus.cpp:368 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 +#: ekos/capture/capture.cpp:900 ekos/capture/capture.cpp:940 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:814 +#: ekos/focus/focus.cpp:373 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 #: indi/streamform.ui:368 oal/equipmentwriter.ui:1163 #, kde-format msgid "--" @@ -4225,7 +4230,7 @@ msgid "Any" msgstr "Enige" -#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1105 kstarsinit.cpp:472 +#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1114 kstarsinit.cpp:472 #: kstarslite/dialogs/finddialoglite.cpp:27 #: kstarslite/qml/modules/TopMenu.qml:159 tools/astrocalc.cpp:166 #: tools/conjunctions.cpp:96 @@ -4350,40 +4355,40 @@ msgid "Set Coordinates Manually" msgstr "Stel Fokus Eiehandig" -#: dialogs/focusdialog.cpp:127 tools/flagmanager.cpp:184 +#: dialogs/focusdialog.cpp:128 tools/flagmanager.cpp:184 #, fuzzy, kde-format msgid "The Right Ascension value must be between 0.0 and 24.0." msgstr "" "Die lengtegraad moet wees uitgedruk as \n" "'n floating-point nommer tussen -90.0 en 90.0" -#: dialogs/focusdialog.cpp:129 tools/flagmanager.cpp:186 +#: dialogs/focusdialog.cpp:130 tools/flagmanager.cpp:186 #, fuzzy, kde-format msgid "The Declination value must be between -90.0 and 90.0." msgstr "" "Die lengtegraad moet wees uitgedruk as \n" "'n floating-point nommer tussen -90.0 en 90.0" -#: dialogs/focusdialog.cpp:132 dialogs/focusdialog.cpp:185 +#: dialogs/focusdialog.cpp:133 dialogs/focusdialog.cpp:191 #: tools/flagmanager.cpp:189 #, fuzzy, kde-format msgid "Invalid Coordinate Data" msgstr "Koördinate" -#: dialogs/focusdialog.cpp:140 +#: dialogs/focusdialog.cpp:141 #, fuzzy, kde-format #| msgid "Invalid URL" msgid "Invalid Epoch format" msgstr "Ongeldige Url" -#: dialogs/focusdialog.cpp:180 +#: dialogs/focusdialog.cpp:186 #, fuzzy, kde-format msgid "The Azimuth value must be between 0.0 and 360.0." msgstr "" "Die lengtegraad moet wees uitgedruk as \n" "'n floating-point nommer tussen -90.0 en 90.0" -#: dialogs/focusdialog.cpp:182 +#: dialogs/focusdialog.cpp:188 #, fuzzy, kde-format msgid "The Altitude value must be between -90.0 and 90.0." msgstr "" @@ -4452,7 +4457,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1) #. i18n: ectx: property (text), widget (QLabel, label_7) #: dialogs/focusdialog.ui:151 ekos/align/polaralignmentassistant.ui:592 -#: ekos/capture/calibrationoptions.ui:88 tools/argsetaltaz.ui:30 +#: ekos/capture/calibrationoptions.ui:73 tools/argsetaltaz.ui:30 #: tools/modcalcplanets.ui:303 #, kde-format msgid "Az:" @@ -5099,7 +5104,7 @@ #. i18n: ectx: attribute (title), widget (QWidget, tab2) #. i18n: ectx: property (text), widget (QLabel, indiCameraLabel) #: dialogs/newfov.ui:433 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:312 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:127 #, fuzzy, kde-format msgid "Camera" msgstr "Cary" @@ -5731,7 +5736,7 @@ "location on Earth.

    To get started, press the Next button.

    " msgstr "" -#: ekos/align/align.cpp:326 +#: ekos/align/align.cpp:333 #, kde-format msgid "" "
    Object %1: %2
    RA:%3
    dDE:%6
    " msgstr "" -#: ekos/align/align.cpp:456 +#: ekos/align/align.cpp:463 #, kde-format msgid "Are you sure you want to clear all of the solution points?" msgstr "" -#: ekos/align/align.cpp:457 +#: ekos/align/align.cpp:464 #, fuzzy, kde-format msgid "Clear Solution Points" msgstr "Maak skoon Velde" -#: ekos/align/align.cpp:530 +#: ekos/align/align.cpp:537 #, kde-format msgid "Solver timed out." msgstr "" -#: ekos/align/align.cpp:822 +#: ekos/align/align.cpp:829 #, fuzzy, kde-format msgid "Mount does not support syncing." msgstr "Planeet" -#: ekos/align/align.cpp:1027 +#: ekos/align/align.cpp:1034 #, kde-format msgid "Effective telescope focal length is updated to %1 mm." msgstr "" -#: ekos/align/align.cpp:1069 +#: ekos/align/align.cpp:1076 #, kde-format msgid "" "Warning! The calculated field of view (%1) is out of bounds. Ensure the " "telescope focal length and camera pixel size are correct." msgstr "" -#: ekos/align/align.cpp:1108 +#: ekos/align/align.cpp:1115 #, kde-format msgid "" "

    Effective field of view size in arcminutes.

    Please capture and " @@ -5779,84 +5784,84 @@ "p>

    Calculated FOV: %1

    " msgstr "" -#: ekos/align/align.cpp:1117 +#: ekos/align/align.cpp:1124 #, kde-format msgid "

    Effective field of view size in arcminutes.

    " msgstr "" -#: ekos/align/align.cpp:1398 +#: ekos/align/align.cpp:1405 #, kde-format msgid "Error: No camera detected." msgstr "" -#: ekos/align/align.cpp:1404 +#: ekos/align/align.cpp:1411 #, fuzzy, kde-format msgid "Error: lost connection to camera." msgstr "Bereken" -#: ekos/align/align.cpp:1405 ekos/align/align.cpp:2308 +#: ekos/align/align.cpp:1412 ekos/align/align.cpp:2344 #, kde-format msgid "Astrometry alignment failed" msgstr "" -#: ekos/align/align.cpp:1421 +#: ekos/align/align.cpp:1428 #, kde-format msgid "" "Telescope aperture and focal length are missing. Please check your optical " "train settings and try again." msgstr "" -#: ekos/align/align.cpp:1427 +#: ekos/align/align.cpp:1434 #, kde-format msgid "" "CCD pixel size is missing. Please check your driver settings and try again." msgstr "" -#: ekos/align/align.cpp:1435 +#: ekos/align/align.cpp:1442 #, fuzzy, kde-format msgid "Error: lost connection to filter wheel." msgstr "Bereken" -#: ekos/align/align.cpp:1455 ekos/capture/captureprocess.cpp:170 -#: ekos/capture/captureprocess.cpp:563 ekos/focus/focus.cpp:4819 +#: ekos/align/align.cpp:1462 ekos/capture/captureprocess.cpp:191 +#: ekos/capture/captureprocess.cpp:584 ekos/focus/focus.cpp:5060 #, kde-format msgid "" "Image transfer is disabled for this camera. Would you like to enable it?" msgstr "" -#: ekos/align/align.cpp:1475 +#: ekos/align/align.cpp:1482 #, kde-format msgid "Cannot capture while focus module is busy. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1483 +#: ekos/align/align.cpp:1490 #, kde-format msgid "" "Cannot capture while CCD exposure is in progress. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1492 +#: ekos/align/align.cpp:1499 #, fuzzy, kde-format msgid "Cannot capture while rotator is busy. Retrying in %1 seconds..." msgstr "Soek Voorwerp" -#: ekos/align/align.cpp:1510 ekos/align/align.cpp:2976 +#: ekos/align/align.cpp:1517 ekos/align/align.cpp:3012 #, kde-format msgid "No remote astrometry driver detected, switching to StellarSolver." msgstr "" -#: ekos/align/align.cpp:1564 ekos/focus/focus.cpp:1735 +#: ekos/align/align.cpp:1571 ekos/focus/focus.cpp:1760 #, fuzzy, kde-format msgid "Capturing image..." msgstr "Laaiïng van K-sterre..." -#: ekos/align/align.cpp:1654 ekos/auxiliary/ledstatuswidget.cpp:71 -#: ekos/focus/focus.cpp:2587 +#: ekos/align/align.cpp:1661 ekos/auxiliary/ledstatuswidget.cpp:71 +#: ekos/focus/focus.cpp:2706 #, fuzzy, kde-format msgid "Image received." msgstr "Beeld" -#: ekos/align/align.cpp:1784 +#: ekos/align/align.cpp:1791 #, kde-format msgid "" "No index files were found on your system in the specified index file " @@ -5864,83 +5869,98 @@ "to the list." msgstr "" -#: ekos/align/align.cpp:1843 +#: ekos/align/align.cpp:1850 #, fuzzy, kde-format msgid "Solving with blind image scale..." msgstr "Laaiïng van K-sterre..." -#: ekos/align/align.cpp:1851 +#: ekos/align/align.cpp:1858 #, fuzzy, kde-format msgid "Solving with blind image position..." msgstr "Laaiïng van K-sterre..." -#: ekos/align/align.cpp:1883 +#: ekos/align/align.cpp:1890 #, fuzzy, kde-format msgid "Loaded image does not have pierside information" msgstr "Kon nie Open Lêer" -#: ekos/align/align.cpp:1888 +#: ekos/align/align.cpp:1895 #, kde-format msgid "Loaded image was taken on pierside %1" msgstr "" -#: ekos/align/align.cpp:1990 +#: ekos/align/align.cpp:2020 #, fuzzy, kde-format msgid "Solver completed after %1 seconds." msgstr "Bereken" -#: ekos/align/align.cpp:2006 +#: ekos/align/align.cpp:2036 #, kde-format msgid "Solver RA (%1) DEC (%2) Orientation (%3) Pixel Scale (%4) Parity (%5)" msgstr "" -#: ekos/align/align.cpp:2073 +#: ekos/align/align.cpp:2103 #, kde-format msgid "" "WCS information updated. Images captured from this point forward shall have " "valid WCS." msgstr "" -#: ekos/align/align.cpp:2091 +#: ekos/align/align.cpp:2121 #, kde-format msgid "" "Solution coordinates: RA (%1) DEC (%2) Telescope Coordinates: RA (%3) DEC " "(%4) Target Coordinates: RA (%5) DEC (%6)" msgstr "" -#: ekos/align/align.cpp:2102 +#: ekos/align/align.cpp:2132 #, kde-format msgid "Target is within %1 degrees of solution coordinates." msgstr "" #. i18n("Camera offset angle is %1 degrees.", OffsetAngle)); -#: ekos/align/align.cpp:2147 +#: ekos/align/align.cpp:2177 #, fuzzy, kde-format msgid "Camera position angle is %1 degrees." msgstr "Koördinate" -#: ekos/align/align.cpp:2169 ekos/align/align.cpp:2601 -#: ekos/align/align.cpp:2641 +#: ekos/align/align.cpp:2199 ekos/align/align.cpp:2637 +#: ekos/align/align.cpp:2677 #, fuzzy, kde-format msgid "Astrometry alignment completed successfully" msgstr "Aarde koördinate" -#: ekos/align/align.cpp:2191 +#: ekos/align/align.cpp:2221 #, kde-format msgid "Maximum number of iterations reached. Solver failed." msgstr "" -#: ekos/align/align.cpp:2220 +#: ekos/align/align.cpp:2250 #, kde-format msgid "Target is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2303 +#: ekos/align/align.cpp:2312 +#, fuzzy, kde-format +msgid "Saving failed solver image to %1" +msgstr "Stooring van die beeld %1 gevaal!" + +#: ekos/align/align.cpp:2321 +#, kde-format +msgid "Solver failed. Retrying without scale constraint." +msgstr "" + +#: ekos/align/align.cpp:2331 +#, kde-format +msgid "Solver failed. Retrying without position constraint." +msgstr "" + +#: ekos/align/align.cpp:2339 #, fuzzy, kde-format msgid "Solver Failed." msgstr "Soek Voorwerp" -#: ekos/align/align.cpp:2306 +#: ekos/align/align.cpp:2342 #, kde-format msgid "" "Please check you have sufficient stars in the image, the indicated FOV is " @@ -5948,258 +5968,258 @@ "Logging in Setup Tab -> Logs to get detailed information on the failure." msgstr "" -#: ekos/align/align.cpp:2365 +#: ekos/align/align.cpp:2401 #, fuzzy, kde-format msgid "Setting camera position angle to %1 degrees ..." msgstr "Koördinate" -#: ekos/align/align.cpp:2372 +#: ekos/align/align.cpp:2408 #, kde-format msgid "Camera position angle is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2386 +#: ekos/align/align.cpp:2422 #, kde-format msgid "Current PA is %1; Target PA is %2; diff: %3" msgstr "" -#: ekos/align/align.cpp:2453 +#: ekos/align/align.cpp:2489 #, fuzzy, kde-format msgid "Refresh is complete." msgstr "Bereken" -#: ekos/align/align.cpp:2460 ekos/auxiliary/darklibrary.cpp:1411 -#: ekos/focus/focus.cpp:1506 +#: ekos/align/align.cpp:2496 ekos/auxiliary/darklibrary.cpp:1411 +#: ekos/focus/focus.cpp:1529 #, fuzzy, kde-format msgid "Capture aborted." msgstr "Stoor Beeld" -#: ekos/align/align.cpp:2466 +#: ekos/align/align.cpp:2502 #, fuzzy, kde-format msgid "Solver aborted after %1 seconds." msgstr "Ongeldige Url" -#: ekos/align/align.cpp:2509 ekos/capture/capture.cpp:1446 -#: ekos/focus/focus.cpp:3964 ekos/guide/guide.cpp:1118 ekos/manager.cpp:1897 -#: ekos/mount/mount.cpp:836 ekos/observatory/observatory.cpp:952 -#: ekos/scheduler/scheduler.cpp:911 +#: ekos/align/align.cpp:2545 ekos/capture/capture.cpp:1477 +#: ekos/focus/focus.cpp:4188 ekos/guide/guide.cpp:1137 ekos/manager.cpp:1903 +#: ekos/mount/mount.cpp:838 ekos/observatory/observatory.cpp:952 +#: ekos/scheduler/scheduler.cpp:748 #, kde-format msgctxt "log entry; %1 is the date, %2 is the text" msgid "%1 %2" msgstr "" -#: ekos/align/align.cpp:2572 +#: ekos/align/align.cpp:2608 #, kde-format msgid "Mount completed slewing near celestial pole. Capture again to verify." msgstr "" -#: ekos/align/align.cpp:2595 +#: ekos/align/align.cpp:2631 #, kde-format msgid "Mount is synced to solution coordinates." msgstr "" -#: ekos/align/align.cpp:2630 ekos/align/align.cpp:2660 -#: ekos/align/align.cpp:3971 ekos/align/polaralignmentassistant.cpp:637 +#: ekos/align/align.cpp:2666 ekos/align/align.cpp:2696 +#: ekos/align/align.cpp:4009 ekos/align/polaralignmentassistant.cpp:639 #, fuzzy, kde-format msgid "Settling..." msgstr "niks" -#: ekos/align/align.cpp:2636 +#: ekos/align/align.cpp:2672 #, fuzzy, kde-format msgid "Differential slewing complete." msgstr "Bereken" -#: ekos/align/align.cpp:2650 +#: ekos/align/align.cpp:2686 #, kde-format msgid "Slew complete. Target accuracy is not met, running solver again..." msgstr "" -#: ekos/align/align.cpp:2652 +#: ekos/align/align.cpp:2688 #, kde-format msgid "Slew complete. Solving Alignment Point. . ." msgstr "" -#: ekos/align/align.cpp:2695 ekos/align/align.cpp:2847 +#: ekos/align/align.cpp:2731 ekos/align/align.cpp:2883 #, kde-format msgid "Syncing failed." msgstr "" -#: ekos/align/align.cpp:2697 +#: ekos/align/align.cpp:2733 #, fuzzy, kde-format msgid "Slewing failed." msgstr "Vertoon naam" -#: ekos/align/align.cpp:2740 +#: ekos/align/align.cpp:2776 #, fuzzy, kde-format msgid "Rotator reached camera position angle." msgstr "Bereken" -#: ekos/align/align.cpp:2752 +#: ekos/align/align.cpp:2788 #, kde-format msgid "" "Rotator failed to arrive at the requested position angle (Deviation %1 " "arcmin)." msgstr "" -#: ekos/align/align.cpp:2797 +#: ekos/align/align.cpp:2833 #, fuzzy, kde-format msgid "Slew detected, suspend solving..." msgstr "Spanje" -#: ekos/align/align.cpp:2841 +#: ekos/align/align.cpp:2877 #, fuzzy, kde-format msgid "Syncing to RA (%1) DEC (%2)" msgstr "Koördinate" -#: ekos/align/align.cpp:2865 +#: ekos/align/align.cpp:2901 #, fuzzy, kde-format msgid "Slewing to target coordinates: RA (%1) DEC (%2)." msgstr "Koördinate" -#: ekos/align/align.cpp:2870 +#: ekos/align/align.cpp:2906 #, fuzzy, kde-format msgid "" "Slewing to target coordinates: RA (%1) DEC (%2) is rejected. (see " "notification)" msgstr "Koördinate" -#: ekos/align/align.cpp:2889 +#: ekos/align/align.cpp:2925 #, kde-format msgid "Ekos job (%1) - Telescope synced" msgstr "" -#: ekos/align/align.cpp:2945 +#: ekos/align/align.cpp:2981 #, fuzzy, kde-format #| msgid "Loading Image URLs" msgctxt "@title:window" msgid "Load Image" msgstr "Laaiïng van Beeld Urls" -#: ekos/align/align.cpp:3175 +#: ekos/align/align.cpp:3211 #, fuzzy, kde-format msgid "World Coordinate System (WCS) is enabled." msgstr "Horisontaal Koördinate" -#: ekos/align/align.cpp:3180 +#: ekos/align/align.cpp:3216 #, kde-format msgid "World Coordinate System (WCS) is disabled." msgstr "" -#: ekos/align/align.cpp:3199 +#: ekos/align/align.cpp:3235 #, fuzzy, kde-format msgid "Capture error. Aborting..." msgstr "Stoor Beeld" -#: ekos/align/align.cpp:3204 ekos/capture/captureprocess.cpp:1444 -#: ekos/capture/captureprocess.cpp:1939 +#: ekos/align/align.cpp:3240 ekos/capture/captureprocess.cpp:1470 +#: ekos/capture/captureprocess.cpp:1965 #, kde-format msgid "Restarting capture attempt #%1" msgstr "" -#: ekos/align/align.cpp:3324 +#: ekos/align/align.cpp:3360 #, fuzzy, kde-format msgctxt "@title:window" msgid "Align Frame" msgstr "Vertoon naam" -#: ekos/align/align.cpp:3399 +#: ekos/align/align.cpp:3435 #, fuzzy, kde-format msgid "StellarSolver Options" msgstr "Leo" -#: ekos/align/align.cpp:3404 +#: ekos/align/align.cpp:3440 #, kde-format msgid "External & Online Programs" msgstr "" -#: ekos/align/align.cpp:3408 +#: ekos/align/align.cpp:3444 #, fuzzy, kde-format msgid "Scale & Position" msgstr "Bereken" -#: ekos/align/align.cpp:3412 +#: ekos/align/align.cpp:3448 #, fuzzy, kde-format msgid "Align Options Profiles Editor" msgstr "Invoer Keuse" #. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/align/align.cpp:3430 ekos/align/opsastrometryindexfiles.ui:329 +#: ekos/align/align.cpp:3466 ekos/align/opsastrometryindexfiles.ui:329 #, fuzzy, kde-format msgid "Index Files" msgstr "Ongeldige Lêernaam" -#: ekos/align/align.cpp:3495 ekos/guide/guidetargetplot.cpp:55 +#: ekos/align/align.cpp:3531 ekos/guide/guidetargetplot.cpp:55 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Spain" msgid "dRA (arcsec)" msgstr "Spanje" -#: ekos/align/align.cpp:3496 ekos/guide/guidetargetplot.cpp:56 +#: ekos/align/align.cpp:3532 ekos/guide/guidetargetplot.cpp:56 #, fuzzy, kde-format #| msgctxt "seconds" #| msgid "secs" msgid "dDE (arcsec)" msgstr "sekondes" -#: ekos/align/align.cpp:3542 ekos/capture/capture.cpp:3297 -#: ekos/focus/focus.cpp:4711 +#: ekos/align/align.cpp:3578 ekos/capture/capture.cpp:2654 +#: ekos/focus/focus.cpp:4952 #, fuzzy, kde-format msgid "Filter operation failed." msgstr "Bereken" -#: ekos/align/align.cpp:3554 ekos/capture/capture.cpp:3233 +#: ekos/align/align.cpp:3590 ekos/capture/capture.cpp:2590 #, kde-format msgid "Changing focus offset by %1 steps..." msgstr "" -#: ekos/align/align.cpp:3561 ekos/auxiliary/buildfilteroffsets.cpp:466 -#: ekos/capture/capture.cpp:3238 +#: ekos/align/align.cpp:3597 ekos/auxiliary/buildfilteroffsets.cpp:466 +#: ekos/capture/capture.cpp:2595 #, kde-format msgid "Changing filter to %1..." msgstr "" -#: ekos/align/align.cpp:3566 ekos/capture/capture.cpp:3243 +#: ekos/align/align.cpp:3602 ekos/capture/capture.cpp:2600 #, fuzzy, kde-format msgid "Auto focus on filter change..." msgstr "Bereken" -#: ekos/align/align.cpp:3687 +#: ekos/align/align.cpp:3723 #, fuzzy, kde-format #| msgid "Invalid URL" msgid "Invalid FOV." msgstr "Ongeldige Url" -#: ekos/align/align.cpp:3822 +#: ekos/align/align.cpp:3860 #, fuzzy, kde-format msgctxt "@title:window" msgid "Export Solution Points" msgstr "Maak skoon Velde" -#: ekos/align/align.cpp:3845 ekos/align/mountmodel.cpp:263 -#: ekos/align/mountmodel.cpp:389 ekos/capture/capture.cpp:2077 -#: ekos/capture/capture.cpp:2507 ekos/guide/guidedriftgraph.cpp:475 -#: ekos/scheduler/scheduler.cpp:3462 ekos/scheduler/scheduler.cpp:3831 -#: fitsviewer/fitstab.cpp:494 tools/scriptbuilder.cpp:832 +#: ekos/align/align.cpp:3883 ekos/align/mountmodel.cpp:264 +#: ekos/align/mountmodel.cpp:390 ekos/capture/capture.cpp:1950 +#: ekos/capture/capture.cpp:2036 ekos/guide/guidedriftgraph.cpp:476 +#: ekos/scheduler/scheduler.cpp:2592 ekos/scheduler/scheduler.cpp:2959 +#: fitsviewer/fitstab.cpp:503 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:929 #, fuzzy, kde-format msgid "Invalid URL: %1" msgstr "Ongeldige Url" -#: ekos/align/align.cpp:3854 ekos/align/mountmodel.cpp:400 -#: ekos/capture/capture.cpp:2530 ekos/guide/guidedriftgraph.cpp:484 -#: ekos/scheduler/scheduler.cpp:3843 ekos/scheduler/scheduler.cpp:6221 +#: ekos/align/align.cpp:3892 ekos/align/mountmodel.cpp:401 +#: ekos/capture/captureprocess.cpp:2392 ekos/guide/guidedriftgraph.cpp:485 +#: ekos/scheduler/scheduler.cpp:4001 ekos/scheduler/schedulerprocess.cpp:1573 #, fuzzy, kde-format msgid "Unable to write to file %1" msgstr "Kon nie Open Lêer" -#: ekos/align/align.cpp:3855 ekos/align/mountmodel.cpp:283 -#: ekos/align/mountmodel.cpp:401 ekos/capture/capture.cpp:2093 -#: ekos/guide/guidedriftgraph.cpp:485 ekos/scheduler/scheduler.cpp:3506 -#: ekos/scheduler/scheduler.cpp:3844 ekos/scheduler/scheduler.cpp:6165 -#: ekos/scheduler/scheduler.cpp:6222 indi/drivermanager.cpp:1520 -#: indi/indidriver.cpp:921 kstarsactions.cpp:1375 oal/execute.cpp:320 -#: options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 +#: ekos/align/align.cpp:3893 ekos/align/mountmodel.cpp:284 +#: ekos/align/mountmodel.cpp:402 ekos/capture/capture.cpp:1966 +#: ekos/capture/captureprocess.cpp:2276 ekos/guide/guidedriftgraph.cpp:486 +#: ekos/scheduler/scheduler.cpp:2636 ekos/scheduler/scheduler.cpp:3945 +#: ekos/scheduler/scheduler.cpp:4002 ekos/scheduler/schedulerprocess.cpp:1574 +#: indi/drivermanager.cpp:1537 indi/indidriver.cpp:921 kstarsactions.cpp:1384 +#: oal/execute.cpp:320 options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 #: tools/modcalcapcoord.cpp:142 tools/modcalcdaylength.cpp:257 #: tools/modcalcgalcoord.cpp:191 tools/modcalcgeodcoord.cpp:231 #: tools/modcalcjd.cpp:117 tools/modcalcplanets.cpp:195 @@ -6211,27 +6231,27 @@ msgid "Could Not Open File" msgstr "Kon nie Open Lêer" -#: ekos/align/align.cpp:3876 +#: ekos/align/align.cpp:3914 #, fuzzy, kde-format msgid "Error in table structure." msgstr "Fout Uitveeïng Lêer" -#: ekos/align/align.cpp:3885 +#: ekos/align/align.cpp:3923 #, fuzzy, kde-format msgid "Solution Points Saved as: %1" msgstr "Horisontaal Koördinate" -#: ekos/align/align.cpp:3899 +#: ekos/align/align.cpp:3937 #, fuzzy, kde-format msgid "Polar Alignment" msgstr "Vertoon naam" -#: ekos/align/align.cpp:4428 +#: ekos/align/align.cpp:4466 #, fuzzy, kde-format msgid "Capture timed out." msgstr "Stoor Beeld" -#: ekos/align/align.cpp:4437 +#: ekos/align/align.cpp:4475 #, fuzzy, kde-format msgid "Capturing still running, Retrying in %1 seconds..." msgstr "Soek Voorwerp" @@ -6276,7 +6296,7 @@ #. i18n: ectx: property (text), widget (QPushButton, stopFocusB) #: ekos/align/align.ui:149 ekos/align/polaralignmentassistant.ui:819 #: ekos/align/polaralignmentassistant.ui:822 ekos/auxiliary/darklibrary.ui:585 -#: ekos/focus/focus.ui:456 ekos/guide/guide.ui:153 ekos/manager.cpp:222 +#: ekos/focus/focus.ui:373 ekos/guide/guide.ui:153 ekos/manager.cpp:226 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:137 @@ -6494,20 +6514,20 @@ #. i18n: ectx: property (text), widget (QLabel, gainLabel) #: ekos/align/align.ui:555 ekos/auxiliary/darklibrary.ui:477 #: ekos/capture/capture.ui:137 ekos/capture/captureprocessoverlay.ui:296 -#: ekos/focus/focus.ui:514 +#: ekos/focus/focus.ui:533 #, kde-format msgid "Gain:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_18) #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/align.ui:562 ekos/focus/focus.ui:790 ekos/guide/guide.ui:401 +#: ekos/align/align.ui:562 ekos/focus/focus.ui:809 ekos/guide/guide.ui:401 #, kde-format msgid "Bin:" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, showFITSViewerB) -#: ekos/align/align.ui:584 ekos/focus/focus.ui:720 ekos/guide/guide.ui:166 +#: ekos/align/align.ui:584 ekos/focus/focus.ui:739 ekos/guide/guide.ui:166 #, fuzzy, kde-format msgid "Show in FITS Viewer" msgstr " Welkom na K-sterre " @@ -6559,7 +6579,7 @@ #. i18n: ectx: property (text), widget (QLabel, filterLabel) #. i18n: ectx: property (text), widget (QLabel, label) #. i18n: ectx: property (text), widget (QLabel, label_18) -#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:558 +#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:577 #: ekos/profileeditor.ui:644 fitsviewer/fitsdebayer.ui:22 oal/execute.ui:358 #, fuzzy, kde-format msgid "Filter:" @@ -6575,7 +6595,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/align/align.ui:700 ekos/focus/focus.ui:571 ekos/guide/guide.ui:375 +#: ekos/align/align.ui:700 ekos/focus/focus.ui:590 ekos/guide/guide.ui:375 #, kde-format msgid "Exp:" msgstr "" @@ -6590,7 +6610,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_11) #. i18n: ectx: property (text), widget (QLabel, ISOLabel) #: ekos/align/align.ui:736 ekos/auxiliary/darklibrary.ui:506 -#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:816 +#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:835 #, kde-format msgid "ISO:" msgstr "" @@ -6649,11 +6669,12 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, l_02) #. i18n: ectx: property (text), widget (QLabel, label_2) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverDECLabel) #: ekos/align/align.ui:916 ekos/align/opsastrometry.ui:389 #: ekos/guide/guide.ui:342 ekos/guide/guide.ui:1247 #: ekos/guide/opscalibration.ui:300 ekos/guide/opsguide.ui:128 #: ekos/mount/mount.ui:161 ekos/scheduler/scheduler.ui:488 -#: skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:222 skycomponents/imageoverlaycomponent.cpp:62 #, fuzzy, kde-format #| msgctxt "Region/state name (optional, rarely needs a translation)" #| msgid "DC" @@ -6804,77 +6825,78 @@ msgid "Take Another Image" msgstr "Noord" -#: ekos/align/mountmodel.cpp:255 +#: ekos/align/mountmodel.cpp:256 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Alignment List" msgstr "Voeg by na Lys" -#: ekos/align/mountmodel.cpp:282 ekos/capture/capture.cpp:2092 -#: ekos/scheduler/scheduler.cpp:3505 ekos/scheduler/scheduler.cpp:6164 +#: ekos/align/mountmodel.cpp:283 ekos/capture/capture.cpp:1965 +#: ekos/capture/captureprocess.cpp:2275 ekos/scheduler/scheduler.cpp:2635 +#: ekos/scheduler/scheduler.cpp:3944 #, fuzzy, kde-format msgid "Unable to open file %1" msgstr "Kon nie Open Lêer" -#: ekos/align/mountmodel.cpp:304 ekos/capture/capture.cpp:2119 +#: ekos/align/mountmodel.cpp:305 ekos/capture/captureprocess.cpp:2301 #, kde-format msgid "" "Deprecated sequence file format version %1. Please construct a new sequence " "file." msgstr "" -#: ekos/align/mountmodel.cpp:366 +#: ekos/align/mountmodel.cpp:367 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save Ekos Alignment List" msgstr "Voeg by na Lys" -#: ekos/align/mountmodel.cpp:383 +#: ekos/align/mountmodel.cpp:384 #, fuzzy, kde-format msgid "Failed to save alignment list" msgstr "Kon nie Open Lêer" -#: ekos/align/mountmodel.cpp:429 +#: ekos/align/mountmodel.cpp:430 #, fuzzy, kde-format msgid "Alignment List saved to %1" msgstr "Ongeldige Url" -#: ekos/align/mountmodel.cpp:541 ekos/align/mountmodel.cpp:549 +#: ekos/align/mountmodel.cpp:542 ekos/align/mountmodel.cpp:550 #, kde-format msgid "DEC is below the altitude limit" msgstr "" -#: ekos/align/mountmodel.cpp:628 +#: ekos/align/mountmodel.cpp:629 #, fuzzy, kde-format msgid "Point calculation error." msgstr "Bereken" -#: ekos/align/mountmodel.cpp:650 +#: ekos/align/mountmodel.cpp:651 #, fuzzy, kde-format msgid "Sky Point" msgstr "Oos Punt" -#: ekos/align/mountmodel.cpp:858 +#: ekos/align/mountmodel.cpp:859 #, kde-format msgid "Are you sure you want to clear all the alignment points?" msgstr "" -#: ekos/align/mountmodel.cpp:859 +#: ekos/align/mountmodel.cpp:860 #, fuzzy, kde-format msgid "Clear Align Points" msgstr "Maak skoon Velde" -#: ekos/align/mountmodel.cpp:964 +#: ekos/align/mountmodel.cpp:965 #, kde-format msgid "The Mount Model Tool is Reset." msgstr "" -#: ekos/align/mountmodel.cpp:1001 +#: ekos/align/mountmodel.cpp:1002 #, kde-format msgid "Please Check the Alignment Points." msgstr "" -#: ekos/align/mountmodel.cpp:1008 +#: ekos/align/mountmodel.cpp:1009 #, kde-format msgid "" "In the Align Module, \"Nothing\" is Selected for the Solver Action. This " @@ -6882,22 +6904,22 @@ "report the pointing model errors. Do you wish to continue?" msgstr "" -#: ekos/align/mountmodel.cpp:1011 +#: ekos/align/mountmodel.cpp:1012 #, kde-format msgid "Pointing Model Report Only?" msgstr "" -#: ekos/align/mountmodel.cpp:1028 +#: ekos/align/mountmodel.cpp:1029 #, kde-format msgid "The Mount Model Tool is Starting." msgstr "" -#: ekos/align/mountmodel.cpp:1037 +#: ekos/align/mountmodel.cpp:1038 #, kde-format msgid "The Mount Model Tool is Paused." msgstr "" -#: ekos/align/mountmodel.cpp:1096 +#: ekos/align/mountmodel.cpp:1097 #, kde-format msgid "The Mount Model Tool is Finished." msgstr "" @@ -7586,8 +7608,11 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUseImageScale) +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_FitsSolverUseScale) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverScale) #. i18n: ectx: label, entry (AstrometryUseImageScale), group (Align) -#: ekos/align/opsastrometry.ui:57 kstars.kcfg:2329 +#: ekos/align/opsastrometry.ui:57 fitsviewer/platesolve.ui:57 +#: fitsviewer/platesolve.ui:70 kstars.kcfg:2399 #, kde-format msgid "" "Set image scale to speed up solver as it does not have to search index files " @@ -7595,7 +7620,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUseImageScale) -#: ekos/align/opsastrometry.ui:60 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUseScale) +#: ekos/align/opsastrometry.ui:60 fitsviewer/platesolve.ui:60 #, fuzzy, kde-format msgid "Use Scale" msgstr "Lyn " @@ -7731,7 +7757,7 @@ #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUsePosition) #. i18n: ectx: label, entry (AstrometryUsePosition), group (Align) -#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2359 +#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2429 #, kde-format msgid "" "Set estimated position to speed up astrometry solver as it does not have to " @@ -7739,16 +7765,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUsePosition) -#: ekos/align/opsastrometry.ui:325 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUsePosition) +#: ekos/align/opsastrometry.ui:325 fitsviewer/platesolve.ui:142 #, fuzzy, kde-format msgid "Use Position" msgstr "Bereken" #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_44) #. i18n: ectx: property (toolTip), widget (QLabel, label_8) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRadiusLabel) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverRadius) #. i18n: ectx: label, entry (AstrometryRadius), group (Align) #: ekos/align/opsastrometry.ui:344 ekos/align/opsastrometry.ui:451 -#: kstars.kcfg:2373 +#: fitsviewer/platesolve.ui:270 fitsviewer/platesolve.ui:286 kstars.kcfg:2443 #, kde-format msgid "" "The Search Radius for the Estimated Telescope/Image Field Position in " @@ -7770,8 +7799,11 @@ #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_47) #. i18n: ectx: property (toolTip), widget (dmsBox, estRA) #. i18n: ectx: property (toolTip), widget (QLabel, label_14) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRALabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstRA) #: ekos/align/opsastrometry.ui:376 ekos/align/opsastrometry.ui:399 -#: ekos/align/opsastrometry.ui:406 +#: ekos/align/opsastrometry.ui:406 fitsviewer/platesolve.ui:174 +#: fitsviewer/platesolve.ui:199 #, kde-format msgid "" "The RA of the Estimated Telescope/Image Field Position in hh:mm:ss notation" @@ -7786,8 +7818,11 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_15) #. i18n: ectx: property (toolTip), widget (dmsBox, estDec) #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_48) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverDECLabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstDec) #: ekos/align/opsastrometry.ui:386 ekos/align/opsastrometry.ui:470 -#: ekos/align/opsastrometry.ui:493 +#: ekos/align/opsastrometry.ui:493 fitsviewer/platesolve.ui:219 +#: fitsviewer/platesolve.ui:250 #, kde-format msgid "" "The DEC of the Estimated Telescope/Image Field Position in dd:mm:ss notation" @@ -7800,7 +7835,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/opsastrometry.ui:454 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRadiusLabel) +#: ekos/align/opsastrometry.ui:454 fitsviewer/platesolve.ui:273 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Reading" @@ -8024,7 +8060,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, northDECGuideEnabled) #: ekos/align/opsastrometryindexfiles.ui:256 ekos/analyze/analyze.ui:199 #: ekos/auxiliary/stellarsolverprofileeditor.ui:213 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:531 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:511 #: ekos/guide/guide.ui:304 ekos/guide/guide.ui:456 #: kstarslite/qml/indi/modules/MotionControl.qml:294 #, kde-format, kde-kuit-format @@ -8965,208 +9001,213 @@ msgid "API Key:" msgstr "Vertoon Opsies" -#: ekos/align/polaralignmentassistant.cpp:28 +#: ekos/align/polaralignmentassistant.cpp:29 #, fuzzy, kde-format msgid "First Capture" msgstr "Stoor Beeld" -#: ekos/align/polaralignmentassistant.cpp:29 +#: ekos/align/polaralignmentassistant.cpp:30 #, kde-format msgid "First Solve" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:30 +#: ekos/align/polaralignmentassistant.cpp:31 #, fuzzy, kde-format msgid "Finding CP" msgstr "Soek Voorwerp" -#: ekos/align/polaralignmentassistant.cpp:31 +#: ekos/align/polaralignmentassistant.cpp:32 #, fuzzy, kde-format msgid "First Rotation" msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:32 +#: ekos/align/polaralignmentassistant.cpp:33 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Sale" msgid "First Settle" msgstr "Koop" -#: ekos/align/polaralignmentassistant.cpp:33 +#: ekos/align/polaralignmentassistant.cpp:34 #, fuzzy, kde-format #| msgid "Close Window" msgid "Second Capture" msgstr "Maak toe Venster" -#: ekos/align/polaralignmentassistant.cpp:34 +#: ekos/align/polaralignmentassistant.cpp:35 #, fuzzy, kde-format #| msgctxt "seconds" #| msgid "secs" msgid "Second Solve" msgstr "sekondes" -#: ekos/align/polaralignmentassistant.cpp:35 +#: ekos/align/polaralignmentassistant.cpp:36 #, fuzzy, kde-format msgid "Second Rotation" msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:36 +#: ekos/align/polaralignmentassistant.cpp:37 #, fuzzy, kde-format #| msgid "Close Window" msgid "Second Settle" msgstr "Maak toe Venster" -#: ekos/align/polaralignmentassistant.cpp:37 +#: ekos/align/polaralignmentassistant.cpp:38 #, fuzzy, kde-format msgid "Third Capture" msgstr "Stoor Beeld" -#: ekos/align/polaralignmentassistant.cpp:38 +#: ekos/align/polaralignmentassistant.cpp:39 #, fuzzy, kde-format msgid "Third Solve" msgstr "Solied Rooi" -#: ekos/align/polaralignmentassistant.cpp:39 +#: ekos/align/polaralignmentassistant.cpp:40 #, fuzzy, kde-format msgid "Select Star" msgstr "Invoer Keuse" -#: ekos/align/polaralignmentassistant.cpp:40 +#: ekos/align/polaralignmentassistant.cpp:41 #, kde-format msgid "Refreshing" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:41 +#: ekos/align/polaralignmentassistant.cpp:42 #, fuzzy, kde-format msgid "Refresh Complete" msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:121 +#: ekos/align/polaralignmentassistant.cpp:122 #, kde-format msgid "

    Polar Alignment tool requires a German Equatorial Mount.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:176 +#: ekos/align/polaralignmentassistant.cpp:177 #, fuzzy, kde-format #| msgctxt "the time at which an object falls below the horizon" #| msgid "Set time: %1" msgid "Refresh solver timed out: %1s" msgstr "Stel tyd: %1" -#: ekos/align/polaralignmentassistant.cpp:181 +#: ekos/align/polaralignmentassistant.cpp:182 #, fuzzy, kde-format msgid "Refresh solver failed: %1s" msgstr "Soek Voorwerp" -#: ekos/align/polaralignmentassistant.cpp:574 +#: ekos/align/polaralignmentassistant.cpp:569 +#, fuzzy, kde-format +msgid "PAA: Solver failed, retrying." +msgstr "Soek Voorwerp" + +#: ekos/align/polaralignmentassistant.cpp:576 #, kde-format msgid "PAA: Stopping, solver failed too many times." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:603 +#: ekos/align/polaralignmentassistant.cpp:605 #, fuzzy, kde-format msgid "Mount first rotation is complete." msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:610 +#: ekos/align/polaralignmentassistant.cpp:612 #, fuzzy, kde-format msgid "Mount second rotation is complete." msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:649 +#: ekos/align/polaralignmentassistant.cpp:651 #, kde-format msgid "Mount aborted. Reverse RA axis direction and try again." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:734 +#: ekos/align/polaralignmentassistant.cpp:736 #, kde-format msgid "" "Warning: Equatorial Grid Lines will not be drawn due to limited resources " "mode." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:738 +#: ekos/align/polaralignmentassistant.cpp:740 #, fuzzy, kde-format msgid "Clearing mount Alignment Model..." msgstr "Spanje" -#: ekos/align/polaralignmentassistant.cpp:779 +#: ekos/align/polaralignmentassistant.cpp:781 #, kde-format msgid "This could cause the telescope to cross the meridian." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:829 +#: ekos/align/polaralignmentassistant.cpp:831 #, fuzzy, kde-format msgid "Parking the mount..." msgstr "Planeet" -#: ekos/align/polaralignmentassistant.cpp:869 +#: ekos/align/polaralignmentassistant.cpp:871 #, kde-format msgid "Please wait until mount completes rotating to RA (%1) DE (%2)" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:885 -#: ekos/align/polaralignmentassistant.cpp:891 +#: ekos/align/polaralignmentassistant.cpp:887 +#: ekos/align/polaralignmentassistant.cpp:893 #, fuzzy, kde-format msgid "PAA: Failed to findCorrectedPixel." msgstr "Kon nie Open Lêer" -#: ekos/align/polaralignmentassistant.cpp:917 +#: ekos/align/polaralignmentassistant.cpp:919 #, fuzzy, kde-format msgid "PAA: Failed to find RA Axis center." msgstr "Kon nie Open Lêer" -#: ekos/align/polaralignmentassistant.cpp:988 +#: ekos/align/polaralignmentassistant.cpp:990 #, kde-format msgid "" "Polar-alignment star cannot be updated during refresh phase as it might " "affect error measurements." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1005 +#: ekos/align/polaralignmentassistant.cpp:1007 #, fuzzy, kde-format msgid "First manual rotation done." msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:1010 +#: ekos/align/polaralignmentassistant.cpp:1012 #, fuzzy, kde-format msgid "Second manual rotation done." msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:1053 +#: ekos/align/polaralignmentassistant.cpp:1055 #, kde-format msgid "" "Mount is synced to celestial pole. You can now continue Polar Alignment " "Assistant procedure." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1072 +#: ekos/align/polaralignmentassistant.cpp:1074 #, kde-format msgid "Please wait while WCS data is processed..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1103 +#: ekos/align/polaralignmentassistant.cpp:1105 #, fuzzy, kde-format msgid "WCS data processing is complete." msgstr "Bereken" -#: ekos/align/polaralignmentassistant.cpp:1112 +#: ekos/align/polaralignmentassistant.cpp:1114 #, kde-format msgid "WCS info is now valid. Capturing next frame..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1154 +#: ekos/align/polaralignmentassistant.cpp:1156 #, fuzzy, kde-format msgid "Failed to process World Coordinate System: %1. Try again." msgstr "Invoer Keuse" -#: ekos/align/polaralignmentassistant.cpp:1172 +#: ekos/align/polaralignmentassistant.cpp:1174 #, fuzzy, kde-format msgid "PAA: Failed to find the RA axis. Quitting." msgstr "Kon nie Open Lêer" #. i18n: ectx: property (text), widget (QLabel, PAHMessageText) -#: ekos/align/polaralignmentassistant.cpp:1203 +#: ekos/align/polaralignmentassistant.cpp:1205 #: ekos/align/polaralignmentassistant.ui:212 #, kde-format msgid "" @@ -9174,59 +9215,59 @@ "capturing the first image...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1205 +#: ekos/align/polaralignmentassistant.cpp:1207 #, fuzzy, kde-format msgid "

    Solving the first image...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1207 +#: ekos/align/polaralignmentassistant.cpp:1209 #, fuzzy, kde-format msgid "

    Executing the first mount rotation...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1209 +#: ekos/align/polaralignmentassistant.cpp:1211 #, kde-format msgid "

    Settling after the first mount rotation.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1211 +#: ekos/align/polaralignmentassistant.cpp:1213 #, fuzzy, kde-format msgid "

    Settling after the second mount rotation.

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1213 +#: ekos/align/polaralignmentassistant.cpp:1215 #, fuzzy, kde-format msgid "

    Capturing the second image...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1215 +#: ekos/align/polaralignmentassistant.cpp:1217 #, fuzzy, kde-format msgid "

    Solving the second image...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1217 +#: ekos/align/polaralignmentassistant.cpp:1219 #, fuzzy, kde-format msgid "

    Executing the second mount rotation...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1219 +#: ekos/align/polaralignmentassistant.cpp:1221 #, fuzzy, kde-format msgid "

    Capturing the third and final image...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1221 +#: ekos/align/polaralignmentassistant.cpp:1223 #, fuzzy, kde-format msgid "

    Solving the third image...

    " msgstr "Laaiïng van K-sterre..." -#: ekos/align/polaralignmentassistant.cpp:1224 +#: ekos/align/polaralignmentassistant.cpp:1226 #, kde-format msgid "" "

    Choose your exposure time & select an adjustment method. Then click " "refresh to begin adjustments.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1226 +#: ekos/align/polaralignmentassistant.cpp:1228 #, kde-format msgid "" "

    Choose your exposure time & select an adjustment method. Click " @@ -9235,7 +9276,7 @@ "MoveStar & Calc Error method to estimate the remaining error.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1229 +#: ekos/align/polaralignmentassistant.cpp:1231 #, kde-format msgid "" "

    Adjust mount's Altitude and Azimuth knobs to reduce the polar " @@ -9244,7 +9285,7 @@ "you're finished.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1231 +#: ekos/align/polaralignmentassistant.cpp:1233 #, kde-format msgid "" "

    Adjust mount's Altitude knob to move the star along the yellow " @@ -9253,7 +9294,7 @@ "Stop when the star is centered.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1247 +#: ekos/align/polaralignmentassistant.cpp:1249 #, kde-format msgid "Cannot change to MoveStar algorithm once refresh has begun" msgstr "" @@ -9456,7 +9497,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1_2) #. i18n: ectx: property (text), widget (QLabel, label_8) #: ekos/align/polaralignmentassistant.ui:548 -#: ekos/capture/calibrationoptions.ui:102 tools/argsetaltaz.ui:37 +#: ekos/capture/calibrationoptions.ui:87 tools/argsetaltaz.ui:37 #: tools/modcalcplanets.ui:296 #, fuzzy, kde-format msgid "Alt:" @@ -9507,7 +9548,7 @@ #. i18n: ectx: property (text), widget (QPushButton, startB) #: ekos/align/polaralignmentassistant.ui:806 #: ekos/align/polaralignmentassistant.ui:809 ekos/auxiliary/darklibrary.ui:575 -#: ekos/manager.cpp:140 ekos/manager.cpp:228 ekos/manager.cpp:580 +#: ekos/manager.cpp:143 ekos/manager.cpp:232 ekos/manager.cpp:584 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:166 @@ -9524,10 +9565,10 @@ #. i18n: ectx: property (text), widget (QPushButton, captureB) #. i18n: ectx: attribute (title), widget (QWidget, captureTab) #: ekos/align/polaralignwidget.ui:37 ekos/align/polaralignwidget.ui:157 -#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1872 +#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1874 #: ekos/analyze/analyze.ui:374 ekos/auxiliary/opslogs.ui:285 #: ekos/capture/capturepreviewwidget.ui:79 ekos/guide/guide.ui:137 -#: ekos/opsekos.ui:538 +#: ekos/opsekos.ui:551 #, fuzzy, kde-format msgid "Capture" msgstr "Stoor Beeld" @@ -9535,9 +9576,11 @@ #. i18n: ectx: property (text), widget (QLabel, PAso1) #. i18n: ectx: property (text), widget (QLabel, PAso2) #. i18n: ectx: property (text), widget (QLabel, PAso3) +#. i18n: ectx: property (text), widget (QPushButton, SolveButton) #. i18n: ectx: property (text), widget (QPushButton, solveButton) #: ekos/align/polaralignwidget.ui:77 ekos/align/polaralignwidget.ui:197 -#: ekos/align/polaralignwidget.ui:317 options/opsimageoverlay.ui:242 +#: ekos/align/polaralignwidget.ui:317 fitsviewer/fitstab.cpp:676 +#: fitsviewer/platesolve.ui:50 options/opsimageoverlay.ui:242 #: skycomponents/imageoverlaycomponent.cpp:343 #: skycomponents/imageoverlaycomponent.cpp:703 #: skycomponents/imageoverlaycomponent.cpp:783 @@ -9555,7 +9598,7 @@ msgstr "Koop" #. i18n: ectx: property (text), widget (QLabel, PAsetup) -#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:324 +#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:328 #, kde-format msgid "Setup" msgstr "" @@ -9598,50 +9641,50 @@ msgid "Failed to find solver settings." msgstr "Kon nie Open Lêer" -#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 #: ekos/observatory/observatory.cpp:356 indi/indidome.cpp:21 #: indi/indidustcap.cpp:18 indi/indimount.cpp:32 #, fuzzy, kde-format msgid "Parked" msgstr "Moore" -#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 +#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 #: ekos/observatory/observatory.cpp:283 ekos/observatory/observatory.cpp:299 #: indi/indidome.cpp:21 indi/indidustcap.cpp:17 indi/indimount.cpp:32 #, fuzzy, kde-format msgid "Parking" msgstr "Trinidad" -#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 ekos/ekos.h:140 -#: ekos/scheduler/schedulerjob.cpp:638 indi/indimount.cpp:31 +#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 ekos/ekos.h:140 +#: ekos/scheduler/schedulerjob.cpp:614 indi/indimount.cpp:31 #, fuzzy, kde-format msgid "Slewing" msgstr "Koop" -#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 +#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 #: indi/indimount.cpp:31 #, fuzzy, kde-format msgid "Moving" msgstr "Laaiïng van K-sterre..." #. i18n: ectx: property (title), widget (QGroupBox, trackingGroup) -#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 +#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:156 #: ekos/mount/mount.ui:611 indi/indidome.cpp:21 indi/indimount.cpp:32 #, fuzzy, kde-format msgid "Tracking" msgstr "Stop Horlosie" -#: ekos/analyze/analyze.cpp:480 ekos/analyze/analyze.cpp:492 +#: ekos/analyze/analyze.cpp:482 ekos/analyze/analyze.cpp:494 #, fuzzy, kde-format msgid "Current Session" msgstr "Stoor Huidige Kleure..." -#: ekos/analyze/analyze.cpp:481 +#: ekos/analyze/analyze.cpp:483 #, fuzzy, kde-format msgid "Read from File" msgstr "Invoer Keuse" -#: ekos/analyze/analyze.cpp:482 +#: ekos/analyze/analyze.cpp:484 #, kde-format msgid "Set alternative image-file base directory" msgstr "" @@ -9649,23 +9692,23 @@ #. i18n call below is broken up (and the word "analyze" is protected from it) because i18n #. translates "analyze" to "analyse" for the English UK locale, but we need to keep it ".analyze" #. because that's what how the files are named. -#: ekos/analyze/analyze.cpp:506 +#: ekos/analyze/analyze.cpp:508 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select input file" msgstr "Invoer Keuse" -#: ekos/analyze/analyze.cpp:507 +#: ekos/analyze/analyze.cpp:509 #, fuzzy, kde-format msgid "All Files (*)" msgstr "Invoer Keuse" -#: ekos/analyze/analyze.cpp:527 +#: ekos/analyze/analyze.cpp:529 #, kde-format msgid "Set an alternate base directory for your captured images" msgstr "" -#: ekos/analyze/analyze.cpp:1169 +#: ekos/analyze/analyze.cpp:1171 #, fuzzy, kde-format #| msgid "Could not delete the file: %1" msgid "Could not find image file: %1" @@ -9674,8 +9717,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FocusLogging) #. i18n: ectx: property (text), widget (QLabel, label_10) #. i18n: ectx: property (text), widget (QCheckBox, focusStepCheck) -#: ekos/analyze/analyze.cpp:1873 ekos/auxiliary/opslogs.ui:377 -#: ekos/manager.cpp:2016 ekos/manager/focusmanager.ui:101 +#: ekos/analyze/analyze.cpp:1875 ekos/auxiliary/opslogs.ui:377 +#: ekos/manager.cpp:2022 ekos/manager/focusmanager.ui:101 #: ekos/scheduler/framingassistant.ui:1490 ekos/scheduler/scheduler.ui:445 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:430 #, kde-format @@ -9683,7 +9726,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, alignStepCheck) -#: ekos/analyze/analyze.cpp:1874 ekos/manager.cpp:1990 +#: ekos/analyze/analyze.cpp:1876 ekos/manager.cpp:1996 #: ekos/scheduler/framingassistant.ui:1262 ekos/scheduler/scheduler.ui:398 #: fitsviewer/fitscommon.h:16 fitsviewer/fitsviewer.cpp:438 #, fuzzy, kde-format @@ -9694,16 +9737,16 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_GuideLogging) #. i18n: ectx: property (text), widget (QPushButton, guideB) #. i18n: ectx: property (text), widget (QCheckBox, guideStepCheck) -#: ekos/analyze/analyze.cpp:1875 ekos/analyze/analyze.ui:338 -#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:55 -#: ekos/guide/guide.ui:263 ekos/manager.cpp:2170 +#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:338 +#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:58 +#: ekos/guide/guide.ui:263 ekos/manager.cpp:2176 #: ekos/scheduler/framingassistant.ui:1226 ekos/scheduler/scheduler.ui:420 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:434 #, kde-format msgid "Guide" msgstr "" -#: ekos/analyze/analyze.cpp:1876 +#: ekos/analyze/analyze.cpp:1878 #, fuzzy, kde-format msgid "Flip" msgstr "Sirkel" @@ -9712,20 +9755,20 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDIMountLogging) #. i18n: ectx: property (text), widget (QCheckBox, kcfg_MountLogging) #. i18n: ectx: property (text), widget (QLabel, mountLabel) -#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:356 +#: ekos/analyze/analyze.cpp:1879 ekos/analyze/analyze.ui:356 #: ekos/auxiliary/opslogs.ui:77 ekos/auxiliary/opslogs.ui:420 -#: ekos/manager.cpp:2099 ekos/manager.ui:665 +#: ekos/manager.cpp:2105 ekos/manager.ui:665 #, fuzzy, kde-format msgid "Mount" msgstr "Land:" #. i18n: ectx: property (text), widget (QLabel, jobLabel) -#: ekos/analyze/analyze.cpp:1878 ekos/capture/capturecountswidget.ui:473 +#: ekos/analyze/analyze.cpp:1880 ekos/capture/capturecountswidget.ui:473 #, kde-format msgid "Job" msgstr "" -#: ekos/analyze/analyze.cpp:2136 +#: ekos/analyze/analyze.cpp:2138 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9733,7 +9776,7 @@ "will have their HFRs computed." msgstr "" -#: ekos/analyze/analyze.cpp:2152 +#: ekos/analyze/analyze.cpp:2154 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9741,107 +9784,107 @@ "newly captured images will have their stars detected." msgstr "" -#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/ledstatuswidget.cpp:78 -#: ekos/capture/sequencejob.cpp:21 ekos/ekos.h:21 ekos/ekos.h:72 +#: ekos/analyze/analyze.cpp:2855 ekos/auxiliary/ledstatuswidget.cpp:78 +#: ekos/capture/sequencejob.cpp:23 ekos/ekos.h:21 ekos/ekos.h:72 #: ekos/ekos.h:119 ekos/ekos.h:139 ekos/ekos.h:188 -#: ekos/scheduler/schedulerjob.cpp:619 +#: ekos/scheduler/schedulerjob.cpp:595 #, fuzzy, kde-format msgid "Aborted" msgstr " norman" -#: ekos/analyze/analyze.cpp:2855 ekos/ekos.h:22 +#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:22 #, fuzzy, kde-format msgid "Connected" msgstr "Bereken" -#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:23 +#: ekos/analyze/analyze.cpp:2859 ekos/ekos.h:23 #, fuzzy, kde-format msgid "Disconnected" msgstr "Bereken" -#: ekos/analyze/analyze.cpp:2859 ekos/auxiliary/ledstatuswidget.cpp:68 -#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:651 +#: ekos/analyze/analyze.cpp:2861 ekos/auxiliary/ledstatuswidget.cpp:68 +#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:627 #, fuzzy, kde-format msgid "Capturing" msgstr "Stoor Beeld" -#: ekos/analyze/analyze.cpp:2861 ekos/ekos.h:25 +#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:25 #, kde-format msgid "Looping" msgstr "" -#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:26 +#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:26 #, fuzzy, kde-format msgid "Subtracting" msgstr "Bereken" -#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:27 +#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:27 #, fuzzy, kde-format msgid "Subframing" msgstr "Ster Naam" -#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:28 +#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:28 #, fuzzy, kde-format msgid "Selecting star" msgstr "Invoer Keuse" -#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:29 ekos/ekos.h:74 +#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:29 ekos/ekos.h:74 #, fuzzy, kde-format msgid "Calibrating" msgstr "Bereken" -#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:30 +#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:30 #, fuzzy, kde-format msgid "Calibration error" msgstr "Bereken" -#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:31 +#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:31 #, fuzzy, kde-format msgid "Calibrated" msgstr "Bereken" #. i18n("Calibrating"); -#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:32 -#: ekos/scheduler/schedulerjob.cpp:649 +#: ekos/analyze/analyze.cpp:2877 ekos/ekos.h:32 +#: ekos/scheduler/schedulerjob.cpp:625 #, fuzzy, kde-format msgid "Guiding" msgstr "niks" -#: ekos/analyze/analyze.cpp:2877 ekos/auxiliary/ledstatuswidget.cpp:33 +#: ekos/analyze/analyze.cpp:2879 ekos/auxiliary/ledstatuswidget.cpp:33 #: ekos/ekos.h:33 ekos/ekos.h:72 ekos/ekos.h:141 #, fuzzy, kde-format msgid "Suspended" msgstr "niks" -#: ekos/analyze/analyze.cpp:2879 ekos/ekos.h:34 +#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:34 #, fuzzy, kde-format msgid "Reacquiring" msgstr "Stoor Beeld" -#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:35 ekos/ekos.h:73 +#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:35 ekos/ekos.h:73 #, fuzzy, kde-format msgid "Dithering" msgstr "Vertoon naam" #. i18n: ectx: property (windowTitle), widget (QDialog, ManualDither) -#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 +#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 #, fuzzy, kde-format msgid "Manual Dithering" msgstr "Vertoon naam" -#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:37 +#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:37 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" msgid "Dithering error" msgstr "Belize Stad" -#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:38 +#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:38 #, kde-format msgid "Dithering successful" msgstr "" -#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:39 +#: ekos/analyze/analyze.cpp:2891 ekos/ekos.h:39 #, fuzzy, kde-format msgid "Settling" msgstr "niks" @@ -9905,7 +9948,7 @@ #. i18n: ectx: property (text), widget (QLabel, statsLabel) #. i18n: ectx: property (windowTitle), widget (QDialog, solveInfo) #. i18n: ectx: property (windowTitle), widget (QDialog, statForm) -#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:123 +#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:129 #: fitsviewer/fitsviewer.cpp:173 fitsviewer/solveInfo.ui:14 #: fitsviewer/statform.ui:14 #, fuzzy, kde-format @@ -10923,8 +10966,8 @@ #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_21) #. i18n: ectx: property (text), widget (QLabel, label_34) -#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1607 -#: ekos/focus/focus.ui:3100 +#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1626 +#: ekos/focus/focus.ui:3119 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Algeria" @@ -11106,7 +11149,7 @@ #. i18n: ectx: property (text), widget (QPushButton, resetFrameB) #. i18n: ectx: property (text), widget (QPushButton, resetB) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:779 +#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:798 #: ekos/guide/manualpulse.ui:140 ekos/mount/mount.ui:346 #, fuzzy, kde-format #| msgid "Stars" @@ -11154,7 +11197,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_7) #. i18n: ectx: label, entry (MaxDarkTemperatureDiff), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1628 +#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1652 #, kde-format msgid "" "Maximum acceptable difference between current and recorded dark frame " @@ -11182,14 +11225,14 @@ #. i18n: ectx: property (text), widget (QLabel, label_8) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:592 +#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:605 #, kde-format msgid "° C" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label_6) #. i18n: ectx: label, entry (DarkLibraryDuration), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1638 +#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1662 #, kde-format msgid "" "Reuse dark frames from the dark library for this many days. If exceeded, a " @@ -11240,7 +11283,7 @@ msgstr "" #: ekos/auxiliary/filtermanager.cpp:112 -#: ekos/capture/capturecountswidget.cpp:154 +#: ekos/capture/capturecountswidget.cpp:156 #, fuzzy, kde-format msgid "Exposure" msgstr "Ewenaar" @@ -11256,7 +11299,7 @@ msgstr "Bereken" #. i18n: ectx: property (text), widget (QPushButton, startFocusB) -#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:285 +#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:286 #, fuzzy, kde-format #| msgid "Start Clock" msgid "Auto Focus" @@ -11348,7 +11391,7 @@ #. i18n: ectx: property (windowTitle), widget (QDialog, FilterSettings) #. i18n: ectx: property (toolTip), widget (QPushButton, filterManagerB) #: ekos/auxiliary/filtersettings.ui:20 ekos/capture/capture.ui:440 -#: ekos/focus/focus.ui:847 +#: ekos/focus/focus.ui:866 #, fuzzy, kde-format msgid "Filter Settings" msgstr "Stoor Huidige Kleure..." @@ -11414,7 +11457,7 @@ msgstr "Vertoon naam" #: ekos/auxiliary/ledstatuswidget.cpp:46 -#: ekos/capture/capturemodulestate.cpp:336 +#: ekos/capture/capturemodulestate.cpp:330 #, fuzzy, kde-format msgid "Dithering..." msgstr "Vertoon naam" @@ -11434,7 +11477,7 @@ msgid "Aligning..." msgstr "Vertoon naam" -#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1395 +#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1426 #, fuzzy, kde-format msgid "Calibrating..." msgstr "Bereken" @@ -11511,8 +11554,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_SchedulerLogging) #. i18n: ectx: attribute (title), widget (QWidget, schedulerTab) -#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:329 ekos/opsekos.ui:184 -#: ekos/scheduler/framingassistantui.cpp:665 +#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:333 ekos/opsekos.ui:184 +#: ekos/scheduler/framingassistantui.cpp:667 #, fuzzy, kde-format msgid "Scheduler" msgstr "Sidereal tyd" @@ -11549,7 +11592,7 @@ #: ekos/auxiliary/opslogs.ui:133 ekos/capture/capturecountswidget.ui:41 #: ekos/capture/capturepreviewwidget.ui:38 ekos/manager.ui:38 #: ekos/manager/focusmanager.ui:41 ekos/manager/guidemanager.ui:41 -#: kstarsactions.cpp:1141 kstarsinit.cpp:454 +#: kstarsactions.cpp:1150 kstarsinit.cpp:454 #, kde-format msgid "Ekos" msgstr "" @@ -11593,7 +11636,7 @@ msgstr "Bereken" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDILogging) -#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1137 +#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1146 #, kde-format msgid "INDI" msgstr "" @@ -11607,7 +11650,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FITSLogging) #. i18n: ectx: property (text), item, widget (QComboBox, captureEncodingS) #: ekos/auxiliary/opslogs.ui:202 ekos/capture/capture.ui:194 -#: kstarsactions.cpp:1131 +#: kstarsactions.cpp:1140 #, fuzzy, kde-format msgid "FITS" msgstr "Stoor Beeld" @@ -11689,7 +11732,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AlignmentLogging) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_6) -#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:415 +#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:428 #, fuzzy, kde-format msgid "Alignment" msgstr "Vertoon naam" @@ -11703,7 +11746,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObservatoryLogging) #. i18n: ectx: property (windowTitle), widget (QWidget, Observatory) -#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2210 +#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2216 #: ekos/observatory/observatory.ui:14 #, fuzzy, kde-format msgid "Observatory" @@ -11934,16 +11977,19 @@ #: ekos/auxiliary/opticaltrains.ui:149 #, fuzzy, kde-format msgid "" -"

    Select the scope or lens used in the optical train.

    To add, edit, or delete optical elements, tap the Telescope & Lens button.

    " +"

    Select the scope or lens used in the optical train. " +"This is a required selection in all trains.

    To add, edit, or delete " +"optical elements, tap the Telescope & " +"Lens button.

    " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, scopeLabel) #: ekos/auxiliary/opticaltrains.ui:152 #, fuzzy, kde-format -msgid "Scope/Lense:" -msgstr "Koop" +msgid "" +"

    Scope/Lens: *" +msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QLabel, mountLabel) #: ekos/auxiliary/opticaltrains.ui:162 @@ -11964,17 +12010,17 @@ #: ekos/auxiliary/opticaltrains.ui:185 #, fuzzy, kde-format msgid "" -"

    Select the imaging camera for this optical train.

    " +"

    Select the imaging camera for this optical train. " +"This is a required selection in all trains.

    " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, cameraLabel) -#. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/auxiliary/opticaltrains.ui:188 ekos/capture/capture.ui:1478 -#: ekos/scheduler/framingassistant.ui:139 +#: ekos/auxiliary/opticaltrains.ui:188 #, fuzzy, kde-format -msgid "Camera:" -msgstr "Cary" +msgid "" +"

    Camera: *

    " +msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QLabel, dustCapLlabel) #: ekos/auxiliary/opticaltrains.ui:208 @@ -12063,7 +12109,7 @@ #. i18n: ectx: property (text), widget (QLabel, focusLabel) #. i18n: ectx: property (text), widget (QLabel, label_33) #. i18n: ectx: property (text), widget (QLabel, label_10) -#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:298 +#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:434 #: ekos/profileeditor.ui:651 #, kde-format msgid "Focuser:" @@ -12653,7 +12699,7 @@ #. i18n: ectx: property (text), item, widget (QComboBox, convFilter) #. i18n: ectx: property (text), item, widget (QComboBox, focusStarPSF) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1871 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1890 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Russia" @@ -12875,7 +12921,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_9) #: ekos/auxiliary/stellarsolverprofileeditor.ui:726 #: ekos/auxiliary/stellarsolverprofileeditor.ui:798 -#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:874 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:887 #, no-c-format, kde-format msgid "%" msgstr "" @@ -13019,10 +13065,13 @@ msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, multiAlgo) +#. i18n: ectx: property (currentText), widget (QComboBox, abInsSelection) +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) #. i18n: ectx: property (text), widget (QPushButton, NoneButton) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 indi/drivermanager.cpp:1312 -#: indi/indidriver.cpp:735 kstarsactions.cpp:1817 kstarsinit.cpp:788 -#: kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 +#: ekos/focus/aberrationinspector.ui:336 ekos/focus/aberrationinspector.ui:340 +#: indi/drivermanager.cpp:1329 indi/indidriver.cpp:735 kstarsactions.cpp:1826 +#: kstarsinit.cpp:788 kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 #: tools/eyepiecefield.cpp:102 tools/obslistwizard.ui:183 #, fuzzy, kde-format, kde-kuit-format msgid "None" @@ -13170,102 +13219,74 @@ msgstr "Leo" #. i18n: ectx: property (toolTip), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:22 -#, kde-format -msgid "Specify the source the flat field evenly illuminated light source" -msgstr "" - -#. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:25 +#: ekos/capture/calibrationoptions.ui:37 #, fuzzy, kde-format -msgid "Flat Source" -msgstr "Datum" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, manualSourceC) -#: ekos/capture/calibrationoptions.ui:31 -#, kde-format -msgid "Light source triggered by the user manually" -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, manualSourceC) -#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:34 ekos/capture/calibrationoptions.ui:161 -#, fuzzy, kde-format -#| msgctxt "Country name (optional, but should be translated)" -#| msgid "Vanuatu" -msgid "Manual" -msgstr "Vanuatu" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:47 -#, kde-format msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, close the dust cap and turn on the light source." -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:50 -#, kde-format -msgid "Dust Cover with Built-in Flat Light" -msgstr "" +"

    Select which actions to perform before a Bias/Dark/" +"Flat frame is captured.

    " +msgstr "Soek Voorwerp" -#. i18n: ectx: property (toolTip), widget (QRadioButton, darkDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:60 -#, kde-format -msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, open the dust cap and turn on the light source." -msgstr "" +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: ekos/capture/calibrationoptions.ui:40 +#, fuzzy, kde-format +msgid "Calibration Pre-Actions" +msgstr "Leo" -#. i18n: ectx: property (text), widget (QRadioButton, darkDeviceSourceC) +#. i18n: ectx: property (toolTip), widget (QCheckBox, gotoWallC) #: ekos/capture/calibrationoptions.ui:63 #, kde-format -msgid "Dust Cover with External Flat Light" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:75 -#, kde-format msgid "" "Slew mount to the specified Azimuth/Altitude coordinates before taking flat " "field images" msgstr "" -#. i18n: ectx: property (text), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:78 +#. i18n: ectx: property (text), widget (QCheckBox, gotoWallC) +#: ekos/capture/calibrationoptions.ui:66 #, fuzzy, kde-format -msgid "Wall" +msgid "Goto Wall" msgstr "Manlik" -#. i18n: ectx: property (toolTip), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:121 +#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) +#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) +#: ekos/capture/calibrationoptions.ui:103 ekos/scheduler/scheduler.ui:1837 #, fuzzy, kde-format -msgid "Use Dawn and Dusk light" -msgstr "Stoor Beeld" +msgid "Park Mount" +msgstr "Land:" -#. i18n: ectx: property (text), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:124 -#, kde-format -msgid "Dawn/Dusk" -msgstr "" +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) +#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) +#: ekos/capture/calibrationoptions.ui:110 ekos/observatory/observatory.ui:944 +#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 +#, fuzzy, kde-format +msgid "Park Dome" +msgstr "Des:" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/capture/calibrationoptions.ui:150 +#: ekos/capture/calibrationoptions.ui:133 #, fuzzy, kde-format msgid "Flat Duration" msgstr "Dag duur" #. i18n: ectx: property (toolTip), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:158 +#: ekos/capture/calibrationoptions.ui:156 #, kde-format msgid "Use the frame exposure value" msgstr "" +#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) +#: ekos/capture/calibrationoptions.ui:159 +#, fuzzy, kde-format +#| msgctxt "Country name (optional, but should be translated)" +#| msgid "Vanuatu" +msgid "Manual" +msgstr "Vanuatu" + #. i18n: ectx: property (toolTip), widget (QRadioButton, ADUC) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUValue) -#: ekos/capture/calibrationoptions.ui:174 -#: ekos/capture/calibrationoptions.ui:187 +#: ekos/capture/calibrationoptions.ui:172 +#: ekos/capture/calibrationoptions.ui:185 #, kde-format msgid "" "Calculate optimal exposure time given the required ADU. If a controllable " @@ -13273,15 +13294,15 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, ADUC) -#: ekos/capture/calibrationoptions.ui:177 +#: ekos/capture/calibrationoptions.ui:175 #, kde-format msgid "ADU" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label_3) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUTolerance) -#: ekos/capture/calibrationoptions.ui:200 -#: ekos/capture/calibrationoptions.ui:210 +#: ekos/capture/calibrationoptions.ui:198 +#: ekos/capture/calibrationoptions.ui:208 #, kde-format msgid "" "

    Accept ADU values that fall within this range around " @@ -13293,334 +13314,291 @@ #. i18n: ectx: property (text), widget (QLabel, label_3) #. i18n: ectx: property (text), widget (QLabel, focusToleranceLabel) #. i18n: ectx: property (text), widget (QLabel, focusCFZToleranceLabel) -#: ekos/capture/calibrationoptions.ui:203 ekos/focus/focus.ui:2068 -#: ekos/focus/focus.ui:2674 +#: ekos/capture/calibrationoptions.ui:201 ekos/focus/focus.ui:2087 +#: ekos/focus/focus.ui:2693 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "France" msgid "Tolerance:" msgstr "Frankryk" -#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) -#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) -#: ekos/capture/calibrationoptions.ui:246 ekos/scheduler/scheduler.ui:1837 -#, fuzzy, kde-format -msgid "Park Mount" -msgstr "Land:" - -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) -#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) -#: ekos/capture/calibrationoptions.ui:253 ekos/observatory/observatory.ui:944 -#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 -#, fuzzy, kde-format -msgid "Park Dome" -msgstr "Des:" - -#: ekos/capture/capture.cpp:248 ekos/capture/capture.cpp:2935 +#: ekos/capture/capture.cpp:262 ekos/capture/capture.cpp:2311 #, fuzzy, kde-format msgid "Add job to sequence queue" msgstr "Stoor Beeld" -#: ekos/capture/capture.cpp:249 ekos/capture/capture.cpp:2936 +#: ekos/capture/capture.cpp:263 ekos/capture/capture.cpp:2312 #, fuzzy, kde-format msgid "Remove job from sequence queue" msgstr "Stoor Beeld" -#: ekos/capture/capture.cpp:500 +#: ekos/capture/capture.cpp:510 #, fuzzy, kde-format msgid "Downloading..." msgstr "Laaiïng van K-sterre..." -#: ekos/capture/capture.cpp:675 +#: ekos/capture/capture.cpp:689 #, kde-format msgid "" "Warning: in-sequence focusing is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:677 +#: ekos/capture/capture.cpp:691 #, kde-format msgid "" "Warning: temperature delta check is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:1336 +#: ekos/capture/capture.cpp:1367 #, fuzzy, kde-format msgid "Framing..." msgstr "Strand" -#: ekos/capture/capture.cpp:1347 +#: ekos/capture/capture.cpp:1378 #, fuzzy, kde-format msgid "Captured image received" msgstr "Stoor Beeld" #. i18n: ectx: property (text), widget (QLabel, frameInfoLabel) -#: ekos/capture/capture.cpp:1365 ekos/capture/capture.ui:2245 +#: ekos/capture/capture.cpp:1396 ekos/capture/capture.ui:2245 #, fuzzy, kde-format msgid "Expose (-/-):" msgstr "Ewenaar" -#: ekos/capture/capture.cpp:1429 +#: ekos/capture/capture.cpp:1460 #, fuzzy, kde-format msgid "Capturing %1-second %2 image..." msgstr "Laaiïng van K-sterre..." -#: ekos/capture/capture.cpp:1512 -#, kde-format -msgid "You must set remote directory for Local & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1518 -#, kde-format -msgid "You must set local directory for Client & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1653 ekos/capture/capture.cpp:1656 -#, fuzzy, kde-format -msgid "Dark Flat" -msgstr "Maak skoon Velde" - -#: ekos/capture/capture.cpp:1737 +#: ekos/capture/capture.cpp:1638 #, kde-format msgid "Job #%1 changes applied." msgstr "" -#: ekos/capture/capture.cpp:1941 +#: ekos/capture/capture.cpp:1814 #, fuzzy, kde-format msgid "Setting temperature to %1 °C..." msgstr "Koördinate" -#: ekos/capture/capture.cpp:1942 +#: ekos/capture/capture.cpp:1815 #, fuzzy, kde-format msgid "Set Temp to %1 °C..." msgstr "Koördinate" -#: ekos/capture/capture.cpp:1946 +#: ekos/capture/capture.cpp:1819 #, fuzzy, kde-format msgid "Waiting for guide drift below %1\"..." msgstr "Soek Voorwerp" -#: ekos/capture/capture.cpp:1948 +#: ekos/capture/capture.cpp:1821 #, kde-format msgid "Wait for Guider < %1\"..." msgstr "" -#: ekos/capture/capture.cpp:1953 +#: ekos/capture/capture.cpp:1826 #, fuzzy, kde-format msgid "Setting camera to %1 degrees E of N..." msgstr "Koördinate" -#: ekos/capture/capture.cpp:1954 +#: ekos/capture/capture.cpp:1827 #, fuzzy, kde-format msgid "Set Camera to %1 deg..." msgstr "Invoer Keuse" -#: ekos/capture/capture.cpp:1997 ekos/capture/capture.cpp:1998 +#: ekos/capture/capture.cpp:1870 ekos/capture/capture.cpp:1871 #, fuzzy, kde-format msgid "Focus complete." msgstr "Bereken" -#: ekos/capture/capture.cpp:2002 +#: ekos/capture/capture.cpp:1875 #, fuzzy, kde-format msgid "Autofocus failed." msgstr "Bereken" -#: ekos/capture/capture.cpp:2024 +#: ekos/capture/capture.cpp:1897 #, kde-format msgid "Paused..." msgstr "" -#: ekos/capture/capture.cpp:2029 +#: ekos/capture/capture.cpp:1902 #, fuzzy, kde-format msgid "Meridian Flip..." msgstr "Wissel Sterre" -#: ekos/capture/capture.cpp:2030 +#: ekos/capture/capture.cpp:1903 #, fuzzy, kde-format msgid "Meridian flip started" msgstr "Wissel Sterre" -#: ekos/capture/capture.cpp:2034 +#: ekos/capture/capture.cpp:1907 #, fuzzy, kde-format msgid "Flip complete." msgstr "Bereken" -#: ekos/capture/capture.cpp:2059 ekos/scheduler/framingassistant.cpp:221 +#: ekos/capture/capture.cpp:1932 ekos/scheduler/framingassistant.cpp:221 #, fuzzy, kde-format msgctxt "@title:window" msgid "FITS Save Directory" msgstr "Stoor Beeld" -#: ekos/capture/capture.cpp:2069 +#: ekos/capture/capture.cpp:1942 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Sequence Queue" msgstr "Voeg by na Lys" -#: ekos/capture/capture.cpp:2180 -#, kde-format -msgid "" -"Meridian flip configuration has been shifted to the mount module. Please " -"configure the meridian flip there." -msgstr "" - -#: ekos/capture/capture.cpp:2269 -#, fuzzy, kde-format -msgid "Warning: Filter %1 not found in filter wheel." -msgstr "Spanje" - -#: ekos/capture/capture.cpp:2478 +#: ekos/capture/capture.cpp:2007 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save Ekos Sequence Queue" msgstr "Stoor Beeld" -#: ekos/capture/capture.cpp:2499 +#: ekos/capture/capture.cpp:2028 #, kde-format msgid "Failed to save sequence queue" msgstr "" -#: ekos/capture/capture.cpp:2531 -#, fuzzy, kde-format -msgid "Could not open file" -msgstr "Kon nie Open Lêer" - -#: ekos/capture/capture.cpp:2551 -#, kde-format -msgid "" -"Warning: HFR-based autofocus is set but option \"Save Sequence HFR Value to " -"File\" is not enabled. Current HFR value will not be written to sequence " -"file." -msgstr "" - -#: ekos/capture/capture.cpp:2686 -#, fuzzy, kde-format -msgid "Sequence queue saved to %1" -msgstr "Ongeldige Url" - -#: ekos/capture/capture.cpp:2713 +#: ekos/capture/capture.cpp:2071 #, kde-format msgid "Are you sure you want to reset status of all jobs?" msgstr "" -#: ekos/capture/capture.cpp:2713 ekos/capture/captureprocess.cpp:2339 +#: ekos/capture/capture.cpp:2071 ekos/capture/captureprocess.cpp:2638 #, fuzzy, kde-format msgid "Reset job status" msgstr "Bereken" -#: ekos/capture/capture.cpp:2914 +#: ekos/capture/capture.cpp:2290 #, fuzzy, kde-format msgid "Editing job #%1..." msgstr "Voeg by Skakel..." -#: ekos/capture/capture.cpp:2917 ekos/scheduler/scheduler.cpp:1619 +#: ekos/capture/capture.cpp:2293 ekos/scheduler/scheduler.cpp:1414 #, kde-format msgid "Apply job changes." msgstr "" -#: ekos/capture/capture.cpp:2918 +#: ekos/capture/capture.cpp:2294 #, fuzzy, kde-format msgid "Cancel job changes." msgstr "Stooring van die beeld %1 gevaal!" -#: ekos/capture/capture.cpp:2930 +#: ekos/capture/capture.cpp:2306 #, fuzzy, kde-format msgid "Editing job canceled." msgstr "Voeg by Skakel..." -#: ekos/capture/capture.cpp:3083 +#: ekos/capture/capture.cpp:2445 #, fuzzy, kde-format msgid "Wall coordinates are invalid." msgstr "Aarde koördinate" -#: ekos/capture/capture.cpp:3172 +#: ekos/capture/capture.cpp:2529 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Current Observer" msgstr "Cary" -#: ekos/capture/capture.cpp:3174 +#: ekos/capture/capture.cpp:2531 #, fuzzy, kde-format msgid "Current Observer:" msgstr "Cary" #. i18n: ectx: property (windowTitle), widget (QWidget, ObserverAdd) -#: ekos/capture/capture.cpp:3185 oal/execute.cpp:38 oal/observeradd.ui:26 +#: ekos/capture/capture.cpp:2542 oal/execute.cpp:38 oal/observeradd.ui:26 #, fuzzy, kde-format msgid "Manage Observers" msgstr "Cary" -#: ekos/capture/capture.cpp:3250 +#: ekos/capture/capture.cpp:2607 #, fuzzy, kde-format msgid "Filter set to %1." msgstr "Ongeldige Url" -#: ekos/capture/capture.cpp:3572 +#: ekos/capture/capture.cpp:2929 #, kde-format msgid "Reset %1 configuration to default?" msgstr "" -#: ekos/capture/capture.cpp:3574 +#: ekos/capture/capture.cpp:2931 #, fuzzy, kde-format msgid "Confirmation" msgstr "Laaiïng van Informasie Urls" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:2969 ekos/capture/capture.cpp:3044 +#, fuzzy, kde-format +msgid "Dark Flat" +msgstr "Maak skoon Velde" + +#: ekos/capture/capture.cpp:3021 +#, kde-format +msgid "You must set remote directory for Local & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3027 +#, kde-format +msgid "You must set local directory for Client & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is on" msgstr "" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is off" msgstr "" -#: ekos/capture/capture.cpp:3809 +#: ekos/capture/capture.cpp:3172 #, kde-format -msgctxt "Temperature ramp celcius per minute" -msgid "Ramp (C/min):" +msgctxt "Maximum temperature variation over time when regulating." +msgid "Ramp (°C/min):" msgstr "" -#: ekos/capture/capture.cpp:3815 +#: ekos/capture/capture.cpp:3178 #, kde-format msgid "" -"Maximum temperature change per minute when cooling or warming the camera. " -"Set zero to disable." +"

    Maximum temperature change per minute when cooling or warming " +"the camera. Set zero to disable.

    This setting is read from and stored in " +"the INDI camera driver configuration." msgstr "" -#. i18n: ectx: property (text), widget (QLabel, focusThresholdLabel) -#: ekos/capture/capture.cpp:3817 ekos/focus/focus.ui:1895 +#: ekos/capture/capture.cpp:3183 #, fuzzy, kde-format -msgid "Threshold:" +msgctxt "Temperature threshold above which regulation triggers." +msgid "Threshold (°C):" msgstr "Leon" -#: ekos/capture/capture.cpp:3823 +#: ekos/capture/capture.cpp:3189 #, kde-format -msgid "Maximum difference between camera and target temperatures" +msgid "" +"

    Maximum difference between camera and target temperatures " +"triggering regulation.

    This setting is read from and stored in the INDI " +"camera driver configuration." msgstr "" -#: ekos/capture/capture.cpp:3833 +#: ekos/capture/capture.cpp:3202 #, fuzzy, kde-format msgctxt "@title:window" msgid "Set Temperature Regulation" msgstr "Koördinate" -#: ekos/capture/capture.cpp:3851 +#: ekos/capture/capture.cpp:3220 #, fuzzy, kde-format #| msgid "open cluster" msgid "Stop Sequence" msgstr "open klaster" -#: ekos/capture/capture.cpp:3857 +#: ekos/capture/capture.cpp:3226 #, fuzzy, kde-format #| msgid "open cluster" msgid "Resume Sequence" msgstr "open klaster" -#: ekos/capture/capture.cpp:3882 +#: ekos/capture/capture.cpp:3251 #, kde-format msgid "One dark flats job was created." msgid_plural "%1 dark flats jobs were created." @@ -13629,7 +13607,7 @@ #. i18n: ectx: property (title), widget (QGroupBox, CCDFWGroup) #. i18n: ectx: property (title), widget (QGroupBox, ccdGroup) -#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:472 +#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:491 #, fuzzy, kde-format msgid "Camera && Filter Wheel" msgstr "Voeg by Katalogus" @@ -13939,44 +13917,61 @@ "\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-" "block-indent:0; text-indent:0px;\">Placeholder %e or %exposure: The " -"exposure duration in seconds.

  • Placeholder %F or " -"%Filter: The active filter name.
    • Placeholder %E or %exp: The exposure duration in seconds as plain " +"number, without any unit as suffix.
  • Placeholder %F " +"or %Filter: The active filter name." +"
  • Placeholder %t or %target: The Target name.
  • Placeholder %C or %temperature: The camera temperature of capturing." -"
    • Placeholder %B or " +"%bin: The binning configured for " +"capturing.
    • Placeholder %G or %gain: The gain configured for capturing.
    • Placeholder %G or %gain: The gain configured for capturing.
    • %O or %offset: The offset configured for capturing.
      • Placeholder %I or %iso: The ISO value (DSLRs only).
    • Placeholder %O " -"or %offset: The offset configured " -"for capturing.
    • Placeholder %P " +"or %pierside: The current mount's " +"pier side.
    • Placeholder %P or %pierside: The current mount's pier side.
    • Placeholder %s* or " -"%sequence: The image sequence identifier where * is the number of " -"digits used (1-9). This tag is mandatory " -"and must be the last element in the format.

    Arbitrary " -"text may also be included within the Format string, except the % and \\ characters. The / path character " -"can be used to define arbitrary directories.

    Notes:

    • Tags are " -"case sensitive in both their short and long forms.
    • Only use the %Datetime tag in the filename " -"portion of the format, not in the path definition.
    " +"\">Placeholder %s* or %sequence: The image sequence identifier where " +"* is the number of digits used (1-9). This " +"tag is mandatory and must be the last element in the format.
  • Arbitrary text may also be included within the Format string, except the % and \\ characters. The / " +"path character can be used to define arbitrary directories.

    Notes:

    • Tags are case sensitive in both their short and long forms.
    • Only use the %Datetime tag " +"in the filename portion of the format, not in the path definition.
    • " msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, remoteLabel) @@ -14017,7 +14012,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, textLabel1_2_5) #. i18n: ectx: property (toolTip), widget (QLabel, FilterPosLabel) #: ekos/capture/capture.ui:1185 ekos/capture/limits.ui:60 -#: ekos/capture/limits.ui:201 ekos/focus/focus.ui:552 +#: ekos/capture/limits.ui:201 ekos/focus/focus.ui:571 #, kde-format msgid "Number of images to capture" msgstr "" @@ -14103,6 +14098,12 @@ msgid "Cooler:" msgstr "" +#. i18n: ectx: property (text), widget (QLabel, label_8) +#: ekos/capture/capture.ui:1478 ekos/scheduler/framingassistant.ui:139 +#, fuzzy, kde-format +msgid "Camera:" +msgstr "Cary" + #. i18n: ectx: property (title), widget (QGroupBox, sequenceBox) #: ekos/capture/capture.ui:1515 #, kde-format @@ -14191,7 +14192,7 @@ msgstr "Spanje" #. i18n: ectx: property (toolTip), widget (QPushButton, liveVideoB) -#: ekos/capture/capture.ui:2009 ekos/focus/focus.ui:745 +#: ekos/capture/capture.ui:2009 ekos/focus/focus.ui:764 #, fuzzy, kde-format msgid "Live Video" msgstr "Planeet" @@ -14315,14 +14316,14 @@ #. i18n: ectx: property (text), widget (QLabel, startGuiderDriftLabel) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZSeeing) #: ekos/capture/capture.ui:2380 ekos/capture/limits.ui:66 -#: ekos/capture/limits.ui:102 ekos/focus/focus.ui:3040 +#: ekos/capture/limits.ui:102 ekos/focus/focus.ui:3059 #, kde-format msgid "\"" msgstr "" #. i18n: ectx: property (text), widget (QLabel, gr_sequenceLabel) #. i18n: ectx: property (text), widget (QLabel, sequenceLabel) -#: ekos/capture/capturecountswidget.cpp:99 +#: ekos/capture/capturecountswidget.cpp:101 #: ekos/capture/capturecountswidget.ui:124 #: ekos/capture/capturecountswidget.ui:397 #, fuzzy, kde-format @@ -14331,7 +14332,7 @@ msgstr "open klaster" #. i18n: ectx: property (text), widget (QLabel, gr_overallLabel) -#: ekos/capture/capturecountswidget.cpp:102 +#: ekos/capture/capturecountswidget.cpp:104 #: ekos/capture/capturecountswidget.ui:140 #, kde-format msgid "Overall" @@ -14433,187 +14434,187 @@ msgid "Switch display to the graphical mode of capture counts display." msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:565 +#: ekos/capture/capturedeviceadaptor.cpp:648 #, kde-format msgid "Remove cover from the telescope in order to continue." msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:566 +#: ekos/capture/capturedeviceadaptor.cpp:649 #, fuzzy, kde-format msgid "Telescope Covered" msgstr "Aarde koördinate" -#: ekos/capture/capturedeviceadaptor.cpp:698 +#: ekos/capture/capturedeviceadaptor.cpp:781 #, kde-format msgid "Does %1 have a shutter?" msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:699 -#: ekos/capture/sequencejobstate.cpp:414 +#: ekos/capture/capturedeviceadaptor.cpp:782 +#: ekos/capture/sequencejobstate.cpp:403 #, fuzzy, kde-format msgid "Dark Exposure" msgstr "Ewenaar" -#: ekos/capture/capturemodulestate.cpp:130 +#: ekos/capture/capturemodulestate.cpp:132 #, kde-format msgid "" "Warning: Guide deviation is selected but autoguide process was not started." msgstr "" -#: ekos/capture/capturemodulestate.cpp:195 +#: ekos/capture/capturemodulestate.cpp:198 #, fuzzy, kde-format msgid "Dithering succeeded." msgstr "Vertoon naam" #. i18np since guidingRate is DOUBLE value (e.g. 1.36) so we always use plural with that. -#: ekos/capture/capturemodulestate.cpp:202 +#: ekos/capture/capturemodulestate.cpp:205 #, fuzzy, kde-format msgid "Dither complete. Resuming in %1 seconds..." msgstr "Soek Voorwerp" -#: ekos/capture/capturemodulestate.cpp:210 +#: ekos/capture/capturemodulestate.cpp:213 #, fuzzy, kde-format msgid "Dither complete." msgstr "Bereken" #. i18np since guidingRate is DOUBLE value (e.g. 1.36) so we always use plural with that. -#: ekos/capture/capturemodulestate.cpp:224 +#: ekos/capture/capturemodulestate.cpp:227 #, fuzzy, kde-format msgid "Warning: Dithering failed. Resuming in %1 seconds..." msgstr "Soek Voorwerp" -#: ekos/capture/capturemodulestate.cpp:233 +#: ekos/capture/capturemodulestate.cpp:236 #, fuzzy, kde-format msgid "Warning: Dithering failed." msgstr "Vertoon naam" -#: ekos/capture/capturemodulestate.cpp:431 +#: ekos/capture/capturemodulestate.cpp:425 #, kde-format msgid "Meridian flip is successfully completed" msgstr "" -#: ekos/capture/capturemodulestate.cpp:527 +#: ekos/capture/capturemodulestate.cpp:521 #, kde-format msgid "Performing post flip re-calibration and guiding..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:540 +#: ekos/capture/capturemodulestate.cpp:534 #, kde-format msgid "Post meridian flip calibration error. Restarting..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:560 +#: ekos/capture/capturemodulestate.cpp:554 #, fuzzy, kde-format msgid "Autoguiding stopped. Waiting for autofocus to finish..." msgstr "Soek Voorwerp" -#: ekos/capture/capturemodulestate.cpp:569 +#: ekos/capture/capturemodulestate.cpp:563 #, fuzzy, kde-format msgid "Autoguiding stopped. Aborting..." msgstr "Soek Voorwerp" -#: ekos/capture/capturemodulestate.cpp:576 +#: ekos/capture/capturemodulestate.cpp:570 #, kde-format msgid "Post meridian flip calibration error. Aborting..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:596 +#: ekos/capture/capturemodulestate.cpp:592 #, fuzzy, kde-format msgid "Adaptive focus complete." msgstr "Bereken" -#: ekos/capture/capturemodulestate.cpp:620 +#: ekos/capture/capturemodulestate.cpp:616 #, kde-format msgid "Autofocus failed. Aborting exposure..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:767 +#: ekos/capture/capturemodulestate.cpp:763 #, kde-format msgid "Performing post flip re-alignment..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:785 +#: ekos/capture/capturemodulestate.cpp:781 #, fuzzy, kde-format msgid "Guide module timed out." msgstr "Soek Voorwerp" -#: ekos/capture/capturemodulestate.cpp:817 +#: ekos/capture/capturemodulestate.cpp:813 #, kde-format msgid "Initial guiding deviation %1 below limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:826 +#: ekos/capture/capturemodulestate.cpp:822 #, kde-format msgid "Initial guiding deviation %1 exceeded limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:848 +#: ekos/capture/capturemodulestate.cpp:844 #, kde-format msgid "Post meridian flip calibration completed successfully." msgstr "" -#: ekos/capture/capturemodulestate.cpp:862 +#: ekos/capture/capturemodulestate.cpp:858 #, kde-format msgid "Guiding deviation at capture startup %1 exceeded limit %2 arcsecs." msgstr "" -#: ekos/capture/capturemodulestate.cpp:876 +#: ekos/capture/capturemodulestate.cpp:872 #, kde-format msgid "Guiding deviation at capture startup %1 below limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:903 +#: ekos/capture/capturemodulestate.cpp:899 #, kde-format msgid "" "Guiding deviation %1 exceeded limit value of %2 arcsecs for %4 consecutive " "samples, suspending exposure and waiting for guider up to %3 seconds." msgstr "" -#: ekos/capture/capturemodulestate.cpp:950 +#: ekos/capture/capturemodulestate.cpp:946 #, kde-format msgid "" "Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming " "exposure." msgstr "" -#: ekos/capture/capturemodulestate.cpp:954 +#: ekos/capture/capturemodulestate.cpp:950 #, kde-format msgid "" "Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming " "exposure in %3 seconds." msgstr "" -#: ekos/capture/capturemodulestate.cpp:969 +#: ekos/capture/capturemodulestate.cpp:965 #, kde-format msgid "Guiding deviation %1 is still higher than limit value of %2 arcsecs." msgstr "" -#: ekos/capture/capturemodulestate.cpp:1350 +#: ekos/capture/capturemodulestate.cpp:1340 #, kde-format msgid "Post flip re-alignment completed successfully." msgstr "" -#: ekos/capture/capturemodulestate.cpp:1369 +#: ekos/capture/capturemodulestate.cpp:1359 #, kde-format msgid "Post-flip alignment failed." msgstr "" -#: ekos/capture/capturemodulestate.cpp:1374 +#: ekos/capture/capturemodulestate.cpp:1364 #, fuzzy, kde-format msgid "Post-flip alignment failed. Retrying..." msgstr "Planeet" -#: ekos/capture/capturepreviewwidget.cpp:138 +#: ekos/capture/capturepreviewwidget.cpp:142 #, kde-format msgid "Delete directly, do not move to trash." msgstr "" -#: ekos/capture/capturepreviewwidget.cpp:195 +#: ekos/capture/capturepreviewwidget.cpp:199 #, kde-format msgid "Do you really want to delete %1 from the file system?" msgstr "" -#: ekos/capture/capturepreviewwidget.cpp:197 +#: ekos/capture/capturepreviewwidget.cpp:201 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Delta" @@ -14621,7 +14622,7 @@ msgstr "Delta" #. i18n: ectx: property (text), widget (QPushButton, delButton) -#: ekos/capture/capturepreviewwidget.cpp:197 +#: ekos/capture/capturepreviewwidget.cpp:201 #: kstarslite/qml/dialogs/menus/DetailsLinkMenu.qml:54 #: kstarslite/qml/dialogs/menus/LocationsGeoMenu.qml:82 #: tools/flagmanager.ui:223 @@ -14637,265 +14638,290 @@ msgid "Target: " msgstr "Leon" -#: ekos/capture/captureprocess.cpp:171 ekos/capture/captureprocess.cpp:564 +#: ekos/capture/captureprocess.cpp:192 ekos/capture/captureprocess.cpp:585 #, fuzzy, kde-format msgid "Image Transfer" msgstr "Invoer Keuse" -#: ekos/capture/captureprocess.cpp:190 +#: ekos/capture/captureprocess.cpp:211 #, fuzzy, kde-format msgid "Sequence resumed." msgstr "Soek Voorwerp" -#: ekos/capture/captureprocess.cpp:226 +#: ekos/capture/captureprocess.cpp:247 #, kde-format msgid "No pending jobs found. Please add a job to the sequence queue." msgstr "" -#: ekos/capture/captureprocess.cpp:240 +#: ekos/capture/captureprocess.cpp:261 #, fuzzy, kde-format msgid "No new job created." msgstr "Bereken" -#: ekos/capture/captureprocess.cpp:263 ekos/capture/captureprocess.cpp:798 +#: ekos/capture/captureprocess.cpp:284 ekos/capture/captureprocess.cpp:823 #, kde-format msgid "Cannot capture while focus module is busy." msgstr "" -#: ekos/capture/captureprocess.cpp:270 +#: ekos/capture/captureprocess.cpp:291 #, fuzzy, kde-format msgid "Starting framing..." msgstr "Spanje" -#: ekos/capture/captureprocess.cpp:300 +#: ekos/capture/captureprocess.cpp:321 #, fuzzy, kde-format #| msgid "Horizon" msgid "CCD capture suspended" msgstr "Horison" -#: ekos/capture/captureprocess.cpp:305 +#: ekos/capture/captureprocess.cpp:326 #, fuzzy, kde-format msgid "CCD capture complete" msgstr "Stoor Beeld" -#: ekos/capture/captureprocess.cpp:310 +#: ekos/capture/captureprocess.cpp:331 #, fuzzy, kde-format msgid "CCD capture aborted" msgstr "Stoor Beeld" -#: ekos/capture/captureprocess.cpp:315 +#: ekos/capture/captureprocess.cpp:336 #, fuzzy, kde-format msgid "CCD capture stopped" msgstr "Stoor Beeld" -#: ekos/capture/captureprocess.cpp:389 +#: ekos/capture/captureprocess.cpp:410 #, kde-format msgid "Pausing only possible while frame capture is running." msgstr "" -#: ekos/capture/captureprocess.cpp:396 +#: ekos/capture/captureprocess.cpp:417 #, kde-format msgid "Sequence shall be paused after current exposure is complete." msgstr "" -#: ekos/capture/captureprocess.cpp:427 +#: ekos/capture/captureprocess.cpp:448 #, kde-format msgid "No view available for previews. Enable FITS viewer?" msgstr "" -#: ekos/capture/captureprocess.cpp:428 +#: ekos/capture/captureprocess.cpp:449 #, fuzzy, kde-format msgid "Display preview" msgstr "Wissel Sterre" -#: ekos/capture/captureprocess.cpp:512 +#: ekos/capture/captureprocess.cpp:533 #, kde-format msgid "" "Job requires %1-second %2 images, has already %3/%4 captures and does not " "need to run." msgstr "" -#: ekos/capture/captureprocess.cpp:525 +#: ekos/capture/captureprocess.cpp:546 #, kde-format msgid "" "Job requires %1-second %2 images, has %3/%4 frames captured and will be " "processed." msgstr "" -#: ekos/capture/captureprocess.cpp:744 +#: ekos/capture/captureprocess.cpp:769 #, fuzzy, kde-format msgid "Autoguiding resumed." msgstr "Soek Voorwerp" -#: ekos/capture/captureprocess.cpp:788 +#: ekos/capture/captureprocess.cpp:813 #, fuzzy, kde-format msgid "Failed to set sub frame." msgstr "Kon nie Open Lêer" -#: ekos/capture/captureprocess.cpp:793 +#: ekos/capture/captureprocess.cpp:818 #, kde-format msgid "Failed to set binning." msgstr "" -#: ekos/capture/captureprocess.cpp:1044 +#: ekos/capture/captureprocess.cpp:1069 #, fuzzy, kde-format msgid "Remote image saved to %1" msgstr "Ongeldige Url" -#: ekos/capture/captureprocess.cpp:1143 +#: ekos/capture/captureprocess.cpp:1168 #, fuzzy, kde-format msgid "Autoguiding suspended." msgstr "Soek Voorwerp" -#: ekos/capture/captureprocess.cpp:1172 +#: ekos/capture/captureprocess.cpp:1197 #, kde-format msgid "Warning: Calibration process was prematurely terminated." msgstr "" #. i18n("CCD capture sequence completed")); -#: ekos/capture/captureprocess.cpp:1238 +#: ekos/capture/captureprocess.cpp:1263 #, fuzzy, kde-format #| msgid "Horizon" msgid "CCD capture sequence completed" msgstr "Horison" -#: ekos/capture/captureprocess.cpp:1295 +#: ekos/capture/captureprocess.cpp:1320 #, fuzzy, kde-format msgid "Error: Lost connection to CCD." msgstr "Bereken" -#: ekos/capture/captureprocess.cpp:1324 +#: ekos/capture/captureprocess.cpp:1349 #, kde-format msgid "Cannot calculate ADU levels in non-FITS images." msgstr "" -#: ekos/capture/captureprocess.cpp:1436 ekos/capture/captureprocess.cpp:1931 +#: ekos/capture/captureprocess.cpp:1462 ekos/capture/captureprocess.cpp:1957 #, kde-format msgid "Capture failed. Check INDI Control Panel for details." msgstr "" -#: ekos/capture/captureprocess.cpp:1537 +#: ekos/capture/captureprocess.cpp:1563 #, kde-format msgid "Download Time: %1 s, New Download Time Estimate: %2 s." msgstr "" -#: ekos/capture/captureprocess.cpp:1585 +#: ekos/capture/captureprocess.cpp:1611 #, kde-format msgid "Received image %1 out of %2." msgstr "" -#: ekos/capture/captureprocess.cpp:1618 +#: ekos/capture/captureprocess.cpp:1644 #, fuzzy, kde-format msgid "Captured %1" msgstr "Stoor Beeld" -#: ekos/capture/captureprocess.cpp:1623 +#: ekos/capture/captureprocess.cpp:1649 #, kde-format msgid "WARNING: remaining and potentially unknown placeholders %1 in %2" msgstr "" -#: ekos/capture/captureprocess.cpp:1655 +#: ekos/capture/captureprocess.cpp:1681 #, fuzzy, kde-format msgid "Executing capture script %1" msgstr "Sonsondergang:" -#: ekos/capture/captureprocess.cpp:1670 +#: ekos/capture/captureprocess.cpp:1696 #, kde-format msgid "Pre capture script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1678 +#: ekos/capture/captureprocess.cpp:1704 #, kde-format msgid "Post capture script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1690 +#: ekos/capture/captureprocess.cpp:1716 #, fuzzy, kde-format msgid "Processing meridian flip..." msgstr "Wissel Sterre" -#: ekos/capture/captureprocess.cpp:1700 +#: ekos/capture/captureprocess.cpp:1726 #, kde-format msgid "Pre job script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1705 +#: ekos/capture/captureprocess.cpp:1731 #, kde-format msgid "Post job script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1878 ekos/focus/focus.cpp:4861 +#: ekos/capture/captureprocess.cpp:1904 ekos/focus/focus.cpp:5102 #, fuzzy, kde-format msgid "Exposure timeout. Aborting..." msgstr "Stoor Beeld" -#: ekos/capture/captureprocess.cpp:1901 ekos/focus/focus.cpp:4866 -#: ekos/guide/guide.cpp:892 +#: ekos/capture/captureprocess.cpp:1927 ekos/focus/focus.cpp:5107 +#: ekos/guide/guide.cpp:911 #, kde-format msgid "Exposure timeout. Restarting exposure..." msgstr "" -#: ekos/capture/captureprocess.cpp:1990 +#: ekos/capture/captureprocess.cpp:2016 #, kde-format msgid "" "Flat calibration failed. Captured image is only %1-bit while requested ADU " "is %2." msgstr "" -#: ekos/capture/captureprocess.cpp:2001 +#: ekos/capture/captureprocess.cpp:2027 #, kde-format msgid "Current image is saturated (%1). Next exposure is %2 seconds." msgstr "" -#: ekos/capture/captureprocess.cpp:2023 +#: ekos/capture/captureprocess.cpp:2049 #, kde-format msgid "Current ADU %1 within target ADU tolerance range." msgstr "" -#: ekos/capture/captureprocess.cpp:2056 +#: ekos/capture/captureprocess.cpp:2082 #, kde-format msgid "" "Unable to calculate optimal exposure settings, please capture the flats " "manually." msgstr "" -#: ekos/capture/captureprocess.cpp:2064 +#: ekos/capture/captureprocess.cpp:2090 #, kde-format msgid "Current ADU is %1 Next exposure is %2 seconds." msgstr "" -#: ekos/capture/captureprocess.cpp:2285 +#: ekos/capture/captureprocess.cpp:2361 +#, kde-format +msgid "" +"Meridian flip configuration has been shifted to the mount module. Please " +"configure the meridian flip there." +msgstr "" + +#: ekos/capture/captureprocess.cpp:2393 +#, fuzzy, kde-format +msgid "Could not open file" +msgstr "Kon nie Open Lêer" + +#: ekos/capture/captureprocess.cpp:2413 +#, kde-format +msgid "" +"Warning: HFR-based autofocus is set but option \"Save Sequence HFR Value to " +"File\" is not enabled. Current HFR value will not be written to sequence " +"file." +msgstr "" + +#: ekos/capture/captureprocess.cpp:2536 +#, fuzzy, kde-format +msgid "Sequence queue saved to %1" +msgstr "Ongeldige Url" + +#: ekos/capture/captureprocess.cpp:2584 #, fuzzy, kde-format #| msgid "open cluster" msgid "Sequence paused." msgstr "open klaster" -#: ekos/capture/captureprocess.cpp:2338 +#: ekos/capture/captureprocess.cpp:2637 #, kde-format msgid "" "All jobs are complete. Do you want to reset the status of all jobs and " "restart capturing?" msgstr "" -#: ekos/capture/captureprocess.cpp:2352 +#: ekos/capture/captureprocess.cpp:2651 #, kde-format msgid "" "Warning: option \"Always Reset Sequence When Starting\" is enabled and " "resets the sequence counts." msgstr "" -#: ekos/capture/captureprocess.cpp:2467 +#: ekos/capture/captureprocess.cpp:2766 #, kde-format msgid "Are you sure you want to restart %1 camera driver?" msgstr "" -#: ekos/capture/captureprocess.cpp:2468 +#: ekos/capture/captureprocess.cpp:2767 #, fuzzy, kde-format #| msgid "star" msgid "Driver Restart" msgstr "ster" -#: ekos/capture/captureprocessoverlay.cpp:107 +#: ekos/capture/captureprocessoverlay.cpp:106 #, fuzzy, kde-format msgid "No target" msgstr "Leon" @@ -15064,55 +15090,64 @@ msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, ExposureCalculatorDialog) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:26 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:32 #, fuzzy, kde-format msgid "Sub-Exposure Calculator" msgstr "Tyd sakrekenaar" -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, noiseTolerance) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:56 -#, kde-format -msgid "Adjust the balance of the two noise sources" -msgstr "" - -#. i18n: ectx: property (text), widget (QLabel, allowableNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:69 -#, no-c-format, kde-format -msgid "Noise Increase (%)" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotSubExposure) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:85 -#, fuzzy, kde-format -msgid "Potential exposure time graph" -msgstr "Aangaande die Maan Beelde" - #. i18n: ectx: property (text), widget (QLabel, SQMLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:108 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:62 #, fuzzy, kde-format msgid "Sky Quality" msgstr "Oos Punt" -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, userSkyQuality) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:127 -#, kde-format -msgid "Adjust the quality of the sky" -msgstr "" +#. i18n: ectx: property (text), widget (QLabel, indiFocalRationLabel) +#. i18n: ectx: property (toolTip), widget (QLabel, l_FbyD) +#. i18n: ectx: property (text), widget (QLabel, label51_2) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:75 +#: ekos/guide/guide.ui:684 oal/equipmentwriter.ui:611 +#, fuzzy, kde-format +msgid "Focal Ratio" +msgstr "Ster Naam" #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:143 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:88 #, fuzzy, kde-format -msgid "Filter Bandwidth:" +msgid "Filter Bandwidth" msgstr "Voeg by Katalogus" -#. i18n: ectx: property (text), widget (QLabel, gainSliderLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:171 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, noiseTolerance) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:107 +#, kde-format +msgid "Alter the bias of the noise sources" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, bortleScaleLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:140 +#, fuzzy, kde-format +msgid "Bortle Class" +msgstr "Planete" + +#. i18n: ectx: property (text), widget (QLabel, gainSpinnerLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:185 #, kde-format msgid "Gain" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, label_2) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:220 +#. i18n: ectx: property (toolTip), widget (QSpinBox, gainSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:210 +#, fuzzy, kde-format +msgid "Select Camera Sensor Gain" +msgstr "Noorweë" + +#. i18n: ectx: property (toolTip), widget (QComboBox, gainISODiscreteSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:229 +#, fuzzy, kde-format +msgid "Select DSLR ISO Value" +msgstr "Laaiïng van K-sterre..." + +#. i18n: ectx: property (text), widget (QLabel, gainISOSelectorLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:248 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "USA" @@ -15120,108 +15155,179 @@ msgstr "Vsa" #. i18n: ectx: property (text), widget (QLabel, gainSelectionFixedLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:249 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:267 #, kde-format msgid "Read noise constant" msgstr "" -#. i18n: ectx: property (toolTip), widget (QWidget, skyQualityColor) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:266 +#. i18n: ectx: property (toolTip), widget (QLabel, subShotNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:321 #, kde-format -msgid "Bortle Zone Color" +msgid "Noise in the sub-exposure from light pollution" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, indiFocalRationLabel) -#. i18n: ectx: property (toolTip), widget (QLabel, l_FbyD) -#. i18n: ectx: property (text), widget (QLabel, label51_2) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:289 -#: ekos/guide/guide.ui:684 oal/equipmentwriter.ui:611 +#. i18n: ectx: property (text), widget (QLabel, subTotalNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:337 #, fuzzy, kde-format -msgid "Focal Ratio" -msgstr "Ster Naam" +msgid "Total Noise" +msgstr "Sidereal Tyd" -#. i18n: ectx: property (text), widget (QLabel, bortleScaleLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:325 +#. i18n: ectx: property (text), widget (QLabel, subPollutionLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:344 #, fuzzy, kde-format -msgid "Bortle Class:" -msgstr "Planete" +msgid "Pollution Electrons" +msgstr "Stoor Huidige Kleure..." -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, filterBandwidth) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:338 +#. i18n: ectx: property (toolTip), widget (QLabel, subTotalNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:363 #, kde-format -msgid "Apply a compensation for an optical filter" +msgid "Total noise in the sub-exposure (light pollution + read-noise)" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, subShotNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:379 +#, fuzzy, kde-format +msgid "Shot Noise" +msgstr "Punt Hoop" + +#. i18n: ectx: property (toolTip), widget (QLabel, subPollutionElectrons) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:398 +#, kde-format +msgid "Estimated light pollution electrons in the sub-exposure." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, subExposureTime) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:452 +#, kde-format +msgid "Duration of Sub-exposure" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, subTimeLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:468 +#, fuzzy, kde-format +msgid "Exposure Time (sec)" +msgstr "Aangaande die Maan Beelde" + +#. i18n: ectx: property (toolTip), widget (QPushButton, downloadCameraB) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:508 +#, fuzzy, kde-format +msgid "Download additional camera data files" +msgstr "Laaiïng van K-sterre..." + +#. i18n: ectx: property (toolTip), widget (QWidget, skyQualityColor) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:539 +#, kde-format +msgid "Bortle Zone Color" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, bortleScaleValue) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:354 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:558 #, kde-format msgid "Bortle class value" msgstr "" #. i18n: ectx: property (text), widget (QLabel, bortleScaleValue) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:357 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:561 #, kde-format msgid "9" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, cameraReadModeSelector) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:373 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:584 #, kde-format msgid "Select read mode on cameras with multiple read modes." msgstr "" +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, userSkyQuality) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:603 +#, kde-format +msgid "Adjust the quality of the sky" +msgstr "" + #. i18n: ectx: property (text), widget (QLabel, indiCameraReadMode) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:386 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:613 #, fuzzy, kde-format msgid "Read Mode" msgstr "Cary" -#. i18n: ectx: property (text), widget (QLabel, subTimeLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:426 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, filterBandwidth) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:638 +#, kde-format +msgid "Apply a compensation for an optical filter" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QComboBox, imagingCameraSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:661 #, fuzzy, kde-format -msgid "Exposure Time (sec)" +msgid "Camera Data Selection" +msgstr "Laaiïng van K-sterre..." + +#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotSubExposure) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:696 +#, fuzzy, kde-format +msgid "Potential exposure time graph" msgstr "Aangaande die Maan Beelde" -#. i18n: ectx: property (text), widget (QLabel, subShotNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:446 +#. i18n: ectx: property (text), widget (QLabel, allowableNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:715 +#, no-c-format, kde-format +msgid "Noise Increase %" +msgstr "" + +#. i18n: ectx: attribute (title), widget (QWidget, tab) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:735 #, fuzzy, kde-format -msgid "Shot Noise" -msgstr "Punt Hoop" +#| msgctxt "Show Detailed Information Dialog" +#| msgid "Details" +msgid "Table" +msgstr "Details" -#. i18n: ectx: property (toolTip), widget (QLabel, subShotNoise) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:453 +#. i18n: ectx: attribute (title), widget (QWidget, tab_2) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:752 +#, fuzzy, kde-format +msgid "Graph" +msgstr "Lang.:" + +#. i18n: ectx: property (toolTip), widget (QLabel, exposureCountDifferential) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:770 #, kde-format -msgid "Noise in the sub-exposure from light pollution" +msgid "Slope of time to noise ratio curve at current exposure count" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, subPollutionLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:469 +#. i18n: ectx: property (text), widget (QLabel, exposureCountLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:792 #, fuzzy, kde-format -msgid "Pollution Electrons" -msgstr "Stoor Huidige Kleure..." +msgid "Exposures" +msgstr "Ewenaar" -#. i18n: ectx: property (toolTip), widget (QLabel, subPollutionElectrons) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:476 +#. i18n: ectx: property (toolTip), widget (QLabel, exposureCount) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:811 #, kde-format -msgid "Calculated count of light pollution electrons in the sub-exposure." +msgid "Calculated exposure count for integration" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, subTotalNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:492 +#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotIntegrationNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:833 #, fuzzy, kde-format -msgid "Total Noise" -msgstr "Sidereal Tyd" +msgid "Integration Time to Noise Ratio" +msgstr "Bereken" -#. i18n: ectx: property (toolTip), widget (QLabel, subTotalNoise) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:499 +#. i18n: ectx: property (text), widget (QLabel, targetNoiseLable) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:865 +#, fuzzy, kde-format +msgid "Time/Noise Ratio" +msgstr "Beeld" + +#. i18n: ectx: property (text), widget (QLabel, exposureDiffLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:884 #, kde-format -msgid "Total noise in the sub-exposure (light pollution + read-noise)" +msgid "dy =" msgstr "" -#. i18n: ectx: property (toolTip), widget (QPushButton, downloadCameraB) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:528 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, targetNoiseRatio) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:897 #, kde-format -msgid "(Future Release) Download additional camera data files" +msgid "Integration time to noise ratio (potential quality)" msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, FileUtilityCameraDataDialog) @@ -15231,7 +15337,7 @@ msgstr "Laaiïng van K-sterre..." #. i18n: ectx: property (text), widget (QLabel, resultLable) -#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:73 +#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:101 #, fuzzy, kde-format msgid "Select all cameras you wish to use:" msgstr "Invoer Keuse" @@ -15378,7 +15484,7 @@ "Ekos will refocus as soon as possible, last procedure was %1 seconds ago." msgstr "" -#: ekos/capture/rotatorsettings.cpp:117 +#: ekos/capture/rotatorsettings.cpp:123 #, fuzzy, kde-format msgid "Initial rotator angle %1° is read in successfully." msgstr "Aarde koördinate" @@ -15616,98 +15722,102 @@ msgid "Post-Job Script:" msgstr "Des:" -#: ekos/capture/sequencejob.cpp:21 ekos/ekos.h:71 ekos/ekos.h:119 +#: ekos/capture/sequencejob.cpp:23 ekos/ekos.h:71 ekos/ekos.h:119 #: ekos/ekos.h:139 #, kde-format msgid "In Progress" msgstr "" -#: ekos/capture/sequencejob.cpp:22 ekos/ekos.h:75 ekos/ekos.h:118 -#: ekos/ekos.h:138 ekos/scheduler/schedulerjob.cpp:618 +#: ekos/capture/sequencejob.cpp:24 ekos/ekos.h:75 ekos/ekos.h:118 +#: ekos/ekos.h:138 ekos/scheduler/schedulerjob.cpp:594 #, fuzzy, kde-format msgid "Complete" msgstr "Bereken" -#: ekos/capture/sequencejobstate.cpp:401 +#: ekos/capture/sequencejobstate.cpp:390 #, kde-format msgid "Cover the telescope with an evenly illuminated light source." msgstr "" -#: ekos/capture/sequencejobstate.cpp:402 +#: ekos/capture/sequencejobstate.cpp:391 #, fuzzy, kde-format msgid "Flat Frame" msgstr "Ster Naam" -#: ekos/capture/sequencejobstate.cpp:413 +#: ekos/capture/sequencejobstate.cpp:402 #, kde-format msgid "Cover the telescope in order to take a dark exposure." msgstr "" -#: ekos/capture/sequencejobstate.cpp:441 ekos/capture/sequencejobstate.cpp:478 +#: ekos/capture/sequencejobstate.cpp:432 ekos/capture/sequencejobstate.cpp:606 +#, fuzzy, kde-format +msgid "Unparking dust cap..." +msgstr "Planeet" + +#: ekos/capture/sequencejobstate.cpp:432 #, fuzzy, kde-format msgid "Parking dust cap..." msgstr "Planeet" -#: ekos/capture/sequencejobstate.cpp:450 ekos/capture/sequencejobstate.cpp:489 -#: ekos/capture/sequencejobstate.cpp:535 +#: ekos/capture/sequencejobstate.cpp:444 ekos/capture/sequencejobstate.cpp:491 #, kde-format msgid "Turn light box light on..." msgstr "" -#: ekos/capture/sequencejobstate.cpp:478 ekos/capture/sequencejobstate.cpp:677 -#, fuzzy, kde-format -msgid "Unparking dust cap..." -msgstr "Planeet" - -#: ekos/capture/sequencejobstate.cpp:489 ekos/capture/sequencejobstate.cpp:535 -#: ekos/capture/sequencejobstate.cpp:662 +#: ekos/capture/sequencejobstate.cpp:444 ekos/capture/sequencejobstate.cpp:491 +#: ekos/capture/sequencejobstate.cpp:592 #, kde-format msgid "Turn light box light off..." msgstr "" -#: ekos/capture/sequencejobstate.cpp:507 +#: ekos/capture/sequencejobstate.cpp:462 #, kde-format -msgid "Mount slewing to wall position..." +msgid "Mount slewing to wall position (az =%1 alt =%2)" msgstr "" -#: ekos/capture/sequencejobstate.cpp:518 ekos/capture/sequencejobstate.cpp:522 +#: ekos/capture/sequencejobstate.cpp:474 #, fuzzy, kde-format msgid "Slew to wall position complete, stop tracking." msgstr "Bereken" -#: ekos/capture/sequencejobstate.cpp:550 +#: ekos/capture/sequencejobstate.cpp:478 +#, fuzzy, kde-format +msgid "Slew to wall position complete, tracking stopped." +msgstr "Bereken" + +#: ekos/capture/sequencejobstate.cpp:506 #, fuzzy, kde-format msgid "Parking mount failed, aborting..." msgstr "Planeet" -#: ekos/capture/sequencejobstate.cpp:560 +#: ekos/capture/sequencejobstate.cpp:516 #, fuzzy, kde-format msgid "Parking mount prior to calibration frames capture..." msgstr "Spanje" -#: ekos/capture/sequencejobstate.cpp:574 +#: ekos/capture/sequencejobstate.cpp:530 #, fuzzy, kde-format msgid "Parking dome failed, aborting..." msgstr "Planeet" -#: ekos/capture/sequencejobstate.cpp:584 +#: ekos/capture/sequencejobstate.cpp:540 #, fuzzy, kde-format msgid "Parking dome prior to calibration frames capture..." msgstr "Spanje" -#: ekos/capture/sequencejobstate.cpp:838 +#: ekos/capture/sequencejobstate.cpp:776 #, kde-format msgid "Light box on." msgstr "" -#: ekos/capture/sequencejobstate.cpp:853 +#: ekos/capture/sequencejobstate.cpp:791 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" msgid "Dust cap parked." msgstr "Belize Stad" -#: ekos/capture/sequencejobstate.cpp:857 +#: ekos/capture/sequencejobstate.cpp:795 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" @@ -15729,7 +15839,7 @@ msgid "Image Received" msgstr "Beeld" -#: ekos/ekos.h:73 ekos/scheduler/schedulerjob.cpp:641 +#: ekos/ekos.h:73 ekos/scheduler/schedulerjob.cpp:617 #, fuzzy, kde-format msgid "Focusing" msgstr "Sidereal Tyd" @@ -15759,7 +15869,7 @@ msgid "Setting Rotator" msgstr "Invoer Keuse" -#: ekos/ekos.h:74 ekos/scheduler/schedulerjob.cpp:644 +#: ekos/ekos.h:74 ekos/scheduler/schedulerjob.cpp:620 #, fuzzy, kde-format msgid "Aligning" msgstr "Vertoon naam" @@ -15812,7 +15922,7 @@ msgid "Startup" msgstr "Ster" -#: ekos/ekos.h:187 ekos/scheduler/schedulerjob.cpp:616 +#: ekos/ekos.h:187 ekos/scheduler/schedulerjob.cpp:592 #, fuzzy, kde-format msgid "Running" msgstr "Manlik" @@ -15898,7 +16008,7 @@ msgid "Offline" msgstr "Bereken" -#: ekos/ekoslive/message.cpp:929 +#: ekos/ekoslive/message.cpp:932 #, fuzzy, kde-format msgid "Mosaic import failed." msgstr "Stooring van die beeld %1 gevaal!" @@ -15913,460 +16023,872 @@ msgid "Error parsing server response: %1" msgstr "Kon nie Open Lêer" -#: ekos/focus/focus.cpp:102 +#: ekos/focus/aberrationinspector.cpp:60 +#, kde-format +msgid "Aberration Inspector - Run %1" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:98 +#, kde-format +msgid "Tile" +msgstr "" + +#. i18n: ectx: property (text), widget (QTreeWidget, OptionsList) +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:99 +#: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:68 +#: tools/optionstreeview.ui:28 +#, fuzzy, kde-format, kde-kuit-format +msgid "Description" +msgstr "Des:" + +#. i18n: ectx: property (title), widget (QGroupBox, SolutionGroupBox) +#. i18n: ectx: property (text), widget (QTableWidget, solutionTable) +#: ekos/focus/aberrationinspector.cpp:93 fitsviewer/platesolve.ui:399 +#: fitsviewer/solveInfo.ui:91 +#, fuzzy, kde-format +msgid "Solution" +msgstr "Bereken" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +msgid "Delta (ticks)" +msgstr "Harrison" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Delta" +msgid "Delta (μm)" +msgstr "Delta" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +msgid "Num Stars" +msgstr "Moore" + +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:104 +#, kde-format +msgid "R²" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:93 +#, kde-format +msgid "Exclude" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:100 +#, fuzzy, kde-format +msgid "Focuser Solution" +msgstr "Voeg by Katalogus" + +#: ekos/focus/aberrationinspector.cpp:101 +#, kde-format +msgid "Delta from central tile in ticks" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:102 +#, fuzzy, kde-format +msgid "Delta from central tile in micrometers" +msgstr "Planeet" + +#: ekos/focus/aberrationinspector.cpp:103 +#, kde-format +msgid "Min / max number of stars detected in the focus run" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:105 +#, kde-format +msgid "Check to exclude row from calculations" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:565 +#: ekos/focus/aberrationinspector.cpp:582 +#: ekos/focus/aberrationinspector.cpp:583 +#: ekos/focus/aberrationinspector.cpp:584 +#, fuzzy, kde-format +msgid "N/A" +msgstr "N/'n" + +#: ekos/focus/aberrationinspector.cpp:570 +#, kde-format +msgid "Move sensor nearer flattener" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:572 +#, kde-format +msgid "Move sensor away from flattener" +msgstr "" + +#. i18n: ectx: property (windowTitle), widget (QDialog, aberrationInspectorDialog) +#: ekos/focus/aberrationinspector.ui:23 +#, fuzzy, kde-format +msgid "Aberration Inspector" +msgstr "Cary" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsShowLabels) +#: ekos/focus/aberrationinspector.ui:48 +#, fuzzy, kde-format +msgid "" +"

      Check to show labels on the graph.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsShowLabels) +#. i18n: ectx: property (text), widget (QCheckBox, abInsLabels) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: ekos/focus/aberrationinspector.ui:51 ekos/focus/aberrationinspector.ui:418 +#: xplanet/opsxplanet.ui:574 +#, fuzzy, kde-format +msgid "Labels" +msgstr "Latyn:" + +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: ekos/focus/aberrationinspector.ui:64 +#, fuzzy, kde-format +msgid "Tiles:" +msgstr "Peru" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:74 +#, kde-format +msgid "" +"

      Select the Mosaic tile combination to use for Analysis:" +"

      - All displays all 9 tiles.

      - Centre and outer corners.

      - " +"Centre and inner diamond.

      " +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#. i18n: ectx: property (text), widget (QPushButton, AllButton) +#: ekos/focus/aberrationinspector.ui:81 tools/obslistwizard.ui:173 +#, kde-format +msgid "All" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:86 +#, fuzzy, kde-format +#| msgid "Center && Track" +msgid "Centre and outer corners" +msgstr "Sentrum && Navolg" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:91 +#, fuzzy, kde-format +#| msgid "Center && Track" +msgid "Centre and inner diamond" +msgstr "Sentrum && Navolg" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsShowCFZ) +#: ekos/focus/aberrationinspector.ui:105 +#, fuzzy, kde-format +msgid "" +"

      Check to show the Critical Focus Zone on the graph." +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsShowCFZ) +#. i18n: ectx: attribute (title), widget (QWidget, CFZTab) +#: ekos/focus/aberrationinspector.ui:108 ekos/focus/focus.ui:2643 +#, kde-format +msgid "CFZ" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsOptCentres) +#: ekos/focus/aberrationinspector.ui:118 +#, kde-format +msgid "Optimise Tile Centres" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: ekos/focus/aberrationinspector.ui:228 +#, kde-format +msgid "Top-Bottom Tilt:" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_5) +#: ekos/focus/aberrationinspector.ui:241 +#, fuzzy, kde-format +msgid "Total Tilt:" +msgstr "Sidereal Tyd" + +#. i18n: ectx: property (toolTip), widget (QLineEdit, backfocus) +#: ekos/focus/aberrationinspector.ui:255 +#, fuzzy, kde-format +msgid "" +"

      Backfocus delta is the difference in focus position " +"between the sensor centre and the average of the centre corners.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: ekos/focus/aberrationinspector.ui:271 +#, kde-format +msgid "Backfocus Δ:" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: ekos/focus/aberrationinspector.ui:284 +#, fuzzy, kde-format +msgid "Left-Right Tilt:" +msgstr "Beeld" + +#. i18n: ectx: property (text), widget (QLabel, label_6) +#: ekos/focus/aberrationinspector.ui:319 +#, fuzzy, kde-format +msgid "Selection:" +msgstr "Bereken" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:333 +#, kde-format +msgid "" +"\n" +"\n" +"

      Selection mode of the 3D " +"Graphic:

      \n" +"

      - None.

      \n" +"

      - Item selects the nearest " +"datapoint.

      \n" +"

      - Slice produces a 2D " +"slice through the graphic.

      " +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:345 fitsviewer/starprofileviewer.cpp:127 +#, kde-format +msgid "Item" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:350 +#, fuzzy, kde-format +msgid "Slice" +msgstr "Ada" + +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: ekos/focus/aberrationinspector.ui:358 +#, kde-format +msgid "Theme:" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:365 +#, fuzzy, kde-format +msgid "" +"

      Select the colour theme of the 3D Graphic.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:372 +#, kde-format +msgid "Qt" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:377 +#, fuzzy, kde-format +msgid "Primary Colors" +msgstr "Planeet" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:382 +#, kde-format +msgid "Digia" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:387 +#, kde-format +msgid "Stone Moss" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:392 +#, fuzzy, kde-format +msgid "Army Blue" +msgstr "Strand" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:397 +#, fuzzy, kde-format +msgid "Retro" +msgstr "Des:" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:402 +#, kde-format +msgid "Ebony" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:407 +#, fuzzy, kde-format +msgid "Isabelle" +msgstr "Kareroon" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsLabels) +#: ekos/focus/aberrationinspector.ui:415 +#, fuzzy, kde-format +msgid "" +"

      Check to display mosaic tile sensor labels.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsSensor) +#: ekos/focus/aberrationinspector.ui:428 +#, fuzzy, kde-format +msgid "

      Check to display the Sensor.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsSensor) +#: ekos/focus/aberrationinspector.ui:431 +#, fuzzy, kde-format +msgid "Sensor" +msgstr "Maak skoon Velde" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsPetzvalWire) +#: ekos/focus/aberrationinspector.ui:441 +#, fuzzy, kde-format +msgid "" +"

      Check to display the Petzval surface mesh.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsPetzvalWire) +#: ekos/focus/aberrationinspector.ui:444 +#, kde-format +msgid "Petzval Wire" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsPetzvalSurface) +#: ekos/focus/aberrationinspector.ui:454 +#, fuzzy, kde-format +msgid "" +"

      Check to display the Petzval surface.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsPetzvalSurface) +#: ekos/focus/aberrationinspector.ui:457 +#, kde-format +msgid "Petzval Surface" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsSimMode) +#: ekos/focus/aberrationinspector.ui:470 +#, fuzzy, kde-format +msgid "" +"

      Check to set 3D Graphic in Simulation Mode

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsSimMode) +#: ekos/focus/aberrationinspector.ui:473 +#, fuzzy, kde-format +msgid "Sim Mode" +msgstr "Moore" + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsBackfocusSlider) +#: ekos/focus/aberrationinspector.ui:483 +#, fuzzy, kde-format +msgid "

      Backfocus slider

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsTiltLRSlider) +#: ekos/focus/aberrationinspector.ui:502 +#, fuzzy, kde-format +msgid "

      Left-to-Right Tilt Slider

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsTiltTBSlider) +#: ekos/focus/aberrationinspector.ui:521 +#, fuzzy, kde-format +msgid "

      Top-to-Bottom Tilt Slider

      " +msgstr "Soek Voorwerp" + +#: ekos/focus/aberrationinspectorplot.cpp:106 +#, kde-format +msgctxt "" +"Graphics tooltip; %2 is tile code; %3 is tile name, %4 is Focus Position; %5 " +"is Focus Measure;" +msgid "" +"
      Tile: %2 (%3)
      Pos: %4
      Val: %5
      " +msgstr "" + +#: ekos/focus/focus.cpp:107 #, kde-format msgid "Idle." msgstr "" -#: ekos/focus/focus.cpp:124 +#: ekos/focus/focus.cpp:129 #, fuzzy, kde-format msgid "Focus Options Profile Editor" msgstr "Invoer Keuse" -#: ekos/focus/focus.cpp:836 +#: ekos/focus/focus.cpp:850 #, fuzzy, kde-format msgid "Finally found temperature source %1" msgstr "Voeg by Katalogus" -#: ekos/focus/focus.cpp:961 +#: ekos/focus/focus.cpp:975 #, kde-format msgid "Adaptive Focus: Temp delta %1 ticks; Alt delta %2 ticks" msgstr "" -#: ekos/focus/focus.cpp:975 +#: ekos/focus/focus.cpp:989 #, kde-format msgid "Adaptive Focus suspended. Total movement would exceed Max Travel limit" msgstr "" -#: ekos/focus/focus.cpp:983 +#: ekos/focus/focus.cpp:997 #, kde-format msgid "Adaptive Focus suspended. Total movement would exceed adaptive limit" msgstr "" -#: ekos/focus/focus.cpp:989 +#: ekos/focus/focus.cpp:1003 #, kde-format msgid "Adaptive Focus moving from %1 to %2" msgstr "" -#: ekos/focus/focus.cpp:1003 +#: ekos/focus/focus.cpp:1017 #, kde-format msgid "Adaptive Focus unable to move focuser" msgstr "" -#: ekos/focus/focus.cpp:1128 +#: ekos/focus/focus.cpp:1149 #, fuzzy, kde-format msgid "No Focuser connected." msgstr "Bereken" -#: ekos/focus/focus.cpp:1135 ekos/focus/focus.cpp:4012 +#: ekos/focus/focus.cpp:1156 ekos/focus/focus.cpp:4236 #, fuzzy, kde-format msgid "No CCD connected." msgstr "Bereken" -#: ekos/focus/focus.cpp:1142 +#: ekos/focus/focus.cpp:1163 #, kde-format msgid "" "Starting pulse step is too low. Increase the step size to %1 or higher..." msgstr "" -#: ekos/focus/focus.cpp:1150 +#: ekos/focus/focus.cpp:1171 #, kde-format msgid "Autofocus is already running, discarding start request." msgstr "" -#: ekos/focus/focus.cpp:1155 +#: ekos/focus/focus.cpp:1176 #, kde-format msgid "Discarding Autofocus start request - AdjustFocus in progress." msgstr "" -#: ekos/focus/focus.cpp:1160 +#: ekos/focus/focus.cpp:1181 #, kde-format msgid "Discarding Autofocus start request - AdaptiveFocus in progress." msgstr "" -#: ekos/focus/focus.cpp:1300 +#: ekos/focus/focus.cpp:1322 #, kde-format msgid "Autofocus in progress..." msgstr "" -#: ekos/focus/focus.cpp:1302 +#: ekos/focus/focus.cpp:1324 #, kde-format msgid "Please wait until image capture is complete..." msgstr "" -#: ekos/focus/focus.cpp:1316 +#: ekos/focus/focus.cpp:1338 #, fuzzy, kde-format msgid "Autofocus operation started" msgstr "Aarde koördinate" -#: ekos/focus/focus.cpp:1403 +#: ekos/focus/focus.cpp:1425 #, kde-format msgid "Adaptive start point, last AF solution outside Max Travel, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1411 +#: ekos/focus/focus.cpp:1433 #, kde-format msgid "Adaptive start point, no temperature source available" msgstr "" -#: ekos/focus/focus.cpp:1413 +#: ekos/focus/focus.cpp:1435 #, kde-format msgid "Adaptive start point, no temperature for last AF solution" msgstr "" -#: ekos/focus/focus.cpp:1420 +#: ekos/focus/focus.cpp:1442 #, kde-format msgid "Adaptive start point, very large temperature delta, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1432 +#: ekos/focus/focus.cpp:1454 #, kde-format msgid "Adaptive start point, no alt recorded for last AF solution" msgstr "" -#: ekos/focus/focus.cpp:1434 +#: ekos/focus/focus.cpp:1456 #, kde-format msgid "Adaptive start point, very large altitude delta, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1444 +#: ekos/focus/focus.cpp:1466 #, kde-format msgid "Adaptive start point, target position is outside Max Travel, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1452 +#: ekos/focus/focus.cpp:1474 #, fuzzy, kde-format #| msgid "Planet Name" msgid "Adaptive start point [%1] excessive move disallowed" msgstr "Planeet Naam" -#: ekos/focus/focus.cpp:1466 +#: ekos/focus/focus.cpp:1488 #, fuzzy, kde-format #| msgid "Planet Name" msgid "Adapting start point [%1] from %2 to %3" msgstr "Planeet Naam" -#: ekos/focus/focus.cpp:1512 +#: ekos/focus/focus.cpp:1535 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" msgid "Detection in progress, please wait." msgstr "Belize Stad" -#: ekos/focus/focus.cpp:1546 +#: ekos/focus/focus.cpp:1569 #, fuzzy, kde-format msgid "Autofocus aborted." msgstr "Bereken" -#: ekos/focus/focus.cpp:1630 +#: ekos/focus/focus.cpp:1655 #, kde-format msgid "Error: No Camera detected." msgstr "" -#: ekos/focus/focus.cpp:1637 +#: ekos/focus/focus.cpp:1662 #, fuzzy, kde-format msgid "Error: Lost connection to Camera." msgstr "Bereken" -#: ekos/focus/focus.cpp:1658 +#: ekos/focus/focus.cpp:1683 #, kde-format msgid "Error: No Filter Wheel detected." msgstr "" -#: ekos/focus/focus.cpp:1664 +#: ekos/focus/focus.cpp:1689 #, fuzzy, kde-format msgid "Error: Lost connection to Filter Wheel." msgstr "Bereken" -#: ekos/focus/focus.cpp:1803 +#: ekos/focus/focus.cpp:1828 #, kde-format msgid "Error: No Focuser detected." msgstr "" -#: ekos/focus/focus.cpp:1810 +#: ekos/focus/focus.cpp:1835 #, fuzzy, kde-format msgid "Error: Lost connection to Focuser." msgstr "Bereken" -#: ekos/focus/focus.cpp:1822 +#: ekos/focus/focus.cpp:1848 #, fuzzy, kde-format msgid "outward" msgstr "Maak skoon" -#: ekos/focus/focus.cpp:1822 +#: ekos/focus/focus.cpp:1848 #, fuzzy, kde-format msgid "inward" msgstr "Maak skoon" -#: ekos/focus/focus.cpp:1836 +#: ekos/focus/focus.cpp:1865 #, fuzzy, kde-format msgid "Focusing %2 by %1 steps..." msgstr "Sidereal tyd" -#: ekos/focus/focus.cpp:1842 +#: ekos/focus/focus.cpp:1871 #, fuzzy, kde-format msgid "Focusing %2 by %1 step..." msgid_plural "Focusing %2 by %1 steps..." msgstr[0] "Sidereal tyd" msgstr[1] "Sidereal tyd" -#: ekos/focus/focus.cpp:1848 +#: ekos/focus/focus.cpp:1877 #, fuzzy, kde-format msgid "Focusing %2 by %1 ms..." msgstr "Sidereal tyd" -#: ekos/focus/focus.cpp:1886 +#: ekos/focus/focus.cpp:1915 #, fuzzy, kde-format msgid "Focuser is still timing out. Aborting..." msgstr "Stoor Beeld" -#: ekos/focus/focus.cpp:1893 +#: ekos/focus/focus.cpp:1922 #, fuzzy, kde-format msgid "Focus motion timed out (%1). Restarting focus driver %2" msgstr "Planeet" -#: ekos/focus/focus.cpp:1904 +#: ekos/focus/focus.cpp:1933 #, fuzzy, kde-format msgid "Focus motion timed out (%1). Focusing to %2 steps..." msgstr "Planeet" -#: ekos/focus/focus.cpp:1960 +#: ekos/focus/focus.cpp:1990 #, kde-format msgid "Attempting to reconnect focuser: %1" msgstr "" -#: ekos/focus/focus.cpp:1969 +#: ekos/focus/focus.cpp:1999 #, fuzzy, kde-format msgid "Cannot reconnect focuser: %1. Aborting..." msgstr "Stoor Beeld" -#: ekos/focus/focus.cpp:2018 +#: ekos/focus/focus.cpp:2048 #, fuzzy, kde-format msgid "Detection complete." msgstr "Bereken" -#: ekos/focus/focus.cpp:2210 +#: ekos/focus/focus.cpp:2240 #, fuzzy, kde-format msgid "Detecting sources..." msgstr "Laaiïng van K-sterre..." -#: ekos/focus/focus.cpp:2324 +#: ekos/focus/focus.cpp:2354 #, fuzzy, kde-format msgid "Autofocus operation completed successfully" msgstr "Aarde koördinate" -#: ekos/focus/focus.cpp:2336 +#: ekos/focus/focus.cpp:2366 #, fuzzy, kde-format msgid "Autofocus operation failed" msgstr "Aarde koördinate" -#: ekos/focus/focus.cpp:2368 +#: ekos/focus/focus.cpp:2402 #, fuzzy, kde-format msgid "Focus procedure completed after %1 iteration." msgid_plural "Focus procedure completed after %1 iterations." msgstr[0] "Bereken" msgstr[1] "Bereken" -#: ekos/focus/focus.cpp:2452 +#: ekos/focus/focus.cpp:2486 #, fuzzy, kde-format msgid "Settling for %1s..." msgstr "niks" -#: ekos/focus/focus.cpp:2459 +#: ekos/focus/focus.cpp:2493 #, fuzzy, kde-format msgid "Settling complete." msgstr "Bereken" -#: ekos/focus/focus.cpp:2472 +#: ekos/focus/focus.cpp:2506 #, kde-format msgid "Autofocus failed, moving back to initial focus position %1." msgstr "" -#: ekos/focus/focus.cpp:2509 +#: ekos/focus/focus.cpp:2543 #, kde-format msgid "FITS received. No stars detected." msgstr "" -#: ekos/focus/focus.cpp:2664 +#: ekos/focus/focus.cpp:2783 #, kde-format msgid "Failed to automatically select a star. Please select a star manually." msgstr "" -#: ekos/focus/focus.cpp:2758 +#: ekos/focus/focus.cpp:2877 #, fuzzy, kde-format msgid "Capture complete. Select a star to focus." msgstr "Wissel Sterre" -#: ekos/focus/focus.cpp:2789 +#: ekos/focus/focus.cpp:2908 #, kde-format msgid "No stars detected while testing HFR, capturing again..." msgstr "" -#: ekos/focus/focus.cpp:2916 +#: ekos/focus/focus.cpp:3052 #, kde-format msgid "Autofocus failed to reach proper focus. Try increasing tolerance value." msgstr "" -#: ekos/focus/focus.cpp:2927 ekos/focus/focus.cpp:3566 +#: ekos/focus/focus.cpp:3063 ekos/focus/focus.cpp:3761 #, kde-format msgid "No stars detected, capturing again..." msgstr "" -#: ekos/focus/focus.cpp:2933 ekos/focus/focus.cpp:3572 +#: ekos/focus/focus.cpp:3069 ekos/focus/focus.cpp:3767 #, fuzzy, kde-format msgid "Failed to detect any stars at position %1. Continuing..." msgstr "Kon nie Open Lêer" -#: ekos/focus/focus.cpp:2938 ekos/focus/focus.cpp:3577 +#: ekos/focus/focus.cpp:3074 ekos/focus/focus.cpp:3772 #, kde-format msgid "Failed to detect any stars. Reset frame and try again." msgstr "" -#: ekos/focus/focus.cpp:3164 +#: ekos/focus/focus.cpp:3257 +#, kde-format +msgid "Unable to launch Aberration Inspector run %1..." +msgstr "" + +#: ekos/focus/focus.cpp:3277 +#, kde-format +msgid "Launching Aberration Inspector run %1..." +msgstr "" + +#: ekos/focus/focus.cpp:3337 #, kde-format msgid "Curve Fit check failed R2=%1 focusR2Limit=%2 retrying..." msgstr "" -#: ekos/focus/focus.cpp:3171 +#: ekos/focus/focus.cpp:3344 #, kde-format msgid "Curve Fit check failed again R2=%1 focusR2Limit=%2 but continuing..." msgstr "" -#: ekos/focus/focus.cpp:3214 +#: ekos/focus/focus.cpp:3387 #, kde-format msgid "FITS received. HFR %1 @ %2. Delta (%3%)" msgstr "" -#: ekos/focus/focus.cpp:3216 +#: ekos/focus/focus.cpp:3389 #, kde-format msgid "FITS received. HFR %1 @ %2." msgstr "" -#: ekos/focus/focus.cpp:3277 +#: ekos/focus/focus.cpp:3450 #, kde-format msgid "" "Change in HFR is too small. Try increasing the step size or decreasing the " "tolerance." msgstr "" -#: ekos/focus/focus.cpp:3284 +#: ekos/focus/focus.cpp:3457 #, kde-format msgid "Failed to detect focus star in frame. Capture and select a focus star." msgstr "" -#: ekos/focus/focus.cpp:3389 +#: ekos/focus/focus.cpp:3562 #, kde-format msgid "Found polynomial solution @ %1" msgstr "" -#: ekos/focus/focus.cpp:3453 +#: ekos/focus/focus.cpp:3626 #, kde-format msgid "Focuser cannot move further, device limits reached. Autofocus aborted." msgstr "" -#: ekos/focus/focus.cpp:3464 +#: ekos/focus/focus.cpp:3637 #, kde-format msgid "" "Unstable fluctuations. Try increasing initial step size or exposure time." msgstr "" -#: ekos/focus/focus.cpp:3474 +#: ekos/focus/focus.cpp:3647 #, kde-format msgid "Deadlock reached. Please try again with different settings." msgstr "" -#: ekos/focus/focus.cpp:3503 +#: ekos/focus/focus.cpp:3676 #, kde-format msgid "Maximum travel limit reached. Autofocus aborted." msgstr "" -#: ekos/focus/focus.cpp:3551 +#: ekos/focus/focus.cpp:3746 #, kde-format msgid "FITS received. HFR %1. Delta (%2%) Min HFR (%3)" msgstr "" -#: ekos/focus/focus.cpp:3555 +#: ekos/focus/focus.cpp:3750 #, kde-format msgid "" "Autofocus failed to reach proper focus. Try adjusting the tolerance value." msgstr "" -#: ekos/focus/focus.cpp:3645 ekos/focus/focus.cpp:3658 -#: ekos/focus/focus.cpp:3779 ekos/focus/focus.cpp:3851 -#: ekos/focus/focus.cpp:3912 ekos/focus/focus.cpp:3956 +#: ekos/focus/focus.cpp:3840 ekos/focus/focus.cpp:3853 +#: ekos/focus/focus.cpp:3983 ekos/focus/focus.cpp:4055 +#: ekos/focus/focus.cpp:4116 ekos/focus/focus.cpp:4180 #, kde-format msgid "Focuser error, check INDI panel." msgstr "" -#: ekos/focus/focus.cpp:3689 ekos/focus/focus.cpp:3795 +#: ekos/focus/focus.cpp:3889 ekos/focus/focus.cpp:3999 #, fuzzy, kde-format msgid "Simulate focuser comms failure..." msgstr "Bereken" -#: ekos/focus/focus.cpp:3760 ekos/focus/focus.cpp:3836 -#: ekos/focus/focus.cpp:3897 ekos/focus/focus.cpp:3930 +#: ekos/focus/focus.cpp:3964 ekos/focus/focus.cpp:4040 +#: ekos/focus/focus.cpp:4101 ekos/focus/focus.cpp:4134 #, fuzzy, kde-format msgid "Restarting autofocus process..." msgstr "Spanje" -#: ekos/focus/focus.cpp:4028 +#: ekos/focus/focus.cpp:4252 #, fuzzy, kde-format msgid "Starting continuous exposure..." msgstr "Spanje" -#: ekos/focus/focus.cpp:4292 +#: ekos/focus/focus.cpp:4528 #, kde-format msgid "Disabling Auto Star Selection as star selection box was moved manually." msgstr "" -#: ekos/focus/focus.cpp:4297 +#: ekos/focus/focus.cpp:4533 #, fuzzy, kde-format msgid "Focus star is selected." msgstr "Nee Voorwerp gekose!" -#: ekos/focus/focus.cpp:4425 +#: ekos/focus/focus.cpp:4661 #, kde-format msgid "No star was selected. Using last known position..." msgstr "" -#: ekos/focus/focus.cpp:4431 +#: ekos/focus/focus.cpp:4667 #, kde-format msgid "No star was selected. Aborting..." msgstr "" -#: ekos/focus/focus.cpp:4542 +#: ekos/focus/focus.cpp:4778 #, fuzzy, kde-format msgctxt "@title:window" msgid "Focus Frame" msgstr "Sidereal Tyd" -#: ekos/focus/focus.cpp:4879 +#: ekos/focus/focus.cpp:5120 #, fuzzy, kde-format msgid "Capturing image again..." msgstr "Laaiïng van K-sterre..." -#: ekos/focus/focus.cpp:4894 +#: ekos/focus/focus.cpp:5135 #, fuzzy, kde-format msgid "Failed to save image. Aborting..." msgstr "Kon nie Open Lêer" -#: ekos/focus/focus.cpp:4904 +#: ekos/focus/focus.cpp:5145 #, fuzzy, kde-format msgid "Exposure failure. Aborting..." msgstr "Stoor Beeld" -#: ekos/focus/focus.cpp:4909 +#: ekos/focus/focus.cpp:5150 #, fuzzy, kde-format msgid "Exposure failure. Restarting exposure..." msgstr "Stoor Beeld" -#: ekos/focus/focus.cpp:5187 +#: ekos/focus/focus.cpp:5438 #, fuzzy, kde-format msgctxt "@title:window" msgid "Relative Profile" msgstr "Beeld" -#: ekos/focus/focus.cpp:6379 +#: ekos/focus/focus.cpp:6643 #, kde-format msgid "" "Focus Advisor (FA) is designed to help you with focus parameters.\n" @@ -16391,7 +16913,7 @@ "default." msgstr "" -#: ekos/focus/focus.cpp:6395 +#: ekos/focus/focus.cpp:6659 #, kde-format msgid "" " You have a scope with a central obstruction so be careful not to move too " @@ -16403,7 +16925,7 @@ "range of focuser motion." msgstr "" -#: ekos/focus/focus.cpp:6402 +#: ekos/focus/focus.cpp:6666 #, kde-format msgid "" "\n" @@ -16424,129 +16946,144 @@ "You are now ready to start an Autofocus run." msgstr "" -#: ekos/focus/focus.cpp:6412 +#: ekos/focus/focus.cpp:6676 #, fuzzy, kde-format msgid "Focus Advisor" msgstr "Planeet" -#. i18n: ectx: property (toolTip), widget (QSpinBox, absTicksSpin) -#: ekos/focus/focus.ui:170 -#, fuzzy, kde-format -msgid "Desired absolute focus position" -msgstr "Des:" - -#. i18n: ectx: property (toolTip), widget (QLineEdit, absTicksLabel) -#: ekos/focus/focus.ui:186 +#. i18n: ectx: property (toolTip), widget (QPushButton, startLoopB) +#: ekos/focus/focus.ui:164 #, fuzzy, kde-format -msgid "Current absolute focuser position" -msgstr "Stoor Huidige Kleure..." +msgid "Start framing" +msgstr "Spanje" -#. i18n: ectx: property (toolTip), widget (QPushButton, focusInB) -#: ekos/focus/focus.ui:208 +#. i18n: ectx: property (toolTip), widget (QPushButton, focusOutB) +#: ekos/focus/focus.ui:193 #, kde-format -msgid "Focus In" +msgid "Focus Out" msgstr "" +#. i18n: ectx: property (toolTip), widget (QPushButton, captureB) +#: ekos/focus/focus.ui:225 +#, fuzzy, kde-format +msgid "Capture image" +msgstr "Stoor Beeld" + #. i18n: ectx: property (toolTip), widget (QPushButton, stopGotoB) -#: ekos/focus/focus.ui:253 +#: ekos/focus/focus.ui:254 #, fuzzy, kde-format msgid "Stop focuser motion" msgstr "Bereken" #. i18n: ectx: property (toolTip), widget (QPushButton, startFocusB) -#: ekos/focus/focus.ui:282 +#: ekos/focus/focus.ui:283 #, fuzzy, kde-format msgid "Start Auto Focus process" msgstr "Spanje" -#. i18n: ectx: property (text), widget (QLabel, label_22) -#: ekos/focus/focus.ui:305 -#, fuzzy, kde-format -msgid "Start:" -msgstr "Ster" - #. i18n: ectx: property (text), widget (QLabel, label_16) #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_4) -#: ekos/focus/focus.ui:315 ekos/scheduler/framingassistant.ui:1281 +#: ekos/focus/focus.ui:299 ekos/scheduler/framingassistant.ui:1281 #: ekos/scheduler/scheduler.ui:111 #, kde-format msgid "Steps:" msgstr "" -#. i18n: ectx: property (toolTip), widget (QPushButton, focusOutB) -#: ekos/focus/focus.ui:334 -#, kde-format -msgid "Focus Out" -msgstr "" - #. i18n: ectx: property (toolTip), widget (QPushButton, startGotoB) -#: ekos/focus/focus.ui:366 +#: ekos/focus/focus.ui:318 #, fuzzy, kde-format msgid "Go to an absolute focus position" msgstr "Des:" -#. i18n: ectx: property (toolTip), widget (QPushButton, startLoopB) -#: ekos/focus/focus.ui:395 +#. i18n: ectx: property (text), widget (QLabel, label_22) +#: ekos/focus/focus.ui:351 #, fuzzy, kde-format -msgid "Start framing" +msgid "Start:" +msgstr "Ster" + +#. i18n: ectx: property (toolTip), widget (QPushButton, stopFocusB) +#: ekos/focus/focus.ui:370 +#, fuzzy, kde-format +msgid "Stop Auto Focus process" msgstr "Spanje" -#. i18n: ectx: property (toolTip), widget (QPushButton, captureB) -#: ekos/focus/focus.ui:424 +#. i18n: ectx: property (toolTip), widget (QLineEdit, absTicksLabel) +#: ekos/focus/focus.ui:389 #, fuzzy, kde-format -msgid "Capture image" -msgstr "Stoor Beeld" +msgid "Current absolute focuser position" +msgstr "Stoor Huidige Kleure..." -#. i18n: ectx: property (toolTip), widget (QPushButton, stopFocusB) +#. i18n: ectx: property (toolTip), widget (QPushButton, focusInB) +#: ekos/focus/focus.ui:411 +#, kde-format +msgid "Focus In" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QPushButton, startAbInsB) +#: ekos/focus/focus.ui:450 +#, fuzzy, kde-format +msgid "" +"

      Run Aberration Inspector (Auto Focus will run first to " +"collect data).

      Note: Mosaic Mask must be set to activate this button.

      This is an experimental feature.

      " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QPushButton, startAbInsB) #: ekos/focus/focus.ui:453 #, fuzzy, kde-format -msgid "Stop Auto Focus process" -msgstr "Spanje" +msgid "Inspector" +msgstr "Invoer Keuse" + +#. i18n: ectx: property (toolTip), widget (QSpinBox, absTicksSpin) +#: ekos/focus/focus.ui:475 +#, fuzzy, kde-format +msgid "Desired absolute focus position" +msgstr "Des:" #. i18n: ectx: property (toolTip), widget (QLabel, gainLabel) #. i18n: ectx: property (toolTip), widget (QLabel, label_7) #. i18n: ectx: property (toolTip), widget (QLabel, label_3) -#: ekos/focus/focus.ui:511 ekos/focus/focus.ui:568 ekos/guide/guide.ui:372 +#: ekos/focus/focus.ui:530 ekos/focus/focus.ui:587 ekos/guide/guide.ui:372 #, kde-format msgid "Exposure time in seconds" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, temperatureSourceLabel) -#: ekos/focus/focus.ui:536 +#: ekos/focus/focus.ui:555 #, fuzzy, kde-format msgid "Focuser temperature source" msgstr "Voeg by Katalogus" #. i18n: ectx: property (text), widget (QLabel, temperatureSourceLabel) -#: ekos/focus/focus.ui:539 +#: ekos/focus/focus.ui:558 #, fuzzy, kde-format msgid "TS." msgstr "St:" #. i18n: ectx: property (toolTip), widget (QLabel, label_30) #. i18n: ectx: property (toolTip), widget (QLabel, absoluteTemperatureLabel) -#: ekos/focus/focus.ui:618 ekos/focus/focus.ui:634 +#: ekos/focus/focus.ui:637 ekos/focus/focus.ui:653 #, fuzzy, kde-format msgid "Source temperature in Celsius" msgstr "Voeg by Katalogus" #. i18n: ectx: property (text), widget (QLabel, label_30) -#: ekos/focus/focus.ui:621 +#: ekos/focus/focus.ui:640 #, fuzzy, kde-format msgid "Temp. =" msgstr "Tyd" #. i18n: ectx: property (text), widget (QLabel, absoluteTemperatureLabel) #. i18n: ectx: property (text), widget (QLabel, deltaTemperatureLabel) -#: ekos/focus/focus.ui:640 ekos/focus/focus.ui:675 +#: ekos/focus/focus.ui:659 ekos/focus/focus.ui:694 #, fuzzy, kde-format msgid "NA" msgstr "N/'n" #. i18n: ectx: property (toolTip), widget (QLabel, label_31) #. i18n: ectx: property (toolTip), widget (QLabel, deltaTemperatureLabel) -#: ekos/focus/focus.ui:650 ekos/focus/focus.ui:669 +#: ekos/focus/focus.ui:669 ekos/focus/focus.ui:688 #, kde-format msgid "" "Delta temperature in Celsius. It is the difference between the last recorded " @@ -16554,25 +17091,25 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_31) -#: ekos/focus/focus.ui:653 +#: ekos/focus/focus.ui:672 #, kde-format msgid "ΔT =" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, toggleFullScreenB) -#: ekos/focus/focus.ui:698 +#: ekos/focus/focus.ui:717 #, fuzzy, kde-format msgid "Toggle Full Screen" msgstr " Welkom na K-sterre " #. i18n: ectx: property (toolTip), widget (QPushButton, resetFrameB) -#: ekos/focus/focus.ui:776 +#: ekos/focus/focus.ui:795 #, kde-format msgid "Reset focus subframe to full capture" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, defaultFocusTemperatureSource) -#: ekos/focus/focus.ui:875 +#: ekos/focus/focus.ui:894 #, fuzzy, kde-format msgid "Select focuser temperature source" msgstr "Koördinate" @@ -16581,21 +17118,21 @@ #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) #. i18n: ectx: property (title), widget (QGroupBox, settingsGroupBox) #. i18n: ectx: property (title), widget (QGroupBox, ImageOverlayBox) -#: ekos/focus/focus.ui:913 ekos/guide/opscalibration.ui:34 +#: ekos/focus/focus.ui:932 ekos/guide/opscalibration.ui:34 #: ekos/guide/opsgpg.ui:103 options/opsimageoverlay.ui:38 #, fuzzy, kde-format msgid "Settings" msgstr "niks" #. i18n: ectx: attribute (toolTip), widget (QWidget, settingsTab) -#: ekos/focus/focus.ui:916 +#: ekos/focus/focus.ui:935 #, fuzzy, kde-format msgid "" "

      General Focus Settings parameters.

      " msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusMosaicMaskRB) -#: ekos/focus/focus.ui:942 +#: ekos/focus/focus.ui:961 #, fuzzy, kde-format msgid "" "

      Aberration inspector style mask with a 3x3 mosaic " @@ -16604,13 +17141,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QRadioButton, focusMosaicMaskRB) -#: ekos/focus/focus.ui:945 +#: ekos/focus/focus.ui:964 #, fuzzy, kde-format msgid "Mosaic Mask:" msgstr "Cary" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMosaicSpace) -#: ekos/focus/focus.ui:955 +#: ekos/focus/focus.ui:974 #, fuzzy, kde-format msgid "" "

      Size of the separator between the tiles.

      During Full Field focusing, this controls the size of " @@ -16647,19 +17184,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusRingMaskRB) -#: ekos/focus/focus.ui:993 +#: ekos/focus/focus.ui:1012 #, kde-format msgid "Ring Mask:" msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusBoxSize) -#: ekos/focus/focus.ui:1012 +#: ekos/focus/focus.ui:1031 #, fuzzy, kde-format msgid "

      Size of the subframe in pixels.

      " msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, guideSettleTime) -#: ekos/focus/focus.ui:1040 +#: ekos/focus/focus.ui:1059 #, fuzzy, kde-format msgid "" "

      Wait this many seconds after autofocus completes " @@ -16668,13 +17205,13 @@ #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, guideSettleTime) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusSettleTime) -#: ekos/focus/focus.ui:1043 ekos/focus/focus.ui:2226 +#: ekos/focus/focus.ui:1062 ekos/focus/focus.ui:2245 #, kde-format msgid " s" msgstr "" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusSubFrame) -#: ekos/focus/focus.ui:1053 +#: ekos/focus/focus.ui:1072 #, kde-format msgid "" "

      Select Sub Frame to make focus to use a single star " @@ -16685,13 +17222,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusSubFrame) -#: ekos/focus/focus.ui:1056 +#: ekos/focus/focus.ui:1075 #, fuzzy, kde-format msgid "Sub Frame" msgstr "Ster Naam" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusUseFullField) -#: ekos/focus/focus.ui:1069 +#: ekos/focus/focus.ui:1088 #, kde-format msgid "" "

      Select Full Field to allow focus to use multiple stars " @@ -16701,14 +17238,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusUseFullField) -#: ekos/focus/focus.ui:1072 +#: ekos/focus/focus.ui:1091 #, fuzzy, kde-format #| msgid "Clear Fields" msgid "Full Field" msgstr "Maak skoon Velde" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusFullFieldOuterRadius) -#: ekos/focus/focus.ui:1091 +#: ekos/focus/focus.ui:1110 #, no-c-format, kde-format msgid "" "

      Diameter of the outer circle to be excluded from " @@ -16723,8 +17260,8 @@ #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusTolerance) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZTau) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, overlapSpin) -#: ekos/focus/focus.ui:1097 ekos/focus/focus.ui:1198 ekos/focus/focus.ui:1241 -#: ekos/focus/focus.ui:1990 ekos/focus/focus.ui:2087 ekos/focus/focus.ui:2914 +#: ekos/focus/focus.ui:1116 ekos/focus/focus.ui:1217 ekos/focus/focus.ui:1260 +#: ekos/focus/focus.ui:2009 ekos/focus/focus.ui:2106 ekos/focus/focus.ui:2933 #: ekos/scheduler/framingassistant.ui:879 #, no-c-format, kde-format msgid " %" @@ -16732,31 +17269,31 @@ #. i18n: ectx: property (text), widget (QLabel, label_15) #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/focus/focus.ui:1119 ekos/guide/guide.ui:365 +#: ekos/focus/focus.ui:1138 ekos/guide/guide.ui:365 #, kde-format msgid "Box:" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, useFocusDarkFrame) -#: ekos/focus/focus.ui:1138 +#: ekos/focus/focus.ui:1157 #, fuzzy, kde-format msgid "Use dark frames from the library." msgstr "Kon nie Open Lêer" #. i18n: ectx: property (text), widget (QCheckBox, useFocusDarkFrame) -#: ekos/focus/focus.ui:1141 +#: ekos/focus/focus.ui:1160 #, fuzzy, kde-format msgid "Dark Frame" msgstr "Maak skoon Velde" #. i18n: ectx: property (text), widget (QLabel, label_13) -#: ekos/focus/focus.ui:1154 +#: ekos/focus/focus.ui:1173 #, fuzzy, kde-format msgid "Guide Settle:" msgstr "Stoor Huidige Kleure..." #. i18n: ectx: property (toolTip), widget (QCheckBox, focusAutoStarEnabled) -#: ekos/focus/focus.ui:1173 +#: ekos/focus/focus.ui:1192 #, kde-format msgid "" "

      This option is only active when Sub Frame is " @@ -16765,13 +17302,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusAutoStarEnabled) -#: ekos/focus/focus.ui:1176 +#: ekos/focus/focus.ui:1195 #, fuzzy, kde-format msgid "Auto Select Star" msgstr "Invoer Keuse" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusFullFieldInnerRadius) -#: ekos/focus/focus.ui:1192 +#: ekos/focus/focus.ui:1211 #, kde-format msgid "" "

      Diameter of the inner circle to be excluded from " @@ -16781,19 +17318,19 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1211 +#: ekos/focus/focus.ui:1230 #, fuzzy, kde-format msgid "

      Display units for HFR and FWHM.

      " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), item, widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1215 +#: ekos/focus/focus.ui:1234 #, fuzzy, kde-format msgid "Pixels" msgstr "Sonsondergang:" #. i18n: ectx: property (text), item, widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1220 +#: ekos/focus/focus.ui:1239 #, fuzzy, kde-format #| msgctxt "seconds" #| msgid "secs" @@ -16801,13 +17338,13 @@ msgstr "sekondes" #. i18n: ectx: property (text), widget (QLabel, focusSpacerLabel) -#: ekos/focus/focus.ui:1228 +#: ekos/focus/focus.ui:1247 #, kde-format msgid "Spacer:" msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMosaicTileWidth) -#: ekos/focus/focus.ui:1235 +#: ekos/focus/focus.ui:1254 #, kde-format msgid "" "

      Tiles are squares with an edge length calculated by " @@ -16817,38 +17354,38 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_38) -#: ekos/focus/focus.ui:1269 +#: ekos/focus/focus.ui:1288 #, fuzzy, kde-format msgid "Display Units:" msgstr "Vertoon Opsies" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusNoMaskRB) -#: ekos/focus/focus.ui:1282 +#: ekos/focus/focus.ui:1301 #, kde-format msgid "All stars are used for focusing." msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusNoMaskRB) -#: ekos/focus/focus.ui:1285 +#: ekos/focus/focus.ui:1304 #, kde-format msgid "Use all stars for focusing" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, adaptiveFocusGroup) #. i18n: ectx: property (text), widget (QCheckBox, focusAdaptive) -#: ekos/focus/focus.ui:1309 ekos/focus/focus.ui:1404 +#: ekos/focus/focus.ui:1328 ekos/focus/focus.ui:1423 #, fuzzy, kde-format msgid "Adaptive Focus" msgstr "Ster Naam" #. i18n: ectx: property (text), widget (QLabel, label_4) -#: ekos/focus/focus.ui:1357 +#: ekos/focus/focus.ui:1376 #, fuzzy, kde-format msgid "Max Total Move:" msgstr "Sidereal Tyd" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdaptiveMaxMove) -#: ekos/focus/focus.ui:1376 +#: ekos/focus/focus.ui:1395 #, kde-format msgid "" "

      The maximum total Adaptive focuser movement between " @@ -16859,13 +17396,13 @@ #. i18n: ectx: property (suffix), widget (QSpinBox, focusAdaptiveMaxMove) #. i18n: ectx: property (suffix), widget (QSpinBox, focusAdaptiveMinMove) -#: ekos/focus/focus.ui:1379 ekos/focus/focus.ui:1446 +#: ekos/focus/focus.ui:1398 ekos/focus/focus.ui:1465 #, fuzzy, kde-format msgid " ticks" msgstr "Harrison" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusAdaptive) -#: ekos/focus/focus.ui:1401 +#: ekos/focus/focus.ui:1420 #, fuzzy, kde-format msgid "" "

      Enable Adaptive Focus between subframes. This is an " @@ -16873,7 +17410,7 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QLabel, label_3) -#: ekos/focus/focus.ui:1411 +#: ekos/focus/focus.ui:1430 #, fuzzy, kde-format msgid "" "

      Minimum focuser movement when using Adaptive Focus.

      Adapt the Autofocus start position based on filter and " @@ -16897,13 +17434,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QCheckBox, focusAdaptStart) -#: ekos/focus/focus.ui:1430 +#: ekos/focus/focus.ui:1449 #, fuzzy, kde-format msgid "Adapt Start Pos" msgstr "Hoogte:" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdaptiveMinMove) -#: ekos/focus/focus.ui:1443 +#: ekos/focus/focus.ui:1462 #, fuzzy, kde-format msgid "" "

      The minimum size of an adaptive focus change that will " @@ -16911,13 +17448,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: attribute (title), widget (QWidget, processTab) -#: ekos/focus/focus.ui:1468 +#: ekos/focus/focus.ui:1487 #, fuzzy, kde-format msgid "Process" msgstr "Sidereal Tyd" #. i18n: ectx: attribute (toolTip), widget (QWidget, processTab) -#: ekos/focus/focus.ui:1471 +#: ekos/focus/focus.ui:1490 #, fuzzy, kde-format msgid "" "

      Focus parameters to do with the Autofocus process.

      Set a minimum for the acceptable R² when performing an " @@ -16936,31 +17473,31 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusStarMeasureLabel) -#: ekos/focus/focus.ui:1531 +#: ekos/focus/focus.ui:1550 #, fuzzy, kde-format msgid "Measure:" msgstr "Koördinate" #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/focus/focus.ui:1550 +#: ekos/focus/focus.ui:1569 #, fuzzy, kde-format msgid "Detection:" msgstr "Bereken" #. i18n: ectx: property (text), widget (QLabel, focusFramesCountLabel) -#: ekos/focus/focus.ui:1569 +#: ekos/focus/focus.ui:1588 #, fuzzy, kde-format msgid "Average Over:" msgstr "Ada" #. i18n: ectx: property (text), widget (QLabel, focusR2LimitLabel) -#: ekos/focus/focus.ui:1585 +#: ekos/focus/focus.ui:1604 #, fuzzy, kde-format msgid "R² Limit:" msgstr "l:" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusFramesCount) -#: ekos/focus/focus.ui:1623 +#: ekos/focus/focus.ui:1642 #, fuzzy, kde-format msgid "" "

      Number of frames to capture at the current focuser " @@ -16968,19 +17505,19 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (suffix), widget (QSpinBox, focusFramesCount) -#: ekos/focus/focus.ui:1626 +#: ekos/focus/focus.ui:1645 #, fuzzy, kde-format msgid " frames" msgstr "Ster Naam" #. i18n: ectx: property (text), widget (QLabel, focusCurveFitLabel) -#: ekos/focus/focus.ui:1645 +#: ekos/focus/focus.ui:1664 #, kde-format msgid "Curve Fit:" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, focusCurveFit) -#: ekos/focus/focus.ui:1655 +#: ekos/focus/focus.ui:1674 #, kde-format msgid "" "

      Select the type of curve to fit to the data:

        Select the Measure to use when fitting a curve for " @@ -17061,38 +17598,38 @@ #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) #. i18n: ectx: property (text), widget (QTableWidget, statsTable) -#: ekos/focus/focus.ui:1703 fitsviewer/statform.ui:81 +#: ekos/focus/focus.ui:1722 fitsviewer/statform.ui:81 #, kde-format msgid "HFR" msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1708 +#: ekos/focus/focus.ui:1727 #, kde-format msgid "HFR Adj" msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1713 +#: ekos/focus/focus.ui:1732 #, kde-format msgid "FWHM" msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1718 +#: ekos/focus/focus.ui:1737 #, fuzzy, kde-format #| msgid "Stars" msgid "# Stars" msgstr "Sterre" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1723 +#: ekos/focus/focus.ui:1742 #, fuzzy, kde-format msgid "Fourier" msgstr "Mount Mario" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusRefineCurveFit) -#: ekos/focus/focus.ui:1731 +#: ekos/focus/focus.ui:1750 #, kde-format msgid "" "

        Check to run an outlier pass when all datapoints have " @@ -17104,13 +17641,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusRefineCurveFit) -#: ekos/focus/focus.ui:1734 +#: ekos/focus/focus.ui:1753 #, kde-format msgid "Refine Curve Fit" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusUseWeights) -#: ekos/focus/focus.ui:1747 +#: ekos/focus/focus.ui:1766 #, kde-format msgid "" "

        Check to use the standard deviation of the star HFR or " @@ -17121,13 +17658,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusUseWeights) -#: ekos/focus/focus.ui:1750 +#: ekos/focus/focus.ui:1769 #, fuzzy, kde-format msgid "Use Weights" msgstr "Stoor Beeld" #. i18n: ectx: property (toolTip), widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1763 +#: ekos/focus/focus.ui:1782 #, no-c-format, kde-format msgid "" "

        Select focus process algorithm:

          Star detection method:

            The type of PSF to use when Measure is set to FWHM:

          " msgstr "" +#. i18n: ectx: property (text), widget (QLabel, focusThresholdLabel) +#: ekos/focus/focus.ui:1914 +#, fuzzy, kde-format +msgid "Threshold:" +msgstr "Leon" + #. i18n: ectx: property (toolTip), widget (QSpinBox, focusGaussianKernelSize) -#: ekos/focus/focus.ui:1911 +#: ekos/focus/focus.ui:1930 #, fuzzy, kde-format msgid "" "

          The gaussian blur kernel size. Used for blurring the " @@ -17272,19 +17815,19 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, focusGaussianKernelSizeLabel) -#: ekos/focus/focus.ui:1936 +#: ekos/focus/focus.ui:1955 #, fuzzy, kde-format msgid "Kernel size:" msgstr "Latyn:" #. i18n: ectx: property (text), widget (QLabel, focusGaussianSigmaLabel) -#: ekos/focus/focus.ui:1952 +#: ekos/focus/focus.ui:1971 #, fuzzy, kde-format msgid "Sigma:" msgstr "Beeld" #. i18n: ectx: property (text), widget (QLabel, focusMultiRowAverageLabel) -#: ekos/focus/focus.ui:1968 +#: ekos/focus/focus.ui:1987 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "High Point" @@ -17292,7 +17835,7 @@ msgstr "Hoog Punt" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusThreshold) -#: ekos/focus/focus.ui:1987 +#: ekos/focus/focus.ui:2006 #, fuzzy, kde-format msgid "" "

          Increase to restrict the centroid to bright cores. Decrease " @@ -17300,7 +17843,7 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMultiRowAverage) -#: ekos/focus/focus.ui:2015 +#: ekos/focus/focus.ui:2034 #, kde-format msgid "" "

          Combine this number of rows in the Bahtinov max " @@ -17309,7 +17852,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusGaussianSigma) -#: ekos/focus/focus.ui:2040 +#: ekos/focus/focus.ui:2059 #, fuzzy, kde-format msgid "" "

          The gaussian blur sigma value. Used for blurring the " @@ -17317,7 +17860,7 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusTolerance) -#: ekos/focus/focus.ui:2084 +#: ekos/focus/focus.ui:2103 #, kde-format msgid "" "Decrease value to narrow optimal focus point solution radius. Increase to " @@ -17325,13 +17868,13 @@ msgstr "" #. i18n: ectx: attribute (title), widget (QWidget, mechanicsTab) -#: ekos/focus/focus.ui:2128 +#: ekos/focus/focus.ui:2147 #, fuzzy, kde-format msgid "Mechanics" msgstr "Eudore" #. i18n: ectx: attribute (toolTip), widget (QWidget, mechanicsTab) -#: ekos/focus/focus.ui:2131 +#: ekos/focus/focus.ui:2150 #, fuzzy, kde-format msgid "" "

          Focus parameters to do with the mechanics of moving " @@ -17339,25 +17882,25 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, label_11) -#: ekos/focus/focus.ui:2169 +#: ekos/focus/focus.ui:2188 #, fuzzy, kde-format msgid "Driver Backlash:" msgstr "Ada" #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/focus/focus.ui:2191 +#: ekos/focus/focus.ui:2210 #, fuzzy, kde-format msgid "Initial Step Size:" msgstr "uur" #. i18n: ectx: property (text), widget (QLabel, label_9) -#: ekos/focus/focus.ui:2207 +#: ekos/focus/focus.ui:2226 #, fuzzy, kde-format msgid "Focuser Settle:" msgstr "Sidereal Tyd" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusSettleTime) -#: ekos/focus/focus.ui:2223 +#: ekos/focus/focus.ui:2242 #, fuzzy, kde-format msgid "" "

          Settle time (in seconds) after moving the focuser " @@ -17367,25 +17910,25 @@ #. i18n: ectx: property (text), widget (QLabel, focusOutStepsLabel) #. i18n: ectx: property (text), widget (QLabel, focusAdvOutStepMultLabel) -#: ekos/focus/focus.ui:2248 ekos/focus/focus.ui:3306 +#: ekos/focus/focus.ui:2267 ekos/focus/focus.ui:3325 #, kde-format msgid "Out Step Multiple:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusWalkLabel) -#: ekos/focus/focus.ui:2264 +#: ekos/focus/focus.ui:2283 #, fuzzy, kde-format msgid "Walk:" msgstr "Moore" #. i18n: ectx: property (text), widget (QLabel, label_17) -#: ekos/focus/focus.ui:2280 +#: ekos/focus/focus.ui:2299 #, fuzzy, kde-format msgid "

          Max Step Size:

          " msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusBacklash) -#: ekos/focus/focus.ui:2296 +#: ekos/focus/focus.ui:2315 #, kde-format msgid "" "

          For backlash-aware focusers, the amount of backlash to " @@ -17396,7 +17939,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusTicks) -#: ekos/focus/focus.ui:2309 +#: ekos/focus/focus.ui:2328 #, kde-format msgid "" "

          Initial Step Size

          Select the type of walk for the focuser to take when " @@ -17439,38 +17982,38 @@ #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) #. i18n: ectx: property (text), item, widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:2357 ekos/focus/focus.ui:3126 +#: ekos/focus/focus.ui:2376 ekos/focus/focus.ui:3145 #: kstarslite/qml/modules/popups/ColorSchemePopup.qml:55 #, fuzzy, kde-format, kde-kuit-format msgid "Classic" msgstr "Kaap Dalk mag" #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) -#: ekos/focus/focus.ui:2362 +#: ekos/focus/focus.ui:2381 #, fuzzy, kde-format msgid "Fixed Steps" msgstr "uur" #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) -#: ekos/focus/focus.ui:2367 +#: ekos/focus/focus.ui:2386 #, kde-format msgid "CFZ Shuffle" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_12) -#: ekos/focus/focus.ui:2384 +#: ekos/focus/focus.ui:2403 #, kde-format msgid "Max Travel:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_26) -#: ekos/focus/focus.ui:2400 +#: ekos/focus/focus.ui:2419 #, fuzzy, kde-format msgid "Capture Timeout:" msgstr "Stoor Beeld" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMaxSingleStep) -#: ekos/focus/focus.ui:2416 +#: ekos/focus/focus.ui:2435 #, kde-format msgid "" "

          The maximum single step size the algorithm is allowed " @@ -17479,7 +18022,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusOutSteps) -#: ekos/focus/focus.ui:2438 +#: ekos/focus/focus.ui:2457 #, kde-format msgid "" "

          This number multiplied by initial-step-size is number of " @@ -17489,7 +18032,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, focusCaptureTimeout) #. i18n: ectx: whatsthis, entry (FocusCaptureTimeout), group (Focus) -#: ekos/focus/focus.ui:2463 kstars.kcfg:2102 +#: ekos/focus/focus.ui:2482 kstars.kcfg:2126 #, kde-format msgid "" "Maximum time in seconds to wait for a captured image to be received before " @@ -17497,7 +18040,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAFOverscan) -#: ekos/focus/focus.ui:2485 +#: ekos/focus/focus.ui:2504 #, kde-format msgid "" "

          Provides backlash overscan in ticks for outward " @@ -17509,7 +18052,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusMaxTravel) -#: ekos/focus/focus.ui:2504 +#: ekos/focus/focus.ui:2523 #, fuzzy, kde-format msgid "" "

          Maximum travel in steps before the autofocus process " @@ -17517,13 +18060,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, label_27) -#: ekos/focus/focus.ui:2532 +#: ekos/focus/focus.ui:2551 #, fuzzy, kde-format msgid "Motion Timeout:" msgstr "Tyd" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMotionTimeout) -#: ekos/focus/focus.ui:2548 +#: ekos/focus/focus.ui:2567 #, fuzzy, kde-format msgid "" "

          Maximum time in seconds to wait for the focuser to " @@ -17531,13 +18074,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, focusNumStepsLabel) -#: ekos/focus/focus.ui:2570 +#: ekos/focus/focus.ui:2589 #, fuzzy, kde-format msgid "Number Steps:" msgstr "Lawrence" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusNumSteps) -#: ekos/focus/focus.ui:2586 +#: ekos/focus/focus.ui:2605 #, fuzzy, kde-format msgid "" "

          The total number of steps to use when Walk is set to " @@ -17545,14 +18088,8 @@ "body>" msgstr "Soek Voorwerp" -#. i18n: ectx: attribute (title), widget (QWidget, CFZTab) -#: ekos/focus/focus.ui:2624 -#, kde-format -msgid "CFZ" -msgstr "" - #. i18n: ectx: attribute (toolTip), widget (QWidget, CFZTab) -#: ekos/focus/focus.ui:2627 +#: ekos/focus/focus.ui:2646 #, kde-format msgid "" "

          Parameters to do with configuring the Critical Focus " @@ -17561,7 +18098,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusCFZTauLabel) -#: ekos/focus/focus.ui:2696 +#: ekos/focus/focus.ui:2715 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "France" @@ -17569,19 +18106,19 @@ msgstr "Frankryk" #. i18n: ectx: property (text), widget (QLabel, focusCFZLabel) -#: ekos/focus/focus.ui:2712 +#: ekos/focus/focus.ui:2731 #, fuzzy, kde-format msgid "

          CFZ:

          " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, focusCFZApertureLabel) -#: ekos/focus/focus.ui:2731 +#: ekos/focus/focus.ui:2750 #, fuzzy, kde-format msgid "Aperture (A):" msgstr "Koördinate" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusCFZDisplayVCurve) -#: ekos/focus/focus.ui:2750 +#: ekos/focus/focus.ui:2769 #, fuzzy, kde-format msgid "" "

          Check to display the CFZ on the V-curve after a " @@ -17590,13 +18127,13 @@ #. i18n: ectx: property (text), widget (QCheckBox, focusCFZDisplayVCurve) #. i18n: ectx: property (title), widget (QGroupBox, displayGroup) -#: ekos/focus/focus.ui:2753 hips/hipsmanager.cpp:96 indi/opsindi.ui:497 +#: ekos/focus/focus.ui:2772 hips/hipsmanager.cpp:96 indi/opsindi.ui:497 #, fuzzy, kde-format msgid "Display" msgstr "Vertoon Opsies" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusCFZAperture) -#: ekos/focus/focus.ui:2772 +#: ekos/focus/focus.ui:2791 #, fuzzy, kde-format msgid "" "

          Set the aperture of your telescope in mm. This is " @@ -17605,7 +18142,7 @@ #. i18n: ectx: property (suffix), widget (QSpinBox, focusCFZAperture) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focalLenSpin) -#: ekos/focus/focus.ui:2775 ekos/scheduler/framingassistant.ui:87 +#: ekos/focus/focus.ui:2794 ekos/scheduler/framingassistant.ui:87 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Hammond" @@ -17613,7 +18150,7 @@ msgstr "Hammond" #. i18n: ectx: property (toolTip), widget (QLineEdit, FocusCFZCameraSteps) -#: ekos/focus/focus.ui:2800 +#: ekos/focus/focus.ui:2819 #, fuzzy, kde-format msgid "" "

          The CFZ of the camera (resolution limit) in the active " @@ -17621,13 +18158,13 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QLineEdit, focusCFZ) -#: ekos/focus/focus.ui:2816 +#: ekos/focus/focus.ui:2835 #, fuzzy, kde-format msgid "

          The calculated CFZ in μm.

          " msgstr "Soek Voorwerp" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZTolerance) -#: ekos/focus/focus.ui:2835 +#: ekos/focus/focus.ui:2854 #, kde-format msgid "" "

          Set the tolerance=t value between 0 and 1. This scales " @@ -17636,7 +18173,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QLineEdit, FocusCFZFinal) -#: ekos/focus/focus.ui:2860 +#: ekos/focus/focus.ui:2879 #, fuzzy, kde-format msgid "" "

          The Final CFZ is the greater of the calculated CFZ and " @@ -17644,19 +18181,19 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, label_37) -#: ekos/focus/focus.ui:2876 +#: ekos/focus/focus.ui:2895 #, fuzzy, kde-format msgid "

          Step Size:

          " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, label_19) -#: ekos/focus/focus.ui:2892 +#: ekos/focus/focus.ui:2911 #, fuzzy, kde-format msgid "CFZ Camera:" msgstr "Cary" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZTau) -#: ekos/focus/focus.ui:2911 +#: ekos/focus/focus.ui:2930 #, kde-format msgid "" "

          Set the

          The calculated CFZ in steps.

          " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, focusCFZFormula) -#: ekos/focus/focus.ui:2955 +#: ekos/focus/focus.ui:2974 #, fuzzy, kde-format msgid "" "

          CFZ = 4.88 t λ f

          Set the step size (in microns) of your focuser. To " @@ -17706,13 +18243,13 @@ msgstr "" #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZStepSize) -#: ekos/focus/focus.ui:3012 +#: ekos/focus/focus.ui:3031 #, kde-format msgid " μm" msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZSeeing) -#: ekos/focus/focus.ui:3037 +#: ekos/focus/focus.ui:3056 #, fuzzy, kde-format msgid "" "

          The total seeing FWHM (in arc-seconds).

          Reset Wavelength, Aperture, Focal Ratio to values " @@ -17728,19 +18265,19 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QPushButton, resetToOTB) -#: ekos/focus/focus.ui:3068 +#: ekos/focus/focus.ui:3087 #, fuzzy, kde-format msgid "Reset To OT" msgstr "Stel Tyd na Nou" #. i18n: ectx: property (text), widget (QLabel, label_14) -#: ekos/focus/focus.ui:3081 +#: ekos/focus/focus.ui:3100 #, fuzzy, kde-format msgid "Focal Ratio (f):" msgstr "Ster Naam" #. i18n: ectx: property (toolTip), widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:3119 +#: ekos/focus/focus.ui:3138 #, kde-format msgid "" "

          Select the Critical Focus Zone (CFZ) algorithm:

            Set the F# to use. This is defaulted from the selected " @@ -17786,19 +18323,19 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QLabel, label_20) -#: ekos/focus/focus.ui:3178 +#: ekos/focus/focus.ui:3197 #, kde-format msgid "Final CFZ:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusCFZSeeingLabel) -#: ekos/focus/focus.ui:3197 +#: ekos/focus/focus.ui:3216 #, kde-format msgid "FWHM (θ):" msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZWavelength) -#: ekos/focus/focus.ui:3213 +#: ekos/focus/focus.ui:3232 #, fuzzy, kde-format msgid "" "

            Set the light wavelength to use. This is defaulted " @@ -17806,7 +18343,7 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZWavelength) -#: ekos/focus/focus.ui:3216 +#: ekos/focus/focus.ui:3235 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Hammond" @@ -17814,13 +18351,13 @@ msgstr "Hammond" #. i18n: ectx: attribute (title), widget (QWidget, advisorTab) -#: ekos/focus/focus.ui:3251 +#: ekos/focus/focus.ui:3270 #, kde-format msgid "Advisor" msgstr "" #. i18n: ectx: attribute (toolTip), widget (QWidget, advisorTab) -#: ekos/focus/focus.ui:3254 +#: ekos/focus/focus.ui:3273 #, fuzzy, kde-format msgid "" "

            Focus Advisor help utility to assist with setting up " @@ -17835,22 +18372,22 @@ #. i18n: ectx: property (text), widget (QCheckBox, focusAdvSettingsTab) #. i18n: ectx: property (text), widget (QPushButton, updateButton) #. i18n: ectx: property (text), widget (QPushButton, Update) -#: ekos/focus/focus.ui:3286 ekos/focus/focus.ui:3322 ekos/focus/focus.ui:3345 -#: ekos/focus/focus.ui:3420 ekos/focus/focus.ui:3436 ekos/focus/focus.ui:3465 +#: ekos/focus/focus.ui:3305 ekos/focus/focus.ui:3341 ekos/focus/focus.ui:3364 +#: ekos/focus/focus.ui:3439 ekos/focus/focus.ui:3455 ekos/focus/focus.ui:3484 #: tools/altvstime.ui:535 tools/observinglist.ui:222 #, fuzzy, kde-format msgid "Update" msgstr "Datum" #. i18n: ectx: property (text), widget (QLabel, focusAdvCameraLabel) -#: ekos/focus/focus.ui:3296 +#: ekos/focus/focus.ui:3315 #, fuzzy, kde-format msgid "Camera & Filter Wheel Parameters" msgstr "Voeg by Katalogus" #. i18n: ectx: property (toolTip), widget (QLabel, focusAdvOutStepMultLabel) #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdvOutStepMult) -#: ekos/focus/focus.ui:3303 ekos/focus/focus.ui:3497 +#: ekos/focus/focus.ui:3322 ekos/focus/focus.ui:3516 #, kde-format msgid "" "

            A good figure to start with is 5. An exception is if " @@ -17864,19 +18401,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusAdvSettingsLabel) -#: ekos/focus/focus.ui:3332 +#: ekos/focus/focus.ui:3351 #, fuzzy, kde-format msgid "Settings Tab Parameters" msgstr "Koördinate" #. i18n: ectx: property (text), widget (QLabel, focusAdvProcessLabel) -#: ekos/focus/focus.ui:3355 +#: ekos/focus/focus.ui:3374 #, fuzzy, kde-format msgid "Process Tab Parameters" msgstr "Koördinate" #. i18n: ectx: property (toolTip), widget (QPushButton, focusAdvReset) -#: ekos/focus/focus.ui:3368 +#: ekos/focus/focus.ui:3387 #, fuzzy, kde-format msgid "" "

            Update Focus Parameters to Focus Advisor suggestions " @@ -17884,14 +18421,14 @@ msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QPushButton, focusAdvReset) -#: ekos/focus/focus.ui:3371 +#: ekos/focus/focus.ui:3390 #, fuzzy, kde-format msgid "Update Params" msgstr "Datum" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdvSteps) #. i18n: ectx: property (toolTip), widget (QLabel, label_32) -#: ekos/focus/focus.ui:3384 ekos/focus/focus.ui:3446 +#: ekos/focus/focus.ui:3403 ekos/focus/focus.ui:3465 #, kde-format msgid "" "

            Step size can be defaulted to the Critical Focus Zone. " @@ -17900,51 +18437,51 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusAdvLabel) -#: ekos/focus/focus.ui:3400 +#: ekos/focus/focus.ui:3419 #, fuzzy, kde-format msgid "Focus Advisor:" msgstr "Planeet" #. i18n: ectx: property (text), widget (QLabel, focusAdvMechanicsLabel) -#: ekos/focus/focus.ui:3407 +#: ekos/focus/focus.ui:3426 #, fuzzy, kde-format msgid "Mechanics Tab Parameters" msgstr "Koördinate" #. i18n: ectx: property (text), widget (QLabel, label_32) -#: ekos/focus/focus.ui:3449 +#: ekos/focus/focus.ui:3468 #, fuzzy, kde-format msgid "Step Size:" msgstr "uur" #. i18n: ectx: property (toolTip), widget (QPushButton, focusAdvHelp) -#: ekos/focus/focus.ui:3481 +#: ekos/focus/focus.ui:3500 #, fuzzy, kde-format msgid "" "

            Launch the Focus Advisor Help dialog.

            " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QPushButton, focusAdvHelp) -#: ekos/focus/focus.ui:3484 +#: ekos/focus/focus.ui:3503 #, kde-format msgid "Help..." msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) -#: ekos/focus/focus.ui:3575 +#: ekos/focus/focus.ui:3594 #, kde-format msgid "V-Curve" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_2) #. i18n: ectx: property (text), widget (QLabel, label_9) -#: ekos/focus/focus.ui:3617 ekos/manager/focusmanager.ui:165 +#: ekos/focus/focus.ui:3636 ekos/manager/focusmanager.ui:165 #, kde-format msgid "HFR:" msgstr "" #. i18n: ectx: property (toolTip), widget (QLineEdit, HFROut) -#: ekos/focus/focus.ui:3636 +#: ekos/focus/focus.ui:3655 #, fuzzy, kde-format msgid "" "

            Averaged HFR value from the last frame.

            Averaged FWHM value from the last frame.

            Number of stars found in the last frame.

            Focuser iteration.

            " msgstr "Soek Voorwerp" #. i18n: ectx: property (text), widget (QPushButton, relativeProfileB) -#: ekos/focus/focus.ui:3781 +#: ekos/focus/focus.ui:3800 #, fuzzy, kde-format msgid "Profile..." msgstr "Strand" @@ -18002,41 +18539,41 @@ #. i18n: ectx: property (text), widget (QPushButton, clearB) #. i18n: ectx: property (text), widget (QPushButton, ClearButton) #. i18n: ectx: property (text), widget (QPushButton, Clear) -#: ekos/focus/focus.ui:3788 ekos/manager.ui:957 fitsviewer/fitstab.cpp:136 +#: ekos/focus/focus.ui:3807 ekos/manager.ui:957 fitsviewer/fitstab.cpp:145 #: indi/guimanager.cpp:75 tools/conjunctions.ui:205 tools/eclipsetool.ui:167 #: tools/modcalcgeod.ui:160 #, fuzzy, kde-format msgid "Clear" msgstr "Maak skoon" -#: ekos/focus/focusalgorithms.cpp:504 +#: ekos/focus/focusalgorithms.cpp:512 #, kde-format msgid "Called newMeasurement after a solution was found." msgstr "" -#: ekos/focus/focusalgorithms.cpp:780 +#: ekos/focus/focusalgorithms.cpp:788 #, fuzzy, kde-format msgid "Failed to fit curve to data." msgstr "Kon nie Open Lêer" -#: ekos/focus/focusalgorithms.cpp:840 +#: ekos/focus/focusalgorithms.cpp:848 #, fuzzy, kde-format msgid "Solution found." msgstr "Horisontaal Koördinate" -#: ekos/focus/focusalgorithms.cpp:884 +#: ekos/focus/focusalgorithms.cpp:892 #, kde-format msgid "Too many steps." msgstr "" -#: ekos/focus/focusalgorithms.cpp:913 +#: ekos/focus/focusalgorithms.cpp:921 #, kde-format msgid "Solution lies outside max travel." msgstr "" #. i18n: ectx: property (text), widget (QTableWidget, tableWidget) #: ekos/focus/focushfrvplot.cpp:42 fitsviewer/fitsheaderdialog.ui:53 -#: fitsviewer/fitstab.cpp:355 +#: fitsviewer/fitstab.cpp:364 #, fuzzy, kde-format msgid "Value" msgstr "Dc" @@ -18059,7 +18596,7 @@ msgstr "" #: ekos/guide/externalguide/linguider.cpp:70 -#: ekos/guide/externalguide/phd2.cpp:278 +#: ekos/guide/externalguide/phd2.cpp:279 #, kde-format msgid "" "The host was not found. Please check the host name and port settings in " @@ -18074,7 +18611,7 @@ msgstr "" #: ekos/guide/externalguide/linguider.cpp:79 -#: ekos/guide/externalguide/phd2.cpp:285 +#: ekos/guide/externalguide/phd2.cpp:286 #, kde-format msgid "The following error occurred: %1." msgstr "" @@ -18137,275 +18674,275 @@ msgid "Failed to set dither range." msgstr "Kon nie Open Lêer" -#: ekos/guide/externalguide/phd2.cpp:134 +#: ekos/guide/externalguide/phd2.cpp:135 #, kde-format msgid "PHD2: There was no dithering response from PHD2, but continue guiding." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:150 +#: ekos/guide/externalguide/phd2.cpp:151 #, kde-format msgid "Giving up reconnecting." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:154 +#: ekos/guide/externalguide/phd2.cpp:155 #, kde-format msgid "Reconnecting to PHD2 Host: %1, on port %2. . ." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:191 +#: ekos/guide/externalguide/phd2.cpp:192 #, kde-format msgid "Connecting to PHD2 Host: %1, on port %2. . ." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:246 +#: ekos/guide/externalguide/phd2.cpp:247 #, kde-format msgid "Aborting any capture before disconnecting equipment..." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:259 +#: ekos/guide/externalguide/phd2.cpp:260 #, kde-format msgid "Disconnected from PHD2 Host: %1, on port %2." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:275 +#: ekos/guide/externalguide/phd2.cpp:276 #, fuzzy, kde-format msgid "The host disconnected." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:281 +#: ekos/guide/externalguide/phd2.cpp:282 #, kde-format msgid "" "The connection was refused by the peer. Make sure the PHD2 is running, and " "check that the host name and port settings are correct." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:307 +#: ekos/guide/externalguide/phd2.cpp:308 #, kde-format msgid "PHD2: invalid response received: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:308 +#: ekos/guide/externalguide/phd2.cpp:309 #, fuzzy, kde-format msgid "PHD2: JSON error: %1" msgstr "Des:" -#: ekos/guide/externalguide/phd2.cpp:332 +#: ekos/guide/externalguide/phd2.cpp:333 #, kde-format msgid "Unknown PHD2 event: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:341 +#: ekos/guide/externalguide/phd2.cpp:342 #, fuzzy, kde-format msgid "PHD2: Version %1" msgstr "Des:" -#: ekos/guide/externalguide/phd2.cpp:345 +#: ekos/guide/externalguide/phd2.cpp:346 #, fuzzy, kde-format msgid "PHD2: Calibration Complete." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:355 +#: ekos/guide/externalguide/phd2.cpp:356 #, fuzzy, kde-format msgid "PHD2: Waiting for guiding to settle." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:378 +#: ekos/guide/externalguide/phd2.cpp:379 #, fuzzy, kde-format msgid "PHD2: Calibration Failed (%1)." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:383 +#: ekos/guide/externalguide/phd2.cpp:384 #, fuzzy, kde-format msgid "Calibration Data Flipped." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:411 +#: ekos/guide/externalguide/phd2.cpp:412 #, kde-format msgid "PHD2: Settling failed (%1)." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:430 +#: ekos/guide/externalguide/phd2.cpp:431 #, kde-format msgid "PHD2: There was a dithering error, but continue guiding." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:439 +#: ekos/guide/externalguide/phd2.cpp:440 #, fuzzy, kde-format msgid "PHD2: Settling failed, aborted." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:445 +#: ekos/guide/externalguide/phd2.cpp:446 #, fuzzy, kde-format msgid "PHD2: Settling complete, Guiding Started." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:474 +#: ekos/guide/externalguide/phd2.cpp:475 #, fuzzy, kde-format msgid "PHD2: Star found, guiding is resuming..." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:556 +#: ekos/guide/externalguide/phd2.cpp:557 #, kde-format msgid "PHD2 %1: %2" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:610 +#: ekos/guide/externalguide/phd2.cpp:611 #, kde-format msgid "PHD2: Looping Exposures Stopped." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:615 +#: ekos/guide/externalguide/phd2.cpp:616 #, fuzzy, kde-format msgid "PHD2: Guiding Stopped." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:634 +#: ekos/guide/externalguide/phd2.cpp:635 #, kde-format msgid "PHD2: Lock Position Set." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:645 +#: ekos/guide/externalguide/phd2.cpp:646 #, kde-format msgid "PHD2: Star Selected." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:655 +#: ekos/guide/externalguide/phd2.cpp:656 #, fuzzy, kde-format msgid "PHD2: Guiding resumed." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:660 +#: ekos/guide/externalguide/phd2.cpp:661 #, fuzzy, kde-format msgid "PHD2: Guiding started." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:671 +#: ekos/guide/externalguide/phd2.cpp:672 #, kde-format msgid "PHD2: Lock Position Lost, continuing calibration." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:677 +#: ekos/guide/externalguide/phd2.cpp:678 #, fuzzy, kde-format msgid "PHD2: Star Lost. Trying to reacquire for %1s." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:683 +#: ekos/guide/externalguide/phd2.cpp:684 #, kde-format msgid "PHD2: Lock Position Lost." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:689 +#: ekos/guide/externalguide/phd2.cpp:690 #, fuzzy, kde-format msgid "PHD2: Guiding paused." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:694 +#: ekos/guide/externalguide/phd2.cpp:695 #, fuzzy, kde-format msgid "PHD2: Calibrating, timing out in %1s." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:703 +#: ekos/guide/externalguide/phd2.cpp:704 #, fuzzy, kde-format msgid "PHD2: Calibration turned to looping, failed." msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:707 +#: ekos/guide/externalguide/phd2.cpp:708 #, fuzzy, kde-format msgid "PHD2: Looping Exposures." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:713 +#: ekos/guide/externalguide/phd2.cpp:714 #, fuzzy, kde-format msgid "PHD2: Dithering started." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:741 +#: ekos/guide/externalguide/phd2.cpp:742 #, fuzzy, kde-format msgid "PHD2: Calibration is cleared" msgstr "Bereken" -#: ekos/guide/externalguide/phd2.cpp:837 +#: ekos/guide/externalguide/phd2.cpp:838 #, kde-format msgid "PHD2: DEC Guide Mode is Set to: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:847 +#: ekos/guide/externalguide/phd2.cpp:848 #, fuzzy, kde-format msgid "PHD2: Exposure Time set to: " msgstr "Aangaande die Maan Beelde" -#: ekos/guide/externalguide/phd2.cpp:855 +#: ekos/guide/externalguide/phd2.cpp:856 #, fuzzy, kde-format msgid "PHD2: Valid Exposure Times: Auto, " msgstr "Aangaande die Maan Beelde" -#: ekos/guide/externalguide/phd2.cpp:886 +#: ekos/guide/externalguide/phd2.cpp:887 #, kde-format msgid "" "PHD2: Please set CCD and telescope parameters in PHD2, Pixel Scale is " "invalid." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:888 +#: ekos/guide/externalguide/phd2.cpp:889 #, kde-format msgid "PHD2: Pixel Scale is %1 arcsec per pixel" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1003 +#: ekos/guide/externalguide/phd2.cpp:1004 #, kde-format msgid "PHD2 Error: unhandled '%1'" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1135 -#: ekos/guide/externalguide/phd2.cpp:1153 -#: ekos/guide/externalguide/phd2.cpp:1304 -#: ekos/guide/externalguide/phd2.cpp:1419 -#: ekos/guide/externalguide/phd2.cpp:1448 -#: ekos/guide/externalguide/phd2.cpp:1477 +#: ekos/guide/externalguide/phd2.cpp:1136 +#: ekos/guide/externalguide/phd2.cpp:1154 +#: ekos/guide/externalguide/phd2.cpp:1305 +#: ekos/guide/externalguide/phd2.cpp:1420 +#: ekos/guide/externalguide/phd2.cpp:1449 +#: ekos/guide/externalguide/phd2.cpp:1478 #, kde-format msgid "PHD2 Error: Equipment not connected." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1297 +#: ekos/guide/externalguide/phd2.cpp:1298 #, fuzzy, kde-format msgid "PHD2: Guiding is already running." msgstr "Soek Voorwerp" -#: ekos/guide/externalguide/phd2.cpp:1363 +#: ekos/guide/externalguide/phd2.cpp:1364 #, fuzzy, kde-format #| msgid "Configure Hidden Objects" msgid "PHD2: Connecting Equipment. . ." msgstr "Konfigureer Weg gesteekte Objekte" -#: ekos/guide/externalguide/phd2.cpp:1365 +#: ekos/guide/externalguide/phd2.cpp:1366 #, kde-format msgid "PHD2: Disconnecting Equipment. . ." msgstr "" -#: ekos/guide/guide.cpp:66 +#: ekos/guide/guide.cpp:69 #, fuzzy, kde-format msgid "Calibration" msgstr "Bereken" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_DitherEnabled) -#: ekos/guide/guide.cpp:70 ekos/guide/opsdither.ui:102 +#: ekos/guide/guide.cpp:73 ekos/guide/opsdither.ui:102 #, fuzzy, kde-format msgid "Dither" msgstr "Vertoon naam" -#: ekos/guide/guide.cpp:74 +#: ekos/guide/guide.cpp:77 #, fuzzy, kde-format msgid "GPG RA Guider" msgstr "niks" -#: ekos/guide/guide.cpp:412 +#: ekos/guide/guide.cpp:415 #, kde-format msgid "" "PHD2's current camera: %1, is not connected to Ekos. The PHD2 Guide Star " "Image will be received, but the full external guide frames cannot." msgstr "" -#: ekos/guide/guide.cpp:422 +#: ekos/guide/guide.cpp:425 #, kde-format msgid "" "PHD2's current camera: %1, is connected to Ekos. You can select whether to " @@ -18413,196 +18950,196 @@ "using the SubFrame checkbox." msgstr "" -#: ekos/guide/guide.cpp:571 +#: ekos/guide/guide.cpp:574 #, kde-format msgid "Connection to the guide CCD is lost." msgstr "" -#: ekos/guide/guide.cpp:743 +#: ekos/guide/guide.cpp:746 #, fuzzy, kde-format msgid "Error: lost connection to CCD." msgstr "Bereken" -#: ekos/guide/guide.cpp:911 +#: ekos/guide/guide.cpp:930 #, kde-format msgid "Exposure timeout. Aborting Autoguide." msgstr "" -#: ekos/guide/guide.cpp:913 +#: ekos/guide/guide.cpp:932 #, kde-format msgid "Exposure timeout. Aborting Dithering." msgstr "" -#: ekos/guide/guide.cpp:915 +#: ekos/guide/guide.cpp:934 #, kde-format msgid "Exposure timeout. Aborting Calibration." msgstr "" -#: ekos/guide/guide.cpp:1272 +#: ekos/guide/guide.cpp:1291 #, kde-format msgid "The mount is parked. Unpark to start guiding." msgstr "" -#: ekos/guide/guide.cpp:1375 +#: ekos/guide/guide.cpp:1394 #, kde-format msgid "Pier side change detected. Clearing calibration." msgstr "" -#: ekos/guide/guide.cpp:1389 +#: ekos/guide/guide.cpp:1408 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Mount Mario" msgid "Mount is moving. Resetting calibration..." msgstr "Mount Mario" -#: ekos/guide/guide.cpp:1405 +#: ekos/guide/guide.cpp:1424 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Mount Mario" msgid "Mount is parking. Aborting guide..." msgstr "Mount Mario" -#: ekos/guide/guide.cpp:1407 +#: ekos/guide/guide.cpp:1426 #, fuzzy, kde-format msgid "Mount is slewing. Aborting guide..." msgstr "Invoer Keuse" -#: ekos/guide/guide.cpp:1470 +#: ekos/guide/guide.cpp:1489 #, fuzzy, kde-format msgid "Calibration is cleared." msgstr "Bereken" -#: ekos/guide/guide.cpp:1491 +#: ekos/guide/guide.cpp:1510 #, kde-format msgid "External guider connected." msgstr "" -#: ekos/guide/guide.cpp:1509 +#: ekos/guide/guide.cpp:1528 #, kde-format msgid "External guider disconnected." msgstr "" -#: ekos/guide/guide.cpp:1526 +#: ekos/guide/guide.cpp:1545 #, fuzzy, kde-format msgid "Calibration completed." msgstr "Bereken" -#: ekos/guide/guide.cpp:1544 +#: ekos/guide/guide.cpp:1563 #, fuzzy, kde-format msgid "Calibration started." msgstr "Bereken" -#: ekos/guide/guide.cpp:1551 +#: ekos/guide/guide.cpp:1570 #, fuzzy, kde-format msgid "Guiding resumed." msgstr "Soek Voorwerp" -#: ekos/guide/guide.cpp:1554 +#: ekos/guide/guide.cpp:1573 #, fuzzy, kde-format msgid "Autoguiding started." msgstr "Soek Voorwerp" -#: ekos/guide/guide.cpp:1566 +#: ekos/guide/guide.cpp:1585 #, fuzzy, kde-format msgid "Autoguiding aborted." msgstr "Soek Voorwerp" -#: ekos/guide/guide.cpp:1571 +#: ekos/guide/guide.cpp:1590 #, fuzzy, kde-format msgid "Guiding suspended." msgstr "Soek Voorwerp" -#: ekos/guide/guide.cpp:1580 +#: ekos/guide/guide.cpp:1599 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" msgid "Manual dithering in progress." msgstr "Belize Stad" -#: ekos/guide/guide.cpp:1584 +#: ekos/guide/guide.cpp:1603 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Belize City" msgid "Dithering in progress." msgstr "Belize Stad" -#: ekos/guide/guide.cpp:1588 +#: ekos/guide/guide.cpp:1607 #, kde-format msgid "Post-dither settling for %1 second..." msgid_plural "Post-dither settling for %1 seconds..." msgstr[0] "" msgstr[1] "" -#: ekos/guide/guide.cpp:1593 +#: ekos/guide/guide.cpp:1612 #, fuzzy, kde-format msgid "Dithering failed." msgstr "Vertoon naam" -#: ekos/guide/guide.cpp:1604 +#: ekos/guide/guide.cpp:1623 #, fuzzy, kde-format msgid "Dithering completed successfully." msgstr "Aarde koördinate" -#: ekos/guide/guide.cpp:1650 +#: ekos/guide/guide.cpp:1669 #, fuzzy, kde-format msgid "%1x%1 guide binning is not supported." msgstr "Planeet" -#: ekos/guide/guide.cpp:1672 +#: ekos/guide/guide.cpp:1691 #, kde-format msgid "Exposure failed. Restarting exposure..." msgstr "" -#: ekos/guide/guide.cpp:1798 +#: ekos/guide/guide.cpp:1817 #, kde-format msgid "Cannot change guider type while active." msgstr "" -#: ekos/guide/guide.cpp:1889 +#: ekos/guide/guide.cpp:1908 #, kde-format msgid "" "Warning: Reset Guiding Calibration is enabled. It is recommended to turn " "this option off for PHD2." msgstr "" -#: ekos/guide/guide.cpp:2272 +#: ekos/guide/guide.cpp:2292 #, fuzzy, kde-format msgid "Calibration failed to start." msgstr "Bereken" -#: ekos/guide/guide.cpp:2423 +#: ekos/guide/guide.cpp:2443 #, fuzzy, kde-format msgid "Auto star selected." msgstr "Nee Voorwerp gekose!" -#: ekos/guide/guide.cpp:2427 +#: ekos/guide/guide.cpp:2447 #, fuzzy, kde-format msgid "Failed to select an auto star." msgstr "Kon nie Open Lêer" -#: ekos/guide/guide.cpp:2436 +#: ekos/guide/guide.cpp:2456 #, fuzzy, kde-format msgid "Select a guide star to calibrate." msgstr "Invoer Keuse" -#: ekos/guide/guide.cpp:2682 +#: ekos/guide/guide.cpp:2702 #, kde-format msgid "x (pixels)" msgstr "" -#: ekos/guide/guide.cpp:2683 +#: ekos/guide/guide.cpp:2703 #, kde-format msgid "y (pixels)" msgstr "" -#: ekos/guide/guide.cpp:2794 ekos/guide/guide.cpp:2920 +#: ekos/guide/guide.cpp:2814 ekos/guide/guide.cpp:2940 #, kde-format msgid "" "The PHD2 camera is not available to Ekos, so you cannot see the captured " "images. But you will still see the Guide Star Image when you guide." msgstr "" -#: ekos/guide/guide.cpp:2798 ekos/guide/guide.cpp:2924 +#: ekos/guide/guide.cpp:2818 ekos/guide/guide.cpp:2944 #, kde-format msgid "" "To receive PHD2 images other than the Guide Star Image, SubFrame must be " @@ -18610,7 +19147,7 @@ "enable it before Guiding" msgstr "" -#: ekos/guide/guide.cpp:3083 +#: ekos/guide/guide.cpp:3103 #, kde-format msgid "Cannot change active optical train while PHD2 is connected" msgstr "" @@ -19086,20 +19623,20 @@ "arcseconds.

            " msgstr "" -#: ekos/guide/guidedriftgraph.cpp:66 +#: ekos/guide/guidedriftgraph.cpp:67 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Spain" msgid "drift (arcsec)" msgstr "Spanje" -#: ekos/guide/guidedriftgraph.cpp:67 +#: ekos/guide/guidedriftgraph.cpp:68 #, fuzzy, kde-format msgid "pulse (ms)" msgstr "Dag lengte:" -#: ekos/guide/guidedriftgraph.cpp:223 ekos/guide/guidedriftgraph.cpp:625 -#: ekos/guide/guidedriftgraph.cpp:700 +#: ekos/guide/guidedriftgraph.cpp:224 ekos/guide/guidedriftgraph.cpp:626 +#: ekos/guide/guidedriftgraph.cpp:701 #, kde-format msgctxt "" "Drift graphics tooltip; %1 is local time; %2 is RA deviation; %3 is DE " @@ -19110,8 +19647,8 @@ "tr>SNR: %5 \"" msgstr "" -#: ekos/guide/guidedriftgraph.cpp:242 ekos/guide/guidedriftgraph.cpp:641 -#: ekos/guide/guidedriftgraph.cpp:716 +#: ekos/guide/guidedriftgraph.cpp:243 ekos/guide/guidedriftgraph.cpp:642 +#: ekos/guide/guidedriftgraph.cpp:717 #, kde-format msgctxt "" "Drift graphics tooltip; %1 is local time; %2 is RA deviation; %3 is DE " @@ -19124,7 +19661,7 @@ "msDE Pulse: %7 ms" msgstr "" -#: ekos/guide/guidedriftgraph.cpp:281 ekos/guide/guidetargetplot.cpp:200 +#: ekos/guide/guidedriftgraph.cpp:282 ekos/guide/guidetargetplot.cpp:200 #: kstarslite/skyitems/horizonitem.cpp:29 #: skycomponents/horizoncomponent.cpp:118 skymapdrawabstract.cpp:184 #, kde-format @@ -19132,7 +19669,7 @@ msgid "N" msgstr "N" -#: ekos/guide/guidedriftgraph.cpp:289 ekos/guide/guidetargetplot.cpp:208 +#: ekos/guide/guidedriftgraph.cpp:290 ekos/guide/guidetargetplot.cpp:208 #: kstarslite/skyitems/horizonitem.cpp:25 #: skycomponents/horizoncomponent.cpp:114 #, kde-format @@ -19140,7 +19677,7 @@ msgid "S" msgstr "S" -#: ekos/guide/guidedriftgraph.cpp:297 ekos/guide/guidetargetplot.cpp:216 +#: ekos/guide/guidedriftgraph.cpp:298 ekos/guide/guidetargetplot.cpp:216 #: kstarslite/skyitems/horizonitem.cpp:27 #: skycomponents/horizoncomponent.cpp:116 #, kde-format @@ -19148,7 +19685,7 @@ msgid "W" msgstr "W" -#: ekos/guide/guidedriftgraph.cpp:305 ekos/guide/guidetargetplot.cpp:224 +#: ekos/guide/guidedriftgraph.cpp:306 ekos/guide/guidetargetplot.cpp:224 #: kstarslite/skyitems/horizonitem.cpp:23 #: skycomponents/horizoncomponent.cpp:112 #, kde-format @@ -19156,7 +19693,7 @@ msgid "E" msgstr "E" -#: ekos/guide/guidedriftgraph.cpp:453 +#: ekos/guide/guidedriftgraph.cpp:454 #, fuzzy, kde-format msgctxt "@title:window" msgid "Export Guide Data" @@ -19179,51 +19716,51 @@ msgid "Run" msgstr "Sun" -#: ekos/guide/internalguide/calibrationprocess.cpp:176 +#: ekos/guide/internalguide/calibrationprocess.cpp:178 #, kde-format msgid "RA drifting forward..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:180 +#: ekos/guide/internalguide/calibrationprocess.cpp:182 #, fuzzy, kde-format msgid "Guide Star found." msgstr "niks" -#: ekos/guide/internalguide/calibrationprocess.cpp:200 +#: ekos/guide/internalguide/calibrationprocess.cpp:202 #, fuzzy, kde-format msgid "Calibrating RA Out" msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:239 +#: ekos/guide/internalguide/calibrationprocess.cpp:241 #, fuzzy, kde-format msgid "RA drifting reverse..." msgstr "Spanje" -#: ekos/guide/internalguide/calibrationprocess.cpp:245 -#: ekos/guide/internalguide/calibrationprocess.cpp:383 -#: ekos/guide/internalguide/calibrationprocess.cpp:601 +#: ekos/guide/internalguide/calibrationprocess.cpp:247 +#: ekos/guide/internalguide/calibrationprocess.cpp:385 +#: ekos/guide/internalguide/calibrationprocess.cpp:603 #, kde-format msgid "" "Calibration rejected. Star drift is too short. Check for mount, cable, or " "backlash problems." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:248 +#: ekos/guide/internalguide/calibrationprocess.cpp:250 #, fuzzy, kde-format msgid "Calibration Failed: Drift too short." msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:277 +#: ekos/guide/internalguide/calibrationprocess.cpp:279 #, fuzzy, kde-format msgid "Calibrating RA In" msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:334 +#: ekos/guide/internalguide/calibrationprocess.cpp:336 #, fuzzy, kde-format msgid "Calibration Failed: couldn't reach start." msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:335 +#: ekos/guide/internalguide/calibrationprocess.cpp:337 #, kde-format msgid "" "Guide RA: Scope cannot reach the start point after %1 iteration. Possible " @@ -19234,48 +19771,48 @@ msgstr[0] "" msgstr[1] "" -#: ekos/guide/internalguide/calibrationprocess.cpp:354 +#: ekos/guide/internalguide/calibrationprocess.cpp:356 #, fuzzy, kde-format #| msgid "Info Box Background" msgid "DEC backlash..." msgstr "Inligting Boks Agtergrond" -#: ekos/guide/internalguide/calibrationprocess.cpp:367 -#: ekos/guide/internalguide/calibrationprocess.cpp:420 +#: ekos/guide/internalguide/calibrationprocess.cpp:369 +#: ekos/guide/internalguide/calibrationprocess.cpp:422 #, kde-format msgid "DEC drifting forward..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:386 -#: ekos/guide/internalguide/calibrationprocess.cpp:602 +#: ekos/guide/internalguide/calibrationprocess.cpp:388 +#: ekos/guide/internalguide/calibrationprocess.cpp:604 #, fuzzy, kde-format msgid "Calibration Failed: drift too short." msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:406 -#: ekos/guide/internalguide/calibrationprocess.cpp:423 +#: ekos/guide/internalguide/calibrationprocess.cpp:408 +#: ekos/guide/internalguide/calibrationprocess.cpp:425 #, fuzzy, kde-format msgid "Calibrating DEC Backlash" msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:432 +#: ekos/guide/internalguide/calibrationprocess.cpp:434 #, fuzzy, kde-format msgid "Calibrating DEC Out" msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:468 +#: ekos/guide/internalguide/calibrationprocess.cpp:470 #, kde-format msgid "DEC drifting reverse..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:478 -#: ekos/guide/internalguide/calibrationprocess.cpp:566 +#: ekos/guide/internalguide/calibrationprocess.cpp:480 +#: ekos/guide/internalguide/calibrationprocess.cpp:568 #, fuzzy, kde-format msgid "Calibration Failed: couldn't reach start point." msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:479 -#: ekos/guide/internalguide/calibrationprocess.cpp:568 +#: ekos/guide/internalguide/calibrationprocess.cpp:481 +#: ekos/guide/internalguide/calibrationprocess.cpp:570 #, kde-format msgid "" "Guide DEC: Scope cannot reach the start point after %1 iteration.\n" @@ -19286,86 +19823,86 @@ msgstr[0] "" msgstr[1] "" -#: ekos/guide/internalguide/calibrationprocess.cpp:511 +#: ekos/guide/internalguide/calibrationprocess.cpp:513 #, fuzzy, kde-format msgid "Calibrating DEC In" msgstr "Bereken" -#: ekos/guide/internalguide/calibrationprocess.cpp:584 +#: ekos/guide/internalguide/calibrationprocess.cpp:586 #, kde-format msgid "DEC swap enabled." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:586 +#: ekos/guide/internalguide/calibrationprocess.cpp:588 #, kde-format msgid "DEC swap disabled." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:590 +#: ekos/guide/internalguide/calibrationprocess.cpp:592 #, fuzzy, kde-format msgid "Calibration Successful" msgstr "Bereken" -#: ekos/guide/internalguide/internalguider.cpp:435 +#: ekos/guide/internalguide/internalguider.cpp:537 #, kde-format msgid "" "Warning: Dithering failed. Autoguiding shall continue as set in the options " "in case of dither failure." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:505 +#: ekos/guide/internalguide/internalguider.cpp:607 #, fuzzy, kde-format msgid "Warning: Manual Dithering failed." msgstr "Vertoon naam" -#: ekos/guide/internalguide/internalguider.cpp:555 +#: ekos/guide/internalguide/internalguider.cpp:657 #, kde-format msgid "%1 info are missing. Please set the values in INDI Control Panel." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:556 +#: ekos/guide/internalguide/internalguider.cpp:658 #, fuzzy, kde-format msgid "Missing Information" msgstr "Laaiïng van Informasie Urls" -#: ekos/guide/internalguide/internalguider.cpp:581 +#: ekos/guide/internalguide/internalguider.cpp:683 #, fuzzy, kde-format msgid "Guiding calibration restored" msgstr "Bereken" -#: ekos/guide/internalguide/internalguider.cpp:633 +#: ekos/guide/internalguide/internalguider.cpp:735 #, kde-format msgid "" "Lost track of the guide star. Try increasing the square size or reducing " "pulse duration." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:636 +#: ekos/guide/internalguide/internalguider.cpp:738 #, fuzzy, kde-format msgid "Guide Star lost." msgstr "niks" -#: ekos/guide/internalguide/internalguider.cpp:668 +#: ekos/guide/internalguide/internalguider.cpp:770 #, fuzzy, kde-format msgid "Guiding calibration failed" msgstr "Bereken" -#: ekos/guide/internalguide/internalguider.cpp:675 +#: ekos/guide/internalguide/internalguider.cpp:777 #, fuzzy, kde-format msgid "Guiding calibration completed successfully" msgstr "Bereken" -#: ekos/guide/internalguide/internalguider.cpp:999 +#: ekos/guide/internalguide/internalguider.cpp:1101 #, kde-format msgid "Lost track of the guide star. Searching for guide stars..." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:1001 +#: ekos/guide/internalguide/internalguider.cpp:1103 #, kde-format msgid "Delta RMS threshold value exceeded. Searching for guide stars..." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:1185 +#: ekos/guide/internalguide/internalguider.cpp:1287 #, fuzzy, kde-format msgid "Failed to find any suitable guide stars. Aborting..." msgstr "Kon nie Open Lêer" @@ -19471,7 +20008,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_CalibrationMaxMove) #. i18n: ectx: label, entry (CalibrationMaxMove), group (Guide) -#: ekos/guide/opscalibration.ui:122 kstars.kcfg:2489 +#: ekos/guide/opscalibration.ui:122 kstars.kcfg:2559 #, kde-format msgid "Maximum number of pixels the calibration should move (approximate)." msgstr "" @@ -19484,7 +20021,7 @@ #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_GuideAutoSquareSizeEnabled) #. i18n: ectx: label, entry (GuideAutoSquareSizeEnabled), group (Guide) -#: ekos/guide/opscalibration.ui:156 kstars.kcfg:2505 +#: ekos/guide/opscalibration.ui:156 kstars.kcfg:2575 #, fuzzy, kde-format msgid "Automatically select the square size based on the selected star width." msgstr "Wissel Sterre" @@ -19603,7 +20140,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ReverseDecOnPierSideChange) #. i18n: ectx: label, entry (ReverseDecOnPierSideChange), group (Scheduler) -#: ekos/guide/opscalibration.ui:411 kstars.kcfg:2770 +#: ekos/guide/opscalibration.ui:411 kstars.kcfg:2840 #, kde-format msgid "Reverse DEC on pier-side change when reusing calibration." msgstr "" @@ -19617,7 +20154,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_4) #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_DitherSettle) #. i18n: ectx: label, entry (DitherSettle), group (Guide) -#: ekos/guide/opsdither.ui:62 ekos/guide/opsdither.ui:147 kstars.kcfg:2565 +#: ekos/guide/opsdither.ui:62 ekos/guide/opsdither.ui:147 kstars.kcfg:2635 #, kde-format msgid "" "After dither is successful, wait for this many seconds before proceeding." @@ -19666,7 +20203,7 @@ #. i18n: ectx: property (text), widget (QLabel, label) #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, label_12) -#: ekos/guide/opsdither.ui:170 ekos/opsekos.ui:477 ekos/opsekos.ui:847 +#: ekos/guide/opsdither.ui:170 ekos/opsekos.ui:490 ekos/opsekos.ui:860 #, fuzzy, kde-format msgid "frames" msgstr "Ster Naam" @@ -20089,7 +20626,7 @@ msgid "Num Periods for Period Estimate" msgstr "" -#: ekos/guide/opsguide.cpp:41 +#: ekos/guide/opsguide.cpp:43 #, fuzzy, kde-format msgid "Guide Options Profile Editor" msgstr "Invoer Keuse" @@ -20314,7 +20851,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_MinDetectionsSEPMultistar) #. i18n: ectx: property (toolTip), widget (QLabel, label_22) #. i18n: ectx: label, entry (MinDetectionsSEPMultistar), group (Guide) -#: ekos/guide/opsguide.ui:524 ekos/guide/opsguide.ui:576 kstars.kcfg:2529 +#: ekos/guide/opsguide.ui:524 ekos/guide/opsguide.ui:576 kstars.kcfg:2599 #, kde-format msgid "Minimum number of stars detected for SEP MultiStar to initialize." msgstr "" @@ -20417,56 +20954,56 @@ msgid "Robotic (Experimental)" msgstr "" -#: ekos/manager.cpp:223 +#: ekos/manager.cpp:227 #, fuzzy, kde-format msgctxt "@title:window" msgid "Ekos - %1 Profile" msgstr "Invoer Keuse" -#: ekos/manager.cpp:233 +#: ekos/manager.cpp:237 #, kde-format msgid "Connection in progress. Click to abort." msgstr "" -#: ekos/manager.cpp:253 +#: ekos/manager.cpp:257 #, fuzzy, kde-format msgid "Logging" msgstr "Soek Voorwerp" -#: ekos/manager.cpp:340 +#: ekos/manager.cpp:344 #, kde-format msgid "Analyze" msgstr "" -#: ekos/manager.cpp:604 +#: ekos/manager.cpp:608 #, fuzzy, kde-format msgctxt "@title:window" msgid "Ekos" msgstr "Moore" -#: ekos/manager.cpp:809 ekos/manager.cpp:835 +#: ekos/manager.cpp:813 ekos/manager.cpp:839 #, kde-format msgid "Ekos requires at least one CCD or Guider to operate." msgstr "" -#: ekos/manager.cpp:897 +#: ekos/manager.cpp:901 #, kde-format msgid "" "Ekos detected that PTP Camera is running and may prevent a Canon or Nikon " "camera from connecting to Ekos. Do you want to quit PTP Camera now?" msgstr "" -#: ekos/manager.cpp:898 +#: ekos/manager.cpp:902 #, fuzzy, kde-format msgid "PTP Camera" msgstr "Cary" -#: ekos/manager.cpp:913 +#: ekos/manager.cpp:917 #, fuzzy, kde-format msgid "Starting INDI services..." msgstr "Spanje" -#: ekos/manager.cpp:944 +#: ekos/manager.cpp:948 #, kde-format msgid "" "Ekos detected an instance of INDI server running. Do you wish to shut down " @@ -20474,80 +21011,80 @@ msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, indiServerGroup) -#: ekos/manager.cpp:946 indi/opsindi.ui:375 +#: ekos/manager.cpp:950 indi/opsindi.ui:375 #, fuzzy, kde-format msgid "INDI Server" msgstr "St. Peter Poort" -#: ekos/manager.cpp:961 +#: ekos/manager.cpp:965 #, kde-format msgid "Connecting to remote INDI server at %1 on port %2 ..." msgstr "" -#: ekos/manager.cpp:981 +#: ekos/manager.cpp:985 #, kde-format msgid "Failed to start profile on remote INDI Web Manager." msgstr "" -#: ekos/manager.cpp:985 +#: ekos/manager.cpp:989 #, kde-format msgid "Starting profile on remote INDI Web Manager..." msgstr "" -#: ekos/manager.cpp:998 +#: ekos/manager.cpp:1002 #, kde-format msgid "Establishing communication with remote INDI Web Manager..." msgstr "" -#: ekos/manager.cpp:1018 +#: ekos/manager.cpp:1022 #, kde-format msgid "Warning: INDI Web Manager is not online." msgstr "" -#: ekos/manager.cpp:1041 +#: ekos/manager.cpp:1045 #, fuzzy, kde-format msgid "INDI services started on port %1." msgstr "St. Peter Poort" -#: ekos/manager.cpp:1044 +#: ekos/manager.cpp:1048 #, kde-format msgid "INDI services started on port %1. Please connect devices." msgstr "" -#: ekos/manager.cpp:1049 +#: ekos/manager.cpp:1053 #, kde-format msgid "" "INDI services started. Connection to remote INDI server %1:%2 is successful. " "Waiting for devices..." msgstr "" -#: ekos/manager.cpp:1059 +#: ekos/manager.cpp:1063 #, fuzzy, kde-format msgid "Failed to connect to local INDI server %1:%2" msgstr "Bereken" -#: ekos/manager.cpp:1061 +#: ekos/manager.cpp:1065 #, fuzzy, kde-format msgid "Failed to connect to remote INDI server %1:%2" msgstr "Bereken" -#: ekos/manager.cpp:1074 +#: ekos/manager.cpp:1078 #, fuzzy, kde-format msgid "Lost connection to local INDI server %1:%2" msgstr "Bereken" -#: ekos/manager.cpp:1076 +#: ekos/manager.cpp:1080 #, fuzzy, kde-format msgid "Lost connection to remote INDI server %1:%2" msgstr "Bereken" -#: ekos/manager.cpp:1153 +#: ekos/manager.cpp:1157 #, kde-format msgid "" "Failed to connect to %1. Please ensure device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1155 +#: ekos/manager.cpp:1159 #, kde-format msgid "" "Failed to connect to \n" @@ -20555,7 +21092,7 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1183 +#: ekos/manager.cpp:1187 #, kde-format msgid "" "Unable to establish:\n" @@ -20563,13 +21100,13 @@ "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1187 ekos/manager.cpp:1195 ekos/manager.cpp:1225 -#: ekos/manager.cpp:1233 +#: ekos/manager.cpp:1191 ekos/manager.cpp:1199 ekos/manager.cpp:1229 +#: ekos/manager.cpp:1237 #, fuzzy, kde-format msgid "Ekos startup error" msgstr "Soek Voorwerp" -#: ekos/manager.cpp:1191 +#: ekos/manager.cpp:1195 #, kde-format msgid "" "Unable to establish the following devices:\n" @@ -20577,7 +21114,7 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1221 +#: ekos/manager.cpp:1225 #, kde-format msgid "" "Unable to remotely establish:\n" @@ -20585,7 +21122,7 @@ "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1229 +#: ekos/manager.cpp:1233 #, kde-format msgid "" "Unable to remotely establish the following devices:\n" @@ -20593,136 +21130,136 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1284 +#: ekos/manager.cpp:1288 #, kde-format msgid "Connecting INDI devices..." msgstr "" -#: ekos/manager.cpp:1295 +#: ekos/manager.cpp:1299 #, kde-format msgid "Disconnecting INDI devices..." msgstr "" -#: ekos/manager.cpp:1333 +#: ekos/manager.cpp:1337 #, kde-format msgid "INDI services stopped." msgstr "" -#: ekos/manager.cpp:1407 +#: ekos/manager.cpp:1411 #, fuzzy, kde-format msgid "Remote devices established." msgstr "Beeld" -#: ekos/manager.cpp:1409 +#: ekos/manager.cpp:1413 #, kde-format msgid "Remote devices established. Please connect devices." msgstr "" -#: ekos/manager.cpp:1470 +#: ekos/manager.cpp:1474 #, kde-format msgid "" "%1 failed to connect.\n" "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1477 +#: ekos/manager.cpp:1481 #, fuzzy, kde-format msgid "%1 is disconnected." msgstr "Bereken" -#: ekos/manager.cpp:1496 ekos/manager.cpp:1505 ekos/manager.cpp:1538 +#: ekos/manager.cpp:1500 ekos/manager.cpp:1509 ekos/manager.cpp:1542 #: indi/indistd.cpp:689 #, kde-format msgid "%1 is online." msgstr "" -#: ekos/manager.cpp:1513 +#: ekos/manager.cpp:1517 #, kde-format msgid "%1 filter is online." msgstr "" -#: ekos/manager.cpp:1522 +#: ekos/manager.cpp:1526 #, fuzzy, kde-format msgid "%1 focuser is online." msgstr "Bereken" -#: ekos/manager.cpp:1529 +#: ekos/manager.cpp:1533 #, fuzzy, kde-format msgid "Rotator %1 is online." msgstr "Bereken" -#: ekos/manager.cpp:1545 +#: ekos/manager.cpp:1549 #, fuzzy, kde-format msgid "%1 Weather is online." msgstr "Bereken" -#: ekos/manager.cpp:1552 +#: ekos/manager.cpp:1556 #, fuzzy, kde-format msgid "%1 GPS is online." msgstr "Bereken" -#: ekos/manager.cpp:1561 +#: ekos/manager.cpp:1565 #, fuzzy, kde-format msgid "%1 Dust cap is online." msgstr "Bereken" -#: ekos/manager.cpp:1568 +#: ekos/manager.cpp:1572 #, fuzzy, kde-format msgid "%1 Light box is online." msgstr "Bereken" -#: ekos/manager.cpp:1700 +#: ekos/manager.cpp:1706 #, kde-format msgid "%1 is offline." msgstr "" -#: ekos/manager.cpp:1947 +#: ekos/manager.cpp:1953 #, kde-format msgctxt "Charge-Coupled Device" msgid "CCD" msgstr "" -#: ekos/manager.cpp:2217 +#: ekos/manager.cpp:2233 #, kde-format msgid "Guider port from %1 is ready." msgstr "" -#: ekos/manager.cpp:2406 +#: ekos/manager.cpp:2422 #, kde-format msgid "Are you sure you want to delete the profile?" msgstr "" -#: ekos/manager.cpp:2407 +#: ekos/manager.cpp:2423 #, fuzzy, kde-format msgid "Confirm Delete" msgstr "Fout Uitveeïng Lêer" -#: ekos/manager.cpp:2459 +#: ekos/manager.cpp:2475 #, kde-format msgid "Site location updated to %1." msgstr "" -#: ekos/manager.cpp:2461 +#: ekos/manager.cpp:2477 #, kde-format msgid "Failed to update site location to %1. City not found." msgstr "" -#: ekos/manager.cpp:2710 +#: ekos/manager.cpp:2726 #, kde-format msgid "Enabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2718 +#: ekos/manager.cpp:2734 #, kde-format msgid "Disabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2746 +#: ekos/manager.cpp:2762 #, kde-format msgid "Re-enabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2758 +#: ekos/manager.cpp:2774 #, kde-format msgid "Re-disabling debug logging for %1..." msgstr "" @@ -21000,127 +21537,127 @@ msgid "Meridian Flip Status" msgstr "Wissel Sterre" -#: ekos/mount/mount.cpp:94 +#: ekos/mount/mount.cpp:96 #, kde-format msgid "Are you sure you want to clear all mount configurations?" msgstr "" -#: ekos/mount/mount.cpp:95 +#: ekos/mount/mount.cpp:97 #, fuzzy, kde-format msgid "Mount Configuration" msgstr "Laaiïng van Informasie Urls" #. i18n: ectx: property (text), widget (QPushButton, mountToolBoxB) -#: ekos/mount/mount.cpp:146 ekos/mount/mount.ui:582 +#: ekos/mount/mount.cpp:148 ekos/mount/mount.ui:582 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Senegal" msgid "Mount Control" msgstr "Senegal" -#: ekos/mount/mount.cpp:371 +#: ekos/mount/mount.cpp:373 #, kde-format msgid "" "GPS driver detected. KStars and mount time and location settings are now " "synced to the GPS driver." msgstr "" -#: ekos/mount/mount.cpp:386 +#: ekos/mount/mount.cpp:388 #, kde-format msgid "GPS is detected. Do you want to switch time and location source to GPS?" msgstr "" -#: ekos/mount/mount.cpp:387 +#: ekos/mount/mount.cpp:389 #, fuzzy, kde-format msgid "GPS Settings" msgstr "niks" -#: ekos/mount/mount.cpp:515 +#: ekos/mount/mount.cpp:517 #, kde-format msgid "Are you sure you want to turn off mount tracking?" msgstr "" -#: ekos/mount/mount.cpp:516 +#: ekos/mount/mount.cpp:518 #, fuzzy, kde-format msgid "Mount Tracking" msgstr "Stop Horlosie" -#: ekos/mount/mount.cpp:603 +#: ekos/mount/mount.cpp:605 #, kde-format msgid "" "Telescope altitude is below minimum altitude limit of %1. Aborting motion..." msgstr "" -#: ekos/mount/mount.cpp:619 +#: ekos/mount/mount.cpp:621 #, kde-format msgid "" "Telescope altitude is above maximum altitude limit of %1. Aborting motion..." msgstr "" -#: ekos/mount/mount.cpp:671 +#: ekos/mount/mount.cpp:673 #, kde-format msgid "" "Telescope hour angle is more than the maximum hour angle of %1. Aborting " "motion..." msgstr "" -#: ekos/mount/mount.cpp:813 +#: ekos/mount/mount.cpp:815 #, kde-format msgid "Meridian flip set inactive during polar alignment." msgstr "" -#: ekos/mount/mount.cpp:827 +#: ekos/mount/mount.cpp:829 #, kde-format msgid "Polar alignment motions finished, meridian flip activated." msgstr "" -#: ekos/mount/mount.cpp:850 +#: ekos/mount/mount.cpp:852 #, kde-format msgctxt "Message shown in Ekos Mount module" msgid "%1" msgstr "" -#: ekos/mount/mount.cpp:1448 +#: ekos/mount/mount.cpp:1450 #, fuzzy, kde-format msgid "Alignment Model cleared." msgstr "Bereken" -#: ekos/mount/mount.cpp:1452 +#: ekos/mount/mount.cpp:1454 #, fuzzy, kde-format msgid "Failed to clear Alignment Model." msgstr "Vertoon naam" -#: ekos/mount/mount.cpp:1562 ekos/scheduler/scheduler.cpp:5364 +#: ekos/mount/mount.cpp:1564 ekos/scheduler/schedulerprocess.cpp:2141 #, kde-format msgid "Mount already parked." msgstr "" -#: ekos/mount/mount.cpp:1587 +#: ekos/mount/mount.cpp:1589 #, fuzzy, kde-format msgid "Parking time cannot be in the past." msgstr "Planeet" -#: ekos/mount/mount.cpp:1596 +#: ekos/mount/mount.cpp:1598 #, kde-format msgid "Parking time must be within 24 hours of current time." msgstr "" -#: ekos/mount/mount.cpp:1601 +#: ekos/mount/mount.cpp:1603 #, kde-format msgid "Warning! Parking time is more than 12 hours away." msgstr "" -#: ekos/mount/mount.cpp:1603 +#: ekos/mount/mount.cpp:1605 #, kde-format msgid "Caution: do not use Auto Park while scheduler is active." msgstr "" -#: ekos/mount/mount.cpp:1622 +#: ekos/mount/mount.cpp:1624 #, fuzzy, kde-format msgid "Parking timer is up." msgstr "Planeet" -#: ekos/mount/mount.cpp:1631 +#: ekos/mount/mount.cpp:1633 #, fuzzy, kde-format msgid "Starting auto park..." msgstr "Spanje" @@ -21328,7 +21865,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, minAltLabel) #. i18n: ectx: whatsthis, entry (MinimumAltLimit), group (Mount) -#: ekos/mount/mount.ui:903 kstars.kcfg:1651 +#: ekos/mount/mount.ui:903 kstars.kcfg:1675 #, kde-format msgid "" "Minimum telescope altitude limit. If the telescope is below this limit, it " @@ -21771,7 +22308,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, weatherAlertSchedulerCB) #. i18n: ectx: property (text), widget (QCheckBox, weatherWarningSchedulerCB) #: ekos/observatory/observatory.ui:951 ekos/observatory/observatory.ui:1086 -#: ekos/scheduler/scheduler.cpp:2008 ekos/scheduler/scheduler.cpp:2034 +#: ekos/scheduler/scheduler.cpp:1796 ekos/scheduler/scheduler.cpp:1822 #, fuzzy, kde-format #| msgid "Start Clock" msgid "Stop Scheduler" @@ -21839,7 +22376,8 @@ msgid "Slaving deactivated." msgstr "Vertoon naam" -#: ekos/observatory/observatorydomemodel.cpp:103 +#: ekos/observatory/observatorydomemodel.cpp:103 fitsviewer/fitstab.cpp:623 +#: fitsviewer/fitstab.cpp:642 #, fuzzy, kde-format msgid "Aborting..." msgstr "Bereken" @@ -21937,7 +22475,7 @@ #. i18n: ectx: property (toolTip), widget (QRadioButton, kcfg_EkosTopIcons) #. i18n: ectx: label, entry (EkosTopIcons), group (Ekos) -#: ekos/opsekos.ui:116 kstars.kcfg:1558 +#: ekos/opsekos.ui:116 kstars.kcfg:1582 #, kde-format msgid "Ekos modules icons are placed on the top of pages" msgstr "" @@ -22130,16 +22668,30 @@ msgid "Remember job progress" msgstr "" +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_GreedyScheduling) +#: ekos/opsekos.ui:412 +#, fuzzy, kde-format +msgid "" +"

            When checked the scheduler tries to run lower priority " +"jobs when no higher priority job can run. Recommended.

            " +msgstr "Soek Voorwerp" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GreedyScheduling) +#: ekos/opsekos.ui:415 +#, kde-format +msgid "Use greedy scheduling" +msgstr "" + #. i18n: ectx: property (text), widget (QLabel, label_10) #. i18n: ectx: property (text), widget (QLabel, DefaultDSSImageSizeUnitLabel) #. i18n: ectx: property (text), widget (QLabel, DSSPaddingUnitLabel) -#: ekos/opsekos.ui:436 options/opsadvanced.ui:163 options/opsadvanced.ui:205 +#: ekos/opsekos.ui:449 options/opsadvanced.ui:163 options/opsadvanced.ui:205 #, kde-format msgid "arcminutes" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_ForceAlignmentBeforeJob) -#: ekos/opsekos.ui:450 +#: ekos/opsekos.ui:463 #, kde-format msgid "" "If Align is enabled, scheduler would initiate a realignment procedure before " @@ -22147,14 +22699,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForceAlignmentBeforeJob) -#: ekos/opsekos.ui:453 +#: ekos/opsekos.ui:466 #, fuzzy, kde-format msgid "Force re-alignment before re-starting jobs" msgstr "Wissel Sterre" #. i18n: ectx: property (toolTip), widget (QLabel, label_6) #. i18n: ectx: label, entry (AlignCheckFrequency), group (Scheduler) -#: ekos/opsekos.ui:460 kstars.kcfg:2853 +#: ekos/opsekos.ui:473 kstars.kcfg:2927 #, kde-format msgid "" "When calculating position after captures, compute it every Nth capture. Set " @@ -22162,20 +22714,20 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_6) -#: ekos/opsekos.ui:463 +#: ekos/opsekos.ui:476 #, fuzzy, kde-format msgid "Verify captured image position every" msgstr "Steek weg objekte terwyl beweeg" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelBeforeJob) -#: ekos/opsekos.ui:470 +#: ekos/opsekos.ui:483 #, fuzzy, kde-format msgid "Reset mount model before starting each job" msgstr "Wissel Sterre" #. i18n: ectx: property (toolTip), widget (QLabel, label_8) #. i18n: ectx: label, entry (AlignCheckThreshold), group (Scheduler) -#: ekos/opsekos.ui:484 kstars.kcfg:2857 +#: ekos/opsekos.ui:497 kstars.kcfg:2931 #, kde-format msgid "" "If captured position exceeds target position by more this many arcminutes, " @@ -22183,19 +22735,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/opsekos.ui:487 +#: ekos/opsekos.ui:500 #, kde-format msgid "Reset pipeline if verified image delta exceeds" msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelOnAlignFail) -#: ekos/opsekos.ui:494 +#: ekos/opsekos.ui:507 #, fuzzy, kde-format msgid "Reset mount model on alignment failure" msgstr "Vertoon naam" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_RealignAfterCalibrationFailure) -#: ekos/opsekos.ui:511 +#: ekos/opsekos.ui:524 #, kde-format msgid "" "

            If guiding calibration fails then restart alignment " @@ -22205,14 +22757,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_RealignAfterCalibrationFailure) -#: ekos/opsekos.ui:514 +#: ekos/opsekos.ui:527 #, fuzzy, kde-format msgid "Restart alignment on guiding calibration failure" msgstr "Spanje" #. i18n: ectx: property (title), widget (QGroupBox, groupBox) #. i18n: ectx: property (title), widget (QGroupBox, ObsListMiscOptions) -#: ekos/opsekos.ui:559 options/opsadvanced.ui:924 +#: ekos/opsekos.ui:572 options/opsadvanced.ui:924 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Monaco" @@ -22220,13 +22772,13 @@ msgstr "Monako" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_GuidingSettle) -#: ekos/opsekos.ui:612 +#: ekos/opsekos.ui:625 #, kde-format msgid "Wait this many seconds after guiding is resumed before starting capture" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label) -#: ekos/opsekos.ui:619 +#: ekos/opsekos.ui:632 #, kde-format msgid "" "Maximum acceptable difference between requested and measured temperature set " @@ -22235,13 +22787,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/opsekos.ui:622 +#: ekos/opsekos.ui:635 #, fuzzy, kde-format msgid "Temperature threshold:" msgstr "Koördinate" #. i18n: ectx: property (toolTip), widget (QLabel, label_13) -#: ekos/opsekos.ui:645 +#: ekos/opsekos.ui:658 #, kde-format msgid "" "Wait this many seconds after guiding is resumed to stabilize the guiding " @@ -22249,25 +22801,25 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_13) -#: ekos/opsekos.ui:648 +#: ekos/opsekos.ui:661 #, fuzzy, kde-format msgid "Guiding settle:" msgstr "niks" #. i18n: ectx: property (toolTip), widget (QLabel, label_15) -#: ekos/opsekos.ui:655 +#: ekos/opsekos.ui:668 #, kde-format msgid "Cover or uncover telescope dialog timeout in seconds" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_15) -#: ekos/opsekos.ui:658 +#: ekos/opsekos.ui:671 #, fuzzy, kde-format msgid "Dialog timeout:" msgstr "Tyd" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AlwaysResetSequenceWhenStarting) -#: ekos/opsekos.ui:687 +#: ekos/opsekos.ui:700 #, kde-format msgid "" "

            When starting to process a sequence list, reset all " @@ -22276,43 +22828,43 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AlwaysResetSequenceWhenStarting) -#: ekos/opsekos.ui:690 +#: ekos/opsekos.ui:703 #, fuzzy, kde-format msgid "Always reset sequence when starting" msgstr "Bereken" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelAfterMeridian) -#: ekos/opsekos.ui:700 +#: ekos/opsekos.ui:713 #, fuzzy, kde-format msgid "Reset mount model after meridian flip" msgstr "Wissel Sterre" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForcedFlip) -#: ekos/opsekos.ui:707 +#: ekos/opsekos.ui:720 #, kde-format msgid "Use flip command if supported by mount" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_useSummaryPreview) -#: ekos/opsekos.ui:719 +#: ekos/opsekos.ui:732 #, fuzzy, kde-format msgid "Display received FITS in the Summary screen preview window." msgstr " Welkom na K-sterre " #. i18n: ectx: property (text), widget (QCheckBox, kcfg_useSummaryPreview) -#: ekos/opsekos.ui:722 +#: ekos/opsekos.ui:735 #, kde-format msgid "Summary screen preview" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) -#: ekos/opsekos.ui:747 +#: ekos/opsekos.ui:760 #, kde-format msgid "DSLR" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_ForceDSLRPresets) -#: ekos/opsekos.ui:765 +#: ekos/opsekos.ui:778 #, kde-format msgid "" "

            Force exposure times to align with DSLR exposure " @@ -22321,44 +22873,44 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForceDSLRPresets) -#: ekos/opsekos.ui:768 +#: ekos/opsekos.ui:781 #, kde-format msgid "Force DSLR presets" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_useDSLRImageViewer) -#: ekos/opsekos.ui:775 +#: ekos/opsekos.ui:788 #, fuzzy, kde-format msgid "Display received DSLR images in the Image Viewer" msgstr " Welkom na K-sterre " #. i18n: ectx: property (text), widget (QCheckBox, kcfg_useDSLRImageViewer) -#: ekos/opsekos.ui:778 +#: ekos/opsekos.ui:791 #, fuzzy, kde-format msgid "DSLR image viewer" msgstr " Welkom na K-sterre " #. i18n: ectx: property (toolTip), widget (QPushButton, clearDSLRInfoB) -#: ekos/opsekos.ui:785 +#: ekos/opsekos.ui:798 #, kde-format msgid "Clear saved DSLR sizes" msgstr "" #. i18n: ectx: property (text), widget (QPushButton, clearDSLRInfoB) -#: ekos/opsekos.ui:788 +#: ekos/opsekos.ui:801 #, fuzzy, kde-format msgid "Clear DSLR Info" msgstr "Maak skoon" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/opsekos.ui:821 +#: ekos/opsekos.ui:834 #, fuzzy, kde-format #| msgid "open cluster" msgid "In-Sequence Focus" msgstr "open klaster" #. i18n: ectx: property (toolTip), widget (QLabel, label_5) -#: ekos/opsekos.ui:881 +#: ekos/opsekos.ui:894 #, kde-format msgid "" "

            Set HFR Threshold percentage gain. When an autofocus " @@ -22371,19 +22923,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/opsekos.ui:884 +#: ekos/opsekos.ui:897 #, fuzzy, kde-format msgid "HFR threshold modifier:" msgstr "Leon" #. i18n: ectx: property (toolTip), widget (QLabel, label_11) -#: ekos/opsekos.ui:891 +#: ekos/opsekos.ui:904 #, kde-format msgid "Run in-sequence HFR check after this many frames." msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_11) -#: ekos/opsekos.ui:894 +#: ekos/opsekos.ui:907 #, fuzzy, kde-format #| msgid "open cluster" msgid "In-sequence HFR check:" @@ -22391,13 +22943,13 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_InSequenceCheckFrames) #. i18n: ectx: label, entry (InSequenceCheckFrames), group (Capture) -#: ekos/opsekos.ui:901 kstars.kcfg:1846 +#: ekos/opsekos.ui:914 kstars.kcfg:1870 #, kde-format msgid "Run In-Sequence HFR check after this many frames." msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_UseMedianFocus) -#: ekos/opsekos.ui:916 +#: ekos/opsekos.ui:929 #, kde-format msgid "" "

            Calculate median focus value after each autofocus " @@ -22408,13 +22960,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseMedianFocus) -#: ekos/opsekos.ui:919 +#: ekos/opsekos.ui:932 #, kde-format msgid "Use median focus" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_SaveHFRToFile) -#: ekos/opsekos.ui:926 +#: ekos/opsekos.ui:939 #, kde-format msgid "" "

            In-sequence HFR threshold value controls when the " @@ -22428,7 +22980,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_SaveHFRToFile) -#: ekos/opsekos.ui:929 +#: ekos/opsekos.ui:942 #, kde-format msgid "Save sequence HFR value to file" msgstr "" @@ -22486,7 +23038,8 @@ msgstr "Planeet" #. i18n: ectx: property (title), widget (QGroupBox, profileGroup) -#: ekos/profileeditor.ui:32 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverProfileLabel) +#: ekos/profileeditor.ui:32 fitsviewer/platesolve.ui:360 #, fuzzy, kde-format msgid "Profile" msgstr "Strand" @@ -23257,7 +23810,7 @@ msgstr "Invoer Keuse" #: ekos/scheduler/framingassistant.cpp:539 -#: ekos/scheduler/framingassistantui.cpp:555 +#: ekos/scheduler/framingassistantui.cpp:556 #, fuzzy, kde-format msgid " Scheduler job" msgid_plural " Scheduler jobs" @@ -23265,7 +23818,7 @@ msgstr[1] "Sidereal tyd" #: ekos/scheduler/framingassistant.cpp:541 -#: ekos/scheduler/framingassistantui.cpp:557 +#: ekos/scheduler/framingassistantui.cpp:558 #, kde-format msgid " (first only)" msgstr "" @@ -23954,46 +24507,46 @@ msgid "Create scheduler jobs to execute the mosaic plan" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:692 ekos/scheduler/scheduler.cpp:1097 +#: ekos/scheduler/framingassistantui.cpp:694 ekos/scheduler/scheduler.cpp:934 #, fuzzy, kde-format #| msgid "open cluster" msgctxt "@title:window" msgid "Select Sequence Queue" msgstr "open klaster" -#: ekos/scheduler/framingassistantui.cpp:694 ekos/scheduler/scheduler.cpp:1099 +#: ekos/scheduler/framingassistantui.cpp:696 ekos/scheduler/scheduler.cpp:936 #, kde-format msgid "Ekos Sequence Queue (*.esq)" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:706 +#: ekos/scheduler/framingassistantui.cpp:708 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Mosaic Import" msgstr "Invoer Keuse" -#: ekos/scheduler/framingassistantui.cpp:708 +#: ekos/scheduler/framingassistantui.cpp:710 #, kde-format msgid "Telescopius CSV (*.csv)" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:767 +#: ekos/scheduler/framingassistantui.cpp:769 #, fuzzy, kde-format msgid "Import must contain center coordinates." msgstr "Ekwatoriale Koördinate" -#: ekos/scheduler/framingassistantui.cpp:846 +#: ekos/scheduler/framingassistantui.cpp:848 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Jobs Directory" msgstr "Bereken" -#: ekos/scheduler/greedyscheduler.cpp:158 +#: ekos/scheduler/greedyscheduler.cpp:159 #, fuzzy, kde-format msgid "Job '%1' has no more batches remaining." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:480 +#: ekos/scheduler/scheduler.cpp:309 #, kde-format msgid "" "Job scheduler list.\n" @@ -24001,29 +24554,29 @@ "Double click to edit a job with the left-hand fields." msgstr "" -#: ekos/scheduler/scheduler.cpp:487 +#: ekos/scheduler/scheduler.cpp:316 #, kde-format msgid "" "Remove selected job from the observation list.\n" "Job properties are copied in the edition fields before removal." msgstr "" -#: ekos/scheduler/scheduler.cpp:491 +#: ekos/scheduler/scheduler.cpp:320 #, kde-format msgid "Move selected job one line up in the list.\n" msgstr "" -#: ekos/scheduler/scheduler.cpp:494 +#: ekos/scheduler/scheduler.cpp:323 #, kde-format msgid "Move selected job one line down in the list.\n" msgstr "" -#: ekos/scheduler/scheduler.cpp:498 +#: ekos/scheduler/scheduler.cpp:327 #, kde-format msgid "Reset state and force reevaluation of all observation jobs." msgstr "" -#: ekos/scheduler/scheduler.cpp:502 +#: ekos/scheduler/scheduler.cpp:331 #, kde-format msgid "" "Reset state and sort observation jobs per altitude and movement in sky, " @@ -24034,84 +24587,84 @@ "evaluates jobs." msgstr "" -#: ekos/scheduler/scheduler.cpp:733 ekos/scheduler/scheduler.cpp:6145 +#: ekos/scheduler/scheduler.cpp:570 ekos/scheduler/scheduler.cpp:3925 #, kde-format msgid "" "Warning: The Classic scheduler algorithm has been retired. Switching you to " "the Greedy algorithm." msgstr "" -#: ekos/scheduler/scheduler.cpp:974 +#: ekos/scheduler/scheduler.cpp:811 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select FITS/XISF Image" msgstr "Laaiïng van K-sterre..." -#: ekos/scheduler/scheduler.cpp:1028 +#: ekos/scheduler/scheduler.cpp:865 #, kde-format msgid "FITS header: cannot find OBJCTRA (%1)." msgstr "" -#: ekos/scheduler/scheduler.cpp:1047 +#: ekos/scheduler/scheduler.cpp:884 #, kde-format msgid "FITS header: cannot find OBJCTDEC (%1)." msgstr "" -#: ekos/scheduler/scheduler.cpp:1106 +#: ekos/scheduler/scheduler.cpp:944 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Startup Script" msgstr "Invoer Keuse" -#: ekos/scheduler/scheduler.cpp:1108 ekos/scheduler/scheduler.cpp:1122 +#: ekos/scheduler/scheduler.cpp:946 ekos/scheduler/scheduler.cpp:961 #, fuzzy, kde-format msgid "Script (*)" msgstr "Ster Naam" -#: ekos/scheduler/scheduler.cpp:1120 +#: ekos/scheduler/scheduler.cpp:959 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Shutdown Script" msgstr "Kies/Verander Koördinate" -#: ekos/scheduler/scheduler.cpp:1222 +#: ekos/scheduler/scheduler.cpp:993 #, kde-format msgid "Warning: You cannot add or modify a job while the scheduler is running." msgstr "" -#: ekos/scheduler/scheduler.cpp:1228 +#: ekos/scheduler/scheduler.cpp:999 #, fuzzy, kde-format msgid "Warning: Target name is required." msgstr "Aarde koördinate" -#: ekos/scheduler/scheduler.cpp:1234 +#: ekos/scheduler/scheduler.cpp:1005 #, kde-format msgid "Warning: Sequence file is required." msgstr "" -#: ekos/scheduler/scheduler.cpp:1241 +#: ekos/scheduler/scheduler.cpp:1012 #, fuzzy, kde-format msgid "Warning: Target coordinates are required." msgstr "Aarde koördinate" -#: ekos/scheduler/scheduler.cpp:1251 +#: ekos/scheduler/scheduler.cpp:1022 #, fuzzy, kde-format msgid "Warning: RA value %1 is invalid." msgstr "Datum:" -#: ekos/scheduler/scheduler.cpp:1257 +#: ekos/scheduler/scheduler.cpp:1028 #, fuzzy, kde-format msgid "Warning: DEC value %1 is invalid." msgstr "Datum:" -#: ekos/scheduler/scheduler.cpp:1359 +#: ekos/scheduler/scheduler.cpp:1128 #, kde-format msgid "" "Warning: job '%1' at row %2 has a duplicate target at row %3, the scheduler " "may consider the same storage for captures." msgstr "" -#: ekos/scheduler/scheduler.cpp:1367 +#: ekos/scheduler/scheduler.cpp:1136 #, kde-format msgid "" "Warning: jobs '%1' at row %2 and %3 probably require a different repeat " @@ -24119,395 +24672,242 @@ "disable option 'Remember job progress')" msgstr "" -#: ekos/scheduler/scheduler.cpp:1375 +#: ekos/scheduler/scheduler.cpp:1144 #, kde-format msgid "Skipped checking for duplicates." msgstr "" -#: ekos/scheduler/scheduler.cpp:1539 +#: ekos/scheduler/scheduler.cpp:1334 #, fuzzy, kde-format #| msgctxt "Country name (optional, but should be translated)" #| msgid "Spain" msgid "%1 %2 %3" msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:1549 +#: ekos/scheduler/scheduler.cpp:1344 #, kde-format msgid "Warning: you cannot add or modify a job while the scheduler is running." msgstr "" -#: ekos/scheduler/scheduler.cpp:1612 +#: ekos/scheduler/scheduler.cpp:1407 #, kde-format msgid "Use edition fields to create a new job in the observation list." msgstr "" -#: ekos/scheduler/scheduler.cpp:1877 +#: ekos/scheduler/scheduler.cpp:1672 #, fuzzy, kde-format msgid "Job '%1' has not been processed upon scheduler stop, marking aborted." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:1884 +#: ekos/scheduler/scheduler.cpp:1679 #, fuzzy, kde-format msgid "Scheduler aborted." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:1943 +#: ekos/scheduler/scheduler.cpp:1731 #, kde-format msgid "Scheduler is in shutdown until next job is ready" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, startB) -#: ekos/scheduler/scheduler.cpp:1969 ekos/scheduler/scheduler.ui:1124 +#: ekos/scheduler/scheduler.cpp:1757 ekos/scheduler/scheduler.ui:1124 #, fuzzy, kde-format #| msgid "Start Clock" msgid "Start Scheduler" msgstr "Begin Horlosie" -#: ekos/scheduler/scheduler.cpp:1990 +#: ekos/scheduler/scheduler.cpp:1777 #, fuzzy, kde-format msgid "Warning: startup script URL %1 is not valid." msgstr "Datum:" -#: ekos/scheduler/scheduler.cpp:1998 +#: ekos/scheduler/scheduler.cpp:1785 #, kde-format msgid "Warning: shutdown script URL %1 is not valid." msgstr "" -#: ekos/scheduler/scheduler.cpp:2027 +#: ekos/scheduler/scheduler.cpp:1815 #, fuzzy, kde-format msgid "Scheduler started." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:2047 +#: ekos/scheduler/scheduler.cpp:1835 #, fuzzy, kde-format msgid "Scheduler resuming." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:2060 +#: ekos/scheduler/scheduler.cpp:1848 #, fuzzy, kde-format msgid "Scheduler pause planned..." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:2064 +#: ekos/scheduler/scheduler.cpp:1852 #, fuzzy, kde-format msgid "Resume Scheduler" msgstr "Sidereal tyd" -#: ekos/scheduler/scheduler.cpp:2073 +#: ekos/scheduler/scheduler.cpp:1861 #, fuzzy, kde-format msgid "Scheduler paused." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:2095 +#: ekos/scheduler/scheduler.cpp:1883 #, kde-format msgid "No job running" msgstr "" -#: ekos/scheduler/scheduler.cpp:2163 +#: ekos/scheduler/scheduler.cpp:1953 #, kde-format msgid "No jobs left in the scheduler queue after evaluating." msgstr "" -#: ekos/scheduler/scheduler.cpp:2171 +#: ekos/scheduler/scheduler.cpp:1961 #, kde-format msgid "" "Only aborted jobs left in the scheduler queue after evaluating, rescheduling " "those." msgstr "" -#: ekos/scheduler/scheduler.cpp:2185 +#: ekos/scheduler/scheduler.cpp:1975 #, kde-format msgid "No jobs scheduled." msgstr "" -#: ekos/scheduler/scheduler.cpp:2199 +#: ekos/scheduler/scheduler.cpp:1989 #, fuzzy, kde-format msgid "Scheduler is awake." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:2205 +#: ekos/scheduler/scheduler.cpp:1995 #, kde-format msgid "Scheduler is awake. Jobs shall be started when ready..." msgstr "" -#: ekos/scheduler/scheduler.cpp:2207 +#: ekos/scheduler/scheduler.cpp:1997 #, kde-format msgid "Scheduler is awake. Jobs shall be started when scheduler is resumed." msgstr "" -#: ekos/scheduler/scheduler.cpp:2271 +#: ekos/scheduler/scheduler.cpp:2061 #, fuzzy, kde-format msgid "Ekos job started (%1)" msgstr "Soek Voorwerp" -#: ekos/scheduler/scheduler.cpp:2310 -#, fuzzy, kde-format -msgid "Ekos started." -msgstr "Soek Voorwerp" - -#: ekos/scheduler/scheduler.cpp:2319 -#, fuzzy, kde-format -msgid "Starting Ekos failed. Retrying..." -msgstr "Kon nie Open Lêer" - -#: ekos/scheduler/scheduler.cpp:2325 -#, fuzzy, kde-format -msgid "Starting Ekos failed." -msgstr "Vertoon naam" - -#: ekos/scheduler/scheduler.cpp:2336 -#, fuzzy, kde-format -msgid "Starting Ekos timed out. Retrying..." -msgstr "Kon nie Open Lêer" - -#: ekos/scheduler/scheduler.cpp:2348 -#, fuzzy, kde-format -msgid "Starting Ekos timed out." -msgstr "Soek Voorwerp" - -#: ekos/scheduler/scheduler.cpp:2359 -#, fuzzy, kde-format -msgid "Ekos stopped." -msgstr "Soek Voorwerp" - -#: ekos/scheduler/scheduler.cpp:2410 -#, fuzzy, kde-format -msgid "INDI devices connected." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:2417 -#, kde-format -msgid "One or more INDI devices failed to connect. Retrying..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2423 -#, kde-format -msgid "" -"One or more INDI devices failed to connect. Check INDI control panel for " -"details." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2432 -#, kde-format -msgid "One or more INDI devices timed out. Retrying..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2439 -#, kde-format -msgid "" -"One or more INDI devices timed out. Check INDI control panel for details." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2450 -#, fuzzy, kde-format -msgid "INDI devices disconnected." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:2466 -#, kde-format -msgid "Warning: dome device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2471 -#, kde-format -msgid "Dome unpark required but dome is not yet ready." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2481 -#, kde-format -msgid "Warning: mount device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2496 -#, kde-format -msgid "Warning: cap device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2547 -#, kde-format -msgid "Observatory is in the startup process" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2560 -#, kde-format -msgid "Ekos is already started, skipping startup script..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2657 +#: ekos/scheduler/scheduler.cpp:2076 #, kde-format msgid "Observatory is in the shutdown process" msgstr "" -#: ekos/scheduler/scheduler.cpp:2673 -#, fuzzy, kde-format -msgid "Warming up CCD..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:2703 -#, kde-format -msgid "Warning: Bypassing parking procedures, no INDI connection." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2827 -#, kde-format -msgid "park/unpark wait procedure failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2838 -#, fuzzy, kde-format -msgid "Executing script %1..." -msgstr "Sonsondergang:" - -#: ekos/scheduler/scheduler.cpp:2873 -#, kde-format -msgid "Startup script failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2878 -#, kde-format -msgid "Shutdown script failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2908 -#, fuzzy, kde-format -msgid "Shutdown complete." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:2910 -#, kde-format -msgid "Shutdown procedure failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2983 +#: ekos/scheduler/scheduler.cpp:2161 #, kde-format msgid "Starting job sequence iteration #%1" msgstr "" -#: ekos/scheduler/scheduler.cpp:3108 ekos/scheduler/scheduler.cpp:6917 +#: ekos/scheduler/scheduler.cpp:2291 ekos/scheduler/schedulerprocess.cpp:1806 #, fuzzy, kde-format msgid "Warning: job '%1' alignment procedure failed, marking aborted." msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:3136 +#: ekos/scheduler/scheduler.cpp:2319 #, fuzzy, kde-format msgid "Warning: job '%1' capture procedure failed, marking aborted." msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:3163 ekos/scheduler/scheduler.cpp:7149 +#: ekos/scheduler/scheduler.cpp:2346 ekos/scheduler/schedulerprocess.cpp:1929 #, fuzzy, kde-format msgid "Warning: job '%1' focusing procedure failed, marking aborted." msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:3187 ekos/scheduler/scheduler.cpp:6990 +#: ekos/scheduler/scheduler.cpp:2370 ekos/scheduler/schedulerprocess.cpp:1877 #, fuzzy, kde-format msgid "Warning: job '%1' guiding procedure failed, marking aborted." msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:3213 +#: ekos/scheduler/scheduler.cpp:2396 #, fuzzy, kde-format msgid "" "Warning: job '%1' lost connection to the mount, attempting to reconnect." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:3233 +#: ekos/scheduler/scheduler.cpp:2416 #, fuzzy, kde-format msgid "Warning: job '%1' lost connection to the dome, attempting to reconnect." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:3271 +#: ekos/scheduler/scheduler.cpp:2454 #, kde-format msgid "Guiding already running, directly start capturing." msgstr "" -#: ekos/scheduler/scheduler.cpp:3283 +#: ekos/scheduler/scheduler.cpp:2466 #, kde-format msgid "" "Job '%1' is proceeding directly to capture stage because only calibration " "frames are pending." msgstr "" -#: ekos/scheduler/scheduler.cpp:3452 +#: ekos/scheduler/scheduler.cpp:2582 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Scheduler List" msgstr "Voeg by na Lys" -#: ekos/scheduler/scheduler.cpp:3803 +#: ekos/scheduler/scheduler.cpp:2931 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save Ekos Scheduler List" msgstr "Voeg by na Lys" -#: ekos/scheduler/scheduler.cpp:3822 +#: ekos/scheduler/scheduler.cpp:2950 #, fuzzy, kde-format msgid "Failed to save scheduler list" msgstr "Kon nie Open Lêer" -#: ekos/scheduler/scheduler.cpp:4013 -#, fuzzy, kde-format -msgid "Scheduler list saved to %1" -msgstr "Ongeldige Url" - -#: ekos/scheduler/scheduler.cpp:4056 -#, fuzzy, kde-format -msgid "Job '%1' is slewing to target." -msgstr "Invoer Keuse" - -#: ekos/scheduler/scheduler.cpp:4099 -#, kde-format -msgid "Warning: job '%1' is unable to proceed with autofocus, not supported." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4182 -#, kde-format -msgid "Job '%1' is focusing." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4232 +#: ekos/scheduler/scheduler.cpp:3013 #, kde-format msgid "Job '%1' is terminated due to errors." msgstr "" -#: ekos/scheduler/scheduler.cpp:4234 +#: ekos/scheduler/scheduler.cpp:3015 #, kde-format msgid "Job '%1' is aborted." msgstr "" -#: ekos/scheduler/scheduler.cpp:4247 +#: ekos/scheduler/scheduler.cpp:3028 #, kde-format msgid "Waiting %1 seconds to restart job '%2'." msgstr "" -#: ekos/scheduler/scheduler.cpp:4253 +#: ekos/scheduler/scheduler.cpp:3034 #, fuzzy, kde-format msgid "Scheduler waits for a retry." msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:4290 +#: ekos/scheduler/scheduler.cpp:3071 #, fuzzy, kde-format msgid "Job '%1' is complete." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:4335 +#: ekos/scheduler/scheduler.cpp:3116 #, fuzzy, kde-format msgid "Job '%1' is complete after #%2 batch." msgid_plural "Job '%1' is complete after #%2 batches." msgstr[0] "Bereken" msgstr[1] "Bereken" -#: ekos/scheduler/scheduler.cpp:4384 ekos/scheduler/scheduler.cpp:4427 +#: ekos/scheduler/scheduler.cpp:3165 ekos/scheduler/scheduler.cpp:3208 #, kde-format msgid "Job '%1' is repeating, #%2 batch remaining." msgid_plural "Job '%1' is repeating, #%2 batches remaining." msgstr[0] "" msgstr[1] "" -#: ekos/scheduler/scheduler.cpp:4431 +#: ekos/scheduler/scheduler.cpp:3212 #, kde-format msgid "Job '%1' is repeating, looping indefinitely." msgstr "" -#: ekos/scheduler/scheduler.cpp:4451 +#: ekos/scheduler/scheduler.cpp:3232 #, kde-format msgid "Job '%1' stopping, reached completion time with #%2 batch done." msgid_plural "" @@ -24515,7 +24915,7 @@ msgstr[0] "" msgstr[1] "" -#: ekos/scheduler/scheduler.cpp:4481 +#: ekos/scheduler/scheduler.cpp:3262 #, kde-format msgid "Job '%1' completed #%2 batch before completion time, restarted." msgid_plural "" @@ -24523,569 +24923,162 @@ msgstr[0] "" msgstr[1] "" -#: ekos/scheduler/scheduler.cpp:4526 -#, fuzzy, kde-format -msgid "Warning: job '%1' target FITS file does not exist." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:4539 -#, kde-format -msgid "Warning: job '%1' loadAndSlew request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4550 -#, fuzzy, kde-format -msgid "Warning: job '%1' loadAndSlew request failed." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:4557 -#, fuzzy, kde-format -msgid "Job '%1' is plate solving %2." -msgstr "Laaiïng van K-sterre..." - -#: ekos/scheduler/scheduler.cpp:4572 -#, kde-format -msgid "Warning: job '%1' setTargetCoords request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4589 -#, kde-format -msgid "" -"Warning: job '%1' setTargetPositionAngle request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4603 -#, fuzzy, kde-format -msgid "Warning: job '%1' captureAndSolve request received DBUS error: %2" -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:4614 -#, fuzzy, kde-format -msgid "Warning: job '%1' captureAndSolve request failed." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:4620 -#, fuzzy, kde-format -msgid "Job '%1' is capturing and plate solving." -msgstr "Laaiïng van K-sterre..." - -#: ekos/scheduler/scheduler.cpp:4635 -#, fuzzy, kde-format -msgid "Guiding already running for %1 ..." -msgstr "Soek Voorwerp" - -#: ekos/scheduler/scheduler.cpp:4663 -#, fuzzy, kde-format -msgid "Starting guiding procedure for %1 ..." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:4747 -#, kde-format -msgid "Ekos job (%1) - Capture started" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4750 -#, kde-format -msgid "Job '%1' capture is in progress (batch #%2)..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4752 -#, fuzzy, kde-format -msgid "Job '%1' capture is in progress..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:4978 +#: ekos/scheduler/scheduler.cpp:3469 #, fuzzy, kde-format msgid "Warning: job '%1' has inaccessible sequence '%2', marking invalid." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:5049 +#: ekos/scheduler/scheduler.cpp:3541 #, kde-format msgid "" "Warning: Job '%1' has its focus step disabled, periodic and/or HFR " "procedures currently set in its sequence will not occur." msgstr "" -#: ekos/scheduler/scheduler.cpp:5077 +#: ekos/scheduler/scheduler.cpp:3569 #, kde-format msgid "Job '%1' %2x%3\" %4" msgstr "" -#: ekos/scheduler/scheduler.cpp:5338 -#, kde-format -msgid "Mount park requested but no mounts detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5397 -#, fuzzy, kde-format -msgid "Parking mount in progress..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:5410 -#, kde-format -msgid "Mount unpark requested but no mounts detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5437 -#, kde-format -msgid "Mount already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5514 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Mount parked." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:5529 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Mount unparked." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:5541 -#, kde-format -msgid "" -"Warning: mount unpark operation timed out on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5547 -#, kde-format -msgid "Warning: mount unpark operation timed out on last attempt." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5561 -#, kde-format -msgid "" -"Warning: mount park operation timed out on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5567 -#, kde-format -msgid "Warning: mount park operation timed out on last attempt." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5579 ekos/scheduler/scheduler.cpp:5607 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Mount unparking error." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:5587 -#, kde-format -msgid "" -"Warning: mount park operation failed on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5593 ekos/scheduler/scheduler.cpp:5601 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Mount parking error." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:5697 -#, kde-format -msgid "Dome park requested but no domes detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5722 -#, fuzzy, kde-format -msgid "Parking dome..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:5728 -#, kde-format -msgid "Dome already parked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5738 -#, kde-format -msgid "Dome unpark requested but no domes detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5760 -#, fuzzy, kde-format -msgid "Unparking dome..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:5766 -#, kde-format -msgid "Dome already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5798 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Belize City" -msgid "Dome parked." -msgstr "Belize Stad" - -#: ekos/scheduler/scheduler.cpp:5809 -#, kde-format -msgid "Dome unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5821 ekos/scheduler/scheduler.cpp:6016 -#, kde-format -msgid "Operation timeout. Restarting operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5836 -#, fuzzy, kde-format -msgid "Dome parking failed. Restarting operation..." -msgstr "Kon nie Open Lêer" - -#: ekos/scheduler/scheduler.cpp:5841 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Belize City" -msgid "Dome parking error." -msgstr "Belize Stad" - -#: ekos/scheduler/scheduler.cpp:5850 -#, fuzzy, kde-format -msgid "Dome unparking failed. Restarting operation..." -msgstr "Stoor Beeld" - -#: ekos/scheduler/scheduler.cpp:5855 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Belize City" -msgid "Dome unparking error." -msgstr "Belize Stad" - -#: ekos/scheduler/scheduler.cpp:5893 -#, kde-format -msgid "Dust cover park requested but no dust covers detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5917 -#, fuzzy, kde-format -msgid "Parking Cap..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:5923 -#, kde-format -msgid "Cap already parked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5932 -#, kde-format -msgid "Dust cover unpark requested but no dust covers detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5956 -#, fuzzy, kde-format -msgid "Unparking cap..." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:5962 -#, kde-format -msgid "Cap already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5994 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Belize City" -msgid "Cap parked." -msgstr "Belize Stad" - -#: ekos/scheduler/scheduler.cpp:6004 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Cap unparked." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:6029 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Belize City" -msgid "Cap parking error." -msgstr "Belize Stad" - -#: ekos/scheduler/scheduler.cpp:6034 -#, fuzzy, kde-format -#| msgctxt "City name (optional, probably does not need a translation)" -#| msgid "Mount Mario" -msgid "Cap unparking error." -msgstr "Mount Mario" - -#: ekos/scheduler/scheduler.cpp:6254 +#: ekos/scheduler/scheduler.cpp:4034 #, kde-format msgid "" "Turning off astronomial twilight check may cause the observatory to run " "during daylight. This can cause irreversible damage to your equipment!" msgstr "" -#: ekos/scheduler/scheduler.cpp:6256 +#: ekos/scheduler/scheduler.cpp:4036 #, kde-format msgid "Astronomial Twilight Warning" msgstr "" -#: ekos/scheduler/scheduler.cpp:6270 -#, fuzzy, kde-format -msgid "Manual startup procedure completed successfully." -msgstr "Aarde koördinate" - -#: ekos/scheduler/scheduler.cpp:6272 -#, kde-format -msgid "Manual startup procedure terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6287 -#, kde-format -msgid "Warning: executing startup procedure manually..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6296 -#, kde-format -msgid "Are you sure you want to execute the startup procedure manually?" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6340 -#, fuzzy, kde-format -#| msgid "Start Clock" -msgid "Startup procedure terminated." -msgstr "Begin Horlosie" - -#: ekos/scheduler/scheduler.cpp:6353 -#, fuzzy, kde-format -msgid "Manual shutdown procedure completed successfully." -msgstr "Aarde koördinate" - -#: ekos/scheduler/scheduler.cpp:6359 -#, kde-format -msgid "Manual shutdown procedure terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6374 -#, kde-format -msgid "Warning: executing shutdown procedure manually..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6382 -#, kde-format -msgid "Are you sure you want to execute the shutdown procedure manually?" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6429 -#, kde-format -msgid "Shutdown procedure terminated." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6459 +#: ekos/scheduler/scheduler.cpp:4061 #, fuzzy, kde-format msgid "Unable to open sequence queue file '%1'" msgstr "Kon nie Open Lêer" -#: ekos/scheduler/scheduler.cpp:6597 +#: ekos/scheduler/scheduler.cpp:4199 #, fuzzy, kde-format msgid "" "Sleeping for %1 on simulation clock update until next observation job is " "ready..." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:6882 -#, fuzzy, kde-format -msgid "Job '%1' alignment is complete." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:6901 -#, fuzzy, kde-format -msgid "Warning: job '%1' alignment failed." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:6907 -#, kde-format -msgid "" -"Warning: job '%1' forcing mount model reset after failing alignment #%2." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6912 ekos/scheduler/scheduler.cpp:6978 -#, fuzzy, kde-format -msgid "Restarting %1 alignment procedure..." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:6950 -#, fuzzy, kde-format -msgid "Job '%1' guiding is in progress." -msgstr "Planeet" - -#: ekos/scheduler/scheduler.cpp:6962 -#, fuzzy, kde-format -msgid "Warning: job '%1' guiding failed." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:6964 -#, fuzzy, kde-format -msgid "Warning: job '%1' calibration failed." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:6983 -#, fuzzy, kde-format -msgid "Job '%1' is guiding, guiding procedure will be restarted in %2 seconds." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:7042 +#: ekos/scheduler/scheduler.cpp:4510 #, fuzzy, kde-format msgid "Warning: job '%1' failed to capture target." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:7055 +#: ekos/scheduler/scheduler.cpp:4523 #, fuzzy, kde-format msgid "" "Job '%1' is capturing, is restarting its guiding procedure (attempt #%2 of " "%3)." msgstr "Spanje" -#: ekos/scheduler/scheduler.cpp:7063 +#: ekos/scheduler/scheduler.cpp:4532 #, fuzzy, kde-format msgid "Warning: job '%1' failed its capture procedure, restarting capture." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:7069 +#: ekos/scheduler/scheduler.cpp:4538 #, fuzzy, kde-format msgid "Warning: job '%1' failed its capture procedure, marking aborted." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:7078 +#: ekos/scheduler/scheduler.cpp:4547 #, kde-format msgid "Ekos job (%1) - Capture finished" msgstr "" -#: ekos/scheduler/scheduler.cpp:7125 -#, fuzzy, kde-format -msgid "Job '%1' focusing is complete." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:7135 -#, fuzzy, kde-format -msgid "Warning: job '%1' focusing failed." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:7139 -#, fuzzy, kde-format -msgid "Job '%1' is restarting its focusing procedure." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:7180 -#, fuzzy, kde-format -msgid "Job '%1' slew is complete." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:7186 -#, kde-format -msgid "Warning: job '%1' slew failed, marking terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:7192 -#, fuzzy, kde-format -msgid "Warning: job '%1' found not slewing, restarting." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:7205 -#, fuzzy, kde-format -msgid "Job '%1' repositioning is complete." -msgstr "Bereken" - -#: ekos/scheduler/scheduler.cpp:7211 -#, kde-format -msgid "" -"Warning: job '%1' repositioning failed, marking terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:7217 -#, fuzzy, kde-format -msgid "Warning: job '%1' found not repositioning, restarting." -msgstr "Spanje" - -#: ekos/scheduler/scheduler.cpp:7238 +#: ekos/scheduler/scheduler.cpp:4591 #, kde-format msgid "Weather conditions are OK." msgstr "" -#: ekos/scheduler/scheduler.cpp:7242 +#: ekos/scheduler/scheduler.cpp:4595 #, kde-format msgid "Warning: weather conditions are in the WARNING zone." msgstr "" -#: ekos/scheduler/scheduler.cpp:7246 +#: ekos/scheduler/scheduler.cpp:4599 #, kde-format msgid "Caution: weather conditions are in the DANGER zone!" msgstr "" -#: ekos/scheduler/scheduler.cpp:7268 +#: ekos/scheduler/scheduler.cpp:4621 #, kde-format msgid "Weather conditions in warning zone" msgstr "" -#: ekos/scheduler/scheduler.cpp:7277 +#: ekos/scheduler/scheduler.cpp:4630 #, kde-format msgid "Weather conditions are critical. Observatory shutdown is imminent" msgstr "" -#: ekos/scheduler/scheduler.cpp:7297 +#: ekos/scheduler/scheduler.cpp:4651 #, kde-format msgid "Starting shutdown procedure due to severe weather." msgstr "" -#: ekos/scheduler/scheduler.cpp:7325 +#: ekos/scheduler/scheduler.cpp:4679 #, kde-format msgid "" "Job '%1' scheduled for execution at %2. Observatory scheduled for shutdown " "until next job is ready." msgstr "" -#: ekos/scheduler/scheduler.cpp:7348 +#: ekos/scheduler/scheduler.cpp:4702 #, kde-format msgid "" "Job '%1' scheduled for execution at %2. Parking the mount until the job is " "ready." msgstr "" -#: ekos/scheduler/scheduler.cpp:7358 +#: ekos/scheduler/scheduler.cpp:4712 #, fuzzy, kde-format msgid "Sleeping until observation job %1 is ready at %2..." msgstr "Bereken" -#: ekos/scheduler/scheduler.cpp:7360 +#: ekos/scheduler/scheduler.cpp:4714 #, fuzzy, kde-format msgid "Scheduler is in sleep mode" msgstr "Ongeldige Url" -#: ekos/scheduler/scheduler.cpp:7368 +#: ekos/scheduler/scheduler.cpp:4722 #, kde-format msgid "" "Warning: Job '%1' is %2 away from now, you may want to enable Preemptive " "Shutdown." msgstr "" -#: ekos/scheduler/scheduler.cpp:7528 +#: ekos/scheduler/scheduler.cpp:4820 #, fuzzy, kde-format #| msgctxt "the time at which an object falls below the horizon" #| msgid "Set time: %1" msgid "Solver timed out: %1s %2" msgstr "Stel tyd: %1" -#: ekos/scheduler/scheduler.cpp:7530 +#: ekos/scheduler/scheduler.cpp:4822 #, fuzzy, kde-format msgid "Solver failed: %1s %2" msgstr "Soek Voorwerp" -#: ekos/scheduler/scheduler.cpp:7565 +#: ekos/scheduler/scheduler.cpp:4857 #, kde-format msgid "Captured frame is %1 arcminutes away from target, re-aligning..." msgstr "" +#: ekos/scheduler/scheduler.cpp:5151 +#, fuzzy, kde-format +msgid "Manual startup procedure completed successfully." +msgstr "Aarde koördinate" + +#: ekos/scheduler/scheduler.cpp:5155 +#, kde-format +msgid "Manual startup procedure terminated due to errors." +msgstr "" + #. i18n: ectx: property (title), widget (QGroupBox, jobSequenceGroup) #: ekos/scheduler/scheduler.ui:38 #, fuzzy, kde-format @@ -25107,7 +25100,8 @@ msgstr "Bereken" #. i18n: ectx: property (text), widget (QLabel, rotationLabel) -#: ekos/scheduler/scheduler.ui:85 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverAngleLabel) +#: ekos/scheduler/scheduler.ui:85 fitsviewer/platesolve.ui:318 #, kde-format msgid "PA" msgstr "" @@ -25646,12 +25640,12 @@ msgid "UnCap" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:360 +#: ekos/scheduler/schedulerjob.cpp:336 #, kde-format msgid "Ekos job failed (%1)" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:404 +#: ekos/scheduler/schedulerjob.cpp:380 #, kde-format msgid "" "Current status of job '%1', managed by the Scheduler.\n" @@ -25663,7 +25657,7 @@ "were stored, including repeats." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:415 +#: ekos/scheduler/schedulerjob.cpp:391 #, kde-format msgid "" "Current altitude of the target of job '%1'.\n" @@ -25671,7 +25665,7 @@ "A setting target is indicated with an arrow going down." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:425 +#: ekos/scheduler/schedulerjob.cpp:401 #, kde-format msgid "" "Startup time for job '%1', as estimated by the Scheduler.\n" @@ -25680,7 +25674,7 @@ "symbol. " msgstr "" -#: ekos/scheduler/schedulerjob.cpp:435 +#: ekos/scheduler/schedulerjob.cpp:411 #, kde-format msgid "" "Completion time for job '%1', as estimated by the Scheduler.\n" @@ -25689,7 +25683,7 @@ "before completion.\n" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:445 +#: ekos/scheduler/schedulerjob.cpp:421 #, kde-format msgid "" "Count of captures stored for job '%1', based on its sequence job.\n" @@ -25697,52 +25691,616 @@ "complete the job." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:614 +#: ekos/scheduler/schedulerjob.cpp:590 #, kde-format msgid "Evaluating" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:615 +#: ekos/scheduler/schedulerjob.cpp:591 #, fuzzy, kde-format msgid "Scheduled" msgstr "Sidereal tyd" -#: ekos/scheduler/schedulerjob.cpp:617 +#: ekos/scheduler/schedulerjob.cpp:593 #, fuzzy, kde-format #| msgid "Invalid URL" msgid "Invalid" msgstr "Ongeldige Url" -#: ekos/scheduler/schedulerjob.cpp:639 +#: ekos/scheduler/schedulerjob.cpp:615 #, fuzzy, kde-format msgid "Slew complete" msgstr "Bereken" -#: ekos/scheduler/schedulerjob.cpp:643 +#: ekos/scheduler/schedulerjob.cpp:619 #, fuzzy, kde-format msgid "Focus complete" msgstr "Bereken" -#: ekos/scheduler/schedulerjob.cpp:645 +#: ekos/scheduler/schedulerjob.cpp:621 #, fuzzy, kde-format msgid "Align complete" msgstr "Bereken" -#: ekos/scheduler/schedulerjob.cpp:646 +#: ekos/scheduler/schedulerjob.cpp:622 #, fuzzy, kde-format msgid "Repositioning" msgstr "Bereken" -#: ekos/scheduler/schedulerjob.cpp:647 +#: ekos/scheduler/schedulerjob.cpp:623 #, fuzzy, kde-format msgid "Repositioning complete" msgstr "Bereken" -#: ekos/scheduler/schedulerjob.cpp:650 +#: ekos/scheduler/schedulerjob.cpp:626 #, fuzzy, kde-format msgid "Guiding complete" msgstr "Bereken" +#: ekos/scheduler/schedulerprocess.cpp:68 +#, fuzzy, kde-format +msgid "Job '%1' is slewing to target." +msgstr "Invoer Keuse" + +#: ekos/scheduler/schedulerprocess.cpp:108 +#, kde-format +msgid "Warning: job '%1' is unable to proceed with autofocus, not supported." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:174 +#, kde-format +msgid "Job '%1' is focusing." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:201 +#, fuzzy, kde-format +msgid "Warning: job '%1' target FITS file does not exist." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:213 +#, kde-format +msgid "Warning: job '%1' loadAndSlew request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:224 +#, fuzzy, kde-format +msgid "Warning: job '%1' loadAndSlew request failed." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:230 +#, fuzzy, kde-format +msgid "Job '%1' is plate solving %2." +msgstr "Laaiïng van K-sterre..." + +#: ekos/scheduler/schedulerprocess.cpp:244 +#, kde-format +msgid "Warning: job '%1' setTargetCoords request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:260 +#, kde-format +msgid "" +"Warning: job '%1' setTargetPositionAngle request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:273 +#, fuzzy, kde-format +msgid "Warning: job '%1' captureAndSolve request received DBUS error: %2" +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:284 +#, fuzzy, kde-format +msgid "Warning: job '%1' captureAndSolve request failed." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:290 +#, fuzzy, kde-format +msgid "Job '%1' is capturing and plate solving." +msgstr "Laaiïng van K-sterre..." + +#: ekos/scheduler/schedulerprocess.cpp:306 +#, fuzzy, kde-format +msgid "Guiding already running for %1, starting next scheduler action..." +msgstr "Soek Voorwerp" + +#: ekos/scheduler/schedulerprocess.cpp:330 +#, fuzzy, kde-format +msgid "Starting guiding procedure for %1 ..." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:439 +#, kde-format +msgid "Ekos job (%1) - Capture started" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:442 +#, kde-format +msgid "Job '%1' capture is in progress (batch #%2)..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:445 +#, fuzzy, kde-format +msgid "Job '%1' capture is in progress..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:467 +#, fuzzy, kde-format +msgid "Executing script %1..." +msgstr "Sonsondergang:" + +#: ekos/scheduler/schedulerprocess.cpp:512 +#, fuzzy, kde-format +msgid "Ekos started." +msgstr "Soek Voorwerp" + +#: ekos/scheduler/schedulerprocess.cpp:521 +#, fuzzy, kde-format +msgid "Starting Ekos failed. Retrying..." +msgstr "Kon nie Open Lêer" + +#: ekos/scheduler/schedulerprocess.cpp:526 +#, fuzzy, kde-format +msgid "Starting Ekos failed." +msgstr "Vertoon naam" + +#: ekos/scheduler/schedulerprocess.cpp:537 +#, fuzzy, kde-format +msgid "Starting Ekos timed out. Retrying..." +msgstr "Kon nie Open Lêer" + +#: ekos/scheduler/schedulerprocess.cpp:547 +#, fuzzy, kde-format +msgid "Starting Ekos timed out." +msgstr "Soek Voorwerp" + +#: ekos/scheduler/schedulerprocess.cpp:558 +#, fuzzy, kde-format +msgid "Ekos stopped." +msgstr "Soek Voorwerp" + +#: ekos/scheduler/schedulerprocess.cpp:601 +#, fuzzy, kde-format +msgid "INDI devices connected." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:608 +#, kde-format +msgid "One or more INDI devices failed to connect. Retrying..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:613 +#, kde-format +msgid "" +"One or more INDI devices failed to connect. Check INDI control panel for " +"details." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:622 +#, kde-format +msgid "One or more INDI devices timed out. Retrying..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:628 +#, kde-format +msgid "" +"One or more INDI devices timed out. Check INDI control panel for details." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:639 +#, fuzzy, kde-format +msgid "INDI devices disconnected." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:655 +#, kde-format +msgid "Warning: dome device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:660 +#, kde-format +msgid "Dome unpark required but dome is not yet ready." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:670 +#, kde-format +msgid "Warning: mount device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:685 +#, kde-format +msgid "Warning: cap device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:747 +#, fuzzy, kde-format +msgid "Shutdown complete." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:749 +#, kde-format +msgid "Shutdown procedure failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:853 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Belize City" +msgid "Cap parked." +msgstr "Belize Stad" + +#: ekos/scheduler/schedulerprocess.cpp:863 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Cap unparked." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:875 +#: ekos/scheduler/schedulerprocess.cpp:1104 +#, kde-format +msgid "Operation timeout. Restarting operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:888 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Belize City" +msgid "Cap parking error." +msgstr "Belize Stad" + +#: ekos/scheduler/schedulerprocess.cpp:893 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Cap unparking error." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:935 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Mount parked." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:950 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Mount unparked." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:962 +#, kde-format +msgid "" +"Warning: mount unpark operation timed out on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:968 +#, kde-format +msgid "Warning: mount unpark operation timed out on last attempt." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:982 +#, kde-format +msgid "" +"Warning: mount park operation timed out on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:989 +#, kde-format +msgid "Warning: mount park operation timed out on last attempt." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1001 +#: ekos/scheduler/schedulerprocess.cpp:1030 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Mount unparking error." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:1009 +#, kde-format +msgid "" +"Warning: mount park operation failed on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1016 +#: ekos/scheduler/schedulerprocess.cpp:1024 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Mount Mario" +msgid "Mount parking error." +msgstr "Mount Mario" + +#: ekos/scheduler/schedulerprocess.cpp:1081 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Belize City" +msgid "Dome parked." +msgstr "Belize Stad" + +#: ekos/scheduler/schedulerprocess.cpp:1092 +#, kde-format +msgid "Dome unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1119 +#, fuzzy, kde-format +msgid "Dome parking failed. Restarting operation..." +msgstr "Kon nie Open Lêer" + +#: ekos/scheduler/schedulerprocess.cpp:1124 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Belize City" +msgid "Dome parking error." +msgstr "Belize Stad" + +#: ekos/scheduler/schedulerprocess.cpp:1133 +#, fuzzy, kde-format +msgid "Dome unparking failed. Restarting operation..." +msgstr "Stoor Beeld" + +#: ekos/scheduler/schedulerprocess.cpp:1138 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Belize City" +msgid "Dome unparking error." +msgstr "Belize Stad" + +#: ekos/scheduler/schedulerprocess.cpp:1161 +#, kde-format +msgid "Observatory is in the startup process" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1174 +#, kde-format +msgid "Ekos is already started, skipping startup script..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1270 +#, fuzzy, kde-format +msgid "Warming up CCD..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:1303 +#, kde-format +msgid "Warning: Bypassing parking procedures, no INDI connection." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1427 +#, kde-format +msgid "park/unpark wait procedure failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1446 +#, kde-format +msgid "Warning: executing startup procedure manually..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1453 +#, kde-format +msgid "Are you sure you want to execute the startup procedure manually?" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1497 +#, fuzzy, kde-format +#| msgid "Start Clock" +msgid "Startup procedure terminated." +msgstr "Begin Horlosie" + +#: ekos/scheduler/schedulerprocess.cpp:1511 +#, kde-format +msgid "Warning: executing shutdown procedure manually..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1517 +#, kde-format +msgid "Are you sure you want to execute the shutdown procedure manually?" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1562 +#, kde-format +msgid "Shutdown procedure terminated." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1746 +#, fuzzy, kde-format +msgid "Scheduler list saved to %1" +msgstr "Ongeldige Url" + +#: ekos/scheduler/schedulerprocess.cpp:1772 +#, fuzzy, kde-format +msgid "Job '%1' alignment is complete." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:1791 +#, fuzzy, kde-format +msgid "Warning: job '%1' alignment failed." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1797 +#, kde-format +msgid "" +"Warning: job '%1' forcing mount model reset after failing alignment #%2." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1801 +#: ekos/scheduler/schedulerprocess.cpp:1865 +#, fuzzy, kde-format +msgid "Restarting %1 alignment procedure..." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1837 +#, fuzzy, kde-format +msgid "Job '%1' guiding is in progress." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:1849 +#, fuzzy, kde-format +msgid "Warning: job '%1' guiding failed." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1851 +#, fuzzy, kde-format +msgid "Warning: job '%1' calibration failed." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:1870 +#, fuzzy, kde-format +msgid "Job '%1' is guiding, guiding procedure will be restarted in %2 seconds." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1906 +#, fuzzy, kde-format +msgid "Job '%1' focusing is complete." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:1916 +#, fuzzy, kde-format +msgid "Warning: job '%1' focusing failed." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1920 +#, fuzzy, kde-format +msgid "Job '%1' is restarting its focusing procedure." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1958 +#, fuzzy, kde-format +msgid "Job '%1' slew is complete." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:1964 +#, kde-format +msgid "Warning: job '%1' slew failed, marking terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1970 +#, fuzzy, kde-format +msgid "Warning: job '%1' found not slewing, restarting." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:1983 +#, fuzzy, kde-format +msgid "Job '%1' repositioning is complete." +msgstr "Bereken" + +#: ekos/scheduler/schedulerprocess.cpp:1989 +#, kde-format +msgid "" +"Warning: job '%1' repositioning failed, marking terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1995 +#, fuzzy, kde-format +msgid "Warning: job '%1' found not repositioning, restarting." +msgstr "Spanje" + +#: ekos/scheduler/schedulerprocess.cpp:2020 +#, fuzzy, kde-format +msgid "Manual shutdown procedure completed successfully." +msgstr "Aarde koördinate" + +#: ekos/scheduler/schedulerprocess.cpp:2026 +#, kde-format +msgid "Manual shutdown procedure terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2041 +#, kde-format +msgid "Dust cover park requested but no dust covers detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2064 +#, fuzzy, kde-format +msgid "Parking Cap..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:2070 +#, kde-format +msgid "Cap already parked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2079 +#, kde-format +msgid "Dust cover unpark requested but no dust covers detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2101 +#, fuzzy, kde-format +msgid "Unparking cap..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:2107 +#, kde-format +msgid "Cap already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2116 +#, kde-format +msgid "Mount park requested but no mounts detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2174 +#, fuzzy, kde-format +msgid "Parking mount in progress..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:2188 +#, kde-format +msgid "Mount unpark requested but no mounts detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2214 +#, kde-format +msgid "Mount already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2312 +#, kde-format +msgid "Dome park requested but no domes detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2335 +#, fuzzy, kde-format +msgid "Parking dome..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:2341 +#, kde-format +msgid "Dome already parked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2351 +#, kde-format +msgid "Dome unpark requested but no domes detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2371 +#, fuzzy, kde-format +msgid "Unparking dome..." +msgstr "Planeet" + +#: ekos/scheduler/schedulerprocess.cpp:2377 +#, kde-format +msgid "Dome already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2495 +#, kde-format +msgid "Startup script failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2500 +#, kde-format +msgid "Shutdown script failed, aborting..." +msgstr "" + #: fitsviewer/fitscommon.h:15 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" @@ -25896,40 +26454,40 @@ msgid "Failed to write image: %1" msgstr "Kon nie Open Lêer" -#: fitsviewer/fitsdata.cpp:2778 fitsviewer/fitsdata.cpp:2789 -#: fitsviewer/fitsdata.cpp:2825 fitsviewer/fitsdata.cpp:2861 -#: fitsviewer/fitsdata.cpp:2908 +#: fitsviewer/fitsdata.cpp:2780 fitsviewer/fitsdata.cpp:2791 +#: fitsviewer/fitsdata.cpp:2827 fitsviewer/fitsdata.cpp:2863 +#: fitsviewer/fitsdata.cpp:2910 #, fuzzy, kde-format msgid "No world coordinate systems found." msgstr "Horisontaal Koördinate" -#: fitsviewer/fitsdata.cpp:3630 +#: fitsviewer/fitsdata.cpp:3632 #, kde-format msgid "Only 8 and 16 bits bayered images supported." msgstr "" -#: fitsviewer/fitsdata.cpp:3663 +#: fitsviewer/fitsdata.cpp:3665 #, kde-format msgid "Unsupported bayer pattern %1." msgstr "" -#: fitsviewer/fitsdata.cpp:3694 +#: fitsviewer/fitsdata.cpp:3696 #, kde-format msgid "Unsupported bayer offsets %1 %2." msgstr "" -#: fitsviewer/fitsdata.cpp:3762 fitsviewer/fitsdata.cpp:3809 -#: fitsviewer/fitsdata.cpp:3854 fitsviewer/fitsdata.cpp:3901 +#: fitsviewer/fitsdata.cpp:3764 fitsviewer/fitsdata.cpp:3811 +#: fitsviewer/fitsdata.cpp:3856 fitsviewer/fitsdata.cpp:3903 #, kde-format msgid "Unable to allocate memory for temporary bayer buffer: %1" msgstr "" -#: fitsviewer/fitsdata.cpp:3772 fitsviewer/fitsdata.cpp:3864 +#: fitsviewer/fitsdata.cpp:3774 fitsviewer/fitsdata.cpp:3866 #, kde-format msgid "Unable to allocate memory for temporary bayer buffer." msgstr "" -#: fitsviewer/fitsdata.cpp:3792 fitsviewer/fitsdata.cpp:3884 +#: fitsviewer/fitsdata.cpp:3794 fitsviewer/fitsdata.cpp:3886 #, kde-format msgid "Debayer failed (%1)" msgstr "" @@ -26037,7 +26595,7 @@ msgstr "Lees" #. i18n: ectx: property (windowTitle), widget (QDialog, fitsHeaderDialog) -#: fitsviewer/fitsheaderdialog.ui:14 fitsviewer/fitstab.cpp:128 +#: fitsviewer/fitsheaderdialog.ui:14 fitsviewer/fitstab.cpp:137 #: fitsviewer/fitsviewer.cpp:138 #, kde-format msgid "FITS Header" @@ -26093,7 +26651,7 @@ msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, FITSHistogramUI) -#: fitsviewer/fitshistogramui.ui:32 fitsviewer/fitstab.cpp:125 +#: fitsviewer/fitshistogramui.ui:32 fitsviewer/fitstab.cpp:134 #: fitsviewer/fitsviewer.cpp:119 #, kde-format msgid "Histogram" @@ -26128,18 +26686,12 @@ msgid "Apply" msgstr "Waarskuwing" -#: fitsviewer/fitslabel.cpp:284 -#, fuzzy, kde-format -msgctxt "Half Flux Radius" -msgid "HFR: %1" -msgstr "Sonsondergang:" - -#: fitsviewer/fitslabel.cpp:342 tools/whatsinteresting/wiview.cpp:332 +#: fitsviewer/fitslabel.cpp:353 tools/whatsinteresting/wiview.cpp:332 #, fuzzy, kde-format msgid "Continue Slew" msgstr " norman" -#: fitsviewer/fitslabel.cpp:425 fitsviewer/fitslabel.cpp:452 +#: fitsviewer/fitslabel.cpp:436 fitsviewer/fitslabel.cpp:463 #, kde-format msgid "KStars did not find any active mounts." msgstr "" @@ -26203,50 +26755,105 @@ msgid "Automatically find stretch parameter." msgstr "Wissel Sterre" -#: fitsviewer/fitstab.cpp:53 +#: fitsviewer/fitstab.cpp:56 #, fuzzy, kde-format msgid "Save Changes to FITS?" msgstr "Stooring van die beeld %1 gevaal!" -#: fitsviewer/fitstab.cpp:54 +#: fitsviewer/fitstab.cpp:57 #, kde-format msgid "" "The current FITS file has unsaved changes. Would you like to save before " "closing it?" msgstr "" -#: fitsviewer/fitstab.cpp:133 +#. i18n: ectx: property (windowTitle), widget (QDialog, PlateSolveUI) +#: fitsviewer/fitstab.cpp:131 fitsviewer/platesolve.ui:14 +#, fuzzy, kde-format +msgid "Plate Solving" +msgstr "St. Peter Poort" + +#: fitsviewer/fitstab.cpp:142 #, fuzzy, kde-format msgid "Recent Images" msgstr "Stoor Beeld" -#: fitsviewer/fitstab.cpp:367 +#: fitsviewer/fitstab.cpp:376 #, fuzzy, kde-format msgctxt "Red" msgid "R" msgstr "Alt:" -#: fitsviewer/fitstab.cpp:448 fitsviewer/fitstab.cpp:452 +#: fitsviewer/fitstab.cpp:457 fitsviewer/fitstab.cpp:461 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save FITS" msgstr "Stoor Beeld" -#: fitsviewer/fitstab.cpp:484 +#: fitsviewer/fitstab.cpp:493 #, fuzzy, kde-format msgid "Image save error: %1" msgstr "Ongeldige Url" -#: fitsviewer/fitstab.cpp:484 +#: fitsviewer/fitstab.cpp:493 #, fuzzy, kde-format msgid "Image Save" msgstr "Invoer Keuse" -#: fitsviewer/fitstab.cpp:488 +#: fitsviewer/fitstab.cpp:497 #, fuzzy, kde-format msgid "File saved to %1" msgstr "Ongeldige Url" +#: fitsviewer/fitstab.cpp:632 +#, fuzzy, kde-format +msgid "Extracting..." +msgstr "Vertoon naam" + +#: fitsviewer/fitstab.cpp:650 +#, fuzzy, kde-format +msgid "Solving..." +msgstr "niks" + +#: fitsviewer/fitstab.cpp:663 +#, fuzzy, kde-format +#| msgctxt "the time at which an object falls below the horizon" +#| msgid "Set time: %1" +msgid "Extractor timed out: %1s" +msgstr "Stel tyd: %1" + +#: fitsviewer/fitstab.cpp:672 +#, fuzzy, kde-format +msgid "Extractor failed: %1s" +msgstr "Soek Voorwerp" + +#: fitsviewer/fitstab.cpp:681 +#, kde-format +msgid "Extracted %1 stars (%2 unfiltered) in %3s" +msgstr "" + +#: fitsviewer/fitstab.cpp:728 +#, fuzzy, kde-format +#| msgctxt "the time at which an object falls below the horizon" +#| msgid "Set time: %1" +msgid "Solver timed out: %1s" +msgstr "Stel tyd: %1" + +#: fitsviewer/fitstab.cpp:733 +#, fuzzy, kde-format +msgid "Solver failed: %1s" +msgstr "Soek Voorwerp" + +#: fitsviewer/fitstab.cpp:823 +#, kde-format +msgid "Warning! This tool only supports the internal StellarSolver solver." +msgstr "" + +#: fitsviewer/fitstab.cpp:824 +#, kde-format +msgid "Change to that in the Ekos Align options menu." +msgstr "" + #: fitsviewer/fitsview.cpp:506 fitsviewer/fitsview.cpp:516 #, fuzzy, kde-format msgid "Rescaling image failed." @@ -26496,7 +27103,7 @@ msgid "HiPS Overlay" msgstr "" -#: fitsviewer/fitsviewer.cpp:711 kstarsactions.cpp:1284 +#: fitsviewer/fitsviewer.cpp:711 kstarsactions.cpp:1293 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Image" @@ -26696,7 +27303,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, stretchPreviewSamplingLabel) #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_StretchPreviewSampling) #. i18n: ectx: label, entry (StretchPreviewSampling), group (Capture) -#: fitsviewer/opsfits.ui:226 fitsviewer/opsfits.ui:236 kstars.kcfg:1854 +#: fitsviewer/opsfits.ui:226 fitsviewer/opsfits.ui:236 kstars.kcfg:1878 #, kde-format msgid "" "Set the coarseness of the preview shown when sliding the fitsviewer's " @@ -26909,6 +27516,69 @@ msgid "StellarSolver Partitioning" msgstr "Stoor Huidige Kleure..." +#. i18n: ectx: property (toolTip), widget (QPushButton, SolveButton) +#: fitsviewer/platesolve.ui:47 +#, kde-format +msgid "Plate solve the image using the parameters below." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:101 +#, kde-format +msgid "

            The units of the imager scale bounds." +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:108 +#, fuzzy, kde-format +msgid "image width º" +msgstr "Beeld" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:113 +#, fuzzy, kde-format +msgid "image width '" +msgstr "Beeld" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:118 +#, fuzzy, kde-format +#| msgctxt "seconds" +#| msgid "secs" +msgid "arcsec/pixel" +msgstr "sekondes" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_FitsSolverUsePosition) +#: fitsviewer/platesolve.ui:139 +#, kde-format +msgid "" +"Use the given position to speed up astrometry solver as it does not have to " +"search in other areas of the sky." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QPushButton, UpdatePosition) +#: fitsviewer/platesolve.ui:164 +#, kde-format +msgid "" +"Set the approximate RA/DEC positions using the center position of the SkyMap." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverAngleLabel) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverAngle) +#: fitsviewer/platesolve.ui:315 fitsviewer/platesolve.ui:331 +#, fuzzy, kde-format +msgid "The solved image position angle, East of North (degrees)." +msgstr "Galaktiese Koördinate" + +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverProfileLabel) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_FitsSolverProfile) +#. i18n: ectx: property (toolTip), widget (QComboBox, imageOverlaySolverProfile) +#: fitsviewer/platesolve.ui:357 fitsviewer/platesolve.ui:373 +#: options/opsimageoverlay.ui:255 +#, kde-format +msgid "Selects the Options Profile (from Align) to use for Plate Solving" +msgstr "" + #. i18n: ectx: property (text), widget (QTableWidget, solutionTable) #: fitsviewer/solveInfo.ui:71 #, fuzzy, kde-format @@ -26929,12 +27599,6 @@ msgid "Rotation" msgstr "Ster Naam" -#. i18n: ectx: property (text), widget (QTableWidget, solutionTable) -#: fitsviewer/solveInfo.ui:91 -#, fuzzy, kde-format -msgid "Solution" -msgstr "Bereken" - #. i18n: ectx: property (text), widget (QPushButton, solveB) #: fitsviewer/solveInfo.ui:99 #, fuzzy, kde-format @@ -27049,11 +27713,6 @@ msgid "Changes the type of selection" msgstr "" -#: fitsviewer/starprofileviewer.cpp:127 -#, kde-format -msgid "Item" -msgstr "" - #: fitsviewer/starprofileviewer.cpp:137 #, kde-format msgid "Toggles the slice view when horizontal or vertical items are selected" @@ -27485,61 +28144,61 @@ msgid "Failed to create local INDI server" msgstr "Bereken" -#: indi/drivermanager.cpp:604 indi/indidriver.cpp:291 +#: indi/drivermanager.cpp:621 indi/indidriver.cpp:291 #, fuzzy, kde-format, kde-kuit-format msgid "Invalid port entry: %1" msgstr "Ongeldige Url" -#: indi/drivermanager.cpp:800 +#: indi/drivermanager.cpp:817 #, fuzzy, kde-format msgid "Connected to INDI server" msgstr "Bereken" -#: indi/drivermanager.cpp:992 indi/indidriver.cpp:487 +#: indi/drivermanager.cpp:1009 indi/indidriver.cpp:487 #, kde-format, kde-kuit-format msgid "" "Unable to find INDI drivers directory: %1\n" "Please make sure to set the correct path in KStars configuration" msgstr "" -#: indi/drivermanager.cpp:1023 indi/indidriver.cpp:528 +#: indi/drivermanager.cpp:1040 indi/indidriver.cpp:528 #, fuzzy, kde-format, kde-kuit-format msgid "Failed to open INDI Driver file: %1" msgstr "Kon nie Open Lêer" -#: indi/drivermanager.cpp:1389 +#: indi/drivermanager.cpp:1406 #, fuzzy, kde-format msgctxt "@title:window" msgid "Add Host" msgstr "Voeg by na Lys" -#: indi/drivermanager.cpp:1400 indi/indidriver.cpp:812 +#: indi/drivermanager.cpp:1417 indi/indidriver.cpp:812 #, kde-format, kde-kuit-format msgid "Error: the port number is invalid." msgstr "" -#: indi/drivermanager.cpp:1413 indi/indidriver.cpp:822 +#: indi/drivermanager.cpp:1430 indi/indidriver.cpp:822 #, kde-format, kde-kuit-format msgid "Host: %1 Port: %2 already exists." msgstr "" -#: indi/drivermanager.cpp:1441 +#: indi/drivermanager.cpp:1458 #, fuzzy, kde-format msgctxt "@title:window" msgid "Modify Host" msgstr "Voeg by na Lys" -#: indi/drivermanager.cpp:1487 indi/indidriver.cpp:890 +#: indi/drivermanager.cpp:1504 indi/indidriver.cpp:890 #, kde-format, kde-kuit-format msgid "You need to disconnect the client before removing it." msgstr "" -#: indi/drivermanager.cpp:1493 indi/indidriver.cpp:895 +#: indi/drivermanager.cpp:1510 indi/indidriver.cpp:895 #, kde-format, kde-kuit-format msgid "Are you sure you want to remove the %1 client?" msgstr "" -#: indi/drivermanager.cpp:1518 indi/indidriver.cpp:920 +#: indi/drivermanager.cpp:1535 indi/indidriver.cpp:920 #, kde-format, kde-kuit-format msgid "" "Unable to write to file 'indihosts.xml'\n" @@ -28309,17 +28968,17 @@ msgid "Post driver startup script failed with exit code: %1" msgstr "" -#: indi/servermanager.cpp:407 +#: indi/servermanager.cpp:415 #, fuzzy, kde-format msgid "Connection to INDI server %1:%2 terminated: %3." msgstr "Bereken" -#: indi/servermanager.cpp:453 +#: indi/servermanager.cpp:461 #, kde-format msgid "INDI Driver %1 crashed. Restart it?" msgstr "" -#: indi/servermanager.cpp:454 +#: indi/servermanager.cpp:462 #, fuzzy, kde-format msgid "Driver crash" msgstr "Ada" @@ -28844,18 +29503,18 @@ msgid "KStars" msgstr "K-sterre" -#: kstars.cpp:314 kstarsactions.cpp:1553 skymap.cpp:427 +#: kstars.cpp:314 kstarsactions.cpp:1562 skymap.cpp:427 #, fuzzy, kde-format msgid "Stop &Tracking" msgstr "Stop Horlosie" -#: kstars.cpp:322 kstarsactions.cpp:1722 kstarsinit.cpp:263 +#: kstars.cpp:322 kstarsactions.cpp:1731 kstarsinit.cpp:263 #, fuzzy, kde-format #| msgid "Equatorial &Coordinates" msgid "Switch to Star Globe View (Equatorial &Coordinates)" msgstr "Ekwatoriale Koördinate" -#: kstars.cpp:323 kstarsactions.cpp:1701 kstarsinit.cpp:264 +#: kstars.cpp:323 kstarsactions.cpp:1710 kstarsinit.cpp:264 #, fuzzy, kde-format #| msgid "Horizontal &Coordinates" msgid "Switch to Horizontal View (Horizontal &Coordinates)" @@ -32309,86 +32968,122 @@ msgid "HiPS overlay Y Offset" msgstr "" +#. i18n: ectx: label, entry (FitsSolverProfile), group (FITSViewer) +#: kstars.kcfg:1526 +#, kde-format +msgid "Options Profile for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverUseScale), group (FITSViewer) +#: kstars.kcfg:1530 +#, kde-format +msgid "Use scale for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverUsePosition), group (FITSViewer) +#: kstars.kcfg:1534 +#, kde-format +msgid "Use position for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverScale), group (FITSViewer) +#: kstars.kcfg:1538 +#, kde-format +msgid "Scale to use with Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverImageScaleUnits), group (FITSViewer) +#: kstars.kcfg:1542 +#, kde-format +msgid "Scale units to use with Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverRadius), group (FITSViewer) +#: kstars.kcfg:1546 +#, kde-format +msgid "Radius in position (degrees) to use with Fitsviewer Solving." +msgstr "" + #. i18n: ectx: label, entry (BortleClass), group (WISettings) -#: kstars.kcfg:1528 +#: kstars.kcfg:1552 #, kde-format msgid "Bortle dark-sky rating" msgstr "" #. i18n: ectx: label, entry (TelescopeCheck), group (WISettings) -#: kstars.kcfg:1532 +#: kstars.kcfg:1556 #, fuzzy, kde-format msgid "Availability of telescope" msgstr "Planeet" #. i18n: ectx: label, entry (BinocularsCheck), group (WISettings) -#: kstars.kcfg:1536 +#: kstars.kcfg:1560 #, kde-format msgid "Availability of binoculars" msgstr "" #. i18n: ectx: label, entry (BinocularsAperture), group (WISettings) -#: kstars.kcfg:1540 +#: kstars.kcfg:1564 #, kde-format msgid "Aperture of available binocular" msgstr "" #. i18n: ectx: label, entry (ScopeListIndex), group (WISettings) -#: kstars.kcfg:1544 +#: kstars.kcfg:1568 #, kde-format msgid "Index of selected scope from list of scopes" msgstr "" #. i18n: ectx: label, entry (EkosWindowWidth), group (Ekos) -#: kstars.kcfg:1550 +#: kstars.kcfg:1574 #, kde-format msgid "Ekos window width" msgstr "" #. i18n: ectx: label, entry (EkosWindowHeight), group (Ekos) -#: kstars.kcfg:1554 +#: kstars.kcfg:1578 #, fuzzy, kde-format msgid "Ekos window height" msgstr "Yukon" #. i18n: ectx: label, entry (EkosLeftIcons), group (Ekos) -#: kstars.kcfg:1562 +#: kstars.kcfg:1586 #, kde-format msgid "Ekos modules icons are placed to the left of pages" msgstr "" #. i18n: ectx: label, entry (independentWindowEkos), group (Ekos) -#: kstars.kcfg:1566 +#: kstars.kcfg:1590 #, kde-format msgid "Make Ekos window independent of KStars main window" msgstr "" #. i18n: ectx: label, entry (profile), group (Ekos) -#: kstars.kcfg:1570 +#: kstars.kcfg:1594 #, kde-format msgid "Ekos drivers profile" msgstr "" #. i18n: ectx: label, entry (neverLoadConfig), group (Ekos) -#: kstars.kcfg:1574 +#: kstars.kcfg:1598 #, fuzzy, kde-format msgid "Never load device configuration?" msgstr "Laaiïng van Informasie Urls" #. i18n: ectx: label, entry (loadConfigOnConnection), group (Ekos) -#: kstars.kcfg:1578 +#: kstars.kcfg:1602 #, kde-format msgid "Load device configuration upon successful connection?" msgstr "" #. i18n: ectx: label, entry (loadDefaultConfig), group (Ekos) -#: kstars.kcfg:1582 +#: kstars.kcfg:1606 #, kde-format msgid "Always load device default configuration upon successful connection?" msgstr "" #. i18n: ectx: label, entry (autoLoadSerialAssistant), group (Ekos) -#: kstars.kcfg:1586 +#: kstars.kcfg:1610 #, kde-format msgid "" "Automatically load Serial Port Assistant tool when detecting unmapped serial " @@ -32396,49 +33091,49 @@ msgstr "" #. i18n: ectx: label, entry (RememberCredentials), group (EkosLive) -#: kstars.kcfg:1592 +#: kstars.kcfg:1616 #, kde-format msgid "Remember Ekos Live credentials." msgstr "" #. i18n: ectx: label, entry (AutoStartEkosLive), group (EkosLive) -#: kstars.kcfg:1596 +#: kstars.kcfg:1620 #, kde-format msgid "Start Ekos Live on KStars startup." msgstr "" #. i18n: ectx: label, entry (EkosLiveUsername), group (EkosLive) -#: kstars.kcfg:1600 +#: kstars.kcfg:1624 #, fuzzy, kde-format msgid "EkosLive username" msgstr "Invoer Keuse" #. i18n: ectx: label, entry (EkosLiveOfflineServer), group (EkosLive) -#: kstars.kcfg:1603 +#: kstars.kcfg:1627 #, fuzzy, kde-format msgid "EkosLive Offline Server" msgstr "Invoer Keuse" #. i18n: ectx: label, entry (EkosLiveOnlineServer), group (EkosLive) -#: kstars.kcfg:1607 +#: kstars.kcfg:1631 #, fuzzy, kde-format msgid "EkosLive Online Server" msgstr "Invoer Keuse" #. i18n: ectx: label, entry (shutterfulCCDs), group (DarkLibrary) -#: kstars.kcfg:1632 +#: kstars.kcfg:1656 #, kde-format msgid "List of CCDs with mechanical or electronic shutters." msgstr "" #. i18n: ectx: label, entry (shutterlessCCDs), group (DarkLibrary) -#: kstars.kcfg:1635 +#: kstars.kcfg:1659 #, kde-format msgid "List of CCDs without mechanical or electronic shutters." msgstr "" #. i18n: ectx: label, entry (UseGraphicalCountsDisplay), group (Manager) -#: kstars.kcfg:1644 +#: kstars.kcfg:1668 #, kde-format msgid "" "Use the graphical version for capture/sequence/total counting using round " @@ -32446,19 +33141,19 @@ msgstr "" #. i18n: ectx: label, entry (MinimumAltLimit), group (Mount) -#: kstars.kcfg:1650 +#: kstars.kcfg:1674 #, kde-format msgid "Default minimum mount altitude limit" msgstr "" #. i18n: ectx: label, entry (MaximumAltLimit), group (Mount) -#: kstars.kcfg:1655 +#: kstars.kcfg:1679 #, kde-format msgid "Default maximum mount altitude limit." msgstr "" #. i18n: ectx: whatsthis, entry (MaximumAltLimit), group (Mount) -#: kstars.kcfg:1656 +#: kstars.kcfg:1680 #, kde-format msgid "" "Maximum telescope altitude limit. If the telescope is above this limit, it " @@ -32466,25 +33161,25 @@ msgstr "" #. i18n: ectx: label, entry (EnableAltitudeLimits), group (Mount) -#: kstars.kcfg:1660 +#: kstars.kcfg:1684 #, kde-format msgid "Enable mount altitude limits." msgstr "" #. i18n: ectx: label, entry (ConfirmBelowHorizon), group (Mount) -#: kstars.kcfg:1664 +#: kstars.kcfg:1688 #, kde-format msgid "Warn user before command mount to go to a target below horizon." msgstr "" #. i18n: ectx: label, entry (MeridianFlipOffsetDegrees), group (Mount) -#: kstars.kcfg:1668 +#: kstars.kcfg:1692 #, fuzzy, kde-format msgid "Default hour angle to perform meridian flip in degrees." msgstr "Wissel Sterre" #. i18n: ectx: whatsthis, entry (MeridianFlipOffsetDegrees), group (Mount) -#: kstars.kcfg:1669 +#: kstars.kcfg:1693 #, kde-format msgid "" "If the target hour angle exceeds this value, Ekos will command a meridian " @@ -32492,13 +33187,13 @@ msgstr "" #. i18n: ectx: label, entry (MaximumHaLimit), group (Mount) -#: kstars.kcfg:1673 +#: kstars.kcfg:1697 #, kde-format msgid "Default maximum limit for the hour angle." msgstr "" #. i18n: ectx: whatsthis, entry (MaximumHaLimit), group (Mount) -#: kstars.kcfg:1674 +#: kstars.kcfg:1698 #, kde-format msgid "" "Maximum limit for the hour angle of the telescope. If the hour angle of the " @@ -32506,79 +33201,79 @@ msgstr "" #. i18n: ectx: label, entry (EnableHaLimit), group (Mount) -#: kstars.kcfg:1678 +#: kstars.kcfg:1702 #, kde-format msgid "Enable mount hour angle limit." msgstr "" #. i18n: ectx: label, entry (ExecuteMeridianFlip), group (Mount) -#: kstars.kcfg:1682 +#: kstars.kcfg:1706 #, kde-format msgid "Flips the mount when reaching the meridian, if supported." msgstr "" #. i18n: ectx: label, entry (LeftRightReversed), group (Mount) -#: kstars.kcfg:1686 +#: kstars.kcfg:1710 #, kde-format msgid "Reverse the direction of right and left buttons in mount control." msgstr "" #. i18n: ectx: label, entry (UpDownReversed), group (Mount) -#: kstars.kcfg:1690 +#: kstars.kcfg:1714 #, kde-format msgid "Reverse the direction of up and down buttons in mount control." msgstr "" #. i18n: ectx: label, entry (ParkEveryDay), group (Mount) -#: kstars.kcfg:1694 +#: kstars.kcfg:1718 #, fuzzy, kde-format msgid "Automatically start parking timer on startup." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ParkTime), group (Mount) -#: kstars.kcfg:1698 +#: kstars.kcfg:1722 #, kde-format msgid "Park mount at this time in 12 hour format." msgstr "" #. i18n: ectx: label, entry (DefaultObserver), group (Capture) -#: kstars.kcfg:1704 +#: kstars.kcfg:1728 #, fuzzy, kde-format msgid "Default observer full name." msgstr "Planeet" #. i18n: ectx: label, entry (SyncFOVPA), group (Capture) -#: kstars.kcfg:1707 +#: kstars.kcfg:1731 #, kde-format msgid "Sync FOV indicator Position Angle with Rotator Settings Position Angle" msgstr "" #. i18n: ectx: label, entry (PAMultiplier), group (Capture) -#: kstars.kcfg:1711 +#: kstars.kcfg:1735 #, fuzzy, kde-format msgid "Position angle multiplier" msgstr "Bereken" #. i18n: ectx: label, entry (PAOffset), group (Capture) -#: kstars.kcfg:1715 +#: kstars.kcfg:1739 #, fuzzy, kde-format msgid "Position angle offset" msgstr "Bereken" #. i18n: ectx: label, entry (PAPierSide), group (Capture) -#: kstars.kcfg:1719 +#: kstars.kcfg:1743 #, fuzzy, kde-format msgid "Position angle calibration pier side" msgstr "Bereken" #. i18n: ectx: label, entry (GuideDeviation), group (Capture) -#: kstars.kcfg:1722 +#: kstars.kcfg:1746 #, kde-format msgid "Default maximum permittable guide deviation" msgstr "" #. i18n: ectx: whatsthis, entry (GuideDeviation), group (Capture) -#: kstars.kcfg:1723 +#: kstars.kcfg:1747 #, kde-format msgid "" "If guide deviation exceeds this limit, the exposure will be automatically " @@ -32586,7 +33281,7 @@ msgstr "" #. i18n: ectx: label, entry (GuideDeviationReps), group (Capture) -#: kstars.kcfg:1727 +#: kstars.kcfg:1751 #, kde-format msgid "" "Number of consecutive samples guide deviation needs to be high to abort " @@ -32594,7 +33289,7 @@ msgstr "" #. i18n: ectx: whatsthis, entry (GuideDeviationReps), group (Capture) -#: kstars.kcfg:1728 +#: kstars.kcfg:1752 #, kde-format msgid "" "Sets the number of consecutive samples guide deviation needs to be high to " @@ -32602,13 +33297,13 @@ msgstr "" #. i18n: ectx: label, entry (StartGuideDeviation), group (Capture) -#: kstars.kcfg:1732 +#: kstars.kcfg:1756 #, kde-format msgid "Default maximum permittable guide deviation before capture start" msgstr "" #. i18n: ectx: whatsthis, entry (StartGuideDeviation), group (Capture) -#: kstars.kcfg:1733 +#: kstars.kcfg:1757 #, kde-format msgid "" "If guide deviation exceeds this limit before capture start, starting an " @@ -32616,13 +33311,13 @@ msgstr "" #. i18n: ectx: label, entry (HFRDeviation), group (Capture) -#: kstars.kcfg:1737 +#: kstars.kcfg:1761 #, kde-format msgid "Default maximum permittable HFR deviation" msgstr "" #. i18n: ectx: whatsthis, entry (HFRDeviation), group (Capture) -#: kstars.kcfg:1738 +#: kstars.kcfg:1762 #, kde-format msgid "" "If HFR deviation exceeds this limit, the autofocus routine will be " @@ -32630,13 +33325,13 @@ msgstr "" #. i18n: ectx: label, entry (MaxFocusTemperatureDelta), group (Capture) -#: kstars.kcfg:1742 +#: kstars.kcfg:1766 #, kde-format msgid "Default maximum focus temperature delta" msgstr "" #. i18n: ectx: whatsthis, entry (MaxFocusTemperatureDelta), group (Capture) -#: kstars.kcfg:1743 +#: kstars.kcfg:1767 #, kde-format msgid "" "If the temperature change exceeds this limit, the autofocus routine will be " @@ -32644,44 +33339,44 @@ msgstr "" #. i18n: ectx: label, entry (AutoDark), group (Capture) -#: kstars.kcfg:1747 +#: kstars.kcfg:1771 #, kde-format msgid "" "Automatically apply dark subtraction if a suitable dark frame is available." msgstr "" #. i18n: ectx: label, entry (EnforceGuideDeviation), group (Capture) -#: kstars.kcfg:1751 +#: kstars.kcfg:1775 #, kde-format msgid "Enforce guiding deviation limit." msgstr "" #. i18n: ectx: label, entry (EnforceAutofocusHFR), group (Capture) -#: kstars.kcfg:1755 +#: kstars.kcfg:1779 #, fuzzy, kde-format msgid "Enforce Autofocus on HFR limit." msgstr "Bereken" #. i18n: ectx: label, entry (EnforceAutofocusOnTemperature), group (Capture) -#: kstars.kcfg:1759 +#: kstars.kcfg:1783 #, fuzzy, kde-format msgid "Enforce Autofocus on temperature change." msgstr "Bereken" #. i18n: ectx: label, entry (EnforceRefocusEveryN), group (Capture) -#: kstars.kcfg:1763 +#: kstars.kcfg:1787 #, kde-format msgid "Enforce Refocus Every N Minutes." msgstr "" #. i18n: ectx: label, entry (RefocusEveryN), group (Capture) -#: kstars.kcfg:1767 +#: kstars.kcfg:1791 #, kde-format msgid "Number of minute between forced refocus attempts" msgstr "" #. i18n: ectx: whatsthis, entry (RefocusEveryN), group (Capture) -#: kstars.kcfg:1768 +#: kstars.kcfg:1792 #, kde-format msgid "" "Sets the time interval before forced autofocus attempts during a capture " @@ -32689,31 +33384,31 @@ msgstr "" #. i18n: ectx: label, entry (RefocusAfterMeridianFlip), group (Capture) -#: kstars.kcfg:1772 +#: kstars.kcfg:1796 #, fuzzy, kde-format msgid "Refocus after meridian flip is done" msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ResetMountModelAfterMeridian), group (Capture) -#: kstars.kcfg:1776 +#: kstars.kcfg:1800 #, fuzzy, kde-format msgid "Reset mount model after meridian flip." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ForcedFlip), group (Capture) -#: kstars.kcfg:1780 +#: kstars.kcfg:1804 #, fuzzy, kde-format msgid "Use Forced meridian flips if supported." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (CalibrationADUValue), group (Capture) -#: kstars.kcfg:1784 +#: kstars.kcfg:1808 #, fuzzy, kde-format msgid "Desired flat field ADU" msgstr "Details" #. i18n: ectx: whatsthis, entry (CalibrationADUValue), group (Capture) -#: kstars.kcfg:1785 +#: kstars.kcfg:1809 #, kde-format msgid "" "If set, Ekos will capture a few flat images to determine the optimal " @@ -32721,45 +33416,45 @@ msgstr "" #. i18n: ectx: label, entry (CalibrationADUValueTolerance), group (Capture) -#: kstars.kcfg:1789 +#: kstars.kcfg:1813 #, kde-format msgid "ADU Value tolerance" msgstr "" #. i18n: ectx: whatsthis, entry (CalibrationADUValueTolerance), group (Capture) -#: kstars.kcfg:1790 +#: kstars.kcfg:1814 #, kde-format msgid "" "Maximum difference between measured and target ADU values to deem the value " "as acceptable." msgstr "" -#. i18n: ectx: label, entry (CalibrationFlatSourceIndex), group (Capture) -#: kstars.kcfg:1794 -#, kde-format -msgid "Index of flat source option." -msgstr "" +#. i18n: ectx: label, entry (CalibrationPreActionIndex), group (Capture) +#: kstars.kcfg:1818 +#, fuzzy, kde-format +msgid "ORed list of calibration pre-actions." +msgstr "Bereken" #. i18n: ectx: label, entry (CalibrationFlatDurationIndex), group (Capture) -#: kstars.kcfg:1798 +#: kstars.kcfg:1822 #, kde-format msgid "Index of flat duration option." msgstr "" #. i18n: ectx: label, entry (CalibrationWallAz), group (Capture) -#: kstars.kcfg:1802 +#: kstars.kcfg:1826 #, fuzzy, kde-format msgid "Azimuth of calibration wall location." msgstr "Bereken" #. i18n: ectx: label, entry (CalibrationWallAlt), group (Capture) -#: kstars.kcfg:1806 +#: kstars.kcfg:1830 #, fuzzy, kde-format msgid "Altitude of calibration wall location." msgstr "Bereken" #. i18n: ectx: label, entry (MaxTemperatureDiff), group (Capture) -#: kstars.kcfg:1810 +#: kstars.kcfg:1834 #, kde-format msgid "" "Maximum acceptable difference between requested and measured temperature set " @@ -32767,27 +33462,27 @@ msgstr "" #. i18n: ectx: label, entry (MaxStartGuiderDrift), group (Capture) -#: kstars.kcfg:1814 +#: kstars.kcfg:1838 #, kde-format msgid "Maximum acceptable guider drift allowed before starting capture." msgstr "" #. i18n: ectx: label, entry (EnforceStartGuiderDrift), group (Capture) -#: kstars.kcfg:1818 +#: kstars.kcfg:1842 #, kde-format msgid "" "Enforce maximum acceptable guider drift allowed before starting capture." msgstr "" #. i18n: ectx: label, entry (GuidingSettle), group (Capture) -#: kstars.kcfg:1822 +#: kstars.kcfg:1846 #, kde-format msgid "" "Wait this many seconds after guiding is resumed before starting capture." msgstr "" #. i18n: ectx: label, entry (AlwaysResetSequenceWhenStarting), group (Capture) -#: kstars.kcfg:1826 +#: kstars.kcfg:1850 #, kde-format msgid "" "

            When starting to process a sequence list, reset all " @@ -32796,13 +33491,13 @@ msgstr "" #. i18n: ectx: label, entry (FlatSyncFocus), group (Capture) -#: kstars.kcfg:1830 +#: kstars.kcfg:1854 #, kde-format msgid "Capture flat frames at the same focus position of light frames." msgstr "" #. i18n: ectx: label, entry (HFRThresholdPercentage), group (Capture) -#: kstars.kcfg:1834 +#: kstars.kcfg:1858 #, kde-format msgid "" "Increase autofocus HFR value by this percentage gain and store it in Capture " @@ -32810,14 +33505,14 @@ msgstr "" #. i18n: ectx: label, entry (UseMedianFocus), group (Capture) -#: kstars.kcfg:1838 +#: kstars.kcfg:1862 #, kde-format msgid "" "Calculate median focus value after each autofocus operation is complete." msgstr "" #. i18n: ectx: label, entry (SaveHFRToFile), group (Capture) -#: kstars.kcfg:1842 +#: kstars.kcfg:1866 #, kde-format msgid "" "When saving a sequence file, save current HFR threshold value. By default, " @@ -32825,33 +33520,33 @@ msgstr "" #. i18n: ectx: label, entry (AutoStretch), group (Capture) -#: kstars.kcfg:1850 +#: kstars.kcfg:1874 #, kde-format msgid "Perform auto stretch on captured images in FITS Viewer." msgstr "" #. i18n: ectx: label, entry (Clipping64KValue), group (Capture) -#: kstars.kcfg:1858 +#: kstars.kcfg:1882 #, kde-format msgid "" "Min value of pixels marked as clipped in the fitsviewer for 16-bit images." msgstr "" #. i18n: ectx: label, entry (Clipping256Value), group (Capture) -#: kstars.kcfg:1862 +#: kstars.kcfg:1886 #, kde-format msgid "" "Min value of pixels marked as clipped in the fitsviewer for 8-bit images." msgstr "" #. i18n: ectx: label, entry (AdaptiveSampling), group (Capture) -#: kstars.kcfg:1867 +#: kstars.kcfg:1891 #, fuzzy, kde-format msgid "Automatically down sample images based on available resources." msgstr "Lang.:" #. i18n: ectx: label, entry (useSummaryPreview), group (Capture) -#: kstars.kcfg:1871 +#: kstars.kcfg:1895 #, fuzzy, kde-format msgid "" "Display every image captured sequence image in the Ekos summary screen " @@ -32859,13 +33554,13 @@ msgstr " Welkom na K-sterre " #. i18n: ectx: label, entry (useDSLRImageViewer), group (Capture) -#: kstars.kcfg:1875 +#: kstars.kcfg:1899 #, fuzzy, kde-format msgid "Display every captured DSLR image in the Image Viewer window." msgstr " Welkom na K-sterre " #. i18n: ectx: label, entry (ForceDSLRPresets), group (Capture) -#: kstars.kcfg:1879 +#: kstars.kcfg:1903 #, kde-format msgid "" "Force exposure times to align with DSLR exposure presets. This insures " @@ -32873,122 +33568,122 @@ msgstr "" #. i18n: ectx: label, entry (CaptureDirectory), group (Capture) -#: kstars.kcfg:1883 +#: kstars.kcfg:1907 #, kde-format msgid "Path to capture directory to save images." msgstr "" #. i18n: ectx: label, entry (PlaceholderFormat), group (Capture) -#: kstars.kcfg:1886 +#: kstars.kcfg:1910 #, fuzzy, kde-format msgid "How to format captured image filename." msgstr "Invoer lêernaam van pasmaak katalogus:" #. i18n: ectx: label, entry (RemoteCaptureDirectory), group (Capture) -#: kstars.kcfg:1890 +#: kstars.kcfg:1914 #, kde-format msgid "Path to remote capture directory to save images." msgstr "" #. i18n: ectx: label, entry (ManualCoverTimeout), group (Capture) -#: kstars.kcfg:1893 +#: kstars.kcfg:1917 #, kde-format msgid "Cover or uncover telescope dialog timeout in seconds." msgstr "" #. i18n: ectx: label, entry (CapturePosition), group (Capture) -#: kstars.kcfg:1897 +#: kstars.kcfg:1921 #, fuzzy, kde-format msgid "Calculate position after captures." msgstr "Koördinate" #. i18n: ectx: whatsthis, entry (AbsTicksSpin), group (Focus) -#: kstars.kcfg:1903 +#: kstars.kcfg:1927 #, fuzzy, kde-format msgid "The desired focuser position." msgstr "Des:" #. i18n: ectx: label, entry (FocusExposure), group (Focus) -#: kstars.kcfg:1907 +#: kstars.kcfg:1931 #, fuzzy, kde-format msgid "Exposure to use during focus" msgstr "Dag duur" #. i18n: ectx: whatsthis, entry (FocusExposure), group (Focus) -#: kstars.kcfg:1908 +#: kstars.kcfg:1932 #, kde-format msgid "Specifies the length of exposure to use during focus." msgstr "" #. i18n: ectx: label, entry (FocusBinning), group (Focus) -#: kstars.kcfg:1912 +#: kstars.kcfg:1936 #, fuzzy, kde-format msgid "Default Camera binning" msgstr "Noorweë" #. i18n: ectx: whatsthis, entry (FocusBinning), group (Focus) -#: kstars.kcfg:1913 +#: kstars.kcfg:1937 #, fuzzy, kde-format msgid "Set binning of camera while in focus mode." msgstr "Planeet" #. i18n: ectx: label, entry (FocusGain), group (Focus) -#: kstars.kcfg:1917 +#: kstars.kcfg:1941 #, fuzzy, kde-format msgid "Default Focuser gain value" msgstr "Planeet" #. i18n: ectx: whatsthis, entry (FocusGain), group (Focus) -#: kstars.kcfg:1918 +#: kstars.kcfg:1942 #, kde-format msgid "" "Specifies gain value of CCD when performing focusing if supported by camera." msgstr "" #. i18n: ectx: label, entry (FocusISO), group (Focus) -#: kstars.kcfg:1922 +#: kstars.kcfg:1946 #, fuzzy, kde-format msgid "Default Focuser Camera ISO value" msgstr "Planeet" #. i18n: ectx: label, entry (DefaultFocusTemperatureSource), group (Focus) -#: kstars.kcfg:1925 +#: kstars.kcfg:1949 #, fuzzy, kde-format msgid "Default focus module temperature source." msgstr "Planeet" #. i18n: ectx: label, entry (FocusFilter), group (Focus) -#: kstars.kcfg:1928 +#: kstars.kcfg:1952 #, fuzzy, kde-format msgid "Default Filter Wheel filter" msgstr "Planeet" #. i18n: ectx: label, entry (UseFocusDarkFrame), group (Focus) -#: kstars.kcfg:1931 +#: kstars.kcfg:1955 #, kde-format msgid "Take a dark frame and subtract it before running autofocus operation." msgstr "" #. i18n: ectx: label, entry (FocusSubFrame), group (Focus) -#: kstars.kcfg:1935 +#: kstars.kcfg:1959 #, kde-format msgid "Subframe the focus star during the autofocus procedure." msgstr "" #. i18n: ectx: label, entry (FocusBoxSize), group (Focus) -#: kstars.kcfg:1939 +#: kstars.kcfg:1963 #, kde-format msgid "Default Focuser star selection box size" msgstr "" #. i18n: ectx: whatsthis, entry (FocusBoxSize), group (Focus) -#: kstars.kcfg:1940 +#: kstars.kcfg:1964 #, kde-format msgid "Set box size to select a focus star." msgstr "" #. i18n: ectx: label, entry (FocusUseFullField), group (Focus) -#: kstars.kcfg:1944 +#: kstars.kcfg:1968 #, kde-format msgid "" "Measure average HFR from all stars combined in a full frame. This method " @@ -32997,7 +33692,7 @@ msgstr "" #. i18n: ectx: label, entry (FocusMaskType), group (Focus) -#: kstars.kcfg:1948 +#: kstars.kcfg:1972 #, kde-format msgid "" "Focus mask type: 0 = All stars used when focusing, 1 = ring mask, 2 = 3x3 " @@ -33005,13 +33700,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusFullFieldInnerRadius), group (Focus) -#: kstars.kcfg:1952 +#: kstars.kcfg:1976 #, kde-format msgid "Full field inner radius." msgstr "" #. i18n: ectx: whatsthis, entry (FocusFullFieldInnerRadius), group (Focus) -#: kstars.kcfg:1953 +#: kstars.kcfg:1977 #, no-c-format, kde-format msgid "" "During full field focusing, stars which are inside this percentage of the " @@ -33020,13 +33715,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusFullFieldOuterRadius), group (Focus) -#: kstars.kcfg:1957 +#: kstars.kcfg:1981 #, kde-format msgid "Full field outer radius." msgstr "" #. i18n: ectx: whatsthis, entry (FocusFullFieldOuterRadius), group (Focus) -#: kstars.kcfg:1958 +#: kstars.kcfg:1982 #, no-c-format, kde-format msgid "" "During full field focusing, stars which are outside this percentage of the " @@ -33035,56 +33730,56 @@ msgstr "" #. i18n: ectx: label, entry (FocusMosaicTileWidth), group (Focus) -#: kstars.kcfg:1962 +#: kstars.kcfg:1986 #, kde-format msgid "Mosaic filter tile width in percent of the frame width." msgstr "" #. i18n: ectx: label, entry (focusMosaicSpace), group (Focus) -#: kstars.kcfg:1966 +#: kstars.kcfg:1990 #, kde-format msgid "Space between the mosaic elements for the mosaic filter." msgstr "" #. i18n: ectx: label, entry (FocusAutoStarEnabled), group (Focus) -#: kstars.kcfg:1970 +#: kstars.kcfg:1994 #, fuzzy, kde-format msgid "Automatically select a star to focus." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (FocusSuspendGuiding), group (Focus) -#: kstars.kcfg:1974 +#: kstars.kcfg:1998 #, kde-format msgid "Suspend guiding while autofocus in progress." msgstr "" #. i18n: ectx: whatsthis, entry (GuideSettleTime), group (Focus) -#: kstars.kcfg:1978 +#: kstars.kcfg:2002 #, kde-format msgid "Wait for this many seconds after resuming guide." msgstr "" #. i18n: ectx: whatsthis, entry (FocusUnits), group (Focus) -#: kstars.kcfg:1982 +#: kstars.kcfg:2006 #, kde-format msgid "Display units for HFR and FWHM" msgstr "" #. i18n: ectx: whatsthis, entry (FocusAdaptive), group (Focus) -#: kstars.kcfg:1986 +#: kstars.kcfg:2010 #, fuzzy, kde-format msgid "Whether Adaptive Focusing is enabled." msgstr "Bereken" #. i18n: ectx: whatsthis, entry (focusAdaptiveMinMove), group (Focus) -#: kstars.kcfg:1990 +#: kstars.kcfg:2014 #, kde-format msgid "" "When using Adaptive Focusing the minimum allowable focuser move in ticks." msgstr "" #. i18n: ectx: whatsthis, entry (FocusAdaptStart), group (Focus) -#: kstars.kcfg:1994 +#: kstars.kcfg:2018 #, kde-format msgid "" "Whether to adapt the focuser starting position at the beginning of an " @@ -33092,7 +33787,7 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusAdaptiveMaxMove), group (Focus) -#: kstars.kcfg:1998 +#: kstars.kcfg:2022 #, kde-format msgid "" "When using Adaptive Focusing the maximum total allowable focuser move in " @@ -33100,79 +33795,79 @@ msgstr "" #. i18n: ectx: label, entry (FocusDetection), group (Focus) -#: kstars.kcfg:2003 +#: kstars.kcfg:2027 #, fuzzy, kde-format msgid "Star detection algorithm" msgstr "Ster Naam" #. i18n: ectx: label, entry (FocusSEPProfile), group (Focus) -#: kstars.kcfg:2007 +#: kstars.kcfg:2031 #, fuzzy, kde-format msgid "Focus source extraction profile" msgstr "Aarde koördinate" #. i18n: ectx: label, entry (FocusAlgorithm), group (Focus) -#: kstars.kcfg:2010 +#: kstars.kcfg:2034 #, kde-format msgid "Focus process algorithm" msgstr "" #. i18n: ectx: whatsthis, entry (FocusCurveFit), group (Focus) -#: kstars.kcfg:2014 +#: kstars.kcfg:2038 #, kde-format msgid "The type of curve to fit" msgstr "" #. i18n: ectx: whatsthis, entry (FocusStarMeasure), group (Focus) -#: kstars.kcfg:2018 +#: kstars.kcfg:2042 #, kde-format msgid "The type of star measure to use." msgstr "" #. i18n: ectx: whatsthis, entry (FocusStarPSF), group (Focus) -#: kstars.kcfg:2022 +#: kstars.kcfg:2046 #, kde-format msgid "The type of star PSF to use if curve fitting star profiles." msgstr "" #. i18n: ectx: whatsthis, entry (FocusUseWeights), group (Focus) -#: kstars.kcfg:2026 +#: kstars.kcfg:2050 #, kde-format msgid "Whether to use weights in the curve fitting process." msgstr "" #. i18n: ectx: whatsthis, entry (FocusR2Limit), group (Focus) -#: kstars.kcfg:2030 +#: kstars.kcfg:2054 #, kde-format msgid "The minimum acceptable R2 value of a curve fit." msgstr "" #. i18n: ectx: whatsthis, entry (FocusRefineCurveFit), group (Focus) -#: kstars.kcfg:2034 +#: kstars.kcfg:2058 #, kde-format msgid "Whether to refine the curve fit by looking for and discarding outliers." msgstr "" #. i18n: ectx: whatsthis, entry (focusFramesCount), group (Focus) -#: kstars.kcfg:2038 +#: kstars.kcfg:2062 #, kde-format msgid "How many frames to average over at each step in the Autofocus process." msgstr "" #. i18n: ectx: label, entry (FocusMultiRowAverage), group (Focus) -#: kstars.kcfg:2042 +#: kstars.kcfg:2066 #, kde-format msgid "Number of rows to combine in the Bahtinov average calculation." msgstr "" #. i18n: ectx: label, entry (FocusGaussianSigma), group (Focus) -#: kstars.kcfg:2046 +#: kstars.kcfg:2070 #, kde-format msgid "Gaussian blur sigma value." msgstr "" #. i18n: ectx: label, entry (FocusThreshold), group (Focus) -#: kstars.kcfg:2050 +#: kstars.kcfg:2074 #, kde-format msgid "" "Relative percentage strength of centroid edge pixel strength to average " @@ -33180,19 +33875,19 @@ msgstr "" #. i18n: ectx: label, entry (FocusGaussianKernelSize), group (Focus) -#: kstars.kcfg:2054 +#: kstars.kcfg:2078 #, kde-format msgid "Gaussian blur kernel size." msgstr "" #. i18n: ectx: label, entry (FocusTolerance), group (Focus) -#: kstars.kcfg:2058 +#: kstars.kcfg:2082 #, kde-format msgid "Default Focuser tolerance value" msgstr "" #. i18n: ectx: whatsthis, entry (FocusTolerance), group (Focus) -#: kstars.kcfg:2059 +#: kstars.kcfg:2083 #, kde-format msgid "" "The tolerance specifies the percentage difference between the current " @@ -33202,13 +33897,13 @@ msgstr "" #. i18n: ectx: whatsthis, entry (FocusWalk), group (Focus) -#: kstars.kcfg:2064 +#: kstars.kcfg:2088 #, kde-format msgid "The type of walk the focuser will take during an Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (FocusSettleTime), group (Focus) -#: kstars.kcfg:2068 +#: kstars.kcfg:2092 #, kde-format msgid "" "Wait for this many seconds after moving the focuser before capturing the " @@ -33216,13 +33911,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusTicks), group (Focus) -#: kstars.kcfg:2072 +#: kstars.kcfg:2096 #, kde-format msgid "Default Focuser step ticks" msgstr "" #. i18n: ectx: whatsthis, entry (FocusTicks), group (Focus) -#: kstars.kcfg:2073 +#: kstars.kcfg:2097 #, kde-format msgid "" "Step size of the absolute focuser. The step size TICKS should be adjusted so " @@ -33231,50 +33926,50 @@ msgstr "" #. i18n: ectx: whatsthis, entry (FocusOutSteps), group (Focus) -#: kstars.kcfg:2077 +#: kstars.kcfg:2101 #, kde-format msgid "The number of steps to move outwards for a Classic Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (focusNumSteps), group (Focus) -#: kstars.kcfg:2081 +#: kstars.kcfg:2105 #, kde-format msgid "" "The total number of steps for a Fixed Steps or CFZ Shuffle Autofocus run." msgstr "" #. i18n: ectx: label, entry (FocusMaxTravel), group (Focus) -#: kstars.kcfg:2085 +#: kstars.kcfg:2109 #, kde-format msgid "Maximum Focus Travel Distance" msgstr "" #. i18n: ectx: whatsthis, entry (FocusMaxTravel), group (Focus) -#: kstars.kcfg:2086 +#: kstars.kcfg:2110 #, kde-format msgid "Set the maximum travel distance of an absolute focuser." msgstr "" #. i18n: ectx: whatsthis, entry (FocusMaxSingleStep), group (Focus) -#: kstars.kcfg:2090 +#: kstars.kcfg:2114 #, kde-format msgid "The maximum size of a single step." msgstr "" #. i18n: ectx: whatsthis, entry (FocusBacklash), group (Focus) -#: kstars.kcfg:2094 +#: kstars.kcfg:2118 #, kde-format msgid "The amount of driver backlash." msgstr "" #. i18n: ectx: whatsthis, entry (FocusAFOverscan), group (Focus) -#: kstars.kcfg:2098 +#: kstars.kcfg:2122 #, kde-format msgid "The amount of Autofocus Overscan." msgstr "" #. i18n: ectx: whatsthis, entry (FocusMotionTimeout), group (Focus) -#: kstars.kcfg:2106 +#: kstars.kcfg:2130 #, kde-format msgid "" "Maximum time in seconds to wait for a focuser to move to desired position " @@ -33282,85 +33977,85 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZAlgorithm), group (Focus) -#: kstars.kcfg:2111 +#: kstars.kcfg:2135 #, kde-format msgid "The type of CFZ Algorithm to use." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZTolerance), group (Focus) -#: kstars.kcfg:2115 +#: kstars.kcfg:2139 #, kde-format msgid "The user defined tolerance to use for Classic and Wavefront algos." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZTau), group (Focus) -#: kstars.kcfg:2119 +#: kstars.kcfg:2143 #, kde-format msgid "The user defined tolerance to use for the Gold algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZDisplayVCurve), group (Focus) -#: kstars.kcfg:2123 +#: kstars.kcfg:2147 #, kde-format msgid "Whether to display the CFZ on the v-curve after an Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZWavelength), group (Focus) -#: kstars.kcfg:2127 +#: kstars.kcfg:2151 #, kde-format msgid "The wavelength in nm to use in the Gold algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZAperture), group (Focus) -#: kstars.kcfg:2131 +#: kstars.kcfg:2155 #, kde-format msgid "Telescope aperture in mm to use in CFZ calcs." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZFNumber), group (Focus) -#: kstars.kcfg:2135 +#: kstars.kcfg:2159 #, kde-format msgid "The f# to use in the CFZ algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZSeeing), group (Focus) -#: kstars.kcfg:2139 +#: kstars.kcfg:2163 #, kde-format msgid "The total seeing in arc-secs to use in the CFZ algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZStepSize), group (Focus) -#: kstars.kcfg:2143 +#: kstars.kcfg:2167 #, kde-format msgid "The size of a focuser tick in micrometers." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvSteps), group (Focus) -#: kstars.kcfg:2148 +#: kstars.kcfg:2172 #, kde-format msgid "Focus Advisor recommended step size" msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvOutStepMult), group (Focus) -#: kstars.kcfg:2152 +#: kstars.kcfg:2176 #, kde-format msgid "Focus Advisor recommended Out Step Multiple" msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvStepSize), group (Focus) -#: kstars.kcfg:2156 +#: kstars.kcfg:2180 #, kde-format msgid "Whether to accept Focus Advisor recommendation on Step Size." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvOutStepMultiple), group (Focus) -#: kstars.kcfg:2160 +#: kstars.kcfg:2184 #, kde-format msgid "Whether to accept Focus Advisor recommendation on Out Step Multiple." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvCamera), group (Focus) -#: kstars.kcfg:2164 +#: kstars.kcfg:2188 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Camera and Filter Wheel " @@ -33368,94 +34063,166 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvSettingsTab), group (Focus) -#: kstars.kcfg:2168 +#: kstars.kcfg:2192 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Settings Tab Parameters." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvProcessTab), group (Focus) -#: kstars.kcfg:2172 +#: kstars.kcfg:2196 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Process Tab Parameters." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvMechanicsTab), group (Focus) -#: kstars.kcfg:2176 +#: kstars.kcfg:2200 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Mechanics Tab Parameters." msgstr "" #. i18n: ectx: label, entry (FocusSplitter), group (Focus) -#: kstars.kcfg:2181 +#: kstars.kcfg:2205 #, fuzzy, kde-format msgid "Position of FocusSplitter." msgstr "Bereken" #. i18n: ectx: label, entry (rightLayout), group (Focus) -#: kstars.kcfg:2184 +#: kstars.kcfg:2208 #, fuzzy, kde-format msgid "Position of rightLayout." msgstr "Wissel Diep Lug Objekte" #. i18n: ectx: whatsthis, entry (adaptFocusBFO), group (Focus) -#: kstars.kcfg:2187 +#: kstars.kcfg:2211 #, kde-format msgid "Whether to use Adaptive Focus in the Build Filter Offsets utility." msgstr "" +#. i18n: ectx: whatsthis, entry (abInsTileSelection), group (Focus) +#: kstars.kcfg:2216 +#, kde-format +msgid "Which set of tiles to use in Aberration Inspector." +msgstr "" + +#. i18n: ectx: label, entry (abInsShowLabels), group (Focus) +#: kstars.kcfg:2220 +#, kde-format +msgid "Show Max Min labels on Aberration Inspector graph." +msgstr "" + +#. i18n: ectx: label, entry (abInsShowCFZ), group (Focus) +#: kstars.kcfg:2224 +#, kde-format +msgid "Show Critical Focus Zone on Aberration Inspector graph." +msgstr "" + +#. i18n: ectx: label, entry (abInsOptCentres), group (Focus) +#: kstars.kcfg:2228 +#, kde-format +msgid "Whether to optimise tile centres used in Aberration Inspector calcs." +msgstr "" + +#. i18n: ectx: label, entry (abInsHSplitter), group (Focus) +#: kstars.kcfg:2232 +#, kde-format +msgid "Position of HSplitter in Aberration Inspector." +msgstr "" + +#. i18n: ectx: label, entry (abInsVSplitter), group (Focus) +#: kstars.kcfg:2235 +#, kde-format +msgid "Position of VSplitter in Aberration Inspector." +msgstr "" + +#. i18n: ectx: whatsthis, entry (abInsSelection), group (Focus) +#: kstars.kcfg:2238 +#, kde-format +msgid "Aberration Inspector 3D graphic selection mode." +msgstr "" + +#. i18n: ectx: whatsthis, entry (abInsTheme), group (Focus) +#: kstars.kcfg:2242 +#, kde-format +msgid "Aberration Inspector 3D graphic theme." +msgstr "" + +#. i18n: ectx: label, entry (abInsLabels), group (Focus) +#: kstars.kcfg:2246 +#, kde-format +msgid "Aberration Inspector 3D graphic show labels." +msgstr "" + +#. i18n: ectx: label, entry (abInsSensor), group (Focus) +#: kstars.kcfg:2250 +#, kde-format +msgid "Aberration Inspector 3D graphic show sensor." +msgstr "" + +#. i18n: ectx: label, entry (abInsPetzvalWire), group (Focus) +#: kstars.kcfg:2254 +#, kde-format +msgid "Aberration Inspector 3D graphic show Petzval wire." +msgstr "" + +#. i18n: ectx: label, entry (abInsPetzvalSurface), group (Focus) +#: kstars.kcfg:2258 +#, kde-format +msgid "Aberration Inspector 3D graphic show Petzval surface." +msgstr "" + #. i18n: ectx: label, entry (FocusSextractorType), group (StellarSolver) -#: kstars.kcfg:2194 +#: kstars.kcfg:2264 #, fuzzy, kde-format msgid "Internal or External Sextractor for Focusing." msgstr "St. Peter Poort" #. i18n: ectx: label, entry (FocusOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2198 +#: kstars.kcfg:2268 #, kde-format msgid "Options Profile for Sextraction when Focusing." msgstr "" #. i18n: ectx: label, entry (HFRSextractorType), group (StellarSolver) -#: kstars.kcfg:2202 +#: kstars.kcfg:2272 #, fuzzy, kde-format msgid "Internal or External Sextractor to compute subs HFR." msgstr "St. Peter Poort" #. i18n: ectx: label, entry (HFROptionsProfile), group (StellarSolver) -#: kstars.kcfg:2206 +#: kstars.kcfg:2276 #, kde-format msgid "Options Profile for Sextraction to compute subs HFR" msgstr "" #. i18n: ectx: label, entry (GuideSextractorType), group (StellarSolver) -#: kstars.kcfg:2210 +#: kstars.kcfg:2280 #, fuzzy, kde-format msgid "Internal or External Sextractor for Guiding." msgstr "St. Peter Poort" #. i18n: ectx: label, entry (GuideOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2214 +#: kstars.kcfg:2284 #, kde-format msgid "Options Profile for Sextraction when Guiding." msgstr "" #. i18n: ectx: label, entry (SolveSextractorType), group (StellarSolver) -#: kstars.kcfg:2218 +#: kstars.kcfg:2288 #, fuzzy, kde-format msgid "Internal, External, or BuiltIn Sextractor for Solving." msgstr "St. Peter Poort" #. i18n: ectx: label, entry (SolverMode), group (StellarSolver) -#: kstars.kcfg:2222 +#: kstars.kcfg:2292 #, kde-format msgid "Local (0) or Remote (1) solver." msgstr "" #. i18n: ectx: label, entry (SolverType), group (StellarSolver) -#: kstars.kcfg:2226 +#: kstars.kcfg:2296 #, kde-format msgid "" "Local solving method. 0 for Internal Solver. 1 for Local Astrometry. 2 for " @@ -33463,98 +34230,98 @@ msgstr "" #. i18n: ectx: label, entry (SolveOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2230 +#: kstars.kcfg:2300 #, kde-format msgid "Options Profile for Solving." msgstr "" #. i18n: ectx: label, entry (LoggerLevel), group (StellarSolver) -#: kstars.kcfg:2234 +#: kstars.kcfg:2304 #, kde-format msgid "Level of verbosity in the log." msgstr "" #. i18n: ectx: label, entry (AstrometryLogToFile), group (StellarSolver) -#: kstars.kcfg:2238 +#: kstars.kcfg:2308 #, kde-format msgid "Whether to log to a file instead." msgstr "" #. i18n: ectx: label, entry (AstrometryLogFilepath), group (StellarSolver) -#: kstars.kcfg:2242 +#: kstars.kcfg:2312 #, kde-format msgid "Path of the log file to save astrometry logging to." msgstr "" #. i18n: ectx: label, entry (AstrometryIndexFolderList), group (StellarSolver) -#: kstars.kcfg:2246 +#: kstars.kcfg:2316 #, fuzzy, kde-format msgid "List of index folder paths." msgstr "Ander Katalogusse" #. i18n: ectx: whatsthis, entry (AstrometryIndexFolderList), group (StellarSolver) -#: kstars.kcfg:2247 +#: kstars.kcfg:2317 #, kde-format msgid "List of folders in which astrometry Index Files can be found." msgstr "" #. i18n: ectx: label, entry (AlignExposure), group (Align) -#: kstars.kcfg:2253 +#: kstars.kcfg:2323 #, kde-format msgid "Default alignment exposure value" msgstr "" #. i18n: ectx: whatsthis, entry (AlignExposure), group (Align) -#: kstars.kcfg:2254 +#: kstars.kcfg:2324 #, kde-format msgid "" "Specifies exposure value of camera in seconds when performing plate solving." msgstr "" #. i18n: ectx: label, entry (AlignBinning), group (Align) -#: kstars.kcfg:2258 +#: kstars.kcfg:2328 #, fuzzy, kde-format msgid "Default camera binning in alignment mode" msgstr "Noorweë" #. i18n: ectx: label, entry (AlignGain), group (Align) -#: kstars.kcfg:2262 +#: kstars.kcfg:2332 #, fuzzy, kde-format msgid "Default camera gain in alignment mode" msgstr "Noorweë" #. i18n: ectx: label, entry (AlignISO), group (Align) -#: kstars.kcfg:2266 +#: kstars.kcfg:2336 #, fuzzy, kde-format msgid "Default camera ISO in alignment mode" msgstr "Planeet" #. i18n: ectx: label, entry (AlignDarkFrame), group (Align) -#: kstars.kcfg:2270 +#: kstars.kcfg:2340 #, kde-format msgid "Take a dark frame and subtract it before running astrometry operation." msgstr "" #. i18n: ectx: label, entry (AlignFilter), group (Align) -#: kstars.kcfg:2274 +#: kstars.kcfg:2344 #, fuzzy, kde-format msgid "Default filter wheel filter in alignment mode" msgstr "Planeet" #. i18n: ectx: label, entry (AlignUseCurrentFilter), group (Align) -#: kstars.kcfg:2277 +#: kstars.kcfg:2347 #, fuzzy, kde-format msgid "Use currently selected filter in alignment mode." msgstr "Planeet" #. i18n: ectx: whatsthis, entry (AstrometryUseRotator), group (Align) -#: kstars.kcfg:2281 +#: kstars.kcfg:2351 #, kde-format msgid "Use rotator when performing load and slew." msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryRotatorThreshold), group (Align) -#: kstars.kcfg:2285 +#: kstars.kcfg:2355 #, kde-format msgid "" "Threshold between measured and FITS position angles in arcminutes to " @@ -33562,19 +34329,19 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryFlipRotationAllowed), group (Align) -#: kstars.kcfg:2289 +#: kstars.kcfg:2359 #, kde-format msgid "PA 180° rotation for rotator is accepted after mount flip." msgstr "" #. i18n: ectx: label, entry (SolverGotoOption), group (Align) -#: kstars.kcfg:2293 +#: kstars.kcfg:2363 #, kde-format msgid "Action to take if solver if successful (Sync, Slew to Target, or None)" msgstr "" #. i18n: ectx: label, entry (AstrometrySolverWCS), group (Align) -#: kstars.kcfg:2297 +#: kstars.kcfg:2367 #, kde-format msgid "" "World Coordinate System (WCS). WCS is used to encode RA/DEC coordinates in " @@ -33582,13 +34349,13 @@ msgstr "" #. i18n: ectx: label, entry (AstrometrySolverOverlay), group (Align) -#: kstars.kcfg:2301 +#: kstars.kcfg:2371 #, kde-format msgid "Display received FITS images unto solver FOV rectangle in the sky map." msgstr "" #. i18n: ectx: label, entry (AstrometryDifferentialSlewing), group (Align) -#: kstars.kcfg:2305 +#: kstars.kcfg:2375 #, kde-format msgid "" "Do not use Sync when Slew to Target is selected. Use differential slewing to " @@ -33596,14 +34363,14 @@ msgstr "" #. i18n: ectx: label, entry (AlignAccuracyThreshold), group (Align) -#: kstars.kcfg:2309 +#: kstars.kcfg:2379 #, kde-format msgid "" "Accuracy threshold in arcseconds between solution and target coordinates." msgstr "" #. i18n: ectx: label, entry (AlignSettlingTime), group (Align) -#: kstars.kcfg:2313 +#: kstars.kcfg:2383 #, kde-format msgid "" "Time to wait in milliseconds after telescope slewing is complete before " @@ -33611,7 +34378,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseNoFITS2FITS), group (Align) -#: kstars.kcfg:2317 +#: kstars.kcfg:2387 #, kde-format msgid "" "Do not sanitize FITS. This option should only be checked if astrometry.net " @@ -33619,7 +34386,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseResort), group (Align) -#: kstars.kcfg:2321 +#: kstars.kcfg:2391 #, kde-format msgid "" "Check this option if your image does not have much nebulosity. If it does " @@ -33627,7 +34394,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseNoVerify), group (Align) -#: kstars.kcfg:2325 +#: kstars.kcfg:2395 #, kde-format msgid "" "This will prevent the solver from looking at an already existing WCS Header " @@ -33636,137 +34403,137 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleLow), group (Align) -#: kstars.kcfg:2333 +#: kstars.kcfg:2403 #, kde-format msgid "Lower image scale." msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleHigh), group (Align) -#: kstars.kcfg:2336 +#: kstars.kcfg:2406 #, fuzzy, kde-format msgid "Upper image scale." msgstr "Stoor Beeld" #. i18n: ectx: label, entry (AstrometryAutoUpdateImageScale), group (Align) -#: kstars.kcfg:2339 +#: kstars.kcfg:2409 #, kde-format msgid "" "Automatically update image scale when CCD or Mount parameters are updated." msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleUnits), group (Align) -#: kstars.kcfg:2343 +#: kstars.kcfg:2413 #, kde-format msgid "" "Image scale units in arcminutes (aw), degrees (dw), or arcsec per pixel (app)" msgstr "" #. i18n: ectx: label, entry (AstrometryUseDownsample), group (Align) -#: kstars.kcfg:2347 +#: kstars.kcfg:2417 #, kde-format msgid "Downsample the image to shrink its size and speed up the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryDownsample), group (Align) -#: kstars.kcfg:2351 +#: kstars.kcfg:2421 #, fuzzy, kde-format msgid "Downsample factor" msgstr "Invoer Keuse" #. i18n: ectx: label, entry (AstrometryAutoDownsample), group (Align) -#: kstars.kcfg:2355 +#: kstars.kcfg:2425 #, fuzzy, kde-format msgid "Automatically downsample based on image size." msgstr "Lang.:" #. i18n: ectx: label, entry (AstrometryPositionRA), group (Align) -#: kstars.kcfg:2363 +#: kstars.kcfg:2433 #, kde-format msgid "" "User supplied Right Ascension value in degrees to be passed to the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryPositionDE), group (Align) -#: kstars.kcfg:2366 +#: kstars.kcfg:2436 #, kde-format msgid "User supplied declination value in degrees to be passed to the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryAutoUpdatePosition), group (Align) -#: kstars.kcfg:2369 +#: kstars.kcfg:2439 #, kde-format msgid "" "Automatically update position coordinates when mounts completes slewing." msgstr "" #. i18n: ectx: label, entry (AstrometryDetectParity), group (Align) -#: kstars.kcfg:2377 +#: kstars.kcfg:2447 #, kde-format msgid "Detect parity and reuse it to speed up solver." msgstr "" #. i18n: ectx: label, entry (AstrometryCustomOptions), group (Align) -#: kstars.kcfg:2381 +#: kstars.kcfg:2451 #, kde-format msgid "Additional optional astrometry.net options" msgstr "" #. i18n: ectx: label, entry (AstrometrySolverBinary), group (Align) -#: kstars.kcfg:2384 +#: kstars.kcfg:2454 #, kde-format msgid "astrometry.net solve-field binary" msgstr "" #. i18n: ectx: whatsthis, entry (AstrometrySolverBinary), group (Align) -#: kstars.kcfg:2385 +#: kstars.kcfg:2455 #, kde-format msgid "Path to astrometry.net solver location." msgstr "" #. i18n: ectx: label, entry (AstrometryWCSInfo), group (Align) -#: kstars.kcfg:2389 +#: kstars.kcfg:2459 #, kde-format msgid "astrometry.net wcsinfo binary" msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryWCSInfo), group (Align) -#: kstars.kcfg:2390 +#: kstars.kcfg:2460 #, kde-format msgid "Path to astrometry.net wcsinfo location." msgstr "" #. i18n: ectx: label, entry (AstrometryConfFile), group (Align) -#: kstars.kcfg:2394 +#: kstars.kcfg:2464 #, kde-format msgid "astrometry.net configuration file" msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryConfFile), group (Align) -#: kstars.kcfg:2395 +#: kstars.kcfg:2465 #, kde-format msgid "Path to astrometry.net file location." msgstr "" #. i18n: ectx: whatsthis, entry (SextractorBinary), group (Align) -#: kstars.kcfg:2400 +#: kstars.kcfg:2470 #, kde-format msgid "Path to the Sextractor executable." msgstr "" #. i18n: ectx: whatsthis, entry (WatneyBinary), group (Align) -#: kstars.kcfg:2405 +#: kstars.kcfg:2475 #, kde-format msgid "Path to the Watney Solver executable." msgstr "" #. i18n: ectx: label, entry (AstrometryAPIKey), group (Align) -#: kstars.kcfg:2409 +#: kstars.kcfg:2479 #, kde-format msgid "astrometry.net API Key" msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryAPIKey), group (Align) -#: kstars.kcfg:2410 +#: kstars.kcfg:2480 #, kde-format msgid "" "Key to access astrometry.net online web services. You must register with " @@ -33774,13 +34541,13 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryAPIURL), group (Align) -#: kstars.kcfg:2414 +#: kstars.kcfg:2484 #, kde-format msgid "astrometry.net API URL" msgstr "" #. i18n: ectx: label, entry (AstrometryUseJPEG), group (Align) -#: kstars.kcfg:2418 +#: kstars.kcfg:2488 #, kde-format msgid "" "Use JPEG format, instead of FITS, to upload images to the astrometry.net " @@ -33788,37 +34555,37 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryTimeout), group (Align) -#: kstars.kcfg:2422 +#: kstars.kcfg:2492 #, kde-format msgid "Timeout in seconds to wait for astrometry solver to complete." msgstr "" #. i18n: ectx: label, entry (PAHMountSpeed), group (Align) -#: kstars.kcfg:2426 +#: kstars.kcfg:2496 #, fuzzy, kde-format msgid "Speed to set mount in Polar Alignment Assistant Tool." msgstr "Vertoon naam" #. i18n: ectx: label, entry (PAHRotaion), group (Align) -#: kstars.kcfg:2429 +#: kstars.kcfg:2499 #, kde-format msgid "Rotate mount by this many degrees during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHRefreshAlgorithm), group (Align) -#: kstars.kcfg:2433 +#: kstars.kcfg:2503 #, kde-format msgid "The algorithm used for polar-align refresh." msgstr "" #. i18n: ectx: label, entry (PAHDirection), group (Align) -#: kstars.kcfg:2436 +#: kstars.kcfg:2506 #, kde-format msgid "Mount rotation direction during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHAutoPark), group (Align) -#: kstars.kcfg:2439 +#: kstars.kcfg:2509 #, kde-format msgid "" "Automatically park the mount after Polar Alignment Assistant Tool is " @@ -33826,32 +34593,32 @@ msgstr "" #. i18n: ectx: label, entry (PAHManualSlew), group (Align) -#: kstars.kcfg:2443 +#: kstars.kcfg:2513 #, kde-format msgid "" "User should manually rotate the mount about its axis during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHExposure), group (Align) -#: kstars.kcfg:2447 +#: kstars.kcfg:2517 #, fuzzy, kde-format msgid "Polar Alignment Assistant exposure duration in seconds." msgstr "Dag duur" #. i18n: ectx: label, entry (GuideExposure), group (Guide) -#: kstars.kcfg:2453 +#: kstars.kcfg:2523 #, kde-format msgid "Guider exposure duration in seconds." msgstr "" #. i18n: ectx: label, entry (GuideDelay), group (Guide) -#: kstars.kcfg:2457 +#: kstars.kcfg:2527 #, fuzzy, kde-format msgid "Delay next exposure by this many seconds." msgstr "Dag duur" #. i18n: ectx: label, entry (GuiderType), group (Guide) -#: kstars.kcfg:2461 +#: kstars.kcfg:2531 #, kde-format msgid "" "Which guider process to utilize for guiding (0 Internal Guider, 1 PHD2, 2 " @@ -33859,7 +34626,7 @@ msgstr "" #. i18n: ectx: label, entry (GuideAlgorithm), group (Guide) -#: kstars.kcfg:2465 +#: kstars.kcfg:2535 #, kde-format msgid "" "Which Algorithm to use track guide square (0 smart, 1 SEP, 2 fast, 3 " @@ -33867,31 +34634,31 @@ msgstr "" #. i18n: ectx: label, entry (PHD2Host), group (Guide) -#: kstars.kcfg:2469 +#: kstars.kcfg:2539 #, kde-format msgid "Host name of external PHD2 service" msgstr "" #. i18n: ectx: label, entry (PHD2Port), group (Guide) -#: kstars.kcfg:2473 +#: kstars.kcfg:2543 #, kde-format msgid "PHD2 Event Monitoring Port" msgstr "" #. i18n: ectx: label, entry (LinGuiderHost), group (Guide) -#: kstars.kcfg:2477 +#: kstars.kcfg:2547 #, kde-format msgid "Host name of external lin_guider service" msgstr "" #. i18n: ectx: label, entry (LinGuiderPort), group (Guide) -#: kstars.kcfg:2481 +#: kstars.kcfg:2551 #, kde-format msgid "Lin_guider Event Monitoring Port" msgstr "" #. i18n: ectx: label, entry (CalibrationPulseDuration), group (Guide) -#: kstars.kcfg:2485 +#: kstars.kcfg:2555 #, kde-format msgid "" "Pulse duration in milliseconds used for guiding pulses during calibration " @@ -33899,67 +34666,67 @@ msgstr "" #. i18n: ectx: label, entry (GuideSquareSize), group (Guide) -#: kstars.kcfg:2493 +#: kstars.kcfg:2563 #, kde-format msgid "Guide square size selection in pixels." msgstr "" #. i18n: ectx: label, entry (GuideBinning), group (Guide) -#: kstars.kcfg:2497 +#: kstars.kcfg:2567 #, fuzzy, kde-format msgid "Guide binning." msgstr "niks" #. i18n: ectx: label, entry (GuideAutoStar), group (Guide) -#: kstars.kcfg:2501 +#: kstars.kcfg:2571 #, fuzzy, kde-format msgid "Automatically select calibration star and perform calibration." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (AutoModeIterations), group (Guide) -#: kstars.kcfg:2509 +#: kstars.kcfg:2579 #, kde-format msgid "Number of automode iterations for calibration process." msgstr "" #. i18n: ectx: label, entry (GuideLostStarTimeout), group (Guide) -#: kstars.kcfg:2513 +#: kstars.kcfg:2583 #, kde-format msgid "When star tracking is lost, wait this many seconds before aborting." msgstr "" #. i18n: ectx: label, entry (GuideCalibrationTimeout), group (Guide) -#: kstars.kcfg:2517 +#: kstars.kcfg:2587 #, kde-format msgid "When calibration starts, wait this many seconds before aborting." msgstr "" #. i18n: ectx: label, entry (GuideMaxDeltaRMS), group (Guide) -#: kstars.kcfg:2521 +#: kstars.kcfg:2591 #, kde-format msgid "Maximum delta RMS permitted while guiding before aborting." msgstr "" #. i18n: ectx: label, entry (GuideMaxHFR), group (Guide) -#: kstars.kcfg:2525 +#: kstars.kcfg:2595 #, kde-format msgid "Maximum HFR permitted for SEP MultiStar guide star." msgstr "" #. i18n: ectx: label, entry (MaxMultistarReferenceStars), group (Guide) -#: kstars.kcfg:2533 +#: kstars.kcfg:2603 #, kde-format msgid "Maximum number of SEP MultiStar number of stars used as references." msgstr "" #. i18n: ectx: label, entry (TwoAxisEnabled), group (Guide) -#: kstars.kcfg:2537 +#: kstars.kcfg:2607 #, kde-format msgid "Use both axes to perform calibration." msgstr "" #. i18n: ectx: label, entry (UseGuideHead), group (Guide) -#: kstars.kcfg:2541 +#: kstars.kcfg:2611 #, kde-format msgid "" "Use the guider chip for guiding from cameras that have a dedicated guider " @@ -33967,25 +34734,25 @@ msgstr "" #. i18n: ectx: label, entry (SaveGuideLog), group (Guide) -#: kstars.kcfg:2545 +#: kstars.kcfg:2615 #, fuzzy, kde-format msgid "Automatically save internal guider user logs." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (GuideDarkFrame), group (Guide) -#: kstars.kcfg:2549 +#: kstars.kcfg:2619 #, kde-format msgid "Take dark frame for autoguider images." msgstr "" #. i18n: ectx: label, entry (GuideSubframe), group (Guide) -#: kstars.kcfg:2553 +#: kstars.kcfg:2623 #, kde-format msgid "Subframe guide image around selected region" msgstr "" #. i18n: ectx: label, entry (DitherPixels), group (Guide) -#: kstars.kcfg:2557 +#: kstars.kcfg:2627 #, kde-format msgid "" "How many pixels to move between subsequent exposures under auto dithering " @@ -33993,43 +34760,43 @@ msgstr "" #. i18n: ectx: label, entry (DitherFrames), group (Guide) -#: kstars.kcfg:2561 +#: kstars.kcfg:2631 #, kde-format msgid "Dither after this many frames." msgstr "" #. i18n: ectx: label, entry (DitherThreshold), group (Guide) -#: kstars.kcfg:2569 +#: kstars.kcfg:2639 #, kde-format msgid "Maximum distance (pixels) for guiding to be considered settled." msgstr "" #. i18n: ectx: label, entry (DitherTimeout), group (Guide) -#: kstars.kcfg:2573 +#: kstars.kcfg:2643 #, kde-format msgid "Time limit (seconds) on dithering to settle down." msgstr "" #. i18n: ectx: label, entry (DitherMaxIterations), group (Guide) -#: kstars.kcfg:2577 +#: kstars.kcfg:2647 #, kde-format msgid "How many dithering attempts to undertake before giving up." msgstr "" #. i18n: ectx: label, entry (DitherNoGuidingPulse), group (Guide) -#: kstars.kcfg:2581 +#: kstars.kcfg:2651 #, kde-format msgid "Pulse length in milliseconds used for non-guiding dither." msgstr "" #. i18n: ectx: label, entry (DitherFailAbortsAutoGuide), group (Guide) -#: kstars.kcfg:2585 +#: kstars.kcfg:2655 #, fuzzy, kde-format msgid "If dithering fails then abort autoguide." msgstr "Soek Voorwerp" #. i18n: ectx: label, entry (DitherWithOnePulse), group (Guide) -#: kstars.kcfg:2589 +#: kstars.kcfg:2659 #, kde-format msgid "" "Dithering amount is randomly generated, pulses are sent, but the resultant " @@ -34040,171 +34807,171 @@ msgstr "" #. i18n: ectx: label, entry (DitherEnabled), group (Guide) -#: kstars.kcfg:2593 +#: kstars.kcfg:2663 #, kde-format msgid "Use Auto Dithering when guiding." msgstr "" #. i18n: ectx: label, entry (DitherNoGuiding), group (Guide) -#: kstars.kcfg:2597 +#: kstars.kcfg:2667 #, fuzzy, kde-format msgid "Perform dithering even when not guiding." msgstr "Soek Voorwerp" #. i18n: ectx: label, entry (RAGuideEnabled), group (Guide) -#: kstars.kcfg:2601 +#: kstars.kcfg:2671 #, kde-format msgid "Enable autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (DECGuideEnabled), group (Guide) -#: kstars.kcfg:2605 +#: kstars.kcfg:2675 #, kde-format msgid "Enable autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (NorthDECGuideEnabled), group (Guide) -#: kstars.kcfg:2609 +#: kstars.kcfg:2679 #, kde-format msgid "Enable North autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (SouthDECGuideEnabled), group (Guide) -#: kstars.kcfg:2613 +#: kstars.kcfg:2683 #, kde-format msgid "Enable South autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (EastRAGuideEnabled), group (Guide) -#: kstars.kcfg:2617 +#: kstars.kcfg:2687 #, kde-format msgid "Enable East autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (WestRAGuideEnabled), group (Guide) -#: kstars.kcfg:2621 +#: kstars.kcfg:2691 #, kde-format msgid "Enable West autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (GuiderAccuracyThreshold), group (Guide) -#: kstars.kcfg:2700 +#: kstars.kcfg:2770 #, kde-format msgid "Accuracy threshold for the Guide Graphs." msgstr "" #. i18n: ectx: label, entry (RADisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2704 +#: kstars.kcfg:2774 #, kde-format msgid "Display the RA Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (DEDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2708 +#: kstars.kcfg:2778 #, kde-format msgid "Display the DEC Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (RACorrDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2712 +#: kstars.kcfg:2782 #, kde-format msgid "Display the RA Corrections Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (DECorrDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2716 +#: kstars.kcfg:2786 #, kde-format msgid "Display the DEC Corrections Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (SNRDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2720 +#: kstars.kcfg:2790 #, kde-format msgid "Display the SNR Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (RMSDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2724 +#: kstars.kcfg:2794 #, kde-format msgid "Display the RMS Error Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (SchedulerAlgorithm), group (Scheduler) -#: kstars.kcfg:2730 +#: kstars.kcfg:2800 #, fuzzy, kde-format msgid "Scheduler algorithm" msgstr "Ongeldige Url" #. i18n: ectx: whatsthis, entry (SchedulerLogging), group (Scheduler) -#: kstars.kcfg:2734 +#: kstars.kcfg:2804 #, fuzzy, kde-format msgid "Log Ekos Scheduler Module activity." msgstr "Voeg by na Lys" #. i18n: ectx: label, entry (StopEkosAfterShutdown), group (Scheduler) -#: kstars.kcfg:2738 +#: kstars.kcfg:2808 #, kde-format msgid "" "After shutdown procedure is successfully executed, shutdown INDI and Ekos." msgstr "" #. i18n: ectx: label, entry (ShutdownScriptTerminatesINDI), group (Scheduler) -#: kstars.kcfg:2742 +#: kstars.kcfg:2812 #, kde-format msgid "" "Whether shutdown script, if exists, terminates INDI server in the process." msgstr "" #. i18n: ectx: label, entry (PreemptiveShutdown), group (Scheduler) -#: kstars.kcfg:2746 +#: kstars.kcfg:2816 #, kde-format msgid "Perform pre-emptive shutdown if no jobs are due for a number of hours." msgstr "" #. i18n: ectx: label, entry (ResetMountModelOnAlignFail), group (Scheduler) -#: kstars.kcfg:2750 +#: kstars.kcfg:2820 #, kde-format msgid "Reset mount model in case of alignment failure." msgstr "" #. i18n: ectx: label, entry (ResetMountModelBeforeJob), group (Scheduler) -#: kstars.kcfg:2754 +#: kstars.kcfg:2824 #, fuzzy, kde-format msgid "Reset mount model before starting each job." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ResetGuideCalibration), group (Scheduler) -#: kstars.kcfg:2758 +#: kstars.kcfg:2828 #, fuzzy, kde-format msgid "Always Reset guiding calibration before starting each job." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ForceAlignmentBeforeJob), group (Scheduler) -#: kstars.kcfg:2762 +#: kstars.kcfg:2832 #, fuzzy, kde-format msgid "Force alignment before starting or restarting each job." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ReuseGuideCalibration), group (Scheduler) -#: kstars.kcfg:2766 +#: kstars.kcfg:2836 #, fuzzy, kde-format msgid "Guider may re-use guiding calibration if one is available." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (GuideCalibrationBacklash), group (Scheduler) -#: kstars.kcfg:2774 +#: kstars.kcfg:2844 #, kde-format msgid "Remove DEC backlash when calibrating guider." msgstr "" #. i18n: ectx: label, entry (SerializedCalibration), group (Scheduler) -#: kstars.kcfg:2778 +#: kstars.kcfg:2848 #, fuzzy, kde-format msgid "Last Calibration serialized." msgstr "Bereken" #. i18n: ectx: label, entry (RealignAfterCalibrationFailure), group (Scheduler) -#: kstars.kcfg:2781 +#: kstars.kcfg:2851 #, kde-format msgid "" "If guiding calibration fails, run alignment process again before proceeding " @@ -34212,7 +34979,7 @@ msgstr "" #. i18n: ectx: label, entry (PreemptiveShutdownTime), group (Scheduler) -#: kstars.kcfg:2785 +#: kstars.kcfg:2855 #, kde-format msgid "" "Maximum number of hours before the next job is due to trigger a pre-emptive " @@ -34220,21 +34987,29 @@ msgstr "" #. i18n: ectx: label, entry (RememberJobProgress), group (Scheduler) -#: kstars.kcfg:2789 +#: kstars.kcfg:2859 #, kde-format msgid "" "When processing a scheduled job, resume the sequence starting from the last " "image present in storage." msgstr "" +#. i18n: ectx: label, entry (GreedyScheduling), group (Scheduler) +#: kstars.kcfg:2863 +#, kde-format +msgid "" +"When true, the scheduler tries to run lower priority jobs when no higher " +"priority job can run. Recommended." +msgstr "" + #. i18n: ectx: label, entry (LeadTime), group (Scheduler) -#: kstars.kcfg:2793 +#: kstars.kcfg:2867 #, kde-format msgid "Minimum time between jobs in minutes." msgstr "" #. i18n: ectx: label, entry (PreDawnTime), group (Scheduler) -#: kstars.kcfg:2797 +#: kstars.kcfg:2871 #, kde-format msgid "" "Do not permit jobs to be scheduled or executed past this many minutes before " @@ -34242,7 +35017,7 @@ msgstr "" #. i18n: ectx: label, entry (SettingAltitudeCutoff), group (Scheduler) -#: kstars.kcfg:2801 +#: kstars.kcfg:2875 #, kde-format msgid "" "Do not permit jobs to be scheduled less than this many degrees before the " @@ -34250,7 +35025,7 @@ msgstr "" #. i18n: ectx: label, entry (DawnOffset), group (Scheduler) -#: kstars.kcfg:2805 +#: kstars.kcfg:2879 #, kde-format msgid "" "Offset astronomical dawn by this many hours to relax twilight restriction " @@ -34258,7 +35033,7 @@ msgstr "" #. i18n: ectx: label, entry (DuskOffset), group (Scheduler) -#: kstars.kcfg:2809 +#: kstars.kcfg:2883 #, kde-format msgid "" "Offset astronomical dusk by this many hours to relax twilight restriction " @@ -34266,55 +35041,55 @@ msgstr "" #. i18n: ectx: label, entry (TelescopeFocalLength), group (Scheduler) -#: kstars.kcfg:2813 +#: kstars.kcfg:2887 #, fuzzy, kde-format msgid "Telescope focal length in millimeters." msgstr "Planeet" #. i18n: ectx: label, entry (TelescopeFocalReducer), group (Scheduler) -#: kstars.kcfg:2817 +#: kstars.kcfg:2891 #, fuzzy, kde-format msgid "Focal Reducer ratio" msgstr "Ster Naam" #. i18n: ectx: label, entry (CameraPixelWidth), group (Scheduler) -#: kstars.kcfg:2821 +#: kstars.kcfg:2895 #, kde-format msgid "Camera pixel size width in micrometers." msgstr "" #. i18n: ectx: label, entry (CameraPixelHeight), group (Scheduler) -#: kstars.kcfg:2825 +#: kstars.kcfg:2899 #, kde-format msgid "Camera pixel size height in micrometers." msgstr "" #. i18n: ectx: label, entry (CameraWidth), group (Scheduler) -#: kstars.kcfg:2829 +#: kstars.kcfg:2903 #, kde-format msgid "Camera Width in pixels." msgstr "" #. i18n: ectx: label, entry (CameraHeight), group (Scheduler) -#: kstars.kcfg:2833 +#: kstars.kcfg:2907 #, kde-format msgid "Camera Height in pixels." msgstr "" #. i18n: ectx: label, entry (CameraRotation), group (Scheduler) -#: kstars.kcfg:2837 +#: kstars.kcfg:2911 #, kde-format msgid "Position angle of the camera with respect to north." msgstr "" #. i18n: ectx: label, entry (ErrorHandlingStrategy), group (Scheduler) -#: kstars.kcfg:2841 +#: kstars.kcfg:2915 #, kde-format msgid "Strategy how to react, when a job aborts or steps into an error." msgstr "" #. i18n: ectx: label, entry (ErrorHandlingStrategyDelay), group (Scheduler) -#: kstars.kcfg:2845 +#: kstars.kcfg:2919 #, kde-format msgid "" "Delay in minutes how long the scheduler should pause before restarting an " @@ -34322,139 +35097,139 @@ msgstr "" #. i18n: ectx: label, entry (RescheduleErrors), group (Scheduler) -#: kstars.kcfg:2849 +#: kstars.kcfg:2923 #, kde-format msgid "Re-schedule jobs that ran into errors." msgstr "" #. i18n: ectx: label, entry (SchedulerParkDome), group (Scheduler) -#: kstars.kcfg:2861 +#: kstars.kcfg:2935 #, kde-format msgid "Default scheduler checkbox for parking dome on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerParkMount), group (Scheduler) -#: kstars.kcfg:2865 +#: kstars.kcfg:2939 #, kde-format msgid "Default scheduler checkbox for parking mount on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerCloseDustCover), group (Scheduler) -#: kstars.kcfg:2869 +#: kstars.kcfg:2943 #, kde-format msgid "Default scheduler checkbox for closing dust cover on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerWarmCCD), group (Scheduler) -#: kstars.kcfg:2873 +#: kstars.kcfg:2947 #, kde-format msgid "Default scheduler checkbox for warming the CCD on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerUnparkDome), group (Scheduler) -#: kstars.kcfg:2877 +#: kstars.kcfg:2951 #, kde-format msgid "Default scheduler checkbox for unparking dome on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerUnparkMount), group (Scheduler) -#: kstars.kcfg:2881 +#: kstars.kcfg:2955 #, kde-format msgid "Default scheduler checkbox for unparking mount on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerOpenDustCover), group (Scheduler) -#: kstars.kcfg:2885 +#: kstars.kcfg:2959 #, kde-format msgid "Default scheduler checkbox for opening dust cover on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerTrackStep), group (Scheduler) -#: kstars.kcfg:2889 +#: kstars.kcfg:2963 #, kde-format msgid "Default scheduler checkbox for starting mount tracking on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerFocusStep), group (Scheduler) -#: kstars.kcfg:2893 +#: kstars.kcfg:2967 #, kde-format msgid "Default scheduler checkbox for running autofocus on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerGuideStep), group (Scheduler) -#: kstars.kcfg:2897 +#: kstars.kcfg:2971 #, kde-format msgid "Default scheduler checkbox for starting guiding on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerAlignStep), group (Scheduler) -#: kstars.kcfg:2901 +#: kstars.kcfg:2975 #, kde-format msgid "Default scheduler checkbox for aligning on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerAltitude), group (Scheduler) -#: kstars.kcfg:2905 +#: kstars.kcfg:2979 #, kde-format msgid "Default scheduler checkbox for job altitude constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerAltitudeValue), group (Scheduler) -#: kstars.kcfg:2909 +#: kstars.kcfg:2983 #, kde-format msgid "Default scheduler job altitude constraint." msgstr "" #. i18n: ectx: label, entry (SchedulerHorizon), group (Scheduler) -#: kstars.kcfg:2913 +#: kstars.kcfg:2987 #, fuzzy, kde-format msgid "Default scheduler checkbox for job artificial horizon constraints." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (SchedulerMoonSeparation), group (Scheduler) -#: kstars.kcfg:2917 +#: kstars.kcfg:2991 #, kde-format msgid "Default scheduler checkbox for job moon separation constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerMoonSeparationValue), group (Scheduler) -#: kstars.kcfg:2921 +#: kstars.kcfg:2995 #, kde-format msgid "Default scheduler job moon separation constraint." msgstr "" #. i18n: ectx: label, entry (SchedulerWeather), group (Scheduler) -#: kstars.kcfg:2925 +#: kstars.kcfg:2999 #, kde-format msgid "Default scheduler checkbox for job weather constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerTwilight), group (Scheduler) -#: kstars.kcfg:2929 +#: kstars.kcfg:3003 #, kde-format msgid "Default scheduler checkbox for job twilight constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerRepeatSequences), group (Scheduler) -#: kstars.kcfg:2933 +#: kstars.kcfg:3007 #, kde-format msgid "Restart sequences as soon as all sequences have been completed." msgstr "" #. i18n: ectx: label, entry (SchedulerExecutionSequencesLimit), group (Scheduler) -#: kstars.kcfg:2937 +#: kstars.kcfg:3011 #, kde-format msgid "Limit how many times the scheduler should execute all sequences." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeHFR), group (Analyze) -#: kstars.kcfg:2943 +#: kstars.kcfg:3017 #, kde-format msgid "Display HFR on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeNumCaptureStars), group (Analyze) -#: kstars.kcfg:2947 +#: kstars.kcfg:3021 #, kde-format msgid "" "Display number of stars detected in the capture on the Analyze Statistics " @@ -34462,14 +35237,14 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMedian), group (Analyze) -#: kstars.kcfg:2951 +#: kstars.kcfg:3025 #, kde-format msgid "" "Display median sample value for the capture on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeEccentricity), group (Analyze) -#: kstars.kcfg:2955 +#: kstars.kcfg:3029 #, kde-format msgid "" "Display the median eccentricity for the stars in the capture on the Analyze " @@ -34477,73 +35252,73 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeTemperature), group (Analyze) -#: kstars.kcfg:2959 +#: kstars.kcfg:3033 #, kde-format msgid "Display the ambient temperature on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (FocusPosition), group (Analyze) -#: kstars.kcfg:2963 +#: kstars.kcfg:3037 #, fuzzy, kde-format msgid "Display the autofocus solution position." msgstr "Wissel Diep Lug Objekte" #. i18n: ectx: whatsthis, entry (AnalyzeNumStars), group (Analyze) -#: kstars.kcfg:2967 +#: kstars.kcfg:3041 #, kde-format msgid "Display NumStars on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeSkyBg), group (Analyze) -#: kstars.kcfg:2971 +#: kstars.kcfg:3045 #, kde-format msgid "Display SkyBackground on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeSNR), group (Analyze) -#: kstars.kcfg:2975 +#: kstars.kcfg:3049 #, kde-format msgid "Display SNR on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRA), group (Analyze) -#: kstars.kcfg:2979 +#: kstars.kcfg:3053 #, kde-format msgid "Display RA on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDEC), group (Analyze) -#: kstars.kcfg:2983 +#: kstars.kcfg:3057 #, kde-format msgid "Display DEC on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRAp), group (Analyze) -#: kstars.kcfg:2987 +#: kstars.kcfg:3061 #, kde-format msgid "Display RA Pulses on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDECp), group (Analyze) -#: kstars.kcfg:2991 +#: kstars.kcfg:3065 #, kde-format msgid "Display DEC Pulses on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDrift), group (Analyze) -#: kstars.kcfg:2995 +#: kstars.kcfg:3069 #, kde-format msgid "Display Drift on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRMS), group (Analyze) -#: kstars.kcfg:2999 +#: kstars.kcfg:3073 #, kde-format msgid "Display RMS Error on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeTargetDistance), group (Analyze) -#: kstars.kcfg:3003 +#: kstars.kcfg:3077 #, kde-format msgid "" "Display the arc-seconds distance between the target position and the plate-" @@ -34551,254 +35326,254 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRMSC), group (Analyze) -#: kstars.kcfg:3007 +#: kstars.kcfg:3081 #, kde-format msgid "Display RMS Error (during capture) on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountRA), group (Analyze) -#: kstars.kcfg:3011 +#: kstars.kcfg:3085 #, kde-format msgid "Display Mount RA on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountDEC), group (Analyze) -#: kstars.kcfg:3015 +#: kstars.kcfg:3089 #, kde-format msgid "Display Mount DEC on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountHA), group (Analyze) -#: kstars.kcfg:3019 +#: kstars.kcfg:3093 #, kde-format msgid "Display Mount Hour Angle on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeAz), group (Analyze) -#: kstars.kcfg:3023 +#: kstars.kcfg:3097 #, kde-format msgid "Display Azimuth on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeAlt), group (Analyze) -#: kstars.kcfg:3027 +#: kstars.kcfg:3101 #, kde-format msgid "Display Altitude on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzePierSide), group (Analyze) -#: kstars.kcfg:3031 +#: kstars.kcfg:3105 #, kde-format msgid "Display PierSide on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: label, entry (AnalyzeStatsYAxis), group (Analyze) -#: kstars.kcfg:3035 +#: kstars.kcfg:3109 #, kde-format msgid "Stored Y-axis upper and lower limits for the Analyze Stats Plot." msgstr "" #. i18n: ectx: label, entry (LastServer), group (INDI Lite) -#: kstars.kcfg:3040 +#: kstars.kcfg:3114 #, kde-format msgid "The address of last used server" msgstr "" #. i18n: ectx: label, entry (LastServerPort), group (INDI Lite) -#: kstars.kcfg:3043 +#: kstars.kcfg:3117 #, kde-format msgid "The port of last used server" msgstr "" #. i18n: ectx: label, entry (LastWebManagerPort), group (INDI Lite) -#: kstars.kcfg:3047 +#: kstars.kcfg:3121 #, kde-format msgid "The port of last used Web Manager" msgstr "" #. i18n: ectx: label, entry (HIPSMemoryCache), group (HIPS) -#: kstars.kcfg:3053 +#: kstars.kcfg:3127 #, kde-format msgid "RAM cache size in MB used to store cached HIPS images." msgstr "" #. i18n: ectx: label, entry (HIPSNetCache), group (HIPS) -#: kstars.kcfg:3057 +#: kstars.kcfg:3131 #, kde-format msgid "Hard disk cache size in MB used to store cached HIPS images." msgstr "" #. i18n: ectx: label, entry (HIPSSource), group (HIPS) -#: kstars.kcfg:3061 +#: kstars.kcfg:3135 #, kde-format msgid "HIPS source catalog title." msgstr "" #. i18n: ectx: label, entry (HIPSBiLinearInterpolation), group (HIPS) -#: kstars.kcfg:3065 +#: kstars.kcfg:3139 #, kde-format msgid "Use Bilinear interpolation when rendering HiPS images?" msgstr "" #. i18n: ectx: label, entry (HIPSShowGrid), group (HIPS) -#: kstars.kcfg:3069 +#: kstars.kcfg:3143 #, fuzzy, kde-format msgid "Show HiPS grid on the sky map." msgstr "Kwik" #. i18n: ectx: label, entry (HIPSPanning), group (HIPS) -#: kstars.kcfg:3073 +#: kstars.kcfg:3147 #, kde-format msgid "Redraw HiPS while panning." msgstr "" #. i18n: ectx: label, entry (ShowHIPS), group (HIPS) -#: kstars.kcfg:3077 +#: kstars.kcfg:3151 #, fuzzy, kde-format msgid "Draw HiPS sources in the sky map?" msgstr "Kwik" #. i18n: ectx: whatsthis, entry (ShowHIPS), group (HIPS) -#: kstars.kcfg:3078 +#: kstars.kcfg:3152 #, fuzzy, kde-format msgid "Toggle whether the HIPS sources are drawn in the sky map." msgstr "Steek weg objekte terwyl beweeg" #. i18n: ectx: label, entry (HIPSUseOfflineSource), group (HIPS) -#: kstars.kcfg:3082 +#: kstars.kcfg:3156 #, kde-format msgid "Use offline storage to load HiPS?" msgstr "" #. i18n: ectx: label, entry (HIPSOfflinePath), group (HIPS) -#: kstars.kcfg:3086 +#: kstars.kcfg:3160 #, fuzzy, kde-format msgid "HIPS offline full path." msgstr "Ander Katalogusse" #. i18n: ectx: label, entry (TerrainSource), group (Terrain) -#: kstars.kcfg:3091 +#: kstars.kcfg:3165 #, fuzzy, kde-format msgid "Terrain Filename." msgstr "Ongeldige Lêernaam" #. i18n: ectx: whatsthis, entry (TerrainSource), group (Terrain) -#: kstars.kcfg:3092 +#: kstars.kcfg:3166 #, fuzzy, kde-format msgid "Terrain source filename." msgstr "Ster Naam" #. i18n: ectx: label, entry (TerrainSourceCorrectAz), group (Terrain) -#: kstars.kcfg:3096 +#: kstars.kcfg:3170 #, kde-format msgid "Terrain Azimuth Correction." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSourceCorrectAz), group (Terrain) -#: kstars.kcfg:3097 +#: kstars.kcfg:3171 #, kde-format msgid "Terrain source azimuth correction." msgstr "" #. i18n: ectx: label, entry (TerrainSourceCorrectAlt), group (Terrain) -#: kstars.kcfg:3101 +#: kstars.kcfg:3175 #, fuzzy, kde-format msgid "Terrain Altitude Correction." msgstr "Hoogte:" #. i18n: ectx: whatsthis, entry (TerrainSourceCorrectAlt), group (Terrain) -#: kstars.kcfg:3102 +#: kstars.kcfg:3176 #, fuzzy, kde-format msgid "Terrain source altitude correction." msgstr "Ster Naam" #. i18n: ectx: label, entry (TerrainDownsampling), group (Terrain) -#: kstars.kcfg:3106 +#: kstars.kcfg:3180 #, fuzzy, kde-format msgid "Terrain Downsampling" msgstr "Invoer Keuse" #. i18n: ectx: whatsthis, entry (TerrainDownsampling), group (Terrain) -#: kstars.kcfg:3107 +#: kstars.kcfg:3181 #, kde-format msgid "Speed quality tradeoff for rendering the terrain image." msgstr "" #. i18n: ectx: label, entry (TerrainPanning), group (Terrain) -#: kstars.kcfg:3111 +#: kstars.kcfg:3185 #, kde-format msgid "Terrain While panning." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainPanning), group (Terrain) -#: kstars.kcfg:3112 +#: kstars.kcfg:3186 #, kde-format msgid "Redraw terrain while panning." msgstr "" #. i18n: ectx: label, entry (ShowTerrain), group (Terrain) -#: kstars.kcfg:3116 +#: kstars.kcfg:3190 #, fuzzy, kde-format msgid "Draw terrain" msgstr "Horison" #. i18n: ectx: whatsthis, entry (ShowTerrain), group (Terrain) -#: kstars.kcfg:3117 +#: kstars.kcfg:3191 #, fuzzy, kde-format msgid "Toggle whether the terrain is drawn in the sky map." msgstr "Steek weg objekte terwyl beweeg" #. i18n: ectx: label, entry (TerrainSkipSpeedup), group (Terrain) -#: kstars.kcfg:3121 +#: kstars.kcfg:3195 #, kde-format msgid "Terrain Skip Speedup" msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSkipSpeedup), group (Terrain) #. i18n: ectx: whatsthis, entry (TerrainTransparencySpeedup), group (Terrain) -#: kstars.kcfg:3122 kstars.kcfg:3127 +#: kstars.kcfg:3196 kstars.kcfg:3201 #, kde-format msgid "Enable a one of the terrain drawing speedups." msgstr "" #. i18n: ectx: label, entry (TerrainTransparencySpeedup), group (Terrain) -#: kstars.kcfg:3126 +#: kstars.kcfg:3200 #, kde-format msgid "Terrain Transparency Speedup." msgstr "" #. i18n: ectx: label, entry (TerrainSmoothPixels), group (Terrain) -#: kstars.kcfg:3131 +#: kstars.kcfg:3205 #, kde-format msgid "Terrain Smooth Pixels." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSmoothPixels), group (Terrain) -#: kstars.kcfg:3132 +#: kstars.kcfg:3206 #, kde-format msgid "Smooth pixels for a more pleasant, but slower rendering." msgstr "" #. i18n: ectx: label, entry (ShowImageOverlays), group (ImageOverlay) -#: kstars.kcfg:3138 +#: kstars.kcfg:3212 #, kde-format msgid "Display Image Overlays." msgstr "" #. i18n: ectx: whatsthis, entry (ShowImageOverlays), group (ImageOverlay) -#: kstars.kcfg:3139 +#: kstars.kcfg:3213 #, fuzzy, kde-format msgid "Toggle whether to display image overlays." msgstr "Steek weg objekte terwyl beweeg" #. i18n: ectx: label, entry (ShowSelectedImageOverlay), group (ImageOverlay) -#: kstars.kcfg:3143 +#: kstars.kcfg:3217 #, kde-format msgid "Center SkyMap over selected image overlay." msgstr "" #. i18n: ectx: whatsthis, entry (ShowSelectedImageOverlay), group (ImageOverlay) -#: kstars.kcfg:3144 +#: kstars.kcfg:3218 #, kde-format msgid "" "Center SkyMap over the selected overlay image in the image overlay table (if " @@ -34806,67 +35581,67 @@ msgstr "" #. i18n: ectx: label, entry (ImageOverlayMaxDimension), group (ImageOverlay) -#: kstars.kcfg:3148 +#: kstars.kcfg:3222 #, kde-format msgid "Image overlay max dimension" msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayMaxDimension), group (ImageOverlay) -#: kstars.kcfg:3149 +#: kstars.kcfg:3223 #, kde-format msgid "Maximum dimension for image overlay images." msgstr "" #. i18n: ectx: label, entry (ImageOverlayTimeout), group (ImageOverlay) -#: kstars.kcfg:3153 +#: kstars.kcfg:3227 #, kde-format msgid "Image overlay plate-solving timeout." msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayTimeout), group (ImageOverlay) -#: kstars.kcfg:3154 +#: kstars.kcfg:3228 #, kde-format msgid "Timeout for plate-solving an image overlay." msgstr "" #. i18n: ectx: label, entry (ImageOverlayDefaultScale), group (ImageOverlay) -#: kstars.kcfg:3158 +#: kstars.kcfg:3232 #, kde-format msgid "Image overlay default plate-solving scale." msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayDefaultScale), group (ImageOverlay) -#: kstars.kcfg:3159 +#: kstars.kcfg:3233 #, kde-format msgid "Default scale (arcseconds/pixel) for image-overlay plate solving." msgstr "" #. i18n: ectx: label, entry (DefaultObservatoryWeatherSource), group (Observatory) -#: kstars.kcfg:3165 +#: kstars.kcfg:3239 #, fuzzy, kde-format msgid "Default observatory module weather source." msgstr "Planeet" #. i18n: ectx: label, entry (warningActionsActive), group (Observatory) -#: kstars.kcfg:3168 +#: kstars.kcfg:3242 #, kde-format msgid "Will be reacted upon warnings?" msgstr "" #. i18n: ectx: label, entry (alertActionsActive), group (Observatory) -#: kstars.kcfg:3172 +#: kstars.kcfg:3246 #, kde-format msgid "Will be reacted upon alerts?" msgstr "" #. i18n: ectx: label, entry (weatherWarningCloseDome), group (Observatory) -#: kstars.kcfg:3176 +#: kstars.kcfg:3250 #, kde-format msgid "Shall the dome being closed when a weather warning occurs?" msgstr "" #. i18n: ectx: label, entry (weatherWarningCloseShutter), group (Observatory) -#: kstars.kcfg:3180 +#: kstars.kcfg:3254 #, kde-format msgid "Shall the shutter being closed when a weather warning occurs?" msgstr "" @@ -34874,62 +35649,62 @@ #. i18n: ectx: label, entry (weatherWarningStopScheduler), group (Observatory) #. i18n: ectx: label, entry (weatherAlertCloseShutter), group (Observatory) #. i18n: ectx: label, entry (weatherAlertStopScheduler), group (Observatory) -#: kstars.kcfg:3184 kstars.kcfg:3196 kstars.kcfg:3200 +#: kstars.kcfg:3258 kstars.kcfg:3270 kstars.kcfg:3274 #, kde-format msgid "Shall the shutter being closed when a weather alert occurs?" msgstr "" #. i18n: ectx: label, entry (weatherWarningDelay), group (Observatory) -#: kstars.kcfg:3188 +#: kstars.kcfg:3262 #, kde-format msgid "Delay for reacting upon a weather warning." msgstr "" #. i18n: ectx: label, entry (weatherAlertCloseDome), group (Observatory) -#: kstars.kcfg:3192 +#: kstars.kcfg:3266 #, kde-format msgid "Shall the dome being closed when a weather alert occurs?" msgstr "" #. i18n: ectx: label, entry (weatherAlertDelay), group (Observatory) -#: kstars.kcfg:3204 +#: kstars.kcfg:3278 #, kde-format msgid "Delay for reacting upon a weather alert." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseDome), group (Observatory) -#: kstars.kcfg:3208 +#: kstars.kcfg:3282 #, kde-format msgid "Dome status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseShutter), group (Observatory) -#: kstars.kcfg:3212 +#: kstars.kcfg:3286 #, kde-format msgid "Shutter status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseWeather), group (Observatory) -#: kstars.kcfg:3216 +#: kstars.kcfg:3290 #, kde-format msgid "Weather status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (weatherAutoScaleValues), group (Observatory) -#: kstars.kcfg:3220 +#: kstars.kcfg:3294 #, fuzzy, kde-format msgid "Scale the sensor graph value axis to the values range." msgstr "Wissel Sterre" #. i18n: ectx: label, entry (ASTAPExecutable), group (ASTAP) -#: kstars.kcfg:3226 +#: kstars.kcfg:3300 #, kde-format msgid "Full path to the ASTAP executable." msgstr "" #. i18n: ectx: label, entry (ASTAPDownSample), group (ASTAP) #. i18n: ectx: label, entry (ASTAPDownSampleValue), group (ASTAP) -#: kstars.kcfg:3230 kstars.kcfg:3234 +#: kstars.kcfg:3304 kstars.kcfg:3308 #, kde-format msgid "" "Down sample prior to solving. Also called binning. A value 0 will result in " @@ -34938,7 +35713,7 @@ #. i18n: ectx: label, entry (ASTAPSearchRadius), group (ASTAP) #. i18n: ectx: label, entry (ASTAPSearchRadiusValue), group (ASTAP) -#: kstars.kcfg:3238 kstars.kcfg:3242 +#: kstars.kcfg:3312 kstars.kcfg:3316 #, kde-format msgid "" "The program will search in a square spiral around the start position up to " @@ -34946,25 +35721,25 @@ msgstr "" #. i18n: ectx: label, entry (ASTAPUpdateFITS), group (ASTAP) -#: kstars.kcfg:3246 +#: kstars.kcfg:3320 #, kde-format msgid "Update the fits header with the found solution." msgstr "" #. i18n: ectx: label, entry (ASTAPLargeSearchWindow), group (ASTAP) -#: kstars.kcfg:3250 +#: kstars.kcfg:3324 #, kde-format msgid "Increase search window size." msgstr "" #. i18n: ectx: whatsthis, entry (MosaicTransparencyAuto), group (Mosaic) -#: kstars.kcfg:3256 +#: kstars.kcfg:3330 #, kde-format msgid "Manage the mosaic panel transparency level automatically." msgstr "" #. i18n: ectx: whatsthis, entry (MosaicTransparencyLevel), group (Mosaic) -#: kstars.kcfg:3260 +#: kstars.kcfg:3334 #, kde-format msgid "Control mosaic panel transparency level." msgstr "" @@ -65123,19 +65898,19 @@ msgid "Other" msgstr "" -#: kstarsactions.cpp:208 +#: kstarsactions.cpp:211 #, kde-format msgid "Refraction effects disabled" msgstr "" -#: kstarsactions.cpp:209 +#: kstarsactions.cpp:212 #, kde-format msgid "" "When the horizon is switched off, refraction effects are temporarily " "disabled." msgstr "" -#: kstarsactions.cpp:448 +#: kstarsactions.cpp:457 #, kde-format msgid "" "Due to a known issue in the kde frameworks, updating already downloaded " @@ -65143,132 +65918,132 @@ "update." msgstr "" -#: kstarsactions.cpp:481 +#: kstarsactions.cpp:490 #, kde-format msgid "The catalog \"%1\" is corrupt." msgstr "" -#: kstarsactions.cpp:489 +#: kstarsactions.cpp:498 #, kde-format msgid "The catalog \"%1\" is corrupt.
            Expected id=%2 but got id=%3" msgstr "" -#: kstarsactions.cpp:499 +#: kstarsactions.cpp:508 #, kde-format msgid "Could not import the catalog \"%1\"
            %2" msgstr "" -#: kstarsactions.cpp:553 +#: kstarsactions.cpp:562 #, fuzzy, kde-format msgid "Light Pollution Settings" msgstr "Stoor Huidige Kleure..." -#: kstarsactions.cpp:555 +#: kstarsactions.cpp:564 #, kde-format msgid "Equipment Settings - Equipment Type and Parameters" msgstr "" -#: kstarsactions.cpp:664 kstarsactions.cpp:701 kstarsactions.cpp:744 -#: kstarsactions.cpp:783 +#: kstarsactions.cpp:673 kstarsactions.cpp:710 kstarsactions.cpp:753 +#: kstarsactions.cpp:792 #, kde-format msgid "" "Unable to find INDI server. Please make sure the package that provides the " "'indiserver' binary is installed." msgstr "" -#: kstarsactions.cpp:718 +#: kstarsactions.cpp:727 #, kde-format msgid "" "INDI Device Manager should only be used by advanced technical users. It " "cannot be used with Ekos. Do you still want to open INDI device manager?" msgstr "" -#: kstarsactions.cpp:721 +#: kstarsactions.cpp:730 #, fuzzy, kde-format msgid "INDI Device Manager" msgstr "Datum:" -#: kstarsactions.cpp:1102 +#: kstarsactions.cpp:1111 #, kde-format msgid "Catalogs" msgstr "Katalogusse" -#: kstarsactions.cpp:1114 +#: kstarsactions.cpp:1123 #, fuzzy, kde-format msgid "Guides" msgstr "niks" -#: kstarsactions.cpp:1117 +#: kstarsactions.cpp:1126 #, fuzzy, kde-format msgid "Terrain" msgstr "Maak skoon" #. i18n: ectx: property (title), widget (QGroupBox, ImageOverlayTableBox) -#: kstarsactions.cpp:1120 options/opsimageoverlay.ui:191 +#: kstarsactions.cpp:1129 options/opsimageoverlay.ui:191 #, fuzzy, kde-format msgid "Image Overlays" msgstr "Invoer Keuse" -#: kstarsactions.cpp:1150 +#: kstarsactions.cpp:1159 #, fuzzy, kde-format #| msgid "planet" msgid "Xplanet" msgstr "planeet" -#: kstarsactions.cpp:1156 +#: kstarsactions.cpp:1165 #, kde-format msgid "Developer" msgstr "" -#: kstarsactions.cpp:1174 kstarsactions.cpp:1934 kstarsinit.cpp:268 +#: kstarsactions.cpp:1183 kstarsactions.cpp:1943 kstarsinit.cpp:268 #, fuzzy, kde-format msgid "Hide Terrain" msgstr "Maak skoon" -#: kstarsactions.cpp:1174 kstarsactions.cpp:1934 kstarsinit.cpp:269 +#: kstarsactions.cpp:1183 kstarsactions.cpp:1943 kstarsinit.cpp:269 #, fuzzy, kde-format msgid "Show Terrain" msgstr "Details" -#: kstarsactions.cpp:1178 kstarsactions.cpp:1944 kstarsinit.cpp:273 +#: kstarsactions.cpp:1187 kstarsactions.cpp:1953 kstarsinit.cpp:273 #, fuzzy, kde-format msgid "Hide Image Overlays" msgstr "Stoor Beeld" -#: kstarsactions.cpp:1178 kstarsactions.cpp:1944 kstarsinit.cpp:274 +#: kstarsactions.cpp:1187 kstarsactions.cpp:1953 kstarsinit.cpp:274 #, fuzzy, kde-format msgid "Show Image Overlays" msgstr "Latyn" -#: kstarsactions.cpp:1297 +#: kstarsactions.cpp:1306 #, fuzzy, kde-format msgid "Open FITS" msgstr "Laaiïng van K-sterre..." -#: kstarsactions.cpp:1312 +#: kstarsactions.cpp:1321 #, fuzzy, kde-format msgctxt "@title:window" msgid "Export Image" msgstr "Ewenaar" -#: kstarsactions.cpp:1358 tools/scriptbuilder.cpp:795 +#: kstarsactions.cpp:1367 tools/scriptbuilder.cpp:795 #: tools/scriptbuilder.cpp:863 #, kde-format msgctxt "Filter by file type: KStars Scripts." msgid "KStars Scripts (*.kstars)" msgstr "" -#: kstarsactions.cpp:1366 +#: kstarsactions.cpp:1375 #, fuzzy, kde-format msgid "Executing remote scripts is not supported." msgstr "Bereken" -#: kstarsactions.cpp:1374 oal/execute.cpp:319 tools/observinglist.cpp:909 +#: kstarsactions.cpp:1383 oal/execute.cpp:319 tools/observinglist.cpp:909 #, fuzzy, kde-format msgid "Could not open file %1" msgstr "Kon nie Open Lêer" -#: kstarsactions.cpp:1399 +#: kstarsactions.cpp:1408 #, kde-format msgid "" "The selected script contains unrecognized elements, indicating that it was " @@ -65277,27 +66052,27 @@ "it anyway?" msgstr "" -#: kstarsactions.cpp:1404 +#: kstarsactions.cpp:1413 #, fuzzy, kde-format msgid "Script Validation Failed" msgstr "Ster Naam" -#: kstarsactions.cpp:1404 +#: kstarsactions.cpp:1413 #, kde-format msgid "Run Nevertheless" msgstr "" -#: kstarsactions.cpp:1411 +#: kstarsactions.cpp:1420 #, fuzzy, kde-format msgid "Running script: %1" msgstr "Sonsondergang:" -#: kstarsactions.cpp:1429 +#: kstarsactions.cpp:1438 #, fuzzy, kde-format msgid "Script finished." msgstr "Ster Naam" -#: kstarsactions.cpp:1441 +#: kstarsactions.cpp:1450 #, fuzzy, kde-format msgid "" "You can save printer ink by using the \"Star Chart\" color scheme, which " @@ -65309,91 +66084,91 @@ "skema vir besig om te druk? (Jou huidige kleur instellings sal wees " "gerestoreer wanneer besig om te druk is klaar gemaak.)" -#: kstarsactions.cpp:1446 +#: kstarsactions.cpp:1455 #, kde-format msgid "Switch to Star Chart Colors?" msgstr "Wissel na Ster Kaart Kleure?" -#: kstarsactions.cpp:1447 +#: kstarsactions.cpp:1456 #, fuzzy, kde-format msgid "Switch Color Scheme" msgstr "Kleur Skemas" -#: kstarsactions.cpp:1447 +#: kstarsactions.cpp:1456 #, fuzzy, kde-format msgid "Do Not Switch" msgstr "Kon nie lees " -#: kstarsactions.cpp:1530 kstarsinit.cpp:236 +#: kstarsactions.cpp:1539 kstarsinit.cpp:236 #, fuzzy, kde-format msgid "Engage &Tracking" msgstr "Stop Horlosie" -#: kstarsactions.cpp:1644 +#: kstarsactions.cpp:1653 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 degrees" msgstr "" -#: kstarsactions.cpp:1649 +#: kstarsactions.cpp:1658 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 arcminutes" msgstr "" -#: kstarsactions.cpp:1655 +#: kstarsactions.cpp:1664 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 arcseconds" msgstr "" -#: kstarsactions.cpp:1672 +#: kstarsactions.cpp:1681 #, kde-format msgctxt "The user should enter an angle for the field-of-view of the display" msgid "Enter Desired Field-of-View Angle" msgstr "" -#: kstarsactions.cpp:1673 +#: kstarsactions.cpp:1682 #, kde-format msgid "Enter a field-of-view angle in degrees: " msgstr "" -#: kstarsactions.cpp:1704 kstarsinit.cpp:716 +#: kstarsactions.cpp:1713 kstarsinit.cpp:716 #, fuzzy, kde-format #| msgid "&North" msgctxt "Orientation of the sky map" msgid "North &Up" msgstr "Noord" -#: kstarsactions.cpp:1707 kstarsinit.cpp:725 +#: kstarsactions.cpp:1716 kstarsinit.cpp:725 #, fuzzy, kde-format msgctxt "Orientation of the sky map" msgid "North &Down" msgstr "Yukon" -#: kstarsactions.cpp:1725 kstarsinit.cpp:716 +#: kstarsactions.cpp:1734 kstarsinit.cpp:716 #, kde-format msgctxt "Orientation of the sky map" msgid "Zenith &Up" msgstr "" -#: kstarsactions.cpp:1728 kstarsinit.cpp:725 +#: kstarsactions.cpp:1737 kstarsinit.cpp:725 #, kde-format msgctxt "Orientation of the sky map" msgid "Zenith &Down" msgstr "" -#: kstarsactions.cpp:1886 +#: kstarsactions.cpp:1895 #, kde-format msgid "Attempt to determine from image" msgstr "" -#: kstarsactions.cpp:1888 +#: kstarsactions.cpp:1897 #, fuzzy, kde-format msgid "Eyepiece View: Choose a field-of-view" msgstr "Wissel Diep Lug Objekte" -#: kstarsactions.cpp:1889 +#: kstarsactions.cpp:1898 #, kde-format msgid "FOV to render eyepiece view for:" msgstr "" @@ -66582,13 +67357,6 @@ msgid "%1 - Add a Link" msgstr "Voeg by Skakel..." -#. i18n: ectx: property (text), widget (QTreeWidget, OptionsList) -#: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:68 -#: tools/optionstreeview.ui:28 -#, fuzzy, kde-format, kde-kuit-format -msgid "Description" -msgstr "Des:" - #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:77 #, fuzzy, kde-kuit-format #| msgid "URL:" @@ -73244,12 +74012,6 @@ "solving is enabled.

            " msgstr "" -#. i18n: ectx: property (toolTip), widget (QComboBox, imageOverlaySolverProfile) -#: options/opsimageoverlay.ui:255 -#, kde-format -msgid "Selects the Options Profile (from Align) to use for Plate Solving" -msgstr "" - #. i18n: ectx: property (toolTip), widget (QLabel, imageOverlayScaleLabel) #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_ImageOverlayDefaultScale) #: options/opsimageoverlay.ui:271 options/opsimageoverlay.ui:287 @@ -79230,12 +79992,6 @@ msgid "Select all items in the list" msgstr "Invoer Keuse" -#. i18n: ectx: property (text), widget (QPushButton, AllButton) -#: tools/obslistwizard.ui:173 -#, kde-format -msgid "All" -msgstr "" - #. i18n: ectx: property (toolTip), widget (QPushButton, NoneButton) #: tools/obslistwizard.ui:180 #, kde-format @@ -81691,12 +82447,6 @@ msgid "Labels and markers" msgstr "" -#. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: xplanet/opsxplanet.ui:574 -#, fuzzy, kde-format -msgid "Labels" -msgstr "Latyn:" - #. i18n: ectx: property (text), widget (QRadioButton, kcfg_XplanetLabelGMT) #: xplanet/opsxplanet.ui:603 #, kde-format @@ -81920,6 +82670,27 @@ msgstr "Wissel Diep Lug Objekte" #, fuzzy +#~ msgctxt "Half Flux Radius" +#~ msgid "HFR: %1" +#~ msgstr "Sonsondergang:" + +#, fuzzy +#~ msgid "Scope/Lense:" +#~ msgstr "Koop" + +#, fuzzy +#~ msgid "Flat Source" +#~ msgstr "Datum" + +#, fuzzy +#~ msgid "Use Dawn and Dusk light" +#~ msgstr "Stoor Beeld" + +#, fuzzy +#~ msgid "Warning: Filter %1 not found in filter wheel." +#~ msgstr "Spanje" + +#, fuzzy #~ msgid "" #~ "

            The camera position angle is saved to a sequence " #~ "capture job. On execution of the job the camera is rotated to the " @@ -82299,10 +83070,6 @@ #~ msgstr "Middag:" #, fuzzy -#~ msgid "Primary Scope" -#~ msgstr "Planeet" - -#, fuzzy #~ msgid "Guide Scope" #~ msgstr "Planeet" @@ -82554,12 +83321,6 @@ #~ msgstr "Bereken" #, fuzzy -#~| msgctxt "seconds" -#~| msgid "secs" -#~ msgid "arcsec" -#~ msgstr "sekondes" - -#, fuzzy #~ msgid "Inline Images" #~ msgstr "Stoor Beeld" @@ -83178,11 +83939,6 @@ #, fuzzy #~ msgctxt "Asteroid name (optional)" -#~ msgid "Isabella" -#~ msgstr "Kareroon" - -#, fuzzy -#~ msgctxt "Asteroid name (optional)" #~ msgid "Medea" #~ msgstr "Lees" @@ -83442,11 +84198,6 @@ #, fuzzy #~ msgctxt "Asteroid name (optional)" -#~ msgid "Alice" -#~ msgstr "Ada" - -#, fuzzy -#~ msgctxt "Asteroid name (optional)" #~ msgid "Brasilia" #~ msgstr "Manlik" @@ -85465,12 +86216,6 @@ #~ msgstr "Koördinate" #, fuzzy -#~| msgctxt "City name (optional, probably does not need a translation)" -#~| msgid "Delta" -#~ msgid "Delta ,\"" -#~ msgstr "Delta" - -#, fuzzy #~ msgid "Pulse duration, ms" #~ msgstr "Dag duur" @@ -85630,10 +86375,6 @@ #~ msgstr "Bahrain" #, fuzzy -#~ msgid "Sensor Data" -#~ msgstr "Maak skoon Velde" - -#, fuzzy #~ msgid "Nebulas" #~ msgstr "Lynx" @@ -85646,10 +86387,6 @@ #~ msgstr "Laaiïng van K-sterre..." #, fuzzy -#~ msgid "Threshold (%):" -#~ msgstr "Leon" - -#, fuzzy #~ msgid "Box Size:" #~ msgstr "Sonsondergang:" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/ar/kstars.po kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/ar/kstars.po --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/ar/kstars.po 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/ar/kstars.po 2023-12-03 05:23:17.000000000 +0000 @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: kstars\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" -"POT-Creation-Date: 2023-09-29 00:39+0000\n" +"POT-Creation-Date: 2023-11-30 00:38+0000\n" "PO-Revision-Date: 2022-09-09 23:43+0400\n" "Last-Translator: Zayed Al-Saidi \n" "Language-Team: \n" @@ -187,7 +187,7 @@ #: auxiliary/colorscheme.cpp:59 data/qml/whatisinteresting/wiview.qml:241 #: data/qml/whatisinteresting/wiview.qml:253 dialogs/finddialog.cpp:48 -#: kstarsactions.cpp:1108 kstarslite/dialogs/finddialoglite.cpp:37 +#: kstarsactions.cpp:1117 kstarslite/dialogs/finddialoglite.cpp:37 #: kstarslite/qml/modules/TopMenu.qml:178 #, kde-format, kde-kuit-format msgid "Satellites" @@ -200,7 +200,7 @@ #: auxiliary/colorscheme.cpp:61 data/qml/whatisinteresting/wiview.qml:526 #: data/qml/whatisinteresting/wiview.qml:538 dialogs/finddialog.cpp:47 -#: kstarsactions.cpp:1111 kstarslite/dialogs/finddialoglite.cpp:36 +#: kstarsactions.cpp:1120 kstarslite/dialogs/finddialoglite.cpp:36 #: kstarslite/qml/modules/TopMenu.qml:169 #, kde-format, kde-kuit-format msgid "Supernovae" @@ -235,7 +235,7 @@ msgid "DEC Guide Error" msgstr "خطا تتبع ميل" -#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:94 +#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:101 #, kde-format msgid "Solver FOV" msgstr "رمز رؤية المحلل" @@ -400,9 +400,9 @@ #. i18n: ectx: property (text), widget (QPushButton, AddScope) #. i18n: ectx: property (text), widget (QPushButton, AddDSLRLens) #. i18n: ectx: property (text), widget (QPushButton, SavePreset) -#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:383 -#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2499 -#: ekos/scheduler/scheduler.cpp:3822 +#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:384 +#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2028 +#: ekos/scheduler/scheduler.cpp:2950 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:88 #: kstarslite/qml/dialogs/helpers/LocationEdit.qml:375 #: oal/equipmentwriter.ui:291 oal/equipmentwriter.ui:702 @@ -428,7 +428,7 @@ #. i18n: ectx: property (text), widget (QPushButton, downloadB) #: auxiliary/imageviewer.cpp:195 -#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:86 +#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:59 #, kde-format msgid "Download" msgstr "تحميل" @@ -455,15 +455,15 @@ msgid "Save Image" msgstr "احفظ الصورة" -#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3835 -#: ekos/guide/guidedriftgraph.cpp:465 kstarsactions.cpp:1326 +#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3873 +#: ekos/guide/guidedriftgraph.cpp:466 kstarsactions.cpp:1335 #: printing/pwizprint.cpp:77 tools/scriptbuilder.cpp:879 #, kde-format msgid "A file named \"%1\" already exists. Overwrite it?" msgstr "الملف المسمى \"%1\" موجود سلفاً. الكتابة فوقه?" -#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3838 -#: ekos/guide/guidedriftgraph.cpp:468 kstarsactions.cpp:1327 +#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3876 +#: ekos/guide/guidedriftgraph.cpp:469 kstarsactions.cpp:1336 #: printing/pwizprint.cpp:78 tools/scriptbuilder.cpp:882 #, kde-format msgid "Overwrite File?" @@ -524,7 +524,7 @@ #: dialogs/catalogdetails.cpp:213 dialogs/catalogsdbui.cpp:153 #: dialogs/catalogsdbui.cpp:189 dialogs/catalogsdbui.cpp:210 #: dialogs/catalogsdbui.cpp:230 dialogs/catalogsdbui.cpp:248 -#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:780 +#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:782 #, kde-format msgid "Warning" msgstr "تحذير" @@ -536,6 +536,7 @@ #. i18n: ectx: property (text), widget (QPushButton, cancelB) #: auxiliary/ksmessagebox.h:38 ekos/align/manualrotator.ui:135 +#: fitsviewer/fitstab.cpp:627 fitsviewer/fitstab.cpp:646 #: indi/telescopewizardprocess.cpp:219 indi/telescopewizardprocess.cpp:226 #: kstarslite/qml/dialogs/FindDialog.qml:107 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:105 @@ -549,18 +550,18 @@ #. i18n: ectx: property (text), widget (QTableWidget, solutionTable) #: auxiliary/ksmessagebox.h:39 auxiliary/ksnotification.h:42 -#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:139 -#: ekos/capture/sequencejob.cpp:21 ekos/manager.cpp:1068 ekos/manager.cpp:1083 -#: ekos/manager.cpp:1113 ekos/scheduler/schedulerjob.cpp:620 +#: ekos/analyze/analyze.cpp:139 ekos/analyze/analyze.cpp:141 +#: ekos/capture/sequencejob.cpp:23 ekos/manager.cpp:1072 ekos/manager.cpp:1087 +#: ekos/manager.cpp:1117 ekos/scheduler/schedulerjob.cpp:596 #: fitsviewer/solveInfo.ui:86 indi/indidome.cpp:22 indi/indidustcap.cpp:18 -#: indi/indimount.cpp:33 kstarsactions.cpp:480 kstarsactions.cpp:488 -#: kstarsactions.cpp:498 skycomponents/imageoverlaycomponent.cpp:519 +#: indi/indimount.cpp:33 kstarsactions.cpp:489 kstarsactions.cpp:497 +#: kstarsactions.cpp:507 skycomponents/imageoverlaycomponent.cpp:519 #, kde-format msgid "Error" msgstr "خطأ" #: auxiliary/ksmessagebox.h:40 auxiliary/ksnotification.h:43 -#: ekos/scheduler/framingassistantui.cpp:767 +#: ekos/scheduler/framingassistantui.cpp:769 #, kde-format msgid "Sorry" msgstr "اسف" @@ -744,10 +745,10 @@ msgid "Cannot write %s %1: %2" msgstr "لا يستطيع كتابة إلى مستخدم سجل ملفّ" -#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:179 -#: ekos/scheduler/framingassistantui.cpp:194 -#: ekos/scheduler/framingassistantui.cpp:853 -#: ekos/scheduler/framingassistantui.cpp:872 skyobjects/ksplanetbase.h:60 +#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:180 +#: ekos/scheduler/framingassistantui.cpp:195 +#: ekos/scheduler/framingassistantui.cpp:855 +#: ekos/scheduler/framingassistantui.cpp:874 skyobjects/ksplanetbase.h:60 #: skyobjects/skyobject.h:24 #, kde-format msgid "unnamed" @@ -987,7 +988,7 @@ #: data/qml/whatisinteresting/wiview.qml:176 #: data/qml/whatisinteresting/wiview.qml:188 dialogs/detaildialog.cpp:216 #: dialogs/detaildialog.cpp:232 dialogs/detaildialog.cpp:255 -#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:153 +#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:129 #: printing/detailstable.cpp:145 printing/detailstable.cpp:162 #: printing/detailstable.cpp:173 printing/detailstable.cpp:186 #: printing/pwizobjectselection.cpp:124 skycomponents/skymapcomposite.cpp:606 @@ -1388,7 +1389,7 @@ #: ekos/guide/opsdither.ui:126 ekos/guide/opsgpg.ui:139 #: ekos/guide/opsgpg.ui:306 ekos/guide/opsgpg.ui:383 ekos/guide/opsgpg.ui:456 #: ekos/guide/opsgpg.ui:539 ekos/guide/opsguide.ui:308 -#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:585 ekos/opsekos.ui:678 +#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:598 ekos/opsekos.ui:691 #, kde-format msgid "seconds" msgstr "ثانية" @@ -1908,16 +1909,16 @@ #. i18n: ectx: property (text), widget (QLabel, idlingStateLabel) #. i18n: ectx: property (text), widget (QLabel, guideStatus) #. i18n: ectx: property (text), widget (QLabel, jobStatus) -#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:27 -#: ekos/analyze/analyze.cpp:125 ekos/analyze/analyze.cpp:144 -#: ekos/analyze/analyze.cpp:2851 ekos/auxiliary/buildfilteroffsets.cpp:153 +#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:28 +#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/buildfilteroffsets.cpp:153 #: ekos/auxiliary/darklibrary.cpp:46 ekos/auxiliary/ledstatuswidget.cpp:19 -#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:21 +#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:23 #: ekos/ekos.h:20 ekos/ekos.h:71 ekos/ekos.h:118 ekos/ekos.h:138 #: ekos/ekos.h:161 ekos/ekos.h:187 ekos/guide/guidestatewidget.ui:38 -#: ekos/manager.cpp:572 ekos/manager/guidemanager.cpp:135 +#: ekos/manager.cpp:576 ekos/manager/guidemanager.cpp:135 #: ekos/manager/guidemanager.ui:117 ekos/scheduler/scheduler.ui:1252 -#: ekos/scheduler/schedulerjob.cpp:613 ekos/scheduler/schedulerjob.cpp:637 +#: ekos/scheduler/schedulerjob.cpp:589 ekos/scheduler/schedulerjob.cpp:613 #: indi/indidome.cpp:20 indi/indidustcap.cpp:17 indi/indimount.cpp:31 #, kde-format, kde-kuit-format msgid "Idle" @@ -2252,8 +2253,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, magUnknown) -#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:621 -#: ekos/scheduler/schedulerjob.cpp:652 fitsviewer/fitscommon.h:16 +#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:597 +#: ekos/scheduler/schedulerjob.cpp:628 fitsviewer/fitscommon.h:16 #: fitsviewer/fitshistogram.cpp:781 fitsviewer/fitshistogramcommand.cpp:267 #: indi/indigroup.cpp:30 skycomponents/constellationboundarylines.cpp:275 #, kde-format @@ -2502,12 +2503,12 @@ "الرابط غير صحيح. هل تريد ان تفتح نافذة متصفح الانترنت\n" "للبحث من خلال جوجل؟" -#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3846 -#: ekos/align/mountmodel.cpp:264 ekos/align/mountmodel.cpp:390 -#: ekos/analyze/analyze.cpp:1170 ekos/capture/capture.cpp:2078 -#: ekos/capture/capture.cpp:2508 ekos/guide/guidedriftgraph.cpp:476 -#: ekos/scheduler/scheduler.cpp:3463 ekos/scheduler/scheduler.cpp:3832 -#: fitsviewer/fitstab.cpp:495 tools/scriptbuilder.cpp:832 +#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3884 +#: ekos/align/mountmodel.cpp:265 ekos/align/mountmodel.cpp:391 +#: ekos/analyze/analyze.cpp:1172 ekos/capture/capture.cpp:1951 +#: ekos/capture/capture.cpp:2037 ekos/guide/guidedriftgraph.cpp:477 +#: ekos/scheduler/scheduler.cpp:2593 ekos/scheduler/scheduler.cpp:2960 +#: fitsviewer/fitstab.cpp:504 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:930 #, kde-format msgid "Invalid URL" @@ -2618,8 +2619,8 @@ #. i18n: ectx: property (text), item, widget (QComboBox, schedulerProfileCombo) #: dialogs/catalogcoloreditor.cpp:109 #: ekos/auxiliary/stellarsolverprofileeditor.ui:441 -#: ekos/scheduler/scheduler.cpp:2569 ekos/scheduler/scheduler.cpp:6444 -#: ekos/scheduler/scheduler.ui:250 skycomponents/flagcomponent.cpp:33 +#: ekos/scheduler/scheduler.ui:250 ekos/scheduler/schedulermodulestate.cpp:38 +#: ekos/scheduler/schedulerprocess.cpp:1183 skycomponents/flagcomponent.cpp:33 #, kde-format msgid "Default" msgstr "المبدئيّ" @@ -2806,7 +2807,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QPushButton, preview_button) -#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:258 +#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:260 #: fitsviewer/fitsviewer.cpp:607 indi/indicamera.cpp:926 #, kde-format msgid "Preview" @@ -3048,11 +3049,13 @@ #. i18n: ectx: property (text), widget (QLabel, l_01) #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_6) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRALabel) #: dialogs/catalogobjectlistmodel.cpp:67 ekos/align/align.ui:911 #: ekos/align/opsastrometry.ui:409 ekos/guide/guide.ui:424 #: ekos/guide/opscalibration.ui:235 ekos/guide/opsguide.ui:138 #: ekos/mount/mount.ui:144 ekos/scheduler/scheduler.ui:468 -#: fitsviewer/solveInfo.ui:66 skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:177 fitsviewer/solveInfo.ui:66 +#: skycomponents/imageoverlaycomponent.cpp:62 #, kde-format msgid "RA" msgstr "" @@ -3247,7 +3250,7 @@ msgstr "استنسخ" #. i18n: ectx: property (text), widget (QPushButton, colorButton) -#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1126 +#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1135 #, kde-format msgid "Colors" msgstr "الألوان" @@ -3543,12 +3546,12 @@ msgid "Could not add the link." msgstr "لم يمكن انزال الملف البعيد" -#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1153 +#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1162 #, kde-format msgid "Advanced" msgstr "خيارات متقدمة" -#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:507 +#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:509 #: kstarslite/qml/dialogs/DetailsDialog.qml:55 #: kstarslite/qml/dialogs/DetailsDialog.qml:453 #, kde-format, kde-kuit-format @@ -3579,7 +3582,7 @@ msgid "Are you sure you want to remove the %1 link?" msgstr "تأكيد حذف الرابط %1 ؟" -#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1495 +#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1512 #: indi/indidriver.cpp:897 #, kde-format, kde-kuit-format msgid "Delete Confirmation" @@ -3598,7 +3601,7 @@ msgstr "لم يمكن حذف الملف: %1" #: dialogs/detaildialog.cpp:1108 dialogs/detaildialog.cpp:1140 -#: kstarsactions.cpp:303 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 +#: kstarsactions.cpp:306 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 #: tools/observinglist.cpp:687 tools/observinglist.cpp:709 #: tools/whatsinteresting/wiview.cpp:339 tools/whatsinteresting/wiview.cpp:364 #, fuzzy, kde-format @@ -3606,8 +3609,8 @@ msgid "No connected mounts found." msgstr "لا يوجد جسم يسمى بــ %1" -#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:436 -#: kstarsactions.cpp:288 tools/observinglist.cpp:698 +#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:447 +#: kstarsactions.cpp:291 tools/observinglist.cpp:698 #: tools/whatsinteresting/wiview.cpp:350 #, fuzzy, kde-format msgid "Mount %1 is offline. Please connect and retry again." @@ -3700,18 +3703,20 @@ #. i18n: ectx: property (text), widget (QLabel, masterMean) #. i18n: ectx: property (text), widget (QLabel, masterMedian) #. i18n: ectx: property (text), widget (QLabel, masterDeviation) +#. i18n: ectx: property (text), widget (QLabel, exposureCount) #. i18n: ectx: property (text), widget (QLabel, l_FOV) #. i18n: ectx: property (text), widget (QLabel, l_Reducer) #. i18n: ectx: property (text), widget (QLabel, avgFPS) #. i18n: ectx: property (text), widget (QLineEdit, f_LockedFilter) -#: dialogs/details_data.ui:390 ekos/align/align.cpp:922 +#: dialogs/details_data.ui:390 ekos/align/align.cpp:929 #: ekos/analyze/analyze.ui:74 ekos/auxiliary/darklibrary.cpp:1054 #: ekos/auxiliary/darklibrary.ui:276 ekos/auxiliary/darklibrary.ui:424 #: ekos/auxiliary/darklibrary.ui:693 ekos/auxiliary/darklibrary.ui:713 #: ekos/auxiliary/darklibrary.ui:733 ekos/auxiliary/darklibrary.ui:753 #: ekos/auxiliary/darklibrary.ui:773 ekos/auxiliary/darklibrary.ui:793 -#: ekos/capture/capture.cpp:876 ekos/capture/capture.cpp:914 -#: ekos/focus/focus.cpp:368 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 +#: ekos/capture/capture.cpp:900 ekos/capture/capture.cpp:940 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:814 +#: ekos/focus/focus.cpp:373 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 #: indi/streamform.ui:368 oal/equipmentwriter.ui:1163 #, kde-format msgid "--" @@ -4193,7 +4198,7 @@ msgid "Any" msgstr "الكل" -#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1105 kstarsinit.cpp:472 +#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1114 kstarsinit.cpp:472 #: kstarslite/dialogs/finddialoglite.cpp:27 #: kstarslite/qml/modules/TopMenu.qml:159 tools/astrocalc.cpp:166 #: tools/conjunctions.cpp:96 @@ -4317,33 +4322,33 @@ msgid "Set Coordinates Manually" msgstr "حدد الإحداثيات يدوياً" -#: dialogs/focusdialog.cpp:127 tools/flagmanager.cpp:184 +#: dialogs/focusdialog.cpp:128 tools/flagmanager.cpp:184 #, kde-format msgid "The Right Ascension value must be between 0.0 and 24.0." msgstr "قمية زاوية الصّعود محصورة بين 0.0 و 24.0" -#: dialogs/focusdialog.cpp:129 tools/flagmanager.cpp:186 +#: dialogs/focusdialog.cpp:130 tools/flagmanager.cpp:186 #, kde-format msgid "The Declination value must be between -90.0 and 90.0." msgstr "قيمة زاوية الميلان محصورة بين -90.0 و 90.0" -#: dialogs/focusdialog.cpp:132 dialogs/focusdialog.cpp:185 +#: dialogs/focusdialog.cpp:133 dialogs/focusdialog.cpp:191 #: tools/flagmanager.cpp:189 #, kde-format msgid "Invalid Coordinate Data" msgstr "الاحداثيات غير صحيحة" -#: dialogs/focusdialog.cpp:140 +#: dialogs/focusdialog.cpp:141 #, fuzzy, kde-format msgid "Invalid Epoch format" msgstr "الـعنوان غير صحيح" -#: dialogs/focusdialog.cpp:180 +#: dialogs/focusdialog.cpp:186 #, kde-format msgid "The Azimuth value must be between 0.0 and 360.0." msgstr "قيمة زاوية السمت محصورة بين 0.0 و 360.0" -#: dialogs/focusdialog.cpp:182 +#: dialogs/focusdialog.cpp:188 #, kde-format msgid "The Altitude value must be between -90.0 and 90.0." msgstr "قيمة زاوية الارتفاع محصورة بين -90.0 و 90.0" @@ -4408,7 +4413,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1) #. i18n: ectx: property (text), widget (QLabel, label_7) #: dialogs/focusdialog.ui:151 ekos/align/polaralignmentassistant.ui:592 -#: ekos/capture/calibrationoptions.ui:88 tools/argsetaltaz.ui:30 +#: ekos/capture/calibrationoptions.ui:73 tools/argsetaltaz.ui:30 #: tools/modcalcplanets.ui:303 #, kde-format msgid "Az:" @@ -5083,7 +5088,7 @@ #. i18n: ectx: attribute (title), widget (QWidget, tab2) #. i18n: ectx: property (text), widget (QLabel, indiCameraLabel) #: dialogs/newfov.ui:433 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:312 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:127 #, kde-format msgid "Camera" msgstr "آلة تصوير" @@ -5748,7 +5753,7 @@ "

            هذا المرشد سيساعدك في إعداد بعض الخيارات الأساسية، مثل موقعك على الأرض.

            للبدء، اضغط زر التالي.

            " -#: ekos/align/align.cpp:326 +#: ekos/align/align.cpp:333 #, kde-format msgid "" "
            Object %1: %2
            RA:%3
            dDE:%6
            " msgstr "" -#: ekos/align/align.cpp:456 +#: ekos/align/align.cpp:463 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to clear all of the solution points?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/align/align.cpp:457 +#: ekos/align/align.cpp:464 #, fuzzy, kde-format msgid "Clear Solution Points" msgstr "امسح الكل" -#: ekos/align/align.cpp:530 +#: ekos/align/align.cpp:537 #, kde-format msgid "Solver timed out." msgstr "" -#: ekos/align/align.cpp:822 +#: ekos/align/align.cpp:829 #, fuzzy, kde-format msgid "Mount does not support syncing." msgstr "المنظار سوّاق هو مفقود." -#: ekos/align/align.cpp:1027 +#: ekos/align/align.cpp:1034 #, kde-format msgid "Effective telescope focal length is updated to %1 mm." msgstr "" -#: ekos/align/align.cpp:1069 +#: ekos/align/align.cpp:1076 #, kde-format msgid "" "Warning! The calculated field of view (%1) is out of bounds. Ensure the " "telescope focal length and camera pixel size are correct." msgstr "" -#: ekos/align/align.cpp:1108 +#: ekos/align/align.cpp:1115 #, kde-format msgid "" "

            Effective field of view size in arcminutes.

            Please capture and " @@ -5797,85 +5802,85 @@ "p>

            Calculated FOV: %1

            " msgstr "" -#: ekos/align/align.cpp:1117 +#: ekos/align/align.cpp:1124 #, fuzzy, kde-format #| msgid "Desired field-of-view size, in arcminutes" msgid "

            Effective field of view size in arcminutes.

            " msgstr "حقل العرض المطلوب (دقائق قوسية)" -#: ekos/align/align.cpp:1398 +#: ekos/align/align.cpp:1405 #, kde-format msgid "Error: No camera detected." msgstr "" -#: ekos/align/align.cpp:1404 +#: ekos/align/align.cpp:1411 #, fuzzy, kde-format msgid "Error: lost connection to camera." msgstr "اتصال" -#: ekos/align/align.cpp:1405 ekos/align/align.cpp:2308 +#: ekos/align/align.cpp:1412 ekos/align/align.cpp:2344 #, fuzzy, kde-format msgid "Astrometry alignment failed" msgstr "حدّد بوصة دَخْل ملفّ." -#: ekos/align/align.cpp:1421 +#: ekos/align/align.cpp:1428 #, fuzzy, kde-format msgid "" "Telescope aperture and focal length are missing. Please check your optical " "train settings and try again." msgstr "عذراً نجوم ك failed إلى كشف أي منها مرفق تفقّد خصائص و." -#: ekos/align/align.cpp:1427 +#: ekos/align/align.cpp:1434 #, fuzzy, kde-format msgid "" "CCD pixel size is missing. Please check your driver settings and try again." msgstr "عذراً نجوم ك failed إلى كشف أي منها مرفق تفقّد خصائص و." -#: ekos/align/align.cpp:1435 +#: ekos/align/align.cpp:1442 #, fuzzy, kde-format msgid "Error: lost connection to filter wheel." msgstr "اتصال" -#: ekos/align/align.cpp:1455 ekos/capture/captureprocess.cpp:170 -#: ekos/capture/captureprocess.cpp:563 ekos/focus/focus.cpp:4819 +#: ekos/align/align.cpp:1462 ekos/capture/captureprocess.cpp:191 +#: ekos/capture/captureprocess.cpp:584 ekos/focus/focus.cpp:5060 #, kde-format msgid "" "Image transfer is disabled for this camera. Would you like to enable it?" msgstr "" -#: ekos/align/align.cpp:1475 +#: ekos/align/align.cpp:1482 #, kde-format msgid "Cannot capture while focus module is busy. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1483 +#: ekos/align/align.cpp:1490 #, kde-format msgid "" "Cannot capture while CCD exposure is in progress. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1492 +#: ekos/align/align.cpp:1499 #, fuzzy, kde-format msgid "Cannot capture while rotator is busy. Retrying in %1 seconds..." msgstr "جاري التّحميل" -#: ekos/align/align.cpp:1510 ekos/align/align.cpp:2976 +#: ekos/align/align.cpp:1517 ekos/align/align.cpp:3012 #, kde-format msgid "No remote astrometry driver detected, switching to StellarSolver." msgstr "" -#: ekos/align/align.cpp:1564 ekos/focus/focus.cpp:1735 +#: ekos/align/align.cpp:1571 ekos/focus/focus.cpp:1760 #, fuzzy, kde-format msgid "Capturing image..." msgstr "جاري التّحميل." -#: ekos/align/align.cpp:1654 ekos/auxiliary/ledstatuswidget.cpp:71 -#: ekos/focus/focus.cpp:2587 +#: ekos/align/align.cpp:1661 ekos/auxiliary/ledstatuswidget.cpp:71 +#: ekos/focus/focus.cpp:2706 #, fuzzy, kde-format msgid "Image received." msgstr "سجّل صورة" -#: ekos/align/align.cpp:1784 +#: ekos/align/align.cpp:1791 #, kde-format msgid "" "No index files were found on your system in the specified index file " @@ -5883,84 +5888,100 @@ "to the list." msgstr "" -#: ekos/align/align.cpp:1843 +#: ekos/align/align.cpp:1850 #, fuzzy, kde-format msgid "Solving with blind image scale..." msgstr "جاري التّحميل." -#: ekos/align/align.cpp:1851 +#: ekos/align/align.cpp:1858 #, fuzzy, kde-format msgid "Solving with blind image position..." msgstr "جاري التّحميل." -#: ekos/align/align.cpp:1883 +#: ekos/align/align.cpp:1890 #, fuzzy, kde-format msgid "Loaded image does not have pierside information" msgstr "فشل في تحميل الصورة " -#: ekos/align/align.cpp:1888 +#: ekos/align/align.cpp:1895 #, kde-format msgid "Loaded image was taken on pierside %1" msgstr "" -#: ekos/align/align.cpp:1990 +#: ekos/align/align.cpp:2020 #, fuzzy, kde-format msgid "Solver completed after %1 seconds." msgstr "مكتمل" -#: ekos/align/align.cpp:2006 +#: ekos/align/align.cpp:2036 #, kde-format msgid "Solver RA (%1) DEC (%2) Orientation (%3) Pixel Scale (%4) Parity (%5)" msgstr "" -#: ekos/align/align.cpp:2073 +#: ekos/align/align.cpp:2103 #, kde-format msgid "" "WCS information updated. Images captured from this point forward shall have " "valid WCS." msgstr "" -#: ekos/align/align.cpp:2091 +#: ekos/align/align.cpp:2121 #, kde-format msgid "" "Solution coordinates: RA (%1) DEC (%2) Telescope Coordinates: RA (%3) DEC " "(%4) Target Coordinates: RA (%5) DEC (%6)" msgstr "" -#: ekos/align/align.cpp:2102 +#: ekos/align/align.cpp:2132 #, fuzzy, kde-format msgid "Target is within %1 degrees of solution coordinates." msgstr "العرض الموضع يعمل خريطة" #. i18n("Camera offset angle is %1 degrees.", OffsetAngle)); -#: ekos/align/align.cpp:2147 +#: ekos/align/align.cpp:2177 #, fuzzy, kde-format msgid "Camera position angle is %1 degrees." msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/align/align.cpp:2169 ekos/align/align.cpp:2601 -#: ekos/align/align.cpp:2641 +#: ekos/align/align.cpp:2199 ekos/align/align.cpp:2637 +#: ekos/align/align.cpp:2677 #, kde-format msgid "Astrometry alignment completed successfully" msgstr "اكتملت المحاذاة الفلكيّة بنجاح" -#: ekos/align/align.cpp:2191 +#: ekos/align/align.cpp:2221 #, kde-format msgid "Maximum number of iterations reached. Solver failed." msgstr "" -#: ekos/align/align.cpp:2220 +#: ekos/align/align.cpp:2250 #, kde-format msgid "Target is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2303 +#: ekos/align/align.cpp:2312 +#, fuzzy, kde-format +#| msgid "Saved image to %1" +msgid "Saving failed solver image to %1" +msgstr "تم حقظ الصورة الى %1" + +#: ekos/align/align.cpp:2321 +#, kde-format +msgid "Solver failed. Retrying without scale constraint." +msgstr "" + +#: ekos/align/align.cpp:2331 +#, kde-format +msgid "Solver failed. Retrying without position constraint." +msgstr "" + +#: ekos/align/align.cpp:2339 #, fuzzy, kde-format #| msgid "Solver FOV" msgid "Solver Failed." msgstr "رمز رؤية المحلل" -#: ekos/align/align.cpp:2306 +#: ekos/align/align.cpp:2342 #, kde-format msgid "" "Please check you have sufficient stars in the image, the indicated FOV is " @@ -5968,261 +5989,261 @@ "Logging in Setup Tab -> Logs to get detailed information on the failure." msgstr "" -#: ekos/align/align.cpp:2365 +#: ekos/align/align.cpp:2401 #, fuzzy, kde-format msgid "Setting camera position angle to %1 degrees ..." msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/align/align.cpp:2372 +#: ekos/align/align.cpp:2408 #, kde-format msgid "Camera position angle is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2386 +#: ekos/align/align.cpp:2422 #, kde-format msgid "Current PA is %1; Target PA is %2; diff: %3" msgstr "" -#: ekos/align/align.cpp:2453 +#: ekos/align/align.cpp:2489 #, fuzzy, kde-format #| msgid "%1 is online." msgid "Refresh is complete." msgstr "%1 على الخط" -#: ekos/align/align.cpp:2460 ekos/auxiliary/darklibrary.cpp:1411 -#: ekos/focus/focus.cpp:1506 +#: ekos/align/align.cpp:2496 ekos/auxiliary/darklibrary.cpp:1411 +#: ekos/focus/focus.cpp:1529 #, fuzzy, kde-format msgid "Capture aborted." msgstr "سجّل صورة" -#: ekos/align/align.cpp:2466 +#: ekos/align/align.cpp:2502 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Solver aborted after %1 seconds." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/align/align.cpp:2509 ekos/capture/capture.cpp:1446 -#: ekos/focus/focus.cpp:3964 ekos/guide/guide.cpp:1118 ekos/manager.cpp:1897 -#: ekos/mount/mount.cpp:836 ekos/observatory/observatory.cpp:952 -#: ekos/scheduler/scheduler.cpp:911 +#: ekos/align/align.cpp:2545 ekos/capture/capture.cpp:1477 +#: ekos/focus/focus.cpp:4188 ekos/guide/guide.cpp:1137 ekos/manager.cpp:1903 +#: ekos/mount/mount.cpp:838 ekos/observatory/observatory.cpp:952 +#: ekos/scheduler/scheduler.cpp:748 #, fuzzy, kde-format msgctxt "log entry; %1 is the date, %2 is the text" msgid "%1 %2" msgstr "و 2" -#: ekos/align/align.cpp:2572 +#: ekos/align/align.cpp:2608 #, kde-format msgid "Mount completed slewing near celestial pole. Capture again to verify." msgstr "" -#: ekos/align/align.cpp:2595 +#: ekos/align/align.cpp:2631 #, fuzzy, kde-format msgid "Mount is synced to solution coordinates." msgstr "العرض الموضع يعمل خريطة" -#: ekos/align/align.cpp:2630 ekos/align/align.cpp:2660 -#: ekos/align/align.cpp:3971 ekos/align/polaralignmentassistant.cpp:637 +#: ekos/align/align.cpp:2666 ekos/align/align.cpp:2696 +#: ekos/align/align.cpp:4009 ekos/align/polaralignmentassistant.cpp:639 #, fuzzy, kde-format msgid "Settling..." msgstr "رسوب" -#: ekos/align/align.cpp:2636 +#: ekos/align/align.cpp:2672 #, fuzzy, kde-format #| msgid "completed" msgid "Differential slewing complete." msgstr "مكتمل" -#: ekos/align/align.cpp:2650 +#: ekos/align/align.cpp:2686 #, kde-format msgid "Slew complete. Target accuracy is not met, running solver again..." msgstr "" -#: ekos/align/align.cpp:2652 +#: ekos/align/align.cpp:2688 #, kde-format msgid "Slew complete. Solving Alignment Point. . ." msgstr "" -#: ekos/align/align.cpp:2695 ekos/align/align.cpp:2847 +#: ekos/align/align.cpp:2731 ekos/align/align.cpp:2883 #, kde-format msgid "Syncing failed." msgstr "" -#: ekos/align/align.cpp:2697 +#: ekos/align/align.cpp:2733 #, fuzzy, kde-format msgid "Slewing failed." msgstr "أخرى" -#: ekos/align/align.cpp:2740 +#: ekos/align/align.cpp:2776 #, fuzzy, kde-format msgid "Rotator reached camera position angle." msgstr "اليوم && الموقع" -#: ekos/align/align.cpp:2752 +#: ekos/align/align.cpp:2788 #, kde-format msgid "" "Rotator failed to arrive at the requested position angle (Deviation %1 " "arcmin)." msgstr "" -#: ekos/align/align.cpp:2797 +#: ekos/align/align.cpp:2833 #, fuzzy, kde-format msgid "Slew detected, suspend solving..." msgstr "فارمنغتون" -#: ekos/align/align.cpp:2841 +#: ekos/align/align.cpp:2877 #, fuzzy, kde-format msgid "Syncing to RA (%1) DEC (%2)" msgstr "انتقِ إدخال الأسس" -#: ekos/align/align.cpp:2865 +#: ekos/align/align.cpp:2901 #, fuzzy, kde-format msgid "Slewing to target coordinates: RA (%1) DEC (%2)." msgstr "انتقِ إدخال الأسس" -#: ekos/align/align.cpp:2870 +#: ekos/align/align.cpp:2906 #, fuzzy, kde-format msgid "" "Slewing to target coordinates: RA (%1) DEC (%2) is rejected. (see " "notification)" msgstr "انتقِ إدخال الأسس" -#: ekos/align/align.cpp:2889 +#: ekos/align/align.cpp:2925 #, kde-format msgid "Ekos job (%1) - Telescope synced" msgstr "" -#: ekos/align/align.cpp:2945 +#: ekos/align/align.cpp:2981 #, kde-format msgctxt "@title:window" msgid "Load Image" msgstr "حمّل الصّورة" -#: ekos/align/align.cpp:3175 +#: ekos/align/align.cpp:3211 #, fuzzy, kde-format msgid "World Coordinate System (WCS) is enabled." msgstr "انتقِ إحداثية النظام لـ مخرجات ملف" -#: ekos/align/align.cpp:3180 +#: ekos/align/align.cpp:3216 #, fuzzy, kde-format msgid "World Coordinate System (WCS) is disabled." msgstr "انتقِ إحداثية النظام لـ مخرجات ملف" -#: ekos/align/align.cpp:3199 +#: ekos/align/align.cpp:3235 #, fuzzy, kde-format msgid "Capture error. Aborting..." msgstr "سجّل صورة" -#: ekos/align/align.cpp:3204 ekos/capture/captureprocess.cpp:1444 -#: ekos/capture/captureprocess.cpp:1939 +#: ekos/align/align.cpp:3240 ekos/capture/captureprocess.cpp:1470 +#: ekos/capture/captureprocess.cpp:1965 #, kde-format msgid "Restarting capture attempt #%1" msgstr "" -#: ekos/align/align.cpp:3324 +#: ekos/align/align.cpp:3360 #, fuzzy, kde-format msgctxt "@title:window" msgid "Align Frame" msgstr "مركّز على:" -#: ekos/align/align.cpp:3399 +#: ekos/align/align.cpp:3435 #, fuzzy, kde-format msgid "StellarSolver Options" msgstr "البرج الاسم خيارات" -#: ekos/align/align.cpp:3404 +#: ekos/align/align.cpp:3440 #, kde-format msgid "External & Online Programs" msgstr "" -#: ekos/align/align.cpp:3408 +#: ekos/align/align.cpp:3444 #, fuzzy, kde-format msgid "Scale & Position" msgstr "إعادة تعيين الموضع" -#: ekos/align/align.cpp:3412 +#: ekos/align/align.cpp:3448 #, fuzzy, kde-format #| msgid "Profile Editor" msgid "Align Options Profiles Editor" msgstr "محرر منظومة الأجهزة" #. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/align/align.cpp:3430 ekos/align/opsastrometryindexfiles.ui:329 +#: ekos/align/align.cpp:3466 ekos/align/opsastrometryindexfiles.ui:329 #, fuzzy, kde-format msgid "Index Files" msgstr "غير صحيح ملف" -#: ekos/align/align.cpp:3495 ekos/guide/guidetargetplot.cpp:55 +#: ekos/align/align.cpp:3531 ekos/guide/guidetargetplot.cpp:55 #, fuzzy, kde-format msgid "dRA (arcsec)" msgstr "دقيقة قوسية" -#: ekos/align/align.cpp:3496 ekos/guide/guidetargetplot.cpp:56 +#: ekos/align/align.cpp:3532 ekos/guide/guidetargetplot.cpp:56 #, fuzzy, kde-format #| msgctxt "City name (optional, probably does not need a translation)" #| msgid "Parsons" msgid "dDE (arcsec)" msgstr "Parsons" -#: ekos/align/align.cpp:3542 ekos/capture/capture.cpp:3297 -#: ekos/focus/focus.cpp:4711 +#: ekos/align/align.cpp:3578 ekos/capture/capture.cpp:2654 +#: ekos/focus/focus.cpp:4952 #, fuzzy, kde-format #| msgid "File verification failed!" msgid "Filter operation failed." msgstr "خطوة التأكد من صحة الملف فشلت!" -#: ekos/align/align.cpp:3554 ekos/capture/capture.cpp:3233 +#: ekos/align/align.cpp:3590 ekos/capture/capture.cpp:2590 #, kde-format msgid "Changing focus offset by %1 steps..." msgstr "" -#: ekos/align/align.cpp:3561 ekos/auxiliary/buildfilteroffsets.cpp:466 -#: ekos/capture/capture.cpp:3238 +#: ekos/align/align.cpp:3597 ekos/auxiliary/buildfilteroffsets.cpp:466 +#: ekos/capture/capture.cpp:2595 #, kde-format msgid "Changing filter to %1..." msgstr "" -#: ekos/align/align.cpp:3566 ekos/capture/capture.cpp:3243 +#: ekos/align/align.cpp:3602 ekos/capture/capture.cpp:2600 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Auto focus on filter change..." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" -#: ekos/align/align.cpp:3687 +#: ekos/align/align.cpp:3723 #, fuzzy, kde-format #| msgid "Invalid URL" msgid "Invalid FOV." msgstr "الـعنوان غير صحيح" -#: ekos/align/align.cpp:3822 +#: ekos/align/align.cpp:3860 #, fuzzy, kde-format msgctxt "@title:window" msgid "Export Solution Points" msgstr "امسح الكل" -#: ekos/align/align.cpp:3845 ekos/align/mountmodel.cpp:263 -#: ekos/align/mountmodel.cpp:389 ekos/capture/capture.cpp:2077 -#: ekos/capture/capture.cpp:2507 ekos/guide/guidedriftgraph.cpp:475 -#: ekos/scheduler/scheduler.cpp:3462 ekos/scheduler/scheduler.cpp:3831 -#: fitsviewer/fitstab.cpp:494 tools/scriptbuilder.cpp:832 +#: ekos/align/align.cpp:3883 ekos/align/mountmodel.cpp:264 +#: ekos/align/mountmodel.cpp:390 ekos/capture/capture.cpp:1950 +#: ekos/capture/capture.cpp:2036 ekos/guide/guidedriftgraph.cpp:476 +#: ekos/scheduler/scheduler.cpp:2592 ekos/scheduler/scheduler.cpp:2959 +#: fitsviewer/fitstab.cpp:503 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:929 #, kde-format msgid "Invalid URL: %1" msgstr "الـعنوان غير صحيح: %1" -#: ekos/align/align.cpp:3854 ekos/align/mountmodel.cpp:400 -#: ekos/capture/capture.cpp:2530 ekos/guide/guidedriftgraph.cpp:484 -#: ekos/scheduler/scheduler.cpp:3843 ekos/scheduler/scheduler.cpp:6221 +#: ekos/align/align.cpp:3892 ekos/align/mountmodel.cpp:401 +#: ekos/capture/captureprocess.cpp:2392 ekos/guide/guidedriftgraph.cpp:485 +#: ekos/scheduler/scheduler.cpp:4001 ekos/scheduler/schedulerprocess.cpp:1573 #, kde-format msgid "Unable to write to file %1" msgstr "تعذّرت الكتابة إلى الملفّ %1" -#: ekos/align/align.cpp:3855 ekos/align/mountmodel.cpp:283 -#: ekos/align/mountmodel.cpp:401 ekos/capture/capture.cpp:2093 -#: ekos/guide/guidedriftgraph.cpp:485 ekos/scheduler/scheduler.cpp:3506 -#: ekos/scheduler/scheduler.cpp:3844 ekos/scheduler/scheduler.cpp:6165 -#: ekos/scheduler/scheduler.cpp:6222 indi/drivermanager.cpp:1520 -#: indi/indidriver.cpp:921 kstarsactions.cpp:1375 oal/execute.cpp:320 -#: options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 +#: ekos/align/align.cpp:3893 ekos/align/mountmodel.cpp:284 +#: ekos/align/mountmodel.cpp:402 ekos/capture/capture.cpp:1966 +#: ekos/capture/captureprocess.cpp:2276 ekos/guide/guidedriftgraph.cpp:486 +#: ekos/scheduler/scheduler.cpp:2636 ekos/scheduler/scheduler.cpp:3945 +#: ekos/scheduler/scheduler.cpp:4002 ekos/scheduler/schedulerprocess.cpp:1574 +#: indi/drivermanager.cpp:1537 indi/indidriver.cpp:921 kstarsactions.cpp:1384 +#: oal/execute.cpp:320 options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 #: tools/modcalcapcoord.cpp:142 tools/modcalcdaylength.cpp:257 #: tools/modcalcgalcoord.cpp:191 tools/modcalcgeodcoord.cpp:231 #: tools/modcalcjd.cpp:117 tools/modcalcplanets.cpp:195 @@ -6234,28 +6255,28 @@ msgid "Could Not Open File" msgstr "لم يمكن فتح الملف" -#: ekos/align/align.cpp:3876 +#: ekos/align/align.cpp:3914 #, fuzzy, kde-format msgid "Error in table structure." msgstr "الأخطاء بوصة سطور" -#: ekos/align/align.cpp:3885 +#: ekos/align/align.cpp:3923 #, fuzzy, kde-format #| msgid "Horizontal Coordinates" msgid "Solution Points Saved as: %1" msgstr "احداثيات افقية" -#: ekos/align/align.cpp:3899 +#: ekos/align/align.cpp:3937 #, fuzzy, kde-format msgid "Polar Alignment" msgstr "مركّز على:" -#: ekos/align/align.cpp:4428 +#: ekos/align/align.cpp:4466 #, fuzzy, kde-format msgid "Capture timed out." msgstr "سجّل صورة" -#: ekos/align/align.cpp:4437 +#: ekos/align/align.cpp:4475 #, fuzzy, kde-format msgid "Capturing still running, Retrying in %1 seconds..." msgstr "جاري التّحميل" @@ -6301,7 +6322,7 @@ #. i18n: ectx: property (text), widget (QPushButton, stopFocusB) #: ekos/align/align.ui:149 ekos/align/polaralignmentassistant.ui:819 #: ekos/align/polaralignmentassistant.ui:822 ekos/auxiliary/darklibrary.ui:585 -#: ekos/focus/focus.ui:456 ekos/guide/guide.ui:153 ekos/manager.cpp:222 +#: ekos/focus/focus.ui:373 ekos/guide/guide.ui:153 ekos/manager.cpp:226 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:137 @@ -6520,20 +6541,20 @@ #. i18n: ectx: property (text), widget (QLabel, gainLabel) #: ekos/align/align.ui:555 ekos/auxiliary/darklibrary.ui:477 #: ekos/capture/capture.ui:137 ekos/capture/captureprocessoverlay.ui:296 -#: ekos/focus/focus.ui:514 +#: ekos/focus/focus.ui:533 #, kde-format msgid "Gain:" msgstr "الكسب:" #. i18n: ectx: property (text), widget (QLabel, label_18) #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/align.ui:562 ekos/focus/focus.ui:790 ekos/guide/guide.ui:401 +#: ekos/align/align.ui:562 ekos/focus/focus.ui:809 ekos/guide/guide.ui:401 #, fuzzy, kde-format msgid "Bin:" msgstr "ثن" #. i18n: ectx: property (toolTip), widget (QPushButton, showFITSViewerB) -#: ekos/align/align.ui:584 ekos/focus/focus.ui:720 ekos/guide/guide.ui:166 +#: ekos/align/align.ui:584 ekos/focus/focus.ui:739 ekos/guide/guide.ui:166 #, fuzzy, kde-format msgid "Show in FITS Viewer" msgstr "مرحبا إلى نجوم ك المستعرض" @@ -6585,7 +6606,7 @@ #. i18n: ectx: property (text), widget (QLabel, filterLabel) #. i18n: ectx: property (text), widget (QLabel, label) #. i18n: ectx: property (text), widget (QLabel, label_18) -#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:558 +#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:577 #: ekos/profileeditor.ui:644 fitsviewer/fitsdebayer.ui:22 oal/execute.ui:358 #, kde-format msgid "Filter:" @@ -6602,7 +6623,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/align/align.ui:700 ekos/focus/focus.ui:571 ekos/guide/guide.ui:375 +#: ekos/align/align.ui:700 ekos/focus/focus.ui:590 ekos/guide/guide.ui:375 #, fuzzy, kde-format msgid "Exp:" msgstr "EXP" @@ -6617,7 +6638,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_11) #. i18n: ectx: property (text), widget (QLabel, ISOLabel) #: ekos/align/align.ui:736 ekos/auxiliary/darklibrary.ui:506 -#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:816 +#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:835 #, kde-format msgid "ISO:" msgstr "آيزو:" @@ -6680,11 +6701,12 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, l_02) #. i18n: ectx: property (text), widget (QLabel, label_2) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverDECLabel) #: ekos/align/align.ui:916 ekos/align/opsastrometry.ui:389 #: ekos/guide/guide.ui:342 ekos/guide/guide.ui:1247 #: ekos/guide/opscalibration.ui:300 ekos/guide/opsguide.ui:128 #: ekos/mount/mount.ui:161 ekos/scheduler/scheduler.ui:488 -#: skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:222 skycomponents/imageoverlaycomponent.cpp:62 #, fuzzy, kde-format msgid "DEC" msgstr "الميل" @@ -6836,81 +6858,82 @@ msgid "Take Another Image" msgstr "احذف الصورة" -#: ekos/align/mountmodel.cpp:255 +#: ekos/align/mountmodel.cpp:256 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Alignment List" msgstr "الملاحظة قائمة" -#: ekos/align/mountmodel.cpp:282 ekos/capture/capture.cpp:2092 -#: ekos/scheduler/scheduler.cpp:3505 ekos/scheduler/scheduler.cpp:6164 +#: ekos/align/mountmodel.cpp:283 ekos/capture/capture.cpp:1965 +#: ekos/capture/captureprocess.cpp:2275 ekos/scheduler/scheduler.cpp:2635 +#: ekos/scheduler/scheduler.cpp:3944 #, kde-format msgid "Unable to open file %1" msgstr "تعذّر فتح الملفّ %1" -#: ekos/align/mountmodel.cpp:304 ekos/capture/capture.cpp:2119 +#: ekos/align/mountmodel.cpp:305 ekos/capture/captureprocess.cpp:2301 #, kde-format msgid "" "Deprecated sequence file format version %1. Please construct a new sequence " "file." msgstr "" -#: ekos/align/mountmodel.cpp:366 +#: ekos/align/mountmodel.cpp:367 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save Ekos Alignment List" msgstr "الملاحظة قائمة" -#: ekos/align/mountmodel.cpp:383 +#: ekos/align/mountmodel.cpp:384 #, fuzzy, kde-format msgid "Failed to save alignment list" msgstr "فشل في تحميل الصورة " -#: ekos/align/mountmodel.cpp:429 +#: ekos/align/mountmodel.cpp:430 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Alignment List saved to %1" msgstr "تم حفظ ملف FITS الى %1" -#: ekos/align/mountmodel.cpp:541 ekos/align/mountmodel.cpp:549 +#: ekos/align/mountmodel.cpp:542 ekos/align/mountmodel.cpp:550 #, kde-format msgid "DEC is below the altitude limit" msgstr "" -#: ekos/align/mountmodel.cpp:628 +#: ekos/align/mountmodel.cpp:629 #, fuzzy, kde-format msgid "Point calculation error." msgstr "العميل" -#: ekos/align/mountmodel.cpp:650 +#: ekos/align/mountmodel.cpp:651 #, fuzzy, kde-format #| msgctxt "City in South Dakota USA" #| msgid "Elk Point" msgid "Sky Point" msgstr "Elk Point" -#: ekos/align/mountmodel.cpp:858 +#: ekos/align/mountmodel.cpp:859 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to clear all the alignment points?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/align/mountmodel.cpp:859 +#: ekos/align/mountmodel.cpp:860 #, fuzzy, kde-format msgid "Clear Align Points" msgstr "امسح الكل" -#: ekos/align/mountmodel.cpp:964 +#: ekos/align/mountmodel.cpp:965 #, kde-format msgid "The Mount Model Tool is Reset." msgstr "" -#: ekos/align/mountmodel.cpp:1001 +#: ekos/align/mountmodel.cpp:1002 #, kde-format msgid "Please Check the Alignment Points." msgstr "" -#: ekos/align/mountmodel.cpp:1008 +#: ekos/align/mountmodel.cpp:1009 #, kde-format msgid "" "In the Align Module, \"Nothing\" is Selected for the Solver Action. This " @@ -6918,22 +6941,22 @@ "report the pointing model errors. Do you wish to continue?" msgstr "" -#: ekos/align/mountmodel.cpp:1011 +#: ekos/align/mountmodel.cpp:1012 #, kde-format msgid "Pointing Model Report Only?" msgstr "" -#: ekos/align/mountmodel.cpp:1028 +#: ekos/align/mountmodel.cpp:1029 #, kde-format msgid "The Mount Model Tool is Starting." msgstr "" -#: ekos/align/mountmodel.cpp:1037 +#: ekos/align/mountmodel.cpp:1038 #, kde-format msgid "The Mount Model Tool is Paused." msgstr "" -#: ekos/align/mountmodel.cpp:1096 +#: ekos/align/mountmodel.cpp:1097 #, kde-format msgid "The Mount Model Tool is Finished." msgstr "" @@ -7684,8 +7707,11 @@ msgstr "L" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUseImageScale) +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_FitsSolverUseScale) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverScale) #. i18n: ectx: label, entry (AstrometryUseImageScale), group (Align) -#: ekos/align/opsastrometry.ui:57 kstars.kcfg:2329 +#: ekos/align/opsastrometry.ui:57 fitsviewer/platesolve.ui:57 +#: fitsviewer/platesolve.ui:70 kstars.kcfg:2399 #, kde-format msgid "" "Set image scale to speed up solver as it does not have to search index files " @@ -7693,7 +7719,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUseImageScale) -#: ekos/align/opsastrometry.ui:60 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUseScale) +#: ekos/align/opsastrometry.ui:60 fitsviewer/platesolve.ui:60 #, fuzzy, kde-format #| msgid "Linear Scale" msgid "Use Scale" @@ -7828,7 +7855,7 @@ #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUsePosition) #. i18n: ectx: label, entry (AstrometryUsePosition), group (Align) -#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2359 +#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2429 #, kde-format msgid "" "Set estimated position to speed up astrometry solver as it does not have to " @@ -7836,16 +7863,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUsePosition) -#: ekos/align/opsastrometry.ui:325 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUsePosition) +#: ekos/align/opsastrometry.ui:325 fitsviewer/platesolve.ui:142 #, fuzzy, kde-format msgid "Use Position" msgstr "إعادة تعيين الموضع" #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_44) #. i18n: ectx: property (toolTip), widget (QLabel, label_8) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRadiusLabel) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverRadius) #. i18n: ectx: label, entry (AstrometryRadius), group (Align) #: ekos/align/opsastrometry.ui:344 ekos/align/opsastrometry.ui:451 -#: kstars.kcfg:2373 +#: fitsviewer/platesolve.ui:270 fitsviewer/platesolve.ui:286 kstars.kcfg:2443 #, kde-format msgid "" "The Search Radius for the Estimated Telescope/Image Field Position in " @@ -7867,8 +7897,11 @@ #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_47) #. i18n: ectx: property (toolTip), widget (dmsBox, estRA) #. i18n: ectx: property (toolTip), widget (QLabel, label_14) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRALabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstRA) #: ekos/align/opsastrometry.ui:376 ekos/align/opsastrometry.ui:399 -#: ekos/align/opsastrometry.ui:406 +#: ekos/align/opsastrometry.ui:406 fitsviewer/platesolve.ui:174 +#: fitsviewer/platesolve.ui:199 #, kde-format msgid "" "The RA of the Estimated Telescope/Image Field Position in hh:mm:ss notation" @@ -7883,8 +7916,11 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_15) #. i18n: ectx: property (toolTip), widget (dmsBox, estDec) #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_48) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverDECLabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstDec) #: ekos/align/opsastrometry.ui:386 ekos/align/opsastrometry.ui:470 -#: ekos/align/opsastrometry.ui:493 +#: ekos/align/opsastrometry.ui:493 fitsviewer/platesolve.ui:219 +#: fitsviewer/platesolve.ui:250 #, kde-format msgid "" "The DEC of the Estimated Telescope/Image Field Position in dd:mm:ss notation" @@ -7897,7 +7933,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/opsastrometry.ui:454 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRadiusLabel) +#: ekos/align/opsastrometry.ui:454 fitsviewer/platesolve.ui:273 #, kde-format msgid "Radius" msgstr "نصف القطر" @@ -8124,7 +8161,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, northDECGuideEnabled) #: ekos/align/opsastrometryindexfiles.ui:256 ekos/analyze/analyze.ui:199 #: ekos/auxiliary/stellarsolverprofileeditor.ui:213 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:531 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:511 #: ekos/guide/guide.ui:304 ekos/guide/guide.ui:456 #: kstarslite/qml/indi/modules/MotionControl.qml:294 #, kde-format, kde-kuit-format @@ -9063,213 +9100,219 @@ msgid "API Key:" msgstr "مفتاح و‌ب‌ت API:" -#: ekos/align/polaralignmentassistant.cpp:28 +#: ekos/align/polaralignmentassistant.cpp:29 #, fuzzy, kde-format #| msgid "Capture" msgid "First Capture" msgstr "الالتقاط" -#: ekos/align/polaralignmentassistant.cpp:29 +#: ekos/align/polaralignmentassistant.cpp:30 #, kde-format msgid "First Solve" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:30 +#: ekos/align/polaralignmentassistant.cpp:31 #, fuzzy, kde-format #| msgid "Find City" msgid "Finding CP" msgstr "ابحث عن مدينة" -#: ekos/align/polaralignmentassistant.cpp:31 +#: ekos/align/polaralignmentassistant.cpp:32 #, fuzzy, kde-format #| msgid "First position" msgid "First Rotation" msgstr "الموقع الأول" -#: ekos/align/polaralignmentassistant.cpp:32 +#: ekos/align/polaralignmentassistant.cpp:33 #, fuzzy, kde-format msgid "First Settle" msgstr "سياتل" -#: ekos/align/polaralignmentassistant.cpp:33 +#: ekos/align/polaralignmentassistant.cpp:34 #, fuzzy, kde-format #| msgid "Single Window Capture" msgid "Second Capture" msgstr "نافذة واحدة للصور الملتقطة" -#: ekos/align/polaralignmentassistant.cpp:34 +#: ekos/align/polaralignmentassistant.cpp:35 #, fuzzy, kde-format msgid "Second Solve" msgstr "كويكبات" -#: ekos/align/polaralignmentassistant.cpp:35 +#: ekos/align/polaralignmentassistant.cpp:36 #, fuzzy, kde-format #| msgid "Second position" msgid "Second Rotation" msgstr "الموقع الثاني" -#: ekos/align/polaralignmentassistant.cpp:36 +#: ekos/align/polaralignmentassistant.cpp:37 #, fuzzy, kde-format #| msgid "Single Window Capture" msgid "Second Settle" msgstr "نافذة واحدة للصور الملتقطة" -#: ekos/align/polaralignmentassistant.cpp:37 +#: ekos/align/polaralignmentassistant.cpp:38 #, fuzzy, kde-format #| msgid "Capture" msgid "Third Capture" msgstr "الالتقاط" -#: ekos/align/polaralignmentassistant.cpp:38 +#: ekos/align/polaralignmentassistant.cpp:39 #, fuzzy, kde-format msgid "Third Solve" msgstr "الشّيش النهر" -#: ekos/align/polaralignmentassistant.cpp:39 +#: ekos/align/polaralignmentassistant.cpp:40 #, fuzzy, kde-format msgid "Select Star" msgstr "انتقِ a نجم" -#: ekos/align/polaralignmentassistant.cpp:40 +#: ekos/align/polaralignmentassistant.cpp:41 #, fuzzy, kde-format #| msgid "Refresh" msgid "Refreshing" msgstr "ينعش…" -#: ekos/align/polaralignmentassistant.cpp:41 +#: ekos/align/polaralignmentassistant.cpp:42 #, kde-format msgid "Refresh Complete" msgstr "اكتمل الإنعاش" -#: ekos/align/polaralignmentassistant.cpp:121 +#: ekos/align/polaralignmentassistant.cpp:122 #, kde-format msgid "

            Polar Alignment tool requires a German Equatorial Mount.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:176 +#: ekos/align/polaralignmentassistant.cpp:177 #, fuzzy, kde-format msgid "Refresh solver timed out: %1s" msgstr "جاري التّحميل" -#: ekos/align/polaralignmentassistant.cpp:181 +#: ekos/align/polaralignmentassistant.cpp:182 #, fuzzy, kde-format #| msgid "Solver FOV" msgid "Refresh solver failed: %1s" msgstr "رمز رؤية المحلل" -#: ekos/align/polaralignmentassistant.cpp:574 +#: ekos/align/polaralignmentassistant.cpp:569 +#, fuzzy, kde-format +#| msgid "Solver FOV" +msgid "PAA: Solver failed, retrying." +msgstr "رمز رؤية المحلل" + +#: ekos/align/polaralignmentassistant.cpp:576 #, kde-format msgid "PAA: Stopping, solver failed too many times." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:603 +#: ekos/align/polaralignmentassistant.cpp:605 #, fuzzy, kde-format msgid "Mount first rotation is complete." msgstr "العميل" -#: ekos/align/polaralignmentassistant.cpp:610 +#: ekos/align/polaralignmentassistant.cpp:612 #, fuzzy, kde-format msgid "Mount second rotation is complete." msgstr "العميل" -#: ekos/align/polaralignmentassistant.cpp:649 +#: ekos/align/polaralignmentassistant.cpp:651 #, kde-format msgid "Mount aborted. Reverse RA axis direction and try again." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:734 +#: ekos/align/polaralignmentassistant.cpp:736 #, kde-format msgid "" "Warning: Equatorial Grid Lines will not be drawn due to limited resources " "mode." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:738 +#: ekos/align/polaralignmentassistant.cpp:740 #, fuzzy, kde-format msgid "Clearing mount Alignment Model..." msgstr "فارمنغتون" -#: ekos/align/polaralignmentassistant.cpp:779 +#: ekos/align/polaralignmentassistant.cpp:781 #, fuzzy, kde-format #| msgid "Display the telescope position on the sky map" msgid "This could cause the telescope to cross the meridian." msgstr "اعرض موقع التلسكوب في خارطة السماء" -#: ekos/align/polaralignmentassistant.cpp:829 +#: ekos/align/polaralignmentassistant.cpp:831 #, fuzzy, kde-format msgid "Parking the mount..." msgstr "إعداد المناظير" -#: ekos/align/polaralignmentassistant.cpp:869 +#: ekos/align/polaralignmentassistant.cpp:871 #, kde-format msgid "Please wait until mount completes rotating to RA (%1) DE (%2)" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:885 -#: ekos/align/polaralignmentassistant.cpp:891 +#: ekos/align/polaralignmentassistant.cpp:887 +#: ekos/align/polaralignmentassistant.cpp:893 #, fuzzy, kde-format msgid "PAA: Failed to findCorrectedPixel." msgstr "فشل في تحميل الصورة " -#: ekos/align/polaralignmentassistant.cpp:917 +#: ekos/align/polaralignmentassistant.cpp:919 #, fuzzy, kde-format msgid "PAA: Failed to find RA Axis center." msgstr "فشل في تحميل الصورة " -#: ekos/align/polaralignmentassistant.cpp:988 +#: ekos/align/polaralignmentassistant.cpp:990 #, kde-format msgid "" "Polar-alignment star cannot be updated during refresh phase as it might " "affect error measurements." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1005 +#: ekos/align/polaralignmentassistant.cpp:1007 #, fuzzy, kde-format #| msgid "First position" msgid "First manual rotation done." msgstr "الموقع الأول" -#: ekos/align/polaralignmentassistant.cpp:1010 +#: ekos/align/polaralignmentassistant.cpp:1012 #, fuzzy, kde-format #| msgid "Second position" msgid "Second manual rotation done." msgstr "الموقع الثاني" -#: ekos/align/polaralignmentassistant.cpp:1053 +#: ekos/align/polaralignmentassistant.cpp:1055 #, kde-format msgid "" "Mount is synced to celestial pole. You can now continue Polar Alignment " "Assistant procedure." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1072 +#: ekos/align/polaralignmentassistant.cpp:1074 #, fuzzy, kde-format msgid "Please wait while WCS data is processed..." msgstr "رجاء إبقاء بينما يجري التحميل ملفّ." -#: ekos/align/polaralignmentassistant.cpp:1103 +#: ekos/align/polaralignmentassistant.cpp:1105 #, fuzzy, kde-format #| msgid "%1 is online." msgid "WCS data processing is complete." msgstr "%1 على الخط" -#: ekos/align/polaralignmentassistant.cpp:1112 +#: ekos/align/polaralignmentassistant.cpp:1114 #, kde-format msgid "WCS info is now valid. Capturing next frame..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1154 +#: ekos/align/polaralignmentassistant.cpp:1156 #, fuzzy, kde-format msgid "Failed to process World Coordinate System: %1. Try again." msgstr "اليوم && الموقع" -#: ekos/align/polaralignmentassistant.cpp:1172 +#: ekos/align/polaralignmentassistant.cpp:1174 #, fuzzy, kde-format msgid "PAA: Failed to find the RA axis. Quitting." msgstr "فشل في تحميل الصورة " #. i18n: ectx: property (text), widget (QLabel, PAHMessageText) -#: ekos/align/polaralignmentassistant.cpp:1203 +#: ekos/align/polaralignmentassistant.cpp:1205 #: ekos/align/polaralignmentassistant.ui:212 #, kde-format msgid "" @@ -9277,59 +9320,59 @@ "capturing the first image...

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1205 +#: ekos/align/polaralignmentassistant.cpp:1207 #, fuzzy, kde-format msgid "

            Solving the first image...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1207 +#: ekos/align/polaralignmentassistant.cpp:1209 #, fuzzy, kde-format msgid "

            Executing the first mount rotation...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1209 +#: ekos/align/polaralignmentassistant.cpp:1211 #, kde-format msgid "

            Settling after the first mount rotation.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1211 +#: ekos/align/polaralignmentassistant.cpp:1213 #, fuzzy, kde-format msgid "

            Settling after the second mount rotation.

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1213 +#: ekos/align/polaralignmentassistant.cpp:1215 #, fuzzy, kde-format msgid "

            Capturing the second image...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1215 +#: ekos/align/polaralignmentassistant.cpp:1217 #, fuzzy, kde-format msgid "

            Solving the second image...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1217 +#: ekos/align/polaralignmentassistant.cpp:1219 #, fuzzy, kde-format msgid "

            Executing the second mount rotation...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1219 +#: ekos/align/polaralignmentassistant.cpp:1221 #, fuzzy, kde-format msgid "

            Capturing the third and final image...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1221 +#: ekos/align/polaralignmentassistant.cpp:1223 #, fuzzy, kde-format msgid "

            Solving the third image...

            " msgstr "جاري التّحميل." -#: ekos/align/polaralignmentassistant.cpp:1224 +#: ekos/align/polaralignmentassistant.cpp:1226 #, kde-format msgid "" "

            Choose your exposure time & select an adjustment method. Then click " "refresh to begin adjustments.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1226 +#: ekos/align/polaralignmentassistant.cpp:1228 #, kde-format msgid "" "

            Choose your exposure time & select an adjustment method. Click " @@ -9338,7 +9381,7 @@ "MoveStar & Calc Error method to estimate the remaining error.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1229 +#: ekos/align/polaralignmentassistant.cpp:1231 #, kde-format msgid "" "

            Adjust mount's Altitude and Azimuth knobs to reduce the polar " @@ -9347,7 +9390,7 @@ "you're finished.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1231 +#: ekos/align/polaralignmentassistant.cpp:1233 #, kde-format msgid "" "

            Adjust mount's Altitude knob to move the star along the yellow " @@ -9356,7 +9399,7 @@ "Stop when the star is centered.

            " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1247 +#: ekos/align/polaralignmentassistant.cpp:1249 #, kde-format msgid "Cannot change to MoveStar algorithm once refresh has begun" msgstr "" @@ -9589,7 +9632,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1_2) #. i18n: ectx: property (text), widget (QLabel, label_8) #: ekos/align/polaralignmentassistant.ui:548 -#: ekos/capture/calibrationoptions.ui:102 tools/argsetaltaz.ui:37 +#: ekos/capture/calibrationoptions.ui:87 tools/argsetaltaz.ui:37 #: tools/modcalcplanets.ui:296 #, kde-format msgid "Alt:" @@ -9641,7 +9684,7 @@ #. i18n: ectx: property (text), widget (QPushButton, startB) #: ekos/align/polaralignmentassistant.ui:806 #: ekos/align/polaralignmentassistant.ui:809 ekos/auxiliary/darklibrary.ui:575 -#: ekos/manager.cpp:140 ekos/manager.cpp:228 ekos/manager.cpp:580 +#: ekos/manager.cpp:143 ekos/manager.cpp:232 ekos/manager.cpp:584 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:166 @@ -9658,10 +9701,10 @@ #. i18n: ectx: property (text), widget (QPushButton, captureB) #. i18n: ectx: attribute (title), widget (QWidget, captureTab) #: ekos/align/polaralignwidget.ui:37 ekos/align/polaralignwidget.ui:157 -#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1872 +#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1874 #: ekos/analyze/analyze.ui:374 ekos/auxiliary/opslogs.ui:285 #: ekos/capture/capturepreviewwidget.ui:79 ekos/guide/guide.ui:137 -#: ekos/opsekos.ui:538 +#: ekos/opsekos.ui:551 #, kde-format msgid "Capture" msgstr "الالتقاط" @@ -9669,9 +9712,11 @@ #. i18n: ectx: property (text), widget (QLabel, PAso1) #. i18n: ectx: property (text), widget (QLabel, PAso2) #. i18n: ectx: property (text), widget (QLabel, PAso3) +#. i18n: ectx: property (text), widget (QPushButton, SolveButton) #. i18n: ectx: property (text), widget (QPushButton, solveButton) #: ekos/align/polaralignwidget.ui:77 ekos/align/polaralignwidget.ui:197 -#: ekos/align/polaralignwidget.ui:317 options/opsimageoverlay.ui:242 +#: ekos/align/polaralignwidget.ui:317 fitsviewer/fitstab.cpp:676 +#: fitsviewer/platesolve.ui:50 options/opsimageoverlay.ui:242 #: skycomponents/imageoverlaycomponent.cpp:343 #: skycomponents/imageoverlaycomponent.cpp:703 #: skycomponents/imageoverlaycomponent.cpp:783 @@ -9689,7 +9734,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, PAsetup) -#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:324 +#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:328 #, kde-format msgid "Setup" msgstr "الإعداد" @@ -9732,52 +9777,52 @@ msgid "Failed to find solver settings." msgstr "فشل في تحميل الصورة " -#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 #: ekos/observatory/observatory.cpp:356 indi/indidome.cpp:21 #: indi/indidustcap.cpp:18 indi/indimount.cpp:32 #, fuzzy, kde-format msgid "Parked" msgstr "كواكب" -#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 +#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 #: ekos/observatory/observatory.cpp:283 ekos/observatory/observatory.cpp:299 #: indi/indidome.cpp:21 indi/indidustcap.cpp:17 indi/indimount.cpp:32 #, kde-format msgid "Parking" msgstr "" -#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 ekos/ekos.h:140 -#: ekos/scheduler/schedulerjob.cpp:638 indi/indimount.cpp:31 +#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 ekos/ekos.h:140 +#: ekos/scheduler/schedulerjob.cpp:614 indi/indimount.cpp:31 #, fuzzy, kde-format msgid "Slewing" msgstr "المجال" -#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 +#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 #: indi/indimount.cpp:31 #, kde-format msgid "Moving" msgstr "ينقل" #. i18n: ectx: property (title), widget (QGroupBox, trackingGroup) -#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 +#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:156 #: ekos/mount/mount.ui:611 indi/indidome.cpp:21 indi/indimount.cpp:32 #, fuzzy, kde-format #| msgid "Track" msgid "Tracking" msgstr "متابعة" -#: ekos/analyze/analyze.cpp:480 ekos/analyze/analyze.cpp:492 +#: ekos/analyze/analyze.cpp:482 ekos/analyze/analyze.cpp:494 #, fuzzy, kde-format msgid "Current Session" msgstr "احفظ الحالي قائمة?" -#: ekos/analyze/analyze.cpp:481 +#: ekos/analyze/analyze.cpp:483 #, fuzzy, kde-format #| msgid "Read from input file" msgid "Read from File" msgstr "إقرأ من ملف المدخلات" -#: ekos/analyze/analyze.cpp:482 +#: ekos/analyze/analyze.cpp:484 #, kde-format msgid "Set alternative image-file base directory" msgstr "" @@ -9785,25 +9830,25 @@ #. i18n call below is broken up (and the word "analyze" is protected from it) because i18n #. translates "analyze" to "analyse" for the English UK locale, but we need to keep it ".analyze" #. because that's what how the files are named. -#: ekos/analyze/analyze.cpp:506 +#: ekos/analyze/analyze.cpp:508 #, fuzzy, kde-format #| msgid "Select Fields in Input File" msgctxt "@title:window" msgid "Select input file" msgstr "اختر الحقول في ملف الادخال" -#: ekos/analyze/analyze.cpp:507 +#: ekos/analyze/analyze.cpp:509 #, fuzzy, kde-format #| msgid "PNG Files (*.png)" msgid "All Files (*)" msgstr "ملفات PNG (*.png)" -#: ekos/analyze/analyze.cpp:527 +#: ekos/analyze/analyze.cpp:529 #, kde-format msgid "Set an alternate base directory for your captured images" msgstr "" -#: ekos/analyze/analyze.cpp:1169 +#: ekos/analyze/analyze.cpp:1171 #, fuzzy, kde-format #| msgid "Could not delete the file: %1" msgid "Could not find image file: %1" @@ -9812,8 +9857,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FocusLogging) #. i18n: ectx: property (text), widget (QLabel, label_10) #. i18n: ectx: property (text), widget (QCheckBox, focusStepCheck) -#: ekos/analyze/analyze.cpp:1873 ekos/auxiliary/opslogs.ui:377 -#: ekos/manager.cpp:2016 ekos/manager/focusmanager.ui:101 +#: ekos/analyze/analyze.cpp:1875 ekos/auxiliary/opslogs.ui:377 +#: ekos/manager.cpp:2022 ekos/manager/focusmanager.ui:101 #: ekos/scheduler/framingassistant.ui:1490 ekos/scheduler/scheduler.ui:445 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:430 #, kde-format @@ -9821,7 +9866,7 @@ msgstr "التركيز البؤري" #. i18n: ectx: property (text), widget (QCheckBox, alignStepCheck) -#: ekos/analyze/analyze.cpp:1874 ekos/manager.cpp:1990 +#: ekos/analyze/analyze.cpp:1876 ekos/manager.cpp:1996 #: ekos/scheduler/framingassistant.ui:1262 ekos/scheduler/scheduler.ui:398 #: fitsviewer/fitscommon.h:16 fitsviewer/fitsviewer.cpp:438 #, kde-format @@ -9832,16 +9877,16 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_GuideLogging) #. i18n: ectx: property (text), widget (QPushButton, guideB) #. i18n: ectx: property (text), widget (QCheckBox, guideStepCheck) -#: ekos/analyze/analyze.cpp:1875 ekos/analyze/analyze.ui:338 -#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:55 -#: ekos/guide/guide.ui:263 ekos/manager.cpp:2170 +#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:338 +#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:58 +#: ekos/guide/guide.ui:263 ekos/manager.cpp:2176 #: ekos/scheduler/framingassistant.ui:1226 ekos/scheduler/scheduler.ui:420 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:434 #, kde-format msgid "Guide" msgstr "التوجيه" -#: ekos/analyze/analyze.cpp:1876 +#: ekos/analyze/analyze.cpp:1878 #, kde-format msgid "Flip" msgstr "اعكس" @@ -9850,20 +9895,20 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDIMountLogging) #. i18n: ectx: property (text), widget (QCheckBox, kcfg_MountLogging) #. i18n: ectx: property (text), widget (QLabel, mountLabel) -#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:356 +#: ekos/analyze/analyze.cpp:1879 ekos/analyze/analyze.ui:356 #: ekos/auxiliary/opslogs.ui:77 ekos/auxiliary/opslogs.ui:420 -#: ekos/manager.cpp:2099 ekos/manager.ui:665 +#: ekos/manager.cpp:2105 ekos/manager.ui:665 #, kde-format msgid "Mount" msgstr "الحامل" #. i18n: ectx: property (text), widget (QLabel, jobLabel) -#: ekos/analyze/analyze.cpp:1878 ekos/capture/capturecountswidget.ui:473 +#: ekos/analyze/analyze.cpp:1880 ekos/capture/capturecountswidget.ui:473 #, kde-format msgid "Job" msgstr "وظيفة" -#: ekos/analyze/analyze.cpp:2136 +#: ekos/analyze/analyze.cpp:2138 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9871,7 +9916,7 @@ "will have their HFRs computed." msgstr "" -#: ekos/analyze/analyze.cpp:2152 +#: ekos/analyze/analyze.cpp:2154 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9879,105 +9924,105 @@ "newly captured images will have their stars detected." msgstr "" -#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/ledstatuswidget.cpp:78 -#: ekos/capture/sequencejob.cpp:21 ekos/ekos.h:21 ekos/ekos.h:72 +#: ekos/analyze/analyze.cpp:2855 ekos/auxiliary/ledstatuswidget.cpp:78 +#: ekos/capture/sequencejob.cpp:23 ekos/ekos.h:21 ekos/ekos.h:72 #: ekos/ekos.h:119 ekos/ekos.h:139 ekos/ekos.h:188 -#: ekos/scheduler/schedulerjob.cpp:619 +#: ekos/scheduler/schedulerjob.cpp:595 #, kde-format msgid "Aborted" msgstr "أُجهض" -#: ekos/analyze/analyze.cpp:2855 ekos/ekos.h:22 +#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:22 #, kde-format msgid "Connected" msgstr "متّصل" -#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:23 +#: ekos/analyze/analyze.cpp:2859 ekos/ekos.h:23 #, kde-format msgid "Disconnected" msgstr "قطع الاتصال" -#: ekos/analyze/analyze.cpp:2859 ekos/auxiliary/ledstatuswidget.cpp:68 -#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:651 +#: ekos/analyze/analyze.cpp:2861 ekos/auxiliary/ledstatuswidget.cpp:68 +#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:627 #, fuzzy, kde-format msgid "Capturing" msgstr "سجّل صورة" -#: ekos/analyze/analyze.cpp:2861 ekos/ekos.h:25 +#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:25 #, kde-format msgid "Looping" msgstr "" -#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:26 +#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:26 #, fuzzy, kde-format msgid "Subtracting" msgstr "العميل" -#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:27 +#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:27 #, fuzzy, kde-format msgid "Subframing" msgstr "الاسم:" -#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:28 +#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:28 #, fuzzy, kde-format msgid "Selecting star" msgstr "انتقِ a نجم" -#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:29 ekos/ekos.h:74 +#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:29 ekos/ekos.h:74 #, fuzzy, kde-format msgid "Calibrating" msgstr "العميل" -#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:30 +#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:30 #, fuzzy, kde-format msgid "Calibration error" msgstr "العميل" -#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:31 +#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:31 #, fuzzy, kde-format msgid "Calibrated" msgstr "العميل" #. i18n("Calibrating"); -#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:32 -#: ekos/scheduler/schedulerjob.cpp:649 +#: ekos/analyze/analyze.cpp:2877 ekos/ekos.h:32 +#: ekos/scheduler/schedulerjob.cpp:625 #, kde-format msgid "Guiding" msgstr "التوجيه" -#: ekos/analyze/analyze.cpp:2877 ekos/auxiliary/ledstatuswidget.cpp:33 +#: ekos/analyze/analyze.cpp:2879 ekos/auxiliary/ledstatuswidget.cpp:33 #: ekos/ekos.h:33 ekos/ekos.h:72 ekos/ekos.h:141 #, kde-format msgid "Suspended" msgstr "مُعلَّق" -#: ekos/analyze/analyze.cpp:2879 ekos/ekos.h:34 +#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:34 #, fuzzy, kde-format msgid "Reacquiring" msgstr "سجّل صورة" -#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:35 ekos/ekos.h:73 +#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:35 ekos/ekos.h:73 #, fuzzy, kde-format msgid "Dithering" msgstr "أخرى" #. i18n: ectx: property (windowTitle), widget (QDialog, ManualDither) -#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 +#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 #, fuzzy, kde-format msgid "Manual Dithering" msgstr "أخرى" -#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:37 +#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:37 #, fuzzy, kde-format msgid "Dithering error" msgstr "القبة الجدول" -#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:38 +#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:38 #, kde-format msgid "Dithering successful" msgstr "" -#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:39 +#: ekos/analyze/analyze.cpp:2891 ekos/ekos.h:39 #, fuzzy, kde-format msgid "Settling" msgstr "رسوب" @@ -10041,7 +10086,7 @@ #. i18n: ectx: property (text), widget (QLabel, statsLabel) #. i18n: ectx: property (windowTitle), widget (QDialog, solveInfo) #. i18n: ectx: property (windowTitle), widget (QDialog, statForm) -#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:123 +#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:129 #: fitsviewer/fitsviewer.cpp:173 fitsviewer/solveInfo.ui:14 #: fitsviewer/statform.ui:14 #, kde-format @@ -11099,8 +11144,8 @@ #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_21) #. i18n: ectx: property (text), widget (QLabel, label_34) -#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1607 -#: ekos/focus/focus.ui:3100 +#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1626 +#: ekos/focus/focus.ui:3119 #, kde-format msgid "Algorithm:" msgstr "الخوارزمية:" @@ -11281,7 +11326,7 @@ #. i18n: ectx: property (text), widget (QPushButton, resetFrameB) #. i18n: ectx: property (text), widget (QPushButton, resetB) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:779 +#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:798 #: ekos/guide/manualpulse.ui:140 ekos/mount/mount.ui:346 #, kde-format msgid "Reset" @@ -11330,7 +11375,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_7) #. i18n: ectx: label, entry (MaxDarkTemperatureDiff), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1628 +#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1652 #, kde-format msgid "" "Maximum acceptable difference between current and recorded dark frame " @@ -11361,14 +11406,14 @@ #. i18n: ectx: property (text), widget (QLabel, label_8) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:592 +#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:605 #, kde-format msgid "° C" msgstr "° مئوية" #. i18n: ectx: property (toolTip), widget (QLabel, label_6) #. i18n: ectx: label, entry (DarkLibraryDuration), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1638 +#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1662 #, kde-format msgid "" "Reuse dark frames from the dark library for this many days. If exceeded, a " @@ -11422,7 +11467,7 @@ msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #: ekos/auxiliary/filtermanager.cpp:112 -#: ekos/capture/capturecountswidget.cpp:154 +#: ekos/capture/capturecountswidget.cpp:156 #, kde-format msgid "Exposure" msgstr "التّعريض" @@ -11439,7 +11484,7 @@ msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" #. i18n: ectx: property (text), widget (QPushButton, startFocusB) -#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:285 +#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:286 #, fuzzy, kde-format msgid "Auto Focus" msgstr "شغّل الساعة" @@ -11532,7 +11577,7 @@ #. i18n: ectx: property (windowTitle), widget (QDialog, FilterSettings) #. i18n: ectx: property (toolTip), widget (QPushButton, filterManagerB) #: ekos/auxiliary/filtersettings.ui:20 ekos/capture/capture.ui:440 -#: ekos/focus/focus.ui:847 +#: ekos/focus/focus.ui:866 #, kde-format msgid "Filter Settings" msgstr "إعدادات المرشح" @@ -11600,7 +11645,7 @@ msgstr "ينتظر..." #: ekos/auxiliary/ledstatuswidget.cpp:46 -#: ekos/capture/capturemodulestate.cpp:336 +#: ekos/capture/capturemodulestate.cpp:330 #, fuzzy, kde-format msgid "Dithering..." msgstr "أخرى" @@ -11621,7 +11666,7 @@ msgid "Aligning..." msgstr "مركّز على:" -#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1395 +#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1426 #, fuzzy, kde-format msgid "Calibrating..." msgstr "العميل" @@ -11704,8 +11749,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_SchedulerLogging) #. i18n: ectx: attribute (title), widget (QWidget, schedulerTab) -#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:329 ekos/opsekos.ui:184 -#: ekos/scheduler/framingassistantui.cpp:665 +#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:333 ekos/opsekos.ui:184 +#: ekos/scheduler/framingassistantui.cpp:667 #, kde-format msgid "Scheduler" msgstr "المجدول" @@ -11742,7 +11787,7 @@ #: ekos/auxiliary/opslogs.ui:133 ekos/capture/capturecountswidget.ui:41 #: ekos/capture/capturepreviewwidget.ui:38 ekos/manager.ui:38 #: ekos/manager/focusmanager.ui:41 ekos/manager/guidemanager.ui:41 -#: kstarsactions.cpp:1141 kstarsinit.cpp:454 +#: kstarsactions.cpp:1150 kstarsinit.cpp:454 #, kde-format msgid "Ekos" msgstr "ايكوس" @@ -11784,7 +11829,7 @@ msgstr "سجّل نشاطات أجهزة INDI" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDILogging) -#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1137 +#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1146 #, fuzzy, kde-format msgid "INDI" msgstr "INDI" @@ -11798,7 +11843,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FITSLogging) #. i18n: ectx: property (text), item, widget (QComboBox, captureEncodingS) #: ekos/auxiliary/opslogs.ui:202 ekos/capture/capture.ui:194 -#: kstarsactions.cpp:1131 +#: kstarsactions.cpp:1140 #, fuzzy, kde-format msgid "FITS" msgstr "افتح" @@ -11880,7 +11925,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AlignmentLogging) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_6) -#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:415 +#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:428 #, kde-format msgid "Alignment" msgstr "ضبط الاستقامة" @@ -11897,7 +11942,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObservatoryLogging) #. i18n: ectx: property (windowTitle), widget (QWidget, Observatory) -#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2210 +#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2216 #: ekos/observatory/observatory.ui:14 #, kde-format msgid "Observatory" @@ -12134,18 +12179,22 @@ #: ekos/auxiliary/opticaltrains.ui:149 #, fuzzy, kde-format msgid "" -"

            Select the scope or lens used in the optical train.

            To add, edit, or delete optical elements, tap the Telescope & Lens button.

            " +"

            Select the scope or lens used in the optical train. " +"This is a required selection in all trains.

            To add, edit, or delete " +"optical elements, tap the Telescope & " +"Lens button.

            " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, scopeLabel) #: ekos/auxiliary/opticaltrains.ui:152 #, fuzzy, kde-format -#| msgctxt "Show the selected object in the telescope" -#| msgid "Scope" -msgid "Scope/Lense:" -msgstr "أدر التلسكوب نحو الجرم" +#| msgid "" +#| "

            Online Resources:" +#| "

            " +msgid "" +"

            Scope/Lens: *" +msgstr "التسلسل" #. i18n: ectx: property (toolTip), widget (QLabel, mountLabel) #: ekos/auxiliary/opticaltrains.ui:162 @@ -12166,17 +12215,20 @@ #: ekos/auxiliary/opticaltrains.ui:185 #, fuzzy, kde-format msgid "" -"

            Select the imaging camera for this optical train.

            " +"

            Select the imaging camera for this optical train. " +"This is a required selection in all trains.

            " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, cameraLabel) -#. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/auxiliary/opticaltrains.ui:188 ekos/capture/capture.ui:1478 -#: ekos/scheduler/framingassistant.ui:139 -#, kde-format -msgid "Camera:" -msgstr "الكاميرا:" +#: ekos/auxiliary/opticaltrains.ui:188 +#, fuzzy, kde-format +#| msgid "" +#| "

            Online Resources:" +#| "

            " +msgid "" +"

            Camera: *

            " +msgstr "الهدف" #. i18n: ectx: property (toolTip), widget (QLabel, dustCapLlabel) #: ekos/auxiliary/opticaltrains.ui:208 @@ -12270,7 +12322,7 @@ #. i18n: ectx: property (text), widget (QLabel, focusLabel) #. i18n: ectx: property (text), widget (QLabel, label_33) #. i18n: ectx: property (text), widget (QLabel, label_10) -#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:298 +#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:434 #: ekos/profileeditor.ui:651 #, kde-format msgid "Focuser:" @@ -12869,7 +12921,7 @@ #. i18n: ectx: property (text), item, widget (QComboBox, convFilter) #. i18n: ectx: property (text), item, widget (QComboBox, focusStarPSF) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1871 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1890 #, kde-format msgid "Gaussian" msgstr "ضبابي" @@ -13087,7 +13139,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_9) #: ekos/auxiliary/stellarsolverprofileeditor.ui:726 #: ekos/auxiliary/stellarsolverprofileeditor.ui:798 -#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:874 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:887 #, no-c-format, kde-format msgid "%" msgstr "%" @@ -13232,10 +13284,13 @@ msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, multiAlgo) +#. i18n: ectx: property (currentText), widget (QComboBox, abInsSelection) +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) #. i18n: ectx: property (text), widget (QPushButton, NoneButton) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 indi/drivermanager.cpp:1312 -#: indi/indidriver.cpp:735 kstarsactions.cpp:1817 kstarsinit.cpp:788 -#: kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 +#: ekos/focus/aberrationinspector.ui:336 ekos/focus/aberrationinspector.ui:340 +#: indi/drivermanager.cpp:1329 indi/indidriver.cpp:735 kstarsactions.cpp:1826 +#: kstarsinit.cpp:788 kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 #: tools/eyepiecefield.cpp:102 tools/obslistwizard.ui:183 #, kde-format, kde-kuit-format msgid "None" @@ -13386,101 +13441,73 @@ msgstr "البرج الاسم خيارات" #. i18n: ectx: property (toolTip), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:22 -#, kde-format -msgid "Specify the source the flat field evenly illuminated light source" -msgstr "" - -#. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:25 +#: ekos/capture/calibrationoptions.ui:37 #, fuzzy, kde-format -msgid "Flat Source" -msgstr "تحديث" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, manualSourceC) -#: ekos/capture/calibrationoptions.ui:31 -#, kde-format -msgid "Light source triggered by the user manually" -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, manualSourceC) -#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:34 ekos/capture/calibrationoptions.ui:161 -#, kde-format -msgid "Manual" -msgstr "يدويّ" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:47 -#, kde-format msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, close the dust cap and turn on the light source." -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:50 -#, kde-format -msgid "Dust Cover with Built-in Flat Light" -msgstr "" +"

            Select which actions to perform before a Bias/Dark/" +"Flat frame is captured.

            " +msgstr "حدّد بوصة دَخْل ملفّ." -#. i18n: ectx: property (toolTip), widget (QRadioButton, darkDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:60 -#, kde-format -msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, open the dust cap and turn on the light source." -msgstr "" +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: ekos/capture/calibrationoptions.ui:40 +#, fuzzy, kde-format +msgid "Calibration Pre-Actions" +msgstr "البرج الاسم خيارات" -#. i18n: ectx: property (text), widget (QRadioButton, darkDeviceSourceC) +#. i18n: ectx: property (toolTip), widget (QCheckBox, gotoWallC) #: ekos/capture/calibrationoptions.ui:63 #, kde-format -msgid "Dust Cover with External Flat Light" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:75 -#, kde-format msgid "" "Slew mount to the specified Azimuth/Altitude coordinates before taking flat " "field images" msgstr "" -#. i18n: ectx: property (text), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:78 -#, kde-format -msgid "Wall" +#. i18n: ectx: property (text), widget (QCheckBox, gotoWallC) +#: ekos/capture/calibrationoptions.ui:66 +#, fuzzy, kde-format +#| msgid "Wall" +msgid "Goto Wall" msgstr "الحائط" -#. i18n: ectx: property (toolTip), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:121 +#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) +#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) +#: ekos/capture/calibrationoptions.ui:103 ekos/scheduler/scheduler.ui:1837 #, fuzzy, kde-format -#| msgid "Use animated slewing" -msgid "Use Dawn and Dusk light" -msgstr "استخدم تحريك حيوي" +msgid "Park Mount" +msgstr "العدد:" -#. i18n: ectx: property (text), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:124 -#, kde-format -msgid "Dawn/Dusk" -msgstr "" +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) +#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) +#: ekos/capture/calibrationoptions.ui:110 ekos/observatory/observatory.ui:944 +#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 +#, fuzzy, kde-format +msgid "Park Dome" +msgstr "احفظ نص برمجي" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/capture/calibrationoptions.ui:150 +#: ekos/capture/calibrationoptions.ui:133 #, fuzzy, kde-format msgid "Flat Duration" msgstr "المدة:" #. i18n: ectx: property (toolTip), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:158 +#: ekos/capture/calibrationoptions.ui:156 #, fuzzy, kde-format msgid "Use the frame exposure value" msgstr "دليل FITS الافتراضي:" +#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) +#: ekos/capture/calibrationoptions.ui:159 +#, kde-format +msgid "Manual" +msgstr "يدويّ" + #. i18n: ectx: property (toolTip), widget (QRadioButton, ADUC) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUValue) -#: ekos/capture/calibrationoptions.ui:174 -#: ekos/capture/calibrationoptions.ui:187 +#: ekos/capture/calibrationoptions.ui:172 +#: ekos/capture/calibrationoptions.ui:185 #, kde-format msgid "" "Calculate optimal exposure time given the required ADU. If a controllable " @@ -13488,7 +13515,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, ADUC) -#: ekos/capture/calibrationoptions.ui:177 +#: ekos/capture/calibrationoptions.ui:175 #, fuzzy, kde-format #| msgid "AU" msgid "ADU" @@ -13496,8 +13523,8 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_3) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUTolerance) -#: ekos/capture/calibrationoptions.ui:200 -#: ekos/capture/calibrationoptions.ui:210 +#: ekos/capture/calibrationoptions.ui:198 +#: ekos/capture/calibrationoptions.ui:208 #, kde-format msgid "" "

            Accept ADU values that fall within this range around " @@ -13509,343 +13536,298 @@ #. i18n: ectx: property (text), widget (QLabel, label_3) #. i18n: ectx: property (text), widget (QLabel, focusToleranceLabel) #. i18n: ectx: property (text), widget (QLabel, focusCFZToleranceLabel) -#: ekos/capture/calibrationoptions.ui:203 ekos/focus/focus.ui:2068 -#: ekos/focus/focus.ui:2674 +#: ekos/capture/calibrationoptions.ui:201 ekos/focus/focus.ui:2087 +#: ekos/focus/focus.ui:2693 #, kde-format msgid "Tolerance:" msgstr "دائرة التأثير:" -#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) -#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) -#: ekos/capture/calibrationoptions.ui:246 ekos/scheduler/scheduler.ui:1837 -#, fuzzy, kde-format -msgid "Park Mount" -msgstr "العدد:" - -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) -#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) -#: ekos/capture/calibrationoptions.ui:253 ekos/observatory/observatory.ui:944 -#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 -#, fuzzy, kde-format -msgid "Park Dome" -msgstr "احفظ نص برمجي" - -#: ekos/capture/capture.cpp:248 ekos/capture/capture.cpp:2935 +#: ekos/capture/capture.cpp:262 ekos/capture/capture.cpp:2311 #, fuzzy, kde-format #| msgid "Capture Image Sequence..." msgid "Add job to sequence queue" msgstr "احفظ مجموعة صور..." -#: ekos/capture/capture.cpp:249 ekos/capture/capture.cpp:2936 +#: ekos/capture/capture.cpp:263 ekos/capture/capture.cpp:2312 #, fuzzy, kde-format #| msgid "Capture Image Sequence..." msgid "Remove job from sequence queue" msgstr "احفظ مجموعة صور..." -#: ekos/capture/capture.cpp:500 +#: ekos/capture/capture.cpp:510 #, kde-format msgid "Downloading..." msgstr "ينزّل..." -#: ekos/capture/capture.cpp:675 +#: ekos/capture/capture.cpp:689 #, kde-format msgid "" "Warning: in-sequence focusing is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:677 +#: ekos/capture/capture.cpp:691 #, kde-format msgid "" "Warning: temperature delta check is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:1336 +#: ekos/capture/capture.cpp:1367 #, fuzzy, kde-format msgid "Framing..." msgstr "هيكل" -#: ekos/capture/capture.cpp:1347 +#: ekos/capture/capture.cpp:1378 #, kde-format msgid "Captured image received" msgstr "استُقبلت صورة ملتقطة" #. i18n: ectx: property (text), widget (QLabel, frameInfoLabel) -#: ekos/capture/capture.cpp:1365 ekos/capture/capture.ui:2245 +#: ekos/capture/capture.cpp:1396 ekos/capture/capture.ui:2245 #, fuzzy, kde-format msgid "Expose (-/-):" msgstr "إكسبوز" -#: ekos/capture/capture.cpp:1429 +#: ekos/capture/capture.cpp:1460 #, fuzzy, kde-format msgid "Capturing %1-second %2 image..." msgstr "جاري التّحميل." -#: ekos/capture/capture.cpp:1512 -#, kde-format -msgid "You must set remote directory for Local & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1518 -#, kde-format -msgid "You must set local directory for Client & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1653 ekos/capture/capture.cpp:1656 -#, fuzzy, kde-format -msgid "Dark Flat" -msgstr "Barnesville" - -#: ekos/capture/capture.cpp:1737 +#: ekos/capture/capture.cpp:1638 #, kde-format msgid "Job #%1 changes applied." msgstr "" -#: ekos/capture/capture.cpp:1941 +#: ekos/capture/capture.cpp:1814 #, fuzzy, kde-format msgid "Setting temperature to %1 °C..." msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/capture/capture.cpp:1942 +#: ekos/capture/capture.cpp:1815 #, fuzzy, kde-format msgid "Set Temp to %1 °C..." msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/capture/capture.cpp:1946 +#: ekos/capture/capture.cpp:1819 #, fuzzy, kde-format msgid "Waiting for guide drift below %1\"..." msgstr "جاري التّحميل" -#: ekos/capture/capture.cpp:1948 +#: ekos/capture/capture.cpp:1821 #, kde-format msgid "Wait for Guider < %1\"..." msgstr "" -#: ekos/capture/capture.cpp:1953 +#: ekos/capture/capture.cpp:1826 #, fuzzy, kde-format msgid "Setting camera to %1 degrees E of N..." msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/capture/capture.cpp:1954 +#: ekos/capture/capture.cpp:1827 #, fuzzy, kde-format msgid "Set Camera to %1 deg..." msgstr "ضبط الموقع." -#: ekos/capture/capture.cpp:1997 ekos/capture/capture.cpp:1998 +#: ekos/capture/capture.cpp:1870 ekos/capture/capture.cpp:1871 #, fuzzy, kde-format msgid "Focus complete." msgstr "مكتمل" -#: ekos/capture/capture.cpp:2002 +#: ekos/capture/capture.cpp:1875 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Autofocus failed." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" -#: ekos/capture/capture.cpp:2024 +#: ekos/capture/capture.cpp:1897 #, kde-format msgid "Paused..." msgstr "أوقِفَ مؤقتا…" -#: ekos/capture/capture.cpp:2029 +#: ekos/capture/capture.cpp:1902 #, fuzzy, kde-format msgid "Meridian Flip..." msgstr "تلقائي عرض من التقاط" -#: ekos/capture/capture.cpp:2030 +#: ekos/capture/capture.cpp:1903 #, kde-format msgid "Meridian flip started" msgstr "بدأ تدوير الحامل إلى الجهة الأخرى من خطّ الزّوال" -#: ekos/capture/capture.cpp:2034 +#: ekos/capture/capture.cpp:1907 #, fuzzy, kde-format #| msgid "completed" msgid "Flip complete." msgstr "مكتمل" -#: ekos/capture/capture.cpp:2059 ekos/scheduler/framingassistant.cpp:221 +#: ekos/capture/capture.cpp:1932 ekos/scheduler/framingassistant.cpp:221 #, fuzzy, kde-format msgctxt "@title:window" msgid "FITS Save Directory" msgstr "افتراضي دليل" -#: ekos/capture/capture.cpp:2069 +#: ekos/capture/capture.cpp:1942 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Sequence Queue" msgstr "الملاحظة قائمة" -#: ekos/capture/capture.cpp:2180 -#, kde-format -msgid "" -"Meridian flip configuration has been shifted to the mount module. Please " -"configure the meridian flip there." -msgstr "" - -#: ekos/capture/capture.cpp:2269 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Warning: Filter %1 not found in filter wheel." -msgstr "%1 على الخط" - -#: ekos/capture/capture.cpp:2478 +#: ekos/capture/capture.cpp:2007 #, fuzzy, kde-format #| msgid "Capture Image Sequence..." msgctxt "@title:window" msgid "Save Ekos Sequence Queue" msgstr "احفظ مجموعة صور..." -#: ekos/capture/capture.cpp:2499 +#: ekos/capture/capture.cpp:2028 #, kde-format msgid "Failed to save sequence queue" msgstr "" -#: ekos/capture/capture.cpp:2531 -#, kde-format -msgid "Could not open file" -msgstr "تعذّر فتح الملفّ" - -#: ekos/capture/capture.cpp:2551 -#, kde-format -msgid "" -"Warning: HFR-based autofocus is set but option \"Save Sequence HFR Value to " -"File\" is not enabled. Current HFR value will not be written to sequence " -"file." -msgstr "" - -#: ekos/capture/capture.cpp:2686 -#, fuzzy, kde-format -#| msgid "FITS file saved to %1" -msgid "Sequence queue saved to %1" -msgstr "تم حفظ ملف FITS الى %1" - -#: ekos/capture/capture.cpp:2713 +#: ekos/capture/capture.cpp:2071 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 link?" msgid "Are you sure you want to reset status of all jobs?" msgstr "تأكيد حذف الرابط %1 ؟" -#: ekos/capture/capture.cpp:2713 ekos/capture/captureprocess.cpp:2339 +#: ekos/capture/capture.cpp:2071 ekos/capture/captureprocess.cpp:2638 #, fuzzy, kde-format msgid "Reset job status" msgstr "إعادة تعيين الموضع" -#: ekos/capture/capture.cpp:2914 +#: ekos/capture/capture.cpp:2290 #, fuzzy, kde-format #| msgid "Edit Link..." msgid "Editing job #%1..." msgstr "حرّر رابط..." -#: ekos/capture/capture.cpp:2917 ekos/scheduler/scheduler.cpp:1619 +#: ekos/capture/capture.cpp:2293 ekos/scheduler/scheduler.cpp:1414 #, kde-format msgid "Apply job changes." msgstr "" -#: ekos/capture/capture.cpp:2918 +#: ekos/capture/capture.cpp:2294 #, fuzzy, kde-format msgid "Cancel job changes." msgstr "حفظ التغييرات إلى FITS?" -#: ekos/capture/capture.cpp:2930 +#: ekos/capture/capture.cpp:2306 #, fuzzy, kde-format #| msgid "Edit Link..." msgid "Editing job canceled." msgstr "حرّر رابط..." -#: ekos/capture/capture.cpp:3083 +#: ekos/capture/capture.cpp:2445 #, fuzzy, kde-format msgid "Wall coordinates are invalid." msgstr "ظاهر:" -#: ekos/capture/capture.cpp:3172 +#: ekos/capture/capture.cpp:2529 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Current Observer" msgstr "خادم" -#: ekos/capture/capture.cpp:3174 +#: ekos/capture/capture.cpp:2531 #, fuzzy, kde-format msgid "Current Observer:" msgstr "خادم" #. i18n: ectx: property (windowTitle), widget (QWidget, ObserverAdd) -#: ekos/capture/capture.cpp:3185 oal/execute.cpp:38 oal/observeradd.ui:26 +#: ekos/capture/capture.cpp:2542 oal/execute.cpp:38 oal/observeradd.ui:26 #, kde-format msgid "Manage Observers" msgstr "إدارة الراصدين" -#: ekos/capture/capture.cpp:3250 +#: ekos/capture/capture.cpp:2607 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Filter set to %1." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/capture/capture.cpp:3572 +#: ekos/capture/capture.cpp:2929 #, fuzzy, kde-format msgid "Reset %1 configuration to default?" msgstr "حدّد بوصة دَخْل ملفّ." -#: ekos/capture/capture.cpp:3574 +#: ekos/capture/capture.cpp:2931 #, kde-format msgid "Confirmation" msgstr "تأكيد" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:2969 ekos/capture/capture.cpp:3044 +#, fuzzy, kde-format +msgid "Dark Flat" +msgstr "Barnesville" + +#: ekos/capture/capture.cpp:3021 +#, kde-format +msgid "You must set remote directory for Local & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3027 +#, kde-format +msgid "You must set local directory for Client & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is on" msgstr "" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is off" msgstr "" -#: ekos/capture/capture.cpp:3809 +#: ekos/capture/capture.cpp:3172 #, kde-format -msgctxt "Temperature ramp celcius per minute" -msgid "Ramp (C/min):" +msgctxt "Maximum temperature variation over time when regulating." +msgid "Ramp (°C/min):" msgstr "" -#: ekos/capture/capture.cpp:3815 +#: ekos/capture/capture.cpp:3178 #, kde-format msgid "" -"Maximum temperature change per minute when cooling or warming the camera. " -"Set zero to disable." +"

            Maximum temperature change per minute when cooling or warming " +"the camera. Set zero to disable.

            This setting is read from and stored in " +"the INDI camera driver configuration." msgstr "" -#. i18n: ectx: property (text), widget (QLabel, focusThresholdLabel) -#: ekos/capture/capture.cpp:3817 ekos/focus/focus.ui:1895 -#, kde-format -msgid "Threshold:" -msgstr "العتبة:" +#: ekos/capture/capture.cpp:3183 +#, fuzzy, kde-format +msgctxt "Temperature threshold above which regulation triggers." +msgid "Threshold (°C):" +msgstr "Freehold" -#: ekos/capture/capture.cpp:3823 +#: ekos/capture/capture.cpp:3189 #, kde-format -msgid "Maximum difference between camera and target temperatures" +msgid "" +"

            Maximum difference between camera and target temperatures " +"triggering regulation.

            This setting is read from and stored in the INDI " +"camera driver configuration." msgstr "" -#: ekos/capture/capture.cpp:3833 +#: ekos/capture/capture.cpp:3202 #, fuzzy, kde-format msgctxt "@title:window" msgid "Set Temperature Regulation" msgstr "ضبط هدف رقاقة [رقاقات]." -#: ekos/capture/capture.cpp:3851 +#: ekos/capture/capture.cpp:3220 #, fuzzy, kde-format #| msgid "Frequency:" msgid "Stop Sequence" msgstr "التّردد:" -#: ekos/capture/capture.cpp:3857 +#: ekos/capture/capture.cpp:3226 #, fuzzy, kde-format #| msgid "Frequency:" msgid "Resume Sequence" msgstr "التّردد:" -#: ekos/capture/capture.cpp:3882 +#: ekos/capture/capture.cpp:3251 #, kde-format msgid "One dark flats job was created." msgid_plural "%1 dark flats jobs were created." @@ -13858,7 +13840,7 @@ #. i18n: ectx: property (title), widget (QGroupBox, CCDFWGroup) #. i18n: ectx: property (title), widget (QGroupBox, ccdGroup) -#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:472 +#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:491 #, fuzzy, kde-format msgid "Camera && Filter Wheel" msgstr "تصفية عجل" @@ -14199,44 +14181,61 @@ "\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-" "block-indent:0; text-indent:0px;\">Placeholder %e or %exposure: The " -"exposure duration in seconds.

          • Placeholder %F or " -"%Filter: The active filter name.
            • Placeholder %E or %exp: The exposure duration in seconds as plain " +"number, without any unit as suffix.
          • Placeholder %F " +"or %Filter: The active filter name." +"
          • Placeholder %t or %target: The Target name.
          • Placeholder %C or %temperature: The camera temperature of capturing." -"
            • Placeholder %B or " +"%bin: The binning configured for " +"capturing.
            • Placeholder %G or %gain: The gain configured for capturing.
            • Placeholder %G or %gain: The gain configured for capturing.
            • %O or %offset: The offset configured for capturing.
              • Placeholder %I or %iso: The ISO value (DSLRs only).
            • Placeholder %O " -"or %offset: The offset configured " -"for capturing.
            • Placeholder %P " +"or %pierside: The current mount's " +"pier side.
            • Placeholder %P or %pierside: The current mount's pier side.
            • Placeholder %s* or " -"%sequence: The image sequence identifier where * is the number of " -"digits used (1-9). This tag is mandatory " -"and must be the last element in the format.

            Arbitrary " -"text may also be included within the Format string, except the % and \\ characters. The / path character " -"can be used to define arbitrary directories.

            Notes:

            • Tags are " -"case sensitive in both their short and long forms.
            • Only use the %Datetime tag in the filename " -"portion of the format, not in the path definition.
            " +"\">Placeholder %s* or %sequence: The image sequence identifier where " +"* is the number of digits used (1-9). This " +"tag is mandatory and must be the last element in the format.
          • Arbitrary text may also be included within the Format string, except the % and \\ characters. The / " +"path character can be used to define arbitrary directories.

            Notes:

            • Tags are case sensitive in both their short and long forms.
            • Only use the %Datetime tag " +"in the filename portion of the format, not in the path definition.
            • " msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, remoteLabel) @@ -14277,7 +14276,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, textLabel1_2_5) #. i18n: ectx: property (toolTip), widget (QLabel, FilterPosLabel) #: ekos/capture/capture.ui:1185 ekos/capture/limits.ui:60 -#: ekos/capture/limits.ui:201 ekos/focus/focus.ui:552 +#: ekos/capture/limits.ui:201 ekos/focus/focus.ui:571 #, kde-format msgid "Number of images to capture" msgstr "عدد الصور المراد التقاطها" @@ -14363,6 +14362,12 @@ msgid "Cooler:" msgstr "المبرد:" +#. i18n: ectx: property (text), widget (QLabel, label_8) +#: ekos/capture/capture.ui:1478 ekos/scheduler/framingassistant.ui:139 +#, kde-format +msgid "Camera:" +msgstr "الكاميرا:" + #. i18n: ectx: property (title), widget (QGroupBox, sequenceBox) #: ekos/capture/capture.ui:1515 #, kde-format @@ -14448,7 +14453,7 @@ msgstr "بداية من:" #. i18n: ectx: property (toolTip), widget (QPushButton, liveVideoB) -#: ekos/capture/capture.ui:2009 ekos/focus/focus.ui:745 +#: ekos/capture/capture.ui:2009 ekos/focus/focus.ui:764 #, fuzzy, kde-format msgid "Live Video" msgstr "منفذ الفيديو:" @@ -14580,14 +14585,14 @@ #. i18n: ectx: property (text), widget (QLabel, startGuiderDriftLabel) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZSeeing) #: ekos/capture/capture.ui:2380 ekos/capture/limits.ui:66 -#: ekos/capture/limits.ui:102 ekos/focus/focus.ui:3040 +#: ekos/capture/limits.ui:102 ekos/focus/focus.ui:3059 #, kde-format msgid "\"" msgstr "" #. i18n: ectx: property (text), widget (QLabel, gr_sequenceLabel) #. i18n: ectx: property (text), widget (QLabel, sequenceLabel) -#: ekos/capture/capturecountswidget.cpp:99 +#: ekos/capture/capturecountswidget.cpp:101 #: ekos/capture/capturecountswidget.ui:124 #: ekos/capture/capturecountswidget.ui:397 #, kde-format @@ -14595,7 +14600,7 @@ msgstr "التسلسل" #. i18n: ectx: property (text), widget (QLabel, gr_overallLabel) -#: ekos/capture/capturecountswidget.cpp:102 +#: ekos/capture/capturecountswidget.cpp:104 #: ekos/capture/capturecountswidget.ui:140 #, kde-format msgid "Overall" @@ -14700,194 +14705,194 @@ msgid "Switch display to the graphical mode of capture counts display." msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:565 +#: ekos/capture/capturedeviceadaptor.cpp:648 #, kde-format msgid "Remove cover from the telescope in order to continue." msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:566 +#: ekos/capture/capturedeviceadaptor.cpp:649 #, fuzzy, kde-format msgid "Telescope Covered" msgstr "انتقِ إدخال الأسس" -#: ekos/capture/capturedeviceadaptor.cpp:698 +#: ekos/capture/capturedeviceadaptor.cpp:781 #, kde-format msgid "Does %1 have a shutter?" msgstr "" -#: ekos/capture/capturedeviceadaptor.cpp:699 -#: ekos/capture/sequencejobstate.cpp:414 +#: ekos/capture/capturedeviceadaptor.cpp:782 +#: ekos/capture/sequencejobstate.cpp:403 #, fuzzy, kde-format msgid "Dark Exposure" msgstr "التّعرّض:" -#: ekos/capture/capturemodulestate.cpp:130 +#: ekos/capture/capturemodulestate.cpp:132 #, kde-format msgid "" "Warning: Guide deviation is selected but autoguide process was not started." msgstr "" -#: ekos/capture/capturemodulestate.cpp:195 +#: ekos/capture/capturemodulestate.cpp:198 #, fuzzy, kde-format msgid "Dithering succeeded." msgstr "أخرى" #. i18np since guidingRate is DOUBLE value (e.g. 1.36) so we always use plural with that. -#: ekos/capture/capturemodulestate.cpp:202 +#: ekos/capture/capturemodulestate.cpp:205 #, fuzzy, kde-format msgid "Dither complete. Resuming in %1 seconds..." msgstr "جاري التّحميل" -#: ekos/capture/capturemodulestate.cpp:210 +#: ekos/capture/capturemodulestate.cpp:213 #, fuzzy, kde-format msgid "Dither complete." msgstr "مكتمل" #. i18np since guidingRate is DOUBLE value (e.g. 1.36) so we always use plural with that. -#: ekos/capture/capturemodulestate.cpp:224 +#: ekos/capture/capturemodulestate.cpp:227 #, fuzzy, kde-format msgid "Warning: Dithering failed. Resuming in %1 seconds..." msgstr "جاري التّحميل" -#: ekos/capture/capturemodulestate.cpp:233 +#: ekos/capture/capturemodulestate.cpp:236 #, fuzzy, kde-format msgid "Warning: Dithering failed." msgstr "أخرى" -#: ekos/capture/capturemodulestate.cpp:431 +#: ekos/capture/capturemodulestate.cpp:425 #, kde-format msgid "Meridian flip is successfully completed" msgstr "" -#: ekos/capture/capturemodulestate.cpp:527 +#: ekos/capture/capturemodulestate.cpp:521 #, kde-format msgid "Performing post flip re-calibration and guiding..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:540 +#: ekos/capture/capturemodulestate.cpp:534 #, kde-format msgid "Post meridian flip calibration error. Restarting..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:560 +#: ekos/capture/capturemodulestate.cpp:554 #, fuzzy, kde-format msgid "Autoguiding stopped. Waiting for autofocus to finish..." msgstr "جاري التّحميل" -#: ekos/capture/capturemodulestate.cpp:569 +#: ekos/capture/capturemodulestate.cpp:563 #, fuzzy, kde-format msgid "Autoguiding stopped. Aborting..." msgstr "جاري التّحميل" -#: ekos/capture/capturemodulestate.cpp:576 +#: ekos/capture/capturemodulestate.cpp:570 #, kde-format msgid "Post meridian flip calibration error. Aborting..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:596 +#: ekos/capture/capturemodulestate.cpp:592 #, fuzzy, kde-format msgid "Adaptive focus complete." msgstr "مكتمل" -#: ekos/capture/capturemodulestate.cpp:620 +#: ekos/capture/capturemodulestate.cpp:616 #, kde-format msgid "Autofocus failed. Aborting exposure..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:767 +#: ekos/capture/capturemodulestate.cpp:763 #, kde-format msgid "Performing post flip re-alignment..." msgstr "" -#: ekos/capture/capturemodulestate.cpp:785 +#: ekos/capture/capturemodulestate.cpp:781 #, fuzzy, kde-format msgid "Guide module timed out." msgstr "جاري التّحميل" -#: ekos/capture/capturemodulestate.cpp:817 +#: ekos/capture/capturemodulestate.cpp:813 #, kde-format msgid "Initial guiding deviation %1 below limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:826 +#: ekos/capture/capturemodulestate.cpp:822 #, kde-format msgid "Initial guiding deviation %1 exceeded limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:848 +#: ekos/capture/capturemodulestate.cpp:844 #, kde-format msgid "Post meridian flip calibration completed successfully." msgstr "" -#: ekos/capture/capturemodulestate.cpp:862 +#: ekos/capture/capturemodulestate.cpp:858 #, kde-format msgid "Guiding deviation at capture startup %1 exceeded limit %2 arcsecs." msgstr "" -#: ekos/capture/capturemodulestate.cpp:876 +#: ekos/capture/capturemodulestate.cpp:872 #, kde-format msgid "Guiding deviation at capture startup %1 below limit value of %2 arcsecs" msgstr "" -#: ekos/capture/capturemodulestate.cpp:903 +#: ekos/capture/capturemodulestate.cpp:899 #, kde-format msgid "" "Guiding deviation %1 exceeded limit value of %2 arcsecs for %4 consecutive " "samples, suspending exposure and waiting for guider up to %3 seconds." msgstr "" -#: ekos/capture/capturemodulestate.cpp:950 +#: ekos/capture/capturemodulestate.cpp:946 #, kde-format msgid "" "Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming " "exposure." msgstr "" -#: ekos/capture/capturemodulestate.cpp:954 +#: ekos/capture/capturemodulestate.cpp:950 #, kde-format msgid "" "Guiding deviation %1 is now lower than limit value of %2 arcsecs, resuming " "exposure in %3 seconds." msgstr "" -#: ekos/capture/capturemodulestate.cpp:969 +#: ekos/capture/capturemodulestate.cpp:965 #, kde-format msgid "Guiding deviation %1 is still higher than limit value of %2 arcsecs." msgstr "" -#: ekos/capture/capturemodulestate.cpp:1350 +#: ekos/capture/capturemodulestate.cpp:1340 #, kde-format msgid "Post flip re-alignment completed successfully." msgstr "" -#: ekos/capture/capturemodulestate.cpp:1369 +#: ekos/capture/capturemodulestate.cpp:1359 #, fuzzy, kde-format msgid "Post-flip alignment failed." msgstr "حدّد بوصة دَخْل ملفّ." -#: ekos/capture/capturemodulestate.cpp:1374 +#: ekos/capture/capturemodulestate.cpp:1364 #, fuzzy, kde-format msgid "Post-flip alignment failed. Retrying..." msgstr "حدّد بوصة دَخْل ملفّ." -#: ekos/capture/capturepreviewwidget.cpp:138 +#: ekos/capture/capturepreviewwidget.cpp:142 #, kde-format msgid "Delete directly, do not move to trash." msgstr "" -#: ekos/capture/capturepreviewwidget.cpp:195 +#: ekos/capture/capturepreviewwidget.cpp:199 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Do you really want to delete %1 from the file system?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/capture/capturepreviewwidget.cpp:197 +#: ekos/capture/capturepreviewwidget.cpp:201 #, kde-format msgid "Delete %1" msgstr "احذف %1" #. i18n: ectx: property (text), widget (QPushButton, delButton) -#: ekos/capture/capturepreviewwidget.cpp:197 +#: ekos/capture/capturepreviewwidget.cpp:201 #: kstarslite/qml/dialogs/menus/DetailsLinkMenu.qml:54 #: kstarslite/qml/dialogs/menus/LocationsGeoMenu.qml:82 #: tools/flagmanager.ui:223 @@ -14901,241 +14906,267 @@ msgid "Target: " msgstr "الهدف:" -#: ekos/capture/captureprocess.cpp:171 ekos/capture/captureprocess.cpp:564 +#: ekos/capture/captureprocess.cpp:192 ekos/capture/captureprocess.cpp:585 #, fuzzy, kde-format msgid "Image Transfer" msgstr "صورة تنسيق" -#: ekos/capture/captureprocess.cpp:190 +#: ekos/capture/captureprocess.cpp:211 #, fuzzy, kde-format msgid "Sequence resumed." msgstr "جاري التّحميل" -#: ekos/capture/captureprocess.cpp:226 +#: ekos/capture/captureprocess.cpp:247 #, kde-format msgid "No pending jobs found. Please add a job to the sequence queue." msgstr "" -#: ekos/capture/captureprocess.cpp:240 +#: ekos/capture/captureprocess.cpp:261 #, fuzzy, kde-format #| msgid "Add to Ekos Scheduler" msgid "No new job created." msgstr "أضف إلى مجدول إيكوس" -#: ekos/capture/captureprocess.cpp:263 ekos/capture/captureprocess.cpp:798 +#: ekos/capture/captureprocess.cpp:284 ekos/capture/captureprocess.cpp:823 #, kde-format msgid "Cannot capture while focus module is busy." msgstr "" -#: ekos/capture/captureprocess.cpp:270 +#: ekos/capture/captureprocess.cpp:291 #, fuzzy, kde-format msgid "Starting framing..." msgstr "فارمنغتون" -#: ekos/capture/captureprocess.cpp:300 +#: ekos/capture/captureprocess.cpp:321 #, fuzzy, kde-format msgid "CCD capture suspended" msgstr "بقايا سوبر نوفا" -#: ekos/capture/captureprocess.cpp:305 +#: ekos/capture/captureprocess.cpp:326 #, fuzzy, kde-format msgid "CCD capture complete" msgstr "سجّل صورة" -#: ekos/capture/captureprocess.cpp:310 +#: ekos/capture/captureprocess.cpp:331 #, fuzzy, kde-format msgid "CCD capture aborted" msgstr "سجّل صورة" -#: ekos/capture/captureprocess.cpp:315 +#: ekos/capture/captureprocess.cpp:336 #, fuzzy, kde-format msgid "CCD capture stopped" msgstr "سجّل صورة" -#: ekos/capture/captureprocess.cpp:389 +#: ekos/capture/captureprocess.cpp:410 #, kde-format msgid "Pausing only possible while frame capture is running." msgstr "" -#: ekos/capture/captureprocess.cpp:396 +#: ekos/capture/captureprocess.cpp:417 #, kde-format msgid "Sequence shall be paused after current exposure is complete." msgstr "" -#: ekos/capture/captureprocess.cpp:427 +#: ekos/capture/captureprocess.cpp:448 #, kde-format msgid "No view available for previews. Enable FITS viewer?" msgstr "" -#: ekos/capture/captureprocess.cpp:428 +#: ekos/capture/captureprocess.cpp:449 #, fuzzy, kde-format msgid "Display preview" msgstr "Point Hope" -#: ekos/capture/captureprocess.cpp:512 +#: ekos/capture/captureprocess.cpp:533 #, kde-format msgid "" "Job requires %1-second %2 images, has already %3/%4 captures and does not " "need to run." msgstr "" -#: ekos/capture/captureprocess.cpp:525 +#: ekos/capture/captureprocess.cpp:546 #, kde-format msgid "" "Job requires %1-second %2 images, has %3/%4 frames captured and will be " "processed." msgstr "" -#: ekos/capture/captureprocess.cpp:744 +#: ekos/capture/captureprocess.cpp:769 #, fuzzy, kde-format msgid "Autoguiding resumed." msgstr "جاري التّحميل" -#: ekos/capture/captureprocess.cpp:788 +#: ekos/capture/captureprocess.cpp:813 #, fuzzy, kde-format msgid "Failed to set sub frame." msgstr "فشل في تحميل الصورة " -#: ekos/capture/captureprocess.cpp:793 +#: ekos/capture/captureprocess.cpp:818 #, fuzzy, kde-format msgid "Failed to set binning." msgstr "فشل في تحميل الصورة " -#: ekos/capture/captureprocess.cpp:1044 +#: ekos/capture/captureprocess.cpp:1069 #, fuzzy, kde-format #| msgid "Data file saved to %1" msgid "Remote image saved to %1" msgstr "تم حفظ الى الملف %1" -#: ekos/capture/captureprocess.cpp:1143 +#: ekos/capture/captureprocess.cpp:1168 #, fuzzy, kde-format msgid "Autoguiding suspended." msgstr "جاري التّحميل" -#: ekos/capture/captureprocess.cpp:1172 +#: ekos/capture/captureprocess.cpp:1197 #, kde-format msgid "Warning: Calibration process was prematurely terminated." msgstr "" #. i18n("CCD capture sequence completed")); -#: ekos/capture/captureprocess.cpp:1238 +#: ekos/capture/captureprocess.cpp:1263 #, fuzzy, kde-format msgid "CCD capture sequence completed" msgstr "بقايا سوبر نوفا" -#: ekos/capture/captureprocess.cpp:1295 +#: ekos/capture/captureprocess.cpp:1320 #, fuzzy, kde-format msgid "Error: Lost connection to CCD." msgstr "اتصال" -#: ekos/capture/captureprocess.cpp:1324 +#: ekos/capture/captureprocess.cpp:1349 #, kde-format msgid "Cannot calculate ADU levels in non-FITS images." msgstr "" -#: ekos/capture/captureprocess.cpp:1436 ekos/capture/captureprocess.cpp:1931 +#: ekos/capture/captureprocess.cpp:1462 ekos/capture/captureprocess.cpp:1957 #, kde-format msgid "Capture failed. Check INDI Control Panel for details." msgstr "" -#: ekos/capture/captureprocess.cpp:1537 +#: ekos/capture/captureprocess.cpp:1563 #, kde-format msgid "Download Time: %1 s, New Download Time Estimate: %2 s." msgstr "" -#: ekos/capture/captureprocess.cpp:1585 +#: ekos/capture/captureprocess.cpp:1611 #, kde-format msgid "Received image %1 out of %2." msgstr "" -#: ekos/capture/captureprocess.cpp:1618 +#: ekos/capture/captureprocess.cpp:1644 #, fuzzy, kde-format #| msgid "Capture" msgid "Captured %1" msgstr "الالتقاط" -#: ekos/capture/captureprocess.cpp:1623 +#: ekos/capture/captureprocess.cpp:1649 #, kde-format msgid "WARNING: remaining and potentially unknown placeholders %1 in %2" msgstr "" -#: ekos/capture/captureprocess.cpp:1655 +#: ekos/capture/captureprocess.cpp:1681 #, fuzzy, kde-format msgid "Executing capture script %1" msgstr "يعمل برنامج نصي 1" -#: ekos/capture/captureprocess.cpp:1670 +#: ekos/capture/captureprocess.cpp:1696 #, kde-format msgid "Pre capture script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1678 +#: ekos/capture/captureprocess.cpp:1704 #, kde-format msgid "Post capture script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1690 +#: ekos/capture/captureprocess.cpp:1716 #, fuzzy, kde-format msgid "Processing meridian flip..." msgstr "تلقائي عرض من التقاط" -#: ekos/capture/captureprocess.cpp:1700 +#: ekos/capture/captureprocess.cpp:1726 #, kde-format msgid "Pre job script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1705 +#: ekos/capture/captureprocess.cpp:1731 #, kde-format msgid "Post job script finished with code %1." msgstr "" -#: ekos/capture/captureprocess.cpp:1878 ekos/focus/focus.cpp:4861 +#: ekos/capture/captureprocess.cpp:1904 ekos/focus/focus.cpp:5102 #, fuzzy, kde-format msgid "Exposure timeout. Aborting..." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/capture/captureprocess.cpp:1901 ekos/focus/focus.cpp:4866 -#: ekos/guide/guide.cpp:892 +#: ekos/capture/captureprocess.cpp:1927 ekos/focus/focus.cpp:5107 +#: ekos/guide/guide.cpp:911 #, fuzzy, kde-format msgid "Exposure timeout. Restarting exposure..." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/capture/captureprocess.cpp:1990 +#: ekos/capture/captureprocess.cpp:2016 #, kde-format msgid "" "Flat calibration failed. Captured image is only %1-bit while requested ADU " "is %2." msgstr "" -#: ekos/capture/captureprocess.cpp:2001 +#: ekos/capture/captureprocess.cpp:2027 #, kde-format msgid "Current image is saturated (%1). Next exposure is %2 seconds." msgstr "" -#: ekos/capture/captureprocess.cpp:2023 +#: ekos/capture/captureprocess.cpp:2049 #, kde-format msgid "Current ADU %1 within target ADU tolerance range." msgstr "" -#: ekos/capture/captureprocess.cpp:2056 +#: ekos/capture/captureprocess.cpp:2082 #, kde-format msgid "" "Unable to calculate optimal exposure settings, please capture the flats " "manually." msgstr "" -#: ekos/capture/captureprocess.cpp:2064 +#: ekos/capture/captureprocess.cpp:2090 #, kde-format msgid "Current ADU is %1 Next exposure is %2 seconds." msgstr "" -#: ekos/capture/captureprocess.cpp:2285 +#: ekos/capture/captureprocess.cpp:2361 +#, kde-format +msgid "" +"Meridian flip configuration has been shifted to the mount module. Please " +"configure the meridian flip there." +msgstr "" + +#: ekos/capture/captureprocess.cpp:2393 +#, kde-format +msgid "Could not open file" +msgstr "تعذّر فتح الملفّ" + +#: ekos/capture/captureprocess.cpp:2413 +#, kde-format +msgid "" +"Warning: HFR-based autofocus is set but option \"Save Sequence HFR Value to " +"File\" is not enabled. Current HFR value will not be written to sequence " +"file." +msgstr "" + +#: ekos/capture/captureprocess.cpp:2536 +#, fuzzy, kde-format +#| msgid "FITS file saved to %1" +msgid "Sequence queue saved to %1" +msgstr "تم حفظ ملف FITS الى %1" + +#: ekos/capture/captureprocess.cpp:2584 #, fuzzy, kde-format #| msgid "Frequency:" msgid "Sequence paused." msgstr "التّردد:" -#: ekos/capture/captureprocess.cpp:2338 +#: ekos/capture/captureprocess.cpp:2637 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 link?" msgid "" @@ -15143,25 +15174,25 @@ "restart capturing?" msgstr "تأكيد حذف الرابط %1 ؟" -#: ekos/capture/captureprocess.cpp:2352 +#: ekos/capture/captureprocess.cpp:2651 #, kde-format msgid "" "Warning: option \"Always Reset Sequence When Starting\" is enabled and " "resets the sequence counts." msgstr "" -#: ekos/capture/captureprocess.cpp:2467 +#: ekos/capture/captureprocess.cpp:2766 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to restart %1 camera driver?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/capture/captureprocess.cpp:2468 +#: ekos/capture/captureprocess.cpp:2767 #, fuzzy, kde-format msgid "Driver Restart" msgstr "نجم" -#: ekos/capture/captureprocessoverlay.cpp:107 +#: ekos/capture/captureprocessoverlay.cpp:106 #, fuzzy, kde-format msgid "No target" msgstr "سارجينت - رسّام أمريكيّ" @@ -15341,172 +15372,257 @@ msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, ExposureCalculatorDialog) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:26 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:32 #, fuzzy, kde-format #| msgid "Time Calculators" msgid "Sub-Exposure Calculator" msgstr "حاسبات الوقت" -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, noiseTolerance) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:56 -#, kde-format -msgid "Adjust the balance of the two noise sources" -msgstr "" - -#. i18n: ectx: property (text), widget (QLabel, allowableNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:69 -#, no-c-format, kde-format -msgid "Noise Increase (%)" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotSubExposure) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:85 -#, fuzzy, kde-format -msgid "Potential exposure time graph" -msgstr "صورة كسوف كلي" - #. i18n: ectx: property (text), widget (QLabel, SQMLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:108 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:62 #, fuzzy, kde-format #| msgid "Sky culture:" msgid "Sky Quality" msgstr "التراث الفلكي:" -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, userSkyQuality) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:127 -#, kde-format -msgid "Adjust the quality of the sky" -msgstr "" +#. i18n: ectx: property (text), widget (QLabel, indiFocalRationLabel) +#. i18n: ectx: property (toolTip), widget (QLabel, l_FbyD) +#. i18n: ectx: property (text), widget (QLabel, label51_2) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:75 +#: ekos/guide/guide.ui:684 oal/equipmentwriter.ui:611 +#, fuzzy, kde-format +msgid "Focal Ratio" +msgstr "Boca Raton" #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:143 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:88 #, fuzzy, kde-format #| msgctxt "string from libindi, used in the config dialog" #| msgid "Filter Count" -msgid "Filter Bandwidth:" +msgid "Filter Bandwidth" msgstr "عدد المرشّح" -#. i18n: ectx: property (text), widget (QLabel, gainSliderLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:171 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, noiseTolerance) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:107 +#, kde-format +msgid "Alter the bias of the noise sources" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, bortleScaleLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:140 +#, fuzzy, kde-format +#| msgid "Orbit class:" +msgid "Bortle Class" +msgstr "فئة المدار:" + +#. i18n: ectx: property (text), widget (QLabel, gainSpinnerLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:185 #, fuzzy, kde-format #| msgid "Gain:" msgid "Gain" msgstr "الكسب:" -#. i18n: ectx: property (text), widget (QLabel, label_2) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:220 +#. i18n: ectx: property (toolTip), widget (QSpinBox, gainSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:210 +#, fuzzy, kde-format +msgid "Select Camera Sensor Gain" +msgstr "بصري" + +#. i18n: ectx: property (toolTip), widget (QComboBox, gainISODiscreteSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:229 +#, fuzzy, kde-format +#| msgid "Open FITS..." +msgid "Select DSLR ISO Value" +msgstr "فتح FITS..." + +#. i18n: ectx: property (text), widget (QLabel, gainISOSelectorLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:248 #, fuzzy, kde-format msgid "ISO" msgstr "الولايات المتحدة الامريكية" #. i18n: ectx: property (text), widget (QLabel, gainSelectionFixedLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:249 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:267 #, kde-format msgid "Read noise constant" msgstr "" -#. i18n: ectx: property (toolTip), widget (QWidget, skyQualityColor) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:266 +#. i18n: ectx: property (toolTip), widget (QLabel, subShotNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:321 #, kde-format -msgid "Bortle Zone Color" +msgid "Noise in the sub-exposure from light pollution" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, indiFocalRationLabel) -#. i18n: ectx: property (toolTip), widget (QLabel, l_FbyD) -#. i18n: ectx: property (text), widget (QLabel, label51_2) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:289 -#: ekos/guide/guide.ui:684 oal/equipmentwriter.ui:611 +#. i18n: ectx: property (text), widget (QLabel, subTotalNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:337 #, fuzzy, kde-format -msgid "Focal Ratio" -msgstr "Boca Raton" +#| msgid "Local Time:" +msgid "Total Noise" +msgstr "الوقت الكلي" -#. i18n: ectx: property (text), widget (QLabel, bortleScaleLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:325 +#. i18n: ectx: property (text), widget (QLabel, subPollutionLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:344 #, fuzzy, kde-format -#| msgid "Orbit class:" -msgid "Bortle Class:" -msgstr "فئة المدار:" +#| msgid "Light Pollution Settings" +msgid "Pollution Electrons" +msgstr "إعدادات التلوث الضوئي" -#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, filterBandwidth) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:338 +#. i18n: ectx: property (toolTip), widget (QLabel, subTotalNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:363 #, kde-format -msgid "Apply a compensation for an optical filter" +msgid "Total noise in the sub-exposure (light pollution + read-noise)" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, subShotNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:379 +#, fuzzy, kde-format +#| msgctxt "City in Congo" +#| msgid "Pointe Noire" +msgid "Shot Noise" +msgstr "بوانت-نوار" + +#. i18n: ectx: property (toolTip), widget (QLabel, subPollutionElectrons) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:398 +#, kde-format +msgid "Estimated light pollution electrons in the sub-exposure." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, subExposureTime) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:452 +#, kde-format +msgid "Duration of Sub-exposure" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, subTimeLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:468 +#, fuzzy, kde-format +msgid "Exposure Time (sec)" +msgstr "صورة كسوف كلي" + +#. i18n: ectx: property (toolTip), widget (QPushButton, downloadCameraB) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:508 +#, fuzzy, kde-format +#| msgid "Download Extra Data Files" +msgid "Download additional camera data files" +msgstr "حمّل بيانات إضافية" + +#. i18n: ectx: property (toolTip), widget (QWidget, skyQualityColor) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:539 +#, kde-format +msgid "Bortle Zone Color" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, bortleScaleValue) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:354 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:558 #, kde-format msgid "Bortle class value" msgstr "" #. i18n: ectx: property (text), widget (QLabel, bortleScaleValue) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:357 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:561 #, kde-format msgid "9" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, cameraReadModeSelector) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:373 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:584 #, kde-format msgid "Select read mode on cameras with multiple read modes." msgstr "" +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, userSkyQuality) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:603 +#, kde-format +msgid "Adjust the quality of the sky" +msgstr "" + #. i18n: ectx: property (text), widget (QLabel, indiCameraReadMode) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:386 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:613 #, fuzzy, kde-format msgid "Read Mode" msgstr "امسح النمط" -#. i18n: ectx: property (text), widget (QLabel, subTimeLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:426 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, filterBandwidth) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:638 +#, kde-format +msgid "Apply a compensation for an optical filter" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QComboBox, imagingCameraSelector) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:661 #, fuzzy, kde-format -msgid "Exposure Time (sec)" +msgid "Camera Data Selection" +msgstr "تحميل مخصص لصورة DSS" + +#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotSubExposure) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:696 +#, fuzzy, kde-format +msgid "Potential exposure time graph" msgstr "صورة كسوف كلي" -#. i18n: ectx: property (text), widget (QLabel, subShotNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:446 +#. i18n: ectx: property (text), widget (QLabel, allowableNoiseLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:715 +#, no-c-format, kde-format +msgid "Noise Increase %" +msgstr "" + +#. i18n: ectx: attribute (title), widget (QWidget, tab) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:735 #, fuzzy, kde-format -#| msgctxt "City in Congo" -#| msgid "Pointe Noire" -msgid "Shot Noise" -msgstr "بوانت-نوار" +#| msgid "Enable" +msgid "Table" +msgstr "مكّن" -#. i18n: ectx: property (toolTip), widget (QLabel, subShotNoise) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:453 +#. i18n: ectx: attribute (title), widget (QWidget, tab_2) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:752 +#, fuzzy, kde-format +#| msgid "Geographic" +msgid "Graph" +msgstr "جغرافي" + +#. i18n: ectx: property (toolTip), widget (QLabel, exposureCountDifferential) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:770 #, kde-format -msgid "Noise in the sub-exposure from light pollution" +msgid "Slope of time to noise ratio curve at current exposure count" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, subPollutionLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:469 +#. i18n: ectx: property (text), widget (QLabel, exposureCountLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:792 #, fuzzy, kde-format -#| msgid "Light Pollution Settings" -msgid "Pollution Electrons" -msgstr "إعدادات التلوث الضوئي" +#| msgid "Exposure" +msgid "Exposures" +msgstr "التّعريض" -#. i18n: ectx: property (toolTip), widget (QLabel, subPollutionElectrons) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:476 +#. i18n: ectx: property (toolTip), widget (QLabel, exposureCount) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:811 #, kde-format -msgid "Calculated count of light pollution electrons in the sub-exposure." +msgid "Calculated exposure count for integration" msgstr "" -#. i18n: ectx: property (text), widget (QLabel, subTotalNoiseLabel) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:492 +#. i18n: ectx: property (toolTip), widget (QCustomPlot, qCustomPlotIntegrationNoise) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:833 #, fuzzy, kde-format -#| msgid "Local Time:" -msgid "Total Noise" -msgstr "الوقت الكلي" +msgid "Integration Time to Noise Ratio" +msgstr "محطة الفضاء الدولية" -#. i18n: ectx: property (toolTip), widget (QLabel, subTotalNoise) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:499 +#. i18n: ectx: property (text), widget (QLabel, targetNoiseLable) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:865 +#, fuzzy, kde-format +#| msgctxt "string from libindi, used in the config dialog" +#| msgid "Noise Reduction" +msgid "Time/Noise Ratio" +msgstr "خفض الضّجيج" + +#. i18n: ectx: property (text), widget (QLabel, exposureDiffLabel) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:884 #, kde-format -msgid "Total noise in the sub-exposure (light pollution + read-noise)" +msgid "dy =" msgstr "" -#. i18n: ectx: property (toolTip), widget (QPushButton, downloadCameraB) -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:528 +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, targetNoiseRatio) +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:897 #, kde-format -msgid "(Future Release) Download additional camera data files" +msgid "Integration time to noise ratio (potential quality)" msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, FileUtilityCameraDataDialog) @@ -15516,7 +15632,7 @@ msgstr "تحميل مخصص لصورة DSS" #. i18n: ectx: property (text), widget (QLabel, resultLable) -#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:73 +#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:101 #, fuzzy, kde-format #| msgid "Select all items in the list" msgid "Select all cameras you wish to use:" @@ -15668,7 +15784,7 @@ "Ekos will refocus as soon as possible, last procedure was %1 seconds ago." msgstr "" -#: ekos/capture/rotatorsettings.cpp:117 +#: ekos/capture/rotatorsettings.cpp:123 #, fuzzy, kde-format msgid "Initial rotator angle %1° is read in successfully." msgstr "انتقِ إدخال الأسس" @@ -15918,96 +16034,100 @@ msgid "Post-Job Script:" msgstr "اختبر البرنامج النصي" -#: ekos/capture/sequencejob.cpp:21 ekos/ekos.h:71 ekos/ekos.h:119 +#: ekos/capture/sequencejob.cpp:23 ekos/ekos.h:71 ekos/ekos.h:119 #: ekos/ekos.h:139 #, fuzzy, kde-format msgid "In Progress" msgstr "في تقدم" -#: ekos/capture/sequencejob.cpp:22 ekos/ekos.h:75 ekos/ekos.h:118 -#: ekos/ekos.h:138 ekos/scheduler/schedulerjob.cpp:618 +#: ekos/capture/sequencejob.cpp:24 ekos/ekos.h:75 ekos/ekos.h:118 +#: ekos/ekos.h:138 ekos/scheduler/schedulerjob.cpp:594 #, fuzzy, kde-format msgid "Complete" msgstr "الإكمال" -#: ekos/capture/sequencejobstate.cpp:401 +#: ekos/capture/sequencejobstate.cpp:390 #, kde-format msgid "Cover the telescope with an evenly illuminated light source." msgstr "" -#: ekos/capture/sequencejobstate.cpp:402 +#: ekos/capture/sequencejobstate.cpp:391 #, fuzzy, kde-format msgid "Flat Frame" msgstr "Barnesville" -#: ekos/capture/sequencejobstate.cpp:413 +#: ekos/capture/sequencejobstate.cpp:402 #, kde-format msgid "Cover the telescope in order to take a dark exposure." msgstr "" -#: ekos/capture/sequencejobstate.cpp:441 ekos/capture/sequencejobstate.cpp:478 +#: ekos/capture/sequencejobstate.cpp:432 ekos/capture/sequencejobstate.cpp:606 +#, fuzzy, kde-format +msgid "Unparking dust cap..." +msgstr "إعداد المناظير" + +#: ekos/capture/sequencejobstate.cpp:432 #, fuzzy, kde-format msgid "Parking dust cap..." msgstr "إعداد المناظير" -#: ekos/capture/sequencejobstate.cpp:450 ekos/capture/sequencejobstate.cpp:489 -#: ekos/capture/sequencejobstate.cpp:535 +#: ekos/capture/sequencejobstate.cpp:444 ekos/capture/sequencejobstate.cpp:491 #, kde-format msgid "Turn light box light on..." msgstr "" -#: ekos/capture/sequencejobstate.cpp:478 ekos/capture/sequencejobstate.cpp:677 -#, fuzzy, kde-format -msgid "Unparking dust cap..." -msgstr "إعداد المناظير" - -#: ekos/capture/sequencejobstate.cpp:489 ekos/capture/sequencejobstate.cpp:535 -#: ekos/capture/sequencejobstate.cpp:662 +#: ekos/capture/sequencejobstate.cpp:444 ekos/capture/sequencejobstate.cpp:491 +#: ekos/capture/sequencejobstate.cpp:592 #, kde-format msgid "Turn light box light off..." msgstr "" -#: ekos/capture/sequencejobstate.cpp:507 +#: ekos/capture/sequencejobstate.cpp:462 #, kde-format -msgid "Mount slewing to wall position..." +msgid "Mount slewing to wall position (az =%1 alt =%2)" msgstr "" -#: ekos/capture/sequencejobstate.cpp:518 ekos/capture/sequencejobstate.cpp:522 +#: ekos/capture/sequencejobstate.cpp:474 #, fuzzy, kde-format msgid "Slew to wall position complete, stop tracking." msgstr "العميل" -#: ekos/capture/sequencejobstate.cpp:550 +#: ekos/capture/sequencejobstate.cpp:478 +#, fuzzy, kde-format +msgid "Slew to wall position complete, tracking stopped." +msgstr "العميل" + +#: ekos/capture/sequencejobstate.cpp:506 #, fuzzy, kde-format msgid "Parking mount failed, aborting..." msgstr "إعداد المناظير" -#: ekos/capture/sequencejobstate.cpp:560 +#: ekos/capture/sequencejobstate.cpp:516 #, fuzzy, kde-format msgid "Parking mount prior to calibration frames capture..." msgstr "فارمنغتون" -#: ekos/capture/sequencejobstate.cpp:574 +#: ekos/capture/sequencejobstate.cpp:530 #, fuzzy, kde-format msgid "Parking dome failed, aborting..." msgstr "إعداد المناظير" -#: ekos/capture/sequencejobstate.cpp:584 +#: ekos/capture/sequencejobstate.cpp:540 #, fuzzy, kde-format msgid "Parking dome prior to calibration frames capture..." msgstr "فارمنغتون" -#: ekos/capture/sequencejobstate.cpp:838 +#: ekos/capture/sequencejobstate.cpp:776 #, kde-format msgid "Light box on." msgstr "" -#: ekos/capture/sequencejobstate.cpp:853 +#: ekos/capture/sequencejobstate.cpp:791 #, fuzzy, kde-format msgid "Dust cap parked." msgstr "القبة الجدول" -#: ekos/capture/sequencejobstate.cpp:857 +#: ekos/capture/sequencejobstate.cpp:795 #, fuzzy, kde-format msgid "Dust cap unparked." msgstr "القبة الجدول" @@ -16029,7 +16149,7 @@ msgid "Image Received" msgstr "سجّل صورة" -#: ekos/ekos.h:73 ekos/scheduler/schedulerjob.cpp:641 +#: ekos/ekos.h:73 ekos/scheduler/schedulerjob.cpp:617 #, fuzzy, kde-format msgid "Focusing" msgstr "مركّز على:" @@ -16059,7 +16179,7 @@ msgid "Setting Rotator" msgstr "انتقِ a نجم" -#: ekos/ekos.h:74 ekos/scheduler/schedulerjob.cpp:644 +#: ekos/ekos.h:74 ekos/scheduler/schedulerjob.cpp:620 #, fuzzy, kde-format msgid "Aligning" msgstr "مركّز على:" @@ -16112,7 +16232,7 @@ msgid "Startup" msgstr "البدء" -#: ekos/ekos.h:187 ekos/scheduler/schedulerjob.cpp:616 +#: ekos/ekos.h:187 ekos/scheduler/schedulerjob.cpp:592 #, kde-format msgid "Running" msgstr "يشغل" @@ -16203,7 +16323,7 @@ msgid "Offline" msgstr "غير متّصل" -#: ekos/ekoslive/message.cpp:929 +#: ekos/ekoslive/message.cpp:932 #, fuzzy, kde-format #| msgid "Saving of the image %1 failed." msgid "Mosaic import failed." @@ -16220,201 +16340,656 @@ msgid "Error parsing server response: %1" msgstr "خطأ: لم يتم حفظ الصورة: %1" -#: ekos/focus/focus.cpp:102 +#: ekos/focus/aberrationinspector.cpp:60 +#, kde-format +msgid "Aberration Inspector - Run %1" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:98 +#, kde-format +msgid "Tile" +msgstr "" + +#. i18n: ectx: property (text), widget (QTreeWidget, OptionsList) +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:99 +#: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:68 +#: tools/optionstreeview.ui:28 +#, kde-format, kde-kuit-format +msgid "Description" +msgstr "الوصف" + +#. i18n: ectx: property (title), widget (QGroupBox, SolutionGroupBox) +#. i18n: ectx: property (text), widget (QTableWidget, solutionTable) +#: ekos/focus/aberrationinspector.cpp:93 fitsviewer/platesolve.ui:399 +#: fitsviewer/solveInfo.ui:91 +#, kde-format +msgid "Solution" +msgstr "الحل" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +msgid "Delta (ticks)" +msgstr "إريكسون" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +msgid "Delta (μm)" +msgstr "دلتا" + +#: ekos/focus/aberrationinspector.cpp:93 +#, fuzzy, kde-format +msgid "Num Stars" +msgstr "خادم" + +#: ekos/focus/aberrationinspector.cpp:93 ekos/focus/aberrationinspector.cpp:104 +#, kde-format +msgid "R²" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:93 +#, kde-format +msgid "Exclude" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:100 +#, fuzzy, kde-format +msgid "Focuser Solution" +msgstr "مركّز على:" + +#: ekos/focus/aberrationinspector.cpp:101 +#, fuzzy, kde-format +msgid "Delta from central tile in ticks" +msgstr "دليل FITS الافتراضي:" + +#: ekos/focus/aberrationinspector.cpp:102 +#, fuzzy, kde-format +#| msgid "Size of chip or film, in millimeters" +msgid "Delta from central tile in micrometers" +msgstr "مقاسات المستشعر أو الفلم بالملم" + +#: ekos/focus/aberrationinspector.cpp:103 +#, kde-format +msgid "Min / max number of stars detected in the focus run" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:105 +#, kde-format +msgid "Check to exclude row from calculations" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:565 +#: ekos/focus/aberrationinspector.cpp:582 +#: ekos/focus/aberrationinspector.cpp:583 +#: ekos/focus/aberrationinspector.cpp:584 +#, fuzzy, kde-format +#| msgctxt "Not Applicable" +#| msgid "N/A" +msgid "N/A" +msgstr "لا ينطبق" + +#: ekos/focus/aberrationinspector.cpp:570 +#, kde-format +msgid "Move sensor nearer flattener" +msgstr "" + +#: ekos/focus/aberrationinspector.cpp:572 +#, kde-format +msgid "Move sensor away from flattener" +msgstr "" + +#. i18n: ectx: property (windowTitle), widget (QDialog, aberrationInspectorDialog) +#: ekos/focus/aberrationinspector.ui:23 +#, fuzzy, kde-format +#| msgid "Observation Planner" +msgid "Aberration Inspector" +msgstr "تجهيز خطة الرصد" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsShowLabels) +#: ekos/focus/aberrationinspector.ui:48 +#, fuzzy, kde-format +msgid "" +"

              Check to show labels on the graph.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsShowLabels) +#. i18n: ectx: property (text), widget (QCheckBox, abInsLabels) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: ekos/focus/aberrationinspector.ui:51 ekos/focus/aberrationinspector.ui:418 +#: xplanet/opsxplanet.ui:574 +#, kde-format +msgid "Labels" +msgstr "اللاصقات" + +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: ekos/focus/aberrationinspector.ui:64 +#, fuzzy, kde-format +#| msgid "Files" +msgid "Tiles:" +msgstr "الملفات" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:74 +#, kde-format +msgid "" +"

              Select the Mosaic tile combination to use for Analysis:" +"

              - All displays all 9 tiles.

              - Centre and outer corners.

              - " +"Centre and inner diamond.

              " +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#. i18n: ectx: property (text), widget (QPushButton, AllButton) +#: ekos/focus/aberrationinspector.ui:81 tools/obslistwizard.ui:173 +#, kde-format +msgid "All" +msgstr "الكل" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:86 +#, fuzzy, kde-format +#| msgid "Center and Track" +msgid "Centre and outer corners" +msgstr "ثبت في المركز و تعقّب" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTileSelection) +#: ekos/focus/aberrationinspector.ui:91 +#, fuzzy, kde-format +#| msgid "Center and Track" +msgid "Centre and inner diamond" +msgstr "ثبت في المركز و تعقّب" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsShowCFZ) +#: ekos/focus/aberrationinspector.ui:105 +#, fuzzy, kde-format +msgid "" +"

              Check to show the Critical Focus Zone on the graph." +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsShowCFZ) +#. i18n: ectx: attribute (title), widget (QWidget, CFZTab) +#: ekos/focus/aberrationinspector.ui:108 ekos/focus/focus.ui:2643 +#, kde-format +msgid "CFZ" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, abInsOptCentres) +#: ekos/focus/aberrationinspector.ui:118 +#, kde-format +msgid "Optimise Tile Centres" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: ekos/focus/aberrationinspector.ui:228 +#, fuzzy, kde-format +#| msgid "Bottom left" +msgid "Top-Bottom Tilt:" +msgstr "أسفل اليسار" + +#. i18n: ectx: property (text), widget (QLabel, label_5) +#: ekos/focus/aberrationinspector.ui:241 +#, fuzzy, kde-format +#| msgid "Local Time:" +msgid "Total Tilt:" +msgstr "الوقت الكلي" + +#. i18n: ectx: property (toolTip), widget (QLineEdit, backfocus) +#: ekos/focus/aberrationinspector.ui:255 +#, fuzzy, kde-format +msgid "" +"

              Backfocus delta is the difference in focus position " +"between the sensor centre and the average of the centre corners.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: ekos/focus/aberrationinspector.ui:271 +#, kde-format +msgid "Backfocus Δ:" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: ekos/focus/aberrationinspector.ui:284 +#, fuzzy, kde-format +#| msgid "Left/Right" +msgid "Left-Right Tilt:" +msgstr "يسار/يمين" + +#. i18n: ectx: property (text), widget (QLabel, label_6) +#: ekos/focus/aberrationinspector.ui:319 +#, fuzzy, kde-format +#| msgid "Detection:" +msgid "Selection:" +msgstr "الاكتشاف:" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:333 +#, fuzzy, kde-format +#| msgid "" +#| "

              Enable limited resource mode to turn off any " +#| "resource-intensive operations:

              • Auto Debayer: Bayered images will not be " +#| "debayered. Only grayscale images are shown.
              • Auto WCS: World Coordinate System data will not be processed. WCS maps sky " +#| "coordinates to image coordinates. Equatorial grid lines, object " +#| "identification, and telescope slew within an image are disabled.
              • 3D Cube: RGB images will not be processed. Only " +#| "grayscale images are shown.
              " +msgid "" +"\n" +"\n" +"

              Selection mode of the 3D " +"Graphic:

              \n" +"

              - None.

              \n" +"

              - Item selects the nearest " +"datapoint.

              \n" +"

              - Slice produces a 2D " +"slice through the graphic.

              " +msgstr "" +"

              مكّن نمط الموارد المحدودة من إيقاف أي عملية " +"تستهلك موارد النظام بشكل مكثف:

              • بناء الألوان التلقائي: الصور ذات البناء اللوني الغير " +"كامل لن يتم معالجتها. ستعرض فقط الصور ذات التدرج الرمادي.
              • نظام " +"الإحداثيات العالمي التلقائي: بيانات نظام الإحداثيات العالمي لن تُعالج. " +"نظام الإحداثيات العالمي (WCS) يطابق الإحداثيات السماوية على إحداثيات الصورة. " +"شبكة الإحداثيات الاستوائية وتعريف الجرم وتدوير التلسكوب في الصورة لن يمكّن.
              • مصفوفة البيانات الثلاثية: الصور ذات الثلاث قنوات RGB لن " +"تعالج. ستظهر فقط الصور ذات التدرج الرمادي.
              " + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:345 fitsviewer/starprofileviewer.cpp:127 +#, kde-format +msgid "Item" +msgstr "عنصر" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) +#: ekos/focus/aberrationinspector.ui:350 +#, fuzzy, kde-format +#| msgctxt "City in Spain" +#| msgid "Alicante" +msgid "Slice" +msgstr "Alicante" + +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: ekos/focus/aberrationinspector.ui:358 +#, fuzzy, kde-format +#| msgid "&Themes" +msgid "Theme:" +msgstr "ال&سمات" + +#. i18n: ectx: property (toolTip), widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:365 +#, fuzzy, kde-format +msgid "" +"

              Select the colour theme of the 3D Graphic.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:372 +#, kde-format +msgid "Qt" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:377 +#, fuzzy, kde-format +msgid "Primary Colors" +msgstr "المنظار" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:382 +#, kde-format +msgid "Digia" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:387 +#, kde-format +msgid "Stone Moss" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:392 +#, fuzzy, kde-format +msgid "Army Blue" +msgstr "أزرق" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:397 +#, fuzzy, kde-format +#| msgctxt "City in Michigan USA" +#| msgid "Detroit" +msgid "Retro" +msgstr "ديترويت" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:402 +#, kde-format +msgid "Ebony" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, abInsTheme) +#: ekos/focus/aberrationinspector.ui:407 +#, fuzzy, kde-format +#| msgctxt "star name" +#| msgid "Capella" +msgid "Isabelle" +msgstr "‎‎العيوق ‎‎‎" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsLabels) +#: ekos/focus/aberrationinspector.ui:415 +#, fuzzy, kde-format +msgid "" +"

              Check to display mosaic tile sensor labels.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsSensor) +#: ekos/focus/aberrationinspector.ui:428 +#, fuzzy, kde-format +msgid "

              Check to display the Sensor.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsSensor) +#: ekos/focus/aberrationinspector.ui:431 +#, fuzzy, kde-format +#| msgid "Sensor FOV" +msgid "Sensor" +msgstr "مستشعر رمز رؤية" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsPetzvalWire) +#: ekos/focus/aberrationinspector.ui:441 +#, fuzzy, kde-format +msgid "" +"

              Check to display the Petzval surface mesh.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsPetzvalWire) +#: ekos/focus/aberrationinspector.ui:444 +#, kde-format +msgid "Petzval Wire" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsPetzvalSurface) +#: ekos/focus/aberrationinspector.ui:454 +#, fuzzy, kde-format +msgid "" +"

              Check to display the Petzval surface.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsPetzvalSurface) +#: ekos/focus/aberrationinspector.ui:457 +#, kde-format +msgid "Petzval Surface" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, abInsSimMode) +#: ekos/focus/aberrationinspector.ui:470 +#, fuzzy, kde-format +#| msgid "

              You're almost done...

              " +msgid "" +"

              Check to set 3D Graphic in Simulation Mode

              " +msgstr "لقد انتهيت من الإعداد تقريباً ..." + +#. i18n: ectx: property (text), widget (QCheckBox, abInsSimMode) +#: ekos/focus/aberrationinspector.ui:473 +#, fuzzy, kde-format +#| msgid "Mode" +msgid "Sim Mode" +msgstr "النمط" + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsBackfocusSlider) +#: ekos/focus/aberrationinspector.ui:483 +#, fuzzy, kde-format +#| msgid "

              You're almost done...

              " +msgid "

              Backfocus slider

              " +msgstr "لقد انتهيت من الإعداد تقريباً ..." + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsTiltLRSlider) +#: ekos/focus/aberrationinspector.ui:502 +#, fuzzy, kde-format +#| msgid "

              You're almost done...

              " +msgid "

              Left-to-Right Tilt Slider

              " +msgstr "لقد انتهيت من الإعداد تقريباً ..." + +#. i18n: ectx: property (toolTip), widget (QSlider, abInsTiltTBSlider) +#: ekos/focus/aberrationinspector.ui:521 +#, fuzzy, kde-format +#| msgid "

              You're almost done...

              " +msgid "

              Top-to-Bottom Tilt Slider

              " +msgstr "لقد انتهيت من الإعداد تقريباً ..." + +#: ekos/focus/aberrationinspectorplot.cpp:106 +#, kde-format +msgctxt "" +"Graphics tooltip; %2 is tile code; %3 is tile name, %4 is Focus Position; %5 " +"is Focus Measure;" +msgid "" +"
              Tile: %2 (%3)
              Pos: %4
              Val: %5
              " +msgstr "" + +#: ekos/focus/focus.cpp:107 #, kde-format msgid "Idle." msgstr "متوقف" -#: ekos/focus/focus.cpp:124 +#: ekos/focus/focus.cpp:129 #, fuzzy, kde-format #| msgid "Profile Editor" msgid "Focus Options Profile Editor" msgstr "محرر منظومة الأجهزة" -#: ekos/focus/focus.cpp:836 +#: ekos/focus/focus.cpp:850 #, fuzzy, kde-format msgid "Finally found temperature source %1" msgstr "مركّز على:" -#: ekos/focus/focus.cpp:961 +#: ekos/focus/focus.cpp:975 #, kde-format msgid "Adaptive Focus: Temp delta %1 ticks; Alt delta %2 ticks" msgstr "" -#: ekos/focus/focus.cpp:975 +#: ekos/focus/focus.cpp:989 #, kde-format msgid "Adaptive Focus suspended. Total movement would exceed Max Travel limit" msgstr "" -#: ekos/focus/focus.cpp:983 +#: ekos/focus/focus.cpp:997 #, kde-format msgid "Adaptive Focus suspended. Total movement would exceed adaptive limit" msgstr "" -#: ekos/focus/focus.cpp:989 +#: ekos/focus/focus.cpp:1003 #, kde-format msgid "Adaptive Focus moving from %1 to %2" msgstr "" -#: ekos/focus/focus.cpp:1003 +#: ekos/focus/focus.cpp:1017 #, kde-format msgid "Adaptive Focus unable to move focuser" msgstr "" -#: ekos/focus/focus.cpp:1128 +#: ekos/focus/focus.cpp:1149 #, fuzzy, kde-format msgid "No Focuser connected." msgstr "ضبط INDI s جهاز اتصال منفذ." -#: ekos/focus/focus.cpp:1135 ekos/focus/focus.cpp:4012 +#: ekos/focus/focus.cpp:1156 ekos/focus/focus.cpp:4236 #, fuzzy, kde-format msgid "No CCD connected." msgstr "ضبط INDI s جهاز اتصال منفذ." -#: ekos/focus/focus.cpp:1142 +#: ekos/focus/focus.cpp:1163 #, kde-format msgid "" "Starting pulse step is too low. Increase the step size to %1 or higher..." msgstr "" -#: ekos/focus/focus.cpp:1150 +#: ekos/focus/focus.cpp:1171 #, kde-format msgid "Autofocus is already running, discarding start request." msgstr "" -#: ekos/focus/focus.cpp:1155 +#: ekos/focus/focus.cpp:1176 #, kde-format msgid "Discarding Autofocus start request - AdjustFocus in progress." msgstr "" -#: ekos/focus/focus.cpp:1160 +#: ekos/focus/focus.cpp:1181 #, kde-format msgid "Discarding Autofocus start request - AdaptiveFocus in progress." msgstr "" -#: ekos/focus/focus.cpp:1300 +#: ekos/focus/focus.cpp:1322 #, kde-format msgid "Autofocus in progress..." msgstr "" -#: ekos/focus/focus.cpp:1302 +#: ekos/focus/focus.cpp:1324 #, kde-format msgid "Please wait until image capture is complete..." msgstr "" -#: ekos/focus/focus.cpp:1316 +#: ekos/focus/focus.cpp:1338 #, kde-format msgid "Autofocus operation started" msgstr "بدأت عمليّة التّركيز الآليّ" -#: ekos/focus/focus.cpp:1403 +#: ekos/focus/focus.cpp:1425 #, kde-format msgid "Adaptive start point, last AF solution outside Max Travel, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1411 +#: ekos/focus/focus.cpp:1433 #, kde-format msgid "Adaptive start point, no temperature source available" msgstr "" -#: ekos/focus/focus.cpp:1413 +#: ekos/focus/focus.cpp:1435 #, kde-format msgid "Adaptive start point, no temperature for last AF solution" msgstr "" -#: ekos/focus/focus.cpp:1420 +#: ekos/focus/focus.cpp:1442 #, kde-format msgid "Adaptive start point, very large temperature delta, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1432 +#: ekos/focus/focus.cpp:1454 #, kde-format msgid "Adaptive start point, no alt recorded for last AF solution" msgstr "" -#: ekos/focus/focus.cpp:1434 +#: ekos/focus/focus.cpp:1456 #, kde-format msgid "Adaptive start point, very large altitude delta, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1444 +#: ekos/focus/focus.cpp:1466 #, kde-format msgid "Adaptive start point, target position is outside Max Travel, ignoring" msgstr "" -#: ekos/focus/focus.cpp:1452 +#: ekos/focus/focus.cpp:1474 #, fuzzy, kde-format #| msgid "Planet Name" msgid "Adaptive start point [%1] excessive move disallowed" msgstr "اسم الكوكب" -#: ekos/focus/focus.cpp:1466 +#: ekos/focus/focus.cpp:1488 #, fuzzy, kde-format #| msgid "Planet Name" msgid "Adapting start point [%1] from %2 to %3" msgstr "اسم الكوكب" -#: ekos/focus/focus.cpp:1512 +#: ekos/focus/focus.cpp:1535 #, fuzzy, kde-format msgid "Detection in progress, please wait." msgstr "القبة الجدول" -#: ekos/focus/focus.cpp:1546 +#: ekos/focus/focus.cpp:1569 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Autofocus aborted." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" -#: ekos/focus/focus.cpp:1630 +#: ekos/focus/focus.cpp:1655 #, kde-format msgid "Error: No Camera detected." msgstr "" -#: ekos/focus/focus.cpp:1637 +#: ekos/focus/focus.cpp:1662 #, fuzzy, kde-format msgid "Error: Lost connection to Camera." msgstr "اتصال" -#: ekos/focus/focus.cpp:1658 +#: ekos/focus/focus.cpp:1683 #, kde-format msgid "Error: No Filter Wheel detected." msgstr "" -#: ekos/focus/focus.cpp:1664 +#: ekos/focus/focus.cpp:1689 #, fuzzy, kde-format msgid "Error: Lost connection to Filter Wheel." msgstr "اتصال" -#: ekos/focus/focus.cpp:1803 +#: ekos/focus/focus.cpp:1828 #, kde-format msgid "Error: No Focuser detected." msgstr "" -#: ekos/focus/focus.cpp:1810 +#: ekos/focus/focus.cpp:1835 #, fuzzy, kde-format msgid "Error: Lost connection to Focuser." msgstr "اتصال" -#: ekos/focus/focus.cpp:1822 +#: ekos/focus/focus.cpp:1848 #, fuzzy, kde-format #| msgctxt "City in Oklahoma USA" #| msgid "Woodward" msgid "outward" msgstr "Woodward" -#: ekos/focus/focus.cpp:1822 +#: ekos/focus/focus.cpp:1848 #, fuzzy, kde-format #| msgctxt "City in Alaska USA" #| msgid "Seward" msgid "inward" msgstr "Seward" -#: ekos/focus/focus.cpp:1836 +#: ekos/focus/focus.cpp:1865 #, fuzzy, kde-format msgid "Focusing %2 by %1 steps..." msgstr "مركّز على:" -#: ekos/focus/focus.cpp:1842 +#: ekos/focus/focus.cpp:1871 #, fuzzy, kde-format msgid "Focusing %2 by %1 step..." msgid_plural "Focusing %2 by %1 steps..." @@ -16425,59 +17000,59 @@ msgstr[4] "مركّز على:" msgstr[5] "مركّز على:" -#: ekos/focus/focus.cpp:1848 +#: ekos/focus/focus.cpp:1877 #, fuzzy, kde-format msgid "Focusing %2 by %1 ms..." msgstr "مركّز على:" -#: ekos/focus/focus.cpp:1886 +#: ekos/focus/focus.cpp:1915 #, fuzzy, kde-format msgid "Focuser is still timing out. Aborting..." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/focus/focus.cpp:1893 +#: ekos/focus/focus.cpp:1922 #, fuzzy, kde-format msgid "Focus motion timed out (%1). Restarting focus driver %2" msgstr "مركّز على:" -#: ekos/focus/focus.cpp:1904 +#: ekos/focus/focus.cpp:1933 #, fuzzy, kde-format msgid "Focus motion timed out (%1). Focusing to %2 steps..." msgstr "مركّز على:" -#: ekos/focus/focus.cpp:1960 +#: ekos/focus/focus.cpp:1990 #, kde-format msgid "Attempting to reconnect focuser: %1" msgstr "" -#: ekos/focus/focus.cpp:1969 +#: ekos/focus/focus.cpp:1999 #, fuzzy, kde-format msgid "Cannot reconnect focuser: %1. Aborting..." msgstr "سجّل صورة" -#: ekos/focus/focus.cpp:2018 +#: ekos/focus/focus.cpp:2048 #, fuzzy, kde-format #| msgid "completed" msgid "Detection complete." msgstr "مكتمل" -#: ekos/focus/focus.cpp:2210 +#: ekos/focus/focus.cpp:2240 #, fuzzy, kde-format #| msgid "Downloading HiPS sources..." msgid "Detecting sources..." msgstr "تحميل مصادر HiPS..." -#: ekos/focus/focus.cpp:2324 +#: ekos/focus/focus.cpp:2354 #, kde-format msgid "Autofocus operation completed successfully" msgstr "اكتملت عمليّة التّركيز الآليّ بنجاح" -#: ekos/focus/focus.cpp:2336 +#: ekos/focus/focus.cpp:2366 #, fuzzy, kde-format msgid "Autofocus operation failed" msgstr "انتقِ إدخال الأسس" -#: ekos/focus/focus.cpp:2368 +#: ekos/focus/focus.cpp:2402 #, fuzzy, kde-format msgid "Focus procedure completed after %1 iteration." msgid_plural "Focus procedure completed after %1 iterations." @@ -16488,209 +17063,219 @@ msgstr[4] "مكتمل" msgstr[5] "مكتمل" -#: ekos/focus/focus.cpp:2452 +#: ekos/focus/focus.cpp:2486 #, fuzzy, kde-format msgid "Settling for %1s..." msgstr "إ&عدادات" -#: ekos/focus/focus.cpp:2459 +#: ekos/focus/focus.cpp:2493 #, fuzzy, kde-format #| msgid "completed" msgid "Settling complete." msgstr "مكتمل" -#: ekos/focus/focus.cpp:2472 +#: ekos/focus/focus.cpp:2506 #, kde-format msgid "Autofocus failed, moving back to initial focus position %1." msgstr "" -#: ekos/focus/focus.cpp:2509 +#: ekos/focus/focus.cpp:2543 #, kde-format msgid "FITS received. No stars detected." msgstr "" -#: ekos/focus/focus.cpp:2664 +#: ekos/focus/focus.cpp:2783 #, kde-format msgid "Failed to automatically select a star. Please select a star manually." msgstr "" -#: ekos/focus/focus.cpp:2758 +#: ekos/focus/focus.cpp:2877 #, fuzzy, kde-format msgid "Capture complete. Select a star to focus." msgstr "تبديل تنسيق" -#: ekos/focus/focus.cpp:2789 +#: ekos/focus/focus.cpp:2908 #, kde-format msgid "No stars detected while testing HFR, capturing again..." msgstr "" -#: ekos/focus/focus.cpp:2916 +#: ekos/focus/focus.cpp:3052 #, kde-format msgid "Autofocus failed to reach proper focus. Try increasing tolerance value." msgstr "" -#: ekos/focus/focus.cpp:2927 ekos/focus/focus.cpp:3566 +#: ekos/focus/focus.cpp:3063 ekos/focus/focus.cpp:3761 #, kde-format msgid "No stars detected, capturing again..." msgstr "" -#: ekos/focus/focus.cpp:2933 ekos/focus/focus.cpp:3572 +#: ekos/focus/focus.cpp:3069 ekos/focus/focus.cpp:3767 #, fuzzy, kde-format msgid "Failed to detect any stars at position %1. Continuing..." msgstr "فشل في تحميل الصورة " -#: ekos/focus/focus.cpp:2938 ekos/focus/focus.cpp:3577 +#: ekos/focus/focus.cpp:3074 ekos/focus/focus.cpp:3772 #, kde-format msgid "Failed to detect any stars. Reset frame and try again." msgstr "" -#: ekos/focus/focus.cpp:3164 +#: ekos/focus/focus.cpp:3257 +#, kde-format +msgid "Unable to launch Aberration Inspector run %1..." +msgstr "" + +#: ekos/focus/focus.cpp:3277 +#, kde-format +msgid "Launching Aberration Inspector run %1..." +msgstr "" + +#: ekos/focus/focus.cpp:3337 #, kde-format msgid "Curve Fit check failed R2=%1 focusR2Limit=%2 retrying..." msgstr "" -#: ekos/focus/focus.cpp:3171 +#: ekos/focus/focus.cpp:3344 #, kde-format msgid "Curve Fit check failed again R2=%1 focusR2Limit=%2 but continuing..." msgstr "" -#: ekos/focus/focus.cpp:3214 +#: ekos/focus/focus.cpp:3387 #, kde-format msgid "FITS received. HFR %1 @ %2. Delta (%3%)" msgstr "" -#: ekos/focus/focus.cpp:3216 +#: ekos/focus/focus.cpp:3389 #, kde-format msgid "FITS received. HFR %1 @ %2." msgstr "" -#: ekos/focus/focus.cpp:3277 +#: ekos/focus/focus.cpp:3450 #, kde-format msgid "" "Change in HFR is too small. Try increasing the step size or decreasing the " "tolerance." msgstr "" -#: ekos/focus/focus.cpp:3284 +#: ekos/focus/focus.cpp:3457 #, kde-format msgid "Failed to detect focus star in frame. Capture and select a focus star." msgstr "" -#: ekos/focus/focus.cpp:3389 +#: ekos/focus/focus.cpp:3562 #, kde-format msgid "Found polynomial solution @ %1" msgstr "" -#: ekos/focus/focus.cpp:3453 +#: ekos/focus/focus.cpp:3626 #, kde-format msgid "Focuser cannot move further, device limits reached. Autofocus aborted." msgstr "" -#: ekos/focus/focus.cpp:3464 +#: ekos/focus/focus.cpp:3637 #, kde-format msgid "" "Unstable fluctuations. Try increasing initial step size or exposure time." msgstr "" -#: ekos/focus/focus.cpp:3474 +#: ekos/focus/focus.cpp:3647 #, kde-format msgid "Deadlock reached. Please try again with different settings." msgstr "" -#: ekos/focus/focus.cpp:3503 +#: ekos/focus/focus.cpp:3676 #, kde-format msgid "Maximum travel limit reached. Autofocus aborted." msgstr "" -#: ekos/focus/focus.cpp:3551 +#: ekos/focus/focus.cpp:3746 #, kde-format msgid "FITS received. HFR %1. Delta (%2%) Min HFR (%3)" msgstr "" -#: ekos/focus/focus.cpp:3555 +#: ekos/focus/focus.cpp:3750 #, kde-format msgid "" "Autofocus failed to reach proper focus. Try adjusting the tolerance value." msgstr "" -#: ekos/focus/focus.cpp:3645 ekos/focus/focus.cpp:3658 -#: ekos/focus/focus.cpp:3779 ekos/focus/focus.cpp:3851 -#: ekos/focus/focus.cpp:3912 ekos/focus/focus.cpp:3956 +#: ekos/focus/focus.cpp:3840 ekos/focus/focus.cpp:3853 +#: ekos/focus/focus.cpp:3983 ekos/focus/focus.cpp:4055 +#: ekos/focus/focus.cpp:4116 ekos/focus/focus.cpp:4180 #, kde-format msgid "Focuser error, check INDI panel." msgstr "" -#: ekos/focus/focus.cpp:3689 ekos/focus/focus.cpp:3795 +#: ekos/focus/focus.cpp:3889 ekos/focus/focus.cpp:3999 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Simulate focuser comms failure..." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" -#: ekos/focus/focus.cpp:3760 ekos/focus/focus.cpp:3836 -#: ekos/focus/focus.cpp:3897 ekos/focus/focus.cpp:3930 +#: ekos/focus/focus.cpp:3964 ekos/focus/focus.cpp:4040 +#: ekos/focus/focus.cpp:4101 ekos/focus/focus.cpp:4134 #, fuzzy, kde-format msgid "Restarting autofocus process..." msgstr "فارمنغتون" -#: ekos/focus/focus.cpp:4028 +#: ekos/focus/focus.cpp:4252 #, fuzzy, kde-format msgid "Starting continuous exposure..." msgstr "فارمنغتون" -#: ekos/focus/focus.cpp:4292 +#: ekos/focus/focus.cpp:4528 #, kde-format msgid "Disabling Auto Star Selection as star selection box was moved manually." msgstr "" -#: ekos/focus/focus.cpp:4297 +#: ekos/focus/focus.cpp:4533 #, fuzzy, kde-format msgid "Focus star is selected." msgstr "لا كائن مُنتقى." -#: ekos/focus/focus.cpp:4425 +#: ekos/focus/focus.cpp:4661 #, kde-format msgid "No star was selected. Using last known position..." msgstr "" -#: ekos/focus/focus.cpp:4431 +#: ekos/focus/focus.cpp:4667 #, kde-format msgid "No star was selected. Aborting..." msgstr "" -#: ekos/focus/focus.cpp:4542 +#: ekos/focus/focus.cpp:4778 #, fuzzy, kde-format msgctxt "@title:window" msgid "Focus Frame" msgstr "مركّز على:" -#: ekos/focus/focus.cpp:4879 +#: ekos/focus/focus.cpp:5120 #, fuzzy, kde-format msgid "Capturing image again..." msgstr "جاري التّحميل." -#: ekos/focus/focus.cpp:4894 +#: ekos/focus/focus.cpp:5135 #, fuzzy, kde-format msgid "Failed to save image. Aborting..." msgstr "فشل في تحميل الصورة " -#: ekos/focus/focus.cpp:4904 +#: ekos/focus/focus.cpp:5145 #, fuzzy, kde-format msgid "Exposure failure. Aborting..." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/focus/focus.cpp:4909 +#: ekos/focus/focus.cpp:5150 #, fuzzy, kde-format msgid "Exposure failure. Restarting exposure..." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/focus/focus.cpp:5187 +#: ekos/focus/focus.cpp:5438 #, fuzzy, kde-format #| msgid "Remove Trail" msgctxt "@title:window" msgid "Relative Profile" msgstr "احذف أثر" -#: ekos/focus/focus.cpp:6379 +#: ekos/focus/focus.cpp:6643 #, kde-format msgid "" "Focus Advisor (FA) is designed to help you with focus parameters.\n" @@ -16715,7 +17300,7 @@ "default." msgstr "" -#: ekos/focus/focus.cpp:6395 +#: ekos/focus/focus.cpp:6659 #, kde-format msgid "" " You have a scope with a central obstruction so be careful not to move too " @@ -16727,7 +17312,7 @@ "range of focuser motion." msgstr "" -#: ekos/focus/focus.cpp:6402 +#: ekos/focus/focus.cpp:6666 #, kde-format msgid "" "\n" @@ -16748,130 +17333,147 @@ "You are now ready to start an Autofocus run." msgstr "" -#: ekos/focus/focus.cpp:6412 +#: ekos/focus/focus.cpp:6676 #, fuzzy, kde-format #| msgid "Focus Star" msgid "Focus Advisor" msgstr "نجم التركيز البؤري" -#. i18n: ectx: property (toolTip), widget (QSpinBox, absTicksSpin) -#: ekos/focus/focus.ui:170 +#. i18n: ectx: property (toolTip), widget (QPushButton, startLoopB) +#: ekos/focus/focus.ui:164 #, fuzzy, kde-format -msgid "Desired absolute focus position" -msgstr "الميلان من الموضع" +msgid "Start framing" +msgstr "فارمنغتون" -#. i18n: ectx: property (toolTip), widget (QLineEdit, absTicksLabel) -#: ekos/focus/focus.ui:186 -#, fuzzy, kde-format -msgid "Current absolute focuser position" -msgstr "الميلان من الموضع" +#. i18n: ectx: property (toolTip), widget (QPushButton, focusOutB) +#: ekos/focus/focus.ui:193 +#, kde-format +msgid "Focus Out" +msgstr "" -#. i18n: ectx: property (toolTip), widget (QPushButton, focusInB) -#: ekos/focus/focus.ui:208 +#. i18n: ectx: property (toolTip), widget (QPushButton, captureB) +#: ekos/focus/focus.ui:225 #, fuzzy, kde-format -msgid "Focus In" -msgstr "مركّز على:" +msgid "Capture image" +msgstr "جاري التّحميل." #. i18n: ectx: property (toolTip), widget (QPushButton, stopGotoB) -#: ekos/focus/focus.ui:253 +#: ekos/focus/focus.ui:254 #, fuzzy, kde-format msgid "Stop focuser motion" msgstr "الميلان من الموضع" #. i18n: ectx: property (toolTip), widget (QPushButton, startFocusB) -#: ekos/focus/focus.ui:282 +#: ekos/focus/focus.ui:283 #, fuzzy, kde-format msgid "Start Auto Focus process" msgstr "فارمنغتون" -#. i18n: ectx: property (text), widget (QLabel, label_22) -#: ekos/focus/focus.ui:305 -#, kde-format -msgid "Start:" -msgstr "البداية:" - #. i18n: ectx: property (text), widget (QLabel, label_16) #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_4) -#: ekos/focus/focus.ui:315 ekos/scheduler/framingassistant.ui:1281 +#: ekos/focus/focus.ui:299 ekos/scheduler/framingassistant.ui:1281 #: ekos/scheduler/scheduler.ui:111 #, kde-format msgid "Steps:" msgstr "الخطوات:" -#. i18n: ectx: property (toolTip), widget (QPushButton, focusOutB) -#: ekos/focus/focus.ui:334 -#, kde-format -msgid "Focus Out" -msgstr "" - #. i18n: ectx: property (toolTip), widget (QPushButton, startGotoB) -#: ekos/focus/focus.ui:366 +#: ekos/focus/focus.ui:318 #, fuzzy, kde-format msgid "Go to an absolute focus position" msgstr "يمين الصّعود من الموضع" -#. i18n: ectx: property (toolTip), widget (QPushButton, startLoopB) -#: ekos/focus/focus.ui:395 +#. i18n: ectx: property (text), widget (QLabel, label_22) +#: ekos/focus/focus.ui:351 +#, kde-format +msgid "Start:" +msgstr "البداية:" + +#. i18n: ectx: property (toolTip), widget (QPushButton, stopFocusB) +#: ekos/focus/focus.ui:370 #, fuzzy, kde-format -msgid "Start framing" +msgid "Stop Auto Focus process" msgstr "فارمنغتون" -#. i18n: ectx: property (toolTip), widget (QPushButton, captureB) -#: ekos/focus/focus.ui:424 +#. i18n: ectx: property (toolTip), widget (QLineEdit, absTicksLabel) +#: ekos/focus/focus.ui:389 #, fuzzy, kde-format -msgid "Capture image" -msgstr "جاري التّحميل." +msgid "Current absolute focuser position" +msgstr "الميلان من الموضع" -#. i18n: ectx: property (toolTip), widget (QPushButton, stopFocusB) +#. i18n: ectx: property (toolTip), widget (QPushButton, focusInB) +#: ekos/focus/focus.ui:411 +#, fuzzy, kde-format +msgid "Focus In" +msgstr "مركّز على:" + +#. i18n: ectx: property (toolTip), widget (QPushButton, startAbInsB) +#: ekos/focus/focus.ui:450 +#, fuzzy, kde-format +msgid "" +"

              Run Aberration Inspector (Auto Focus will run first to " +"collect data).

              Note: Mosaic Mask must be set to activate this button.

              This is an experimental feature.

              " +msgstr "حدّد بوصة دَخْل ملفّ." + +#. i18n: ectx: property (text), widget (QPushButton, startAbInsB) #: ekos/focus/focus.ui:453 #, fuzzy, kde-format -msgid "Stop Auto Focus process" -msgstr "فارمنغتون" +#| msgctxt "Advanced URLs: description or category" +#| msgid "Spectra" +msgid "Inspector" +msgstr "الأطياف" + +#. i18n: ectx: property (toolTip), widget (QSpinBox, absTicksSpin) +#: ekos/focus/focus.ui:475 +#, fuzzy, kde-format +msgid "Desired absolute focus position" +msgstr "الميلان من الموضع" #. i18n: ectx: property (toolTip), widget (QLabel, gainLabel) #. i18n: ectx: property (toolTip), widget (QLabel, label_7) #. i18n: ectx: property (toolTip), widget (QLabel, label_3) -#: ekos/focus/focus.ui:511 ekos/focus/focus.ui:568 ekos/guide/guide.ui:372 +#: ekos/focus/focus.ui:530 ekos/focus/focus.ui:587 ekos/guide/guide.ui:372 #, fuzzy, kde-format msgid "Exposure time in seconds" msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: property (toolTip), widget (QLabel, temperatureSourceLabel) -#: ekos/focus/focus.ui:536 +#: ekos/focus/focus.ui:555 #, fuzzy, kde-format msgid "Focuser temperature source" msgstr "مركّز على:" #. i18n: ectx: property (text), widget (QLabel, temperatureSourceLabel) -#: ekos/focus/focus.ui:539 +#: ekos/focus/focus.ui:558 #, fuzzy, kde-format msgid "TS." msgstr "الكويكب 11351" #. i18n: ectx: property (toolTip), widget (QLabel, label_30) #. i18n: ectx: property (toolTip), widget (QLabel, absoluteTemperatureLabel) -#: ekos/focus/focus.ui:618 ekos/focus/focus.ui:634 +#: ekos/focus/focus.ui:637 ekos/focus/focus.ui:653 #, fuzzy, kde-format msgid "Source temperature in Celsius" msgstr "مركّز على:" #. i18n: ectx: property (text), widget (QLabel, label_30) -#: ekos/focus/focus.ui:621 +#: ekos/focus/focus.ui:640 #, fuzzy, kde-format msgid "Temp. =" msgstr "درجة الحرارة" #. i18n: ectx: property (text), widget (QLabel, absoluteTemperatureLabel) #. i18n: ectx: property (text), widget (QLabel, deltaTemperatureLabel) -#: ekos/focus/focus.ui:640 ekos/focus/focus.ui:675 +#: ekos/focus/focus.ui:659 ekos/focus/focus.ui:694 #, kde-format msgid "NA" msgstr "NA" #. i18n: ectx: property (toolTip), widget (QLabel, label_31) #. i18n: ectx: property (toolTip), widget (QLabel, deltaTemperatureLabel) -#: ekos/focus/focus.ui:650 ekos/focus/focus.ui:669 +#: ekos/focus/focus.ui:669 ekos/focus/focus.ui:688 #, kde-format msgid "" "Delta temperature in Celsius. It is the difference between the last recorded " @@ -16879,25 +17481,25 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_31) -#: ekos/focus/focus.ui:653 +#: ekos/focus/focus.ui:672 #, kde-format msgid "ΔT =" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, toggleFullScreenB) -#: ekos/focus/focus.ui:698 +#: ekos/focus/focus.ui:717 #, kde-format msgid "Toggle Full Screen" msgstr "بدّل ملء الشّاشة" #. i18n: ectx: property (toolTip), widget (QPushButton, resetFrameB) -#: ekos/focus/focus.ui:776 +#: ekos/focus/focus.ui:795 #, kde-format msgid "Reset focus subframe to full capture" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, defaultFocusTemperatureSource) -#: ekos/focus/focus.ui:875 +#: ekos/focus/focus.ui:894 #, fuzzy, kde-format msgid "Select focuser temperature source" msgstr "دليل FITS الافتراضي:" @@ -16906,21 +17508,21 @@ #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) #. i18n: ectx: property (title), widget (QGroupBox, settingsGroupBox) #. i18n: ectx: property (title), widget (QGroupBox, ImageOverlayBox) -#: ekos/focus/focus.ui:913 ekos/guide/opscalibration.ui:34 +#: ekos/focus/focus.ui:932 ekos/guide/opscalibration.ui:34 #: ekos/guide/opsgpg.ui:103 options/opsimageoverlay.ui:38 #, kde-format msgid "Settings" msgstr "إعدادات" #. i18n: ectx: attribute (toolTip), widget (QWidget, settingsTab) -#: ekos/focus/focus.ui:916 +#: ekos/focus/focus.ui:935 #, fuzzy, kde-format msgid "" "

              General Focus Settings parameters.

              " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (toolTip), widget (QRadioButton, focusMosaicMaskRB) -#: ekos/focus/focus.ui:942 +#: ekos/focus/focus.ui:961 #, fuzzy, kde-format msgid "" "

              Aberration inspector style mask with a 3x3 mosaic " @@ -16929,14 +17531,14 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QRadioButton, focusMosaicMaskRB) -#: ekos/focus/focus.ui:945 +#: ekos/focus/focus.ui:964 #, fuzzy, kde-format #| msgid "Observation Planner" msgid "Mosaic Mask:" msgstr "تجهيز خطة الرصد" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMosaicSpace) -#: ekos/focus/focus.ui:955 +#: ekos/focus/focus.ui:974 #, fuzzy, kde-format msgid "" "

              Size of the separator between the tiles.

              During Full Field focusing, this controls the size of " @@ -16973,19 +17575,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusRingMaskRB) -#: ekos/focus/focus.ui:993 +#: ekos/focus/focus.ui:1012 #, kde-format msgid "Ring Mask:" msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusBoxSize) -#: ekos/focus/focus.ui:1012 +#: ekos/focus/focus.ui:1031 #, fuzzy, kde-format msgid "

              Size of the subframe in pixels.

              " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, guideSettleTime) -#: ekos/focus/focus.ui:1040 +#: ekos/focus/focus.ui:1059 #, fuzzy, kde-format msgid "" "

              Wait this many seconds after autofocus completes " @@ -16994,13 +17596,13 @@ #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, guideSettleTime) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusSettleTime) -#: ekos/focus/focus.ui:1043 ekos/focus/focus.ui:2226 +#: ekos/focus/focus.ui:1062 ekos/focus/focus.ui:2245 #, fuzzy, kde-format msgid " s" msgstr " ث" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusSubFrame) -#: ekos/focus/focus.ui:1053 +#: ekos/focus/focus.ui:1072 #, kde-format msgid "" "

              Select Sub Frame to make focus to use a single star " @@ -17011,13 +17613,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusSubFrame) -#: ekos/focus/focus.ui:1056 +#: ekos/focus/focus.ui:1075 #, fuzzy, kde-format msgid "Sub Frame" msgstr "الاسم:" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusUseFullField) -#: ekos/focus/focus.ui:1069 +#: ekos/focus/focus.ui:1088 #, kde-format msgid "" "

              Select Full Field to allow focus to use multiple stars " @@ -17027,14 +17629,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusUseFullField) -#: ekos/focus/focus.ui:1072 +#: ekos/focus/focus.ui:1091 #, fuzzy, kde-format #| msgid "Clear Fields" msgid "Full Field" msgstr "امسح الحقول" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusFullFieldOuterRadius) -#: ekos/focus/focus.ui:1091 +#: ekos/focus/focus.ui:1110 #, no-c-format, kde-format msgid "" "

              Diameter of the outer circle to be excluded from " @@ -17049,8 +17651,8 @@ #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusTolerance) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZTau) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, overlapSpin) -#: ekos/focus/focus.ui:1097 ekos/focus/focus.ui:1198 ekos/focus/focus.ui:1241 -#: ekos/focus/focus.ui:1990 ekos/focus/focus.ui:2087 ekos/focus/focus.ui:2914 +#: ekos/focus/focus.ui:1116 ekos/focus/focus.ui:1217 ekos/focus/focus.ui:1260 +#: ekos/focus/focus.ui:2009 ekos/focus/focus.ui:2106 ekos/focus/focus.ui:2933 #: ekos/scheduler/framingassistant.ui:879 #, no-c-format, kde-format msgid " %" @@ -17058,31 +17660,31 @@ #. i18n: ectx: property (text), widget (QLabel, label_15) #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/focus/focus.ui:1119 ekos/guide/guide.ui:365 +#: ekos/focus/focus.ui:1138 ekos/guide/guide.ui:365 #, kde-format msgid "Box:" msgstr "الصندوق:" #. i18n: ectx: property (toolTip), widget (QCheckBox, useFocusDarkFrame) -#: ekos/focus/focus.ui:1138 +#: ekos/focus/focus.ui:1157 #, kde-format msgid "Use dark frames from the library." msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, useFocusDarkFrame) -#: ekos/focus/focus.ui:1141 +#: ekos/focus/focus.ui:1160 #, fuzzy, kde-format msgid "Dark Frame" msgstr "Barnesville" #. i18n: ectx: property (text), widget (QLabel, label_13) -#: ekos/focus/focus.ui:1154 +#: ekos/focus/focus.ui:1173 #, fuzzy, kde-format msgid "Guide Settle:" msgstr "الحالي اللّون خصائص" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusAutoStarEnabled) -#: ekos/focus/focus.ui:1173 +#: ekos/focus/focus.ui:1192 #, kde-format msgid "" "

              This option is only active when Sub Frame is " @@ -17091,13 +17693,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusAutoStarEnabled) -#: ekos/focus/focus.ui:1176 +#: ekos/focus/focus.ui:1195 #, fuzzy, kde-format msgid "Auto Select Star" msgstr "انتقِ a نجم" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusFullFieldInnerRadius) -#: ekos/focus/focus.ui:1192 +#: ekos/focus/focus.ui:1211 #, kde-format msgid "" "

              Diameter of the inner circle to be excluded from " @@ -17107,33 +17709,33 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1211 +#: ekos/focus/focus.ui:1230 #, fuzzy, kde-format msgid "

              Display units for HFR and FWHM.

              " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), item, widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1215 +#: ekos/focus/focus.ui:1234 #, fuzzy, kde-format #| msgid "pixels" msgid "Pixels" msgstr "بكسل" #. i18n: ectx: property (text), item, widget (QComboBox, focusUnits) -#: ekos/focus/focus.ui:1220 +#: ekos/focus/focus.ui:1239 #, fuzzy, kde-format #| msgid "arc seconds" msgid "Arc Seconds" msgstr "ثوانٍ قوسية" #. i18n: ectx: property (text), widget (QLabel, focusSpacerLabel) -#: ekos/focus/focus.ui:1228 +#: ekos/focus/focus.ui:1247 #, kde-format msgid "Spacer:" msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMosaicTileWidth) -#: ekos/focus/focus.ui:1235 +#: ekos/focus/focus.ui:1254 #, kde-format msgid "" "

              Tiles are squares with an edge length calculated by " @@ -17143,41 +17745,41 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_38) -#: ekos/focus/focus.ui:1269 +#: ekos/focus/focus.ui:1288 #, fuzzy, kde-format #| msgid "Display" msgid "Display Units:" msgstr "العرض" #. i18n: ectx: property (toolTip), widget (QRadioButton, focusNoMaskRB) -#: ekos/focus/focus.ui:1282 +#: ekos/focus/focus.ui:1301 #, kde-format msgid "All stars are used for focusing." msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, focusNoMaskRB) -#: ekos/focus/focus.ui:1285 +#: ekos/focus/focus.ui:1304 #, kde-format msgid "Use all stars for focusing" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, adaptiveFocusGroup) #. i18n: ectx: property (text), widget (QCheckBox, focusAdaptive) -#: ekos/focus/focus.ui:1309 ekos/focus/focus.ui:1404 +#: ekos/focus/focus.ui:1328 ekos/focus/focus.ui:1423 #, fuzzy, kde-format #| msgid "Adaptive Optics" msgid "Adaptive Focus" msgstr "بصريات مكيفة" #. i18n: ectx: property (text), widget (QLabel, label_4) -#: ekos/focus/focus.ui:1357 +#: ekos/focus/focus.ui:1376 #, fuzzy, kde-format #| msgid "Local Time:" msgid "Max Total Move:" msgstr "الوقت الكلي" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdaptiveMaxMove) -#: ekos/focus/focus.ui:1376 +#: ekos/focus/focus.ui:1395 #, kde-format msgid "" "

              The maximum total Adaptive focuser movement between " @@ -17188,13 +17790,13 @@ #. i18n: ectx: property (suffix), widget (QSpinBox, focusAdaptiveMaxMove) #. i18n: ectx: property (suffix), widget (QSpinBox, focusAdaptiveMinMove) -#: ekos/focus/focus.ui:1379 ekos/focus/focus.ui:1446 +#: ekos/focus/focus.ui:1398 ekos/focus/focus.ui:1465 #, fuzzy, kde-format msgid " ticks" msgstr "إريكسون" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusAdaptive) -#: ekos/focus/focus.ui:1401 +#: ekos/focus/focus.ui:1420 #, fuzzy, kde-format #| msgid "

              You're almost done...

              " msgid "" @@ -17203,7 +17805,7 @@ msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (toolTip), widget (QLabel, label_3) -#: ekos/focus/focus.ui:1411 +#: ekos/focus/focus.ui:1430 #, fuzzy, kde-format #| msgid "

              You're almost done...

              " msgid "" @@ -17212,14 +17814,14 @@ msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/focus/focus.ui:1414 +#: ekos/focus/focus.ui:1433 #, fuzzy, kde-format #| msgid "Minimum Alt:" msgid "Min Move:" msgstr "الارتفاع الادنى:" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusAdaptStart) -#: ekos/focus/focus.ui:1427 +#: ekos/focus/focus.ui:1446 #, fuzzy, kde-format msgid "" "

              Adapt the Autofocus start position based on filter and " @@ -17228,13 +17830,13 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QCheckBox, focusAdaptStart) -#: ekos/focus/focus.ui:1430 +#: ekos/focus/focus.ui:1449 #, fuzzy, kde-format msgid "Adapt Start Pos" msgstr "تحجيم تلقائي" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdaptiveMinMove) -#: ekos/focus/focus.ui:1443 +#: ekos/focus/focus.ui:1462 #, fuzzy, kde-format #| msgid "

              You're almost done...

              " msgid "" @@ -17243,13 +17845,13 @@ msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: attribute (title), widget (QWidget, processTab) -#: ekos/focus/focus.ui:1468 +#: ekos/focus/focus.ui:1487 #, kde-format msgid "Process" msgstr "العمليّة" #. i18n: ectx: attribute (toolTip), widget (QWidget, processTab) -#: ekos/focus/focus.ui:1471 +#: ekos/focus/focus.ui:1490 #, fuzzy, kde-format msgid "" "

              Focus parameters to do with the Autofocus process.

              Set a minimum for the acceptable R² when performing an " @@ -17268,34 +17870,34 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusStarMeasureLabel) -#: ekos/focus/focus.ui:1531 +#: ekos/focus/focus.ui:1550 #, fuzzy, kde-format #| msgid "Temperature:" msgid "Measure:" msgstr "درجة الحرارة:" #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/focus/focus.ui:1550 +#: ekos/focus/focus.ui:1569 #, kde-format msgid "Detection:" msgstr "الاكتشاف:" #. i18n: ectx: property (text), widget (QLabel, focusFramesCountLabel) -#: ekos/focus/focus.ui:1569 +#: ekos/focus/focus.ui:1588 #, fuzzy, kde-format #| msgid "Average" msgid "Average Over:" msgstr "المتوسط" #. i18n: ectx: property (text), widget (QLabel, focusR2LimitLabel) -#: ekos/focus/focus.ui:1585 +#: ekos/focus/focus.ui:1604 #, fuzzy, kde-format #| msgid "RA limits:" msgid "R² Limit:" msgstr "حدود الصعود المستقيم، من:" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusFramesCount) -#: ekos/focus/focus.ui:1623 +#: ekos/focus/focus.ui:1642 #, fuzzy, kde-format msgid "" "

              Number of frames to capture at the current focuser " @@ -17303,19 +17905,19 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (suffix), widget (QSpinBox, focusFramesCount) -#: ekos/focus/focus.ui:1626 +#: ekos/focus/focus.ui:1645 #, kde-format msgid " frames" msgstr " الإطارات" #. i18n: ectx: property (text), widget (QLabel, focusCurveFitLabel) -#: ekos/focus/focus.ui:1645 +#: ekos/focus/focus.ui:1664 #, kde-format msgid "Curve Fit:" msgstr "ملاءمة المنحنى:" #. i18n: ectx: property (toolTip), widget (QComboBox, focusCurveFit) -#: ekos/focus/focus.ui:1655 +#: ekos/focus/focus.ui:1674 #, fuzzy, kde-format #| msgid "" #| "

              Enable limited resource mode to turn off any " @@ -17369,7 +17971,7 @@ "الصور ذات التدرج الرمادي.

            " #. i18n: ectx: property (text), item, widget (QComboBox, focusCurveFit) -#: ekos/focus/focus.ui:1662 +#: ekos/focus/focus.ui:1681 #, fuzzy, kde-format #| msgctxt "City in Quebec Canada" #| msgid "Paradis" @@ -17377,26 +17979,26 @@ msgstr "بارادي" #. i18n: ectx: property (text), item, widget (QComboBox, focusCurveFit) -#: ekos/focus/focus.ui:1667 +#: ekos/focus/focus.ui:1686 #, kde-format msgid "Hyperbola" msgstr "قطع زائد" #. i18n: ectx: property (text), item, widget (QComboBox, focusCurveFit) -#: ekos/focus/focus.ui:1672 +#: ekos/focus/focus.ui:1691 #, kde-format msgid "Parabola" msgstr "قطع مكافئ" #. i18n: ectx: property (text), widget (QLabel, label_25) -#: ekos/focus/focus.ui:1689 +#: ekos/focus/focus.ui:1708 #, fuzzy, kde-format #| msgid "Profile:" msgid "SEP Profile:" msgstr "اسم المنظومة:" #. i18n: ectx: property (toolTip), widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1699 +#: ekos/focus/focus.ui:1718 #, fuzzy, kde-format #| msgid "" #| "

            Enable limited resource mode to turn off any " @@ -17463,32 +18065,32 @@ #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) #. i18n: ectx: property (text), widget (QTableWidget, statsTable) -#: ekos/focus/focus.ui:1703 fitsviewer/statform.ui:81 +#: ekos/focus/focus.ui:1722 fitsviewer/statform.ui:81 #, kde-format msgid "HFR" msgstr "HFR" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1708 +#: ekos/focus/focus.ui:1727 #, kde-format msgid "HFR Adj" msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1713 +#: ekos/focus/focus.ui:1732 #, kde-format msgid "FWHM" msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1718 +#: ekos/focus/focus.ui:1737 #, fuzzy, kde-format #| msgid "Stars" msgid "# Stars" msgstr "النجوم" #. i18n: ectx: property (text), item, widget (QComboBox, focusStarMeasure) -#: ekos/focus/focus.ui:1723 +#: ekos/focus/focus.ui:1742 #, fuzzy, kde-format #| msgctxt "City in Quebec Canada" #| msgid "Mont-Laurier" @@ -17496,7 +18098,7 @@ msgstr "مونت لوريل" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusRefineCurveFit) -#: ekos/focus/focus.ui:1731 +#: ekos/focus/focus.ui:1750 #, kde-format msgid "" "

            Check to run an outlier pass when all datapoints have " @@ -17508,14 +18110,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusRefineCurveFit) -#: ekos/focus/focus.ui:1734 +#: ekos/focus/focus.ui:1753 #, fuzzy, kde-format #| msgid "Curve Fit:" msgid "Refine Curve Fit" msgstr "ملاءمة المنحنى:" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusUseWeights) -#: ekos/focus/focus.ui:1747 +#: ekos/focus/focus.ui:1766 #, kde-format msgid "" "

            Check to use the standard deviation of the star HFR or " @@ -17526,14 +18128,14 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, focusUseWeights) -#: ekos/focus/focus.ui:1750 +#: ekos/focus/focus.ui:1769 #, fuzzy, kde-format #| msgid "Use images" msgid "Use Weights" msgstr "استخدم صور" #. i18n: ectx: property (toolTip), widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1763 +#: ekos/focus/focus.ui:1782 #, fuzzy, no-c-format, kde-format #| msgid "" #| "

            Enable limited resource mode to turn off any " @@ -17599,32 +18201,32 @@ "الصور ذات التدرج الرمادي.

          " #. i18n: ectx: property (text), item, widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1770 +#: ekos/focus/focus.ui:1789 #, kde-format msgid "Iterative" msgstr "تكراري" #. i18n: ectx: property (text), item, widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1775 +#: ekos/focus/focus.ui:1794 #, kde-format msgid "Polynomial" msgstr "متعددة الحدود" #. i18n: ectx: property (text), item, widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1780 +#: ekos/focus/focus.ui:1799 #, kde-format msgid "Linear" msgstr "خطّي" #. i18n: ectx: property (text), item, widget (QComboBox, focusAlgorithm) -#: ekos/focus/focus.ui:1785 +#: ekos/focus/focus.ui:1804 #, fuzzy, kde-format #| msgid "Linear Scale" msgid "Linear 1 Pass" msgstr "تصنيف طردي" #. i18n: ectx: property (toolTip), widget (QComboBox, focusDetection) -#: ekos/focus/focus.ui:1816 +#: ekos/focus/focus.ui:1835 #, fuzzy, kde-format #| msgid "" #| "

          Enable limited resource mode to turn off any " @@ -17684,32 +18286,32 @@ "الصور ذات التدرج الرمادي.

        " #. i18n: ectx: property (text), item, widget (QComboBox, focusDetection) -#: ekos/focus/focus.ui:1823 +#: ekos/focus/focus.ui:1842 #, kde-format msgid "Gradient" msgstr "التّدرّج" #. i18n: ectx: property (text), item, widget (QComboBox, focusDetection) -#: ekos/focus/focus.ui:1828 +#: ekos/focus/focus.ui:1847 #, kde-format msgid "Centroid" msgstr "نقطة مركزية" #. i18n: ectx: property (text), item, widget (QComboBox, focusDetection) -#: ekos/focus/focus.ui:1833 +#: ekos/focus/focus.ui:1852 #, kde-format msgid "Threshold" msgstr "العتبة" #. i18n: ectx: property (text), item, widget (QComboBox, focusDetection) #. i18n: ectx: property (text), item, widget (QComboBox, kcfg_GuideAlgorithm) -#: ekos/focus/focus.ui:1838 ekos/guide/opsguide.ui:456 +#: ekos/focus/focus.ui:1857 ekos/guide/opsguide.ui:456 #, fuzzy, kde-format msgid "SEP" msgstr "سبتمبر" #. i18n: ectx: property (text), item, widget (QComboBox, focusDetection) -#: ekos/focus/focus.ui:1843 +#: ekos/focus/focus.ui:1862 #, fuzzy, kde-format #| msgctxt "City in Finland" #| msgid "Lahti" @@ -17717,13 +18319,13 @@ msgstr "Lahti" #. i18n: ectx: property (text), widget (QLabel, focusStarPSFLabel) -#: ekos/focus/focus.ui:1857 +#: ekos/focus/focus.ui:1876 #, kde-format msgid "PSF:" msgstr "" #. i18n: ectx: property (toolTip), widget (QComboBox, focusStarPSF) -#: ekos/focus/focus.ui:1867 +#: ekos/focus/focus.ui:1886 #, kde-format msgid "" "

        The type of PSF to use when Measure is set to FWHM:

      " msgstr "" +#. i18n: ectx: property (text), widget (QLabel, focusThresholdLabel) +#: ekos/focus/focus.ui:1914 +#, kde-format +msgid "Threshold:" +msgstr "العتبة:" + #. i18n: ectx: property (toolTip), widget (QSpinBox, focusGaussianKernelSize) -#: ekos/focus/focus.ui:1911 +#: ekos/focus/focus.ui:1930 #, fuzzy, kde-format msgid "" "

      The gaussian blur kernel size. Used for blurring the " @@ -17743,25 +18351,25 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, focusGaussianKernelSizeLabel) -#: ekos/focus/focus.ui:1936 +#: ekos/focus/focus.ui:1955 #, fuzzy, kde-format msgid "Kernel size:" msgstr "الحصن رايلي" #. i18n: ectx: property (text), widget (QLabel, focusGaussianSigmaLabel) -#: ekos/focus/focus.ui:1952 +#: ekos/focus/focus.ui:1971 #, kde-format msgid "Sigma:" msgstr "سيغما:" #. i18n: ectx: property (text), widget (QLabel, focusMultiRowAverageLabel) -#: ekos/focus/focus.ui:1968 +#: ekos/focus/focus.ui:1987 #, kde-format msgid "Num. of rows:" msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusThreshold) -#: ekos/focus/focus.ui:1987 +#: ekos/focus/focus.ui:2006 #, fuzzy, kde-format msgid "" "

      Increase to restrict the centroid to bright cores. Decrease " @@ -17769,7 +18377,7 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMultiRowAverage) -#: ekos/focus/focus.ui:2015 +#: ekos/focus/focus.ui:2034 #, kde-format msgid "" "

      Combine this number of rows in the Bahtinov max " @@ -17778,7 +18386,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusGaussianSigma) -#: ekos/focus/focus.ui:2040 +#: ekos/focus/focus.ui:2059 #, fuzzy, kde-format msgid "" "

      The gaussian blur sigma value. Used for blurring the " @@ -17786,7 +18394,7 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusTolerance) -#: ekos/focus/focus.ui:2084 +#: ekos/focus/focus.ui:2103 #, kde-format msgid "" "Decrease value to narrow optimal focus point solution radius. Increase to " @@ -17794,13 +18402,13 @@ msgstr "" #. i18n: ectx: attribute (title), widget (QWidget, mechanicsTab) -#: ekos/focus/focus.ui:2128 +#: ekos/focus/focus.ui:2147 #, kde-format msgid "Mechanics" msgstr "ميكانيكا" #. i18n: ectx: attribute (toolTip), widget (QWidget, mechanicsTab) -#: ekos/focus/focus.ui:2131 +#: ekos/focus/focus.ui:2150 #, fuzzy, kde-format msgid "" "

      Focus parameters to do with the mechanics of moving " @@ -17808,27 +18416,27 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, label_11) -#: ekos/focus/focus.ui:2169 +#: ekos/focus/focus.ui:2188 #, fuzzy, kde-format #| msgid "Driver:" msgid "Driver Backlash:" msgstr "السواق:" #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/focus/focus.ui:2191 +#: ekos/focus/focus.ui:2210 #, fuzzy, kde-format msgid "Initial Step Size:" msgstr "الحصن رايلي" #. i18n: ectx: property (text), widget (QLabel, label_9) -#: ekos/focus/focus.ui:2207 +#: ekos/focus/focus.ui:2226 #, fuzzy, kde-format #| msgid "Focuser:" msgid "Focuser Settle:" msgstr "جهاز التركيز البؤري:" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusSettleTime) -#: ekos/focus/focus.ui:2223 +#: ekos/focus/focus.ui:2242 #, fuzzy, kde-format msgid "" "

      Settle time (in seconds) after moving the focuser " @@ -17838,13 +18446,13 @@ #. i18n: ectx: property (text), widget (QLabel, focusOutStepsLabel) #. i18n: ectx: property (text), widget (QLabel, focusAdvOutStepMultLabel) -#: ekos/focus/focus.ui:2248 ekos/focus/focus.ui:3306 +#: ekos/focus/focus.ui:2267 ekos/focus/focus.ui:3325 #, kde-format msgid "Out Step Multiple:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusWalkLabel) -#: ekos/focus/focus.ui:2264 +#: ekos/focus/focus.ui:2283 #, fuzzy, kde-format #| msgctxt "City in Louisiana USA" #| msgid "Walker" @@ -17852,14 +18460,14 @@ msgstr "ووكر" #. i18n: ectx: property (text), widget (QLabel, label_17) -#: ekos/focus/focus.ui:2280 +#: ekos/focus/focus.ui:2299 #, fuzzy, kde-format #| msgid "

      You're almost done...

      " msgid "

      Max Step Size:

      " msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (toolTip), widget (QSpinBox, focusBacklash) -#: ekos/focus/focus.ui:2296 +#: ekos/focus/focus.ui:2315 #, kde-format msgid "" "

      For backlash-aware focusers, the amount of backlash to " @@ -17870,7 +18478,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusTicks) -#: ekos/focus/focus.ui:2309 +#: ekos/focus/focus.ui:2328 #, fuzzy, kde-format #| msgid "" #| "

      Tip: " @@ -17888,14 +18496,14 @@ "يستدعي القيام بخطوات إضافية للإعداد خارج نطاق إيكوس.

      " #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/focus/focus.ui:2334 +#: ekos/focus/focus.ui:2353 #, fuzzy, kde-format #| msgid "Overlap:" msgid "AF Overscan:" msgstr "التراكب:" #. i18n: ectx: property (toolTip), widget (QComboBox, focusWalk) -#: ekos/focus/focus.ui:2353 +#: ekos/focus/focus.ui:2372 #, kde-format msgid "" "

      Select the type of walk for the focuser to take when " @@ -17922,14 +18530,14 @@ #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) #. i18n: ectx: property (text), item, widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:2357 ekos/focus/focus.ui:3126 +#: ekos/focus/focus.ui:2376 ekos/focus/focus.ui:3145 #: kstarslite/qml/modules/popups/ColorSchemePopup.qml:55 #, kde-format, kde-kuit-format msgid "Classic" msgstr "كلاسيكي" #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) -#: ekos/focus/focus.ui:2362 +#: ekos/focus/focus.ui:2381 #, fuzzy, kde-format #| msgctxt "string from libindi, used in the config dialog" #| msgid "Steps" @@ -17937,25 +18545,25 @@ msgstr "الخطوات:" #. i18n: ectx: property (text), item, widget (QComboBox, focusWalk) -#: ekos/focus/focus.ui:2367 +#: ekos/focus/focus.ui:2386 #, kde-format msgid "CFZ Shuffle" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_12) -#: ekos/focus/focus.ui:2384 +#: ekos/focus/focus.ui:2403 #, kde-format msgid "Max Travel:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_26) -#: ekos/focus/focus.ui:2400 +#: ekos/focus/focus.ui:2419 #, fuzzy, kde-format msgid "Capture Timeout:" msgstr "سجّل صورة" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMaxSingleStep) -#: ekos/focus/focus.ui:2416 +#: ekos/focus/focus.ui:2435 #, kde-format msgid "" "

      The maximum single step size the algorithm is allowed " @@ -17964,7 +18572,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusOutSteps) -#: ekos/focus/focus.ui:2438 +#: ekos/focus/focus.ui:2457 #, kde-format msgid "" "

      This number multiplied by initial-step-size is number of " @@ -17974,7 +18582,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, focusCaptureTimeout) #. i18n: ectx: whatsthis, entry (FocusCaptureTimeout), group (Focus) -#: ekos/focus/focus.ui:2463 kstars.kcfg:2102 +#: ekos/focus/focus.ui:2482 kstars.kcfg:2126 #, kde-format msgid "" "Maximum time in seconds to wait for a captured image to be received before " @@ -17982,7 +18590,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAFOverscan) -#: ekos/focus/focus.ui:2485 +#: ekos/focus/focus.ui:2504 #, kde-format msgid "" "

      Provides backlash overscan in ticks for outward " @@ -17994,7 +18602,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusMaxTravel) -#: ekos/focus/focus.ui:2504 +#: ekos/focus/focus.ui:2523 #, fuzzy, kde-format msgid "" "

      Maximum travel in steps before the autofocus process " @@ -18002,13 +18610,13 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, label_27) -#: ekos/focus/focus.ui:2532 +#: ekos/focus/focus.ui:2551 #, fuzzy, kde-format msgid "Motion Timeout:" msgstr "المهلة:" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusMotionTimeout) -#: ekos/focus/focus.ui:2548 +#: ekos/focus/focus.ui:2567 #, fuzzy, kde-format msgid "" "

      Maximum time in seconds to wait for the focuser to " @@ -18016,14 +18624,14 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, focusNumStepsLabel) -#: ekos/focus/focus.ui:2570 +#: ekos/focus/focus.ui:2589 #, fuzzy, kde-format #| msgid "Steps:" msgid "Number Steps:" msgstr "الخطوات:" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusNumSteps) -#: ekos/focus/focus.ui:2586 +#: ekos/focus/focus.ui:2605 #, fuzzy, kde-format msgid "" "

      The total number of steps to use when Walk is set to " @@ -18031,14 +18639,8 @@ "body>" msgstr "حدّد بوصة دَخْل ملفّ." -#. i18n: ectx: attribute (title), widget (QWidget, CFZTab) -#: ekos/focus/focus.ui:2624 -#, kde-format -msgid "CFZ" -msgstr "" - #. i18n: ectx: attribute (toolTip), widget (QWidget, CFZTab) -#: ekos/focus/focus.ui:2627 +#: ekos/focus/focus.ui:2646 #, kde-format msgid "" "

      Parameters to do with configuring the Critical Focus " @@ -18047,26 +18649,26 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusCFZTauLabel) -#: ekos/focus/focus.ui:2696 +#: ekos/focus/focus.ui:2715 #, fuzzy, kde-format msgid "Tolerance (τ):" msgstr "تورانس" #. i18n: ectx: property (text), widget (QLabel, focusCFZLabel) -#: ekos/focus/focus.ui:2712 +#: ekos/focus/focus.ui:2731 #, fuzzy, kde-format #| msgid "

      You're almost done...

      " msgid "

      CFZ:

      " msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (text), widget (QLabel, focusCFZApertureLabel) -#: ekos/focus/focus.ui:2731 +#: ekos/focus/focus.ui:2750 #, fuzzy, kde-format msgid "Aperture (A):" msgstr "بُؤرة:" #. i18n: ectx: property (toolTip), widget (QCheckBox, focusCFZDisplayVCurve) -#: ekos/focus/focus.ui:2750 +#: ekos/focus/focus.ui:2769 #, fuzzy, kde-format msgid "" "

      Check to display the CFZ on the V-curve after a " @@ -18075,13 +18677,13 @@ #. i18n: ectx: property (text), widget (QCheckBox, focusCFZDisplayVCurve) #. i18n: ectx: property (title), widget (QGroupBox, displayGroup) -#: ekos/focus/focus.ui:2753 hips/hipsmanager.cpp:96 indi/opsindi.ui:497 +#: ekos/focus/focus.ui:2772 hips/hipsmanager.cpp:96 indi/opsindi.ui:497 #, kde-format msgid "Display" msgstr "العرض" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusCFZAperture) -#: ekos/focus/focus.ui:2772 +#: ekos/focus/focus.ui:2791 #, fuzzy, kde-format msgid "" "

      Set the aperture of your telescope in mm. This is " @@ -18090,13 +18692,13 @@ #. i18n: ectx: property (suffix), widget (QSpinBox, focusCFZAperture) #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focalLenSpin) -#: ekos/focus/focus.ui:2775 ekos/scheduler/framingassistant.ui:87 +#: ekos/focus/focus.ui:2794 ekos/scheduler/framingassistant.ui:87 #, kde-format msgid " mm" msgstr "مم" #. i18n: ectx: property (toolTip), widget (QLineEdit, FocusCFZCameraSteps) -#: ekos/focus/focus.ui:2800 +#: ekos/focus/focus.ui:2819 #, fuzzy, kde-format msgid "" "

      The CFZ of the camera (resolution limit) in the active " @@ -18104,14 +18706,14 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (toolTip), widget (QLineEdit, focusCFZ) -#: ekos/focus/focus.ui:2816 +#: ekos/focus/focus.ui:2835 #, fuzzy, kde-format #| msgid "

      You're almost done...

      " msgid "

      The calculated CFZ in μm.

      " msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZTolerance) -#: ekos/focus/focus.ui:2835 +#: ekos/focus/focus.ui:2854 #, kde-format msgid "" "

      Set the tolerance=t value between 0 and 1. This scales " @@ -18120,7 +18722,7 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QLineEdit, FocusCFZFinal) -#: ekos/focus/focus.ui:2860 +#: ekos/focus/focus.ui:2879 #, fuzzy, kde-format msgid "" "

      The Final CFZ is the greater of the calculated CFZ and " @@ -18128,21 +18730,21 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, label_37) -#: ekos/focus/focus.ui:2876 +#: ekos/focus/focus.ui:2895 #, fuzzy, kde-format #| msgid "

      You're almost done...

      " msgid "

      Step Size:

      " msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (text), widget (QLabel, label_19) -#: ekos/focus/focus.ui:2892 +#: ekos/focus/focus.ui:2911 #, fuzzy, kde-format #| msgid "Camera:" msgid "CFZ Camera:" msgstr "الكاميرا:" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZTau) -#: ekos/focus/focus.ui:2911 +#: ekos/focus/focus.ui:2930 #, kde-format msgid "" "

      Set the

      You're almost done...

      " msgid "

      The calculated CFZ in steps.

      " msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (text), widget (QLabel, focusCFZFormula) -#: ekos/focus/focus.ui:2955 +#: ekos/focus/focus.ui:2974 #, fuzzy, kde-format #| msgid "" #| "

      Online Resources:" @@ -18172,20 +18774,20 @@ msgstr "الهدف" #. i18n: ectx: property (text), widget (QLabel, focusCFZStepsLabel) -#: ekos/focus/focus.ui:2974 +#: ekos/focus/focus.ui:2993 #, kde-format msgid "CFZ:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusCFZWavelengthLabel) -#: ekos/focus/focus.ui:2993 +#: ekos/focus/focus.ui:3012 #, fuzzy, kde-format #| msgid "Wavelength:" msgid "Wavelength (λ):" msgstr "طول الموجة:" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZStepSize) -#: ekos/focus/focus.ui:3009 +#: ekos/focus/focus.ui:3028 #, kde-format msgid "" "

      Set the step size (in microns) of your focuser. To " @@ -18197,13 +18799,13 @@ msgstr "" #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZStepSize) -#: ekos/focus/focus.ui:3012 +#: ekos/focus/focus.ui:3031 #, kde-format msgid " μm" msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZSeeing) -#: ekos/focus/focus.ui:3037 +#: ekos/focus/focus.ui:3056 #, fuzzy, kde-format msgid "" "

      The total seeing FWHM (in arc-seconds).

      Reset Wavelength, Aperture, Focal Ratio to values " @@ -18219,20 +18821,20 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QPushButton, resetToOTB) -#: ekos/focus/focus.ui:3068 +#: ekos/focus/focus.ui:3087 #, fuzzy, kde-format #| msgid "Reset to Now" msgid "Reset To OT" msgstr "أعد الوقت إلى الآن" #. i18n: ectx: property (text), widget (QLabel, label_14) -#: ekos/focus/focus.ui:3081 +#: ekos/focus/focus.ui:3100 #, fuzzy, kde-format msgid "Focal Ratio (f):" msgstr "Boca Raton" #. i18n: ectx: property (toolTip), widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:3119 +#: ekos/focus/focus.ui:3138 #, fuzzy, kde-format #| msgid "" #| "

      Enable limited resource mode to turn off any " @@ -18291,14 +18893,14 @@ "الصور ذات التدرج الرمادي.

    " #. i18n: ectx: property (text), item, widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:3131 +#: ekos/focus/focus.ui:3150 #, fuzzy, kde-format #| msgid "Wavelength:" msgid "Wavefront" msgstr "طول الموجة:" #. i18n: ectx: property (text), item, widget (QComboBox, focusCFZAlgorithm) -#: ekos/focus/focus.ui:3136 +#: ekos/focus/focus.ui:3155 #, fuzzy, kde-format #| msgctxt "City in British Columbia Canada" #| msgid "Golden" @@ -18306,7 +18908,7 @@ msgstr "غولدن" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZFNumber) -#: ekos/focus/focus.ui:3150 +#: ekos/focus/focus.ui:3169 #, fuzzy, kde-format msgid "" "

    Set the F# to use. This is defaulted from the selected " @@ -18314,19 +18916,19 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QLabel, label_20) -#: ekos/focus/focus.ui:3178 +#: ekos/focus/focus.ui:3197 #, kde-format msgid "Final CFZ:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusCFZSeeingLabel) -#: ekos/focus/focus.ui:3197 +#: ekos/focus/focus.ui:3216 #, kde-format msgid "FWHM (θ):" msgstr "" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, focusCFZWavelength) -#: ekos/focus/focus.ui:3213 +#: ekos/focus/focus.ui:3232 #, fuzzy, kde-format msgid "" "

    Set the light wavelength to use. This is defaulted " @@ -18334,14 +18936,14 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (suffix), widget (QDoubleSpinBox, focusCFZWavelength) -#: ekos/focus/focus.ui:3216 +#: ekos/focus/focus.ui:3235 #, fuzzy, kde-format #| msgid " mm" msgid " nm" msgstr "مم" #. i18n: ectx: attribute (title), widget (QWidget, advisorTab) -#: ekos/focus/focus.ui:3251 +#: ekos/focus/focus.ui:3270 #, fuzzy, kde-format #| msgctxt "string from libindi, used in the config dialog" #| msgid "Divisor" @@ -18349,7 +18951,7 @@ msgstr "قاسم" #. i18n: ectx: attribute (toolTip), widget (QWidget, advisorTab) -#: ekos/focus/focus.ui:3254 +#: ekos/focus/focus.ui:3273 #, fuzzy, kde-format msgid "" "

    Focus Advisor help utility to assist with setting up " @@ -18364,22 +18966,22 @@ #. i18n: ectx: property (text), widget (QCheckBox, focusAdvSettingsTab) #. i18n: ectx: property (text), widget (QPushButton, updateButton) #. i18n: ectx: property (text), widget (QPushButton, Update) -#: ekos/focus/focus.ui:3286 ekos/focus/focus.ui:3322 ekos/focus/focus.ui:3345 -#: ekos/focus/focus.ui:3420 ekos/focus/focus.ui:3436 ekos/focus/focus.ui:3465 +#: ekos/focus/focus.ui:3305 ekos/focus/focus.ui:3341 ekos/focus/focus.ui:3364 +#: ekos/focus/focus.ui:3439 ekos/focus/focus.ui:3455 ekos/focus/focus.ui:3484 #: tools/altvstime.ui:535 tools/observinglist.ui:222 #, kde-format msgid "Update" msgstr "تحديث" #. i18n: ectx: property (text), widget (QLabel, focusAdvCameraLabel) -#: ekos/focus/focus.ui:3296 +#: ekos/focus/focus.ui:3315 #, fuzzy, kde-format msgid "Camera & Filter Wheel Parameters" msgstr "تصفية عجل" #. i18n: ectx: property (toolTip), widget (QLabel, focusAdvOutStepMultLabel) #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdvOutStepMult) -#: ekos/focus/focus.ui:3303 ekos/focus/focus.ui:3497 +#: ekos/focus/focus.ui:3322 ekos/focus/focus.ui:3516 #, kde-format msgid "" "

    A good figure to start with is 5. An exception is if " @@ -18393,20 +18995,20 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusAdvSettingsLabel) -#: ekos/focus/focus.ui:3332 +#: ekos/focus/focus.ui:3351 #, fuzzy, kde-format msgid "Settings Tab Parameters" msgstr "إدخال معاملات" #. i18n: ectx: property (text), widget (QLabel, focusAdvProcessLabel) -#: ekos/focus/focus.ui:3355 +#: ekos/focus/focus.ui:3374 #, fuzzy, kde-format #| msgid "All parameters" msgid "Process Tab Parameters" msgstr "كل المعطيات" #. i18n: ectx: property (toolTip), widget (QPushButton, focusAdvReset) -#: ekos/focus/focus.ui:3368 +#: ekos/focus/focus.ui:3387 #, fuzzy, kde-format msgid "" "

    Update Focus Parameters to Focus Advisor suggestions " @@ -18414,14 +19016,14 @@ msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QPushButton, focusAdvReset) -#: ekos/focus/focus.ui:3371 +#: ekos/focus/focus.ui:3390 #, fuzzy, kde-format msgid "Update Params" msgstr "تحديث" #. i18n: ectx: property (toolTip), widget (QSpinBox, focusAdvSteps) #. i18n: ectx: property (toolTip), widget (QLabel, label_32) -#: ekos/focus/focus.ui:3384 ekos/focus/focus.ui:3446 +#: ekos/focus/focus.ui:3403 ekos/focus/focus.ui:3465 #, kde-format msgid "" "

    Step size can be defaulted to the Critical Focus Zone. " @@ -18430,27 +19032,27 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, focusAdvLabel) -#: ekos/focus/focus.ui:3400 +#: ekos/focus/focus.ui:3419 #, fuzzy, kde-format #| msgid "Focus Star" msgid "Focus Advisor:" msgstr "نجم التركيز البؤري" #. i18n: ectx: property (text), widget (QLabel, focusAdvMechanicsLabel) -#: ekos/focus/focus.ui:3407 +#: ekos/focus/focus.ui:3426 #, fuzzy, kde-format #| msgid "All parameters" msgid "Mechanics Tab Parameters" msgstr "كل المعطيات" #. i18n: ectx: property (text), widget (QLabel, label_32) -#: ekos/focus/focus.ui:3449 +#: ekos/focus/focus.ui:3468 #, fuzzy, kde-format msgid "Step Size:" msgstr "الحصن رايلي" #. i18n: ectx: property (toolTip), widget (QPushButton, focusAdvHelp) -#: ekos/focus/focus.ui:3481 +#: ekos/focus/focus.ui:3500 #, fuzzy, kde-format #| msgid "

    You're almost done...

    " msgid "" @@ -18458,27 +19060,27 @@ msgstr "لقد انتهيت من الإعداد تقريباً ..." #. i18n: ectx: property (text), widget (QPushButton, focusAdvHelp) -#: ekos/focus/focus.ui:3484 +#: ekos/focus/focus.ui:3503 #, fuzzy, kde-format #| msgid "Help" msgid "Help..." msgstr "مساعدة" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) -#: ekos/focus/focus.ui:3575 +#: ekos/focus/focus.ui:3594 #, kde-format msgid "V-Curve" msgstr "منحنى V" #. i18n: ectx: property (text), widget (QLabel, label_2) #. i18n: ectx: property (text), widget (QLabel, label_9) -#: ekos/focus/focus.ui:3617 ekos/manager/focusmanager.ui:165 +#: ekos/focus/focus.ui:3636 ekos/manager/focusmanager.ui:165 #, kde-format msgid "HFR:" msgstr ":HFR" #. i18n: ectx: property (toolTip), widget (QLineEdit, HFROut) -#: ekos/focus/focus.ui:3636 +#: ekos/focus/focus.ui:3655 #, fuzzy, kde-format msgid "" "

    Averaged HFR value from the last frame.

    Averaged FWHM value from the last frame.

    Number of stars found in the last frame.

    Focuser iteration.

    " msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: property (text), widget (QPushButton, relativeProfileB) -#: ekos/focus/focus.ui:3781 +#: ekos/focus/focus.ui:3800 #, fuzzy, kde-format #| msgid "Profile" msgid "Profile..." @@ -18537,42 +19139,42 @@ #. i18n: ectx: property (text), widget (QPushButton, clearB) #. i18n: ectx: property (text), widget (QPushButton, ClearButton) #. i18n: ectx: property (text), widget (QPushButton, Clear) -#: ekos/focus/focus.ui:3788 ekos/manager.ui:957 fitsviewer/fitstab.cpp:136 +#: ekos/focus/focus.ui:3807 ekos/manager.ui:957 fitsviewer/fitstab.cpp:145 #: indi/guimanager.cpp:75 tools/conjunctions.ui:205 tools/eclipsetool.ui:167 #: tools/modcalcgeod.ui:160 #, kde-format msgid "Clear" msgstr "امسح" -#: ekos/focus/focusalgorithms.cpp:504 +#: ekos/focus/focusalgorithms.cpp:512 #, kde-format msgid "Called newMeasurement after a solution was found." msgstr "" -#: ekos/focus/focusalgorithms.cpp:780 +#: ekos/focus/focusalgorithms.cpp:788 #, fuzzy, kde-format msgid "Failed to fit curve to data." msgstr "اليوم && الموقع" -#: ekos/focus/focusalgorithms.cpp:840 +#: ekos/focus/focusalgorithms.cpp:848 #, fuzzy, kde-format #| msgid "Horizontal Coordinates" msgid "Solution found." msgstr "احداثيات افقية" -#: ekos/focus/focusalgorithms.cpp:884 +#: ekos/focus/focusalgorithms.cpp:892 #, kde-format msgid "Too many steps." msgstr "" -#: ekos/focus/focusalgorithms.cpp:913 +#: ekos/focus/focusalgorithms.cpp:921 #, kde-format msgid "Solution lies outside max travel." msgstr "" #. i18n: ectx: property (text), widget (QTableWidget, tableWidget) #: ekos/focus/focushfrvplot.cpp:42 fitsviewer/fitsheaderdialog.ui:53 -#: fitsviewer/fitstab.cpp:355 +#: fitsviewer/fitstab.cpp:364 #, kde-format msgid "Value" msgstr "قيمة" @@ -18595,7 +19197,7 @@ msgstr "" #: ekos/guide/externalguide/linguider.cpp:70 -#: ekos/guide/externalguide/phd2.cpp:278 +#: ekos/guide/externalguide/phd2.cpp:279 #, kde-format msgid "" "The host was not found. Please check the host name and port settings in " @@ -18610,7 +19212,7 @@ msgstr "" #: ekos/guide/externalguide/linguider.cpp:79 -#: ekos/guide/externalguide/phd2.cpp:285 +#: ekos/guide/externalguide/phd2.cpp:286 #, kde-format msgid "The following error occurred: %1." msgstr "حدث الخطأ التالي: %1." @@ -18675,279 +19277,279 @@ msgid "Failed to set dither range." msgstr "فشل في تحميل الصورة " -#: ekos/guide/externalguide/phd2.cpp:134 +#: ekos/guide/externalguide/phd2.cpp:135 #, kde-format msgid "PHD2: There was no dithering response from PHD2, but continue guiding." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:150 +#: ekos/guide/externalguide/phd2.cpp:151 #, kde-format msgid "Giving up reconnecting." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:154 +#: ekos/guide/externalguide/phd2.cpp:155 #, fuzzy, kde-format msgid "Reconnecting to PHD2 Host: %1, on port %2. . ." msgstr "الإتصال إلى INDI مضيف عند يعمل منفذ failed." -#: ekos/guide/externalguide/phd2.cpp:191 +#: ekos/guide/externalguide/phd2.cpp:192 #, fuzzy, kde-format msgid "Connecting to PHD2 Host: %1, on port %2. . ." msgstr "الإتصال إلى INDI مضيف عند يعمل منفذ failed." -#: ekos/guide/externalguide/phd2.cpp:246 +#: ekos/guide/externalguide/phd2.cpp:247 #, kde-format msgid "Aborting any capture before disconnecting equipment..." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:259 +#: ekos/guide/externalguide/phd2.cpp:260 #, fuzzy, kde-format msgid "Disconnected from PHD2 Host: %1, on port %2." msgstr "الإتصال إلى INDI مضيف عند يعمل منفذ failed." -#: ekos/guide/externalguide/phd2.cpp:275 +#: ekos/guide/externalguide/phd2.cpp:276 #, fuzzy, kde-format #| msgid "Disconnect" msgid "The host disconnected." msgstr "اقطع الاتصال" -#: ekos/guide/externalguide/phd2.cpp:281 +#: ekos/guide/externalguide/phd2.cpp:282 #, kde-format msgid "" "The connection was refused by the peer. Make sure the PHD2 is running, and " "check that the host name and port settings are correct." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:307 +#: ekos/guide/externalguide/phd2.cpp:308 #, kde-format msgid "PHD2: invalid response received: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:308 +#: ekos/guide/externalguide/phd2.cpp:309 #, fuzzy, kde-format #| msgid "Version" msgid "PHD2: JSON error: %1" msgstr "الاصدار" -#: ekos/guide/externalguide/phd2.cpp:332 +#: ekos/guide/externalguide/phd2.cpp:333 #, kde-format msgid "Unknown PHD2 event: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:341 +#: ekos/guide/externalguide/phd2.cpp:342 #, fuzzy, kde-format #| msgid "Version" msgid "PHD2: Version %1" msgstr "الاصدار" -#: ekos/guide/externalguide/phd2.cpp:345 +#: ekos/guide/externalguide/phd2.cpp:346 #, fuzzy, kde-format msgid "PHD2: Calibration Complete." msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:355 +#: ekos/guide/externalguide/phd2.cpp:356 #, fuzzy, kde-format msgid "PHD2: Waiting for guiding to settle." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:378 +#: ekos/guide/externalguide/phd2.cpp:379 #, fuzzy, kde-format msgid "PHD2: Calibration Failed (%1)." msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:383 +#: ekos/guide/externalguide/phd2.cpp:384 #, fuzzy, kde-format msgid "Calibration Data Flipped." msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:411 +#: ekos/guide/externalguide/phd2.cpp:412 #, kde-format msgid "PHD2: Settling failed (%1)." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:430 +#: ekos/guide/externalguide/phd2.cpp:431 #, kde-format msgid "PHD2: There was a dithering error, but continue guiding." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:439 +#: ekos/guide/externalguide/phd2.cpp:440 #, fuzzy, kde-format msgid "PHD2: Settling failed, aborted." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:445 +#: ekos/guide/externalguide/phd2.cpp:446 #, fuzzy, kde-format msgid "PHD2: Settling complete, Guiding Started." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:474 +#: ekos/guide/externalguide/phd2.cpp:475 #, fuzzy, kde-format msgid "PHD2: Star found, guiding is resuming..." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:556 +#: ekos/guide/externalguide/phd2.cpp:557 #, fuzzy, kde-format msgid "PHD2 %1: %2" msgstr "PHD2" -#: ekos/guide/externalguide/phd2.cpp:610 +#: ekos/guide/externalguide/phd2.cpp:611 #, kde-format msgid "PHD2: Looping Exposures Stopped." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:615 +#: ekos/guide/externalguide/phd2.cpp:616 #, fuzzy, kde-format msgid "PHD2: Guiding Stopped." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:634 +#: ekos/guide/externalguide/phd2.cpp:635 #, kde-format msgid "PHD2: Lock Position Set." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:645 +#: ekos/guide/externalguide/phd2.cpp:646 #, kde-format msgid "PHD2: Star Selected." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:655 +#: ekos/guide/externalguide/phd2.cpp:656 #, fuzzy, kde-format msgid "PHD2: Guiding resumed." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:660 +#: ekos/guide/externalguide/phd2.cpp:661 #, fuzzy, kde-format msgid "PHD2: Guiding started." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:671 +#: ekos/guide/externalguide/phd2.cpp:672 #, kde-format msgid "PHD2: Lock Position Lost, continuing calibration." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:677 +#: ekos/guide/externalguide/phd2.cpp:678 #, fuzzy, kde-format msgid "PHD2: Star Lost. Trying to reacquire for %1s." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:683 +#: ekos/guide/externalguide/phd2.cpp:684 #, kde-format msgid "PHD2: Lock Position Lost." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:689 +#: ekos/guide/externalguide/phd2.cpp:690 #, fuzzy, kde-format msgid "PHD2: Guiding paused." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:694 +#: ekos/guide/externalguide/phd2.cpp:695 #, fuzzy, kde-format msgid "PHD2: Calibrating, timing out in %1s." msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:703 +#: ekos/guide/externalguide/phd2.cpp:704 #, fuzzy, kde-format msgid "PHD2: Calibration turned to looping, failed." msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:707 +#: ekos/guide/externalguide/phd2.cpp:708 #, fuzzy, kde-format msgid "PHD2: Looping Exposures." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:713 +#: ekos/guide/externalguide/phd2.cpp:714 #, fuzzy, kde-format msgid "PHD2: Dithering started." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:741 +#: ekos/guide/externalguide/phd2.cpp:742 #, fuzzy, kde-format msgid "PHD2: Calibration is cleared" msgstr "العميل" -#: ekos/guide/externalguide/phd2.cpp:837 +#: ekos/guide/externalguide/phd2.cpp:838 #, kde-format msgid "PHD2: DEC Guide Mode is Set to: %1" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:847 +#: ekos/guide/externalguide/phd2.cpp:848 #, fuzzy, kde-format msgid "PHD2: Exposure Time set to: " msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/guide/externalguide/phd2.cpp:855 +#: ekos/guide/externalguide/phd2.cpp:856 #, fuzzy, kde-format msgid "PHD2: Valid Exposure Times: Auto, " msgstr "صورة كسوف كلي" -#: ekos/guide/externalguide/phd2.cpp:886 +#: ekos/guide/externalguide/phd2.cpp:887 #, kde-format msgid "" "PHD2: Please set CCD and telescope parameters in PHD2, Pixel Scale is " "invalid." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:888 +#: ekos/guide/externalguide/phd2.cpp:889 #, kde-format msgid "PHD2: Pixel Scale is %1 arcsec per pixel" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1003 +#: ekos/guide/externalguide/phd2.cpp:1004 #, kde-format msgid "PHD2 Error: unhandled '%1'" msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1135 -#: ekos/guide/externalguide/phd2.cpp:1153 -#: ekos/guide/externalguide/phd2.cpp:1304 -#: ekos/guide/externalguide/phd2.cpp:1419 -#: ekos/guide/externalguide/phd2.cpp:1448 -#: ekos/guide/externalguide/phd2.cpp:1477 +#: ekos/guide/externalguide/phd2.cpp:1136 +#: ekos/guide/externalguide/phd2.cpp:1154 +#: ekos/guide/externalguide/phd2.cpp:1305 +#: ekos/guide/externalguide/phd2.cpp:1420 +#: ekos/guide/externalguide/phd2.cpp:1449 +#: ekos/guide/externalguide/phd2.cpp:1478 #, kde-format msgid "PHD2 Error: Equipment not connected." msgstr "" -#: ekos/guide/externalguide/phd2.cpp:1297 +#: ekos/guide/externalguide/phd2.cpp:1298 #, fuzzy, kde-format msgid "PHD2: Guiding is already running." msgstr "جاري التّحميل" -#: ekos/guide/externalguide/phd2.cpp:1363 +#: ekos/guide/externalguide/phd2.cpp:1364 #, fuzzy, kde-format #| msgid "Configure Equipment" msgid "PHD2: Connecting Equipment. . ." msgstr "إعدادات الأجهزة" -#: ekos/guide/externalguide/phd2.cpp:1365 +#: ekos/guide/externalguide/phd2.cpp:1366 #, fuzzy, kde-format msgid "PHD2: Disconnecting Equipment. . ." msgstr "اتصل أو اقطع الاتصال INDI جهاز." -#: ekos/guide/guide.cpp:66 +#: ekos/guide/guide.cpp:69 #, kde-format msgid "Calibration" msgstr "المعايرة" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_DitherEnabled) -#: ekos/guide/guide.cpp:70 ekos/guide/opsdither.ui:102 +#: ekos/guide/guide.cpp:73 ekos/guide/opsdither.ui:102 #, fuzzy, kde-format msgid "Dither" msgstr "محاكاة" -#: ekos/guide/guide.cpp:74 +#: ekos/guide/guide.cpp:77 #, fuzzy, kde-format #| msgid "RA Guide Error" msgid "GPG RA Guider" msgstr "خطا تتبع م.م" -#: ekos/guide/guide.cpp:412 +#: ekos/guide/guide.cpp:415 #, kde-format msgid "" "PHD2's current camera: %1, is not connected to Ekos. The PHD2 Guide Star " "Image will be received, but the full external guide frames cannot." msgstr "" -#: ekos/guide/guide.cpp:422 +#: ekos/guide/guide.cpp:425 #, kde-format msgid "" "PHD2's current camera: %1, is connected to Ekos. You can select whether to " @@ -18955,112 +19557,112 @@ "using the SubFrame checkbox." msgstr "" -#: ekos/guide/guide.cpp:571 +#: ekos/guide/guide.cpp:574 #, kde-format msgid "Connection to the guide CCD is lost." msgstr "" -#: ekos/guide/guide.cpp:743 +#: ekos/guide/guide.cpp:746 #, fuzzy, kde-format msgid "Error: lost connection to CCD." msgstr "اتصال" -#: ekos/guide/guide.cpp:911 +#: ekos/guide/guide.cpp:930 #, fuzzy, kde-format msgid "Exposure timeout. Aborting Autoguide." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/guide/guide.cpp:913 +#: ekos/guide/guide.cpp:932 #, fuzzy, kde-format msgid "Exposure timeout. Aborting Dithering." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/guide/guide.cpp:915 +#: ekos/guide/guide.cpp:934 #, fuzzy, kde-format msgid "Exposure timeout. Aborting Calibration." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." -#: ekos/guide/guide.cpp:1272 +#: ekos/guide/guide.cpp:1291 #, kde-format msgid "The mount is parked. Unpark to start guiding." msgstr "" -#: ekos/guide/guide.cpp:1375 +#: ekos/guide/guide.cpp:1394 #, kde-format msgid "Pier side change detected. Clearing calibration." msgstr "" -#: ekos/guide/guide.cpp:1389 +#: ekos/guide/guide.cpp:1408 #, fuzzy, kde-format msgid "Mount is moving. Resetting calibration..." msgstr "Mount Ekar" -#: ekos/guide/guide.cpp:1405 +#: ekos/guide/guide.cpp:1424 #, fuzzy, kde-format msgid "Mount is parking. Aborting guide..." msgstr "Mount Ekar" -#: ekos/guide/guide.cpp:1407 +#: ekos/guide/guide.cpp:1426 #, fuzzy, kde-format msgid "Mount is slewing. Aborting guide..." msgstr "اليوم && الموقع" -#: ekos/guide/guide.cpp:1470 +#: ekos/guide/guide.cpp:1489 #, fuzzy, kde-format msgid "Calibration is cleared." msgstr "العميل" -#: ekos/guide/guide.cpp:1491 +#: ekos/guide/guide.cpp:1510 #, kde-format msgid "External guider connected." msgstr "" -#: ekos/guide/guide.cpp:1509 +#: ekos/guide/guide.cpp:1528 #, kde-format msgid "External guider disconnected." msgstr "" -#: ekos/guide/guide.cpp:1526 +#: ekos/guide/guide.cpp:1545 #, fuzzy, kde-format msgid "Calibration completed." msgstr "العميل" -#: ekos/guide/guide.cpp:1544 +#: ekos/guide/guide.cpp:1563 #, fuzzy, kde-format msgid "Calibration started." msgstr "العميل" -#: ekos/guide/guide.cpp:1551 +#: ekos/guide/guide.cpp:1570 #, fuzzy, kde-format msgid "Guiding resumed." msgstr "جاري التّحميل" -#: ekos/guide/guide.cpp:1554 +#: ekos/guide/guide.cpp:1573 #, fuzzy, kde-format msgid "Autoguiding started." msgstr "جاري التّحميل" -#: ekos/guide/guide.cpp:1566 +#: ekos/guide/guide.cpp:1585 #, fuzzy, kde-format msgid "Autoguiding aborted." msgstr "جاري التّحميل" -#: ekos/guide/guide.cpp:1571 +#: ekos/guide/guide.cpp:1590 #, fuzzy, kde-format msgid "Guiding suspended." msgstr "جاري التّحميل" -#: ekos/guide/guide.cpp:1580 +#: ekos/guide/guide.cpp:1599 #, fuzzy, kde-format msgid "Manual dithering in progress." msgstr "القبة الجدول" -#: ekos/guide/guide.cpp:1584 +#: ekos/guide/guide.cpp:1603 #, fuzzy, kde-format msgid "Dithering in progress." msgstr "القبة الجدول" -#: ekos/guide/guide.cpp:1588 +#: ekos/guide/guide.cpp:1607 #, kde-format msgid "Post-dither settling for %1 second..." msgid_plural "Post-dither settling for %1 seconds..." @@ -19071,78 +19673,78 @@ msgstr[4] "" msgstr[5] "" -#: ekos/guide/guide.cpp:1593 +#: ekos/guide/guide.cpp:1612 #, fuzzy, kde-format msgid "Dithering failed." msgstr "أخرى" -#: ekos/guide/guide.cpp:1604 +#: ekos/guide/guide.cpp:1623 #, fuzzy, kde-format msgid "Dithering completed successfully." msgstr "انتقِ إدخال الأسس" -#: ekos/guide/guide.cpp:1650 +#: ekos/guide/guide.cpp:1669 #, fuzzy, kde-format msgid "%1x%1 guide binning is not supported." msgstr "إعداد المناظير" -#: ekos/guide/guide.cpp:1672 +#: ekos/guide/guide.cpp:1691 #, kde-format msgid "Exposure failed. Restarting exposure..." msgstr "" -#: ekos/guide/guide.cpp:1798 +#: ekos/guide/guide.cpp:1817 #, kde-format msgid "Cannot change guider type while active." msgstr "" -#: ekos/guide/guide.cpp:1889 +#: ekos/guide/guide.cpp:1908 #, kde-format msgid "" "Warning: Reset Guiding Calibration is enabled. It is recommended to turn " "this option off for PHD2." msgstr "" -#: ekos/guide/guide.cpp:2272 +#: ekos/guide/guide.cpp:2292 #, fuzzy, kde-format msgid "Calibration failed to start." msgstr "العميل" -#: ekos/guide/guide.cpp:2423 +#: ekos/guide/guide.cpp:2443 #, fuzzy, kde-format msgid "Auto star selected." msgstr "لا كائن مُنتقى." -#: ekos/guide/guide.cpp:2427 +#: ekos/guide/guide.cpp:2447 #, fuzzy, kde-format msgid "Failed to select an auto star." msgstr "فشل في تحميل الصورة " -#: ekos/guide/guide.cpp:2436 +#: ekos/guide/guide.cpp:2456 #, fuzzy, kde-format msgid "Select a guide star to calibrate." msgstr "انتقِ a نجم" -#: ekos/guide/guide.cpp:2682 +#: ekos/guide/guide.cpp:2702 #, fuzzy, kde-format #| msgid "pixels" msgid "x (pixels)" msgstr "%1 (%2 - %3×%4 بكسل)" -#: ekos/guide/guide.cpp:2683 +#: ekos/guide/guide.cpp:2703 #, fuzzy, kde-format #| msgid "pixels" msgid "y (pixels)" msgstr "بكسل" -#: ekos/guide/guide.cpp:2794 ekos/guide/guide.cpp:2920 +#: ekos/guide/guide.cpp:2814 ekos/guide/guide.cpp:2940 #, kde-format msgid "" "The PHD2 camera is not available to Ekos, so you cannot see the captured " "images. But you will still see the Guide Star Image when you guide." msgstr "" -#: ekos/guide/guide.cpp:2798 ekos/guide/guide.cpp:2924 +#: ekos/guide/guide.cpp:2818 ekos/guide/guide.cpp:2944 #, kde-format msgid "" "To receive PHD2 images other than the Guide Star Image, SubFrame must be " @@ -19150,7 +19752,7 @@ "enable it before Guiding" msgstr "" -#: ekos/guide/guide.cpp:3083 +#: ekos/guide/guide.cpp:3103 #, kde-format msgid "Cannot change active optical train while PHD2 is connected" msgstr "" @@ -19625,18 +20227,18 @@ "arcseconds.

    " msgstr "" -#: ekos/guide/guidedriftgraph.cpp:66 +#: ekos/guide/guidedriftgraph.cpp:67 #, fuzzy, kde-format msgid "drift (arcsec)" msgstr "دقيقة قوسية" -#: ekos/guide/guidedriftgraph.cpp:67 +#: ekos/guide/guidedriftgraph.cpp:68 #, fuzzy, kde-format msgid "pulse (ms)" msgstr "بؤري الطول:" -#: ekos/guide/guidedriftgraph.cpp:223 ekos/guide/guidedriftgraph.cpp:625 -#: ekos/guide/guidedriftgraph.cpp:700 +#: ekos/guide/guidedriftgraph.cpp:224 ekos/guide/guidedriftgraph.cpp:626 +#: ekos/guide/guidedriftgraph.cpp:701 #, kde-format msgctxt "" "Drift graphics tooltip; %1 is local time; %2 is RA deviation; %3 is DE " @@ -19647,8 +20249,8 @@ "tr>SNR: %5 \"" msgstr "" -#: ekos/guide/guidedriftgraph.cpp:242 ekos/guide/guidedriftgraph.cpp:641 -#: ekos/guide/guidedriftgraph.cpp:716 +#: ekos/guide/guidedriftgraph.cpp:243 ekos/guide/guidedriftgraph.cpp:642 +#: ekos/guide/guidedriftgraph.cpp:717 #, kde-format msgctxt "" "Drift graphics tooltip; %1 is local time; %2 is RA deviation; %3 is DE " @@ -19661,7 +20263,7 @@ "msDE Pulse: %7 ms" msgstr "" -#: ekos/guide/guidedriftgraph.cpp:281 ekos/guide/guidetargetplot.cpp:200 +#: ekos/guide/guidedriftgraph.cpp:282 ekos/guide/guidetargetplot.cpp:200 #: kstarslite/skyitems/horizonitem.cpp:29 #: skycomponents/horizoncomponent.cpp:118 skymapdrawabstract.cpp:184 #, fuzzy, kde-format @@ -19669,7 +20271,7 @@ msgid "N" msgstr "ش" -#: ekos/guide/guidedriftgraph.cpp:289 ekos/guide/guidetargetplot.cpp:208 +#: ekos/guide/guidedriftgraph.cpp:290 ekos/guide/guidetargetplot.cpp:208 #: kstarslite/skyitems/horizonitem.cpp:25 #: skycomponents/horizoncomponent.cpp:114 #, fuzzy, kde-format @@ -19677,7 +20279,7 @@ msgid "S" msgstr "ج" -#: ekos/guide/guidedriftgraph.cpp:297 ekos/guide/guidetargetplot.cpp:216 +#: ekos/guide/guidedriftgraph.cpp:298 ekos/guide/guidetargetplot.cpp:216 #: kstarslite/skyitems/horizonitem.cpp:27 #: skycomponents/horizoncomponent.cpp:116 #, fuzzy, kde-format @@ -19685,7 +20287,7 @@ msgid "W" msgstr "غرب" -#: ekos/guide/guidedriftgraph.cpp:305 ekos/guide/guidetargetplot.cpp:224 +#: ekos/guide/guidedriftgraph.cpp:306 ekos/guide/guidetargetplot.cpp:224 #: kstarslite/skyitems/horizonitem.cpp:23 #: skycomponents/horizoncomponent.cpp:112 #, fuzzy, kde-format @@ -19693,7 +20295,7 @@ msgid "E" msgstr "شرق" -#: ekos/guide/guidedriftgraph.cpp:453 +#: ekos/guide/guidedriftgraph.cpp:454 #, fuzzy, kde-format #| msgid "Explore Catalogs" msgctxt "@title:window" @@ -19718,52 +20320,52 @@ msgid "Run" msgstr "نفّذ" -#: ekos/guide/internalguide/calibrationprocess.cpp:176 +#: ekos/guide/internalguide/calibrationprocess.cpp:178 #, kde-format msgid "RA drifting forward..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:180 +#: ekos/guide/internalguide/calibrationprocess.cpp:182 #, fuzzy, kde-format #| msgid "Guide Star" msgid "Guide Star found." msgstr "نجم التوجيه" -#: ekos/guide/internalguide/calibrationprocess.cpp:200 +#: ekos/guide/internalguide/calibrationprocess.cpp:202 #, fuzzy, kde-format msgid "Calibrating RA Out" msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:239 +#: ekos/guide/internalguide/calibrationprocess.cpp:241 #, fuzzy, kde-format msgid "RA drifting reverse..." msgstr "فارمنغتون" -#: ekos/guide/internalguide/calibrationprocess.cpp:245 -#: ekos/guide/internalguide/calibrationprocess.cpp:383 -#: ekos/guide/internalguide/calibrationprocess.cpp:601 +#: ekos/guide/internalguide/calibrationprocess.cpp:247 +#: ekos/guide/internalguide/calibrationprocess.cpp:385 +#: ekos/guide/internalguide/calibrationprocess.cpp:603 #, kde-format msgid "" "Calibration rejected. Star drift is too short. Check for mount, cable, or " "backlash problems." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:248 +#: ekos/guide/internalguide/calibrationprocess.cpp:250 #, fuzzy, kde-format msgid "Calibration Failed: Drift too short." msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:277 +#: ekos/guide/internalguide/calibrationprocess.cpp:279 #, fuzzy, kde-format msgid "Calibrating RA In" msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:334 +#: ekos/guide/internalguide/calibrationprocess.cpp:336 #, fuzzy, kde-format msgid "Calibration Failed: couldn't reach start." msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:335 +#: ekos/guide/internalguide/calibrationprocess.cpp:337 #, kde-format msgid "" "Guide RA: Scope cannot reach the start point after %1 iteration. Possible " @@ -19778,47 +20380,47 @@ msgstr[4] "" msgstr[5] "" -#: ekos/guide/internalguide/calibrationprocess.cpp:354 +#: ekos/guide/internalguide/calibrationprocess.cpp:356 #, kde-format msgid "DEC backlash..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:367 -#: ekos/guide/internalguide/calibrationprocess.cpp:420 +#: ekos/guide/internalguide/calibrationprocess.cpp:369 +#: ekos/guide/internalguide/calibrationprocess.cpp:422 #, kde-format msgid "DEC drifting forward..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:386 -#: ekos/guide/internalguide/calibrationprocess.cpp:602 +#: ekos/guide/internalguide/calibrationprocess.cpp:388 +#: ekos/guide/internalguide/calibrationprocess.cpp:604 #, fuzzy, kde-format msgid "Calibration Failed: drift too short." msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:406 -#: ekos/guide/internalguide/calibrationprocess.cpp:423 +#: ekos/guide/internalguide/calibrationprocess.cpp:408 +#: ekos/guide/internalguide/calibrationprocess.cpp:425 #, fuzzy, kde-format msgid "Calibrating DEC Backlash" msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:432 +#: ekos/guide/internalguide/calibrationprocess.cpp:434 #, fuzzy, kde-format msgid "Calibrating DEC Out" msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:468 +#: ekos/guide/internalguide/calibrationprocess.cpp:470 #, kde-format msgid "DEC drifting reverse..." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:478 -#: ekos/guide/internalguide/calibrationprocess.cpp:566 +#: ekos/guide/internalguide/calibrationprocess.cpp:480 +#: ekos/guide/internalguide/calibrationprocess.cpp:568 #, fuzzy, kde-format msgid "Calibration Failed: couldn't reach start point." msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:479 -#: ekos/guide/internalguide/calibrationprocess.cpp:568 +#: ekos/guide/internalguide/calibrationprocess.cpp:481 +#: ekos/guide/internalguide/calibrationprocess.cpp:570 #, kde-format msgid "" "Guide DEC: Scope cannot reach the start point after %1 iteration.\n" @@ -19833,87 +20435,87 @@ msgstr[4] "" msgstr[5] "" -#: ekos/guide/internalguide/calibrationprocess.cpp:511 +#: ekos/guide/internalguide/calibrationprocess.cpp:513 #, fuzzy, kde-format msgid "Calibrating DEC In" msgstr "العميل" -#: ekos/guide/internalguide/calibrationprocess.cpp:584 +#: ekos/guide/internalguide/calibrationprocess.cpp:586 #, kde-format msgid "DEC swap enabled." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:586 +#: ekos/guide/internalguide/calibrationprocess.cpp:588 #, kde-format msgid "DEC swap disabled." msgstr "" -#: ekos/guide/internalguide/calibrationprocess.cpp:590 +#: ekos/guide/internalguide/calibrationprocess.cpp:592 #, fuzzy, kde-format msgid "Calibration Successful" msgstr "العميل" -#: ekos/guide/internalguide/internalguider.cpp:435 +#: ekos/guide/internalguide/internalguider.cpp:537 #, kde-format msgid "" "Warning: Dithering failed. Autoguiding shall continue as set in the options " "in case of dither failure." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:505 +#: ekos/guide/internalguide/internalguider.cpp:607 #, fuzzy, kde-format msgid "Warning: Manual Dithering failed." msgstr "أخرى" -#: ekos/guide/internalguide/internalguider.cpp:555 +#: ekos/guide/internalguide/internalguider.cpp:657 #, kde-format msgid "%1 info are missing. Please set the values in INDI Control Panel." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:556 +#: ekos/guide/internalguide/internalguider.cpp:658 #, kde-format msgid "Missing Information" msgstr "معلومات ناقصة" -#: ekos/guide/internalguide/internalguider.cpp:581 +#: ekos/guide/internalguide/internalguider.cpp:683 #, fuzzy, kde-format msgid "Guiding calibration restored" msgstr "العميل" -#: ekos/guide/internalguide/internalguider.cpp:633 +#: ekos/guide/internalguide/internalguider.cpp:735 #, kde-format msgid "" "Lost track of the guide star. Try increasing the square size or reducing " "pulse duration." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:636 +#: ekos/guide/internalguide/internalguider.cpp:738 #, fuzzy, kde-format #| msgid "Guide Star" msgid "Guide Star lost." msgstr "نجم التوجيه" -#: ekos/guide/internalguide/internalguider.cpp:668 +#: ekos/guide/internalguide/internalguider.cpp:770 #, fuzzy, kde-format msgid "Guiding calibration failed" msgstr "العميل" -#: ekos/guide/internalguide/internalguider.cpp:675 +#: ekos/guide/internalguide/internalguider.cpp:777 #, kde-format msgid "Guiding calibration completed successfully" msgstr "اكتملت معايرة التّوجيه بنجاح" -#: ekos/guide/internalguide/internalguider.cpp:999 +#: ekos/guide/internalguide/internalguider.cpp:1101 #, kde-format msgid "Lost track of the guide star. Searching for guide stars..." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:1001 +#: ekos/guide/internalguide/internalguider.cpp:1103 #, kde-format msgid "Delta RMS threshold value exceeded. Searching for guide stars..." msgstr "" -#: ekos/guide/internalguide/internalguider.cpp:1185 +#: ekos/guide/internalguide/internalguider.cpp:1287 #, fuzzy, kde-format msgid "Failed to find any suitable guide stars. Aborting..." msgstr "فشل في تحميل الصورة " @@ -20020,7 +20622,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_CalibrationMaxMove) #. i18n: ectx: label, entry (CalibrationMaxMove), group (Guide) -#: ekos/guide/opscalibration.ui:122 kstars.kcfg:2489 +#: ekos/guide/opscalibration.ui:122 kstars.kcfg:2559 #, kde-format msgid "Maximum number of pixels the calibration should move (approximate)." msgstr "" @@ -20033,7 +20635,7 @@ #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_GuideAutoSquareSizeEnabled) #. i18n: ectx: label, entry (GuideAutoSquareSizeEnabled), group (Guide) -#: ekos/guide/opscalibration.ui:156 kstars.kcfg:2505 +#: ekos/guide/opscalibration.ui:156 kstars.kcfg:2575 #, fuzzy, kde-format msgid "Automatically select the square size based on the selected star width." msgstr "تبديل تنسيق" @@ -20157,7 +20759,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ReverseDecOnPierSideChange) #. i18n: ectx: label, entry (ReverseDecOnPierSideChange), group (Scheduler) -#: ekos/guide/opscalibration.ui:411 kstars.kcfg:2770 +#: ekos/guide/opscalibration.ui:411 kstars.kcfg:2840 #, kde-format msgid "Reverse DEC on pier-side change when reusing calibration." msgstr "" @@ -20171,7 +20773,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_4) #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_DitherSettle) #. i18n: ectx: label, entry (DitherSettle), group (Guide) -#: ekos/guide/opsdither.ui:62 ekos/guide/opsdither.ui:147 kstars.kcfg:2565 +#: ekos/guide/opsdither.ui:62 ekos/guide/opsdither.ui:147 kstars.kcfg:2635 #, kde-format msgid "" "After dither is successful, wait for this many seconds before proceeding." @@ -20220,7 +20822,7 @@ #. i18n: ectx: property (text), widget (QLabel, label) #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, label_12) -#: ekos/guide/opsdither.ui:170 ekos/opsekos.ui:477 ekos/opsekos.ui:847 +#: ekos/guide/opsdither.ui:170 ekos/opsekos.ui:490 ekos/opsekos.ui:860 #, kde-format msgid "frames" msgstr "إطارات" @@ -20703,7 +21305,7 @@ msgid "Num Periods for Period Estimate" msgstr "" -#: ekos/guide/opsguide.cpp:41 +#: ekos/guide/opsguide.cpp:43 #, fuzzy, kde-format #| msgid "Profile Editor" msgid "Guide Options Profile Editor" @@ -20931,7 +21533,7 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_MinDetectionsSEPMultistar) #. i18n: ectx: property (toolTip), widget (QLabel, label_22) #. i18n: ectx: label, entry (MinDetectionsSEPMultistar), group (Guide) -#: ekos/guide/opsguide.ui:524 ekos/guide/opsguide.ui:576 kstars.kcfg:2529 +#: ekos/guide/opsguide.ui:524 ekos/guide/opsguide.ui:576 kstars.kcfg:2599 #, kde-format msgid "Minimum number of stars detected for SEP MultiStar to initialize." msgstr "" @@ -21039,57 +21641,57 @@ msgid "Robotic (Experimental)" msgstr "" -#: ekos/manager.cpp:223 +#: ekos/manager.cpp:227 #, fuzzy, kde-format msgctxt "@title:window" msgid "Ekos - %1 Profile" msgstr "انتقِ أسماء الملفات" -#: ekos/manager.cpp:233 +#: ekos/manager.cpp:237 #, kde-format msgid "Connection in progress. Click to abort." msgstr "" -#: ekos/manager.cpp:253 +#: ekos/manager.cpp:257 #, kde-format msgid "Logging" msgstr "السجلّ" -#: ekos/manager.cpp:340 +#: ekos/manager.cpp:344 #, kde-format msgid "Analyze" msgstr "حلل" -#: ekos/manager.cpp:604 +#: ekos/manager.cpp:608 #, kde-format msgctxt "@title:window" msgid "Ekos" msgstr "ايكوس" -#: ekos/manager.cpp:809 ekos/manager.cpp:835 +#: ekos/manager.cpp:813 ekos/manager.cpp:839 #, kde-format msgid "Ekos requires at least one CCD or Guider to operate." msgstr "" -#: ekos/manager.cpp:897 +#: ekos/manager.cpp:901 #, kde-format msgid "" "Ekos detected that PTP Camera is running and may prevent a Canon or Nikon " "camera from connecting to Ekos. Do you want to quit PTP Camera now?" msgstr "" -#: ekos/manager.cpp:898 +#: ekos/manager.cpp:902 #, fuzzy, kde-format #| msgid "Camera" msgid "PTP Camera" msgstr "آلة تصوير" -#: ekos/manager.cpp:913 +#: ekos/manager.cpp:917 #, fuzzy, kde-format msgid "Starting INDI services..." msgstr "اتصل أو اقطع الاتصال INDI جهاز." -#: ekos/manager.cpp:944 +#: ekos/manager.cpp:948 #, kde-format msgid "" "Ekos detected an instance of INDI server running. Do you wish to shut down " @@ -21097,81 +21699,81 @@ msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, indiServerGroup) -#: ekos/manager.cpp:946 indi/opsindi.ui:375 +#: ekos/manager.cpp:950 indi/opsindi.ui:375 #, fuzzy, kde-format msgid "INDI Server" msgstr "خادم INDI:" -#: ekos/manager.cpp:961 +#: ekos/manager.cpp:965 #, fuzzy, kde-format msgid "Connecting to remote INDI server at %1 on port %2 ..." msgstr "الإتصال إلى INDI مضيف عند يعمل منفذ failed." -#: ekos/manager.cpp:981 +#: ekos/manager.cpp:985 #, fuzzy, kde-format msgid "Failed to start profile on remote INDI Web Manager." msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: ekos/manager.cpp:985 +#: ekos/manager.cpp:989 #, kde-format msgid "Starting profile on remote INDI Web Manager..." msgstr "" -#: ekos/manager.cpp:998 +#: ekos/manager.cpp:1002 #, fuzzy, kde-format msgid "Establishing communication with remote INDI Web Manager..." msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: ekos/manager.cpp:1018 +#: ekos/manager.cpp:1022 #, kde-format msgid "Warning: INDI Web Manager is not online." msgstr "" -#: ekos/manager.cpp:1041 +#: ekos/manager.cpp:1045 #, fuzzy, kde-format msgid "INDI services started on port %1." msgstr "INDI الخادم نهائي منفذ" -#: ekos/manager.cpp:1044 +#: ekos/manager.cpp:1048 #, kde-format msgid "INDI services started on port %1. Please connect devices." msgstr "" -#: ekos/manager.cpp:1049 +#: ekos/manager.cpp:1053 #, kde-format msgid "" "INDI services started. Connection to remote INDI server %1:%2 is successful. " "Waiting for devices..." msgstr "" -#: ekos/manager.cpp:1059 +#: ekos/manager.cpp:1063 #, fuzzy, kde-format msgid "Failed to connect to local INDI server %1:%2" msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: ekos/manager.cpp:1061 +#: ekos/manager.cpp:1065 #, fuzzy, kde-format msgid "Failed to connect to remote INDI server %1:%2" msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: ekos/manager.cpp:1074 +#: ekos/manager.cpp:1078 #, fuzzy, kde-format #| msgid "Connect" msgid "Lost connection to local INDI server %1:%2" msgstr "اتصل" -#: ekos/manager.cpp:1076 +#: ekos/manager.cpp:1080 #, fuzzy, kde-format msgid "Lost connection to remote INDI server %1:%2" msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: ekos/manager.cpp:1153 +#: ekos/manager.cpp:1157 #, kde-format msgid "" "Failed to connect to %1. Please ensure device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1155 +#: ekos/manager.cpp:1159 #, kde-format msgid "" "Failed to connect to \n" @@ -21179,7 +21781,7 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1183 +#: ekos/manager.cpp:1187 #, kde-format msgid "" "Unable to establish:\n" @@ -21187,13 +21789,13 @@ "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1187 ekos/manager.cpp:1195 ekos/manager.cpp:1225 -#: ekos/manager.cpp:1233 +#: ekos/manager.cpp:1191 ekos/manager.cpp:1199 ekos/manager.cpp:1229 +#: ekos/manager.cpp:1237 #, fuzzy, kde-format msgid "Ekos startup error" msgstr "جاري التّحميل" -#: ekos/manager.cpp:1191 +#: ekos/manager.cpp:1195 #, kde-format msgid "" "Unable to establish the following devices:\n" @@ -21201,7 +21803,7 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1221 +#: ekos/manager.cpp:1225 #, kde-format msgid "" "Unable to remotely establish:\n" @@ -21209,7 +21811,7 @@ "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1229 +#: ekos/manager.cpp:1233 #, kde-format msgid "" "Unable to remotely establish the following devices:\n" @@ -21217,145 +21819,145 @@ "Please ensure each device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1284 +#: ekos/manager.cpp:1288 #, fuzzy, kde-format msgid "Connecting INDI devices..." msgstr "اتصل أو اقطع الاتصال INDI جهاز." -#: ekos/manager.cpp:1295 +#: ekos/manager.cpp:1299 #, fuzzy, kde-format msgid "Disconnecting INDI devices..." msgstr "اتصل أو اقطع الاتصال INDI جهاز." -#: ekos/manager.cpp:1333 +#: ekos/manager.cpp:1337 #, kde-format msgid "INDI services stopped." msgstr "" -#: ekos/manager.cpp:1407 +#: ekos/manager.cpp:1411 #, fuzzy, kde-format msgid "Remote devices established." msgstr "خادم" -#: ekos/manager.cpp:1409 +#: ekos/manager.cpp:1413 #, kde-format msgid "Remote devices established. Please connect devices." msgstr "" -#: ekos/manager.cpp:1470 +#: ekos/manager.cpp:1474 #, kde-format msgid "" "%1 failed to connect.\n" "Please ensure the device is connected and powered on." msgstr "" -#: ekos/manager.cpp:1477 +#: ekos/manager.cpp:1481 #, fuzzy, kde-format #| msgid "Disconnect" msgid "%1 is disconnected." msgstr "اقطع الاتصال" -#: ekos/manager.cpp:1496 ekos/manager.cpp:1505 ekos/manager.cpp:1538 +#: ekos/manager.cpp:1500 ekos/manager.cpp:1509 ekos/manager.cpp:1542 #: indi/indistd.cpp:689 #, kde-format msgid "%1 is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1513 +#: ekos/manager.cpp:1517 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 filter is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1522 +#: ekos/manager.cpp:1526 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 focuser is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1529 +#: ekos/manager.cpp:1533 #, fuzzy, kde-format #| msgid "%1 is online." msgid "Rotator %1 is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1545 +#: ekos/manager.cpp:1549 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 Weather is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1552 +#: ekos/manager.cpp:1556 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 GPS is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1561 +#: ekos/manager.cpp:1565 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 Dust cap is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1568 +#: ekos/manager.cpp:1572 #, fuzzy, kde-format #| msgid "%1 is online." msgid "%1 Light box is online." msgstr "%1 على الخط" -#: ekos/manager.cpp:1700 +#: ekos/manager.cpp:1706 #, fuzzy, kde-format msgid "%1 is offline." msgstr "%1 على الخط" -#: ekos/manager.cpp:1947 +#: ekos/manager.cpp:1953 #, kde-format msgctxt "Charge-Coupled Device" msgid "CCD" msgstr "سي سي دي" -#: ekos/manager.cpp:2217 +#: ekos/manager.cpp:2233 #, kde-format msgid "Guider port from %1 is ready." msgstr "" -#: ekos/manager.cpp:2406 +#: ekos/manager.cpp:2422 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to delete the profile?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/manager.cpp:2407 +#: ekos/manager.cpp:2423 #, kde-format msgid "Confirm Delete" msgstr "أكّد الحذف" -#: ekos/manager.cpp:2459 +#: ekos/manager.cpp:2475 #, kde-format msgid "Site location updated to %1." msgstr "" -#: ekos/manager.cpp:2461 +#: ekos/manager.cpp:2477 #, kde-format msgid "Failed to update site location to %1. City not found." msgstr "" -#: ekos/manager.cpp:2710 +#: ekos/manager.cpp:2726 #, kde-format msgid "Enabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2718 +#: ekos/manager.cpp:2734 #, kde-format msgid "Disabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2746 +#: ekos/manager.cpp:2762 #, kde-format msgid "Re-enabling debug logging for %1..." msgstr "" -#: ekos/manager.cpp:2758 +#: ekos/manager.cpp:2774 #, kde-format msgid "Re-disabling debug logging for %1..." msgstr "" @@ -21640,129 +22242,129 @@ msgid "Meridian Flip Status" msgstr "تلقائي عرض من التقاط" -#: ekos/mount/mount.cpp:94 +#: ekos/mount/mount.cpp:96 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to clear all mount configurations?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/mount/mount.cpp:95 +#: ekos/mount/mount.cpp:97 #, fuzzy, kde-format #| msgid "Configuration" msgid "Mount Configuration" msgstr "الإعدادات" #. i18n: ectx: property (text), widget (QPushButton, mountToolBoxB) -#: ekos/mount/mount.cpp:146 ekos/mount/mount.ui:582 +#: ekos/mount/mount.cpp:148 ekos/mount/mount.ui:582 #, fuzzy, kde-format msgid "Mount Control" msgstr "مونتريال" -#: ekos/mount/mount.cpp:371 +#: ekos/mount/mount.cpp:373 #, kde-format msgid "" "GPS driver detected. KStars and mount time and location settings are now " "synced to the GPS driver." msgstr "" -#: ekos/mount/mount.cpp:386 +#: ekos/mount/mount.cpp:388 #, kde-format msgid "GPS is detected. Do you want to switch time and location source to GPS?" msgstr "" -#: ekos/mount/mount.cpp:387 +#: ekos/mount/mount.cpp:389 #, fuzzy, kde-format msgid "GPS Settings" msgstr "إ&عدادات" -#: ekos/mount/mount.cpp:515 +#: ekos/mount/mount.cpp:517 #, fuzzy, kde-format #| msgid "Are you sure you want to remove the %1 client?" msgid "Are you sure you want to turn off mount tracking?" msgstr "هل تريد حذف العميل %1؟" -#: ekos/mount/mount.cpp:516 +#: ekos/mount/mount.cpp:518 #, fuzzy, kde-format #| msgid "Track" msgid "Mount Tracking" msgstr "تعقّب" -#: ekos/mount/mount.cpp:603 +#: ekos/mount/mount.cpp:605 #, kde-format msgid "" "Telescope altitude is below minimum altitude limit of %1. Aborting motion..." msgstr "" -#: ekos/mount/mount.cpp:619 +#: ekos/mount/mount.cpp:621 #, kde-format msgid "" "Telescope altitude is above maximum altitude limit of %1. Aborting motion..." msgstr "" -#: ekos/mount/mount.cpp:671 +#: ekos/mount/mount.cpp:673 #, kde-format msgid "" "Telescope hour angle is more than the maximum hour angle of %1. Aborting " "motion..." msgstr "" -#: ekos/mount/mount.cpp:813 +#: ekos/mount/mount.cpp:815 #, kde-format msgid "Meridian flip set inactive during polar alignment." msgstr "" -#: ekos/mount/mount.cpp:827 +#: ekos/mount/mount.cpp:829 #, kde-format msgid "Polar alignment motions finished, meridian flip activated." msgstr "" -#: ekos/mount/mount.cpp:850 +#: ekos/mount/mount.cpp:852 #, fuzzy, kde-format msgctxt "Message shown in Ekos Mount module" msgid "%1" msgstr "1" -#: ekos/mount/mount.cpp:1448 +#: ekos/mount/mount.cpp:1450 #, fuzzy, kde-format msgid "Alignment Model cleared." msgstr "العميل" -#: ekos/mount/mount.cpp:1452 +#: ekos/mount/mount.cpp:1454 #, fuzzy, kde-format msgid "Failed to clear Alignment Model." msgstr "مركّز على:" -#: ekos/mount/mount.cpp:1562 ekos/scheduler/scheduler.cpp:5364 +#: ekos/mount/mount.cpp:1564 ekos/scheduler/schedulerprocess.cpp:2141 #, kde-format msgid "Mount already parked." msgstr "" -#: ekos/mount/mount.cpp:1587 +#: ekos/mount/mount.cpp:1589 #, fuzzy, kde-format msgid "Parking time cannot be in the past." msgstr "إعداد المناظير" -#: ekos/mount/mount.cpp:1596 +#: ekos/mount/mount.cpp:1598 #, kde-format msgid "Parking time must be within 24 hours of current time." msgstr "" -#: ekos/mount/mount.cpp:1601 +#: ekos/mount/mount.cpp:1603 #, kde-format msgid "Warning! Parking time is more than 12 hours away." msgstr "" -#: ekos/mount/mount.cpp:1603 +#: ekos/mount/mount.cpp:1605 #, kde-format msgid "Caution: do not use Auto Park while scheduler is active." msgstr "" -#: ekos/mount/mount.cpp:1622 +#: ekos/mount/mount.cpp:1624 #, fuzzy, kde-format msgid "Parking timer is up." msgstr "إعداد المناظير" -#: ekos/mount/mount.cpp:1631 +#: ekos/mount/mount.cpp:1633 #, fuzzy, kde-format msgid "Starting auto park..." msgstr "فارمنغتون" @@ -21971,7 +22573,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, minAltLabel) #. i18n: ectx: whatsthis, entry (MinimumAltLimit), group (Mount) -#: ekos/mount/mount.ui:903 kstars.kcfg:1651 +#: ekos/mount/mount.ui:903 kstars.kcfg:1675 #, kde-format msgid "" "Minimum telescope altitude limit. If the telescope is below this limit, it " @@ -22406,7 +23008,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, weatherAlertSchedulerCB) #. i18n: ectx: property (text), widget (QCheckBox, weatherWarningSchedulerCB) #: ekos/observatory/observatory.ui:951 ekos/observatory/observatory.ui:1086 -#: ekos/scheduler/scheduler.cpp:2008 ekos/scheduler/scheduler.cpp:2034 +#: ekos/scheduler/scheduler.cpp:1796 ekos/scheduler/scheduler.cpp:1822 #, fuzzy, kde-format msgid "Stop Scheduler" msgstr "شغّل الساعة" @@ -22474,7 +23076,8 @@ msgid "Slaving deactivated." msgstr "أخرى" -#: ekos/observatory/observatorydomemodel.cpp:103 +#: ekos/observatory/observatorydomemodel.cpp:103 fitsviewer/fitstab.cpp:623 +#: fitsviewer/fitstab.cpp:642 #, kde-format msgid "Aborting..." msgstr "يجهض..." @@ -22573,7 +23176,7 @@ #. i18n: ectx: property (toolTip), widget (QRadioButton, kcfg_EkosTopIcons) #. i18n: ectx: label, entry (EkosTopIcons), group (Ekos) -#: ekos/opsekos.ui:116 kstars.kcfg:1558 +#: ekos/opsekos.ui:116 kstars.kcfg:1582 #, kde-format msgid "Ekos modules icons are placed on the top of pages" msgstr "أيقونات إيكوس توضع في أعلى الصفحة" @@ -22794,16 +23397,34 @@ msgid "Remember job progress" msgstr "تذكّر تسلسل العمل" +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_GreedyScheduling) +#: ekos/opsekos.ui:412 +#, fuzzy, kde-format +#| msgid "" +#| "

    Which guider application do you want to use?

    " +msgid "" +"

    When checked the scheduler tries to run lower priority " +"jobs when no higher priority job can run. Recommended.

    " +msgstr "" +"

    أي تطبيق للتوجيه تريد أن تستخدم؟

    " + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GreedyScheduling) +#: ekos/opsekos.ui:415 +#, kde-format +msgid "Use greedy scheduling" +msgstr "" + #. i18n: ectx: property (text), widget (QLabel, label_10) #. i18n: ectx: property (text), widget (QLabel, DefaultDSSImageSizeUnitLabel) #. i18n: ectx: property (text), widget (QLabel, DSSPaddingUnitLabel) -#: ekos/opsekos.ui:436 options/opsadvanced.ui:163 options/opsadvanced.ui:205 +#: ekos/opsekos.ui:449 options/opsadvanced.ui:163 options/opsadvanced.ui:205 #, kde-format msgid "arcminutes" msgstr "دقيقة قوسية" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_ForceAlignmentBeforeJob) -#: ekos/opsekos.ui:450 +#: ekos/opsekos.ui:463 #, kde-format msgid "" "If Align is enabled, scheduler would initiate a realignment procedure before " @@ -22811,7 +23432,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForceAlignmentBeforeJob) -#: ekos/opsekos.ui:453 +#: ekos/opsekos.ui:466 #, fuzzy, kde-format #| msgid "Reset Mount Model After Meridian Flip" msgid "Force re-alignment before re-starting jobs" @@ -22820,7 +23441,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_6) #. i18n: ectx: label, entry (AlignCheckFrequency), group (Scheduler) -#: ekos/opsekos.ui:460 kstars.kcfg:2853 +#: ekos/opsekos.ui:473 kstars.kcfg:2927 #, kde-format msgid "" "When calculating position after captures, compute it every Nth capture. Set " @@ -22828,20 +23449,20 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_6) -#: ekos/opsekos.ui:463 +#: ekos/opsekos.ui:476 #, fuzzy, kde-format msgid "Verify captured image position every" msgstr "إذا مؤكّد المريخ يعمل خريطة." #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelBeforeJob) -#: ekos/opsekos.ui:470 +#: ekos/opsekos.ui:483 #, fuzzy, kde-format msgid "Reset mount model before starting each job" msgstr "تلقائي عرض من التقاط" #. i18n: ectx: property (toolTip), widget (QLabel, label_8) #. i18n: ectx: label, entry (AlignCheckThreshold), group (Scheduler) -#: ekos/opsekos.ui:484 kstars.kcfg:2857 +#: ekos/opsekos.ui:497 kstars.kcfg:2931 #, kde-format msgid "" "If captured position exceeds target position by more this many arcminutes, " @@ -22849,19 +23470,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/opsekos.ui:487 +#: ekos/opsekos.ui:500 #, kde-format msgid "Reset pipeline if verified image delta exceeds" msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelOnAlignFail) -#: ekos/opsekos.ui:494 +#: ekos/opsekos.ui:507 #, kde-format msgid "Reset mount model on alignment failure" msgstr "عد للتعيين الابتدائي لأداة توجيه الحامل عند فشل ضبط الاستقامة" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_RealignAfterCalibrationFailure) -#: ekos/opsekos.ui:511 +#: ekos/opsekos.ui:524 #, kde-format msgid "" "

    If guiding calibration fails then restart alignment " @@ -22871,26 +23492,26 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_RealignAfterCalibrationFailure) -#: ekos/opsekos.ui:514 +#: ekos/opsekos.ui:527 #, fuzzy, kde-format msgid "Restart alignment on guiding calibration failure" msgstr "فارمنغتون" #. i18n: ectx: property (title), widget (QGroupBox, groupBox) #. i18n: ectx: property (title), widget (QGroupBox, ObsListMiscOptions) -#: ekos/opsekos.ui:559 options/opsadvanced.ui:924 +#: ekos/opsekos.ui:572 options/opsadvanced.ui:924 #, kde-format msgid "Miscellaneous" msgstr "متفرقات" #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_GuidingSettle) -#: ekos/opsekos.ui:612 +#: ekos/opsekos.ui:625 #, kde-format msgid "Wait this many seconds after guiding is resumed before starting capture" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label) -#: ekos/opsekos.ui:619 +#: ekos/opsekos.ui:632 #, kde-format msgid "" "Maximum acceptable difference between requested and measured temperature set " @@ -22902,14 +23523,14 @@ "بنجاح. " #. i18n: ectx: property (text), widget (QLabel, label) -#: ekos/opsekos.ui:622 +#: ekos/opsekos.ui:635 #, fuzzy, kde-format #| msgid "Temperature Threshold:" msgid "Temperature threshold:" msgstr "حد الحرارة" #. i18n: ectx: property (toolTip), widget (QLabel, label_13) -#: ekos/opsekos.ui:645 +#: ekos/opsekos.ui:658 #, kde-format msgid "" "Wait this many seconds after guiding is resumed to stabilize the guiding " @@ -22917,25 +23538,25 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_13) -#: ekos/opsekos.ui:648 +#: ekos/opsekos.ui:661 #, fuzzy, kde-format msgid "Guiding settle:" msgstr "خطوط ارشادية" #. i18n: ectx: property (toolTip), widget (QLabel, label_15) -#: ekos/opsekos.ui:655 +#: ekos/opsekos.ui:668 #, kde-format msgid "Cover or uncover telescope dialog timeout in seconds" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_15) -#: ekos/opsekos.ui:658 +#: ekos/opsekos.ui:671 #, fuzzy, kde-format msgid "Dialog timeout:" msgstr "المهلة:" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AlwaysResetSequenceWhenStarting) -#: ekos/opsekos.ui:687 +#: ekos/opsekos.ui:700 #, kde-format msgid "" "

    When starting to process a sequence list, reset all " @@ -22944,44 +23565,44 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AlwaysResetSequenceWhenStarting) -#: ekos/opsekos.ui:690 +#: ekos/opsekos.ui:703 #, kde-format msgid "Always reset sequence when starting" msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ResetMountModelAfterMeridian) -#: ekos/opsekos.ui:700 +#: ekos/opsekos.ui:713 #, kde-format msgid "Reset mount model after meridian flip" msgstr "" "عد للتعيين الابتدائي لأداة توجيه الحامل بعد عملية عكس الثقل عند خط الزوال" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForcedFlip) -#: ekos/opsekos.ui:707 +#: ekos/opsekos.ui:720 #, kde-format msgid "Use flip command if supported by mount" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_useSummaryPreview) -#: ekos/opsekos.ui:719 +#: ekos/opsekos.ui:732 #, kde-format msgid "Display received FITS in the Summary screen preview window." msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_useSummaryPreview) -#: ekos/opsekos.ui:722 +#: ekos/opsekos.ui:735 #, kde-format msgid "Summary screen preview" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) -#: ekos/opsekos.ui:747 +#: ekos/opsekos.ui:760 #, kde-format msgid "DSLR" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_ForceDSLRPresets) -#: ekos/opsekos.ui:765 +#: ekos/opsekos.ui:778 #, kde-format msgid "" "

    Force exposure times to align with DSLR exposure " @@ -22990,46 +23611,46 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ForceDSLRPresets) -#: ekos/opsekos.ui:768 +#: ekos/opsekos.ui:781 #, kde-format msgid "Force DSLR presets" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_useDSLRImageViewer) -#: ekos/opsekos.ui:775 +#: ekos/opsekos.ui:788 #, fuzzy, kde-format msgid "Display received DSLR images in the Image Viewer" msgstr "مرحبا إلى نجوم ك المستعرض" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_useDSLRImageViewer) -#: ekos/opsekos.ui:778 +#: ekos/opsekos.ui:791 #, fuzzy, kde-format #| msgid "Image Viewer" msgid "DSLR image viewer" msgstr "عارض الصور" #. i18n: ectx: property (toolTip), widget (QPushButton, clearDSLRInfoB) -#: ekos/opsekos.ui:785 +#: ekos/opsekos.ui:798 #, kde-format msgid "Clear saved DSLR sizes" msgstr "" #. i18n: ectx: property (text), widget (QPushButton, clearDSLRInfoB) -#: ekos/opsekos.ui:788 +#: ekos/opsekos.ui:801 #, fuzzy, kde-format #| msgid "Clear Row" msgid "Clear DSLR Info" msgstr "امسح السطر" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/opsekos.ui:821 +#: ekos/opsekos.ui:834 #, fuzzy, kde-format #| msgid "Frequency:" msgid "In-Sequence Focus" msgstr "التّردد:" #. i18n: ectx: property (toolTip), widget (QLabel, label_5) -#: ekos/opsekos.ui:881 +#: ekos/opsekos.ui:894 #, kde-format msgid "" "

    Set HFR Threshold percentage gain. When an autofocus " @@ -23042,20 +23663,20 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_5) -#: ekos/opsekos.ui:884 +#: ekos/opsekos.ui:897 #, fuzzy, kde-format #| msgid "HFR Threshold:" msgid "HFR threshold modifier:" msgstr "حد نصف قطر تناقص السطوع من مركز النجم (HFR): " #. i18n: ectx: property (toolTip), widget (QLabel, label_11) -#: ekos/opsekos.ui:891 +#: ekos/opsekos.ui:904 #, kde-format msgid "Run in-sequence HFR check after this many frames." msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_11) -#: ekos/opsekos.ui:894 +#: ekos/opsekos.ui:907 #, fuzzy, kde-format #| msgid "Frequency:" msgid "In-sequence HFR check:" @@ -23063,13 +23684,13 @@ #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_InSequenceCheckFrames) #. i18n: ectx: label, entry (InSequenceCheckFrames), group (Capture) -#: ekos/opsekos.ui:901 kstars.kcfg:1846 +#: ekos/opsekos.ui:914 kstars.kcfg:1870 #, kde-format msgid "Run In-Sequence HFR check after this many frames." msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_UseMedianFocus) -#: ekos/opsekos.ui:916 +#: ekos/opsekos.ui:929 #, kde-format msgid "" "

    Calculate median focus value after each autofocus " @@ -23080,13 +23701,13 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseMedianFocus) -#: ekos/opsekos.ui:919 +#: ekos/opsekos.ui:932 #, kde-format msgid "Use median focus" msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_SaveHFRToFile) -#: ekos/opsekos.ui:926 +#: ekos/opsekos.ui:939 #, kde-format msgid "" "

    In-sequence HFR threshold value controls when the " @@ -23100,7 +23721,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_SaveHFRToFile) -#: ekos/opsekos.ui:929 +#: ekos/opsekos.ui:942 #, kde-format msgid "Save sequence HFR value to file" msgstr "" @@ -23161,7 +23782,8 @@ msgstr "منفذ مدير INDI للشبكة" #. i18n: ectx: property (title), widget (QGroupBox, profileGroup) -#: ekos/profileeditor.ui:32 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverProfileLabel) +#: ekos/profileeditor.ui:32 fitsviewer/platesolve.ui:360 #, kde-format msgid "Profile" msgstr "منظومة الأجهزة" @@ -23997,7 +24619,7 @@ "واختر الأجهزة" #: ekos/scheduler/framingassistant.cpp:539 -#: ekos/scheduler/framingassistantui.cpp:555 +#: ekos/scheduler/framingassistantui.cpp:556 #, fuzzy, kde-format #| msgid "Scheduler" msgid " Scheduler job" @@ -24010,7 +24632,7 @@ msgstr[5] "المجدول" #: ekos/scheduler/framingassistant.cpp:541 -#: ekos/scheduler/framingassistantui.cpp:557 +#: ekos/scheduler/framingassistantui.cpp:558 #, kde-format msgid " (first only)" msgstr "" @@ -24724,47 +25346,47 @@ msgid "Create scheduler jobs to execute the mosaic plan" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:692 ekos/scheduler/scheduler.cpp:1097 +#: ekos/scheduler/framingassistantui.cpp:694 ekos/scheduler/scheduler.cpp:934 #, fuzzy, kde-format #| msgid "Frequency:" msgctxt "@title:window" msgid "Select Sequence Queue" msgstr "التّردد:" -#: ekos/scheduler/framingassistantui.cpp:694 ekos/scheduler/scheduler.cpp:1099 +#: ekos/scheduler/framingassistantui.cpp:696 ekos/scheduler/scheduler.cpp:936 #, kde-format msgid "Ekos Sequence Queue (*.esq)" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:706 +#: ekos/scheduler/framingassistantui.cpp:708 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Mosaic Import" msgstr "انتقِ a نجم" -#: ekos/scheduler/framingassistantui.cpp:708 +#: ekos/scheduler/framingassistantui.cpp:710 #, kde-format msgid "Telescopius CSV (*.csv)" msgstr "" -#: ekos/scheduler/framingassistantui.cpp:767 +#: ekos/scheduler/framingassistantui.cpp:769 #, kde-format msgid "Import must contain center coordinates." msgstr "" -#: ekos/scheduler/framingassistantui.cpp:846 +#: ekos/scheduler/framingassistantui.cpp:848 #, fuzzy, kde-format #| msgid "Default FITS directory:" msgctxt "@title:window" msgid "Select Jobs Directory" msgstr "دليل FITS الافتراضي:" -#: ekos/scheduler/greedyscheduler.cpp:158 +#: ekos/scheduler/greedyscheduler.cpp:159 #, fuzzy, kde-format msgid "Job '%1' has no more batches remaining." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:480 +#: ekos/scheduler/scheduler.cpp:309 #, kde-format msgid "" "Job scheduler list.\n" @@ -24772,31 +25394,31 @@ "Double click to edit a job with the left-hand fields." msgstr "" -#: ekos/scheduler/scheduler.cpp:487 +#: ekos/scheduler/scheduler.cpp:316 #, kde-format msgid "" "Remove selected job from the observation list.\n" "Job properties are copied in the edition fields before removal." msgstr "" -#: ekos/scheduler/scheduler.cpp:491 +#: ekos/scheduler/scheduler.cpp:320 #, fuzzy, kde-format #| msgid "Clear all selected items in the list" msgid "Move selected job one line up in the list.\n" msgstr "امسح جميع الخيارات من القائمة" -#: ekos/scheduler/scheduler.cpp:494 +#: ekos/scheduler/scheduler.cpp:323 #, fuzzy, kde-format #| msgid "Clear all selected items in the list" msgid "Move selected job one line down in the list.\n" msgstr "امسح جميع الخيارات من القائمة" -#: ekos/scheduler/scheduler.cpp:498 +#: ekos/scheduler/scheduler.cpp:327 #, kde-format msgid "Reset state and force reevaluation of all observation jobs." msgstr "" -#: ekos/scheduler/scheduler.cpp:502 +#: ekos/scheduler/scheduler.cpp:331 #, kde-format msgid "" "Reset state and sort observation jobs per altitude and movement in sky, " @@ -24807,86 +25429,86 @@ "evaluates jobs." msgstr "" -#: ekos/scheduler/scheduler.cpp:733 ekos/scheduler/scheduler.cpp:6145 +#: ekos/scheduler/scheduler.cpp:570 ekos/scheduler/scheduler.cpp:3925 #, kde-format msgid "" "Warning: The Classic scheduler algorithm has been retired. Switching you to " "the Greedy algorithm." msgstr "" -#: ekos/scheduler/scheduler.cpp:974 +#: ekos/scheduler/scheduler.cpp:811 #, fuzzy, kde-format #| msgid "Open FITS..." msgctxt "@title:window" msgid "Select FITS/XISF Image" msgstr "فتح FITS..." -#: ekos/scheduler/scheduler.cpp:1028 +#: ekos/scheduler/scheduler.cpp:865 #, kde-format msgid "FITS header: cannot find OBJCTRA (%1)." msgstr "" -#: ekos/scheduler/scheduler.cpp:1047 +#: ekos/scheduler/scheduler.cpp:884 #, kde-format msgid "FITS header: cannot find OBJCTDEC (%1)." msgstr "" -#: ekos/scheduler/scheduler.cpp:1106 +#: ekos/scheduler/scheduler.cpp:944 #, fuzzy, kde-format msgctxt "@title:window" msgid "Select Startup Script" msgstr "انتقِ a نجم" -#: ekos/scheduler/scheduler.cpp:1108 ekos/scheduler/scheduler.cpp:1122 +#: ekos/scheduler/scheduler.cpp:946 ekos/scheduler/scheduler.cpp:961 #, kde-format msgid "Script (*)" msgstr "سكربت (*)" -#: ekos/scheduler/scheduler.cpp:1120 +#: ekos/scheduler/scheduler.cpp:959 #, fuzzy, kde-format #| msgid "Select a category:" msgctxt "@title:window" msgid "Select Shutdown Script" msgstr "اختر تصنيفاً:" -#: ekos/scheduler/scheduler.cpp:1222 +#: ekos/scheduler/scheduler.cpp:993 #, kde-format msgid "Warning: You cannot add or modify a job while the scheduler is running." msgstr "" -#: ekos/scheduler/scheduler.cpp:1228 +#: ekos/scheduler/scheduler.cpp:999 #, fuzzy, kde-format msgid "Warning: Target name is required." msgstr "ظاهر:" -#: ekos/scheduler/scheduler.cpp:1234 +#: ekos/scheduler/scheduler.cpp:1005 #, kde-format msgid "Warning: Sequence file is required." msgstr "" -#: ekos/scheduler/scheduler.cpp:1241 +#: ekos/scheduler/scheduler.cpp:1012 #, fuzzy, kde-format msgid "Warning: Target coordinates are required." msgstr "ظاهر:" -#: ekos/scheduler/scheduler.cpp:1251 +#: ekos/scheduler/scheduler.cpp:1022 #, fuzzy, kde-format msgid "Warning: RA value %1 is invalid." msgstr "نهاية التاريخ." -#: ekos/scheduler/scheduler.cpp:1257 +#: ekos/scheduler/scheduler.cpp:1028 #, fuzzy, kde-format msgid "Warning: DEC value %1 is invalid." msgstr "نهاية التاريخ." -#: ekos/scheduler/scheduler.cpp:1359 +#: ekos/scheduler/scheduler.cpp:1128 #, kde-format msgid "" "Warning: job '%1' at row %2 has a duplicate target at row %3, the scheduler " "may consider the same storage for captures." msgstr "" -#: ekos/scheduler/scheduler.cpp:1367 +#: ekos/scheduler/scheduler.cpp:1136 #, kde-format msgid "" "Warning: jobs '%1' at row %2 and %3 probably require a different repeat " @@ -24894,12 +25516,12 @@ "disable option 'Remember job progress')" msgstr "" -#: ekos/scheduler/scheduler.cpp:1375 +#: ekos/scheduler/scheduler.cpp:1144 #, kde-format msgid "Skipped checking for duplicates." msgstr "" -#: ekos/scheduler/scheduler.cpp:1539 +#: ekos/scheduler/scheduler.cpp:1334 #, fuzzy, kde-format #| msgctxt "" #| "%1 magnitude of object, %2 type of sky object (planet, asteroid etc), %3 " @@ -24908,372 +25530,218 @@ msgid "%1 %2 %3" msgstr "%3 %2 قدر سطوعه: %1 في" -#: ekos/scheduler/scheduler.cpp:1549 +#: ekos/scheduler/scheduler.cpp:1344 #, kde-format msgid "Warning: you cannot add or modify a job while the scheduler is running." msgstr "" -#: ekos/scheduler/scheduler.cpp:1612 +#: ekos/scheduler/scheduler.cpp:1407 #, kde-format msgid "Use edition fields to create a new job in the observation list." msgstr "" -#: ekos/scheduler/scheduler.cpp:1877 +#: ekos/scheduler/scheduler.cpp:1672 #, fuzzy, kde-format msgid "Job '%1' has not been processed upon scheduler stop, marking aborted." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:1884 +#: ekos/scheduler/scheduler.cpp:1679 #, kde-format msgid "Scheduler aborted." msgstr "أُجهض المجدول." -#: ekos/scheduler/scheduler.cpp:1943 +#: ekos/scheduler/scheduler.cpp:1731 #, kde-format msgid "Scheduler is in shutdown until next job is ready" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, startB) -#: ekos/scheduler/scheduler.cpp:1969 ekos/scheduler/scheduler.ui:1124 +#: ekos/scheduler/scheduler.cpp:1757 ekos/scheduler/scheduler.ui:1124 #, fuzzy, kde-format msgid "Start Scheduler" msgstr "شغّل الساعة" -#: ekos/scheduler/scheduler.cpp:1990 +#: ekos/scheduler/scheduler.cpp:1777 #, fuzzy, kde-format msgid "Warning: startup script URL %1 is not valid." msgstr "نهاية التاريخ." -#: ekos/scheduler/scheduler.cpp:1998 +#: ekos/scheduler/scheduler.cpp:1785 #, kde-format msgid "Warning: shutdown script URL %1 is not valid." msgstr "" -#: ekos/scheduler/scheduler.cpp:2027 +#: ekos/scheduler/scheduler.cpp:1815 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler started." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:2047 +#: ekos/scheduler/scheduler.cpp:1835 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler resuming." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:2060 +#: ekos/scheduler/scheduler.cpp:1848 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler pause planned..." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:2064 +#: ekos/scheduler/scheduler.cpp:1852 #, fuzzy, kde-format msgid "Resume Scheduler" msgstr "Schuyler" -#: ekos/scheduler/scheduler.cpp:2073 +#: ekos/scheduler/scheduler.cpp:1861 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler paused." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:2095 +#: ekos/scheduler/scheduler.cpp:1883 #, kde-format msgid "No job running" msgstr "" -#: ekos/scheduler/scheduler.cpp:2163 +#: ekos/scheduler/scheduler.cpp:1953 #, kde-format msgid "No jobs left in the scheduler queue after evaluating." msgstr "" -#: ekos/scheduler/scheduler.cpp:2171 +#: ekos/scheduler/scheduler.cpp:1961 #, kde-format msgid "" "Only aborted jobs left in the scheduler queue after evaluating, rescheduling " "those." msgstr "" -#: ekos/scheduler/scheduler.cpp:2185 +#: ekos/scheduler/scheduler.cpp:1975 #, fuzzy, kde-format #| msgid "Add to Ekos Scheduler" msgid "No jobs scheduled." msgstr "أضف إلى مجدول إيكوس" -#: ekos/scheduler/scheduler.cpp:2199 +#: ekos/scheduler/scheduler.cpp:1989 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler is awake." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:2205 +#: ekos/scheduler/scheduler.cpp:1995 #, kde-format msgid "Scheduler is awake. Jobs shall be started when ready..." msgstr "" -#: ekos/scheduler/scheduler.cpp:2207 +#: ekos/scheduler/scheduler.cpp:1997 #, kde-format msgid "Scheduler is awake. Jobs shall be started when scheduler is resumed." msgstr "" -#: ekos/scheduler/scheduler.cpp:2271 +#: ekos/scheduler/scheduler.cpp:2061 #, fuzzy, kde-format msgid "Ekos job started (%1)" msgstr "جاري التّحميل" -#: ekos/scheduler/scheduler.cpp:2310 -#, fuzzy, kde-format -msgid "Ekos started." -msgstr "جاري التّحميل" - -#: ekos/scheduler/scheduler.cpp:2319 -#, fuzzy, kde-format -msgid "Starting Ekos failed. Retrying..." -msgstr "لم أتمكن من فتح الملف %1." - -#: ekos/scheduler/scheduler.cpp:2325 -#, fuzzy, kde-format -msgid "Starting Ekos failed." -msgstr "أخرى" - -#: ekos/scheduler/scheduler.cpp:2336 -#, fuzzy, kde-format -msgid "Starting Ekos timed out. Retrying..." -msgstr "لم أتمكن من فتح الملف %1." - -#: ekos/scheduler/scheduler.cpp:2348 -#, fuzzy, kde-format -msgid "Starting Ekos timed out." -msgstr "جاري التّحميل" - -#: ekos/scheduler/scheduler.cpp:2359 -#, fuzzy, kde-format -msgid "Ekos stopped." -msgstr "جاري التّحميل" - -#: ekos/scheduler/scheduler.cpp:2410 -#, fuzzy, kde-format -msgid "INDI devices connected." -msgstr "ضبط INDI s جهاز اتصال منفذ." - -#: ekos/scheduler/scheduler.cpp:2417 -#, kde-format -msgid "One or more INDI devices failed to connect. Retrying..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2423 -#, kde-format -msgid "" -"One or more INDI devices failed to connect. Check INDI control panel for " -"details." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2432 -#, kde-format -msgid "One or more INDI devices timed out. Retrying..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2439 -#, kde-format -msgid "" -"One or more INDI devices timed out. Check INDI control panel for details." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2450 -#, fuzzy, kde-format -msgid "INDI devices disconnected." -msgstr "ضبط INDI s جهاز اتصال منفذ." - -#: ekos/scheduler/scheduler.cpp:2466 -#, kde-format -msgid "Warning: dome device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2471 -#, kde-format -msgid "Dome unpark required but dome is not yet ready." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2481 -#, kde-format -msgid "Warning: mount device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2496 -#, kde-format -msgid "Warning: cap device not ready after timeout, attempting to recover..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2547 -#, kde-format -msgid "Observatory is in the startup process" -msgstr "دخل المرصد عمليّة الإعداد" - -#: ekos/scheduler/scheduler.cpp:2560 -#, kde-format -msgid "Ekos is already started, skipping startup script..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2657 +#: ekos/scheduler/scheduler.cpp:2076 #, kde-format msgid "Observatory is in the shutdown process" msgstr "دخل المرصد عمليّة الإطفاء" -#: ekos/scheduler/scheduler.cpp:2673 -#, fuzzy, kde-format -msgid "Warming up CCD..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:2703 -#, kde-format -msgid "Warning: Bypassing parking procedures, no INDI connection." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2827 -#, kde-format -msgid "park/unpark wait procedure failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2838 -#, fuzzy, kde-format -msgid "Executing script %1..." -msgstr "يعمل برنامج نصي 1" - -#: ekos/scheduler/scheduler.cpp:2873 -#, kde-format -msgid "Startup script failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2878 -#, kde-format -msgid "Shutdown script failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2908 -#, fuzzy, kde-format -msgid "Shutdown complete." -msgstr "مكتمل" - -#: ekos/scheduler/scheduler.cpp:2910 -#, kde-format -msgid "Shutdown procedure failed, aborting..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:2983 +#: ekos/scheduler/scheduler.cpp:2161 #, kde-format msgid "Starting job sequence iteration #%1" msgstr "" -#: ekos/scheduler/scheduler.cpp:3108 ekos/scheduler/scheduler.cpp:6917 +#: ekos/scheduler/scheduler.cpp:2291 ekos/scheduler/schedulerprocess.cpp:1806 #, fuzzy, kde-format msgid "Warning: job '%1' alignment procedure failed, marking aborted." msgstr "فارمنغتون" -#: ekos/scheduler/scheduler.cpp:3136 +#: ekos/scheduler/scheduler.cpp:2319 #, fuzzy, kde-format msgid "Warning: job '%1' capture procedure failed, marking aborted." msgstr "فارمنغتون" -#: ekos/scheduler/scheduler.cpp:3163 ekos/scheduler/scheduler.cpp:7149 +#: ekos/scheduler/scheduler.cpp:2346 ekos/scheduler/schedulerprocess.cpp:1929 #, fuzzy, kde-format msgid "Warning: job '%1' focusing procedure failed, marking aborted." msgstr "فارمنغتون" -#: ekos/scheduler/scheduler.cpp:3187 ekos/scheduler/scheduler.cpp:6990 +#: ekos/scheduler/scheduler.cpp:2370 ekos/scheduler/schedulerprocess.cpp:1877 #, fuzzy, kde-format msgid "Warning: job '%1' guiding procedure failed, marking aborted." msgstr "فارمنغتون" -#: ekos/scheduler/scheduler.cpp:3213 +#: ekos/scheduler/scheduler.cpp:2396 #, fuzzy, kde-format msgid "" "Warning: job '%1' lost connection to the mount, attempting to reconnect." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:3233 +#: ekos/scheduler/scheduler.cpp:2416 #, fuzzy, kde-format msgid "Warning: job '%1' lost connection to the dome, attempting to reconnect." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:3271 +#: ekos/scheduler/scheduler.cpp:2454 #, kde-format msgid "Guiding already running, directly start capturing." msgstr "" -#: ekos/scheduler/scheduler.cpp:3283 +#: ekos/scheduler/scheduler.cpp:2466 #, kde-format msgid "" "Job '%1' is proceeding directly to capture stage because only calibration " "frames are pending." msgstr "" -#: ekos/scheduler/scheduler.cpp:3452 +#: ekos/scheduler/scheduler.cpp:2582 #, fuzzy, kde-format msgctxt "@title:window" msgid "Open Ekos Scheduler List" msgstr "الملاحظة قائمة" -#: ekos/scheduler/scheduler.cpp:3803 +#: ekos/scheduler/scheduler.cpp:2931 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save Ekos Scheduler List" msgstr "الملاحظة قائمة" -#: ekos/scheduler/scheduler.cpp:3822 +#: ekos/scheduler/scheduler.cpp:2950 #, fuzzy, kde-format msgid "Failed to save scheduler list" msgstr "فشل في تحميل الصورة " -#: ekos/scheduler/scheduler.cpp:4013 -#, fuzzy, kde-format -#| msgid "FITS file saved to %1" -msgid "Scheduler list saved to %1" -msgstr "تم حفظ ملف FITS الى %1" - -#: ekos/scheduler/scheduler.cpp:4056 -#, fuzzy, kde-format -msgid "Job '%1' is slewing to target." -msgstr "اليوم && الموقع" - -#: ekos/scheduler/scheduler.cpp:4099 -#, kde-format -msgid "Warning: job '%1' is unable to proceed with autofocus, not supported." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4182 -#, kde-format -msgid "Job '%1' is focusing." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4232 +#: ekos/scheduler/scheduler.cpp:3013 #, kde-format msgid "Job '%1' is terminated due to errors." msgstr "" -#: ekos/scheduler/scheduler.cpp:4234 +#: ekos/scheduler/scheduler.cpp:3015 #, kde-format msgid "Job '%1' is aborted." msgstr "" -#: ekos/scheduler/scheduler.cpp:4247 +#: ekos/scheduler/scheduler.cpp:3028 #, kde-format msgid "Waiting %1 seconds to restart job '%2'." msgstr "" -#: ekos/scheduler/scheduler.cpp:4253 +#: ekos/scheduler/scheduler.cpp:3034 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler waits for a retry." msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:4290 +#: ekos/scheduler/scheduler.cpp:3071 #, fuzzy, kde-format #| msgid "%1 is online." msgid "Job '%1' is complete." msgstr "%1 على الخط" -#: ekos/scheduler/scheduler.cpp:4335 +#: ekos/scheduler/scheduler.cpp:3116 #, fuzzy, kde-format msgid "Job '%1' is complete after #%2 batch." msgid_plural "Job '%1' is complete after #%2 batches." @@ -25284,7 +25752,7 @@ msgstr[4] "مكتمل" msgstr[5] "مكتمل" -#: ekos/scheduler/scheduler.cpp:4384 ekos/scheduler/scheduler.cpp:4427 +#: ekos/scheduler/scheduler.cpp:3165 ekos/scheduler/scheduler.cpp:3208 #, kde-format msgid "Job '%1' is repeating, #%2 batch remaining." msgid_plural "Job '%1' is repeating, #%2 batches remaining." @@ -25295,12 +25763,12 @@ msgstr[4] "" msgstr[5] "" -#: ekos/scheduler/scheduler.cpp:4431 +#: ekos/scheduler/scheduler.cpp:3212 #, kde-format msgid "Job '%1' is repeating, looping indefinitely." msgstr "" -#: ekos/scheduler/scheduler.cpp:4451 +#: ekos/scheduler/scheduler.cpp:3232 #, kde-format msgid "Job '%1' stopping, reached completion time with #%2 batch done." msgid_plural "" @@ -25312,7 +25780,7 @@ msgstr[4] "" msgstr[5] "" -#: ekos/scheduler/scheduler.cpp:4481 +#: ekos/scheduler/scheduler.cpp:3262 #, kde-format msgid "Job '%1' completed #%2 batch before completion time, restarted." msgid_plural "" @@ -25324,557 +25792,162 @@ msgstr[4] "" msgstr[5] "" -#: ekos/scheduler/scheduler.cpp:4526 -#, fuzzy, kde-format -msgid "Warning: job '%1' target FITS file does not exist." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:4539 -#, kde-format -msgid "Warning: job '%1' loadAndSlew request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4550 -#, fuzzy, kde-format -msgid "Warning: job '%1' loadAndSlew request failed." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:4557 -#, fuzzy, kde-format -msgid "Job '%1' is plate solving %2." -msgstr "جاري التّحميل." - -#: ekos/scheduler/scheduler.cpp:4572 -#, kde-format -msgid "Warning: job '%1' setTargetCoords request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4589 -#, kde-format -msgid "" -"Warning: job '%1' setTargetPositionAngle request received DBUS error: %2" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4603 -#, fuzzy, kde-format -msgid "Warning: job '%1' captureAndSolve request received DBUS error: %2" -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:4614 -#, fuzzy, kde-format -msgid "Warning: job '%1' captureAndSolve request failed." -msgstr "العميل" - -#: ekos/scheduler/scheduler.cpp:4620 -#, fuzzy, kde-format -msgid "Job '%1' is capturing and plate solving." -msgstr "جاري التّحميل." - -#: ekos/scheduler/scheduler.cpp:4635 -#, fuzzy, kde-format -msgid "Guiding already running for %1 ..." -msgstr "جاري التّحميل" - -#: ekos/scheduler/scheduler.cpp:4663 -#, fuzzy, kde-format -msgid "Starting guiding procedure for %1 ..." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:4747 -#, kde-format -msgid "Ekos job (%1) - Capture started" -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4750 -#, kde-format -msgid "Job '%1' capture is in progress (batch #%2)..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:4752 -#, fuzzy, kde-format -msgid "Job '%1' capture is in progress..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:4978 +#: ekos/scheduler/scheduler.cpp:3469 #, fuzzy, kde-format msgid "Warning: job '%1' has inaccessible sequence '%2', marking invalid." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:5049 +#: ekos/scheduler/scheduler.cpp:3541 #, kde-format msgid "" "Warning: Job '%1' has its focus step disabled, periodic and/or HFR " "procedures currently set in its sequence will not occur." msgstr "" -#: ekos/scheduler/scheduler.cpp:5077 +#: ekos/scheduler/scheduler.cpp:3569 #, kde-format msgid "Job '%1' %2x%3\" %4" msgstr "" -#: ekos/scheduler/scheduler.cpp:5338 -#, kde-format -msgid "Mount park requested but no mounts detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5397 -#, fuzzy, kde-format -msgid "Parking mount in progress..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:5410 -#, kde-format -msgid "Mount unpark requested but no mounts detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5437 -#, kde-format -msgid "Mount already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5514 -#, kde-format -msgid "Mount parked." -msgstr "رُكن الحامل." - -#: ekos/scheduler/scheduler.cpp:5529 -#, kde-format -msgid "Mount unparked." -msgstr "أُلغي ركن الحامل." - -#: ekos/scheduler/scheduler.cpp:5541 -#, kde-format -msgid "" -"Warning: mount unpark operation timed out on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5547 -#, kde-format -msgid "Warning: mount unpark operation timed out on last attempt." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5561 -#, kde-format -msgid "" -"Warning: mount park operation timed out on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5567 -#, kde-format -msgid "Warning: mount park operation timed out on last attempt." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5579 ekos/scheduler/scheduler.cpp:5607 -#, fuzzy, kde-format -msgid "Mount unparking error." -msgstr "Mount Ekar" - -#: ekos/scheduler/scheduler.cpp:5587 -#, kde-format -msgid "" -"Warning: mount park operation failed on attempt %1/%2. Restarting " -"operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5593 ekos/scheduler/scheduler.cpp:5601 -#, fuzzy, kde-format -msgid "Mount parking error." -msgstr "Mount Ekar" - -#: ekos/scheduler/scheduler.cpp:5697 -#, kde-format -msgid "Dome park requested but no domes detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5722 -#, fuzzy, kde-format -msgid "Parking dome..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:5728 -#, kde-format -msgid "Dome already parked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5738 -#, kde-format -msgid "Dome unpark requested but no domes detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5760 -#, fuzzy, kde-format -msgid "Unparking dome..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:5766 -#, kde-format -msgid "Dome already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5798 -#, kde-format -msgid "Dome parked." -msgstr "رُكنت القبّة." - -#: ekos/scheduler/scheduler.cpp:5809 -#, kde-format -msgid "Dome unparked." -msgstr "أُلغي ركن القبّة." - -#: ekos/scheduler/scheduler.cpp:5821 ekos/scheduler/scheduler.cpp:6016 -#, kde-format -msgid "Operation timeout. Restarting operation..." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5836 -#, fuzzy, kde-format -msgid "Dome parking failed. Restarting operation..." -msgstr "لم أتمكن من فتح الملف %1." - -#: ekos/scheduler/scheduler.cpp:5841 -#, fuzzy, kde-format -msgid "Dome parking error." -msgstr "القبة الجدول" - -#: ekos/scheduler/scheduler.cpp:5850 -#, fuzzy, kde-format -msgid "Dome unparking failed. Restarting operation..." -msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." - -#: ekos/scheduler/scheduler.cpp:5855 -#, fuzzy, kde-format -msgid "Dome unparking error." -msgstr "القبة الجدول" - -#: ekos/scheduler/scheduler.cpp:5893 -#, kde-format -msgid "Dust cover park requested but no dust covers detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5917 -#, fuzzy, kde-format -msgid "Parking Cap..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:5923 -#, kde-format -msgid "Cap already parked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5932 -#, kde-format -msgid "Dust cover unpark requested but no dust covers detected." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5956 -#, fuzzy, kde-format -msgid "Unparking cap..." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:5962 -#, kde-format -msgid "Cap already unparked." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:5994 -#, fuzzy, kde-format -msgid "Cap parked." -msgstr "القبة الجدول" - -#: ekos/scheduler/scheduler.cpp:6004 -#, fuzzy, kde-format -msgid "Cap unparked." -msgstr "Mount Ekar" - -#: ekos/scheduler/scheduler.cpp:6029 -#, fuzzy, kde-format -msgid "Cap parking error." -msgstr "القبة الجدول" - -#: ekos/scheduler/scheduler.cpp:6034 -#, fuzzy, kde-format -msgid "Cap unparking error." -msgstr "Mount Ekar" - -#: ekos/scheduler/scheduler.cpp:6254 +#: ekos/scheduler/scheduler.cpp:4034 #, kde-format msgid "" "Turning off astronomial twilight check may cause the observatory to run " "during daylight. This can cause irreversible damage to your equipment!" msgstr "" -#: ekos/scheduler/scheduler.cpp:6256 +#: ekos/scheduler/scheduler.cpp:4036 #, kde-format msgid "Astronomial Twilight Warning" msgstr "" -#: ekos/scheduler/scheduler.cpp:6270 -#, fuzzy, kde-format -msgid "Manual startup procedure completed successfully." -msgstr "انتقِ إدخال الأسس" - -#: ekos/scheduler/scheduler.cpp:6272 -#, kde-format -msgid "Manual startup procedure terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6287 -#, fuzzy, kde-format -#| msgid "Are you sure you want to remove the %1 client?" -msgid "Warning: executing startup procedure manually..." -msgstr "هل تريد حذف العميل %1؟" - -#: ekos/scheduler/scheduler.cpp:6296 -#, fuzzy, kde-format -#| msgid "Are you sure you want to remove the %1 client?" -msgid "Are you sure you want to execute the startup procedure manually?" -msgstr "هل تريد حذف العميل %1؟" - -#: ekos/scheduler/scheduler.cpp:6340 -#, fuzzy, kde-format -msgid "Startup procedure terminated." -msgstr "شغّل الساعة" - -#: ekos/scheduler/scheduler.cpp:6353 -#, fuzzy, kde-format -msgid "Manual shutdown procedure completed successfully." -msgstr "انتقِ إدخال الأسس" - -#: ekos/scheduler/scheduler.cpp:6359 -#, kde-format -msgid "Manual shutdown procedure terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6374 -#, fuzzy, kde-format -#| msgid "Are you sure you want to remove the %1 client?" -msgid "Warning: executing shutdown procedure manually..." -msgstr "هل تريد حذف العميل %1؟" - -#: ekos/scheduler/scheduler.cpp:6382 -#, fuzzy, kde-format -#| msgid "Are you sure you want to remove the %1 client?" -msgid "Are you sure you want to execute the shutdown procedure manually?" -msgstr "هل تريد حذف العميل %1؟" - -#: ekos/scheduler/scheduler.cpp:6429 -#, kde-format -msgid "Shutdown procedure terminated." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6459 +#: ekos/scheduler/scheduler.cpp:4061 #, fuzzy, kde-format msgid "Unable to open sequence queue file '%1'" msgstr "لم أتمكن من فتح الملف %1." -#: ekos/scheduler/scheduler.cpp:6597 +#: ekos/scheduler/scheduler.cpp:4199 #, fuzzy, kde-format msgid "" "Sleeping for %1 on simulation clock update until next observation job is " "ready..." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:6882 -#, fuzzy, kde-format -msgid "Job '%1' alignment is complete." -msgstr "العميل" - -#: ekos/scheduler/scheduler.cpp:6901 -#, fuzzy, kde-format -msgid "Warning: job '%1' alignment failed." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:6907 -#, kde-format -msgid "" -"Warning: job '%1' forcing mount model reset after failing alignment #%2." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:6912 ekos/scheduler/scheduler.cpp:6978 -#, fuzzy, kde-format -msgid "Restarting %1 alignment procedure..." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:6950 -#, fuzzy, kde-format -msgid "Job '%1' guiding is in progress." -msgstr "إعداد المناظير" - -#: ekos/scheduler/scheduler.cpp:6962 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Warning: job '%1' guiding failed." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:6964 -#, fuzzy, kde-format -msgid "Warning: job '%1' calibration failed." -msgstr "العميل" - -#: ekos/scheduler/scheduler.cpp:6983 -#, fuzzy, kde-format -msgid "Job '%1' is guiding, guiding procedure will be restarted in %2 seconds." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:7042 +#: ekos/scheduler/scheduler.cpp:4510 #, fuzzy, kde-format msgid "Warning: job '%1' failed to capture target." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:7055 +#: ekos/scheduler/scheduler.cpp:4523 #, fuzzy, kde-format msgid "" "Job '%1' is capturing, is restarting its guiding procedure (attempt #%2 of " "%3)." msgstr "فارمنغتون" -#: ekos/scheduler/scheduler.cpp:7063 +#: ekos/scheduler/scheduler.cpp:4532 #, fuzzy, kde-format msgid "Warning: job '%1' failed its capture procedure, restarting capture." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:7069 +#: ekos/scheduler/scheduler.cpp:4538 #, fuzzy, kde-format msgid "Warning: job '%1' failed its capture procedure, marking aborted." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:7078 +#: ekos/scheduler/scheduler.cpp:4547 #, kde-format msgid "Ekos job (%1) - Capture finished" msgstr "" -#: ekos/scheduler/scheduler.cpp:7125 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Job '%1' focusing is complete." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7135 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Warning: job '%1' focusing failed." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7139 -#, fuzzy, kde-format -msgid "Job '%1' is restarting its focusing procedure." -msgstr "فارمنغتون" - -#: ekos/scheduler/scheduler.cpp:7180 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Job '%1' slew is complete." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7186 -#, kde-format -msgid "Warning: job '%1' slew failed, marking terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:7192 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Warning: job '%1' found not slewing, restarting." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7205 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Job '%1' repositioning is complete." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7211 -#, kde-format -msgid "" -"Warning: job '%1' repositioning failed, marking terminated due to errors." -msgstr "" - -#: ekos/scheduler/scheduler.cpp:7217 -#, fuzzy, kde-format -#| msgid "%1 is online." -msgid "Warning: job '%1' found not repositioning, restarting." -msgstr "%1 على الخط" - -#: ekos/scheduler/scheduler.cpp:7238 +#: ekos/scheduler/scheduler.cpp:4591 #, kde-format msgid "Weather conditions are OK." msgstr "" -#: ekos/scheduler/scheduler.cpp:7242 +#: ekos/scheduler/scheduler.cpp:4595 #, kde-format msgid "Warning: weather conditions are in the WARNING zone." msgstr "" -#: ekos/scheduler/scheduler.cpp:7246 +#: ekos/scheduler/scheduler.cpp:4599 #, kde-format msgid "Caution: weather conditions are in the DANGER zone!" msgstr "" -#: ekos/scheduler/scheduler.cpp:7268 +#: ekos/scheduler/scheduler.cpp:4621 #, kde-format msgid "Weather conditions in warning zone" msgstr "دخلت الأحوال الجوّيّة منطقةَ الخطر" -#: ekos/scheduler/scheduler.cpp:7277 +#: ekos/scheduler/scheduler.cpp:4630 #, kde-format msgid "Weather conditions are critical. Observatory shutdown is imminent" msgstr "الأحوال الجوّيّة عصيبة. سيجري قريبًا إطفاء المرصد" -#: ekos/scheduler/scheduler.cpp:7297 +#: ekos/scheduler/scheduler.cpp:4651 #, kde-format msgid "Starting shutdown procedure due to severe weather." msgstr "" -#: ekos/scheduler/scheduler.cpp:7325 +#: ekos/scheduler/scheduler.cpp:4679 #, kde-format msgid "" "Job '%1' scheduled for execution at %2. Observatory scheduled for shutdown " "until next job is ready." msgstr "" -#: ekos/scheduler/scheduler.cpp:7348 +#: ekos/scheduler/scheduler.cpp:4702 #, kde-format msgid "" "Job '%1' scheduled for execution at %2. Parking the mount until the job is " "ready." msgstr "" -#: ekos/scheduler/scheduler.cpp:7358 +#: ekos/scheduler/scheduler.cpp:4712 #, fuzzy, kde-format msgid "Sleeping until observation job %1 is ready at %2..." msgstr "العميل" -#: ekos/scheduler/scheduler.cpp:7360 +#: ekos/scheduler/scheduler.cpp:4714 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "Scheduler is in sleep mode" msgstr "تم حفظ ملف FITS الى %1" -#: ekos/scheduler/scheduler.cpp:7368 +#: ekos/scheduler/scheduler.cpp:4722 #, kde-format msgid "" "Warning: Job '%1' is %2 away from now, you may want to enable Preemptive " "Shutdown." msgstr "" -#: ekos/scheduler/scheduler.cpp:7528 +#: ekos/scheduler/scheduler.cpp:4820 #, fuzzy, kde-format msgid "Solver timed out: %1s %2" msgstr "جاري التّحميل" -#: ekos/scheduler/scheduler.cpp:7530 +#: ekos/scheduler/scheduler.cpp:4822 #, fuzzy, kde-format #| msgid "Solver FOV" msgid "Solver failed: %1s %2" msgstr "رمز رؤية المحلل" -#: ekos/scheduler/scheduler.cpp:7565 +#: ekos/scheduler/scheduler.cpp:4857 #, kde-format msgid "Captured frame is %1 arcminutes away from target, re-aligning..." msgstr "" +#: ekos/scheduler/scheduler.cpp:5151 +#, fuzzy, kde-format +msgid "Manual startup procedure completed successfully." +msgstr "انتقِ إدخال الأسس" + +#: ekos/scheduler/scheduler.cpp:5155 +#, kde-format +msgid "Manual startup procedure terminated due to errors." +msgstr "" + #. i18n: ectx: property (title), widget (QGroupBox, jobSequenceGroup) #: ekos/scheduler/scheduler.ui:38 #, fuzzy, kde-format @@ -25894,7 +25967,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, rotationLabel) -#: ekos/scheduler/scheduler.ui:85 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverAngleLabel) +#: ekos/scheduler/scheduler.ui:85 fitsviewer/platesolve.ui:318 #, fuzzy, kde-format #| msgctxt "Constellation name (optional)" #| msgid "PAVO" @@ -26475,12 +26549,12 @@ msgid "UnCap" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:360 +#: ekos/scheduler/schedulerjob.cpp:336 #, kde-format msgid "Ekos job failed (%1)" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:404 +#: ekos/scheduler/schedulerjob.cpp:380 #, kde-format msgid "" "Current status of job '%1', managed by the Scheduler.\n" @@ -26492,7 +26566,7 @@ "were stored, including repeats." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:415 +#: ekos/scheduler/schedulerjob.cpp:391 #, kde-format msgid "" "Current altitude of the target of job '%1'.\n" @@ -26500,7 +26574,7 @@ "A setting target is indicated with an arrow going down." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:425 +#: ekos/scheduler/schedulerjob.cpp:401 #, kde-format msgid "" "Startup time for job '%1', as estimated by the Scheduler.\n" @@ -26509,7 +26583,7 @@ "symbol. " msgstr "" -#: ekos/scheduler/schedulerjob.cpp:435 +#: ekos/scheduler/schedulerjob.cpp:411 #, kde-format msgid "" "Completion time for job '%1', as estimated by the Scheduler.\n" @@ -26518,7 +26592,7 @@ "before completion.\n" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:445 +#: ekos/scheduler/schedulerjob.cpp:421 #, kde-format msgid "" "Count of captures stored for job '%1', based on its sequence job.\n" @@ -26526,54 +26600,607 @@ "complete the job." msgstr "" -#: ekos/scheduler/schedulerjob.cpp:614 +#: ekos/scheduler/schedulerjob.cpp:590 #, kde-format msgid "Evaluating" msgstr "" -#: ekos/scheduler/schedulerjob.cpp:615 +#: ekos/scheduler/schedulerjob.cpp:591 #, kde-format msgid "Scheduled" msgstr "مجدول" -#: ekos/scheduler/schedulerjob.cpp:617 +#: ekos/scheduler/schedulerjob.cpp:593 #, kde-format msgid "Invalid" msgstr "غير صالح" -#: ekos/scheduler/schedulerjob.cpp:639 +#: ekos/scheduler/schedulerjob.cpp:615 #, fuzzy, kde-format #| msgid "completed" msgid "Slew complete" msgstr "مكتمل" -#: ekos/scheduler/schedulerjob.cpp:643 +#: ekos/scheduler/schedulerjob.cpp:619 #, fuzzy, kde-format msgid "Focus complete" msgstr "مكتمل" -#: ekos/scheduler/schedulerjob.cpp:645 +#: ekos/scheduler/schedulerjob.cpp:621 #, fuzzy, kde-format #| msgid "completed" msgid "Align complete" msgstr "مكتمل" -#: ekos/scheduler/schedulerjob.cpp:646 +#: ekos/scheduler/schedulerjob.cpp:622 #, fuzzy, kde-format msgid "Repositioning" msgstr "الموضع" -#: ekos/scheduler/schedulerjob.cpp:647 +#: ekos/scheduler/schedulerjob.cpp:623 #, fuzzy, kde-format msgid "Repositioning complete" msgstr "العميل" -#: ekos/scheduler/schedulerjob.cpp:650 +#: ekos/scheduler/schedulerjob.cpp:626 #, fuzzy, kde-format #| msgid "completed" msgid "Guiding complete" msgstr "مكتمل" +#: ekos/scheduler/schedulerprocess.cpp:68 +#, fuzzy, kde-format +msgid "Job '%1' is slewing to target." +msgstr "اليوم && الموقع" + +#: ekos/scheduler/schedulerprocess.cpp:108 +#, kde-format +msgid "Warning: job '%1' is unable to proceed with autofocus, not supported." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:174 +#, kde-format +msgid "Job '%1' is focusing." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:201 +#, fuzzy, kde-format +msgid "Warning: job '%1' target FITS file does not exist." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:213 +#, kde-format +msgid "Warning: job '%1' loadAndSlew request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:224 +#, fuzzy, kde-format +msgid "Warning: job '%1' loadAndSlew request failed." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:230 +#, fuzzy, kde-format +msgid "Job '%1' is plate solving %2." +msgstr "جاري التّحميل." + +#: ekos/scheduler/schedulerprocess.cpp:244 +#, kde-format +msgid "Warning: job '%1' setTargetCoords request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:260 +#, kde-format +msgid "" +"Warning: job '%1' setTargetPositionAngle request received DBUS error: %2" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:273 +#, fuzzy, kde-format +msgid "Warning: job '%1' captureAndSolve request received DBUS error: %2" +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:284 +#, fuzzy, kde-format +msgid "Warning: job '%1' captureAndSolve request failed." +msgstr "العميل" + +#: ekos/scheduler/schedulerprocess.cpp:290 +#, fuzzy, kde-format +msgid "Job '%1' is capturing and plate solving." +msgstr "جاري التّحميل." + +#: ekos/scheduler/schedulerprocess.cpp:306 +#, fuzzy, kde-format +msgid "Guiding already running for %1, starting next scheduler action..." +msgstr "جاري التّحميل" + +#: ekos/scheduler/schedulerprocess.cpp:330 +#, fuzzy, kde-format +msgid "Starting guiding procedure for %1 ..." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:439 +#, kde-format +msgid "Ekos job (%1) - Capture started" +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:442 +#, kde-format +msgid "Job '%1' capture is in progress (batch #%2)..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:445 +#, fuzzy, kde-format +msgid "Job '%1' capture is in progress..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:467 +#, fuzzy, kde-format +msgid "Executing script %1..." +msgstr "يعمل برنامج نصي 1" + +#: ekos/scheduler/schedulerprocess.cpp:512 +#, fuzzy, kde-format +msgid "Ekos started." +msgstr "جاري التّحميل" + +#: ekos/scheduler/schedulerprocess.cpp:521 +#, fuzzy, kde-format +msgid "Starting Ekos failed. Retrying..." +msgstr "لم أتمكن من فتح الملف %1." + +#: ekos/scheduler/schedulerprocess.cpp:526 +#, fuzzy, kde-format +msgid "Starting Ekos failed." +msgstr "أخرى" + +#: ekos/scheduler/schedulerprocess.cpp:537 +#, fuzzy, kde-format +msgid "Starting Ekos timed out. Retrying..." +msgstr "لم أتمكن من فتح الملف %1." + +#: ekos/scheduler/schedulerprocess.cpp:547 +#, fuzzy, kde-format +msgid "Starting Ekos timed out." +msgstr "جاري التّحميل" + +#: ekos/scheduler/schedulerprocess.cpp:558 +#, fuzzy, kde-format +msgid "Ekos stopped." +msgstr "جاري التّحميل" + +#: ekos/scheduler/schedulerprocess.cpp:601 +#, fuzzy, kde-format +msgid "INDI devices connected." +msgstr "ضبط INDI s جهاز اتصال منفذ." + +#: ekos/scheduler/schedulerprocess.cpp:608 +#, kde-format +msgid "One or more INDI devices failed to connect. Retrying..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:613 +#, kde-format +msgid "" +"One or more INDI devices failed to connect. Check INDI control panel for " +"details." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:622 +#, kde-format +msgid "One or more INDI devices timed out. Retrying..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:628 +#, kde-format +msgid "" +"One or more INDI devices timed out. Check INDI control panel for details." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:639 +#, fuzzy, kde-format +msgid "INDI devices disconnected." +msgstr "ضبط INDI s جهاز اتصال منفذ." + +#: ekos/scheduler/schedulerprocess.cpp:655 +#, kde-format +msgid "Warning: dome device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:660 +#, kde-format +msgid "Dome unpark required but dome is not yet ready." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:670 +#, kde-format +msgid "Warning: mount device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:685 +#, kde-format +msgid "Warning: cap device not ready after timeout, attempting to recover..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:747 +#, fuzzy, kde-format +msgid "Shutdown complete." +msgstr "مكتمل" + +#: ekos/scheduler/schedulerprocess.cpp:749 +#, kde-format +msgid "Shutdown procedure failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:853 +#, fuzzy, kde-format +msgid "Cap parked." +msgstr "القبة الجدول" + +#: ekos/scheduler/schedulerprocess.cpp:863 +#, fuzzy, kde-format +msgid "Cap unparked." +msgstr "Mount Ekar" + +#: ekos/scheduler/schedulerprocess.cpp:875 +#: ekos/scheduler/schedulerprocess.cpp:1104 +#, kde-format +msgid "Operation timeout. Restarting operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:888 +#, fuzzy, kde-format +msgid "Cap parking error." +msgstr "القبة الجدول" + +#: ekos/scheduler/schedulerprocess.cpp:893 +#, fuzzy, kde-format +msgid "Cap unparking error." +msgstr "Mount Ekar" + +#: ekos/scheduler/schedulerprocess.cpp:935 +#, kde-format +msgid "Mount parked." +msgstr "رُكن الحامل." + +#: ekos/scheduler/schedulerprocess.cpp:950 +#, kde-format +msgid "Mount unparked." +msgstr "أُلغي ركن الحامل." + +#: ekos/scheduler/schedulerprocess.cpp:962 +#, kde-format +msgid "" +"Warning: mount unpark operation timed out on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:968 +#, kde-format +msgid "Warning: mount unpark operation timed out on last attempt." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:982 +#, kde-format +msgid "" +"Warning: mount park operation timed out on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:989 +#, kde-format +msgid "Warning: mount park operation timed out on last attempt." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1001 +#: ekos/scheduler/schedulerprocess.cpp:1030 +#, fuzzy, kde-format +msgid "Mount unparking error." +msgstr "Mount Ekar" + +#: ekos/scheduler/schedulerprocess.cpp:1009 +#, kde-format +msgid "" +"Warning: mount park operation failed on attempt %1/%2. Restarting " +"operation..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1016 +#: ekos/scheduler/schedulerprocess.cpp:1024 +#, fuzzy, kde-format +msgid "Mount parking error." +msgstr "Mount Ekar" + +#: ekos/scheduler/schedulerprocess.cpp:1081 +#, kde-format +msgid "Dome parked." +msgstr "رُكنت القبّة." + +#: ekos/scheduler/schedulerprocess.cpp:1092 +#, kde-format +msgid "Dome unparked." +msgstr "أُلغي ركن القبّة." + +#: ekos/scheduler/schedulerprocess.cpp:1119 +#, fuzzy, kde-format +msgid "Dome parking failed. Restarting operation..." +msgstr "لم أتمكن من فتح الملف %1." + +#: ekos/scheduler/schedulerprocess.cpp:1124 +#, fuzzy, kde-format +msgid "Dome parking error." +msgstr "القبة الجدول" + +#: ekos/scheduler/schedulerprocess.cpp:1133 +#, fuzzy, kde-format +msgid "Dome unparking failed. Restarting operation..." +msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." + +#: ekos/scheduler/schedulerprocess.cpp:1138 +#, fuzzy, kde-format +msgid "Dome unparking error." +msgstr "القبة الجدول" + +#: ekos/scheduler/schedulerprocess.cpp:1161 +#, kde-format +msgid "Observatory is in the startup process" +msgstr "دخل المرصد عمليّة الإعداد" + +#: ekos/scheduler/schedulerprocess.cpp:1174 +#, kde-format +msgid "Ekos is already started, skipping startup script..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1270 +#, fuzzy, kde-format +msgid "Warming up CCD..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:1303 +#, kde-format +msgid "Warning: Bypassing parking procedures, no INDI connection." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1427 +#, kde-format +msgid "park/unpark wait procedure failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1446 +#, fuzzy, kde-format +#| msgid "Are you sure you want to remove the %1 client?" +msgid "Warning: executing startup procedure manually..." +msgstr "هل تريد حذف العميل %1؟" + +#: ekos/scheduler/schedulerprocess.cpp:1453 +#, fuzzy, kde-format +#| msgid "Are you sure you want to remove the %1 client?" +msgid "Are you sure you want to execute the startup procedure manually?" +msgstr "هل تريد حذف العميل %1؟" + +#: ekos/scheduler/schedulerprocess.cpp:1497 +#, fuzzy, kde-format +msgid "Startup procedure terminated." +msgstr "شغّل الساعة" + +#: ekos/scheduler/schedulerprocess.cpp:1511 +#, fuzzy, kde-format +#| msgid "Are you sure you want to remove the %1 client?" +msgid "Warning: executing shutdown procedure manually..." +msgstr "هل تريد حذف العميل %1؟" + +#: ekos/scheduler/schedulerprocess.cpp:1517 +#, fuzzy, kde-format +#| msgid "Are you sure you want to remove the %1 client?" +msgid "Are you sure you want to execute the shutdown procedure manually?" +msgstr "هل تريد حذف العميل %1؟" + +#: ekos/scheduler/schedulerprocess.cpp:1562 +#, kde-format +msgid "Shutdown procedure terminated." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1746 +#, fuzzy, kde-format +#| msgid "FITS file saved to %1" +msgid "Scheduler list saved to %1" +msgstr "تم حفظ ملف FITS الى %1" + +#: ekos/scheduler/schedulerprocess.cpp:1772 +#, fuzzy, kde-format +msgid "Job '%1' alignment is complete." +msgstr "العميل" + +#: ekos/scheduler/schedulerprocess.cpp:1791 +#, fuzzy, kde-format +msgid "Warning: job '%1' alignment failed." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:1797 +#, kde-format +msgid "" +"Warning: job '%1' forcing mount model reset after failing alignment #%2." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1801 +#: ekos/scheduler/schedulerprocess.cpp:1865 +#, fuzzy, kde-format +msgid "Restarting %1 alignment procedure..." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:1837 +#, fuzzy, kde-format +msgid "Job '%1' guiding is in progress." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:1849 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Warning: job '%1' guiding failed." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1851 +#, fuzzy, kde-format +msgid "Warning: job '%1' calibration failed." +msgstr "العميل" + +#: ekos/scheduler/schedulerprocess.cpp:1870 +#, fuzzy, kde-format +msgid "Job '%1' is guiding, guiding procedure will be restarted in %2 seconds." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:1906 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Job '%1' focusing is complete." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1916 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Warning: job '%1' focusing failed." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1920 +#, fuzzy, kde-format +msgid "Job '%1' is restarting its focusing procedure." +msgstr "فارمنغتون" + +#: ekos/scheduler/schedulerprocess.cpp:1958 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Job '%1' slew is complete." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1964 +#, kde-format +msgid "Warning: job '%1' slew failed, marking terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1970 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Warning: job '%1' found not slewing, restarting." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1983 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Job '%1' repositioning is complete." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:1989 +#, kde-format +msgid "" +"Warning: job '%1' repositioning failed, marking terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:1995 +#, fuzzy, kde-format +#| msgid "%1 is online." +msgid "Warning: job '%1' found not repositioning, restarting." +msgstr "%1 على الخط" + +#: ekos/scheduler/schedulerprocess.cpp:2020 +#, fuzzy, kde-format +msgid "Manual shutdown procedure completed successfully." +msgstr "انتقِ إدخال الأسس" + +#: ekos/scheduler/schedulerprocess.cpp:2026 +#, kde-format +msgid "Manual shutdown procedure terminated due to errors." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2041 +#, kde-format +msgid "Dust cover park requested but no dust covers detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2064 +#, fuzzy, kde-format +msgid "Parking Cap..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:2070 +#, kde-format +msgid "Cap already parked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2079 +#, kde-format +msgid "Dust cover unpark requested but no dust covers detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2101 +#, fuzzy, kde-format +msgid "Unparking cap..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:2107 +#, kde-format +msgid "Cap already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2116 +#, kde-format +msgid "Mount park requested but no mounts detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2174 +#, fuzzy, kde-format +msgid "Parking mount in progress..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:2188 +#, kde-format +msgid "Mount unpark requested but no mounts detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2214 +#, kde-format +msgid "Mount already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2312 +#, kde-format +msgid "Dome park requested but no domes detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2335 +#, fuzzy, kde-format +msgid "Parking dome..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:2341 +#, kde-format +msgid "Dome already parked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2351 +#, kde-format +msgid "Dome unpark requested but no domes detected." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2371 +#, fuzzy, kde-format +msgid "Unparking dome..." +msgstr "إعداد المناظير" + +#: ekos/scheduler/schedulerprocess.cpp:2377 +#, kde-format +msgid "Dome already unparked." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2495 +#, kde-format +msgid "Startup script failed, aborting..." +msgstr "" + +#: ekos/scheduler/schedulerprocess.cpp:2500 +#, kde-format +msgid "Shutdown script failed, aborting..." +msgstr "" + #: fitsviewer/fitscommon.h:15 #, kde-format msgid "Normal" @@ -26735,40 +27362,40 @@ msgid "Failed to write image: %1" msgstr "فشل في تحميل الصورة " -#: fitsviewer/fitsdata.cpp:2778 fitsviewer/fitsdata.cpp:2789 -#: fitsviewer/fitsdata.cpp:2825 fitsviewer/fitsdata.cpp:2861 -#: fitsviewer/fitsdata.cpp:2908 +#: fitsviewer/fitsdata.cpp:2780 fitsviewer/fitsdata.cpp:2791 +#: fitsviewer/fitsdata.cpp:2827 fitsviewer/fitsdata.cpp:2863 +#: fitsviewer/fitsdata.cpp:2910 #, fuzzy, kde-format msgid "No world coordinate systems found." msgstr "إستعمل أفقي تنسيق نظام?" -#: fitsviewer/fitsdata.cpp:3630 +#: fitsviewer/fitsdata.cpp:3632 #, kde-format msgid "Only 8 and 16 bits bayered images supported." msgstr "" -#: fitsviewer/fitsdata.cpp:3663 +#: fitsviewer/fitsdata.cpp:3665 #, kde-format msgid "Unsupported bayer pattern %1." msgstr "" -#: fitsviewer/fitsdata.cpp:3694 +#: fitsviewer/fitsdata.cpp:3696 #, kde-format msgid "Unsupported bayer offsets %1 %2." msgstr "" -#: fitsviewer/fitsdata.cpp:3762 fitsviewer/fitsdata.cpp:3809 -#: fitsviewer/fitsdata.cpp:3854 fitsviewer/fitsdata.cpp:3901 +#: fitsviewer/fitsdata.cpp:3764 fitsviewer/fitsdata.cpp:3811 +#: fitsviewer/fitsdata.cpp:3856 fitsviewer/fitsdata.cpp:3903 #, kde-format msgid "Unable to allocate memory for temporary bayer buffer: %1" msgstr "" -#: fitsviewer/fitsdata.cpp:3772 fitsviewer/fitsdata.cpp:3864 +#: fitsviewer/fitsdata.cpp:3774 fitsviewer/fitsdata.cpp:3866 #, kde-format msgid "Unable to allocate memory for temporary bayer buffer." msgstr "" -#: fitsviewer/fitsdata.cpp:3792 fitsviewer/fitsdata.cpp:3884 +#: fitsviewer/fitsdata.cpp:3794 fitsviewer/fitsdata.cpp:3886 #, kde-format msgid "Debayer failed (%1)" msgstr "" @@ -26877,7 +27504,7 @@ msgstr "جاهز." #. i18n: ectx: property (windowTitle), widget (QDialog, fitsHeaderDialog) -#: fitsviewer/fitsheaderdialog.ui:14 fitsviewer/fitstab.cpp:128 +#: fitsviewer/fitsheaderdialog.ui:14 fitsviewer/fitstab.cpp:137 #: fitsviewer/fitsviewer.cpp:138 #, kde-format msgid "FITS Header" @@ -26933,7 +27560,7 @@ msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, FITSHistogramUI) -#: fitsviewer/fitshistogramui.ui:32 fitsviewer/fitstab.cpp:125 +#: fitsviewer/fitshistogramui.ui:32 fitsviewer/fitstab.cpp:134 #: fitsviewer/fitsviewer.cpp:119 #, kde-format msgid "Histogram" @@ -26966,18 +27593,12 @@ msgid "Apply" msgstr "طبّق" -#: fitsviewer/fitslabel.cpp:284 -#, fuzzy, kde-format -msgctxt "Half Flux Radius" -msgid "HFR: %1" -msgstr ":HFR" - -#: fitsviewer/fitslabel.cpp:342 tools/whatsinteresting/wiview.cpp:332 +#: fitsviewer/fitslabel.cpp:353 tools/whatsinteresting/wiview.cpp:332 #, fuzzy, kde-format msgid "Continue Slew" msgstr "Aalborg" -#: fitsviewer/fitslabel.cpp:425 fitsviewer/fitslabel.cpp:452 +#: fitsviewer/fitslabel.cpp:436 fitsviewer/fitslabel.cpp:463 #, fuzzy, kde-format #| msgid "KStars did not find any active telescopes." msgid "KStars did not find any active mounts." @@ -27043,52 +27664,106 @@ msgid "Automatically find stretch parameter." msgstr "تبديل تنسيق" -#: fitsviewer/fitstab.cpp:53 +#: fitsviewer/fitstab.cpp:56 #, kde-format msgid "Save Changes to FITS?" msgstr "حفظ التغييرات إلى FITS?" -#: fitsviewer/fitstab.cpp:54 +#: fitsviewer/fitstab.cpp:57 #, kde-format msgid "" "The current FITS file has unsaved changes. Would you like to save before " "closing it?" msgstr "ملف FITS الحالي غير محفوط. هل تريد حفط الملف قبل اغلاقه؟" -#: fitsviewer/fitstab.cpp:133 +#. i18n: ectx: property (windowTitle), widget (QDialog, PlateSolveUI) +#: fitsviewer/fitstab.cpp:131 fitsviewer/platesolve.ui:14 +#, fuzzy, kde-format +msgid "Plate Solving" +msgstr "خادم" + +#: fitsviewer/fitstab.cpp:142 #, fuzzy, kde-format #| msgid "Reference Images:" msgid "Recent Images" msgstr "الصور المرجعية:" -#: fitsviewer/fitstab.cpp:367 +#: fitsviewer/fitstab.cpp:376 #, fuzzy, kde-format msgctxt "Red" msgid "R" msgstr "ح" -#: fitsviewer/fitstab.cpp:448 fitsviewer/fitstab.cpp:452 +#: fitsviewer/fitstab.cpp:457 fitsviewer/fitstab.cpp:461 #, fuzzy, kde-format msgctxt "@title:window" msgid "Save FITS" msgstr "احفظ" -#: fitsviewer/fitstab.cpp:484 +#: fitsviewer/fitstab.cpp:493 #, fuzzy, kde-format msgid "Image save error: %1" msgstr "ملفّ حفظ خطأ 1" -#: fitsviewer/fitstab.cpp:484 +#: fitsviewer/fitstab.cpp:493 #, fuzzy, kde-format msgid "Image Save" msgstr "صورة تنسيق" -#: fitsviewer/fitstab.cpp:488 +#: fitsviewer/fitstab.cpp:497 #, fuzzy, kde-format #| msgid "FITS file saved to %1" msgid "File saved to %1" msgstr "تم حفظ ملف FITS الى %1" +#: fitsviewer/fitstab.cpp:632 +#, fuzzy, kde-format +#| msgid "Waiting..." +msgid "Extracting..." +msgstr "ينتظر..." + +#: fitsviewer/fitstab.cpp:650 +#, fuzzy, kde-format +msgid "Solving..." +msgstr "رسوب" + +#: fitsviewer/fitstab.cpp:663 +#, fuzzy, kde-format +msgid "Extractor timed out: %1s" +msgstr "جاري التّحميل" + +#: fitsviewer/fitstab.cpp:672 +#, fuzzy, kde-format +#| msgid "Solver FOV" +msgid "Extractor failed: %1s" +msgstr "رمز رؤية المحلل" + +#: fitsviewer/fitstab.cpp:681 +#, kde-format +msgid "Extracted %1 stars (%2 unfiltered) in %3s" +msgstr "" + +#: fitsviewer/fitstab.cpp:728 +#, fuzzy, kde-format +msgid "Solver timed out: %1s" +msgstr "جاري التّحميل" + +#: fitsviewer/fitstab.cpp:733 +#, fuzzy, kde-format +#| msgid "Solver FOV" +msgid "Solver failed: %1s" +msgstr "رمز رؤية المحلل" + +#: fitsviewer/fitstab.cpp:823 +#, kde-format +msgid "Warning! This tool only supports the internal StellarSolver solver." +msgstr "" + +#: fitsviewer/fitstab.cpp:824 +#, kde-format +msgid "Change to that in the Ekos Align options menu." +msgstr "" + #: fitsviewer/fitsview.cpp:506 fitsviewer/fitsview.cpp:516 #, fuzzy, kde-format #| msgid "Saving of the image %1 failed." @@ -27355,7 +28030,7 @@ msgid "HiPS Overlay" msgstr "طبقة HiPS لكامل السماء (تجريبي)" -#: fitsviewer/fitsviewer.cpp:711 kstarsactions.cpp:1284 +#: fitsviewer/fitsviewer.cpp:711 kstarsactions.cpp:1293 #, kde-format msgctxt "@title:window" msgid "Open Image" @@ -27564,7 +28239,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, stretchPreviewSamplingLabel) #. i18n: ectx: property (toolTip), widget (QSpinBox, kcfg_StretchPreviewSampling) #. i18n: ectx: label, entry (StretchPreviewSampling), group (Capture) -#: fitsviewer/opsfits.ui:226 fitsviewer/opsfits.ui:236 kstars.kcfg:1854 +#: fitsviewer/opsfits.ui:226 fitsviewer/opsfits.ui:236 kstars.kcfg:1878 #, kde-format msgid "" "Set the coarseness of the preview shown when sliding the fitsviewer's " @@ -27819,6 +28494,71 @@ msgid "StellarSolver Partitioning" msgstr "الحالي اللّون خصائص" +#. i18n: ectx: property (toolTip), widget (QPushButton, SolveButton) +#: fitsviewer/platesolve.ui:47 +#, kde-format +msgid "Plate solve the image using the parameters below." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:101 +#, kde-format +msgid "

    The units of the imager scale bounds." +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:108 +#, fuzzy, kde-format +#| msgid "Image width:" +msgid "image width º" +msgstr "عرض صورة:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:113 +#, fuzzy, kde-format +#| msgid "Image width:" +msgid "image width '" +msgstr "عرض صورة:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_FitsSolverImageScaleUnits) +#: fitsviewer/platesolve.ui:118 +#, fuzzy, kde-format +#| msgctxt "City name (optional, probably does not need a translation)" +#| msgid "Parsons" +msgid "arcsec/pixel" +msgstr "%1 ثانية قوسية" + +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_FitsSolverUsePosition) +#: fitsviewer/platesolve.ui:139 +#, kde-format +msgid "" +"Use the given position to speed up astrometry solver as it does not have to " +"search in other areas of the sky." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QPushButton, UpdatePosition) +#: fitsviewer/platesolve.ui:164 +#, kde-format +msgid "" +"Set the approximate RA/DEC positions using the center position of the SkyMap." +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverAngleLabel) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverAngle) +#: fitsviewer/platesolve.ui:315 fitsviewer/platesolve.ui:331 +#, fuzzy, kde-format +msgid "The solved image position angle, East of North (degrees)." +msgstr "جغرافي خط الطول بوصة درجات." + +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverProfileLabel) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_FitsSolverProfile) +#. i18n: ectx: property (toolTip), widget (QComboBox, imageOverlaySolverProfile) +#: fitsviewer/platesolve.ui:357 fitsviewer/platesolve.ui:373 +#: options/opsimageoverlay.ui:255 +#, kde-format +msgid "Selects the Options Profile (from Align) to use for Plate Solving" +msgstr "" + #. i18n: ectx: property (text), widget (QTableWidget, solutionTable) #: fitsviewer/solveInfo.ui:71 #, fuzzy, kde-format @@ -27839,12 +28579,6 @@ msgid "Rotation" msgstr "التّدوير" -#. i18n: ectx: property (text), widget (QTableWidget, solutionTable) -#: fitsviewer/solveInfo.ui:91 -#, kde-format -msgid "Solution" -msgstr "الحل" - #. i18n: ectx: property (text), widget (QPushButton, solveB) #: fitsviewer/solveInfo.ui:99 #, fuzzy, kde-format @@ -27963,11 +28697,6 @@ msgid "Changes the type of selection" msgstr "" -#: fitsviewer/starprofileviewer.cpp:127 -#, kde-format -msgid "Item" -msgstr "عنصر" - #: fitsviewer/starprofileviewer.cpp:137 #, kde-format msgid "Toggles the slice view when horizontal or vertical items are selected" @@ -28398,62 +29127,62 @@ msgid "Failed to create local INDI server" msgstr "خطأ في تشغيل خادم INDI: خطأ في المنفذ" -#: indi/drivermanager.cpp:604 indi/indidriver.cpp:291 +#: indi/drivermanager.cpp:621 indi/indidriver.cpp:291 #, fuzzy, kde-format, kde-kuit-format msgid "Invalid port entry: %1" msgstr "الملف غير صحيح: %1" -#: indi/drivermanager.cpp:800 +#: indi/drivermanager.cpp:817 #, fuzzy, kde-format #| msgid "Connect" msgid "Connected to INDI server" msgstr "اتصل" -#: indi/drivermanager.cpp:992 indi/indidriver.cpp:487 +#: indi/drivermanager.cpp:1009 indi/indidriver.cpp:487 #, kde-format, kde-kuit-format msgid "" "Unable to find INDI drivers directory: %1\n" "Please make sure to set the correct path in KStars configuration" msgstr "" -#: indi/drivermanager.cpp:1023 indi/indidriver.cpp:528 +#: indi/drivermanager.cpp:1040 indi/indidriver.cpp:528 #, fuzzy, kde-format, kde-kuit-format msgid "Failed to open INDI Driver file: %1" msgstr "لم يمكن فتح الملف: %1" -#: indi/drivermanager.cpp:1389 +#: indi/drivermanager.cpp:1406 #, kde-format msgctxt "@title:window" msgid "Add Host" msgstr "اضف مضيف" -#: indi/drivermanager.cpp:1400 indi/indidriver.cpp:812 +#: indi/drivermanager.cpp:1417 indi/indidriver.cpp:812 #, kde-format, kde-kuit-format msgid "Error: the port number is invalid." msgstr "رقم المنفذ غير صحيح" -#: indi/drivermanager.cpp:1413 indi/indidriver.cpp:822 +#: indi/drivermanager.cpp:1430 indi/indidriver.cpp:822 #, kde-format, kde-kuit-format msgid "Host: %1 Port: %2 already exists." msgstr "المضيف: %1 المنفذ: %2 موجود حاليا." -#: indi/drivermanager.cpp:1441 +#: indi/drivermanager.cpp:1458 #, kde-format msgctxt "@title:window" msgid "Modify Host" msgstr "عدل المضيف" -#: indi/drivermanager.cpp:1487 indi/indidriver.cpp:890 +#: indi/drivermanager.cpp:1504 indi/indidriver.cpp:890 #, kde-format, kde-kuit-format msgid "You need to disconnect the client before removing it." msgstr "يجب ان تفصل العميل قبل حذفه" -#: indi/drivermanager.cpp:1493 indi/indidriver.cpp:895 +#: indi/drivermanager.cpp:1510 indi/indidriver.cpp:895 #, kde-format, kde-kuit-format msgid "Are you sure you want to remove the %1 client?" msgstr "هل تريد حذف العميل %1؟" -#: indi/drivermanager.cpp:1518 indi/indidriver.cpp:920 +#: indi/drivermanager.cpp:1535 indi/indidriver.cpp:920 #, fuzzy, kde-format, kde-kuit-format msgid "" "Unable to write to file 'indihosts.xml'\n" @@ -29222,18 +29951,18 @@ msgid "Post driver startup script failed with exit code: %1" msgstr "" -#: indi/servermanager.cpp:407 +#: indi/servermanager.cpp:415 #, fuzzy, kde-format #| msgid "Connection to INDI server at host %1 with port %2 failed." msgid "Connection to INDI server %1:%2 terminated: %3." msgstr "الاتصال على خادم INDI في المضيف %1 عبر المنفذ %2 فشل." -#: indi/servermanager.cpp:453 +#: indi/servermanager.cpp:461 #, kde-format msgid "INDI Driver %1 crashed. Restart it?" msgstr "" -#: indi/servermanager.cpp:454 +#: indi/servermanager.cpp:462 #, fuzzy, kde-format #| msgid "Driver:" msgid "Driver crash" @@ -29783,18 +30512,18 @@ msgid "KStars" msgstr "نجوم ك" -#: kstars.cpp:314 kstarsactions.cpp:1553 skymap.cpp:427 +#: kstars.cpp:314 kstarsactions.cpp:1562 skymap.cpp:427 #, kde-format msgid "Stop &Tracking" msgstr "اوقف ال&تتبع" -#: kstars.cpp:322 kstarsactions.cpp:1722 kstarsinit.cpp:263 +#: kstars.cpp:322 kstarsactions.cpp:1731 kstarsinit.cpp:263 #, fuzzy, kde-format #| msgid "Switch to star globe view (Equatorial &Coordinates)" msgid "Switch to Star Globe View (Equatorial &Coordinates)" msgstr "اعرض باستخدام الإحداثيات الاستوائية" -#: kstars.cpp:323 kstarsactions.cpp:1701 kstarsinit.cpp:264 +#: kstars.cpp:323 kstarsactions.cpp:1710 kstarsinit.cpp:264 #, fuzzy, kde-format #| msgid "Switch to horizonal view (Horizontal &Coordinates)" msgid "Switch to Horizontal View (Horizontal &Coordinates)" @@ -33279,86 +34008,122 @@ msgid "HiPS overlay Y Offset" msgstr "" +#. i18n: ectx: label, entry (FitsSolverProfile), group (FITSViewer) +#: kstars.kcfg:1526 +#, kde-format +msgid "Options Profile for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverUseScale), group (FITSViewer) +#: kstars.kcfg:1530 +#, kde-format +msgid "Use scale for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverUsePosition), group (FITSViewer) +#: kstars.kcfg:1534 +#, kde-format +msgid "Use position for Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverScale), group (FITSViewer) +#: kstars.kcfg:1538 +#, kde-format +msgid "Scale to use with Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverImageScaleUnits), group (FITSViewer) +#: kstars.kcfg:1542 +#, kde-format +msgid "Scale units to use with Fitsviewer Solving." +msgstr "" + +#. i18n: ectx: label, entry (FitsSolverRadius), group (FITSViewer) +#: kstars.kcfg:1546 +#, kde-format +msgid "Radius in position (degrees) to use with Fitsviewer Solving." +msgstr "" + #. i18n: ectx: label, entry (BortleClass), group (WISettings) -#: kstars.kcfg:1528 +#: kstars.kcfg:1552 #, kde-format msgid "Bortle dark-sky rating" msgstr "" #. i18n: ectx: label, entry (TelescopeCheck), group (WISettings) -#: kstars.kcfg:1532 +#: kstars.kcfg:1556 #, fuzzy, kde-format msgid "Availability of telescope" msgstr "إعداد المناظير" #. i18n: ectx: label, entry (BinocularsCheck), group (WISettings) -#: kstars.kcfg:1536 +#: kstars.kcfg:1560 #, kde-format msgid "Availability of binoculars" msgstr "" #. i18n: ectx: label, entry (BinocularsAperture), group (WISettings) -#: kstars.kcfg:1540 +#: kstars.kcfg:1564 #, kde-format msgid "Aperture of available binocular" msgstr "" #. i18n: ectx: label, entry (ScopeListIndex), group (WISettings) -#: kstars.kcfg:1544 +#: kstars.kcfg:1568 #, kde-format msgid "Index of selected scope from list of scopes" msgstr "" #. i18n: ectx: label, entry (EkosWindowWidth), group (Ekos) -#: kstars.kcfg:1550 +#: kstars.kcfg:1574 #, kde-format msgid "Ekos window width" msgstr "" #. i18n: ectx: label, entry (EkosWindowHeight), group (Ekos) -#: kstars.kcfg:1554 +#: kstars.kcfg:1578 #, fuzzy, kde-format msgid "Ekos window height" msgstr "Rowland Heights" #. i18n: ectx: label, entry (EkosLeftIcons), group (Ekos) -#: kstars.kcfg:1562 +#: kstars.kcfg:1586 #, kde-format msgid "Ekos modules icons are placed to the left of pages" msgstr "" #. i18n: ectx: label, entry (independentWindowEkos), group (Ekos) -#: kstars.kcfg:1566 +#: kstars.kcfg:1590 #, kde-format msgid "Make Ekos window independent of KStars main window" msgstr "" #. i18n: ectx: label, entry (profile), group (Ekos) -#: kstars.kcfg:1570 +#: kstars.kcfg:1594 #, kde-format msgid "Ekos drivers profile" msgstr "" #. i18n: ectx: label, entry (neverLoadConfig), group (Ekos) -#: kstars.kcfg:1574 +#: kstars.kcfg:1598 #, fuzzy, kde-format msgid "Never load device configuration?" msgstr "تأكيد الحذف" #. i18n: ectx: label, entry (loadConfigOnConnection), group (Ekos) -#: kstars.kcfg:1578 +#: kstars.kcfg:1602 #, kde-format msgid "Load device configuration upon successful connection?" msgstr "" #. i18n: ectx: label, entry (loadDefaultConfig), group (Ekos) -#: kstars.kcfg:1582 +#: kstars.kcfg:1606 #, kde-format msgid "Always load device default configuration upon successful connection?" msgstr "" #. i18n: ectx: label, entry (autoLoadSerialAssistant), group (Ekos) -#: kstars.kcfg:1586 +#: kstars.kcfg:1610 #, kde-format msgid "" "Automatically load Serial Port Assistant tool when detecting unmapped serial " @@ -33366,52 +34131,52 @@ msgstr "" #. i18n: ectx: label, entry (RememberCredentials), group (EkosLive) -#: kstars.kcfg:1592 +#: kstars.kcfg:1616 #, kde-format msgid "Remember Ekos Live credentials." msgstr "" #. i18n: ectx: label, entry (AutoStartEkosLive), group (EkosLive) -#: kstars.kcfg:1596 +#: kstars.kcfg:1620 #, kde-format msgid "Start Ekos Live on KStars startup." msgstr "" #. i18n: ectx: label, entry (EkosLiveUsername), group (EkosLive) -#: kstars.kcfg:1600 +#: kstars.kcfg:1624 #, fuzzy, kde-format #| msgid "Stop Service" msgid "EkosLive username" msgstr "أوقف الخدمة" #. i18n: ectx: label, entry (EkosLiveOfflineServer), group (EkosLive) -#: kstars.kcfg:1603 +#: kstars.kcfg:1627 #, fuzzy, kde-format #| msgid "Stop Service" msgid "EkosLive Offline Server" msgstr "أوقف الخدمة" #. i18n: ectx: label, entry (EkosLiveOnlineServer), group (EkosLive) -#: kstars.kcfg:1607 +#: kstars.kcfg:1631 #, fuzzy, kde-format #| msgid "Stop Service" msgid "EkosLive Online Server" msgstr "أوقف الخدمة" #. i18n: ectx: label, entry (shutterfulCCDs), group (DarkLibrary) -#: kstars.kcfg:1632 +#: kstars.kcfg:1656 #, kde-format msgid "List of CCDs with mechanical or electronic shutters." msgstr "" #. i18n: ectx: label, entry (shutterlessCCDs), group (DarkLibrary) -#: kstars.kcfg:1635 +#: kstars.kcfg:1659 #, kde-format msgid "List of CCDs without mechanical or electronic shutters." msgstr "" #. i18n: ectx: label, entry (UseGraphicalCountsDisplay), group (Manager) -#: kstars.kcfg:1644 +#: kstars.kcfg:1668 #, kde-format msgid "" "Use the graphical version for capture/sequence/total counting using round " @@ -33419,19 +34184,19 @@ msgstr "" #. i18n: ectx: label, entry (MinimumAltLimit), group (Mount) -#: kstars.kcfg:1650 +#: kstars.kcfg:1674 #, kde-format msgid "Default minimum mount altitude limit" msgstr "" #. i18n: ectx: label, entry (MaximumAltLimit), group (Mount) -#: kstars.kcfg:1655 +#: kstars.kcfg:1679 #, kde-format msgid "Default maximum mount altitude limit." msgstr "" #. i18n: ectx: whatsthis, entry (MaximumAltLimit), group (Mount) -#: kstars.kcfg:1656 +#: kstars.kcfg:1680 #, kde-format msgid "" "Maximum telescope altitude limit. If the telescope is above this limit, it " @@ -33439,25 +34204,25 @@ msgstr "" #. i18n: ectx: label, entry (EnableAltitudeLimits), group (Mount) -#: kstars.kcfg:1660 +#: kstars.kcfg:1684 #, kde-format msgid "Enable mount altitude limits." msgstr "" #. i18n: ectx: label, entry (ConfirmBelowHorizon), group (Mount) -#: kstars.kcfg:1664 +#: kstars.kcfg:1688 #, kde-format msgid "Warn user before command mount to go to a target below horizon." msgstr "" #. i18n: ectx: label, entry (MeridianFlipOffsetDegrees), group (Mount) -#: kstars.kcfg:1668 +#: kstars.kcfg:1692 #, fuzzy, kde-format msgid "Default hour angle to perform meridian flip in degrees." msgstr "تلقائي عرض من التقاط" #. i18n: ectx: whatsthis, entry (MeridianFlipOffsetDegrees), group (Mount) -#: kstars.kcfg:1669 +#: kstars.kcfg:1693 #, kde-format msgid "" "If the target hour angle exceeds this value, Ekos will command a meridian " @@ -33465,13 +34230,13 @@ msgstr "" #. i18n: ectx: label, entry (MaximumHaLimit), group (Mount) -#: kstars.kcfg:1673 +#: kstars.kcfg:1697 #, fuzzy, kde-format msgid "Default maximum limit for the hour angle." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (MaximumHaLimit), group (Mount) -#: kstars.kcfg:1674 +#: kstars.kcfg:1698 #, kde-format msgid "" "Maximum limit for the hour angle of the telescope. If the hour angle of the " @@ -33479,79 +34244,79 @@ msgstr "" #. i18n: ectx: label, entry (EnableHaLimit), group (Mount) -#: kstars.kcfg:1678 +#: kstars.kcfg:1702 #, kde-format msgid "Enable mount hour angle limit." msgstr "" #. i18n: ectx: label, entry (ExecuteMeridianFlip), group (Mount) -#: kstars.kcfg:1682 +#: kstars.kcfg:1706 #, kde-format msgid "Flips the mount when reaching the meridian, if supported." msgstr "" #. i18n: ectx: label, entry (LeftRightReversed), group (Mount) -#: kstars.kcfg:1686 +#: kstars.kcfg:1710 #, kde-format msgid "Reverse the direction of right and left buttons in mount control." msgstr "" #. i18n: ectx: label, entry (UpDownReversed), group (Mount) -#: kstars.kcfg:1690 +#: kstars.kcfg:1714 #, kde-format msgid "Reverse the direction of up and down buttons in mount control." msgstr "" #. i18n: ectx: label, entry (ParkEveryDay), group (Mount) -#: kstars.kcfg:1694 +#: kstars.kcfg:1718 #, fuzzy, kde-format msgid "Automatically start parking timer on startup." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (ParkTime), group (Mount) -#: kstars.kcfg:1698 +#: kstars.kcfg:1722 #, kde-format msgid "Park mount at this time in 12 hour format." msgstr "" #. i18n: ectx: label, entry (DefaultObserver), group (Capture) -#: kstars.kcfg:1704 +#: kstars.kcfg:1728 #, fuzzy, kde-format msgid "Default observer full name." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (SyncFOVPA), group (Capture) -#: kstars.kcfg:1707 +#: kstars.kcfg:1731 #, kde-format msgid "Sync FOV indicator Position Angle with Rotator Settings Position Angle" msgstr "" #. i18n: ectx: label, entry (PAMultiplier), group (Capture) -#: kstars.kcfg:1711 +#: kstars.kcfg:1735 #, fuzzy, kde-format msgid "Position angle multiplier" msgstr "الموضع الزاوية" #. i18n: ectx: label, entry (PAOffset), group (Capture) -#: kstars.kcfg:1715 +#: kstars.kcfg:1739 #, fuzzy, kde-format msgid "Position angle offset" msgstr "الموضع الزاوية" #. i18n: ectx: label, entry (PAPierSide), group (Capture) -#: kstars.kcfg:1719 +#: kstars.kcfg:1743 #, fuzzy, kde-format msgid "Position angle calibration pier side" msgstr "الموضع الزاوية" #. i18n: ectx: label, entry (GuideDeviation), group (Capture) -#: kstars.kcfg:1722 +#: kstars.kcfg:1746 #, kde-format msgid "Default maximum permittable guide deviation" msgstr "" #. i18n: ectx: whatsthis, entry (GuideDeviation), group (Capture) -#: kstars.kcfg:1723 +#: kstars.kcfg:1747 #, kde-format msgid "" "If guide deviation exceeds this limit, the exposure will be automatically " @@ -33559,7 +34324,7 @@ msgstr "" #. i18n: ectx: label, entry (GuideDeviationReps), group (Capture) -#: kstars.kcfg:1727 +#: kstars.kcfg:1751 #, kde-format msgid "" "Number of consecutive samples guide deviation needs to be high to abort " @@ -33567,7 +34332,7 @@ msgstr "" #. i18n: ectx: whatsthis, entry (GuideDeviationReps), group (Capture) -#: kstars.kcfg:1728 +#: kstars.kcfg:1752 #, kde-format msgid "" "Sets the number of consecutive samples guide deviation needs to be high to " @@ -33575,13 +34340,13 @@ msgstr "" #. i18n: ectx: label, entry (StartGuideDeviation), group (Capture) -#: kstars.kcfg:1732 +#: kstars.kcfg:1756 #, kde-format msgid "Default maximum permittable guide deviation before capture start" msgstr "" #. i18n: ectx: whatsthis, entry (StartGuideDeviation), group (Capture) -#: kstars.kcfg:1733 +#: kstars.kcfg:1757 #, kde-format msgid "" "If guide deviation exceeds this limit before capture start, starting an " @@ -33589,13 +34354,13 @@ msgstr "" #. i18n: ectx: label, entry (HFRDeviation), group (Capture) -#: kstars.kcfg:1737 +#: kstars.kcfg:1761 #, kde-format msgid "Default maximum permittable HFR deviation" msgstr "" #. i18n: ectx: whatsthis, entry (HFRDeviation), group (Capture) -#: kstars.kcfg:1738 +#: kstars.kcfg:1762 #, kde-format msgid "" "If HFR deviation exceeds this limit, the autofocus routine will be " @@ -33603,13 +34368,13 @@ msgstr "" #. i18n: ectx: label, entry (MaxFocusTemperatureDelta), group (Capture) -#: kstars.kcfg:1742 +#: kstars.kcfg:1766 #, fuzzy, kde-format msgid "Default maximum focus temperature delta" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (MaxFocusTemperatureDelta), group (Capture) -#: kstars.kcfg:1743 +#: kstars.kcfg:1767 #, kde-format msgid "" "If the temperature change exceeds this limit, the autofocus routine will be " @@ -33617,46 +34382,46 @@ msgstr "" #. i18n: ectx: label, entry (AutoDark), group (Capture) -#: kstars.kcfg:1747 +#: kstars.kcfg:1771 #, kde-format msgid "" "Automatically apply dark subtraction if a suitable dark frame is available." msgstr "" #. i18n: ectx: label, entry (EnforceGuideDeviation), group (Capture) -#: kstars.kcfg:1751 +#: kstars.kcfg:1775 #, kde-format msgid "Enforce guiding deviation limit." msgstr "" #. i18n: ectx: label, entry (EnforceAutofocusHFR), group (Capture) -#: kstars.kcfg:1755 +#: kstars.kcfg:1779 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Enforce Autofocus on HFR limit." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" #. i18n: ectx: label, entry (EnforceAutofocusOnTemperature), group (Capture) -#: kstars.kcfg:1759 +#: kstars.kcfg:1783 #, fuzzy, kde-format #| msgid "Autofocus on Filter Change" msgid "Enforce Autofocus on temperature change." msgstr "تركيز بؤري تلقائي عند تغيير المرشّح" #. i18n: ectx: label, entry (EnforceRefocusEveryN), group (Capture) -#: kstars.kcfg:1763 +#: kstars.kcfg:1787 #, kde-format msgid "Enforce Refocus Every N Minutes." msgstr "" #. i18n: ectx: label, entry (RefocusEveryN), group (Capture) -#: kstars.kcfg:1767 +#: kstars.kcfg:1791 #, kde-format msgid "Number of minute between forced refocus attempts" msgstr "" #. i18n: ectx: whatsthis, entry (RefocusEveryN), group (Capture) -#: kstars.kcfg:1768 +#: kstars.kcfg:1792 #, kde-format msgid "" "Sets the time interval before forced autofocus attempts during a capture " @@ -33664,33 +34429,33 @@ msgstr "" #. i18n: ectx: label, entry (RefocusAfterMeridianFlip), group (Capture) -#: kstars.kcfg:1772 +#: kstars.kcfg:1796 #, fuzzy, kde-format msgid "Refocus after meridian flip is done" msgstr "تلقائي عرض من التقاط" #. i18n: ectx: label, entry (ResetMountModelAfterMeridian), group (Capture) -#: kstars.kcfg:1776 +#: kstars.kcfg:1800 #, kde-format msgid "Reset mount model after meridian flip." msgstr "" "عد للتعيين الابتدائي لأداة توجيه الحامل بعد عملية عكس الثقل عند خط الزوال." #. i18n: ectx: label, entry (ForcedFlip), group (Capture) -#: kstars.kcfg:1780 +#: kstars.kcfg:1804 #, fuzzy, kde-format #| msgid "Meridian flip started." msgid "Use Forced meridian flips if supported." msgstr "بدأ تدوير الحامل إلى الجهة الأخرى من خطّ الزّوال" #. i18n: ectx: label, entry (CalibrationADUValue), group (Capture) -#: kstars.kcfg:1784 +#: kstars.kcfg:1808 #, fuzzy, kde-format msgid "Desired flat field ADU" msgstr "صف البيانات حقول" #. i18n: ectx: whatsthis, entry (CalibrationADUValue), group (Capture) -#: kstars.kcfg:1785 +#: kstars.kcfg:1809 #, kde-format msgid "" "If set, Ekos will capture a few flat images to determine the optimal " @@ -33698,45 +34463,45 @@ msgstr "" #. i18n: ectx: label, entry (CalibrationADUValueTolerance), group (Capture) -#: kstars.kcfg:1789 +#: kstars.kcfg:1813 #, fuzzy, kde-format msgid "ADU Value tolerance" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (CalibrationADUValueTolerance), group (Capture) -#: kstars.kcfg:1790 +#: kstars.kcfg:1814 #, kde-format msgid "" "Maximum difference between measured and target ADU values to deem the value " "as acceptable." msgstr "" -#. i18n: ectx: label, entry (CalibrationFlatSourceIndex), group (Capture) -#: kstars.kcfg:1794 -#, kde-format -msgid "Index of flat source option." -msgstr "" +#. i18n: ectx: label, entry (CalibrationPreActionIndex), group (Capture) +#: kstars.kcfg:1818 +#, fuzzy, kde-format +msgid "ORed list of calibration pre-actions." +msgstr "البرج الاسم خيارات" #. i18n: ectx: label, entry (CalibrationFlatDurationIndex), group (Capture) -#: kstars.kcfg:1798 +#: kstars.kcfg:1822 #, kde-format msgid "Index of flat duration option." msgstr "" #. i18n: ectx: label, entry (CalibrationWallAz), group (Capture) -#: kstars.kcfg:1802 +#: kstars.kcfg:1826 #, kde-format msgid "Azimuth of calibration wall location." msgstr "" #. i18n: ectx: label, entry (CalibrationWallAlt), group (Capture) -#: kstars.kcfg:1806 +#: kstars.kcfg:1830 #, kde-format msgid "Altitude of calibration wall location." msgstr "" #. i18n: ectx: label, entry (MaxTemperatureDiff), group (Capture) -#: kstars.kcfg:1810 +#: kstars.kcfg:1834 #, kde-format msgid "" "Maximum acceptable difference between requested and measured temperature set " @@ -33744,27 +34509,27 @@ msgstr "" #. i18n: ectx: label, entry (MaxStartGuiderDrift), group (Capture) -#: kstars.kcfg:1814 +#: kstars.kcfg:1838 #, kde-format msgid "Maximum acceptable guider drift allowed before starting capture." msgstr "" #. i18n: ectx: label, entry (EnforceStartGuiderDrift), group (Capture) -#: kstars.kcfg:1818 +#: kstars.kcfg:1842 #, kde-format msgid "" "Enforce maximum acceptable guider drift allowed before starting capture." msgstr "" #. i18n: ectx: label, entry (GuidingSettle), group (Capture) -#: kstars.kcfg:1822 +#: kstars.kcfg:1846 #, kde-format msgid "" "Wait this many seconds after guiding is resumed before starting capture." msgstr "" #. i18n: ectx: label, entry (AlwaysResetSequenceWhenStarting), group (Capture) -#: kstars.kcfg:1826 +#: kstars.kcfg:1850 #, kde-format msgid "" "

    When starting to process a sequence list, reset all " @@ -33773,13 +34538,13 @@ msgstr "" #. i18n: ectx: label, entry (FlatSyncFocus), group (Capture) -#: kstars.kcfg:1830 +#: kstars.kcfg:1854 #, kde-format msgid "Capture flat frames at the same focus position of light frames." msgstr "" #. i18n: ectx: label, entry (HFRThresholdPercentage), group (Capture) -#: kstars.kcfg:1834 +#: kstars.kcfg:1858 #, kde-format msgid "" "Increase autofocus HFR value by this percentage gain and store it in Capture " @@ -33787,14 +34552,14 @@ msgstr "" #. i18n: ectx: label, entry (UseMedianFocus), group (Capture) -#: kstars.kcfg:1838 +#: kstars.kcfg:1862 #, kde-format msgid "" "Calculate median focus value after each autofocus operation is complete." msgstr "" #. i18n: ectx: label, entry (SaveHFRToFile), group (Capture) -#: kstars.kcfg:1842 +#: kstars.kcfg:1866 #, kde-format msgid "" "When saving a sequence file, save current HFR threshold value. By default, " @@ -33802,34 +34567,34 @@ msgstr "" #. i18n: ectx: label, entry (AutoStretch), group (Capture) -#: kstars.kcfg:1850 +#: kstars.kcfg:1874 #, kde-format msgid "Perform auto stretch on captured images in FITS Viewer." msgstr "" "قم بالتوسيع التلقائي لنطاق التباين لصور FITS الملتقطة في عارض صور FITS." #. i18n: ectx: label, entry (Clipping64KValue), group (Capture) -#: kstars.kcfg:1858 +#: kstars.kcfg:1882 #, kde-format msgid "" "Min value of pixels marked as clipped in the fitsviewer for 16-bit images." msgstr "" #. i18n: ectx: label, entry (Clipping256Value), group (Capture) -#: kstars.kcfg:1862 +#: kstars.kcfg:1886 #, kde-format msgid "" "Min value of pixels marked as clipped in the fitsviewer for 8-bit images." msgstr "" #. i18n: ectx: label, entry (AdaptiveSampling), group (Capture) -#: kstars.kcfg:1867 +#: kstars.kcfg:1891 #, fuzzy, kde-format msgid "Automatically down sample images based on available resources." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (useSummaryPreview), group (Capture) -#: kstars.kcfg:1871 +#: kstars.kcfg:1895 #, fuzzy, kde-format msgid "" "Display every image captured sequence image in the Ekos summary screen " @@ -33837,13 +34602,13 @@ msgstr "مرحبا إلى نجوم ك المستعرض" #. i18n: ectx: label, entry (useDSLRImageViewer), group (Capture) -#: kstars.kcfg:1875 +#: kstars.kcfg:1899 #, fuzzy, kde-format msgid "Display every captured DSLR image in the Image Viewer window." msgstr "مرحبا إلى نجوم ك المستعرض" #. i18n: ectx: label, entry (ForceDSLRPresets), group (Capture) -#: kstars.kcfg:1879 +#: kstars.kcfg:1903 #, kde-format msgid "" "Force exposure times to align with DSLR exposure presets. This insures " @@ -33851,13 +34616,13 @@ msgstr "" #. i18n: ectx: label, entry (CaptureDirectory), group (Capture) -#: kstars.kcfg:1883 +#: kstars.kcfg:1907 #, kde-format msgid "Path to capture directory to save images." msgstr "" #. i18n: ectx: label, entry (PlaceholderFormat), group (Capture) -#: kstars.kcfg:1886 +#: kstars.kcfg:1910 #, fuzzy, kde-format msgid "How to format captured image filename." msgstr "" @@ -33865,110 +34630,110 @@ "مسرد ملفّ" #. i18n: ectx: label, entry (RemoteCaptureDirectory), group (Capture) -#: kstars.kcfg:1890 +#: kstars.kcfg:1914 #, kde-format msgid "Path to remote capture directory to save images." msgstr "" #. i18n: ectx: label, entry (ManualCoverTimeout), group (Capture) -#: kstars.kcfg:1893 +#: kstars.kcfg:1917 #, kde-format msgid "Cover or uncover telescope dialog timeout in seconds." msgstr "" #. i18n: ectx: label, entry (CapturePosition), group (Capture) -#: kstars.kcfg:1897 +#: kstars.kcfg:1921 #, fuzzy, kde-format msgid "Calculate position after captures." msgstr "ضبط هدف رقاقة [رقاقات]." #. i18n: ectx: whatsthis, entry (AbsTicksSpin), group (Focus) -#: kstars.kcfg:1903 +#: kstars.kcfg:1927 #, fuzzy, kde-format msgid "The desired focuser position." msgstr "الميلان من الموضع" #. i18n: ectx: label, entry (FocusExposure), group (Focus) -#: kstars.kcfg:1907 +#: kstars.kcfg:1931 #, fuzzy, kde-format msgid "Exposure to use during focus" msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: whatsthis, entry (FocusExposure), group (Focus) -#: kstars.kcfg:1908 +#: kstars.kcfg:1932 #, fuzzy, kde-format msgid "Specifies the length of exposure to use during focus." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: label, entry (FocusBinning), group (Focus) -#: kstars.kcfg:1912 +#: kstars.kcfg:1936 #, fuzzy, kde-format msgid "Default Camera binning" msgstr "بصري" #. i18n: ectx: whatsthis, entry (FocusBinning), group (Focus) -#: kstars.kcfg:1913 +#: kstars.kcfg:1937 #, fuzzy, kde-format msgid "Set binning of camera while in focus mode." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (FocusGain), group (Focus) -#: kstars.kcfg:1917 +#: kstars.kcfg:1941 #, fuzzy, kde-format msgid "Default Focuser gain value" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (FocusGain), group (Focus) -#: kstars.kcfg:1918 +#: kstars.kcfg:1942 #, kde-format msgid "" "Specifies gain value of CCD when performing focusing if supported by camera." msgstr "" #. i18n: ectx: label, entry (FocusISO), group (Focus) -#: kstars.kcfg:1922 +#: kstars.kcfg:1946 #, fuzzy, kde-format msgid "Default Focuser Camera ISO value" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (DefaultFocusTemperatureSource), group (Focus) -#: kstars.kcfg:1925 +#: kstars.kcfg:1949 #, fuzzy, kde-format msgid "Default focus module temperature source." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (FocusFilter), group (Focus) -#: kstars.kcfg:1928 +#: kstars.kcfg:1952 #, fuzzy, kde-format msgid "Default Filter Wheel filter" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (UseFocusDarkFrame), group (Focus) -#: kstars.kcfg:1931 +#: kstars.kcfg:1955 #, kde-format msgid "Take a dark frame and subtract it before running autofocus operation." msgstr "" #. i18n: ectx: label, entry (FocusSubFrame), group (Focus) -#: kstars.kcfg:1935 +#: kstars.kcfg:1959 #, kde-format msgid "Subframe the focus star during the autofocus procedure." msgstr "" #. i18n: ectx: label, entry (FocusBoxSize), group (Focus) -#: kstars.kcfg:1939 +#: kstars.kcfg:1963 #, fuzzy, kde-format msgid "Default Focuser star selection box size" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (FocusBoxSize), group (Focus) -#: kstars.kcfg:1940 +#: kstars.kcfg:1964 #, kde-format msgid "Set box size to select a focus star." msgstr "" #. i18n: ectx: label, entry (FocusUseFullField), group (Focus) -#: kstars.kcfg:1944 +#: kstars.kcfg:1968 #, kde-format msgid "" "Measure average HFR from all stars combined in a full frame. This method " @@ -33977,7 +34742,7 @@ msgstr "" #. i18n: ectx: label, entry (FocusMaskType), group (Focus) -#: kstars.kcfg:1948 +#: kstars.kcfg:1972 #, kde-format msgid "" "Focus mask type: 0 = All stars used when focusing, 1 = ring mask, 2 = 3x3 " @@ -33985,13 +34750,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusFullFieldInnerRadius), group (Focus) -#: kstars.kcfg:1952 +#: kstars.kcfg:1976 #, kde-format msgid "Full field inner radius." msgstr "" #. i18n: ectx: whatsthis, entry (FocusFullFieldInnerRadius), group (Focus) -#: kstars.kcfg:1953 +#: kstars.kcfg:1977 #, no-c-format, kde-format msgid "" "During full field focusing, stars which are inside this percentage of the " @@ -34000,13 +34765,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusFullFieldOuterRadius), group (Focus) -#: kstars.kcfg:1957 +#: kstars.kcfg:1981 #, kde-format msgid "Full field outer radius." msgstr "" #. i18n: ectx: whatsthis, entry (FocusFullFieldOuterRadius), group (Focus) -#: kstars.kcfg:1958 +#: kstars.kcfg:1982 #, no-c-format, kde-format msgid "" "During full field focusing, stars which are outside this percentage of the " @@ -34015,57 +34780,57 @@ msgstr "" #. i18n: ectx: label, entry (FocusMosaicTileWidth), group (Focus) -#: kstars.kcfg:1962 +#: kstars.kcfg:1986 #, kde-format msgid "Mosaic filter tile width in percent of the frame width." msgstr "" #. i18n: ectx: label, entry (focusMosaicSpace), group (Focus) -#: kstars.kcfg:1966 +#: kstars.kcfg:1990 #, kde-format msgid "Space between the mosaic elements for the mosaic filter." msgstr "" #. i18n: ectx: label, entry (FocusAutoStarEnabled), group (Focus) -#: kstars.kcfg:1970 +#: kstars.kcfg:1994 #, fuzzy, kde-format msgid "Automatically select a star to focus." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (FocusSuspendGuiding), group (Focus) -#: kstars.kcfg:1974 +#: kstars.kcfg:1998 #, kde-format msgid "Suspend guiding while autofocus in progress." msgstr "" #. i18n: ectx: whatsthis, entry (GuideSettleTime), group (Focus) -#: kstars.kcfg:1978 +#: kstars.kcfg:2002 #, fuzzy, kde-format #| msgid "Wait for this key to be pressed" msgid "Wait for this many seconds after resuming guide." msgstr "انتظر حتى يُكبس هذا المفتاح" #. i18n: ectx: whatsthis, entry (FocusUnits), group (Focus) -#: kstars.kcfg:1982 +#: kstars.kcfg:2006 #, kde-format msgid "Display units for HFR and FWHM" msgstr "" #. i18n: ectx: whatsthis, entry (FocusAdaptive), group (Focus) -#: kstars.kcfg:1986 +#: kstars.kcfg:2010 #, kde-format msgid "Whether Adaptive Focusing is enabled." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdaptiveMinMove), group (Focus) -#: kstars.kcfg:1990 +#: kstars.kcfg:2014 #, kde-format msgid "" "When using Adaptive Focusing the minimum allowable focuser move in ticks." msgstr "" #. i18n: ectx: whatsthis, entry (FocusAdaptStart), group (Focus) -#: kstars.kcfg:1994 +#: kstars.kcfg:2018 #, kde-format msgid "" "Whether to adapt the focuser starting position at the beginning of an " @@ -34073,7 +34838,7 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusAdaptiveMaxMove), group (Focus) -#: kstars.kcfg:1998 +#: kstars.kcfg:2022 #, kde-format msgid "" "When using Adaptive Focusing the maximum total allowable focuser move in " @@ -34081,81 +34846,81 @@ msgstr "" #. i18n: ectx: label, entry (FocusDetection), group (Focus) -#: kstars.kcfg:2003 +#: kstars.kcfg:2027 #, fuzzy, kde-format msgid "Star detection algorithm" msgstr "التعيين اسقاط الخوارزميات" #. i18n: ectx: label, entry (FocusSEPProfile), group (Focus) -#: kstars.kcfg:2007 +#: kstars.kcfg:2031 #, fuzzy, kde-format msgid "Focus source extraction profile" msgstr "انتقِ إدخال الأسس" #. i18n: ectx: label, entry (FocusAlgorithm), group (Focus) -#: kstars.kcfg:2010 +#: kstars.kcfg:2034 #, kde-format msgid "Focus process algorithm" msgstr "" #. i18n: ectx: whatsthis, entry (FocusCurveFit), group (Focus) -#: kstars.kcfg:2014 +#: kstars.kcfg:2038 #, kde-format msgid "The type of curve to fit" msgstr "" #. i18n: ectx: whatsthis, entry (FocusStarMeasure), group (Focus) -#: kstars.kcfg:2018 +#: kstars.kcfg:2042 #, kde-format msgid "The type of star measure to use." msgstr "" #. i18n: ectx: whatsthis, entry (FocusStarPSF), group (Focus) -#: kstars.kcfg:2022 +#: kstars.kcfg:2046 #, kde-format msgid "The type of star PSF to use if curve fitting star profiles." msgstr "" #. i18n: ectx: whatsthis, entry (FocusUseWeights), group (Focus) -#: kstars.kcfg:2026 +#: kstars.kcfg:2050 #, fuzzy, kde-format #| msgid "Observatory is in the shutdown process" msgid "Whether to use weights in the curve fitting process." msgstr "دخل المرصد عمليّة الإطفاء" #. i18n: ectx: whatsthis, entry (FocusR2Limit), group (Focus) -#: kstars.kcfg:2030 +#: kstars.kcfg:2054 #, kde-format msgid "The minimum acceptable R2 value of a curve fit." msgstr "" #. i18n: ectx: whatsthis, entry (FocusRefineCurveFit), group (Focus) -#: kstars.kcfg:2034 +#: kstars.kcfg:2058 #, kde-format msgid "Whether to refine the curve fit by looking for and discarding outliers." msgstr "" #. i18n: ectx: whatsthis, entry (focusFramesCount), group (Focus) -#: kstars.kcfg:2038 +#: kstars.kcfg:2062 #, kde-format msgid "How many frames to average over at each step in the Autofocus process." msgstr "" #. i18n: ectx: label, entry (FocusMultiRowAverage), group (Focus) -#: kstars.kcfg:2042 +#: kstars.kcfg:2066 #, fuzzy, kde-format #| msgid "Number of images to capture" msgid "Number of rows to combine in the Bahtinov average calculation." msgstr "عدد الصور المراد التقاطها" #. i18n: ectx: label, entry (FocusGaussianSigma), group (Focus) -#: kstars.kcfg:2046 +#: kstars.kcfg:2070 #, kde-format msgid "Gaussian blur sigma value." msgstr "" #. i18n: ectx: label, entry (FocusThreshold), group (Focus) -#: kstars.kcfg:2050 +#: kstars.kcfg:2074 #, kde-format msgid "" "Relative percentage strength of centroid edge pixel strength to average " @@ -34163,19 +34928,19 @@ msgstr "" #. i18n: ectx: label, entry (FocusGaussianKernelSize), group (Focus) -#: kstars.kcfg:2054 +#: kstars.kcfg:2078 #, kde-format msgid "Gaussian blur kernel size." msgstr "" #. i18n: ectx: label, entry (FocusTolerance), group (Focus) -#: kstars.kcfg:2058 +#: kstars.kcfg:2082 #, fuzzy, kde-format msgid "Default Focuser tolerance value" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (FocusTolerance), group (Focus) -#: kstars.kcfg:2059 +#: kstars.kcfg:2083 #, kde-format msgid "" "The tolerance specifies the percentage difference between the current " @@ -34185,13 +34950,13 @@ msgstr "" #. i18n: ectx: whatsthis, entry (FocusWalk), group (Focus) -#: kstars.kcfg:2064 +#: kstars.kcfg:2088 #, kde-format msgid "The type of walk the focuser will take during an Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (FocusSettleTime), group (Focus) -#: kstars.kcfg:2068 +#: kstars.kcfg:2092 #, kde-format msgid "" "Wait for this many seconds after moving the focuser before capturing the " @@ -34199,13 +34964,13 @@ msgstr "" #. i18n: ectx: label, entry (FocusTicks), group (Focus) -#: kstars.kcfg:2072 +#: kstars.kcfg:2096 #, fuzzy, kde-format msgid "Default Focuser step ticks" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (FocusTicks), group (Focus) -#: kstars.kcfg:2073 +#: kstars.kcfg:2097 #, kde-format msgid "" "Step size of the absolute focuser. The step size TICKS should be adjusted so " @@ -34214,50 +34979,50 @@ msgstr "" #. i18n: ectx: whatsthis, entry (FocusOutSteps), group (Focus) -#: kstars.kcfg:2077 +#: kstars.kcfg:2101 #, kde-format msgid "The number of steps to move outwards for a Classic Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (focusNumSteps), group (Focus) -#: kstars.kcfg:2081 +#: kstars.kcfg:2105 #, kde-format msgid "" "The total number of steps for a Fixed Steps or CFZ Shuffle Autofocus run." msgstr "" #. i18n: ectx: label, entry (FocusMaxTravel), group (Focus) -#: kstars.kcfg:2085 +#: kstars.kcfg:2109 #, kde-format msgid "Maximum Focus Travel Distance" msgstr "" #. i18n: ectx: whatsthis, entry (FocusMaxTravel), group (Focus) -#: kstars.kcfg:2086 +#: kstars.kcfg:2110 #, fuzzy, kde-format msgid "Set the maximum travel distance of an absolute focuser." msgstr "الـ الأقصى لـ." #. i18n: ectx: whatsthis, entry (FocusMaxSingleStep), group (Focus) -#: kstars.kcfg:2090 +#: kstars.kcfg:2114 #, fuzzy, kde-format msgid "The maximum size of a single step." msgstr "الـ الأقصى لـ." #. i18n: ectx: whatsthis, entry (FocusBacklash), group (Focus) -#: kstars.kcfg:2094 +#: kstars.kcfg:2118 #, kde-format msgid "The amount of driver backlash." msgstr "" #. i18n: ectx: whatsthis, entry (FocusAFOverscan), group (Focus) -#: kstars.kcfg:2098 +#: kstars.kcfg:2122 #, kde-format msgid "The amount of Autofocus Overscan." msgstr "" #. i18n: ectx: whatsthis, entry (FocusMotionTimeout), group (Focus) -#: kstars.kcfg:2106 +#: kstars.kcfg:2130 #, kde-format msgid "" "Maximum time in seconds to wait for a focuser to move to desired position " @@ -34265,86 +35030,86 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZAlgorithm), group (Focus) -#: kstars.kcfg:2111 +#: kstars.kcfg:2135 #, kde-format msgid "The type of CFZ Algorithm to use." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZTolerance), group (Focus) -#: kstars.kcfg:2115 +#: kstars.kcfg:2139 #, kde-format msgid "The user defined tolerance to use for Classic and Wavefront algos." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZTau), group (Focus) -#: kstars.kcfg:2119 +#: kstars.kcfg:2143 #, kde-format msgid "The user defined tolerance to use for the Gold algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZDisplayVCurve), group (Focus) -#: kstars.kcfg:2123 +#: kstars.kcfg:2147 #, kde-format msgid "Whether to display the CFZ on the v-curve after an Autofocus run." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZWavelength), group (Focus) -#: kstars.kcfg:2127 +#: kstars.kcfg:2151 #, kde-format msgid "The wavelength in nm to use in the Gold algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZAperture), group (Focus) -#: kstars.kcfg:2131 +#: kstars.kcfg:2155 #, kde-format msgid "Telescope aperture in mm to use in CFZ calcs." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZFNumber), group (Focus) -#: kstars.kcfg:2135 +#: kstars.kcfg:2159 #, kde-format msgid "The f# to use in the CFZ algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZSeeing), group (Focus) -#: kstars.kcfg:2139 +#: kstars.kcfg:2163 #, kde-format msgid "The total seeing in arc-secs to use in the CFZ algo." msgstr "" #. i18n: ectx: whatsthis, entry (focusCFZStepSize), group (Focus) -#: kstars.kcfg:2143 +#: kstars.kcfg:2167 #, fuzzy, kde-format #| msgid "Size of chip or film, in millimeters" msgid "The size of a focuser tick in micrometers." msgstr "مقاسات المستشعر أو الفلم بالملم" #. i18n: ectx: whatsthis, entry (focusAdvSteps), group (Focus) -#: kstars.kcfg:2148 +#: kstars.kcfg:2172 #, kde-format msgid "Focus Advisor recommended step size" msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvOutStepMult), group (Focus) -#: kstars.kcfg:2152 +#: kstars.kcfg:2176 #, kde-format msgid "Focus Advisor recommended Out Step Multiple" msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvStepSize), group (Focus) -#: kstars.kcfg:2156 +#: kstars.kcfg:2180 #, kde-format msgid "Whether to accept Focus Advisor recommendation on Step Size." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvOutStepMultiple), group (Focus) -#: kstars.kcfg:2160 +#: kstars.kcfg:2184 #, kde-format msgid "Whether to accept Focus Advisor recommendation on Out Step Multiple." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvCamera), group (Focus) -#: kstars.kcfg:2164 +#: kstars.kcfg:2188 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Camera and Filter Wheel " @@ -34352,94 +35117,166 @@ msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvSettingsTab), group (Focus) -#: kstars.kcfg:2168 +#: kstars.kcfg:2192 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Settings Tab Parameters." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvProcessTab), group (Focus) -#: kstars.kcfg:2172 +#: kstars.kcfg:2196 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Process Tab Parameters." msgstr "" #. i18n: ectx: whatsthis, entry (focusAdvMechanicsTab), group (Focus) -#: kstars.kcfg:2176 +#: kstars.kcfg:2200 #, kde-format msgid "" "Whether to accept Focus Advisor recommendation on Mechanics Tab Parameters." msgstr "" #. i18n: ectx: label, entry (FocusSplitter), group (Focus) -#: kstars.kcfg:2181 +#: kstars.kcfg:2205 #, fuzzy, kde-format msgid "Position of FocusSplitter." msgstr "الموضع الزاوية" #. i18n: ectx: label, entry (rightLayout), group (Focus) -#: kstars.kcfg:2184 +#: kstars.kcfg:2208 #, fuzzy, kde-format msgid "Position of rightLayout." msgstr "الموضع من وقت." #. i18n: ectx: whatsthis, entry (adaptFocusBFO), group (Focus) -#: kstars.kcfg:2187 +#: kstars.kcfg:2211 #, kde-format msgid "Whether to use Adaptive Focus in the Build Filter Offsets utility." msgstr "" +#. i18n: ectx: whatsthis, entry (abInsTileSelection), group (Focus) +#: kstars.kcfg:2216 +#, kde-format +msgid "Which set of tiles to use in Aberration Inspector." +msgstr "" + +#. i18n: ectx: label, entry (abInsShowLabels), group (Focus) +#: kstars.kcfg:2220 +#, kde-format +msgid "Show Max Min labels on Aberration Inspector graph." +msgstr "" + +#. i18n: ectx: label, entry (abInsShowCFZ), group (Focus) +#: kstars.kcfg:2224 +#, kde-format +msgid "Show Critical Focus Zone on Aberration Inspector graph." +msgstr "" + +#. i18n: ectx: label, entry (abInsOptCentres), group (Focus) +#: kstars.kcfg:2228 +#, kde-format +msgid "Whether to optimise tile centres used in Aberration Inspector calcs." +msgstr "" + +#. i18n: ectx: label, entry (abInsHSplitter), group (Focus) +#: kstars.kcfg:2232 +#, kde-format +msgid "Position of HSplitter in Aberration Inspector." +msgstr "" + +#. i18n: ectx: label, entry (abInsVSplitter), group (Focus) +#: kstars.kcfg:2235 +#, kde-format +msgid "Position of VSplitter in Aberration Inspector." +msgstr "" + +#. i18n: ectx: whatsthis, entry (abInsSelection), group (Focus) +#: kstars.kcfg:2238 +#, kde-format +msgid "Aberration Inspector 3D graphic selection mode." +msgstr "" + +#. i18n: ectx: whatsthis, entry (abInsTheme), group (Focus) +#: kstars.kcfg:2242 +#, kde-format +msgid "Aberration Inspector 3D graphic theme." +msgstr "" + +#. i18n: ectx: label, entry (abInsLabels), group (Focus) +#: kstars.kcfg:2246 +#, kde-format +msgid "Aberration Inspector 3D graphic show labels." +msgstr "" + +#. i18n: ectx: label, entry (abInsSensor), group (Focus) +#: kstars.kcfg:2250 +#, kde-format +msgid "Aberration Inspector 3D graphic show sensor." +msgstr "" + +#. i18n: ectx: label, entry (abInsPetzvalWire), group (Focus) +#: kstars.kcfg:2254 +#, kde-format +msgid "Aberration Inspector 3D graphic show Petzval wire." +msgstr "" + +#. i18n: ectx: label, entry (abInsPetzvalSurface), group (Focus) +#: kstars.kcfg:2258 +#, kde-format +msgid "Aberration Inspector 3D graphic show Petzval surface." +msgstr "" + #. i18n: ectx: label, entry (FocusSextractorType), group (StellarSolver) -#: kstars.kcfg:2194 +#: kstars.kcfg:2264 #, fuzzy, kde-format msgid "Internal or External Sextractor for Focusing." msgstr "خادم" #. i18n: ectx: label, entry (FocusOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2198 +#: kstars.kcfg:2268 #, kde-format msgid "Options Profile for Sextraction when Focusing." msgstr "" #. i18n: ectx: label, entry (HFRSextractorType), group (StellarSolver) -#: kstars.kcfg:2202 +#: kstars.kcfg:2272 #, fuzzy, kde-format msgid "Internal or External Sextractor to compute subs HFR." msgstr "خادم" #. i18n: ectx: label, entry (HFROptionsProfile), group (StellarSolver) -#: kstars.kcfg:2206 +#: kstars.kcfg:2276 #, kde-format msgid "Options Profile for Sextraction to compute subs HFR" msgstr "" #. i18n: ectx: label, entry (GuideSextractorType), group (StellarSolver) -#: kstars.kcfg:2210 +#: kstars.kcfg:2280 #, fuzzy, kde-format msgid "Internal or External Sextractor for Guiding." msgstr "خادم" #. i18n: ectx: label, entry (GuideOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2214 +#: kstars.kcfg:2284 #, kde-format msgid "Options Profile for Sextraction when Guiding." msgstr "" #. i18n: ectx: label, entry (SolveSextractorType), group (StellarSolver) -#: kstars.kcfg:2218 +#: kstars.kcfg:2288 #, fuzzy, kde-format msgid "Internal, External, or BuiltIn Sextractor for Solving." msgstr "خادم" #. i18n: ectx: label, entry (SolverMode), group (StellarSolver) -#: kstars.kcfg:2222 +#: kstars.kcfg:2292 #, kde-format msgid "Local (0) or Remote (1) solver." msgstr "" #. i18n: ectx: label, entry (SolverType), group (StellarSolver) -#: kstars.kcfg:2226 +#: kstars.kcfg:2296 #, kde-format msgid "" "Local solving method. 0 for Internal Solver. 1 for Local Astrometry. 2 for " @@ -34447,98 +35284,98 @@ msgstr "" #. i18n: ectx: label, entry (SolveOptionsProfile), group (StellarSolver) -#: kstars.kcfg:2230 +#: kstars.kcfg:2300 #, kde-format msgid "Options Profile for Solving." msgstr "" #. i18n: ectx: label, entry (LoggerLevel), group (StellarSolver) -#: kstars.kcfg:2234 +#: kstars.kcfg:2304 #, kde-format msgid "Level of verbosity in the log." msgstr "" #. i18n: ectx: label, entry (AstrometryLogToFile), group (StellarSolver) -#: kstars.kcfg:2238 +#: kstars.kcfg:2308 #, kde-format msgid "Whether to log to a file instead." msgstr "" #. i18n: ectx: label, entry (AstrometryLogFilepath), group (StellarSolver) -#: kstars.kcfg:2242 +#: kstars.kcfg:2312 #, kde-format msgid "Path of the log file to save astrometry logging to." msgstr "" #. i18n: ectx: label, entry (AstrometryIndexFolderList), group (StellarSolver) -#: kstars.kcfg:2246 +#: kstars.kcfg:2316 #, kde-format msgid "List of index folder paths." msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryIndexFolderList), group (StellarSolver) -#: kstars.kcfg:2247 +#: kstars.kcfg:2317 #, kde-format msgid "List of folders in which astrometry Index Files can be found." msgstr "" #. i18n: ectx: label, entry (AlignExposure), group (Align) -#: kstars.kcfg:2253 +#: kstars.kcfg:2323 #, fuzzy, kde-format msgid "Default alignment exposure value" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (AlignExposure), group (Align) -#: kstars.kcfg:2254 +#: kstars.kcfg:2324 #, kde-format msgid "" "Specifies exposure value of camera in seconds when performing plate solving." msgstr "" #. i18n: ectx: label, entry (AlignBinning), group (Align) -#: kstars.kcfg:2258 +#: kstars.kcfg:2328 #, fuzzy, kde-format msgid "Default camera binning in alignment mode" msgstr "بصري" #. i18n: ectx: label, entry (AlignGain), group (Align) -#: kstars.kcfg:2262 +#: kstars.kcfg:2332 #, fuzzy, kde-format msgid "Default camera gain in alignment mode" msgstr "بصري" #. i18n: ectx: label, entry (AlignISO), group (Align) -#: kstars.kcfg:2266 +#: kstars.kcfg:2336 #, fuzzy, kde-format msgid "Default camera ISO in alignment mode" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (AlignDarkFrame), group (Align) -#: kstars.kcfg:2270 +#: kstars.kcfg:2340 #, kde-format msgid "Take a dark frame and subtract it before running astrometry operation." msgstr "" #. i18n: ectx: label, entry (AlignFilter), group (Align) -#: kstars.kcfg:2274 +#: kstars.kcfg:2344 #, fuzzy, kde-format msgid "Default filter wheel filter in alignment mode" msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (AlignUseCurrentFilter), group (Align) -#: kstars.kcfg:2277 +#: kstars.kcfg:2347 #, fuzzy, kde-format msgid "Use currently selected filter in alignment mode." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: whatsthis, entry (AstrometryUseRotator), group (Align) -#: kstars.kcfg:2281 +#: kstars.kcfg:2351 #, kde-format msgid "Use rotator when performing load and slew." msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryRotatorThreshold), group (Align) -#: kstars.kcfg:2285 +#: kstars.kcfg:2355 #, kde-format msgid "" "Threshold between measured and FITS position angles in arcminutes to " @@ -34546,19 +35383,19 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AstrometryFlipRotationAllowed), group (Align) -#: kstars.kcfg:2289 +#: kstars.kcfg:2359 #, kde-format msgid "PA 180° rotation for rotator is accepted after mount flip." msgstr "" #. i18n: ectx: label, entry (SolverGotoOption), group (Align) -#: kstars.kcfg:2293 +#: kstars.kcfg:2363 #, kde-format msgid "Action to take if solver if successful (Sync, Slew to Target, or None)" msgstr "" #. i18n: ectx: label, entry (AstrometrySolverWCS), group (Align) -#: kstars.kcfg:2297 +#: kstars.kcfg:2367 #, kde-format msgid "" "World Coordinate System (WCS). WCS is used to encode RA/DEC coordinates in " @@ -34566,13 +35403,13 @@ msgstr "" #. i18n: ectx: label, entry (AstrometrySolverOverlay), group (Align) -#: kstars.kcfg:2301 +#: kstars.kcfg:2371 #, kde-format msgid "Display received FITS images unto solver FOV rectangle in the sky map." msgstr "" #. i18n: ectx: label, entry (AstrometryDifferentialSlewing), group (Align) -#: kstars.kcfg:2305 +#: kstars.kcfg:2375 #, kde-format msgid "" "Do not use Sync when Slew to Target is selected. Use differential slewing to " @@ -34580,14 +35417,14 @@ msgstr "" #. i18n: ectx: label, entry (AlignAccuracyThreshold), group (Align) -#: kstars.kcfg:2309 +#: kstars.kcfg:2379 #, kde-format msgid "" "Accuracy threshold in arcseconds between solution and target coordinates." msgstr "" #. i18n: ectx: label, entry (AlignSettlingTime), group (Align) -#: kstars.kcfg:2313 +#: kstars.kcfg:2383 #, kde-format msgid "" "Time to wait in milliseconds after telescope slewing is complete before " @@ -34595,7 +35432,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseNoFITS2FITS), group (Align) -#: kstars.kcfg:2317 +#: kstars.kcfg:2387 #, kde-format msgid "" "Do not sanitize FITS. This option should only be checked if astrometry.net " @@ -34603,7 +35440,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseResort), group (Align) -#: kstars.kcfg:2321 +#: kstars.kcfg:2391 #, kde-format msgid "" "Check this option if your image does not have much nebulosity. If it does " @@ -34611,7 +35448,7 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryUseNoVerify), group (Align) -#: kstars.kcfg:2325 +#: kstars.kcfg:2395 #, kde-format msgid "" "This will prevent the solver from looking at an already existing WCS Header " @@ -34620,138 +35457,138 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleLow), group (Align) -#: kstars.kcfg:2333 +#: kstars.kcfg:2403 #, kde-format msgid "Lower image scale." msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleHigh), group (Align) -#: kstars.kcfg:2336 +#: kstars.kcfg:2406 #, fuzzy, kde-format #| msgid "Use images" msgid "Upper image scale." msgstr "استخدم صور" #. i18n: ectx: label, entry (AstrometryAutoUpdateImageScale), group (Align) -#: kstars.kcfg:2339 +#: kstars.kcfg:2409 #, kde-format msgid "" "Automatically update image scale when CCD or Mount parameters are updated." msgstr "" #. i18n: ectx: label, entry (AstrometryImageScaleUnits), group (Align) -#: kstars.kcfg:2343 +#: kstars.kcfg:2413 #, kde-format msgid "" "Image scale units in arcminutes (aw), degrees (dw), or arcsec per pixel (app)" msgstr "" #. i18n: ectx: label, entry (AstrometryUseDownsample), group (Align) -#: kstars.kcfg:2347 +#: kstars.kcfg:2417 #, kde-format msgid "Downsample the image to shrink its size and speed up the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryDownsample), group (Align) -#: kstars.kcfg:2351 +#: kstars.kcfg:2421 #, fuzzy, kde-format msgid "Downsample factor" msgstr "انتقِ الكل" #. i18n: ectx: label, entry (AstrometryAutoDownsample), group (Align) -#: kstars.kcfg:2355 +#: kstars.kcfg:2425 #, fuzzy, kde-format msgid "Automatically downsample based on image size." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (AstrometryPositionRA), group (Align) -#: kstars.kcfg:2363 +#: kstars.kcfg:2433 #, kde-format msgid "" "User supplied Right Ascension value in degrees to be passed to the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryPositionDE), group (Align) -#: kstars.kcfg:2366 +#: kstars.kcfg:2436 #, kde-format msgid "User supplied declination value in degrees to be passed to the solver." msgstr "" #. i18n: ectx: label, entry (AstrometryAutoUpdatePosition), group (Align) -#: kstars.kcfg:2369 +#: kstars.kcfg:2439 #, kde-format msgid "" "Automatically update position coordinates when mounts completes slewing." msgstr "" #. i18n: ectx: label, entry (AstrometryDetectParity), group (Align) -#: kstars.kcfg:2377 +#: kstars.kcfg:2447 #, kde-format msgid "Detect parity and reuse it to speed up solver." msgstr "" #. i18n: ectx: label, entry (AstrometryCustomOptions), group (Align) -#: kstars.kcfg:2381 +#: kstars.kcfg:2451 #, fuzzy, kde-format msgid "Additional optional astrometry.net options" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (AstrometrySolverBinary), group (Align) -#: kstars.kcfg:2384 +#: kstars.kcfg:2454 #, fuzzy, kde-format msgid "astrometry.net solve-field binary" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: whatsthis, entry (AstrometrySolverBinary), group (Align) -#: kstars.kcfg:2385 +#: kstars.kcfg:2455 #, fuzzy, kde-format msgid "Path to astrometry.net solver location." msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (AstrometryWCSInfo), group (Align) -#: kstars.kcfg:2389 +#: kstars.kcfg:2459 #, fuzzy, kde-format msgid "astrometry.net wcsinfo binary" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: whatsthis, entry (AstrometryWCSInfo), group (Align) -#: kstars.kcfg:2390 +#: kstars.kcfg:2460 #, fuzzy, kde-format msgid "Path to astrometry.net wcsinfo location." msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (AstrometryConfFile), group (Align) -#: kstars.kcfg:2394 +#: kstars.kcfg:2464 #, fuzzy, kde-format msgid "astrometry.net configuration file" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: whatsthis, entry (AstrometryConfFile), group (Align) -#: kstars.kcfg:2395 +#: kstars.kcfg:2465 #, kde-format msgid "Path to astrometry.net file location." msgstr "" #. i18n: ectx: whatsthis, entry (SextractorBinary), group (Align) -#: kstars.kcfg:2400 +#: kstars.kcfg:2470 #, kde-format msgid "Path to the Sextractor executable." msgstr "" #. i18n: ectx: whatsthis, entry (WatneyBinary), group (Align) -#: kstars.kcfg:2405 +#: kstars.kcfg:2475 #, fuzzy, kde-format msgid "Path to the Watney Solver executable." msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (AstrometryAPIKey), group (Align) -#: kstars.kcfg:2409 +#: kstars.kcfg:2479 #, fuzzy, kde-format msgid "astrometry.net API Key" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: whatsthis, entry (AstrometryAPIKey), group (Align) -#: kstars.kcfg:2410 +#: kstars.kcfg:2480 #, kde-format msgid "" "Key to access astrometry.net online web services. You must register with " @@ -34759,13 +35596,13 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryAPIURL), group (Align) -#: kstars.kcfg:2414 +#: kstars.kcfg:2484 #, fuzzy, kde-format msgid "astrometry.net API URL" msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (AstrometryUseJPEG), group (Align) -#: kstars.kcfg:2418 +#: kstars.kcfg:2488 #, kde-format msgid "" "Use JPEG format, instead of FITS, to upload images to the astrometry.net " @@ -34773,37 +35610,37 @@ msgstr "" #. i18n: ectx: label, entry (AstrometryTimeout), group (Align) -#: kstars.kcfg:2422 +#: kstars.kcfg:2492 #, fuzzy, kde-format msgid "Timeout in seconds to wait for astrometry solver to complete." msgstr "حدّد بوصة دَخْل ملفّ." #. i18n: ectx: label, entry (PAHMountSpeed), group (Align) -#: kstars.kcfg:2426 +#: kstars.kcfg:2496 #, fuzzy, kde-format msgid "Speed to set mount in Polar Alignment Assistant Tool." msgstr "مركّز على:" #. i18n: ectx: label, entry (PAHRotaion), group (Align) -#: kstars.kcfg:2429 +#: kstars.kcfg:2499 #, kde-format msgid "Rotate mount by this many degrees during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHRefreshAlgorithm), group (Align) -#: kstars.kcfg:2433 +#: kstars.kcfg:2503 #, kde-format msgid "The algorithm used for polar-align refresh." msgstr "" #. i18n: ectx: label, entry (PAHDirection), group (Align) -#: kstars.kcfg:2436 +#: kstars.kcfg:2506 #, kde-format msgid "Mount rotation direction during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHAutoPark), group (Align) -#: kstars.kcfg:2439 +#: kstars.kcfg:2509 #, kde-format msgid "" "Automatically park the mount after Polar Alignment Assistant Tool is " @@ -34811,32 +35648,32 @@ msgstr "" #. i18n: ectx: label, entry (PAHManualSlew), group (Align) -#: kstars.kcfg:2443 +#: kstars.kcfg:2513 #, kde-format msgid "" "User should manually rotate the mount about its axis during polar alignment." msgstr "" #. i18n: ectx: label, entry (PAHExposure), group (Align) -#: kstars.kcfg:2447 +#: kstars.kcfg:2517 #, fuzzy, kde-format msgid "Polar Alignment Assistant exposure duration in seconds." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: label, entry (GuideExposure), group (Guide) -#: kstars.kcfg:2453 +#: kstars.kcfg:2523 #, fuzzy, kde-format msgid "Guider exposure duration in seconds." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: label, entry (GuideDelay), group (Guide) -#: kstars.kcfg:2457 +#: kstars.kcfg:2527 #, fuzzy, kde-format msgid "Delay next exposure by this many seconds." msgstr "ابدأ آلة تصوير الـ هو بوصة ثوان." #. i18n: ectx: label, entry (GuiderType), group (Guide) -#: kstars.kcfg:2461 +#: kstars.kcfg:2531 #, kde-format msgid "" "Which guider process to utilize for guiding (0 Internal Guider, 1 PHD2, 2 " @@ -34844,7 +35681,7 @@ msgstr "" #. i18n: ectx: label, entry (GuideAlgorithm), group (Guide) -#: kstars.kcfg:2465 +#: kstars.kcfg:2535 #, kde-format msgid "" "Which Algorithm to use track guide square (0 smart, 1 SEP, 2 fast, 3 " @@ -34852,31 +35689,31 @@ msgstr "" #. i18n: ectx: label, entry (PHD2Host), group (Guide) -#: kstars.kcfg:2469 +#: kstars.kcfg:2539 #, kde-format msgid "Host name of external PHD2 service" msgstr "" #. i18n: ectx: label, entry (PHD2Port), group (Guide) -#: kstars.kcfg:2473 +#: kstars.kcfg:2543 #, kde-format msgid "PHD2 Event Monitoring Port" msgstr "" #. i18n: ectx: label, entry (LinGuiderHost), group (Guide) -#: kstars.kcfg:2477 +#: kstars.kcfg:2547 #, kde-format msgid "Host name of external lin_guider service" msgstr "" #. i18n: ectx: label, entry (LinGuiderPort), group (Guide) -#: kstars.kcfg:2481 +#: kstars.kcfg:2551 #, kde-format msgid "Lin_guider Event Monitoring Port" msgstr "" #. i18n: ectx: label, entry (CalibrationPulseDuration), group (Guide) -#: kstars.kcfg:2485 +#: kstars.kcfg:2555 #, kde-format msgid "" "Pulse duration in milliseconds used for guiding pulses during calibration " @@ -34884,67 +35721,67 @@ msgstr "" #. i18n: ectx: label, entry (GuideSquareSize), group (Guide) -#: kstars.kcfg:2493 +#: kstars.kcfg:2563 #, kde-format msgid "Guide square size selection in pixels." msgstr "" #. i18n: ectx: label, entry (GuideBinning), group (Guide) -#: kstars.kcfg:2497 +#: kstars.kcfg:2567 #, fuzzy, kde-format msgid "Guide binning." msgstr "فشل في تحميل الصورة " #. i18n: ectx: label, entry (GuideAutoStar), group (Guide) -#: kstars.kcfg:2501 +#: kstars.kcfg:2571 #, fuzzy, kde-format msgid "Automatically select calibration star and perform calibration." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (AutoModeIterations), group (Guide) -#: kstars.kcfg:2509 +#: kstars.kcfg:2579 #, kde-format msgid "Number of automode iterations for calibration process." msgstr "" #. i18n: ectx: label, entry (GuideLostStarTimeout), group (Guide) -#: kstars.kcfg:2513 +#: kstars.kcfg:2583 #, kde-format msgid "When star tracking is lost, wait this many seconds before aborting." msgstr "" #. i18n: ectx: label, entry (GuideCalibrationTimeout), group (Guide) -#: kstars.kcfg:2517 +#: kstars.kcfg:2587 #, kde-format msgid "When calibration starts, wait this many seconds before aborting." msgstr "" #. i18n: ectx: label, entry (GuideMaxDeltaRMS), group (Guide) -#: kstars.kcfg:2521 +#: kstars.kcfg:2591 #, kde-format msgid "Maximum delta RMS permitted while guiding before aborting." msgstr "" #. i18n: ectx: label, entry (GuideMaxHFR), group (Guide) -#: kstars.kcfg:2525 +#: kstars.kcfg:2595 #, kde-format msgid "Maximum HFR permitted for SEP MultiStar guide star." msgstr "" #. i18n: ectx: label, entry (MaxMultistarReferenceStars), group (Guide) -#: kstars.kcfg:2533 +#: kstars.kcfg:2603 #, kde-format msgid "Maximum number of SEP MultiStar number of stars used as references." msgstr "" #. i18n: ectx: label, entry (TwoAxisEnabled), group (Guide) -#: kstars.kcfg:2537 +#: kstars.kcfg:2607 #, kde-format msgid "Use both axes to perform calibration." msgstr "" #. i18n: ectx: label, entry (UseGuideHead), group (Guide) -#: kstars.kcfg:2541 +#: kstars.kcfg:2611 #, kde-format msgid "" "Use the guider chip for guiding from cameras that have a dedicated guider " @@ -34952,25 +35789,25 @@ msgstr "" #. i18n: ectx: label, entry (SaveGuideLog), group (Guide) -#: kstars.kcfg:2545 +#: kstars.kcfg:2615 #, fuzzy, kde-format msgid "Automatically save internal guider user logs." msgstr "تبديل تنسيق" #. i18n: ectx: label, entry (GuideDarkFrame), group (Guide) -#: kstars.kcfg:2549 +#: kstars.kcfg:2619 #, kde-format msgid "Take dark frame for autoguider images." msgstr "" #. i18n: ectx: label, entry (GuideSubframe), group (Guide) -#: kstars.kcfg:2553 +#: kstars.kcfg:2623 #, kde-format msgid "Subframe guide image around selected region" msgstr "" #. i18n: ectx: label, entry (DitherPixels), group (Guide) -#: kstars.kcfg:2557 +#: kstars.kcfg:2627 #, kde-format msgid "" "How many pixels to move between subsequent exposures under auto dithering " @@ -34978,43 +35815,43 @@ msgstr "" #. i18n: ectx: label, entry (DitherFrames), group (Guide) -#: kstars.kcfg:2561 +#: kstars.kcfg:2631 #, kde-format msgid "Dither after this many frames." msgstr "" #. i18n: ectx: label, entry (DitherThreshold), group (Guide) -#: kstars.kcfg:2569 +#: kstars.kcfg:2639 #, kde-format msgid "Maximum distance (pixels) for guiding to be considered settled." msgstr "" #. i18n: ectx: label, entry (DitherTimeout), group (Guide) -#: kstars.kcfg:2573 +#: kstars.kcfg:2643 #, kde-format msgid "Time limit (seconds) on dithering to settle down." msgstr "" #. i18n: ectx: label, entry (DitherMaxIterations), group (Guide) -#: kstars.kcfg:2577 +#: kstars.kcfg:2647 #, kde-format msgid "How many dithering attempts to undertake before giving up." msgstr "" #. i18n: ectx: label, entry (DitherNoGuidingPulse), group (Guide) -#: kstars.kcfg:2581 +#: kstars.kcfg:2651 #, kde-format msgid "Pulse length in milliseconds used for non-guiding dither." msgstr "" #. i18n: ectx: label, entry (DitherFailAbortsAutoGuide), group (Guide) -#: kstars.kcfg:2585 +#: kstars.kcfg:2655 #, fuzzy, kde-format msgid "If dithering fails then abort autoguide." msgstr "جاري التّحميل" #. i18n: ectx: label, entry (DitherWithOnePulse), group (Guide) -#: kstars.kcfg:2589 +#: kstars.kcfg:2659 #, kde-format msgid "" "Dithering amount is randomly generated, pulses are sent, but the resultant " @@ -35025,172 +35862,172 @@ msgstr "" #. i18n: ectx: label, entry (DitherEnabled), group (Guide) -#: kstars.kcfg:2593 +#: kstars.kcfg:2663 #, kde-format msgid "Use Auto Dithering when guiding." msgstr "" #. i18n: ectx: label, entry (DitherNoGuiding), group (Guide) -#: kstars.kcfg:2597 +#: kstars.kcfg:2667 #, fuzzy, kde-format msgid "Perform dithering even when not guiding." msgstr "جاري التّحميل" #. i18n: ectx: label, entry (RAGuideEnabled), group (Guide) -#: kstars.kcfg:2601 +#: kstars.kcfg:2671 #, kde-format msgid "Enable autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (DECGuideEnabled), group (Guide) -#: kstars.kcfg:2605 +#: kstars.kcfg:2675 #, kde-format msgid "Enable autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (NorthDECGuideEnabled), group (Guide) -#: kstars.kcfg:2609 +#: kstars.kcfg:2679 #, kde-format msgid "Enable North autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (SouthDECGuideEnabled), group (Guide) -#: kstars.kcfg:2613 +#: kstars.kcfg:2683 #, kde-format msgid "Enable South autoguiding in the DEC axis." msgstr "" #. i18n: ectx: label, entry (EastRAGuideEnabled), group (Guide) -#: kstars.kcfg:2617 +#: kstars.kcfg:2687 #, kde-format msgid "Enable East autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (WestRAGuideEnabled), group (Guide) -#: kstars.kcfg:2621 +#: kstars.kcfg:2691 #, kde-format msgid "Enable West autoguiding in the RA axis." msgstr "" #. i18n: ectx: label, entry (GuiderAccuracyThreshold), group (Guide) -#: kstars.kcfg:2700 +#: kstars.kcfg:2770 #, kde-format msgid "Accuracy threshold for the Guide Graphs." msgstr "" #. i18n: ectx: label, entry (RADisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2704 +#: kstars.kcfg:2774 #, kde-format msgid "Display the RA Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (DEDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2708 +#: kstars.kcfg:2778 #, kde-format msgid "Display the DEC Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (RACorrDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2712 +#: kstars.kcfg:2782 #, kde-format msgid "Display the RA Corrections Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (DECorrDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2716 +#: kstars.kcfg:2786 #, kde-format msgid "Display the DEC Corrections Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (SNRDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2720 +#: kstars.kcfg:2790 #, kde-format msgid "Display the SNR Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (RMSDisplayedOnGuideGraph), group (Guide) -#: kstars.kcfg:2724 +#: kstars.kcfg:2794 #, kde-format msgid "Display the RMS Error Plot on the Guide Drift Graphics." msgstr "" #. i18n: ectx: label, entry (SchedulerAlgorithm), group (Scheduler) -#: kstars.kcfg:2730 +#: kstars.kcfg:2800 #, fuzzy, kde-format #| msgid "Scheduler aborted." msgid "Scheduler algorithm" msgstr "أُجهض المجدول." #. i18n: ectx: whatsthis, entry (SchedulerLogging), group (Scheduler) -#: kstars.kcfg:2734 +#: kstars.kcfg:2804 #, kde-format msgid "Log Ekos Scheduler Module activity." msgstr "سجّل نشاطات وحدة مجدول إيكوس" #. i18n: ectx: label, entry (StopEkosAfterShutdown), group (Scheduler) -#: kstars.kcfg:2738 +#: kstars.kcfg:2808 #, kde-format msgid "" "After shutdown procedure is successfully executed, shutdown INDI and Ekos." msgstr "" #. i18n: ectx: label, entry (ShutdownScriptTerminatesINDI), group (Scheduler) -#: kstars.kcfg:2742 +#: kstars.kcfg:2812 #, kde-format msgid "" "Whether shutdown script, if exists, terminates INDI server in the process." msgstr "" #. i18n: ectx: label, entry (PreemptiveShutdown), group (Scheduler) -#: kstars.kcfg:2746 +#: kstars.kcfg:2816 #, kde-format msgid "Perform pre-emptive shutdown if no jobs are due for a number of hours." msgstr "" #. i18n: ectx: label, entry (ResetMountModelOnAlignFail), group (Scheduler) -#: kstars.kcfg:2750 +#: kstars.kcfg:2820 #, kde-format msgid "Reset mount model in case of alignment failure." msgstr "" #. i18n: ectx: label, entry (ResetMountModelBeforeJob), group (Scheduler) -#: kstars.kcfg:2754 +#: kstars.kcfg:2824 #, fuzzy, kde-format msgid "Reset mount model before starting each job." msgstr "تلقائي عرض من التقاط" #. i18n: ectx: label, entry (ResetGuideCalibration), group (Scheduler) -#: kstars.kcfg:2758 +#: kstars.kcfg:2828 #, fuzzy, kde-format msgid "Always Reset guiding calibration before starting each job." msgstr "تلقائي عرض من التقاط" #. i18n: ectx: label, entry (ForceAlignmentBeforeJob), group (Scheduler) -#: kstars.kcfg:2762 +#: kstars.kcfg:2832 #, fuzzy, kde-format msgid "Force alignment before starting or restarting each job." msgstr "تلقائي عرض من التقاط" #. i18n: ectx: label, entry (ReuseGuideCalibration), group (Scheduler) -#: kstars.kcfg:2766 +#: kstars.kcfg:2836 #, fuzzy, kde-format msgid "Guider may re-use guiding calibration if one is available." msgstr "تلقائي عرض من التقاط" #. i18n: ectx: label, entry (GuideCalibrationBacklash), group (Scheduler) -#: kstars.kcfg:2774 +#: kstars.kcfg:2844 #, kde-format msgid "Remove DEC backlash when calibrating guider." msgstr "" #. i18n: ectx: label, entry (SerializedCalibration), group (Scheduler) -#: kstars.kcfg:2778 +#: kstars.kcfg:2848 #, fuzzy, kde-format msgid "Last Calibration serialized." msgstr "العميل" #. i18n: ectx: label, entry (RealignAfterCalibrationFailure), group (Scheduler) -#: kstars.kcfg:2781 +#: kstars.kcfg:2851 #, kde-format msgid "" "If guiding calibration fails, run alignment process again before proceeding " @@ -35198,7 +36035,7 @@ msgstr "" #. i18n: ectx: label, entry (PreemptiveShutdownTime), group (Scheduler) -#: kstars.kcfg:2785 +#: kstars.kcfg:2855 #, kde-format msgid "" "Maximum number of hours before the next job is due to trigger a pre-emptive " @@ -35206,7 +36043,7 @@ msgstr "" #. i18n: ectx: label, entry (RememberJobProgress), group (Scheduler) -#: kstars.kcfg:2789 +#: kstars.kcfg:2859 #, fuzzy, kde-format #| msgid "" #| "When loading a sequence file, resume the sequence starting from the last " @@ -35218,14 +36055,22 @@ "عندما يتم تحميل ملف لسلسلة من الصور، استأنف من آخر صورة ملتقطة، في حال " "وجودها." +#. i18n: ectx: label, entry (GreedyScheduling), group (Scheduler) +#: kstars.kcfg:2863 +#, kde-format +msgid "" +"When true, the scheduler tries to run lower priority jobs when no higher " +"priority job can run. Recommended." +msgstr "" + #. i18n: ectx: label, entry (LeadTime), group (Scheduler) -#: kstars.kcfg:2793 +#: kstars.kcfg:2867 #, kde-format msgid "Minimum time between jobs in minutes." msgstr "" #. i18n: ectx: label, entry (PreDawnTime), group (Scheduler) -#: kstars.kcfg:2797 +#: kstars.kcfg:2871 #, kde-format msgid "" "Do not permit jobs to be scheduled or executed past this many minutes before " @@ -35233,7 +36078,7 @@ msgstr "لا تسمح للأعمال أن تجدول أو تنفذ بعد هذا الفارق من الدقائق قبل الفجر." #. i18n: ectx: label, entry (SettingAltitudeCutoff), group (Scheduler) -#: kstars.kcfg:2801 +#: kstars.kcfg:2875 #, kde-format msgid "" "Do not permit jobs to be scheduled less than this many degrees before the " @@ -35241,7 +36086,7 @@ msgstr "" #. i18n: ectx: label, entry (DawnOffset), group (Scheduler) -#: kstars.kcfg:2805 +#: kstars.kcfg:2879 #, kde-format msgid "" "Offset astronomical dawn by this many hours to relax twilight restriction " @@ -35249,7 +36094,7 @@ msgstr "" #. i18n: ectx: label, entry (DuskOffset), group (Scheduler) -#: kstars.kcfg:2809 +#: kstars.kcfg:2883 #, kde-format msgid "" "Offset astronomical dusk by this many hours to relax twilight restriction " @@ -35257,55 +36102,55 @@ msgstr "" #. i18n: ectx: label, entry (TelescopeFocalLength), group (Scheduler) -#: kstars.kcfg:2813 +#: kstars.kcfg:2887 #, kde-format msgid "Telescope focal length in millimeters." msgstr "البعد البؤري للتلسكوب بالميلليمترات" #. i18n: ectx: label, entry (TelescopeFocalReducer), group (Scheduler) -#: kstars.kcfg:2817 +#: kstars.kcfg:2891 #, fuzzy, kde-format msgid "Focal Reducer ratio" msgstr "Boca Raton" #. i18n: ectx: label, entry (CameraPixelWidth), group (Scheduler) -#: kstars.kcfg:2821 +#: kstars.kcfg:2895 #, kde-format msgid "Camera pixel size width in micrometers." msgstr "" #. i18n: ectx: label, entry (CameraPixelHeight), group (Scheduler) -#: kstars.kcfg:2825 +#: kstars.kcfg:2899 #, kde-format msgid "Camera pixel size height in micrometers." msgstr "" #. i18n: ectx: label, entry (CameraWidth), group (Scheduler) -#: kstars.kcfg:2829 +#: kstars.kcfg:2903 #, kde-format msgid "Camera Width in pixels." msgstr "" #. i18n: ectx: label, entry (CameraHeight), group (Scheduler) -#: kstars.kcfg:2833 +#: kstars.kcfg:2907 #, kde-format msgid "Camera Height in pixels." msgstr "" #. i18n: ectx: label, entry (CameraRotation), group (Scheduler) -#: kstars.kcfg:2837 +#: kstars.kcfg:2911 #, kde-format msgid "Position angle of the camera with respect to north." msgstr "" #. i18n: ectx: label, entry (ErrorHandlingStrategy), group (Scheduler) -#: kstars.kcfg:2841 +#: kstars.kcfg:2915 #, kde-format msgid "Strategy how to react, when a job aborts or steps into an error." msgstr "" #. i18n: ectx: label, entry (ErrorHandlingStrategyDelay), group (Scheduler) -#: kstars.kcfg:2845 +#: kstars.kcfg:2919 #, kde-format msgid "" "Delay in minutes how long the scheduler should pause before restarting an " @@ -35313,139 +36158,139 @@ msgstr "" #. i18n: ectx: label, entry (RescheduleErrors), group (Scheduler) -#: kstars.kcfg:2849 +#: kstars.kcfg:2923 #, kde-format msgid "Re-schedule jobs that ran into errors." msgstr "" #. i18n: ectx: label, entry (SchedulerParkDome), group (Scheduler) -#: kstars.kcfg:2861 +#: kstars.kcfg:2935 #, kde-format msgid "Default scheduler checkbox for parking dome on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerParkMount), group (Scheduler) -#: kstars.kcfg:2865 +#: kstars.kcfg:2939 #, kde-format msgid "Default scheduler checkbox for parking mount on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerCloseDustCover), group (Scheduler) -#: kstars.kcfg:2869 +#: kstars.kcfg:2943 #, kde-format msgid "Default scheduler checkbox for closing dust cover on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerWarmCCD), group (Scheduler) -#: kstars.kcfg:2873 +#: kstars.kcfg:2947 #, kde-format msgid "Default scheduler checkbox for warming the CCD on shutdown." msgstr "" #. i18n: ectx: label, entry (SchedulerUnparkDome), group (Scheduler) -#: kstars.kcfg:2877 +#: kstars.kcfg:2951 #, kde-format msgid "Default scheduler checkbox for unparking dome on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerUnparkMount), group (Scheduler) -#: kstars.kcfg:2881 +#: kstars.kcfg:2955 #, kde-format msgid "Default scheduler checkbox for unparking mount on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerOpenDustCover), group (Scheduler) -#: kstars.kcfg:2885 +#: kstars.kcfg:2959 #, kde-format msgid "Default scheduler checkbox for opening dust cover on startup." msgstr "" #. i18n: ectx: label, entry (SchedulerTrackStep), group (Scheduler) -#: kstars.kcfg:2889 +#: kstars.kcfg:2963 #, kde-format msgid "Default scheduler checkbox for starting mount tracking on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerFocusStep), group (Scheduler) -#: kstars.kcfg:2893 +#: kstars.kcfg:2967 #, kde-format msgid "Default scheduler checkbox for running autofocus on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerGuideStep), group (Scheduler) -#: kstars.kcfg:2897 +#: kstars.kcfg:2971 #, kde-format msgid "Default scheduler checkbox for starting guiding on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerAlignStep), group (Scheduler) -#: kstars.kcfg:2901 +#: kstars.kcfg:2975 #, kde-format msgid "Default scheduler checkbox for aligning on job startup." msgstr "" #. i18n: ectx: label, entry (SchedulerAltitude), group (Scheduler) -#: kstars.kcfg:2905 +#: kstars.kcfg:2979 #, kde-format msgid "Default scheduler checkbox for job altitude constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerAltitudeValue), group (Scheduler) -#: kstars.kcfg:2909 +#: kstars.kcfg:2983 #, kde-format msgid "Default scheduler job altitude constraint." msgstr "" #. i18n: ectx: label, entry (SchedulerHorizon), group (Scheduler) -#: kstars.kcfg:2913 +#: kstars.kcfg:2987 #, fuzzy, kde-format msgid "Default scheduler checkbox for job artificial horizon constraints." msgstr "الـ اللّون لـ تنسيق سطور." #. i18n: ectx: label, entry (SchedulerMoonSeparation), group (Scheduler) -#: kstars.kcfg:2917 +#: kstars.kcfg:2991 #, kde-format msgid "Default scheduler checkbox for job moon separation constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerMoonSeparationValue), group (Scheduler) -#: kstars.kcfg:2921 +#: kstars.kcfg:2995 #, kde-format msgid "Default scheduler job moon separation constraint." msgstr "" #. i18n: ectx: label, entry (SchedulerWeather), group (Scheduler) -#: kstars.kcfg:2925 +#: kstars.kcfg:2999 #, kde-format msgid "Default scheduler checkbox for job weather constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerTwilight), group (Scheduler) -#: kstars.kcfg:2929 +#: kstars.kcfg:3003 #, kde-format msgid "Default scheduler checkbox for job twilight constraints." msgstr "" #. i18n: ectx: label, entry (SchedulerRepeatSequences), group (Scheduler) -#: kstars.kcfg:2933 +#: kstars.kcfg:3007 #, kde-format msgid "Restart sequences as soon as all sequences have been completed." msgstr "" #. i18n: ectx: label, entry (SchedulerExecutionSequencesLimit), group (Scheduler) -#: kstars.kcfg:2937 +#: kstars.kcfg:3011 #, kde-format msgid "Limit how many times the scheduler should execute all sequences." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeHFR), group (Analyze) -#: kstars.kcfg:2943 +#: kstars.kcfg:3017 #, kde-format msgid "Display HFR on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeNumCaptureStars), group (Analyze) -#: kstars.kcfg:2947 +#: kstars.kcfg:3021 #, kde-format msgid "" "Display number of stars detected in the capture on the Analyze Statistics " @@ -35453,14 +36298,14 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMedian), group (Analyze) -#: kstars.kcfg:2951 +#: kstars.kcfg:3025 #, kde-format msgid "" "Display median sample value for the capture on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeEccentricity), group (Analyze) -#: kstars.kcfg:2955 +#: kstars.kcfg:3029 #, kde-format msgid "" "Display the median eccentricity for the stars in the capture on the Analyze " @@ -35468,73 +36313,73 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeTemperature), group (Analyze) -#: kstars.kcfg:2959 +#: kstars.kcfg:3033 #, kde-format msgid "Display the ambient temperature on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (FocusPosition), group (Analyze) -#: kstars.kcfg:2963 +#: kstars.kcfg:3037 #, fuzzy, kde-format msgid "Display the autofocus solution position." msgstr "العرض?" #. i18n: ectx: whatsthis, entry (AnalyzeNumStars), group (Analyze) -#: kstars.kcfg:2967 +#: kstars.kcfg:3041 #, kde-format msgid "Display NumStars on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeSkyBg), group (Analyze) -#: kstars.kcfg:2971 +#: kstars.kcfg:3045 #, kde-format msgid "Display SkyBackground on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeSNR), group (Analyze) -#: kstars.kcfg:2975 +#: kstars.kcfg:3049 #, kde-format msgid "Display SNR on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRA), group (Analyze) -#: kstars.kcfg:2979 +#: kstars.kcfg:3053 #, kde-format msgid "Display RA on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDEC), group (Analyze) -#: kstars.kcfg:2983 +#: kstars.kcfg:3057 #, kde-format msgid "Display DEC on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRAp), group (Analyze) -#: kstars.kcfg:2987 +#: kstars.kcfg:3061 #, kde-format msgid "Display RA Pulses on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDECp), group (Analyze) -#: kstars.kcfg:2991 +#: kstars.kcfg:3065 #, kde-format msgid "Display DEC Pulses on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeDrift), group (Analyze) -#: kstars.kcfg:2995 +#: kstars.kcfg:3069 #, kde-format msgid "Display Drift on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRMS), group (Analyze) -#: kstars.kcfg:2999 +#: kstars.kcfg:3073 #, kde-format msgid "Display RMS Error on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeTargetDistance), group (Analyze) -#: kstars.kcfg:3003 +#: kstars.kcfg:3077 #, kde-format msgid "" "Display the arc-seconds distance between the target position and the plate-" @@ -35542,254 +36387,254 @@ msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeRMSC), group (Analyze) -#: kstars.kcfg:3007 +#: kstars.kcfg:3081 #, kde-format msgid "Display RMS Error (during capture) on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountRA), group (Analyze) -#: kstars.kcfg:3011 +#: kstars.kcfg:3085 #, kde-format msgid "Display Mount RA on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountDEC), group (Analyze) -#: kstars.kcfg:3015 +#: kstars.kcfg:3089 #, kde-format msgid "Display Mount DEC on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeMountHA), group (Analyze) -#: kstars.kcfg:3019 +#: kstars.kcfg:3093 #, kde-format msgid "Display Mount Hour Angle on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeAz), group (Analyze) -#: kstars.kcfg:3023 +#: kstars.kcfg:3097 #, kde-format msgid "Display Azimuth on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzeAlt), group (Analyze) -#: kstars.kcfg:3027 +#: kstars.kcfg:3101 #, kde-format msgid "Display Altitude on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: whatsthis, entry (AnalyzePierSide), group (Analyze) -#: kstars.kcfg:3031 +#: kstars.kcfg:3105 #, kde-format msgid "Display PierSide on the Analyze Statistics Plot." msgstr "" #. i18n: ectx: label, entry (AnalyzeStatsYAxis), group (Analyze) -#: kstars.kcfg:3035 +#: kstars.kcfg:3109 #, kde-format msgid "Stored Y-axis upper and lower limits for the Analyze Stats Plot." msgstr "" #. i18n: ectx: label, entry (LastServer), group (INDI Lite) -#: kstars.kcfg:3040 +#: kstars.kcfg:3114 #, kde-format msgid "The address of last used server" msgstr "" #. i18n: ectx: label, entry (LastServerPort), group (INDI Lite) -#: kstars.kcfg:3043 +#: kstars.kcfg:3117 #, kde-format msgid "The port of last used server" msgstr "" #. i18n: ectx: label, entry (LastWebManagerPort), group (INDI Lite) -#: kstars.kcfg:3047 +#: kstars.kcfg:3121 #, kde-format msgid "The port of last used Web Manager" msgstr "" #. i18n: ectx: label, entry (HIPSMemoryCache), group (HIPS) -#: kstars.kcfg:3053 +#: kstars.kcfg:3127 #, kde-format msgid "RAM cache size in MB used to store cached HIPS images." msgstr "" #. i18n: ectx: label, entry (HIPSNetCache), group (HIPS) -#: kstars.kcfg:3057 +#: kstars.kcfg:3131 #, kde-format msgid "Hard disk cache size in MB used to store cached HIPS images." msgstr "" #. i18n: ectx: label, entry (HIPSSource), group (HIPS) -#: kstars.kcfg:3061 +#: kstars.kcfg:3135 #, kde-format msgid "HIPS source catalog title." msgstr "" #. i18n: ectx: label, entry (HIPSBiLinearInterpolation), group (HIPS) -#: kstars.kcfg:3065 +#: kstars.kcfg:3139 #, kde-format msgid "Use Bilinear interpolation when rendering HiPS images?" msgstr "" #. i18n: ectx: label, entry (HIPSShowGrid), group (HIPS) -#: kstars.kcfg:3069 +#: kstars.kcfg:3143 #, fuzzy, kde-format msgid "Show HiPS grid on the sky map." msgstr "رسم الأحد بوصة خريطة?" #. i18n: ectx: label, entry (HIPSPanning), group (HIPS) -#: kstars.kcfg:3073 +#: kstars.kcfg:3147 #, kde-format msgid "Redraw HiPS while panning." msgstr "" #. i18n: ectx: label, entry (ShowHIPS), group (HIPS) -#: kstars.kcfg:3077 +#: kstars.kcfg:3151 #, fuzzy, kde-format msgid "Draw HiPS sources in the sky map?" msgstr "رسم بوصة خريطة?" #. i18n: ectx: whatsthis, entry (ShowHIPS), group (HIPS) -#: kstars.kcfg:3078 +#: kstars.kcfg:3152 #, fuzzy, kde-format msgid "Toggle whether the HIPS sources are drawn in the sky map." msgstr "تبديل بوصة خريطة." #. i18n: ectx: label, entry (HIPSUseOfflineSource), group (HIPS) -#: kstars.kcfg:3082 +#: kstars.kcfg:3156 #, kde-format msgid "Use offline storage to load HiPS?" msgstr "" #. i18n: ectx: label, entry (HIPSOfflinePath), group (HIPS) -#: kstars.kcfg:3086 +#: kstars.kcfg:3160 #, kde-format msgid "HIPS offline full path." msgstr "" #. i18n: ectx: label, entry (TerrainSource), group (Terrain) -#: kstars.kcfg:3091 +#: kstars.kcfg:3165 #, fuzzy, kde-format msgid "Terrain Filename." msgstr "اسم الملف:" #. i18n: ectx: whatsthis, entry (TerrainSource), group (Terrain) -#: kstars.kcfg:3092 +#: kstars.kcfg:3166 #, kde-format msgid "Terrain source filename." msgstr "" #. i18n: ectx: label, entry (TerrainSourceCorrectAz), group (Terrain) -#: kstars.kcfg:3096 +#: kstars.kcfg:3170 #, kde-format msgid "Terrain Azimuth Correction." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSourceCorrectAz), group (Terrain) -#: kstars.kcfg:3097 +#: kstars.kcfg:3171 #, kde-format msgid "Terrain source azimuth correction." msgstr "" #. i18n: ectx: label, entry (TerrainSourceCorrectAlt), group (Terrain) -#: kstars.kcfg:3101 +#: kstars.kcfg:3175 #, kde-format msgid "Terrain Altitude Correction." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSourceCorrectAlt), group (Terrain) -#: kstars.kcfg:3102 +#: kstars.kcfg:3176 #, kde-format msgid "Terrain source altitude correction." msgstr "" #. i18n: ectx: label, entry (TerrainDownsampling), group (Terrain) -#: kstars.kcfg:3106 +#: kstars.kcfg:3180 #, fuzzy, kde-format msgid "Terrain Downsampling" msgstr "انتقِ الكل" #. i18n: ectx: whatsthis, entry (TerrainDownsampling), group (Terrain) -#: kstars.kcfg:3107 +#: kstars.kcfg:3181 #, kde-format msgid "Speed quality tradeoff for rendering the terrain image." msgstr "" #. i18n: ectx: label, entry (TerrainPanning), group (Terrain) -#: kstars.kcfg:3111 +#: kstars.kcfg:3185 #, kde-format msgid "Terrain While panning." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainPanning), group (Terrain) -#: kstars.kcfg:3112 +#: kstars.kcfg:3186 #, kde-format msgid "Redraw terrain while panning." msgstr "" #. i18n: ectx: label, entry (ShowTerrain), group (Terrain) -#: kstars.kcfg:3116 +#: kstars.kcfg:3190 #, kde-format msgid "Draw terrain" msgstr "" #. i18n: ectx: whatsthis, entry (ShowTerrain), group (Terrain) -#: kstars.kcfg:3117 +#: kstars.kcfg:3191 #, kde-format msgid "Toggle whether the terrain is drawn in the sky map." msgstr "" #. i18n: ectx: label, entry (TerrainSkipSpeedup), group (Terrain) -#: kstars.kcfg:3121 +#: kstars.kcfg:3195 #, kde-format msgid "Terrain Skip Speedup" msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSkipSpeedup), group (Terrain) #. i18n: ectx: whatsthis, entry (TerrainTransparencySpeedup), group (Terrain) -#: kstars.kcfg:3122 kstars.kcfg:3127 +#: kstars.kcfg:3196 kstars.kcfg:3201 #, kde-format msgid "Enable a one of the terrain drawing speedups." msgstr "" #. i18n: ectx: label, entry (TerrainTransparencySpeedup), group (Terrain) -#: kstars.kcfg:3126 +#: kstars.kcfg:3200 #, kde-format msgid "Terrain Transparency Speedup." msgstr "" #. i18n: ectx: label, entry (TerrainSmoothPixels), group (Terrain) -#: kstars.kcfg:3131 +#: kstars.kcfg:3205 #, kde-format msgid "Terrain Smooth Pixels." msgstr "" #. i18n: ectx: whatsthis, entry (TerrainSmoothPixels), group (Terrain) -#: kstars.kcfg:3132 +#: kstars.kcfg:3206 #, kde-format msgid "Smooth pixels for a more pleasant, but slower rendering." msgstr "" #. i18n: ectx: label, entry (ShowImageOverlays), group (ImageOverlay) -#: kstars.kcfg:3138 +#: kstars.kcfg:3212 #, kde-format msgid "Display Image Overlays." msgstr "" #. i18n: ectx: whatsthis, entry (ShowImageOverlays), group (ImageOverlay) -#: kstars.kcfg:3139 +#: kstars.kcfg:3213 #, fuzzy, kde-format msgid "Toggle whether to display image overlays." msgstr "تبديل بلوتو هو بوصة خريطة." #. i18n: ectx: label, entry (ShowSelectedImageOverlay), group (ImageOverlay) -#: kstars.kcfg:3143 +#: kstars.kcfg:3217 #, kde-format msgid "Center SkyMap over selected image overlay." msgstr "" #. i18n: ectx: whatsthis, entry (ShowSelectedImageOverlay), group (ImageOverlay) -#: kstars.kcfg:3144 +#: kstars.kcfg:3218 #, kde-format msgid "" "Center SkyMap over the selected overlay image in the image overlay table (if " @@ -35797,67 +36642,67 @@ msgstr "" #. i18n: ectx: label, entry (ImageOverlayMaxDimension), group (ImageOverlay) -#: kstars.kcfg:3148 +#: kstars.kcfg:3222 #, kde-format msgid "Image overlay max dimension" msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayMaxDimension), group (ImageOverlay) -#: kstars.kcfg:3149 +#: kstars.kcfg:3223 #, fuzzy, kde-format msgid "Maximum dimension for image overlay images." msgstr "الأقصى لـ مذنب" #. i18n: ectx: label, entry (ImageOverlayTimeout), group (ImageOverlay) -#: kstars.kcfg:3153 +#: kstars.kcfg:3227 #, kde-format msgid "Image overlay plate-solving timeout." msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayTimeout), group (ImageOverlay) -#: kstars.kcfg:3154 +#: kstars.kcfg:3228 #, kde-format msgid "Timeout for plate-solving an image overlay." msgstr "" #. i18n: ectx: label, entry (ImageOverlayDefaultScale), group (ImageOverlay) -#: kstars.kcfg:3158 +#: kstars.kcfg:3232 #, kde-format msgid "Image overlay default plate-solving scale." msgstr "" #. i18n: ectx: whatsthis, entry (ImageOverlayDefaultScale), group (ImageOverlay) -#: kstars.kcfg:3159 +#: kstars.kcfg:3233 #, kde-format msgid "Default scale (arcseconds/pixel) for image-overlay plate solving." msgstr "" #. i18n: ectx: label, entry (DefaultObservatoryWeatherSource), group (Observatory) -#: kstars.kcfg:3165 +#: kstars.kcfg:3239 #, fuzzy, kde-format msgid "Default observatory module weather source." msgstr "دليل FITS الافتراضي:" #. i18n: ectx: label, entry (warningActionsActive), group (Observatory) -#: kstars.kcfg:3168 +#: kstars.kcfg:3242 #, kde-format msgid "Will be reacted upon warnings?" msgstr "" #. i18n: ectx: label, entry (alertActionsActive), group (Observatory) -#: kstars.kcfg:3172 +#: kstars.kcfg:3246 #, kde-format msgid "Will be reacted upon alerts?" msgstr "" #. i18n: ectx: label, entry (weatherWarningCloseDome), group (Observatory) -#: kstars.kcfg:3176 +#: kstars.kcfg:3250 #, kde-format msgid "Shall the dome being closed when a weather warning occurs?" msgstr "" #. i18n: ectx: label, entry (weatherWarningCloseShutter), group (Observatory) -#: kstars.kcfg:3180 +#: kstars.kcfg:3254 #, kde-format msgid "Shall the shutter being closed when a weather warning occurs?" msgstr "" @@ -35865,62 +36710,62 @@ #. i18n: ectx: label, entry (weatherWarningStopScheduler), group (Observatory) #. i18n: ectx: label, entry (weatherAlertCloseShutter), group (Observatory) #. i18n: ectx: label, entry (weatherAlertStopScheduler), group (Observatory) -#: kstars.kcfg:3184 kstars.kcfg:3196 kstars.kcfg:3200 +#: kstars.kcfg:3258 kstars.kcfg:3270 kstars.kcfg:3274 #, kde-format msgid "Shall the shutter being closed when a weather alert occurs?" msgstr "" #. i18n: ectx: label, entry (weatherWarningDelay), group (Observatory) -#: kstars.kcfg:3188 +#: kstars.kcfg:3262 #, kde-format msgid "Delay for reacting upon a weather warning." msgstr "" #. i18n: ectx: label, entry (weatherAlertCloseDome), group (Observatory) -#: kstars.kcfg:3192 +#: kstars.kcfg:3266 #, kde-format msgid "Shall the dome being closed when a weather alert occurs?" msgstr "" #. i18n: ectx: label, entry (weatherAlertDelay), group (Observatory) -#: kstars.kcfg:3204 +#: kstars.kcfg:3278 #, kde-format msgid "Delay for reacting upon a weather alert." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseDome), group (Observatory) -#: kstars.kcfg:3208 +#: kstars.kcfg:3282 #, kde-format msgid "Dome status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseShutter), group (Observatory) -#: kstars.kcfg:3212 +#: kstars.kcfg:3286 #, kde-format msgid "Shutter status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (observatoryStatusUseWeather), group (Observatory) -#: kstars.kcfg:3216 +#: kstars.kcfg:3290 #, kde-format msgid "Weather status relevant for the Observatory status." msgstr "" #. i18n: ectx: label, entry (weatherAutoScaleValues), group (Observatory) -#: kstars.kcfg:3220 +#: kstars.kcfg:3294 #, kde-format msgid "Scale the sensor graph value axis to the values range." msgstr "" #. i18n: ectx: label, entry (ASTAPExecutable), group (ASTAP) -#: kstars.kcfg:3226 +#: kstars.kcfg:3300 #, kde-format msgid "Full path to the ASTAP executable." msgstr "" #. i18n: ectx: label, entry (ASTAPDownSample), group (ASTAP) #. i18n: ectx: label, entry (ASTAPDownSampleValue), group (ASTAP) -#: kstars.kcfg:3230 kstars.kcfg:3234 +#: kstars.kcfg:3304 kstars.kcfg:3308 #, kde-format msgid "" "Down sample prior to solving. Also called binning. A value 0 will result in " @@ -35929,7 +36774,7 @@ #. i18n: ectx: label, entry (ASTAPSearchRadius), group (ASTAP) #. i18n: ectx: label, entry (ASTAPSearchRadiusValue), group (ASTAP) -#: kstars.kcfg:3238 kstars.kcfg:3242 +#: kstars.kcfg:3312 kstars.kcfg:3316 #, kde-format msgid "" "The program will search in a square spiral around the start position up to " @@ -35937,25 +36782,25 @@ msgstr "" #. i18n: ectx: label, entry (ASTAPUpdateFITS), group (ASTAP) -#: kstars.kcfg:3246 +#: kstars.kcfg:3320 #, kde-format msgid "Update the fits header with the found solution." msgstr "" #. i18n: ectx: label, entry (ASTAPLargeSearchWindow), group (ASTAP) -#: kstars.kcfg:3250 +#: kstars.kcfg:3324 #, kde-format msgid "Increase search window size." msgstr "" #. i18n: ectx: whatsthis, entry (MosaicTransparencyAuto), group (Mosaic) -#: kstars.kcfg:3256 +#: kstars.kcfg:3330 #, kde-format msgid "Manage the mosaic panel transparency level automatically." msgstr "" #. i18n: ectx: whatsthis, entry (MosaicTransparencyLevel), group (Mosaic) -#: kstars.kcfg:3260 +#: kstars.kcfg:3334 #, kde-format msgid "Control mosaic panel transparency level." msgstr "" @@ -64447,19 +65292,19 @@ msgid "Other" msgstr "أخرى" -#: kstarsactions.cpp:208 +#: kstarsactions.cpp:211 #, kde-format msgid "Refraction effects disabled" msgstr "" -#: kstarsactions.cpp:209 +#: kstarsactions.cpp:212 #, kde-format msgid "" "When the horizon is switched off, refraction effects are temporarily " "disabled." msgstr "" -#: kstarsactions.cpp:448 +#: kstarsactions.cpp:457 #, kde-format msgid "" "Due to a known issue in the kde frameworks, updating already downloaded " @@ -64467,138 +65312,138 @@ "update." msgstr "" -#: kstarsactions.cpp:481 +#: kstarsactions.cpp:490 #, kde-format msgid "The catalog \"%1\" is corrupt." msgstr "" -#: kstarsactions.cpp:489 +#: kstarsactions.cpp:498 #, kde-format msgid "The catalog \"%1\" is corrupt.
    Expected id=%2 but got id=%3" msgstr "" -#: kstarsactions.cpp:499 +#: kstarsactions.cpp:508 #, kde-format msgid "Could not import the catalog \"%1\"
    %2" msgstr "" -#: kstarsactions.cpp:553 +#: kstarsactions.cpp:562 #, kde-format msgid "Light Pollution Settings" msgstr "إعدادات التلوث الضوئي" -#: kstarsactions.cpp:555 +#: kstarsactions.cpp:564 #, kde-format msgid "Equipment Settings - Equipment Type and Parameters" msgstr "إعدادات الأجهزة - نوعها وخصائصها" -#: kstarsactions.cpp:664 kstarsactions.cpp:701 kstarsactions.cpp:744 -#: kstarsactions.cpp:783 +#: kstarsactions.cpp:673 kstarsactions.cpp:710 kstarsactions.cpp:753 +#: kstarsactions.cpp:792 #, kde-format msgid "" "Unable to find INDI server. Please make sure the package that provides the " "'indiserver' binary is installed." msgstr "" -#: kstarsactions.cpp:718 +#: kstarsactions.cpp:727 #, kde-format msgid "" "INDI Device Manager should only be used by advanced technical users. It " "cannot be used with Ekos. Do you still want to open INDI device manager?" msgstr "" -#: kstarsactions.cpp:721 +#: kstarsactions.cpp:730 #, fuzzy, kde-format #| msgid "Device Manager" msgid "INDI Device Manager" msgstr "مدير الأجهزة" -#: kstarsactions.cpp:1102 +#: kstarsactions.cpp:1111 #, kde-format msgid "Catalogs" msgstr "أدلة النجوم" -#: kstarsactions.cpp:1114 +#: kstarsactions.cpp:1123 #, kde-format msgid "Guides" msgstr "التوسيمات" -#: kstarsactions.cpp:1117 +#: kstarsactions.cpp:1126 #, kde-format msgid "Terrain" msgstr "تضاريس" #. i18n: ectx: property (title), widget (QGroupBox, ImageOverlayTableBox) -#: kstarsactions.cpp:1120 options/opsimageoverlay.ui:191 +#: kstarsactions.cpp:1129 options/opsimageoverlay.ui:191 #, fuzzy, kde-format #| msgid "Overlay" msgid "Image Overlays" msgstr "طبّق الصورة" -#: kstarsactions.cpp:1150 +#: kstarsactions.cpp:1159 #, fuzzy, kde-format msgid "Xplanet" msgstr "كوكب" -#: kstarsactions.cpp:1156 +#: kstarsactions.cpp:1165 #, kde-format msgid "Developer" msgstr "مطوّر" -#: kstarsactions.cpp:1174 kstarsactions.cpp:1934 kstarsinit.cpp:268 +#: kstarsactions.cpp:1183 kstarsactions.cpp:1943 kstarsinit.cpp:268 #, fuzzy, kde-format #| msgctxt "City in Spain" #| msgid "Terrassa" msgid "Hide Terrain" msgstr "Terrassa" -#: kstarsactions.cpp:1174 kstarsactions.cpp:1934 kstarsinit.cpp:269 +#: kstarsactions.cpp:1183 kstarsactions.cpp:1943 kstarsinit.cpp:269 #, fuzzy, kde-format #| msgid "Show details..." msgid "Show Terrain" msgstr "اظهر التفاصيل ..." -#: kstarsactions.cpp:1178 kstarsactions.cpp:1944 kstarsinit.cpp:273 +#: kstarsactions.cpp:1187 kstarsactions.cpp:1953 kstarsinit.cpp:273 #, fuzzy, kde-format #| msgid "HiPS All Sky Overlay (Experimental)" msgid "Hide Image Overlays" msgstr "طبقة HiPS لكامل السماء (تجريبي)" -#: kstarsactions.cpp:1178 kstarsactions.cpp:1944 kstarsinit.cpp:274 +#: kstarsactions.cpp:1187 kstarsactions.cpp:1953 kstarsinit.cpp:274 #, fuzzy, kde-format #| msgid "Show HiPS Grid" msgid "Show Image Overlays" msgstr "أظهر شبكة HiPS" -#: kstarsactions.cpp:1297 +#: kstarsactions.cpp:1306 #, kde-format msgid "Open FITS" msgstr "FITS افتح ملف" -#: kstarsactions.cpp:1312 +#: kstarsactions.cpp:1321 #, kde-format msgctxt "@title:window" msgid "Export Image" msgstr "صدّر لقطة الشاشة بصيغة ..." -#: kstarsactions.cpp:1358 tools/scriptbuilder.cpp:795 +#: kstarsactions.cpp:1367 tools/scriptbuilder.cpp:795 #: tools/scriptbuilder.cpp:863 #, kde-format msgctxt "Filter by file type: KStars Scripts." msgid "KStars Scripts (*.kstars)" msgstr "" -#: kstarsactions.cpp:1366 +#: kstarsactions.cpp:1375 #, fuzzy, kde-format msgid "Executing remote scripts is not supported." msgstr "مكتمل" -#: kstarsactions.cpp:1374 oal/execute.cpp:319 tools/observinglist.cpp:909 +#: kstarsactions.cpp:1383 oal/execute.cpp:319 tools/observinglist.cpp:909 #, kde-format msgid "Could not open file %1" msgstr "لم يمكن فتح الملف: %1" -#: kstarsactions.cpp:1399 +#: kstarsactions.cpp:1408 #, fuzzy, kde-format msgid "" "The selected script contains unrecognized elements, indicating that it was " @@ -64610,27 +65455,27 @@ "برنامج نصي أيار ليس الدالة و الإيطالية أيار تحوي على رمز هل مثل إلى نفِّذ " "الإيطالية?" -#: kstarsactions.cpp:1404 +#: kstarsactions.cpp:1413 #, kde-format msgid "Script Validation Failed" msgstr "النص البرمجي غير صالح!" -#: kstarsactions.cpp:1404 +#: kstarsactions.cpp:1413 #, fuzzy, kde-format msgid "Run Nevertheless" msgstr "التشغيل بالرغم من هذا" -#: kstarsactions.cpp:1411 +#: kstarsactions.cpp:1420 #, fuzzy, kde-format msgid "Running script: %1" msgstr "يعمل برنامج نصي 1" -#: kstarsactions.cpp:1429 +#: kstarsactions.cpp:1438 #, fuzzy, kde-format msgid "Script finished." msgstr "مخطوط إنتهيت." -#: kstarsactions.cpp:1441 +#: kstarsactions.cpp:1450 #, kde-format msgid "" "You can save printer ink by using the \"Star Chart\" color scheme, which " @@ -64641,62 +65486,62 @@ "تكون الخلفية بيضاء. هل تريد التحوّل مؤقتاً إلى نسق ألوان خارطة النجوم الورقية " "للطباعة ؟" -#: kstarsactions.cpp:1446 +#: kstarsactions.cpp:1455 #, kde-format msgid "Switch to Star Chart Colors?" msgstr "هل تريد التحوّل إلى نسق ألوان خارطة النجوم الورقية؟" -#: kstarsactions.cpp:1447 +#: kstarsactions.cpp:1456 #, kde-format msgid "Switch Color Scheme" msgstr "غيّر نسق الألوان" -#: kstarsactions.cpp:1447 +#: kstarsactions.cpp:1456 #, kde-format msgid "Do Not Switch" msgstr "لاتغيّر" -#: kstarsactions.cpp:1530 kstarsinit.cpp:236 +#: kstarsactions.cpp:1539 kstarsinit.cpp:236 #, kde-format msgid "Engage &Tracking" msgstr "شغّل ال&تتبع" -#: kstarsactions.cpp:1644 +#: kstarsactions.cpp:1653 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 degrees" msgstr "" -#: kstarsactions.cpp:1649 +#: kstarsactions.cpp:1658 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 arcminutes" msgstr "" -#: kstarsactions.cpp:1655 +#: kstarsactions.cpp:1664 #, kde-format msgctxt "approximate field of view" msgid "Approximate FOV: %1 arcseconds" msgstr "" -#: kstarsactions.cpp:1672 +#: kstarsactions.cpp:1681 #, kde-format msgctxt "The user should enter an angle for the field-of-view of the display" msgid "Enter Desired Field-of-View Angle" msgstr "أدخل زاوية حقل الرؤية المرغوب" -#: kstarsactions.cpp:1673 +#: kstarsactions.cpp:1682 #, kde-format msgid "Enter a field-of-view angle in degrees: " msgstr "أدخل زاوية حقل الرؤية بالدرجات:" -#: kstarsactions.cpp:1704 kstarsinit.cpp:716 +#: kstarsactions.cpp:1713 kstarsinit.cpp:716 #, fuzzy, kde-format msgctxt "Orientation of the sky map" msgid "North &Up" msgstr "الشمال" -#: kstarsactions.cpp:1707 kstarsinit.cpp:725 +#: kstarsactions.cpp:1716 kstarsinit.cpp:725 #, fuzzy, kde-format #| msgctxt "City in Kansas USA" #| msgid "Norton" @@ -64704,31 +65549,31 @@ msgid "North &Down" msgstr "نورتون" -#: kstarsactions.cpp:1725 kstarsinit.cpp:716 +#: kstarsactions.cpp:1734 kstarsinit.cpp:716 #, fuzzy, kde-format #| msgid "&Zenith" msgctxt "Orientation of the sky map" msgid "Zenith &Up" msgstr "سمت الرأس" -#: kstarsactions.cpp:1728 kstarsinit.cpp:725 +#: kstarsactions.cpp:1737 kstarsinit.cpp:725 #, fuzzy, kde-format #| msgid "&Zenith" msgctxt "Orientation of the sky map" msgid "Zenith &Down" msgstr "سمت الرأس" -#: kstarsactions.cpp:1886 +#: kstarsactions.cpp:1895 #, kde-format msgid "Attempt to determine from image" msgstr "" -#: kstarsactions.cpp:1888 +#: kstarsactions.cpp:1897 #, kde-format msgid "Eyepiece View: Choose a field-of-view" msgstr "منظر العدسة العينية: اختر حقل الرؤية" -#: kstarsactions.cpp:1889 +#: kstarsactions.cpp:1898 #, kde-format msgid "FOV to render eyepiece view for:" msgstr "حقل الرؤية المرغوب لمنظر العدسة العينية:" @@ -65909,13 +66754,6 @@ msgid "%1 - Add a Link" msgstr "اضف رابط..." -#. i18n: ectx: property (text), widget (QTreeWidget, OptionsList) -#: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:68 -#: tools/optionstreeview.ui:28 -#, kde-format, kde-kuit-format -msgid "Description" -msgstr "الوصف" - #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:77 #, fuzzy, kde-kuit-format #| msgid "URL:" @@ -72491,12 +73329,6 @@ "solving is enabled.

    " msgstr "" -#. i18n: ectx: property (toolTip), widget (QComboBox, imageOverlaySolverProfile) -#: options/opsimageoverlay.ui:255 -#, kde-format -msgid "Selects the Options Profile (from Align) to use for Plate Solving" -msgstr "" - #. i18n: ectx: property (toolTip), widget (QLabel, imageOverlayScaleLabel) #. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_ImageOverlayDefaultScale) #: options/opsimageoverlay.ui:271 options/opsimageoverlay.ui:287 @@ -78674,12 +79506,6 @@ msgid "Select all items in the list" msgstr "اختر جميع العناصر في القائمة" -#. i18n: ectx: property (text), widget (QPushButton, AllButton) -#: tools/obslistwizard.ui:173 -#, kde-format -msgid "All" -msgstr "الكل" - #. i18n: ectx: property (toolTip), widget (QPushButton, NoneButton) #: tools/obslistwizard.ui:180 #, kde-format @@ -81217,12 +82043,6 @@ msgid "Labels and markers" msgstr "" -#. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: xplanet/opsxplanet.ui:574 -#, kde-format -msgid "Labels" -msgstr "اللاصقات" - #. i18n: ectx: property (text), widget (QRadioButton, kcfg_XplanetLabelGMT) #: xplanet/opsxplanet.ui:603 #, kde-format @@ -81444,6 +82264,31 @@ msgstr "الـ اللّون لـ الخلفية." #, fuzzy +#~ msgctxt "Half Flux Radius" +#~ msgid "HFR: %1" +#~ msgstr ":HFR" + +#, fuzzy +#~| msgctxt "Show the selected object in the telescope" +#~| msgid "Scope" +#~ msgid "Scope/Lense:" +#~ msgstr "أدر التلسكوب نحو الجرم" + +#, fuzzy +#~ msgid "Flat Source" +#~ msgstr "تحديث" + +#, fuzzy +#~| msgid "Use animated slewing" +#~ msgid "Use Dawn and Dusk light" +#~ msgstr "استخدم تحريك حيوي" + +#, fuzzy +#~| msgid "%1 is online." +#~ msgid "Warning: Filter %1 not found in filter wheel." +#~ msgstr "%1 على الخط" + +#, fuzzy #~ msgid "" #~ "

    The camera position angle is saved to a sequence " #~ "capture job. On execution of the job the camera is rotated to the " @@ -81887,10 +82732,6 @@ #~ msgstr "لا شيء" #, fuzzy -#~ msgid "Primary Scope" -#~ msgstr "المنظار" - -#, fuzzy #~ msgid "Guide Scope" #~ msgstr "المنظار" @@ -82193,12 +83034,6 @@ #~ msgstr "مكتمل" #, fuzzy -#~| msgctxt "City name (optional, probably does not need a translation)" -#~| msgid "Parsons" -#~ msgid "arcsec" -#~ msgstr "%1 ثانية قوسية" - -#, fuzzy #~| msgid "Save Image" #~ msgid "Inline Images" #~ msgstr "احفظ الصورة" @@ -83011,13 +83846,6 @@ #~ msgstr "‎‎ميموسا ‎‎‎" #, fuzzy -#~| msgctxt "star name" -#~| msgid "Capella" -#~ msgctxt "Asteroid name (optional)" -#~ msgid "Isabella" -#~ msgstr "‎‎العيوق ‎‎‎" - -#, fuzzy #~| msgctxt "City in Tunisia" #~| msgid "Medenine" #~ msgctxt "Asteroid name (optional)" @@ -83339,13 +84167,6 @@ #~ msgstr "Kiruna" #, fuzzy -#~| msgctxt "City in Spain" -#~| msgid "Alicante" -#~ msgctxt "Asteroid name (optional)" -#~ msgid "Alice" -#~ msgstr "Alicante" - -#, fuzzy #~| msgctxt "City in Brazil" #~| msgid "Brasilia" #~ msgctxt "Asteroid name (optional)" @@ -85697,10 +86518,6 @@ #~ msgstr "بُؤرة:" #, fuzzy -#~ msgid "Delta ,\"" -#~ msgstr "دلتا" - -#, fuzzy #~ msgid "Pulse duration, ms" #~ msgstr "المدة:" @@ -85885,10 +86702,6 @@ #~ msgstr "عدد الصور المراد التقاطها" #, fuzzy -#~ msgid "Threshold (%):" -#~ msgstr "Freehold" - -#, fuzzy #~ msgid "Delay between two consequent focus images" #~ msgstr "التأخير بالثواني بين الصّور المتتالية" diff -Nru kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/az/kstars.po kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/az/kstars.po --- kstars-bleeding-3.6.7+202310142136~ubuntu22.04.1/po/az/kstars.po 2023-10-14 21:36:49.000000000 +0000 +++ kstars-bleeding-3.6.8+202312030523~ubuntu22.04.1/po/az/kstars.po 2023-12-03 05:23:17.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: kstars\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" -"POT-Creation-Date: 2023-09-29 00:39+0000\n" +"POT-Creation-Date: 2023-11-30 00:38+0000\n" "PO-Revision-Date: 2022-07-31 23:14+0400\n" "Last-Translator: Kheyyam \n" "Language-Team: Azerbaijani \n" @@ -178,7 +178,7 @@ #: auxiliary/colorscheme.cpp:59 data/qml/whatisinteresting/wiview.qml:241 #: data/qml/whatisinteresting/wiview.qml:253 dialogs/finddialog.cpp:48 -#: kstarsactions.cpp:1108 kstarslite/dialogs/finddialoglite.cpp:37 +#: kstarsactions.cpp:1117 kstarslite/dialogs/finddialoglite.cpp:37 #: kstarslite/qml/modules/TopMenu.qml:178 #, kde-format, kde-kuit-format msgid "Satellites" @@ -191,7 +191,7 @@ #: auxiliary/colorscheme.cpp:61 data/qml/whatisinteresting/wiview.qml:526 #: data/qml/whatisinteresting/wiview.qml:538 dialogs/finddialog.cpp:47 -#: kstarsactions.cpp:1111 kstarslite/dialogs/finddialoglite.cpp:36 +#: kstarsactions.cpp:1120 kstarslite/dialogs/finddialoglite.cpp:36 #: kstarslite/qml/modules/TopMenu.qml:169 #, kde-format, kde-kuit-format msgid "Supernovae" @@ -226,7 +226,7 @@ msgid "DEC Guide Error" msgstr "DEC Bələdçi Xətası" -#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:94 +#: auxiliary/colorscheme.cpp:66 ekos/align/align.cpp:101 #, kde-format msgid "Solver FOV" msgstr "Həlledicinin BaxışBucağı" @@ -396,9 +396,9 @@ #. i18n: ectx: property (text), widget (QPushButton, AddScope) #. i18n: ectx: property (text), widget (QPushButton, AddDSLRLens) #. i18n: ectx: property (text), widget (QPushButton, SavePreset) -#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:383 -#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2499 -#: ekos/scheduler/scheduler.cpp:3822 +#: auxiliary/imageviewer.cpp:134 ekos/align/mountmodel.cpp:384 +#: ekos/auxiliary/buildfilteroffsets.cpp:343 ekos/capture/capture.cpp:2028 +#: ekos/scheduler/scheduler.cpp:2950 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:88 #: kstarslite/qml/dialogs/helpers/LocationEdit.qml:375 #: oal/equipmentwriter.ui:291 oal/equipmentwriter.ui:702 @@ -424,7 +424,7 @@ #. i18n: ectx: property (text), widget (QPushButton, downloadB) #: auxiliary/imageviewer.cpp:195 -#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:86 +#: ekos/capture/exposurecalculator/fileutilitycameradatadialog.ui:59 #, kde-format msgid "Download" msgstr "Yükləmək" @@ -452,15 +452,15 @@ msgid "Save Image" msgstr "Şəkli saxlamaq" -#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3835 -#: ekos/guide/guidedriftgraph.cpp:465 kstarsactions.cpp:1326 +#: auxiliary/imageviewer.cpp:320 ekos/align/align.cpp:3873 +#: ekos/guide/guidedriftgraph.cpp:466 kstarsactions.cpp:1335 #: printing/pwizprint.cpp:77 tools/scriptbuilder.cpp:879 #, kde-format msgid "A file named \"%1\" already exists. Overwrite it?" msgstr "\"%1\" adlı fayl artıq mövcuddur. Üzərinə yazılsın?" -#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3838 -#: ekos/guide/guidedriftgraph.cpp:468 kstarsactions.cpp:1327 +#: auxiliary/imageviewer.cpp:323 ekos/align/align.cpp:3876 +#: ekos/guide/guidedriftgraph.cpp:469 kstarsactions.cpp:1336 #: printing/pwizprint.cpp:78 tools/scriptbuilder.cpp:882 #, kde-format msgid "Overwrite File?" @@ -521,7 +521,7 @@ #: dialogs/catalogdetails.cpp:213 dialogs/catalogsdbui.cpp:153 #: dialogs/catalogsdbui.cpp:189 dialogs/catalogsdbui.cpp:210 #: dialogs/catalogsdbui.cpp:230 dialogs/catalogsdbui.cpp:248 -#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:780 +#: dialogs/catalogsdbui.cpp:283 ekos/align/polaralignmentassistant.cpp:782 #, kde-format msgid "Warning" msgstr "Xəbərdarlıq" @@ -533,6 +533,7 @@ #. i18n: ectx: property (text), widget (QPushButton, cancelB) #: auxiliary/ksmessagebox.h:38 ekos/align/manualrotator.ui:135 +#: fitsviewer/fitstab.cpp:627 fitsviewer/fitstab.cpp:646 #: indi/telescopewizardprocess.cpp:219 indi/telescopewizardprocess.cpp:226 #: kstarslite/qml/dialogs/FindDialog.qml:107 #: kstarslite/qml/dialogs/helpers/DetailsAddLink.qml:105 @@ -546,18 +547,18 @@ #. i18n: ectx: property (text), widget (QTableWidget, solutionTable) #: auxiliary/ksmessagebox.h:39 auxiliary/ksnotification.h:42 -#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:139 -#: ekos/capture/sequencejob.cpp:21 ekos/manager.cpp:1068 ekos/manager.cpp:1083 -#: ekos/manager.cpp:1113 ekos/scheduler/schedulerjob.cpp:620 +#: ekos/analyze/analyze.cpp:139 ekos/analyze/analyze.cpp:141 +#: ekos/capture/sequencejob.cpp:23 ekos/manager.cpp:1072 ekos/manager.cpp:1087 +#: ekos/manager.cpp:1117 ekos/scheduler/schedulerjob.cpp:596 #: fitsviewer/solveInfo.ui:86 indi/indidome.cpp:22 indi/indidustcap.cpp:18 -#: indi/indimount.cpp:33 kstarsactions.cpp:480 kstarsactions.cpp:488 -#: kstarsactions.cpp:498 skycomponents/imageoverlaycomponent.cpp:519 +#: indi/indimount.cpp:33 kstarsactions.cpp:489 kstarsactions.cpp:497 +#: kstarsactions.cpp:507 skycomponents/imageoverlaycomponent.cpp:519 #, kde-format msgid "Error" msgstr "Xəta" #: auxiliary/ksmessagebox.h:40 auxiliary/ksnotification.h:43 -#: ekos/scheduler/framingassistantui.cpp:767 +#: ekos/scheduler/framingassistantui.cpp:769 #, kde-format msgid "Sorry" msgstr "Təəssüf" @@ -737,10 +738,10 @@ msgid "Cannot write %s %1: %2" msgstr "%s %1 yazıla bilmir: %2" -#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:179 -#: ekos/scheduler/framingassistantui.cpp:194 -#: ekos/scheduler/framingassistantui.cpp:853 -#: ekos/scheduler/framingassistantui.cpp:872 skyobjects/ksplanetbase.h:60 +#: auxiliary/ksutils.cpp:1825 ekos/scheduler/framingassistantui.cpp:180 +#: ekos/scheduler/framingassistantui.cpp:195 +#: ekos/scheduler/framingassistantui.cpp:855 +#: ekos/scheduler/framingassistantui.cpp:874 skyobjects/ksplanetbase.h:60 #: skyobjects/skyobject.h:24 #, kde-format msgid "unnamed" @@ -982,7 +983,7 @@ #: data/qml/whatisinteresting/wiview.qml:176 #: data/qml/whatisinteresting/wiview.qml:188 dialogs/detaildialog.cpp:216 #: dialogs/detaildialog.cpp:232 dialogs/detaildialog.cpp:255 -#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:153 +#: dialogs/detaildialog.cpp:270 ekos/scheduler/schedulerjob.cpp:129 #: printing/detailstable.cpp:145 printing/detailstable.cpp:162 #: printing/detailstable.cpp:173 printing/detailstable.cpp:186 #: printing/pwizobjectselection.cpp:124 skycomponents/skymapcomposite.cpp:606 @@ -1395,7 +1396,7 @@ #: ekos/guide/opsdither.ui:126 ekos/guide/opsgpg.ui:139 #: ekos/guide/opsgpg.ui:306 ekos/guide/opsgpg.ui:383 ekos/guide/opsgpg.ui:456 #: ekos/guide/opsgpg.ui:539 ekos/guide/opsguide.ui:308 -#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:585 ekos/opsekos.ui:678 +#: ekos/guide/opsguide.ui:407 ekos/opsekos.ui:598 ekos/opsekos.ui:691 #, kde-format msgid "seconds" msgstr "saniyələr" @@ -1902,16 +1903,16 @@ #. i18n: ectx: property (text), widget (QLabel, idlingStateLabel) #. i18n: ectx: property (text), widget (QLabel, guideStatus) #. i18n: ectx: property (text), widget (QLabel, jobStatus) -#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:27 -#: ekos/analyze/analyze.cpp:125 ekos/analyze/analyze.cpp:144 -#: ekos/analyze/analyze.cpp:2851 ekos/auxiliary/buildfilteroffsets.cpp:153 +#: data/qml/mount/mountbox.qml:1054 ekos/align/polaralignmentassistant.cpp:28 +#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/buildfilteroffsets.cpp:153 #: ekos/auxiliary/darklibrary.cpp:46 ekos/auxiliary/ledstatuswidget.cpp:19 -#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:21 +#: ekos/auxiliary/ledstatuswidget.cpp:27 ekos/capture/sequencejob.cpp:23 #: ekos/ekos.h:20 ekos/ekos.h:71 ekos/ekos.h:118 ekos/ekos.h:138 #: ekos/ekos.h:161 ekos/ekos.h:187 ekos/guide/guidestatewidget.ui:38 -#: ekos/manager.cpp:572 ekos/manager/guidemanager.cpp:135 +#: ekos/manager.cpp:576 ekos/manager/guidemanager.cpp:135 #: ekos/manager/guidemanager.ui:117 ekos/scheduler/scheduler.ui:1252 -#: ekos/scheduler/schedulerjob.cpp:613 ekos/scheduler/schedulerjob.cpp:637 +#: ekos/scheduler/schedulerjob.cpp:589 ekos/scheduler/schedulerjob.cpp:613 #: indi/indidome.cpp:20 indi/indidustcap.cpp:17 indi/indimount.cpp:31 #, kde-format, kde-kuit-format msgid "Idle" @@ -2282,8 +2283,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, magUnknown) -#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:621 -#: ekos/scheduler/schedulerjob.cpp:652 fitsviewer/fitscommon.h:16 +#: dialogs/addcatalogobject.ui:113 ekos/scheduler/schedulerjob.cpp:597 +#: ekos/scheduler/schedulerjob.cpp:628 fitsviewer/fitscommon.h:16 #: fitsviewer/fitshistogram.cpp:781 fitsviewer/fitshistogramcommand.cpp:267 #: indi/indigroup.cpp:30 skycomponents/constellationboundarylines.cpp:275 #, kde-format @@ -2531,12 +2532,12 @@ "URL düzgün deyil: Google'də axtarış üçün internet bələdçi\n" "pəncərəsini açmaq istəyirsiniz?" -#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3846 -#: ekos/align/mountmodel.cpp:264 ekos/align/mountmodel.cpp:390 -#: ekos/analyze/analyze.cpp:1170 ekos/capture/capture.cpp:2078 -#: ekos/capture/capture.cpp:2508 ekos/guide/guidedriftgraph.cpp:476 -#: ekos/scheduler/scheduler.cpp:3463 ekos/scheduler/scheduler.cpp:3832 -#: fitsviewer/fitstab.cpp:495 tools/scriptbuilder.cpp:832 +#: dialogs/addlinkdialog.cpp:60 ekos/align/align.cpp:3884 +#: ekos/align/mountmodel.cpp:265 ekos/align/mountmodel.cpp:391 +#: ekos/analyze/analyze.cpp:1172 ekos/capture/capture.cpp:1951 +#: ekos/capture/capture.cpp:2037 ekos/guide/guidedriftgraph.cpp:477 +#: ekos/scheduler/scheduler.cpp:2593 ekos/scheduler/scheduler.cpp:2960 +#: fitsviewer/fitstab.cpp:504 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:930 #, kde-format msgid "Invalid URL" @@ -2649,8 +2650,8 @@ #. i18n: ectx: property (text), item, widget (QComboBox, schedulerProfileCombo) #: dialogs/catalogcoloreditor.cpp:109 #: ekos/auxiliary/stellarsolverprofileeditor.ui:441 -#: ekos/scheduler/scheduler.cpp:2569 ekos/scheduler/scheduler.cpp:6444 -#: ekos/scheduler/scheduler.ui:250 skycomponents/flagcomponent.cpp:33 +#: ekos/scheduler/scheduler.ui:250 ekos/scheduler/schedulermodulestate.cpp:38 +#: ekos/scheduler/schedulerprocess.cpp:1183 skycomponents/flagcomponent.cpp:33 #, kde-format msgid "Default" msgstr "" @@ -2841,7 +2842,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QPushButton, preview_button) -#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:258 +#: dialogs/catalogcsvimport.ui:297 ekos/capture/capturecountswidget.cpp:260 #: fitsviewer/fitsviewer.cpp:607 indi/indicamera.cpp:926 #, kde-format msgid "Preview" @@ -3089,11 +3090,13 @@ #. i18n: ectx: property (text), widget (QLabel, l_01) #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_6) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRALabel) #: dialogs/catalogobjectlistmodel.cpp:67 ekos/align/align.ui:911 #: ekos/align/opsastrometry.ui:409 ekos/guide/guide.ui:424 #: ekos/guide/opscalibration.ui:235 ekos/guide/opsguide.ui:138 #: ekos/mount/mount.ui:144 ekos/scheduler/scheduler.ui:468 -#: fitsviewer/solveInfo.ui:66 skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:177 fitsviewer/solveInfo.ui:66 +#: skycomponents/imageoverlaycomponent.cpp:62 #, kde-format msgid "RA" msgstr "" @@ -3290,7 +3293,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QPushButton, colorButton) -#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1126 +#: dialogs/catalogsdbui.ui:113 kstarsactions.cpp:1135 #, kde-format msgid "Colors" msgstr "" @@ -3588,12 +3591,12 @@ msgid "Could not add the link." msgstr "Fayl açıla bilmədi" -#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1153 +#: dialogs/detaildialog.cpp:766 kstarsactions.cpp:1162 #, kde-format msgid "Advanced" msgstr "Təkmilləşmiş" -#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:507 +#: dialogs/detaildialog.cpp:781 ekos/analyze/analyze.cpp:509 #: kstarslite/qml/dialogs/DetailsDialog.qml:55 #: kstarslite/qml/dialogs/DetailsDialog.qml:453 #, kde-format, kde-kuit-format @@ -3626,7 +3629,7 @@ msgid "Are you sure you want to remove the %1 link?" msgstr "%1 keçif=dini silmək istədiyinizə əminsiniz?" -#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1495 +#: dialogs/detaildialog.cpp:963 indi/drivermanager.cpp:1512 #: indi/indidriver.cpp:897 #, kde-format, kde-kuit-format msgid "Delete Confirmation" @@ -3645,7 +3648,7 @@ msgstr "En dairəsi/Uzunluq dairəsi təhlil edilə bilmədi." #: dialogs/detaildialog.cpp:1108 dialogs/detaildialog.cpp:1140 -#: kstarsactions.cpp:303 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 +#: kstarsactions.cpp:306 tools/flagmanager.cpp:267 tools/flagmanager.cpp:292 #: tools/observinglist.cpp:687 tools/observinglist.cpp:709 #: tools/whatsinteresting/wiview.cpp:339 tools/whatsinteresting/wiview.cpp:364 #, fuzzy, kde-format @@ -3653,8 +3656,8 @@ msgid "No connected mounts found." msgstr "%1 adlı cisim tapılmadı." -#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:436 -#: kstarsactions.cpp:288 tools/observinglist.cpp:698 +#: dialogs/detaildialog.cpp:1119 fitsviewer/fitslabel.cpp:447 +#: kstarsactions.cpp:291 tools/observinglist.cpp:698 #: tools/whatsinteresting/wiview.cpp:350 #, fuzzy, kde-format #| msgid "Telescope %1 is offline. Please connect and retry again." @@ -3748,18 +3751,20 @@ #. i18n: ectx: property (text), widget (QLabel, masterMean) #. i18n: ectx: property (text), widget (QLabel, masterMedian) #. i18n: ectx: property (text), widget (QLabel, masterDeviation) +#. i18n: ectx: property (text), widget (QLabel, exposureCount) #. i18n: ectx: property (text), widget (QLabel, l_FOV) #. i18n: ectx: property (text), widget (QLabel, l_Reducer) #. i18n: ectx: property (text), widget (QLabel, avgFPS) #. i18n: ectx: property (text), widget (QLineEdit, f_LockedFilter) -#: dialogs/details_data.ui:390 ekos/align/align.cpp:922 +#: dialogs/details_data.ui:390 ekos/align/align.cpp:929 #: ekos/analyze/analyze.ui:74 ekos/auxiliary/darklibrary.cpp:1054 #: ekos/auxiliary/darklibrary.ui:276 ekos/auxiliary/darklibrary.ui:424 #: ekos/auxiliary/darklibrary.ui:693 ekos/auxiliary/darklibrary.ui:713 #: ekos/auxiliary/darklibrary.ui:733 ekos/auxiliary/darklibrary.ui:753 #: ekos/auxiliary/darklibrary.ui:773 ekos/auxiliary/darklibrary.ui:793 -#: ekos/capture/capture.cpp:876 ekos/capture/capture.cpp:914 -#: ekos/focus/focus.cpp:368 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 +#: ekos/capture/capture.cpp:900 ekos/capture/capture.cpp:940 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:814 +#: ekos/focus/focus.cpp:373 ekos/guide/guide.ui:553 ekos/guide/guide.ui:677 #: indi/streamform.ui:368 oal/equipmentwriter.ui:1163 #, kde-format msgid "--" @@ -4244,7 +4249,7 @@ msgid "Any" msgstr "Hər hansı" -#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1105 kstarsinit.cpp:472 +#: dialogs/finddialog.cpp:38 kstarsactions.cpp:1114 kstarsinit.cpp:472 #: kstarslite/dialogs/finddialoglite.cpp:27 #: kstarslite/qml/modules/TopMenu.qml:159 tools/astrocalc.cpp:166 #: tools/conjunctions.cpp:96 @@ -4368,33 +4373,33 @@ msgid "Set Coordinates Manually" msgstr "Kordinatları əl ilə daxil etmək" -#: dialogs/focusdialog.cpp:127 tools/flagmanager.cpp:184 +#: dialogs/focusdialog.cpp:128 tools/flagmanager.cpp:184 #, kde-format msgid "The Right Ascension value must be between 0.0 and 24.0." msgstr "Birbaşa Yüksəliş dəyəri 0.0 ilə 24.0 arasında olmalıdır." -#: dialogs/focusdialog.cpp:129 tools/flagmanager.cpp:186 +#: dialogs/focusdialog.cpp:130 tools/flagmanager.cpp:186 #, kde-format msgid "The Declination value must be between -90.0 and 90.0." msgstr "Meyillənmə dəyəri 90.0 ilə 90.0 arasında olmalıdır." -#: dialogs/focusdialog.cpp:132 dialogs/focusdialog.cpp:185 +#: dialogs/focusdialog.cpp:133 dialogs/focusdialog.cpp:191 #: tools/flagmanager.cpp:189 #, kde-format msgid "Invalid Coordinate Data" msgstr "Yalnış koordinat göstəriciləri" -#: dialogs/focusdialog.cpp:140 +#: dialogs/focusdialog.cpp:141 #, kde-format msgid "Invalid Epoch format" msgstr "Yalnış dövr formatı" -#: dialogs/focusdialog.cpp:180 +#: dialogs/focusdialog.cpp:186 #, kde-format msgid "The Azimuth value must be between 0.0 and 360.0." msgstr "Azimut dəyəri 0.0 ilə 360.0 arasında olmalıdır." -#: dialogs/focusdialog.cpp:182 +#: dialogs/focusdialog.cpp:188 #, kde-format msgid "The Altitude value must be between -90.0 and 90.0." msgstr "Hündürlük dəyəri 90.0 ilə 90.0 arasında olmalıdır." @@ -4459,7 +4464,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1) #. i18n: ectx: property (text), widget (QLabel, label_7) #: dialogs/focusdialog.ui:151 ekos/align/polaralignmentassistant.ui:592 -#: ekos/capture/calibrationoptions.ui:88 tools/argsetaltaz.ui:30 +#: ekos/capture/calibrationoptions.ui:73 tools/argsetaltaz.ui:30 #: tools/modcalcplanets.ui:303 #, kde-format msgid "Az:" @@ -5132,7 +5137,7 @@ #. i18n: ectx: attribute (title), widget (QWidget, tab2) #. i18n: ectx: property (text), widget (QLabel, indiCameraLabel) #: dialogs/newfov.ui:433 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:312 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:127 #, kde-format msgid "Camera" msgstr "" @@ -5760,7 +5765,7 @@ "location on Earth.

    To get started, press the Next button.

    " msgstr "" -#: ekos/align/align.cpp:326 +#: ekos/align/align.cpp:333 #, kde-format msgid "" "
    Object %1: %2
    RA:%3
    dDE:%6
    " msgstr "" -#: ekos/align/align.cpp:456 +#: ekos/align/align.cpp:463 #, kde-format msgid "Are you sure you want to clear all of the solution points?" msgstr "" -#: ekos/align/align.cpp:457 +#: ekos/align/align.cpp:464 #, kde-format msgid "Clear Solution Points" msgstr "" -#: ekos/align/align.cpp:530 +#: ekos/align/align.cpp:537 #, kde-format msgid "Solver timed out." msgstr "" -#: ekos/align/align.cpp:822 +#: ekos/align/align.cpp:829 #, kde-format msgid "Mount does not support syncing." msgstr "" -#: ekos/align/align.cpp:1027 +#: ekos/align/align.cpp:1034 #, kde-format msgid "Effective telescope focal length is updated to %1 mm." msgstr "" -#: ekos/align/align.cpp:1069 +#: ekos/align/align.cpp:1076 #, kde-format msgid "" "Warning! The calculated field of view (%1) is out of bounds. Ensure the " "telescope focal length and camera pixel size are correct." msgstr "" -#: ekos/align/align.cpp:1108 +#: ekos/align/align.cpp:1115 #, kde-format msgid "" "

    Effective field of view size in arcminutes.

    Please capture and " @@ -5808,84 +5813,84 @@ "p>

    Calculated FOV: %1

    " msgstr "" -#: ekos/align/align.cpp:1117 +#: ekos/align/align.cpp:1124 #, kde-format msgid "

    Effective field of view size in arcminutes.

    " msgstr "" -#: ekos/align/align.cpp:1398 +#: ekos/align/align.cpp:1405 #, kde-format msgid "Error: No camera detected." msgstr "" -#: ekos/align/align.cpp:1404 +#: ekos/align/align.cpp:1411 #, kde-format msgid "Error: lost connection to camera." msgstr "" -#: ekos/align/align.cpp:1405 ekos/align/align.cpp:2308 +#: ekos/align/align.cpp:1412 ekos/align/align.cpp:2344 #, kde-format msgid "Astrometry alignment failed" msgstr "" -#: ekos/align/align.cpp:1421 +#: ekos/align/align.cpp:1428 #, kde-format msgid "" "Telescope aperture and focal length are missing. Please check your optical " "train settings and try again." msgstr "" -#: ekos/align/align.cpp:1427 +#: ekos/align/align.cpp:1434 #, kde-format msgid "" "CCD pixel size is missing. Please check your driver settings and try again." msgstr "" -#: ekos/align/align.cpp:1435 +#: ekos/align/align.cpp:1442 #, kde-format msgid "Error: lost connection to filter wheel." msgstr "" -#: ekos/align/align.cpp:1455 ekos/capture/captureprocess.cpp:170 -#: ekos/capture/captureprocess.cpp:563 ekos/focus/focus.cpp:4819 +#: ekos/align/align.cpp:1462 ekos/capture/captureprocess.cpp:191 +#: ekos/capture/captureprocess.cpp:584 ekos/focus/focus.cpp:5060 #, kde-format msgid "" "Image transfer is disabled for this camera. Would you like to enable it?" msgstr "" -#: ekos/align/align.cpp:1475 +#: ekos/align/align.cpp:1482 #, kde-format msgid "Cannot capture while focus module is busy. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1483 +#: ekos/align/align.cpp:1490 #, kde-format msgid "" "Cannot capture while CCD exposure is in progress. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1492 +#: ekos/align/align.cpp:1499 #, kde-format msgid "Cannot capture while rotator is busy. Retrying in %1 seconds..." msgstr "" -#: ekos/align/align.cpp:1510 ekos/align/align.cpp:2976 +#: ekos/align/align.cpp:1517 ekos/align/align.cpp:3012 #, kde-format msgid "No remote astrometry driver detected, switching to StellarSolver." msgstr "" -#: ekos/align/align.cpp:1564 ekos/focus/focus.cpp:1735 +#: ekos/align/align.cpp:1571 ekos/focus/focus.cpp:1760 #, kde-format msgid "Capturing image..." msgstr "" -#: ekos/align/align.cpp:1654 ekos/auxiliary/ledstatuswidget.cpp:71 -#: ekos/focus/focus.cpp:2587 +#: ekos/align/align.cpp:1661 ekos/auxiliary/ledstatuswidget.cpp:71 +#: ekos/focus/focus.cpp:2706 #, kde-format msgid "Image received." msgstr "" -#: ekos/align/align.cpp:1784 +#: ekos/align/align.cpp:1791 #, kde-format msgid "" "No index files were found on your system in the specified index file " @@ -5893,86 +5898,102 @@ "to the list." msgstr "" -#: ekos/align/align.cpp:1843 +#: ekos/align/align.cpp:1850 #, fuzzy, kde-format #| msgid "Saving of the image %1 failed." msgid "Solving with blind image scale..." msgstr "%1 çəklinin saxlanılması baş tutmadı." -#: ekos/align/align.cpp:1851 +#: ekos/align/align.cpp:1858 #, kde-format msgid "Solving with blind image position..." msgstr "" -#: ekos/align/align.cpp:1883 +#: ekos/align/align.cpp:1890 #, kde-format msgid "Loaded image does not have pierside information" msgstr "" -#: ekos/align/align.cpp:1888 +#: ekos/align/align.cpp:1895 #, kde-format msgid "Loaded image was taken on pierside %1" msgstr "" -#: ekos/align/align.cpp:1990 +#: ekos/align/align.cpp:2020 #, kde-format msgid "Solver completed after %1 seconds." msgstr "" -#: ekos/align/align.cpp:2006 +#: ekos/align/align.cpp:2036 #, kde-format msgid "Solver RA (%1) DEC (%2) Orientation (%3) Pixel Scale (%4) Parity (%5)" msgstr "" -#: ekos/align/align.cpp:2073 +#: ekos/align/align.cpp:2103 #, kde-format msgid "" "WCS information updated. Images captured from this point forward shall have " "valid WCS." msgstr "" -#: ekos/align/align.cpp:2091 +#: ekos/align/align.cpp:2121 #, kde-format msgid "" "Solution coordinates: RA (%1) DEC (%2) Telescope Coordinates: RA (%3) DEC " "(%4) Target Coordinates: RA (%5) DEC (%6)" msgstr "" -#: ekos/align/align.cpp:2102 +#: ekos/align/align.cpp:2132 #, kde-format msgid "Target is within %1 degrees of solution coordinates." msgstr "" #. i18n("Camera offset angle is %1 degrees.", OffsetAngle)); -#: ekos/align/align.cpp:2147 +#: ekos/align/align.cpp:2177 #, fuzzy, kde-format #| msgid "Position Angle" msgid "Camera position angle is %1 degrees." msgstr "Mövqe Bucağı" -#: ekos/align/align.cpp:2169 ekos/align/align.cpp:2601 -#: ekos/align/align.cpp:2641 +#: ekos/align/align.cpp:2199 ekos/align/align.cpp:2637 +#: ekos/align/align.cpp:2677 #, kde-format msgid "Astrometry alignment completed successfully" msgstr "" -#: ekos/align/align.cpp:2191 +#: ekos/align/align.cpp:2221 #, kde-format msgid "Maximum number of iterations reached. Solver failed." msgstr "" -#: ekos/align/align.cpp:2220 +#: ekos/align/align.cpp:2250 #, kde-format msgid "Target is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2303 +#: ekos/align/align.cpp:2312 +#, fuzzy, kde-format +#| msgid "Saved image to %1" +msgid "Saving failed solver image to %1" +msgstr "Şəkil %1 də(a) saxlanıldı" + +#: ekos/align/align.cpp:2321 +#, kde-format +msgid "Solver failed. Retrying without scale constraint." +msgstr "" + +#: ekos/align/align.cpp:2331 +#, kde-format +msgid "Solver failed. Retrying without position constraint." +msgstr "" + +#: ekos/align/align.cpp:2339 #, fuzzy, kde-format #| msgid "Solver FOV" msgid "Solver Failed." msgstr "Həlledicinin BaxışBucağı" -#: ekos/align/align.cpp:2306 +#: ekos/align/align.cpp:2342 #, kde-format msgid "" "Please check you have sufficient stars in the image, the indicated FOV is " @@ -5980,254 +6001,254 @@ "Logging in Setup Tab -> Logs to get detailed information on the failure." msgstr "" -#: ekos/align/align.cpp:2365 +#: ekos/align/align.cpp:2401 #, kde-format msgid "Setting camera position angle to %1 degrees ..." msgstr "" -#: ekos/align/align.cpp:2372 +#: ekos/align/align.cpp:2408 #, kde-format msgid "Camera position angle is within acceptable range." msgstr "" -#: ekos/align/align.cpp:2386 +#: ekos/align/align.cpp:2422 #, kde-format msgid "Current PA is %1; Target PA is %2; diff: %3" msgstr "" -#: ekos/align/align.cpp:2453 +#: ekos/align/align.cpp:2489 #, kde-format msgid "Refresh is complete." msgstr "" -#: ekos/align/align.cpp:2460 ekos/auxiliary/darklibrary.cpp:1411 -#: ekos/focus/focus.cpp:1506 +#: ekos/align/align.cpp:2496 ekos/auxiliary/darklibrary.cpp:1411 +#: ekos/focus/focus.cpp:1529 #, kde-format msgid "Capture aborted." msgstr "" -#: ekos/align/align.cpp:2466 +#: ekos/align/align.cpp:2502 #, kde-format msgid "Solver aborted after %1 seconds." msgstr "" -#: ekos/align/align.cpp:2509 ekos/capture/capture.cpp:1446 -#: ekos/focus/focus.cpp:3964 ekos/guide/guide.cpp:1118 ekos/manager.cpp:1897 -#: ekos/mount/mount.cpp:836 ekos/observatory/observatory.cpp:952 -#: ekos/scheduler/scheduler.cpp:911 +#: ekos/align/align.cpp:2545 ekos/capture/capture.cpp:1477 +#: ekos/focus/focus.cpp:4188 ekos/guide/guide.cpp:1137 ekos/manager.cpp:1903 +#: ekos/mount/mount.cpp:838 ekos/observatory/observatory.cpp:952 +#: ekos/scheduler/scheduler.cpp:748 #, kde-format msgctxt "log entry; %1 is the date, %2 is the text" msgid "%1 %2" msgstr "" -#: ekos/align/align.cpp:2572 +#: ekos/align/align.cpp:2608 #, kde-format msgid "Mount completed slewing near celestial pole. Capture again to verify." msgstr "" -#: ekos/align/align.cpp:2595 +#: ekos/align/align.cpp:2631 #, kde-format msgid "Mount is synced to solution coordinates." msgstr "" -#: ekos/align/align.cpp:2630 ekos/align/align.cpp:2660 -#: ekos/align/align.cpp:3971 ekos/align/polaralignmentassistant.cpp:637 +#: ekos/align/align.cpp:2666 ekos/align/align.cpp:2696 +#: ekos/align/align.cpp:4009 ekos/align/polaralignmentassistant.cpp:639 #, kde-format msgid "Settling..." msgstr "" -#: ekos/align/align.cpp:2636 +#: ekos/align/align.cpp:2672 #, kde-format msgid "Differential slewing complete." msgstr "" -#: ekos/align/align.cpp:2650 +#: ekos/align/align.cpp:2686 #, kde-format msgid "Slew complete. Target accuracy is not met, running solver again..." msgstr "" -#: ekos/align/align.cpp:2652 +#: ekos/align/align.cpp:2688 #, kde-format msgid "Slew complete. Solving Alignment Point. . ." msgstr "" -#: ekos/align/align.cpp:2695 ekos/align/align.cpp:2847 +#: ekos/align/align.cpp:2731 ekos/align/align.cpp:2883 #, kde-format msgid "Syncing failed." msgstr "" -#: ekos/align/align.cpp:2697 +#: ekos/align/align.cpp:2733 #, kde-format msgid "Slewing failed." msgstr "" -#: ekos/align/align.cpp:2740 +#: ekos/align/align.cpp:2776 #, kde-format msgid "Rotator reached camera position angle." msgstr "" -#: ekos/align/align.cpp:2752 +#: ekos/align/align.cpp:2788 #, kde-format msgid "" "Rotator failed to arrive at the requested position angle (Deviation %1 " "arcmin)." msgstr "" -#: ekos/align/align.cpp:2797 +#: ekos/align/align.cpp:2833 #, kde-format msgid "Slew detected, suspend solving..." msgstr "" -#: ekos/align/align.cpp:2841 +#: ekos/align/align.cpp:2877 #, kde-format msgid "Syncing to RA (%1) DEC (%2)" msgstr "" -#: ekos/align/align.cpp:2865 +#: ekos/align/align.cpp:2901 #, kde-format msgid "Slewing to target coordinates: RA (%1) DEC (%2)." msgstr "" -#: ekos/align/align.cpp:2870 +#: ekos/align/align.cpp:2906 #, kde-format msgid "" "Slewing to target coordinates: RA (%1) DEC (%2) is rejected. (see " "notification)" msgstr "" -#: ekos/align/align.cpp:2889 +#: ekos/align/align.cpp:2925 #, kde-format msgid "Ekos job (%1) - Telescope synced" msgstr "" -#: ekos/align/align.cpp:2945 +#: ekos/align/align.cpp:2981 #, fuzzy, kde-format #| msgid "Save Image" msgctxt "@title:window" msgid "Load Image" msgstr "Şəkli saxlamaq" -#: ekos/align/align.cpp:3175 +#: ekos/align/align.cpp:3211 #, kde-format msgid "World Coordinate System (WCS) is enabled." msgstr "" -#: ekos/align/align.cpp:3180 +#: ekos/align/align.cpp:3216 #, kde-format msgid "World Coordinate System (WCS) is disabled." msgstr "" -#: ekos/align/align.cpp:3199 +#: ekos/align/align.cpp:3235 #, kde-format msgid "Capture error. Aborting..." msgstr "" -#: ekos/align/align.cpp:3204 ekos/capture/captureprocess.cpp:1444 -#: ekos/capture/captureprocess.cpp:1939 +#: ekos/align/align.cpp:3240 ekos/capture/captureprocess.cpp:1470 +#: ekos/capture/captureprocess.cpp:1965 #, kde-format msgid "Restarting capture attempt #%1" msgstr "" -#: ekos/align/align.cpp:3324 +#: ekos/align/align.cpp:3360 #, kde-format msgctxt "@title:window" msgid "Align Frame" msgstr "" -#: ekos/align/align.cpp:3399 +#: ekos/align/align.cpp:3435 #, kde-format msgid "StellarSolver Options" msgstr "" -#: ekos/align/align.cpp:3404 +#: ekos/align/align.cpp:3440 #, kde-format msgid "External & Online Programs" msgstr "" -#: ekos/align/align.cpp:3408 +#: ekos/align/align.cpp:3444 #, fuzzy, kde-format #| msgid "Position" msgid "Scale & Position" msgstr "Mövqeyi" -#: ekos/align/align.cpp:3412 +#: ekos/align/align.cpp:3448 #, kde-format msgid "Align Options Profiles Editor" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/align/align.cpp:3430 ekos/align/opsastrometryindexfiles.ui:329 +#: ekos/align/align.cpp:3466 ekos/align/opsastrometryindexfiles.ui:329 #, kde-format msgid "Index Files" msgstr "" -#: ekos/align/align.cpp:3495 ekos/guide/guidetargetplot.cpp:55 +#: ekos/align/align.cpp:3531 ekos/guide/guidetargetplot.cpp:55 #, kde-format msgid "dRA (arcsec)" msgstr "" -#: ekos/align/align.cpp:3496 ekos/guide/guidetargetplot.cpp:56 +#: ekos/align/align.cpp:3532 ekos/guide/guidetargetplot.cpp:56 #, kde-format msgid "dDE (arcsec)" msgstr "" -#: ekos/align/align.cpp:3542 ekos/capture/capture.cpp:3297 -#: ekos/focus/focus.cpp:4711 +#: ekos/align/align.cpp:3578 ekos/capture/capture.cpp:2654 +#: ekos/focus/focus.cpp:4952 #, kde-format msgid "Filter operation failed." msgstr "" -#: ekos/align/align.cpp:3554 ekos/capture/capture.cpp:3233 +#: ekos/align/align.cpp:3590 ekos/capture/capture.cpp:2590 #, kde-format msgid "Changing focus offset by %1 steps..." msgstr "" -#: ekos/align/align.cpp:3561 ekos/auxiliary/buildfilteroffsets.cpp:466 -#: ekos/capture/capture.cpp:3238 +#: ekos/align/align.cpp:3597 ekos/auxiliary/buildfilteroffsets.cpp:466 +#: ekos/capture/capture.cpp:2595 #, kde-format msgid "Changing filter to %1..." msgstr "" -#: ekos/align/align.cpp:3566 ekos/capture/capture.cpp:3243 +#: ekos/align/align.cpp:3602 ekos/capture/capture.cpp:2600 #, kde-format msgid "Auto focus on filter change..." msgstr "" -#: ekos/align/align.cpp:3687 +#: ekos/align/align.cpp:3723 #, kde-format msgid "Invalid FOV." msgstr "" -#: ekos/align/align.cpp:3822 +#: ekos/align/align.cpp:3860 #, kde-format msgctxt "@title:window" msgid "Export Solution Points" msgstr "" -#: ekos/align/align.cpp:3845 ekos/align/mountmodel.cpp:263 -#: ekos/align/mountmodel.cpp:389 ekos/capture/capture.cpp:2077 -#: ekos/capture/capture.cpp:2507 ekos/guide/guidedriftgraph.cpp:475 -#: ekos/scheduler/scheduler.cpp:3462 ekos/scheduler/scheduler.cpp:3831 -#: fitsviewer/fitstab.cpp:494 tools/scriptbuilder.cpp:832 +#: ekos/align/align.cpp:3883 ekos/align/mountmodel.cpp:264 +#: ekos/align/mountmodel.cpp:390 ekos/capture/capture.cpp:1950 +#: ekos/capture/capture.cpp:2036 ekos/guide/guidedriftgraph.cpp:476 +#: ekos/scheduler/scheduler.cpp:2592 ekos/scheduler/scheduler.cpp:2959 +#: fitsviewer/fitstab.cpp:503 tools/scriptbuilder.cpp:832 #: tools/scriptbuilder.cpp:929 #, kde-format msgid "Invalid URL: %1" msgstr "" -#: ekos/align/align.cpp:3854 ekos/align/mountmodel.cpp:400 -#: ekos/capture/capture.cpp:2530 ekos/guide/guidedriftgraph.cpp:484 -#: ekos/scheduler/scheduler.cpp:3843 ekos/scheduler/scheduler.cpp:6221 +#: ekos/align/align.cpp:3892 ekos/align/mountmodel.cpp:401 +#: ekos/capture/captureprocess.cpp:2392 ekos/guide/guidedriftgraph.cpp:485 +#: ekos/scheduler/scheduler.cpp:4001 ekos/scheduler/schedulerprocess.cpp:1573 #, kde-format msgid "Unable to write to file %1" msgstr "" -#: ekos/align/align.cpp:3855 ekos/align/mountmodel.cpp:283 -#: ekos/align/mountmodel.cpp:401 ekos/capture/capture.cpp:2093 -#: ekos/guide/guidedriftgraph.cpp:485 ekos/scheduler/scheduler.cpp:3506 -#: ekos/scheduler/scheduler.cpp:3844 ekos/scheduler/scheduler.cpp:6165 -#: ekos/scheduler/scheduler.cpp:6222 indi/drivermanager.cpp:1520 -#: indi/indidriver.cpp:921 kstarsactions.cpp:1375 oal/execute.cpp:320 -#: options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 +#: ekos/align/align.cpp:3893 ekos/align/mountmodel.cpp:284 +#: ekos/align/mountmodel.cpp:402 ekos/capture/capture.cpp:1966 +#: ekos/capture/captureprocess.cpp:2276 ekos/guide/guidedriftgraph.cpp:486 +#: ekos/scheduler/scheduler.cpp:2636 ekos/scheduler/scheduler.cpp:3945 +#: ekos/scheduler/scheduler.cpp:4002 ekos/scheduler/schedulerprocess.cpp:1574 +#: indi/drivermanager.cpp:1537 indi/indidriver.cpp:921 kstarsactions.cpp:1384 +#: oal/execute.cpp:320 options/opscolors.cpp:262 tools/modcalcangdist.cpp:132 #: tools/modcalcapcoord.cpp:142 tools/modcalcdaylength.cpp:257 #: tools/modcalcgalcoord.cpp:191 tools/modcalcgeodcoord.cpp:231 #: tools/modcalcjd.cpp:117 tools/modcalcplanets.cpp:195 @@ -6239,27 +6260,27 @@ msgid "Could Not Open File" msgstr "Fayl açıla bilmədi" -#: ekos/align/align.cpp:3876 +#: ekos/align/align.cpp:3914 #, kde-format msgid "Error in table structure." msgstr "" -#: ekos/align/align.cpp:3885 +#: ekos/align/align.cpp:3923 #, kde-format msgid "Solution Points Saved as: %1" msgstr "" -#: ekos/align/align.cpp:3899 +#: ekos/align/align.cpp:3937 #, kde-format msgid "Polar Alignment" msgstr "" -#: ekos/align/align.cpp:4428 +#: ekos/align/align.cpp:4466 #, kde-format msgid "Capture timed out." msgstr "" -#: ekos/align/align.cpp:4437 +#: ekos/align/align.cpp:4475 #, kde-format msgid "Capturing still running, Retrying in %1 seconds..." msgstr "" @@ -6305,7 +6326,7 @@ #. i18n: ectx: property (text), widget (QPushButton, stopFocusB) #: ekos/align/align.ui:149 ekos/align/polaralignmentassistant.ui:819 #: ekos/align/polaralignmentassistant.ui:822 ekos/auxiliary/darklibrary.ui:585 -#: ekos/focus/focus.ui:456 ekos/guide/guide.ui:153 ekos/manager.cpp:222 +#: ekos/focus/focus.ui:373 ekos/guide/guide.ui:153 ekos/manager.cpp:226 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:137 @@ -6539,20 +6560,20 @@ #. i18n: ectx: property (text), widget (QLabel, gainLabel) #: ekos/align/align.ui:555 ekos/auxiliary/darklibrary.ui:477 #: ekos/capture/capture.ui:137 ekos/capture/captureprocessoverlay.ui:296 -#: ekos/focus/focus.ui:514 +#: ekos/focus/focus.ui:533 #, kde-format msgid "Gain:" msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_18) #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/align.ui:562 ekos/focus/focus.ui:790 ekos/guide/guide.ui:401 +#: ekos/align/align.ui:562 ekos/focus/focus.ui:809 ekos/guide/guide.ui:401 #, kde-format msgid "Bin:" msgstr "" #. i18n: ectx: property (toolTip), widget (QPushButton, showFITSViewerB) -#: ekos/align/align.ui:584 ekos/focus/focus.ui:720 ekos/guide/guide.ui:166 +#: ekos/align/align.ui:584 ekos/focus/focus.ui:739 ekos/guide/guide.ui:166 #, kde-format msgid "Show in FITS Viewer" msgstr "" @@ -6604,7 +6625,7 @@ #. i18n: ectx: property (text), widget (QLabel, filterLabel) #. i18n: ectx: property (text), widget (QLabel, label) #. i18n: ectx: property (text), widget (QLabel, label_18) -#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:558 +#: ekos/align/align.ui:686 ekos/capture/capture.ui:506 ekos/focus/focus.ui:577 #: ekos/profileeditor.ui:644 fitsviewer/fitsdebayer.ui:22 oal/execute.ui:358 #, kde-format msgid "Filter:" @@ -6620,7 +6641,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/align/align.ui:700 ekos/focus/focus.ui:571 ekos/guide/guide.ui:375 +#: ekos/align/align.ui:700 ekos/focus/focus.ui:590 ekos/guide/guide.ui:375 #, kde-format msgid "Exp:" msgstr "" @@ -6635,7 +6656,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_11) #. i18n: ectx: property (text), widget (QLabel, ISOLabel) #: ekos/align/align.ui:736 ekos/auxiliary/darklibrary.ui:506 -#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:816 +#: ekos/capture/capture.ui:1198 ekos/focus/focus.ui:835 #, kde-format msgid "ISO:" msgstr "" @@ -6695,11 +6716,12 @@ #. i18n: ectx: property (text), widget (QLabel, label_7) #. i18n: ectx: property (text), widget (QLabel, l_02) #. i18n: ectx: property (text), widget (QLabel, label_2) +#. i18n: ectx: property (text), widget (QLabel, FitsSolverDECLabel) #: ekos/align/align.ui:916 ekos/align/opsastrometry.ui:389 #: ekos/guide/guide.ui:342 ekos/guide/guide.ui:1247 #: ekos/guide/opscalibration.ui:300 ekos/guide/opsguide.ui:128 #: ekos/mount/mount.ui:161 ekos/scheduler/scheduler.ui:488 -#: skycomponents/imageoverlaycomponent.cpp:62 +#: fitsviewer/platesolve.ui:222 skycomponents/imageoverlaycomponent.cpp:62 #, kde-format msgid "DEC" msgstr "" @@ -6846,77 +6868,78 @@ msgid "Take Another Image" msgstr "" -#: ekos/align/mountmodel.cpp:255 +#: ekos/align/mountmodel.cpp:256 #, kde-format msgctxt "@title:window" msgid "Open Ekos Alignment List" msgstr "" -#: ekos/align/mountmodel.cpp:282 ekos/capture/capture.cpp:2092 -#: ekos/scheduler/scheduler.cpp:3505 ekos/scheduler/scheduler.cpp:6164 +#: ekos/align/mountmodel.cpp:283 ekos/capture/capture.cpp:1965 +#: ekos/capture/captureprocess.cpp:2275 ekos/scheduler/scheduler.cpp:2635 +#: ekos/scheduler/scheduler.cpp:3944 #, kde-format msgid "Unable to open file %1" msgstr "" -#: ekos/align/mountmodel.cpp:304 ekos/capture/capture.cpp:2119 +#: ekos/align/mountmodel.cpp:305 ekos/capture/captureprocess.cpp:2301 #, kde-format msgid "" "Deprecated sequence file format version %1. Please construct a new sequence " "file." msgstr "" -#: ekos/align/mountmodel.cpp:366 +#: ekos/align/mountmodel.cpp:367 #, kde-format msgctxt "@title:window" msgid "Save Ekos Alignment List" msgstr "" -#: ekos/align/mountmodel.cpp:383 +#: ekos/align/mountmodel.cpp:384 #, kde-format msgid "Failed to save alignment list" msgstr "" -#: ekos/align/mountmodel.cpp:429 +#: ekos/align/mountmodel.cpp:430 #, kde-format msgid "Alignment List saved to %1" msgstr "" -#: ekos/align/mountmodel.cpp:541 ekos/align/mountmodel.cpp:549 +#: ekos/align/mountmodel.cpp:542 ekos/align/mountmodel.cpp:550 #, kde-format msgid "DEC is below the altitude limit" msgstr "" -#: ekos/align/mountmodel.cpp:628 +#: ekos/align/mountmodel.cpp:629 #, kde-format msgid "Point calculation error." msgstr "" -#: ekos/align/mountmodel.cpp:650 +#: ekos/align/mountmodel.cpp:651 #, kde-format msgid "Sky Point" msgstr "" -#: ekos/align/mountmodel.cpp:858 +#: ekos/align/mountmodel.cpp:859 #, kde-format msgid "Are you sure you want to clear all the alignment points?" msgstr "" -#: ekos/align/mountmodel.cpp:859 +#: ekos/align/mountmodel.cpp:860 #, kde-format msgid "Clear Align Points" msgstr "" -#: ekos/align/mountmodel.cpp:964 +#: ekos/align/mountmodel.cpp:965 #, kde-format msgid "The Mount Model Tool is Reset." msgstr "" -#: ekos/align/mountmodel.cpp:1001 +#: ekos/align/mountmodel.cpp:1002 #, kde-format msgid "Please Check the Alignment Points." msgstr "" -#: ekos/align/mountmodel.cpp:1008 +#: ekos/align/mountmodel.cpp:1009 #, kde-format msgid "" "In the Align Module, \"Nothing\" is Selected for the Solver Action. This " @@ -6924,22 +6947,22 @@ "report the pointing model errors. Do you wish to continue?" msgstr "" -#: ekos/align/mountmodel.cpp:1011 +#: ekos/align/mountmodel.cpp:1012 #, kde-format msgid "Pointing Model Report Only?" msgstr "" -#: ekos/align/mountmodel.cpp:1028 +#: ekos/align/mountmodel.cpp:1029 #, kde-format msgid "The Mount Model Tool is Starting." msgstr "" -#: ekos/align/mountmodel.cpp:1037 +#: ekos/align/mountmodel.cpp:1038 #, kde-format msgid "The Mount Model Tool is Paused." msgstr "" -#: ekos/align/mountmodel.cpp:1096 +#: ekos/align/mountmodel.cpp:1097 #, kde-format msgid "The Mount Model Tool is Finished." msgstr "" @@ -7624,8 +7647,11 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUseImageScale) +#. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_FitsSolverUseScale) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverScale) #. i18n: ectx: label, entry (AstrometryUseImageScale), group (Align) -#: ekos/align/opsastrometry.ui:57 kstars.kcfg:2329 +#: ekos/align/opsastrometry.ui:57 fitsviewer/platesolve.ui:57 +#: fitsviewer/platesolve.ui:70 kstars.kcfg:2399 #, kde-format msgid "" "Set image scale to speed up solver as it does not have to search index files " @@ -7633,7 +7659,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUseImageScale) -#: ekos/align/opsastrometry.ui:60 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUseScale) +#: ekos/align/opsastrometry.ui:60 fitsviewer/platesolve.ui:60 #, kde-format msgid "Use Scale" msgstr "" @@ -7765,7 +7792,7 @@ #. i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_AstrometryUsePosition) #. i18n: ectx: label, entry (AstrometryUsePosition), group (Align) -#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2359 +#: ekos/align/opsastrometry.ui:322 kstars.kcfg:2429 #, kde-format msgid "" "Set estimated position to speed up astrometry solver as it does not have to " @@ -7773,16 +7800,19 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AstrometryUsePosition) -#: ekos/align/opsastrometry.ui:325 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_FitsSolverUsePosition) +#: ekos/align/opsastrometry.ui:325 fitsviewer/platesolve.ui:142 #, kde-format msgid "Use Position" msgstr "" #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_44) #. i18n: ectx: property (toolTip), widget (QLabel, label_8) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRadiusLabel) +#. i18n: ectx: property (toolTip), widget (QDoubleSpinBox, kcfg_FitsSolverRadius) #. i18n: ectx: label, entry (AstrometryRadius), group (Align) #: ekos/align/opsastrometry.ui:344 ekos/align/opsastrometry.ui:451 -#: kstars.kcfg:2373 +#: fitsviewer/platesolve.ui:270 fitsviewer/platesolve.ui:286 kstars.kcfg:2443 #, kde-format msgid "" "The Search Radius for the Estimated Telescope/Image Field Position in " @@ -7804,8 +7834,11 @@ #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_47) #. i18n: ectx: property (toolTip), widget (dmsBox, estRA) #. i18n: ectx: property (toolTip), widget (QLabel, label_14) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverRALabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstRA) #: ekos/align/opsastrometry.ui:376 ekos/align/opsastrometry.ui:399 -#: ekos/align/opsastrometry.ui:406 +#: ekos/align/opsastrometry.ui:406 fitsviewer/platesolve.ui:174 +#: fitsviewer/platesolve.ui:199 #, kde-format msgid "" "The RA of the Estimated Telescope/Image Field Position in hh:mm:ss notation" @@ -7820,8 +7853,11 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_15) #. i18n: ectx: property (toolTip), widget (dmsBox, estDec) #. i18n: ectx: property (toolTip), widget (QLineEdit, lineEdit_48) +#. i18n: ectx: property (toolTip), widget (QLabel, FitsSolverDECLabel) +#. i18n: ectx: property (toolTip), widget (dmsBox, FitsSolverEstDec) #: ekos/align/opsastrometry.ui:386 ekos/align/opsastrometry.ui:470 -#: ekos/align/opsastrometry.ui:493 +#: ekos/align/opsastrometry.ui:493 fitsviewer/platesolve.ui:219 +#: fitsviewer/platesolve.ui:250 #, kde-format msgid "" "The DEC of the Estimated Telescope/Image Field Position in dd:mm:ss notation" @@ -7834,7 +7870,8 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/align/opsastrometry.ui:454 +#. i18n: ectx: property (text), widget (QLabel, FitsSolverRadiusLabel) +#: ekos/align/opsastrometry.ui:454 fitsviewer/platesolve.ui:273 #, kde-format msgid "Radius" msgstr "" @@ -8054,7 +8091,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, northDECGuideEnabled) #: ekos/align/opsastrometryindexfiles.ui:256 ekos/analyze/analyze.ui:199 #: ekos/auxiliary/stellarsolverprofileeditor.ui:213 -#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:531 +#: ekos/capture/exposurecalculator/exposurecalculatordialog.ui:511 #: ekos/guide/guide.ui:304 ekos/guide/guide.ui:456 #: kstarslite/qml/indi/modules/MotionControl.qml:294 #, kde-format, kde-kuit-format @@ -8992,201 +9029,207 @@ msgid "API Key:" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:28 +#: ekos/align/polaralignmentassistant.cpp:29 #, kde-format msgid "First Capture" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:29 +#: ekos/align/polaralignmentassistant.cpp:30 #, kde-format msgid "First Solve" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:30 +#: ekos/align/polaralignmentassistant.cpp:31 #, kde-format msgid "Finding CP" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:31 +#: ekos/align/polaralignmentassistant.cpp:32 #, kde-format msgid "First Rotation" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:32 +#: ekos/align/polaralignmentassistant.cpp:33 #, kde-format msgid "First Settle" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:33 +#: ekos/align/polaralignmentassistant.cpp:34 #, kde-format msgid "Second Capture" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:34 +#: ekos/align/polaralignmentassistant.cpp:35 #, kde-format msgid "Second Solve" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:35 +#: ekos/align/polaralignmentassistant.cpp:36 #, kde-format msgid "Second Rotation" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:36 +#: ekos/align/polaralignmentassistant.cpp:37 #, kde-format msgid "Second Settle" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:37 +#: ekos/align/polaralignmentassistant.cpp:38 #, kde-format msgid "Third Capture" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:38 +#: ekos/align/polaralignmentassistant.cpp:39 #, kde-format msgid "Third Solve" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:39 +#: ekos/align/polaralignmentassistant.cpp:40 #, kde-format msgid "Select Star" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:40 +#: ekos/align/polaralignmentassistant.cpp:41 #, kde-format msgid "Refreshing" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:41 +#: ekos/align/polaralignmentassistant.cpp:42 #, kde-format msgid "Refresh Complete" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:121 +#: ekos/align/polaralignmentassistant.cpp:122 #, kde-format msgid "

    Polar Alignment tool requires a German Equatorial Mount.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:176 +#: ekos/align/polaralignmentassistant.cpp:177 #, kde-format msgid "Refresh solver timed out: %1s" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:181 +#: ekos/align/polaralignmentassistant.cpp:182 #, fuzzy, kde-format #| msgid "Solver FOV" msgid "Refresh solver failed: %1s" msgstr "Həlledicinin BaxışBucağı" -#: ekos/align/polaralignmentassistant.cpp:574 +#: ekos/align/polaralignmentassistant.cpp:569 +#, fuzzy, kde-format +#| msgid "Solver FOV" +msgid "PAA: Solver failed, retrying." +msgstr "Həlledicinin BaxışBucağı" + +#: ekos/align/polaralignmentassistant.cpp:576 #, kde-format msgid "PAA: Stopping, solver failed too many times." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:603 +#: ekos/align/polaralignmentassistant.cpp:605 #, kde-format msgid "Mount first rotation is complete." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:610 +#: ekos/align/polaralignmentassistant.cpp:612 #, kde-format msgid "Mount second rotation is complete." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:649 +#: ekos/align/polaralignmentassistant.cpp:651 #, kde-format msgid "Mount aborted. Reverse RA axis direction and try again." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:734 +#: ekos/align/polaralignmentassistant.cpp:736 #, kde-format msgid "" "Warning: Equatorial Grid Lines will not be drawn due to limited resources " "mode." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:738 +#: ekos/align/polaralignmentassistant.cpp:740 #, kde-format msgid "Clearing mount Alignment Model..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:779 +#: ekos/align/polaralignmentassistant.cpp:781 #, kde-format msgid "This could cause the telescope to cross the meridian." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:829 +#: ekos/align/polaralignmentassistant.cpp:831 #, kde-format msgid "Parking the mount..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:869 +#: ekos/align/polaralignmentassistant.cpp:871 #, kde-format msgid "Please wait until mount completes rotating to RA (%1) DE (%2)" msgstr "" -#: ekos/align/polaralignmentassistant.cpp:885 -#: ekos/align/polaralignmentassistant.cpp:891 +#: ekos/align/polaralignmentassistant.cpp:887 +#: ekos/align/polaralignmentassistant.cpp:893 #, kde-format msgid "PAA: Failed to findCorrectedPixel." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:917 +#: ekos/align/polaralignmentassistant.cpp:919 #, kde-format msgid "PAA: Failed to find RA Axis center." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:988 +#: ekos/align/polaralignmentassistant.cpp:990 #, kde-format msgid "" "Polar-alignment star cannot be updated during refresh phase as it might " "affect error measurements." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1005 +#: ekos/align/polaralignmentassistant.cpp:1007 #, kde-format msgid "First manual rotation done." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1010 +#: ekos/align/polaralignmentassistant.cpp:1012 #, kde-format msgid "Second manual rotation done." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1053 +#: ekos/align/polaralignmentassistant.cpp:1055 #, kde-format msgid "" "Mount is synced to celestial pole. You can now continue Polar Alignment " "Assistant procedure." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1072 +#: ekos/align/polaralignmentassistant.cpp:1074 #, kde-format msgid "Please wait while WCS data is processed..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1103 +#: ekos/align/polaralignmentassistant.cpp:1105 #, kde-format msgid "WCS data processing is complete." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1112 +#: ekos/align/polaralignmentassistant.cpp:1114 #, kde-format msgid "WCS info is now valid. Capturing next frame..." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1154 +#: ekos/align/polaralignmentassistant.cpp:1156 #, kde-format msgid "Failed to process World Coordinate System: %1. Try again." msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1172 +#: ekos/align/polaralignmentassistant.cpp:1174 #, kde-format msgid "PAA: Failed to find the RA axis. Quitting." msgstr "" #. i18n: ectx: property (text), widget (QLabel, PAHMessageText) -#: ekos/align/polaralignmentassistant.cpp:1203 +#: ekos/align/polaralignmentassistant.cpp:1205 #: ekos/align/polaralignmentassistant.ui:212 #, kde-format msgid "" @@ -9194,62 +9237,62 @@ "capturing the first image...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1205 +#: ekos/align/polaralignmentassistant.cpp:1207 #, kde-format msgid "

    Solving the first image...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1207 +#: ekos/align/polaralignmentassistant.cpp:1209 #, kde-format msgid "

    Executing the first mount rotation...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1209 +#: ekos/align/polaralignmentassistant.cpp:1211 #, kde-format msgid "

    Settling after the first mount rotation.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1211 +#: ekos/align/polaralignmentassistant.cpp:1213 #, kde-format msgid "

    Settling after the second mount rotation.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1213 +#: ekos/align/polaralignmentassistant.cpp:1215 #, fuzzy, kde-format #| msgid "Loading images..." msgid "

    Capturing the second image...

    " msgstr "Şəkillər yüklənir..." -#: ekos/align/polaralignmentassistant.cpp:1215 +#: ekos/align/polaralignmentassistant.cpp:1217 #, fuzzy, kde-format #| msgid "Saving of the image %1 failed." msgid "

    Solving the second image...

    " msgstr "%1 çəklinin saxlanılması baş tutmadı." -#: ekos/align/polaralignmentassistant.cpp:1217 +#: ekos/align/polaralignmentassistant.cpp:1219 #, kde-format msgid "

    Executing the second mount rotation...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1219 +#: ekos/align/polaralignmentassistant.cpp:1221 #, kde-format msgid "

    Capturing the third and final image...

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1221 +#: ekos/align/polaralignmentassistant.cpp:1223 #, fuzzy, kde-format #| msgid "Saving of the image %1 failed." msgid "

    Solving the third image...

    " msgstr "%1 çəklinin saxlanılması baş tutmadı." -#: ekos/align/polaralignmentassistant.cpp:1224 +#: ekos/align/polaralignmentassistant.cpp:1226 #, kde-format msgid "" "

    Choose your exposure time & select an adjustment method. Then click " "refresh to begin adjustments.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1226 +#: ekos/align/polaralignmentassistant.cpp:1228 #, kde-format msgid "" "

    Choose your exposure time & select an adjustment method. Click " @@ -9258,7 +9301,7 @@ "MoveStar & Calc Error method to estimate the remaining error.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1229 +#: ekos/align/polaralignmentassistant.cpp:1231 #, kde-format msgid "" "

    Adjust mount's Altitude and Azimuth knobs to reduce the polar " @@ -9267,7 +9310,7 @@ "you're finished.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1231 +#: ekos/align/polaralignmentassistant.cpp:1233 #, kde-format msgid "" "

    Adjust mount's Altitude knob to move the star along the yellow " @@ -9276,7 +9319,7 @@ "Stop when the star is centered.

    " msgstr "" -#: ekos/align/polaralignmentassistant.cpp:1247 +#: ekos/align/polaralignmentassistant.cpp:1249 #, kde-format msgid "Cannot change to MoveStar algorithm once refresh has begun" msgstr "" @@ -9482,7 +9525,7 @@ #. i18n: ectx: property (text), widget (QLabel, textLabel1_2) #. i18n: ectx: property (text), widget (QLabel, label_8) #: ekos/align/polaralignmentassistant.ui:548 -#: ekos/capture/calibrationoptions.ui:102 tools/argsetaltaz.ui:37 +#: ekos/capture/calibrationoptions.ui:87 tools/argsetaltaz.ui:37 #: tools/modcalcplanets.ui:296 #, kde-format msgid "Alt:" @@ -9534,7 +9577,7 @@ #. i18n: ectx: property (text), widget (QPushButton, startB) #: ekos/align/polaralignmentassistant.ui:806 #: ekos/align/polaralignmentassistant.ui:809 ekos/auxiliary/darklibrary.ui:575 -#: ekos/manager.cpp:140 ekos/manager.cpp:228 ekos/manager.cpp:580 +#: ekos/manager.cpp:143 ekos/manager.cpp:232 ekos/manager.cpp:584 #: ekos/observatory/observatorydomemodel.cpp:132 #: ekos/observatory/observatorydomemodel.cpp:135 #: kstarslite/qml/indi/INDIControlPanel.qml:166 @@ -9551,10 +9594,10 @@ #. i18n: ectx: property (text), widget (QPushButton, captureB) #. i18n: ectx: attribute (title), widget (QWidget, captureTab) #: ekos/align/polaralignwidget.ui:37 ekos/align/polaralignwidget.ui:157 -#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1872 +#: ekos/align/polaralignwidget.ui:277 ekos/analyze/analyze.cpp:1874 #: ekos/analyze/analyze.ui:374 ekos/auxiliary/opslogs.ui:285 #: ekos/capture/capturepreviewwidget.ui:79 ekos/guide/guide.ui:137 -#: ekos/opsekos.ui:538 +#: ekos/opsekos.ui:551 #, kde-format msgid "Capture" msgstr "" @@ -9562,9 +9605,11 @@ #. i18n: ectx: property (text), widget (QLabel, PAso1) #. i18n: ectx: property (text), widget (QLabel, PAso2) #. i18n: ectx: property (text), widget (QLabel, PAso3) +#. i18n: ectx: property (text), widget (QPushButton, SolveButton) #. i18n: ectx: property (text), widget (QPushButton, solveButton) #: ekos/align/polaralignwidget.ui:77 ekos/align/polaralignwidget.ui:197 -#: ekos/align/polaralignwidget.ui:317 options/opsimageoverlay.ui:242 +#: ekos/align/polaralignwidget.ui:317 fitsviewer/fitstab.cpp:676 +#: fitsviewer/platesolve.ui:50 options/opsimageoverlay.ui:242 #: skycomponents/imageoverlaycomponent.cpp:343 #: skycomponents/imageoverlaycomponent.cpp:703 #: skycomponents/imageoverlaycomponent.cpp:783 @@ -9583,7 +9628,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QLabel, PAsetup) -#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:324 +#: ekos/align/polaralignwidget.ui:357 ekos/manager.cpp:328 #, kde-format msgid "Setup" msgstr "" @@ -9626,50 +9671,50 @@ msgid "Failed to find solver settings." msgstr "" -#: ekos/analyze/analyze.cpp:127 ekos/analyze/analyze.cpp:146 +#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 #: ekos/observatory/observatory.cpp:356 indi/indidome.cpp:21 #: indi/indidustcap.cpp:18 indi/indimount.cpp:32 #, kde-format msgid "Parked" msgstr "" -#: ekos/analyze/analyze.cpp:129 ekos/analyze/analyze.cpp:148 +#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 #: ekos/observatory/observatory.cpp:283 ekos/observatory/observatory.cpp:299 #: indi/indidome.cpp:21 indi/indidustcap.cpp:17 indi/indimount.cpp:32 #, kde-format msgid "Parking" msgstr "" -#: ekos/analyze/analyze.cpp:131 ekos/analyze/analyze.cpp:150 ekos/ekos.h:140 -#: ekos/scheduler/schedulerjob.cpp:638 indi/indimount.cpp:31 +#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 ekos/ekos.h:140 +#: ekos/scheduler/schedulerjob.cpp:614 indi/indimount.cpp:31 #, kde-format msgid "Slewing" msgstr "" -#: ekos/analyze/analyze.cpp:133 ekos/analyze/analyze.cpp:152 +#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 #: indi/indimount.cpp:31 #, kde-format msgid "Moving" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, trackingGroup) -#: ekos/analyze/analyze.cpp:135 ekos/analyze/analyze.cpp:154 +#: ekos/analyze/analyze.cpp:137 ekos/analyze/analyze.cpp:156 #: ekos/mount/mount.ui:611 indi/indidome.cpp:21 indi/indimount.cpp:32 #, kde-format msgid "Tracking" msgstr "" -#: ekos/analyze/analyze.cpp:480 ekos/analyze/analyze.cpp:492 +#: ekos/analyze/analyze.cpp:482 ekos/analyze/analyze.cpp:494 #, kde-format msgid "Current Session" msgstr "" -#: ekos/analyze/analyze.cpp:481 +#: ekos/analyze/analyze.cpp:483 #, kde-format msgid "Read from File" msgstr "" -#: ekos/analyze/analyze.cpp:482 +#: ekos/analyze/analyze.cpp:484 #, kde-format msgid "Set alternative image-file base directory" msgstr "" @@ -9677,23 +9722,23 @@ #. i18n call below is broken up (and the word "analyze" is protected from it) because i18n #. translates "analyze" to "analyse" for the English UK locale, but we need to keep it ".analyze" #. because that's what how the files are named. -#: ekos/analyze/analyze.cpp:506 +#: ekos/analyze/analyze.cpp:508 #, kde-format msgctxt "@title:window" msgid "Select input file" msgstr "" -#: ekos/analyze/analyze.cpp:507 +#: ekos/analyze/analyze.cpp:509 #, kde-format msgid "All Files (*)" msgstr "" -#: ekos/analyze/analyze.cpp:527 +#: ekos/analyze/analyze.cpp:529 #, kde-format msgid "Set an alternate base directory for your captured images" msgstr "" -#: ekos/analyze/analyze.cpp:1169 +#: ekos/analyze/analyze.cpp:1171 #, fuzzy, kde-format #| msgid "Could not upload image to remote location: %1" msgid "Could not find image file: %1" @@ -9702,8 +9747,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FocusLogging) #. i18n: ectx: property (text), widget (QLabel, label_10) #. i18n: ectx: property (text), widget (QCheckBox, focusStepCheck) -#: ekos/analyze/analyze.cpp:1873 ekos/auxiliary/opslogs.ui:377 -#: ekos/manager.cpp:2016 ekos/manager/focusmanager.ui:101 +#: ekos/analyze/analyze.cpp:1875 ekos/auxiliary/opslogs.ui:377 +#: ekos/manager.cpp:2022 ekos/manager/focusmanager.ui:101 #: ekos/scheduler/framingassistant.ui:1490 ekos/scheduler/scheduler.ui:445 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:430 #, kde-format @@ -9711,7 +9756,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, alignStepCheck) -#: ekos/analyze/analyze.cpp:1874 ekos/manager.cpp:1990 +#: ekos/analyze/analyze.cpp:1876 ekos/manager.cpp:1996 #: ekos/scheduler/framingassistant.ui:1262 ekos/scheduler/scheduler.ui:398 #: fitsviewer/fitscommon.h:16 fitsviewer/fitsviewer.cpp:438 #, kde-format @@ -9722,16 +9767,16 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_GuideLogging) #. i18n: ectx: property (text), widget (QPushButton, guideB) #. i18n: ectx: property (text), widget (QCheckBox, guideStepCheck) -#: ekos/analyze/analyze.cpp:1875 ekos/analyze/analyze.ui:338 -#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:55 -#: ekos/guide/guide.ui:263 ekos/manager.cpp:2170 +#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:338 +#: ekos/auxiliary/opslogs.ui:120 ekos/guide/guide.cpp:58 +#: ekos/guide/guide.ui:263 ekos/manager.cpp:2176 #: ekos/scheduler/framingassistant.ui:1226 ekos/scheduler/scheduler.ui:420 #: fitsviewer/fitscommon.h:15 fitsviewer/fitsviewer.cpp:434 #, kde-format msgid "Guide" msgstr "" -#: ekos/analyze/analyze.cpp:1876 +#: ekos/analyze/analyze.cpp:1878 #, kde-format msgid "Flip" msgstr "" @@ -9740,20 +9785,20 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDIMountLogging) #. i18n: ectx: property (text), widget (QCheckBox, kcfg_MountLogging) #. i18n: ectx: property (text), widget (QLabel, mountLabel) -#: ekos/analyze/analyze.cpp:1877 ekos/analyze/analyze.ui:356 +#: ekos/analyze/analyze.cpp:1879 ekos/analyze/analyze.ui:356 #: ekos/auxiliary/opslogs.ui:77 ekos/auxiliary/opslogs.ui:420 -#: ekos/manager.cpp:2099 ekos/manager.ui:665 +#: ekos/manager.cpp:2105 ekos/manager.ui:665 #, kde-format msgid "Mount" msgstr "" #. i18n: ectx: property (text), widget (QLabel, jobLabel) -#: ekos/analyze/analyze.cpp:1878 ekos/capture/capturecountswidget.ui:473 +#: ekos/analyze/analyze.cpp:1880 ekos/capture/capturecountswidget.ui:473 #, kde-format msgid "Job" msgstr "" -#: ekos/analyze/analyze.cpp:2136 +#: ekos/analyze/analyze.cpp:2138 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9761,7 +9806,7 @@ "will have their HFRs computed." msgstr "" -#: ekos/analyze/analyze.cpp:2152 +#: ekos/analyze/analyze.cpp:2154 #, kde-format msgid "" "The \"Auto Compute HFR\" option in the KStars FITS options menu is not set. " @@ -9769,105 +9814,105 @@ "newly captured images will have their stars detected." msgstr "" -#: ekos/analyze/analyze.cpp:2853 ekos/auxiliary/ledstatuswidget.cpp:78 -#: ekos/capture/sequencejob.cpp:21 ekos/ekos.h:21 ekos/ekos.h:72 +#: ekos/analyze/analyze.cpp:2855 ekos/auxiliary/ledstatuswidget.cpp:78 +#: ekos/capture/sequencejob.cpp:23 ekos/ekos.h:21 ekos/ekos.h:72 #: ekos/ekos.h:119 ekos/ekos.h:139 ekos/ekos.h:188 -#: ekos/scheduler/schedulerjob.cpp:619 +#: ekos/scheduler/schedulerjob.cpp:595 #, kde-format msgid "Aborted" msgstr "" -#: ekos/analyze/analyze.cpp:2855 ekos/ekos.h:22 +#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:22 #, kde-format msgid "Connected" msgstr "" -#: ekos/analyze/analyze.cpp:2857 ekos/ekos.h:23 +#: ekos/analyze/analyze.cpp:2859 ekos/ekos.h:23 #, kde-format msgid "Disconnected" msgstr "" -#: ekos/analyze/analyze.cpp:2859 ekos/auxiliary/ledstatuswidget.cpp:68 -#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:651 +#: ekos/analyze/analyze.cpp:2861 ekos/auxiliary/ledstatuswidget.cpp:68 +#: ekos/ekos.h:24 ekos/ekos.h:71 ekos/scheduler/schedulerjob.cpp:627 #, kde-format msgid "Capturing" msgstr "" -#: ekos/analyze/analyze.cpp:2861 ekos/ekos.h:25 +#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:25 #, kde-format msgid "Looping" msgstr "" -#: ekos/analyze/analyze.cpp:2863 ekos/ekos.h:26 +#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:26 #, kde-format msgid "Subtracting" msgstr "" -#: ekos/analyze/analyze.cpp:2865 ekos/ekos.h:27 +#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:27 #, kde-format msgid "Subframing" msgstr "" -#: ekos/analyze/analyze.cpp:2867 ekos/ekos.h:28 +#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:28 #, kde-format msgid "Selecting star" msgstr "" -#: ekos/analyze/analyze.cpp:2869 ekos/ekos.h:29 ekos/ekos.h:74 +#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:29 ekos/ekos.h:74 #, kde-format msgid "Calibrating" msgstr "" -#: ekos/analyze/analyze.cpp:2871 ekos/ekos.h:30 +#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:30 #, kde-format msgid "Calibration error" msgstr "" -#: ekos/analyze/analyze.cpp:2873 ekos/ekos.h:31 +#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:31 #, kde-format msgid "Calibrated" msgstr "" #. i18n("Calibrating"); -#: ekos/analyze/analyze.cpp:2875 ekos/ekos.h:32 -#: ekos/scheduler/schedulerjob.cpp:649 +#: ekos/analyze/analyze.cpp:2877 ekos/ekos.h:32 +#: ekos/scheduler/schedulerjob.cpp:625 #, kde-format msgid "Guiding" msgstr "" -#: ekos/analyze/analyze.cpp:2877 ekos/auxiliary/ledstatuswidget.cpp:33 +#: ekos/analyze/analyze.cpp:2879 ekos/auxiliary/ledstatuswidget.cpp:33 #: ekos/ekos.h:33 ekos/ekos.h:72 ekos/ekos.h:141 #, kde-format msgid "Suspended" msgstr "" -#: ekos/analyze/analyze.cpp:2879 ekos/ekos.h:34 +#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:34 #, kde-format msgid "Reacquiring" msgstr "" -#: ekos/analyze/analyze.cpp:2881 ekos/ekos.h:35 ekos/ekos.h:73 +#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:35 ekos/ekos.h:73 #, kde-format msgid "Dithering" msgstr "" #. i18n: ectx: property (windowTitle), widget (QDialog, ManualDither) -#: ekos/analyze/analyze.cpp:2883 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 +#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:36 ekos/guide/manualdither.ui:14 #, kde-format msgid "Manual Dithering" msgstr "" -#: ekos/analyze/analyze.cpp:2885 ekos/ekos.h:37 +#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:37 #, kde-format msgid "Dithering error" msgstr "" -#: ekos/analyze/analyze.cpp:2887 ekos/ekos.h:38 +#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:38 #, kde-format msgid "Dithering successful" msgstr "" -#: ekos/analyze/analyze.cpp:2889 ekos/ekos.h:39 +#: ekos/analyze/analyze.cpp:2891 ekos/ekos.h:39 #, kde-format msgid "Settling" msgstr "" @@ -9931,7 +9976,7 @@ #. i18n: ectx: property (text), widget (QLabel, statsLabel) #. i18n: ectx: property (windowTitle), widget (QDialog, solveInfo) #. i18n: ectx: property (windowTitle), widget (QDialog, statForm) -#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:123 +#: ekos/analyze/analyze.ui:176 fitsviewer/fitstab.cpp:129 #: fitsviewer/fitsviewer.cpp:173 fitsviewer/solveInfo.ui:14 #: fitsviewer/statform.ui:14 #, kde-format @@ -11065,8 +11110,8 @@ #. i18n: ectx: property (text), widget (QLabel, label_5) #. i18n: ectx: property (text), widget (QLabel, label_21) #. i18n: ectx: property (text), widget (QLabel, label_34) -#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1607 -#: ekos/focus/focus.ui:3100 +#: ekos/auxiliary/darklibrary.ui:346 ekos/focus/focus.ui:1626 +#: ekos/focus/focus.ui:3119 #, kde-format msgid "Algorithm:" msgstr "" @@ -11246,7 +11291,7 @@ #. i18n: ectx: property (text), widget (QPushButton, resetFrameB) #. i18n: ectx: property (text), widget (QPushButton, resetB) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:779 +#: ekos/auxiliary/darklibrary.ui:982 ekos/focus/focus.ui:798 #: ekos/guide/manualpulse.ui:140 ekos/mount/mount.ui:346 #, kde-format msgid "Reset" @@ -11294,7 +11339,7 @@ #. i18n: ectx: property (toolTip), widget (QLabel, label_7) #. i18n: ectx: label, entry (MaxDarkTemperatureDiff), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1628 +#: ekos/auxiliary/darklibrary.ui:1102 kstars.kcfg:1652 #, kde-format msgid "" "Maximum acceptable difference between current and recorded dark frame " @@ -11322,14 +11367,14 @@ #. i18n: ectx: property (text), widget (QLabel, label_8) #. i18n: ectx: property (text), widget (QLabel, label_3) -#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:592 +#: ekos/auxiliary/darklibrary.ui:1122 ekos/opsekos.ui:605 #, kde-format msgid "° C" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label_6) #. i18n: ectx: label, entry (DarkLibraryDuration), group (DarkLibrary) -#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1638 +#: ekos/auxiliary/darklibrary.ui:1129 kstars.kcfg:1662 #, kde-format msgid "" "Reuse dark frames from the dark library for this many days. If exceeded, a " @@ -11379,7 +11424,7 @@ msgstr "" #: ekos/auxiliary/filtermanager.cpp:112 -#: ekos/capture/capturecountswidget.cpp:154 +#: ekos/capture/capturecountswidget.cpp:156 #, kde-format msgid "Exposure" msgstr "" @@ -11395,7 +11440,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QPushButton, startFocusB) -#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:285 +#: ekos/auxiliary/filtermanager.cpp:119 ekos/ekos.h:162 ekos/focus/focus.ui:286 #, kde-format msgid "Auto Focus" msgstr "" @@ -11488,7 +11533,7 @@ #. i18n: ectx: property (windowTitle), widget (QDialog, FilterSettings) #. i18n: ectx: property (toolTip), widget (QPushButton, filterManagerB) #: ekos/auxiliary/filtersettings.ui:20 ekos/capture/capture.ui:440 -#: ekos/focus/focus.ui:847 +#: ekos/focus/focus.ui:866 #, kde-format msgid "Filter Settings" msgstr "" @@ -11556,7 +11601,7 @@ msgstr "" #: ekos/auxiliary/ledstatuswidget.cpp:46 -#: ekos/capture/capturemodulestate.cpp:336 +#: ekos/capture/capturemodulestate.cpp:330 #, kde-format msgid "Dithering..." msgstr "" @@ -11577,7 +11622,7 @@ msgid "Aligning..." msgstr "" -#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1395 +#: ekos/auxiliary/ledstatuswidget.cpp:61 ekos/capture/capture.cpp:1426 #, kde-format msgid "Calibrating..." msgstr "" @@ -11654,8 +11699,8 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_SchedulerLogging) #. i18n: ectx: attribute (title), widget (QWidget, schedulerTab) -#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:329 ekos/opsekos.ui:184 -#: ekos/scheduler/framingassistantui.cpp:665 +#: ekos/auxiliary/opslogs.ui:90 ekos/manager.cpp:333 ekos/opsekos.ui:184 +#: ekos/scheduler/framingassistantui.cpp:667 #, kde-format msgid "Scheduler" msgstr "" @@ -11692,7 +11737,7 @@ #: ekos/auxiliary/opslogs.ui:133 ekos/capture/capturecountswidget.ui:41 #: ekos/capture/capturepreviewwidget.ui:38 ekos/manager.ui:38 #: ekos/manager/focusmanager.ui:41 ekos/manager/guidemanager.ui:41 -#: kstarsactions.cpp:1141 kstarsinit.cpp:454 +#: kstarsactions.cpp:1150 kstarsinit.cpp:454 #, kde-format msgid "Ekos" msgstr "" @@ -11734,7 +11779,7 @@ msgstr "" #. i18n: ectx: property (text), widget (QCheckBox, kcfg_INDILogging) -#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1137 +#: ekos/auxiliary/opslogs.ui:189 kstarsactions.cpp:1146 #, kde-format msgid "INDI" msgstr "" @@ -11748,7 +11793,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_FITSLogging) #. i18n: ectx: property (text), item, widget (QComboBox, captureEncodingS) #: ekos/auxiliary/opslogs.ui:202 ekos/capture/capture.ui:194 -#: kstarsactions.cpp:1131 +#: kstarsactions.cpp:1140 #, kde-format msgid "FITS" msgstr "" @@ -11830,7 +11875,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_AlignmentLogging) #. i18n: ectx: property (title), widget (QGroupBox, groupBox_6) -#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:415 +#: ekos/auxiliary/opslogs.ui:315 ekos/opsekos.ui:428 #, kde-format msgid "Alignment" msgstr "" @@ -11844,7 +11889,7 @@ #. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObservatoryLogging) #. i18n: ectx: property (windowTitle), widget (QWidget, Observatory) -#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2210 +#: ekos/auxiliary/opslogs.ui:328 ekos/manager.cpp:2216 #: ekos/observatory/observatory.ui:14 #, kde-format msgid "Observatory" @@ -12083,16 +12128,24 @@ #: ekos/auxiliary/opticaltrains.ui:149 #, kde-format msgid "" -"

    Select the scope or lens used in the optical train.

    To add, edit, or delete optical elements, tap the Telescope & Lens button.

    " +"

    Select the scope or lens used in the optical train. " +"This is a required selection in all trains.

    To add, edit, or delete " +"optical elements, tap the Telescope & " +"Lens button.

    " msgstr "" #. i18n: ectx: property (text), widget (QLabel, scopeLabel) #: ekos/auxiliary/opticaltrains.ui:152 -#, kde-format -msgid "Scope/Lense:" +#, fuzzy, kde-format +#| msgid "" +#| "

    Latitude in degrees. North of equator is positive " +#| "and South is negative.

    " +msgid "" +"

    Scope/Lens: *" msgstr "" +"

    En dairəsi dərəcələr ilə. Ekvatordan Şimala müsbətdir, " +"Cənuba mənfidir.

    " #. i18n: ectx: property (toolTip), widget (QLabel, mountLabel) #: ekos/auxiliary/opticaltrains.ui:162 @@ -12116,19 +12169,24 @@ #| "

    Latitude in degrees. North of equator is positive " #| "and South is negative.

    " msgid "" -"

    Select the imaging camera for this optical train.

    " +"

    Select the imaging camera for this optical train. " +"This is a required selection in all trains.

    " msgstr "" "

    En dairəsi dərəcələr ilə. Ekvatordan Şimala müsbətdir, " "Cənuba mənfidir.

    " #. i18n: ectx: property (text), widget (QLabel, cameraLabel) -#. i18n: ectx: property (text), widget (QLabel, label_8) -#: ekos/auxiliary/opticaltrains.ui:188 ekos/capture/capture.ui:1478 -#: ekos/scheduler/framingassistant.ui:139 -#, kde-format -msgid "Camera:" +#: ekos/auxiliary/opticaltrains.ui:188 +#, fuzzy, kde-format +#| msgid "" +#| "

    Latitude in degrees. North of equator is positive " +#| "and South is negative.

    " +msgid "" +"

    Camera: *

    " msgstr "" +"

    En dairəsi dərəcələr ilə. Ekvatordan Şimala müsbətdir, " +"Cənuba mənfidir.

    " #. i18n: ectx: property (toolTip), widget (QLabel, dustCapLlabel) #: ekos/auxiliary/opticaltrains.ui:208 @@ -12224,7 +12282,7 @@ #. i18n: ectx: property (text), widget (QLabel, focusLabel) #. i18n: ectx: property (text), widget (QLabel, label_33) #. i18n: ectx: property (text), widget (QLabel, label_10) -#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:298 +#: ekos/auxiliary/opticaltrains.ui:326 ekos/focus/focus.ui:434 #: ekos/profileeditor.ui:651 #, kde-format msgid "Focuser:" @@ -12811,7 +12869,7 @@ #. i18n: ectx: property (text), item, widget (QComboBox, convFilter) #. i18n: ectx: property (text), item, widget (QComboBox, focusStarPSF) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1871 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:451 ekos/focus/focus.ui:1890 #, kde-format msgid "Gaussian" msgstr "" @@ -13030,7 +13088,7 @@ #. i18n: ectx: property (text), widget (QLabel, label_9) #: ekos/auxiliary/stellarsolverprofileeditor.ui:726 #: ekos/auxiliary/stellarsolverprofileeditor.ui:798 -#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:874 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:819 ekos/opsekos.ui:887 #, no-c-format, kde-format msgid "%" msgstr "" @@ -13175,10 +13233,13 @@ msgstr "" #. i18n: ectx: property (text), item, widget (QComboBox, multiAlgo) +#. i18n: ectx: property (currentText), widget (QComboBox, abInsSelection) +#. i18n: ectx: property (text), item, widget (QComboBox, abInsSelection) #. i18n: ectx: property (text), widget (QPushButton, NoneButton) -#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 indi/drivermanager.cpp:1312 -#: indi/indidriver.cpp:735 kstarsactions.cpp:1817 kstarsinit.cpp:788 -#: kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 +#: ekos/auxiliary/stellarsolverprofileeditor.ui:946 +#: ekos/focus/aberrationinspector.ui:336 ekos/focus/aberrationinspector.ui:340 +#: indi/drivermanager.cpp:1329 indi/indidriver.cpp:735 kstarsactions.cpp:1826 +#: kstarsinit.cpp:788 kstarsinit.cpp:789 tools/exporteyepieceview.cpp:57 #: tools/eyepiecefield.cpp:102 tools/obslistwizard.ui:183 #, kde-format, kde-kuit-format msgid "None" @@ -13328,100 +13389,77 @@ msgstr "" #. i18n: ectx: property (toolTip), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:22 -#, kde-format -msgid "Specify the source the flat field evenly illuminated light source" -msgstr "" - -#. i18n: ectx: property (title), widget (QGroupBox, groupBox) -#: ekos/capture/calibrationoptions.ui:25 -#, kde-format -msgid "Flat Source" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, manualSourceC) -#: ekos/capture/calibrationoptions.ui:31 -#, kde-format -msgid "Light source triggered by the user manually" -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, manualSourceC) -#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:34 ekos/capture/calibrationoptions.ui:161 -#, kde-format -msgid "Manual" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:47 -#, kde-format +#: ekos/capture/calibrationoptions.ui:37 +#, fuzzy, kde-format +#| msgid "" +#| "

    Latitude in degrees. North of equator is positive " +#| "and South is negative.

    " msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, close the dust cap and turn on the light source." -msgstr "" - -#. i18n: ectx: property (text), widget (QRadioButton, flatDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:50 -#, kde-format -msgid "Dust Cover with Built-in Flat Light" +"

    Select which actions to perform before a Bias/Dark/" +"Flat frame is captured.

    " msgstr "" +"

    En dairəsi dərəcələr ilə. Ekvatordan Şimala müsbətdir, " +"Cənuba mənfidir.

    " -#. i18n: ectx: property (toolTip), widget (QRadioButton, darkDeviceSourceC) -#: ekos/capture/calibrationoptions.ui:60 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: ekos/capture/calibrationoptions.ui:40 #, kde-format -msgid "" -"For dark and bias frames, close the dust cap before proceeding. For flat " -"frames, open the dust cap and turn on the light source." +msgid "Calibration Pre-Actions" msgstr "" -#. i18n: ectx: property (text), widget (QRadioButton, darkDeviceSourceC) +#. i18n: ectx: property (toolTip), widget (QCheckBox, gotoWallC) #: ekos/capture/calibrationoptions.ui:63 #, kde-format -msgid "Dust Cover with External Flat Light" -msgstr "" - -#. i18n: ectx: property (toolTip), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:75 -#, kde-format msgid "" "Slew mount to the specified Azimuth/Altitude coordinates before taking flat " "field images" msgstr "" -#. i18n: ectx: property (text), widget (QRadioButton, wallSourceC) -#: ekos/capture/calibrationoptions.ui:78 +#. i18n: ectx: property (text), widget (QCheckBox, gotoWallC) +#: ekos/capture/calibrationoptions.ui:66 #, kde-format -msgid "Wall" +msgid "Goto Wall" msgstr "" -#. i18n: ectx: property (toolTip), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:121 +#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) +#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) +#: ekos/capture/calibrationoptions.ui:103 ekos/scheduler/scheduler.ui:1837 #, kde-format -msgid "Use Dawn and Dusk light" +msgid "Park Mount" msgstr "" -#. i18n: ectx: property (text), widget (QRadioButton, dawnDuskFlatsC) -#: ekos/capture/calibrationoptions.ui:124 +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) +#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) +#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) +#: ekos/capture/calibrationoptions.ui:110 ekos/observatory/observatory.ui:944 +#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 #, kde-format -msgid "Dawn/Dusk" +msgid "Park Dome" msgstr "" #. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) -#: ekos/capture/calibrationoptions.ui:150 +#: ekos/capture/calibrationoptions.ui:133 #, kde-format msgid "Flat Duration" msgstr "" #. i18n: ectx: property (toolTip), widget (QRadioButton, manualDurationC) -#: ekos/capture/calibrationoptions.ui:158 +#: ekos/capture/calibrationoptions.ui:156 #, kde-format msgid "Use the frame exposure value" msgstr "" +#. i18n: ectx: property (text), widget (QRadioButton, manualDurationC) +#: ekos/capture/calibrationoptions.ui:159 +#, kde-format +msgid "Manual" +msgstr "" + #. i18n: ectx: property (toolTip), widget (QRadioButton, ADUC) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUValue) -#: ekos/capture/calibrationoptions.ui:174 -#: ekos/capture/calibrationoptions.ui:187 +#: ekos/capture/calibrationoptions.ui:172 +#: ekos/capture/calibrationoptions.ui:185 #, kde-format msgid "" "Calculate optimal exposure time given the required ADU. If a controllable " @@ -13429,15 +13467,15 @@ msgstr "" #. i18n: ectx: property (text), widget (QRadioButton, ADUC) -#: ekos/capture/calibrationoptions.ui:177 +#: ekos/capture/calibrationoptions.ui:175 #, kde-format msgid "ADU" msgstr "" #. i18n: ectx: property (toolTip), widget (QLabel, label_3) #. i18n: ectx: property (toolTip), widget (QSpinBox, ADUTolerance) -#: ekos/capture/calibrationoptions.ui:200 -#: ekos/capture/calibrationoptions.ui:210 +#: ekos/capture/calibrationoptions.ui:198 +#: ekos/capture/calibrationoptions.ui:208 #, kde-format msgid "" "

    Accept ADU values that fall within this range around " @@ -13449,330 +13487,287 @@ #. i18n: ectx: property (text), widget (QLabel, label_3) #. i18n: ectx: property (text), widget (QLabel, focusToleranceLabel) #. i18n: ectx: property (text), widget (QLabel, focusCFZToleranceLabel) -#: ekos/capture/calibrationoptions.ui:203 ekos/focus/focus.ui:2068 -#: ekos/focus/focus.ui:2674 +#: ekos/capture/calibrationoptions.ui:201 ekos/focus/focus.ui:2087 +#: ekos/focus/focus.ui:2693 #, kde-format msgid "Tolerance:" msgstr "" -#. i18n: ectx: property (text), widget (QCheckBox, parkMountC) -#. i18n: ectx: property (text), widget (QCheckBox, parkMountCheck) -#: ekos/capture/calibrationoptions.ui:246 ekos/scheduler/scheduler.ui:1837 -#, kde-format -msgid "Park Mount" -msgstr "" - -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeC) -#. i18n: ectx: property (text), widget (QCheckBox, weatherAlertDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, weatherWarningDomeCB) -#. i18n: ectx: property (text), widget (QCheckBox, parkDomeCheck) -#: ekos/capture/calibrationoptions.ui:253 ekos/observatory/observatory.ui:944 -#: ekos/observatory/observatory.ui:1079 ekos/scheduler/scheduler.ui:1859 -#, kde-format -msgid "Park Dome" -msgstr "" - -#: ekos/capture/capture.cpp:248 ekos/capture/capture.cpp:2935 +#: ekos/capture/capture.cpp:262 ekos/capture/capture.cpp:2311 #, kde-format msgid "Add job to sequence queue" msgstr "" -#: ekos/capture/capture.cpp:249 ekos/capture/capture.cpp:2936 +#: ekos/capture/capture.cpp:263 ekos/capture/capture.cpp:2312 #, kde-format msgid "Remove job from sequence queue" msgstr "" -#: ekos/capture/capture.cpp:500 +#: ekos/capture/capture.cpp:510 #, kde-format msgid "Downloading..." msgstr "" -#: ekos/capture/capture.cpp:675 +#: ekos/capture/capture.cpp:689 #, kde-format msgid "" "Warning: in-sequence focusing is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:677 +#: ekos/capture/capture.cpp:691 #, kde-format msgid "" "Warning: temperature delta check is selected but autofocus process was not " "started." msgstr "" -#: ekos/capture/capture.cpp:1336 +#: ekos/capture/capture.cpp:1367 #, kde-format msgid "Framing..." msgstr "" -#: ekos/capture/capture.cpp:1347 +#: ekos/capture/capture.cpp:1378 #, kde-format msgid "Captured image received" msgstr "" #. i18n: ectx: property (text), widget (QLabel, frameInfoLabel) -#: ekos/capture/capture.cpp:1365 ekos/capture/capture.ui:2245 +#: ekos/capture/capture.cpp:1396 ekos/capture/capture.ui:2245 #, kde-format msgid "Expose (-/-):" msgstr "" -#: ekos/capture/capture.cpp:1429 +#: ekos/capture/capture.cpp:1460 #, kde-format msgid "Capturing %1-second %2 image..." msgstr "" -#: ekos/capture/capture.cpp:1512 -#, kde-format -msgid "You must set remote directory for Local & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1518 -#, kde-format -msgid "You must set local directory for Client & Both modes." -msgstr "" - -#: ekos/capture/capture.cpp:1653 ekos/capture/capture.cpp:1656 -#, kde-format -msgid "Dark Flat" -msgstr "" - -#: ekos/capture/capture.cpp:1737 +#: ekos/capture/capture.cpp:1638 #, kde-format msgid "Job #%1 changes applied." msgstr "" -#: ekos/capture/capture.cpp:1941 +#: ekos/capture/capture.cpp:1814 #, kde-format msgid "Setting temperature to %1 °C..." msgstr "" -#: ekos/capture/capture.cpp:1942 +#: ekos/capture/capture.cpp:1815 #, kde-format msgid "Set Temp to %1 °C..." msgstr "" -#: ekos/capture/capture.cpp:1946 +#: ekos/capture/capture.cpp:1819 #, kde-format msgid "Waiting for guide drift below %1\"..." msgstr "" -#: ekos/capture/capture.cpp:1948 +#: ekos/capture/capture.cpp:1821 #, kde-format msgid "Wait for Guider < %1\"..." msgstr "" -#: ekos/capture/capture.cpp:1953 +#: ekos/capture/capture.cpp:1826 #, kde-format msgid "Setting camera to %1 degrees E of N..." msgstr "" -#: ekos/capture/capture.cpp:1954 +#: ekos/capture/capture.cpp:1827 #, kde-format msgid "Set Camera to %1 deg..." msgstr "" -#: ekos/capture/capture.cpp:1997 ekos/capture/capture.cpp:1998 +#: ekos/capture/capture.cpp:1870 ekos/capture/capture.cpp:1871 #, kde-format msgid "Focus complete." msgstr "" -#: ekos/capture/capture.cpp:2002 +#: ekos/capture/capture.cpp:1875 #, kde-format msgid "Autofocus failed." msgstr "" -#: ekos/capture/capture.cpp:2024 +#: ekos/capture/capture.cpp:1897 #, kde-format msgid "Paused..." msgstr "" -#: ekos/capture/capture.cpp:2029 +#: ekos/capture/capture.cpp:1902 #, kde-format msgid "Meridian Flip..." msgstr "" -#: ekos/capture/capture.cpp:2030 +#: ekos/capture/capture.cpp:1903 #, kde-format msgid "Meridian flip started" msgstr "" -#: ekos/capture/capture.cpp:2034 +#: ekos/capture/capture.cpp:1907 #, kde-format msgid "Flip complete." msgstr "" -#: ekos/capture/capture.cpp:2059 ekos/scheduler/framingassistant.cpp:221 +#: ekos/capture/capture.cpp:1932 ekos/scheduler/framingassistant.cpp:221 #, kde-format msgctxt "@title:window" msgid "FITS Save Directory" msgstr "" -#: ekos/capture/capture.cpp:2069 +#: ekos/capture/capture.cpp:1942 #, kde-format msgctxt "@title:window" msgid "Open Ekos Sequence Queue" msgstr "" -#: ekos/capture/capture.cpp:2180 -#, kde-format -msgid "" -"Meridian flip configuration has been shifted to the mount module. Please " -"configure the meridian flip there." -msgstr "" - -#: ekos/capture/capture.cpp:2269 -#, kde-format -msgid "Warning: Filter %1 not found in filter wheel." -msgstr "" - -#: ekos/capture/capture.cpp:2478 +#: ekos/capture/capture.cpp:2007 #, kde-format msgctxt "@title:window" msgid "Save Ekos Sequence Queue" msgstr "" -#: ekos/capture/capture.cpp:2499 +#: ekos/capture/capture.cpp:2028 #, kde-format msgid "Failed to save sequence queue" msgstr "" -#: ekos/capture/capture.cpp:2531 -#, kde-format -msgid "Could not open file" -msgstr "" - -#: ekos/capture/capture.cpp:2551 -#, kde-format -msgid "" -"Warning: HFR-based autofocus is set but option \"Save Sequence HFR Value to " -"File\" is not enabled. Current HFR value will not be written to sequence " -"file." -msgstr "" - -#: ekos/capture/capture.cpp:2686 -#, kde-format -msgid "Sequence queue saved to %1" -msgstr "" - -#: ekos/capture/capture.cpp:2713 +#: ekos/capture/capture.cpp:2071 #, kde-format msgid "Are you sure you want to reset status of all jobs?" msgstr "" -#: ekos/capture/capture.cpp:2713 ekos/capture/captureprocess.cpp:2339 +#: ekos/capture/capture.cpp:2071 ekos/capture/captureprocess.cpp:2638 #, kde-format msgid "Reset job status" msgstr "" -#: ekos/capture/capture.cpp:2914 +#: ekos/capture/capture.cpp:2290 #, kde-format msgid "Editing job #%1..." msgstr "" -#: ekos/capture/capture.cpp:2917 ekos/scheduler/scheduler.cpp:1619 +#: ekos/capture/capture.cpp:2293 ekos/scheduler/scheduler.cpp:1414 #, kde-format msgid "Apply job changes." msgstr "" -#: ekos/capture/capture.cpp:2918 +#: ekos/capture/capture.cpp:2294 #, kde-format msgid "Cancel job changes." msgstr "" -#: ekos/capture/capture.cpp:2930 +#: ekos/capture/capture.cpp:2306 #, kde-format msgid "Editing job canceled." msgstr "" -#: ekos/capture/capture.cpp:3083 +#: ekos/capture/capture.cpp:2445 #, kde-format msgid "Wall coordinates are invalid." msgstr "" -#: ekos/capture/capture.cpp:3172 +#: ekos/capture/capture.cpp:2529 #, kde-format msgctxt "@title:window" msgid "Select Current Observer" msgstr "" -#: ekos/capture/capture.cpp:3174 +#: ekos/capture/capture.cpp:2531 #, kde-format msgid "Current Observer:" msgstr "" #. i18n: ectx: property (windowTitle), widget (QWidget, ObserverAdd) -#: ekos/capture/capture.cpp:3185 oal/execute.cpp:38 oal/observeradd.ui:26 +#: ekos/capture/capture.cpp:2542 oal/execute.cpp:38 oal/observeradd.ui:26 #, kde-format msgid "Manage Observers" msgstr "" -#: ekos/capture/capture.cpp:3250 +#: ekos/capture/capture.cpp:2607 #, kde-format msgid "Filter set to %1." msgstr "" -#: ekos/capture/capture.cpp:3572 +#: ekos/capture/capture.cpp:2929 #, kde-format msgid "Reset %1 configuration to default?" msgstr "" -#: ekos/capture/capture.cpp:3574 +#: ekos/capture/capture.cpp:2931 #, kde-format msgid "Confirmation" msgstr "" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:2969 ekos/capture/capture.cpp:3044 +#, kde-format +msgid "Dark Flat" +msgstr "" + +#: ekos/capture/capture.cpp:3021 +#, kde-format +msgid "You must set remote directory for Local & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3027 +#, kde-format +msgid "You must set local directory for Client & Both modes." +msgstr "" + +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is on" msgstr "" -#: ekos/capture/capture.cpp:3625 +#: ekos/capture/capture.cpp:3065 #, kde-format msgid "Cooler is off" msgstr "" -#: ekos/capture/capture.cpp:3809 +#: ekos/capture/capture.cpp:3172 #, kde-format -msgctxt "Temperature ramp celcius per minute" -msgid "Ramp (C/min):" +msgctxt "Maximum temperature variation over time when regulating." +msgid "Ramp (°C/min):" msgstr "" -#: ekos/capture/capture.cpp:3815 +#: ekos/capture/capture.cpp:3178 #, kde-format msgid "" -"Maximum temperature change per minute when cooling or warming the camera. " -"Set zero to disable." +"

    Maximum temperature change per minute when cooling or warming " +"the camera. Set zero to disable.

    This setting is read from and stored in " +"the INDI camera driver configuration." msgstr "" -#. i18n: ectx: property (text), widget (QLabel, focusThresholdLabel) -#: ekos/capture/capture.cpp:3817 ekos/focus/focus.ui:1895 +#: ekos/capture/capture.cpp:3183 #, kde-format -msgid "Threshold:" +msgctxt "Temperature threshold above which regulation triggers." +msgid "Threshold (°C):" msgstr "" -#: ekos/capture/capture.cpp:3823 +#: ekos/capture/capture.cpp:3189 #, kde-format -msgid "Maximum difference between camera and target temperatures" +msgid "" +"

    Maximum difference between camera and target temperatures " +"triggering regulation.

    This setting is read from and stored in the INDI " +"camera driver configuration." msgstr "" -#: ekos/capture/capture.cpp:3833 +#: ekos/capture/capture.cpp:3202 #, kde-format msgctxt "@title:window" msgid "Set Temperature Regulation" msgstr "" -#: ekos/capture/capture.cpp:3851 +#: ekos/capture/capture.cpp:3220 #, kde-format msgid "Stop Sequence" msgstr "" -#: ekos/capture/capture.cpp:3857 +#: ekos/capture/capture.cpp:3226 #, kde-format msgid "Resume Sequence" msgstr "" -#: ekos/capture/capture.cpp:3882 +#: ekos/capture/capture.cpp:3251 #, kde-format msgid "One dark flats job was created." msgid_plural "%1 dark flats jobs were created." @@ -13781,7 +13776,7 @@ #. i18n: ectx: property (title), widget (QGroupBox, CCDFWGroup) #. i18n: ectx: property (title), widget (QGroupBox, ccdGroup) -#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:472 +#: ekos/capture/capture.ui:110 ekos/focus/focus.ui:491 #, kde-format msgid "Camera && Filter Wheel" msgstr "" @@ -14109,44 +14104,61 @@ "\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-" "block-indent:0; text-indent:0px;\">Placeholder %e or %exposure: The " -"exposure duration in seconds.

  • Placeholder %F or " -"%Filter: The active filter name.
    • Placeholder %E or %exp: The exposure duration in seconds as plain " +"number, without any unit as suffix.
  • Placeholder %F " +"or %Filter: The active filter name." +"
  • Placeholder %t or %target: The Target name.
  • Placeholder %C or %temperature: The camera temperature of capturing." -"
    • Placeholder %B or " +"%bin: The binning configured for " +"capturing.
    • Placeholder %G or %gain: The gain configured for capturing.
    • Placeholder %G or %gain: The gain configured for capturing.
    • %O or %offset: The offset configured for capturing.
      • Placeholder %I or %iso: The ISO value (DSLRs only).
    • Placeholder %O " -"or %offset: The offset configured " -"for capturing.
    • Placeholder %P " +"or %pierside: The current mount's " +"pier side.
    • Placeholder %P or %pierside: The current mount's pier side.
    • Placeholder %s* or " -"%sequence: The image sequence identifier where * is the number of " -"digits used (1-9). This tag is mandatory " -"and must be the last element in the format.

    Arbitrary " -"text may also be included within the Format string, except the % and \\ characters. The / path character " -"can be used to define arbitrary directories.

    Notes:

    • Tags are " -"case sensitive in both their short and long forms.
    • Only use the %Datetime tag in the filename " -"portion of the format, not in the path definition.
    " +"\">Placeholder %s* or %sequence: The image sequence identifier where " +"* is the number of digits used (1-9). This " +"tag is mandatory and must be the last element in the format.
  • Arbitrary text may also be included within the Format string, except the % and \\ characters. The / " +"path character can be used to define arbitrary directories.

    Notes: