QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
17 #include "qgssymbolv2.h"
18 #include "qgssymbollayerv2utils.h"
19 #include "qgsvectorcolorrampv2.h"
20 #include "qgsstylev2.h"
21 
22 #include "qgsvectorlayer.h"
23 
26 
27 #include "qgsludialog.h"
28 
29 #include "qgsproject.h"
30 
31 #include <QKeyEvent>
32 #include <QMenu>
33 #include <QMessageBox>
34 #include <QStandardItemModel>
35 #include <QStandardItem>
36 #include <QPen>
37 #include <QPainter>
38 
39 // ------------------------------ Model ------------------------------------
40 
41 QgsGraduatedSymbolRendererV2Model::QgsGraduatedSymbolRendererV2Model( QObject * parent ) : QAbstractItemModel( parent )
42  , mRenderer( 0 )
43  , mMimeFormat( "application/x-qgsgraduatedsymbolrendererv2model" )
44 {
45 }
46 
48 {
49  if ( mRenderer )
50  {
51  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
52  mRenderer = 0;
53  endRemoveRows();
54  }
55  if ( renderer )
56  {
57  beginInsertRows( QModelIndex(), 0, renderer->ranges().size() - 1 );
58  mRenderer = renderer;
59  endInsertRows();
60  }
61 }
62 
64 {
65  if ( !mRenderer ) return;
66  int idx = mRenderer->ranges().size();
67  beginInsertRows( QModelIndex(), idx, idx );
68  mRenderer->addClass( symbol );
69  endInsertRows();
70 }
71 
73 {
74  if ( !mRenderer )
75  {
76  return;
77  }
78  int idx = mRenderer->ranges().size();
79  beginInsertRows( QModelIndex(), idx, idx );
80  mRenderer->addClass( range );
81  endInsertRows();
82 }
83 
85 {
86  if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
87  {
88  return QgsRendererRangeV2();
89  }
90 
91  return mRenderer->ranges().value( index.row() );
92 }
93 
94 Qt::ItemFlags QgsGraduatedSymbolRendererV2Model::flags( const QModelIndex & index ) const
95 {
96  if ( !index.isValid() )
97  {
98  return Qt::ItemIsDropEnabled;
99  }
100 
101  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
102 
103  if ( index.column() == 2 )
104  {
105  flags |= Qt::ItemIsEditable;
106  }
107 
108  return flags;
109 }
110 
112 {
113  return Qt::MoveAction;
114 }
115 
116 QVariant QgsGraduatedSymbolRendererV2Model::data( const QModelIndex &index, int role ) const
117 {
118  if ( !index.isValid() || !mRenderer ) return QVariant();
119 
120  const QgsRendererRangeV2 range = mRenderer->ranges().value( index.row() );
121  QString rangeStr = QString::number( range.lowerValue(), 'f', 4 ) + " - " + QString::number( range.upperValue(), 'f', 4 );
122 
123  if ( role == Qt::CheckStateRole && index.column() == 0 )
124  {
125  return range.renderState() ? Qt::Checked : Qt::Unchecked;
126  }
127  else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
128  {
129  switch ( index.column() )
130  {
131  case 1: return rangeStr;
132  case 2: return range.label();
133  default: return QVariant();
134  }
135  }
136  else if ( role == Qt::DecorationRole && index.column() == 0 && range.symbol() )
137  {
138  return QgsSymbolLayerV2Utils::symbolPreviewIcon( range.symbol(), QSize( 16, 16 ) );
139  }
140  else if ( role == Qt::TextAlignmentRole )
141  {
142  return ( index.column() == 0 ) ? Qt::AlignHCenter : Qt::AlignLeft;
143  }
144  else if ( role == Qt::EditRole )
145  {
146  switch ( index.column() )
147  {
148  case 1: return rangeStr;
149  case 2: return range.label();
150  default: return QVariant();
151  }
152  }
153 
154  return QVariant();
155 }
156 
157 bool QgsGraduatedSymbolRendererV2Model::setData( const QModelIndex & index, const QVariant & value, int role )
158 {
159  if ( !index.isValid() )
160  return false;
161 
162  if ( index.column() == 0 && role == Qt::CheckStateRole )
163  {
164  mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
165  emit dataChanged( index, index );
166  return true;
167  }
168 
169  if ( role != Qt::EditRole )
170  return false;
171 
172  switch ( index.column() )
173  {
174  case 1: // range
175  return false; // range is edited in popup dialog
176  break;
177  case 2: // label
178  mRenderer->updateRangeLabel( index.row(), value.toString() );
179  break;
180  default:
181  return false;
182  }
183 
184  emit dataChanged( index, index );
185  return true;
186 }
187 
188 QVariant QgsGraduatedSymbolRendererV2Model::headerData( int section, Qt::Orientation orientation, int role ) const
189 {
190  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
191  {
192  QStringList lst; lst << tr( "Symbol" ) << tr( "Value" ) << tr( "Label" );
193  return lst.value( section );
194  }
195  return QVariant();
196 }
197 
198 int QgsGraduatedSymbolRendererV2Model::rowCount( const QModelIndex &parent ) const
199 {
200  if ( parent.isValid() || !mRenderer )
201  {
202  return 0;
203  }
204  return mRenderer->ranges().size();
205 }
206 
208 {
209  Q_UNUSED( index );
210  return 3;
211 }
212 
213 QModelIndex QgsGraduatedSymbolRendererV2Model::index( int row, int column, const QModelIndex &parent ) const
214 {
215  if ( hasIndex( row, column, parent ) )
216  {
217  return createIndex( row, column, 0 );
218  }
219  return QModelIndex();
220 }
221 
222 QModelIndex QgsGraduatedSymbolRendererV2Model::parent( const QModelIndex &index ) const
223 {
224  Q_UNUSED( index );
225  return QModelIndex();
226 }
227 
229 {
230  QStringList types;
231  types << mMimeFormat;
232  return types;
233 }
234 
235 QMimeData *QgsGraduatedSymbolRendererV2Model::mimeData( const QModelIndexList &indexes ) const
236 {
237  QMimeData *mimeData = new QMimeData();
238  QByteArray encodedData;
239 
240  QDataStream stream( &encodedData, QIODevice::WriteOnly );
241 
242  // Create list of rows
243  foreach ( const QModelIndex &index, indexes )
244  {
245  if ( !index.isValid() || index.column() != 0 )
246  continue;
247 
248  stream << index.row();
249  }
250  mimeData->setData( mMimeFormat, encodedData );
251  return mimeData;
252 }
253 
254 bool QgsGraduatedSymbolRendererV2Model::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
255 {
256  Q_UNUSED( row );
257  Q_UNUSED( column );
258  if ( action != Qt::MoveAction ) return true;
259 
260  if ( !data->hasFormat( mMimeFormat ) ) return false;
261 
262  QByteArray encodedData = data->data( mMimeFormat );
263  QDataStream stream( &encodedData, QIODevice::ReadOnly );
264 
265  QVector<int> rows;
266  while ( !stream.atEnd() )
267  {
268  int r;
269  stream >> r;
270  rows.append( r );
271  }
272 
273  int to = parent.row();
274  // to is -1 if dragged outside items, i.e. below any item,
275  // then move to the last position
276  if ( to == -1 ) to = mRenderer->ranges().size(); // out of rang ok, will be decreased
277  for ( int i = rows.size() - 1; i >= 0; i-- )
278  {
279  QgsDebugMsg( QString( "move %1 to %2" ).arg( rows[i] ).arg( to ) );
280  int t = to;
281  // moveCategory first removes and then inserts
282  if ( rows[i] < to ) t--;
283  mRenderer->moveClass( rows[i], t );
284  // current moved under another, shift its index up
285  for ( int j = 0; j < i; j++ )
286  {
287  if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
288  }
289  // removed under 'to' so the target shifted down
290  if ( rows[i] < to ) to--;
291  }
292  emit dataChanged( createIndex( 0, 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
293  emit rowsMoved();
294  return false;
295 }
296 
298 {
299  for ( int i = rows.size() - 1; i >= 0; i-- )
300  {
301  beginRemoveRows( QModelIndex(), rows[i], rows[i] );
302  mRenderer->deleteClass( rows[i] );
303  endRemoveRows();
304  }
305 }
306 
308 {
309  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
311  endRemoveRows();
312 }
313 
314 void QgsGraduatedSymbolRendererV2Model::sort( int column, Qt::SortOrder order )
315 {
316  QgsDebugMsg( "Entered" );
317  if ( column == 0 )
318  {
319  return;
320  }
321  if ( column == 1 )
322  {
323  mRenderer->sortByValue( order );
324  }
325  else if ( column == 2 )
326  {
327  mRenderer->sortByLabel( order );
328  }
329  emit dataChanged( createIndex( 0, 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
330  QgsDebugMsg( "Done" );
331 }
332 
333 // ------------------------------ View style --------------------------------
335  : QProxyStyle( style )
336 {}
337 
338 void QgsGraduatedSymbolRendererV2ViewStyle::drawPrimitive( PrimitiveElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget ) const
339 {
340  if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
341  {
342  QStyleOption opt( *option );
343  opt.rect.setLeft( 0 );
344  // draw always as line above, because we move item to that index
345  opt.rect.setHeight( 0 );
346  if ( widget ) opt.rect.setRight( widget->width() );
347  QProxyStyle::drawPrimitive( element, &opt, painter, widget );
348  return;
349  }
350  QProxyStyle::drawPrimitive( element, option, painter, widget );
351 }
352 
353 // ------------------------------ Widget ------------------------------------
354 
356 {
357  return new QgsGraduatedSymbolRendererV2Widget( layer, style, renderer );
358 }
359 
361  : QgsRendererV2Widget( layer, style )
362  , mRenderer( 0 )
363  , mModel( 0 )
364 {
365 
366  // try to recognize the previous renderer
367  // (null renderer means "no previous renderer")
368  if ( !renderer || renderer->type() != "graduatedSymbol" )
369  {
370  // we're not going to use it - so let's delete the renderer
371  delete renderer;
372 
374  }
375  else
376  {
378  }
379 
380  // setup user interface
381  setupUi( this );
382 
383  mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date );
384  mExpressionWidget->setLayer( mLayer );
385 
386  cboGraduatedColorRamp->populate( mStyle );
387 
388  // set project default color ramp
389  QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" );
390  if ( defaultColorRamp != "" )
391  {
392  int index = cboGraduatedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive );
393  if ( index >= 0 )
394  cboGraduatedColorRamp->setCurrentIndex( index );
395  }
396 
399  viewGraduated->setModel( mModel );
400  viewGraduated->resizeColumnToContents( 0 );
401  viewGraduated->resizeColumnToContents( 1 );
402  viewGraduated->resizeColumnToContents( 2 );
403 
404  viewGraduated->setStyle( new QgsGraduatedSymbolRendererV2ViewStyle( viewGraduated->style() ) );
405 
407 
408  connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) );
409  connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) );
410  connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) );
411  connect( viewGraduated, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) );
412 
413  connect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) );
414 
415  connect( btnGraduatedClassify, SIGNAL( clicked() ), this, SLOT( classifyGraduated() ) );
416  connect( btnChangeGraduatedSymbol, SIGNAL( clicked() ), this, SLOT( changeGraduatedSymbol() ) );
417  connect( btnGraduatedDelete, SIGNAL( clicked() ), this, SLOT( deleteClasses() ) );
418  connect( btnDeleteAllClasses, SIGNAL( clicked() ), this, SLOT( deleteAllClasses() ) );
419  connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) );
420 
421  // initialize from previously set renderer
423 
424  connect( spinGraduatedClasses, SIGNAL( valueChanged( int ) ) , this, SLOT( classifyGraduated() ) );
425  connect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( classifyGraduated() ) );
426  connect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( reapplyColorRamp() ) );
427 
428  // menus for data-defined rotation/size
429  QMenu* advMenu = new QMenu;
430 
431  advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );
432 
435  connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
436  connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
438  btnAdvanced->setMenu( advMenu );
439 }
440 
442 {
443  delete mRenderer;
444  delete mModel;
445 }
446 
448 {
449  return mRenderer;
450 }
451 
452 
454 {
456 
457  // update UI from the graduated renderer (update combo boxes, view)
458  if ( mRenderer->mode() < cboGraduatedMode->count() )
459  cboGraduatedMode->setCurrentIndex( mRenderer->mode() );
460  if ( mRenderer->ranges().count() )
461  spinGraduatedClasses->setValue( mRenderer->ranges().count() );
462 
463  // set column
464  disconnect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) );
465  QString attrName = mRenderer->classAttribute();
466  mExpressionWidget->setField( attrName );
467  connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) );
468 
469  // set source symbol
470  if ( mRenderer->sourceSymbol() )
471  {
472  delete mGraduatedSymbol;
475  }
476 
477  // set source color ramp
478  if ( mRenderer->sourceColorRamp() )
479  {
480  cboGraduatedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() );
481  cbxInvertedColorRamp->setChecked( mRenderer->invertedColorRamp() );
482  }
483 }
484 
486 {
487  mRenderer->setClassAttribute( field );
488 }
489 
491 {
492  QString attrName = mExpressionWidget->currentField();
493 
494  int classes = spinGraduatedClasses->value();
495 
496  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
497 
498  if ( ramp == NULL )
499  {
500  if ( cboGraduatedColorRamp->count() == 0 )
501  QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) );
502  else
503  QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) );
504  return;
505  }
506 
508  if ( cboGraduatedMode->currentIndex() == 0 )
510  else if ( cboGraduatedMode->currentIndex() == 2 )
512  else if ( cboGraduatedMode->currentIndex() == 3 )
514  else if ( cboGraduatedMode->currentIndex() == 4 )
516  else // default should be quantile for now
518 
519 
520  // Jenks is n^2 complexity, warn for big dataset (more than 50k records)
521  // and give the user the chance to cancel
523  && mLayer->featureCount() > 50000 )
524  {
525  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 ) ) return;
526  }
527 
528  // create and set new renderer
529  QApplication::setOverrideCursor( Qt::WaitCursor );
531  mLayer, attrName, classes, mode, mGraduatedSymbol, ramp, cbxInvertedColorRamp->isChecked() );
532  QApplication::restoreOverrideCursor();
533  if ( !r )
534  {
535  QMessageBox::critical( this, tr( "Error" ), tr( "Renderer creation has failed." ) );
536  return;
537  }
538 
542 
543  if ( mModel )
544  {
545  mModel->setRenderer( r );
546  }
547  delete mRenderer;
548  mRenderer = r;
549 }
550 
552 {
553  QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp();
554  if ( ramp == NULL )
555  return;
556 
557  mRenderer->updateColorRamp( ramp, cbxInvertedColorRamp->isChecked() );
559 }
560 
562 {
563  // Change the selected symbols alone if anything is selected
564  QItemSelectionModel* m = viewGraduated->selectionModel();
565  QModelIndexList i = m->selectedRows();
566  if ( m && i.size() > 0 )
567  {
569  return;
570  }
571 
572  // Otherwise change the base mGraduatedSymbol
573  QgsSymbolV2* newSymbol = mGraduatedSymbol->clone();
574 
575  QgsSymbolV2SelectorDialog dlg( newSymbol, mStyle, mLayer, this );
576  if ( !dlg.exec() )
577  {
578  delete newSymbol;
579  return;
580  }
581 
582  mGraduatedSymbol = newSymbol;
583 
587 }
588 
590 {
591  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mGraduatedSymbol, btnChangeGraduatedSymbol->iconSize() );
592  btnChangeGraduatedSymbol->setIcon( icon );
593 }
594 
595 #if 0
596 int QgsRendererV2PropertiesDialog::currentRangeRow()
597 {
598  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
599  if ( !idx.isValid() )
600  return -1;
601  return idx.row();
602 }
603 #endif
604 
606 {
607  QList<int> rows;
608  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
609 
610  foreach ( QModelIndex r, selectedRows )
611  {
612  if ( r.isValid() )
613  {
614  rows.append( r.row() );
615  }
616  }
617  return rows;
618 }
619 
621 {
623  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
624  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
625 
626  for ( ; sIt != selectedRows.constEnd(); ++sIt )
627  {
628  selectedRanges.append( mModel->rendererRange( *sIt ) );
629  }
630  return selectedRanges;
631 }
632 
634 {
635  if ( idx.isValid() && idx.column() == 0 )
636  changeRangeSymbol( idx.row() );
637  if ( idx.isValid() && idx.column() == 1 )
638  changeRange( idx.row() );
639 }
640 
642 {
643  if ( !idx.isValid() )
644  mRowSelected = -1;
645  else
646  mRowSelected = idx.row();
647 }
648 
649 
650 
652 {
653  QItemSelectionModel* m = viewGraduated->selectionModel();
654  QModelIndexList selectedIndexes = m->selectedRows( 1 );
655  if ( m && selectedIndexes.size() > 0 )
656  {
657  QgsSymbolV2* newSymbol = mGraduatedSymbol->clone();
658  QgsSymbolV2SelectorDialog dlg( newSymbol, mStyle, mLayer, this );
659  if ( !dlg.exec() )
660  {
661  delete newSymbol;
662  return;
663  }
664 
665  foreach ( QModelIndex idx, selectedIndexes )
666  {
667  if ( idx.isValid() )
668  {
669  int rangeIdx = idx.row();
670  QgsSymbolV2* newRangeSymbol = newSymbol->clone();
671  newRangeSymbol->setColor( mRenderer->ranges()[rangeIdx].symbol()->color() );
672  mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
673  }
674  }
675  }
677 }
678 
680 {
681  QgsSymbolV2* newSymbol = mRenderer->ranges()[rangeIdx].symbol()->clone();
682 
683  QgsSymbolV2SelectorDialog dlg( newSymbol, mStyle, mLayer, this );
684  if ( !dlg.exec() )
685  {
686  delete newSymbol;
687  return;
688  }
689 
690  mRenderer->updateRangeSymbol( rangeIdx, newSymbol );
691 }
692 
694 {
695  QgsLUDialog dialog( this );
696 
697  const QgsRendererRangeV2& range = mRenderer->ranges()[rangeIdx];
698  dialog.setLowerValue( QString::number( range.lowerValue(), 'f', 4 ) );
699  dialog.setUpperValue( QString::number( range.upperValue(), 'f', 4 ) );
700 
701  if ( dialog.exec() == QDialog::Accepted )
702  {
703  double lowerValue = dialog.lowerValue().toDouble();
704  double upperValue = dialog.upperValue().toDouble();
705  mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
706  mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
707  }
708 }
709 
711 {
713 }
714 
716 {
717  QList<int> classIndexes = selectedClasses();
718  mModel->deleteRows( classIndexes );
719 }
720 
722 {
724 }
725 
727 {
728  if ( item->column() == 2 )
729  {
730  QString label = item->text();
731  int idx = item->row();
732  mRenderer->updateRangeLabel( idx, label );
733  }
734 }
735 
737 {
738  mRenderer->setRotationField( fldName );
739 }
740 
742 {
743  mRenderer->setSizeScaleField( fldName );
744 }
745 
747 {
748  mRenderer->setScaleMethod( scaleMethod );
749 }
750 
752 {
753  QList<QgsSymbolV2*> selectedSymbols;
754 
755  QItemSelectionModel* m = viewGraduated->selectionModel();
756  QModelIndexList selectedIndexes = m->selectedRows( 1 );
757  if ( m && selectedIndexes.size() > 0 )
758  {
759  const QgsRangeList& ranges = mRenderer->ranges();
760  QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
761  for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
762  {
763  QStringList list = m->model()->data( *indexIt ).toString().split( " " );
764  if ( list.size() < 3 )
765  {
766  continue;
767  }
768 
769  double lowerBound = list.at( 0 ).toDouble();
770  double upperBound = list.at( 2 ).toDouble();
771  QgsSymbolV2* s = findSymbolForRange( lowerBound, upperBound, ranges );
772  if ( s )
773  {
774  selectedSymbols.append( s );
775  }
776  }
777  }
778  return selectedSymbols;
779 }
780 
781 QgsSymbolV2* QgsGraduatedSymbolRendererV2Widget::findSymbolForRange( double lowerBound, double upperBound, const QgsRangeList& ranges ) const
782 {
783  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
784  {
785  //range string has been created with option 'f',4
786  if ( qgsDoubleNear( lowerBound, it->lowerValue(), 0.0001 ) && qgsDoubleNear( upperBound, it->upperValue(), 0.0001 ) )
787  {
788  return it->symbol();
789  }
790  }
791  return 0;
792 }
793 
795 {
796 }
797 
799 {
801 }
802 
804 {
805  viewGraduated->selectionModel()->clear();
806 }
807 
809 {
810  if ( !event )
811  {
812  return;
813  }
814 
815  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
816  {
817  mCopyBuffer.clear();
819  }
820  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
821  {
822  QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
823  for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
824  {
825  mModel->addClass( *rIt );
826  }
827  }
828 }
void addClass()
Adds a class manually to the classification.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
void showSymbolLevelsDialog(QgsFeatureRendererV2 *r)
show a dialog with renderer's symbol level settings
QList< QgsRendererRangeV2 > QgsRangeList
static unsigned index
QVariant data(const QModelIndex &index, int role) const
void sort(int column, Qt::SortOrder order=Qt::AscendingOrder)
int rowCount(const QModelIndex &parent=QModelIndex()) const
QgsGraduatedSymbolRendererV2Widget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void contextMenuViewCategories(const QPoint &p)
bool updateRangeLabel(int rangeIndex, QString label)
QString upperValue() const
Definition: qgsludialog.cpp:37
void updateSymbols(QgsSymbolV2 *sym)
Update the all symbols but leave breaks and colors.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
virtual QgsSymbolV2 * clone() const =0
virtual QgsFeatureRendererV2 * renderer()
return pointer to the renderer (no transfer of ownership)
void updateColorRamp(QgsVectorColorRampV2 *ramp, bool inverted=false)
Update the color ramp used.
bool updateRangeRenderState(int rangeIndex, bool render)
static QgsGraduatedSymbolRendererV2 * createRenderer(QgsVectorLayer *vlayer, QString attrName, int classes, Mode mode, QgsSymbolV2 *symbol, QgsVectorColorRampV2 *ramp, bool inverted=false)
void setSizeScaleField(QString fieldOrExpression)
QList< QgsSymbolV2 * > selectedSymbols()
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
void setUpperValue(QString val)
Definition: qgsludialog.cpp:47
void scaleMethodChanged(QgsSymbolV2::ScaleMethod scaleMethod)
void setScaleMethod(QgsSymbolV2::ScaleMethod scaleMethod)
static QIcon icon(QString icon)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:324
void setRenderer(QgsGraduatedSymbolRendererV2 *renderer)
int columnCount(const QModelIndex &=QModelIndex()) const
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
QVariant headerData(int section, Qt::Orientation orientation, int role) const
QgsSymbolV2 * findSymbolForRange(double lowerBound, double upperBound, const QgsRangeList &ranges) const
QString type() const
Definition: qgsrendererv2.h:80
void setRotationField(QString fieldOrExpression)
void setColor(const QColor &color)
Utility class for providing GUI for data-defined rendering.
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
QgsVectorLayer * mLayer
QgsSymbolV2::ScaleMethod scaleMethod() const
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
QgsRendererRangeV2 rendererRange(const QModelIndex &index)
QModelIndex parent(const QModelIndex &index) const
QgsSymbolV2 * symbol() const
bool updateRangeLowerValue(int rangeIndex, double value)
QGis::GeometryType geometryType() const
Returns point, line or polygon.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
void deleteClasses()
Removes currently selected classes.
virtual long featureCount() const
Number of features in the layer.
void setLowerValue(QString val)
Definition: qgsludialog.cpp:42
void moveClass(int from, int to)
Moves the category at index position from to index position to.
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget=0) const
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
Qt::ItemFlags flags(const QModelIndex &index) const
bool setData(const QModelIndex &index, const QVariant &value, int role)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
bool updateRangeSymbol(int rangeIndex, QgsSymbolV2 *symbol)
Base class for renderer settings widgets.
bool updateRangeUpperValue(int rangeIndex, double value)
QMimeData * mimeData(const QModelIndexList &indexes) const
Represents a vector layer which manages a vector based data sets.
QString lowerValue() const
Definition: qgsludialog.cpp:32
void deleteAllClasses()
Removes all classes from the classification.
QList< int > selectedClasses()
return a list of indexes for the classes under selection
#define tr(sourceText)