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