void PlaylistView::moveItems(int steps) { PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model()); if (playlistModel == nullptr) { return; } QItemSelection indexList = this->selectionModel()->selection(); std::sort(indexList.begin(), indexList.end(), steps > 0 ? sortQItemSelectionDesc : sortQItemSelectionAsc); for (QItemSelection::const_iterator i = indexList.cbegin(); i != indexList.cend(); ++i) { int top = i->top(); int btm = i->bottom(); int count = abs(top - btm); int srcRow = min(top, btm); int destRow = srcRow + steps; QModelIndex newIdx = steps > 0 ? playlistModel->index(destRow + count, 0) : playlistModel->index(srcRow - 1, 0); QModelIndex oldIdx = steps > 0 ? playlistModel->index(srcRow, 0) : playlistModel->index(srcRow + count, 0); if (newIdx.isValid()) { this->selectionModel()->select(newIdx, QItemSelectionModel::SelectionFlag::Select | QItemSelectionModel::SelectionFlag::Rows); this->selectionModel()->select(oldIdx, QItemSelectionModel::SelectionFlag::Deselect | QItemSelectionModel::SelectionFlag::Rows); playlistModel->moveRows(playlistModel->index(0, 0), srcRow, count, playlistModel->index(playlistModel->rowCount(QModelIndex()) - 1, playlistModel->columnCount(QModelIndex()) - 1), destRow); } } }
void PlaylistView::keyPressEvent(QKeyEvent *event) { PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model()); if (playlistModel == nullptr) { return; } QModelIndex bot = playlistModel->index(playlistModel->rowCount(QModelIndex()) - 1, 0); QModelIndex top = playlistModel->index(0, 0); int key = event->key(); switch (key) { case Qt::Key_Delete: { QItemSelection indexList = this->selectionModel()->selection(); int lastCount = 0; for (QItemSelection::const_iterator i = indexList.cbegin(); i != indexList.cend(); ++i) { int btm = i->bottom(); int top = i->top(); if (btm < 0 || top < 0) { break; } lastCount = abs(top - btm) + 1; playlistModel->removeRows(min(btm, top), lastCount); } } break; case Qt::Key_W: this->moveItems(-1); break; case Qt::Key_S: this->moveItems(1); break; case Qt::Key_Home: case Qt::Key_End: if ((event->modifiers() & Qt::ShiftModifier) == Qt::ShiftModifier) { QModelIndex cur = this->currentIndex(); QItemSelectionRange aboveCur(top, cur); QItemSelection selection; selection.append(aboveCur); this->selectionModel()->select(selection, ((key == Qt::Key_Home) ? QItemSelectionModel::Select : QItemSelectionModel::Deselect) | QItemSelectionModel::Rows); selection.clear(); QItemSelectionRange belowCur(cur, bot); selection.append(belowCur); this->selectionModel()->select(selection, ((key == Qt::Key_Home) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select) | QItemSelectionModel::Rows); // make sure the current index is selected this->selectionModel()->select(this->currentIndex(), QItemSelectionModel::Select | QItemSelectionModel::Rows); break; } else if ((event->modifiers() & Qt::NoModifier) == Qt::NoModifier) { this->setCurrentIndex((key == Qt::Key_Home) ? top : bot); break; } else { [[fallthrough]]; } default: QTableView::keyPressEvent(event); break; } }