/****************************************************************************+ −
**+ −
** Copyright (C) 2010 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();+ −
}+ −
if (currentIndex.row() != indexBeforeChange)+ −
_q_emitCurrentIndexChanged(currentIndex);+ −
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.height(), 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);+ −
+ −
// 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());+ −
}+ −
+ −
/*+ −
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(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(destroyed()),+ −
this, SLOT(viewDestroyed()));+ −
+ −
#ifdef QT_SOFTKEYS_ENABLED+ −
selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, itemView);+ −
cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, itemView);+ −
addAction(selectAction);+ −
addAction(cancelAction);+ −
#endif+ −
}+ −
+ −
/*!+ −
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();+ −
QModelIndex indexUnderMouse = view->indexAt(m->pos());+ −
if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()+ −
&& !QComboBoxDelegate::isSeparator(indexUnderMouse)) {+ −
view->setCurrentIndex(indexUnderMouse);+ −
}+ −
}+ −
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));+ −
if (!q->isEditable())+ −
q->setAttribute(Qt::WA_InputMethodEnabled, false);+ −
else+ −
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_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_updateIndexBeforeChange()+ −
{+ −
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);+ −
}+ −
+ −
Qt::MatchFlags QComboBoxPrivate::matchFlags() const+ −
{+ −
// 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;+ −
return flags;+ −
}+ −
+ −
+ −
void QComboBoxPrivate::_q_editingFinished()+ −
{+ −
Q_Q(QComboBox);+ −
if (lineEdit && !lineEdit->text().isEmpty()) {+ −
//here we just check if the current item was entered+ −
const int index = q_func()->findText(lineEdit->text(), matchFlags());+ −
if (index != -1 && itemText(currentIndex) != lineEdit->text()) {+ −
q->setCurrentIndex(index);+ −
emitActivated(currentIndex);+ −
}+ −
}+ −
+ −
}+ −
+ −
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) {+ −
index = q->findText(text, matchFlags());+ −
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(editingFinished()), this, SLOT(_q_editingFinished()));+ −
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_updateIndexBeforeChange()));+ −
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_updateIndexBeforeChange()));+ −
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(modelAboutToBeReset()),+ −
this, SLOT(_q_updateIndexBeforeChange()));+ −
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_updateIndexBeforeChange()));+ −
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),+ −
this, SLOT(_q_rowsInserted(QModelIndex,int,int)));+ −
connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),+ −
this, SLOT(_q_updateIndexBeforeChange()));+ −
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(modelAboutToBeReset()),+ −
this, SLOT(_q_updateIndexBeforeChange()));+ −
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(newText);+ −
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+ −