]> vaikene.ee Git - evaf/commitdiff
Making the ScosTime application more user friendly (unfinished).
authorEnar Vaikene <enar.vaikene@logica.com>
Tue, 14 Aug 2012 07:05:20 +0000 (10:05 +0300)
committerEnar Väikene <enar@vaikene.net>
Tue, 10 Sep 2013 07:04:27 +0000 (10:04 +0300)
src/apps/ScosTime/gui.cpp
src/apps/ScosTime/gui.h

index 1ea9ba1d744866a62f2a58dc7c023536d78a4009..6efd962c5e791f4e7f03ae2e04cc2d78fccc2778 100644 (file)
@@ -38,17 +38,34 @@ Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::ScosTime::Module)
 using namespace eVaf;
 using namespace eVaf::ScosTime;
 
+
+//-------------------------------------------------------------------
+
+Internal::DateTime::DateTime(QString const & s, QString const & epoch)
+{
+
+}
+
+
+//-------------------------------------------------------------------
+
 Module::Module()
     : Plugins::iPlugin()
     , mReady(false)
+    , mLastValidEntry(NoValidEntry)
 {
     setObjectName(QString("%1.%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__));
 
+    rxIsoDateTime = new QRegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(.\\d{3})?)?$");
+    rxAsdDateTime = new QRegExp("^\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}(\\.\\d{2}(\\.\\d{3})?)?$");
+
     EVAF_INFO("%s created", qPrintable(objectName()));
 }
 
 Module::~Module()
 {
+    delete rxIsoDateTime;
+    delete rxAsdDateTime;
     EVAF_INFO("%s destroyed", qPrintable(objectName()));
 }
 
@@ -77,7 +94,9 @@ bool Module::init(QString const & args)
     wEpoch = new QComboBox;
     l->setBuddy(wEpoch);
     wEpoch->setEditable(true);
+    wEpoch->setValidator(new QRegExpValidator(*rxIsoDateTime, wEpoch));
     wEpoch->addItems(QStringList() << "1970-01-01T00:00:00.000" << "1999-08-22T00:00:00.000");
+    connect(wEpoch, SIGNAL(editTextChanged(QString)), this, SLOT(epochChanged(QString)));
     g->addWidget(wEpoch, 0, 1);
     panel->setFocusProxy(wEpoch);
 
@@ -87,27 +106,27 @@ bool Module::init(QString const & args)
 
     wDateTime = new QLineEdit;
     l->setBuddy(wDateTime);
-    QRegExp rxDateTime("^\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}(\\.\\d{3})?$");
+    QRegExp rxDateTime("^(\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}(\\.\\d{3})?)|(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(.\\d{3})?)$");
     wDateTime->setValidator(new QRegExpValidator(rxDateTime, wDateTime));
+    connect(wDateTime, SIGNAL(textEdited(QString)), this, SLOT(dateTimeEdited(QString)));
     g->addWidget(wDateTime, 1, 1);
 
-    QPushButton * btn = new QPushButton(tr("Convert", VER_MODULE_NAME_STR));
+    QPushButton * btn = new QPushButton();
+    btn->setDisabled(true);
     g->addWidget(btn, 1, 2);
     connect(btn, SIGNAL(clicked()), this, SLOT(dateTimeClicked()));
+    wConvertDateTime = btn;
 
-    l = new QLabel(tr("&HEX:", VER_MODULE_NAME_STR));
+    l = new QLabel(tr("&CUC:", VER_MODULE_NAME_STR));
     l->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
     g->addWidget(l, 2, 0);
 
-    wHex = new QLineEdit;
-    l->setBuddy(wHex);
-    wHex->setMaxLength(12);
-    wHex->setInputMask(">HHHHHHHHhhhh");
-    g->addWidget(wHex, 2, 1);
-
-    btn = new QPushButton(tr("Convert", VER_MODULE_NAME_STR));
-    g->addWidget(btn, 2, 2);
-    connect(btn, SIGNAL(clicked()), this, SLOT(hexClicked()));
+    wCucHex = new QLineEdit;
+    l->setBuddy(wCucHex);
+    wCucHex->setMaxLength(12);
+    wCucHex->setInputMask(">HHHHHHHHhhhh");
+    connect(wCucHex, SIGNAL(textEdited(QString)), this, SLOT(cucHexEdited(QString)));
+    g->addWidget(wCucHex, 2, 1);
 
     v->addStretch();
 
@@ -134,73 +153,217 @@ void Module::done()
     EVAF_INFO("%s finalized", qPrintable(objectName()));
 }
 
