X-Git-Url: https://vaikene.ee/gitweb/gitweb.cgi?p=evaf;a=blobdiff_plain;f=src%2Fapps%2FScosTime%2Fgui.cpp;fp=src%2Fapps%2FScosTime%2Fgui.cpp;h=e8c2ae9d1d6f2a40dbbb390cae20a6d97096865c;hp=1a978afa34612aafc6ac15ce13bfbd3472596a04;hb=0c61450fcffcb36a6e23ca5b083c26543d956084;hpb=a81a943bee20df3c7eb34bafb3e3fe878facfe4e diff --git a/src/apps/ScosTime/gui.cpp b/src/apps/ScosTime/gui.cpp index 1a978af..e8c2ae9 100644 --- a/src/apps/ScosTime/gui.cpp +++ b/src/apps/ScosTime/gui.cpp @@ -36,9 +36,238 @@ VER_EXPORT_VERSION_INFO() 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 +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); @@ -85,27 +319,32 @@ 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})?$"); - 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 +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; + } }