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

Generated by: LCOV version 2.0-1