25#include <QAbstractItemView> 
   29  : QStandardItemModel( 0, 1, parent )
 
   35  return QStandardItemModel::flags( index ) | Qt::ItemIsUserCheckable;
 
   40  QVariant value = QStandardItemModel::data( index, role );
 
   42  if ( index.isValid() && role == Qt::CheckStateRole && !value.isValid() )
 
   44    value = Qt::Unchecked;
 
   52  const bool ok = QStandardItemModel::setData( index, value, role );
 
   54  if ( ok && role == Qt::CheckStateRole )
 
   59  emit dataChanged( index, index );
 
   65  : QStyledItemDelegate( parent )
 
   71  QStyleOptionViewItem &nonConstOpt = 
const_cast<QStyleOptionViewItem &
>( option );
 
   72  nonConstOpt.showDecorationSelected = 
false;
 
   73  QStyledItemDelegate::paint( painter, nonConstOpt, index );
 
   80  , mSeparator( QStringLiteral( 
", " ) )
 
   85  QLineEdit *lineEdit = 
new QLineEdit( 
this );
 
   86  lineEdit->setReadOnly( 
true );
 
   87  QPalette 
pal = qApp->palette();
 
   88  pal.setBrush( QPalette::Base, 
pal.button() );
 
   89  lineEdit->setPalette( 
pal );
 
   90  setLineEdit( lineEdit );
 
   91  lineEdit->installEventFilter( 
this );
 
   92  lineEdit->setContextMenuPolicy( Qt::CustomContextMenu );
 
   95  mContextMenu = 
new QMenu( 
this );
 
   96  mSelectAllAction = mContextMenu->addAction( tr( 
"Select All" ) );
 
   97  mDeselectAllAction = mContextMenu->addAction( tr( 
"Deselect All" ) );
 
  101  view()->viewport()->installEventFilter( 
this );
 
  102  view()->setContextMenuPolicy( Qt::CustomContextMenu );
 
  105  connect( 
model(), &QStandardItemModel::rowsInserted, 
this, [ = ]( 
const QModelIndex &, 
int, 
int ) { updateDisplayText(); } );
 
  106  connect( 
model(), &QStandardItemModel::rowsRemoved, 
this, [ = ]( 
const QModelIndex &, 
int, 
int ) { updateDisplayText(); } );
 
  107  connect( 
model(), &QStandardItemModel::dataChanged, 
this, [ = ]( 
const QModelIndex &, 
const QModelIndex &, 
const QVector< int > & ) { updateDisplayText(); } );
 
  131  if ( mDefaultText != text )
 
  140  QComboBox::addItem( text, userData );
 
  148  if ( 
auto *lModel = 
model() )
 
  150    const QModelIndex index = lModel->index( 0, modelColumn(), rootModelIndex() );
 
  151    const QModelIndexList indexes = lModel->match( index, Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly );
 
  152    const auto constIndexes = indexes;
 
  153    for ( 
const QModelIndex &index : constIndexes )
 
  155      items += index.data().toString();
 
  166  if ( 
auto *lModel = 
model() )
 
  168    const QModelIndex index = lModel->index( 0, modelColumn(), rootModelIndex() );
 
  169    const QModelIndexList indexes = lModel->match( index, Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchExactly );
 
  170    const auto constIndexes = indexes;
 
  171    for ( 
const QModelIndex &index : constIndexes )
 
  173      data += index.data( Qt::UserRole ).toString();
 
  182  return static_cast<Qt::CheckState
>( itemData( index, Qt::CheckStateRole ).toInt() );
 
  187  setItemData( index, state, Qt::CheckStateRole );
 
  192  const QVariant value = itemData( index, Qt::CheckStateRole );
 
  193  if ( value.isValid() )
 
  195    const Qt::CheckState state = 
