1786 lines
41 KiB
C++
Executable File
1786 lines
41 KiB
C++
Executable File
|
|
|
|
|
|
#include "lts_date_time_edit.h"
|
|
#include "lts_date_time_edit_p.h"
|
|
|
|
#include "ui_lts_date_time_edit_touch.h"
|
|
|
|
|
|
#include <LtsUtilsSettings/settings.h>
|
|
|
|
#include <ngltools/ngltools_dtg.h>
|
|
|
|
#include <QApplication>
|
|
#include <QCheckBox>
|
|
#include <QCompleter>
|
|
#include <QDateTime>
|
|
#include <QGridLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QKeyEvent>
|
|
#include <QLineEdit>
|
|
#include <QPushButton>
|
|
#include <QRegularExpressionValidator>
|
|
#include <QShortcut>
|
|
#include <QSlider>
|
|
#include <QToolButton>
|
|
|
|
static constexpr qint64 s_oneSecondMSec = 1000LL;
|
|
static constexpr qint64 s_oneMinuteMSec = 60 * s_oneSecondMSec;
|
|
static constexpr qint64 s_oneHourMSec = 60 * s_oneMinuteMSec;
|
|
static constexpr qint64 s_oneDayMSec = 24 * s_oneHourMSec;
|
|
|
|
namespace Ui
|
|
{
|
|
class LtsDateTimeEditLe
|
|
{
|
|
public:
|
|
LtsWidgets::DigitsLineEdit *leLongDay = nullptr;
|
|
LtsWidgets::DigitsLineEdit *leLongHHMMSS = nullptr;
|
|
LtsWidgets::LineEdit *leLongTZ = nullptr;
|
|
LtsWidgets::DigitsLineEdit *leLongMonth = nullptr;
|
|
LtsWidgets::DigitsLineEdit *leLongYear = nullptr;
|
|
QCheckBox *checkBox = nullptr;
|
|
QGridLayout *gridLayout = nullptr;
|
|
QPushButton *pbBBB = nullptr;
|
|
QPushButton *pbBB = nullptr;
|
|
QPushButton *pbB = nullptr;
|
|
QPushButton *pbF = nullptr;
|
|
QPushButton *pbFF = nullptr;
|
|
QPushButton *pbFFF = nullptr;
|
|
QPushButton *pbNow = nullptr;
|
|
QSlider *slTime = nullptr;
|
|
|
|
static void setFixedSize(QLineEdit *le, int charCount)
|
|
{
|
|
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
sizePolicy.setVerticalStretch(0);
|
|
sizePolicy.setHeightForWidth(false);
|
|
|
|
const QFontMetricsF fm(le->font());
|
|
const auto textMargins = le->textMargins();
|
|
le->setSizePolicy(sizePolicy);
|
|
charCount += 3;
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
|
const qreal w = fm.width(QLatin1Char('x')) * charCount + textMargins.left() + textMargins.right();
|
|
#else
|
|
const qreal w = fm.horizontalAdvance(QLatin1Char('x')) * charCount + textMargins.left() + textMargins.right();
|
|
#endif
|
|
le->setMinimumWidth(w);
|
|
le->setMaximumWidth(w);
|
|
}
|
|
|
|
void setupUi(QWidget *parent)
|
|
{
|
|
gridLayout = new QGridLayout(parent);
|
|
gridLayout->setMargin(0);
|
|
|
|
int iStart = 3;
|
|
|
|
checkBox = new QCheckBox;
|
|
gridLayout->addWidget(checkBox, 0, iStart++, 1, 1);
|
|
|
|
auto horizontalLayout = new QHBoxLayout;
|
|
horizontalLayout->setSpacing(0);
|
|
horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
leLongDay = new LtsWidgets::DigitsLineEdit(parent);
|
|
setFixedSize(leLongDay, 2);
|
|
leLongDay->setObjectName(QStringLiteral("leLongDay"));
|
|
horizontalLayout->addWidget(leLongDay);
|
|
|
|
leLongHHMMSS = new LtsWidgets::DigitsLineEdit(parent);
|
|
leLongHHMMSS->setExactNumDigits(6);
|
|
setFixedSize(leLongHHMMSS, 6);
|
|
leLongHHMMSS->setObjectName(QStringLiteral("leLongHHMMSS"));
|
|
horizontalLayout->addWidget(leLongHHMMSS);
|
|
|
|
leLongTZ = new LtsWidgets::LineEdit(parent);
|
|
leLongTZ->setAlignment(Qt::AlignCenter);
|
|
setFixedSize(leLongTZ, 1);
|
|
leLongTZ->setObjectName(QStringLiteral("leLongTZ"));
|
|
horizontalLayout->addWidget(leLongTZ);
|
|
|
|
leLongMonth = new LtsWidgets::DigitsLineEdit(parent);
|
|
leLongMonth->setAlignment(Qt::AlignCenter);
|
|
setFixedSize(leLongMonth, 3);
|
|
leLongMonth->setObjectName(QStringLiteral("leLongMonth"));
|
|
horizontalLayout->addWidget(leLongMonth);
|
|
|
|
leLongYear = new LtsWidgets::DigitsLineEdit(parent);
|
|
leLongYear->setExactNumDigits(2);
|
|
setFixedSize(leLongYear, 2);
|
|
leLongYear->setObjectName(QStringLiteral("leLongYear"));
|
|
horizontalLayout->addWidget(leLongYear);
|
|
|
|
gridLayout->addLayout(horizontalLayout, 0, iStart++, 1, 1);
|
|
|
|
pbNow = new QPushButton(QApplication::translate("LtsDateTimeEdit", "Now", nullptr));
|
|
pbNow->setObjectName(QStringLiteral("pbNow"));
|
|
gridLayout->addWidget(pbNow, 0, iStart++, 1, 1);
|
|
|
|
QWidget::setTabOrder(checkBox, leLongDay);
|
|
QWidget::setTabOrder(leLongDay, leLongHHMMSS);
|
|
QWidget::setTabOrder(leLongHHMMSS, leLongTZ);
|
|
QWidget::setTabOrder(leLongTZ, leLongMonth);
|
|
QWidget::setTabOrder(leLongMonth, leLongYear);
|
|
QWidget::setTabOrder(leLongYear, pbNow);
|
|
|
|
parent->setFocusProxy(leLongDay);
|
|
}
|
|
|
|
static QPushButton *addButton(const QString &text, QWidget *parent)
|
|
{
|
|
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
|
|
auto pb = new QPushButton(parent);
|
|
pb->setMinimumWidth(27);
|
|
pb->setMaximumWidth(27);
|
|
pb->setText(text);
|
|
sizePolicy.setHorizontalStretch(0);
|
|
sizePolicy.setVerticalStretch(0);
|
|
sizePolicy.setHeightForWidth(pb->sizePolicy().hasHeightForWidth());
|
|
pb->setSizePolicy(sizePolicy);
|
|
return pb;
|
|
}
|
|
|
|
void addButtons(QWidget *parent)
|
|
{
|
|
pbBBB = addButton(QLatin1String("<<<"), parent);
|
|
pbBB = addButton(QLatin1String("<<"), parent);
|
|
pbB = addButton(QLatin1String("<"), parent);
|
|
gridLayout->addWidget(pbBBB, 0, 0, 1, 1);
|
|
gridLayout->addWidget(pbBB, 0, 1, 1, 1);
|
|
gridLayout->addWidget(pbB, 0, 2, 1, 1);
|
|
|
|
int iStart = 5;
|
|
pbF = addButton(QLatin1String(">"), parent);
|
|
pbFF = addButton(QLatin1String(">>"), parent);
|
|
pbFFF = addButton(QLatin1String(">>>"), parent);
|
|
gridLayout->addWidget(pbF, 0, iStart++, 1, 1);
|
|
gridLayout->addWidget(pbFF, 0, iStart++, 1, 1);
|
|
gridLayout->addWidget(pbFFF, 0, iStart++, 1, 1);
|
|
}
|
|
|
|
void addSlider(QWidget *parent)
|
|
{
|
|
slTime = new QSlider(parent);
|
|
slTime->setOrientation(Qt::Horizontal);
|
|
gridLayout->addWidget(slTime, 1, 0, 1, 7);
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
namespace LtsWidgets
|
|
{
|
|
|
|
|
|
|
|
|
|
void setItemText(LtsWidgets::LineEdit *lineEdit, const QString &text)
|
|
{
|
|
if (!lineEdit)
|
|
return;
|
|
lineEdit->setText(text);
|
|
}
|
|
void setItemText(QComboBox *comboxBox, const QString &text)
|
|
{
|
|
if (!comboxBox)
|
|
return;
|
|
comboxBox->setCurrentIndex(comboxBox->findText(text));
|
|
}
|
|
void setItemData(QComboBox *comboxBox, int data)
|
|
{
|
|
if (!comboxBox)
|
|
return;
|
|
comboxBox->setCurrentIndex(comboxBox->findData(data));
|
|
}
|
|
void setItemValue(QSpinBox *spinBox, int value)
|
|
{
|
|
if (!spinBox)
|
|
return;
|
|
spinBox->setValue(value);
|
|
}
|
|
|
|
|
|
QString getItemText(LtsWidgets::LineEdit *lineEdit)
|
|
{
|
|
if (!lineEdit)
|
|
return {};
|
|
return lineEdit->text();
|
|
}
|
|
QString getItemText(QComboBox *comboxBox)
|
|
{
|
|
if (!comboxBox || (comboxBox->count() <= 0))
|
|
return {};
|
|
const QString &curTest = comboxBox->currentText();
|
|
if (curTest.isEmpty())
|
|
return {};
|
|
return curTest.at(0).toUpper();
|
|
}
|
|
int getItemData(QComboBox *comboxBox)
|
|
{
|
|
if (!comboxBox || (comboxBox->count() <= 0))
|
|
return {};
|
|
int data = comboxBox->currentData().toInt();
|
|
return data;
|
|
}
|
|
int getItemValue(QSpinBox *spinBox)
|
|
{
|
|
if (!spinBox)
|
|
return 0;
|
|
return spinBox->value();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LtsDateTimeEdit::LtsDateTimeEdit(QWidget *parent, bool withNowButton, bool checkable)
|
|
: QWidget(parent)
|
|
|
|
, m_scFixed(new QShortcut(QKeySequence(Qt::ShiftModifier + Qt::Key_F2), this, SLOT(setFixedDateTime()), nullptr, Qt::WidgetWithChildrenShortcut))
|
|
, m_scOffset(new QShortcut(QKeySequence(Qt::Key_F2), this, SLOT(setOffsetDateTime()), nullptr, Qt::WidgetWithChildrenShortcut))
|
|
, m_checkable(checkable)
|
|
, m_withNowButton(withNowButton)
|
|
{
|
|
|
|
#ifdef TABLET_MODE
|
|
|
|
setupUiTouch();
|
|
return;
|
|
#else
|
|
|
|
m_uiLe = new Ui::LtsDateTimeEditLe;
|
|
m_uiLe->setupUi(this);
|
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setContentsMargins(QMargins());
|
|
|
|
QCompleter *completer = new QCompleter(DTG::months(), this);
|
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
|
completer->setCompletionMode(QCompleter::InlineCompletion);
|
|
|
|
QRegularExpression rx(DTG::months().join(QLatin1Char('|')));
|
|
QRegularExpressionValidator *val = new QRegularExpressionValidator(rx, this);
|
|
m_uiLe->leLongMonth->setCompleter(completer);
|
|
m_uiLe->leLongMonth->setValidator(val);
|
|
|
|
connect(m_uiLe->leLongDay, &DigitsLineEdit::textEdited, this, &LtsDateTimeEdit::valueDayChanged);
|
|
connect(m_uiLe->leLongMonth, &LineEdit::textEdited, this, &LtsDateTimeEdit::valueMonthChanged2);
|
|
connect(m_uiLe->leLongTZ, &LineEdit::textEdited, this, &LtsDateTimeEdit::valueTimezoneChangedStr);
|
|
connect(m_uiLe->leLongYear, &DigitsLineEdit::textEdited, this, &LtsDateTimeEdit::valueYearChanged);
|
|
|
|
connect(m_uiLe->leLongHHMMSS, &DigitsLineEdit::focusOut, this, &LtsDateTimeEdit::onFocusOutHHMMSS);
|
|
connect(m_uiLe->leLongDay, &DigitsLineEdit::focusOut, this, &LtsDateTimeEdit::onFocusOutDay);
|
|
connect(m_uiLe->leLongMonth, &LineEdit::focusOut, this, &LtsDateTimeEdit::onFocusOutMonth);
|
|
connect(m_uiLe->leLongTZ, &LineEdit::focusOut, this, &LtsDateTimeEdit::onFocusOutTZ);
|
|
connect(m_uiLe->leLongYear, &DigitsLineEdit::focusOut, this, &LtsDateTimeEdit::onFocusOutYear);
|
|
|
|
connect(m_uiLe->leLongHHMMSS, &DigitsLineEdit::focusOutBackspace, this, &LtsDateTimeEdit::onFocusOutBackspace);
|
|
connect(m_uiLe->leLongDay, &DigitsLineEdit::focusOutBackspace, this, &LtsDateTimeEdit::onFocusOutBackspace);
|
|
connect(m_uiLe->leLongMonth, &LineEdit::focusOutBackspace, this, &LtsDateTimeEdit::onFocusOutBackspace);
|
|
connect(m_uiLe->leLongTZ, &LineEdit::focusOutBackspace, this, &LtsDateTimeEdit::onFocusOutBackspace);
|
|
connect(m_uiLe->leLongYear, &DigitsLineEdit::focusOutBackspace, this, &LtsDateTimeEdit::onFocusOutBackspace);
|
|
|
|
connect(m_uiLe->leLongHHMMSS, &DigitsLineEdit::wheelEventReceived, this, &LtsDateTimeEdit::onHmsWheelEvent);
|
|
connect(m_uiLe->leLongDay, &DigitsLineEdit::wheelEventReceived, this, &LtsDateTimeEdit::onDayWheelEvent);
|
|
connect(m_uiLe->leLongMonth, &DigitsLineEdit::wheelEventReceived, this, &LtsDateTimeEdit::onMonthWheelEvent);
|
|
connect(m_uiLe->leLongYear, &DigitsLineEdit::wheelEventReceived, this, &LtsDateTimeEdit::onYearWheelEvent);
|
|
|
|
connect(m_uiLe->checkBox, &QCheckBox::toggled, this, &LtsDateTimeEdit::onCheckBoxChanged);
|
|
connect(m_uiLe->pbNow, &QPushButton::clicked, this, &LtsDateTimeEdit::setOffsetDateTime);
|
|
connect(checkBox(), &QCheckBox::toggled, this, &LtsDateTimeEdit::toggled);
|
|
|
|
setTimezone(DTG::timezone());
|
|
|
|
setCheckable(m_checkable);
|
|
|
|
setWithNowButton(m_withNowButton);
|
|
|
|
onCheckBoxChanged();
|
|
#endif
|
|
}
|
|
|
|
LtsDateTimeEdit::~LtsDateTimeEdit()
|
|
{
|
|
delete m_uiLe;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setupUiTouch()
|
|
{
|
|
m_uiTouch = new Ui::LtsDateTimeEdit;
|
|
m_uiTouch->setupUi(this);
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
|
|
for (int i = 65; i < 91; i++ )
|
|
{
|
|
if (QChar(i).toUpper() == QChar::fromLatin1('I'))
|
|
continue;
|
|
m_uiTouch->cbxTimeZone->addItem(QChar(i), QChar(i));
|
|
}
|
|
|
|
connect(m_uiTouch->pbNow, &QPushButton::clicked,
|
|
this, &LtsDateTimeEdit::setOffsetDateTime);
|
|
connect(m_uiTouch->cbxMonth, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
connect(m_uiTouch->spDay, &QSpinBox::editingFinished,
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
connect(m_uiTouch->spHour, &QSpinBox::editingFinished,
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
connect(m_uiTouch->spMinutes, &QSpinBox::editingFinished,
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
connect(m_uiTouch->spSeconds, &QSpinBox::editingFinished,
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
connect(m_uiTouch->spYear, &QSpinBox::editingFinished,
|
|
this, &LtsDateTimeEdit::dateTimeChanged);
|
|
|
|
connect(m_uiTouch->checkBox, &QCheckBox::toggled,
|
|
this, &LtsDateTimeEdit::onCheckBoxChanged);
|
|
connect(m_uiTouch->cbxTimeZone, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
|
this, &LtsDateTimeEdit::valueTimezoneChangedInt);
|
|
|
|
|
|
|
|
connect(m_uiTouch->cbxMonth, &QComboBox::currentTextChanged,
|
|
this, &LtsDateTimeEdit::valueMonthChanged);
|
|
|
|
connect(checkBox(), &QCheckBox::toggled, this, &LtsDateTimeEdit::toggled);
|
|
|
|
setMinMaxMonth(1,12);
|
|
|
|
setTimezone(DTG::timezone());
|
|
|
|
|
|
setCheckable(m_checkable);
|
|
|
|
setWithNowButton(m_withNowButton);
|
|
|
|
onCheckBoxChanged();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void LtsDateTimeEdit::setRetrieveCurrentTimeCallback(const CurrentTimeCallback &cb)
|
|
{
|
|
m_getCurrentTimeCallback = cb;
|
|
}
|
|
|
|
void LtsDateTimeEdit::setEditTimezone(const bool edit)
|
|
{
|
|
m_editTimezone = edit;
|
|
if (m_uiLe)
|
|
m_uiLe->leLongTZ->setEnabled(m_editTimezone);
|
|
if (m_uiTouch)
|
|
m_uiTouch->cbxTimeZone->setEnabled(m_editTimezone);
|
|
}
|
|
|
|
void LtsDateTimeEdit::setWithButtons(const bool buttons)
|
|
{
|
|
m_withButtons = buttons;
|
|
if (buttons)
|
|
{
|
|
if (m_uiLe && !m_uiLe->pbBBB)
|
|
{
|
|
m_uiLe->addButtons(this);
|
|
connect(m_uiLe->pbBBB, &QPushButton::clicked, this, &LtsDateTimeEdit::onBackHourClicked);
|
|
connect(m_uiLe->pbBB, &QPushButton::clicked, this, &LtsDateTimeEdit::onBackMinuteClicked);
|
|
connect(m_uiLe->pbB, &QPushButton::clicked, this, &LtsDateTimeEdit::onBackSecondClicked);
|
|
connect(m_uiLe->pbF, &QPushButton::clicked, this, &LtsDateTimeEdit::onForwardSecondClicked);
|
|
connect(m_uiLe->pbFF, &QPushButton::clicked, this, &LtsDateTimeEdit::onForwardMinuteClicked);
|
|
connect(m_uiLe->pbFFF, &QPushButton::clicked, this, &LtsDateTimeEdit::onForwardHourClicked);
|
|
disableControls();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
delete m_uiLe->pbBBB;
|
|
delete m_uiLe->pbBB;
|
|
delete m_uiLe->pbB;
|
|
delete m_uiLe->pbFFF;
|
|
delete m_uiLe->pbFF;
|
|
delete m_uiLe->pbF;
|
|
|
|
m_uiLe->pbBBB = nullptr;
|
|
m_uiLe->pbBB = nullptr;
|
|
m_uiLe->pbB = nullptr;
|
|
m_uiLe->pbFFF = nullptr;
|
|
m_uiLe->pbFF = nullptr;
|
|
m_uiLe->pbF = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::setWithSlider(const bool slider)
|
|
{
|
|
m_withSlider = slider;
|
|
|
|
if (!m_uiLe)
|
|
return;
|
|
|
|
if (slider)
|
|
{
|
|
m_uiLe->addSlider(this);
|
|
m_uiLe->slTime->setMinimum(m_minTimeMSec / 1000);
|
|
m_uiLe->slTime->setMaximum(m_maxTimeMSec > 0 ? m_maxTimeMSec / 1000 : time(nullptr));
|
|
connect(m_uiLe->slTime, &QSlider::sliderMoved, this, &LtsDateTimeEdit::setSliderValue);
|
|
disableControls();
|
|
}
|
|
else
|
|
{
|
|
delete m_uiLe->slTime;
|
|
m_uiLe->slTime = nullptr;
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::setReadOnly(const bool readOnly)
|
|
{
|
|
if (m_readOnly == readOnly)
|
|
return;
|
|
m_readOnly = readOnly;
|
|
|
|
if (m_uiLe)
|
|
{
|
|
m_uiLe->leLongDay->setReadOnly(m_readOnly);
|
|
m_uiLe->leLongHHMMSS->setReadOnly(m_readOnly);
|
|
m_uiLe->leLongMonth->setReadOnly(m_readOnly);
|
|
m_uiLe->leLongTZ->setReadOnly(m_readOnly);
|
|
m_uiLe->leLongYear->setReadOnly(m_readOnly);
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
m_uiTouch->spDay->setReadOnly(m_readOnly);
|
|
m_uiTouch->spHour->setReadOnly(m_readOnly);
|
|
m_uiTouch->spMinutes->setReadOnly(m_readOnly);
|
|
m_uiTouch->spSeconds->setReadOnly(m_readOnly);
|
|
m_uiTouch->spYear->setReadOnly(m_readOnly);
|
|
m_uiTouch->cbxTimeZone->setEnabled(m_readOnly);
|
|
}
|
|
}
|
|
|
|
QCheckBox *LtsDateTimeEdit::checkBox() const
|
|
{
|
|
return m_uiLe ? m_uiLe->checkBox : m_uiTouch ? m_uiTouch->checkBox : nullptr;
|
|
}
|
|
|
|
void LtsDateTimeEdit::setCheckable(bool checkable)
|
|
{
|
|
if (!checkBox() || (m_checkable == checkable))
|
|
return;
|
|
|
|
m_checkable = checkable;
|
|
checkBox()->setVisible(checkable);
|
|
if (!checkable)
|
|
checkBox()->setChecked(true);
|
|
}
|
|
|
|
void LtsDateTimeEdit::setChecked(bool bChecked)
|
|
{
|
|
if (!checkBox())
|
|
return;
|
|
checkBox()->setChecked(bChecked);
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isChecked() const
|
|
{
|
|
if (!checkBox())
|
|
return false;
|
|
return checkBox()->isChecked();
|
|
}
|
|
|
|
QPushButton *LtsDateTimeEdit::pbNow() const
|
|
{
|
|
return m_uiLe ? m_uiLe->pbNow : m_uiTouch ? m_uiTouch->pbNow : nullptr;
|
|
}
|
|
|
|
void LtsDateTimeEdit::setWithNowButton(bool nowButton)
|
|
{
|
|
if (!pbNow())
|
|
return;
|
|
|
|
pbNow()->setVisible(nowButton);
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setMsecsSinceEpoch(qint64 msec, bool setToNearestPossible)
|
|
{
|
|
if (msec == 0 && isCheckable())
|
|
{
|
|
if (m_uiLe)
|
|
m_uiLe->checkBox->setChecked(false);
|
|
m_dateIsAcceptable = true;
|
|
return true;
|
|
}
|
|
if (m_uiLe)
|
|
m_uiLe->checkBox->setChecked(true);
|
|
|
|
m_dateIsAcceptable = false;
|
|
if (msec == 0)
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!setToNearestPossible)
|
|
{
|
|
if (!isDataAcceptable())
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (msec < m_minTimeMSec && m_minTimeMSec > 0)
|
|
msec = m_minTimeMSec;
|
|
if (msec > m_maxTimeMSec && m_maxTimeMSec > 0)
|
|
msec = m_maxTimeMSec;
|
|
}
|
|
|
|
m_curTimeMSec = msec;
|
|
|
|
const qint64 offsetTimeZoneMsec = getTimezoneAsSecs() * 1000;
|
|
const QDateTime datetime(QDateTime::fromMSecsSinceEpoch(m_curTimeMSec + offsetTimeZoneMsec, Qt::UTC));
|
|
const QDate date(datetime.date());
|
|
const QTime time(datetime.time());
|
|
|
|
const int day = date.day();
|
|
const int month = date.month();
|
|
const int year = date.year();
|
|
const int hour = time.hour();
|
|
const int minute = time.minute();
|
|
const int second = time.second();
|
|
|
|
|
|
if (!setYear(year) ||
|
|
!setMonth(month) ||
|
|
!setDay(day) ||
|
|
!setHHMMSS(hour, minute, second))
|
|
return false;
|
|
|
|
if (!isDataAcceptable())
|
|
return false;
|
|
|
|
enableControls();
|
|
|
|
emit dateTimeChanged();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
qint64 LtsDateTimeEdit::msecsSinceEpoch() const
|
|
{
|
|
if (isEmpty())
|
|
return 0;
|
|
|
|
if (m_uiLe && !m_uiLe->checkBox->isChecked())
|
|
return 0;
|
|
if (m_uiTouch && !m_uiTouch->checkBox->isChecked())
|
|
return 0;
|
|
|
|
auto that = const_cast<LtsDateTimeEdit *>(this);
|
|
if (!that->isDataAcceptable())
|
|
return 0;
|
|
|
|
return m_curTimeMSec;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setTimezone(char tz)
|
|
{
|
|
tz = toupper(tz);
|
|
if (!DTG::isTimezoneValid(tz))
|
|
return false;
|
|
|
|
if (m_uiLe)
|
|
setItemText(m_uiLe->leLongTZ, QString(QLatin1Char(tz)));
|
|
if (m_uiTouch)
|
|
setItemText(m_uiTouch->cbxTimeZone, QString(QLatin1Char(tz)));
|
|
|
|
setMsecsSinceEpoch(m_curTimeMSec);
|
|
|
|
return true;
|
|
}
|
|
|
|
char LtsDateTimeEdit::getTimezone() const
|
|
{
|
|
QString str;
|
|
if (m_uiLe)
|
|
str = getItemText(m_uiLe->leLongTZ);
|
|
if (m_uiTouch)
|
|
str = getItemText(m_uiTouch->cbxTimeZone);
|
|
|
|
if (str.isEmpty())
|
|
return DTG::timezone();
|
|
return str[0].toUpper().toLatin1();
|
|
}
|
|
|
|
qint64 LtsDateTimeEdit::getTimezoneAsSecs() const
|
|
{
|
|
const char tzGUI = getTimezone();
|
|
return DTG::timezone2Secs(tzGUI);
|
|
}
|
|
|
|
void LtsDateTimeEdit::clearTimezone()
|
|
{
|
|
if (m_uiLe)
|
|
m_uiLe->leLongTZ->clear();
|
|
if (m_uiTouch)
|
|
m_uiTouch->cbxTimeZone->setCurrentIndex(0);
|
|
}
|
|
|
|
void LtsDateTimeEdit::setMinMaxMonth(int minMonth, int maxMonth)
|
|
{
|
|
if (!m_uiTouch)
|
|
return;
|
|
|
|
m_minMonth = minMonth;
|
|
m_maxMonth = maxMonth;
|
|
|
|
const int currentMonth = m_uiTouch->cbxMonth->currentData().toInt();
|
|
m_uiTouch->cbxMonth->blockSignals(true);
|
|
m_uiTouch->cbxMonth->clear();
|
|
for (int i = 1; i <= 12; ++i)
|
|
{
|
|
if (i < m_minMonth)
|
|
continue;
|
|
if (i > m_maxMonth)
|
|
break;
|
|
|
|
|
|
|
|
const QStringList &monthSl = DTG::months();
|
|
m_uiTouch->cbxMonth->addItem(monthSl[i-1], i);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
m_uiTouch->cbxMonth->setCurrentIndex(m_uiTouch->cbxMonth->findData(currentMonth));
|
|
m_uiTouch->cbxMonth->blockSignals(false);
|
|
}
|
|
|
|
|
|
void LtsDateTimeEdit::setSubWidgetsProperties(const QString &name, const QVariant &value)
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
m_uiLe->leLongDay->setProperty(name.toStdString().c_str(), value);
|
|
m_uiLe->leLongHHMMSS->setProperty(name.toStdString().c_str(), value);
|
|
m_uiLe->leLongMonth->setProperty(name.toStdString().c_str(), value);
|
|
m_uiLe->leLongYear->setProperty(name.toStdString().c_str(), value);
|
|
m_uiLe->leLongTZ->setProperty(name.toStdString().c_str(), value);
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
m_uiTouch->spDay->setProperty(name.toStdString().c_str(), value);
|
|
m_uiTouch->spHour->setProperty(name.toStdString().c_str(), value);
|
|
m_uiTouch->spMinutes->setProperty(name.toStdString().c_str(), value);
|
|
m_uiTouch->spSeconds->setProperty(name.toStdString().c_str(), value);
|
|
m_uiTouch->spYear->setProperty(name.toStdString().c_str(), value);
|
|
}
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setMonth(int month)
|
|
{
|
|
const auto months(DTG::months());
|
|
if (month < 1 || month > months.size())
|
|
return false;
|
|
|
|
if (m_uiLe)
|
|
setItemText(m_uiLe->leLongMonth, months.at(month - 1));
|
|
if (m_uiTouch)
|
|
setItemData(m_uiTouch->cbxMonth, month);
|
|
return true;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getMonth() const
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
const QString str = getItemText(m_uiLe->leLongMonth);
|
|
if (str.length() != 3)
|
|
return -1;
|
|
|
|
int idx = DTG::months().indexOf(str);
|
|
if (idx < 0)
|
|
return -1;
|
|
return idx + 1;
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
int month = getItemData(m_uiTouch->cbxMonth);
|
|
return month;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setDay(int day)
|
|
{
|
|
if (day < 1 || day > 31)
|
|
return false;
|
|
|
|
QString oldDay;
|
|
if (m_uiLe)
|
|
oldDay = m_uiLe->leLongDay->text();
|
|
int oldDayInt = 0;
|
|
if (m_uiTouch)
|
|
oldDayInt = getItemValue(m_uiTouch->spDay);
|
|
|
|
if (m_uiLe)
|
|
setItemText(m_uiLe->leLongDay, QStringLiteral("%1").arg(day, 2, 10, QLatin1Char('0')));
|
|
if (m_uiTouch)
|
|
setItemValue(m_uiTouch->spDay, day);
|
|
|
|
if (!isDayAcceptable())
|
|
{
|
|
if (m_uiLe)
|
|
setItemText(m_uiLe->leLongDay, oldDay);
|
|
if (m_uiTouch)
|
|
setItemValue(m_uiTouch->spDay, oldDayInt);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getDay() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongDay->getValue();
|
|
if (m_uiTouch)
|
|
return getItemValue(m_uiTouch->spDay);
|
|
return 0;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setHHMMSS(int hour, int minute, int second)
|
|
{
|
|
if (hour < 0 || hour > 23 ||
|
|
minute < 0 || minute > 59 ||
|
|
second < 0 || second > 59)
|
|
return false;
|
|
|
|
if (m_uiLe)
|
|
m_uiLe->leLongHHMMSS->setValue(hour * 10000 + minute * 100 + second);
|
|
if (m_uiTouch)
|
|
{
|
|
setItemValue(m_uiTouch->spHour , hour);
|
|
setItemValue(m_uiTouch->spMinutes, minute);
|
|
setItemValue(m_uiTouch->spSeconds, second);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getHour() const
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
const int time = m_uiLe->leLongHHMMSS->getValue();
|
|
return time / 10000;
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
return getItemValue(m_uiTouch->spHour);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getMinute() const
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
const int time = m_uiLe->leLongHHMMSS->getValue();
|
|
return (time / 100) % 100;
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
return getItemValue(m_uiTouch->spMinutes);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getSecond() const
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
const int time = m_uiLe->leLongHHMMSS->getValue();
|
|
return time % 100;
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
return getItemValue(m_uiTouch->spSeconds);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::setYear(int year)
|
|
{
|
|
int finalYear = -1;
|
|
if (year >= 0 && year <= 99)
|
|
finalYear = year;
|
|
else if (year >= 2000 && year <= 2099)
|
|
finalYear = year - 2000;
|
|
|
|
if (finalYear >= 0)
|
|
{
|
|
if (m_uiLe)
|
|
m_uiLe->leLongYear->setValue(finalYear);
|
|
if (m_uiTouch)
|
|
setItemValue(m_uiTouch->spYear, finalYear);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int LtsDateTimeEdit::getYear() const
|
|
{
|
|
if (m_uiLe)
|
|
return 2000 + m_uiLe->leLongYear->getValue();
|
|
if (m_uiTouch)
|
|
return 2000 + m_uiTouch->spYear->value();
|
|
return 2000;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isEmpty() const
|
|
{
|
|
return (isEmptyDay() ||
|
|
isEmptyHHMMSS() ||
|
|
isEmptyMonth() ||
|
|
isEmptyTimezone() ||
|
|
isEmptyYear());
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isValidDate() const
|
|
{
|
|
return m_dateIsAcceptable;
|
|
}
|
|
|
|
|
|
bool LtsDateTimeEdit::isEmptyDay() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongDay->isEmpty();
|
|
return false;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isEmptyHHMMSS() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongHHMMSS->isEmpty();
|
|
return false;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isEmptyMonth() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongMonth->text().isEmpty();
|
|
return false;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isEmptyTimezone() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongTZ->text().isEmpty();
|
|
return false;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isEmptyYear() const
|
|
{
|
|
if (m_uiLe)
|
|
return m_uiLe->leLongYear->isEmpty();
|
|
return false;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::hasFocus() const
|
|
{
|
|
if (!m_uiLe)
|
|
return false;
|
|
return (m_uiLe->leLongDay->hasFocus() ||
|
|
m_uiLe->leLongHHMMSS->hasFocus() ||
|
|
m_uiLe->leLongMonth->hasFocus() ||
|
|
m_uiLe->leLongTZ->hasFocus() ||
|
|
m_uiLe->leLongYear->hasFocus());
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isDataAcceptable()
|
|
{
|
|
m_dateIsAcceptable = false;
|
|
|
|
bool state =
|
|
isDayAcceptable() &&
|
|
isHHMMSSAcceptable() &&
|
|
isMonthAcceptable() &&
|
|
isYearAcceptable() &&
|
|
QDate::isValid(getYear(), getMonth(), getDay()) &&
|
|
QTime::isValid(getHour(), getMinute(), getSecond());
|
|
|
|
if (m_editTimezone && state)
|
|
state = isTzAcceptable();
|
|
|
|
showInvalidData(false);
|
|
|
|
if (!state)
|
|
{
|
|
disableControls();
|
|
return false;
|
|
}
|
|
|
|
qint64 msec = QDateTime(QDate(getYear(), getMonth(), getDay()), QTime(getHour(), getMinute(), getSecond()), Qt::UTC).toMSecsSinceEpoch();
|
|
msec -= DTG::timezone2Secs(getTimezone()) * 1000LL;
|
|
if (m_minTimeMSec > 0 && m_maxTimeMSec > 0 && m_minTimeMSec < m_maxTimeMSec)
|
|
{
|
|
if (msec < m_minTimeMSec || msec > m_maxTimeMSec)
|
|
return false;
|
|
}
|
|
|
|
m_curTimeMSec = msec;
|
|
enableControls();
|
|
m_dateIsAcceptable = true;
|
|
return true;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isDayAcceptable() const
|
|
{
|
|
int value = getDay();
|
|
int max = 31;
|
|
if (isMonthAcceptable())
|
|
{
|
|
const int month = getMonth();
|
|
switch (month)
|
|
{
|
|
case 2:
|
|
{
|
|
max = 28;
|
|
if (isYearAcceptable())
|
|
{
|
|
if (getYear() % 4 == 0 && (getYear() % 100 != 0 || getYear() % 400 == 0))
|
|
|
|
max = 29;
|
|
}
|
|
break;
|
|
}
|
|
case 4:
|
|
case 6:
|
|
case 9:
|
|
case 11:
|
|
max = 30;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return (value > 0 && value <= max);
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isHHMMSSAcceptable() const
|
|
{
|
|
int hh = getHour();
|
|
if (hh < 0 || hh > 23)
|
|
return false;
|
|
|
|
int mm = getMinute();
|
|
if (mm < 0 || mm > 59)
|
|
return false;
|
|
|
|
int ss = getSecond();
|
|
if (ss < 0 || ss > 59)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isMonthAcceptable() const
|
|
{
|
|
int value = getMonth();
|
|
return (value > 0 && value <= 12);
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isYearAcceptable() const
|
|
{
|
|
if (m_uiLe)
|
|
return isLineEditDataAcceptable(m_uiLe->leLongYear);
|
|
return true;
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isTzAcceptable() const
|
|
{
|
|
if (m_uiLe)
|
|
return isLineEditDataAcceptable(m_uiLe->leLongTZ);
|
|
return true;
|
|
}
|
|
|
|
void LtsDateTimeEdit::showInvalidData(bool setFocus)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
|
|
bool focus = setFocus;
|
|
|
|
auto check = [&](QLineEdit * le, bool isValid)
|
|
{
|
|
if (isValid)
|
|
le->setStyleSheet(QString());
|
|
else
|
|
{
|
|
le->setStyleSheet(QLatin1String("background-color: yellow;"));
|
|
if (focus)
|
|
{
|
|
le->setFocus();
|
|
focus = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
check(m_uiLe->leLongDay, isDayAcceptable());
|
|
check(m_uiLe->leLongHHMMSS, isHHMMSSAcceptable());
|
|
if (m_editTimezone)
|
|
check(m_uiLe->leLongTZ, isTzAcceptable());
|
|
check(m_uiLe->leLongMonth, isMonthAcceptable());
|
|
check(m_uiLe->leLongYear, isYearAcceptable());
|
|
}
|
|
|
|
bool LtsDateTimeEdit::isLineEditDataAcceptable(QLineEdit *le) const
|
|
{
|
|
const QValidator *pValidator = le->validator();
|
|
|
|
if (!pValidator)
|
|
return true;
|
|
|
|
QString text = le->text();
|
|
|
|
int pos;
|
|
QValidator::State state = pValidator->validate(text, pos);
|
|
|
|
if (state == QValidator::Acceptable || state == QValidator::Intermediate)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void LtsDateTimeEdit::setFixedDateTime()
|
|
{
|
|
setMsecsSinceEpoch(LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("TimeSettings"), QStringLiteral("FixedTime"), 0).toLongLong());
|
|
}
|
|
|
|
void LtsDateTimeEdit::setOffsetDateTime()
|
|
{
|
|
if (!m_getCurrentTimeCallback)
|
|
return;
|
|
|
|
qint64 offset = LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("TimeSettings"), QStringLiteral("Offset"), 0).toLongLong();
|
|
|
|
setMsecsSinceEpoch((m_getCurrentTimeCallback() / 1000) * 1000 + offset);
|
|
}
|
|
|
|
void LtsDateTimeEdit::setSliderValue(int val)
|
|
{
|
|
setMsecsSinceEpoch(val * 1000LL);
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueDayChanged(const QString &str)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
int curpos = m_uiLe->leLongDay->cursorPosition();
|
|
int cp = curpos;
|
|
|
|
bool changed = false;
|
|
|
|
QString tag(str);
|
|
|
|
if (tag.length() > 2)
|
|
{
|
|
tag = tag.left(2);
|
|
changed = true;
|
|
}
|
|
|
|
bool ok;
|
|
int t = tag.toInt(&ok, 10);
|
|
|
|
if (ok)
|
|
{
|
|
if (t > 31)
|
|
{
|
|
tag.remove(curpos - 1, 1);
|
|
if (cp >= curpos)
|
|
cp--;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
m_uiLe->leLongDay->setText(tag);
|
|
m_uiLe->leLongDay->setCursorPosition(cp);
|
|
}
|
|
|
|
if (tag.length() == 2)
|
|
{
|
|
showInvalidData(false);
|
|
|
|
if (m_autoForward)
|
|
focusNextPrevChild(true);
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::fixupHHMMSS()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
|
|
int curpos = m_uiLe->leLongHHMMSS->cursorPosition();
|
|
int cp = curpos;
|
|
|
|
bool changed = false;
|
|
|
|
QString uhrzeit(m_uiLe->leLongHHMMSS->text());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString hh;
|
|
QString mm;
|
|
QString ss;
|
|
|
|
if (uhrzeit.length() > 1)
|
|
hh = uhrzeit.left(2);
|
|
else
|
|
hh = uhrzeit + QLatin1Char('0');
|
|
|
|
if (uhrzeit.length() > 0)
|
|
{
|
|
if (uhrzeit.length() == 1)
|
|
hh = uhrzeit.mid(0, 1) + QLatin1Char('0');
|
|
else if (uhrzeit.length() >= 2)
|
|
{
|
|
hh = uhrzeit.mid(0, 2);
|
|
if (uhrzeit.length() > 2)
|
|
{
|
|
if (uhrzeit.length() == 3)
|
|
mm = uhrzeit.mid(2, 1) + QLatin1Char('0');
|
|
else if (uhrzeit.length() >= 4)
|
|
{
|
|
mm = uhrzeit.mid(2, 2);
|
|
if (uhrzeit.length() == 5)
|
|
ss = uhrzeit.mid(4, 1) + QLatin1Char('0');
|
|
else if (uhrzeit.length() == 6)
|
|
ss = uhrzeit.mid(4, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ok;
|
|
|
|
int h = hh.toInt(&ok, 10);
|
|
if (ok)
|
|
{
|
|
if (h > 23)
|
|
{
|
|
uhrzeit.remove(curpos - 1, 1);
|
|
if (cp >= curpos)
|
|
cp--;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
int m = mm.toInt(&ok, 10);
|
|
|
|
if (ok)
|
|
{
|
|
if ((hh.length() == 2) && (m > 59))
|
|
{
|
|
uhrzeit.remove(curpos - 1, 1);
|
|
if (cp >= curpos)
|
|
cp--;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
int s = ss.toInt(&ok, 10);
|
|
|
|
if (ok)
|
|
{
|
|
if ((hh.length() == 2 && mm.length() == 2) && (s > 59))
|
|
{
|
|
uhrzeit.remove(curpos - 1, 1);
|
|
if (cp >= curpos)
|
|
cp--;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
m_uiLe->leLongHHMMSS->setText(uhrzeit);
|
|
m_uiLe->leLongHHMMSS->setCursorPosition(cp);
|
|
}
|
|
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueMonthChanged2(const QString &str)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (str.length() == 3 && m_uiLe->leLongMonth->selectedText().isEmpty())
|
|
focusNextPrevChild(true);
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueMonthChanged(const QString &str)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
int curpos = m_uiLe->leLongMonth->cursorPosition();
|
|
int cp = curpos;
|
|
|
|
bool changed = false;
|
|
|
|
QString monStr = str;
|
|
|
|
const auto months = DTG::months();
|
|
for (int i = 0; i < months.size(); ++i)
|
|
{
|
|
const QString &mon = months.at(i);
|
|
if (mon.startsWith(monStr, Qt::CaseInsensitive))
|
|
{
|
|
monStr = mon;
|
|
changed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!changed)
|
|
{
|
|
monStr.remove(curpos - 1, 1);
|
|
if (cp >= curpos)
|
|
cp--;
|
|
changed = true;
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
m_uiLe->leLongMonth->setText(monStr);
|
|
|
|
|
|
if (cp > 0)
|
|
m_uiLe->leLongMonth->setCursorPosition(cp);
|
|
else
|
|
m_uiLe->leLongMonth->setCursorPosition(1);
|
|
}
|
|
|
|
if (monStr.size() == 3)
|
|
{
|
|
showInvalidData(false);
|
|
if (m_autoForward)
|
|
focusNextPrevChild(true);
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueTimezoneChangedStr(const QString &str)
|
|
{
|
|
if (str.length() > 1)
|
|
{
|
|
clearTimezone();
|
|
return;
|
|
}
|
|
if (str.length() == 0)
|
|
return;
|
|
QChar c = str.at(0);
|
|
if (!c.isLetter() || c.toUpper() == QLatin1Char('J'))
|
|
{
|
|
clearTimezone();
|
|
return;
|
|
}
|
|
if (c.isLower())
|
|
setTimezone(c.toUpper().toLatin1());
|
|
|
|
showInvalidData(false);
|
|
if (m_autoForward)
|
|
focusNextPrevChild(true);
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueTimezoneChangedInt(int newTimezone)
|
|
{
|
|
Q_UNUSED(newTimezone);
|
|
if (!m_uiTouch)
|
|
return;
|
|
const QString &curText = m_uiTouch->cbxTimeZone->currentText();
|
|
if (curText.isEmpty())
|
|
return;
|
|
|
|
const QChar tz = curText.at(0);
|
|
setTimezone(tz.toUpper().toLatin1());
|
|
}
|
|
|
|
void LtsDateTimeEdit::valueYearChanged(const QString &str)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
int curpos = m_uiLe->leLongYear->cursorPosition();
|
|
int cp = curpos;
|
|
|
|
bool changed = false;
|
|
|
|
const QString &year = str;
|
|
|
|
QString yy;
|
|
if (year.length() > 2)
|
|
{
|
|
yy = year.left(2);
|
|
changed = true;
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
m_uiLe->leLongYear->setText(yy);
|
|
m_uiLe->leLongYear->setCursorPosition(cp);
|
|
}
|
|
|
|
if (year.length() == 2)
|
|
{
|
|
showInvalidData(false);
|
|
if (m_autoForward)
|
|
focusNextPrevChild(true);
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::onBackHourClicked()
|
|
{
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec - s_oneHourMSec))
|
|
setMsecsSinceEpoch(m_minTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onBackMinuteClicked()
|
|
{
|
|
const int ofs = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier) ? 5 : 1;
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec - ofs * s_oneMinuteMSec))
|
|
setMsecsSinceEpoch(m_minTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onBackSecondClicked()
|
|
{
|
|
const int ofs = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier) ? 5 : 1;
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec - ofs * s_oneSecondMSec))
|
|
setMsecsSinceEpoch(m_minTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onForwardSecondClicked()
|
|
{
|
|
const int ofs = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier) ? 5 : 1;
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec + ofs * s_oneSecondMSec))
|
|
setMsecsSinceEpoch(m_maxTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onForwardMinuteClicked()
|
|
{
|
|
const int ofs = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier) ? 5 : 1;
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec + ofs * s_oneMinuteMSec))
|
|
setMsecsSinceEpoch(m_maxTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onForwardHourClicked()
|
|
{
|
|
if (!setMsecsSinceEpoch(m_curTimeMSec + s_oneHourMSec))
|
|
setMsecsSinceEpoch(m_maxTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::onCheckBoxChanged()
|
|
{
|
|
QVector<QWidget *> widgets;
|
|
bool bEnable = false;
|
|
|
|
if (m_uiLe)
|
|
{
|
|
widgets = {m_uiLe->leLongDay, m_uiLe->leLongHHMMSS, m_uiLe->leLongTZ,
|
|
m_uiLe->leLongMonth, m_uiLe->leLongYear};
|
|
}
|
|
|
|
if (m_uiTouch)
|
|
{
|
|
widgets = {m_uiTouch->spDay, m_uiTouch->spHour, m_uiTouch->spMinutes, m_uiTouch->spSeconds, m_uiTouch->spYear, m_uiTouch->cbxMonth, m_uiTouch->cbxTimeZone, m_uiTouch->pbNow};
|
|
}
|
|
|
|
bEnable = checkBox()->isChecked();
|
|
for (auto w : qAsConst(widgets))
|
|
{
|
|
if (w)
|
|
w->setEnabled(bEnable);
|
|
}
|
|
enaDisaControls(bEnable);
|
|
}
|
|
|
|
void LtsDateTimeEdit::disableControls()
|
|
{
|
|
enaDisaControls(false);
|
|
}
|
|
|
|
void LtsDateTimeEdit::enableControls()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
|
|
enaDisaControls(true);
|
|
if (m_withSlider &&
|
|
m_minTimeMSec != 0 &&
|
|
m_maxTimeMSec > 0 &&
|
|
m_maxTimeMSec > m_minTimeMSec)
|
|
{
|
|
m_uiLe->slTime->setEnabled(true);
|
|
m_uiLe->slTime->setValue(m_curTimeMSec / 1000LL);
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::enaDisaControls(bool bEnable)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
const QVector<QWidget *> widgets({m_uiLe->pbBBB, m_uiLe->pbBB, m_uiLe->pbB,
|
|
m_uiLe->pbF, m_uiLe->pbFF, m_uiLe->pbFFF,
|
|
m_uiLe->slTime});
|
|
for (auto w : widgets)
|
|
{
|
|
if (w)
|
|
w->setEnabled(bEnable);
|
|
}
|
|
}
|
|
|
|
void LtsDateTimeEdit::setMinimumTimeMSec(qint64 msec)
|
|
{
|
|
if (m_minTimeMSec == msec)
|
|
return;
|
|
m_minTimeMSec = msec;
|
|
if (m_minTimeMSec > 0 && m_uiLe && m_uiLe->slTime)
|
|
{
|
|
m_uiLe->slTime->setMinimum(m_minTimeMSec / 1000LL);
|
|
if (m_maxTimeMSec > m_minTimeMSec)
|
|
m_uiLe->slTime->setEnabled(true);
|
|
}
|
|
if (m_curTimeMSec < m_minTimeMSec)
|
|
setMsecsSinceEpoch(m_minTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::setMaximumTimeMSec(qint64 msec)
|
|
{
|
|
if (m_maxTimeMSec == msec)
|
|
return;
|
|
m_maxTimeMSec = msec;
|
|
if (!m_uiLe || !m_uiLe->slTime)
|
|
return;
|
|
|
|
m_uiLe->slTime->setMaximum(m_maxTimeMSec / 1000LL);
|
|
if (m_minTimeMSec > 0 && m_maxTimeMSec > m_minTimeMSec)
|
|
m_uiLe->slTime->setEnabled(true);
|
|
if (m_maxTimeMSec > 0 && m_curTimeMSec > m_maxTimeMSec)
|
|
setMsecsSinceEpoch(m_maxTimeMSec);
|
|
}
|
|
|
|
void LtsDateTimeEdit::clear()
|
|
{
|
|
if (m_uiLe)
|
|
{
|
|
m_uiLe->leLongDay->clear();
|
|
m_uiLe->leLongHHMMSS->clear();
|
|
m_uiLe->leLongMonth->clear();
|
|
m_uiLe->leLongYear->clear();
|
|
m_uiLe->leLongTZ->clear();
|
|
m_curTimeMSec = 0;
|
|
}
|
|
if (m_uiTouch)
|
|
{
|
|
m_uiTouch->spDay->clear();
|
|
m_uiTouch->spHour->clear();
|
|
m_uiTouch->spMinutes->clear();
|
|
m_uiTouch->spSeconds->clear();
|
|
m_uiTouch->spYear->clear();
|
|
}
|
|
emit dateTimeChanged();
|
|
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutDay()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
if (!m_recursionAvoid && !hasFocus())
|
|
onFocusOut();
|
|
|
|
QString value = m_uiLe->leLongDay->text();
|
|
|
|
if (value.length() == 0 && !m_backspacePressed)
|
|
{
|
|
if (!isEmptyHHMMSS() ||
|
|
!isEmptyMonth() ||
|
|
(!isEmptyTimezone() && m_uiLe->leLongTZ->isEnabled()) ||
|
|
!isEmptyYear())
|
|
{
|
|
if (m_getCurrentTimeCallback)
|
|
{
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_getCurrentTimeCallback(), Qt::UTC));
|
|
setDay(dt.date().day());
|
|
}
|
|
}
|
|
}
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutHHMMSS()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
if (!m_recursionAvoid && !hasFocus())
|
|
onFocusOut();
|
|
|
|
QString value = m_uiLe->leLongHHMMSS->text();
|
|
|
|
if (value.length() == 0 && !m_backspacePressed)
|
|
{
|
|
if (!isEmptyDay() ||
|
|
!isEmptyMonth() ||
|
|
!(isEmptyTimezone() && m_uiLe->leLongTZ->isEnabled()) ||
|
|
!isEmptyYear())
|
|
{
|
|
if (m_getCurrentTimeCallback)
|
|
{
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_getCurrentTimeCallback(), Qt::UTC));
|
|
setHHMMSS(dt.time().hour(), dt.time().minute(), dt.time().second());
|
|
}
|
|
}
|
|
}
|
|
value += QString(6 - value.length(), QLatin1Char('0'));
|
|
m_uiLe->leLongHHMMSS->setText(value);
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutTZ()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
if (!m_recursionAvoid && !hasFocus())
|
|
onFocusOut();
|
|
|
|
QString value = m_uiLe->leLongTZ->text();
|
|
|
|
if (value.length() == 0 && !m_backspacePressed)
|
|
{
|
|
if (!isEmptyHHMMSS() ||
|
|
!isEmptyMonth() ||
|
|
!isEmptyDay() ||
|
|
!isEmptyYear())
|
|
setTimezone(DTG::timezone());
|
|
}
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutMonth()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
|
|
if (!m_recursionAvoid && !hasFocus())
|
|
onFocusOut();
|
|
|
|
QString value = m_uiLe->leLongMonth->text();
|
|
|
|
if (value.length() == 0 && !m_backspacePressed)
|
|
{
|
|
if (!isEmptyHHMMSS() ||
|
|
!isEmptyDay() ||
|
|
(!isEmptyTimezone() && m_uiLe->leLongTZ->isEnabled()) ||
|
|
!isEmptyYear())
|
|
{
|
|
if (m_getCurrentTimeCallback)
|
|
{
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_getCurrentTimeCallback(), Qt::UTC));
|
|
setMonth(dt.date().month());
|
|
}
|
|
}
|
|
}
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutYear()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
|
|
if (!m_recursionAvoid && !hasFocus())
|
|
onFocusOut();
|
|
|
|
QString value = m_uiLe->leLongYear->text();
|
|
|
|
if (value.length() == 1)
|
|
{
|
|
value = QLatin1Char('0') + value;
|
|
m_uiLe->leLongYear->setText(value);
|
|
}
|
|
|
|
if (value.length() == 0 && !m_backspacePressed)
|
|
{
|
|
if (!isEmptyHHMMSS() ||
|
|
!isEmptyMonth() ||
|
|
(!isEmptyTimezone() && m_uiLe->leLongTZ->isEnabled()) ||
|
|
!isEmptyDay())
|
|
{
|
|
if (m_getCurrentTimeCallback)
|
|
{
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_getCurrentTimeCallback(), Qt::UTC));
|
|
setYear(dt.date().year());
|
|
}
|
|
}
|
|
}
|
|
isDataAcceptable();
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOutBackspace()
|
|
{
|
|
m_backspacePressed = true;
|
|
}
|
|
|
|
void LtsDateTimeEdit::onFocusOut()
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_backspacePressed)
|
|
{
|
|
m_backspacePressed = false;
|
|
return;
|
|
}
|
|
m_recursionAvoid = true;
|
|
onFocusOutDay();
|
|
onFocusOutHHMMSS();
|
|
onFocusOutMonth();
|
|
onFocusOutTZ();
|
|
onFocusOutYear();
|
|
m_recursionAvoid = false;
|
|
}
|
|
|
|
void LtsDateTimeEdit::onHmsWheelEvent(bool bForward, int cursorPos)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (m_uiLe->leLongHHMMSS->text().size() != 6)
|
|
return;
|
|
|
|
fixupHHMMSS();
|
|
|
|
int selStart = 0;
|
|
switch (cursorPos)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
if (bForward)
|
|
onForwardHourClicked();
|
|
else
|
|
onBackHourClicked();
|
|
selStart = 0;
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
if (bForward)
|
|
onForwardMinuteClicked();
|
|
else
|
|
onBackMinuteClicked();
|
|
selStart = 2;
|
|
break;
|
|
case 5:
|
|
case 6:
|
|
if (bForward)
|
|
onForwardSecondClicked();
|
|
else
|
|
onBackSecondClicked();
|
|
selStart = 4;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
m_uiLe->leLongHHMMSS->setCursorPosition(cursorPos);
|
|
m_uiLe->leLongHHMMSS->setSelection(selStart, 2);
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onDayWheelEvent(bool bForward, int cursorPos)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (!isDayAcceptable())
|
|
return;
|
|
const int ofs = bForward ? 1 : -1;
|
|
setMsecsSinceEpoch(m_curTimeMSec + ofs * s_oneDayMSec, true);
|
|
m_uiLe->leLongDay->setCursorPosition(cursorPos);
|
|
m_uiLe->leLongDay->setSelection(0, 2);
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onMonthWheelEvent(bool bForward, int cursorPos)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (!isMonthAcceptable())
|
|
return;
|
|
const int ofs = bForward ? 1 : -1;
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_curTimeMSec, Qt::UTC).addMonths(ofs));
|
|
setMsecsSinceEpoch(dt.toMSecsSinceEpoch(), true);
|
|
m_uiLe->leLongMonth->setCursorPosition(cursorPos);
|
|
m_uiLe->leLongMonth->setSelection(0, 3);
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
void LtsDateTimeEdit::onYearWheelEvent(bool bForward, int cursorPos)
|
|
{
|
|
if (!m_uiLe)
|
|
return;
|
|
if (!isYearAcceptable())
|
|
return;
|
|
const int ofs = bForward ? 1 : -1;
|
|
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(m_curTimeMSec, Qt::UTC).addYears(ofs));
|
|
setMsecsSinceEpoch(dt.toMSecsSinceEpoch(), true);
|
|
m_uiLe->leLongYear->setCursorPosition(cursorPos);
|
|
m_uiLe->leLongYear->setSelection(0, 2);
|
|
emit dateTimeChanged();
|
|
}
|
|
|
|
}
|