Skip to content

Commit

Permalink
Merge pull request #5960 from 3nids/fix16657
Browse files Browse the repository at this point in the history
fix date/time widget for field with time zones
  • Loading branch information
3nids authored Jan 3, 2018
2 parents cef2db9 + 69cfdc4 commit bdf744e
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 66 deletions.
8 changes: 5 additions & 3 deletions python/core/fieldformatter/qgsdatetimefieldformatter.sip
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ the field configuration.
#include "qgsdatetimefieldformatter.h"
%End
public:
static const QString DEFAULT_DATE_FORMAT;
static const QString DEFAULT_TIME_FORMAT;
static const QString DEFAULT_DATETIME_FORMAT;
static const QString DATE_FORMAT;
static const QString TIME_FORMAT;
static const QString DATETIME_FORMAT;
static const QString QT_ISO_FORMAT;
static const QString DISPLAY_FOR_ISO_FORMAT;

QgsDateTimeFieldFormatter();
%Docstring
Expand Down
30 changes: 21 additions & 9 deletions src/core/fieldformatter/qgsdatetimefieldformatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
#include "qgsfield.h"
#include "qgsvectorlayer.h"

const QString QgsDateTimeFieldFormatter::DEFAULT_DATE_FORMAT = QStringLiteral( "yyyy-MM-dd" );
const QString QgsDateTimeFieldFormatter::DEFAULT_TIME_FORMAT = QStringLiteral( "HH:mm:ss" );
const QString QgsDateTimeFieldFormatter::DEFAULT_DATETIME_FORMAT = QStringLiteral( "yyyy-MM-dd HH:mm:ss" );
const QString QgsDateTimeFieldFormatter::DATE_FORMAT = QStringLiteral( "yyyy-MM-dd" );
const QString QgsDateTimeFieldFormatter::TIME_FORMAT = QStringLiteral( "HH:mm:ss" );
const QString QgsDateTimeFieldFormatter::DATETIME_FORMAT = QStringLiteral( "yyyy-MM-dd HH:mm:ss" );
// we need to use Qt::ISODate rather than a string format definition in QDate::fromString
const QString QgsDateTimeFieldFormatter::QT_ISO_FORMAT = QStringLiteral( "Qt ISO Date" );
// but QDateTimeEdit::setDisplayFormat only accepts string formats, so use with time zone by default
const QString QgsDateTimeFieldFormatter::DISPLAY_FOR_ISO_FORMAT = QStringLiteral( "yyyy-MM-dd HH:mm:ss+t" );


QString QgsDateTimeFieldFormatter::id() const
Expand All @@ -37,15 +41,23 @@ QString QgsDateTimeFieldFormatter::representValue( QgsVectorLayer *layer, int fi

if ( value.isNull() )
{
QgsSettings settings;
return QgsApplication::nullRepresentation();
}

const QgsField field = layer->fields().at( fieldIndex );
const QString displayFormat = config.value( QStringLiteral( "display_format" ), defaultFormat( field.type() ) ).toString();
const bool fieldIsoFormat = config.value( QStringLiteral( "field_iso_format" ), false ).toBool();
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), defaultFormat( field.type() ) ).toString();
const QString displayFormat = config.value( QStringLiteral( "display_format" ), defaultFormat( field.type() ) ).toString();

QDateTime date = QDateTime::fromString( value.toString(), fieldFormat );
QDateTime date;
if ( fieldIsoFormat )
{
date = QDateTime::fromString( value.toString(), Qt::ISODate );
}
else
{
date = QDateTime::fromString( value.toString(), fieldFormat );
}

