Skip to content

Commit 03216df

Browse files
author
wonder
committedMay 30, 2010
[FEATURE] manual adding of categories in symbology-ng. Patch contributed by Lynx, thanks!
+ added missing python bindings and fixed some issues. git-svn-id: http://svn.osgeo.org/qgis/trunk@13601 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 712b108 commit 03216df

File tree

6 files changed

+141
-28
lines changed

6 files changed

+141
-28
lines changed
 

‎python/core/symbology-ng-core.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public:
181181
QgsSymbolV2* symbol();
182182
QString label() const;
183183

184+
void setValue( const QVariant &value );
184185
void setSymbol(QgsSymbolV2* s /Transfer/);
185186
void setLabel(QString label);
186187

@@ -220,9 +221,11 @@ public:
220221
//! return index of category with specified value (-1 if not found)
221222
int categoryIndexForValue(QVariant val);
222223

224+
bool updateCategoryValue( int catIndex, const QVariant &value );
223225
bool updateCategorySymbol(int catIndex, QgsSymbolV2* symbol /Transfer/);
224226
bool updateCategoryLabel(int catIndex, QString label);
225227

228+
void addCategory( const QgsRendererCategoryV2 &category );
226229
bool deleteCategory(int catIndex);
227230
void deleteAllCategories();
228231

‎src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ QString QgsRendererCategoryV2::label() const
4545
return mLabel;
4646
}
4747

48+
void QgsRendererCategoryV2::setValue( const QVariant &value )
49+
{
50+
mValue = value;
51+
}
52+
4853
void QgsRendererCategoryV2::setSymbol( QgsSymbolV2* s )
4954
{
5055
if ( mSymbol == s )
@@ -53,7 +58,7 @@ void QgsRendererCategoryV2::setSymbol( QgsSymbolV2* s )
5358
mSymbol = s;
5459
}
5560

56-
void QgsRendererCategoryV2::setLabel( QString label )
61+
void QgsRendererCategoryV2::setLabel( const QString &label )
5762
{
5863
mLabel = label;
5964
}
@@ -143,6 +148,14 @@ int QgsCategorizedSymbolRendererV2::categoryIndexForValue( QVariant val )
143148
return -1;
144149
}
145150

151+
bool QgsCategorizedSymbolRendererV2::updateCategoryValue( int catIndex, const QVariant &value )
152+
{
153+
if ( catIndex < 0 || catIndex >= mCategories.size() )
154+
return false;
155+
mCategories[catIndex].setValue( value );
156+
return true;
157+
}
158+
146159
bool QgsCategorizedSymbolRendererV2::updateCategorySymbol( int catIndex, QgsSymbolV2* symbol )
147160
{
148161
if ( catIndex < 0 || catIndex >= mCategories.size() )
@@ -159,6 +172,18 @@ bool QgsCategorizedSymbolRendererV2::updateCategoryLabel( int catIndex, QString
159172
return true;
160173
}
161174

175+
void QgsCategorizedSymbolRendererV2::addCategory( const QgsRendererCategoryV2 &cat )
176+
{
177+
if ( cat.symbol() == NULL )
178+
{
179+
QgsDebugMsg( "invalid symbol in a category! ignoring..." );
180+
}
181+
else
182+
{
183+
mCategories.append( cat );
184+
}
185+
}
186+
162187
bool QgsCategorizedSymbolRendererV2::deleteCategory( int catIndex )
163188
{
164189
if ( catIndex < 0 || catIndex >= mCategories.size() )

‎src/core/symbology-ng/qgscategorizedsymbolrendererv2.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ class CORE_EXPORT QgsRendererCategoryV2
2424
QgsSymbolV2* symbol() const;
2525
QString label() const;
2626

27+
void setValue( const QVariant &value );
2728
void setSymbol( QgsSymbolV2* s );
28-
void setLabel( QString label );
29+
void setLabel( const QString &label );
2930

3031
// debugging
3132
QString dump();
@@ -65,9 +66,11 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
6566
//! return index of category with specified value (-1 if not found)
6667
int categoryIndexForValue( QVariant val );
6768

69+
bool updateCategoryValue( int catIndex, const QVariant &value );
6870
bool updateCategorySymbol( int catIndex, QgsSymbolV2* symbol );
6971
bool updateCategoryLabel( int catIndex, QString label );
7072

73+
void addCategory( const QgsRendererCategoryV2 &category );
7174
bool deleteCategory( int catIndex );
7275
void deleteAllCategories();
7376

‎src/gui/symbology-ng/qgscategorizedsymbolrendererv2widget.cpp

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,17 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
4040
mRenderer = static_cast<QgsCategorizedSymbolRendererV2*>( renderer );
4141
}
4242

43+
QString attrName = mRenderer->classAttribute();
44+
mOldClassificationAttribute = attrName;
45+
4346
// setup user interface
4447
setupUi( this );
4548

4649
populateColumns();
4750
populateColorRamps();
4851
QStandardItemModel* m = new QStandardItemModel( this );
4952
QStringList labels;
50-
labels << "Value" << "Label";
53+
labels << tr( "Symbol" ) << tr( "Value" ) << tr( "Label" );
5154
m->setHorizontalHeaderLabels( labels );
5255
viewCategories->setModel( m );
5356

@@ -61,6 +64,7 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
6164
connect( btnAddCategories, SIGNAL( clicked() ), this, SLOT( addCategories() ) );
6265
connect( btnDeleteCategory, SIGNAL( clicked() ), this, SLOT( deleteCategory() ) );
6366
connect( btnDeleteAllCategories, SIGNAL( clicked() ), this, SLOT( deleteAllCategories() ) );
67+
connect( btnAddCategory, SIGNAL( clicked() ), this, SLOT( addCategory() ) );
6468
connect( m, SIGNAL( itemChanged( QStandardItem * ) ), this, SLOT( changeCurrentValue( QStandardItem * ) ) );
6569

6670
// update GUI from renderer
@@ -81,6 +85,7 @@ void QgsCategorizedSymbolRendererV2Widget::updateUiFromRenderer()
8185
// set column
8286
disconnect( cboCategorizedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( categoryColumnChanged() ) );
8387
QString attrName = mRenderer->classAttribute();
88+
mOldClassificationAttribute = attrName;
8489
int idx = cboCategorizedColumn->findText( attrName, Qt::MatchExactly );
8590
cboCategorizedColumn->setCurrentIndex( idx >= 0 ? idx : 0 );
8691
connect( cboCategorizedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( categoryColumnChanged() ) );
@@ -127,36 +132,28 @@ void QgsCategorizedSymbolRendererV2Widget::updateCategorizedSymbolIcon()
127132
btnChangeCategorizedSymbol->setIcon( icon );
128133
}
129134

