Edgewall Software

Ticket #4717: 4717.diff

File 4717.diff, 4.3 KB (added by jomae, 21 months ago)
  • trac/ticket/notification.py

    diff --git a/trac/ticket/notification.py b/trac/ticket/notification.py
    index df67904..ab5e343 100644
    a b from trac.notification import NotifyEmail 
    2222from trac.ticket.api import TicketSystem 
    2323from trac.util import md5 
    2424from trac.util.datefmt import to_utimestamp 
    25 from trac.util.text import CRLF, wrap, obfuscate_email_address 
     25from trac.util.text import CRLF, wrap, obfuscate_email_address, to_unicode 
    2626from trac.util.translation import deactivate, reactivate 
    2727 
    2828from genshi.template.text import NewTextTemplate 
     29from unicodedata import east_asian_width 
    2930 
    3031class TicketNotificationSystem(Component): 
    3132 
    class TicketNotificationSystem(Component): 
    5152        `$prefix` being the value of the `smtp_subject_prefix` option. 
    5253        ''(since 0.11)''""") 
    5354 
     55    ambiguous_char_width = Option('notification', 'ambiguous_char_width', 'single', 
     56        """Which width of ambiguous characters (e.g. 'single' or 'double') 
     57        should be used in the table of notification mail. 
     58 
     59        If 'single', the same width as characters in US-ASCII. This is expected 
     60        by most users. If 'double', twice the width of US-ASCII characters. 
     61        This is expected by CJK users.""") 
     62 
    5463 
    5564class TicketNotifyEmail(NotifyEmail): 
    5665    """Notification of ticket changes.""" 
    class TicketNotifyEmail(NotifyEmail): 
    6574    def __init__(self, env): 
    6675        NotifyEmail.__init__(self, env) 
    6776        self.prev_cc = [] 
     77        self.ambiguous_char_width = env.config.get('notification', 'ambiguous_char_width', 'single') 
     78        self.text_widths = {} 
    6879 
    6980    def notify(self, ticket, newticket=True, modtime=None): 
    7081        """Send ticket change notification e-mail (untranslated)""" 
    class TicketNotifyEmail(NotifyEmail): 
    180191            if fval.find('\n') != -1: 
    181192                continue 
    182193            idx = 2 * (i % 2) 
    183             if len(f) > width[idx]: 
    184                 width[idx] = len(f) 
    185             if len(fval) > width[idx + 1]: 
    186                 width[idx + 1] = len(fval) 
     194            text_width = self.get_text_width(f) 
     195            if text_width > width[idx]: 
     196                width[idx] = text_width 
     197            text_width = self.get_text_width(fval) 
     198            if text_width > width[idx + 1]: 
     199                width[idx + 1] = text_width 
    187200            i += 1 
    188         format = (u'%%%is:  %%-%is  |  ' % (width[0], width[1]), 
    189                   u' %%%is:  %%-%is%s' % (width[2], width[3], CRLF)) 
    190201        l = (width[0] + width[1] + 5) 
    191202        sep = l * '-' + '+' + (self.COLS - l) * '-' 
    192203        txt = sep + CRLF 
    class TicketNotifyEmail(NotifyEmail): 
    204215            else: 
    205216                # Note: f['label'] is a Babel's LazyObject, make sure its 
    206217                # __str__ method won't be called. 
    207                 txt += format[i % 2] % (f['label'], unicode(fval)) 
     218                flabel = f['label'] 
     219                if i % 2 == 0: 
     220                    format = u'%%%is:  %%-%is  |  ' % ( 
     221                                width[0] - (self.get_text_width(flabel) - len(flabel)), 
     222                                width[1] - (self.get_text_width(fval) - len(fval))) 
     223                else: 
     224                    format = u' %%%is:  %%-%is%s' % ( 
     225                                width[2] - (self.get_text_width(flabel) - len(flabel)), 
     226                                width[3] - (self.get_text_width(fval) - len(fval)), 
     227                                CRLF) 
     228                txt += format % (flabel, unicode(fval)) 
    208229                i += 1 
    209230        if i % 2: 
    210231            txt += CRLF 
    class TicketNotifyEmail(NotifyEmail): 
    327348            hdrs['References'] = msgid 
    328349        NotifyEmail.send(self, torcpts, ccrcpts, hdrs) 
    329350 
     351    def get_text_width(self, text): 
     352        if self.ambiguous_char_width == 'double': 
     353            ambiwidth = 2 
     354        else: 
     355            ambiwidth = 1 
     356 
     357        if not isinstance(text, unicode): 
     358            text = to_unicode(text) 
     359 
     360        if text in self.text_widths: 
     361            return self.text_widths[text] 
     362 
     363        width = 0 
     364        for ch in text: 
     365            eaw = east_asian_width(ch) 
     366            if eaw == 'W' or eaw == 'F': 
     367                width += 2 
     368            elif eaw == 'A': 
     369                width += ambiwidth 
     370            else: 
     371                width += 1 
     372        self.text_widths[text] = width 
     373        return width 
     374