Browse Source

DATAQ SDK device configuration widget. Still requires channel configuration widget.

Neal Wilson 11 years ago
parent
commit
6ced403dde
3 changed files with 162 additions and 13 deletions
  1. 153
    2
      src/dataqsdk.w
  2. 9
    8
      src/typica.w
  3. 0
    3
      src/units.w

+ 153
- 2
src/dataqsdk.w View File

@@ -631,7 +631,8 @@ void setDataqSdkDeviceProperties(QScriptValue value, QScriptEngine *engine)
631 631
 	value.setProperty("newChannel", engine->newFunction(DataqSdkDevice_newChannel));
632 632
 }
633 633
 
634
-@ The |newChannel()| wrapper requires two arguments.
634
+@ The |newChannel()| wrapper requires one argument to specify the measurement
635
+unit that will eventually be produced from that channel.
635 636
 
636 637
 @<Functions for scripting@>=
637 638
 QScriptValue DataqSdkDevice_newChannel(QScriptContext *context, QScriptEngine *engine)
@@ -644,4 +645,154 @@ QScriptValue DataqSdkDevice_newChannel(QScriptContext *context, QScriptEngine *e
644 645
 		setChannelProperties(object, engine);
645 646
 	}
646 647
 	return object;
647
-}
648
+}
649
+
650
+@ In order to configure supported devices within Typica, a set of configuration
651
+controls is required. First there is the base device configuration widget.
652
+
653
+@<Class declarations@>=
654
+class DataqSdkDeviceConfWidget : public BasicDeviceConfigurationWidget
655
+{
656
+	Q_OBJECT
657
+	public:
658
+		Q_INVOKABLE DataqSdkDeviceConfWidget(DeviceTreeModel *model,
659
+		                                     const QModelIndex &index);
660
+	private slots:
661
+		void updateAutoSelect(bool automatic);
662
+		void updateDeviceNumber(int deviceNumber);
663
+		void updatePort(QString portId);
664
+		void addChannel();
665
+	private:
666
+		QStackedWidget *deviceIdStack;
667
+};
668
+
669
+@ The constructor sets up the interface for updating device configuration
670
+settings.
671
+
672
+@<DataqSdkDeviceConfWidget implementation@>=
673
+DataqSdkDeviceConfWidget::DataqSdkDeviceConfWidget(DeviceTreeModel *model,
674
+                                                   const QModelIndex &index)
675
+	: BasicDeviceConfigurationWidget(model, index),
676
+	deviceIdStack(new QStackedWidget)
677
+{
678
+	QVBoxLayout *layout = new QVBoxLayout;
679
+	QCheckBox *autoDetect = new QCheckBox("Automatically select device");
680
+	layout->addWidget(autoDetect);
681
+	QWidget *autoLayerWidget = new QWidget;
682
+	QHBoxLayout *autoLayerLayout = new QHBoxLayout;
683
+	QLabel *autoLabel = new QLabel(tr("Device number"));
684
+	QSpinBox *autoNumber = new QSpinBox;
685
+	autoNumber->setMinimum(1);
686
+	autoNumber->setMaximum(99);
687
+	autoLayerLayout->addWidget(autoLabel);
688
+	autoLayerLayout->addWidget(autoNumber);
689
+	autoLayerWidget->setLayout(autoLayerLayout);
690
+	QWidget *fixedLayerWidget = new QWidget;
691
+	QHBoxLayout *fixedLayerLayout = new QHBoxLayout;
692
+	QLabel *fixedLabel = new QLabel(tr("Device port"));
693
+	QComboBox *portSelection = new QComboBox;
694
+	portSelection->setEditable(true);
695
+	portSelection->addItems(DataqSdkDevice::detectHardware());
696
+	fixedLayerLayout->addWidget(fixedLabel);
697
+	fixedLayerLayout->addWidget(portSelection);
698
+	fixedLayerWidget->setLayout(fixedLayerLayout);
699
+	deviceIdStack->addWidget(autoLayerWidget);
700
+	deviceIdStack->addWidget(fixedLayerWidget);
701
+	layout->addWidget(deviceIdStack);
702
+	QPushButton *addChannelButton = new QPushButton(tr("Add Channel"));
703
+	layout->addWidget(addChannelButton);
704
+	@<Get device configuration data for current node@>@;
705
+	for(int i = 0; i < configData.size(); i++)
706
+	{
707
+		node = configData.at(i).toElement();
708
+		if(node.attribute("name") == "autoSelect")
709
+		{
710
+			autoDetect->setChecked(node.attribute("value") == "true" ? true : false);
711
+		}
712
+		else if(node.attribute("name") == "deviceNumber")
713
+		{
714
+			autoNumber->setValue(node.attribute("value").toInt());
715
+		}
716
+		else if(node.attribute("name") == "port")
717
+		{
718
+			int index = portSelection->findText(node.attribute("value"));
719
+			if(index > -1)
720
+			{
721
+				portSelection->setCurrentIndex(index);
722
+			}
723
+			else
724
+			{
725
+				portSelection->setEditText(node.attribute("value"));
726
+			}
727
+		}
728
+	}
729
+	updateAutoSelect(autoDetect->isChecked());
730
+	updateDeviceNumber(autoNumber->value());
731
+	updatePort(portSelection->currentText());
732
+	connect(autoDetect, SIGNAL(toggled(bool)), this, SLOT(updateAutoSelect(bool)));
733
+	connect(autoNumber, SIGNAL(valueChanged(int)), this, SLOT(updateDeviceNumber(int)));
734
+	connect(portSelection, SIGNAL(currentIndexChanged(QString)), this, SLOT(updatePort(QString)));
735
+	connect(addChannelButton, SIGNAL(clicked()), this, SLOT(addChannel()));
736
+	setLayout(layout);
737
+}
738
+
739
+@ In addition to setting a value in the device configuration, the choice to
740
+automatically select devices also requires changing which controls in the
741
+configuration widget are presently available. It is recommended that automatic
742
+device selection is only used in cases where there is a single device supported
743
+by the DATAQ SDK present and it will always be the first detected device
744
+regardless of the current virtual COM port number. In cases where multiple
745
+devices must be connected, it is recommended to always plug devices into the
746
+same port and specify the port for each device explicitly.
747
+
748
+@<DataqSdkDeviceConfWidget implementation@>=
749
+void DataqSdkDeviceConfWidget::updateAutoSelect(bool automatic)
750
+{
751
+	if(automatic)
752
+	{
753
+		updateAttribute("autoSelect", "true");
754
+		deviceIdStack->setCurrentIndex(0);
755
+	}
756
+	else
757
+	{
758
+		updateAttribute("autoSelect", "false");
759
+		deviceIdStack->setCurrentIndex(1);
760
+	}
761
+}
762
+
763
+@ Other update methods only need to set a new current value.
764
+
765
+@<DataqSdkDeviceConfWidget implementation@>=
766
+void DataqSdkDeviceConfWidget::updateDeviceNumber(int deviceNumber)
767
+{
768
+	updateAttribute("deviceNumber", QString("%1").arg(deviceNumber));
769
+}
770
+
771
+void DataqSdkDeviceConfWidget::updatePort(QString portId)
772
+{
773
+	updateAttribute("port", portId);
774
+}
775
+
776
+@ The Add Channel button creates a new configuration node.
777
+
778
+@<DataqSdkDeviceConfWidget implementation@>=
779
+void DataqSdkDeviceConfWidget::addChannel()
780
+{
781
+	insertChildNode(tr("Channel"), "dataqsdkchannel");
782
+}
783
+
784
+@ These configuration widgets are registered with the configuration system.
785
+
786
+@<Register device configuration widgets@>=
787
+app.registerDeviceConfigurationWidget("dataqsdk", DataqSdkDeviceConfWidget::staticMetaObject);
788
+
789
+@ A |NodeInserter| is also added to provide access to
790
+|DataqSdkDeviceConfWidget|, but only on Windows.
791
+
792
+@<Register top level device configuration nodes@>=
793
+#ifdef Q_OS_WIN32
794
+inserter = new NodeInserter(tr("DATAQ SDK Device"), tr("DATAQ Device"),
795
+                            "dataqsdk", NULL);
796
+topLevelNodeInserters.append(inserter);
797
+#endif
798
+

