Browse Source

Configuration widget for free text annotation.

Neal Wilson 11 years ago
parent
commit
e22c03d64f
2 changed files with 109 additions and 41 deletions
  1. 59
    0
      src/freeannotation.w
  2. 50
    41
      src/typica.w

+ 59
- 0
src/freeannotation.w View File

@@ -0,0 +1,59 @@
1
+@* Free text annotation control configuration.
2
+
3
+\noindent Some roasting firms like to be able to provide arbitrary text as an
4
+annotation in addition to or instead of fixed form annotations. There is very
5
+little to configure for an annotation control that facilitates that
6
+functionality. The existence and position of the control is implicit in the
7
+existence of a node representing the control in the configuration. An optional
8
+label next to the control is the only configurable option at present. A
9
+configuration widget and associated registrations to integrate with the
10
+configuration system is still required.
11
+
12
+@<Class declarations@>=
13
+class FreeAnnotationConfWidget : public BasicDeviceConfigurationWidget
14
+{
15
+	Q_OBJECT
16
+	public:
17
+		Q_INVOKABLE FreeAnnotationConfWidget(DeviceTreeModel *model, const QModelIndex &index);
18
+	private slots:
19
+		void updateLabel(const QString &text);
20
+};
21
+
22
+@ The constructor should seem familiar by now.
23
+
24
+@<FreeAnnotationConfWidget implementation@>=
25
+FreeAnnotationConfWidget::FreeAnnotationConfWidget(DeviceTreeModel *model,
26
+                                                   const QModelIndex &index)
27
+	: BasicDeviceConfigurationWidget(model, index)
28
+{
29
+	QFormLayout *layout = new QFormLayout;
30
+	QLineEdit *labelEdit = new QLineEdit;
31
+	layout->addRow(tr("Label Text:"), labelEdit);
32
+	@<Get device configuration data for current node@>@;
33
+	for(int i = 0; i < configData.size(); i++)
34
+	{
35
+		node = configData.at(i).toElement();
36
+		if(node.attribute("name") == "labeltext")
37
+		{
38
+			labelEdit->setText(node.attribute("value"));
39
+		}
40
+	}
41
+	updateLabel(labelEdit->text());
42
+	connect(labelEdit, SIGNAL(textEdited(QString)),
43
+	        this, SLOT(updateLabel(QString)));
44
+	setLayout(layout);
45
+}
46
+
47
+@ The update slot is trivial.
48
+
49
+@<FreeAnnotationConfWidget implementation@>=
50
+void FreeAnnotationConfWidget::updateLabel(const QString &text)
51
+{
52
+	updateAttribute("labeltext", text);
53
+}
54
+
55
+@ There is nothing unusual in the control registration.
56
+
57
+@<Register device configuration widgets@>=
58
+app.registerDeviceConfigurationWidget("freeannotation",
59
+                                      FreeAnnotationConfWidget::staticMetaObject);

+ 50
- 41
src/typica.w View File

@@ -22,7 +22,7 @@
22 22
 \mark{\noexpand\nullsec0{A Note on Notation}}
23 23
 \def\pn{Typica}
24 24
 \def\filebase{typica}
25
-\def\version{1.4.3 \number\year-\number\month-\number\day}
25
+\def\version{1.5 \number\year-\number\month-\number\day}
26 26
 \def\years{2007--2013}
27 27
 \def\title{\pn{} (Version \version)}
28 28
 \newskip\dangerskipb
@@ -60,10 +60,10 @@
60 60
 	distribute, sublicense, and/or sell copies of the Software, and to permit
61 61
 	persons to whom the Software is furnished to do so, subject to the following
62 62
 	conditions:\medskip
63
-	
63
+
64 64
 	The above copyright notice and this permission notice shall be included in
65 65
 	all copies or substantial portions of the Software.\medskip
66
-	
66
+
67 67
 	THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 68
 	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 69
 	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -71,24 +71,24 @@
71 71
 	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72 72
 	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73 73
 	IN THE SOFTWARE.
74
-	
74
+
75 75
 	\bigskip\noindent Parts of \pn{} are from QextSerialPort which is used under the
76 76
 	MIT license as follows:
77
-	
77
+
78 78
 	\bigskip\noindent Copyright \copyright\ 2000--2003 Wayne Roth
79
-	
79
+
80 80
     \noindent Copyright \copyright\ 2004--2007 Stefan Sander
81
-    
81
+
82 82
 	\noindent Copyright \copyright\ 2007 Michal Policht
