| 169 | } |
| 170 | |
| 171 | void ExpandingWidgetModel::rowSelected(const QModelIndex& idx_) |
| 172 | { |
| 173 | Q_ASSERT(idx_.model() == this); |
| 174 | |
| 175 | QModelIndex idx(firstColumn(idx_)); |
| 176 | if (!m_partiallyExpanded.contains(idx)) { |
| 177 | QModelIndex oldIndex = partiallyExpandedRow(); |
| 178 | //Unexpand the previous partially expanded row |
| 179 | if (!m_partiallyExpanded.isEmpty()) { ///@todo allow multiple partially expanded rows |
| 180 | while (!m_partiallyExpanded.isEmpty()) |
| 181 | m_partiallyExpanded.erase(m_partiallyExpanded.begin()); |
| 182 | //partiallyUnExpand( m_partiallyExpanded.begin().key() ); |
| 183 | } |
| 184 | //Notify the underlying models that the item was selected, and eventually get back the text for the expanding widget. |
| 185 | if (!idx.isValid()) { |
| 186 | //All items have been unselected |
| 187 | if (oldIndex.isValid()) { |
| 188 | emit dataChanged(oldIndex, oldIndex); |
| 189 | } |
| 190 | } else { |
| 191 | QVariant variant = data(idx, CodeCompletionModel::ItemSelected); |
| 192 | |
| 193 | if (!isExpanded(idx) && variant.typeId() == qMetaTypeId<QString>()) { |
| 194 | //Either expand upwards or downwards, choose in a way that |
| 195 | //the visible fields of the new selected entry are not moved. |
| 196 | if (oldIndex.isValid() && (oldIndex < idx || (!(oldIndex < idx) && oldIndex.parent() < idx.parent()))) { |
| 197 | m_partiallyExpanded.insert(idx, ExpandUpwards); |
| 198 | } else { |
| 199 | m_partiallyExpanded.insert(idx, ExpandDownwards); |
| 200 | } |
| 201 | |
| 202 | //Say that one row above until one row below has changed, so no items will need to be moved(the space that is taken from one item is given to the other) |
| 203 | if (oldIndex.isValid() && oldIndex < idx) { |
| 204 | emit dataChanged(oldIndex, idx); |
| 205 | |
| 206 | if (treeView()->verticalScrollMode() == QAbstractItemView::ScrollPerItem) { |
| 207 | const QModelIndex viewIndex = mapFromSource(idx); |
| 208 | //Qt fails to correctly scroll in ScrollPerItem mode, so the selected index is completely visible, |
| 209 | //so we do the scrolling by hand. |
| 210 | QRect selectedRect = treeView()->visualRect(viewIndex); |
| 211 | QRect frameRect = treeView()->frameRect(); |
| 212 | |
| 213 | if (selectedRect.bottom() > frameRect.bottom()) { |
| 214 | int diff = selectedRect.bottom() - frameRect.bottom(); |
| 215 | //We need to scroll down |
| 216 | QModelIndex newTopIndex = viewIndex; |
| 217 | |
| 218 | QModelIndex nextTopIndex = viewIndex; |
| 219 | QRect nextRect = treeView()->visualRect(nextTopIndex); |
| 220 | while (nextTopIndex.isValid() && nextRect.isValid() && nextRect.top() >= diff) { |
| 221 | newTopIndex = nextTopIndex; |
| 222 | nextTopIndex = treeView()->indexAbove(nextTopIndex); |
| 223 | if (nextTopIndex.isValid()) { |
| 224 | nextRect = treeView()->visualRect(nextTopIndex); |
| 225 | } |
| 226 | } |
| 227 | treeView()->scrollTo(newTopIndex, QAbstractItemView::PositionAtTop); |
| 228 | } |
no test coverage detected