LCOV - code coverage report
Current view: top level - dbe/apps/SchemaEditor - SchemaMainWindow.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 615 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 48 0

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

Generated by: LCOV version 2.0-1