QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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  QgsSymbolV2SelectorWidget *dlg = qobject_cast<QgsSymbolV2SelectorWidget*>( container );
693  if ( !dlg )
694  return;
695 
696  dlg->releaseSymbol();
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  if ( selectedIndexes.count() > 1 )
721  {
722  //if updating multiple ranges, retain the existing range colors
723  newRangeSymbol->setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
724  }
725  mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
726  }
727  }
728  }
729  else
730  {
732  mRenderer->updateSymbols( mGraduatedSymbol );
733  }
734 
736  emit widgetChanged();
737 }
738 
739 
741 {
742  QString attrName = mExpressionWidget->currentField();
743 
744  int nclasses = spinGraduatedClasses->value();
745 
746  QSharedPointer<QgsVectorColorRampV2> ramp( cboGraduatedColorRamp->currentColorRamp() );
747  if ( !ramp )
748  {
749  if ( cboGraduatedColorRamp->count() == 0 )
750  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
751  else
752  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
753  return;
754  }
755 
757  if ( cboGraduatedMode->currentIndex() == 0 )
759  else if ( cboGraduatedMode->currentIndex() == 2 )
761  else if ( cboGraduatedMode->currentIndex() == 3 )
763  else if ( cboGraduatedMode->currentIndex() == 4 )
765  else // default should be quantile for now
767 
768  // Jenks is n^2 complexity, warn for big dataset (more than 50k records)
769  // and give the user the chance to cancel
770  if ( QgsGraduatedSymbolRendererV2::Jenks == mode && mLayer->featureCount() > 50000 )
771  {
772  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 ) )
773  return;
774  }
775 
776  // create and set new renderer
777 
778  mRenderer->setClassAttribute( attrName );
779  mRenderer->setMode( mode );
780 
781  if ( methodComboBox->currentIndex() == 0 )
782  {
783  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
784 
785  if ( !ramp )
786  {
787  if ( cboGraduatedColorRamp->count() == 0 )
788  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
789  else
790  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
791  return;
792  }
793  mRenderer->setSourceColorRamp( ramp );
794  }
795  else
796  {
797  mRenderer->setSourceColorRamp( nullptr );
798  }
799 
800  QApplication::setOverrideCursor( Qt::WaitCursor );
801  mRenderer->updateClasses( mLayer, mode, nclasses );
802 
803  if ( methodComboBox->currentIndex() == 1 )
804  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
805 
808  // PrettyBreaks and StdDev calculation don't generate exact
809  // number of classes - leave user interface unchanged for these
810  updateUiFromRenderer( false );
811 }
812 
814 {
815  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
816  if ( !ramp )
817  return;
818 
819  mRenderer->updateColorRamp( ramp, cbxInvertedColorRamp->isChecked() );
822 }
823 
825 {
826  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
829 }
830 
832 {
833  QgsSymbolV2* newSymbol = mGraduatedSymbol->clone();
834  QgsSymbolV2SelectorWidget* dlg = new QgsSymbolV2SelectorWidget( newSymbol, mStyle, mLayer, nullptr );
835  dlg->setMapCanvas( mMapCanvas );
836 
837  connect( dlg, SIGNAL( widgetChanged() ), this, SLOT( updateSymbolsFromWidget() ) );
838  connect( dlg, SIGNAL( accepted( QgsPanelWidget* ) ), this, SLOT( cleanUpSymbolSelector( QgsPanelWidget* ) ) );
839  openPanel( dlg );
840 }
841 
843 {
844  if ( !mGraduatedSymbol )
845  return;
846 
847  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mGraduatedSymbol, btnChangeGraduatedSymbol->iconSize() );
848  btnChangeGraduatedSymbol->setIcon( icon );
849 }
850 
851 #if 0
852 int QgsRendererV2PropertiesDialog::currentRangeRow()
853 {
854  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
855  if ( !idx.isValid() )
856  return -1;
857  return idx.row();
858 }
859 #endif
860 
862 {
863  QList<int> rows;
864  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
865 
866  Q_FOREACH ( const QModelIndex& r, selectedRows )
867  {
868  if ( r.isValid() )
869  {
870  rows.append( r.row() );
871  }
872  }
873  return rows;
874 }
875 
877 {
879  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
880  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
881 
882  for ( ; sIt != selectedRows.constEnd(); ++sIt )
883  {
884  selectedRanges.append( mModel->rendererRange( *sIt ) );
885  }
886  return selectedRanges;
887 }
888 
890 {
891  if ( idx.isValid() && idx.column() == 0 )
892  changeRangeSymbol( idx.row() );
893  if ( idx.isValid() && idx.column() == 1 )
894  changeRange( idx.row() );
895 }
896 
898 {
899  if ( !idx.isValid() )
900  mRowSelected = -1;
901  else
902  mRowSelected = idx.row();
903 }
904 
906 {
907 }
908 
910 {
911  QgsSymbolV2* newSymbol = mRenderer->ranges()[rangeIdx].symbol()->clone();
912  QgsSymbolV2SelectorWidget* dlg = new QgsSymbolV2SelectorWidget( newSymbol, mStyle, mLayer, nullptr );
913  dlg->setDockMode( this->dockMode() );
914  dlg->setMapCanvas( mMapCanvas );
915 
916  connect( dlg, SIGNAL( widgetChanged() ), this, SLOT( updateSymbolsFromWidget() ) );
917  connect( dlg, SIGNAL( accepted( QgsPanelWidget* ) ), this, SLOT( cleanUpSymbolSelector( QgsPanelWidget* ) ) );
918  openPanel( dlg );
919 }
920 
922 {
923  QgsLUDialog dialog( this );
924 
925  const QgsRendererRangeV2& range = mRenderer->ranges()[rangeIdx];
926  // Add arbitrary 2 to number of decimal places to retain a bit extra.
927  // Ensures users can see if legend is not completely honest!
928  int decimalPlaces = mRenderer->labelFormat().precision() + 2;
929  if ( decimalPlaces < 0 ) decimalPlaces = 0;
930  dialog.setLowerValue( QString::number( range.lowerValue(), 'f', decimalPlaces ) );
931  dialog.setUpperValue( QString::number( range.upperValue(), 'f', decimalPlaces ) );
932 
933  if ( dialog.exec() == QDialog::Accepted )
934  {
935  double lowerValue = dialog.lowerValue().toDouble();
936  double upperValue = dialog.upperValue().toDouble();
937  mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
938  mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
939 
940  //If the boundaries have to stay linked, we update the ranges above and below, as well as their label if needed
941  if ( cbxLinkBoundaries->isChecked() )
942  {
943  if ( rangeIdx > 0 )
944  {
945  mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
946  }
947 
948  if ( rangeIdx < mRenderer->ranges().size() - 1 )
949  {
950  mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
951  }
952  }
953  }
954  mHistogramWidget->refresh();
955  emit widgetChanged();
956 }
957 
959 {
960  mModel->addClass( mGraduatedSymbol );
961  mHistogramWidget->refresh();
962 }
963 
965 {
966  QList<int> classIndexes = selectedClasses();
967  mModel->deleteRows( classIndexes );
968  mHistogramWidget->refresh();
969 }
970 
972 {
973  mModel->removeAllRows();
974  mHistogramWidget->refresh();
975 }
976 
978 {
979  const QgsRangeList &ranges = mRenderer->ranges();
980  bool ordered = true;
981  for ( int i = 1;i < ranges.size();++i )
982  {
983  if ( ranges[i] < ranges[i-1] )
984  {
985  ordered = false;
986  break;
987  }
988  }
989  return ordered;
990 }
991 
993 {
994  //If the checkbox controlling the link between boundaries was unchecked and we check it, we have to link the boundaries
995  //This is done by updating all lower ranges to the upper value of the range above
996  if ( linked )
997  {
998  if ( ! rowsOrdered() )
999  {
1000  int result = QMessageBox::warning(
1001  this,
1002  tr( "Linked range warning" ),
1003  tr( "Rows will be reordered before linking boundaries. Continue?" ),
1004  QMessageBox::Ok | QMessageBox::Cancel );
1005  if ( result != QMessageBox::Ok )
1006  {
1007  cbxLinkBoundaries->setChecked( false );
1008  return;
1009  }
1011  }
1012 
1013  // Ok to proceed
1014  for ( int i = 1;i < mRenderer->ranges().size();++i )
1015  {
1016  mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i-1].upperValue() );
1017  }
1019  }
1020 }
1021 
1023 {
1024  if ( item->column() == 2 )
1025  {
1026  QString label = item->text();
1027  int idx = item->row();
1028  mRenderer->updateRangeLabel( idx, label );
1029  }
1030 }
1031 
1033 {
1034  mRenderer->setSizeScaleField( fldName );
1035 }
1036 
1038 {
1039  mRenderer->setScaleMethod( scaleMethod );
1040 }
1041 
1043 {
1045  txtLegendFormat->text(),
1046  spinPrecision->value(),
1047  cbxTrimTrailingZeroes->isChecked() );
1048  mRenderer->setLabelFormat( labelFormat, true );
1049  mModel->updateLabels();
1050 }
1051 
1052 
1054 {
1056 
1057  QItemSelectionModel* m = viewGraduated->selectionModel();
1058  QModelIndexList selectedIndexes = m->selectedRows( 1 );
1059  if ( m && !selectedIndexes.isEmpty() )
1060  {
1061  const QgsRangeList& ranges = mRenderer->ranges();
1062  QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1063  for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1064  {
1065  QStringList list = m->model()->data( *indexIt ).toString().split( ' ' );
1066  if ( list.size() < 3 )
1067  {
1068  continue;
1069  }
1070 
1071  double lowerBound = list.at( 0 ).toDouble();
1072  double upperBound = list.at( 2 ).toDouble();
1073  QgsSymbolV2* s = findSymbolForRange( lowerBound, upperBound, ranges );
1074  if ( s )
1075  {
1076  selectedSymbols.append( s );
1077  }
1078  }
1079  }
1080  return selectedSymbols;
1081 }
1082 
1083 QgsSymbolV2* QgsGraduatedSymbolRendererV2Widget::findSymbolForRange( double lowerBound, double upperBound, const QgsRangeList& ranges ) const
1084 {
1085  int decimalPlaces = mRenderer->labelFormat().precision() + 2;
1086  if ( decimalPlaces < 0 )
1087  decimalPlaces = 0;
1088  double precision = 1.0 / qPow( 10, decimalPlaces );
1089 
1090  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1091  {
1092  if ( qgsDoubleNear( lowerBound, it->lowerValue(), precision ) && qgsDoubleNear( upperBound, it->upperValue(), precision ) )
1093  {
1094  return it->symbol();
1095  }
1096  }
1097  return nullptr;
1098 }
1099 
1101 {
1102  if ( mModel )
1103  {
1104  mModel->updateSymbology();
1105  }
1106  mHistogramWidget->refresh();
1107  emit widgetChanged();
1108 }
1109 
1111 {
1113 }
1114 
1116 {
1117  viewGraduated->selectionModel()->clear();
1118  if ( ! rowsOrdered() )
1119  {
1120  cbxLinkBoundaries->setChecked( false );
1121  }
1122  emit widgetChanged();
1123 }
1124 
1126 {
1127  emit widgetChanged();
1128 }
1129 
1131 {
1132  if ( !event )
1133  {
1134  return;
1135  }
1136 
1137  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1138  {
1139  mCopyBuffer.clear();
1141  }
1142  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1143  {
1145  for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1146  {
1147  mModel->addClass( *rIt );
1148  }
1149  emit widgetChanged();
1150  }
1151 }
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()
const QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
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
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=nullptr) 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.
void append(const T &value)
void releaseSymbol()
Delete the symbol.
void keyPressEvent(QKeyEvent *event) override
Overridden 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
GraduatedMethod graduatedMethod() const
return the method used for graduation (either size or color)
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:70
const T & at(int i) const
void addAction(QAction *action)
void setSizeScaleField(const QString &fieldOrExpression)
QgsMapCanvas * mMapCanvas
QgsSymbolV2 * findSymbolForRange(double lowerBound, double upperBound, const QgsRangeList &ranges) const
int exec()
SymbolType type() const
Definition: qgssymbolv2.h:107
void updateColorRamp(QgsVectorColorRampV2 *ramp=nullptr, bool inverted=false)
Update the color ramp used.
Line symbol.
Definition: qgssymbolv2.h:82
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:353
QgsVectorColorRampV2 * sourceColorRamp()
Returns the source color ramp, from which each classes&#39; color is derived.
Marker symbol.
Definition: qgssymbolv2.h:81
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.
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
QSize size() const
void setColor(const QColor &color)
bool isValid() const
The output shall be in millimeters.
Definition: qgssymbolv2.h:67
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)
const QgsRangeList & ranges() const
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QgsExpressionContext _getExpressionContext(const void *context)
QModelIndexList selectedRows(int column) const
int row() const
QgsSymbolV2 * sourceSymbol()
Returns the renderer&#39;s source symbol, which is the base symbol used for the each classes&#39; symbol befo...
The output shall be in map unitx.
Definition: qgssymbolv2.h:68
void setOverrideCursor(const QCursor &cursor)
bool updateRangeLowerValue(int rangeIndex, double value)
void restoreOverrideCursor()
virtual QVariant data(const QModelIndex &index, int role) const=0
QGis::GeometryType geometryType() const
Returns point, line or polygon.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Single scope for storing variables and functions for use within a QgsExpressionContext.
QgsMapUnitScale mapUnitScale() const
void widgetChanged()
Emitted when the widget state changes.
iterator end()
int key() const
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void contextMenuViewCategories(QPoint p)
QgsSymbolV2::OutputUnit outputUnit() const
void deleteClasses()
Removes currently selected classes.
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
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
const QgsRendererRangeV2LabelFormat & labelFormat() const
Return the label format used to generate default classification labels.
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
ScaleMethod
Scale method.
Definition: qgssymbolv2.h:90
typedef DropActions
void setClassAttribute(const QString &attr)
double minSymbolSize() const
return the min symbol size when graduated by size
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)
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
double maxSymbolSize() const
return the max symbol size when graduated by size
int column() const
void setSourceColorRamp(QgsVectorColorRampV2 *ramp)
Sets the source color ramp.
int column() const
Base class for renderer settings widgets.
QString lowerValue() const
Definition: qgsludialog.cpp:32
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)
QString upperValue() const
Definition: qgsludialog.cpp:37
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()
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