130-
131135
void QgsCategorizedSymbolRendererV2Widget::populateCategories()
132136
{
133137
QStandardItemModel* m = qobject_cast<QStandardItemModel*>( viewCategories->model() );
134138
m->clear();
135139

136140
QStringList labels;
137-
labels << "Value" << "Label";
141+
labels << tr( "Symbol" ) << tr( "Value" ) << tr( "Label" );
138142
m->setHorizontalHeaderLabels( labels );
139143

140-
QSize iconSize( 16, 16 );
141-
142144
int i, count = mRenderer->categories().count();
143145

144146
// TODO: sort?? utils.sortVariantList(keys);
145147

146148
for ( i = 0; i < count; i++ )
147149
{
148-
const QgsRendererCategoryV2& cat = mRenderer->categories()[i];
149-
QVariant k = cat.value();
150-
151-
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( cat.symbol(), iconSize );
152-
QStandardItem* item = new QStandardItem( icon, k.toString() );
153-
item->setData( k ); // set attribute value as user role
154-
item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
155-
156-
QList<QStandardItem *> list;
157-
list << item << new QStandardItem( cat.label() );
158-
m->appendRow( list );
150+
const QgsRendererCategoryV2 &cat = mRenderer->categories()[i];
151+
addCategory( cat );
159152
}
153+
154+
viewCategories->resizeColumnToContents( 0 );
155+
viewCategories->resizeColumnToContents( 1 );
156+
viewCategories->resizeColumnToContents( 2 );
160157
}
161158

162159
void QgsCategorizedSymbolRendererV2Widget::populateColumns()
@@ -185,6 +182,21 @@ void QgsCategorizedSymbolRendererV2Widget::populateColorRamps()
185182
}
186183
}
187184

185+
void QgsCategorizedSymbolRendererV2Widget::addCategory( const QgsRendererCategoryV2 &cat )
186+
{
187+
QSize iconSize( 16, 16 );
188+
189+
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( cat.symbol(), iconSize );
190+
QStandardItem *symbolItem = new QStandardItem( icon, "" );
191+
symbolItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
192+
193+
QStandardItem *valueItem = new QStandardItem( cat.value().toString() );
194+
valueItem->setData( cat.value() ); // set attribute value as user role
195+
196+
QList<QStandardItem *> list;
197+
list << symbolItem << valueItem << new QStandardItem( cat.label() );
198+
qobject_cast<QStandardItemModel *>( viewCategories->model() )->appendRow( list );
199+
}
188200

189201
void QgsCategorizedSymbolRendererV2Widget::categoryColumnChanged()
190202
{
@@ -218,9 +230,6 @@ void QgsCategorizedSymbolRendererV2Widget::changeCategorySymbol()
218230
populateCategories();
219231
}
220232

