Skip to content

Commit 230e91c

Browse files
committedJan 3, 2018
[date time widget] do not use minimumDateTime for NULL values
fixes issue when setting min and max values for the widget
1 parent 2129698 commit 230e91c

File tree

3 files changed

+125
-45
lines changed

3 files changed

+125
-45
lines changed
 

‎python/gui/editorwidgets/qgsdatetimeedit.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ Resets the widget to show no value (ie, an "unknown" state).
6868
protected:
6969
virtual void mousePressEvent( QMouseEvent *event );
7070

71+
virtual void focusOutEvent( QFocusEvent *event );
72+
73+
virtual void wheelEvent( QWheelEvent *event );
74+
75+
virtual void showEvent( QShowEvent *event );
76+
7177

7278
};
7379

‎src/gui/editorwidgets/qgsdatetimeedit.cpp

Lines changed: 110 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,13 @@ QgsDateTimeEdit::QgsDateTimeEdit( QWidget *parent )
3838

3939
connect( this, &QDateTimeEdit::dateTimeChanged, this, &QgsDateTimeEdit::changed );
4040

41-
// set this by default to properly connect the calendar widget
41+
// enable calendar widget by default so it's already created
4242
setCalendarPopup( true );
43-
// when clearing the widget, date of the QDateTimeEdit will be set to minimum date
44-
// hence when the calendar popups, on selection changed if it set to the minimum date,
45-
// the page of the current date will be shown
46-
connect( calendarWidget(), &QCalendarWidget::selectionChanged, this, &QgsDateTimeEdit::calendarSelectionChanged );
43+
44+
setMinimumEditDateTime();
4745

4846
// init with current time so mIsNull is properly initialized
4947
QDateTimeEdit::setDateTime( QDateTime::currentDateTime() );
50-
51-
setMinimumEditDateTime();
5248
}
5349

5450
void QgsDateTimeEdit::setAllowNull( bool allowNull )
@@ -60,12 +56,17 @@ void QgsDateTimeEdit::setAllowNull( bool allowNull )
6056

6157
void QgsDateTimeEdit::clear()
6258
{
63-
QDateTimeEdit::blockSignals( true );
64-
setSpecialValueText( QgsApplication::nullRepresentation() );
65-
QDateTimeEdit::setDateTime( minimumDateTime() );
66-
QDateTimeEdit::blockSignals( false );
67-
changed( QDateTime() );
68-
emit dateTimeChanged( QDateTime() );
59+
if ( mAllowNull )
60+
{
61+
displayNull();
62+
63+
changed( QDateTime() );
64+
65+
// avoid slot double activation
66+
disconnect( this, &QDateTimeEdit::dateTimeChanged, this, &QgsDateTimeEdit::changed );
67+
emit dateTimeChanged( QDateTime() );
68+
connect( this, &QDateTimeEdit::dateTimeChanged, this, &QgsDateTimeEdit::changed );
69+
}
6970
}
7071

7172
void QgsDateTimeEdit::setEmpty()
@@ -76,51 +77,86 @@ void QgsDateTimeEdit::setEmpty()
7677

7778
void QgsDateTimeEdit::mousePressEvent( QMouseEvent *event )
7879
{
79-
// catch mouse press on the button when in non-calendar mode to modifiy the date
80-
// so it leads to showing current date (don't bother about time)
80+
// catch mouse press on the button
81+
// in non-calendar mode: modifiy the date so it leads to showing current date (don't bother about time)
82+
// in calendar mode: be sure NULL is displayed when needed and show page of current date in calendar widget
83+
84+
bool updateCalendar = false;
8185

82-
if ( mIsNull && !calendarPopup() )
86+
if ( mIsNull )
8387
{
8488
QStyleOptionSpinBox opt;
8589
this->initStyleOption( &opt );
8690
const QRect buttonUpRect = style()->subControlRect( QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp );
8791
const QRect buttonDownRect = style()->subControlRect( QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown );
8892
if ( buttonUpRect.contains( event->pos() ) || buttonDownRect.contains( event->pos() ) )
8993
{
90-
int before = 1;
91-
if ( buttonUpRect.contains( event->pos() ) )
94+
if ( calendarPopup() && calendarWidget() )
9295
{
93-
before = -1;
96+
// ensure the line edit still displays NULL
97+
displayNull( true );
98+
updateCalendar = true;
9499
}
95-
96-
blockSignals( true );
97-
switch ( currentSection() )
100+
else
98101
{
99-
case QDateTimeEdit::DaySection:
100-
QDateTimeEdit::setDateTime( QDateTime::currentDateTime().addDays( before ) );
101-
break;
102-
case QDateTimeEdit::MonthSection:
103-
QDateTimeEdit::setDateTime( QDateTime::currentDateTime().addMonths( before ) );
104-
break;
105-
case QDateTimeEdit::YearSection:
106-
QDateTimeEdit::setDateTime( QDateTime::currentDateTime().addYears( before ) );
107-
break;
108-
default:
109-
QDateTimeEdit::setDateTime( QDateTime::currentDateTime() );
110-
break;
102+
blockSignals( true );
103+
resetBeforeChange( buttonUpRect.contains( event->pos() ) ? -1 : 1 );
104+
blockSignals( false );
111105
}
112-
blockSignals( false );
113106
}
114107
}
115108

116109
QDateTimeEdit::mousePressEvent( event );
110+
111+
if ( updateCalendar )
112+
{
113+
// set calendar page to current date to avoid going to minimal date page when value is null
114+
calendarWidget()->setCurrentPage( QDate::currentDate().year(), QDate::currentDate().month() );
115+
}
116+
}
117+
118+
void QgsDateTimeEdit::focusOutEvent( QFocusEvent *event )
119+
{
120+
if ( mAllowNull && mIsNull )
121+
{
122+
if ( lineEdit()->text() != QgsApplication::nullRepresentation() )
123+
{
124+
displayNull();
125+
}
126+
QWidget::focusOutEvent( event );
127+
emit editingFinished();
128+
}
129+
else
130+
{
131+
QDateTimeEdit::focusOutEvent( event );
132+
}
133+
}
134+
135+
void QgsDateTimeEdit::wheelEvent( QWheelEvent *event )
136+
{
137+
// dateTime might have been set to minimum in calendar mode
138+
if ( mAllowNull && mIsNull )
139+
{
140+
resetBeforeChange( -event->delta() );
141+
}
142+
QDateTimeEdit::wheelEvent( event );
143+
}
144+
145+
void QgsDateTimeEdit::showEvent( QShowEvent *event )
146+
{
147+
QDateTimeEdit::showEvent( event );
148+
if ( mAllowNull && mIsNull &&
149+
lineEdit()->text() != QgsApplication::nullRepresentation() )
150+
{
151+
displayNull();
152+
}
117153
}
118154

