QGIS API Documentation  2.15.0-Master (972fc9f)
qgsgraduatedsymbolrendererv2widget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgraduatedsymbolrendererv2widget.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot 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  ***************************************************************************/
16 #include "qgspanelwidget.h"
17 
18 #include "qgssymbolv2.h"
19 #include "qgssymbollayerv2utils.h"
20 #include "qgsvectorcolorrampv2.h"
21 #include "qgsstylev2.h"
22 
23 #include "qgsvectorlayer.h"
24 
27 
28 #include "qgsludialog.h"
29 
30 #include "qgsproject.h"
31 #include "qgsmapcanvas.h"
32 
33 #include <QKeyEvent>
34 #include <QMenu>
35 #include <QMessageBox>
36 #include <QStandardItemModel>
37 #include <QStandardItem>
38 #include <QPen>
39 #include <QPainter>
40 
41 // ------------------------------ Model ------------------------------------
42 
44 
45 QgsGraduatedSymbolRendererV2Model::QgsGraduatedSymbolRendererV2Model( QObject * parent ) : QAbstractItemModel( parent )
46  , mRenderer( nullptr )
47  , mMimeFormat( "application/x-qgsgraduatedsymbolrendererv2model" )
48 {
49 }
50 
51 void QgsGraduatedSymbolRendererV2Model::setRenderer( QgsGraduatedSymbolRendererV2* renderer )
52 {
53  if ( mRenderer )
54  {
55  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
56  mRenderer = nullptr;
57  endRemoveRows();
58  }
59  if ( renderer )
60  {
61  beginInsertRows( QModelIndex(), 0, renderer->ranges().size() - 1 );
62  mRenderer = renderer;
63  endInsertRows();
64  }
65 }
66 
67 void QgsGraduatedSymbolRendererV2Model::addClass( QgsSymbolV2* symbol )
68 {
69  if ( !mRenderer ) return;
70  int idx = mRenderer->ranges().size();
71  beginInsertRows( QModelIndex(), idx, idx );
72  mRenderer->addClass( symbol );
73  endInsertRows();
74 }
75 
76 void QgsGraduatedSymbolRendererV2Model::addClass( const QgsRendererRangeV2& range )
77 {
78  if ( !mRenderer )
79  {
80  return;
81  }
82  int idx = mRenderer->ranges().size();
83  beginInsertRows( QModelIndex(), idx, idx );
84  mRenderer->addClass( range );
85  endInsertRows();
86 }
87 
88 QgsRendererRangeV2 QgsGraduatedSymbolRendererV2Model::rendererRange( const QModelIndex &index )
89 {
90  if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
91  {
92  return QgsRendererRangeV2();
93  }
94 
95  return mRenderer->ranges().value( index.row() );
96 }
97 
98 Qt::ItemFlags QgsGraduatedSymbolRendererV2Model::flags( const QModelIndex & index ) const
99 {
100  if ( !index.isValid() )
101  {
102  return Qt::ItemIsDropEnabled;
103  }
104 
105  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
106 
107  if ( index.column() == 2 )
108  {
109  flags |= Qt::ItemIsEditable;
110  }
111 
112  return flags;
113 }
114 
115 Qt::DropActions QgsGraduatedSymbolRendererV2Model::supportedDropActions() const
116 {
117  return Qt::MoveAction;
118 }
119 
120 QVariant QgsGraduatedSymbolRendererV2Model::data( const QModelIndex &index, int role ) const
121 {
122  if ( !index.isValid() || !mRenderer ) return QVariant();
123 
124  const QgsRendererRangeV2 range = mRenderer->ranges().value( index.row() );
125 
126  if ( role == Qt::CheckStateRole && index.column() == 0 )
127  {
128  return range.renderState() ? Qt::Checked : Qt::Unchecked;
129  }
130  else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
131  {
132  switch ( index.column() )
133  {
134  case 1:
135  {
136  int decimalPlaces = mRenderer->labelFormat().precision() + 2;
137  if ( decimalPlaces < 0 ) decimalPlaces = 0;
138  return QString::number( range.lowerValue(), 'f', decimalPlaces ) + " - " + QString::number( range.upperValue(), 'f', decimalPlaces );
139  }
140  case 2:
141  return range.label();
142  default:
143  return QVariant();
144  }
145  }
146  else if ( role == Qt::DecorationRole && index.column() == 0 && range.symbol() )
147  {
148  return QgsSymbolLayerV2Utils::symbolPreviewIcon( range.symbol(), QSize( 16, 16 ) );
149  }
150  else if ( role == Qt::TextAlignmentRole )
151  {
152  return ( index.column() == 0 ) ? Qt::AlignHCenter : Qt::AlignLeft;
153  }
154  else if ( role == Qt::EditRole )
155  {
156  switch ( index.column() )
157  {
158  // case 1: return rangeStr;
159  case 2:
160  return range.label();
161  default:
162  return QVariant();
163  }
164  }
165 
166  return QVariant();
167 }
168 
169 bool QgsGraduatedSymbolRendererV2Model::setData( const QModelIndex & index, const QVariant & value, int role )
170 {
171  if ( !index.isValid() )
172  return false;
173 
174  if ( index.column() == 0 && role == Qt::CheckStateRole )
175  {
176  mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
177  emit dataChanged( index, index );
178  return true;
179  }
180 
181  if ( role != Qt::EditRole )
182  return false;
183 
184  switch ( index.column() )
185  {
186  case 1: // range
187  return false; // range is edited in popup dialog
188  case 2: // label
189  mRenderer->updateRangeLabel( index.row(), value.toString() );
190  break;
191  default:
192  return false;
193  }
194 
195  emit dataChanged( index, index );
196  return true;
197 }
198 
199 QVariant QgsGraduatedSymbolRendererV2Model::headerData( int section, Qt::Orientation orientation, int role ) const
200 {
201  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
202  {
203  QStringList lst;
204  lst << tr( "Symbol" ) << tr( "Values" ) << tr( "Legend" );
205  return lst.value( section );
206  }
207  return QVariant();
208 }
209 
210 int QgsGraduatedSymbolRendererV2Model::rowCount( const QModelIndex &parent ) const
211 {
212  if ( parent.isValid() || !mRenderer )
213  {
214  return 0;
215  }
216  return mRenderer->ranges().size();
217 }
218 
219 int QgsGraduatedSymbolRendererV2Model::columnCount( const QModelIndex & index ) const
220 {
221  Q_UNUSED( index );
222  return 3;
223 }
224 
225 QModelIndex QgsGraduatedSymbolRendererV2Model::index( int row, int column, const QModelIndex &parent ) const
226 {
227  if ( hasIndex( row, column, parent ) )
228  {
229  return createIndex( row, column );
230  }
231  return QModelIndex();
232 }
233 
234 QModelIndex QgsGraduatedSymbolRendererV2Model::parent( const QModelIndex &index ) const
235 {
236  Q_UNUSED( index );
237  return QModelIndex();
238 }
239 
240 QStringList QgsGraduatedSymbolRendererV2Model::mimeTypes() const
241 {
242  QStringList types;
243  types << mMimeFormat;
244  return types;
245 }
246 
247 QMimeData *QgsGraduatedSymbolRendererV2Model::mimeData( const QModelIndexList &indexes ) const
248 {
249  QMimeData *mimeData = new QMimeData();
250  QByteArray encodedData;
251 
252  QDataStream stream( &encodedData, QIODevice::WriteOnly );
253 
254  // Create list of rows
255  Q_FOREACH ( const QModelIndex &index, indexes )
256  {
257  if ( !index.isValid() || index.column() != 0 )
258  continue;
259 
260  stream << index.row();
261  }
262  mimeData->setData( mMimeFormat, encodedData );
263  return mimeData;
264 }
265 
266 bool QgsGraduatedSymbolRendererV2Model::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
267 {
268  Q_UNUSED( row );
269  Q_UNUSED( column );
270  if ( action != Qt::MoveAction ) return true;
271 
272  if ( !data->hasFormat( mMimeFormat ) ) return false;
273 
274  QByteArray encodedData = data->data( mMimeFormat );
275  QDataStream stream( &encodedData, QIODevice::ReadOnly );
276 
277  QVector<int> rows;
278  while ( !stream.atEnd() )
279  {
280  int r;
281  stream >> r;
282  rows.append( r );
283  }
284 
285  int to = parent.row();
286  // to is -1 if dragged outside items, i.e. below any item,
287  // then move to the last position
288  if ( to == -1 ) to = mRenderer->ranges().size(); // out of rang ok, will be decreased
289  for ( int i = rows.size() - 1; i >= 0; i-- )
290  {
291  QgsDebugMsg( QString( "move %1 to %2" ).arg( rows[i] ).arg( to ) );
292  int t = to;
293  // moveCategory first removes and then inserts
294  if ( rows[i] < t ) t--;
295  mRenderer->moveClass( rows[i], t );
296  // current moved under another, shift its index up
297  for ( int j = 0; j < i; j++ )
298  {
299  if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
300  }
301  // removed under 'to' so the target shifted down
302  if ( rows[i] < to ) to--;
303  }
304  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
305  emit rowsMoved();
306  return false;
307 }
308 
309 void QgsGraduatedSymbolRendererV2Model::deleteRows( QList<int> rows )
310 {
311  for ( int i = rows.size() - 1; i >= 0; i-- )
312  {
313  beginRemoveRows( QModelIndex(), rows[i], rows[i] );
314  mRenderer->deleteClass( rows[i] );
315  endRemoveRows();
316  }
317 }
318 
319 void QgsGraduatedSymbolRendererV2Model::removeAllRows()
320 {
321  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
322  mRenderer->deleteAllClasses();
323  endRemoveRows();
324 }
325 
326 void QgsGraduatedSymbolRendererV2Model::sort( int column, Qt::SortOrder order )
327 {
328  if ( column == 0 )
329  {
330  return;
331  }
332  if ( column == 1 )
333  {
334  mRenderer->sortByValue( order );
335  }
336  else if ( column == 2 )
337  {
338  mRenderer->sortByLabel( order );
339  }
340  emit rowsMoved();
341  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
342  QgsDebugMsg( "Done" );
343 }
344 
345 void QgsGraduatedSymbolRendererV2Model::updateSymbology( bool resetModel )
346 {
347  if ( resetModel )
348  {
349  reset();
350  }
351  else
352  {
353  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
354  }
355 }
356 
357 void QgsGraduatedSymbolRendererV2Model::updateLabels()
358 {
359  emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
360 }
361 
362 // ------------------------------ View style --------------------------------
363 QgsGraduatedSymbolRendererV2ViewStyle::QgsGraduatedSymbolRendererV2ViewStyle( QStyle* style )
364  : QProxyStyle( style )
365 {}
366 
367 void QgsGraduatedSymbolRendererV2ViewStyle::drawPrimitive( PrimitiveElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget ) const
368 {
369  if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
370  {
371  QStyleOption opt( *option );
372  opt.rect.setLeft( 0 );
373  // draw always as line above, because we move item to that index
374  opt.rect.setHeight( 0 );
375  if ( widget ) opt.rect.setRight( widget->width() );
376  QProxyStyle::drawPrimitive( element, &opt, painter, widget );
377  return;
378  }
379  QProxyStyle::drawPrimitive( element, option, painter, widget );
380 }
381 
383 
384 // ------------------------------ Widget ------------------------------------
385 
387 {
388  return new QgsGraduatedSymbolRendererV2Widget( layer, style, renderer );
389 }
390 
391 static QgsExpressionContext _getExpressionContext( const void* context )
392 {
394 
395  QgsExpressionContext expContext;
399 
400  if ( widget->mapCanvas() )
401  {
404  }
405  else
406  {
408  }
409 
410  if ( widget->vectorLayer() )
411  expContext << QgsExpressionContextUtils::layerScope( widget->vectorLayer() );
412 
413  return expContext;
414 }
415 
417  : QgsRendererV2Widget( layer, style )
418  , mRenderer( nullptr )
419  , mModel( nullptr )
420 {
421 
422 
423  // try to recognize the previous renderer
424  // (null renderer means "no previous renderer")
425  if ( renderer )
426  {
428  }
429  if ( !mRenderer )
430  {
432  }
433 
434  // setup user interface
435  setupUi( this );
436 
437  mModel = new QgsGraduatedSymbolRendererV2Model( this );
438 
439  mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date );
440  mExpressionWidget->setLayer( mLayer );
441 
443 
444  cboGraduatedColorRamp->populate( mStyle );
445 
446  spinPrecision->setMinimum( QgsRendererRangeV2LabelFormat::MinPrecision );
447  spinPrecision->setMaximum( QgsRendererRangeV2LabelFormat::MaxPrecision );
448 
449  // set project default color ramp
450  QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" );
451  if ( defaultColorRamp != "" )
452  {
453  int index = cboGraduatedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive );
454  if ( index >= 0 )
455  cboGraduatedColorRamp->setCurrentIndex( index );
456  }
457 
458 
459  viewGraduated->setStyle( new QgsGraduatedSymbolRendererV2ViewStyle( viewGraduated->style() ) );
460 
462 
463  methodComboBox->blockSignals( true );
464  methodComboBox->addItem( "Color" );
466  {
467  methodComboBox->addItem( "Size" );
468  minSizeSpinBox->setValue( 1 );
469  maxSizeSpinBox->setValue( 8 );
470  }
471  else if ( mGraduatedSymbol->type() == QgsSymbolV2::Line )
472  {
473  methodComboBox->addItem( "Size" );
474  minSizeSpinBox->setValue( .1 );
475  maxSizeSpinBox->setValue( 2 );
476  }
477  methodComboBox->blockSignals( false );
478 
479  connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) );
480  connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) );
481  connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) );
482  connect( viewGraduated, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) );
483 
484  connect( btnGraduatedClassify, SIGNAL( clicked() ), this, SLOT( classifyGraduated() ) );
485  connect( btnChangeGraduatedSymbol, SIGNAL( clicked() ), this, SLOT( changeGraduatedSymbol() ) );
486  connect( btnGraduatedDelete, SIGNAL( clicked() ), this, SLOT( deleteClasses() ) );
487  connect( btnDeleteAllClasses, SIGNAL( clicked() ), this, SLOT( deleteAllClasses() ) );
488  connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) );
489  connect( cbxLinkBoundaries, SIGNAL( toggled( bool ) ), this, SLOT( toggleBoundariesLink( bool ) ) );
490 
491  connect( mSizeUnitWidget, SIGNAL( changed() ), this, SLOT( on_mSizeUnitWidget_changed() ) );
492 
494 
495  // initialize from previously set renderer
497 
498  // menus for data-defined rotation/size
499  QMenu* advMenu = new QMenu;
500 
501  advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );
502 
503  btnAdvanced->setMenu( advMenu );
504 
505  mHistogramWidget->setLayer( mLayer );
506  mHistogramWidget->setRenderer( mRenderer );
507  connect( mHistogramWidget, SIGNAL( rangesModified( bool ) ), this, SLOT( refreshRanges( bool ) ) );
508  connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), mHistogramWidget, SLOT( setSourceFieldExp( QString ) ) );
509 
510  mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, this );
511 }
512 
514 {
515  if ( !mGraduatedSymbol ) return;
516  mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
517  mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
521 }
522 
524 {
525  delete mRenderer;
526  delete mModel;
527  delete mGraduatedSymbol;
528 }
529 
531 {
532  return mRenderer;
533 }
534 
535 // Connect/disconnect event handlers which trigger updating renderer
536 
538 {
539  connect( spinGraduatedClasses, SIGNAL( valueChanged( int ) ), this, SLOT( classifyGraduated() ) );
540  connect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ), this, SLOT( classifyGraduated() ) );
541  connect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ), this, SLOT( reapplyColorRamp() ) );
542  connect( cboGraduatedColorRamp, SIGNAL( sourceRampEdited() ), this, SLOT( reapplyColorRamp() ) );
543  connect( mButtonEditRamp, SIGNAL( clicked() ), cboGraduatedColorRamp, SLOT( editSourceRamp() ) );
544  connect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( reapplyColorRamp() ) );
545  connect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
546  connect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) );
547  connect( txtLegendFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) );
548  connect( minSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) );
549  connect( maxSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) );
550 
551  connect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) );
552  connect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
553 }
554 
555 // Connect/disconnect event handlers which trigger updating renderer
556 
558 {
559  disconnect( spinGraduatedClasses, SIGNAL( valueChanged( int ) ), this, SLOT( classifyGraduated() ) );
560  disconnect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ), this, SLOT( classifyGraduated() ) );
561  disconnect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ), this, SLOT( reapplyColorRamp() ) );
562  disconnect( cboGraduatedColorRamp, SIGNAL( sourceRampEdited() ), this, SLOT( reapplyColorRamp() ) );
563  disconnect( mButtonEditRamp, SIGNAL( clicked() ), cboGraduatedColorRamp, SLOT( editSourceRamp() ) );
564  disconnect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( reapplyColorRamp() ) );
565  disconnect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
566  disconnect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) );
567  disconnect( txtLegendFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) );
568  disconnect( minSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) );
569  disconnect( maxSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) );
570 
571  disconnect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) );
572  disconnect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
573 }
574 
576 {
578 
580 
581  // update UI from the graduated renderer (update combo boxes, view)
582  if ( mRenderer->mode() < cboGraduatedMode->count() )
583  cboGraduatedMode->setCurrentIndex( mRenderer->mode() );
584 
585  // Only update class count if different - otherwise typing value gets very messy
586  int nclasses = mRenderer->ranges().count();
587  if ( nclasses && updateCount )
588  spinGraduatedClasses->setValue( mRenderer->ranges().count() );
589 
590  // set column
591  QString attrName = mRenderer->classAttribute();
592  mExpressionWidget->setField( attrName );
593  mHistogramWidget->setSourceFieldExp( attrName );
594 
595  // set source symbol
596  if ( mRenderer->sourceSymbol() )
597  {
598  delete mGraduatedSymbol;
601  }
602 
603  mModel->setRenderer( mRenderer );
604  viewGraduated->setModel( mModel );
605 
606  if ( mGraduatedSymbol )
607  {
608  mSizeUnitWidget->blockSignals( true );
609  mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
610  mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
611  mSizeUnitWidget->blockSignals( false );
612  }
613 
614  // set source color ramp
615  methodComboBox->blockSignals( true );
617  {
618  methodComboBox->setCurrentIndex( 0 );
619  if ( mRenderer->sourceColorRamp() )
620  cboGraduatedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() );
621  cbxInvertedColorRamp->setChecked( mRenderer->invertedColorRamp() );
622  }
623  else
624  {
625  methodComboBox->setCurrentIndex( 1 );
626  if ( !mRenderer->ranges().isEmpty() ) // avoid overiding default size with zeros
627  {
628  minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
629  maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
630  }
631  }
632  mMethodStackedWidget->setCurrentIndex( methodComboBox->currentIndex() );
633  methodComboBox->blockSignals( false );
634 
636  txtLegendFormat->setText( labelFormat.format() );
637  spinPrecision->setValue( labelFormat.precision() );
638  cbxTrimTrailingZeroes->setChecked( labelFormat.trimTrailingZeroes() );
639 
640  viewGraduated->resizeColumnToContents( 0 );
641  viewGraduated->resizeColumnToContents( 1 );
642  viewGraduated->resizeColumnToContents( 2 );
643 
644  mHistogramWidget->refresh();
645 
647  emit widgetChanged();
648 }
649 
651 {
652  mRenderer->setClassAttribute( field );
653 }
654 
656 {
657  mMethodStackedWidget->setCurrentIndex( idx );
658  if ( idx == 0 )
659  {
661  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
662 
663  if ( !ramp )
664  {
665  if ( cboGraduatedColorRamp->count() == 0 )
666  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
667  else
668  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
669  return;
670  }
671  mRenderer->setSourceColorRamp( ramp );
673  }
674  else
675  {
677  reapplySizes();
678  }
679 }
680 
682 {
683  if ( !mModel )
684  return;
685 
686  mModel->updateSymbology( reset );
687  emit widgetChanged();
688 }
689 
690 void QgsGraduatedSymbolRendererV2Widget::cleanUpSymbolSelector( QgsPanelWidget *container )
691 {
692  if ( container )
693  {
694  QgsSymbolV2SelectorWidget* dlg = qobject_cast<QgsSymbolV2SelectorWidget*>( container );
695  delete dlg->symbol();
696  }
697 }
698 
699 void QgsGraduatedSymbolRendererV2Widget::updateSymbolsFromWidget()
700 {
702  delete mGraduatedSymbol;
703  mGraduatedSymbol = dlg->symbol()->clone();
704 
705  mSizeUnitWidget->blockSignals( true );
706  mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
707  mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
708  mSizeUnitWidget->blockSignals( false );
709 
710  QItemSelectionModel* m = viewGraduated->selectionModel();
711  QModelIndexList selectedIndexes = m->selectedRows( 1 );
712  if ( m && !selectedIndexes.isEmpty() )
713  {
714  Q_FOREACH ( const QModelIndex& idx, selectedIndexes )
715  {
716  if ( idx.isValid() )
717  {
718  int rangeIdx = idx.row();
719  QgsSymbolV2* newRangeSymbol = mGraduatedSymbol->clone();
720  newRangeSymbol->setColor( mRenderer->ranges()[rangeIdx].symbol()->color() );
721  mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
722  }
723  }
724  }
725  else
726  {
728  mRenderer->updateSymbols( mGraduatedSymbol );
729  }
730 
732  emit widgetChanged();
733 }
734 
735 
737 {
738  QString attrName = mExpressionWidget->currentField();
739 
740  int nclasses = spinGraduatedClasses->value();
741 
742  QSharedPointer<QgsVectorColorRampV2> ramp( cboGraduatedColorRamp->currentColorRamp() );
743  if ( !ramp )
744  {
745  if ( cboGraduatedColorRamp->count() == 0 )
746  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
747  else
748  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
749  return;
750  }
751 
753  if ( cboGraduatedMode->currentIndex() == 0 )
755  else if ( cboGraduatedMode->currentIndex() == 2 )
757  else if ( cboGraduatedMode->currentIndex() == 3 )
759  else if ( cboGraduatedMode->currentIndex() == 4 )
761  else // default should be quantile for now
763 
764  // Jenks is n^2 complexity, warn for big dataset (more than 50k records)
765  // and give the user the chance to cancel
766  if ( QgsGraduatedSymbolRendererV2::Jenks == mode && mLayer->featureCount() > 50000 )
767  {
768  if ( QMessageBox::Cancel == QMessageBox::question( this, tr( "Warning" ), tr( "Natural break classification (Jenks) is O(n2) complexity, your classification may take a long time.\nPress cancel to abort breaks calculation or OK to continue." ), QMessageBox::Cancel, QMessageBox::Ok ) )
769  return;
770  }
771 
772  // create and set new renderer
773 
774  mRenderer->setClassAttribute( attrName );
775  mRenderer->setMode( mode );
776 
777  if ( methodComboBox->currentIndex() == 0 )
778  {
779  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
780 
781  if ( !ramp )
782  {
783  if ( cboGraduatedColorRamp->count() == 0 )
784  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
785  else
786  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
787  return;
788  }
789  mRenderer->setSourceColorRamp( ramp );
790  }
791  else
792  {
793  mRenderer->setSourceColorRamp( nullptr );
794  }
795 
796  QApplication::setOverrideCursor( Qt::WaitCursor );
797  mRenderer->updateClasses( mLayer, mode, nclasses );
798 
799  if ( methodComboBox->currentIndex() == 1 )
800  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
801 
804  // PrettyBreaks and StdDev calculation don't generate exact
805  // number of classes - leave user interface unchanged for these
806  updateUiFromRenderer( false );
807 }
808 
810 {
811  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
812  if ( !ramp )
813  return;
814 
815  mRenderer->updateColorRamp( ramp, cbxInvertedColorRamp->isChecked() );
818 }
819 
821 {
822  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
825 }
826 
828 {
829  QgsSymbolV2* newSymbol = mGraduatedSymbol->clone();
830  QgsSymbolV2SelectorWidget* dlg = new QgsSymbolV2SelectorWidget( newSymbol, mStyle, mLayer, nullptr );
831  dlg->setMapCanvas( mMapCanvas );
832 
833  connect( dlg, SIGNAL( widgetChanged() ), this, SLOT( updateSymbolsFromWidget() ) );
834  connect( dlg, SIGNAL( accepted( QgsPanelWidget* ) ), this, SLOT( cleanUpSymbolSelector( QgsPanelWidget* ) ) );
835  openPanel( dlg );
836 }
837 
839 {
840  if ( !mGraduatedSymbol )
841  return;
842 
843  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mGraduatedSymbol, btnChangeGraduatedSymbol->iconSize() );
844  btnChangeGraduatedSymbol->setIcon( icon );
845 }
846 
847 #if 0
848 int QgsRendererV2PropertiesDialog::currentRangeRow()
849 {
850  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
851  if ( !idx.isValid() )
852  return -1;
853  return idx.row();
854 }
855 #endif
856 
858 {
859  QList<int> rows;
860  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
861 
862  Q_FOREACH ( const QModelIndex& r, selectedRows )
863  {
864  if ( r.isValid() )
865  {
866  rows.append( r.row() );
867  }
868  }
869  return rows;
870 }
871 
873 {
875  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
876  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
877 
878  for ( ; sIt != selectedRows.constEnd(); ++sIt )
879  {
880  selectedRanges.append( mModel->rendererRange( *sIt ) );
881  }
882  return selectedRanges;
883 }
884 
886 {
887  if ( idx.isValid() && idx.column() == 0 )
888  changeRangeSymbol( idx.row() );
889  if ( idx.isValid() && idx.column() == 1 )
890  changeRange( idx.row() );
891 }
892 
894 {
895  if ( !idx.isValid() )
896  mRowSelected = -1;
897  else
898  mRowSelected = idx.row();
899 }
900 
902 {
903 }
904 
906 {
907  QgsSymbolV2* newSymbol = mRenderer->ranges()[rangeIdx].symbol()->clone();
908  QgsSymbolV2SelectorWidget* dlg = new QgsSymbolV2SelectorWidget( newSymbol, mStyle, mLayer, nullptr );
909  dlg->setDockMode( this->dockMode() );
910  dlg->setMapCanvas( mMapCanvas );
911 
912  connect( dlg, SIGNAL( widgetChanged() ), this, SLOT( updateSymbolsFromWidget() ) );
913  connect( dlg, SIGNAL( accepted( QgsPanelWidget* ) ), this, SLOT( cleanUpSymbolSelector( QgsPanelWidget* ) ) );
914  openPanel( dlg );
915 }
916 
918 {
919  QgsLUDialog dialog( this );
920 
921  const QgsRendererRangeV2& range = mRenderer->ranges()[rangeIdx];
922  // Add arbitrary 2 to number of decimal places to retain a bit extra.
923  // Ensures users can see if legend is not completely honest!
924  int decimalPlaces = mRenderer->labelFormat().precision() + 2;
925  if ( decimalPlaces < 0 ) decimalPlaces = 0;
926  dialog.setLowerValue( QString::number( range.lowerValue(), 'f', decimalPlaces ) );
927  dialog.setUpperValue( QString::number( range.upperValue(), 'f', decimalPlaces ) );
928 
929  if ( dialog.exec() == QDialog::Accepted )
930  {
931  double lowerValue = dialog.lowerValue().toDouble();
932  double upperValue = dialog.upperValue().toDouble();
933  mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
934  mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
935 
936  //If the boundaries have to stay linked, we update the ranges above and below, as well as their label if needed
937  if ( cbxLinkBoundaries->isChecked() )
938  {
939  if ( rangeIdx > 0 )
940  {
941  mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
942  }
943 
944  if ( rangeIdx < mRenderer->ranges().size() - 1 )
945  {
946  mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
947  }
948  }
949  }
950  mHistogramWidget->refresh();
951  emit widgetChanged();
952 }
953 
955 {
956  mModel->addClass( mGraduatedSymbol );
957  mHistogramWidget->refresh();
958 }
959 
961 {
962  QList<int> classIndexes = selectedClasses();
963  mModel->deleteRows( classIndexes );
964  mHistogramWidget->refresh();
965 }
966 
968 {
969  mModel->removeAllRows();
970  mHistogramWidget->refresh();
971 }
972 
974 {
975  const QgsRangeList &ranges = mRenderer->ranges();
976  bool ordered = true;
977  for ( int i = 1;i < ranges.size();++i )
978  {
979  if ( ranges[i] < ranges[i-1] )
980  {
981  ordered = false;
982  break;
983  }
984  }
985  return ordered;
986 }
987 
989 {
990  //If the checkbox controlling the link between boundaries was unchecked and we check it, we have to link the boundaries
991  //This is done by updating all lower ranges to the upper value of the range above
992  if ( linked )
993  {
994  if ( ! rowsOrdered() )
995  {
996  int result = QMessageBox::warning(
997  this,
998  tr( "Linked range warning" ),
999  tr( "Rows will be reordered before linking boundaries. Continue?" ),
1000  QMessageBox::Ok | QMessageBox::Cancel );
1001  if ( result != QMessageBox::Ok )
1002  {
1003  cbxLinkBoundaries->setChecked( false );
1004  return;
1005  }
1007  }
1008 
1009  // Ok to proceed
1010  for ( int i = 1;i < mRenderer->ranges().size();++i )
1011  {
1012  mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i-1].upperValue() );
1013  }
1015  }
1016 }
1017 
1019 {
1020  if ( item->column() == 2 )
1021  {
1022  QString label = item->text();
1023  int idx = item->row();
1024  mRenderer->updateRangeLabel( idx, label );
1025  }
1026 }
1027 
1029 {
1030  mRenderer->setSizeScaleField( fldName );
1031 }
1032 
1034 {
1035  mRenderer->setScaleMethod( scaleMethod );
1036 }
1037 
1039 {
1041  txtLegendFormat->text(),
1042  spinPrecision->value(),
1043  cbxTrimTrailingZeroes->isChecked() );
1044  mRenderer->setLabelFormat( labelFormat, true );
1045  mModel->updateLabels();
1046 }
1047 
1048 
1050 {
1052 
1053  QItemSelectionModel* m = viewGraduated->selectionModel();
1054  QModelIndexList selectedIndexes = m->selectedRows( 1 );
1055  if ( m && !selectedIndexes.isEmpty() )
1056  {
1057  const QgsRangeList& ranges = mRenderer->ranges();
1058  QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1059  for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1060  {
1061  QStringList list = m->model()->data( *indexIt ).toString().split( ' ' );
1062  if ( list.size() < 3 )
1063  {
1064  continue;
1065  }
1066 
1067  double lowerBound = list.at( 0 ).toDouble();
1068  double upperBound = list.at( 2 ).toDouble();
1069  QgsSymbolV2* s = findSymbolForRange( lowerBound, upperBound, ranges );
1070  if ( s )
1071  {
1072  selectedSymbols.append( s );
1073  }
1074  }
1075  }
1076  return selectedSymbols;
1077 }
1078 
1079 QgsSymbolV2* QgsGraduatedSymbolRendererV2Widget::findSymbolForRange( double lowerBound, double upperBound, const QgsRangeList& ranges ) const
1080 {
1081  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1082  {
1083  //range string has been created with option 'f',4
1084  if ( qgsDoubleNear( lowerBound, it->lowerValue(), 0.0001 ) && qgsDoubleNear( upperBound, it->upperValue(), 0.0001 ) )
1085  {
1086  return it->symbol();
1087  }
1088  }
1089  return nullptr;
1090 }
1091 
1093 {
1094  if ( mModel )
1095  {
1096  mModel->updateSymbology();
1097  }
1098  mHistogramWidget->refresh();
1099  emit widgetChanged();
1100 }
1101 
1103 {
1105 }
1106 
1108 {
1109  viewGraduated->selectionModel()->clear();
1110  if ( ! rowsOrdered() )
1111  {
1112  cbxLinkBoundaries->setChecked( false );
1113  }
1114  emit widgetChanged();
1115 }
1116 
1118 {
1119  emit widgetChanged();
1120 }
1121 
1123 {
1124  if ( !event )
1125  {
1126  return;
1127  }
1128 
1129  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1130  {
1131  mCopyBuffer.clear();
1133  }
1134  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1135  {
1137  for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1138  {
1139  mModel->addClass( *rIt );
1140  }
1141  emit widgetChanged();
1142  }
1143 }
void customContextMenuRequested(const QPoint &pos)
void addClass()
Adds a class manually to the classification.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void showSymbolLevelsDialog(QgsFeatureRendererV2 *r)
show a dialog with renderer&#39;s symbol level settings
QList< QgsRendererRangeV2 > QgsRangeList
void clear()
Symbol selector widget that cna be used to select and build a symbol.
static unsigned index
void setSymbolSizes(double minSize, double maxSize)
set varying symbol size for classes
void setupUi(QWidget *widget)
QByteArray data(const QString &mimeType) const
bool dockMode()
Return the dock mode state.
void setLabelFormat(const QgsRendererRangeV2LabelFormat &labelFormat, bool updateRanges=false)
Set the label format used to generate default classification labels.
static QgsGraduatedSymbolRendererV2 * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsGraduatedSymbolRendererV2 from an existing renderer.
QgsGraduatedSymbolRendererV2Widget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the dialog.
void updateClasses(QgsVectorLayer *vlayer, Mode mode, int nclasses)
Recalculate classes for a layer.
QString upperValue() const
Definition: qgsludialog.cpp:37
void append(const T &value)
SymbolType type() const
Definition: qgssymbolv2.h:104
void keyPressEvent(QKeyEvent *event) override
Overriden key press event to handle the esc event on the widget.
static QgsExpressionContextScope * atlasScope(const QgsAtlasComposition *atlas)
Creates a new scope which contains variables and functions relating to a QgsAtlasComposition.
void toggleBoundariesLink(bool linked)
Toggle the link between classes boundaries.
void updateSymbols(QgsSymbolV2 *sym)
Update all the symbols but leave breaks and colors.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
virtual bool hasFormat(const QString &mimeType) const
QObject * sender() const
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
virtual QgsSymbolV2 * clone() const =0
QStyle * style() const
QgsSymbolV2 * symbol()
Return the symbol that is currently active in the widget.
bool updateRangeRenderState(int rangeIndex, bool render)
The output shall be in pixels.
Definition: qgssymbolv2.h:67
const T & at(int i) const
void addAction(QAction *action)
void setSizeScaleField(const QString &fieldOrExpression)
QgsMapCanvas * mMapCanvas
QgsMapUnitScale mapUnitScale() const
double minSymbolSize() const
return the min symbol size when graduated by size
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
int exec()
void updateColorRamp(QgsVectorColorRampV2 *ramp=nullptr, bool inverted=false)
Update the color ramp used.
Line symbol.
Definition: qgssymbolv2.h:79
Base class for any widget that can be shown as a inline panel.
void calculateLabelPrecision(bool updateRanges=true)
Reset the label decimal places to a numberbased on the minimum class interval.
const QPixmap * icon() const
virtual QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
void scaleMethodChanged(QgsSymbolV2::ScaleMethod scaleMethod)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
void setLowerValue(const QString &val)
Definition: qgsludialog.cpp:42
double toDouble(bool *ok) const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString text() const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:352
QgsVectorColorRampV2 * sourceColorRamp()
Returns the source color ramp, from which each classes&#39; color is derived.
Marker symbol.
Definition: qgssymbolv2.h:78
int size() const
void setMapUnitScale(const QgsMapUnitScale &scale)
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs...
T value(int i) const
The QgsMapSettings class contains configuration for rendering of the map.
QgsSymbolV2 * findSymbolForRange(double lowerBound, double upperBound, const QgsRangeList &ranges) const
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
QSize size() const
void setColor(const QColor &color)
bool isValid() const
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=nullptr) const
The output shall be in millimeters.
Definition: qgssymbolv2.h:64
QString number(int n, int base)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
int count(const T &value) const
QgsVectorLayer * mLayer
void setGraduatedMethod(GraduatedMethod method)
set the method used for graduation (either size or color)
void append(const T &value)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
StandardButton question(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QgsExpressionContext _getExpressionContext(const void *context)
const QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QModelIndexList selectedRows(int column) const
int row() const
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
QgsSymbolV2 * sourceSymbol()
Returns the renderer&#39;s source symbol, which is the base symbol used for the each classes&#39; symbol befo...
QgsSymbolV2 * symbol() const
GraduatedMethod graduatedMethod() const
return the method used for graduation (either size or color)
The output shall be in map unitx.
Definition: qgssymbolv2.h:65
void setOverrideCursor(const QCursor &cursor)
bool updateRangeLowerValue(int rangeIndex, double value)
void restoreOverrideCursor()
QGis::GeometryType geometryType() const
Returns point, line or polygon.
virtual QVariant data(const QModelIndex &index, int role) const =0
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Single scope for storing variables and functions for use within a QgsExpressionContext.
void widgetChanged()
Emiited when the widget state changes.
iterator end()
int key() const
const QgsRendererRangeV2LabelFormat & labelFormat() const
Return the label format used to generate default classification labels.
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
void contextMenuViewCategories(QPoint p)
void deleteClasses()
Removes currently selected classes.
void moveClass(int from, int to)
Moves the category at index position from to index position to.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object...
QgsExpressionContextScope & expressionContextScope()
Returns a reference to the expression context scope for the map canvas.
Definition: qgsmapcanvas.h:455
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
ScaleMethod
Scale method.
Definition: qgssymbolv2.h:87
typedef DropActions
double maxSymbolSize() const
return the max symbol size when graduated by size
const QgsRangeList & ranges() const
void setClassAttribute(const QString &attr)
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:382
void setUpperValue(const QString &val)
Definition: qgsludialog.cpp:47
bool updateRangeSymbol(int rangeIndex, QgsSymbolV2 *symbol)
QgsSymbolV2::OutputUnit outputUnit() const
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
int column() const
void setSourceColorRamp(QgsVectorColorRampV2 *ramp)
Sets the source color ramp.
int column() const
Base class for renderer settings widgets.
bool updateRangeUpperValue(int rangeIndex, double value)
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
void setData(const QString &mimeType, const QByteArray &data)
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
const_iterator constEnd() const
const_iterator constBegin() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
int size() const
Represents a vector layer which manages a vector based data sets.
Abstract base class for color ramps.
QList< QgsSymbolV2 * > selectedSymbols() override
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
QString toString() const
virtual bool event(QEvent *event)
const QAbstractItemModel * model() const
void setOutputUnit(QgsSymbolV2::OutputUnit u)
int row() const
iterator begin()
QString lowerValue() const
Definition: qgsludialog.cpp:32
QgsVectorLayer * layer()
Returns the layer currently associated with the widget.
void deleteAllClasses()
Removes all classes from the classification.
bool updateRangeLabel(int rangeIndex, const QString &label)
QList< int > selectedClasses()
return a list of indexes for the classes under selection
typedef ItemFlags