Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the star ratings in the tracks view editable via keyboard #13717

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions res/skins/Deere/style.qss
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ WLibrary QPlainTextEdit,
WBeatSpinBox,
/* Track label inline editor */
WTrackPropertyEditor,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
color: #ddd;
background-color: #0f0f0f;
Expand All @@ -293,6 +295,8 @@ WTrackPropertyEditor,
}
WLibrary QLineEdit,
WTrackPropertyEditor,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
border: 1px solid #006596;
}
Expand Down
2 changes: 2 additions & 0 deletions res/skins/LateNight/style_classic.qss
Original file line number Diff line number Diff line change
Expand Up @@ -2191,6 +2191,8 @@ WLibrarySidebar {
/* Table cell in edit mode */
WLibrary QLineEdit,
WLibrary QPlainTextEdit,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox,
/* Track label inline editor in decks and samplers */
WTrackPropertyEditor,
Expand Down
4 changes: 4 additions & 0 deletions res/skins/LateNight/style_palemoon.qss
Original file line number Diff line number Diff line change
Expand Up @@ -2607,6 +2607,8 @@ WSearchLineEdit,
WTrackPropertyEditor,
WLibrary QLineEdit,
WLibrary QPlainTextEdit,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#spinBoxTransition,
#LibraryBPMSpinBox {
background-color: #0f0f0f;
Expand Down Expand Up @@ -2675,6 +2677,8 @@ WTrackTableView {
/* Table cell in edit mode */
WLibrary QLineEdit,
WLibrary QPlainTextEdit,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox,
/* Track label inline editor in decks and samplers */
WTrackPropertyEditor {
Expand Down
4 changes: 4 additions & 0 deletions res/skins/Shade/style.qss
Original file line number Diff line number Diff line change
Expand Up @@ -571,13 +571,17 @@ WTrackTableView {
WLibrary QPlainTextEdit,
/* Track label inline editor in decks and samplers */
WTrackPropertyEditor,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
color: #ddd;
background-color: #0f0f0f;
selection-color: #000;
selection-background-color: #ccc;
}
WLibrary QLineEdit,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
border: 1px solid #656d75;
}
Expand Down
2 changes: 2 additions & 0 deletions res/skins/Shade/style_dark.qss
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ WTrackTableView {
WLibrary QPlainTextEdit,
/* Track label inline editor in decks and samplers */
WTrackPropertyEditor,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
color: #ddd;
background-color: #0f0f0f;
Expand Down
4 changes: 4 additions & 0 deletions res/skins/Tango/style.qss
Original file line number Diff line number Diff line change
Expand Up @@ -2661,6 +2661,8 @@ WTrackTableView {
WLibrary QPlainTextEdit,
/* Track label inline editor in decks and samplers */
WTrackPropertyEditor,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
color: #ddd;
background-color: #0f0f0f;
Expand All @@ -2670,6 +2672,8 @@ WTrackTableView {
border-style: solid;
}
WLibrary QLineEdit,
#LibraryStarEditor[isKeyboardEditMode="true"],
#LibraryStarEditor[isKeyboardEditMode="true"]::item,
#LibraryBPMSpinBox {
border-color: #555;
}
Expand Down
138 changes: 124 additions & 14 deletions src/library/tabledelegates/stardelegate.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
#include "library/tabledelegates/stardelegate.h"

#include <QTableView>
#include <QTimer>

#include "library/starrating.h"
#include "library/tabledelegates/stareditor.h"
#include "library/tabledelegates/tableitemdelegate.h"
#include "moc_stardelegate.cpp"
#include "widget/wtracktableview.h"

StarDelegate::StarDelegate(QTableView* pTableView)
: TableItemDelegate(pTableView),
m_isOneCellInEditMode(false) {
m_persistentEditorState(PersistentEditor_NotOpen) {
connect(this, &QAbstractItemDelegate::closeEditor, this, &StarDelegate::closingEditor);
connect(pTableView, &QTableView::entered, this, &StarDelegate::cellEntered);
connect(pTableView, &QTableView::viewportEntered, this, &StarDelegate::cursorNotOverAnyCell);

auto* pTrackTableView = qobject_cast<WTrackTableView*>(pTableView);
if (pTrackTableView) {
connect(pTrackTableView,
&WTrackTableView::viewportLeaving,
this,
&StarDelegate::cursorNotOverAnyCell);
connect(pTrackTableView,
&WTrackTableView::editRequested,
this,
&StarDelegate::editRequested);
}
}

void StarDelegate::paintItem(
Expand Down Expand Up @@ -43,8 +59,15 @@ QWidget* StarDelegate::createEditor(QWidget* parent,
QStyleOptionViewItem newOption = option;
initStyleOption(&newOption, index);

StarEditor* editor =
new StarEditor(parent, m_pTableView, index, newOption, m_focusBorderColor);
StarEditor* editor = new StarEditor(parent,
m_pTableView,
index,
newOption,
m_persistentEditorState != PersistentEditor_Opening);

editor->setObjectName("LibraryStarEditor");
editor->ensurePolished();

connect(editor,
&StarEditor::editingFinished,
this,
Expand All @@ -68,24 +91,111 @@ void StarDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
void StarDelegate::commitAndCloseEditor() {
StarEditor* editor = qobject_cast<StarEditor*>(sender());
emit commitData(editor);
emit closeEditor(editor);
emit closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
}

void StarDelegate::closingEditor(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) {
Q_UNUSED(hint);

auto* editor = qobject_cast<StarEditor*>(widget);
VERIFY_OR_DEBUG_ASSERT(editor) {
return;
}

restorePersistentRatingEditor(editor->getModelIndex());
}

void StarDelegate::editRequested(const QModelIndex& index,
QAbstractItemView::EditTrigger trigger,
QEvent* event) {
Q_UNUSED(event);

// This slot is called when an edit is requested for ANY cell on the
// QTableView but the code should only be executed on a column with a
// StarRating.
if (trigger == QAbstractItemView::EditTrigger::EditKeyPressed &&
m_persistentEditorState == PersistentEditor_Open &&
index.data().canConvert<StarRating>() &&
m_currentEditedCellIndex == index) {
// Close the (implicit) persistent editor for the current cell,
// so that a new explicit editor can be opened instead.
closeCurrentPersistentRatingEditor(true);
}
}

void StarDelegate::cellEntered(const QModelIndex& index) {
// This slot is called if the mouse pointer enters ANY cell on the
// QTableView but the code should only be executed on a column with a
// StarRating.
if (index.data().canConvert<StarRating>()) {
if (m_isOneCellInEditMode) {
// Don't close other editors when hovering the stars cell!
m_pTableView->closePersistentEditor(m_currentEditedCellIndex);
}
m_pTableView->openPersistentEditor(index);
m_isOneCellInEditMode = true;
m_currentEditedCellIndex = index;
} else if (m_isOneCellInEditMode) {
m_isOneCellInEditMode = false;
openPersistentRatingEditor(index);
} else {
closeCurrentPersistentRatingEditor(false);
}
}

void StarDelegate::cursorNotOverAnyCell() {
// Invoked when the mouse cursor is not over any specific cell,
// or when the mouse cursor has left the table area
closeCurrentPersistentRatingEditor(false);
}

void StarDelegate::openPersistentRatingEditor(const QModelIndex& index) {
// Qt6: Check whether a non-persistent editor exists at index.
// QTableView::closePersistentEditor() would also close
// a non-persistent editor, so we have to make sure to
// not call it if an editor already exists.
if (m_pTableView->indexWidget(index)) {
return;
}

// Close the previously open persistent rating editor
if (m_persistentEditorState == PersistentEditor_Open) {
// Don't close other editors when hovering the stars cell!
m_pTableView->closePersistentEditor(m_currentEditedCellIndex);
}

m_persistentEditorState = PersistentEditor_NotOpen;
m_persistentEditorState = PersistentEditor_Opening;
m_pTableView->openPersistentEditor(index);
m_persistentEditorState = PersistentEditor_Open;
m_currentEditedCellIndex = index;
}

void StarDelegate::closeCurrentPersistentRatingEditor(bool rememberForRestore) {
if (m_persistentEditorState == PersistentEditor_Open) {
m_pTableView->closePersistentEditor(m_currentEditedCellIndex);
m_currentEditedCellIndex = QModelIndex();
}

if (rememberForRestore &&
(m_persistentEditorState == PersistentEditor_Open ||
m_persistentEditorState == PersistentEditor_ShouldRestore)) {
// Keep m_currentEditedCellIndex so the persistent editor
// can be restored when the currently active explicit editor
// is closed.
m_persistentEditorState = PersistentEditor_ShouldRestore;
} else {
m_persistentEditorState = PersistentEditor_NotOpen;
m_currentEditedCellIndex = QPersistentModelIndex();
}
}

void StarDelegate::restorePersistentRatingEditor(const QModelIndex& index) {
if (m_persistentEditorState == PersistentEditor_ShouldRestore &&
index.isValid() && m_currentEditedCellIndex == index) {
// Avoid race conditions by deferring the restore until
// we have returned to the event loop, and the closing of
// the current editor has been finished. Otherwise,
// the internal state of QAbstractItemView may become
// inconsistent.
m_persistentEditorState = PersistentEditor_InDeferredRestore;
QTimer::singleShot(0, this, &StarDelegate::restorePersistentRatingEditorNow);
}
}

void StarDelegate::restorePersistentRatingEditorNow() {
if (m_persistentEditorState == PersistentEditor_InDeferredRestore &&
m_currentEditedCellIndex.isValid()) {
openPersistentRatingEditor(m_currentEditedCellIndex);
}
}
22 changes: 21 additions & 1 deletion src/library/tabledelegates/stardelegate.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <QAbstractItemView>

#include "library/tabledelegates/tableitemdelegate.h"

class StarDelegate : public TableItemDelegate {
Expand Down Expand Up @@ -31,9 +33,27 @@ class StarDelegate : public TableItemDelegate {

private slots:
void commitAndCloseEditor();
void closingEditor(QWidget* widget, QAbstractItemDelegate::EndEditHint hint);
void cellEntered(const QModelIndex& index);
void cursorNotOverAnyCell();
void editRequested(const QModelIndex& index,
QAbstractItemView::EditTrigger trigger,
QEvent* event);
void restorePersistentRatingEditorNow();

private:
void openPersistentRatingEditor(const QModelIndex& index);
void closeCurrentPersistentRatingEditor(bool rememberForRestore);
void restorePersistentRatingEditor(const QModelIndex& index);

enum PersistentEditorState {
PersistentEditor_NotOpen,
PersistentEditor_Opening,
PersistentEditor_Open,
PersistentEditor_ShouldRestore,
PersistentEditor_InDeferredRestore
};

QPersistentModelIndex m_currentEditedCellIndex;
bool m_isOneCellInEditMode;
PersistentEditorState m_persistentEditorState;
};
Loading
Loading