• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

projecteditor.h

Go to the documentation of this file.
00001 #ifndef PROJECTSEDITOR_H
00002 #define PROJECTSEDITOR_H
00003 
00004 #include <QDebug>
00005 
00006 #include "baseeditor.h"
00007 #include "database.h"
00008 #include "global.h"
00009 
00013 class PrivilegeEditor : public QTableView {
00014 public:
00015     PrivilegeEditor(QWidget *parent = 0) : QTableView(parent) {
00016         setWindowTitle("Privilege Editor");
00017 
00018         // model setup
00019         SqlTableModel *privModel = new SqlTableModel(this, Database::staticCon());
00020         privModel->setEditStrategy(QSqlTableModel::OnFieldChange);
00021         privModel->setTable("vew_project_privileges");
00022         setModel(privModel);
00023 
00024         // model header setup (no need to call model()->select() for this as the model has allready fetched the field-data)
00025         privModel->setHeaderData(privModel->record().indexOf("rls_user_name"), Qt::Horizontal, "user", Qt::DisplayRole);
00026         privModel->setHeaderData(privModel->record().indexOf("proj_name"), Qt::Horizontal, "project", Qt::DisplayRole);
00027 
00028         QString ownerToolTip("<body>Shows whether the user is the owner of (i.e. has made the) the project or not. Owners have full access to the project they own. They can also grant privileges to others for the projects they own.</body>");
00029         QString readToolTip("<body>Shows whether the user can see the project and it's dependencies: the setup and sensor data.</body>");
00030         QString writeToolTip("<body>Shows whether the user can adjust the projectdependant data: the project record, setup?, add data?</body>");
00031         QString deleteToolTip("<body>Shows whether the user can delete projectdependant data, such as the setup, the sensor data, but also the project itself? = miss best alleen de owner?</body>");
00032         privModel->setHeaderData(privModel->record().indexOf("owner"), Qt::Horizontal, ownerToolTip, Qt::ToolTipRole);
00033         privModel->setHeaderData(privModel->record().indexOf("read"), Qt::Horizontal, readToolTip, Qt::ToolTipRole);
00034         privModel->setHeaderData(privModel->record().indexOf("write"), Qt::Horizontal, writeToolTip, Qt::ToolTipRole);
00035         privModel->setHeaderData(privModel->record().indexOf("delete"), Qt::Horizontal, deleteToolTip, Qt::ToolTipRole);
00036     }
00037 
00038     SqlTableModel *model() const {
00039         Q_ASSERT(QTableView::model());
00040         SqlTableModel *m = dynamic_cast<SqlTableModel*>(QTableView::model());
00041         Q_ASSERT(m);
00042         return m;
00043     }
00044 
00045     void hideColumn(const QString &columnName) {
00046         hideColumn(model()->record().indexOf(columnName));
00047     }
00048 
00049     void hideColumn(int column) {
00050         QTableView::hideColumn(column);
00051     }
00052 
00053     void select() {
00054         model()->select();
00055     }
00056 };
00057 
00058 #include <QGroupBox>
00059 #include <QSpacerItem>
00060 #include <QCheckBox>
00061 #include <QLabel>
00062 #include <QLineEdit>
00063 
00069 class UserEditor : public MappedBaseEditor {
00070     Q_OBJECT
00071 public:
00072     UserEditor(QWidget *parent = 0) : MappedBaseEditor(parent), privView(new PrivilegeEditor(this)) {
00073         setObjectName("UserEditor");
00074         setWindowTitle("User editor");
00075 
00076         //set source
00077         setTable("tbl_users", "user_name", Qt::AscendingOrder);
00078         model()->setRowIdentifierField("user_name");
00079 
00080         // widget setup
00081         QLabel *name = new QLabel("&Name*:", this);
00082         QLabel *pwd = new QLabel("&Password:", this);
00083         QLabel *priv = new QLabel("Project &rights:", this);
00084         QLineEdit *nameEdit = new QLineEdit(this);
00085         QLineEdit *pwdEdit = new QLineEdit(this);
00086         pwdEdit->setReadOnly(true);
00087         name->setBuddy(nameEdit);
00088         priv->setBuddy(privView);
00089         pwd->setBuddy(pwdEdit);
00090 
00091         // privilege box
00092         QGroupBox *privBox = new QGroupBox("Privileges", this);
00093         privBox->setLayout(new QVBoxLayout());
00094         QCheckBox *isAdmin = new QCheckBox("Admin", privBox);
00095         QCheckBox *canCreateProjects = new QCheckBox("Create projects", privBox);
00096         privBox->layout()->addWidget(isAdmin);
00097         privBox->layout()->addWidget(canCreateProjects);
00098         dynamic_cast<QBoxLayout*>(privBox->layout())->addStretch(0);
00099 
00100         // privileges hide columns
00101         privView->hideColumn("rls_user_name");
00102 
00103         // add widgets
00104         addWidget(name, 0, 0, 1, 1);
00105         addWidget(nameEdit, 0, 1, 1, 1, "user_name");
00106         addWidget(pwd, 1, 0, 1, 1);
00107         addWidget(pwdEdit, 1, 1, 1, 1, "password");
00108         addWidget(priv, 2, 0, 1, 2);
00109         addWidget(privView, 3, 0, 1, 2);
00110         addWidget(privBox, 0, 3, 4, 1);
00111 
00112         // add extra widget mappings
00113         addWidgetMapping(isAdmin, "isadmin");
00114         addWidgetMapping(canCreateProjects, "cancreateproject");
00115 
00116         // setup connections
00117         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00118         connect(isAdmin, SIGNAL(toggled(bool)), this, SLOT(updateButtons()));
00119         connect(canCreateProjects, SIGNAL(toggled(bool)), this, SLOT(updateButtons()));
00120 
00121         // update changes
00122         select();
00123         privView->select();
00124     }
00125 
00126 protected:
00127     virtual void onCurrentRecordChange(int row){
00128         MappedBaseEditor::onCurrentRecordChange(row);
00129         updatePrivilegesView();
00130     }
00131 
00132 private:
00133     void updatePrivilegesView(){
00134         Q_ASSERT(model()->record().indexOf("user_name") != -1);
00135         QString user_name = model()->index(currentMapperRow(), model()->record().indexOf("user_name")).data(Qt::DisplayRole).toString();
00136         privView->model()->setFilter("rls_user_name = '" + user_name + "'"); // auto selects if was previously selected
00137     }
00138 
00139 private:
00140     PrivilegeEditor *privView;
00141 };
00142 
00143 #include <QTextEdit>
00144 
00153 class ProjectEditor : public MappedBaseEditor {
00154     Q_OBJECT
00155 public:
00156     ProjectEditor(QWidget *parent = 0) : MappedBaseEditor(parent), privView(new PrivilegeEditor(this)) {
00157         setObjectName("ProjectEditor");
00158         setWindowTitle("Project editor");
00159 
00160         //set source
00161         setTable("tbl_projects", "proj_name", Qt::AscendingOrder);
00162 
00163         // widget setup
00164         QLabel *name = new QLabel("&Name*:", this);
00165         QLabel *desc = new QLabel("&Description*:", this);
00166         QLabel *owner = new QLabel("&Owner:", this);
00167         QLabel *priv = new QLabel("User &rights:", this);
00168         QLineEdit *nameEdit = new QLineEdit(this);
00169         QTextEdit *descEdit = new QTextEdit(this);
00170         QComboBox *ownerEdit = new QComboBox(this);
00171         name->setBuddy(nameEdit);
00172         desc->setBuddy(descEdit);
00173         owner->setBuddy(ownerEdit);
00174         priv->setBuddy(privView);
00175 
00176         // privileges hide columns
00177         privView->hideColumn("proj_name");
00178         privView->hideColumn("owner");
00179 
00180         // add widgets
00181         addWidget(name, 0, 0, 1, 1);
00182         addWidget(nameEdit, 0, 1, 1, 1, "proj_name");
00183         addWidget(owner, 1, 0, 1, 1);
00184         addWidget(ownerEdit, 1, 1, 1, 1, QSqlRelation("tbl_users", "user_name", "user_name"), "rls_owner");
00185         addWidget(desc, 2, 0, 1, 2);
00186         addWidget(descEdit, 3, 0, 1, 2, "proj_desc", "plainText");
00187         addWidget(priv, 0, 2, 1, 1);
00188         addWidget(privView, 1, 2, 3, 1);
00189 
00190         // setup connections
00191         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00192         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00193         connect(ownerEdit, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
00194 
00195         // update changes
00196         select();
00197         privView->select();
00198     }
00199 
00200 protected:
00201     virtual void onCurrentRecordChange(int row){
00202         MappedBaseEditor::onCurrentRecordChange(row);
00203         updatePrivilegesView();
00204     }
00205 
00206 private:
00207     void updatePrivilegesView(){
00208         Q_ASSERT(model()->record().indexOf("proj_name") != -1);
00209         QString proj_name = model()->index(currentMapperRow(), model()->record().indexOf("proj_name")).data(Qt::DisplayRole).toString();
00210         privView->model()->setFilter("proj_name = '" + proj_name + "'"); // auto selects if was previously selected
00211     }
00212 
00213 private:
00214     PrivilegeEditor *privView;
00215 };
00216 
00222 class LocationEditor : public MappedBaseEditor {
00223     Q_OBJECT
00224 public:
00225     LocationEditor(QWidget *parent = 0) : MappedBaseEditor(parent) {
00226         setObjectName("LocationEditor");
00227         setWindowTitle("Location editor");
00228 
00229         //set source
00230         setTable("tbl_locations", "loca_country", Qt::AscendingOrder);
00231 
00232         // widget setup
00233         QLabel *country = new QLabel("&Country*:", this);
00234         QLabel *region = new QLabel("&City*:", this);
00235         QLabel *postalCode = new QLabel("&Postal code:", this);
00236         QLabel *address = new QLabel("&Address:", this);
00237         QLabel *phone = new QLabel("Phone &number:", this);
00238         QLabel *desc = new QLabel("Decription:", this);
00239         QLineEdit *countryEdit = new QLineEdit(this);
00240         QLineEdit *regionEdit = new QLineEdit(this);
00241         QLineEdit *postalCodeEdit = new QLineEdit(this);
00242         QTextEdit *addressEdit = new QTextEdit(this);
00243         QLineEdit *phoneEdit = new QLineEdit(this);
00244         QTextEdit *descEdit = new QTextEdit(this);
00245         country->setBuddy(countryEdit);
00246         region->setBuddy(regionEdit);
00247         postalCode->setBuddy(postalCodeEdit);
00248         address->setBuddy(addressEdit);
00249         phone->setBuddy(phoneEdit);
00250         desc->setBuddy(descEdit);
00251 
00252         QSizePolicy policy(addressEdit->sizePolicy());
00253         policy.setVerticalStretch(1);
00254         addressEdit->setSizePolicy(policy);
00255         policy.setVerticalStretch(2);
00256         descEdit->setSizePolicy(policy);
00257 
00258         // add widgets
00259         addWidget(country, 0, 0, 1, 1);
00260         addWidget(countryEdit, 0, 1, 1, 1, "loca_country");
00261         addWidget(region, 1, 0, 1, 1);
00262         addWidget(regionEdit, 1, 1, 1, 1, "loca_region");
00263         addWidget(postalCode, 2, 0, 1, 1);
00264         addWidget(postalCodeEdit, 2, 1, 1, 1, "loca_postalcode");
00265         addWidget(address, 3, 0, 1, 1);
00266         addWidget(addressEdit, 3, 1, 1, 1, "loca_address", "plainText");
00267         addWidget(phone, 4, 0, 1, 1);
00268         addWidget(phoneEdit, 4, 1, 1, 1, "loca_phone");
00269         addWidget(desc, 5, 0, 1, 1);
00270         addWidget(descEdit, 5, 1, 1, 1, "loca_desc", "plainText");
00271 
00272         // setup connections
00273         connect(countryEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00274         connect(regionEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00275         connect(postalCodeEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00276         connect(addressEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00277         connect(phoneEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00278         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00279 
00280         // update changes
00281         select();
00282     }
00283 };
00284 
00290 class InstallationEditor : public MappedBaseEditor {
00291     Q_OBJECT
00292 public:
00293     InstallationEditor(QWidget *parent = 0) : MappedBaseEditor(parent) {
00294         setObjectName("InstallationEditor");
00295         setWindowTitle("Installation editor");
00296 
00297         //set source
00298         setTable("tbl_installations", "inst_type", Qt::AscendingOrder);
00299 
00300         // widget setup
00301         QLabel *type = new QLabel("&Type*:", this);
00302         QLabel *desc = new QLabel("&Description*:", this);
00303         QLineEdit *typeEdit = new QLineEdit(this);
00304         QTextEdit *descEdit = new QTextEdit(this);
00305         type->setBuddy(typeEdit);
00306         desc->setBuddy(descEdit);
00307 
00308         // add widgets
00309         addWidget(type, 0, 0, 1, 1);
00310         addWidget(typeEdit, 0, 1, 1, 1, "inst_type");
00311         addWidget(desc, 1, 0, 1, 1);
00312         addWidget(descEdit, 2, 0, 1, 2, "inst_desc", "plainText");
00313 
00314         // setup connections
00315         connect(typeEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00316         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00317 
00318         // update changes
00319         select();
00320     }
00321 };
00322 
00328 class UnitEditor : public MappedBaseEditor {
00329     Q_OBJECT
00330 public:
00331     UnitEditor(QWidget *parent = 0) : MappedBaseEditor(parent) {
00332         setObjectName("UnitEditor");
00333         setWindowTitle("Unit editor");
00334 
00335         //set source
00336         setTable("tbl_units", "unit_name", Qt::AscendingOrder);
00337 
00338         // widget setup
00339         QLabel *name = new QLabel("&Name*:", this);
00340         QLabel *symbol = new QLabel("&Symbol*:", this);
00341         QLineEdit *nameEdit = new QLineEdit(this);
00342         QLineEdit *symbolEdit = new QLineEdit(this);
00343         name->setBuddy(nameEdit);
00344         symbol->setBuddy(symbolEdit);
00345 
00346         // add widgets
00347         addWidget(name, 0, 0, 1, 1);
00348         addWidget(nameEdit, 0, 1, 1, 1, "unit_name");
00349         addWidget(symbol, 1, 0, 1, 1);
00350         addWidget(symbolEdit, 1, 1, 1, 1, "unit_symbol");
00351 
00352         // setup connections
00353         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00354         connect(symbolEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00355 
00356         // update changes
00357         select();
00358     }
00359 };
00360 
00366 class SensorCategoryEditor : public MappedBaseEditor {
00367     Q_OBJECT
00368 public:
00369     SensorCategoryEditor(QWidget *parent = 0) : MappedBaseEditor(parent) {
00370         setObjectName("SensorCategoryEditor");
00371         setWindowTitle("Sensor category editor");
00372 
00373         //set source
00374         setTable("tbl_sensor_categories", "sens_cate_name", Qt::AscendingOrder);
00375 
00376         // widget setup
00377         QLabel *name = new QLabel("&Name*:", this);
00378         QLabel *desc = new QLabel("&Description:", this);
00379         QLineEdit *nameEdit = new QLineEdit(this);
00380         QTextEdit *descEdit = new QTextEdit(this);
00381         name->setBuddy(nameEdit);
00382         desc->setBuddy(descEdit);
00383 
00384         // add widgets
00385         addWidget(name, 0, 0, 1, 1);
00386         addWidget(nameEdit, 0, 1, 1, 1, "sens_cate_name");
00387         addWidget(desc, 1, 0, 1, 1);
00388         addWidget(descEdit, 2, 0, 1, 2, "sens_cate_desc", "plainText");
00389 
00390         // setup connections
00391         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00392         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00393 
00394         // update changes
00395         select();
00396     }
00397 };
00398 
00399 #include <QDateTimeEdit>
00405 class SensorChannelCalibrationEditor : public MappedBaseEditor {
00406     Q_OBJECT
00407 public:
00408     SensorChannelCalibrationEditor(int sens_id, int sens_chan_nr, int positionOnId = -1 /* = sens_chan_cali_id */, QWidget *parent = 0)
00409         : MappedBaseEditor(parent), m_sens_id(sens_id), m_sens_chan_nr(sens_chan_nr) {
00410         setObjectName("SensorChannelCalibrationEditor");
00411 
00412         // set units
00413         QSqlRecord result = Database::execStaticR(QString("SELECT su.unit_symbol AS unit_from, scu.unit_symbol AS unit_to, s.unit_id, sc.sens_chan_cali_unit_id "
00414                                                           "FROM tbl_sensors s "
00415                                                           "INNER JOIN tbl_sensor_channels sc USING (sens_id) "
00416                                                           "INNER JOIN tbl_units su ON (s.unit_id = su.unit_id) "
00417                                                           "INNER JOIN tbl_units scu ON (sc.sens_chan_cali_unit_id = scu.unit_id) "
00418                                                           "WHERE sens_id = %1 AND sens_chan_nr = %2")
00419                                                   .arg(QString::number(m_sens_id), QString::number(m_sens_chan_nr)));
00420         bool ok;
00421         m_sens_unit_id = result.value("unit_id").toInt(&ok);
00422         Q_ASSERT(ok);
00423         m_sens_chan_cali_unit_id = result.value("sens_chan_cali_unit_id").toInt(&ok);
00424         Q_ASSERT(ok);
00425 
00426         // sanity check
00427         Q_ASSERT(sens_id > 0);
00428         Q_ASSERT(sens_chan_nr > 0);
00429 
00430         // convert constraint numbers to strings
00431         const QString sens_id_str = QString::number(sens_id);
00432         const QString sens_chan_nr_str = QString::number(sens_chan_nr);
00433 
00434         // make title
00435         static const QString baseQuery("SELECT sens_type || ' [SN: ' || sens_serialnr || '] Channel #' || sens_chan_nr "
00436                                 "FROM tbl_sensors s INNER JOIN tbl_sensor_channels sc USING (sens_id) "
00437                                 "WHERE sens_id = %1 AND sens_chan_nr = %2");
00438         const QString query(baseQuery.arg(sens_id_str, sens_chan_nr_str));
00439         const QString title = Database::execStaticR(query).value(0).toString();
00440 
00441         // set window title
00442         setWindowTitle(QString("Calibration editor for ").append(title));
00443 
00444         // set source
00445         setTable("tbl_sensor_channel_calibrations", "sens_chan_cali_timestamp", Qt::DescendingOrder, "sens_id = " + sens_id_str + " AND sens_chan_nr = " + sens_chan_nr_str);
00446         
00447         // widget setup
00448         QLabel *timestamp = new QLabel("&Timestamp*:", this);
00449         QLabel *formula = new QLabel(QString("&Formula* [%1]->[%2]:").arg(result.value("unit_from").toString(), result.value("unit_to").toString()), this);
00450         QLabel *desc = new QLabel("&Description:", this);
00451         QDateTimeEdit *timestampEdit = new QDateTimeEdit(this);
00452         QLineEdit *formulaEdit = new QLineEdit(this);
00453         QTextEdit *descEdit = new QTextEdit(this);
00454         timestamp->setBuddy(timestampEdit);
00455         formula->setBuddy(timestampEdit);
00456         desc->setBuddy(descEdit);
00457 
00458         // adjust imput widgets
00459         timestampEdit->setCalendarPopup(true);
00460 
00461         // add widgets
00462         addWidget(timestamp, 0, 0, 1, 1);
00463         addWidget(timestampEdit, 0, 1, 1, 1, "sens_chan_cali_timestamp");
00464         addWidget(formula, 1, 0, 1, 1);
00465         addWidget(formulaEdit, 1, 1, 1, 1, "sens_chan_cali_formula");
00466         addWidget(desc, 2, 0, 1, 1);
00467         addWidget(descEdit, 3, 0, 1, 2, "sens_chan_cali_desc", "plainText");
00468 
00469         // setup connections
00470         connect(timestampEdit, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(updateButtons()));
00471         connect(formulaEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00472         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00473 
00474         // setup formula note
00475         QLabel *formulaNote = new QLabel(GlobalConst::CALI_FORMULA_HELP, this);
00476         formulaNote->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
00477         formulaNote->setOpenExternalLinks(true);
00478         formulaNote->setWordWrap(true);
00479         bottomLayout()->addWidget(bottomLayout()->itemAtPosition(0, 0)->widget(), 1, 0);
00480         bottomLayout()->addWidget(formulaNote, 0, 0);
00481 
00482         // update changes
00483         select();
00484 
00485         // update mapper to current record
00486         if (positionOnId > 0) setCurrent("sens_chan_cali_id", QVariant::fromValue<int>(positionOnId));
00487     }
00488 
00489 protected:
00490     virtual void onNewButtonPress(){
00491          MappedBaseEditor::onNewButtonPress();
00492          model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_id")),
00493                         QVariant::fromValue(m_sens_id));
00494          model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_chan_nr")),
00495                         QVariant::fromValue(m_sens_chan_nr));
00496          model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_chan_cali_unit_from_id")),
00497                         QVariant::fromValue(m_sens_unit_id));
00498          model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_chan_cali_unit_to_id")),
00499                         QVariant::fromValue(m_sens_chan_cali_unit_id));
00500      }
00501 
00502 private:
00503     const int m_sens_id;
00504     const int m_sens_chan_nr;
00505     int m_sens_unit_id;
00506     int m_sens_chan_cali_unit_id;
00507 };
00508 
00509 #include <QDialog>
00510 #include <QModelIndex>
00511 #include <QMouseEvent>
00512 
00516 class CalibrationEditDialog : public QDialog {
00517 public:
00518     CalibrationEditDialog(int sens_id, int sens_chan_nr, int positionOnId /* = sens_chan_cali_id */, QWidget *parent = 0) : QDialog(parent) {
00519         SensorChannelCalibrationEditor *editor = new SensorChannelCalibrationEditor(sens_id, sens_chan_nr, positionOnId, this);
00520 
00521         setWindowTitle(editor->windowTitle());
00522 
00523         setLayout(new QVBoxLayout);
00524         layout()->addWidget(editor);
00525 
00526         connect(editor, SIGNAL(closeRequested()),
00527                 this, SLOT(close()));
00528     }
00529 };
00530 
00531 #include <QSqlError>
00532 
00536 class SensorChannelCalibrationsView : public QListView {
00537 public:
00538     SensorChannelCalibrationsView(int sens_id, int sens_chan_nr, QWidget *parent = 0) : QListView(parent) {
00539         // setup base query
00540         baseQuery = QString("SELECT '#' || row_number() OVER (PARTITION BY scc.sens_id, scc.sens_chan_nr ORDER BY scc.sens_chan_cali_timestamp ASC) || ' @ ' || sens_chan_cali_timestamp || ': ' || replace(sens_chan_cali_formula, '$1', 'RAW') || '' AS Calibrations, sens_chan_cali_id "
00541                             "FROM tbl_sensor_channel_calibrations scc "
00542                             "WHERE scc.sens_id = %1 AND scc.sens_chan_nr = %2 "
00543                             "ORDER BY scc.sens_chan_cali_timestamp DESC");
00544 
00545         // pk validity check
00546         Q_ASSERT(sens_id > 0);
00547         // sens_chan_nr > 0 geldt niet, bijvoorbeeld voor een nieuwe sensor!
00548 
00549         // setup model
00550         setModel(new SqlQueryModel(this));
00551         model()->setDependency("tbl_sensor_channel_calibrations");
00552 
00553         // constrain model
00554         setConstraint(sens_id, sens_chan_nr);
00555     }
00556 
00557     SqlQueryModel *model() const {
00558         Q_ASSERT(QListView::model()); // roep hier niet model() --> infinite loop!
00559         Q_ASSERT(dynamic_cast<SqlQueryModel*>(QListView::model()));
00560         return dynamic_cast<SqlQueryModel*>(QListView::model());
00561     }
00562 
00563     void setConstraint(int sens_id, int sens_chan_nr){
00564         // pk validity check
00565         Q_ASSERT(sens_id > 0);
00566         if (sens_chan_nr <= 0) return;
00567 
00568         this->sens_id = sens_id;
00569         this->sens_chan_nr = sens_chan_nr;
00570 
00571         model()->setQuery(Database::execStatic(baseQuery.arg(QString::number(sens_id), QString::number(sens_chan_nr))));
00572 
00573         if (model()->query().lastError().isValid()) {
00574             qWarning() << "Unable to constrain SensorChannelCalibrationView with " << sens_id << " and " << sens_chan_nr;
00575             model()->clear();
00576         }
00577     }
00578 
00579 protected:
00580     virtual void setModel(SqlQueryModel *model) {
00581         QListView::setModel(model);
00582     }
00583 
00584     virtual void mouseDoubleClickEvent(QMouseEvent *event){
00585         QModelIndex idx = indexAt(event->pos());
00586         if (idx.isValid() || model()->rowCount() == 0) {
00587             Q_ASSERT(model()->record().indexOf("sens_chan_cali_id") != -1 || model()->rowCount() == 0); // cannot be found = -1
00588             int sens_chan_cali_id = -1;
00589             if (model()->rowCount() != 0) {
00590                 bool ok;
00591                 sens_chan_cali_id = model()->index(idx.row(), model()->record().indexOf("sens_chan_cali_id")).data(Qt::DisplayRole).toInt(&ok);
00592                 Q_ASSERT(ok);
00593             }
00594             Q_ASSERT(sens_id > 0);
00595             Q_ASSERT(sens_chan_nr > 0); // Dit is de constraint van de DB
00596             CalibrationEditDialog e(sens_id, sens_chan_nr, sens_chan_cali_id, this);
00597             e.exec();
00598         }
00599     }
00600 
00601 private:
00602     int sens_id;
00603     int sens_chan_nr;
00604     QString baseQuery;
00605 };
00606 
00607 #include <QSpinBox>
00608 
00614 class SensorChannelEditor : public MappedBaseEditor {
00615     Q_OBJECT
00616 public:
00617     SensorChannelEditor(QWidget *parent = 0, int sens_id = -1, int sens_chan_nr = -1) : MappedBaseEditor(parent) {
00618         setObjectName("SensorChannelEditor");
00619         setWindowTitle("Sensor channel editor");
00620 
00621         //set source
00622         setTable("tbl_sensor_channels", "sens_chan_nr", Qt::AscendingOrder,
00623                  sens_id != -1 ? QString::number(sens_id).prepend("sens_id = ") : QString());
00624 
00625         // widget setup
00626         QLabel *name = new QLabel("&Name*:", this);
00627         QLabel *nr = new QLabel("Numbe&r* (>0):", this);
00628         QLabel *caliUnit = new QLabel("&Calibrated unit*:", this);
00629         QLabel *desc = new QLabel("&Description:", this);
00630         QLineEdit *nameEdit = new QLineEdit(this);
00631         QSpinBox *nrEdit = new QSpinBox(this);
00632         QComboBox *caliUnitEdit = new QComboBox(this);
00633         QTextEdit *descEdit = new QTextEdit(this);
00634         name->setBuddy(nameEdit);
00635         nr->setBuddy(nrEdit);
00636         caliUnit->setBuddy(caliUnitEdit);
00637         desc->setBuddy(descEdit);
00638 
00639         // set calibrations view
00640         QLabel *cLabel = new QLabel("&Calibrations:", this);
00641         cView = new SensorChannelCalibrationsView(sens_id, sens_chan_nr, this);
00642         cView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
00643         cLabel->setBuddy(cView);
00644 
00645         // add widgets
00646         addWidget(name, 0, 0, 1, 1);
00647         addWidget(nameEdit, 0, 1, 1, 1, "sens_chan_name");
00648         addWidget(nr, 1, 0, 1, 1);
00649         addWidget(nrEdit, 1, 1, 1, 1, "sens_chan_nr");
00650         addWidget(caliUnit, 0, 2, 1, 1);
00651         addWidget(caliUnitEdit, 0, 3, 1, 1, QSqlRelation("tbl_units", "unit_id", "unit_symbol"), "sens_chan_cali_unit_id");
00652         addWidget(cLabel, 1, 2, 1, 2);
00653         addWidget(cView, 2, 2, 2, 2);
00654         addWidget(desc, 2, 0, 1, 1);
00655         addWidget(descEdit, 3, 0, 1, 2, "sens_chan_desc", "plainText");
00656 
00657         // setup connections
00658         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00659         connect(nrEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButtons()));
00660         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00661         connect(caliUnitEdit, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
00662 
00663         // update changes
00664         select();
00665 
00666         // update mapper to current record
00667         if (sens_chan_nr > 0) setCurrent("sens_chan_nr", QVariant::fromValue<int>(sens_chan_nr));
00668 
00669         // update cView
00670         if (sens_chan_nr > 0) cView->setConstraint(sens_id == -1 ? 0 : sens_id, sens_id == -1 ? 0 : sens_chan_nr);
00671     }
00672 
00673 protected:
00674     virtual void onCurrentRecordChange(int row){
00675         MappedBaseEditor::onCurrentRecordChange(row);
00676         updateSensorChannelView();
00677     }
00678 
00679     virtual void updateButtons(){
00680         MappedBaseEditor::updateButtons();
00681         cView->setDisabled(isCurrentRecordNew() || model()->rowCount() == 0);
00682     }
00683 
00684     virtual void onNewButtonPress(){
00685          MappedBaseEditor::onNewButtonPress();
00686          bool ok;
00687          model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_id")),
00688                         QVariant::fromValue(model()->filter().remove("sens_id = ").toInt(&ok)));
00689          Q_ASSERT(ok);
00690      }
00691 
00692 private:
00693     void updateSensorChannelView(){
00694         Q_ASSERT(cView);
00695         bool ok;
00696         int sens_id = model()->index(currentMapperRow(), model()->record().indexOf("sens_id")).data(Qt::DisplayRole).toInt(&ok);
00697         Q_ASSERT(ok);
00698         int sens_chan_nr = model()->index(currentMapperRow(), model()->record().indexOf("sens_chan_nr")).data(Qt::DisplayRole).toInt(&ok);
00699         Q_ASSERT(ok);
00700         if (!ok || sens_id == 0 || sens_id == -1 || sens_chan_nr == 0 || sens_chan_nr == -1){
00701             cView->model()->clear();
00702         } else {
00703             cView->setConstraint(sens_id, sens_chan_nr);
00704         }
00705     }
00706 
00707 private:
00708     SensorChannelCalibrationsView *cView;
00709 };
00710 
00711 #include <QDialog>
00712 #include <QVBoxLayout>
00713 
00717 class SensorChannelEditDialog : public QDialog {
00718 public:
00719     SensorChannelEditDialog(int sens_id, int sens_chan_nr /*= position*/, QWidget *parent = 0) : QDialog(parent) {
00720         SensorChannelEditor *editor = new SensorChannelEditor(this, sens_id, sens_chan_nr);
00721         setWindowTitle(editor->windowTitle());
00722 
00723         setLayout(new QVBoxLayout);
00724         layout()->addWidget(editor);
00725 
00726         connect(editor, SIGNAL(closeRequested()),
00727                 this, SLOT(close()));
00728     }
00729 };
00730 
00731 #include <QSqlQueryModel>
00732 
00736 class SensorChannelModel : public SqlQueryModel {
00737     Q_OBJECT
00738 public:
00739     enum Field {
00740         FieldSensorId = Qt::UserRole,
00741         FieldSensorChannelNr,
00742         FieldSensorCustomName
00743     };
00744 
00745     SensorChannelModel(QObject *parent = 0) : SqlQueryModel(parent), sens_id(0){
00746         setDependency("tbl_sensor_channel_calibrations");
00747         setDependency("tbl_sensor_channels");
00748 
00749         defaultQuery = QString("SELECT '#' || sens_chan_nr || ': ' || sens_chan_name || COALESCE(' [' || (SELECT count(*)  || ' calibrations: last @ ' || max(sens_chan_cali_timestamp) || ']' FROM tbl_sensor_channel_calibrations scc WHERE scc.sens_id = c.sens_id AND scc.sens_chan_nr = c.sens_chan_nr)::text, ' [Never calibrated]'), "
00750                                "sens_id, sens_chan_nr, "
00751                                "sens_type || ' (' || sens_serialnr || ')' "
00752                                "FROM tbl_sensor_channels c "
00753                                "INNER JOIN tbl_sensors s USING (sens_id) ");
00754         unconstrain();
00755     }
00756 
00757     QVariant data(const QModelIndex &index, int role) const {
00758         if (!index.isValid())
00759             return QVariant();
00760 
00761         switch (role) {
00762         case SensorChannelModel::FieldSensorId:
00763             return QSqlQueryModel::data(this->index(index.row(), 1));
00764         case SensorChannelModel::FieldSensorChannelNr:
00765             return QSqlQueryModel::data(this->index(index.row(), 2));
00766         case SensorChannelModel::FieldSensorCustomName:
00767             return QSqlQueryModel::data(this->index(index.row(), 3));
00768         default:
00769             return QSqlQueryModel::data(index, role);
00770         }
00771     }
00772 
00773     void setConstraint(const int &sens_id){
00774         this->sens_id = sens_id;
00775         setQuery(Database::execStatic(defaultQuery + QString(" WHERE sens_id = ") + QString::number(sens_id) + " ORDER BY sens_id, sens_chan_nr "));
00776 
00777         // This should check whether constraint is successfull;
00778         if (query().lastError().isValid()) {
00779             unconstrain();
00780             return;
00781         }
00782 
00783         constrained = true;
00784     }
00785 
00786     int constraint(){
00787         return sens_id;
00788     }
00789 
00790     void unconstrain(){
00791         setQuery(Database::execStatic(defaultQuery + " ORDER BY sens_id, sens_chan_nr "));
00792         constrained = false;
00793         sens_id = 0;
00794     }
00795 
00796 private slots:
00797 private:
00798     QString defaultQuery;
00799     bool constrained;
00800     int sens_id;
00801 };
00802 
00803 #include <QListView>
00804 #include <QSqlQueryModel>
00805 #include <QMouseEvent>
00806 
00810 class SensorChannelView : public QListView {
00811     Q_OBJECT
00812 public:
00813     SensorChannelView(QWidget *parent = 0) : QListView(parent) {
00814         setModel(new SensorChannelModel(this));
00815     }
00816 
00817     SensorChannelModel *model(){
00818         Q_ASSERT(dynamic_cast<SensorChannelModel*>(QListView::model()));
00819         return dynamic_cast<SensorChannelModel*>(QListView::model());
00820     }
00821 
00822 private slots:
00823     virtual void mouseDoubleClickEvent(QMouseEvent *event){
00824         // Hier kon even goed de "virtual void mouseDoubleClickEvent(QMouseEvent *event)"
00825         // geimplementeerd worden daar het standaard SIGNAL(doubleClicked(QModelIndex)
00826         // zendt en item editable maakt.
00827         QModelIndex index = indexAt(event->pos());
00828         if (index.isValid() || model()->rowCount() == 0) {
00829             int sens_id = model()->constraint();
00830             int sens_chan_nr = index.data(SensorChannelModel::FieldSensorChannelNr).toInt();
00831             Q_ASSERT(sens_id);
00832             SensorChannelEditDialog e(sens_id, sens_chan_nr, this);
00833             e.exec();
00834             model()->reQuery();
00835         }
00836     }
00837 };
00838 
00839 #include <QComboBox>
00840 #include <QSqlRelation>
00841 
00847 class SensorEditor : public MappedBaseEditor {
00848     Q_OBJECT
00849 public:
00850     SensorEditor(QWidget *parent = 0) :
00851             MappedBaseEditor(parent), channelView(new SensorChannelView(this)) {
00852         setObjectName("SesnorEditor");
00853         setWindowTitle("Sensor editor");
00854 
00855         // set source
00856         setTable("tbl_sensors");
00857 
00858         // widget setup
00859         QLabel *type = new QLabel("&Type*:", this);
00860         QLabel *sn = new QLabel("&Serial number*:", this);
00861         QLabel *name = new QLabel("&Name:", this);
00862         QLabel *category = new QLabel("&Category*:", this);
00863         QLabel *unit = new QLabel("&Unit*:", this);
00864         QLabel *desc = new QLabel("Description:", this);
00865         QLineEdit *typeEdit = new QLineEdit(this);
00866         QLineEdit *snEdit = new QLineEdit(this);
00867         QLineEdit *nameEdit = new QLineEdit(this);
00868         QComboBox *categoryEdit = new QComboBox(this);
00869         QComboBox *unitEdit = new QComboBox(this);
00870         QTextEdit *descEdit = new QTextEdit(this);
00871         type->setBuddy(typeEdit);
00872         sn->setBuddy(snEdit);
00873         name->setBuddy(nameEdit);
00874         category->setBuddy(categoryEdit);
00875         unit->setBuddy(unitEdit);
00876         desc->setBuddy(descEdit);
00877 
00878         // add channels widget
00879         QLabel *channels = new QLabel("&Channels:\n(Doubleclick to edit/add/delete)", this);
00880         channels->setBuddy(channelView);
00881         channelView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); //descEdit is enige met QSizePolicy::ExpandFlag
00882 
00883         // add widgets
00884         addWidget(type, 0, 0, 1, 1);
00885         addWidget(typeEdit, 0, 1, 1, 1, "sens_type");
00886         addWidget(sn, 1, 0, 1, 1);
00887         addWidget(snEdit, 1, 1, 1, 1, "sens_serialnr");
00888         addWidget(name, 2, 0, 1, 1);
00889         addWidget(nameEdit, 2, 1, 1, 1, "sens_name");
00890         addWidget(category, 3, 0, 1, 1);
00891         addWidget(categoryEdit, 3, 1, 1, 1, QSqlRelation("tbl_sensor_categories", "sens_cate_id", "sens_cate_name"));
00892         addWidget(unit, 4, 0, 1, 1);
00893         addWidget(unitEdit, 4, 1, 1, 1, QSqlRelation("vew_sensor_units", "unit_id", "unit_symbol"));
00894         addWidget(channels, 0, 2, 1, 1);
00895         addWidget(channelView, 1, 2, 4, 1);
00896         addWidget(desc, 5, 0, 1, 3);
00897         addWidget(descEdit, 6, 0, 1, 3, "sens_desc", "plainText");
00898 
00899         // setup connections
00900         connect(typeEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00901         connect(snEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00902         connect(nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
00903         connect(categoryEdit, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
00904         connect(unitEdit, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
00905         connect(descEdit, SIGNAL(textChanged()), this, SLOT(updateButtons()));
00906 
00907         // update changes
00908         select();
00909     }
00910 protected:
00911     virtual void onCurrentRecordChange(int row){
00912         MappedBaseEditor::onCurrentRecordChange(row);
00913         updateSensorChannelView();
00914     }
00915 
00916     virtual void updateButtons(){
00917         MappedBaseEditor::updateButtons();
00918         channelView->setDisabled(isCurrentRecordNew() || model()->rowCount() == 0);
00919     }
00920 
00921     virtual void onQueryChange(){
00922         MappedBaseEditor::onQueryChange();
00923         updateSensorChannelView();
00924     }
00925 
00926 private:
00927     void updateSensorChannelView(){
00928         Q_ASSERT(channelView);
00929         bool ok;
00930         int sens_id = currentPrimaryKey().value("sens_id").toInt(&ok);
00931         if (!ok || sens_id == 0 || sens_id == -1 ){
00932             channelView->model()->clear();
00933         } else {
00934             channelView->model()->setConstraint(sens_id);
00935         }
00936     }
00937 
00938 private:
00939     SensorChannelView *channelView;
00940 };
00941 
00942 #include "global.h"
00943 #include <QSqlField>
00944 #include <QListView>
00945 #include <QSqlQueryModel>
00946 #include <QPushButton>
00947 
00953 class SensorUnitEditor : public BaseEditor {
00954     Q_OBJECT
00955 public:
00956     SensorUnitEditor(QWidget *parent = 0) : BaseEditor(parent) {
00957         setObjectName("SensorUnitEditor");
00958         setWindowTitle("Sensor unit editor");
00959 
00960         m_model = new SqlQueryModel(this);
00961         m_model->setQuery(Database::execStatic("SELECT unit_name || ' (' || unit_symbol || ')' "
00962                                              "FROM tbl_sensor_units "
00963                                              "INNER JOIN tbl_units USING (unit_id) ORDER BY 1"));
00964         m_view = new QListView(this);
00965         m_view->setModel(m_model);
00966         m_view->setSelectionMode(QAbstractItemView::NoSelection);
00967 
00968         // button setup
00969         QVBoxLayout *buttonLayout = new QVBoxLayout();
00970         buttonLayout->addWidget(button(BaseEditor::ButtonAdd));
00971         buttonLayout->addStretch();
00972         buttonLayout->addWidget(button(BaseEditor::ButtonClose));
00973 
00974         mainLayout()->addWidget(m_view, 0, 0, 1, 1);
00975         mainLayout()->addLayout(buttonLayout, 0, 1, 2, 1);
00976 
00977         connect(button(BaseEditor::ButtonAdd), SIGNAL(clicked()), this, SLOT(onAddButtonPress()));
00978     }
00979 
00980     virtual bool isDirty() const {return false;}
00981 
00982 protected slots:
00983     void onAddButtonPress(){
00984         QSqlQueryModel model;
00985         model.setQuery(Database::execStatic("SELECT unit_name || ' (' || unit_symbol || ')', unit_id "
00986                                             "FROM "
00987                                             " ( "
00988                                             " SELECT unit_id FROM tbl_units "
00989                                             " EXCEPT "
00990                                             " SELECT unit_id FROM tbl_sensor_units "
00991                                             " ) "
00992                                             "AS e INNER JOIN tbl_units USING (unit_id) ORDER BY 1"));
00993         SimpleViewSelectionDialog d("Unit selector", &model, this);
00994         if (d.exec()){
00995             int row = d.selection().row();
00996             bool ok;
00997             int unit_id = model.index(row, 1).data(Qt::DisplayRole).toInt(&ok);
00998             Q_ASSERT(ok);
00999             Q_ASSERT(unit_id != 0);
01000             Q_ASSERT(unit_id != -1);
01001             Database::execStatic("INSERT INTO tbl_sensor_units VALUES (" + QString::number(unit_id) + ")");
01002             m_model->reQuery();
01003         }
01004     }
01005 
01006     virtual void updateButtons(){};
01007 
01008     virtual void onNewButtonPress(){};
01009 
01010     virtual void onSubmitButtonPress(){};
01011 
01012     virtual void onUndoButtonPress(){};
01013 
01014 private:
01015     QListView *m_view;
01016     SqlQueryModel *m_model;
01017 };
01018 
01019 #endif // PROJECTSEDITOR_H

Generated on Tue Aug 24 2010 15:58:55 for Smartlet by  doxygen 1.7.1