119155
void QgsDateTimeEdit::changed( const QDateTime &dateTime )
120156
{
121157
mIsEmpty = false;
122-
bool isNull = dateTime.isNull() || dateTime == minimumDateTime();
123-
if ( mIsNull != isNull )
158+
bool isNull = dateTime.isNull();
159+
if ( isNull != mIsNull )
124160
{
125161
mIsNull = isNull;
126162
if ( mIsNull )
@@ -136,16 +172,49 @@ void QgsDateTimeEdit::changed( const QDateTime &dateTime )
136172
lineEdit()->setStyleSheet( mOriginalStyleSheet );
137173
}
138174
}
175+
139176
mClearAction->setVisible( mAllowNull && !mIsNull );
140177
}
141178

142-
void QgsDateTimeEdit::calendarSelectionChanged()
179+
void QgsDateTimeEdit::displayNull( bool updateCalendar )
143180
{
144-
// set calendar page to current date to avoid going to minimal date page when value is null
145-
if ( mAllowNull && calendarWidget() && calendarWidget()->selectedDate() == minimumDate() )
181+
blockSignals( true );
182+
if ( updateCalendar )
146183
{
147-
calendarWidget()->setCurrentPage( QDate::currentDate().year(), QDate::currentDate().month() );
184+
// set current time to minimum date time to avoid having
185+
// a date selected in calendar widget
186+
QDateTimeEdit::setDateTime( minimumDateTime() );
187+
}
188+
lineEdit()->setText( QgsApplication::nullRepresentation() );
189+
blockSignals( false );
190+
}
191+
192+
void QgsDateTimeEdit::resetBeforeChange( int delta )
193+
{
194+
QDateTime dt = QDateTime::currentDateTime();
195+
switch ( currentSection() )
196+
{
197+
case QDateTimeEdit::DaySection:
198+
dt = dt.addDays( delta );
199+
break;
200+
case QDateTimeEdit::MonthSection:
201+
dt = dt.addMonths( delta );
202+
break;
203+
case QDateTimeEdit::YearSection:
204+
dt = dt.addYears( delta );
205+
break;
206+
default:
207+
break;
208+
}
209+
if ( dt < minimumDateTime() )
210+
{
211+
dt = minimumDateTime();
212+
}
213+
else if ( dt > maximumDateTime() )
214+
{
215+
dt = maximumDateTime();
148216
}
217+
QDateTimeEdit::setDateTime( dt );
149218
}
150219

151220
void QgsDateTimeEdit::setDateTime( const QDateTime &dateTime )
@@ -160,7 +229,6 @@ void QgsDateTimeEdit::setDateTime( const QDateTime &dateTime )
160229
else
161230
{
162231
QDateTimeEdit::setDateTime( dateTime );
163-
mIsNull = false;
164232
changed( dateTime );
165233
}
166234
}

‎src/gui/editorwidgets/qgsdatetimeedit.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,26 @@ class GUI_EXPORT QgsDateTimeEdit : public QDateTimeEdit
6464

6565
protected:
6666
void mousePressEvent( QMouseEvent *event ) override;
67+
void focusOutEvent( QFocusEvent *event ) override;
68+
void wheelEvent( QWheelEvent *event ) override;
69+
void showEvent( QShowEvent *event ) override;
6770

6871
private slots:
6972
void changed( const QDateTime &dateTime );
7073

71-
void calendarSelectionChanged();
72-
7374
private:
7475
bool mAllowNull = true;
75-
bool mIsNull = true;
76+
bool mIsNull = false;
7677
bool mIsEmpty = false;
7778

7879
QString mOriginalStyleSheet = QString();
7980
QAction *mClearAction;
8081

82+
void displayNull( bool updateCalendar = false );
83+
84+
//! reset the value to current date time
85+
void resetBeforeChange( int delta );
86+
8187
/**
8288
* Set the lowest Date that can be displayed with the Qt::ISODate format
8389
* - uses QDateTimeEdit::setMinimumDateTime (since Qt 4.4)

0 commit comments

Comments
 (0)