paulb@342 | 1 | #!/usr/bin/env python |
paulb@342 | 2 | |
paulb@413 | 3 | "An example of a system configurator which runs under PyQt and WebStack." |
paulb@413 | 4 | |
paulb@332 | 5 | import os |
paulb@332 | 6 | |
paulb@351 | 7 | class ConfiguratorResource: |
paulb@332 | 8 | |
paulb@342 | 9 | # Standard attributes. |
paulb@342 | 10 | |
paulb@332 | 11 | resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") |
paulb@342 | 12 | |
paulb@355 | 13 | design_resources = { |
paulb@342 | 14 | "configuration" : "config.ui" |
paulb@342 | 15 | } |
paulb@342 | 16 | |
paulb@342 | 17 | widget_resources = { |
paulb@385 | 18 | "hard_disk" : ("config_hard_disk.ui", "hard_disk"), |
paulb@385 | 19 | "memory_unit" : ("config_memory_unit.ui", "memory_unit"), |
paulb@385 | 20 | "storage_unit" : ("config_storage_unit.ui", "storage_unit") |
paulb@385 | 21 | #"hard_disks" : ("config_hard_disks.ui", "hard_disks"), |
paulb@385 | 22 | #"memory_units" : ("config_memory_units.ui", "memory_units"), |
paulb@385 | 23 | #"storage_units" : ("config_storage_units.ui", "storage_units") |
paulb@342 | 24 | } |
paulb@342 | 25 | |
paulb@342 | 26 | document_resources = { |
paulb@342 | 27 | "base-system" : "config_base_system.xml", |
paulb@342 | 28 | "cpu" : "config_cpu.xml", |
paulb@342 | 29 | "hard-disk" : "config_hard_disk.xml", |
paulb@342 | 30 | "keyboard" : "config_keyboard.xml", |
paulb@376 | 31 | "memory-unit" : "config_memory_unit.xml", |
paulb@342 | 32 | "mouse" : "config_mouse.xml", |
paulb@376 | 33 | "screen" : "config_screen.xml", |
paulb@376 | 34 | "storage-unit" : "config_storage_unit.xml" |
paulb@342 | 35 | } |
paulb@342 | 36 | |
paulb@342 | 37 | # Initialisation. |
paulb@332 | 38 | |
paulb@332 | 39 | def __init__(self, *args, **kw): |
paulb@361 | 40 | pass |
paulb@342 | 41 | |
paulb@361 | 42 | def form_init(self): |
paulb@361 | 43 | |
paulb@370 | 44 | self.reset_collection(self.child("hard_disks")) |
paulb@370 | 45 | self.reset_collection(self.child("memory_units")) |
paulb@370 | 46 | self.reset_collection(self.child("storage_units")) |
paulb@370 | 47 | |
paulb@370 | 48 | def form_populate(self): |
paulb@342 | 49 | |
paulb@361 | 50 | # Get field data. |
paulb@370 | 51 | # NOTE: This would be done for whole page updates in a Web application. |
paulb@361 | 52 | |
paulb@361 | 53 | self.populate_list(self.child("base_system"), self.get_elements("base-system")) |
paulb@361 | 54 | self.populate_list(self.child("keyboard"), self.get_elements("keyboard")) |
paulb@361 | 55 | self.populate_list(self.child("mouse"), self.get_elements("mouse")) |
paulb@361 | 56 | self.populate_list(self.child("screen"), self.get_elements("screen")) |
paulb@342 | 57 | |
paulb@342 | 58 | # General functionality. |
paulb@342 | 59 | |
paulb@361 | 60 | def form_refresh(self, current_text=None): |
paulb@342 | 61 | |
paulb@342 | 62 | # Ensure consistency. |
paulb@342 | 63 | # NOTE: This would be done for whole page updates in a Web application. |
paulb@342 | 64 | # NOTE: This would also be done for page updates where the information |
paulb@342 | 65 | # NOTE: involved was important. |
paulb@342 | 66 | |
paulb@361 | 67 | current_text = current_text or self.child("base_system").currentText() |
paulb@332 | 68 | |
paulb@342 | 69 | # Find the CPU socket and the interface of the current base system. |
paulb@342 | 70 | cpu_socket = None |
paulb@342 | 71 | interface = None |
paulb@342 | 72 | for element in self.get_elements("base-system"): |
paulb@342 | 73 | text = element.getAttribute("value") |
paulb@342 | 74 | if text == current_text: |
paulb@342 | 75 | cpu_socket = element.getAttribute("cpu-socket") |
paulb@342 | 76 | interface = element.getAttribute("interface") |
paulb@342 | 77 | |
paulb@342 | 78 | # Find all valid CPUs. |
paulb@342 | 79 | valid = [] |
paulb@342 | 80 | for element in self.get_elements("cpu"): |
paulb@342 | 81 | if not element.hasAttribute("cpu-socket") or element.getAttribute("cpu-socket") == cpu_socket: |
paulb@342 | 82 | valid.append(element) |
paulb@361 | 83 | self.populate_list(self.child("cpu"), valid) |
paulb@342 | 84 | |
paulb@342 | 85 | # Find all valid hard disks. |
paulb@342 | 86 | valid = [] |
paulb@342 | 87 | for element in self.get_elements("hard-disk"): |
paulb@342 | 88 | if not element.hasAttribute("interface") or element.getAttribute("interface") == interface: |
paulb@342 | 89 | valid.append(element) |
paulb@342 | 90 | for hard_disk_value in self.factory.find_widgets(self, "hard_disk_value"): |
paulb@342 | 91 | self.populate_list(hard_disk_value, valid) |
paulb@342 | 92 | |
paulb@376 | 93 | # Find memory units. |
paulb@376 | 94 | for memory_unit_value in self.factory.find_widgets(self, "memory_unit_value"): |
paulb@376 | 95 | self.populate_list(memory_unit_value, self.get_elements("memory-unit")) |
paulb@376 | 96 | |
paulb@376 | 97 | # Find storage units. |
paulb@376 | 98 | for storage_unit_value in self.factory.find_widgets(self, "storage_unit_value"): |
paulb@376 | 99 | self.populate_list(storage_unit_value, self.get_elements("storage-unit")) |
paulb@376 | 100 | |
paulb@342 | 101 | # Slots. |
paulb@342 | 102 | |
paulb@342 | 103 | def baseSystemChanged(self, current_text): |
paulb@376 | 104 | self.request_refresh(current_text) |
paulb@332 | 105 | |
paulb@332 | 106 | def addHardDisk(self): |
paulb@385 | 107 | #hard_disks = self.prepare_widget("configuration", "hard_disks") |
paulb@345 | 108 | #tab_pages = hard_disks.child("tab pages") |
paulb@345 | 109 | #tab = tab_pages.child("tab") |
paulb@361 | 110 | #self.child("hard_disks").addTab(tab, hard_disks.tabLabel(tab)) |
paulb@345 | 111 | #self.factory.connect(tab, self) |
paulb@385 | 112 | hard_disk = self.prepare_widget("configuration", "hard_disk", self.child("hard_disks")) |
paulb@361 | 113 | self.child("hard_disks").layout().add(hard_disk) |
paulb@345 | 114 | hard_disk.show() |
paulb@345 | 115 | self.factory.connect(hard_disk, self) |
paulb@332 | 116 | |
paulb@342 | 117 | # Perform the consistency check. |
paulb@342 | 118 | # NOTE: This is not as efficient as it could be since the general check |
paulb@342 | 119 | # NOTE: refreshes all fields, not just newly added ones. |
paulb@376 | 120 | self.request_refresh() |
paulb@342 | 121 | |
paulb@332 | 122 | def addMemoryUnit(self): |
paulb@385 | 123 | #memory_units = self.prepare_widget("configuration", "memory_units") |
paulb@345 | 124 | #tab_pages = memory_units.child("tab pages") |
paulb@345 | 125 | #tab = tab_pages.child("tab") |
paulb@361 | 126 | #self.child("memory_units").addTab(tab, memory_units.tabLabel(tab)) |
paulb@345 | 127 | #self.factory.connect(tab, self) |
paulb@385 | 128 | memory_unit = self.prepare_widget("configuration", "memory_unit", self.child("memory_units")) |
paulb@361 | 129 | self.child("memory_units").layout().add(memory_unit) |
paulb@345 | 130 | memory_unit.show() |
paulb@345 | 131 | self.factory.connect(memory_unit, self) |
paulb@332 | 132 | |
paulb@342 | 133 | # Perform the consistency check. |
paulb@342 | 134 | # NOTE: This is not as efficient as it could be since the general check |
paulb@342 | 135 | # NOTE: refreshes all fields, not just newly added ones. |
paulb@376 | 136 | self.request_refresh() |
paulb@342 | 137 | |
paulb@332 | 138 | def addStorageUnit(self): |
paulb@385 | 139 | #storage_units = self.prepare_widget("configuration", "storage_units") |
paulb@345 | 140 | #tab_pages = storage_units.child("tab pages") |
paulb@345 | 141 | #tab = tab_pages.child("tab") |
paulb@361 | 142 | #self.child("storage_units").addTab(tab, storage_units.tabLabel(tab)) |
paulb@345 | 143 | #self.factory.connect(tab, self) |
paulb@385 | 144 | storage_unit = self.prepare_widget("configuration", "storage_unit", self.child("storage_units")) |
paulb@361 | 145 | self.child("storage_units").layout().add(storage_unit) |
paulb@345 | 146 | storage_unit.show() |
paulb@345 | 147 | self.factory.connect(storage_unit, self) |
paulb@332 | 148 | |
paulb@342 | 149 | # Perform the consistency check. |
paulb@342 | 150 | # NOTE: This is not as efficient as it could be since the general check |
paulb@342 | 151 | # NOTE: refreshes all fields, not just newly added ones. |
paulb@376 | 152 | self.request_refresh() |
paulb@342 | 153 | |
paulb@332 | 154 | def removeHardDisk(self): |
paulb@345 | 155 | #page = self.hard_disks.currentPage() |
paulb@345 | 156 | #self.hard_disks.removePage(page) |
paulb@345 | 157 | #page.deleteLater() |
paulb@345 | 158 | remove_hard_disk = self.sender() |
paulb@345 | 159 | hard_disk = remove_hard_disk.parent() |
paulb@361 | 160 | self.child("hard_disks").layout().remove(hard_disk) |
paulb@345 | 161 | hard_disk.deleteLater() |
paulb@332 | 162 | |
paulb@332 | 163 | def removeMemoryUnit(self): |
paulb@345 | 164 | #page = self.memory_units.currentPage() |
paulb@345 | 165 | #self.memory_units.removePage(page) |
paulb@345 | 166 | #page.deleteLater() |
paulb@345 | 167 | remove_memory_unit = self.sender() |
paulb@345 | 168 | memory_unit = remove_memory_unit.parent() |
paulb@361 | 169 | self.child("memory_units").layout().remove(memory_unit) |
paulb@345 | 170 | memory_unit.deleteLater() |
paulb@332 | 171 | |
paulb@332 | 172 | def removeStorageUnit(self): |
paulb@345 | 173 | #page = self.storage_units.currentPage() |
paulb@345 | 174 | #self.storage_units.removePage(page) |
paulb@345 | 175 | #page.deleteLater() |
paulb@345 | 176 | remove_storage_unit = self.sender() |
paulb@345 | 177 | storage_unit = remove_storage_unit.parent() |
paulb@361 | 178 | self.child("storage_units").layout().remove(storage_unit) |
paulb@345 | 179 | storage_unit.deleteLater() |
paulb@332 | 180 | |
paulb@332 | 181 | def updateConfig(self): |
paulb@361 | 182 | self.form_refresh() |
paulb@332 | 183 | |
paulb@332 | 184 | def exportConfig(self): |
paulb@332 | 185 | print "configuration.exportConfig(): Not implemented yet" |
paulb@332 | 186 | |
paulb@361 | 187 | def get_resource(resource_type, *args, **kw): |
paulb@351 | 188 | |
paulb@351 | 189 | if resource_type == "PyQt": |
paulb@353 | 190 | import XSLForms.Resources.PyQtResources |
paulb@410 | 191 | try: |
paulb@410 | 192 | import QtConfigurator.Forms |
paulb@410 | 193 | except ImportError: |
paulb@410 | 194 | print "*" * 60 |
paulb@410 | 195 | print "Please generate the following file before running this example:" |
paulb@410 | 196 | print os.path.join(os.path.split(__file__)[0], "Forms.py") |
paulb@410 | 197 | print "Use the pyuic program along with the form definition file:" |
paulb@410 | 198 | print os.path.join(os.path.split(__file__)[0], "Resources", "config.ui") |
paulb@410 | 199 | print "*" * 60 |
paulb@410 | 200 | print |
paulb@410 | 201 | raise |
paulb@353 | 202 | class Configurator(ConfiguratorResource, QtConfigurator.Forms.Configurator, XSLForms.Resources.PyQtResources.XSLFormsResource): |
paulb@351 | 203 | def __init__(self, *args, **kw): |
paulb@351 | 204 | QtConfigurator.Forms.Configurator.__init__(self, *args, **kw) |
paulb@361 | 205 | XSLForms.Resources.PyQtResources.XSLFormsResource.__init__(self, "configuration") |
paulb@351 | 206 | ConfiguratorResource.__init__(self, *args, **kw) |
paulb@361 | 207 | resource = Configurator(*args, **kw) |
paulb@361 | 208 | resource.form_init() |
paulb@370 | 209 | resource.form_populate() |
paulb@361 | 210 | |
paulb@351 | 211 | else: |
paulb@353 | 212 | import XSLForms.Resources.PyQtWebResources |
paulb@388 | 213 | from WebStack.Resources.ResourceMap import MapResource |
paulb@388 | 214 | from WebStack.Resources.Static import DirectoryResource |
paulb@385 | 215 | |
paulb@353 | 216 | class Configurator(ConfiguratorResource, XSLForms.Resources.PyQtWebResources.XSLFormsResource): |
paulb@351 | 217 | def __init__(self, *args, **kw): |
paulb@361 | 218 | XSLForms.Resources.PyQtWebResources.XSLFormsResource.__init__(self, "configuration") |
paulb@351 | 219 | ConfiguratorResource.__init__(self, *args, **kw) |
paulb@385 | 220 | |
paulb@388 | 221 | configurator_resource = Configurator(*args, **kw) |
paulb@388 | 222 | directory = configurator_resource.resource_dir |
paulb@388 | 223 | resource = MapResource({ |
paulb@388 | 224 | "styles" : DirectoryResource(os.path.join(directory, "styles"), {"css" : "text/css"}), |
paulb@388 | 225 | "scripts" : DirectoryResource(os.path.join(directory, "scripts"), {"js" : "text/javascript"}), |
paulb@388 | 226 | "" : configurator_resource |
paulb@388 | 227 | }) |
paulb@385 | 228 | |
paulb@370 | 229 | # Do not initialise or populate the resource here: both happen when a |
paulb@370 | 230 | # Web request is received (initialisation when no form document is |
paulb@370 | 231 | # found; population when a form document is prepared for output). |
paulb@351 | 232 | |
paulb@361 | 233 | return resource |
paulb@351 | 234 | |
paulb@332 | 235 | # vim: tabstop=4 expandtab shiftwidth=4 |