@@ -38,17 +38,13 @@ QgsDateTimeEdit::QgsDateTimeEdit( QWidget *parent )
38
38
39
39
connect ( this , &QDateTimeEdit::dateTimeChanged, this , &QgsDateTimeEdit::changed );
40
40
41
- // set this by default to properly connect the calendar widget
41
+ // enable calendar widget by default so it's already created
42
42
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 ();
47
45
48
46
// init with current time so mIsNull is properly initialized
49
47
QDateTimeEdit::setDateTime ( QDateTime::currentDateTime () );
50
-
51
- setMinimumEditDateTime ();
52
48
}
53
49
54
50
void QgsDateTimeEdit::setAllowNull ( bool allowNull )
@@ -60,12 +56,17 @@ void QgsDateTimeEdit::setAllowNull( bool allowNull )
60
56
61
57
void QgsDateTimeEdit::clear ()
62
58
{
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
+ }
69
70
}
70
71
71
72
void QgsDateTimeEdit::setEmpty ()
@@ -76,51 +77,86 @@ void QgsDateTimeEdit::setEmpty()
76
77
77
78
void QgsDateTimeEdit::mousePressEvent ( QMouseEvent *event )
78
79
{
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 ;
81
85
82
- if ( mIsNull && ! calendarPopup () )
86
+ if ( mIsNull )
83
87
{
84
88
QStyleOptionSpinBox opt;
85
89
this ->initStyleOption ( &opt );
86
90
const QRect buttonUpRect = style ()->subControlRect ( QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp );
87
91
const QRect buttonDownRect = style ()->subControlRect ( QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown );
88
92
if ( buttonUpRect.contains ( event->pos () ) || buttonDownRect.contains ( event->pos () ) )
89
93
{
90
- int before = 1 ;
91
- if ( buttonUpRect.contains ( event->pos () ) )
94
+ if ( calendarPopup () && calendarWidget () )
92
95
{
93
- before = -1 ;
96
+ // ensure the line edit still displays NULL
97
+ displayNull ( true );
98
+ updateCalendar = true ;
94
99
}
95
-
96
- blockSignals ( true );
97
- switch ( currentSection () )
100
+ else
98
101
{
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 );
111
105
}
112
- blockSignals ( false );
113
106
}
114
107
}
115
108
116
109
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
+ }
117
153
}
118
154
119
155
void QgsDateTimeEdit::changed ( const QDateTime &dateTime )
120
156
{
121
157
mIsEmpty = false ;
122
- bool isNull = dateTime.isNull () || dateTime == minimumDateTime () ;
123
- if ( mIsNull != isNull )
158
+ bool isNull = dateTime.isNull ();
159
+ if ( isNull != mIsNull )
124
160
{
125
161
mIsNull = isNull;
126
162
if ( mIsNull )
@@ -136,16 +172,49 @@ void QgsDateTimeEdit::changed( const QDateTime &dateTime )
136
172
lineEdit ()->setStyleSheet ( mOriginalStyleSheet );
137
173
}
138
174
}
175
+
139
176
mClearAction ->setVisible ( mAllowNull && !mIsNull );
140
177
}
141
178
142
- void QgsDateTimeEdit::calendarSelectionChanged ( )
179
+ void QgsDateTimeEdit::displayNull ( bool updateCalendar )
143
180
{
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 )
146
183
{
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 ();
148
216
}
217
+ QDateTimeEdit::setDateTime ( dt );
149
218
}
150
219
151
220
void QgsDateTimeEdit::setDateTime ( const QDateTime &dateTime )
@@ -160,7 +229,6 @@ void QgsDateTimeEdit::setDateTime( const QDateTime &dateTime )
160
229
else
161
230
{
162
231
QDateTimeEdit::setDateTime ( dateTime );
163
- mIsNull = false ;
164
232
changed ( dateTime );
165
233
}
166
234
}
0 commit comments