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