aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h
diff options
context:
space:
mode:
Diffstat (limited to 'examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h')
-rw-r--r--examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h b/examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h
new file mode 100644
index 0000000000..4ef4cd176c
--- /dev/null
+++ b/examples/quickcontrols/spreadsheets/Spreadsheets/spreadmodel.h
@@ -0,0 +1,154 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef SPREADMODEL_H
+#define SPREADMODEL_H
+
+#include "datamodel.h"
+#include "spreadformula.h"
+
+#include <QQmlEngine>
+#include <QAbstractTableModel>
+#include <QItemSelectionModel>
+#include <QMutex>
+
+
+class DataModel;
+class SpreadModel;
+
+class SpreadModel final : public QAbstractTableModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ Q_DISABLE_COPY_MOVE(SpreadModel)
+
+ friend class SpreadSelectionModel;
+ friend class SpreadCell;
+ friend struct Formula;
+
+protected:
+ explicit SpreadModel(QObject *parent = nullptr) : QAbstractTableModel(parent) { }
+
+public:
+ int rowCount() const { return rowCount(QModelIndex{}); }
+ int columnCount() const { return columnCount(QModelIndex{}); }
+
+ const DataModel *dataModel() { return &m_dataModel; }
+
+ int columnNumberFromName(const QString &text);
+ int rowNumberFromName(const QString &text);
+ // returns nullptr if it's not been created yet.
+ static SpreadModel *instance();
+ static SpreadModel *create(QQmlEngine *, QJSEngine *);
+
+protected:
+ Q_INVOKABLE void update(int row, int column);
+ Q_INVOKABLE void clearHighlight();
+ Q_INVOKABLE void setHighlight(const QModelIndex &index, bool highlight);
+ Q_INVOKABLE bool clearItemData(const QModelIndexList &indexes);
+ Q_INVOKABLE bool removeColumns(QModelIndexList indexes);
+ Q_INVOKABLE bool removeRows(QModelIndexList indexes);
+ Q_INVOKABLE void mapColumn(int model, int view);
+ Q_INVOKABLE void mapRow(int model, int view);
+ Q_INVOKABLE void resetColumnMapping() { m_viewColumns.clear(); }
+ Q_INVOKABLE void resetRowMapping() { m_viewRows.clear(); }
+
+ // QAbstractItemModel interface
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ Q_INVOKABLE bool clearItemData(const QModelIndex &index) override;
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QHash<int, QByteArray> roleNames() const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex{}) override;
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex{}) override;
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
+
+private:
+ Formula parseFormulaString(const QString &text);
+ QString formulaValueText(const Formula &formula);
+ int getViewColumn(int modelColumn) const;
+ int getModelColumn(int viewColumn) const;
+ int getViewRow(int modelRow) const;
+ int getModelRow(int viewRow) const;
+
+private:
+ std::pair<int, int> m_size {1000, 26}; // rows:1-1000, columns:A-Z
+ DataModel m_dataModel;
+ QMap<int, int> m_viewColumns;
+ QMap<int, int> m_viewRows;
+ QMutex m_updateMutex;
+ static inline SpreadModel *s_instance {nullptr};
+};
+
+class SpreadSelectionModel : public QItemSelectionModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ Q_PROPERTY(Behavior behavior READ getBehavior WRITE setBehavior NOTIFY behaviorChanged FINAL)
+
+public:
+ enum Behavior {
+ DisabledBehavior,
+ SelectCells,
+ SelectColumns,
+ SelectRows,
+ };
+ Q_ENUM(Behavior)
+
+public:
+ Q_INVOKABLE void toggleColumn(int column);
+ Q_INVOKABLE void deselectColumn(int column);
+ Q_INVOKABLE void selectColumn(int column, bool clear = true);
+ Q_INVOKABLE void toggleRow(int row);
+ Q_INVOKABLE void deselectRow(int row);
+ Q_INVOKABLE void selectRow(int row, bool clear = true);
+
+protected:
+ Behavior getBehavior() const { return m_behavior; }
+
+protected slots:
+ void setBehavior(Behavior);
+
+signals:
+ void behaviorChanged();
+
+private:
+ Behavior m_behavior = Behavior::DisabledBehavior;
+};
+
+class HeaderSelectionModel : public QItemSelectionModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ Q_PROPERTY(SpreadSelectionModel* selectionModel READ getSelectionModel WRITE setSelectionModel NOTIFY selectionModelChanged FINAL)
+ Q_PROPERTY(Qt::Orientation orientation READ getOrientation WRITE setOrientation NOTIFY orientationChanged FINAL)
+
+protected:
+ Q_INVOKABLE void setCurrent(int current = -1);
+ SpreadSelectionModel *getSelectionModel() { return m_selectionModel; }
+ Qt::Orientation getOrientation() const { return m_orientation; }
+
+protected slots:
+ void setSelectionModel(SpreadSelectionModel *selectionModel);
+ void setOrientation(Qt::Orientation orientation);
+
+private slots:
+ void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+
+signals:
+ void selectionModelChanged();
+ void orientationChanged();
+
+private:
+ SpreadSelectionModel *m_selectionModel = nullptr;
+ Qt::Orientation m_orientation = Qt::Horizontal;
+};
+
+#endif // SPREADMODEL_H