Index: kstars/ekos/capture/capture.h =================================================================== --- kstars/ekos/capture/capture.h +++ kstars/ekos/capture/capture.h @@ -712,7 +712,7 @@ void processCaptureTimeout(); // selection of a job - void selectedJobCanged(QModelIndex current, QModelIndex previous); + void selectedJobChanged(QModelIndex current, QModelIndex previous); /* Capture */ Index: kstars/ekos/capture/capture.cpp =================================================================== --- kstars/ekos/capture/capture.cpp +++ kstars/ekos/capture/capture.cpp @@ -144,7 +144,7 @@ connect(queueSaveAsB, &QPushButton::clicked, this, &Ekos::Capture::saveSequenceQueueAs); connect(queueLoadB, &QPushButton::clicked, this, static_cast(&Ekos::Capture::loadSequenceQueue)); connect(resetB, &QPushButton::clicked, this, &Ekos::Capture::resetJobs); - connect(queueTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Ekos::Capture::selectedJobCanged); + connect(queueTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Ekos::Capture::selectedJobChanged); connect(queueTable, &QAbstractItemView::doubleClicked, this, &Ekos::Capture::editJob); connect(queueTable, &QTableWidget::itemSelectionChanged, this, &Ekos::Capture::resetJobEdit); connect(setTemperatureB, &QPushButton::clicked, [&]() @@ -2404,6 +2404,15 @@ currentRow = queueTable->rowCount() - 1; removeJob(currentRow); + + // update selection + if (queueTable->rowCount() == 0) + return; + + if (currentRow > queueTable->rowCount()) + queueTable->selectRow(queueTable->rowCount()-1); + else + queueTable->selectRow(currentRow); } void Capture::removeJob(int index) @@ -2550,6 +2559,10 @@ qCDebug(KSTARS_EKOS_CAPTURE) << "Preparing capture job" << job->getSignature() << "for execution."; + int index = jobs.indexOf(job); + if (index >= 0) + queueTable->selectRow(index); + if (activeJob->getActiveCCD() != currentCCD) { setCamera(activeJob->getActiveCCD()->getDeviceName()); @@ -3997,21 +4010,29 @@ emit settingsUpdated(settings); } -void Capture::selectedJobCanged(QModelIndex current, QModelIndex previous) +void Capture::selectedJobChanged(QModelIndex current, QModelIndex previous) { Q_UNUSED(previous); selectJob(current); } void Capture::selectJob(QModelIndex i) { + if (i.row() < 0 || (i.row()+1) > jobs.size()) + return; + SequenceJob * job = jobs.at(i.row()); if (job == nullptr) return; syncGUIToJob(job); + if (isBusy || jobs.size() < 2) + return; + + queueUpB->setEnabled(i.row() > 0); + queueDownB->setEnabled(i.row()+1 < jobs.size()); } void Capture::editJob(QModelIndex i) @@ -4229,10 +4250,10 @@ activeJob = nullptr; //m_TargetName.clear(); //stop(); - qDeleteAll(jobs); - jobs.clear(); while (queueTable->rowCount() > 0) queueTable->removeRow(0); + qDeleteAll(jobs); + jobs.clear(); } QString Capture::getSequenceQueueStatus() Index: kstars/ekos/ekos.h =================================================================== --- kstars/ekos/ekos.h +++ kstars/ekos/ekos.h @@ -158,7 +158,7 @@ typedef enum { SCHEDULER_IDLE, /*< Scheduler is stopped. */ SCHEDULER_STARTUP, /*< Scheduler is starting the observatory up. */ - SCHEDULER_RUNNIG, /*< Scheduler is running. */ + SCHEDULER_RUNNING, /*< Scheduler is running. */ SCHEDULER_PAUSED, /*< Scheduler is paused by the end-user. */ SCHEDULER_SHUTDOWN, /*< Scheduler is shutting the observatory down. */ SCHEDULER_ABORTED, /*< Scheduler is stopped in error. */ Index: kstars/ekos/scheduler/scheduler.cpp =================================================================== --- kstars/ekos/scheduler/scheduler.cpp +++ kstars/ekos/scheduler/scheduler.cpp @@ -457,7 +457,7 @@ void Scheduler::saveJob() { - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) { appendLogText(i18n("Warning: You cannot add or modify a job while the scheduler is running.")); return; @@ -791,6 +791,8 @@ minMoonSeparation->setValue(DEFAULT_MIN_MOON_SEPARATION); } + weatherCheck->setChecked(job->getEnforceWeather()); + twilightCheck->blockSignals(true); twilightCheck->setChecked(job->getEnforceTwilight()); twilightCheck->blockSignals(false); @@ -816,14 +818,15 @@ break; } + setJobManipulation(!Options::sortSchedulerJobs(), true); } void Scheduler::loadJob(QModelIndex i) { if (jobUnderEdit == i.row()) return; - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) { appendLogText(i18n("Warning: you cannot add or modify a job while the scheduler is running.")); return; @@ -847,8 +850,6 @@ sequenceURL = job->getSequenceFile(); - weatherCheck->setChecked(job->getEnforceWeather()); - /* Turn the add button into an apply button */ setJobAddApply(false); @@ -868,6 +869,14 @@ void Scheduler::queueTableSelectionChanged(QModelIndex current, QModelIndex previous) { Q_UNUSED(previous); + + // prevent selection when not idle + if (state != SCHEDULER_IDLE) + return; + + if (current.row() < 0 || (current.row()+1) > jobs.size()) + return; + SchedulerJob * const job = jobs.at(current.row()); if (job == nullptr) @@ -902,19 +911,21 @@ void Scheduler::setJobManipulation(bool can_reorder, bool can_delete) { + bool can_edit = (state == SCHEDULER_IDLE); + if (can_reorder) { int const currentRow = queueTable->currentRow(); - queueUpB->setEnabled(0 < currentRow); - queueDownB->setEnabled(currentRow < queueTable->rowCount() - 1); + queueUpB->setEnabled(can_edit && 0 < currentRow); + queueDownB->setEnabled(can_edit && currentRow < queueTable->rowCount() - 1); } else { queueUpB->setEnabled(false); queueDownB->setEnabled(false); } - sortJobsB->setEnabled(can_reorder); - removeFromQueueB->setEnabled(can_delete); + sortJobsB->setEnabled(can_edit && can_reorder); + removeFromQueueB->setEnabled(can_edit && can_delete); } bool Scheduler::reorderJobs(QList reordered_sublist) @@ -1087,8 +1098,16 @@ startB->setEnabled(false); pauseB->setEnabled(false); } - /* Else load the settings of the job that was just deleted */ - else loadJob(queueTable->currentIndex()); + + /* Else update the selection */ + else + { + if (currentRow > queueTable->rowCount()) + currentRow = queueTable->rowCount() - 1; + + loadJob(queueTable->currentIndex()); + queueTable->selectRow(currentRow); + } /* If needed, reset edit mode to clean up UI */ if (jobUnderEdit >= 0) @@ -1105,7 +1124,7 @@ void Scheduler::toggleScheduler() { - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) { preemptiveShutdown = false; stop(); @@ -1116,7 +1135,7 @@ void Scheduler::stop() { - if (state != SCHEDULER_RUNNIG) + if (state != SCHEDULER_RUNNING) return; qCInfo(KSTARS_EKOS_SCHEDULER) << "Scheduler is stopping..."; @@ -1271,7 +1290,7 @@ /* Reset and re-evaluate all scheduler jobs, then start the Scheduler */ startJobEvaluation(); - state = SCHEDULER_RUNNIG; + state = SCHEDULER_RUNNING; emit newStatus(state); schedulerTimer.start(); @@ -1286,7 +1305,7 @@ /* 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_RUNNIG; + state = SCHEDULER_RUNNING; emit newStatus(state); qCDebug(KSTARS_EKOS_SCHEDULER) << "Scheduler paused."; @@ -1378,7 +1397,7 @@ case SchedulerJob::JOB_ABORTED: /* If job is aborted and we're running, keep its evaluation until there is nothing else to do */ - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) continue; /* Fall through */ case SchedulerJob::JOB_IDLE: @@ -1967,7 +1986,7 @@ /* Apply sorting to queue table, and mark it for saving if it changes */ mDirty = reorderJobs(sortedJobs); - if (jobEvaluationOnly || state != SCHEDULER_RUNNIG) + if (jobEvaluationOnly || state != SCHEDULER_RUNNING) { qCInfo(KSTARS_EKOS_SCHEDULER) << "Ekos finished evaluating jobs, no job selection required."; jobEvaluationOnly = false; @@ -2051,7 +2070,7 @@ } else { - if (state == SCHEDULER_RUNNIG) + if (state == 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.")); @@ -2554,6 +2573,9 @@ return; setCurrentJob(job); + int index = jobs.indexOf(job); + if (index >= 0) + queueTable->selectRow(index); QDateTime const now = KStarsData::Instance()->lt(); @@ -3018,7 +3040,7 @@ setCurrentJob(nullptr); - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) schedulerTimer.start(); if (preemptiveShutdown == false) @@ -3988,7 +4010,7 @@ bool Scheduler::manageConnectionLoss() { - if (SCHEDULER_RUNNIG != state) + if (SCHEDULER_RUNNING != state) return false; // Don't manage loss if Ekos is actually down in the state machine @@ -4082,11 +4104,12 @@ if (jobUnderEdit >= 0) resetJobEdit(); - qDeleteAll(jobs); - jobs.clear(); while (queueTable->rowCount() > 0) queueTable->removeRow(0); + qDeleteAll(jobs); + jobs.clear(); + LilXML *xmlParser = newLilXML(); char errmsg[MAXRBUF]; XMLEle *root = nullptr; @@ -4987,7 +5010,7 @@ if (sender() == startupProcedureButtonGroup || sender() == shutdownProcedureGroup) return; - if (0 <= jobUnderEdit && state != SCHEDULER_RUNNIG && 0 <= queueTable->currentRow()) + if (0 <= jobUnderEdit && state != 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++) @@ -6248,7 +6271,7 @@ void Scheduler::resetAllJobs() { - if (state == SCHEDULER_RUNNIG) + if (state == SCHEDULER_RUNNING) return; // Reset capture count of all jobs before re-evaluating