# HG changeset patch # User Sylvain Thénault # Date 1251879855 -7200 # Node ID b415bca9a9ed408095cf4542e2e5597a2292361c # Parent 3084bc9ccc64ea7475de4b0630affe1006dcd72f# Parent 096d680c9da2c43afb7c47940b6eef1f4aa17ded backport 3.5 diff -r 3084bc9ccc64 -r b415bca9a9ed ext/xhtml2fo.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ext/xhtml2fo.py Wed Sep 02 10:24:15 2009 +0200 @@ -0,0 +1,142 @@ +from cubicweb.utils import can_do_pdf_conversion +assert can_do_pdf_conversion() + +from xml.etree.ElementTree import QName, fromstring +from pysixt.standard.xhtml_xslfo.transformer import XHTML2FOTransformer +from pysixt.utils.xslfo.standard import cm +from pysixt.utils.xslfo import SimplePageMaster +from pysixt.standard.xhtml_xslfo.default_styling import default_styles +from pysixt.standard.xhtml_xslfo import XHTML_NS + + +class ReportTransformer(XHTML2FOTransformer): + """ + Class transforming an XHTML input tree into a FO document + displaying reports (one report for each
+ element in the input tree. + """ + + def __init__(self, section, + page_width=21.0, page_height=29.7, + margin_top=1.0, margin_bottom=1.0, + margin_left=1.0, margin_right=1.0, + header_footer_height=0.75, + standard_font_size=11.0, default_lang=u"fr" ): + """ + Initializes a transformer turning an XHTML input tree + containing
elements representing + main content sections into a FO output tree displaying the + reports. + + page_width: float - width of the page (in cm) + page_height: float - height of the page (in cm) + margin_top: float - top margin of the page (in cm) + margin_bottom: float - bottom margin of the page (in cm) + margin_left: float - left margin of the page (in cm) + margin_right: float - right margin of the page (in cm) + header_footer_height: float - height of the header or the footer of the + page that the page number (if any) will be + inserted in. + standard_font_size: float - standard size of the font (in pt) + default_lang: u"" - default language (used for hyphenation) + """ + self.section = section + self.page_width = page_width + self.page_height = page_height + + self.page_tmargin = margin_top + self.page_bmargin = margin_bottom + self.page_lmargin = margin_left + self.page_rmargin = margin_right + + self.hf_height = header_footer_height + + self.font_size = standard_font_size + self.lang = default_lang + + XHTML2FOTransformer.__init__(self) + + + def define_pagemasters(self): + """ + Defines the page masters for the FO output document. + """ + pm = SimplePageMaster(u"page-report") + pm.set_page_dims( self.page_width*cm, self.page_height*cm ) + pm.set_page_margins({u'top' : self.page_tmargin*cm, + u'bottom': self.page_bmargin*cm, + u'left' : self.page_lmargin*cm, + u'right' : self.page_rmargin*cm }) + pm.add_peripheral_region(u"end",self.hf_height) + dims = {} + dims[u"bottom"] = self.hf_height + 0.25 + pm.set_main_region_margins(dims) + return [pm] + + def _visit_report(self, in_elt, _out_elt, params): + """ + Specific visit function for the input
elements whose class is + "report". The _root_visit method of this class selects these input + elements and asks the process of these elements with this specific + visit function. + """ + + ps = self.create_pagesequence(u"page-report") + props = { u"force-page-count": u"no-force", + u"initial-page-number": u"1", + u"format": u"1", } + self._output_properties(ps,props) + + sc = self.create_staticcontent(ps, u"end") + sc_bl = self.create_block(sc) + attrs = { u"hyphenate": u"false", } + attrs[u"font-size"] = u"%.1fpt" %(self.font_size*0.7) + attrs[u"language"] = self.lang + attrs[u"text-align"] = u"center" + self._output_properties(sc_bl,attrs) + sc_bl.text = u"Page" + u" " # ### Should be localised! + pn = self.create_pagenumber(sc_bl) + pn.tail = u"/" + lpn = self.create_pagenumbercitation( sc_bl, + u"last-block-of-report-%d" % params[u"context_pos"] + ) + + + fl = self.create_flow(ps,u"body") + bl = self.create_block(fl) + + # Sets on the highest block element the properties of the XHTML body + # element. These properties (at the least the inheritable ones) will + # be inherited by all the future FO elements. + bodies = list(self.in_tree.getiterator(QName(XHTML_NS,u"body"))) + if len(bodies) > 0: + attrs = self._extract_properties([bodies[0]]) + else: + attrs = default_styles[u"body"].copy() + attrs[u"font-size"] = u"%.1fpt" %self.font_size + attrs[u"language"] = self.lang + self._output_properties(bl,attrs) + + # Processes the report content + self._copy_text(in_elt,bl) + self._process_nodes(in_elt.getchildren(),bl) + + # Inserts an empty block at the end of the report in order to be able + # to compute the last page number of this report. + last_bl = self.create_block(bl) + props = { u"keep-with-previous": u"always", } + props[u"id"] = u"last-block-of-report-%d" % params[u"context_pos"] + self._output_properties(last_bl,props) + + + def _root_visit(self): + """ + Visit function called when starting the process of the input tree. + """ + content = [ d for d in self.in_tree.getiterator(QName(XHTML_NS,u"div")) + if d.get(u"id") == self.section ] + # Asks the process of the report elements with a specific visit + # function + self._process_nodes(content, self.fo_root, + with_function=self._visit_report) + diff -r 3084bc9ccc64 -r b415bca9a9ed server/session.py --- a/server/session.py Wed Sep 02 10:22:47 2009 +0200 +++ b/server/session.py Wed Sep 02 10:24:15 2009 +0200 @@ -153,8 +153,11 @@ if row[0] == targeteid: break else: - raise Exception('cache inconsistency for %s %s %s %s' % - (eid, rtype, role, targeteid)) + # this may occurs if the cache has been filed by a hook + # after the database update + self.debug('cache inconsistency for %s %s %s %s', eid, rtype, + role, targeteid) + return del rset.rows[idx] if isinstance(rset.description, list): # else description not set del rset.description[idx] diff -r 3084bc9ccc64 -r b415bca9a9ed web/data/cubicweb.ajax.js --- a/web/data/cubicweb.ajax.js Wed Sep 02 10:22:47 2009 +0200 +++ b/web/data/cubicweb.ajax.js Wed Sep 02 10:24:15 2009 +0200 @@ -63,7 +63,12 @@ roundedCorners(node); } loadDynamicFragments(node); - jQuery(CubicWeb).trigger('ajax-loaded'); + // XXX simulates document.ready, but the former + // only runs once, this one potentially many times + // we probably need to unbind the fired events + // When this is done, jquery.treeview.js (for instance) + // can be unpatched. + jQuery(CubicWeb).trigger('ajax-loaded'); } /* cubicweb loadxhtml plugin to make jquery handle xhtml response @@ -390,9 +395,10 @@ /* convenience function that returns a DOM node based on req's result. */ function getDomFromResponse(response) { if (typeof(response) == 'string') { - return html2dom(response); + var doc = html2dom(response); + } else { + var doc = response.documentElement; } - var doc = response.documentElement; var children = doc.childNodes; if (!children.length) { // no child (error cases) => return the whole document diff -r 3084bc9ccc64 -r b415bca9a9ed web/data/cubicweb.widgets.js --- a/web/data/cubicweb.widgets.js Wed Sep 02 10:22:47 2009 +0200 +++ b/web/data/cubicweb.widgets.js Wed Sep 02 10:24:15 2009 +0200 @@ -181,13 +181,6 @@ } } -Widgets.TreeView = defclass("TreeView", null, { - __init__: function(wdgnode) { - jQuery(wdgnode).treeview({toggle: toggleTree, - prerendered: true}); - } -}); - /* widget based on SIMILE's timeline widget * http://code.google.com/p/simile-widgets/ diff -r 3084bc9ccc64 -r b415bca9a9ed web/data/jquery.treeview.js --- a/web/data/jquery.treeview.js Wed Sep 02 10:22:47 2009 +0200 +++ b/web/data/jquery.treeview.js Wed Sep 02 10:24:15 2009 +0200 @@ -1,6 +1,6 @@ /* * Treeview 1.4 - jQuery plugin to hide and show branches of a tree - * + * * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ * http://docs.jquery.com/Plugins/Treeview * @@ -11,5 +11,6 @@ * http://www.gnu.org/licenses/gpl.html * * Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $ + * updated by Aurelien Campeas, 2009-09-01, to handle top-level ajax loads * - */;(function($){$.extend($.fn,{swapClass:function(c1,c2){var c1Elements=this.filter('.'+c1);this.filter('.'+c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass:function(c1,c2){return this.filter('.'+c1).removeClass(c1).addClass(c2).end();},hoverClass:function(className){className=className||"hover";return this.hover(function(){$(this).addClass(className);},function(){$(this).removeClass(className);});},heightToggle:function(animated,callback){animated?this.animate({height:"toggle"},animated,callback):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();if(callback)callback.apply(this,arguments);});},heightHide:function(animated,callback){if(animated){this.animate({height:"hide"},animated,callback);}else{this.hide();if(callback)this.each(callback);}},prepareBranches:function(settings){if(!settings.prerendered){this.filter(":last-child:not(ul)").addClass(CLASSES.last);this.filter((settings.collapsed?"":"."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide();}return this.filter(":has(>ul)");},applyClasses:function(settings,toggler){this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){toggler.apply($(this).next());}).add($("a",this)).hoverClass();if(!settings.prerendered){this.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last,CLASSES.lastExpandable);this.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last,CLASSES.lastCollapsable);this.prepend("
").find("div."+CLASSES.hitarea).each(function(){var classes="";$.each($(this).parent().attr("class").split(" "),function(){classes+=this+"-hitarea ";});$(this).addClass(classes);});}this.find("div."+CLASSES.hitarea).click(toggler);},treeview:function(settings){settings=$.extend({cookieId:"treeview"},settings);if(settings.add){return this.trigger("add",[settings.add]);}if(settings.toggle){var callback=settings.toggle;settings.toggle=function(){return callback.apply($(this).parent()[0],arguments);};}function treeController(tree,control){function handler(filter){return function(){toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){return filter?$(this).parent("."+filter).length:true;}));return false;};}$("a:eq(0)",control).click(handler(CLASSES.collapsable));$("a:eq(1)",control).click(handler(CLASSES.expandable));$("a:eq(2)",control).click(handler());}function toggler(){$(this).parent().find(">.hitarea").swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().swapClass(CLASSES.collapsable,CLASSES.expandable).swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightToggle(settings.animated,settings.toggle);if(settings.unique){$(this).parent().siblings().find(">.hitarea").replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().replaceClass(CLASSES.collapsable,CLASSES.expandable).replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightHide(settings.animated,settings.toggle);}}function serialize(){function binary(arg){return arg?1:0;}var data=[];branches.each(function(i,e){data[i]=$(e).is(":has(>ul:visible)")?1:0;});$.cookie(settings.cookieId,data.join(""));}function deserialize(){var stored=$.cookie(settings.cookieId);if(stored){var data=stored.split("");branches.each(function(i,e){$(e).find(">ul")[parseInt(data[i])?"show":"hide"]();});}}this.addClass("treeview");var branches=this.find("li").prepareBranches(settings);switch(settings.persist){case"cookie":var toggleCallback=settings.toggle;settings.toggle=function(){serialize();if(toggleCallback){toggleCallback.apply(this,arguments);}};deserialize();break;case"location":var current=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase();});if(current.length){current.addClass("selected").parents("ul, li").add(current.next()).show();}break;}branches.applyClasses(settings,toggler);if(settings.control){treeController(this,settings.control);$(settings.control).show();}return this.bind("add",function(event,branches){$(branches).prev().removeClass(CLASSES.last).removeClass(CLASSES.lastCollapsable).removeClass(CLASSES.lastExpandable).find(">.hitarea").removeClass(CLASSES.lastCollapsableHitarea).removeClass(CLASSES.lastExpandableHitarea);$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler);});}});var CLASSES=$.fn.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"};$.fn.Treeview=$.fn.treeview;})(jQuery); \ No newline at end of file + */;(function($){$.extend($.fn,{swapClass:function(c1,c2){var c1Elements=this.filter('.'+c1);this.filter('.'+c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass:function(c1,c2){return this.filter('.'+c1).removeClass(c1).addClass(c2).end();},hoverClass:function(className){className=className||"hover";return this.hover(function(){$(this).addClass(className);},function(){$(this).removeClass(className);});},heightToggle:function(animated,callback){animated?this.animate({height:"toggle"},animated,callback):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();if(callback)callback.apply(this,arguments);});},heightHide:function(animated,callback){if(animated){this.animate({height:"hide"},animated,callback);}else{this.hide();if(callback)this.each(callback);}},prepareBranches:function(settings){if(!settings.prerendered){this.filter(":last-child:not(ul)").addClass(CLASSES.last);this.filter((settings.collapsed?"":"."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide();}return this.filter(":has(>ul)");},applyClasses:function(settings,toggler){this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){toggler.apply($(this).next());}).add($("a",this)).hoverClass();if(!settings.prerendered){this.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last,CLASSES.lastExpandable);this.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last,CLASSES.lastCollapsable);this.prepend("
").find("div."+CLASSES.hitarea).each(function(){var classes="";$.each($(this).parent().attr("class").split(" "),function(){classes+=this+"-hitarea ";});$(this).addClass(classes);});}this.find("div."+CLASSES.hitarea).click(toggler);},treeview:function(settings){if(this.attr('cubicweb:type')=='prepared-treeview'){return this;}this.attr('cubicweb:type','prepared-treeview');settings=$.extend({cookieId:"treeview"},settings);if(settings.add){return this.trigger("add",[settings.add]);}if(settings.toggle){var callback=settings.toggle;settings.toggle=function(){return callback.apply($(this).parent()[0],arguments);};}function treeController(tree,control){function handler(filter){return function(){toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){return filter?$(this).parent("."+filter).length:true;}));return false;};}$("a:eq(0)",control).click(handler(CLASSES.collapsable));$("a:eq(1)",control).click(handler(CLASSES.expandable));$("a:eq(2)",control).click(handler());}function toggler(){$(this).parent().find(">.hitarea").swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().swapClass(CLASSES.collapsable,CLASSES.expandable).swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightToggle(settings.animated,settings.toggle);if(settings.unique){$(this).parent().siblings().find(">.hitarea").replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().replaceClass(CLASSES.collapsable,CLASSES.expandable).replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightHide(settings.animated,settings.toggle);}}function serialize(){function binary(arg){return arg?1:0;}var data=[];branches.each(function(i,e){data[i]=$(e).is(":has(>ul:visible)")?1:0;});$.cookie(settings.cookieId,data.join(""));}function deserialize(){var stored=$.cookie(settings.cookieId);if(stored){var data=stored.split("");branches.each(function(i,e){$(e).find(">ul")[parseInt(data[i])?"show":"hide"]();});}}this.addClass("treeview");var branches=this.find("li").prepareBranches(settings);switch(settings.persist){case"cookie":var toggleCallback=settings.toggle;settings.toggle=function(){serialize();if(toggleCallback){toggleCallback.apply(this,arguments);}};deserialize();break;case"location":var current=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase();});if(current.length){current.addClass("selected").parents("ul, li").add(current.next()).show();}break;}branches.applyClasses(settings,toggler);if(settings.control){treeController(this,settings.control);$(settings.control).show();}return this.bind("add",function(event,branches){$(branches).prev().removeClass(CLASSES.last).removeClass(CLASSES.lastCollapsable).removeClass(CLASSES.lastExpandable).find(">.hitarea").removeClass(CLASSES.lastCollapsableHitarea).removeClass(CLASSES.lastExpandableHitarea);$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler);});}});var CLASSES=$.fn.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"};$.fn.Treeview=$.fn.treeview;})(jQuery); \ No newline at end of file diff -r 3084bc9ccc64 -r b415bca9a9ed web/test/unittest_pdf.py --- a/web/test/unittest_pdf.py Wed Sep 02 10:22:47 2009 +0200 +++ b/web/test/unittest_pdf.py Wed Sep 02 10:24:15 2009 +0200 @@ -7,7 +7,7 @@ from cubicweb.utils import can_do_pdf_conversion -from cubicweb.web.xhtml2fo import ReportTransformer +from cubicweb.ext.xhtml2fo import ReportTransformer DATADIR = osp.join(osp.dirname(__file__), 'data') diff -r 3084bc9ccc64 -r b415bca9a9ed web/views/basetemplates.py --- a/web/views/basetemplates.py Wed Sep 02 10:22:47 2009 +0200 +++ b/web/views/basetemplates.py Wed Sep 02 10:24:15 2009 +0200 @@ -270,7 +270,7 @@ from subprocess import Popen as sub from StringIO import StringIO from tempfile import NamedTemporaryFile - from cubicweb.web.xhtml2fo import ReportTransformer + from cubicweb.ext.xhtml2fo import ReportTransformer class PdfMainTemplate(TheMainTemplate): id = 'pdf-main-template' @@ -279,7 +279,8 @@ """build the standard view, then when it's all done, convert xhtml to pdf """ super(PdfMainTemplate, self).call(view) - pdf = self.to_pdf(self._stream) + section = self.req.form.pop('section', 'contentmain') + pdf = self.to_pdf(self._stream, section) self.req.set_content_type('application/pdf', filename='report.pdf') self.binary = True self.w = None @@ -287,7 +288,7 @@ # pylint needs help self.w(pdf) - def to_pdf(self, stream, section='contentmain'): + def to_pdf(self, stream, section): # XXX see ticket/345282 stream = stream.getvalue().replace(' ', ' ').encode('utf-8') xmltree = ElementTree() diff -r 3084bc9ccc64 -r b415bca9a9ed web/views/boxes.py --- a/web/views/boxes.py Wed Sep 02 10:22:47 2009 +0200 +++ b/web/views/boxes.py Wed Sep 02 10:24:15 2009 +0200 @@ -140,10 +140,13 @@ for tr in entity.possible_transitions(): url = entity.absolute_url(vid='statuschange', treid=tr.eid) menu_items.append(self.mk_action(_(tr.name), url)) - wfurl = self.build_url('cwetype/%s'%entity.e_schema, vid='workflow') - menu_items.append(self.mk_action(_('view workflow'), wfurl)) - wfurl = entity.absolute_url(vid='wfhistory') - menu_items.append(self.mk_action(_('view history'), wfurl)) + # don't propose to see wf if user can't pass any transition + if menu_items: + wfurl = self.build_url('cwetype/%s'%entity.e_schema, vid='workflow') + menu_items.append(self.mk_action(_('view workflow'), wfurl)) + if entity.workflow_history: + wfurl = entity.absolute_url(vid='wfhistory') + menu_items.append(self.mk_action(_('view history'), wfurl)) box.append(BoxMenu(menu_title, menu_items)) return None diff -r 3084bc9ccc64 -r b415bca9a9ed web/views/editforms.py --- a/web/views/editforms.py Wed Sep 02 10:22:47 2009 +0200 +++ b/web/views/editforms.py Wed Sep 02 10:24:15 2009 +0200 @@ -20,7 +20,8 @@ from cubicweb.utils import make_uid from cubicweb.view import EntityView from cubicweb.common import tags -from cubicweb.web import INTERNAL_FIELD_VALUE, stdmsgs, eid_param, uicfg +from cubicweb.web import INTERNAL_FIELD_VALUE, RequestError, stdmsgs, eid_param +from cubicweb.web import uicfg from cubicweb.web.form import FormViewMixIn, FieldNotFound from cubicweb.web.formfields import guess_field from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton @@ -327,13 +328,13 @@ """creation view for an entity""" etype = kwargs.pop('etype', self.req.form.get('etype')) try: - entity = self.vreg['etypes'].etype_class(etype)(self.req) - except: - self.w(self.req._('no such entity type %s') % etype) - else: - self.initialize_varmaker() - entity.eid = self.varmaker.next() - self.render_form(entity) + etype = self.vreg.case_insensitive_etypes[etype.lower()] + except KeyError: + raise RequestError(self.req._('no such entity type %s') % etype) + entity = self.vreg['etypes'].etype_class(etype)(self.req) + self.initialize_varmaker() + entity.eid = self.varmaker.next() + self.render_form(entity) def form_title(self, entity): """the form view title""" diff -r 3084bc9ccc64 -r b415bca9a9ed web/views/treeview.py --- a/web/views/treeview.py Wed Sep 02 10:22:47 2009 +0200 +++ b/web/views/treeview.py Wed Sep 02 10:24:15 2009 +0200 @@ -32,17 +32,22 @@ if treeid is None: self.warning('Tree state won\'t be properly restored after next reload') treeid = make_uid('throw away uid') - self.w(u'
    ' % (treeid, self.css_classes)) + toplevel_thru_ajax = self.req.form.pop('treeview_top', False) + toplevel = toplevel_thru_ajax or (initial_load and not self.req.form.get('fname')) + ulid = ' ' + if toplevel: + ulid = ' id="tree-%s"' % treeid + self.w(u'' % (ulid, self.css_classes)) for rowidx in xrange(len(self.rset)): self.wview(self.itemvid, self.rset, row=rowidx, col=0, vid=subvid, parentvid=self.id, treeid=treeid) self.w(u'
') - if initial_load and not self.req.form.get('fname'): + if toplevel: self.req.add_css('jquery.treeview.css') self.req.add_js(('cubicweb.ajax.js', 'cubicweb.widgets.js', 'jquery.treeview.js')) self.req.html_headers.add_onload(u""" -jQuery("#tree-%s").treeview({toggle: toggleTree, prerendered: true});""" % treeid) - +jQuery("#tree-%s").treeview({toggle: toggleTree, prerendered: true});""" % treeid, + jsoncall=toplevel_thru_ajax) class FileTreeView(TreeView): """specific version of the treeview to display file trees @@ -91,14 +96,15 @@ (each item should be expandable if it's not a tree leaf) """ id = 'treeitemview' - __select__ = EntityView.__select__ & implements(ITree) # XXX + default_branch_state_is_open = False + __select__ = EntityView.__select__ & implements(ITree) def open_state(self, eeid, treeid): cookies = self.req.get_cookie() treestate = cookies.get(treecookiename(treeid)) if treestate: return str(eeid) in treestate.value.split(';') - return False + return self.default_branch_state_is_open def cell_call(self, row, col, treeid, vid='oneline', parentvid='treeview'): w = self.w diff -r 3084bc9ccc64 -r b415bca9a9ed web/xhtml2fo.py --- a/web/xhtml2fo.py Wed Sep 02 10:22:47 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -from cubicweb.utils import can_do_pdf_conversion -assert can_do_pdf_conversion() - -from xml.etree.ElementTree import QName, fromstring -from pysixt.standard.xhtml_xslfo.transformer import XHTML2FOTransformer -from pysixt.utils.xslfo.standard import cm -from pysixt.utils.xslfo import SimplePageMaster -from pysixt.standard.xhtml_xslfo.default_styling import default_styles -from pysixt.standard.xhtml_xslfo import XHTML_NS - - -class ReportTransformer(XHTML2FOTransformer): - """ - Class transforming an XHTML input tree into a FO document - displaying reports (one report for each
- element in the input tree. - """ - - def __init__(self, section, - page_width=21.0, page_height=29.7, - margin_top=1.0, margin_bottom=1.0, - margin_left=1.0, margin_right=1.0, - header_footer_height=0.75, - standard_font_size=11.0, default_lang=u"fr" ): - """ - Initializes a transformer turning an XHTML input tree - containing
elements representing - main content sections into a FO output tree displaying the - reports. - - page_width: float - width of the page (in cm) - page_height: float - height of the page (in cm) - margin_top: float - top margin of the page (in cm) - margin_bottom: float - bottom margin of the page (in cm) - margin_left: float - left margin of the page (in cm) - margin_right: float - right margin of the page (in cm) - header_footer_height: float - height of the header or the footer of the - page that the page number (if any) will be - inserted in. - standard_font_size: float - standard size of the font (in pt) - default_lang: u"" - default language (used for hyphenation) - """ - self.section = section - self.page_width = page_width - self.page_height = page_height - - self.page_tmargin = margin_top - self.page_bmargin = margin_bottom - self.page_lmargin = margin_left - self.page_rmargin = margin_right - - self.hf_height = header_footer_height - - self.font_size = standard_font_size - self.lang = default_lang - - XHTML2FOTransformer.__init__(self) - - - def define_pagemasters(self): - """ - Defines the page masters for the FO output document. - """ - pm = SimplePageMaster(u"page-report") - pm.set_page_dims( self.page_width*cm, self.page_height*cm ) - pm.set_page_margins({u'top' : self.page_tmargin*cm, - u'bottom': self.page_bmargin*cm, - u'left' : self.page_lmargin*cm, - u'right' : self.page_rmargin*cm }) - pm.add_peripheral_region(u"end",self.hf_height) - dims = {} - dims[u"bottom"] = self.hf_height + 0.25 - pm.set_main_region_margins(dims) - return [pm] - - def _visit_report(self, in_elt, _out_elt, params): - """ - Specific visit function for the input
elements whose class is - "report". The _root_visit method of this class selects these input - elements and asks the process of these elements with this specific - visit function. - """ - - ps = self.create_pagesequence(u"page-report") - props = { u"force-page-count": u"no-force", - u"initial-page-number": u"1", - u"format": u"1", } - self._output_properties(ps,props) - - sc = self.create_staticcontent(ps, u"end") - sc_bl = self.create_block(sc) - attrs = { u"hyphenate": u"false", } - attrs[u"font-size"] = u"%.1fpt" %(self.font_size*0.7) - attrs[u"language"] = self.lang - attrs[u"text-align"] = u"center" - self._output_properties(sc_bl,attrs) - sc_bl.text = u"Page" + u" " # ### Should be localised! - pn = self.create_pagenumber(sc_bl) - pn.tail = u"/" - lpn = self.create_pagenumbercitation( sc_bl, - u"last-block-of-report-%d" % params[u"context_pos"] - ) - - - fl = self.create_flow(ps,u"body") - bl = self.create_block(fl) - - # Sets on the highest block element the properties of the XHTML body - # element. These properties (at the least the inheritable ones) will - # be inherited by all the future FO elements. - bodies = list(self.in_tree.getiterator(QName(XHTML_NS,u"body"))) - if len(bodies) > 0: - attrs = self._extract_properties([bodies[0]]) - else: - attrs = default_styles[u"body"].copy() - attrs[u"font-size"] = u"%.1fpt" %self.font_size - attrs[u"language"] = self.lang - self._output_properties(bl,attrs) - - # Processes the report content - self._copy_text(in_elt,bl) - self._process_nodes(in_elt.getchildren(),bl) - - # Inserts an empty block at the end of the report in order to be able - # to compute the last page number of this report. - last_bl = self.create_block(bl) - props = { u"keep-with-previous": u"always", } - props[u"id"] = u"last-block-of-report-%d" % params[u"context_pos"] - self._output_properties(last_bl,props) - - - def _root_visit(self): - """ - Visit function called when starting the process of the input tree. - """ - content = [ d for d in self.in_tree.getiterator(QName(XHTML_NS,u"div")) - if d.get(u"id") == self.section ] - # Asks the process of the report elements with a specific visit - # function - self._process_nodes(content, self.fo_root, - with_function=self._visit_report) -