diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 917a325..8f08ae0 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -101,8 +101,7 @@ QComboBoxPrivate::QComboBoxPrivate() inserting(false), arrowState(QStyle::State_None), hoverControl(QStyle::SC_None), - autoCompletionCaseSensitivity(Qt::CaseInsensitive), - indexBeforeChange(-1) + autoCompletionCaseSensitivity(Qt::CaseInsensitive) #ifndef QT_NO_COMPLETER , completer(0) #endif @@ -208,7 +207,7 @@ void QComboBoxPrivate::_q_modelReset() lineEdit->setText(QString()); updateLineEditGeometry(); } - if (currentIndex.row() != indexBeforeChange) + if (currentIndex != indexBeforeChange) _q_emitCurrentIndexChanged(currentIndex); q->update(); } @@ -996,7 +995,7 @@ void QComboBoxPrivate::_q_resetButton() void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { Q_Q(QComboBox); - if (inserting || topLeft.parent() != root) + if (inserting) return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { @@ -1005,9 +1004,11 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn q->updateGeometry(); } - if (currentIndex.row() >= topLeft.row() && currentIndex.row() <= bottomRight.row()) { + if (currentIndex.parent() != topLeft.parent() + || (currentIndex.parent() == topLeft.parent() + && currentIndex.row() >= topLeft.row() && currentIndex.row() <= bottomRight.row())) { if (lineEdit) { - lineEdit->setText(q->itemText(currentIndex.row())); + lineEdit->setText(itemText(currentIndex)); updateLineEditGeometry(); } q->update(); @@ -1017,7 +1018,7 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end) { Q_Q(QComboBox); - if (inserting || parent != root) + if (inserting) return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { @@ -1030,7 +1031,7 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int 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) { + } else if (currentIndex != indexBeforeChange) { q->update(); _q_emitCurrentIndexChanged(currentIndex); } @@ -1038,14 +1039,12 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int void QComboBoxPrivate::_q_updateIndexBeforeChange() { - indexBeforeChange = currentIndex.row(); + indexBeforeChange = currentIndex; } void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/) { Q_Q(QComboBox); - if (parent != root) - return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { sizeHint = QSize(); @@ -1054,13 +1053,13 @@ void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, } // model has changed the currentIndex - if (currentIndex.row() != indexBeforeChange) { + if (currentIndex != indexBeforeChange) { if (!currentIndex.isValid() && q->count()) { - q->setCurrentIndex(qMin(q->count() - 1, qMax(indexBeforeChange, 0))); + q->setCurrentIndex(qMin(q->count() - 1, qMax(indexBeforeChange.row(), 0))); // TODO return; } if (lineEdit) { - lineEdit->setText(q->itemText(currentIndex.row())); + lineEdit->setText(itemText(currentIndex)); updateLineEditGeometry(); } q->update(); @@ -1233,7 +1232,7 @@ void QComboBoxPrivate::_q_itemSelected(const QModelIndex &item) setCurrentIndex(item); } else if (lineEdit) { lineEdit->selectAll(); - lineEdit->setText(q->itemText(currentIndex.row())); + lineEdit->setText(itemText(currentIndex)); } emitActivated(currentIndex); } @@ -1246,6 +1245,7 @@ void QComboBoxPrivate::emitActivated(const QModelIndex &index) QString text(itemText(index)); emit q->activated(index.row()); emit q->activated(text); + emit q->activated(index); } void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index) @@ -1256,6 +1256,7 @@ void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index) QString text(itemText(index)); emit q->highlighted(index.row()); emit q->highlighted(text); + emit q->highlighted(index); } void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) @@ -1263,6 +1264,7 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) Q_Q(QComboBox); emit q->currentIndexChanged(index.row()); emit q->currentIndexChanged(itemText(index)); + emit q->currentModelIndexChanged(index); } QString QComboBoxPrivate::itemText(const QModelIndex &index) const @@ -2005,6 +2007,24 @@ void QComboBox::setCurrentIndex(int index) d->setCurrentIndex(mi); } +/*! + \property QComboBox::currentModelIndex + \brief the index of the current item in the combobox. + + The model index of the current item in the combobox. +*/ +QModelIndex QComboBox::currentModelIndex() const +{ + Q_D(const QComboBox); + return d->currentIndex; +} + +void QComboBox::setCurrentModelIndex(const QModelIndex &index) +{ + Q_D(QComboBox); + d->setCurrentIndex(index); +} + void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) { Q_Q(QComboBox); @@ -2012,7 +2032,7 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) if (indexChanged) currentIndex = QPersistentModelIndex(mi); if (lineEdit) { - QString newText = q->itemText(currentIndex.row()); + QString newText = itemText(currentIndex); if (lineEdit->text() != newText) lineEdit->setText(newText); updateLineEditGeometry(); @@ -3077,9 +3097,8 @@ 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()) { + if (currentIndex != view->currentIndex()) { setCurrentIndex(view->currentIndex()); emitActivated(currentIndex); } diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index fb9af9f..fe6d934 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -69,6 +69,7 @@ class Q_GUI_EXPORT QComboBox : public QWidget Q_PROPERTY(int count READ count) Q_PROPERTY(QString currentText READ currentText) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(QModelIndex currentModelIndex READ currentModelIndex WRITE setCurrentModelIndex NOTIFY currentModelIndexChanged) Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems) Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount) Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy) @@ -182,6 +183,7 @@ public: void setModelColumn(int visibleColumn); int currentIndex() const; + QModelIndex currentModelIndex() const; QString currentText() const; @@ -223,15 +225,19 @@ public Q_SLOTS: void clearEditText(); void setEditText(const QString &text); void setCurrentIndex(int index); + void setCurrentModelIndex(const QModelIndex &index); Q_SIGNALS: void editTextChanged(const QString &); void activated(int index); void activated(const QString &); + void activated(const QModelIndex &); void highlighted(int index); void highlighted(const QString &); + void highlighted(const QModelIndex &); void currentIndexChanged(int index); void currentIndexChanged(const QString &); + void currentModelIndexChanged(const QModelIndex &index); protected: void focusInEvent(QFocusEvent *e); diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index 29a628c..fc6cd59 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -406,7 +406,7 @@ public: QPersistentModelIndex currentIndex; QPersistentModelIndex root; Qt::CaseSensitivity autoCompletionCaseSensitivity; - int indexBeforeChange; + QModelIndex indexBeforeChange; #ifndef QT_NO_COMPLETER QPointer completer; #endif diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 1fcea9e..36879d1 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -125,6 +125,7 @@ private slots: void modelDeleted(); void setMaxCount(); void setCurrentIndex(); + void setCurrentModelIndex(); void convenienceViews(); void findText_data(); void findText(); @@ -157,6 +158,7 @@ private slots: void keyBoardNavigationWithMouse(); void task_QTBUG_1071_changingFocusEmitsActivated(); void maxVisibleItems(); + void modelChanges(); protected slots: void onEditTextChanged( const QString &newString ); @@ -1366,6 +1368,33 @@ void tst_QComboBox::setCurrentIndex() QCOMPARE(testWidget->currentText(), QString("foo")); } +void tst_QComboBox::setCurrentModelIndex() +{ + QStandardItemModel treeModel; + QStandardItem *item1 = new QStandardItem("item1"); + item1->appendRow(new QStandardItem("item1a")); + item1->appendRow(new QStandardItem("item1b")); + QStandardItem *item2 = new QStandardItem("item2"); + treeModel.appendRow(item1); + treeModel.appendRow(item2); + + + QComboBox treeCombo; + treeCombo.setModel(&treeModel); + + treeCombo.setCurrentModelIndex(item1->index()); + QCOMPARE(treeCombo.currentModelIndex(), item1->index()); + QCOMPARE(treeCombo.currentText(), QString("item1")); + + treeCombo.setCurrentModelIndex(item1->child(0)->index()); + QCOMPARE(treeCombo.currentModelIndex(), item1->child(0)->index()); + QCOMPARE(treeCombo.currentText(), QString("item1a")); + + treeCombo.setCurrentModelIndex(QModelIndex()); + QCOMPARE(treeCombo.currentModelIndex(), QModelIndex()); + QCOMPARE(treeCombo.currentText(), QString()); +} + void tst_QComboBox::editTextChanged() { QCOMPARE(testWidget->count(), 0); @@ -2558,6 +2587,34 @@ void tst_QComboBox::maxVisibleItems() // QCombobox without a popup does not work, see QTBUG-760 } +void tst_QComboBox::modelChanges() +{ + QComboBox comboBox; + QLineEdit lineEdit; + + comboBox.setLineEdit(&lineEdit); + + QStandardItemModel treeModel; + QStandardItem *item1 = new QStandardItem("item1"); + QStandardItem *item1a = new QStandardItem("item1a"); + QStandardItem *item2 = new QStandardItem("item2"); + treeModel.appendRow(item1); + item1->appendRow(item1a); + treeModel.appendRow(item2); + + comboBox.setModel(&treeModel); + + comboBox.setCurrentModelIndex(item1->index()); + QCOMPARE(lineEdit.text(), QLatin1String("item1")); + item1->setText("ITEM1"); + QCOMPARE(lineEdit.text(), QLatin1String("ITEM1")); + + comboBox.setCurrentModelIndex(item1a->index()); + QCOMPARE(lineEdit.text(), QLatin1String("item1a")); + item1a->setText("ITEM1a"); + QCOMPARE(lineEdit.text(), QLatin1String("ITEM1a")); + +} QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc"