Commit ac3e1df0 authored by David Faure's avatar David Faure Committed by Allen Winter
Browse files

KTimeZoneComboBox: fix support for floating events

12:00 my time can be either
 * floating if timeSpec() == Qt::LocalTime
 * non-floating if timeSpec() == Qt::TimeZone (in which case the system timezone is set)

KTimeZoneComboBox didn't distinguish the two, returning systemTimeZone()
in both cases. This commit adds new API that works with QDateTimes so
that the combo can read/write both timeSpec() and timeZone().
parent be61ef9d
Pipeline #146238 passed with stage
in 1 minute and 8 seconds
......@@ -8,12 +8,15 @@
#include "qtest.h"
#include <QTimeZone>
QTEST_MAIN(KTimeZoneComboBoxTest)
void KTimeZoneComboBoxTest::test_timeSpec()
{
IncidenceEditorNG::KTimeZoneComboBox combo;
combo.selectLocalTimeZone();
QVERIFY(!combo.isFloating());
if (combo.selectedTimeZone().id() != "UTC") {
QCOMPARE(combo.selectedTimeZone(), QTimeZone::systemTimeZone());
} else {
......@@ -24,5 +27,27 @@ void KTimeZoneComboBoxTest::test_timeSpec()
QCOMPARE(combo.selectedTimeZone(), QTimeZone::systemTimeZone());
combo.setFloating(true);
QVERIFY(combo.isFloating());
QCOMPARE(combo.selectedTimeZone(), QTimeZone::systemTimeZone());
}
void KTimeZoneComboBoxTest::test_dateTime()
{
IncidenceEditorNG::KTimeZoneComboBox combo;
// Floating
QDateTime dt(QDate(2021, 12, 12), QTime(12, 0, 0));
QCOMPARE(dt.timeSpec(), Qt::LocalTime);
combo.selectTimeZoneFor(dt);
QVERIFY(combo.isFloating());
// Non-floating
const QDateTime dtParis(QDate(2021, 12, 12), QTime(12, 0, 0), QTimeZone("Europe/Paris"));
QCOMPARE(dtParis.timeSpec(), Qt::TimeZone);
combo.selectTimeZoneFor(dtParis);
QVERIFY(!combo.isFloating());
QCOMPARE(combo.selectedTimeZone().id(), "Europe/Paris");
combo.applyTimeZoneTo(dt);
QCOMPARE(dt.timeSpec(), Qt::TimeZone);
QCOMPARE(dt.timeZone().id(), "Europe/Paris");
}
......@@ -12,5 +12,6 @@ class KTimeZoneComboBoxTest : public QObject
Q_OBJECT
private Q_SLOTS:
void test_timeSpec();
void test_dateTime();
};
......@@ -149,11 +149,11 @@ void IncidenceDateTime::load(const KCalendarCore::Incidence::Ptr &incidence)
enableTimeEdits();
if (mUi->mTimeZoneComboStart->currentIndex() == 0) { // Floating
mInitialStartDT.setTimeZone(QTimeZone::systemTimeZone());
mInitialStartDT.setTimeSpec(Qt::LocalTime);
}
if (mUi->mTimeZoneComboEnd->currentIndex() == 0) { // Floating
mInitialEndDT.setTimeZone(QTimeZone::systemTimeZone());
mInitialEndDT.setTimeSpec(Qt::LocalTime);
}
mWasDirty = false;
......@@ -286,10 +286,10 @@ void IncidenceDateTime::updateStartSpec()
const QDate prevDate = mCurrentStartDateTime.date();
if (mUi->mEndCheck->isChecked() && currentEndDateTime().timeZone() == mCurrentStartDateTime.timeZone()) {
mUi->mTimeZoneComboEnd->selectTimeZone(mUi->mTimeZoneComboStart->selectedTimeZone());
mUi->mTimeZoneComboEnd->setFloating(mUi->mTimeZoneComboStart->isFloating(), mUi->mTimeZoneComboStart->selectedTimeZone());
}
mCurrentStartDateTime.setTimeZone(mUi->mTimeZoneComboStart->selectedTimeZone());
mUi->mTimeZoneComboStart->applyTimeZoneTo(mCurrentStartDateTime);
const bool dateChanged = mCurrentStartDateTime.date() != prevDate;
......@@ -375,12 +375,18 @@ void IncidenceDateTime::enableTimeEdits()
if (mUi->mStartCheck->isChecked()) {
mUi->mStartTimeEdit->setEnabled(!wholeDayChecked);
mUi->mTimeZoneComboStart->setEnabled(!wholeDayChecked);
mUi->mTimeZoneComboStart->setFloating(wholeDayChecked, mInitialStartDT.timeZone());
if (wholeDayChecked)
mUi->mTimeZoneComboStart->setFloating(true);
else
mUi->mTimeZoneComboStart->selectTimeZoneFor(mInitialStartDT);
}
if (mUi->mEndCheck->isChecked()) {
mUi->mEndTimeEdit->setEnabled(!wholeDayChecked);
mUi->mTimeZoneComboEnd->setEnabled(!wholeDayChecked);
mUi->mTimeZoneComboEnd->setFloating(wholeDayChecked, mInitialEndDT.timeZone());
if (wholeDayChecked)
mUi->mTimeZoneComboEnd->setFloating(true);
else
mUi->mTimeZoneComboEnd->selectTimeZoneFor(mInitialEndDT);
}
/**
......@@ -493,12 +499,16 @@ bool IncidenceDateTime::isDirty(const KCalendarCore::Journal::Ptr &journal) cons
QDateTime IncidenceDateTime::currentStartDateTime() const
{
return QDateTime(mUi->mStartDateEdit->date(), mUi->mStartTimeEdit->time(), mUi->mTimeZoneComboStart->selectedTimeZone());
QDateTime dt(mUi->mStartDateEdit->date(), mUi->mStartTimeEdit->time());
mUi->mTimeZoneComboStart->applyTimeZoneTo(dt);
return dt;
}
QDateTime IncidenceDateTime::currentEndDateTime() const
{
return QDateTime(mUi->mEndDateEdit->date(), mUi->mEndTimeEdit->time(), mUi->mTimeZoneComboEnd->selectedTimeZone());
QDateTime dt(mUi->mEndDateEdit->date(), mUi->mEndTimeEdit->time());
mUi->mTimeZoneComboEnd->applyTimeZoneTo(dt);
return dt;
}
void IncidenceDateTime::load(const KCalendarCore::Event::Ptr &event, bool isTemplate, bool templateOverridesTimes)
......@@ -698,23 +708,23 @@ void IncidenceDateTime::setDateTimes(const QDateTime &start, const QDateTime &en
if (start.isValid()) {
mUi->mStartDateEdit->setDate(start.date());
mUi->mStartTimeEdit->setTime(start.time());
mUi->mTimeZoneComboStart->selectTimeZone(start.timeZone());
mUi->mTimeZoneComboStart->selectTimeZoneFor(start);
} else {
QDateTime dt = QDateTime::currentDateTime();
mUi->mStartDateEdit->setDate(dt.date());
mUi->mStartTimeEdit->setTime(dt.time());
mUi->mTimeZoneComboStart->selectTimeZone(dt.timeZone());
mUi->mTimeZoneComboStart->selectTimeZoneFor(dt);
}
if (end.isValid()) {
mUi->mEndDateEdit->setDate(end.date());
mUi->mEndTimeEdit->setTime(end.time());
mUi->mTimeZoneComboEnd->selectTimeZone(end.timeZone());
mUi->mTimeZoneComboEnd->selectTimeZoneFor(end);
} else {
QDateTime dt(QDate::currentDate(), QTime::currentTime().addSecs(60 * 60));
mUi->mEndDateEdit->setDate(dt.date());
mUi->mEndTimeEdit->setTime(dt.time());
mUi->mTimeZoneComboEnd->selectTimeZone(dt.timeZone());
mUi->mTimeZoneComboEnd->selectTimeZoneFor(dt);
}
mCurrentStartDateTime = currentStartDateTime();
......@@ -771,8 +781,8 @@ void IncidenceDateTime::setTimes(const QDateTime &start, const QDateTime &end)
mUi->mEndTimeEdit->setTime(end.time());
mUi->mTimeZoneComboStart->selectTimeZone(start.timeZone());
mUi->mTimeZoneComboEnd->selectTimeZone(end.timeZone());
mUi->mTimeZoneComboStart->selectTimeZoneFor(start);
mUi->mTimeZoneComboEnd->selectTimeZoneFor(end);
// emitDateTimeStr();
}
......
......@@ -135,10 +135,20 @@ void IncidenceDefaultsPrivate::eventDefaults(const KCalendarCore::Event::Ptr &ev
}
}
if (startDT.timeSpec() == Qt::LocalTime) {
// Ensure the default is not "floating"
startDT.setTimeZone(QTimeZone::systemTimeZone());
}
const QTime defaultDurationTime = KCalPrefs::instance()->defaultDuration().time();
const int defaultDuration = (defaultDurationTime.hour() * 3600) + (defaultDurationTime.minute() * 60);
const QDateTime endDT = mEndDt.isValid() ? mEndDt : startDT.addSecs(defaultDuration);
QDateTime endDT = mEndDt.isValid() ? mEndDt : startDT.addSecs(defaultDuration);
if (endDT.timeSpec() == Qt::LocalTime) {
// Ensure the default is not "floating"
endDT.setTimeZone(QTimeZone::systemTimeZone());
}
event->setDtStart(startDT);
event->setDtEnd(endDT);
......
......@@ -83,6 +83,14 @@ void KTimeZoneComboBox::selectTimeZone(const QTimeZone &zone)
}
}
void KTimeZoneComboBox::selectTimeZoneFor(const QDateTime &dateTime)
{
if (dateTime.timeSpec() == Qt::LocalTime)
setCurrentIndex(1); // Floating
else
selectTimeZone(dateTime.timeZone());
}
QTimeZone KTimeZoneComboBox::selectedTimeZone() const
{
QTimeZone zone;
......@@ -118,3 +126,17 @@ void KTimeZoneComboBox::setFloating(bool floating, const QTimeZone &zone)
}
}
}
void KTimeZoneComboBox::applyTimeZoneTo(QDateTime &dt) const
{
if (isFloating()) {
dt.setTimeSpec(Qt::LocalTime);
} else {
dt.setTimeZone(selectedTimeZone());
}
}
bool KTimeZoneComboBox::isFloating() const
{
return currentIndex() == 1;
}
......@@ -45,6 +45,11 @@ public:
*/
void selectTimeZone(const QTimeZone &zone);
/**
* Selects the item in the combobox corresponding to the zone for the given @p datetime.
*/
void selectTimeZoneFor(const QDateTime &dateTime);
/**
* Convenience version of selectTimeZone(const QTimeZone &).
* Selects the local time zone specified in the user settings.
......@@ -58,11 +63,23 @@ public:
*/
void setFloating(bool floating, const QTimeZone &zone = {});
/**
* Applies the selected timezone to the given QDateTime
* This isn't the same as dt.setTimeZone(selectedTimeZone) because
* of the "floating" special case.
*/
void applyTimeZoneTo(QDateTime &dt) const;
/**
* Return the time zone associated with the currently selected item.
*/
Q_REQUIRED_RESULT QTimeZone selectedTimeZone() const;
/**
* Returns true if the selecting timezone is the floating time zone
*/
Q_REQUIRED_RESULT bool isFloating() const;
private:
//@cond PRIVATE
std::unique_ptr<KTimeZoneComboBoxPrivate> const d;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment