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