Skip to content

Commit

Permalink
Merge pull request #3459 from pvalsecc/hstore
Browse files Browse the repository at this point in the history
[FEATURE] hstore
  • Loading branch information
m-kuhn committed Sep 8, 2016
2 parents 74cceb4 + e533f0c commit a90217d
Show file tree
Hide file tree
Showing 30 changed files with 1,069 additions and 19 deletions.
1 change: 1 addition & 0 deletions python/gui/gui.sip
Expand Up @@ -95,6 +95,7 @@
%Include qgshistogramwidget.sip
%Include qgshtmlannotationitem.sip
%Include qgsidentifymenu.sip
%Include qgskeyvaluewidget.sip
%Include qgslegendfilterbutton.sip
%Include qgslegendinterface.sip
%Include qgslimitedrandomcolorrampdialog.sip
Expand Down
32 changes: 32 additions & 0 deletions python/gui/qgskeyvaluewidget.sip
@@ -0,0 +1,32 @@
/** \ingroup gui
* Widget allowing to edit a QVariantMap, using a table.
* @note added in QGIS 3.0
*/
class QgsKeyValueWidget : public QWidget
{
%TypeHeaderCode
#include "qgskeyvaluewidget.h"
%End
public:
/**
* Constructor.
*/
explicit QgsKeyValueWidget( QWidget* parent /TransferThis/ = 0 );

/**
* Set the initial value of the widget.
*/
void setMap( const QVariantMap& map );

/**
* Get the edit value.
* @return the QVariantMap
*/
QVariantMap map() const;

signals:
/**
* Emitted each time a key or a value is changed.
*/
void valueChanged();
};
22 changes: 20 additions & 2 deletions src/core/qgsexpression.cpp
Expand Up @@ -4978,6 +4978,8 @@ QString QgsExpression::group( const QString& name )

