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