diff options
Diffstat (limited to 'src/gui/widgets/qcombobox.cpp')
-rw-r--r-- | src/gui/widgets/qcombobox.cpp | 3365 |
1 files changed, 0 insertions, 3365 deletions
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp deleted file mode 100644 index dd1ad9cd28..0000000000 --- a/src/gui/widgets/qcombobox.cpp +++ /dev/null @@ -1,3365 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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> -#include <qmath.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 -#if defined(Q_WS_S60) -#include "private/qt_s60_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; - - QPalette resolvedpalette = option.palette.resolve(QApplication::palette("QMenu")); - QVariant value = index.data(Qt::ForegroundRole); - if (value.canConvert<QBrush>()) { - resolvedpalette.setBrush(QPalette::WindowText, qvariant_cast<QBrush>(value)); - resolvedpalette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(value)); - resolvedpalette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value)); - } - menuOption.palette = resolvedpalette; - 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; - } - if (index.data(Qt::BackgroundRole).canConvert<QBrush>()) { - menuOption.palette.setBrush(QPalette::All, QPalette::Background, - qvariant_cast<QBrush>(index.data(Qt::BackgroundRole))); - } - 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(qCeil(QFontMetricsF(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->updateGeometry(); - 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 -#ifndef Q_WS_S60 - if (usePopup) - view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -#endif -#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)); -#ifdef QT_SOFTKEYS_ENABLED - } else if (e->type() == QEvent::LanguageChange) { - selectAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::SelectSoftKey)); - cancelAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::CancelSoftKey)); -#endif - } - - 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() - && !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(); -#ifndef QT_NO_GRAPHICSVIEW - // QGraphicsScenePrivate::removePopup closes the combo box popup, it hides it non-explicitly. - // Hiding/showing the QComboBox after this will unexpectedly show the popup as well. - // Re-hiding the popup container makes sure it is explicitly hidden. - if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) - proxy->hide(); -#endif -} - -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 selects 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. Note - that you cannot alter the \l{QAbstractItemView::}{SelectionMode} - of the view(), e.g., by using - \l{QAbstractItemView::}{setSelectionMode()}. - - \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); - } - if (lineEdit) - lineEdit->setPalette(q->palette()); -} - -/*! - 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 styles that returns - true for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ 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); - - QModelIndex normalized; - if (mi.column() != modelColumn) - normalized = model->index(mi.row(), modelColumn, mi.parent()); - if (!normalized.isValid()) - normalized = mi; // Fallback to passed index. - - bool indexChanged = (normalized != currentIndex); - if (indexChanged) - currentIndex = QPersistentModelIndex(normalized); - if (lineEdit) { - QString newText = q->itemText(normalized.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)); -#ifndef Q_WS_S60 - QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); -#else - QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); -#endif - - 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()); - -#ifndef Q_WS_S60 - // 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()); -#endif - - - // 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()); - } -#ifdef Q_WS_S60 - if (screen.width() < screen.height()) { - // in portait, menu should be positioned above softkeys - listRect.moveBottom(screen.bottom()); - } else { - TRect staConTopRect = TRect(); - AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); - listRect.setWidth(listRect.height()); - //by default popup is centered on screen in landscape - listRect.moveCenter(screen.center()); - if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) { - // landscape without stacon, menu should be at the right - (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : - listRect.setLeft(screen.left()); - } - } -#endif - } 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); - -#ifdef Q_WS_S60 - if (d->container) { - QStyleOptionComboBox opt; - initStyleOption(&opt); - - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); - - QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt, - QStyle::SC_ComboBoxListBoxPopup, this)); - listRect.setHeight(qMin(screen.height(), screen.width())); - - if (screen.width() < screen.height()) { - // in portait, menu should be positioned above softkeys - listRect.moveBottom(screen.bottom()); - } else { - TRect staConTopRect = TRect(); - AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); - listRect.setWidth(listRect.height()); - //by default popup is centered on screen in landscape - listRect.moveCenter(screen.center()); - if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) { - // landscape without stacon, menu should be at the right - (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : - listRect.setLeft(screen.left()); - } - } - - d->container->setGeometry(listRect); - } - } -#endif - - // ### 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); -#ifdef Q_WS_S60 - if (d->viewContainer() && d->viewContainer()->isVisible()) - showPopup(); -#endif - 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 the container already exists, then d->viewContainer() is safe to call - if (d->container) { -#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 |