83
-    
83
+
84 84
 	\noindent Copyright \copyright\ 2008 Brandon Fosdick
85
-    
85
+
86 86
 	\noindent Copyright \copyright\ 2009--2010 Liam Staskawicz
87
-    
87
+
88 88
 	\noindent Copyright \copyright\ 2011 Debao Zhang
89
-    
89
+
90 90
     \bigskip\noindent Web: http://code.google.com/p/qextserialport/
91
-    
91
+
92 92
     \bigskip\noindent Permission is hereby granted, free of charge, to any person obtaining
93 93
     a copy of this software and associated documentation files (the
94 94
     ``Software''), to deal in the Software without restriction, including
@@ -96,10 +96,10 @@
96 96
     distribute, sublicense, and/or sell copies of the Software, and to
97 97
     permit persons to whom the Software is furnished to do so, subject to
98 98
     the following conditions:
99
-    
99
+
100 100
     The above copyright notice and this permission notice shall be
101 101
     included in all copies or substantial portions of the Software.
102
-    
102
+
103 103
     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
104 104
     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
105 105
     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -833,6 +833,7 @@ generated file empty.
833 833
 @<LinearSplineInterpolator Implementation@>@/
834 834
 @<LinearSplineInterpolationConfWidget implementation@>@/
835 835
 @<TranslationConfWidget implementation@>@/
836
+@<FreeAnnotationConfWidget implementation@>@/
836 837
 
837 838
 @ A few headers are required for various parts of \pn{}. These allow the use of
838 839
 various Qt modules.
@@ -1141,7 +1142,7 @@ settings and restoring the window geometry from these settings.
1141 1142
 
1142 1143
 As of version 1.4 window geometry management is provided for all windows. The
1143 1144
 |restoreSizeAndPosition()| and |saveSizeAndPosition()| methods should be
1144
-considered depreciated. 
1145
+considered depreciated.
1145 1146
 
1146 1147
 @<Class declarations@>=
1147 1148
 class ScriptQMainWindow : public QMainWindow@/
