BibleTime
btbookshelftreemodel.h
Go to the documentation of this file.
1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, https://bibletime.info/
6 *
7 * Copyright 1999-2021 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12 
13 #pragma once
14 
15 #include <QAbstractItemModel>
16 
17 #include <memory>
18 #include <QList>
19 #include <QObject>
20 #include <QMap>
21 #include <QModelIndex>
22 #include <QPersistentModelIndex>
23 #include <QString>
24 #include <QtCore>
25 #include <QVariant>
26 #include "../drivers/btconstmoduleset.h"
27 #include "../drivers/btmoduleset.h"
28 #include "btbookshelfmodel.h"
29 #include "item.h"
30 
31 
32 namespace BookshelfModel { class ModuleItem; }
33 class BtConfigCore;
34 class CSwordModuleInfo;
35 
37 
38  Q_OBJECT
39  Q_ENUMS(Group)
40 
41 private: // types:
42 
43  using ModuleItemMap = QMap<CSwordModuleInfo *, BookshelfModel::ModuleItem *>;
44  using SourceIndexMap = QMap<CSwordModuleInfo *, QPersistentModelIndex>;
45 
46 public: // types:
47 
48  enum ModuleRole {
51  };
52 
53  enum Group {
57  };
58 
60  CHECKED, /**< Check all added modules by default. */
61  UNCHECKED, /**< Uncheck all added modules by default. */
62  MODULE_HIDDEN, /**< By default, check only added modules that are not hidden. */
63  MODULE_INDEXED /**< By default, check only added modules that are indexed. */
64  };
65 
66  class Grouping: public QList<Group> {
67 
68  public: // methods:
69 
70  /**
71  \warning Be careful using this constructor!
72  */
73  explicit Grouping(bool empty = false) {
74  if (empty)
75  return;
76  push_back(GROUP_CATEGORY);
77  push_back(GROUP_LANGUAGE);
78  }
79 
80  explicit Grouping(Group group) { push_back(group); }
81 
82  Grouping(BtConfigCore const & config, QString const & key) {
83  if (loadFrom(config, key))
84  return;
85  push_back(GROUP_CATEGORY);
86  push_back(GROUP_LANGUAGE);
87  }
88 
89  Grouping(Grouping const & copy) = default;
90  Grouping & operator=(Grouping const & copy) = default;
91 
92  bool loadFrom(BtConfigCore const & config, QString const & key);
93  void saveTo(BtConfigCore & config, QString const & key) const;
94 
95  };
96 
97 public: // methods:
98 
99  BtBookshelfTreeModel(QObject * parent = nullptr);
100  BtBookshelfTreeModel(BtConfigCore const & config,
101  QString const & configKey,
102  QObject * parent = nullptr);
103  BtBookshelfTreeModel(const Grouping & grouping, QObject * parent = nullptr);
105 
106  int rowCount(const QModelIndex & parent = QModelIndex()) const override;
107  int columnCount(const QModelIndex & parent = QModelIndex()) const override;
108  bool hasChildren(const QModelIndex & parent = QModelIndex()) const override;
109  QModelIndex index(int row,
110  int column,
111  const QModelIndex & parent = QModelIndex())
112  const override;
113  QModelIndex parent(const QModelIndex & index) const override;
114  QVariant data(const QModelIndex & index, int role = Qt::DisplayRole)
115  const override;
116  QVariant data(CSwordModuleInfo & module, int role = Qt::DisplayRole) const;
117  Qt::ItemFlags flags(const QModelIndex & index) const override;
118  QVariant headerData(int section,
119  Qt::Orientation orientation,
120  int role = Qt::DisplayRole) const override;
121  bool setData(const QModelIndex & index,
122  const QVariant & value,
123  int role) override;
124 
125  CSwordModuleInfo * module(QModelIndex const & index) const {
126  return static_cast<CSwordModuleInfo *>(
127  data(index,
128  BtBookshelfModel::ModulePointerRole).value<void *>());
129  }
130  std::shared_ptr<QAbstractItemModel> sourceModel() const noexcept
131  { return m_sourceModel; }
132 
133  Grouping const & groupingOrder() const { return m_groupingOrder; }
134  bool checkable() const { return m_checkable; }
136  QList<CSwordModuleInfo *> modules() const { return m_modules.keys(); }
137  BtModuleSet const & checkedModules() const {
138  return m_checkedModulesCache;
139  }
140 
141 public Q_SLOTS:
142 
143  void setSourceModel(std::shared_ptr<QAbstractItemModel> sourceModel);
145  bool emitSignal = true);
146  void setCheckable(bool checkable);
149 
150 Q_SIGNALS:
151 
153  void moduleChecked(CSwordModuleInfo * module, bool checked);
154 
155 protected: // methods:
156 
157  void resetData();
158 
159 protected Q_SLOTS:
160 
161  void moduleDataChanged(const QModelIndex & topLeft,
162  const QModelIndex & bottomRight);
163  void moduleInserted(const QModelIndex & parent, int start, int end);
164  void moduleRemoved(const QModelIndex & parent, int start, int end);
165 
166 private: // methods:
167 
168  void addModule(CSwordModuleInfo & module, bool checked);
170  QModelIndex parentIndex,
171  Grouping & intermediateGrouping,
172  bool checked);
174 
175  BookshelfModel::Item & getItem(const QModelIndex & index) const;
176  QModelIndex getIndex(const BookshelfModel::Item & item);
177  void resetParentCheckStates(QModelIndex parentIndex);
178 
179  template <class T>
181  QModelIndex parentIndex)
182  {
183  BookshelfModel::Item & parentItem = getItem(parentIndex);
184  int groupIndex;
185  T * groupItem = parentItem.getGroupItem<T>(module, groupIndex);
186 
187  if (!groupItem) {
188  groupItem = new T(module);
189  groupIndex = parentItem.indexFor(*groupItem);
190  beginInsertRows(parentIndex, groupIndex, groupIndex);
191  parentItem.insertChild(groupIndex, groupItem);
192  endInsertRows();
193  }
194  return index(groupIndex, 0, parentIndex);
195  }
196 
197 private: // fields:
198 
199  std::shared_ptr<QAbstractItemModel> m_sourceModel;
200  std::unique_ptr<BookshelfModel::Item> m_rootItem;
206 
208 
209 };
210 
211 QDataStream & operator <<(QDataStream & os, const BtBookshelfTreeModel::Grouping & o);
212 QDataStream & operator >>(QDataStream & is, BtBookshelfTreeModel::Grouping & o);
213 
214 Q_DECLARE_METATYPE(BtBookshelfTreeModel::Grouping)
QDataStream & operator<<(QDataStream &os, const BtBookshelfTreeModel::Grouping &o)
QDataStream & operator>>(QDataStream &is, BtBookshelfTreeModel::Grouping &o)
T * getGroupItem(CSwordModuleInfo &module, int &outIndex)
Definition: item.h:93
int indexFor(Item const &newItem)
Returns the position for where the given child item would be inserted.
Definition: item.cpp:27
void insertChild(int index, Item *newItem)
Inserts the given item as a child at the given index.
Definition: item.h:85
Grouping & operator=(Grouping const &copy)=default
void saveTo(BtConfigCore &config, QString const &key) const
Grouping(Grouping const &copy)=default
Grouping(BtConfigCore const &config, QString const &key)
bool loadFrom(BtConfigCore const &config, QString const &key)
void moduleInserted(const QModelIndex &parent, int start, int end)
CheckedBehavior m_defaultChecked
QModelIndex getGroup(CSwordModuleInfo &module, QModelIndex parentIndex)
std::unique_ptr< BookshelfModel::Item > m_rootItem
void groupingOrderChanged(BtBookshelfTreeModel::Grouping newGrouping)
void removeModule(CSwordModuleInfo &module)
void resetParentCheckStates(QModelIndex parentIndex)
Qt::ItemFlags flags(const QModelIndex &index) const override
QModelIndex getIndex(const BookshelfModel::Item &item)
void moduleRemoved(const QModelIndex &parent, int start, int end)
QModelIndex parent(const QModelIndex &index) const override
BookshelfModel::Item & getItem(const QModelIndex &index) const
std::shared_ptr< QAbstractItemModel > m_sourceModel
void setDefaultChecked(CheckedBehavior b)
void setCheckable(bool checkable)
void setCheckedModules(BtConstModuleSet const &modules)
BtBookshelfTreeModel(QObject *parent=nullptr)
std::shared_ptr< QAbstractItemModel > sourceModel() const noexcept
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QMap< CSwordModuleInfo *, QPersistentModelIndex > SourceIndexMap
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
~BtBookshelfTreeModel() override
void setGroupingOrder(const BtBookshelfTreeModel::Grouping &groupingOrder, bool emitSignal=true)
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
SourceIndexMap m_sourceIndexMap
BtModuleSet const & checkedModules() const
CheckedBehavior defaultChecked() const
Grouping const & groupingOrder() const
void moduleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
QList< CSwordModuleInfo * > modules() const
int rowCount(const QModelIndex &parent=QModelIndex()) const override
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
void setSourceModel(std::shared_ptr< QAbstractItemModel > sourceModel)
CSwordModuleInfo * module(QModelIndex const &index) const
QMap< CSwordModuleInfo *, BookshelfModel::ModuleItem * > ModuleItemMap
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
void moduleChecked(CSwordModuleInfo *module, bool checked)
void addModule(CSwordModuleInfo &module, bool checked)
#define T(f)