QGIS API Documentation  2.17.0-Master (00653d2)
qgsrulebasedrendererv2widget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrulebasedrendererv2widget.cpp - Settings widget for rule-based renderer
3  ---------------------
4  begin : May 2010
5  copyright : (C) 2010 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  ***************************************************************************/
15 
17 
18 #include "qgsrulebasedrendererv2.h"
19 #include "qgssymbollayerv2utils.h"
20 #include "qgssymbolv2.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsapplication.h"
23 #include "qgsexpression.h"
25 #include "qgslogger.h"
26 #include "qstring.h"
28 #include "qgspanelwidget.h"
29 
30 #include <QKeyEvent>
31 #include <QMenu>
32 #include <QProgressDialog>
33 #include <QSettings>
34 #include <QTreeWidgetItem>
35 #include <QVBoxLayout>
36 #include <QMessageBox>
37 
38 #ifdef ENABLE_MODELTEST
39 #include "modeltest.h"
40 #endif
41 
43 {
44  return new QgsRuleBasedRendererV2Widget( layer, style, renderer );
45 }
46 
48  : QgsRendererV2Widget( layer, style )
49 {
50  mRenderer = nullptr;
51  // try to recognize the previous renderer
52  // (null renderer means "no previous renderer")
53 
54 
55  if ( renderer )
56  {
58  }
59  if ( !mRenderer )
60  {
61  // some default options
63 
64  mRenderer = new QgsRuleBasedRendererV2( symbol );
65  }
66 
67  setupUi( this );
68 
70 #ifdef ENABLE_MODELTEST
71  new ModelTest( mModel, this ); // for model validity checking
72 #endif
73  viewRules->setModel( mModel );
74 
75  mDeleteAction = new QAction( tr( "Remove Rule" ), this );
76  mDeleteAction->setShortcut( QKeySequence( QKeySequence::Delete ) );
77 
78  viewRules->addAction( mDeleteAction );
79  viewRules->addAction( mCopyAction );
80  viewRules->addAction( mPasteAction );
81 
82  mRefineMenu = new QMenu( tr( "Refine current rule" ), btnRefineRule );
83  mRefineMenu->addAction( tr( "Add scales to rule" ), this, SLOT( refineRuleScales() ) );
84  mRefineMenu->addAction( tr( "Add categories to rule" ), this, SLOT( refineRuleCategories() ) );
85  mRefineMenu->addAction( tr( "Add ranges to rule" ), this, SLOT( refineRuleRanges() ) );
86  btnRefineRule->setMenu( mRefineMenu );
88 
89  btnAddRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
90  btnEditRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.png" ) ) );
91  btnRemoveRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
92 
93  connect( viewRules, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( editRule( const QModelIndex & ) ) );
94 
95  // support for context menu (now handled generically)
96  connect( viewRules, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) );
97 
98  connect( viewRules->selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ), this, SLOT( currentRuleChanged( QModelIndex, QModelIndex ) ) );
99  connect( viewRules->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), this, SLOT( selectedRulesChanged() ) );
100 
101  connect( btnAddRule, SIGNAL( clicked() ), this, SLOT( addRule() ) );
102  connect( btnEditRule, SIGNAL( clicked() ), this, SLOT( editRule() ) );
103  connect( btnRemoveRule, SIGNAL( clicked() ), this, SLOT( removeRule() ) );
104  connect( mDeleteAction, SIGNAL( triggered() ), this, SLOT( removeRule() ) );
105  connect( btnCountFeatures, SIGNAL( clicked() ), this, SLOT( countFeatures() ) );
106 
107  connect( btnRenderingOrder, SIGNAL( clicked() ), this, SLOT( setRenderingOrder() ) );
108 
109  connect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SIGNAL( widgetChanged() ) );
110  connect( mModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), this, SIGNAL( widgetChanged() ) );
111  connect( mModel, SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SIGNAL( widgetChanged() ) );
112 
115 
116  // store/restore header section widths
117  connect( viewRules->header(), SIGNAL( sectionResized( int, int, int ) ), this, SLOT( saveSectionWidth( int, int, int ) ) );
118 
120 
121 }
122 
124 {
125  qDeleteAll( mCopyBuffer );
126  delete mRenderer;
127 }
128 
130 {
131  return mRenderer;
132 }
133 
135 {
138 
140  if ( current )
141  {
142  // add after this rule
143  QModelIndex currentIndex = viewRules->selectionModel()->currentIndex();
144  mModel->insertRule( currentIndex.parent(), currentIndex.row() + 1, newrule );
145  QModelIndex newindex = mModel->index( currentIndex.row() + 1, 0, currentIndex.parent() );
146  viewRules->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect );
147  }
148  else
149  {
150  // append to root rule
151  int rows = mModel->rowCount();
152  mModel->insertRule( QModelIndex(), rows, newrule );
153  QModelIndex newindex = mModel->index( rows, 0 );
154  viewRules->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect );
155  }
156  editRule();
157 }
158 
160 {
161  QItemSelectionModel* sel = viewRules->selectionModel();
162  QModelIndex idx = sel->currentIndex();
163  if ( !idx.isValid() )
164  return nullptr;
165  return mModel->ruleForIndex( idx );
166 }
167 
169 {
170  editRule( viewRules->selectionModel()->currentIndex() );
171 }
172 
174 {
175  if ( !index.isValid() )
176  return;
177 
179 
181  widget->setDockMode( true );
182  widget->setPanelTitle( tr( "Edit rule" ) );
183  connect( widget, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( ruleWidgetPanelAccepted( QgsPanelWidget* ) ) );
184  connect( widget, SIGNAL( widgetChanged() ), this, SLOT( liveUpdateRuleFromPanel() ) );
185  openPanel( widget );
186 }
187 
189 {
190  QItemSelection sel = viewRules->selectionModel()->selection();
191  QgsDebugMsg( QString( "REMOVE RULES!!! ranges: %1" ).arg( sel.count() ) );
192  Q_FOREACH ( const QItemSelectionRange& range, sel )
193  {
194  QgsDebugMsg( QString( "RANGE: r %1 - %2" ).arg( range.top() ).arg( range.bottom() ) );
195  if ( range.isValid() )
196  mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
197  }
198  // make sure that the selection is gone
199  viewRules->selectionModel()->clear();
201 }
202 
204 {
205  Q_UNUSED( previous );
206  btnEditRule->setEnabled( current.isValid() );
207 }
208 
209 
215 #include <QDialogButtonBox>
216 #include <QInputDialog>
217 #include <QClipboard>
218 
220 {
221  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
222 
223  if ( indexlist.isEmpty() )
224  return;
225 
226 
227  if ( type == 0 ) // categories
228  refineRuleCategoriesGui( indexlist );
229  else if ( type == 1 ) // ranges
230  refineRuleRangesGui( indexlist );
231  else // scales
232  refineRuleScalesGui( indexlist );
233 
234  // TODO: set initial rule's symbol to NULL (?)
235 
236  // show the newly added rules
237  Q_FOREACH ( const QModelIndex& index, indexlist )
238  viewRules->expand( index );
239 }
240 
242 {
243  refineRule( 0 );
244 }
245 
247 {
248  refineRule( 1 );
249 }
250 
252 {
253  refineRule( 2 );
254 }
255 
257 {
259  w->setPanelTitle( tr( "Add categories to rules" ) );
260  connect( w, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( refineRuleCategoriesAccepted( QgsPanelWidget* ) ) );
261  w->setMapCanvas( mMapCanvas );
262  openPanel( w );
263 }
264 
266 {
268  w->setPanelTitle( tr( "Add ranges to rules" ) );
269  connect( w, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( refineRuleRangesAccepted( QgsPanelWidget* ) ) );
270  w->setMapCanvas( mMapCanvas );
271  openPanel( w );
272 }
273 
274 void QgsRuleBasedRendererV2Widget::refineRuleScalesGui( const QModelIndexList& indexList )
275 {
276  Q_FOREACH ( const QModelIndex& index, indexList )
277  {
278  QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
279 
280  // If any of the rules don't have a symbol let the user know and exit.
281  if ( !initialRule->symbol() )
282  {
283  QMessageBox::warning( this, tr( "Scale refinement" ), tr( "Parent rule %1 must have a symbol for this operation." ).arg( initialRule->label() ) );
284  return;
285  }
286  }
287 
288  QString txt = QInputDialog::getText( this,
289  tr( "Scale refinement" ),
290  tr( "Please enter scale denominators at which will split the rule, separate them by commas (e.g. 1000,5000):" ) );
291  if ( txt.isEmpty() )
292  return;
293 
294  QList<int> scales;
295  bool ok;
296  Q_FOREACH ( const QString& item, txt.split( ',' ) )
297  {
298  int scale = item.toInt( &ok );
299  if ( ok )
300  scales.append( scale );
301  else
302  QMessageBox::information( this, tr( "Error" ), QString( tr( "\"%1\" is not valid scale denominator, ignoring it." ) ).arg( item ) );
303  }
304 
305  Q_FOREACH ( const QModelIndex& index, indexList )
306  {
307  QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
308  mModel->willAddRules( index, scales.count() + 1 );
309  QgsRuleBasedRendererV2::refineRuleScales( initialRule, scales );
310  }
312 }
313 
315 {
316  QList<QgsSymbolV2*> symbolList;
317 
318  if ( !mRenderer )
319  {
320  return symbolList;
321  }
322 
323  QItemSelection sel = viewRules->selectionModel()->selection();
324  Q_FOREACH ( const QItemSelectionRange& range, sel )
325  {
326  QModelIndex parent = range.parent();
327  QgsRuleBasedRendererV2::Rule* parentRule = mModel->ruleForIndex( parent );
329  for ( int row = range.top(); row <= range.bottom(); row++ )
330  {
331  symbolList.append( children[row]->symbol() );
332  }
333  }
334 
335  return symbolList;
336 }
337 
339 {
341  QItemSelection sel = viewRules->selectionModel()->selection();
342  Q_FOREACH ( const QItemSelectionRange& range, sel )
343  {
344  QModelIndex parent = range.parent();
345  QgsRuleBasedRendererV2::Rule* parentRule = mModel->ruleForIndex( parent );
347  for ( int row = range.top(); row <= range.bottom(); row++ )
348  {
349  rl.append( children[row]->clone() );
350  }
351  }
352  return rl;
353 }
354 
356 {
357  // TODO: model/view
358  /*
359  if ( treeRules )
360  {
361  treeRules->populateRules();
362  }
363  */
364  emit widgetChanged();
365 }
366 
368 {
369  if ( !event )
370  {
371  return;
372  }
373 
374  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
375  {
376  qDeleteAll( mCopyBuffer );
377  mCopyBuffer.clear();
379  }
380  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
381  {
383  for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
384  {
385  int rows = mModel->rowCount();
386  mModel->insertRule( QModelIndex(), rows, ( *rIt )->clone() );
387  }
388  }
389 }
390 
391 #include "qgssymbollevelsv2dialog.h"
392 
394 {
396 
397  QgsSymbolLevelsV2Dialog dlg( lst, true, this );
398  dlg.setForceOrderingEnabled( true );
399 
400  dlg.exec();
401 }
402 
403 void QgsRuleBasedRendererV2Widget::saveSectionWidth( int section, int oldSize, int newSize )
404 {
405  Q_UNUSED( oldSize );
406  // skip last section, as it stretches
407  if ( section == 5 )
408  return;
409  QSettings settings;
410  QString path = "/Windows/RuleBasedTree/sectionWidth/" + QString::number( section );
411  settings.setValue( path, newSize );
412 }
413 
415 {
416  QSettings settings;
417  QString path = "/Windows/RuleBasedTree/sectionWidth/";
418  QHeaderView* head = viewRules->header();
419  head->resizeSection( 0, settings.value( path + QString::number( 0 ), 150 ).toInt() );
420  head->resizeSection( 1, settings.value( path + QString::number( 1 ), 150 ).toInt() );
421  head->resizeSection( 2, settings.value( path + QString::number( 2 ), 80 ).toInt() );
422  head->resizeSection( 3, settings.value( path + QString::number( 3 ), 80 ).toInt() );
423  head->resizeSection( 4, settings.value( path + QString::number( 4 ), 50 ).toInt() );
424  head->resizeSection( 5, settings.value( path + QString::number( 5 ), 50 ).toInt() );
425 }
426 
428 {
429  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
430  QgsDebugMsg( QString( "%1" ).arg( indexlist.count() ) );
431 
432  if ( indexlist.isEmpty() )
433  return;
434 
435  QMimeData* mime = mModel->mimeData( indexlist );
437 }
438 
440 {
441  const QMimeData* mime = QApplication::clipboard()->mimeData();
442  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
444  if ( indexlist.isEmpty() )
445  index = mModel->index( mModel->rowCount(), 0 );
446  else
447  index = indexlist.first();
448  mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() );
449 }
450 
451 void QgsRuleBasedRendererV2Widget::refineRuleCategoriesAccepted( QgsPanelWidget *panel )
452 {
454 
455  // create new rules
457  QModelIndexList indexList = viewRules->selectionModel()->selectedRows();
458  Q_FOREACH ( const QModelIndex& index, indexList )
459  {
460  QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
461  mModel->willAddRules( index, r->categories().count() );
463  }
465 }
466 
467 void QgsRuleBasedRendererV2Widget::refineRuleRangesAccepted( QgsPanelWidget *panel )
468 {
470  // create new rules
472  QModelIndexList indexList = viewRules->selectionModel()->selectedRows();
473  Q_FOREACH ( const QModelIndex& index, indexList )
474  {
475  QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
476  mModel->willAddRules( index, r->ranges().count() );
478  }
480 }
481 
482 void QgsRuleBasedRendererV2Widget::ruleWidgetPanelAccepted( QgsPanelWidget *panel )
483 {
484  QgsRendererRulePropsWidget *widget = qobject_cast<QgsRendererRulePropsWidget*>( panel );
485  if ( !widget )
486  return;
487 
488  widget->apply();
489 
490  // model should know about the change and emit dataChanged signal for the view
491  QModelIndex index = viewRules->selectionModel()->currentIndex();
492  mModel->updateRule( index.parent(), index.row() );
494 }
495 
496 void QgsRuleBasedRendererV2Widget::liveUpdateRuleFromPanel()
497 {
498  ruleWidgetPanelAccepted( qobject_cast<QgsPanelWidget*>( sender() ) );
499 }
500 
501 
503 {
504  if ( !mLayer || !mRenderer || !mRenderer->rootRule() )
505  {
506  return;
507  }
509 
511  // insert all so that we have counts 0
512  Q_FOREACH ( QgsRuleBasedRendererV2::Rule* rule, ruleList )
513  {
514  countMap[rule].count = 0;
515  countMap[rule].duplicateCount = 0;
516  }
517 
518  QgsRenderContext renderContext;
519  renderContext.setRendererScale( 0 ); // ignore scale
520 
521  QgsExpressionContext context;
525  if ( mMapCanvas )
526  {
529  }
530  else
531  {
533  }
535 
536  renderContext.setExpressionContext( context );
537 
538  mRenderer->startRender( renderContext, mLayer->fields() );
539  // QgsRuleBasedRenderer::filter must be called after startRender
541  req.setExpressionContext( context );
543  QgsFeatureIterator fit = mLayer->getFeatures( req );
544 
545  int nFeatures = mLayer->featureCount();
546  QProgressDialog p( tr( "Calculating feature count." ), tr( "Abort" ), 0, nFeatures );
547  p.setWindowModality( Qt::WindowModal );
548  int featuresCounted = 0;
549 
550  QgsFeature f;
551  while ( fit.nextFeature( f ) )
552  {
553  renderContext.expressionContext().setFeature( f );
554  QgsRuleBasedRendererV2::RuleList featureRuleList = mRenderer->rootRule()->rulesForFeature( f, &renderContext );
555 
556  Q_FOREACH ( QgsRuleBasedRendererV2::Rule* rule, featureRuleList )
557  {
558  countMap[rule].count++;
559  if ( featureRuleList.size() > 1 )
560  {
561  countMap[rule].duplicateCount++;
562  }
563  Q_FOREACH ( QgsRuleBasedRendererV2::Rule* duplicateRule, featureRuleList )
564  {
565  if ( duplicateRule == rule ) continue;
566  countMap[rule].duplicateCountMap[duplicateRule] += 1;
567  }
568  }
569  ++featuresCounted;
570  if ( featuresCounted % 50 == 0 )
571  {
572  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
573  {
574  p.setMaximum( 0 );
575  }
576  p.setValue( featuresCounted );
577  if ( p.wasCanceled() )
578  {
579  return;
580  }
581  }
582  }
583  p.setValue( nFeatures );
584 
585  mRenderer->stopRender( renderContext );
586 
587 #ifdef QGISDEBUG
588  Q_FOREACH ( QgsRuleBasedRendererV2::Rule *rule, countMap.keys() )
589  {
590  QgsDebugMsg( QString( "rule: %1 count %2" ).arg( rule->label() ).arg( countMap[rule].count ) );
591  }
592 #endif
593 
594  mModel->setFeatureCounts( countMap );
595 }
596 
598 {
599  bool enabled = !viewRules->selectionModel()->selectedIndexes().isEmpty();
600  btnRefineRule->setEnabled( enabled );
601  btnRemoveRule->setEnabled( enabled );
602 }
603 
605 
607  : QgsPanelWidget( parent )
608  , mRule( rule )
609  , mLayer( layer )
610  , mSymbolSelector( nullptr )
611  , mSymbol( nullptr )
612  , mMapCanvas( mapCanvas )
613 {
614  setupUi( this );
615  layout()->setMargin( 0 );
616  layout()->setContentsMargins( 0, 0, 0, 0 );
617 
618  editFilter->setText( mRule->filterExpression() );
619  editFilter->setToolTip( mRule->filterExpression() );
620  editLabel->setText( mRule->label() );
621  editDescription->setText( mRule->description() );
622  editDescription->setToolTip( mRule->description() );
623 
624  if ( mRule->dependsOnScale() )
625  {
626  groupScale->setChecked( true );
627  // caution: rule uses scale denom, scale widget uses true scales
628  if ( rule->scaleMinDenom() > 0 )
629  mScaleRangeWidget->setMaximumScale( 1.0 / rule->scaleMinDenom() );
630  if ( rule->scaleMaxDenom() > 0 )
631  mScaleRangeWidget->setMinimumScale( 1.0 / rule->scaleMaxDenom() );
632  }
633  mScaleRangeWidget->setMapCanvas( mMapCanvas );
634 
635  if ( mRule->symbol() )
636  {
637  groupSymbol->setChecked( true );
638  mSymbol = mRule->symbol()->clone(); // use a clone!
639  }
640  else
641  {
642  groupSymbol->setChecked( false );
644  }
645 
647  mSymbolSelector->setMapCanvas( mMapCanvas );
648  connect( mSymbolSelector, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
649  connect( mSymbolSelector, SIGNAL( showPanel( QgsPanelWidget* ) ), this, SLOT( openPanel( QgsPanelWidget* ) ) );
650 
651  QVBoxLayout* l = new QVBoxLayout;
652  l->addWidget( mSymbolSelector );
653  groupSymbol->setLayout( l );
654 
655  connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) );
656  connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) );
657  connect( editFilter, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
658  connect( editLabel, SIGNAL( editingFinished() ), this, SIGNAL( widgetChanged() ) );
659  connect( editDescription, SIGNAL( editingFinished() ), this, SIGNAL( widgetChanged() ) );
660  connect( groupSymbol, SIGNAL( toggled( bool ) ), this, SIGNAL( widgetChanged() ) );
661  connect( groupScale, SIGNAL( toggled( bool ) ), this, SIGNAL( widgetChanged() ) );
662  connect( mScaleRangeWidget, SIGNAL( rangeChanged( double, double ) ), this, SIGNAL( widgetChanged() ) );
663 }
664 
666 {
667 
668 }
669 
671  : QDialog( parent )
672 {
673 
674 #ifdef Q_OS_MAC
675  setWindowModality( Qt::WindowModal );
676 #endif
677  this->setLayout( new QVBoxLayout() );
678 
679  buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
680  mPropsWidget = new QgsRendererRulePropsWidget( rule, layer, style, this, mapCanvas );
681 
682  this->layout()->addWidget( mPropsWidget );
683  this->layout()->addWidget( buttonBox );
684 
685  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
686  connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
687 
688  QSettings settings;
689  restoreGeometry( settings.value( "/Windows/QgsRendererRulePropsDialog/geometry" ).toByteArray() );
690 }
691 
693 {
694  QSettings settings;
695  settings.setValue( "/Windows/QgsRendererRulePropsDialog/geometry", saveGeometry() );
696 }
697 
699 {
700  mPropsWidget->testFilter();
701 }
702 
704 {
705  mPropsWidget->buildExpression();
706 }
707 
709 {
710  mPropsWidget->apply();
711  QDialog::accept();
712 }
713 
715 {
716  QgsExpressionContext context;
720  if ( mMapCanvas )
721  {
722  context << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
723  << new QgsExpressionContextScope( mMapCanvas->expressionContextScope() );
724  }
725  else
726  {
728  }
729  context << QgsExpressionContextUtils::layerScope( mLayer );
730 
731  QgsExpressionBuilderDialog dlg( mLayer, editFilter->text(), this, "generic", context );
732 
733  if ( dlg.exec() )
734  editFilter->setText( dlg.expressionText() );
735 }
736 
738 {
739  QgsExpression filter( editFilter->text() );
740  if ( filter.hasParserError() )
741  {
742  QMessageBox::critical( this, tr( "Error" ), tr( "Filter expression parsing error:\n" ) + filter.parserErrorString() );
743  return;
744  }
745 
746  QgsExpressionContext context;
750  if ( mMapCanvas )
751  {
752  context << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
753  << new QgsExpressionContextScope( mMapCanvas->expressionContextScope() );
754  }
755  else
756  {
758  }
759  context << QgsExpressionContextUtils::layerScope( mLayer );
760 
761  if ( !filter.prepare( &context ) )
762  {
763  QMessageBox::critical( this, tr( "Evaluation error" ), filter.evalErrorString() );
764  return;
765  }
766 
767  QApplication::setOverrideCursor( Qt::WaitCursor );
768 
771  .setFilterExpression( editFilter->text() )
772  .setExpressionContext( context );
773 
774  QgsFeatureIterator fit = mLayer->getFeatures( req );
775 
776  int count = 0;
777  QgsFeature f;
778  while ( fit.nextFeature( f ) )
779  {
780  count++;
781  }
782 
784 
785  QMessageBox::information( this, tr( "Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) );
786 }
787 
789 {
790  mRule->setFilterExpression( editFilter->text() );
791  mRule->setLabel( editLabel->text() );
792  mRule->setDescription( editDescription->text() );
793  // caution: rule uses scale denom, scale widget uses true scales
794  mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
795  mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
796  mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr );
797 }
798 
800 {
801  QgsPanelWidget::setDockMode( dockMode );
802  mSymbolSelector->setDockMode( true );
803 }
804 
806 
807 /*
808  setDragEnabled(true);
809  viewport()->setAcceptDrops(true);
810  setDropIndicatorShown(true);
811  setDragDropMode(QAbstractItemView::InternalMove);
812 */
813 
814 static QString _formatScale( int denom )
815 {
816  if ( denom != 0 )
817  {
818  QString txt = QString( "1:%L1" ).arg( denom );
819  return txt;
820  }
821  else
822  return QString();
823 }
824 
826 
828  : mR( r )
829 {
830 }
831 
833 {
834  if ( !index.isValid() )
835  return Qt::ItemIsDropEnabled;
836 
837  // allow drop only at first column
838  Qt::ItemFlag drop = ( index.column() == 0 ? Qt::ItemIsDropEnabled : Qt::NoItemFlags );
839 
840  Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
841 
842  return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
843  Qt::ItemIsEditable | checkable |
844  Qt::ItemIsDragEnabled | drop;
845 }
846 
848 {
849  if ( !index.isValid() )
850  return QVariant();
851 
853 
854  if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
855  {
856  switch ( index.column() )
857  {
858  case 0:
859  return rule->label();
860  case 1:
861  if ( rule->isElse() )
862  {
863  return "ELSE";
864  }
865  else
866  {
867  return rule->filterExpression().isEmpty() ? tr( "(no filter)" ) : rule->filterExpression();
868  }
869  case 2:
870  return rule->dependsOnScale() ? _formatScale( rule->scaleMaxDenom() ) : QVariant();
871  case 3:
872  return rule->dependsOnScale() ? _formatScale( rule->scaleMinDenom() ) : QVariant();
873  case 4:
874  if ( mFeatureCountMap.count( rule ) == 1 )
875  {
876  return QVariant( mFeatureCountMap[rule].count );
877  }
878  return QVariant();
879  case 5:
880  if ( mFeatureCountMap.count( rule ) == 1 )
881  {
882  if ( role == Qt::DisplayRole )
883  {
884  return QVariant( mFeatureCountMap[rule].duplicateCount );
885  }
886  else // tooltip - detailed info about duplicates
887  {
888  if ( mFeatureCountMap[rule].duplicateCount > 0 )
889  {
890  QString tip = "<p style='margin:0px;'><ul>";
891  Q_FOREACH ( QgsRuleBasedRendererV2::Rule* duplicateRule, mFeatureCountMap[rule].duplicateCountMap.keys() )
892  {
893  QString label = duplicateRule->label().replace( '&', "&amp;" ).replace( '>', "&gt;" ).replace( '<', "&lt;" );
894  tip += tr( "<li><nobr>%1 features also in rule %2</nobr></li>" ).arg( mFeatureCountMap[rule].duplicateCountMap[duplicateRule] ).arg( label );
895  }
896  tip += "</ul>";
897  return tip;
898  }
899  else
900  {
901  return 0;
902  }
903  }
904  }
905  return QVariant();
906  default:
907  return QVariant();
908  }
909  }
910  else if ( role == Qt::DecorationRole && index.column() == 0 && rule->symbol() )
911  {
912  return QgsSymbolLayerV2Utils::symbolPreviewIcon( rule->symbol(), QSize( 16, 16 ) );
913  }
914  else if ( role == Qt::TextAlignmentRole )
915  {
916  return ( index.column() == 2 || index.column() == 3 ) ? Qt::AlignRight : Qt::AlignLeft;
917  }
918  else if ( role == Qt::FontRole && index.column() == 1 )
919  {
920  if ( rule->isElse() )
921  {
922  QFont italicFont;
923  italicFont.setItalic( true );
924  return italicFont;
925  }
926  return QVariant();
927  }
928  else if ( role == Qt::EditRole )
929  {
930  switch ( index.column() )
931  {
932  case 0:
933  return rule->label();
934  case 1:
935  return rule->filterExpression();
936  case 2:
937  return rule->scaleMaxDenom();
938  case 3:
939  return rule->scaleMinDenom();
940  default:
941  return QVariant();
942  }
943  }
944  else if ( role == Qt::CheckStateRole )
945  {
946  if ( index.column() != 0 )
947  return QVariant();
948  return rule->active() ? Qt::Checked : Qt::Unchecked;
949  }
950  else
951  return QVariant();
952 }
953 
954 QVariant QgsRuleBasedRendererV2Model::headerData( int section, Qt::Orientation orientation, int role ) const
955 {
956  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 7 )
957  {
958  QStringList lst;
959  lst << tr( "Label" ) << tr( "Rule" ) << tr( "Min. scale" ) << tr( "Max. scale" ) << tr( "Count" ) << tr( "Duplicate count" );
960  return lst[section];
961  }
962  else if ( orientation == Qt::Horizontal && role == Qt::ToolTipRole )
963  {
964  if ( section == 4 ) // Count
965  {
966  return tr( "Number of features in this rule." );
967  }
968  else if ( section == 5 ) // Duplicate count
969  {
970  return tr( "Number of features in this rule which are also present in other rule(s)." );
971  }
972  }
973 
974  return QVariant();
975 }
976 
978 {
979  if ( parent.column() > 0 )
980  return 0;
981 
982  QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
983 
984  return parentRule->children().count();
985 }
986 
988 {
989  return 6;
990 }
991 
993 {
994  if ( hasIndex( row, column, parent ) )
995  {
996  QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
997  QgsRuleBasedRendererV2::Rule* childRule = parentRule->children()[row];
998  return createIndex( row, column, childRule );
999  }
1000  return QModelIndex();
1001 }
1002 
1004 {
1005  if ( !index.isValid() )
1006  return QModelIndex();
1007 
1008  QgsRuleBasedRendererV2::Rule* childRule = ruleForIndex( index );
1009  QgsRuleBasedRendererV2::Rule* parentRule = childRule->parent();
1010 
1011  if ( parentRule == mR->rootRule() )
1012  return QModelIndex();
1013 
1014  // this is right: we need to know row number of our parent (in our grandparent)
1015  int row = parentRule->parent()->children().indexOf( parentRule );
1016 
1017  return createIndex( row, 0, parentRule );
1018 }
1019 
1020 bool QgsRuleBasedRendererV2Model::setData( const QModelIndex & index, const QVariant & value, int role )
1021 {
1022  if ( !index.isValid() )
1023  return false;
1024 
1025  QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
1026 
1027  if ( role == Qt::CheckStateRole )
1028  {
1029  rule->setActive( value.toInt() == Qt::Checked );
1030  emit dataChanged( index, index );
1031  return true;
1032  }
1033 
1034  if ( role != Qt::EditRole )
1035  return false;
1036 
1037  switch ( index.column() )
1038  {
1039  case 0: // label
1040  rule->setLabel( value.toString() );
1041  break;
1042  case 1: // filter
1043  rule->setFilterExpression( value.toString() );
1044  break;
1045  case 2: // scale min
1046  rule->setScaleMaxDenom( value.toInt() );
1047  break;
1048  case 3: // scale max
1049  rule->setScaleMinDenom( value.toInt() );
1050  break;
1051  default:
1052  return false;
1053  }
1054 
1055  emit dataChanged( index, index );
1056  return true;
1057 }
1058 
1060 {
1061  return Qt::MoveAction; // | Qt::CopyAction
1062 }
1063 
1065 {
1066  QStringList types;
1067  types << "application/vnd.text.list";
1068  return types;
1069 }
1070 
1071 QMimeData *QgsRuleBasedRendererV2Model::mimeData( const QModelIndexList &indexes ) const
1072 {
1073  QMimeData *mimeData = new QMimeData();
1074  QByteArray encodedData;
1075 
1076  QDataStream stream( &encodedData, QIODevice::WriteOnly );
1077 
1078  Q_FOREACH ( const QModelIndex &index, indexes )
1079  {
1080  // each item consists of several columns - let's add it with just first one
1081  if ( !index.isValid() || index.column() != 0 )
1082  continue;
1083 
1084  // we use a clone of the existing rule because it has a new unique rule key
1085  // non-unique rule keys would confuse other components using them (e.g. legend)
1086  QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index )->clone();
1087  QDomDocument doc;
1088  QgsSymbolV2Map symbols;
1089 
1090  QDomElement rootElem = doc.createElement( "rule_mime" );
1091  rootElem.setAttribute( "type", "renderer" ); // for determining whether rules are from renderer or labeling
1092  QDomElement rulesElem = rule->save( doc, symbols );
1093  rootElem.appendChild( rulesElem );
1094  QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
1095  rootElem.appendChild( symbolsElem );
1096  doc.appendChild( rootElem );
1097 
1098  delete rule;
1099 
1100  stream << doc.toString( -1 );
1101  }
1102 
1103  mimeData->setData( "application/vnd.text.list", encodedData );
1104  return mimeData;
1105 }
1106 
1107 
1108 // manipulate DOM before dropping it so that rules are more useful
1110 {
1111  // labeling rules recognize only "description"
1112  if ( ruleElem.hasAttribute( "description" ) )
1113  ruleElem.setAttribute( "label", ruleElem.attribute( "description" ) );
1114 
1115  // run recursively
1116  QDomElement childRuleElem = ruleElem.firstChildElement( "rule" );
1117  while ( !childRuleElem.isNull() )
1118  {
1119  _labeling2rendererRules( childRuleElem );
1120  childRuleElem = childRuleElem.nextSiblingElement( "rule" );
1121  }
1122 }
1123 
1124 
1126  Qt::DropAction action, int row, int column, const QModelIndex &parent )
1127 {
1128  Q_UNUSED( column );
1129 
1130  if ( action == Qt::IgnoreAction )
1131  return true;
1132 
1133  if ( !data->hasFormat( "application/vnd.text.list" ) )
1134  return false;
1135 
1136  if ( parent.column() > 0 )
1137  return false;
1138 
1139  QByteArray encodedData = data->data( "application/vnd.text.list" );
1140  QDataStream stream( &encodedData, QIODevice::ReadOnly );
1141  int rows = 0;
1142 
1143  if ( row == -1 )
1144  {
1145  // the item was dropped at a parent - we may decide where to put the items - let's append them
1146  row = rowCount( parent );
1147  }
1148 
1149  while ( !stream.atEnd() )
1150  {
1151  QString text;
1152  stream >> text;
1153 
1154  QDomDocument doc;
1155  if ( !doc.setContent( text ) )
1156  continue;
1157  QDomElement rootElem = doc.documentElement();
1158  if ( rootElem.tagName() != "rule_mime" )
1159  continue;
1160  if ( rootElem.attribute( "type" ) == "labeling" )
1161  rootElem.appendChild( doc.createElement( "symbols" ) );
1162  QDomElement symbolsElem = rootElem.firstChildElement( "symbols" );
1163  if ( symbolsElem.isNull() )
1164  continue;
1165  QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
1166  QDomElement ruleElem = rootElem.firstChildElement( "rule" );
1167  if ( rootElem.attribute( "type" ) == "labeling" )
1168  _labeling2rendererRules( ruleElem );
1170 
1171  insertRule( parent, row + rows, rule );
1172 
1173  ++rows;
1174  }
1175  return true;
1176 }
1177 
1179 {
1180  if ( index.isValid() )
1181  return static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
1182  return mR->rootRule();
1183 }
1184 
1186 {
1187  QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
1188 
1189  if ( row < 0 || row >= parentRule->children().count() )
1190  return false;
1191 
1192  QgsDebugMsg( QString( "Called: row %1 count %2 parent ~~%3~~" ).arg( row ).arg( count ).arg( parentRule->dump() ) );
1193 
1194  beginRemoveRows( parent, row, row + count - 1 );
1195 
1196  for ( int i = 0; i < count; i++ )
1197  {
1198  if ( row < parentRule->children().count() )
1199  {
1200  //QgsRuleBasedRendererV2::Rule* r = parentRule->children()[row];
1201  parentRule->removeChildAt( row );
1202  //parentRule->takeChildAt( row );
1203  }
1204  else
1205  {
1206  QgsDebugMsg( "trying to remove invalid index - this should not happen!" );
1207  }
1208  }
1209 
1210  endRemoveRows();
1211 
1212  return true;
1213 }
1214 
1215 
1217 {
1218  beginInsertRows( parent, before, before );
1219 
1220  QgsDebugMsg( QString( "insert before %1 rule: %2" ).arg( before ).arg( newrule->dump() ) );
1221 
1222  QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
1223  parentRule->insertChild( before, newrule );
1224 
1225  endInsertRows();
1226 }
1227 
1229 {
1230  emit dataChanged( index( row, 0, parent ),
1231  index( row, columnCount( parent ), parent ) );
1232 }
1233 
1235 {
1236  emit dataChanged( index( 0, 0, idx ),
1237  index( rowCount( idx ) - 1, columnCount( idx ) - 1, idx ) );
1238 
1239  for ( int i = 0; i < rowCount( idx ); i++ )
1240  {
1241  updateRule( index( i, 0, idx ) );
1242  }
1243 }
1244 
1245 
1247 {
1248  if ( !index.isValid() )
1249  return;
1250 
1251  beginRemoveRows( index.parent(), index.row(), index.row() );
1252 
1253  QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
1254  rule->parent()->removeChild( rule );
1255 
1256  endRemoveRows();
1257 }
1258 
1260 {
1261  int row = rowCount( parent ); // only consider appending
1262  beginInsertRows( parent, row, row + count - 1 );
1263 }
1264 
1266 {
1267  emit endInsertRows();
1268 }
1269 
1271 {
1272  mFeatureCountMap = theCountMap;
1273  updateRule( QModelIndex() );
1274 }
1275 
1277 {
1279  updateRule( QModelIndex() );
1280 }
bool hasIndex(int row, int column, const QModelIndex &parent) const
QLayout * layout() const
void customContextMenuRequested(const QPoint &pos)
QgsRuleBasedRendererV2Widget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
bool active() const
Returns if this rule is active.
QgsRendererRulePropsDialog(QgsRuleBasedRendererV2::Rule *rule, QgsVectorLayer *layer, QgsStyleV2 *style, QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr)
static QDomElement saveSymbols(QgsSymbolV2Map &symbols, const QString &tagName, QDomDocument &doc)
Class for parsing and evaluation of expressions (formerly called "search strings").
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 setLabel(const QString &label)
void clear()
const QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Wrapper for iterator of features from vector data provider or vector layer.
Symbol selector widget that cna be used to select and build a symbol.
static QgsSymbolV2Map loadSymbols(QDomElement &element)
QByteArray toByteArray() const
static unsigned index
void refineRuleScalesGui(const QModelIndexList &index)
void setContentsMargins(int left, int top, int right, int bottom)
virtual QString filter(const QgsFields &fields=QgsFields()) override
If a renderer does not require all the features this method may be overridden and return an expressio...
QByteArray data(const QString &mimeType) const
void setupUi(QWidget *widget)
int bottom() const
virtual void reject()
void keyPressEvent(QKeyEvent *event) override
Overridden key press event to handle the esc event on the widget.
QgsRuleBasedRendererV2Model * mModel
QgsRuleBasedRendererV2::Rule * rule()
Return the current set rule.
QModelIndex currentIndex() const
const QMimeData * mimeData(Mode mode) const
QDomNode appendChild(const QDomNode &newChild)
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
void setMaximum(int maximum)
static QgsExpressionContextScope * atlasScope(const QgsAtlasComposition *atlas)
Creates a new scope which contains variables and functions relating to a QgsAtlasComposition.
QString attribute(const QString &name, const QString &defValue) const
void setWindowModality(Qt::WindowModality windowModality)
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
virtual bool hasFormat(const QString &mimeType) const
void setActive(bool state)
Sets if this rule is active.
QString toString(int indent) const
QObject * sender() const
void setScaleMaxDenom(int scaleMaxDenom)
Set the maximum denominator for which this rule shall apply.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
virtual QgsSymbolV2 * clone() const =0
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void rejected()
QStyle * style() const
void testFilter()
Test the filter that is set in the widget.
void setRendererScale(double scale)
void setIcon(const QIcon &icon)
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
const QObjectList & children() const
QgsRuleBasedRendererV2::Rule * ruleForIndex(const QModelIndex &index) const
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
void addAction(QAction *action)
QgsMapCanvas * mMapCanvas
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QList< QgsSymbolV2 * > selectedSymbols() override
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
void refineRuleCategoriesGui(const QModelIndexList &index)
QgsRuleBasedRendererV2Model(QgsRuleBasedRendererV2 *r)
QgsRuleBasedRendererV2::Rule * mRule
QDomElement nextSiblingElement(const QString &tagName) const
Qt::DropActions supportedDropActions() const override
void accepted()
QDomElement save(QDomDocument &doc, QgsSymbolV2Map &symbolMap) const
int exec()
QgsRuleBasedRendererV2::RuleList mCopyBuffer
Base class for any widget that can be shown as a inline panel.
QDomElement documentElement() const
void updateRule(const QModelIndex &parent, int row)
virtual QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
void saveSectionWidth(int section, int oldSize, int newSize)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
virtual QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
void clear()
QgsRuleBasedRendererV2::Rule * currentRule()
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
bool isElse()
Check if this rule is an ELSE rule.
QString tr(const char *sourceText, const char *disambiguation, int n)
StandardButton information(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:109
void removeChildAt(int i)
delete child rule
int size() const
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs...
QgsFields fields() const
Returns the list of fields of this layer.
QgsRendererRulePropsWidget(QgsRuleBasedRendererV2::Rule *rule, QgsVectorLayer *layer, QgsStyleV2 *style, QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr)
Widget to edit the details of a rule based renderer rule.
QString description() const
A human readable description for this rule.
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
The QgsMapSettings class contains configuration for rendering of the map.
int indexOf(const T &value, int from) const
void resizeSection(int logicalIndex, int size)
virtual QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
QList< Key > keys() const
void setValue(const QString &key, const QVariant &value)
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
void setValue(int progress)
bool isValid() const
void refineRuleRangesGui(const QModelIndexList &index)
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QString number(int n, int base)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
int count(const T &value) const
QgsVectorLayer * mLayer
QgsSymbolV2SelectorWidget * mSymbolSelector
void append(const T &value)
static void refineRuleCategories(Rule *initialRule, QgsCategorizedSymbolRendererV2 *r)
take a rule and create a list of new rules based on the categories from categorized symbol renderer ...
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
void setLayout(QLayout *layout)
int toInt(bool *ok) const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
bool hasAttribute(const QString &name) const
virtual void stopRender(QgsRenderContext &context) override
Needs to be called when a render cycle has finished to clean up.
QClipboard * clipboard()
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
bool restoreGeometry(const QByteArray &geometry)
static QString _formatScale(int denom)
void setAttribute(const QString &name, const QString &value)
void buildExpression()
Open the expression builder widget to check if the.
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
int toInt(bool *ok, int base) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static Rule * create(QDomElement &ruleElem, QgsSymbolV2Map &symbolMap)
Create a rule from an XML definition.
bool isEmpty() const
void beginRemoveRows(const QModelIndex &parent, int first, int last)
int row() const
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setOverrideCursor(const QCursor &cursor)
QList< int > QgsAttributeList
This class keeps data about a rules for rule-based renderer.
void restoreOverrideCursor()
void * internalPointer() const
Rule * clone() const
clone this rule, return new instance
QModelIndex parent() const
RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
Single scope for storing variables and functions for use within a QgsExpressionContext.
QMap< QgsRuleBasedRendererV2::Rule *, QgsRuleBasedRendererV2Count > mFeatureCountMap
void setMimeData(QMimeData *src, Mode mode)
QModelIndex parent() const
void setMargin(int margin)
void removeRule(const QModelIndex &index)
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
bool atEnd() const
static void refineRuleRanges(Rule *initialRule, QgsGraduatedSymbolRendererV2 *r)
take a rule and create a list of new rules based on the ranges from graduated symbol renderer ...
void addWidget(QWidget *w)
virtual void accept()
void widgetChanged()
Emitted when the widget state changes.
void currentRuleChanged(const QModelIndex &current=QModelIndex(), const QModelIndex &previous=QModelIndex())
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
void setFeatureCounts(const QMap< QgsRuleBasedRendererV2::Rule *, QgsRuleBasedRendererV2Count > &theCountMap)
QModelIndex createIndex(int row, int column, void *ptr) const
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
int key() const
void setShortcut(const QKeySequence &shortcut)
QgsExpressionContext & expressionContext()
Gets the expression context.
QString filterExpression() const
A filter that will check if this rule applies.
QMimeData * mimeData(const QModelIndexList &indexes) const override
void setItalic(bool enable)
void beginInsertRows(const QModelIndex &parent, int first, int last)
bool isNull() const
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void contextMenuViewCategories(QPoint p)
QString & replace(int position, int n, QChar after)
void setForceOrderingEnabled(bool enabled)
QVariant value(const QString &key, const QVariant &defaultValue) const
QStringList mimeTypes() const override
Contains information about the context of a rendering operation.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object...
void insertRule(const QModelIndex &parent, int before, QgsRuleBasedRendererV2::Rule *newrule)
QgsExpressionContextScope & expressionContextScope()
Returns a reference to the expression context scope for the map canvas.
Definition: qgsmapcanvas.h:455
void setPanelTitle(QString panelTitle)
Set the title of the panel when shown in the interface.
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
QByteArray saveGeometry() const
typedef DropActions
void apply()
Apply any changes from the widget to the set rule.
Rule * parent()
The parent rule.
QAction * addMenu(QMenu *menu)
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
RuleList rulesForFeature(QgsFeature &feat, QgsRenderContext *context=nullptr)
tell which rules will be used to render the feature
QDomElement firstChildElement(const QString &tagName) const
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
provide model index for parent&#39;s child item
virtual int columnCount(const QModelIndex &=QModelIndex()) const override
QgsRuleBasedRendererV2::RuleList selectedRules()
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
Needs to be called when a new render cycle is started.
RuleList & children()
Return all children rules of this rule.
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
virtual void setDockMode(bool dockMode)
Set the widget in dock mode.
int column() const
Base class for renderer settings widgets.
virtual QList< QString > usedAttributes() override
Returns a set of attributes required for this renderer.
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
static QgsRuleBasedRendererV2 * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsRuleBasedRendererV2 from an existing renderer.
QString tagName() const
void _labeling2rendererRules(QDomElement &ruleElem)
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...
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
const_iterator constEnd() const
void insertChild(int i, Rule *rule)
add child rule, take ownership, sets this as parent
void setFilterExpression(const QString &filterExp)
Set the expression used to check if a given feature shall be rendered with this rule.
QDomElement createElement(const QString &tagName)
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
bool isValid() const
Geometry is not required. It may still be returned if e.g. required for a filter condition.
void setScaleMinDenom(int scaleMinDenom)
Set the minimum denominator for which this rule shall apply.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
Represents a vector layer which manages a vector based data sets.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
virtual bool event(QEvent *event)
int count(const Key &key) const
A generic dialog for building expression strings.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="") override
return a list of item text / symbol
QString dump(int indent=0) const
Dump for debug purpose.
void willAddRules(const QModelIndex &parent, int count)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
static void refineRuleScales(Rule *initialRule, QList< int > scales)
take a rule and create a list of new rules with intervals of scales given by the passed scale denomin...
typedef ItemFlags