QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsdatetimeeditwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatetimeeditwrapper.cpp
3  --------------------------------------
4  Date : 03.2014
5  Copyright : (C) 2014 Denis Rouzaud
6  Email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsdatetimeeditwrapper.h"
17 #include "qgsdatetimeeditfactory.h"
18 #include "qgsmessagelog.h"
19 #include "qgslogger.h"
20 #include "qgsdatetimeedit.h"
21 #include "qgsdatetimeeditconfig.h"
23 #include "qgsapplication.h"
24 
25 #include <QDateTimeEdit>
26 #include <QDateEdit>
27 #include <QTimeEdit>
28 #include <QTextCharFormat>
29 #include <QCalendarWidget>
30 
31 QgsDateTimeEditWrapper::QgsDateTimeEditWrapper( QgsVectorLayer *layer, int fieldIdx, QWidget *editor, QWidget *parent )
32  : QgsEditorWidgetWrapper( layer, fieldIdx, editor, parent )
33 
34 {
35 }
36 
37 QWidget *QgsDateTimeEditWrapper::createWidget( QWidget *parent )
38 {
39  QgsDateTimeEdit *widget = new QgsDateTimeEdit( parent );
40  widget->setDateTime( QDateTime::currentDateTime() );
41  return widget;
42 }
43 
44 void QgsDateTimeEditWrapper::initWidget( QWidget *editor )
45 {
46  QgsDateTimeEdit *qgsEditor = dynamic_cast<QgsDateTimeEdit *>( editor );
47  if ( qgsEditor )
48  {
49  mQgsDateTimeEdit = qgsEditor;
50  }
51  // assign the Qt editor also if the QGIS editor has been previously assigned
52  // this avoids testing each time which widget to use
53  // the QGIS editor must be used for non-virtual methods (dateTime, setDateTime)
54  QDateTimeEdit *qtEditor = dynamic_cast<QDateTimeEdit *>( editor );
55  if ( qtEditor )
56  {
57  mQDateTimeEdit = qtEditor;
58  }
59 
60  if ( !mQDateTimeEdit )
61  {
62  QgsDebugError( QStringLiteral( "Date/time edit widget could not be initialized because provided widget is not a QDateTimeEdit." ) );
63  QgsMessageLog::logMessage( tr( "Date/time edit widget could not be initialized because provided widget is not a QDateTimeEdit." ), tr( "UI forms" ), Qgis::MessageLevel::Warning );
64  return;
65  }
66 
67  const QString displayFormat = config( QStringLiteral( "display_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
68  mQDateTimeEdit->setDisplayFormat( displayFormat );
69 
70  const bool calendar = config( QStringLiteral( "calendar_popup" ), true ).toBool();
71  if ( calendar != mQDateTimeEdit->calendarPopup() )
72  {
73  mQDateTimeEdit->setCalendarPopup( calendar );
74  }
75  if ( calendar && mQDateTimeEdit->calendarWidget() )
76  {
77  // highlight today's date
78  QTextCharFormat todayFormat;
79  todayFormat.setBackground( QColor( 160, 180, 200 ) );
80  mQDateTimeEdit->calendarWidget()->setDateTextFormat( QDate::currentDate(), todayFormat );
81  }
82 
83  const bool allowNull = config( QStringLiteral( "allow_null" ), true ).toBool();
84  if ( mQgsDateTimeEdit )
85  {
86  mQgsDateTimeEdit->setAllowNull( allowNull );
87  }
88  else
89  {
90  QgsMessageLog::logMessage( tr( "The usual date/time widget QDateTimeEdit cannot be configured to allow NULL values. "
91  "For that the QGIS custom widget QgsDateTimeEdit needs to be used." ),
92  tr( "field widgets" ) );
93  }
94 
95  if ( mQgsDateTimeEdit )
96  {
97  connect( mQgsDateTimeEdit, &QgsDateTimeEdit::valueChanged, this, &QgsDateTimeEditWrapper::dateTimeChanged );
98  }
99  else
100  {
101  connect( mQDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this, &QgsDateTimeEditWrapper::dateTimeChanged );
102  }
103 }
104 
106 {
107  return mQgsDateTimeEdit || mQDateTimeEdit;
108 }
109 
111 {
112  if ( mQgsDateTimeEdit )
113  mQgsDateTimeEdit->setEmpty();
114 }
115 
116 void QgsDateTimeEditWrapper::dateTimeChanged( const QDateTime &dateTime )
117 {
118  switch ( field().type() )
119  {
120  case QVariant::DateTime:
122  emit valueChanged( dateTime );
124  emit valuesChanged( dateTime );
125  break;
126  case QVariant::Date:
128  emit valueChanged( dateTime.date() );
130  emit valuesChanged( dateTime.date() );
131  break;
132  case QVariant::Time:
134  emit valueChanged( dateTime.time() );
136  emit valuesChanged( dateTime.time() );
137  break;
138  default:
139  if ( !dateTime.isValid() || dateTime.isNull() )
140  {
142  emit valueChanged( QVariant( field().type() ) );
144  emit valuesChanged( QVariant( field().type() ) );
145  }
146  else
147  {
148  const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
149  const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
150  if ( fieldIsoFormat )
151  {
153  emit valueChanged( dateTime.toString( Qt::ISODate ) );
155  emit valuesChanged( dateTime.toString( Qt::ISODate ) );
156  }
157  else
158  {
160  emit valueChanged( dateTime.toString( fieldFormat ) );
162  emit valuesChanged( dateTime.toString( fieldFormat ) );
163  }
164  }
165  break;
166  }
167 }
168 
170 {
171  if ( !mQDateTimeEdit )
172  return QVariant( field().type() );
173 
174  QDateTime dateTime;
175  if ( mQgsDateTimeEdit )
176  {
177  dateTime = mQgsDateTimeEdit->dateTime();
178  }
179  else
180  {
181  dateTime = mQDateTimeEdit->dateTime();
182  }
183 
184  if ( dateTime.isNull() )
185  return QVariant( field().type() );
186 
187  switch ( field().type() )
188  {
189  case QVariant::DateTime:
190  return dateTime;
191  case QVariant::Date:
192  return dateTime.date();
193  case QVariant::Time:
194  return dateTime.time();
195  default:
196  const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
197  const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
198  if ( fieldIsoFormat )
199  {
200  return dateTime.toString( Qt::ISODate );
201  }
202  else
203  {
204  return dateTime.toString( fieldFormat );
205  }
206  }
207 #ifndef _MSC_VER // avoid warnings
208  return QVariant(); // avoid warnings
209 #endif
210 }
211 
212 void QgsDateTimeEditWrapper::updateValues( const QVariant &value, const QVariantList & )
213 {
214  if ( !mQDateTimeEdit )
215  return;
216 
217  QDateTime dateTime;
218 
219  switch ( field().type() )
220  {
221  case QVariant::DateTime:
222  dateTime = value.toDateTime();
223  break;
224  case QVariant::Date:
225  dateTime.setDate( value.toDate() );
226  dateTime.setTime( QTime( 0, 0, 0 ) );
227  break;
228  case QVariant::Time:
229  dateTime.setDate( QDate::currentDate() );
230  dateTime.setTime( value.toTime() );
231  break;
232  default:
233  // Field type is not a date/time but we might already have a date/time variant
234  // value coming from a default: no need for string parsing in that case
235  switch ( value.type() )
236  {
237  case QVariant::DateTime:
238  {
239  dateTime = value.toDateTime();
240  break;
241  }
242  case QVariant::Date:
243  {
244  dateTime.setDate( value.toDate() );
245  dateTime.setTime( QTime( 0, 0, 0 ) );
246  break;
247  }
248  case QVariant::Time:
249  {
250  dateTime.setDate( QDate::currentDate() );
251  dateTime.setTime( value.toTime() );
252  break;
253  }
254  default:
255  {
256  const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
257  const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
258  if ( fieldIsoFormat )
259  {
260  dateTime = QDateTime::fromString( value.toString(), Qt::ISODate );
261  }
262  else
263  {
264  dateTime = QDateTime::fromString( value.toString(), fieldFormat );
265  }
266  break;
267  }
268  }
269  break;
270  }
271 
272  if ( mQgsDateTimeEdit )
273  {
274  mQgsDateTimeEdit->setDateTime( dateTime );
275  }
276  else
277  {
278  mQDateTimeEdit->setDateTime( dateTime );
279  }
280 }
281 
283 {
284  if ( !mQDateTimeEdit )
285  return;
286 
287  mQDateTimeEdit->setReadOnly( !enabled );
288  mQDateTimeEdit->setFrame( enabled );
289 }
bool valid() const override
Returns true if the widget has been properly initialized.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QgsDateTimeEditWrapper(QgsVectorLayer *layer, int fieldIdx, QWidget *editor, QWidget *parent=nullptr)
Constructor for QgsDateTimeEditWrapper.
QVariant value() const override
Will be used to access the widget's value.
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
void setEnabled(bool enabled) override
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
The QgsDateTimeEdit class is a QDateTimeEdit with the capability of setting/reading null date/times.
void setAllowNull(bool allowNull)
Determines if the widget allows setting null date/time.
QDateTime dateTime() const
Returns the date time which can be a null date/time.
void setDateTime(const QDateTime &dateTime)
Set the date time in the widget and handles null date times.
void setEmpty()
Resets the widget to show no value (ie, an "unknown" state).
void valueChanged(const QDateTime &date)
Signal emitted whenever the value changes.
static QString defaultFormat(QVariant::Type type)
Gets the default format in function of the type.
Manages an editor widget Widget and wrapper share the same parent.
Q_DECL_DEPRECATED void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
void valuesChanged(const QVariant &value, const QVariantList &additionalFieldValues=QVariantList())
Emit this signal, whenever the value changed.
QgsField field() const
Access the field.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Represents a vector layer which manages a vector based data sets.
QWidget * widget()
Access the widget managed by this wrapper.
QVariantMap config() const
Returns the whole config.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:5741
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:5740
#define QgsDebugError(str)
Definition: qgslogger.h:38