Introduction

WIP Notes

The main

The "main" is launched from file uipf.cc. @line 109, and follow these steps:

  • Q_INIT_RESOURCES(uipf) load uipf.qrc resource file.

  • testUniqueness of the application on OS and Win systems

  • instantiate the app, appTranslator, qtTranslator objects following qt practice

  • create the LIBPF required strings:

    • locale: for language settings
    • homePath: ?
    • home: ?

    Which are actually set by instantiating a Settings object (Settings.h, Settings.cc)

  • LIBPF files are copied inside the application directory

  • check argv[1] for locale setting

  • load appTranslator and install it as following qt practice

  • create and show the WindowMain as per qt practice: here the application is created with all features, actions, slots, dialogs, widgets...

  • int rc = app.exec() actually run the application (hic sunt leones!)

  • before application closure release "perrsistency" database resources

  • return rc exit the application with exit code rc

Main window

The WindowMain class actually manage the application. When created from the main (uipf.cc) it launch the constructor with he following steps (NOTE: order things get done is important):

  • populate actions. Every action has at least:

    • instantiation

          newAction_ = new QAction(tr("&New"), this);
      
    • set properties

          newAction_->setStatusTip(tr("Create a new case"));
          newAction_->setIcon(QIcon(":/images/document-new.png"));
      
    • create a signal-slot connection:

          connect(newAction_, SIGNAL(triggered()), this, SLOT(new_()));
      
  • set the initial enable/disable status of actions (@line 306-337)

  • populate menus with at least:

    • positioning

          menuCase_ = menuBar()->addMenu(tr("&Case"));
      
    • insert desired actions

          menuCase_->addAction(newAction_);
          menuCase_->addAction(openAction_);
          menuCase_->addAction(saveAction_);
      
    • insert sub menus with related desired actions

          subMenuUnits_ = menuSettings_->addMenu(QIcon(":/images/applications-accessories.png"), tr("&Units"));
          subMenuUnits_->setToolTip(tr("Change units of measurements"));
          subMenuUnits_->addAction(siUnitAction_);
          subMenuUnits_->addAction(enUnitAction_);
      
  • populate the toolbars

    • create it:

          toolbarMain_ = addToolBar(tr("Main toolbar"));
      
    • insert desired actions

          toolbarMain_->addAction(newAction_);
          toolbarMain_->addAction(openAction_);
          toolbarMain_->addSeparator();
          toolbarMain_->addAction(calculateAction_);
          toolbarMain_->addAction(stopAction_);
      
  • created horizontal and vertical layouts

            vsplitter_ = new QSplitter(Qt::Vertical);
            hsplitter_ = new QSplitter(Qt::Horizontal);
    
  • created and set up the message panel:

            messages_ = new QTextEdit();
            messages_->setReadOnly(true);
            messages_->addAction(clearmsgAction_);
            messages_->setContextMenuPolicy(Qt::DefaultContextMenu);
            QFont mono("Monotype");
            mono.setStyleHint(QFont::TypeWriter);
            messages_->setCurrentFont(mono);
            messages_->setFontPointSize(9);
    
  • created table for the detail view panel (see WidgetTableDouble and WidgetTableIntegers classes) Here there is the first query calls to the persistency.

            tablewInput_ = new WidgetTableDouble(" AND QTBL.input = \'1\'", undoStack_);
            intTablewInput_ = new WidgetTableIntegers(" AND ITBL.tag like '%enableAssignment%'", undoStack_);
            tablewOutput_ = new WidgetTableDouble(" AND QTBL.output = \'1\'", undoStack_);
            tablewInput_->setRw(true);
            intTablewInput_->setRw(true);
            tablewOutput_->setRw(false);
            tablewMessages_ = new WidgetTableMessages;
    
  • created the tree view panel

            treew_ = new WidgetTree;
    
  • connect the tree view exploration with the tables

            connect(treew_, SIGNAL(gone(int)), tablewInput_, SLOT(go(int)));
            connect(treew_, SIGNAL(gone(int)), intTablewInput_, SLOT(go(int)));
            connect(treew_, SIGNAL(gone(int)), tablewOutput_, SLOT(go(int)));
            connect(treew_, SIGNAL(gone(int)), tablewMessages_, SLOT(go(int)));
            connect(treew_, SIGNAL(gone(int)), this, SLOT(showMessage(int)));
            connect(treew_, SIGNAL(gone(int)), this, SLOT(setUnit_(int)));
            connect(treew_, SIGNAL(showPfd(int)), this, SLOT(showPfd(int)));
    
  • created the svg area for the detailed view panel tab and connected its behavior

            svgw_ = new ScrollAreaSvg();
            connect(svgw_, SIGNAL(select(int)), treew_, SLOT(forceGo(int)));
    
  • connect tables, treew and exploring actions

            connect(tablewInput_, SIGNAL(forceGo(int)), this, SLOT(forceGoTable(int)));
            connect(intTablewInput_, SIGNAL(forceGo(int)), this, SLOT(forceGoIntTable(int)));
            connect(expandAction_, SIGNAL(triggered()), treew_, SLOT(expandAll()));
            connect(expandAction_, SIGNAL(triggered()), this, SLOT(clearStatusMessage()));
            connect(collapseAction_, SIGNAL(triggered()), treew_, SLOT(collapseAll()));
            connect(collapseAction_, SIGNAL(triggered()), this, SLOT(clearStatusMessage()));
            connect(rootAction_, SIGNAL(triggered()), treew_, SLOT(go()));
            connect(rootAction_, SIGNAL(triggered()), this, SLOT(clearStatusMessage()));
            connect(upAction_, SIGNAL(triggered()), treew_, SLOT(goUp()));
            connect(upAction_, SIGNAL(triggered()), this, SLOT(clearStatusMessage()));
            connect(toggleTC_, SIGNAL(triggered()), tablewInput_, SLOT(toggleChild()));
            connect(toggleTC_, SIGNAL(triggered()), intTablewInput_, SLOT(toggleChild()));
            connect(toggleTC_, SIGNAL(triggered()), tablewOutput_, SLOT(toggleChild()));
            connect(toggleTC_, SIGNAL(triggered()), treew_, SLOT(refresh()));
            connect(toggleTC_, SIGNAL(triggered()), this, SLOT(clearStatusMessage()));
    
  • connect the kernel selection action with the kernel actual selection function

            connect(selectKernelAction_, SIGNAL(triggered()), this, SLOT(selectkernel()));
    
  • create the tab for the detail panel and insert tables and svg:

            tabs_ = new QTabWidget();
            tabs_->addTab(tablewInput_, tr("Inputs"));
            tabs_->addTab(intTablewInput_, tr("Config"));
            tabs_->addTab(tablewOutput_, tr("Outputs"));
            tabs_->addTab(tablewMessages_, tr("Messages"));
            tabs_->addTab(svgw_, "PFD");
            tabs_->setTabEnabled(4, false);
    
  • insert the tree view and detail panels in the horizontal layout

            hsplitter_->addWidget(treew_);
            hsplitter_->addWidget(tabs_);
    
  • insert the horizontal layout and the message panel in the vertical layout

            vsplitter_->addWidget(hsplitter_);
            vsplitter_->addWidget(messages_);
    
  • show/hide edit-submenus according to what is active/selected

            connect(menuEdit_, SIGNAL(aboutToShow()), this, SLOT(editShowMenuClicked()));
            connect(menuEdit_, SIGNAL(aboutToHide()), this, SLOT(editHideMenuClicked()));
    
  • connect tables and contextmenu (here you can set connection to different context menu according to what is i.e. right-clicked)

  • insert the vertical layout in the center of the window:

            setCentralWidget(vsplitter_);
    
  • load the types.txt file and create the hierarchy object

            h_ = new Hierarchy(typesFile().toStdString());
    
  • create the Open and New dialogs (Why here and not inside the slot called by newAction and openAction?)

            od_ = new DialogOpen();
            connect(od_, SIGNAL(openExisting(const QString &, int)), this, SLOT(openExisting(const QString &, int)));
            nd_ = new DialogNew();
            buildNewDialog();
            connect(nd_, SIGNAL(open(const QString &, const QString &, const QString &)), this, SLOT(openNew(const QString &, const QString &, const QString &)));
    
  • create process and connect it to listen to kernel standard output and print it to the message panel

            process_ = new QProcess(this);
            connect(process_, SIGNAL(readyReadStandardOutput()), this, SLOT(updateLog()));
            connect(process_, SIGNAL(readyReadStandardError()), this, SLOT(updateLogErr()));
            connect(process_, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
            connect(process_, SIGNAL(started()), this, SLOT(started()));
            connect(process_, SIGNAL(error(QProcess::ProcessError)), this, SLOT(errorProcess(QProcess::ProcessError)));
            loggingProcess_ = NULL;
    
  • complete the interface with some features:

    • icon

          setWindowIcon(QIcon(":data/128x128/uipf.png"));
      
    • status message and status bar

          statusMessage_ = new QLabel(statusBar());
          stateMessage_ = new QLabel(statusBar());
          flag_ = new QLabel(statusBar());
          pix_ = new QPixmap(statusBar()->height() / 2, statusBar()->height() / 2);
          flag_->setPixmap(*pix_);
          flag_->setToolTip(tr("Status indicator"));
          statusBar()->addPermanentWidget(statusMessage_);
          statusBar()->addPermanentWidget(stateMessage_);
          statusBar()->addPermanentWidget(flag_);
      
    • readyness

          setState(State::empty);
          showMessage(tr("Ready"));
      

Persistency

The persistency database is queried in different place:

  1. Population of tables in the detail view panel tabs (WindowsMain.cc @line 495-502)

          #if defined(Q_OS_WIN) && (!defined(SQLITE))
            tablewInput_ = new WidgetTableDouble(" AND QTBL.input = true", undoStack_);
          intTablewInput_ = new WidgetTableIntegers(" AND ITBL.tag like '%enableAssignment%'", undoStack_);
          tablewOutput_ = new WidgetTableDouble(" AND QTBL.output = true", undoStack_);
         #else
          tablewInput_ = new WidgetTableDouble(" AND QTBL.input = \'1\'", undoStack_);
          intTablewInput_ = new WidgetTableIntegers(" AND ITBL.tag like '%enableAssignment%'", undoStack_);
          tablewOutput_ = new WidgetTableDouble(" AND QTBL.output = \'1\'", undoStack_);
         #endif
    
  2. In DialogOpen::addItem

          QSqlDatabase db = QSqlDatabase::database("persistency");
          QSqlQuery query(db);
      QString querystring = QString("select tag, description, id from N where type = \'%1\'").arg(type);
      query.exec(querystring);
    
  3. In void ActionLibpf::getErrorsWarnings to get warnings and errors after kernel computation:

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
    
            QString querystring;
          #if defined SQLITE
            querystring = "SELECT warn.warnings, err.errors FROM (select ITBL.catalogid as catalogid, ITBL.i as warnings from ITBL where tag = \'nWarnings\') as warn join (select ITBL.catalogid as catalogid, ITBL.i as errors from ITBL where tag = \'nErrors\') as err join CATALOG on CATALOG.id = warn.catalogid and CATALOG.id = err.catalogid and CATALOG.id = ?";
          #else
            querystring = "SELECT distinct ITBL.I as warnings, itbl2.I as errors FROM ((CATALOG inner join ITBL on CATALOG.id = ITBL.catalogid) inner join ITBL as itbl2 on CATALOG.id = itbl2.catalogid) WHERE CATALOG.id = ? and ITBL.tag = \'nWarnings\' and itbl2.tag = \'nErrors\'";
          #endif
    
  4. In ModelIntegerEditable::go used by CommandDataSetInteger and WidgetTableIntegers to set and update integer table in the detail view panel

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
          #if defined(Q_OS_WIN) && (!defined(SQLITE))
            query.exec(QString("select completetag from CATALOG where id = %1").arg(node));
          #else
            query.exec(QString("select trim(completetag) from CATALOG where id = %1").arg(node));
          #endif
            query.next();
            prefix_ = query.value(0).toString().toStdString();
            strip_ = prefix_.length();
            // qDebug() << strip_;
    
            QString qs;
            if (child_) {
          #if defined SQLITE
              qs = "SELECT distinct substr(CATALOG.completetag||\'.\'||ITBL.tag,%3+2), ITBL.i, ITBL.DESCRIPTION, ITBL.ID FROM "
                   "ITBL join (select TC.finish as finish, TC.start as start from TC where TC.start = %1 or TC.finish = %1) as mytc join CATALOG on CATALOG.id = ITBL.catalogid and (CATALOG.id = mytc.finish or CATALOG.id = mytc.start) %2 order by ITBL.ID";
          #elif defined Q_OS_WIN
              qs = "select distinct right(CATALOG.completetag+\'.\'+ITBL.tag, len(CATALOG.completetag)+1+len(ITBL.tag)-%3-1), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(TC inner join (ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by ITBL.ID";
          #elif defined MYSQL
              qs = "select distinct substring(concat(CATALOG.completetag,\'.\',ITBL.tag) from (%3+2)), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(TC inner join (ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by ITBL.ID";
          #elif defined POSTGRESQL
              // Added by StoianE postgres+linux
              qs = "select distinct substring(CATALOG.completetag||\'.\'||ITBL.tag from (%3+2)), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(TC inner join (ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by ITBL.ID";
          #endif
            } else {
          #if defined SQLITE
              qs = "SELECT substr(CATALOG.completetag||\'.\'||ITBL.tag,%3+2), ITBL.i, ITBL.DESCRIPTION, ITBL.ID FROM "
                   "ITBL join CATALOG on CATALOG.id = ITBL.catalogid where (CATALOG.id = %1) %2 order by ITBL.ID";
          #elif defined Q_OS_WIN
              qs = "select distinct right(CATALOG.completetag+\'.\'+ITBL.tag, len(CATALOG.completetag)+1+len(ITBL.tag)-%3-1), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by ITBL.ID";
          #elif defined MYSQL
              qs = "select distinct substring(concat(CATALOG.completetag,\'.\',ITBL.tag) from (%3+2)), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by ITBL.ID";
          #elif defined POSTGRESQL
              // Added by StoianE postgres+linux
              qs = "select distinct substring(CATALOG.completetag||\'.\'||ITBL.tag from (%3+2)), ITBL.i, ITBL.DESCRIPTION, ITBL.ID from "
                   "(ITBL inner join CATALOG on (ITBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by ITBL.ID";
          #endif
            }
    
  5. In ModelQuantityEditable::go used by CommandDataSetDouble and WidgetTableDouble to set and update double table in the detail view panel. The usage is for both input and output table: see point 1 (WindowsMain.cc @line 495-502) for the queries modifications.

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
            if (currentNode_ != node) {
              qDebug() << "ModelQuantityEditable::go" << node;
              qValue_.clear();
              uValue_.clear();
            }
            query.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble);
          #if defined SQLITE
            query.exec(QString("select completetag from CATALOG where id = %1").arg(node));
          #else
            query.exec(QString("select trim(completetag) from CATALOG where id = %1").arg(node));
          #endif
            query.next();
            prefix_ = query.value(0).toString().toStdString();
            strip_ = prefix_.length();
            qDebug() << "complete tag = " << prefix_.c_str();
            // qDebug() << strip_;
    
            QString qs;
            if (child_) {
          #if defined SQLITE
              qs = "SELECT distinct substr(CATALOG.completetag||\'.\'||QTBL.tag,%3+2), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID FROM "
                   "QTBL join (select TC.finish as finish, TC.start as start from TC where TC.start = %1 or TC.finish = %1) as mytc join CATALOG on CATALOG.id = QTBL.catalogid and (CATALOG.id = mytc.finish or CATALOG.id = mytc.start) %2 order by QTBL.ID";
          #elif defined Q_OS_WIN
              qs = "select distinct right(CATALOG.completetag+\'.\'+QTBL.tag, len(CATALOG.completetag)+1+len(QTBL.tag)-%3-1), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(TC inner join (QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by QTBL.ID";
          #elif defined MYSQL
              qs = "select distinct substring(concat(CATALOG.completetag,\'.\',QTBL.tag) from (%3+2) ), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(TC inner join (QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by QTBL.ID";
          #elif defined POSTGRESQL
              // Added by StoianE postgres + linux
              qs = "select distinct substring(CATALOG.completetag||\'.\'||QTBL.tag from (%3+2)), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(TC inner join (QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) on ((TC.finish = CATALOG.id) or (CATALOG.id = %1))) "
                   "where ((TC.start = %1) or (CATALOG.id = %1)) %2 order by QTBL.ID";
          #endif
            } else {
          #if defined SQLITE
              qs = "SELECT substr(CATALOG.completetag||\'.\'||QTBL.tag, %3+2), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID FROM "
                   "QTBL join CATALOG on CATALOG.id = QTBL.catalogid where (CATALOG.id = %1) %2 order by QTBL.ID";
          #elif defined Q_OS_WIN
              qs = "select distinct right(CATALOG.completetag+\'.\'+QTBL.tag, len(CATALOG.completetag)+1+len(QTBL.tag)-%3-1), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by QTBL.ID";
          #elif defined MYSQL
              qs = "select distinct substring(concat(CATALOG.completetag,\'.\',QTBL.tag) from (%3+2)), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by QTBL.ID";
          #elif defined POSTGRESQL
              // Added by StoianE postgres + linux
              qs = "select distinct substring(CATALOG.completetag||\'.\'||QTBL.tag from (%3+2)), QTBL.Q, QTBL.UOM, QTBL.DESCRIPTION, QTBL.ID from "
                   "(QTBL inner join CATALOG on (QTBL.catalogid = CATALOG.id)) where (CATALOG.id = %1) %2 order by QTBL.ID";
          #endif
            }
            qs = qs.arg(node).arg(extraFilter_.c_str()).arg(strip_);
            // qDebug() << "Query in ModelQuantityEditable::go = " << qs;
            setQuery(qs, db);
            if (lastError().isValid())
              qDebug() << "Error while executing query in ModelQuantityEditable::go: " << lastError();
    
  6. In WidgetTableMessages::go used to set and update message table in the detail view panel

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
    
          #if defined(Q_OS_WIN) && (!defined(SQLITE))
            QString qs("select STBL.tag+\' \'+STBL.s from (STBL inner join CATALOG on (STBL.catalogid = CATALOG.id)) where ((CATALOG.id = %1) and ((STBL.tag like \'errorMsg%\') or (STBL.tag like \'warningMsg%\')))");
          #elif !defined(POSTGRESQL)
            QString qs("SELECT CONCAT(smsg.tag,\' \',smsg.s) FROM (select STBL.tag as tag, STBL.s as s, STBL.catalogid as catalogid from STBL where tag like \'errorMsg%\' or tag like \'warningMsg%\') as smsg join CATALOG on CATALOG.id = smsg.catalogid and CATALOG.id = %1");
          #else
            QString qs("SELECT smsg.tag||\' \'||smsg.s FROM (select STBL.tag as tag, STBL.s as s, STBL.catalogid as catalogid from STBL where tag like \'errorMsg%\' or tag like \'warningMsg%\') as smsg join CATALOG on CATALOG.id = smsg.catalogid and CATALOG.id = %1");
          #endif
    
            qs = qs.arg(node);
            model_->setQuery(qs, db);
            if (model_->lastError().isValid())
              qDebug() << "Error while executing query in WidgetTableMessages::go: " << model_->lastError();
            model_->setHeaderData(0, Qt::Horizontal, tr("Error/Warning message"));
    
  7. In WidgetTree::forceGo

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery queryItem(db);
    
            QString queryString;
          #if defined SQLITE
            queryString = "SELECT CATALOG.tag, CATALOG.type, CATALOG.description, CATALOG.parent, CATALOG.completetag, warn.warnings, err.errors FROM (select ITBL.catalogid as catalogid, ITBL.i as warnings from ITBL where tag = \'nWarnings\') as warn join (select ITBL.catalogid as catalogid, ITBL.i as errors from ITBL where tag = \'nErrors\') as err join CATALOG on CATALOG.id = warn.catalogid and CATALOG.id = err.catalogid and CATALOG.id = ?";
          #else
            queryString = "SELECT distinct CATALOG.tag, CATALOG.type, CATALOG.description, CATALOG.parent, CATALOG.completetag, ITBL.I as warnings, itbl2.I as errors FROM ((CATALOG inner join ITBL on CATALOG.id = ITBL.catalogid) inner join ITBL as itbl2 on CATALOG.id = itbl2.catalogid) WHERE CATALOG.id = ? and ITBL.tag = \'nWarnings\' and itbl2.tag = \'nErrors\'";
          #endif
            queryItem.prepare(queryString);
            queryItem.addBindValue(node);
            queryItem.exec();
    
  8. In WidgetTree::addChilds

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery queryChilds(db);
    
            QTreeWidgetItem* itemChild;
            queryChilds.prepare("SELECT i FROM ITBL WHERE tag like \'embedded%\' AND catalogid = ? ORDER BY id");
            queryChilds.addBindValue(cid);
            queryChilds.exec();
    
           ...
    
         #if defined SQLITE
               QString queryString("SELECT CATALOG.tag, CATALOG.type, CATALOG.description, warn.warnings, err.errors FROM (select ITBL.catalogid as catalogid, ITBL.i as warnings from ITBL where tag = \'nWarnings\') as warn join (select ITBL.catalogid as catalogid, ITBL.i as errors from ITBL where tag = \'nErrors\') as err join CATALOG on CATALOG.id = warn.catalogid and CATALOG.id = err.catalogid and CATALOG.id = ");
         #else
               QString queryString("SELECT distinct CATALOG.tag, CATALOG.type, CATALOG.description, ITBL.I as warnings, itbl2.I as errors FROM ((CATALOG inner join ITBL on CATALOG.id = ITBL.catalogid) inner join ITBL as itbl2 on CATALOG.id = itbl2.catalogid) WHERE ITBL.tag = \'nWarnings\' and itbl2.tag = \'nErrors\' and CATALOG.id = ");
         #endif
    
               queryString += QVariant(i).toString();
               query.exec(queryString);
    
  9. in DelegateControl constructor (DelegateControl.cc) used in WidgetTableControl for DialogSensitivity:

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
          #if defined SQLITE
            query.prepare("SELECT distinct QTBL.ID, CATALOG.completetag||\'.\'||QTBL.tag, QTBL.UOM, QTBL.DESCRIPTION, QTBL.tag, QTBL.Q FROM" \
                          " QTBL join (select TC.finish as finish, TC.start as start from TC where TC.start = ? or TC.finish = ?) as mytc" \
                          " join CATALOG on CATALOG.id = QTBL.catalogid and (CATALOG.id = mytc.finish or CATALOG.id = mytc.start) AND QTBL.input = 1");
          #elif defined Q_OS_WIN
            query.prepare("SELECT DISTINCT qtbl.id, catalog.completetag+\'.\'+QTBL.tag, qtbl.uom, qtbl.description, qtbl.tag, qtbl.q FROM" \
                          " ((SELECT finish, start FROM tc WHERE tc.start = ? OR tc.finish = ?) AS mytc INNER JOIN" \
                          " (qtbl INNER JOIN catalog ON (qtbl.catalogid = catalog.id AND qtbl.input = true)) on ((mytc.finish = catalog.id) or (mytc.start = catalog.id))) ORDER BY qtbl.id;");
    
          #else // postgres
            query.prepare("SELECT DISTINCT qtbl.id, catalog.completetag||\'.\'||qtbl.tag, qtbl.uom, qtbl.description, qtbl.tag, qtbl.q FROM " \
                          " ((SELECT finish, start FROM tc WHERE tc.start = ? OR tc.finish = ?) AS mytc INNER JOIN" \
                          "  (qtbl INNER JOIN catalog ON (qtbl.catalogid = catalog.id AND qtbl.input = true)) on ((mytc.finish = catalog.id) or (mytc.start = catalog.id))) ORDER BY qtbl.id;");
    
          #endif
    
  10. In DelegateMonitor constructor (DelegateMonitor.cc) used in WidgetTableMonitor for DialogSensitivity:

            QSqlDatabase db = QSqlDatabase::database("persistency");
            QSqlQuery query(db);
          #if defined SQLITE
            query.prepare("SELECT distinct qtbl.id, CATALOG.completetag||\'.\'||QTBL.tag, QTBL.UOM, QTBL.DESCRIPTION, QTBL.tag FROM " \
                          " QTBL join (select TC.finish as finish, TC.start as start from TC where TC.start = ? or TC.finish = ?) as mytc" \
                          " join CATALOG on CATALOG.id = QTBL.catalogid and (CATALOG.id = mytc.finish or CATALOG.id = mytc.start) and qtbl.output = 1");
          #elif defined Q_OS_WIN
            query.prepare("SELECT DISTINCT qtbl.id, catalog.completetag+\'.\'+qtbl.tag, qtbl.uom, qtbl.description, qtbl.tag FROM" \
                          " ((SELECT finish, start FROM tc WHERE tc.start = ? OR tc.finish = ?) AS mytc INNER JOIN (qtbl INNER JOIN catalog ON (qtbl.catalogid = catalog.id AND qtbl.output = true)) on ((mytc.finish = catalog.id) or (mytc.start = catalog.id))) ORDER BY qtbl.id;");
          #else // postgres
            query.prepare("SELECT DISTINCT qtbl.id, catalog.completetag||\'.\'||qtbl.tag, qtbl.uom, qtbl.description, qtbl.tag FROM" \
                          " ((SELECT finish, start FROM tc WHERE tc.start = ? OR tc.finish = ?) AS mytc INNER JOIN (qtbl INNER JOIN catalog ON (qtbl.catalogid = catalog.id AND qtbl.output = true)) on ((mytc.finish = catalog.id) or (mytc.start = catalog.id))) ORDER BY qtbl.id;");
          #endif