Stabilized ListEditDelegate (#4725)

* The fields using a ListEditDelegate were not editable any more (the
  action buttons didn't react to interactions)
* Refactored ListEditWidget / ListEditDelegate to a similar pattern like
  in #4720
This commit is contained in:
Joachim Kohlhammer
2025-11-01 15:00:27 +01:00
committed by GitHub
parent c8da333ab0
commit 78da128849
3 changed files with 81 additions and 88 deletions

View File

@@ -2216,8 +2216,6 @@ KeywordsPage::KeywordsPage(MetadataPage *parent, QList<KeywordDefinition>keyword
HelpWhatsThis *help = new HelpWhatsThis(this);
this->setWhatsThis(help->getWhatsThisText(HelpWhatsThis::Preferences_DataFields_Notes_Keywords));
relatedDelegate.setTitle(tr("<h3>Alternative Keywords</h3>Add additional keyword to have the same color"));
QHBoxLayout *field = new QHBoxLayout();
fieldLabel = new QLabel(tr("Field"),this);
fieldChooser = new QComboBox(this);
@@ -2276,6 +2274,19 @@ KeywordsPage::KeywordsPage(MetadataPage *parent, QList<KeywordDefinition>keyword
connect(actionButtons, &ActionButtonBox::addRequested, this, &KeywordsPage::addClicked);
connect(actionButtons, &ActionButtonBox::deleteRequested, this, &KeywordsPage::deleteClicked);
connect(fieldChooser, SIGNAL(currentIndexChanged(int)), this, SLOT(colorfieldChanged()));
QAbstractItemModel *model = keywords->model();
connect(&relatedDelegate, &ListEditDelegate::requestListEdit, this, [this, model](const QModelIndex &index) {
ListEditWidget *dlg = new ListEditWidget(nullptr);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setTitle(tr("<h3>Alternative Keywords</h3>Add additional keyword to have the same color"));
dlg->setList(model->data(index, Qt::DisplayRole).toString().split(','));
dlg->showDialog(this);
connect(dlg, &ListEditWidget::editingFinished, this, [model, index, dlg](const QStringList &newList) {
model->setData(index, newList.join(','), Qt::EditRole);
dlg->deleteLater();
});
});
keywords->setCurrentItem(keywords->invisibleRootItem()->child(0));
}
@@ -2936,12 +2947,7 @@ FieldsPage::FieldsPage(QWidget *parent, QList<FieldDefinition>fieldDefinitions)
HelpWhatsThis *help = new HelpWhatsThis(this);
this->setWhatsThis(help->getWhatsThisText(HelpWhatsThis::Preferences_DataFields_Fields));
valueDelegate.setTitle(tr("<h3>Manage allowed values</h3>"
"If the list is empty, any value is accepted. A list containing "
"<tt>*</tt> as its only entry indicates previous values for the "
"same field will be used to autocomplete input."));
valueDelegate.setDisplayLength(15, 2);
fields = new QTreeWidget;
fields->headerItem()->setText(0, tr("Screen Tab"));
fields->headerItem()->setText(1, tr("Field"));
@@ -2999,6 +3005,23 @@ FieldsPage::FieldsPage(QWidget *parent, QList<FieldDefinition>fieldDefinitions)
connect(actionButtons, &ActionButtonBox::downRequested, this, &FieldsPage::downClicked);
connect(actionButtons, &ActionButtonBox::addRequested, this, &FieldsPage::addClicked);
connect(actionButtons, &ActionButtonBox::deleteRequested, this, &FieldsPage::deleteClicked);
QAbstractItemModel *model = fields->model();
connect(&valueDelegate, &ListEditDelegate::requestListEdit, this, [this, model](const QModelIndex &index) {
ListEditWidget *dlg = new ListEditWidget(nullptr);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setTitle(tr("<h3>Manage allowed values</h3>"
"If the list is empty, any value is accepted. A list containing "
"<tt>*</tt> as its only entry indicates previous values for the "
"same field will be used to autocomplete input."));
dlg->setList(model->data(index, Qt::DisplayRole).toString().split(','));
dlg->showDialog(this);
connect(dlg, &ListEditWidget::editingFinished, this, [model, index, dlg](const QStringList &newList) {
model->setData(index, newList.join(','), Qt::EditRole);
dlg->deleteLater();
});
});
fields->setCurrentItem(fields->invisibleRootItem()->child(0));
}
@@ -3795,6 +3818,18 @@ MeasuresConfigPage::MeasuresConfigPage(QWidget *parent, Context *context) :
connect(measuresActions, &ActionButtonBox::deleteRequested, this, &MeasuresConfigPage::removeMeasuresClicked);
connect(measureFieldsActions, &ActionButtonBox::addRequested, this, &MeasuresConfigPage::addMeasuresFieldClicked);
connect(measureFieldsActions, &ActionButtonBox::deleteRequested, this, &MeasuresConfigPage::removeMeasuresFieldClicked);
QAbstractItemModel *model = measuresFieldsTable->model();
connect(&meFiHeaderDelegate, &ListEditDelegate::requestListEdit, this, [this, model](const QModelIndex &index) {
ListEditWidget *dlg = new ListEditWidget(nullptr);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setList(model->data(index, Qt::DisplayRole).toString().split(','));
dlg->showDialog(this);
connect(dlg, &ListEditWidget::editingFinished, this, [model, index, dlg](const QStringList &newList) {
model->setData(index, newList.join(','), Qt::EditRole);
dlg->deleteLater();
});
});
refreshMeasuresTable();
}

View File

@@ -627,9 +627,6 @@ ListEditWidget::ListEditWidget
(QWidget *parent)
: QWidget(parent)
{
dialog = new QDialog(parent);
dialog->setModal(true);
title = new QLabel();
title->setWordWrap(true);
title->setVisible(false);
@@ -645,23 +642,11 @@ ListEditWidget::ListEditWidget
actionButtons->defaultConnect(ActionButtonBox::UpDownGroup, listWidget);
actionButtons->defaultConnect(ActionButtonBox::AddDeleteGroup, listWidget);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
QVBoxLayout *dialogLayout = new QVBoxLayout(dialog);
dialogLayout->addWidget(title);
dialogLayout->addWidget(listWidget);
dialogLayout->addWidget(actionButtons);
dialogLayout->addSpacing(10 * dpiYFactor);
dialogLayout->addWidget(buttons);
connect(listWidget, &QListWidget::itemChanged, this, &ListEditWidget::itemChanged);
connect(actionButtons, &ActionButtonBox::upRequested, this, &ListEditWidget::moveUp);
connect(actionButtons, &ActionButtonBox::downRequested, this, &ListEditWidget::moveDown);
connect(actionButtons, &ActionButtonBox::addRequested, this, &ListEditWidget::addItem);
connect(actionButtons, &ActionButtonBox::deleteRequested, this, &ListEditWidget::deleteItem);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
connect(dialog, &QDialog::finished, this, &ListEditWidget::dialogFinished);
}
@@ -669,12 +654,8 @@ void
ListEditWidget::setTitle
(const QString &text)
{
if (text.trimmed().size() > 0) {
title->setText(text);
title->setVisible(true);
} else {
title->setVisible(false);
}
title->setVisible(! text.trimmed().isEmpty());
title->setText(text);
}
@@ -702,8 +683,25 @@ ListEditWidget::getList
void
ListEditWidget::showDialog
()
(QWidget *owner)
{
dialog = new QDialog(owner);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowModality(Qt::ApplicationModal);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
QVBoxLayout *layout = new QVBoxLayout(dialog);
layout->addWidget(title);
layout->addWidget(listWidget);
layout->addWidget(actionButtons);
layout->addSpacing(10 * dpiYFactor);
layout->addWidget(buttons);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
connect(dialog, &QDialog::finished, this, &ListEditWidget::dialogFinished);
dialog->show();
}
@@ -727,8 +725,8 @@ ListEditWidget::dialogFinished
for (int i = 0; i < listWidget->count(); ++i) {
data << listWidget->item(i)->data(Qt::DisplayRole).toString().trimmed();
}
emit editingFinished(data);
}
emit editingFinished();
}
@@ -768,21 +766,18 @@ void
ListEditWidget::addItem
()
{
int index = listWidget->count();
if (listWidget->currentItem() != nullptr) {
index = listWidget->row(listWidget->currentItem());
}
int index = listWidget->currentRow();
if (index < 0) {
index = 0;
}
QListWidgetItem *add = new QListWidgetItem();
add->setFlags(add->flags() | Qt::ItemIsEditable);
listWidget->insertItem(index, add);
QString text = tr("New");
for (int i = 0; listWidget->findItems(text, Qt::MatchExactly).count() > 0; ++i) {
text = tr("New (%1)").arg(i + 1);
}
add->setData(Qt::DisplayRole, text);
listWidget->insertItem(index, add);
listWidget->setCurrentItem(add);
listWidget->editItem(add);
}
@@ -798,7 +793,6 @@ ListEditWidget::deleteItem
}
// ListEditDelegate ////////////////////////////////////////////////////////////////////
ListEditDelegate::ListEditDelegate
@@ -808,14 +802,6 @@ ListEditDelegate::ListEditDelegate
}
void
ListEditDelegate::setTitle
(const QString &title)
{
this->title = title;
}
void
ListEditDelegate::setDisplayLength
(int limit, int reduce)
@@ -831,32 +817,8 @@ ListEditDelegate::createEditor
{
Q_UNUSED(option)
Q_UNUSED(index)
ListEditWidget *editor = new ListEditWidget(parent);
editor->setTitle(title);
connect(editor, &ListEditWidget::editingFinished, this, &ListEditDelegate::commitAndCloseEditor);
editor->showDialog();
return editor;
}
void
ListEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
ListEditWidget *listEditor = static_cast<ListEditWidget*>(editor);
listEditor->setList(index.data(Qt::DisplayRole).toString().split(','));
}
void
ListEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
ListEditWidget *listEditor = static_cast<ListEditWidget*>(editor);
QString newValue = listEditor->getList().join(',');
if (model->data(index, Qt::EditRole).toString() != newValue) {
model->setData(index, newValue, Qt::EditRole);
}
emit requestListEdit(index);
return nullptr;
}

