Skip to content

Commit a90217d

Browse files
authored
Merge pull request #3459 from pvalsecc/hstore
[FEATURE] hstore
2 parents 74cceb4 + e533f0c commit a90217d

30 files changed

+1069
-19
lines changed

python/gui/gui.sip

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
%Include qgshistogramwidget.sip
9696
%Include qgshtmlannotationitem.sip
9797
%Include qgsidentifymenu.sip
98+
%Include qgskeyvaluewidget.sip
9899
%Include qgslegendfilterbutton.sip
99100
%Include qgslegendinterface.sip
100101
%Include qgslimitedrandomcolorrampdialog.sip

python/gui/qgskeyvaluewidget.sip

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/** \ingroup gui
2+
* Widget allowing to edit a QVariantMap, using a table.
3+
* @note added in QGIS 3.0
4+
*/
5+
class QgsKeyValueWidget : public QWidget
6+
{
7+
%TypeHeaderCode
8+
#include "qgskeyvaluewidget.h"
9+
%End
10+
public:
11+
/**
12+
* Constructor.
13+
*/
14+
explicit QgsKeyValueWidget( QWidget* parent /TransferThis/ = 0 );
15+
16+
/**
17+
* Set the initial value of the widget.
18+
*/
19+
void setMap( const QVariantMap& map );
20+
21+
/**
22+
* Get the edit value.
23+
* @return the QVariantMap
24+
*/
25+
QVariantMap map() const;
26+
27+
signals:
28+
/**
29+
* Emitted each time a key or a value is changed.
30+
*/
31+
void valueChanged();
32+
};

src/core/qgsexpression.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -4978,6 +4978,8 @@ QString QgsExpression::group( const QString& name )
49784978

