BibleTime
btbookshelfmodel.cpp
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-2025 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#include "btbookshelfmodel.h"
14
15#include <QIcon>
16#include <QSet>
17#include <QtAlgorithms>
18#include <QtGlobal>
19#include "../../util/btassert.h"
20#include "../../util/btconnect.h"
21#include "../../util/macros.h"
22#include "../drivers/cswordmoduleinfo.h"
23#include "../drivers/btconstmoduleset.h"
24
25
27
28std::shared_ptr<BtBookshelfModel> BtBookshelfModel::newInstance()
29{ return std::make_shared<BtBookshelfModel>(ConstructInPrivate()); }
30
31BtBookshelfModel::~BtBookshelfModel() noexcept = default;
32
33int BtBookshelfModel::rowCount(QModelIndex const & parent) const {
34 if (parent.isValid())
35 return 0;
36
37 return m_data.size();
38}
39
40QVariant BtBookshelfModel::data(CSwordModuleInfo * module, int const role) const
41{
43 switch (role) {
44 case Qt::DisplayRole:
45 case ModuleNameRole:
46 return module->name();
47 case Qt::DecorationRole:
48 case ModuleIconRole:
51 return QVariant::fromValue(static_cast<void *>(module));
53 return QVariant::fromValue(module->category());
55 return QVariant(); /// \todo Unimplemented
57 return module->isHidden();
59 return module->config(CSwordModuleInfo::AbsoluteDataPath);
61 return module->hasIndex();
63 return module->indexSize();
65 return module->config(CSwordModuleInfo::Description);
66 case Qt::ToolTipRole:
67 return QStringLiteral("<b>%1:</b><br/>%2")
68 .arg(module->name())
70 default:
71 return QVariant();
72 }
73}
74
75QVariant BtBookshelfModel::data(QModelIndex const & index, int const role) const
76{
77 if (!index.isValid() || index.column() != 0 || index.parent().isValid())
78 return QVariant();
79
80 int const row = index.row();
81 if (row >= m_data.size())
82 return QVariant();
83
84 return data(m_data.at(row), role);
85}
86
87QVariant BtBookshelfModel::headerData(int const section,
88 Qt::Orientation const orientation,
89 int const role) const
90{
91 if (role == Qt::DisplayRole
92 && orientation == Qt::Horizontal
93 && section == 0)
94 {
95 return tr("Module");
96 }
97
98 return QVariant();
99}
100
101bool BtBookshelfModel::setData(QModelIndex const & index,
102 QVariant const & value,
103 int const role)
104{
105 int const row = index.row();
106 if (role == ModuleHiddenRole
107 && row >= 0
108 && row < m_data.size()
109 && index.column() == 0)
110 {
111 /*
112 Emitting dataChanged here is actually mandatory, but were not doing it
113 directly. Since we're connected to the module, changing its hidden
114 state will emit a signal we catch in moduleHidden(), which in turn is
115 what will actually emit dataChanged().
116 */
117 return m_data.at(row)->setHidden(value.toBool());
118 }
119 return false;
120}
121
122void BtBookshelfModel::clear(bool const destroy) {
123 if (m_data.size() <= 0)
124 return;
125
126 beginRemoveRows(QModelIndex(), 0, m_data.size() - 1);
127 if (destroy)
128 qDeleteAll(m_data);
129 m_data.clear();
130 endRemoveRows();
131}
132
135
136 if (m_data.contains(module))
137 return;
138
139 const int index(m_data.size());
140 beginInsertRows(QModelIndex(), index, index);
141 m_data.append(module);
148 endInsertRows();
149}
150
152 bool const destroy) {
153 const int index = m_data.indexOf(module);
154 if (index == -1)
155 return;
156
157 beginRemoveRows(QModelIndex(), index, index);
164 m_data.removeAt(index);
165 endRemoveRows();
166 if (destroy)
167 delete module;
168}
169
170void BtBookshelfModel::removeModules(QList<CSwordModuleInfo *> const & modules,
171 bool const destroy)
172{
173 QSet<CSwordModuleInfo *> moduleSet;
174 for (auto module: modules)
175 moduleSet.insert(module);
176 removeModules(moduleSet, destroy);
177}
178
180 bool const destroy)
181{
182 // This is inefficient, since signals are emitted for each removed module:
183 for (auto const * const module : modules)
184 removeModule(const_cast<CSwordModuleInfo *>(module), destroy);
185}
186
187CSwordModuleInfo * BtBookshelfModel::getModule(QString const & name) const {
188 for (auto * const module : m_data)
189 if (UNLIKELY(module->name() == name))
190 return module;
191 return nullptr;
192}
193
195 BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()));
196
197 moduleDataChanged(static_cast<CSwordModuleInfo *>(sender()));
198}
199
201 BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()));
202
203 moduleDataChanged(static_cast<CSwordModuleInfo *>(sender()));
204}
205
207 BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()));
208
209 moduleDataChanged(static_cast<CSwordModuleInfo *>(sender()));
210}
211
213 BT_ASSERT(m_data.count(module) == 1);
214
215 QModelIndex i(index(m_data.indexOf(module), 0));
216 Q_EMIT dataChanged(i, i);
217}
#define BT_ASSERT(...)
Definition btassert.h:17
#define BT_CONNECT(...)
Definition btconnect.h:20
bool setData(QModelIndex const &index, QVariant const &value, int role=ModuleHiddenRole) override
static std::shared_ptr< BtBookshelfModel > newInstance()
void removeModule(CSwordModuleInfo *const module, bool destroy=false)
void addModule(CSwordModuleInfo *const module)
void moduleIndexed(bool indexed)
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
~BtBookshelfModel() noexcept override
CSwordModuleInfo * getModule(QString const &name) const
CSwordModuleInfo * module(QModelIndex const &index) const
QList< CSwordModuleInfo * > m_data
QVariant data(CSwordModuleInfo *module, int role) const
void moduleHidden(bool hidden)
void moduleUnlocked(bool unlocked)
void moduleDataChanged(CSwordModuleInfo *module)
BtBookshelfModel(BtBookshelfModel &&)=delete
void removeModules(BtConstModuleSet const &modules, bool destroy=false)
void clear(bool destroy=false)
QString config(const CSwordModuleInfo::ConfigEntry entry) const
QIcon moduleIcon() const
QString const & name() const
void hasIndexChanged(bool hasIndex)
void hiddenChanged(bool hidden)
void unlockedChanged(bool unlocked)
CSwordModuleInfo::Category category() const
#define UNLIKELY(c)
Gives the compiler a hint that the given conditional is likely to evaluate to false.
Definition macros.h:44
Used to restrict construction to newInstance() only.