@@ -1709,7 +1710,7 @@ QScriptValue constructQBoxLayout(QScriptContext *context,
1709 1710
 void setQBoxLayoutProperties(QScriptValue value, QScriptEngine *engine);
1710 1711
 QScriptValue QBoxLayout_addLayout(QScriptContext *context, QScriptEngine *engine);
1711 1712
 QScriptValue QBoxLayout_addWidget(QScriptContext *context, QScriptEngine *engine);
1712
-								  
1713
+
1713 1714
 @ The script constructor must be passed to the scripting engine.
1714 1715
 
1715 1716
 @<Set up the scripting engine@>=
@@ -1815,7 +1816,7 @@ QScriptValue QBoxLayout_addWidget(QScriptContext *context, QScriptEngine *)
1815 1816
 \noindent The |QAction| class is used in \pn{} to create menu items and respond
1816 1817
 to the selection of these items. Three functions are required for our scripting
1817 1818
 needs with regard to this class.
1818
-								  
1819
+
1819 1820
 @<Function prototypes for scripting@>=
1820 1821
 QScriptValue constructQAction(QScriptContext *context, QScriptEngine *engine);
1821 1822
 QScriptValue QAction_setShortcut(QScriptContext *context,
@@ -1945,7 +1946,7 @@ QScriptValue QFileDialog_getSaveFileName(QScriptContext *context,
1945 1946
 			retval = QScriptValue(engine,
1946 1947
 							      QFileDialog::getSaveFileName(widget, caption,
1947 1948
 								                               dir, "", 0, 0));
1948
-		
1949
+
1949 1950
 			setQFileDialogProperties(retval, engine);
1950 1951
 		}
1951 1952
 		else
@@ -3168,7 +3169,7 @@ are not created directly.
3168 3169
 @<Function prototypes for scripting@>=
3169 3170
 void setQAbstractScrollAreaProperties(QScriptValue value,
3170 3171
                                       QScriptEngine *engine);
3171
-									  
3172
+
3172 3173
 @ The implementation of this is simple.
3173 3174
 
3174 3175
 @<Functions for scripting@>=
@@ -3494,7 +3495,7 @@ QScriptValue setFont(QScriptContext *context, QScriptEngine *engine);
3494 3495
 QScriptValue annotationFromRecord(QScriptContext *context,
3495 3496
                                   QScriptEngine *engine);
3496 3497
 QScriptValue setTabOrder(QScriptContext *context, QScriptEngine *engine);
3497
-									
3498
+
3498 3499
 @ These functions are passed to the scripting engine.
3499 3500
 
3500 3501
 @<Set up the scripting engine@>=
@@ -3771,7 +3772,7 @@ and reorganized.\endanger
3771 3772
 
3772 3773
 @<Function prototypes for scripting@>=
3773 3774
 QScriptValue createWindow(QScriptContext *context, QScriptEngine *engine);
3774
-void addLayoutToWidget(QDomElement element, QStack<QWidget*> *widgetStack, 
3775
+void addLayoutToWidget(QDomElement element, QStack<QWidget*> *widgetStack,
3775 3776
                        QStack<QLayout*> *layoutStack);
3776 3777
 void addLayoutToLayout(QDomElement element, QStack<QWidget *> *widgetStack,
3777 3778
                        QStack<QLayout *> *layoutStack);
@@ -4046,7 +4047,7 @@ are supported. The first two resolve to |QBoxLayout| layouts, {\tt grid}
4046 4047
 resolves to a |QGridLayout|, and {\tt stack} resolves to a |QStackedLayout|.
4047 4048
 
4048 4049
 @<Functions for scripting@>=
4049
-void addLayoutToWidget(QDomElement element, QStack<QWidget*> *widgetStack, 
4050
+void addLayoutToWidget(QDomElement element, QStack<QWidget*> *widgetStack,
4050 4051
                        QStack<QLayout*> *layoutStack)
4051 4052
 {
4052 4053
 	if(element.hasAttribute("type"))
@@ -7413,7 +7414,7 @@ QScriptValue constructMeasurementTimeOffset(QScriptContext *context,@|
7413 7414
                                             QScriptEngine *engine);
7414 7415
 void setMeasurementTimeOffsetProperties(QScriptValue value,
7415 7416
                                         QScriptEngine *engine);
7416
-										   
7417
+
7417 7418
 @ The scripting engine must be informed of the constructor.
7418 7419
 
7419 7420
 @<Set up the scripting engine@>=
@@ -8782,7 +8783,7 @@ QScriptValue ZoomLog_lastTime(QScriptContext *context, QScriptEngine *engine)
8782 8783
 	ZoomLog *self = getself<@[ZoomLog *@]>(context);
8783 8784
 	return QScriptValue(engine, self->lastTime(argument<int>(0, context)));
8784 8785
 }
8785
-		
8786
+
8786 8787
 @* A model for roasting data.
8787 8788
 
8788 8789
 \noindent Qt provides a tool called the model view architecture. This provides a
@@ -8914,7 +8915,7 @@ void MeasurementModel::newMeasurement(Measurement measure, int tempcolumn)
8914 8915
 	emit rowChanged(insertion);
8915 8916
 	delete temp;
8916 8917
 }
8917
-	
8918
+
8918 8919
 @ To find the insertion point for new measurements we use a binary search of the
8919 8920
 existing data. The code below is a direct adaptation of Program B\nfnote{%
8920 8921
 \underbar{The Art of Computer Programming} Volume 3 Sorting and Searching 2nd
@@ -9404,7 +9405,7 @@ QVariant MeasurementModel::data(const QModelIndex &index, int role) const@/
9404 9405
 					default:
9405 9406
 						break;
9406 9407
 				}
9407
-			} 
9408
+			}
9408 9409
 			return QVariant(row->at(index.column()).toString());
9409 9410
 		}
9410 9411
 	}
@@ -9757,7 +9758,7 @@ because there were no shops in Racine that could sell a simple dual digital
9757 9758
 count up timer at a time when my first timer was malfunctioning. After
9758 9759
 attempting to purchase a replacement device at several stores that have sold
9759 9760
 such devices in the past, I decided to spend a couple hours writing my own
9760
-timer. 
9761
+timer.
9761 9762
 
9762 9763
 For historical reasons, the |TimerDisplay| class is considerably more functional
9763 9764
 than \pn{} requires. Those needing only a digital timer can extract the code for
@@ -10207,7 +10208,7 @@ class PackLayout : public QLayout@/
10207 10208
 };
10208 10209
 
10209 10210
 @ The interesting portion of this class is in |doLayout()|. This function goes
10210
-over the items in the layout and sets the geometry appropriately. 
10211
+over the items in the layout and sets the geometry appropriately.
10211 10212
 
10212 10213
 The seemingly odd choice of returning |y| at the end of this function (indeed of
10213 10214
 having a return value at all) is to allow this function to provide the return
@@ -10536,7 +10537,7 @@ WidgetDecorator::WidgetDecorator(QWidget *widget, const QString &labeltext,
10536 10537
 	@<Adjust the decoration width@>@;
10537 10538
 	@<Pack widgets into the layout@>@;
10538 10539
 }
10539
-	
10540
+
10540 10541
 @ The decoration is a |QGraphicsView|. To get this to look right, we need to
10541 10542
 make sure there aren't any scroll bars and there shouldn't be a frame
10542 10543
 surrounding it. While we're at it, we allow it to accept clicks, though this
@@ -12368,16 +12369,16 @@ int main(int argc, char **argv)@/
12368 12369
 	Application app(*c, argv);
12369 12370
 	@<Set up icons@>@;
12370 12371
 	@<Set up fonts@>@;
12371
-	
12372
+
12372 12373
 	QSettings settings;
12373
-	
12374
+
12374 12375
 	@<Register device configuration widgets@>@;
12375 12376
 	@<Prepare the database connection@>@;
12376 12377
 	@<Load the application configuration@>@;
12377 12378
 	@<Set up the scripting engine@>@;
12378 12379
 	app.engine = engine;
12379 12380
 	@<Find and evaluate starting script@>@;
12380
-	
12381
+
12381 12382
 	int retval = app.exec();
12382 12383
 	delete engine;
12383 12384
 	return retval;@/
@@ -13216,7 +13217,7 @@ QScriptValue QTextEdit_print(QScriptContext *context, QScriptEngine *)
13216 13217
 	QTextEdit *self = getself<QTextEdit *>(context);
13217 13218
 	QTextDocument *document = self->document();
13218 13219
 	QPrinter printer;
13219
-	
13220
+
13220 13221
 	QPrintDialog printwindow(&printer, self);
13221 13222
 	if(printwindow.exec() != QDialog::Accepted)
