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