QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsrulebasedrendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrulebasedrendererwidget.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 "qgsrulebasedrenderer.h"
19 #include "qgsfeatureiterator.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgssymbol.h"
22 #include "qgsvectorlayer.h"
23 #include "qgsapplication.h"
24 #include "qgsexpression.h"
26 #include "qgslogger.h"
27 #include "qgsreadwritecontext.h"
28 #include "qstring.h"
30 #include "qgspanelwidget.h"
31 #include "qgsmapcanvas.h"
32 #include "qgssettings.h"
33 #include "qgsguiutils.h"
34 
35 #include <QKeyEvent>
36 #include <QMenu>
37 #include <QProgressDialog>
38 #include <QTreeWidgetItem>
39 #include <QVBoxLayout>
40 #include <QMessageBox>
41 #include <QClipboard>
42 
43 #ifdef ENABLE_MODELTEST
44 #include "modeltest.h"
45 #endif
46 
47 
49 {
50  return new QgsRuleBasedRendererWidget( layer, style, renderer );
51 }
52 
54  : QgsRendererWidget( layer, style )
55  , mContextMenu( new QMenu( this ) )
56 {
57  mRenderer = nullptr;
58  // try to recognize the previous renderer
59  // (null renderer means "no previous renderer")
60 
61 
62  if ( renderer )
63  {
65  }
66  if ( !mRenderer )
67  {
68  // some default options
70 
71  mRenderer = new QgsRuleBasedRenderer( symbol );
72  }
73 
74  setupUi( this );
75  this->layout()->setContentsMargins( 0, 0, 0, 0 );
76 
77  mModel = new QgsRuleBasedRendererModel( mRenderer, viewRules );
78 #ifdef ENABLE_MODELTEST
79  new ModelTest( mModel, this ); // for model validity checking
80 #endif
81  viewRules->setModel( mModel );
82 
83  mDeleteAction = new QAction( tr( "Remove Rule" ), this );
84  mDeleteAction->setShortcut( QKeySequence( QKeySequence::Delete ) );
85 
86  viewRules->addAction( mCopyAction );
87  viewRules->addAction( mPasteAction );
88  viewRules->addAction( mDeleteAction );
89 
90  mRefineMenu = new QMenu( tr( "Refine Current Rule" ), btnRefineRule );
91  mRefineMenu->addAction( tr( "Add Scales to Rule" ), this, SLOT( refineRuleScales() ) );
92  mRefineMenu->addAction( tr( "Add Categories to Rule" ), this, SLOT( refineRuleCategories() ) );
93  mRefineMenu->addAction( tr( "Add Ranges to Rule" ), this, SLOT( refineRuleRanges() ) );
94  btnRefineRule->setMenu( mRefineMenu );
95 
96  btnAddRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
97  btnEditRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.svg" ) ) );
98  btnRemoveRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
99 
100  connect( viewRules, &QAbstractItemView::doubleClicked, this, static_cast < void ( QgsRuleBasedRendererWidget::* )( const QModelIndex &index ) > ( &QgsRuleBasedRendererWidget::editRule ) );
101 
102  // support for context menu (now handled generically)
103  connect( viewRules, &QWidget::customContextMenuRequested, this, &QgsRuleBasedRendererWidget::showContextMenu );
104 
105  connect( viewRules->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsRuleBasedRendererWidget::currentRuleChanged );
106  connect( viewRules->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsRuleBasedRendererWidget::selectedRulesChanged );
107 
108  connect( btnAddRule, &QAbstractButton::clicked, this, &QgsRuleBasedRendererWidget::addRule );
109  connect( btnEditRule, &QAbstractButton::clicked, this, static_cast < void ( QgsRuleBasedRendererWidget::* )() > ( &QgsRuleBasedRendererWidget::editRule ) );
110  connect( btnRemoveRule, &QAbstractButton::clicked, this, &QgsRuleBasedRendererWidget::removeRule );
111  connect( mDeleteAction, &QAction::triggered, this, &QgsRuleBasedRendererWidget::removeRule );
112  connect( btnCountFeatures, &QAbstractButton::clicked, this, &QgsRuleBasedRendererWidget::countFeatures );
113 
114  connect( btnRenderingOrder, &QAbstractButton::clicked, this, &QgsRuleBasedRendererWidget::setRenderingOrder );
115 
116  connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged );
117  connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsPanelWidget::widgetChanged );
118  connect( mModel, &QAbstractItemModel::rowsRemoved, this, &QgsPanelWidget::widgetChanged );
119 
122 
123  // store/restore header section widths
124  connect( viewRules->header(), &QHeaderView::sectionResized, this, &QgsRuleBasedRendererWidget::saveSectionWidth );
125 
127 
128  connect( mContextMenu, &QMenu::aboutToShow, this, [ = ]
129  {
130  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
131  mPasteSymbolAction->setEnabled( static_cast< bool >( tempSymbol ) );
132  } );
133 }
134 
136 {
137  qDeleteAll( mCopyBuffer );
138  delete mRenderer;
139 }
140 
142 {
143  return mRenderer;
144 }
145 
147 {
148  if ( dockMode )
149  {
150  // when in dock mode, these shortcuts conflict with the main window shortcuts and cannot be used
151  if ( mDeleteAction )
152  mDeleteAction->setShortcut( QKeySequence() );
153  }
154  QgsRendererWidget::setDockMode( dockMode );
155 }
156 
158 {
159  QgsSymbol *s = QgsSymbol::defaultSymbol( mLayer->geometryType() );
161 
162  QgsRuleBasedRenderer::Rule *current = currentRule();
163  if ( current )
164  {
165  // add after this rule
166  QModelIndex currentIndex = viewRules->selectionModel()->currentIndex();
167  mModel->insertRule( currentIndex.parent(), currentIndex.row() + 1, newrule );
168  QModelIndex newindex = mModel->index( currentIndex.row() + 1, 0, currentIndex.parent() );
169  viewRules->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect );
170  }
171  else
172  {
173  // append to root rule
174  int rows = mModel->rowCount();
175  mModel->insertRule( QModelIndex(), rows, newrule );
176  QModelIndex newindex = mModel->index( rows, 0 );
177  viewRules->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect );
178  }
179  editRule();
180 }
181 
183 {
184  QItemSelectionModel *sel = viewRules->selectionModel();
185  QModelIndex idx = sel->currentIndex();
186  if ( !idx.isValid() )
187  return nullptr;
188  return mModel->ruleForIndex( idx );
189 }
190 
192 {
193  editRule( viewRules->selectionModel()->currentIndex() );
194 }
195 
196 void QgsRuleBasedRendererWidget::editRule( const QModelIndex &index )
197 {
198  if ( !index.isValid() )
199  return;
200 
201  QgsRuleBasedRenderer::Rule *rule = mModel->ruleForIndex( index );
203 
204  if ( panel && panel->dockMode() )
205  {
206  QgsRendererRulePropsWidget *widget = new QgsRendererRulePropsWidget( rule, mLayer, mStyle, this, mContext );//panel?
207  widget->setPanelTitle( tr( "Edit Rule" ) );
208  connect( widget, &QgsPanelWidget::panelAccepted, this, &QgsRuleBasedRendererWidget::ruleWidgetPanelAccepted );
209  connect( widget, &QgsPanelWidget::widgetChanged, this, &QgsRuleBasedRendererWidget::liveUpdateRuleFromPanel );
210  openPanel( widget );
211  return;
212  }
213 
214  QgsRendererRulePropsDialog dlg( rule, mLayer, mStyle, this, mContext );
215  if ( dlg.exec() )
216  {
217  mModel->updateRule( index.parent(), index.row() );
218  mModel->clearFeatureCounts();
219  emit widgetChanged();
220  }
221 }
222 
224 {
225  QItemSelection sel = viewRules->selectionModel()->selection();
226  QgsDebugMsg( QStringLiteral( "REMOVE RULES!!! ranges: %1" ).arg( sel.count() ) );
227  const auto constSel = sel;
228  for ( const QItemSelectionRange &range : constSel )
229  {
230  QgsDebugMsg( QStringLiteral( "RANGE: r %1 - %2" ).arg( range.top() ).arg( range.bottom() ) );
231  if ( range.isValid() )
232  mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
233  }
234  // make sure that the selection is gone
235  viewRules->selectionModel()->clear();
236  mModel->clearFeatureCounts();
237 }
238 
239 void QgsRuleBasedRendererWidget::currentRuleChanged( const QModelIndex &current, const QModelIndex &previous )
240 {
241  Q_UNUSED( previous )
242  btnEditRule->setEnabled( current.isValid() );
243 }
244 
245 
251 #include <QDialogButtonBox>
252 #include <QInputDialog>
253 #include <QClipboard>
254 
256 {
257  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
258 
259  if ( indexlist.isEmpty() )
260  return;
261 
262 
263  if ( type == 0 ) // categories
264  refineRuleCategoriesGui();
265  else if ( type == 1 ) // ranges
266  refineRuleRangesGui();
267  else // scales
268  refineRuleScalesGui( indexlist );
269 
270  // TODO: set initial rule's symbol to NULL (?)
271 
272  // show the newly added rules
273  const auto constIndexlist = indexlist;
274  for ( const QModelIndex &index : constIndexlist )
275  viewRules->expand( index );
276 }
277 
279 {
280  refineRule( 0 );
281 }
282 
284 {
285  refineRule( 1 );
286 }
287 
289 {
290  refineRule( 2 );
291 }
292 
294 {
295  QgsCategorizedSymbolRendererWidget *w = new QgsCategorizedSymbolRendererWidget( mLayer, mStyle, nullptr );
296  w->setPanelTitle( tr( "Add Categories to Rules" ) );
297  connect( w, &QgsPanelWidget::panelAccepted, this, &QgsRuleBasedRendererWidget::refineRuleCategoriesAccepted );
298  w->setContext( mContext );
299  openPanel( w );
300 }
301 
303 {
304  QgsGraduatedSymbolRendererWidget *w = new QgsGraduatedSymbolRendererWidget( mLayer, mStyle, nullptr );
305  w->setPanelTitle( tr( "Add Ranges to Rules" ) );
306  connect( w, &QgsPanelWidget::panelAccepted, this, &QgsRuleBasedRendererWidget::refineRuleRangesAccepted );
307  w->setContext( mContext );
308  openPanel( w );
309 }
310 
311 void QgsRuleBasedRendererWidget::refineRuleScalesGui( const QModelIndexList &indexList )
312 {
313  for ( const QModelIndex &index : indexList )
314  {
315  QgsRuleBasedRenderer::Rule *initialRule = mModel->ruleForIndex( index );
316 
317  // If any of the rules don't have a symbol let the user know and exit.
318  if ( !initialRule->symbol() )
319  {
320  QMessageBox::warning( this, tr( "Scale Refinement" ), tr( "Parent rule %1 must have a symbol for this operation." ).arg( initialRule->label() ) );
321  return;
322  }
323  }
324 
325  QString txt = QInputDialog::getText( this,
326  tr( "Scale Refinement" ),
327  tr( "Please enter scale denominators at which will split the rule, separate them by commas (e.g. 1000,5000):" ) );
328  if ( txt.isEmpty() )
329  return;
330 
331  QList<int> scales;
332  bool ok;
333  const auto constSplit = txt.split( ',' );
334  for ( const QString &item : constSplit )
335  {
336  int scale = item.toInt( &ok );
337  if ( ok )
338  scales.append( scale );
339  else
340  QMessageBox::information( this, tr( "Scale Refinement" ), tr( "\"%1\" is not valid scale denominator, ignoring it." ).arg( item ) );
341  }
342 
343  for ( const QModelIndex &index : indexList )
344  {
345  QgsRuleBasedRenderer::Rule *initialRule = mModel->ruleForIndex( index );
346  mModel->willAddRules( index, scales.count() + 1 );
347  QgsRuleBasedRenderer::refineRuleScales( initialRule, scales );
348  }
349  mModel->finishedAddingRules();
350 }
351 
353 {
354  QList<QgsSymbol *> symbolList;
355 
356  if ( !mRenderer )
357  {
358  return symbolList;
359  }
360 
361  QItemSelection sel = viewRules->selectionModel()->selection();
362  const auto constSel = sel;
363  for ( const QItemSelectionRange &range : constSel )
364  {
365  QModelIndex parent = range.parent();
366  QgsRuleBasedRenderer::Rule *parentRule = mModel->ruleForIndex( parent );
367  const QgsRuleBasedRenderer::RuleList &children = parentRule->children();
368  for ( int row = range.top(); row <= range.bottom(); row++ )
369  {
370  symbolList.append( children.at( row )->symbol() );
371  }
372  }
373 
374  return symbolList;
375 }
376 
378 {
380  QItemSelection sel = viewRules->selectionModel()->selection();
381  const auto constSel = sel;
382  for ( const QItemSelectionRange &range : constSel )
383  {
384  QModelIndex parent = range.parent();
385  QgsRuleBasedRenderer::Rule *parentRule = mModel->ruleForIndex( parent );
386  const QgsRuleBasedRenderer::RuleList &children = parentRule->children();
387  for ( int row = range.top(); row <= range.bottom(); row++ )
388  {
389  rl.append( children.at( row )->clone() );
390  }
391  }
392  return rl;
393 }
394 
396 {
397  // TODO: model/view
398  /*
399  if ( treeRules )
400  {
401  treeRules->populateRules();
402  }
403  */
404  emit widgetChanged();
405 }
406 
408 {
409  if ( !event )
410  {
411  return;
412  }
413 
414  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
415  {
416  qDeleteAll( mCopyBuffer );
417  mCopyBuffer.clear();
418  mCopyBuffer = selectedRules();
419  }
420  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
421  {
422  QgsRuleBasedRenderer::RuleList::const_iterator rIt = mCopyBuffer.constBegin();
423  for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
424  {
425  int rows = mModel->rowCount();
426  mModel->insertRule( QModelIndex(), rows, ( *rIt )->clone() );
427  }
428  }
429 }
430 
431 #include "qgssymbollevelsdialog.h"
432 
434 {
436  if ( panel && panel->dockMode() )
437  {
438  QgsSymbolLevelsWidget *widget = new QgsSymbolLevelsWidget( mRenderer, true, panel );
439  widget->setForceOrderingEnabled( true );
440  widget->setPanelTitle( tr( "Symbol Levels" ) );
441  connect( widget, &QgsPanelWidget::widgetChanged, widget, &QgsSymbolLevelsWidget::apply );
443  panel->openPanel( widget );
444  return;
445  }
446 
447  QgsSymbolLevelsDialog dlg( mRenderer, true, panel );
448  dlg.setForceOrderingEnabled( true );
449  if ( dlg.exec() )
450  {
451  emit widgetChanged();
452  }
453 }
454 
455 void QgsRuleBasedRendererWidget::saveSectionWidth( int section, int oldSize, int newSize )
456 {
457  Q_UNUSED( oldSize )
458  // skip last section, as it stretches
459  if ( section == 5 )
460  return;
461  QgsSettings settings;
462  QString path = "/Windows/RuleBasedTree/sectionWidth/" + QString::number( section );
463  settings.setValue( path, newSize );
464 }
465 
467 {
468  QgsSettings settings;
469  QString path = QStringLiteral( "/Windows/RuleBasedTree/sectionWidth/" );
470  QHeaderView *head = viewRules->header();
471  head->resizeSection( 0, settings.value( path + QString::number( 0 ), 150 ).toInt() );
472  head->resizeSection( 1, settings.value( path + QString::number( 1 ), 150 ).toInt() );
473  head->resizeSection( 2, settings.value( path + QString::number( 2 ), 80 ).toInt() );
474  head->resizeSection( 3, settings.value( path + QString::number( 3 ), 80 ).toInt() );
475  head->resizeSection( 4, settings.value( path + QString::number( 4 ), 50 ).toInt() );
476  head->resizeSection( 5, settings.value( path + QString::number( 5 ), 50 ).toInt() );
477 }
478 
480 {
481  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
482  QgsDebugMsgLevel( QString::number( indexlist.count() ), 2 );
483 
484  if ( indexlist.isEmpty() )
485  return;
486 
487  QMimeData *mime = mModel->mimeData( indexlist );
488  QApplication::clipboard()->setMimeData( mime );
489 }
490 
492 {
493  const QMimeData *mime = QApplication::clipboard()->mimeData();
494  QModelIndexList indexlist = viewRules->selectionModel()->selectedRows();
495  QModelIndex index;
496  if ( indexlist.isEmpty() )
497  index = mModel->index( mModel->rowCount(), 0 );
498  else
499  index = indexlist.first();
500  mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() );
501 }
502 
504 {
505  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
506  if ( !tempSymbol )
507  return;
508 
509  const QModelIndexList indexList = viewRules->selectionModel()->selectedRows();
510  for ( const QModelIndex &index : indexList )
511  {
512  if ( QgsRuleBasedRenderer::Rule *rule = mModel->ruleForIndex( index ) )
513  {
514  if ( !rule->symbol() || rule->symbol()->type() != tempSymbol->type() )
515  continue;
516 
517  mModel->setSymbol( index, tempSymbol->clone() );
518  }
519  }
520  emit widgetChanged();
521 }
522 
523 void QgsRuleBasedRendererWidget::refineRuleCategoriesAccepted( QgsPanelWidget *panel )
524 {
525  QgsCategorizedSymbolRendererWidget *w = qobject_cast<QgsCategorizedSymbolRendererWidget *>( panel );
526 
527  // create new rules
528  QgsCategorizedSymbolRenderer *r = static_cast<QgsCategorizedSymbolRenderer *>( w->renderer() );
529  QModelIndexList indexList = viewRules->selectionModel()->selectedRows();
530  const auto constIndexList = indexList;
531  for ( const QModelIndex &index : constIndexList )
532  {
533  QgsRuleBasedRenderer::Rule *initialRule = mModel->ruleForIndex( index );
534  mModel->willAddRules( index, r->categories().count() );
536  }
537  mModel->finishedAddingRules();
538 }
539 
540 void QgsRuleBasedRendererWidget::refineRuleRangesAccepted( QgsPanelWidget *panel )
541 {
542  QgsGraduatedSymbolRendererWidget *w = qobject_cast<QgsGraduatedSymbolRendererWidget *>( panel );
543  // create new rules
544  QgsGraduatedSymbolRenderer *r = static_cast<QgsGraduatedSymbolRenderer *>( w->renderer() );
545  QModelIndexList indexList = viewRules->selectionModel()->selectedRows();
546  const auto constIndexList = indexList;
547  for ( const QModelIndex &index : constIndexList )
548  {
549  QgsRuleBasedRenderer::Rule *initialRule = mModel->ruleForIndex( index );
550  mModel->willAddRules( index, r->ranges().count() );
551  QgsRuleBasedRenderer::refineRuleRanges( initialRule, r );
552  }
553  mModel->finishedAddingRules();
554 }
555 
556 void QgsRuleBasedRendererWidget::ruleWidgetPanelAccepted( QgsPanelWidget *panel )
557 {
558  QgsRendererRulePropsWidget *widget = qobject_cast<QgsRendererRulePropsWidget *>( panel );
559  if ( !widget )
560  return;
561 
562  widget->apply();
563 
564  // model should know about the change and emit dataChanged signal for the view
565  QModelIndex index = viewRules->selectionModel()->currentIndex();
566  mModel->updateRule( index.parent(), index.row() );
567  mModel->clearFeatureCounts();
568 }
569 
570 void QgsRuleBasedRendererWidget::liveUpdateRuleFromPanel()
571 {
572  ruleWidgetPanelAccepted( qobject_cast<QgsPanelWidget *>( sender() ) );
573 }
574 
575 void QgsRuleBasedRendererWidget::showContextMenu( QPoint )
576 {
577  mContextMenu->clear();
578  mContextMenu->addAction( mCopyAction );
579  mContextMenu->addAction( mPasteAction );
580 
581  const QList< QAction * > actions = contextMenu->actions();
582  for ( QAction *act : actions )
583  {
584  mContextMenu->addAction( act );
585  }
586 
587  mContextMenu->addMenu( mRefineMenu );
588 
589  mContextMenu->exec( QCursor::pos() );
590 }
591 
592 
594 {
595  if ( !mLayer || !mRenderer || !mRenderer->rootRule() )
596  {
597  return;
598  }
599  QHash<QgsRuleBasedRenderer::Rule *, QgsRuleBasedRendererCount> countMap;
600 
601  QgsRuleBasedRenderer::RuleList ruleList = mRenderer->rootRule()->descendants();
602  // insert all so that we have counts 0
603  const auto constRuleList = ruleList;
604  for ( QgsRuleBasedRenderer::Rule *rule : constRuleList )
605  {
606  countMap[rule].count = 0;
607  countMap[rule].duplicateCount = 0;
608  }
609 
610  QgsRenderContext renderContext;
611  renderContext.setRendererScale( 0 ); // ignore scale
612 
613  QgsExpressionContext context( mContext.globalProjectAtlasMapLayerScopes( mLayer ) );
614 
615  // additional scopes
616  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
617  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
618  {
619  context.appendScope( new QgsExpressionContextScope( scope ) );
620  }
621 
622  renderContext.setExpressionContext( context );
623 
624  mRenderer->startRender( renderContext, mLayer->fields() );
625  // QgsRuleBasedRenderer::filter must be called after startRender
626  QgsFeatureRequest req = QgsFeatureRequest().setFilterExpression( mRenderer->filter( mLayer->fields() ) );
627  req.setExpressionContext( context );
628  req.setSubsetOfAttributes( mRenderer->usedAttributes( renderContext ), mLayer->fields() );
629  QgsFeatureIterator fit = mLayer->getFeatures( req );
630 
631  int nFeatures = mLayer->featureCount();
632  QProgressDialog p( tr( "Calculating feature count." ), tr( "Abort" ), 0, nFeatures );
633  p.setWindowModality( Qt::WindowModal );
634  int featuresCounted = 0;
635 
636  QgsFeature f;
637  while ( fit.nextFeature( f ) )
638  {
639  renderContext.expressionContext().setFeature( f );
640  QgsRuleBasedRenderer::RuleList featureRuleList = mRenderer->rootRule()->rulesForFeature( f, &renderContext );
641 
642  const auto constFeatureRuleList = featureRuleList;
643  for ( QgsRuleBasedRenderer::Rule *rule : constFeatureRuleList )
644  {
645  countMap[rule].count++;
646  if ( featureRuleList.size() > 1 )
647  {
648  countMap[rule].duplicateCount++;
649  }
650  const auto constFeatureRuleList = featureRuleList;
651  for ( QgsRuleBasedRenderer::Rule *duplicateRule : constFeatureRuleList )
652  {
653  if ( duplicateRule == rule ) continue;
654  countMap[rule].duplicateCountMap[duplicateRule] += 1;
655  }
656  }
657  ++featuresCounted;
658  if ( featuresCounted % 50 == 0 )
659  {
660  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
661  {
662  p.setMaximum( 0 );
663  }
664  p.setValue( featuresCounted );
665  if ( p.wasCanceled() )
666  {
667  return;
668  }
669  }
670  }
671  p.setValue( nFeatures );
672 
673  mRenderer->stopRender( renderContext );
674 
675 #ifdef QGISDEBUG
676  const auto constKeys = countMap.keys();
677  for ( QgsRuleBasedRenderer::Rule *rule : constKeys )
678  {
679  QgsDebugMsg( QStringLiteral( "rule: %1 count %2" ).arg( rule->label() ).arg( countMap[rule].count ) );
680  }
681 #endif
682 
683  mModel->setFeatureCounts( countMap );
684 }
685 
687 {
688  bool enabled = !viewRules->selectionModel()->selectedIndexes().isEmpty();
689  btnRefineRule->setEnabled( enabled );
690  btnRemoveRule->setEnabled( enabled );
691 }
692 
694 
696  : QgsPanelWidget( parent )
697  , mRule( rule )
698  , mLayer( layer )
699  , mContext( context )
700 {
701  setupUi( this );
702  layout()->setContentsMargins( 0, 0, 0, 0 );
703 
704  mElseRadio->setChecked( mRule->isElse() );
705  mFilterRadio->setChecked( !mRule->isElse() );
706  editFilter->setText( mRule->filterExpression() );
707  editFilter->setToolTip( mRule->filterExpression() );
708  editLabel->setText( mRule->label() );
709  editDescription->setText( mRule->description() );
710  editDescription->setToolTip( mRule->description() );
711 
712  if ( mRule->dependsOnScale() )
713  {
714  groupScale->setChecked( true );
715  mScaleRangeWidget->setScaleRange( std::max( rule->minimumScale(), 0.0 ),
716  std::max( rule->maximumScale(), 0.0 ) );
717  }
718  mScaleRangeWidget->setMapCanvas( mContext.mapCanvas() );
719 
720  if ( mRule->symbol() )
721  {
722  groupSymbol->setChecked( true );
723  mSymbol = mRule->symbol()->clone(); // use a clone!
724  }
725  else
726  {
727  groupSymbol->setChecked( false );
729  }
730 
731  mSymbolSelector = new QgsSymbolSelectorWidget( mSymbol, style, mLayer, this );
735 
736  QVBoxLayout *l = new QVBoxLayout;
737  l->addWidget( mSymbolSelector );
738  groupSymbol->setLayout( l );
739 
740  connect( btnExpressionBuilder, &QAbstractButton::clicked, this, &QgsRendererRulePropsWidget::buildExpression );
741  connect( btnTestFilter, &QAbstractButton::clicked, this, &QgsRendererRulePropsWidget::testFilter );
742  connect( editFilter, &QLineEdit::textChanged, this, &QgsPanelWidget::widgetChanged );
743  connect( editLabel, &QLineEdit::editingFinished, this, &QgsPanelWidget::widgetChanged );
744  connect( editDescription, &QLineEdit::editingFinished, this, &QgsPanelWidget::widgetChanged );
745  connect( groupSymbol, &QGroupBox::toggled, this, &QgsPanelWidget::widgetChanged );
746  connect( groupScale, &QGroupBox::toggled, this, &QgsPanelWidget::widgetChanged );
747  connect( mScaleRangeWidget, &QgsScaleRangeWidget::rangeChanged, this, &QgsPanelWidget::widgetChanged );
748  connect( mFilterRadio, &QRadioButton::toggled, this, [ = ]( bool toggled ) { filterFrame->setEnabled( toggled ) ; } );
749  connect( mElseRadio, &QRadioButton::toggled, this, [ = ]( bool toggled ) { if ( toggled ) editFilter->setText( QStringLiteral( "ELSE" ) );} );
750 }
751 
752 #include "qgsvscrollarea.h"
753 
755  : QDialog( parent )
756 {
757 
758 #ifdef Q_OS_MAC
759  setWindowModality( Qt::WindowModal );
760 #endif
761 
762  QVBoxLayout *layout = new QVBoxLayout( this );
763  QgsVScrollArea *scrollArea = new QgsVScrollArea( this );
764  scrollArea->setFrameShape( QFrame::NoFrame );
765  layout->addWidget( scrollArea );
766 
767  buttonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
768  mPropsWidget = new QgsRendererRulePropsWidget( rule, layer, style, this, context );
769 
770  scrollArea->setWidget( mPropsWidget );
771  layout->addWidget( buttonBox );
772  this->setWindowTitle( "Edit Rule" );
774 
775  connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsRendererRulePropsDialog::accept );
776  connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
777  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRendererRulePropsDialog::showHelp );
778 }
779 
781 {
782  mPropsWidget->testFilter();
783 }
784 
786 {
787  mPropsWidget->buildExpression();
788 }
789 
791 {
792  mPropsWidget->apply();
793  QDialog::accept();
794 }
795 
796 void QgsRendererRulePropsDialog::showHelp()
797 {
798  QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#rule-based-rendering" ) );
799 }
800 
801 
803 {
804  QgsExpressionContext context( mContext.globalProjectAtlasMapLayerScopes( mLayer ) );
805 
806  // additional scopes
807  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
808  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
809  {
810  context.appendScope( new QgsExpressionContextScope( scope ) );
811  }
812 
813  QgsExpressionBuilderDialog dlg( mLayer, editFilter->text(), this, QStringLiteral( "generic" ), context );
814 
815  if ( dlg.exec() )
816  editFilter->setText( dlg.expressionText() );
817 }
818 
820 {
821  if ( !mFilterRadio->isChecked() )
822  return;
823 
824  QgsExpression filter( editFilter->text() );
825  if ( filter.hasParserError() )
826  {
827  QMessageBox::critical( this, tr( "Test Filter" ), tr( "Filter expression parsing error:\n" ) + filter.parserErrorString() );
828  return;
829  }
830 
831  QgsExpressionContext context( mContext.globalProjectAtlasMapLayerScopes( mLayer ) );
832 
833  // additional scopes
834  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
835  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
836  {
837  context.appendScope( new QgsExpressionContextScope( scope ) );
838  }
839 
840  if ( !filter.prepare( &context ) )
841  {
842  QMessageBox::critical( this, tr( "Test Filter" ), filter.evalErrorString() );
843  return;
844  }
845 
846  QApplication::setOverrideCursor( Qt::WaitCursor );
847 
850  .setFilterExpression( editFilter->text() )
851  .setExpressionContext( context );
852 
853  QgsFeatureIterator fit = mLayer->getFeatures( req );
854 
855  int count = 0;
856  QgsFeature f;
857  while ( fit.nextFeature( f ) )
858  {
859  count++;
860  }
861 
862  QApplication::restoreOverrideCursor();
863 
864  QMessageBox::information( this, tr( "Test Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) );
865 }
866 
868 {
869  QString filter = mElseRadio->isChecked() ? QStringLiteral( "ELSE" ) : editFilter->text();
870  mRule->setFilterExpression( filter );
871  mRule->setLabel( editLabel->text() );
872  mRule->setDescription( editDescription->text() );
873  // caution: rule uses scale denom, scale widget uses true scales
874  mRule->setMinimumScale( groupScale->isChecked() ? mScaleRangeWidget->minimumScale() : 0 );
875  mRule->setMaximumScale( groupScale->isChecked() ? mScaleRangeWidget->maximumScale() : 0 );
876  mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr );
877 }
878 
880 {
881  QgsPanelWidget::setDockMode( dockMode );
882  mSymbolSelector->setDockMode( dockMode );
883 }
884 
886 
887 /*
888  setDragEnabled(true);
889  viewport()->setAcceptDrops(true);
890  setDropIndicatorShown(true);
891  setDragDropMode(QAbstractItemView::InternalMove);
892 */
893 
895 
897  : QAbstractItemModel( parent )
898  , mR( renderer )
899 {
900 }
901 
902 Qt::ItemFlags QgsRuleBasedRendererModel::flags( const QModelIndex &index ) const
903 {
904  if ( !index.isValid() )
905  return Qt::ItemIsDropEnabled;
906 
907  // allow drop only at first column
908  Qt::ItemFlag drop = ( index.column() == 0 ? Qt::ItemIsDropEnabled : Qt::NoItemFlags );
909 
910  Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
911 
912  return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
913  Qt::ItemIsEditable | checkable |
914  Qt::ItemIsDragEnabled | drop;
915 }
916 
917 QVariant QgsRuleBasedRendererModel::data( const QModelIndex &index, int role ) const
918 {
919  if ( !index.isValid() )
920  return QVariant();
921 
923 
924  if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
925  {
926  switch ( index.column() )
927  {
928  case 0:
929  return rule->label();
930  case 1:
931  if ( rule->isElse() )
932  {
933  return "ELSE";
934  }
935  else
936  {
937  return rule->filterExpression().isEmpty() ? tr( "(no filter)" ) : rule->filterExpression();
938  }
939  case 2:
940  return rule->dependsOnScale() ? QgsScaleComboBox::toString( rule->minimumScale() ) : QVariant();
941  case 3:
942  return rule->dependsOnScale() ? QgsScaleComboBox::toString( rule->maximumScale() ) : QVariant();
943  case 4:
944  if ( mFeatureCountMap.count( rule ) == 1 )
945  {
946  return QVariant( mFeatureCountMap[rule].count );
947  }
948  return QVariant();
949  case 5:
950  if ( mFeatureCountMap.count( rule ) == 1 )
951  {
952  if ( role == Qt::DisplayRole )
953  {
954  return QVariant( mFeatureCountMap[rule].duplicateCount );
955  }
956  else // tooltip - detailed info about duplicates
957  {
958  if ( mFeatureCountMap[rule].duplicateCount > 0 )
959  {
960  QString tip = QStringLiteral( "<p style='margin:0px;'><ul>" );
961  const auto duplicateMap = mFeatureCountMap[rule].duplicateCountMap;
962  for ( auto it = duplicateMap.constBegin(); it != duplicateMap.constEnd(); ++it )
963  {
964  QString label = it.key()->label().replace( '&', QLatin1String( "&amp;" ) ).replace( '>', QLatin1String( "&gt;" ) ).replace( '<', QLatin1String( "&lt;" ) );
965  tip += tr( "<li><nobr>%1 features also in rule %2</nobr></li>" ).arg( it.value() ).arg( label );
966  }
967  tip += QLatin1String( "</ul>" );
968  return tip;
969  }
970  else
971  {
972  return 0;
973  }
974  }
975  }
976  return QVariant();
977  default:
978  return QVariant();
979  }
980  }
981  else if ( role == Qt::DecorationRole && index.column() == 0 && rule->symbol() )
982  {
983  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
984  return QgsSymbolLayerUtils::symbolPreviewIcon( rule->symbol(), QSize( iconSize, iconSize ) );
985  }
986  else if ( role == Qt::TextAlignmentRole )
987  {
988  return ( index.column() == 2 || index.column() == 3 ) ? Qt::AlignRight : Qt::AlignLeft;
989  }
990  else if ( role == Qt::FontRole && index.column() == 1 )
991  {
992  if ( rule->isElse() )
993  {
994  QFont italicFont;
995  italicFont.setItalic( true );
996  return italicFont;
997  }
998  return QVariant();
999  }
1000  else if ( role == Qt::EditRole )
1001  {
1002  switch ( index.column() )
1003  {
1004  case 0:
1005  return rule->label();
1006  case 1:
1007  return rule->filterExpression();
1008  case 2:
1009  return rule->minimumScale();
1010  case 3:
1011  return rule->maximumScale();
1012  default:
1013  return QVariant();
1014  }
1015  }
1016  else if ( role == Qt::CheckStateRole )
1017  {
1018  if ( index.column() != 0 )
1019  return QVariant();
1020  return rule->active() ? Qt::Checked : Qt::Unchecked;
1021  }
1022  else
1023  return QVariant();
1024 }
1025 
1026 QVariant QgsRuleBasedRendererModel::headerData( int section, Qt::Orientation orientation, int role ) const
1027 {
1028  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 7 )
1029  {
1030  QStringList lst;
1031  lst << tr( "Label" ) << tr( "Rule" ) << tr( "Min. Scale" ) << tr( "Max. Scale" ) << tr( "Count" ) << tr( "Duplicate Count" );
1032  return lst[section];
1033  }
1034  else if ( orientation == Qt::Horizontal && role == Qt::ToolTipRole )
1035  {
1036  if ( section == 4 ) // Count
1037  {
1038  return tr( "Number of features in this rule." );
1039  }
1040  else if ( section == 5 ) // Duplicate count
1041  {
1042  return tr( "Number of features in this rule which are also present in other rule(s)." );
1043  }
1044  }
1045 
1046  return QVariant();
1047 }
1048 
1049 int QgsRuleBasedRendererModel::rowCount( const QModelIndex &parent ) const
1050 {
1051  if ( parent.column() > 0 )
1052  return 0;
1053 
1055 
1056  return parentRule->children().count();
1057 }
1058 
1059 int QgsRuleBasedRendererModel::columnCount( const QModelIndex & ) const
1060 {
1061  return 6;
1062 }
1063 
1064 QModelIndex QgsRuleBasedRendererModel::index( int row, int column, const QModelIndex &parent ) const
1065 {
1066  if ( hasIndex( row, column, parent ) )
1067  {
1069  QgsRuleBasedRenderer::Rule *childRule = parentRule->children()[row];
1070  return createIndex( row, column, childRule );
1071  }
1072  return QModelIndex();
1073 }
1074 
1075 QModelIndex QgsRuleBasedRendererModel::parent( const QModelIndex &index ) const
1076 {
1077  if ( !index.isValid() )
1078  return QModelIndex();
1079 
1081  QgsRuleBasedRenderer::Rule *parentRule = childRule->parent();
1082 
1083  if ( parentRule == mR->rootRule() )
1084  return QModelIndex();
1085 
1086  // this is right: we need to know row number of our parent (in our grandparent)
1087  int row = parentRule->parent()->children().indexOf( parentRule );
1088 
1089  return createIndex( row, 0, parentRule );
1090 }
1091 
1092 bool QgsRuleBasedRendererModel::setData( const QModelIndex &index, const QVariant &value, int role )
1093 {
1094  if ( !index.isValid() )
1095  return false;
1096 
1098 
1099  if ( role == Qt::CheckStateRole )
1100  {
1101  rule->setActive( value.toInt() == Qt::Checked );
1102  emit dataChanged( index, index );
1103  return true;
1104  }
1105 
1106  if ( role != Qt::EditRole )
1107  return false;
1108 
1109  switch ( index.column() )
1110  {
1111  case 0: // label
1112  rule->setLabel( value.toString() );
1113  break;
1114  case 1: // filter
1115  rule->setFilterExpression( value.toString() );
1116  break;
1117  case 2: // scale min
1118  rule->setMinimumScale( value.toDouble() );
1119  break;
1120  case 3: // scale max
1121  rule->setMaximumScale( value.toDouble() );
1122  break;
1123  default:
1124  return false;
1125  }
1126 
1127  emit dataChanged( index, index );
1128  return true;
1129 }
1130 
1132 {
1133  return Qt::MoveAction; // | Qt::CopyAction
1134 }
1135 
1137 {
1138  QStringList types;
1139  types << QStringLiteral( "application/vnd.text.list" );
1140  return types;
1141 }
1142 
1143 QMimeData *QgsRuleBasedRendererModel::mimeData( const QModelIndexList &indexes ) const
1144 {
1145  QMimeData *mimeData = new QMimeData();
1146  QByteArray encodedData;
1147 
1148  QDataStream stream( &encodedData, QIODevice::WriteOnly );
1149 
1150  const auto constIndexes = indexes;
1151  for ( const QModelIndex &index : constIndexes )
1152  {
1153  // each item consists of several columns - let's add it with just first one
1154  if ( !index.isValid() || index.column() != 0 )
1155  continue;
1156 
1157  // we use a clone of the existing rule because it has a new unique rule key
1158  // non-unique rule keys would confuse other components using them (e.g. legend)
1160  QDomDocument doc;
1161  QgsSymbolMap symbols;
1162 
1163  QDomElement rootElem = doc.createElement( QStringLiteral( "rule_mime" ) );
1164  rootElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "renderer" ) ); // for determining whether rules are from renderer or labeling
1165  QDomElement rulesElem = rule->save( doc, symbols );
1166  rootElem.appendChild( rulesElem );
1167  QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, QgsReadWriteContext() );
1168  rootElem.appendChild( symbolsElem );
1169  doc.appendChild( rootElem );
1170 
1171  delete rule;
1172 
1173  stream << doc.toString( -1 );
1174  }
1175 
1176  mimeData->setData( QStringLiteral( "application/vnd.text.list" ), encodedData );
1177  return mimeData;
1178 }
1179 
1180 
1181 // manipulate DOM before dropping it so that rules are more useful
1182 void _labeling2rendererRules( QDomElement &ruleElem )
1183 {
1184  // labeling rules recognize only "description"
1185  if ( ruleElem.hasAttribute( QStringLiteral( "description" ) ) )
1186  ruleElem.setAttribute( QStringLiteral( "label" ), ruleElem.attribute( QStringLiteral( "description" ) ) );
1187 
1188  // run recursively
1189  QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( "rule" ) );
1190  while ( !childRuleElem.isNull() )
1191  {
1192  _labeling2rendererRules( childRuleElem );
1193  childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( "rule" ) );
1194  }
1195 }
1196 
1197 
1198 bool QgsRuleBasedRendererModel::dropMimeData( const QMimeData *data,
1199  Qt::DropAction action, int row, int column, const QModelIndex &parent )
1200 {
1201  Q_UNUSED( column )
1202 
1203  if ( action == Qt::IgnoreAction )
1204  return true;
1205 
1206  if ( !data->hasFormat( QStringLiteral( "application/vnd.text.list" ) ) )
1207  return false;
1208 
1209  if ( parent.column() > 0 )
1210  return false;
1211 
1212  QByteArray encodedData = data->data( QStringLiteral( "application/vnd.text.list" ) );
1213  QDataStream stream( &encodedData, QIODevice::ReadOnly );
1214  int rows = 0;
1215 
1216  if ( row == -1 )
1217  {
1218  // the item was dropped at a parent - we may decide where to put the items - let's append them
1219  row = rowCount( parent );
1220  }
1221 
1222  while ( !stream.atEnd() )
1223  {
1224  QString text;
1225  stream >> text;
1226 
1227  QDomDocument doc;
1228  if ( !doc.setContent( text ) )
1229  continue;
1230  QDomElement rootElem = doc.documentElement();
1231  if ( rootElem.tagName() != QLatin1String( "rule_mime" ) )
1232  continue;
1233  if ( rootElem.attribute( QStringLiteral( "type" ) ) == QLatin1String( "labeling" ) )
1234  rootElem.appendChild( doc.createElement( QStringLiteral( "symbols" ) ) );
1235  QDomElement symbolsElem = rootElem.firstChildElement( QStringLiteral( "symbols" ) );
1236  if ( symbolsElem.isNull() )
1237  continue;
1239  QDomElement ruleElem = rootElem.firstChildElement( QStringLiteral( "rule" ) );
1240  if ( rootElem.attribute( QStringLiteral( "type" ) ) == QLatin1String( "labeling" ) )
1241  _labeling2rendererRules( ruleElem );
1242  QgsRuleBasedRenderer::Rule *rule = QgsRuleBasedRenderer::Rule::create( ruleElem, symbolMap );
1243 
1244  insertRule( parent, row + rows, rule );
1245 
1246  ++rows;
1247  }
1248  return true;
1249 }
1250 
1252 {
1253  if ( index.isValid() )
1254  return static_cast<QgsRuleBasedRenderer::Rule *>( index.internalPointer() );
1255  return mR->rootRule();
1256 }
1257 
1258 bool QgsRuleBasedRendererModel::removeRows( int row, int count, const QModelIndex &parent )
1259 {
1261 
1262  if ( row < 0 || row >= parentRule->children().count() )
1263  return false;
1264 
1265  QgsDebugMsg( QStringLiteral( "Called: row %1 count %2 parent ~~%3~~" ).arg( row ).arg( count ).arg( parentRule->dump() ) );
1266 
1267  beginRemoveRows( parent, row, row + count - 1 );
1268 
1269  for ( int i = 0; i < count; i++ )
1270  {
1271  if ( row < parentRule->children().count() )
1272  {
1273  //QgsRuleBasedRenderer::Rule* r = parentRule->children()[row];
1274  parentRule->removeChildAt( row );
1275  //parentRule->takeChildAt( row );
1276  }
1277  else
1278  {
1279  QgsDebugMsg( QStringLiteral( "trying to remove invalid index - this should not happen!" ) );
1280  }
1281  }
1282 
1283  endRemoveRows();
1284 
1285  return true;
1286 }
1287 
1288 
1289 void QgsRuleBasedRendererModel::insertRule( const QModelIndex &parent, int before, QgsRuleBasedRenderer::Rule *newrule )
1290 {
1291  beginInsertRows( parent, before, before );
1292 
1293  QgsDebugMsg( QStringLiteral( "insert before %1 rule: %2" ).arg( before ).arg( newrule->dump() ) );
1294 
1296  parentRule->insertChild( before, newrule );
1297 
1298  endInsertRows();
1299 }
1300 
1301 void QgsRuleBasedRendererModel::updateRule( const QModelIndex &parent, int row )
1302 {
1303  emit dataChanged( index( row, 0, parent ),
1304  index( row, columnCount( parent ), parent ) );
1305 }
1306 
1307 void QgsRuleBasedRendererModel::updateRule( const QModelIndex &idx )
1308 {
1309  emit dataChanged( index( 0, 0, idx ),
1310  index( rowCount( idx ) - 1, columnCount( idx ) - 1, idx ) );
1311 
1312  for ( int i = 0; i < rowCount( idx ); i++ )
1313  {
1314  updateRule( index( i, 0, idx ) );
1315  }
1316 }
1317 
1318 
1319 void QgsRuleBasedRendererModel::removeRule( const QModelIndex &index )
1320 {
1321  if ( !index.isValid() )
1322  return;
1323 
1324  beginRemoveRows( index.parent(), index.row(), index.row() );
1325 
1327  rule->parent()->removeChild( rule );
1328 
1329  endRemoveRows();
1330 }
1331 
1332 void QgsRuleBasedRendererModel::setSymbol( const QModelIndex &index, QgsSymbol *symbol )
1333 {
1335  rule->setSymbol( symbol );
1336  emit dataChanged( index, index );
1337 }
1338 
1339 void QgsRuleBasedRendererModel::willAddRules( const QModelIndex &parent, int count )
1340 {
1341  int row = rowCount( parent ); // only consider appending
1342  beginInsertRows( parent, row, row + count - 1 );
1343 }
1344 
1346 {
1347  endInsertRows();
1348 }
1349 
1350 void QgsRuleBasedRendererModel::setFeatureCounts( const QHash<QgsRuleBasedRenderer::Rule *, QgsRuleBasedRendererCount> &countMap )
1351 {
1352  mFeatureCountMap = countMap;
1353  updateRule( QModelIndex() );
1354 }
1355 
1357 {
1358  mFeatureCountMap.clear();
1359  updateRule( QModelIndex() );
1360 }
QgsRuleBasedRenderer::Rule::create
static QgsRuleBasedRenderer::Rule * create(QDomElement &ruleElem, QgsSymbolMap &symbolMap)
Create a rule from an XML definition.
Definition: qgsrulebasedrenderer.cpp:729
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:81
QgsRendererRulePropsWidget::QgsRendererRulePropsWidget
QgsRendererRulePropsWidget(QgsRuleBasedRenderer::Rule *rule, QgsVectorLayer *layer, QgsStyle *style, QWidget *parent=nullptr, const QgsSymbolWidgetContext &context=QgsSymbolWidgetContext())
Widget to edit the details of a rule based renderer rule.
Definition: qgsrulebasedrendererwidget.cpp:695
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
qgsrulebasedrendererwidget.h
QgsRuleBasedRendererWidget::refineRuleCategories
void refineRuleCategories()
Definition: qgsrulebasedrendererwidget.cpp:278
QgsRuleBasedRenderer::Rule::save
QDomElement save(QDomDocument &doc, QgsSymbolMap &symbolMap) const
Definition: qgsrulebasedrenderer.cpp:317
QgsSymbolWidgetContext::mapCanvas
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Definition: qgssymbolwidgetcontext.cpp:54
QgsSymbolLayerUtils::loadSymbols
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
Definition: qgssymbollayerutils.cpp:2946
QgsRuleBasedRenderer
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
Definition: qgsrulebasedrenderer.h:38
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:596
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsSymbol::defaultSymbol
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:320
QgsExpression::evalErrorString
QString evalErrorString() const
Returns evaluation error.
Definition: qgsexpression.cpp:379
qgscategorizedsymbolrenderer.h
QgsRuleBasedRendererWidget::create
static QgsRendererWidget * create(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Definition: qgsrulebasedrendererwidget.cpp:48
qgsmapcanvas.h
QgsRendererWidget::mCopyAction
QAction * mCopyAction
Definition: qgsrendererwidget.h:102
QgsPanelWidget::setDockMode
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
Definition: qgspanelwidget.cpp:44
QgsRuleBasedRendererModel::willAddRules
void willAddRules(const QModelIndex &parent, int count)
Definition: qgsrulebasedrendererwidget.cpp:1339
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgssinglesymbolrenderer.h
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:49
QgsRuleBasedRendererWidget::paste
void paste() override
Definition: qgsrulebasedrendererwidget.cpp:491
QgsRuleBasedRendererModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Definition: qgsrulebasedrendererwidget.cpp:1092
qgsexpression.h
QgsRuleBasedRendererModel::finishedAddingRules
void finishedAddingRules()
Definition: qgsrulebasedrendererwidget.cpp:1345
QgsRendererWidget::mLayer
QgsVectorLayer * mLayer
Definition: qgsrendererwidget.h:99
QgsRuleBasedRendererWidget::restoreSectionWidths
void restoreSectionWidths()
Definition: qgsrulebasedrendererwidget.cpp:466
QgsSymbolLayerUtils::symbolFromMimeData
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Definition: qgssymbollayerutils.cpp:3062
qgsreadwritecontext.h
QgsRendererWidget::mPasteSymbolAction
QAction * mPasteSymbolAction
Paste symbol action.
Definition: qgsrendererwidget.h:115
QgsSymbolMap
QMap< QString, QgsSymbol * > QgsSymbolMap
Definition: qgsrenderer.h:46
QgsRuleBasedRendererModel::removeRows
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: qgsrulebasedrendererwidget.cpp:1258
QgsRuleBasedRendererWidget::removeRule
void removeRule()
Definition: qgsrulebasedrendererwidget.cpp:223
QgsRuleBasedRendererModel::columnCount
int columnCount(const QModelIndex &=QModelIndex()) const override
Definition: qgsrulebasedrendererwidget.cpp:1059
QgsCategorizedSymbolRenderer::categories
const QgsCategoryList & categories() const
Returns a list of all categories recognized by the renderer.
Definition: qgscategorizedsymbolrenderer.h:191
qgssymbollayerutils.h
qgsfeatureiterator.h
QgsSymbolWidgetContext
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Definition: qgssymbolwidgetcontext.h:36
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:79
QgsScaleComboBox::toString
static QString toString(double scale)
Helper function to convert a scale double to scale string.
Definition: qgsscalecombobox.cpp:203
QgsSymbolLevelsWidget::apply
void apply()
Apply button.
Definition: qgssymbollevelsdialog.cpp:130
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsRuleBasedRenderer::Rule::dump
QString dump(int indent=0) const
Dump for debug purpose.
Definition: qgsrulebasedrenderer.cpp:188
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsRuleBasedRendererModel::setSymbol
void setSymbol(const QModelIndex &index, QgsSymbol *symbol)
Sets the symbol for the rule at the specified index.
Definition: qgsrulebasedrendererwidget.cpp:1332
QgsSymbolSelectorWidget
Symbol selector widget that can be used to select and build a symbol.
Definition: qgssymbolselectordialog.h:88
QgsRuleBasedRendererModel::parent
QModelIndex parent(const QModelIndex &index) const override
Definition: qgsrulebasedrendererwidget.cpp:1075
QgsRendererRulePropsWidget::testFilter
void testFilter()
Test the filter that is set in the widget.
Definition: qgsrulebasedrendererwidget.cpp:819
QgsRuleBasedRenderer::RuleList
QList< QgsRuleBasedRenderer::Rule * > RuleList
Definition: qgsrulebasedrenderer.h:124
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:64
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsRendererRulePropsDialog::rule
QgsRuleBasedRenderer::Rule * rule()
Definition: qgsrulebasedrendererwidget.h:279
QgsApplication::iconPath
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Definition: qgsapplication.cpp:615
QgsRuleBasedRenderer::Rule::setMaximumScale
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
Definition: qgsrulebasedrenderer.h:281
QgsRuleBasedRendererWidget::refreshSymbolView
void refreshSymbolView() override
Definition: qgsrulebasedrendererwidget.cpp:395
QgsSymbolSelectorWidget::setContext
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Definition: qgssymbolselectordialog.cpp:355
QgsRendererRulePropsWidget::buildExpression
void buildExpression()
Open the expression builder widget to check if the.
Definition: qgsrulebasedrendererwidget.cpp:802
QgsRuleBasedRendererWidget::editRule
void editRule()
Definition: qgsrulebasedrendererwidget.cpp:191
qgssymbollevelsdialog.h
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:83
QgsRuleBasedRendererModel::QgsRuleBasedRendererModel
QgsRuleBasedRendererModel(QgsRuleBasedRenderer *renderer, QObject *parent)
Constructor for QgsRuleBasedRendererModel, for the specified renderer.
Definition: qgsrulebasedrendererwidget.cpp:896
QgsRuleBasedRendererWidget::refineRuleScalesGui
void refineRuleScalesGui(const QModelIndexList &index)
Definition: qgsrulebasedrendererwidget.cpp:311
QgsRuleBasedRendererModel::setFeatureCounts
void setFeatureCounts(const QHash< QgsRuleBasedRenderer::Rule *, QgsRuleBasedRendererCount > &countMap)
Definition: qgsrulebasedrendererwidget.cpp:1350
QgsSymbolLevelsWidget
A widget which allows the user to modify the rendering order of symbol layers.
Definition: qgssymbollevelsdialog.h:38
QgsRendererRulePropsWidget::mSymbol
QgsSymbol * mSymbol
Definition: qgsrulebasedrendererwidget.h:254
QgsRuleBasedRendererModel::ruleForIndex
QgsRuleBasedRenderer::Rule * ruleForIndex(const QModelIndex &index) const
Definition: qgsrulebasedrendererwidget.cpp:1251
QgsFeatureRequest::setExpressionContext
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
Definition: qgsfeaturerequest.cpp:144
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:250
QgsRuleBasedRenderer::Rule::minimumScale
double minimumScale() const
Returns the minimum map scale (i.e.
Definition: qgsrulebasedrenderer.h:221
QgsRuleBasedRenderer::Rule::maximumScale
double maximumScale() const
Returns the maximum map scale (i.e.
Definition: qgsrulebasedrenderer.h:211
QgsPanelWidget::showPanel
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
QgsFeatureRequest::setFilterExpression
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Definition: qgsfeaturerequest.cpp:124
qgsapplication.h
QgsGui::enableAutoGeometryRestore
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:139
QgsRuleBasedRendererWidget::refineRuleRangesGui
void refineRuleRangesGui()
Opens the dialog for refining a rule using ranges.
Definition: qgsrulebasedrendererwidget.cpp:302
QgsRuleBasedRenderer::Rule::dependsOnScale
bool dependsOnScale() const
Definition: qgsrulebasedrenderer.h:201
QgsRuleBasedRendererWidget::renderer
QgsFeatureRenderer * renderer() override
Returns pointer to the renderer (no transfer of ownership)
Definition: qgsrulebasedrendererwidget.cpp:141
QgsSymbolLayerUtils::symbolPreviewIcon
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
Definition: qgssymbollayerutils.cpp:762
QgsRuleBasedRendererModel::mR
QgsRuleBasedRenderer * mR
Definition: qgsrulebasedrendererwidget.h:104
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsRuleBasedRendererWidget::keyPressEvent
void keyPressEvent(QKeyEvent *event) override
Definition: qgsrulebasedrendererwidget.cpp:407
QgsRuleBasedRenderer::Rule::setSymbol
void setSymbol(QgsSymbol *sym)
Sets a new symbol (or nullptr). Deletes old symbol.
Definition: qgsrulebasedrenderer.cpp:254
QgsRuleBasedRendererWidget::selectedRules
QgsRuleBasedRenderer::RuleList selectedRules()
Definition: qgsrulebasedrendererwidget.cpp:377
QgsRuleBasedRendererWidget::mContextMenu
QMenu * mContextMenu
Definition: qgsrulebasedrendererwidget.h:174
QgsRendererRulePropsWidget::rule
QgsRuleBasedRenderer::Rule * rule()
Returns the current set rule.
Definition: qgsrulebasedrendererwidget.h:224
QgsRuleBasedRendererWidget::refineRuleScales
void refineRuleScales()
Definition: qgsrulebasedrendererwidget.cpp:288
QgsRuleBasedRendererModel::supportedDropActions
Qt::DropActions supportedDropActions() const override
Definition: qgsrulebasedrendererwidget.cpp:1131
qgsgraduatedsymbolrendererwidget.h
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:30
QgsRuleBasedRendererModel::dropMimeData
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
Definition: qgsrulebasedrendererwidget.cpp:1198
QgsRuleBasedRenderer::Rule::insertChild
void insertChild(int i, QgsRuleBasedRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
Definition: qgsrulebasedrenderer.cpp:88
QgsRuleBasedRendererWidget::setRenderingOrder
void setRenderingOrder()
Definition: qgsrulebasedrendererwidget.cpp:433
QgsRuleBasedRendererModel::mFeatureCountMap
QHash< QgsRuleBasedRenderer::Rule *, QgsRuleBasedRendererCount > mFeatureCountMap
Definition: qgsrulebasedrendererwidget.h:105
QgsRuleBasedRenderer::rootRule
QgsRuleBasedRenderer::Rule * rootRule()
Definition: qgsrulebasedrenderer.h:532
QgsExpression::parserErrorString
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.cpp:207
QgsRuleBasedRenderer::Rule::description
QString description() const
A human readable description for this rule.
Definition: qgsrulebasedrenderer.h:240
QgsRuleBasedRendererModel::mimeTypes
QStringList mimeTypes() const override
Definition: qgsrulebasedrendererwidget.cpp:1136
QgsRuleBasedRendererModel::data
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Definition: qgsrulebasedrendererwidget.cpp:917
QgsPanelWidget::panelAccepted
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
QgsExpressionBuilderDialog
A generic dialog for building expression strings.
Definition: qgsexpressionbuilderdialog.h:31
QgsSymbolLevelsWidget::setForceOrderingEnabled
void setForceOrderingEnabled(bool enabled)
Sets whether the level ordering is always forced on and hide the checkbox (used by rule-based rendere...
Definition: qgssymbollevelsdialog.cpp:173
QgsRuleBasedRendererModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgsrulebasedrendererwidget.cpp:1049
QgsGraduatedSymbolRenderer
Definition: qgsgraduatedsymbolrenderer.h:36
QgsRendererWidget::mPasteAction
QAction * mPasteAction
Definition: qgsrendererwidget.h:103
QgsRendererWidget::setDockMode
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
Definition: qgsrendererwidget.cpp:352
QgsRuleBasedRenderer::Rule::symbol
QgsSymbol * symbol()
Definition: qgsrulebasedrenderer.h:199
QgsRuleBasedRenderer::refineRuleScales
static void refineRuleScales(QgsRuleBasedRenderer::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...
Definition: qgsrulebasedrenderer.cpp:1249
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsRuleBasedRenderer::Rule::label
QString label() const
Definition: qgsrulebasedrenderer.h:200
QgsSymbolLevelsDialog::setForceOrderingEnabled
void setForceOrderingEnabled(bool enabled)
Definition: qgssymbollevelsdialog.cpp:201
QgsRuleBasedRendererWidget::setDockMode
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
Definition: qgsrulebasedrendererwidget.cpp:146
qgsvscrollarea.h
QgsRuleBasedRendererModel::insertRule
void insertRule(const QModelIndex &parent, int before, QgsRuleBasedRenderer::Rule *newrule)
Definition: qgsrulebasedrendererwidget.cpp:1289
QgsRuleBasedRenderer::refineRuleRanges
static void refineRuleRanges(QgsRuleBasedRenderer::Rule *initialRule, QgsGraduatedSymbolRenderer *r)
take a rule and create a list of new rules based on the ranges from graduated symbol renderer
Definition: qgsrulebasedrenderer.cpp:1217
QgsRuleBasedRenderer::Rule::removeChild
void removeChild(QgsRuleBasedRenderer::Rule *rule)
delete child rule
Definition: qgsrulebasedrenderer.cpp:95
QgsRuleBasedRendererModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: qgsrulebasedrendererwidget.cpp:902
QgsRendererRulePropsDialog::testFilter
void testFilter()
Definition: qgsrulebasedrendererwidget.cpp:780
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsRuleBasedRendererModel
Tree model for the rules:
Definition: qgsrulebasedrendererwidget.h:48
QgsRuleBasedRendererWidget::mDeleteAction
QAction * mDeleteAction
Definition: qgsrulebasedrendererwidget.h:171
QgsScaleRangeWidget::rangeChanged
void rangeChanged(double min, double max)
Emitted when the scale range set in the widget is changed.
QgsVScrollArea
QgsVScrollArea is a QScrollArea subclass which only displays a vertical scrollbar and fits the width ...
Definition: qgsvscrollarea.h:32
QgsFeatureRequest::setNoAttributes
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
Definition: qgsfeaturerequest.cpp:192
QgsExpression::prepare
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
Definition: qgsexpression.cpp:323
qgsrulebasedrenderer.h
QgsRendererRulePropsWidget::mLayer
QgsVectorLayer * mLayer
Definition: qgsrulebasedrendererwidget.h:251
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
QgsRuleBasedRendererWidget::mRenderer
QgsRuleBasedRenderer * mRenderer
Definition: qgsrulebasedrendererwidget.h:167
QgsRendererRulePropsWidget::setDockMode
void setDockMode(bool dockMode) override
Set the widget in dock mode.
Definition: qgsrulebasedrendererwidget.cpp:879
QgsRuleBasedRendererModel::clearFeatureCounts
void clearFeatureCounts()
Definition: qgsrulebasedrendererwidget.cpp:1356
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext.
Definition: qgsexpressioncontext.h:112
qgssymbolselectordialog.h
QgsRendererWidget
Base class for renderer settings widgets.
Definition: qgsrendererwidget.h:45
QgsRenderContext::setRendererScale
void setRendererScale(double scale)
Sets the renderer map scale.
Definition: qgsrendercontext.h:483
QgsExpressionContext::appendScope
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Definition: qgsexpressioncontext.cpp:490
qgsvectorlayer.h
QgsSymbolLevelsDialog
A dialog which allows the user to modify the rendering order of symbol layers.
Definition: qgssymbollevelsdialog.h:91
QgsSymbol::clone
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
QgsRuleBasedRendererWidget::QgsRuleBasedRendererWidget
QgsRuleBasedRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Definition: qgsrulebasedrendererwidget.cpp:53
QgsGraduatedSymbolRenderer::ranges
const QgsRangeList & ranges() const
Definition: qgsgraduatedsymbolrenderer.h:59
QgsRuleBasedRendererWidget::mModel
QgsRuleBasedRendererModel * mModel
Definition: qgsrulebasedrendererwidget.h:168
QgsRuleBasedRendererWidget::addRule
void addRule()
Definition: qgsrulebasedrendererwidget.cpp:157
QgsExpressionBuilderDialog::expressionText
QString expressionText()
Definition: qgsexpressionbuilderdialog.cpp:50
QgsGui::instance
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:63
QgsFeatureRenderer
Definition: qgsrenderer.h:103
QgsRuleBasedRendererWidget::currentRuleChanged
void currentRuleChanged(const QModelIndex &current=QModelIndex(), const QModelIndex &previous=QModelIndex())
Definition: qgsrulebasedrendererwidget.cpp:239
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsRuleBasedRendererWidget::refineRuleCategoriesGui
void refineRuleCategoriesGui()
Opens the dialog for refining a rule using categories.
Definition: qgsrulebasedrendererwidget.cpp:293
QgsStyle
Definition: qgsstyle.h:160
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsRuleBasedRendererWidget::currentRule
QgsRuleBasedRenderer::Rule * currentRule()
Definition: qgsrulebasedrendererwidget.cpp:182
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsSymbolLayerUtils::saveSymbols
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Definition: qgssymbollayerutils.cpp:3024
QgsRuleBasedRenderer::Rule::clone
QgsRuleBasedRenderer::Rule * clone() const
clone this rule, return new instance
Definition: qgsrulebasedrenderer.cpp:305
QgsRuleBasedRenderer::Rule::isElse
bool isElse() const
Check if this rule is an ELSE rule.
Definition: qgsrulebasedrenderer.h:434
QgsRuleBasedRenderer::Rule::setMinimumScale
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
Definition: qgsrulebasedrenderer.h:272
QgsRuleBasedRenderer::Rule::setLabel
void setLabel(const QString &label)
Definition: qgsrulebasedrenderer.h:263
qgssettings.h
QgsRuleBasedRenderer::refineRuleCategories
static void refineRuleCategories(QgsRuleBasedRenderer::Rule *initialRule, QgsCategorizedSymbolRenderer *r)
take a rule and create a list of new rules based on the categories from categorized symbol renderer
Definition: qgsrulebasedrenderer.cpp:1186
QgsRuleBasedRendererModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const override
Definition: qgsrulebasedrendererwidget.cpp:1143
QgsRuleBasedRendererWidget::pasteSymbolToSelection
void pasteSymbolToSelection() override
Definition: qgsrulebasedrendererwidget.cpp:503
QgsRuleBasedRenderer::Rule::parent
QgsRuleBasedRenderer::Rule * parent()
The parent rule.
Definition: qgsrulebasedrenderer.h:396
QgsRuleBasedRendererWidget::selectedRulesChanged
void selectedRulesChanged()
Definition: qgsrulebasedrendererwidget.cpp:686
QgsRuleBasedRendererModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: qgsrulebasedrendererwidget.cpp:1064
QgsRuleBasedRendererModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: qgsrulebasedrendererwidget.cpp:1026
QgsRendererRulePropsDialog::accept
void accept() override
Definition: qgsrulebasedrendererwidget.cpp:790
QgsRenderContext::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Definition: qgsrendercontext.h:588
QgsRuleBasedRendererWidget::copy
void copy() override
Definition: qgsrulebasedrendererwidget.cpp:479
QgsRendererRulePropsWidget::mSymbolSelector
QgsSymbolSelectorWidget * mSymbolSelector
Definition: qgsrulebasedrendererwidget.h:253
qgscategorizedsymbolrendererwidget.h
QgsCategorizedSymbolRenderer
Definition: qgscategorizedsymbolrenderer.h:152
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsRuleBasedRendererWidget::countFeatures
void countFeatures()
Definition: qgsrulebasedrendererwidget.cpp:593
QgsExpression::hasParserError
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.cpp:202
QgsRuleBasedRendererWidget::refineRule
void refineRule(int type)
Definition: qgsrulebasedrendererwidget.cpp:255
qgslogger.h
qgsguiutils.h
QgsRendererRulePropsWidget::mRule
QgsRuleBasedRenderer::Rule * mRule
Definition: qgsrulebasedrendererwidget.h:250
QgsRendererRulePropsDialog::buildExpression
void buildExpression()
Definition: qgsrulebasedrendererwidget.cpp:785
QgsRuleBasedRenderer::Rule::setActive
void setActive(bool state)
Sets if this rule is active.
Definition: qgsrulebasedrenderer.h:301
QgsRuleBasedRendererModel::removeRule
void removeRule(const QModelIndex &index)
Definition: qgsrulebasedrendererwidget.cpp:1319
QgsRuleBasedRenderer::Rule::setFilterExpression
void setFilterExpression(const QString &filterExp)
Set the expression used to check if a given feature shall be rendered with this rule.
Definition: qgsrulebasedrenderer.cpp:259
QgsGuiUtils::scaleIconSize
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsguiutils.cpp:245
qgspanelwidget.h
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsRuleBasedRendererWidget::~QgsRuleBasedRendererWidget
~QgsRuleBasedRendererWidget() override
Definition: qgsrulebasedrendererwidget.cpp:135
qgsgraduatedsymbolrenderer.h
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:659
QgsRuleBasedRendererModel::updateRule
void updateRule(const QModelIndex &parent, int row)
Definition: qgsrulebasedrendererwidget.cpp:1301
QgsRuleBasedRenderer::Rule::children
const QgsRuleBasedRenderer::RuleList & children()
Returns all children rules of this rule.
Definition: qgsrulebasedrenderer.h:382
_labeling2rendererRules
void _labeling2rendererRules(QDomElement &ruleElem)
Definition: qgsrulebasedrendererwidget.cpp:1182
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:179
QgsRuleBasedRendererWidget::selectedSymbols
QList< QgsSymbol * > selectedSymbols() override
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
Definition: qgsrulebasedrendererwidget.cpp:352
QgsRuleBasedRendererWidget::mRefineMenu
QMenu * mRefineMenu
Definition: qgsrulebasedrendererwidget.h:170
qgssymbol.h
QgsRuleBasedRendererWidget::refineRuleRanges
void refineRuleRanges()
Definition: qgsrulebasedrendererwidget.cpp:283
QgsRendererRulePropsWidget::apply
void apply()
Apply any changes from the widget to the set rule.
Definition: qgsrulebasedrendererwidget.cpp:867
QgsRuleBasedRenderer::Rule::removeChildAt
void removeChildAt(int i)
delete child rule
Definition: qgsrulebasedrenderer.cpp:102
QgsRuleBasedRenderer::convertFromRenderer
static QgsRuleBasedRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsRuleBasedRenderer from an existing renderer.
Definition: qgsrulebasedrenderer.cpp:1301
QgsRuleBasedRenderer::Rule
This class keeps data about a rules for rule-based renderer.
Definition: qgsrulebasedrenderer.h:137
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog
QgsRendererRulePropsDialog(QgsRuleBasedRenderer::Rule *rule, QgsVectorLayer *layer, QgsStyle *style, QWidget *parent=nullptr, const QgsSymbolWidgetContext &context=QgsSymbolWidgetContext())
Constructor for QgsRendererRulePropsDialog.
Definition: qgsrulebasedrendererwidget.cpp:754
QgsRuleBasedRendererWidget::saveSectionWidth
void saveSectionWidth(int section, int oldSize, int newSize)
Definition: qgsrulebasedrendererwidget.cpp:455
QgsRendererRulePropsDialog
Definition: qgsrulebasedrendererwidget.h:264
QgsRuleBasedRenderer::Rule::active
bool active() const
Returns if this rule is active.
Definition: qgsrulebasedrenderer.h:247
QgsRendererRulePropsWidget::mContext
QgsSymbolWidgetContext mContext
Definition: qgsrulebasedrendererwidget.h:256
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521
qgsexpressionbuilderdialog.h
QgsRuleBasedRenderer::Rule::filterExpression
QString filterExpression() const
A filter that will check if this rule applies.
Definition: qgsrulebasedrenderer.h:233