DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
FileInfo.cpp
Go to the documentation of this file.
1#include "dbe/FileInfo.hpp"
2#include "dbe/MainWindow.hpp"
6#include "dbe/config_api.hpp"
8
9#include "ui_FileInfo.h"
10
11#include <QFileDialog>
12#include <QInputDialog>
13#include <QListWidgetItem>
14#include <QMessageBox>
15#include <QScopedValueRollback>
16#include <QString>
17#include <QWidget>
18
20
21namespace dbe {
22
23QString FileInfo::s_schema_path{ "." };
24QString FileInfo::s_data_path{ "." };
25QStringList FileInfo::s_path_list{};
26QList<QUrl> FileInfo::s_path_urls{};
27std::map<QString, std::map<QString, const tref>> FileInfo::s_obj_map{};
28std::map<QString, std::set<QString>> FileInfo::s_missing_schema_map{};
29std::map<QString, std::set<QString>> FileInfo::s_missing_data_map{};
30
31void
33{
34 QString DUNEDAQ_DB_PATH = getenv("DUNEDAQ_DB_PATH");
35 s_path_list.clear();
36 s_path_urls.clear();
37 auto path_list = DUNEDAQ_DB_PATH.split(QLatin1Char(':'), Qt::SkipEmptyParts);
38 for (QString& path : path_list) {
39 char* rpath = realpath(path.toStdString().c_str(), NULL);
40 path = QString(rpath);
41 free(rpath);
42
43 if (!path.isEmpty()) {
44 if (!path.endsWith("/")) {
45 path.append("/");
46 }
47 s_path_urls.append(QUrl::fromLocalFile(path));
48 s_path_list.append(path);
49 }
50 }
51 auto dbpath = confaccessor::dbfullname();
52 dbpath.truncate(dbpath.lastIndexOf("/") + 1);
53 if (!s_path_list.contains(dbpath)) {
54 s_path_urls.append(QUrl::fromLocalFile(dbpath));
55 s_path_list.append(dbpath);
56 }
57 char* rpath_cd = realpath(".", NULL);
58 auto path_cd = QString(rpath_cd);
59 free(rpath_cd);
60 if (!s_path_list.contains(path_cd)) {
61 s_path_urls.append(QUrl::fromLocalFile(path_cd));
62 }
63}
64
65QString
67{
68 if (s_path_list.isEmpty()) {
70 }
71 for (const QString& element : s_path_list) {
72 if (file.startsWith(element)) {
73 file.remove(element);
74 break;
75 }
76 }
77 return file;
78}
79
80bool
81FileInfo::match_path(const QString& file, const QString& top_file, const QStringList& includes)
82{
83 if (top_file.endsWith(file)) {
84 return true;
85 }
86
87 if (s_path_list.isEmpty()) {
89 }
90
91 QStringList candidates{ file };
92 for (const auto& element : s_path_list) {
93 if (file.startsWith(element)) {
94 auto short_name = file;
95 candidates.append(short_name.remove(element));
96 }
97 }
98
99 for (auto cand : candidates) {
100 if (includes.contains(cand)) {
101 return true;
102 }
103 }
104 return false;
105}
106
107QList<QUrl>
109{
110 if (s_path_urls.isEmpty()) {
111 setup_paths();
112 }
113 return s_path_urls;
114}
115QStringList
117{
118 if (s_path_list.isEmpty()) {
119 setup_paths();
120 }
121 return s_path_list;
122}
123
124void
126{
127 s_obj_map.clear();
128 for (auto const& class_name : config::api::info::onclass::allnames<std::vector<std::string>>()) {
129 for (auto obj : config::api::info::onclass::objects(class_name, false)) {
130 auto file = prune_path(QString::fromStdString(obj.contained_in()));
131 auto name = QString::fromStdString(obj.full_name());
132 if (!s_obj_map.contains(file)) {
133 s_obj_map.insert({ file, {} });
134 s_missing_schema_map.insert({ file, {} });
135 s_missing_data_map.insert({ file, {} });
136 }
137 s_obj_map.at(file).insert({ name, obj });
138 }
139 }
140}
141
142QString
143FileInfo::check_file_includes(const QString& filename)
144{
145 QString message{};
146
147 auto fname = prune_path(filename);
148 if (!s_missing_schema_map.contains(fname)) {
149 s_missing_schema_map.insert({ fname, {} });
150 } else {
151 s_missing_schema_map.at(fname).clear();
152 }
153 if (!s_missing_data_map.contains(fname)) {
154 s_missing_data_map.insert({ fname, {} });
155 } else {
156 s_missing_data_map.at(fname).clear();
157 }
159 if (s_obj_map.contains(prune_path(filename))) {
160 for (auto [id, obj] : s_obj_map.at(prune_path(filename))) {
161 dunedaq::conffwk::class_t const& classdef = dbe::config::api::info::onclass::definition(obj.class_name(), false);
162
163 auto schema_file = QString::fromStdString(classdef.p_schema_path);
164 if (!match_path(schema_file, filename, includes)) {
165 message += QString("Object <i>" + id + "</i> is of class <i>" + QString::fromStdString(obj.class_name()) +
166 "</i> defined in file <b>" + schema_file + "</b> which is not included<br>");
167 s_missing_schema_map.at(fname).insert(prune_path(schema_file));
168 }
169 std::vector<tref> relobjs;
170 for (auto rel : classdef.p_relationships) {
172 try {
173 relobjs.push_back(dbegraph::linked::through::relation<tref>(obj, rel));
174 } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
175 // nothing needs be done to handle cases that a relation has not been set
176 }
177 } else {
179 }
180
181 for (auto relobj : relobjs) {
182 auto file = QString::fromStdString(relobj.contained_in());
183 if (!(match_path(file, filename, includes))) {
184 message +=
185 QString("Object <i>" + id + "</i> has relationship to <i>" + QString::fromStdString(relobj.full_name()) +
186 "</i> in file <b>" + file + "</b> which is not included<br>");
187 s_missing_data_map.at(fname).insert(prune_path(file));
188 }
189 }
190 }
191 }
192 }
193 return message;
194}
195
196FileInfo::FileInfo(QString filename, QWidget* /*parent*/)
197 : m_ui(new Ui::FileInfo)
199 , m_uuid(QUuid::createUuid())
200{
201
202 QWidget::setAttribute(Qt::WA_DeleteOnClose);
203
204 m_ui->setupUi(this);
205 m_ui->filename->setText(filename);
207 m_ui->rstatus->setText(QString("RW"));
208 m_readonly = false;
209 } else {
210 m_ui->rstatus->setText(QString("RO"));
211 m_readonly = true;
212 }
213
214 setObjectName(filename);
215 setWindowTitle("File: " + filename.section('/', -1));
216
217 setup_paths();
220
221 m_ui->schema_list->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
222 m_ui->data_list->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
223 m_ui->object_list->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
224
225 connect(m_ui->add_schema, SIGNAL(pressed()), this, SLOT(add_schemafile()));
226 connect(m_ui->add_data, SIGNAL(pressed()), this, SLOT(add_datafile()));
227
228 connect(m_ui->add_missing_schema, SIGNAL(pressed()), this, SLOT(add_missing_schemafiles()));
229 connect(m_ui->add_missing, SIGNAL(pressed()), this, SLOT(add_missing_datafiles()));
230
231 connect(
232 m_ui->schema_list, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(activate_schema_context_menu(QPoint)));
233
234 connect(m_ui->data_list, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(activate_data_context_menu(QPoint)));
235 connect(m_ui->data_list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(file_info_slot(QListWidgetItem*)));
236
237 connect(m_ui->object_list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(edit_object_slot(QListWidgetItem*)));
238 connect(
239 m_ui->object_list, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(activate_object_context_menu(QPoint)));
240
241 connect(MainWindow::findthis(), SIGNAL(signal_new_file_model()), this, SLOT(filemodel_updated()));
242}
243
244void
246{
247 if (m_updating) {
248 return;
249 }
252}
253
254void
256{
258 m_ui->object_list->clear();
259 auto fname = prune_path(m_filename);
260 if (s_obj_map.contains(fname)) {
261 auto& omap = s_obj_map.at(fname);
262 for (auto const& [obj_name, obj_ref] : omap) {
263 auto item = new QListWidgetItem(obj_name);
264 m_ui->object_list->addItem(item);
265 }
266 }
267 m_ui->object_list->update();
268
269 auto status = check_includes();
270 if (!s_missing_schema_map.contains(fname)) {
271 s_missing_schema_map.insert({ fname, {} });
272 }
273 if (!s_missing_data_map.contains(fname)) {
274 s_missing_data_map.insert({ fname, {} });
275 }
276 m_ui->add_missing_schema->setVisible(!s_missing_schema_map.at(fname).empty());
277 m_ui->add_missing->setVisible(!s_missing_data_map.at(fname).empty());
278
279 m_ui->warningBox->setVisible(!status);
280}
281
282bool
284{
285 QString message = check_file_includes(m_filename);
286 m_ui->message->setText(message);
287 return message.isEmpty();
288}
289
290void
292{
294 m_ui->schema_list->clear();
295 m_ui->data_list->clear();
296 for (auto inc : includes) {
297 auto item = new QListWidgetItem(inc);
298 if (!confaccessor::check_file_rw(inc)) {
299 item->setForeground(QBrush(StyleUtility::FileReadOnlyForeground));
300 item->setBackground(QBrush(StyleUtility::FileReadOnlyBackground));
301 }
302 if (inc.endsWith(".schema.xml")) {
303 m_ui->schema_list->addItem(item);
304 }
305 if (inc.endsWith(".data.xml")) {
306 m_ui->data_list->addItem(item);
307 }
308 }
309 m_ui->schema_list->update();
310 m_ui->data_list->update();
311}
312
313void
314FileInfo::keyPressEvent(QKeyEvent* event)
315{
316 if (event->key() == Qt::Key_Escape) {
317 close();
318 }
319 QWidget::keyPressEvent(event);
320}
321
322void
324{
325 close();
326}
327void
329{
330 close();
331}
332
333void
335{
336 auto item = m_ui->object_list->currentItem();
337 edit_object_slot(item);
338}
339
340void
341FileInfo::edit_object_slot(QListWidgetItem* item)
342{
343 auto name = item->text();
344 if (s_obj_map.at(prune_path(m_filename)).contains(name)) {
345 for (QWidget* widget : QApplication::allWidgets()) {
346 auto oe = dynamic_cast<ObjectEditor*>(widget);
347 if (oe != nullptr) {
348 if (oe->objectName() == name) {
349 oe->raise();
350 oe->setVisible(true);
351 oe->activateWindow();
352 return;
353 }
354 }
355 }
356
357 auto obj = s_obj_map.at(prune_path(m_filename)).at(name);
358 auto oe = new ObjectEditor(obj);
359 oe->show();
360 }
361}
362
363void
365{
366 auto name = m_ui->object_list->currentItem()->text();
367 auto file = prune_path(m_filename);
368 if (s_obj_map.at(file).contains(name)) {
370 }
372}
373
374void
376{
377 auto name = m_ui->object_list->currentItem()->text();
378 auto file = prune_path(m_filename);
379 if (s_obj_map.at(file).contains(name)) {
380 QInputDialog dia(this);
381 dia.setLabelText("Enter new name for " + name);
382 auto code = dia.exec();
383 if (code == QDialog::Accepted) {
384 std::string new_name = dia.textValue().toStdString();
385 config::api::commands::renobj(s_obj_map.at(file).at(name), new_name, m_uuid);
386 }
387 }
389}
390
391void
393{
394 if (s_data_path == ".") {
396 }
397 auto fd = new QFileDialog(this, tr("Open Data File"), s_data_path, tr("XML data files (*.data.xml)"));
398 add_includefile(fd);
399 if (fd->result() == QDialog::Accepted) {
400 s_data_path = fd->directory().path();
401 }
402}
403void
405{
406 if (s_schema_path == ".") {
408 }
409 auto fd = new QFileDialog(this, tr("Open Schema File"), s_schema_path, tr("XML schema files (*.schema.xml)"));
410 add_includefile(fd);
411 if (fd->result() == QDialog::Accepted) {
412 s_schema_path = fd->directory().path();
413 }
414}
415void
417{
418 fd->setFileMode(QFileDialog::ExistingFiles);
419 fd->setViewMode(QFileDialog::Detail);
420 fd->setAcceptMode(QFileDialog::AcceptOpen);
421 fd->setSidebarUrls(s_path_urls);
422 if (fd->exec() == QDialog::Accepted) {
423 auto files = fd->selectedFiles();
424 QScopedValueRollback<bool> rb(m_updating, true);
425 for (auto file : files) {
426 file = prune_path(file);
428 }
431 }
432}
433
434void
436{
437 QScopedValueRollback<bool> rb(m_updating, true);
438 auto short_filename = prune_path(m_filename);
439 if (!s_missing_schema_map.contains(short_filename)) {
440 QMessageBox::warning(
441 this, "Warning", QString("Missing schema map is corrupt and does not contain %1").arg(short_filename));
442 return;
443 }
444 for (const auto& file : s_missing_schema_map.at(short_filename)) {
446 }
449}
450
451void
453{
454 QScopedValueRollback<bool> rb(m_updating, true);
455 auto short_filename = prune_path(m_filename);
456 if (!s_missing_data_map.contains(short_filename)) {
457 QMessageBox::warning(
458 this, "Warning", QString("Missing data map is corrupt and does not contain %1").arg(short_filename));
459 return;
460 }
461 for (const auto& file : s_missing_data_map.at(prune_path(m_filename))) {
463 }
466}
467
468void
470{
471 remove_includefile(m_ui->schema_list->currentItem()->text());
472}
473void
475{
476 remove_includefile(m_ui->data_list->currentItem()->text());
477}
478void
485
486void
488{
489 show_file_info(m_ui->data_list->currentItem()->text());
490}
491
492void
493FileInfo::file_info_slot(QListWidgetItem* item)
494{
495 show_file_info(item->text());
496}
497
498void
499FileInfo::file_info_slot(const QString& filename)
500{
502}
503
504void
505FileInfo::show_file_info(const QString& filename)
506{
507 for (QWidget* widget : QApplication::allWidgets()) {
508 auto fi = dynamic_cast<FileInfo*>(widget);
509 if (fi != nullptr) {
510 if (fi->objectName() == filename) {
511 fi->raise();
512 fi->setVisible(true);
513 fi->activateWindow();
514 return;
515 }
516 }
517 }
518
519 auto fi = new FileInfo(filename);
520 fi->show();
521}
522
523void
525{
526 if (m_schema_menu == nullptr) {
527 m_schema_menu = new QMenu(this);
528
529 if (!m_readonly) {
530 auto add = new QAction("Add include file", this);
531 connect(add, SIGNAL(triggered()), this, SLOT(add_schemafile()));
532 m_schema_menu->addAction(add);
533
534 auto remove = new QAction("Remove include file", this);
535 connect(remove, SIGNAL(triggered()), this, SLOT(remove_schemafile_slot()));
536 m_schema_menu->addAction(remove);
537 }
538 }
539
540 if (m_ui->schema_list->currentIndex().isValid()) {
541 m_schema_menu->actions().at(1)->setVisible(true);
542 }
543 m_schema_menu->exec(m_ui->schema_list->mapToGlobal(pos));
544}
545
546void
548{
549 if (m_data_menu == nullptr) {
550 m_data_menu = new QMenu(this);
551
552 auto info = new QAction(tr("Show file info"), this);
553 connect(info, SIGNAL(triggered()), this, SLOT(file_info_slot()));
554 m_data_menu->addAction(info);
555
556 if (!m_readonly) {
557 auto add = new QAction("Add include file", this);
558 connect(add, SIGNAL(triggered()), this, SLOT(add_datafile()));
559 m_data_menu->addAction(add);
560
561 auto remove = new QAction("Remove include file", this);
562 connect(remove, SIGNAL(triggered()), this, SLOT(remove_datafile_slot()));
563 m_data_menu->addAction(remove);
564 }
565 }
566
567 if (m_ui->data_list->currentIndex().isValid()) {
568 m_data_menu->actions().at(0)->setVisible(true);
569 m_data_menu->actions().at(2)->setVisible(true);
570 } else {
571 m_data_menu->actions().at(0)->setVisible(false);
572 m_data_menu->actions().at(2)->setVisible(false);
573 }
574 m_data_menu->exec(m_ui->data_list->mapToGlobal(pos));
575}
576
577void
579{
580 if (m_object_menu == nullptr) {
581 m_object_menu = new QMenu(this);
582
583 auto edit_action = new QAction(tr("&Edit object"), this);
584 connect(edit_action, SIGNAL(triggered()), this, SLOT(edit_object_slot()));
585 m_object_menu->addAction(edit_action);
586
587 auto delete_action = new QAction(tr("&Delete Object"), this);
588 connect(delete_action, SIGNAL(triggered()), this, SLOT(delete_object_slot()));
589 m_object_menu->addAction(delete_action);
590
591 auto rename_action = new QAction(tr("&Rename Object"), this);
592 connect(rename_action, SIGNAL(triggered()), this, SLOT(rename_object_slot()));
593 m_object_menu->addAction(rename_action);
594 }
595
596 if (m_ui->object_list->currentIndex().isValid()) {
597 m_object_menu->exec(m_ui->object_list->mapToGlobal(pos));
598 }
599}
600
601} // namespace dbe
QString m_filename
Definition FileInfo.hpp:76
static bool match_path(const QString &file, const QString &top_file, const QStringList &includes)
Definition FileInfo.cpp:81
static QList< QUrl > get_path_urls()
Definition FileInfo.cpp:108
static QString prune_path(QString file)
Definition FileInfo.cpp:66
void keyPressEvent(QKeyEvent *event) override
Definition FileInfo.cpp:314
static void parse_all_objects()
Definition FileInfo.cpp:125
QMenu * m_data_menu
Definition FileInfo.hpp:79
void add_missing_datafiles()
Definition FileInfo.cpp:452
static QStringList get_path_list()
Definition FileInfo.cpp:116
void activate_data_context_menu(QPoint point)
Definition FileInfo.cpp:547
void parse_includes()
Definition FileInfo.cpp:291
void rename_object_slot()
Definition FileInfo.cpp:375
void filemodel_updated()
Definition FileInfo.cpp:245
void add_datafile()
Definition FileInfo.cpp:392
QMenu * m_schema_menu
Definition FileInfo.hpp:78
void file_info_slot()
Definition FileInfo.cpp:487
Ui::FileInfo * m_ui
Definition FileInfo.hpp:74
bool check_includes()
Definition FileInfo.cpp:283
void remove_datafile_slot()
Definition FileInfo.cpp:474
QMenu * m_object_menu
Definition FileInfo.hpp:80
void activate_schema_context_menu(QPoint point)
Definition FileInfo.cpp:524
void edit_object_slot()
Definition FileInfo.cpp:334
static std::map< QString, std::set< QString > > s_missing_data_map
Definition FileInfo.hpp:87
void add_includefile(QFileDialog *fd)
Definition FileInfo.cpp:416
void add_schemafile()
Definition FileInfo.cpp:404
void delete_object_slot()
Definition FileInfo.cpp:364
static QStringList s_path_list
Definition FileInfo.hpp:89
void activate_object_context_menu(QPoint point)
Definition FileInfo.cpp:578
static std::map< QString, std::set< QString > > s_missing_schema_map
Definition FileInfo.hpp:86
static QString check_file_includes(const QString &file)
Definition FileInfo.cpp:143
static void setup_paths()
Definition FileInfo.cpp:32
static QString s_data_path
Definition FileInfo.hpp:92
void remove_schemafile_slot()
Definition FileInfo.cpp:469
FileInfo(QString filename, QWidget *parent=0)
Definition FileInfo.cpp:196
static QList< QUrl > s_path_urls
Definition FileInfo.hpp:90
void add_missing_schemafiles()
Definition FileInfo.cpp:435
static QString s_schema_path
Definition FileInfo.hpp:91
static std::map< QString, std::map< QString, const tref > > s_obj_map
Definition FileInfo.hpp:85
static void show_file_info(const QString &filename)
Definition FileInfo.cpp:505
void remove_includefile(const QString &file)
Definition FileInfo.cpp:479
QUuid const m_uuid
Definition FileInfo.hpp:81
void parse_objects()
Definition FileInfo.cpp:255
static MainWindow * findthis()
ObjectEditor(QWidget *parent=nullptr)
static QColor FileReadOnlyForeground
static QColor FileReadOnlyBackground
static bool check_file_rw(const QString &FileName)
static QString dbfullname()
static QStringList inclusions_singlefile(QString const &)
static std::vector< dbe::inner::configobject::tref > objects(std::string const &cname, bool const keep_inherited=true)
static dunedaq::conffwk::class_t definition(std::string const &cn, bool direct_only)
void remove(QString const &db, QString const &fn)
void add(QString const &db, QString const &fn)
bool renobj(inner::configobject::tref obj, std::string const &newuuid, QUuid const &src)
bool delobj(inner::configobject::tref obj, QUuid const &src)
T relation(tref item, dunedaq::conffwk::relationship_t const &relation)
bool is_simple(dunedaq::conffwk::relationship_t const &)
Include QT Headers.
const std::vector< relationship_t > p_relationships
Definition Schema.hpp:162
std::string p_schema_path
Definition Schema.hpp:157