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

Generated by: LCOV version 2.0-1