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; } }