[FEATURE] Add a search widget wrapper for datetime widgets

This commit is contained in:
Nyall Dawson 2016-05-23 07:28:09 +10:00
parent 6d868598f5
commit 026e352cd9
10 changed files with 346 additions and 1 deletions

View File

@ -0,0 +1,32 @@
/**
* Wraps a date time search widget.
*/
class QgsDateTimeSearchWidgetWrapper : QgsSearchWidgetWrapper
{
%TypeHeaderCode
#include <qgsdatetimesearchwidgetwrapper.h>
%End
public:
public:
explicit QgsDateTimeSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* parent /TransferThis/ = nullptr );
bool applyDirectly();
QString expression();
bool valid() const;
QVariant value() const;
FilterFlags supportedFlags() const;
FilterFlags defaultFlags() const;
virtual QString createExpression( FilterFlags flags ) const;
public slots:
virtual void clearWidget();
virtual void setEnabled( bool enabled );
protected:
QWidget* createWidget( QWidget* parent );
void initWidget( QWidget* editor );
protected slots:
void setExpression( QString exp );
};

View File

@ -254,6 +254,7 @@
%Include editorwidgets/core/qgswidgetwrapper.sip
%Include editorwidgets/qgscheckboxsearchwidgetwrapper.sip
%Include editorwidgets/qgsdatetimeedit.sip
%Include editorwidgets/qgsdatetimesearchwidgetwrapper.sip
%Include editorwidgets/qgsdefaultsearchwidgetwrapper.sip
%Include editorwidgets/qgsdoublespinbox.sip
%Include editorwidgets/qgsmultiedittoolbutton.sip

View File

@ -105,6 +105,7 @@ SET(QGIS_GUI_SRCS
editorwidgets/qgsdatetimeeditfactory.cpp
editorwidgets/qgsdatetimeeditconfig.cpp
editorwidgets/qgsdatetimeeditwrapper.cpp
editorwidgets/qgsdatetimesearchwidgetwrapper.cpp
editorwidgets/qgsdefaultsearchwidgetwrapper.cpp
editorwidgets/qgsdoublespinbox.cpp
editorwidgets/qgsdummyconfigdlg.cpp
@ -530,6 +531,7 @@ SET(QGIS_GUI_MOC_HDRS
editorwidgets/qgscolorwidgetwrapper.h
editorwidgets/qgsdatetimeedit.h
editorwidgets/qgsdatetimeeditconfig.h
editorwidgets/qgsdatetimesearchwidgetwrapper.h
editorwidgets/qgsdatetimeeditwrapper.h
editorwidgets/qgsdefaultsearchwidgetwrapper.h
editorwidgets/qgsdoublespinbox.h

View File

@ -16,6 +16,7 @@
#include "qgsdatetimeeditfactory.h"
#include "qgsdatetimeeditconfig.h"
#include "qgsdatetimeeditwrapper.h"
#include "qgsdatetimesearchwidgetwrapper.h"
#include <QSettings>
@ -29,6 +30,11 @@ QgsEditorWidgetWrapper *QgsDateTimeEditFactory::create( QgsVectorLayer *vl, int
return new QgsDateTimeEditWrapper( vl, fieldIdx, editor, parent );
}
QgsSearchWidgetWrapper* QgsDateTimeEditFactory::createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const
{
return new QgsDateTimeSearchWidgetWrapper( vl, fieldIdx, parent );
}
QgsEditorConfigWidget *QgsDateTimeEditFactory::configWidget( QgsVectorLayer *vl, int fieldIdx, QWidget *parent ) const
{
return new QgsDateTimeEditConfig( vl, fieldIdx, parent );

View File

@ -34,6 +34,7 @@ class GUI_EXPORT QgsDateTimeEditFactory : public QgsEditorWidgetFactory
// QgsEditorWidgetFactory interface
public:
QgsEditorWidgetWrapper* create( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent ) const override;
QgsSearchWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
QgsEditorConfigWidget* configWidget( QgsVectorLayer *vl, int fieldIdx, QWidget *parent ) const override;
QgsEditorWidgetConfig readConfig( const QDomElement &configElement, QgsVectorLayer *layer, int fieldIdx ) override;
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;

View File

@ -101,6 +101,12 @@ bool QgsDateTimeEditWrapper::valid() const
return mQgsDateTimeEdit || mQDateTimeEdit;
}
void QgsDateTimeEditWrapper::showIndeterminateState()
{
if ( mQgsDateTimeEdit )
mQgsDateTimeEdit->setEmpty();
}
void QgsDateTimeEditWrapper::dateTimeChanged( const QDateTime& dateTime )
{
const QString fieldFormat = config( "field_format", QGSDATETIMEEDIT_DATEFORMAT ).toString();

View File

@ -55,6 +55,7 @@ class GUI_EXPORT QgsDateTimeEditWrapper : public QgsEditorWidgetWrapper
QWidget *createWidget( QWidget *parent ) override;
void initWidget( QWidget *editor ) override;
bool valid() const override;
virtual void showIndeterminateState() override;
public slots:
void setValue( const QVariant &value ) override;

View File

@ -0,0 +1,171 @@
/***************************************************************************
qgsdatetimesearchwidgetwrapper.cpp
---------------------------------
Date : 2016-05-23
Copyright : (C) 2016 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdatetimesearchwidgetwrapper.h"
#include "qgsfield.h"
#include "qgsdatetimeeditfactory.h"
#include "qgsvectorlayer.h"
#include "qgsdatetimeedit.h"
#include "qcalendarwidget.h"
#include <QSettings>
QgsDateTimeSearchWidgetWrapper::QgsDateTimeSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
: QgsSearchWidgetWrapper( vl, fieldIdx, parent )
, mDateTimeEdit( nullptr )
, mLayer( nullptr )
{
}
bool QgsDateTimeSearchWidgetWrapper::applyDirectly()
{
return true;
}
QString QgsDateTimeSearchWidgetWrapper::expression()
{
return mExpression;
}
QVariant QgsDateTimeSearchWidgetWrapper::value() const
{
if ( ! mDateTimeEdit )
return QDateTime();
const QString fieldFormat = config( "field_format", QGSDATETIMEEDIT_DATEFORMAT ).toString();
return mDateTimeEdit->dateTime().toString( fieldFormat );
}
QgsSearchWidgetWrapper::FilterFlags QgsDateTimeSearchWidgetWrapper::supportedFlags() const
{
return EqualTo | NotEqualTo | GreaterThan | LessThan | GreaterThanOrEqualTo | LessThanOrEqualTo | IsNull;
}
QgsSearchWidgetWrapper::FilterFlags QgsDateTimeSearchWidgetWrapper::defaultFlags() const
{
return EqualTo;
}
QString QgsDateTimeSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
{
QString fieldName = QgsExpression::quotedColumnRef( layer()->fields().at( mFieldIdx ).name() );
//clear any unsupported flags
flags &= supportedFlags();
if ( flags & IsNull )
return fieldName + " IS NULL";
QVariant v = value();
if ( !v.isValid() )
return QString();
if ( flags & EqualTo )
return fieldName + "='" + v.toString() + '\'';
else if ( flags & NotEqualTo )
return fieldName + "<>'" + v.toString() + '\'';
else if ( flags & GreaterThan )
return fieldName + ">'" + v.toString() + '\'';
else if ( flags & LessThan )
return fieldName + "<'" + v.toString() + '\'';
else if ( flags & GreaterThanOrEqualTo )
return fieldName + ">='" + v.toString() + '\'';
else if ( flags & LessThanOrEqualTo )
return fieldName + "<='" + v.toString() + '\'';
return QString();
}
void QgsDateTimeSearchWidgetWrapper::clearWidget()
{
if ( mDateTimeEdit )
{
mDateTimeEdit->setEmpty();
}
}
void QgsDateTimeSearchWidgetWrapper::setEnabled( bool enabled )
{
if ( mDateTimeEdit )
{
mDateTimeEdit->setEnabled( enabled );
}
}
bool QgsDateTimeSearchWidgetWrapper::valid() const
{
return true;
}
void QgsDateTimeSearchWidgetWrapper::setExpression( QString exp )
{
QString fieldName = layer()->fields().at( mFieldIdx ).name();
QString str = QString( "%1 = '%3'" )
.arg( QgsExpression::quotedColumnRef( fieldName ),
exp.replace( '\'', "''" )
);
mExpression = str;
}
void QgsDateTimeSearchWidgetWrapper::dateTimeChanged( const QDateTime& dt )
{
if ( mDateTimeEdit )
{
QString exp = value().toString();
setExpression( exp );
if ( dt.isValid() && !dt.isNull() )
emit valueChanged();
else
emit valueCleared();
emit expressionChanged( mExpression );
}
}
QWidget* QgsDateTimeSearchWidgetWrapper::createWidget( QWidget* parent )
{
QgsDateTimeEdit* widget = new QgsDateTimeEdit( parent );
widget->setEmpty();
return widget;
}
void QgsDateTimeSearchWidgetWrapper::initWidget( QWidget* editor )
{
mDateTimeEdit = qobject_cast<QgsDateTimeEdit*>( editor );
if ( mDateTimeEdit )
{
mDateTimeEdit->setAllowNull( false );
const QString displayFormat = config( "display_format", QGSDATETIMEEDIT_DATEFORMAT ).toString();
mDateTimeEdit->setDisplayFormat( displayFormat );
const bool calendar = config( "calendar_popup", false ).toBool();
mDateTimeEdit->setCalendarPopup( calendar );
if ( calendar )
{
// highlight today's date
QTextCharFormat todayFormat;
todayFormat.setBackground( QColor( 160, 180, 200 ) );
mDateTimeEdit->calendarWidget()->setDateTextFormat( QDate::currentDate(), todayFormat );
}
mDateTimeEdit->setEmpty();
connect( mDateTimeEdit, SIGNAL( dateTimeChanged( QDateTime ) ), this, SLOT( dateTimeChanged( QDateTime ) ) );
}
}

View File

@ -0,0 +1,67 @@
/***************************************************************************
qgsdatetimesearchwidgetwrapper.h
-------------------------------
Date : 2016-05-23
Copyright : (C) 2016 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDATETIMESEARCHWIDGETWRAPPER_H
#define QGSDATETIMESEARCHWIDGETWRAPPER_H
#include "qgssearchwidgetwrapper.h"
#include "qgsdatetimeeditwrapper.h"
#include <QComboBox>
#include <QListWidget>
#include <QLineEdit>
class QgsDateTimeEditFactory;
/**
* Wraps a date time search widget.
*/
class GUI_EXPORT QgsDateTimeSearchWidgetWrapper : public QgsSearchWidgetWrapper
{
Q_OBJECT
public:
explicit QgsDateTimeSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* parent = nullptr );
bool applyDirectly() override;
QString expression() override;
bool valid() const override;
QVariant value() const;
FilterFlags supportedFlags() const override;
FilterFlags defaultFlags() const override;
virtual QString createExpression( FilterFlags flags ) const override;
public slots:
virtual void clearWidget() override;
virtual void setEnabled( bool enabled ) override;
protected:
QWidget* createWidget( QWidget* parent ) override;
void initWidget( QWidget* editor ) override;
protected slots:
void setExpression( QString exp ) override;
private slots:
void dateTimeChanged( const QDateTime &date );
private:
QgsDateTimeEdit* mDateTimeEdit;
QgsVectorLayer* mLayer;
friend class QgsDateTimeEditFactory;
};
#endif // QGSDATETIMESEARCHWIDGETWRAPPER_H

View File

@ -18,11 +18,13 @@ from qgis.gui import (QgsSearchWidgetWrapper,
QgsDefaultSearchWidgetWrapper,
QgsValueMapSearchWidgetWrapper,
QgsValueRelationSearchWidgetWrapper,
QgsCheckboxSearchWidgetWrapper)
QgsCheckboxSearchWidgetWrapper,
QgsDateTimeSearchWidgetWrapper)
from qgis.core import (QgsVectorLayer,
QgsFeature,
QgsMapLayerRegistry,
)
from qgis.PyQt.QtCore import QDateTime, QDate, QTime
from qgis.PyQt.QtWidgets import QWidget
from qgis.testing import start_app, unittest
@ -259,5 +261,61 @@ class PyQgsCheckboxSearchWidgetWrapper(unittest.TestCase):
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=9')
class PyQgsDateTimeSearchWidgetWrapper(unittest.TestCase):
def testCreateExpression(self):
""" Test creating an expression using the widget"""
layer = QgsVectorLayer("Point?field=date:date&field=time:time&field=datetime:datetime", "test", "memory")
w = QgsDateTimeSearchWidgetWrapper(layer, 0)
config = {"field_format": 'yyyy-MM-dd',
"display_format": 'yyyy-MM-dd'}
w.setConfig(config)
c = w.widget()
# first check with date field type
c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime()))
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"date" IS NULL')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"date"=\'2013-04-05\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"date"<>\'2013-04-05\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThan), '"date">\'2013-04-05\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThan), '"date"<\'2013-04-05\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo), '"date">=\'2013-04-05\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo), '"date"<=\'2013-04-05\'')
# time field type
w = QgsDateTimeSearchWidgetWrapper(layer, 1)
config = {"field_format": 'HH:mm:ss',
"display_format": 'HH:mm:ss'}
w.setConfig(config)
c = w.widget()
c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime(13, 14, 15)))
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"time" IS NULL')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"time"=\'13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"time"<>\'13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThan), '"time">\'13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThan), '"time"<\'13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo), '"time">=\'13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo), '"time"<=\'13:14:15\'')
# datetime field type
w = QgsDateTimeSearchWidgetWrapper(layer, 2)
config = {"field_format": 'yyyy-MM-dd HH:mm:ss',
"display_format": 'yyyy-MM-dd HH:mm:ss'}
w.setConfig(config)
c = w.widget()
c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime(13, 14, 15)))
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"datetime" IS NULL')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"datetime"=\'2013-04-05 13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"datetime"<>\'2013-04-05 13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThan), '"datetime">\'2013-04-05 13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThan), '"datetime"<\'2013-04-05 13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo), '"datetime">=\'2013-04-05 13:14:15\'')
self.assertEquals(w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo), '"datetime"<=\'2013-04-05 13:14:15\'')
if __name__ == '__main__':
unittest.main()