⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qcombobox.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qcombobox.h"#ifndef QT_NO_COMBOBOX#include <qstylepainter.h>#include <qlineedit.h>#include <qapplication.h>#include <qdesktopwidget.h>#include <qlistview.h>#include <qitemdelegate.h>#include <qstandarditemmodel.h>#include <qmap.h>#include <qevent.h>#include <qlayout.h>#include <qscrollbar.h>#ifndef QT_NO_IM#include "qinputcontext.h"#endif#include <private/qcombobox_p.h>#include <qdebug.h>QComboBoxPrivate::QComboBoxPrivate()    : QWidgetPrivate(),      model(0),      lineEdit(0),      container(0),      insertPolicy(QComboBox::InsertAtBottom),      sizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow),      minimumContentsLength(0),      shownOnce(false),      autoCompletion(true),      duplicatesEnabled(false),      skipCompletion(false),      frame(true),      maxVisibleItems(10),      maxCount(INT_MAX),      modelColumn(0),      arrowState(QStyle::State_None),      hoverControl(QStyle::SC_None),      autoCompletionCaseSensitivity(Qt::CaseInsensitive),      indexBeforeChange(-1){}QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewItem &option,                                                  const QModelIndex &index) const{    QStyleOptionMenuItem menuOption;    menuOption.palette = QApplication::palette("QMenu");    menuOption.state = QStyle::State_None;    if (mCombo->window()->isActiveWindow())        menuOption.state = QStyle::State_Active;    if (option.state & QStyle::State_Enabled)        menuOption.state |= QStyle::State_Enabled;    if (option.state & QStyle::State_Selected)        menuOption.state |= QStyle::State_Selected;    menuOption.checkType = QStyleOptionMenuItem::NonExclusive;    menuOption.checked = mCombo->currentIndex() == index.row();    menuOption.menuItemType = QStyleOptionMenuItem::Normal;    menuOption.icon = qvariant_cast<QIcon>(index.model()->data(index, Qt::DecorationRole));    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;    extern QHash<QByteArray, QFont> *qt_app_fonts_hash();    menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font());    return menuOption;}void QComboBoxPrivate::updateArrow(QStyle::StateFlag state){    Q_Q(QComboBox);    if (arrowState == state)        return;    arrowState = state;    QStyleOptionComboBox opt = getStyleOption();    q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow));}void QComboBoxPrivate::_q_modelReset(){    Q_Q(QComboBox);    if (lineEdit) {        lineEdit->setText("");        updateLineEditGeometry();    }    q->update();}void QComboBoxPrivate::_q_modelDestroyed(){    Q_Q(QComboBox);    model = 0;    q->setModel(new QStandardItemModel(0, 1, q));}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 = getStyleOption();    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;}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);    // 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();    if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {        top = new QComboBoxPrivateScroller(QAbstractSlider::SliderSingleStepSub, this);        bottom = new QComboBoxPrivateScroller(QAbstractSlider::SliderSingleStepAdd, this);        top->hide();        bottom->hide();    } else {        setFrameStyle(QFrame::StyledPanel|QFrame::Plain);        setLineWidth(1);    }    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)));    }}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;    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}/*    Sets currentIndex on entered if the LeftButton is not pressed. This    means that if mouseTracking(...) is on, we setCurrentIndex and select    even when LeftButton is not pressed.*/void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index){    view->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);}/*    Returns the item view used for the combobox popup.*/QAbstractItemView *QComboBoxPrivateContainer::itemView() const{    return view;}/*!    Sets the item view to be used for the combobox popup.*/void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView){    Q_ASSERT(itemView);    // clean up old one    if (view) {        view->removeEventFilter(this);        view->viewport()->removeEventFilter(this);#ifndef QT_NO_SCROLLBAR        disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),                   this, SLOT(updateScrollers()));        disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),                   this, SLOT(updateScrollers()));#endif        disconnect(view, SIGNAL(entered(QModelIndex)),                   this, SLOT(setCurrentIndex(QModelIndex)));        delete view;        view = 0;    }    // setup the item view    view = itemView;    view->setParent(this);    qobject_cast<QBoxLayout*>(layout())->insertWidget(top ? 1 : 0, view);    view->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);    view->installEventFilter(this);    view->viewport()->installEventFilter(this);    QStyleOptionComboBox opt = comboStyleOption();#ifndef QT_NO_SCROLLBAR    if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo))        view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);#endif    if (style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||        style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) {        view->setMouseTracking(true);    }    view->setSelectionMode(QAbstractItemView::SingleSelection);    view->setFrameStyle(QFrame::NoFrame);    view->setLineWidth(0);    view->setEditTriggers(QAbstractItemView::NoEditTriggers);#ifndef QT_NO_SCROLLBAR    connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)),            this, SLOT(updateScrollers()));    connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),            this, SLOT(updateScrollers()));#endif    connect(view, SIGNAL(entered(QModelIndex)),            this, SLOT(setCurrentIndex(QModelIndex)));}/*!    Returns the spacing between the items in the view.*/int QComboBoxPrivateContainer::spacing() const{    QListView *lview = qobject_cast<QListView*>(view);    if (lview)        return lview->spacing();    return 0;}void QComboBoxPrivateContainer::changeEvent(QEvent *e){    if (e->type() == QEvent::StyleChange) {        QStyleOptionComboBox opt = comboStyleOption();        view->setMouseTracking(style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||                               style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo));    }    QWidget::changeEvent(e);}bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e){    switch (e->type()) {    case QEvent::KeyPress:        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()) {                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:#ifdef QT_KEYPAD_NAVIGATION        case Qt::Key_Back:#endif            combo->hidePopup();            return true;        default:            break;        }    break;    case QEvent::MouseMove: {        if (isVisible()) {            QMouseEvent *m = static_cast<QMouseEvent *>(e);            QPoint vector = m->pos() - initialClickPosition;            if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())                blockMouseReleaseTimer.stop();        }        break;    }    case QEvent::MouseButtonRelease: {        QMouseEvent *m = static_cast<QMouseEvent *>(e);        if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()            && !blockMouseReleaseTimer.isActive()) {            combo->hidePopup();            emit itemSelected(view->currentIndex());            return true;        }        break;    }    default:        break;    }    return QFrame::eventFilter(o, e);}void QComboBoxPrivateContainer::hideEvent(QHideEvent *){    emit resetButton();}void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e){    QStyleOptionComboBox opt = comboStyleOption();    opt.subControls = QStyle::SC_All;    opt.activeSubControls = QStyle::SC_ComboBoxArrow;    QStyle::SubControl sc = 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);    QFrame::mousePressEvent(e);}void QComboBoxPrivateContainer::mouseReleaseEvent(QMouseEvent *e){    Q_UNUSED(e);    emit resetButton();}QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const{    QStyleOptionComboBox opt;    opt.state = QStyle::State_None;    opt.rect = combo->rect();    opt.palette = combo->palette();    opt.init(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.    \omitvalue NoInsertion    \omitvalue AtTop    \omitvalue AtCurrent    \omitvalue AtBottom    \omitvalue AfterCurrent    \omitvalue BeforeCurrent*//*!    \enum QComboBox::SizeAdjustPolicy    This enum specifies how the size of the QComboBox should adjust    when new content is added or content changes.    \value AdjustToContents              The combobox will always adjust to the contens    \value AdjustToContentsOnFirstShow   The combobox will adjust to its contents the first time it is show.    \value AdjustToMinimumContentsLength The combobox only adjusts to the \l minimumContentsLength*//*!    \fn void QComboBox::activated(int index)    This signal is sent when an item in the combobox is activated by    the user. The item's \a index is given.*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -