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 );
57 setUniformItemSizes(
true);
60 setFrameStyle( QFrame::Box | QFrame::Plain );
62 setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
63 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
65 connect(
this, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
67 connect(
this, SIGNAL(itemClicked(QListWidgetItem*)),
68 SLOT(slotItemClicked(QListWidgetItem*)) );
81 for (
int i = 0 ; i < count() ; i++)
83 const QListWidgetItem* currItem = item(i);
85 list.append(currItem->text());
102 int type = e->type();
109 if (wid && wid == d->m_parent &&
110 (type == QEvent::Move || type == QEvent::Resize)) {
115 if (wid && (wid->windowFlags() & Qt::Window) &&
116 type == QEvent::Move && wid == d->m_parent->window()) {
121 if (type == QEvent::MouseButtonPress && (wid && !isAncestorOf(wid))) {
122 if (!d->emitSelected && currentItem() && !qobject_cast<QScrollBar*>(o)) {
123 Q_ASSERT(currentItem());
124 emit currentTextChanged(currentItem()->text() );
131 if (wid && wid->isAncestorOf(d->m_parent) && isVisible()) {
132 if ( type == QEvent::KeyPress ) {
133 QKeyEvent *ev =
static_cast<QKeyEvent *
>( e );
134 switch ( ev->key() ) {
135 case Qt::Key_Backtab:
136 if ( d->tabHandling && (ev->modifiers() == Qt::NoButton ||
137 (ev->modifiers() & Qt::ShiftModifier)) ) {
144 if ( d->tabHandling && (ev->modifiers() == Qt::NoButton) ) {
167 if ( !selectedItems().isEmpty() ||
168 mapToGlobal(
QPoint( 0, 0 ) ).y() >
169 d->m_parent->mapToGlobal(
QPoint( 0, 0 ) ).y() )
179 case Qt::Key_PageDown:
189 if ( ev->modifiers() & Qt::ShiftModifier ) {
196 if ( ev->modifiers() & Qt::ControlModifier )
204 if ( ev->modifiers() & Qt::ControlModifier )
213 }
else if ( type == QEvent::ShortcutOverride ) {
216 QKeyEvent *ev =
static_cast<QKeyEvent *
>( e );
217 switch ( ev->key() ) {
221 case Qt::Key_PageDown:
228 case Qt::Key_Backtab:
229 if ( ev->modifiers() == Qt::NoButton ||
230 (ev->modifiers() & Qt::ShiftModifier))
238 if ( ev->modifiers() & Qt::ControlModifier )
247 }
else if ( type == QEvent::FocusOut ) {
248 QFocusEvent*
event =
static_cast<QFocusEvent*
>( e );
249 if (event->reason() != Qt::PopupFocusReason
251 && (
event->reason() != Qt::ActiveWindowFocusReason || QApplication::activeWindow() !=
this)
258 return KListWidget::eventFilter( o, e );
266 bool block = signalsBlocked();
267 blockSignals(
true );
269 blockSignals( block );
273 else if ( size().height() !=
sizeHint().height() )
280 int currentGeom = height();
281 QPoint currentPos = pos();
283 resize( geom.size() );
285 int x = currentPos.x(), y = currentPos.y();
287 if ( !isVisible() ) {
291 x = orig.x() + geom.x();
292 y = orig.y() + geom.y();
294 if ( x + width() > screenSize.right() )
295 x = screenSize.right() - width();
296 if (y + height() > screenSize.bottom() ) {
297 y = y - height() - d->m_parent->height();
304 y += (currentGeom-height());
314 return d->m_parent->mapToGlobal(
QPoint(0, d->m_parent->height()) );
320 d->upwardBox =
false;
323 qApp->installEventFilter(
this );
338 qApp->sendPostedEvents();
341 qApp->removeEventFilter(
this );
342 d->cancelText.clear();
345 KListWidget::setVisible(visible);
351 if (count() == 0 || !(visualRect = visualItemRect(item(0))).isValid())
355 int ih = visualRect.height();
356 int h = qMin( 15 * ih, (
int) count() * ih ) + 2*frameWidth();
358 int w = (d->m_parent) ? d->m_parent->width() : KListWidget::minimumSizeHint().width();
359 w = qMax( KListWidget::minimumSizeHint().width(), w );
367 if ( d->m_parent && (combo = d->m_parent->parent() ) &&
368 qobject_cast<QComboBox*>(combo) )
373 w = qMax( w, cb->width() );
375 QPoint parentCorner = d->m_parent->mapToGlobal(
QPoint(0, 0));
379 x += comboCorner.x() - parentCorner.x();
382 y += cb->height() - d->m_parent->height() +
383 comboCorner.y() - parentCorner.y();
386 QRect styleAdj = style().querySubControlMetrics(QStyle::CC_ComboBox,
387 cb, QStyle::SC_ComboBoxListBoxPopup,
388 QStyleOption(x, y, w, h));
391 if (!styleAdj.isNull())
396 return QRect(x, y, w, h);
406 const int row = currentRow();
407 const int lastRow = count() - 1;
409 setCurrentRow(row + 1);
420 const int row = currentRow();
422 setCurrentRow(row - 1);
426 const int lastRow = count() - 1;
428 setCurrentRow(lastRow);
437 moveCursor(QAbstractItemView::MovePageDown , Qt::NoModifier);
446 moveCursor(QAbstractItemView::MovePageUp , Qt::NoModifier);
456 setCurrentRow( count() -1 );
461 d->tabHandling = enable;
466 return d->tabHandling;
471 d->cancelText = text;
476 return d->cancelText;
479 void KCompletionBox::canceled()
481 if ( !d->cancelText.isNull() )
487 class KCompletionBoxItem :
public QListWidgetItem
491 bool reuse(
const QString& newText )
493 if ( text() == newText )
503 bool block = signalsBlocked();
504 blockSignals(
true );
505 KListWidget::insertItems( index, items );
506 blockSignals( block );
512 bool block = signalsBlocked();
513 blockSignals(
true );
525 QStringList::ConstIterator it = items.constBegin();
526 const QStringList::ConstIterator itEnd = items.constEnd();
528 for ( ; it != itEnd; ++it) {
529 if ( rowIndex < count() ) {
530 const bool changed = ((KCompletionBoxItem*)item(rowIndex))->reuse( *it );
531 dirty = dirty || changed;
541 if (rowIndex < count()) {
546 for ( ; rowIndex < count() ; ) {
547 QListWidgetItem* item = takeItem(rowIndex);
557 if (isVisible() && size().height() !=
sizeHint().height())
563 void KCompletionBox::slotItemClicked( QListWidgetItem *item )
568 emit currentTextChanged( item->text() );
575 d->emitSelected = state;
580 return d->emitSelected;
583 #include "kcompletionbox.moc"