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 std::string filename = qfilename.toStdString();
344 std::set<std::string> includes;
346
347 QString advice{"<br><br>Use the File info window to fix the problem."};
348 for (auto cls: KernelWrapper::GetInstance().get_schema_classes(filename)) {
349 auto relationships = cls->direct_relationships();
350 if (relationships != nullptr) {
351 for (auto rel: *relationships) {
352 auto rel_class = rel->get_class_type();
353 if (rel_class == nullptr) {
354 QString warning = "<b>Warning</b> class <i>"
355 + QString::fromStdString(cls->get_name())
356 + "</i> has relationship "
357 + QString::fromStdString(rel->get_name())
358 + " referring to class <i>"
359 + QString::fromStdString(rel->get_type())
360 + "</i> which is not loaded<br>";
361 QMessageBox::warning(0,
362 "Check Schema",
363 warning+advice,
364 QMessageBox::Ok);
365 show_file_info(qfilename);
366 return false;
367 }
368 auto file = rel_class->get_file()->get_full_file_name();
369 if (file != filename && !includes.contains(file)) {
370 QString warning = "<b>Warning</b> class <i>"
371 + QString::fromStdString(cls->get_name())
372 + "</i> has relationship "
373 + QString::fromStdString(rel->get_name())
374 + " referring to class <i>"
375 + QString::fromStdString(rel->get_class_type()->get_name())
376 + "</i> from " + QString::fromStdString(file)
377 + " which is not included by " + qfilename;
378 QMessageBox::warning(0,
379 "Check Schema",
380 warning+advice,
381 QMessageBox::Ok);
382 show_file_info(qfilename);
383 return false;
384 }
385 }
386 }
387
388 auto super_classes = cls->direct_super_classes();
389 if (super_classes != nullptr) {
390 for (auto sc: *super_classes) {
391 auto sclass = KernelWrapper::GetInstance().FindClass(*sc);
392 if (sclass == nullptr) {
393 QString warning = "<b>Warning</b> class <i>"
394 + QString::fromStdString(cls->get_name())
395 + "</i> refers to super class <i>" + QString::fromStdString(*sc)
396 + "</i> which is not known<br>";
397 QMessageBox::warning(0,
398 "Check Schema",
399 warning+advice,
400 QMessageBox::Ok);
401 show_file_info(qfilename);
402 return false;
403 }
404 auto file = sclass->get_file()->get_full_file_name();
405 if (file != filename && !includes.contains(file)) {
406 QString warning = "<b>Warning</b> class <i>"
407 + QString::fromStdString(cls->get_name())
408 + "</i> refers to super class <i>" + QString::fromStdString(*sc)
409 + "</i> from " + QString::fromStdString(file)
410 + " which is not included by" + qfilename;
411 QMessageBox::warning(0,
412 "Check Schema",
413 warning+advice,
414 QMessageBox::Ok);
415 show_file_info(qfilename);
416 return false;
417 }
418 }
419 }
420 }
421 return true;
422}
423
425 if (!check_schema_file(filename)) {
426 return false;
427 }
428 bool status;
429 QString message;
430 try {
432 message = QString ( "File %1 saved" ).arg (filename);
433 status = true;
434 }
435 catch (const oks::exception& exc) {
436 message = QString ( "Failed to save file %1" ).arg (filename);
437 status = false;
438 }
439 ui->StatusBar->showMessage( message );
440 return status;
441}
442
444{
445 QModelIndex index = ui->FileView->currentIndex();
446 const auto file = FileModel->getRowFromIndex (index).at (0);
447 save_schema_file (file);
448 BuildFileModel();
449}
450
452{
453 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
454
455 QPrinter printer;
456
457 if ( QPrintDialog ( &printer ).exec() == QDialog::Accepted )
458 {
459 QPainter painter ( &printer );
460 painter.setRenderHint ( QPainter::Antialiasing );
461
462 SchemaGraphicsScene * Scene = CurrentTab->GetScene();
463 QGraphicsView * View = CurrentTab->GetView();
464 Scene->render ( &painter, QRectF(), View->viewport()->rect() );
465 }
466}
468 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
469
470 auto file = QFileDialog::getSaveFileName(
471 this, tr("Export to SVG"),
472 m_export_path,
473 tr("SVG files (*.svg);;All files (*)"));
474 if (file.isEmpty()) {
475 return;
476 }
477
478 auto spos = file.lastIndexOf('/');
479 if (spos != -1) {
480 m_export_path = file;
481 m_export_path.truncate(spos);
482 }
483
484 auto scene = tab->GetScene();
485 auto view = tab->GetView();
486
487 QSvgGenerator generator;
488 generator.setFileName(file);
489 auto vpr=view->viewport()->rect();
490 generator.setSize(QSize(vpr.width(),vpr.height()));
491 generator.setViewBox(vpr);
492
493 QPainter painter;
494 painter.begin(&generator);
495 scene->render ( &painter, QRectF(), view->viewport()->rect() );
496 painter.end();
497}
498
499void dbse::SchemaMainWindow::closeEvent ( QCloseEvent * event )
500{
501 int UserChoice = ShouldSaveChanges();
502
503 if ( UserChoice == QMessageBox::Save )
504 {
505 if (!SaveModifiedSchema()) {
506 event->ignore();
507 return;
508 }
509 }
510 else if ( UserChoice == QMessageBox::Cancel )
511 {
512 event->ignore();
513 return;
514 }
515
516 UserChoice = ShouldSaveViewChanges();
517 if ( UserChoice == QMessageBox::Cancel )
518 {
519 event->ignore();
520 return;
521 }
522
524
525 for ( QWidget * Widget : QApplication::allWidgets() )
526 {
527 Widget->close();
528 }
529
530 event->accept();
531}
532
534 BuildFileModel();
535 BuildTableModel();
536}
537
539 OksFile* file{nullptr};
540 if(!SchemaFile.isEmpty()) {
541 try {
542 file = KernelWrapper::GetInstance().LoadSchema(SchemaFile.toStdString());
543
544 if (m_schema_directory == QString(".")) {
545 std::vector<std::string> fnames;
547 std::string dir = fnames[0].substr(0,fnames[0].find_last_of('/'));
548 m_schema_directory.setPath(QString::fromStdString(dir));
549 }
550
551#ifdef QT_DEBUG
553#endif
554 }
555 catch(oks::exception &Ex) {
556 QMessageBox::warning(0,
557 "Load Schema",
558 QString("Could not load schema!\n\n").append(QString(Ex.what())),
559 QMessageBox::Ok);
560 }
561
562 if (KernelWrapper::GetInstance().GetActiveSchema().empty()) {
563 try {
564 KernelWrapper::GetInstance().SetActiveSchema(SchemaFile.toStdString());
565 }
566 catch (oks::CanNotSetActiveFile& exc) {
567 QMessageBox::warning(0,
568 "Load Schema",
569 QString("Could not make schema active!\n\n").append(QString(exc.what())),
570 QMessageBox::Ok);
571 }
572 }
573
574 BuildTableModel();
575 BuildFileModel();
576
577 update_window_title(QFileInfo(SchemaFile).fileName());
578 //ui->CreateNewSchema->setDisabled (true );
579 //ui->OpenFileSchema->setDisabled (true );
580 if (file != nullptr) {
581 check_schema_file(QString::fromStdString(file->get_full_file_name()));
582 }
583 }
584}
585
587 m_title.remove(QRegularExpression(": --.*"));
588 m_title.append(QString(": -- ") + text);
589 setWindowTitle ( m_title );
590}
591
593{
594 QFileDialog FileDialog ( this, tr ( "Open File" ), ".",
595 tr ( "XML schema files (*.schema.xml);;All files (*)" ) );
596 FileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
597 FileDialog.setFileMode ( QFileDialog::AnyFile );
598 FileDialog.setViewMode ( QFileDialog::Detail );
599 FileDialog.setDirectory ( m_schema_directory );
600 QStringList FilesSelected;
601 QString SchemaPath;
602
603 if ( FileDialog.exec() )
604 {
605 FilesSelected = FileDialog.selectedFiles();
606 }
607
608 if ( FilesSelected.size() )
609 {
610 m_schema_directory = FileDialog.directory();
611 SchemaPath = FilesSelected.value ( 0 );
612 }
613
614 OpenSchemaFile(SchemaPath);
615}
616
618{
619 bool result = true;
620 for (auto file: KernelWrapper::GetInstance().get_modified_schema_files()) {
621 if (!save_schema_file(QString::fromStdString(file))) {
622 result = false;
623 }
624 }
625 BuildFileModel();
626 return result;
627}
628
630{
632 if (modified.empty())
633 {
634 QMessageBox::information ( 0, "Schema editor",
635 QString ( "No modified schema files need saving" ) );
636
637 }
638 else {
639 SaveModifiedSchema();
640 }
641 BuildFileModel();
642}
643
645{
646 QString FileName = QFileDialog::getSaveFileName (
647 this, tr ( "New schema File" ), ".",
648 tr ( "XML schema files (*.schema.xml);;All files (*)" ) );
649
650 if ( FileName.isEmpty() )
651 {
652 QMessageBox::warning ( 0, "Schema editor",
653 QString ( "Please provide a name for the schema !" ) );
654 return;
655 }
656
657 if ( !FileName.endsWith ( ".schema.xml" ) )
658 {
659 FileName.append ( ".schema.xml" );
660 }
661
662 QFile FileInfo ( FileName );
663 std::string FileNameStd = FileInfo.fileName().toStdString();
664
665 try
666 {
668 KernelWrapper::GetInstance().SaveSchema ( FileNameStd );
669 BuildTableModel();
670 BuildFileModel();
671 ui->CreateNewSchema->setDisabled (true );
672 ui->OpenFileSchema->setDisabled (true );
673 }
674 catch ( oks::exception & Ex )
675 {
676 QMessageBox::warning (
677 0,
678 "Schema editor",
679 QString ( "Could not create file : %1.\n\n%2" ).arg ( QString::fromStdString (
680 FileNameStd ) ).arg (
681 QString ( Ex.what() ) ) );
682 }
683}
684
686{
687 if ( ui->SetInheritance->isChecked() )
688 {
689 ui->SetInheritance->setChecked ( false );
690 }
691
692 if ( State )
693 {
694 ui->TabWidget->setCursor ( Qt::CrossCursor );
695 }
696 else
697 {
698 ui->TabWidget->setCursor ( Qt::ArrowCursor );
699 }
700
702}
703
705{
706 if ( ui->SetRelationship->isChecked() )
707 {
708 ui->SetRelationship->setChecked ( false );
709 }
710
711 if ( State )
712 {
713 ui->TabWidget->setCursor ( Qt::CrossCursor );
714 }
715 else
716 {
717 ui->TabWidget->setCursor ( Qt::ArrowCursor );
718 }
719
721}
722
724{
725 auto index = ui->TabWidget->addTab ( new SchemaTab(), "unnamed Schema View" );
726 ui->TabWidget->setCurrentIndex ( index );
727 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
728 connect (tab->GetScene(), &SchemaGraphicsScene::sceneModified,
730}
731
733 auto index = ui->TabWidget->currentIndex();
734 auto label = ui->TabWidget->tabText(index);
735 if (modified && !label.endsWith("*")) {
736 label += "*";
737 }
738 if (!modified && label.endsWith("*")) {
739 label = label.remove('*');
740 }
741 ui->TabWidget->setTabText(index, label);
742}
743
745 auto index = ui->TabWidget->currentIndex();
746 bool ok;
747 QString text = QInputDialog::getText(nullptr,
748 "Schema editor: rename class view",
749 "New view name:",
750 QLineEdit::Normal,
751 "New Class View",
752 &ok);
753 if(ok && !text.isEmpty()) {
754 ui->TabWidget->setTabText(index, text);
755 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
756 CurrentTab->setName(text);
757 }
758
759 auto newtext = ui->TabWidget->tabText(index);
760}
761
763 SchemaTab * tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
764 if ( tab->GetScene()->items().size() != 0 )
765 {
766 auto file_name = tab->getFileName();
767 if (file_name == "./") {
768 SaveViewAs();
769 return;
770 }
771 write_view_file(file_name, tab);
772 }
773}
775 SchemaTab * CurrentTab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
776 if ( CurrentTab->GetScene()->items().size() != 0 )
777 {
778 auto defName = CurrentTab->getFileName();
779 if (defName == "./") {
780 defName = m_view_dir;
781 }
782 QString FileName = QFileDialog::getSaveFileName (
783 this, tr ( "Save View" ), defName,
784 tr("View files (*.view);;All files (*)") );
785
786 if (! FileName.isEmpty()) {
787 auto spos = FileName.lastIndexOf('/');
788 if (spos != -1) {
789 m_view_dir = FileName;
790 m_view_dir.truncate(spos);
791 }
792
793 if ( !FileName.endsWith ( ".view" ) ) {
794 FileName.append ( ".view" );
795 }
796
797 CurrentTab->setFileName ( FileName );
798 auto text = QFileInfo(FileName).baseName();
799 CurrentTab->setName(text);
800 auto index = ui->TabWidget->currentIndex();
801 ui->TabWidget->setTabText(index, text);
802
803 write_view_file(FileName, CurrentTab);
804 }
805 }
806}
807
808void dbse::SchemaMainWindow::write_view_file (const QString& file_name,
809 SchemaTab* tab) {
810 QFile file ( file_name );
811 file.open ( QIODevice::WriteOnly );
812
813 for ( QGraphicsItem * item : tab->GetScene()->items() ) {
814 auto object = dynamic_cast<SchemaGraphicObject *> ( item );
815 if ( object != nullptr ) {
816 QString description = object->GetClassName() + ","
817 + QString::number ( object->scenePos().x() ) + ","
818 + QString::number ( object->scenePos().y() ) + "\n";
819 file.write ( description.toUtf8() );
820 }
821 else {
822 auto note = dynamic_cast<SchemaGraphicNote*> (item);
823 if ( note != nullptr && !note->text().isEmpty()) {
824 auto text = note->text().replace("\n", "<br>");
825 text = text.replace(",", "<comma>");
826 QString line = "#,"
827 + QString::number ( note->scenePos().x() ) + ","
828 + QString::number ( note->scenePos().y() ) + ","
829 + text + "\n";
830 file.write ( line.toUtf8() );
831 }
832 }
833 }
834
835 file.close();
836 auto message = QString("Saved view to %1").arg(file_name);
837 ui->StatusBar->showMessage( message );
838 tab->GetScene()->ClearModified();
839}
840
842 QString ViewPath = QFileDialog::getOpenFileName (
843 this,
844 tr ("Open view file"),
845 m_view_dir,
846 tr("View files (*.view);;All files (*)"));
847
848 if ( !ViewPath.isEmpty() )
849 {
850 auto spos = ViewPath.lastIndexOf('/');
851 if (spos != -1) {
852 m_view_dir = ViewPath;
853 m_view_dir.truncate(spos);
854 }
855 QFile ViewFile ( ViewPath );
856 ViewFile.open ( QIODevice::ReadOnly );
857
858 auto text = QFileInfo(ViewPath).baseName();
859 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
860 if (!tab->getName().isEmpty() || tab->GetScene()->IsModified()) {
861 add_tab();
862 tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
863 }
864 auto index = ui->TabWidget->currentIndex();
865 ui->TabWidget->setTabText(index, text);
866 tab->setName(text);
867 tab->setFileName(ViewPath);
868
869 QStringList ClassesNames;
870 QList<QPointF> Positions;
871 QList<QPointF> note_positions;
872 QStringList notes;
873 while ( !ViewFile.atEnd() )
874 {
875 QString Line ( ViewFile.readLine() );
876 if (!Line.isEmpty()) {
877 QStringList ObjectDescription = Line.split ( "," );
878 QPointF Position;
879 Position.setX ( ObjectDescription.at ( 1 ).toInt() );
880 Position.setY ( ObjectDescription.at ( 2 ).toInt() );
881 if (ObjectDescription.at ( 0 ) == "#") {
882 note_positions.append (Position);
883 auto note_text = ObjectDescription.at(3);
884 if (note_text.back() == '\n') {
885 note_text.chop(1);
886 }
887 note_text = note_text.replace("<br>", "\n");
888 note_text = note_text.replace("<comma>", ",");
889 notes.append ( note_text );
890 }
891 else {
892 ClassesNames.append ( ObjectDescription.at ( 0 ) );
893 Positions.append ( Position );
894 }
895 }
896 }
897 ViewFile.close();
898
899 auto message = QString("Loaded view from %1").arg(ViewPath);
900 ui->StatusBar->showMessage( message );
901
902 auto scene = tab->GetScene();
903 scene->CleanItemMap();
904 auto missing = scene->AddItemsToScene ( ClassesNames, Positions );
905 if (!missing.empty()) {
906 QString warning_text{"The following classes in "};
907 warning_text.append(QFileInfo(ViewPath).fileName());
908 warning_text.append(" are not present in the loaded schema:\n ");
909 warning_text.append(missing.join(",\n "));
910 QMessageBox::warning(this, tr("Load View"), warning_text);
911 }
912 scene->ClearModified();
913
914 scene->add_notes(notes, note_positions);
915 }
916}
917
919{
920 QModelIndex proxyIndex = m_proxyModel->mapToSource( Index );
921 QStringList Row = TableModel->getRowFromIndex ( proxyIndex );
922
923 if ( !Row.isEmpty() ) {
924 SchemaClassEditor::launch(Row.at ( 0 ));
925 }
926}
927
929 RemoveTab(ui->TabWidget->currentIndex());
930}
931
933{
934 if ( index == -1 || ( ( ui->TabWidget->count() == 1 ) && index == 0 ) ) {
935 return;
936 }
937
938 auto tab = dynamic_cast<SchemaTab *> (ui->TabWidget->widget(index));
939 if (tab->GetScene()->IsModified()) {
940 auto choice = QMessageBox::question (
941 0, tr ( "SchemaEditor" ),
942 QString ( "There are unsaved changes in the schema view:\n"
943 "Do you really want to delete this schema view?\n" ),
944 QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel );
945 if (choice == QMessageBox::Cancel) {
946 return;
947 }
948 }
949 ui->TabWidget->removeTab ( index );
950 delete tab;
951}
952
954{
955 if ( ContextMenuFileView == nullptr )
956 {
957 ContextMenuFileView = new QMenu ( this );
958
959 QAction * Act = new QAction ( tr ( "Set as Active Schema" ), this );
960 connect ( Act, SIGNAL ( triggered() ), this, SLOT ( SetSchemaFileActive() ) );
961 QAction * Sav = new QAction ( tr ( "Save Schema File" ), this );
962 connect ( Sav, SIGNAL ( triggered() ), this, SLOT ( SaveSchemaFile() ) );
963 QAction * info = new QAction ( tr ( "Show file info" ), this );
964 connect ( info, SIGNAL ( triggered() ), this, SLOT ( show_file_info() ) );
965
966 ContextMenuFileView->addAction ( info );
967 ContextMenuFileView->addAction ( Act );
968 ContextMenuFileView->addAction ( Sav );
969 }
970
971 QModelIndex index = ui->FileView->currentIndex();
972
973 if ( index.isValid() )
974 {
975 QStringList row = FileModel->getRowFromIndex ( index );
976 if (row.at(1) == "RW") {
977 ContextMenuFileView->actions().at(2)->setVisible(true);
978 if (!row.at(2).contains("Active")) {
979 ContextMenuFileView->actions().at(1)->setVisible(true);
980 }
981 else {
982 ContextMenuFileView->actions().at(1)->setVisible(false);
983 }
984 }
985 else {
986 ContextMenuFileView->actions().at(2)->setVisible(false);
987 ContextMenuFileView->actions().at(1)->setVisible(false);
988 }
989 ContextMenuFileView->exec ( ui->FileView->mapToGlobal ( Pos ) );
990 }
991}
992
994{
995 if ( ContextMenuTableView == nullptr )
996 {
997 ContextMenuTableView = new QMenu ( this );
998
999 QAction * add = new QAction ( tr ( "&Add New Class" ), this );
1000 connect ( add, SIGNAL ( triggered() ), this, SLOT ( AddNewClass() ) );
1001
1002 QAction * remove = new QAction ( tr ( "&Remove Selected Class" ), this );
1003 connect ( remove, SIGNAL ( triggered() ), this, SLOT ( RemoveClass() ) );
1004
1005 QAction * edit = new QAction ( tr ( "&Edit Selected Class" ), this );
1006 connect ( edit, SIGNAL ( triggered() ), this, SLOT ( editClass() ) );
1007
1008 ContextMenuTableView->addAction ( add );
1009 ContextMenuTableView->addAction ( edit );
1010 ContextMenuTableView->addAction ( remove );
1011 }
1012
1013 QModelIndex Index = ui->ClassTableView->currentIndex();
1014
1015 if ( Index.isValid() )
1016 {
1017 ContextMenuTableView->exec ( ui->ClassTableView->mapToGlobal ( Pos ) );
1018 }
1019}
1020
1022{
1023 if ( ui->case_sensitive->isChecked() ) {
1024 m_proxyModel->setFilterCaseSensitivity ( Qt::CaseSensitive );
1025 }
1026 else {
1027 m_proxyModel->setFilterCaseSensitivity ( Qt::CaseInsensitive );
1028 }
1029}
1031 auto tab = dynamic_cast<SchemaTab *> ( ui->TabWidget->currentWidget() );
1032 tab->GetScene()->update();
1033
1034 BuildTableModel();
1035 BuildFileModel();
1036}
1037
1039 if (m_settings == nullptr) {
1040 m_settings = new SchemaSettings(this);
1041 connect(m_settings, SIGNAL(settings_updated()), this, SLOT(update_view()));
1042 }
1043 m_settings->show();
1044}
static KernelWrapper & GetInstance()
dunedaq::oks::OksFile * LoadSchema(const std::string &SchemaName) const
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 PushRemoveClassCommand(dunedaq::oks::OksClass *Class, std::string ClassName, std::string ClassDescription, bool Abstract)
void get_all_includes(const std::string &FileName, std::set< std::string > &IncludedFiles)
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)
bool check_schema_file(QString file)
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
Provides interface to the OKS XML schema and data files.
Definition file.hpp:340
virtual const char * what() const noexcept
Including Qt Headers.
static void load()