if ( date.isValid() )
{
Expand All @@ -64,12 +76,12 @@ QString QgsDateTimeFieldFormatter::defaultFormat( QVariant::Type type )
switch ( type )
{
case QVariant::DateTime:
return QgsDateTimeFieldFormatter::DEFAULT_DATETIME_FORMAT;
return QgsDateTimeFieldFormatter::DATETIME_FORMAT;
break;
case QVariant::Time:
return QgsDateTimeFieldFormatter::DEFAULT_TIME_FORMAT;
return QgsDateTimeFieldFormatter::TIME_FORMAT;
break;
default:
return QgsDateTimeFieldFormatter::DEFAULT_DATE_FORMAT;
return QgsDateTimeFieldFormatter::DATE_FORMAT;
}
}
8 changes: 5 additions & 3 deletions src/core/fieldformatter/qgsdatetimefieldformatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
class CORE_EXPORT QgsDateTimeFieldFormatter : public QgsFieldFormatter
{
public:
static const QString DEFAULT_DATE_FORMAT;
static const QString DEFAULT_TIME_FORMAT;
static const QString DEFAULT_DATETIME_FORMAT;
static const QString DATE_FORMAT;
static const QString TIME_FORMAT;
static const QString DATETIME_FORMAT;
static const QString QT_ISO_FORMAT;
static const QString DISPLAY_FOR_ISO_FORMAT;

/**
* Default constructor of field formatter for a date time field.
Expand Down
59 changes: 36 additions & 23 deletions src/gui/editorwidgets/qgsdatetimeeditconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ QgsDateTimeEditConfig::QgsDateTimeEditConfig( QgsVectorLayer *vl, int fieldIdx,
{
setupUi( this );

mFieldFormatComboBox->clear();
mFieldFormatComboBox->addItem( tr( "Date" ), QgsDateTimeFieldFormatter::DATE_FORMAT );
mFieldFormatComboBox->addItem( tr( "Time" ), QgsDateTimeFieldFormatter::TIME_FORMAT );
mFieldFormatComboBox->addItem( tr( "Date time" ), QgsDateTimeFieldFormatter::DATETIME_FORMAT );
mFieldFormatComboBox->addItem( tr( "ISO date time" ), QgsDateTimeFieldFormatter::QT_ISO_FORMAT );
mFieldFormatComboBox->addItem( tr( "Custom" ), QString() );

mDemoDateTimeEdit->setDateTime( QDateTime::currentDateTime() );

connect( mDisplayFormatEdit, &QLineEdit::textChanged, this, &QgsDateTimeEditConfig::updateDemoWidget );
Expand Down Expand Up @@ -55,21 +62,16 @@ void QgsDateTimeEditConfig::updateDemoWidget()

void QgsDateTimeEditConfig::updateFieldFormat( int idx )
{
if ( idx == 0 )
{
mFieldFormatEdit->setText( QgsDateTimeFieldFormatter::DEFAULT_DATE_FORMAT );
}
else if ( idx == 1 )
{
mFieldFormatEdit->setText( QgsDateTimeFieldFormatter::DEFAULT_TIME_FORMAT );
}
else if ( idx == 2 )
Q_UNUSED( idx );
const QString format = mFieldFormatComboBox->currentData().toString();
bool custom = format.isEmpty();
if ( !custom )
{
mFieldFormatEdit->setText( QgsDateTimeFieldFormatter::DEFAULT_DATETIME_FORMAT );
mFieldFormatEdit->setText( format );
}

mFieldFormatEdit->setVisible( idx == 3 );
mFieldHelpToolButton->setVisible( idx == 3 );
mFieldFormatEdit->setEnabled( custom );
mFieldHelpToolButton->setVisible( custom );
if ( mFieldHelpToolButton->isHidden() && mDisplayHelpToolButton->isHidden() )
{
mHelpScrollArea->setVisible( false );
Expand All @@ -81,20 +83,29 @@ void QgsDateTimeEditConfig::updateDisplayFormat( const QString &fieldFormat )
{
if ( mDisplayFormatComboBox->currentIndex() == 0 )
{
mDisplayFormatEdit->setText( fieldFormat );
// i.e. display format is default
if ( mFieldFormatComboBox->currentData() == QgsDateTimeFieldFormatter::QT_ISO_FORMAT )
{
mDisplayFormatEdit->setText( QgsDateTimeFieldFormatter::DISPLAY_FOR_ISO_FORMAT );
}
else
{
mDisplayFormatEdit->setText( fieldFormat );
}
}
}


void QgsDateTimeEditConfig::displayFormatChanged( int idx )
{
mDisplayFormatEdit->setEnabled( idx == 1 );
mDisplayHelpToolButton->setVisible( idx == 1 );
const bool custom = idx == 1;
mDisplayFormatEdit->setEnabled( custom );
mDisplayHelpToolButton->setVisible( custom );
if ( mFieldHelpToolButton->isHidden() && mDisplayHelpToolButton->isHidden() )
{
mHelpScrollArea->setVisible( false );
}
if ( idx == 0 )
if ( !custom )
{
mDisplayFormatEdit->setText( mFieldFormatEdit->text() );
}
Expand All @@ -112,6 +123,7 @@ QVariantMap QgsDateTimeEditConfig::config()
{
QVariantMap myConfig;

myConfig.insert( QStringLiteral( "field_iso_format" ), mFieldFormatEdit->text() == QgsDateTimeFieldFormatter::QT_ISO_FORMAT );
myConfig.insert( QStringLiteral( "field_format" ), mFieldFormatEdit->text() );
myConfig.insert( QStringLiteral( "display_format" ), mDisplayFormatEdit->text() );
myConfig.insert( QStringLiteral( "calendar_popup" ), mCalendarPopupCheckBox->isChecked() );
Expand All @@ -126,14 +138,15 @@ void QgsDateTimeEditConfig::setConfig( const QVariantMap &config )
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( fieldDef.type() ) ).toString();
mFieldFormatEdit->setText( fieldFormat );

if ( fieldFormat == QgsDateTimeFieldFormatter::DEFAULT_DATE_FORMAT )
mFieldFormatComboBox->setCurrentIndex( 0 );
else if ( fieldFormat == QgsDateTimeFieldFormatter::DEFAULT_TIME_FORMAT )
mFieldFormatComboBox->setCurrentIndex( 1 );
else if ( fieldFormat == QgsDateTimeFieldFormatter::DEFAULT_DATETIME_FORMAT )
mFieldFormatComboBox->setCurrentIndex( 2 );
const int idx = mFieldFormatComboBox->findData( fieldFormat );
if ( idx >= 0 )
{
mFieldFormatComboBox->setCurrentIndex( idx );
}
else
mFieldFormatComboBox->setCurrentIndex( 3 );
{
mFieldFormatComboBox->setCurrentIndex( 4 );
}

QString displayFormat = config.value( QStringLiteral( "display_format" ), QgsDateTimeFieldFormatter::defaultFormat( fieldDef.type() ) ).toString();
mDisplayFormatEdit->setText( displayFormat );
Expand Down
43 changes: 39 additions & 4 deletions src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,16 @@ void QgsDateTimeEditWrapper::showIndeterminateState()

void QgsDateTimeEditWrapper::dateTimeChanged( const QDateTime &dateTime )
{
const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
emit valueChanged( dateTime.toString( fieldFormat ) );
if ( fieldIsoFormat )
{
emit valueChanged( dateTime.toString( Qt::ISODate ) );
}
else
{
emit valueChanged( dateTime.toString( fieldFormat ) );
}
}

QVariant QgsDateTimeEditWrapper::value() const
Expand All @@ -135,15 +143,25 @@ QVariant QgsDateTimeEditWrapper::value() const
}
}

const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();

QDateTime date;
if ( mQgsDateTimeEdit )
{
return mQgsDateTimeEdit->dateTime().toString( fieldFormat );
date = mQgsDateTimeEdit->dateTime();
}
else
{
return mQDateTimeEdit->dateTime().toString( fieldFormat );
date = mQDateTimeEdit->dateTime();
}
if ( fieldIsoFormat )
{
return date.toString( Qt::ISODate );
}
else
{
return date.toString( fieldFormat );
}
}

Expand All @@ -152,8 +170,25 @@ void QgsDateTimeEditWrapper::setValue( const QVariant &value )
if ( !mQDateTimeEdit )
return;

const bool fieldIsoFormat = config( QStringLiteral( "field_iso_format" ), false ).toBool();
const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field().type() ) ).toString();
const QDateTime date = field().type() == QVariant::DateTime ? value.toDateTime() : QDateTime::fromString( value.toString(), fieldFormat );

QDateTime date;
if ( field().type() == QVariant::DateTime )
{
date = value.toDateTime();
}
else
{
if ( fieldIsoFormat )
{
date = QDateTime::fromString( value.toString(), Qt::ISODate );
}
else
{
date = QDateTime::fromString( value.toString(), fieldFormat );
}
}

if ( mQgsDateTimeEdit )
{
Expand Down
9 changes: 8 additions & 1 deletion src/gui/editorwidgets/qgsdatetimesearchwidgetwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ QVariant QgsDateTimeSearchWidgetWrapper::value() const
return QDateTime();

const QString fieldFormat = config( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( layer()->fields().at( mFieldIdx ).type() ) ).toString();
return mDateTimeEdit->dateTime().toString( fieldFormat );
if ( fieldFormat == QgsDateTimeFieldFormatter::QT_ISO_FORMAT )
{
return mDateTimeEdit->dateTime().toString( Qt::ISODate );
}
else
{
return mDateTimeEdit->dateTime().toString( fieldFormat );
}
}

QgsSearchWidgetWrapper::FilterFlags QgsDateTimeSearchWidgetWrapper::supportedFlags() const
Expand Down
39 changes: 16 additions & 23 deletions src/ui/editorwidgets/qgsdatetimeeditconfig.ui

Large diffs are not rendered by default.

0 comments on commit bdf744e

Please sign in to comment.