|
@@ -8026,6 +8026,7 @@ class ZoomLog : public QTableView@/
|
8026
|
8026
|
int annotationcolumn);
|
8027
|
8027
|
void clear();
|
8028
|
8028
|
void addOutputTemperatureColumn(int column);
|
|
8029
|
+ void addOutputControlColumn(int column);
|
8029
|
8030
|
void addOutputAnnotationColumn(int column);
|
8030
|
8031
|
void clearOutputColumns();
|
8031
|
8032
|
void setDisplayUnits(Units::Unit scale);
|
|
@@ -8052,6 +8053,7 @@ QList<MeasurementModel *> modelSet;
|
8052
|
8053
|
QHash<int, Measurement> lastMeasurement;
|
8053
|
8054
|
MeasurementModel *currentModel;
|
8054
|
8055
|
QList<int> saveTempCols;
|
|
8056
|
+QList<int> saveControlCols;
|
8055
|
8057
|
QList<int> saveNoteCols;
|
8056
|
8058
|
QList<int> currentColumnSet;
|
8057
|
8059
|
|
|
@@ -8083,7 +8085,8 @@ void ZoomLog::newMeasurement(Measurement measure, int tempcolumn)
|
8083
|
8085
|
{
|
8084
|
8086
|
Measurement adjusted(measure.temperature(),
|
8085
|
8087
|
QTime(0, measure.time().minute(),
|
8086
|
|
- measure.time().second(), 0));
|
|
8088
|
+ measure.time().second(), 0),
|
|
8089
|
+ measure.scale());
|
8087
|
8090
|
model_1s->newMeasurement(adjusted, tempcolumn);
|
8088
|
8091
|
if(adjusted.time().second() % 5 == 0)
|
8089
|
8092
|
{
|
|
@@ -8294,6 +8297,7 @@ void ZoomLog::clear()
|
8294
|
8297
|
}
|
8295
|
8298
|
lastMeasurement.clear();
|
8296
|
8299
|
saveTempCols.clear();
|
|
8300
|
+ saveControlCols.clear();
|
8297
|
8301
|
saveNoteCols.clear();
|
8298
|
8302
|
}
|
8299
|
8303
|
|
|
@@ -8339,6 +8343,11 @@ bool ZoomLog::saveXML(QIODevice *device)
|
8339
|
8343
|
writer.addTemperatureColumn(model_ms->headerData(c, Qt::Horizontal).
|
8340
|
8344
|
toString(), c);
|
8341
|
8345
|
}
|
|
8346
|
+ foreach(c, saveControlCols)
|
|
8347
|
+ {
|
|
8348
|
+ writer.addControlColumn(model_ms->headerData(c, Qt::Horizontal).
|
|
8349
|
+ toString(), c);
|
|
8350
|
+ }
|
8342
|
8351
|
foreach(c, saveNoteCols)
|
8343
|
8352
|
{
|
8344
|
8353
|
writer.addAnnotationColumn(model_ms->headerData(c, Qt::Horizontal).
|
|
@@ -8365,6 +8374,11 @@ bool ZoomLog::saveCSV(QIODevice *device)
|
8365
|
8374
|
writer.addTemperatureColumn(model_ms->headerData(c, Qt::Horizontal).
|
8366
|
8375
|
toString(), c);
|
8367
|
8376
|
}
|
|
8377
|
+ foreach(c, saveControlCols)
|
|
8378
|
+ {
|
|
8379
|
+ writer.addControlColumn(model_ms->headerData(c, Qt::Horizontal).
|
|
8380
|
+ toString(), c);
|
|
8381
|
+ }
|
8368
|
8382
|
foreach(c, saveNoteCols)
|
8369
|
8383
|
{
|
8370
|
8384
|
writer.addAnnotationColumn(model_ms->headerData(c, Qt::Horizontal).
|
|
@@ -8494,12 +8508,21 @@ void ZoomLog::setHeaderData(int section, QString text)
|
8494
|
8508
|
1.0.8. The main difference is that it is now possible to save multiple data
|
8495
|
8509
|
series to the same output document.
|
8496
|
8510
|
|
|
8511
|
+Starting in version 1.6 it is possible to save control columns. These should
|
|
8512
|
+contain unitless data which should remain unaffected by the current displayed
|
|
8513
|
+unit.
|
|
8514
|
+
|
8497
|
8515
|
@<ZoomLog Implementation@>=
|
8498
|
8516
|
void ZoomLog::addOutputTemperatureColumn(int column)
|
8499
|
8517
|
{
|
8500
|
8518
|
saveTempCols.append(column);
|
8501
|
8519
|
}
|
8502
|
8520
|
|
|
8521
|
+void ZoomLog::addOutputControlColumn(int column)
|
|
8522
|
+{
|
|
8523
|
+ saveControlCols.append(column);
|
|
8524
|
+}
|
|
8525
|
+
|
8503
|
8526
|
void ZoomLog::addOutputAnnotationColumn(int column)
|
8504
|
8527
|
{
|
8505
|
8528
|
saveNoteCols.append(column);
|
|
@@ -8508,6 +8531,7 @@ void ZoomLog::addOutputAnnotationColumn(int column)
|
8508
|
8531
|
void ZoomLog::clearOutputColumns()
|
8509
|
8532
|
{
|
8510
|
8533
|
saveTempCols.clear();
|
|
8534
|
+ saveControlCols.clear();
|
8511
|
8535
|
saveNoteCols.clear();
|
8512
|
8536
|
}
|
8513
|
8537
|
|
|
@@ -8719,6 +8743,7 @@ class MeasurementModel : public QAbstractItemModel@/
|
8719
|
8743
|
int colcount;
|
8720
|
8744
|
QHash<int, int> *lastTemperature;
|
8721
|
8745
|
QList<MeasurementList *>::iterator@, lastInsertion;
|
|
8746
|
+ QHash<int, bool> *controlColumns;
|
8722
|
8747
|
public:@/
|
8723
|
8748
|
MeasurementModel(QObject *parent = NULL);
|
8724
|
8749
|
~MeasurementModel();
|
|
@@ -8793,6 +8818,14 @@ while keeping the model sorted by time.
|
8793
|
8818
|
@<MeasurementModel Implementation@>=
|
8794
|
8819
|
void MeasurementModel::newMeasurement(Measurement measure, int tempcolumn)
|
8795
|
8820
|
{
|
|
8821
|
+ if(measure.scale() == Units::Unitless)
|
|
8822
|
+ {
|
|
8823
|
+ controlColumns->insert(tempcolumn, true);
|
|
8824
|
+ }
|
|
8825
|
+ else
|
|
8826
|
+ {
|
|
8827
|
+ controlColumns->insert(tempcolumn, false);
|
|
8828
|
+ }
|
8796
|
8829
|
MeasurementList *temp;
|
8797
|
8830
|
temp = new MeasurementList;
|
8798
|
8831
|
temp->append(QVariant(measure.time()));
|
|
@@ -8924,8 +8957,8 @@ if(entries->size() > 5)@/
|
8924
|
8957
|
}@t\2@>@/
|
8925
|
8958
|
}
|
8926
|
8959
|
|
8927
|
|
-@ If the chosen insertion point is at an existing time, we don't need to worry
|
8928
|
|
-about inserting rows. There may be a need to increase the size of the
|
|
8960
|
+@ If the chosen insertion point is at an existing time, we don'@q'@>t need to
|
|
8961
|
+worry about inserting rows. There may be a need to increase the size of the
|
8929
|
8962
|
measurement list to accept an entry in a new data series.
|
8930
|
8963
|
|
8931
|
8964
|
@<Insert a new measurement at an existing time@>=
|
|
@@ -8968,12 +9001,13 @@ inserting at a new time anywhere else.
|
8968
|
9001
|
insertion = entries->size();@/
|
8969
|
9002
|
@<Insert a new measurement somewhere else@>
|
8970
|
9003
|
|
8971
|
|
-@ The other bit of code that's a little bit more complicated than other parts of
|
8972
|
|
-the class handles adding annotations to the data. Two signals are emitted in
|
8973
|
|
-this method. The |dataChanged| signal is expected by view classes that can use
|
8974
|
|
-this model. The |rowChanged| signal is used by |ZoomLog| to scroll the view to
|
8975
|
|
-the row the annotation has been added to. This is mainly useful when loading a
|
8976
|
|
-target profile and entering the first annotation prior to starting the batch.
|
|
9004
|
+@ The other bit of code that'@q'@>s a little bit more complicated than other
|
|
9005
|
+parts of the class handles adding annotations to the data. Two signals are
|
|
9006
|
+emitted in this method. The |dataChanged| signal is expected by view classes
|
|
9007
|
+that can use this model. The |rowChanged| signal is used by |ZoomLog| to scroll
|
|
9008
|
+the view to the row the annotation has been added to. This is mainly useful
|
|
9009
|
+when loading a target profile and entering the first annotation prior to
|
|
9010
|
+starting the batch.
|
8977
|
9011
|
|
8978
|
9012
|
@<MeasurementModel Implementation@>=
|
8979
|
9013
|
void MeasurementModel::newAnnotation(QString annotation, int tempcolumn,@|
|
|
@@ -9041,7 +9075,7 @@ void MeasurementModel::clear()
|
9041
|
9075
|
|
9042
|
9076
|
@ While these methods for adding measurements and annotations are fine when
|
9043
|
9077
|
recording a stream of measurements, either from the |DAQ| or when loading saved
|
9044
|
|
-data, there are also cases where we'd like to edit the data in the model
|
|
9078
|
+data, there are also cases where we'@q'@>d like to edit the data in the model
|
9045
|
9079
|
directly from the table view. For this, we need to reimplement |setData()|.
|
9046
|
9080
|
|
9047
|
9081
|
Very little input checking is done here. Editable views may want to place
|
|
@@ -9079,7 +9113,7 @@ bool MeasurementModel::setData(const QModelIndex &index,
|
9079
|
9113
|
return true;@t\2@>@/
|
9080
|
9114
|
}
|
9081
|
9115
|
|
9082
|
|
-@ There is no sense in attempting to edit the data if there isn't any data
|
|
9116
|
+@ There is no sense in attempting to edit the data if there isn'@q'@>t any data
|
9083
|
9117
|
available to edit. This check is also used when retrieving data from the model.
|
9084
|
9118
|
|
9085
|
9119
|
@<Check that the index is valid@>=
|
|
@@ -9151,7 +9185,8 @@ constructor.
|
9151
|
9185
|
@<MeasurementModel Implementation@>=
|
9152
|
9186
|
MeasurementModel::MeasurementModel(QObject *parent) : QAbstractItemModel(parent),
|
9153
|
9187
|
unit(Units::Fahrenheit), hData(new QStringList),
|
9154
|
|
- lastTemperature(new QHash<int, int>)@/
|
|
9188
|
+ lastTemperature(new QHash<int, int>),
|
|
9189
|
+ controlColumns(new QHash<int, bool>)@/
|
9155
|
9190
|
{
|
9156
|
9191
|
colcount = 1;
|
9157
|
9192
|
entries = new QList<MeasurementList *>;
|
|
@@ -9171,7 +9206,7 @@ MeasurementModel::~MeasurementModel()
|
9171
|
9206
|
|
9172
|
9207
|
@ A pair of functions are used to determine the number of rows and columns the
|
9173
|
9208
|
model provides. No entries in the model have children, so the parent should
|
9174
|
|
-always be the invisible root object. If it isn't, we should return 0.
|
|
9209
|
+always be the invisible root object. If it isn'@q'@>t, we should return 0.
|
9175
|
9210
|
|
9176
|
9211
|
@<MeasurementModel Implementation@>=
|
9177
|
9212
|
int MeasurementModel::rowCount(const QModelIndex &parent) const
|
|
@@ -9193,7 +9228,7 @@ int MeasurementModel::columnCount(const QModelIndex &parent) const
|
9193
|
9228
|
}
|
9194
|
9229
|
|
9195
|
9230
|
@ The model maintains a set of header data. At present, it only supports header
|
9196
|
|
-data at the top of the model due to the author's preference to not have row
|
|
9231
|
+data at the top of the model due to the author'@q'@>s preference to not have row
|
9197
|
9232
|
numbers littering the left of the table (the time column is sufficient to
|
9198
|
9233
|
identify the row for the user).
|
9199
|
9234
|
|
|
@@ -9291,6 +9326,13 @@ QVariant MeasurementModel::data(const QModelIndex &index, int role) const@/
|
9291
|
9326
|
{
|
9292
|
9327
|
return QVariant();
|
9293
|
9328
|
}
|
|
9329
|
+ if(controlColumns->contains(index.column()))
|
|
9330
|
+ {
|
|
9331
|
+ if(controlColumns->value(index.column()) == true)
|
|
9332
|
+ {
|
|
9333
|
+ return QVariant(QString("%1").arg(QVariant(row->at(index.column()).toInt()).toString()));
|
|
9334
|
+ }
|
|
9335
|
+ }
|
9294
|
9336
|
switch(unit)
|
9295
|
9337
|
{
|
9296
|
9338
|
case Units::Fahrenheit:
|
|
@@ -10902,10 +10944,12 @@ class XMLOutput : public QObject@/
|
10902
|
10944
|
QIODevice *out;
|
10903
|
10945
|
int time;
|
10904
|
10946
|
QMap<int, QString> temperatureColumns;
|
|
10947
|
+ QMap<int, QString> controlColumns;
|
10905
|
10948
|
QMap<int, QString> annotationColumns;
|
10906
|
10949
|
public:@/
|
10907
|
10950
|
XMLOutput(MeasurementModel *model, QIODevice *device, int timec = 0);
|
10908
|
10951
|
void addTemperatureColumn(const QString &series, int column);
|
|
10952
|
+ void addControlColumn(const QString &series, int column);
|
10909
|
10953
|
void addAnnotationColumn(const QString &series, int column);
|
10910
|
10954
|
void setModel(MeasurementModel *model);
|
10911
|
10955
|
void setTimeColumn(int column);
|
|
@@ -10926,7 +10970,7 @@ bool XMLOutput::output()@t\2\2@>@/
|
10926
|
10970
|
}@/
|
10927
|
10971
|
QXmlStreamWriter xmlout(out);
|
10928
|
10972
|
xmlout.writeStartDocument("1.0");
|
10929
|
|
- xmlout.writeDTD("<!DOCTYPE roastlog2.0>");
|
|
10973
|
+ xmlout.writeDTD("<!DOCTYPE roastlog3.0>");
|
10930
|
10974
|
xmlout.writeStartElement("roastlog");
|
10931
|
10975
|
@<Output the column declarations@>@;
|
10932
|
10976
|
xmlout.writeStartElement("roast");
|
|
@@ -10957,6 +11001,12 @@ foreach(int c, temperatureColumns.keys())
|
10957
|
11001
|
xmlout.writeAttribute("name", temperatureColumns.value(c));
|
10958
|
11002
|
xmlout.writeEndElement();
|
10959
|
11003
|
}
|
|
11004
|
+foreach(int c, controlColumns.keys())
|
|
11005
|
+{
|
|
11006
|
+ xmlout.writeStartElement("controlseries");
|
|
11007
|
+ xmlout.writeAttribute("name", controlColumns.value(c));
|
|
11008
|
+ xmlout.writeEndElement();
|
|
11009
|
+}
|
10960
|
11010
|
foreach(int c, annotationColumns.keys())
|
10961
|
11011
|
{
|
10962
|
11012
|
xmlout.writeStartElement("noteseries");
|
|
@@ -10980,6 +11030,15 @@ foreach(int c, temperatureColumns.keys())@/
|
10980
|
11030
|
break;@t\2@>@/
|
10981
|
11031
|
}@t\2@>@/
|
10982
|
11032
|
}@/
|
|
11033
|
+foreach(int c, controlColumns.keys())
|
|
11034
|
+{
|
|
11035
|
+ if(data->data(data->index(i, c), Qt::DisplayRole).isValid() &&
|
|
11036
|
+ !(data->data(data->index(i, c), Qt::DisplayRole).toString().isEmpty()))
|
|
11037
|
+ {
|
|
11038
|
+ oresult = true;
|
|
11039
|
+ break;
|
|
11040
|
+ }
|
|
11041
|
+}
|
10983
|
11042
|
if(oresult == false)@/
|
10984
|
11043
|
{@t\1@>@/
|
10985
|
11044
|
foreach(int c, annotationColumns.keys())@/
|
|
@@ -11015,6 +11074,17 @@ foreach(int c, temperatureColumns.keys())@/
|
11015
|
11074
|
xmlout.writeEndElement();
|
11016
|
11075
|
}
|
11017
|
11076
|
}
|
|
11077
|
+foreach(int c, controlColumns.keys())
|
|
11078
|
+{
|
|
11079
|
+ if(data->data(data->index(i, c), Qt::DisplayRole).isValid() &&
|
|
11080
|
+ !(data->data(data->index(i, c), Qt::DisplayRole).toString().isEmpty()))
|
|
11081
|
+ {
|
|
11082
|
+ xmlout.writeStartElement("control");
|
|
11083
|
+ xmlout.writeAttribute("series", controlColumns.value(c));
|
|
11084
|
+ xmlout.writeCharacters(data->data(data->index(i, c), Qt::DisplayRole).toString());
|
|
11085
|
+ xmlout.writeEndElement();
|
|
11086
|
+ }
|
|
11087
|
+}
|
11018
|
11088
|
foreach(int c, annotationColumns.keys())@/
|
11019
|
11089
|
{
|
11020
|
11090
|
if(data->data(data->index(i, c), Qt::DisplayRole).isValid() &&
|
|
@@ -11066,6 +11136,11 @@ void XMLOutput::addTemperatureColumn(const QString &series, int column)
|
11066
|
11136
|
temperatureColumns.insert(column, series);
|
11067
|
11137
|
}
|
11068
|
11138
|
|
|
11139
|
+void XMLOutput::addControlColumn(const QString &series, int column)
|
|
11140
|
+{
|
|
11141
|
+ controlColumns.insert(column, series);
|
|
11142
|
+}
|
|
11143
|
+
|
11069
|
11144
|
void XMLOutput::addAnnotationColumn(const QString &series, int column)
|
11070
|
11145
|
{
|
11071
|
11146
|
annotationColumns.insert(column, series);
|
|
@@ -11179,7 +11254,7 @@ while(xmlin.name() != "roast")
|
11179
|
11254
|
{
|
11180
|
11255
|
if(xmlin.isStartElement())
|
11181
|
11256
|
{
|
11182
|
|
- if(xmlin.name() == "tempseries")
|
|
11257
|
+ if((xmlin.name() == "tempseries") || (xmlin.name() == "controlseries"))
|
11183
|
11258
|
{
|
11184
|
11259
|
temperatureColumns.insert(xmlin.attributes().value("name").
|
11185
|
11260
|
toString(),
|
|
@@ -11255,6 +11330,15 @@ else if(xmlin.name() == "temperature")
|
11255
|
11330
|
Measurement measurement(tempval, timeval);
|
11256
|
11331
|
emit measure(measurement, column);
|
11257
|
11332
|
}
|
|
11333
|
+else if(xmlin.name() == "control")
|
|
11334
|
+{
|
|
11335
|
+ column = xmlin.attributes().value("series").toString().isEmpty() ?
|
|
11336
|
+ firstc : temperatureColumns.value(xmlin.attributes().
|
|
11337
|
+ value("series").toString());
|
|
11338
|
+ tempval = xmlin.readElementText().toDouble();
|
|
11339
|
+ Measurement measurement(tempval, timeval, Units::Unitless);
|
|
11340
|
+ emit measure(measurement, column);
|
|
11341
|
+}
|
11258
|
11342
|
else if(xmlin.name() == "annotation")
|
11259
|
11343
|
{
|
11260
|
11344
|
column = xmlin.attributes().value("series").toString().isEmpty() ?
|
|
@@ -11338,10 +11422,12 @@ class CSVOutput@/
|
11338
|
11422
|
QIODevice *out;
|
11339
|
11423
|
int time;
|
11340
|
11424
|
QMap<int, QString> temperatureColumns;
|
|
11425
|
+ QMap<int, QString> controlColumns;
|
11341
|
11426
|
QMap<int, QString> annotationColumns;@/
|
11342
|
11427
|
public:@/
|
11343
|
11428
|
CSVOutput(MeasurementModel *model, QIODevice *device, int timec = 0);
|
11344
|
11429
|
void addTemperatureColumn(const QString &series, int column);
|
|
11430
|
+ void addControlColumn(const QString &series, int column);
|
11345
|
11431
|
void addAnnotationColumn(const QString &series, int column);
|
11346
|
11432
|
void setModel(MeasurementModel *model);
|
11347
|
11433
|
void setTimeColumn(int column);
|
|
@@ -11388,6 +11474,10 @@ foreach(int c, temperatureColumns.keys())
|
11388
|
11474
|
{
|
11389
|
11475
|
output << ',' << temperatureColumns.value(c);
|
11390
|
11476
|
}
|
|
11477
|
+foreach(int c, controlColumns.keys())
|
|
11478
|
+{
|
|
11479
|
+ output << ',' << controlColumns.value(c);
|
|
11480
|
+}
|
11391
|
11481
|
foreach(int c, annotationColumns.keys())
|
11392
|
11482
|
{
|
11393
|
11483
|
output << ',' << annotationColumns.value(c);
|
|
@@ -11409,6 +11499,10 @@ foreach(int c, temperatureColumns.keys())
|
11409
|
11499
|
{
|
11410
|
11500
|
output << ',' << data->data(data->index(i, c), Qt::DisplayRole).toString();
|
11411
|
11501
|
}
|
|
11502
|
+foreach(int c, controlColumns.keys())
|
|
11503
|
+{
|
|
11504
|
+ output << ',' << data->data(data->index(i, c), Qt::DisplayRole).toString();
|
|
11505
|
+}
|
11412
|
11506
|
foreach(int c, annotationColumns.keys())
|
11413
|
11507
|
{
|
11414
|
11508
|
output << ',' << data->data(data->index(i, c), Qt::DisplayRole).toString();
|
|
@@ -11440,6 +11534,11 @@ void CSVOutput::addTemperatureColumn(const QString &series, int column)
|
11440
|
11534
|
temperatureColumns.insert(column, series);
|
11441
|
11535
|
}
|
11442
|
11536
|
|
|
11537
|
+void CSVOutput::addControlColumn(const QString &series, int column)
|
|
11538
|
+{
|
|
11539
|
+ controlColumns.insert(column, series);
|
|
11540
|
+}
|
|
11541
|
+
|
11443
|
11542
|
void CSVOutput::addAnnotationColumn(const QString &series, int column)
|
11444
|
11543
|
{
|
11445
|
11544
|
annotationColumns.insert(column, series);
|