DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
table.cpp
Go to the documentation of this file.
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
7#include "dbe/table.hpp"
8#include "dbe/Conversion.hpp"
9#include "dbe/Exceptions.hpp"
10#include "dbe/StyleUtility.hpp"
11#include "dbe/confaccessor.hpp"
13#include "dbe/dbcontroller.hpp"
14#include "dbe/messenger.hpp"
15#include "dbe/treenode.hpp"
16
17#include <QBrush>
18#include <QFont>
19#include <QMimeData>
20
21#include <bitset>
22
24 : QAbstractTableModel(parent)
25 , enabled(false)
26{
28}
29
31
32int
33dbe::models::table::rowCount(const QModelIndex& parent) const
34{
35 if (!parent.isValid()) {
36 return this_structure.size();
37 }
38
39 return 0;
40}
41
42int
43dbe::models::table::columnCount(const QModelIndex& parent) const
44{
45 if (!parent.isValid()) {
46 return this_headers.size();
47 }
48
49 return 0;
50}
51
52QVariant
53dbe::models::table::data(const QModelIndex& index, int role) const
54{
55
56 if (index.isValid()) {
57 TableNode* TableItem = getnode(index);
58
59 if (role == Qt::DisplayRole) {
60 QString Data;
61
62 for (QString const& i : TableItem->GetData()) {
63 static QString space{ ", " };
64 Data.append(i).append(space);
65 }
66 Data.remove(Data.length() - 2, 2);
67
68 return QVariant(Data);
69 }
70
71 if (role == Qt::ToolTipRole) {
72 return TableItem->get_tooltip();
73 }
74 if (role == Qt::FontRole) {
75 if (dynamic_cast<TableAttributeNode*>(TableItem))
76 return QFont("Helvetica", 10, -1, false);
77 else if (dynamic_cast<TableRelationshipNode*>(TableItem))
78 return QFont("Courier", 10, QFont::Bold);
79 else {
80 return QFont("SansSerif", 10, QFont::Bold);
81 }
82 }
83
84 if (role == Qt::ForegroundRole) {
85 if (dynamic_cast<TableAttributeNode*>(TableItem))
87 else if (dynamic_cast<TableRelationshipNode*>(TableItem))
89 else {
90 dref obj_desc = this_objects[index.row()];
91 tref Object = dbe::inner::dbcontroller::get({ obj_desc.UID(), obj_desc.class_name() });
92 if (!confaccessor::check_file_rw(QString::fromStdString(Object.contained_in()))) {
94 }
95 return QVariant();
96 }
97 }
98
99 if (role == Qt::BackgroundRole) {
100 auto attr_node = dynamic_cast<TableAttributeNode*>(TableItem);
101 if (attr_node != nullptr) {
102 auto val = attr_node->GetData();
103 if (val.size() == 1 && val[0].toStdString() == attr_node->GetAttribute().p_default_value) {
105 }
107 } else if (dynamic_cast<TableRelationshipNode*>(TableItem)) {
109 } else {
110 dref obj_desc = this_objects[index.row()];
111 tref Object = dbe::inner::dbcontroller::get({ obj_desc.UID(), obj_desc.class_name() });
112 if (!confaccessor::check_file_rw(QString::fromStdString(Object.contained_in()))) {
114 }
115 }
116 }
117 }
118 return QVariant();
119}
120
121bool
122dbe::models::table::setData(const QModelIndex& index, const QVariant& value, int role)
123{
124 if (!index.isValid() || role != Qt::EditRole) {
125 return false;
126 }
127
128 TableNode* TableItem = getnode(index);
129
130 QStringList OldDataList = TableItem->GetData();
131
132 QStringList NewDataList = value.toStringList();
133
134 if (NewDataList == OldDataList) {
135 return false;
136 }
137
138 dref obj_desc = this_objects[index.row()];
139
140 tref Object = dbe::inner::dbcontroller::get({ obj_desc.UID(), obj_desc.class_name() });
141
142 if (dynamic_cast<TableRelationshipNode*>(TableItem)) {
144 dunedaq::conffwk::relationship_t RelationshipData = RelationshipNode->GetRelationship();
145 dbe::config::api::set::relation(Object, RelationshipData, NewDataList);
146 } else if (dynamic_cast<TableAttributeNode*>(TableItem)) {
147 TableAttributeNode* AttributeNode = dynamic_cast<TableAttributeNode*>(TableItem);
148 dunedaq::conffwk::attribute_t AttributeData = AttributeNode->GetAttribute();
149 dbe::config::api::set::attribute(Object, AttributeData, NewDataList);
150 }
151
152 return true;
153}
154
155QVariant
156dbe::models::table::headerData(int section, Qt::Orientation orientation, int role) const
157{
158 if (role == Qt::DisplayRole) {
159 if (orientation == Qt::Horizontal) {
160 return this_headers.at(section);
161 }
162 if (orientation == Qt::Vertical) {
163 return section + 1;
164 }
165 }
166
167 if (role == Qt::FontRole) {
168 return QFont("Helvetica [Cronyx]", 10);
169 }
170
171 return QVariant();
172}
173
174Qt::ItemFlags
175dbe::models::table::flags(const QModelIndex& index) const
176{
177 if (index.isValid()) {
178 dref obj_desc = this_objects[index.row()];
179 tref Object = dbe::inner::dbcontroller::get({ obj_desc.UID(), obj_desc.class_name() });
180
181 if (confaccessor::check_file_rw(QString::fromStdString(Object.contained_in()))) {
182 return (Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled);
183 }
184 }
185
186 return (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
187}
188
189Qt::DropActions
191{
192 return Qt::CopyAction;
193}
194
195QStringList
197{
198 QStringList types;
199 types << "application/vnd.text.list";
200 return types;
201}
202
203bool
205 Qt::DropAction action,
206 int row,
207 int column,
208 const QModelIndex& parent)
209{
210 Q_UNUSED(row)
211 Q_UNUSED(column)
212 Q_UNUSED(parent)
213
214 bool Accept = true;
215
216 if (action == Qt::IgnoreAction) {
217 return true;
218 }
219
220 if (!data->hasFormat("application/vnd.text.list")) {
221 return false;
222 }
223
225 QByteArray encodedData = data->data("application/vnd.text.list");
226
227 QDataStream stream(&encodedData, QIODevice::ReadOnly);
228
229 QList<QStringList> newItems;
230
231 while (!stream.atEnd()) {
232 QStringList text;
233 stream >> text;
234 newItems << text;
235 }
236
237 for (int i = 0; i < newItems.size(); ++i) {
238 if (newItems.at(0).at(1) != newItems.at(i).at(1)) {
239 Accept = false;
240 }
241 }
242
243 if (Accept) {
244 BuildTableFromObject(newItems);
245 emit ResetTab();
246 }
247
248 return Accept;
249}
250
251bool
252dbe::models::table::BuildTableFromClass(const QString& cname, bool include_derived)
253{
254 reset(cname);
255
257
258 dunedaq::conffwk::class_t classinfo = dbe::config::api::info::onclass::definition(cname.toStdString(), false);
259
260 setheader(classinfo);
261
262 if (treenode* NodeClass = dbaccess_guard->getnode(cname)) {
263 std::vector<treenode*> classnodes{ NodeClass };
264
265 if (include_derived) {
266
267 for (std::string const& sbcname : classinfo.p_subclasses) {
268 if (treenode* sbcnode = dbaccess_guard->getnode(sbcname)) {
269 classnodes.push_back(sbcnode);
270 }
271 }
272 }
273
276
277 for (treenode* clelement : classnodes) {
279
280 for (treenode* child : clelement->GetChildren()) {
281 this_structure.append(createrow(child));
282 }
283 }
284
285 enabled = true;
286 return true;
287 } else {
288 return false;
289 }
290}
291
292QList<dbe::models::table::type_datum*>
294{
295
296 dref obj = rownode->GetObject();
297
298 this_objects.append(obj);
299
300 dunedaq::conffwk::class_t const& cdef = dbe::config::api::info::onclass::definition(obj.class_name(), false);
301 std::vector<dunedaq::conffwk::attribute_t> const& attributes = cdef.p_attributes;
302 std::vector<dunedaq::conffwk::relationship_t> const& relations = cdef.p_relationships;
303
304 assert(attributes.size() + relations.size() < 1025);
305 std::bitset<1024> hindex; // maximum number of columns to display
306
307 {
308 int column = 0;
309
310 for (dunedaq::conffwk::attribute_t const& attr : attributes) {
311 hindex.set(column++, this_headers.contains(QString::fromStdString(attr.p_name)));
312 }
313
314 for (dunedaq::conffwk::relationship_t const& rel : relations) {
315 hindex.set(column++, this_headers.contains(QString::fromStdString(rel.p_name)));
316 }
317 }
318
319 // Create the row for this object
320 QList<TableNode*> Row;
321 Row.append(
322 new TableNode(QStringList{ rownode->GetData(0).toString() }, QVariant(QString::fromStdString(cdef.p_description))));
323 {
324 // Loop over object values and add them to the row
325 // Values are represent as nodes ( attributes or relations ) and these contain
326 // the structured data associated either with a attribute / multi-attribute or a relation
327 std::size_t column = 0;
328
329 for (treenode* valuenode : rownode->GetChildren()) {
330 QStringList values;
331 // Every valuenode has its attributes and relations defined as its childs
332
333 if (hindex[column++]) {
334
335 for (treenode* nodevalues : valuenode->GetChildren()) {
336 // Here we need to filter such that only values corresponding to the header are kept
337 // Add only the first of values in a list of values
338 values.append(nodevalues->GetData(0).toString());
339 }
340
341 if (AttributeNode* NodeAttribute = dynamic_cast<AttributeNode*>(valuenode)) {
342 Row.append(new TableAttributeNode(NodeAttribute->attribute_t(), values));
343 } else if (RelationshipNode* NodeRelationship = dynamic_cast<RelationshipNode*>(valuenode)) {
344 Row.append(new TableRelationshipNode(NodeRelationship->relation_t(), values));
345 }
346 }
347 }
348 }
349
350 return Row;
351}
352
353void
354dbe::models::table::reset(QString const& cname)
355{
356
357 for (auto& List : this_structure) {
358 qDeleteAll(List);
359 }
360
361 this_objects.clear();
362 this_structure.clear();
363 this_headers.clear();
364 this_class_name = cname;
365}
366
367void
369{
370 if (!this_headers.contains("Object Name")) {
371 this_headers.append("Object Name");
372 }
373
374 for (auto& i : cinfo.p_attributes) {
375 if (!this_headers.contains(QString::fromStdString(i.p_name))) {
376 this_headers.append(QString::fromStdString(i.p_name));
377 }
378 }
379
380 for (auto& i : cinfo.p_relationships) {
381 if (!this_headers.contains(QString::fromStdString(i.p_name))) {
382 this_headers.append(QString::fromStdString(i.p_name));
383 }
384 }
385}
386
387bool
388dbe::models::table::BuildTableFromObject(QList<QStringList> BuildList)
389{
390 reset(BuildList.at(0).at(1));
391
392 treenode* classnode = confaccessor::gethandler()->getnode(this_class_name);
393
394 dunedaq::conffwk::class_t classinfo =
396
397 setheader(classinfo);
398
399 confaccessor::gethandler()->FetchMore(classnode);
400
401 for (const QStringList& i : BuildList) {
402 QString name = i.at(0);
403 treenode* node = confaccessor::gethandler()->getnode(this_class_name, name);
404 this_structure.append(createrow(node));
405 }
406
407 enabled = false;
408 return true;
409}
410
413{
414 return this_objects.at(ObjectIndex).ref();
415}
416
417bool
419{
420 return enabled;
421}
422
423QString
428
429QAbstractItemModel*
431{
432 return nullptr;
433}
434
435QList<dbe::dref>*
440
442dbe::models::table::getnode(const QModelIndex& Index) const
443{
444 if (Index.isValid()) {
445 return this_structure.at(Index.row()).at(Index.column());
446 }
447
448 return nullptr;
449}
450
451void
453{
454 beginResetModel();
455 endResetModel();
456}
457
458void
459dbe::models::table::slot_data_dropped(QMimeData const& data, Qt::DropAction action)
460{
461 QModelIndex dum;
462 this->dropMimeData(&data, action, 0, 0, dum);
463}
464
466dbe::models::table::getobject(QModelIndex const& index) const
467{
468 if (index.isValid()) {
469 return this_objects[index.row()].ref();
470 }
471
472 throw daq::dbe::cannot_handle_invalid_qmodelindex(ERS_HERE);
473}
474
476dbe::models::table::getclass(QModelIndex const& index) const
477{
478 if (index.isValid()) {
479 return class_type_info;
480 }
481
482 return dunedaq::conffwk::class_t();
483}
484
485void
486dbe::models::table::objectsUpdated(const std::vector<dbe::dref>& objects)
487{
489}
490
491//-----------------------------------------------------------------------------------------------------
493{
494 Q_UNUSED(index);
495 if (treenode* handlerclass = confaccessor::gethandler()->getnode(obj.class_name())) {
496 if (obj.class_name() == this_class_name.toStdString() or
497 config::api::info::onclass::derived(this_class_name.toStdString(), obj.class_name())) {
498
499 dbe::treenode const* handlernode = dbe::datahandler::findchild(handlerclass, QString::fromStdString(obj.UID()));
500
501 if (handlernode == nullptr) {
502 handlernode = new ObjectNode(obj, false, handlerclass);
503 }
504
505 emit layoutAboutToBeChanged();
506
507 // We assume that the objects are sorted and we want to insert a new element
508
509 tref const handlerobj = handlernode->GetObject();
510 auto sit = this_structure.begin();
511 auto it = this_objects.begin();
512
513 for (; it != this_objects.end() and sit != this_structure.end() and it->UID() < handlerobj.UID(); ++it, ++sit) {
514 }
515
516 this_structure.insert(++sit, createrow(handlernode));
517
518 this_objects.insert(++it, handlerobj);
519
520 // Normally we would have to call changePersistentIndex.
521 // Because an objectnode is created which had no index
522 // before this creation had occured there is no need to call it.
523 emit layoutChanged();
524 }
525 }
526}
527
529{
530 if (index.isValid()) {
531 try {
532 this->removeRows(index.row(), 1, index.parent());
533 } catch (daq::dbe::ObjectChangeWasNotSuccessful const& err) {
534 WARN("Object cannot be deleted", dbe::config::errors::parse(err).c_str());
535 }
536 }
537}
538
540{
541 if (index.isValid()) {
542 type_datum* element = getnode(index);
543 element->resetdata(QStringList(QString::fromStdString(obj.ref().UID())));
544 this_objects[index.row()] = obj.ref();
545 emit dataChanged(index, index);
546 }
547}
548
550{
551 if (treenode* handlerclass = confaccessor::gethandler()->getnode(obj.class_name())) {
552 if (obj.class_name() == this_class_name.toStdString() or
553 config::api::info::onclass::derived(this_class_name.toStdString(), obj.class_name())) {
554 dbe::treenode const* handlernode = dbe::datahandler::findchild(handlerclass, QString::fromStdString(obj.UID()));
555
556 tref handlerobj = handlernode->GetObject();
557
558 auto sit = this_structure.begin();
559 auto it = this_objects.begin();
560
561 // find the object to be updated by looping through both objects and nodes
562
563 for (; it != this_objects.end() and sit != this_structure.end() and it->UID() != handlerobj.UID(); ++it, ++sit)
564
565 ;
566
567 // delete all table nodes in the list ( remove elements of the row )
568 for (TableNode* x : *sit) {
569 delete x;
570 }
571
572 // Recreate the row
573 *sit = createrow(handlernode);
574
575 int row = index.row() == 0 ? 0 : index.row() - 1;
576
577 int column = index.column() == 0 ? 0 : index.column() - 1;
578
579 emit dataChanged(createIndex(row, column), createIndex(row + 1, column + 1));
580 }
581 }
582}
583
584//----------------------------------------------------------------------------------------------------
585
586//-----------------------------------------------------------------------------------------------------
587MODEL_COMMON_INTERFACE_SLOTS_DEF(dbe::models::table)
588//-----------------------------------------------------------------------------------------------------
589
590//-----------------------------------------------------------------------------------------------------
592{
593 for (int row = 0; row < this_objects.size(); ++row) {
594 dref ListElement = this_objects.at(row);
595
596 if (ListElement.UID() == obj.UID()) {
597 return this->index(row, 0);
598 }
599 }
600
601 return QModelIndex();
602}
603
604//-----------------------------------------------------------------------------------------------------
605
606//-----------------------------------------------------------------------------------------------------
608{
609 beginRemoveRows(parent, row, row + count - 1);
610
611 for (; count != 0; --count) {
612 this_structure.removeOne(this_structure.at(row + count - 1));
613 this_objects.removeAt(row + count - 1);
614 }
615
616 endRemoveRows();
617 return true;
618}
619
620//-----------------------------------------------------------------------------------------------------
#define ERS_HERE
Definition cptr.hpp:56
ObjectNode(dref ObjectData, bool IsCopy, treenode *ParentNode)
Definition treenode.cpp:228
static QColor TableRelationshipBackground
static QColor FileReadOnlyForeground
static QColor TableColorAttribute
Including DBE.
static QColor TableAttributeBackground
static QColor DefaultValueBackground
static QColor TableColorRelationship
static QColor FileReadOnlyBackground
TableAttributeNode(dunedaq::conffwk::attribute_t Attribute, const QStringList &NodeData)
Definition TableNode.cpp:23
TableNode(QStringList const &NodeData, const QVariant &tooltip)
Including DBE.
Definition TableNode.cpp:9
const QVariant & get_tooltip() const
Definition TableNode.hpp:18
virtual QStringList GetData() const
Definition TableNode.cpp:18
TableRelationshipNode(dunedaq::conffwk::relationship_t Relationship, const QStringList &NodeData)
Definition TableNode.cpp:43
static cptr< datahandler > gethandler()
static bool check_file_rw(const QString &FileName)
static bool derived(std::string const &fromclass, std::string const &aclass)
static dunedaq::conffwk::class_t definition(std::string const &cn, bool direct_only)
static treenode * findchild(treenode *top, QString const &name)
dunedaq::conffwk::ConfigObject & ref(bool check_null=true) const
static configobject::tref get(dbe::cokey const &desc)
void update_multiple_objects(std::vector< type_object_info > const &)
table(QObject *parent=nullptr)
Including QT Headers.
Definition table.cpp:23
QList< type_datum * > createrow(treenode const *)
Definition table.cpp:293
TableNode * getnode(const QModelIndex &Index) const
Definition table.cpp:442
void reset(QString const &)
Definition table.cpp:354
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, type_index const &parent) override
Definition table.cpp:204
QList< dbe::dref > * GetTableObjects()
Definition table.cpp:436
Qt::DropActions supportedDropActions() const override
Definition table.cpp:190
int rowCount(type_index const &parent) const override
Definition table.cpp:33
QStringList mimeTypes() const override
Definition table.cpp:196
void setheader(dunedaq::conffwk::class_t const &)
Definition table.cpp:368
QVariant data(type_index const &index, int role) const override
Definition table.cpp:53
bool BuildTableFromObject(QList< QStringList > BuildList)
Definition table.cpp:388
bool is_built() const
Definition table.cpp:418
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Definition table.cpp:156
Qt::ItemFlags flags(type_index const &index) const override
Definition table.cpp:175
bool setData(type_index const &index, const QVariant &value, int role) override
Definition table.cpp:122
QString get_class_name() const
Definition table.cpp:424
QStringList this_headers
Definition table.hpp:79
QList< QList< TableNode * > > this_structure
Definition table.hpp:81
QString this_class_name
Definition table.hpp:76
void slot_data_dropped(QMimeData const &, Qt::DropAction)
Definition table.cpp:459
tref GetTableObject(int ObjectIndex) const
Definition table.cpp:412
int columnCount(type_index const &parent) const override
Definition table.cpp:43
bool BuildTableFromClass(const QString &ClassName, bool BuildSubClasses=false)
Definition table.cpp:252
QList< dref > this_objects
Definition table.hpp:80
void objectsUpdated(const std::vector< dbe::dref > &objects)
Definition table.cpp:486
virtual tref GetObject() const
Definition treenode.cpp:76
QList< treenode * > GetChildren() const
Definition treenode.cpp:110
virtual QVariant GetData(const int Column, int role=Qt::DisplayRole) const
Definition treenode.cpp:60
#define WARN(...)
Definition messenger.hpp:82
#define MODEL_COMMON_INTERFACE_LOOKUP_IMPL(classname)
#define MODEL_REMOVE_ROWS_DEF(classname)
#define MODEL_COMMON_INTERFACE_RENAME_THAT_OBJ_IMPL(classname)
#define MODEL_COMMON_INTERFACE_UPDATE_THAT_OBJ_IMPL(classname)
#define MODEL_COMMON_INTERFACE_DELETE_THAT_OBJ_IMPL(classname)
#define MODEL_COMMON_INTERFACE_SLOTS_DEF(classname)
#define MODEL_COMMON_INTERFACE_CREATE_THAT_OBJ_IMPL(classname)
void relation(dbe::inner::configobject::tref src, dunedaq::conffwk::relationship_t const &edge, QStringList const &targets)
void attribute(dbe::inner::configobject::tref objectref, dunedaq::conffwk::attribute_t const &attribute_info, QStringList const &attribute_values)
std::string const parse(ers::Issue const &)
Include QT Headers.
inner::configobject::tref tref
Definition tref.hpp:36
config_object_description dref
virtual type_class_info getclass(type_index const &index) const =0
virtual type_object_ref getobject(type_index const &index) const =0
virtual QAbstractItemModel * ReturnSourceModel() const =0
const std::vector< attribute_t > p_attributes
Definition Schema.hpp:161
const std::vector< relationship_t > p_relationships
Definition Schema.hpp:162
const std::vector< std::string > p_subclasses
Definition Schema.hpp:160
std::string p_description
Definition Schema.hpp:156