]> vaikene.ee Git - evaf/commitdiff
Merge branch 'ScosTime' into qt5
authorEnar Väikene <enar@vaikene.net>
Thu, 7 Nov 2013 12:03:28 +0000 (14:03 +0200)
committerEnar Väikene <enar@vaikene.net>
Thu, 7 Nov 2013 12:03:28 +0000 (14:03 +0200)
1  2 
src/apps/ScosTime/gui.cpp
src/apps/ScosTime/gui.h

index 1a978afa34612aafc6ac15ce13bfbd3472596a04,74d980ef58fac19ddc414a0f11e9f93f76d3bdf2..e8c2ae9d1d6f2a40dbbb390cae20a6d97096865c
@@@ -18,6 -18,7 +18,6 @@@
   */
  
  #include "gui.h"
 -#include "version.h"
  
  #include <Common/Globals>
  #include <Common/iLogger>
  #include <SdiWindow/iSdiWindow>
  #include <Gui/Panel>
  
 -#include <QtGui>
 +#include <QtWidgets>
  
  
  VER_EXPORT_VERSION_INFO()
 -Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::ScosTime::Module)
  
  
  //-------------------------------------------------------------------
  using namespace eVaf;
  using namespace eVaf::ScosTime;
  
+ //-------------------------------------------------------------------
+ Internal::DateTime::DateTime()
+     : mType(Invalid)
+     , mEpoch(QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC))
+     , mRxIso(new QRegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{3})?)?$"))
+     , mRxAsd(new QRegExp("^\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}(\\.\\d{2}(\\.\\d{3})?)?$"))
+     , mRxCUC(new QRegExp("^[0-9a-f]{8}([0-9a-f]{4})?$", Qt::CaseInsensitive))
+ {}
+ Internal::DateTime::~DateTime()
+ {
+     delete mRxCUC;
+     delete mRxAsd;
+     delete mRxIso;
+ }
+ Internal::DateTime::Type Internal::DateTime::setDateTime(QString const & s, QDateTime const & epoch)
+ {
+     mEpoch = epoch;
+     return setDateTime(s);
+ }
+ Internal::DateTime::Type Internal::DateTime::setDateTime(QString const & s)
+ {
+     // Detect the type of the date/time string
+     mType = getDateTimeType(s);
+     if (mType == Invalid)
+     {
+         return mType;
+     }
+     // Convert the string to a date/time value
+     mDateTime = strToDateTime(s, mType);
+     if (!mDateTime.isValid())
+     {
+         mType = Invalid;
+     }
+     return mType;
+ }
+ void Internal::DateTime::setEpoch(QDateTime const & epoch)
+ {
+     if (!epoch.isValid())
+     {
+         return;
+     }
+     if (epoch != mEpoch)
+     {
+         // Adjust the date/time if the value was set from a CUC HEX string
+         if (mType == CUC && mDateTime.isValid())
+         {
+             qint64 diff = mEpoch.msecsTo(epoch);
+             mDateTime = mDateTime.addMSecs(diff);
+         }
+         mEpoch = epoch;
+     }
+ }
+ Internal::DateTime::Type Internal::DateTime::getDateTimeType(QString const & s) const
+ {
+     if (mRxIso->exactMatch(s))
+     {
+         return ISO;
+     }
+     else if (mRxAsd->exactMatch(s))
+     {
+         return ASD;
+     }
+     else if (mRxCUC->exactMatch(s))
+     {
+         return CUC;
+     }
+     return Invalid;
+ }
+ QDateTime Internal::DateTime::strToDateTime(QString const & s, Type type) const
+ {
+     switch (type)
+     {
+         case ASD:
+         {
+             // 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 ISO:
+         {
+             // Using the ISO format yyyy-MM-ddThh:mm:ss[.zzz]
+             QString tmp = s;
+             if (tmp.length() < 19)
+             {
+                 tmp += ":00";
+             }
+             QDateTime dt = QDateTime::fromString(tmp, Qt::ISODate);
+             dt.setTimeSpec(Qt::UTC);
+             return dt;
+             break;
+         }
+         case CUC:
+         {
+             // Get the CUC coarse and fine values
+             bool ok = false;
+             int coarse = s.left(8).toLong(&ok, 16);
+             if (!ok)
+             {
+                 return QDateTime();
+             }
+             int fine = 0;
+             if (s.size() == 12)
+             {
+                 fine = s.mid(8, 4).toLong(&ok, 16);
+                 if (!ok)
+                 {
+                     return QDateTime();
+                 }
+             }
+             // Get the date/time value
+             QDateTime tm = mEpoch.addSecs(coarse);
+             tm = tm.addMSecs(rint((double(fine) / 58.0 * 885.0) / 1000.0));
+             return tm;
+             break;
+         }
+         default:
+         {
+             return QDateTime();
+         }
+     }
+ }
+ QString Internal::DateTime::asISOstring() const
+ {
+     if (mDateTime.isValid())
+     {
+         return mDateTime.toString("yyyy-MM-ddThh:mm:ss.zzz"); 
+     }
+     return QString();
+ }
+ QString Internal::DateTime::asASDstring() const
+ {
+     if (mDateTime.isValid())
+     {
+         return QString("%1.%2.%3.%4.%5.%6")
+             .arg(mDateTime.date().year(), 4, 10, QChar('0'))
+             .arg(mDateTime.date().dayOfYear(), 3, 10, QChar('0'))
+             .arg(mDateTime.time().hour(), 2, 10, QChar('0'))
+             .arg(mDateTime.time().minute(), 2, 10, QChar('0'))
+             .arg(mDateTime.time().second(), 2, 10, QChar('0'))
+             .arg(mDateTime.time().msec(), 3, 10, QChar('0'));
+     }
+     return QString();
+ }
+ QString Internal::DateTime::asCUChexString() const
+ {
+     if (!mDateTime.isValid())
+     {
+         return QString();
+     }
+     // Convert to CUC coarse and fine values
+     qint64 msecs = mEpoch.msecsTo(mDateTime);
+     quint32 coarse = quint32(msecs / 1000);
+     quint32 fine = quint32(rint(1000.0 * double(msecs % 1000) * 58.0 / 885.0));
+     // Set the CUC hex string
+     return QString("%1%2").arg(coarse, 8, 16, QChar('0')).arg(fine, 4, 16, QChar('0'));
+ }
+ //-------------------------------------------------------------------
  Module::Module()
      : Plugins::iPlugin()
      , mReady(false)
+     , mLastDateTimeType(Internal::DateTime::Invalid)
  {
      setObjectName(QString("%1.%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__));
  
@@@ -75,7 -306,12 +304,12 @@@ bool Module::init(QString const & args
      wEpoch = new QComboBox;
      l->setBuddy(wEpoch);
      wEpoch->setEditable(true);
+     {
+         QRegExp rx("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$");
+         wEpoch->setValidator(new QRegExpValidator(rx, 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);
  
  
      wDateTime = new QLineEdit;
      l->setBuddy(wDateTime);
-     QRegExp rxDateTime("^\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}(\\.\\d{3})?$");
-     wDateTime->setValidator(new QRegExpValidator(rxDateTime, wDateTime));
+     {
+         QRegExp rx("^(\\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(rx, 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);
+     {
+         QRegExp rx("^[0-9a-f]{8}([0-9a-f]{4})?$", Qt::CaseInsensitive);
+         wCucHex->setValidator(new QRegExpValidator(rx, wCucHex));
+     }
+     connect(wCucHex, SIGNAL(textEdited(QString)), this, SLOT(cucHexEdited(QString)));
+     g->addWidget(wCucHex, 2, 1);
  
      v->addStretch();
  
@@@ -132,73 -373,137 +371,137 @@@ void Module::done(
      EVAF_INFO("%s finalized", qPrintable(objectName()));
  }
  
- QDateTime Module::strToDateTime(QString const & s) const
- {
-     QStringList tok = s.split(QChar('.'));
-     if (tok.size() < 5)
-         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 = tok.at(4).toInt(&ok);
-     if (!ok)
-         return QDateTime();
-     int msecs = 0;
-     if (tok.size() > 5) {
-         msecs = tok.at(5).toInt(&ok);
-         if (!ok)
-             return QDateTime();
+ void Module::dateTimeClicked()
+ {
+     if (!mDateTime.isValid())
+     {
+         return;
      }
  
-     QDate dt(year, 1, 1);
-     dt = dt.addDays(days - 1);
+     // Convert to another type
+     switch (mLastDateTimeType)
+     {
+         case Internal::DateTime::ISO:
+         {
+             mLastDateTimeType = Internal::DateTime::ASD;
+             wDateTime->setText(mDateTime.asASDstring());
+             wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+             break;
+         }
+         case Internal::DateTime::ASD:
+         {
+             mLastDateTimeType = Internal::DateTime::ISO;
+             wDateTime->setText(mDateTime.asISOstring());
+             wConvertDateTime->setText(tr("&to ASD", VER_MODULE_NAME_STR));
+             break;
+         }
+         default:
+             break;
+     }
+ }
+ void Module::dateTimeEdited(QString const & s)
+ {
+     wConvertDateTime->setDisabled(true);
+     wConvertDateTime->setText(QString());
+     mLastDateTimeType = Internal::DateTime::Invalid;
  
-     return QDateTime(dt, QTime(hours, minutes, secs, msecs), Qt::UTC);
+     if (s.isEmpty())
+     {
+         return;
+     }
+     mDateTime.setDateTime(s);
+     if (!mDateTime.isValid())
+     {
+         return;
+     }
+     mLastDateTimeType = mDateTime.type();
+     // Set the CUC hex string from this date/time string
+     wCucHex->setText(mDateTime.asCUChexString());
+     // Enable the button that converts between ISO and ASD date/time strings
+     if (mDateTime.type() == Internal::DateTime::ISO)
+     {
+         wConvertDateTime->setEnabled(true);
+         wConvertDateTime->setText(tr("&to ASD", VER_MODULE_NAME_STR));
+     }
+     else if (mDateTime.type() == Internal::DateTime::ISO)
+     {
+         wConvertDateTime->setEnabled(true);
+         wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+     }
  }
  
- void Module::dateTimeClicked()
+ void Module::cucHexEdited(QString const & s)
  {
-     QDateTime epoch = QDateTime::fromString(wEpoch->currentText(), Qt::ISODate);
-     epoch.setTimeSpec(Qt::UTC);
-     QDateTime tm = strToDateTime(wDateTime->text());
-     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')));
+     if (s.isEmpty() || s.size() < 8)
+     {
+         return;
+     }
+     mDateTime.setDateTime(s);
+     if (!mDateTime.isValid())
+     {
+         return;
+     }
+     if (mLastDateTimeType == Internal::DateTime::Invalid)
+     {
+         mLastDateTimeType = Internal::DateTime::ASD;
+     }
+     // Set the date/time string in the last used format
+     if (mLastDateTimeType == Internal::DateTime::ASD)
+     {
+         wDateTime->setText(mDateTime.asASDstring());
+         wConvertDateTime->setEnabled(true);
+         wConvertDateTime->setText(tr("&to ISO", VER_MODULE_NAME_STR));
+     }
+     else if (mLastDateTimeType == Internal::DateTime::ISO)
+     {
+         wDateTime->setText(mDateTime.asISOstring());
+         wConvertDateTime->setEnabled(true);
+         wConvertDateTime->setText(tr("&to ASD", VER_MODULE_NAME_STR));
+     }
  }
  
- void Module::hexClicked()
+ void Module::epochChanged(QString const & s)
  {
-     bool ok = false;
-     int coarse = wHex->text().left(8).toLong(&ok, 16);
-     if (!ok)
+     if (s.isEmpty())
          return;
-     int fine = 0;
-     if (wHex->text().size() > 8)
-         fine = wHex->text().mid(8, 4).toLong(&ok, 16);
-     if (!ok)
+     QRegExp rx("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$");
+     if (!rx.exactMatch(s))
          return;
  
-     QDateTime epoch = QDateTime::fromString(wEpoch->currentText(), Qt::ISODate);
-     epoch.setTimeSpec(Qt::UTC);
-     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')));
+     QDateTime dt = QDateTime::fromString(s, Qt::ISODate);
+     dt.setTimeSpec(Qt::UTC);
+     mDateTime.setEpoch(dt);
+     // If there is a valid entry, do the conversion
+     switch (mDateTime.type())
+     {
+         case Internal::DateTime::ISO:
+         case Internal::DateTime::ASD:
+         {
+             wCucHex->setText(mDateTime.asCUChexString());
+             break;
+         }
+         case Internal::DateTime::CUC:
+         {
+             if (mLastDateTimeType == Internal::DateTime::ASD)
+             {
+                 wDateTime->setText(mDateTime.asASDstring());
+             }
+             else if (mLastDateTimeType == Internal::DateTime::ISO)
+             {
+                 wDateTime->setText(mDateTime.asISOstring());
+             }
+             break;
+         }
+         default:
+             break;
+     }
  }
diff --combined src/apps/ScosTime/gui.h
index 581760bc1daaab003b29e944dbd2c4593067d894,1ce7972344dfb574bacde9050f66c03385adb0f8..42516e5ec736af20be2a74a0a9fe776a55c3143d
@@@ -20,8 -20,6 +20,8 @@@
  #ifndef __SCOSTIME_GUI_H
  #  define __SCOSTIME_GUI_H
  
 +#include "version.h"
 +
  #include <Plugins/iPlugin>
  
  #include <QObject>
  
  class QLineEdit;
  class QComboBox;
+ class QRegExp;
+ class QPushButton;
  
  namespace eVaf {
  namespace ScosTime {
  
+ namespace Internal {
+ /**
+  * SCOS date/time class
+  */
+ class DateTime
+ {
+ public:
+     /// Type of the date/time entry
+     enum Type
+     {
+         Invalid,
+         ASD,
+         ISO,
+         CUC
+     };
+     /**
+      * Creates an invalid date/time value with the default epoch
+      */
+     DateTime();
+     /**
+      * Dtor
+      */
+     ~DateTime();
+     /**
+      * Sets the date/time value from a string.
+      * @param s Input string
+      * @param epoch Epoch
+      * @return Type of the input string
+      *
+      * 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.
+      */
+     Type setDateTime(QString const & s, QDateTime const & epoch);
+     /**
+      * Sets the date/time value from a string using the previously set epoch.
+      * @param s Input string
+      * @return Type of the input string
+      *
+      * 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 input string is invalid or no epoch is set, creates an invalid
+      * date/time value.
+      */
+     Type setDateTime(QString const & s);
+     /**
+      * Sets the epoch
+      * @param epoch Epoch
+      */
+     void setEpoch(QDateTime const & epoch);
+     /**
+      * Returns the current epoch
+      */
+     QDateTime const & epoch() const { return mEpoch; }
+     /**
+      * Returns true if the date/time value is valid.
+      */
+     bool isValid() const { return mDateTime.isValid(); }
+     /**
+      * Returns the type of the date/time string from which the date/time
+      * value was created.
+      */
+     Type type() const { return mType; }
+     /**
+      * Returns the current date/time value
+      */
+     QDateTime const & dateTime() const { return mDateTime; }
+     /**
+      * 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: // methods
+     Type getDateTimeType(QString const & s) const;
+     QDateTime strToDateTime(QString const & s, Type t) const;
+ private: // members
+     /// Type of the input string
+     Type mType;
+     /// Epoch
+     QDateTime mEpoch;
+     /// Date/time value
+     QDateTime mDateTime;
+     /// Regular expression for ISO date/time strings
+     QRegExp * mRxIso;
+     /// Regular expression for ASD date/time strings
+     QRegExp * mRxAsd;
+     /// Regular expression for CUC date/time strings
+     QRegExp * mRxCUC;
+ };
+ } // namespace eVaf::ScosTime::Internal
  /**
   * Graphical User Interface for the ScosTime application.
   *
@@@ -43,8 -175,14 +177,15 @@@ class Module : public Plugins::iPlugi
  {
      Q_OBJECT
      Q_INTERFACES(eVaf::Plugins::iPlugin)
 +    Q_PLUGIN_METADATA(IID VER_MODULE_NAME_STR)
  
+     enum ValidEntry
+     {
+         NoValidEntry,
+         DateTimeEntry,
+         CUCEntry
+     };
  public:
  
      Module();
  
  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;
  
  private: // Members
  
      /// Flag indicating that the module is ready
      bool mReady;
  
+     /// Current date/time value
+     Internal::DateTime mDateTime;
+     /// Last date/time format type used in the date/time entry field
+     Internal::DateTime::Type mLastDateTimeType;
      /// Widgets on the screen
      QComboBox * wEpoch;
      QLineEdit * wDateTime;
-     QLineEdit * wHex;
+     QPushButton * wConvertDateTime;
+     QLineEdit * wCucHex;
  
  };