[libraries/ktextaddons] textautogeneratetext: Prepare to implement textautogeneratetextpromptmodel

Laurent Montel <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 65b7a3e2ff6ab637688ebbe3c8c569d0d86d1481 by Laurent Montel.
Committed on 27/07/2026 at 20:21.
Pushed by mlaurent into branch 'master'.

Prepare to implement textautogeneratetextpromptmodel

M  +3    -0    textautogeneratetext/CMakeLists.txt
A  +237  -0    textautogeneratetext/core/models/textautogeneratetextpromptmodel.cpp     [License: GPL(v2.0+)]
A  +135  -0    textautogeneratetext/core/models/textautogeneratetextpromptmodel.h     [License: GPL(v2.0+)]

https://invent.kde.org/libraries/ktextaddons/-/commit/65b7a3e2ff6ab637688ebbe3c8c569d0d86d1481

diff --git a/textautogeneratetext/CMakeLists.txt b/textautogeneratetext/CMakeLists.txt
index 1fbc4ab8d..a2b31d90b 100644
--- a/textautogeneratetext/CMakeLists.txt
+++ b/textautogeneratetext/CMakeLists.txt
@@ -180,6 +180,8 @@ target_sources(
         core/models/textautogeneratetextinstancemodel.cpp
         core/models/textautogeneratetextinstancesortfilterproxymodel.h
         core/models/textautogeneratetextinstancesortfilterproxymodel.cpp
+        core/models/textautogeneratetextpromptmodel.cpp
+        core/models/textautogeneratetextpromptmodel.h
         core/localdatabase/textautogeneratelocaldatabaseutils.h
         core/localdatabase/textautogeneratelocaldatabaseutils.cpp
         core/localdatabase/textautogeneratelocaldatabaseabstract.h
@@ -557,6 +559,7 @@ ecm_generate_headers(TextAutoGenerateText_Camelcasestextautogeneratetextcoremode
     TextAutoGenerateMessagesModel
     TextAutoGenerateSearchMessagesModel
     TextAutoGenerateChatsModel
+    TextAutoGenerateTextPromptModel
     REQUIRED_HEADERS TextAutoGenerateText_textautogeneratetextcoremodels_HEADERS
     PREFIX TextAutoGenerateText
     RELATIVE core/models
diff --git a/textautogeneratetext/core/models/textautogeneratetextpromptmodel.cpp b/textautogeneratetext/core/models/textautogeneratetextpromptmodel.cpp
new file mode 100644
index 000000000..439802910
--- /dev/null
+++ b/textautogeneratetext/core/models/textautogeneratetextpromptmodel.cpp
@@ -0,0 +1,237 @@
+/*
+  SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+  SPDX-License-Identifier: GPL-2.0-or-later
+*/
+#include "textautogeneratetextpromptmodel.h"
+#include "core/textautogeneratetextplugin.h"
+#include "textautogeneratetextcore_debug.h"
+
+using namespace TextAutoGenerateText;
+TextAutoGenerateTextPromptModel::TextAutoGenerateTextPromptModel(QObject *parent)
+    : QAbstractListModel{parent}
+{
+}
+
+TextAutoGenerateTextPromptModel::~TextAutoGenerateTextPromptModel()
+{
+    qDeleteAll(mTextInstances);
+}
+
+int TextAutoGenerateTextPromptModel::rowCount(const QModelIndex &parent) const
+{
+    if (parent.isValid()) {
+        return 0; // flat model
+    }
+    return mTextInstances.count();
+}
+
+bool TextAutoGenerateTextPromptModel::setData(const QModelIndex &idx, const QVariant &value, int role)
+{
+    if (!idx.isValid() || idx.row() < 0 || idx.row() >= mTextInstances.count()) {
+        qCWarning(TEXTAUTOGENERATETEXT_CORE_LOG) << "ERROR: invalid index";
+        return false;
+    }
+    const int id = idx.row();
+    const auto &instance = mTextInstances[id];
+    switch (role) {
+    case Qt::CheckStateRole:
+    case InstanceRoles::Enabled:
+        instance->setEnabled(value.toBool());
+        Q_EMIT dataChanged(idx, idx, {InstanceRoles::Enabled});
+        return true;
+    default:
+        break;
+    }
+    return QAbstractListModel::setData(idx, value, role);
+}
+
+QVariant TextAutoGenerateTextPromptModel::data(const QModelIndex &index, int role) const
+{
+    if (index.row() < 0 || index.row() >= mTextInstances.count()) {
+        return {};
+    }
+    const auto &instance = mTextInstances[index.row()];
+    switch (role) {
+    case Qt::DisplayRole:
+    case InstanceRoles::Name:
+        return instance->displayName();
+    case InstanceRoles::PluginName:
+        return instance->pluginName();
+    case InstanceRoles::Uuid:
+        return instance->instanceUuid();
+    case InstanceRoles::PluginIdentifier:
+        return instance->pluginIdentifier();
+    case InstanceRoles::Plugin:
+        return QVariant::fromValue(instance->plugin());
+    case Qt::CheckStateRole:
+        return instance->enabled() ? Qt::Checked : Qt::Unchecked;
+    case InstanceRoles::Enabled:
+        return instance->enabled();
+    case InstanceRoles::IsDefault:
+        return !instance->instanceUuid().isEmpty() && !mCurrentinstance.isEmpty() && (instance->instanceUuid() == mCurrentinstance) && instance->enabled();
+    case InstanceRoles::TranslatedPluginName:
+        return instance->plugin()->translatedPluginName();
+    default:
+        break;
+    }
+    return {};
+}
+
+QStringList TextAutoGenerateTextPromptModel::instanceDisplayNames() const
+{
+    QStringList lstDisplayNames;
+    lstDisplayNames.reserve(mTextInstances.size());
+    for (const auto &inst : mTextInstances) {
+        lstDisplayNames.append(inst->displayName());
+    }
+    return lstDisplayNames;
+}
+
+QList<TextAutoGenerateTextInstance *> TextAutoGenerateTextPromptModel::textInstances() const
+{
+    return mTextInstances;
+}
+
+void TextAutoGenerateTextPromptModel::setTextInstances(const QList<TextAutoGenerateTextInstance *> &newTextInstances)
+{
+    beginResetModel();
+    qDeleteAll(mTextInstances);
+    mTextInstances.clear();
+    mTextInstances = newTextInstances;
+    endResetModel();
+}
+
+bool TextAutoGenerateTextPromptModel::isEmpty() const
+{
+    if (mTextInstances.isEmpty()) {
+        return true;
+    }
+    for (const auto &inst : mTextInstances) {
+        if (inst->enabled()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+QByteArray TextAutoGenerateTextPromptModel::currentInstance() const
+{
+    return mCurrentinstance;
+}
+
+void TextAutoGenerateTextPromptModel::setCurrentInstance(const QByteArray &newCurrentinstance)
+{
+    if (mCurrentinstance != newCurrentinstance) {
+        auto matchesUuid = [&](TextAutoGenerateTextInstance *instance) {
+            return instance->instanceUuid() == newCurrentinstance;
+        };
+        const auto answerIt = std::find_if(mTextInstances.constBegin(), mTextInstances.constEnd(), matchesUuid);
+
+        // Notify for old current instance row before changing state
+        auto notifyRow = [&](const QByteArray &uuid) {
+            auto it = std::find_if(mTextInstances.constBegin(), mTextInstances.constEnd(), [&](TextAutoGenerateTextInstance *instance) {
+                return instance->instanceUuid() == uuid;
+            });
+            if (it != mTextInstances.constEnd()) {
+                const int row = std::distance(mTextInstances.constBegin(), it);
+                const auto idx = index(row, 0);
+                Q_EMIT dataChanged(idx, idx, {InstanceRoles::IsDefault});
+            }
+        };
+
+        if (answerIt == mTextInstances.constEnd()) {
+            // If we don't find it. => clear it.
+            const QByteArray oldInstance = mCurrentinstance;
+            mCurrentinstance.clear();
+            notifyRow(oldInstance);
+            return;
+        }
+        notifyRow(mCurrentinstance);
+        mCurrentinstance = newCurrentinstance;
+        const int newRow = std::distance(mTextInstances.constBegin(), answerIt);
+        const auto newIdx = index(newRow, 0);
+        Q_EMIT dataChanged(newIdx, newIdx, {InstanceRoles::IsDefault});
+    }
+}
+
+TextAutoGenerateTextPlugin *TextAutoGenerateTextPromptModel::currentPlugin() const
+{
+    if (isEmpty()) {
+        return nullptr;
+    }
+    if (mCurrentinstance.isEmpty()) {
+        // Fall back to first enable instance
+        for (const auto &inst : mTextInstances) {
+            if (inst->enabled()) {
+                return inst->plugin();
+            }
+        }
+        return nullptr;
+    }
+    auto matchesUuid = [&](TextAutoGenerateTextInstance *instance) {
+        return (instance->instanceUuid() == mCurrentinstance) && instance->enabled();
+    };
+    const auto answerIt = std::find_if(mTextInstances.constBegin(), mTextInstances.constEnd(), matchesUuid);
+    if (answerIt != mTextInstances.constEnd()) {
+        return (*answerIt)->plugin();
+    }
+    // Fall back to first enable instance
+    for (const auto &inst : mTextInstances) {
+        if (inst->enabled()) {
+            return inst->plugin();
+        }
+    }
+    return nullptr;
+}
+
+void TextAutoGenerateTextPromptModel::addInstance(TextAutoGenerateTextInstance *instance)
+{
+    beginInsertRows(QModelIndex(), mTextInstances.count(), mTextInstances.count());
+    mTextInstances.append(instance);
+    endInsertRows();
+}
+
+void TextAutoGenerateTextPromptModel::removeInstance(const QByteArray &uuid)
+{
+    auto matchesUuid = [&](TextAutoGenerateTextInstance *instance) {
+        return instance->instanceUuid() == uuid;
+    };
+    const auto answerIt = std::find_if(mTextInstances.constBegin(), mTextInstances.constEnd(), matchesUuid);
+    if (answerIt != mTextInstances.constEnd()) {
+        const int i = std::distance(mTextInstances.constBegin(), answerIt);
+        beginRemoveRows(QModelIndex(), i, i);
+        auto instance = mTextInstances.at(i);
+        mTextInstances.removeAt(i);
+        endRemoveRows();
+        if (auto plugin = instance->plugin()) {
+            plugin->remove();
+        }
+        delete instance;
+    }
+}
+
+TextAutoGenerateTextPlugin *TextAutoGenerateTextPromptModel::editInstance(const QByteArray &uuid)
+{
+    auto matchesUuid = [&](TextAutoGenerateTextInstance *instance) {
+        return instance->instanceUuid() == uuid;
+    };
+    const auto answerIt = std::find_if(mTextInstances.constBegin(), mTextInstances.constEnd(), matchesUuid);
+    if (answerIt != mTextInstances.constEnd()) {
+        const int i = std::distance(mTextInstances.constBegin(), answerIt);
+        return mTextInstances.at(i)->plugin();
+    }
+    qCWarning(TEXTAUTOGENERATETEXT_CORE_LOG) << "Instance not found for uuid:" << uuid;
+    return nullptr;
+}
+
+Qt::ItemFlags TextAutoGenerateTextPromptModel::flags(const QModelIndex &index) const
+{
+    if (!index.isValid()) {
+        return Qt::NoItemFlags;
+    }
+
+    return Qt::ItemIsUserCheckable | QAbstractListModel::flags(index);
+}
+
+#include "moc_textautogeneratetextpromptmodel.cpp"
diff --git a/textautogeneratetext/core/models/textautogeneratetextpromptmodel.h b/textautogeneratetext/core/models/textautogeneratetextpromptmodel.h
new file mode 100644
index 000000000..0db0ab382
--- /dev/null
+++ b/textautogeneratetext/core/models/textautogeneratetextpromptmodel.h
@@ -0,0 +1,135 @@
+/*
+  SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+  SPDX-License-Identifier: GPL-2.0-or-later
+*/
+#pragma once
+
+#include "textautogeneratetext_export.h"
+#include <QAbstractListModel>
+#include <TextAutoGenerateText/TextAutoGenerateTextInstance>
+namespace TextAutoGenerateText
+{
+/*!
+ * \class TextAutoGenerateText::TextAutoGenerateTextPromptModel
+ * \brief The TextAutoGenerateTextPromptModel class
+ * \author Laurent Montel <[email protected]>
+ * \inmodule TextAutoGenerateText
+ * \inheaderfile TextAutoGenerateText/TextAutoGenerateTextPromptModel
+ */
+class TEXTAUTOGENERATETEXT_EXPORT TextAutoGenerateTextPromptModel : public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    enum InstanceRoles : uint16_t {
+        Name = Qt::UserRole + 1,
+        PluginName,
+        PluginIdentifier,
+        Uuid,
+        Plugin,
+        Enabled,
+        IsDefault,
+        TranslatedPluginName,
+    };
+    /*!
+     * Constructs a new TextAutoGenerateTextPromptModel object.
+     * \param parent The parent QObject
+     */
+    explicit TextAutoGenerateTextPromptModel(QObject *parent = nullptr);
+    /*!
+     * Destroys the TextAutoGenerateTextPromptModel object.
+     */
+    ~TextAutoGenerateTextPromptModel() override;
+
+    /*!
+     * Returns the number of rows in the model.
+     * \return The row count
+     */
+    [[nodiscard]] int rowCount(const QModelIndex & = {}) const override;
+    /*!
+     * Returns the data at the given index for the specified role.
+     * \param index The model index
+     * \param role The data role
+     * \return The data value
+     */
+    [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
+    /*!
+     * Sets the data at the given index for the specified role.
+     * \param index The model index
+     * \param value The value to set
+     * \param role The data role
+     * \return true if successful, false otherwise
+     */
+    [[nodiscard]] bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+    /*!
+     * Returns the flags for the given index.
+     * \param index The model index
+     * \return The item flags
+     */
+    [[nodiscard]] Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+    /*!
+     * Returns the list of text instances in the model.
+     * \return The list of TextAutoGenerateTextInstance pointers
+     */
+    [[nodiscard]] QList<TextAutoGenerateTextInstance *> textInstances() const;
+    /*!
+     * Sets the list of text instances in the model.
+     * \param newTextInstances The instances to set
+     */
+    void setTextInstances(const QList<TextAutoGenerateTextInstance *> &newTextInstances);
+
+    /*!
+     * Adds an instance to the model.
+     * \param instance The instance to add
+     */
+    void addInstance(TextAutoGenerateTextInstance *instance);
+
+    /*!
+     * Removes an instance from the model by UUID.
+     * Calls plugin->remove() and deletes the instance.
+     * \param uuid The UUID of the instance to remove
+     */
+    void removeInstance(const QByteArray &uuid);
+
+    /*!
+     * Gets the plugin for editing an instance by UUID.
+     * \param uuid The UUID of the instance to edit
+     * \return The plugin from the instance
+     */
+    [[nodiscard]] TextAutoGenerateTextPlugin *editInstance(const QByteArray &uuid);
+
+    /*!
+     * Returns whether the model is empty.
+     * \return true if empty, false otherwise
+     */
+    [[nodiscard]] bool isEmpty() const;
+
+    /*!
+     * Returns the UUID of the current instance.
+     * \return The current instance UUID
+     */
+    [[nodiscard]] QByteArray currentInstance() const;
+    /*!
+     * Sets the current instance by UUID.
+     * \param newCurrentinstance The UUID to set as current
+     */
+    void setCurrentInstance(const QByteArray &newCurrentinstance);
+
+    /*!
+     * Returns the plugin of the current instance.
+     * \return The plugin pointer or nullptr
+     */
+    [[nodiscard]] TextAutoGenerateTextPlugin *currentPlugin() const;
+
+    /*!
+     * Returns a list of display names for all instances.
+     * \return List of instance display names
+     */
+    [[nodiscard]] QStringList instanceDisplayNames() const;
+
+private:
+    QList<TextAutoGenerateTextInstance *> mTextInstances;
+    QByteArray mCurrentinstance;
+};
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.