#include "lts_date_time_edit_touch.h" #include "ui_lts_date_time_edit_touch.h" #include #include #include #include namespace LtsWidgets { LtsDateTimeEdit::LtsDateTimeEdit(QWidget *parent, bool withNowButton, bool withCheckBox) : QWidget(parent) , m_withCheckBox(withCheckBox) , m_withNowButton(withNowButton) , m_tzOffset(0) , m_minMonth(1) , m_maxMonth(12) , m_scFixed(new QShortcut(QKeySequence(Qt::ShiftModifier + Qt::Key_F2), this, SLOT(onSetFixedDateTime()), nullptr, Qt::WidgetWithChildrenShortcut)) , m_scOffset(new QShortcut(QKeySequence(Qt::Key_F2), this, SLOT(onSetOffsetDateTime()), nullptr, Qt::WidgetWithChildrenShortcut)) , m_getCurrentTimeCallback(nullptr) , m_ui(new Ui::LtsDateTimeEdit) { m_ui->setupUi(this); setFocusPolicy(Qt::StrongFocus); for (int i = 65; i < 91; i++ ) { if (QChar(i).toUpper() == QChar::fromLatin1('I')) continue; m_ui->cbxTimeZone->addItem(QChar(i), QChar(i)); } connect(m_ui->pbNow, &QPushButton::clicked, this, &LtsDateTimeEdit::onSetOffsetDateTime); connect(m_ui->cbxMonth, static_cast(&QComboBox::currentIndexChanged), this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->spDay, &QSpinBox::editingFinished, this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->spHour, &QSpinBox::editingFinished, this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->spMinutes, &QSpinBox::editingFinished, this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->spSeconds, &QSpinBox::editingFinished, this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->spYear, &QSpinBox::editingFinished, this, &LtsDateTimeEdit::onDateTimeChanged); connect(m_ui->checkBox, &QCheckBox::toggled, this, &LtsDateTimeEdit::onCheckBoxChanged); connect(m_ui->cbxTimeZone, static_cast(&QComboBox::currentIndexChanged), this, &LtsDateTimeEdit::onTimeZoneChanged); connect(m_ui->cbxMonth, static_cast(&QComboBox::currentIndexChanged), this, &LtsDateTimeEdit::onMonthChanged); m_tzOffset = DTG::timezone2Secs(QLatin1Char(DTG::timezone()).toLatin1()); m_ui->cbxTimeZone->setCurrentIndex(m_ui->cbxTimeZone->findText(QString(QLatin1Char(DTG::timezone())))); onTimeZoneChanged(); setMinMaxMonth(1,12); int offset = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("TimeSettings"), QStringLiteral("Offset"), 0).toLongLong()/1000; m_ui->pbNow->setToolTip(tr("Set to current time plus %n second(s) offset", "", offset)); updateDateTimeType(); m_ui->checkBox->setVisible(m_withCheckBox); m_ui->pbNow->setVisible(m_withNowButton); } LtsDateTimeEdit::~LtsDateTimeEdit() { delete m_ui; } void LtsDateTimeEdit::updateDateTimeType() { switch (DTG::dateTimeType()) { case DTG::DateTimeType::DTG: break; case DTG::DateTimeType::DDMMYYYY_HHMMSS_Z: break; case DTG::DateTimeType::DDMMYYYY_Z_HHMMSS: break; default: break; } } bool LtsDateTimeEdit::setTimezone(char tz) { QChar tzLocal = QChar(QLatin1Char(tz)).toUpper(); if (tzLocal.toLatin1() == 'J') tzLocal = QLatin1Char('Z'); m_ui->cbxTimeZone->setCurrentIndex(m_ui->cbxTimeZone->findData(tzLocal)); int offset = DTG::timezone2Secs(tzLocal.toLatin1()); if (offset != m_tzOffset) { const auto ms = msecsSinceEpoch(); m_tzOffset = offset; setMsecsSinceEpoch(ms+m_tzOffset); } return true; } char LtsDateTimeEdit::getTimezone() const { QChar tz = m_ui->cbxTimeZone->currentText().at(0).toUpper(); if (tz.toLatin1() == 'J') tz = QLatin1Char('Z'); if (tz.isNull()) return DTG::timezone(); return tz.toLatin1(); } void LtsDateTimeEdit::setMinMaxMonth(int minMonth, int maxMonth ) { if (m_minMonth != minMonth) m_minMonth = minMonth; if (m_maxMonth != maxMonth) m_maxMonth = maxMonth; int currentMonth = m_ui->cbxMonth->currentData().toInt(); m_ui->cbxMonth->blockSignals(true); m_ui->cbxMonth->clear(); for (int i =1; i<= 12 ; i++) { if (i < m_minMonth) continue; if (i > m_maxMonth) break; QDate date(1777,i,1); m_ui->cbxMonth->addItem(date.toString(QStringLiteral("MMM")),i); } m_ui->cbxMonth->setCurrentIndex(m_ui->cbxMonth->findData(currentMonth)); m_ui->cbxMonth->blockSignals(false); } void LtsDateTimeEdit::setDateTime(const QDateTime &datetime) { if (!datetime.isValid() && m_withCheckBox) { m_ui->checkBox->setChecked(false); return; } QDateTime dt = datetime.toUTC().addSecs(m_tzOffset); dt.setOffsetFromUtc(m_tzOffset); QDateTime oldDateTime = dateTime(); if (dt == oldDateTime) return; blockSignals(true); m_ui->spDay->setValue(dt.date().day()); m_ui->cbxMonth->setCurrentIndex(m_ui->cbxMonth->findData(dt.date().month())); m_ui->spYear->setValue(dt.date().year()-2000); m_ui->spHour->setValue(dt.time().hour()); m_ui->spMinutes->setValue(dt.time().minute()); m_ui->spSeconds->setValue(dt.time().second()); blockSignals(false); const QDateTime dtNew = dateTime(); if (dtNew != oldDateTime) emit dateTimeChanged(); } void LtsDateTimeEdit::onDateTimeChanged() { emit dateTimeChanged(); QDateTime dateTime; dateTime = dateTime.addYears(m_ui->spYear->value()); dateTime = dateTime.addMonths(m_ui->cbxMonth->currentData().toInt()); dateTime = dateTime.addDays(m_ui->spDay->value()); dateTime = dateTime.addSecs(m_ui->spHour->value()*60*60 + m_ui->spMinutes->value()*60 + m_ui->spSeconds->value()); if (dateTime.isValid()) { m_dateTime = dateTime; } } void LtsDateTimeEdit::onTimeZoneChanged() { if (m_ui->cbxMonth->currentText().isEmpty()) { return; } QChar tz = m_ui->cbxTimeZone->currentText().at(0); if (tz.isLower()) tz = tz.toUpper(); if (tz.toLatin1() == 'J') tz = QLatin1Char('Z'); m_ui->cbxTimeZone->setCurrentIndex(m_ui->cbxTimeZone->findData(tz)); int offset = DTG::timezone2Secs(tz.toLatin1()); if (offset != m_tzOffset) { const auto ms = msecsSinceEpoch(); m_tzOffset = offset; setMsecsSinceEpoch(ms+m_tzOffset); } } void LtsDateTimeEdit::onMonthChanged(int month) { Q_UNUSED(month); } void LtsDateTimeEdit::setWithCheckBox(bool checkBoxEnabled) { if (m_withCheckBox == checkBoxEnabled) return; m_withCheckBox = checkBoxEnabled; m_ui->checkBox->setVisible(m_withCheckBox); if (!m_withCheckBox) m_ui->checkBox->setChecked(true); emit withCheckBoxChanged(m_withCheckBox); } bool LtsDateTimeEdit::isCheckBoxChecked() const { return m_ui->checkBox->isChecked(); } void LtsDateTimeEdit::setWithNowButton(bool nowButton) { if (m_withNowButton == nowButton) return; m_withNowButton = nowButton; m_ui->pbNow->setVisible(m_withNowButton); emit withNowButtonChanged(m_withNowButton); } void LtsDateTimeEdit::onCheckBoxChanged(bool checked) { m_ui->spDay->setEnabled(checked); m_ui->spHour->setEnabled(checked); m_ui->spMinutes->setEnabled(checked); m_ui->spSeconds->setEnabled(checked); m_ui->spYear->setEnabled(checked); m_ui->cbxMonth->setEnabled(checked); m_ui->cbxTimeZone->setEnabled(checked); m_ui->pbNow->setEnabled(checked); emit dateTimeChanged(); } void LtsDateTimeEdit::setMsecsSinceEpoch(qint64 mSecsSinceEpoch) { if (mSecsSinceEpoch == 0 && m_withCheckBox) { m_ui->checkBox->setChecked(false); return; } m_ui->checkBox->setChecked(true); setDateTime(QDateTime::fromMSecsSinceEpoch(mSecsSinceEpoch).toUTC()); } qint64 LtsDateTimeEdit::msecsSinceEpoch() const { const QDateTime dt(dateTime()); if (dt.isNull()) return 0; return dt.toMSecsSinceEpoch(); } void LtsDateTimeEdit::clear() { m_ui->spDay->clear(); m_ui->spHour->clear(); m_ui->spMinutes->clear(); m_ui->spSeconds->clear(); m_ui->spYear->clear(); emit dateTimeChanged(); } void LtsDateTimeEdit::setCheckBoxChecked(bool bChecked) { m_ui->checkBox->setChecked(bChecked); } QDateTime LtsDateTimeEdit::dateTime() const { if (!m_ui->checkBox->isChecked()) return QDateTime(); QDateTime final; int year = 0; if (m_ui->spYear->value() < 1000) { year=m_ui->spYear->value()+2000; } else { year=m_ui->spYear->value(); } QDate date(year,m_ui->cbxMonth->currentData().toInt(), m_ui->spDay->value()); final.setDate(date); final = final.addSecs(m_ui->spHour->value()*60*60 + m_ui->spMinutes->value()*60 + m_ui->spSeconds->value()); if (!final.isValid()) return QDateTime(); return QDateTime(final.date(), final.time(), Qt::OffsetFromUTC, m_tzOffset).toUTC(); } void LtsDateTimeEdit::setMaximumTimeMSec(qint64 msec) { const auto maximumDate(QDateTime::fromMSecsSinceEpoch(msec).date()); m_ui->spYear->setMaximum(maximumDate.year()-2000); } qint64 LtsDateTimeEdit::minimumTimeMSec() const { QDate date; date.setDate(m_ui->spYear->minimum(), m_maxMonth, m_ui->spMinutes->minimum() ); return QDateTime(date).toMSecsSinceEpoch(); } void LtsDateTimeEdit::setMinimumTimeMSec(qint64 msec) { const auto minimumDate(QDateTime::fromMSecsSinceEpoch(msec).date()); m_ui->spYear->setMinimum(minimumDate.year()-2000); } void LtsDateTimeEdit::setRetrieveCurrentTimeCallback(const CurrentTimeCallback &cb) { m_getCurrentTimeCallback = cb; } void LtsDateTimeEdit::onSetFixedDateTime() { setMsecsSinceEpoch(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("TimeSettings"), QStringLiteral("FixedTime"), 0).toLongLong()); } void LtsDateTimeEdit::onSetOffsetDateTime() { if (!m_getCurrentTimeCallback) return; qint64 offset = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("TimeSettings"), QStringLiteral("Offset"), 0).toLongLong(); setMsecsSinceEpoch((m_getCurrentTimeCallback() / 1000) * 1000 + offset); } void LtsDateTimeEdit::setSubWidgetsProperties(QString name, QVariant value) { m_ui->spDay->setProperty(name.toStdString().c_str(), value); m_ui->spHour->setProperty(name.toStdString().c_str(), value); m_ui->spMinutes->setProperty(name.toStdString().c_str(), value); m_ui->spSeconds->setProperty(name.toStdString().c_str(), value); m_ui->spYear->setProperty(name.toStdString().c_str(), value); } }