diff --git a/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm b/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm
index 51aed99582c..cf6646f5ce7 100755
--- a/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm
+++ b/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm
@@ -40,8 +40,8 @@
# Contributor(s):
-# $Revision: 1.52 $
-# $Date: 2002-05-07 00:23:49 $
+# $Revision: 1.53 $
+# $Date: 2002-05-07 01:50:48 $
# $Author: kestes%walrus.com $
# $Source: /home/jrmuizel/cvs-mirror/mozilla/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm,v $
# $Name: $
@@ -101,7 +101,7 @@ use TreeData;
use VCDisplay;
-$VERSION = ( qw $Revision: 1.52 $ )[1];
+$VERSION = ( qw $Revision: 1.53 $ )[1];
@ISA = qw(TinderDB::BasicTxtDB);
@@ -340,6 +340,264 @@ sub status_table_header {
}
+# Return the data which would appear in a cell if we were to render
+# it. The checkin data comes back in a datastructure and we return
+# the oldest treestate found in this cell.
+
+sub cell_data {
+ my ($db_index, $last_time) = @_;
+
+ my (%authors) = ();
+ my $last_treestate;
+
+ while (1) {
+ my ($time) = $DB_TIMES[$db_index];
+
+ # find the DB entries which are needed for this cell
+ ($time < $last_time) && last;
+
+ $db_index++;
+
+ if (defined($DATABASE{$tree}{$time}{'treestate'})) {
+ $last_treestate = $DATABASE{$tree}{$time}{'treestate'};
+ }
+
+ # Inside each cell, we want all the posts by the same author to
+ # appear together. The previous data structure allowed us to find
+ # out what data was in each cell.
+
+ my $recs = $DATABASE{$tree}{$time}{'author'};
+ foreach $author (keys %{ $recs }) {
+ foreach $file (keys %{ $recs->{'author'}{$author} }) {
+ my ($log) = $recs->{$author}{$file};
+ $authors{$author}{$time}{$file} = $log;
+ }
+ }
+ } # while (1)
+
+ return ($db_index, $last_treestate, \%authors);
+}
+
+
+
+# produce the HTML which goes with this data.
+
+sub render_authors {
+ my ($last_treestate, $authors, $mindate, $maxdate,) = @_;
+
+ # Now invert the data structure.
+ my %authors = %{$authors};
+
+ my ($cell_color) = TreeData::TreeState2color($last_treestate);
+ my ($char) = TreeData::TreeState2char($last_treestate);
+
+ my $cell_options;
+ my $text_browser_color_string;
+
+ if ( ($last_treestate) && ($cell_color) ) {
+ $cell_options = "bgcolor=$cell_color ";
+
+ $text_browser_color_string =
+ HTMLPopUp::text_browser_color_string($cell_color, $char);
+ }
+
+ my $query_links = '';
+ $query_links.= "\t\t".$text_browser_color_string."\n";
+
+ if ( scalar(%authors) ) {
+
+ # find the times which bound the cell so that we can set up a
+ # VC query.
+
+ my ($format_maxdate) = HTMLPopUp::timeHTML($maxdate);
+ my ($format_mindate) = HTMLPopUp::timeHTML($mindate);
+ my ($time_interval_str) = "$format_maxdate to $format_mindate",
+
+ # create a string of all VC data for displaying with the
+ # checkin table
+
+ my ($vc_info);
+ foreach $key ('module','branch',) {
+ my ($value) = $TreeData::VC_TREE{$tree}{$key};
+ $vc_info .= "$key: $value
\n";
+ }
+
+ # define a table, to show what was checked in for each author
+
+ foreach $author (sort keys %authors) {
+ my ($table) = '';
+ my ($num_rows) = 0;
+ my ($max_length) = 0;
+
+ $table .= (
+ "Checkins by $author
for $vc_info \n".
+ "
\n".
+ "");
+
+ # add table headers
+ $table .= (
+ "\t".
+ "Time | ".
+ "File | ".
+ "Log | ".
+ "
\n".
+ "");
+
+ my @bug_numbers;
+ # sort numerically descending
+ foreach $time ( sort {$b <=> $a} keys %{ $authors{$author} }) {
+ foreach $file (keys %{ $authors{$author}{$time}}) {
+ $num_rows++;
+ my ($log) = $authors{$author}{$time}{$file};
+ if ($log =~ m/$VC_BUGNUM_REGEXP/) {
+ push @bug_numbers, $1;
+ }
+ $max_length = main::max(
+ $max_length ,
+ (length($file) + length($log)),
+ );
+ $table .= (
+ "\t".
+ "".HTMLPopUp::timeHTML($time)." | ".
+ "".$file." | ".
+ "".$log." | ".
+ "
\n".
+ "");
+ }
+ }
+ $table .= "
";
+
+ # This is a Netscape specific CVS/Bonsai issue. Most users do
+ # not have '%' in their CVS names. Do not display the full mail
+ # address in the status column, it takes up too much space.
+ # Keep only the user name.
+
+ my $display_author=$author;
+ $display_author =~ s/\%.*//;
+
+ # we display the list of names in 'teletype font' so that the
+ # names do not bunch together. It seems to make a difference if
+ # there is a between each link or not, but it does make a
+ # difference if we close the for each author or only for
+ # the group of links.
+
+ my (%popup_args) = (
+
+ "windowtxt" => $table,
+ "windowtitle" => ("$VC_NAME Info ".
+ "Author: $author ".
+ "$time_interval_str "),
+
+ "windowheight" => ($num_rows * 50) + 100,
+ "windowwidth" => ($max_length * 10) + 100,
+ );
+
+ my $mailto_author=$author;
+ $mailto_author =~ s/\%/\@/;
+
+ # If you have a VCDisplay implementation you should make the
+ # link point to its query method otherwise you want a 'mailto:'
+ # link
+
+ my ($query_link) = "";
+
+ if (
+ ($TinderConfig::VCDisplayImpl) &&
+ ($TinderConfig::VCDisplayImpl =~ 'None')
+ ) {
+
+ $query_link .=
+ HTMLPopUp::Link(
+ "href" => "mailto: $mailto_author",
+ "linktxt" => "\t\t$display_author",
+
+ %popup_args,
+ );
+ } else {
+
+ $query_link .=
+ VCDisplay::query(
+ 'tree' => $tree,
+ 'mindate' => $mindate,
+ 'maxdate' => $maxdate,
+ 'who' => $author,
+
+ "linktxt" => "\t\t$display_author",
+ %popup_args,
+ );
+ }
+
+ @bug_numbers = main::uniq(@bug_numbers);
+ foreach $bug_number (@bug_numbers) {
+ my $href = BTData::bug_id2bug_url($bug_number);
+ $query_link .=
+ HTMLPopUp::Link(
+ "href" => $href,
+ "linktxt" => "\t\t$bug_number",
+
+ %popup_args,
+ );
+ }
+
+ # put each link on its own line and add good comments so we
+ # can debug the HTML.
+
+ my ($date_str) = localtime($mindate)."-".localtime($maxdate);
+
+ $query_links .= (
+ "\t\t\n".
+ "");
+
+ $query_links .= "\t\t".$query_link."\n";
+
+ } # foreach %author
+ } # if %authors
+
+ $query_links.= "\t\t".$text_browser_color_string."\n";
+
+ @outrow = (
+ "\t\n".
+ "\t\n".
+ $query_links.
+ "\t | \n".
+ "");
+
+ return @outrow;
+}
+
+sub render_empty_cell {
+ my ($last_treestate, $rowspan) = @_;
+
+ my ($cell_color) = TreeData::TreeState2color($last_treestate);
+ my ($char) = TreeData::TreeState2char($last_treestate);
+
+ my $cell_options;
+ my $text_browser_color_string;
+
+ if ( ($last_treestate) && ($cell_color) ) {
+ $cell_options = "bgcolor=$cell_color ";
+
+ $text_browser_color_string =
+ HTMLPopUp::text_browser_color_string($cell_color, $char) ;
+ }
+
+ my $cell_contents = $text_browser_color_string || $EMPTY_TABLE_CELL;
+
+ return ("\t\n".
+
+ "\t\t".
+ "$cell_contents | \n");
+}
+
+
# clear data structures in preparation for printing a new table
@@ -380,44 +638,6 @@ sub status_table_start {
return ;
}
-# a helper function to determine if we break a large cell symbolizing
-# no data.
-
-sub is_break_cell {
- my ($tree,$time,$next_time) = @_;
-
- # When building the first row of the status table LAST_TREESTATE
- # is not defined. If we can find a treestate in the data
- # structure use it.
-
- if (defined($DATABASE{$tree}{$time}{'treestate'})) {
- $LAST_TREESTATE{$tree} = $DATABASE{$tree}{$time}{'treestate'};
- }
-
- my $is_state1_different =
- (
- (defined($LAST_TREESTATE{$tree})) &&
- (defined($DATABASE{$tree}{$next_time}{'treestate'})) &&
- ($LAST_TREESTATE{$tree} ne $DATABASE{$tree}{$next_time}{'treestate'}) &&
- 1);
-
- my $is_state2_different =
- (
- (defined($LAST_TREESTATE{$tree})) &&
- (defined($DATABASE{$tree}{$time}{'treestate'})) &&
- ($LAST_TREESTATE ne $DATABASE{$tree}{$time}{'treestate'}) &&
- 1);
-
- my $is_state_different = $is_state1_different || $is_state2_different;
- my $is_author_data = ( defined($DATABASE{$tree}{$time}{'author'}) ||
- defined($DATABASE{$tree}{$next_time}{'author'}) );
-
- my $is_break_cell = ( ($is_state_different) || ($is_author_data) );
-
- return $is_break_cell;
-}
-
-
sub status_table_row {
my ($self, $row_times, $row_index, $tree, ) = @_;
@@ -438,316 +658,70 @@ sub status_table_row {
return @outrow;
}
- # create a multi-row dummy cell for missing data?
- # cell stops if there is author data in the following cell or the
- # treestate changes.
-
- # first find out what time the break will occur at.
-
- while (
- ( $DB_TIMES[$NEXT_DB{$tree}] >= $row_times->[$#{$row_times}] ) &&
-
- (!(
- is_break_cell(
- $tree,
- $DB_TIMES[$NEXT_DB{$tree}],
- $DB_TIMES[$NEXT_DB{$tree}+1],
- )
- ))
- ) {
- $NEXT_DB{$tree}++
- }
-
- # If there is no treestate, then the tree state has not changed
- # since an early time. The earliest time was assigned a state in
- # apply_db_updates(). It is possible that there are no treestates at
- # all this should not prevent the VC column from being rendered.
-
- if (!($LAST_TREESTATE{$tree})) {
- $LAST_TREESTATE{$tree} = $TinderHeader::HEADER2DEFAULT_HTML{'TreeState'};
- }
-
- my ($cell_color) = TreeData::TreeState2color($LAST_TREESTATE{$tree});
- my ($char) = TreeData::TreeState2char($LAST_TREESTATE{$tree});
-
- my $cell_options;
- my $text_browser_color_string;
-
- if ( ($LAST_TREESTATE{$tree}) && ($cell_color) ) {
- $cell_options = "bgcolor=$cell_color ";
-
- $text_browser_color_string =
- HTMLPopUp::text_browser_color_string($cell_color, $char);
- }
-
- # Do we need a multiline empty cell or do we have data?
- $next_time = $DB_TIMES[$NEXT_DB{$tree}];
-
- if (
- (!(defined($DATABASE{$tree}{$next_time}{'author'}))) ||
- ($next_time < $row_times->[$row_index] )
- ) {
-
- # now convert the break time to a rowspan.
-
- my ($rowspan) = 1;
- while (
- ( ($row_index + $rowspan) <= $#{$row_times}) &&
- ( $next_time <
- $row_times->[$row_index + $rowspan] )
- ) {
- $rowspan++ ;
- }
-
- my ($cell_options) = ("rowspan=$rowspan ".
- "bgcolor=$cell_color ");
- my ($lc_time) = localtime($next_time);
-
- push @outrow, ("\t\n".
-
- "\t\t".
- "$EMPTY_TABLE_CELL | \n");
-
- $NEXT_ROW{$tree} = $row_index + $rowspan;
- $NEXT_DB{$tree}++;
-
- return @outrow;
- }
-
- # ----Where VC Data gets renderd-----
-
- $NEXT_ROW{$tree} = $row_index + 1;
-
- # we assume that tree states only change rarely so there are very
- # few cells which have more then one state associated with them.
- # It does not matter what we do with those cells.
# find all the authors who changed code at any point in this cell
# find the tree state for this cell.
- my (%authors) = ();
+ my ($db_index, $last_treestate, $authors) =
+ cell_data( $NEXT_DB{$tree}, $row_times->[$row_index]);
- while (1) {
- my ($time) = $DB_TIMES[$NEXT_DB{$tree}];
+ if (%{$authors}) {
- # find the DB entries which are needed for this cell
- ($time < $row_times->[$row_index]) && last;
+ $NEXT_DB{$tree} = $db_index;
+ $NEXT_ROW{$tree} = $row_index + 1;
+ $LAST_TREESTATE{$tree} = $last_treestate || $LAST_TREESTATE{$tree};
- $NEXT_DB{$tree}++;
-
- if (defined($DATABASE{$tree}{$time}{'treestate'})) {
- $LAST_TREESTATE{$tree} = $DATABASE{$tree}{$time}{'treestate'};
- }
-
- # Now invert the data structure.
-
- # Inside each cell, we want all the posts by the same author to
- # appear together. The previous data structure allowed us to find
- # out what data was in each cell.
-
- foreach $author (keys %{ $DATABASE{$tree}{$time}{'author'} }) {
- foreach $file (keys %{ $DATABASE{$tree}{$time}{'author'}{$author} }) {
- my ($log) = $DATABASE{$tree}{$time}{'author'}{$author}{$file};
- $authors{$author}{$time}{$file} = $log;
- }
- }
- } # while (1)
-
- my $query_links = '';
- $query_links.= "\t\t".$text_browser_color_string."\n";
-
- if ( scalar(%authors) ) {
-
- # find the times which bound the cell so that we can set up a
- # VC query.
-
- my ($mindate) = $row_times->[$row_index];
-
- my ($maxdate);
- if ($row_index > 0){
- $maxdate = $row_times->[$row_index - 1];
- } else {
- $maxdate = $main::TIME;
- }
- my ($format_maxdate) = HTMLPopUp::timeHTML($maxdate);
- my ($format_mindate) = HTMLPopUp::timeHTML($mindate);
- my ($time_interval_str) = "$format_maxdate to $format_mindate",
-
- # create a string of all VC data for displaying with the checkin table
-
- my ($vc_info);
- foreach $key ('module','branch',) {
- my ($value) = $TreeData::VC_TREE{$tree}{$key};
- $vc_info .= "$key: $value
\n";
- }
-
- # define a table, to show what was checked in for each author
-
- foreach $author (sort keys %authors) {
- my ($table) = '';
- my ($num_rows) = 0;
- my ($max_length) = 0;
-
- $table .= (
- "Checkins by $author
for $vc_info \n".
- "\n".
- "");
-
- # add table headers
- $table .= (
- "\t".
- "Time | ".
- "File | ".
- "Log | ".
- "
\n".
- "");
-
- my @bug_numbers;
- # sort numerically descending
- foreach $time ( sort {$b <=> $a} keys %{ $authors{$author} }) {
- foreach $file (keys %{ $authors{$author}{$time}}) {
- $num_rows++;
- my ($log) = $authors{$author}{$time}{$file};
- if ($log =~ m/$VC_BUGNUM_REGEXP/) {
- push @bug_numbers, $1;
- }
- $max_length = main::max(
- $max_length ,
- (length($file) + length($log)),
- );
- $table .= (
- "\t".
- "".HTMLPopUp::timeHTML($time)." | ".
- "".$file." | ".
- "".$log." | ".
- "
\n".
- "");
- }
- }
- $table .= "
";
-
- # This is a Netscape specific CVS/Bonsai issue. Most users do
- # not have '%' in their CVS names. Do not display the full mail
- # address in the status column, it takes up too much space.
- # Keep only the user name.
-
- my $display_author=$author;
- $display_author =~ s/\%.*//;
-
- # we display the list of names in 'teletype font' so that the
- # names do not bunch together. It seems to make a difference if
- # there is a between each link or not, but it does make a
- # difference if we close the for each author or only for
- # the group of links.
-
- my (%popup_args) = (
-
- "windowtxt" => $table,
- "windowtitle" => ("$VC_NAME Info ".
- "Author: $author ".
- "$time_interval_str "),
-
- "windowheight" => ($num_rows * 50) + 100,
- "windowwidth" => ($max_length * 10) + 100,
- );
-
- my $mailto_author=$author;
- $mailto_author =~ s/\%/\@/;
-
- # If you have a VCDisplay implementation you should make the
- # link point to its query method otherwise you want a 'mailto:'
- # link
-
- my ($query_link) = "";
-
- if (
- ($TinderConfig::VCDisplayImpl) &&
- ($TinderConfig::VCDisplayImpl =~ 'None')
- ) {
-
- $query_link .=
- HTMLPopUp::Link(
- "href" => "mailto: $mailto_author",
- "linktxt" => "\t\t$display_author",
-
- %popup_args,
- );
+ my ($mindate) = $row_times->[$row_index],
+ my ($maxdate);
+ if ($row_index > 0){
+ $maxdate = $row_times->[$row_index - 1];
} else {
-
- $query_link .=
- VCDisplay::query(
- 'tree' => $tree,
- 'mindate' => $mindate,
- 'maxdate' => $maxdate,
- 'who' => $author,
-
- "linktxt" => "\t\t$display_author",
- %popup_args,
- );
+ $maxdate = $main::TIME;
}
- @bug_numbers = main::uniq(@bug_numbers);
- foreach $bug_number (@bug_numbers) {
- my $href = BTData::bug_id2bug_url($bug_number);
- $query_link .=
- HTMLPopUp::Link(
- "href" => $href,
- "linktxt" => "\t\t$bug_number",
-
- %popup_args,
- );
- }
-
- # put each link on its own line and add good comments so we
- # can debug the HTML.
-
- my ($date_str) = localtime($mindate)."-".localtime($maxdate);
-
- $query_links .= (
- "\t\t\n".
- "");
-
- $query_links .= "\t\t".$query_link."\n";
-
- }
-
- $query_links.= "\t\t".$text_browser_color_string."\n";
-
- @outrow = (
- "\t\n".
- "\t\n".
- $query_links.
- "\t | \n".
- "");
-
+ my @html = render_authors(
+ $LAST_TREESTATE{$tree},
+ $authors,
+ $mindate,
+ $maxdate,
+ );
+ return @html;
} else {
- # I should not need to put some arbitrary single empty cell here
- # at the bottom, but I think this is prudent to have one.
+ # create a multi-row dummy cell for missing data?
+ # cell stops if there is author data in the following cell or the
+ # treestate changes.
+
+ my $rowspan = 1;
+ my ($next_db_index, $next_treestate, $next_authors);
- push @outrow, ("\t\n");
+ while (
+ !(%{$next_authors}) &&
+ (
+ !defined($next_treestate) ||
+ ($last_treestate eq $next_treestate)
+ )
+ ) {
+
+ ($next_db_index, $next_treestate, $next_authors) =
+ cell_data( $db_index, $row_times->[$row_index+$rowspan]);
+
+ $db_index = $next_db_index;
+ $rowspan++ ;
+ }
+
+ $NEXT_ROW{$tree} = $row_index + $rowspan;
+ $NEXT_DB{$tree} = $db_index;
+ $LAST_TREESTATE{$tree} = $last_treestate || $LAST_TREESTATE{$tree};
+
+ my @html= render_empty_cell($LAST_TREESTATE{$tree}, $rowspan);
+ return @html;
}
- return @outrow;
+ # not reached
}
-
1;