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