00001 #ifndef CALIBRATIONEDITOR_H
00002 #define CALIBRATIONEDITOR_H
00003
00004 #include "treemodel.h"
00005 #include "treeitem.h"
00006 #include "tableeditor.h"
00007 #include "baseeditor.h"
00008 #include "global.h"
00009
00013 class AdjustedTreeModel : public ProjectTreeModel {
00014 public:
00015 AdjustedTreeModel(QObject *parent = 0) : ProjectTreeModel(parent){}
00016 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const {
00017 return 1;
00018 }
00019 virtual Qt::ItemFlags flags (const QModelIndex & index) const {
00020 Qt::ItemFlags flags = Qt::ItemIsEnabled;
00021 if (index.data(ProjectTreeModel::TreeItemPointer).value<TreeItem*>()->data(TreeItem::TreeItemColumnName).toString() == QString("sens_chan_nr"))
00022 flags = flags | Qt::ItemIsSelectable;
00023 return flags;
00024 }
00025 };
00026
00027 #include <QStyledItemDelegate>
00028 #include <QSqlTableModel>
00029 #include <QDateTimeEdit>
00030
00034 class CalibrationDelegate : public QStyledItemDelegate {
00035 public:
00036 CalibrationDelegate(QObject *parent = 0) : QStyledItemDelegate(parent){}
00037
00038 QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
00039 const QModelIndex &index) const {
00040 if (QSqlTableModel *model = dynamic_cast<QSqlTableModel*>(
00041 const_cast<QAbstractItemModel*>(index.model()))) {
00042 int timestampColumn = model->record().indexOf("sens_chan_cali_timestamp");
00043 int formulaColumn = model->record().indexOf("sens_chan_cali_formula");
00044 int indexColumn = index.column();
00045 if (indexColumn == timestampColumn) {
00046 QDateTimeEdit *editor = new QDateTimeEdit(parent);
00047 editor->setCalendarPopup(true);
00048 return editor;
00049 }
00050 if (indexColumn == formulaColumn) {
00051
00052
00053 }
00054 }
00055 return QStyledItemDelegate::createEditor(parent, option, index);
00056 }
00057 };
00058
00064 class CalibrationEditor : public TableBaseEditor {
00065 public:
00066 CalibrationEditor(QWidget *parent = 0) : TableBaseEditor(parent){
00067 table()->setItemDelegate(new CalibrationDelegate(table()));
00068 model()->setTable("tbl_sensor_channel_calibrations");
00069 }
00070 };
00071
00072 #include <QTreeView>
00073 #include <QSqlIndex>
00074 #include <QLabel>
00075
00081 class ProjectCalibrationEditor : public CalibrationEditor {
00082 Q_OBJECT
00083 public:
00084 ProjectCalibrationEditor(QWidget *parent = 0) : CalibrationEditor(parent) {
00085 setObjectName("ProjectCalibrationEditorEditor");
00086 setWindowTitle("Calibrations editor, project based");
00087 treeView = new QTreeView(this);
00088 treeView->setModel(new AdjustedTreeModel(treeView));
00089
00090 QSplitter *splitter = new QSplitter(this);
00091 splitter->addWidget(treeView);
00092 splitter->addWidget(table());
00093 splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00094
00095 QLabel *note = new QLabel(this);
00096 note->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
00097 note->setOpenExternalLinks(true);
00098 note->setTextFormat(Qt::RichText);
00099 note->setWordWrap(true);
00100 note->setText(GlobalConst::CALI_FORMULA_HELP);
00101
00102 QGridLayout *widgetLayout = new QGridLayout();
00103 widgetLayout->addWidget(splitter, 0, 0, 1, 1);
00104 widgetLayout->addWidget(note, 1, 0, 1, 1);
00105
00106
00107 mainLayout()->addLayout(widgetLayout, 0, 0, 1, 1);
00108
00109
00110 connect(treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
00111 this, SLOT(onSensorChannelSelection(QItemSelection,QItemSelection)));
00112
00113
00114 onSensorChannelSelection(QItemSelection(), QItemSelection());
00115
00116
00117 connect(table()->itemDelegate(), SIGNAL(closeEditor(QWidget*)), this, SLOT(updateButtons()));
00118 }
00119
00120 protected slots:
00121 void onSensorChannelSelection(const QItemSelection &newSelection, const QItemSelection&){
00122 int tree_id = 0;
00123 QString filter("(sens_id, sens_chan_nr) IN (SELECT DISTINCT sens_id, sens_chan_nr FROM tbl_trees INNER JOIN tbl_sensor_channel_calibrations USING (sens_id, sens_chan_nr) WHERE tree_id = %1)");
00124 bool channelIsSelected = isChannelSelected();
00125
00126 table()->setEnabled(channelIsSelected);
00127 if (!channelIsSelected) {
00128
00129 tree_id = 0;
00130 } else {
00131
00132 tree_id = newSelection.indexes().first().data(ProjectTreeModel::TreeId).toInt();
00133
00134
00135 Q_ASSERT(newSelection.indexes().count() == 1);
00136 Q_ASSERT(tree_id != 0);
00137 Q_ASSERT(tree_id != -1);
00138 }
00139
00140
00141
00142
00143 model()->setTable(channelIsSelected ? "tbl_sensor_channel_calibrations" : QString());
00144 model()->setFilter(filter.arg(QString::number(tree_id)));
00145 model()->setSort(model()->record().indexOf("sens_chan_cali_timestamp"), Qt::AscendingOrder);
00146 model()->select();
00147
00148
00149 QSqlIndex pk = model()->primaryKey();
00150 for(int i = 0; i < pk.count() ; i++){
00151 table()->setColumnHidden(model()->record().indexOf(pk.fieldName(i)), true);
00152 }
00153
00154
00155 table()->setColumnHidden(model()->record().indexOf("sens_id"), true);
00156 table()->setColumnHidden(model()->record().indexOf("sens_chan_nr"), true);
00157 }
00158
00159 virtual void updateButtons() {
00160 CalibrationEditor::updateButtons();
00161 treeView->setEnabled(!isDirty());
00162 }
00163
00164 virtual void onNewButtonPress() {
00165 CalibrationEditor::onNewButtonPress();
00166 Q_ASSERT(isChannelSelected());
00167 Q_ASSERT(table()->isEnabled());
00168
00169
00170 bool ok;
00171 int tree_id = treeView->selectionModel()->selection().indexes().first().data(ProjectTreeModel::TreeId).toInt(&ok);
00172 Q_ASSERT(ok);
00173 QSqlRecord key = Database::execStaticR(QString::number(tree_id).prepend("SELECT DISTINCT sens_id, sens_chan_nr FROM tbl_trees WHERE tree_id = "));
00174 int sens_id = key.value("sens_id").toInt(&ok);
00175 Q_ASSERT(ok);
00176 int sens_chan_nr = key.value("sens_chan_nr").toInt(&ok);
00177 Q_ASSERT(ok);
00178 model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_id")), sens_id);
00179 model()->setData(model()->index(model()->rowCount() - 1, model()->record().indexOf("sens_chan_nr")), sens_chan_nr);
00180 }
00181
00182 bool isChannelSelected(){
00183 Q_ASSERT(treeView->selectionModel()->selection().indexes().count() <= 1);
00184 return !treeView->selectionModel()->selection().indexes().isEmpty();
00185 }
00186
00187 private:
00188 QTreeView *treeView;
00189 };
00190
00191 #include <QSqlRelationalTableModel>
00192 #include <QSqlRelationalDelegate>
00193 #include <QSplitter>
00194 #include <QGroupBox>
00195
00201 class UnitConversionEditor : public TableBaseEditor {
00202 Q_OBJECT
00203 public:
00204 UnitConversionEditor(QWidget *parent = 0) : TableBaseEditor(parent) {
00205 setObjectName("UnitConversionEditor");
00206 setWindowTitle("Unit conversion editor");
00207 model()->setTable("tbl_unit_conversions");
00208 model()->setRelation(model()->record().indexOf("unit_id_from"), QSqlRelation("tbl_units", "unit_id", "unit_symbol"));
00209 model()->setRelation(model()->record().indexOf("unit_id_to"), QSqlRelation("tbl_units", "unit_id", "unit_symbol"));
00210 model()->setSort(0, Qt::AscendingOrder);
00211 model()->select();
00212
00213 model()->setHeaderData(0, Qt::Horizontal, "From*", Qt::DisplayRole);
00214 model()->setHeaderData(1, Qt::Horizontal, "To*", Qt::DisplayRole);
00215 model()->setHeaderData(2, Qt::Horizontal, "Factor*", Qt::DisplayRole);
00216 model()->setHeaderData(3, Qt::Horizontal, "Offset*", Qt::DisplayRole);
00217
00218 editor = new QTableView(this);
00219 editor->setItemDelegate(new QSqlRelationalDelegate());
00220 editor->setModel(model());
00221
00222 SqlQueryModel *m = new SqlQueryModel(this);
00223 m->setQuery(Database::execStatic("SELECT f.unit_symbol AS \"From*\", t.unit_symbol AS \"To*\", unit_conv_factor as \"Factor\", unit_conv_offset AS \"Offset\" "
00224 "FROM vew_unit_conversions AS c INNER JOIN tbl_units AS f ON (unit_id_from = f.unit_id) INNER JOIN tbl_units AS t ON (unit_id_to = t.unit_id) "
00225 "WHERE f.unit_symbol <> t.unit_symbol "
00226 "ORDER BY 1, 2"));
00227 QTableView *view = new QTableView(this);
00228 view->setModel(m);
00229
00230 QGroupBox *eView = new QGroupBox("Editable conversions");
00231 eView->setLayout(new QHBoxLayout());
00232 eView->layout()->addWidget(editor);
00233 QGroupBox *sView = new QGroupBox("Derived conversions");
00234 sView->setLayout(new QHBoxLayout());
00235 sView->layout()->addWidget(view);
00236
00237 QSplitter *splitter = new QSplitter(this);
00238 splitter->addWidget(sView);
00239 splitter->addWidget(eView);
00240
00241
00242
00243 mainLayout()->addWidget(splitter, 0, 0, 1, 1);
00244
00245
00246 connect(editor->itemDelegate(), SIGNAL(closeEditor(QWidget*)), this, SLOT(updateButtons()));
00247 connect(model(), SIGNAL(queryChanged()), m, SLOT(reQuery()));
00248 }
00249
00250 protected slots:
00251 private:
00252 QTableView *editor;
00253 };
00254
00255 #endif // CALIBRATIONEDITOR_H