1793 lines
44 KiB
C++
Executable File
1793 lines
44 KiB
C++
Executable File
/**
|
||
* @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
|