swift
listmodelbase.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_GUI_MODELS_LISTMODELBASE_H
7 #define SWIFT_GUI_MODELS_LISTMODELBASE_H
8 
9 #include <memory>
10 
11 #include <QJsonDocument>
12 #include <QJsonObject>
13 #include <QModelIndex>
14 #include <QModelIndexList>
15 #include <QString>
16 #include <QVariant>
17 #include <QVector>
18 
20 #include "gui/models/modelfilter.h"
22 
23 class QMimeData;
24 class QModelIndex;
25 
26 namespace swift::misc
27 {
28  class CWorker;
29 }
30 namespace swift::gui::models
31 {
33  template <typename T, bool UseCompare = false>
35  {
36  public:
38  using ContainerType = T;
39 
41  using ObjectType = typename T::value_type;
42 
44  ~CListModelBase() override = default;
45 
48 
50  QVariant data(const QModelIndex &index, int role) const override;
51 
53  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) final;
54 
56  QMimeData *mimeData(const QModelIndexList &indexes) const final;
57 
59  void sort(int column, Qt::SortOrder order) final;
60 
62  int rowCount(const QModelIndex &parentIndex = QModelIndex()) const final;
63 
65  bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
66  const QModelIndex &parent) const final;
67 
69  bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column,
70  const QModelIndex &parent) final;
72 
75 
77  QJsonObject toJson(bool selectedOnly = false) const override;
78 
80  QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented,
81  bool selectedOnly = false) const override;
82 
84  bool isOrderable() const override;
86 
88  virtual bool isValidIndex(const QModelIndex &index) const;
89 
91  const ContainerType &container() const;
92 
94  const ContainerType &containerFiltered() const;
95 
97  const ContainerType &containerOrFilteredContainer(bool *filtered = nullptr) const;
98 
101  bool setInContainer(const QModelIndex &index, const ObjectType &obj);
102 
106  virtual int update(const ContainerType &container, bool sort = true);
107 
109  virtual swift::misc::CWorker *updateAsync(const ContainerType &container, bool sort = true);
110 
112  virtual void updateContainerMaybeAsync(const ContainerType &container, bool sort = true);
113 
115  virtual void update(const QModelIndex &index, const ObjectType &object);
116 
118  virtual void update(int rowIndex, const ObjectType &object);
119 
122  virtual void moveItems(const ContainerType &items, int position);
123 
125  virtual const ObjectType &at(const QModelIndex &index) const;
126 
128  void sort();
129 
132  void resort();
133 
135  void truncate(int maxNumber, bool forceSort = false);
136 
143  ContainerType sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const;
144 
146  virtual void push_back(const ObjectType &object);
147 
149  virtual void push_back(const ContainerType &container);
150 
152  virtual void insert(const ObjectType &object);
153 
155  virtual void insert(const ContainerType &container);
156 
158  virtual void remove(const ObjectType &object);
159 
161  template <class K0, class V0, class... KeysValues>
162  int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
163  {
164  int c = m_container.removeIf(swift::misc::predicates::MemberEqual(k0, v0, keysValues...));
165  this->updateFilteredContainer();
166  if (c > 0) { this->emitModelDataChanged(); }
167  return c;
168  }
169 
171  virtual void clear();
172 
174  virtual bool isEmpty() const;
175 
177  bool hasFilter() const;
178 
180  void removeFilter();
181 
183  void takeFilterOwnership(std::unique_ptr<IModelFilter<ContainerType>> &filter);
184 
187  {
188  m_selectionModel = selectionModel;
189  }
190 
191  protected:
193  CListModelBase(const QString &translationContext, QObject *parent = nullptr);
194 
197 
199  void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomLeft,
200  const QVector<int> &roles) override;
201 
203  void onChangedDigest() override;
205 
208 
210  void emitModelDataChanged();
211 
214  std::unique_ptr<IModelFilter<ContainerType>> m_filter;
216  };
217 
218  namespace Private
219  {
221  template <class ObjectType>
222  bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order,
223  const swift::misc::CPropertyIndex &index,
224  const swift::misc::CPropertyIndexList &tieBreakers, std::true_type)
225  {
226  const int c = a.comparePropertyByIndex(index, b);
227  if (c == 0)
228  {
229  if (!tieBreakers.isEmpty())
230  {
231  return compareForModelSort<ObjectType>(a, b, order, tieBreakers.front(),
232  tieBreakers.copyFrontRemoved(), std::true_type());
233  }
234  return false;
235  }
236  return (order == Qt::AscendingOrder) ? (c < 0) : (c > 0);
237  }
238 
240  template <typename ObjectType>
241  bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order,
242  const swift::misc::CPropertyIndex &index,
243  const swift::misc::CPropertyIndexList &tieBreakers, std::false_type)
244  {
245  const swift::misc::CVariant aQv = a.propertyByIndex(index);
246  const swift::misc::CVariant bQv = b.propertyByIndex(index);
247  if (!tieBreakers.isEmpty() && aQv == bQv)
248  {
249  return compareForModelSort<ObjectType>(a, b, order, tieBreakers.front(), tieBreakers.copyFrontRemoved(),
250  std::false_type());
251  }
252  return (order == Qt::AscendingOrder) ? (aQv < bQv) : (bQv < aQv);
253  }
254  } // namespace Private
255 } // namespace swift::gui::models
256 
257 #endif // SWIFT_GUI_MODELS_LISTMODELBASE_H
const ContainerType & container() const
Used container data.
virtual void clear()
Clear the list.
~CListModelBase()=default
Destructor.
virtual const ObjectType & at(const QModelIndex &index) const
Object at row position.
QMimeData * mimeData(const QModelIndexList &indexes) const final
void sort()
Sort by given sort order.
virtual bool isEmpty() const
Empty?
QVariant data(const QModelIndex &index, int role) const
bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) final
ISelectionModel< ContainerType > * m_selectionModel
selection model
virtual void push_back(const ObjectType &object)
Similar to ContainerType::push_back.
bool hasFilter() const
Filter available.
void takeFilterOwnership(std::unique_ptr< IModelFilter< ContainerType >> &filter)
Set the filter.
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented, bool selectedOnly=false) const
Convert to JSON string.
virtual void insert(const ObjectType &object)
Similar to ContainerType::insert here inserts at first position.
void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomLeft, const QVector< int > &roles)
Feedback when QStandardItemModel::dataChanged was called.
bool isOrderable() const
Orderable, normally use a container swift::misc::IOrderableList.
virtual swift::misc::CWorker * updateAsync(const ContainerType &container, bool sort=true)
Asynchronous update.
std::unique_ptr< IModelFilter< ContainerType > > m_filter
used filter
void setSelectionModel(swift::gui::models::ISelectionModel< ContainerType > *selectionModel)
Set the selection model.
void truncate(int maxNumber, bool forceSort=false)
Truncate to given number.
void onChangedDigest()
Feedback when QStandardItemModel::dataChanged was called.
typename T::value_type ObjectType
Container element type.
Definition: listmodelbase.h:41
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
Remove elements matching some particular key/value pair(s).
virtual void remove(const ObjectType &object)
Remove object.
virtual bool isValidIndex(const QModelIndex &index) const
Valid index (in range)
ContainerType m_container
used container
void updateFilteredContainer()
Update filtered container.
ContainerType m_containerFiltered
cache for filtered container data
int rowCount(const QModelIndex &parentIndex=QModelIndex()) const final
QJsonObject toJson(bool selectedOnly=false) const
Convert to JSON.
ContainerType sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const
Sort container by given column / order. This is used by sort() but als for asynchronous updates in th...
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) final
const ContainerType & containerOrFilteredContainer(bool *filtered=nullptr) const
Full container or cached filtered container as approproiate.
const ContainerType & containerFiltered() const
Used container data.
virtual void moveItems(const ContainerType &items, int position)
Move items to position, normally called from dropMimeData.
void emitModelDataChanged()
Model changed.
void resort()
Sort by given sort order.
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const final
virtual int update(const ContainerType &container, bool sort=true)
Update by new container.
CListModelBase(const QString &translationContext, QObject *parent=nullptr)
Constructor.
virtual void updateContainerMaybeAsync(const ContainerType &container, bool sort=true)
Update by new container.
bool setInContainer(const QModelIndex &index, const ObjectType &obj)
Simple set of data in container, using class is responsible for firing signals etc.
Non templated base class, allows Q_OBJECT and signals to be used.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const final
QModelIndex parent(const QModelIndex &child) const final
Model filter interface.
Definition: modelfilter.h:21
Allow to get and select objects.
Value object encapsulating a list of property indexes.
Q_REQUIRED_RESULT CPropertyIndexList copyFrontRemoved() const
List without front element, or empty list if not applicable.
reference front()
Access the first element.
Definition: sequence.h:225
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order, const swift::misc::CPropertyIndex &index, const swift::misc::CPropertyIndexList &tieBreakers, std::true_type)
Sort with compare function.
Models to be used with views, mainly QTableView.
auto MemberEqual(Ts... vs)
Predicate which tests whether some member functions return some values.
Definition: predicates.h:26
Free functions in swift::misc.