221-
222-
223-
224233
static void _createCategories( QgsCategoryList& cats, QList<QVariant>& values, QgsSymbolV2* symbol, QgsVectorColorRampV2* ramp )
225234
{
226235
// sort the categories first
@@ -270,9 +279,47 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
270279
QgsCategoryList cats;
271280
_createCategories( cats, unique_vals, mCategorizedSymbol, ramp );
272281

282+
bool deleteExisting = false;
283+
if ( !mOldClassificationAttribute.isEmpty() &&
284+
attrName != mOldClassificationAttribute &&
285+
mRenderer->categories().count() > 0 )
286+
{
287+
int res = QMessageBox::question( this,
288+
tr( "Confirm Delete" ),
289+
tr( "The classification field was changed from '%1' to '%2'.\n"
290+
"Should the existing classes be deleted before classification?" )
291+
.arg( mOldClassificationAttribute ).arg( attrName ),
292+
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel );
293+
if ( res == QMessageBox::Cancel )
294+
return;
295+
if ( res == QMessageBox::Yes )
296+
deleteExisting = true;
297+
}
298+
299+
mOldClassificationAttribute = attrName;
300+
301+
if ( !deleteExisting )
302+
{
303+
QgsCategoryList prevCats = mRenderer->categories();
304+
for ( int i = 0; i < cats.size(); ++i )
305+
{
306+
bool contains = false;
307+
QVariant value = cats.at( i ).value();
308+
for ( int j = 0; j < prevCats.size() && !contains; ++j )
309+
{
310+
if ( prevCats.at( j ).value() == value )
311+
contains = true;
312+
}
313+
314+
if ( !contains )
315+
prevCats.append( cats.at( i ) );
316+
}
317+
cats = prevCats;
318+
}
319+
273320
// TODO: if not all categories are desired, delete some!
274321
/*
275-
if (not dlg.radAllCats.isChecked())
322+
if (not dlg.readAllCats.isChecked())
276323
{
277324
cats2 = {}
278325
for item in dlg.listCategories.selectedItems():
@@ -307,7 +354,7 @@ QVariant QgsCategorizedSymbolRendererV2Widget::currentCategory()
307354
if ( row == -1 )
308355
return QVariant();
309356
QStandardItemModel* m = qobject_cast<QStandardItemModel*>( viewCategories->model() );
310-
return m->item( row )->data();
357+
return m->item( row, 1 )->data();
311358
}
312359

313360
void QgsCategorizedSymbolRendererV2Widget::deleteCategory()
@@ -333,10 +380,29 @@ void QgsCategorizedSymbolRendererV2Widget::deleteAllCategories()
333380

334381
void QgsCategorizedSymbolRendererV2Widget::changeCurrentValue( QStandardItem * item )
335382
{
383+
int idx = item->row();
384+
QString newtext = item->text();
336385
if ( item->column() == 1 )
337386
{
338-
QString label = item->text();
339-
int idx = item->row();
340-
mRenderer->updateCategoryLabel( idx, label );
387+
QVariant value = newtext;
388+
// try to preserve variant type for this value
389+
QVariant::Type t = item->data().type();
390+
if ( t == QVariant::Int )
391+
value = newtext.toInt();
392+
else if ( t == QVariant::Double )
393+
value = newtext.toDouble();
394+
mRenderer->updateCategoryValue( idx, value );
395+
}
396+
else if ( item->column() == 2 )
397+
{
398+
mRenderer->updateCategoryLabel( idx, newtext );
341399
}
342400
}
401+
402+
void QgsCategorizedSymbolRendererV2Widget::addCategory()
403+
{
404+
QgsSymbolV2 *symbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
405+
QgsRendererCategoryV2 cat( QString(), symbol, QString() );
406+
addCategory( cat );
407+
mRenderer->addCategory( cat );
408+
}

‎src/gui/symbology-ng/qgscategorizedsymbolrendererv2widget.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <QStandardItem>
66

77
class QgsCategorizedSymbolRendererV2;
8+
class QgsRendererCategoryV2;
89

910
#include "ui_qgscategorizedsymbolrendererv2widget.h"
1011

@@ -30,6 +31,9 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
3031
void deleteAllCategories();
3132
void changeCurrentValue( QStandardItem * item );
3233

34+
protected slots:
35+
void addCategory();
36+
3337
protected:
3438

3539
void updateUiFromRenderer();
@@ -44,6 +48,8 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
4448

4549
void populateColorRamps();
4650

51+
void addCategory( const QgsRendererCategoryV2& cat );
52+
4753
//! return row index for the currently selected category (-1 if on no selection)
4854
int currentCategoryRow();
4955

@@ -56,6 +62,9 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
5662
QgsCategorizedSymbolRendererV2* mRenderer;
5763

5864
QgsSymbolV2* mCategorizedSymbol;
65+
66+
private:
67+
QString mOldClassificationAttribute;
5968
};
6069

6170

‎src/ui/qgscategorizedsymbolrendererv2widget.ui

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>464</width>
10-
<height>316</height>
9+
<width>599</width>
10+
<height>298</height>
1111
</rect>
1212
</property>
1313
<layout class="QVBoxLayout" name="verticalLayout">
@@ -114,6 +114,13 @@
114114
</property>
115115
</widget>
116116
</item>
117+
<item>
118+
<widget class="QPushButton" name="btnAddCategory">
119+
<property name="text">
120+
<string>Add</string>
121+
</property>
122+
</widget>
123+
</item>
117124
<item>
118125
<widget class="QPushButton" name="btnDeleteCategory">
119126
<property name="text">

0 commit comments

Comments
 (0)
Please sign in to comment.