From fbb2f70747e4d8257230964e0940aecdb075f8a4 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 28 May 2024 13:54:37 +0200 Subject: [PATCH] Utils: Implement StringListAspect::addToLayout Change-Id: I48806e397a8fa51c9b31860645a16c242e789a3d Reviewed-by: hjk --- src/libs/utils/aspects.cpp | 143 +++++++++++++++++++++++++++++++++++-- src/libs/utils/aspects.h | 11 +++ 2 files changed, 149 insertions(+), 5 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index e9552c1e1ed..25a21fb7397 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include using namespace Layouting; @@ -931,6 +932,10 @@ public: class StringListAspectPrivate { public: + UndoableValue undoable; + bool allowAdding{true}; + bool allowRemoving{true}; + bool allowEditing{true}; }; class FilePathListAspectPrivate @@ -2629,13 +2634,115 @@ StringListAspect::StringListAspect(AspectContainer *container) */ StringListAspect::~StringListAspect() = default; -/*! - \reimp -*/ +bool StringListAspect::guiToBuffer() +{ + const QStringList newValue = d->undoable.get(); + if (newValue != m_buffer) { + m_buffer = newValue; + return true; + } + return false; +} + +void StringListAspect::bufferToGui() +{ + d->undoable.setWithoutUndo(m_buffer); +} + void StringListAspect::addToLayout(Layout &parent) { - Q_UNUSED(parent) - // TODO - when needed. + d->undoable.setSilently(value()); + + auto editor = new QTreeWidget(); + editor->setHeaderHidden(true); + editor->setRootIsDecorated(false); + editor->setEditTriggers( + d->allowEditing ? QAbstractItemView::AllEditTriggers : QAbstractItemView::NoEditTriggers); + + QPushButton *add = d->allowAdding ? new QPushButton(Tr::tr("Add")) : nullptr; + QPushButton *remove = d->allowRemoving ? new QPushButton(Tr::tr("Remove")) : nullptr; + + auto itemsToStringList = [editor] { + QStringList items; + const QTreeWidgetItem *rootItem = editor->invisibleRootItem(); + for (int i = 0, count = rootItem->childCount(); i < count; ++i) { + auto expr = rootItem->child(i)->data(0, Qt::DisplayRole).toString(); + items.append(expr); + } + return items; + }; + + auto populate = [editor, this] { + editor->clear(); + for (const QString &entry : d->undoable.get()) { + auto item = new QTreeWidgetItem(editor, {entry}); + item->setData(0, Qt::ToolTipRole, entry); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable); + } + }; + + connect(add, &QPushButton::clicked, this, [this, populate, editor] { + d->undoable.setSilently(d->undoable.get() << ""); + populate(); + const QTreeWidgetItem *root = editor->invisibleRootItem(); + QTreeWidgetItem *lastChild = root->child(root->childCount() - 1); + const QModelIndex index = editor->indexFromItem(lastChild, 0); + editor->edit(index); + }); + + connect(remove, &QPushButton::clicked, this, [this, editor, itemsToStringList] { + const QList selected = editor->selectedItems(); + QTC_ASSERT(selected.size() == 1, return); + editor->invisibleRootItem()->removeChild(selected.first()); + delete selected.first(); + d->undoable.set(undoStack(), itemsToStringList()); + }); + + connect( + &d->undoable.m_signal, &UndoSignaller::changed, editor, [this, populate, itemsToStringList] { + if (itemsToStringList() != d->undoable.get()) + populate(); + + handleGuiChanged(); + }); + + connect( + editor->model(), + &QAbstractItemModel::dataChanged, + this, + [this, + itemsToStringList](const QModelIndex &tl, const QModelIndex &br, const QList &roles) { + if (!roles.contains(Qt::DisplayRole)) + return; + if (tl != br) + return; + d->undoable.set(undoStack(), itemsToStringList()); + }); + + populate(); + + parent.addItem( + // clang-format off + Column { + createLabel(), + Row { + editor, + If { d->allowAdding || d->allowRemoving, { + Column { + If { d->allowAdding, {add}, {}}, + If { d->allowRemoving, {remove}, {}}, + st, + } + }, {}}, + } + } // clang-format on + ); + + registerSubWidget(editor); + if (d->allowAdding) + registerSubWidget(add); + if (d->allowRemoving) + registerSubWidget(remove); } void StringListAspect::appendValue(const QString &s, bool allowDuplicates) @@ -2671,6 +2778,32 @@ void StringListAspect::removeValues(const QStringList &values) setValue(val); } +void StringListAspect::setUiAllowAdding(bool allowAdding) +{ + d->allowAdding = allowAdding; +} +void StringListAspect::setUiAllowRemoving(bool allowRemoving) +{ + d->allowRemoving = allowRemoving; +} +void StringListAspect::setUiAllowEditing(bool allowEditing) +{ + d->allowEditing = allowEditing; +} + +bool StringListAspect::uiAllowAdding() const +{ + return d->allowAdding; +} +bool StringListAspect::uiAllowRemoving() const +{ + return d->allowRemoving; +} +bool StringListAspect::uiAllowEditing() const +{ + return d->allowEditing; +} + /*! \class Utils::FilePathListAspect \inmodule QtCreator diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index 13c1c22e4fc..47aeb35458b 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -828,6 +828,9 @@ public: StringListAspect(AspectContainer *container = nullptr); ~StringListAspect() override; + bool guiToBuffer() override; + void bufferToGui() override; + void addToLayout(Layouting::Layout &parent) override; void appendValue(const QString &value, bool allowDuplicates = true); @@ -835,6 +838,14 @@ public: void appendValues(const QStringList &values, bool allowDuplicates = true); void removeValues(const QStringList &values); + void setUiAllowAdding(bool allowAdding); + void setUiAllowRemoving(bool allowRemoving); + void setUiAllowEditing(bool allowEditing); + + bool uiAllowAdding() const; + bool uiAllowRemoving() const; + bool uiAllowEditing() const; + private: std::unique_ptr d; };