LCOV - code coverage report
Current view: top level - dbe/src/structure - CustomTreeView.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 255 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 13 0

            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 <QAction>
      14              : #include <QContextMenuEvent>
      15              : #include <QMenu>
      16              : #include <QMessageBox>
      17              : 
      18              : /// Including DBE
      19              : #include "dbe/CustomTreeView.hpp"
      20              : #include "dbe/ObjectCreator.hpp"
      21              : #include "dbe/ObjectEditor.hpp"
      22              : #include "dbe/TreeModelInterface.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              : void
      41            0 : dbe::CustomTreeView::contextMenuEvent(QContextMenuEvent* Event)
      42              : {
      43            0 :   if (contextMenu == nullptr) {
      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 = dynamic_cast<model_common_interface*>(this->model());
      58            0 :   QModelIndex index = this->currentIndex();
      59              : 
      60            0 :   if (index.isValid()) {
      61            0 :     if (modelInterface) {
      62              : 
      63            0 :       try {
      64            0 :         tref obj = modelInterface->getobject(index);
      65            0 :         (contextMenu->actions()).at(0)->setVisible(true);
      66            0 :         (contextMenu->actions()).at(1)->setVisible(true);
      67            0 :         (contextMenu->actions()).at(2)->setVisible(true);
      68            0 :         (contextMenu->actions()).at(3)->setVisible(false);
      69            0 :         (contextMenu->actions()).at(4)->setVisible(true);
      70            0 :         (contextMenu->actions()).at(5)->setVisible(false);
      71            0 :         (contextMenu->actions()).at(6)->setVisible(false);
      72            0 :         (contextMenu->actions()).at(7)->setVisible(false);
      73            0 :         (contextMenu->actions()).at(8)->setVisible(true);
      74            0 :         (contextMenu->actions()).at(9)->setVisible(true);
      75            0 :       } catch (daq::dbe::cannot_handle_invalid_qmodelindex const& e) {
      76            0 :         (contextMenu->actions()).at(0)->setVisible(false);
      77            0 :         (contextMenu->actions()).at(1)->setVisible(false);
      78            0 :         (contextMenu->actions()).at(2)->setVisible(true);
      79            0 :         (contextMenu->actions()).at(3)->setVisible(false);
      80            0 :         (contextMenu->actions()).at(4)->setVisible(false);
      81            0 :         (contextMenu->actions()).at(5)->setVisible(false);
      82            0 :         (contextMenu->actions()).at(6)->setVisible(false);
      83            0 :         (contextMenu->actions()).at(7)->setVisible(false);
      84            0 :         (contextMenu->actions()).at(8)->setVisible(false);
      85            0 :         (contextMenu->actions()).at(9)->setVisible(false);
      86            0 :       }
      87              :     }
      88              : 
      89            0 :     contextMenu->exec(Event->globalPos());
      90              :   }
      91            0 : }
      92              : //------------------------------------------------------------------------------------------
      93              : 
      94              : //------------------------------------------------------------------------------------------
      95              : void
      96            0 : 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("Find objects (ONLY Composite ones) which reference the selecetd object");
     159            0 :   refByAcOnlyComp->setStatusTip(refByAcOnlyComp->toolTip());
     160            0 :   connect(refByAcOnlyComp, SIGNAL(triggered()), this, SLOT(referencedbyOnlycomposite()));
     161            0 :   addAction(refByAcOnlyComp);
     162            0 : }
     163              : //------------------------------------------------------------------------------------------
     164              : 
     165              : //------------------------------------------------------------------------------------------
     166              : void
     167            0 : dbe::CustomTreeView::slot_create_object()
     168              : {
     169              :   // To create an object we only need to extract the information of the class that the
     170              :   // user had clicked onto.
     171            0 :   model_common_interface* common_model = dynamic_cast<model_common_interface*>(model());
     172            0 :   QModelIndex const& treeindex = currentIndex();
     173            0 :   treenode* cnode = nullptr;
     174              : 
     175            0 :   if (common_model && treeindex.isValid()) {
     176            0 :     dunedaq::conffwk::class_t classinfo = common_model->getclass(treeindex);
     177              : 
     178            0 :     if (dynamic_cast<models::treeselection*>(model())) {
     179            0 :       models::treeselection* selectionmodel = dynamic_cast<models::treeselection*>(model());
     180              : 
     181            0 :       if (selectionmodel) {
     182            0 :         QModelIndex const& srcindex = selectionmodel->mapToSource(treeindex);
     183              : 
     184            0 :         if (dbe::models::tree* tree_model = dynamic_cast<dbe::models::tree*>(selectionmodel->sourceModel())) {
     185            0 :           cnode = tree_model->getnode(srcindex);
     186              :         }
     187              :       }
     188            0 :     } else if (dbe::models::subtree_proxy* subtree_model = dynamic_cast<dbe::models::subtree_proxy*>(model())) {
     189            0 :       cnode = subtree_model->getnode(treeindex);
     190              :     }
     191              : 
     192            0 :     if (dynamic_cast<RelationshipNode*>(cnode)) {
     193            0 :       treenode* parent = cnode->GetParent();
     194            0 :       ObjectNode* NodeObject = dynamic_cast<ObjectNode*>(parent);
     195            0 :       RelationshipNode* RelationshipTreeNode = dynamic_cast<RelationshipNode*>(cnode);
     196              : 
     197            0 :       (new ObjectCreator(NodeObject->GetObject(), RelationshipTreeNode->relation_t()))->show();
     198              :     } else {
     199            0 :       (new ObjectCreator(classinfo))->show();
     200              :     }
     201            0 :   }
     202            0 : }
     203              : //------------------------------------------------------------------------------------------
     204              : 
     205              : //------------------------------------------------------------------------------------------
     206              : void
     207            0 : dbe::CustomTreeView::slot_delete_objects()
     208              : {
     209            0 :   if (this->model() != nullptr) {
     210            0 :     QModelIndexList qindices = this->selectedIndexes();
     211            0 :     std::vector<QModelIndex> indices;
     212              : 
     213            0 :     for (QModelIndex const& q : qindices) {
     214            0 :       if (q.isValid() and q.column() == 0) {
     215            0 :         indices.push_back(q);
     216              :       }
     217              :     }
     218              : 
     219            0 :     if (models::treeselection* casted_model = dynamic_cast<models::treeselection*>(this->model())) {
     220            0 :       casted_model->delete_objects(indices.begin(), indices.end());
     221            0 :     } else if (dbe::models::subtree_proxy* casted_model = dynamic_cast<dbe::models::subtree_proxy*>(this->model())) {
     222            0 :       casted_model->delete_objects(indices.begin(), indices.end());
     223              :     } else {
     224            0 :       WARN("Object Deleting",
     225              :            "Object deletion failed due to the internal model being in invalid state",
     226            0 :            "You are advised to restart the application before proceeding any further");
     227              :     }
     228            0 :   }
     229            0 : }
     230              : //------------------------------------------------------------------------------------------
     231              : 
     232              : //------------------------------------------------------------------------------------------
     233              : void
     234            0 : dbe::CustomTreeView::slot_edit_object()
     235              : {
     236            0 :   if (this->model() != nullptr) {
     237            0 :     QModelIndexList indices = this->selectedIndexes();
     238              : 
     239            0 :     for (QModelIndex const& q : indices) {
     240            0 :       edit_object(q);
     241              :     }
     242            0 :   }
     243            0 : }
     244              : //------------------------------------------------------------------------------------------
     245              : 
     246              : //------------------------------------------------------------------------------------------
     247              : void
     248            0 : dbe::CustomTreeView::edit_object(QModelIndex const& index)
     249              : {
     250            0 :   model_common_interface* filtermodel = dynamic_cast<model_common_interface*>(model());
     251              : 
     252            0 :   if (!index.isValid()) {
     253              :     return;
     254              :   }
     255              : 
     256            0 :   if (filtermodel) {
     257            0 :     try {
     258            0 :       tref obj = filtermodel->getobject(index);
     259            0 :       bool WidgetFound = false;
     260            0 :       QString ObjectEditorName = QString("%1@%2").arg(obj.UID().c_str()).arg(obj.class_name().c_str());
     261              : 
     262            0 :       for (QWidget* Editor : QApplication::allWidgets()) {
     263            0 :         ObjectEditor* Widget = dynamic_cast<ObjectEditor*>(Editor);
     264              : 
     265            0 :         if (Widget != nullptr) {
     266            0 :           if ((Widget->objectName()).compare(ObjectEditorName) == 0) {
     267            0 :             Widget->raise();
     268            0 :             Widget->setVisible(true);
     269              :             WidgetFound = true;
     270              :           }
     271              :         }
     272            0 :       }
     273              : 
     274            0 :       if (!WidgetFound) {
     275            0 :         (new ObjectEditor(obj))->show();
     276              :       }
     277            0 :     } catch (daq::dbe::cannot_handle_invalid_qmodelindex const& e) {
     278              :       // nothing to do , maybe the user just clicked the wrong place
     279            0 :     }
     280              :   }
     281              : }
     282              : //------------------------------------------------------------------------------------------
     283              : 
     284              : //------------------------------------------------------------------------------------------
     285              : void
     286            0 : dbe::CustomTreeView::slot_copy_object()
     287              : {
     288            0 :   model_common_interface* filtermodel = dynamic_cast<model_common_interface*>(model());
     289            0 :   QModelIndex i = currentIndex();
     290              : 
     291            0 :   if (i.isValid() and filtermodel) {
     292            0 :     try {
     293            0 :       (new ObjectCreator(filtermodel->getobject(i)))->show();
     294            0 :     } catch (daq::dbe::cannot_handle_invalid_qmodelindex const& e) {
     295              :       // TODO the index can be invalid in this case
     296            0 :     }
     297              :   }
     298            0 : }
     299              : //------------------------------------------------------------------------------------------
     300              : void
     301            0 : dbe::CustomTreeView::referencedbyOnlycomposite()
     302              : {
     303            0 :   referencedBy(true);
     304            0 : }
     305              : 
     306              : void
     307            0 : dbe::CustomTreeView::referencedByAll()
     308              : {
     309            0 :   referencedBy(false);
     310            0 : }
     311              : //------------------------------------------------------------------------------------------
     312              : void
     313            0 : dbe::CustomTreeView::closeEvent(QCloseEvent* event)
     314              : {
     315              :   // Reset the model when the widget is closed
     316              :   // If not done, reference to removed objects may create issues
     317            0 :   models::treeselection* filtermodel = dynamic_cast<models::treeselection*>(model());
     318              : 
     319            0 :   setModel(nullptr);
     320              : 
     321            0 :   if (filtermodel != nullptr) {
     322            0 :     filtermodel->ResetQueryObjects();
     323            0 :     filtermodel->deleteLater();
     324              :   }
     325              : 
     326            0 :   event->accept();
     327            0 : }
     328              : 
     329              : //------------------------------------------------------------------------------------------
     330              : void
     331            0 : dbe::CustomTreeView::referencedBy(bool All)
     332              : {
     333            0 :   model_common_interface* filtermodel = dynamic_cast<model_common_interface*>(model());
     334            0 :   QModelIndex Index = currentIndex();
     335              : 
     336            0 :   if (!Index.isValid()) {
     337            0 :     return;
     338              :   }
     339              : 
     340            0 :   if (filtermodel) {
     341              : 
     342            0 :     try {
     343            0 :       tref obj = filtermodel->getobject(Index);
     344            0 :       std::vector<tref> objects;
     345              : 
     346            0 :       if (not obj.is_null()) {
     347            0 :         objects = obj.referenced_by("*", All);
     348              :       }
     349              : 
     350            0 :       if (objects.size() > 0) {
     351            0 :         dbe::models::tree* Source = dynamic_cast<dbe::models::tree*>(filtermodel->ReturnSourceModel());
     352            0 :         models::treeselection* Selection = new models::treeselection();
     353            0 :         Selection->SetFilterType(models::treeselection::ObjectFilterType);
     354            0 :         Selection->SetQueryObjects(objects);
     355            0 :         Selection->setFilterRegExp("Dummy");
     356            0 :         Selection->setSourceModel(Source);
     357              : 
     358            0 :         CustomTreeView* tView = new CustomTreeView(0);
     359            0 :         tView->setModel(Selection);
     360            0 :         tView->setWindowTitle(QString("Objects referencing '%1'").arg(obj.UID().c_str()));
     361            0 :         tView->setSortingEnabled(true);
     362            0 :         tView->setAlternatingRowColors(true);
     363            0 :         tView->resizeColumnToContents(0);
     364            0 :         tView->resizeColumnToContents(1);
     365            0 :         tView->setAttribute(Qt::WA_DeleteOnClose);
     366              : 
     367            0 :         connect(tView, SIGNAL(doubleClicked(QModelIndex)), tView, SLOT(slot_edit_object()));
     368              : 
     369            0 :         tView->show();
     370              :       } else {
     371            0 :         if (All) {
     372            0 :           WARN("No references of only composite objects have been found for object",
     373              :                " ",
     374              :                "with UID:",
     375              :                obj.UID(),
     376              :                "of class",
     377            0 :                obj.class_name());
     378              :         } else {
     379            0 :           WARN("No references of objects have been found for object",
     380              :                " ",
     381              :                "with UID:",
     382              :                obj.UID(),
     383              :                "of class",
     384            0 :                obj.class_name());
     385              :         }
     386              :       }
     387            0 :     } catch (daq::dbe::cannot_handle_invalid_qmodelindex const& e) {
     388            0 :     }
     389              :   }
     390              : }
     391              : //------------------------------------------------------------------------------------------
     392              : 
     393              : //------------------------------------------------------------------------------------------
     394              : void
     395            0 : dbe::CustomTreeView::referencedBy(bool All, tref obj)
     396              : {
     397            0 :   model_common_interface* filtermodel = dynamic_cast<model_common_interface*>(model());
     398              : 
     399            0 :   if (filtermodel) {
     400            0 :     std::vector<tref> objects;
     401              : 
     402            0 :     if (!obj.is_null()) {
     403            0 :       objects = obj.referenced_by("*", All);
     404              :     }
     405              : 
     406            0 :     if (objects.size() > 0) {
     407            0 :       dbe::models::tree* Source = dynamic_cast<dbe::models::tree*>(filtermodel->ReturnSourceModel());
     408            0 :       models::treeselection* Selection = new models::treeselection();
     409            0 :       Selection->SetFilterType(models::treeselection::ObjectFilterType);
     410            0 :       Selection->SetQueryObjects(objects);
     411            0 :       Selection->setFilterRegExp("Dummy");
     412            0 :       Selection->setSourceModel(Source);
     413              : 
     414            0 :       CustomTreeView* tView = new CustomTreeView(0);
     415            0 :       tView->setModel(Selection);
     416            0 :       tView->setSortingEnabled(true);
     417            0 :       tView->setAlternatingRowColors(true);
     418            0 :       tView->resizeColumnToContents(0);
     419            0 :       tView->hideColumn(1);
     420              :       // tView->resizeColumnToContents(1);
     421            0 :       tView->setWindowTitle(QString("Objects referencing '%1'").arg(obj.UID().c_str()));
     422            0 :       tView->setAttribute(Qt::WA_DeleteOnClose);
     423              : 
     424            0 :       connect(tView, SIGNAL(doubleClicked(QModelIndex)), tView, SLOT(slot_edit_object()));
     425              : 
     426            0 :       tView->show();
     427              :     } else {
     428            0 :       if (All) {
     429            0 :         WARN("No references for object", "Only Composite Objects - Not found", "with UID:", obj.UID());
     430              :       } else {
     431            0 :         WARN("No references for object", "All Objects - Not found", "with UID:", obj.UID());
     432              :       }
     433              :     }
     434            0 :   }
     435            0 : }
     436              : //------------------------------------------------------------------------------------------
        

Generated by: LCOV version 2.0-1