import copy from PyQt4 import QtGui, QtCore from nupic_studio.htm.node_sensor import DataSourceType, PredictionsMethod from nupic_studio.ui import Global from nupic_studio.ui.node_sensor_encoding_form import EncodingForm class SensorForm(QtGui.QDialog): #region Constructor def __init__(self): """ Initializes a new instance of this class. """ QtGui.QDialog.__init__(self) self.initUI() #region Instance fields self.encodings = [] """Temporary list of encodings that is being edited""" self.encodingsChanged = False """Flag to indicate if encodings list was edited""" #endregion #endregion #region Methods def initUI(self): # labelSensorWidth self.labelSensorWidth = QtGui.QLabel() self.labelSensorWidth.setText("Sensor Width") self.labelSensorWidth.setAlignment(QtCore.Qt.AlignRight) # spinnerSensorWidth self.spinnerSensorWidth = QtGui.QSpinBox() self.spinnerSensorWidth.setAlignment(QtCore.Qt.AlignRight) self.spinnerSensorWidth.setToolTip("Number of output bits in the X direction for this sensor.") self.spinnerSensorWidth.setMaximum(1000) self.spinnerSensorWidth.setEnabled(not Global.simulationInitialized) # labelSensorHeight self.labelSensorHeight = QtGui.QLabel() self.labelSensorHeight.setText("Sensor Height") self.labelSensorHeight.setAlignment(QtCore.Qt.AlignRight) # spinnerSensorHeight self.spinnerSensorHeight = QtGui.QSpinBox() self.spinnerSensorHeight.setAlignment(QtCore.Qt.AlignRight) self.spinnerSensorHeight.setToolTip("Number of output bits in the Y direction for this sensor.") self.spinnerSensorHeight.setMaximum(1000) self.spinnerSensorHeight.setEnabled(not Global.simulationInitialized) # radioButtonDataSourceFile self.radioButtonDataSourceFile = QtGui.QRadioButton() self.radioButtonDataSourceFile.setText("File") self.radioButtonDataSourceFile.toggled.connect(self.__radioButtonDataSource_Click) # labelFile self.labelFile = QtGui.QLabel() self.labelFile.setText("File:") self.labelFile.setAlignment(QtCore.Qt.AlignRight) # textBoxFile self.textBoxFile = QtGui.QLineEdit() # buttonBrowseFile self.buttonBrowseFile = QtGui.QPushButton() self.buttonBrowseFile.setText("Browse...") self.buttonBrowseFile.clicked.connect(self.__buttonBrowseFile_Click) # radioButtonDataSourceDatabase self.radioButtonDataSourceDatabase = QtGui.QRadioButton() self.radioButtonDataSourceDatabase.setText("Database") self.radioButtonDataSourceDatabase.toggled.connect(self.__radioButtonDataSource_Click) # labelDatabaseConnectionString self.labelDatabaseConnectionString = QtGui.QLabel() self.labelDatabaseConnectionString.setText("Connection String:") self.labelDatabaseConnectionString.setAlignment(QtCore.Qt.AlignRight) # textBoxDatabaseConnectionString self.textBoxDatabaseConnectionString = QtGui.QLineEdit() # labelDatabaseTable self.labelDatabaseTable = QtGui.QLabel() self.labelDatabaseTable.setText("Table:") self.labelDatabaseTable.setAlignment(QtCore.Qt.AlignRight) # textBoxDatabaseTable self.textBoxDatabaseTable = QtGui.QLineEdit() # groupBoxDataSourceTypeLayout groupBoxDataSourceTypeLayout = QtGui.QGridLayout() groupBoxDataSourceTypeLayout.addWidget(self.radioButtonDataSourceFile, 0, 0) groupBoxDataSourceTypeLayout.addWidget(self.labelFile, 1, 0) groupBoxDataSourceTypeLayout.addWidget(self.textBoxFile, 1, 1) groupBoxDataSourceTypeLayout.addWidget(self.buttonBrowseFile, 2, 1) groupBoxDataSourceTypeLayout.addWidget(self.radioButtonDataSourceDatabase, 3, 0) groupBoxDataSourceTypeLayout.addWidget(self.labelDatabaseConnectionString, 4, 0) groupBoxDataSourceTypeLayout.addWidget(self.textBoxDatabaseConnectionString, 4, 1) groupBoxDataSourceTypeLayout.addWidget(self.labelDatabaseTable, 5, 0) groupBoxDataSourceTypeLayout.addWidget(self.textBoxDatabaseTable, 5, 1) # groupBoxDataSourceType self.groupBoxDataSourceType = QtGui.QGroupBox() self.groupBoxDataSourceType.setLayout(groupBoxDataSourceTypeLayout) self.groupBoxDataSourceType.setTitle("Data Source Type") self.groupBoxDataSourceType.setEnabled(not Global.simulationInitialized) # labelPredictionsMethod self.labelPredictionsMethod = QtGui.QLabel() self.labelPredictionsMethod.setText("Predictions Method:") self.labelPredictionsMethod.setAlignment(QtCore.Qt.AlignRight) # comboBoxPredictionsMethod self.comboBoxPredictionsMethod = QtGui.QComboBox() self.comboBoxPredictionsMethod.addItem(PredictionsMethod.reconstruction) self.comboBoxPredictionsMethod.addItem(PredictionsMethod.classification) self.comboBoxPredictionsMethod.setEnabled(not Global.simulationInitialized) # buttonNewEncoding self.buttonNewEncoding = QtGui.QPushButton() self.buttonNewEncoding.setText("New...") self.buttonNewEncoding.clicked.connect(self.__buttonNewEncoding_Click) self.buttonNewEncoding.setEnabled(not Global.simulationInitialized) # buttonEditEncoding self.buttonEditEncoding = QtGui.QPushButton() self.buttonEditEncoding.setText("Edit...") self.buttonEditEncoding.clicked.connect(self.__buttonEditEncoding_Click) self.buttonEditEncoding.setEnabled(not Global.simulationInitialized) # buttonDeleteEncoding self.buttonDeleteEncoding = QtGui.QPushButton() self.buttonDeleteEncoding.setText("Delete") self.buttonDeleteEncoding.clicked.connect(self.__buttonDeleteEncoding_Click) self.buttonDeleteEncoding.setEnabled(not Global.simulationInitialized) # listBoxEncodings self.listBoxEncodings = QtGui.QListWidget() self.listBoxEncodings.setEnabled(not Global.simulationInitialized) # encodingsButtonsLayout encodingsButtonsLayout = QtGui.QHBoxLayout() encodingsButtonsLayout.addWidget(self.buttonNewEncoding) encodingsButtonsLayout.addWidget(self.buttonEditEncoding) encodingsButtonsLayout.addWidget(self.buttonDeleteEncoding) # groupBoxEncodingsLayout groupBoxEncodingsLayout = QtGui.QVBoxLayout() groupBoxEncodingsLayout.addLayout(encodingsButtonsLayout) groupBoxEncodingsLayout.addWidget(self.listBoxEncodings) # groupBoxEncodings self.groupBoxEncodings = QtGui.QGroupBox() self.groupBoxEncodings.setLayout(groupBoxEncodingsLayout) self.groupBoxEncodings.setTitle("Encodings") # groupBoxMainLayout groupBoxMainLayout = QtGui.QGridLayout() groupBoxMainLayout.addWidget(self.labelSensorWidth, 0, 0) groupBoxMainLayout.addWidget(self.spinnerSensorWidth, 0, 1) groupBoxMainLayout.addWidget(self.labelSensorHeight, 1, 0) groupBoxMainLayout.addWidget(self.spinnerSensorHeight, 1, 1) groupBoxMainLayout.addWidget(self.groupBoxDataSourceType, 2, 1) groupBoxMainLayout.addWidget(self.labelPredictionsMethod, 3, 0) groupBoxMainLayout.addWidget(self.comboBoxPredictionsMethod, 3, 1) groupBoxMainLayout.addWidget(self.groupBoxEncodings, 4, 1) # groupBoxMain self.groupBoxMain = QtGui.QGroupBox() self.groupBoxMain.setLayout(groupBoxMainLayout) # buttonBox self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) self.buttonBox.button(QtGui.QDialogButtonBox.Ok).clicked.connect(self.__buttonOk_Click) self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(not Global.simulationInitialized) self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).clicked.connect(self.__buttonCancel_Click) # layout layout = QtGui.QVBoxLayout() layout.addWidget(self.groupBoxMain) layout.addWidget(self.buttonBox) # SensorForm self.setLayout(layout) self.setModal(True) self.setWindowTitle("Sensor Properties") self.setWindowIcon(QtGui.QIcon(Global.appPath + '/images/logo.ico')) self.resize(400, 200) def setControlsValues(self): """ Set controls values from a class instance. """ # Set controls value with sensor params node = Global.architectureForm.designPanel.underMouseNode self.spinnerSensorWidth.setValue(node.width) self.spinnerSensorHeight.setValue(node.height) if node.dataSourceType == DataSourceType.file: self.radioButtonDataSourceFile.setChecked(True) self.textBoxFile.setText(node.fileName) elif node.dataSourceType == DataSourceType.database: self.radioButtonDataSourceDatabase.setChecked(True) self.textBoxDatabaseConnectionString.setText(node.databaseConnectionString) self.textBoxDatabaseTable.setText(node.databaseTable) self.comboBoxPredictionsMethod.setCurrentIndex(self.comboBoxPredictionsMethod.findText(node.predictionsMethod, QtCore.Qt.MatchFixedString)) self.encodings = copy.deepcopy(node.encodings) self.__updateEncodingsListBox() def __updateEncodingsListBox(self): # Update the list box with the updated encodings self.listBoxEncodings.clear() for encoding in self.encodings: name = encoding.encoderFieldName.split('.')[0] self.listBoxEncodings.addItem(name) # Update controls according to list state if self.listBoxEncodings.count() > 0: if self.listBoxEncodings.currentRow() == -1: self.listBoxEncodings.setCurrentRow(0) self.buttonEditEncoding.setEnabled(not Global.simulationInitialized) self.buttonDeleteEncoding.setEnabled(not Global.simulationInitialized) else: self.buttonEditEncoding.setEnabled(False) self.buttonDeleteEncoding.setEnabled(False) #endregion #region Events def __buttonOk_Click(self, event): """ Check if values changed and save the,. """ if self.radioButtonDataSourceFile.isChecked() and self.textBoxFile.text() == '': QtGui.QMessageBox.warning(self, "Warning", "Input stream file was not specified.") return elif self.radioButtonDataSourceDatabase.isChecked() and self.textBoxDatabaseConnectionString.text() == '': QtGui.QMessageBox.warning(self, "Warning", "Database connection string was not specified.") return elif self.radioButtonDataSourceDatabase.isChecked() and self.textBoxDatabaseTable.text() == '': QtGui.QMessageBox.warning(self, "Warning", "Database table was not specified.") return elif self.listBoxEncodings.count() == 0: QtGui.QMessageBox.warning(self, "Warning", "Encodings list is empty. At least one encoding should be specified.") return else: hasFieldsWithInference = False for encoding in self.encodings: if encoding.enableInference: hasFieldsWithInference = True break if not hasFieldsWithInference: QtGui.QMessageBox.warning(self, "Warning", "At least one encoding should have inference enabled.") return width = self.spinnerSensorWidth.value() height = self.spinnerSensorHeight.value() dataSourceType = None if self.radioButtonDataSourceFile.isChecked(): dataSourceType = DataSourceType.file elif self.radioButtonDataSourceDatabase.isChecked(): dataSourceType = DataSourceType.database fileName = str(self.textBoxFile.text()) databaseConnectionString = str(self.textBoxDatabaseConnectionString.text()) databaseTable = str(self.textBoxDatabaseTable.text()) predictionsMethod = str(self.comboBoxPredictionsMethod.currentText()) # If anything has changed node = Global.architectureForm.designPanel.underMouseNode if node.width != width or node.height != height or node.predictionsMethod != predictionsMethod or node.dataSourceType != dataSourceType or node.fileName != fileName or node.databaseConnectionString != databaseConnectionString or node.databaseTable != databaseTable or self.encodingsChanged: # Set sensor params with controls values node.width = width node.height = height node.predictionsMethod = predictionsMethod node.dataSourceType = dataSourceType node.fileName = fileName node.databaseConnectionString = databaseConnectionString node.databaseTable = databaseTable node.encodings = copy.deepcopy(self.encodings) self.accept() self.close() def __buttonCancel_Click(self, event): self.reject() self.close() def __buttonBrowseFile_Click(self, event): # Ask user for an existing file selectedFile = QtGui.QFileDialog().getOpenFileName(self, "Open File", Global.appPath + '/projects', "Input files (*.csv)") # If file exists, set data source file if selectedFile != '': # Set file self.textBoxFile.setText(selectedFile) def __radioButtonDataSource_Click(self, event): if not Global.simulationInitialized: flag = self.radioButtonDataSourceFile.isChecked() self.textBoxFile.setEnabled(flag) self.buttonBrowseFile.setEnabled(flag) self.textBoxDatabaseConnectionString.setEnabled(not flag) self.textBoxDatabaseTable.setEnabled(not flag) def __buttonNewEncoding_Click(self, event): encodingForm = EncodingForm() encodingForm.encodingIdx = -1 encodingForm.encodings = self.encodings dialogResult = encodingForm.exec_() if dialogResult == QtGui.QDialog.Accepted: self.encodingsChanged = True self.__updateEncodingsListBox() def __buttonEditEncoding_Click(self, event): encodingForm = EncodingForm() encodingForm.encodingIdx = self.listBoxEncodings.currentRow() encodingForm.encodings = self.encodings encodingForm.setControlsValues() dialogResult = encodingForm.exec_() if dialogResult == QtGui.QDialog.Accepted: self.encodingsChanged = True self.__updateEncodingsListBox() def __buttonDeleteEncoding_Click(self, event): self.encodings.remove(self.encodings[self.listBoxEncodings.currentRow()]) self.encodingsChanged = True self.__updateEncodingsListBox() #endregion