49794979
QString QgsExpression::formatPreviewString( const QVariant& value )
49804980
{
4981+
static const int MAX_PREVIEW = 60;
4982+
49814983
if ( value.canConvert<QgsGeometry>() )
49824984
{
49834985
//result is a geometry
@@ -5017,15 +5019,31 @@ QString QgsExpression::formatPreviewString( const QVariant& value )
50175019
else if ( value.type() == QVariant::String )
50185020
{
50195021
QString previewString = value.toString();
5020-
if ( previewString.length() > 63 )
5022+
if ( previewString.length() > MAX_PREVIEW + 3 )
50215023
{
5022-
return QString( tr( "'%1...'" ) ).arg( previewString.left( 60 ) );
5024+
return QString( tr( "'%1...'" ) ).arg( previewString.left( MAX_PREVIEW ) );
50235025
}
50245026
else
50255027
{
50265028
return previewString.prepend( '\'' ).append( '\'' );
50275029
}
50285030
}
5031+
else if ( value.type() == QVariant::Map )
5032+
{
5033+
QString mapStr;
5034+
const QVariantMap map = value.toMap();
5035+
for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
5036+
{
5037+
if ( !mapStr.isEmpty() ) mapStr.append( ", " );
5038+
mapStr.append( it.key() ).append( ": " ).append( formatPreviewString( it.value() ) );
5039+
if ( mapStr.length() > MAX_PREVIEW + 3 )
5040+
{
5041+
mapStr = QString( tr( "%1..." ) ).arg( mapStr.left( MAX_PREVIEW ) );
5042+
break;
5043+
}
5044+
}
5045+
return tr( "<i>&lt;map: %1&gt;</i>" ).arg( mapStr );
5046+
}
50295047
else
50305048
{
50315049
return value.toString();

src/core/qgsvectorlayer.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -2231,7 +2231,10 @@ bool QgsVectorLayer::deleteFeature( QgsFeatureId fid )
22312231
bool QgsVectorLayer::deleteFeatures( const QgsFeatureIds& fids )
22322232
{
22332233
if ( !mEditBuffer )
2234+
{
2235+
QgsDebugMsg( "Cannot delete features (mEditBuffer==NULL)" );
22342236
return false;
2237+
}
22352238

22362239
bool res = mEditBuffer->deleteFeatures( fids );
22372240

src/core/qgsvectorlayereditbuffer.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "qgsvectordataprovider.h"
2121
#include "qgsvectorlayer.h"
2222

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

155157
if ( FID_IS_NEW( fid ) )
156158
{
157159
if ( !mAddedFeatures.contains( fid ) )
160+
{
161+
QgsDebugMsg( "Cannot delete features (in the list of added features)" );
158162
return false;
163+
}
159164
}
160165
else // existing feature
161166
{
162167
if ( mDeletedFeatureIds.contains( fid ) )
168+
{
169+
QgsDebugMsg( "Cannot delete features (in the list of deleted features)" );
163170
return false;
171+
}
164172
}
165173

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

186+
bool ok = true;
175187
Q_FOREACH ( QgsFeatureId fid, fids )
176-
deleteFeature( fid );
188+
ok = deleteFeature( fid ) && ok;
177189

178-
return true;
190+
return ok;
179191
}
180192

181193

src/gui/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ SET(QGIS_GUI_SRCS
116116
editorwidgets/qgsfilenamewidgetfactory.cpp
117117
editorwidgets/qgshiddenwidgetwrapper.cpp
118118
editorwidgets/qgshiddenwidgetfactory.cpp
119+
editorwidgets/qgskeyvaluewidgetfactory.cpp
120+
editorwidgets/qgskeyvaluewidgetwrapper.cpp
119121
editorwidgets/qgsmultiedittoolbutton.cpp
120122
editorwidgets/qgsphotoconfigdlg.cpp
121123
editorwidgets/qgsphotowidgetwrapper.cpp
@@ -231,6 +233,7 @@ SET(QGIS_GUI_SRCS
231233
qgshistogramwidget.cpp
232234
qgshtmlannotationitem.cpp
233235
qgsidentifymenu.cpp
236+
qgskeyvaluewidget.cpp
234237
qgslegendfilterbutton.cpp
235238
qgslegendinterface.cpp
236239
qgslimitedrandomcolorrampdialog.cpp
@@ -388,6 +391,7 @@ SET(QGIS_GUI_MOC_HDRS
388391
qgshistogramwidget.h
389392
qgshtmlannotationitem.h
390393
qgsidentifymenu.h
394+
qgskeyvaluewidget.h
391395
qgslegendfilterbutton.h
392396
qgslegendinterface.h
393397
qgslimitedrandomcolorrampdialog.h
@@ -561,6 +565,7 @@ SET(QGIS_GUI_MOC_HDRS
561565
editorwidgets/qgsexternalresourcewidgetwrapper.h
562566
editorwidgets/qgsfilenamewidgetwrapper.h
563567
editorwidgets/qgshiddenwidgetwrapper.h
568+
editorwidgets/qgskeyvaluewidgetwrapper.h
564569
editorwidgets/qgsmultiedittoolbutton.h
565570
editorwidgets/qgsphotoconfigdlg.h
566571
editorwidgets/qgsphotowidgetwrapper.h
@@ -676,6 +681,7 @@ SET(QGIS_GUI_HDRS
676681
editorwidgets/qgsexternalresourcewidgetfactory.h
677682
editorwidgets/qgsfilenamewidgetfactory.h
678683
editorwidgets/qgshiddenwidgetfactory.h
684+
editorwidgets/qgskeyvaluewidgetfactory.h
679685
editorwidgets/qgsphotowidgetfactory.h
680686
editorwidgets/qgsrangewidgetfactory.h
681687
editorwidgets/qgsrelationreferencefactory.h
@@ -731,6 +737,7 @@ SET(QGIS_GUI_UI_HDRS
731737
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionbuilder.h
732738
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsexpressionselectiondialogbase.h
733739
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsgenericprojectionselectorbase.h
740+
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgskeyvaluewidgetbase.h
734741
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmessagelogviewer.h
735742
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmessageviewer.h
736743
${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsowssourceselectbase.h

src/gui/attributetable/qgsattributetabledelegate.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ QWidget* QgsAttributeTableDelegate::createEditor( QWidget *parent, const QStyleO
7272
QWidget* w = eww->widget();
7373

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

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

src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "qgsexternalresourcewidgetfactory.h"
3333
#include "qgsfilenamewidgetfactory.h"
3434
#include "qgshiddenwidgetfactory.h"
35+
#include "qgskeyvaluewidgetfactory.h"
3536
#include "qgsphotowidgetfactory.h"
3637
#include "qgsrangewidgetfactory.h"
3738
#include "qgsrelationreferencefactory.h"
@@ -73,6 +74,7 @@ void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBa
7374
reg->registerWidget( "RelationReference", new QgsRelationReferenceFactory( tr( "Relation Reference" ), mapCanvas, messageBar ) );
7475
reg->registerWidget( "DateTime", new QgsDateTimeEditFactory( tr( "Date/Time" ) ) );
7576
reg->registerWidget( "ExternalResource", new QgsExternalResourceWidgetFactory( tr( "External Resource" ) ) );
77+
reg->registerWidget( "KeyValue", new QgsKeyValueWidgetFactory( tr( "Key/Value" ) ) );
7678
}
7779

7880
QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()

src/gui/editorwidgets/qgshiddenwidgetwrapper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <QWidget>
1919

2020
QgsHiddenWidgetWrapper::QgsHiddenWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
21-
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
21+
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
2222
{
2323
}
2424

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/***************************************************************************
2+
qgskeyvaluewidgetfactory.cpp
3+
--------------------------------------
4+
Date : 08.2016
5+
Copyright : (C) 2016 Patrick Valsecchi
6+
Email : patrick.valsecchi@camptocamp.com
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 "qgskeyvaluewidgetfactory.h"
17+
#include "qgskeyvaluewidgetwrapper.h"
18+
#include "qgsdummyconfigdlg.h"
19+
#include "qgsfield.h"
20+
#include "qgsvectorlayer.h"
21+
22+
#include <QVariant>
23+
#include <QSettings>
24+
25+
QgsKeyValueWidgetFactory::QgsKeyValueWidgetFactory( const QString& name ):
26+
QgsEditorWidgetFactory( name )
27+
{
28+
}
29+
30+
QgsEditorWidgetWrapper* QgsKeyValueWidgetFactory::create( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent ) const
31+
{
32+
return new QgsKeyValueWidgetWrapper( vl, fieldIdx, editor, parent );
33+
}
34+
35+
QgsEditorConfigWidget* QgsKeyValueWidgetFactory::configWidget( QgsVectorLayer *vl, int fieldIdx, QWidget *parent ) const
36+
{
37+
Q_UNUSED( vl );
38+
Q_UNUSED( fieldIdx );
39+
Q_UNUSED( parent );
40+
return new QgsDummyConfigDlg( vl, fieldIdx, parent, QObject::tr( "Key/Value field" ) );
41+
}
42+
43+
QgsEditorWidgetConfig QgsKeyValueWidgetFactory::readConfig( const QDomElement &configElement, QgsVectorLayer *layer, int fieldIdx )
44+
{
45+
Q_UNUSED( configElement );
46+
Q_UNUSED( layer );
47+
Q_UNUSED( fieldIdx );
48+
return QgsEditorWidgetConfig();
49+
}
50+
51+
void QgsKeyValueWidgetFactory::writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx )
52+
{
53+
Q_UNUSED( config );
54+
Q_UNUSED( configElement );
55+
Q_UNUSED( doc );
56+
Q_UNUSED( layer );
57+
Q_UNUSED( fieldIdx );
58+
}
59+
60+
QString QgsKeyValueWidgetFactory::representValue( QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, const QVariant& cache, const QVariant& value ) const
61+
{
62+
Q_UNUSED( vl );
63+
Q_UNUSED( fieldIdx );
64+
Q_UNUSED( config );
65+
Q_UNUSED( cache );
66+
67+
if ( value.isNull() )
68+
{
69+
QSettings settings;
70+
return settings.value( "qgis/nullValue", "NULL" ).toString();
71+
}
72+
73+
QString result;
74+
const QVariantMap map = value.toMap();
75+
for ( QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i )
76+
{
77+
if ( !result.isEmpty() ) result.append( ", " );
78+
result.append( i.key() ).append( ": " ).append( i.value().toString() );
79+
}
80+
return result;
81+
}
82+
83+
Qt::AlignmentFlag QgsKeyValueWidgetFactory::alignmentFlag( QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config ) const
84+
{
85+
Q_UNUSED( vl );
86+
Q_UNUSED( fieldIdx );
87+
Q_UNUSED( config );
88+
89+
return Qt::AlignLeft;
90+
}
91+
92+
unsigned int QgsKeyValueWidgetFactory::fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const
93+
{
94+
const QgsField field = vl->fields().field( fieldIdx );
95+
return field.type() == QVariant::Map ? 20 : 0;
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/***************************************************************************
2+
qgskeyvaluewidgetfactory.h
3+
--------------------------------------
4+
Date : 08.2016
5+
Copyright : (C) 2016 Patrick Valsecchi
6+
Email : patrick.valsecchi@camptocamp.com
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+
#ifndef QGSKEYVALUEEDITFACTORY_H
17+
#define QGSKEYVALUEEDITFACTORY_H
18+
19+
#include "qgseditorwidgetfactory.h"
20+
21+
/** @ingroup gui
22+
* Factory for widgets for editing a QVariantMap
23+
* @note added in QGIS 3.0
24+
* @note not available in Python bindings
25+
*/
26+
class GUI_EXPORT QgsKeyValueWidgetFactory : public QgsEditorWidgetFactory
27+
{
28+
public:
29+
/**
30+
* Constructor.
31+
*/
32+
QgsKeyValueWidgetFactory( const QString& name );
33+
34+
// QgsEditorWidgetFactory interface
35+
public:
36+
QgsEditorWidgetWrapper* create( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent ) const override;
37+
//QgsSearchWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
38+
QgsEditorConfigWidget* configWidget( QgsVectorLayer *vl, int fieldIdx, QWidget *parent ) const override;
39+
QgsEditorWidgetConfig readConfig( const QDomElement &configElement, QgsVectorLayer *layer, int fieldIdx ) override;
40+
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;
41+
QString representValue( QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, const QVariant& cache, const QVariant& value ) const override;
42+
Qt::AlignmentFlag alignmentFlag( QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config ) const override;
43+
unsigned int fieldScore( const QgsVectorLayer* vl, int fieldIdx ) const override;
44+
};
45+
46+
#endif // QGSKEYVALUEEDITFACTORY_H

0 commit comments

Comments
 (0)