]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 94534: Customised resolutions - Patch by Frédéric Buclin <LpSolit@gmail.com>...
authorlpsolit%gmail.com <>
Fri, 14 Jul 2006 01:00:40 +0000 (01:00 +0000)
committerlpsolit%gmail.com <>
Fri, 14 Jul 2006 01:00:40 +0000 (01:00 +0000)
25 files changed:
collectstats.pl
editvalues.cgi
reports.cgi
t/008filter.t
template/en/default/admin/fieldvalues/confirm-delete.html.tmpl
template/en/default/admin/fieldvalues/edit.html.tmpl
template/en/default/admin/fieldvalues/list.html.tmpl
template/en/default/bug/activity/table.html.tmpl
template/en/default/bug/edit.html.tmpl
template/en/default/bug/knob.html.tmpl
template/en/default/bug/show-multiple.html.tmpl
template/en/default/email/whine.txt.tmpl
template/en/default/global/field-descs.none.tmpl
template/en/default/global/user-error.html.tmpl
template/en/default/list/edit-multiple.html.tmpl
template/en/default/list/table.html.tmpl
template/en/default/pages/fields.html.tmpl
template/en/default/reports/report-bar.png.tmpl
template/en/default/reports/report-line.png.tmpl
template/en/default/reports/report-pie.png.tmpl
template/en/default/reports/report-table.csv.tmpl
template/en/default/reports/report-table.html.tmpl
template/en/default/search/form.html.tmpl
template/en/default/whine/mail.html.tmpl
template/en/default/whine/mail.txt.tmpl

index 0739d03122793373ab65b810338f5fd4cbdca587..5ba56fe4b18d5626f1397672f91dc80ee1940a84 100755 (executable)
@@ -23,6 +23,7 @@
 #                 Gervase Markham <gerv@gerv.net>
 #                 Richard Walters <rwalters@qualcomm.com>
 #                 Jean-Sebastien Guay <jean_seb@hybride.com>
+#                 Frédéric Buclin <LpSolit@gmail.com>
 
 # Run me out of cron at midnight to collect Bugzilla statistics.
 #
@@ -41,6 +42,7 @@ use Bugzilla::Util;
 use Bugzilla::Search;
 use Bugzilla::User;
 use Bugzilla::Product;
+use Bugzilla::Field;
 
 # Turn off output buffering (probably needed when displaying output feedback
 # in the regenerate mode.)