static_cast<Qt::CheckState
>( value.toInt() );
 
  196    setItemData( index, ( state == Qt::Unchecked ? Qt::Checked : Qt::Unchecked ), Qt::CheckStateRole );
 
  198  updateCheckedItems();
 
  205    QComboBox::hidePopup();
 
  214  mContextMenu->exec( QCursor::pos() );
 
  219  blockSignals( 
true );
 
  220  for ( 
int i = 0;  i < count(); i++ )
 
  222    setItemData( i, Qt::Checked, Qt::CheckStateRole );
 
  224  blockSignals( 
false );
 
  225  updateCheckedItems();
 
  230  blockSignals( 
true );
 
  231  for ( 
int i = 0;  i < count(); i++ )
 
  233    setItemData( i, Qt::Unchecked, Qt::CheckStateRole );
 
  235  blockSignals( 
false );
 
  236  updateCheckedItems();
 
  241  if ( 
object == lineEdit() )
 
  243    if ( event->type() == QEvent::MouseButtonPress && 
static_cast<QMouseEvent *
>( event )->button() == Qt::LeftButton && 
object == lineEdit() )
 
  249  else if ( ( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease )
 
  250            && 
object == view()->viewport() )
 
  254    if ( event->type() == QEvent::MouseButtonRelease && 
static_cast<QMouseEvent *
>( event )->button() == Qt::RightButton )
 
  259    if ( event->type() == QEvent::MouseButtonRelease )
 
  261      const QModelIndex index = view()->indexAt( 
static_cast<QMouseEvent *
>( event )->pos() );
 
  262      if ( index.isValid() )
 
  265        QStandardItem *item = myModel->itemFromIndex( index );
 
  266        item->setCheckState( item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked );
 
  267        updateCheckedItems();
 
  273  return QComboBox::eventFilter( 
object, event );
 
  278  const auto constItems = items;
 
  279  for ( 
const QString &text : constItems )
 
  281    const int index = findText( text );
 
  284  updateCheckedItems();
 
  289  QComboBox::resizeEvent( event );
 
  293void QgsCheckableComboBox::updateCheckedItems()
 
  300void QgsCheckableComboBox::updateDisplayText()
 
  308  if ( items.isEmpty() )
 
  314    text = items.join( mSeparator );
 
  317  const QRect rect = lineEdit()->rect();
 
  318  const QFontMetrics fontMetrics( font() );
 
  319  text = fontMetrics.elidedText( text, Qt::ElideRight, rect.width() );
 
QStyledItemDelegate subclass for QgsCheckableComboBox.
 
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Renders the delegate using the given painter and style option for the item specified by index.
 
QgsCheckBoxDelegate(QObject *parent=nullptr)
Constructor for QgsCheckBoxDelegate.
 
void setSeparator(const QString &separator)
Set separator used to separate items in the display text.
 
void setItemCheckState(int index, Qt::CheckState state)
Sets the item check state to state.
 
void deselectAllOptions()
Removes selection from all items.
 
void selectAllOptions()
Selects all items.
 
void checkedItemsChanged(const QStringList &items)
Emitted whenever the checked items list changed.
 
void setCheckedItems(const QStringList &items)
Set items which should be checked/selected.
 
void toggleItemCheckState(int index)
Toggles the item check state.
 
bool eventFilter(QObject *object, QEvent *event) override
Filters events to enable context menu.
 
QgsCheckableComboBox(QWidget *parent=nullptr)
Constructor for QgsCheckableComboBox.
 
QVariantList checkedItemsData() const
Returns userData (stored in the Qt::UserRole) associated with currently checked items.
 
QgsCheckableItemModel * mModel
 
QgsCheckableItemModel * model() const
Returns the custom item model which handles checking the items.
 
Qt::CheckState itemCheckState(int index) const
Returns the checked state of the item identified by index.
 
void addItemWithCheckState(const QString &text, Qt::CheckState state, const QVariant &userData=QVariant())
Adds an item to the combobox with the given text, check state (stored in the Qt::CheckStateRole) and ...
 
void showContextMenu(QPoint pos)
Display context menu which allows selecting/deselecting all items at once.
 
void hidePopup() override
Hides the list of items in the combobox if it is currently visible and resets the internal state.
 
void resizeEvent(QResizeEvent *event) override
Handler for widget resizing.
 
void setDefaultText(const QString &text)
Set default text which will be displayed in the widget when no items selected.
 
QStandardItemModel subclass which makes all items checkable by default.
 
void itemCheckStateChanged(const QModelIndex &index)
Emitted whenever the item's checkstate has changed.
 
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Sets the role data for the item at index to value.
 
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns a combination of the item flags: items are enabled (ItemIsEnabled), selectable (ItemIsSelecta...
 
QgsCheckableItemModel(QObject *parent=nullptr)
Constructor for QgsCheckableItemModel.
 
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.