You need to sign in or sign up before continuing.
query.cgi 26.2 KB
Newer Older
1 2
#!/usr/bonsaitools/bin/perl -w
# -*- Mode: perl; indent-tabs-mode: nil -*-
terry%netscape.com's avatar
terry%netscape.com committed
3
#
4 5 6 7 8 9 10 11 12 13
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
terry%netscape.com's avatar
terry%netscape.com committed
14
# The Original Code is the Bugzilla Bug Tracking System.
15
#
terry%netscape.com's avatar
terry%netscape.com committed
16
# The Initial Developer of the Original Code is Netscape Communications
17 18 19 20
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
terry%netscape.com's avatar
terry%netscape.com committed
21
# Contributor(s): Terry Weissman <terry@mozilla.org>
22
#                 David Gardiner <david.gardiner@unisa.edu.au>
23
#                 Matthias Radestock <matthias@sorted.org>
terry%netscape.com's avatar
terry%netscape.com committed
24

25 26
use diagnostics;
use strict;
terry%netscape.com's avatar
terry%netscape.com committed
27

28
require "CGI.pl";
terry%netscape.com's avatar
terry%netscape.com committed
29

30 31 32 33 34
$::CheckOptionValues = 0;       # It's OK if we have some bogus things in the
                                # pop-up lists here, from a remembered query
                                # that is no longer quite valid.  We don't
                                # want to crap out in the query page.

35
# Shut up misguided -w warnings about "used only once":
terry%netscape.com's avatar
terry%netscape.com committed
36

terry%mozilla.org's avatar
terry%mozilla.org committed
37 38 39
use vars
  @::CheckOptionValues,
  @::legal_resolution,
40
  @::legal_bug_status,
terry%mozilla.org's avatar
terry%mozilla.org committed
41 42
  @::legal_components,
  @::legal_keywords,
43
  @::legal_opsys,
44
  @::legal_platform,
terry%mozilla.org's avatar
terry%mozilla.org committed
45 46
  @::legal_priority,
  @::legal_product,
47
  @::legal_severity,
48
  @::legal_target_milestone,
terry%mozilla.org's avatar
terry%mozilla.org committed
49
  @::legal_versions,
50
  @::log_columns,
51 52
  %::versions,
  %::components,
53 54 55 56
  %::FORM;


if (defined $::FORM{"GoAheadAndLogIn"}) {
terry%netscape.com's avatar
terry%netscape.com committed
57 58
    # We got here from a login page, probably from relogin.cgi.  We better
    # make sure the password is legit.
59
    confirm_login();
60 61 62 63 64 65
} else {
    quietly_check_login();
}
my $userid = 0;
if (defined $::COOKIE{"Bugzilla_login"}) {
    $userid = DBNameToIdAndCheck($::COOKIE{"Bugzilla_login"});
terry%netscape.com's avatar
terry%netscape.com committed
66 67
}

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
# Backwards compatability hack -- if there are any of the old QUERY_*
# cookies around, and we are logged in, then move them into the database
# and nuke the cookie.
if ($userid) {
    my @oldquerycookies;
    foreach my $i (keys %::COOKIE) {
        if ($i =~ /^QUERY_(.*)$/) {
            push(@oldquerycookies, [$1, $i, $::COOKIE{$i}]);
        }
    }
    if (defined $::COOKIE{'DEFAULTQUERY'}) {
        push(@oldquerycookies, [$::defaultqueryname, 'DEFAULTQUERY',
                                $::COOKIE{'DEFAULTQUERY'}]);
    }
    if (@oldquerycookies) {
        foreach my $ref (@oldquerycookies) {
            my ($name, $cookiename, $value) = (@$ref);
            if ($value) {
                my $qname = SqlQuote($name);
                SendSQL("SELECT query FROM namedqueries " .
                        "WHERE userid = $userid AND name = $qname");
                my $query = FetchOneColumn();
                if (!$query) {
                    SendSQL("REPLACE INTO namedqueries " .
                            "(userid, name, query) VALUES " .
                            "($userid, $qname, " . SqlQuote($value) . ")");
                }
            }
            print "Set-Cookie: $cookiename= ; path=/ ; expires=Sun, 30-Jun-1980 00:00:00 GMT\n";
        }
    }
99
}
100
                
101 102


terry%netscape.com's avatar
terry%netscape.com committed
103

104 105 106 107 108 109
if ($::FORM{'nukedefaultquery'}) {
    if ($userid) {
        SendSQL("DELETE FROM namedqueries " .
                "WHERE userid = $userid AND name = '$::defaultqueryname'");
    }
    $::buffer = "";
terry%netscape.com's avatar
terry%netscape.com committed
110 111
}

112