13222 13223
 	{
@@ -14580,7 +14581,7 @@ QScriptValue QAbstractItemModel_data(QScriptContext *context, QScriptEngine *eng
14580 14581
 QScriptValue QAbstractItemModel_index(QScriptContext *context, QScriptEngine *engine);
14581 14582
 QScriptValue QAbstractItemModel_rowCount(QScriptContext *context, QScriptEngine *engine);
14582 14583
 QScriptValue QAbstractItemModel_hasChildren(QScriptContext *context, QScriptEngine *engine);
14583
-	
14584
+
14584 14585
 @ The constructor is trivial.
14585 14586
 
14586 14587
 @<Functions for scripting@>=
@@ -15149,15 +15150,21 @@ RoasterConfWidget::RoasterConfWidget(DeviceTreeModel *model, const QModelIndex &
15149 15150
 	NodeInserter *basicButtonInserter = new NodeInserter(tr("Annotation Button"), tr("Annotation Button"), "annotationbutton");
15150 15151
 	NodeInserter *countingButtonInserter = new NodeInserter(tr("Counting Button"), tr("Counting Button"), "reconfigurablebutton");
15151 15152
 	NodeInserter *spinBoxInserter = new NodeInserter(tr("Numeric Entry"), tr("Numeric Entry"), "annotationspinbox");
15153
+	NodeInserter *freeAnnotationInserter = new NodeInserter(tr("Free Text"),
15154
+	                                                        tr("Free Text"),
15155
+	                                                        "freeannotation");
15152 15156
 	annotationMenu->addAction(basicButtonInserter);
15153 15157
 	annotationMenu->addAction(countingButtonInserter);
15154 15158
 	annotationMenu->addAction(spinBoxInserter);
15159
+	annotationMenu->addAction(freeAnnotationInserter);
15155 15160
 	connect(basicButtonInserter, SIGNAL(triggered(QString, QString)),
15156 15161
 	        this, SLOT(insertChildNode(QString, QString)));
15157 15162
 	connect(countingButtonInserter, SIGNAL(triggered(QString, QString)),
15158 15163
 	        this, SLOT(insertChildNode(QString, QString)));
15159 15164
 	connect(spinBoxInserter, SIGNAL(triggered(QString, QString)),
15160 15165
 	        this, SLOT(insertChildNode(QString, QString)));
15166
+	connect(freeAnnotationInserter, SIGNAL(triggered(QString, QString)),
15167
+	        this, SLOT(insertChildNode(QString, QString)));
15161 15168
 	addAnnotationControlButton->setMenu(annotationMenu);
15162 15169
 	layout->addWidget(addAnnotationControlButton);
15163 15170
 	QPushButton *advancedButton = new QPushButton(tr("Advanced Features"));
@@ -15190,7 +15197,7 @@ RoasterConfWidget::RoasterConfWidget(DeviceTreeModel *model, const QModelIndex &
15190 15197
 	connect(id, SIGNAL(valueChanged(int)), this, SLOT(updateRoasterId(int)));
15191 15198
 	setLayout(layout);
15192 15199
 }
15193
-	
15200
+
15194 15201
 @ Iterating over the configuration data associated with the current node is
15195 15202
 required in nearly every configuration widget. The specifics of the loop
15196 15203
 vary, but there is likely a better way to generalize that. Until then,
@@ -15452,7 +15459,7 @@ app.registerDeviceConfigurationWidget("nidaqmxbase9211series",
15452 15459
 	NiDaqMxBase9211ConfWidget::staticMetaObject);
15453 15460
 app.registerDeviceConfigurationWidget("ni9211seriestc",
15454 15461
 	Ni9211TcConfWidget::staticMetaObject);
15455
-	
15462
+
15456 15463
 @ Furthermore, we should create the NodeInserter objects for adding top level
15457 15464
 nodes to the configuration. Preferably we would only allow top level nodes to
15458 15465
 be inserted when all prerequisite software is available.
@@ -16639,7 +16646,7 @@ inserter = new NodeInserter(tr("Modbus RTU Port"), tr("Modbus RTU Port"), "modbu
16639 16646
 topLevelNodeInserters.append(inserter);
16640 16647
 #endif
16641 16648
 
16642
-@* Configuration of Annotation Controls.
16649
+@** Configuration of Annotation Controls.
16643 16650
 
16644 16651
 \noindent Aside from the details of hardware devices, the logging view must
16645 16652
 also be able to set up log annotation controls. A few different control types
@@ -16908,6 +16915,8 @@ void NoteSpinConfWidget::updatePosttext(const QString &text)
16908 16915
 @<Register device configuration widgets@>=
16909 16916
 app.registerDeviceConfigurationWidget("annotationspinbox", NoteSpinConfWidget::staticMetaObject);
16910 16917
 
16918
+@i freeannotation.w
16919
+
16911 16920
 @** Communicating with a Device through Modbus RTU.
16912 16921
 
16913 16922
 \noindent The classes described here need to be further generalized to support
@@ -17362,7 +17371,7 @@ Messages with a function number of 0x03 or 0x04 will be at least 7 bytes in
17362 17371
 length with the total length determined by the sum of 5 and the value in the
17363 17372
 fifth byte. Messages with a function number of 0x05, 0x06, or 0x10 will be 8
17364 17373
 bytes in length. Messages with a function number greater than 0x80 will be five
17365
-bytes in length. 
17374
+bytes in length.
17366 17375
 
17367 17376
 @<Check Modbus RTU message size@>=
17368 17377
 if(responseBuffer.size() < 5)
@@ -17480,7 +17489,7 @@ void ModbusRTUDevice::outputSV(double value)
17480 17489
 	char *valBytes = (char*)&outval;
17481 17490
 	message.append(valBytes[1]);
17482 17491
 	message.append(valBytes[0]);
17483
-	queueMessage(message, this, "ignore(QByteArray)");	
17492
+	queueMessage(message, this, "ignore(QByteArray)");
17484 17493
 }
17485 17494
 
17486 17495
 @ We don't care about the response when sending a new SV.
@@ -18144,7 +18153,7 @@ LinearSplineInterpolationConfWidget::LinearSplineInterpolationConfWidget(DeviceT
18144 18153
 			@<Convert numeric array literal to list@>@;
18145 18154
 			int column = 0;
18146 18155
 			@<Populate model column from list@>@;
18147
-			
18156
+
18148 18157
 		}
18149 18158
 		else if(node.attribute("name") == "destinationvalues")
18150 18159
 		{
@@ -18183,7 +18192,7 @@ for(int i = 0; i < itemList.size(); i++)
18183 18192
 {
18184 18193
 	knotmodel->setData(knotmodel->index(i, column),
18185 18194
 	                   QVariant(itemList.at(i).toDouble()),
18186
-                       Qt::DisplayRole);   
18195
+                       Qt::DisplayRole);
18187 18196
 }
18188 18197
 
18189 18198
 @ When data in the table is changed we simply overwrite any previously saved

Loading…
Cancel
Save