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