113 114 115 116 117
my $userdefaultquery;
if ($userid) {
    SendSQL("SELECT query FROM namedqueries " .
            "WHERE userid = $userid AND name = '$::defaultqueryname'");
    $userdefaultquery = FetchOneColumn();
terry%netscape.com's avatar
terry%netscape.com committed
118 119
}

120 121
my %default;
my %type;
122

123 124 125 126 127 128 129
sub ProcessFormStuff {
    my ($buf) = (@_);
    my $foundone = 0;
    foreach my $name ("bug_status", "resolution", "assigned_to",
                      "rep_platform", "priority", "bug_severity",
                      "product", "reporter", "op_sys",
                      "component", "version", "chfield", "chfieldfrom",
130
                      "chfieldto", "chfieldvalue", "target_milestone",
131 132 133 134 135 136 137 138 139
                      "email1", "emailtype1", "emailreporter1",
                      "emailassigned_to1", "emailcc1", "emailqa_contact1",
                      "emaillongdesc1",
                      "email2", "emailtype2", "emailreporter2",
                      "emailassigned_to2", "emailcc2", "emailqa_contact2",
                      "emaillongdesc2",
                      "changedin", "votes", "short_desc", "short_desc_type",
                      "long_desc", "long_desc_type", "bug_file_loc",
                      "bug_file_loc_type", "status_whiteboard",
140 141
                      "status_whiteboard_type", "bug_id",
                      "bugidtype", "keywords", "keywords_type") {
142 143
        $default{$name} = "";
        $type{$name} = 0;
144
    }
145 146 147 148 149 150 151 152


    foreach my $item (split(/\&/, $buf)) {
        my @el = split(/=/, $item);
        my $name = $el[0];
        my $value;
        if ($#el > 0) {
            $value = url_decode($el[1]);
terry%netscape.com's avatar
terry%netscape.com committed
153
        } else {
154 155 156 157 158 159 160 161 162 163
            $value = "";
        }
        if (defined $default{$name}) {
            $foundone = 1;
            if ($default{$name} ne "") {
                $default{$name} .= "|$value";
                $type{$name} = 1;
            } else {
                $default{$name} = $value;
            }
terry%netscape.com's avatar
terry%netscape.com committed
164 165
        }
    }
166
    return $foundone;
terry%netscape.com's avatar
terry%netscape.com committed
167
}
168

169

170 171 172 173 174 175 176 177 178
if (!ProcessFormStuff($::buffer)) {
    # Ah-hah, there was no form stuff specified.  Do it again with the
    # default query.
    if ($userdefaultquery) {
        ProcessFormStuff($userdefaultquery);
    } else {
        ProcessFormStuff(Param("defaultquery"));
    }
}
179

180

181
                 
terry%netscape.com's avatar
terry%netscape.com committed
182

183 184
if ($default{'chfieldto'} eq "") {
    $default{'chfieldto'} = "Now";
terry%netscape.com's avatar
terry%netscape.com committed
185 186
}

187 188


189 190 191 192
print "Set-Cookie: BUGLIST=
Content-type: text/html\n\n";

GetVersionTable();
193 194 195 196 197 198 199 200 201 202 203

sub GenerateEmailInput {
    my ($id) = (@_);
    my $defstr = value_quote($default{"email$id"});
    my $deftype = $default{"emailtype$id"};
    if ($deftype eq "") {
        $deftype = "substring";
    }
    my $assignedto = ($default{"emailassigned_to$id"} eq "1") ? "checked" : "";
    my $reporter = ($default{"emailreporter$id"} eq "1") ? "checked" : "";
    my $cc = ($default{"emailcc$id"} eq "1") ? "checked" : "";
204
    my $longdesc = ($default{"emaillongdesc$id"} eq "1") ? "checked" : "";
205

206
    my $qapart = "";
207
    my $qacontact = "";
208
    if (Param("useqacontact")) {
209
        $qacontact = ($default{"emailqa_contact$id"} eq "1") ? "checked" : "";
210 211 212 213 214 215 216 217 218
        $qapart = qq|
<tr>
<td></td>
<td>
<input type="checkbox" name="emailqa_contact$id" value=1 $qacontact>QA Contact
</td>
</tr>
|;
    }
219 220 221 222 223 224 225 226 227
    if ($assignedto eq "" && $reporter eq "" && $cc eq "" &&
          $qacontact eq "") {
        if ($id eq "1") {
            $assignedto = "checked";
        } else {
            $reporter = "checked";
        }
    }

228

229 230 231
    $default{"emailtype$id"} ||= "substring";

    return qq{
232 233 234 235
<table border=1 cellspacing=0 cellpadding=0>
<tr><td>
<table cellspacing=0 cellpadding=0>
<tr>
236
<td rowspan=2 valign=top><a href="queryhelp.cgi#peopleinvolved">Email:</a>
237
<input name="email$id" size="30" value="$defstr">&nbsp;matching as
238 239 240 241 242 243
} . BuildPulldown("emailtype$id",
                  [["regexp", "regexp"],
                   ["notregexp", "not regexp"],
                   ["substring", "substring"],
                   ["exact", "exact"]],
                  $default{"emailtype$id"}) . qq{
244 245 246 247 248 249 250 251 252
</td>
<td>
<input type="checkbox" name="emailassigned_to$id" value=1 $assignedto>Assigned To
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="emailreporter$id" value=1 $reporter>Reporter
</td>
253
</tr>$qapart
254 255 256
<tr>
<td align=right>(Will match any of the selected fields)</td>
<td>
257 258 259 260 261 262 263
<input type="checkbox" name="emailcc$id" value=1 $cc>CC
</td>
</tr>
<tr>
<td></td>
<td>
<input type="checkbox" name="emaillongdesc$id" value=1 $longdesc>Added comment
264 265 266 267
</td>
</tr>
</table>
</table>
268
};
269 270 271 272 273 274 275 276 277
}


            


