Commit f1dbdc49 authored by Jasem Mutlaq's avatar Jasem Mutlaq

Make scheduler job edit more interactive to avoid usability problems with adding and editing jobs

parent 25ff36e9
......@@ -38,6 +38,10 @@
#define UPDATE_PERIOD_MS 1000
#define SETTING_ALTITUDE_CUTOFF 3
#define DEFAULT_CULMINATION_TIME -60
#define DEFAULT_MIN_ALTITUDE 15
#define DEFAULT_MIN_MOON_SEPARATION 0
namespace Ekos
{
......@@ -134,7 +138,7 @@ Scheduler::Scheduler()
raBox->setDegType(false); //RA box should be HMS-style
addToQueueB->setIcon(QIcon::fromTheme("list-add"));
addToQueueB->setToolTip(i18n("Add observation job to list."));
addToQueueB->setToolTip(i18n("Add observation job to list."));
removeFromQueueB->setIcon(QIcon::fromTheme("list-remove"));
removeFromQueueB->setToolTip(i18n("Remove observation job from list."));
......@@ -161,32 +165,14 @@ Scheduler::Scheduler()
connect(addToQueueB,SIGNAL(clicked()),this,SLOT(addJob()));
connect(removeFromQueueB, SIGNAL(clicked()), this, SLOT(removeJob()));
connect(evaluateOnlyB, SIGNAL(clicked()), this, SLOT(startJobEvaluation()));
connect(queueTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editJob(QModelIndex)));
connect(queueTable, SIGNAL(itemSelectionChanged()), this, SLOT(resetJobEdit()));
connect(queueTable, SIGNAL(clicked(QModelIndex)), this, SLOT(loadJob(QModelIndex)));
//connect(queueTable, SIGNAL(itemSelectionChanged()), this, SLOT(resetJobEdit()));
connect(startB,SIGNAL(clicked()),this,SLOT(toggleScheduler()));
connect(queueSaveAsB,SIGNAL(clicked()),this,SLOT(saveAs()));
connect(queueSaveB,SIGNAL(clicked()),this,SLOT(save()));
connect(queueLoadB,SIGNAL(clicked()),this,SLOT(load()));
connect(startupScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
connect(shutdownScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
connect(weatherCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(trackStepCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(focusStepCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(alignStepCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(guideStepCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(capCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(uncapCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(parkMountCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(unparkMountCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(parkDomeCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(unparkDomeCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(warmCCDCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
connect(startupScript, SIGNAL(textChanged(QString)), this, SLOT(setDirty()));
connect(shutdownScript, SIGNAL(textChanged(QString)), this, SLOT(setDirty()));
connect(fitsEdit, SIGNAL(textChanged(QString)), this, SLOT(setDirty()));
connect(queueLoadB,SIGNAL(clicked()),this,SLOT(load()));
}
Scheduler::~Scheduler()
......@@ -194,6 +180,40 @@ Scheduler::~Scheduler()
}
void Scheduler::watchJobChanges(bool enable)
{
if (enable)
{
connect(fitsEdit, SIGNAL(editingFinished()), this, SLOT(setDirty()));
connect(startupScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
connect(shutdownScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
connect(stepsButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
connect(startupButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
connect(constraintButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
connect(completionButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
connect(startupProcedureButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
connect(shutdownProcedureGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
}
else
{
//disconnect(this, SLOT(setDirty()));
disconnect(fitsEdit, SIGNAL(editingFinished()), this, SLOT(setDirty()));
disconnect(startupScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
disconnect(shutdownScript, SIGNAL(editingFinished()), this, SLOT(setDirty()));
disconnect(stepsButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
disconnect(startupButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
disconnect(constraintButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
disconnect(completionButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
disconnect(startupProcedureButtonGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
disconnect(shutdownProcedureGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(setDirty()));
}
}
void Scheduler::appendLogText(const QString &text)
{
......@@ -314,6 +334,12 @@ void Scheduler::selectShutdownScript()
}
void Scheduler::addJob()
{
jobUnderEdit = false;
saveJob();
}
void Scheduler::saveJob()
{
if (state == SCHEDULER_RUNNIG)
......@@ -322,6 +348,8 @@ void Scheduler::addJob()
return;
}
watchJobChanges(false);
if(nameEdit->text().isEmpty())
{
appendLogText(i18n("Target name is required."));
......@@ -401,9 +429,14 @@ void Scheduler::addJob()
// Do we have minimum altitude constraint?
if (altConstraintCheck->isChecked())
job->setMinAltitude(minAltitude->value());
else
job->setMinAltitude(-1);
// Do we have minimum moon separation constraint?
if (moonSeparationCheck->isChecked())
job->setMinMoonSeparation(minMoonSeparation->value());
else
job->setMinMoonSeparation(-1);
// Check enforce weather constraints
job->setEnforceWeather(weatherCheck->isChecked());
......@@ -494,14 +527,16 @@ void Scheduler::addJob()
if (jobUnderEdit)
{
jobUnderEdit = false;
resetJobEdit();
appendLogText(i18n("Job #%1 changes applied.", currentRow+1));
//resetJobEdit();
//appendLogText(i18n("Job #%1 changes applied.", currentRow+1));
}
startB->setEnabled(true);
watchJobChanges(true);
}
void Scheduler::editJob(QModelIndex i)
void Scheduler::loadJob(QModelIndex i)
{
if (state == SCHEDULER_RUNNIG)
{
......@@ -511,7 +546,9 @@ void Scheduler::editJob(QModelIndex i)
SchedulerJob *job = jobs.at(i.row());
if (job == NULL)
return;
return;
watchJobChanges(false);
job->setState(SchedulerJob::JOB_IDLE);
job->setStage(SchedulerJob::STAGE_IDLE);
......@@ -546,10 +583,12 @@ void Scheduler::editJob(QModelIndex i)
{
case SchedulerJob::START_ASAP:
asapConditionR->setChecked(true);
culminationOffset->setValue(DEFAULT_CULMINATION_TIME);
break;
case SchedulerJob::START_FORCE_NOW:
forceNowConditionR->setChecked(true);
culminationOffset->setValue(DEFAULT_CULMINATION_TIME);
break;
case SchedulerJob::START_CULMINATION:
......@@ -560,6 +599,7 @@ void Scheduler::editJob(QModelIndex i)
case SchedulerJob::START_AT:
startupTimeConditionR->setChecked(true);
startupTimeEdit->setDateTime(job->getStartupTime());
culminationOffset->setValue(DEFAULT_CULMINATION_TIME);
break;
}
......@@ -568,12 +608,22 @@ void Scheduler::editJob(QModelIndex i)
altConstraintCheck->setChecked(true);
minAltitude->setValue(job->getMinAltitude());
}
else
{
altConstraintCheck->setChecked(false);
minAltitude->setValue(DEFAULT_MIN_ALTITUDE);
}
if (job->getMinMoonSeparation() >= 0)
{
moonSeparationCheck->setChecked(true);
minMoonSeparation->setValue(job->getMinMoonSeparation());
}
else
{
moonSeparationCheck->setChecked(false);
minMoonSeparation->setValue(DEFAULT_MIN_MOON_SEPARATION);
}
weatherCheck->setChecked(job->getEnforceWeather());
......@@ -593,7 +643,7 @@ void Scheduler::editJob(QModelIndex i)
break;
}
appendLogText(i18n("Editing job #%1...", i.row()+1));
/*appendLogText(i18n("Editing job #%1...", i.row()+1));
addToQueueB->setIcon(QIcon::fromTheme("dialog-ok-apply"));
addToQueueB->setEnabled(true);
......@@ -603,10 +653,13 @@ void Scheduler::editJob(QModelIndex i)
addToQueueB->setToolTip(i18n("Apply job changes."));
removeFromQueueB->setToolTip(i18n("Cancel job changes."));
jobUnderEdit = true;
jobUnderEdit = true;*/
watchJobChanges(true);
}
void Scheduler::resetJobEdit()
/*void Scheduler::resetJobEdit()
{
if (jobUnderEdit)
appendLogText(i18n("Editing job canceled."));
......@@ -618,15 +671,15 @@ void Scheduler::resetJobEdit()
removeFromQueueB->setToolTip(i18n("Remove observation job from list."));
evaluateOnlyB->setEnabled(true);
}
}*/
void Scheduler::removeJob()
{
if (jobUnderEdit)
/*if (jobUnderEdit)
{
resetJobEdit();
return;
}
}*/
int currentRow = queueTable->currentRow();
......@@ -2924,7 +2977,7 @@ bool Scheduler::processJobInfo(XMLEle *root)
}
}
addJob();
saveJob();
return true;
......@@ -3372,6 +3425,15 @@ void Scheduler::stopEkos()
void Scheduler::setDirty()
{
mDirty = true;
if (sender() == startupProcedureButtonGroup || sender() == shutdownProcedureGroup)
return;
if (state != SCHEDULER_RUNNIG && queueTable->selectedItems().isEmpty() == false)
{
jobUnderEdit=true;
saveJob();
}
}
bool Scheduler::estimateJobTime(SchedulerJob *job)
......@@ -3988,7 +4050,7 @@ void Scheduler::startMosaicTool()
raBox->setText(oneJob->skyCenter.ra0().toHMSString());
decBox->setText(oneJob->skyCenter.dec0().toDMSString());
addJob();
saveJob();
}
delXMLEle(root);
......
......@@ -171,7 +171,13 @@ protected slots:
void selectShutdownScript();
/**
* @brief addToQueue Construct a SchedulerJob and add it to the queue
* @brief addToQueue Construct a SchedulerJob and add it to the queue or save job settings from current form values.
* jobUnderEdit determines whether to add or edit
*/
void saveJob();
/**
* @brief addJob Add a new job from form values
*/
void addJob();
......@@ -179,7 +185,7 @@ protected slots:
* @brief editJob Edit an observation job
* @param i index model in queue table
*/
void editJob(QModelIndex i);
void loadJob(QModelIndex i);
/**
* @brief removeJob Remove a job from the currently selected row. If no row is selected, it remove the last job in the queue.
......@@ -191,7 +197,7 @@ protected slots:
void saveAs();
void load();
void resetJobEdit();
//void resetJobEdit();
/**
* @brief checkJobStatus Check the overall state of the scheduler, Ekos, and INDI. When all is OK, it call evaluateJobs();
......@@ -224,6 +230,11 @@ protected slots:
*/
void checkProcessExit(int exitCode);
/**
* @brief watchJobChanges Watch any changes in form values and apply changes to current job selection or ignore any changes
* @param enable True to watch changes and apply them to current job, false to ignore changes
*/
void watchJobChanges(bool enable);
/**
* @brief setDirty Call it to mark the Ekos Scheduler List for change. Next time save button is invoked, the complete content is written to disk.
*/
......
......@@ -101,6 +101,9 @@
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">stepsButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -114,6 +117,9 @@
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">stepsButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -127,6 +133,9 @@
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">stepsButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -140,6 +149,9 @@
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">stepsButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -462,6 +474,12 @@
</item>
<item>
<widget class="QTableWidget" name="queueTable">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
......@@ -636,6 +654,9 @@
<property name="text">
<string>Alt &gt; </string>
</property>
<attribute name="buttonGroup">
<string notr="true">constraintButtonGroup</string>
</attribute>
</widget>
</item>
<item row="0" column="1">
......@@ -663,6 +684,9 @@
<property name="text">
<string>Moon &gt; </string>
</property>
<attribute name="buttonGroup">
<string notr="true">constraintButtonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="1">
......@@ -694,6 +718,9 @@
<property name="text">
<string>Weather</string>
</property>
<attribute name="buttonGroup">
<string notr="true">constraintButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -830,6 +857,9 @@
<property name="text">
<string>UnPark Dome</string>
</property>
<attribute name="buttonGroup">
<string notr="true">startupProcedureButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -843,6 +873,9 @@
<property name="text">
<string>UnPark Mount</string>
</property>
<attribute name="buttonGroup">
<string notr="true">startupProcedureButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -853,6 +886,9 @@
<property name="text">
<string>UnCap</string>
</property>
<attribute name="buttonGroup">
<string notr="true">startupProcedureButtonGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -929,6 +965,9 @@
<property name="text">
<string>Warm CCD</string>
</property>
<attribute name="buttonGroup">
<string notr="true">shutdownProcedureGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -939,6 +978,9 @@
<property name="text">
<string>Cap</string>
</property>
<attribute name="buttonGroup">
<string notr="true">shutdownProcedureGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -952,6 +994,9 @@
<property name="text">
<string>Park Mount</string>
</property>
<attribute name="buttonGroup">
<string notr="true">shutdownProcedureGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -965,6 +1010,9 @@
<property name="text">
<string>Park Dome</string>
</property>
<attribute name="buttonGroup">
<string notr="true">shutdownProcedureGroup</string>
</attribute>
</widget>
</item>
<item>
......@@ -1074,7 +1122,27 @@
<resources/>
<connections/>
<buttongroups>
<buttongroup name="startupProcedureButtonGroup">
<property name="exclusive">
<bool>false</bool>
</property>
</buttongroup>
<buttongroup name="startupButtonGroup"/>
<buttongroup name="completionButtonGroup"/>
<buttongroup name="stepsButtonGroup">
<property name="exclusive">
<bool>false</bool>
</property>
</buttongroup>
<buttongroup name="constraintButtonGroup">
<property name="exclusive">
<bool>false</bool>
</property>
</buttongroup>
<buttongroup name="shutdownProcedureGroup">
<property name="exclusive">
<bool>false</bool>
</property>
</buttongroup>
</buttongroups>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment