Changeset 4344

Show
Ignore:
Timestamp:
09/26/08 06:53:22 (3 months ago)
Author:
Blackhex
Message:

ScreenshotsPlugin:

  • DB schema updated with priority field. Backup your DB before upgrading!!!
  • Screnshots order facility introduced (default_orders and default_order_directions configuration options added. SCREENSHOTS_ORDER permission added.).
  • Screenshot images can be now replaced via edit form.
  • AND/OR relation between component and version filters added.
  • Fixed UnicodeDecodeError? when system error messages has international characters.
  • Fixed missing components, versions and description in HTML view.
  • Behavior of align attribute of [[Screnshot()]] macro changed for ticket #3771.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • screenshotsplugin/0.11/setup.py

    r3141 r4344  
    66setup( 
    77  name = 'TracScreenshots', 
    8   version = '0.6', 
     8  version = '0.7', 
    99  packages = ['tracscreenshots', 'tracscreenshots.db'], 
    1010  package_data = {'tracscreenshots' : ['templates/*.html', 'htdocs/css/*.css', 
  • screenshotsplugin/0.11/tracscreenshots/api.py

    r4314 r4344  
    4040 
    4141class ScreenshotsApi(Component): 
     42 
     43    default_priority = 0 
    4244 
    4345    # Get list functions 
     
    6769        # Get screenshots from database. 
    6870        return self._get_items(context, 'screenshot', ('id', 'name', 
    69           'description', 'time', 'author', 'tags', 'file', 'width', 'height')) 
     71          'description', 'time', 'author', 'tags', 'file', 'width', 'height', 
     72          'priority')) 
    7073 
    7174    def get_screenshots_complete(self, context): 
     
    7881        return screenshots 
    7982 
    80     def get_filtered_screenshots(self, context, components, versions): 
     83    def get_filtered_screenshots(self, context, components, versions, relation 
     84      = 'or', orders = ('id', 'name', 'time')): 
    8185        has_none_version = True 
    8286        has_none_component = True 
    8387        columns = ('id', 'name', 'description', 'time', 'author', 'tags', 
    84           'file', 'width', 'height'
     88          'file', 'width', 'height', 'priority'
    8589        versions_str = (', '.join(['%s'] * len(versions))) or 'NULL' 
    8690        components_str = (', '.join(['%s'] * len(components))) or 'NULL' 
     91        orders_str = ', '.join(['%s %s' % (field, direction.upper()) for \ 
     92          field, direction in orders]) 
    8793        sql = 'SELECT DISTINCT ' + ', '.join(columns) + ' FROM screenshot s ' \ 
    8894          'LEFT JOIN (SELECT screenshot, version FROM screenshot_version) v ' \ 
    8995          'ON s.id = v.screenshot LEFT JOIN (SELECT screenshot, component ' \ 
    9096          'FROM screenshot_component) c ON s.id = c.screenshot WHERE ' \ 
    91           'v.version IN (' + versions_str + ')' + (('none' in versions) and \ 
    92           ' OR v.version IS NULL' or '') + ' OR c.component IN (' + \ 
    93           components_str + ')' + (('none' in components) and \ 
    94           ' OR c.component IS NULL' or '') 
     97          '(v.version IN (' + versions_str + ')' + (('none' in versions) and \ 
     98          ' OR v.version IS NULL) ' or ') ') + ((relation == 'and') and 'AND' or \ 
     99          'OR') + ' (c.component IN (' + components_str + ')' + (('none' in  
     100          components) and ' OR c.component IS NULL) ' or ') ') + 'ORDER BY ' + \ 
     101            orders_str 
    95102        self.log.debug(versions + components) 
    96103        self.log.debug(sql % tuple(versions + components)) 
     
    143150        # Get screenshot from database. 
    144151        screenshot = self._get_item(context, 'screenshot', ('id', 'name', 
    145           'description', 'time', 'author', 'tags', 'file', 'width', 'height')
    146           'id = %s', (id,)) 
     152          'description', 'time', 'author', 'tags', 'file', 'width', 'height'
     153          'priority'), 'id = %s', (id,)) 
    147154 
    148155        if screenshot: 
     
    161168        # Get screenshot from database. 
    162169        screenshot = self._get_item(context, 'screenshot', ('id', 'name', 
    163           'description', 'time', 'author', 'tags', 'file', 'width', 'height')
    164           'time = %s', (time,)) 
     170          'description', 'time', 'author', 'tags', 'file', 'width', 'height'
     171          'priority'), 'time = %s', (time,)) 
    165172 
    166173        if screenshot: 
     
    265272        self.log.debug(sql % (id,)) 
    266273        context.cursor.execute(sql, (id,)) 
     274 
     275    # Other methods. 
     276 
     277    def set_version(self, context, version): 
     278        # Check if version item exists. 
     279        sql = "SELECT value FROM system WHERE name = 'screenshots_version'" 
     280        self.log.debug(sql) 
     281        context.cursor.execute(sql) 
     282        in_db = False 
     283        for row in context.cursor: 
     284            in_db = True 
     285            break 
     286 
     287        # Insert of update version. 
     288        if in_db: 
     289            sql = "UPDATE system SET value = %s WHERE name = 'screenshots_" \ 
     290              "version'" 
     291        else: 
     292            sql = "INSERT INTO system (name, value) VALUES ('screenshots_" \ 
     293              "version', %s)" 
     294        self.log.debug(sql % (version,)) 
     295        context.cursor.execute(sql, (version,)) 
  • screenshotsplugin/0.11/tracscreenshots/core.py

    r4314 r4344  
    5959    default_versions = ListOption('screenshots', 'default_versions', 'none', 
    6060      doc = 'List of versions enabled by default.') 
     61    default_filter_relation = Option('screenshots', 'default_filter_relation', 
     62      'or', doc = 'Logical relation between component and version part of' 
     63      ' screenshots filter.') 
     64    default_orders = ListOption('screenshots', 'default_orders', 
     65      'id', doc = 'List of names of database fields that are used to' 
     66      ' sort screenshots.') 
     67    default_order_directions = ListOption('screenshots', 
     68      'default_order_directions', 'asc', doc = 'List of ordering ' 
     69      'directions for fields specified in default_orders configuration ' 
     70      'options.') 
    6171 
    6272    # IPermissionRequestor methods. 
     
    6575        view = 'SCREENSHOTS_VIEW' 
    6676        filter = ('SCREENSHOTS_FILTER', ['SCREENSHOTS_VIEW']) 
    67         admin = ('SCREENSHOTS_ADMIN', ['SCREENSHOTS_FILTER', 
    68           'SCREENSHOTS_VIEW']) 
    69         return [view, filter, admin] 
     77        order = ('SCREENSHOTS_ORDER', ['SCREENSHOTS_VIEW']) 
     78        admin = ('SCREENSHOTS_ADMIN', ['SCREENSHOTS_ORDER', 
     79          'SCREENSHOTS_FILTER', 'SCREENSHOTS_VIEW']) 
     80        return [view, filter, order, admin] 
    7081 
    7182    # ITemplateProvider methods. 
     
    154165        elif action == 'filter': 
    155166            return ['filter', 'view'] 
     167        elif action == 'order': 
     168            return ['order', 'view'] 
    156169        else: 
    157170            return ['view'] 
     
    265278                              'file' : filename, 
    266279                              'width' : image.size[0], 
    267                               'height' : image.size[1]} 
     280                              'height' : image.size[1], 
     281                              'priority' : int(context.req.args.get('priority') 
     282                                or '0')} 
    268283 
    269284                # Add new screenshot. 
     
    294309                screenshot['versions'] = versions 
    295310 
    296                 self.log.debug(screenshot
     311                self.log.debug('screenshot: %s' % (screenshot,)
    297312 
    298313                # Prepare file paths 
     
    327342                      ' specified in path config option in [screenshots]' \ 
    328343                      ' section of trac.ini existing? Original message was: %s' \ 
    329                       % (error,)) 
     344                      % (to_unicode(error),)) 
    330345 
    331346                # Notify change listeners. 
     
    345360                self.data['screenshot'] = api.get_screenshot(context, 
    346361                  screenshot_id) 
    347                 self.log.debug(self.data['screenshot']) 
    348362 
    349363            elif action == 'post-edit': 
     
    379393                                'components') or [], 
    380394                              'versions' : context.req.args.get('versions') or \ 
    381                                 []} 
     395                                [], 
     396                              'priority' : int(context.req.args.get('priority') 
     397                                or '0')} 
    382398 
    383399                # Update dimensions and filename if image file is updated. 
     
    395411                     screenshot['versions'] = [screenshot['versions']] 
    396412 
    397                 self.log.debug(screenshot
     413                self.log.debug('screenshot: %s' % (screenshot)
    398414 
    399415                # Edit screenshot. 
     
    420436                    except Exception, error: 
    421437                        raise TracError('Error deleting screenshot. Original' \ 
    422                           ' message was: %s' % (error,)) 
     438                          ' message was: %s' % (to_unicode(error),)) 
    423439 
    424440                    # Store uploaded image. 
     
    436452                          ' specified in path config option in [screenshots]' \ 
    437453                          ' section of trac.ini existing? Original message was: %s' \ 
    438                           % (error,)) 
     454                          % (to_unicode(error),)) 
    439455 
    440456                # Notify change listeners. 
     
    477493                except Exception, error: 
    478494                    raise TracError('Error deleting screenshot. Original' \ 
    479                       ' message was: %s' % (error,)) 
     495                      ' message was: %s' % (to_unicode(error),)) 
    480496 
    481497                # Notify change listeners. 
     
    487503 
    488504            elif action == 'filter': 
     505                context.req.perm.assert_permission('SCREENSHOTS_FILTER') 
     506 
    489507                # Update enabled components from request. 
    490508                components = context.req.args.get('components') or [] 
    491509                if not isinstance(components, list): 
    492510                    components = [components] 
    493                 context.req.session['enabled_components'] = str(components) 
     511                self._set_enabled_components(context.req, components) 
    494512 
    495513                # Update enabled versions from request. 
     
    497515                if not isinstance(versions, list): 
    498516                    versions = [versions] 
    499                 context.req.session['enabled_versions'] = str(versions) 
     517                self._set_enabled_versions(context.req, versions) 
     518 
     519                # Update filter relation from request. 
     520                relation = context.req.args.get('filter_relation') or 'or' 
     521                self._set_filter_relation(context.req, relation) 
     522 
     523            elif action == 'order': 
     524                context.req.perm.assert_permission('SCREENSHOTS_ORDER') 
     525 
     526                # Get three order fields from request and store them to session. 
     527                orders = [] 
     528                I = 0 
     529                while context.req.args.has_key('order_%s' % (I,)): 
     530                    orders.append((context.req.args.get('order_%s' % (I,)) or 'id', 
     531                      context.req.args.get('order_direction_%s' % (I,)) or 'asc')) 
     532                    I += 1 
     533                self._set_orders(context.req, orders) 
    500534 
    501535            elif action == 'view': 
     
    516550                  context.cursor) 
    517551 
    518                 # Get enabled components and versions from request or session. 
     552                # Get enabled components, versions and filter relation from 
     553                # request or session. 
    519554                enabled_components = self._get_enabled_components(context.req) 
    520555                enabled_versions = self._get_enabled_versions(context.req) 
     556                relation = self._get_filter_relation(context.req) 
    521557                if 'all' in enabled_components: 
    522558                    enabled_components = [component['name'] for component in 
     
    526562                    versions] 
    527563 
    528                 self.log.debug(enabled_components) 
     564                self.log.debug('enabled_components: %s' % (enabled_components,)) 
     565                self.log.debug('enabled_versions: %s' % (enabled_versions,)) 
     566                self.log.debug('filter_relation: %s' % (relation,)) 
     567 
     568                # Get order fields of screenshots. 
     569                orders = self._get_orders(context.req) 
    529570 
    530571                # Filter screenshots. 
    531572                screenshots = api.get_filtered_screenshots(context, 
    532                   enabled_components, enabled_versions
     573                  enabled_components, enabled_versions, relation, orders
    533574 
    534575                # Convert enabled components and versions to dictionary. 
     
    546587                self.data['enabled_versions'] = enabled_versions 
    547588                self.data['enabled_components'] = enabled_components 
     589                self.data['filter_relation'] = relation 
     590                self.data['orders'] = orders 
    548591 
    549592                # Get screenshots content template and data. 
     
    596639        if req.perm.has_permission('SCREENSHOTS_FILTER'): 
    597640            # Return existing filter from session or create default. 
    598             if req.session.has_key('enabled_components'): 
    599                 components = eval(req.session.get('enabled_components')) 
     641            if req.session.has_key('screenshots_enabled_components'): 
     642                components = eval(req.session.get('screenshots_enabled_' 
     643                  'components')) 
    600644            else: 
    601645                components = self.default_components 
    602                 req.session['enabled_components'] = str(components) 
     646                req.session['screenshots_enabled_components'] = str(components) 
    603647        else: 
    604648            # Users without SCREENSHOTS_FILTER permission uses 
    605649            # 'default_components' configuration option. 
    606650            components = self.default_components 
    607         self.log.debug('enabled_components: %s' % (components,)) 
    608651        return components 
     652 
     653    def _set_enabled_components(self, req, components): 
     654        req.session['screenshots_enabled_components'] = str(components) 
    609655 
    610656    def _get_enabled_versions(self, req): 
    611657        if req.perm.has_permission('SCREENSHOTS_FILTER'): 
    612658            # Return existing filter from session or create default. 
    613             if req.session.has_key('enabled_versions'): 
    614                 versions = eval(req.session.get('enabled_versions')) 
     659            if req.session.has_key('screenshots_enabled_versions'): 
     660                versions = eval(req.session.get('screenshots_enabled_versions')) 
    615661            else: 
    616662                versions = self.default_versions 
    617                 req.session['enabled_versions'] = str(versions) 
     663                req.session['screenshots_enabled_versions'] = str(versions) 
    618664        else: 
    619665            # Users without SCREENSHOTS_FILTER permission uses 
    620666            # 'default_versions' configuration option. 
    621667            versions = self.default_versions 
    622         self.log.debug('enabled_versions: %s' % (versions,)) 
    623668        return versions 
     669 
     670    def _set_enabled_versions(self, req, versions): 
     671        req.session['screenshots_enabled_versions'] = str(versions) 
     672 
     673    def _get_filter_relation(self, req): 
     674        if req.perm.has_permission('SCREENSHOTS_FILTER'): 
     675            # Return existing filter relation from session or create default. 
     676            if req.session.has_key('screenshots_filter_relation'): 
     677                relation = req.session.get('screenshots_filter_relation') 
     678            else: 
     679                relation = self.default_filter_relation 
     680                req.session['screenshots_filter_relation'] = relation 
     681        else: 
     682            # Users without SCREENSHOTS_FILTER permission uses 
     683            # 'default_filter_relation' configuration option. 
     684            relation = self.default_filter_relation 
     685        return relation 
     686 
     687    def _set_filter_relation(self, req, relation): 
     688        req.session['screenshots_filter_relation'] = relation 
     689 
     690    def _get_orders(self, req): 
     691        if req.perm.has_permission('SCREENSHOTS_ORDER'): 
     692            # Get ordering fields from session or default ones. 
     693            if req.session.has_key('screenshots_orders'): 
     694                orders = eval(req.session.get('screenshots_orders')) 
     695            else: 
     696                orders = tuple(self.default_orders) 
     697                directions = tuple(self.default_order_directions) 
     698                orders = [(orders[I], directions[I]) for I in \ 
     699                  xrange(len(orders))] 
     700                req.session['screenshots_orders'] = str(orders) 
     701        else: 
     702            # Users without SCREENSHOTS_ORDER permission uses 
     703            # 'default_orders' configuration option. 
     704            orders = tuple(self.default_orders) 
     705            directions = tuple(self.default_order_directions) 
     706            orders = [(orders[I], directions[I]) for I in xrange(len(orders))] 
     707        return tuple(orders) 
     708 
     709    def _set_orders(self, req, orders): 
     710        req.session['screenshots_orders'] = str(orders) 
  • screenshotsplugin/0.11/tracscreenshots/htdocs/css/screenshots.css

    r3313 r4344  
    2222} 
    2323 
     24div.order fieldset.order 
     25{ 
     26  float: left; 
     27  padding: 1em; 
     28  margin: 0.5em; 
     29} 
     30 
     31div.order hr 
     32{ 
     33  padding: 0em; 
     34  margin: 0.5em 0em; 
     35} 
     36 
     37div.order div.buttons 
     38{ 
     39  clear: both; 
     40} 
     41 
    2442/* Wiki [[Screenshot()]] macro styles. */ 
    25 span.thumbnail > a > img 
     43span.thumbnail 
    2644{ 
    27   display: inline; 
    28   border-color: #b00; 
    29   border-style: solid; 
     45  display: block; 
    3046  margin: 0em; 
    3147  padding: 0em; 
    3248} 
    3349 
    34 span.thumbnail > a 
     50span.thumbnail span.aux 
    3551{ 
    36   display: inline-block; 
    37   border: 0px none; 
    38   margin: 0.2em; 
     52  display: block; 
     53  padding: 1em; 
     54  margin-top: 0em; 
     55  margin-bottom: 0em; 
     56  margin-left: auto; 
     57  margin-right: auto; 
     58
     59 
     60span.thumbnail a 
     61
     62  display: block; 
     63
     64 
     65span.thumbnail a img 
     66
     67  display: block; 
     68  border-color: #b00; 
     69  border-style: solid; 
     70
     71 
     72span.thumbnail span.description 
     73
     74  display: block; 
     75  margin-top: 0.5em; 
     76
     77 
     78span.thumbnail-left, span.thumbnail-righ 
     79
     80  display: block; 
     81  margin: 0em; 
    3982  padding: 0em; 
    4083} 
    4184 
    42 span.thumbnail > span.description 
     85span.thumbnail-left span.aux, span.thumbnail-righ span.aux 
    4386{ 
    44   display: inline-block; 
     87  display: block; 
     88  margin: 0em; 
     89  margin-top: 0.5em; 
     90  padding: 0em; 
     91
     92 
     93span.thumbnail-left a, span.thumbnail-right a, 
     94
     95  display: block; 
     96
     97 
     98span.thumbnail-left a img, span.thumbnail-right a img 
     99
     100  display: block; 
     101  border-color: #b00; 
     102  border-style: solid; 
     103
     104 
     105span.thumbnail-left span.description, span.thumbnail-right span.description 
     106
     107  display: block; 
     108  margin-top: 0.5em; 
    45109} 
    46110 
    47111span.thumbnail, span.thumbnail-left, span.thumbnail-right 
    48112{ 
    49   display: inline-block; 
    50   margin: 1em; 
    51   margin-top: 0.5em; 
     113  margin: 16px; 
     114  margin-top: 0em; 
    52115  padding: 0em; 
    53116  font-size: 75%; 
    54117  text-align: center; 
    55   vertical-align: middle; 
    56118} 
    57119 
  • screenshotsplugin/0.11/tracscreenshots/htdocs/js/screenshots.js

    r2659 r4344  
    1 function check_all(name, check) 
     1function checkAll(name, check) 
    22{ 
    33  var checkboxes = document.getElementsByName(name); 
     
    77  } 
    88} 
     9 
     10function checkNumber(evt) 
     11{ 
     12  var keycode; 
     13 
     14  if (evt) 
     15    ; 
     16  else if (window.event) 
     17    evt = window.event; 
     18  else if (event) 
     19    evt = event; 
     20  else 
     21    return true; 
     22 
     23  if (evt.charCode) 
     24    keycode = evt.charCode; 
     25  else if (evt.keyCode) 
     26    keycode = evt.keyCode; 
     27  else if (evt.which) 
     28    keycode = evt.which; 
     29  else 
     30    keycode = 0; 
     31 
     32  return ((keycode >= 48 && keycode <= 57) || (keycode == 8) || 
     33   (keycode == 46) || (keycode >= 33 && keycode <= 40)); 
     34} 
  • screenshotsplugin/0.11/tracscreenshots/init.py

    r3140 r4344  
    66 
    77# Last screenshots database shcema version 
    8 last_db_version = 3 
     8last_db_version = 4 
    99 
    1010class ScreenshotsInit(Component): 
     
    3030        # Get current database schema version 
    3131        db_version = self._get_db_version(cursor) 
    32  
    3332 
    3433        # Is this clean installation? 
  • screenshotsplugin/0.11/tracscreenshots/templates/screenshot-add.html

    r4314 r4344  
    5555            </select><br/> 
    5656          </div> 
     57          <div class="field"> 
     58            <label for="priority">Priority (number 0..x):</label><br/> 
     59            <input type="text" onkeypress="return checkNumber(event)" name="priority" value="${(req.args.action == 'edit') and screenshots.screenshot.priority or '0'}"/> 
     60          </div> 
    5761          <div class="buttons"> 
    5862            <input type="submit" name="submit" value="Submit"/> 
  • screenshotsplugin/0.11/tracscreenshots/templates/screenshot.html

    r3141 r4344  
    2020            <td class="components"> 
    2121              <strong>Components:</strong> 
    22               <?cs each:component = screenshots.screenshot.components ?
    23                 <?cs var:component ?> 
    24               <?cs /each ?
     22              <py:for each="component in screenshots.screenshot.components"
     23                $component 
     24              </py:for
    2525            </td> 
    2626          </tr> 
     
    2828            <td class="versions"> 
    2929              <strong>Versions:</strong>  
    30               <?cs each:version = screenshots.screenshot.versions ?
    31                 <?cs var:version ?> 
    32               <?cs /each ?
     30              <py:for each="version in screenshots.screenshot.versions"
     31                $version 
     32              </py:for
    3333            </td> 
    3434          </tr> 
    3535          <tr> 
    3636            <td class="message"> 
    37               <?cs var:screenshots.screenshot.description ?> 
     37              ${screenshots.screenshot.description} 
    3838            </td> 
    3939          </tr> 
  • screenshotsplugin/0.11/tracscreenshots/templates/screenshots.html

    r4277 r4344  
    11<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
    2 <?python 
    3   test = {'ř': 1} 
    4 ?> 
    52<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:py="http://genshi.edgewall.org/"> 
    63  <xi:include href="layout.html"/> 
     
    1714      <xi:include href="${screenshots.content_template}"/> 
    1815 
    19       <div py:if="'SCREENSHOTS_ADMIN'in perm" class="buttons screenshot_buttons"> 
     16      <div py:if="'SCREENSHOTS_ADMIN' in perm" class="buttons screenshot_buttons"> 
    2017        <form method="post" action="${href.screenshots()}"> 
    2118          <div> 
     
    4340      </div> 
    4441 
     42      <div py:if="'SCREENSHOTS_ORDER' in perm" class="order"> 
     43        <form method="post" action="${href.screenshots()}"> 
     44          <fieldset> 
     45            <legend> 
     46              Order: 
     47            </legend> 
     48 
     49            <fieldset py:for="index, order in enumerate(screenshots.orders)" class="order"> 
     50              <legend> 
     51                 ${index + 1}. field: 
     52              </legend> 
     53 
     54              <div> 
     55                <py:choose> 
     56                  <input py:when="order[0] == 'id'" type="radio" name="order_$index" value="id" checked="checked">ID</input> 
     57                  <input py:otherwise="" type="radio" name="order_$index" value="id">ID</input><br/> 
     58                </py:choose> 
     59                <py:choose> 
     60                  <input py:when="order[0] == 'name'" type="radio" name="order_$index" value="name" checked="checked">Name</input> 
     61                  <input py:otherwise="" type="radio" name="order_$index" value="name">Name</input><br/> 
     62                </py:choose> 
     63                <py:choose> 
     64                  <input py:when="order[0] == 'author'" type="radio" name="order_$index" value="author" checked="checked">Author</input> 
     65                  <input py:otherwise="" type="radio" name="order_$index" value="author">Author</input><br/> 
     66                </py:choose> 
     67                <py:choose> 
     68                  <input py:when="order[0] == 'time'" type="radio" name="order_$index" value="time" checked="checked">Time</input> 
     69                  <input py:otherwise="" type="radio" name="order_$index" value="time">Time</input><br/> 
     70                </py:choose> 
     71                <py:choose> 
     72                  <input py:when="order[0] == 'description'" type="radio" name="order_$index" value="description" checked="checked">Description</input> 
     73                  <input py:otherwise="" type="radio" name="order_$index" value="description">Description</input><br/> 
     74                </py:choose> 
     75                <py:choose> 
     76                  <input py:when="order[0] == 'priority'" type="radio" name="order_$index" value="priority" checked="checked">Priority</input> 
     77                  <input py:otherwise="" type="radio" name="order_$index" value="priority">Priority</input><br/> 
     78                </py:choose> 
     79 
     80                <hr/> 
     81                <py:choose> 
     82                  <input py:when="order[1] == 'asc'" type="radio" name="order_direction_$index" value="asc" checked="checked">Ascending</input> 
     83                  <input py:otherwise="" type="radio" name="order_direction_$index" value="asc">Ascending</input> 
     84                </py:choose> 
     85                <py:choose> 
     86                  <input py:when="order[1] == 'desc'" type="radio" name="order_direction_$index" value="desc" checked="checked">Descending</input> 
     87                  <input py:otherwise="" type="radio" name="order_direction_$index" value="desc">Descending</input> 
     88                </py:choose> 
     89              </div> 
     90            </fieldset> 
     91 
     92            <div class="buttons"> 
     93              <input type="submit" name="filter" value="Apply Order"/> 
     94              <input type="hidden" name="action" value="order"/> 
     95            </div> 
     96 
     97          </fieldset> 
     98        </form> 
     99      </div> 
     100 
    45101      <div py:if="'SCREENSHOTS_FILTER' in perm" class="filter"> 
    46102        <form method="post" action="${href.screenshots()}"> 
     
    64120                  </input> 
    65121                </py:choose> 
    66                 <input type="button" name="all" value="All" onclick="check_all('components', true)"/> 
    67                 <input type="button" name="none" value="None" onclick="check_all('components', false)"/> 
     122                <input type="button" name="all" value="All" onclick="checkAll('components', true)"/> 
     123                <input type="button" name="none" value="None" onclick="checkAll('components', false)"/> 
    68124              </div> 
    69125            </fieldset> 
     126 
     127            <div> 
     128              <py:choose> 
     129                <py:when test="screenshots.filter_relation == 'and'"> 
     130                  <input type="radio" name="filter_relation" value="and" checked="checked">AND</input> 
     131                  <input type="radio" name="filter_relation" value="or">OR</input> 
     132                </py:when> 
     133                <py:otherwise> 
     134                  <input type="radio" name="filter_relation" value="and">AND</input> 
     135                  <input type="radio" name="filter_relation" value="or" checked="checked">OR</input> 
     136                </py:otherwise> 
     137              </py:choose> 
     138            </div> 
    70139 
    71140            <fieldset> 
     
    83152                  </input> 
    84153                </py:choose> 
    85                 <input type="button" name="all" value="All" onclick="check_all('versions', true)"/> 
    86                 <input type="button" name="none" value="None" onclick="check_all('versions', false)"/> 
     154                <input type="button" name="all" value="All" onclick="checkAll('versions', true)"/> 
     155                <input type="button" name="none" value="None" onclick="checkAll('versions', false)"/> 
    87156              </div> 
    88157            </fieldset> 
  • screenshotsplugin/0.11/tracscreenshots/wiki.py

    r4304 r4344  
    169169 
    170170                # Make copy of attributes for image tag. 
    171                 img_attributes = {'align' : 'center', 
    172                                   'style' : 'border-width: %spx;' % ( 
     171                img_attributes = {'style' : 'border-width: %spx;' % ( 
    173172                                    attributes['border'],)} 
    174173                for attribute in attributes.keys(): 
     
    187186                  screenshot['id'], format = attributes['format']), title = 
    188187                  screenshot['description']) 
     188                width_and_border = int(attributes['width']) + 2 * \ 
     189                  int(attributes['border']) 
    189190                description = html.span(attributes['description'], class_ = 
    190                   'description') 
     191                  'description', style = "width: %spx;" % (width_and_border,)) 
     192                auxilary = html.span(link, description, class_ = 'aux', 
     193                  style = "width: %spx;" % (width_and_border,)) 
    191194                thumbnail_class = 'thumbnail' + ((attributes['align'] == 'left') 
    192195                  and '-left' or (attributes['align'] == 'right') and '-right' 
    193196                  or '') 
    194                 thumbnail = html.span(link, ' ', description, class_ = 
    195                   thumbnail_class, style = "width: %spx;" % ( 
    196                   int(attributes['width']) + 2 * int(attributes['border'],))) 
     197                thumbnail = html.span(auxilary, class_ = thumbnail_class) 
    197198                return thumbnail 
    198199            else: