DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
SchemaMainWindow.cpp
Go to the documentation of this file.
1
5#include "dbe/SchemaTab.hpp"
10#include "dbe/SchemaStyle.hpp"
11
12#include "oks/kernel.hpp" // for CanNotSetActiveFile exception
13
15#include "ui_SchemaMainWindow.h"
17#include <QFileDialog>
18#include <QMessageBox>
19#include <QHeaderView>
20#include <QPushButton>
21#include <QGraphicsScene>
22#include "QInputDialog"
23#include <QCloseEvent>
24#include <QPrinter>
25#include <QPrintDialog>
26#include <QSvgGenerator>
27
28//#include <format>
29#include <sstream>
30
31using namespace dunedaq;
32using namespace dunedaq::oks;
33
34
35dbse::SchemaMainWindow::SchemaMainWindow ( QString SchemaFile, QWidget * parent )
36 : QMainWindow ( parent ),
37 ui ( new Ui::SchemaMainWindow ),
38 FileModel ( nullptr ),
39 TableModel ( nullptr ),
40 m_proxyModel ( new QSortFilterProxyModel() ),
41 ContextMenuFileView ( nullptr ),
42 ContextMenuTableView ( nullptr )
43{
45
47 InitialTab();
50 setFocusPolicy( Qt::StrongFocus );
51
52 OpenSchemaFile(SchemaFile);
53}
54
56
58{
59 ui->setupUi ( this );
60 setWindowTitle ( m_title );
61 ui->UndoView->setStack ( KernelWrapper::GetInstance().GetUndoStack() );
62 ui->ClassTableView->horizontalHeader()->setSectionResizeMode ( QHeaderView::Stretch );
63 ui->ClassTableView->setDragEnabled ( true );
64 ui->ClassTableView->setContextMenuPolicy ( Qt::ContextMenuPolicy::CustomContextMenu );
65 ui->FileView->horizontalHeader()->setSectionResizeMode ( QHeaderView::Stretch );
66 ui->FileView->setContextMenuPolicy ( Qt::ContextMenuPolicy::CustomContextMenu );
67 ui->FileView->setSelectionBehavior ( QAbstractItemView::SelectRows );
68 ui->TabWidget->setTabsClosable ( true );
69 ui->ClassTableSearchLine->setProperty ( "placeholderText",
70 QVariant ( QString ( "Search for classes regex" ) ) );
71 ui->ClassTableSearchLine->setClearButtonEnabled(true);
72 m_proxyModel->setFilterCaseSensitivity (Qt::CaseInsensitive);
73}
74
76{
77 add_tab();
78 ui->TabWidget->removeTab ( 0 );
79}
80
82{
83 QPushButton * RightButton = new QPushButton ( "+" );
84 ui->TabWidget->setCornerWidget ( RightButton, Qt::TopLeftCorner );
85 connect ( RightButton, SIGNAL ( clicked() ), this, SLOT ( add_tab() ) );
86}
87
89{
90 connect ( ui->OpenFileSchema, SIGNAL ( triggered() ), this, SLOT ( OpenSchemaFile() ) );
91 connect ( ui->CreateNewSchema, SIGNAL ( triggered() ), this, SLOT ( CreateNewSchema() ) );
92 connect ( ui->ShowSchema, SIGNAL ( triggered() ), this, SLOT ( show_file_info_active_schema() ) );
93 connect ( ui->SaveSchema, SIGNAL ( triggered() ), this, SLOT ( SaveSchema() ) );
94 connect ( ui->SetRelationship, SIGNAL ( triggered ( bool ) ), this,
95 SLOT ( ChangeCursorRelationship ( bool ) ) );
96 connect ( ui->SetInheritance, SIGNAL ( triggered ( bool ) ), this,
97 SLOT ( ChangeCursorInheritance ( bool ) ) );
98 connect ( ui->AddClass, SIGNAL ( triggered() ), this, SLOT ( AddNewClass() ) );
99 connect ( ui->SaveView, SIGNAL ( triggered() ), this, SLOT ( SaveView() ) );
100 connect ( ui->SaveViewAs, SIGNAL ( triggered() ), this, SLOT ( SaveViewAs() ) );
101 connect ( ui->LoadView, SIGNAL ( triggered() ), this, SLOT ( LoadView() ) );
102 connect ( ui->NameView, SIGNAL ( triggered() ), this, SLOT ( NameView() ) );
103 connect ( ui->Exit, SIGNAL ( triggered() ), this, SLOT ( close() ) );
104
105 connect ( ui->actionSettings, SIGNAL (triggered() ), this, SLOT ( edit_settings() ));
106
107 connect ( ui->ClassTableView, SIGNAL ( activated ( QModelIndex ) ), this,
108 SLOT ( LaunchClassEditor ( QModelIndex ) ) );
109 connect ( ui->close_tab, SIGNAL ( triggered() ), this, SLOT ( close_tab() ) );
110
111 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassCreated( QString ) ), this,
112 SLOT ( update_models() ) );
113 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassUpdated ( QString ) ), this,
114 SLOT ( update_models() ) );
115 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassRemoved ( QString ) ), this,
116 SLOT ( update_models() ) );
117 connect ( &KernelWrapper::GetInstance(), SIGNAL ( active_updated ( ) ), this,
118 SLOT ( update_models() ) );
119 connect ( ui->TabWidget, SIGNAL ( tabCloseRequested ( int ) ), this,
120 SLOT ( RemoveTab ( int ) ) );
121
122 connect ( ui->FileView, SIGNAL ( customContextMenuRequested ( QPoint ) ), this,
123 SLOT ( CustomContextMenuFileView ( QPoint ) ) );
124 connect ( ui->FileView, SIGNAL ( activated(QModelIndex) ), this, SLOT ( show_file_info(QModelIndex) ) );
125
126
127 connect ( ui->ClassTableView, SIGNAL ( customContextMenuRequested ( QPoint ) ), this,
128 SLOT ( CustomContextMenuTableView ( QPoint ) ) );
129 connect ( ui->PrintView, SIGNAL ( triggered() ), this, SLOT ( PrintCurrentView() ) );
130 connect ( ui->exportView, SIGNAL ( triggered() ), this, SLOT ( export_current_view() ) );
131 connect ( ui->ClassTableSearchLine, SIGNAL( textChanged ( QString ) ), m_proxyModel, SLOT( setFilterRegExp( QString ) ) );
132 connect ( ui->case_sensitive, SIGNAL ( stateChanged(int) ), this,
133 SLOT (toggle_case_sensitive(int)) );
134}
135
137{
138 show_file_info(QString::fromStdString(
139 KernelWrapper::GetInstance().GetActiveSchema()));
140}
141
143{
144 QModelIndex index = ui->FileView->currentIndex();
145 show_file_info(index);
146}
148{
149 QStringList row = FileModel->getRowFromIndex ( index );
150 show_file_info(row.at ( 0 ));
151}
153 bool widget_found = false;
154 for ( QWidget * widget : QApplication::allWidgets() ) {
155 auto sfi = dynamic_cast<SchemaFileInfo *> ( widget );
156 if ( sfi != nullptr ) {
157 if ( (sfi->objectName() ).compare ( fn ) == 0 ) {
158 sfi->raise();
159 sfi->setVisible ( true );
160 sfi->activateWindow();
161 widget_found = true;
162 break;
163 }
164 }
165 }
166 if ( !widget_found ) {
167 auto info = new SchemaFileInfo(fn.toStdString());
168 connect (info, &SchemaFileInfo::files_updated,
170 connect (info, &SchemaFileInfo::new_window,
172 info->show();
173 }
174}
176 std::cout << __FUNCTION__ << " New SchemaFileInfo\n";
177 connect (win, &SchemaFileInfo::files_updated,
179}
181{
182 QStringList Headers { "File Name", "Access", "Status" };
183
184 if ( FileModel != nullptr )
185 {
186 delete FileModel;
187 }
188 FileModel = new CustomFileModel ( Headers );
189
190 ui->FileView->setModel ( FileModel );
191 ui->FileView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
192 ui->FileView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
193 ui->FileView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
194}
195
197{
198 QStringList Headers
199 { "Class Name" };
200
201 if ( TableModel != nullptr )
202 {
203 delete TableModel;
204 }
205 TableModel = new CustomTableModel ( Headers );
206
207 m_proxyModel->setSourceModel(TableModel);
208 ui->ClassTableView->setModel ( m_proxyModel );
209}
210
212{
213 QString modified_views;
214 for (int index=0; index<ui->TabWidget->count(); ++index) {
215 auto tab = dynamic_cast<SchemaTab *> (ui->TabWidget->widget(index));
216 if (tab->GetScene()->IsModified()) {
217 auto label = ui->TabWidget->tabText(index);
218 label = label.remove('*');
219 modified_views.append(" " + label + "\n");
220 }
221 }
222 if (!modified_views.isEmpty()) {
223 QString message ( "There are unsaved changes in the schema views:\n");
224 message.append (modified_views);
225 message.append ("Do you want to save the changes in the schema views?\n" );
226 return QMessageBox::question (
227 0, tr ( "SchemaEditor" ),
228 message,
229 QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard );
230 }
231
232 return QMessageBox::Discard;
233}
234
236{
237 // if ( KernelWrapper::GetInstance().GetUndoStack()->isClean() )
239 if (modified.empty())
240 {
241 return QMessageBox::Discard;
242 }
243
244 std::string msg = "There are unsaved changes in the following files:\n\n"
245 + modified + "Do you want to save the changes in the schema?\n";
246 return QMessageBox::question (
247 0, tr ( "SchemaEditor" ),
248 QString ( msg.c_str() ),
249 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save );
250}
251
253{
255 BuildFileModel();
256}
257
259{
260 QModelIndex Index = ui->ClassTableView->currentIndex();
261 QModelIndex proxyIndex = m_proxyModel->mapToSource( Index );
262 QStringList Row = TableModel->getRowFromIndex ( proxyIndex );
263 OksClass * SchemaClass = KernelWrapper::GetInstance().FindClass ( Row.at (
264 0 ).toStdString() );
265
266 if ( SchemaClass->all_sub_classes()->size() != 0 )
267 {
268 QMessageBox::warning ( 0, "Schema editor",
269 QString ( "Cannot delete class because it has sub-classes." ) );
270 return;
271 }
272 else if ( KernelWrapper::GetInstance().AnyClassReferenceThis ( SchemaClass ) )
273 {
274 QMessageBox::warning ( 0, "Schema editor",
275 QString ( "Cannot delete class because some classes references it." ) );
276 return;
277 }
278 else
279 {
280 QString Name = QString::fromStdString ( SchemaClass->get_name() );
281 KernelWrapper::GetInstance().PushRemoveClassCommand ( SchemaClass, SchemaClass->get_name(),
282 SchemaClass->get_description(),
283 SchemaClass->get_is_abstract() );
284 BuildFileModel();
285 }
286}
287
289 QModelIndex Index = ui->ClassTableView->currentIndex();
290 QModelIndex proxyIndex = m_proxyModel->mapToSource( Index );
291 QStringList Row = TableModel->getRowFromIndex ( proxyIndex );
292
293 if ( !Row.isEmpty() ) {
294 bool widget_found = false;
295 QString class_name = Row.at ( 0 );
297 class_name.toStdString() );
298
299 for ( QWidget * widget : QApplication::allWidgets() ) {
300 auto editor = dynamic_cast<SchemaClassEditor *> ( widget );
301 if ( editor != nullptr ) {
302 if ( ( editor->objectName() ).compare ( class_name ) == 0 ) {
303 editor->raise();
304 editor->setVisible ( true );
305 editor->activateWindow();
306 widget_found = true;
307 }
308 }
309 }
310 if ( !widget_found ) {
311 SchemaClassEditor * editor = new SchemaClassEditor ( class_info );
312 editor->show();
313 }
314 }
315}
316
318{
319 QModelIndex index = ui->FileView->currentIndex();
320 QString file = FileModel->getRowFromIndex ( index ).at(0);
321 try {
322 KernelWrapper::GetInstance().SetActiveSchema ( file.toStdString() );
323 }
324 catch (oks::CanNotSetActiveFile& exc) {
325 QMessageBox::warning(0,
326 "Set Active Schema",
327 QString("Could not make schema active!\n\n").append(QString(exc.what())),
328 QMessageBox::Ok);
329 return;
330 }
331 update_window_title(file);
332
333 // In case we are highlighting classes in the active file, redraw current
334 // view tab now we've changed active file
335 SchemaTab * current_tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
336 SchemaGraphicsScene * scene = current_tab->GetScene();
337 scene->update();
338
339 BuildFileModel();
340}
341
343 bool status;
344 QString message;
345 try {
347 message = QString ( "File %1 saved" ).arg (filename);
348 status = true;
349 }
350 catch (const oks::exception& exc) {
351 message = QString ( "Failed to save file %1" ).arg (filename);
352 status = false;
353 }
354 ui->StatusBar->showMessage( message );
355 return status;
356}
357
359{
360 QModelIndex index = ui->FileView->currentIndex();
361 const auto file = FileModel->getRowFromIndex (index).at (0);
362 save_schema_file (file);
363 BuildFileModel();
364}
365
367{
368 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
369
370 QPrinter printer;
371
372 if ( QPrintDialog ( &printer ).exec() == QDialog::Accepted )
373 {
374 QPainter painter ( &printer );
375 painter.setRenderHint ( QPainter::Antialiasing );
376
377 SchemaGraphicsScene * Scene = CurrentTab->GetScene();
378 QGraphicsView * View = CurrentTab->GetView();
379 Scene->render ( &painter, QRectF(), View->viewport()->rect() );
380 }
381}
383 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
384
385 auto file = QFileDialog::getSaveFileName(
386 this, tr("Export to SVG"),
387 m_export_path,
388 tr("SVG files (*.svg);;All files (*)"));
389 if (file.isEmpty()) {
390 return;
391 }
392
393 auto spos = file.lastIndexOf('/');
394 if (spos != -1) {
395 m_export_path = file;
396 m_export_path.truncate(spos);
397 }
398
399 auto scene = tab->GetScene();
400 auto view = tab->GetView();
401
402 QSvgGenerator generator;
403 generator.setFileName(file);
404 auto vpr=view->viewport()->rect();
405 generator.setSize(QSize(vpr.width(),vpr.height()));
406 generator.setViewBox(vpr);
407
408 QPainter painter;
409 painter.begin(&generator);
410 scene->render ( &painter, QRectF(), view->viewport()->rect() );
411 painter.end();
412}
413
414void dbse::SchemaMainWindow::closeEvent ( QCloseEvent * event )
415{
416 int UserChoice = ShouldSaveChanges();
417
418 if ( UserChoice == QMessageBox::Save )
419 {
420 SaveModifiedSchema();
421 }
422 else if ( UserChoice == QMessageBox::Cancel )
423 {
424 event->ignore();
425 return;
426 }
427
428 UserChoice = ShouldSaveViewChanges();
429 if ( UserChoice == QMessageBox::Cancel )
430 {
431 event->ignore();
432 return;
433 }
434
436
437 for ( QWidget * Widget : QApplication::allWidgets() )
438 {
439 Widget->close();
440 }
441
442 event->accept();
443}
444
446 BuildFileModel();
447 BuildTableModel();
448}
449
451 if(!SchemaFile.isEmpty()) {
452 try {
453 KernelWrapper::GetInstance().LoadSchema(SchemaFile.toStdString());
454
455 if (m_schema_directory == QString(".")) {
456 std::vector<std::string> fnames;
458 std::string dir = fnames[0].substr(0,fnames[0].find_last_of('/'));
459 m_schema_directory.setPath(QString::fromStdString(dir));
460 }
461
462#ifdef QT_DEBUG
464#endif
465 }
466 catch(oks::exception &Ex) {
467 QMessageBox::warning(0,
468 "Load Schema",
469 QString("Could not load schema!\n\n").append(QString(Ex.what())),
470 QMessageBox::Ok);
471 }
472
473 if (KernelWrapper::GetInstance().GetActiveSchema().empty()) {
474 try {
475 KernelWrapper::GetInstance().SetActiveSchema(SchemaFile.toStdString());
476 }
477 catch (oks::CanNotSetActiveFile& exc) {
478 QMessageBox::warning(0,
479 "Load Schema",
480 QString("Could not make schema active!\n\n").append(QString(exc.what())),
481 QMessageBox::Ok);
482 }
483 }
484
485 BuildTableModel();
486 BuildFileModel();
487
488 update_window_title(QFileInfo(SchemaFile).fileName());
489 //ui->CreateNewSchema->setDisabled (true );
490 //ui->OpenFileSchema->setDisabled (true );
491 }
492}
493
495 m_title.remove(QRegularExpression(": --.*"));
496 m_title.append(QString(": -- ") + text);
497 setWindowTitle ( m_title );
498}
499
501{
502 QFileDialog FileDialog ( this, tr ( "Open File" ), ".",
503 tr ( "XML schema files (*.schema.xml);;All files (*)" ) );
504 FileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
505 FileDialog.setFileMode ( QFileDialog::AnyFile );
506 FileDialog.setViewMode ( QFileDialog::Detail );
507 FileDialog.setDirectory ( m_schema_directory );
508 QStringList FilesSelected;
509 QString SchemaPath;
510
511 if ( FileDialog.exec() )
512 {
513 FilesSelected = FileDialog.selectedFiles();
514 }
515
516 if ( FilesSelected.size() )
517 {
518 m_schema_directory = FileDialog.directory();
519 SchemaPath = FilesSelected.value ( 0 );
520 }
521
522 OpenSchemaFile(SchemaPath);
523}
525{
526 for (auto file: KernelWrapper::GetInstance().get_modified_schema_files()) {
527 save_schema_file(QString::fromStdString(file));
528 }
529 BuildFileModel();
530}
531
533{
535 if (modified.empty())
536 {
537 QMessageBox::information ( 0, "Schema editor",
538 QString ( "No modified schema files need saving" ) );
539
540 }
541 else {
542 SaveModifiedSchema();
543 }
544 BuildFileModel();
545}
546
548{
549 QString FileName = QFileDialog::getSaveFileName (
550 this, tr ( "New schema File" ), ".",
551 tr ( "XML schema files (*.schema.xml);;All files (*)" ) );
552
553 if ( FileName.isEmpty() )
554 {
555 QMessageBox::warning ( 0, "Schema editor",
556 QString ( "Please provide a name for the schema !" ) );
557 return;
558 }
559
560 if ( !FileName.endsWith ( ".schema.xml" ) )
561 {
562 FileName.append ( ".schema.xml" );
563 }
564
565 QFile FileInfo ( FileName );
566 std::string FileNameStd = FileInfo.fileName().toStdString();
567
568 try
569 {
571 KernelWrapper::GetInstance().SaveSchema ( FileNameStd );
572 BuildTableModel();
573 BuildFileModel();
574 ui->CreateNewSchema->setDisabled (true );
575 ui->OpenFileSchema->setDisabled (true );
576 }
577 catch ( oks::exception & Ex )
578 {
579 QMessageBox::warning (
580 0,
581 "Schema editor",
582 QString ( "Could not create file : %1.\n\n%2" ).arg ( QString::fromStdString (
583 FileNameStd ) ).arg (
584 QString ( Ex.what() ) ) );
585 }
586}
587
589{
590 if ( ui->SetInheritance->isChecked() )
591 {
592 ui->SetInheritance->setChecked ( false );
593 }
594
595 if ( State )
596 {
597 ui->TabWidget->setCursor ( Qt::CrossCursor );
598 }
599 else
600 {
601 ui->TabWidget->setCursor ( Qt::ArrowCursor );
602 }
603
605}
606
608{
609 if ( ui->SetRelationship->isChecked() )
610 {
611 ui->SetRelationship->setChecked ( false );
612 }
613
614 if ( State )
615 {
616 ui->TabWidget->setCursor ( Qt::CrossCursor );
617 }
618 else
619 {
620 ui->TabWidget->setCursor ( Qt::ArrowCursor );
621 }
622
624}
625
627{
628 auto index = ui->TabWidget->addTab ( new SchemaTab(), "unnamed Schema View" );
629 ui->TabWidget->setCurrentIndex ( index );
630 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
631 connect (tab->GetScene(), &SchemaGraphicsScene::sceneModified,
633}
634
636 auto index = ui->TabWidget->currentIndex();
637 auto label = ui->TabWidget->tabText(index);
638 if (modified && !label.endsWith("*")) {
639 label += "*";
640 }
641 if (!modified && label.endsWith("*")) {
642 label = label.remove('*');
643 }
644 ui->TabWidget->setTabText(index, label);
645}
646
648 auto index = ui->TabWidget->currentIndex();
649 bool ok;
650 QString text = QInputDialog::getText(nullptr,
651 "Schema editor: rename class view",
652 "New view name:",
653 QLineEdit::Normal,
654 "New Class View",
655 &ok);
656 if(ok && !text.isEmpty()) {
657 ui->TabWidget->setTabText(index, text);
658 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
659 CurrentTab->setName(text);
660 }
661
662 auto newtext = ui->TabWidget->tabText(index);
663}
664
666 SchemaTab * tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
667 if ( tab->GetScene()->items().size() != 0 )
668 {
669 auto file_name = tab->getFileName();
670 if (file_name == "./") {
671 SaveViewAs();
672 return;
673 }
674 write_view_file(file_name, tab);
675 }
676}
678 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
679 if ( CurrentTab->GetScene()->items().size() != 0 )
680 {
681 auto defName = CurrentTab->getFileName();
682 if (defName == "./") {
683 defName = m_view_dir;
684 }
685 QString FileName = QFileDialog::getSaveFileName (
686 this, tr ( "Save View" ), defName,
687 tr("View files (*.view);;All files (*)") );
688
689 if (! FileName.isEmpty()) {
690 auto spos = FileName.lastIndexOf('/');
691 if (spos != -1) {
692 m_view_dir = FileName;
693 m_view_dir.truncate(spos);
694 }
695
696 if ( !FileName.endsWith ( ".view" ) ) {
697 FileName.append ( ".view" );
698 }
699
700 CurrentTab->setFileName ( FileName );
701 auto text = QFileInfo(FileName).baseName();
702 CurrentTab->setName(text);
703 auto index = ui->TabWidget->currentIndex();
704 ui->TabWidget->setTabText(index, text);
705
706 write_view_file(FileName, CurrentTab);
707 }
708 }
709}
710
711void dbse::SchemaMainWindow::write_view_file (const QString& file_name,
712 SchemaTab* tab) {
713 QFile file ( file_name );
714 file.open ( QIODevice::WriteOnly );
715
716 for ( QGraphicsItem * item : tab->GetScene()->items() ) {
717 auto object = dynamic_cast<SchemaGraphicObject *> ( item );
718 if ( object != nullptr ) {
719 QString description = object->GetClassName() + ","
720 + QString::number ( object->scenePos().x() ) + ","
721 + QString::number ( object->scenePos().y() ) + "\n";
722 file.write ( description.toUtf8() );
723 }
724 else {
725 auto note = dynamic_cast<SchemaGraphicNote*> (item);
726 if ( note != nullptr && !note->text().isEmpty()) {
727 auto text = note->text().replace("\n", "<br>");
728 text = text.replace(",", "<comma>");
729 QString line = "#,"
730 + QString::number ( note->scenePos().x() ) + ","
731 + QString::number ( note->scenePos().y() ) + ","
732 + text + "\n";
733 file.write ( line.toUtf8() );
734 }
735 }
736 }
737
738 file.close();
739 auto message = QString("Saved view to %1").arg(file_name);
740 ui->StatusBar->showMessage( message );
741 tab->GetScene()->ClearModified();
742}
743
745 QString ViewPath = QFileDialog::getOpenFileName (
746 this,
747 tr ("Open view file"),
748 m_view_dir,
749 tr("View files (*.view);;All files (*)"));
750
751 if ( !ViewPath.isEmpty() )
752 {
753 auto spos = ViewPath.lastIndexOf('/');
754 if (spos != -1) {
755 m_view_dir = ViewPath;
756 m_view_dir.truncate(spos);
757 }
758 QFile ViewFile ( ViewPath );
759 ViewFile.open ( QIODevice::ReadOnly );
760
761 auto text = QFileInfo(ViewPath).baseName();
762 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
763 if (!tab->getName().isEmpty() || tab->GetScene()->IsModified()) {
764 add_tab();
765 tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
766 }
767 auto index = ui->TabWidget->currentIndex();
768 ui->TabWidget->setTabText(index, text);
769 tab->setName(text);
770 tab->setFileName(ViewPath);
771
772 QStringList ClassesNames;
773 QList<QPointF> Positions;
774 QList<QPointF> note_positions;
775 QStringList notes;
776 while ( !ViewFile.atEnd() )
777 {
778 QString Line ( ViewFile.readLine() );
779 if (!Line.isEmpty()) {
780 QStringList ObjectDescription = Line.split ( "," );
781 QPointF Position;
782 Position.setX ( ObjectDescription.at ( 1 ).toInt() );
783 Position.setY ( ObjectDescription.at ( 2 ).toInt() );
784 if (ObjectDescription.at ( 0 ) == "#") {
785 note_positions.append (Position);
786 auto note_text = ObjectDescription.at(3);
787 if (note_text.back() == '\n') {
788 note_text.chop(1);
789 }
790 note_text = note_text.replace("<br>", "\n");
791 note_text = note_text.replace("<comma>", ",");
792 notes.append ( note_text );
793 }
794 else {
795 ClassesNames.append ( ObjectDescription.at ( 0 ) );
796 Positions.append ( Position );
797 }
798 }
799 }
800 ViewFile.close();
801
802 auto message = QString("Loaded view from %1").arg(ViewPath);
803 ui->StatusBar->showMessage( message );
804
805 auto scene = tab->GetScene();
806 scene->CleanItemMap();
807 auto missing = scene->AddItemsToScene ( ClassesNames, Positions );
808 if (!missing.empty()) {
809 QString warning_text{"The following classes in "};
810 warning_text.append(QFileInfo(ViewPath).fileName());
811 warning_text.append(" are not present in the loaded schema:\n ");
812 warning_text.append(missing.join(",\n "));
813 QMessageBox::warning(this, tr("Load View"), warning_text);
814 }
815 scene->ClearModified();
816
817 scene->add_notes(notes, note_positions);
818 }
819}
820
822{
823 QModelIndex proxyIndex = m_proxyModel->mapToSource( Index );
824 QStringList Row = TableModel->getRowFromIndex ( proxyIndex );
825
826 if ( !Row.isEmpty() ) {
827 SchemaClassEditor::launch(Row.at ( 0 ));
828 }
829}
830
832 RemoveTab(ui->TabWidget->currentIndex());
833}
834
836{
837 if ( index == -1 || ( ( ui->TabWidget->count() == 1 ) && index == 0 ) ) {
838 return;
839 }
840
841 auto tab = dynamic_cast<SchemaTab *> (ui->TabWidget->widget(index));
842 if (tab->GetScene()->IsModified()) {
843 auto choice = QMessageBox::question (
844 0, tr ( "SchemaEditor" ),
845 QString ( "There are unsaved changes in the schema view:\n"
846 "Do you really want to delete this schema view?\n" ),
847 QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel );
848 if (choice == QMessageBox::Cancel) {
849 return;
850 }
851 }
852 ui->TabWidget->removeTab ( index );
853 delete tab;
854}
855
857{
858 if ( ContextMenuFileView == nullptr )
859 {
860 ContextMenuFileView = new QMenu ( this );
861
862 QAction * Act = new QAction ( tr ( "Set as Active Schema" ), this );
863 connect ( Act, SIGNAL ( triggered() ), this, SLOT ( SetSchemaFileActive() ) );
864 QAction * Sav = new QAction ( tr ( "Save Schema File" ), this );
865 connect ( Sav, SIGNAL ( triggered() ), this, SLOT ( SaveSchemaFile() ) );
866 QAction * info = new QAction ( tr ( "Show file info" ), this );
867 connect ( info, SIGNAL ( triggered() ), this, SLOT ( show_file_info() ) );
868
869 ContextMenuFileView->addAction ( info );
870 ContextMenuFileView->addAction ( Act );
871 ContextMenuFileView->addAction ( Sav );
872 }
873
874 QModelIndex index = ui->FileView->currentIndex();
875
876 if ( index.isValid() )
877 {
878 QStringList row = FileModel->getRowFromIndex ( index );
879 if (row.at(1) == "RW") {
880 ContextMenuFileView->actions().at(2)->setVisible(true);
881 if (!row.at(2).contains("Active")) {
882 ContextMenuFileView->actions().at(1)->setVisible(true);
883 }
884 else {
885 ContextMenuFileView->actions().at(1)->setVisible(false);
886 }
887 }
888 else {
889 ContextMenuFileView->actions().at(2)->setVisible(false);
890 ContextMenuFileView->actions().at(1)->setVisible(false);
891 }
892 ContextMenuFileView->exec ( ui->FileView->mapToGlobal ( Pos ) );
893 }
894}
895
897{
898 if ( ContextMenuTableView == nullptr )
899 {
900 ContextMenuTableView = new QMenu ( this );
901
902 QAction * add = new QAction ( tr ( "&Add New Class" ), this );
903 connect ( add, SIGNAL ( triggered() ), this, SLOT ( AddNewClass() ) );
904
905 QAction * remove = new QAction ( tr ( "&Remove Selected Class" ), this );
906 connect ( remove, SIGNAL ( triggered() ), this, SLOT ( RemoveClass() ) );
907
908 QAction * edit = new QAction ( tr ( "&Edit Selected Class" ), this );
909 connect ( edit, SIGNAL ( triggered() ), this, SLOT ( editClass() ) );
910
911 ContextMenuTableView->addAction ( add );
912 ContextMenuTableView->addAction ( edit );
913 ContextMenuTableView->addAction ( remove );
914 }
915
916 QModelIndex Index = ui->ClassTableView->currentIndex();
917
918 if ( Index.isValid() )
919 {
920 ContextMenuTableView->exec ( ui->ClassTableView->mapToGlobal ( Pos ) );
921 }
922}
923
925{
926 if ( ui->case_sensitive->isChecked() ) {
927 m_proxyModel->setFilterCaseSensitivity ( Qt::CaseSensitive );
928 }
929 else {
930 m_proxyModel->setFilterCaseSensitivity ( Qt::CaseInsensitive );
931 }
932}
934 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
935 tab->GetScene()->update();
936
937 BuildTableModel();
938 BuildFileModel();
939}
940
942 if (m_settings == nullptr) {
943 m_settings = new SchemaSettings(this);
944 connect(m_settings, SIGNAL(settings_updated()), this, SLOT(update_view()));
945 }
946 m_settings->show();
947}
static KernelWrapper & GetInstance()
void SetActiveSchema(const std::string &ActiveSchema)
dunedaq::oks::OksClass * FindClass(std::string ClassName) const
void SaveSchema(const std::string &file) const
std::string ModifiedSchemaFiles() const
void SetInheritanceMode(bool Mode)
Editor Functions.
void CreateNewSchema(const std::string &SchemaName) const
void LoadSchema(const std::string &SchemaName) const
void PushRemoveClassCommand(dunedaq::oks::OksClass *Class, std::string ClassName, std::string ClassDescription, bool Abstract)
void GetSchemaFiles(std::vector< std::string > &SchemaFiles)
static void launch(QString class_name)
void new_window(SchemaFileInfo *win)
SchemaMainWindow(QString SchemaFile, QWidget *parent=nullptr)
void connect_file_info(SchemaFileInfo *win)
void LaunchClassEditor(QModelIndex Index)
void CustomContextMenuTableView(QPoint Pos)
void ChangeCursorInheritance(bool State)
void write_view_file(const QString &fn, SchemaTab *tab)
void modifiedView(bool modified)
void CustomContextMenuFileView(QPoint Pos)
bool save_schema_file(QString file)
void update_window_title(QString text)
void ChangeCursorRelationship(bool State)
void closeEvent(QCloseEvent *event)
void setFileName(const QString &)
Definition SchemaTab.cpp:33
QString getFileName()
Definition SchemaTab.cpp:37
SchemaGraphicsScene * GetScene() const
Definition SchemaTab.cpp:19
void setName(const QString &)
Definition SchemaTab.cpp:29
QGraphicsView * GetView() const
Definition SchemaTab.cpp:24
Failed to set active file.
Definition kernel.hpp:250
The OKS class.
Definition class.hpp:200
bool get_is_abstract() const noexcept
Definition class.hpp:384
const FList * all_sub_classes() const noexcept
Definition class.hpp:466
const std::string & get_name() const noexcept
Definition class.hpp:363
const std::string & get_description() const noexcept
Definition class.hpp:368
virtual const char * what() const noexcept
The DUNE-DAQ namespace.
static void load()