Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qcombobox.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#include "qinputcontext.h"
    6161#endif
     62#include <private/qapplication_p.h>
    6263#include <private/qcombobox_p.h>
    6364#include <private/qabstractitemmodel_p.h>
    6465#include <private/qabstractscrollarea_p.h>
     66#include <private/qsoftkeymanager_p.h>
    6567#include <qdebug.h>
    66 
    6768#ifdef Q_WS_X11
    6869#include <private/qt_x11_p.h>
     
    7778#endif
    7879QT_BEGIN_NAMESPACE
    79 
    80 extern QHash<QByteArray, QFont> *qt_app_fonts_hash();
    8180
    8281QComboBoxPrivate::QComboBoxPrivate()
     
    150149
    151150    // Make sure fonts set on the combo box also overrides the font for the popup menu.
    152     if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize)
    153             || mCombo->testAttribute(Qt::WA_MacMiniSize))
     151    if (mCombo->testAttribute(Qt::WA_SetFont)
     152            || mCombo->testAttribute(Qt::WA_MacSmallSize)
     153            || mCombo->testAttribute(Qt::WA_MacMiniSize)
     154            || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont()))
    154155        menuOption.font = mCombo->font();
    155156    else
     
    192193        updateLineEditGeometry();
    193194    }
     195    if (currentIndex.row() != indexBeforeChange)
     196        _q_emitCurrentIndexChanged(currentIndex);
    194197    q->update();
    195198}
     
    314317
    315318        // height
    316         sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
     319        sh.setHeight(qMax(fm.height(), 14) + 2);
    317320        if (hasIcon) {
    318321            sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
     
    487490
    488491/*
    489     Sets currentIndex on entered if the LeftButton is not pressed. This
    490     means that if mouseTracking(...) is on, we setCurrentIndex and select
    491     even when LeftButton is not pressed.
    492 */
    493 void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index)
    494 {
    495     if (QComboBoxDelegate::isSeparator(index))
    496         return;
    497     view->setCurrentIndex(index);
    498 }
    499 
    500 /*
    501492    Returns the item view used for the combobox popup.
    502493*/
     
    523514                   this, SLOT(updateScrollers()));
    524515#endif
    525         disconnect(view, SIGNAL(entered(QModelIndex)),
    526                    this, SLOT(setCurrentIndex(QModelIndex)));
    527516        disconnect(view, SIGNAL(destroyed()),
    528517                   this, SLOT(viewDestroyed()));
     518
    529519        delete view;
    530520        view = 0;
     
    560550            this, SLOT(updateScrollers()));
    561551#endif
    562     connect(view, SIGNAL(entered(QModelIndex)),
    563             this, SLOT(setCurrentIndex(QModelIndex)));
    564552    connect(view, SIGNAL(destroyed()),
    565553            this, SLOT(viewDestroyed()));
     554
     555#ifdef QT_SOFTKEYS_ENABLED
     556    selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, itemView);
     557    cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, itemView);
     558    addAction(selectAction);
     559    addAction(cancelAction);
     560#endif
    566561}
    567562
     
    639634        case Qt::Key_F4:
    640635        case Qt::Key_Escape:
    641 #ifdef QT_KEYPAD_NAVIGATION
    642         case Qt::Key_Back:
    643 #endif
    644636            combo->hidePopup();
    645637            return true;
     
    648640        }
    649641    break;
    650     case QEvent::MouseMove: {
     642    case QEvent::MouseMove:
    651643        if (isVisible()) {
    652644            QMouseEvent *m = static_cast<QMouseEvent *>(e);
     
    655647            if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
    656648                blockMouseReleaseTimer.stop();
     649            QModelIndex indexUnderMouse = view->indexAt(m->pos());
     650            if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()
     651                    && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
     652                view->setCurrentIndex(indexUnderMouse);
     653            }
    657654        }
    658655        break;
    659     }
    660656    case QEvent::MouseButtonRelease: {
    661657        QMouseEvent *m = static_cast<QMouseEvent *>(e);
     
    863859
    864860    \ingroup basicwidgets
    865     \mainclass
     861
    866862
    867863    A QComboBox provides a means of presenting a list of options to the user
     
    936932    setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
    937933    q->setModel(new QStandardItemModel(0, 1, q));
    938     q->setAttribute(Qt::WA_InputMethodEnabled);
     934    if (!q->isEditable())
     935        q->setAttribute(Qt::WA_InputMethodEnabled, false);
     936    else
     937        q->setAttribute(Qt::WA_InputMethodEnabled);
    939938}
    940939
     
    948947    container->itemView()->setModel(model);
    949948    container->itemView()->setTextElideMode(Qt::ElideMiddle);
    950     updateDelegate();
     949    updateDelegate(true);
    951950    updateLayoutDirection();
     951    updateViewContainerPaletteAndOpacity();
    952952    QObject::connect(container, SIGNAL(itemSelected(QModelIndex)),
    953953                     q, SLOT(_q_itemSelected(QModelIndex)));
     
    986986}
    987987
    988 void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent,
    989                                              int /*start*/, int /*end*/)
    990 {
    991     if (parent != root)
    992         return;
    993     indexBeforeChange = currentIndex.row();
    994 }
    995 
    996988void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
    997989{
     
    10161008}
    10171009
    1018 void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
    1019 {
    1020     if (parent != root)
    1021         return;
    1022 
     1010void QComboBoxPrivate::_q_updateIndexBeforeChange()
     1011{
    10231012    indexBeforeChange = currentIndex.row();
    10241013}
     
    10511040}
    10521041
     1042
     1043void QComboBoxPrivate::updateViewContainerPaletteAndOpacity()
     1044{
     1045    if (!container)
     1046        return;
     1047    Q_Q(QComboBox);
     1048    QStyleOptionComboBox opt;
     1049    q->initStyleOption(&opt);
     1050#ifndef QT_NO_MENU
     1051    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
     1052        QMenu menu;
     1053        menu.ensurePolished();
     1054        container->setPalette(menu.palette());
     1055        container->setWindowOpacity(menu.windowOpacity());
     1056    } else
     1057#endif
     1058    {
     1059        container->setPalette(q->palette());
     1060        container->setWindowOpacity(1.0);
     1061    }
     1062}
    10531063
    10541064/*!
     
    11051115}
    11061116
     1117Qt::MatchFlags QComboBoxPrivate::matchFlags() const
     1118{
     1119    // Base how duplicates are determined on the autocompletion case sensitivity
     1120    Qt::MatchFlags flags = Qt::MatchFixedString;
     1121#ifndef QT_NO_COMPLETER
     1122    if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
     1123#endif
     1124        flags |= Qt::MatchCaseSensitive;
     1125    return flags;
     1126}
     1127
     1128
     1129void QComboBoxPrivate::_q_editingFinished()
     1130{
     1131    Q_Q(QComboBox);
     1132    if (lineEdit && !lineEdit->text().isEmpty()) {
     1133        //here we just check if the current item was entered
     1134        const int index = q_func()->findText(lineEdit->text(), matchFlags());
     1135        if (index != -1 && itemText(currentIndex) != lineEdit->text()) {
     1136            q->setCurrentIndex(index);
     1137            emitActivated(currentIndex);
     1138        }
     1139    }
     1140
     1141}
     1142
    11071143void QComboBoxPrivate::_q_returnPressed()
    11081144{
     
    11171153        int index = -1;
    11181154        if (!duplicatesEnabled) {
    1119             // Base how duplicates are determined on the autocompletion case sensitivity
    1120             Qt::MatchFlags flags = Qt::MatchFixedString;
    1121 #ifndef QT_NO_COMPLETER
    1122             if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
    1123 #endif
    1124                 flags |= Qt::MatchCaseSensitive;
    1125             index = q->findText(text, flags);
     1155            index = q->findText(text, matchFlags());
    11261156            if (index != -1) {
    11271157                q->setCurrentIndex(index);
     
    12251255    Q_D(QComboBox);
    12261256
    1227     disconnect(d->model, SIGNAL(destroyed()),
    1228                this, SLOT(_q_modelDestroyed()));
     1257    QT_TRY {
     1258        disconnect(d->model, SIGNAL(destroyed()),
     1259                this, SLOT(_q_modelDestroyed()));
     1260    } QT_CATCH(...) {
     1261        ; // objects can't throw in destructor
     1262    }
    12291263}
    12301264
     
    15681602}
    15691603
    1570 void QComboBoxPrivate::updateDelegate()
     1604/*! \internal
     1605    update the default delegate
     1606    depending on the style's SH_ComboBox_Popup hint, we use a different default delegate.
     1607
     1608    but we do not change the delegate is the combobox use a custom delegate,
     1609    unless \a force is set to true.
     1610 */
     1611void QComboBoxPrivate::updateDelegate(bool force)
    15711612{
    15721613    Q_Q(QComboBox);
    15731614    QStyleOptionComboBox opt;
    15741615    q->initStyleOption(&opt);
    1575     if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q))
    1576         q->setItemDelegate(new QComboMenuDelegate(q->view(), q));
    1577     else
    1578         q->setItemDelegate(new QComboBoxDelegate(q->view(), q));
     1616    if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) {
     1617        if (force || qobject_cast<QComboBoxDelegate *>(q->itemDelegate()))
     1618            q->setItemDelegate(new QComboMenuDelegate(q->view(), q));
     1619    } else {
     1620        if (force || qobject_cast<QComboMenuDelegate *>(q->itemDelegate()))
     1621            q->setItemDelegate(new QComboBoxDelegate(q->view(), q));
     1622    }
    15791623}
    15801624
     
    16441688        d->lineEdit->setParent(this);
    16451689    connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
     1690    connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
    16461691    connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
    16471692#ifdef QT3_SUPPORT
     
    18271872                   this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    18281873        disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
    1829                    this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
     1874                   this, SLOT(_q_updateIndexBeforeChange()));
    18301875        disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    18311876                   this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
    18321877        disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
    1833                    this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
     1878                   this, SLOT(_q_updateIndexBeforeChange()));
    18341879        disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
    18351880                   this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
    18361881        disconnect(d->model, SIGNAL(destroyed()),
    18371882                   this, SLOT(_q_modelDestroyed()));
     1883        disconnect(d->model, SIGNAL(modelAboutToBeReset()),
     1884                   this, SLOT(_q_updateIndexBeforeChange()));
    18381885        disconnect(d->model, SIGNAL(modelReset()),
    18391886                   this, SLOT(_q_modelReset()));
     
    18471894            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
    18481895    connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
    1849             this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
     1896            this, SLOT(_q_updateIndexBeforeChange()));
    18501897    connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
    18511898            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
    18521899    connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
    1853             this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
     1900            this, SLOT(_q_updateIndexBeforeChange()));
    18541901    connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
    18551902            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
    18561903    connect(model, SIGNAL(destroyed()),
    18571904            this, SLOT(_q_modelDestroyed()));
     1905    connect(model, SIGNAL(modelAboutToBeReset()),
     1906            this, SLOT(_q_updateIndexBeforeChange()));
    18581907    connect(model, SIGNAL(modelReset()),
    18591908            this, SLOT(_q_modelReset()));
     
    19361985        QString newText = q->itemText(currentIndex.row());
    19371986        if (lineEdit->text() != newText)
    1938             lineEdit->setText(q->itemText(currentIndex.row()));
     1987            lineEdit->setText(newText);
    19391988        updateLineEditGeometry();
    19401989    }
     
    21332182    Removes the item at the given \a index from the combobox.
    21342183    This will update the current index if the index is removed.
     2184
     2185    This function does nothing if \a index is out of range.
    21352186*/
    21362187void QComboBox::removeItem(int index)
    21372188{
    2138     Q_ASSERT(index >= 0 && index < count());
    2139     Q_D(QComboBox);
     2189    Q_D(QComboBox);
     2190    if (index < 0 || index >= count())
     2191        return;
    21402192    d->model->removeRows(index, 1, d->root);
    21412193}
     
    24022454    container->setGeometry(listRect);
    24032455
    2404     bool updatesEnabled = container->updatesEnabled();
     2456#ifndef Q_WS_MAC
     2457    const bool updatesEnabled = container->updatesEnabled();
     2458#endif
     2459
    24052460#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
    24062461    bool scrollDown = (listRect.topLeft() == below);
    2407     if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) 
     2462    if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
    24082463        && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen))
    24092464        qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150);
    24102465#endif
     2466
     2467// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform,
     2468// which means that the window will be visible before the call to container->show() returns.
     2469// If updates are disabled at this point we'll miss our chance at painting the popup
     2470// menu before it's shown, causing flicker since the window then displays the standard gray
     2471// background.
     2472#ifndef Q_WS_MAC
    24112473    container->setUpdatesEnabled(false);
     2474#endif
     2475
    24122476    container->raise();
    24132477    container->show();
     
    24202484                             : QAbstractItemView::EnsureVisible);
    24212485
     2486#ifndef Q_WS_MAC
    24222487    container->setUpdatesEnabled(updatesEnabled);
     2488#endif
     2489
    24232490    container->update();
     2491#ifdef QT_KEYPAD_NAVIGATION
     2492    if (QApplication::keypadNavigationEnabled())
     2493        view()->setEditFocus(true);
     2494#endif
    24242495}
    24252496
     
    25732644        break;
    25742645    case QEvent::PaletteChange: {
    2575         QStyleOptionComboBox opt;
    2576         initStyleOption(&opt);
    2577 #ifndef QT_NO_MENU
    2578         if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
    2579             QMenu menu;
    2580             menu.ensurePolished();
    2581             d->viewContainer()->setPalette(menu.palette());
    2582             d->viewContainer()->setWindowOpacity(menu.windowOpacity());
    2583         } else
    2584 #endif
    2585         {
    2586             d->viewContainer()->setPalette(palette());
    2587             d->viewContainer()->setWindowOpacity(1.0);
    2588         }
     2646        d->updateViewContainerPaletteAndOpacity();
    25892647        break;
    25902648    }
Note: See TracChangeset for help on using the changeset viewer.