@@ -55,7 +57,7 @@ if (chdir("graphs")) {
 
 # Let Throw*Error() work correctly outside a web browser.
 Bugzilla->batch(1);
-Bugzilla->switch_to_shadow_db();
+my $dbh = Bugzilla->switch_to_shadow_db();
 
 # To recreate the daily statistics,  run "collectstats.pl --regenerate" .
 my $regenerate = 0;
@@ -69,6 +71,39 @@ my $datadir = bz_locations()->{'datadir'};
 my @myproducts = map {$_->name} Bugzilla::Product::get_all_products();
 unshift(@myproducts, "-All-");
 
+# As we can now customize the list of resolutions, looking at the actual list
+# of available resolutions only is not enough as some now removed resolutions
+# may have existed in the past, or have been renamed. We want them all.
+my @resolutions = @{get_legal_field_values('resolution')};
+my $old_resolutions =
+    $dbh->selectcol_arrayref('SELECT bugs_activity.added
+                                FROM bugs_activity
+                          INNER JOIN fielddefs
+                                  ON fielddefs.fieldid = bugs_activity.fieldid
+                           LEFT JOIN resolution
+                                  ON resolution.value = bugs_activity.added
+                               WHERE fielddefs.name = ?
+                                 AND resolution.id IS NULL
+
+                               UNION
+
+                              SELECT bugs_activity.removed
+                                FROM bugs_activity
+                          INNER JOIN fielddefs
+                                  ON fielddefs.fieldid = bugs_activity.fieldid
+                           LEFT JOIN resolution
+                                  ON resolution.value = bugs_activity.removed
+                               WHERE fielddefs.name = ?
+                                 AND resolution.id IS NULL',
+                               undef, ('resolution', 'resolution'));
+
+push(@resolutions, @$old_resolutions);
+# Exclude "" from the resolution list.
+@resolutions = grep {$_} @resolutions;
+
+# Actually, the list of statuses is predefined. This will change in the near future.
+my @statuses = qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED VERIFIED CLOSED);
+
 my $tstart = time;
 foreach (@myproducts) {
     my $dir = "$datadir/mining";
@@ -143,56 +178,108 @@ sub collect_stats {
     my $file = join '/', $dir, $file_product;
     my $exists = -f $file;
 
-    if (open DATA, ">>$file") {
-        push (my @row, &today);
-        my $status_sql = q{SELECT COUNT(*) 
-                             FROM bugs 
-                            WHERE bug_status = ?};
-        
-        my $reso_sql   = q{SELECT COUNT(*) 
-                             FROM bugs 
-                            WHERE resolution = ?};
-        
-        if ($product ne '-All-') {
-            $status_sql .= q{ AND product_id = ?};
-            $reso_sql   .= q{ AND product_id = ?};
-        }
-        
-        my $sth_status = $dbh->prepare($status_sql);
-        my $sth_reso   = $dbh->prepare($reso_sql);
-        
-        my @values ;
-        foreach my $status ('NEW', 'ASSIGNED', 'REOPENED', 'UNCONFIRMED', 'RESOLVED', 'VERIFIED', 'CLOSED') {
-            @values = ($status);
-            push (@values, $product_id) if ($product ne '-All-');
-            my $count = $dbh->selectrow_array($sth_status, undef, @values);
-            push(@row, $count);
-        }
-        foreach my $resolution ('FIXED', 'INVALID', 'WONTFIX', 'LATER', 'REMIND', 'DUPLICATE', 'WORKSFORME', 'MOVED') {
-            @values = ($resolution);
-            push (@values, $product_id) if ($product ne '-All-');
-            my $count = $dbh->selectrow_array($sth_reso, undef, @values);
-            push(@row, $count);
-        }
+    # if the file exists, get the old status and resolution list for that product.
+    my @data;
+    @data = get_old_data($file) if $exists;
+
+    # If @data is not empty, then we have to recreate the data file.
+    if (scalar(@data)) {
+        open(DATA, '>', $file)
+          || ThrowCodeError('chart_file_open_fail', {'filename' => $file});
+    }
+    else {
+        open(DATA, '>>', $file)
+          || ThrowCodeError('chart_file_open_fail', {'filename' => $file});
+    }
+
+    # Now collect current data.
+    my @row = (today());
+    my $status_sql = q{SELECT COUNT(*) FROM bugs WHERE bug_status = ?};
+    my $reso_sql   = q{SELECT COUNT(*) FROM bugs WHERE resolution = ?};
+
+    if ($product ne '-All-') {
+        $status_sql .= q{ AND product_id = ?};
+        $reso_sql   .= q{ AND product_id = ?};
+    }
+
+    my $sth_status = $dbh->prepare($status_sql);
+    my $sth_reso   = $dbh->prepare($reso_sql);
+
+    my @values ;
+    foreach my $status (@statuses) {
+        @values = ($status);
+        push (@values, $product_id) if ($product ne '-All-');
+        my $count = $dbh->selectrow_array($sth_status, undef, @values);
+        push(@row, $count);
+    }
+    foreach my $resolution (@resolutions) {
+        @values = ($resolution);
+        push (@values, $product_id) if ($product ne '-All-');
+        my $count = $dbh->selectrow_array($sth_reso, undef, @values);
+        push(@row, $count);
+    }
 
-        if (! $exists) {
-            print DATA <<FIN;
+    if (!$exists || scalar(@data)) {
+        my $fields = join('|', ('DATE', @statuses, @resolutions));
+        print DATA <<FIN;
 # Bugzilla Daily Bug Stats
 #
 # Do not edit me! This file is generated.
 #
-# fields: DATE|NEW|ASSIGNED|REOPENED|UNCONFIRMED|RESOLVED|VERIFIED|CLOSED|FIXED|INVALID|WONTFIX|LATER|REMIND|DUPLICATE|WORKSFORME|MOVED
+# fields: $fields
 # Product: $product
 # Created: $when
 FIN
-        }
+    }
 
-        print DATA (join '|', @row) . "\n";
-        close DATA;
-        chmod 0644, $file;
-    } else {
-        print "$0: $file, $!";
+    # Add existing data, if needed. Note that no count is not treated
+    # the same way as a count with 0 bug.
+    foreach my $data (@data) {
+        print DATA join('|', map {defined $data->{$_} ? $data->{$_} : ''}
+                                 ('DATE', @statuses, @resolutions)) . "\n";
+    }
+    print DATA (join '|', @row) . "\n";
+    close DATA;
+    chmod 0644, $file;
+}
+
+sub get_old_data {
+    my $file = shift;
+
+    open(DATA, '<', $file)
+      || ThrowCodeError('chart_file_open_fail', {'filename' => $file});
+
+    my @data;
+    my @columns;
+    my $recreate = 0;
+    while (<DATA>) {
+        chomp;
+        next unless $_;
+        if (/^# fields?:\s*(.+)\s*$/) {
+            @columns = split(/\|/, $1);
+            # Compare this list with @statuses and @resolutions.
+            # If they are identical, then we can safely append new data
+            # to the end of the file; else we have to recreate it.
+            $recreate = 1;
+            my @new_cols = ($columns[0], @statuses, @resolutions);
+            if (scalar(@columns) == scalar(@new_cols)) {
+                my ($removed, $added) = diff_arrays(\@columns, \@new_cols);
+                last if (!scalar(@$removed) && !scalar(@$added));
+            }
+        }
+        next unless $recreate;
+        next if (/^#/); # Ignore comments.
+        # If we have to recreate the file, we have to load all existing
+        # data first.
+        my @line = split /\|/;
+        my %data;
+        foreach my $column (@columns) {
+            $data{$column} = shift @line;
+        }
+        push(@data, \%data);
     }
+    close(DATA);
+    return @data;
 }
 
 sub calculate_dupes {
@@ -317,12 +404,13 @@ sub regenerate_stats {
 
     if (open DATA, ">$file") {
         DATA->autoflush(1);
+        my $fields = join('|', ('DATE', @statuses, @resolutions));
         print DATA <<FIN;
 # Bugzilla Daily Bug Stats
 #
 # Do not edit me! This file is generated.
 #
-# fields: DATE|NEW|ASSIGNED|REOPENED|UNCONFIRMED|RESOLVED|VERIFIED|CLOSED|FIXED|INVALID|WONTFIX|LATER|REMIND|DUPLICATE|WORKSFORME|MOVED
+# fields: $fields
 # Product: $product
 # Created: $when
 FIN
@@ -355,17 +443,8 @@ FIN
             # the bugs_activity table for that bug made on or after that
             # day.
             my %bugcount;
-            my @logstates = qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED 
-                               VERIFIED CLOSED);
-            my @logresolutions = qw(FIXED INVALID WONTFIX LATER REMIND 
-                                    DUPLICATE WORKSFORME MOVED);
-            foreach (@logstates) {
-                $bugcount{$_} = 0;
-            }
-            
-            foreach (@logresolutions) {
-                $bugcount{$_} = 0;
-            }
+            foreach (@statuses) { $bugcount{$_} = 0; }
+            foreach (@resolutions) { $bugcount{$_} = 0; }
             # Get information on bug states and resolutions.
             $query = qq{SELECT bugs_activity.removed 
                           FROM bugs_activity 
@@ -412,14 +491,8 @@ FIN
             # of bugs in each state.
             my $date = sqlday($day, $base);
             print DATA "$date";
-            foreach (@logstates) {
-                print DATA "|$bugcount{$_}";
-            }
-            
-            foreach (@logresolutions) {
-                print DATA "|$bugcount{$_}";
-            }
-            
+            foreach (@statuses) { print DATA "|$bugcount{$_}"; }
+            foreach (@resolutions) { print DATA "|$bugcount{$_}"; }
             print DATA "\n";
         }
         
index 013e82be787f7987994fdd1b16df02300e7ce69b..109f8a29e2b1b72409749e24c140e334dd5000be 100755 (executable)
@@ -31,9 +31,9 @@ use Bugzilla::Config qw(:admin);
 # (the old "enums.") Keep them in alphabetical order by their 
 # English name from field-descs.html.tmpl.
 # Format: Array of valid field names.
-# Admins may add resolution and bug_status to this list, but they
-# do so at their own risk.
-our @valid_fields = ('op_sys', 'rep_platform', 'priority', 'bug_severity',);
+# Admins may add bug_status to this list, but they do so at their own risk.
+our @valid_fields = ('op_sys', 'rep_platform', 'priority', 'bug_severity',
+                     'resolution');
 
 ######################################################################
 # Subroutines
@@ -124,6 +124,11 @@ $defaults{'rep_platform'} = 'defaultplatform';
 $defaults{'priority'} = 'defaultpriority';
 $defaults{'bug_severity'} = 'defaultseverity';
 
+# Alternatively, a list of non-editable values can be specified.
+# In this case, only the sortkey can be altered.
+my %static;
+$static{'resolution'} = ['', 'FIXED', 'MOVED', 'DUPLICATE'];
+
 #
 # field = '' -> Show nice list of fields
 #
@@ -156,9 +161,9 @@ unless ($action) {
                                  {Slice =>{}});
     $vars->{'field'} = $field;
     $vars->{'values'} = $fieldvalues;
-    $vars->{'default'} = Bugzilla->params->{$defaults{$field}};
-    $template->process("admin/fieldvalues/list.html.tmpl",
-                       $vars)
+    $vars->{'default'} = Bugzilla->params->{$defaults{$field}} if defined $defaults{$field};
+    $vars->{'static'} = $static{$field} if exists $static{$field};
+    $template->process("admin/fieldvalues/list.html.tmpl", $vars)
       || ThrowTemplateError($template->error());
 
     exit;
@@ -245,6 +250,12 @@ if ($action eq 'del') {
     $vars->{'value'} = $value;
     $vars->{'field'} = $field;
     $vars->{'param_name'} = $defaults{$field};
+
+    # If the value cannot be deleted, throw an error.
+    if (lsearch($static{$field}, $value) >= 0) {
+        ThrowUserError('fieldvalue_not_deletable', $vars);
+    }
+
     $template->process("admin/fieldvalues/confirm-delete.html.tmpl",
                        $vars)
       || ThrowTemplateError($template->error());
@@ -258,11 +269,21 @@ if ($action eq 'del') {
 #
 if ($action eq 'delete') {
     ValueMustExist($field, $value);
-    if ($value eq Bugzilla->params->{$defaults{$field}}) {
-        ThrowUserError('fieldvalue_is_default', {field      => $field,
-                                                 value      => $value,
-                                                 param_name => $defaults{$field}})
+
+    $vars->{'value'} = $value;
+    $vars->{'field'} = $field;
+    $vars->{'param_name'} = $defaults{$field};
+
+    if (defined $defaults{$field}
+        && ($value eq Bugzilla->params->{$defaults{$field}}))
+    {
+        ThrowUserError('fieldvalue_is_default', $vars);
+    }
+    # If the value cannot be deleted, throw an error.
+    if (lsearch($static{$field}, $value) >= 0) {
+        ThrowUserError('fieldvalue_not_deletable', $vars);
     }
+
     trick_taint($field);
     trick_taint($value);
 
@@ -284,8 +305,6 @@ if ($action eq 'delete') {
 
     $dbh->bz_unlock_tables();
 
-    $vars->{'value'} = $value;
-    $vars->{'field'} = $field;
     $template->process("admin/fieldvalues/deleted.html.tmpl",
                        $vars)
       || ThrowTemplateError($template->error());
@@ -307,9 +326,9 @@ if ($action eq 'edit') {
 
     $vars->{'value'} = $value;
     $vars->{'field'} = $field;
+    $vars->{'is_static'} = (lsearch($static{$field}, $value) >= 0) ? 1 : 0;
 
-    $template->process("admin/fieldvalues/edit.html.tmpl",
-                       $vars)
+    $template->process("admin/fieldvalues/edit.html.tmpl", $vars)
       || ThrowTemplateError($template->error());
 
     exit;
@@ -327,9 +346,17 @@ if ($action eq 'update') {
     trick_taint($field);
     trick_taint($valueold);
 
+    $vars->{'value'} = $value;
+    $vars->{'field'} = $field;
+
+    # If the value cannot be renamed, throw an error.
+    if (lsearch($static{$field}, $valueold) >= 0 && $value ne $valueold) {
+        $vars->{'old_value'} = $valueold;
+        ThrowUserError('fieldvalue_not_editable', $vars);
+    }
+
     if (length($value) > 60) {
-        ThrowUserError('fieldvalue_name_too_long',
-                       {'value' => $value});
+        ThrowUserError('fieldvalue_name_too_long', $vars);
     }
 
     $dbh->bz_lock_tables('bugs WRITE', "$field WRITE");
@@ -359,9 +386,7 @@ if ($action eq 'update') {
             ThrowUserError('fieldvalue_undefined');
         }
         if (ValueExists($field, $value)) {
-            ThrowUserError('fieldvalue_already_exists',
-                           {'value' => $value,
-                            'field' => $field});
+            ThrowUserError('fieldvalue_already_exists', $vars);
         }
         trick_taint($value);
 
@@ -380,7 +405,8 @@ if ($action eq 'update') {
     # update data/params accordingly.
     # This update is done while tables are unlocked due to the
     # annoying calls in Bugzilla/Config/Common.pm.
-    if ($value ne $valueold
+    if (defined $defaults{$field}
+        && $value ne $valueold
         && $valueold eq Bugzilla->params->{$defaults{$field}})
     {
         SetParam($defaults{$field}, $value);
@@ -388,8 +414,6 @@ if ($action eq 'update') {
         $vars->{'default_value_updated'} = 1;
     }
 
-    $vars->{'value'} = $value;
-    $vars->{'field'} = $field;
     $template->process("admin/fieldvalues/updated.html.tmpl",
                        $vars)
       || ThrowTemplateError($template->error());
index 9df5824d7fec1669a73d7ed64338ed1c96a3a0da..e0ef55dafed2eb02be9961b670025d24078003bd 100755 (executable)
@@ -228,10 +228,10 @@ sub chart_image_name {
     # is that we have to check the safety of doing this. We can't just require
     # that the fields exist, because what stats were collected could change
     # over time (eg by changing the resolutions available)
-    # Instead, just require that each field name consists only of letters
-    # and number
+    # Instead, just require that each field name consists only of letters,
+    # numbers, underscores and hyphens.
 
-    if ($datasets !~ m/^[A-Za-z0-9:]+$/) {
+    if ($datasets !~ m/^[A-Za-z0-9:_-]+$/) {
         $vars->{'datasets'} = $datasets;
         ThrowUserError('invalid_datasets', $vars);
     }
index 1046218a862f36128b51ce38a49191c9a8448b54..02d4d4a7e919bc2679b4d7dfba3cc6c0c7ad3ffa 100644 (file)
@@ -176,7 +176,7 @@ sub directive_ok {
     return 1 if $directive =~ /^(IF|END|UNLESS|FOREACH|PROCESS|INCLUDE|
                                  BLOCK|USE|ELSE|NEXT|LAST|DEFAULT|FLUSH|
                                  ELSIF|SET|SWITCH|CASE|WHILE|RETURN|STOP|
-                                 TRY|CATCH|FINAL|THROW|CLEAR)/x;
+                                 TRY|CATCH|FINAL|THROW|CLEAR|MACRO)/x;
 
     # ? :
     if ($directive =~ /.+\?(.+):(.+)/) {
index 317f1f4b36d9d482df92e34c2017fa42438f7fe6..d29c124d6ac499fceb1cd2a2534de8141a5d53b2 100644 (file)
 
 <h2>Confirmation</h2>
 
-[% IF (Param(param_name) == value) || bug_count || (value_count == 1) %]
+[% IF (param_name.defined && Param(param_name) == value) || bug_count || (value_count == 1) %]
 
   <p>Sorry, but the '[% value FILTER html %]' value cannot be deleted
   from the '[% field FILTER html %]' field for the following reason(s):</p>
 
   <ul class="warningmessages">
-    [% IF Param(param_name) == value %]
+    [% IF param_name.defined && Param(param_name) == value %]
       <li>'[% value FILTER html %]' is the default value for
           the '[% field FILTER html %]' field.
           [% IF user.groups.tweakparams %]
index c798bb3a925e2985136fdc30a232c37c806966fb..362ed47533c70821de6cfdb6cbb1dce571058a49 100644 (file)
 
     <tr>
       <th valign="top"><label for="value">Field Value:</label></th>
-      <td><input id="value" size="20" maxlength="60" name="value" value="
-      [%- value FILTER html %]"></td>
+      <td>
+        [% IF is_static %]
+          <input type="hidden" name="value" value="[% value FILTER html %]">
+          [% value FILTER html %]
+        [% ELSE %]
+          <input id="value" size="20" maxlength="60" name="value" value="
+          [%- value FILTER html %]">
+        [% END %]
+      </td>
     </tr>
     <tr>
       <th align="right"><label for="sortkey">Sortkey:</label></th>
index d25adf2b10229b629af3cc553c17477153041c9a..f446d0f96ffe4e383d78d77aadde4d256bdf089f 100644 (file)
@@ -21,6 +21,7 @@
   #              displayed to the user in a list.
   #
   # field: string; the name of the field we are editing values for.
+  # static: array; list of values which cannot be renamed nor deleted.
   #%]
 
 [% USE Bugzilla %]
      } ]
 %]
 
-[% overrides.action = [ {
-     match_value => "$default"
-     match_field => 'name'
-     override_content => 1
-     content => "(Default value)"
-     override_contentlink => 1
-     contentlink => undef
-   } ]
-%] 
+[% IF default.defined %]
+  [% overrides.action = [ {
+       match_value => "$default"
+       match_field => 'name'
+       override_content => 1
+       content => "(Default value)"
+       override_contentlink => 1
+       contentlink => undef
+     } ]
+  %]
+[% END %]
+
+[% IF static.size %]
+  [% UNLESS overrides.action.size %]
+    [% overrides.action = [] %]
+  [% END %]
+
+  [% FOREACH static_value = static %]
+    [% overrides.action.push({
+         match_value => "$static_value"
+         match_field => 'name'
+         override_content => 1
+         content => "(Non deletable value)"
+         override_contentlink => 1
+         contentlink => undef
+       })
+    %]
+  [% END %]
+[% END %]
 
 [% PROCESS admin/table.html.tmpl
      columns = columns
index 31556623d34448d74b3b7f5827b3d9b72bc87dce..5bfb79f377e2d08dbb783460b3886abcea865734 100644 (file)
@@ -85,7 +85,7 @@
                 [% ELSIF change.fieldname == 'bug_status' %]
                   [% status_descs.${change.removed} FILTER html %]
                 [% ELSIF change.fieldname == 'resolution' %]
-                  [% resolution_descs.${change.removed} FILTER html %]
+                  [% get_resolution(change.removed) FILTER html %]
                 [% ELSIF change.fieldname == 'blocked' ||
                          change.fieldname == 'dependson' %]
                   [% change.removed FILTER bug_list_link FILTER none %]
                 [% ELSIF change.fieldname == 'bug_status' %]
                   [% status_descs.${change.added} FILTER html %]
                 [% ELSIF change.fieldname == 'resolution' %]
-                  [% resolution_descs.${change.added} FILTER html %]
+                  [% get_resolution(change.added) FILTER html %]
                 [% ELSIF change.fieldname == 'blocked' ||
                          change.fieldname == 'dependson' %]
                   [% change.added FILTER bug_list_link FILTER none %]
index adbccd1419e5b3caf21474633caaa6159a7d76d7..2ea8d0db638f55a79385198934a5664cdf6659fa 100644 (file)
               </b>
             </td>
             <td>
-              [% resolution_descs.${bug.resolution} FILTER html %]
+              [% get_resolution(bug.resolution) FILTER html %]
               [% IF bug.resolution == "DUPLICATE" %]
                 of [% terms.bug %] [%+ "${bug.dup_id}" FILTER bug_link(bug.dup_id) %]
               [% END %]
index 38a4898fece40191e686d44fece6b83e7727b7e2..36712911e012b3e629b7aca7d55de6f3ebc47030 100644 (file)
@@ -28,7 +28,7 @@
   <input type="radio" id="knob-leave" name="knob" value="none" checked="checked">
   <label for="knob-leave">
     Leave as <b>[% status_descs.${bug.bug_status} FILTER html %]&nbsp;
-                [% resolution_descs.${bug.resolution} FILTER html %]</b>
+                [% get_resolution(bug.resolution) FILTER html %]</b>
   </label>
   <br>
 
   <select name="resolution"
           onchange="document.changeform.knob[[% knum %]].checked=true">
     [% FOREACH r = bug.choices.resolution %]
-      <option value="[% r FILTER html %]">[% resolution_descs.${r} FILTER html %]</option>
+      <option value="[% r FILTER html %]">[% get_resolution(r) FILTER html %]</option>
     [% END %]
   </select>
   <br>
index 023cb9573281fbd85175f87c8cfac7add27b493b..22bc3db69943f999ca8a19e7282716847720c7ed 100644 (file)
       <th>[% field_descs.bug_status  FILTER html %]:</th>
       <td>
         [% status_descs.${bug.bug_status} FILTER html %]
-        [%+ resolution_descs.${bug.resolution} FILTER html %]
+        [%+ get_resolution(bug.resolution) FILTER html %]
       </td>
 
       [% PROCESS rightcell %]
index 2e10617097045320cdbcc860465a513e859dbe5d..214231394b7b710c7357ff126233eacf9f448915 100644 (file)
@@ -37,7 +37,7 @@ You need to take a look at them, and decide on an initial action.
 
 Generally, this means one of three things:
 
-(1) You decide this [% terms.bug %] is really quick to deal with (like, it's [% resolution_descs.INVALID %]),
+(1) You decide this [% terms.bug %] is really quick to deal with (like, it's [% get_resolution("INVALID") %]),
     and so you get rid of it immediately.
 (2) You decide the [% terms.bug %] doesn't belong to you, and you reassign it to
     someone else. (Hint: if you don't know who to reassign it to, make
index 8014fe2559603e0718bc2ef0abe170c6c2d0d717..7a27251212ad2899c38ee88681eb05a0357db7a1 100644 (file)
@@ -88,4 +88,6 @@
                         "---"        => "---",
                         " "          => " " } %]
 
+[% MACRO get_resolution(res) GET resolution_descs.$res || res %]
+
 [% Hook.process("end") %]
index 3b901929f40e2b52076d17c4daf598e43e300dd3..c615598b9f4b07ee1ff978dd43daf4e96bcac752 100644 (file)
     The value of a field is limited to 60 characters.
     '[% value FILTER html %]' is too long ([% value.length %] characters).
 
+  [% ELSIF error == "fieldvalue_not_editable" %]
+    [% title = "Field Value Not Editable" %]
+    The value '[% old_value FILTER html %]' cannot be renamed because
+    it plays some special role for the '[% field FILTER html %]' field.
+
+  [% ELSIF error == "fieldvalue_not_deletable" %]
+    [% title = "Field Value Not Deletable" %]
+    The value '[% value FILTER html %]' cannot be removed because
+    it plays some special role for the '[% field FILTER html %]' field.
+
   [% ELSIF error == "fieldvalue_not_specified" %]
     [% title = "Field Value Not Specified" %]
     No field value specified when trying to edit a field value.
index 687888b247661469270691947596591b18b26582..92a083a68196ab5029d1a3c502d7c6113464445c 100644 (file)
   <select name="resolution" onchange="document.forms.changeform.knob[[% knum %]].checked=true">
     [% FOREACH resolution = resolutions %]
       [% NEXT IF !resolution %]
-      <option value="[% resolution FILTER html %]" [% 'selected="selected"' IF resolution == "FIXED" %]>
-        [% resolution_descs.$resolution FILTER html %]
+      <option value="[% resolution FILTER html %]">
+        [% get_resolution(resolution) FILTER html %]
       </option>
     [% END %]
   </select><br>
index 7ef53058a04ff046cfdcc509bf4943742723fb4b..0387adafb92126d1d3c481596338f80ebbba6d83 100644 (file)
       [% ELSIF column == 'bug_status' %]
         [%- status_descs.${bug.$column}.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %]
       [% ELSIF column == 'resolution' %]
-        [%- resolution_descs.${bug.$column}.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %]
+        [%- get_resolution(bug.$column).truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %]
       [% ELSE %]
         [%- bug.$column.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%]
       [% END %]
index a45fa0b87c98eca9d3e12069fc75d5ae82af8997..7a41801f4e208593a1083ceb555e8885999193ae 100644 (file)
@@ -148,7 +148,7 @@ cycle of [% terms.abug %].
     <td>
       <dl>
         <dt>
-          <b>[% resolution_descs.FIXED FILTER html %]</b>
+          <b>[% get_resolution("FIXED") FILTER html %]</b>
         </dt>
         <dd>
           A fix for this [% terms.bug %] is checked into the tree and 
@@ -156,14 +156,14 @@ cycle of [% terms.abug %].
         </dd>
 
         <dt>
-          <b>[% resolution_descs.INVALID FILTER html %]</b>
+          <b>[% get_resolution("INVALID") FILTER html %]</b>
         </dt>
         <dd>
           The problem described is not [% terms.abug %].
         </dd>
 
         <dt>
-          <b>[% resolution_descs.WONTFIX FILTER html %]</b>
+          <b>[% get_resolution("WONTFIX") FILTER html %]</b>
         </dt>
         <dd>
           The problem described is [% terms.abug %] which will never be 
@@ -171,7 +171,7 @@ cycle of [% terms.abug %].
         </dd>
 
         <dt>
-         <b>[% resolution_descs.DUPLICATE FILTER html %]</b>
+         <b>[% get_resolution("DUPLICATE") FILTER html %]</b>
         </dt>
         <dd>
           The problem is a duplicate of an existing [% terms.bug %].
@@ -181,7 +181,7 @@ cycle of [% terms.abug %].
         </dd>
 
         <dt>
-          <b>[% resolution_descs.WORKSFORME FILTER html %]</b>
+          <b>[% get_resolution("WORKSFORME") FILTER html %]</b>
         </dt>
         <dd>
           All attempts at reproducing this [% terms.bug %] were futile, 
@@ -191,7 +191,7 @@ cycle of [% terms.abug %].
         </dd>
 
         <dt>
-          <b>[% resolution_descs.MOVED FILTER html %]</b>
+          <b>[% get_resolution("MOVED") FILTER html %]</b>
         </dt>
         <dd>
           The problem was specific to a related product 
index bb5dab7cd66f8640feb026cd341e4a429d2dba74..2c29a3558c6f85ec27faf8436bf1437a1fefe221 100644 (file)
@@ -35,7 +35,7 @@
 
 [% IF col_field == 'resolution' %]
   [% FOR i IN [ 0 .. data.0.0.max ] %]
-    [% data.0.0.$i = resolution_descs.${data.0.0.$i} %]
+    [% data.0.0.$i = get_resolution(data.0.0.$i) %]
   [% END %]
 [% END %]
 
@@ -47,7 +47,7 @@
 
 [% IF row_field == 'resolution' %]
   [% FOR i IN [ 0 .. row_names.max ] %]
-    [% row_names.$i = resolution_descs.${row_names.$i} %]
+    [% row_names.$i = get_resolution(row_names.$i) %]
   [% END %]
 [% END %]
 
index 60e9f261adc236040129e432f202bd499269d62e..24215af98fd45cc4efc71f93685842a00f7de879 100644 (file)
@@ -35,7 +35,7 @@
 
 [% IF col_field == 'resolution' %]
   [% FOR i IN [ 0 .. data.0.0.max ] %]
-    [% data.0.0.$i = resolution_descs.${data.0.0.$i} %]
+    [% data.0.0.$i = get_resolution(data.0.0.$i) %]
   [% END %]
 [% END %]
 
@@ -47,7 +47,7 @@
 
 [% IF row_field == 'resolution' %]
   [% FOR i IN [ 0 .. row_names.max ] %]
-    [% row_names.$i = resolution_descs.${row_names.$i} %]
+    [% row_names.$i = get_resolution(row_names.$i) %]
   [% END %]
 [% END %]
 
index c70b06bcf49cf702c21fd02622d230e356d23405..3eb73b1b0f6a35cfaa91f835ef33f22b04260f44 100644 (file)
@@ -31,7 +31,7 @@
 
 [% IF col_field == 'resolution' %]
   [% FOR i IN [ 0 .. data.0.0.max ] %]
-    [% data.0.0.$i = resolution_descs.${data.0.0.$i} %]
+    [% data.0.0.$i = get_resolution(data.0.0.$i) %]
   [% END %]
 [% END %]
 
index 0abb68ece919a92b23dcc8c4f82cb22b0cdca497..2f7f867af80f38c820ab898e75da42f998e625e3 100644 (file)
@@ -44,7 +44,7 @@
     [% IF col_field == 'bug_status' %]
       [% status_descs.$col FILTER csv -%]
     [% ELSIF col_field == 'resolution' %]
-      [% resolution_descs.$col FILTER csv -%]
+      [% get_resolution(col) FILTER csv -%]
     [% ELSE %]
       [% col FILTER csv -%]
     [% END %]
@@ -57,7 +57,7 @@
   [% IF row_field == 'bug_status' %]
     [% status_descs.$row FILTER csv -%]
   [% ELSIF row_field == 'resolution' %]
-    [% resolution_descs.$row FILTER csv -%]
+    [% get_resolution(row) FILTER csv -%]
   [% ELSE %]
     [% row FILTER csv -%]
   [% END %]
index 0e2ae62c86ad43148512ee2a729487a2f7a330b3..679eb1c1dd9b3f302ba440aac6023fc997ec89f7 100644 (file)
@@ -88,7 +88,7 @@
           [% IF col_field == 'bug_status' %]
             [% status_descs.$col FILTER html FILTER replace('^ $','&nbsp;') %]
           [% ELSIF col_field == 'resolution' %]
-            [% resolution_descs.$col FILTER html FILTER replace('^ $','&nbsp;') %]
+            [% get_resolution(col) FILTER html FILTER replace('^ $','&nbsp;') %]
           [% ELSE %]
             [% col FILTER html FILTER replace('^ $','&nbsp;') %]
           [% END %]
         [% IF row_field == 'bug_status' %]
           [% status_descs.$row FILTER html FILTER replace('^ $','&nbsp;') %]
         [% ELSIF row_field == 'resolution' %]
-          [% resolution_descs.$row FILTER html FILTER replace('^ $','&nbsp;') %]
+          [% get_resolution(row) FILTER html FILTER replace('^ $','&nbsp;') %]
         [% ELSE %]
           [% row FILTER html FILTER replace('^ $','&nbsp;') %]
         [% END %]
index ee85675863f3c926568ebb740831b49e2ce6811f..230a438c1838dcec1bd17ae809c9b869550d994c 100644 (file)
@@ -628,12 +628,13 @@ function doOnSelectProduct(selectmode) {
         <option value="[% name FILTER html %]"
           [% " selected" IF lsearch(default.${sel.name}, name) != -1 %]>
           [% IF sel.name == "bug_status" %]
-            [% status_descs.${name} FILTER html %]</option>
+            [% status_descs.${name} FILTER html %]
           [% ELSIF sel.name == "resolution" %]
-            [% resolution_descs.${name} FILTER html %]</option>
+            [% get_resolution(name) FILTER html %]
           [% ELSE %]
-            [% name FILTER html %]</option>
+            [% name FILTER html %]
           [% END %]
+        </option>
       [% END %]
     </select>
   </td>
index d81043a36d01d32b887f451e0fbf99688378863c..8fe11d6577ef50c329a2118195b770db69729f3f 100644 (file)
@@ -84,7 +84,7 @@
         <td align="left">[% bug.rep_platform FILTER html %]</td>
         <td align="left">[% bug.$assignee_login_string FILTER html %]</td>
         <td align="left">[% status_descs.${bug.bug_status} FILTER html %]</td>
-        <td align="left">[% resolution_descs.${bug.resolution} FILTER html %]</td>
+        <td align="left">[% get_resolution(bug.resolution) FILTER html %]</td>
         <td align="left">[% bug.short_desc FILTER html %]</td>
       </tr>
     [% END %]
index 962972197f3902ab22cbe3f7cf67a910e6a07168..c7dcef3dcaa5229b95ae1267bf923679cc660363 100644 (file)
@@ -59,7 +59,7 @@
   Platform: [%+ bug.rep_platform %]
   Assignee: [%+ bug.$assignee_login_string %]
     Status: [%+ status_descs.${bug.bug_status} %]
-            [%- IF bug.resolution -%] Resolution: [% resolution_descs.${bug.resolution} -%]
+            [%- IF bug.resolution -%] Resolution: [% get_resolution(bug.resolution) -%]
                                 [%- END %]
    Summary: [% bug.short_desc %]