Changeset 9751
- Timestamp:
- May 23, 2010, 5:44:53 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/trac/ticket/web_ui.py
r9669 r9751 42 42 shorten_line, to_unicode 43 43 from trac.util.presentation import separated 44 from trac.util.translation import _, tag_, tagn_, N_, gettext 44 from trac.util.translation import _, tag_, tagn_, N_, gettext, ngettext 45 45 from trac.versioncontrol.diff import get_diff_options, diff_blocks 46 46 from trac.web import arg_list_to_args, parse_arg_list, IRequestHandler … … 108 108 if name.startswith('default_'): 109 109 if name not in self._warn_for_default_attr: 110 self.log.warning( '%s option should be accessed via '111 'TicketSystem component', name)110 self.log.warning("%s option should be accessed via " 111 "TicketSystem component", name) 112 112 self._warn_for_default_attr.add(name) 113 113 return getattr(TicketSystem(self.env), name) … … 124 124 125 125 def get_supported_conversions(self): 126 yield ('csv', _( 'Comma-delimited Text'), 'csv',126 yield ('csv', _("Comma-delimited Text"), 'csv', 127 127 'trac.ticket.Ticket', 'text/csv', 8) 128 yield ('tab', _( 'Tab-delimited Text'), 'tsv',128 yield ('tab', _("Tab-delimited Text"), 'tsv', 129 129 'trac.ticket.Ticket', 'text/tab-separated-values', 8) 130 yield ('rss', _( 'RSS Feed'), 'xml',130 yield ('rss', _("RSS Feed"), 'xml', 131 131 'trac.ticket.Ticket', 'application/rss+xml', 8) 132 132 … … 150 150 if 'TICKET_CREATE' in req.perm: 151 151 yield ('mainnav', 'newticket', 152 tag.a(_( 'New Ticket'), href=req.href.newticket(),152 tag.a(_("New Ticket"), href=req.href.newticket(), 153 153 accesskey=7)) 154 154 … … 182 182 def get_search_filters(self, req): 183 183 if 'TICKET_VIEW' in req.perm: 184 yield ('ticket', _( 'Tickets'))184 yield ('ticket', _("Tickets")) 185 185 186 186 def get_search_results(self, req, terms, filters): … … 212 212 if 'TICKET_VIEW' in req.perm(t): 213 213 yield (req.href.ticket(tid), 214 tag (tag.span(get_resource_shortname(self.env, t),215 class_=status),216 ': ',217 ticketsystem.format_summary(summary, status,218 214 tag_("%(title)s: %(message)s", 215 title=tag.span(get_resource_shortname(self.env, t), 216 class_=status), 217 message=ticketsystem.format_summary( 218 summary, status, resolution, type)), 219 219 from_utimestamp(ts), author, 220 220 shorten_result(desc, terms)) … … 229 229 def get_timeline_filters(self, req): 230 230 if 'TICKET_VIEW' in req.perm: 231 yield ('ticket', _( 'Opened and closed tickets'))231 yield ('ticket', _("Opened and closed tickets")) 232 232 if self.timeline_details: 233 yield ('ticket_details', _( 'Ticket updates'), False)233 yield ('ticket_details', _("Ticket updates"), False) 234 234 235 235 def get_timeline_events(self, req, start, stop, filters): … … 237 237 ts_stop = to_utimestamp(stop) 238 238 239 status_map = {'new': ('newticket', N_( 'created')),240 'reopened': ('reopenedticket', N_( 'reopened')),241 'closed': ('closedticket', N_( 'closed')),242 'edit': ('editedticket', N_( 'updated'))}239 status_map = {'new': ('newticket', N_("created")), 240 'reopened': ('reopenedticket', N_("reopened")), 241 'closed': ('closedticket', N_("closed")), 242 'edit': ('editedticket', N_("updated"))} 243 243 244 244 ticket_realm = Resource('ticket') … … 258 258 labels = [tag.i(field_labels.get(k, k.capitalize())) 259 259 for k in fields.keys()] 260 info = tagn_( '%(labels)s changed',261 '%(labels)s changed', len(labels),262 labels=separated(labels, ', ')) + tag.br()260 info = tagn_("%(labels)s changed", 261 "%(labels)s changed", len(labels), 262 labels=separated(labels, ', ')) + tag.br() 263 263 else: 264 264 return None 265 265 elif 'ticket' in filters: 266 266 if status == 'closed' and resolution: 267 info = resolution 268 if info and comment: 269 info += ': ' 267 if resolution and comment: 268 info = _("%(title)s: %(message)s", title=resolution, 269 message='') # typographical translation (fr) 270 else: 271 info = resolution 270 272 else: 271 273 return None … … 339 341 title = TicketSystem(self.env).format_summary(summary, status, 340 342 resolution, type) 341 return tag_( 'Ticket %(ticketref)s (%(summary)s) %(verb)s',343 return tag_("Ticket %(ticketref)s (%(summary)s) %(verb)s", 342 344 ticketref=tag.em('#', ticket.id, title=title), 343 345 summary=shorten_line(summary), verb=gettext(verb)) … … 517 519 add_warning(req, problem) 518 520 add_warning(req, 519 tag_( 'Please review your configuration, '520 'probably starting with %(section)s '521 'in your %(tracini)s.',522 section =tag.pre('[ticket]', tag.br(),523 524 tracini =tag.tt('trac.ini')))521 tag_("Please review your configuration, " 522 "probably starting with %(section)s " 523 "in your %(tracini)s.", 524 section=tag.pre('[ticket]', tag.br(), 525 'workflow = ...'), 526 tracini=tag.tt('trac.ini'))) 525 527 526 528 # Apply changes made by the workflow … … 576 578 if t: 577 579 add_link(req, css_class, req.href.ticket(id), 578 'Ticket #%s' % id)580 _("Ticket #%(id)s", id=id)) 579 581 580 582 global_sequence = True … … 627 629 conversion[4], format) 628 630 629 prevnext_nav(req, _( 'Previous Ticket'), _('Next Ticket'),630 _( 'Back to Query'))631 prevnext_nav(req, _("Previous Ticket"), _("Next Ticket"), 632 _("Back to Query")) 631 633 632 634 return 'ticket.html', data, None … … 710 712 'author': ticket['reporter'] # not 100% accurate... 711 713 }) 712 data.update({'title': _( 'Ticket History'),714 data.update({'title': _("Ticket History"), 713 715 'resource': ticket.resource, 714 716 'history': history}) 715 717 716 add_ctxtnav(req, _( 'Back to Ticket #%(num)s', num=ticket.id),718 add_ctxtnav(req, _("Back to Ticket #%(num)s", num=ticket.id), 717 719 req.href.ticket(ticket.id)) 718 720 return 'history_view.html', data, None … … 756 758 new_version, new_change = descriptions[new_idx] 757 759 else: 758 raise TracError(_( 'No differences to show'))760 raise TracError(_("No differences to show")) 759 761 760 762 tnew = ticket.resource(version=new_version) … … 793 795 794 796 def version_info(t, field=None): 795 path = 'Ticket #%s' % ticket.id797 path = _("Ticket #%(id)s", id=ticket.id) 796 798 # TODO: field info should probably be part of the Resource as well 797 799 if field: … … 799 801 field_labels.get(field, field.capitalize())) 800 802 if t.version: 801 rev = _( 'Version %(num)s', num=t.version)803 rev = _("Version %(num)s", num=t.version) 802 804 shortrev = 'v%d' % t.version 803 805 else: 804 rev, shortrev = _( 'Initial Version'), _('initial')806 rev, shortrev = _("Initial Version"), _("initial") 805 807 return {'path': path, 'rev': rev, 'shortrev': shortrev, 806 808 'href': get_resource_url(self.env, t, req.href)} … … 819 821 old, new, tnew) 820 822 if rendered: 821 prop['diff'] = tag.li('Property ', tag.strong(label), 822 ' ', rendered) 823 prop['diff'] = tag.li( 824 tag_("Property %(label)s %(rendered)s", 825 label=tag.strong(label), rendered=rendered)) 823 826 props.append(prop) 824 827 changes.append({'props': props, 'diffs': [], … … 855 858 req.href, action='diff', 856 859 version=prev_version), 857 _( 'Version %(num)s', num=prev_version))860 _("Version %(num)s", num=prev_version)) 858 861 add_link(req, 'up', get_resource_url(self.env, ticket.resource, 859 862 req.href, action='history'), 860 _( 'Ticket History'))863 _("Ticket History")) 861 864 if next_version: 862 865 add_link(req, 'next', get_resource_url(self.env, ticket.resource, 863 866 req.href, action='diff', 864 867 version=next_version), 865 _( 'Version %(num)s', num=next_version))866 867 prevnext_nav(req, _( 'Previous Change'), _('Next Change'),868 _( 'Ticket History'))868 _("Version %(num)s", num=next_version)) 869 870 prevnext_nav(req, _("Previous Change"), _("Next Change"), 871 _("Ticket History")) 869 872 add_stylesheet(req, 'common/css/diff.css') 870 873 add_script(req, 'common/js/diff.js') 871 874 872 875 data.update({ 873 'title': _( 'Ticket Diff'),876 'title': _("Ticket Diff"), 874 877 'resource': ticket.resource, 875 878 'old_version': old_version, 'new_version': new_version, … … 892 895 history.append({ 893 896 'version': version, 'date': date, 'author': author, 894 'comment': version == 0 and "''Initial version''"or '',897 'comment': version == 0 and _("''Initial version''") or '', 895 898 'value': comment, 896 899 'url': self._make_comment_url(req, ticket, cnum, version) … … 905 908 url = self._make_comment_url(req, ticket, cnum) 906 909 data.update({ 907 'title': _( 'Ticket Comment History'),910 'title': _("Ticket Comment History"), 908 911 'resource': ticket.resource, 909 'name': _( 'Ticket #%(num)s, comment %(cnum)d',912 'name': _("Ticket #%(num)s, comment %(cnum)d", 910 913 num=ticket.id, cnum=cnum), 911 914 'url': url, … … 913 916 'history': history, 914 917 }) 915 add_ctxtnav(req, _( 'Back to Ticket #%(num)s', num=ticket.id), url)918 add_ctxtnav(req, _("Back to Ticket #%(num)s", num=ticket.id), url) 916 919 return 'history_view.html', data, None 917 920 … … 931 934 932 935 def version_info(version): 933 path = _( 'Ticket #%(num)s, comment %(cnum)d',936 path = _("Ticket #%(num)s, comment %(cnum)d", 934 937 num=ticket.id, cnum=cnum) 935 938 if version: 936 rev = _( 'Version %(num)s', num=version)939 rev = _("Version %(num)s", num=version) 937 940 shortrev = 'v%d' % version 938 941 else: 939 rev, shortrev = _( 'Initial Version'), _('initial')942 rev, shortrev = _("Initial Version"), _("initial") 940 943 return {'path': path, 'rev': rev, 'shortrev': shortrev} 941 944 … … 954 957 return text and text.splitlines() or [] 955 958 except KeyError: 956 raise ResourceNotFound(_( 'No version %(version)d for comment '957 '%(cnum)d on ticket #%(ticket)s',959 raise ResourceNotFound(_("No version %(version)d for comment " 960 "%(cnum)d on ticket #%(ticket)s", 958 961 version=version, cnum=cnum, 959 962 ticket=ticket.id)) … … 979 982 url = req.href.ticket(ticket.id, cnum=cnum, action='comment-diff', 980 983 version=prev_version) 981 add_link(req, 'prev', url, _( 'Version %(num)s', num=prev_version))984 add_link(req, 'prev', url, _("Version %(num)s", num=prev_version)) 982 985 add_link(req, 'up', req.href.ticket(ticket.id, cnum=cnum, 983 986 action='comment-history'), 984 _( 'Ticket Comment History'))987 _("Ticket Comment History")) 985 988 if next_version: 986 989 url = req.href.ticket(ticket.id, cnum=cnum, action='comment-diff', 987 990 version=next_version) 988 add_link(req, 'next', url, _( 'Version %(num)s', num=next_version))989 990 prevnext_nav(req, _( 'Previous Change'), _('Next Change'),991 _( 'Ticket Comment History'))991 add_link(req, 'next', url, _("Version %(num)s", num=next_version)) 992 993 prevnext_nav(req, _("Previous Change"), _("Next Change"), 994 _("Ticket Comment History")) 992 995 add_stylesheet(req, 'common/css/diff.css') 993 996 add_script(req, 'common/js/diff.js') 994 997 995 998 data.update({ 996 'title': _( 'Ticket Comment Diff'),999 'title': _("Ticket Comment Diff"), 997 1000 'resource': ticket.resource, 998 'name': _( 'Ticket #%(num)s, comment %(cnum)d',1001 'name': _("Ticket #%(num)s, comment %(cnum)d", 999 1002 num=ticket.id, cnum=cnum), 1000 1003 'url': self._make_comment_url(req, ticket, cnum), … … 1058 1061 chg = 'deleted' 1059 1062 change_summary.setdefault(chg, []).append(field) 1060 change['title'] = '; '.join(['%s %s' % (', '.join(v), k) for k, v \ 1061 in change_summary.iteritems()]) 1063 c = change_summary.get('changed') 1064 if c: 1065 c = ngettext("%(labels)s changed", "%(labels)s changed", 1066 len(c), labels=', '.join(c)) 1067 s = change_summary.get('set') 1068 if s: 1069 s = ngettext("%(labels)s set", "%(labels)s set", 1070 len(s), labels=', '.join(s)) 1071 d = change_summary.get('deleted') 1072 if d: 1073 d = ngettext("%(labels)s deleted", "%(labels)s deleted", 1074 len(d), labels=', '.join(d)) 1075 change['title'] = _("; ").join(g for g in [c, s, d] if g) 1062 1076 1063 1077 data = self._prepare_data(req, ticket, absurls=True) … … 1113 1127 # Always require a summary 1114 1128 if not ticket['summary']: 1115 add_warning(req, _( 'Tickets must contain a summary.'))1129 add_warning(req, _("Tickets must contain a summary.")) 1116 1130 valid = False 1117 1131 … … 1131 1145 valid = False 1132 1146 elif not field.get('optional', False): 1133 add_warning(req, 'field %s must be set' % name) 1147 add_warning(req, _("field %(name)s must be set", 1148 name=name)) 1134 1149 valid = False 1135 1150 1136 1151 # Validate description length 1137 1152 if len(ticket['description'] or '') > self.max_description_size: 1138 add_warning(req, _( 'Ticket description is too long (must be less '1139 'than %(num)s characters)',1140 num=self.max_description_size))1153 add_warning(req, _("Ticket description is too long (must be less " 1154 "than %(num)s characters)", 1155 num=self.max_description_size)) 1141 1156 valid = False 1142 1157 1143 1158 # Validate comment length 1144 1159 if len(comment or '') > self.max_comment_size: 1145 add_warning(req, _( 'Ticket comment is too long (must be less '1146 'than %(num)s characters)',1160 add_warning(req, _("Ticket comment is too long (must be less " 1161 "than %(num)s characters)", 1147 1162 num=self.max_comment_size)) 1148 1163 valid = False … … 1158 1173 except ValueError: 1159 1174 # Shouldn't happen in "normal" circumstances, hence not a warning 1160 raise InvalidTicket(_( 'Invalid comment threading identifier'))1175 raise InvalidTicket(_("Invalid comment threading identifier")) 1161 1176 1162 1177 # Custom validation rules … … 1166 1181 if field: 1167 1182 add_warning(req, _("The ticket field '%(field)s' is " 1168 "invalid: %(message)s",1169 field=field, message=message))1183 "invalid: %(message)s", 1184 field=field, message=message)) 1170 1185 else: 1171 1186 add_warning(req, message) … … 1182 1197 self.log.error("Failure sending notification on creation of " 1183 1198 "ticket #%s: %s", ticket.id, exception_to_unicode(e)) 1184 add_warning(req, _( 'The ticket has been created, but an error '1185 'occurred while sending notifications: '1186 '%(message)s', message=to_unicode(e)))1199 add_warning(req, _("The ticket has been created, but an error " 1200 "occurred while sending notifications: " 1201 "%(message)s", message=to_unicode(e))) 1187 1202 1188 1203 # Redirect the user to the newly created ticket or add attachment … … 1228 1243 if fragment: 1229 1244 change = tag.a(change, href=fragment) 1230 add_warning(req, tag_( 'The %(change)s has been saved, but an '1231 'error occurred while sending '1232 'notifications: %(message)s',1245 add_warning(req, tag_("The %(change)s has been saved, but an " 1246 "error occurred while sending " 1247 "notifications: %(message)s", 1233 1248 change=change, message=to_unicode(e))) 1234 1249 fragment = '' … … 1236 1251 # After saving the changes, apply the side-effects. 1237 1252 for controller in controllers: 1238 self.env.log.debug( 'Side effect for %s'%1253 self.env.log.debug("Side effect for %s" % 1239 1254 controller.__class__.__name__) 1240 1255 controller.apply_action_side_effects(req, ticket, action) … … 1335 1350 field['skip'] = True 1336 1351 if not ticket.exists: 1337 field['label'] = _( 'Owner')1352 field['label'] = _("Owner") 1338 1353 if 'TICKET_MODIFY' in req.perm(ticket.resource): 1339 1354 field['skip'] = False … … 1389 1404 if value in ('1', '0'): 1390 1405 field['rendered'] = self._query_link(req, name, value, 1391 value == '1' and _( 'yes') or _('no'))1406 value == '1' and _("yes") or _("no")) 1392 1407 elif type_ == 'text': 1393 1408 if field.get('format') == 'wiki': … … 1430 1445 if 'comment' not in req.args: # i.e. the comment was not yet edited 1431 1446 data['comment'] = '\n'.join( 1432 [ 'Replying to [%s %s]:'% (link,1447 ["Replying to [%s %s]:" % (link, 1433 1448 obfuscate_email_address(author))] + 1434 [ '> %s'% line for line in original.splitlines()] + [''])1449 ["> %s" % line for line in original.splitlines()] + ['']) 1435 1450 1436 1451 if replyto == 'description': … … 1575 1590 break 1576 1591 if type_ == 'checkbox': 1577 rendered = new == '1' and _( 'set') or _('unset')1592 rendered = new == '1' and _("set") or _("unset") 1578 1593 elif type_ == 'textarea': 1579 1594 if not resource_new: 1580 rendered = _( 'modified')1595 rendered = _("modified") 1581 1596 else: 1582 1597 href = get_resource_url(self.env, resource_new, req.href, 1583 1598 action='diff') 1584 1599 # TRANSLATOR: modified ('diff') (link) 1585 diff = tag.a(_( 'diff'), href=href)1586 rendered = tag_( 'modified (%(diff)s)', diff=diff)1600 diff = tag.a(_("diff"), href=href) 1601 rendered = tag_("modified (%(diff)s)", diff=diff) 1587 1602 1588 1603 # per name special rendering of diffs … … 1604 1619 remvd = [tag.em(render_elt(x)) for x in old_list 1605 1620 if x not in new_list] 1606 added = added and tagn_( '%(items)s added', '%(items)s added',1621 added = added and tagn_("%(items)s added", "%(items)s added", 1607 1622 len(added), items=separated(added, sep)) 1608 remvd = remvd and tagn_( '%(items)s removed', '%(items)s removed',1623 remvd = remvd and tagn_("%(items)s removed", "%(items)s removed", 1609 1624 len(remvd), items=separated(remvd, sep)) 1610 1625 if added or remvd: 1611 rendered = tag(added, added and remvd and '; ', remvd)1626 rendered = tag(added, added and remvd and _("; "), remvd) 1612 1627 if field in ('reporter', 'owner'): 1613 1628 if not (Chrome(self.env).show_email_addresses or … … 1616 1631 new = obfuscate_email_address(new) 1617 1632 if old and not new: 1618 rendered = tag_( '%(value)s deleted', value=tag.em(old))1633 rendered = tag_("%(value)s deleted", value=tag.em(old)) 1619 1634 elif new and not old: 1620 rendered = tag_( 'set to %(value)s', value=tag.em(new))1635 rendered = tag_("set to %(value)s", value=tag.em(new)) 1621 1636 elif old and new: 1622 rendered = tag_( 'changed from %(old)s to %(new)s',1637 rendered = tag_("changed from %(old)s to %(new)s", 1623 1638 old=tag.em(old), new=tag.em(new)) 1624 1639 return rendered
Note:
See TracChangeset
for help on using the changeset viewer.