my $emailinput1 = GenerateEmailInput(1);
my $emailinput2 = GenerateEmailInput(2);

278 279 280 281
# if using usebuggroups, then we don't want people to see products they don't
# have access to.  remove them from the list.

@::product_list = ();
282 283 284
my %component_set;
my %version_set;
my %milestone_set;
285
foreach my $p (@::legal_product) {
286 287 288 289 290 291 292 293 294
  if(Param("usebuggroups")
     && GroupExists($p)
     && !UserInGroup($p)) {
    # If we're using bug groups to restrict entry on products, and
    # this product has a bug group, and the user is not in that
    # group, we don't want to include that product in this list.
    next;
  }
  push @::product_list, $p;
295 296 297 298
  if ($::components{$p}) {
    foreach my $c (@{$::components{$p}}) {
      $component_set{$c} = 1;
    }
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
  }
  foreach my $v (@{$::versions{$p}}) {
    $version_set{$v} = 1;
  }
  foreach my $m (@{$::target_milestone{$p}}) {
    $milestone_set{$m} = 1;
  }
}

@::component_list = ();
@::version_list = ();
@::milestone_list = ();
foreach my $c (@::legal_components) {
  if ($component_set{$c}) {
    push @::component_list, $c;
  }
}
foreach my $v (@::legal_versions) {
  if ($version_set{$v}) {
    push @::version_list, $v;
  }
}
foreach my $m (@::legal_target_milestone) {
  if ($milestone_set{$m}) {
    push @::milestone_list, $m;
  }
325
}
326

327 328 329
# javascript
    
my $jscript = << 'ENDSCRIPT';
330
<script language="Javascript1.1" type="text/javascript">
331 332 333
<!--
var cpts = new Array();
var vers = new Array();
334
var tms  = new Array();
335 336 337 338 339 340
ENDSCRIPT


my $p;
my $v;
my $c;
341
my $m;
342 343 344
my $i = 0;
my $j = 0;

345
foreach $c (@::component_list) {
346
    $jscript .= "cpts['$c'] = new Array();\n";
347 348
}

349
foreach $v (@::version_list) {
350
    $jscript .= "vers['$v'] = new Array();\n";
351 352
}

353
my $tm;
354
foreach $tm (@::milestone_list) {
355 356
    $jscript .= "tms['$tm'] = new Array();\n";
}
357

358
for $p (@::product_list) {
359 360
    if ($::components{$p}) {
        foreach $c (@{$::components{$p}}) {
361
            $jscript .= "cpts['$c'][cpts['$c'].length] = '$p';\n";
362
        }
363
    }
364 365 366

    if ($::versions{$p}) {
        foreach $v (@{$::versions{$p}}) {
367
            $jscript .= "vers['$v'][vers['$v'].length] = '$p';\n";
368
        }
369
    }
370 371 372 373 374 375

    if ($::target_milestone{$p}) {
        foreach $m (@{$::target_milestone{$p}}) {
            $jscript .= "tms['$m'][tms['$m'].length] = '$p';\n";
        }
    }
376 377 378
}

$i = 0;
379
$jscript .= << 'ENDSCRIPT';
380 381 382 383

// Only display versions/components valid for selected product(s)

