Skip to content

Commit 9fbb31a

Browse files
committed
add context menu with select/deselect all options
1 parent c8e4bca commit 9fbb31a

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

python/gui/qgscheckablecombobox.sip

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class QgsCheckableComboBox : QComboBox
7272
*/
7373
virtual void hidePopup();
7474

75+
/** Filters events to enable context menu
76+
*/
77+
virtual bool eventFilter( QObject *object, QEvent *event );
78+
7579
signals:
7680

7781
/** This signal is emitted whenever the checked items list changed.
@@ -90,4 +94,18 @@ class QgsCheckableComboBox : QComboBox
9094
/** Handler for widget resizing
9195
*/
9296
virtual void resizeEvent( QResizeEvent *event );
97+
98+
protected slots:
99+
/** Display context menu which allows to select/deselect
100+
* all items at once.
101+
*/
102+
void showContextMenu( const QPoint &pos );
103+
104+
/** Selects all items.
105+
*/
106+
void selectAllOptions();
107+
108+
/** Removes selection from all items.
109+
*/
110+
void deselectAllOptions();
93111
};

src/gui/qgscheckablecombobox.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
#include "qgscheckablecombobox.h"
1919

20+
#include <QEvent>
21+
#include <QMouseEvent>
2022
#include <QLineEdit>
23+
#include <QPoint>
2124
#include <QAbstractItemView>
2225

2326

@@ -81,6 +84,16 @@ QgsCheckableComboBox::QgsCheckableComboBox( QWidget *parent )
8184
lineEdit->setReadOnly( true );
8285
setLineEdit( lineEdit );
8386

87+
mContextMenu = new QMenu( this );
88+
mSelectAllAction = mContextMenu->addAction( tr( "Select all" ) );
89+
mDeselectAllAction = mContextMenu->addAction( tr( "Deselect all" ) );
90+
connect( mSelectAllAction, &QAction::triggered, this, &QgsCheckableComboBox::selectAllOptions );
91+
connect( mDeselectAllAction, &QAction::triggered, this, &QgsCheckableComboBox::deselectAllOptions );
92+
93+
view()->viewport()->installEventFilter( this );
94+
view()->setContextMenuPolicy( Qt::CustomContextMenu );
95+
connect( view(), &QAbstractItemView::customContextMenuRequested, this, &QgsCheckableComboBox::showContextMenu );
96+
8497
QgsCheckableItemModel *myModel = qobject_cast<QgsCheckableItemModel *>( model() );
8598
connect( myModel, &QgsCheckableItemModel::itemCheckStateChanged, this, &QgsCheckableComboBox::updateCheckedItems );
8699
connect( model(), &QStandardItemModel::rowsInserted, this, [ = ]( const QModelIndex &, int, int ) { updateCheckedItems(); } );
@@ -162,6 +175,49 @@ void QgsCheckableComboBox::hidePopup()
162175
}
163176
}
164177

178+
void QgsCheckableComboBox::showContextMenu( const QPoint &pos )
179+
{
180+
Q_UNUSED( pos );
181+
182+
mContextMenu->exec( QCursor::pos() );
183+
}
184+
185+
void QgsCheckableComboBox::selectAllOptions()
186+
{
187+
blockSignals( true );
188+
for ( int i; i < count(); i++ )
189+
{
190+
setItemData( i, Qt::Checked, Qt::CheckStateRole );
191+
}
192+
blockSignals( false );
193+
updateCheckedItems();
194+
}
195+
196+
void QgsCheckableComboBox::deselectAllOptions()
197+
{
198+
blockSignals( true );
199+
for ( int i; i < count(); i++ )
200+
{
201+
setItemData( i, Qt::Unchecked, Qt::CheckStateRole );
202+
}
203+
blockSignals( false );
204+
updateCheckedItems();
205+
}
206+
207+
bool QgsCheckableComboBox::eventFilter( QObject *object, QEvent *event )
208+
{
209+
Q_UNUSED( object );
210+
211+
if ( event->type() == QEvent::MouseButtonRelease )
212+
{
213+
if ( static_cast<QMouseEvent *>( event )->button() == Qt::RightButton )
214+
{
215+
return true;
216+
}
217+
}
218+
return false;
219+
}
220+
165221
void QgsCheckableComboBox::setCheckedItems( const QStringList &items )
166222
{
167223
Q_FOREACH ( const QString &text, items )
@@ -202,3 +258,4 @@ void QgsCheckableComboBox::updateDisplayText()
202258
text = fontMetrics.elidedText( text, Qt::ElideRight, rect.width() );
203259
setEditText( text );
204260
}
261+

src/gui/qgscheckablecombobox.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
#define QGSCHECKABLECOMBOBOX_H
2020

2121
#include <QComboBox>
22+
#include <QMenu>
2223
#include <QStandardItemModel>
2324
#include <QStyledItemDelegate>
2425

2526
#include "qgis_gui.h"
2627

28+
class QEvent;
29+
2730
/** \class QgsCheckableItemModel
2831
* \ingroup gui
2932
* QStandardItemModel subclass which makes all items checkable
@@ -178,6 +181,10 @@ class GUI_EXPORT QgsCheckableComboBox : public QComboBox
178181
*/
179182
virtual void hidePopup();
180183

184+
/** Filters events to enable context menu
185+
*/
186+
virtual bool eventFilter( QObject *object, QEvent *event ) override;
187+
181188
signals:
182189

183190
/** This signal is emitted whenever the checked items list changed.
@@ -198,12 +205,31 @@ class GUI_EXPORT QgsCheckableComboBox : public QComboBox
198205
*/
199206
virtual void resizeEvent( QResizeEvent *event );
200207

208+
protected slots:
209+
210+
/** Display context menu which allows to select/deselect
211+
* all items at once.
212+
*/
213+
void showContextMenu( const QPoint &pos );
214+
215+
/** Selects all items.
216+
*/
217+
void selectAllOptions();
218+
219+
/** Removes selection from all items.
220+
*/
221+
void deselectAllOptions();
222+
201223
private:
202224
void updateCheckedItems();
203225
void updateDisplayText();
204226

205227
QString mSeparator;
206228
QString mDefaultText;
229+
230+
QMenu *mContextMenu = nullptr;
231+
QAction *mSelectAllAction = nullptr;
232+
QAction *mDeselectAllAction = nullptr;
207233
};
208234

209235
#endif // QGSCHECKABLECOMBOBOX_H

0 commit comments

Comments
 (0)