[Rt-commit] rt branch, librarize-search-logic, created. 20fdc5f179a20f0adc1530f2675a216d9afbcf6a

jesse jesse at bestpractical.com
Thu Nov 5 19:31:40 EST 2009


The branch, librarize-search-logic has been created
        at  20fdc5f179a20f0adc1530f2675a216d9afbcf6a (commit)

- Log -----------------------------------------------------------------
commit 1346a0281f28db61a7cd795a4221298431a75730
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 11:20:06 2009 -0500

    First round of moving Search/Build logic to lib/
    
    Conflicts:
    
    	share/html/Search/Build.html

diff --git a/lib/RT/Interface/Web/QueryBuilder.pm b/lib/RT/Interface/Web/QueryBuilder.pm
new file mode 100644
index 0000000..788a9de
--- /dev/null
+++ b/lib/RT/Interface/Web/QueryBuilder.pm
@@ -0,0 +1,175 @@
+package RT::Interface::Web::QueryBuilder;
+use warnings;
+use strict;
+
+sub process_query {
+	my $self = shift;
+	my $ARGS = shift;
+	my $tree = shift;
+	my $selected = shift;
+	my $new = shift || [];
+
+my @NewSelection = ();
+
+my @results;
+if ( $ARGS->{'up'} || $ARGS->{'down'} ) {
+    if (@$selected) {
+        foreach my $value (@$selected) {
+            my $parent = $value->getParent;
+            my $index = $value->getIndex;
+            my $newindex = $index;
+            $newindex++ if $ARGS->{'down'};
+            $newindex-- if $ARGS->{'up'};
+            if ( $newindex < 0 || $newindex >= $parent->getChildCount ) {
+                push( @results, [ _("error: can't move up"), -1 ] ) if $ARGS->{'up'};
+                push( @results, [ _("error: can't move down"), -1 ] ) if $ARGS->{'down'};
+                next;
+            }
+
+            $parent->removeChild( $index );
+            $parent->insertChild( $newindex, $value );
+        }
+    }
+    else {
+        push( @results, [ _("error: nothing to move"), -1 ] );
+    }
+}
+elsif ( $ARGS->{"left"} ) {
+    if (@$selected) {
+        foreach my $value (@$selected) {
+            my $parent = $value->getParent;
+            if( $value->isRoot || $parent->isRoot ) {
+                push( @results, [ _("error: can't move left"), -1 ] );
+                next;
+            }
+
+            my $grandparent = $parent->getParent;
+            if( $grandparent->isRoot ) {
+                push( @results, [ _("error: can't move left"), -1 ] );
+                next;
+            }
+            
+            my $index = $parent->getIndex;
+            $parent->removeChild($value);
+            $grandparent->insertChild( $index, $value );
+            if ( $parent->isLeaf ) {
+                $grandparent->removeChild($parent);
+            }
+        }
+    }
+    else {
+        push( @results, [ _("error: nothing to move"), -1 ] );
+    }
+}
+elsif ( $ARGS->{"right"} ) {
+    if (@$selected) {
+        foreach my $value (@$selected) {
+            my $parent = $value->getParent;
+            my $index  = $value->getIndex;
+
+            my $newparent;
+            if ( $index > 0 ) {
+                my $sibling = $parent->getChild( $index - 1 );
+                $newparent = $sibling unless $sibling->isLeaf;
+            }
+            $newparent ||= RT::Interface::Web::QueryBuilder::Tree->new( $ARGS->{'and_or'} || 'AND', $parent );
+
+            $parent->removeChild($value);
+            $newparent->addChild($value);
+        }
+    }
+    else {
+        push( @results, [ _("error: nothing to move"), -1 ] );
+    }
+}
+elsif ( $ARGS->{"delete_clause"} ) {
+    if (@$selected) {
+        my (@top);
+        my %Selected = map { $_ => 1 } @$selected;
+        foreach my $node ( @$selected ) {
+            my $tmp = $node->getParent;
+            while ( !$Selected{ $tmp } && !$tmp->isRoot ) {
+                $tmp = $tmp->getParent;
+            }
+            next if $Selected{ $tmp };
+            push @top, $node;
+        }
+
+        my %seen;
+        my @non_siblings_top = grep !$seen{ $_->getParent }++, @top;
+
+        foreach ( @$new ) {
+            my $add = $_->clone;
+            foreach my $sel( @non_siblings_top ) {
+                my $newindex = $sel->getIndex + 1;
+                $sel->insertSibling( $newindex, $add );
+            }
+            $add->getParent->setNodeValue( $ARGS->{'and_or'} );
+            push @NewSelection, $add;
+        }
+        @$new = ();
+    
+        while( my $node = shift @top ) {
+            my $parent = $node->getParent;
+            $parent->removeChild($node);
+            $node->DESTROY;
+        }
+        @$selected = ();
+    }
+    else {
+        push( @results, [ _("error: nothing to delete"), -1 ] );
+    }
+}
+elsif ( $ARGS->{"toggle"} ) {
+    if (@$selected) {
+        my %seen;
+        my @unique_nodes = grep !$seen{ $_ + 0 }++,
+            map ref $_->getNodeValue? $_->getParent: $_,
+            @$selected;
+
+        foreach my $node ( @unique_nodes ) {
+            if ( $node->getNodeValue eq 'AND' ) {
+                $node->setNodeValue('OR');
+            }
+            else {
+                $node->setNodeValue('AND');
+            }
+        }
+    }
+    else {
+        push( @results, [ _("error: nothing to toggle"), -1 ] );
+    }
+}
+
+if ( @$new && @$selected ) {
+    my %seen;
+    my @non_siblings_selected = grep !$seen{ $_->getParent }++, @$selected;
+
+    foreach ( @$new ) {
+        my $add = $_->clone;
+        foreach my $sel( @non_siblings_selected ) {
+            my $newindex = $sel->getIndex + 1;
+            $sel->insertSibling( $newindex, $add );
+        }
+        $add->getParent->setNodeValue( $ARGS->{'and_or'} );
+        push @NewSelection, $add;
+    }
+    @$selected = ();
+}
+elsif ( @$new ) {
+    foreach ( @$new ) {
+        my $add = $_->clone;
+        $tree->addChild( $add );
+        push @NewSelection, $add;
+    }
+    $tree->setNodeValue( $ARGS->{'and_or'} );
+}
+$_->DESTROY foreach @$new;
+
+push @$selected, @NewSelection;
+
+$tree->prune_childless_aggregators;
+
+return @results;
+}
+1;
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index fa10b35..915d5b5 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -225,7 +225,7 @@ foreach my $arg ( keys %ARGS ) {
                 $op = "IS NOT";
             }
 
-            # This isn't "right", but...
+            # This is not "right", but...
             # It has to be this way until #5182 is fixed
             $value = "'NULL'";
         }
@@ -245,12 +245,12 @@ foreach my $arg ( keys %ARGS ) {
 }
 
 # }}}