-QDateTime Module::strToDateTime(QString const & s) const
+Module::DateTimeType Module::getDateTimeType(QString const & s) const
 {
-    QStringList tok = s.split(QChar('.'));
-    if (tok.size() < 5)
-        return QDateTime();
+    if (rxIsoDateTime->exactMatch(s))
+        return IsoDateTime;
+    else if (rxAsdDateTime->exactMatch(s))
+        return AsdDateTime;
+    else
+        return InvalidDateTime;
+}
 
-    bool ok = false;
-    int year = tok.at(0).toInt(&ok);
-    if (!ok)
-        return QDateTime();
-    int days = tok.at(1).toInt(&ok);
-    if (!ok)
-        return QDateTime();
-    int hours = tok.at(2).toInt(&ok);
-    if (!ok)
-        return QDateTime();
-    int minutes = tok.at(3).toInt(&ok);
-    if (!ok)
-        return QDateTime();
-    int secs = tok.at(4).toInt(&ok);
-    if (!ok)
-        return QDateTime();
-    int msecs = 0;
-    if (tok.size() > 5) {
-        msecs = tok.at(5).toInt(&ok);
-        if (!ok)
+QDateTime Module::strToDateTime(QString const & s, DateTimeType type) const
+{
+    switch (type)
+    {
+        case AsdDateTime:
+        {
+            // Using the yyyy.ddd.hh.mm.ss[.zzz] format
+            QStringList tok = s.split(QChar('.'));
+            if (tok.size() < 4)
+                return QDateTime();
+
+            bool ok = false;
+            int year = tok.at(0).toInt(&ok);
+            if (!ok)
+                return QDateTime();
+            int days = tok.at(1).toInt(&ok);
+            if (!ok)
+                return QDateTime();
+            int hours = tok.at(2).toInt(&ok);
+            if (!ok)
+                return QDateTime();
+            int minutes = tok.at(3).toInt(&ok);
+            if (!ok)
+                return QDateTime();
+            int secs = 0;
+            int msecs = 0;
+            if (tok.size() > 4) {
+                secs = tok.at(4).toInt(&ok);
+                if (!ok)
+                    return QDateTime();
+                if (tok.size() > 5) {
+                    msecs = tok.at(5).toInt(&ok);
+                    if (!ok)
+                        return QDateTime();
+                }
+            }
+
+            QDate dt(year, 1, 1);
+            dt = dt.addDays(days - 1);
+
+            return QDateTime(dt, QTime(hours, minutes, secs, msecs), Qt::UTC);
+            break;
+        }
+        case IsoDateTime:
+        {
+            // Using the ISO format yyyy-MM-ddThh:mm:ss[.zzz]
+            QDateTime dt = QDateTime::fromString(s, Qt::ISODate);
+            dt.setTimeSpec(Qt::UTC);
+            return dt;
+            break;
+        }
+        default:
             return QDateTime();
     }
+}
 
-    QDate dt(year, 1, 1);
-    dt = dt.addDays(days - 1);
+QString Module::dateTimeToAsdStr(QDateTime const & tm) const
+{
+    return QString("%1.%2.%3.%4.%5.%6")
+            .arg(tm.date().year(), 4, 10, QChar('0'))
+            .arg(tm.date().dayOfYear(), 3, 10, QChar('0'))
+            .arg(tm.time().hour(), 2, 10, QChar('0'))
+            .arg(tm.time().minute(), 2, 10, QChar('0'))
+            .arg(tm.time().second(), 2, 10, QChar('0'))
+            .arg(tm.time().msec(), 3, 10, QChar('0'));
+}
+
+void Module::setDateTimeFromCucHex(QString const & s)
+{
 
-    return QDateTime(dt, QTime(hours, minutes, secs, msecs), Qt::UTC);
 }
 
-void Module::dateTimeClicked()
+void Module::setCucHexFromDateTime(QString const & s, DateTimeType type)
 {
+    // Get the epoch
     QDateTime epoch = QDateTime::fromString(wEpoch->currentText(), Qt::ISODate);
     epoch.setTimeSpec(Qt::UTC);
-    QDateTime tm = strToDateTime(wDateTime->text());
+
+    // Convert the date/time string to a QDateTime type
+    QDateTime tm = strToDateTime(s, type);
+
+    // Convert to CUC coarse and fine values
     qint64 msecs = epoch.msecsTo(tm);
     quint32 coarse = quint32(msecs / 1000);
     quint32 fine = quint32(rint(1000.0 * double(msecs % 1000) * 58.0 / 885.0));
-    wHex->setText(QString("%1%2").arg(coarse, 8, 16, QChar('0')).arg(fine, 4, 16, QChar('0')));
+
+    // Set the CUC hex string
+    wCucHex->setText(QString("%1%2").arg(coarse, 8, 16, QChar('0')).arg(fine, 4, 16, QChar('0')));
 }
 
-void Module::hexClicked()
+void Module::dateTimeClicked()
 {
+    // Get the date/time string, type and QDateTime value
+    QString s = wDateTime->text();
+    DateTimeType type = getDateTimeType(s);
+    QDateTime tm = strToDateTime(s, type);
+
+    // Convert to another type
+    switch (type)
+    {
+        case IsoDateTime:
+        {
+            wDateTime->setText(dateTimeToAsdStr(tm));
+            wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+            break;
+        }
+        case AsdDateTime:
+        {
+            wDateTime->setText(tm.toString("yyyy-MM-ddThh:mm:ss.zzz"));
+            wConvertDateTime->setText(tr("&to ASD", VER_MODULE_NAME_STR));
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+void Module::dateTimeEdited(QString const & s)
+{
+    if (mLastValidEntry == DateTimeEntry)
+        mLastValidEntry = NoValidEntry;
+    wConvertDateTime->setDisabled(true);
+    wConvertDateTime->setText(QString());
+
+    if (s.isEmpty())
+        return;
+
+    // Detect the type of the date/time string
+    DateTimeType type = getDateTimeType(s);
+    if (type == InvalidDateTime)
+        return;
+
+    // Set the date/time field as the last valid entry done by the user
+    mLastValidEntry = DateTimeEntry;
+
+    // Set the CUC hex string from this date/time string
+    setCucHexFromDateTime(s);
+
+    // Enable the button that converts between ISO and ASD date/time strings
+    if (type == IsoDateTime) {
+        wConvertDateTime->setEnabled(true);
+        wConvertDateTime->setText(tr("&to ASD", VER_MODULE_NAME_STR));
+    }
+    else if (type == AsdDateTime) {
+        wConvertDateTime->setEnabled(true);
+        wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+    }
+}
+
+void Module::cucHexEdited(QString const & s)
+{
+    if (mLastValidEntry == CUCEntry)
+        mLastValidEntry = NoValidEntry;
+    if (s.isEmpty() || s.size() < 8)
+        return;
+
+    // Get the CUC coarse and fine values
     bool ok = false;
-    int coarse = wHex->text().left(8).toLong(&ok, 16);
+    int coarse = s.left(8).toLong(&ok, 16);
     if (!ok)
         return;
     int fine = 0;
-    if (wHex->text().size() > 8)
-        fine = wHex->text().mid(8, 4).toLong(&ok, 16);
+    if (s.size() == 12)
+        fine = s.mid(8, 4).toLong(&ok, 16);
     if (!ok)
         return;
 
+    // Set the CUC field as the last valid entry done by the user
+    mLastValidEntry = CUCEntry;
+
+    // Get the epoch
     QDateTime epoch = QDateTime::fromString(wEpoch->currentText(), Qt::ISODate);
     epoch.setTimeSpec(Qt::UTC);
+
+    // Get the date/time value
     QDateTime tm = epoch.addSecs(coarse);
     tm = tm.addMSecs(rint((double(fine) / 58.0 * 885.0) / 1000.0));
-    wDateTime->setText(QString("%1.%2.%3.%4.%5.%6")
-                       .arg(tm.date().year(), 4, 10, QChar('0'))
-                       .arg(tm.date().dayOfYear(), 3, 10, QChar('0'))
-                       .arg(tm.time().hour(), 2, 10, QChar('0'))
-                       .arg(tm.time().minute(), 2, 10, QChar('0'))
-                       .arg(tm.time().second(), 2, 10, QChar('0'))
-                       .arg(tm.time().msec(), 3, 10, QChar('0')));
+
+    // Set the date/time string in ASD format
+    wDateTime->setText(dateTimeToAsdStr(tm));
+
+    // Enable conversion to ISO format
+    wConvertDateTime->setEnabled(true);
+    wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+}
+
+void Module::epochChanged(QString const & s)
+{
+    if (s.isEmpty())
+        return;
+    if (!rxIsoDateTime->exactMatch(s))
+        return;
+
+    // If there is a valid entry, do the conversion
+    switch (mLastValidEntry)
+    {
+    case DateTimeEntry:
+        break;
+    case CUCEntry:
+        break;
+    default:
+        break;
+    }
 }
index fe6b5e3f3dcad059f2b9c6d0f6983bf1570c4d26..90f33c2f90edf3e269acf84c022e355ce79d0d30 100644 (file)
 
 class QLineEdit;
 class QComboBox;
+class QRegExp;
+class QPushButton;
 
 namespace eVaf {
 namespace ScosTime {
 
+namespace Internal {
+
+/**
+ * SCOS date/time class
+ */
+class DateTime
+{
+public:
+
+    /**
+     * Creates an invalid date/time value
+     */
+    DateTime() {}
+
+    /**
+     * Creates a date/time value from the string.
+     * @param s Input string
+     * @param epoch Epoch
+     *
+     * The input string can be:
+     * @li Date/time in ISO format yyyy-MM-ddThh:mm[:ss[.zzz]]
+     * @li Date/time in ASD format yyyy.ddd.hh.mm[.ss[.zzz]]
+     * @li CUC hex string cccccccc[ffff]
+     *
+     * If the string is invalid, creates an invalid date/time value.
+     */
+    DateTime(String const & s, String const & epoch);
+
+    /**
+     * Returns true if the date/time value is valid.
+     */
+    bool isValid() const { return mDateTime.isValid(); }
+
+    /**
+     * Returns the date/time value a string in the ISO format yyyy-MM-ddThh:mm:ss.zzz
+     */
+    QString asIsoString() const;
+
+    /**
+     * Returns the date/time value as a string in the ASD format yyyy.ddd.hh.mm.ss.zzz
+     */
+    QString asAsdString() const;
+
+    /**
+     * Returns the date/time value as a CUC hex string in the format ccccccccffff
+     */
+    QString asCucHexString() const;
+
+
+private:
+
+    /// Date/time value
+    QDateTime mDateTime;
+
+    /// Epoch
+    QDateTime mEpoch;
+
+};
+
+} // namespace eVaf::ScosTime::Internal
+
 /**
  * Graphical User Interface for the ScosTime application.
  *
@@ -42,6 +105,20 @@ class Module : public Plugins::iPlugin
     Q_OBJECT
     Q_INTERFACES(eVaf::Plugins::iPlugin)
 
+    enum DateTimeType
+    {
+        InvalidDateTime,
+        AsdDateTime,
+        IsoDateTime
+    };
+
+    enum ValidEntry
+    {
+        NoValidEntry,
+        DateTimeEntry,
+        CUCEntry
+    };
+
 public:
 
     Module();
@@ -57,24 +134,45 @@ public:
 
 private slots:
 
+    void epochChanged(QString const & s);
+
     void dateTimeClicked();
 
-    void hexClicked();
+    void dateTimeEdited(QString const & s);
+
+    void cucHexEdited(QString const & s);
 
 
 private: // Methods
 
-    QDateTime strToDateTime(QString const & s) const;
+    DateTimeType getDateTimeType(QString const & s) const;
+
+    QDateTime strToDateTime(QString const & s, DateTimeType type) const;
+
+    QString dateTimeToAsdStr(QDateTime const & tm) const;
+
+    void setDateTimeFromCucHex(QString const & s);
+
+    void setCucHexFromDateTime(QString const & s, DateTimeType type);
+
 
 private: // Members
 
     /// Flag indicating that the module is ready
     bool mReady;
 
+    /// Last valid entry (field modified by the user)
+    ValidEntry mLastValidEntry;
+
+    /// Regular expressions
+    QRegExp * rxIsoDateTime;
+    QRegExp * rxAsdDateTime;
+
     /// Widgets on the screen
     QComboBox * wEpoch;
     QLineEdit * wDateTime;
-    QLineEdit * wHex;
+    QPushButton * wConvertDateTime;
+    QLineEdit * wCucHex;
 
 };