]>
vaikene.ee Git - evaf/blob - src/apps/ScosTime/gui.cpp
2 * @file ScosTime/gui.cpp
3 * @brief GUI for the ScosTime application
6 * Copyright (c) 2012-2019 Enar Vaikene
8 * This file is part of the eVaf C++ cross-platform application development framework.
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
22 #include <Common/Globals>
23 #include <Common/iLogger>
24 #include <Common/iRegistry>
25 #include <SdiWindow/iSdiWindow>
31 VER_EXPORT_VERSION_INFO()
34 //-------------------------------------------------------------------
37 using namespace eVaf::ScosTime
;
40 //-------------------------------------------------------------------
42 Internal::DateTime::DateTime()
44 , mEpoch(QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC
))
45 , mRxIso(new QRegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{3})?)?$"))
46 , mRxAsd(new QRegExp("^\\d{4}\\.\\d{3}\\.\\d{2}\\.\\d{2}(\\.\\d{2}(\\.\\d{3})?)?$"))
47 , mRxCUC(new QRegExp("^[0-9a-f]{8}([0-9a-f]{4})?$", Qt::CaseInsensitive
))
50 Internal::DateTime::~DateTime()
57 Internal::DateTime::Type
Internal::DateTime::setDateTime(QString
const & s
, QDateTime
const & epoch
)
60 return setDateTime(s
);
63 Internal::DateTime::Type
Internal::DateTime::setDateTime(QString
const & s
)
65 // Detect the type of the date/time string
66 mType
= getDateTimeType(s
);
72 // Convert the string to a date/time value
73 mDateTime
= strToDateTime(s
, mType
);
74 if (!mDateTime
.isValid())
83 void Internal::DateTime::setEpoch(QDateTime
const & epoch
)
92 // Adjust the date/time if the value was set from a CUC HEX string
93 if (mType
== CUC
&& mDateTime
.isValid())
95 qint64 diff
= mEpoch
.msecsTo(epoch
);
96 mDateTime
= mDateTime
.addMSecs(diff
);
102 Internal::DateTime::Type
Internal::DateTime::getDateTimeType(QString
const & s
) const
104 if (mRxIso
->exactMatch(s
))
108 else if (mRxAsd
->exactMatch(s
))
112 else if (mRxCUC
->exactMatch(s
))
119 QDateTime
Internal::DateTime::strToDateTime(QString
const & s
, Type type
) const
125 // Using the yyyy.ddd.hh.mm.ss[.zzz] format
126 QStringList tok
= s
.split(QChar('.'));
133 int year
= tok
.at(0).toInt(&ok
);
138 int days
= tok
.at(1).toInt(&ok
);
143 int hours
= tok
.at(2).toInt(&ok
);
148 int minutes
= tok
.at(3).toInt(&ok
);
157 secs
= tok
.at(4).toInt(&ok
);
164 msecs
= tok
.at(5).toInt(&ok
);
172 QDate
dt(year
, 1, 1);
173 dt
= dt
.addDays(days
- 1);
175 return QDateTime(dt
, QTime(hours
, minutes
, secs
, msecs
), Qt::UTC
);
179 // Using the ISO format yyyy-MM-ddThh:mm:ss[.zzz]
181 if (tmp
.length() < 19)
185 QDateTime dt
= QDateTime::fromString(tmp
, Qt::ISODate
);
186 dt
.setTimeSpec(Qt::UTC
);
191 // Get the CUC coarse and fine values
193 int const coarse
= static_cast<int>(s
.left(8).toLong(&ok
, 16));
201 fine
= static_cast<int>(s
.mid(8, 4).toLong(&ok
, 16));
208 // Get the date/time value
209 QDateTime tm
= mEpoch
.addSecs(coarse
);
210 tm
= tm
.addMSecs(static_cast<int>(rint((double(fine
) / 58.0 * 885.0) / 1000.0)));
220 QString
Internal::DateTime::asISOstring() const
222 if (mDateTime
.isValid())
224 return mDateTime
.toString("yyyy-MM-ddThh:mm:ss.zzz");
229 QString
Internal::DateTime::asASDstring() const
231 if (mDateTime
.isValid())
233 return QString("%1.%2.%3.%4.%5.%6")
234 .arg(mDateTime
.date().year(), 4, 10, QChar('0'))
235 .arg(mDateTime
.date().dayOfYear(), 3, 10, QChar('0'))
236 .arg(mDateTime
.time().hour(), 2, 10, QChar('0'))
237 .arg(mDateTime
.time().minute(), 2, 10, QChar('0'))
238 .arg(mDateTime
.time().second(), 2, 10, QChar('0'))
239 .arg(mDateTime
.time().msec(), 3, 10, QChar('0'));
244 QString
Internal::DateTime::asCUChexString() const
246 if (!mDateTime
.isValid())
251 // Convert to CUC coarse and fine values
252 qint64 msecs
= mEpoch
.msecsTo(mDateTime
);
253 quint32 coarse
= quint32(msecs
/ 1000);
254 quint32 fine
= quint32(rint(1000.0 * double(msecs
% 1000) * 58.0 / 885.0));
256 // Set the CUC hex string
257 return QString("%1%2").arg(coarse
, 8, 16, QChar('0')).arg(fine
, 4, 16, QChar('0'));
261 //-------------------------------------------------------------------
266 , mLastDateTimeType(Internal::DateTime::Invalid
)
268 setObjectName(QString("%1.%2").arg(VER_MODULE_NAME_STR
).arg(__FUNCTION__
));
270 EVAF_INFO("%s created", qPrintable(objectName()));
275 EVAF_INFO("%s destroyed", qPrintable(objectName()));
278 bool Module::init(QString
const & args
)
282 // Get the main window interface and fill it with the widgets
283 SdiWindow::iSdiWindow
* win
= evafQueryInterface
<SdiWindow::iSdiWindow
>("iSdiWindow");
284 EVAF_TEST_X(win
, "No iSdiWindow interface")
286 Gui::Panel
* panel
= new Gui::Panel
;
287 win
->addPanel("PswGen", panel
);
289 QVBoxLayout
* v
= new QVBoxLayout
;
292 QGridLayout
* g
= new QGridLayout
;
294 g
->setColumnStretch(1, 2);
296 QLabel
* l
= new QLabel(tr("&Epoch:", VER_MODULE_NAME_STR
));
297 l
->setAlignment(Qt::AlignRight
| Qt::AlignVCenter
);
298 g
->addWidget(l
, 0, 0);
300 wEpoch
= new QComboBox
;
302 wEpoch
->setEditable(true);
304 QRegExp
rx("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$");
305 wEpoch
->setValidator(new QRegExpValidator(rx
, wEpoch
));
307 wEpoch
->addItems(QStringList() << "1970-01-01T00:00:00.000" << "1999-08-22T00:00:00.000");
308 connect(wEpoch
, SIGNAL(editTextChanged(QString
)), this, SLOT(epochChanged(QString
)));
309 g
->addWidget(wEpoch
, 0, 1);
310 panel
->setFocusProxy(wEpoch
);
312 l
= new QLabel(tr("&Date/time:", VER_MODULE_NAME_STR
));
313 l
->setAlignment(Qt::AlignRight
| Qt::AlignVCenter
);
314 g
->addWidget(l
, 1, 0);
316 wDateTime
= new QLineEdit
;
317 l
->setBuddy(wDateTime
);
319 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})?)$");
320 wDateTime
->setValidator(new QRegExpValidator(rx
, wDateTime
));
322 connect(wDateTime
, SIGNAL(textEdited(QString
)), this, SLOT(dateTimeEdited(QString
)));
323 g
->addWidget(wDateTime
, 1, 1);
325 QPushButton
* btn
= new QPushButton();
326 btn
->setDisabled(true);
327 g
->addWidget(btn
, 1, 2);
328 connect(btn
, SIGNAL(clicked()), this, SLOT(dateTimeClicked()));
329 wConvertDateTime
= btn
;
331 l
= new QLabel(tr("&CUC:", VER_MODULE_NAME_STR
));
332 l
->setAlignment(Qt::AlignRight
| Qt::AlignVCenter
);
333 g
->addWidget(l
, 2, 0);
335 wCucHex
= new QLineEdit
;
336 l
->setBuddy(wCucHex
);
337 wCucHex
->setMaxLength(12);
339 QRegExp
rx("^[0-9a-f]{8}([0-9a-f]{4})?$", Qt::CaseInsensitive
);
340 wCucHex
->setValidator(new QRegExpValidator(rx
, wCucHex
));
342 connect(wCucHex
, SIGNAL(textEdited(QString
)), this, SLOT(cucHexEdited(QString
)));
343 g
->addWidget(wCucHex
, 2, 1);
347 QHBoxLayout
* h
= new QHBoxLayout
;
351 QAction
* a
= new QAction(panel
);
352 a
->setShortcut(Qt::Key_Escape
);
353 connect(a
, SIGNAL(triggered()), qApp
, SLOT(quit()));
358 EVAF_INFO("%s initialized", qPrintable(objectName()));
367 EVAF_INFO("%s finalized", qPrintable(objectName()));
370 void Module::dateTimeClicked()
372 if (!mDateTime
.isValid())
377 // Convert to another type
378 switch (mLastDateTimeType
)
380 case Internal::DateTime::ISO
:
382 mLastDateTimeType
= Internal::DateTime::ASD
;
383 wDateTime
->setText(mDateTime
.asASDstring());
384 wConvertDateTime
->setText(tr("&to ISO", VER_MODULE_NAME_STR
));
387 case Internal::DateTime::ASD
:
389 mLastDateTimeType
= Internal::DateTime::ISO
;
390 wDateTime
->setText(mDateTime
.asISOstring());
391 wConvertDateTime
->setText(tr("&to ASD", VER_MODULE_NAME_STR
));
399 void Module::dateTimeEdited(QString
const & s
)
401 wConvertDateTime
->setDisabled(true);
402 wConvertDateTime
->setText(QString());
403 mLastDateTimeType
= Internal::DateTime::Invalid
;
410 mDateTime
.setDateTime(s
);
411 if (!mDateTime
.isValid())
416 mLastDateTimeType
= mDateTime
.type();
418 // Set the CUC hex string from this date/time string
419 wCucHex
->setText(mDateTime
.asCUChexString());
421 // Enable the button that converts between ISO and ASD date/time strings
422 if (mDateTime
.type() == Internal::DateTime::ISO
)
424 wConvertDateTime
->setEnabled(true);
425 wConvertDateTime
->setText(tr("&to ASD", VER_MODULE_NAME_STR
));
427 else if (mDateTime
.type() == Internal::DateTime::ASD
)
429 wConvertDateTime
->setEnabled(true);
430 wConvertDateTime
->setText(tr("&to ISO", VER_MODULE_NAME_STR
));
434 void Module::cucHexEdited(QString
const & s
)
436 if (s
.isEmpty() || s
.size() < 8)
441 mDateTime
.setDateTime(s
);
442 if (!mDateTime
.isValid())
447 if (mLastDateTimeType
== Internal::DateTime::Invalid
)
449 mLastDateTimeType
= Internal::DateTime::ASD
;
452 // Set the date/time string in the last used format
453 if (mLastDateTimeType
== Internal::DateTime::ASD
)
455 wDateTime
->setText(mDateTime
.asASDstring());
456 wConvertDateTime
->setEnabled(true);
457 wConvertDateTime
->setText(tr("&to ISO", VER_MODULE_NAME_STR
));
459 else if (mLastDateTimeType
== Internal::DateTime::ISO
)
461 wDateTime
->setText(mDateTime
.asISOstring());
462 wConvertDateTime
->setEnabled(true);
463 wConvertDateTime
->setText(tr("&to ASD", VER_MODULE_NAME_STR
));
467 void Module::epochChanged(QString
const & s
)
471 QRegExp
rx("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?$");
472 if (!rx
.exactMatch(s
))
475 QDateTime dt
= QDateTime::fromString(s
, Qt::ISODate
);
476 dt
.setTimeSpec(Qt::UTC
);
477 mDateTime
.setEpoch(dt
);
479 // If there is a valid entry, do the conversion
480 switch (mDateTime
.type())
482 case Internal::DateTime::ISO
:
483 case Internal::DateTime::ASD
:
485 wCucHex
->setText(mDateTime
.asCUChexString());
488 case Internal::DateTime::CUC
:
490 if (mLastDateTimeType
== Internal::DateTime::ASD
)
492 wDateTime
->setText(mDateTime
.asASDstring());
494 else if (mLastDateTimeType
== Internal::DateTime::ISO
)
496 wDateTime
->setText(mDateTime
.asISOstring());