LCOV - code coverage report
Current view: top level - dbe/src/internal - MainWindow.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 894 0
Test Date: 2026-07-12 15:23:06 Functions: 0.0 % 74 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              : #include "dbe/MainWindow.hpp"
       7              : #include "dbe/ObjectEditor.hpp"
       8              : #include "dbe/ObjectCreator.hpp"
       9              : #include "dbe/BatchChangeWidget.hpp"
      10              : #include "dbe/BuildingBlockEditors.hpp"
      11              : #include "dbe/CommitDialog.hpp"
      12              : #include "dbe/StyleUtility.hpp"
      13              : #include "dbe/CreateDatabaseWidget.hpp"
      14              : #include "dbe/Command.hpp"
      15              : #include "dbe/FileInfo.hpp"
      16              : #include "dbe/messenger.hpp"
      17              : #include "dbe/messenger_proxy.hpp"
      18              : #include "dbe/config_api.hpp"
      19              : #include "dbe/config_api_version.hpp"
      20              : #include "dbe/subtreeproxy.hpp"
      21              : #include "dbe/treenode.hpp"
      22              : #include "dbe/version.hpp"
      23              : #include "dbe/MyApplication.hpp"
      24              : 
      25              : #include "logging/Logging.hpp"
      26              : 
      27              : #include <QFileDialog>
      28              : #include <QMessageBox>
      29              : #include <QProgressDialog>
      30              : #include <QTime>
      31              : #include <QUndoStack>
      32              : #include <QSettings>
      33              : #include <QCloseEvent>
      34              : #include <QWhatsThis>
      35              : #include <QDesktopServices>
      36              : #include <QUrl>
      37              : #include <QApplication>
      38              : #include <QItemDelegate>
      39              : 
      40              : #include <future>
      41              : #include <thread>
      42              : 
      43              : #include <boost/scope_exit.hpp>
      44              : 
      45              : 
      46              : namespace {
      47              :     // This allows to select data in the cells but to not modify them
      48              :     class DummyEditorDelegate : public QItemDelegate {
      49              :         public:
      50            0 :             void setModelData(QWidget * /* editor */, QAbstractItemModel * /* model */, const QModelIndex & /* index */) const override {}
      51              :     };
      52              : }
      53              : 
      54            0 : dbe::MainWindow::MainWindow ( QMap<QString, QString> const & cmdargs, QWidget * parent )
      55              :   : QMainWindow ( parent ),
      56            0 :     m_batch_change_in_progress ( false ),
      57            0 :     this_files ( nullptr ),
      58            0 :     this_filesort ( new QSortFilterProxyModel ( this ) ),
      59            0 :     this_classes ( nullptr ),
      60            0 :     this_treefilter ( nullptr ),
      61            0 :     isArchivedConf ( false )
      62              : {
      63              :   //qRegisterMetaType<RDBMap>("RDBMap");
      64              : 
      65              :   /// Setting up ui
      66            0 :   setupUi ( this );
      67              : 
      68              :   /// Initial Settings
      69            0 :   init();
      70            0 :   init_tabs();
      71              :   //init_rdb_menu();
      72              : 
      73              :   /// Setting up application controller
      74            0 :   attach();
      75              : 
      76              :   /// Reading Applications Settings/CommandLine
      77            0 :   load_settings ( false );
      78            0 :   argsparse ( cmdargs );
      79              : 
      80            0 :   if (isArchivedConf == true) {
      81            0 :       OpenDB->setEnabled(false);
      82              :       //OpenOracleDB->setEnabled(false);
      83              :       //ConnectToRdb->setEnabled(false);
      84            0 :       CreateDatabase->setEnabled(false);
      85            0 :       Commit->setEnabled(false);
      86              : 
      87            0 :       QMessageBox::information(this,
      88              :                                "DBE",
      89            0 :                                QString("The configuration is opened in archival/detached mode.")
      90            0 :                                       .append("\nYou can browse or modify objects, but changes cannot be saved or commited."));
      91              :   }
      92              : 
      93            0 :   UndoView->show();
      94              : 
      95            0 : }
      96              : 
      97            0 : void dbe::MainWindow::init_tabs()
      98              : {
      99            0 :   tableholder->addTab ( new TableTab ( tableholder ), "Table View" );
     100            0 :   tableholder->removeTab ( 0 );
     101              : 
     102            0 :   QPushButton * addtab_button = new QPushButton ( "+" );
     103            0 :   tableholder->setCornerWidget ( addtab_button, Qt::TopLeftCorner );
     104            0 :   connect ( addtab_button, SIGNAL ( clicked() ), this, SLOT ( slot_add_tab() ) );
     105              : 
     106            0 :   tableholder->setTabsClosable ( true );
     107            0 :   connect ( tableholder, SIGNAL ( tabCloseRequested ( int ) ), this,
     108              :             SLOT ( slot_remove_tab ( int ) ) );
     109            0 : }
     110              : 
     111            0 : void dbe::MainWindow::slot_add_tab()
     112              : {
     113            0 :   tableholder->addTab ( new TableTab ( tableholder ), "Table View" );
     114            0 :   tableholder->setCurrentIndex ( tableholder->count()-1 );
     115            0 :   tableholder->show();
     116            0 : }
     117              : 
     118            0 : void dbe::MainWindow::slot_remove_tab ( int i )
     119              : {
     120            0 :   if ( i == -1 || ( ( tableholder->count() == 1 ) && i == 0 ) )
     121              :   {
     122            0 :     return;
     123              :   }
     124              : 
     125            0 :   QWidget * Widget = tableholder->widget ( i );
     126              : 
     127            0 :   tableholder->removeTab ( i );
     128              : 
     129            0 :   delete Widget;
     130              : 
     131            0 :   Widget = nullptr;
     132              : }
     133              : 
     134              : 
     135            0 : void dbe::MainWindow::init()
     136              : {
     137              :   /// Window Settings
     138            0 :   setWindowTitle ( "DUNE DAQ Configuration Database Editor (DBE)" );
     139              :   /// Table Settings
     140            0 :   UndoView->setStack ( confaccessor::get_commands().get() );
     141            0 :   SearchLineTable->hide();
     142            0 :   SearchLineTable->setClearButtonEnabled(true);
     143            0 :   SearchTreeLine->setClearButtonEnabled(true);
     144            0 :   CaseSensitiveCheckBoxTable->hide();
     145            0 :   tableholder->removeTab ( 1 );
     146              : 
     147              :   /// Menus Settings
     148            0 :   HelpMenu->setEnabled ( false );  // Until help is updated to be useful!!!
     149              : 
     150              :   /// Commands Settings
     151            0 :   Commit->setEnabled ( false );
     152            0 :   UndoAction->setEnabled ( true );
     153            0 :   RedoAction->setEnabled ( true );
     154              : 
     155              :   /// Search Box Settings
     156            0 :   SearchBox->setFocusPolicy ( Qt::ClickFocus );
     157              : 
     158              :   /// What is this
     159            0 :   TreeView->setWhatsThis ( "This view shows the classes and objects of the database" );
     160            0 :   FileView->setWhatsThis ( "This view shows the file structure of the database" );
     161            0 :   UndoView->setWhatsThis ( "This view shows the commands in the Undo Command stack" );
     162              : 
     163            0 :   CommittedTable->setHorizontalHeaderLabels(QStringList() << "File" << "Comment" << "Date");
     164            0 :   CommittedTable->setAlternatingRowColors(true);
     165            0 :   CommittedTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     166            0 :   CommittedTable->horizontalHeader()->setDefaultSectionSize(250);
     167            0 :   CommittedTable->setWordWrap(true);
     168            0 :   CommittedTable->setTextElideMode(Qt::ElideRight);
     169            0 :   CommittedTable->setItemDelegate(new DummyEditorDelegate());
     170              : 
     171              :   // Make Files the current tab 
     172            0 :   InfoWidget->setCurrentIndex (0);
     173              : 
     174              : 
     175              :   /// Color Management
     176            0 :   StyleUtility::InitColorManagement();
     177            0 : }
     178              : 
     179            0 : void dbe::MainWindow::attach()
     180              : {
     181            0 :   connect ( OpenDB, SIGNAL ( triggered() ), this, SLOT ( slot_open_database_from_file() ) );
     182            0 :   connect ( Commit, SIGNAL ( triggered() ), this, SLOT ( slot_commit_database() ) );
     183            0 :   connect ( Exit, SIGNAL ( triggered() ), this, SLOT ( close() ) );
     184            0 :   connect ( UndoAction, SIGNAL ( triggered() ), UndoView->stack(), SLOT ( undo() ) );
     185            0 :   connect ( RedoAction, SIGNAL ( triggered() ), UndoView->stack(), SLOT ( redo() ) );
     186            0 :   connect ( UndoAll, SIGNAL ( triggered() ), this, SLOT ( slot_undo_allchanges() ) );
     187            0 :   connect ( BatchChange, SIGNAL ( triggered() ), this, SLOT ( slot_launch_batchchange() ) );
     188            0 :   connect ( BatchChangeTable, SIGNAL ( triggered() ), this,
     189              :             SLOT ( slot_launch_batchchange_on_table() ) );
     190              : 
     191            0 :   connect ( DisplayClassView, SIGNAL ( triggered ( bool ) ), TreeDockWidget,
     192              :             SLOT ( setVisible ( bool ) ) );
     193            0 :   connect ( DisplayTableView, SIGNAL ( triggered ( bool ) ), TableGroupBox,
     194              :             SLOT ( setVisible ( bool ) ) );
     195            0 :   connect ( DisplayMessages, SIGNAL ( triggered ( bool ) ), InfoDockWidget,
     196              :             SLOT ( setVisible ( bool ) ) );
     197            0 :   connect ( DisplayToolbar, SIGNAL ( triggered ( bool ) ), MainToolBar,
     198              :             SLOT ( setVisible ( bool ) ) );
     199              : 
     200            0 :   connect ( TreeDockWidget, SIGNAL ( visibilityChanged ( bool ) ), DisplayTableView,
     201              :             SLOT ( setChecked ( bool ) ) );
     202            0 :   connect ( InfoDockWidget , SIGNAL ( visibilityChanged ( bool ) ), DisplayMessages,
     203              :             SLOT ( setChecked ( bool ) ) );
     204            0 :   connect ( MainToolBar , SIGNAL ( visibilityChanged ( bool ) ), DisplayToolbar,
     205              :             SLOT ( setChecked ( bool ) ) );
     206              : 
     207              : 
     208            0 :   connect ( LoadDefaultSettings, SIGNAL ( triggered() ), this,
     209              :             SLOT ( LoadDefaultSetting() ) );
     210            0 :   connect ( CreateDatabase, SIGNAL ( triggered() ), this, SLOT ( slot_create_newdb() ) );
     211              :   //connect ( OpenOracleDB, SIGNAL ( triggered() ), this, SLOT ( slot_oracle_prepare() ) );
     212              : 
     213            0 :   connect ( WhatThisAction, SIGNAL ( triggered() ), this, SLOT ( slot_whatisthis() ) );
     214            0 :   connect ( UserGuide, SIGNAL ( triggered() ), this, SLOT ( slot_show_userguide() ) );
     215            0 :   connect ( UserChanges, SIGNAL ( triggered() ), this, SLOT ( slot_show_userchanges() ) );
     216              : 
     217            0 :   connect ( TreeView, SIGNAL ( activated ( QModelIndex ) ), this,
     218              :             SLOT ( slot_edit_object_from_class_view ( QModelIndex ) ) );
     219              : 
     220            0 :   connect( &confaccessor::ref(), SIGNAL(db_committed(const std::list<std::string>&, const std::string&)), this,
     221              :            SLOT(slot_update_committed_files(const std::list<std::string>&, const std::string&)));
     222              : 
     223            0 :   connect ( confaccessor::gethandler().get(), SIGNAL ( FetchMoreData ( const treenode * ) ),
     224              :             this,
     225              :             SLOT ( slot_fetch_data ( const treenode * ) ) );
     226              : 
     227            0 :   connect( &confaccessor::ref(), SIGNAL(object_created(QString, dref)), this,
     228              :            SLOT(slot_toggle_commit_button()));
     229            0 :   connect( &confaccessor::ref(), SIGNAL(object_renamed(QString, dref)), this,
     230              :            SLOT(slot_toggle_commit_button()));
     231            0 :   connect( &confaccessor::ref(), SIGNAL(object_changed(QString, dref)), this,
     232              :            SLOT(slot_toggle_commit_button()));
     233            0 :   connect( &confaccessor::ref(), SIGNAL(object_deleted(QString, dref)), this,
     234              :            SLOT(slot_toggle_commit_button()));
     235            0 :   connect( &confaccessor::ref(), SIGNAL(db_committed(const std::list<std::string>&, const std::string&)), this,
     236              :            SLOT(slot_toggle_commit_button()));
     237            0 :   connect( &confaccessor::ref(), SIGNAL(IncludeFileDone()), this,
     238              :            SLOT(slot_toggle_commit_button()));
     239            0 :   connect( &confaccessor::ref(), SIGNAL(RemoveFileDone()), this,
     240              :            SLOT(slot_toggle_commit_button()));
     241            0 :   connect( &confaccessor::ref(), SIGNAL(ExternalChangesDetected()), this,
     242              :            SLOT(slot_toggle_commit_button()));
     243            0 :   connect( &confaccessor::ref(), SIGNAL(ExternalChangesAccepted()), this,
     244              :            SLOT(slot_toggle_commit_button()));
     245            0 :   connect( this, SIGNAL(signal_batch_change_stopped(const QList<QPair<QString, QString>>&)), this,
     246              :            SLOT(slot_toggle_commit_button()));
     247              : 
     248            0 :   connect ( &confaccessor::ref(), SIGNAL ( IncludeFileDone() ), this,
     249              :             SLOT ( slot_model_rebuild() ) );
     250            0 :   connect ( &confaccessor::ref(), SIGNAL ( RemoveFileDone() ), this,
     251              :             SLOT ( slot_model_rebuild() ) );
     252            0 :   connect ( &confaccessor::ref(), SIGNAL ( ExternalChangesAccepted() ), this,
     253              :             SLOT ( slot_process_externalchanges() ) );
     254              : 
     255              : 
     256            0 :   connect ( SearchBox, SIGNAL ( currentIndexChanged(int) ), this,
     257              :             SLOT ( slot_filter_query() ) );
     258            0 :   connect ( SearchTreeLine, SIGNAL ( textChanged ( const QString & ) ), this,
     259              :             SLOT ( slot_filter_textchange ( const QString & ) ) );
     260            0 :   connect ( SearchTreeLine, SIGNAL ( textEdited ( const QString & ) ), this,
     261              :             SLOT ( slot_filter_query() ) );
     262            0 :   connect ( SearchTreeLine, SIGNAL ( returnPressed() ), this, SLOT ( slot_filter_query() ) );
     263            0 :   connect ( SearchLineTable, SIGNAL ( textChanged ( const QString & ) ), this,
     264              :             SLOT ( slot_filter_table_textchange ( const QString & ) ) );
     265            0 :   connect ( CaseSensitiveCheckBoxTree, SIGNAL ( clicked ( bool ) ), this,
     266              :             SLOT ( slot_toggle_casesensitive_for_treeview ( bool ) ) );
     267              :   //connect ( ConnectToRdb, SIGNAL ( triggered ( QAction * ) ), this,
     268              :   //        SLOT ( slot_rdb_selected ( QAction * ) ) );
     269              : 
     270            0 :   connect ( information_about_dbe, SIGNAL ( triggered() ), this,
     271              :             SLOT ( slot_show_information_about_dbe() ) );
     272              : 
     273              :   // Connect to signals from the messenger system
     274              : 
     275            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     276              :             SIGNAL ( signal_debug ( QString const, QString const ) ), this,
     277              :             SLOT ( slot_debuginfo_message ( QString , QString ) ), Qt::QueuedConnection );
     278              : 
     279            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     280              :             SIGNAL ( signal_info ( QString const, QString const ) ), this,
     281              :             SLOT ( slot_information_message ( QString , QString ) ), Qt::QueuedConnection );
     282              : 
     283            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     284              :             SIGNAL ( signal_note ( QString const, QString const ) ), this,
     285              :             SLOT ( slot_notice_message ( QString , QString ) ), Qt::QueuedConnection );
     286              : 
     287            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     288              :             SIGNAL ( signal_warn ( QString const, QString const ) ), this,
     289              :             SLOT ( slot_warning_message ( QString , QString ) ), Qt::QueuedConnection );
     290              : 
     291            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     292              :             SIGNAL ( signal_error ( QString const, QString const ) ), this,
     293              :             SLOT ( slot_error_message ( QString, QString ) ), Qt::QueuedConnection );
     294              : 
     295            0 :   connect ( &dbe::interface::messenger_proxy::ref(),
     296              :             SIGNAL ( signal_fail ( QString const, QString const ) ), this,
     297              :             SLOT ( slot_failure_message ( QString , QString ) ), Qt::QueuedConnection );
     298              : 
     299              :   // connect ( this, SIGNAL ( signal_rdb_found(const QString&, const RDBMap& ) ),
     300              :   //           this, SLOT ( slot_rdb_found(const QString&, const RDBMap&) ), Qt::AutoConnection );
     301            0 : }
     302              : 
     303            0 : void dbe::MainWindow::build_class_tree_model()
     304              : {
     305            0 :   QStringList Headers
     306            0 :   { "Class Name", "# Objects" };
     307              : 
     308            0 :   if ( this_classes != nullptr )
     309              :   {
     310            0 :     delete this_classes;
     311            0 :     delete this_treefilter;
     312              :   }
     313              :   /// Creating new Main Model
     314            0 :   this_classes = new dbe::models::tree ( Headers );
     315              :   /// Resetting attached models
     316            0 :   this_treefilter = new models::treeselection();
     317            0 :   this_treefilter->setFilterRegExp ( "" );
     318              : 
     319            0 :   connect ( this_classes, SIGNAL ( ObjectFile ( QString ) ),
     320              :             this, SLOT ( slot_loaded_db_file ( QString ) ) );
     321              : 
     322            0 :   this_treefilter->setDynamicSortFilter ( true );
     323            0 :   this_treefilter->setSourceModel ( this_classes );
     324            0 :   slot_toggle_casesensitive_for_treeview ( true );
     325            0 :   TreeView->setModel ( this_treefilter );
     326            0 :   TreeView->setSortingEnabled ( true );
     327            0 :   TreeView->resizeColumnToContents ( 0 );
     328            0 :   TreeView->resizeColumnToContents ( 1 );
     329              : 
     330            0 :   connect ( HideCheckBox, SIGNAL ( toggled ( bool ) ), this_treefilter,
     331              :             SLOT ( ToggleEmptyClasses ( bool ) ) );
     332              : 
     333            0 :   connect ( ShowDerivedObjects, SIGNAL ( toggled ( bool ) ), this_classes,
     334              :             SLOT ( ToggleAbstractClassesSelectable ( bool ) ) );
     335              : 
     336            0 :   update_total_objects();
     337            0 : }
     338              : 
     339            0 : void dbe::MainWindow::build_table_model()
     340              : {
     341              :   /// Displaying table widgets
     342            0 :   SearchLineTable->clear();
     343            0 :   SearchLineTable->show();
     344            0 :   SearchLineTable->setProperty ( "placeholderText", QVariant ( QString ( "Table Filter" ) ) );
     345            0 :   CaseSensitiveCheckBoxTable->show();
     346            0 : }
     347              : 
     348            0 : void dbe::MainWindow::edit_object_at ( const QModelIndex & Index )
     349              : {
     350            0 :   treenode * tree_node = this_classes->getnode ( Index );
     351              : 
     352              :   /*
     353              :    * If an object node is linked to this index then launch the object editor
     354              :    * else build a table for the class , showing all objects
     355              :    */
     356              : 
     357            0 :   if ( dynamic_cast<ObjectNode *> ( tree_node ) )
     358              :   {
     359            0 :     ObjectNode * NodeObject = dynamic_cast<ObjectNode *> ( tree_node );
     360            0 :     tref ObjectToBeEdited = NodeObject->GetObject();
     361            0 :     slot_launch_object_editor ( ObjectToBeEdited );
     362            0 :   }
     363              :   else
     364              :   {
     365              :     // Class node
     366            0 :     QString const cname = tree_node->GetData ( 0 ).toString();
     367            0 :     dunedaq::conffwk::class_t cinfo = dbe::config::api::info::onclass::definition (
     368            0 :                                    cname.toStdString(),
     369            0 :                                    false );
     370              : 
     371            0 :     if ( not cinfo.p_abstract or ShowDerivedObjects->isChecked() )
     372              :     {
     373            0 :       if ( TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->currentWidget() ) )
     374              :       {
     375            0 :         CurrentTab->CreateModels();
     376            0 :         dbe::models::table * CurrentTabModel = CurrentTab->GetTableModel();
     377            0 :         CustomDelegate * CurrentDelegate = CurrentTab->GetTableDelegate();
     378            0 :         CustomTableView * CurrentView = CurrentTab->GetTableView();
     379              : 
     380            0 :         connect ( CurrentView, SIGNAL ( OpenEditor ( tref ) ), this,
     381              :                   SLOT ( slot_launch_object_editor ( tref ) ), Qt::UniqueConnection );
     382            0 :         connect ( CurrentDelegate, SIGNAL ( CreateObjectEditorSignal ( tref ) ), this,
     383              :                   SLOT ( slot_launch_object_editor ( tref ) ), Qt::UniqueConnection );
     384              : 
     385            0 :         if ( dynamic_cast<ClassNode *> ( tree_node ) )
     386              :         {
     387            0 :           BOOST_SCOPE_EXIT(CurrentTabModel)
     388              :           {
     389            0 :               emit CurrentTabModel->layoutChanged();
     390            0 :           }
     391            0 :           BOOST_SCOPE_EXIT_END
     392              : 
     393            0 :           emit CurrentTabModel->layoutAboutToBeChanged();
     394              : 
     395            0 :           CurrentTabModel->BuildTableFromClass ( cname, ShowDerivedObjects->isChecked() );
     396            0 :           build_table_model();
     397            0 :           tableholder->setTabText ( tableholder->currentIndex(), cname );
     398            0 :           CurrentTab->ResetTableView();
     399            0 :         }
     400              : 
     401            0 :         CurrentTab->ResizeHeaders();
     402              :       }
     403              :     }
     404            0 :   }
     405            0 : }
     406              : 
     407              : 
     408            0 : void dbe::MainWindow::build_file_model()
     409              : {
     410              :   /// Changed -> Now accepting rdbconfig this means || !ConfigWrapper::GetInstance().GetDatabaseImplementation().contains("rdbconfig") was removed
     411              : 
     412            0 :   if ( !confaccessor::db_implementation_name().contains ( "roksconflibs" ) )
     413              :   {
     414            0 :     if ( this_files != nullptr ) {
     415            0 :       delete this_files;
     416              :     }
     417            0 :     this_files = new FileModel();
     418              : 
     419            0 :     this_filesort.setSourceModel ( this_files );
     420            0 :     FileView->setModel ( &this_filesort );
     421              : 
     422            0 :     FileView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
     423            0 :     FileView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
     424            0 :     FileView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
     425            0 :     FileView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
     426              : 
     427            0 :     emit signal_new_file_model();
     428              :   }
     429            0 : }
     430              : 
     431              : 
     432            0 : void dbe::MainWindow::slot_fetch_data ( const treenode * ClassNode )
     433              : {
     434            0 :   if ( this_classes->canFetchMore ( this_classes->index ( ClassNode->GetRow(), 0,
     435            0 :                                                           QModelIndex() ) ) )
     436              :   {
     437            0 :     this_classes->fetchMore ( this_classes->index ( ClassNode->GetRow(), 0, QModelIndex() ) );
     438              :   }
     439            0 : }
     440              : 
     441            0 : bool dbe::MainWindow::slot_commit_database ( bool Exit )
     442              : {
     443            0 :   CommitDialog * SaveDialog = new CommitDialog();
     444            0 :   int DialogResult = SaveDialog->exec();
     445              : 
     446            0 :   if ( DialogResult )
     447              :   {
     448            0 :     FileInfo::parse_all_objects();
     449            0 :     for (auto file : dbe::confaccessor::uncommitted_files()) {
     450            0 :       auto message = FileInfo::check_file_includes(QString::fromStdString(file));
     451            0 :       if (!message.isEmpty()) {
     452            0 :         QMessageBox::warning ( 0, "Save database", message );
     453            0 :         FileInfo::show_file_info(QString::fromStdString(file));
     454            0 :         return false;
     455              :       }
     456            0 :     }
     457              : 
     458            0 :     QString CommitMessage = SaveDialog->GetCommitMessage();
     459              : 
     460            0 :     try
     461              :     {
     462            0 :       std::list<std::string> const & modified = confaccessor::save ( CommitMessage );
     463            0 :       confaccessor::clear_commands();
     464              : 
     465            0 :       build_file_model();
     466              : 
     467            0 :       if ( not modified.empty() )
     468              :       {
     469            0 :         std::string msg;
     470              : 
     471            0 :         for ( std::string const & f : modified )
     472              :         {
     473            0 :           msg += "\n" + f;
     474              :         }
     475              : 
     476            0 :         INFO ( "List of modified files committed to the database ", "Program execution success",
     477            0 :                msg );
     478            0 :       }
     479              :       else
     480              :       {
     481            0 :         WARN ( "Changes where committed successfully but list of modified files could not be retrieved",
     482            0 :                "Unexpected program execution" );
     483              :       }
     484              : 
     485            0 :     }
     486            0 :     catch ( dunedaq::conffwk::Exception const & e )
     487              :     {
     488            0 :       WARN ( "The changes could not be committed", dbe::config::errors::parse ( e ).c_str() )
     489            0 :       ers::error ( e );
     490            0 :       return false;
     491            0 :     }
     492              :     // Gaahhh confaccessor catches dunedaq::conffwk::Exception and
     493              :     // rethrows it as daq::dbe::CouldNotCommitChanges!!
     494            0 :     catch (daq::dbe::CouldNotCommitChanges const& exc)
     495              :     {
     496            0 :       std::string reason{exc.what()};
     497            0 :       auto cause = exc.cause();
     498            0 :       while (cause != nullptr) {
     499            0 :         reason = cause->what();
     500            0 :         cause = cause->cause();
     501              :       }
     502            0 :       WARN ("The changes could not be committed",
     503              :             // dbe::config::errors::parse(exc).c_str(),
     504              :             reason,
     505              :             "\n\nTry fixing includes from File Info window")
     506            0 :       ers::error (exc);
     507            0 :       return false;
     508            0 :     }
     509            0 :   }
     510              :   else
     511              :   {
     512            0 :     if ( Exit )
     513              :     {
     514            0 :       slot_abort_changes();
     515              :     }
     516              :   }
     517              :   return true;
     518              : }
     519              : 
     520            0 : void dbe::MainWindow::slot_abort_changes()
     521              : {
     522            0 :   try
     523              :   {
     524            0 :     if ( confaccessor::is_database_loaded() )
     525              :     {
     526            0 :       confaccessor::abort();
     527            0 :       confaccessor::clear_commands();
     528              :     }
     529              :   }
     530            0 :   catch ( dunedaq::conffwk::Exception const & e )
     531              :   {
     532            0 :     ERROR ( "Database changes aborted", dbe::config::errors::parse ( e ).c_str() );
     533            0 :     ers::error ( e );
     534            0 :   }
     535            0 : }
     536              : 
     537            0 : void dbe::MainWindow::slot_abort_external_changes()
     538              : {
     539            0 :   try
     540              :   {
     541            0 :     if ( confaccessor::is_database_loaded() )
     542              :     {
     543            0 :       confaccessor::abort();
     544              :     }
     545              :   }
     546            0 :   catch ( dunedaq::conffwk::Exception const & e )
     547              :   {
     548            0 :     ERROR ( "External changes aborted", dbe::config::errors::parse ( e ).c_str() );
     549            0 :     ers::error ( e );
     550            0 :   }
     551            0 : }
     552              : 
     553            0 : void dbe::MainWindow::slot_launch_object_editor ( tref Object )
     554              : {
     555            0 :   bool WidgetFound = false;
     556            0 :   QString ObjectEditorName = QString ( "%1@%2" ).arg ( Object.UID().c_str() ).arg (
     557            0 :                                Object.class_name().c_str() );
     558              : 
     559            0 :   for ( QWidget * Editor : QApplication::allWidgets() )
     560              :   {
     561            0 :     ObjectEditor * Widget = dynamic_cast<ObjectEditor *> ( Editor );
     562              : 
     563            0 :     if ( Widget != nullptr )
     564              :     {
     565            0 :       if ( ( Widget->objectName() ).compare ( ObjectEditorName ) == 0 )
     566              :       {
     567            0 :         Widget->raise();
     568            0 :         Widget->setVisible ( true );
     569              :         WidgetFound = true;
     570              :       }
     571              :     }
     572            0 :   }
     573              : 
     574            0 :   if ( !WidgetFound )
     575              :   {
     576            0 :     ( new ObjectEditor ( Object ) )->show();
     577              :   }
     578            0 : }
     579              : 
     580            0 : void dbe::MainWindow::slot_launch_batchchange()
     581              : {
     582            0 :   if ( confaccessor::is_database_loaded() )
     583              :   {
     584            0 :     BatchChangeWidget * Batch = new BatchChangeWidget ( nullptr );
     585            0 :     Batch->setWindowModality ( Qt::WindowModal );
     586            0 :     Batch->show();
     587              :   }
     588              :   else
     589              :   {
     590            0 :     ERROR ( "Database must have been loaded", "No database loaded" );
     591              :   }
     592            0 : }
     593              : 
     594            0 : void dbe::MainWindow::slot_launch_batchchange_on_table()
     595              : {
     596            0 :   if ( !confaccessor::is_database_loaded() )
     597              :   {
     598            0 :     ERROR ( "Database must have been loaded", "No database loaded" );
     599            0 :     return;
     600              :   }
     601              : 
     602            0 :   dbe::models::table * CurrentTableModel = nullptr;
     603            0 :   TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->currentWidget() );
     604            0 :   if ( CurrentTab ) {
     605            0 :       CurrentTableModel = CurrentTab->GetTableModel();
     606              :   }
     607              : 
     608            0 :   std::vector<dref> TableObject;
     609              : 
     610            0 :   if ( !CurrentTab || !CurrentTableModel )
     611              :   {
     612            0 :     ERROR ( "Table cannot be processed", "Table is empty" );
     613            0 :     return;
     614              :   }
     615              : 
     616            0 :   if ( ( *CurrentTableModel->GetTableObjects() ).isEmpty() )
     617              :   {
     618            0 :     ERROR ( "Table cannot be processed", "Table is empty" );
     619            0 :     return;
     620              :   }
     621              : 
     622            0 :   QString Filter = SearchLineTable->text();
     623              : 
     624            0 :   for ( dref Object : *CurrentTableModel->GetTableObjects() )
     625              :   {
     626            0 :     if ( Filter.isEmpty() )
     627              :     {
     628            0 :       TableObject.push_back ( Object );
     629              :     }
     630              :     else
     631              :     {
     632            0 :       QString ObjectString = QString::fromStdString ( Object.UID() );
     633              : 
     634            0 :       if ( ObjectString.contains ( Filter, Qt::CaseInsensitive ) )
     635              :       {
     636            0 :         TableObject.push_back ( Object );
     637              :       }
     638            0 :     }
     639            0 :   }
     640              : 
     641            0 :   BatchChangeWidget * Batch = new BatchChangeWidget (
     642              :     true,
     643            0 :     CurrentTableModel->get_class_name(),
     644            0 :     TableObject, nullptr );
     645            0 :   Batch->setWindowModality ( Qt::WindowModal );
     646            0 :   Batch->show();
     647            0 : }
     648              : 
     649            0 : void dbe::MainWindow::LoadDefaultSetting()
     650              : {
     651            0 :   load_settings ( false );
     652            0 : }
     653              : 
     654            0 : QString dbe::MainWindow::find_db_repository_dir()
     655              : {
     656            0 :     if (confaccessor::dbfullname().isEmpty()) {
     657            0 :       return "";
     658              :     }
     659              : 
     660            0 :     const QStringList& incs =dbe::config::api::get::file::inclusions({confaccessor::dbfullname()});
     661            0 :     for(QString f : allFiles) {
     662            0 :         for(const QString& j : incs) {
     663            0 :             if(f.endsWith(j)) {
     664            0 :                 return f.remove(j);
     665              :             }
     666              :         }
     667            0 :     }
     668              : 
     669            0 :     return "";
     670            0 : }
     671              : 
     672            0 : void dbe::MainWindow::slot_create_newdb()
     673              : {
     674              : 
     675            0 :   CreateDatabaseWidget * CreateDatabaseW = new CreateDatabaseWidget(nullptr, false, find_db_repository_dir());
     676            0 :   CreateDatabaseW->show();
     677            0 :   connect ( CreateDatabaseW, SIGNAL ( CanLoadDatabase ( const QString & ) ), this,
     678              :             SLOT ( slot_load_db_from_create_widget ( const QString & ) ) );
     679            0 : }
     680              : 
     681            0 : void dbe::MainWindow::slot_load_db_from_create_widget ( const QString & DatabaseName )
     682              : {
     683            0 :   if ( !DatabaseName.isEmpty() )
     684              :   {
     685            0 :     QFileInfo DatabaseFile = QFileInfo ( DatabaseName );
     686              : 
     687            0 :     if ( DatabaseFile.exists() )
     688              :     {
     689            0 :       QString Path = QString ( DatabaseFile.absoluteFilePath() );
     690              : 
     691            0 :       if ( dbreload() )
     692              :       {
     693            0 :         confaccessor::setdbinfo ( Path );
     694              : 
     695            0 :         if ( dbload() )
     696              :         {
     697            0 :           setinternals();
     698            0 :           build_class_tree_model();
     699              :           // // build_partition_tree_model();
     700              :           // build_resource_tree_model();
     701            0 :           build_file_model();
     702              :         }
     703              :       }
     704            0 :     }
     705              :     else
     706              :     {
     707            0 :       WARN ( "File not found during database load", "File does not exist", "\n\n Filename:",
     708            0 :              DatabaseFile.fileName().toStdString() );
     709              :     }
     710            0 :   }
     711              :   else
     712              :   {
     713            0 :     ERROR ( "Database load error", "File was not selected" );
     714              :   }
     715            0 : }
     716              : 
     717            0 : bool dbe::MainWindow::dbreload()
     718              : {
     719            0 :   if ( confaccessor::is_database_loaded() )
     720              :   {
     721            0 :     QMessageBox MessageBox;
     722            0 :     MessageBox.setText (
     723              :       "Do you really wish to abandon the current database and load a new one ?" );
     724            0 :     MessageBox.setStandardButtons ( QMessageBox::Yes | QMessageBox::Cancel );
     725            0 :     MessageBox.setDefaultButton ( QMessageBox::Cancel );
     726            0 :     int UserOption = MessageBox.exec();
     727              : 
     728            0 :     switch ( UserOption )
     729              :     {
     730              : 
     731              :     case QMessageBox::Yes:
     732              :       return true;
     733              : 
     734            0 :     case QMessageBox::Cancel:
     735            0 :       return false;
     736              : 
     737            0 :     default:
     738            0 :       return false;
     739              :     }
     740            0 :   }
     741              :   else
     742              :   {
     743              :     return true;
     744              :   }
     745              : }
     746              : 
     747            0 : bool dbe::MainWindow::dbload()
     748              : {
     749              :     // For issues related to loading the configuration in a separate thread, see ATLASDBE-229
     750              : 
     751            0 :     const bool alreadyLoaded = confaccessor::is_database_loaded();
     752              : 
     753              :     // The QueuedConnection is mandatory to let the loop receive the signal even if
     754              :     // it is emitted before "exec" is called
     755            0 :     QEventLoop loop;
     756            0 :     connect(this, SIGNAL(signal_db_loaded()), &loop, SLOT(quit()), Qt::QueuedConnection);
     757              : 
     758              :     // Make life of the progress dialog longer
     759              :     // Show only the first time, when the configuration is not loaded
     760              :     // In other cases, just show a busy cursor
     761            0 :     std::unique_ptr<QProgressDialog> progress_bar;
     762            0 :     if(!alreadyLoaded) {
     763            0 :         progress_bar.reset(new QProgressDialog( "Loading Configuration...", QString(), 0, 0, this ));
     764            0 :         progress_bar->setWindowModality ( Qt::WindowModal );
     765            0 :         progress_bar->show();
     766              :     }
     767              : 
     768            0 :     BOOST_SCOPE_EXIT(void)
     769              :     {
     770            0 :         QApplication::restoreOverrideCursor();
     771            0 :     }
     772            0 :     BOOST_SCOPE_EXIT_END
     773              : 
     774            0 :     QApplication::setOverrideCursor ( QCursor ( Qt::WaitCursor ) );
     775              : 
     776              :     // Close widgets
     777            0 :     for ( QWidget * widget : QApplication::allWidgets() )
     778              :     {
     779            0 :         if ( dynamic_cast<ObjectEditor *> ( widget ) )
     780              :         {
     781            0 :             widget->close();
     782              :         }
     783            0 :         else if ( dynamic_cast<widgets::editors::base *> ( widget ) )
     784              :         {
     785            0 :             widget->close();
     786              :         }
     787            0 :     }
     788              : 
     789              :     // Asynchronous execution only the first time the configuration is loaded
     790            0 :     std::future<bool> waiter = std::async ( alreadyLoaded ? std::launch::deferred : std::launch::async, [this]
     791              :     {
     792            0 :       const bool result = confaccessor::load(!isArchivedConf);
     793            0 :       emit signal_db_loaded(); // "loop.exec()" will return now
     794            0 :       return result;
     795            0 :     } );
     796              : 
     797              : 
     798              :     // Do not call "exec" if the previous call is not asynchronous
     799            0 :     if(!alreadyLoaded) {
     800            0 :         loop.exec(QEventLoop::ExcludeUserInputEvents);
     801              :     }
     802              : 
     803              :     // If "deferred", the async call is executed now and here
     804            0 :     return waiter.get();
     805            0 : }
     806              : 
     807            0 : void dbe::MainWindow::setinternals()
     808              : {
     809            0 :   confaccessor::clear_commands();
     810            0 :   confaccessor::gethandler()->ResetData();
     811            0 :   confaccessor::set_total_objects ( 0 );
     812              : 
     813              :   /// Disconnecting models from views
     814              : 
     815            0 :   for ( int i = 0; i < tableholder->count(); i++ )
     816              :   {
     817            0 :     TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->widget ( i ) );
     818            0 :     if ( CurrentTab ) {
     819            0 :         CurrentTab->DisconnectView();
     820              :     }
     821              :   }
     822              : 
     823            0 :   FileView->setModel ( NULL );
     824            0 : }
     825              : 
     826            0 : void dbe::MainWindow::load_settings ( bool LoadSettings )
     827              : {
     828              :   /// Load Settings means default settings
     829            0 :   QSettings * Settings;
     830            0 :   QString userPath = QDir::homePath() + "/.conffwk/ATLAS_TDAQ_DBE";
     831            0 :   QString userFile = "DBE_User_Settings.conf";
     832              : 
     833            0 :   if ( !LoadSettings )
     834              :   {
     835            0 :     if ( QDir ( userPath ).exists ( userFile ) )
     836            0 :       Settings = new QSettings ( "ATLAS_TDAQ_DBE",
     837            0 :                                  "DBE_User_Settings" );
     838              :     else
     839            0 :       Settings = new QSettings ( ":theme/DBE_Default_User_Settings.conf",
     840            0 :                                  QSettings::NativeFormat );
     841              :   }
     842              :   else
     843              :   {
     844            0 :     Settings = new QSettings ( ":theme/DBE_Default_User_Settings.conf",
     845            0 :                                QSettings::NativeFormat );
     846              :   }
     847              : 
     848            0 :   Settings->beginGroup ( "MainWindow-layout" );
     849            0 :   resize ( Settings->value ( "size" ).toSize() );
     850            0 :   move ( Settings->value ( "pos" ).toPoint() );
     851            0 :   DisplayTableView->setChecked ( Settings->value ( "TableView" ).toBool() );
     852            0 :   DisplayClassView->setChecked ( Settings->value ( "ClassView" ).toBool() );
     853              : 
     854            0 :   DisplayMessages->setChecked ( Settings->value ( "Messages" ).toBool() );
     855            0 :   restoreGeometry ( Settings->value ( "geometry" ).toByteArray() );
     856            0 :   restoreState ( Settings->value ( "state" ).toByteArray() );
     857            0 :   Settings->endGroup();
     858              : 
     859            0 :   Settings->beginGroup ( "MainWindow-checkboxes" );
     860            0 :   CaseSensitiveCheckBoxTree->setChecked (
     861            0 :     Settings->value ( "tree-case-sensitive" ).toBool() );
     862            0 :   CaseSensitiveCheckBoxTable->setChecked (
     863            0 :     Settings->value ( "table-case-sensitive" ).toBool() );
     864            0 :   Settings->endGroup();
     865            0 : }
     866              : 
     867            0 : void dbe::MainWindow::WriteSettings()
     868              : {
     869            0 :   QSettings Settings ( "ATLAS_TDAQ_DBE", "DBE_User_Settings" );
     870            0 :   Settings.beginGroup ( "MainWindow-layout" );
     871            0 :   Settings.setValue ( "size", size() );
     872            0 :   Settings.setValue ( "pos", pos() );
     873            0 :   Settings.setValue ( "TableView", DisplayTableView->isChecked() );
     874            0 :   Settings.setValue ( "ClassView", DisplayClassView->isChecked() );
     875              : 
     876            0 :   Settings.setValue ( "Messages", DisplayMessages->isChecked() );
     877            0 :   Settings.setValue ( "geometry", saveGeometry() );
     878            0 :   Settings.setValue ( "state", saveState() );
     879            0 :   Settings.endGroup();
     880              : 
     881            0 :   Settings.beginGroup ( "MainWindow-checkboxes" );
     882            0 :   Settings.setValue ( "tree-case-sensitive", CaseSensitiveCheckBoxTree->isChecked() );
     883            0 :   Settings.setValue ( "table-case-sensitive", CaseSensitiveCheckBoxTable->isChecked() );
     884            0 :   Settings.endGroup();
     885            0 : }
     886              : 
     887            0 : void dbe::MainWindow::argsparse ( QMap<QString, QString> const & opts )
     888              : {
     889            0 :   if ( !opts.isEmpty() )
     890              :   {
     891            0 :     dbinfo LoadConfig;
     892            0 :     QString FileToLoad;
     893              : 
     894            0 :     QString FileName = opts.value ( "f" );
     895            0 :     QString RdbFileName = opts.value ( "r" );
     896            0 :     QString RoksFileName = opts.value ( "o" );
     897            0 :     QString HashVersion = opts.value ( "v" );
     898              : 
     899            0 :     if ( !FileName.isEmpty() )
     900              :     {
     901            0 :       FileToLoad = FileName;
     902            0 :       LoadConfig = dbinfo::oks;
     903              : 
     904            0 :       if ( !HashVersion.isEmpty() )
     905              :       {
     906            0 :         ::setenv("TDAQ_DB_VERSION", QString("hash:").append(HashVersion).toStdString().c_str(), 1);
     907            0 :         ::setenv("OKS_GIT_PROTOCOL", "http", 1);
     908            0 :         isArchivedConf = true;
     909              :       }
     910              :     }
     911            0 :     else if ( !RdbFileName.isEmpty() )
     912              :     {
     913            0 :       FileToLoad = RdbFileName;
     914            0 :       LoadConfig = dbinfo::rdb;
     915              :     }
     916            0 :     else if ( !RoksFileName.isEmpty() )
     917              :     {
     918            0 :       FileToLoad = RoksFileName;
     919            0 :       LoadConfig = dbinfo::roks;
     920              :     }
     921              : 
     922            0 :     if ( not FileToLoad.isEmpty() )
     923              :     {
     924            0 :       dbopen ( FileToLoad, LoadConfig );
     925              :     }
     926            0 :   }
     927            0 : }
     928              : 
     929              : // /**
     930              : //  * Create Rdb menu based on the available Rdb information
     931              : //  */
     932              : // void dbe::MainWindow::init_rdb_menu()
     933              : // {
     934              : //   ConnectToRdb->clear();
     935              : 
     936              : //   std::list<IPCPartition> pl;
     937              : //   IPCPartition::getPartitions(pl);
     938              : //   TLOG_DEBUG(1) <<  "Found " << pl.size() << " partitions"  ;
     939              : 
     940              : //   pl.push_front(IPCPartition("initial"));
     941              : 
     942              : //   auto f = [pl, this] () {
     943              : //       for ( auto it = pl.begin(); it != pl.end(); ++it )
     944              : //       {
     945              : //           lookForRDBServers ( *it );
     946              : //       }
     947              : //   };
     948              : 
     949              : //   std::thread t(f);
     950              : //   t.detach();
     951              : // }
     952              : 
     953              : // void dbe::MainWindow::slot_rdb_found(const QString& p, const RDBMap& rdbs) {
     954              : //     QMenu * part_menu = new QMenu(p);
     955              : 
     956              : //     for(auto it = rdbs.begin(); it != rdbs.end(); ++it) {
     957              : //         QAction * newAct = new QAction ( it.key(), part_menu );
     958              : 
     959              : //         QFont actFont = newAct->font();
     960              : //         if(it.value() == true) {
     961              : //             newAct->setToolTip ( QString ( "This is a Read-Only instance of the DB" ) );
     962              : //             actFont.setItalic ( true );
     963              : //         } else {
     964              : //             newAct->setToolTip ( QString ( "This is a Read/Write instance of the DB" ) );
     965              : //             actFont.setBold ( true );
     966              : //         }
     967              : 
     968              : //         newAct->setFont ( actFont );
     969              : 
     970              : //         part_menu->addAction ( newAct );
     971              : //     }
     972              : 
     973              : //     ConnectToRdb->addMenu ( part_menu );
     974              : // }
     975              : 
     976              : // /**
     977              : //  * Add rdb servers for each partition
     978              : //  *
     979              : //  * @param p is the partition source for which to populate with server information
     980              : //  */
     981              : // void dbe::MainWindow::lookForRDBServers ( const IPCPartition & p )
     982              : // {
     983              : //   TLOG_DEBUG(2) <<  "dbe::MainWindow::addRDBServers()"  ;
     984              : 
     985              : //   if ( p.isValid() )
     986              : //   {
     987              : //     TLOG_DEBUG(2) <<  "Inserting partition = " << p.name()  ;
     988              : 
     989              : //     RDBMap rdbs;
     990              : 
     991              : //     try
     992              : //     {
     993              : //         {
     994              : //             std::map<std::string, rdb::cursor_var> objects;
     995              : //             p.getObjects<rdb::cursor, ::ipc::use_cache, ::ipc::unchecked_narrow> ( objects );
     996              : //             std::map<std::string, rdb::cursor_var>::iterator rdb_it = objects.begin();
     997              : 
     998              : //             while ( rdb_it != objects.end() )
     999              : //             {
    1000              : //                 TLOG_DEBUG(2) <<  "Found server : " << rdb_it->first  ;
    1001              : 
    1002              : //                 rdbs.insert(QString::fromStdString(rdb_it->first), true);
    1003              : 
    1004              : //                 ++rdb_it;
    1005              : //             }
    1006              : //         }
    1007              : 
    1008              : //         {
    1009              : //             std::map<std::string, rdb::writer_var> objects;
    1010              : //             p.getObjects<rdb::writer, ::ipc::use_cache, ::ipc::unchecked_narrow> ( objects );
    1011              : //             std::map<std::string, rdb::writer_var>::iterator rdb_it = objects.begin();
    1012              : 
    1013              : //             while ( rdb_it != objects.end() )
    1014              : //             {
    1015              : //                 TLOG_DEBUG(2) <<  "Found server : " << rdb_it->first  ;
    1016              : 
    1017              : //                 rdbs.insert(QString::fromStdString(rdb_it->first), false);
    1018              : 
    1019              : //                 ++rdb_it;
    1020              : //             }
    1021              : //         }
    1022              : //     }
    1023              : //     catch ( daq::ipc::InvalidPartition& e )
    1024              : //     {
    1025              : //       ers::error ( e );
    1026              : //     }
    1027              : 
    1028              : //     if(rdbs.isEmpty() == false) {
    1029              : //         emit signal_rdb_found (QString::fromStdString(p.name()), rdbs);
    1030              : //     }
    1031              : //   }
    1032              : // }
    1033              : 
    1034              : // void dbe::MainWindow::slot_rdb_selected ( QAction * action )
    1035              : // {
    1036              : //   QMenu * parentMenu = qobject_cast<QMenu *> ( action->parent() );
    1037              : 
    1038              : //   if ( parentMenu )
    1039              : //   {
    1040              : //     if ( dbreload() )
    1041              : //     {
    1042              : //       BOOST_SCOPE_EXIT(void)
    1043              : //       {
    1044              : //           QApplication::restoreOverrideCursor();
    1045              : //        }
    1046              : //       BOOST_SCOPE_EXIT_END
    1047              : 
    1048              : //       QApplication::setOverrideCursor(Qt::WaitCursor);
    1049              : 
    1050              : //       confaccessor::setdbinfo ( action->text() + "@" + parentMenu->title(), dbinfo::rdb );
    1051              : 
    1052              : //       if ( dbload() )
    1053              : //       {
    1054              : //         setinternals();
    1055              : //         build_class_tree_model();
    1056              : //         build_partition_tree_model();
    1057              : //         build_resource_tree_model();
    1058              : //         build_file_model();
    1059              : //       }
    1060              : //     }
    1061              : //   }
    1062              : // }
    1063              : 
    1064              : // void dbe::MainWindow::slot_oracle_prepare()
    1065              : // {
    1066              : //   if ( this_oraclewidget == nullptr )
    1067              : //   {
    1068              : //     this_oraclewidget = new OracleWidget();
    1069              : //     connect ( this_oraclewidget, SIGNAL ( OpenOracleConfig ( const QString & ) ), this,
    1070              : //               SLOT ( slot_load_oracle ( const QString & ) ) );
    1071              : //   }
    1072              : 
    1073              : //   this_oraclewidget->raise();
    1074              : //   this_oraclewidget->show();
    1075              : // }
    1076              : 
    1077              : // void dbe::MainWindow::slot_load_oracle ( const QString & OracleDatabase )
    1078              : // {
    1079              : //   if ( dbreload() )
    1080              : //   {
    1081              : //     confaccessor::setdblocation ( OracleDatabase );
    1082              : 
    1083              : //     if ( dbload() )
    1084              : //     {
    1085              : //       setinternals();
    1086              : //       build_class_tree_model();
    1087              : //       build_partition_tree_model();
    1088              : //       build_resource_tree_model();
    1089              : //       build_file_model();
    1090              : //     }
    1091              : //   }
    1092              : 
    1093              : //   if ( this_oraclewidget != nullptr )
    1094              : //   {
    1095              : //     this_oraclewidget->close();
    1096              : //   }
    1097              : // }
    1098              : 
    1099            0 : void dbe::MainWindow::slot_whatisthis()
    1100              : {
    1101            0 :   QWhatsThis::enterWhatsThisMode();
    1102            0 : }
    1103              : 
    1104            0 : void dbe::MainWindow::slot_show_information_about_dbe()
    1105              : {
    1106            0 :   static QString const title ( "About DBE" );
    1107            0 :   static QString const msg = QString().
    1108            0 :                              append ( "DBE is an editor to work with OKS and RDB backends that manages most of the hard work for you in editing the configuration database\n" ).
    1109            0 :                              append ( "\n\nMaintained :\t\tC&C Working group \n\t\t\t(atlas-tdaq-cc-wg@cern.ch)" ).
    1110            0 :                              append ( "\nProgram version:\t\t" ).append ( dbe_compiled_version ).
    1111            0 :                              append ( "\nLibraries version:\t" ).
    1112            0 :                              append ( "\n\t\t\tdbecore(" ).append ( dbe_lib_core_version ).
    1113            0 :                              append ( "),\n\t\t\tdbe_config_api(" ).append ( dbe_lib_config_api_version ).
    1114            0 :                              append ( "),\n\t\t\tdbe_structure(" ).append ( dbe_lib_structure_version ).
    1115            0 :                              append ( "),\n\t\t\tdbe_internal(" ).append ( dbe_lib_internal_version ).append ( ')' ).
    1116            0 :                              append ( "\nRepo commit hash:\t" ).append ( dbe_compiled_commit );
    1117              : 
    1118            0 :   QMessageBox::about ( this, title, msg );
    1119            0 : }
    1120              : 
    1121            0 : void dbe::MainWindow::slot_show_userguide()
    1122              : {
    1123            0 :   QDesktopServices::openUrl ( QUrl ( "https://atlasdaq.cern.ch/dbe/" ) );
    1124            0 : }
    1125              : 
    1126            0 : void dbe::MainWindow::slot_show_userchanges()
    1127              : {
    1128            0 :   InfoWidget->setCurrentIndex ( InfoWidget->indexOf ( CommitedTab ) );
    1129            0 : }
    1130              : 
    1131            0 : void dbe::MainWindow::slot_undo_allchanges()
    1132              : {
    1133            0 :   UndoView->stack()->setIndex ( 0 );
    1134            0 : }
    1135              : 
    1136            0 : void dbe::MainWindow::slot_toggle_casesensitive_for_treeview ( bool )
    1137              : {
    1138            0 :   if ( CaseSensitiveCheckBoxTree->isChecked() )
    1139            0 :     this_treefilter->setFilterCaseSensitivity (
    1140              :       Qt::CaseSensitive );
    1141              :   else
    1142              :   {
    1143            0 :     this_treefilter->setFilterCaseSensitivity ( Qt::CaseInsensitive );
    1144              :   }
    1145            0 :   update_total_objects();
    1146            0 : }
    1147              : 
    1148            0 : void dbe::MainWindow::slot_model_rebuild()
    1149              : {
    1150              :   /// Preparing data
    1151            0 :   confaccessor::gethandler()->ResetData();
    1152            0 :   confaccessor::set_total_objects ( 0 );
    1153              :   /// Disconnecting models from views
    1154              : 
    1155            0 :   for ( int i = 0; i < tableholder->count(); i++ )
    1156              :   {
    1157            0 :     TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->widget ( i ) );
    1158            0 :     if( CurrentTab ) {
    1159            0 :         CurrentTab->DisconnectView();
    1160              :     }
    1161              :   }
    1162              : 
    1163            0 :   FileView->setModel ( NULL );
    1164              : 
    1165            0 :   build_class_tree_model();
    1166            0 :   build_file_model();
    1167            0 : }
    1168              : 
    1169            0 : void dbe::MainWindow::slot_filter_textchange ( const QString & FilterText )
    1170              : {
    1171            0 :   if ( this_treefilter != nullptr and SearchBox->currentIndex() != 1 )
    1172              :   {
    1173            0 :     this_treefilter->SetFilterType ( models::treeselection::RegExpFilterType );
    1174              : 
    1175            0 :     if ( SearchBox->currentIndex() == 2 )
    1176              :     {
    1177            0 :       this_treefilter->SetFilterRestrictionLevel ( 1000 );
    1178              :     }
    1179              :     else
    1180              :     {
    1181            0 :       this_treefilter->SetFilterRestrictionLevel ( 1 );
    1182              :     }
    1183              : 
    1184            0 :     this_treefilter->setFilterRegExp ( FilterText );
    1185              :   }
    1186              : 
    1187            0 :   update_total_objects();
    1188            0 : }
    1189              : 
    1190            0 : void dbe::MainWindow::slot_filter_query()
    1191              : {
    1192            0 :   if ( this_treefilter == nullptr )
    1193              :   {
    1194            0 :     return;
    1195              :   }
    1196              : 
    1197            0 :   QString Tmp = SearchTreeLine->text();
    1198            0 :   if ( SearchBox->currentIndex() == 1 )
    1199              :   {
    1200            0 :     this_treefilter->SetFilterType ( models::treeselection::ObjectFilterType );
    1201            0 :     std::vector<dbe::tref> Objects = ProcessQuery ( Tmp );
    1202              : 
    1203            0 :     this_treefilter->SetQueryObjects ( Objects );
    1204            0 :     this_treefilter->setFilterRegExp ( Tmp );
    1205            0 :     update_total_objects();
    1206            0 :   }
    1207              :   else {
    1208            0 :     this_treefilter->ResetQueryObjects ( );
    1209            0 :     slot_filter_textchange( Tmp );
    1210              :   }
    1211            0 : }
    1212              : 
    1213            0 : void dbe::MainWindow::slot_filter_table_textchange ( const QString & FilterText )
    1214              : {
    1215            0 :   TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->currentWidget() );
    1216              : 
    1217            0 :   if ( CurrentTab )
    1218              :   {
    1219            0 :     dbe::models::tableselection * TableFilter = CurrentTab->GetTableFilter();
    1220              : 
    1221            0 :     if ( TableFilter == nullptr )
    1222              :     {
    1223              :       return;
    1224              :     }
    1225              : 
    1226            0 :     TableFilter->SetFilterType ( dbe::models::tableselection::RegExpFilter );
    1227              : 
    1228            0 :     if ( CaseSensitiveCheckBoxTable->isChecked() )
    1229            0 :       TableFilter->setFilterCaseSensitivity (
    1230              :         Qt::CaseSensitive );
    1231              :     else
    1232              :     {
    1233            0 :       TableFilter->setFilterCaseSensitivity ( Qt::CaseInsensitive );
    1234              :     }
    1235              : 
    1236            0 :     TableFilter->setFilterRegExp ( FilterText );
    1237              :   }
    1238              : }
    1239              : 
    1240            0 : void dbe::MainWindow::slot_tree_reset()
    1241              : {
    1242              :     // Keep track of the selected tab
    1243            0 :     int IndexOfCurrentTab = tableholder->currentIndex();
    1244              : 
    1245              :     // Here are the all the open tabs
    1246            0 :     std::vector<QModelIndex> idxs;
    1247              : 
    1248            0 :     for(int i = 0; i < tableholder->count(); ++i) {
    1249            0 :         TableTab * CurrentTab = dynamic_cast<TableTab *>(tableholder->widget(i));
    1250            0 :         if(CurrentTab) {
    1251            0 :             if(CurrentTab->GetTableModel()) {
    1252            0 :                 const QString& TableClassName = CurrentTab->GetTableModel()->get_class_name();
    1253            0 :                 if(!TableClassName.isEmpty()) {
    1254            0 :                     treenode * NodeClass = confaccessor::gethandler()->getnode(TableClassName);
    1255            0 :                     if(NodeClass != nullptr) {
    1256            0 :                         idxs.push_back(this_classes->getindex(NodeClass));
    1257              :                     }
    1258              :                 }
    1259            0 :             }
    1260              :         }
    1261              :     }
    1262              : 
    1263              :     // Remove all the tabs
    1264            0 :     while(tableholder->count() != 0) {
    1265            0 :         tableholder->widget(0)->deleteLater();
    1266            0 :         tableholder->removeTab(0);
    1267              :     }
    1268              : 
    1269              :     // Disconnecting models from views
    1270            0 :     build_class_tree_model();
    1271              : 
    1272              :     // Re-create all the tabs
    1273            0 :     for(const auto& idx : idxs) {
    1274            0 :         slot_add_tab();
    1275            0 :         edit_object_at(idx);
    1276              :     }
    1277              : 
    1278              :     // Set the current tab
    1279            0 :     tableholder->setCurrentIndex ( IndexOfCurrentTab );
    1280            0 : }
    1281              : 
    1282            0 : void dbe::MainWindow::update_total_objects()
    1283              : {
    1284            0 :   int total=0;
    1285            0 :   for (int item=0; item<this_treefilter->rowCount(); item++) {
    1286            0 :     auto index = this_treefilter->index(item, 1);
    1287            0 :     auto data = this_treefilter->data(index);
    1288            0 :     total += data.toInt();
    1289            0 :   }
    1290            0 :   TotalObjectsLabel->setText (
    1291            0 :     QString ( "Total Objects: %1" ).arg ( total ) );
    1292            0 : }
    1293              : 
    1294            0 : void dbe::MainWindow::closeEvent ( QCloseEvent * event )
    1295              : {
    1296            0 :   if ( isArchivedConf || check_close() )
    1297              :   {
    1298            0 :     WriteSettings();
    1299              : 
    1300            0 :     foreach ( QWidget * widget, QApplication::allWidgets() ) widget->close();
    1301              : 
    1302            0 :     event->accept();
    1303              :   }
    1304              :   else
    1305              :   {
    1306            0 :     event->ignore();
    1307              :   }
    1308            0 : }
    1309              : 
    1310            0 : std::vector<dbe::tref> dbe::MainWindow::ProcessQuery ( QString const & Tmp )
    1311              : {
    1312            0 :   if ( not Tmp.isEmpty() )
    1313              :   {
    1314            0 :     QString const Query = QString ( "(this (object-id \".*%1.*\" ~=))" ).arg ( Tmp );
    1315              : 
    1316            0 :     try
    1317              :     {
    1318            0 :       std::vector<dbe::tref> result;
    1319              : 
    1320            0 :       for ( std::string const & cname : dbe::config::api::info::onclass::allnames <
    1321            0 :             std::vector<std::string >> () )
    1322              :       {
    1323            0 :         std::vector<dbe::tref> class_matching_objects = inner::dbcontroller::gets (
    1324            0 :                                                           cname, Query.toStdString() );
    1325              : 
    1326            0 :         result.insert ( result.end(), class_matching_objects.begin(),
    1327              :                         class_matching_objects.end() );
    1328            0 :       }
    1329              : 
    1330            0 :       return result;
    1331            0 :     }
    1332            0 :     catch ( dunedaq::conffwk::Exception const & ex )
    1333              :     {
    1334            0 :       ers::error ( ex );
    1335            0 :       ERROR ( "Query process error", dbe::config::errors::parse ( ex ).c_str() );
    1336            0 :     }
    1337            0 :   }
    1338              : 
    1339            0 :   return
    1340            0 :     {};
    1341              : }
    1342              : 
    1343            0 : bool dbe::MainWindow::eventFilter ( QObject * Target, QEvent * Event )
    1344              : {
    1345            0 :   if ( Target == SearchBox->lineEdit() && Event->type() == QEvent::MouseButtonRelease )
    1346              :   {
    1347            0 :     if ( !SearchBox->lineEdit()->hasSelectedText() )
    1348              :     {
    1349            0 :       SearchBox->lineEdit()->selectAll();
    1350            0 :       return true;
    1351              :     }
    1352              :   }
    1353              : 
    1354              :   return false;
    1355              : }
    1356              : 
    1357            0 : bool dbe::MainWindow::check_close()
    1358              : {
    1359            0 :   bool OK = true;
    1360              : 
    1361            0 :   foreach ( QWidget * widget, QApplication::allWidgets() )
    1362              :   {
    1363            0 :     ObjectCreator * ObjectCreatorInstance = dynamic_cast<ObjectCreator *> ( widget );
    1364            0 :     ObjectEditor * ObjectEditorInstance = dynamic_cast<ObjectEditor *> ( widget );
    1365              : 
    1366            0 :     if ( ObjectEditorInstance )
    1367              :     {
    1368            0 :       OK = ObjectEditorInstance->CanCloseWindow();
    1369              :     }
    1370              : 
    1371            0 :     if ( !OK )
    1372              :     {
    1373              :       return false;
    1374              :     }
    1375              : 
    1376            0 :     if ( ObjectCreatorInstance )
    1377              :     {
    1378            0 :       OK = ObjectCreatorInstance->CanClose();
    1379              :     }
    1380              : 
    1381            0 :     if ( !OK )
    1382              :     {
    1383              :       return false;
    1384              :     }
    1385            0 :   }
    1386              : 
    1387            0 :   {
    1388            0 :     cptr<QUndoStack> undo_stack ( confaccessor::get_commands() );
    1389              : 
    1390            0 :     if ( undo_stack->isClean() )
    1391              :     {
    1392            0 :       if ( undo_stack->count() == 0 )
    1393              :       {
    1394              :         return true;
    1395              :       }
    1396              :       else
    1397              :       {
    1398            0 :         slot_abort_changes();
    1399              :         return true;
    1400              :       }
    1401              :     }
    1402              :     else
    1403              :     {
    1404            0 :       int ret =
    1405            0 :         QMessageBox::question (
    1406              :           0,
    1407            0 :           tr ( "DBE" ),
    1408            0 :           QString (
    1409            0 :             "There are unsaved changes.\n\nDo you want to save and commit them to the DB?\n" ),
    1410            0 :           QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
    1411              :           QMessageBox::Save );
    1412              : 
    1413            0 :       if ( ret == QMessageBox::Discard )
    1414              :       {
    1415            0 :         slot_abort_changes();
    1416              :         return true;
    1417              :       }
    1418            0 :       else if ( ret == QMessageBox::Save )
    1419              :       {
    1420            0 :         return slot_commit_database ( true );
    1421              :       }
    1422            0 :       else if ( ret == QMessageBox::Cancel )
    1423              :       {
    1424              :         return false;
    1425              :       }
    1426              :       else
    1427              :       {
    1428              :         return true;
    1429              :       }
    1430              :     }
    1431            0 :   }
    1432              : }
    1433              : 
    1434            0 : void dbe::MainWindow::slot_edit_object_from_class_view ( QModelIndex const & ProxyIndex )
    1435              : {
    1436            0 :   edit_object_at ( this_treefilter->mapToSource ( ProxyIndex ) );
    1437            0 : }
    1438              : 
    1439              : /**
    1440              :  * Takes necessary actions to load a database from a file provided
    1441              :  * @param dbpath is the path (absolute or relative to the DUNEDAQ_DB_PATH) of the associated file
    1442              :  * @return
    1443              :  */
    1444            0 : bool dbe::MainWindow::dbopen ( QString const & dbpath, dbinfo const & loadtype )
    1445              : {
    1446            0 :     if ( dbreload() )
    1447              :     {
    1448            0 :       confaccessor::setdbinfo ( dbpath, loadtype );
    1449              : 
    1450            0 :       BOOST_SCOPE_EXIT(void)
    1451              :       {
    1452            0 :           QApplication::restoreOverrideCursor();
    1453            0 :       }
    1454            0 :       BOOST_SCOPE_EXIT_END
    1455              : 
    1456            0 :       QApplication::setOverrideCursor(Qt::WaitCursor);
    1457              : 
    1458            0 :       if ( dbload() )
    1459              :       {
    1460            0 :         setinternals();
    1461            0 :         build_class_tree_model();
    1462              :         // build_partition_tree_model();
    1463              :         // build_resource_tree_model();
    1464            0 :         build_file_model();
    1465              :       }
    1466            0 :     }
    1467              : 
    1468            0 :   return true;
    1469              : }
    1470              : 
    1471            0 : void dbe::MainWindow::slot_open_database_from_file()
    1472              : {
    1473            0 :   QFileDialog FileDialog ( this, tr ( "Open File" ), ".", tr ( "XML files (*.xml)" ) );
    1474            0 :   FileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
    1475            0 :   FileDialog.setFileMode ( QFileDialog::ExistingFile );
    1476            0 :   FileDialog.setViewMode ( QFileDialog::Detail );
    1477              : 
    1478            0 :   if ( FileDialog.exec() )
    1479              :   {
    1480            0 :     QStringList FilesSelected = FileDialog.selectedFiles();
    1481              : 
    1482            0 :     if ( FilesSelected.size() )
    1483              :     {
    1484            0 :       QString DatabasePath = FilesSelected.value ( 0 );
    1485            0 :       dbopen ( DatabasePath, dbinfo::oks );
    1486            0 :     }
    1487            0 :   }
    1488            0 : }
    1489              : 
    1490              : 
    1491              : /**
    1492              :  * The purpose of this method is to replay local changes after the database has been externally
    1493              :  * modified.
    1494              :  *
    1495              :  * It is called when there is a callback from config layer.
    1496              :  *
    1497              :  * The user is being given the option to ignore the external change and proceed without bringing
    1498              :  * his current database to a consistent state. This will cause the database to be overwritten when
    1499              :  * local changes are going to be applied.
    1500              :  */
    1501            0 : void dbe::MainWindow::slot_process_externalchanges()
    1502              : {
    1503            0 :   auto user_confirmation = [] ( QString const & msg )
    1504              :   {
    1505            0 :     QMessageBox ExternalMessageBox;
    1506            0 :     ExternalMessageBox.setText ( msg );
    1507            0 :     ExternalMessageBox.setStandardButtons ( QMessageBox::Yes | QMessageBox::No );
    1508            0 :     ExternalMessageBox.setDefaultButton ( QMessageBox::Yes );
    1509            0 :     return ExternalMessageBox.exec() == QMessageBox::Yes;
    1510            0 :   };
    1511              : 
    1512            0 :   confaccessor::t_undo_stack_cptr undo_stack = confaccessor::get_commands();
    1513              : 
    1514            0 :   auto rewind_stack = [&undo_stack] ()
    1515              :   {
    1516            0 :       std::vector<bool > commands_original_undo_state;
    1517              : 
    1518              :       // Loop over the commands and set their undo-state to false such that when the undostack
    1519              :       // index is rewind to zero they will not be undone. The purpose is to replay them on top of
    1520              :       // current changes.
    1521              : 
    1522            0 :       for ( int i = 0; i < undo_stack->count(); ++i )
    1523              :       {
    1524            0 :         if ( dbe::actions::onobject const * Command =
    1525            0 :                dynamic_cast<dbe::actions::onobject const *> ( undo_stack->command ( i ) )
    1526              :            )
    1527              :         {
    1528            0 :           commands_original_undo_state.push_back ( Command->undoable() );
    1529            0 :           Command->setundoable ( false );
    1530              :         }
    1531              :       }
    1532              : 
    1533              :       // Rewind the command stack by setting the index to zero
    1534              :       // Commands will not be replayed since we have set their state to false
    1535            0 :       undo_stack->setIndex ( 0 );
    1536              : 
    1537              :       // Reset the state of all commands one by one
    1538            0 :       {
    1539            0 :         auto cmdstate = commands_original_undo_state.begin();
    1540              : 
    1541            0 :         for ( int i = 0; i != undo_stack->count(); ++i )
    1542              :         {
    1543            0 :           if ( dbe::actions::onobject const * Command =
    1544            0 :                  dynamic_cast<dbe::actions::onobject const *> ( undo_stack->command ( i ) )
    1545              :              )
    1546              :           {
    1547            0 :             Command->setundoable ( *cmdstate++ );
    1548              :           }
    1549              :         }
    1550              :       }
    1551            0 :   };
    1552              : 
    1553              :   // Close active editor widgets before replaying changes
    1554            0 :   for ( QWidget * widget : QApplication::allWidgets() )
    1555              :   {
    1556            0 :       if ( dynamic_cast<widgets::editors::relation *> ( widget ) )
    1557              :       {
    1558            0 :           widget->close();
    1559              :       }
    1560            0 :   }
    1561              : 
    1562              : 
    1563            0 :   if ( undo_stack->count() != 0 )
    1564              :   {
    1565            0 :     const QString msg = QString("External changes to the database have been applied. Do you want to replay your changes on top? ")
    1566            0 :                        + QString(" Otherwise any local change will be lost.\n");
    1567            0 :     if ( user_confirmation ( msg ) )
    1568              :     {
    1569            0 :       rewind_stack();
    1570              : 
    1571              :       // Empty the internal stack and place the changes in a reverse order in a local stack
    1572            0 :       confaccessor::t_internal_changes_stack internal_changes_reverse_copy;
    1573            0 :       auto internal_changes = confaccessor::get_internal_change_stack();
    1574              : 
    1575            0 :       while ( not internal_changes->empty() )
    1576              :       {
    1577            0 :         internal_changes_reverse_copy.push ( internal_changes->top() );
    1578            0 :         internal_changes->pop();
    1579              :       }
    1580              : 
    1581              :       // Replay the commands one by one
    1582            0 :       for ( int i = 0; i < undo_stack->count(); ++i )
    1583              :       {
    1584            0 :         config_internal_change Change = internal_changes_reverse_copy.top();
    1585            0 :         internal_changes_reverse_copy.pop();
    1586            0 :         internal_changes->push ( Change );
    1587              : 
    1588            0 :         try
    1589              :         {
    1590              : 
    1591            0 :           dbe::actions::onobject const * Command =
    1592            0 :             dynamic_cast<dbe::actions::onobject const *> ( undo_stack->command ( i ) );
    1593              : 
    1594            0 :           if ( not Command->redoable() )
    1595              :           {
    1596            0 :             undo_stack->redo();
    1597              :           }
    1598              :           else
    1599              :           {
    1600              :             // If the object we are trying to make the changes to does not exist it means it was deleted
    1601              : 
    1602            0 :             if ( ( dbe::config::api::info::has_obj ( Change.classname, Change.uid ) and Change
    1603            0 :                    .request
    1604              :                    != config_internal_change::CREATED )
    1605            0 :                  or Change.request == config_internal_change::FILE_INCLUDED
    1606            0 :                  or Change.request == config_internal_change::FILE_DELETED )
    1607              :             {
    1608              :               // If in virtue of external modification the object still exists and our action was not a creation
    1609            0 :               Command->reload();
    1610            0 :               undo_stack->redo();
    1611              :             }
    1612            0 :             else if ( not dbe::config::api::info::has_obj ( Change.classname, Change.uid ) and Change
    1613            0 :                       .request
    1614              :                       == config_internal_change::CREATED )
    1615              :             {
    1616              :               // If the external changes have removed the object and we have created it
    1617            0 :               undo_stack->redo();
    1618            0 :               Command->reload();
    1619              :             }
    1620              :             else
    1621              :             {
    1622              :               /// "Emptying" the command so it does nothing at all
    1623            0 :               Command->setredoable ( false );
    1624            0 :               Command->setundoable ( false );
    1625              : 
    1626              :               // Advance the stack by redoing an non-redoable (i.e. the redo action has no effect) command
    1627            0 :               undo_stack->redo();
    1628              :             }
    1629              :           }
    1630              : 
    1631              :         }
    1632            0 :         catch ( dunedaq::conffwk::Exception const & e )
    1633              :         {
    1634            0 :           WARN ( "Object reference could not be changed",
    1635              :                  dbe::config::errors::parse ( e ).c_str(), "for object with UID:", Change.uid,
    1636            0 :                  "of class", Change.classname );
    1637            0 :         }
    1638            0 :         catch ( ... )
    1639              :         {
    1640            0 :           WARN ( "Unknown exception during object modification", "s",
    1641              :                  "\n\nFor object with UID:", Change.uid.c_str(), "of class:",
    1642            0 :                  Change.classname.c_str() );
    1643            0 :         }
    1644            0 :       }
    1645            0 :     } else {
    1646            0 :         confaccessor::clear_commands();
    1647              :     }
    1648            0 :   }
    1649              :   else
    1650              :   {
    1651            0 :     INFO ( "Database reloaded due external changes", "Database consistency enforcement" );
    1652            0 :     confaccessor::clear_commands();
    1653              :   }
    1654              : 
    1655            0 :   slot_tree_reset();
    1656            0 :   build_file_model();
    1657              : 
    1658              :   // Emit the signal for connected listeners (e.g., the object editors)
    1659            0 :   emit signal_externalchanges_processed();
    1660            0 : }
    1661              : 
    1662              : /**
    1663              :  * Permits to retrieve the main window pointer throughout the application
    1664              :  *
    1665              :  * @return a pointer of type MainWindow to the first class of type MainWindow
    1666              :  */
    1667            0 : dbe::MainWindow * dbe::MainWindow::findthis()
    1668              : {
    1669            0 :   QWidgetList allwidgets = QApplication::topLevelWidgets();
    1670              : 
    1671            0 :   QWidgetList::iterator it = allwidgets.begin();
    1672            0 :   MainWindow * main_win = qobject_cast<MainWindow *> ( *it );
    1673              : 
    1674            0 :   for ( ; it != allwidgets.end() and main_win == nullptr; ++it )
    1675              :   {
    1676            0 :     main_win = qobject_cast<MainWindow *> ( *it );
    1677              :   }
    1678              : 
    1679            0 :   return main_win;
    1680            0 : }
    1681              : 
    1682              : //-----------------------------------------------------------------------------------------------------------------------------
    1683              : 
    1684              : //-----------------------------------------------------------------------------------------------------------------------------
    1685              : /**
    1686              :  * This method permits to propagate and display messages from the messaging subsytem.
    1687              :  *
    1688              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1689              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1690              :  *
    1691              :  */
    1692              : namespace {
    1693              :     const int MAX_MESSAGE_LENGTH = 500;
    1694              : }
    1695              : 
    1696            0 : void dbe::MainWindow::slot_failure_message ( QString const title, QString const msg )
    1697              : {
    1698            0 :     QMessageBox mb(this);
    1699            0 :     mb.setIcon(QMessageBox::Icon::Critical);
    1700            0 :     mb.setWindowTitle(title);
    1701            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1702            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1703            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1704            0 :         m.append("...");
    1705            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1706            0 :         mb.setInformativeText(m);
    1707            0 :         mb.setDetailedText(msg);
    1708            0 :     } else {
    1709            0 :         mb.setText(msg);
    1710              :     }
    1711              : 
    1712            0 :     mb.exec();
    1713            0 : }
    1714              : 
    1715              : /**
    1716              :  * This method permits to propagate and display messages from the messaging subsytem.
    1717              :  *
    1718              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1719              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1720              :  *
    1721              :  */
    1722            0 : void dbe::MainWindow::slot_information_message ( QString const title, QString const msg )
    1723              : {
    1724            0 :     QMessageBox mb(this);
    1725            0 :     mb.setIcon(QMessageBox::Icon::Information);
    1726            0 :     mb.setWindowTitle(title);
    1727            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1728            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1729            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1730            0 :         m.append("...");
    1731            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1732            0 :         mb.setInformativeText(m);
    1733            0 :         mb.setDetailedText(msg);
    1734            0 :     } else {
    1735            0 :         mb.setText(msg);
    1736              :     }
    1737              : 
    1738            0 :     mb.exec();
    1739            0 : }
    1740              : 
    1741              : /**
    1742              :  * This method permits to propagate and display messages from the messaging subsytem.
    1743              :  *
    1744              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1745              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1746              :  *
    1747              :  */
    1748            0 : void dbe::MainWindow::slot_debuginfo_message ( QString const title, QString const msg )
    1749              : {
    1750            0 :     QMessageBox mb(this);
    1751            0 :     mb.setIcon(QMessageBox::Icon::Information);
    1752            0 :     mb.setWindowTitle(title);
    1753            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1754            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1755            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1756            0 :         m.append("...");
    1757            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1758            0 :         mb.setInformativeText(m);
    1759            0 :         mb.setDetailedText(msg);
    1760            0 :     } else {
    1761            0 :         mb.setText(msg);
    1762              :     }
    1763              : 
    1764            0 :     mb.exec();
    1765            0 : }
    1766              : 
    1767              : /**
    1768              :  * This method permits to propagate and display messages from the messaging subsytem.
    1769              :  *
    1770              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1771              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1772              :  *
    1773              :  */
    1774            0 : void dbe::MainWindow::slot_notice_message ( QString const title, QString const msg )
    1775              : {
    1776            0 :     QMessageBox mb(this);
    1777            0 :     mb.setIcon(QMessageBox::Icon::Information);
    1778            0 :     mb.setWindowTitle(title);
    1779            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1780            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1781            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1782            0 :         m.append("...");
    1783            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1784            0 :         mb.setInformativeText(m);
    1785            0 :         mb.setDetailedText(msg);
    1786            0 :     } else {
    1787            0 :         mb.setText(msg);
    1788              :     }
    1789              : 
    1790            0 :     mb.exec();
    1791            0 : }
    1792              : 
    1793              : /**
    1794              :  * This method permits to propagate and display messages from the messaging subsytem.
    1795              :  *
    1796              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1797              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1798              :  *
    1799              :  */
    1800            0 : void dbe::MainWindow::slot_error_message ( QString const title, QString const msg )
    1801              : {
    1802            0 :     QMessageBox mb(this);
    1803            0 :     mb.setIcon(QMessageBox::Icon::Critical);
    1804            0 :     mb.setWindowTitle(title);
    1805            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1806            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1807            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1808            0 :         m.append("...");
    1809            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1810            0 :         mb.setInformativeText(m);
    1811            0 :         mb.setDetailedText(msg);
    1812            0 :     } else {
    1813            0 :         mb.setText(msg);
    1814              :     }
    1815              : 
    1816            0 :     mb.exec();
    1817            0 : }
    1818              : 
    1819              : /**
    1820              :  * This method permits to propagate and display messages from the messaging subsytem.
    1821              :  *
    1822              :  * It is important that the arguments are pass-by-copy because references will become invalid,
    1823              :  * even if they are bound to consted temporaries, once the deleter from the other thread is called.
    1824              :  *
    1825              :  */
    1826            0 : void dbe::MainWindow::slot_warning_message ( QString const title, QString const msg )
    1827              : {
    1828            0 :     QMessageBox mb(this);
    1829            0 :     mb.setIcon(QMessageBox::Icon::Warning);
    1830            0 :     mb.setWindowTitle(title);
    1831            0 :     mb.setStandardButtons(QMessageBox::Ok);
    1832            0 :     if(msg.length() > MAX_MESSAGE_LENGTH) {
    1833            0 :         QString&& m = msg.left(MAX_MESSAGE_LENGTH);
    1834            0 :         m.append("...");
    1835            0 :         mb.setText("<b>The message has been truncated because too long, look at the details for the full message</b>");
    1836            0 :         mb.setInformativeText(m);
    1837            0 :         mb.setDetailedText(msg);
    1838            0 :     } else {
    1839            0 :         mb.setText(msg);
    1840              :     }
    1841              : 
    1842            0 :     mb.exec();
    1843            0 : }
    1844              : 
    1845              : //-----------------------------------------------------------------------------------------------------------------------------
    1846              : 
    1847            0 : cptr<dbe::CustomTreeView> dbe::MainWindow::get_view() const
    1848              : {
    1849            0 :   return cptr<CustomTreeView> ( TreeView );
    1850              : }
    1851              : 
    1852            0 : void dbe::MainWindow::slot_batch_change_start()
    1853              : {
    1854            0 :   m_batch_change_in_progress = true;
    1855            0 : }
    1856              : 
    1857            0 : void dbe::MainWindow::slot_batch_change_stop(const QList<QPair<QString, QString>>& objs)
    1858              : {
    1859            0 :   std::vector<dbe::dref> objects;
    1860            0 :   for(const auto& o : objs) {
    1861            0 :       objects.push_back(inner::dbcontroller::get({o.second.toStdString(), o.first.toStdString()}));
    1862              :   }
    1863              : 
    1864              :   // This allows to not reset the main tree
    1865            0 :   this_classes->objectsUpdated(objects);
    1866              : 
    1867              :   // In this case the corresponding trees are reset
    1868              :   // In order to apply the same policy as in the class tree
    1869              :   // the subtree_proxy class needs to be completed with proper
    1870              :   // implementation of slots when objects are modified
    1871              : 
    1872              :   // Proper "refresh" of table tabs
    1873            0 :   for ( int i = 0; i < tableholder->count(); i++ )
    1874              :   {
    1875            0 :       TableTab * CurrentTab = dynamic_cast<TableTab *> ( tableholder->widget ( i ) );
    1876            0 :       if ( CurrentTab ) {
    1877            0 :           dbe::models::table* m = CurrentTab->GetTableModel();
    1878            0 :           if ( m ) {
    1879            0 :               m->objectsUpdated(objects);
    1880              :           }
    1881              :       }
    1882              :   }
    1883              : 
    1884            0 :   emit signal_batch_change_stopped(objs);
    1885              : 
    1886            0 :   m_batch_change_in_progress = false;
    1887            0 : }
    1888              : 
    1889            0 : void dbe::MainWindow::slot_toggle_commit_button()
    1890              : {
    1891            0 :     if(isArchivedConf == false) {
    1892            0 :         const auto& uncommittedFiles = confaccessor::uncommitted_files();
    1893              : 
    1894            0 :         if(uncommittedFiles.empty() == true) {
    1895            0 :             Commit->setEnabled(false);
    1896            0 :             Commit->setToolTip("There is nothing to commit");
    1897              :         } else {
    1898            0 :             Commit->setEnabled(true);
    1899              : 
    1900            0 :             std::string l;
    1901            0 :             for(const std::string& f : uncommittedFiles) {
    1902            0 :                 l += "  " + f + "\n";
    1903              :             }
    1904              : 
    1905            0 :             Commit->setToolTip(QString::fromStdString("Commit changes.\nHere are the uncommitted files:\n" + l));
    1906            0 :         }
    1907              : 
    1908            0 :         build_file_model();
    1909              : 
    1910            0 :     } else {
    1911            0 :         Commit->setEnabled(false);
    1912              :     }
    1913            0 : }
    1914              : 
    1915            0 : void dbe::MainWindow::slot_update_committed_files(const std::list<std::string>& files, const std::string& msg) {
    1916            0 :     for(const std::string& f : files) {
    1917            0 :         CommittedTable->insertRow(0);
    1918            0 :         CommittedTable->setItem(0, 0, new QTableWidgetItem(QString::fromStdString(f)));
    1919            0 :         CommittedTable->setItem(0, 1, new QTableWidgetItem(QString::fromStdString(msg)));
    1920            0 :         CommittedTable->setItem(0, 2, new QTableWidgetItem(QDate::currentDate().toString() + " " + QTime::currentTime().toString()));
    1921              :     }
    1922              : 
    1923            0 :     CommittedTable->resizeColumnsToContents();
    1924            0 : }
    1925              : 
    1926            0 : bool dbe::MainWindow::check_ready() const
    1927              : {
    1928            0 :   return not m_batch_change_in_progress;
    1929              : }
    1930              : 
    1931            0 : void dbe::MainWindow::slot_loaded_db_file( QString file )
    1932              : {
    1933            0 :     allFiles.insert(file);
    1934            0 : }
        

Generated by: LCOV version 2.0-1