Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS dbe source for the DUNE DAQ project.
3 : // Fork baseline commit: dbe-02-12-17 (2022-05-12).
4 : // Renamed since fork: no.
5 :
6 : #include "dbe/tree.hpp"
7 : #include "dbe/StyleUtility.hpp"
8 : #include "dbe/confaccessor.hpp"
9 : #include "dbe/config_api.hpp"
10 : #include "dbe/config_reference.hpp"
11 : #include "dbe/treenode.hpp"
12 : #include "dbe/ui_constants.hpp"
13 : #include "dbe/version.hpp"
14 :
15 : #include <QMimeData>
16 :
17 : char const* const dbe_lib_structure_version = dbe_compiled_version;
18 :
19 0 : dbe::models::tree::tree(const QStringList& Headers, QObject* parent)
20 : : QAbstractItemModel(parent)
21 0 : , abstract_classes_selectable(false)
22 : {
23 0 : confaccessor::gethandler()->root = new dbe::treenode(Headers);
24 :
25 0 : for (std::string const& aclass : dbe::config::api::info::onclass::allnames<std::vector<std::string>>()) {
26 0 : new ClassNode(dbe::config::api::info::onclass::definition(aclass, false), confaccessor::gethandler()->root);
27 0 : }
28 :
29 0 : model_common_connections();
30 0 : }
31 :
32 0 : dbe::models::tree::~tree() {}
33 :
34 : dbe::models::tree::type_index
35 0 : dbe::models::tree::index(int row, int column, type_index const& parent) const
36 : {
37 : // This is standard qt implementation for a tree mode;
38 0 : dbe::treenode* up{ parent.isValid() ? getnode(parent) : confaccessor::gethandler()->root };
39 :
40 0 : if (dbe::treenode* down = up->GetChild(row)) {
41 0 : return createIndex(row, column, down);
42 : } else {
43 0 : return QModelIndex();
44 : }
45 : }
46 :
47 : dbe::models::tree::type_index
48 0 : dbe::models::tree::parent(const type_index& child) const
49 : {
50 0 : if (child.isValid()) {
51 0 : dbe::treenode* up = getnode(child)->GetParent();
52 :
53 0 : if (up != confaccessor::gethandler()->root) {
54 0 : return createIndex(up->GetRow(), 0, up);
55 : }
56 : }
57 :
58 0 : return QModelIndex();
59 : }
60 :
61 : int
62 0 : dbe::models::tree::rowCount(const QModelIndex& parent) const
63 : {
64 0 : dbe::treenode* ParentNode;
65 :
66 0 : if (!parent.isValid()) {
67 0 : ParentNode = confaccessor::gethandler()->getnode();
68 : } else {
69 0 : ParentNode = getnode(parent);
70 : }
71 :
72 0 : return ParentNode->ChildCount();
73 : }
74 :
75 : int
76 0 : dbe::models::tree::columnCount(const type_index& parent) const
77 : {
78 0 : if (parent.isValid()) {
79 0 : dbe::treenode* DataNode = getnode(parent);
80 :
81 0 : return DataNode->ColumnCount();
82 : } else {
83 0 : return confaccessor::gethandler()->root->ColumnCount();
84 : }
85 : }
86 :
87 : Qt::ItemFlags
88 0 : dbe::models::tree::flags(type_index const& index) const
89 : {
90 0 : treenode* node = getnode(index);
91 :
92 0 : if (ClassNode* classnode = dynamic_cast<ClassNode*>(node)) {
93 0 : dunedaq::conffwk::class_t classinfo = classnode->GetClassInfo();
94 :
95 0 : if (classinfo.p_abstract) {
96 0 : return abstract_classes_selectable ? (Qt::ItemIsEnabled | Qt::ItemIsSelectable) : (Qt::ItemIsSelectable);
97 : } else {
98 0 : return (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
99 : }
100 0 : }
101 :
102 0 : return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
103 : }
104 :
105 : QVariant
106 0 : dbe::models::tree::data(type_index const& index, int role) const
107 : {
108 0 : if (index.isValid()) {
109 0 : switch (role) {
110 0 : case Qt::ForegroundRole:
111 0 : if (ObjectNode* onode = dynamic_cast<ObjectNode*>(getnode(index))) {
112 0 : try {
113 0 : tref const& obj = onode->GetObject();
114 :
115 0 : if (confaccessor::check_file_rw(QString::fromStdString(obj.contained_in()))) {
116 0 : return QVariant(StyleUtility::ObjectForeground);
117 : } else {
118 0 : return QVariant(StyleUtility::FileReadOnlyForeground);
119 : }
120 0 : } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
121 : // nothing to do the onode refers to a removed object and has not yet been removed
122 0 : return QVariant();
123 0 : }
124 : }
125 :
126 : break;
127 :
128 0 : case Qt::BackgroundRole:
129 0 : if (ObjectNode* onode = dynamic_cast<ObjectNode*>(getnode(index))) {
130 0 : try {
131 0 : tref const& obj = onode->GetObject();
132 :
133 0 : if (confaccessor::check_file_rw(QString::fromStdString(obj.contained_in()))) {
134 0 : return QVariant(StyleUtility::ObjectBackground);
135 : } else {
136 0 : return QVariant(StyleUtility::FileReadOnlyBackground);
137 : }
138 0 : } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
139 : // nothing to do the onode refers to a removed object and has not yet been removed
140 0 : return QVariant();
141 0 : }
142 : }
143 :
144 : break;
145 :
146 0 : case Qt::ToolTipRole:
147 0 : if (auto cnode = dynamic_cast<ClassNode*>(getnode(index))) {
148 0 : return cnode->GetData(index.column(), role);
149 : }
150 : break;
151 :
152 0 : case Qt::DisplayRole:
153 0 : case Qt::DecorationRole:
154 0 : return getnode(index)->GetData(index.column(), role);
155 : }
156 : }
157 :
158 0 : return QVariant();
159 : }
160 :
161 : QVariant
162 0 : dbe::models::tree::headerData(int section, Qt::Orientation orientation, int role) const
163 : {
164 0 : if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
165 0 : return confaccessor::gethandler()->root->GetData(section);
166 : }
167 :
168 0 : return QVariant();
169 : }
170 :
171 : bool
172 0 : dbe::models::tree::insertRows(int position, int rows, const QModelIndex& parent)
173 : {
174 0 : if (ClassNode* onode = dynamic_cast<ClassNode*>(getnode(parent))) {
175 0 : rows = onode->ChildCount();
176 :
177 0 : beginInsertRows(parent, position, position + rows - 1);
178 :
179 0 : std::string const& classname = onode->GetData(static_cast<int>(tablepositions::classname)).toString().toStdString();
180 :
181 0 : std::vector<tref> const& objects = config::api::info::onclass::objects(classname, false);
182 :
183 0 : for (auto const& i : objects) {
184 0 : new ObjectNode(i, false, onode);
185 0 : emit ObjectFile(QString::fromStdString(i.contained_in()));
186 : }
187 :
188 0 : endInsertRows();
189 :
190 0 : return true;
191 0 : } else {
192 : return false;
193 : }
194 : }
195 :
196 : bool
197 0 : dbe::models::tree::canFetchMore(type_index const& parent) const
198 : {
199 0 : if (parent.isValid()) {
200 0 : treenode* ParentNode = getnode(parent);
201 0 : return (!ParentNode->GetWasFetched());
202 : }
203 :
204 : return false;
205 : }
206 :
207 : void
208 0 : dbe::models::tree::fetchMore(type_index const& parent)
209 : {
210 0 : if (parent.isValid()) {
211 0 : treenode* ParentNode = getnode(parent);
212 :
213 0 : if (!ParentNode->GetWasFetched()) {
214 0 : insertRows(0, 0, parent);
215 0 : ParentNode->SetWasFetched(true);
216 : }
217 : }
218 0 : }
219 :
220 : bool
221 0 : dbe::models::tree::hasChildren(const QModelIndex& parent) const
222 : {
223 0 : if (parent.isValid()) {
224 0 : treenode* ParentNode = getnode(parent);
225 0 : return (ParentNode->GetHasStructure());
226 : }
227 :
228 : return true;
229 : }
230 :
231 : bool
232 0 : dbe::models::tree::setData(type_index const& index, const QVariant& value, int role)
233 : {
234 0 : Q_UNUSED(index)
235 0 : Q_UNUSED(value)
236 0 : Q_UNUSED(role)
237 :
238 0 : return true;
239 : }
240 :
241 : QStringList
242 0 : dbe::models::tree::mimeTypes() const
243 : {
244 0 : QStringList types;
245 0 : types << "application/vnd.text.list";
246 0 : return types;
247 0 : }
248 :
249 : QMimeData*
250 0 : dbe::models::tree::mimeData(const QModelIndexList& indexes) const
251 : {
252 0 : QMimeData* mimeData = new QMimeData();
253 0 : QByteArray encodedData;
254 :
255 0 : QDataStream stream(&encodedData, QIODevice::WriteOnly);
256 :
257 0 : foreach (QModelIndex index, indexes) {
258 0 : if (index.isValid() && index.column() == 0) {
259 0 : QStringList Text;
260 0 : treenode* NodeObject = getnode(index);
261 :
262 0 : tref Object = NodeObject->GetObject();
263 0 : QString ObjectUid = QString::fromStdString(Object.UID());
264 0 : QString ObjectClassName = QString::fromStdString(Object.class_name());
265 :
266 0 : Text.append(ObjectUid);
267 0 : Text.append(ObjectClassName);
268 :
269 0 : stream << Text;
270 0 : }
271 0 : }
272 :
273 0 : mimeData->setData("application/vnd.text.list", encodedData);
274 0 : return mimeData;
275 0 : }
276 :
277 : QModelIndex
278 0 : dbe::models::tree::getindex(treenode* NodeItem, type_index const& RootIndex) const
279 : {
280 0 : for (int i = 0; i < rowCount(RootIndex); ++i) {
281 0 : QModelIndex ChildIndex = index(i, 0, RootIndex);
282 0 : treenode* ChildNode = getnode(ChildIndex);
283 :
284 0 : if (NodeItem == ChildNode) {
285 0 : return ChildIndex;
286 : }
287 :
288 0 : QModelIndex ChildChildIndex = getindex(NodeItem, ChildIndex);
289 :
290 0 : if (ChildChildIndex.isValid()) {
291 0 : return ChildChildIndex;
292 : }
293 : }
294 :
295 0 : return QModelIndex();
296 : }
297 :
298 : void
299 0 : dbe::models::tree::ResetModel()
300 : {
301 0 : beginResetModel();
302 0 : endResetModel();
303 0 : }
304 :
305 : dbe::models::tree::type_datum*
306 0 : dbe::models::tree::getnode(type_index const& index) const
307 : {
308 0 : if (index.isValid()) {
309 0 : return static_cast<treenode*>(index.internalPointer());
310 : }
311 :
312 0 : return confaccessor::gethandler()->root;
313 : }
314 :
315 : dbe::tref
316 0 : dbe::models::tree::getobject(const QModelIndex& index) const
317 : {
318 0 : if (index.isValid()) {
319 0 : if (ObjectNode* ObjectItem = dynamic_cast<ObjectNode*>(getnode(index))) {
320 0 : return ObjectItem->GetObject();
321 : }
322 : }
323 :
324 0 : throw daq::dbe::cannot_handle_invalid_qmodelindex(ERS_HERE);
325 : }
326 :
327 : dunedaq::conffwk::class_t
328 0 : dbe::models::tree::getclass(type_index const& index) const
329 : {
330 0 : treenode* Item = getnode(index);
331 :
332 0 : if (Item != 0) {
333 0 : ClassNode* ClassItem = dynamic_cast<ClassNode*>(Item);
334 :
335 0 : if (ClassItem != nullptr) {
336 0 : return ClassItem->GetClassInfo();
337 : }
338 :
339 0 : ObjectNode* ObjectItem = dynamic_cast<ObjectNode*>(Item);
340 :
341 0 : if (ObjectItem != nullptr) {
342 0 : tref Object = ObjectItem->GetObject();
343 0 : return dbe::config::api::info::onclass::definition(Object.class_name(), false);
344 0 : }
345 :
346 0 : RelationshipNode* RelationshipItem = dynamic_cast<RelationshipNode*>(Item);
347 :
348 0 : if (RelationshipItem != nullptr) {
349 0 : return dbe::config::api::info::onclass::definition(RelationshipItem->relation_t().p_type, false);
350 : }
351 : }
352 :
353 0 : return dunedaq::conffwk::class_t();
354 : }
355 :
356 : QAbstractItemModel*
357 0 : dbe::models::tree::ReturnSourceModel() const
358 : {
359 0 : return nullptr;
360 : }
361 :
362 : void
363 0 : dbe::models::tree::ToggleAbstractClassesSelectable(bool const val)
364 : {
365 0 : abstract_classes_selectable = val;
366 0 : ResetModel();
367 0 : }
368 :
369 : void
370 0 : dbe::models::tree::objectsUpdated(const std::vector<dbe::dref>& objects)
371 : {
372 0 : update_multiple_objects(objects);
373 0 : }
374 :
375 : //----------------------------------------------------------------------------------------------------
376 :
377 : //----------------------------------------------------------------------------------------------------
378 0 : MODEL_COMMON_INTERFACE_LOOKUP_IMPL(dbe::models::tree)
379 : {
380 0 : if (treenode* classnode = confaccessor::gethandler()->getnode(QString::fromStdString(obj.class_name()))) {
381 :
382 0 : auto found = [&obj, classnode](int i) {
383 0 : return obj.UID() == classnode->GetChild(i)->GetData(0).toString().toStdString();
384 0 : };
385 :
386 0 : int i = 0;
387 0 : int const childs = classnode->ChildCount();
388 :
389 0 : for (; i < childs and not found(i); ++i)
390 :
391 : ;
392 :
393 0 : QModelIndex parent_index = getindex(classnode);
394 :
395 0 : return childs == i ? QModelIndex() : index(i, parent_index.column(), parent_index);
396 : }
397 :
398 0 : return QModelIndex();
399 : }
400 :
401 0 : MODEL_COMMON_INTERFACE_CREATE_THAT_OBJ_IMPL(dbe::models::tree)
402 : {
403 0 : Q_UNUSED(index);
404 0 : if (treenode* classnode = confaccessor::gethandler()->getnode(obj.class_name())) {
405 0 : if (not dbe::datahandler::findchild(classnode, QString::fromStdString(obj.UID()))) {
406 0 : layoutAboutToBeChanged();
407 0 : new ObjectNode(obj, false, classnode);
408 : // Normally we would have to call changePersistentIndex.
409 : // Because an objectnode is created which had no index
410 : // before this creation had occured there is no need to call it.
411 0 : emit layoutChanged();
412 : }
413 : }
414 0 : }
415 :
416 0 : MODEL_COMMON_INTERFACE_DELETE_THAT_OBJ_IMPL(dbe::models::tree)
417 : {
418 0 : if (index.isValid()) {
419 0 : this->removeRows(index.row(), 1, index.parent());
420 : }
421 0 : }
422 :
423 0 : MODEL_COMMON_INTERFACE_RENAME_THAT_OBJ_IMPL(dbe::models::tree)
424 : {
425 0 : if (index.isValid()) {
426 0 : treenode* child = getnode(index);
427 0 : child->rename(QString::fromStdString(obj.ref().UID()));
428 0 : emit dataChanged(index, index);
429 : }
430 0 : }
431 :
432 0 : MODEL_COMMON_INTERFACE_UPDATE_THAT_OBJ_IMPL(dbe::models::tree)
433 : {
434 : // Some form of change has occured , we remove and insert a new object node
435 : // for the specified object
436 0 : if (index.isValid()) {
437 : // This in the worst case return a pointer to root in the tree
438 0 : treenode* child = getnode(index);
439 :
440 0 : if (treenode* parent = child->GetParent()) {
441 0 : emit layoutAboutToBeChanged();
442 0 : parent->RemoveChild(child);
443 0 : new ObjectNode(obj, false, parent);
444 0 : emit layoutChanged();
445 : }
446 : }
447 0 : }
448 :
449 : //----------------------------------------------------------------------------------------------------
450 :
451 : //----------------------------------------------------------------------------------------------------
452 0 : TREEMODEL_REMOVE_ROWS_DEF(dbe::models::tree)
453 0 : MODEL_COMMON_INTERFACE_SLOTS_DEF(dbe::models::tree)
454 : //----------------------------------------------------------------------------------------------------
|