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/BatchChangeWidget.hpp"
7 :
8 : #include "ui_BatchChangeWidget.h"
9 :
10 : #include "dbe/MainWindow.hpp"
11 : #include "dbe/config_api.hpp"
12 : #include "dbe/config_api_get.hpp"
13 : #include "dbe/config_api_graph.hpp"
14 : #include "dbe/config_api_set.hpp"
15 : #include "dbe/messenger.hpp"
16 :
17 : #include <QApplication>
18 : #include <boost/scope_exit.hpp>
19 :
20 : namespace dbegraph = dbe::config::api::graph;
21 :
22 0 : dbe::BatchChangeWidget::~BatchChangeWidget() = default;
23 :
24 0 : dbe::BatchChangeWidget::BatchChangeWidget(QWidget* parent)
25 : : QWidget(parent)
26 0 : , ui(new Ui::BatchChangeWidget)
27 0 : , UseTable(false)
28 0 : , ClassChanged(true)
29 0 : , TableClass("")
30 0 : , m_filter_table(nullptr)
31 : {
32 0 : ui->setupUi(this);
33 0 : ui->TitleLabel->setStyleSheet(
34 : "QLabel { background-color:green; color:beige; font:bold14px; border-style:outset; border-width:2px;"
35 : "border-radius:10px; border-color:beige; font:bold14px; min-width:10em; padding:6px}");
36 0 : ui->FirstStepLabel->setStyleSheet("QLabel { color:#DB5816; font: bold 14px;}");
37 0 : ui->SecondStepLabel->setStyleSheet("QLabel { color:#DE8A14; font: bold 14px;}");
38 0 : ui->ThirdStepLabel->setStyleSheet("QLabel { color:#8DAA2E; font: bold 14px;}");
39 0 : setWindowTitle("Batch Change");
40 :
41 0 : QStringList ListOfClasses(dbe::config::api::info::onclass::allnames<QStringList>());
42 0 : ui->ClassCombo->addItems(ListOfClasses);
43 0 : ui->ClassCombo->setEditable(true);
44 0 : ui->ClassCombo->setEditText("Type/Select Classes");
45 :
46 0 : ui->AttributeBox->setEnabled(false);
47 0 : ui->RelationshipBox->setEnabled(false);
48 0 : ui->NewAttributeGroupBox->setEnabled(false);
49 0 : ui->NewRelationshipGroupBox->setEnabled(false);
50 0 : ui->MatchButton->setEnabled(false);
51 0 : ui->FilterUid->setText("*");
52 0 : ui->AttributeValueFilter->setText("*");
53 :
54 0 : SetController();
55 0 : }
56 :
57 0 : dbe::BatchChangeWidget::BatchChangeWidget(bool ObjectsFromTable,
58 : QString ClassName,
59 : std::vector<dref>& Objects,
60 0 : QWidget* parent)
61 0 : : BatchChangeWidget(parent)
62 : {
63 0 : ClassChanged = false;
64 :
65 0 : TableObjects = Objects;
66 0 : UseTable = ObjectsFromTable;
67 0 : TableClass = ClassName;
68 :
69 0 : ui->ClassCombo->setCurrentIndex(ui->ClassCombo->findText(TableClass));
70 0 : ui->SubclassesCheckBox->setEnabled(false);
71 0 : FillInfo(TableClass);
72 :
73 0 : if (UseTable) {
74 0 : setWindowTitle("Batch change - Table");
75 0 : ui->FilterGroupBox->hide();
76 0 : ui->Label1->hide();
77 0 : ui->Label2->hide();
78 0 : ui->FirstStepLabel->hide();
79 0 : ui->SecondStepLabel->hide();
80 0 : ui->ThirdStepLabel->hide();
81 0 : ui->Line1->hide();
82 0 : ui->Line2->hide();
83 0 : ui->TitleLabel->setText("Batch Change of multiple objects - Table");
84 0 : resize(540, 280);
85 : }
86 0 : }
87 :
88 : void
89 0 : dbe::BatchChangeWidget::SetController()
90 : {
91 0 : connect(ui->ClassCombo, SIGNAL(activated(QString)), this, SLOT(FillInfo(const QString&)));
92 :
93 0 : connect(ui->ChangeButton, SIGNAL(clicked()), this, SLOT(MakeChanges()));
94 :
95 0 : connect(ui->MatchButton, SIGNAL(clicked()), this, SLOT(FindMatching()));
96 :
97 0 : connect(ui->NewRelationshipComboBox, SIGNAL(activated(QString)), this, SLOT(EnableCheckBox(QString)));
98 0 : connect(ui->CancelButton, SIGNAL(clicked()), this, SLOT(close()));
99 :
100 0 : connect(ui->RelationshipComboBox, SIGNAL(activated(int)), this, SLOT(UpdateRelationshipFilter(int)));
101 :
102 0 : connect(ui->NewRelationshipComboBox, SIGNAL(activated(int)), this, SLOT(UpdateRelationshipNewValues(int)));
103 :
104 0 : MainWindow* mainwin = MainWindow::findthis();
105 :
106 0 : if (mainwin != nullptr) {
107 0 : connect(this, SIGNAL(sig_batch_change_start()), mainwin, SLOT(slot_batch_change_start()), Qt::UniqueConnection);
108 0 : connect(this,
109 : SIGNAL(sig_batch_change_stop(const QList<QPair<QString, QString>>&)),
110 : mainwin,
111 : SLOT(slot_batch_change_stop(const QList<QPair<QString, QString>>&)),
112 : Qt::UniqueConnection);
113 : }
114 0 : }
115 :
116 : void
117 0 : dbe::BatchChangeWidget::keyPressEvent(QKeyEvent* event)
118 : {
119 0 : if (event->key() == Qt::Key_Escape) {
120 0 : close();
121 : }
122 0 : QWidget::keyPressEvent(event);
123 0 : }
124 :
125 : void
126 0 : dbe::BatchChangeWidget::filter(std::vector<dref>& objs, const QString& cname)
127 : {
128 :
129 0 : dunedaq::conffwk::class_t const& cinfo = dbe::config::api::info::onclass::definition(cname.toStdString(), false);
130 0 : std::vector<dunedaq::conffwk::attribute_t> const& attributes = cinfo.p_attributes;
131 0 : std::vector<dunedaq::conffwk::relationship_t> const& relations = cinfo.p_relationships;
132 :
133 : // Filtering UID
134 0 : std::vector<dref> filtered;
135 :
136 0 : if (!ui->FilterUid->text().isEmpty()) {
137 0 : QRegExp uidfilter(ui->FilterUid->text());
138 0 : uidfilter.setPatternSyntax(QRegExp::Wildcard);
139 :
140 0 : for (dbe::dref const& it : objs) {
141 :
142 0 : if (uidfilter.exactMatch(QString::fromStdString(it.ref().UID()))) {
143 0 : filtered.push_back(it);
144 : }
145 : }
146 :
147 0 : objs = filtered;
148 0 : filtered.clear();
149 0 : }
150 :
151 : /// Filtering Attributes
152 0 : QRegExp attribute_filter(ui->AttributeValueFilter->text());
153 0 : attribute_filter.setPatternSyntax(QRegExp::Wildcard);
154 :
155 0 : std::string selected_attribute_name = ui->AttributeComboBox->currentText().toStdString();
156 :
157 0 : std::vector<dunedaq::conffwk::attribute_t>::const_iterator attrdef =
158 0 : std::find_if(std::begin(attributes),
159 : std::end(attributes),
160 0 : [&selected_attribute_name](dunedaq::conffwk::attribute_t const& attr) {
161 0 : return attr.p_name == selected_attribute_name;
162 : });
163 :
164 0 : if (attrdef != std::end(attributes)) {
165 0 : for (dbe::dref const& it : objs) {
166 0 : QStringList values{ dbe::config::api::get::attribute::list<QStringList>(it.ref(), *attrdef) };
167 :
168 0 : for (QString& v : values)
169 0 : if (attribute_filter.exactMatch(v)) {
170 0 : filtered.push_back(it);
171 : break;
172 : }
173 0 : }
174 : }
175 :
176 0 : objs = filtered;
177 0 : filtered.clear();
178 :
179 : // Filter on Relationship
180 :
181 0 : std::string selected_relation_name = ui->RelationshipComboBox->currentText().toStdString();
182 :
183 0 : std::vector<dunedaq::conffwk::relationship_t>::const_iterator relationdef = std::find_if(
184 0 : std::begin(relations), std::end(relations), [&selected_relation_name](dunedaq::conffwk::relationship_t const& rel) {
185 0 : return rel.p_name == selected_relation_name;
186 : });
187 :
188 0 : if (relationdef != std::end(relations)) {
189 0 : QRegExp relation_filter(ui->RelationshipValueFilter->currentText());
190 0 : relation_filter.setPatternSyntax(QRegExp::Wildcard);
191 :
192 0 : for (dbe::dref const& it : objs) {
193 0 : QStringList ValueList{ dbegraph::linked::through::relation<QStringList>(it.ref(), *relationdef) };
194 :
195 0 : if (ValueList.isEmpty() and
196 0 : (ui->RelationshipValueFilter->currentText() == "*" or ui->RelationshipValueFilter->currentText() == "")) {
197 0 : filtered.push_back(it);
198 : } else {
199 0 : for (QString const& v : ValueList)
200 0 : if (relation_filter.exactMatch(v)) {
201 0 : filtered.push_back(it);
202 : break;
203 : }
204 : }
205 0 : }
206 0 : }
207 :
208 0 : objs = filtered;
209 0 : filtered.clear();
210 0 : }
211 :
212 : void
213 0 : dbe::BatchChangeWidget::FillInfo(const QString& Name)
214 : {
215 0 : ui->AttributeBox->setEnabled(false);
216 0 : ui->RelationshipBox->setEnabled(false);
217 0 : ui->NewAttributeGroupBox->setEnabled(false);
218 0 : ui->NewRelationshipGroupBox->setEnabled(false);
219 :
220 0 : const dunedaq::conffwk::class_t& ClassInfo = dbe::config::api::info::onclass::definition(Name.toStdString(), false);
221 0 : const std::vector<dunedaq::conffwk::attribute_t> AttributeList = ClassInfo.p_attributes;
222 0 : const std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfo.p_relationships;
223 :
224 0 : QStringList ValueList;
225 :
226 0 : for (dunedaq::conffwk::attribute_t Attribute : AttributeList) {
227 0 : ValueList.append(QString(Attribute.p_name.c_str()));
228 0 : }
229 :
230 0 : ui->AttributeComboBox->clear();
231 0 : ui->NewAttributeComboBox->clear();
232 0 : ui->AttributeComboBox->addItems(ValueList);
233 0 : ui->NewAttributeComboBox->addItems(ValueList);
234 :
235 0 : if (!AttributeList.empty() && !UseTable) {
236 0 : ui->AttributeBox->setEnabled(true);
237 0 : ui->NewAttributeGroupBox->setEnabled(true);
238 0 : ui->MatchButton->setEnabled(true);
239 : }
240 :
241 0 : if (!AttributeList.empty() && UseTable) {
242 0 : ui->NewAttributeGroupBox->setEnabled(true);
243 : }
244 :
245 0 : ValueList.clear();
246 :
247 0 : for (dunedaq::conffwk::relationship_t Relationship : RelationshipList) {
248 0 : ValueList.append(QString(Relationship.p_name.c_str()));
249 0 : }
250 :
251 0 : ui->RelationshipComboBox->clear();
252 0 : ui->NewRelationshipComboBox->clear();
253 0 : ui->RelationshipComboBox->addItems(ValueList);
254 0 : ui->NewRelationshipComboBox->addItems(ValueList);
255 :
256 0 : if (!RelationshipList.empty() && !UseTable) {
257 0 : ui->RelationshipBox->setEnabled(true);
258 0 : ui->NewRelationshipGroupBox->setEnabled(true);
259 0 : ui->MatchButton->setEnabled(true);
260 : }
261 :
262 0 : if (!RelationshipList.empty() && UseTable) {
263 0 : ui->NewRelationshipGroupBox->setEnabled(true);
264 : }
265 :
266 0 : if (!UseTable) {
267 0 : UpdateRelationshipFilter(0);
268 0 : UpdateRelationshipNewValues(0);
269 0 : ui->RelationshipValueFilter->setCurrentIndex(0);
270 0 : ui->RelationshipEdit->setCurrentIndex(-1);
271 : } else {
272 0 : UpdateRelationshipNewValues(0);
273 0 : ui->RelationshipEdit->setCurrentIndex(-1);
274 : }
275 :
276 0 : if (ClassChanged) {
277 0 : UseTable = false;
278 : }
279 :
280 0 : ClassChanged = true;
281 0 : }
282 :
283 : void
284 0 : dbe::BatchChangeWidget::MakeChanges()
285 : {
286 0 : std::vector<dref> Objects;
287 :
288 0 : BOOST_SCOPE_EXIT(&Objects, this_)
289 : {
290 0 : QList<QPair<QString, QString>> objs;
291 0 : for (const auto& o : Objects) {
292 0 : objs.append(QPair<QString, QString>(QString::fromStdString(o.class_name()), QString::fromStdString(o.UID())));
293 : }
294 :
295 0 : this_->emit sig_batch_change_stop(objs);
296 :
297 0 : QApplication::restoreOverrideCursor();
298 0 : this_->ui->ChangeButton->setEnabled(true);
299 0 : confaccessor::ref().blockSignals(false);
300 0 : }
301 0 : BOOST_SCOPE_EXIT_END
302 :
303 0 : ui->ChangeButton->setEnabled(false);
304 0 : QApplication::setOverrideCursor(Qt::WaitCursor);
305 0 : confaccessor::ref().blockSignals(true);
306 :
307 0 : bool SubClasses = ui->SubclassesCheckBox->isChecked();
308 0 : QString ClassName = ui->ClassCombo->currentText();
309 :
310 0 : std::unique_ptr<dbe::interface::messenger::batch_guard> batchmode(interface::messenger::qt::batchmode());
311 :
312 0 : emit sig_batch_change_start();
313 :
314 0 : if (not UseTable) {
315 0 : std::vector<tref> const& tmprefs = dbe::config::api::info::onclass::objects(ClassName.toStdString(), SubClasses);
316 :
317 0 : std::copy(tmprefs.begin(), tmprefs.end(), std::back_inserter(Objects));
318 :
319 0 : if (not Objects.empty()) {
320 0 : filter(Objects, ClassName);
321 : }
322 0 : } else {
323 0 : Objects = TableObjects;
324 : }
325 :
326 0 : if (Objects.empty())
327 0 : QMessageBox::information(this, tr("Message"), tr("No objects match filter!"));
328 : else {
329 0 : const dunedaq::conffwk::class_t& ClassInfo =
330 0 : dbe::config::api::info::onclass::definition(ClassName.toStdString(), false);
331 0 : const std::vector<dunedaq::conffwk::attribute_t> AttributeList = ClassInfo.p_attributes;
332 0 : const std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfo.p_relationships;
333 0 : dunedaq::conffwk::attribute_t AttributeChange;
334 0 : dunedaq::conffwk::relationship_t RelationshipChange;
335 :
336 0 : for (dunedaq::conffwk::attribute_t i : AttributeList)
337 0 : if (i.p_name == ui->NewAttributeComboBox->currentText().toStdString()) {
338 0 : AttributeChange = i;
339 0 : break;
340 0 : }
341 :
342 0 : for (dunedaq::conffwk::relationship_t i : RelationshipList)
343 0 : if (i.p_name == ui->NewRelationshipComboBox->currentText().toStdString()) {
344 0 : RelationshipChange = i;
345 0 : break;
346 0 : }
347 :
348 0 : QStringList AttributeChangeList;
349 :
350 0 : if (!ui->AttributeEdit->text().isEmpty())
351 0 : AttributeChangeList << ui->AttributeEdit->text();
352 :
353 0 : for (auto objects_iter = Objects.begin(); objects_iter != Objects.end(); ++objects_iter) {
354 0 : tref Object = objects_iter->ref();
355 :
356 0 : QStringList RelationshipChangeList;
357 :
358 0 : if (ui->ChangeAtrributeCheckBox->isChecked()) {
359 0 : if (!AttributeChangeList.isEmpty()) {
360 0 : dbe::config::api::set::attribute(Object, AttributeChange, AttributeChangeList);
361 : }
362 : }
363 :
364 0 : if (ui->ChangeRelationshipCheckBox->isChecked()) {
365 0 : if (ui->AddCheckBox->isChecked()) {
366 0 : RelationshipChangeList = dbegraph::linked::through::relation<QStringList>(Object, RelationshipChange);
367 : }
368 :
369 0 : RelationshipChangeList << ui->RelationshipEdit->currentText();
370 0 : dbe::config::api::set::relation(Object, RelationshipChange, RelationshipChangeList);
371 : }
372 0 : }
373 0 : }
374 0 : }
375 :
376 : void
377 0 : dbe::BatchChangeWidget::FindMatching()
378 : {
379 0 : QString ClassName = ui->ClassCombo->currentText();
380 0 : bool SubClasses = ui->SubclassesCheckBox->isChecked();
381 :
382 0 : std::vector<tref> const& tmprefs = dbe::config::api::info::onclass::objects(ClassName.toStdString(), SubClasses);
383 :
384 0 : std::vector<dref> candidates;
385 0 : std::copy(tmprefs.begin(), tmprefs.end(), std::back_inserter(candidates));
386 :
387 0 : if (!candidates.empty()) {
388 0 : filter(candidates, ClassName);
389 : }
390 :
391 0 : if (candidates.empty()) {
392 0 : QMessageBox::information(this, tr("Message"), tr("No objects match filter!"));
393 : } else {
394 0 : int NumberOfColumns = 1;
395 0 : bool AttributeEnabled = false;
396 0 : bool RelationshipEnabled = false;
397 :
398 0 : if (ui->AttributeComboBox->isEnabled()) {
399 0 : AttributeEnabled = true;
400 0 : NumberOfColumns++;
401 : }
402 :
403 0 : if (ui->RelationshipComboBox->isEnabled()) {
404 0 : RelationshipEnabled = true;
405 0 : NumberOfColumns++;
406 : }
407 :
408 0 : m_filter_table = std::unique_ptr<QTableWidget>(new QTableWidget());
409 0 : m_filter_table->setWindowTitle(tr("Objects matching filter"));
410 0 : m_filter_table->setColumnCount(NumberOfColumns);
411 0 : m_filter_table->setRowCount(candidates.size());
412 :
413 0 : for (size_t i = 0; i < candidates.size(); i++) {
414 0 : QTableWidgetItem* AttributeValue;
415 0 : QTableWidgetItem* RelationshipValue;
416 :
417 0 : QTableWidgetItem* ObjectUid = new QTableWidgetItem(
418 0 : tr("%1@%2").arg(candidates.at(i).UID().c_str()).arg(candidates.at(i).class_name().c_str()));
419 0 : m_filter_table->setItem(i, 0, ObjectUid);
420 :
421 0 : if (AttributeEnabled) {
422 0 : dunedaq::conffwk::attribute_t Attribute =
423 0 : dbe::config::api::info::attributematch(ui->AttributeComboBox->currentText(), ClassName);
424 :
425 0 : QStringList AttributeValueList{ dbe::config::api::get::attribute::list<QStringList>(candidates.at(i).ref(),
426 0 : Attribute) };
427 :
428 0 : AttributeValue = new QTableWidgetItem(AttributeValueList.join(" "));
429 0 : m_filter_table->setItem(i, 1, AttributeValue);
430 0 : }
431 :
432 0 : if (RelationshipEnabled) {
433 0 : dunedaq::conffwk::relationship_t Relationship =
434 0 : config::api::info::relation::match(ui->RelationshipComboBox->currentText(), ClassName);
435 :
436 0 : QStringList RelationshipList{ dbegraph::linked::through::relation<QStringList>(candidates.at(i).ref(),
437 0 : Relationship) };
438 :
439 0 : RelationshipValue = new QTableWidgetItem(RelationshipList.join(" "));
440 0 : m_filter_table->setItem(i, 2, RelationshipValue);
441 0 : }
442 : }
443 :
444 0 : QStringList Headers;
445 0 : Headers << "Object Id";
446 :
447 0 : if (AttributeEnabled) {
448 0 : Headers << ui->AttributeComboBox->currentText();
449 : }
450 :
451 0 : if (RelationshipEnabled) {
452 0 : Headers << ui->RelationshipComboBox->currentText();
453 : }
454 :
455 0 : m_filter_table->setHorizontalHeaderLabels(Headers);
456 :
457 0 : QHeaderView* HeaderView = m_filter_table->horizontalHeader();
458 0 : HeaderView->setStretchLastSection(true);
459 0 : m_filter_table->resize(500, 300);
460 0 : m_filter_table->show();
461 0 : }
462 0 : }
463 :
464 : void
465 0 : dbe::BatchChangeWidget::EnableCheckBox(QString RelationshipName)
466 : {
467 0 : QString ClassName = ui->ClassCombo->currentText();
468 0 : const dunedaq::conffwk::class_t& ClassInfo =
469 0 : dbe::config::api::info::onclass::definition(ClassName.toStdString(), false);
470 0 : std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfo.p_relationships;
471 :
472 0 : for (dunedaq::conffwk::relationship_t& i : RelationshipList) {
473 0 : if (i.p_name == RelationshipName.toStdString()) {
474 0 : if ((i.p_cardinality == dunedaq::conffwk::zero_or_many) || (i.p_cardinality == dunedaq::conffwk::one_or_many)) {
475 0 : ui->AddCheckBox->setEnabled(true);
476 : } else {
477 0 : ui->AddCheckBox->setEnabled(false);
478 : }
479 :
480 : break;
481 : }
482 : }
483 0 : }
484 :
485 : void
486 0 : dbe::BatchChangeWidget::UpdateRelationshipFilter(int)
487 : {
488 0 : ui->RelationshipValueFilter->clear();
489 0 : ui->RelationshipValueFilter->addItem("*");
490 :
491 0 : QString ClassName = ui->ClassCombo->currentText();
492 0 : QString RelationshipName = ui->RelationshipComboBox->currentText();
493 :
494 0 : const dunedaq::conffwk::class_t& ClassInfo =
495 0 : dbe::config::api::info::onclass::definition(ClassName.toStdString(), false);
496 0 : std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfo.p_relationships;
497 :
498 0 : if (RelationshipList.size() != 0) {
499 0 : dunedaq::conffwk::relationship_t ChosenRelationship;
500 :
501 0 : for (dunedaq::conffwk::relationship_t& i : RelationshipList) {
502 0 : if (i.p_name == RelationshipName.toStdString()) {
503 0 : ChosenRelationship = i;
504 : break;
505 : }
506 : }
507 :
508 0 : std::vector<tref> const& Objects = dbe::config::api::info::onclass::objects(ChosenRelationship.p_type);
509 :
510 0 : QStringList ObjectsUid;
511 :
512 0 : for (tref const& Object : Objects) {
513 0 : ObjectsUid.append(Object.UID().c_str());
514 : }
515 :
516 0 : ui->RelationshipValueFilter->addItems(ObjectsUid);
517 0 : }
518 0 : }
519 :
520 : void
521 0 : dbe::BatchChangeWidget::UpdateRelationshipNewValues(int)
522 : {
523 0 : ui->RelationshipEdit->clear();
524 :
525 0 : QString ClassName = ui->ClassCombo->currentText();
526 0 : QString RelationshipName = ui->NewRelationshipComboBox->currentText();
527 :
528 0 : const dunedaq::conffwk::class_t& ClassInfo =
529 0 : dbe::config::api::info::onclass::definition(ClassName.toStdString(), false);
530 0 : std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfo.p_relationships;
531 :
532 0 : if (RelationshipList.size() != 0) {
533 0 : dunedaq::conffwk::relationship_t ChosenRelationship;
534 :
535 0 : for (dunedaq::conffwk::relationship_t& i : RelationshipList) {
536 0 : if (i.p_name == RelationshipName.toStdString()) {
537 0 : ChosenRelationship = i;
538 : break;
539 : }
540 : }
541 :
542 0 : std::vector<tref> const& Objects = dbe::config::api::info::onclass::objects(ChosenRelationship.p_type);
543 :
544 0 : QStringList ObjectsUid;
545 :
546 0 : for (tref const& Object : Objects) {
547 0 : ObjectsUid.append(Object.UID().c_str());
548 : }
549 :
550 0 : ui->RelationshipEdit->addItems(ObjectsUid);
551 0 : }
552 0 : }
|