| 
				
			 | 
			
			
				
				@@ -0,0 +1,252 @@ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				
				+@** Unsupported Serial Port Devices 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				3
			 | 
			
			
				
				+\noindent There are many data acquisition products which connect over or 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				
				+present themselves as a serial port and it has become relatively easy for 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				
				+hardware tinkerers to develop new devices matching this description. In this 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				
				+space there is no apparent consideration given to interoperability and with 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				
				+some devices the communications protocol even changes significantly between 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				
				+firmware revisions. There are far too many devices like this to support 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				
				+everything. At the same time, there are people who have these devices, are 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				
				+capable of programming the basic communications handling, but have difficulty 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				
				+with all of the supporting code that must be written to properly integrate with 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				
				+the rest of \pn. By providing an in-program environment that handles much of 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				13
			 | 
			
			
				
				+the boilerplate and allowing people to write scripts implementing these 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				
				+protocols without the need to modify core \pn code or recompile the program, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				
				+these people may find it easier to make their existing hardware work. Such 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				
				+scripts can also serve as prototypes for later integration. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				
				+It is common among these devices that port settings aside from the port name 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				
				+are fixed, but there may be other characteristics that are configurable on a 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				
				+per-device or per-channel basis. As it is impossible to know what these 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				
				+details might be, the configuration widgets for these devices and channels 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				
				+simply provide space to provide key value pairs which are provided to the host 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				
				+environment. Common configurations will have a device node representing a 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				
				+single logical device, usually a single physical device but this is not in any 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				
				+way enforced, and one child node per channel, the details of which are made 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				
				+available to the device script and are also used to integrate with the logging 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				
				+view. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				
				+The use of the word serial should be considered legacy of the initial 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				
				+conception of this feature. The implementation here is sufficiently generic 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				
				+that there is no reason this could not be extended to cover devices that are 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				
				+interfaced through USB HID, Bluetooth, COM, output piped from an external 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				
				+console program, devices interfaced through arbitrary libraries, or any other 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+class of device not directly supported in the core code should there be an 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				
				+interest in these. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+@<Class declarations@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				
				+class UnsupportedSerialDeviceConfWidget : public BasicDeviceConfigurationWidget 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				
				+	Q_OBJECT 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				
				+	public: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				
				+		Q_INVOKABLE UnsupportedSerialDeviceConfWidget(DeviceTreeModel *model, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				
				+		                                              const QModelIndex &index); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+	private slots: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				
				+		void updateConfiguration(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				
				+		void saveScript(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				
				+		void addChannel(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				
				+	private: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				
				+		SaltModel *deviceSettingsModel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				
				+		QTextEdit *scriptEditor; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+@ The device configuration widget consists of two tabs. One tab provides a 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+button for adding channels and an area for entering device specific 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+configuration details. The other provides an area for entering the device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+script. This may be extended later to provide better editing, testing, and 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+debugging support, but the initial concern is simply having a working feature. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+UnsupportedSerialDeviceConfWidget::UnsupportedSerialDeviceConfWidget(DeviceTreeModel *model, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+                                                                     const QModelIndex &index) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+	: BasicDeviceConfigurationWidget(model, index), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+	deviceSettingsModel(new SaltModel(2)), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+	scriptEditor(new QTextEdit) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				
				+	QVBoxLayout *dummyLayout = new QVBoxLayout; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				
				+	QTabWidget *central = new QTabWidget; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				
				+	QWidget *deviceConfigurationWidget = new QWidget; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+	QVBoxLayout *deviceConfigurationLayout = new QVBoxLayout; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+	QPushButton *addChannelButton = new QPushButton(tr("Add Channel")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+	deviceConfigurationLayout->addWidget(addChannelButton); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+	connect(addChannelButton, SIGNAL(clicked()), this, SLOT(addChannel())); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+	QLabel *deviceSettingsLabel = new QLabel(tr("Device Settings:")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+	deviceConfigurationLayout->addWidget(deviceSettingsLabel); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+	QTableView *deviceSettingsView = new QTableView; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+	deviceSettingsModel->setHeaderData(0, Qt::Horizontal, tr("Key")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				
				+	deviceSettingsModel->setHeaderData(1, Qt::Horizontal, tr("Value")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				
				+	deviceSettingsView->setModel(deviceSettingsModel); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				
				+	deviceConfigurationLayout->addWidget(deviceSettingsView); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+	deviceConfigurationWidget->setLayout(deviceConfigurationLayout); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+	central->addTab(deviceConfigurationWidget, tr("Configuration")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+	central->addTab(scriptEditor, tr("Script")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+	dummyLayout->addWidget(central); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+	@<Get device configuration data for current node@>@; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				
				+	for(int i = 0; i < configData.size(); i++) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				
				+	{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				
				+		node = configData.at(i).toElement(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+		if(node.attribute("name") == "keys" || node.attribute("name") == "values") 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+		{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+			int column = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+			if(node.attribute("name") == "values") 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+			{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+				column = 1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+			QString data = node.attribute("value"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				
				+			if(data.length() > 3) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				
				+			{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+				data.chop(2); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+				data = data.remove(0, 2); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+			QStringList keyList = data.split(","); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+			for(int j = 0; j < keyList.size(); j++) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+			{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+				deviceSettingsModel->setData(deviceSettingsModel->index(j, column), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+				                             QVariant(keyList.at(j)), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+				                             Qt::DisplayRole); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+			} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				
				+		else if(node.attribute("name") == "script") 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				
				+		{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				
				+			scriptEditor->setPlainText(node.attribute("value")); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				114
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+	connect(deviceSettingsModel, SIGNAL(dataChanged()), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				
				+	        this, SLOT(updateConfiguration())); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				119
			 | 
			
			
				
				+	connect(scriptEditor, SIGNAL(textChanged()), this, SLOT(saveScript())); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				
				+	setLayout(dummyLayout); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				121
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				122
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				123
			 | 
			
			
				
				+@ Device configuration data is entered through an ordinary |QTableView| with a 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				124
			 | 
			
			
				
				+|SaltModel| backing. The original use case for that model does not apply here, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				125
			 | 
			
			
				
				+but that model does ensure that additional blank rows are added as needed so 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				126
			 | 
			
			
				
				+that arbitrarily many key value pairs can be entered. When data changes in the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				127
			 | 
			
			
				
				+model we write the full content of the model out. Note that commas may not be 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				128
			 | 
			
			
				
				+used in keys or values. For keys in which lists make sense, a different 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				129
			 | 
			
			
				
				+delimiter must be chosen. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				130
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				131
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				
				+void UnsupportedSerialDeviceConfWidget::updateConfiguration() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				133
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				134
			 | 
			
			
				
				+	updateAttribute("keys", deviceSettingsModel->arrayLiteral(0, Qt::DisplayRole)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				
				+	updateAttribute("values", deviceSettingsModel->arrayLiteral(0, Qt::DisplayRole)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				137
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				138
			 | 
			
			
				
				+@ Every time the script text is changed, the new version of the script is 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+saved. My expectation is that scripts will either be small or that they will be 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+pasted in from outside of \pn so that this decision will not cause usability 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+issues, however if I am wrong about this there may be a need to handle this 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				142
			 | 
			
			
				
				+more intelligently. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				143
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				144
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				145
			 | 
			
			
				
				+void UnsupportedSerialDeviceConfWidget::saveScript() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				146
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+	updateAttribute("script", scriptEditor->toPlainText()); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+@ Typica requires channel nodes to simplify integration with other existing 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+device code. Providing a new node type allows arbitrary attributes to be 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+configured on a per-channel basis without resorting to strange conventions in 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+the device configuration. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+void UnsupportedSerialDeviceConfWidget::addChannel() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				158
			 | 
			
			
				
				+	insertChildNode(tr("Channel"), "unsupporteddevicechannel"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				160
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				161
			 | 
			
			
				
				+@ Channel configuration for unsupported devices is like unsupported device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+configuration in that arbitrary key value pairs may be entered for use by the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+device script. Conventions common to all other channel node types are also 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+present here. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				165
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				166
			 | 
			
			
				
				+@<Class declarations@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				167
			 | 
			
			
				
				+class UnsupportedDeviceChannelConfWidget : public BasicDeviceConfigurationWidget 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				168
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				169
			 | 
			
			
				
				+	Q_OBJECT 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				170
			 | 
			
			
				
				+	public: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				171
			 | 
			
			
				
				+		Q_INVOKABLE UnsupportedDeviceChannelConfWidget(DeviceTreeModel *model, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				172
			 | 
			
			
				
				+		                                               const QModelIndex &index); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				173
			 | 
			
			
				
				+	private slots: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				174
			 | 
			
			
				
				+		void updateColumnName(const QString &value); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				175
			 | 
			
			
				
				+		void updateHidden(bool hidden); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				176
			 | 
			
			
				
				+		void updateConfiguration(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				177
			 | 
			
			
				
				+	private: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				178
			 | 
			
			
				
				+		SaltModel *channelSettingsModel; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				179
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				180
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				181
			 | 
			
			
				
				+@ The constructor is typical for for channel node configuraion widgets. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				182
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				184
			 | 
			
			
				
				+UnsupportedDeviceChannelConfWidget::UnsupportedDeviceChannelConfWidget(DeviceTreeModel *model, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				185
			 | 
			
			
				
				+                                                                       const QModelIndex &index) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				186
			 | 
			
			
				
				+	: BasicDeviceConfigurationWidget(model, index), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				187
			 | 
			
			
				
				+	channelSettingsModel(new SaltModel(2)) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				188
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+	QFormLayout *layout = new QFormLayout; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				190
			 | 
			
			
				
				+	QLineEdit *columnName = new QLineEdit; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+	layout->addRow(tr("Column Name:"), columnName); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+	QCheckBox *hideSeries = new QCheckBox("Hide this channel"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				193
			 | 
			
			
				
				+	layout->addRow(hideSeries); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				
				+	QTableView *channelSettings = new QTableView; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				195
			 | 
			
			
				
				+	channelSettingsModel->setHeaderData(0, Qt::Horizontal, "Key"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				196
			 | 
			
			
				
				+	channelSettingsModel->setHeaderData(1, Qt::Horizontal, "Value"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				197
			 | 
			
			
				
				+	channelSettings->setModel(channelSettingsModel); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+	layout->addRow(channelSettings); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+	setLayout(layout); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				200
			 | 
			
			
				
				+	@<Get device configuration data for current node@>@; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+	for(int i = 0; i < configData.size(); i++) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+	{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				203
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				204
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				205
			 | 
			
			
				
				+	connect(columnName, SIGNAL(textEdited(QString)), this, SLOT(updateColumnName(QString))); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+	connect(hideSeries, SIGNAL(toggled(bool)), this, SLOT(updateHidden(bool))); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+	connect(channelSettingsModel, SIGNAL(dataChanged()), this, SLOT(updateConfiguration())); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+@ Arbitrary channel configuration data is handled in the same way as device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+level settings while the column name and hidden status is handled in the same 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+way as they are in other channel nodes. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				213
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				214
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				215
			 | 
			
			
				
				+void UnsupportedDeviceChannelConfWidget::updateColumnName(const QString &value) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				216
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				217
			 | 
			
			
				
				+	updateAttribute("columnname", value); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				218
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				219
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				220
			 | 
			
			
				
				+void UnsupportedDeviceChannelConfWidget::updateHidden(bool hidden) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				221
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				222
			 | 
			
			
				
				+	updateAttribute("hidden", hidden ? "true" : "false"); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				223
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				224
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				225
			 | 
			
			
				
				+void UnsupportedDeviceChannelConfWidget::updateConfiguration() 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				226
			 | 
			
			
				
				+{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				227
			 | 
			
			
				
				+	updateAttribute("keys", channelSettingsModel->arrayLiteral(0, Qt::DisplayRole)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				228
			 | 
			
			
				
				+	updateAttribute("values", channelSettingsModel->arrayLiteral(0, Qt::DisplayRole)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				229
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				230
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				231
			 | 
			
			
				
				+@ The configuration widgets need to be registered so they can be instantiated 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				232
			 | 
			
			
				
				+as appropriate. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				233
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				234
			 | 
			
			
				
				+@<Register device configuration widgets@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				235
			 | 
			
			
				
				+app.registerDeviceConfigurationWidget("unsupporteddevicechannel", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				236
			 | 
			
			
				
				+	UnsupportedDeviceChannelConfWidget::staticMetaObject); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				237
			 | 
			
			
				
				+app.registerDeviceConfigurationWidget("unsupporteddevice", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				238
			 | 
			
			
				
				+	UnsupportedSerialDeviceConfWidget::staticMetaObject); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				239
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				240
			 | 
			
			
				
				+@ A |NodeInserter| for the device node is also provided. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				241
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				242
			 | 
			
			
				
				+@<Register top level device configuration nodes@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				243
			 | 
			
			
				
				+inserter = new NodeInserter(tr("Other Device"), tr("Other Device"), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				244
			 | 
			
			
				
				+	"unsupporteddevice", NULL); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				245
			 | 
			
			
				
				+topLevelNodeInserters.append(inserter); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				246
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				247
			 | 
			
			
				
				+@ At present, implementations are not broken out to a separate file. This 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				248
			 | 
			
			
				
				+should be changed at some point. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				249
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				250
			 | 
			
			
				
				+@<Class implementations@>= 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				251
			 | 
			
			
				
				+@<UnsupportedSerialDeviceConfWidget implementation@> 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				252
			 | 
			
			
				
				+ 
			 |