Browse Source

Add threshold annotations

Neal Wilson 7 years ago
parent
commit
f83a30f45d
5 changed files with 2064 additions and 1095 deletions
  1. 19
    0
      config/Windows/productionroaster.xml
  2. 482
    2
      src/moc_typica.cpp
  3. 235
    0
      src/thresholdannotation.w
  4. 1324
    1093
      src/typica.cpp
  5. 4
    0
      src/typica.w

+ 19
- 0
config/Windows/productionroaster.xml View File

@@ -457,6 +457,25 @@
457 457
 				annotationPanel.addWidget(button);
458 458
 				tabControls.push(button);
459 459
 			}
460
+                        else if(driverReference.driver == "thresholdannotation")
461
+                        {
462
+                            var noteDetector = new ThresholdDetector();
463
+                            var noteEmitter = new Annotator(driverReference.annotation);
464
+                            noteDetector.setThreshold(Number(driverReference.value));
465
+                            for(var j = 0; j < columnNames.length; j++) {
466
+                                if(columnNames[j] == driverReference.source) {
467
+                                    channels[j].newData.connect(noteDetector.newMeasurement);
468
+                                    break;
469
+                                }
470
+                            }
471
+                            if(Number(driverReference.direction) == 1) {
472
+                                noteDetector.setEdgeDirection(ThresholdDetector.Descending);
473
+                            } else {
474
+                                noteDetector.setEdgeDirection(ThresholdDetector.Ascending);
475
+                            }
476
+                            noteDetector.timeForValue.connect(noteEmitter.annotate);
477
+                            annotationButtons.push(noteEmitter);
478
+                        }
460 479
 			else if(driverReference.driver == "valueannotation")
461 480
 			{
462 481
 				var checker = new ValueAnnotation;

+ 482
- 2
src/moc_typica.cpp View File

@@ -1,7 +1,7 @@
1 1
 /****************************************************************************
2 2
 ** Meta object code from reading C++ file 'typica.cpp'
3 3
 **
4
-** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.6)
4
+** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.7)
5 5
 **
6 6
 ** WARNING! All changes made in this file will be lost!
7 7
 *****************************************************************************/
@@ -9,7 +9,7 @@
9 9
 #if !defined(Q_MOC_OUTPUT_REVISION)
10 10
 #error "The header file 'typica.cpp' doesn't include <QObject>."
11 11
 #elif Q_MOC_OUTPUT_REVISION != 63
12
-#error "This file was generated using the moc from 4.8.6. It"
12
+#error "This file was generated using the moc from 4.8.7. It"
13 13
 #error "cannot be used with the include files from this version of Qt."
14 14
 #error "(The moc has changed too much.)"
15 15
 #endif
@@ -6081,6 +6081,297 @@ int ModbusConfigurator::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
6081 6081
     }
6082 6082
     return _id;
6083 6083
 }
