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

Generated by: LCOV version 2.0-1