LCOV - code coverage report
Current view: top level - dbe/src/widgets - BuildingBlockEditors.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 1259 0
Test Date: 2026-07-12 15:23:06 Functions: 0.0 % 113 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/config_api.hpp"
       7              : #include "dbe/confaccessor.hpp"
       8              : #include "dbe/BuildingBlockEditors.hpp"
       9              : #include "dbe/Validator.hpp"
      10              : #include "dbe/StyleUtility.hpp"
      11              : #include "dbe/ObjectEditor.hpp"
      12              : #include "dbe/CustomDelegate.hpp"
      13              : 
      14              : #include <QStringListModel>
      15              : #include <QMessageBox>
      16              : #include <QCompleter>
      17              : #include <QLineEdit>
      18              : #include <QListWidget>
      19              : #include <QPair>
      20              : #include <QMimeData>
      21              : #include <QByteArray>
      22              : #include <QDataStream>
      23              : #include <QEvent>
      24              : #include <QWidget>
      25              : 
      26              : #include <boost/scope_exit.hpp>
      27              : 
      28              : #include <functional>
      29              : #include <memory>
      30              : 
      31              : namespace dbe
      32              : {
      33            0 : editor_data_state::~editor_data_state() = default;
      34              : 
      35              : 
      36              : template<>
      37            0 : editor_data<dunedaq::conffwk::relationship_t>::editor_data (
      38            0 :   dunedaq::conffwk::relationship_t const & virtue )
      39              :   :
      40              :   editor_data_state ( true, false, true ),
      41            0 :   this_virtue ( virtue )
      42            0 : {}
      43              : 
      44            0 : template<typename T> editor_data<T>::~editor_data() = default;
      45              : 
      46              : namespace widgets
      47              : {
      48              : 
      49              : namespace editors
      50              : {
      51              : //------------------------------------------------------------------------------------------------
      52            0 : base::base ( std::shared_ptr<editor_data_state> editordata,
      53            0 :              QWidget * parent, bool owned )
      54              :   :
      55              :   QWidget ( parent ),
      56            0 :   p_data_editor ( editordata ),
      57            0 :   this_is_owned ( owned ),
      58            0 :   this_value_changed ( false ),
      59            0 :   this_initial_load ( false )
      60            0 : {}
      61              : 
      62              : 
      63              : template<>
      64            0 : std::shared_ptr<editor_data_state> base::dataeditor<editor_data_state>()
      65              : {
      66            0 :   return p_data_editor;
      67              : }
      68              : 
      69            0 : QStringList base::getdata()
      70              : {
      71            0 :   return this_data;
      72              : }
      73              : 
      74            0 : void base::setdata ( QStringList const & ValueList )
      75              : {
      76            0 :   this_data = ValueList;
      77            0 : }
      78              : 
      79            0 : void base::setdefaults ( QString const & ValueDefault )
      80              : {
      81            0 :   this_defaults = ValueDefault;
      82            0 : }
      83              : 
      84            0 : void base::setchanged ( bool const val )
      85              : {
      86            0 :   this_value_changed = val;
      87            0 : }
      88              : 
      89            0 : bool base::ischanged() const
      90              : {
      91            0 :   return this_value_changed;
      92              : }
      93              : 
      94            0 : void base::slot_set_initial_loaded()
      95              : {
      96            0 :   this_initial_load = true;
      97            0 : }
      98              : 
      99            0 : void base::closeEvent ( QCloseEvent * Event )
     100              : {
     101            0 :   Q_UNUSED ( Event )
     102            0 : }
     103              : 
     104              : //------------------------------------------------------------------------------------------------
     105              : 
     106              : 
     107              : //------------------------------------------------------------------------------------------------
     108            0 : relation::relation ( t_virtue const & relation, QWidget * parent,
     109            0 :                      bool owned )
     110              :   :
     111              :   base (
     112            0 :    std::make_shared<t_build_block_editor> ( relation ), parent, owned ),
     113            0 :   p_base_data_editor ( std::static_pointer_cast<t_build_block_editor> ( p_data_editor ) ),
     114            0 :   IsMultiValue ( false ),
     115            0 :   StatusBar ( nullptr ),
     116            0 :   ContextMenu ( nullptr ),
     117            0 :   RemoveAction ( nullptr ),
     118            0 :   MoveTop ( nullptr ),
     119            0 :   MoveBottom ( nullptr ),
     120            0 :   MoveUp ( nullptr ),
     121            0 :   MoveDown ( nullptr ),
     122            0 :   EditAction ( nullptr ),
     123            0 :   CurrentItem ( nullptr )
     124              : {
     125            0 :   setupUi ( this );
     126              : 
     127            0 :   t_virtue const & Virtue = p_base_data_editor->get();
     128              : 
     129            0 :   setWindowTitle ( QString ( "Edit Relationship: %1" ).arg ( Virtue.p_name.c_str() ) );
     130            0 :   ListWidget->setContextMenuPolicy ( Qt::CustomContextMenu );
     131            0 :   ComboBox->setHidden ( true );
     132              : 
     133              :   // if it is X_ and many then set multivalue
     134              : 
     135            0 :   if ( ( Virtue.p_cardinality == dunedaq::conffwk::zero_or_many ) ||
     136              :        ( Virtue.p_cardinality == dunedaq::conffwk::one_or_many ) )
     137              :   {
     138            0 :     IsMultiValue = true;
     139              :   }
     140              : 
     141              :   // Check if this relation can be left unset
     142            0 :   if ( ( Virtue.p_cardinality == dunedaq::conffwk::one_or_many ) ||
     143              :        ( Virtue.p_cardinality == dunedaq::conffwk::only_one ) )
     144              :   {
     145            0 :     p_base_data_editor->set_not_null ( true );
     146            0 :     p_base_data_editor->set_valid ( false );
     147              :   }
     148              : 
     149              :   /// Setting Controller
     150            0 :   SetController();
     151              : 
     152            0 :   if ( this_is_owned )
     153              :   {
     154            0 :     SaveButton->setHidden ( true );
     155            0 :     RemoveButton->setHidden ( true );
     156              :   }
     157              : 
     158            0 :   buildtooltip();
     159            0 : }
     160              : 
     161            0 : bool relation::eventFilter ( QObject * Target, QEvent * Event )
     162              : {
     163            0 :     if(dynamic_cast<QListWidget*>(Target)) {
     164            0 :         auto decode = [this] (const QMimeData * const data) -> QPair<bool, QStringList>
     165              :         {
     166            0 :             bool allGood = true;
     167            0 :             QStringList newItems;
     168              : 
     169            0 :             if(data->hasFormat("application/vnd.text.list") == true) {
     170            0 :                 QByteArray encodedData = data->data("application/vnd.text.list");
     171            0 :                 QDataStream stream(&encodedData, QIODevice::ReadOnly);
     172              : 
     173            0 :                 const std::string& referenceClass = p_base_data_editor->get().p_type;
     174              : 
     175            0 :                 while(!stream.atEnd()) {
     176            0 :                     QStringList text;
     177            0 :                     stream >> text;
     178              : 
     179            0 :                     const QString& obj_id = text.at(0);
     180            0 :                     const QString& obj_class = text.at(1);
     181              : 
     182            0 :                     if((obj_class.toStdString() == referenceClass) ||
     183            0 :                        (dbe::config::api::info::onclass::derived(referenceClass, obj_class.toStdString()) == true))
     184              :                     {
     185            0 :                         newItems.append(obj_id);
     186              :                     } else {
     187            0 :                         allGood = false;
     188              :                     }
     189            0 :                 }
     190            0 :             } else {
     191            0 :                 allGood = false;
     192              :             }
     193              : 
     194            0 :             return qMakePair(allGood, newItems);
     195            0 :         };
     196              : 
     197            0 :         if(Event->type() == QEvent::DragEnter) {
     198            0 :            QDragEnterEvent *tDropEvent = static_cast<QDragEnterEvent *>(Event);
     199              : 
     200            0 :            const QMimeData * const data = tDropEvent->mimeData();
     201            0 :            const auto& decodedData = decode(data);
     202            0 :            if((decodedData.first == true) && (decodedData.second.size() > 0)) {
     203            0 :                tDropEvent->acceptProposedAction();
     204              :            }
     205              : 
     206            0 :            return true;
     207            0 :         }
     208              : 
     209            0 :         if(Event->type() == QEvent::Drop) {
     210            0 :             QDropEvent *tDropEvent = static_cast<QDropEvent *>(Event);
     211              : 
     212            0 :             const QMimeData * const data = tDropEvent->mimeData();
     213            0 :             for(const QString& o : decode(data).second) {
     214              :                 // TODO: this is not very efficient for large lists
     215            0 :                 AddToDataList(o);
     216            0 :             }
     217              : 
     218            0 :             tDropEvent->acceptProposedAction();
     219              : 
     220            0 :             return true;
     221              :         }
     222            0 :     } else if(QComboBox * Box = dynamic_cast<QComboBox *>(Target)) {
     223            0 :         if(Event->type() == QEvent::Wheel) {
     224              :             return true;
     225              :         }
     226              : 
     227            0 :         if(Event->type() == QEvent::KeyPress) {
     228            0 :             QKeyEvent * KeyEvent = dynamic_cast<QKeyEvent *>(Event);
     229              : 
     230            0 :             if(KeyEvent->key() == Qt::Key_Up || KeyEvent->key() == Qt::Key_Down) {
     231              :                 return true;
     232              :             } else {
     233              :                 return false;
     234              :             }
     235              :         }
     236              : 
     237            0 :         if(Event->type() == QEvent::FocusOut) {
     238            0 :             QWidget * popup = Box->findChild<QFrame *>();
     239            0 :             QWidget * popup1 = Box->lineEdit()->findChild<QFrame *>();
     240              : 
     241            0 :             if(popup != popup1 and not popup->isHidden()) {
     242              :                 return true;
     243              :             }
     244              : 
     245            0 :             if(FirstItem == nullptr) {
     246            0 :                 if(IsMultiValue) {
     247            0 :                     FirstItem = new QListWidgetItem("Type here");
     248              :                 } else {
     249            0 :                     if(this_data.isEmpty()) {
     250            0 :                         FirstItem = new QListWidgetItem("No Object");
     251              :                     } else {
     252            0 :                         FirstItem = new QListWidgetItem(this_data.at(0));
     253              :                     }
     254              :                 }
     255              : 
     256            0 :                 ListWidget->addItem(FirstItem);
     257              : 
     258            0 :                 if(IsMultiValue) {
     259            0 :                     FirstItem->setBackground(Qt::GlobalColor::lightGray);
     260            0 :                     FirstItem->setForeground(QColor(0, 0, 0, 127));
     261              :                 }
     262              : 
     263            0 :                 FirstItem->setSizeHint(FirstItem->sizeHint() + QSize(0, 25));
     264            0 :             } else if(FirstItem->listWidget() == ListWidget && ListWidget->itemWidget(FirstItem) != 0) {
     265            0 :                 ListWidget->takeItem(ListWidget->row(FirstItem));
     266            0 :                 ListWidget->setItemWidget(FirstItem, nullptr);
     267            0 :                 delete FirstItem;
     268              : 
     269            0 :                 if(IsMultiValue) {
     270            0 :                     FirstItem = new QListWidgetItem("Type here");
     271              :                 } else {
     272            0 :                     if(this_data.isEmpty()) {
     273            0 :                         FirstItem = new QListWidgetItem("No Object");
     274              :                     } else {
     275            0 :                         FirstItem = new QListWidgetItem(this_data.at(0));
     276              :                     }
     277              :                 }
     278              : 
     279            0 :                 ListWidget->addItem(FirstItem);
     280              : 
     281            0 :                 if(IsMultiValue) {
     282            0 :                     FirstItem->setBackground(Qt::GlobalColor::lightGray);
     283            0 :                     FirstItem->setForeground(QColor(0, 0, 0, 127));
     284              :                 }
     285              : 
     286            0 :                 FirstItem->setSizeHint(FirstItem->sizeHint() + QSize(0, 25));
     287              :             }
     288              : 
     289            0 :             return false;
     290              :         }
     291            0 :     } else if(QLineEdit* le = dynamic_cast<QLineEdit *>(Target)) {
     292            0 :         if(Event->type() == QEvent::MouseButtonDblClick) {
     293            0 :             const QString& value = le->text();
     294              : 
     295              :             // This string checking is very very bad...
     296            0 :             if((value.isEmpty() == false) && (value != "Type here") && (value != "No Object")) {
     297            0 :                 CreateObjectEditor(le->text().toStdString());
     298            0 :                 return false;
     299              :             }
     300            0 :         }
     301              :     }
     302              : 
     303              :     return false;
     304              : }
     305              : 
     306            0 : void relation::SetEditor()
     307              : {
     308            0 :   ListWidget->clear();
     309              : 
     310            0 :   if ( IsMultiValue )
     311              :   {
     312            0 :     ListWidget->addItems ( this_data );
     313              : 
     314              :     // Enable drops only for multi-value
     315              :     // This allows to drop several objects in a relationship (e.g., several computers in a rack)
     316              :     // Not really needed for single-value relationship (the item can be selected from the list)
     317            0 :     ListWidget->setAcceptDrops ( true );
     318            0 :     ListWidget->installEventFilter ( this );
     319              :   }
     320              : 
     321            0 :   SetFirstItem();
     322              : 
     323            0 :   ListWidget->setSelectionMode ( QAbstractItemView::ExtendedSelection );
     324            0 :   ListWidget->setEditTriggers ( QAbstractItemView::DoubleClicked );
     325            0 :   ListWidget->setDragDropMode ( QAbstractItemView::InternalMove );
     326              : 
     327            0 :   CurrentDataList = this_data;
     328              : 
     329              :   /// Cleaning and Fetching Data
     330            0 :   ComboBox->clear();
     331              : 
     332            0 :   FetchData();
     333            0 : }
     334              : 
     335            0 : void relation::FetchData()
     336              : {
     337            0 :   QStringList result;
     338            0 :   t_virtue const & Virtue = p_base_data_editor->get();
     339              : 
     340            0 :   std::vector<tref> const & related
     341              :   {
     342            0 :     dbe::config::api::info::onclass::objects<true> ( Virtue.p_type )
     343            0 :   };
     344              : 
     345            0 :   for ( tref const & o : related )
     346              :   {
     347            0 :     result.append ( QString::fromStdString ( o.UID() ) );
     348              :   }
     349              : 
     350            0 :   emit FetchDataDone ( result );
     351            0 : }
     352              : 
     353            0 : bool relation::GetIsMultiValue() const
     354              : {
     355            0 :   return IsMultiValue;
     356              : }
     357              : 
     358            0 : void relation::DataWasFetched ( QStringList ListOfObjects )
     359              : {
     360            0 :   ComboBox->clear();
     361            0 :   ComboBox->addItems ( ListOfObjects );
     362              : 
     363            0 :   emit signal_internal_value_change();
     364              : 
     365            0 :   if ( this_initial_load )
     366              :   {
     367            0 :     emit LoadedInitials();
     368              :   }
     369            0 : }
     370              : 
     371            0 : void relation::SetController()
     372              : {
     373            0 :   connect ( SaveButton, SIGNAL ( clicked() ), this, SLOT ( EndSignal() ) );
     374            0 :   connect ( RemoveButton, SIGNAL ( clicked() ), this, SLOT ( RemoveFromDataList() ) );
     375            0 :   connect ( this, SIGNAL ( signal_internal_value_change() ), this, SLOT ( UpdateActions() ) );
     376            0 :   connect (
     377              :     this, SIGNAL ( FetchDataDone ( QStringList ) ), this,
     378              :     SLOT ( DataWasFetched ( QStringList ) ) );
     379              :   /// Connect an action to edit objects from the list view
     380            0 :   connect ( ListWidget, SIGNAL ( customContextMenuRequested ( QPoint ) ), this,
     381              :             SLOT ( CustomContextMenuRequested ( QPoint ) ) );
     382            0 :   connect ( ListWidget, SIGNAL ( itemDoubleClicked ( QListWidgetItem * ) ), this,
     383              :             SLOT ( CreateObjectEditor ( QListWidgetItem * ) ), Qt::UniqueConnection );
     384            0 :   connect ( ListWidget->model(), SIGNAL ( layoutChanged() ), this, SLOT ( DummyMovement() ) );
     385            0 :   connect ( ListWidget, SIGNAL ( itemPressed ( QListWidgetItem * ) ), this,
     386              :             SLOT ( EditItemEntered ( QListWidgetItem * ) ) );
     387            0 :   connect ( &confaccessor::ref(), SIGNAL ( object_created ( QString, dref ) ), this,
     388              :               SLOT ( FetchData () ) );
     389            0 :   connect ( &confaccessor::ref(), SIGNAL ( object_deleted ( QString, dref ) ), this,
     390              :                 SLOT ( FetchData () ) );
     391            0 : }
     392              : 
     393            0 : void relation::SetFirstItem()
     394              : {
     395            0 :   if ( IsMultiValue )
     396              :   {
     397            0 :     FirstItem = new QListWidgetItem ( "Type here" );
     398              :   }
     399              :   else
     400              :   {
     401            0 :     if ( this_data.isEmpty() )
     402              :     {
     403            0 :       FirstItem = new QListWidgetItem ( "No Object" );
     404              :     }
     405              : 
     406              :     else
     407              :     {
     408            0 :       FirstItem = new QListWidgetItem ( this_data.at ( 0 ) );
     409              :     }
     410              :   }
     411              : 
     412            0 :   ListWidget->addItem ( FirstItem );
     413              : 
     414            0 :   if ( IsMultiValue )
     415              :   {
     416            0 :     FirstItem->setBackground ( Qt::GlobalColor::lightGray );
     417            0 :     FirstItem->setForeground ( QColor ( 0, 0, 0, 127 ) );
     418              :   }
     419              : 
     420            0 :   FirstItem->setSizeHint ( FirstItem->sizeHint() + QSize ( 0, 25 ) );
     421            0 : }
     422              : 
     423            0 : void relation::buildtooltip()
     424              : {
     425            0 :   t_virtue const & Virtue = p_base_data_editor->get();
     426            0 :   setToolTip (
     427            0 :     QString ( "Relationship Name:            %1 \n" ).arg ( Virtue.p_name.c_str() ) + QString (
     428            0 :       "             Type:            %1 \n" ).arg ( Virtue.p_type.c_str() )
     429            0 :     + QString ( "             Cardinality:     %1 \n" ).arg (
     430            0 :       dunedaq::conffwk::relationship_t::card2str ( Virtue.p_cardinality ) )
     431            0 :     + QString ( "             Is Aggregation:  %1 \n" ).arg ( Virtue.p_is_aggregation )
     432            0 :     + QString ( "             Description:     %1 \n" ).arg ( Virtue.p_description.c_str() ) );
     433            0 : }
     434            0 : void relation::CreateObjectEditor ( const std::string& objectID )
     435              : {
     436            0 :     t_virtue const & virt = p_base_data_editor->get();
     437            0 :     tref const & obj = inner::dbcontroller::get( {objectID, virt.p_type} );
     438              : 
     439            0 :     QString oname = QString::fromStdString ( obj.full_name() );
     440              : 
     441            0 :     for ( QWidget * editor : QApplication::allWidgets() )
     442              :     {
     443            0 :       if ( ObjectEditor * w = dynamic_cast<ObjectEditor *> ( editor ) )
     444              :       {
     445            0 :         if ( ( w->objectName() ).compare ( oname ) == 0 )
     446              :         {
     447            0 :           w->raise();
     448            0 :           w->setVisible ( true );
     449            0 :           return;
     450              :         }
     451              :       }
     452            0 :     }
     453              : 
     454            0 :     ( new ObjectEditor ( obj ) )->show();
     455            0 : }
     456              : 
     457            0 : void relation::CreateObjectEditor ( QListWidgetItem * Item )
     458              : {
     459            0 :   if ( Item == FirstItem )
     460              :   {
     461            0 :     EditItemEntered ( FirstItem );
     462            0 :     return;
     463              :   }
     464              : 
     465            0 :   std::string const & ouid = Item->data ( Qt::DisplayRole ).toString().toStdString();
     466            0 :   CreateObjectEditor(ouid);
     467            0 : }
     468              : 
     469            0 : void relation::CustomContextMenuRequested ( const QPoint & pos )
     470              : {
     471            0 :   if ( ContextMenu == nullptr )
     472              :   {
     473            0 :     ContextMenu = new QMenu ( ListWidget );
     474              : 
     475            0 :     MoveTop = new QAction ( tr ( "Move Top" ), this );
     476            0 :     MoveTop->setShortcutContext ( Qt::WidgetShortcut );
     477            0 :     connect ( MoveTop, SIGNAL ( triggered() ), this, SLOT ( MoveTopSlot() ) );
     478            0 :     ContextMenu->addAction ( MoveTop );
     479              : 
     480            0 :     MoveBottom = new QAction ( tr ( "Move Bottom" ), this );
     481            0 :     MoveBottom->setShortcutContext ( Qt::WidgetShortcut );
     482            0 :     connect ( MoveBottom, SIGNAL ( triggered() ), this, SLOT ( MoveBottomSlot() ) );
     483            0 :     ContextMenu->addAction ( MoveBottom );
     484              : 
     485            0 :     MoveUp = new QAction ( tr ( "Move Up" ), this );
     486            0 :     MoveUp->setShortcutContext ( Qt::WidgetShortcut );
     487            0 :     connect ( MoveUp, SIGNAL ( triggered() ), this, SLOT ( MoveUpSlot() ) );
     488            0 :     ContextMenu->addAction ( MoveUp );
     489              : 
     490            0 :     MoveDown = new QAction ( tr ( "Move Down" ), this );
     491            0 :     MoveDown->setShortcutContext ( Qt::WidgetShortcut );
     492            0 :     connect ( MoveDown, SIGNAL ( triggered() ), this, SLOT ( MoveDownSlot() ) );
     493            0 :     ContextMenu->addAction ( MoveDown );
     494              : 
     495            0 :     ContextMenu->addSeparator();
     496              : 
     497            0 :     EditAction = new QAction ( tr ( "Edit" ), this );
     498            0 :     EditAction->setShortcutContext ( Qt::WidgetShortcut );
     499            0 :     connect ( EditAction, SIGNAL ( triggered() ), this, SLOT ( EditSlot() ) );
     500            0 :     ContextMenu->addAction ( EditAction );
     501              : 
     502            0 :     RemoveAction = new QAction ( tr ( "Remove" ), this );
     503            0 :     RemoveAction->setShortcutContext ( Qt::WidgetShortcut );
     504            0 :     connect ( RemoveAction, SIGNAL ( triggered() ), this, SLOT ( RemoveSlot() ) );
     505            0 :     ContextMenu->addAction ( RemoveAction );
     506              :   }
     507              : 
     508            0 :   if ( ( CurrentItem = ListWidget->itemAt ( pos ) ) )
     509              :   {
     510            0 :     if ( CurrentItem != FirstItem )
     511              :     {
     512            0 :       ( ContextMenu->actions() ).at ( 0 )->setVisible ( true );
     513            0 :       ( ContextMenu->actions() ).at ( 1 )->setVisible ( true );
     514            0 :       ( ContextMenu->actions() ).at ( 2 )->setVisible ( true );
     515            0 :       ( ContextMenu->actions() ).at ( 3 )->setVisible ( true );
     516            0 :       ( ContextMenu->actions() ).at ( 4 )->setVisible ( true );
     517            0 :       ( ContextMenu->actions() ).at ( 5 )->setVisible ( false );
     518            0 :       ( ContextMenu->actions() ).at ( 6 )->setVisible ( true );
     519              : 
     520            0 :       ContextMenu->exec ( ListWidget->mapToGlobal ( pos ) );
     521              :     }
     522              : 
     523            0 :     else if ( CurrentItem == FirstItem and not IsMultiValue )
     524              :     {
     525            0 :       ( ContextMenu->actions() ).at ( 0 )->setVisible ( false );
     526            0 :       ( ContextMenu->actions() ).at ( 1 )->setVisible ( false );
     527            0 :       ( ContextMenu->actions() ).at ( 2 )->setVisible ( false );
     528            0 :       ( ContextMenu->actions() ).at ( 3 )->setVisible ( false );
     529            0 :       ( ContextMenu->actions() ).at ( 4 )->setVisible ( true );
     530            0 :       ( ContextMenu->actions() ).at ( 5 )->setVisible ( true );
     531            0 :       ( ContextMenu->actions() ).at ( 6 )->setVisible ( true );
     532              : 
     533            0 :       ContextMenu->exec ( ListWidget->mapToGlobal ( pos ) );
     534              :     }
     535              :   }
     536            0 : }
     537              : 
     538            0 : void relation::RemoveSlot()
     539              : {
     540            0 :   RemoveFromDataList();
     541            0 : }
     542              : 
     543            0 : void relation::MoveTopSlot()
     544              : {
     545            0 :   int ItemPosition = ListWidget->row ( CurrentItem );
     546            0 :   QString Item = this_data.at ( ItemPosition );
     547              : 
     548            0 :   this_data.removeAt ( ItemPosition );
     549            0 :   this_data.push_front ( Item );
     550              : 
     551            0 :   FirstItem = ListWidget->takeItem ( this_data.size() );
     552            0 :   ListWidget->clear();
     553            0 :   ListWidget->addItems ( this_data );
     554            0 :   ListWidget->addItem ( FirstItem );
     555              : 
     556            0 :   int index = this_data.indexOf ( Item );
     557            0 :   ListWidget->scrollTo ( ListWidget->model()->index ( index, 0 ) );
     558            0 :   ListWidget->setCurrentRow ( index );
     559              : 
     560            0 :   emit signal_internal_value_change();
     561            0 : }
     562              : 
     563            0 : void relation::MoveBottomSlot()
     564              : {
     565            0 :   int ItemPosition = ListWidget->row ( CurrentItem );
     566            0 :   QString Item = this_data.at ( ItemPosition );
     567              : 
     568            0 :   this_data.removeAt ( ItemPosition );
     569            0 :   this_data.push_back ( Item );
     570              : 
     571            0 :   FirstItem = ListWidget->takeItem ( this_data.size() );
     572            0 :   ListWidget->clear();
     573            0 :   ListWidget->addItems ( this_data );
     574            0 :   ListWidget->addItem ( FirstItem );
     575              : 
     576            0 :   int index = this_data.indexOf ( Item );
     577            0 :   ListWidget->scrollTo ( ListWidget->model()->index ( index, 0 ) );
     578            0 :   ListWidget->setCurrentRow ( index );
     579              : 
     580            0 :   emit signal_internal_value_change();
     581            0 : }
     582              : 
     583            0 : void relation::MoveUpSlot()
     584              : {
     585            0 :   int ItemPosition = ListWidget->row ( CurrentItem );
     586            0 :   QString Item = this_data.at ( ItemPosition );
     587              : 
     588            0 :   if ( ItemPosition != 0 )
     589              :   {
     590            0 :     this_data.swapItemsAt ( ItemPosition, ItemPosition - 1 );
     591              : 
     592            0 :     FirstItem = ListWidget->takeItem ( this_data.size() );
     593            0 :     ListWidget->clear();
     594            0 :     ListWidget->addItems ( this_data );
     595            0 :     ListWidget->addItem ( FirstItem );
     596              : 
     597            0 :     int index = this_data.indexOf ( Item );
     598            0 :     ListWidget->scrollTo ( ListWidget->model()->index ( index, 0 ) );
     599            0 :     ListWidget->setCurrentRow ( index );
     600              : 
     601            0 :     emit signal_internal_value_change();
     602              :   }
     603            0 : }
     604              : 
     605            0 : void relation::MoveDownSlot()
     606              : {
     607            0 :   int ItemPosition = ListWidget->row ( CurrentItem );
     608            0 :   QString Item = this_data.at ( ItemPosition );
     609              : 
     610            0 :   if ( ItemPosition != ( this_data.size() - 1 ) )
     611              :   {
     612            0 :     this_data.swapItemsAt ( ItemPosition, ItemPosition + 1 );
     613              : 
     614            0 :     FirstItem = ListWidget->takeItem ( this_data.size() );
     615            0 :     ListWidget->clear();
     616            0 :     ListWidget->addItems ( this_data );
     617            0 :     ListWidget->addItem ( FirstItem );
     618              : 
     619            0 :     int index = this_data.indexOf ( Item );
     620            0 :     ListWidget->scrollTo ( ListWidget->model()->index ( index, 0 ) );
     621            0 :     ListWidget->setCurrentRow ( index );
     622              : 
     623            0 :     emit signal_internal_value_change();
     624              :   }
     625            0 : }
     626              : 
     627            0 : void relation::EditSlot()
     628              : {
     629            0 :   if ( QComboBox * ComboBox = dynamic_cast<QComboBox *> ( ListWidget->itemWidget (
     630            0 :                                                             FirstItem ) )
     631              :      )
     632              :   {
     633            0 :     ComboBox->lineEdit()->setFocus();
     634              :   }
     635              : 
     636            0 :   t_virtue const & virt = p_base_data_editor->get();
     637            0 :   tref const & obj = inner::dbcontroller::get (
     638              :   {
     639            0 :     FirstItem->text().toStdString(), virt.p_type
     640              :   }
     641              : 
     642            0 :   );
     643            0 :   QString const & editorname = QString::fromStdString ( obj.full_name() );
     644              : 
     645            0 :   for ( QWidget * editor :
     646            0 :         QApplication::allWidgets()
     647              :       )
     648              :   {
     649            0 :     if ( ObjectEditor * w = dynamic_cast<ObjectEditor *> ( editor ) )
     650              :     {
     651            0 :       if ( ( w->objectName() ).compare ( editorname ) == 0 )
     652              :       {
     653            0 :         w->raise();
     654            0 :         w->setVisible ( true );
     655            0 :         return;
     656              :       }
     657              :     }
     658            0 :   }
     659              : 
     660            0 :   ( new ObjectEditor ( obj ) )->show();
     661            0 : }
     662              : 
     663            0 : void relation::DummyMovement()
     664              : {
     665            0 :   if ( this_is_owned )
     666              :   {
     667            0 :     emit signal_internal_value_change();
     668              :   }
     669            0 : }
     670              : 
     671            0 : void relation::EditItemEntered ( QListWidgetItem * Item )
     672              : {
     673            0 :   if ( Item != FirstItem )
     674              :   {
     675            0 :     return;
     676              :   }
     677              : 
     678            0 :   QStringList ListOfObjects;
     679              : 
     680            0 :   for ( int i = 0; i < ComboBox->count(); ++i )
     681              :   {
     682            0 :     ListOfObjects.append ( ComboBox->itemText ( i ) );
     683              :   }
     684              : 
     685            0 :   QComboBox * NewComboBox = new QComboBox ( this );
     686              : 
     687            0 :   NewComboBox->setLineEdit ( new QLineEdit() );
     688              : 
     689            0 :   NewComboBox->addItems ( ListOfObjects );
     690              : 
     691            0 :   QCompleter * Completer = new QCompleter ( ListOfObjects );
     692            0 :   Completer->setCaseSensitivity ( Qt::CaseInsensitive );
     693            0 :   Completer->setFilterMode(Qt::MatchContains);
     694              : 
     695            0 :   NewComboBox->lineEdit()->setCompleter ( Completer );
     696              : 
     697            0 :   NewComboBox->setEditable ( true );
     698              : 
     699            0 :   NewComboBox->setEditText ( Item->text() );
     700              : 
     701            0 :   if ( ListOfObjects.size() > 0 )
     702              :   {
     703            0 :     NewComboBox->lineEdit()->selectAll();
     704              :   }
     705              : 
     706              :   else
     707              :   {
     708            0 :     NewComboBox->setEnabled ( false );
     709              :   }
     710              : 
     711            0 :   QVariant VariantFromList ( ListOfObjects );
     712            0 :   ValidatorAcceptMatch * MyCustomValidator = new ValidatorAcceptMatch ( VariantFromList );
     713            0 :   NewComboBox->setValidator ( MyCustomValidator );
     714            0 :   NewComboBox->installEventFilter ( this );
     715              : 
     716            0 :   connect ( NewComboBox, SIGNAL ( activated ( const QString & ) ), this,
     717              :             SLOT ( AddToDataList ( const QString & ) ) );
     718              : 
     719            0 :   NewComboBox->lineEdit()->installEventFilter(this);
     720              : 
     721            0 :   ListWidget->setItemWidget ( FirstItem, NewComboBox );
     722            0 : }
     723              : 
     724            0 : void relation::EndSignal()
     725              : {
     726            0 :   if ( IsMultiValue and ListWidget->item ( 0 )->text() == "Type here"
     727            0 :        and not this_value_changed )
     728              :   {
     729              :     return;
     730              :   }
     731              : 
     732            0 :   if ( not this_data.isEmpty() )
     733              :   {
     734            0 :     this_data.clear();
     735              :   }
     736              : 
     737            0 :   for ( int i = 0; i != ListWidget->count(); ++i )
     738              :   {
     739            0 :     QListWidgetItem * Item = ListWidget->item ( i );
     740            0 :     QString const & val = Item->text();
     741              : 
     742            0 :     if ( val != "Type here" and val != "No Object" )
     743              :     {
     744            0 :       this_data.append ( val );
     745              :     }
     746            0 :   }
     747              : 
     748            0 :   if ( not this_is_owned )
     749              :   {
     750            0 :     p_base_data_editor->set_valid ( true );
     751            0 :     emit signal_edit_end();
     752              :   }
     753              :   else
     754              :   {
     755            0 :     emit signal_value_change(); /// This signal is caught by Object editor
     756              :   }
     757              : }
     758              : 
     759            0 : void relation::AddToDataList ( const QString & DataValue )
     760              : {
     761            0 :   if ( IsMultiValue )
     762              :   {
     763            0 :     this_data.append ( DataValue );
     764              :   }
     765              :   else
     766              :   {
     767            0 :     this_data = QStringList ( DataValue );
     768              :   }
     769              : 
     770            0 :   ListWidget->clear();
     771              : 
     772            0 :   if ( IsMultiValue )
     773              :   {
     774            0 :     ListWidget->addItems ( this_data );
     775              :   }
     776              : 
     777            0 :   int index = this_data.indexOf ( DataValue );
     778            0 :   ListWidget->scrollTo ( ListWidget->model()->index ( index, 0 ) );
     779            0 :   ListWidget->setCurrentRow ( index );
     780              : 
     781            0 :   if ( IsMultiValue )
     782              :   {
     783            0 :     FirstItem = new QListWidgetItem ( "Type here" );
     784              :   }
     785              :   else
     786              :   {
     787            0 :     FirstItem = new QListWidgetItem ( DataValue.toStdString().c_str() );
     788              :   }
     789              : 
     790            0 :   ListWidget->addItem ( FirstItem );
     791              : 
     792            0 :   if ( IsMultiValue )
     793              :   {
     794            0 :     FirstItem->setBackground ( Qt::GlobalColor::lightGray );
     795            0 :     FirstItem->setForeground ( QColor ( 0, 0, 0, 127 ) );
     796              :   }
     797              : 
     798            0 :   FirstItem->setSizeHint ( FirstItem->sizeHint() + QSize ( 0, 25 ) );
     799              : 
     800            0 :   if ( this_is_owned )
     801              :   {
     802            0 :     emit signal_internal_value_change();
     803              :   }
     804            0 : }
     805              : 
     806            0 : void relation::RemoveFromDataList()
     807              : {
     808            0 :   QList<QListWidgetItem *> items;
     809              : 
     810            0 :   if ( IsMultiValue )
     811              :   {
     812            0 :     items = ListWidget->selectedItems();
     813              :   }
     814              : 
     815              :   else
     816              :   {
     817            0 :     items.append ( FirstItem );
     818              :   }
     819              : 
     820            0 :   if ( items.size() > 0 )
     821              :   {
     822              : 
     823            0 :     for ( QListWidgetItem * item : items )
     824              :     {
     825            0 :       QString text = item->text();
     826              : 
     827            0 :       if ( text != "Type here" )
     828              :       {
     829            0 :         if ( IsMultiValue )
     830              :         {
     831            0 :           if ( QListWidgetItem * toremove = ListWidget->takeItem ( ListWidget->row ( item ) ) )
     832              :           {
     833            0 :             delete toremove;
     834              :           }
     835              :         }
     836              :         else
     837              :         {
     838              : 
     839            0 :           if ( QComboBox * editbox = dynamic_cast<QComboBox *> ( ListWidget->itemWidget (
     840            0 :                                                                    FirstItem ) )
     841              :              )
     842              :           {
     843            0 :             editbox->lineEdit()->clear();
     844            0 :             editbox->lineEdit()->clearFocus();
     845            0 :             FirstItem->setText ( "No Object" );
     846              :           }
     847              :         }
     848              : 
     849            0 :         this_data.removeOne ( text );
     850              :       }
     851            0 :     }
     852              : 
     853            0 :     emit signal_internal_value_change();
     854              :   }
     855            0 : }
     856              : 
     857            0 : void relation::UpdateActions()
     858              : {
     859            0 :   QStringList values;
     860              : 
     861            0 :   for ( int i = 0; i < ListWidget->count(); ++i )
     862              :   {
     863            0 :     QString const & value = ListWidget->item ( i )->text();
     864              : 
     865            0 :     if ( value != "No Object" and value != "Type here" )
     866              :     {
     867            0 :       values.append ( value );
     868              :     }
     869            0 :   }
     870              : 
     871            0 :   if ( p_base_data_editor->must_not_be_null() )
     872              :   {
     873            0 :     if ( values.size() > 0 )
     874              :     {
     875            0 :       p_base_data_editor->set_valid ( true );
     876            0 :       ListWidget->setPalette ( QApplication::palette ( this ) );
     877              :     }
     878              :     else
     879              :     {
     880            0 :       p_base_data_editor->set_valid ( false );
     881            0 :       ListWidget->setPalette ( StyleUtility::WarningStatusBarPallete );
     882              :     }
     883              :   }
     884              :   else
     885              :   {
     886            0 :     p_base_data_editor->set_valid ( true );
     887              :   }
     888              : 
     889            0 :   if ( values != CurrentDataList )
     890              :   {
     891            0 :     this_value_changed = true;
     892              :   }
     893              : 
     894            0 :   if ( this_is_owned )
     895              :   {
     896            0 :     EndSignal();
     897              :   }
     898            0 : }
     899              : 
     900            0 : void relation::closeEvent ( QCloseEvent * Event )
     901              : {
     902            0 :   Q_UNUSED ( Event )
     903            0 :   emit signal_force_close();
     904            0 : }
     905              : 
     906              : //------------------------------------------------------------------------------------------------
     907              : 
     908              : //------------------------------------------------------------------------------------------------
     909            0 : stringattr::stringattr ( t_virtue const & attr, QWidget * parent,
     910            0 :                          bool owned )
     911              :   :
     912            0 :   base ( std::make_shared<t_build_block_editor> ( attr ), parent, owned ),
     913            0 :   m_base_data_editor ( std::static_pointer_cast<t_build_block_editor> ( p_data_editor ) ),
     914            0 :   DefaultValue ( "" ),
     915            0 :   PopUpButton ( nullptr ),
     916            0 :   Dialog ( nullptr ),
     917            0 :   OkButtonDialog ( nullptr ),
     918            0 :   TextEditDialog ( nullptr )
     919              : {
     920            0 :   setupUi ( this );
     921            0 :   t_virtue const & virtue = m_base_data_editor->get();
     922              : 
     923            0 :  StringLineEdit->installEventFilter(this);
     924            0 :  StringLineEdit->setTabChangesFocus(true);
     925              : 
     926            0 :   setWindowTitle ( QString ( "Edit Attr : %1" ).arg ( virtue.p_name.c_str() ) );
     927            0 :   AttributeNameLabel->setText ( QString ( virtue.p_name.c_str() ) + " : " );
     928              :   /// LAYOUT CHANGE
     929            0 :   AttributeNameLabel->setHidden ( true );
     930              : 
     931            0 :   UpdateActions (  );
     932              : 
     933            0 :   if ( m_base_data_editor->must_not_be_null() )
     934              :   {
     935            0 :     m_base_data_editor->set_valid ( true );
     936            0 :     StringLineEdit->setPalette ( StyleUtility::WarningStatusBarPallete );
     937            0 :     OkButton->setDisabled ( true );
     938            0 :     SetNullCheck ( true );
     939              :   }
     940              :   else
     941              :   {
     942            0 :     SetNullCheck ( false );
     943              :   }
     944              : 
     945            0 :   if ( virtue.p_is_multi_value )
     946              :   {
     947            0 :     StringLineEdit->setPalette ( QApplication::palette ( this ) );
     948              :   }
     949              : 
     950            0 :   OkButton->setHidden ( true );
     951              : 
     952            0 :   if ( this_is_owned )
     953              :   {
     954            0 :     connect ( StringLineEdit, SIGNAL ( StringValidated() ), this, SLOT ( AddToDataList() ),
     955              :               Qt::UniqueConnection );
     956            0 :     OkButton->setHidden ( true );
     957              :   }
     958              : 
     959            0 :   SetController();
     960              : 
     961            0 :   buildtooltip();
     962            0 :   UpdateActions (  );
     963              : 
     964            0 :   AttributeNameLabel->setFocus();
     965            0 : }
     966              : 
     967            0 : stringattr::~stringattr()
     968              : {
     969            0 :   delete Dialog;
     970            0 :   delete PopUpButton;
     971            0 : }
     972              : 
     973            0 : void stringattr::SetEditor()
     974              : {
     975            0 :   if ( this_data.isEmpty() )
     976              :   {
     977              :     return;
     978              :   }
     979              : 
     980            0 :   StringLineEdit->setText ( this_data.value ( 0 ) );
     981              : 
     982            0 :   slot_set_initial_loaded();
     983              : }
     984              : 
     985            0 : QTextEdit * stringattr::GetLineEdit() const
     986              : {
     987            0 :   return StringLineEdit;
     988              : }
     989              : 
     990            0 : void stringattr::SetNullCheck ( bool Check )
     991              : {
     992            0 :   StringLineEdit->SetNullCheck ( Check );
     993            0 : }
     994              : 
     995            0 : void stringattr::SetMultiCheck ( bool Multi )
     996              : {
     997            0 :   StringLineEdit->SetMultiCheck ( Multi );
     998            0 : }
     999              : 
    1000            0 : void stringattr::SetCheckDefaults ( bool Default )
    1001              : {
    1002            0 :   StringLineEdit->SetCheckDefault ( Default );
    1003            0 : }
    1004              : 
    1005            0 : void stringattr::SetFocusOnLine()
    1006              : {
    1007            0 :   StringLineEdit->selectAll();
    1008            0 : }
    1009              : 
    1010            0 : bool stringattr::eventFilter(QObject * target, QEvent * evt)
    1011              : {
    1012            0 :         if (target == StringLineEdit)
    1013              :         {
    1014            0 :                 if (evt->type() == QEvent::FocusIn)
    1015              :                 {
    1016            0 :                         ShowPopupButton();
    1017              :                 }
    1018            0 :                 else if (evt->type() == QEvent::KeyPress)
    1019              :                 {
    1020            0 :                         QKeyEvent *kevt = static_cast<QKeyEvent*>(evt);
    1021            0 :                         switch (kevt->key())
    1022              :                         {
    1023            0 :                                 case Qt::Key_Enter:
    1024            0 :                                 case Qt::Key_Return:
    1025              : 
    1026            0 :                         if ( kevt->modifiers() == Qt::AltModifier)
    1027              :                         {
    1028            0 :                                 kevt->setModifiers(Qt::NoModifier);
    1029            0 :                                 return false;
    1030              :                         }else
    1031              :                         {
    1032            0 :                                 StringLineEdit->parentWidget()->setFocus(Qt::FocusReason::TabFocusReason);
    1033            0 :                                 emit signal_data_input_complete();
    1034            0 :                                 return true;
    1035              :                         }
    1036              : 
    1037              :                                         break;
    1038              :                                 default:
    1039              :                                         break;
    1040              :                         }
    1041              :                 }
    1042              :         }
    1043              :   return false;
    1044              : }
    1045              : 
    1046            0 : void stringattr::ClearText()
    1047              : {
    1048            0 :   GetLineEdit()->clear();
    1049            0 : }
    1050              : 
    1051            0 : void stringattr::buildtooltip()
    1052              : {
    1053            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    1054              : 
    1055            0 :   setToolTip (
    1056            0 :     QString ( "Attribute Name:           %1 \n" ).arg ( Virtue.p_name.c_str() ) + QString (
    1057            0 :       "          Type:           %1 \n" ).arg (
    1058            0 :       dunedaq::conffwk::attribute_t::type2str ( Virtue.p_type ) )
    1059            0 :     + QString ( "          Range:          %1 \n" ).arg ( Virtue.p_range.c_str() )
    1060            0 :     + QString ( "          Format:         %1 \n" ).arg (
    1061            0 :       dunedaq::conffwk::attribute_t::format2str ( Virtue.p_int_format ) )
    1062            0 :     + QString ( "          Not Null:       %1 \n" ).arg ( Virtue.p_is_not_null )
    1063            0 :     + QString ( "          Is Multi Value: %1 \n" ).arg ( Virtue.p_is_multi_value )
    1064            0 :     + QString ( "          Default Value:  %1 \n" ).arg ( Virtue.p_default_value.c_str() )
    1065            0 :     + QString ( "          Description:    %1 \n" ).arg ( Virtue.p_description.c_str() ) );
    1066            0 : }
    1067              : 
    1068            0 : void stringattr::closeEvent ( QCloseEvent * Event )
    1069              : {
    1070            0 :   Q_UNUSED ( Event )
    1071            0 :   emit signal_force_close();
    1072            0 : }
    1073              : 
    1074            0 : void stringattr::SetController()
    1075              : {
    1076            0 :   connect ( StringLineEdit, SIGNAL ( textChanged (  ) ), this, SLOT ( UpdateActions (  ) ), Qt::UniqueConnection );
    1077            0 :   connect ( this, SIGNAL ( signal_data_input_complete() ), this, SLOT ( AddToDataList() ) );
    1078            0 :   connect ( OkButton, SIGNAL ( clicked() ), this, SLOT ( AddToDataList() ), Qt::UniqueConnection );
    1079            0 : }
    1080              : 
    1081            0 : void stringattr::setdefaults ( const QString & ValueDefault )
    1082              : {
    1083            0 :   this_defaults = ValueDefault;
    1084            0 :   StringLineEdit->SetDefaultValue ( ValueDefault );
    1085            0 : }
    1086              : 
    1087            0 : void stringattr::ShowPopupButton()
    1088              : {
    1089            0 :   if ( PopUpButton == nullptr )
    1090              :   {
    1091            0 :     PopUpButton = new QPushButton ( "..." );
    1092            0 :     PopUpButton->setMaximumWidth (
    1093            0 :       PopUpButton->fontMetrics().boundingRect ( "..." ).width() + 15 );
    1094            0 :     connect ( PopUpButton, SIGNAL ( clicked() ), this, SLOT ( ShowDialog() ),
    1095              :               Qt::UniqueConnection );
    1096            0 :     horizontalLayout->addWidget ( PopUpButton );
    1097              :   }
    1098              : 
    1099            0 :   PopUpButton->show();
    1100            0 : }
    1101              : 
    1102            0 : void stringattr::HidePopupButton()
    1103              : {
    1104            0 :   if ( PopUpButton != nullptr )
    1105              :   {
    1106            0 :     PopUpButton->hide();
    1107              :   }
    1108            0 : }
    1109              : 
    1110            0 : void stringattr::UpdateActions ( )
    1111              : {
    1112            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    1113              : 
    1114            0 :   if ( Virtue.p_is_not_null && ( this_data.size() == 0 ) )
    1115              :   {
    1116            0 :     OkButton->setEnabled ( true );
    1117            0 :     m_base_data_editor->set_valid ( false );
    1118              :   }
    1119              : 
    1120              :   else
    1121              :   {
    1122            0 :     OkButton->setEnabled ( true );
    1123            0 :     m_base_data_editor->set_valid ( true );
    1124              :   }
    1125            0 : }
    1126              : 
    1127            0 : void stringattr::AddToDataList()
    1128              : {
    1129            0 :   QString NewValue = StringLineEdit->toPlainText();
    1130              : 
    1131            0 :   if ( !this_data.contains ( NewValue ) )
    1132              :   {
    1133            0 :     StringLineEdit->setToolTip ( QString ( "The set value is : %1" ).arg ( NewValue ) );
    1134            0 :     this_data.clear();
    1135            0 :     this_data.append ( NewValue );
    1136              : 
    1137            0 :     UpdateActions ( );
    1138            0 :     this_value_changed = true;
    1139              : 
    1140            0 :     if ( !this_is_owned )
    1141              :     {
    1142            0 :       emit signal_value_change();
    1143            0 :       emit signal_edit_end();
    1144              :     }
    1145              :     else
    1146              :     {
    1147            0 :       emit signal_value_change();
    1148              :     }
    1149              :   }
    1150            0 : }
    1151              : 
    1152            0 : void stringattr::ShowDialog()
    1153              : {
    1154              : 
    1155            0 :   if ( Dialog == nullptr )
    1156              :   {
    1157            0 :     QVBoxLayout * Layout = new QVBoxLayout();
    1158            0 :     Dialog = new QDialog();
    1159            0 :     t_virtue const & Virtue = m_base_data_editor->get();
    1160            0 :     Dialog->setWindowTitle ( QString ( "Edit Attr : %1" ).arg ( Virtue.p_name.c_str() ) );
    1161            0 :     TextEditDialog = new QPlainTextEdit ( Dialog );
    1162            0 :     OkButtonDialog = new QPushButton ( "OK", Dialog );
    1163            0 :     Layout->addWidget ( TextEditDialog );
    1164            0 :     Layout->addWidget ( OkButtonDialog );
    1165            0 :     Dialog->setLayout ( Layout );
    1166            0 :     Dialog->setModal ( true );
    1167              : 
    1168            0 :     connect ( TextEditDialog, SIGNAL ( textChanged() ), this, SLOT ( ToogleTextEditOkButton() ),
    1169              :               Qt::UniqueConnection );
    1170            0 :     connect ( OkButtonDialog, SIGNAL ( clicked() ), this, SLOT ( UpdateFromTextEdit() ),
    1171              :               Qt::UniqueConnection );
    1172              :   }
    1173              : 
    1174            0 :   TextEditDialog->clear();
    1175            0 :   TextEditDialog->insertPlainText ( StringLineEdit->toPlainText() );
    1176            0 :   Dialog->show();
    1177            0 : }
    1178              : 
    1179            0 : void stringattr::UpdateFromTextEdit()
    1180              : {
    1181            0 :   StringLineEdit->clear();
    1182            0 :   StringLineEdit->setText ( TextEditDialog->toPlainText() );
    1183            0 :   AddToDataList();
    1184            0 :   Dialog->close();
    1185            0 : }
    1186              : 
    1187            0 : void stringattr::ToogleTextEditOkButton()
    1188              : {
    1189            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    1190              : 
    1191            0 :   if ( TextEditDialog->toPlainText().isEmpty() && Virtue.p_is_not_null )
    1192            0 :     OkButtonDialog
    1193            0 :     ->setEnabled (
    1194              :       false );
    1195              :   else
    1196              :   {
    1197            0 :     OkButtonDialog->setEnabled ( true );
    1198              :   }
    1199            0 : }
    1200              : 
    1201              : //------------------------------------------------------------------------------------------------
    1202              : 
    1203              : //------------------------------------------------------------------------------------------------
    1204            0 : numericattr::numericattr ( t_virtue const & attr, QWidget * parent,
    1205            0 :                            bool owned )
    1206              :   :
    1207            0 :   base ( std::make_shared<t_build_block_editor> ( attr ), parent, owned ),
    1208            0 :   this_base_data_editor ( std::static_pointer_cast<t_build_block_editor> ( p_data_editor ) ),
    1209            0 :   this_native_base ( -1 )
    1210              : {
    1211            0 :   setupUi ( this );
    1212            0 :   t_virtue const & Virtue = this_base_data_editor->get();
    1213              : 
    1214            0 :   setWindowTitle ( QString ( "Edit Attribute: %1" ).arg ( Virtue.p_name.c_str() ) );
    1215            0 :   LineEdit->SetPopupMenu();
    1216              : 
    1217            0 :   if ( Virtue.p_is_not_null )
    1218              :   {
    1219            0 :     this_base_data_editor->set_valid ( false );
    1220            0 :     LineEdit->setPalette ( StyleUtility::WarningStatusBarPallete );
    1221              :   }
    1222              :   else
    1223              :   {
    1224            0 :     LineEdit->SetNullCheck ( false );
    1225              :   }
    1226              : 
    1227            0 :   if ( ! ( Virtue.p_type == dunedaq::conffwk::float_type
    1228              :            || Virtue.p_type == dunedaq::conffwk::double_type ) )
    1229              :   {
    1230            0 :     if ( Virtue.p_int_format == dunedaq::conffwk::oct_int_format )
    1231              :     {
    1232            0 :       FormatBox->setCurrentIndex ( 2 );
    1233            0 :       this_base = 8;
    1234            0 :       this_native_base = 8;
    1235              :     }
    1236            0 :     else if ( Virtue.p_int_format == dunedaq::conffwk::dec_int_format )
    1237              :     {
    1238            0 :       FormatBox->setCurrentIndex ( 0 );
    1239            0 :       this_base = 10;
    1240            0 :       this_native_base = 10;
    1241              :     }
    1242            0 :     else if ( Virtue.p_int_format == dunedaq::conffwk::hex_int_format )
    1243              :     {
    1244            0 :       FormatBox->setCurrentIndex ( 1 );
    1245            0 :       this_base = 16;
    1246            0 :       this_native_base = 16;
    1247              :     }
    1248              : 
    1249            0 :     FormatBox->hide();
    1250              :   }
    1251              :   else
    1252              :   {
    1253            0 :     FormatBox->hide();
    1254              :   }
    1255              : 
    1256            0 :   SetController();
    1257              : 
    1258            0 :   AttributeName->setText ( QString ( Virtue.p_name.c_str() ) + " : " );
    1259            0 :   AttributeName->setHidden ( true );
    1260            0 :   buildtooltip();
    1261              : 
    1262            0 :   QString Dummy ( "Dummy" );
    1263            0 :   UpdateActions ( Dummy );
    1264            0 : }
    1265              : 
    1266            0 : void numericattr::setdefaults ( const QString & ValueDefault )
    1267              : {
    1268            0 :   this_defaults = ValueDefault;
    1269            0 :   LineEdit->SetDefaultValue ( this_defaults );
    1270            0 : }
    1271              : 
    1272            0 : QLineEdit * numericattr::GetLineEdit() const
    1273              : {
    1274            0 :   return LineEdit;
    1275              : }
    1276              : 
    1277            0 : void numericattr::SetEditor()
    1278              : {
    1279            0 :   if ( this_data.isEmpty() )
    1280              :   {
    1281              :     return;
    1282              :   }
    1283              : 
    1284            0 :   LineEdit->clear();
    1285              : 
    1286              :   /// change here
    1287            0 :   if ( this_base == 16 )
    1288              :   {
    1289            0 :     if ( not this_data.value ( 0 ).startsWith ( "0x" ) )
    1290              :     {
    1291            0 :       LineEdit->setText ( "0x" + this_data.value ( 0 ) );
    1292              :     }
    1293              :     else
    1294              :     {
    1295            0 :       LineEdit->setText ( this_data.value ( 0 ) );
    1296              :     }
    1297              :   }
    1298            0 :   else if ( this_base == 8 )
    1299              :   {
    1300            0 :     if ( not this_data.value ( 0 ).startsWith ( "0" ) and this_data.value ( 0 ) != 0 )
    1301              :     {
    1302            0 :       LineEdit->setText ( "0" + this_data.value ( 0 ) );
    1303              :     }
    1304              :     else
    1305              :     {
    1306            0 :       LineEdit->setText ( this_data.value ( 0 ) );
    1307              :     }
    1308              :   }
    1309              :   else
    1310              :   {
    1311            0 :     LineEdit->setText ( this_data.value ( 0 ) );
    1312              :   }
    1313              : }
    1314              : 
    1315            0 : void numericattr::buildtooltip()
    1316              : {
    1317            0 :   t_virtue const & Virtue = this_base_data_editor->get();
    1318              : 
    1319            0 :   setToolTip (
    1320            0 :     QString ( "Attribute Name:           %1 \n" ).arg ( Virtue.p_name.c_str() ) + QString (
    1321            0 :       "          Type:           %1 \n" ).arg (
    1322            0 :       dunedaq::conffwk::attribute_t::type2str ( Virtue.p_type ) )
    1323            0 :     + QString ( "          Range:          %1 \n" ).arg ( Virtue.p_range.c_str() )
    1324            0 :     + QString ( "          Format:         %1 \n" ).arg (
    1325            0 :       dunedaq::conffwk::attribute_t::format2str ( Virtue.p_int_format ) )
    1326            0 :     + QString ( "          Not Null:       %1 \n" ).arg ( Virtue.p_is_not_null )
    1327            0 :     + QString ( "          Is Multi Value: %1 \n" ).arg ( Virtue.p_is_multi_value )
    1328            0 :     + QString ( "          Default Value:  %1 \n" ).arg ( Virtue.p_default_value.c_str() )
    1329            0 :     + QString ( "          Description:    %1 \n" ).arg ( Virtue.p_description.c_str() ) );
    1330            0 : }
    1331              : 
    1332            0 : void numericattr::closeEvent ( QCloseEvent * Event )
    1333              : {
    1334            0 :   Q_UNUSED ( Event )
    1335            0 :   emit signal_force_close();
    1336            0 : }
    1337              : 
    1338            0 : void numericattr::SetController()
    1339              : {
    1340            0 :   connect ( LineEdit, SIGNAL ( DecChange() ), this, SLOT ( ChangeFormatDec() ) );
    1341            0 :   connect ( LineEdit, SIGNAL ( OctChange() ), this, SLOT ( ChangeFormatOct() ) );
    1342            0 :   connect ( LineEdit, SIGNAL ( HexChange() ), this, SLOT ( ChangeFormatHex() ) );
    1343              : 
    1344            0 :   connect ( FormatBox, SIGNAL ( currentIndexChanged ( int ) ),
    1345              :             this, SLOT ( ChangeFormat ( int ) ), Qt::UniqueConnection );
    1346              : 
    1347            0 :   connect ( LineEdit, SIGNAL ( editingFinished() ),
    1348              :             this, SLOT ( AddToList() ), Qt::UniqueConnection );
    1349            0 :   connect ( LineEdit, SIGNAL ( textChanged ( QString ) ),
    1350              :             this, SLOT ( UpdateActions ( QString ) ), Qt::UniqueConnection );
    1351            0 :   connect ( LineEdit, SIGNAL ( returnPressed () ),
    1352              :             this, SLOT ( checkIfDuplicated () ), Qt::UniqueConnection );
    1353              : 
    1354            0 : }
    1355              : 
    1356            0 : void numericattr::ShowWarning ( QString Format, QString Range )
    1357              : {
    1358            0 :   LineEdit->setPalette ( StyleUtility::AlertStatusBarPallete );
    1359              : 
    1360            0 :   t_virtue const & Virtue = this_base_data_editor->get();
    1361              : 
    1362            0 :   QString Message = QString ( "The value for attribute %1 is in the wrong format" ).arg (
    1363            0 :                       Virtue.p_name.c_str() );
    1364              : 
    1365            0 :   if ( Range != "" )
    1366              :   {
    1367            0 :     QString RangeMex = QString ( " - The value should be in the range : %1" ).arg ( Range );
    1368            0 :     Message.append ( "\n\n" + RangeMex );
    1369            0 :   }
    1370              : 
    1371            0 :   if ( Format != "" )
    1372              :   {
    1373            0 :     Message.append ( QString ( "\n\n - The value should be formatted as a %1." ).arg (
    1374              :                        Format ) );
    1375              :   }
    1376              : 
    1377            0 :   QMessageBox::warning ( this, tr ( "Wrong value" ), Message );
    1378            0 :   return;
    1379            0 : }
    1380              : 
    1381            0 : bool numericattr::ValidateIntegerValue ( QString const & text )
    1382              : {
    1383            0 :   auto checkInteger = [this, text]()
    1384              :   {
    1385            0 :       t_virtue const & input = this_base_data_editor->get();
    1386              : 
    1387            0 :       bool convert_to_defined_base;
    1388              : 
    1389            0 :       qlonglong NewLongLong{0};
    1390            0 :       qulonglong NewULongLong{0};
    1391              : 
    1392            0 :       auto check_convert = [this, &convert_to_defined_base]()
    1393              :       {
    1394              :         // If input cannot be converted to any base then show a warning and invalidate
    1395              : 
    1396            0 :         if ( not convert_to_defined_base )
    1397              :         {
    1398            0 :           if ( this_native_base == 10 )
    1399              :           {
    1400            0 :             ShowWarning ( "DECIMAL" );
    1401              :           }
    1402            0 :           else if ( this_native_base == 16 )
    1403              :           {
    1404            0 :             ShowWarning ( "HEX-DECIMAL" );
    1405              :           }
    1406            0 :           else if ( this_native_base == 8 )
    1407              :           {
    1408            0 :             ShowWarning ( "OCT-DECIMAL" );
    1409              :           }
    1410              : 
    1411            0 :           return false;
    1412              :         }
    1413              : 
    1414              :         return true;
    1415            0 :       };
    1416              : 
    1417            0 :       if ( input.p_type == dunedaq::conffwk::u8_type
    1418            0 :            or input.p_type == dunedaq::conffwk::u16_type
    1419              :            or input.p_type == dunedaq::conffwk::u32_type
    1420              :            or input.p_type == dunedaq::conffwk::u64_type )
    1421              :       {
    1422            0 :         NewULongLong = text.toULongLong ( &convert_to_defined_base, this_base );
    1423              : 
    1424            0 :         if ( not check_convert() )
    1425              :         {
    1426              :           return false;
    1427              :         }
    1428              : 
    1429            0 :         qulonglong min_u;
    1430            0 :         qulonglong max_u;
    1431              : 
    1432            0 :         if ( input.p_type == dunedaq::conffwk::u8_type )
    1433              :         {
    1434              :           min_u = 0;
    1435              :           max_u = UCHAR_MAX;
    1436              :         }
    1437            0 :         else if ( input.p_type == dunedaq::conffwk::u16_type )
    1438              :         {
    1439              :           min_u = 0;
    1440              :           max_u = USHRT_MAX;
    1441              :         }
    1442              :         else if ( input.p_type == dunedaq::conffwk::u32_type )
    1443              :         {
    1444              :           min_u = 0;
    1445              :           max_u = ULONG_MAX;
    1446              :         }
    1447              :         else if ( input.p_type == dunedaq::conffwk::u64_type )
    1448              :         {
    1449              :           min_u = 0;
    1450              :           max_u = ULONG_LONG_MAX;
    1451              :         }
    1452              :         else
    1453              :         {
    1454              :           return true;
    1455              :         }
    1456              : 
    1457            0 :         if ( min_u <= NewULongLong and NewULongLong <= max_u )
    1458              :         {
    1459              :           return true;
    1460              :         }
    1461              : 
    1462            0 :         ShowWarning ( "", QString ( "[%1 - %2]" ).arg ( min_u ).arg ( max_u ) );
    1463            0 :       }
    1464              :       else
    1465              :       {
    1466            0 :         NewLongLong = text.toLongLong ( &convert_to_defined_base, this_base );
    1467              : 
    1468            0 :         if ( not check_convert() )
    1469              :         {
    1470              :           return false;
    1471              :         }
    1472              : 
    1473            0 :         qlonglong min_s;
    1474            0 :         qlonglong max_s;
    1475              : 
    1476            0 :         if ( input.p_type == dunedaq::conffwk::s8_type )
    1477              :         {
    1478              :           min_s = SCHAR_MIN;
    1479              :           max_s = SCHAR_MAX;
    1480              :         }
    1481              :         else if ( input.p_type == dunedaq::conffwk::s16_type )
    1482              :         {
    1483              :           min_s = SHRT_MIN;
    1484              :           max_s = SHRT_MAX;
    1485              :         }
    1486              :         else if ( input.p_type == dunedaq::conffwk::s32_type )
    1487              :         {
    1488              :           min_s = LONG_MIN;
    1489              :           max_s = LONG_MAX;
    1490              :         }
    1491              :         else if ( input.p_type == dunedaq::conffwk::s64_type )
    1492              :         {
    1493              :           min_s = - ( LONG_LONG_MAX ) - 1;
    1494              :           max_s = LONG_LONG_MAX;
    1495              :         }
    1496              :         else
    1497              :         {
    1498              :           return true;
    1499              :         }
    1500              : 
    1501            0 :         if ( min_s <= NewLongLong and NewLongLong <= max_s )
    1502              :         {
    1503              :           return true;
    1504              :         }
    1505              : 
    1506            0 :         ShowWarning ( "", QString ( "[%1 - %2]" ).arg ( min_s ).arg ( max_s ) );
    1507              :       }
    1508              : 
    1509              :       return false;
    1510            0 :   };
    1511              : 
    1512            0 :   return (checkInteger() && checkRange(text));
    1513            0 : }
    1514              : 
    1515            0 : bool numericattr::checkRange (QString const & Value)
    1516              : {
    1517            0 :     t_virtue const & Virtue = this_base_data_editor->get();
    1518              : 
    1519            0 :     QString Range = QString::fromStdString ( Virtue.p_range );
    1520              : 
    1521            0 :     if ( Range.isEmpty() )
    1522              :     {
    1523              :       return true;
    1524              :     }
    1525              : 
    1526            0 :     QStringList ValueList = Range.split ( "," );
    1527              : 
    1528            0 :     QList<QPair<QString, QString>> RangeList;
    1529              : 
    1530            0 :     for ( QString & RangeValue : ValueList )
    1531              :     {
    1532            0 :       if ( RangeValue.contains ( ".." ) )
    1533              :       {
    1534            0 :         QStringList Ranges = RangeValue.split ( ".." );
    1535            0 :         RangeList.append ( QPair<QString, QString> ( Ranges.at ( 0 ), Ranges.at ( 1 ) ) );
    1536            0 :         ValueList.removeOne ( RangeValue );
    1537            0 :       }
    1538              :     }
    1539              : 
    1540            0 :     if ( ValueList.contains ( Value ) )
    1541              :     {
    1542              :       return true;
    1543              :     }
    1544              : 
    1545            0 :     for ( QPair<QString, QString> & ValuePair : RangeList )
    1546              :     {
    1547            0 :       if ( ValuePair.first == "*" )
    1548              :       {
    1549            0 :         if ( Value.toDouble() <= ValuePair.second.toDouble() )
    1550              :         {
    1551            0 :           return true;
    1552              :         }
    1553              : 
    1554            0 :         ShowWarning("", Range);
    1555              : 
    1556            0 :         return false;
    1557              :       }
    1558              : 
    1559            0 :       else if ( ValuePair.second == "*" )
    1560              :       {
    1561            0 :         if ( Value.toDouble() >= ValuePair.first.toDouble() )
    1562              :         {
    1563              :           return true;
    1564              :         }
    1565              : 
    1566            0 :         ShowWarning("", Range);
    1567              : 
    1568            0 :         return false;
    1569              :       }
    1570              : 
    1571              :       else
    1572              :       {
    1573            0 :         if ( ( Value.toDouble() >= ValuePair.first.toDouble() ) &&
    1574            0 :              ( Value.toDouble() <= ValuePair.second.toDouble() ) )
    1575              :         {
    1576              :           return true;
    1577              :         }
    1578              : 
    1579            0 :         ShowWarning("", Range);
    1580              : 
    1581            0 :         return false;
    1582              :       }
    1583              :     }
    1584              : 
    1585            0 :     ShowWarning("", Range);
    1586              : 
    1587            0 :     return false;
    1588            0 : }
    1589              : 
    1590            0 : bool numericattr::ValidateFloatValue ( QString const & Value )
    1591              : {
    1592            0 :   bool validValue = true;
    1593              : 
    1594            0 :   t_virtue const & Virtue = this_base_data_editor->get();
    1595              : 
    1596            0 :   if(Virtue.p_type == dunedaq::conffwk::float_type) {
    1597            0 :       bool ok;
    1598            0 :       Value.toFloat(&ok);
    1599              : 
    1600            0 :       if(ok == false) {
    1601            0 :           ShowWarning("FLOAT");
    1602            0 :           validValue = false;
    1603              :       }
    1604              :   } else {
    1605            0 :       bool ok;
    1606            0 :       Value.toDouble(&ok);
    1607              : 
    1608            0 :       if(ok == false) {
    1609            0 :           ShowWarning("DOUBLE");
    1610            0 :           validValue = false;
    1611              :       }
    1612              :   }
    1613              : 
    1614            0 :   return (validValue && checkRange(Value));
    1615              : }
    1616              : 
    1617            0 : void numericattr::checkIfDuplicated() {
    1618              :     // Emit a special signal when the Enter/Return key is pressed
    1619              :     // and the data have not been changed
    1620              :     // That is useful, for instance, for the multi-attribute
    1621              :     // widget in order to add multiple times the same attribute
    1622              :     // (you do not want to add the same value multiple times just
    1623              :     // when the focus is lost)
    1624            0 :     if ( this_data.contains(LineEdit->text()) ) {
    1625            0 :         emit signal_value_duplicated();
    1626              :     }
    1627            0 : }
    1628              : 
    1629            0 : void numericattr::AddToList()
    1630              : {
    1631              :   // No change in data, do nothing
    1632              :   // It avoids some unwanted loops when focus is acquired/lost
    1633            0 :   if ( this_data.contains(LineEdit->text()) ) {
    1634            0 :       return;
    1635              :   }
    1636              : 
    1637            0 :   auto convert_to_proper_base = [this] (const QString& value) -> QString {
    1638            0 :       if((value.isEmpty() == false) && (this_native_base != -1) && (this_native_base != this_base)) {
    1639            0 :           QString cnvrtd;
    1640              : 
    1641            0 :           t_virtue const & virtue = this_base_data_editor->get();
    1642            0 :           bool Unsigned = ( virtue.p_type == dunedaq::conffwk::u8_type
    1643            0 :                               || virtue.p_type == dunedaq::conffwk::u16_type
    1644              :                               || virtue.p_type == dunedaq::conffwk::u32_type
    1645              :                               || virtue.p_type == dunedaq::conffwk::u64_type );
    1646              : 
    1647            0 :           if(Unsigned == true) {
    1648            0 :               cnvrtd.setNum(LineEdit->text().toULongLong(0, this_base), this_native_base);
    1649              :           } else {
    1650            0 :               cnvrtd.setNum(LineEdit->text().toLongLong(0, this_base), this_native_base);
    1651              :           }
    1652              : 
    1653              :           // Be careful to set the contextaul menu properly
    1654            0 :           if(this_native_base == 8) {
    1655            0 :               if(cnvrtd.startsWith("0") == false) {
    1656            0 :                   cnvrtd.insert(0, "0");
    1657              :               }
    1658            0 :               LineEdit->EmitOctSlot();
    1659            0 :           } else if(this_native_base == 10) {
    1660            0 :               LineEdit->EmitDecSlot();
    1661            0 :           } else if(this_native_base == 16) {
    1662            0 :               if(cnvrtd.startsWith("0x", Qt::CaseInsensitive) == false) {
    1663            0 :                   cnvrtd.insert(0, "0x");
    1664              :               }
    1665            0 :               LineEdit->EmitHexSlot();
    1666              :           }
    1667              : 
    1668              :           // The current and native bases are now the same
    1669            0 :           this_base = this_native_base;
    1670              : 
    1671            0 :           return cnvrtd;
    1672            0 :       }
    1673              : 
    1674            0 :       return value;
    1675            0 :   };
    1676              : 
    1677            0 :   LineEdit->blockSignals ( true );
    1678              : 
    1679            0 :   BOOST_SCOPE_EXIT(this_)
    1680              :   {
    1681            0 :       this_->LineEdit->blockSignals ( false );
    1682            0 :   }
    1683            0 :   BOOST_SCOPE_EXIT_END
    1684              : 
    1685            0 :   bool isValid = true;
    1686              : 
    1687            0 :   QString input = LineEdit->text();
    1688              : 
    1689            0 :   t_virtue const & virtue = this_base_data_editor->get();
    1690            0 :   if ( ( virtue.p_type == dunedaq::conffwk::float_type
    1691            0 :            or virtue.p_type == dunedaq::conffwk::double_type ))
    1692              :   {
    1693            0 :       if (not ValidateFloatValue ( input )) {
    1694            0 :           isValid = false;
    1695              :       }
    1696            0 :   } else if ( not ValidateIntegerValue ( input ) )
    1697              :   {
    1698            0 :     isValid = false;
    1699              :   }
    1700              : 
    1701              :   //    ShowWarning("FLOAT", QString::fromStdString(virtue.p_name));
    1702              : 
    1703            0 :   this_data.clear();
    1704              : 
    1705              :   // We better save data in the proper format, in order to avoid issues
    1706              :   // with conversions (and having data saved in a bad format)
    1707            0 :   this_data.append ( convert_to_proper_base(input) );
    1708              : 
    1709            0 :   this_value_changed = true;
    1710              : 
    1711            0 :   if(isValid == true) {
    1712            0 :       QString Dummy ( "Dummy" );
    1713            0 :       UpdateActions ( Dummy );
    1714            0 :   } else {
    1715            0 :       this_base_data_editor->set_valid ( false );
    1716              :   }
    1717              : 
    1718            0 :   if ( not this_is_owned )
    1719              :   {
    1720              :     // Not owned: multiattr (connected to signal_value_change) and
    1721              :     //            CustomDelegate (connected to signal_edit_end and signal_force_close)
    1722            0 :     if(isValid == true) {
    1723              :         // Do not emit the signal in this case
    1724              :         // The table will try t write data and get back an exception
    1725            0 :         emit signal_edit_end();
    1726              :     }
    1727              : 
    1728            0 :     emit signal_value_change();
    1729              :   }
    1730              :   else
    1731              :   {
    1732              :     // Owned: ObjectEditor (connected to signal_value_change)
    1733            0 :     emit signal_value_change();
    1734              :   }
    1735            0 : }
    1736              : 
    1737            0 : void numericattr::ChangeFormat ( int i )
    1738              : {
    1739            0 :   QString CurrentString = LineEdit->text();
    1740              : 
    1741            0 :   if ( CurrentString.isEmpty() )
    1742              :   {
    1743              :     //if(DecButton->isChecked())
    1744              : 
    1745            0 :     if ( i == 0 )
    1746              :     {
    1747            0 :       this_base = 10;
    1748              :     }
    1749              : 
    1750              :     //else if(OctButton->isChecked())
    1751            0 :     else if ( i == 2 )
    1752              :     {
    1753            0 :       this_base = 8;
    1754              :     }
    1755              : 
    1756              :     //else if(HexButton->isChecked())
    1757            0 :     else if ( i == 1 )
    1758              :     {
    1759            0 :       this_base = 16;
    1760              :     }
    1761              : 
    1762            0 :     return;
    1763              :   }
    1764              : 
    1765            0 :   QString ConvertedString;
    1766            0 :   t_virtue const & Virtue = this_base_data_editor->get();
    1767              : 
    1768            0 :   bool Unsigned = ( Virtue.p_type == dunedaq::conffwk::u8_type
    1769            0 :                     || Virtue.p_type == dunedaq::conffwk::u16_type || Virtue.p_type == dunedaq::conffwk::u32_type
    1770              :                     || Virtue.p_type == dunedaq::conffwk::u64_type );
    1771            0 :   bool OkConversion = false;
    1772              : 
    1773              :   //if(DecButton->isChecked())
    1774              : 
    1775            0 :   if ( i == 0 )
    1776              :   {
    1777            0 :     if ( Unsigned )
    1778              :     {
    1779            0 :       ConvertedString.setNum ( CurrentString.toULongLong ( &OkConversion, 0 ), 10 );
    1780              :     }
    1781              :     else
    1782              :     {
    1783            0 :       ConvertedString.setNum ( CurrentString.toLongLong ( &OkConversion, 0 ), 10 );
    1784              :     }
    1785              : 
    1786            0 :     this_base = 10;
    1787              :   }
    1788              : 
    1789              :   //else if(OctButton->isChecked())
    1790            0 :   else if ( i == 2 )
    1791              :   {
    1792            0 :     if ( Unsigned )
    1793              :     {
    1794            0 :       ConvertedString.setNum ( CurrentString.toULongLong ( &OkConversion, 0 ), 8 );
    1795              :     }
    1796              :     else
    1797              :     {
    1798            0 :       ConvertedString.setNum ( CurrentString.toLongLong ( &OkConversion, 0 ), 8 );
    1799              :     }
    1800              : 
    1801            0 :     ConvertedString.insert(0, "0");
    1802            0 :     this_base = 8;
    1803              :   }
    1804              : 
    1805              :   //else if(HexButton->isChecked())
    1806            0 :   else if ( i == 1 )
    1807              :   {
    1808            0 :     if ( Unsigned )
    1809              :     {
    1810            0 :       ConvertedString.setNum ( CurrentString.toULongLong ( &OkConversion, 0 ), 16 );
    1811              :     }
    1812              :     else
    1813              :     {
    1814            0 :       ConvertedString.setNum ( CurrentString.toLongLong ( &OkConversion, 0 ), 16 );
    1815              :     }
    1816              : 
    1817            0 :     ConvertedString.insert(0, "0x");
    1818            0 :     this_base = 16;
    1819              :   }
    1820              : 
    1821            0 :   if ( !OkConversion )
    1822              :   {
    1823            0 :     QString Format;
    1824              : 
    1825            0 :     if ( this_native_base == 10 )
    1826              :     {
    1827            0 :       Format = "DECIMAL";
    1828              :     }
    1829            0 :     else if ( this_native_base == 16 )
    1830              :     {
    1831            0 :       Format = "HEX-DECIMAL";
    1832              :     }
    1833            0 :     else if ( this_native_base == 8 )
    1834              :     {
    1835            0 :       Format = "OCT-DECIMAL";
    1836              :     }
    1837              : 
    1838            0 :     ShowWarning ( Format );
    1839              : 
    1840            0 :     return;
    1841            0 :   }
    1842              : 
    1843            0 :   if ( !ConvertedString.isEmpty() )
    1844              :   {
    1845            0 :     LineEdit->clear();
    1846            0 :     LineEdit->setText ( ConvertedString );
    1847              :   }
    1848            0 : }
    1849              : 
    1850            0 : void numericattr::UpdateActions ( QString Dummy )
    1851              : {
    1852            0 :   Q_UNUSED ( Dummy )
    1853              : 
    1854            0 :   if ( this_base_data_editor->must_not_be_null() and ( LineEdit->text().isEmpty() ) )
    1855              :   {
    1856            0 :     this_base_data_editor->set_valid ( false );
    1857              :   }
    1858            0 :   else if ( this_base_data_editor->must_not_be_null() and ( this_data.size() == 0 ) )
    1859              :   {
    1860            0 :     this_base_data_editor->set_valid ( false );
    1861              :   }
    1862              :   else
    1863              :   {
    1864            0 :     this_base_data_editor->set_valid ( true );
    1865              :   }
    1866            0 : }
    1867              : 
    1868            0 : void numericattr::ChangeFormatDec()
    1869              : {
    1870            0 :   ChangeFormat ( 0 );
    1871            0 : }
    1872              : 
    1873            0 : void numericattr::ChangeFormatHex()
    1874              : {
    1875            0 :   ChangeFormat ( 1 );
    1876            0 : }
    1877              : 
    1878            0 : void numericattr::ChangeFormatOct()
    1879              : {
    1880            0 :   ChangeFormat ( 2 );
    1881            0 : }
    1882              : 
    1883              : //------------------------------------------------------------------------------------------------
    1884              : 
    1885              : //------------------------------------------------------------------------------------------------
    1886            0 : combo::combo ( t_virtue const & attr, QWidget * parent,
    1887            0 :                bool owned )
    1888              :   :
    1889            0 :   base ( std::make_shared<t_build_block_editor> ( attr ), parent, owned ),
    1890            0 :   m_base_data_editor ( std::static_pointer_cast<t_build_block_editor> ( p_data_editor ) )
    1891              : {
    1892            0 :   setupUi ( this );
    1893            0 :   SetController();
    1894              :   /// Configuration of combo box
    1895            0 :   Combo->setFocusPolicy ( Qt::ClickFocus );
    1896            0 :   Combo->installEventFilter ( this );
    1897              : 
    1898            0 :   if ( Combo->lineEdit() != nullptr )
    1899              :   {
    1900            0 :     Combo->lineEdit()->installEventFilter ( this );
    1901              :   }
    1902              : 
    1903            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    1904              : 
    1905            0 :   if ( Virtue.p_type == dunedaq::conffwk::class_type )
    1906              :   {
    1907            0 :     Combo->setEditable ( true );
    1908              :   }
    1909            0 : }
    1910              : 
    1911            0 : void combo::SetData ( QStringList const & Data )
    1912              : {
    1913            0 :   if ( Data.isEmpty() )
    1914              :   {
    1915              :     return;
    1916              :   }
    1917              : 
    1918            0 :   int Index = Combo->findText ( Data.value ( 0 ) );
    1919              : 
    1920            0 :   if ( Index != -1 )
    1921              :   {
    1922            0 :     Combo->setCurrentIndex ( Index );
    1923            0 :     Combo->setEditText ( Data.value ( 0 ) );
    1924              :   }
    1925              : }
    1926              : 
    1927            0 : void combo::SetValidatorData ( QStringList const & Data, bool AcceptNoMatch )
    1928              : {
    1929            0 :   Combo->clear();
    1930            0 :   Combo->addItems ( Data );
    1931              : 
    1932            0 :   QCompleter * Completer = new QCompleter ( Combo->model(), Combo );
    1933            0 :   Completer->setCaseSensitivity ( Qt::CaseInsensitive );
    1934            0 :   Completer->setCompletionMode ( QCompleter::PopupCompletion );
    1935            0 :   Completer->setFilterMode(Qt::MatchContains);
    1936              : 
    1937            0 :   Combo->setCompleter ( Completer );
    1938              : 
    1939            0 :   m_base_data_editor->set_obligatory ( false );
    1940              : 
    1941            0 :   QVariant VarFromList ( Data );
    1942              : 
    1943            0 :   if ( AcceptNoMatch )
    1944              :   {
    1945            0 :     ValidatorAcceptNoMatch * TmpValidator = new ValidatorAcceptNoMatch ( VarFromList, this );
    1946            0 :     Combo->setValidator ( TmpValidator );
    1947              :   }
    1948              : 
    1949              :   else
    1950              :   {
    1951            0 :     ValidatorAcceptMatch * TmpValidator = new ValidatorAcceptMatch ( VarFromList, this );
    1952            0 :     Combo->setValidator ( TmpValidator );
    1953              :   }
    1954            0 : }
    1955              : 
    1956            0 : QStringList combo::getdata()
    1957              : {
    1958            0 :   this_data.clear();
    1959            0 :   this_data << Combo->currentText();
    1960            0 :   return this_data;
    1961              : }
    1962              : 
    1963            0 : void combo::SetEditor()
    1964              : {
    1965            0 :   t_virtue const & virt = m_base_data_editor->get();
    1966              : 
    1967            0 :   if ( virt.p_type == dunedaq::conffwk::bool_type )
    1968              :   {
    1969            0 :     QStringList tmp
    1970            0 :     { "true", "false" };
    1971            0 :     SetValidatorData ( tmp );
    1972            0 :   }
    1973            0 :   else if ( virt.p_type == dunedaq::conffwk::enum_type )
    1974              :   {
    1975            0 :     QString rangename = virt.p_range.c_str();
    1976            0 :     QStringList range = rangename.split ( "," );
    1977            0 :     range.sort();
    1978            0 :     SetValidatorData ( range );
    1979            0 :   }
    1980            0 :   else if ( virt.p_type == dunedaq::conffwk::class_type )
    1981              :   {
    1982            0 :     QStringList classes ( dbe::config::api::info::onclass::allnames<QStringList>() );
    1983            0 :     classes.sort();
    1984            0 :     SetValidatorData ( classes );
    1985            0 :   }
    1986              : 
    1987            0 :   SetData ( this_data );
    1988            0 : }
    1989              : 
    1990            0 : void combo::setdata ( QStringList const & v )
    1991              : {
    1992            0 :   this_data = v;
    1993            0 : }
    1994              : 
    1995            0 : bool combo::eventFilter ( QObject * Target, QEvent * Event )
    1996              : {
    1997            0 :   if ( Target == Combo->lineEdit() && Event->type() == QEvent::MouseButtonRelease )
    1998              :   {
    1999            0 :     if ( !Combo->lineEdit()->hasSelectedText() )
    2000              :     {
    2001            0 :       Combo->lineEdit()->selectAll();
    2002            0 :       return true;
    2003              :     }
    2004              :   }
    2005              : 
    2006            0 :   if ( Event->type() == QEvent::Wheel )
    2007              :   {
    2008              :     return true;
    2009              :   }
    2010              : 
    2011              :   return false;
    2012              : }
    2013              : 
    2014            0 : void combo::wheelEvent ( QWheelEvent * Event )
    2015              : {
    2016            0 :   Q_UNUSED ( Event )
    2017            0 :   return;
    2018              : }
    2019              : 
    2020            0 : void combo::SetController()
    2021              : {
    2022            0 :   connect ( Combo, SIGNAL ( editTextChanged ( const QString & ) ), this,
    2023              :             SLOT ( TryValidate ( const QString & ) ), Qt::UniqueConnection );
    2024            0 :   connect ( Combo, SIGNAL ( activated ( const QString & ) ), this,
    2025              :             SLOT ( ChangeDetected ( const QString & ) ), Qt::UniqueConnection );
    2026            0 :   connect ( Combo, SIGNAL ( currentIndexChanged ( int ) ), this,
    2027              :             SLOT ( CheckDefaults ( int ) ),
    2028              :             Qt::UniqueConnection );
    2029            0 : }
    2030              : 
    2031            0 : void combo::TryValidate ( QString tmp )
    2032              : {
    2033            0 :   int index = 0;
    2034              : 
    2035            0 :   if ( Combo->validator() != nullptr )
    2036              :   {
    2037            0 :     if ( Combo->validator()->validate ( tmp, index ) == QValidator::Acceptable )
    2038              :     {
    2039            0 :       m_base_data_editor->set_valid ( true );
    2040              : 
    2041            0 :       if ( CompareDefaults() )
    2042              :       {
    2043            0 :         Combo->setPalette ( StyleUtility::LoadedDefault );
    2044              :       }
    2045              : 
    2046              :       else
    2047              :       {
    2048            0 :         Combo->setPalette ( QApplication::palette ( this ) );
    2049              :       }
    2050              :     }
    2051              : 
    2052            0 :     else if ( Combo->validator()->validate ( tmp, index ) == QValidator::Intermediate )
    2053              :     {
    2054            0 :       m_base_data_editor->set_not_null ( false );
    2055            0 :       Combo->setPalette ( StyleUtility::WarningStatusBarPallete );
    2056              :     }
    2057              :   }
    2058              : 
    2059              :   else
    2060              :   {
    2061            0 :     if ( CompareDefaults() )
    2062              :     {
    2063            0 :       Combo->setPalette ( StyleUtility::LoadedDefault );
    2064              :     }
    2065              :     else
    2066              :     {
    2067            0 :       Combo->setPalette ( QApplication::palette ( this ) );
    2068              :     }
    2069              :   }
    2070            0 : }
    2071              : 
    2072            0 : void combo::ChangeDetected ( const QString & StringChange )
    2073              : {
    2074            0 :   Q_UNUSED ( StringChange )
    2075            0 :   this_value_changed = true;
    2076            0 :   emit signal_value_change();
    2077            0 : }
    2078              : 
    2079            0 : void combo::CheckDefaults ( int DefaultIndex )
    2080              : {
    2081            0 :   Q_UNUSED ( DefaultIndex )
    2082              : 
    2083            0 :   if ( !this_defaults.isEmpty() )
    2084              :   {
    2085            0 :     TryValidate ( Combo->currentText() );
    2086              :   }
    2087            0 : }
    2088              : 
    2089            0 : bool combo::CompareDefaults()
    2090              : {
    2091            0 :   if ( this_defaults.isEmpty() )
    2092              :   {
    2093              :     return false;
    2094              :   }
    2095              : 
    2096            0 :   if ( this_defaults == Combo->currentText() )
    2097              :   {
    2098              :     return true;
    2099              :   }
    2100              : 
    2101              :   return false;
    2102              : }
    2103              : 
    2104            0 : void combo::buildtooltip()
    2105            0 : {}
    2106              : 
    2107              : //------------------------------------------------------------------------------------------------
    2108              : 
    2109              : //------------------------------------------------------------------------------------------------
    2110            0 : multiattr::multiattr ( t_virtue const & attr, QWidget * parent,
    2111            0 :                        bool owned )
    2112              :   :
    2113            0 :   base ( std::make_shared<t_build_block_editor> ( attr ), parent, owned ),
    2114            0 :   m_base_data_editor ( std::static_pointer_cast<t_build_block_editor> ( p_data_editor ) ),
    2115            0 :   StatusBar ( nullptr ),
    2116            0 :   OkButton ( nullptr ),
    2117            0 :   RemoveButton ( nullptr ),
    2118            0 :   ListWidget ( nullptr ),
    2119            0 :   ContextMenu ( nullptr ),
    2120            0 :   RemoveAction ( nullptr )
    2121              : {
    2122            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    2123              : 
    2124            0 :   setWindowTitle ( QString ( "Edit Attribute : %1" ).arg ( Virtue.p_name.c_str() ) );
    2125            0 :   QVBoxLayout * MainLayout = new QVBoxLayout ( this );
    2126            0 :   MainLayout->setSpacing ( 0 );
    2127            0 :   MainLayout->setMargin ( 0 );
    2128            0 :   MainLayout->setContentsMargins ( 0, 0, 0, 0 );
    2129            0 :   QHBoxLayout * ButtonLayout = new QHBoxLayout();
    2130            0 :   ListWidget = new QListWidget ( this );
    2131            0 :   ListWidget->setContextMenuPolicy ( Qt::CustomContextMenu );
    2132              : 
    2133            0 :   switch ( Virtue.p_type )
    2134              :   {
    2135              :   // Bool and enums have the same widget
    2136              : 
    2137            0 :   case dunedaq::conffwk::bool_type:
    2138            0 :   case dunedaq::conffwk::class_type:
    2139            0 :   case dunedaq::conffwk::enum_type:
    2140            0 :   {
    2141            0 :     combo * Combo = new combo ( attr, this );
    2142            0 :     MainLayout->addWidget ( Combo );
    2143            0 :     connect ( Combo->Combo, SIGNAL ( activated ( const QString & ) ), this,
    2144              :               SLOT ( AddToDataList ( const QString & ) ), Qt::UniqueConnection );
    2145            0 :     BaseWidget = Combo;
    2146              : 
    2147            0 :     break;
    2148              :   }
    2149              : 
    2150              :   // All numeric types are treated as uint64
    2151              : 
    2152            0 :   case dunedaq::conffwk::double_type:
    2153            0 :   case dunedaq::conffwk::float_type:
    2154            0 :   case dunedaq::conffwk::s8_type:
    2155            0 :   case dunedaq::conffwk::s16_type:
    2156            0 :   case dunedaq::conffwk::s32_type:
    2157            0 :   case dunedaq::conffwk::s64_type:
    2158            0 :   case dunedaq::conffwk::u8_type:
    2159            0 :   case dunedaq::conffwk::u16_type:
    2160            0 :   case dunedaq::conffwk::u32_type:
    2161            0 :   case dunedaq::conffwk::u64_type:
    2162            0 :   {
    2163            0 :     numericattr * Numeric = new numericattr ( Virtue, this );
    2164            0 :     MainLayout->addWidget ( Numeric );
    2165            0 :     connect ( Numeric, SIGNAL ( signal_value_change() ), this, SLOT ( LineValueChanged() ),
    2166              :               Qt::UniqueConnection );
    2167            0 :     connect ( Numeric, SIGNAL ( signal_value_duplicated() ), this, SLOT ( LineValueChanged() ),
    2168              :                   Qt::UniqueConnection );
    2169            0 :     BaseWidget = Numeric;
    2170              :     /// Frame
    2171            0 :     Numeric->GetLineEdit()->setFrame ( false );
    2172            0 :     Numeric->GetLineEdit()->setPlaceholderText ( "Type Here" );
    2173            0 :     Numeric->setStyleSheet (
    2174              :       "QLineEdit { background: #c0c0c0;} QLineEdit:focus {background: white;}" );
    2175            0 :     Numeric->GetLineEdit()->setFixedHeight ( 24 );
    2176            0 :     ListWidget->setFrameStyle ( QFrame::NoFrame );
    2177              :     break;
    2178              :   }
    2179              : 
    2180              :   // Types below are all treated as string types
    2181              : 
    2182            0 :   case dunedaq::conffwk::date_type:
    2183            0 :   case dunedaq::conffwk::time_type:
    2184            0 :   case dunedaq::conffwk::string_type:
    2185            0 :   {
    2186            0 :     stringattr * String = new stringattr ( Virtue, this );
    2187            0 :     String->SetMultiCheck ( true );
    2188            0 :     MainLayout->addWidget ( String );
    2189            0 :     connect ( String, SIGNAL ( signal_value_change() ), this, SLOT ( LineValueChanged() ),
    2190              :               Qt::UniqueConnection );
    2191            0 :     BaseWidget = String;
    2192              :     /// Frame
    2193            0 :     String->GetLineEdit()->setFrameStyle(QFrame::NoFrame);
    2194              : //    String->GetLineEdit()->setPlaceholderText ( "Type here" );
    2195            0 :     String->setStyleSheet ( "QLineEdit { background: #c0c0c0;} "
    2196              :                                                                                                                                                                                 "QLineEdit:focus {background: white;}" );
    2197              : //    String->GetLineEdit()->setFixedHeight ( 24 );
    2198              : 
    2199            0 :     ListWidget->setFrameStyle ( QFrame::NoFrame );
    2200              :     break;
    2201              :   }
    2202              : 
    2203              :   default:
    2204              :     break;
    2205              :   }
    2206              : 
    2207            0 :   OkButton = new QPushButton ( tr ( "Apply" ) );
    2208              :   //RemoveButton = new QPushButton(tr("Remove"));
    2209            0 :   ButtonLayout->addWidget ( OkButton );
    2210              :   //ButtonLayout->addWidget(RemoveButton);
    2211            0 :   connect ( OkButton, SIGNAL ( clicked() ), this, SLOT ( EndSignal() ) );
    2212              :   //connect(RemoveButton,SIGNAL(clicked()),this,SLOT(RemoveFromDataList()));
    2213            0 :   connect ( this, SIGNAL ( signal_internal_value_change() ), this, SLOT ( UpdateActions() ) );
    2214            0 :   connect ( ListWidget, SIGNAL ( customContextMenuRequested ( QPoint ) ), this,
    2215              :             SLOT ( CustomContextMenuRequested ( QPoint ) ) );
    2216              : 
    2217            0 :   MainLayout->addWidget ( ListWidget );
    2218            0 :   MainLayout->addLayout ( ButtonLayout );
    2219            0 :   SetStatusBar();
    2220            0 :   MainLayout->addWidget ( StatusBar );
    2221              : 
    2222            0 :   setLayout ( MainLayout );
    2223              : 
    2224            0 :   if ( Virtue.p_is_not_null )
    2225              :   {
    2226            0 :     m_base_data_editor->set_valid ( false );
    2227            0 :     OkButton->setDisabled ( true );
    2228              :   }
    2229              : 
    2230            0 :   if ( this_is_owned )
    2231              :   {
    2232            0 :     OkButton->setHidden ( true );
    2233              :   }
    2234              : 
    2235              :   else
    2236              :   {
    2237            0 :     QFont Font;
    2238            0 :     QFontMetrics FontMetrics ( Font );
    2239            0 :     setMinimumWidth (
    2240            0 :       2 * FontMetrics.horizontalAdvance ( QString ( "Edit Relationship: %1" ).arg ( Virtue.p_name.c_str() ) )
    2241              :       - 15 );
    2242            0 :     setMinimumHeight ( 100 );
    2243            0 :   }
    2244              : 
    2245            0 :   buildtooltip();
    2246            0 :   UpdateActions();
    2247            0 : }
    2248              : 
    2249            0 : void multiattr::SetEditor()
    2250              : {
    2251            0 :   BaseWidget->SetEditor();
    2252              : 
    2253            0 :   ListWidget->clear();
    2254            0 :   ListWidget->addItems ( this_data );
    2255            0 :   ListWidget->setSelectionMode ( QAbstractItemView::ExtendedSelection );
    2256            0 :   ListWidget->setDragEnabled ( true );
    2257            0 :   ListWidget->setAcceptDrops ( true );
    2258            0 :   ListWidget->setEditTriggers ( QAbstractItemView::DoubleClicked );
    2259            0 :   ListWidget->setDragDropMode ( QAbstractItemView::InternalMove );
    2260              : 
    2261            0 :   for ( int i = 0; i < ListWidget->count(); ++i )
    2262              :   {
    2263            0 :     QListWidgetItem * widget = ListWidget->item ( i );
    2264            0 :     widget->setFlags (
    2265            0 :       Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled
    2266            0 :       | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled );
    2267              : 
    2268              :   }
    2269              : 
    2270            0 :   connect ( ListWidget, SIGNAL ( itemChanged ( QListWidgetItem * ) ), this,
    2271              :             SLOT ( LineValueChanged ( QListWidgetItem * ) ) );
    2272            0 :   emit signal_internal_value_change();
    2273            0 : }
    2274              : 
    2275            0 : void multiattr::buildtooltip()
    2276              : {
    2277            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    2278              : 
    2279            0 :   setToolTip (
    2280            0 :     QString ( "Attribute Name:           %1 \n" ).arg ( Virtue.p_name.c_str() ) + QString (
    2281            0 :       "          Type:           %1 \n" ).arg (
    2282            0 :       dunedaq::conffwk::attribute_t::type2str ( Virtue.p_type ) )
    2283            0 :     + QString ( "          Range:          %1 \n" ).arg ( Virtue.p_range.c_str() )
    2284            0 :     + QString ( "          Format:         %1 \n" ).arg (
    2285            0 :       dunedaq::conffwk::attribute_t::format2str ( Virtue.p_int_format ) )
    2286            0 :     + QString ( "          Not Null:       %1 \n" ).arg ( Virtue.p_is_not_null )
    2287            0 :     + QString ( "          Is Multi Value: %1 \n" ).arg ( Virtue.p_is_multi_value )
    2288            0 :     + QString ( "          Default Value:  %1 \n" ).arg ( Virtue.p_default_value.c_str() )
    2289            0 :     + QString ( "          Description:    %1 \n" ).arg ( Virtue.p_description.c_str() ) );
    2290            0 : }
    2291              : 
    2292            0 : void multiattr::closeEvent ( QCloseEvent * Event )
    2293              : {
    2294            0 :   Q_UNUSED ( Event )
    2295            0 :   emit signal_force_close();
    2296            0 : }
    2297              : 
    2298            0 : void multiattr::SetStatusBar()
    2299              : {
    2300            0 :   StatusBar = new QStatusBar ( this );
    2301            0 :   StatusBar->setSizeGripEnabled ( false );
    2302              :   /// Color Management needs to be done
    2303            0 :   StatusBar->setAutoFillBackground ( true );
    2304              :   /// Uncomment if you want a status bar
    2305            0 :   StatusBar->setHidden ( true );
    2306            0 : }
    2307              : 
    2308            0 : bool multiattr::eventFilter ( QObject * Target, QEvent * Event )
    2309              : {
    2310            0 :   ( void ) Target;
    2311            0 :   ( void ) Event;
    2312            0 :   return false;
    2313              : }
    2314              : 
    2315            0 : void multiattr::AddToDataList ( const QString & Data )
    2316              : {
    2317            0 :   if ( Data.isEmpty() )
    2318              :   {
    2319              :     return;
    2320              :   }
    2321              : 
    2322            0 :   this_data.append ( Data );
    2323              : 
    2324            0 :   ListWidget->clear();
    2325            0 :   ListWidget->addItems ( this_data );
    2326            0 :   StatusBar->showMessage ( QString ( "Item %1 was added." ).arg ( Data ) );
    2327              : 
    2328            0 :   this_value_changed = true;
    2329            0 :   emit signal_internal_value_change();
    2330              : }
    2331              : 
    2332            0 : void multiattr::RemoveFromDataList()
    2333              : {
    2334            0 :   QList<QListWidgetItem *> widgets = ListWidget->selectedItems();
    2335            0 :   this_value_changed = true;
    2336              : 
    2337            0 :   for ( QListWidgetItem * widget : widgets )
    2338              :   {
    2339            0 :     int index = this_data.indexOf ( widget->text() );
    2340              : 
    2341            0 :     if ( index != -1 )
    2342              :     {
    2343            0 :       this_data.takeAt ( index );
    2344              :     }
    2345              : 
    2346            0 :     int r = ListWidget->row ( widget );
    2347              : 
    2348            0 :     if ( QListWidgetItem * w = ListWidget->takeItem ( r ) )
    2349              :     {
    2350            0 :       delete w;
    2351              :     }
    2352              : 
    2353              :   }
    2354              : 
    2355            0 :   if ( this_is_owned )
    2356              :   {
    2357            0 :     StatusBar->showMessage ( "The selected items were removed." );
    2358              :   }
    2359              : 
    2360            0 :   if ( dynamic_cast<stringattr *> ( BaseWidget ) )
    2361              :   {
    2362              :     /// Color management needs to be done
    2363            0 :     stringattr * StringWidget = dynamic_cast<stringattr *> ( BaseWidget );
    2364            0 :     StringWidget->GetLineEdit()->selectAll();
    2365            0 :     StringWidget->GetLineEdit()->clear();
    2366            0 :     StringWidget->SetCheckDefaults ( false );
    2367            0 :     StringWidget->SetNullCheck ( true );
    2368              :   }
    2369              : 
    2370            0 :   emit signal_internal_value_change();
    2371            0 :   emit signal_value_change();
    2372            0 : }
    2373              : 
    2374            0 : void multiattr::UpdateActions()
    2375              : {
    2376            0 :   t_virtue const & Virtue = m_base_data_editor->get();
    2377              : 
    2378            0 :   if ( Virtue.p_is_not_null and this_data.size() == 0 )
    2379              :   {
    2380            0 :     OkButton->setDisabled ( true );
    2381            0 :     StatusBar->showMessage ( "Attribute can not be null." );
    2382            0 :     m_base_data_editor->set_valid ( false );
    2383            0 :     ListWidget->setPalette ( StyleUtility::WarningStatusBarPallete );
    2384              :     /// EditString validator string
    2385              :   }
    2386              : 
    2387            0 :   else if ( Virtue.p_is_not_null and this_data.size() > 0 )
    2388              :   {
    2389              :     /// Null Check validator string
    2390              : 
    2391            0 :     StatusBar->showMessage ( "Attribute is set." );
    2392            0 :     ListWidget->setPalette ( QApplication::palette ( this ) );
    2393            0 :     OkButton->setEnabled ( true );
    2394            0 :     m_base_data_editor->set_valid ( true );
    2395              : 
    2396            0 :     if ( this_is_owned )
    2397              :     {
    2398            0 :       EndSignal();
    2399              :     }
    2400              :   }
    2401            0 :   else if ( not Virtue.p_is_not_null and this_is_owned )
    2402              :   {
    2403            0 :     m_base_data_editor->set_valid ( true );
    2404            0 :     EndSignal();
    2405              :   }
    2406            0 : }
    2407              : 
    2408            0 : void multiattr::LineValueChanged()
    2409              : {
    2410            0 :   QStringList Data = BaseWidget->getdata();
    2411              : 
    2412            0 :   if ( (!Data.isEmpty()) && BaseWidget->dataeditor()->is_valid())
    2413              :   {
    2414            0 :     AddToDataList ( Data.at ( 0 ) );
    2415              :   }
    2416            0 : }
    2417              : 
    2418            0 : void multiattr::LineValueChanged ( QListWidgetItem * changed )
    2419              : {
    2420            0 :   int r = ListWidget->row ( changed );
    2421            0 :   QString newtext = changed->text();
    2422            0 :   QString oldtext = this_data.at ( r );
    2423            0 :   this_data.replace ( r, newtext );
    2424            0 :   this_value_changed = true;
    2425              : 
    2426            0 :   StatusBar->showMessage ( QString ( "Item %1 was modified." ).arg ( oldtext ) );
    2427              : 
    2428            0 :   emit signal_internal_value_change();
    2429            0 : }
    2430              : 
    2431            0 : void multiattr::ListOrderChange ( const QModelIndexList & IndexList )
    2432              : {
    2433            0 :   Q_UNUSED ( IndexList )
    2434              : 
    2435            0 :   this_data.clear();
    2436              : 
    2437            0 :   for ( int i = 0; i < ListWidget->count(); ++i )
    2438              :   {
    2439            0 :     this_data.append ( ListWidget->item ( i )->text() );
    2440              :   }
    2441            0 : }
    2442              : 
    2443            0 : void multiattr::EndSignal()
    2444              : {
    2445            0 :   this_data.clear();
    2446              : 
    2447            0 :   for ( int i = 0; i < ListWidget->count(); ++i )
    2448              :   {
    2449            0 :     this_data.append ( ListWidget->item ( i )->text() );
    2450              :   }
    2451              : 
    2452            0 :   if ( !this_is_owned )
    2453              :   {
    2454            0 :     m_base_data_editor->set_valid ( true );
    2455            0 :     emit signal_edit_end();
    2456              :   }
    2457              : 
    2458              :   else
    2459              :   {
    2460            0 :     emit signal_value_change();
    2461              :   }
    2462            0 : }
    2463              : 
    2464            0 : void multiattr::CustomContextMenuRequested ( const QPoint & pos )
    2465              : {
    2466            0 :   if ( ContextMenu == nullptr )
    2467              :   {
    2468            0 :     ContextMenu = new QMenu ( ListWidget );
    2469              : 
    2470            0 :     RemoveAction = new QAction ( tr ( "Remove" ), this );
    2471            0 :     RemoveAction->setShortcutContext ( Qt::WidgetShortcut );
    2472            0 :     connect ( RemoveAction, SIGNAL ( triggered() ), this, SLOT ( RemoveSlot() ),
    2473              :               Qt::UniqueConnection );
    2474            0 :     ContextMenu->addAction ( RemoveAction );
    2475              :   }
    2476              : 
    2477            0 :   ContextMenu->exec ( ListWidget->mapToGlobal ( pos ) );
    2478            0 : }
    2479              : 
    2480            0 : void multiattr::RemoveSlot()
    2481              : {
    2482            0 :   RemoveFromDataList();
    2483            0 : }
    2484              : 
    2485              : //------------------------------------------------------------------------------------------------
    2486              : 
    2487              : } // end namespace editors
    2488              : } // end namespace widgets
    2489              : } // end namespace dbe
    2490              : 
    2491              : //------------------------------------------------------------------------------------------------
        

Generated by: LCOV version 2.0-1