# # # patch "AdvancedFind.pm" # from [93700481be1aff4ba68009aa13d3436465bbc7ed] # to [c1b16b8bee1ad2c756404a2f542b860a9d4587f7] # # patch "Annotate.pm" # from [27cfdc6358dc6b448c976c2e5c8073b267389a61] # to [1493920915b434690ff4c1f7e6192a4c32e7bb77] # # patch "Common.pm" # from [7068c80291b5130224db7a8d70c5b15c0ba8c00c] # to [d3591a613d333dcab84a11ff965b836cd882088a] # # patch "FindFiles.pm" # from [0da8fa825fe041547b6ecbda0c30d967050d2c4e] # to [9a53448f388865ef0aae2b9efaaa731296737f07] # # patch "History.pm" # from [8d2d115bea7e921a6a0ba711cbb0974691f83051] # to [1fea04fcf7d196ce884c4c1d74162f783e1a4f0b] # # patch "mtn-browse" # from [bb0c210124e86ea129859b57e88febda4f14f18a] # to [3b5148c89ee9ae73df8c18d104e476e27c6aa764] # # patch "mtn-browse.glade" # from [64a3a44c3739541710e729d840bcf096deb76837] # to [cfe9e3171f3f842633db5c602f10340385122831] # ============================================================ --- AdvancedFind.pm 93700481be1aff4ba68009aa13d3436465bbc7ed +++ AdvancedFind.pm c1b16b8bee1ad2c756404a2f542b860a9d4587f7 @@ -45,6 +45,15 @@ use warnings; use strict; use warnings; +# ***** GLOBAL DATA DECLARATIONS ***** + +# Constants for the columns within the manifest liststore widget. + +use constant AFLS_REVISION_ID_COLUMN => 0; +use constant AFLS_BRANCH_COLUMN => 1; +use constant AFLS_DATE_COLUMN => 2; +use constant AFLS_AUTHOR_COLUMN => 3; + # ***** FUNCTIONAL PROTOTYPES ***** # Public routines. @@ -172,6 +181,9 @@ sub advanced_find($$$) } $advanced_find->{mtn} = undef; + $advanced_find->{branch_combo_details}->{preset} = 0; + $advanced_find->{revision_combo_details}->{preset} = 0; + &{$advanced_find->{update_handler}}($advanced_find, ALL_CHANGED); return $ret_val; @@ -429,14 +441,13 @@ sub revisions_treeview_cursor_changed_cb $widget->get_selection()->selected_foreach (sub { my($model, $path, $iter) = @_; - $revision_id = $model->get($iter, 0); }); + $revision_id = $model->get($iter, AFLS_REVISION_ID_COLUMN); }); if (defined($revision_id) && $revision_id ne $advanced_find->{revisions_treeview_details}->{value}) { $advanced_find->{revisions_treeview_details}->{value} = $revision_id; - $advanced_find->{appbar}->clear_stack(); &{$advanced_find->{update_handler}}($advanced_find, SELECTED_REVISION_CHANGED); } @@ -480,12 +491,11 @@ sub revisions_treeview_row_activated_cb( $widget->get_selection()->selected_foreach (sub { my($model, $path, $iter) = @_; - $revision_id = $model->get($iter, 0); }); + $revision_id = $model->get($iter, AFLS_REVISION_ID_COLUMN); }); if (defined($revision_id)) { $advanced_find->{revisions_treeview_details}->{value} = $revision_id; - $advanced_find->{appbar}->clear_stack(); $advanced_find->{selected} = 1; $advanced_find->{done} = 1; } @@ -561,8 +571,6 @@ sub get_advanced_find_window($) "revisions_treeview", "details_textview", "details_scrolledwindow", - "selected_branch_value_label", - "selected_revision_value_label", "ok_button") { $instance->{$widget} = $instance->{glade}->get_widget($widget); @@ -616,18 +624,58 @@ sub get_advanced_find_window($) # Setup the revisions list browser. $instance->{revisions_liststore} = - Gtk2::ListStore->new("Glib::String"); + Gtk2::ListStore->new("Glib::String", + "Glib::String", + "Glib::String", + "Glib::String"); $instance->{revisions_treeview}-> set_model($instance->{revisions_liststore}); + $tv_column = Gtk2::TreeViewColumn->new(); - $tv_column->set_title(__("Matching Revision Ids")); - $tv_column->set_sort_column_id(0); + $tv_column->set_title(__("Revision Id")); + $tv_column->set_resizable(TRUE); + $tv_column->set_sizing("fixed"); + $tv_column->set_fixed_width(100); + $tv_column->set_sort_column_id(AFLS_REVISION_ID_COLUMN); $renderer = Gtk2::CellRendererText->new(); $tv_column->pack_start($renderer, FALSE); - $tv_column->set_attributes($renderer, "text" => 0); + $tv_column->set_attributes($renderer, + "text" => AFLS_REVISION_ID_COLUMN); $instance->{revisions_treeview}->append_column($tv_column); - $instance->{revisions_treeview}->set_search_column(0); + $tv_column = Gtk2::TreeViewColumn->new(); + $tv_column->set_title(__("Branch")); + $tv_column->set_resizable(TRUE); + $tv_column->set_sizing("grow-only"); + $tv_column->set_sort_column_id(AFLS_BRANCH_COLUMN); + $renderer = Gtk2::CellRendererText->new(); + $tv_column->pack_start($renderer, FALSE); + $tv_column->set_attributes($renderer, "text" => AFLS_BRANCH_COLUMN); + $instance->{revisions_treeview}->append_column($tv_column); + + $tv_column = Gtk2::TreeViewColumn->new(); + $tv_column->set_title(__("Date")); + $tv_column->set_resizable(TRUE); + $tv_column->set_sizing("grow-only"); + $tv_column->set_sort_column_id(AFLS_DATE_COLUMN); + $renderer = Gtk2::CellRendererText->new(); + $tv_column->pack_start($renderer, FALSE); + $tv_column->set_attributes($renderer, "text" => AFLS_DATE_COLUMN); + $instance->{revisions_treeview}->append_column($tv_column); + + $tv_column = Gtk2::TreeViewColumn->new(); + $tv_column->set_title(__("Author")); + $tv_column->set_resizable(TRUE); + $tv_column->set_sizing("grow-only"); + $tv_column->set_sort_column_id(AFLS_AUTHOR_COLUMN); + $renderer = Gtk2::CellRendererText->new(); + $tv_column->pack_start($renderer, FALSE); + $tv_column->set_attributes($renderer, "text" => AFLS_AUTHOR_COLUMN); + $instance->{revisions_treeview}->append_column($tv_column); + + $instance->{revisions_treeview}-> + set_search_column(AFLS_REVISION_ID_COLUMN); + # Setup the revision details viewer. $instance->{details_buffer} = @@ -710,6 +758,7 @@ sub update_advanced_find_state($$) my($advanced_find, $changed) = @_; + my $matches; my $made_busy = 0; my $wm = WindowManager->instance(); @@ -718,7 +767,8 @@ sub update_advanced_find_state($$) $made_busy = 1; $wm->make_busy($advanced_find, 1); } - $advanced_find->{appbar}->push(""); + $advanced_find->{appbar}-> + push($advanced_find->{appbar}->get_status()->get_text()); $wm->update_gui(); # The list of available branches has changed. @@ -851,7 +901,7 @@ sub update_advanced_find_state($$) if ($changed & REVISION_LIST) { - my($counter, + my($i, @revision_ids); # Reset the revisions tree view. @@ -868,12 +918,15 @@ sub update_advanced_find_state($$) if ($advanced_find->{revision_combo_details}->{complete}) { get_revision_ids($advanced_find, address@hidden); + $matches = scalar(@revision_ids); } } else { + my($err, $query); + $query = $advanced_find->{search_term_comboboxentry}->child()-> get_text(); @@ -900,12 +953,13 @@ sub update_advanced_find_state($$) eval { $advanced_find->{mtn}->select(address@hidden, $query); + $matches = scalar(@revision_ids); }; $err = $@; Monotone::AutomateStdio->register_error_handler ("both", \&mtn_error_handler); - # If the query was valid the store it in the history. + # If the query was valid then store it in the history. if ($err eq "") { @@ -949,29 +1003,119 @@ sub update_advanced_find_state($$) } } - $advanced_find->{mtn}->toposort(address@hidden, @revision_ids); + $advanced_find->{mtn}->toposort(address@hidden, @revision_ids) + if (scalar(@revision_ids) > 0); @revision_ids = reverse(@revision_ids); # Update the revisions tree view. $advanced_find->{appbar}-> set_status(__("Populating revision details")); - $counter = 1; $advanced_find->{stop_button}->set_sensitive(TRUE); - foreach my $item (@revision_ids) + $i = 0; + while ($i < scalar(@revision_ids) && ! $advanced_find->{stop}) { - $advanced_find->{revisions_liststore}-> - set($advanced_find->{revisions_liststore}->append(), - 0, $item); - if (($counter % 10) == 0) + + my($branch, + %branch_hits, + $nr_revisions, + @revision_group); + + # Build up a list of revision ids that share the same branch. + + for ($nr_revisions = 1; + $i < scalar(@revision_ids); + ++ $i, ++ $nr_revisions) { - $advanced_find->{appbar}->set_progress_percentage - ($counter / scalar(@revision_ids)); - $wm->update_gui(); + + my ($author, + @certs, + $date, + $found, + $key, + %unique, + $value); + + $advanced_find->{mtn}->certs(address@hidden, $revision_ids[$i]); + + # Total up unique occurrences of branch names for this + # revision and stash away any author and date information that + # we may find. + + $found = 0; + $author = $date = ""; + foreach my $cert (@certs) + { + if ($cert->{name} eq "author") + { + $author = $cert->{value}; + } + elsif ($cert->{name} eq "branch") + { + if (! $unique{$cert->{value}} ++) + { + ++ $branch_hits{$cert->{value}}; + $found = 1; + } + } + elsif ($cert->{name} eq "date") + { + $date = $cert->{value}; + $date =~ s/T/ /; + } + } + ++ $branch_hits{""} if (! $found); + + # Exit this loop if a new sequence of revisions with a + # different common branch has started. + + $found = 0; + while (($key, $value) = each(%branch_hits)) + { + if ($value == $nr_revisions) + { + $branch = $key; + $found = 1; + last; + } + } + last if (! $found); + + # Ok so add this revision onto the end of the group. + + push(@revision_group, + {revision_id => $revision_ids[$i], + author => $author, + date => $date}); + + if ((($i + 1) % 10) == 0) + { + $advanced_find->{appbar}->set_progress_percentage + (($i + 1) / scalar(@revision_ids)); + $wm->update_gui(); + } + if ($advanced_find->{stop}) + { + $matches = $i + 1; + last; + } + } - ++ $counter; - last if ($advanced_find->{stop}); + + # Add the current revision group to the revisions tree view. + + foreach my $item (@revision_group) + { + $advanced_find->{revisions_liststore}-> + set($advanced_find->{revisions_liststore}->append(), + AFLS_REVISION_ID_COLUMN, $item->{revision_id}, + AFLS_BRANCH_COLUMN, $branch, + AFLS_DATE_COLUMN, $item->{date}, + AFLS_AUTHOR_COLUMN, $item->{author}); + } + } + $advanced_find->{appbar}->set_progress_percentage(1); $wm->update_gui(); $advanced_find->{stop_button}->set_sensitive(FALSE); @@ -991,68 +1135,42 @@ sub update_advanced_find_state($$) if ($advanced_find->{revisions_treeview_details}->{value} ne "") { - if ($advanced_find->{selected_revision_value_label}->get_text() - ne $advanced_find->{revisions_treeview_details}->{value}) - { - my($branch, - @certs_list, - @revision_details); + my(@certs_list, + @revision_details); - $advanced_find->{details_buffer}->set_text(""); - $advanced_find->{mtn}->certs - (address@hidden, - $advanced_find->{revisions_treeview_details}->{value}); - $advanced_find->{mtn}->get_revision - (address@hidden, - $advanced_find->{revisions_treeview_details}->{value}); - generate_revision_report - ($advanced_find->{details_buffer}, - $advanced_find->{revisions_treeview_details}->{value}, - address@hidden, - "", - address@hidden); + $advanced_find->{details_buffer}->set_text(""); + $advanced_find->{mtn}->certs + (address@hidden, + $advanced_find->{revisions_treeview_details}->{value}); + $advanced_find->{mtn}->get_revision + (address@hidden, + $advanced_find->{revisions_treeview_details}->{value}); + generate_revision_report + ($advanced_find->{details_buffer}, + $advanced_find->{revisions_treeview_details}->{value}, + address@hidden, + "", + address@hidden); - # Scroll back up to the top left. + # Scroll back up to the top left. - $advanced_find->{details_buffer}-> - place_cursor($advanced_find->{details_buffer}-> - get_start_iter()); - if ($advanced_find->{details_scrolledwindow}->realized()) - { - $advanced_find->{details_scrolledwindow}-> - get_vadjustment()->set_value(0); - $advanced_find->{details_scrolledwindow}-> - get_hadjustment()->set_value(0); - } + $advanced_find->{details_buffer}-> + place_cursor($advanced_find->{details_buffer}-> + get_start_iter()); + if ($advanced_find->{details_scrolledwindow}->realized()) + { + $advanced_find->{details_scrolledwindow}-> + get_vadjustment()->set_value(0); + $advanced_find->{details_scrolledwindow}-> + get_hadjustment()->set_value(0); + } - # Update the selected branch and revision labels. - - $branch = ""; - foreach my $cert (@certs_list) - { - if ($cert->{name} eq "branch") - { - $branch = $cert->{value}; - last; - } - } - set_label_value($advanced_find->{selected_branch_value_label}, - $branch); - set_label_value($advanced_find-> - {selected_revision_value_label}, - $advanced_find->{revisions_treeview_details}-> - {value}); - - $advanced_find->{ok_button}->set_sensitive(TRUE); - } + $advanced_find->{ok_button}->set_sensitive(TRUE); } else { $advanced_find->{ok_button}->set_sensitive(FALSE); $advanced_find->{details_buffer}->set_text(""); - set_label_value($advanced_find->{selected_branch_value_label}, ""); - set_label_value($advanced_find->{selected_revision_value_label}, - ""); } } @@ -1060,6 +1178,22 @@ sub update_advanced_find_state($$) $advanced_find->{appbar}->pop(); $wm->make_busy($advanced_find, 0) if ($made_busy); + if (defined($matches)) + { + if ($matches > 0) + { + $advanced_find->{appbar}-> + set_status(__nx("Found 1 revision", + "Found {revisions_found} revisions", + $matches, + revisions_found => $matches)); + } + else + { + $advanced_find->{appbar}->set_status(__("Nothing found")); + } + } + } 1; ============================================================ --- Annotate.pm 27cfdc6358dc6b448c976c2e5c8073b267389a61 +++ Annotate.pm 1493920915b434690ff4c1f7e6192a4c32e7bb77 @@ -99,7 +99,7 @@ sub display_annotation($$$) $instance->{window}->show_all(); $wm->make_busy($instance, 1); - $instance->{appbar}->push(""); + $instance->{appbar}->push($instance->{appbar}->get_status()->get_text()); $wm->update_gui(); # Get Monotone to do the annotation. @@ -113,7 +113,7 @@ sub display_annotation($$$) $max_len = 0; $template = sprintf("a%da2a*", length(($lines[0] =~ m/^([^:]+):.*$/)[0])); - for ($i = 0; $i <= $#lines; ++ $i) + for ($i = 0; $i < scalar(@lines); ++ $i) { ($prefix[$i], $lines[$i]) = (unpack($template, $lines[$i]))[0,2]; $lines[$i] =~ s/\s+$//; @@ -128,7 +128,7 @@ sub display_annotation($$$) $wm->update_gui(); $padding = " " x $max_len; $prefix_tag = $text_tag = ""; - for ($i = 0; $i <= $#lines; ++ $i) + for ($i = 0; $i < scalar(@lines); ++ $i) { # Change the colours if there is a new prefix. ============================================================ --- Common.pm 7068c80291b5130224db7a8d70c5b15c0ba8c00c +++ Common.pm d3591a613d333dcab84a11ff965b836cd882088a @@ -815,7 +815,7 @@ sub get_file_details($$$$$$) { $$author = $cert->{value}; } - if ($cert->{name} eq "date") + elsif ($cert->{name} eq "date") { $$last_update = $cert->{value}; } @@ -850,6 +850,7 @@ sub file_glob_to_regexp($) $escaping = 0; $first = 1; + $re_text = "^"; foreach my $char (split(//, $file_glob)) { if ($first) @@ -863,11 +864,11 @@ sub file_glob_to_regexp($) } elsif ($char eq "*") { - $re_text .= $escaping ? "\\*" : ".*"; + $re_text .= $escaping ? "\\*" : "[^/]*"; } elsif ($char eq "?") { - $re_text .= $escaping ? "\\?" : "."; + $re_text .= $escaping ? "\\?" : "[^/]"; } elsif ($char eq "\\") { @@ -888,7 +889,6 @@ sub file_glob_to_regexp($) $escaping = 0; } } - $re_text .= "\$"; return $re_text; @@ -1150,9 +1150,19 @@ sub glade_signal_autoconnect($$) my($callback_name, $widget, $signal_name, $signal_data, $connect_object, $after, $user_data) = @_; my $func = $after ? "signal_connect_after" : "signal_connect"; + + # Need to fully qualify any callback name that isn't prefixed by + # it's package name. + + $callback_name = "main::" . $callback_name + if (index($callback_name, "::") < 0); + + # Actually connect the signal handler. + $widget->$func($signal_name, $callback_name, - $connect_object ? $connect_object : $user_data); }, + $connect_object ? $connect_object : $user_data); + }, $client_data); } ============================================================ --- FindFiles.pm 0da8fa825fe041547b6ecbda0c30d967050d2c4e +++ FindFiles.pm 9a53448f388865ef0aae2b9efaaa731296737f07 @@ -480,7 +480,7 @@ sub search_files_button_clicked_cb($$) } $wm->make_busy($instance, 1); - $instance->{appbar}->push(""); + $instance->{appbar}->push($instance->{appbar}->get_status()->get_text()); $wm->update_gui(); $instance->{appbar}->set_status(__("Finding matching files")); @@ -632,11 +632,22 @@ sub search_files_button_clicked_cb($$) $instance->{appbar}->pop(); if ($matches > 0) { - $instance->{appbar}->set_status(__x("Found {files_found} files", - files_found => $matches)); + $instance->{appbar}->set_status(__nx("Found 1 file", + "Found {files_found} files", + $matches, + files_found => $matches)); } else { + my $dialog; + $dialog = Gtk2::MessageDialog->new + ($instance->{window}, + ["modal"], + "info", + "close", + __("No files matched your query.")); + WindowManager::instance()->allow_input(sub { $dialog->run(); }); + $dialog->destroy(); $instance->{appbar}->set_status(__("Nothing found")); } $wm->make_busy($instance, 0); ============================================================ --- History.pm 8d2d115bea7e921a6a0ba711cbb0974691f83051 +++ History.pm 1fea04fcf7d196ce884c4c1d74162f783e1a4f0b @@ -123,7 +123,7 @@ sub display_revision_change_history($$$) $instance->{window}->show_all(); $wm->make_busy($instance, 1); - $instance->{appbar}->push(""); + $instance->{appbar}->push($instance->{appbar}->get_status()->get_text()); $wm->update_gui(); $instance->{stop_button}->set_sensitive(TRUE); @@ -330,7 +330,7 @@ sub display_file_change_history($$$) $instance->{window}->show_all(); $wm->make_busy($instance, 1); - $instance->{appbar}->push(""); + $instance->{appbar}->push($instance->{appbar}->get_status()->get_text()); $wm->update_gui(); # Get the list of file change revisions. Remember that a warning is @@ -718,7 +718,7 @@ sub compare_revisions($$$;$) $instance->{window}->show_all(); $wm->make_busy($instance, 1); - $instance->{appbar}->push(""); + $instance->{appbar}->push($instance->{appbar}->get_status()->get_text()); $wm->update_gui(); $instance->{mtn} = $mtn; @@ -798,7 +798,7 @@ sub compare_revisions($$$;$) ($instance->{comparison_buffer}->get_end_iter(), $line . "\n", "compare-info"); - for ($i = 1; $i <= $#lines; ++ $i) + for ($i = 1; $i < scalar(@lines); ++ $i) { # Deal with the initial comment lines that summarise the entire set @@ -956,7 +956,7 @@ sub compare_revisions($$$;$) $instance->{appbar}->set_status(__("Displaying differences")); $wm->update_gui(); - for ($i = 0; $i <= $#{$instance->{diff_output}}; ++ $i) + for ($i = 0; $i < scalar(@{$instance->{diff_output}}); ++ $i) { # Deal with lines that introduce a new file comparison. ============================================================ --- mtn-browse bb0c210124e86ea129859b57e88febda4f14f18a +++ mtn-browse 3b5148c89ee9ae73df8c18d104e476e27c6aa764 @@ -1744,7 +1744,7 @@ sub update_browser_state($$) my $wm = WindowManager->instance(); $wm->make_busy($browser, 1); - $browser->{appbar}->push(""); + $browser->{appbar}->push($browser->{appbar}->get_status()->get_text()); $wm->update_gui(); # The database has changed. ============================================================ --- mtn-browse.glade 64a3a44c3739541710e729d840bcf096deb76837 +++ mtn-browse.glade cfe9e3171f3f842633db5c602f10340385122831 @@ -2827,7 +2827,7 @@ Tag - True + False True @@ -2905,7 +2905,7 @@ Tag - True + False True @@ -2916,271 +2916,6 @@ Tag True - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 0 - 0 - - - - 5 - True - True - 5 - - - - True - False - 5 - - - - 0 - 0 - True - Name of the currently selected branch - True - False - - - - 0 - 0 - True - True - Branch: - False - False - GTK_JUSTIFY_LEFT - False - True - 0 - 0.5 - 0 - 0 - - - - - 0 - False - False - - - - - - True - True - GTK_POLICY_NEVER - GTK_POLICY_NEVER - GTK_SHADOW_NONE - GTK_CORNER_TOP_LEFT - - - - True - 1 - 1 - 0 0 310 10 279 310 - 0 0 17 10 15.3 17 - - - - 0 - 0 - True - True - False - - - - 0 - 0 - True - True - - False - False - GTK_JUSTIFY_LEFT - False - True - 0 - 0.5 - 0 - 0 - - - - - 0 - 0 - - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - False - 5 - - - - True - Id of the currently selected revision - True - False - - - - True - Revision id: - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - - - - - 0 - False - False - - - - - - True - True - GTK_POLICY_NEVER - GTK_POLICY_NEVER - GTK_SHADOW_NONE - GTK_CORNER_TOP_LEFT - - - - True - 1 - 1 - 0 0 287 10 258.3 287 - 0 0 17 10 15.3 17 - - - - 0 - 0 - True - True - False - - - - 0 - 0 - True - True - - False - False - GTK_JUSTIFY_LEFT - False - True - 0 - 0.5 - 0 - 0 - - - - - 0 - 0 - - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - - - - True - <b>Current Selection</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - - - label_item - - - - - 0 - False - True - - 0