-
-push @actions, $m->comp('Elements/EditQuery:Process',
-    %ARGS,
-    tree     => $tree,
-    selected => \@current_values,
-    new      => \@new_values,
+use RT::Interface::Web::QueryBuilder;
+push @actions, RT::Interface::Web::QueryBuilder->process_query(
+    \%ARGS,
+    $tree,
+    \@current_values,
+    \@new_values,
 );
 
 # {{{ Rebuild $Query based on the additions / movements
@@ -307,7 +307,7 @@ if ($new_query) {
     $query_string = 'new_query=1';
 }
 elsif ( $query{'query'} ) {
-    $query_string = $m->comp('/Elements/QueryString', %query );
+$query_string = URI->new->query_form( %query );
 }
 
 # }}}
diff --git a/share/html/Search/Elements/EditQuery b/share/html/Search/Elements/EditQuery
index c3f0d12..19f9cc8 100644
--- a/share/html/Search/Elements/EditQuery
+++ b/share/html/Search/Elements/EditQuery
@@ -68,176 +68,3 @@ $description => undef
 $optionlist => ''
 $actions => []
 </%ARGS>
-
-<%METHOD Process>
-<%ARGS>
-$tree
-$selected
- at new       => ()
-</%ARGS>
-<%INIT>
-
-my @NewSelection = ();
-
-my @results;
-if ( $ARGS{'up'} || $ARGS{'down'} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            my $index = $value->getIndex;
-            my $newindex = $index;
-            $newindex++ if $ARGS{'down'};
-            $newindex-- if $ARGS{'up'};
-            if ( $newindex < 0 || $newindex >= $parent->getChildCount ) {
-                push( @results, [ _("error: can't move up"), -1 ] ) if $ARGS{'up'};
-                push( @results, [ _("error: can't move down"), -1 ] ) if $ARGS{'down'};
-                next;
-            }
-
-            $parent->removeChild( $index );
-            $parent->insertChild( $newindex, $value );
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS{"left"} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            if( $value->isRoot || $parent->isRoot ) {
-                push( @results, [ _("error: can't move left"), -1 ] );
-                next;
-            }
-
-            my $grandparent = $parent->getParent;
-            if( $grandparent->isRoot ) {
-                push( @results, [ _("error: can't move left"), -1 ] );
-                next;
-            }
-            
-            my $index = $parent->getIndex;
-            $parent->removeChild($value);
-            $grandparent->insertChild( $index, $value );
-            if ( $parent->isLeaf ) {
-                $grandparent->removeChild($parent);
-            }
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS{"right"} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            my $index  = $value->getIndex;
-
-            my $newparent;
-            if ( $index > 0 ) {
-                my $sibling = $parent->getChild( $index - 1 );
-                $newparent = $sibling unless $sibling->isLeaf;
-            }
-            $newparent ||= RT::Interface::Web::QueryBuilder::Tree->new( $ARGS{'and_or'} || 'AND', $parent );
-
-            $parent->removeChild($value);
-            $newparent->addChild($value);
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS{"delete_clause"} ) {
-    if (@$selected) {
-        my (@top);
-        my %Selected = map { $_ => 1 } @$selected;
-        foreach my $node ( @$selected ) {
-            my $tmp = $node->getParent;
-            while ( !$Selected{ $tmp } && !$tmp->isRoot ) {
-                $tmp = $tmp->getParent;
-            }
-            next if $Selected{ $tmp };
-            push @top, $node;
-        }
-
-        my %seen;
-        my @non_siblings_top = grep !$seen{ $_->getParent }++, @top;
-
-        foreach ( @new ) {
-            my $add = $_->clone;
-            foreach my $sel( @non_siblings_top ) {
-                my $newindex = $sel->getIndex + 1;
-                $sel->insertSibling( $newindex, $add );
-            }
-            $add->getParent->setNodeValue( $ARGS{'and_or'} );
-            push @NewSelection, $add;
-        }
-        @new = ();
-    
-        while( my $node = shift @top ) {
-            my $parent = $node->getParent;
-            $parent->removeChild($node);
-            $node->DESTROY;
-        }
-        @$selected = ();
-    }
-    else {
-        push( @results, [ _("error: nothing to delete"), -1 ] );
-    }
-}
-elsif ( $ARGS{"toggle"} ) {
-    if (@$selected) {
-        my %seen;
-        my @unique_nodes = grep !$seen{ $_ + 0 }++,
-            map ref $_->getNodeValue? $_->getParent: $_,
-            @$selected;
-
-        foreach my $node ( @unique_nodes ) {
-            if ( $node->getNodeValue eq 'AND' ) {
-                $node->setNodeValue('OR');
-            }
-            else {
-                $node->setNodeValue('AND');
-            }
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to toggle"), -1 ] );
-    }
-}
-
-if ( @new && @$selected ) {
-    my %seen;
-    my @non_siblings_selected = grep !$seen{ $_->getParent }++, @$selected;
-
-    foreach ( @new ) {
-        my $add = $_->clone;
-        foreach my $sel( @non_siblings_selected ) {
-            my $newindex = $sel->getIndex + 1;
-            $sel->insertSibling( $newindex, $add );
-        }
-        $add->getParent->setNodeValue( $ARGS{'and_or'} );
-        push @NewSelection, $add;
-    }
-    @$selected = ();
-}
-elsif ( @new ) {
-    foreach ( @new ) {
-        my $add = $_->clone;
-        $tree->addChild( $add );
-        push @NewSelection, $add;
-    }
-    $tree->setNodeValue( $ARGS{'and_or'} );
-}
-$_->DESTROY foreach @new;
-
-push @$selected, @NewSelection;
-
-$tree->prune_childless_aggregators;
-
-return @results;
-</%INIT>
-</%METHOD>

commit b2bbf538585fbb95e27693eb7b0f3115e1b294c1
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 14:28:39 2009 -0500

    tiny change to how we use base in RT/I18N.pm

diff --git a/lib/RT/I18N.pm b/lib/RT/I18N.pm
index f4c45df..a8d1b11 100755
--- a/lib/RT/I18N.pm
+++ b/lib/RT/I18N.pm
@@ -59,7 +59,7 @@ use warnings;
 
 use Locale::Maketext 1.04;
 use Locale::Maketext::Lexicon 0.25;
-use base ('Locale::Maketext::Fuzzy');
+use base 'Locale::Maketext::Fuzzy';
 
 use Encode;
 use MIME::Entity;

commit 7dc91a5149e5743f6ac946bd23593184f0e24d60
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 14:29:47 2009 -0500

    Added a new format_query_params method to RT::Interface::Web to replace /Elements/QueryString

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index c948e83..a3a8119 100755
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -64,6 +64,8 @@ package RT::Interface::Web;
 use RT::Report::Tickets;
 use RT::System;
 use RT::SavedSearches;
+use RT::Interface::Web::QueryBuilder;
+
 use URI qw();
 use Digest::MD5 ();
 use Encode qw();
@@ -289,6 +291,18 @@ sub strip_content {
     return $content;
 }
 
+
+
+sub format_query_params {
+	my $self = shift;
+	my %params = @_;
+
+	my $uri = URI->new;
+	$uri->query_form(%params);
+	return $uri->query;
+}
+
+
 package HTML::Mason::Commands;
 
 use vars qw/$r $m/;
@@ -1493,4 +1507,5 @@ sub _detailed_messages {
 }
 
 
+
 1;

commit c82f2934a4621d3cde7bb2a591739d437ce77f53
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 14:30:36 2009 -0500

    extract saved search related display logic from mason components into a library.

diff --git a/lib/RT/Interface/Web/QueryBuilder.pm b/lib/RT/Interface/Web/QueryBuilder.pm
index 788a9de..a699d67 100644
--- a/lib/RT/Interface/Web/QueryBuilder.pm
+++ b/lib/RT/Interface/Web/QueryBuilder.pm
@@ -3,173 +3,314 @@ use warnings;
 use strict;
 
 sub process_query {
-	my $self = shift;
-	my $ARGS = shift;
-	my $tree = shift;
-	my $selected = shift;
-	my $new = shift || [];
-
-my @NewSelection = ();
-
-my @results;
-if ( $ARGS->{'up'} || $ARGS->{'down'} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            my $index = $value->getIndex;
-            my $newindex = $index;
-            $newindex++ if $ARGS->{'down'};
-            $newindex-- if $ARGS->{'up'};
-            if ( $newindex < 0 || $newindex >= $parent->getChildCount ) {
-                push( @results, [ _("error: can't move up"), -1 ] ) if $ARGS->{'up'};
-                push( @results, [ _("error: can't move down"), -1 ] ) if $ARGS->{'down'};
-                next;
-            }
+    my $self     = shift;
+    my $ARGS     = shift;
+    my $tree     = shift;
+    my $selected = shift;
+    my $new      = shift || [];
 
-            $parent->removeChild( $index );
-            $parent->insertChild( $newindex, $value );
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS->{"left"} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            if( $value->isRoot || $parent->isRoot ) {
-                push( @results, [ _("error: can't move left"), -1 ] );
-                next;
+    my @NewSelection = ();
+
+    my @results;
+    if ( $ARGS->{'up'} || $ARGS->{'down'} ) {
+        if (@$selected) {
+            foreach my $value (@$selected) {
+                my $parent   = $value->getParent;
+                my $index    = $value->getIndex;
+                my $newindex = $index;
+                $newindex++ if $ARGS->{'down'};
+                $newindex-- if $ARGS->{'up'};
+                if ( $newindex < 0 || $newindex >= $parent->getChildCount ) {
+                    push( @results, [ _("error: can't move up"),   -1 ] ) if $ARGS->{'up'};
+                    push( @results, [ _("error: can't move down"), -1 ] ) if $ARGS->{'down'};
+                    next;
+                }
+
+                $parent->removeChild($index);
+                $parent->insertChild( $newindex, $value );
             }
+        } else {
+            push( @results, [ _("error: nothing to move"), -1 ] );
+        }
+    } elsif ( $ARGS->{"left"} ) {
+        if (@$selected) {
+            foreach my $value (@$selected) {
+                my $parent = $value->getParent;
+                if ( $value->isRoot || $parent->isRoot ) {
+                    push( @results, [ _("error: can't move left"), -1 ] );
+                    next;
+                }
+
+                my $grandparent = $parent->getParent;
+                if ( $grandparent->isRoot ) {
+                    push( @results, [ _("error: can't move left"), -1 ] );
+                    next;
+                }
 
-            my $grandparent = $parent->getParent;
-            if( $grandparent->isRoot ) {
-                push( @results, [ _("error: can't move left"), -1 ] );
-                next;
+                my $index = $parent->getIndex;
+                $parent->removeChild($value);
+                $grandparent->insertChild( $index, $value );
+                if ( $parent->isLeaf ) {
+                    $grandparent->removeChild($parent);
+                }
             }
-            
-            my $index = $parent->getIndex;
-            $parent->removeChild($value);
-            $grandparent->insertChild( $index, $value );
-            if ( $parent->isLeaf ) {
-                $grandparent->removeChild($parent);
+        } else {
+            push( @results, [ _("error: nothing to move"), -1 ] );
+        }
+    } elsif ( $ARGS->{"right"} ) {
+        if (@$selected) {
+            foreach my $value (@$selected) {
+                my $parent = $value->getParent;
+                my $index  = $value->getIndex;
+
+                my $newparent;
+                if ( $index > 0 ) {
+                    my $sibling = $parent->getChild( $index - 1 );
+                    $newparent = $sibling unless $sibling->isLeaf;
+                }
+                $newparent ||= RT::Interface::Web::QueryBuilder::Tree->new( $ARGS->{'and_or'} || 'AND', $parent );
+
+                $parent->removeChild($value);
+                $newparent->addChild($value);
             }
+        } else {
+            push( @results, [ _("error: nothing to move"), -1 ] );
         }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS->{"right"} ) {
-    if (@$selected) {
-        foreach my $value (@$selected) {
-            my $parent = $value->getParent;
-            my $index  = $value->getIndex;
-
-            my $newparent;
-            if ( $index > 0 ) {
-                my $sibling = $parent->getChild( $index - 1 );
-                $newparent = $sibling unless $sibling->isLeaf;
+    } elsif ( $ARGS->{"delete_clause"} ) {
+        if (@$selected) {
+            my (@top);
+            my %Selected = map { $_ => 1 } @$selected;
+            foreach my $node (@$selected) {
+                my $tmp = $node->getParent;
+                while ( !$Selected{$tmp} && !$tmp->isRoot ) {
+                    $tmp = $tmp->getParent;
+                }
+                next if $Selected{$tmp};
+                push @top, $node;
+            }
+
+            my %seen;
+            my @non_siblings_top = grep !$seen{ $_->getParent }++, @top;
+
+            foreach (@$new) {
+                my $add = $_->clone;
+                foreach my $sel (@non_siblings_top) {
+                    my $newindex = $sel->getIndex + 1;
+                    $sel->insertSibling( $newindex, $add );
+                }
+                $add->getParent->setNodeValue( $ARGS->{'and_or'} );
+                push @NewSelection, $add;
             }
-            $newparent ||= RT::Interface::Web::QueryBuilder::Tree->new( $ARGS->{'and_or'} || 'AND', $parent );
+            @$new = ();
 
-            $parent->removeChild($value);
-            $newparent->addChild($value);
+            while ( my $node = shift @top ) {
+                my $parent = $node->getParent;
+                $parent->removeChild($node);
+                $node->DESTROY;
+            }
+            @$selected = ();
+        } else {
+            push( @results, [ _("error: nothing to delete"), -1 ] );
         }
-    }
-    else {
-        push( @results, [ _("error: nothing to move"), -1 ] );
-    }
-}
-elsif ( $ARGS->{"delete_clause"} ) {
-    if (@$selected) {
-        my (@top);
-        my %Selected = map { $_ => 1 } @$selected;
-        foreach my $node ( @$selected ) {
-            my $tmp = $node->getParent;
-            while ( !$Selected{ $tmp } && !$tmp->isRoot ) {
-                $tmp = $tmp->getParent;
+    } elsif ( $ARGS->{"toggle"} ) {
+        if (@$selected) {
+            my %seen;
+            my @unique_nodes = grep !$seen{ $_ + 0 }++, map ref $_->getNodeValue ? $_->getParent : $_, @$selected;
+
+            foreach my $node (@unique_nodes) {
+                if ( $node->getNodeValue eq 'AND' ) {
+                    $node->setNodeValue('OR');
+                } else {
+                    $node->setNodeValue('AND');
+                }
             }
-            next if $Selected{ $tmp };
-            push @top, $node;
+        } else {
+            push( @results, [ _("error: nothing to toggle"), -1 ] );
         }
+    }
 
+    if ( @$new && @$selected ) {
         my %seen;
-        my @non_siblings_top = grep !$seen{ $_->getParent }++, @top;
+        my @non_siblings_selected = grep !$seen{ $_->getParent }++, @$selected;
 
-        foreach ( @$new ) {
+        foreach (@$new) {
             my $add = $_->clone;
-            foreach my $sel( @non_siblings_top ) {
+            foreach my $sel (@non_siblings_selected) {
                 my $newindex = $sel->getIndex + 1;
                 $sel->insertSibling( $newindex, $add );
             }
             $add->getParent->setNodeValue( $ARGS->{'and_or'} );
             push @NewSelection, $add;
         }
-        @$new = ();
-    
-        while( my $node = shift @top ) {
-            my $parent = $node->getParent;
-            $parent->removeChild($node);
-            $node->DESTROY;
-        }
         @$selected = ();
+    } elsif (@$new) {
+        foreach (@$new) {
+            my $add = $_->clone;
+            $tree->addChild($add);
+            push @NewSelection, $add;
+        }
+        $tree->setNodeValue( $ARGS->{'and_or'} );
     }
-    else {
-        push( @results, [ _("error: nothing to delete"), -1 ] );
-    }
+    $_->DESTROY foreach @$new;
+
+    push @$selected, @NewSelection;
+
+    $tree->prune_childless_aggregators;
+
+    return @results;
 }
-elsif ( $ARGS->{"toggle"} ) {
-    if (@$selected) {
-        my %seen;
-        my @unique_nodes = grep !$seen{ $_ + 0 }++,
-            map ref $_->getNodeValue? $_->getParent: $_,
-            @$selected;
 
-        foreach my $node ( @unique_nodes ) {
-            if ( $node->getNodeValue eq 'AND' ) {
-                $node->setNodeValue('OR');
-            }
-            else {
-                $node->setNodeValue('AND');
-            }
-        }
-    }
-    else {
-        push( @results, [ _("error: nothing to toggle"), -1 ] );
+
+sub load_saved_search {
+    my $self          = shift;
+    my $ARGS          = shift;
+    my $query         = shift;
+    my $saved_search  = shift;
+    my $search_fields = shift || [qw( query format order_by order rows_per_page)];
+
+    $saved_search->{'id'}          = $ARGS->{'saved_search_id'}          || 'new';
+    $saved_search->{'description'} = $ARGS->{'saved_search_description'} || undef;
+    $saved_search->{'Privacy'}     = $ARGS->{'saved_search_owner'}       || undef;
+
+    my @results;
+
+    if ( $ARGS->{'saved_search_revert'} ) {
+        $ARGS->{'saved_search_load'} = $saved_search->{'id'};
     }
-}
 
-if ( @$new && @$selected ) {
-    my %seen;
-    my @non_siblings_selected = grep !$seen{ $_->getParent }++, @$selected;
+    if ( $ARGS->{'saved_search_load'} ) {
+        my ( $container, $id ) = _parse_saved_search( $ARGS->{'saved_search_load'} );
+        my $search = $container->attributes->with_id($id);
+
+        $saved_search->{'id'}          = $ARGS->{'saved_search_load'};
+        $saved_search->{'object'}      = $search;
+        $saved_search->{'description'} = $search->description;
+        $query->{$_} = $search->sub_value($_) foreach @$search_fields;
+
+        if ( $ARGS->{'saved_search_revert'} ) {
+            push @results, _( 'Loaded original "%1" saved search', $saved_search->{'description'} );
+        } else {
+            push @results, _( 'Loaded saved search "%1"', $saved_search->{'description'} );
+        }
+    } elsif ( $ARGS->{'saved_search_delete'} ) {
+
+        # We set $SearchId to 'new' above already, so peek into the %ARGS
+        my ( $container, $id ) = _parse_saved_search( $saved_search->{'id'} );
+        if ( $container && $container->id ) {
 
-    foreach ( @$new ) {
-        my $add = $_->clone;
-        foreach my $sel( @non_siblings_selected ) {
-            my $newindex = $sel->getIndex + 1;
-            $sel->insertSibling( $newindex, $add );
+            # We have the object the entry is an attribute on; delete the entry...
+            $container->attributes->delete_entry( name => 'saved_search', id => $id );
+        }
+        $saved_search->{'id'}          = 'new';
+        $saved_search->{'object'}      = undef;
+        $saved_search->{'description'} = undef;
+        push @results, _("Deleted saved search");
+    } elsif ( $ARGS->{'saved_search_copy'} ) {
+        my ( $container, $id ) = _parse_saved_search( $ARGS->{'saved_search_id'} );
+        $saved_search->{'object'} = $container->attributes->withid($id);
+        if (   $ARGS->{'saved_search_description'}
+            && $ARGS->{'saved_search_description'} ne $saved_search->{'object'}->description )
+        {
+            $saved_search->{'description'} = $ARGS->{'saved_search_description'};
+        } else {
+            $saved_search->{'description'} = _( "%1 copy", $saved_search->{'object'}->description );
         }
-        $add->getParent->setNodeValue( $ARGS->{'and_or'} );
-        push @NewSelection, $add;
+        $saved_search->{'id'}     = 'new';
+        $saved_search->{'object'} = undef;
     }
-    @$selected = ();
-}
-elsif ( @$new ) {
-    foreach ( @$new ) {
-        my $add = $_->clone;
-        $tree->addChild( $add );
-        push @NewSelection, $add;
+
+    if (   $saved_search->{'id'}
+        && $saved_search->{'id'} ne 'new'
+        && !$saved_search->{'object'} )
+    {
+        my ( $container, $id ) = _parse_saved_search( $ARGS->{'saved_search_id'} );
+        $saved_search->{'object'} = $container->attributes->with_id($id);
+        $saved_search->{'description'} ||= $saved_search->{'object'}->description;
     }
-    $tree->setNodeValue( $ARGS->{'and_or'} );
+
+    return @results;
 }
-$_->DESTROY foreach @$new;
 
-push @$selected, @NewSelection;
 
-$tree->prune_childless_aggregators;
+sub save_search {
+    my $self          = shift;
+    my $ARGS          = shift;
+    my $query         = shift;
+    my $saved_search  = shift;
+    my $search_fields = shift || [qw( query format order_by order rows_per_page)];
+
+    return unless $ARGS->{'saved_search_save'} || $ARGS->{'saved_search_copy'};
+
+    my @results;
+    my $obj  = $saved_search->{'object'};
+    my $id   = $saved_search->{'id'};
+    my $desc = $saved_search->{'description'};
+
+    my $privacy = $saved_search->{'Privacy'};
+
+    my %params = map { $_ => $query->{$_} } @$search_fields;
+    my ( $new_obj_type, $new_obj_id ) = split( /\-/, ( $privacy || '' ) );
 
-return @results;
+    if ( $obj && $obj->id ) {
+
+        # permission check
+        if ( $obj->object->isa('RT::System') ) {
+            unless ( Jifty->web->current_user->has_right( object => RT->system, right => 'SuperUser' ) ) {
+                push @results, _("No permission to save system-wide searches");
+                return @results;
+            }
+        }
+
+        $obj->set_sub_values(%params);
+        $obj->set_description($desc);
+
+        my $obj_type = ref( $obj->object );
+
+        # We need to get current obj_id now, because when we change obj_type to
+        # RT::System, $obj->object->id returns 1, not the old one :(
+        my $obj_id = $obj->object->id;
+
+        if ( $new_obj_type && $new_obj_id ) {
+            my ( $val, $msg );
+            if ( $new_obj_type ne $obj_type ) {
+                ( $val, $msg ) = $obj->set_objectType($new_obj_type);
+                push @results, _( 'Unable to set privacy object: %1', $msg ) unless ($val);
+            }
+            if ( $new_obj_id != $obj_id ) {
+                ( $val, $msg ) = $obj->set_objectid($new_obj_id);
+                push @results, _( 'Unable to set privacy id: %1', $msg ) unless ($val);
+            }
+        } else {
+            push @results, _('Unable to determine object type or id');
+        }
+        push @results, _( 'Updated saved search "%1"', $desc );
+    } elsif ( $id eq 'new' ) {
+        my $saved_search = RT::SavedSearch->new();
+        my ( $status, $msg ) = $saved_search->save(
+            privacy       => $privacy,
+            name          => $desc,
+            type          => $saved_search->{'type'},
+            search_params => \%params,
+        );
+
+        if ($status) {
+            $saved_search->{'object'} = Jifty->web->current_user->user_object->attributes->with_id( $saved_search->id );
+
+            # Build new SearchId
+            $saved_search->{'id'}
+                = ref( Jifty->web->current_user->user_object ) . '-'
+                . Jifty->web->current_user->user_object->id
+                . '-SavedSearch-'
+                . $saved_search->{'object'}->id;
+        } else {
+            push @results, _("Can't find a saved search to work with") . ': ' . _($msg);
+        }
+    } else {
+        push @results, _("Can't save this search");
+    }
+
+    return @results;
 }
+
+
 1;
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 915d5b5..93b69ed 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -125,7 +125,7 @@ for( qw(query format order_by order rows_per_page) ) {
 }
 
 my %saved_search;
-my @actions = $m->comp( 'Elements/EditSearches:Init', %ARGS, query => \%query, saved_search => \%saved_search);
+my @actions = RT::Interface::Web::QueryBuilder->load_saved_search(\%ARGS, \%query, \%saved_search);
 
 if ( $new_query ) {
 
@@ -278,7 +278,8 @@ my ( $AvailableColumns, $current_format );
 # }}}
 
 # if we're asked to save the current search, save it
-push @actions, $m->comp( 'Elements/EditSearches:Save', %ARGS, query => \%query, saved_search => \%saved_search);
+push @actions, RT::Interface::Web::QueryBuilder->save_search(\%ARGS, \%query, \%saved_search);
+
 
 # {{{ Push the updates into the session so we don't loose 'em
 
@@ -307,7 +308,7 @@ if ($new_query) {
     $query_string = 'new_query=1';
 }
 elsif ( $query{'query'} ) {
-$query_string = URI->new->query_form( %query );
+$query_string = RT::Interface::Web->format_query_params( %query );
 }
 
 # }}}
diff --git a/share/html/Search/Elements/EditSearches b/share/html/Search/Elements/EditSearches
index fa0be1a..5bed321 100644
--- a/share/html/Search/Elements/EditSearches
+++ b/share/html/Search/Elements/EditSearches
@@ -135,157 +135,3 @@ $allow_copy     => 1
 $title         => _('Saved searches')
 </%ARGS>
 
-<%METHOD Init>
-<%ARGS>
-$query       => {}
-$saved_search => {}
- at search_fields => qw(Query format order_by order rows_per_page)
-</%ARGS>
-<%INIT>
-
-
-$saved_search->{'id'}          = $ARGS{'saved_search_id'}          || 'new';
-$saved_search->{'description'} = $ARGS{'saved_search_description'} || undef;
-$saved_search->{'Privacy'}     = $ARGS{'saved_search_owner'}       || undef;
-
-my @results;
-
-if ( $ARGS{'saved_search_revert'} ) {
-    $ARGS{'saved_search_load'} = $saved_search->{'id'};
-}
-
-if ( $ARGS{'saved_search_load'} ) {
-    my ($container, $id ) = _parse_saved_search ($ARGS{'saved_search_load'});
-    my $search = $container->attributes->with_id( $id );
-
-    $saved_search->{'id'}          = $ARGS{'saved_search_load'};
-    $saved_search->{'object'}      = $search;
-    $saved_search->{'description'} = $search->description;
-    $query->{$_} = $search->sub_value($_) foreach @search_fields;
-
-    if ( $ARGS{'saved_search_revert'} ) {
-        push @results, _('Loaded original "%1" saved search', $saved_search->{'description'} );
-    } else {
-        push @results, _('Loaded saved search "%1"', $saved_search->{'description'} );
-    }
-}
-elsif ( $ARGS{'saved_search_delete'} ) {
-    # We set $SearchId to 'new' above already, so peek into the %ARGS
-    my ($container, $id) = _parse_saved_search( $saved_search->{'id'} );
-    if ( $container && $container->id ) {
-        # We have the object the entry is an attribute on; delete the entry...
-        $container->attributes->delete_entry( name => 'saved_search', id => $id );
-    }
-    $saved_search->{'id'}          = 'new';
-    $saved_search->{'object'}      = undef;
-    $saved_search->{'description'} = undef;
-    push @results, _("Deleted saved search");
-}
-elsif ( $ARGS{'saved_search_copy'} ) {
-    my ($container, $id ) = _parse_saved_search( $ARGS{'saved_search_id'} );
-    $saved_search->{'object'} = $container->attributes->withid( $id );
-    if ( $ARGS{'saved_search_description'} && $ARGS{'saved_search_description'} ne $saved_search->{'object'}->description ) {
-        $saved_search->{'description'} = $ARGS{'saved_search_description'};
-    } else {
-        $saved_search->{'description'} = _( "%1 copy", $saved_search->{'object'}->description );
-    }
-    $saved_search->{'id'}          = 'new';
-    $saved_search->{'object'}      = undef;
-}
-
-if ( $saved_search->{'id'} && $saved_search->{'id'} ne 'new'
-     && !$saved_search->{'object'} )
-{
-    my ($container, $id ) = _parse_saved_search( $ARGS{'saved_search_id'} );
-    $saved_search->{'object'} = $container->attributes->with_id( $id );
-    $saved_search->{'description'} ||= $saved_search->{'object'}->description;
-}
-
-return @results;
-
-</%INIT>
-</%METHOD>
-
-<%METHOD Save>
-<%ARGS>
-$query        => {}
-$saved_search  => {}
- at search_fields => qw(query format order_by order rows_per_page)
-</%ARGS>
-<%INIT>
-
-return unless $ARGS{'saved_search_save'} || $ARGS{'saved_search_copy'};
-
-my @results;
-my $obj  = $saved_search->{'object'};
-my $id   = $saved_search->{'id'};
-my $desc = $saved_search->{'description'};
-
-my $privacy = $saved_search->{'Privacy'};
-
-my %params = map { $_ => $query->{$_} } @search_fields;
-my ($new_obj_type, $new_obj_id) = split(/\-/, ($privacy || ''));
-
-if ( $obj && $obj->id ) {
-    # permission check
-    if ($obj->object->isa('RT::System')) {
-        unless (Jifty->web->current_user->has_right( object=> RT->system, right => 'SuperUser')) {
-            push @results, _("No permission to save system-wide searches");
-            return @results;
-        }
-    }
-
-    $obj->set_sub_values( %params );
-    $obj->set_description( $desc );
-
-    my $obj_type = ref($obj->object);
-    # We need to get current obj_id now, because when we change obj_type to
-    # RT::System, $obj->object->id returns 1, not the old one :(
-    my $obj_id = $obj->object->id;
-
-    if ( $new_obj_type && $new_obj_id ) {
-        my ($val, $msg);
-        if ( $new_obj_type ne $obj_type ) {
-            ($val, $msg ) = $obj->set_objectType($new_obj_type);
-            push @results, _('Unable to set privacy object: %1', $msg) unless ( $val );
-        }
-        if ( $new_obj_id != $obj_id ) {
-            ($val, $msg) = $obj->set_objectid($new_obj_id);
-            push @results, _('Unable to set privacy id: %1', $msg) unless ( $val );
-        }
-    } else {
-        push @results, _('Unable to determine object type or id');
-    }
-    push @results, _('Updated saved search "%1"', $desc);
-}
-elsif ( $id eq 'new' ) {
-    my $saved_search = RT::SavedSearch->new();
-    my ($status, $msg) = $saved_search->save(
-        privacy      => $privacy,
-        name         => $desc,
-        type         => $saved_search->{'type'},
-        search_params => \%params,
-    );
-
-    if ( $status ) {
-        $saved_search->{'object'} =
-            Jifty->web->current_user->user_object->attributes->with_id( $saved_search->id );
-        # Build new SearchId
-        $saved_search->{'id'} =
-                ref( Jifty->web->current_user->user_object ) . '-'
-                    . Jifty->web->current_user->user_object->id
-                    . '-SavedSearch-'
-                    . $saved_search->{'object'}->id;
-    }
-    else {
-        push @results, _("Can't find a saved search to work with").': '._($msg);
-    }
-}
-else {
-    push @results, _("Can't save this search");
-}
-
-return @results;
-
-</%INIT>
-</%METHOD>
diff --git a/share/html/Ticket/Graphs/index.html b/share/html/Ticket/Graphs/index.html
index 40ba94f..52ab0aa 100644
--- a/share/html/Ticket/Graphs/index.html
+++ b/share/html/Ticket/Graphs/index.html
@@ -84,12 +84,7 @@ foreach my $level ( 0 .. 6 ) {
     push @save_arguments, "Level-". $level ."-Properties";
 }
 my $saved_search = { type => 'Graph' };
-push @results, $m->comp( '/Search/Elements/EditSearches:Init',
-    %ARGS,
-    query        => \%ARGS,
-    saved_search  => $saved_search,
-    search_fields => \@save_arguments,
-);
+push @results, RT::Interface::Web::QueryBuilder->load_saved_search(\%ARGS, \%ARGS, $saved_search, \@save_arguments);
 
 my $id = $ARGS{'id'};
 my $ticket = load_ticket( $id );
@@ -104,12 +99,7 @@ if ( $ARGS{'show_links'} && !ref $ARGS{'show_links'} ) {
 $ARGS{'show_links'} = [ grep $_ ne $ARGS{'leading_link'}, @{ $ARGS{'show_links'} } ];
 $ARGS{'max_depth'} = 3 unless defined $ARGS{'max_depth'} && length $ARGS{'max_depth'};
 
-push @results, $m->comp( '/Search/Elements/EditSearches:Save',
-    %ARGS,
-    query        => \%ARGS,
-    saved_search  => $saved_search,
-    search_fields => \@save_arguments,
-);
+push @results, RT::Interface::Web::QueryBuilder->save_search(\%ARGS, \%ARGS, $saved_search, \@save_arguments);
 
 my $title = _( "Ticket #%1 relationships graph", $id );
 </%INIT>

commit a76a42f2ab98429c6b4b952249210d96b11c0f2b
Merge: c82f293 d70f744
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 14:34:59 2009 -0500

    Merge commit 'origin/3.999-trunk' into librarize-search-logic
    
    * commit 'origin/3.999-trunk':
      ShowLinks was made aware of autovivification of queue objects


commit 048c9f30b546c1856f6163808c45c5357b638e22
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 14:45:26 2009 -0500

    remove  {{{ }}} and tidy Build.html

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 93b69ed..060801d 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -1,4 +1,4 @@
-%# BEGIN BPS TAGGED BLOCK {{{
+%# BEGIN BPS TAGGED BLOCK 
 %# 
 %# COPYRIGHT:
 %# 
@@ -44,7 +44,7 @@
 %# works based on those contributions, and sublicense and distribute
 %# those contributions and any derivatives thereof.
 %# 
-%# END BPS TAGGED BLOCK }}}
+%# END BPS TAGGED BLOCK
 %#
 %# Data flow here:
 %#   The page receives a Query from the previous page, and maybe arguments
@@ -120,14 +120,14 @@
 use RT::Interface::Web::QueryBuilder::Tree;
 
 my %query;
-for( qw(query format order_by order rows_per_page) ) {
+for (qw(query format order_by order rows_per_page)) {
     $query{$_} = $ARGS{$_};
 }
 
 my %saved_search;
-my @actions = RT::Interface::Web::QueryBuilder->load_saved_search(\%ARGS, \%query, \%saved_search);
+my @actions = RT::Interface::Web::QueryBuilder->load_saved_search( \%ARGS, \%query, \%saved_search );
 
-if ( $new_query ) {
+if ($new_query) {
 
     # Wipe all data-carrying variables clear if we want a new
     # search, or we're deleting an old one..
@@ -141,31 +141,32 @@ if ( $new_query ) {
     Jifty->web->session->get('tickets')->clean_slate if defined Jifty->web->session->get('tickets');
 }
 
-{ # Attempt to load what we can from the session and preferences, set defaults
+{    # Attempt to load what we can from the session and preferences, set defaults
 
     my $current = Jifty->web->session->get('CurrentSearchHash');
-    my $prefs = Jifty->web->current_user->user_object->preferences("SearchDisplay") || {};
-    my $default = {query => '', format => '', order_by => 'id', order => 'ASC', rows_per_page => 50 };
+    my $prefs   = Jifty->web->current_user->user_object->preferences("SearchDisplay") || {};
+    my $default = { query => '', format => '', order_by => 'id', order => 'ASC', rows_per_page => 50 };
 
-    for( qw(query format order_by order rows_per_page) ) {
+    for (qw(query format order_by order rows_per_page)) {
         $query{$_} = $current->{$_} unless defined $query{$_};
-        $query{$_} = $prefs->{$_} unless defined $query{$_};
+        $query{$_} = $prefs->{$_}   unless defined $query{$_};
         $query{$_} = $default->{$_} unless defined $query{$_};
     }
 
-    for( qw(order order_by) ) {
-        if (ref $query{$_} eq "ARRAY") {
+    for (qw(order order_by)) {
+        if ( ref $query{$_} eq "ARRAY" ) {
             $query{$_} = join( '|', @{ $query{$_} } );
         }
     }
     if ( $query{'format'} ) {
+
         # Clean unwanted junk from the format
         $query{'format'} = $m->comp( '/Elements/ScrubHTML', content => $query{'format'} );
     }
 }
 
-my $parse_query = sub  {
-    my ($string, $results) = @_;
+my $parse_query = sub {
+    my ( $string, $results ) = @_;
 
     my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
     @$results = $tree->parse_sql( query => $string );
@@ -180,33 +181,35 @@ if ( $actions[0] ) {
     return $m->comp( "Edit.html", query => $query{'query'}, actions => \@actions );
 }
 
-my @options = $tree->get_displayed_nodes;
+my @options        = $tree->get_displayed_nodes;
 my @current_values = grep defined, @options[@clauses];
-my @new_values = ();
+my @new_values     = ();
 
-# {{{ Try to find if we're adding a clause
+#  Try to find if we're adding a clause
 foreach my $arg ( keys %ARGS ) {
-    next unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/
-                && ( ref $ARGS{$arg} eq "ARRAY"
-                     ? grep $_ ne '', @{ $ARGS{$arg} }
-                     : $ARGS{$arg} ne '' );
+    next
+        unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/
+            && (ref $ARGS{$arg} eq "ARRAY"
+                ? grep $_ ne '', @{ $ARGS{$arg} }
+                : $ARGS{$arg} ne ''
+            );
 
     # We're adding a $1 clause
     my $field = $1;
 
-    my ($op, $value);
+    my ( $op, $value );
 
     #figure out if it's a grouping
     my $keyword = $ARGS{ $field . "_field" } || $field;
 
     my ( @ops, @values );
     if ( ref $ARGS{ 'value_of_' . $field } eq "ARRAY" ) {
+
         # we have many keys/values to iterate over, because there is
         # more than one CF with the same name.
         @ops    = @{ $ARGS{ $field . '_op' } };
         @values = @{ $ARGS{ 'value_of_' . $field } };
-    }
-    else {
+    } else {
         @ops    = ( $ARGS{ $field . '_op' } );
         @values = ( $ARGS{ 'value_of_' . $field } );
     }
@@ -220,16 +223,14 @@ foreach my $arg ( keys %ARGS ) {
         if ( $value eq 'NULL' && $op =~ /=/ ) {
             if ( $op eq '=' ) {
                 $op = "IS";
-            }
-            elsif ( $op eq '!=' ) {
+            } elsif ( $op eq '!=' ) {
                 $op = "IS NOT";
             }
 
             # This is not "right", but...
             # It has to be this way until #5182 is fixed
             $value = "'NULL'";
-        }
-        else {
+        } else {
             $value =~ s/'/\\'/g;
             $value = "'$value'" unless $value =~ /^\d+$/;
         }
@@ -244,74 +245,61 @@ foreach my $arg ( keys %ARGS ) {
     }
 }
 
-# }}}
 use RT::Interface::Web::QueryBuilder;
-push @actions, RT::Interface::Web::QueryBuilder->process_query(
-    \%ARGS,
-    $tree,
-    \@current_values,
-    \@new_values,
-);
+push @actions, RT::Interface::Web::QueryBuilder->process_query( \%ARGS, $tree, \@current_values, \@new_values, );
 
-# {{{ Rebuild $Query based on the additions / movements
+#  Rebuild $Query based on the additions / movements
 
 my $optionlist_arrayref;
-($query{'query'}, $optionlist_arrayref) = $tree->get_query_and_option_list(\@current_values);
+( $query{'query'}, $optionlist_arrayref ) = $tree->get_query_and_option_list( \@current_values );
 
-my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>) 
-                                  . ("&nbsp;" x (5 * $_->{DEPTH}))
-                                  . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;
-
-# }}}
+my $optionlist = join "\n", map {
+          qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
+        . ( "&nbsp;" x ( 5 * $_->{DEPTH} ) )
+        . $m->interp->apply_escapes( $_->{TEXT}, 'h' )
+        . qq(</option>)
+} @$optionlist_arrayref;
 
 my $queues = $tree->get_referenced_queues;
 
-# {{{ Deal with format changes
+#  Deal with format changes
 my ( $AvailableColumns, $current_format );
 ( $query{'format'}, $AvailableColumns, $current_format ) = $m->comp(
     'Elements/BuildFormatString',
     %ARGS,
     cfqueues => $queues,
-    format => $query{'format'},
+    format   => $query{'format'},
 );
 
-# }}}
-
 # if we're asked to save the current search, save it
-push @actions, RT::Interface::Web::QueryBuilder->save_search(\%ARGS, \%query, \%saved_search);
+push @actions, RT::Interface::Web::QueryBuilder->save_search( \%ARGS, \%query, \%saved_search );
 
+#  Push the updates into the session so we don't loose 'em
 
-# {{{ Push the updates into the session so we don't loose 'em
-
-Jifty->web->session->set('CurrentSearchHash', {
-    %query,
-    search_id    => $saved_search{'id'},
-    object      => $saved_search{'object'},
-    description => $saved_search{'description'},
-} );
-
-# }}}
+Jifty->web->session->set(
+    'CurrentSearchHash',
+    {   %query,
+        search_id   => $saved_search{'id'},
+        object      => $saved_search{'object'},
+        description => $saved_search{'description'},
+    }
+);
 
-# {{{ Show the results, if we were asked.
+#  Show the results, if we were asked.
 
 if ( $ARGS{'do_search'} ) {
     $m->comp( 'Results.html', %query );
     $m->abort;
 }
 
-# }}}
-
-# {{{ Build a query_string for the tabs
+#  Build a query_string for the tabs
 
 my $query_string = '';
 if ($new_query) {
     $query_string = 'new_query=1';
+} elsif ( $query{'query'} ) {
+    $query_string = RT::Interface::Web->format_query_params(%query);
 }
-elsif ( $query{'query'} ) {
-$query_string = RT::Interface::Web->format_query_params( %query );
-}
-
-# }}}
 
 </%INIT>
 

commit cf15d14559267c7f4f4849193a3f9dfae487f442
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 15:22:09 2009 -0500

    Replace Elements/ScrubHTML with a library routine

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index a3a8119..ea1842f 100755
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -66,9 +66,12 @@ use RT::System;
 use RT::SavedSearches;
 use RT::Interface::Web::QueryBuilder;
 
+
 use URI qw();
 use Digest::MD5 ();
 use Encode qw();
+use HTML::Scrubber;
+
 
 =head2 web_canonicalize_info();
 
@@ -302,6 +305,33 @@ sub format_query_params {
 	return $uri->query;
 }
 
+my $scrubber = HTML::Scrubber->new();
+$scrubber->default(
+    0,
+    {
+        '*'    => 0,
+        id     => 1,
+        class  => 1,
+        # Match http, ftp and relative urls
+        # XXX: we also scrub format strings with this module then allow simple config options
+        href   => qr{^(?:http:|ftp:|https:|/|__Web(?:Path|baseURL|URL)__)}i,
+        face   => 1,
+        size   => 1,
+        target => 1,
+        style  => qr{^(?:(?:color:\s*rgb\(\d+,\s*\d+,\s*\d+\))|
+                         (?:text-align:\s*))}ix,
+    }
+);
+$scrubber->deny(qw[*]);
+$scrubber->allow( qw[A B U P BR I HR BR SMALL EM FONT SPAN STRONG SUB SUP STRIKE H1 H2 H3 H4 H5 H6 DIV UL OL LI DL DT DD PRE]);
+$scrubber->comment(0);
+
+sub scrub_html {
+	my $self = shift;
+	my $content = shift;
+	return $scrubber->scrub($content);
+}
+
 
 package HTML::Mason::Commands;
 
diff --git a/share/html/Elements/CollectionAsTable/Header b/share/html/Elements/CollectionAsTable/Header
index 6bd146d..283cde1 100644
--- a/share/html/Elements/CollectionAsTable/Header
+++ b/share/html/Elements/CollectionAsTable/Header
@@ -102,7 +102,7 @@ foreach my $col ( @format ) {
     );
 
     unless( $tmp ) {
-        $title = $m->comp('/Elements/ScrubHTML', content => $title);
+        $title = RT::Interface::Web->scrub_html( $title);
     } else {
         if ( UNIVERSAL::isa( $tmp, 'CODE' ) ) {
             my @tmp = $tmp->( $title );
diff --git a/share/html/Elements/CollectionList b/share/html/Elements/CollectionList
index 015a424..89329b5 100644
--- a/share/html/Elements/CollectionList
+++ b/share/html/Elements/CollectionList
@@ -84,8 +84,8 @@ $collection->set_page_info(
 $display_format ||= $format;
 
 # Scrub the html of the format string to remove any potential nasties.
-$format = $m->comp('/Elements/ScrubHTML', content => $format);
-$display_format = $m->comp('/Elements/ScrubHTML', content => $display_format);
+$format = RT::Interface::Web->scrub_html( $format);
+$display_format = RT::Interface::Web->scrub_html( $display_format);
 
 my @format = $m->comp('/Elements/CollectionAsTable/ParseFormat', format => $display_format);
 
diff --git a/share/html/Elements/ScrubHTML b/share/html/Elements/ScrubHTML
deleted file mode 100644
index 912cc80..0000000
--- a/share/html/Elements/ScrubHTML
+++ /dev/null
@@ -1,77 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%# 
-%# COPYRIGHT:
-%# 
-%# This software is Copyright (c) 1996-2008 Best Practical Solutions, LLC
-%#                                          <jesse at bestpractical.com>
-%# 
-%# (Except where explicitly superseded by other copyright notices)
-%# 
-%# 
-%# LICENSE:
-%# 
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%# 
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%# 
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%# 
-%# 
-%# CONTRIBUTION SUBMISSION POLICY:
-%# 
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%# 
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%# 
-%# END BPS TAGGED BLOCK }}}
-<%ONCE>
-my $scrubber = new HTML::Scrubber;
-$scrubber->default(
-    0,
-    {
-        '*'    => 0,
-        id     => 1,
-        class  => 1,
-        # Match http, ftp and relative urls
-        # XXX: we also scrub format strings with this module then allow simple config options
-        href   => qr{^(?:http:|ftp:|https:|/|__Web(?:Path|baseURL|URL)__)}i,
-        face   => 1,
-        size   => 1,
-        target => 1,
-        style  => qr{^(?:(?:color:\s*rgb\(\d+,\s*\d+,\s*\d+\))|
-                         (?:text-align:\s*))}ix,
-    }
-);
-$scrubber->deny(qw[*]);
-$scrubber->allow(
-    qw[A B U P BR I HR BR SMALL EM FONT SPAN STRONG SUB SUP STRIKE H1 H2 H3 H4 H5 H6 DIV UL OL LI DL DT DD PRE]
-);
-$scrubber->comment(0);
-</%ONCE>
-<%init>
-return $scrubber->scrub($content);
-</%init>
-<%args>
-$content => undef
-</%args>
diff --git a/share/html/Elements/ShowCustomFieldText b/share/html/Elements/ShowCustomFieldText
index 6955f4a..c0b0d23 100644
--- a/share/html/Elements/ShowCustomFieldText
+++ b/share/html/Elements/ShowCustomFieldText
@@ -47,7 +47,7 @@
 %# END BPS TAGGED BLOCK }}}
 <%init>
  my $content = $object->large_content || $object->content;
- $content = $m->comp('/Elements/ScrubHTML', content => $content);
+ $content = RT::Interface::Web->scrub_html(  $content);
  $content =~ s|\n|<br />|g;
 </%init>
 <%$content|n%>
diff --git a/share/html/Elements/ShowCustomFieldWikitext b/share/html/Elements/ShowCustomFieldWikitext
index 7be0d7d..4567fec 100644
--- a/share/html/Elements/ShowCustomFieldWikitext
+++ b/share/html/Elements/ShowCustomFieldWikitext
@@ -46,7 +46,7 @@
 %# 
 %# END BPS TAGGED BLOCK }}}
 % my $content = $object->large_content || $object->content;
-% $content = $m->comp('/Elements/ScrubHTML', content => $content);
+% $content = RT::Interface::Web->scrub_html( $content);
 % my $base = $object->object->wiki_base;
 % my $wiki_content = Text::WikiFormat::format( $content."\n" , {}, { extended => 1,  absolute_links => 1, implicit_links => RT->config->get('wiki_implicit_links'), prefix => $base} );
 <%$wiki_content|n%>
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 060801d..a0332f3 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -161,7 +161,7 @@ if ($new_query) {
     if ( $query{'format'} ) {
 
         # Clean unwanted junk from the format
-        $query{'format'} = $m->comp( '/Elements/ScrubHTML', content => $query{'format'} );
+		$query{'format'} = RT::Interface::Web->scrub_html( $query{'format'} );
     }
 }
 
diff --git a/share/html/Search/Edit.html b/share/html/Search/Edit.html
index 4c7c467..9e86374 100755
--- a/share/html/Search/Edit.html
+++ b/share/html/Search/Edit.html
@@ -73,7 +73,7 @@
 </&>
 <%INIT>
 my $title = _("Edit Query");
-$format = $m->comp('/Elements/ScrubHTML', content => $format);
+$format = RT::Interface::Web->scrub_html( $format);
 my $query_string = $m->comp('/Elements/QueryString',
                            query   => $query,
                            format  => $format,
diff --git a/share/html/Ticket/Elements/ShowTransactionAttachments b/share/html/Ticket/Elements/ShowTransactionAttachments
index ae63080..28652f0 100644
--- a/share/html/Ticket/Elements/ShowTransactionAttachments
+++ b/share/html/Ticket/Elements/ShowTransactionAttachments
@@ -117,7 +117,7 @@ unless ( ($message->get_header('Content-Disposition')||"") =~ /attachment/i ) {
 
             # if it's a text/html clean the body and show it
             if ( $message->content_type =~ m{^text/(?:html|enriched)$}i ) {
-                $content = $m->comp( '/Elements/ScrubHTML', content => $content );
+                $content = RT::Interface::Web->scrub_html( $content );
                 if ( $message->content_type eq 'text/html' ) {
                     $m->comp('/Elements/MakeClicky', 
                             content => \$content, html => 1 );

commit 5dec3e324f0d46891b4cc0c7a13cfc2a6a879a83
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:27:53 2009 -0500

    librarize BuildFormatString

diff --git a/lib/RT/Interface/Web/QueryBuilder.pm b/lib/RT/Interface/Web/QueryBuilder.pm
index a699d67..6eff61f 100644
--- a/lib/RT/Interface/Web/QueryBuilder.pm
+++ b/lib/RT/Interface/Web/QueryBuilder.pm
@@ -312,5 +312,179 @@ sub save_search {
     return @results;
 }
 
+sub build_format_string {
+    my $self = shift;
+    my %args = (
+        format                  => RT->config->get('default_search_result_format'),
+        cfqueues                => undef,
+        face                    => undef,
+        size                    => undef,
+        link                    => undef,
+        title                   => undef,
+        add_col                 => undef,
+        remove_col              => undef,
+        col_up                  => undef,
+        col_down                => undef,
+        select_display_columns  => undef,
+        current_display_columns => undef,
+        @_
+    );
+
+    # All the things we can display in the format string by default
+    my @fields = qw(
+        id queue_name subject
+        status extended_status update_status
+        type owner_name requestors cc admin_cc created_by last_updated_by
+        priority initial_priority final_priority
+        time_worked time_left time_estimated
+        starts      starts_relative
+        started     started_relative
+        created     created_relative
+        last_updated last_updated_relative
+        told        told_relative
+        due         due_relative
+        resolved    resolved_relative
+        refers_to    referred_to_by
+        depends_on   depended_on_by
+        member_of    members
+        parents     children
+        Bookmark
+        NEWLINE     Bookmark
+        );    # loc_qw
+
+    my $CustomFields = RT::Model::CustomFieldCollection->new();
+    foreach my $id ( keys %{$args{cfqueues}} ) {
+
+        # Gotta load up the $queue object, since queues get stored by name now. my $id
+        my $queue = RT::Model::Queue->new();
+        $queue->load($id);
+        unless ( $queue->id ) {
+
+            # XXX TODO: This ancient code dates from a former developer
+            # we have no idea what it means or why cfqueues are so encoded.
+            $id =~ s/^.'*(.*).'*$/$1/;
+            $queue->load($id);
+        }
+        $CustomFields->limit_to_queue( $queue->id );
+    }
+    $CustomFields->limit_to_global;
+
+    while ( my $CustomField = $CustomFields->next ) {
+        push @fields, "custom_field.{" . $CustomField->name . "}";
+    }
+
+    my (@seen);
+
+    my @format = split( /,\s*/, $args{format} );
+    foreach my $field (@format) {
+        my %column = ();
+        $field =~ s/'(.*)'/$1/;
+        my ( $prefix, $suffix );
+        if ( $field =~ m/(.*)__(.*)__(.*)/ ) {
+            $prefix = $1;
+            $suffix = $3;
+            $field  = $2;
+        }
+        $field = "<blank>" if !$field;
+        $column{Prefix} = $prefix;
+        $column{Suffix} = $suffix;
+        $field =~ s/\s*(.*)\s*/$1/;
+        $column{Column} = $field;
+        push @seen, \%column;
+    }
+
+    if ( $args{remove_col} ) {
+
+        # we do this regex match to avoid a non-numeric warning
+        my ($index) = $args{current_display_columns} =~ /^(\d+)/;
+
+        my $column = $seen[$index];
+        if ($index) {
+            delete $seen[$index];
+            my @temp = @seen;
+            @seen = ();
+            foreach my $element (@temp) {
+                next unless $element;
+                push @seen, $element;
+            }
+        }
+    } elsif ( $args{add_col} ) {
+        if ( defined $args{select_display_columns} ) {
+            my $selected = $args{select_display_columns};
+            my @columns;
+            if ( ref($selected) eq 'ARRAY' ) {
+                @columns = @$selected;
+            } else {
+                push @columns, $selected;
+            }
+            foreach my $col (@columns) {
+                my %column = ();
+                $column{Column} = $col;
+
+                if ( $args{face} eq "Bold" ) {
+                    $column{Prefix} .= "<b>";
+                    $column{Suffix} .= "</b>";
+                }
+                if ( $args{face} eq "Italic" ) {
+                    $column{Prefix} .= "<i>";
+                    $column{Suffix} .= "</i>";
+                }
+                if ($args{size}) {
+                    $column{Prefix} .= "<" . Jifty->web->escape($args{size}) . ">";
+                    $column{Suffix} .= "</" . Jifty->web->escape($args{size}) . ">";
+                }
+                if ( $args{link} eq "Display" ) {
+                    $column{Prefix} .= q{<a HREF="__WebPath__/Ticket/Display.html?id=__id__">};
+                    $column{Suffix} .= "</a>";
+                } elsif ( $args{link} eq "Take" ) {
+                    $column{Prefix} .= q{<a HREF="__WebPath__/Ticket/Display.html?Action=Take&id=__id__">};
+                    $column{Suffix} .= "</a>";
+                }
+
+                if ( $args{title} ) {
+                    $column{Suffix} .= "/TITLE:" . Jifty->web->escape( $args{title} );
+                }
+                push @seen, \%column;
+            }
+        }
+    } elsif ( $args{col_up} ) {
+        my $index = $args{current_display_columns};
+        if ( defined $index && ( $index - 1 ) >= 0 ) {
+            my $column = $seen[$index];
+            $seen[$index]                  = $seen[ $index - 1 ];
+            $seen[ $index - 1 ]            = $column;
+            $args{current_display_columns} = $index - 1;
+        }
+    } elsif ( $args{col_down} ) {
+        my $index = $args{current_display_columns};
+        if ( defined $index && ( $index + 1 ) < scalar @seen ) {
+            my $column = $seen[$index];
+            $seen[$index]                  = $seen[ $index + 1 ];
+            $seen[ $index + 1 ]            = $column;
+            $args{current_display_columns} = $index + 1;
+        }
+    }
+
+    my @format_string;
+    foreach my $field (@seen) {
+        next unless $field;
+        my $row = "'";
+        $row .= $field->{'Prefix'} if defined $field->{'Prefix'};
+        $row .= "__" . (
+              $field->{'Column'} =~ m/\(/
+            ? $field->{'Column'}    # func, don't escape
+            : Jifty->web->escape( $field->{'Column'} )
+            )
+            . "__"
+            unless ( $field->{'Column'} eq "<blank>" );
+        $row .= $field->{'Suffix'} if defined $field->{'Suffix'};
+        $row .= "'";
+        push( @format_string, $row );
+    }
+
+    return ( join( ",\n", @format_string ), \@fields, \@seen );
+
+}
+
 
 1;
diff --git a/share/html/Prefs/Search.html b/share/html/Prefs/Search.html
index 8712afa..6e62506 100644
--- a/share/html/Prefs/Search.html
+++ b/share/html/Prefs/Search.html
@@ -98,8 +98,7 @@ $ARGS{'order'} = join '|', grep defined && /\S/, (ref $ARGS{'order'})? @{$ARGS{'
 $ARGS{'order_by'} = join '|', grep defined && /\S/, (ref $ARGS{'order_by'})? @{$ARGS{'order_by'}}: $ARGS{'order_by'};
 
 my ( $AvailableColumns, $current_format );
-( $ARGS{format}, $AvailableColumns, $current_format ) = $m->comp(
-    '/Search/Elements/BuildFormatString',
+( $ARGS{format}, $AvailableColumns, $current_format ) = RT::Interface::Web::QueryBuilder->build_format_string(
     cfqueues => {}, %ARGS
 );
 
diff --git a/share/html/Prefs/SearchOptions.html b/share/html/Prefs/SearchOptions.html
index c92ee4d..2136df7 100644
--- a/share/html/Prefs/SearchOptions.html
+++ b/share/html/Prefs/SearchOptions.html
@@ -96,8 +96,7 @@ $order_by     ||= ($prefs->{'order_by'} || 'id');
 ($rows_per_page =  defined( $prefs->{'rows_per_page'} ) ? $prefs->{'rows_per_page'}  : 50) unless defined ($rows_per_page);
 
 my ( $AvailableColumns, $current_format );
-( $format, $AvailableColumns, $current_format ) = $m->comp(
-    '/Search/Elements/BuildFormatString',
+( $format, $AvailableColumns, $current_format ) = RT::Interface::Web::QueryBuilder->build_format_string(
     %ARGS, format => $format
 );
 </%INIT>
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index a0332f3..bb49c89 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -264,8 +264,8 @@ my $queues = $tree->get_referenced_queues;
 
 #  Deal with format changes
 my ( $AvailableColumns, $current_format );
-( $query{'format'}, $AvailableColumns, $current_format ) = $m->comp(
-    'Elements/BuildFormatString',
+
+( $query{'format'}, $AvailableColumns, $current_format ) = RT::Interface::Web::QueryBuilder->build_format_string(
     %ARGS,
     cfqueues => $queues,
     format   => $query{'format'},
diff --git a/share/html/Search/Elements/BuildFormatString b/share/html/Search/Elements/BuildFormatString
deleted file mode 100644
index eca3fd9..0000000
--- a/share/html/Search/Elements/BuildFormatString
+++ /dev/null
@@ -1,230 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%# 
-%# COPYRIGHT:
-%#  
-%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
-%#                                          <jesse at bestpractical.com>
-%# 
-%# (Except where explicitly superseded by other copyright notices)
-%# 
-%# 
-%# LICENSE:
-%# 
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%# 
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%# 
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/copyleft/gpl.html.
-%# 
-%# 
-%# CONTRIBUTION SUBMISSION POLICY:
-%# 
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%# 
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%# 
-%# END BPS TAGGED BLOCK }}}
-<%ARGS>
-$format => RT->config->get('default_search_result_format')
-%cfqueues => ()
-$face => undef
-$size => undef
-$link => undef
-$title => undef
-
-$add_col => undef
-$remove_col => undef
-$col_up => undef
-$col_down => undef
-
-$select_display_columns => undef
-$current_display_columns => undef
-</%ARGS>
-
-<%init>
-# This can't be in a <once> block, because otherwise we return the
-# same \@fields every request, and keep tacking more CustomFields onto
-# it -- and it grows per request.
-
-# All the things we can display in the format string by default
-my @fields = qw(
-    id queue_name subject
-    status extended_status update_status
-    type owner_name requestors cc admin_cc created_by last_updated_by
-    priority initial_priority final_priority
-    time_worked time_left time_estimated
-    starts      starts_relative
-    started     started_relative
-    created     created_relative
-    last_updated last_updated_relative
-    told        told_relative
-    due         due_relative
-    resolved    resolved_relative
-    refers_to    referred_to_by
-    depends_on   depended_on_by
-    member_of    members
-    parents     children
-    Bookmark
-    NEWLINE     Bookmark
-); # loc_qw
-
-$m->callback( callback_once => 1, callback_name => 'SetFieldsOnce', Fields => \@fields );
-
-my $CustomFields = RT::Model::CustomFieldCollection->new( current_user => Jifty->web->current_user);
-foreach my $id (keys %cfqueues) {
-    # Gotta load up the $queue object, since queues get stored by name now. my $id
-    my $queue = RT::Model::Queue->new( current_user => Jifty->web->current_user );
-    $queue->load($id);
-    unless ($queue->id) {
-        # XXX TODO: This ancient code dates from a former developer
-        # we have no idea what it means or why cfqueues are so encoded.
-        $id =~ s/^.'*(.*).'*$/$1/;
-        $queue->load($id);
-    }
-    $CustomFields->limit_to_queue($queue->id);
-}
-$CustomFields->limit_to_global;
-
-while ( my $CustomField = $CustomFields->next ) {
-    push @fields, "custom_field.{" . $CustomField->name . "}";
-}
-
-$m->callback( Fields => \@fields, args_ref => \%ARGS );
-
-my ( @seen);
-
-$format ||= RT->config->get('default_search_result_format');
-my @format = split( /,\s*/, $format );
-foreach my $field (@format) {
-    my %column = ();
-    $field =~ s/'(.*)'/$1/;
-    my ( $prefix, $suffix );
-    if ( $field =~ m/(.*)__(.*)__(.*)/ ) {
-        $prefix = $1;
-        $suffix = $3;
-        $field  = $2;
-    }
-    $field = "<blank>" if !$field;
-    $column{Prefix} = $prefix;
-    $column{Suffix} = $suffix;
-    $field =~ s/\s*(.*)\s*/$1/;
-    $column{Column} = $field;
-    push @seen, \%column;
-}
-
-if ( $remove_col ) {
-    # we do this regex match to avoid a non-numeric warning
-    my ($index) = $current_display_columns =~ /^(\d+)/;
-    
-    my $column = $seen[$index];
-    if ($index) {
-        delete $seen[$index];
-        my @temp = @seen;
-        @seen = ();
-        foreach my $element (@temp) {
-            next unless $element;
-            push @seen, $element;
-        }
-    }
-}
-elsif ( $add_col ) {
-    if ( defined $select_display_columns ) {
-        my $selected = $select_display_columns;
-        my @columns;
-        if (ref($selected) eq 'ARRAY') {
-            @columns = @$selected;
-        } else {
-            push @columns, $selected;
-        }
-        foreach my $col (@columns) {
-            my %column = ();
-            $column{Column} = $col;
-
-            if ( $face eq "Bold" ) {
-                $column{Prefix} .= "<b>";
-                $column{Suffix} .= "</b>";
-            }
-            if ( $face eq "Italic" ) {
-                $column{Prefix} .= "<i>";
-                $column{Suffix} .= "</i>";
-            }
-            if ($size) {
-                $column{Prefix} .= "<" . $m->interp->apply_escapes( $size,  'h' ) . ">";
-                $column{Suffix} .= "</" . $m->interp->apply_escapes( $size, 'h' ) . ">";
-            }
-            if ( $link eq "Display" ) {
-                $column{Prefix} .= q{<a HREF="__WebPath__/Ticket/Display.html?id=__id__">};
-                $column{Suffix} .= "</a>";
-            }
-            elsif ( $link eq "Take" ) {
-                $column{Prefix} .= q{<a HREF="__WebPath__/Ticket/Display.html?Action=Take&id=__id__">};
-                $column{Suffix} .= "</a>";
-            }
-
-            if ($title) {
-                $column{Suffix} .= "/TITLE:" . $m->interp->apply_escapes( $title, 'h' );
-            }
-            push @seen, \%column;
-        }
-    }
-}
-elsif ( $col_up ) {
-    my $index = $current_display_columns;
-    if ( defined $index && ( $index - 1 ) >= 0 ) {
-        my $column = $seen[$index];
-        $seen[$index]       = $seen[ $index - 1 ];
-        $seen[ $index - 1 ] = $column;
-        $current_display_columns     = $index - 1;
-    }
-}
-elsif ( $col_down ) {
-    my $index = $current_display_columns;
-    if ( defined $index && ( $index + 1 ) < scalar @seen ) {
-        my $column = $seen[$index];
-        $seen[$index]       = $seen[ $index + 1 ];
-        $seen[ $index + 1 ] = $column;
-        $current_display_columns     = $index + 1;
-    }
-}
-
-
-my @format_string;
-foreach my $field (@seen) {
-    next unless $field;
-    my $row = "'";
-    $row .= $field->{'Prefix'} if defined $field->{'Prefix'};
-    $row .= "__" . ($field->{'Column'} =~ m/\(/ ? $field->{'Column'} # func, don't escape
-		    : $m->interp->apply_escapes( $field->{'Column'}, 'h' )) . "__"
-      unless ( $field->{'Column'} eq "<blank>" );
-    $row .= $field->{'Suffix'} if defined $field->{'Suffix'};
-    $row .= "'";
-    push( @format_string, $row );
-}
-
-$format = join(",\n", @format_string);
-
-
-return($format, \@fields, \@seen);
-
-</%init>

commit bdb999258e08f19d6c5f2b61beb47565d7dd3c47
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:29:23 2009 -0500

    remove a mason escaping call

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index bb49c89..5770448 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -256,7 +256,7 @@ my $optionlist_arrayref;
 my $optionlist = join "\n", map {
           qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
         . ( "&nbsp;" x ( 5 * $_->{DEPTH} ) )
-        . $m->interp->apply_escapes( $_->{TEXT}, 'h' )
+		. Jifty->web->escape( $_->{TEXT})
         . qq(</option>)
 } @$optionlist_arrayref;
 

commit 6b08e74a1c449cf301154e87bd17ce0c0157d0ca
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:48:59 2009 -0500

    incremental refactoring

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 5770448..7929b74 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -106,7 +106,7 @@
 
 <& Elements/DisplayOptions,
     %ARGS, %query,
-    available_columns => $AvailableColumns,
+    available_columns => $available_columns,
     current_format    => $current_format,
 &>
 
@@ -119,12 +119,8 @@
 <%INIT>
 use RT::Interface::Web::QueryBuilder::Tree;
 
-my %query;
-for (qw(query format order_by order rows_per_page)) {
-    $query{$_} = $ARGS{$_};
-}
-
 my %saved_search;
+my %query = map { $_ => $ARGS{$_} } qw(query format order_by order rows_per_page);
 my @actions = RT::Interface::Web::QueryBuilder->load_saved_search( \%ARGS, \%query, \%saved_search );
 
 if ($new_query) {
@@ -157,24 +153,13 @@ if ($new_query) {
         if ( ref $query{$_} eq "ARRAY" ) {
             $query{$_} = join( '|', @{ $query{$_} } );
         }
-    }
-    if ( $query{'format'} ) {
+	}
 
-        # Clean unwanted junk from the format
-		$query{'format'} = RT::Interface::Web->scrub_html( $query{'format'} );
-    }
+	$query{'format'} = RT::Interface::Web->scrub_html( $query{'format'} ) if ( $query{'format'} );
 }
 
-my $parse_query = sub {
-    my ( $string, $results ) = @_;
-
-    my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
-    @$results = $tree->parse_sql( query => $string );
-
-    return $tree;
-};
-
-my $tree = $parse_query->( $query{'query'}, \@actions );
+my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
+push @actions, = $tree->parse_sql( query => $query{query} );
 
 # if parsing went poorly, send them to the edit page to fix it
 if ( $actions[0] ) {
@@ -185,36 +170,35 @@ my @options        = $tree->get_displayed_nodes;
 my @current_values = grep defined, @options[@clauses];
 my @new_values     = ();
 
-#  Try to find if we're adding a clause
 foreach my $arg ( keys %ARGS ) {
-    next
-        unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/
-            && (ref $ARGS{$arg} eq "ARRAY"
-                ? grep $_ ne '', @{ $ARGS{$arg} }
-                : $ARGS{$arg} ne ''
-            );
-
-    # We're adding a $1 clause
-    my $field = $1;
+	#  Try to find if we're adding a clause
+    next unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/ && (ref $ARGS{$arg} eq "ARRAY" ? grep $_ ne '', @{ $ARGS{$arg} } : $ARGS{$arg} ne '');
 
+    my $field = $1;
     my ( $op, $value );
 
     #figure out if it's a grouping
     my $keyword = $ARGS{ $field . "_field" } || $field;
 
-    my ( @ops, @values );
-    if ( ref $ARGS{ 'value_of_' . $field } eq "ARRAY" ) {
+	my ( @ops, @values );
+
 
+	my $op_name = $field. "_op";
+	my $op_value = 'value_of_'.$field;
+
+    if ( ref $ARGS{$op_value} eq "ARRAY" ) {
         # we have many keys/values to iterate over, because there is
         # more than one CF with the same name.
-        @ops    = @{ $ARGS{ $field . '_op' } };
-        @values = @{ $ARGS{ 'value_of_' . $field } };
+		@ops    = @{ $ARGS{ $op_name } };
+		@values = @{ $ARGS{ $op_value } };
     } else {
-        @ops    = ( $ARGS{ $field . '_op' } );
-        @values = ( $ARGS{ 'value_of_' . $field } );
-    }
-    Jifty->log->error("Bad Parameters passed into Query Builder")
-        unless @ops == @values;
+        @ops    = ( $ARGS{ $op_name } );
+		@values = ( $ARGS{ $op_value } );
+	}
+
+
+
+    Jifty->log->error("Bad Parameters passed into Query Builder") unless @ops == @values;
 
     for ( my $i = 0; $i < @ops; $i++ ) {
         my ( $op, $value ) = ( $ops[$i], $values[$i] );
@@ -257,15 +241,14 @@ my $optionlist = join "\n", map {
           qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
         . ( "&nbsp;" x ( 5 * $_->{DEPTH} ) )
 		. Jifty->web->escape( $_->{TEXT})
-        . qq(</option>)
-} @$optionlist_arrayref;
+        . qq(</option>) } @$optionlist_arrayref;
 
 my $queues = $tree->get_referenced_queues;
 
 #  Deal with format changes
-my ( $AvailableColumns, $current_format );
+my ( $available_columns, $current_format );
 
-( $query{'format'}, $AvailableColumns, $current_format ) = RT::Interface::Web::QueryBuilder->build_format_string(
+( $query{'format'}, $available_columns, $current_format ) = RT::Interface::Web::QueryBuilder->build_format_string(
     %ARGS,
     cfqueues => $queues,
     format   => $query{'format'},
@@ -276,8 +259,7 @@ push @actions, RT::Interface::Web::QueryBuilder->save_search( \%ARGS, \%query, \
 
 #  Push the updates into the session so we don't loose 'em
 
-Jifty->web->session->set(
-    'CurrentSearchHash',
+Jifty->web->session->set( 'CurrentSearchHash',
     {   %query,
         search_id   => $saved_search{'id'},
         object      => $saved_search{'object'},

commit 2fad999bd772e8e4cf7a113c7a96e8124486874a
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:50:24 2009 -0500

    incremental refactoring

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 7929b74..6a77a0c 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -186,15 +186,10 @@ foreach my $arg ( keys %ARGS ) {
 	my $op_name = $field. "_op";
 	my $op_value = 'value_of_'.$field;
 
-    if ( ref $ARGS{$op_value} eq "ARRAY" ) {
-        # we have many keys/values to iterate over, because there is
-        # more than one CF with the same name.
-		@ops    = @{ $ARGS{ $op_name } };
-		@values = @{ $ARGS{ $op_value } };
-    } else {
-        @ops    = ( $ARGS{ $op_name } );
-		@values = ( $ARGS{ $op_value } );
-	}
+        # we may have many keys/values to iterate over, because there
+        # may be more than one CF with the same name.
+		@ops    = ref $ARGS{$op_value} ? @{ $ARGS{ $op_name } } : $ARGS{$op_name};
+		@values    = ref $ARGS{$op_value} ? @{ $ARGS{ $op_value } } : $ARGS{$op_value};
 
 
 

commit d85893c906619d110c6f71a2ad70144b89fb120a
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:50:42 2009 -0500

    perltidy

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 6a77a0c..4ca110e 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -171,8 +171,11 @@ my @current_values = grep defined, @options[@clauses];
 my @new_values     = ();
 
 foreach my $arg ( keys %ARGS ) {
-	#  Try to find if we're adding a clause
-    next unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/ && (ref $ARGS{$arg} eq "ARRAY" ? grep $_ ne '', @{ $ARGS{$arg} } : $ARGS{$arg} ne '');
+
+    #  Try to find if we're adding a clause
+    next
+        unless $arg =~ m/^value_of_(\w+|'CF.{.*?}')$/
+            && ( ref $ARGS{$arg} eq "ARRAY" ? grep $_ ne '', @{ $ARGS{$arg} } : $ARGS{$arg} ne '' );
 
     my $field = $1;
     my ( $op, $value );
@@ -180,18 +183,15 @@ foreach my $arg ( keys %ARGS ) {
     #figure out if it's a grouping
     my $keyword = $ARGS{ $field . "_field" } || $field;
 
-	my ( @ops, @values );
-
-
-	my $op_name = $field. "_op";
-	my $op_value = 'value_of_'.$field;
-
-        # we may have many keys/values to iterate over, because there
-        # may be more than one CF with the same name.
-		@ops    = ref $ARGS{$op_value} ? @{ $ARGS{ $op_name } } : $ARGS{$op_name};
-		@values    = ref $ARGS{$op_value} ? @{ $ARGS{ $op_value } } : $ARGS{$op_value};
+    my ( @ops, @values );
 
+    my $op_name  = $field . "_op";
+    my $op_value = 'value_of_' . $field;
 
+    # we may have many keys/values to iterate over, because there
+    # may be more than one CF with the same name.
+    @ops    = ref $ARGS{$op_value} ? @{ $ARGS{$op_name} }  : $ARGS{$op_name};
+    @values = ref $ARGS{$op_value} ? @{ $ARGS{$op_value} } : $ARGS{$op_value};
 
     Jifty->log->error("Bad Parameters passed into Query Builder") unless @ops == @values;
 

commit 8da265dd6181ffc9f22a42ee14fcf0fb6adb3df1
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 16:52:01 2009 -0500

    typo fix

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 4ca110e..df6b6c3 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -159,7 +159,7 @@ if ($new_query) {
 }
 
 my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
-push @actions, = $tree->parse_sql( query => $query{query} );
+push @actions, $tree->parse_sql( query => $query{query} );
 
 # if parsing went poorly, send them to the edit page to fix it
 if ( $actions[0] ) {

commit e08153afd1ace3939b1cf17b36a2c91b9b10209d
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 17:38:26 2009 -0500

    remove a temp variable

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index df6b6c3..d2660b1 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -214,13 +214,13 @@ foreach my $arg ( keys %ARGS ) {
             $value = "'$value'" unless $value =~ /^\d+$/;
         }
 
-        my $clause = {
-            Key   => $keyword,
-            Op    => $op,
-            Value => $value
-        };
+        push @new_values, RT::Interface::Web::QueryBuilder::Tree->new(
+            {   Key   => $keyword,
+                Op    => $op,
+                Value => $value
+            }
 
-        push @new_values, RT::Interface::Web::QueryBuilder::Tree->new($clause);
+        );
     }
 }
 

commit d3229b63b34c22e0561a12606da939a5dd4f7f3e
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:00:10 2009 -0500

    remove a workaround for a bug 4 years ago

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index d2660b1..059f5a6 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -205,10 +205,6 @@ foreach my $arg ( keys %ARGS ) {
             } elsif ( $op eq '!=' ) {
                 $op = "IS NOT";
             }
-
-            # This is not "right", but...
-            # It has to be this way until #5182 is fixed
-            $value = "'NULL'";
         } else {
             $value =~ s/'/\\'/g;
             $value = "'$value'" unless $value =~ /^\d+$/;

commit ebcaa03b0845f2dd435b97ec642504cd6e225bc1
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:01:11 2009 -0500

    one more line down

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 059f5a6..1e7ba36 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -183,15 +183,13 @@ foreach my $arg ( keys %ARGS ) {
     #figure out if it's a grouping
     my $keyword = $ARGS{ $field . "_field" } || $field;
 
-    my ( @ops, @values );
-
     my $op_name  = $field . "_op";
     my $op_value = 'value_of_' . $field;
 
     # we may have many keys/values to iterate over, because there
     # may be more than one CF with the same name.
-    @ops    = ref $ARGS{$op_value} ? @{ $ARGS{$op_name} }  : $ARGS{$op_name};
-    @values = ref $ARGS{$op_value} ? @{ $ARGS{$op_value} } : $ARGS{$op_value};
+    my @ops    = ref $ARGS{$op_value} ? @{ $ARGS{$op_name} }  : $ARGS{$op_name};
+    my @values = ref $ARGS{$op_value} ? @{ $ARGS{$op_value} } : $ARGS{$op_value};
 
     Jifty->log->error("Bad Parameters passed into Query Builder") unless @ops == @values;
 

commit 306d05b930d472069e5b0b9e848976f91a8985e2
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:01:25 2009 -0500

    runtime bad web params don't merit logged errors

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 1e7ba36..4f31560 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -191,7 +191,7 @@ foreach my $arg ( keys %ARGS ) {
     my @ops    = ref $ARGS{$op_value} ? @{ $ARGS{$op_name} }  : $ARGS{$op_name};
     my @values = ref $ARGS{$op_value} ? @{ $ARGS{$op_value} } : $ARGS{$op_value};
 
-    Jifty->log->error("Bad Parameters passed into Query Builder") unless @ops == @values;
+    Jifty->log->debug("Bad Parameters passed into Query Builder") unless @ops == @values;
 
     for ( my $i = 0; $i < @ops; $i++ ) {
         my ( $op, $value ) = ( $ops[$i], $values[$i] );

commit 2df7ebc690749164e85d6b7b8be9dca3f6c0c21a
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:02:52 2009 -0500

    declared and then not used

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 4f31560..0c9b3fa 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -178,7 +178,6 @@ foreach my $arg ( keys %ARGS ) {
             && ( ref $ARGS{$arg} eq "ARRAY" ? grep $_ ne '', @{ $ARGS{$arg} } : $ARGS{$arg} ne '' );
 
     my $field = $1;
-    my ( $op, $value );
 
     #figure out if it's a grouping
     my $keyword = $ARGS{ $field . "_field" } || $field;

commit 0ee30e6a7ea5de1d39c2787730942df03ab92c0a
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:05:29 2009 -0500

    removed unneeded lines

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index ea1842f..06af369 100755
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -66,7 +66,6 @@ use RT::System;
 use RT::SavedSearches;
 use RT::Interface::Web::QueryBuilder;
 
-
 use URI qw();
 use Digest::MD5 ();
 use Encode qw();
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 0c9b3fa..24af53b 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -217,7 +217,6 @@ foreach my $arg ( keys %ARGS ) {
     }
 }
 
-use RT::Interface::Web::QueryBuilder;
 push @actions, RT::Interface::Web::QueryBuilder->process_query( \%ARGS, $tree, \@current_values, \@new_values, );
 
 #  Rebuild $Query based on the additions / movements

commit 8c36128ee57e7e9d525a63d1e42a0a8177ec165f
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:32:08 2009 -0500

    redirect rather than fall through for results display

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 24af53b..fb5a638 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -153,9 +153,9 @@ if ($new_query) {
         if ( ref $query{$_} eq "ARRAY" ) {
             $query{$_} = join( '|', @{ $query{$_} } );
         }
-	}
+    }
 
-	$query{'format'} = RT::Interface::Web->scrub_html( $query{'format'} ) if ( $query{'format'} );
+    $query{'format'} = RT::Interface::Web->scrub_html( $query{'format'} ) if ( $query{'format'} );
 }
 
 my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
@@ -227,7 +227,7 @@ my $optionlist_arrayref;
 my $optionlist = join "\n", map {
           qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
         . ( "&nbsp;" x ( 5 * $_->{DEPTH} ) )
-		. Jifty->web->escape( $_->{TEXT})
+        . Jifty->web->escape( $_->{TEXT})
         . qq(</option>) } @$optionlist_arrayref;
 
 my $queues = $tree->get_referenced_queues;
@@ -257,8 +257,9 @@ Jifty->web->session->set( 'CurrentSearchHash',
 #  Show the results, if we were asked.
 
 if ( $ARGS{'do_search'} ) {
-    $m->comp( 'Results.html', %query );
-    $m->abort;
+    Jifty->web->redirect( Jifty->web->url . "Search/Results.html?" . 
+                          RT::Interface::Web->format_query_params(%query) );
+
 }
 
 #  Build a query_string for the tabs

commit e75caec4ea20db7b5f229bb40c8a6f8d9a5b8f53
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:33:03 2009 -0500

    kill a bandaid we haven't needed in a looong time.

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index fb5a638..63acca5 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -161,10 +161,6 @@ if ($new_query) {
 my $tree = RT::Interface::Web::QueryBuilder::Tree->new('AND');
 push @actions, $tree->parse_sql( query => $query{query} );
 
-# if parsing went poorly, send them to the edit page to fix it
-if ( $actions[0] ) {
-    return $m->comp( "Edit.html", query => $query{'query'}, actions => \@actions );
-}
 
 my @options        = $tree->get_displayed_nodes;
 my @current_values = grep defined, @options[@clauses];

commit 69ef54528958856f7f5727d9f1bf2b86e1e2d38b
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:43:25 2009 -0500

    saved_search is now a ref

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 63acca5..fd9ea3e 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -70,11 +70,11 @@
     current_tab => "Search/Build.html?".$query_string, 
     title => _("Query Builder"),
     %query,
-    saved_search_id => $saved_search{'id'},
+	saved_search_id => $saved_search->{'id'},
 &>
 
 <form method="post" action="Build.html" name="build_query">
-<input type="hidden" class="hidden" name="saved_search_id" value="<% $saved_search{'id'} %>" />
+	<input type="hidden" class="hidden" name="saved_search_id" value="<% $saved_search->{'id'} %>" />
 <input type="hidden" class="hidden" name="query" value="<% $query{'query'} %>" />
 <input type="hidden" class="hidden" name="format" value="<% $query{'format'} %>" />
 
@@ -93,11 +93,11 @@
     %ARGS,
     actions => \@actions,
     optionlist => $optionlist,
-    description => $saved_search{'description'},
+	description => $saved_search->{'description'},
     &>
 </div>
 <div id="editsearches">
-    <& Elements/EditSearches, %saved_search, current_search => \%query &>
+    <& Elements/EditSearches, %$saved_search, current_search => \%query &>
 </div>
 
 
@@ -119,21 +119,19 @@
 <%INIT>
 use RT::Interface::Web::QueryBuilder::Tree;
 
-my %saved_search;
+my $saved_search;
 my %query = map { $_ => $ARGS{$_} } qw(query format order_by order rows_per_page);
-my @actions = RT::Interface::Web::QueryBuilder->load_saved_search( \%ARGS, \%query, \%saved_search );
+my @actions = RT::Interface::Web::QueryBuilder->load_saved_search( \%ARGS, \%query, $saved_search );
 
 if ($new_query) {
 
     # Wipe all data-carrying variables clear if we want a new
     # search, or we're deleting an old one..
     %query = ();
-    %saved_search = ( id => 'new' );
+	$saved_search = { id => 'new'};
 
-    # ..then wipe the session out..
+    # ..then wipe the sessionand the search results.
     Jifty->web->session->remove('CurrentSearchHash');
-
-    # ..and the search results.
     Jifty->web->session->get('tickets')->clean_slate if defined Jifty->web->session->get('tickets');
 }
 
@@ -238,15 +236,15 @@ my ( $available_columns, $current_format );
 );
 
 # if we're asked to save the current search, save it
-push @actions, RT::Interface::Web::QueryBuilder->save_search( \%ARGS, \%query, \%saved_search );
+push @actions, RT::Interface::Web::QueryBuilder->save_search( \%ARGS, \%query, $saved_search );
 
 #  Push the updates into the session so we don't loose 'em
 
 Jifty->web->session->set( 'CurrentSearchHash',
     {   %query,
-        search_id   => $saved_search{'id'},
-        object      => $saved_search{'object'},
-        description => $saved_search{'description'},
+	search_id   => $saved_search->{'id'},
+	object      => $saved_search->{'object'},
+	description => $saved_search->{'description'},
     }
 );
 

commit 54dcf157b1c57a3b629df808a769ac3784cfa1b8
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 18:44:16 2009 -0500

    factor out a "use" line

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 06af369..c06d800 100755
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -65,6 +65,7 @@ use RT::Report::Tickets;
 use RT::System;
 use RT::SavedSearches;
 use RT::Interface::Web::QueryBuilder;
+use RT::Interface::Web::QueryBuilder::Tree;
 
 use URI qw();
 use Digest::MD5 ();
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index fd9ea3e..a81ce5d 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -117,8 +117,6 @@
 
 </&>
 <%INIT>
-use RT::Interface::Web::QueryBuilder::Tree;
-
 my $saved_search;
 my %query = map { $_ => $ARGS{$_} } qw(query format order_by order rows_per_page);
 my @actions = RT::Interface::Web::QueryBuilder->load_saved_search( \%ARGS, \%query, $saved_search );

commit 40c61ed0e4c87ccf57b78dab641c3408e1c97bc2
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 19:06:40 2009 -0500

    remove unneeded current_user

diff --git a/share/html/Search/Elements/DisplayOptions b/share/html/Search/Elements/DisplayOptions
index 36d8c47..797e3e6 100644
--- a/share/html/Search/Elements/DisplayOptions
+++ b/share/html/Search/Elements/DisplayOptions
@@ -101,7 +101,7 @@ selected="selected"
 </&>
 
 <%INIT>
-my $tickets = RT::Model::TicketCollection->new( current_user => Jifty->web->current_user );
+my $tickets = RT::Model::TicketCollection->new( );
 my %fields = %{$tickets->columns};
 map { $fields{$_}->[0] =~ /^(?:ENUM|INT|DATE|STRING|ID)$/ || delete $fields{$_} } keys %fields;
 delete $fields{'effective_id'};

commit a16b6af4b3ab91a3ea42757dcc24d479b192e155
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 19:12:56 2009 -0500

    don't stomp the default format

diff --git a/lib/RT/Interface/Web/QueryBuilder.pm b/lib/RT/Interface/Web/QueryBuilder.pm
index 6eff61f..87fe764 100644
--- a/lib/RT/Interface/Web/QueryBuilder.pm
+++ b/lib/RT/Interface/Web/QueryBuilder.pm
@@ -315,7 +315,7 @@ sub save_search {
 sub build_format_string {
     my $self = shift;
     my %args = (
-        format                  => RT->config->get('default_search_result_format'),
+        format                  => undef,
         cfqueues                => undef,
         face                    => undef,
         size                    => undef,
@@ -329,6 +329,9 @@ sub build_format_string {
         current_display_columns => undef,
         @_
     );
+		
+	
+	$args{format} = RT->config->get('default_search_result_format') unless $args{format};
 
     # All the things we can display in the format string by default
     my @fields = qw(

commit 33ddbccf5e829b20cecbdd2333365c8627a0fe9b
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 19:13:32 2009 -0500

    warning avoidance

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index a81ce5d..928fbbc 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -74,9 +74,9 @@
 &>
 
 <form method="post" action="Build.html" name="build_query">
-	<input type="hidden" class="hidden" name="saved_search_id" value="<% $saved_search->{'id'} %>" />
-<input type="hidden" class="hidden" name="query" value="<% $query{'query'} %>" />
-<input type="hidden" class="hidden" name="format" value="<% $query{'format'} %>" />
+<input type="hidden" class="hidden" name="saved_search_id" value="<% $saved_search->{'id'} || '' %>" />
+<input type="hidden" class="hidden" name="query" value="<% $query{'query'} || '' %>" />
+<input type="hidden" class="hidden" name="format" value="<% $query{'format'} || '' %>" />
 
 
 

commit f39e4e7ae94956e2928553aa0cc36b34164b8e26
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 19:16:07 2009 -0500

    capitalization fix

diff --git a/share/html/Ticket/Elements/Tabs b/share/html/Ticket/Elements/Tabs
index 0f21125..d12f63c 100755
--- a/share/html/Ticket/Elements/Tabs
+++ b/share/html/Ticket/Elements/Tabs
@@ -270,7 +270,7 @@ $has_query = 1 if ( $ARGS{'query'} or Jifty->web->session->get('CurrentSearchHas
     $args = "?" . $m->comp( '/Elements/QueryString', %query_args );
 
 $tabs->{"f"} = {
-    path  => "Search/Build.html?NewQuery=1",
+    path  => "Search/Build.html?new_query=1",
     title => _('New Search')
 };
 $tabs->{"g"} = {

commit 20fdc5f179a20f0adc1530f2675a216d9afbcf6a
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Nov 5 19:19:57 2009 -0500

    minor refactoring to reuse a compiled query string

diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 928fbbc..5e4537b 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -247,22 +247,19 @@ Jifty->web->session->set( 'CurrentSearchHash',
 );
 
 #  Show the results, if we were asked.
-
-if ( $ARGS{'do_search'} ) {
-    Jifty->web->redirect( Jifty->web->url . "Search/Results.html?" . 
-                          RT::Interface::Web->format_query_params(%query) );
-
-}
+my $query_string = '';
 
 #  Build a query_string for the tabs
-
-my $query_string = '';
 if ($new_query) {
     $query_string = 'new_query=1';
 } elsif ( $query{'query'} ) {
     $query_string = RT::Interface::Web->format_query_params(%query);
 }
 
+if ( $ARGS{'do_search'} ) {
+	Jifty->web->redirect( Jifty->web->url . "Search/Results.html?" .$query_string;
+}
+
 </%INIT>
 
 <%ARGS>

-----------------------------------------------------------------------


More information about the Rt-commit mailing list