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)
257 return KListWidget::eventFilter( o, e );
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();
344 KListWidget::setVisible(visible);
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 );
504 KListWidget::insertItems( index, items );
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"
void down()
Moves the selection one line down or select the first item if nothing is selected yet...
~KCompletionBox()
Destroys the box.
QRect calculateGeometry() const
This calculates the size of the dropdown and the relative position of the top left corner with respec...
bool activateOnSelect() const
void doCompletion(const QString &txt)
Do completion now.
KCompletionBox(QWidget *parent=0)
Constructs a KCompletionBox.
void up()
Moves the selection one line up or select the first item if nothing is selected yet.
void setCancelledText(const QString &txt)
Sets the text to be emitted if the user chooses not to pick from the available matches.
QString cancelledText() const
void pageUp()
Moves the selection one page up.
QStringList items() const
Returns a list of all items currently in the box.
static QRect desktopGeometry(const QPoint &point)
This function returns the desktop geometry for an application that needs to set the geometry of a wid...
void setActivateOnSelect(bool state)
Set whether or not the selected signal should be emitted when an item is selected.
virtual void setVisible(bool visible)
Re-implemented for internal reasons.
virtual void popup()
Adjusts the size of the box to fit the width of the parent given in the constructor and pops it up at...
virtual QPoint globalPositionHint() const
The preferred global coordinate at which the completion box's top left corner should be positioned...
void insertItems(const QStringList &items, int index=-1)
Inserts items into the box.
void end()
Moves the selection down to the last item.
void pageDown()
Moves the selection one page down.
void setTabHandling(bool enable)
Makes this widget (when visible) capture Tab-key events to traverse the items in the dropdown list (T...
void home()
Moves the selection up to the first item.
virtual bool eventFilter(QObject *, QEvent *)
Reimplemented from KListWidget to get events from the viewport (to hide this widget on mouse-click...
void activated(const QString &)
Emitted when an item was selected, contains the text of the selected item.
bool isTabHandling() const
An enhanced QLineEdit widget for inputting text.
virtual QSize sizeHint() const
void sizeAndPosition()
This properly sizes and positions the listbox.
void userCancelled(const QString &)
Emitted whenever the user chooses to ignore the available selections and close the this box...
void setItems(const QStringList &items)
Clears the box and inserts items.
virtual void slotActivated(QListWidgetItem *)
Called when an item was activated.