+ 9
- 8
src/typica.w View File

@@ -838,6 +838,7 @@ generated file empty.
838 838
 @<RateOfChange implementation@>@/
839 839
 @<SettingsWindow implementation@>@/
840 840
 @<GraphSettingsWidget implementation@>@/
841
+@<DataqSdkDeviceConfWidget implementation@>@/
841 842
 
842 843
 @ A few headers are required for various parts of \pn{}. These allow the use of
843 844
 various Qt modules.
@@ -6402,8 +6403,6 @@ QScriptValue DAQ_newChannel(QScriptContext *context, QScriptEngine *engine)
6402 6403
 	return object;
6403 6404
 }
6404 6405
 
6405
-@i dataqsdk.w
6406
-
6407 6406
 @ Sometimes it can be useful to test other parts of the program (for example,
6408 6407
 when developing new scripts) when the DAQ hardware is not available. In these
6409 6408
 cases, it is possible to temporarily use the |FakeDAQ| class. This class mimics
@@ -15119,7 +15118,7 @@ required child nodes for hardware and configurable elements of the logging
15119 15118
 window that may vary from one machine to the next.
15120 15119
 
15121 15120
 All of the configuration widgets follow a similar pattern. One important detail
15122
-to note is that these configuration widgets are instantiated through Qt's
15121
+to note is that these configuration widgets are instantiated through Qt'@q'@>s
15123 15122
 meta-object system. All of these constructors take a |DeviceTreeModel *| and a
15124 15123
 |QModelIndex &| as arguments and they are marked as |Q_INVOKABLE|.
15125 15124
 
@@ -15243,7 +15242,7 @@ app.registerDeviceConfigurationWidget("roaster", RoasterConfWidget::staticMetaOb
15243 15242
 \noindent The primary concern in supporting hardware that communicates through
15244 15243
 NI-DAQmx Base is in configurations using a single NI USB 9211 (for NI-DAQmx
15245 15244
 Base 2.x) or NI USB 9211A (for NI-DAQmx Base 3.x), but if it is reasonable to
15246
-do so I'd like to later add support for multiple device configurations and
15245
+do so I'@q'@>d like to later add support for multiple device configurations and
15247 15246
 limited support for other devices including the ability to use devices with
15248 15247
 voltage inputs for non-temperature measurement data. The top priority, however,
15249 15248
 is in continuing to support hardware that people are already using with Typica.
@@ -15266,7 +15265,7 @@ class NiDaqMxBaseDriverConfWidget : public BasicDeviceConfigurationWidget
15266 15265
 		                                        const QModelIndex &index);
15267 15266
 };
15268 15267
 
15269
-@ There is very little to configure here so there isn't much for the
15268
+@ There is very little to configure here so there isn'@q'@>t much for the
15270 15269
 constructor to do. We do need to keep a reference to the node we are
15271 15270
 configuring so that child nodes can later be added. At present, no real
15272 15271
 configuration data other than the existence of the node is required so
@@ -15380,7 +15379,7 @@ specific, all of the options can be easily enumerated to match markings on the
15380 15379
 device. Next is the thermocouple type. Many options are supported, but I would
15381 15380
 like to ensure that the most commonly used choices are listed first. The other
15382 15381
 piece of information that DAQmx or DAQmx Base require is the measurement unit.
15383
-As all of Typica's internal operations are in Fahrenheit there is no need to
15382
+As all of Typica'@q'@>s internal operations are in Fahrenheit there is no need to
15384 15383
 make this configurable so long as everything else that can display temperature
15385 15384
 measurements can perform the appropriate conversions.
15386 15385
 
@@ -16473,7 +16472,7 @@ void ModbusRtuDeviceTPvConfWidget::updateAddress(int newAddress)
16473 16472
 
16474 16473
 @ Set values are slightly more complicated as we may want either a fixed range
16475 16474
 or the ability to query the device for its current allowed range, but nothing
16476
-is here that hasn't been seen elsewhere.
16475
+is here that hasn'@q'@>t been seen elsewhere.
16477 16476
 
16478 16477
 @<Class declarations@>=
16479 16478
 class ModbusRtuDeviceTSvConfWidget : public BasicDeviceConfigurationWidget
@@ -18294,7 +18293,7 @@ TranslationConfWidget::TranslationConfWidget(DeviceTreeModel *model, const QMode
18294 18293
 }
18295 18294
 
18296 18295
 @ To update the temperature at which to match we save both the values of the
18297
-two widgets which control this and the value in Fahrenheit so we don't need to
18296
+two widgets which control this and the value in Fahrenheit so we don'@q@'@>t need to
18298 18297
 run unit conversions during view initialization.
18299 18298
 
18300 18299
 @<TranslationConfWidget implementation@>=
@@ -18324,6 +18323,8 @@ app.registerDeviceConfigurationWidget("translation", TranslationConfWidget::stat
18324 18323
 
18325 18324
 @i rate.w
18326 18325
 
18326
+@i dataqsdk.w
18327
+
18327 18328
 @** Local changes.
18328 18329
 
18329 18330
 \noindent This is the end of \pn{} as distributed by its author. It is expected

+ 0
- 3
src/units.w View File

@@ -35,9 +35,6 @@ class Units: public QObject
35 35
 
36 36
 @(units.cpp@>=
37 37
 #include "units.h"
38
-#ifndef Q_OS_WIN32
39
-#include "moc_units.cpp"
40
-#endif
41 38
 
42 39
 @ The |isTemperatureUnit()| method may seem counter-intuitive while the enum
43 40
 only contains represenations of temperature measurements, but there are plans

Loading…
Cancel
Save