6084
+static const uint qt_meta_data_ModbusNGConfWidget[] = {
6085
+
6086
+ // content:
6087
+       6,       // revision
6088
+       0,       // classname
6089
+       0,    0, // classinfo
6090
+       6,   14, // methods
6091
+       0,    0, // properties
6092
+       0,    0, // enums/sets
6093
+       1,   44, // constructors
6094
+       0,       // flags
6095
+       0,       // signalCount
6096
+
6097
+ // slots: signature, parameters, type, tag, flags
6098
+      26,   20,   19,   19, 0x08,
6099
+      46,   20,   19,   19, 0x08,
6100
+      70,   20,   19,   19, 0x08,
6101
+      88,   20,   19,   19, 0x08,
6102
+     111,   20,   19,   19, 0x08,
6103
+     131,   19,   19,   19, 0x08,
6104
+
6105
+ // constructors: signature, parameters, type, tag, flags
6106
+     154,  142,   19,   19, 0x0e,
6107
+
6108
+       0        // eod
6109
+};
6110
+
6111
+static const char qt_meta_stringdata_ModbusNGConfWidget[] = {
6112
+    "ModbusNGConfWidget\0\0value\0updatePort(QString)\0"
6113
+    "updateBaudRate(QString)\0updateParity(int)\0"
6114
+    "updateFlowControl(int)\0updateStopBits(int)\0"
6115
+    "addInput()\0model,index\0"
6116
+    "ModbusNGConfWidget(DeviceTreeModel*,QModelIndex)\0"
6117
+};
6118
+
6119
+void ModbusNGConfWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
6120
+{
6121
+    if (_c == QMetaObject::CreateInstance) {
6122
+        switch (_id) {
6123
+        case 0: { ModbusNGConfWidget *_r = new ModbusNGConfWidget((*reinterpret_cast< DeviceTreeModel*(*)>(_a[1])),(*reinterpret_cast< const QModelIndex(*)>(_a[2])));
6124
+            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
6125
+        }
6126
+    } else if (_c == QMetaObject::InvokeMetaMethod) {
6127
+        Q_ASSERT(staticMetaObject.cast(_o));
6128
+        ModbusNGConfWidget *_t = static_cast<ModbusNGConfWidget *>(_o);
6129
+        switch (_id) {
6130
+        case 0: _t->updatePort((*reinterpret_cast< const QString(*)>(_a[1]))); break;
6131
+        case 1: _t->updateBaudRate((*reinterpret_cast< const QString(*)>(_a[1]))); break;
6132
+        case 2: _t->updateParity((*reinterpret_cast< int(*)>(_a[1]))); break;
6133
+        case 3: _t->updateFlowControl((*reinterpret_cast< int(*)>(_a[1]))); break;
6134
+        case 4: _t->updateStopBits((*reinterpret_cast< int(*)>(_a[1]))); break;
6135
+        case 5: _t->addInput(); break;
6136
+        default: ;
6137
+        }
6138
+    }
6139
+}
6140
+
6141
+const QMetaObjectExtraData ModbusNGConfWidget::staticMetaObjectExtraData = {
6142
+    0,  qt_static_metacall 
6143
+};
6144
+
6145
+const QMetaObject ModbusNGConfWidget::staticMetaObject = {
6146
+    { &BasicDeviceConfigurationWidget::staticMetaObject, qt_meta_stringdata_ModbusNGConfWidget,
6147
+      qt_meta_data_ModbusNGConfWidget, &staticMetaObjectExtraData }
6148
+};
6149
+
6150
+#ifdef Q_NO_DATA_RELOCATION
6151
+const QMetaObject &ModbusNGConfWidget::getStaticMetaObject() { return staticMetaObject; }
6152
+#endif //Q_NO_DATA_RELOCATION
6153
+
6154
+const QMetaObject *ModbusNGConfWidget::metaObject() const
6155
+{
6156
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
6157
+}
6158
+
6159
+void *ModbusNGConfWidget::qt_metacast(const char *_clname)
6160
+{
6161
+    if (!_clname) return 0;
6162
+    if (!strcmp(_clname, qt_meta_stringdata_ModbusNGConfWidget))
6163
+        return static_cast<void*>(const_cast< ModbusNGConfWidget*>(this));
6164
+    return BasicDeviceConfigurationWidget::qt_metacast(_clname);
6165
+}
6166
+
6167
+int ModbusNGConfWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
6168
+{
6169
+    _id = BasicDeviceConfigurationWidget::qt_metacall(_c, _id, _a);
6170
+    if (_id < 0)
6171
+        return _id;
6172
+    if (_c == QMetaObject::InvokeMetaMethod) {
6173
+        if (_id < 6)
6174
+            qt_static_metacall(this, _c, _id, _a);
6175
+        _id -= 6;
6176
+    }
6177
+    return _id;
6178
+}
6179
+static const uint qt_meta_data_ModbusNGInputConfWidget[] = {
6180
+
6181
+ // content:
6182
+       6,       // revision
6183
+       0,       // classname
6184
+       0,    0, // classinfo
6185
+       8,   14, // methods
6186
+       0,    0, // properties
6187
+       0,    0, // enums/sets
6188
+       1,   54, // constructors
6189
+       0,       // flags
6190
+       0,       // signalCount
6191
+
6192
+ // slots: signature, parameters, type, tag, flags
6193
+      31,   25,   24,   24, 0x08,
6194
+      50,   25,   24,   24, 0x08,
6195
+      69,   25,   24,   24, 0x08,
6196
+      89,   25,   24,   24, 0x08,
6197
+     107,   25,   24,   24, 0x08,
6198
+     127,   25,   24,   24, 0x08,
6199
+     143,   25,   24,   24, 0x08,
6200
+     169,   25,   24,   24, 0x08,
6201
+
6202
+ // constructors: signature, parameters, type, tag, flags
6203
+     200,  188,   24,   24, 0x0e,
6204
+
6205
+       0        // eod
6206
+};
6207
+
6208
+static const char qt_meta_stringdata_ModbusNGInputConfWidget[] = {
6209
+    "ModbusNGInputConfWidget\0\0value\0"
6210
+    "updateStation(int)\0updateAddress(int)\0"
6211
+    "updateFunction(int)\0updateFormat(int)\0"
6212
+    "updateDecimals(int)\0updateUnit(int)\0"
6213
+    "updateColumnName(QString)\0updateHidden(bool)\0"
6214
+    "model,index\0"
6215
+    "ModbusNGInputConfWidget(DeviceTreeModel*,QModelIndex)\0"
6216
+};
6217
+
6218
+void ModbusNGInputConfWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
6219
+{
6220
+    if (_c == QMetaObject::CreateInstance) {
6221
+        switch (_id) {
6222
+        case 0: { ModbusNGInputConfWidget *_r = new ModbusNGInputConfWidget((*reinterpret_cast< DeviceTreeModel*(*)>(_a[1])),(*reinterpret_cast< const QModelIndex(*)>(_a[2])));
6223
+            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
6224
+        }
6225
+    } else if (_c == QMetaObject::InvokeMetaMethod) {
6226
+        Q_ASSERT(staticMetaObject.cast(_o));
6227
+        ModbusNGInputConfWidget *_t = static_cast<ModbusNGInputConfWidget *>(_o);
6228
+        switch (_id) {
6229
+        case 0: _t->updateStation((*reinterpret_cast< int(*)>(_a[1]))); break;
6230
+        case 1: _t->updateAddress((*reinterpret_cast< int(*)>(_a[1]))); break;
6231
+        case 2: _t->updateFunction((*reinterpret_cast< int(*)>(_a[1]))); break;
6232
+        case 3: _t->updateFormat((*reinterpret_cast< int(*)>(_a[1]))); break;
6233
+        case 4: _t->updateDecimals((*reinterpret_cast< int(*)>(_a[1]))); break;
6234
+        case 5: _t->updateUnit((*reinterpret_cast< int(*)>(_a[1]))); break;
6235
+        case 6: _t->updateColumnName((*reinterpret_cast< const QString(*)>(_a[1]))); break;
6236
+        case 7: _t->updateHidden((*reinterpret_cast< bool(*)>(_a[1]))); break;
6237
+        default: ;
6238
+        }
6239
+    }
6240
+}
6241
+
6242
+const QMetaObjectExtraData ModbusNGInputConfWidget::staticMetaObjectExtraData = {
6243
+    0,  qt_static_metacall 
6244
+};
6245
+
6246
+const QMetaObject ModbusNGInputConfWidget::staticMetaObject = {
6247
+    { &BasicDeviceConfigurationWidget::staticMetaObject, qt_meta_stringdata_ModbusNGInputConfWidget,
6248
+      qt_meta_data_ModbusNGInputConfWidget, &staticMetaObjectExtraData }
6249
+};
6250
+
6251
+#ifdef Q_NO_DATA_RELOCATION
6252
+const QMetaObject &ModbusNGInputConfWidget::getStaticMetaObject() { return staticMetaObject; }
6253
+#endif //Q_NO_DATA_RELOCATION
6254
+
6255
+const QMetaObject *ModbusNGInputConfWidget::metaObject() const
6256
+{
6257
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
6258
+}
6259
+
6260
+void *ModbusNGInputConfWidget::qt_metacast(const char *_clname)
6261
+{
6262
+    if (!_clname) return 0;
6263
+    if (!strcmp(_clname, qt_meta_stringdata_ModbusNGInputConfWidget))
6264
+        return static_cast<void*>(const_cast< ModbusNGInputConfWidget*>(this));
6265
+    return BasicDeviceConfigurationWidget::qt_metacast(_clname);
6266
+}
6267
+
6268
+int ModbusNGInputConfWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
6269
+{
6270
+    _id = BasicDeviceConfigurationWidget::qt_metacall(_c, _id, _a);
6271
+    if (_id < 0)
6272
+        return _id;
6273
+    if (_c == QMetaObject::InvokeMetaMethod) {
6274
+        if (_id < 8)
6275
+            qt_static_metacall(this, _c, _id, _a);
6276
+        _id -= 8;
6277
+    }
6278
+    return _id;
6279
+}
6280
+static const uint qt_meta_data_ModbusNG[] = {
6281
+
6282
+ // content:
6283
+       6,       // revision
6284
+       0,       // classname
6285
+       0,    0, // classinfo
6286
+       7,   14, // methods
6287
+       0,    0, // properties
6288
+       0,    0, // enums/sets
6289
+       0,    0, // constructors
6290
+       0,       // flags
6291
+       0,       // signalCount
6292
+
6293
+ // slots: signature, parameters, type, tag, flags
6294
+      10,    9,    9,    9, 0x08,
6295
+      28,    9,    9,    9, 0x08,
6296
+      38,    9,    9,    9, 0x08,
6297
+
6298
+ // methods: signature, parameters, type, tag, flags
6299
+      58,    9,   54,    9, 0x02,
6300
+      81,    9,   73,    9, 0x02,
6301
+     104,    9,   73,    9, 0x02,
6302
+     135,    9,  130,    9, 0x02,
6303
+
6304
+       0        // eod
6305
+};
6306
+
6307
+static const char qt_meta_stringdata_ModbusNG[] = {
6308
+    "ModbusNG\0\0sendNextMessage()\0timeout()\0"
6309
+    "dataAvailable()\0int\0channelCount()\0"
6310
+    "QString\0channelColumnName(int)\0"
6311
+    "channelIndicatorText(int)\0bool\0"
6312
+    "isChannelHidden(int)\0"
6313
+};
6314
+
6315
+void ModbusNG::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
6316
+{
6317
+    if (_c == QMetaObject::InvokeMetaMethod) {
6318
+        Q_ASSERT(staticMetaObject.cast(_o));
6319
+        ModbusNG *_t = static_cast<ModbusNG *>(_o);
6320
+        switch (_id) {
6321
+        case 0: _t->sendNextMessage(); break;
6322
+        case 1: _t->timeout(); break;
6323
+        case 2: _t->dataAvailable(); break;
6324
+        case 3: { int _r = _t->channelCount();
6325
+            if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; }  break;
6326
+        case 4: { QString _r = _t->channelColumnName((*reinterpret_cast< int(*)>(_a[1])));
6327
+            if (_a[0]) *reinterpret_cast< QString*>(_a[0]) = _r; }  break;
6328
+        case 5: { QString _r = _t->channelIndicatorText((*reinterpret_cast< int(*)>(_a[1])));
6329
+            if (_a[0]) *reinterpret_cast< QString*>(_a[0]) = _r; }  break;
6330
+        case 6: { bool _r = _t->isChannelHidden((*reinterpret_cast< int(*)>(_a[1])));
6331
+            if (_a[0]) *reinterpret_cast< bool*>(_a[0]) = _r; }  break;
6332
+        default: ;
6333
+        }
6334
+    }
6335
+}
6336
+
6337
+const QMetaObjectExtraData ModbusNG::staticMetaObjectExtraData = {
6338
+    0,  qt_static_metacall 
6339
+};
6340
+
6341
+const QMetaObject ModbusNG::staticMetaObject = {
6342
+    { &QObject::staticMetaObject, qt_meta_stringdata_ModbusNG,
6343
+      qt_meta_data_ModbusNG, &staticMetaObjectExtraData }
6344
+};
6345
+
6346
+#ifdef Q_NO_DATA_RELOCATION
6347
+const QMetaObject &ModbusNG::getStaticMetaObject() { return staticMetaObject; }
6348
+#endif //Q_NO_DATA_RELOCATION
6349
+
6350
+const QMetaObject *ModbusNG::metaObject() const
6351
+{
6352
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
6353
+}
6354
+
6355
+void *ModbusNG::qt_metacast(const char *_clname)
6356
+{
6357
+    if (!_clname) return 0;
6358
+    if (!strcmp(_clname, qt_meta_stringdata_ModbusNG))
6359
+        return static_cast<void*>(const_cast< ModbusNG*>(this));
6360
+    return QObject::qt_metacast(_clname);
6361
+}
6362
+
6363
+int ModbusNG::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
6364
+{
6365
+    _id = QObject::qt_metacall(_c, _id, _a);
6366
+    if (_id < 0)
6367
+        return _id;
6368
+    if (_c == QMetaObject::InvokeMetaMethod) {
6369
+        if (_id < 7)
6370
+            qt_static_metacall(this, _c, _id, _a);
6371
+        _id -= 7;
6372
+    }
6373
+    return _id;
6374
+}
6084 6375
 static const uint qt_meta_data_UnsupportedSerialDeviceConfWidget[] = {
6085 6376
 
6086 6377
  // content:
@@ -7980,4 +8271,193 @@ void ValueAnnotation::annotation(QString _t1, int _t2, int _t3)
7980 8271
     void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)), const_cast<void*>(reinterpret_cast<const void*>(&_t3)) };
