399 |
401 |
400 // we need a vertical layout |
402 // we need a vertical layout |
401 QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); |
403 QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); |
402 layout->setSpacing(0); |
404 layout->setSpacing(0); |
403 layout->setMargin(0); |
405 layout->setMargin(0); |
404 |
|
405 #ifdef QT_SOFTKEYS_ENABLED |
|
406 selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, this); |
|
407 cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, this); |
|
408 addAction(selectAction); |
|
409 addAction(cancelAction); |
|
410 #endif |
|
411 |
406 |
412 // set item view |
407 // set item view |
413 setItemView(itemView); |
408 setItemView(itemView); |
414 |
409 |
415 // add scroller arrows if style needs them |
410 // add scroller arrows if style needs them |
528 disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), |
511 disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), |
529 this, SLOT(updateScrollers())); |
512 this, SLOT(updateScrollers())); |
530 disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), |
513 disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), |
531 this, SLOT(updateScrollers())); |
514 this, SLOT(updateScrollers())); |
532 #endif |
515 #endif |
533 disconnect(view, SIGNAL(entered(QModelIndex)), |
|
534 this, SLOT(setCurrentIndex(QModelIndex))); |
|
535 disconnect(view, SIGNAL(destroyed()), |
516 disconnect(view, SIGNAL(destroyed()), |
536 this, SLOT(viewDestroyed())); |
517 this, SLOT(viewDestroyed())); |
537 |
518 |
538 delete view; |
519 delete view; |
539 view = 0; |
520 view = 0; |
566 connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), |
547 connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), |
567 this, SLOT(updateScrollers())); |
548 this, SLOT(updateScrollers())); |
568 connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), |
549 connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), |
569 this, SLOT(updateScrollers())); |
550 this, SLOT(updateScrollers())); |
570 #endif |
551 #endif |
571 connect(view, SIGNAL(entered(QModelIndex)), |
|
572 this, SLOT(setCurrentIndex(QModelIndex))); |
|
573 connect(view, SIGNAL(destroyed()), |
552 connect(view, SIGNAL(destroyed()), |
574 this, SLOT(viewDestroyed())); |
553 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 |
575 } |
561 } |
576 |
562 |
577 /*! |
563 /*! |
578 Returns the spacing between the items in the view. |
564 Returns the spacing between the items in the view. |
579 */ |
565 */ |
651 return true; |
637 return true; |
652 default: |
638 default: |
653 break; |
639 break; |
654 } |
640 } |
655 break; |
641 break; |
656 case QEvent::MouseMove: { |
642 case QEvent::MouseMove: |
657 if (isVisible()) { |
643 if (isVisible()) { |
658 QMouseEvent *m = static_cast<QMouseEvent *>(e); |
644 QMouseEvent *m = static_cast<QMouseEvent *>(e); |
659 QWidget *widget = static_cast<QWidget *>(o); |
645 QWidget *widget = static_cast<QWidget *>(o); |
660 QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition; |
646 QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition; |
661 if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) |
647 if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) |
662 blockMouseReleaseTimer.stop(); |
648 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 } |
663 } |
654 } |
664 break; |
655 break; |
665 } |
|
666 case QEvent::MouseButtonRelease: { |
656 case QEvent::MouseButtonRelease: { |
667 QMouseEvent *m = static_cast<QMouseEvent *>(e); |
657 QMouseEvent *m = static_cast<QMouseEvent *>(e); |
668 if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid() |
658 if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid() |
669 && !blockMouseReleaseTimer.isActive() |
659 && !blockMouseReleaseTimer.isActive() |
670 && (view->currentIndex().flags() & Qt::ItemIsEnabled) |
660 && (view->currentIndex().flags() & Qt::ItemIsEnabled) |
939 q->setFocusPolicy(Qt::WheelFocus); |
929 q->setFocusPolicy(Qt::WheelFocus); |
940 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, |
930 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, |
941 QSizePolicy::ComboBox)); |
931 QSizePolicy::ComboBox)); |
942 setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); |
932 setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); |
943 q->setModel(new QStandardItemModel(0, 1, q)); |
933 q->setModel(new QStandardItemModel(0, 1, q)); |
944 q->setAttribute(Qt::WA_InputMethodEnabled); |
934 if (!q->isEditable()) |
|
935 q->setAttribute(Qt::WA_InputMethodEnabled, false); |
|
936 else |
|
937 q->setAttribute(Qt::WA_InputMethodEnabled); |
945 } |
938 } |
946 |
939 |
947 QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer() |
940 QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer() |
948 { |
941 { |
949 if (container) |
942 if (container) |
1130 editRect.size(), comboRect); |
1112 editRect.size(), comboRect); |
1131 } |
1113 } |
1132 lineEdit->setGeometry(editRect); |
1114 lineEdit->setGeometry(editRect); |
1133 } |
1115 } |
1134 |
1116 |
|
1117 Qt::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 |
|
1129 void 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 |
1135 void QComboBoxPrivate::_q_returnPressed() |
1143 void QComboBoxPrivate::_q_returnPressed() |
1136 { |
1144 { |
1137 Q_Q(QComboBox); |
1145 Q_Q(QComboBox); |
1138 if (lineEdit && !lineEdit->text().isEmpty()) { |
1146 if (lineEdit && !lineEdit->text().isEmpty()) { |
1139 if (q->count() >= maxCount && !(this->insertPolicy == QComboBox::InsertAtCurrent)) |
1147 if (q->count() >= maxCount && !(this->insertPolicy == QComboBox::InsertAtCurrent)) |
1142 lineEdit->end(false); |
1150 lineEdit->end(false); |
1143 QString text = lineEdit->text(); |
1151 QString text = lineEdit->text(); |
1144 // check for duplicates (if not enabled) and quit |
1152 // check for duplicates (if not enabled) and quit |
1145 int index = -1; |
1153 int index = -1; |
1146 if (!duplicatesEnabled) { |
1154 if (!duplicatesEnabled) { |
1147 // Base how duplicates are determined on the autocompletion case sensitivity |
1155 index = q->findText(text, matchFlags()); |
1148 Qt::MatchFlags flags = Qt::MatchFixedString; |
|
1149 #ifndef QT_NO_COMPLETER |
|
1150 if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive) |
|
1151 #endif |
|
1152 flags |= Qt::MatchCaseSensitive; |
|
1153 index = q->findText(text, flags); |
|
1154 if (index != -1) { |
1156 if (index != -1) { |
1155 q->setCurrentIndex(index); |
1157 q->setCurrentIndex(index); |
1156 emitActivated(currentIndex); |
1158 emitActivated(currentIndex); |
1157 return; |
1159 return; |
1158 } |
1160 } |
1683 |
1685 |
1684 d->lineEdit = edit; |
1686 d->lineEdit = edit; |
1685 if (d->lineEdit->parent() != this) |
1687 if (d->lineEdit->parent() != this) |
1686 d->lineEdit->setParent(this); |
1688 d->lineEdit->setParent(this); |
1687 connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed())); |
1689 connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed())); |
|
1690 connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished())); |
1688 connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString))); |
1691 connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString))); |
1689 #ifdef QT3_SUPPORT |
1692 #ifdef QT3_SUPPORT |
1690 connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString))); |
1693 connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString))); |
1691 #endif |
1694 #endif |
1692 d->lineEdit->setFrame(false); |
1695 d->lineEdit->setFrame(false); |
1866 #endif |
1869 #endif |
1867 if (d->model) { |
1870 if (d->model) { |
1868 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
1871 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
1869 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); |
1872 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); |
1870 disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), |
1873 disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), |
1871 this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); |
1874 this, SLOT(_q_updateIndexBeforeChange())); |
1872 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
1875 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
1873 this, SLOT(_q_rowsInserted(QModelIndex,int,int))); |
1876 this, SLOT(_q_rowsInserted(QModelIndex,int,int))); |
1874 disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
1877 disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
1875 this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); |
1878 this, SLOT(_q_updateIndexBeforeChange())); |
1876 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
1879 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
1877 this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); |
1880 this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); |
1878 disconnect(d->model, SIGNAL(destroyed()), |
1881 disconnect(d->model, SIGNAL(destroyed()), |
1879 this, SLOT(_q_modelDestroyed())); |
1882 this, SLOT(_q_modelDestroyed())); |
|
1883 disconnect(d->model, SIGNAL(modelAboutToBeReset()), |
|
1884 this, SLOT(_q_updateIndexBeforeChange())); |
1880 disconnect(d->model, SIGNAL(modelReset()), |
1885 disconnect(d->model, SIGNAL(modelReset()), |
1881 this, SLOT(_q_modelReset())); |
1886 this, SLOT(_q_modelReset())); |
1882 if (d->model->QObject::parent() == this) |
1887 if (d->model->QObject::parent() == this) |
1883 delete d->model; |
1888 delete d->model; |
1884 } |
1889 } |
1886 d->model = model; |
1891 d->model = model; |
1887 |
1892 |
1888 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
1893 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
1889 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); |
1894 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); |
1890 connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), |
1895 connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), |
1891 this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); |
1896 this, SLOT(_q_updateIndexBeforeChange())); |
1892 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
1897 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), |
1893 this, SLOT(_q_rowsInserted(QModelIndex,int,int))); |
1898 this, SLOT(_q_rowsInserted(QModelIndex,int,int))); |
1894 connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
1899 connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), |
1895 this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); |
1900 this, SLOT(_q_updateIndexBeforeChange())); |
1896 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
1901 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
1897 this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); |
1902 this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); |
1898 connect(model, SIGNAL(destroyed()), |
1903 connect(model, SIGNAL(destroyed()), |
1899 this, SLOT(_q_modelDestroyed())); |
1904 this, SLOT(_q_modelDestroyed())); |
|
1905 connect(model, SIGNAL(modelAboutToBeReset()), |
|
1906 this, SLOT(_q_updateIndexBeforeChange())); |
1900 connect(model, SIGNAL(modelReset()), |
1907 connect(model, SIGNAL(modelReset()), |
1901 this, SLOT(_q_modelReset())); |
1908 this, SLOT(_q_modelReset())); |
1902 |
1909 |
1903 if (d->container) |
1910 if (d->container) |
1904 d->container->itemView()->setModel(model); |
1911 d->container->itemView()->setModel(model); |
2450 const bool updatesEnabled = container->updatesEnabled(); |
2457 const bool updatesEnabled = container->updatesEnabled(); |
2451 #endif |
2458 #endif |
2452 |
2459 |
2453 #if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS) |
2460 #if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS) |
2454 bool scrollDown = (listRect.topLeft() == below); |
2461 bool scrollDown = (listRect.topLeft() == below); |
2455 if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) |
2462 if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) |
2456 && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen)) |
2463 && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen)) |
2457 qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150); |
2464 qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150); |
2458 #endif |
2465 #endif |
2459 |
2466 |
2460 // Don't disable updates on Mac OS X. Windows are displayed immediately on this platform, |
2467 // Don't disable updates on Mac OS X. Windows are displayed immediately on this platform, |
2461 // which means that the window will be visible before the call to container->show() returns. |
2468 // which means that the window will be visible before the call to container->show() returns. |
2462 // If updates are disabled at this point we'll miss our chance at painting the popup |
2469 // If updates are disabled at this point we'll miss our chance at painting the popup |
2463 // menu before it's shown, causing flicker since the window then displays the standard gray |
2470 // menu before it's shown, causing flicker since the window then displays the standard gray |
2464 // background. |
2471 // background. |
2465 #ifndef Q_WS_MAC |
2472 #ifndef Q_WS_MAC |
2466 container->setUpdatesEnabled(false); |
2473 container->setUpdatesEnabled(false); |
2467 #endif |
2474 #endif |
2468 |
2475 |