function selectProduct(f) {
384 385 386 387 388
    // Netscape 4.04 and 4.05 also choke with an "undefined"
    // error.  if someone can figure out how to "define" the
    // whatever, we'll remove this hack.  in the mean time, we'll
    // assume that v4.00-4.03 also die, so we'll disable the neat
    // javascript stuff for Netscape 4.05 and earlier.
389

390 391 392
    var cnt = 0;
    var i;
    var j;
393 394 395 396 397

    if (!f) {
        return;
    }

398 399 400 401 402 403 404
    for (i=0 ; i<f.product.length ; i++) {
        if (f.product[i].selected) {
            cnt++;
        }
    }
    var doall = (cnt == f.product.length || cnt == 0);

405
    var csel = new Object();
406 407 408 409 410 411 412 413 414
    for (i=0 ; i<f.component.length ; i++) {
        if (f.component[i].selected) {
            csel[f.component[i].value] = 1;
        }
    }

    f.component.options.length = 0;

    for (c in cpts) {
415
        if (typeof(cpts[c]) == 'function') continue;
416 417 418 419 420
        var doit = doall;
        for (i=0 ; !doit && i<f.product.length ; i++) {
            if (f.product[i].selected) {
                var p = f.product[i].value;
                for (j in cpts[c]) {
421
                    if (typeof(cpts[c][j]) == 'function') continue;
422 423 424 425 426 427 428 429 430 431 432
                    var p2 = cpts[c][j];
                    if (p2 == p) {
                        doit = true;
                        break;
                    }
                }
            }
        }
        if (doit) {
            var l = f.component.length;
            f.component[l] = new Option(c, c);
433
            if (csel[c]) {
434 435 436 437 438
                f.component[l].selected = true;
            }
        }
    }

439
    var vsel = new Object();
440 441 442 443 444 445 446 447 448
    for (i=0 ; i<f.version.length ; i++) {
        if (f.version[i].selected) {
            vsel[f.version[i].value] = 1;
        }
    }

    f.version.options.length = 0;

    for (v in vers) {
449
        if (typeof(vers[v]) == 'function') continue;
450
        doit = doall;
451 452
        for (i=0 ; !doit && i<f.product.length ; i++) {
            if (f.product[i].selected) {
453
                p = f.product[i].value;
454
                for (j in vers[v]) {
455
                    if (typeof(vers[v][j]) == 'function') continue;
456
                    p2 = vers[v][j];
457 458 459 460 461 462 463 464
                    if (p2 == p) {
                        doit = true;
                        break;
                    }
                }
            }
        }
        if (doit) {
465
            l = f.version.length;
466
            f.version[l] = new Option(v, v);
467
            if (vsel[v]) {
468 469 470 471 472
                f.version[l].selected = true;
            }
        }
    }

473 474 475 476
ENDSCRIPT
if (Param("usetargetmilestone")) {
    $jscript .= q{
      if (f.target_milestone) {
477
        var tmsel = new Object();
478 479 480 481
        for (i=0 ; i<f.target_milestone.length ; i++) {
            if (f.target_milestone[i].selected) {
                tmsel[f.target_milestone[i].value] = 1;
            }
482
        }
483 484 485 486 487
    
        f.target_milestone.options.length = 0;
    
        for (tm in tms) {
            if (typeof(tms[v]) == 'function') continue;
488
            doit = doall;
489 490
            for (i=0 ; !doit && i<f.product.length ; i++) {
                if (f.product[i].selected) {
491
                    p = f.product[i].value;
492 493
                    for (j in tms[tm]) {
                        if (typeof(tms[tm][j]) == 'function') continue;
494
                        p2 = tms[tm][j];
495 496 497 498
                        if (p2 == p) {
                            doit = true;
                            break;
                        }
499 500 501
                    }
                }
            }
502
            if (doit) {
503
                l = f.target_milestone.length;
504
                f.target_milestone[l] = new Option(tm, tm);
505
                if (tmsel[tm]) {
506 507
                    f.target_milestone[l].selected = true;
                }
508 509
            }
        }
510 511 512 513 514 515
      }
    };

}

$jscript .= << 'ENDSCRIPT';
516 517
}
// -->
518 519
</script>

520
ENDSCRIPT
521

terry%netscape.com's avatar
terry%netscape.com committed
522 523 524 525 526 527 528


# Muck the "legal product" list so that the default one is always first (and
# is therefore visibly selected.

# Commented out, until we actually have enough products for this to matter.

529
# set w [lsearch $legal_product $default{"product"}]
terry%netscape.com's avatar
terry%netscape.com committed
530
# if {$w >= 0} {
531
#    set legal_product [concat $default{"product"} [lreplace $legal_product $w $w]]
terry%netscape.com's avatar
terry%netscape.com committed
532 533
# }

534 535 536 537
PutHeader("Bugzilla Query Page", "Query", 
          "This page lets you search the database for recorded bugs.",
          q{onLoad="selectProduct(document.forms[0]);"},
          0, $jscript);
538 539

push @::legal_resolution, "---"; # Oy, what a hack.
terry%netscape.com's avatar
terry%netscape.com committed
540

