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