QString QgsExpression::formatPreviewString( const QVariant& value )
{
static const int MAX_PREVIEW = 60;

if ( value.canConvert<QgsGeometry>() )
{
//result is a geometry
Expand Down Expand Up @@ -5017,15 +5019,31 @@ QString QgsExpression::formatPreviewString( const QVariant& value )
else if ( value.type() == QVariant::String )
{
QString previewString = value.toString();
if ( previewString.length() > 63 )
if ( previewString.length() > MAX_PREVIEW + 3 )
{
return QString( tr( "'%1...'" ) ).arg( previewString.left( 60 ) );
return QString( tr( "'%1...'" ) ).arg( previewString.left( MAX_PREVIEW ) );
}
else
{
return previewString.prepend( '\'' ).append( '\'' );
}
}
else if ( value.type() == QVariant::Map )
{
QString mapStr;
const QVariantMap map = value.toMap();
for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
{
if ( !mapStr.isEmpty() ) mapStr.append( ", " );
mapStr.append( it.key() ).append( ": " ).append( formatPreviewString( it.value() ) );
if ( mapStr.length() > MAX_PREVIEW + 3 )
{
mapStr = QString( tr( "%1..." ) ).arg( mapStr.left( MAX_PREVIEW ) );
break;
}
}
return tr( "<i>&lt;map: %1&gt;</i>" ).arg( mapStr );
}
else
{
return value.toString();
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2231,7 +2231,10 @@ bool QgsVectorLayer::deleteFeature( QgsFeatureId fid )
bool QgsVectorLayer::deleteFeatures( const QgsFeatureIds& fids )
{
if ( !mEditBuffer )
{
QgsDebugMsg( "Cannot delete features (mEditBuffer==NULL)" );
return false;
}

bool res = mEditBuffer->deleteFeatures( fids );

Expand Down
18 changes: 15 additions & 3 deletions src/core/qgsvectorlayereditbuffer.cpp
Expand Up @@ -20,7 +20,6 @@
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"


//! populate two lists (ks, vs) from map - in reverse order
template <class Key, class T> void mapToReversedLists( const QMap< Key, T >& map, QList<Key>& ks, QList<T>& vs )
{
Expand Down Expand Up @@ -150,17 +149,26 @@ bool QgsVectorLayerEditBuffer::addFeatures( QgsFeatureList& features )
bool QgsVectorLayerEditBuffer::deleteFeature( QgsFeatureId fid )
{
if ( !( L->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
{
QgsDebugMsg( "Cannot delete features (missing DeleteFeature capability)" );
return false;
}

if ( FID_IS_NEW( fid ) )
{
if ( !mAddedFeatures.contains( fid ) )
{
QgsDebugMsg( "Cannot delete features (in the list of added features)" );
return false;
}
}
else // existing feature
{
if ( mDeletedFeatureIds.contains( fid ) )
{
QgsDebugMsg( "Cannot delete features (in the list of deleted features)" );
return false;
}
}

L->undoStack()->push( new QgsVectorLayerUndoCommandDeleteFeature( this, fid ) );
Expand All @@ -170,12 +178,16 @@ bool QgsVectorLayerEditBuffer::deleteFeature( QgsFeatureId fid )
bool QgsVectorLayerEditBuffer::deleteFeatures( const QgsFeatureIds& fids )
{
if ( !( L->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
{
QgsDebugMsg( "Cannot delete features (missing DeleteFeatures capability)" );
return false;
}

bool ok = true;
Q_FOREACH ( QgsFeatureId fid, fids )
deleteFeature( fid );
ok = deleteFeature( fid ) && ok;

return true;
return ok;
}


Expand Down
7 changes: 7 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -116,6 +116,8 @@ SET(QGIS_GUI_SRCS
editorwidgets/qgsfilenamewidgetfactory.cpp
editorwidgets/qgshiddenwidgetwrapper.cpp
editorwidgets/qgshiddenwidgetfactory.cpp
editorwidgets/qgskeyvaluewidgetfactory.cpp
editorwidgets/qgskeyvaluewidgetwrapper.cpp
editorwidgets/qgsmultiedittoolbutton.cpp
editorwidgets/qgsphotoconfigdlg.cpp
editorwidgets/qgsphotowidgetwrapper.cpp
Expand Down Expand Up @@ -231,6 +233,7 @@ SET(QGIS_GUI_SRCS
qgshistogramwidget.cpp
qgshtmlannotationitem.cpp
qgsidentifymenu.cpp
qgskeyvaluewidget.cpp
qgslegendfilterbutton.cpp
qgslegendinterface.cpp
qgslimitedrandomcolorrampdialog.cpp
Expand Down Expand Up @@ -388,6 +391,7 @@ SET(QGIS_GUI_MOC_HDRS
qgshistogramwidget.h
qgshtmlannotationitem.h
qgsidentifymenu.h
qgskeyvaluewidget.h
qgslegendfilterbutton.h
qgslegendinterface.h
qgslimitedrandomcolorrampdialog.h
Expand Down Expand Up @@ -561,6 +565,7 @@ SET(QGIS_GUI_MOC_HDRS
editorwidgets/qgsexternalresourcewidgetwrapper.h
editorwidgets/qgsfilenamewidgetwrapper.h
editorwidgets/qgshiddenwidgetwrapper.h
editorwidgets/qgskeyvaluewidgetwrapper.h
editorwidgets/qgsmultiedittoolbutton.h
editorwidgets/qgsphotoconfigdlg.h
editorwidgets/qgsphotowidgetwrapper.h
Expand Down Expand Up @@ -676,6 +681,7 @@ SET(QGIS_GUI_HDRS
editorwidgets/qgsexternalresourcewidgetfactory.h
editorwidgets/qgsfilenamewidgetfactory.h
editorwidgets/qgshiddenwidgetfactory.h
editorwidgets/qgskeyvaluewidgetfactory.h
editorwidgets/qgsphotowidgetfactory.h
editorwidgets/qgsrangewidgetfactory.h
editorwidgets/qgsrelationreferencefactory.h
Expand Down Expand Up @@ -731,6 +737,7 @@ 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
Expand Down
1 change: 1 addition & 0 deletions src/gui/attributetable/qgsattributetabledelegate.cpp
Expand Up @@ -72,6 +72,7 @@ QWidget* QgsAttributeTableDelegate::createEditor( QWidget *parent, const QStyleO
QWidget* w = eww->widget();

w->setAutoFillBackground( true );
w->setFocusPolicy( Qt::StrongFocus ); // to make sure QMouseEvents are propagated to the editor widget

eww->setEnabled( !vl->editFormConfig().readOnly( fieldIdx ) );

Expand Down
2 changes: 2 additions & 0 deletions src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
Expand Up @@ -32,6 +32,7 @@
#include "qgsexternalresourcewidgetfactory.h"
#include "qgsfilenamewidgetfactory.h"
#include "qgshiddenwidgetfactory.h"
#include "qgskeyvaluewidgetfactory.h"
#include "qgsphotowidgetfactory.h"
#include "qgsrangewidgetfactory.h"
#include "qgsrelationreferencefactory.h"
Expand Down Expand Up @@ -73,6 +74,7 @@ void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBa
reg->registerWidget( "RelationReference", new QgsRelationReferenceFactory( tr( "Relation Reference" ), mapCanvas, messageBar ) );
reg->registerWidget( "DateTime", new QgsDateTimeEditFactory( tr( "Date/Time" ) ) );
reg->registerWidget( "ExternalResource", new QgsExternalResourceWidgetFactory( tr( "External Resource" ) ) );
reg->registerWidget( "KeyValue", new QgsKeyValueWidgetFactory( tr( "Key/Value" ) ) );
}

QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()
Expand Down
2 changes: 1 addition & 1 deletion src/gui/editorwidgets/qgshiddenwidgetwrapper.cpp
Expand Up @@ -18,7 +18,7 @@
#include <QWidget>

QgsHiddenWidgetWrapper::QgsHiddenWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
{
}

Expand Down
96 changes: 96 additions & 0 deletions src/gui/editorwidgets/qgskeyvaluewidgetfactory.cpp
@@ -0,0 +1,96 @@
/***************************************************************************
qgskeyvaluewidgetfactory.cpp
--------------------------------------
Date : 08.2016
Copyright : (C) 2016 Patrick Valsecchi
Email : patrick.valsecchi@camptocamp.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 "qgskeyvaluewidgetfactory.h"
#include "qgskeyvaluewidgetwrapper.h"
#include "qgsdummyconfigdlg.h"
#include "qgsfield.h"
#include "qgsvectorlayer.h"

#include <QVariant>
#include <QSettings>

QgsKeyValueWidgetFactory::QgsKeyValueWidgetFactory( const QString& name ):
QgsEditorWidgetFactory( name )
{
}

QgsEditorWidgetWrapper* QgsKeyValueWidgetFactory::create( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent ) const
{
return new QgsKeyValueWidgetWrapper( vl, fieldIdx, editor, parent );
}

QgsEditorConfigWidget* QgsKeyValueWidgetFactory::configWidget( QgsVectorLayer *vl, int fieldIdx, QWidget *parent ) const
{
Q_UNUSED( vl );
Q_UNUSED( fieldIdx );
Q_UNUSED( parent );
return new QgsDummyConfigDlg( vl, fieldIdx, parent, QObject::tr( "Key/Value field" ) );
}

QgsEditorWidgetConfig QgsKeyValueWidgetFactory::readConfig( const QDomElement &configElement, QgsVectorLayer *layer, int fieldIdx )
{
Q_UNUSED( configElement );
Q_UNUSED( layer );
Q_UNUSED( fieldIdx );
return QgsEditorWidgetConfig();
}

void QgsKeyValueWidgetFactory::writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx )
{
Q_UNUSED( config );
Q_UNUSED( configElement );
Q_UNUSED( doc );
Q_UNUSED( layer );
Q_UNUSED( fieldIdx );
}

QString QgsKeyValueWidgetFactory::representValue( QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, const QVariant& cache, const QVariant& value ) const
{
Q_UNUSED( vl );
Q_UNUSED( fieldIdx );
Q_UNUSED( config );
Q_UNUSED( cache );

if ( value.isNull() )
{
QSettings settings;
return settings.value( "qgis/nullValue", "NULL" ).toString();
}

QString result;
const QVariantMap map = value.toMap();
for ( QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i )
{
if ( !result.isEmpty() ) result.append( ", " );
result.append( i.key() ).append( ": " ).append( i.value().toString() );
}
return result;
}

Qt::AlignmentFlag QgsKeyValueWidgetFactory::alignmentFlag( QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config ) const
{
Q_UNUSED( vl );
Q_UNUSED( fieldIdx );
Q_UNUSED( config );

return Qt::AlignLeft;
}

unsigned int QgsKeyValueWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
{
const QgsField field = vl->fields().field( fieldIdx );
return field.type() == QVariant::Map ? 20 : 0;
}
46 changes: 46 additions & 0 deletions src/gui/editorwidgets/qgskeyvaluewidgetfactory.h
@@ -0,0 +1,46 @@
/***************************************************************************
qgskeyvaluewidgetfactory.h
--------------------------------------
Date : 08.2016
Copyright : (C) 2016 Patrick Valsecchi
Email : patrick.valsecchi@camptocamp.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 QGSKEYVALUEEDITFACTORY_H
#define QGSKEYVALUEEDITFACTORY_H

#include "qgseditorwidgetfactory.h"

/** @ingroup gui
* Factory for widgets for editing a QVariantMap
* @note added in QGIS 3.0
* @note not available in Python bindings
*/
class GUI_EXPORT QgsKeyValueWidgetFactory : public QgsEditorWidgetFactory
{
public:
/**
* Constructor.
*/
QgsKeyValueWidgetFactory( const QString& name );

// 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;
QString representValue( QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, const QVariant& cache, const QVariant& value ) const override;
Qt::AlignmentFlag alignmentFlag( QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config ) const override;
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
};

#endif // QGSKEYVALUEEDITFACTORY_H

0 comments on commit a90217d

Please sign in to comment.