541 542
my @logfields = ("[Bug creation]", @::log_columns);

543 544
print"<P>Give me a <A HREF=\"queryhelp.cgi\">clue</A> about how to use this form.<P>";

545 546
print qq{
<FORM METHOD=GET ACTION="buglist.cgi">
terry%netscape.com's avatar
terry%netscape.com committed
547 548 549

<table>
<tr>
550 551 552 553 554 555
<th align=left><A HREF="queryhelp.cgi#status">Status</a>:</th>
<th align=left><A HREF="queryhelp.cgi#resolution">Resolution</a>:</th>
<th align=left><A HREF="queryhelp.cgi#platform">Platform</a>:</th>
<th align=left><A HREF="queryhelp.cgi#opsys">OpSys</a>:</th>
<th align=left><A HREF="queryhelp.cgi#priority">Priority</a>:</th>
<th align=left><A HREF="queryhelp.cgi#severity">Severity</a>:</th>
556 557 558
};

print "
terry%netscape.com's avatar
terry%netscape.com committed
559 560
</tr>
<tr>
561
<td align=left valign=top>
562 563 564

@{[make_selection_widget(\"bug_status\",\@::legal_bug_status,$default{'bug_status'}, $type{'bug_status'}, 1)]}

terry%netscape.com's avatar
terry%netscape.com committed
565
</td>
566
<td align=left valign=top>
567 568
@{[make_selection_widget(\"resolution\",\@::legal_resolution,$default{'resolution'}, $type{'resolution'}, 1)]}

terry%netscape.com's avatar
terry%netscape.com committed
569
</td>
570
<td align=left valign=top>
571
@{[make_selection_widget(\"rep_platform\",\@::legal_platform,$default{'platform'}, $type{'platform'}, 1)]}
572

terry%netscape.com's avatar
terry%netscape.com committed
573
</td>
574
<td align=left valign=top>
575
@{[make_selection_widget(\"op_sys\",\@::legal_opsys,$default{'op_sys'}, $type{'op_sys'}, 1)]}
576

577 578
</td>
<td align=left valign=top>
579 580
@{[make_selection_widget(\"priority\",\@::legal_priority,$default{'priority'}, $type{'priority'}, 1)]}

terry%netscape.com's avatar
terry%netscape.com committed
581
</td>
582
<td align=left valign=top>
583 584
@{[make_selection_widget(\"bug_severity\",\@::legal_severity,$default{'bug_severity'}, $type{'bug_severity'}, 1)]}

terry%netscape.com's avatar
terry%netscape.com committed
585 586 587 588
</tr>
</table>

<p>
589 590 591

<table>
<tr><td colspan=2>
592
$emailinput1<p>
593
</td></tr><tr><td colspan=2>
594
$emailinput2<p>
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
</td></tr>";

my $inclselected = "SELECTED";
my $exclselected = "";

    
if ($default{'bugidtype'} eq "exclude") {
    $inclselected = "";
    $exclselected = "SELECTED";
}
my $bug_id = value_quote($default{'bug_id'}); 

print qq{
<TR>
<TD COLSPAN="3">
<SELECT NAME="bugidtype">
<OPTION VALUE="include" $inclselected>Only
<OPTION VALUE="exclude" $exclselected>Exclude
</SELECT>
bugs numbered: 
<INPUT TYPE="text" NAME="bug_id" VALUE="$bug_id" SIZE=30>
</TD>
</TR>
};

print "
621 622
<tr>
<td>
623
Changed in the <NOBR>last <INPUT NAME=changedin SIZE=2 VALUE=\"$default{'changedin'}\"> days.</NOBR>
624 625 626 627 628 629
</td>
<td align=right>
At <NOBR>least <INPUT NAME=votes SIZE=3 VALUE=\"$default{'votes'}\"> votes.</NOBR>
</tr>
</table>

630

631 632 633 634 635
<table>
<tr>
<td rowspan=2 align=right>Where the field(s)
</td><td rowspan=2>
<SELECT NAME=\"chfield\" MULTIPLE SIZE=4>
636
@{[make_options(\@logfields, $default{'chfield'}, $type{'chfield'})]}
637 638 639 640 641 642 643 644 645 646 647 648
</SELECT>
</td><td rowspan=2>
changed.
</td><td>
<nobr>dates <INPUT NAME=chfieldfrom SIZE=10 VALUE=\"$default{'chfieldfrom'}\"></nobr>
<nobr>to <INPUT NAME=chfieldto SIZE=10 VALUE=\"$default{'chfieldto'}\"></nobr>
</td>
</tr>
<tr>
<td>changed to value <nobr><INPUT NAME=chfieldvalue SIZE=10> (optional)</nobr>
</td>
</table>
terry%netscape.com's avatar
terry%netscape.com committed
649 650 651 652 653 654


<P>

<table>
<tr>
655 656
<TH ALIGN=LEFT VALIGN=BOTTOM>Program:</th>
<TH ALIGN=LEFT VALIGN=BOTTOM>Version:</th>
657
<TH ALIGN=LEFT VALIGN=BOTTOM><A HREF=describecomponents.cgi>Component:</a></th>
658 659 660 661 662 663 664
";

if (Param("usetargetmilestone")) {
    print "<TH ALIGN=LEFT VALIGN=BOTTOM>Target Milestone:</th>";
}

print "
terry%netscape.com's avatar
terry%netscape.com committed
665 666 667
</tr>
<tr>

668
<td align=left valign=top>
669
<SELECT NAME=\"product\" MULTIPLE SIZE=5 onChange=\"selectProduct(this.form);\">
670
@{[make_options(\@::product_list, $default{'product'}, $type{'product'})]}
671
</SELECT>
terry%netscape.com's avatar
terry%netscape.com committed
672 673
</td>

674 675
<td align=left valign=top>
<SELECT NAME=\"version\" MULTIPLE SIZE=5>
676
@{[make_options(\@::version_list, $default{'version'}, $type{'version'})]}
677
</SELECT>
terry%netscape.com's avatar
terry%netscape.com committed
678 679
</td>

680 681
<td align=left valign=top>
<SELECT NAME=\"component\" MULTIPLE SIZE=5>
682
@{[make_options(\@::component_list, $default{'component'}, $type{'component'})]}
683
</SELECT>
684
</td>";
terry%netscape.com's avatar
terry%netscape.com committed
685

686 687 688 689
if (Param("usetargetmilestone")) {
    print "
<td align=left valign=top>
<SELECT NAME=\"target_milestone\" MULTIPLE SIZE=5>
690
@{[make_options(\@::milestone_list, $default{'target_milestone'}, $type{'target_milestone'})]}
691 692 693 694
</SELECT>
</td>";
}

695 696 697 698 699 700 701 702 703 704 705

sub StringSearch {
    my ($desc, $name) = (@_);
    my $type = $name . "_type";
    my $def = value_quote($default{$name});
    print qq{<tr>
<td align=right>$desc:</td>
<td><input name=$name size=30 value="$def"></td>
<td><SELECT NAME=$type>
};
    if ($default{$type} eq "") {
706
        $default{$type} = "allwordssubstr";
707 708 709
    }
    foreach my $i (["substring", "case-insensitive substring"],
                   ["casesubstring", "case-sensitive substring"],
710 711
                   ["allwordssubstr", "all words as substrings"],
                   ["anywordssubstr", "any words as substrings"],
712 713
                   ["allwords", "all words"],
                   ["anywords", "any words"],
714 715 716 717 718 719 720 721 722 723 724 725 726 727
                   ["regexp", "regular expression"],
                   ["notregexp", "not ( regular expression )"]) {
        my ($n, $d) = (@$i);
        my $sel = "";
        if ($default{$type} eq $n) {
            $sel = " SELECTED";
        }
        print qq{<OPTION VALUE="$n"$sel>$d\n};
    }
    print "</SELECT></TD>
</tr>
";
}

728
print "
terry%netscape.com's avatar
terry%netscape.com committed
729 730 731
</tr>
</table>

732
<table border=0>
733 734 735
";

StringSearch("Summary", "short_desc");
736
StringSearch("A description entry", "long_desc");
737
StringSearch("URL", "bug_file_loc");
738 739

if (Param("usestatuswhiteboard")) {
740
    StringSearch("Status whiteboard", "status_whiteboard");
741 742
}

743 744 745 746 747
if (@::legal_keywords) {
    my $def = value_quote($default{'keywords'});
    print qq{
<TR>
<TD ALIGN="right"><A HREF="describekeywords.cgi">Keywords</A>:</TD>
748 749
<TD><INPUT NAME="keywords" SIZE=30 VALUE="$def"></TD>
<TD>
750
};
751 752 753
    my $type = $default{"keywords_type"};
    if ($type eq "or") {        # Backward compatability hack.
        $type = "anywords";
754
    }
755 756 757 758 759 760
    print BuildPulldown("keywords_type",
                        [["anywords", "Any of the listed keywords set"],
                         ["allwords", "All of the listed keywords set"],
                         ["nowords", "None of the listed keywords set"]],
                        $type);
    print qq{</TD></TR>};
761 762
}

763
print "
764
</table>
terry%netscape.com's avatar
terry%netscape.com committed
765
<p>
766
";
terry%netscape.com's avatar
terry%netscape.com committed
767

768 769 770

my @fields;
push(@fields, ["noop", "---"]);
771
ConnectToDatabase();
772 773 774 775 776 777 778 779 780 781 782 783 784
SendSQL("SELECT name, description FROM fielddefs ORDER BY sortkey");
while (MoreSQLData()) {
    my ($name, $description) = (FetchSQLData());
    push(@fields, [$name, $description]);
}

my @types = (
	     ["noop", "---"],
	     ["equals", "equal to"],
	     ["notequals", "not equal to"],
	     ["casesubstring", "contains (case-sensitive) substring"],
	     ["substring", "contains (case-insensitive) substring"],
	     ["notsubstring", "does not contain (case-insensitive) substring"],
785 786
	     ["allwordssubstr", "all words as (case-insensitive) substrings"],
	     ["anywordssubstr", "any words as (case-insensitive) substrings"],
787 788 789 790 791 792 793 794 795 796 797 798 799 800
	     ["regexp", "contains regexp"],
	     ["notregexp", "does not contain regexp"],
	     ["lessthan", "less than"],
	     ["greaterthan", "greater than"],
	     ["anywords", "any words"],
	     ["allwords", "all words"],
	     ["nowords", "none of the words"],
	     ["changedbefore", "changed before"],
	     ["changedafter", "changed after"],
	     ["changedto", "changed to"],
	     ["changedby", "changed by"],
	     );


801 802
print qq{<A NAME="chart"> </A>\n};

803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
foreach my $cmd (grep(/^cmd-/, keys(%::FORM))) {
    if ($cmd =~ /^cmd-add(\d+)-(\d+)-(\d+)$/) {
	$::FORM{"field$1-$2-$3"} = "xyzzy";
    }
}
	
#  foreach my $i (sort(keys(%::FORM))) {
#      print "$i : " . value_quote($::FORM{$i}) . "<BR>\n";
#  }


if (!exists $::FORM{'field0-0-0'}) {
    $::FORM{'field0-0-0'} = "xyzzy";
}

818
my $jsmagic = qq{ONCLICK="document.forms[0].action='query.cgi#chart' ; document.forms[0].method='POST' ; return 1;"};
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840

my $chart;
for ($chart=0 ; exists $::FORM{"field$chart-0-0"} ; $chart++) {
    my @rows;
    my $row;
    for ($row = 0 ; exists $::FORM{"field$chart-$row-0"} ; $row++) {
	my @cols;
	my $col;
	for ($col = 0 ; exists $::FORM{"field$chart-$row-$col"} ; $col++) {
	    my $key = "$chart-$row-$col";
	    my $deffield = $::FORM{"field$key"} || "";
	    my $deftype = $::FORM{"type$key"} || "";
	    my $defvalue = value_quote($::FORM{"value$key"} || "");
	    my $line = "";
	    $line .= "<TD>";
	    $line .= BuildPulldown("field$key", \@fields, $deffield);
	    $line .= BuildPulldown("type$key", \@types, $deftype);
	    $line .= qq{<INPUT NAME="value$key" VALUE="$defvalue">};
	    $line .= "</TD>\n";
	    push(@cols, $line);
	}
	push(@rows, "<TR>" . join(qq{<TD ALIGN="center"> or </TD>\n}, @cols) .
841
	     qq{<TD><INPUT TYPE="submit" VALUE="Or" NAME="cmd-add$chart-$row-$col" $jsmagic></TD></TR>});
842 843 844 845 846 847 848
    }
    print qq{
<HR>
<TABLE>
};
    print join('<TR><TD>And</TD></TR>', @rows);
    print qq{
849
<TR><TD><INPUT TYPE="submit" VALUE="And" NAME="cmd-add$chart-$row-0" $jsmagic>
850 851 852 853 854
};
    my $n = $chart + 1;
    if (!exists $::FORM{"field$n-0-0"}) {
        print qq{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
855
<INPUT TYPE="submit" VALUE="Add another boolean chart" NAME="cmd-add$n-0-0" $jsmagic>
856
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
857
<NOBR><A HREF="queryhelp.cgi#advancedquerying">What is this stuff?</A></NOBR>
858 859 860 861 862 863 864 865 866 867 868 869 870
};
    }
    print qq{
</TD>
</TR>
</TABLE>
    };
}
print qq{<HR>};




871 872 873 874
if (!$userid) {
    print qq{<INPUT TYPE="hidden" NAME="cmdtype" VALUE="doit">};
} else {
    print "
terry%netscape.com's avatar
terry%netscape.com committed
875
<BR>
876
<INPUT TYPE=radio NAME=cmdtype VALUE=doit CHECKED> Run this query
877 878
<BR>
";
terry%netscape.com's avatar
terry%netscape.com committed
879

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
    my @namedqueries;
    if ($userid) {
        SendSQL("SELECT name FROM namedqueries " .
                "WHERE userid = $userid AND name != '$::defaultqueryname' " .
                "ORDER BY name");
        while (MoreSQLData()) {
            push(@namedqueries, FetchOneColumn());
        }
    }
    
    
    
    
    if (@namedqueries) {
        my $namelist = make_options(\@namedqueries);
        print qq{
896 897 898
<table cellspacing=0 cellpadding=0><tr>
<td><INPUT TYPE=radio NAME=cmdtype VALUE=editnamed> Load the remembered query:</td>
<td rowspan=3><select name=namedcmd>$namelist</select>
terry%netscape.com's avatar
terry%netscape.com committed
899
</tr><tr>
900
<td><INPUT TYPE=radio NAME=cmdtype VALUE=runnamed> Run the remembered query:</td>
terry%netscape.com's avatar
terry%netscape.com committed
901
</tr><tr>
902
<td><INPUT TYPE=radio NAME=cmdtype VALUE=forgetnamed> Forget the remembered query:</td>
903 904
</tr></table>};
    }
terry%netscape.com's avatar
terry%netscape.com committed
905

cyeh%bluemartini.com's avatar
cyeh%bluemartini.com committed
906
    print qq{
907
<INPUT TYPE=radio NAME=cmdtype VALUE=asdefault> Remember this as the default query
terry%netscape.com's avatar
terry%netscape.com committed
908
<BR>
909 910
<INPUT TYPE=radio NAME=cmdtype VALUE=asnamed> Remember this query, and name it:
<INPUT TYPE=text NAME=newqueryname>
cyeh%bluemartini.com's avatar
cyeh%bluemartini.com committed
911 912
<br>&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE="checkbox" NAME="tofooter" VALUE="1">
    and put it in my page footer.
terry%netscape.com's avatar
terry%netscape.com committed
913
<BR>
cyeh%bluemartini.com's avatar
cyeh%bluemartini.com committed
914
    };
915
}
terry%netscape.com's avatar
terry%netscape.com committed
916

cyeh%bluemartini.com's avatar
cyeh%bluemartini.com committed
917
print qq{
terry%netscape.com's avatar
terry%netscape.com committed
918 919
<NOBR><B>Sort By:</B>
<SELECT NAME=\"order\">
cyeh%bluemartini.com's avatar
cyeh%bluemartini.com committed
920
};
921 922 923 924 925 926 927 928

my $deforder = "'Importance'";
my @orders = ('Bug Number', $deforder, 'Assignee');

if ($::COOKIE{'LASTORDER'}) {
    $deforder = "Reuse same sort as last time";
    unshift(@orders, $deforder);
}
929

930 931
if ($::FORM{'order'}) { $deforder = $::FORM{'order'} }

932 933
my $defquerytype = $userdefaultquery ? "my" : "the";

934 935
print make_options(\@orders, $deforder);
print "</SELECT></NOBR>
936
<INPUT TYPE=\"submit\" VALUE=\"Submit query\">
937 938 939 940 941 942
<INPUT TYPE=\"reset\" VALUE=\"Reset back to $defquerytype default query\">
";

if ($userdefaultquery) {
    print qq{<BR><A HREF="query.cgi?nukedefaultquery=1">Set my default query back to the system default</A>};
}
terry%netscape.com's avatar
terry%netscape.com committed
943

944 945
print "
</FORM>
946
";
terry%netscape.com's avatar
terry%netscape.com committed
947

948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
###
### I really hate this redudancy, but if somebody for some inexplicable reason doesn't like using
### the footer for these links, they can uncomment this section. 
###

# if (UserInGroup("tweakparams")) {
#     print "<a href=editparams.cgi>Edit Bugzilla operating parameters</a><br>\n";
# }
# if (UserInGroup("editcomponents")) {
#     print "<a href=editproducts.cgi>Edit Bugzilla products and components</a><br>\n";
# }
# if (UserInGroup("editkeywords")) {
#     print "<a href=editkeywords.cgi>Edit Bugzilla keywords</a><br>\n";
# }
# if ($userid) {
#     print "<a href=relogin.cgi>Log in as someone besides <b>$::COOKIE{'Bugzilla_login'}</b></a><br>\n";
# }
# print "<a href=userprefs.cgi>Change your password or preferences.</a><br>\n";
# print "<a href=\"enter_bug.cgi\">Report a new bug.</a><br>\n";
# print "<a href=\"createaccount.cgi\">Open a new Bugzilla account</a><br>\n";
# print "<a href=\"reports.cgi\">Bug reports</a><br>\n";
terry%netscape.com's avatar
terry%netscape.com committed
969

970 971

PutFooter();