Line data Source code
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 :
6 : /// Including QT Headers
7 : #include "dbe/subtreeproxy.hpp"
8 : #include "dbe/tree.hpp"
9 :
10 : #include "dbe/treenode.hpp"
11 : #include "dbe/treeselection.hpp"
12 :
13 : #include <QContextMenuEvent>
14 : #include <QAction>
15 : #include <QMenu>
16 : #include <QMessageBox>
17 :
18 : /// Including DBE
19 : #include "dbe/CustomTreeView.hpp"
20 : #include "dbe/TreeModelInterface.hpp"
21 : #include "dbe/ObjectCreator.hpp"
22 : #include "dbe/ObjectEditor.hpp"
23 : #include "dbe/messenger.hpp"
24 :
25 : //------------------------------------------------------------------------------------------
26 0 : dbe::CustomTreeView::CustomTreeView ( QWidget * Parent )
27 : : QTreeView ( Parent ),
28 0 : contextMenu ( nullptr )
29 : {
30 0 : setDragEnabled ( true );
31 0 : setSortingEnabled ( true );
32 0 : setExpandsOnDoubleClick ( false );
33 0 : CreateActions();
34 0 : setSelectionMode ( QAbstractItemView::ExtendedSelection );
35 0 : setUniformRowHeights(true);
36 0 : }
37 : //------------------------------------------------------------------------------------------
38 :
39 : //------------------------------------------------------------------------------------------
40 0 : void dbe::CustomTreeView::contextMenuEvent ( QContextMenuEvent * Event )
41 : {
42 0 : if ( contextMenu == nullptr )
43 : {
44 0 : contextMenu = new QMenu ( this );
45 0 : contextMenu->addAction ( editObjectAc );
46 0 : contextMenu->addAction ( deleteObjectAc );
47 0 : contextMenu->addAction ( createObjectAc );
48 0 : contextMenu->addAction ( deleteObjectWidgetAc );
49 0 : contextMenu->addAction ( copyObjectAc );
50 0 : contextMenu->addAction ( buildTableFromClassAc );
51 0 : contextMenu->addAction ( expandAllAc );
52 0 : contextMenu->addAction ( collapseAllAc );
53 0 : contextMenu->addAction ( refByAc );
54 0 : contextMenu->addAction ( refByAcOnlyComp );
55 : }
56 :
57 0 : model_common_interface * modelInterface =
58 0 : dynamic_cast<model_common_interface *> ( this->model() );
59 0 : QModelIndex index = this->currentIndex();
60 :
61 0 : if ( index.isValid() )
62 : {
63 0 : if ( modelInterface )
64 : {
65 :
66 0 : try
67 : {
68 0 : tref obj = modelInterface->getobject ( index );
69 0 : ( contextMenu->actions() ).at ( 0 )->setVisible ( true );
70 0 : ( contextMenu->actions() ).at ( 1 )->setVisible ( true );
71 0 : ( contextMenu->actions() ).at ( 2 )->setVisible ( true );
72 0 : ( contextMenu->actions() ).at ( 3 )->setVisible ( false );
73 0 : ( contextMenu->actions() ).at ( 4 )->setVisible ( true );
74 0 : ( contextMenu->actions() ).at ( 5 )->setVisible ( false );
75 0 : ( contextMenu->actions() ).at ( 6 )->setVisible ( false );
76 0 : ( contextMenu->actions() ).at ( 7 )->setVisible ( false );
77 0 : ( contextMenu->actions() ).at ( 8 )->setVisible ( true );
78 0 : ( contextMenu->actions() ).at ( 9 )->setVisible ( true );
79 0 : }
80 0 : catch ( daq::dbe::cannot_handle_invalid_qmodelindex const & e )
81 : {
82 0 : ( contextMenu->actions() ).at ( 0 )->setVisible ( false );
83 0 : ( contextMenu->actions() ).at ( 1 )->setVisible ( false );
84 0 : ( contextMenu->actions() ).at ( 2 )->setVisible ( true );
85 0 : ( contextMenu->actions() ).at ( 3 )->setVisible ( false );
86 0 : ( contextMenu->actions() ).at ( 4 )->setVisible ( false );
87 0 : ( contextMenu->actions() ).at ( 5 )->setVisible ( false );
88 0 : ( contextMenu->actions() ).at ( 6 )->setVisible ( false );
89 0 : ( contextMenu->actions() ).at ( 7 )->setVisible ( false );
90 0 : ( contextMenu->actions() ).at ( 8 )->setVisible ( false );
91 0 : ( contextMenu->actions() ).at ( 9 )->setVisible ( false );
92 0 : }
93 : }
94 :
95 0 : contextMenu->exec ( Event->globalPos() );
96 : }
97 0 : }
98 : //------------------------------------------------------------------------------------------
99 :
100 : //------------------------------------------------------------------------------------------
101 0 : void dbe::CustomTreeView::CreateActions()
102 : {
103 :
104 0 : editObjectAc = new QAction ( tr ( "&Edit Object" ), this );
105 0 : editObjectAc->setShortcut ( tr ( "Ctrl+E" ) );
106 0 : editObjectAc->setShortcutContext ( Qt::WidgetShortcut );
107 0 : connect ( editObjectAc, SIGNAL ( triggered() ), this, SLOT ( slot_edit_object() ) );
108 0 : addAction ( editObjectAc );
109 :
110 0 : deleteObjectAc = new QAction ( tr ( "&Delete Object" ), this );
111 0 : deleteObjectAc->setShortcut ( tr ( "Ctrl+D" ) );
112 0 : deleteObjectAc->setShortcutContext ( Qt::WidgetShortcut );
113 0 : connect ( deleteObjectAc, SIGNAL ( triggered() ), this, SLOT ( slot_delete_objects() ) );
114 0 : addAction ( deleteObjectAc );
115 :
116 0 : createObjectAc = new QAction ( tr ( "Create &New Object" ), this );
117 0 : createObjectAc->setShortcut ( tr ( "Ctrl+N" ) );
118 0 : createObjectAc->setShortcutContext ( Qt::WidgetShortcut );
119 0 : connect ( createObjectAc, SIGNAL ( triggered() ), this, SLOT ( slot_create_object() ) );
120 0 : addAction ( createObjectAc );
121 :
122 0 : copyObjectAc = new QAction ( tr ( "&Copy This Object Into A New One" ), this );
123 0 : copyObjectAc->setShortcut ( tr ( "Ctrl+Shift+N" ) );
124 0 : copyObjectAc->setShortcutContext ( Qt::WidgetShortcut );
125 0 : connect ( copyObjectAc, SIGNAL ( triggered() ), this, SLOT ( slot_copy_object() ) );
126 0 : addAction ( copyObjectAc );
127 :
128 0 : deleteObjectWidgetAc = new QAction ( tr ( "Delete Object &Widget" ), this );
129 0 : deleteObjectWidgetAc->setShortcut ( tr ( "Ctrl+W" ) );
130 0 : deleteObjectWidgetAc->setShortcutContext ( Qt::WidgetShortcut );
131 0 : addAction ( deleteObjectWidgetAc );
132 :
133 0 : buildTableFromClassAc = new QAction ( tr ( "Build Tab&le From Class" ), this );
134 0 : buildTableFromClassAc->setShortcut ( tr ( "Ctrl+L" ) );
135 0 : buildTableFromClassAc->setShortcutContext ( Qt::WidgetShortcut );
136 0 : addAction ( buildTableFromClassAc );
137 :
138 0 : expandAllAc = new QAction ( tr ( "Expand &All" ), this );
139 0 : expandAllAc->setShortcut ( tr ( "Ctrl+A" ) );
140 0 : expandAllAc->setShortcutContext ( Qt::WidgetShortcut );
141 0 : connect ( expandAllAc, SIGNAL ( triggered() ), this,
142 : SLOT ( expandAll() ) ); // QTreeView slot
143 0 : addAction ( expandAllAc );
144 :
145 0 : collapseAllAc = new QAction ( tr ( "C&ollapse All" ), this );
146 0 : collapseAllAc->setShortcut ( tr ( "Ctrl+Shift+C" ) );
147 0 : collapseAllAc->setShortcutContext ( Qt::WidgetShortcut );
148 0 : connect ( collapseAllAc, SIGNAL ( triggered() ), this,
149 : SLOT ( collapseAll() ) ); // QTreeView slot
150 0 : addAction ( collapseAllAc );
151 :
152 0 : refByAc = new QAction ( tr ( "&Referenced By (All objects)" ), this );
153 0 : refByAc->setShortcut ( tr ( "Ctrl+Y" ) );
154 0 : refByAc->setShortcutContext ( Qt::WidgetShortcut );
155 0 : refByAc->setToolTip ( "Find all objects which reference the selecetd object" );
156 0 : refByAc->setStatusTip ( refByAc->toolTip() );
157 0 : connect ( refByAc, SIGNAL ( triggered() ), this, SLOT ( referencedByAll() ) );
158 0 : addAction ( refByAc );
159 :
160 0 : refByAcOnlyComp = new QAction ( tr ( "Referenced B&y (Only Composite)" ), this );
161 0 : refByAcOnlyComp->setShortcut ( tr ( "Ctrl+Shift+Y" ) );
162 0 : refByAcOnlyComp->setShortcutContext ( Qt::WidgetShortcut );
163 0 : refByAcOnlyComp->setToolTip (
164 : "Find objects (ONLY Composite ones) which reference the selecetd object" );
165 0 : refByAcOnlyComp->setStatusTip ( refByAcOnlyComp->toolTip() );
166 0 : connect ( refByAcOnlyComp, SIGNAL ( triggered() ), this,
167 : SLOT ( referencedbyOnlycomposite() ) );
168 0 : addAction ( refByAcOnlyComp );
169 0 : }
170 : //------------------------------------------------------------------------------------------
171 :
172 : //------------------------------------------------------------------------------------------
173 0 : void dbe::CustomTreeView::slot_create_object()
174 : {
175 : // To create an object we only need to extract the information of the class that the
176 : // user had clicked onto.
177 0 : model_common_interface * common_model = dynamic_cast<model_common_interface *> ( model() );
178 0 : QModelIndex const & treeindex = currentIndex();
179 0 : treenode * cnode = nullptr;
180 :
181 0 : if ( common_model && treeindex.isValid() )
182 : {
183 0 : dunedaq::conffwk::class_t classinfo = common_model->getclass ( treeindex );
184 :
185 0 : if ( dynamic_cast<models::treeselection *> ( model() ) )
186 : {
187 0 : models::treeselection * selectionmodel = dynamic_cast<models::treeselection *> ( model() );
188 :
189 0 : if ( selectionmodel )
190 : {
191 0 : QModelIndex const & srcindex = selectionmodel->mapToSource ( treeindex );
192 :
193 0 : if ( dbe::models::tree * tree_model = dynamic_cast<dbe::models::tree *>
194 0 : ( selectionmodel->sourceModel() )
195 : )
196 : {
197 0 : cnode = tree_model->getnode ( srcindex );
198 : }
199 : }
200 : }
201 0 : else if ( dbe::models::subtree_proxy * subtree_model =
202 0 : dynamic_cast<dbe::models::subtree_proxy *> ( model() ) )
203 : {
204 0 : cnode = subtree_model->getnode ( treeindex );
205 : }
206 :
207 0 : if ( dynamic_cast<RelationshipNode *> ( cnode ) )
208 : {
209 0 : treenode * parent = cnode->GetParent();
210 0 : ObjectNode * NodeObject = dynamic_cast<ObjectNode *> ( parent );
211 0 : RelationshipNode * RelationshipTreeNode = dynamic_cast<RelationshipNode *> ( cnode );
212 :
213 0 : ( new ObjectCreator ( NodeObject->GetObject(),
214 0 : RelationshipTreeNode->relation_t() ) )->show();
215 : }
216 : else
217 : {
218 0 : ( new ObjectCreator ( classinfo ) )->show();
219 : }
220 0 : }
221 0 : }
222 : //------------------------------------------------------------------------------------------
223 :
224 : //------------------------------------------------------------------------------------------
225 0 : void dbe::CustomTreeView::slot_delete_objects()
226 : {
227 0 : if ( this->model() != nullptr )
228 : {
229 0 : QModelIndexList qindices = this->selectedIndexes();
230 0 : std::vector<QModelIndex> indices;
231 :
232 0 : for ( QModelIndex const & q : qindices )
233 : {
234 0 : if ( q.isValid() and q.column() == 0 )
235 : {
236 0 : indices.push_back ( q );
237 : }
238 : }
239 :
240 0 : if ( models::treeselection * casted_model = dynamic_cast<models::treeselection *> ( this
241 0 : ->model() )
242 : )
243 : {
244 0 : casted_model->delete_objects ( indices.begin(), indices.end() );
245 : }
246 0 : else if ( dbe::models::subtree_proxy * casted_model =
247 0 : dynamic_cast<dbe::models::subtree_proxy *>
248 0 : ( this->model() ) )
249 : {
250 0 : casted_model->delete_objects ( indices.begin(), indices.end() );
251 : }
252 : else
253 : {
254 0 : WARN ( "Object Deleting",
255 : "Object deletion failed due to the internal model being in invalid state",
256 0 : "You are advised to restart the application before proceeding any further" );
257 : }
258 :
259 0 : }
260 0 : }
261 : //------------------------------------------------------------------------------------------
262 :
263 : //------------------------------------------------------------------------------------------
264 0 : void dbe::CustomTreeView::slot_edit_object()
265 : {
266 0 : if ( this->model() != nullptr )
267 : {
268 0 : QModelIndexList indices = this->selectedIndexes();
269 :
270 0 : for ( QModelIndex const & q : indices )
271 : {
272 0 : edit_object ( q );
273 : }
274 0 : }
275 0 : }
276 : //------------------------------------------------------------------------------------------
277 :
278 : //------------------------------------------------------------------------------------------
279 0 : void dbe::CustomTreeView::edit_object ( QModelIndex const & index )
280 : {
281 0 : model_common_interface * filtermodel = dynamic_cast<model_common_interface *> ( model() );
282 :
283 0 : if ( !index.isValid() )
284 : {
285 : return;
286 : }
287 :
288 0 : if ( filtermodel )
289 : {
290 0 : try
291 : {
292 0 : tref obj = filtermodel->getobject ( index );
293 0 : bool WidgetFound = false;
294 0 : QString ObjectEditorName = QString ( "%1@%2" ).arg ( obj.UID().c_str() ).arg (
295 0 : obj.class_name().c_str() );
296 :
297 0 : for ( QWidget * Editor : QApplication::allWidgets() )
298 : {
299 0 : ObjectEditor * Widget = dynamic_cast<ObjectEditor *> ( Editor );
300 :
301 0 : if ( Widget != nullptr )
302 : {
303 0 : if ( ( Widget->objectName() ).compare ( ObjectEditorName ) == 0 )
304 : {
305 0 : Widget->raise();
306 0 : Widget->setVisible ( true );
307 : WidgetFound = true;
308 : }
309 : }
310 0 : }
311 :
312 0 : if ( !WidgetFound )
313 : {
314 0 : ( new ObjectEditor ( obj ) )->show();
315 : }
316 0 : }
317 0 : catch ( daq::dbe::cannot_handle_invalid_qmodelindex const & e )
318 : {
319 : // nothing to do , maybe the user just clicked the wrong place
320 0 : }
321 : }
322 : }
323 : //------------------------------------------------------------------------------------------
324 :
325 : //------------------------------------------------------------------------------------------
326 0 : void dbe::CustomTreeView::slot_copy_object()
327 : {
328 0 : model_common_interface * filtermodel = dynamic_cast<model_common_interface *> ( model() );
329 0 : QModelIndex i = currentIndex();
330 :
331 0 : if ( i.isValid() and filtermodel )
332 : {
333 0 : try
334 : {
335 0 : ( new ObjectCreator ( filtermodel->getobject ( i ) ) )->show();
336 : }
337 0 : catch ( daq::dbe::cannot_handle_invalid_qmodelindex const & e )
338 : {
339 : //TODO the index can be invalid in this case
340 0 : }
341 : }
342 0 : }
343 : //------------------------------------------------------------------------------------------
344 0 : void dbe::CustomTreeView::referencedbyOnlycomposite()
345 : {
346 0 : referencedBy ( true );
347 0 : }
348 :
349 0 : void dbe::CustomTreeView::referencedByAll()
350 : {
351 0 : referencedBy ( false );
352 0 : }
353 : //------------------------------------------------------------------------------------------
354 0 : void dbe::CustomTreeView::closeEvent(QCloseEvent * event) {
355 : // Reset the model when the widget is closed
356 : // If not done, reference to removed objects may create issues
357 0 : models::treeselection* filtermodel = dynamic_cast<models::treeselection*>(model());
358 :
359 0 : setModel(nullptr);
360 :
361 0 : if(filtermodel != nullptr) {
362 0 : filtermodel->ResetQueryObjects();
363 0 : filtermodel->deleteLater();
364 : }
365 :
366 0 : event->accept();
367 0 : }
368 :
369 : //------------------------------------------------------------------------------------------
370 0 : void dbe::CustomTreeView::referencedBy ( bool All )
371 : {
372 0 : model_common_interface * filtermodel = dynamic_cast<model_common_interface *> ( model() );
373 0 : QModelIndex Index = currentIndex();
374 :
375 0 : if ( !Index.isValid() )
376 : {
377 0 : return;
378 : }
379 :
380 0 : if ( filtermodel )
381 : {
382 :
383 0 : try
384 : {
385 0 : tref obj = filtermodel->getobject ( Index );
386 0 : std::vector<tref> objects;
387 :
388 0 : if ( not obj.is_null() )
389 : {
390 0 : objects = obj.referenced_by ( "*", All );
391 : }
392 :
393 0 : if ( objects.size() > 0 )
394 : {
395 0 : dbe::models::tree * Source = dynamic_cast<dbe::models::tree *> ( filtermodel
396 0 : ->ReturnSourceModel() );
397 0 : models::treeselection * Selection = new models::treeselection();
398 0 : Selection->SetFilterType ( models::treeselection::ObjectFilterType );
399 0 : Selection->SetQueryObjects ( objects );
400 0 : Selection->setFilterRegExp ( "Dummy" );
401 0 : Selection->setSourceModel ( Source );
402 :
403 0 : CustomTreeView * tView = new CustomTreeView ( 0 );
404 0 : tView->setModel ( Selection );
405 0 : tView->setWindowTitle ( QString ( "Objects referencing '%1'" ).arg ( obj.UID().c_str() ) );
406 0 : tView->setSortingEnabled ( true );
407 0 : tView->setAlternatingRowColors ( true );
408 0 : tView->resizeColumnToContents ( 0 );
409 0 : tView->resizeColumnToContents ( 1 );
410 0 : tView->setAttribute(Qt::WA_DeleteOnClose);
411 :
412 0 : connect ( tView, SIGNAL ( doubleClicked ( QModelIndex ) ),
413 : tView, SLOT ( slot_edit_object () ) );
414 :
415 0 : tView->show();
416 : }
417 : else
418 : {
419 0 : if ( All )
420 : {
421 0 : WARN ( "No references of only composite objects have been found for object", " ",
422 0 : "with UID:", obj.UID(), "of class", obj.class_name() );
423 : }
424 : else
425 : {
426 0 : WARN ( "No references of objects have been found for object", " ", "with UID:",
427 0 : obj.UID(), "of class", obj.class_name() );
428 : }
429 : }
430 0 : }
431 0 : catch ( daq::dbe::cannot_handle_invalid_qmodelindex const & e )
432 0 : {}
433 : }
434 : }
435 : //------------------------------------------------------------------------------------------
436 :
437 : //------------------------------------------------------------------------------------------
438 0 : void dbe::CustomTreeView::referencedBy ( bool All, tref obj )
439 : {
440 0 : model_common_interface * filtermodel = dynamic_cast<model_common_interface *> ( model() );
441 :
442 0 : if ( filtermodel )
443 : {
444 0 : std::vector<tref> objects;
445 :
446 0 : if ( !obj.is_null() )
447 : {
448 0 : objects = obj.referenced_by ( "*", All );
449 : }
450 :
451 0 : if ( objects.size() > 0 )
452 : {
453 0 : dbe::models::tree * Source = dynamic_cast<dbe::models::tree *> ( filtermodel
454 0 : ->ReturnSourceModel() );
455 0 : models::treeselection * Selection = new models::treeselection();
456 0 : Selection->SetFilterType ( models::treeselection::ObjectFilterType );
457 0 : Selection->SetQueryObjects ( objects );
458 0 : Selection->setFilterRegExp ( "Dummy" );
459 0 : Selection->setSourceModel ( Source );
460 :
461 0 : CustomTreeView * tView = new CustomTreeView ( 0 );
462 0 : tView->setModel ( Selection );
463 0 : tView->setSortingEnabled ( true );
464 0 : tView->setAlternatingRowColors ( true );
465 0 : tView->resizeColumnToContents ( 0 );
466 0 : tView->hideColumn ( 1 );
467 : //tView->resizeColumnToContents(1);
468 0 : tView->setWindowTitle ( QString ( "Objects referencing '%1'" ).arg ( obj.UID().c_str() ) );
469 0 : tView->setAttribute(Qt::WA_DeleteOnClose);
470 :
471 0 : connect ( tView, SIGNAL ( doubleClicked ( QModelIndex ) ), tView,
472 : SLOT ( slot_edit_object () ) );
473 :
474 0 : tView->show();
475 : }
476 : else
477 : {
478 0 : if ( All )
479 : {
480 0 : WARN ( "No references for object", "Only Composite Objects - Not found", "with UID:",
481 0 : obj.UID() );
482 : }
483 : else
484 : {
485 0 : WARN ( "No references for object", "All Objects - Not found", "with UID:", obj.UID() );
486 : }
487 : }
488 0 : }
489 0 : }
490 : //------------------------------------------------------------------------------------------
|