DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
ObjectEditor.cpp
Go to the documentation of this file.
3#include "dbe/Sorting.hpp"
8#include "dbe/messenger.hpp"
9#include "ui_ObjectEditor.h"
10#include "dbe/MainWindow.hpp"
11
12#include <QFileInfo>
13#include <QCloseEvent>
14#include <QMessageBox>
15
17
18namespace {
19 class NoScrollingTable : public QTableWidget {
20 public:
21 NoScrollingTable(QWidget* parent = 0) : QTableWidget(parent) {}
22
23 void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible) override {
24 // NOTE: for the reason why this is an empty implementation, see ATLASDBE-202
25 }
26 };
27}
28
29//------------------------------------------------------------------------------------------
31//------------------------------------------------------------------------------------------
32
33//------------------------------------------------------------------------------------------
34dbe::ObjectEditor::ObjectEditor ( std::string const & cname, QWidget * parent )
35 :
36 QWidget ( parent ),
37 ui ( new Ui::ObjectEditor ),
38 classname ( cname ),
39 object_to_edit ( nullptr ),
40 IsValid ( false ),
41 this_is_in_copy_mode ( true ),
42 this_editor_is_owned ( true ),
43 this_is_in_creation_mode ( true ),
44 this_editor_values_changed ( false ),
45 CurrentRow ( 0 ),
46
47 MainLayout ( new QHBoxLayout() ),
48 WidgetTable ( new NoScrollingTable() ),
49
50 RenameWidget ( nullptr ),
51 LineEdit ( nullptr ),
52 GoButton ( nullptr ),
53
54 MoveWidget ( nullptr ),
55 FileView ( nullptr ),
56 IncludedFileModel ( nullptr ),
57 MoveGoButton ( nullptr ),
58 uuid ( QUuid::createUuid() )
59{
60 ui->setupUi ( this );
61
62 ui->RenameButton->setDisabled ( true ); // Cannot rename an object that does not exist
63 ui->ClassLabel->setText ( QString ( "New Object" ) );
64
65 dunedaq::conffwk::class_t const & Class =
67 int NumberOfRows = Class.p_attributes.size() + Class.p_relationships.size();
68 int NumberOfColumns = 1;
69 WidgetTable->setRowCount ( NumberOfRows );
70 WidgetTable->setColumnCount ( NumberOfColumns );
71 setAttribute ( Qt::WA_DeleteOnClose, true );
72
77
78 ui->DetailsGroupBox->setVisible ( false );
79
80 WidgetTable->setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding );
81 WidgetTable->horizontalHeader()->setVisible ( false );
82 WidgetTable->horizontalHeader()->setSectionResizeMode ( QHeaderView::ResizeToContents );
83 WidgetTable->horizontalHeader()->setSectionResizeMode ( 0, QHeaderView::Stretch );
84 WidgetTable->setVerticalHeaderLabels ( HorizontalHeaders );
85 WidgetTable->setSelectionMode ( QAbstractItemView::NoSelection );
86
87 ui->TableLayout->addWidget ( WidgetTable );
88
89 ui->ApplyButton->setEnabled ( false );
90
91 ui->RenameButton->setToolTip ( "Rename object" );
92
94 {
95 ui->RenameButton->setDisabled ( true );
96 ui->MoveButton->setDisabled ( true );
97 }
98
99 this->show();
100}
101
102//------------------------------------------------------------------------------------------
103
104//------------------------------------------------------------------------------------------
105dbe::ObjectEditor::ObjectEditor ( tref const & object, QWidget * parent, bool iscopy )
106 :
107 QWidget ( parent ),
108 ui ( new Ui::ObjectEditor ),
109 classname ( object.class_name() ),
110 object_to_edit ( new dref ( object ) ),
111 IsValid ( false ),
112 this_is_in_copy_mode ( iscopy ),
113 this_editor_is_owned ( false ),
114 this_is_in_creation_mode ( false ),
115 this_editor_values_changed ( false ),
116 CurrentRow ( 0 ),
117 MainLayout ( new QHBoxLayout() ),
118 WidgetTable ( new NoScrollingTable() ),
119 RenameWidget ( nullptr ),
120 LineEdit ( nullptr ),
121 GoButton ( nullptr ),
122 MoveWidget ( nullptr ),
123 FileView ( nullptr ),
124 IncludedFileModel ( nullptr ),
125 MoveGoButton ( nullptr ),
126 uuid ( QUuid::createUuid() )
127{
128 ui->setupUi ( this );
129
130 ui->ClassLabel->setText (
131 QString ( "Full object name : %1@%2" ).arg ( Object().UID().c_str() ).arg (
132 Object().class_name().c_str() ) );
133
134 this->setWindowTitle (
135 QString ( "Edit Object %1 of Class %2" ).arg ( Object().UID().c_str() ).arg (
136 Object().class_name().c_str() ) );
137
138 this->setObjectName (
139 QString ( "%1@%2" ).arg ( Object().UID().c_str() ).arg ( Object().class_name().c_str() ) );
140
141 dunedaq::conffwk::class_t const & Class =
143 int NumberOfRows = Class.p_attributes.size() + Class.p_relationships.size();
144 int NumberOfColumns = 1;
145 WidgetTable->setRowCount ( NumberOfRows );
146 WidgetTable->setColumnCount ( NumberOfColumns );
147 setAttribute ( Qt::WA_DeleteOnClose, true );
148
150 BuildWidgets();
153
154 ui->DetailsGroupBox->setVisible ( false );
155
156 WidgetTable->setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding );
157 WidgetTable->horizontalHeader()->setVisible ( false );
158 WidgetTable->horizontalHeader()->setSectionResizeMode ( QHeaderView::ResizeToContents );
159 WidgetTable->horizontalHeader()->setSectionResizeMode ( 0, QHeaderView::Stretch );
160 WidgetTable->setVerticalHeaderLabels ( HorizontalHeaders );
161 WidgetTable->setSelectionMode ( QAbstractItemView::NoSelection );
162
163 ui->TableLayout->addWidget ( WidgetTable );
164
165 ui->ApplyButton->setEnabled ( false );
166
167 ui->RenameButton->setToolTip ( "Rename object" );
168
170 {
171 ui->RenameButton->setDisabled ( true );
172 ui->MoveButton->setDisabled ( true );
173 }
174
175 this->show();
176}
177
178//------------------------------------------------------------------------------------------
179
180//------------------------------------------------------------------------------------------
182{
183 if ( Hide )
184 {
185 ui->DetailWidget->hide();
186 ui->DetailsGroupBox->hide();
187 }
188 else
189 {
190 ui->DetailWidget->show();
191 ui->DetailsGroupBox->show();
192 }
193}
194
195//------------------------------------------------------------------------------------------
196
197//------------------------------------------------------------------------------------------
199{
200 return IsValid;
201}
202
204{
205 return this_editor_values_changed;
206}
207
208//------------------------------------------------------------------------------------------
209
210//------------------------------------------------------------------------------------------
212{
213 if ( this_editor_values_changed and ui->ApplyButton->isEnabled() )
214 {
215 int ret =
216 QMessageBox::question (
217 0,
218 tr ( "DBE - ObjectEditor" ),
219 QString (
220 "There are unsaved changes for object\n'%1.%2'\n\nDo you want to apply changes?\n" )
221 .arg ( QString::fromStdString ( Object().full_name() ) ),
222 QMessageBox::Apply | QMessageBox::Discard | QMessageBox::Cancel,
223 QMessageBox::Apply );
224
225 switch ( ret )
226 {
227
228 case QMessageBox::Discard:
229 ResetObjectChanged();
230 break;
231
232 case QMessageBox::Apply:
233 ParseToSave();
234 break;
235
236 case QMessageBox::Cancel:
237 return false;
238 break;
239 }
240
241 return true;
242 }
243 else
244 {
245 return true;
246 }
247}
248
249//------------------------------------------------------------------------------------------
250
251//------------------------------------------------------------------------------------------
253{
254 StatusBar->setSizeGripEnabled ( false );
255 StatusBar->setAutoFillBackground ( true );
256}
257
258//------------------------------------------------------------------------------------------
259
260//------------------------------------------------------------------------------------------
262{
263 connect ( ui->DetailButton, SIGNAL ( toggled ( bool ) ), ui->DetailsGroupBox,
264 SLOT ( setVisible ( bool ) ), Qt::UniqueConnection );
265
266 connect ( ui->CloseButton, SIGNAL ( clicked ( bool ) ), this, SLOT ( close() ),
267 Qt::UniqueConnection );
268
269 connect ( ui->ApplyButton, SIGNAL ( clicked() ), this, SLOT ( ParseToSave() ),
270 Qt::UniqueConnection );
271
272 connect ( ui->RenameButton, SIGNAL ( clicked() ), this, SLOT ( LaunchRenameObject() ) );
273 connect ( ui->MoveButton, SIGNAL ( clicked() ), this, SLOT ( LaunchMoveObject() ) );
274
275 connect ( &confaccessor::ref(), SIGNAL ( object_changed ( QString, dref ) ), this,
276 SLOT ( UpdateObjectEditor ( QString, dref ) ) );
277
278 connect ( &confaccessor::ref(), SIGNAL ( object_deleted ( QString, dref ) ), this,
279 SLOT ( ShouldCloseThisWindow ( QString, dref ) ) );
280
281 MainWindow * mainwin = MainWindow::findthis();
282 if(mainwin != nullptr) {
283 connect (mainwin, SIGNAL(signal_batch_change_stopped(const QList<QPair<QString, QString>>&)),
284 this, SLOT(UpdateObjectEditor(const QList<QPair<QString, QString>>&)), Qt::UniqueConnection);
285 connect (mainwin, SIGNAL(signal_externalchanges_processed()),
286 this, SLOT(UpdateObjectEditor()), Qt::UniqueConnection);
287 }
288}
289
290void dbe::ObjectEditor::UpdateObjectEditor(const QList<QPair<QString, QString>>& objs) {
291 for(const auto& p : objs) {
292 if((p.first.toStdString() == Object().class_name()) && (p.second.toStdString() == Object().UID())) {
293 UpdateObjectEditor("", inner::dbcontroller::get({Object().UID(), Object().class_name()}));
294 break;
295 }
296 }
297}
298
300 const auto& ref = inner::dbcontroller::get({Object().UID(), Object().class_name()});
301 if(ref.is_null() == false) {
302 UpdateObjectEditor("", inner::dbcontroller::get({Object().UID(), Object().class_name()}));
303 } else {
304 // The object has been deleted
305 this->close();
306 }
307}
308
309//------------------------------------------------------------------------------------------
310
311//------------------------------------------------------------------------------------------
312void dbe::ObjectEditor::UpdateObjectEditor ( QString const & src, dref updated_object )
313{
314 // src is ignored even in the case of this being the source
315 // changes must always be applied since it is developer responsibility
316 // to emit signals as needed
317 Q_UNUSED ( src );
318
319 if ( not this_editor_is_owned and object_to_edit and Object().UID() == updated_object.UID()
320 and Object().class_name() == updated_object.class_name() )
321 {
322
323 object_to_edit.reset ( new dref ( updated_object ) );
324
325 dunedaq::conffwk::class_t const & classdef =
327 std::vector<dunedaq::conffwk::attribute_t> class_attributes = classdef.p_attributes;
328 std::vector<dunedaq::conffwk::relationship_t> class_relations = classdef.p_relationships;
329
330 for ( dunedaq::conffwk::attribute_t attr : class_attributes )
331 {
332 if ( widgets::editors::base * attreditor =
333 this_widgets[QString::fromStdString ( attr.p_name )] )
334 {
335 set_attribute_widget ( attr, attreditor );
336 }
337 }
338
339 for ( dunedaq::conffwk::relationship_t arelation : class_relations )
340 {
341 QStringList relvalues;
342 QString relname = QString ( arelation.p_name.c_str() );
343
344 if ( widgets::editors::relation * relwidget =
345 dynamic_cast<widgets::editors::relation *> ( this_widgets[relname] ) )
346 {
347 if ( relwidget->ischanged() )
348 {
349 relvalues = relwidget->getdata();
350 }
351 else
352 {
353 std::vector<tref> connected;
354
355 if ( config::api::info::relation::is_simple ( arelation ) )
356 {
357 try
358 {
359 connected.push_back (
361 }
362 catch ( daq::dbe::config_object_retrieval_result_is_null const & e )
363 {
364 // nothing needs be done to handle the case that a relation has no object set
365 }
366 }
367 else
368 {
369 connected =
370 dbegraph::linked::through::relation<std::vector<tref>> ( Object(), arelation );
371 }
372
373 std::transform ( connected.begin(), connected.end(), std::back_inserter ( relvalues ),
374 [] ( decltype ( connected ) ::value_type const & x )
375 {
376 return QString::fromStdString ( x.UID() );
377 }
378
379 );
380
381 }
382
383 relwidget->setdata ( relvalues );
384 relwidget->SetEditor();
385 }
386 }
387 }
388
389 // Trick to properly refresh the window (repaint and update does not seem to work)
390 const auto& s = size();
391 resize(s.width() + 1, s.height() +1);
392 resize(s.width(), s.height());
393}
394
395//------------------------------------------------------------------------------------------
396
397//------------------------------------------------------------------------------------------
398void dbe::ObjectEditor::ShouldCloseThisWindow ( QString const src, dref const key )
399{
400 Q_UNUSED ( src );
401
402 std::string const & fullname = key.UID() + "@" + key.class_name();
403
404 if ( ( object_to_edit and not object_to_edit->is_valid() )
405 or ( this->objectName().toStdString() == fullname ) )
406 {
407 this->close();
408 }
409}
410
411//------------------------------------------------------------------------------------------
412
413//------------------------------------------------------------------------------------------
415{
416 dunedaq::conffwk::class_t const & classdef =
418 std::vector<dunedaq::conffwk::attribute_t> attributes = classdef.p_attributes;
419 std::vector<dunedaq::conffwk::relationship_t> relations = classdef.p_relationships;
420
421 for ( dunedaq::conffwk::attribute_t const & attr : attributes ) // Build widgets for attributes
422
423 {
424 QString name = QString::fromStdString ( attr.p_name );
425
426 if ( attr.p_is_multi_value )
427 {
429 true );
430 set_attribute_widget ( attr, widget );
431 set_tooltip ( attr, widget );
432 register_attribute_widget ( name, widget );
433 connect ( widget, SIGNAL ( signal_value_change() ), this, SLOT ( UpdateActions() ),
434 Qt::UniqueConnection );
435 connect ( widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
436 Qt::UniqueConnection );
437 emit LoadedInitials();
438 }
439 else
440 {
441 switch ( attr.p_type )
442 {
443
445
447 {
448 widgets::editors::combo * Widget = new widgets::editors::combo ( attr, this, true );
449 set_attribute_widget ( attr, Widget );
450 set_tooltip ( attr, Widget );
451 register_attribute_widget ( name, Widget );
452 connect ( Widget->Combo, SIGNAL ( activated ( QString ) ), this, SLOT ( UpdateActions() ),
453 Qt::UniqueConnection );
454 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
455 Qt::UniqueConnection );
456 emit LoadedInitials();
457 break;
458 }
459
461
463
465
467
469
471
473
475
477
479 {
481 true );
482 set_attribute_widget ( attr, Widget );
483 set_tooltip ( attr, Widget );
484 register_attribute_widget ( name, Widget );
485 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( UpdateActions() ),
486 Qt::UniqueConnection );
487 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
488 Qt::UniqueConnection );
489 emit LoadedInitials();
490 break;
491 }
492
494
496
498 {
500 true );
501 set_attribute_widget ( attr, Widget );
502 set_tooltip ( attr, Widget );
503 register_attribute_widget ( name, Widget );
504 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( UpdateActions() ),
505 Qt::UniqueConnection );
506 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
507 Qt::UniqueConnection );
508 emit LoadedInitials();
509 break;
510 }
511
513 {
514 widgets::editors::combo * Widget = new widgets::editors::combo ( attr, this, true );
515 set_attribute_widget ( attr, Widget );
516 set_tooltip ( attr, Widget );
517 register_attribute_widget ( name, Widget );
518 connect ( Widget->Combo, SIGNAL ( activated ( QString ) ), this, SLOT ( UpdateActions() ),
519 Qt::UniqueConnection );
520 connect ( Widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
521 Qt::UniqueConnection );
522 emit LoadedInitials();
523 break;
524 }
525 }
526 }
527 }
528
529 for ( dunedaq::conffwk::relationship_t const & arelation :
530 relations ) // Build widgets for relations ( relationships )
531 {
532 widgets::editors::relation * widget = new widgets::editors::relation ( arelation, this,
533 true );
534 QString name = QString::fromStdString ( arelation.p_name );
535 QStringList Data;
536
537 if ( object_to_edit and not Object().is_null() )
538 {
539 std::vector<tref> DataList;
540
541 if ( config::api::info::relation::is_simple ( arelation ) )
542 {
543 try
544 {
545 DataList.push_back (
546 dbegraph::linked::through::relation<tref> ( Object(), arelation ) );
547 }
548 catch ( daq::dbe::config_object_retrieval_result_is_null const & e )
549 {
550 // nothing needs be done to handle cases that a relation has not been set
551 }
552 }
553 else
554 {
555 DataList = dbegraph::linked::through::relation<std::vector<tref>> ( Object(), arelation );
556 }
557
558 for ( tref const & i : DataList )
559 {
560 if ( not i.is_null() )
561 {
562 Data.push_back ( QString::fromStdString ( i.UID() ) );
563 }
564 }
565 }
566
567 widget->setdata ( Data );
568 widget->SetEditor();
569 set_tooltip ( arelation, widget );
570 register_relation_widget ( name, widget );
571 connect ( widget, SIGNAL ( signal_value_change() ), this, SLOT ( UpdateActions() ),
572 Qt::UniqueConnection );
573 connect ( widget, SIGNAL ( signal_value_change() ), this, SLOT ( ObjectChanged() ),
574 Qt::UniqueConnection );
575 connect ( widget, SIGNAL ( LoadedInitials() ), this, SLOT ( ResetObjectChanged() ),
576 Qt::UniqueConnection );
577 connect ( this, SIGNAL ( LoadedInitials() ), widget, SLOT ( slot_set_initial_loaded() ),
578 Qt::UniqueConnection );
580 emit LoadedInitials();
581 }
582}
583
584//------------------------------------------------------------------------------------------
585
586//------------------------------------------------------------------------------------------
588 widgets::editors::base * Widget )
589{
590 QString ToolTip;
591 ToolTip.append ( QString ( "Attribute Name: %1 \n" ).arg (
592 Attribute.p_name.c_str() ) );
593 ToolTip.append (
594 QString ( " Type: %1 \n" ).arg (
596 ToolTip.append ( QString ( " Range: %1 \n" ).arg (
597 Attribute.p_range.c_str() ) );
598 ToolTip.append (
599 QString ( " Format: %1 \n" ).arg (
601 ToolTip.append ( QString ( " Not Null: %1 \n" ).arg (
602 Attribute.p_is_not_null ) );
603 ToolTip.append (
604 QString ( " Is Multi Value: %1 \n" ).arg ( Attribute.p_is_multi_value ) );
605 ToolTip.append (
606 QString ( " Default Value: %1 \n" ).arg ( Attribute.p_default_value.c_str() ) );
607 ToolTip.append (
608 QString ( " Description: %1 \n" ).arg ( Attribute.p_description.c_str() ) );
609 Widget->setToolTip ( ToolTip );
610}
611
612//------------------------------------------------------------------------------------------
613
614//------------------------------------------------------------------------------------------
616 widgets::editors::base * widget )
617{
618 QString ToolTip;
619 ToolTip.append (
620 QString ( "Relationship Name: %1 \n" ).arg ( relation.p_name.c_str() ) );
621 ToolTip.append (
622 QString ( " Type: %1 \n" ).arg ( relation.p_type.c_str() ) );
623 ToolTip.append (
624 QString ( " Cardinality %1 \n" ).arg (
625 dunedaq::conffwk::relationship_t::card2str ( relation.p_cardinality ) ) );
626 ToolTip.append (
627 QString ( " Is Aggregation: %1 \n" ).arg ( relation.p_is_aggregation ) );
628 ToolTip.append (
629 QString ( " Description: %1 \n" ).arg ( relation.p_description.c_str() ) );
630 widget->setToolTip ( ToolTip );
631}
632
633//------------------------------------------------------------------------------------------
634
635//------------------------------------------------------------------------------------------
637 widgets::editors::base * Widget )
638{
639 {
640 QStringList values;
641
642 if ( not Widget->ischanged() and object_to_edit and not Object().is_null() )
643 {
644 values = dbe::config::api::get::attribute::list<QStringList> ( Object(), Attribute );
645 }
646 else
647 {
648 values = Widget->getdata();
649 }
650
651 Widget->setdata ( values );
652 }
653
654 {
655 QStringList defaults_values
657 Widget->setdefaults ( defaults_values.at ( 0 ) );
658
659 if ( this_is_in_creation_mode) {
660 Widget->setdata(defaults_values);
661 }
662 }
663
664 Widget->SetEditor();
665}
666
667//------------------------------------------------------------------------------------------
668
669//------------------------------------------------------------------------------------------
671 widgets::editors::base * widget )
672{
673 HorizontalHeaders.append(name);
674 WidgetTable->setCellWidget(CurrentRow, 0, widget);
675
676 if(dynamic_cast<widgets::editors::multiattr *>(widget)) {
677 WidgetTable->setRowHeight(CurrentRow, 100);
678 } else if(widgets::editors::stringattr * sa = dynamic_cast<widgets::editors::stringattr *>(widget)) {
679 QTextEdit* le = sa->GetLineEdit();
680 const auto& textSize = QFontMetrics(le->document()->defaultFont()).size(0, le->toPlainText());
681 WidgetTable->setRowHeight(CurrentRow, std::min(150, textSize.height() + 15));
682 } else {
683 WidgetTable->verticalHeader()->setSectionResizeMode(CurrentRow, QHeaderView::Fixed);
684 }
685
686 CurrentRow++;
687 this_widgets[name] = widget;
688}
689
690//------------------------------------------------------------------------------------------
691
692//------------------------------------------------------------------------------------------
694 widgets::editors::base * widget )
695{
696 HorizontalHeaders.append ( name );
697 WidgetTable->setCellWidget ( CurrentRow, 0, widget );
698
699 if(widgets::editors::relation * w = dynamic_cast<widgets::editors::relation *>(widget)) {
700 if(w->GetIsMultiValue() == true) {
701 WidgetTable->setRowHeight(CurrentRow, 100);
702 } else {
703 WidgetTable->verticalHeader()->setSectionResizeMode(CurrentRow, QHeaderView::Fixed);
704 }
705 }
706
707 CurrentRow++;
708 this_widgets[name] = widget;
709}
710
711//------------------------------------------------------------------------------------------
712
713//------------------------------------------------------------------------------------------
715{
716 if ( object_to_edit and not Object().is_null() )
717 {
718 QString FileName = QString ( Object().contained_in().c_str() );
719 QList<QStringList> FileCache = confaccessor::ref().GetIncludedFileCache();
720 QFileInfo FileInfo = QFileInfo ( FileName );
721
722 for ( QStringList File : FileCache )
723 {
724 if ( FileName.contains ( File.at ( 1 ) ) )
725 {
726 FilePermission = File.at ( 2 );
727 break;
728 }
729 }
730
731 ui->FileLabel->setText ( QString ( "File: %1" ).arg ( FileInfo.fileName() ) );
732 ui->DirLabel->setText ( QString ( "Dir: %1" ).arg ( FileInfo.absolutePath() ) );
733 ui->WriteLabel->setText ( QString ( "Permission: %1" ).arg ( FilePermission ) );
734 }
735}
736
737//------------------------------------------------------------------------------------------
738
739//------------------------------------------------------------------------------------------
740void dbe::ObjectEditor::closeEvent ( QCloseEvent * e )
741{
742 if ( not this_editor_is_owned and CanCloseWindow() )
743 {
744 e->accept();
745 }
746 else if ( this_editor_is_owned )
747 {
748 e->accept();
749 }
750 else
751 {
752 e->ignore();
753 }
754}
755
756//------------------------------------------------------------------------------------------
757
758//------------------------------------------------------------------------------------------
760{
761 int NotNullCounter = 0;
762 int NotValidCounter = 0;
763
764 QStringList NotValidList;
765
766 for ( auto & i : this_widgets )
767 {
768 std::shared_ptr<editor_data_state> Editor = i.second->dataeditor<editor_data_state>();
769
770 if ( Editor != nullptr )
771 {
772 if ( not Editor->is_valid() )
773 {
774 NotValidCounter++;
775 NotValidList.append ( i.first );
776 }
777
778 if ( Editor->must_not_be_null() )
779 {
780 NotNullCounter++;
781 }
782 }
783 }
784
785 QLabel * StatusLabel = new QLabel();
786 StatusLabel->setWordWrap ( true );
787 StatusLabel->setFrameStyle ( QFrame::NoFrame );
788
789 if ( NotValidCounter == 0 )
790 {
791 StatusLabel->setText (
792 QString ( "All minimal necessary attributes and relationships are set" ) );
793
794 if ( this_is_in_copy_mode or this_is_in_creation_mode or
795 confaccessor::check_file_rw ( QString::fromStdString ( Object().contained_in() ) ) )
796 {
797 ui->ApplyButton->setEnabled ( true );
798 }
799
800 IsValid = true;
801 }
802 else
803 {
804 QString MexHead = QString ( "From %1 NOT NULL attributes/relationships, %2 are not set: " )
805 .arg ( NotNullCounter ).arg ( NotValidCounter );
806 QString Mex = MexHead + NotValidList.join ( "," );
807 StatusLabel->setText ( Mex );
808
809 ui->ApplyButton->setEnabled ( false );
810 IsValid = false;
811 }
812
814 emit WidgetUpdated();
815}
816
817//------------------------------------------------------------------------------------------
818
819//------------------------------------------------------------------------------------------
821{
822 this_editor_values_changed = true;
823
824 if ( IsValid and (this_is_in_creation_mode
825 or confaccessor::check_file_rw ( QString::fromStdString ( Object().contained_in() ) ) ))
826 {
827 ui->ApplyButton->setEnabled ( true );
828 }
829}
830
832{
833 this_editor_values_changed = false;
834 ui->ApplyButton->setEnabled ( false );
835}
836
837//------------------------------------------------------------------------------------------
838
839//------------------------------------------------------------------------------------------
841{
842 if ( FilePermission != "RO" )
843 {
844 if ( not IsValid )
845 {
846 ERROR ( "Changes cannot be applied for object", "Changes are invalid", "with UID:",
847 Object().UID(), "of class:", Object().class_name() );
848 return;
849 }
850
851 for ( auto const & i : this_widgets )
852 {
853 widgets::editors::base * ceditor = i.second;
854 bool Changed = ceditor->ischanged();
855
856 if ( Changed || this_is_in_copy_mode )
857 {
858 QStringList DataList = ceditor->getdata();
859
860 if ( auto attreditor = ceditor->dataeditor<editor_data<dunedaq::conffwk::attribute_t>>() )
861 {
862 dunedaq::conffwk::attribute_t Attribute = attreditor->get();
863
864 dbe::config::api::set::attribute ( Object(), Attribute, DataList );
865 ceditor->setdata ( DataList );
866 ceditor->setchanged ( false );
867 }
868 else if ( auto releditor =
870 {
871 dunedaq::conffwk::relationship_t Relationship = releditor->get();
872 dbe::config::api::set::relation ( Object(), Relationship, DataList );
873 ceditor->setdata ( DataList );
874 ceditor->setchanged ( false );
875 }
876 }
877 }
878
879 ui->ApplyButton->setDisabled ( true );
880 this_editor_values_changed = false;
881 }
882 else
883 {
884 ERROR ( "Changes cannot be applied", "File access permission error" );
885 }
886}
887
888//------------------------------------------------------------------------------------------
889
890//------------------------------------------------------------------------------------------
892{
893 if ( RenameWidget == nullptr )
894 {
895 RenameWidget = new QDialog ( this );
896 RenameWidget->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::Preferred );
897 RenameWidget->setToolTip ( "Type string to edit line and press Enter." );
898 RenameWidget->setWindowTitle ( "Choose a new object id" );
899
900 QHBoxLayout * Layout = new QHBoxLayout ( RenameWidget );
901 QLabel * Label = new QLabel ( QString ( "Rename Object:" ), RenameWidget );
902 GoButton = new QPushButton ( "Rename !" );
903
904 LineEdit = new QLineEdit ( RenameWidget );
905 LineEdit->setToolTip ( "Type string and press Enter" );
906
907 Layout->addWidget ( Label );
908 Layout->addWidget ( LineEdit );
909 Layout->addWidget ( GoButton );
910 RenameWidget->setLayout ( Layout );
911
912 connect ( LineEdit, SIGNAL ( returnPressed() ), this, SLOT ( RenameObject() ) );
913 connect ( GoButton, SIGNAL ( clicked() ), this, SLOT ( RenameObject() ) );
914 connect ( &confaccessor::ref(), SIGNAL ( object_renamed ( QString, dref ) ), this,
915 SLOT ( slot_external_rename_object ( QString, dref ) ) );
916 }
917
918 RenameWidget->show();
919}
920
922{
923 if ( MoveWidget == nullptr )
924 {
925 MoveWidget = new QDialog ( this );
926 MoveWidget->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::Preferred );
927 MoveWidget->setToolTip ( "Choose file and press Move." );
928 MoveWidget->setWindowTitle ( "Choose new file for object" );
929
930 QVBoxLayout * Layout = new QVBoxLayout ( MoveWidget );
931 QLabel * Label = new QLabel ( QString ( "Choose new file" ), MoveWidget );
932 MoveGoButton = new QPushButton ( "Move !" );
933
934 if ( IncludedFileModel == nullptr )
935 {
936 QList<QStringList> List = confaccessor::ref().GetIncludedFileCache();
937 IncludedFileModel = new FileModel ( List );
938 }
939
940 FileView = new CustomFileView ( MoveWidget );
941 FileView->setModel ( IncludedFileModel );
942 FileView->horizontalHeader()->setSectionResizeMode ( QHeaderView::Stretch );
943
944 Layout->addWidget ( Label );
945 Layout->addWidget ( FileView );
946 Layout->addWidget ( MoveGoButton );
947
948 MoveWidget->setLayout ( Layout );
949 connect ( FileView, SIGNAL ( stateChanged ( const QString & ) ), this,
950 SLOT ( ActiveFileChanged ( const QString & ) ), Qt::UniqueConnection );
951 connect ( MoveGoButton, SIGNAL ( clicked() ), this, SLOT ( MoveObject() ) );
952 }
953
954 MoveWidget->show();
955}
956
957//------------------------------------------------------------------------------------------
958
959//------------------------------------------------------------------------------------------
961{
962 std::string newname = LineEdit->text().toStdString();
963 dbe::config::api::commands::renobj ( Object(), newname, uuid );
964 RenameWidget->close();
965}
966
968 dref const & obj )
969{
970 // Rename can only occur by undoing a command issued from an ObjectEditor therefore
971 // the uuid and src have to be equal. We also check the UID
972
973 if ( src == uuid.toString() )
974 {
975 ui->ClassLabel->setText (
976 QString ( "Object : %1@%2" ).arg ( Object().UID().c_str() ).arg (
977 Object().class_name().c_str() ) );
978 setWindowTitle (
979 QString ( "Edit Object %1 of Class %2" ).arg ( Object().UID().c_str() ).arg (
980 Object().class_name().c_str() ) );
981 setObjectName (
982 QString ( "%1@%2" ).arg ( Object().UID().c_str() ).arg ( Object().class_name().c_str() ) );
983 }
984}
985
987{
988 if ( dbe::config::api::commands::movobj ( Object(), ActivateFile.toStdString(), uuid ) )
989 {
990 ui->FileLabel->setText ( QString ( "File: %1" ).arg ( Object().contained_in().c_str() ) );
991 }
992
993 MoveWidget->close();
994}
995
996void dbe::ObjectEditor::ActiveFileChanged ( const QString & File )
997{
998 if ( File.isEmpty() )
999 {
1000 return;
1001 }
1002
1003 ActivateFile = File;
1004}
1005
1006//------------------------------------------------------------------------------------------
1007
1008//------------------------------------------------------------------------------------------
1009bool dbe::ObjectEditor::ParseToCreate ( std::string const & objectname,
1010 std::string const & filename )
1011{
1012 if ( not config::api::info::has_obj ( classname, objectname ) )
1013 {
1014 try
1015 {
1018
1019 // Build [attribute , new values ] map and [ relation , new relations ] map
1020 // by looping through all widgets contained in this objects
1021
1022 for ( auto const & awidget : this_widgets )
1023 {
1024 widgets::editors::base * editor = awidget.second;
1025
1026 // Retrieve data held by the editor
1027 QStringList editordata = editor->getdata();
1028
1029 if ( std::shared_ptr<editor_data<dunedaq::conffwk::attribute_t>> accessor =
1031 {
1032 dunedaq::conffwk::attribute_t attribute = accessor->get();
1033
1034 /*
1035 * Convert to the preimage value type
1036 */
1037
1038 for ( auto const & element : editordata )
1039 {
1040 object_attributes[attribute.p_name].push_back ( element.toStdString() );
1041 }
1042 }
1043 else if ( std::shared_ptr<editor_data<dunedaq::conffwk::relationship_t>> accessor =
1045 {
1046 dunedaq::conffwk::relationship_t relation = accessor->get();
1047
1048 /*
1049 * Convert to the preimage value type
1050 */
1051
1052 for ( auto const & element : editordata )
1053 {
1054 object_relations[relation.p_name].push_back (
1055 { element.toStdString(), relation.p_type } );
1056 }
1057 }
1058
1059 // editor->SetValueList(editordata);
1060 editor->setchanged ( false );
1061 }
1062
1064 filename, classname, objectname,
1065 object_attributes, object_relations, uuid );
1066
1067 }
1068 catch ( daq::dbe::ObjectChangeWasNotSuccessful const & e )
1069 {
1070 ERROR ( "Object creation did not complete successfully", dbe::config::errors::parse ( e ) );
1071 return false;
1072 }
1073 catch ( dunedaq::conffwk::Exception const & e )
1074 {
1075 ERROR ( "Object could not be created", dbe::config::errors::parse ( e ) );
1076 return false;
1077 }
1078
1079 return true;
1080 }
1081 else
1082 {
1083 ERROR ( "Object cannot be created for", "Object already exists", "with name (UID):",
1084 objectname, " in class ", classname );
1085 return false;
1086 }
1087}
1088
1090{
1091 this_is_in_copy_mode = Used;
1092}
1093
1094//------------------------------------------------------------------------------------------
static MainWindow * findthis()
QTableWidget * WidgetTable
void set_attribute_widget(dunedaq::conffwk::attribute_t const &, widgets::editors::base *)
bool IsEditorValid() const
void slot_external_rename_object(QString const &src, dref const &obj)
bool WasObjectChanged() const
void SetUsedForCopy(bool Used)
std::unique_ptr< dbe::Ui::ObjectEditor > ui
bool ParseToCreate(std::string const &name, std::string const &filename)
void set_tooltip(dunedaq::conffwk::attribute_t const &, widgets::editors::base *)
void ShouldCloseThisWindow(QString const src, dref const)
QStringList HorizontalHeaders
void register_attribute_widget(QString const &name, widgets::editors::base *widget)
void HideDetailWidget(bool Hide)
void register_relation_widget(QString const &name, widgets::editors::base *widget)
void ActiveFileChanged(const QString &File)
void closeEvent(QCloseEvent *Event)
ObjectEditor(std::string const &classname, QWidget *parent=nullptr)
std::string classname
QList< QStringList > GetIncludedFileCache() const
static bool check_file_rw(const QString &FileName)
static confaccessor & ref()
static T list(dbe::inner::configobject::tref obj, dunedaq::conffwk::attribute_t const &attr)
static dunedaq::conffwk::class_t definition(std::string const &cn, bool direct_only)
static configobject::tref get(dbe::cokey const &desc)
virtual void setdata(QStringList const &)
virtual void SetEditor()=0
virtual void setdefaults(QString const &)
#define ERROR(...)
Definition messenger.hpp:88
void newobj(std::string const &fn, std::string const &class_name, std::string const &UID, dbe::t_config_object_preimage::type_attrmap const &attributes, dbe::t_config_object_preimage::type_relmap const &relations, QUuid const &src)
bool renobj(inner::configobject::tref obj, std::string const &newuuid, QUuid const &src)
bool movobj(inner::configobject::tref obj, std::string const &destination, QUuid const &src)
tref relation< tref >(tref object, dunedaq::conffwk::relationship_t const &r)
bool is_simple(dunedaq::conffwk::relationship_t const &)
bool has_obj(std::string const &classname, std::string const &object_uid)
void relation(dbe::inner::configobject::tref src, dunedaq::conffwk::relationship_t const &edge, QStringList const &targets)
void attribute(dbe::inner::configobject::tref objectref, dunedaq::conffwk::attribute_t const &attribute_info, QStringList const &attribute_values)
std::string const parse(ers::Issue const &)
static QStringList value(dunedaq::conffwk::attribute_t const &)
M< type_str, type_attributes > type_attrmap
M< type_str, type_images > type_relmap
static const char * type2str(type_t type)
static const char * format2str(int_format_t format)
const std::vector< attribute_t > p_attributes
Definition Schema.hpp:163
const std::vector< relationship_t > p_relationships
Definition Schema.hpp:164
static const char * card2str(cardinality_t cardinality)