Skip to content

Commit

Permalink
MIDI Input editor: allow selecting multiple Options
Browse files Browse the repository at this point in the history
  • Loading branch information
ronso0 committed Nov 24, 2023
1 parent 91c1869 commit 9247ac6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 18 deletions.
73 changes: 55 additions & 18 deletions src/controllers/delegates/midioptionsdelegate.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "controllers/delegates/midioptionsdelegate.h"

#include <QComboBox>
#include <QStandardItemModel>

#include "controllers/midi/midimessage.h"
#include "controllers/midi/midiutils.h"
#include "moc_midioptionsdelegate.cpp"
#include "util/parented_ptr.h"

namespace {

Expand Down Expand Up @@ -41,12 +43,16 @@ QWidget* MidiOptionsDelegate::createEditor(QWidget* parent,
const QModelIndex& index) const {
Q_UNUSED(option);
Q_UNUSED(index);
QComboBox* pComboBox = new QComboBox(parent);

for (const MidiOption choice : kMidiOptions) {
pComboBox->addItem(MidiUtils::midiOptionToTranslatedString(choice),
static_cast<uint16_t>(choice));
}
// Create and connect the box. It'll be opulated in seteditorData().
QComboBox* pComboBox = make_parented<QComboBox>(parent);
// Clicking an option or pressing Enter on a selected option toggles it,
// closes the list view and commits the updated data.
// Press Space in list view only toggles the check state.
connect(pComboBox,
QOverload<int>::of(&QComboBox::activated),
this,
&MidiOptionsDelegate::commitAndCloseEditor);

return pComboBox;
}
Expand All @@ -66,28 +72,59 @@ QString MidiOptionsDelegate::displayText(const QVariant& value,

void MidiOptionsDelegate::setEditorData(QWidget* editor,
const QModelIndex& index) const {
MidiOptions options = index.data(Qt::EditRole).value<MidiOptions>();

QComboBox* pComboBox = qobject_cast<QComboBox*>(editor);
if (pComboBox == nullptr) {
auto* pComboBox = qobject_cast<QComboBox*>(editor);
if (!pComboBox) {
return;
}
for (int i = 0; i < pComboBox->count(); ++i) {
if (MidiOptions(pComboBox->itemData(i).toInt()) & options) {
pComboBox->setCurrentIndex(i);
return;
}

MidiOptions options = index.data(Qt::EditRole).value<MidiOptions>();
auto* pModel = static_cast<QStandardItemModel*>(pComboBox->model());
DEBUG_ASSERT(pModel);
for (const MidiOption opt : kMidiOptions) {
QStandardItem* pItem =
new QStandardItem(MidiUtils::midiOptionToTranslatedString(opt));
pItem->setData(static_cast<uint16_t>(opt));
pItem->setCheckable(true);
pItem->setCheckState(options.testFlag(opt) ? Qt::Checked : Qt::Unchecked);
pModel->appendRow(pItem);
}

// Show popup immediately, don't require another click
pComboBox->showPopup();
}

void MidiOptionsDelegate::setModelData(QWidget* editor,
QAbstractItemModel* model,
const QModelIndex& index) const {
MidiOptions options;
QComboBox* pComboBox = qobject_cast<QComboBox*>(editor);
if (pComboBox == nullptr) {
// Collect checked options and write them back to the model
auto* pComboBox = qobject_cast<QComboBox*>(editor);
if (!pComboBox) {
return;
}
options = MidiOptions(pComboBox->itemData(pComboBox->currentIndex()).toInt());

auto* pModel = static_cast<QStandardItemModel*>(pComboBox->model());
DEBUG_ASSERT(pModel);
MidiOptions options;
for (int i = 0; i < pModel->rowCount(); i++) {
auto* pItem = pModel->item(i);
// Only check for Qt::Checked or else, ignore Qt::PartiallyChecked
options.setFlag(static_cast<MidiOption>(pItem->data().toUInt()),
pItem->checkState() == Qt::Checked);
}
model->setData(index, QVariant::fromValue(options), Qt::EditRole);
}

void MidiOptionsDelegate::commitAndCloseEditor(int index) {
QComboBox* pComboBox = qobject_cast<QComboBox*>(sender());
if (!pComboBox) {
return;
}
auto* pModel = static_cast<QStandardItemModel*>(pComboBox->model());
DEBUG_ASSERT(pModel);
auto* pItem = pModel->item(index);
DEBUG_ASSERT(pItem);
pItem->setCheckState(pItem->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);

emit commitData(pComboBox);
emit closeEditor(pComboBox);
}
3 changes: 3 additions & 0 deletions src/controllers/delegates/midioptionsdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ class MidiOptionsDelegate : public QStyledItemDelegate {

void setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const;

private slots:
void commitAndCloseEditor(int index);
};

0 comments on commit 9247ac6

Please sign in to comment.