Skip to content

Commit d91c9cd

Browse files
committed
Fix a bunch of crashes in renderer widgets when used with a rule
based rule which has no symbol
1 parent e9cd829 commit d91c9cd

File tree

3 files changed

+91
-34
lines changed

3 files changed

+91
-34
lines changed

src/core/symbology-ng/qgssymbolv2.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,8 @@ void QgsLineSymbolV2::setWidth( double w )
13241324
double QgsLineSymbolV2::width() const
13251325
{
13261326
double maxWidth = 0;
1327+
if ( mLayers.isEmpty() )
1328+
return maxWidth;
13271329

13281330
Q_FOREACH ( QgsSymbolLayerV2* symbolLayer, mLayers )
13291331
{

src/gui/symbology-ng/qgsrendererv2widget.cpp

+87-32
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,30 @@ void QgsRendererV2Widget::contextMenuViewCategories( const QPoint & )
6161
void QgsRendererV2Widget::changeSymbolColor()
6262
{
6363
QList<QgsSymbolV2*> symbolList = selectedSymbols();
64-
if ( symbolList.size() < 1 )
64+
if ( symbolList.isEmpty() )
6565
{
6666
return;
6767
}
6868

69-
QColor color = QgsColorDialogV2::getColor( symbolList.at( 0 )->color(), this, "Change Symbol Color", true );
69+
QgsSymbolV2* firstSymbol = nullptr;
70+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
71+
{
72+
if ( symbol )
73+
{
74+
firstSymbol = symbol;
75+
break;
76+
}
77+
}
78+
if ( !firstSymbol )
79+
return;
80+
81+
QColor color = QgsColorDialogV2::getColor( firstSymbol->color(), this, "Change Symbol Color", true );
7082
if ( color.isValid() )
7183
{
72-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
73-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
84+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
7485
{
75-
( *symbolIt )->setColor( color );
86+
if ( symbol )
87+
symbol->setColor( color );
7688
}
7789
refreshSymbolView();
7890
}
@@ -81,20 +93,32 @@ void QgsRendererV2Widget::changeSymbolColor()
8193
void QgsRendererV2Widget::changeSymbolTransparency()
8294
{
8395
QList<QgsSymbolV2*> symbolList = selectedSymbols();
84-
if ( symbolList.size() < 1 )
96+
if ( symbolList.isEmpty() )
8597
{
8698
return;
8799
}
88100

101+
QgsSymbolV2* firstSymbol = nullptr;
102+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
103+
{
104+
if ( symbol )
105+
{
106+
firstSymbol = symbol;
107+
break;
108+
}
109+
}
110+
if ( !firstSymbol )
111+
return;
112+
89113
bool ok;
90-
double oldTransparency = ( 1 - symbolList.at( 0 )->alpha() ) * 100; // convert to percents
114+
double oldTransparency = ( 1 - firstSymbol->alpha() ) * 100; // convert to percents
91115
double transparency = QInputDialog::getDouble( this, tr( "Transparency" ), tr( "Change symbol transparency [%]" ), oldTransparency, 0.0, 100.0, 0, &ok );
92116
if ( ok )
93117
{
94-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
95-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
118+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
96119
{
97-
( *symbolIt )->setAlpha( 1 - transparency / 100 );
120+
if ( symbol )
121+
symbol->setAlpha( 1 - transparency / 100 );
98122
}
99123
refreshSymbolView();
100124
}
@@ -103,22 +127,34 @@ void QgsRendererV2Widget::changeSymbolTransparency()
103127
void QgsRendererV2Widget::changeSymbolUnit()
104128
{
105129
QList<QgsSymbolV2*> symbolList = selectedSymbols();
106-
if ( symbolList.size() < 1 )
130+
if ( symbolList.isEmpty() )
107131
{
108132
return;
109133
}
110134

135+
QgsSymbolV2* firstSymbol = nullptr;
136+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
137+
{
138+
if ( symbol )
139+
{
140+
firstSymbol = symbol;
141+
break;
142+
}
143+
}
144+
if ( !firstSymbol )
145+
return;
146+
111147
bool ok;
112-
int currentUnit = ( symbolList.at( 0 )->outputUnit() == QgsSymbolV2::MM ) ? 0 : 1;
148+
int currentUnit = ( firstSymbol->outputUnit() == QgsSymbolV2::MM ) ? 0 : 1;
113149
QString item = QInputDialog::getItem( this, tr( "Symbol unit" ), tr( "Select symbol unit" ), QStringList() << tr( "Millimeter" ) << tr( "Map unit" ), currentUnit, false, &ok );
114150
if ( ok )
115151
{
116152
QgsSymbolV2::OutputUnit unit = ( item.compare( tr( "Millimeter" ) ) == 0 ) ? QgsSymbolV2::MM : QgsSymbolV2::MapUnit;
117153

118-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
119-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
154+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
120155
{
121-
( *symbolIt )->setOutputUnit( unit );
156+
if ( symbol )
157+
symbol->setOutputUnit( unit );
122158
}
123159
refreshSymbolView();
124160
}
@@ -127,7 +163,7 @@ void QgsRendererV2Widget::changeSymbolUnit()
127163
void QgsRendererV2Widget::changeSymbolWidth()
128164
{
129165
QList<QgsSymbolV2*> symbolList = selectedSymbols();
130-
if ( symbolList.size() < 1 )
166+
if ( symbolList.isEmpty() )
131167
{
132168
return;
133169
}
@@ -139,11 +175,13 @@ void QgsRendererV2Widget::changeSymbolWidth()
139175
{
140176
if ( !dlg.mDDBtn->isActive() )
141177
{
142-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
143-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
178+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
144179
{
145-
if (( *symbolIt )->type() == QgsSymbolV2::Line )
146-
static_cast<QgsLineSymbolV2*>( *symbolIt )->setWidth( dlg.mSpinBox->value() );
180+
if ( !symbol )
181+
continue;
182+
183+
if ( symbol->type() == QgsSymbolV2::Line )
184+
static_cast<QgsLineSymbolV2*>( symbol )->setWidth( dlg.mSpinBox->value() );
147185
}
148186
}
149187
refreshSymbolView();
@@ -153,7 +191,7 @@ void QgsRendererV2Widget::changeSymbolWidth()
153191
void QgsRendererV2Widget::changeSymbolSize()
154192
{
155193
QList<QgsSymbolV2*> symbolList = selectedSymbols();
156-
if ( symbolList.size() < 1 )
194+
if ( symbolList.isEmpty() )
157195
{
158196
return;
159197
}
@@ -165,11 +203,13 @@ void QgsRendererV2Widget::changeSymbolSize()
165203
{
166204
if ( !dlg.mDDBtn->isActive() )
167205
{
168-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
169-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
206+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
170207
{
171-
if (( *symbolIt )->type() == QgsSymbolV2::Marker )
172-
static_cast<QgsMarkerSymbolV2*>( *symbolIt )->setSize( dlg.mSpinBox->value() );
208+
if ( !symbol )
209+
continue;
210+
211+
if ( symbol->type() == QgsSymbolV2::Marker )
212+
static_cast<QgsMarkerSymbolV2*>( symbol )->setSize( dlg.mSpinBox->value() );
173213
}
174214
}
175215
refreshSymbolView();
@@ -179,7 +219,7 @@ void QgsRendererV2Widget::changeSymbolSize()
179219
void QgsRendererV2Widget::changeSymbolAngle()
180220
{
181221
QList<QgsSymbolV2*> symbolList = selectedSymbols();
182-
if ( symbolList.size() < 1 )
222+
if ( symbolList.isEmpty() )
183223
{
184224
return;
185225
}
@@ -191,11 +231,13 @@ void QgsRendererV2Widget::changeSymbolAngle()
191231
{
192232
if ( !dlg.mDDBtn->isActive() )
193233
{
194-
QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
195-
for ( ; symbolIt != symbolList.end(); ++symbolIt )
234+
Q_FOREACH ( QgsSymbolV2* symbol, symbolList )
196235
{
197-
if (( *symbolIt )->type() == QgsSymbolV2::Marker )
198-
static_cast<QgsMarkerSymbolV2*>( *symbolIt )->setAngle( dlg.mSpinBox->value() );
236+
if ( !symbol )
237+
continue;
238+
239+
if ( symbol->type() == QgsSymbolV2::Marker )
240+
static_cast<QgsMarkerSymbolV2*>( symbol )->setAngle( dlg.mSpinBox->value() );
199241
}
200242
}
201243
refreshSymbolView();
@@ -460,17 +502,30 @@ void QgsDataDefinedValueDialog::init( const QString & description )
460502
QgsDataDefined dd = symbolDataDefined();
461503
mDDBtn->init( mLayer, &dd, QgsDataDefinedButton::Double, description );
462504
mDDBtn->registerGetExpressionContextCallback( &_getExpressionContext, this );
463-
mSpinBox->setValue( value( mSymbolList.back() ) );
505+
506+
QgsSymbolV2* initialSymbol = nullptr;
507+
Q_FOREACH ( QgsSymbolV2* symbol, mSymbolList )
508+
{
509+
if ( symbol )
510+
{
511+
initialSymbol = symbol;
512+
}
513+
}
514+
mSpinBox->setValue( initialSymbol ? value( initialSymbol ) : 0 );
464515
mSpinBox->setEnabled( !mDDBtn->isActive() );
465516
}
466517

467518
QgsDataDefined QgsDataDefinedValueDialog::symbolDataDefined() const
468519
{
520+
if ( mSymbolList.isEmpty() || !mSymbolList.back() )
521+
return QgsDataDefined();
522+
469523
// check that all symbols share the same size expression
470524
QgsDataDefined dd = symbolDataDefined( mSymbolList.back() );
471525
Q_FOREACH ( QgsSymbolV2 * it, mSymbolList )
472526
{
473-
if ( symbolDataDefined( it ) != dd ) return QgsDataDefined();
527+
if ( !it || symbolDataDefined( it ) != dd )
528+
return QgsDataDefined();
474529
}
475530
return dd;
476531
}

src/gui/symbology-ng/qgsrendererv2widget.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ class GUI_EXPORT QgsDataDefinedSizeDialog : public QgsDataDefinedValueDialog
215215
: QgsDataDefinedValueDialog( symbolList, layer, tr( "Size" ) )
216216
{
217217
init( tr( "Symbol size" ) );
218-
if ( !symbolList.isEmpty() && mLayer )
219-
mDDBtn->setAssistant( tr( "Size Assistant..." ), new QgsSizeScaleWidget( mLayer, static_cast<const QgsMarkerSymbolV2*>( symbolList[0] ) ) );
218+
if ( !symbolList.isEmpty() && symbolList.at( 0 ) && mLayer )
219+
mDDBtn->setAssistant( tr( "Size Assistant..." ), new QgsSizeScaleWidget( mLayer, static_cast<const QgsMarkerSymbolV2*>( symbolList.at( 0 ) ) ) );
220220
}
221221

222222
protected:

0 commit comments

Comments
 (0)