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