|
@@ -0,0 +1,484 @@
|
|
1
|
+@** Phidget22 library.
|
|
2
|
+
|
|
3
|
+\noindent Around the same time as the \pn{} 1.8.0 release, Phidgets released a
|
|
4
|
+new hardware communications library with no regard for compatibility with
|
|
5
|
+existing software and poor communication around that fact. They did, however,
|
|
6
|
+provide hardware specimen for testing that requires the new library.
|
|
7
|
+
|
|
8
|
+API differences are significant enough that it makes more sense to write new
|
|
9
|
+code for interacting with phidget22 than attempting to retrofit existing
|
|
10
|
+phidget21 code. By leaving both in, there is no configuration disription for
|
|
11
|
+people already using hardware previously supported and it is possible to use
|
|
12
|
+both libraries simultaneously to communicate with different hardware.
|
|
13
|
+
|
|
14
|
+The option to configure devices with this library should only be shown if the
|
|
15
|
+library is installed. The library name is different on a Mac.
|
|
16
|
+
|
|
17
|
+@<Register top level device configuration nodes@>=
|
|
18
|
+#if __APPLE__
|
|
19
|
+QLibrary phidget22check("Phidget22.framework/Phidget22");
|
|
20
|
+#else
|
|
21
|
+QLibrary phidget22check("phidget22");
|
|
22
|
+#endif
|
|
23
|
+if(phidget22check.load())
|
|
24
|
+{
|
|
25
|
+ inserter = new NodeInserter(tr("Phidget22"), tr("Phidget22"), "phidget22",
|
|
26
|
+ NULL);
|
|
27
|
+ topLevelNodeInserters.append(inserter);
|
|
28
|
+ phidget22check.unload();
|
|
29
|
+}
|
|
30
|
+
|
|
31
|
+@ A top level configuration is used to group channels using this library while
|
|
32
|
+child nodes provide channel configuration. The configuration widgets need to be
|
|
33
|
+registered so they can be instantiated as appropriate.
|
|
34
|
+
|
|
35
|
+@<Register device configuration widgets@>=
|
|
36
|
+app.registerDeviceConfigurationWidget("phidget22",
|
|
37
|
+ PhidgetConfWidget::staticMetaObject);
|
|
38
|
+app.registerDeviceConfigurationWidget("phidgetchannel",
|
|
39
|
+ PhidgetChannelConfWidget::staticMetaObject);
|
|
40
|
+
|
|
41
|
+@ The first configuration widget just serves as a parent to all channels using
|
|
42
|
+this library. There does not seem to be a need for the configuration to mirror
|
|
43
|
+how the hardware is connected, so this serves as a parent node for any number
|
|
44
|
+of devices connected either directly or through a hub.
|
|
45
|
+
|
|
46
|
+@<Class declarations@>=
|
|
47
|
+class PhidgetConfWidget : public BasicDeviceConfigurationWidget
|
|
48
|
+{
|
|
49
|
+ Q_OBJECT
|
|
50
|
+ public:
|
|
51
|
+ Q_INVOKABLE PhidgetConfWidget(DeviceTreeModel *model,
|
|
52
|
+ const QModelIndex &index);
|
|
53
|
+ private slots:
|
|
54
|
+ void addChannel();
|
|
55
|
+};
|
|
56
|
+
|
|
57
|
+@ The only thing this configuration widget provides is a way to create child
|
|
58
|
+nodes.
|
|
59
|
+
|
|
60
|
+@<Phidget implementation@>=
|
|
61
|
+PhidgetConfWidget::PhidgetConfWidget(DeviceTreeModel *model,
|
|
62
|
+ const QModelIndex &index)
|
|
63
|
+ : BasicDeviceConfigurationWidget(model, index)
|
|
64
|
+{
|
|
65
|
+ QHBoxLayout *layout = new QHBoxLayout;
|
|
66
|
+ QPushButton *addChannelButton = new QPushButton(tr("Add Channel"));
|
|
67
|
+ connect(addChannelButton, SIGNAL(clicked()), this, SLOT(addChannel()));
|
|
68
|
+ layout->addWidget(addChannelButton);
|
|
69
|
+ setLayout(layout);
|
|
70
|
+}
|
|
71
|
+
|
|
72
|
+void PhidgetConfWidget::addChannel()
|
|
73
|
+{
|
|
74
|
+ insertChildNode(tr("Channel"), "phidgetchannel");
|
|
75
|
+}
|
|
76
|
+
|
|
77
|
+@ For this library, \pn{} supports a broader range of hardware. This requires
|
|
78
|
+slightly more involved hardware configuration to ensure that a given channel
|
|
79
|
+configuration consistently refers to the same sensor.
|
|
80
|
+
|
|
81
|
+Channels will be initialized with a device serial number, a channel number, and
|
|
82
|
+other channel specific configuration options as applicable. These other
|
|
83
|
+configuration options depend on the sensor type associated with the channel. A
|
|
84
|
+thermocouple requires different configuration options than an RTD while the
|
|
85
|
+built in ambient temperature sensors on some devices do not require additional
|
|
86
|
+configuration.
|
|
87
|
+
|
|
88
|
+At present, only temperature sensors are supported, however this code could be
|
|
89
|
+extended to support other options.
|
|
90
|
+
|
|
91
|
+To simplify configuration, a combo box is provided which displays all of the
|
|
92
|
+currently connected channels that \pn{} supports and allows a configuration
|
|
93
|
+widget to obtain relevant channel information when the desired channel is
|
|
94
|
+selected.
|
|
95
|
+
|
|
96
|
+@<Class declarations@>=
|
|
97
|
+class PhidgetChannelSelector : public QComboBox
|
|
98
|
+{
|
|
99
|
+ Q_OBJECT
|
|
100
|
+ public:
|
|
101
|
+ PhidgetChannelSelector();
|
|
102
|
+ ~PhidgetChannelSelector();
|
|
103
|
+ void addChannel(void *device);
|
|
104
|
+ void removeChannel(void *device);
|
|
105
|
+ private:
|
|
106
|
+ QLibrary driver;
|
|
107
|
+ void *manager;
|
|
108
|
+ @<Phidget22 function pointers@>@;
|
|
109
|
+};
|
|
110
|
+
|
|
111
|
+@ At this point, it becomes necessary to call functions in the library. To avoid
|
|
112
|
+a dependency on phidget22.h some function pointer types are created.
|
|
113
|
+
|
|
114
|
+@<Additional type definitions@>=
|
|
115
|
+#if defined(__stdcall)
|
|
116
|
+ #define CCONV __stdcall
|
|
117
|
+#else
|
|
118
|
+ #if defined(_MSC_VER)
|
|
119
|
+ #define CCONV __stdcall
|
|
120
|
+ #else
|
|
121
|
+ #define CCONV
|
|
122
|
+ #endif
|
|
123
|
+#endif
|
|
124
|
+
|
|
125
|
+typedef int (CCONV *PhidgetPointer)(void *);
|
|
126
|
+typedef int (CCONV *PhidgetPointerStringOut)(void *, char **);
|
|
127
|
+typedef int (CCONV *PhidgetPointerIntOut)(void *, int *);
|
|
128
|
+typedef void (CCONV *PhidgetManagerCallback)(void *, void *, void *);
|
|
129
|
+typedef int (CCONV *PhidgetPointerCallbackPointer)(void *,
|
|
130
|
+ PhidgetManagerCallback,
|
|
131
|
+ void *);
|
|
132
|
+
|
|
133
|
+@ These are used to define function pointers that will be used to
|
|
134
|
+communicate with the library.
|
|
135
|
+
|
|
136
|
+@<Phidget22 function pointers@>=
|
|
137
|
+PhidgetPointer createManager;
|
|
138
|
+PhidgetPointerCallbackPointer setOnAttachManager;
|
|
139
|
+PhidgetPointerCallbackPointer setOnDetachManager;
|
|
140
|
+PhidgetPointer openManager;
|
|
141
|
+PhidgetPointerStringOut getDeviceName;
|
|
142
|
+PhidgetPointerIntOut getDeviceSerialNumber;
|
|
143
|
+PhidgetPointerIntOut getChannel;
|
|
144
|
+PhidgetPointerIntOut getChannelClass;
|
|
145
|
+PhidgetPointerIntOut getChannelSubclass;
|
|
146
|
+PhidgetPointer closeManager;
|
|
147
|
+PhidgetPointer deleteManager;
|
|
148
|
+
|
|
149
|
+@ These pointers must be initialized before they can be used.
|
|
150
|
+
|
|
151
|
+@<Initialize phidget22 function pointers@>=
|
|
152
|
+if((createManager = (PhidgetPointer) driver.resolve("PhidgetManager_create")) == 0 ||
|
|
153
|
+ (setOnAttachManager = (PhidgetPointerCallbackPointer) driver.resolve("PhidgetManager_setOnAttachHandler")) == 0 ||
|
|
154
|
+ (setOnDetachManager = (PhidgetPointerCallbackPointer) driver.resolve("PhidgetManager_setOnDetachHandler")) == 0 ||
|
|
155
|
+ (openManager = (PhidgetPointer) driver.resolve("PhidgetManager_open")) == 0 ||
|
|
156
|
+ (getDeviceName = (PhidgetPointerStringOut) driver.resolve("Phidget_getDeviceName")) == 0 ||
|
|
157
|
+ (getDeviceSerialNumber = (PhidgetPointerIntOut) driver.resolve("Phidget_getDeviceSerialNumber")) == 0 ||
|
|
158
|
+ (getChannel = (PhidgetPointerIntOut) driver.resolve("Phidget_getChannel")) == 0 ||
|
|
159
|
+ (getChannelClass = (PhidgetPointerIntOut) driver.resolve("Phidget_getChannelClass")) == 0 ||
|
|
160
|
+ (getChannelSubclass = (PhidgetPointerIntOut) driver.resolve("Phidget_getChannelSubclass")) == 0 ||
|
|
161
|
+ (closeManager = (PhidgetPointer) driver.resolve("PhidgetManager_close")) == 0 ||
|
|
162
|
+ (deleteManager = (PhidgetPointer) driver.resolve("PhidgetManager_delete")) == 0)
|
|
163
|
+{
|
|
164
|
+ QMessageBox::critical(NULL, tr("Typica: Link error"),
|
|
165
|
+ tr("Failed to link a required symbol in phidget22."));
|
|
166
|
+ return;
|
|
167
|
+}
|
|
168
|
+
|
|
169
|
+@ The constuctor sets up a manager so that appropriate channels can be added to
|
|
170
|
+the combo box.
|
|
171
|
+
|
|
172
|
+@<Phidget implementation@>=
|
|
173
|
+PhidgetChannelSelector::PhidgetChannelSelector() : QComboBox(), manager(NULL)
|
|
174
|
+{
|
|
175
|
+#if __APPLE__
|
|
176
|
+ driver.setFileName("Phidget22.framework/Phidget22");
|
|
177
|
+#else
|
|
178
|
+ driver.setFileName("phidget22");
|
|
179
|
+#endif
|
|
180
|
+ if(!driver.load())
|
|
181
|
+ {
|
|
182
|
+ QMessageBox::critical(NULL, tr("Typica: Driver not found"),
|
|
183
|
+ tr("Failed to find phidget22. Please install it."));
|
|
184
|
+ return;
|
|
185
|
+ }
|
|
186
|
+ @<Initialize phidget22 function pointers@>@;
|
|
187
|
+ createManager(&manager);
|
|
188
|
+ setOnAttachManager(manager, ChannelListAddChannel, this);
|
|
189
|
+ setOnDetachManager(manager, ChannelListRemoveChannel, this);
|
|
190
|
+ openManager(manager);
|
|
191
|
+}
|
|
192
|
+
|
|
193
|
+@ The callbacks registered in the constructor pass a pointer to the combo box
|
|
194
|
+so that contents can be updated from the relevant global functions.
|
|
195
|
+
|
|
196
|
+@<Additional functions@>=
|
|
197
|
+void CCONV ChannelListAddChannel(void *, void *context, void *device)
|
|
198
|
+{
|
|
199
|
+ PhidgetChannelSelector *list =
|
|
200
|
+ qobject_cast<PhidgetChannelSelector*>((QObject*)context);
|
|
201
|
+ list->addChannel(device);
|
|
202
|
+}
|
|
203
|
+
|
|
204
|
+void CCONV ChannelListRemoveChannel(void *, void *context, void *device)
|
|
205
|
+{
|
|
206
|
+ PhidgetChannelSelector *list =
|
|
207
|
+ qobject_cast<PhidgetChannelSelector*>((QObject*)context);
|
|
208
|
+ list->removeChannel(device);
|
|
209
|
+}
|
|
210
|
+
|
|
211
|
+@ These require function prototypes.
|
|
212
|
+
|
|
213
|
+@<Additional function prototypes@>=
|
|
214
|
+void CCONV ChannelListAddChannel(void *manager, void *context, void *device);
|
|
215
|
+void CCONV ChannelListRemoveChannel(void *manager, void *context,
|
|
216
|
+ void *device);
|
|
217
|
+
|
|
218
|
+@ Adding and removing channels from the list happens in class where pointers
|
|
219
|
+to the required library functions are known.
|
|
220
|
+
|
|
221
|
+@<Phidget implementation@>=
|
|
222
|
+void PhidgetChannelSelector::addChannel(void *device)
|
|
223
|
+{
|
|
224
|
+ char *deviceName;
|
|
225
|
+ int deviceSerialNumber;
|
|
226
|
+ int channel;
|
|
227
|
+ int channelClass;
|
|
228
|
+ int channelSubclass;
|
|
229
|
+
|
|
230
|
+ getDeviceName(device, &deviceName);
|
|
231
|
+ getDeviceSerialNumber(device, &deviceSerialNumber);
|
|
232
|
+ getChannel(device, &channel);
|
|
233
|
+ getChannelClass(device, &channelClass);
|
|
234
|
+ getChannelSubclass(device, &channelSubclass);
|
|
235
|
+
|
|
236
|
+ QMap<QString,QVariant> itemData;
|
|
237
|
+
|
|
238
|
+ if(channelClass == 28) // Temperature sensor
|
|
239
|
+ {
|
|
240
|
+ itemData.insert("serialNumber", QString("%1").arg(deviceSerialNumber));
|
|
241
|
+ itemData.insert("channel", QString("%1").arg(channel));
|
|
242
|
+ itemData.insert("class", QString("%1").arg(channelClass));
|
|
243
|
+ itemData.insert("subclass", QString("%1").arg(channelSubclass));
|
|
244
|
+ addItem(QString("%1: %2").arg(deviceName).arg(channel), QVariant(itemData));
|
|
245
|
+ }
|
|
246
|
+}
|
|
247
|
+
|
|
248
|
+@ On removal, no attempt is made to match each call to the exact channel
|
|
249
|
+referenced. Rather, the assumption is that all channels on a device with a
|
|
250
|
+matching serial number should be removed at once and in the case of a
|
|
251
|
+multi-channel device getting removed, subsequent calls will just fail to match
|
|
252
|
+anything. The most common expected scenario is that only one device will be
|
|
253
|
+connected or not connected, so removing this results in an empty list for
|
|
254
|
+channels that were removed early.
|
|
255
|
+
|
|
256
|
+@<Phidget implementation@>=
|
|
257
|
+void PhidgetChannelSelector::removeChannel(void *device)
|
|
258
|
+{
|
|
259
|
+ int deviceSerialNumber;
|
|
260
|
+
|
|
261
|
+ getDeviceSerialNumber(device, &deviceSerialNumber);
|
|
262
|
+
|
|
263
|
+ for(int i = count() - 1; i >= 0; i--)
|
|
264
|
+ {
|
|
265
|
+ QMap<QString,QVariant> data = itemData(i).toMap();
|
|
266
|
+ if(data.value("serialNumber").toInt() == deviceSerialNumber)
|
|
267
|
+ {
|
|
268
|
+ removeItem(i);
|
|
269
|
+ }
|
|
270
|
+ }
|
|
271
|
+}
|
|
272
|
+
|
|
273
|
+@ A destructor closes and deletes the manager.
|
|
274
|
+
|
|
275
|
+@<Phidget implementation@>=
|
|
276
|
+PhidgetChannelSelector::~PhidgetChannelSelector()
|
|
277
|
+{
|
|
278
|
+ if(manager != NULL)
|
|
279
|
+ {
|
|
280
|
+ closeManager(manager);
|
|
281
|
+ deleteManager(&manager);
|
|
282
|
+ }
|
|
283
|
+}
|
|
284
|
+
|
|
285
|
+@ Channel configuration provides a |PhidgetChannelSelector| for choosing
|
|
286
|
+among connected devices but also displays the relevant configuration data.
|
|
287
|
+
|
|
288
|
+@<Class declarations@>=
|
|
289
|
+class PhidgetChannelConfWidget : public BasicDeviceConfigurationWidget
|
|
290
|
+{
|
|
291
|
+ Q_OBJECT
|
|
292
|
+ public:
|
|
293
|
+ Q_INVOKABLE PhidgetChannelConfWidget(DeviceTreeModel *model,
|
|
294
|
+ const QModelIndex &index);
|
|
295
|
+ public slots:
|
|
296
|
+ void changeSelectedChannel(int index);
|
|
297
|
+ void updateSerialNumber(const QString &value);
|
|
298
|
+ void updateChannel(const QString &value);
|
|
299
|
+ void updateColumnName(const QString &value);
|
|
300
|
+ void updateChannelType(int value);
|
|
301
|
+ void updateTCType(int value);
|
|
302
|
+ void updateRTDType(int value);
|
|
303
|
+ void updateRTDWiring(int value);
|
|
304
|
+ private:
|
|
305
|
+ PhidgetChannelSelector *channelSelector;
|
|
306
|
+ QLineEdit *serialNumber;
|
|
307
|
+ QLineEdit *channel;
|
|
308
|
+ QComboBox *subtype;
|
|
309
|
+ QStackedLayout *subtypeLayout;
|
|
310
|
+ QComboBox *tctype;
|
|
311
|
+ QComboBox *rtdtype;
|
|
312
|
+ QComboBox *rtdwiring;
|
|
313
|
+};
|
|
314
|
+
|
|
315
|
+@ The constructor is responsible for setting up the interface.
|
|
316
|
+
|
|
317
|
+@<Phidget implementation@>=
|
|
318
|
+PhidgetChannelConfWidget::PhidgetChannelConfWidget(DeviceTreeModel *model,
|
|
319
|
+ const QModelIndex &index)
|
|
320
|
+ : BasicDeviceConfigurationWidget(model, index),
|
|
321
|
+ channelSelector(new PhidgetChannelSelector),
|
|
322
|
+ serialNumber(new QLineEdit),
|
|
323
|
+ channel(new QLineEdit),
|
|
324
|
+ subtype(new QComboBox),
|
|
325
|
+ subtypeLayout(new QStackedLayout),
|
|
326
|
+ tctype(new QComboBox),
|
|
327
|
+ rtdtype(new QComboBox),
|
|
328
|
+ rtdwiring(new QComboBox)
|
|
329
|
+{
|
|
330
|
+ QVBoxLayout *outerLayout = new QVBoxLayout;
|
|
331
|
+ QFormLayout *layout = new QFormLayout;
|
|
332
|
+ QLineEdit *columnName = new QLineEdit;
|
|
333
|
+ subtype->addItem(tr("IC"), QVariant(1));
|
|
334
|
+ subtype->addItem(tr("RTD"), QVariant(32));
|
|
335
|
+ subtype->addItem(tr("Thermocouple"), QVariant(33));
|
|
336
|
+ layout->addRow(tr("Channels:"), channelSelector);
|
|
337
|
+ layout->addRow(tr("Column Name:"), columnName);
|
|
338
|
+ layout->addRow(tr("Serial Number:"), serialNumber);
|
|
339
|
+ layout->addRow(tr("Channel Number:"), channel);
|
|
340
|
+ layout->addRow(tr("Channel Type:"), subtype);
|
|
341
|
+ serialNumber->setEnabled(false);
|
|
342
|
+ channel->setEnabled(false);
|
|
343
|
+ subtype->setEnabled(false);
|
|
344
|
+ outerLayout->addLayout(layout);
|
|
345
|
+ QWidget *icconfiguration = new QWidget;
|
|
346
|
+ QWidget *rtdconfiguration = new QWidget;
|
|
347
|
+ QFormLayout *rtdconfigurationLayout = new QFormLayout;
|
|
348
|
+ rtdtype->addItem(tr("PT100 with .00385 curve"), QVariant(1));
|
|
349
|
+ rtdtype->addItem(tr("PT1000 with .00385 curve"), QVariant(2));
|
|
350
|
+ rtdtype->addItem(tr("PT100 with .00392 curve"), QVariant(3));
|
|
351
|
+ rtdtype->addItem(tr("PT1000 with .00392 curve"), QVariant(4));
|
|
352
|
+ rtdconfigurationLayout->addRow(tr("RTD type:"), rtdtype);
|
|
353
|
+ rtdwiring->addItem(tr("2 wire"), QVariant(1));
|
|
354
|
+ rtdwiring->addItem(tr("3 wire"), QVariant(2));
|
|
355
|
+ rtdwiring->addItem(tr("4 wire"), QVariant(3));
|
|
356
|
+ rtdconfigurationLayout->addRow(tr("RTD wiring:"), rtdwiring);
|
|
357
|
+ rtdconfiguration->setLayout(rtdconfigurationLayout);
|
|
358
|
+ QWidget *tcconfiguration = new QWidget;
|
|
359
|
+ QFormLayout *tcconfigurationLayout = new QFormLayout;
|
|
360
|
+ tctype->addItem(tr("Type J"), QVariant(1));
|
|
361
|
+ tctype->addItem(tr("Type K"), QVariant(2));
|
|
362
|
+ tctype->addItem(tr("Type E"), QVariant(3));
|
|
363
|
+ tctype->addItem(tr("Type T"), QVariant(4));
|
|
364
|
+ tcconfigurationLayout->addRow(tr("Thermocouple type:"), tctype);
|
|
365
|
+ tcconfiguration->setLayout(tcconfigurationLayout);
|
|
366
|
+ subtypeLayout->addWidget(icconfiguration);
|
|
367
|
+ subtypeLayout->addWidget(rtdconfiguration);
|
|
368
|
+ subtypeLayout->addWidget(tcconfiguration);
|
|
369
|
+
|
|
370
|
+ @<Get device configuration data for current node@>@;
|
|
371
|
+ for(int i = 0; i < configData.size(); i++)
|
|
372
|
+ {
|
|
373
|
+ node = configData.at(i).toElement();
|
|
374
|
+ if(node.attribute("name") == "serialnumber")
|
|
375
|
+ {
|
|
376
|
+ serialNumber->setText(node.attribute("value"));
|
|
377
|
+ }
|
|
378
|
+ else if(node.attribute("name") == "channel")
|
|
379
|
+ {
|
|
380
|
+ channel->setText(node.attribute("value"));
|
|
381
|
+ }
|
|
382
|
+ else if(node.attribute("name") == "columnname")
|
|
383
|
+ {
|
|
384
|
+ columnName->setText(node.attribute("value"));
|
|
385
|
+ }
|
|
386
|
+ else if(node.attribute("name") == "channeltype")
|
|
387
|
+ {
|
|
388
|
+ subtype->setCurrentIndex(subtype->
|
|
389
|
+ findData(QVariant(node.attribute("value").toInt())));
|
|
390
|
+ subtypeLayout->setCurrentIndex(subtype->currentIndex());
|
|
391
|
+ }
|
|
392
|
+ else if(node.attribute("name") == "tctype")
|
|
393
|
+ {
|
|
394
|
+ tctype->setCurrentIndex(tctype->
|
|
395
|
+ findData(QVariant(node.attribute("value").toInt())));
|
|
396
|
+ }
|
|
397
|
+ else if(node.attribute("name") == "rtdtype")
|
|
398
|
+ {
|
|
399
|
+ rtdtype->setCurrentIndex(rtdtype->
|
|
400
|
+ findData(QVariant(node.attribute("value").toInt())));
|
|
401
|
+ }
|
|
402
|
+ else if(node.attribute("name") == "rtdwiring")
|
|
403
|
+ {
|
|
404
|
+ rtdwiring->setCurrentIndex(rtdwiring->
|
|
405
|
+ findData(QVariant(node.attribute("value").toInt())));
|
|
406
|
+ }
|
|
407
|
+ }
|
|
408
|
+ outerLayout->addLayout(subtypeLayout);
|
|
409
|
+ setLayout(outerLayout);
|
|
410
|
+ connect(channelSelector, SIGNAL(currentIndexChanged(int)),
|
|
411
|
+ this, SLOT(changeSelectedChannel(int)));
|
|
412
|
+ connect(subtype, SIGNAL(currentIndexChanged(int)),
|
|
413
|
+ subtypeLayout, SLOT(setCurrentIndex(int)));
|
|
414
|
+ connect(serialNumber, SIGNAL(textChanged(QString)),
|
|
415
|
+ this, SLOT(updateSerialNumber(QString)));
|
|
416
|
+ connect(channel, SIGNAL(textChanged(QString)),
|
|
417
|
+ this, SLOT(updateChannel(QString)));
|
|
418
|
+ connect(columnName, SIGNAL(textEdited(QString)),
|
|
419
|
+ this, SLOT(updateColumnName(QString)));
|
|
420
|
+ connect(subtype, SIGNAL(currentIndexChanged(int)),
|
|
421
|
+ this, SLOT(updateChannelType(int)));
|
|
422
|
+ connect(tctype, SIGNAL(currentIndexChanged(int)),
|
|
423
|
+ this, SLOT(updateTCType(int)));
|
|
424
|
+ connect(rtdtype, SIGNAL(currentIndexChanged(int)),
|
|
425
|
+ this, SLOT(updateRTDType(int)));
|
|
426
|
+ connect(rtdwiring, SIGNAL(currentIndexChanged(int)),
|
|
427
|
+ this, SLOT(updateRTDWiring(int)));
|
|
428
|
+}
|
|
429
|
+
|
|
430
|
+@ The combo box provides a convenient way to populate required configuration
|
|
431
|
+fields with values that are not immediately obvious.
|
|
432
|
+
|
|
433
|
+@<Phidget implementation@>=
|
|
434
|
+void PhidgetChannelConfWidget::changeSelectedChannel(int index)
|
|
435
|
+{
|
|
436
|
+ QMap<QString,QVariant> data = channelSelector->itemData(index).toMap();
|
|
437
|
+ serialNumber->setText(data.value("serialNumber").toString());
|
|
438
|
+ channel->setText(data.value("channel").toString());
|
|
439
|
+ subtype->setCurrentIndex(subtype->
|
|
440
|
+ findData(QVariant(data.value("subclass").toString().toInt())));
|
|
441
|
+}
|
|
442
|
+
|
|
443
|
+@ Channel configuration settings are persisted as they are updated.
|
|
444
|
+
|
|
445
|
+@<Phidget implementation@>=
|
|
446
|
+void PhidgetChannelConfWidget::updateSerialNumber(const QString &value)
|
|
447
|
+{
|
|
448
|
+ updateAttribute("serialnumber", value);
|
|
449
|
+}
|
|
450
|
+
|
|
451
|
+void PhidgetChannelConfWidget::updateChannel(const QString &value)
|
|
452
|
+{
|
|
453
|
+ updateAttribute("channel", value);
|
|
454
|
+}
|
|
455
|
+
|
|
456
|
+void PhidgetChannelConfWidget::updateColumnName(const QString &value)
|
|
457
|
+{
|
|
458
|
+ updateAttribute("columnname", value);
|
|
459
|
+}
|
|
460
|
+
|
|
461
|
+void PhidgetChannelConfWidget::updateChannelType(int value)
|
|
462
|
+{
|
|
463
|
+ updateAttribute("channeltype", subtype->itemData(value).toString());
|
|
464
|
+}
|
|
465
|
+
|
|
466
|
+void PhidgetChannelConfWidget::updateTCType(int value)
|
|
467
|
+{
|
|
468
|
+ updateAttribute("tctype", tctype->itemData(value).toString());
|
|
469
|
+}
|
|
470
|
+
|
|
471
|
+void PhidgetChannelConfWidget::updateRTDType(int value)
|
|
472
|
+{
|
|
473
|
+ updateAttribute("rtdtype", rtdtype->itemData(value).toString());
|
|
474
|
+}
|
|
475
|
+
|
|
476
|
+void PhidgetChannelConfWidget::updateRTDWiring(int value)
|
|
477
|
+{
|
|
478
|
+ updateAttribute("rtdwiring", rtdwiring->itemData(value).toString());
|
|
479
|
+}
|
|
480
|
+
|
|
481
|
+@ Class implementations are currently folded into typica.cpp.
|
|
482
|
+
|
|
483
|
+@<Class implementations@>=
|
|
484
|
+@<Phidget implementation@>@;
|