27 #include <QtCore/QEvent>
28 #include <QtGui/QApplication>
29 #include <QtGui/QComboBox>
30 #include <QtGui/QStyle>
31 #include <QtGui/QScrollBar>
32 #include <QtGui/QKeyEvent>
38 class KCompletionBox::KCompletionBoxPrivate
45 bool emitSelected : 1;
52 d->tabHandling =
true;
54 d->emitSelected =
true;
56 setWindowFlags( Qt::ToolTip );
59 setFrameStyle( QFrame::Box | QFrame::Plain );
61 setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
62 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
64 connect(
this, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
66 connect(
this, SIGNAL(itemClicked(QListWidgetItem*)),
67 SLOT(slotItemClicked(QListWidgetItem*)) );
80 for (
int i = 0 ; i < count() ; i++)
82 const QListWidgetItem* currItem = item(i);
84 list.append(currItem->text());
101 int type = e->type();
108 if (wid && wid == d->m_parent &&
109 (type == QEvent::Move || type == QEvent::Resize)) {
114 if (wid && (wid->windowFlags() & Qt::Window) &&
115 type == QEvent::Move && wid == d->m_parent->window()) {
120 if (type == QEvent::MouseButtonPress && (wid && !isAncestorOf(wid))) {
121 if (!d->emitSelected && currentItem() && !qobject_cast<QScrollBar*>(o)) {
122 Q_ASSERT(currentItem());
123 emit currentTextChanged(currentItem()->text() );
130 if (wid && wid->isAncestorOf(d->m_parent) && isVisible()) {
131 if ( type == QEvent::KeyPress ) {
132 QKeyEvent *ev =
static_cast<QKeyEvent *
>( e );
133 switch ( ev->key() ) {
134 case Qt::Key_Backtab:
135 if ( d->tabHandling && (ev->modifiers() == Qt::NoButton ||
136 (ev->modifiers() & Qt::ShiftModifier)) ) {
143 if ( d->tabHandling && (ev->modifiers() == Qt::NoButton) ) {
166 if ( !selectedItems().isEmpty() ||
167 mapToGlobal(
QPoint( 0, 0 ) ).y() >
168 d->m_parent->mapToGlobal(
QPoint( 0, 0 ) ).y() )
178 case Qt::Key_PageDown:
188 if ( ev->modifiers() & Qt::ShiftModifier ) {
195 if ( ev->modifiers() & Qt::ControlModifier )
203 if ( ev->modifiers() & Qt::ControlModifier )
212 }
else if ( type == QEvent::ShortcutOverride ) {
215 QKeyEvent *ev =
static_cast<QKeyEvent *
>( e );
216 switch ( ev->key() ) {
220 case Qt::Key_PageDown:
227 case Qt::Key_Backtab:
228 if ( ev->modifiers() == Qt::NoButton ||
229 (ev->modifiers() & Qt::ShiftModifier))
237 if ( ev->modifiers() & Qt::ControlModifier )
246 }
else if ( type == QEvent::FocusOut ) {
247 QFocusEvent*
event =
static_cast<QFocusEvent*
>( e );
248 if (event->reason() != Qt::PopupFocusReason
250 && (
event->reason() != Qt::ActiveWindowFocusReason || QApplication::activeWindow() !=
this)
265 bool block = signalsBlocked();
266 blockSignals(
true );
268 blockSignals( block );
272 else if ( size().height() !=
sizeHint().height() )
279 int currentGeom = height();
280 QPoint currentPos = pos();
282 resize( geom.size() );
284 int x = currentPos.x(), y = currentPos.y();
286 if ( !isVisible() ) {
290 x = orig.x() + geom.x();
291 y = orig.y() + geom.y();
293 if ( x + width() > screenSize.right() )
294 x = screenSize.right() - width();
295 if (y + height() > screenSize.bottom() ) {
296 y = y - height() - d->m_parent->height();
303 y += (currentGeom-height());
313 return d->m_parent->mapToGlobal(
QPoint(0, d->m_parent->height()) );
319 d->upwardBox =
false;
322 qApp->installEventFilter(
this );
337 qApp->sendPostedEvents();
340 qApp->removeEventFilter(
this );
341 d->cancelText.clear();
350 if (count() == 0 || !(visualRect = visualItemRect(item(0))).isValid())
354 int ih = visualRect.height();
355 int h = qMin( 15 * ih, (
int) count() * ih ) + 2*frameWidth();
357 int w = (d->m_parent) ? d->m_parent->width() : KListWidget::minimumSizeHint().width();
358 w = qMax( KListWidget::minimumSizeHint().width(), w );
366 if ( d->m_parent && (combo = d->m_parent->parent() ) &&
367 qobject_cast<QComboBox*>(combo) )
372 w = qMax( w, cb->width() );
374 QPoint parentCorner = d->m_parent->mapToGlobal(
QPoint(0, 0));
378 x += comboCorner.x() - parentCorner.x();
381 y += cb->height() - d->m_parent->height() +
382 comboCorner.y() - parentCorner.y();
385 QRect styleAdj = style().querySubControlMetrics(QStyle::CC_ComboBox,
386 cb, QStyle::SC_ComboBoxListBoxPopup,
387 QStyleOption(x, y, w, h));
390 if (!styleAdj.isNull())
395 return QRect(x, y, w, h);
405 const int row = currentRow();
406 const int lastRow = count() - 1;
408 setCurrentRow(row + 1);
419 const int row = currentRow();
421 setCurrentRow(row - 1);
425 const int lastRow = count() - 1;
427 setCurrentRow(lastRow);
436 moveCursor(QAbstractItemView::MovePageDown , Qt::NoModifier);
445 moveCursor(QAbstractItemView::MovePageUp , Qt::NoModifier);
455 setCurrentRow( count() -1 );
460 d->tabHandling = enable;
465 return d->tabHandling;
470 d->cancelText = text;
475 return d->cancelText;
478 void KCompletionBox::canceled()
480 if ( !d->cancelText.isNull() )
486 class KCompletionBoxItem :
public QListWidgetItem
490 bool reuse(
const QString& newText )
492 if ( text() == newText )
502 bool block = signalsBlocked();
503 blockSignals(
true );
505 blockSignals( block );
511 bool block = signalsBlocked();
512 blockSignals(
true );
524 QStringList::ConstIterator it = items.constBegin();
525 const QStringList::ConstIterator itEnd = items.constEnd();
527 for ( ; it != itEnd; ++it) {
528 if ( rowIndex < count() ) {
529 const bool changed = ((KCompletionBoxItem*)item(rowIndex))->reuse( *it );
530 dirty = dirty || changed;
540 if (rowIndex < count()) {
545 for ( ; rowIndex < count() ; ) {
546 QListWidgetItem* item = takeItem(rowIndex);
556 if (isVisible() && size().height() !=
sizeHint().height())
562 void KCompletionBox::slotItemClicked( QListWidgetItem *item )
567 emit currentTextChanged( item->text() );
574 d->emitSelected = state;
579 return d->emitSelected;
582 #include "kcompletionbox.moc"