src/gui/widgets/qcombobox.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/widgets/qcombobox.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,3249 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcombobox.h"
+
+#ifndef QT_NO_COMBOBOX
+#include <qstylepainter.h>
+#include <qlineedit.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qlistview.h>
+#include <qtableview.h>
+#include <qitemdelegate.h>
+#include <qmap.h>
+#include <qmenu.h>
+#include <qevent.h>
+#include <qlayout.h>
+#include <qscrollbar.h>
+#include <qtreeview.h>
+#include <qheaderview.h>
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#endif
+#include <private/qapplication_p.h>
+#include <private/qcombobox_p.h>
+#include <private/qabstractitemmodel_p.h>
+#include <private/qabstractscrollarea_p.h>
+#include <private/qsoftkeymanager_p.h>
+#include <qdebug.h>
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#endif
+#if defined(Q_WS_MAC) && !defined(QT_NO_EFFECTS) && !defined(QT_NO_STYLE_MAC)
+#include <private/qcore_mac_p.h>
+#include <QMacStyle>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+#ifndef QT_NO_EFFECTS
+# include <private/qeffects_p.h>
+#endif
+QT_BEGIN_NAMESPACE
+
+QComboBoxPrivate::QComboBoxPrivate()
+    : QWidgetPrivate(),
+      model(0),
+      lineEdit(0),
+      container(0),
+      insertPolicy(QComboBox::InsertAtBottom),
+      sizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow),
+      minimumContentsLength(0),
+      shownOnce(false),
+      autoCompletion(true),
+      duplicatesEnabled(false),
+      frame(true),
+      maxVisibleItems(10),
+      maxCount(INT_MAX),
+      modelColumn(0),
+      inserting(false),
+      arrowState(QStyle::State_None),
+      hoverControl(QStyle::SC_None),
+      autoCompletionCaseSensitivity(Qt::CaseInsensitive),
+      indexBeforeChange(-1)
+#ifndef QT_NO_COMPLETER
+      , completer(0)
+#endif
+{
+}
+
+QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewItem &option,
+                                                        const QModelIndex &index) const
+{
+    QStyleOptionMenuItem menuOption;
+    menuOption.palette = option.palette.resolve(QApplication::palette("QMenu"));
+    menuOption.state = QStyle::State_None;
+    if (mCombo->window()->isActiveWindow())
+        menuOption.state = QStyle::State_Active;
+    if ((option.state & QStyle::State_Enabled) && (index.model()->flags(index) & Qt::ItemIsEnabled))
+        menuOption.state |= QStyle::State_Enabled;
+    else
+        menuOption.palette.setCurrentColorGroup(QPalette::Disabled);
+    if (option.state & QStyle::State_Selected)
+        menuOption.state |= QStyle::State_Selected;
+    menuOption.checkType = QStyleOptionMenuItem::NonExclusive;
+    menuOption.checked = mCombo->currentIndex() == index.row();
+    if (QComboBoxDelegate::isSeparator(index))
+        menuOption.menuItemType = QStyleOptionMenuItem::Separator;
+    else
+        menuOption.menuItemType = QStyleOptionMenuItem::Normal;
+
+    QVariant variant = index.model()->data(index, Qt::DecorationRole);
+    switch (variant.type()) {
+    case QVariant::Icon:
+        menuOption.icon = qvariant_cast<QIcon>(variant);
+        break;
+    case QVariant::Color: {
+        static QPixmap pixmap(option.decorationSize);
+        pixmap.fill(qvariant_cast<QColor>(variant));
+        menuOption.icon = pixmap;
+        break; }
+    default:
+        menuOption.icon = qvariant_cast<QPixmap>(variant);
+        break;
+    }
+
+    menuOption.text = index.model()->data(index, Qt::DisplayRole).toString()
+                           .replace(QLatin1Char('&'), QLatin1String("&&"));
+    menuOption.tabWidth = 0;
+    menuOption.maxIconWidth =  option.decorationSize.width() + 4;
+    menuOption.menuRect = option.rect;
+    menuOption.rect = option.rect;
+
+    // Make sure fonts set on the combo box also overrides the font for the popup menu.
+    if (mCombo->testAttribute(Qt::WA_SetFont)
+            || mCombo->testAttribute(Qt::WA_MacSmallSize)
+            || mCombo->testAttribute(Qt::WA_MacMiniSize)
+            || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont()))
+        menuOption.font = mCombo->font();
+    else
+        menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font());
+
+    menuOption.fontMetrics = QFontMetrics(menuOption.font);
+
+    return menuOption;
+}
+
+#ifdef QT_KEYPAD_NAVIGATION
+void QComboBoxPrivate::_q_completerActivated()
+{
+    Q_Q(QComboBox);
+    if ( QApplication::keypadNavigationEnabled()
+         && q->isEditable()
+         && q->completer()
+         && q->completer()->completionMode() == QCompleter::UnfilteredPopupCompletion ) {
+        q->setEditFocus(false);
+    }
+}
+#endif
+
+void QComboBoxPrivate::updateArrow(QStyle::StateFlag state)
+{
+    Q_Q(QComboBox);
+    if (arrowState == state)
+        return;
+    arrowState = state;
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, q));
+}
+
+void QComboBoxPrivate::_q_modelReset()
+{
+    Q_Q(QComboBox);
+    if (lineEdit) {
+        lineEdit->setText(QString());
+        updateLineEditGeometry();
+    }
+    q->update();
+}
+
+void QComboBoxPrivate::_q_modelDestroyed()
+{
+    model = QAbstractItemModelPrivate::staticEmptyModel();
+}
+
+
+//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
+QRect QComboBoxPrivate::popupGeometry(int screen) const
+{
+#ifdef Q_WS_WIN
+    return QApplication::desktop()->screenGeometry(screen);
+#elif defined Q_WS_X11
+    if (X11->desktopEnvironment == DE_KDE)
+        return QApplication::desktop()->screenGeometry(screen);
+    else
+        return QApplication::desktop()->availableGeometry(screen);
+#else
+        return QApplication::desktop()->availableGeometry(screen);
+#endif
+}
+
+bool QComboBoxPrivate::updateHoverControl(const QPoint &pos)
+{
+
+    Q_Q(QComboBox);
+    QRect lastHoverRect = hoverRect;
+    QStyle::SubControl lastHoverControl = hoverControl;
+    bool doesHover = q->testAttribute(Qt::WA_Hover);
+    if (lastHoverControl != newHoverControl(pos) && doesHover) {
+        q->update(lastHoverRect);
+        q->update(hoverRect);
+        return true;
+    }
+    return !doesHover;
+}
+
+QStyle::SubControl QComboBoxPrivate::newHoverControl(const QPoint &pos)
+{
+    Q_Q(QComboBox);
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    opt.subControls = QStyle::SC_All;
+    hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, pos, q);
+    hoverRect = (hoverControl != QStyle::SC_None)
+                   ? q->style()->subControlRect(QStyle::CC_ComboBox, &opt, hoverControl, q)
+                   : QRect();
+    return hoverControl;
+}
+
+/*
+    Computes a size hint based on the maximum width
+    for the items in the combobox.
+*/
+int QComboBoxPrivate::computeWidthHint() const
+{
+    Q_Q(const QComboBox);
+
+    int width = 0;
+    const int count = q->count();
+    const int iconWidth = q->iconSize().width() + 4;
+    const QFontMetrics &fontMetrics = q->fontMetrics();
+
+    for (int i = 0; i < count; ++i) {
+        const int textWidth = fontMetrics.width(q->itemText(i));
+        if (q->itemIcon(i).isNull())
+            width = (qMax(width, textWidth));
+        else
+            width = (qMax(width, textWidth + iconWidth));
+    }
+
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    QSize tmp(width, 0);
+    tmp = q->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, tmp, q);
+    return tmp.width();
+}
+
+QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
+{
+    Q_Q(const QComboBox);
+    if (!sh.isValid()) {
+        bool hasIcon = sizeAdjustPolicy == QComboBox::AdjustToMinimumContentsLengthWithIcon ? true : false;
+        int count = q->count();
+        QSize iconSize = q->iconSize();
+        const QFontMetrics &fm = q->fontMetrics();
+
+        // text width
+        if (&sh == &sizeHint || minimumContentsLength == 0) {
+            switch (sizeAdjustPolicy) {
+            case QComboBox::AdjustToContents:
+            case QComboBox::AdjustToContentsOnFirstShow:
+                if (count == 0) {
+                    sh.rwidth() = 7 * fm.width(QLatin1Char('x'));
+                } else {
+                    for (int i = 0; i < count; ++i) {
+                        if (!q->itemIcon(i).isNull()) {
+                            hasIcon = true;
+                            sh.setWidth(qMax(sh.width(), fm.boundingRect(q->itemText(i)).width() + iconSize.width() + 4));
+                        } else {
+                            sh.setWidth(qMax(sh.width(), fm.boundingRect(q->itemText(i)).width()));
+                        }
+                    }
+                }
+                break;
+            case QComboBox::AdjustToMinimumContentsLength:
+                for (int i = 0; i < count && !hasIcon; ++i)
+                    hasIcon = !q->itemIcon(i).isNull();
+            default:
+                ;
+            }
+        } else {
+            for (int i = 0; i < count && !hasIcon; ++i)
+                hasIcon = !q->itemIcon(i).isNull();
+        }
+        if (minimumContentsLength > 0)
+            sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.width(QLatin1Char('X')) + (hasIcon ? iconSize.width() + 4 : 0)));
+
+
+        // height
+        sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
+        if (hasIcon) {
+            sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
+        }
+
+        // add style and strut values
+        QStyleOptionComboBox opt;
+        q->initStyleOption(&opt);
+        sh = q->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, q);
+    }
+    return sh.expandedTo(QApplication::globalStrut());
+}
+
+void QComboBoxPrivate::adjustComboBoxSize()
+{
+    viewContainer()->adjustSizeTimer.start(20, container);
+}
+
+void QComboBoxPrivate::updateLayoutDirection()
+{
+    Q_Q(const QComboBox);
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    Qt::LayoutDirection dir = Qt::LayoutDirection(
+        q->style()->styleHint(QStyle::SH_ComboBox_LayoutDirection, &opt, q));
+    if (lineEdit)
+        lineEdit->setLayoutDirection(dir);
+    if (container)
+        container->setLayoutDirection(dir);
+}
+
+
+void QComboBoxPrivateContainer::timerEvent(QTimerEvent *timerEvent)
+{
+    if (timerEvent->timerId() == adjustSizeTimer.timerId()) {
+        adjustSizeTimer.stop();
+        if (combo->sizeAdjustPolicy() == QComboBox::AdjustToContents) {
+            combo->adjustSize();
+            combo->update();
+        }
+    }
+}
+
+void QComboBoxPrivateContainer::resizeEvent(QResizeEvent *e)
+{
+    QStyleOptionComboBox opt = comboStyleOption();
+    if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) {
+        QStyleOption myOpt;
+        myOpt.initFrom(this);
+        QStyleHintReturnMask mask;
+        if (combo->style()->styleHint(QStyle::SH_Menu_Mask, &myOpt, this, &mask)) {
+            setMask(mask.region);
+        }
+    } else {
+        clearMask();
+    }
+    QFrame::resizeEvent(e);
+}
+
+void QComboBoxPrivateContainer::leaveEvent(QEvent *)
+{
+// On Mac using the Mac style we want to clear the selection
+// when the mouse moves outside the popup.
+#ifdef Q_WS_MAC
+    QStyleOptionComboBox opt = comboStyleOption();
+    if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo))
+        view->clearSelection();
+#endif
+}
+
+QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent)
+    : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0)
+{
+    // we need the combobox and itemview
+    Q_ASSERT(parent);
+    Q_ASSERT(itemView);
+
+    setAttribute(Qt::WA_WindowPropagation);
+    setAttribute(Qt::WA_X11NetWmWindowTypeCombo);
+
+    // setup container
+    blockMouseReleaseTimer.setSingleShot(true);
+
+    // we need a vertical layout
+    QBoxLayout *layout =  new QBoxLayout(QBoxLayout::TopToBottom, this);
+    layout->setSpacing(0);
+    layout->setMargin(0);
+
+#ifdef QT_SOFTKEYS_ENABLED
+    selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, this);
+    cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, this);
+    addAction(selectAction);
+    addAction(cancelAction);
+#endif
+
+    // set item view
+    setItemView(itemView);
+
+    // add scroller arrows if style needs them
+    QStyleOptionComboBox opt = comboStyleOption();
+    const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo);
+    if (usePopup) {
+        top = new QComboBoxPrivateScroller(QAbstractSlider::SliderSingleStepSub, this);
+        bottom = new QComboBoxPrivateScroller(QAbstractSlider::SliderSingleStepAdd, this);
+        top->hide();
+        bottom->hide();
+    } else {
+        setLineWidth(1);
+    }
+
+    setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
+
+    if (top) {
+        layout->insertWidget(0, top);
+        connect(top, SIGNAL(doScroll(int)), this, SLOT(scrollItemView(int)));
+    }
+    if (bottom) {
+        layout->addWidget(bottom);
+        connect(bottom, SIGNAL(doScroll(int)), this, SLOT(scrollItemView(int)));
+    }
+
+    // Some styles (Mac) have a margin at the top and bottom of the popup.
+    layout->insertSpacing(0, 0);
+    layout->addSpacing(0);
+    updateTopBottomMargin();
+}
+
+void QComboBoxPrivateContainer::scrollItemView(int action)
+{
+#ifndef QT_NO_SCROLLBAR
+    if (view->verticalScrollBar())
+        view->verticalScrollBar()->triggerAction(static_cast<QAbstractSlider::SliderAction>(action));
+#endif
+}
+
+/*
+    Hides or shows the scrollers when we emulate a popupmenu
+*/
+void QComboBoxPrivateContainer::updateScrollers()
+{
+#ifndef QT_NO_SCROLLBAR
+    if (!top || !bottom)
+        return;
+
+    if (isVisible() == false)
+        return;
+
+    QStyleOptionComboBox opt = comboStyleOption();
+    if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo) &&
+        view->verticalScrollBar()->minimum() < view->verticalScrollBar()->maximum()) {
+
+        bool needTop = view->verticalScrollBar()->value()
+                       > (view->verticalScrollBar()->minimum() + spacing());
+        bool needBottom = view->verticalScrollBar()->value()
+                          < (view->verticalScrollBar()->maximum() - spacing()*2);
+        if (needTop)
+            top->show();
+        else
+            top->hide();
+        if (needBottom)
+            bottom->show();
+        else
+            bottom->hide();
+    } else {
+        top->hide();
+        bottom->hide();
+    }
+#endif // QT_NO_SCROLLBAR
+}
+
+/*
+    Cleans up when the view is destroyed.
+*/
+void QComboBoxPrivateContainer::viewDestroyed()
+{
+    view = 0;
+    setItemView(new QComboBoxListView());
+}
+
+/*
+    Sets currentIndex on entered if the LeftButton is not pressed. This
+    means that if mouseTracking(...) is on, we setCurrentIndex and select
+    even when LeftButton is not pressed.
+*/
+void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index)
+{
+    if (QComboBoxDelegate::isSeparator(index))
+        return;
+    view->setCurrentIndex(index);
+}
+
+/*
+    Returns the item view used for the combobox popup.
+*/
+QAbstractItemView *QComboBoxPrivateContainer::itemView() const
+{
+    return view;
+}
+
+/*!
+    Sets the item view to be used for the combobox popup.
+*/
+void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
+{
+    Q_ASSERT(itemView);
+
+    // clean up old one
+    if (view) {
+        view->removeEventFilter(this);
+        view->viewport()->removeEventFilter(this);
+#ifndef QT_NO_SCROLLBAR
+        disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),
+                   this, SLOT(updateScrollers()));
+        disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
+                   this, SLOT(updateScrollers()));
+#endif
+        disconnect(view, SIGNAL(entered(QModelIndex)),
+                   this, SLOT(setCurrentIndex(QModelIndex)));
+        disconnect(view, SIGNAL(destroyed()),
+                   this, SLOT(viewDestroyed()));
+
+        delete view;
+        view = 0;
+    }
+
+    // setup the item view
+    view = itemView;
+    view->setParent(this);
+    view->setAttribute(Qt::WA_MacShowFocusRect, false);
+    qobject_cast<QBoxLayout*>(layout())->insertWidget(top ? 2 : 0, view);
+    view->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+    view->installEventFilter(this);
+    view->viewport()->installEventFilter(this);
+    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    QStyleOptionComboBox opt = comboStyleOption();
+    const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo);
+#ifndef QT_NO_SCROLLBAR
+    if (usePopup)
+        view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+#endif
+    if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
+        usePopup) {
+        view->setMouseTracking(true);
+    }
+    view->setSelectionMode(QAbstractItemView::SingleSelection);
+    view->setFrameStyle(QFrame::NoFrame);
+    view->setLineWidth(0);
+    view->setEditTriggers(QAbstractItemView::NoEditTriggers);
+#ifndef QT_NO_SCROLLBAR
+    connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),
+            this, SLOT(updateScrollers()));
+    connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
+            this, SLOT(updateScrollers()));
+#endif
+    connect(view, SIGNAL(entered(QModelIndex)),
+            this, SLOT(setCurrentIndex(QModelIndex)));
+    connect(view, SIGNAL(destroyed()),
+            this, SLOT(viewDestroyed()));
+}
+
+/*!
+    Returns the spacing between the items in the view.
+*/
+int QComboBoxPrivateContainer::spacing() const
+{
+    QListView *lview = qobject_cast<QListView*>(view);
+    if (lview)
+        return lview->spacing();
+#ifndef QT_NO_TABLEVIEW
+    QTableView *tview = qobject_cast<QTableView*>(view);
+    if (tview)
+        return tview->showGrid() ? 1 : 0;
+#endif
+    return 0;
+}
+
+void QComboBoxPrivateContainer::updateTopBottomMargin()
+{
+    if (!layout() || layout()->count() < 1)
+        return;
+
+    QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(layout());
+    if (!boxLayout)
+        return;
+
+    const QStyleOptionComboBox opt = comboStyleOption();
+    const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo);
+    const int margin = usePopup ? combo->style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, combo) : 0;
+
+    QSpacerItem *topSpacer = boxLayout->itemAt(0)->spacerItem();
+    if (topSpacer)
+        topSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+    QSpacerItem *bottomSpacer = boxLayout->itemAt(boxLayout->count() - 1)->spacerItem();
+    if (bottomSpacer && bottomSpacer != topSpacer)
+        bottomSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+    boxLayout->invalidate();
+}
+
+void QComboBoxPrivateContainer::changeEvent(QEvent *e)
+{
+    if (e->type() == QEvent::StyleChange) {
+        QStyleOptionComboBox opt = comboStyleOption();
+        view->setMouseTracking(combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
+                               combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo));
+        setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo));
+    }
+    QWidget::changeEvent(e);
+}
+
+
+bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
+{
+    switch (e->type()) {
+    case QEvent::ShortcutOverride:
+        switch (static_cast<QKeyEvent*>(e)->key()) {
+        case Qt::Key_Enter:
+        case Qt::Key_Return:
+#ifdef QT_KEYPAD_NAVIGATION
+        case Qt::Key_Select:
+#endif
+            if (view->currentIndex().isValid() && (view->currentIndex().flags() & Qt::ItemIsEnabled) ) {
+                combo->hidePopup();
+                emit itemSelected(view->currentIndex());
+            }
+            return true;
+        case Qt::Key_Down:
+            if (!(static_cast<QKeyEvent*>(e)->modifiers() & Qt::AltModifier))
+                break;
+            // fall through
+        case Qt::Key_F4:
+        case Qt::Key_Escape:
+            combo->hidePopup();
+            return true;
+        default:
+            break;
+        }
+    break;
+    case QEvent::MouseMove: {
+        if (isVisible()) {
+            QMouseEvent *m = static_cast<QMouseEvent *>(e);
+            QWidget *widget = static_cast<QWidget *>(o);
+            QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition;
+            if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
+                blockMouseReleaseTimer.stop();
+        }
+        break;
+    }
+    case QEvent::MouseButtonRelease: {
+        QMouseEvent *m = static_cast<QMouseEvent *>(e);
+        if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()
+            && !blockMouseReleaseTimer.isActive()
+            && (view->currentIndex().flags() & Qt::ItemIsEnabled)
+            && (view->currentIndex().flags() & Qt::ItemIsSelectable)) {
+            combo->hidePopup();
+            emit itemSelected(view->currentIndex());
+            return true;
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    return QFrame::eventFilter(o, e);
+}
+
+void QComboBoxPrivateContainer::showEvent(QShowEvent *)
+{
+    combo->update();
+}
+
+void QComboBoxPrivateContainer::hideEvent(QHideEvent *)
+{
+    emit resetButton();
+    combo->update();
+}
+
+void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e)
+{
+
+    QStyleOptionComboBox opt = comboStyleOption();
+    opt.subControls = QStyle::SC_All;
+    opt.activeSubControls = QStyle::SC_ComboBoxArrow;
+    QStyle::SubControl sc = combo->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt,
+                                                           combo->mapFromGlobal(e->globalPos()),
+                                                           combo);
+    if ((combo->isEditable() && sc == QStyle::SC_ComboBoxArrow)
+        || (!combo->isEditable() && sc != QStyle::SC_None))
+        setAttribute(Qt::WA_NoMouseReplay);
+    combo->hidePopup();
+}
+
+void QComboBoxPrivateContainer::mouseReleaseEvent(QMouseEvent *e)
+{
+    Q_UNUSED(e);
+    if (!blockMouseReleaseTimer.isActive()){
+        combo->hidePopup();
+        emit resetButton();
+    }
+}
+
+QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
+{
+    // ### This should use QComboBox's initStyleOption(), but it's protected
+    // perhaps, we could cheat by having the QCombo private instead?
+    QStyleOptionComboBox opt;
+    opt.initFrom(combo);
+    opt.subControls = QStyle::SC_All;
+    opt.activeSubControls = QStyle::SC_None;
+    opt.editable = combo->isEditable();
+    return opt;
+}
+
+/*!
+    \enum QComboBox::InsertPolicy
+
+    This enum specifies what the QComboBox should do when a new string is
+    entered by the user.
+
+    \value NoInsert             The string will not be inserted into the combobox.
+    \value InsertAtTop          The string will be inserted as the first item in the combobox.
+    \value InsertAtCurrent      The current item will be \e replaced by the string.
+    \value InsertAtBottom       The string will be inserted after the last item in the combobox.
+    \value InsertAfterCurrent   The string is inserted after the current item in the combobox.
+    \value InsertBeforeCurrent  The string is inserted before the current item in the combobox.
+    \value InsertAlphabetically The string is inserted in the alphabetic order in the combobox.
+    \omitvalue NoInsertion
+    \omitvalue AtTop
+    \omitvalue AtCurrent
+    \omitvalue AtBottom
+    \omitvalue AfterCurrent
+    \omitvalue BeforeCurrent
+*/
+
+/*!
+    \enum QComboBox::SizeAdjustPolicy
+
+    This enum specifies how the size hint of the QComboBox should
+    adjust when new content is added or content changes.
+
+    \value AdjustToContents              The combobox will always adjust to the contents
+    \value AdjustToContentsOnFirstShow   The combobox will adjust to its contents the first time it is shown.
+    \value AdjustToMinimumContentsLength Use AdjustToContents or AdjustToContentsOnFirstShow instead.
+    \value AdjustToMinimumContentsLengthWithIcon The combobox will adjust to \l minimumContentsLength plus space for an icon. For performance reasons use this policy on large models.
+*/
+
+/*!
+    \fn void QComboBox::activated(int index)
+
+    This signal is sent when the user chooses an item in the combobox.
+    The item's \a index is passed. Note that this signal is sent even
+    when the choice is not changed. If you need to know when the
+    choice actually changes, use signal currentIndexChanged().
+
+*/
+
+/*!
+    \fn void QComboBox::activated(const QString &text)
+
+    This signal is sent when the user chooses an item in the combobox.
+    The item's \a text is passed. Note that this signal is sent even
+    when the choice is not changed. If you need to know when the
+    choice actually changes, use signal currentIndexChanged().
+
+*/
+
+/*!
+    \fn void QComboBox::highlighted(int index)
+
+    This signal is sent when an item in the combobox popup list is
+    highlighted by the user. The item's \a index is passed.
+*/
+
+/*!
+    \fn void QComboBox::highlighted(const QString &text)
+
+    This signal is sent when an item in the combobox popup list is
+    highlighted by the user. The item's \a text is passed.
+*/
+
+/*!
+    \fn void QComboBox::currentIndexChanged(int index)
+    \since 4.1
+
+    This signal is sent whenever the currentIndex in the combobox
+    changes either through user interaction or programmatically. The
+    item's \a index is passed or -1 if the combobox becomes empty or the
+    currentIndex was reset.
+*/
+
+/*!
+    \fn void QComboBox::currentIndexChanged(const QString &text)
+    \since 4.1
+
+    This signal is sent whenever the currentIndex in the combobox
+    changes either through user interaction or programmatically.  The
+    item's \a text is passed.
+*/
+
+/*!
+    Constructs a combobox with the given \a parent, using the default
+    model QStandardItemModel.
+*/
+QComboBox::QComboBox(QWidget *parent)
+    : QWidget(*new QComboBoxPrivate(), parent, 0)
+{
+    Q_D(QComboBox);
+    d->init();
+}
+
+/*!
+  \internal
+*/
+QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent)
+    : QWidget(dd, parent, 0)
+{
+    Q_D(QComboBox);
+    d->init();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+    Use one of the constructors that doesn't take the \a name
+    argument and then use setObjectName() instead.
+*/
+QComboBox::QComboBox(QWidget *parent, const char *name)
+    : QWidget(*new QComboBoxPrivate(), parent, 0)
+{
+    Q_D(QComboBox);
+    d->init();
+    setObjectName(QString::fromAscii(name));
+}
+
+/*!
+    Use one of the constructors that doesn't take the \a name
+    argument and then use setObjectName() instead.
+*/
+QComboBox::QComboBox(bool rw, QWidget *parent, const char *name)
+    : QWidget(*new QComboBoxPrivate(), parent, 0)
+{
+    Q_D(QComboBox);
+    d->init();
+    setEditable(rw);
+    setObjectName(QString::fromAscii(name));
+}
+
+#endif //QT3_SUPPORT
+
+/*!
+    \class QComboBox
+    \brief The QComboBox widget is a combined button and popup list.
+
+    \ingroup basicwidgets
+
+
+    A QComboBox provides a means of presenting a list of options to the user
+    in a way that takes up the minimum amount of screen space.
+
+    A combobox is a selection widget that displays the current item,
+    and can pop up a list of selectable items. A combobox may be editable,
+    allowing the user to modify each item in the list.
+
+    Comboboxes can contain pixmaps as well as strings; the
+    insertItem() and setItemText() functions are suitably overloaded.
+    For editable comboboxes, the function clearEditText() is provided,
+    to clear the displayed string without changing the combobox's
+    contents.
+
+    There are two signals emitted if the current item of a combobox
+    changes, currentIndexChanged() and activated().
+    currentIndexChanged() is always emitted regardless if the change
+    was done programmatically or by user interaction, while
+    activated() is only emitted when the change is caused by user
+    interaction. The highlighted() signal is emitted when the user
+    highlights an item in the combobox popup list. All three signals
+    exist in two versions, one with a QString argument and one with an
+    \c int argument. If the user selectes or highlights a pixmap, only
+    the \c int signals are emitted. Whenever the text of an editable
+    combobox is changed the editTextChanged() signal is emitted.
+
+    When the user enters a new string in an editable combobox, the
+    widget may or may not insert it, and it can insert it in several
+    locations. The default policy is is \l AtBottom but you can change
+    this using setInsertPolicy().
+
+    It is possible to constrain the input to an editable combobox
+    using QValidator; see setValidator(). By default, any input is
+    accepted.
+
+    A combobox can be populated using the insert functions,
+    insertItem() and insertItems() for example. Items can be
+    changed with setItemText(). An item can be removed with
+    removeItem() and all items can be removed with clear(). The text
+    of the current item is returned by currentText(), and the text of
+    a numbered item is returned with text(). The current item can be
+    set with setCurrentIndex(). The number of items in the combobox is
+    returned by count(); the maximum number of items can be set with
+    setMaxCount(). You can allow editing using setEditable(). For
+    editable comboboxes you can set auto-completion using
+    setCompleter() and whether or not the user can add duplicates
+    is set with setDuplicatesEnabled().
+
+    QComboBox uses the \l{Model/View Programming}{model/view
+    framework} for its popup list and to store its items.  By default
+    a QStandardItemModel stores the items and a QListView subclass
+    displays the popuplist. You can access the model and view directly
+    (with model() and view()), but QComboBox also provides functions
+    to set and get item data (e.g., setItemData() and itemText()). You
+    can also set a new model and view (with setModel() and setView()).
+    For the text and icon in the combobox label, the data in the model
+    that has the Qt::DisplayRole and Qt::DecorationRole is used.
+
+    \image qstyle-comboboxes.png Comboboxes in the different built-in styles.
+
+    \sa QLineEdit, QSpinBox, QRadioButton, QButtonGroup,
+        {fowler}{GUI Design Handbook: Combo Box, Drop-Down List Box}
+*/
+
+void QComboBoxPrivate::init()
+{
+    Q_Q(QComboBox);
+    q->setFocusPolicy(Qt::WheelFocus);
+    q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed,
+                                 QSizePolicy::ComboBox));
+    setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
+    q->setModel(new QStandardItemModel(0, 1, q));
+    q->setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer()
+{
+    if (container)
+        return container;
+
+    Q_Q(QComboBox);
+    container = new QComboBoxPrivateContainer(new QComboBoxListView(q), q);
+    container->itemView()->setModel(model);
+    container->itemView()->setTextElideMode(Qt::ElideMiddle);
+    updateDelegate(true);
+    updateLayoutDirection();
+    updateViewContainerPaletteAndOpacity();
+    QObject::connect(container, SIGNAL(itemSelected(QModelIndex)),
+                     q, SLOT(_q_itemSelected(QModelIndex)));
+    QObject::connect(container->itemView()->selectionModel(),
+                     SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+                     q, SLOT(_q_emitHighlighted(QModelIndex)));
+    QObject::connect(container, SIGNAL(resetButton()), q, SLOT(_q_resetButton()));
+    return container;
+}
+
+
+void QComboBoxPrivate::_q_resetButton()
+{
+    updateArrow(QStyle::State_None);
+}
+
+void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+    Q_Q(QComboBox);
+    if (inserting || topLeft.parent() != root)
+        return;
+
+    if (sizeAdjustPolicy == QComboBox::AdjustToContents) {
+        sizeHint = QSize();
+        adjustComboBoxSize();
+        q->updateGeometry();
+    }
+
+    if (currentIndex.row() >= topLeft.row() && currentIndex.row() <= bottomRight.row()) {
+        if (lineEdit) {
+            lineEdit->setText(q->itemText(currentIndex.row()));
+            updateLineEditGeometry();
+        }
+        q->update();
+    }
+}
+
+void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent,
+                                             int /*start*/, int /*end*/)
+{
+    if (parent != root)
+        return;
+    indexBeforeChange = currentIndex.row();
+}
+
+void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
+{
+    Q_Q(QComboBox);
+    if (inserting || parent != root)
+        return;
+
+    if (sizeAdjustPolicy == QComboBox::AdjustToContents) {
+        sizeHint = QSize();
+        adjustComboBoxSize();
+        q->updateGeometry();
+    }
+
+    // set current index if combo was previously empty
+    if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid()) {
+        q->setCurrentIndex(0);
+        // need to emit changed if model updated index "silently"
+    } else if (currentIndex.row() != indexBeforeChange) {
+        q->update();
+        _q_emitCurrentIndexChanged(currentIndex);
+    }
+}
+
+void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
+{
+    if (parent != root)
+        return;
+
+    indexBeforeChange = currentIndex.row();
+}
+
+void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
+{
+    Q_Q(QComboBox);
+    if (parent != root)
+        return;
+
+    if (sizeAdjustPolicy == QComboBox::AdjustToContents) {
+        sizeHint = QSize();
+        adjustComboBoxSize();
+        q->updateGeometry();
+    }
+
+    // model has changed the currentIndex
+    if (currentIndex.row() != indexBeforeChange) {
+        if (!currentIndex.isValid() && q->count()) {
+            q->setCurrentIndex(qMin(q->count() - 1, qMax(indexBeforeChange, 0)));
+            return;
+        }
+        if (lineEdit) {
+            lineEdit->setText(q->itemText(currentIndex.row()));
+            updateLineEditGeometry();
+        }
+        q->update();
+        _q_emitCurrentIndexChanged(currentIndex);
+    }
+}
+
+
+void QComboBoxPrivate::updateViewContainerPaletteAndOpacity()
+{
+    if (!container)
+        return;
+    Q_Q(QComboBox);
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+#ifndef QT_NO_MENU
+    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
+        QMenu menu;
+        menu.ensurePolished();
+        container->setPalette(menu.palette());
+        container->setWindowOpacity(menu.windowOpacity());
+    } else
+#endif
+    {
+        container->setPalette(q->palette());
+        container->setWindowOpacity(1.0);
+    }
+}
+
+/*!
+    Initialize \a option with the values from this QComboBox. This method
+    is useful for subclasses when they need a QStyleOptionComboBox, but don't want
+    to fill in all the information themselves.
+
+    \sa QStyleOption::initFrom()
+*/
+void QComboBox::initStyleOption(QStyleOptionComboBox *option) const
+{
+    if (!option)
+        return;
+
+    Q_D(const QComboBox);
+    option->initFrom(this);
+    option->editable = isEditable();
+    option->frame = d->frame;
+    if (hasFocus() && !option->editable)
+        option->state |= QStyle::State_Selected;
+    option->subControls = QStyle::SC_All;
+    if (d->arrowState == QStyle::State_Sunken) {
+        option->activeSubControls = QStyle::SC_ComboBoxArrow;
+        option->state |= d->arrowState;
+    } else {
+        option->activeSubControls = d->hoverControl;
+    }
+    if (d->currentIndex.isValid()) {
+        option->currentText = currentText();
+        option->currentIcon = d->itemIcon(d->currentIndex);
+    }
+    option->iconSize = iconSize();
+    if (d->container && d->container->isVisible())
+        option->state |= QStyle::State_On;
+}
+
+void QComboBoxPrivate::updateLineEditGeometry()
+{
+    if (!lineEdit)
+        return;
+
+    Q_Q(QComboBox);
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    QRect editRect = q->style()->subControlRect(QStyle::CC_ComboBox, &opt,
+                                                QStyle::SC_ComboBoxEditField, q);
+    if (!q->itemIcon(q->currentIndex()).isNull()) {
+        QRect comboRect(editRect);
+        editRect.setWidth(editRect.width() - q->iconSize().width() - 4);
+        editRect = QStyle::alignedRect(q->layoutDirection(), Qt::AlignRight,
+                                       editRect.size(), comboRect);
+    }
+    lineEdit->setGeometry(editRect);
+}
+
+void QComboBoxPrivate::_q_returnPressed()
+{
+    Q_Q(QComboBox);
+    if (lineEdit && !lineEdit->text().isEmpty()) {
+        if (q->count() >= maxCount && !(this->insertPolicy == QComboBox::InsertAtCurrent))
+            return;
+        lineEdit->deselect();
+        lineEdit->end(false);
+        QString text = lineEdit->text();
+        // check for duplicates (if not enabled) and quit
+        int index = -1;
+        if (!duplicatesEnabled) {
+            // Base how duplicates are determined on the autocompletion case sensitivity
+            Qt::MatchFlags flags = Qt::MatchFixedString;
+#ifndef QT_NO_COMPLETER
+            if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
+#endif
+                flags |= Qt::MatchCaseSensitive;
+            index = q->findText(text, flags);
+            if (index != -1) {
+                q->setCurrentIndex(index);
+                emitActivated(currentIndex);
+                return;
+            }
+        }
+        switch (insertPolicy) {
+        case QComboBox::InsertAtTop:
+            index = 0;
+            break;
+        case QComboBox::InsertAtBottom:
+            index = q->count();
+            break;
+        case QComboBox::InsertAtCurrent:
+        case QComboBox::InsertAfterCurrent:
+        case QComboBox::InsertBeforeCurrent:
+            if (!q->count() || !currentIndex.isValid())
+                index = 0;
+            else if (insertPolicy == QComboBox::InsertAtCurrent)
+                q->setItemText(q->currentIndex(), text);
+            else if (insertPolicy == QComboBox::InsertAfterCurrent)
+                index = q->currentIndex() + 1;
+            else if (insertPolicy == QComboBox::InsertBeforeCurrent)
+                index = q->currentIndex();
+            break;
+        case QComboBox::InsertAlphabetically:
+            index = 0;
+            for (int i=0; i< q->count(); i++, index++ ) {
+                if (text.toLower() < q->itemText(i).toLower())
+                    break;
+            }
+            break;
+        case QComboBox::NoInsert:
+        default:
+            break;
+        }
+        if (index >= 0) {
+            q->insertItem(index, text);
+            q->setCurrentIndex(index);
+            emitActivated(currentIndex);
+        }
+    }
+}
+
+void QComboBoxPrivate::_q_itemSelected(const QModelIndex &item)
+{
+    Q_Q(QComboBox);
+    if (item != currentIndex) {
+        setCurrentIndex(item);
+    } else if (lineEdit) {
+        lineEdit->selectAll();
+        lineEdit->setText(q->itemText(currentIndex.row()));
+    }
+    emitActivated(currentIndex);
+}
+
+void QComboBoxPrivate::emitActivated(const QModelIndex &index)
+{
+    Q_Q(QComboBox);
+    if (!index.isValid())
+        return;
+    QString text(itemText(index));
+    emit q->activated(index.row());
+    emit q->activated(text);
+}
+
+void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index)
+{
+    Q_Q(QComboBox);
+    if (!index.isValid())
+        return;
+    QString text(itemText(index));
+    emit q->highlighted(index.row());
+    emit q->highlighted(text);
+}
+
+void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
+{
+    Q_Q(QComboBox);
+    emit q->currentIndexChanged(index.row());
+    emit q->currentIndexChanged(itemText(index));
+}
+
+QString QComboBoxPrivate::itemText(const QModelIndex &index) const
+{
+    return index.isValid() ? model->data(index, itemRole()).toString() : QString();
+}
+
+int QComboBoxPrivate::itemRole() const
+{
+    return q_func()->isEditable() ? Qt::EditRole : Qt::DisplayRole;
+}
+
+/*!
+    Destroys the combobox.
+*/
+QComboBox::~QComboBox()
+{
+    // ### check delegateparent and delete delegate if us?
+    Q_D(QComboBox);
+
+    QT_TRY {
+        disconnect(d->model, SIGNAL(destroyed()),
+                this, SLOT(_q_modelDestroyed()));
+    } QT_CATCH(...) {
+        ; // objects can't throw in destructor
+    }
+}
+
+/*!
+    \property QComboBox::maxVisibleItems
+    \brief the maximum allowed size on screen of the combo box, measured in items
+
+    By default, this property has a value of 10.
+
+    \note This property is ignored for non-editable comboboxes in Mac style.
+*/
+int QComboBox::maxVisibleItems() const
+{
+    Q_D(const QComboBox);
+    return d->maxVisibleItems;
+}
+
+void QComboBox::setMaxVisibleItems(int maxItems)
+{
+    Q_D(QComboBox);
+    if (maxItems < 0) {
+        qWarning("QComboBox::setMaxVisibleItems: "
+                 "Invalid max visible items (%d) must be >= 0", maxItems);
+        return;
+    }
+    d->maxVisibleItems = maxItems;
+}
+
+/*!
+    \property QComboBox::count
+    \brief the number of items in the combobox
+
+    By default, for an empty combo box, this property has a value of 0.
+*/
+int QComboBox::count() const
+{
+    Q_D(const QComboBox);
+    return d->model->rowCount(d->root);
+}
+
+/*!
+    \property QComboBox::maxCount
+    \brief the maximum number of items allowed in the combobox
+
+    \note If you set the maximum number to be less then the current
+    amount of items in the combobox, the extra items will be
+    truncated. This also applies if you have set an external model on
+    the combobox.
+
+    By default, this property's value is derived from the highest
+    signed integer available (typically 2147483647).
+*/
+void QComboBox::setMaxCount(int max)
+{
+    Q_D(QComboBox);
+    if (max < 0) {
+        qWarning("QComboBox::setMaxCount: Invalid count (%d) must be >= 0", max);
+        return;
+    }
+
+    if (max < count())
+        d->model->removeRows(max, count() - max, d->root);
+
+    d->maxCount = max;
+}
+
+int QComboBox::maxCount() const
+{
+    Q_D(const QComboBox);
+    return d->maxCount;
+}
+
+#ifndef QT_NO_COMPLETER
+
+/*!
+    \property QComboBox::autoCompletion
+    \brief whether the combobox provides auto-completion for editable items
+    \since 4.1
+    \obsolete
+
+    Use setCompleter() instead.
+
+    By default, this property is true.
+
+    \sa editable
+*/
+
+/*!
+    \obsolete
+
+    Use setCompleter() instead.
+*/
+bool QComboBox::autoCompletion() const
+{
+    Q_D(const QComboBox);
+    return d->autoCompletion;
+}
+
+/*!
+    \obsolete
+
+    Use setCompleter() instead.
+*/
+void QComboBox::setAutoCompletion(bool enable)
+{
+    Q_D(QComboBox);
+
+#ifdef QT_KEYPAD_NAVIGATION
+    if (QApplication::keypadNavigationEnabled() && !enable && isEditable())
+        qWarning("QComboBox::setAutoCompletion: auto completion is mandatory when combo box editable");
+#endif
+
+    d->autoCompletion = enable;
+    if (!d->lineEdit)
+        return;
+    if (enable) {
+        if (d->lineEdit->completer())
+            return;
+        d->completer = new QCompleter(d->model, d->lineEdit);
+        d->completer->setCaseSensitivity(d->autoCompletionCaseSensitivity);
+        d->completer->setCompletionMode(QCompleter::InlineCompletion);
+        d->completer->setCompletionColumn(d->modelColumn);
+        d->lineEdit->setCompleter(d->completer);
+        d->completer->setWidget(this);
+    } else {
+        d->lineEdit->setCompleter(0);
+    }
+}
+
+/*!
+    \property QComboBox::autoCompletionCaseSensitivity
+    \brief whether string comparisons are case-sensitive or case-insensitive for auto-completion
+    \obsolete
+
+    By default, this property is Qt::CaseInsensitive.
+
+    Use setCompleter() instead. Case sensitivity of the auto completion can be
+    changed using QCompleter::setCaseSensitivity().
+
+    \sa autoCompletion
+*/
+
+/*!
+    \obsolete
+
+    Use setCompleter() and QCompleter::setCaseSensitivity() instead.
+*/
+Qt::CaseSensitivity QComboBox::autoCompletionCaseSensitivity() const
+{
+    Q_D(const QComboBox);
+    return d->autoCompletionCaseSensitivity;
+}
+
+/*!
+    \obsolete
+
+    Use setCompleter() and QCompleter::setCaseSensitivity() instead.
+*/
+void QComboBox::setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity)
+{
+    Q_D(QComboBox);
+    d->autoCompletionCaseSensitivity = sensitivity;
+    if (d->lineEdit && d->lineEdit->completer())
+        d->lineEdit->completer()->setCaseSensitivity(sensitivity);
+}
+
+#endif // QT_NO_COMPLETER
+
+/*!
+    \property QComboBox::duplicatesEnabled
+    \brief whether the user can enter duplicate items into the combobox
+
+    Note that it is always possible to programmatically insert duplicate items into the
+    combobox.
+
+    By default, this property is false (duplicates are not allowed).
+*/
+bool QComboBox::duplicatesEnabled() const
+{
+    Q_D(const QComboBox);
+    return d->duplicatesEnabled;
+}
+
+void QComboBox::setDuplicatesEnabled(bool enable)
+{
+    Q_D(QComboBox);
+    d->duplicatesEnabled = enable;
+}
+
+/*!  \fn int QComboBox::findText(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly|Qt::MatchCaseSensitive) const
+
+  Returns the index of the item containing the given \a text; otherwise
+  returns -1.
+
+  The \a flags specify how the items in the combobox are searched.
+*/
+
+/*!
+  Returns the index of the item containing the given \a data for the
+  given \a role; otherwise returns -1.
+
+  The \a flags specify how the items in the combobox are searched.
+*/
+int QComboBox::findData(const QVariant &data, int role, Qt::MatchFlags flags) const
+{
+    Q_D(const QComboBox);
+    QModelIndexList result;
+    QModelIndex start = d->model->index(0, d->modelColumn, d->root);
+    result = d->model->match(start, role, data, 1, flags);
+    if (result.isEmpty())
+        return -1;
+    return result.first().row();
+}
+
+/*!
+    \property QComboBox::insertPolicy
+    \brief the policy used to determine where user-inserted items should
+    appear in the combobox
+
+    The default value is \l AtBottom, indicating that new items will appear
+    at the bottom of the list of items.
+
+    \sa InsertPolicy
+*/
+
+QComboBox::InsertPolicy QComboBox::insertPolicy() const
+{
+    Q_D(const QComboBox);
+    return d->insertPolicy;
+}
+
+void QComboBox::setInsertPolicy(InsertPolicy policy)
+{
+    Q_D(QComboBox);
+    d->insertPolicy = policy;
+}
+
+/*!
+    \property QComboBox::sizeAdjustPolicy
+    \brief the policy describing how the size of the combobox changes
+    when the content changes
+
+    The default value is \l AdjustToContentsOnFirstShow.
+
+    \sa SizeAdjustPolicy
+*/
+
+QComboBox::SizeAdjustPolicy QComboBox::sizeAdjustPolicy() const
+{
+    Q_D(const QComboBox);
+    return d->sizeAdjustPolicy;
+}
+
+void QComboBox::setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy policy)
+{
+    Q_D(QComboBox);
+    if (policy == d->sizeAdjustPolicy)
+        return;
+
+    d->sizeAdjustPolicy = policy;
+    d->sizeHint = QSize();
+    d->adjustComboBoxSize();
+    updateGeometry();
+}
+
+/*!
+    \property QComboBox::minimumContentsLength
+    \brief the minimum number of characters that should fit into the combobox.
+
+    The default value is 0.
+
+    If this property is set to a positive value, the
+    minimumSizeHint() and sizeHint() take it into account.
+
+    \sa sizeAdjustPolicy
+*/
+int QComboBox::minimumContentsLength() const
+{
+    Q_D(const QComboBox);
+    return d->minimumContentsLength;
+}
+
+void QComboBox::setMinimumContentsLength(int characters)
+{
+    Q_D(QComboBox);
+    if (characters == d->minimumContentsLength || characters < 0)
+        return;
+
+    d->minimumContentsLength = characters;
+
+    if (d->sizeAdjustPolicy == AdjustToContents
+            || d->sizeAdjustPolicy == AdjustToMinimumContentsLength
+            || d->sizeAdjustPolicy == AdjustToMinimumContentsLengthWithIcon) {
+        d->sizeHint = QSize();
+        d->adjustComboBoxSize();
+        updateGeometry();
+    }
+}
+
+/*!
+    \property QComboBox::iconSize
+    \brief the size of the icons shown in the combobox.
+
+    Unless explicitly set this returns the default value of the
+    current style.  This size is the maximum size that icons can have;
+    icons of smaller size are not scaled up.
+*/
+
+QSize QComboBox::iconSize() const
+{
+    Q_D(const QComboBox);
+    if (d->iconSize.isValid())
+        return d->iconSize;
+
+    int iconWidth = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
+    return QSize(iconWidth, iconWidth);
+}
+
+void QComboBox::setIconSize(const QSize &size)
+{
+    Q_D(QComboBox);
+    if (size == d->iconSize)
+        return;
+
+    view()->setIconSize(size);
+    d->iconSize = size;
+    d->sizeHint = QSize();
+    updateGeometry();
+}
+
+/*!
+    \property QComboBox::editable
+    \brief whether the combo box can be edited by the user
+
+    By default, this property is false.
+*/
+bool QComboBox::isEditable() const
+{
+    Q_D(const QComboBox);
+    return d->lineEdit != 0;
+}
+
+/*! \internal
+    update the default delegate
+    depending on the style's SH_ComboBox_Popup hint, we use a different default delegate.
+
+    but we do not change the delegate is the combobox use a custom delegate,
+    unless \a force is set to true.
+ */
+void QComboBoxPrivate::updateDelegate(bool force)
+{
+    Q_Q(QComboBox);
+    QStyleOptionComboBox opt;
+    q->initStyleOption(&opt);
+    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
+        if (force || qobject_cast<QComboBoxDelegate *>(q->itemDelegate()))
+            q->setItemDelegate(new QComboMenuDelegate(q->view(), q));
+    } else {
+        if (force || qobject_cast<QComboMenuDelegate *>(q->itemDelegate()))
+            q->setItemDelegate(new QComboBoxDelegate(q->view(), q));
+    }
+}
+
+QIcon QComboBoxPrivate::itemIcon(const QModelIndex &index) const
+{
+    QVariant decoration = model->data(index, Qt::DecorationRole);
+    if (decoration.type() == QVariant::Pixmap)
+        return QIcon(qvariant_cast<QPixmap>(decoration));
+    else
+        return qvariant_cast<QIcon>(decoration);
+}
+
+void QComboBox::setEditable(bool editable)
+{
+    Q_D(QComboBox);
+    if (isEditable() == editable)
+        return;
+
+    d->updateDelegate();
+
+    QStyleOptionComboBox opt;
+    initStyleOption(&opt);
+    if (editable) {
+        if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
+            d->viewContainer()->updateScrollers();
+            view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+        }
+        QLineEdit *le = new QLineEdit(this);
+        setLineEdit(le);
+    } else {
+        if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
+            d->viewContainer()->updateScrollers();
+            view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+        }
+        setAttribute(Qt::WA_InputMethodEnabled, false);
+        d->lineEdit->hide();
+        d->lineEdit->deleteLater();
+        d->lineEdit = 0;
+    }
+
+    d->viewContainer()->updateTopBottomMargin();
+    if (!testAttribute(Qt::WA_Resized))
+        adjustSize();
+}
+
+/*!
+    Sets the line \a edit to use instead of the current line edit widget.
+
+    The combo box takes ownership of the line edit.
+*/
+void QComboBox::setLineEdit(QLineEdit *edit)
+{
+    Q_D(QComboBox);
+    if (!edit) {
+        qWarning("QComboBox::setLineEdit: cannot set a 0 line edit");
+        return;
+    }
+
+    if (edit == d->lineEdit)
+        return;
+
+    edit->setText(currentText());
+    delete d->lineEdit;
+
+    d->lineEdit = edit;
+    if (d->lineEdit->parent() != this)
+        d->lineEdit->setParent(this);
+    connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
+    connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
+#ifdef QT3_SUPPORT
+    connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
+#endif
+    d->lineEdit->setFrame(false);
+    d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
+    d->lineEdit->setFocusProxy(this);
+    d->lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
+#ifndef QT_NO_COMPLETER
+    setAutoCompletion(d->autoCompletion);
+#endif
+
+#ifdef QT_KEYPAD_NAVIGATION
+#ifndef QT_NO_COMPLETER
+    if (QApplication::keypadNavigationEnabled()) {
+        // Editable combo boxes will have a completer that is set to UnfilteredPopupCompletion.
+        // This means that when the user enters edit mode they are immediately presented with a
+        // list of possible completions.
+        setAutoCompletion(true);
+        if (d->completer) {
+            d->completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+            connect(d->completer, SIGNAL(activated(QModelIndex)), this, SLOT(_q_completerActivated()));
+        }
+    }
+#endif
+#endif
+
+    setAttribute(Qt::WA_InputMethodEnabled);
+    d->updateLayoutDirection();
+    d->updateLineEditGeometry();
+    if (isVisible())
+        d->lineEdit->show();
+
+    update();
+}
+
+/*!
+    Returns the line edit used to edit items in the combobox, or 0 if there
+    is no line edit.
+
+    Only editable combo boxes have a line edit.
+*/
+QLineEdit *QComboBox::lineEdit() const
+{
+    Q_D(const QComboBox);
+    return d->lineEdit;
+}
+
+#ifndef QT_NO_VALIDATOR
+/*!
+    \fn void QComboBox::setValidator(const QValidator *validator)
+
+    Sets the \a validator to use instead of the current validator.
+*/
+
+void QComboBox::setValidator(const QValidator *v)
+{
+    Q_D(QComboBox);
+    if (d->lineEdit)
+        d->lineEdit->setValidator(v);
+}
+
+/*!
+    Returns the validator that is used to constrain text input for the
+    combobox.
+
+    \sa editable
+*/
+const QValidator *QComboBox::validator() const
+{
+    Q_D(const QComboBox);
+    return d->lineEdit ? d->lineEdit->validator() : 0;
+}
+#endif // QT_NO_VALIDATOR
+
+#ifndef QT_NO_COMPLETER
+
+/*!
+    \fn void QComboBox::setCompleter(QCompleter *completer)
+    \since 4.2
+
+    Sets the \a completer to use instead of the current completer.
+    If \a completer is 0, auto completion is disabled.
+
+    By default, for an editable combo box, a QCompleter that
+    performs case insensitive inline completion is automatically created.
+*/
+void QComboBox::setCompleter(QCompleter *c)
+{
+    Q_D(QComboBox);
+    if (!d->lineEdit)
+        return;
+    d->lineEdit->setCompleter(c);
+    if (c)
+        c->setWidget(this);
+}
+
+/*!
+    \since 4.2
+
+    Returns the completer that is used to auto complete text input for the
+    combobox.
+
+    \sa editable
+*/
+QCompleter *QComboBox::completer() const
+{
+    Q_D(const QComboBox);
+    return d->lineEdit ? d->lineEdit->completer() : 0;
+}
+
+#endif // QT_NO_COMPLETER
+
+/*!
+    Returns the item delegate used by the popup list view.
+
+    \sa setItemDelegate()
+*/
+QAbstractItemDelegate *QComboBox::itemDelegate() const
+{
+    return view()->itemDelegate();
+}
+
+/*!
+    Sets the item \a delegate for the popup list view.
+    The combobox takes ownership of the delegate.
+
+    \warning You should not share the same instance of a delegate between comboboxes,
+    widget mappers or views. Doing so can cause incorrect or unintuitive editing behavior
+    since each view connected to a given delegate may receive the
+    \l{QAbstractItemDelegate::}{closeEditor()} signal, and attempt to access, modify or
+    close an editor that has already been closed.
+
+    \sa itemDelegate()
+*/
+void QComboBox::setItemDelegate(QAbstractItemDelegate *delegate)
+{
+    if (!delegate) {
+        qWarning("QComboBox::setItemDelegate: cannot set a 0 delegate");
+        return;
+    }
+    delete view()->itemDelegate();
+    view()->setItemDelegate(delegate);
+}
+
+/*!
+    Returns the model used by the combobox.
+*/
+
+QAbstractItemModel *QComboBox::model() const
+{
+    Q_D(const QComboBox);
+    if (d->model == QAbstractItemModelPrivate::staticEmptyModel()) {
+        QComboBox *that = const_cast<QComboBox*>(this);
+        that->setModel(new QStandardItemModel(0, 1, that));
+    }
+    return d->model;
+}
+
+/*!
+    Sets the model to be \a model. \a model must not be 0.
+    If you want to clear the contents of a model, call clear().
+
+    \sa clear()
+*/
+void QComboBox::setModel(QAbstractItemModel *model)
+{
+    Q_D(QComboBox);
+
+    if (!model) {
+        qWarning("QComboBox::setModel: cannot set a 0 model");
+        return;
+    }
+
+#ifndef QT_NO_COMPLETER
+    if (d->lineEdit && d->lineEdit->completer()
+        && d->lineEdit->completer() == d->completer)
+        d->lineEdit->completer()->setModel(model);
+#endif
+    if (d->model) {
+        disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                   this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+        disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
+                   this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+        disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                   this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+        disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+                   this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                   this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+        disconnect(d->model, SIGNAL(destroyed()),
+                   this, SLOT(_q_modelDestroyed()));
+        disconnect(d->model, SIGNAL(modelReset()),
+                   this, SLOT(_q_modelReset()));
+        if (d->model->QObject::parent() == this)
+            delete d->model;
+    }
+
+    d->model = model;
+
+    connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+    connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
+            this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+    connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+    connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+            this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+    connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+    connect(model, SIGNAL(destroyed()),
+            this, SLOT(_q_modelDestroyed()));
+    connect(model, SIGNAL(modelReset()),
+            this, SLOT(_q_modelReset()));
+
+    if (d->container)
+        d->container->itemView()->setModel(model);
+
+    bool currentReset = false;
+
+    if (count()) {
+        for (int pos=0; pos < count(); pos++) {
+            if (d->model->index(pos, d->modelColumn, d->root).flags() & Qt::ItemIsEnabled) {
+                setCurrentIndex(pos);
+                currentReset = true;
+                break;
+            }
+        }
+    }
+
+    if (!currentReset)
+        setCurrentIndex(-1);
+
+    d->modelChanged();
+}
+
+/*!
+    Returns the root model item index for the items in the combobox.
+
+    \sa setRootModelIndex()
+*/
+
+QModelIndex QComboBox::rootModelIndex() const
+{
+    Q_D(const QComboBox);
+    return QModelIndex(d->root);
+}
+
+/*!
+    Sets the root model item \a index for the items in the combobox.
+
+    \sa rootModelIndex()
+*/
+void QComboBox::setRootModelIndex(const QModelIndex &index)
+{
+    Q_D(QComboBox);
+    d->root = QPersistentModelIndex(index);
+    view()->setRootIndex(index);
+    update();
+}
+
+/*!
+    \property QComboBox::currentIndex
+    \brief the index of the current item in the combobox.
+
+    The current index can change when inserting or removing items.
+
+    By default, for an empty combo box or a combo box in which no current
+    item is set, this property has a value of -1.
+*/
+int QComboBox::currentIndex() const
+{
+    Q_D(const QComboBox);
+    return d->currentIndex.row();
+}
+
+void QComboBox::setCurrentIndex(int index)
+{
+    Q_D(QComboBox);
+    QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
+    d->setCurrentIndex(mi);
+}
+
+void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
+{
+    Q_Q(QComboBox);
+    bool indexChanged = (mi != currentIndex);
+    if (indexChanged)
+        currentIndex = QPersistentModelIndex(mi);
+    if (lineEdit) {
+        QString newText = q->itemText(currentIndex.row());
+        if (lineEdit->text() != newText)
+            lineEdit->setText(q->itemText(currentIndex.row()));
+        updateLineEditGeometry();
+    }
+    if (indexChanged) {
+        q->update();
+        _q_emitCurrentIndexChanged(currentIndex);
+    }
+}
+
+/*!
+    \property QComboBox::currentText
+    \brief the text of the current item
+
+    By default, for an empty combo box or a combo box in which no current
+    item is set, this property contains an empty string.
+*/
+QString QComboBox::currentText() const
+{
+    Q_D(const QComboBox);
+    if (d->lineEdit)
+        return d->lineEdit->text();
+    else if (d->currentIndex.isValid())
+        return d->itemText(d->currentIndex);
+    else
+        return QString();
+}
+
+/*!
+    Returns the text for the given \a index in the combobox.
+*/
+QString QComboBox::itemText(int index) const
+{
+    Q_D(const QComboBox);
+    QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
+    return d->itemText(mi);
+}
+
+/*!
+    Returns the icon for the given \a index in the combobox.
+*/
+QIcon QComboBox::itemIcon(int index) const
+{
+    Q_D(const QComboBox);
+    QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
+    return d->itemIcon(mi);
+}
+
+/*!
+   Returns the data for the given \a role in the given \a index in the
+   combobox, or QVariant::Invalid if there is no data for this role.
+*/
+QVariant QComboBox::itemData(int index, int role) const
+{
+    Q_D(const QComboBox);
+    QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
+    return d->model->data(mi, role);
+}
+
+/*!
+  \fn void QComboBox::insertItem(int index, const QString &text, const QVariant &userData)
+
+    Inserts the \a text and \a userData (stored in the Qt::UserRole)
+    into the combobox at the given \a index.
+
+    If the index is equal to or higher than the total number of items,
+    the new item is appended to the list of existing items. If the
+    index is zero or negative, the new item is prepended to the list
+    of existing items.
+
+  \sa insertItems()
+*/
+
+/*!
+
+    Inserts the \a icon, \a text and \a userData (stored in the
+    Qt::UserRole) into the combobox at the given \a index.
+
+    If the index is equal to or higher than the total number of items,
+    the new item is appended to the list of existing items. If the
+    index is zero or negative, the new item is prepended to the list
+    of existing items.
+
+    \sa insertItems()
+*/
+void QComboBox::insertItem(int index, const QIcon &icon, const QString &text, const QVariant &userData)
+{
+    Q_D(QComboBox);
+    int itemCount = count();
+    index = qBound(0, index, itemCount);
+    if (index >= d->maxCount)
+        return;
+
+    // For the common case where we are using the built in QStandardItemModel
+    // construct a QStandardItem, reducing the number of expensive signals from the model
+    if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(d->model)) {
+        QStandardItem *item = new QStandardItem(text);
+        if (!icon.isNull()) item->setData(icon, Qt::DecorationRole);
+        if (userData.isValid()) item->setData(userData, Qt::UserRole);
+        m->insertRow(index, item);
+        ++itemCount;
+    } else {
+        d->inserting = true;
+        if (d->model->insertRows(index, 1, d->root)) {
+            QModelIndex item = d->model->index(index, d->modelColumn, d->root);
+            if (icon.isNull() && !userData.isValid()) {
+                d->model->setData(item, text, Qt::EditRole);
+            } else {
+                QMap<int, QVariant> values;
+                if (!text.isNull()) values.insert(Qt::EditRole, text);
+                if (!icon.isNull()) values.insert(Qt::DecorationRole, icon);
+                if (userData.isValid()) values.insert(Qt::UserRole, userData);
+                if (!values.isEmpty()) d->model->setItemData(item, values);
+            }
+            d->inserting = false;
+            d->_q_rowsInserted(d->root, index, index);
+            ++itemCount;
+        } else {
+            d->inserting = false;
+        }
+    }
+
+    if (itemCount > d->maxCount)
+        d->model->removeRows(itemCount - 1, itemCount - d->maxCount, d->root);
+}
+
+/*!
+    Inserts the strings from the \a list into the combobox as separate items,
+    starting at the \a index specified.
+
+    If the index is equal to or higher than the total number of items, the new items
+    are appended to the list of existing items. If the index is zero or negative, the
+    new items are prepended to the list of existing items.
+
+    \sa insertItem()
+    */
+void QComboBox::insertItems(int index, const QStringList &list)
+{
+    Q_D(QComboBox);
+    if (list.isEmpty())
+        return;
+    index = qBound(0, index, count());
+    int insertCount = qMin(d->maxCount - index, list.count());
+    if (insertCount <= 0)
+        return;
+    // For the common case where we are using the built in QStandardItemModel
+    // construct a QStandardItem, reducing the number of expensive signals from the model
+    if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(d->model)) {
+        QList<QStandardItem *> items;
+        QStandardItem *hiddenRoot = m->invisibleRootItem();
+        for (int i = 0; i < insertCount; ++i)
+            items.append(new QStandardItem(list.at(i)));
+        hiddenRoot->insertRows(index, items);
+    } else {
+        d->inserting = true;
+        if (d->model->insertRows(index, insertCount, d->root)) {
+            QModelIndex item;
+            for (int i = 0; i < insertCount; ++i) {
+                item = d->model->index(i+index, d->modelColumn, d->root);
+                d->model->setData(item, list.at(i), Qt::EditRole);
+            }
+            d->inserting = false;
+            d->_q_rowsInserted(d->root, index, index + insertCount - 1);
+        } else {
+            d->inserting = false;
+        }
+    }
+
+    int mc = count();
+    if (mc > d->maxCount)
+        d->model->removeRows(d->maxCount, mc - d->maxCount, d->root);
+}
+
+/*!
+    \since 4.4
+
+    Inserts a separator item into the combobox at the given \a index.
+
+    If the index is equal to or higher than the total number of items, the new item
+    is appended to the list of existing items. If the index is zero or negative, the
+    new item is prepended to the list of existing items.
+
+    \sa insertItem()
+*/
+void QComboBox::insertSeparator(int index)
+{
+    Q_D(QComboBox);
+    int itemCount = count();
+    index = qBound(0, index, itemCount);
+    if (index >= d->maxCount)
+        return;
+    insertItem(index, QIcon(), QString());
+    QComboBoxDelegate::setSeparator(d->model, d->model->index(index, 0, d->root));
+}
+
+/*!
+    Removes the item at the given \a index from the combobox.
+    This will update the current index if the index is removed.
+
+    This function does nothing if \a index is out of range.
+*/
+void QComboBox::removeItem(int index)
+{
+    Q_D(QComboBox);
+    if (index < 0 || index >= count())
+        return;
+    d->model->removeRows(index, 1, d->root);
+}
+
+/*!
+    Sets the \a text for the item on the given \a index in the combobox.
+*/
+void QComboBox::setItemText(int index, const QString &text)
+{
+    Q_D(const QComboBox);
+    QModelIndex item = d->model->index(index, d->modelColumn, d->root);
+    if (item.isValid()) {
+        d->model->setData(item, text, Qt::EditRole);
+    }
+}
+
+/*!
+    Sets the \a icon for the item on the given \a index in the combobox.
+*/
+void QComboBox::setItemIcon(int index, const QIcon &icon)
+{
+    Q_D(const QComboBox);
+    QModelIndex item = d->model->index(index, d->modelColumn, d->root);
+    if (item.isValid()) {
+        d->model->setData(item, icon, Qt::DecorationRole);
+    }
+}
+
+/*!
+    Sets the data \a role for the item on the given \a index in the combobox
+    to the specified \a value.
+*/
+void QComboBox::setItemData(int index, const QVariant &value, int role)
+{
+    Q_D(const QComboBox);
+    QModelIndex item = d->model->index(index, d->modelColumn, d->root);
+    if (item.isValid()) {
+        d->model->setData(item, value, role);
+    }
+}
+
+/*!
+    Returns the list view used for the combobox popup.
+*/
+QAbstractItemView *QComboBox::view() const
+{
+    Q_D(const QComboBox);
+    return const_cast<QComboBoxPrivate*>(d)->viewContainer()->itemView();
+}
+
+/*!
+  Sets the view to be used in the combobox popup to the given \a
+  itemView. The combobox takes ownership of the view.
+
+  Note: If you want to use the convenience views (like QListWidget,
+  QTableWidget or QTreeWidget), make sure to call setModel() on the
+  combobox with the convenience widgets model before calling this
+  function.
+*/
+void QComboBox::setView(QAbstractItemView *itemView)
+{
+    Q_D(QComboBox);
+    if (!itemView) {
+        qWarning("QComboBox::setView: cannot set a 0 view");
+        return;
+    }
+
+    if (itemView->model() != d->model)
+        itemView->setModel(d->model);
+    d->viewContainer()->setItemView(itemView);
+}
+
+/*!
+    \reimp
+*/
+QSize QComboBox::minimumSizeHint() const
+{
+    Q_D(const QComboBox);
+    return d->recomputeSizeHint(d->minimumSizeHint);
+}
+
+/*!
+    \reimp
+
+    This implementation caches the size hint to avoid resizing when
+    the contents change dynamically. To invalidate the cached value
+    change the \l sizeAdjustPolicy.
+*/
+QSize QComboBox::sizeHint() const
+{
+    Q_D(const QComboBox);
+    return d->recomputeSizeHint(d->sizeHint);
+}
+
+/*!
+    Displays the list of items in the combobox. If the list is empty
+    then the no items will be shown.
+
+    If you reimplement this function to show a custom pop-up, make
+    sure you call hidePopup() to reset the internal state.
+
+    \sa hidePopup()
+*/
+void QComboBox::showPopup()
+{
+    Q_D(QComboBox);
+    if (count() <= 0)
+        return;
+
+#ifdef QT_KEYPAD_NAVIGATION
+#ifndef QT_NO_COMPLETER
+    if (QApplication::keypadNavigationEnabled() && d->completer) {
+        // editable combo box is line edit plus completer
+        setEditFocus(true);
+        d->completer->complete(); // show popup
+        return;
+    }
+#endif
+#endif
+
+    QStyle * const style = this->style();
+
+    // set current item and select it
+    view()->selectionModel()->setCurrentIndex(d->currentIndex,
+                                              QItemSelectionModel::ClearAndSelect);
+    QComboBoxPrivateContainer* container = d->viewContainer();
+    QStyleOptionComboBox opt;
+    initStyleOption(&opt);
+    QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
+                                         QStyle::SC_ComboBoxListBoxPopup, this));
+    QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
+    QPoint below = mapToGlobal(listRect.bottomLeft());
+    int belowHeight = screen.bottom() - below.y();
+    QPoint above = mapToGlobal(listRect.topLeft());
+    int aboveHeight = above.y() - screen.y();
+    bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen);
+
+    const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
+    {
+        int listHeight = 0;
+        int count = 0;
+        QStack<QModelIndex> toCheck;
+        toCheck.push(view()->rootIndex());
+#ifndef QT_NO_TREEVIEW
+        QTreeView *treeView = qobject_cast<QTreeView*>(view());
+        if (treeView && treeView->header() && !treeView->header()->isHidden())
+            listHeight += treeView->header()->height();
+#endif
+        while (!toCheck.isEmpty()) {
+            QModelIndex parent = toCheck.pop();
+            for (int i = 0; i < d->model->rowCount(parent); ++i) {
+                QModelIndex idx = d->model->index(i, d->modelColumn, parent);
+                if (!idx.isValid())
+                    continue;
+                listHeight += view()->visualRect(idx).height() + container->spacing();
+#ifndef QT_NO_TREEVIEW
+                if (d->model->hasChildren(idx) && treeView && treeView->isExpanded(idx))
+                    toCheck.push(idx);
+#endif
+                ++count;
+                if (!usePopup && count > d->maxVisibleItems) {
+                    toCheck.clear();
+                    break;
+                }
+            }
+        }
+        listRect.setHeight(listHeight);
+    }
+
+    {
+        // add the spacing for the grid on the top and the bottom;
+        int heightMargin = 2*container->spacing();
+
+        // add the frame of the container
+        int marginTop, marginBottom;
+        container->getContentsMargins(0, &marginTop, 0, &marginBottom);
+        heightMargin += marginTop + marginBottom;
+
+        //add the frame of the view
+        view()->getContentsMargins(0, &marginTop, 0, &marginBottom);
+        marginTop += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->top;
+        marginBottom += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->bottom;
+        heightMargin += marginTop + marginBottom;
+
+        listRect.setHeight(listRect.height() + heightMargin);
+    }
+
+    // Add space for margin at top and bottom if the style wants it.
+    if (usePopup)
+        listRect.setHeight(listRect.height() + style->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) * 2);
+
+    // Make sure the popup is wide enough to display its contents.
+    if (usePopup) {
+        const int diff = d->computeWidthHint() - width();
+        if (diff > 0)
+            listRect.setWidth(listRect.width() + diff);
+    }
+
+    //we need to activate the layout to make sure the min/maximum size are set when the widget was not yet show
+    container->layout()->activate();
+    //takes account of the minimum/maximum size of the container
+    listRect.setSize( listRect.size().expandedTo(container->minimumSize())
+                      .boundedTo(container->maximumSize()));
+
+    // make sure the widget fits on screen
+    if (boundToScreen) {
+        if (listRect.width() > screen.width() )
+            listRect.setWidth(screen.width());
+        if (mapToGlobal(listRect.bottomRight()).x() > screen.right()) {
+            below.setX(screen.x() + screen.width() - listRect.width());
+            above.setX(screen.x() + screen.width() - listRect.width());
+        }
+        if (mapToGlobal(listRect.topLeft()).x() < screen.x() ) {
+            below.setX(screen.x());
+            above.setX(screen.x());
+        }
+    }
+
+    if (usePopup) {
+        // Position horizontally.
+        listRect.moveLeft(above.x());
+
+        // Position vertically so the curently selected item lines up
+        // with the combo box.
+        const QRect currentItemRect = view()->visualRect(view()->currentIndex());
+        const int offset = listRect.top() - currentItemRect.top();
+        listRect.moveTop(above.y() + offset - listRect.top());
+
+
+        // Clamp the listRect height and vertical position so we don't expand outside the
+        // available screen geometry.This may override the vertical position, but it is more
+        // important to show as much as possible of the popup.
+        const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height());
+        listRect.setHeight(height);
+        if (boundToScreen) {
+            if (listRect.top() < screen.top())
+                listRect.moveTop(screen.top());
+            if (listRect.bottom() > screen.bottom())
+                listRect.moveBottom(screen.bottom());
+        }
+    } else if (!boundToScreen || listRect.height() <= belowHeight) {
+        listRect.moveTopLeft(below);
+    } else if (listRect.height() <= aboveHeight) {
+        listRect.moveBottomLeft(above);
+    } else if (belowHeight >= aboveHeight) {
+        listRect.setHeight(belowHeight);
+        listRect.moveTopLeft(below);
+    } else {
+        listRect.setHeight(aboveHeight);
+        listRect.moveBottomLeft(above);
+    }
+
+#ifndef QT_NO_IM
+    if (QInputContext *qic = inputContext())
+        qic->reset();
+#endif
+    QScrollBar *sb = view()->horizontalScrollBar();
+    Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy();
+    bool needHorizontalScrollBar = (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn)
+                                   && sb->minimum() < sb->maximum();
+    if (needHorizontalScrollBar) {
+        listRect.adjust(0, 0, 0, sb->height());
+    }
+    container->setGeometry(listRect);
+
+#ifndef Q_WS_MAC
+    const bool updatesEnabled = container->updatesEnabled();
+#endif
+
+#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
+    bool scrollDown = (listRect.topLeft() == below);
+    if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) 
+        && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen))
+        qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150);
+#endif
+
+// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform,
+// which means that the window will be visible before the call to container->show() returns.
+// If updates are disabled at this point we'll miss our chance at painting the popup 
+// menu before it's shown, causing flicker since the window then displays the standard gray 
+// background.
+#ifndef Q_WS_MAC
+    container->setUpdatesEnabled(false);
+#endif
+
+    container->raise();
+    container->show();
+    container->updateScrollers();
+    view()->setFocus();
+
+    view()->scrollTo(view()->currentIndex(),
+                     style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)
+                             ? QAbstractItemView::PositionAtCenter
+                             : QAbstractItemView::EnsureVisible);
+
+#ifndef Q_WS_MAC
+    container->setUpdatesEnabled(updatesEnabled);
+#endif
+
+    container->update();
+#ifdef QT_KEYPAD_NAVIGATION
+    if (QApplication::keypadNavigationEnabled())
+        view()->setEditFocus(true);
+#endif
+}
+
+/*!
+    Hides the list of items in the combobox if it is currently visible
+    and resets the internal state, so that if the custom pop-up was
+    shown inside the reimplemented showPopup(), then you also need to
+    reimplement the hidePopup() function to hide your custom pop-up
+    and call the base class implementation to reset the internal state
+    whenever your custom pop-up widget is hidden.
+
+    \sa showPopup()
+*/
+void QComboBox::hidePopup()
+{
+    Q_D(QComboBox);
+    if (d->container && d->container->isVisible()) {
+#if !defined(QT_NO_EFFECTS)
+        d->model->blockSignals(true);
+        d->container->itemView()->blockSignals(true);
+        d->container->blockSignals(true);
+        // Flash selected/triggered item (if any).
+        if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) {
+            QItemSelectionModel *selectionModel = view() ? view()->selectionModel() : 0;
+            if (selectionModel && selectionModel->hasSelection()) {
+                QEventLoop eventLoop;
+                const QItemSelection selection = selectionModel->selection();
+
+                // Deselect item and wait 60 ms.
+                selectionModel->select(selection, QItemSelectionModel::Toggle);
+                QTimer::singleShot(60, &eventLoop, SLOT(quit()));
+                eventLoop.exec();
+
+                // Select item and wait 20 ms.
+                selectionModel->select(selection, QItemSelectionModel::Toggle);
+                QTimer::singleShot(20, &eventLoop, SLOT(quit()));
+                eventLoop.exec();
+            }
+        }
+
+        // Fade out.
+        bool needFade = style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
+        if (needFade) {
+#if defined(Q_WS_MAC)
+            macWindowFade(qt_mac_window_for(d->container));
+#endif // Q_WS_MAC
+            // Other platform implementations welcome :-)
+        }
+        d->model->blockSignals(false);
+        d->container->itemView()->blockSignals(false);
+        d->container->blockSignals(false);
+
+        if (!needFade)
+#endif // QT_NO_EFFECTS
+            // Fade should implicitly hide as well ;-)
+            d->container->hide();
+    }
+#ifdef QT_KEYPAD_NAVIGATION
+    if (QApplication::keypadNavigationEnabled() && isEditable() && hasFocus())
+        setEditFocus(true);
+#endif
+    d->_q_resetButton();
+}
+
+/*!
+    Clears the combobox, removing all items.
+
+    Note: If you have set an external model on the combobox this model
+    will still be cleared when calling this function.
+*/
+void QComboBox::clear()
+{
+    Q_D(QComboBox);
+    d->model->removeRows(0, d->model->rowCount(d->root), d->root);
+}
+
+/*!
+    \fn void QComboBox::clearValidator()
+
+    Use setValidator(0) instead.
+*/
+
+/*!
+    Clears the contents of the line edit used for editing in the combobox.
+*/
+void QComboBox::clearEditText()
+{
+    Q_D(QComboBox);
+    if (d->lineEdit)
+        d->lineEdit->clear();
+}
+
+/*!
+    Sets the \a text in the combobox's text edit.
+*/
+void QComboBox::setEditText(const QString &text)
+{
+    Q_D(QComboBox);
+    if (d->lineEdit)
+        d->lineEdit->setText(text);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::focusInEvent(QFocusEvent *e)
+{
+    Q_D(QComboBox);
+    update();
+    if (d->lineEdit) {
+        d->lineEdit->event(e);
+#ifndef QT_NO_COMPLETER
+        if (d->lineEdit->completer())
+            d->lineEdit->completer()->setWidget(this);
+#endif
+    }
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::focusOutEvent(QFocusEvent *e)
+{
+    Q_D(QComboBox);
+    update();
+    if (d->lineEdit)
+        d->lineEdit->event(e);
+}
+
+/*! \reimp */
+void QComboBox::changeEvent(QEvent *e)
+{
+    Q_D(QComboBox);
+    switch (e->type()) {
+    case QEvent::StyleChange:
+        d->updateDelegate();
+#ifdef Q_WS_MAC
+    case QEvent::MacSizeChange:
+#endif
+        d->sizeHint = QSize(); // invalidate size hint
+        d->minimumSizeHint = QSize();
+        d->updateLayoutDirection();
+        if (d->lineEdit)
+            d->updateLineEditGeometry();
+        d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
+        // ### need to update scrollers etc. as well here
+        break;
+    case QEvent::EnabledChange:
+        if (!isEnabled())
+            hidePopup();
+        break;
+    case QEvent::PaletteChange: {
+        d->updateViewContainerPaletteAndOpacity();
+        break;
+    }
+    case QEvent::FontChange:
+        d->sizeHint = QSize(); // invalidate size hint
+        d->viewContainer()->setFont(font());
+        if (d->lineEdit)
+            d->updateLineEditGeometry();
+        break;
+    default:
+        break;
+    }
+    QWidget::changeEvent(e);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::resizeEvent(QResizeEvent *)
+{
+    Q_D(QComboBox);
+    d->updateLineEditGeometry();
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::paintEvent(QPaintEvent *)
+{
+    QStylePainter painter(this);
+    painter.setPen(palette().color(QPalette::Text));
+
+    // draw the combobox frame, focusrect and selected etc.
+    QStyleOptionComboBox opt;
+    initStyleOption(&opt);
+    painter.drawComplexControl(QStyle::CC_ComboBox, opt);
+
+    // draw the icon and text
+    painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::showEvent(QShowEvent *e)
+{
+    Q_D(QComboBox);
+    if (!d->shownOnce && d->sizeAdjustPolicy == QComboBox::AdjustToContentsOnFirstShow) {
+        d->sizeHint = QSize();
+        updateGeometry();
+    }
+    d->shownOnce = true;
+    QWidget::showEvent(e);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::hideEvent(QHideEvent *)
+{
+    hidePopup();
+}
+
+/*!
+    \reimp
+*/
+bool QComboBox::event(QEvent *event)
+{
+    Q_D(QComboBox);
+    switch(event->type()) {
+    case QEvent::LayoutDirectionChange:
+    case QEvent::ApplicationLayoutDirectionChange:
+        d->updateLayoutDirection();
+        d->updateLineEditGeometry();
+        break;
+    case QEvent::HoverEnter:
+    case QEvent::HoverLeave:
+    case QEvent::HoverMove:
+    if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
+        d->updateHoverControl(he->pos());
+        break;
+    case QEvent::ShortcutOverride:
+        if (d->lineEdit)
+            return d->lineEdit->event(event);
+        break;
+#ifdef QT_KEYPAD_NAVIGATION
+    case QEvent::EnterEditFocus:
+        if (!d->lineEdit)
+            setEditFocus(false); // We never want edit focus if we are not editable
+        else
+            d->lineEdit->event(event);  //so cursor starts
+        break;
+    case QEvent::LeaveEditFocus:
+        if (d->lineEdit)
+            d->lineEdit->event(event);  //so cursor stops
+        break;
+#endif
+    default:
+        break;
+    }
+    return QWidget::event(event);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::mousePressEvent(QMouseEvent *e)
+{
+    Q_D(QComboBox);
+    QStyleOptionComboBox opt;
+    initStyleOption(&opt);
+    QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(),
+                                                           this);
+    if (e->button() == Qt::LeftButton && (sc == QStyle::SC_ComboBoxArrow || !isEditable())
+        && !d->viewContainer()->isVisible()) {
+        if (sc == QStyle::SC_ComboBoxArrow)
+            d->updateArrow(QStyle::State_Sunken);
+#ifdef QT_KEYPAD_NAVIGATION
+        if (!d->lineEdit) {
+#endif
+            // We've restricted the next couple of lines, because by not calling
+            // viewContainer(), we avoid creating the QComboBoxPrivateContainer.
+            d->viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval());
+            d->viewContainer()->initialClickPosition = mapToGlobal(e->pos());
+#ifdef QT_KEYPAD_NAVIGATION
+        }
+#endif
+        showPopup();
+    } else {
+#ifdef QT_KEYPAD_NAVIGATION
+        if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && d->lineEdit) {
+            d->lineEdit->event(e);  //so lineedit can move cursor, etc
+            return;
+        }
+#endif
+        QWidget::mousePressEvent(e);
+    }
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::mouseReleaseEvent(QMouseEvent *e)
+{
+    Q_D(QComboBox);
+    Q_UNUSED(e);
+    d->updateArrow(QStyle::State_None);
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::keyPressEvent(QKeyEvent *e)
+{
+    Q_D(QComboBox);
+
+#ifndef QT_NO_COMPLETER
+    if (d->lineEdit
+        && d->lineEdit->completer()
+        && d->lineEdit->completer()->popup()
+        && d->lineEdit->completer()->popup()->isVisible()) {
+        // provide same autocompletion support as line edit
+        d->lineEdit->event(e);
+        return;
+    }
+#endif
+
+    enum Move { NoMove=0 , MoveUp , MoveDown , MoveFirst , MoveLast};
+
+    Move move = NoMove;
+    int newIndex = currentIndex();
+    switch (e->key()) {
+    case Qt::Key_Up:
+        if (e->modifiers() & Qt::ControlModifier)
+            break; // pass to line edit for auto completion
+    case Qt::Key_PageUp:
+#ifdef QT_KEYPAD_NAVIGATION
+        if (QApplication::keypadNavigationEnabled())
+            e->ignore();
+        else
+#endif
+        move = MoveUp;
+        break;
+    case Qt::Key_Down:
+        if (e->modifiers() & Qt::AltModifier) {
+            showPopup();
+            return;
+        } else if (e->modifiers() & Qt::ControlModifier)
+            break; // pass to line edit for auto completion
+        // fall through
+    case Qt::Key_PageDown:
+#ifdef QT_KEYPAD_NAVIGATION
+        if (QApplication::keypadNavigationEnabled())
+            e->ignore();
+        else
+#endif
+        move = MoveDown;
+        break;
+    case Qt::Key_Home:
+        if (!d->lineEdit)
+            move = MoveFirst;
+        break;
+    case Qt::Key_End:
+        if (!d->lineEdit)
+            move = MoveLast;
+        break;
+    case Qt::Key_F4:
+        if (!e->modifiers()) {
+            showPopup();
+            return;
+        }
+        break;
+    case Qt::Key_Space:
+        if (!d->lineEdit) {
+            showPopup();
+            return;
+        }
+    case Qt::Key_Enter:
+    case Qt::Key_Return:
+    case Qt::Key_Escape:
+        if (!d->lineEdit)
+            e->ignore();
+        break;
+#ifdef QT_KEYPAD_NAVIGATION
+    case Qt::Key_Select:
+        if (QApplication::keypadNavigationEnabled()
+                && (!hasEditFocus() || !d->lineEdit)) {
+            showPopup();
+            return;
+        }
+        break;
+    case Qt::Key_Left:
+    case Qt::Key_Right:
+        if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
+            e->ignore();
+        break;
+    case Qt::Key_Back:
+        if (QApplication::keypadNavigationEnabled()) {
+            if (!hasEditFocus() || !d->lineEdit)
+                e->ignore();
+        } else {
+            e->ignore(); // let the surounding dialog have it
+        }
+        break;
+#endif
+    default:
+        if (!d->lineEdit) {
+            if (!e->text().isEmpty())
+                d->keyboardSearchString(e->text());
+            else
+                e->ignore();
+        }
+    }
+
+    if (move != NoMove) {
+        e->accept();
+        switch (move) {
+        case MoveFirst:
+            newIndex = -1;
+        case MoveDown:
+            newIndex++;
+            while ((newIndex < count()) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+                newIndex++;
+            break;
+        case MoveLast:
+            newIndex = count();
+        case MoveUp:
+            newIndex--;
+            while ((newIndex >= 0) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+                newIndex--;
+            break;
+        default:
+            e->ignore();
+            break;
+        }
+
+        if (newIndex >= 0 && newIndex < count() && newIndex != currentIndex()) {
+            setCurrentIndex(newIndex);
+            d->emitActivated(d->currentIndex);
+        }
+    } else if (d->lineEdit) {
+        d->lineEdit->event(e);
+    }
+}
+
+
+/*!
+    \reimp
+*/
+void QComboBox::keyReleaseEvent(QKeyEvent *e)
+{
+    Q_D(QComboBox);
+    if (d->lineEdit)
+        d->lineEdit->event(e);
+}
+
+/*!
+    \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QComboBox::wheelEvent(QWheelEvent *e)
+{
+    Q_D(QComboBox);
+    if (!d->viewContainer()->isVisible()) {
+        int newIndex = currentIndex();
+
+        if (e->delta() > 0) {
+            newIndex--;
+            while ((newIndex >= 0) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+                newIndex--;
+        } else {
+            newIndex++;
+            while ((newIndex < count()) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+                newIndex++;
+        }
+
+        if (newIndex >= 0 && newIndex < count() && newIndex != currentIndex()) {
+            setCurrentIndex(newIndex);
+            d->emitActivated(d->currentIndex);
+        }
+        e->accept();
+    }
+}
+#endif
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+    \reimp
+*/
+void QComboBox::contextMenuEvent(QContextMenuEvent *e)
+{
+    Q_D(QComboBox);
+    if (d->lineEdit) {
+        Qt::ContextMenuPolicy p = d->lineEdit->contextMenuPolicy();
+        d->lineEdit->setContextMenuPolicy(Qt::DefaultContextMenu);
+        d->lineEdit->event(e);
+        d->lineEdit->setContextMenuPolicy(p);
+    }
+}
+#endif // QT_NO_CONTEXTMENU
+
+void QComboBoxPrivate::keyboardSearchString(const QString &text)
+{
+    // use keyboardSearch from the listView so we do not duplicate code
+    QAbstractItemView *view = viewContainer()->itemView();
+    view->setCurrentIndex(currentIndex);
+    int currentRow = view->currentIndex().row();
+    view->keyboardSearch(text);
+    if (currentRow != view->currentIndex().row()) {
+        setCurrentIndex(view->currentIndex());
+        emitActivated(currentIndex);
+    }
+}
+
+void QComboBoxPrivate::modelChanged()
+{
+    Q_Q(QComboBox);
+
+    if (sizeAdjustPolicy == QComboBox::AdjustToContents) {
+        sizeHint = QSize();
+        adjustComboBoxSize();
+        q->updateGeometry();
+    }
+}
+
+/*!
+    \reimp
+*/
+void QComboBox::inputMethodEvent(QInputMethodEvent *e)
+{
+    Q_D(QComboBox);
+    if (d->lineEdit) {
+        d->lineEdit->event(e);
+    } else {
+        if (!e->commitString().isEmpty())
+            d->keyboardSearchString(e->commitString());
+        else
+            e->ignore();
+    }
+}
+
+/*!
+    \reimp
+*/
+QVariant QComboBox::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QComboBox);
+    if (d->lineEdit)
+        return d->lineEdit->inputMethodQuery(query);
+    return QWidget::inputMethodQuery(query);
+}
+
+/*!
+    \fn bool QComboBox::editable() const
+
+    Use isEditable() instead.
+*/
+
+/*!
+    \fn void QComboBox::insertItem(const QPixmap &pixmap, int index)
+
+    Use an insertItem() function that takes a QIcon instead, for
+    example, insertItem(index, QIcon(pixmap)).
+*/
+
+/*!
+    \fn void QComboBox::insertItem(const QPixmap &pixmap, const QString &text, int index)
+
+    Use an insertItem() function that takes a QIcon instead, for
+    example, insertItem(index, QIcon(pixmap), text).
+
+    \sa insertItems()
+*/
+
+/*!
+    \fn void QComboBox::changeItem(const QString &text, int index)
+
+    Use setItemText() instead.
+*/
+
+/*!
+    \fn void QComboBox::changeItem(const QPixmap &pixmap, int index)
+
+    Use setItemIcon() instead, for example,
+    setItemIcon(index, QIcon(pixmap)).
+*/
+
+/*!
+    \fn void QComboBox::changeItem(const QPixmap &pixmap, const QString &text, int index)
+
+    Use setItem() instead, for example, setItem(index, QIcon(pixmap),text).
+*/
+
+/*!
+    \fn void QComboBox::addItem(const QString &text, const QVariant &userData)
+
+    Adds an item to the combobox with the given \a text, and
+    containing the specified \a userData (stored in the Qt::UserRole).
+    The item is appended to the list of existing items.
+*/
+
+/*!
+    \fn void QComboBox::addItem(const QIcon &icon, const QString &text,
+                                const QVariant &userData)
+
+    Adds an item to the combobox with the given \a icon and \a text,
+    and containing the specified \a userData (stored in the
+    Qt::UserRole). The item is appended to the list of existing items.
+*/
+
+/*!
+    \fn void QComboBox::addItems(const QStringList &texts)
+
+    Adds each of the strings in the given \a texts to the combobox. Each item
+    is appended to the list of existing items in turn.
+*/
+
+/*!
+    \fn void QComboBox::editTextChanged(const QString &text)
+
+    This signal is emitted when the text in the combobox's line edit
+    widget is changed. The new text is specified by \a text.
+*/
+
+/*!
+    \fn QComboBox::InsertPolicy QComboBox::insertionPolicy() const
+    \compat
+
+    Use QComboBox::insertPolicy instead.
+*/
+
+/*!
+    \fn void QComboBox::setInsertionPolicy(InsertPolicy policy)
+    \compat
+
+    Use QComboBox::insertPolicy instead.
+*/
+
+/*!
+    \fn void QComboBox::setCurrentText(const QString &text)
+    \compat
+
+    Use setItemText() instead.
+
+    \sa currentIndex()
+*/
+
+/*!
+    \fn QString QComboBox::text(int index) const
+    \compat
+
+    Use itemText() instead.
+*/
+
+/*!
+    \fn QPixmap QComboBox::pixmap(int index) const
+    \compat
+
+    Use itemIcon() instead.
+*/
+
+/*!
+    \fn void QComboBox::insertStringList(const QStringList &list, int index)
+    \compat
+
+    Use insertItems() instead.
+*/
+
+/*!
+    \fn void QComboBox::insertItem(const QString &text, int index)
+    \compat
+*/
+
+/*!
+    \fn void QComboBox::clearEdit()
+    \compat
+
+    Use clearEditText() instead.
+*/
+
+
+/*!
+    \property QComboBox::frame
+    \brief whether the combo box draws itself with a frame
+
+
+    If enabled (the default) the combo box draws itself inside a
+    frame, otherwise the combo box draws itself without any frame.
+*/
+bool QComboBox::hasFrame() const
+{
+    Q_D(const QComboBox);
+    return d->frame;
+}
+
+
+void QComboBox::setFrame(bool enable)
+{
+    Q_D(QComboBox);
+    d->frame = enable;
+    update();
+    updateGeometry();
+}
+
+/*!
+    \property QComboBox::modelColumn
+    \brief the column in the model that is visible.
+
+    If set prior to populating the combo box, the pop-up view will
+    not be affected and will show the first column (using this property's
+    default value).
+
+    By default, this property has a value of 0.
+*/
+int QComboBox::modelColumn() const
+{
+    Q_D(const QComboBox);
+    return d->modelColumn;
+}
+
+void QComboBox::setModelColumn(int visibleColumn)
+{
+    Q_D(QComboBox);
+    d->modelColumn = visibleColumn;
+    QListView *lv = qobject_cast<QListView *>(d->viewContainer()->itemView());
+    if (lv)
+        lv->setModelColumn(visibleColumn);
+#ifndef QT_NO_COMPLETER
+    if (d->lineEdit && d->lineEdit->completer()
+        && d->lineEdit->completer() == d->completer)
+        d->lineEdit->completer()->setCompletionColumn(visibleColumn);
+#endif
+    setCurrentIndex(currentIndex()); //update the text to the text of the new column;
+}
+
+/*!
+    \fn int QComboBox::currentItem() const
+
+    Use currentIndex() instead.
+*/
+
+/*!
+    \fn void QComboBox::setCurrentItem(int)
+
+    Use setCurrentIndex(int) instead.
+*/
+
+/*!
+    \fn void QComboBox::popup()
+
+    Use showPopup() instead.
+*/
+
+/*!
+    \fn void QComboBox::textChanged(const QString &text)
+
+    Use the editTextChanged(const QString &text) signal instead.
+*/
+
+/*!
+    \typedef QComboBox::Policy
+    \compat
+
+    Use QComboBox::InsertPolicy instead.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qcombobox.cpp"
+
+#endif // QT_NO_COMBOBOX