31 #include <QAbstractItemView>
34 #include <QStandardItemModel>
42 class KCheckComboBox::Private
49 , mSeparator( QLatin1Char(
',' ) )
50 , mSqueezeText( false )
51 , mIgnoreHide( false )
52 , mAlwaysShowDefaultText( false )
55 void makeInsertedItemsCheckable(
const QModelIndex &,
int start,
int end);
56 QString squeeze(
const QString &text );
57 void updateCheckedItems(
const QModelIndex &topLeft = QModelIndex(),
58 const QModelIndex &bottomRight = QModelIndex(),
59 int role = Qt::DisplayRole );
60 void toggleCheckState();
67 bool mAlwaysShowDefaultText;
72 void KCheckComboBox::Private::makeInsertedItemsCheckable(
const QModelIndex &parent,
int start,
int end)
75 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( q->model() );
77 for (
int r = start; r <= end; ++r ) {
78 QStandardItem *item = model->item( r, 0 );
79 item->setCheckable(
true );
82 kWarning() <<
"KCheckComboBox: model is not a QStandardItemModel but a" << q->model() <<
". Cannot proceed.";
86 QString KCheckComboBox::Private::squeeze(
const QString &text )
88 QFontMetrics fm( q->fontMetrics() );
92 const int minLB = qMax(0, -fm.minLeftBearing());
93 const int minRB = qMax(0, -fm.minRightBearing());
94 const int lineEditWidth = q->lineEdit()->width() - 4 - minLB - minRB;
95 const int textWidth = fm.width( text );
96 if ( textWidth > lineEditWidth ) {
97 return fm.elidedText( text, Qt::ElideMiddle, lineEditWidth );
103 void KCheckComboBox::Private::updateCheckedItems(
const QModelIndex &topLeft,
104 const QModelIndex &bottomRight,
108 Q_UNUSED( bottomRight );
110 const QStringList items = q->checkedItems( role );
112 if ( items.isEmpty() || mAlwaysShowDefaultText ) {
115 text = items.join( mSeparator );
119 text = squeeze( text );
121 q->lineEdit()->setText( text );
123 emit q->checkedItemsChanged( items );
126 void KCheckComboBox::Private::toggleCheckState()
128 if (q->view()->isVisible()) {
129 const QModelIndex index = q->view()->currentIndex();
130 QVariant value = index.data( Qt::CheckStateRole );
131 if ( value.isValid() ) {
132 Qt::CheckState state =
static_cast<Qt::CheckState
>( value.toInt() );
133 q->model()->setData( index, state == Qt::Unchecked ? Qt::Checked : Qt::Unchecked,
134 Qt::CheckStateRole );
145 connect(
this, SIGNAL(activated(
int)),
this, SLOT(toggleCheckState()) );
146 connect( model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
147 SLOT(makeInsertedItemsCheckable(QModelIndex,
int,
int)) );
148 connect( model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
149 this, SLOT(updateCheckedItems(QModelIndex,QModelIndex)) );
153 lineEdit()->setAlignment( Qt::AlignLeft );
156 qobject_cast<
KLineEdit *>(lineEdit())->setReadOnly(
true );
157 setInsertPolicy( KComboBox::NoInsert );
159 view()->installEventFilter(
this );
160 view()->viewport()->installEventFilter(
this );
162 lineEdit()->installEventFilter(
this );
164 d->updateCheckedItems();
174 if ( !d->mIgnoreHide ) {
175 KComboBox::hidePopup();
177 d->mIgnoreHide =
false;
182 return static_cast<Qt::CheckState
>( itemData( index, Qt::CheckStateRole ).toInt() );
187 setItemData( index, state, Qt::CheckStateRole );
194 const QModelIndex index = model()->index( 0, modelColumn(), rootModelIndex() );
195 const QModelIndexList indexes = model()->match( index, Qt::CheckStateRole,
196 Qt::Checked, -1, Qt::MatchExactly );
197 foreach (
const QModelIndex &index, indexes ) {
198 items += index.data( role ).toString();
206 for (
int r = 0; r < model()->rowCount( rootModelIndex() ); ++r ) {
207 const QModelIndex indx = model()->index( r, modelColumn(), rootModelIndex() );
209 const QString text = indx.data( role ).toString();
210 const bool found = items.contains( text );
211 model()->setData( indx, found ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole );
213 d->updateCheckedItems( QModelIndex(), QModelIndex(), role );
218 return d->mDefaultText;
223 if ( d->mDefaultText != text ) {
224 d->mDefaultText = text;
225 d->updateCheckedItems();
231 return d->mSqueezeText;
236 if ( d->mSqueezeText != squeeze ) {
237 d->mSqueezeText = squeeze;
238 d->updateCheckedItems();
244 Q_ASSERT( index >= 0 && index <= count() );
246 QStandardItemModel *itemModel = qobject_cast<QStandardItemModel *>( model() );
247 Q_ASSERT( itemModel );
249 QStandardItem *item = itemModel->item( index, 0 );
250 return item->isEnabled();
255 Q_ASSERT( index >= 0 && index <= count() );
257 QStandardItemModel *itemModel = qobject_cast<QStandardItemModel *>( model() );
258 Q_ASSERT( itemModel );
260 QStandardItem *item = itemModel->item( index, 0 );
261 item->setEnabled( enabled );
266 return d->mSeparator;
271 if ( d->mSeparator != separator ) {
273 d->updateCheckedItems();
279 switch ( event->key() ) {
297 #ifndef QT_NO_WHEELEVENT
307 KComboBox::resizeEvent( event );
308 if ( d->mSqueezeText )
309 d->updateCheckedItems();
314 switch ( event->type() ) {
315 case QEvent::KeyPress:
316 case QEvent::KeyRelease:
317 case QEvent::ShortcutOverride:
319 switch ( static_cast<QKeyEvent *>( event )->key() ) {
321 if ( event->type() == QEvent::KeyPress && view()->isVisible() ) {
322 d->toggleCheckState();
337 case QEvent::MouseButtonDblClick:
338 case QEvent::MouseButtonPress:
339 case QEvent::MouseButtonRelease:
340 d->mIgnoreHide =
true;
341 if ( receiver == lineEdit() ) {
349 return KComboBox::eventFilter( receiver, event );
354 return d->mAlwaysShowDefaultText;
359 if ( always != d->mAlwaysShowDefaultText ) {
360 d->mAlwaysShowDefaultText = always;
361 d->updateCheckedItems();
365 #include "kcheckcombobox.moc"
void setItemCheckState(int index, Qt::CheckState state)
Changes the check state of the given index to the given state.
bool alwaysShowDefaultText() const
Returns whether the default text is always shown, even if there are no checked items.
KCheckComboBox(QWidget *parent=0)
Creates a new checkable combobox.
void setAlwaysShowDefaultText(bool always)
Sets if the default text should always be shown even if there are no checked items.
A combobox that shows its items in such a way that they can be checked in the drop menu...
bool itemEnabled(int index)
Return whether or not the item at.
virtual ~KCheckComboBox()
Destroys the time zone combobox.
QString defaultText() const
Returns the default text that is shown when no items are selected.
virtual void resizeEvent(QResizeEvent *event)
void setItemEnabled(int index, bool enabled=true)
Set the item at.
virtual bool eventFilter(QObject *receiver, QEvent *event)
void setSeparator(const QString &separator)
Sets the separator used to separate items in the line edit.
virtual void keyPressEvent(QKeyEvent *event)
QString separator() const
Returns the current separator used to separate the selected items in the line edit of the combo box...
void setDefaultText(const QString &text)
Sets the default text that is shown when no items are selected.
void setSqueezeText(bool squeeze)
Sets whether or not the text must be squeezed.
bool squeezeText() const
Returns whether or not the text will be squeezed to fit in the combo's line edit. ...
Qt::CheckState itemCheckState(int index) const
Returns the check state of item at given index.
void setCheckedItems(const QStringList &items, int role=Qt::DisplayRole)
Sets the currently selected items.
virtual void hidePopup()
Hides the popup list if it is currently shown.
virtual void wheelEvent(QWheelEvent *event)