Files
qt5-legatus-legacy/Lts/Common/LtsWidgets/lts_date_time_edit.cpp
T
2026-08-13 18:33:10 +02:00

1793 lines
44 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* DTGEdit
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2016-08-17
*/
#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; // don't know why
#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; // 3 invisible widgets before
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);
} // setupUi
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; // 3 from above, 3 by default
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);
} //addButtons
void addSlider(QWidget *parent)
{
slTime = new QSlider(parent);
slTime->setOrientation(Qt::Horizontal);
gridLayout->addWidget(slTime, 1, 0, 1, 7);
} //addSlider
};
}
namespace LtsWidgets
{
//
// helper (via overloading)
//
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();
}
// helper (via overloading) END
//
// class LtsDateTimeEdit
//
LtsDateTimeEdit::LtsDateTimeEdit(QWidget *parent, bool withNowButton, bool checkable)
: QWidget(parent)
// , m_uiLe(new Ui::LtsDateTimeEditLe)
, 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) // see below
, m_withNowButton(withNowButton) // see below
{
#ifdef TABLET_MODE
// entweder TOUCH (SpinBox/ComboBox)
setupUiTouch();
return;
#else
// oder default (LineEdit)
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, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
// this, &LtsDateTimeEdit::valueMonthChanged);
connect(m_uiTouch->cbxMonth, &QComboBox::currentTextChanged,
this, &LtsDateTimeEdit::valueMonthChanged);
connect(checkBox(), &QCheckBox::toggled, this, &LtsDateTimeEdit::toggled);
setMinMaxMonth(1,12);
setTimezone(DTG::timezone());
//m_tzOffset = DTG::timezone2Secs(QLatin1Char(DTG::timezone()).toLatin1());
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) // If no checkBox -> set other Elements enabled
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; // will be correctly set in isDataAcceptable()
if (msec == 0)
return false;
// nothing changed ?
// deactivate since m_offsetTimeZone may have changed:
// if (m_curTimeMSec / 1000 == msec / 1000)
// return isDataAcceptable();
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 (!setTimezone(tz) ||
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); // to update GUI
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;
// DTG-Widget: DTG = DateTimeGroup.
// So using the english abbreviations (available via DTG::months()) is correct:
const QStringList &monthSl = DTG::months();
m_uiTouch->cbxMonth->addItem(monthSl[i-1], i);
// Former (incorrect) way
// QDate date(1777,i,1);
// m_uiTouch->cbxMonth->addItem(date.toString(QStringLiteral("MMM")), i);
}
// cbxMonth.currentData return the correct inht value for the month :-)
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; // spinBox can´t be empty
}
bool LtsDateTimeEdit::isEmptyHHMMSS() const
{
if (m_uiLe)
return m_uiLe->leLongHHMMSS->isEmpty();
return false; // spinBox can´t be empty
}
bool LtsDateTimeEdit::isEmptyMonth() const
{
if (m_uiLe)
return m_uiLe->leLongMonth->text().isEmpty();
return false; // spinBox can´t be empty
}
bool LtsDateTimeEdit::isEmptyTimezone() const
{
if (m_uiLe)
return m_uiLe->leLongTZ->text().isEmpty();
return false; // comboBox can´t be empty
}
bool LtsDateTimeEdit::isEmptyYear() const
{
if (m_uiLe)
return m_uiLe->leLongYear->isEmpty();
return false; // spinBox can´t be empty
}
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))
// centennial years (2100, 2200...) are not leap, unless they divide by 400 (2000, 2400...)!
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; // spinBox/combobox !acceptable
}
bool LtsDateTimeEdit::isTzAcceptable() const
{
if (m_uiLe)
return isLineEditDataAcceptable(m_uiLe->leLongTZ);
return true; // spinBox/combobox !acceptable
}
void LtsDateTimeEdit::showInvalidData(bool setFocus)
{
if (!m_uiLe)
return;
bool focus = setFocus; // Fokus bei Fehler setzen ???
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();
// we only show seconds, so strip away milliseconds
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); // letztes Zeichen wieder entfernen
if (cp >= curpos)
cp--; // Korrektur der neuen Cursorposition
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());
//
// Wertebereich überprüfen: 000000 bis 235959 zulässig
//
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); // letztes Zeichen wieder entfernen
if (cp >= curpos)
cp--; // Korrektur der neuen Cursorposition
changed = true;
}
}
int m = mm.toInt(&ok, 10);
if (ok)
{
if ((hh.length() == 2) && (m > 59)) // WICHTIG: beide Stellen fuer Stunde bereits gesetzt !!!
{
uhrzeit.remove(curpos - 1, 1); // letztes Zeichen wieder entfernen
if (cp >= curpos)
cp--; // Korrektur der neuen Cursorposition
changed = true;
}
}
int s = ss.toInt(&ok, 10);
if (ok)
{
if ((hh.length() == 2 && mm.length() == 2) && (s > 59)) // WICHTIG: beide Stellen fuer Stunde und Minute bereits gesetzt !!!
{
uhrzeit.remove(curpos - 1, 1); // letztes Zeichen wieder entfernen
if (cp >= curpos)
cp--; // Korrektur der neuen Cursorposition
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); // letztes Zeichen wieder entfernen
if (cp >= curpos)
cp--; // Korrektur der neuen Cursorposition
changed = true;
}
if (changed)
{
m_uiLe->leLongMonth->setText(monStr);
// WICHTIG: keine negativen Cursorpositionen setzen, da sonst Absturzgefahr !!!
// Bem.: wird in DigitsLineEdit bereits abgefangen
if (cp > 0)
m_uiLe->leLongMonth->setCursorPosition(cp);
else
m_uiLe->leLongMonth->setCursorPosition(1); // Ausweichposition linker Textanfang
}
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();
// Leeres Feld nur mit aktueller Uhrzeit auffüllen, wenn irgendein Feld schon befüllt ist:
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();
// Leeres Feld nur mit aktueller Uhrzeit auffüllen, wenn irgendein Feld schon befüllt ist:
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();
// Leeres Feld nur mit aktueller Uhrzeit auffüllen, wenn irgendein Feld schon befüllt ist:
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();
// Leeres Feld nur mit aktueller Uhrzeit auffüllen, wenn irgendein Feld schon befüllt ist:
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();
// should always be displayed with 2 digits
if (value.length() == 1)
{
value = QLatin1Char('0') + value;
m_uiLe->leLongYear->setText(value);
}
// Leeres Feld nur mit aktueller Uhrzeit auffüllen, wenn irgendein Feld schon befüllt ist:
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();
}
} // namespace LtsWidgets