QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
qgsprocessingmultipleselectiondialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingmultipleselectiondialog.cpp
3  ------------------------------------
4  Date : February 2019
5  Copyright : (C) 2019 Nyall Dawson
6  Email : nyall dot dawson 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 #include "qgsgui.h"
18 #include <QStandardItemModel>
19 #include <QStandardItem>
20 #include <QPushButton>
21 #include <QLineEdit>
22 #include <QToolButton>
23 
25 
26 QgsProcessingMultipleSelectionDialog::QgsProcessingMultipleSelectionDialog( const QVariantList &availableOptions,
27  const QVariantList &selectedOptions,
28  QWidget *parent, Qt::WindowFlags flags )
29  : QDialog( parent, flags )
30  , mValueFormatter( []( const QVariant & v )->QString { return v.toString(); } )
31 {
32  setupUi( this );
33 
35 
36  mSelectionList->setSelectionBehavior( QAbstractItemView::SelectRows );
37  mSelectionList->setSelectionMode( QAbstractItemView::ExtendedSelection );
38  mSelectionList->setDragDropMode( QAbstractItemView::InternalMove );
39 
40  mButtonSelectAll = new QPushButton( tr( "Select All" ) );
41  mButtonBox->addButton( mButtonSelectAll, QDialogButtonBox::ActionRole );
42 
43  mButtonClearSelection = new QPushButton( tr( "Clear Selection" ) );
44  mButtonBox->addButton( mButtonClearSelection, QDialogButtonBox::ActionRole );
45 
46  mButtonToggleSelection = new QPushButton( tr( "Toggle Selection" ) );
47  mButtonBox->addButton( mButtonToggleSelection, QDialogButtonBox::ActionRole );
48 
49  connect( mButtonSelectAll, &QPushButton::clicked, this, [ = ] { selectAll( true ); } );
50  connect( mButtonClearSelection, &QPushButton::clicked, this, [ = ] { selectAll( false ); } );
51  connect( mButtonToggleSelection, &QPushButton::clicked, this, &QgsProcessingMultipleSelectionDialog::toggleSelection );
52 
53  populateList( availableOptions, selectedOptions );
54 }
55 
56 void QgsProcessingMultipleSelectionDialog::setValueFormatter( const std::function<QString( const QVariant & )> &formatter )
57 {
58  mValueFormatter = formatter;
59  // update item text using new formatter
60  for ( int i = 0; i < mModel->rowCount(); ++i )
61  {
62  mModel->item( i )->setText( mValueFormatter( mModel->item( i )->data( Qt::UserRole ) ) );
63  }
64 }
65 
66 QVariantList QgsProcessingMultipleSelectionDialog::selectedOptions() const
67 {
68  QVariantList options;
69  options.reserve( mModel->rowCount() );
70  for ( int i = 0; i < mModel->rowCount(); ++i )
71  {
72  if ( mModel->item( i )->checkState() == Qt::Checked )
73  options << mModel->item( i )->data( Qt::UserRole );
74  }
75  return options;
76 }
77 
78 void QgsProcessingMultipleSelectionDialog::selectAll( const bool checked )
79 {
80  const QList<QStandardItem *> items = currentItems();
81  for ( QStandardItem *item : items )
82  {
83  item->setCheckState( checked ? Qt::Checked : Qt::Unchecked );
84  }
85 }
86 
87 void QgsProcessingMultipleSelectionDialog::toggleSelection()
88 {
89  const QList<QStandardItem *> items = currentItems();
90  for ( QStandardItem *item : items )
91  {
92  item->setCheckState( item->checkState() == Qt::Unchecked ? Qt::Checked : Qt::Unchecked );
93  }
94 }
95 
96 QList<QStandardItem *> QgsProcessingMultipleSelectionDialog::currentItems()
97 {
98  QList<QStandardItem *> items;
99  const QModelIndexList selection = mSelectionList->selectionModel()->selectedIndexes();
100  if ( selection.size() > 1 )
101  {
102  items.reserve( selection.size() );
103  for ( const QModelIndex &index : selection )
104  {
105  items << mModel->itemFromIndex( index );
106  }
107  }
108  else
109  {
110  items.reserve( mModel->rowCount() );
111  for ( int i = 0; i < mModel->rowCount(); ++i )
112  {
113  items << mModel->item( i );
114  }
115  }
116  return items;
117 }
118 
119 void QgsProcessingMultipleSelectionDialog::populateList( const QVariantList &availableOptions, const QVariantList &selectedOptions )
120 {
121  mModel = new QStandardItemModel( this );
122 
123  QVariantList remainingOptions = availableOptions;
124 
125  // we add selected options first, keeping the existing order of options
126  for ( const QVariant &option : selectedOptions )
127  {
128 // if isinstance(t, QgsProcessingModelChildParameterSource):
129 // item = QStandardItem(t.staticValue())
130  // else:
131  std::unique_ptr< QStandardItem > item = qgis::make_unique< QStandardItem >( mValueFormatter( option ) );
132  item->setData( option, Qt::UserRole );
133  item->setCheckState( Qt::Checked );
134  item->setCheckable( true );
135  item->setDropEnabled( false );
136  mModel->appendRow( item.release() );
137  remainingOptions.removeAll( option );
138  }
139 
140  for ( const QVariant &option : qgis::as_const( remainingOptions ) )
141  {
142  std::unique_ptr< QStandardItem > item = qgis::make_unique< QStandardItem >( mValueFormatter( option ) );
143  item->setData( option, Qt::UserRole );
144  item->setCheckState( Qt::Unchecked );
145  item->setCheckable( true );
146  item->setDropEnabled( false );
147  mModel->appendRow( item.release() );
148  }
149 
150  mSelectionList->setModel( mModel );
151 }
152 
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:127