# HG changeset patch # User Sylvain Thénault # Date 1245757578 -7200 # Node ID 476a75ede2cc8a2cf7099e6db186741f231e4970 # Parent d4c2fb633062780fa20e1cc320f3746e49701561# Parent 6645e18e8c934a4395b38e07e3041b1fa036159a merge and add missing import in schema.py diff -r 6645e18e8c93 -r 476a75ede2cc .hgtags --- a/.hgtags Tue Jun 23 13:43:39 2009 +0200 +++ b/.hgtags Tue Jun 23 13:46:18 2009 +0200 @@ -40,3 +40,4 @@ 4003d24974f15f17bd03b7efd6a5047cad4e4c41 cubicweb-debian-version-3_2_3-1 2d7d3062ca03d4b4144100013dc4ab7f9d9cb25e cubicweb-version-3_3_0 07214e923e75c8f0490e609e9bee0f4964b87114 cubicweb-debian-version-3_3_0-1 +a356da3e725bfcb59d8b48a89d04be05ea261fd3 3.3.1 diff -r 6645e18e8c93 -r 476a75ede2cc __pkginfo__.py --- a/__pkginfo__.py Tue Jun 23 13:43:39 2009 +0200 +++ b/__pkginfo__.py Tue Jun 23 13:46:18 2009 +0200 @@ -7,7 +7,7 @@ distname = "cubicweb" modname = "cubicweb" -numversion = (3, 3, 0) +numversion = (3, 3, 1) version = '.'.join(str(num) for num in numversion) license = 'LGPL v2' diff -r 6645e18e8c93 -r 476a75ede2cc common/migration.py --- a/common/migration.py Tue Jun 23 13:43:39 2009 +0200 +++ b/common/migration.py Tue Jun 23 13:46:18 2009 +0200 @@ -17,6 +17,8 @@ from logilab.common.decorators import cached from logilab.common.configuration import REQUIRED, read_old_config +from cubicweb import ConfigurationError + def migration_files(config, toupgrade): """return an orderer list of path of scripts to execute to upgrade @@ -328,18 +330,18 @@ self.config.add_cubes(newcubes) return newcubes - def cmd_remove_cube(self, cube): + def cmd_remove_cube(self, cube, removedeps=False): + if removedeps: + toremove = self.config.expand_cubes([cube]) + else: + toremove = (cube,) origcubes = self.config._cubes - basecubes = list(origcubes) - for pkg in self.config.expand_cubes([cube]): - try: - basecubes.remove(pkg) - except ValueError: - continue + basecubes = [c for c in origcubes if not c in toremove] self.config._cubes = tuple(self.config.expand_cubes(basecubes)) removed = [p for p in origcubes if not p in self.config._cubes] - assert cube in removed, \ - "can't remove cube %s, used as a dependancy" % cube + if not cube in removed: + raise ConfigurationError("can't remove cube %s, " + "used as a dependency" % cube) return removed def rewrite_configuration(self): diff -r 6645e18e8c93 -r 476a75ede2cc common/mixins.py --- a/common/mixins.py Tue Jun 23 13:43:39 2009 +0200 +++ b/common/mixins.py Tue Jun 23 13:46:18 2009 +0200 @@ -191,11 +191,18 @@ return rset.get_entity(0, 0) return None - def change_state(self, stateeid, trcomment=None, trcommentformat=None): + def change_state(self, state, trcomment=None, trcommentformat=None): """change the entity's state according to a state defined in given parameters """ - assert not isinstance(stateeid, basestring), 'change_state wants a state eid' + if isinstance(state, basestring): + state = self.wf_state(state) + assert state is not None, 'not a %s state: %s' % (self.id, state) + if hasattr(state, 'eid'): + stateeid = state.eid + else: + stateeid = state + stateeid = typed_eid(stateeid) if trcomment: self.req.set_shared_data('trcomment', trcomment) if trcommentformat: diff -r 6645e18e8c93 -r 476a75ede2cc debian/changelog --- a/debian/changelog Tue Jun 23 13:43:39 2009 +0200 +++ b/debian/changelog Tue Jun 23 13:46:18 2009 +0200 @@ -1,3 +1,9 @@ +cubicweb (3.3.1-1) unstable; urgency=low + + * new upstream release + + -- Aurélien Campéas Mon, 22 Jun 2009 12:00:00 +0200 + cubicweb (3.3.0-1) unstable; urgency=low * new upstream release diff -r 6645e18e8c93 -r 476a75ede2cc devtools/fill.py --- a/devtools/fill.py Tue Jun 23 13:43:39 2009 +0200 +++ b/devtools/fill.py Tue Jun 23 13:46:18 2009 +0200 @@ -10,7 +10,7 @@ from random import randint, choice from copy import deepcopy -from datetime import datetime, date, timedelta +from datetime import datetime, date, time#timedelta from decimal import Decimal from yams.constraints import (SizeConstraint, StaticVocabularyConstraint, @@ -163,7 +163,7 @@ def generate_time(self, attrname, index): """generates a random time (format is ' HH:MM')""" - return timedelta(0, 11, index%60) #'11:%02d' % (index % 60) + return time(11, index%60) #'11:%02d' % (index % 60) def generate_datetime(self, attrname, index): """generates a random date (format is 'yyyy-mm-dd HH:MM')""" diff -r 6645e18e8c93 -r 476a75ede2cc entity.py --- a/entity.py Tue Jun 23 13:43:39 2009 +0200 +++ b/entity.py Tue Jun 23 13:46:18 2009 +0200 @@ -398,7 +398,7 @@ path = etype.lower() if mainattr != 'eid': value = getattr(self, mainattr) - if value is None: + if value is None or unicode(value) == u'': mainattr = 'eid' path += '/eid' elif needcheck: diff -r 6645e18e8c93 -r 476a75ede2cc interfaces.py --- a/interfaces.py Tue Jun 23 13:43:39 2009 +0200 +++ b/interfaces.py Tue Jun 23 13:46:18 2009 +0200 @@ -197,6 +197,14 @@ """interface for items that do have a begin date 'start' and an end date 'stop' """ + @property + def start(self): + """return start date""" + + @property + def stop(self): + """return stop state""" + class ICalendarViews(Interface): """calendar views interface""" def matching_dates(self, begin, end): diff -r 6645e18e8c93 -r 476a75ede2cc schema.py --- a/schema.py Tue Jun 23 13:43:39 2009 +0200 +++ b/schema.py Tue Jun 23 13:46:18 2009 +0200 @@ -6,8 +6,10 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode import re +from os.path import join from logging import getLogger from warnings import warn @@ -34,7 +36,7 @@ BASEGROUPS = ('managers', 'users', 'guests', 'owners') -LOGGER = getLogger('cubicweb.schemaloader') +_LOGGER = getLogger('cubicweb.schemaloader') # schema entities created from serialized schema have an eid rproperty ybo.ETYPE_PROPERTIES += ('eid',) @@ -636,8 +638,8 @@ raise RQLSyntaxError(expression) for mainvar in mainvars.split(','): if len(self.rqlst.defined_vars[mainvar].references()) <= 2: - LOGGER.warn('You did not use the %s variable in your RQL expression %s', - mainvar, self) + _LOGGER.warn('You did not use the %s variable in your RQL ' + 'expression %s', mainvar, self) def __str__(self): return self.full_rql @@ -904,9 +906,9 @@ def _load_definition_files(self, cubes=None): # bootstraping, ignore cubes - for filepath in self.include_schema_files('bootstrap'): - self.info('loading %s', filepath) - self.handle_file(filepath) + filepath = join(self.lib_directory, 'bootstrap.py') + self.info('loading %s', filepath) + self.handle_file(filepath) def unhandled_file(self, filepath): """called when a file without handler associated has been found""" @@ -930,10 +932,10 @@ return super(CubicWebSchemaLoader, self).load(config, path=path, **kwargs) def _load_definition_files(self, cubes): - for filepath in (self.include_schema_files('bootstrap') - + self.include_schema_files('base') - + self.include_schema_files('workflow') - + self.include_schema_files('Bookmark')): + for filepath in (join(self.lib_directory, 'bootstrap.py'), + join(self.lib_directory, 'base.py'), + join(self.lib_directory, 'workflow.py'), + join(self.lib_directory, 'Bookmark.py')): self.info('loading %s', filepath) self.handle_file(filepath) for cube in cubes: diff -r 6645e18e8c93 -r 476a75ede2cc server/migractions.py --- a/server/migractions.py Tue Jun 23 13:43:39 2009 +0200 +++ b/server/migractions.py Tue Jun 23 13:46:18 2009 +0200 @@ -523,8 +523,9 @@ self.exec_event_script('postcreate', self.config.cube_dir(pack)) self.commit() - def cmd_remove_cube(self, cube): - removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube(cube) + def cmd_remove_cube(self, cube, removedeps=False): + removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube( + cube, removedeps) if not removedcubes: return fsschema = self.fs_schema diff -r 6645e18e8c93 -r 476a75ede2cc server/schemaserial.py --- a/server/schemaserial.py Tue Jun 23 13:43:39 2009 +0200 +++ b/server/schemaserial.py Tue Jun 23 13:46:18 2009 +0200 @@ -109,7 +109,7 @@ ETYPE_NAME_MAP[etype]) print sql sqlcu.execute(sql) - # other table renaming done once schema has been readen + # other table renaming done once schema has been read # print 'reading schema from the database...' index = {} permsdict = deserialize_ertype_permissions(session) diff -r 6645e18e8c93 -r 476a75ede2cc server/test/unittest_migractions.py --- a/server/test/unittest_migractions.py Tue Jun 23 13:43:39 2009 +0200 +++ b/server/test/unittest_migractions.py Tue Jun 23 13:46:18 2009 +0200 @@ -7,6 +7,7 @@ from logilab.common.testlib import TestCase, unittest_main from cubicweb.devtools.apptest import RepositoryBasedTC, get_versions +from cubicweb import ConfigurationError from cubicweb.schema import CubicWebSchemaLoader from cubicweb.server.sqlutils import SQL_PREFIX from cubicweb.server.repository import Repository @@ -365,7 +366,7 @@ finally: self.mh.cmd_set_size_constraint('CWEType', 'description', None) - def test_add_remove_cube(self): + def test_add_remove_cube_and_deps(self): cubes = set(self.config.cubes()) schema = self.repo.schema self.assertEquals(sorted(schema['see_also']._rproperties.keys()), @@ -374,11 +375,10 @@ ('Note', 'Note'), ('Note', 'Bookmark')])) try: try: - self.mh.cmd_remove_cube('email') + self.mh.cmd_remove_cube('email', removedeps=True) # file was there because it's an email dependancy, should have been removed - cubes.remove('email') - cubes.remove('file') - self.assertEquals(set(self.config.cubes()), cubes) + self.failIf('email' in self.config.cubes()) + self.failIf('file' in self.config.cubes()) for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image', 'sender', 'in_thread', 'reply_to', 'data_format'): self.failIf(ertype in schema, ertype) @@ -392,17 +392,14 @@ self.assertEquals(sorted(schema['see_also'].objects()), ['Bookmark', 'Folder', 'Note']) self.assertEquals(self.execute('Any X WHERE X pkey "system.version.email"').rowcount, 0) self.assertEquals(self.execute('Any X WHERE X pkey "system.version.file"').rowcount, 0) - self.failIf('email' in self.config.cubes()) - self.failIf('file' in self.config.cubes()) except : import traceback traceback.print_exc() raise finally: self.mh.cmd_add_cube('email') - cubes.add('email') - cubes.add('file') - self.assertEquals(set(self.config.cubes()), cubes) + self.failUnless('email' in self.config.cubes()) + self.failUnless('file' in self.config.cubes()) for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image', 'sender', 'in_thread', 'reply_to', 'data_format'): self.failUnless(ertype in schema, ertype) @@ -420,8 +417,6 @@ email_version) self.assertEquals(self.execute('Any V WHERE X value V, X pkey "system.version.file"')[0][0], file_version) - self.failUnless('email' in self.config.cubes()) - self.failUnless('file' in self.config.cubes()) # trick: overwrite self.maxeid to avoid deletion of just reintroduced # types (and their associated tables!) self.maxeid = self.execute('Any MAX(X)')[0][0] @@ -429,6 +424,38 @@ # next test may fail complaining of missing tables self.commit() + + def test_add_remove_cube_no_deps(self): + cubes = set(self.config.cubes()) + schema = self.repo.schema + try: + try: + self.mh.cmd_remove_cube('email') + cubes.remove('email') + self.failIf('email' in self.config.cubes()) + self.failUnless('file' in self.config.cubes()) + for ertype in ('Email', 'EmailThread', 'EmailPart', + 'sender', 'in_thread', 'reply_to'): + self.failIf(ertype in schema, ertype) + except : + import traceback + traceback.print_exc() + raise + finally: + self.mh.cmd_add_cube('email') + self.failUnless('email' in self.config.cubes()) + # trick: overwrite self.maxeid to avoid deletion of just reintroduced + # types (and their associated tables!) + self.maxeid = self.execute('Any MAX(X)')[0][0] + # why this commit is necessary is unclear to me (though without it + # next test may fail complaining of missing tables + self.commit() + + def test_remove_dep_cube(self): + ex = self.assertRaises(ConfigurationError, self.mh.cmd_remove_cube, 'file') + self.assertEquals(str(ex), "can't remove cube file, used as a dependency") + + def test_set_state(self): user = self.session.user self.mh.set_state(user.eid, 'deactivated') diff -r 6645e18e8c93 -r 476a75ede2cc test/unittest_entity.py --- a/test/unittest_entity.py Tue Jun 23 13:43:39 2009 +0200 +++ b/test/unittest_entity.py Tue Jun 23 13:46:18 2009 +0200 @@ -390,6 +390,11 @@ metainf['extid'] = 1234 self.assertEquals(note.absolute_url(), 'http://cubicweb2.com/note/1234') + def test_absolute_url_empty_field(self): + card = self.add_entity('Card', wikiid=u'', title=u'test') + self.assertEquals(card.absolute_url(), + 'http://testing.fr/cubicweb/card/eid/%s' % card.eid) + if __name__ == '__main__': from logilab.common.testlib import unittest_main unittest_main() diff -r 6645e18e8c93 -r 476a75ede2cc web/data/cubicweb.css --- a/web/data/cubicweb.css Tue Jun 23 13:43:39 2009 +0200 +++ b/web/data/cubicweb.css Tue Jun 23 13:46:18 2009 +0200 @@ -1,6 +1,6 @@ /* * :organization: Logilab - * :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. + * :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr */ /***************************************/ @@ -12,7 +12,7 @@ padding :0px; } -html, body { +html, body { background: #e2e2e2; } @@ -277,8 +277,8 @@ position: relative; min-height: 800px; } - -table#mainLayout{ + +table#mainLayout{ margin:0px 3px; } @@ -321,7 +321,7 @@ /* boxes */ div.navboxes { - margin-top: 8px; + margin-top: 8px; } div.boxFrame { @@ -459,9 +459,9 @@ max-width: 50em; } -ul.sideBox li{ +ul.sideBox li{ list-style: none; - background: none; + background: none; padding: 0px 0px 1px 1px; } @@ -576,7 +576,7 @@ div.primaryRight{ float:right; - + } div.metadata { @@ -603,7 +603,7 @@ padding-bottom:0.4px } -div.row span.label{ +div.row span.label{ padding-right:1em } @@ -772,20 +772,20 @@ /* addcombobox */ /***************************************/ -input#newopt{ - width:120px ; +input#newopt{ + width:120px ; display:block; float:left; } -div#newvalue{ +div#newvalue{ margin-top:2px; } #add_newopt{ background: #fffff8 url("go.png") 50% 50% no-repeat; width: 20px; - line-height: 20px; + line-height: 20px; display:block; float:left; } @@ -794,7 +794,7 @@ /* buttons */ /***************************************/ -input.button{ +input.button{ margin: 1em 1em 0px 0px; border: 1px solid #edecd2; border-color:#edecd2 #cfceb7 #cfceb7 #edecd2; @@ -838,7 +838,7 @@ font-weight: bold; } -input.validateButton { +input.validateButton { margin: 1em 1em 0px 0px; border: 1px solid #edecd2; border-color:#edecd2 #cfceb7 #cfceb7 #edecd2; diff -r 6645e18e8c93 -r 476a75ede2cc web/data/cubicweb.facets.css --- a/web/data/cubicweb.facets.css Tue Jun 23 13:43:39 2009 +0200 +++ b/web/data/cubicweb.facets.css Tue Jun 23 13:46:18 2009 +0200 @@ -1,7 +1,7 @@ #filterbox fieldset{ margin: 0px; padding: 0px; -} +} div.facet { margin-bottom: 8px; @@ -14,11 +14,11 @@ font-size: 80%; color: #000; margin-bottom: 2px; - cursor: pointer; + cursor: pointer; font: bold 100% Georgia; } -div.facetTitle a { +div.facetTitle a { padding-left: 10px; background: transparent url("puce.png") 0% 50% no-repeat; } @@ -26,12 +26,12 @@ div.facetBody { } -.opened{ - color: #000 !important; +.opened{ + color: #000 !important; } div.overflowed{ - height: 12em; + height: 12em; overflow-y: auto; } @@ -50,12 +50,12 @@ } div.facetValue img{ - float: left; + float: left; background: #fff; } div.facetValue a { - margin-left: 20px; + margin-left: 20px; display: block; margin-top: -6px; /* FIXME why do we need this ? */ } @@ -78,11 +78,11 @@ } -div.facetCheckBox{ +div.facetCheckBox{ line-height:0.8em; } -.facet input{ +.facet input{ margin-top:3px; border:1px solid #ccc; font-size:11px; diff -r 6645e18e8c93 -r 476a75ede2cc web/data/cubicweb.htmlhelpers.js --- a/web/data/cubicweb.htmlhelpers.js Tue Jun 23 13:43:39 2009 +0200 +++ b/web/data/cubicweb.htmlhelpers.js Tue Jun 23 13:46:18 2009 +0200 @@ -247,6 +247,11 @@ } } +function limitTextAreaSize(textarea, size) { + var $area = jQuery(textarea); + $area.val($area.val().slice(0, size)); +} + //============= page loading events ==========================================// function roundedCornersOnLoad() { jQuery('div.sideBox').corner('bottom 6px'); diff -r 6645e18e8c93 -r 476a75ede2cc web/data/cubicweb.login.css --- a/web/data/cubicweb.login.css Tue Jun 23 13:43:39 2009 +0200 +++ b/web/data/cubicweb.login.css Tue Jun 23 13:46:18 2009 +0200 @@ -1,7 +1,7 @@ /* styles for the login popup and login form * * :organization: Logilab - * :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. + * :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr */ @@ -12,7 +12,7 @@ width: 26em; padding: 0px 1px 1px; font-weight: bold; - background: #E4EAD8; + background: #E4EAD8; } div#popupLoginBox div#loginContent { @@ -20,7 +20,7 @@ padding: 5px 3px 4px; } -div#loginBox { +div#loginBox { position : absolute; top: 15%; left : 50%; @@ -32,12 +32,12 @@ text-align: center; } -div#loginBox h1 { +div#loginBox h1 { color: #FF7700; font-size: 140%; } -div#loginTitle { +div#loginTitle { color: #fff; font-weight: bold; font-size: 140%; @@ -46,32 +46,32 @@ background: #ff7700 url("banner.png") left top repeat-x; } -div#loginBox div#loginContent form { +div#loginBox div#loginContent form { padding-top: 1em; - width: 90%; - margin: auto; + width: 90%; + margin: auto; } -#popupLoginBox table td { - padding: 0px 3px; +#popupLoginBox table td { + padding: 0px 3px; white-space: nowrap; } -#loginContent table { +#loginContent table { padding: 0px 0.5em; margin: auto; } -#loginBox table td { - padding: 0px 3px 0.6em; +#loginBox table td { + padding: 0px 3px 0.6em; white-space: nowrap; } -#loginBox .loginButton { +#loginBox .loginButton { margin-top: 0.6em; } -#loginContent input.data { +#loginContent input.data { width:12em; } @@ -79,5 +79,5 @@ border: 1px solid #edecd2; border-color:#edecd2 #cfceb7 #cfceb7 #edecd2; margin: 2px 0px 0px; - background: #f0eff0 url("gradient-grey-up.png") left top repeat-x; + background: #f0eff0 url("gradient-grey-up.png") left top repeat-x; } diff -r 6645e18e8c93 -r 476a75ede2cc web/data/cubicweb.preferences.js --- a/web/data/cubicweb.preferences.js Tue Jun 23 13:43:39 2009 +0200 +++ b/web/data/cubicweb.preferences.js Tue Jun 23 13:46:18 2009 +0200 @@ -4,6 +4,8 @@ * move me in a more appropriate place */ +var prefsValues = {}; + function togglePrefVisibility(elemId) { clearPreviousMessages(); jQuery('#' + elemId).toggleClass('hidden'); @@ -21,7 +23,6 @@ _toggleFieldset(fieldsetid, 0, linklabel, linkhref); } - function _toggleFieldset(fieldsetid, closeaction, linklabel, linkhref){ jQuery('#'+fieldsetid).find('div.openlink').each(function(){ var link = A({'href' : "javascript:noop();", @@ -75,7 +76,6 @@ jQuery('#err-value:' + formid).remove(); } - function checkValues(form, success){ var unfreezeButtons = false; jQuery(form).find('select').each(function () { @@ -100,8 +100,8 @@ } function _checkValue(input, unfreezeButtons){ - var currentValueInput = jQuery("input[name=current-" + input.attr('name') + "]"); - if (currentValueInput.val() != input.val()){ + var currentValue = prefsValues[input.attr('name')]; + if (currentValue != input.val()){ input.addClass('changed'); unfreezeButtons = true; }else{ @@ -112,27 +112,22 @@ return unfreezeButtons; } - function setCurrentValues(form){ - jQuery(form).find('input[name^=current-value]').each(function () { - var currentValueInput = jQuery(this); - var name = currentValueInput.attr('name').split('-')[1]; - jQuery(form).find("[name=" + name + "]").each(function (){ - var input = jQuery(this); - if(input.attr('type') == 'radio'){ - // NOTE: there seems to be a bug with jQuery(input).attr('checked') - // in our case, we can't rely on its value, we use - // the DOM API instead. - if(input[0].checked){ - currentValueInput.val(input.val()); - } - }else{ - currentValueInput.val(input.val()); - } - }); - }); + jQuery(form).find('input[name^=value]').each(function () { + var input = jQuery(this); + if(input.attr('type') == 'radio'){ + // NOTE: there seems to be a bug with jQuery(input).attr('checked') + // in our case, we can't rely on its value, we use + // the DOM API instead. + if(input[0].checked){ + prefsValues[input.attr('name')] = input.val(); + } + }else{ + prefsValues[input.attr('name')] = input.val(); + } + }); } - + function initEvents(){ jQuery('form').each(function() { var form = jQuery(this); @@ -153,4 +148,3 @@ $(document).ready(function() { initEvents(); }); - diff -r 6645e18e8c93 -r 476a75ede2cc web/facet.py --- a/web/facet.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/facet.py Tue Jun 23 13:46:18 2009 +0200 @@ -744,7 +744,7 @@ % (cssclass, html_escape(unicode(self.value)))) self.w(u'
') self.w(u'%s ' % (imgsrc, imgalt)) - self.w(u'' % (facetid,title)) + self.w(u'' % (facetid, title)) self.w(u'
\n') self.w(u'\n') self.w(u'\n') diff -r 6645e18e8c93 -r 476a75ede2cc web/formwidgets.py --- a/web/formwidgets.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/formwidgets.py Tue Jun 23 13:46:18 2009 +0200 @@ -148,7 +148,7 @@ """''' % {'eid': file.eid}) +''' % {'eid': file.eid}) def test_passwordfield(self): diff -r 6645e18e8c93 -r 476a75ede2cc web/views/actions.py --- a/web/views/actions.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/actions.py Tue Jun 23 13:46:18 2009 +0200 @@ -6,6 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from cubicweb.vregistry import objectify_selector from cubicweb.selectors import (EntitySelector, @@ -18,8 +19,6 @@ from cubicweb.web.views import linksearch_select_url, vid_from_rset from cubicweb.web.views.autoform import AutomaticEntityForm -_ = unicode - class has_editable_relation(EntitySelector): """accept if some relations for an entity found in the result set is diff -r 6645e18e8c93 -r 476a75ede2cc web/views/autoform.py --- a/web/views/autoform.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/autoform.py Tue Jun 23 13:46:18 2009 +0200 @@ -292,7 +292,7 @@ by default true if there is no related entity and we need at least one """ - return not existant and card in '1+' + return not existant and card in '1+' or self.req.form.has_key('force_%s_display' % rschema) def should_display_add_new_relation_link(self, rschema, existant, card): """return true if we should add a link to add a new creation form diff -r 6645e18e8c93 -r 476a75ede2cc web/views/basecomponents.py --- a/web/views/basecomponents.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/basecomponents.py Tue Jun 23 13:46:18 2009 +0200 @@ -29,7 +29,8 @@ """build the rql input form, usually displayed in the header""" id = 'rqlinput' property_defs = VISIBLE_PROP_DEF - + visible = False + def call(self, view=None): if hasattr(view, 'filter_box_context_info'): rset = view.filter_box_context_info()[0] @@ -148,8 +149,10 @@ site_wide = True def call(self): - self.w(u'%s' % ( - self.req.base_url(), self.req.property_value('ui.site-title'))) + title = self.req.property_value('ui.site-title') + if title: + self.w(u'%s' % ( + self.req.base_url(), title)) class SeeAlsoVComponent(component.RelatedObjectsVComponent): diff -r 6645e18e8c93 -r 476a75ede2cc web/views/basetemplates.py --- a/web/views/basetemplates.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/basetemplates.py Tue Jun 23 13:46:18 2009 +0200 @@ -431,7 +431,7 @@ self.w(u'
' % (id, klass)) if title: self.w(u'
%s
' - % self.req.property_value('ui.site-title')) + % (self.req.property_value('ui.site-title') or u' ')) self.w(u'
\n') if message: diff -r 6645e18e8c93 -r 476a75ede2cc web/views/cwproperties.py --- a/web/views/cwproperties.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/cwproperties.py Tue Jun 23 13:46:18 2009 +0200 @@ -139,7 +139,6 @@ w(u'

%s

\n' % (make_togglable_link('fieldset_' + group, label.capitalize()))) w(u'
' % (group, status)) - # create selection sorted_objects = sorted((self.req.__('%s_%s' % (group, o)), o, f) for o, f in objects.iteritems()) @@ -217,10 +216,9 @@ eidparam=True)) subform.vreg = self.vreg subform.form_add_hidden('pkey', key, eidparam=True) - subform.form_add_hidden("current-value:%s" % entity.eid,) form.form_add_subform(subform) return subform - + def is_user_prefs(cls, req, rset, row=None, col=0, **kwargs): return req.user.eid == rset[row or 0][col] @@ -303,7 +301,7 @@ choices = entity.vreg.user_property_keys() return [(u'', u'')] + sorted(zip((_(v) for v in choices), choices)) - + class PropertyValueField(StringField): """specific field for CWProperty.value which will be different according to the selected key type and vocabulary information @@ -355,7 +353,6 @@ self.choices = field.vocabulary(form) self.widget = wdg - uicfg.autoform_field.tag_attribute(('CWProperty', 'pkey'), PropertyKeyField) uicfg.autoform_field.tag_attribute(('CWProperty', 'value'), PropertyValueField) diff -r 6645e18e8c93 -r 476a75ede2cc web/views/idownloadable.py --- a/web/views/idownloadable.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/idownloadable.py Tue Jun 23 13:46:18 2009 +0200 @@ -125,7 +125,7 @@ """the secondary view is a link to download the file""" entity = self.entity(row, col) url = html_escape(entity.absolute_url()) - name = html_escape(entity.download_file_name()) + name = html_escape(title or entity.download_file_name()) durl = html_escape(entity.download_url()) self.w(u'%s [%s]' % (url, name, durl, self.req._('download'))) diff -r 6645e18e8c93 -r 476a75ede2cc web/views/primary.py --- a/web/views/primary.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/views/primary.py Tue Jun 23 13:46:18 2009 +0200 @@ -54,6 +54,7 @@ self.w(u'
') self.w(u'
') self.w(u'
') + self.content_navigation_components('navcontenttop') try: self.render_entity_attributes(entity) except TypeError: # XXX bw compat @@ -61,7 +62,6 @@ 'deprecated (%s)' % self.__class__) self.render_entity_attributes(entity, []) self.w(u'
') - self.content_navigation_components('navcontenttop') if self.main_related_section: try: self.render_entity_relations(entity) diff -r 6645e18e8c93 -r 476a75ede2cc web/widgets.py --- a/web/widgets.py Tue Jun 23 13:43:39 2009 +0200 +++ b/web/widgets.py Tue Jun 23 13:46:18 2009 +0200 @@ -418,7 +418,7 @@ hidden = u'\n'\ '\n' % ( frname, format, frname) - return u'%s' % ( + return u'%s' % ( hidden, self.rname, self.format_attrs(), dvalue) if with_format and entity.e_schema.has_metadata(self.name, 'format'): fmtwdg = entity.get_widget(self.name + '_format') @@ -426,7 +426,7 @@ self.attrs['tabindex'] = entity.req.next_tabindex() else: fmtwdgstr = '' - return u'%s
' % ( + return u'%s
' % ( fmtwdgstr, self.rname, self.format_attrs(), dvalue)