# HG changeset patch # User paulb # Date 1130871461 0 # Node ID 6029e3d9497f2c27aec23776c4aab83277e265be # Parent eb6be3a3dd04ff4cac4b9074a503d20e891cb3ae [project @ 2005-11-01 18:57:41 by paulb] Added request_refresh as the application method for refreshing a form. Added tentative functionality for editing, including addition and removal of widgets. diff -r eb6be3a3dd04 -r 6029e3d9497f XSLForms/Resources/PyQtWebResources.py --- a/XSLForms/Resources/PyQtWebResources.py Tue Nov 01 18:56:33 2005 +0000 +++ b/XSLForms/Resources/PyQtWebResources.py Tue Nov 01 18:57:41 2005 +0000 @@ -41,7 +41,7 @@ self.factory = Factory() self.default_design = design_identifier - # NOTE: Filename extended by string concatenation. + # NOTE: Filenames extended by string concatenation. self.template_resources = {} self.init_resources = {} @@ -49,6 +49,27 @@ self.template_resources[design_identifier] = (design_name + "_template.xhtml", design_name + "_output.xsl") self.init_resources[design_identifier] = (design_name + "_template.xhtml", design_name + "_input.xsl") + # Initialisation of connections - just a mapping from field names to + # methods in the Web version. + + self.method_resources = {} + for design_identifier, design_name in self.design_resources.items(): + design_path = self.prepare_design(design_identifier) + design_doc = libxml2dom.parse(design_path) + connections = {} + for connection in design_doc.xpath("UI/connections/connection"): + receiver = "".join([n.nodeValue for n in connection.xpath("receiver/text()")]) + if receiver == design_identifier: + sender = "".join([n.nodeValue for n in connection.xpath("sender/text()")]) + slot = "".join([n.nodeValue for n in connection.xpath("slot/text()")]) + slot = slot.split("(")[0] + connections[sender] = slot + self.method_resources[design_identifier] = connections + + # Refresh status - avoiding multiple refresh calls. + + self._refreshed = 0 + # Resource methods. def prepare_output(self, design_identifier): @@ -79,16 +100,20 @@ return libxml2dom.parse(self.prepare_document(document_identifier)) def prepare_widget(self, design_identifier, widget_identifier, parent=None): - design_path = self.prepare_design(design_identifier) fragment_name, widget_name = self.widget_resources[widget_identifier] - fragment_path = os.path.abspath(os.path.join(self.resource_dir, fragment_name)) - XSLForms.Prepare.ensure_qt_fragment(design_path, fragment_path, widget_name) - # NOTE: Implement the equivalent here! - return qtui.QWidgetFactory.create(fragment_path, None, parent) + element = UINode(self.doc._node.ownerDocument.createElement(widget_name)) + + # NOTE: Creating an element which may not be appropriate. + + element._node.appendChild(self.doc._node.ownerDocument.createElement(widget_name + "_value")) + return element def child(self, name): return self.doc.child(name) + def sender(self): + return self._sender + # PyQt structural methods. def form_init(self): @@ -109,6 +134,14 @@ raise NotImplementedError, "form_refresh" + def request_refresh(self, *args, **kw): + + "Request a refresh of the form." + + if not self._refreshed: + self._refreshed = 1 + self.form_refresh(*args, **kw) + # Standard XSLFormsResource method, overridden to handle presentation. def respond_to_form(self, trans, form): @@ -120,6 +153,8 @@ documents). """ + self._refreshed = 0 + # Ensure the presence of the template. self.prepare_output(self.default_design) @@ -129,25 +164,45 @@ doc = form.get_document(self.default_design) if doc is None: doc = form.new_document(self.default_design) - doc = self._form_init(doc) + doc = self._get_initialised_form(doc) self.doc = UINode(doc.xpath("*")[0]) self.form_init() else: - doc = self._form_init(doc) + doc = self._get_initialised_form(doc) self.doc = UINode(doc.xpath("*")[0]) self.form_populate() + + # Updates happen here. + + form.set_document(self.default_design, doc) + selectors = form.get_selectors() + connections = self.method_resources[self.default_design] + for selector_name, selector_values in selectors.items(): + if connections.has_key(selector_name): + slot = connections[selector_name] + if hasattr(self, slot): + + # Initialise the sender. + + for selector_value in selector_values: + # NOTE: Fake a special attribute to simulate the Qt widget hierarchy. + selector_value.setAttribute("_sender", "") + self._sender = UINode(selector_value.getAttributeNode("_sender")) + getattr(self, slot)() + + # Consistency is ensured and filtering enforced. + + self.request_refresh() #print self.doc._node.toString("iso-8859-1") - # NOTE: Updates happen here. - - self.form_refresh() + # Output is produced. trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding)) design_xsl = self.prepare_output(self.default_design) self.send_output(trans, [design_xsl], doc._node) - def _form_init(self, doc): + def _get_initialised_form(self, doc): input_xsl = self.prepare_initialiser(self.default_design, init_enumerations=0) return self.get_result([input_xsl], doc) @@ -158,6 +213,9 @@ def __init__(self, node): self._node = node + def add(self, node): + self._node.appendChild(node._node) + def child(self, name): nodes = self._node.xpath(name) if len(nodes) > 0: @@ -181,6 +239,9 @@ else: return 0 + def deleteLater(self): + pass + def insertItem(self, item, position=-1): # NOTE: Names invented rather than being extracted from the schema. new_element = self._node.ownerDocument.createElement(self._node.localName + "_enum") @@ -194,29 +255,37 @@ else: self._node.appendChild(new_element) + def layout(self): + return self + def parent(self): return UINode(self._node.parentNode) def removeItem(self, item): - pass # NOTE: Not implemented yet! + elements = self._node.xpath("*") + if item < len(elements): + self._node.removeChild(elements[item]) def remove(self, item): - pass # NOTE: Not implemented yet! - - def layout(self): - return self + self._node.removeChild(item._node) def setCurrentItem(self, index): pass # NOTE: Not implemented yet! - def deleteLater(self): - self._node.parentNode.removeChild(self._node) + def show(self): + pass class Factory: "A widget factory helper class." def connect(self, widget, obj): + + """ + Connection is done all at once by mapping field names to method names in + the resource object. + """ + pass def find_widgets(self, widget, name):