# HG changeset patch # User paulb # Date 1130430833 0 # Node ID 8a070b0798216dbf250c006f71d2a1f5167d15c4 # Parent 05f71ae90993dbd1b7b7d33f07f70b42f6e1c829 [project @ 2005-10-27 16:33:53 by paulb] Moved various methods into the PyQt-compatible superclass. Introduced widget factory initialisation. Added wrappers around DOM nodes for the PyQt Web resource, although usage of a DOM for the PyQt widget tree may be more convenient. Introduced the standard form_init and form_refresh methods. diff -r 05f71ae90993 -r 8a070b079821 XSLForms/Resources/Common.py --- a/XSLForms/Resources/Common.py Thu Oct 27 16:31:26 2005 +0000 +++ b/XSLForms/Resources/Common.py Thu Oct 27 16:33:53 2005 +0000 @@ -48,6 +48,14 @@ design_resources = {} def get_document(self, document_identifier): + + """ + Return a DOM-style document retrieved using the given + 'document_identifier'. + + Each implementation is free to choose its own DOM library. + """ + raise NotImplementedError, "get_document" def get_elements(self, document_identifier): @@ -58,4 +66,33 @@ filename = self.design_resources[design_identifier] return os.path.abspath(os.path.join(self.resource_dir, filename)) + def populate_list(self, field, elements): + + "Populate the given 'field' using a list of DOM 'elements'." + + current_text = field.currentText() + while field.count() > 0: + field.removeItem(0) + item = 0 + set = 0 + for element in elements: + text = element.getAttribute("value") + field.insertItem(text) + if text == current_text: + field.setCurrentItem(item) + set = 1 + item += 1 + if not set: + field.setCurrentItem(0) + + def reset_collection(self, field): + + "Empty the given collection 'field'." + + layout = field.layout() + for child in field.children(): + if child is not layout: + layout.remove(child) + child.deleteLater() + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 05f71ae90993 -r 8a070b079821 XSLForms/Resources/PyQtResources.py --- a/XSLForms/Resources/PyQtResources.py Thu Oct 27 16:31:26 2005 +0000 +++ b/XSLForms/Resources/PyQtResources.py Thu Oct 27 16:33:53 2005 +0000 @@ -31,6 +31,9 @@ widget_resources = {} + def __init__(self, design_identifier): + self.factory = Factory(self.prepare_design(design_identifier)) + def get_document(self, document_identifier): return qtxmldom.parse(self.prepare_document(document_identifier)) @@ -41,29 +44,6 @@ XSLForms.Prepare.ensure_qt_fragment(design_path, fragment_path, widget_name) return qtui.QWidgetFactory.create(fragment_path, None, parent) - def populate_list(self, field, elements): - current_text = field.currentText() - while field.count() > 0: - field.removeItem(0) - item = 0 - set = 0 - for element in elements: - text = element.getAttribute("value") - field.insertItem(text) - if text == current_text: - field.setCurrentItem(item) - set = 1 - item += 1 - if not set: - field.setCurrentItem(0) - - def reset_collection(self, field): - layout = field.layout() - for child in field.children(): - if child is not layout: - layout.remove(child) - child.deleteLater() - class Factory: "A widget factory helper class." @@ -90,6 +70,10 @@ for sender in senders: qt.QObject.connect(sender, signal, getattr(obj, slot)) + def get_text(self, node): + node.normalize() + return node.childNodes[0].nodeValue + def find_widgets(self, widget, name): widgets = [] found = widget.child(name) @@ -99,18 +83,4 @@ widgets += self.find_widgets(child, name) return widgets - def get_text(self, node): - node.normalize() - return node.childNodes[0].nodeValue - - def find_widget_element(self, name): - for widget in self.ui_doc.getElementsByTagName("widget"): - for property in widget.getElementsByTagName("property"): - if property.getAttribute("name") == "name": - for cstring in property.getElementsByTagName("cstring"): - found_name = self.get_text(cstring) - if found_name == name: - return widget - return None - # vim: tabstop=4 expandtab shiftwidth=4 diff -r 05f71ae90993 -r 8a070b079821 XSLForms/Resources/PyQtWebResources.py --- a/XSLForms/Resources/PyQtWebResources.py Thu Oct 27 16:31:26 2005 +0000 +++ b/XSLForms/Resources/PyQtWebResources.py Thu Oct 27 16:33:53 2005 +0000 @@ -23,6 +23,7 @@ import XSLForms.Prepare import XSLForms.Resources.Common import XSLForms.Resources.WebResources +import WebStack.Generic import os import libxml2dom @@ -35,6 +36,42 @@ widget_resources = {} + def __init__(self, design_identifier): + self.factory = Factory() + self.default_design = design_identifier + + # NOTE: Filename extended by string concatenation. + + self.template_resources = {} + for design_identifier, design_name in self.design_resources.items(): + self.template_resources[design_identifier] = (design_name + ".xhtml", design_name + ".xsl") + + # Resource methods. + + def prepare_output(self, design_identifier): + + """ + Prepare the output stylesheets using the given 'design_identifier' to + indicate which templates and stylesheets are to be employed in the + production of output from the resource. + + The 'design_identifier' is used as a key to the 'design_resources' and + 'template_resources' dictionary attributes. + + Return the full path to the output stylesheet for use with 'send_output' + or 'get_result'. + """ + + design_path = self.prepare_design(design_identifier) + template_filename, output_filename = self.template_resources[output_identifier] + output_path = os.path.abspath(os.path.join(self.resource_dir, output_filename)) + template_path = os.path.abspath(os.path.join(self.resource_dir, template_filename)) + XSLForms.Prepare.ensure_qt_template(design_path, template_path) + XSLForms.Prepare.ensure_stylesheet(template_path, output_path) + return output_path + + # PyQt compatibility methods. + def get_document(self, document_identifier): return libxml2dom.parse(self.prepare_document(document_identifier)) @@ -46,50 +83,107 @@ # NOTE: Implement the equivalent here! return qtui.QWidgetFactory.create(fragment_path, None, parent) - def populate_list(self, field, elements): - # NOTE: Support this! - current_text = field.currentText() - while field.count() > 0: - field.removeItem(0) - item = 0 - set = 0 - for element in elements: - text = element.getAttribute("value") - field.insertItem(text) - if text == current_text: - field.setCurrentItem(item) - set = 1 - item += 1 - if not set: - field.setCurrentItem(0) + def child(self, name): + return self.doc.child(name) + + # PyQt structural methods. + + def form_init(self): + raise NotImplementedError, "form_init" + + def form_refresh(self): + raise NotImplementedError, "form_refresh" + + # Standard XSLFormsResource method, overridden to handle presentation. + + def respond_to_form(self, trans, form): + + """ + Respond to the request described by the given transaction 'trans', using + the given 'form' object to conveniently retrieve field (request + parameter) information and structured form information (as DOM-style XML + documents). + """ + + # Remember the document since it is accessed independently elsewhere. + + doc = form.get_document(self.default_design) + if doc is None: + self.doc = UINode(form.new_document(self.default_design)) + else: + self.doc = UINode(doc) + + self.form_init() + + # NOTE: Updates happen here. + + self.form_refresh() + + 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) + +class UINode: - def reset_collection(self, field): - # NOTE: Support this! - layout = field.layout() - for child in field.children(): - if child is not layout: - layout.remove(child) - child.deleteLater() + "A PyQt widget tree emulation node." + + def __init__(self, node): + self._node = node + + def child(self, name): + nodes = self._node.xpath(name) + if len(nodes) > 0: + return UINode(nodes[0]) + else: + return None + + def children(self): + return [UINode(node) for node in self._node.childNodes] + + def count(self): + return len(self._node.childNodes) + + def currentText(self): + return self.getAttribute("value") + + def currentItem(self): + found = self._node.xpath("*[@value=current()/@value]") + if found: + return int(found.xpath("count(preceding-sibling::*)")) + else: + return 0 + + def insertItem(self, item, position=-1): + + def parent(self): + return UINode(self._node.parentNode) + + def removeItem(self, item): + + def remove(self, item): + + def layout(self): + return self + + def setCurrentItem(self): + + def deleteLater(self): + self._node.parentNode.removeChild(self._node) class Factory: "A widget factory helper class." - def __init__(self, ui_filename): - self.ui_filename = ui_filename - self.ui_doc = libxml2dom.parse(ui_filename) - def connect(self, widget, obj): pass def find_widgets(self, widget, name): - # NOTE: Support this! - widgets = [] - found = widget.child(name) - if found: - widgets.append(found) - for child in widget.children(): - widgets += self.find_widgets(child, name) - return widgets + + """ + Find within the given 'widget' (a DOM node) the widget with the given + 'name'. + """ + + return widget.getElementsByTagName(name) # vim: tabstop=4 expandtab shiftwidth=4