/** * @file ScosTime/gui.cpp * @brief GUI for the ScosTime application * @author Enar Vaikene * * Copyright (c) 2012 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "gui.h" #include "version.h" #include #include #include #include #include #include VER_EXPORT_VERSION_INFO() 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())); } bool Module::init(QString const & args) { Q_UNUSED(args); // Get the main window interface and fill it with the widgets SdiWindow::iSdiWindow * win = evafQueryInterface("iSdiWindow"); EVAF_TEST_X(win, "No iSdiWindow interface"); Gui::Panel * panel = new Gui::Panel; win->addPanel("PswGen", panel); QVBoxLayout * v = new QVBoxLayout; panel->setLayout(v); QGridLayout * g = new QGridLayout; v->addLayout(g); g->setColumnStretch(1, 2); QLabel * l = new QLabel(tr("&Epoch:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); g->addWidget(l, 0, 0); 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); l = new QLabel(tr("&Date/time:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); g->addWidget(l, 1, 0); wDateTime = new QLineEdit; l->setBuddy(wDateTime); 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(); btn->setDisabled(true); g->addWidget(btn, 1, 2); connect(btn, SIGNAL(clicked()), this, SLOT(dateTimeClicked())); wConvertDateTime = btn; l = new QLabel(tr("&CUC:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); g->addWidget(l, 2, 0); 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(); QHBoxLayout * h = new QHBoxLayout; h->addStretch(); v->addLayout(h); QAction * a = new QAction(panel); a->setShortcut(Qt::Key_Escape); connect(a, SIGNAL(triggered()), qApp, SLOT(quit())); panel->addAction(a); mReady = true; EVAF_INFO("%s initialized", qPrintable(objectName())); return true; } void Module::done() { mReady = false; EVAF_INFO("%s finalized", qPrintable(objectName())); } Module::DateTimeType Module::getDateTimeType(QString const & s) const { if (rxIsoDateTime->exactMatch(s)) return IsoDateTime; else if (rxAsdDateTime->exactMatch(s)) return AsdDateTime; else return InvalidDateTime; } 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(); } } 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) { } void Module::setCucHexFromDateTime(QString const & s, DateTimeType type) { // Get the epoch QDateTime epoch = QDateTime::fromString(wEpoch->currentText(), Qt::ISODate); epoch.setTimeSpec(Qt::UTC); // 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)); // Set the CUC hex string wCucHex->setText(QString("%1%2").arg(coarse, 8, 16, QChar('0')).arg(fine, 4, 16, QChar('0'))); } 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 = s.left(8).toLong(&ok, 16); if (!ok) return; int fine = 0; 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)); // 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; } }