[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kstars/bleeding] kstars/ekos/capture: Moving all capture module files to their own dedicated direct
From:       Jasem Mutlaq <mutlaqja () ikarustech ! com>
Date:       2016-09-24 20:20:10
Message-ID: E1bntQg-00086b-BZ () code ! kde ! org
[Download RAW message or body]

Git commit 37fecee9cca8503903c8e6e60ae74274bf5ad685 by Jasem Mutlaq.
Committed on 24/09/2016 at 20:13.
Pushed by mutlaqja into branch 'bleeding'.

Moving all capture module files to their own dedicated directly

A  +277  -0    kstars/ekos/capture/calibrationoptions.ui
A  +3805 -0    kstars/ekos/capture/capture.cpp     [License: GPL (v2+)]
A  +590  -0    kstars/ekos/capture/capture.h     [License: GPL (v2+)]
A  +1602 -0    kstars/ekos/capture/capture.ui
A  +422  -0    kstars/ekos/capture/sequencejob.cpp     [License: GPL (v2+)]
A  +206  -0    kstars/ekos/capture/sequencejob.h     [License: GPL (v2+)]

http://commits.kde.org/kstars/37fecee9cca8503903c8e6e60ae74274bf5ad685

diff --git a/kstars/ekos/capture/calibrationoptions.ui \
b/kstars/ekos/capture/calibrationoptions.ui new file mode 100644
index 0000000..d7411a2
--- /dev/null
+++ b/kstars/ekos/capture/calibrationoptions.ui
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>calibrationOptions</class>
+ <widget class="QDialog" name="calibrationOptions">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>475</width>
+    <height>241</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Calibration Options</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QGroupBox" name="groupBox">
+       <property name="toolTip">
+        <string>Specify the source the flat field evenly illuminated light \
source</string> +       </property>
+       <property name="title">
+        <string>Flat Source</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QRadioButton" name="manualSourceC">
+          <property name="toolTip">
+           <string>Light source triggered by the user manually</string>
+          </property>
+          <property name="text">
+           <string>Manual</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="flatDeviceSourceC">
+          <property name="toolTip">
+           <string>For dark and bias frames, close the dust cap before proceeding. \
For flat frames, close the dust cap and turn on the light source.</string> +          \
</property> +          <property name="text">
+           <string>Dust Cover with Built-in Flat Light</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="darkDeviceSourceC">
+          <property name="toolTip">
+           <string>For dark and bias frames, close the dust cap before proceeding. \
For flat frames, open the dust cap and turn on the light source.</string> +          \
</property> +          <property name="text">
+           <string>Dust Cover with External Flat Light</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <widget class="QRadioButton" name="wallSourceC">
+            <property name="toolTip">
+             <string>Slew mount to the specified Azimuth/Altitude coordinates before \
taking flat field images</string> +            </property>
+            <property name="text">
+             <string>Wall</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Az:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="dmsBox" name="azBox">
+            <property name="toolTip">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="label_2">
+            <property name="text">
+             <string>Alt:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="dmsBox" name="altBox">
+            <property name="toolTip">
+             <string/>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="dawnDuskFlatsC">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+          <property name="toolTip">
+           <string>Use Dawn and Dusk light</string>
+          </property>
+          <property name="text">
+           <string>Dawn/Dusk</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="groupBox_2">
+       <property name="title">
+        <string>Flat Duration</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="QRadioButton" name="manualDurationC">
+          <property name="toolTip">
+           <string>Use the frame exposure value</string>
+          </property>
+          <property name="text">
+           <string>Manual</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QRadioButton" name="ADUC">
+            <property name="toolTip">
+             <string>Calculate optimal exposure time given the required ADU. If a \
controllable device is selected, calculate optimal brightness.</string> +            \
</property> +            <property name="text">
+             <string>ADU</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QSpinBox" name="ADUValue">
+            <property name="toolTip">
+             <string/>
+            </property>
+            <property name="maximum">
+             <number>65535</number>
+            </property>
+            <property name="singleStep">
+             <number>1000</number>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="parkMountC">
+     <property name="text">
+      <string>Park Mount</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="parkDomeC">
+     <property name="text">
+      <string>Park Dome</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>dmsBox</class>
+   <extends>QLineEdit</extends>
+   <header>widgets/dmsbox.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>manualSourceC</tabstop>
+  <tabstop>flatDeviceSourceC</tabstop>
+  <tabstop>darkDeviceSourceC</tabstop>
+  <tabstop>wallSourceC</tabstop>
+  <tabstop>azBox</tabstop>
+  <tabstop>altBox</tabstop>
+  <tabstop>dawnDuskFlatsC</tabstop>
+  <tabstop>manualDurationC</tabstop>
+  <tabstop>ADUC</tabstop>
+  <tabstop>ADUValue</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>calibrationOptions</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>calibrationOptions</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/kstars/ekos/capture/capture.cpp b/kstars/ekos/capture/capture.cpp
new file mode 100644
index 0000000..0f7b1aa
--- /dev/null
+++ b/kstars/ekos/capture/capture.cpp
@@ -0,0 +1,3805 @@
+/*  Ekos
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+#include <QFileDialog>
+#include <QDirIterator>
+#include <QStandardPaths>
+
+#include <KMessageBox>
+#include <KDirWatch>
+#include <KLocalizedString>
+#include <KNotifications/KNotification>
+
+#include <basedevice.h>
+#include <lilxml.h>
+
+#include "Options.h"
+
+#include "kstars.h"
+#include "kstarsdata.h"
+
+#include "capture.h"
+#include "sequencejob.h"
+
+#include "indi/driverinfo.h"
+#include "indi/indifilter.h"
+#include "indi/clientmanager.h"
+
+#include "fitsviewer/fitsviewer.h"
+#include "fitsviewer/fitsview.h"
+
+#include "darklibrary.h"
+#include "ekosmanager.h"
+#include "captureadaptor.h"
+#include "ui_calibrationoptions.h"
+
+#include "QProgressIndicator.h"
+
+#define INVALID_TEMPERATURE 10000
+#define INVALID_HA          10000
+#define MF_TIMER_TIMEOUT    90000
+#define MF_RA_DIFF_LIMIT    4
+#define MAX_CAPTURE_RETRIES 3
+
+namespace Ekos
+{
+
+Capture::Capture()
+{
+    setupUi(this);
+
+    new CaptureAdaptor(this);
+    QDBusConnection::sessionBus().registerObject("/KStars/Ekos/Capture",  this);
+
+    dirPath = QUrl(QDir::homePath());
+
+    state = CAPTURE_IDLE;
+    focusState = FOCUS_IDLE;
+    guideState = GUIDE_IDLE;
+    alignState = ALIGN_IDLE;
+
+    currentCCD = NULL;
+    currentTelescope = NULL;
+    currentFilter = NULL;
+    dustCap = NULL;
+    lightBox= NULL;
+    dome    = NULL;
+
+    filterSlot = NULL;
+    filterName = NULL;
+    activeJob  = NULL;
+
+    targetChip = NULL;
+    guideChip  = NULL;
+
+    targetADU  = 0;
+    flatFieldDuration = DURATION_MANUAL;
+    flatFieldSource   = SOURCE_MANUAL;
+    calibrationStage         = CAL_NONE;
+    preMountPark           = false;
+    preDomePark            = false;
+
+    deviationDetected = false;
+    spikeDetected     = false;
+    isBusy            = false;
+
+    ignoreJobProgress=true;
+
+    dustCapLightEnabled = lightBoxLightEnabled = false;
+
+    //isAutoGuiding   = false;
+    guideDither     = false;
+    isAutoFocus     = false;
+    autoFocusStatus = false;
+    resumeAlignmentAfterFlip= false;
+
+    mDirty          = false;
+    jobUnderEdit    = false;
+    currentFilterPosition   = -1;
+
+    //calibrationState  = CALIBRATE_NONE;
+    meridianFlipStage = MF_NONE;
+    resumeGuidingAfterFlip = false;
+
+    //ADURaw1 = ADURaw2 = ExpRaw1 = ExpRaw2 = -1;
+    //ADUSlope = 0;
+
+    pi = new QProgressIndicator(this);
+
+    progressLayout->addWidget(pi, 0, 4, 1, 1);
+
+    seqFileCount    = 0;
+    //seqWatcher		= new KDirWatch();
+    seqTimer = new QTimer(this);
+    connect(seqTimer, SIGNAL(timeout()), this, SLOT(captureImage()));
+
+    connect(startB, SIGNAL(clicked()), this, SLOT(toggleSequence()));
+    connect(pauseB, SIGNAL(clicked()), this, SLOT(pause()));
+
+    startB->setIcon(QIcon::fromTheme("media-playback-start"));
+    pauseB->setIcon(QIcon::fromTheme("media-playback-pause"));
+
+    connect(binXIN, SIGNAL(valueChanged(int)), binYIN, SLOT(setValue(int)));
+
+    connect(CCDCaptureCombo, SIGNAL(activated(QString)), this, \
SLOT(setDefaultCCD(QString))); +    connect(CCDCaptureCombo, \
SIGNAL(currentIndexChanged(int)), this, SLOT(checkCCD(int))); +
+
+    connect(FilterCaptureCombo, SIGNAL(activated(int)), this, \
SLOT(checkFilter(int))); +
+    connect(previewB, SIGNAL(clicked()), this, SLOT(captureOne()));
+
+    //connect( seqWatcher, SIGNAL(dirty(QString)), this, \
SLOT(checkSeqFile(QString))); +
+    connect(addToQueueB, SIGNAL(clicked()), this, SLOT(addJob()));
+    connect(removeFromQueueB, SIGNAL(clicked()), this, SLOT(removeJob()));
+    connect(queueUpB, SIGNAL(clicked()), this, SLOT(moveJobUp()));
+    connect(queueDownB, SIGNAL(clicked()), this, SLOT(moveJobDown()));
+    connect(selectFITSDirB, SIGNAL(clicked()), this, SLOT(saveFITSDirectory()));
+    connect(queueSaveB, SIGNAL(clicked()), this, SLOT(saveSequenceQueue()));
+    connect(queueSaveAsB, SIGNAL(clicked()), this, SLOT(saveSequenceQueueAs()));
+    connect(queueLoadB, SIGNAL(clicked()), this, SLOT(loadSequenceQueue()));
+    connect(resetB, SIGNAL(clicked()), this, SLOT(resetJobs()));
+    connect(queueTable, SIGNAL(doubleClicked(QModelIndex)), this, \
SLOT(editJob(QModelIndex))); +    connect(queueTable, SIGNAL(itemSelectionChanged()), \
this, SLOT(resetJobEdit())); +    connect(setTemperatureB, SIGNAL(clicked()), this, \
SLOT(setTemperature())); +    connect(temperatureIN, SIGNAL(editingFinished()), \
setTemperatureB, SLOT(setFocus())); +    connect(frameTypeCombo, \
SIGNAL(currentIndexChanged(int)), this, SLOT(checkFrameType(int))); +    \
connect(resetFrameB, SIGNAL(clicked()), this, SLOT(resetFrame())); +    \
connect(calibrationB, SIGNAL(clicked()), this, SLOT(openCalibrationDialog())); +
+    addToQueueB->setIcon(QIcon::fromTheme("list-add"));
+    removeFromQueueB->setIcon(QIcon::fromTheme("list-remove"));
+    queueUpB->setIcon(QIcon::fromTheme("go-up"));
+    queueDownB->setIcon(QIcon::fromTheme("go-down"));
+    selectFITSDirB->setIcon(QIcon::fromTheme("document-open-folder"));
+    queueLoadB->setIcon(QIcon::fromTheme("document-open"));
+    queueSaveB->setIcon(QIcon::fromTheme("document-save"));
+    queueSaveAsB->setIcon(QIcon::fromTheme("document-save-as"));
+    resetB->setIcon(QIcon::fromTheme("system-reboot"));
+    resetFrameB->setIcon(QIcon::fromTheme("view-refresh"));
+    calibrationB->setIcon(QIcon::fromTheme("run-build"));
+
+    addToQueueB->setToolTip(i18n("Add job to sequence queue"));
+    removeFromQueueB->setToolTip(i18n("Remove job from sequence queue"));
+
+    fitsDir->setText(Options::fitsDir());
+
+    seqExpose = 0;
+    seqTotalCount = 0;
+    seqCurrentCount = 0;
+    seqDelay = 0;
+    fileHFR=0;
+    useGuideHead = false;
+    guideDither = false;
+    firstAutoFocus = true;
+
+    foreach(QString filter, FITSViewer::filterTypes)
+        filterCombo->addItem(filter);
+
+    guideDeviationCheck->setChecked(Options::enforceGuideDeviation());
+    guideDeviation->setValue(Options::guideDeviation());
+    autofocusCheck->setChecked(Options::enforceAutofocus());
+    parkCheck->setChecked(Options::autoParkTelescope());
+    meridianCheck->setChecked(Options::autoMeridianFlip());
+    meridianHours->setValue(Options::autoMeridianHours());
+
+    connect(autofocusCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
+    connect(HFRPixels, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
+    connect(guideDeviationCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
+    connect(guideDeviation, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
+    connect(meridianCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
+    connect(meridianHours, SIGNAL(valueChanged(double)), this, SLOT(setDirty()));
+    connect(parkCheck, SIGNAL(toggled(bool)), this, SLOT(setDirty()));
+
+
+    // FIXME remove this later
+    connect(&postCaptureScript, SIGNAL(finished(int)), this, \
SLOT(postScriptFinished(int))); +}
+
+Capture::~Capture()
+{
+    qDeleteAll(jobs);
+}
+
+void Capture::setDefaultCCD(QString ccd)
+{
+    Options::setDefaultCaptureCCD(ccd);
+}
+
+void Capture::addCCD(ISD::GDInterface *newCCD)
+{
+    ISD::CCD *ccd = static_cast<ISD::CCD *> (newCCD);
+
+    if (CCDs.contains(ccd))
+            return;
+
+    CCDs.append(ccd);
+
+    CCDCaptureCombo->addItem(ccd->getDeviceName());
+
+    if (Filters.count() > 0)
+        syncFilterInfo();
+    //checkCCD(CCDs.count()-1);
+    //CCDCaptureCombo->setCurrentIndex(CCDs.count()-1);
+
+}
+
+void Capture::addGuideHead(ISD::GDInterface *newCCD)
+{
+    QString guiderName = newCCD->getDeviceName() + QString(" Guider");
+
+    if (CCDCaptureCombo->findText(guiderName) == -1)
+    {
+        CCDCaptureCombo->addItem(guiderName);
+        CCDs.append(static_cast<ISD::CCD *> (newCCD));
+    }
+}
+
+void Capture::addFilter(ISD::GDInterface *newFilter)
+{
+    foreach(ISD::GDInterface *filter, Filters)
+    {
+        if (!strcmp(filter->getDeviceName(), newFilter->getDeviceName()))
+            return;
+    }
+
+    FilterCaptureCombo->addItem(newFilter->getDeviceName());
+
+    Filters.append(static_cast<ISD::Filter *>(newFilter));
+
+    checkFilter(0);
+
+    FilterCaptureCombo->setCurrentIndex(0);
+
+}
+
+void Capture::pause()
+{
+    pauseFunction=NULL;
+    state = CAPTURE_PAUSED;
+    emit newStatus(Ekos::CAPTURE_PAUSED);
+    appendLogText(i18n("Sequence shall be paused after current exposure is \
complete.")); +    pauseB->setEnabled(false);
+
+    startB->setIcon(QIcon::fromTheme("media-playback-start"));
+    startB->setToolTip(i18n("Resume Sequence"));
+}
+
+void Capture::toggleSequence()
+{
+    if (state == CAPTURE_PAUSED)
+    {
+        startB->setIcon(QIcon::fromTheme("media-playback-stop"));
+        startB->setToolTip(i18n("Stop Sequence"));
+        pauseB->setEnabled(true);
+
+        state = CAPTURE_CAPTURING;
+        emit newStatus(Ekos::CAPTURE_CAPTURING);
+
+        appendLogText(i18n("Sequence resumed."));
+
+        // Call from where ever we have left of when we paused
+        if (pauseFunction)
+            (this->*pauseFunction)();
+    }
+    else if (state == CAPTURE_IDLE || state == CAPTURE_COMPLETE)
+    {
+        start();
+    }
+    else
+    {
+        abort();
+    }
+}
+
+void Capture::start()
+{
+    if (darkSubCheck->isChecked())
+    {
+        KMessageBox::error(this, i18n("Auto dark subtract is not supported in batch \
mode.")); +        return;
+    }
+
+    Options::setGuideDeviation(guideDeviation->value());
+    Options::setEnforceGuideDeviation(guideDeviationCheck->isChecked());
+    Options::setEnforceAutofocus(autofocusCheck->isChecked());
+    Options::setAutoMeridianFlip(meridianCheck->isChecked());
+    Options::setAutoMeridianHours(meridianHours->value());
+    Options::setAutoParkTelescope(parkCheck->isChecked());
+
+    if (queueTable->rowCount() ==0)
+        addJob();
+
+    SequenceJob *first_job = NULL;
+
+    foreach(SequenceJob *job, jobs)
+    {
+        if (job->getStatus() == SequenceJob::JOB_IDLE || job->getStatus() == \
SequenceJob::JOB_ABORTED) +        {
+            first_job = job;
+            break;
+        }
+    }
+
+    if (first_job == NULL)
+    {
+        foreach(SequenceJob *job, jobs)
+        {
+            if (job->getStatus() != SequenceJob::JOB_DONE)
+            {
+                appendLogText(i18n("No pending jobs found. Please add a job to the \
sequence queue.")); +                return;
+            }
+        }
+
+        if (KMessageBox::warningContinueCancel(NULL, i18n("All jobs are complete. Do \
you want to reset the status of all jobs and restart capturing?"), +                  \
i18n("Reset job status"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), +     \
"reset_job_complete_status_warning") !=KMessageBox::Continue) +            return;
+
+        foreach(SequenceJob *job, jobs)
+            job->resetStatus();
+
+        first_job = jobs.first();
+    }
+
+    deviationDetected = false;
+    spikeDetected     = false;
+
+    initialHA = getCurrentHA();
+    meridianFlipStage = MF_NONE;
+
+    // Check if we need to update the sequence directory numbers before starting
+    /*for (int i=0; i < jobs.count(); i++)
+    {
+        QString firstDir = jobs.at(i)->getFITSDir();
+        int sequenceID=1;
+
+        for (int j=i+1; j < jobs.count(); j++)
+        {
+            if (firstDir == jobs.at(j)->getFITSDir())
+            {
+                jobs.at(i)->setFITSDir(QString("%1/Sequence_1").arg(firstDir));
+                jobs.at(j)->setFITSDir(QString("%1/Sequence_%2").arg(jobs.at(j)->getFITSDir()).arg(++sequenceID));
 +            }
+        }
+    }*/
+
+    state = CAPTURE_PROGRESS;
+    emit newStatus(Ekos::CAPTURE_PROGRESS);
+
+    startB->setIcon(QIcon::fromTheme("media-playback-stop"));
+    startB->setToolTip(i18n("Stop Sequence"));
+    pauseB->setEnabled(true);
+
+    foreach (QAbstractButton *button, queueEditButtonGroup->buttons())
+        button->setEnabled(false);
+
+    prepareJob(first_job);
+
+}
+
+void Capture::stop(bool abort)
+{
+
+    retries              = 0;
+    seqTotalCount        = 0;
+    seqCurrentCount      = 0;
+    //ADURaw1 = ADURaw2 = ExpRaw1 = ExpRaw2 = -1;
+    //ADUSlope = 0;
+    ADURaw.clear();
+    ExpRaw.clear();
+
+    calibrationStage = CAL_NONE;
+
+    if (activeJob)
+    {
+        if (activeJob->getStatus() == SequenceJob::JOB_BUSY)
+        {
+            KNotification::event( QLatin1String( "CaptureFailed"), i18n("CCD capture \
failed with errors") ); +            activeJob->abort();
+            emit newStatus(Ekos::CAPTURE_ABORTED);
+        }
+
+        activeJob->disconnect(this);
+        activeJob->reset();
+    }
+
+    state = CAPTURE_IDLE;
+
+    // Turn off any calibration light, IF they were turned on by Capture module
+    if  (dustCap && dustCapLightEnabled)
+    {
+        dustCapLightEnabled = false;
+        dustCap->SetLightEnabled(false);
+    }
+    if (lightBox && lightBoxLightEnabled)
+    {
+        lightBoxLightEnabled = false;
+        lightBox->SetLightEnabled(false);
+    }
+
+    secondsLabel->clear();
+    disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, \
SLOT(newFITS(IBLOB*))); +    disconnect(currentCCD, \
SIGNAL(newImage(QImage*,ISD::CCDChip*)), this, \
SLOT(sendNewImage(QImage*,ISD::CCDChip*))); +    disconnect(currentCCD, \
SIGNAL(newExposureValue(ISD::CCDChip*,double, IPState)), this, \
SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState))); +
+    currentCCD->setFITSDir("");
+
+    imgProgress->reset();
+    imgProgress->setEnabled(false);
+
+    fullImgCountOUT->setText(QString());
+    currentImgCountOUT->setText(QString());
+    exposeOUT->setText(QString());
+
+    setBusy(false);
+
+    if (abort)
+    {
+        startB->setIcon(QIcon::fromTheme("media-playback-start"));
+        startB->setToolTip(i18n("Start Sequence"));
+        pauseB->setEnabled(false);
+    }
+
+    foreach (QAbstractButton *button, queueEditButtonGroup->buttons())
+        button->setEnabled(true);
+
+    seqTimer->stop();
+
+}
+
+void Capture::sendNewImage(QImage *image, ISD::CCDChip *myChip)
+{
+    if (activeJob && myChip != guideChip)
+        emit newImage(image, activeJob);
+}
+
+bool Capture::setCCD(QString device)
+{
+    for (int i=0; i < CCDCaptureCombo->count(); i++)
+        if (device == CCDCaptureCombo->itemText(i))
+        {
+            CCDCaptureCombo->setCurrentIndex(i);
+            return true;
+        }
+
+    return false;
+}
+
+void Capture::checkCCD(int ccdNum)
+{
+    if (ccdNum == -1)
+    {
+        ccdNum = CCDCaptureCombo->currentIndex();
+
+        if (ccdNum == -1)
+            return;
+    }
+
+    foreach(ISD::CCD *ccd, CCDs)
+    {
+        disconnect(ccd, SIGNAL(numberUpdated(INumberVectorProperty*)), this, \
SLOT(processCCDNumber(INumberVectorProperty*))); +        disconnect(ccd, \
SIGNAL(newTemperatureValue(double)), this, SLOT(updateCCDTemperature(double))); +     \
disconnect(ccd, SIGNAL(newRemoteFile(QString)), this, \
SLOT(setNewRemoteFile(QString))); +    }
+
+    if (ccdNum <= CCDs.count())
+    {
+        // Check whether main camera or guide head only
+        currentCCD = CCDs.at(ccdNum);
+
+        if (CCDCaptureCombo->itemText(ccdNum).right(6) == QString("Guider"))
+        {
+            useGuideHead = true;
+            targetChip = currentCCD->getChip(ISD::CCDChip::GUIDE_CCD);
+        }
+        else
+        {
+            currentCCD = CCDs.at(ccdNum);
+            targetChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
+            useGuideHead = false;
+        }
+
+        if (currentCCD->hasCooler())
+        {
+
+            temperatureCheck->setEnabled(true);
+            temperatureIN->setEnabled(true);
+
+            if (currentCCD->getBaseDevice()->getPropertyPermission("CCD_TEMPERATURE") \
!= IP_RO) +            {
+                double min,max,step;
+                setTemperatureB->setEnabled(true);
+                temperatureIN->setReadOnly(false);
+                currentCCD->getMinMaxStep("CCD_TEMPERATURE", \
"CCD_TEMPERATURE_VALUE", &min, &max, &step); +                \
temperatureIN->setMinimum(min); +                temperatureIN->setMaximum(max);
+                temperatureIN->setSingleStep(1);
+            }
+            else
+            {
+                setTemperatureB->setEnabled(false);
+                temperatureIN->setReadOnly(true);
+            }
+
+            double temperature=0;
+            if (currentCCD->getTemperature(&temperature))
+            {
+                temperatureOUT->setText(QString::number(temperature, 'f', 2));
+                if (temperatureIN->cleanText().isEmpty())
+                    temperatureIN->setValue(temperature);
+            }
+        }
+        else
+        {
+            temperatureCheck->setEnabled(false);
+            temperatureIN->setEnabled(false);
+            temperatureIN->clear();
+            setTemperatureB->setEnabled(false);
+        }
+
+        updateFrameProperties();
+
+        QStringList frameTypes = targetChip->getFrameTypes();
+
+        frameTypeCombo->clear();
+
+        if (frameTypes.isEmpty())
+            frameTypeCombo->setEnabled(false);
+        else
+        {
+            frameTypeCombo->setEnabled(true);
+            frameTypeCombo->addItems(frameTypes);
+            frameTypeCombo->setCurrentIndex(targetChip->getFrameType());
+        }
+
+        QStringList isoList = targetChip->getISOList();
+        ISOCombo->clear();
+
+        if (isoList.isEmpty())
+        {
+            ISOCombo->setEnabled(false);
+            ISOLabel->setEnabled(false);
+        }
+        else
+        {
+            ISOCombo->setEnabled(true);
+            ISOLabel->setEnabled(true);
+            ISOCombo->addItems(isoList);
+            ISOCombo->setCurrentIndex(targetChip->getISOIndex());
+        }
+
+        connect(currentCCD, SIGNAL(numberUpdated(INumberVectorProperty*)), this, \
SLOT(processCCDNumber(INumberVectorProperty*)), Qt::UniqueConnection); +        \
connect(currentCCD, SIGNAL(newTemperatureValue(double)), this, \
SLOT(updateCCDTemperature(double)), Qt::UniqueConnection); +        \
connect(currentCCD, SIGNAL(newRemoteFile(QString)), this, \
SLOT(setNewRemoteFile(QString))); +    }
+}
+
+void Capture::updateFrameProperties(bool reset)
+{
+    int x,y,w,h;
+    int binx=1,biny=1;
+    double min,max,step;
+    int xstep=0, ystep=0;
+
+    QString frameProp = useGuideHead ? QString("GUIDER_FRAME") : \
QString("CCD_FRAME"); +    QString exposureProp = useGuideHead ? \
QString("GUIDER_EXPOSURE") : QString("CCD_EXPOSURE"); +    QString exposureElem = \
useGuideHead ? QString("GUIDER_EXPOSURE_VALUE") : QString("CCD_EXPOSURE_VALUE"); +    \
targetChip = useGuideHead ? currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) : \
currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD); +
+    frameWIN->setEnabled(targetChip->canSubframe());
+    frameHIN->setEnabled(targetChip->canSubframe());
+    frameXIN->setEnabled(targetChip->canSubframe());
+    frameYIN->setEnabled(targetChip->canSubframe());
+
+    binXIN->setEnabled(targetChip->canBin());
+    binYIN->setEnabled(targetChip->canBin());
+
+    if (currentCCD->getMinMaxStep(exposureProp, exposureElem, &min, &max, &step))
+    {
+        exposureIN->setMinimum(min);
+        exposureIN->setMaximum(max);
+        exposureIN->setSingleStep(step);
+    }
+
+    if (currentCCD->getMinMaxStep(frameProp, "WIDTH", &min, &max, &step))
+    {
+
+        if (min == max)
+            return;
+
+        if (step == 0)
+            xstep = (int) max * 0.05;
+        else
+            xstep = step;
+
+        if (min >= 0 && max > 0)
+        {
+            frameWIN->setMinimum(min);
+            frameWIN->setMaximum(max);
+            frameWIN->setSingleStep(xstep);
+        }
+    }
+    else
+        return;
+
+    if (currentCCD->getMinMaxStep(frameProp, "HEIGHT", &min, &max, &step))
+    {
+        if (min == max)
+            return;
+
+        if (step == 0)
+            ystep = (int) max * 0.05;
+        else
+            ystep = step;
+
+        if (min >= 0 && max > 0)
+        {
+            frameHIN->setMinimum(min);
+            frameHIN->setMaximum(max);
+            frameHIN->setSingleStep(ystep);
+        }
+    }
+    else
+        return;
+
+    if (currentCCD->getMinMaxStep(frameProp, "X", &min, &max, &step))
+    {
+        if (min == max)
+            return;
+
+        if (step == 0)
+            step = xstep;
+
+        if (min >= 0 && max > 0)
+        {
+            frameXIN->setMinimum(min);
+            frameXIN->setMaximum(max);
+            frameXIN->setSingleStep(step);
+        }
+    }
+    else
+        return;
+
+    if (currentCCD->getMinMaxStep(frameProp, "Y", &min, &max, &step))
+    {
+        if (min == max)
+            return;
+
+        if (step == 0)
+            step = ystep;
+
+        if (min >= 0 && max > 0)
+        {
+            frameYIN->setMinimum(min);
+            frameYIN->setMaximum(max);
+            frameYIN->setSingleStep(step);
+        }
+    }
+    else
+        return;
+
+    if (reset || frameSettings.contains(targetChip) == false)
+    {
+        QVariantMap settings;
+
+        settings["x"] = 0;
+        settings["y"] = 0;
+        settings["w"] = frameWIN->maximum();
+        settings["h"] = frameHIN->maximum();
+        settings["binx"] = 1;
+        settings["biny"] = 1;
+
+        frameSettings[targetChip] = settings;
+    }
+
+    if (frameSettings.contains(targetChip))
+    {
+        QVariantMap settings = frameSettings[targetChip];
+
+        if (targetChip->canBin())
+        {
+            targetChip->getMaxBin(&binx, &biny);
+            binXIN->setMaximum(binx);
+            binYIN->setMaximum(biny);
+
+            binXIN->setValue(settings["binx"].toInt());
+            binYIN->setValue(settings["biny"].toInt());
+        }
+        else
+        {
+            binXIN->setValue(1);
+            binYIN->setValue(1);
+        }
+
+        x = settings["x"].toInt();
+        y = settings["y"].toInt();
+        w = settings["w"].toInt();
+        h = settings["h"].toInt();
+
+        if (x >= 0)
+            frameXIN->setValue(x);
+        if (y >= 0)
+            frameYIN->setValue(y);
+        if (w > 0)
+            frameWIN->setValue(w);
+        if (h > 0)
+            frameHIN->setValue(h);
+    }
+}
+
+void Capture::processCCDNumber(INumberVectorProperty *nvp)
+{
+    if (currentCCD && ( (!strcmp(nvp->name, "CCD_FRAME") && useGuideHead == false) \
|| (!strcmp(nvp->name, "GUIDER_FRAME") && useGuideHead))) +        \
updateFrameProperties(); +}
+
+void Capture::resetFrame()
+{
+    targetChip = useGuideHead ? currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) : \
currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD); +    targetChip->resetFrame();
+    updateFrameProperties(true);
+}
+
+void Capture::syncFrameType(ISD::GDInterface *ccd)
+{
+    if (strcmp(ccd->getDeviceName(), CCDCaptureCombo->currentText().toLatin1()))
+        return;
+
+    ISD::CCDChip *tChip = NULL;
+    tChip = (static_cast<ISD::CCD *> (ccd) )->getChip(ISD::CCDChip::PRIMARY_CCD);
+
+    QStringList frameTypes = tChip->getFrameTypes();
+
+    frameTypeCombo->clear();
+
+    if (frameTypes.isEmpty())
+        frameTypeCombo->setEnabled(false);
+    else
+    {
+        frameTypeCombo->setEnabled(true);
+        frameTypeCombo->addItems(frameTypes);
+        frameTypeCombo->setCurrentIndex(tChip->getFrameType());
+    }
+
+
+}
+
+bool Capture::setFilter(QString device, int filterSlot)
+{
+    bool deviceFound=false;
+
+    for (int i=0; i < FilterCaptureCombo->count(); i++)
+        if (device == FilterCaptureCombo->itemText(i))
+        {
+            checkFilter(i);
+            deviceFound = true;
+            break;
+        }
+
+    if (deviceFound == false)
+        return false;
+
+    if (filterSlot < FilterCaptureCombo->count())
+        FilterCaptureCombo->setCurrentIndex(filterSlot);
+
+    return true;
+}
+
+void Capture::checkFilter(int filterNum)
+{
+
+    if (filterNum == -1)
+    {
+        filterNum = FilterCaptureCombo->currentIndex();
+        if (filterNum == -1)
+            return;
+    }
+
+
+    QStringList filterAlias = Options::filterAlias();
+
+    if (filterNum <= Filters.count())
+        currentFilter = Filters.at(filterNum);
+
+    syncFilterInfo();
+
+    FilterPosCombo->clear();
+
+    filterName   = currentFilter->getBaseDevice()->getText("FILTER_NAME");
+    filterSlot = currentFilter->getBaseDevice()->getNumber("FILTER_SLOT");
+
+    if (filterSlot == NULL)
+    {
+        KMessageBox::error(0, i18n("Unable to find FILTER_SLOT property in driver \
%1", currentFilter->getBaseDevice()->getDeviceName())); +        return;
+    }
+
+    for (int i=0; i < filterSlot->np[0].max; i++)
+    {
+        QString item;
+
+        if (filterName != NULL && (i < filterName->ntp))
+            item = filterName->tp[i].text;
+        else if (i < filterAlias.count() && filterAlias[i].isEmpty() == false)
+            item = filterAlias.at(i);
+        else
+            item = QString("Filter_%1").arg(i+1);
+
+        FilterPosCombo->addItem(item);
+
+    }
+
+    FilterPosCombo->setCurrentIndex( (int) filterSlot->np[0].value-1);
+
+    currentFilterPosition = (int) filterSlot->np[0].value;
+
+    if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || \
activeJob->getStatus() == SequenceJob::JOB_IDLE)) +        \
activeJob->setCurrentFilter(currentFilterPosition); +
+}
+
+void Capture::syncFilterInfo()
+{
+    if (currentCCD && currentFilter)
+    {
+        ITextVectorProperty *activeDevices = \
currentCCD->getBaseDevice()->getText("ACTIVE_DEVICES"); +        if (activeDevices)
+        {
+            IText *activeFilter = IUFindText(activeDevices, "ACTIVE_FILTER");
+            if (activeFilter && strcmp(activeFilter->text, \
currentFilter->getDeviceName())) +            {
+                IUSaveText(activeFilter, currentFilter->getDeviceName());
+                currentCCD->getDriverInfo()->getClientManager()->sendNewText(activeDevices);
 +            }
+        }
+    }
+}
+
+bool Capture::startNextExposure()
+{
+    if (state == CAPTURE_PAUSED)
+    {
+        pauseFunction = &Capture::startNextExposure;
+        appendLogText(i18n("Sequence paused."));
+        secondsLabel->setText(i18n("Paused..."));
+        return false;
+    }
+
+    if (seqDelay > 0)
+    {
+        secondsLabel->setText(i18n("Waiting..."));
+        state = CAPTURE_WAITING;
+        emit newStatus(Ekos::CAPTURE_WAITING);
+    }
+
+    seqTimer->start(seqDelay);
+
+    return true;
+}
+
+void Capture::newFITS(IBLOB *bp)
+{
+    ISD::CCDChip *tChip = NULL;
+
+    // If there is no active job, ignore
+    if (activeJob == NULL || meridianFlipStage >= MF_ALIGNING)
+        return;
+
+    if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
+    {
+        if (bp == NULL)
+        {
+            abort();
+            return;
+        }
+
+        if (!strcmp(bp->name, "CCD2"))
+            tChip = currentCCD->getChip(ISD::CCDChip::GUIDE_CCD);
+        else
+            tChip = currentCCD->getChip(ISD::CCDChip::PRIMARY_CCD);
+
+        if (tChip != targetChip)
+            return;
+
+        if (targetChip->getCaptureMode() == FITS_FOCUS || \
targetChip->getCaptureMode() == FITS_GUIDE) +            return;
+
+        // If this is a preview job, make sure to enable preview button after
+        // we receive the FITS
+        if (activeJob->isPreview() && previewB->isEnabled() == false)
+            previewB->setEnabled(true);
+
+        // If the FITS is not for our device, simply ignore
+        //if (QString(bp->bvp->device)  != currentCCD->getDeviceName() || \
(startB->isEnabled() && previewB->isEnabled())) +        if (QString(bp->bvp->device) \
!= currentCCD->getDeviceName() || state == CAPTURE_IDLE) +            return;
+
+        disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, \
SLOT(newFITS(IBLOB*))); +        disconnect(currentCCD, SIGNAL(newImage(QImage*, \
ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*))); +
+        if (useGuideHead == false && darkSubCheck->isChecked() && \
activeJob->isPreview()) +        {
+            FITSView *currentImage   = targetChip->getImage(FITS_NORMAL);
+            FITSData *darkData       = NULL;
+            uint16_t offsetX = activeJob->getSubX() / activeJob->getXBin();
+            uint16_t offsetY = activeJob->getSubY() / activeJob->getYBin();
+
+            darkData = DarkLibrary::Instance()->getDarkFrame(targetChip, \
activeJob->getExposure()); +
+            connect(DarkLibrary::Instance(), SIGNAL(darkFrameCompleted(bool)), this, \
SLOT(setCaptureComplete())); +            connect(DarkLibrary::Instance(), \
SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString))); +
+            if (darkData)
+                DarkLibrary::Instance()->subtract(darkData, currentImage, \
activeJob->getCaptureFilter(), offsetX, offsetY); +            else
+                DarkLibrary::Instance()->captureAndSubtract(targetChip, \
currentImage, activeJob->getExposure(), offsetX, offsetY); +
+            return;
+        }
+    }
+
+    setCaptureComplete();
+
+}
+
+bool Capture::setCaptureComplete()
+{
+    disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), \
this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState))); +    \
DarkLibrary::Instance()->disconnect(this); +    \
secondsLabel->setText(i18n("Complete.")); +
+    // If it was initially set as preview job
+    if (seqTotalCount <= 0)
+    {
+       jobs.removeOne(activeJob);
+       delete(activeJob);
+       // Reset active job pointer
+       activeJob = NULL;
+       abort();
+       return true;
+    }
+
+    if (state == CAPTURE_PAUSED)
+    {
+        pauseFunction = &Capture::setCaptureComplete;
+        appendLogText(i18n("Sequence paused."));
+        secondsLabel->setText(i18n("Paused..."));
+        return false;
+    }
+
+    if (activeJob->getFrameType() != FRAME_LIGHT)
+    {
+        if (processPostCaptureCalibrationStage() == false)
+            return true;
+
+            if (calibrationStage == CAL_CALIBRATION_COMPLETE)
+                calibrationStage = CAL_CAPTURING;
+    }
+
+    seqCurrentCount++;
+    activeJob->setCompleted(seqCurrentCount);
+    imgProgress->setValue(seqCurrentCount);
+
+    appendLogText(i18n("Received image %1 out of %2.", seqCurrentCount, \
seqTotalCount)); +
+    state = CAPTURE_IMAGE_RECEIVED;
+    emit newStatus(Ekos::CAPTURE_IMAGE_RECEIVED);
+
+    currentImgCountOUT->setText( QString::number(seqCurrentCount));
+
+    // if we're done
+    if (seqCurrentCount >= seqTotalCount)
+    {
+       processJobCompletion();
+       return true;
+    }
+
+    // Check if meridian condition is met
+    if (checkMeridianFlip())
+        return true;
+
+    // FIXME remove post capture script later
+    if (Options::postCaptureScript().isEmpty() == false)
+    {
+        postCaptureScript.start(Options::postCaptureScript());
+        appendLogText(i18n("Executing post capture script %1", \
Options::postCaptureScript())); +    }
+    else
+        resumeSequence();
+
+    return true;
+}
+
+void Capture::processJobCompletion()
+{
+    activeJob->done();
+
+    stop();
+
+    // Check if meridian condition is met
+    if (checkMeridianFlip())
+        return;
+
+    // Check if there are more pending jobs and execute them
+    if (resumeSequence())
+        return;
+    // Otherwise, we're done. We park if required and resume guiding if no parking \
is done and autoguiding was engaged before. +    else
+    {
+        KNotification::event( QLatin1String( "CaptureSuccessful"), i18n("CCD capture \
sequence completed")); +
+        abort();
+
+        state = CAPTURE_COMPLETE;
+        emit newStatus(Ekos::CAPTURE_COMPLETE);
+
+        if (parkCheck->isChecked() && currentTelescope && \
currentTelescope->canPark()) +        {
+            appendLogText(i18n("Parking telescope..."));
+            //emit mountParking();
+            currentTelescope->Park();
+            return;
+        }
+
+        //Resume guiding if it was suspended before
+        //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == \
guideChip) +        if (guideState == GUIDE_SUSPENDED && \
currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip) +            emit \
suspendGuiding(false); +    }
+
+}
+
+bool Capture::resumeSequence()
+{
+    if (state == CAPTURE_PAUSED)
+    {
+        pauseFunction = &Capture::resumeSequence;
+        appendLogText(i18n("Sequence paused."));
+        secondsLabel->setText(i18n("Paused..."));
+        return false;
+    }
+
+    // If seqTotalCount is zero, we have to find if there are more pending jobs in \
the queue +    if (seqTotalCount == 0)
+    {
+        SequenceJob *next_job = NULL;
+
+        foreach(SequenceJob *job, jobs)
+        {
+            if (job->getStatus() == SequenceJob::JOB_IDLE || job->getStatus() == \
SequenceJob::JOB_ABORTED) +            {
+                next_job = job;
+                break;
+            }
+        }
+
+        if (next_job)
+        {
+            prepareJob(next_job);
+
+            //Resume guiding if it was suspended before
+            //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == \
guideChip) +            if (guideState == GUIDE_SUSPENDED && \
currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip) +                emit \
suspendGuiding(false); +
+            return true;
+        }
+        else
+            return false;
+    }
+    // Otherwise, let's prepare for next exposure after making sure in-sequence \
focus and dithering are complete if applicable. +    else
+    {
+        isAutoFocus = (autofocusCheck->isEnabled() && autofocusCheck->isChecked() && \
HFRPixels->value() > 0); +        if (isAutoFocus)
+            autoFocusStatus = false;
+
+        // Reset HFR pixels to zero after merdian flip
+        if (isAutoFocus && meridianFlipStage != MF_NONE)
+        {
+            firstAutoFocus=true;
+            HFRPixels->setValue(fileHFR);
+        }
+
+        // If we suspended guiding due to primary chip download, resume guide chip \
guiding now +        if (guideState == GUIDE_SUSPENDED && \
currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip) +            emit \
suspendGuiding(false); +
+        //if (isAutoGuiding && guideDither && activeJob->getFrameType() == \
FRAME_LIGHT) +        if (guideState == GUIDE_GUIDING && guideDither && \
activeJob->getFrameType() == FRAME_LIGHT) +        {
+                secondsLabel->setText(i18n("Dithering..."));
+                //emit exposureComplete();
+
+                state = CAPTURE_DITHERING;
+                emit newStatus(Ekos::CAPTURE_DITHERING);
+        }
+        else if (isAutoFocus && activeJob->getFrameType() == FRAME_LIGHT)
+        {
+            secondsLabel->setText(i18n("Focusing..."));
+            emit checkFocus(HFRPixels->value());
+
+            state = CAPTURE_FOCUSING;
+            emit newStatus(Ekos::CAPTURE_FOCUSING);
+        }
+        else
+            startNextExposure();
+    }
+
+    return true;
+}
+
+void Capture::captureOne()
+{
+    if (currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
+    {
+        appendLogText(i18n("Cannot take preview image while CCD upload mode is set \
to local. Please change upload mode to client and try again.")); +        return;
+    }
+
+    addJob(true);
+
+    prepareJob(jobs.last());
+}
+
+void Capture::captureImage()
+{
+    seqTimer->stop();
+    //bool isDark=false;
+    SequenceJob::CAPTUREResult rc=SequenceJob::CAPTURE_OK;
+
+    if (focusState >= FOCUS_PROGRESS)
+    {
+        appendLogText(i18n("Cannot capture while focus module is busy."));
+        abort();
+        return;
+    }
+
+    //if (useGuideHead == false && darkSubCheck->isChecked() && calibrationState == \
CALIBRATE_NONE) +    //isDark = true;
+
+    if (filterSlot != NULL)
+    {
+        currentFilterPosition = (int) filterSlot->np[0].value;
+        activeJob->setCurrentFilter(currentFilterPosition);
+    }
+
+    if (currentCCD->hasCooler())
+    {
+        double temperature=0;
+        currentCCD->getTemperature(&temperature);
+        activeJob->setCurrentTemperature(temperature);
+    }
+
+    connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)), \
Qt::UniqueConnection); +    connect(currentCCD, SIGNAL(newImage(QImage*, \
ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*)), \
Qt::UniqueConnection); +
+    if (activeJob->getFrameType() == FRAME_FLAT)
+    {
+        // If we have to calibrate ADU levels, first capture must be preview and not \
in batch mode +        if (activeJob->isPreview() == false && \
activeJob->getFlatFieldDuration() == DURATION_ADU && calibrationStage == \
CAL_PRECAPTURE_COMPLETE) +        {
+            calibrationStage = CAL_CALIBRATION;
+            activeJob->setPreview(true);
+        }
+    }
+
+    if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
+        checkSeqBoundary(activeJob->getFITSDir());
+
+    state = CAPTURE_CAPTURING;
+
+    if (activeJob->isPreview() == false)
+        emit newStatus(Ekos::CAPTURE_CAPTURING);
+
+    if (frameSettings.contains(activeJob->getActiveChip()))
+    {
+        QVariantMap settings;
+        settings["x"]      = activeJob->getSubX();
+        settings["y"]      = activeJob->getSubY();
+        settings["w"]      = activeJob->getSubW();
+        settings["h"]      = activeJob->getSubH();
+        settings["binx"]   = activeJob->getXBin();
+        settings["biny"]   = activeJob->getYBin();
+
+        frameSettings[activeJob->getActiveChip()] = settings;
+    }
+
+    rc = activeJob->capture(darkSubCheck->isChecked() ? true : false);
+
+    switch (rc)
+    {
+    case SequenceJob::CAPTURE_OK:
+        connect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), \
this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)), \
Qt::UniqueConnection); +        appendLogText(i18n("Capturing image..."));
+        break;
+
+    case SequenceJob::CAPTURE_FRAME_ERROR:
+        appendLogText(i18n("Failed to set sub frame."));
+        abort();
+        break;
+
+    case SequenceJob::CAPTURE_BIN_ERROR:
+        appendLogText(i18n("Failed to set binning."));
+        abort();
+        break;
+
+    case SequenceJob::CAPTURE_FILTER_BUSY:
+        // Try again in 1 second if filter is busy
+        QTimer::singleShot(1000, this, SLOT(captureImage()));
+        break;
+
+    case SequenceJob::CAPTURE_FOCUS_ERROR:
+        appendLogText(i18n("Cannot capture while focus module is busy."));
+        abort();
+        break;
+
+    }
+}
+
+bool Capture::resumeCapture()
+{
+    if (state == CAPTURE_PAUSED)
+    {
+        pauseFunction = &Capture::resumeCapture;
+        appendLogText(i18n("Sequence paused."));
+        secondsLabel->setText(i18n("Paused..."));
+        return false;
+    }
+
+    appendLogText(i18n("Dither complete."));
+
+    if (isAutoFocus && autoFocusStatus == false)
+    {
+        secondsLabel->setText(i18n("Focusing..."));
+        emit checkFocus(HFRPixels->value());
+        state = CAPTURE_FOCUSING;
+        emit newStatus(Ekos::CAPTURE_FOCUSING);
+        return true;
+    }
+
+    startNextExposure();
+
+    return true;
+}
+
+/*******************************************************************************/
+/* Update the prefix for the sequence of images to be captured                 */
+/*******************************************************************************/
+void Capture::updateSequencePrefix( const QString &newPrefix, const QString &dir)
+{
+    //static QString lastDir=QDir::homePath();
+
+    seqPrefix = newPrefix;
+
+    // If it doesn't exist, create it
+    QDir().mkpath(dir);
+
+    /*if (dir != lastDir)
+    {
+        seqWatcher->removeDir(lastDir);
+        lastDir = dir;
+    }
+
+    seqWatcher->addDir(dir, KDirWatch::WatchFiles);*/
+
+    nextSequenceID = 1;
+
+    //checkSeqBoundary(dir);
+}
+
+/*void Capture::checkSeqFile(const QString &path)
+{
+    checkSeqBoundary(QFileInfo(path).absolutePath());
+}*/
+
+/*******************************************************************************/
+/* Determine the next file number sequence. That is, if we have file1.png      */
+/* and file2.png, then the next sequence should be file3.png		       */
+/*******************************************************************************/
+void Capture::checkSeqBoundary(const QString &path)
+{
+    int newFileIndex=-1;
+    QString tempName;
+    seqFileCount=0;
+
+    // No updates during meridian flip
+    if (meridianFlipStage >= MF_ALIGNING)
+        return;
+
+    QDirIterator it(path, QDir::Files);
+
+    while (it.hasNext())
+    {
+        tempName = it.next();
+        QFileInfo info(tempName);
+        tempName = info.baseName();
+
+        // find the prefix first
+        if (tempName.startsWith(seqPrefix) == false)
+            continue;
+
+        seqFileCount++;
+
+        tempName = tempName.remove(seqPrefix);
+
+        if (tempName.startsWith("_"))
+            tempName = tempName.remove(0, 1);
+
+        bool indexOK = false;
+        newFileIndex = tempName.mid(0, 3).toInt(&indexOK);
+
+        if (indexOK && newFileIndex >= nextSequenceID)
+            nextSequenceID = newFileIndex + 1;
+    }
+
+    currentCCD->setNextSequenceID(nextSequenceID);
+}
+
+void Capture::appendLogText(const QString &text)
+{
+    logText.insert(0, i18nc("log entry; %1 is the date, %2 is the text", "%1 %2", \
QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"), text)); +
+    if (Options::captureLogging())
+        qDebug() << "Capture: " << text;
+
+    emit newLog();
+}
+
+void Capture::clearLog()
+{
+    logText.clear();
+    emit newLog();
+}
+
+void Capture::updateCaptureProgress(ISD::CCDChip * tChip, double value, IPState \
state) +{
+
+    if (targetChip != tChip || targetChip->getCaptureMode() != FITS_NORMAL || \
meridianFlipStage >= MF_ALIGNING) +        return;
+
+    exposeOUT->setText(QString::number(value, 'd', 2));
+
+    if (activeJob)
+        activeJob->setExposeLeft(value);
+
+    if (activeJob && state == IPS_ALERT)
+    {
+        int retries = activeJob->getCaptureRetires()+1;
+
+        activeJob->setCaptureRetires(retries);
+
+        appendLogText(i18n("Capture failed."));
+
+        if (retries == 3)
+        {
+            abort();
+            return;
+        }
+
+        appendLogText(i18n("Restarting capture attempt #%1", retries));
+
+        nextSequenceID = 1;
+
+        captureImage();
+        return;
+    }
+
+    if (value == 0)
+    {
+        activeJob->setCaptureRetires(0);
+
+        if (currentCCD && currentCCD->getUploadMode() == ISD::CCD::UPLOAD_LOCAL)
+        {
+            if (activeJob && activeJob->getStatus() == SequenceJob::JOB_BUSY && \
activeJob->getExposeLeft() == 0 && state == IPS_OK) +            {
+               newFITS(0);
+               return;
+            }
+        }
+
+        //if (isAutoGuiding && Options::useEkosGuider() && \
currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip) +        if (guideState == \
GUIDE_GUIDING && Options::useEkosGuider() && \
currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == guideChip) +        {
+            if (Options::captureLogging())
+                qDebug() << "Capture: Autoguiding suspended until primary CCD chip \
completes downloading..."; +            emit suspendGuiding(true);
+        }
+
+           secondsLabel->setText(i18n("Downloading..."));
+
+            //disconnect(currentCCD, \
SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, \
SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState))); +    }
+    // JM: Don't change to i18np, value is DOUBLE, not Integer.
+    else if (value <= 1)
+        secondsLabel->setText(i18n("second left"));
+    else
+        secondsLabel->setText(i18n("seconds left"));
+}
+
+void Capture::updateCCDTemperature(double value)
+{
+    if (temperatureCheck->isEnabled() == false)
+        checkCCD();
+
+    temperatureOUT->setText(QString::number(value, 'f', 2));
+
+    if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || \
activeJob->getStatus() == SequenceJob::JOB_IDLE)) +        \
activeJob->setCurrentTemperature(value); +}
+
+void Capture::addJob(bool preview)
+{
+    SequenceJob *job = NULL;
+    QString imagePrefix;
+
+    if (preview == false && darkSubCheck->isChecked())
+    {
+        KMessageBox::error(this, i18n("Auto dark subtract is not supported in batch \
mode.")); +        return;
+    }
+
+    if (jobUnderEdit)
+        job = jobs.at(queueTable->currentRow());
+    else
+        job = new SequenceJob();
+
+    if (job == NULL)
+    {
+        qWarning() << "Job is NULL!" << endl;
+        return;
+    }
+
+    if (ISOCombo->isEnabled())
+        job->setISOIndex(ISOCombo->currentIndex());
+
+    job->setPreview(preview);
+
+    if (temperatureIN->isEnabled())
+    {
+        double currentTemperature;
+        currentCCD->getTemperature(&currentTemperature);
+        job->setEnforceTemperature(temperatureCheck->isChecked());
+        job->setTargetTemperature(temperatureIN->value());
+        job->setCurrentTemperature(currentTemperature);
+    }
+
+    job->setCaptureFilter((FITSScale)  filterCombo->currentIndex());
+
+    job->setFlatFieldDuration(flatFieldDuration);
+    job->setFlatFieldSource(flatFieldSource);
+    job->setPreMountPark(preMountPark);
+    job->setPreDomePark(preDomePark);
+    job->setWallCoord(wallCoord);
+    job->setTargetADU(targetADU);
+
+    imagePrefix = prefixIN->text();
+
+    constructPrefix(imagePrefix);
+
+    job->setPrefixSettings(prefixIN->text(), filterCheck->isChecked(), \
expDurationCheck->isChecked(), ISOCheck->isChecked()); +    \
job->setFrameType(frameTypeCombo->currentIndex(), frameTypeCombo->currentText()); +   \
job->setFullPrefix(imagePrefix); +
+    if (filterSlot != NULL && currentFilter != NULL)
+       job->setTargetFilter(FilterPosCombo->currentIndex()+1, \
FilterPosCombo->currentText()); +
+    job->setExposure(exposureIN->value());
+
+    job->setCount(countIN->value());
+
+    job->setBin(binXIN->value(), binYIN->value());
+
+    job->setDelay(delayIN->value() * 1000);		/* in ms */
+
+    job->setActiveChip(targetChip);
+    job->setActiveCCD(currentCCD);
+    job->setActiveFilter(currentFilter);
+
+    job->setFrame(frameXIN->value(), frameYIN->value(), frameWIN->value(), \
frameHIN->value()); +
+    job->setRootFITSDir(fitsDir->text());
+
+    if (jobUnderEdit == false)
+    {
+        jobs.append(job);
+
+        // Nothing more to do if preview
+        if (preview)
+            return;
+    }
+
+    QString finalFITSDir = fitsDir->text();
+
+    if (targetName.isEmpty())
+        finalFITSDir += QLatin1Literal("/") + frameTypeCombo->currentText();
+    else
+        finalFITSDir += QLatin1Literal("/") + targetName + QLatin1Literal("/") + \
frameTypeCombo->currentText(); +    if ( (job->getFrameType() == FRAME_LIGHT || \
job->getFrameType() == FRAME_FLAT) && job->getFilterName().isEmpty() == false) +      \
finalFITSDir += QLatin1Literal("/") + job->getFilterName(); +
+    job->setFITSDir(finalFITSDir);
+
+    int currentRow = 0;
+    if (jobUnderEdit == false)
+    {
+        currentRow = queueTable->rowCount();
+        queueTable->insertRow(currentRow);
+    }
+    else
+        currentRow = queueTable->currentRow();
+
+    QTableWidgetItem *status = jobUnderEdit ? queueTable->item(currentRow, 0) : new \
QTableWidgetItem(); +    status->setText(job->getStatusString());
+    status->setTextAlignment(Qt::AlignHCenter);
+    status->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+    job->setStatusCell(status);
+
+    QTableWidgetItem *filter = jobUnderEdit ? queueTable->item(currentRow, 1) : new \
QTableWidgetItem(); +    filter->setText("--");
+    if (frameTypeCombo->currentText().compare("Bias", Qt::CaseInsensitive) &&
+            frameTypeCombo->currentText().compare("Dark", Qt::CaseInsensitive) &&
+            FilterPosCombo->count() > 0)
+        filter->setText(FilterPosCombo->currentText());
+
+    filter->setTextAlignment(Qt::AlignHCenter);
+    filter->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+    QTableWidgetItem *type = jobUnderEdit ? queueTable->item(currentRow, 2) : new \
QTableWidgetItem(); +    type->setText(frameTypeCombo->currentText());
+    type->setTextAlignment(Qt::AlignHCenter);
+    type->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+    QTableWidgetItem *bin = jobUnderEdit ? queueTable->item(currentRow, 3) : new \
QTableWidgetItem(); +    \
bin->setText(QString("%1x%2").arg(binXIN->value()).arg(binYIN->value())); +    \
bin->setTextAlignment(Qt::AlignHCenter); +    bin->setFlags(Qt::ItemIsSelectable | \
Qt::ItemIsEnabled); +
+    QTableWidgetItem *exp = jobUnderEdit ? queueTable->item(currentRow, 4) : new \
QTableWidgetItem(); +    exp->setText(QString::number(exposureIN->value()));
+    exp->setTextAlignment(Qt::AlignHCenter);
+    exp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+    QTableWidgetItem *iso = jobUnderEdit ? queueTable->item(currentRow, 5) : new \
QTableWidgetItem(); +    if (ISOCombo->currentIndex() != -1)
+        iso->setText(ISOCombo->currentText());
+    else
+        iso->setText("--");
+    iso->setTextAlignment(Qt::AlignHCenter);
+    iso->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+
+    QTableWidgetItem *count = jobUnderEdit ? queueTable->item(currentRow, 6) : new \
QTableWidgetItem(); +    count->setText(QString::number(countIN->value()));
+    count->setTextAlignment(Qt::AlignHCenter);
+    count->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
+    if (jobUnderEdit == false)
+    {
+        queueTable->setItem(currentRow, 0, status);
+        queueTable->setItem(currentRow, 1, filter);
+        queueTable->setItem(currentRow, 2, type);
+        queueTable->setItem(currentRow, 3, bin);
+        queueTable->setItem(currentRow, 4, exp);
+        queueTable->setItem(currentRow, 5, iso);
+        queueTable->setItem(currentRow, 6, count);
+    }
+
+    removeFromQueueB->setEnabled(true);
+
+    if (queueTable->rowCount() > 0)
+    {
+        queueSaveAsB->setEnabled(true);
+        queueSaveB->setEnabled(true);
+        resetB->setEnabled(true);
+        mDirty = true;
+    }
+
+    if (queueTable->rowCount() > 1)
+    {
+        queueUpB->setEnabled(true);
+        queueDownB->setEnabled(true);
+    }
+
+    if (jobUnderEdit)
+    {
+        jobUnderEdit = false;
+        resetJobEdit();
+        appendLogText(i18n("Job #%1 changes applied.", currentRow+1));
+    }
+
+}
+
+void Capture::removeJob()
+{
+    if (jobUnderEdit)
+    {
+        resetJobEdit();
+        return;
+    }
+
+    int currentRow = queueTable->currentRow();
+
+    if (currentRow < 0)
+    {
+        currentRow = queueTable->rowCount()-1;
+        if (currentRow < 0)
+            return;
+    }
+
+    queueTable->removeRow(currentRow);
+
+    SequenceJob *job = jobs.at(currentRow);
+    jobs.removeOne(job);
+    delete (job);
+
+    if (queueTable->rowCount() == 0)
+        removeFromQueueB->setEnabled(false);
+
+    if (queueTable->rowCount() == 1)
+    {
+        queueUpB->setEnabled(false);
+        queueDownB->setEnabled(false);
+    }
+
+    for (int i=0; i < jobs.count(); i++)
+        jobs.at(i)->setStatusCell(queueTable->item(i, 0));
+
+    queueTable->selectRow(queueTable->currentRow());
+
+    if (queueTable->rowCount() == 0)
+    {
+        queueSaveAsB->setEnabled(false);
+        queueSaveB->setEnabled(false);
+        resetB->setEnabled(false);
+    }
+
+    mDirty = true;
+
+
+}
+
+void Capture::moveJobUp()
+{
+    int currentRow = queueTable->currentRow();
+
+    int columnCount = queueTable->columnCount();
+
+    if (currentRow <= 0 || queueTable->rowCount() == 1)
+        return;
+
+    int destinationRow = currentRow - 1;
+
+    for (int i=0; i < columnCount; i++)
+    {
+        QTableWidgetItem *downItem = queueTable->takeItem(currentRow, i);
+        QTableWidgetItem *upItem   = queueTable->takeItem(destinationRow, i);
+
+        queueTable->setItem(destinationRow, i, downItem);
+        queueTable->setItem(currentRow, i, upItem);
+    }
+
+    SequenceJob *job = jobs.takeAt(currentRow);
+
+    jobs.removeOne(job);
+    jobs.insert(destinationRow, job);
+
+    queueTable->selectRow(destinationRow);
+
+    for (int i=0; i < jobs.count(); i++)
+      jobs.at(i)->setStatusCell(queueTable->item(i, 0));
+
+
+    mDirty = true;
+
+}
+
+void Capture::moveJobDown()
+{
+    int currentRow = queueTable->currentRow();
+
+    int columnCount = queueTable->columnCount();
+
+    if (currentRow < 0 || queueTable->rowCount() == 1 || (currentRow+1) == \
queueTable->rowCount() ) +        return;
+
+    int destinationRow = currentRow + 1;
+
+    for (int i=0; i < columnCount; i++)
+    {
+        QTableWidgetItem *downItem = queueTable->takeItem(currentRow, i);
+        QTableWidgetItem *upItem   = queueTable->takeItem(destinationRow, i);
+
+        queueTable->setItem(destinationRow, i, downItem);
+        queueTable->setItem(currentRow, i, upItem);
+    }
+
+    SequenceJob *job = jobs.takeAt(currentRow);
+
+    jobs.removeOne(job);
+    jobs.insert(destinationRow, job);
+
+    queueTable->selectRow(destinationRow);
+
+    for (int i=0; i < jobs.count(); i++)
+        jobs.at(i)->setStatusCell(queueTable->item(i, 0));
+
+    mDirty = true;
+
+}
+
+void Capture::setBusy(bool enable)
+{
+    isBusy = enable;
+
+    enable ? pi->startAnimation() : pi->stopAnimation();
+    previewB->setEnabled(!enable);
+    //startB->setEnabled(!enable);
+    //stopB->setEnabled(enable);
+}
+
+void Capture::prepareJob(SequenceJob *job)
+{
+    activeJob = job;
+
+    // Just notification of active job stating up
+    emit newImage(NULL, activeJob);
+
+    connect(job, SIGNAL(checkFocus()), this, SLOT(startPostFilterAutoFocus()));
+
+    // Reset calibration stage
+    if (calibrationStage == CAL_CAPTURING)
+    {
+        if (job->getFrameType() != FRAME_LIGHT)
+            calibrationStage = CAL_PRECAPTURE_COMPLETE;
+        else
+            calibrationStage = CAL_NONE;
+    }
+
+    if (currentFilterPosition > 0)
+    {
+        // If we haven't performed a single autofocus yet, we stop
+        if (Options::autoFocusOnFilterChange() && (isAutoFocus == false && \
firstAutoFocus == true)) +        {
+            appendLogText(i18n("Manual focusing post filter change is not supported. \
Run Autofocus process before trying again.")); +            abort();
+            return;
+        }
+
+        activeJob->setCurrentFilter(currentFilterPosition);
+
+        if (currentFilterPosition != activeJob->getTargetFilter())
+        {
+            appendLogText(i18n("Changing filter to %1...", \
FilterPosCombo->itemText(activeJob->getTargetFilter()-1))); +            \
secondsLabel->setText(i18n("Set filter...")); +
+            if (activeJob->isPreview() == false)
+            {
+                state = CAPTURE_CHANGING_FILTER;
+                emit newStatus(Ekos::CAPTURE_CHANGING_FILTER);
+            }
+
+            setBusy(true);
+
+        }
+    }
+
+    if (currentCCD->hasCooler() && activeJob->getEnforceTemperature())
+    {
+        if (activeJob->getCurrentTemperature() != INVALID_TEMPERATURE &&
+                fabs(activeJob->getCurrentTemperature() - \
activeJob->getTargetTemperature()) > Options::maxTemperatureDiff()) +        {
+            appendLogText(i18n("Setting temperature to %1 C...", \
activeJob->getTargetTemperature())); +            secondsLabel->setText(i18n("Set %1 \
C...", activeJob->getTargetTemperature())); +
+            if (activeJob->isPreview() == false)
+            {
+                state = CAPTURE_SETTING_TEMPERATURE;
+                emit newStatus(Ekos::CAPTURE_SETTING_TEMPERATURE);
+            }
+
+            setBusy(true);
+        }
+    }
+
+    connect(activeJob, SIGNAL(prepareComplete()), this, SLOT(executeJob()));
+
+    job->prepareCapture();
+}
+
+void Capture::executeJob()
+{
+    activeJob->disconnect(this);
+
+    if (activeJob->isPreview())
+        seqTotalCount = -1;
+    else
+        seqTotalCount = activeJob->getCount();
+
+    seqDelay = activeJob->getDelay();
+
+    seqCurrentCount = activeJob->getCompleted();
+
+    if (activeJob->isPreview() == false)
+    {
+        fullImgCountOUT->setText( QString::number(seqTotalCount));
+        currentImgCountOUT->setText(QString::number(seqCurrentCount));
+
+        // set the progress info
+        imgProgress->setEnabled(true);
+        imgProgress->setMaximum(seqTotalCount);
+        imgProgress->setValue(seqCurrentCount);
+
+        if (currentCCD->getUploadMode() != ISD::CCD::UPLOAD_LOCAL)
+            updateSequencePrefix(activeJob->getPrefix(), activeJob->getFITSDir());
+    }
+
+    // We check if the job is already fully or partially complete by checking how \
many files of its type exist on the file system unless ignoreJobProgress is set to \
true +    if (ignoreJobProgress == false && Options::rememberJobProgress() && \
activeJob->isPreview() == false) +    {
+        checkSeqBoundary(activeJob->getFITSDir());
+
+        if (seqFileCount > 0)
+        {
+            // Fully complete
+            if (seqFileCount >= seqTotalCount)
+            {
+                seqCurrentCount=seqTotalCount;
+                activeJob->setCompleted(seqCurrentCount);
+                imgProgress->setValue(seqCurrentCount);
+                processJobCompletion();
+                return;
+            }
+
+            // Partially complete
+            seqCurrentCount=seqFileCount;
+            activeJob->setCompleted(seqCurrentCount);
+            currentImgCountOUT->setText( QString::number(seqCurrentCount));
+            imgProgress->setValue(seqCurrentCount);
+
+            // Emit progress update
+            emit newImage(NULL, activeJob);
+        }
+    }
+
+    // Update button status
+    setBusy(true);
+
+    useGuideHead = (activeJob->getActiveChip()->getType() == \
ISD::CCDChip::PRIMARY_CCD) ? false : true; +
+    // Check flat field frame requirements
+    if (activeJob->getFrameType() != FRAME_LIGHT && activeJob->isPreview() == false)
+    {
+        // Make sure we don't have any pre-capture pending jobs for flat frames
+        IPState rc = processPreCaptureCalibrationStage();
+
+        if (rc == IPS_ALERT)
+            return;
+        else if (rc == IPS_BUSY)
+        {
+            secondsLabel->clear();
+            QTimer::singleShot(1000, this, SLOT(executeJob()));
+            return;
+        }
+    }
+
+    syncGUIToJob(activeJob);
+
+    captureImage();
+}
+
+void Capture::setGuideDeviation(double delta_ra, double delta_dec)
+{
+    if (guideDeviationCheck->isChecked() == false || activeJob == NULL)
+        return;
+
+    // If guiding is started after a meridian flip we will start getting guide \
deviations again +    // if the guide deviations are within our limits, we resume the \
sequence +    if (meridianFlipStage == MF_GUIDING)
+    {
+        double deviation_rms = sqrt(delta_ra*delta_ra + delta_dec*delta_dec);
+        if (deviation_rms < guideDeviation->value())
+        {
+                initialHA = getCurrentHA();
+                appendLogText(i18n("Post meridian flip calibration completed \
successfully.")); +                resumeSequence();
+                // N.B. Set meridian flip stage AFTER resumeSequence() always
+                meridianFlipStage = MF_NONE;
+                return;
+        }
+    }
+
+    // We don't enforce limit on previews
+    if (activeJob->isPreview() || activeJob->getExposeLeft() == 0)
+        return;
+
+    double deviation_rms = sqrt(delta_ra*delta_ra + delta_dec*delta_dec);
+
+    QString deviationText = QString("%1").arg(deviation_rms, 0, 'g', 3);
+
+    if (activeJob->getStatus() == SequenceJob::JOB_BUSY)
+    {
+        if (deviation_rms > guideDeviation->value())
+        {
+            // Ignore spikes ONCE
+            if (spikeDetected == false)
+            {
+                spikeDetected = true;
+                return;
+            }
+
+            spikeDetected = false;
+            deviationDetected = true;
+            appendLogText(i18n("Guiding deviation %1 exceeded limit value of %2 \
arcsecs, aborting exposure.", deviationText, guideDeviation->value())); +            \
abort(); +        }
+        return;
+    }
+
+    if (activeJob->getStatus() == SequenceJob::JOB_ABORTED && deviationDetected)
+    {
+        if (deviation_rms <= guideDeviation->value())
+        {
+            if (seqDelay == 0)
+                appendLogText(i18n("Guiding deviation %1 is now lower than limit \
value of %2 arcsecs, resuming exposure.", deviationText, guideDeviation->value())); + \
else +                appendLogText(i18n("Guiding deviation %1 is now lower than \
limit value of %2 arcsecs, resuming exposure in %3 seconds.", deviationText, \
guideDeviation->value(), seqDelay/1000.0)); +
+            activeJob = NULL;
+
+            QTimer::singleShot(seqDelay, this, SLOT(start()));
+            return;
+        }
+    }
+}
+
+void Capture::setGuideDither(bool enable)
+{
+    guideDither = enable;
+}
+
+void Capture::setFocusStatus(FocusState state)
+{
+    focusState = state;
+
+    if (focusState > FOCUS_ABORTED)
+        return;
+
+    if (focusState == FOCUS_COMPLETE)
+    {
+        autofocusCheck->setEnabled(true);
+        HFRPixels->setEnabled(true);
+        if (focusHFR > 0 && firstAutoFocus && HFRPixels->value() == 0 && fileHFR == \
0) +        {
+           firstAutoFocus = false;
+           // Add 2.5% to the automatic initial HFR value to allow for minute \
changes in HFR without need to refocus +           // in case in-sequence-focusing is \
used. +           HFRPixels->setValue(focusHFR + (focusHFR * 0.025));
+        }
+    }
+
+    if (activeJob && (activeJob->getStatus() == SequenceJob::JOB_ABORTED || \
activeJob->getStatus() == SequenceJob::JOB_IDLE)) +    {
+        if (focusState == FOCUS_COMPLETE)
+        {
+            HFRPixels->setValue(focusHFR+ (focusHFR * 0.025));
+            appendLogText(i18n("Focus complete."));
+        }
+        else
+        {
+            appendLogText(i18n("Autofocus failed. Aborting exposure..."));
+            secondsLabel->setText("");
+            abort();
+        }
+
+        activeJob->setFilterPostFocusReady(focusState == FOCUS_COMPLETE);
+        return;
+    }
+
+    if (isAutoFocus && activeJob && activeJob->getStatus() == SequenceJob::JOB_BUSY)
+    {
+        if (focusState == FOCUS_COMPLETE)
+        {
+            appendLogText(i18n("Focus complete."));
+            startNextExposure();
+        }
+        else
+        {
+            appendLogText(i18n("Autofocus failed. Aborting exposure..."));
+            secondsLabel->setText("");
+            abort();
+        }
+    }
+}
+
+void Capture::setTelescope(ISD::GDInterface *newTelescope)
+{
+    currentTelescope = static_cast<ISD::Telescope*> (newTelescope);
+
+    connect(currentTelescope, SIGNAL(numberUpdated(INumberVectorProperty*)), this, \
SLOT(processTelescopeNumber(INumberVectorProperty*)), Qt::UniqueConnection); +
+    meridianCheck->setEnabled(true);
+    meridianHours->setEnabled(true);
+
+    syncTelescopeInfo();
+}
+
+void Capture::syncTelescopeInfo()
+{
+    if (currentCCD && currentTelescope && currentTelescope->isConnected())
+    {
+        parkCheck->setEnabled(currentTelescope->canPark());
+
+        ITextVectorProperty *activeDevices = \
currentCCD->getBaseDevice()->getText("ACTIVE_DEVICES"); +        if (activeDevices)
+        {
+            IText *activeTelescope = IUFindText(activeDevices, "ACTIVE_TELESCOPE");
+            if (activeTelescope)
+            {
+                IUSaveText(activeTelescope, currentTelescope->getDeviceName());
+
+                currentCCD->getDriverInfo()->getClientManager()->sendNewText(activeDevices);
 +            }
+        }
+    }
+}
+
+void Capture::saveFITSDirectory()
+{
+    QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18n("FITS \
Save Directory"), dirPath.toLocalFile()); +
+    if (dir.isEmpty())
+        return;
+
+    fitsDir->setText(dir);
+
+}
+
+void Capture::loadSequenceQueue()
+{
+    QUrl fileURL = QFileDialog::getOpenFileUrl(KStars::Instance(), i18n("Open Ekos \
Sequence Queue"), dirPath, "Ekos Sequence Queue (*.esq)"); +    if \
(fileURL.isEmpty()) +        return;
+
+    if (fileURL.isValid() == false)
+    {
+       QString message = i18n( "Invalid URL: %1", fileURL.toLocalFile() );
+       KMessageBox::sorry( 0, message, i18n( "Invalid URL" ) );
+       return;
+    }
+
+    dirPath = QUrl(fileURL.url(QUrl::RemoveFilename));
+
+    loadSequenceQueue(fileURL.toLocalFile());
+
+}
+
+bool Capture::loadSequenceQueue(const QString &fileURL)
+{
+    QFile sFile;
+    sFile.setFileName(fileURL);
+
+    if ( !sFile.open( QIODevice::ReadOnly))
+    {
+        QString message = i18n( "Unable to open file %1",  fileURL);
+        KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
+        return false;
+    }
+
+    //QTextStream instream(&sFile);
+
+    qDeleteAll(jobs);
+    jobs.clear();
+    while (queueTable->rowCount() > 0)
+        queueTable->removeRow(0);
+
+    LilXML *xmlParser = newLilXML();
+    char errmsg[MAXRBUF];
+    XMLEle *root = NULL;
+    XMLEle *ep;
+    char c;
+
+    while ( sFile.getChar(&c))
+    {
+        root = readXMLEle(xmlParser, c, errmsg);
+
+        if (root)
+        {
+             for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
+             {
+                 if (!strcmp(tagXMLEle(ep), "GuideDeviation"))
+                 {
+                      if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
+                      {
+                         guideDeviationCheck->setChecked(true);
+                         guideDeviation->setValue(atof(pcdataXMLEle(ep)));
+                      }
+                     else
+                         guideDeviationCheck->setChecked(false);
+
+                 }
+                 else if (!strcmp(tagXMLEle(ep), "Autofocus"))
+                 {
+                      if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
+                      {
+                         autofocusCheck->setChecked(true);
+                         float HFRValue = atof(pcdataXMLEle(ep));
+                         if (HFRValue > 0)
+                         {
+                            fileHFR = HFRValue;
+                            HFRPixels->setValue(HFRValue);
+                         }
+                         else
+                             fileHFR=0;
+                      }
+                     else
+                         autofocusCheck->setChecked(false);
+
+                 }
+                 else if (!strcmp(tagXMLEle(ep), "MeridianFlip"))
+                 {
+                      if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
+                      {
+                         meridianCheck->setChecked(true);
+                         meridianHours->setValue(atof(pcdataXMLEle(ep)));
+                      }
+                     else
+                         meridianCheck->setChecked(false);
+
+                 }
+                 else if (!strcmp(tagXMLEle(ep), "Park"))
+                 {
+                      if (!strcmp(findXMLAttValu(ep, "enabled"), "true"))
+                         parkCheck->setChecked(true);
+                     else
+                         parkCheck->setChecked(false);
+
+                 }
+                 else
+                 {
+                     processJobInfo(ep);
+                 }
+
+             }
+             delXMLEle(root);
+        }
+        else if (errmsg[0])
+        {
+            appendLogText(QString(errmsg));
+            delLilXML(xmlParser);
+            return false;
+        }
+    }
+
+    sequenceURL = QUrl::fromLocalFile(fileURL);
+    mDirty = false;
+    delLilXML(xmlParser);
+
+    if (Options::rememberJobProgress())
+        ignoreJobProgress = false;
+
+    return true;
+
+}
+
+bool Capture::processJobInfo(XMLEle *root)
+{
+
+    XMLEle *ep;
+    XMLEle *subEP;
+
+    for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
+    {
+        if (!strcmp(tagXMLEle(ep), "Exposure"))
+            exposureIN->setValue(atof(pcdataXMLEle(ep)));
+        else if (!strcmp(tagXMLEle(ep), "Binning"))
+        {
+            subEP = findXMLEle(ep, "X");
+            if (subEP)
+                binXIN->setValue(atoi(pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "Y");
+            if (subEP)
+                binYIN->setValue(atoi(pcdataXMLEle(subEP)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Frame"))
+        {
+            subEP = findXMLEle(ep, "X");
+            if (subEP)
+                frameXIN->setValue(atoi(pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "Y");
+            if (subEP)
+                frameYIN->setValue(atoi(pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "W");
+            if (subEP)
+                frameWIN->setValue(atoi(pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "H");
+            if (subEP)
+                frameHIN->setValue(atoi(pcdataXMLEle(subEP)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Temperature"))
+        {
+            if (temperatureIN->isEnabled())
+                temperatureIN->setValue(atof(pcdataXMLEle(ep)));
+
+            // If force attribute exist, we change temperatureCheck, otherwise do \
nothing. +            if (!strcmp(findXMLAttValu(ep, "force"), "true"))
+                temperatureCheck->setChecked(true);
+            else if (!strcmp(findXMLAttValu(ep, "force"), "false"))
+                temperatureCheck->setChecked(false);
+
+        }
+        else if (!strcmp(tagXMLEle(ep), "Filter"))
+        {
+            FilterPosCombo->setCurrentIndex(atoi(pcdataXMLEle(ep))-1);
+        }
+        else if (!strcmp(tagXMLEle(ep), "Type"))
+        {
+            frameTypeCombo->setCurrentText(pcdataXMLEle(ep));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Prefix"))
+        {
+            subEP = findXMLEle(ep, "RawPrefix");
+            if (subEP)
+                prefixIN->setText(pcdataXMLEle(subEP));
+            subEP = findXMLEle(ep, "FilterEnabled");
+            if (subEP)
+                filterCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "ExpEnabled");
+            if (subEP)
+                expDurationCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
+            subEP = findXMLEle(ep, "TimeStampEnabled");
+            if (subEP)
+                ISOCheck->setChecked( !strcmp("1", pcdataXMLEle(subEP)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Count"))
+        {
+            countIN->setValue(atoi(pcdataXMLEle(ep)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Delay"))
+        {
+            delayIN->setValue(atoi(pcdataXMLEle(ep)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "FITSDirectory"))
+        {
+            fitsDir->setText(pcdataXMLEle(ep));
+        }
+        else if (!strcmp(tagXMLEle(ep), "ISOIndex"))
+        {
+            if (ISOCombo->isEnabled())
+                ISOCombo->setCurrentIndex(atoi(pcdataXMLEle(ep)));
+        }
+        else if (!strcmp(tagXMLEle(ep), "Calibration"))
+        {
+            subEP = findXMLEle(ep, "FlatSource");
+            if (subEP)
+            {
+                XMLEle *typeEP = findXMLEle(subEP, "Type");
+                if (typeEP)
+                {
+                    if (!strcmp(pcdataXMLEle(typeEP), "Manual"))
+                        flatFieldSource = SOURCE_MANUAL;
+                    else if (!strcmp(pcdataXMLEle(typeEP), "FlatCap"))
+                        flatFieldSource = SOURCE_FLATCAP;
+                    else if (!strcmp(pcdataXMLEle(typeEP), "DarkCap"))
+                        flatFieldSource = SOURCE_DARKCAP;
+                    else if (!strcmp(pcdataXMLEle(typeEP), "Wall"))
+                    {
+                        XMLEle *azEP=NULL, *altEP=NULL;
+                        azEP  = findXMLEle(subEP, "Az");
+                        altEP = findXMLEle(subEP, "Alt");
+                        if (azEP && altEP)
+                        {
+                            flatFieldSource =SOURCE_WALL;
+                            wallCoord.setAz(atof(pcdataXMLEle(azEP)));
+                            wallCoord.setAlt(atof(pcdataXMLEle(altEP)));
+                        }
+                    }
+                    else
+                        flatFieldSource = SOURCE_DAWN_DUSK;
+
+                }
+            }
+
+            subEP = findXMLEle(ep, "FlatDuration");
+            if (subEP)
+            {
+                XMLEle *typeEP = findXMLEle(subEP, "Type");
+                if (typeEP)
+                {
+                    if (!strcmp(pcdataXMLEle(typeEP), "Manual"))
+                        flatFieldDuration = DURATION_MANUAL;
+                }
+
+                XMLEle *aduEP= findXMLEle(subEP, "Value");
+                if (aduEP)
+                {
+                    flatFieldDuration = DURATION_ADU;
+                    targetADU         = atof(pcdataXMLEle(aduEP));
+                }
+            }
+
+            subEP = findXMLEle(ep, "PreMountPark");
+            if (subEP)
+            {
+                if (!strcmp(pcdataXMLEle(subEP), "True"))
+                    preMountPark = true;
+                else
+                    preMountPark = false;
+            }
+
+            subEP = findXMLEle(ep, "PreDomePark");
+            if (subEP)
+            {
+                if (!strcmp(pcdataXMLEle(subEP), "True"))
+                    preDomePark = true;
+                else
+                    preDomePark = false;
+            }
+        }
+    }
+
+    addJob(false);
+
+    return true;
+}
+
+void Capture::saveSequenceQueue()
+{
+    QUrl backupCurrent = sequenceURL;
+
+    if (sequenceURL.toLocalFile().startsWith("/tmp/") || \
sequenceURL.toLocalFile().contains("/Temp")) +        sequenceURL.clear();
+
+    // If no changes made, return.
+    if( mDirty == false && !sequenceURL.isEmpty())
+        return;
+
+    if (sequenceURL.isEmpty())
+    {
+        sequenceURL = QFileDialog::getSaveFileUrl(KStars::Instance(), i18n("Save \
Ekos Sequence Queue"), dirPath, "Ekos Sequence Queue (*.esq)"); +        // if user \
presses cancel +        if (sequenceURL.isEmpty())
+        {
+            sequenceURL = backupCurrent;
+            return;
+        }
+
+        dirPath = QUrl(sequenceURL.url(QUrl::RemoveFilename));
+
+        if (sequenceURL.toLocalFile().endsWith(".esq") == false)
+            sequenceURL.setPath(sequenceURL.toLocalFile() + ".esq");
+
+        if (QFile::exists(sequenceURL.toLocalFile()))
+        {
+            int r = KMessageBox::warningContinueCancel(0,
+                        i18n( "A file named \"%1\" already exists. "
+                              "Overwrite it?", sequenceURL.fileName() ),
+                        i18n( "Overwrite File?" ),
+                        KGuiItem(i18n( "&Overwrite" )) );
+            if(r==KMessageBox::Cancel) return;
+        }
+    }
+
+    if ( sequenceURL.isValid() )
+    {
+        if ( (saveSequenceQueue(sequenceURL.toLocalFile())) == false)
+        {
+            KMessageBox::error(KStars::Instance(), i18n("Failed to save sequence \
queue"), i18n("Save")); +            return;
+        }
+
+        mDirty = false;
+
+    } else
+    {
+        QString message = i18n( "Invalid URL: %1", sequenceURL.url() );
+        KMessageBox::sorry(KStars::Instance(), message, i18n( "Invalid URL" ) );
+    }
+
+}
+
+void Capture::saveSequenceQueueAs()
+{
+    sequenceURL.clear();
+    saveSequenceQueue();
+}
+
+bool Capture::saveSequenceQueue(const QString &path)
+{
+    QFile file;
+    QString rawPrefix;
+    bool filterEnabled, expEnabled, tsEnabled;
+
+    file.setFileName(path);
+
+    if ( !file.open( QIODevice::WriteOnly))
+    {
+        QString message = i18n( "Unable to write to file %1",  path);
+        KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
+        return false;
+    }
+
+    QTextStream outstream(&file);
+
+    outstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+    outstream << "<SequenceQueue version='1.3'>" << endl;
+    outstream << "<GuideDeviation enabled='" << (guideDeviationCheck->isChecked() ? \
"true" : "false") << "'>" << guideDeviation->value() << "</GuideDeviation>" << endl; \
+    outstream << "<Autofocus enabled='" << (autofocusCheck->isChecked() ? "true" : \
"false") << "'>" << HFRPixels->value() << "</Autofocus>" << endl; +    outstream << \
"<MeridianFlip enabled='" << (meridianCheck->isChecked() ? "true" : "false") << "'>" \
<< meridianHours->value() << "</MeridianFlip>" << endl; +    outstream << "<Park \
enabled='" << (parkCheck->isChecked() ? "true" : "false") << "'></Park>" << endl; +   \
foreach(SequenceJob *job, jobs) +    {
+        job->getPrefixSettings(rawPrefix, filterEnabled, expEnabled, tsEnabled);
+
+         outstream << "<Job>" << endl;
+
+         outstream << "<Exposure>" << job->getExposure() << "</Exposure>" << endl;
+         outstream << "<Binning>" << endl;
+            outstream << "<X>"<< job->getXBin() << "</X>" << endl;
+            outstream << "<Y>"<< job->getXBin() << "</Y>" << endl;
+         outstream << "</Binning>" << endl;
+         outstream << "<Frame>" << endl;
+            outstream << "<X>" << job->getSubX() << "</X>" << endl;
+            outstream << "<Y>" << job->getSubY() << "</Y>" << endl;
+            outstream << "<W>" << job->getSubW() << "</W>" << endl;
+            outstream << "<H>" << job->getSubH() << "</H>" << endl;
+        outstream << "</Frame>" << endl;
+        if (job->getTargetTemperature() != INVALID_TEMPERATURE)
+            outstream << "<Temperature force='" << (job->getEnforceTemperature() ? \
"true":"false") << "'>" << job->getTargetTemperature() << "</Temperature>" << endl; + \
if (job->getTargetFilter() >= 0) +            outstream << "<Filter>" << \
job->getTargetFilter() << "</Filter>" << endl; +        outstream << "<Type>" << \
frameTypeCombo->itemText(job->getFrameType()) << "</Type>" << endl; +        \
outstream << "<Prefix>" << endl; +            //outstream << "<CompletePrefix>" << \
job->getPrefix() << "</CompletePrefix>" << endl; +            outstream << \
"<RawPrefix>" << rawPrefix << "</RawPrefix>" << endl; +            outstream << \
"<FilterEnabled>" << (filterEnabled ? 1 : 0) << "</FilterEnabled>" << endl; +         \
outstream << "<ExpEnabled>" << (expEnabled ? 1 : 0) << "</ExpEnabled>" << endl; +     \
outstream << "<TimeStampEnabled>" << (tsEnabled ? 1 : 0) << "</TimeStampEnabled>" << \
endl; +        outstream << "</Prefix>" << endl;
+        outstream << "<Count>" << job->getCount() << "</Count>" << endl;
+        // ms to seconds
+        outstream << "<Delay>" << job->getDelay()/1000 << "</Delay>" << endl;
+        QString rootDir = job->getRootFITSDir();
+        outstream << "<FITSDirectory>" << rootDir << "</FITSDirectory>" << endl;
+        if (job->getISOIndex() != -1)
+            outstream << "<ISOIndex>" << (job->getISOIndex()) << "</ISOIndex>" << \
endl; +
+        outstream << "<Calibration>" << endl;
+        outstream << "<FlatSource>" << endl;
+        if (job->getFlatFieldSource() == SOURCE_MANUAL)
+            outstream << "<Type>Manual</Type>" << endl;
+        else if (job->getFlatFieldSource() == SOURCE_FLATCAP)
+            outstream << "<Type>FlatCap</Type>" << endl;
+        else if (job->getFlatFieldSource() == SOURCE_DARKCAP)
+            outstream << "<Type>DarkCap</Type>" << endl;
+        else if (job->getFlatFieldSource() == SOURCE_WALL)
+        {
+            outstream << "<Type>Wall</Type>" << endl;
+            outstream << "<Az>" << job->getWallCoord().az().Degrees() << "</Az>" << \
endl; +            outstream << "<Alt>" << job->getWallCoord().alt().Degrees() << \
"</Alt>" << endl; +        }
+        else
+            outstream << "<Type>DawnDust</Type>" << endl;
+        outstream << "</FlatSource>" << endl;
+
+        outstream << "<FlatDuration>" << endl;
+        if (job->getFlatFieldDuration() == DURATION_MANUAL)
+            outstream << "<Type>Manual</Type>" << endl;
+        else
+        {
+            outstream << "<Type>ADU</Type>" << endl;
+            outstream << "<Value>" << job->getTargetADU() << "</Value>" << endl;
+        }
+        outstream << "</FlatDuration>" << endl;
+
+        outstream << "<PreMountPark>" << (job->isPreMountPark() ? "True" : "False") \
<< "</PreMountPark>" << endl; +        outstream << "<PreDomePark>" << \
(job->isPreDomePark() ? "True" : "False") << "</PreDomePark>" << endl; +        \
outstream << "</Calibration>" << endl; +
+        outstream << "</Job>" << endl;
+    }
+
+    outstream << "</SequenceQueue>" << endl;
+
+    appendLogText(i18n("Sequence queue saved to %1", path));
+    file.close();
+   return true;
+}
+
+void Capture::resetJobs()
+{
+    if (KMessageBox::warningContinueCancel(NULL, i18n("Are you sure you want to \
reset status of all jobs?"), +                                           i18n("Reset \
job status"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), +                 \
"reset_job_status_warning") !=KMessageBox::Continue) +        return;
+
+    foreach(SequenceJob *job, jobs)
+        job->resetStatus();
+
+    stop();
+
+    // Reste active job pointer
+    activeJob = NULL;
+
+    ignoreJobProgress=true;
+}
+
+void Capture::ignoreSequenceHistory()
+{
+    ignoreJobProgress=true;
+}
+
+void Capture::syncGUIToJob(SequenceJob *job)
+{
+    QString rawPrefix;
+    bool filterEnabled, expEnabled, tsEnabled;
+
+   job->getPrefixSettings(rawPrefix, filterEnabled, expEnabled, tsEnabled);
+
+   exposureIN->setValue(job->getExposure());
+   binXIN->setValue(job->getXBin());
+   binYIN->setValue(job->getYBin());
+   frameXIN->setValue(job->getSubX());
+   frameYIN->setValue(job->getSubY());
+   frameWIN->setValue(job->getSubW());
+   frameHIN->setValue(job->getSubH());
+   FilterPosCombo->setCurrentIndex(job->getTargetFilter()-1);
+   frameTypeCombo->setCurrentIndex(job->getFrameType());
+   prefixIN->setText(rawPrefix);
+   filterCheck->setChecked(filterEnabled);
+   expDurationCheck->setChecked(expEnabled);
+   ISOCheck->setChecked(tsEnabled);
+   countIN->setValue(job->getCount());
+   delayIN->setValue(job->getDelay()/1000);
+
+   // Temperature Options
+   temperatureCheck->setChecked(job->getEnforceTemperature());
+
+   // Flat field options
+   calibrationB->setEnabled(job->getFrameType() != FRAME_LIGHT);
+   flatFieldDuration = job->getFlatFieldDuration();
+   flatFieldSource   = job->getFlatFieldSource();
+   targetADU         = job->getTargetADU();
+   wallCoord         = job->getWallCoord();
+   preMountPark      = job->isPreMountPark();
+   preDomePark       = job->isPreDomePark();
+
+   fitsDir->setText(job->getRootFITSDir());
+
+   if (ISOCombo->isEnabled())
+        ISOCombo->setCurrentIndex(job->getISOIndex());
+}
+
+void Capture::editJob(QModelIndex i)
+{
+    SequenceJob *job = jobs.at(i.row());
+    if (job == NULL)
+        return;
+
+
+   syncGUIToJob(job);
+
+   appendLogText(i18n("Editing job #%1...", i.row()+1));
+
+   addToQueueB->setIcon(QIcon::fromTheme("dialog-ok-apply"));
+   addToQueueB->setToolTip(i18n("Apply job changes."));
+   removeFromQueueB->setToolTip(i18n("Cancel job changes."));
+
+   jobUnderEdit = true;
+
+}
+
+void Capture::resetJobEdit()
+{
+   if (jobUnderEdit)
+       appendLogText(i18n("Editing job canceled."));
+
+   jobUnderEdit = false;
+   addToQueueB->setIcon(QIcon::fromTheme("list-add"));
+
+   addToQueueB->setToolTip(i18n("Add job to sequence queue"));
+   removeFromQueueB->setToolTip(i18n("Remove job from sequence queue"));
+}
+
+void Capture::constructPrefix(QString &imagePrefix)
+{
+
+    if (imagePrefix.isEmpty() == false)
+        imagePrefix += '_';
+
+    imagePrefix += frameTypeCombo->currentText();
+
+    if (filterCheck->isChecked() && FilterPosCombo->currentText().isEmpty() == false \
&& +            frameTypeCombo->currentText().compare("Bias", Qt::CaseInsensitive) &&
+            frameTypeCombo->currentText().compare("Dark", Qt::CaseInsensitive))
+    {
+        //if (imagePrefix.isEmpty() == false || frameTypeCheck->isChecked())
+        imagePrefix += '_';
+
+        imagePrefix += FilterPosCombo->currentText();
+    }
+    if (expDurationCheck->isChecked())
+    {
+        //if (imagePrefix.isEmpty() == false || frameTypeCheck->isChecked())
+        imagePrefix += '_';
+
+        imagePrefix += QString::number(exposureIN->value(), 'd', 0) + \
QString("_secs"); +    }
+}
+
+double Capture::getProgressPercentage()
+{
+    int totalImageCount=0;
+    int totalImageCompleted=0;
+
+    foreach(SequenceJob *job, jobs)
+    {
+        totalImageCount += job->getCount();
+        totalImageCompleted += job->getCompleted();
+    }
+
+    if (totalImageCount != 0)
+        return ( ( (double) totalImageCompleted / totalImageCount) * 100.0);
+    else
+        return -1;
+}
+
+int Capture::getActiveJobID()
+{
+    if (activeJob == NULL)
+        return -1;
+
+    for (int i=0; i < jobs.count(); i++)
+    {
+        if (activeJob == jobs[i])
+            return i;
+    }
+
+    return -1;
+}
+
+QString Capture::getJobState(int id)
+{
+    if (id < jobs.count())
+    {
+        SequenceJob *job = jobs.at(id);
+        return job->getStatusString();
+    }
+
+    return QString();
+}
+
+int Capture::getJobImageProgress(int id)
+{
+    if (id < jobs.count())
+    {
+        SequenceJob *job = jobs.at(id);
+        return job->getCompleted();
+    }
+
+    return -1;
+}
+
+int Capture::getJobImageCount(int id)
+{
+    if (id < jobs.count())
+    {
+        SequenceJob *job = jobs.at(id);
+        return job->getCount();
+    }
+
+    return -1;
+}
+
+double Capture::getJobExposureProgress(int id)
+{
+    if (id < jobs.count())
+    {
+        SequenceJob *job = jobs.at(id);
+        return job->getExposeLeft();
+    }
+
+    return -1;
+}
+
+double Capture::getJobExposureDuration(int id)
+{
+    if (id < jobs.count())
+    {
+        SequenceJob *job = jobs.at(id);
+        return job->getExposure();
+    }
+
+    return -1;
+}
+
+int Capture::getJobRemainingTime(SequenceJob *job)
+{
+    int remaining=0;
+
+    if (job->getStatus() == SequenceJob::JOB_BUSY)
+        remaining += (job->getExposure() + job->getDelay()/1000) * (job->getCount() \
- job->getCompleted()) + job->getExposeLeft(); +    else
+        remaining += (job->getExposure() + job->getDelay()/1000) * (job->getCount() \
- job->getCompleted()); +
+    return remaining;
+}
+
+int Capture::getOverallRemainingTime()
+{
+    double remaining=0;
+
+    foreach(SequenceJob *job, jobs)
+        remaining += getJobRemainingTime(job);
+
+    return remaining;
+}
+
+int Capture::getActiveJobRemainingTime()
+{
+    if (activeJob == NULL)
+        return -1;
+
+    return getJobRemainingTime(activeJob);
+}
+
+void Capture::setMaximumGuidingDeviaiton(bool enable, double value)
+{
+    if (guideDeviationCheck->isEnabled())
+    {
+        guideDeviationCheck->setChecked(enable);
+        if (enable)
+            guideDeviation->setValue(value);
+    }
+
+}
+
+void Capture::setInSequenceFocus(bool enable, double HFR)
+{
+    if (autofocusCheck->isEnabled())
+    {
+        autofocusCheck->setChecked(enable);
+        if (enable)
+            HFRPixels->setValue(HFR);
+    }
+}
+
+void Capture::setParkOnComplete(bool enable)
+{
+    if (parkCheck->isEnabled())
+        parkCheck->setChecked(enable);
+}
+
+void Capture::setTemperature()
+{
+    if (currentCCD)
+        currentCCD->setTemperature(temperatureIN->value());
+}
+
+void Capture::clearSequenceQueue()
+{
+    activeJob=NULL;
+    targetName = QString();
+    stop();
+    while (queueTable->rowCount() > 0)
+        queueTable->removeRow(0);
+    jobs.clear();
+    qDeleteAll(jobs);
+    ignoreJobProgress = true;
+
+}
+
+QString Capture::getSequenceQueueStatus()
+{
+    if (jobs.count() == 0)
+        return "Invalid";
+
+    if (isBusy)
+        return "Running";
+
+    int idle=0, error=0, complete=0, aborted=0,running=0;
+
+    foreach(SequenceJob* job, jobs)
+    {
+        switch (job->getStatus())
+        {
+            case SequenceJob::JOB_ABORTED:
+                aborted++;
+                break;
+            case SequenceJob::JOB_BUSY:
+                running++;
+                break;
+            case SequenceJob::JOB_DONE:
+                complete++;
+                break;
+            case SequenceJob::JOB_ERROR:
+                error++;
+                break;
+            case SequenceJob::JOB_IDLE:
+                idle++;
+            break;
+        }
+    }
+
+    if (error > 0)
+            return "Error";
+
+    if (aborted > 0)
+    {
+        if (guideState == GUIDE_GUIDING && deviationDetected)
+            return "Suspended";
+        else
+            return "Aborted";
+    }
+
+    if (running > 0)
+        return "Running";
+
+    if (idle == jobs.count())
+        return "Idle";
+
+    if (complete == jobs.count())
+        return "Complete";
+
+    return "Invalid";
+}
+
+void Capture::processTelescopeNumber(INumberVectorProperty *nvp)
+{
+    // If it is not ours, return.
+    if (strcmp(nvp->device, currentTelescope->getDeviceName()) || strcmp(nvp->name, \
"EQUATORIAL_EOD_COORD")) +        return;
+
+    switch (meridianFlipStage)
+    {
+        case MF_NONE:
+            break;
+        case MF_INITIATED:
+        {
+            if (nvp->s == IPS_BUSY)
+                meridianFlipStage = MF_FLIPPING;
+        }
+        break;
+
+        case MF_FLIPPING:
+        {
+            double ra, dec;
+            currentTelescope->getEqCoords(&ra, &dec);
+            double diffRA = initialRA - ra;
+            if (fabs(diffRA) > MF_RA_DIFF_LIMIT || nvp->s == IPS_OK)
+                meridianFlipStage = MF_SLEWING;
+        }
+        break;
+
+        case MF_SLEWING:
+
+            if (nvp->s != IPS_OK)
+                break;
+
+            // If dome is syncing, wait until it stops
+            if (dome && dome->isMoving())
+                break;
+
+            // We are at a new initialHA
+            initialHA= getCurrentHA();
+
+            appendLogText(i18n("Telescope completed the meridian flip."));
+
+            if (resumeAlignmentAfterFlip == true)
+            {
+                appendLogText(i18n("Performing post flip re-alignment..."));
+                secondsLabel->setText(i18n("Aligning..."));
+
+                state = CAPTURE_ALIGNING;
+                emit newStatus(Ekos::CAPTURE_ALIGNING);
+
+                meridianFlipStage = MF_ALIGNING;
+                //QTimer::singleShot(Options::settlingTime(), [this]() {emit \
meridialFlipTracked();}); +                //emit meridialFlipTracked();
+                return;
+            }
+
+            checkGuidingAfterFlip();
+            break;
+
+       default:
+        break;
+    }
+
+}
+
+void Capture::checkGuidingAfterFlip()
+{
+    // If we're not autoguiding then we're done
+    if (resumeGuidingAfterFlip == false)
+    {
+        resumeSequence();
+        // N.B. Set meridian flip stage AFTER resumeSequence() always
+        meridianFlipStage = MF_NONE;
+    }
+    else
+    {
+        appendLogText(i18n("Performing post flip re-calibration and guiding..."));
+        secondsLabel->setText(i18n("Calibrating..."));
+
+        state = CAPTURE_CALIBRATING;
+        emit newStatus(Ekos::CAPTURE_CALIBRATING);
+
+        meridianFlipStage = MF_GUIDING;
+        emit meridianFlipCompleted();
+    }
+}
+
+double Capture::getCurrentHA()
+{
+    double currentRA, currentDEC;
+
+    if (currentTelescope == NULL)
+        return INVALID_HA;
+
+    if (currentTelescope->getEqCoords(&currentRA, &currentDEC) == false)
+    {
+        appendLogText(i18n("Failed to retrieve telescope coordinates. Unable to \
calculate telescope's hour angle.")); +        return INVALID_HA;
+    }
+
+    dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
 +
+    dms ha( lst.Degrees() - currentRA*15.0 );
+
+    double HA = ha.Hours();
+
+    if (HA > 12)
+        HA -= 24;
+
+    return HA;
+}
+
+bool Capture::checkMeridianFlip()
+{
+
+    if (meridianCheck->isEnabled() == false || meridianCheck->isChecked() == false \
|| initialHA > 0) +        return false;
+
+
+    double currentHA = getCurrentHA();
+
+    //appendLogText(i18n("Current hour angle %1", currentHA));
+
+    if (currentHA == INVALID_HA)
+        return false;
+
+    if (currentHA > meridianHours->value())
+    {
+        //NOTE: DO NOT make the follow sentence PLURAL as the value is in double
+        appendLogText(i18n("Current hour angle %1 hours exceeds meridian flip limit \
of %2 hours. Auto meridian flip is initiated.", QString::number(currentHA, 'f', 2), \
meridianHours->value())); +        meridianFlipStage = MF_INITIATED;
+
+        // Suspend guiding first before commanding a meridian flip
+        //if (isAutoGuiding && currentCCD->getChip(ISD::CCDChip::GUIDE_CCD) == \
guideChip) +//            emit suspendGuiding(false);
+
+        // If we are autoguiding, we should resume autoguiding after flip
+        resumeGuidingAfterFlip = (guideState == GUIDE_GUIDING);
+
+        if ((guideState == GUIDE_GUIDING) || isAutoFocus)
+            emit meridianFlipStarted();
+
+        double dec;
+        currentTelescope->getEqCoords(&initialRA, &dec);
+        currentTelescope->Slew(initialRA,dec);
+        secondsLabel->setText(i18n("Meridian Flip..."));
+
+        state = CAPTURE_MERIDIAN_FLIP;
+        emit newStatus(Ekos::CAPTURE_MERIDIAN_FLIP);
+
+        QTimer::singleShot(MF_TIMER_TIMEOUT, this, \
SLOT(checkMeridianFlipTimeout())); +        return true;
+    }
+
+    return false;
+}
+
+void Capture::checkMeridianFlipTimeout()
+{
+    if (meridianFlipStage == MF_NONE)
+        return;
+
+    if (meridianFlipStage < MF_ALIGNING)
+    {
+        appendLogText(i18n("Telescope meridian flip timed out."));
+        abort();
+    }
+}
+
+void Capture::setAlignStatus(AlignState state)
+{
+    alignState = state;
+
+    resumeAlignmentAfterFlip = true;
+
+    switch (state)
+    {
+        case ALIGN_COMPLETE:
+        if (meridianFlipStage == MF_ALIGNING)
+        {
+            appendLogText(i18n("Post flip re-alignment completed successfully."));
+            checkGuidingAfterFlip();
+        }
+        break;
+
+      case ALIGN_FAILED:
+        // TODO run it 3 times before giving up
+        if (meridianFlipStage == MF_ALIGNING)
+        {
+            appendLogText(i18n("Post-flip alignment failed."));
+            abort();
+        }
+        break;
+
+        default:
+        break;
+
+    }
+}
+
+void Capture::setGuideStatus(GuideState state)
+{
+    switch (state)
+    {
+
+    case GUIDE_IDLE:
+        // If Autoguiding was started before and now stopped, let's abort (unless \
we're doing a meridian flip) +        if (guideState == GUIDE_GUIDING && \
meridianFlipStage == MF_NONE && activeJob && activeJob->getStatus() == \
SequenceJob::JOB_BUSY) +        {
+            appendLogText(i18n("Autoguiding stopped. Aborting..."));
+            abort();
+        }
+        //isAutoGuiding = false;
+        break;
+
+    case GUIDE_GUIDING:
+        break;
+        //isAutoGuiding = true;
+
+    case GUIDE_CALIBRATION_SUCESS:
+        guideDeviationCheck->setEnabled(true);
+        guideDeviation->setEnabled(true);
+        break;
+
+    case GUIDE_CALIBRATION_ERROR:
+    case GUIDE_ABORTED:
+        // TODO try restarting calibration a couple of times before giving up
+        if (meridianFlipStage == MF_GUIDING)
+        {
+            appendLogText(i18n("Post meridian flip calibration error. \
Aborting...")); +            abort();
+        }
+        break;
+
+    case GUIDE_DITHERING_SUCCESS:
+        resumeCapture();
+        break;
+
+     case GUIDE_DITHERING_ERROR:
+        abort();
+        break;
+
+    default:
+        break;
+    }
+
+    guideState = state;
+}
+
+void Capture::checkFrameType(int index)
+{
+    if (index == FRAME_LIGHT)
+        calibrationB->setEnabled(false);
+    else
+        calibrationB->setEnabled(true);
+}
+
+double Capture::setCurrentADU(double value)
+{
+    double nextExposure = 0;
+
+    /*if (ExpRaw1 == -1)
+        ExpRaw1 = activeJob->getExposure();
+    else if (ExpRaw2 == -1)
+        ExpRaw2 = activeJob->getExposure();
+    else
+    {
+        ExpRaw1 = ExpRaw2;
+        ExpRaw2 = activeJob->getExposure();
+    }
+
+    if (ADURaw1 == -1)
+        ADURaw1 = value;
+    else if (ADURaw2 == -1)
+        ADURaw2 = value;
+    else
+    {
+        ADURaw1 = ADURaw2;
+        ADURaw2 = value;
+    }
+
+    qDebug() << "Exposure #1 (" << ExpRaw1 << "," << ADURaw1 << ") Exspoure #2 (" << \
ExpRaw2 << "," << ADURaw2 << ")"; +
+    // If we don't have the 2nd point, let's take another exposure with value \
relative to what we have now +    if (ADURaw2 == -1 || ExpRaw2 == -1 || (ADURaw1 == \
ADURaw2)) +    {
+        if (value < activeJob->getTargetADU())
+            nextExposure = activeJob->getExposure()*1.5;
+        else
+            nextExposure = activeJob->getExposure()*.75;
+
+        qDebug() << "Next Exposure: " << nextExposure;
+
+        return nextExposure;
+    }
+
+    if (fabs(ADURaw2 - ADURaw1) < 0.01)
+        ADUSlope=1e-6;
+    else
+        ADUSlope = (ExpRaw2 - ExpRaw1) / (ADURaw2 - ADURaw1);
+
+    qDebug() << "ADU Slope: " << ADUSlope;
+
+    nextExposure = ADUSlope * (activeJob->getTargetADU() - ADURaw2) + ExpRaw2;
+
+    qDebug() << "Next Exposure: " << nextExposure;
+
+    return nextExposure;*/
+
+    double a=0,b=0;
+
+    ExpRaw.append(activeJob->getExposure());
+    ADURaw.append(value);
+
+    llsq(ExpRaw, ADURaw, a, b);
+
+    if (a == 0)
+    {
+        if (value < activeJob->getTargetADU())
+            nextExposure = activeJob->getExposure()*1.5;
+        else
+            nextExposure = activeJob->getExposure()*.75;
+
+        qDebug() << "Next Exposure: " << nextExposure;
+
+        return nextExposure;
+    }
+
+    nextExposure = (activeJob->getTargetADU() - b) / a;
+
+    qDebug() << "Next Exposure: " << nextExposure;
+
+    return nextExposure;
+
+}
+
+//  Based on  John Burkardt LLSQ (LGPL)
+void Capture::llsq (QList<double> x, QList<double> y, double &a, double &b)
+{
+  double bot;
+  int i;
+  double top;
+  double xbar;
+  double ybar;
+  int n = x.count();
+//
+//  Special case.
+//
+  if ( n == 1 )
+  {
+    a = 0.0;
+    b = y[0];
+    return;
+  }
+//
+//  Average X and Y.
+//
+  xbar = 0.0;
+  ybar = 0.0;
+  for ( i = 0; i < n; i++ )
+  {
+    xbar = xbar + x[i];
+    ybar = ybar + y[i];
+  }
+  xbar = xbar / ( double ) n;
+  ybar = ybar / ( double ) n;
+//
+//  Compute Beta.
+//
+  top = 0.0;
+  bot = 0.0;
+  for ( i = 0; i < n; i++ )
+  {
+    top = top + ( x[i] - xbar ) * ( y[i] - ybar );
+    bot = bot + ( x[i] - xbar ) * ( x[i] - xbar );
+  }
+
+  a = top / bot;
+
+  b = ybar - a * xbar;
+
+  return;
+}
+
+
+void Capture::setDirty()
+{
+    mDirty = true;
+}
+
+void Capture::setMeridianFlip(bool enable)
+{
+    meridianCheck->setChecked(enable);
+}
+
+void Capture::setMeridianFlipHour(double hours)
+{
+    meridianHours->setValue(hours);
+}
+
+bool Capture::hasCoolerControl()
+{
+    if (currentCCD && currentCCD->hasCoolerControl())
+        return true;
+
+    return false;
+}
+
+bool Capture::setCoolerControl(bool enable)
+{
+    if (currentCCD && currentCCD->hasCoolerControl())
+        return currentCCD->setCoolerControl(enable);
+
+    return false;
+}
+
+void Capture::clearAutoFocusHFR()
+{
+    // If HFR limit was set from file, we cannot overide it.
+    if (fileHFR > 0)
+        return;
+
+    HFRPixels->setValue(0);
+    firstAutoFocus=true;
+}
+
+void Capture::openCalibrationDialog()
+{
+    QDialog calibrationDialog;
+
+    Ui_calibrationOptions calibrationOptions;
+    calibrationOptions.setupUi(&calibrationDialog);
+
+    if (currentTelescope)
+    {
+        calibrationOptions.parkMountC->setEnabled(currentTelescope->canPark());
+        calibrationOptions.parkMountC->setChecked(preMountPark);
+    }
+    else
+        calibrationOptions.parkMountC->setEnabled(false);
+
+    if (dome)
+    {
+        calibrationOptions.parkDomeC->setEnabled(dome->canPark());
+        calibrationOptions.parkDomeC->setChecked(preDomePark);
+    }
+    else
+        calibrationOptions.parkDomeC->setEnabled(false);
+
+
+    //connect(calibrationOptions.wallSourceC, SIGNAL(toggled(bool)), \
calibrationOptions.parkC, SLOT(setDisabled(bool))); +
+    switch (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(wallCoord.az().toDMSString());
+        calibrationOptions.altBox->setText(wallCoord.alt().toDMSString());
+        break;
+
+    case SOURCE_DAWN_DUSK:
+        calibrationOptions.dawnDuskFlatsC->setChecked(true);
+        break;
+    }
+
+    switch (flatFieldDuration)
+    {
+    case DURATION_MANUAL:
+        calibrationOptions.manualDurationC->setChecked(true);
+        break;
+
+    case DURATION_ADU:
+        calibrationOptions.ADUC->setChecked(true);
+        calibrationOptions.ADUValue->setValue(targetADU);
+        break;
+    }
+
+    if (calibrationDialog.exec() == QDialog::Accepted)
+    {
+        if (calibrationOptions.manualSourceC->isChecked())
+           flatFieldSource =  SOURCE_MANUAL;
+        else if (calibrationOptions.flatDeviceSourceC->isChecked())
+            flatFieldSource =  SOURCE_FLATCAP;
+        else if (calibrationOptions.darkDeviceSourceC->isChecked())
+            flatFieldSource = SOURCE_DARKCAP;
+        else if (calibrationOptions.wallSourceC->isChecked())
+        {
+            dms wallAz, wallAlt;
+            bool azOk=false, altOk=false;
+
+            wallAz  = calibrationOptions.azBox->createDms(true, &azOk);
+            wallAlt = calibrationOptions.altBox->createDms(true, &altOk);
+
+            if (azOk && altOk)
+            {
+                flatFieldSource =  SOURCE_WALL;
+                wallCoord.setAz(wallAz);
+                wallCoord.setAlt(wallAlt);
+            }
+            else
+            {
+                calibrationOptions.manualSourceC->setChecked(true);
+                KMessageBox::error(this, i18n("Wall coordinates are invalid."));
+            }
+        }
+        else
+            flatFieldSource =  SOURCE_DAWN_DUSK;
+
+
+        if (calibrationOptions.manualDurationC->isChecked())
+            flatFieldDuration = DURATION_MANUAL;
+        else
+        {
+            flatFieldDuration = DURATION_ADU;
+            targetADU = calibrationOptions.ADUValue->value();
+        }
+
+        preMountPark = calibrationOptions.parkMountC->isChecked();
+        preDomePark  = calibrationOptions.parkDomeC->isChecked();
+
+        setDirty();
+    }
+}
+
+IPState Capture::processPreCaptureCalibrationStage()
+{
+    if (guideState == GUIDE_GUIDING)
+    {
+        appendLogText(i18n("Autoguiding suspended."));
+        emit suspendGuiding(true);
+    }
+
+    // Let's check what actions to be taken, if any, for the flat field source
+    switch (activeJob->getFlatFieldSource())
+    {
+    case SOURCE_MANUAL:
+    case SOURCE_DAWN_DUSK: // Not yet implemented
+        break;
+
+    // Park cap, if not parked
+    // Turn on Light
+    case SOURCE_FLATCAP:
+        if (dustCap)
+        {
+            // If cap is not park, park it
+            if (calibrationStage < CAL_DUSTCAP_PARKING && dustCap->isParked() == \
false) +            {
+                if (dustCap->Park())
+                {
+                    calibrationStage = CAL_DUSTCAP_PARKING;
+                    appendLogText(i18n("Parking dust cap..."));
+                    return IPS_BUSY;
+                }
+                else
+                {
+                    appendLogText(i18n("Parking dust cap failed, aborting..."));
+                    abort();
+                    return IPS_ALERT;
+                }
+            }
+
+            // Wait until  cap is parked
+            if (calibrationStage == CAL_DUSTCAP_PARKING)
+            {
+                if (dustCap->isParked() == false)
+                    return IPS_BUSY;
+                else
+                {
+                    calibrationStage = CAL_DUSTCAP_PARKED;
+                    appendLogText(i18n("Dust cap parked."));
+                }
+            }
+
+            // If light is not on, turn it on. For flat frames only
+            if (activeJob->getFrameType() == FRAME_FLAT && dustCap->isLightOn() == \
false) +            {
+                dustCapLightEnabled = true;
+                dustCap->SetLightEnabled(true);
+            }
+            else if (activeJob->getFrameType() != FRAME_FLAT && dustCap->isLightOn() \
== true) +            {
+                dustCapLightEnabled = false;
+                dustCap->SetLightEnabled(false);
+            }
+        }
+        break;
+
+
+    // Park cap, if not parked and not flat frame
+    // Unpark cap, if flat frame
+    // Turn on Light
+    case SOURCE_DARKCAP:
+        if (dustCap)
+        {
+            // If cap is not park, park it if not flat frame. (external lightsource)
+            if (calibrationStage < CAL_DUSTCAP_PARKING && dustCap->isParked() == \
false && activeJob->getFrameType() != FRAME_FLAT) +            {
+                if (dustCap->Park())
+                {
+                    calibrationStage = CAL_DUSTCAP_PARKING;
+                    appendLogText(i18n("Parking dust cap..."));
+                    return IPS_BUSY;
+                }
+                else
+                {
+                    appendLogText(i18n("Parking dust cap failed, aborting..."));
+                    abort();
+                    return IPS_ALERT;
+                }
+            }
+
+            // Wait until  cap is parked
+            if (calibrationStage == CAL_DUSTCAP_PARKING)
+            {
+                if (dustCap->isParked() == false)
+                    return IPS_BUSY;
+                else
+                {
+                    calibrationStage = CAL_DUSTCAP_PARKED;
+                    appendLogText(i18n("Dust cap parked."));
+                }
+            }
+
+            // If cap is parked, unpark it if flat frame. (external lightsource)
+            if (calibrationStage < CAL_DUSTCAP_UNPARKING && dustCap->isParked() == \
true && activeJob->getFrameType() == FRAME_FLAT) +            {
+                if (dustCap->UnPark())
+                {
+                    calibrationStage = CAL_DUSTCAP_UNPARKING;
+                    appendLogText(i18n("UnParking dust cap..."));
+                    return IPS_BUSY;
+                }
+                else
+                {
+                    appendLogText(i18n("UnParking dust cap failed, aborting..."));
+                    abort();
+                    return IPS_ALERT;
+                }
+            }
+
+            // Wait until  cap is parked
+            if (calibrationStage == CAL_DUSTCAP_UNPARKING)
+            {
+                if (dustCap->isParked() == true)
+                    return IPS_BUSY;
+                else
+                {
+                    calibrationStage = CAL_DUSTCAP_UNPARKED;
+                    appendLogText(i18n("Dust cap unparked."));
+                }
+            }
+
+            // If light is not on, turn it on. For flat frames only
+            if (activeJob->getFrameType() == FRAME_FLAT && dustCap->isLightOn() == \
false) +            {
+                dustCapLightEnabled = true;
+                dustCap->SetLightEnabled(true);
+            }
+            else if (activeJob->getFrameType() != FRAME_FLAT && dustCap->isLightOn() \
== true) +            {
+                dustCapLightEnabled = false;
+                dustCap->SetLightEnabled(false);
+            }
+        }
+        break;
+
+    // Go to wall coordinates
+    case SOURCE_WALL:
+        if (currentTelescope)
+        {
+            if (calibrationStage < CAL_SLEWING)
+            {
+                    wallCoord = activeJob->getWallCoord();
+                    wallCoord.HorizontalToEquatorial(KStarsData::Instance()->lst(), \
KStarsData::Instance()->geo()->lat()); +                    \
currentTelescope->Slew(&wallCoord); +                    appendLogText(i18n("Mount \
slewing to wall position...")); +                    calibrationStage = CAL_SLEWING;
+                    return IPS_BUSY;
+            }
+
+            // Check if slewing is complete
+            if (calibrationStage == CAL_SLEWING)
+            {
+                if (currentTelescope->isSlewing() == false)
+                {
+                    calibrationStage = CAL_SLEWING_COMPLETE;
+                    appendLogText(i18n("Slew to wall position complete."));
+                }
+                else
+                    return IPS_BUSY;
+            }
+
+            if (lightBox)
+            {
+                // Check if we have a light box to turn on
+                if (activeJob->getFrameType() == FRAME_FLAT  && \
lightBox->isLightOn() == false) +                {
+                    lightBoxLightEnabled = true;
+                    lightBox->SetLightEnabled(true);
+                }
+                else if (activeJob->getFrameType() != FRAME_FLAT  && \
lightBox->isLightOn() == true) +                {
+                    lightBoxLightEnabled = false;
+                    lightBox->SetLightEnabled(false);
+                }
+            }
+        }
+        break;
+    }
+
+    // Check if we need to perform mount prepark
+    if (preMountPark && currentTelescope && activeJob->getFlatFieldSource() != \
SOURCE_WALL) +    {
+        if (calibrationStage < CAL_MOUNT_PARKING && currentTelescope->isParked() == \
false) +        {
+            if (currentTelescope->Park())
+            {
+                calibrationStage = CAL_MOUNT_PARKING;
+                //emit mountParking();
+                appendLogText(i18n("Parking mount prior to calibration frames \
capture...")); +                return IPS_BUSY;
+            }
+            else
+            {
+                appendLogText(i18n("Parking mount failed, aborting..."));
+                abort();
+                return IPS_ALERT;
+            }
+        }
+
+        if (calibrationStage == CAL_MOUNT_PARKING)
+        {
+          // If not parked yet, check again in 1 second
+          // Otherwise proceed to the rest of the algorithm
+          if (currentTelescope->isParked() == false)
+              return IPS_BUSY;
+          else
+          {
+              calibrationStage = CAL_MOUNT_PARKED;
+              appendLogText(i18n("Mount parked."));
+          }
+        }
+    }
+
+    // Check if we need to perform dome prepark
+    if (preDomePark && dome)
+    {
+        if (calibrationStage < CAL_DOME_PARKING && dome->isParked() == false)
+        {
+            if (dome->Park())
+            {
+                calibrationStage = CAL_DOME_PARKING;
+                //emit mountParking();
+                appendLogText(i18n("Parking dome..."));
+                return IPS_BUSY;
+            }
+            else
+            {
+                appendLogText(i18n("Parking dome failed, aborting..."));
+                abort();
+                return IPS_ALERT;
+            }
+        }
+
+        if (calibrationStage == CAL_DOME_PARKING)
+        {
+          // If not parked yet, check again in 1 second
+          // Otherwise proceed to the rest of the algorithm
+          if (dome->isParked() == false)
+              return IPS_BUSY;
+          else
+          {
+              calibrationStage = CAL_DOME_PARKED;
+              appendLogText(i18n("Dome parked."));
+          }
+        }
+    }
+
+    calibrationStage = CAL_PRECAPTURE_COMPLETE;
+    return IPS_OK;
+}
+
+bool Capture::processPostCaptureCalibrationStage()
+{
+    // Check if we need to do flat field slope calculation if the user specified a \
desired ADU value +    if (activeJob->getFrameType() == FRAME_FLAT && \
activeJob->getFlatFieldDuration() == DURATION_ADU && activeJob->getTargetADU() > 0) + \
{ +        FITSData *image_data = NULL;
+        FITSView *currentImage   = targetChip->getImage(FITS_NORMAL);
+        if (currentImage)
+        {
+            image_data = currentImage->getImageData();
+            double currentADU = image_data->getADU();
+            //double currentSlope = ADUSlope;
+
+            double percentageDiff=0;
+            if (currentADU > activeJob->getTargetADU())
+                percentageDiff = activeJob->getTargetADU()/currentADU;
+            else
+                percentageDiff = currentADU / activeJob->getTargetADU();
+
+            // If it is within 2% of target ADU
+            if (percentageDiff >= 0.98)
+            {
+                if (calibrationStage == CAL_CALIBRATION)
+                {
+                    appendLogText(i18n("Current ADU %1 within target ADU tolerance \
range.", QString::number(currentADU, 'f', 0))); +                    \
activeJob->setPreview(false); +                    calibrationStage = \
CAL_CALIBRATION_COMPLETE; +                    startNextExposure();
+                    return false;
+                }
+
+                return true;
+            }
+
+            double nextExposure = setCurrentADU(currentADU);
+
+            if (nextExposure <= 0)
+            {
+                appendLogText(i18n("Unable to calculate optimal exposure settings, \
please take the flats manually.")); +                //activeJob->setTargetADU(0);
+                //targetADU = 0;
+                abort();
+                return false;
+            }
+
+            appendLogText(i18n("Current ADU is %1 Next exposure is %2 seconds.", \
QString::number(currentADU, 'f', 0), QString::number(nextExposure, 'f', 3))); +
+            calibrationStage = CAL_CALIBRATION;
+            activeJob->setExposure(nextExposure);
+            activeJob->setPreview(true);
+
+            startNextExposure();
+            return false;
+
+            // Start next exposure in case ADU Slope is not calculated yet
+            /*if (currentSlope == 0)
+            {
+                startNextExposure();
+                return;
+            }*/
+        }
+        else
+        {
+            appendLogText(i18n("An empty image is received, aborting..."));
+            abort();
+            return false;
+        }
+    }
+
+    calibrationStage = CAL_CALIBRATION_COMPLETE;
+    return true;
+}
+
+bool Capture::isSequenceFileComplete(const QString &fileURL)
+{
+    // If we don't remember job progress, then no sequence would be complete
+    if (Options::rememberJobProgress() == false)
+        return false;
+
+    // We cannot know if the job is complete if the upload mode is local since we \
cannot inspect the files +    if (currentCCD && currentCCD->getUploadMode() == \
ISD::CCD::UPLOAD_LOCAL) +        return false;
+
+    if (Options::captureLogging())
+    {
+        qDebug() << "Capture: Loading sequence to check for completion: " << \
fileURL; +    }
+
+    bool rc = loadSequenceQueue(fileURL);
+
+    if (rc == false)
+        return false;
+
+    ignoreJobProgress = false;
+
+    QStringList jobDirs;
+    int totalJobCount = 0, totalFileCount=0;
+    foreach(SequenceJob *job, jobs)
+    {
+        jobDirs << job->getFITSDir();
+        totalJobCount   += job->getCount();
+    }
+
+    jobDirs.removeDuplicates();
+
+    if (Options::captureLogging())
+    {
+        qDebug() << "Capture: Total Job Count --> " << totalFileCount;
+        qDebug() << "Capture: isSequenceFileComplete directories --> " << jobDirs;
+    }
+
+    foreach(QString dir, jobDirs)
+    {
+        QDir oneDir(dir);
+        oneDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
+        totalFileCount += oneDir.count();
+
+        if (Options::captureLogging())
+        {
+            qDebug() << "Capture: Directory " << dir << " file count is " << \
oneDir.count() << " and total count is " << totalFileCount; +        }
+    }
+
+    clearSequenceQueue();
+
+    return (totalFileCount >= totalJobCount);
+}
+
+void Capture::setNewRemoteFile(QString file)
+{
+    appendLogText(i18n("Remote image saved to %1", file));
+}
+
+void Capture::startPostFilterAutoFocus()
+{
+    if (focusState >= FOCUS_PROGRESS)
+        return;
+
+    secondsLabel->setText(i18n("Focusing..."));
+
+    state = CAPTURE_FOCUSING;
+    emit newStatus(Ekos::CAPTURE_FOCUSING);
+
+    appendLogText(i18n("Post filter change Autofocus..."));
+
+    // Force it to always run autofocus routine
+    emit checkFocus(0.1);
+}
+
+void Capture::postScriptFinished(int exitCode)
+{
+    appendLogText(i18n("Post capture script finished with code %1. Resuming \
sequence...", exitCode)); +    resumeSequence();
+}
+
+}
diff --git a/kstars/ekos/capture/capture.h b/kstars/ekos/capture/capture.h
new file mode 100644
index 0000000..34335b3
--- /dev/null
+++ b/kstars/ekos/capture/capture.h
@@ -0,0 +1,590 @@
+/*  Ekos Capture tool
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+#include <QTimer>
+#include <QUrl>
+#include <QtDBus/QtDBus>
+
+#include "ui_capture.h"
+
+#include "ekos.h"
+#include "fitsviewer/fitscommon.h"
+#include "indi/indistd.h"
+#include "indi/indiccd.h"
+#include "indi/indicap.h"
+#include "indi/indidome.h"
+#include "indi/indilightbox.h"
+#include "indi/inditelescope.h"
+
+class QProgressIndicator;
+class QTableWidgetItem;
+class KDirWatch;
+
+/**
+ *@namespace Ekos
+ *@short Ekos is an advanced Astrophotography tool for Linux.
+ * It is based on a modular extensible framework to perform common astrophotography \
tasks. This includes highly accurate GOTOs using astrometry solver, ability to \
measure and correct polar alignment errors , + * auto-focus & auto-guide \
capabilities, and capture of single or stack of images with filter wheel support.\n + \
* Features: + * - Control your telescope, CCD (& DSLRs), filter wheel, focuser, \
guider, adaptive optics unit, and any INDI-compatible auxiliary device from Ekos. + * \
- Extremely accurate GOTOs using astrometry.net solver (both Online and Offline \
solvers supported). + * - Load & Slew: Load a FITS image, slew to solved coordinates, \
and center the mount on the exact image coordinates in order to get the same desired \
frame. + * - Measure & Correct Polar Alignment errors using astromety.net solver.
+ * - Auto and manual focus modes using Half-Flux-Radius (HFR) method.
+ * - Automated unattended meridian flip. Ekos performs post meridian flip alignment, \
calibration, and guiding to resume the capture session. + * - Automatic focus between \
exposures when a user-configurable HFR limit is exceeded. + * - Auto guiding with \
support for automatic dithering between exposures and support for Adaptive Optics \
devices in addition to traditional guiders. + * - Powerful sequence queue for batch \
capture of images with optional prefixes, timestamps, filter wheel selection, and \
much more! + * - Export and import sequence queue sets as Ekos Sequence Queue (.esq) \
files. + * - Center the telescope anywhere in a captured FITS image or any FITS with \
World Coordinate System (WCS) header. + * - Automatic flat field capture, just set \
the desired ADU and let Ekos does the rest! + * - Automatic abort and resumption of \
exposure tasks if guiding errors exceed a user-configurable value. + * - Support for \
dome slaving. + * - Complete integration with KStars Observation Planner and SkyMap
+ * - Integrate with all INDI native devices.
+ * - Powerful scripting capabilities via \ref EkosDBusInterface "DBus."
+ *
+ * The primary class is EkosManager. It handles startup and shutdown of local and \
remote INDI devices, manages and orchesterates the various Ekos modules, and provides \
advanced DBus + * interface to enable unattended scripting.
+*@author Jasem Mutlaq
+ *@version 1.3
+ */
+namespace Ekos
+{
+
+class SequenceJob;
+
+/**
+ *@class Capture
+ *@short Captures single or sequence of images from a CCD.
+ * The capture class support capturing single or multiple images from a CCD, it \
provides a powerful sequence queue with filter wheel selection. Any sequence queue \
can be saved as Ekos Sequence Queue (.esq). + * All image capture operations are \
saved as Sequence Jobs that encapsulate all the different options in a capture \
process. The user may select in sequence autofocusing by setting a maximum HFR limit. \
When the limit + * is exceeded, it automatically trigger autofocus operation. The \
capture process can also be linked with guide module. If guiding deviations exceed a \
certain threshold, the capture operation aborts until + * the guiding deviation \
resume to acceptable levels and the capture operation is resumed. + *@author Jasem \
Mutlaq + *@version 1.2
+ */
+class Capture : public QWidget, public Ui::Capture
+{
+
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Capture")
+
+public:
+
+    enum { CALIBRATE_NONE, CALIBRATE_START, CALIBRATE_DONE };
+    typedef enum { MF_NONE, MF_INITIATED, MF_FLIPPING, MF_SLEWING, MF_ALIGNING, \
MF_GUIDING } MFStage; +    typedef enum { CAL_NONE, CAL_DUSTCAP_PARKING, \
CAL_DUSTCAP_PARKED, CAL_LIGHTBOX_ON, CAL_SLEWING, CAL_SLEWING_COMPLETE, \
CAL_MOUNT_PARKING, CAL_MOUNT_PARKED, CAL_DOME_PARKING, CAL_DOME_PARKED, \
CAL_PRECAPTURE_COMPLETE, CAL_CALIBRATION, CAL_CALIBRATION_COMPLETE, CAL_CAPTURING, \
CAL_DUSTCAP_UNPARKING, CAL_DUSTCAP_UNPARKED} CalibrationStage; +    typedef bool \
(Capture::*PauseFunctionPointer)(); +
+    Capture();
+    ~Capture();
+
+    /** @defgroup CaptureDBusInterface Ekos DBus Interface - Capture Module
+     * Ekos::Capture interface provides advanced scripting capabilities to capture \
image sequences. +    */
+
+    /*@{*/
+
+    /** DBUS interface function.
+     * select the CCD device from the available CCD drivers.
+     * @param device The CCD device name
+     */
+    Q_SCRIPTABLE bool setCCD(QString device);
+
+    /** DBUS interface function.
+     * select the filter device from the available filter drivers. The filter device \
can be the same as the CCD driver if the filter functionality was embedded within the \
driver. +     * @param device The filter device name
+     */
+    Q_SCRIPTABLE bool setFilter(QString device, int filterSlot);
+
+    /** DBUS interface function.
+     * Aborts any current jobs and remove all sequence queue jobs.
+     */
+    Q_SCRIPTABLE Q_NOREPLY void clearSequenceQueue();
+
+    /** DBUS interface function.
+     * Returns the overall sequence queue status. If there are no jobs pending, it \
returns "Invalid". If all jobs are idle, it returns "Idle". If all jobs are complete, \
it returns "Complete". If one or more jobs are aborted +     * it returns "Aborted" \
unless it was temporarily aborted due to guiding deviations, then it would return \
"Suspended". If one or more jobs have errors, it returns "Error". If any jobs is \
under progress, returns "Running". +     */
+    Q_SCRIPTABLE QString getSequenceQueueStatus();
+
+    /** DBUS interface function.
+     * Opens a sequence files and checks whether the jobs contained within are \
complete or not. The check is done by quering the file system for the produced files \
for each job. +     * If returns true if all jobs are complete, false otherwise.sudo
+     */
+    Q_SCRIPTABLE bool isSequenceFileComplete(const QString &fileURL);
+
+    /** 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
+     */
+    Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL);
+
+    /** DBUS interface function.
+     * Sets target name. The target name shall be appended to the root directory \
specified by the user. +     * e.g. If root directory is /home/jasem and target is \
M31, then root directory becomes /home/jasem/M31 +     * @param name Name of desired \
target +     */
+    Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &name) { targetName = \
name; } +
+    /** DBUS interface function.
+     * Enables or disables the maximum guiding deviation and sets its value.
+     * @param enable If true, enable the guiding deviation check, otherwise, disable \
it. +     * @param if enable is true, it sets the maximum guiding deviation in \
arcsecs. If the value is exceeded, the capture operation is aborted until the value \
falls below the value threshold. +     */
+    Q_SCRIPTABLE Q_NOREPLY void setMaximumGuidingDeviaiton(bool enable, double \
value); +
+    /** DBUS interface function.
+     * Enables or disables the in sequence focus and sets Half-Flux-Radius (HFR) \
limit. +     * @param enable If true, enable the in sequence auto focus check, \
otherwise, disable it. +     * @param if enable is true, it sets HFR in pixels. After \
each exposure, the HFR is re-measured and if it exceeds the specified value, an \
autofocus operation will be commanded. +     */
+    Q_SCRIPTABLE Q_NOREPLY void setInSequenceFocus(bool enable, double HFR);
+
+    /** DBUS interface function.
+     * Enables or disables park on complete option.
+     * @param enable If true, mount shall be commanded to parking position after all \
jobs are complete in the sequence queue. +     */
+    Q_SCRIPTABLE Q_NOREPLY void setParkOnComplete(bool enable);
+
+    /** DBUS interface function.
+     * Enable or Disable meridian flip, and sets its activation hour.
+     * @param enable If true, meridian flip will be command after user-configurable \
number of hours. +     */
+    Q_SCRIPTABLE Q_NOREPLY void setMeridianFlip(bool enable);
+
+    /** DBUS interface function.
+     * Sets meridian flip trigger hour.
+     * @param hours Number of hours after the meridian at which the mount is \
commanded to flip. +     */
+    Q_SCRIPTABLE Q_NOREPLY void setMeridianFlipHour(double hours);
+
+    /** DBUS interface function.
+     * Does the CCD has a cooler control (On/Off) ?
+     */
+    Q_SCRIPTABLE bool hasCoolerControl();
+
+    /** DBUS interface function.
+     * Set the CCD cooler ON/OFF
+     *
+     */
+    Q_SCRIPTABLE bool setCoolerControl(bool enable);
+
+    /** DBUS interface function.
+     * @return Returns the percentage of completed captures in all active jobs
+     */
+    Q_SCRIPTABLE double            getProgressPercentage();
+
+    /** DBUS interface function.
+     * @return Returns the number of jobs in the sequence queue.
+     */
+    Q_SCRIPTABLE int            getJobCount() { return jobs.count(); }
+
+    /** DBUS interface function.
+     * @return Returns ID of current active job if any, or -1 if there are no active \
jobs. +     */
+    Q_SCRIPTABLE int            getActiveJobID();
+
+    /** DBUS interface function.
+     * @return Returns time left in seconds until active job is estimated to be \
complete. +     */
+    Q_SCRIPTABLE int getActiveJobRemainingTime();
+
+    /** DBUS interface function.
+     * @return Returns overall time left in seconds until all jobs are estimated to \
be complete +     */
+    Q_SCRIPTABLE int getOverallRemainingTime();
+
+    /** DBUS interface function.
+     * @param id job number. Job IDs start from 0 to N-1.
+     * @return Returns the job state (Idle, In Progress, Error, Aborted, Complete)
+     */
+    Q_SCRIPTABLE QString        getJobState(int id);
+
+    /** DBUS interface function.
+     * @param id job number. Job IDs start from 0 to N-1.
+     * @return Returns The number of images completed capture in the job.
+     */
+    Q_SCRIPTABLE int            getJobImageProgress(int id);
+
+    /** DBUS interface function.
+     * @param id job number. Job IDs start from 0 to N-1.
+     * @return Returns the total number of images to capture in the job.
+     */
+    Q_SCRIPTABLE int            getJobImageCount(int id);
+
+    /** DBUS interface function.
+     * @param id job number. Job IDs start from 0 to N-1.
+     * @return Returns the number of seconds left in an exposure operation.
+     */
+    Q_SCRIPTABLE double         getJobExposureProgress(int id);
+
+    /** DBUS interface function.
+     * @param id job number. Job IDs start from 0 to N-1.
+     * @return Returns the total requested exposure duration in the job.
+     */
+    Q_SCRIPTABLE double         getJobExposureDuration(int id);
+
+    /** DBUS interface function.
+     * Clear in-sequence focus settings. It sets the autofocus HFR to zero so that \
next autofocus value is remembered for the in-sequence focusing. +     */
+    Q_SCRIPTABLE Q_NOREPLY  void clearAutoFocusHFR();
+
+
+    /** DBUS interface function.
+     * Jobs will NOT be checked for progress against the file system and will be \
always assumed as new jobs. +     */
+    Q_SCRIPTABLE Q_NOREPLY  void ignoreSequenceHistory();
+
+    /** @}*/
+
+    void addCCD(ISD::GDInterface *newCCD);
+    void addFilter(ISD::GDInterface *newFilter);
+    void setDome(ISD::GDInterface *device) { dome = \
dynamic_cast<ISD::Dome*>(device); } +    void setDustCap(ISD::GDInterface *device) { \
dustCap = dynamic_cast<ISD::DustCap*>(device); } +    void \
setLightBox(ISD::GDInterface *device) { lightBox = \
dynamic_cast<ISD::LightBox*>(device); } +    void addGuideHead(ISD::GDInterface \
*newCCD); +    void syncFrameType(ISD::GDInterface *ccd);
+    void setTelescope(ISD::GDInterface *newTelescope);
+    void syncTelescopeInfo();
+    void syncFilterInfo();
+
+    void clearLog();
+    QString getLogText() { return logText.join("\n"); }
+
+    /* Capture */
+    void updateSequencePrefix( const QString &newPrefix, const QString &dir);
+
+public slots:
+
+    /** \addtogroup CaptureDBusInterface
+     *  @{
+     */
+
+    /* Capture */
+    /** DBUS interface function.
+     * Starts the sequence queue capture procedure sequentially by starting all jobs \
that are either Idle or Aborted in order. +     */
+    Q_SCRIPTABLE Q_NOREPLY void start();
+
+    /** DBUS interface function.
+     * Stop all jobs and set current job status to aborted if abort is set to true, \
otherwise status is idle until +     * sequence is resumed or restarted.
+     * @param abort abort jobs if in progress
+     */
+    Q_SCRIPTABLE Q_NOREPLY void stop(bool abort=false);
+
+    /** DBUS interface function.
+     * Aborts all jobs. It simply calls stop(true)
+     */
+    Q_SCRIPTABLE Q_NOREPLY void abort() { stop(true); }
+
+    /** @}*/
+
+    /**
+     * @brief captureOne Capture one preview image
+     */
+    void captureOne();
+
+    /**
+     * @brief captureImage Initiates image capture in the active job.
+     */
+    void captureImage();
+
+    /**
+     * @brief newFITS process new FITS data received from camera. Update status of \
active job and overall sequence. +     * @param bp pointer to blob contianing FITS \
data +     */
+    void newFITS(IBLOB *bp);
+
+    /**
+     * @brief checkCCD Refreshes the CCD information in the capture module.
+     * @param CCDNum The CCD index in the CCD combo box to select as the active CCD.
+     */
+    void checkCCD(int CCDNum=-1);
+
+    /**
+     * @brief checkFilter Refreshes the filter wheel information in the capture \
module. +     * @param filterNum The filter wheel index in the filter device combo \
box to set as the active filter. +     */
+    void checkFilter(int filterNum=-1);
+
+    /**
+     * @brief processCCDNumber Process number properties arriving from CCD. \
Currently, only CCD and Guider frames are processed. +     * @param nvp pointer to \
number property. +     */
+    void processCCDNumber(INumberVectorProperty *nvp);
+
+    /**
+     * @brief processTelescopeNumber Process number properties arriving from \
telescope for meridian flip purposes. +     * @param nvp pointer to number property.
+     */
+    void processTelescopeNumber(INumberVectorProperty *nvp);
+
+    /**
+     * @brief addJob Add a new job to the sequence queue given the settings in the \
GUI. +     * @param preview True if the job is a preview job, otherwise, it is added \
as a batch job. +     */
+    void addJob(bool preview=false);
+
+    /**
+     * @brief removeJob Remove a job from the currently selected row. If no row is \
selected, it remove the last job in the queue. +     */
+    void removeJob();
+
+    /**
+     * @brief moveJobUp Move the job in the sequence queue one place up.
+     */
+    void moveJobUp();
+
+    /**
+     * @brief moveJobDown Move the job in the sequence queue one place down.
+     */
+    void moveJobDown();
+
+    /**
+     * @brief setGuideDeviation Set the guiding deviaiton as measured by the guiding \
module. Abort capture if deviation exceeds user value. Resume capture if capture was \
aborted and guiding deviations are below user value. +     * @param delta_ra \
Deviation in RA in arcsecs from the selected guide star. +     * @param delta_dec \
Deviation in DEC in arcsecs from the selected guide star. +     */
+    void setGuideDeviation(double delta_ra, double delta_dec);
+
+    /**
+     * @brief setGuideDither Set whether dithering is enable/disabled in guiding \
module. +     * @param enable True if dithering is enabled, false otherwise.
+     */
+    void setGuideDither(bool enable);
+
+    /**
+     * @brief resumeCapture Resume capture after dither and/or focusing processes \
are complete. +     */
+    bool resumeCapture();
+
+    /**
+     * @brief updateCCDTemperature Update CCD temperature in capture module.
+     * @param value Temperature in celcius.
+     */
+    void updateCCDTemperature(double value);
+
+    /**
+     * @brief setTemperature Set CCD temperature from the user GUI settings.
+     */
+    void setTemperature();
+
+    // Pause Sequence Queue
+    void pause();
+
+    // Logs
+    void appendLogText(const QString &);
+
+    // Auto Focus
+    void setFocusStatus(Ekos::FocusState state);
+    // Guide
+    void setGuideStatus(Ekos::GuideState state);
+    // Align
+    void setAlignStatus(Ekos::AlignState state);
+
+private slots:
+
+    /**
+     * @brief setDirty Set dirty bit to indicate sequence queue file was modified \
and needs saving. +     */
+    void setDirty();
+
+    void toggleSequence();
+
+
+    void checkFrameType(int index);
+    void resetFrame();
+    void updateCaptureProgress(ISD::CCDChip *tChip, double value, IPState state);
+    void checkSeqBoundary(const QString &path);
+    void saveFITSDirectory();
+    void setDefaultCCD(QString ccd);
+    void setNewRemoteFile(QString file);
+    void setGuideChip(ISD::CCDChip* chip) { guideChip = chip; }
+
+    // Sequence Queue
+    void loadSequenceQueue();
+    void saveSequenceQueue();
+    void saveSequenceQueueAs();
+
+    // Jobs
+    void resetJobs();
+    void editJob(QModelIndex i);
+    void resetJobEdit();
+    void executeJob();
+
+    // Meridian Flip
+    void checkMeridianFlipTimeout();
+    //void checkAlignmentSlewComplete();
+
+    // Auto Focus
+    //void updateAutofocusStatus(bool status, double HFR);
+    void setHFR(double newHFR) { focusHFR = newHFR; }
+    void startPostFilterAutoFocus();
+
+    // Flat field
+    void openCalibrationDialog();
+    IPState processPreCaptureCalibrationStage();
+    bool processPostCaptureCalibrationStage();
+
+    // Send image info
+    void sendNewImage(QImage *image, ISD::CCDChip *myChip);
+
+    // Capture
+    bool setCaptureComplete();
+
+    // Temporary for post capture script
+    void postScriptFinished(int exitCode);
+
+signals:
+        void newLog();
+        //void exposureComplete();
+        void checkFocus(double);
+        //void mountParking();
+        void suspendGuiding(bool);
+        void meridianFlipStarted();
+        void meridianFlipCompleted();
+        void newStatus(Ekos::CaptureState status);
+        void newImage(QImage *image, Ekos::SequenceJob *job);
+
+private:
+
+    void setBusy(bool enable);
+    bool resumeSequence();
+    bool startNextExposure();
+    void updateFrameProperties(bool reset=false);
+    void prepareJob(SequenceJob *job);
+    void syncGUIToJob(SequenceJob *job);
+    bool processJobInfo(XMLEle *root);
+    void processJobCompletion();
+    bool saveSequenceQueue(const QString &path);
+    void constructPrefix(QString &imagePrefix);
+    double setCurrentADU(double value);
+    void llsq (QList<double> x, QList<double> y, double &a, double &b);
+
+    /* Meridian Flip */
+    bool checkMeridianFlip();
+    void checkGuidingAfterFlip();
+    double getCurrentHA();
+
+    // Remaining Time in seconds
+    int getJobRemainingTime(SequenceJob *job);
+
+    /* Capture */
+    double	seqExpose;
+    int	seqTotalCount;
+    int	seqCurrentCount;
+    int	seqDelay;
+    int     retries;
+    QTimer *seqTimer;
+    QString		seqPrefix;
+    int			nextSequenceID;
+    int         seqFileCount;
+    bool        isBusy;
+
+    //int calibrationState;
+    bool useGuideHead;
+
+    QString targetName;
+
+    SequenceJob *activeJob;
+
+    QList<ISD::CCD *> CCDs;
+
+    ISD::CCDChip *targetChip;
+    ISD::CCDChip *guideChip;
+
+    // They're generic GDInterface because they could be either ISD::CCD or \
ISD::Filter +    QList<ISD::GDInterface *> Filters;
+
+    QList<SequenceJob *> jobs;
+
+    ISD::Telescope *currentTelescope;
+    ISD::CCD *currentCCD;
+    ISD::GDInterface *currentFilter;
+    ISD::DustCap *dustCap;
+    ISD::LightBox *lightBox;
+    ISD::Dome *dome;
+
+    ITextVectorProperty *filterName;
+    INumberVectorProperty *filterSlot;
+
+    QStringList logText;
+    QUrl sequenceURL;
+    bool mDirty;
+    bool jobUnderEdit;
+    int currentFilterPosition;
+    QProgressIndicator *pi;
+
+    // Guide Deviation
+    bool deviationDetected;
+    bool spikeDetected;
+
+    // Dither
+    bool guideDither;
+    //bool isAutoGuiding;
+
+    // Autofocus
+    bool isAutoFocus;
+    bool autoFocusStatus;
+    bool firstAutoFocus;
+    double focusHFR;                    // HFR value as received from the Ekos focus \
module +    double fileHFR;                     // HFR value as loaded from the \
sequence file +
+    //Meridan flip
+    double initialHA;
+    double initialRA;
+    bool resumeAlignmentAfterFlip;
+    bool resumeGuidingAfterFlip;
+    MFStage meridianFlipStage;
+
+    // Flat field automation
+    /*double ExpRaw1, ExpRaw2;
+    double ADURaw1, ADURaw2;
+    double ADUSlope;*/
+    QList<double> ExpRaw;
+    QList<double> ADURaw;
+    double targetADU;
+    SkyPoint wallCoord;
+    bool preMountPark, preDomePark;
+    FlatFieldDuration flatFieldDuration;
+    FlatFieldSource   flatFieldSource;
+    CalibrationStage calibrationStage;
+    bool dustCapLightEnabled, lightBoxLightEnabled;
+
+    QUrl dirPath;
+
+    // Misc
+    bool ignoreJobProgress;
+
+    // State
+    CaptureState state;
+    FocusState focusState;
+    GuideState guideState;
+    AlignState alignState;
+
+    PauseFunctionPointer pauseFunction;
+
+    // CCD Chip frame settings
+    QMap<ISD::CCDChip *, QVariantMap> frameSettings;
+
+    // Temporary Only
+    QProcess postCaptureScript;
+
+
+};
+
+}
+
+#endif  // CAPTURE_H
diff --git a/kstars/ekos/capture/capture.ui b/kstars/ekos/capture/capture.ui
new file mode 100644
index 0000000..ff64248
--- /dev/null
+++ b/kstars/ekos/capture/capture.ui
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Capture</class>
+ <widget class="QWidget" name="Capture">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>728</width>
+    <height>413</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>3</number>
+   </property>
+   <property name="topMargin">
+    <number>3</number>
+   </property>
+   <property name="rightMargin">
+    <number>3</number>
+   </property>
+   <property name="bottomMargin">
+    <number>3</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_11">
+     <property name="spacing">
+      <number>1</number>
+     </property>
+     <item>
+      <widget class="QGroupBox" name="CCDFWGroup">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="title">
+        <string>CCD &amp;&amp; Filter Wheel</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <item>
+         <layout class="QGridLayout" name="gridLayout">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="textLabel1_6">
+            <property name="toolTip">
+             <string/>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>CCD:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="CCDCaptureCombo"/>
+          </item>
+          <item row="0" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_4">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="textLabel1_5_3">
+              <property name="toolTip">
+               <string>Filter Wheel</string>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>FW:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QComboBox" name="FilterCaptureCombo">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="textLabel1_2_3">
+              <property name="toolTip">
+               <string>Number of images to capture</string>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>Filter:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QComboBox" name="FilterPosCombo">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="exposureLabel_2">
+            <property name="toolTip">
+             <string>Set the exposure time in seconds for individual images, if \
applicable</string> +            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Exposure:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QDoubleSpinBox" name="exposureIN">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="decimals">
+             <number>3</number>
+            </property>
+            <property name="minimum">
+             <double>0.001000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>3600.000000000000000</double>
+            </property>
+            <property name="value">
+             <double>1.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="textLabel1_9">
+              <property name="toolTip">
+               <string>Horizontal and Vertical binning</string>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>Binning:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="textLabel1_10">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>X:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="binXIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="toolTip">
+               <string>Horizontal binning</string>
+              </property>
+              <property name="minimum">
+               <number>1</number>
+              </property>
+              <property name="maximum">
+               <number>10</number>
+              </property>
+              <property name="value">
+               <number>1</number>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="textLabel1_11">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>Y:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="binYIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="toolTip">
+               <string>Vertical binning</string>
+              </property>
+              <property name="minimum">
+               <number>1</number>
+              </property>
+              <property name="maximum">
+               <number>10</number>
+              </property>
+              <property name="value">
+               <number>1</number>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="textLabel1_12">
+            <property name="toolTip">
+             <string/>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Frame:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <layout class="QHBoxLayout" name="horizontalLayout_9">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="textLabel1_13">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>X:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="frameXIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="textLabel1_14">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>Y:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="frameYIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="2" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_10">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="textLabel1_15">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>W:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="frameWIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="maximum">
+               <number>99</number>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="textLabel1_16">
+              <property name="toolTip">
+               <string/>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>H:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="frameHIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="resetFrameB">
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="toolTip">
+               <string>Reset CCD frame values to default values</string>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="textLabel1_17">
+            <property name="toolTip">
+             <string/>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Type:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <widget class="QComboBox" name="frameTypeCombo">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_12">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QCheckBox" name="temperatureCheck">
+              <property name="toolTip">
+               <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enforce \
temperature value before capturing an \
image&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> +              </property>
+              <property name="text">
+               <string>T º</string>
+              </property>
+              <property name="checked">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="temperatureOUT">
+              <property name="minimumSize">
+               <size>
+                <width>0</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QDoubleSpinBox" name="temperatureIN">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="setTemperatureB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="toolTip">
+               <string>Set CCD temperature</string>
+              </property>
+              <property name="text">
+               <string>Set</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="calibrationB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="toolTip">
+               <string>Calibration Options</string>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="textLabel1_7">
+            <property name="toolTip">
+             <string>Prefix to append to the beginning of file names</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Prefix:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <widget class="QLineEdit" name="prefixIN"/>
+          </item>
+          <item row="4" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_16">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QCheckBox" name="filterCheck">
+              <property name="toolTip">
+               <string>Append the active filter slot to the prefix</string>
+              </property>
+              <property name="text">
+               <string>Filter</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QCheckBox" name="expDurationCheck">
+              <property name="toolTip">
+               <string>Append the expose duration to the prefix</string>
+              </property>
+              <property name="text">
+               <string>Duration</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QCheckBox" name="ISOCheck">
+              <property name="toolTip">
+               <string>Append time stamp to the prefix</string>
+              </property>
+              <property name="text">
+               <string>TS</string>
+              </property>
+              <property name="checked">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_2">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="textLabel1_4">
+            <property name="toolTip">
+             <string>Number of images to capture</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Count:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="1">
+           <widget class="QSpinBox" name="countIN">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimum">
+             <number>1</number>
+            </property>
+            <property name="maximum">
+             <number>999</number>
+            </property>
+            <property name="value">
+             <number>1</number>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_3">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="textLabel1_8">
+              <property name="toolTip">
+               <string>Delay in seconds between consecutive images</string>
+              </property>
+              <property name="whatsThis">
+               <string/>
+              </property>
+              <property name="text">
+               <string>Delay:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="delayIN">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="maximum">
+               <number>3600</number>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="label_8">
+            <property name="toolTip">
+             <string>Apply filter to image after capture to enhance it</string>
+            </property>
+            <property name="text">
+             <string>Filters:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="1">
+           <widget class="QComboBox" name="filterCombo">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <item>
+             <property name="text">
+              <string>--</string>
+             </property>
+            </item>
+           </widget>
+          </item>
+          <item row="6" column="2">
+           <layout class="QHBoxLayout" name="horizontalLayout_2">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QLabel" name="ISOLabel">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="text">
+               <string>ISO:</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QComboBox" name="ISOCombo">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_8">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item>
+           <widget class="QLabel" name="textLabel1_18">
+            <property name="toolTip">
+             <string>Directory to save sequence images</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>Directory:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLineEdit" name="fitsDir"/>
+          </item>
+          <item>
+           <widget class="QPushButton" name="selectFITSDirB">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>28</width>
+              <height>28</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>28</width>
+              <height>28</height>
+             </size>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="SequenceQueue">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <item>
+        <widget class="QGroupBox" name="groupBox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="title">
+          <string>Sequence Queue</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_8">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_14">
+            <property name="spacing">
+             <number>1</number>
+            </property>
+            <item>
+             <widget class="QPushButton" name="addToQueueB">
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="removeFromQueueB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="queueUpB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="queueDownB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="resetB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="toolTip">
+               <string>Reset status of all jobs</string>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item>
+             <widget class="QPushButton" name="queueLoadB">
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="queueSaveB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="queueSaveAsB">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>32</width>
+                <height>32</height>
+               </size>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">queueEditButtonGroup</string>
+              </attribute>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <widget class="QTableWidget" name="queueTable">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="horizontalScrollBarPolicy">
+             <enum>Qt::ScrollBarAsNeeded</enum>
+            </property>
+            <attribute name="horizontalHeaderDefaultSectionSize">
+             <number>85</number>
+            </attribute>
+            <attribute name="horizontalHeaderMinimumSectionSize">
+             <number>30</number>
+            </attribute>
+            <column>
+             <property name="text">
+              <string>Status</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>Filter</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>Type</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>Bin</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>Exp</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>ISO</string>
+             </property>
+            </column>
+            <column>
+             <property name="text">
+              <string>Count</string>
+             </property>
+            </column>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_7">
+         <property name="spacing">
+          <number>1</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="previewB">
+           <property name="toolTip">
+            <string/>
+           </property>
+           <property name="text">
+            <string>Preview</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="buttonSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Expanding</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>18</width>
+             <height>21</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="startB">
+           <property name="minimumSize">
+            <size>
+             <width>32</width>
+             <height>32</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>32</width>
+             <height>32</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Start Sequence</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+           <property name="autoDefault">
+            <bool>true</bool>
+           </property>
+           <property name="default">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pauseB">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>32</width>
+             <height>32</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>32</width>
+             <height>32</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Pause Sequence</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+           <property name="autoDefault">
+            <bool>true</bool>
+           </property>
+           <property name="default">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_13">
+     <property name="spacing">
+      <number>1</number>
+     </property>
+     <item>
+      <widget class="QGroupBox" name="optionsGroup">
+       <property name="title">
+        <string>Options</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_5">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item>
+           <widget class="QCheckBox" name="darkSubCheck">
+            <property name="toolTip">
+             <string>Perform automatic dark subtraction in preview mode</string>
+            </property>
+            <property name="text">
+             <string>Auto dark subtract</string>
+            </property>
+            <property name="checked">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <layout class="QGridLayout" name="gridLayout_2">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="QCheckBox" name="guideDeviationCheck">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="toolTip">
+             <string>Abort sequence if guiding deviation exceed this value</string>
+            </property>
+            <property name="text">
+             <string>Guiding Deviation &lt;</string>
+            </property>
+            <property name="checked">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QDoubleSpinBox" name="guideDeviation">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="decimals">
+             <number>2</number>
+            </property>
+            <property name="maximum">
+             <double>30.000000000000000</double>
+            </property>
+            <property name="singleStep">
+             <double>0.500000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QLabel" name="textLabel1_2_4">
+            <property name="toolTip">
+             <string>Number of images to capture</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>&quot;</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="6">
+           <widget class="QLabel" name="textLabel1_2_5">
+            <property name="toolTip">
+             <string>Number of images to capture</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>pixels</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QCheckBox" name="meridianCheck">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="toolTip">
+             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Command a \
meridian flip if the hour angle exceeds the specified value. Capture and Guiding will \
be suspended and resumed after the flip is \
complete.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> +            </property>
+            <property name="text">
+             <string>Meridian Flip if HA &gt;</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="4" colspan="2">
+           <widget class="QCheckBox" name="parkCheck">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="toolTip">
+             <string>Automatically park telescope once all sequence jobs are \
completed</string> +            </property>
+            <property name="text">
+             <string>Park When Complete</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="5">
+           <widget class="QDoubleSpinBox" name="HFRPixels">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="decimals">
+             <number>3</number>
+            </property>
+            <property name="minimum">
+             <double>0.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>10.000000000000000</double>
+            </property>
+            <property name="singleStep">
+             <double>0.100000000000000</double>
+            </property>
+            <property name="value">
+             <double>0.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="2">
+           <widget class="QLabel" name="textLabel1_2_6">
+            <property name="toolTip">
+             <string>Number of images to capture</string>
+            </property>
+            <property name="whatsThis">
+             <string/>
+            </property>
+            <property name="text">
+             <string>hours</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QDoubleSpinBox" name="meridianHours">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="decimals">
+             <number>2</number>
+            </property>
+            <property name="minimum">
+             <double>0.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>3.000000000000000</double>
+            </property>
+            <property name="singleStep">
+             <double>0.100000000000000</double>
+            </property>
+            <property name="value">
+             <double>0.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="4">
+           <widget class="QCheckBox" name="autofocusCheck">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="toolTip">
+             <string>Perform autofocusing once Half-Flux-Radius (HFR) value exceeds \
this limit</string> +            </property>
+            <property name="text">
+             <string>Autofocus if HFR &gt;</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="3">
+           <widget class="Line" name="line">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="3">
+           <widget class="Line" name="line_2">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="progressGroup">
+       <property name="title">
+        <string>Progress</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_7">
+        <property name="spacing">
+         <number>3</number>
+        </property>
+        <property name="leftMargin">
+         <number>3</number>
+        </property>
+        <property name="topMargin">
+         <number>3</number>
+        </property>
+        <property name="rightMargin">
+         <number>3</number>
+        </property>
+        <property name="bottomMargin">
+         <number>3</number>
+        </property>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_6">
+          <property name="spacing">
+           <number>1</number>
+          </property>
+          <item>
+           <layout class="QGridLayout" name="progressLayout">
+            <property name="spacing">
+             <number>5</number>
+            </property>
+            <item row="0" column="0">
+             <widget class="QLabel" name="progressLabel_3">
+              <property name="text">
+               <string>Expose:</string>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="1">
+             <widget class="QLabel" name="exposeOUT">
+              <property name="minimumSize">
+               <size>
+                <width>50</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="frameShape">
+               <enum>QFrame::Box</enum>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="2" colspan="2">
+             <widget class="QLabel" name="secondsLabel">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="minimumSize">
+               <size>
+                <width>85</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="maximumSize">
+               <size>
+                <width>85</width>
+                <height>16777215</height>
+               </size>
+              </property>
+              <property name="text">
+               <string notr="true">second left</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="progressLabel_2">
+              <property name="text">
+               <string>Progress:</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <widget class="QLabel" name="currentImgCountOUT">
+              <property name="minimumSize">
+               <size>
+                <width>50</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="frameShape">
+               <enum>QFrame::Box</enum>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="2">
+             <widget class="QLabel" name="textLabel1_4_2_3">
+              <property name="text">
+               <string>of</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignCenter</set>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="3">
+             <widget class="QLabel" name="fullImgCountOUT">
+              <property name="minimumSize">
+               <size>
+                <width>50</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="frameShape">
+               <enum>QFrame::Box</enum>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="4">
+             <widget class="QLabel" name="completedLabel_2">
+              <property name="text">
+               <string>completed</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <spacer name="progressSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Expanding</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>51</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QProgressBar" name="imgProgress">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>1</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>2</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+  <zorder>verticalSpacer</zorder>
+ </widget>
+ <resources/>
+ <connections/>
+ <buttongroups>
+  <buttongroup name="queueEditButtonGroup">
+   <property name="exclusive">
+    <bool>false</bool>
+   </property>
+  </buttongroup>
+ </buttongroups>
+</ui>
diff --git a/kstars/ekos/capture/sequencejob.cpp \
b/kstars/ekos/capture/sequencejob.cpp new file mode 100644
index 0000000..b5b3215
--- /dev/null
+++ b/kstars/ekos/capture/sequencejob.cpp
@@ -0,0 +1,422 @@
+/*  Ekos
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+#include <KMessageBox>
+#include <KDirWatch>
+#include <KLocalizedString>
+#include <KNotifications/KNotification>
+
+
+#include "sequencejob.h"
+#include "Options.h"
+
+#include "kstars.h"
+#include "kstarsdata.h"
+
+#include "ui_calibrationoptions.h"
+
+#define INVALID_TEMPERATURE 10000
+#define INVALID_HA          10000
+#define MF_TIMER_TIMEOUT    90000
+#define MF_RA_DIFF_LIMIT    4
+#define MAX_CAPTURE_RETRIES 3
+
+namespace Ekos
+{
+
+SequenceJob::SequenceJob()
+{
+    statusStrings = QStringList() << i18n("Idle") << i18n("In Progress") << \
i18n("Error") << i18n("Aborted") << i18n("Complete"); +    status = JOB_IDLE;
+    exposure=count=delay=frameType=targetFilter=isoIndex=-1;
+    currentTemperature=targetTemperature=INVALID_TEMPERATURE;
+    captureFilter=FITS_NONE;
+    preview=false;
+    filterReady=temperatureReady=filterPostFocusReady=prepareReady=true;
+    enforceTemperature=false;
+    activeChip=NULL;
+    activeCCD=NULL;
+    activeFilter= NULL;
+    statusCell = NULL;
+    completed=0;
+    captureRetires=0;
+
+    calibrationSettings.flatFieldSource   = SOURCE_MANUAL;
+    calibrationSettings.flatFieldDuration = DURATION_MANUAL;
+    calibrationSettings.targetADU         = 0;
+    calibrationSettings.preMountPark           = false;
+    calibrationSettings.preDomePark            = false;
+
+    typePrefixEnabled     = false;
+    filterPrefixEnabled   = false;
+    expPrefixEnabled      = false;
+    timeStampPrefixEnabled= false;
+}
+
+void SequenceJob::reset()
+{
+    // Reset to default values
+    activeChip->setBatchMode(false);
+}
+
+void SequenceJob::resetStatus()
+{
+    status = JOB_IDLE;
+    completed=0;
+    exposeLeft=0;
+    captureRetires=0;
+    if (preview == false && statusCell)
+        statusCell->setText(statusStrings[status]);
+}
+
+void SequenceJob::abort()
+{
+    status = JOB_ABORTED;
+    if (preview == false && statusCell)
+        statusCell->setText(statusStrings[status]);
+    if (activeChip->canAbort())
+        activeChip->abortExposure();
+    activeChip->setBatchMode(false);
+}
+
+void SequenceJob::done()
+{
+    status = JOB_DONE;
+
+    if (statusCell)
+        statusCell->setText(statusStrings[status]);
+
+}
+
+void SequenceJob::prepareCapture()
+{
+    prepareReady=false;
+
+    activeChip->setBatchMode(!preview);
+
+    activeCCD->setFITSDir(fitsDir);
+
+    activeCCD->setISOMode(timeStampPrefixEnabled);
+
+    activeCCD->setSeqPrefix(fullPrefix);
+
+    if (activeChip->isBatchMode())
+        activeCCD->updateUploadSettings();
+
+    if (isoIndex != -1)
+    {
+        if (isoIndex != activeChip->getISOIndex())
+             activeChip->setISOIndex(isoIndex);
+    }
+
+    if (frameType == FRAME_DARK || frameType == FRAME_BIAS)
+        filterReady = true;
+    else if (targetFilter != -1 && activeFilter != NULL)
+    {
+        if (targetFilter == currentFilter)
+            filterReady = true;
+        else
+        {
+            filterReady = false;
+
+            // Post Focus on Filter change. If frame is NOT light, then we do not \
perform autofocusing on filter change +            filterPostFocusReady = \
(!Options::autoFocusOnFilterChange() || frameType != FRAME_LIGHT); +
+            activeFilter->runCommand(INDI_SET_FILTER, &targetFilter);
+        }
+    }
+
+    if (enforceTemperature && fabs(targetTemperature - currentTemperature) > \
Options::maxTemperatureDiff()) +    {
+        temperatureReady = false;
+        activeCCD->setTemperature(targetTemperature);
+    }
+
+    if (prepareReady == false && temperatureReady && filterReady)
+    {
+        prepareReady = true;
+        emit prepareComplete();
+    }
+
+}
+
+//SequenceJob::CAPTUREResult SequenceJob::capture(bool isDark)
+SequenceJob::CAPTUREResult SequenceJob::capture(bool noCaptureFilter)
+{
+    // If focusing is busy, return error
+    //if (activeChip->getCaptureMode() == FITS_FOCUS)
+      //  return CAPTURE_FOCUS_ERROR;
+
+    activeChip->setBatchMode(!preview);
+
+    if (targetFilter != -1 && activeFilter != NULL)
+    {
+        if (targetFilter != currentFilter)
+        {
+            activeFilter->runCommand(INDI_SET_FILTER, &targetFilter);
+            return CAPTURE_FILTER_BUSY;
+        }
+    }
+
+   if (isoIndex != -1)
+   {
+       if (isoIndex != activeChip->getISOIndex())
+            activeChip->setISOIndex(isoIndex);
+   }
+
+   if ((w > 0 && h > 0) && activeChip->canSubframe() && activeChip->setFrame(x, y, \
w, h) == false) +   {
+        status = JOB_ERROR;
+
+        if (preview == false && statusCell)
+            statusCell->setText(statusStrings[status]);
+
+        return CAPTURE_FRAME_ERROR;
+
+   }
+
+   if (activeChip->canBin() && activeChip->setBinning(binX, binY) == false)
+   {
+       status = JOB_ERROR;
+
+       if (preview == false && statusCell)
+           statusCell->setText(statusStrings[status]);
+
+       return CAPTURE_BIN_ERROR;
+   }
+
+   activeChip->setFrameType(frameTypeName);
+   activeChip->setCaptureMode(FITS_NORMAL);
+
+   if (noCaptureFilter)
+       activeChip->setCaptureFilter(FITS_NONE);
+   else
+       activeChip->setCaptureFilter(captureFilter);
+
+   // If filter is different that CCD, send the filter info
+   if (activeFilter && activeFilter != activeCCD)
+       activeCCD->setFilter(filter);
+
+   status = JOB_BUSY;
+
+    if (preview == false && statusCell)
+        statusCell->setText(statusStrings[status]);
+
+    exposeLeft = exposure;
+
+    activeChip->capture(exposure);
+
+    return CAPTURE_OK;
+
+}
+
+void SequenceJob::setTargetFilter(int pos, const QString & name)
+{
+    targetFilter = pos;
+    filter    = name;
+}
+
+void SequenceJob::setFrameType(int type, const QString & name)
+{
+    frameType = type;
+    frameTypeName = name;
+}
+
+double SequenceJob::getExposeLeft() const
+{
+    return exposeLeft;
+}
+
+void SequenceJob::setExposeLeft(double value)
+{
+    exposeLeft = value;
+}
+
+void SequenceJob::setPrefixSettings(const QString &prefix, bool filterEnabled, bool \
exposureEnabled, bool tsEnabled) +{
+    rawPrefix               = prefix;
+    filterPrefixEnabled     = filterEnabled;
+    expPrefixEnabled        = exposureEnabled;
+    timeStampPrefixEnabled        = tsEnabled;
+}
+
+void SequenceJob::getPrefixSettings(QString &prefix, bool &filterEnabled, bool \
&exposureEnabled, bool &tsEnabled) +{
+    prefix          = rawPrefix;
+
+    filterEnabled   = filterPrefixEnabled;
+    exposureEnabled = expPrefixEnabled;
+    tsEnabled       = timeStampPrefixEnabled;
+}
+double SequenceJob::getCurrentTemperature() const
+{
+    return currentTemperature;
+}
+
+void SequenceJob::setCurrentTemperature(double value)
+{
+    currentTemperature = value;
+
+    if (enforceTemperature == false || fabs(targetTemperature - currentTemperature) \
<= Options::maxTemperatureDiff()) +        temperatureReady = true;
+
+    if (prepareReady == false && filterReady && temperatureReady && \
filterPostFocusReady && (status == JOB_IDLE || status == JOB_ABORTED)) +    {
+        prepareReady = true;
+        emit prepareComplete();
+    }
+}
+
+double SequenceJob::getTargetTemperature() const
+{
+    return targetTemperature;
+}
+
+void SequenceJob::setTargetTemperature(double value)
+{
+    targetTemperature = value;
+}
+
+double SequenceJob::getTargetADU() const
+{
+    return calibrationSettings.targetADU;
+}
+
+void SequenceJob::setTargetADU(double value)
+{
+    calibrationSettings.targetADU = value;
+}
+int SequenceJob::getCaptureRetires() const
+{
+    return captureRetires;
+}
+
+void SequenceJob::setCaptureRetires(int value)
+{
+    captureRetires = value;
+}
+
+FlatFieldSource SequenceJob::getFlatFieldSource() const
+{
+    return calibrationSettings.flatFieldSource;
+}
+
+void SequenceJob::setFlatFieldSource(const FlatFieldSource &value)
+{
+    calibrationSettings.flatFieldSource = value;
+}
+
+FlatFieldDuration SequenceJob::getFlatFieldDuration() const
+{
+    return calibrationSettings.flatFieldDuration;
+}
+
+void SequenceJob::setFlatFieldDuration(const FlatFieldDuration &value)
+{
+    calibrationSettings.flatFieldDuration = value;
+}
+
+SkyPoint SequenceJob::getWallCoord() const
+{
+    return calibrationSettings.wallCoord;
+}
+
+void SequenceJob::setWallCoord(const SkyPoint &value)
+{
+    calibrationSettings.wallCoord = value;
+}
+
+bool SequenceJob::isPreMountPark() const
+{
+    return calibrationSettings.preMountPark;
+}
+
+void SequenceJob::setPreMountPark(bool value)
+{
+    calibrationSettings.preMountPark = value;
+}
+
+bool SequenceJob::isPreDomePark() const
+{
+    return calibrationSettings.preDomePark;
+}
+
+void SequenceJob::setPreDomePark(bool value)
+{
+    calibrationSettings.preDomePark = value;
+}
+
+bool SequenceJob::getEnforceTemperature() const
+{
+    return enforceTemperature;
+}
+
+void SequenceJob::setEnforceTemperature(bool value)
+{
+    enforceTemperature = value;
+}
+
+QString SequenceJob::getRootFITSDir() const
+{
+    return rootFITSDir;
+}
+
+void SequenceJob::setRootFITSDir(const QString &value)
+{
+    rootFITSDir = value;
+}
+
+bool SequenceJob::getFilterPostFocusReady() const
+{
+    return filterPostFocusReady;
+}
+
+void SequenceJob::setFilterPostFocusReady(bool value)
+{
+    filterPostFocusReady = value;
+
+    if (prepareReady == false && filterPostFocusReady && filterReady && \
temperatureReady && (status == JOB_IDLE || status == JOB_ABORTED)) +    {
+        prepareReady = true;
+        emit prepareComplete();
+    }
+}
+
+int SequenceJob::getISOIndex() const
+{
+    return isoIndex;
+}
+
+void SequenceJob::setISOIndex(int value)
+{
+    isoIndex = value;
+}
+
+int SequenceJob::getCurrentFilter() const
+{
+    return currentFilter;
+}
+
+void SequenceJob::setCurrentFilter(int value)
+{
+    currentFilter = value;
+
+    if (currentFilter == targetFilter)
+        filterReady = true;
+
+    if (prepareReady == false && filterReady && temperatureReady && \
filterPostFocusReady && (status == JOB_IDLE || status == JOB_ABORTED)) +    {
+        prepareReady = true;
+        emit prepareComplete();
+    }
+    else if (filterReady && filterPostFocusReady == false)
+        emit checkFocus();
+}
+
+}
diff --git a/kstars/ekos/capture/sequencejob.h b/kstars/ekos/capture/sequencejob.h
new file mode 100644
index 0000000..d30d5fd
--- /dev/null
+++ b/kstars/ekos/capture/sequencejob.h
@@ -0,0 +1,206 @@
+/*  Ekos Capture tool
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef SEQUENCEJOB_H
+#define SEQUENCEJOB_H
+
+#include <QTableWidgetItem>
+
+#include "indi/indistd.h"
+#include "indi/indiccd.h"
+
+/**
+ *@class SequenceJob
+ *@short Sequence Job is a container for the details required to capture a series of \
images. + *@author Jasem Mutlaq
+ *@version 1.0
+ */
+namespace Ekos
+{
+
+class SequenceJob : public QObject
+{
+    Q_OBJECT    
+
+    public:
+
+    typedef enum { JOB_IDLE, JOB_BUSY, JOB_ERROR, JOB_ABORTED, JOB_DONE } JOBStatus;
+    typedef enum { CAPTURE_OK, CAPTURE_FRAME_ERROR, CAPTURE_BIN_ERROR, \
CAPTURE_FILTER_BUSY, CAPTURE_FOCUS_ERROR} CAPTUREResult; +
+    SequenceJob();
+    ~SequenceJob() {}
+
+    CAPTUREResult capture(bool noCaptureFilter);
+    void reset();
+    void abort();
+    void done();
+    void prepareCapture();
+
+    JOBStatus getStatus() { return status; }
+    const QString & getStatusString() { return statusStrings[status]; }
+    bool isPreview() { return preview;}
+    int getDelay() { return delay;}
+    int getCount() { return count;}
+    unsigned int getCompleted() { return completed; }
+    const QString & getPrefix() { return fullPrefix;}
+    const QString & getRawPrefix() { return rawPrefix;}
+    double getExposure() const { return exposure;}
+
+    void setActiveCCD(ISD::CCD *ccd) { activeCCD = ccd; }
+    ISD::CCD *getActiveCCD() { return activeCCD;}
+
+    void setActiveFilter(ISD::GDInterface *filter) { activeFilter = filter; }
+    ISD::GDInterface *getActiveFilter() { return activeFilter;}
+
+    void setActiveChip(ISD::CCDChip *chip) { activeChip = chip; }
+    ISD::CCDChip *getActiveChip() { return activeChip;}
+
+    void setFITSDir(const QString &dir) { fitsDir = dir;}
+    const QString & getFITSDir() { return fitsDir; }
+
+    void setTargetFilter(int pos, const QString & name);
+    int getTargetFilter() { return targetFilter;}
+    int getCurrentFilter() const;
+    void setCurrentFilter(int value);
+
+    const QString &getFilterName() { return filter; }
+
+    void setFrameType(int type, const QString & name);
+    int getFrameType() { return frameType;}
+
+    void setCaptureFilter(FITSScale capFilter) { captureFilter = capFilter; }
+    FITSScale getCaptureFilter() { return captureFilter;}
+
+    void setPreview(bool enable) { preview = enable; }
+    void setFullPrefix(const QString &cprefix) { fullPrefix = cprefix;}
+    void setFrame(int in_x, int in_y, int in_w, int in_h) { x=in_x; y=in_y; w=in_w; \
h=in_h; } +
+    int getSubX() { return x;}
+    int getSubY() { return y;}
+    int getSubW() { return w;}
+    int getSubH() { return h;}
+
+    void setBin(int xbin, int ybin) { binX = xbin; binY=ybin;}
+    int getXBin() { return binX; }
+    int getYBin() { return binY; }
+
+    void setDelay(int in_delay) { delay = in_delay; }
+    void setCount(int in_count) { count = in_count;}    
+    void setExposure(double duration) { exposure = duration;}
+    void setStatusCell(QTableWidgetItem *cell) { statusCell = cell; }
+    void setCompleted(unsigned int in_completed) { completed = in_completed;}
+    int getISOIndex() const;
+    void setISOIndex(int value);
+
+    double getExposeLeft() const;
+    void setExposeLeft(double value);
+    void resetStatus();
+    void setPrefixSettings(const QString &fullPrefix, bool filterEnabled, bool \
exposureEnabled, bool tsEnabled); +    void getPrefixSettings(QString &fullPrefix, \
bool &filterEnabled, bool &exposureEnabled, bool &tsEnabled); +
+    bool isFilterPrefixEnabled() { return filterPrefixEnabled; }
+    bool isExposurePrefixEnabled() { return expPrefixEnabled; }
+    bool isTimestampPrefixEnabled() { return timeStampPrefixEnabled;}
+
+    double getCurrentTemperature() const;
+    void setCurrentTemperature(double value);
+
+    double getTargetTemperature() const;
+    void setTargetTemperature(double value);    
+
+    double getTargetADU() const;
+    void setTargetADU(double value);
+
+    int getCaptureRetires() const;
+    void setCaptureRetires(int value);
+
+    FlatFieldSource getFlatFieldSource() const;
+    void setFlatFieldSource(const FlatFieldSource &value);
+
+    FlatFieldDuration getFlatFieldDuration() const;
+    void setFlatFieldDuration(const FlatFieldDuration &value);
+
+    SkyPoint getWallCoord() const;
+    void setWallCoord(const SkyPoint &value);
+
+    bool isPreMountPark() const;
+    void setPreMountPark(bool value);
+
+    bool isPreDomePark() const;
+    void setPreDomePark(bool value);
+
+    bool getEnforceTemperature() const;
+    void setEnforceTemperature(bool value);
+
+    QString getRootFITSDir() const;
+    void setRootFITSDir(const QString &value);
+
+    bool getFilterPostFocusReady() const;
+    void setFilterPostFocusReady(bool value);
+
+signals:
+    void prepareComplete();
+    void checkFocus();
+
+private:
+
+    QStringList statusStrings;
+    ISD::CCDChip *activeChip;
+    ISD::CCD *activeCCD;
+    ISD::GDInterface *activeFilter;
+
+    double exposure;
+    int frameType;
+    QString frameTypeName;
+    int targetFilter;
+    int currentFilter;
+
+    QString filter;    
+    int binX, binY;
+    int x,y,w,h;
+    QString fullPrefix;
+    int count;
+    int delay;    
+    bool preview;
+    bool filterReady, temperatureReady, filterPostFocusReady, prepareReady;
+    bool enforceTemperature;
+    int isoIndex;
+    int captureRetires;
+    unsigned int completed;
+    double exposeLeft;
+    double currentTemperature, targetTemperature;
+    FITSScale captureFilter;
+    QTableWidgetItem *statusCell;
+    QString fitsDir;
+    QString rootFITSDir;
+
+    bool typePrefixEnabled, filterPrefixEnabled, expPrefixEnabled, \
timeStampPrefixEnabled; +    QString rawPrefix;
+
+    JOBStatus status;
+
+    // Flat field variables
+    struct
+    {
+        double targetADU;
+        FlatFieldSource flatFieldSource;
+        FlatFieldDuration flatFieldDuration;
+        SkyPoint wallCoord;
+        bool preMountPark;
+        bool preDomePark;
+
+    } calibrationSettings;
+
+
+
+};
+
+}
+
+#endif  // SEQUENCEJOB_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic