Skip to content

Commit

Permalink
Add an editor widget for QVariantList
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Valsecchi committed Sep 13, 2016
1 parent abc55f4 commit 57d0094
Show file tree
Hide file tree
Showing 33 changed files with 941 additions and 81 deletions.
10 changes: 8 additions & 2 deletions python/core/qgsfield.sip
Expand Up @@ -24,7 +24,9 @@ class QgsField
* @param prec Field precision. Usually decimal places but may also be
* used in conjunction with other fields types (eg. variable character fields)
* @param comment Comment for the field
* @param subType If the field is a collection, its element's type.
* @param subType If the field is a collection, its element's type. When
* all the elements don't need to have the same type, leave
* this to QVariant::Invalid.
*/
QgsField( const QString& name = QString(),
QVariant::Type type = QVariant::Invalid,
Expand Down Expand Up @@ -62,7 +64,9 @@ class QgsField
QVariant::Type type() const;

/**
* If the field is a collection, gets its element's type
* If the field is a collection, gets its element's type.
* When all the elements don't need to have the same type, this returns
* QVariant::Invalid.
* @note added in QGIS 3.0
*/
QVariant::Type subType() const;
Expand Down Expand Up @@ -113,6 +117,8 @@ class QgsField

/**
* If the field is a collection, set its element's type.
* When all the elements don't need to have the same type, set this to
* QVariant::Invalid.
* @note added in QGIS 3.0
*/
void setSubType( QVariant::Type subType );
Expand Down
3 changes: 2 additions & 1 deletion python/core/qgsvectordataprovider.sip
Expand Up @@ -302,7 +302,7 @@ class QgsVectorDataProvider : QgsDataProvider

struct NativeType
{
NativeType( const QString& typeDesc, const QString& typeName, QVariant::Type type, int minLen = 0, int maxLen = 0, int minPrec = 0, int maxPrec = 0 );
NativeType( const QString& typeDesc, const QString& typeName, QVariant::Type type, int minLen = 0, int maxLen = 0, int minPrec = 0, int maxPrec = 0, QVariant::Type subType = QVariant::Invalid );

QString mTypeDesc;
QString mTypeName;
Expand All @@ -311,6 +311,7 @@ class QgsVectorDataProvider : QgsDataProvider
int mMaxLen;
int mMinPrec;
int mMaxPrec;
QVariant::Type mSubType;
};

/**
Expand Down
7 changes: 7 additions & 0 deletions python/gui/editorwidgets/core/qgseditorwidgetwrapper.sip
Expand Up @@ -75,6 +75,13 @@ class QgsEditorWidgetWrapper : QgsWidgetWrapper
*/
static QgsEditorWidgetWrapper* fromWidget( QWidget* widget );

/**
* Check if the given widget or one of its parent is a QTableView.
* @param parent the widget to check
* @return true if yes
*/
static bool isInTable( const QWidget* parent );

/**
* Is used to enable or disable the edit functionality of the managed widget.
* By default this will enable or disable the whole widget
Expand Down
2 changes: 2 additions & 0 deletions python/gui/gui.sip
Expand Up @@ -96,6 +96,7 @@
%Include qgshtmlannotationitem.sip
%Include qgsidentifymenu.sip
%Include qgskeyvaluewidget.sip
%Include qgslistwidget.sip
%Include qgslegendfilterbutton.sip
%Include qgslegendinterface.sip
%Include qgslimitedrandomcolorrampdialog.sip
Expand Down Expand Up @@ -161,6 +162,7 @@
%Include qgssourceselectdialog.sip
%Include qgssublayersdialog.sip
%Include qgssvgannotationitem.sip
%Include qgstablewidgetbase.sip
%Include qgstabwidget.sip
%Include qgstablewidgetitem.sip
%Include qgstextannotationitem.sip
Expand Down
2 changes: 1 addition & 1 deletion python/gui/qgskeyvaluewidget.sip
Expand Up @@ -2,7 +2,7 @@
* Widget allowing to edit a QVariantMap, using a table.
* @note added in QGIS 3.0
*/
class QgsKeyValueWidget : public QWidget
class QgsKeyValueWidget : public QgsTableWidgetBase
{
%TypeHeaderCode
#include "qgskeyvaluewidget.h"
Expand Down
32 changes: 32 additions & 0 deletions python/gui/qgslistwidget.sip
@@ -0,0 +1,32 @@
/** \ingroup gui
* Widget allowing to edit a QVariantList, using a table.
* @note added in QGIS 3.0
*/
class QgsListWidget : public QgsTableWidgetBase
{
%TypeHeaderCode
#include "qgslistwidget.h"
%End
public:
/**
* Constructor.
*/
explicit QgsListWidget( QVariant::Type subType, QWidget* parent = nullptr );

/**
* Set the initial value of the widget.
*/
void setList( const QVariantList& list );

/**
* Get the edit value.
* @return the QVariantList
*/
QVariantList list() const;

/**
* Check the content is valid
* @return true if valid
*/
bool valid() const;
};
28 changes: 28 additions & 0 deletions python/gui/qgstablewidgetbase.sip
@@ -0,0 +1,28 @@
/** \ingroup gui
* Base widget allowing to edit a collection, using a table.
* @note added in QGIS 3.0
*/
class QgsTableWidgetBase: public QWidget
{
%TypeHeaderCode
#include "qgstablewidgetbase.h"
%End
public:
/**
* Constructor.
*/
explicit QgsTableWidgetBase( QWidget* parent );

protected:
/**
* Initialise the table with the given model.
* Must be called once in the child class' constructor.
*/
void init( QAbstractTableModel* model );

signals:
/**
* Emitted each time a key or a value is changed.
*/
void valueChanged();
};
1 change: 1 addition & 0 deletions src/app/qgsfieldcalculator.cpp
Expand Up @@ -346,6 +346,7 @@ void QgsFieldCalculator::populateOutputFieldTypes()
mOutputFieldTypeComboBox->setItemData( i, typelist[i].mMaxLen, Qt::UserRole + 3 );
mOutputFieldTypeComboBox->setItemData( i, typelist[i].mMinPrec, Qt::UserRole + 4 );
mOutputFieldTypeComboBox->setItemData( i, typelist[i].mMaxPrec, Qt::UserRole + 5 );
mOutputFieldTypeComboBox->setItemData( i, static_cast<int>( typelist[i].mSubType ), Qt::UserRole + 6 );
}
mOutputFieldTypeComboBox->blockSignals( false );
mOutputFieldTypeComboBox->setCurrentIndex( 0 );
Expand Down
5 changes: 4 additions & 1 deletion src/app/qgsfieldcalculator.h
Expand Up @@ -67,7 +67,10 @@ class APP_EXPORT QgsFieldCalculator: public QDialog, private Ui::QgsFieldCalcula
static_cast< QVariant::Type >( mOutputFieldTypeComboBox->itemData( mOutputFieldTypeComboBox->currentIndex(), Qt::UserRole ).toInt() ),
mOutputFieldTypeComboBox->itemData( mOutputFieldTypeComboBox->currentIndex(), Qt::UserRole + 1 ).toString(),
mOutputFieldWidthSpinBox->value(),
mOutputFieldPrecisionSpinBox->value() );
mOutputFieldPrecisionSpinBox->value(),
QString(),
static_cast< QVariant::Type >( mOutputFieldTypeComboBox->itemData( mOutputFieldTypeComboBox->currentIndex(), Qt::UserRole + 6 ).toInt() )
);
}

/** Idx of changed attribute*/
Expand Down
10 changes: 8 additions & 2 deletions src/core/qgsfield.h
Expand Up @@ -66,7 +66,9 @@ class CORE_EXPORT QgsField
* @param prec Field precision. Usually decimal places but may also be
* used in conjunction with other fields types (eg. variable character fields)
* @param comment Comment for the field
* @param subType If the field is a collection, its element's type
* @param subType If the field is a collection, its element's type. When
* all the elements don't need to have the same type, leave
* this to QVariant::Invalid.
*/
QgsField( const QString& name = QString(),
QVariant::Type type = QVariant::Invalid,
Expand Down Expand Up @@ -108,7 +110,9 @@ class CORE_EXPORT QgsField
QVariant::Type type() const;

/**
* If the field is a collection, gets its element's type
* If the field is a collection, gets its element's type.
* When all the elements don't need to have the same type, this returns
* QVariant::Invalid.
* @note added in QGIS 3.0
*/
QVariant::Type subType() const;
Expand Down Expand Up @@ -159,6 +163,8 @@ class CORE_EXPORT QgsField

/**
* If the field is a collection, set its element's type.
* When all the elements don't need to have the same type, set this to
* QVariant::Invalid.
* @note added in QGIS 3.0
*/
void setSubType( QVariant::Type subType );
Expand Down
4 changes: 3 additions & 1 deletion src/core/qgsvectordataprovider.h
Expand Up @@ -352,14 +352,15 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider

struct NativeType
{
NativeType( const QString& typeDesc, const QString& typeName, QVariant::Type type, int minLen = 0, int maxLen = 0, int minPrec = 0, int maxPrec = 0 )
NativeType( const QString& typeDesc, const QString& typeName, QVariant::Type type, int minLen = 0, int maxLen = 0, int minPrec = 0, int maxPrec = 0, QVariant::Type subType = QVariant::Invalid )
: mTypeDesc( typeDesc )
, mTypeName( typeName )
, mType( type )
, mMinLen( minLen )
, mMaxLen( maxLen )
, mMinPrec( minPrec )
, mMaxPrec( maxPrec )
, mSubType( subType )
{}

QString mTypeDesc;
Expand All @@ -369,6 +370,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
int mMaxLen;
int mMinPrec;
int mMaxPrec;
QVariant::Type mSubType;
};

/**
Expand Down
10 changes: 9 additions & 1 deletion src/gui/CMakeLists.txt
Expand Up @@ -118,6 +118,8 @@ SET(QGIS_GUI_SRCS
editorwidgets/qgshiddenwidgetfactory.cpp
editorwidgets/qgskeyvaluewidgetfactory.cpp
editorwidgets/qgskeyvaluewidgetwrapper.cpp
editorwidgets/qgslistwidgetfactory.cpp
editorwidgets/qgslistwidgetwrapper.cpp
editorwidgets/qgsmultiedittoolbutton.cpp
editorwidgets/qgsphotoconfigdlg.cpp
editorwidgets/qgsphotowidgetwrapper.cpp
Expand Down Expand Up @@ -234,6 +236,7 @@ SET(QGIS_GUI_SRCS
qgshtmlannotationitem.cpp
qgsidentifymenu.cpp
qgskeyvaluewidget.cpp
qgslistwidget.cpp
qgslegendfilterbutton.cpp
qgslegendinterface.cpp
qgslimitedrandomcolorrampdialog.cpp
Expand Down Expand Up @@ -299,6 +302,7 @@ SET(QGIS_GUI_SRCS
qgssublayersdialog.cpp
qgssqlcomposerdialog.cpp
qgssvgannotationitem.cpp
qgstablewidgetbase.cpp
qgstabwidget.cpp
qgstablewidgetitem.cpp
qgstextannotationitem.cpp
Expand Down Expand Up @@ -393,6 +397,7 @@ SET(QGIS_GUI_MOC_HDRS
qgshtmlannotationitem.h
qgsidentifymenu.h
qgskeyvaluewidget.h
qgslistwidget.h
qgslegendfilterbutton.h
qgslegendinterface.h
qgslimitedrandomcolorrampdialog.h
Expand Down Expand Up @@ -452,6 +457,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsslider.h
qgssqlcomposerdialog.h
qgssublayersdialog.h
qgstablewidgetbase.h
qgstabwidget.h
qgstreewidgetitem.h
qgsunitselectionwidget.h
Expand Down Expand Up @@ -568,6 +574,7 @@ SET(QGIS_GUI_MOC_HDRS
editorwidgets/qgsfilenamewidgetwrapper.h
editorwidgets/qgshiddenwidgetwrapper.h
editorwidgets/qgskeyvaluewidgetwrapper.h
editorwidgets/qgslistwidgetwrapper.h
editorwidgets/qgsmultiedittoolbutton.h
editorwidgets/qgsphotoconfigdlg.h
editorwidgets/qgsphotowidgetwrapper.h
Expand Down Expand Up @@ -684,6 +691,7 @@ SET(QGIS_GUI_HDRS
editorwidgets/qgsfilenamewidgetfactory.h
editorwidgets/qgshiddenwidgetfactory.h
editorwidgets/qgskeyvaluewidgetfactory.h
editorwidgets/qgslistwidgetfactory.h
editorwidgets/qgsphotowidgetfactory.h
editorwidgets/qgsrangewidgetfactory.h
editorwidgets/qgsrelationreferencefactory.h
Expand Down Expand Up @@ -739,14 +747,14 @@ SET(QGIS_GUI_UI_HDRS
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionbuilder.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionselectiondialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsgenericprojectionselectorbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgskeyvaluewidgetbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmessagelogviewer.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmessageviewer.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsowssourceselectbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsprojectionselectorbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsquerybuilderbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgssqlcomposerdialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgssublayersdialogbase.h
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgstablewidgetbase.h
)

IF(ENABLE_MODELTEST)
Expand Down
2 changes: 2 additions & 0 deletions src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
Expand Up @@ -33,6 +33,7 @@
#include "qgsfilenamewidgetfactory.h"
#include "qgshiddenwidgetfactory.h"
#include "qgskeyvaluewidgetfactory.h"
#include "qgslistwidgetfactory.h"
#include "qgsphotowidgetfactory.h"
#include "qgsrangewidgetfactory.h"
#include "qgsrelationreferencefactory.h"
Expand Down Expand Up @@ -75,6 +76,7 @@ void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBa
reg->registerWidget( "DateTime", new QgsDateTimeEditFactory( tr( "Date/Time" ) ) );
reg->registerWidget( "ExternalResource", new QgsExternalResourceWidgetFactory( tr( "External Resource" ) ) );
reg->registerWidget( "KeyValue", new QgsKeyValueWidgetFactory( tr( "Key/Value" ) ) );
reg->registerWidget( "List", new QgsListWidgetFactory( tr( "List" ) ) );
}

QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()
Expand Down
9 changes: 8 additions & 1 deletion src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
Expand Up @@ -18,7 +18,7 @@
#include "qgsvectordataprovider.h"
#include "qgsfield.h"

#include <QWidget>
#include <QTableView>

QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
: QgsWidgetWrapper( vl, editor, parent )
Expand Down Expand Up @@ -169,3 +169,10 @@ bool QgsEditorWidgetWrapper::isValidConstraint() const
{
return mValidConstraint;
}

bool QgsEditorWidgetWrapper::isInTable( const QWidget* parent )
{
if ( !parent ) return false;
if ( qobject_cast<const QTableView*>( parent ) ) return true;
return isInTable( parent->parentWidget() );
}
7 changes: 7 additions & 0 deletions src/gui/editorwidgets/core/qgseditorwidgetwrapper.h
Expand Up @@ -95,6 +95,13 @@ class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
*/
static QgsEditorWidgetWrapper* fromWidget( QWidget* widget );

/**
* Check if the given widget or one of its parent is a QTableView.
* @param parent the widget to check
* @return true if yes
*/
static bool isInTable( const QWidget* parent );

/**
* Is used to enable or disable the edit functionality of the managed widget.
* By default this will enable or disable the whole widget
Expand Down
16 changes: 7 additions & 9 deletions src/gui/editorwidgets/qgskeyvaluewidgetwrapper.cpp
Expand Up @@ -33,13 +33,6 @@ void QgsKeyValueWidgetWrapper::showIndeterminateState()
mWidget->setMap( QVariantMap() );
}

static bool isInTable( const QWidget* parent )
{
if ( !parent ) return false;
if ( qobject_cast<const QTableView*>( parent ) ) return true;
return isInTable( parent->parentWidget() );
}

QWidget* QgsKeyValueWidgetWrapper::createWidget( QWidget* parent )
{
if ( isInTable( parent ) )
Expand All @@ -66,7 +59,7 @@ void QgsKeyValueWidgetWrapper::initWidget( QWidget* editor )
mWidget = editor->findChild<QgsKeyValueWidget*>();
}

connect( mWidget, SIGNAL( valueChanged( const QVariant& ) ), this, SIGNAL( valueChanged( const QVariant& ) ) );
connect( mWidget, SIGNAL( valueChanged() ), this, SLOT( onValueChanged() ) );
}

bool QgsKeyValueWidgetWrapper::valid() const
Expand All @@ -82,4 +75,9 @@ void QgsKeyValueWidgetWrapper::setValue( const QVariant& value )
void QgsKeyValueWidgetWrapper::updateConstraintWidgetStatus( bool /*constraintValid*/ )
{
// Nothing
}
}

void QgsKeyValueWidgetWrapper::onValueChanged()
{
emit valueChanged( value() );
}
3 changes: 3 additions & 0 deletions src/gui/editorwidgets/qgskeyvaluewidgetwrapper.h
Expand Up @@ -47,6 +47,9 @@ class GUI_EXPORT QgsKeyValueWidgetWrapper : public QgsEditorWidgetWrapper
public slots:
void setValue( const QVariant& value ) override;

private slots:
void onValueChanged();

private:
void updateConstraintWidgetStatus( bool constraintValid ) override;

Expand Down

0 comments on commit 57d0094

Please sign in to comment.