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