View File

@@ -204,16 +204,17 @@ private slots:
class ListEditWidget: public QWidget
{
Q_OBJECT
public:
ListEditWidget(QWidget *parent = nullptr);
explicit ListEditWidget(QWidget *parent = nullptr);
void setTitle(const QString &text);
void setList(const QStringList &list);
QStringList getList() const;
public slots:
void showDialog();
void showDialog(QWidget *owner = nullptr);
signals:
void editingFinished(const QStringList &newList);
private slots:
void itemChanged(QListWidgetItem *item);
@@ -223,16 +224,12 @@ private slots:
void addItem();
void deleteItem();
signals:
void editingFinished();
private:
QDialog *dialog = nullptr;
QLabel *title = nullptr;
QListWidget *listWidget = nullptr;
ActionButtonBox *actionButtons = nullptr;
QStringList data;
QDialog *dialog;
QLabel *title;
QListWidget *listWidget;
ActionButtonBox *actionButtons;
};
@@ -243,19 +240,18 @@ class ListEditDelegate: public QStyledItemDelegate
public:
ListEditDelegate(QObject *parent = nullptr);
void setTitle(const QString &title);
void setDisplayLength(int limit, int reduce = 2);
virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override;
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
virtual QString displayText(const QVariant &value, const QLocale &locale) const override;
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QString displayText(const QVariant &value, const QLocale &locale) const override;
signals:
void requestListEdit(const QModelIndex &index) const;
private slots:
void commitAndCloseEditor();
private:
QString title;
int limit = -1;
int reduce = 2;
};