7981 8272
     QMetaObject::activate(this, &staticMetaObject, 0, _a);
7982 8273
 }
8274
+static const uint qt_meta_data_ThresholdAnnotationConfWidget[] = {
8275
+
8276
+ // content:
8277
+       6,       // revision
8278
+       0,       // classname
8279
+       0,    0, // classinfo
8280
+       4,   14, // methods
8281
+       0,    0, // properties
8282
+       0,    0, // enums/sets
8283
+       1,   34, // constructors
8284
+       0,       // flags
8285
+       0,       // signalCount
8286
+
8287
+ // slots: signature, parameters, type, tag, flags
8288
+      38,   31,   30,   30, 0x08,
8289
+      72,   66,   30,   30, 0x08,
8290
+     102,   96,   30,   30, 0x08,
8291
+     128,  123,   30,   30, 0x08,
8292
+
8293
+ // constructors: signature, parameters, type, tag, flags
8294
+     166,  154,   30,   30, 0x0e,
8295
+
8296
+       0        // eod
8297
+};
8298
+
8299
+static const char qt_meta_stringdata_ThresholdAnnotationConfWidget[] = {
8300
+    "ThresholdAnnotationConfWidget\0\0source\0"
8301
+    "updateSourceColumn(QString)\0value\0"
8302
+    "updateThreshold(double)\0index\0"
8303
+    "updateDirection(int)\0note\0"
8304
+    "updateAnnotation(QString)\0model,index\0"
8305
+    "ThresholdAnnotationConfWidget(DeviceTreeModel*,QModelIndex)\0"
8306
+};
8307
+
8308
+void ThresholdAnnotationConfWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
8309
+{
8310
+    if (_c == QMetaObject::CreateInstance) {
8311
+        switch (_id) {
8312
+        case 0: { ThresholdAnnotationConfWidget *_r = new ThresholdAnnotationConfWidget((*reinterpret_cast< DeviceTreeModel*(*)>(_a[1])),(*reinterpret_cast< const QModelIndex(*)>(_a[2])));
8313
+            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
8314
+        }
8315
+    } else if (_c == QMetaObject::InvokeMetaMethod) {
8316
+        Q_ASSERT(staticMetaObject.cast(_o));
8317
+        ThresholdAnnotationConfWidget *_t = static_cast<ThresholdAnnotationConfWidget *>(_o);
8318
+        switch (_id) {
8319
+        case 0: _t->updateSourceColumn((*reinterpret_cast< const QString(*)>(_a[1]))); break;
8320
+        case 1: _t->updateThreshold((*reinterpret_cast< double(*)>(_a[1]))); break;
8321
+        case 2: _t->updateDirection((*reinterpret_cast< int(*)>(_a[1]))); break;
8322
+        case 3: _t->updateAnnotation((*reinterpret_cast< const QString(*)>(_a[1]))); break;
8323
+        default: ;
8324
+        }
8325
+    }
8326
+}
8327
+
8328
+const QMetaObjectExtraData ThresholdAnnotationConfWidget::staticMetaObjectExtraData = {
8329
+    0,  qt_static_metacall 
8330
+};
8331
+
8332
+const QMetaObject ThresholdAnnotationConfWidget::staticMetaObject = {
8333
+    { &BasicDeviceConfigurationWidget::staticMetaObject, qt_meta_stringdata_ThresholdAnnotationConfWidget,
8334
+      qt_meta_data_ThresholdAnnotationConfWidget, &staticMetaObjectExtraData }
8335
+};
8336
+
8337
+#ifdef Q_NO_DATA_RELOCATION
8338
+const QMetaObject &ThresholdAnnotationConfWidget::getStaticMetaObject() { return staticMetaObject; }
8339
+#endif //Q_NO_DATA_RELOCATION
8340
+
8341
+const QMetaObject *ThresholdAnnotationConfWidget::metaObject() const
8342
+{
8343
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
8344
+}
8345
+
8346
+void *ThresholdAnnotationConfWidget::qt_metacast(const char *_clname)
8347
+{
8348
+    if (!_clname) return 0;
8349
+    if (!strcmp(_clname, qt_meta_stringdata_ThresholdAnnotationConfWidget))
8350
+        return static_cast<void*>(const_cast< ThresholdAnnotationConfWidget*>(this));
8351
+    return BasicDeviceConfigurationWidget::qt_metacast(_clname);
8352
+}
8353
+
8354
+int ThresholdAnnotationConfWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
8355
+{
8356
+    _id = BasicDeviceConfigurationWidget::qt_metacall(_c, _id, _a);
8357
+    if (_id < 0)
8358
+        return _id;
8359
+    if (_c == QMetaObject::InvokeMetaMethod) {
8360
+        if (_id < 4)
8361
+            qt_static_metacall(this, _c, _id, _a);
8362
+        _id -= 4;
8363
+    }
8364
+    return _id;
8365
+}
8366
+static const uint qt_meta_data_Annotator[] = {
8367
+
8368
+ // content:
8369
+       6,       // revision
8370
+       0,       // classname
8371
+       0,    0, // classinfo
8372
+       6,   14, // methods
8373
+       0,    0, // properties
8374
+       0,    0, // enums/sets
8375
+       0,    0, // constructors
8376
+       0,       // flags
8377
+       1,       // signalCount
8378
+
8379
+ // signals: signature, parameters, type, tag, flags
8380
+      44,   11,   10,   10, 0x05,
8381
+
8382
+ // slots: signature, parameters, type, tag, flags
8383
+      83,   72,   10,   10, 0x0a,
8384
+     117,  106,   10,   10, 0x0a,
8385
+     160,  143,   10,   10, 0x0a,
8386
+     185,   10,   10,   10, 0x0a,
8387
+     196,   10,   10,   10, 0x08,
8388
+
8389
+       0        // eod
8390
+};
8391
+
8392
+static const char qt_meta_stringdata_Annotator[] = {
8393
+    "Annotator\0\0annotation,tempcolumn,notecolumn\0"
8394
+    "annotation(QString,int,int)\0annotation\0"
8395
+    "setAnnotation(QString)\0tempcolumn\0"
8396
+    "setTemperatureColumn(int)\0annotationcolumn\0"
8397
+    "setAnnotationColumn(int)\0annotate()\0"
8398
+    "catchTimer()\0"
8399
+};
8400
+
8401
+void Annotator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
8402
+{
8403
+    if (_c == QMetaObject::InvokeMetaMethod) {
8404
+        Q_ASSERT(staticMetaObject.cast(_o));
8405
+        Annotator *_t = static_cast<Annotator *>(_o);
8406
+        switch (_id) {
8407
+        case 0: _t->annotation((*reinterpret_cast< QString(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
8408
+        case 1: _t->setAnnotation((*reinterpret_cast< const QString(*)>(_a[1]))); break;
8409
+        case 2: _t->setTemperatureColumn((*reinterpret_cast< int(*)>(_a[1]))); break;
8410
+        case 3: _t->setAnnotationColumn((*reinterpret_cast< int(*)>(_a[1]))); break;
8411
+        case 4: _t->annotate(); break;
8412
+        case 5: _t->catchTimer(); break;
8413
+        default: ;
8414
+        }
8415
+    }
8416
+}
8417
+
8418
+const QMetaObjectExtraData Annotator::staticMetaObjectExtraData = {
8419
+    0,  qt_static_metacall 
8420
+};
8421
+
8422
+const QMetaObject Annotator::staticMetaObject = {
8423
+    { &QObject::staticMetaObject, qt_meta_stringdata_Annotator,
8424
+      qt_meta_data_Annotator, &staticMetaObjectExtraData }
8425
+};
8426
+
8427
+#ifdef Q_NO_DATA_RELOCATION
8428
+const QMetaObject &Annotator::getStaticMetaObject() { return staticMetaObject; }
8429
+#endif //Q_NO_DATA_RELOCATION
8430
+
8431
+const QMetaObject *Annotator::metaObject() const
8432
+{
8433
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
8434
+}
8435
+
8436
+void *Annotator::qt_metacast(const char *_clname)
8437
+{
8438
+    if (!_clname) return 0;
8439
+    if (!strcmp(_clname, qt_meta_stringdata_Annotator))
8440
+        return static_cast<void*>(const_cast< Annotator*>(this));
8441
+    return QObject::qt_metacast(_clname);
8442
+}
8443
+
8444
+int Annotator::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
8445
+{
8446
+    _id = QObject::qt_metacall(_c, _id, _a);
8447
+    if (_id < 0)
8448
+        return _id;
8449
+    if (_c == QMetaObject::InvokeMetaMethod) {
8450
+        if (_id < 6)
8451
+            qt_static_metacall(this, _c, _id, _a);
8452
+        _id -= 6;
8453
+    }
8454
+    return _id;
8455
+}
8456
+
8457
+// SIGNAL 0
8458
+void Annotator::annotation(QString _t1, int _t2, int _t3)
8459
+{
8460
+    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)), const_cast<void*>(reinterpret_cast<const void*>(&_t3)) };
8461
+    QMetaObject::activate(this, &staticMetaObject, 0, _a);
8462
+}
7983 8463
 QT_END_MOC_NAMESPACE

+ 235
- 0
src/thresholdannotation.w View File

@@ -0,0 +1,235 @@
1
+@** Threshold Annotations.
2
+
3
+\noindent Value annotations are fine for cases where we want to capture the
4
+fact that a control series has changed to some specific value, but there are
5
+times when it is more useful to know when a data series has passed through some
6
+value in a particular direction even if the exact value of interest is never
7
+directly recorded. For example, it would be possible to automatically mark a
8
+point near turnaround by watching for a rate of temperature change ascending
9
+through 0. This could also be set up to match range timers and mark events of
10
+interest that begin at consistent temperatures.
11
+
12
+As usual, this is a feature that must be configured on a per roaster basis.
13
+
14
+@<Class declarations@>=
15
+class ThresholdAnnotationConfWidget : public BasicDeviceConfigurationWidget
16
+{
17
+    Q_OBJECT
18
+    public:
19
+        Q_INVOKABLE ThresholdAnnotationConfWidget(DeviceTreeModel *model,
20
+                                                  const QModelIndex &index);
21
+    private slots:
22
+        void updateSourceColumn(const QString &source);
23
+        void updateThreshold(double value);
24
+        void updateDirection(int index);
25
+        void updateAnnotation(const QString &note);
26
+};
27
+
28
+@ The configuration widget needs to provide fields for determining which data
29
+series should be used to generate the annotation, the value that the
30
+|ThresholdDetector| should use as its trigger, the direction this should fire
31
+on, and the text of the annotation.
32
+
33
+@<ThresholdAnnotationConfWidget implementation@>=
34
+ThresholdAnnotationConfWidget::ThresholdAnnotationConfWidget(DeviceTreeModel *model,
35
+                                                             const QModelIndex &index)
36
+: BasicDeviceConfigurationWidget(model, index)
37
+{
38
+    QFormLayout *layout = new QFormLayout;
39
+    QLineEdit *source = new QLineEdit;
40
+    layout->addRow(tr("Source column name:"), source);
41
+    QDoubleSpinBox *value = new QDoubleSpinBox;
42
+
43
+@ A |QDoubleSpinBox| is used for entering the value. By default this allows for
44
+entering data in a range from 0 to 99.99, however this range is inadequate for
45
+many coffee roasting applications. Instead, we allow the full range of the
46
+underlying data type, but as this might be different on different platforms,
47
+another header is required.
48
+
49
+@<Header files to include@>=
50
+#include <limits>
51
+
52
+@ The number of decimal places is limited to 2, however this is an arbitrary
53
+decision which can be raised later if needed.
54
+
55
+@<ThresholdAnnotationConfWidget implementation@>=
56
+
57
+    value->setMinimum(std::numeric_limits<double>::min());
58
+    value->setMaximum(std::numeric_limits<double>::max());
59
+    value->setDecimals(2);
60
+    layout->addRow(tr("Threshold value:"), value);
61
+    QComboBox *direction = new QComboBox;
62
+    direction->addItem(tr("Ascending"));
63
+    direction->addItem(tr("Descending"));
64
+    layout->addRow(tr("Direction:"), direction);
65
+    QLineEdit *annotation = new QLineEdit;
66
+    layout->addRow(tr("Annotation:"), annotation);
67
+    @<Get device configuration data for current node@>@;
68
+    for(int i = 0; i < configData.size(); i++)
69
+    {
70
+        node = configData.at(i).toElement();
71
+        if(node.attribute("name") == "source")
72
+        {
73
+            source->setText(node.attribute("value"));
74
+        }
75
+        else if(node.attribute("name") == "value")
76
+        {
77
+            value->setValue(node.attribute("value").toDouble());
78
+        }
79
+        else if(node.attribute("name") == "direction")
80
+        {
81
+            direction->setCurrentIndex(node.attribute("value").toInt());
82
+        }
83
+        else if(node.attribute("name") == "annotation")
84
+        {
85
+            annotation->setText(node.attribute("value"));
86
+        }
87
+    }
88
+    updateSourceColumn(source->text());
89
+    updateThreshold(value->value());
90
+    updateDirection(direction->currentIndex());
91
+    updateAnnotation(annotation->text());
92
+    connect(source, SIGNAL(textEdited(QString)), this, SLOT(updateSourceColumn(QString)));
93
+    connect(value, SIGNAL(valueChanged(double)), this, SLOT(updateThreshold(double)));
94
+    connect(direction, SIGNAL(currentIndexChanged(int)), this, SLOT(updateDirection(int)));
95
+    connect(annotation, SIGNAL(textEdited(QString)), this, SLOT(updateAnnotation(QString)));
96
+    setLayout(layout);
97
+}
98
+
99
+@ Configuration of the model is done as usual.
100
+
101
+@<ThresholdAnnotationConfWidget implementation@>=
102
+void ThresholdAnnotationConfWidget::updateSourceColumn(const QString &source)
103
+{
104
+    updateAttribute("source", source);
105
+}
106
+
107
+void ThresholdAnnotationConfWidget::updateThreshold(double value)
108
+{
109
+    updateAttribute("value", QString("%1").arg(value));
110
+}
111
+
112
+void ThresholdAnnotationConfWidget::updateDirection(int direction)
113
+{
114
+    updateAttribute("direction", QString("%1").arg(direction));
115
+}
116
+
117
+void ThresholdAnnotationConfWidget::updateAnnotation(const QString &annotation)
118
+{
119
+    updateAttribute("annotation", annotation);
120
+}
121
+
122
+@ The configurationwidget is registered with the configuration system as usual.
123
+
124
+@<Register device configuration widgets@>=
125
+app.registerDeviceConfigurationWidget("thresholdannotation",
126
+                                      ThresholdAnnotationConfWidget::staticMetaObject);
127
+
128
+@ A NodeInserter makes the configuration available.
129
+
130
+@<Add annotation control node inserters@>=
131
+NodeInserter *thresholdAnnotationInserter = new NodeInserter(tr("Threshold Annotation"),
132
+                                                             tr("Threshold Annotation"),
133
+                                                             "thresholdannotation");
134
+annotationMenu->addAction(thresholdAnnotationInserter);
135
+connect(thresholdAnnotationInserter, SIGNAL(triggered(QString, QString)),
136
+        this, SLOT(insertChildNode(QString, QString)));
137
+
138
+@ While we could use |ThresholdDetector| in the configuration directly, it is
139
+easier to provide another class with the same interface as |AnnotationButton|
140
+to leverage existing code for handling these.
141
+
142
+@<Class declarations@>=
143
+class Annotator : public QObject
144
+{@t\1@>@/
145
+    Q_OBJECT@;
146
+    QString note;
147
+    int tc;
148
+    int ac;
149
+    QTimer t;
150
+    public:
151
+        Annotator(const QString &text);@/
152
+    @t\4@>public slots@t\kern-3pt@>:@/
153
+        void setAnnotation(const QString &annotation);
154
+        void setTemperatureColumn(int tempcolumn);
155
+        void setAnnotationColumn(int annotationcolumn);
156
+        void annotate();
157
+    private slots:
158
+        void catchTimer();
159
+    signals:@/
160
+        void annotation(QString annotation, int tempcolumn, int notecolumn);@t\2@>@/
161
+}@t\kern-3pt@>;
162
+
163
+@ To use this class with a |ThresholdDetector|, simply connect the
164
+|timeForValue()| signal to the |annotate()| slot and use the existing
165
+|AnnotationButton| code to keep the columns up to date.
166
+
167
+@<Annotator implementation@>=
168
+Annotator::Annotator(const QString &text) : QObject(NULL), note(text)
169
+{
170
+    t.setInterval(0);
171
+    t.setSingleShot(true);
172
+    connect(&t, SIGNAL(timeout()), this, SLOT(catchTimer()));
173
+}
174
+
175
+void Annotator::setAnnotation(const QString &annotation)
176
+{
177
+    note = annotation;
178
+}
179
+
180
+void Annotator::setTemperatureColumn(int tempcolumn)
181
+{
182
+    tc = tempcolumn;
183
+}
184
+
185
+void Annotator::setAnnotationColumn(int annotationcolumn)
186
+{
187
+    ac = annotationcolumn;
188
+}
189
+
190
+@ When connecting a |ThresholdDetector| to an |Annotator| directly, the
191
+annotation can be recorded before the measurement reaches the log. The result
192
+of this is that the annotation appears with the measurement immediately before
193
+the one it should appear next to. To solve this, the annotation is delayed
194
+until the next iteration of the event loop.
195
+
196
+@<Annotator implementation@>=
197
+void Annotator::catchTimer()
198
+{
199
+    emit annotation(note, tc, ac);
200
+}
201
+
202
+void Annotator::annotate()
203
+{
204
+    t.start();
205
+}
206
+
207
+@ It must be possible to create these from a script.
208
+
209
+@<Function prototypes for scripting@>=
210
+QScriptValue constructAnnotator(QScriptContext *context,
211
+                                QScriptEngine *engine);
212
+void setAnnotatorProperties(QScriptValue value, QScriptEngine *engine);
213
+
214
+@ The engine is informed of the constructor.
215
+
216
+@<Set up the scripting engine@>=
217
+constructor = engine->newFunction(constructAnnotator);
218
+value = engine->newQMetaObject(&Annotator::staticMetaObject, constructor);
219
+engine->globalObject().setProperty("Annotator", value);
220
+
221
+@ The implementation is trivial.
222
+
223
+@<Functions for scripting@>=
224
+QScriptValue constructAnnotator(QScriptContext *context, QScriptEngine *engine)
225
+{
226
+    QScriptValue object = engine->newQObject(new Annotator(argument<QString>(0, context)));
227
+    setAnnotatorProperties(object, engine);
228
+    return object;
229
+}
230
+
231
+void setAnnotatorProperties(QScriptValue value, QScriptEngine *engine)
232
+{
233
+    setQObjectProperties(value, engine);
234
+}
235
+

+ 1324
- 1093
src/typica.cpp
File diff suppressed because it is too large
View File


+ 4
- 0
src/typica.w View File

@@ -610,6 +610,8 @@ generated file empty.
610 610
 @<ValueAnnotation implementation@>@/
611 611
 @<ValueAnnotationConfWidget implementation@>@/
612 612
 @<ModbusNG implementation@>@/
613
+@<ThresholdAnnotationConfWidget implementation@>@/
614
+@<Annotator implementation@>@/
613 615
 
614 616
 @ A few headers are required for various parts of \pn{}. These allow the use of
615 617
 various Qt modules.
@@ -19988,6 +19990,8 @@ app.registerDeviceConfigurationWidget("translation", TranslationConfWidget::stat
19988 19990
 
19989 19991
 @i valueannotation.w
19990 19992
 
19993
+@i thresholdannotation.w
19994
+
19991 19995
 @** Local changes.
19992 19996
 
19993 19997
 \noindent This is the end of \pn{} as distributed by its author. It is expected

Loading…
Cancel
Save