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"
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.