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