Example #1
0
class TestCorpusDescriberWindow(Frame):
	def __init__(self, parent, coordinator=None):
		# Call the parent constructors
		super(TestCorpusDescriberWindow, self).__init__(parent, fill=True)

		# Initialize class variables
		self.coordinator = coordinator
		self.firmwareDict = dict() # firmware objects by key basename
		self.sectionDict = dict() # section objects by key bounds

		# Setup the window objects
		# First, the firmware list
		self.__firmwareList = Listbox(self,
				listChangeCallback=self._firmwareSelectionChangeCallback)
		self.__firmwareList.grid({"row": 0, "column": 0, "rowspan": 10,
				"sticky": "nswe"})

		# The buttons that manage the firmware list - in their own frame
		self.__firmwareButtonFrame = Frame(self)
		self.__firmwareButtonFrame.grid({"row": 10, "column": 0})

		self.__deleteFirmwareButton = Button(self.__firmwareButtonFrame,
				text="Delete", callback=self._deleteFirmwareButtonCallback)
		self.__deleteFirmwareButton.grid({"row": 0, "column": 0})

		self.__addFirmwareButton = Button(self.__firmwareButtonFrame,
				text="Add", callback=self._addFirmwareButtonCallback)
		self.__addFirmwareButton.grid({"row": 0, "column": 2})
		
		# Second, the section list
		self.__sectionList = Listbox(self,
				listChangeCallback=self._sectionSelectionChangeCallback)
		self.__sectionList.grid({"row": 0, "column": 1, "rowspan": 9,
				"sticky": "nsew"})

		# The buttons that manage the section list - in their own frame
		self.__sectionListButtonFrame = Frame(self)
		self.__sectionListButtonFrame.grid({"row": 9, "column": 1, "rowspan": 2})

		self.__sectionStartEntry = Entry(self.__sectionListButtonFrame, width=4)
		self.__sectionStartEntry.grid({"row": 0, "column": 0})
		self.__sectionEndEntry = Entry(self.__sectionListButtonFrame, width=4)
		self.__sectionEndEntry.grid({"row": 0, "column": 1})

		self.__addSection = Button(self.__sectionListButtonFrame, text="Add",
				callback=self._addSectionCallback)
		self.__addSection.grid({"row": 1, "column": 0})

		self.__deleteSection = Button(self.__sectionListButtonFrame,
				text="Delete", callback=self._deleteSectionCallback)
		self.__deleteSection.grid({"row": 1, "column": 1})

		# Lastly, the properties box
		# First the global config options, in their own frame
		self.__globalOptionsFrame = Frame(self, highlight=True)
		self.__globalOptionsFrame.grid({"row": 0, "column": 2, "rowspan": 4,
				"sticky": "nsew"})

		self.__globalSettingsLabel = Label(self.__globalOptionsFrame,
				text="Global Settings")
		self.__globalSettingsLabel.grid({"row": 0, "column":0, "columnspan": 3})

		self.__corpusNameLabel = Label(self.__globalOptionsFrame,
				text="Corpus Name:")
		self.__corpusNameLabel.grid({"row": 1, "column": 0})
		self.__corpusNameEntry = Entry(self.__globalOptionsFrame)
		self.__corpusNameEntry.grid({"row": 1, "column": 1, "columnspan": 2})

		self.__corpusDescriptionLabel = Label(self.__globalOptionsFrame,
				text="Description:")
		self.__corpusDescriptionLabel.grid({"row": 2, "column": 0})
		self.__corpusDescriptionEntry = Entry(self.__globalOptionsFrame)
		self.__corpusDescriptionEntry.grid({"row": 2, "column": 1, "columnspan": 2})

		# Next the firmware options in their own frame
		self.__firmwareOptionsFrame = Frame(self, highlight=True)
		self.__firmwareOptionsFrame.grid({"row": 4, "column": 2, "rowspan": 4, 
				"sticky": "nsew"})

		self.__firmwareSettingsLabel = Label(self.__firmwareOptionsFrame,
				text="Firmware Settings")
		self.__firmwareSettingsLabel.grid({"row": 0, "column":0, "columnspan": 3})

		self.__firmwareNameLabel = Label(self.__firmwareOptionsFrame,
				"Firmware Name:")
		self.__firmwareNameLabel.grid({"row": 1, "column": 0})
		self.__firmwareNameEntry = Entry(self.__firmwareOptionsFrame)
		self.__firmwareNameEntry.grid({"row": 1, "column": 1, "columnspan": 2})

		self.__firmwareFileNameLabel = Label(self.__firmwareOptionsFrame,
				text="Firmware File:")
		self.__firmwareFileNameLabel.grid({"row": 2, "column": 0})
		self.__firmwareFileNameEntry = Entry(self.__firmwareOptionsFrame)
		self.__firmwareFileNameEntry.grid({"row": 2, "column": 1, "columnspan": 2})

		# Next the section options in their own frame
		self.__sectionOptionsFrame = Frame(self, highlight=True)
		self.__sectionOptionsFrame.grid({"row": 8, "column": 2, "rowspan": 2,
				"sticky": "nsew"})

		self.__sectionSettingsLabel = Label(self.__sectionOptionsFrame,
				text="Section Settings")
		self.__sectionSettingsLabel.grid({"row": 0, "column":0, "columnspan": 3})

		self.__sectionFiletypeLabel = Label(self.__sectionOptionsFrame,
				"Section Filetype:")
		self.__sectionFiletypeLabel.grid({"row": 1, "column": 0})
		self.__sectionFiletypeEntry = Entry(self.__sectionOptionsFrame)
		self.__sectionFiletypeEntry.grid({"row": 1, "column": 1,
				"columnspan": 2})

		# Lastly the buttons that manage the config
		self.__globalButtonFrame = Frame(self)
		self.__globalButtonFrame.grid({"row": 10, "column": 2})

		self.__writeConfigButton = Button(self.__globalButtonFrame,
				text="Write Config", callback = self._writeConfigButtonCallback)
		self.__writeConfigButton.grid({"row": 0, "column": 0})

	def getCorpusOutputFile(self):
		"""Return the filename to save the config to."""
		fd = FileDialog(self)
		return fd.getFilenameToSave()

	def getDefinedCorpus(self):
		"""Return the corpus described by the GUI."""
		# Store off the current screen entries into their appropriate filetype
		curSelection = self.__firmwareList.getSelected()
		if len(curSelection) > 0:
			self._storeCurrentFirmwareEntries(curSelection[0])
		# Build the corpus object
		name = self.__corpusNameEntry.text
		description = self.__corpusDescriptionEntry.text
		corpus = TestCorpus(name, description)
		for firmwareKey in self.firmwareDict:
			corpus.appendFirmware(self.firmwareDict[firmwareKey])
		return corpus

	def _clearFirmwareScreenEntries(self):
		self.__firmwareNameEntry.text = ""
		self.__firmwareFileNameEntry.text = ""
		self.sectionDict = dict()
		self.__sectionList.populate(list())
		self._clearSectionScreenEntries()

	def _clearSectionScreenEntries(self):
		self.__sectionFiletypeEntry.text = ""

	def _firmwareSelectionChangeCallback(self, oldSelection, newSelection):
		"""Gets called when the firmware listbox selection changes."""
		# Save the data on screen as the old file type
		if len(oldSelection) > 0:
			self._storeCurrentFirmwareEntries(oldSelection[0])

		self._clearFirmwareScreenEntries()
	
		# Load the new selection file type data to screen
		if len(newSelection) > 0:
			firmware = self.firmwareDict[newSelection[0]]
			self.__firmwareNameEntry.text = firmware.name
			self.__firmwareFileNameEntry.text = firmware.filename
			# Generate the section dictionary
			self.sectionDict = dict([(sec.bounds, sec) for sec in firmware.sections])
			self.__sectionList.populate(list(self.sectionDict.keys()))

	def _sectionSelectionChangeCallback(self, oldSelection, newSelection):
		"""Gets called when the section listbox selection changes."""
		# Save the data on screen as the old file type
		if len(oldSelection) > 0:
			self._storeCurrentSectionEntries(oldSelection[0])
	
		# Load the new selection file type data to screen
		if len(newSelection) > 0:
			section = self.sectionDict[newSelection[0]]
			self.__sectionFiletypeEntry.text = section.filetype
		else:
			self.__sectionFiletypeEntry.text = ""

	def _storeCurrentFirmwareEntries(self, firmwareKey):
		"""Store the current screen info into the firmwareDict, at the key."""
		curSelection = self.__sectionList.getSelected()
		if len(curSelection) > 0:
			self._storeCurrentSectionEntries(curSelection[0])
		firmwareDef = dict()
		firmwareDef["Name"] = self.__firmwareNameEntry.text
		firmwareDef["Filename"] = self.__firmwareFileNameEntry.text
		firmwareDef["Sections"] = list(self.sectionDict.values())
		self.firmwareDict[firmwareKey] = Firmware(firmwareDef)

	def _storeCurrentSectionEntries(self, sectionKey):
		"""Store the current section info on the screen."""
		if sectionKey in self.sectionDict:
			sectionDef = self.sectionDict[sectionKey]
			sectionDef.filetype = self.__sectionFiletypeEntry.text
			self.sectionDict[sectionKey] = sectionDef

	def _deleteFirmwareButtonCallback(self):
		# Delete the selected firmware
		firmware = self.__firmwareList.getSelected()
		self.__firmwareList.removeSelected()
		for fw in firmware:
			self.firmwareDict.pop(fw)
		self._clearFirmwareScreenEntries()

	def _addFirmwareButtonCallback(self):
		# If firmware was entered in the box that isn't already on screen, add it
		fd = FileDialog(self)
		firmwareName = fd.getFilenameToOpen()
		firmwarePath = os.path.realpath(firmwareName)
		basename = os.path.basename(firmwarePath)
		if (firmwareName != "") and (basename not in self.firmwareDict):
			self.firmwareDict[basename] = Firmware({"Name": basename,
					"Filename": firmwarePath})
			self.__firmwareList.append(basename)

	def _deleteSectionCallback(self):
		"""Delete the selected section."""
		curSelection = self.__sectionList.getSelected()
		self.__sectionList.removeSelected()
		for sec in curSelection:
			self.sectionDict.pop(sec)
		self._clearSectionScreenEntries()

	def _addSectionCallback(self):
		"""Add a section to the section list."""
		setupDict = dict()
		setupDict["Start"] = int(self.__sectionStartEntry.text)
		setupDict["End"] = int(self.__sectionEndEntry.text)
		fw = FirmwareSection(setupDict)
		if fw.bounds not in self.sectionDict:
			self.sectionDict[fw.bounds] = fw
			self.__sectionList.append(fw.bounds)

	def _writeConfigButtonCallback(self):
		# Tell the coordinator to write out the configuration
		self.coordinator.outputCorpus()