# # # patch "AdvancedFind.pm" # from [1c1e1b4b9573f5ceec6105e0de31a41fb096213f] # to [43deae55d1e14ea540a8923aae6db003740009ea] # # patch "Annotate.pm" # from [27b565bcb841d57451ff9944b3c1c7d031530576] # to [a52d53d39423ef6e79fa3a4cdcb6b2f43abbf737] # # patch "ChangeLog.pm" # from [8c4a5ab8cd8fc1f6358cd19034a7453b199fed75] # to [89f70ee2d0dd7470cb5590dc9c22ece02bb8dc06] # # patch "FindText.pm" # from [1ed4fb06ae9a50815ead9253eb8c327a2ee6f16f] # to [39ea4d5ebd6e568d9c81f72c856034190e43ee5d] # # patch "History.pm" # from [67ca912ec21997a9775b03bcbfcdf0e2528c9bc8] # to [d6dad9209d2187519bd67157e783eed160663b2c] # # patch "Preferences.pm" # from [499a8f9813ceca365a122fb4b53dd603f9f76a23] # to [90ea14810e3e1261c6274543705063f785c38e9e] # # patch "WindowManager.pm" # from [22103783ebb0475581144a676cc5e2e749117c74] # to [f952244a969836e522550630537279fdcbf93480] # # patch "mtn-browse" # from [0fe7623067ba6fb3c228e5fa2a5bfefcc5fd2061] # to [95cb6a8f3691166b8795b620ceece7412c810b59] # # patch "mtn-browse.glade" # from [393e92167fc51dff47ba78efad7ed3740246ad38] # to [8601c9c63f24e449ff2af42b19f5e722aa755583] # ============================================================ --- AdvancedFind.pm 1c1e1b4b9573f5ceec6105e0de31a41fb096213f +++ AdvancedFind.pm 43deae55d1e14ea540a8923aae6db003740009ea @@ -688,10 +688,8 @@ sub get_advanced_find_window($) $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}); - $wm->add_busy_windows($instance, - $instance->{details_textview}-> - get_window("text")); + $instance->{stop_button}, + $instance->{details_textview}->get_window("text")); } else ============================================================ --- Annotate.pm 27b565bcb841d57451ff9944b3c1c7d031530576 +++ Annotate.pm a52d53d39423ef6e79fa3a4cdcb6b2f43abbf737 @@ -53,6 +53,7 @@ sub display_annotation($$$); # Private routines. +sub annotation_textview_populate_popup_cb($$$); sub get_annotation_window(); sub mtn_annotate($$$$); # @@ -94,6 +95,7 @@ sub display_annotation($$$) $instance = get_annotation_window(); local $instance->{in_cb} = 1; + $instance->{mtn} = $mtn; $instance->{window}->set_title(__x("Annotated Listing Of {file}", file => $file_name)); $instance->{window}->show_all(); @@ -109,10 +111,11 @@ sub display_annotation($$$) mtn_annotate(address@hidden, $mtn->get_db_name(), $revision_id, $file_name); # Find the longest line for future padding and also split each line into - # the prefix and text parts. + # their prefix and text parts. $max_len = 0; - $template = sprintf("a%da2a*", length(($lines[0] =~ m/^([^:]+):.*$/)[0])); + $instance->{prefix_length} = length(($lines[0] =~ m/^([^:]+):.*$/)[0]); + $template = sprintf("a%da2a*", $instance->{prefix_length}); for ($i = 0; $i < scalar(@lines); ++ $i) { ($prefix[$i], $lines[$i]) = (unpack($template, $lines[$i]))[0,2]; @@ -196,6 +199,139 @@ sub display_annotation($$$) # ############################################################################## # +# Routine - annotation_textview_populate_popup_cb +# +# Description - Callback routine called when the user right clicks on any +# textview window. +# +# Data - $widget : The widget object that received the signal. +# $menu : The Gtk2::Menu widget that is to be updated. +# $instance : The window instance that is associated with +# this widget. +# +############################################################################## + + + +sub annotation_textview_populate_popup_cb($$$) +{ + + my($widget, $menu, $instance) = @_; + + return if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + + my($menu_item, + $revision_part, + $separator, + $start_iter, + $x, + $y); + + # Extract the revision id relating to the block of text directly under the + # mouse cursor. + + ($x, $y) = ($widget->window()->get_pointer())[1 .. 2]; + ($x, $y) = $widget->window_to_buffer_coords("widget", $x, $y); + if (defined($start_iter = ($widget->get_line_at_y($y))[0])) + { + my($end_iter, + $prefix, + $no_more, + $text_buffer); + $end_iter = ($widget->get_line_at_y($y))[0]; + $end_iter->forward_to_line_end(); + $text_buffer = $widget->get_buffer(); + $prefix = substr($text_buffer->get_text($start_iter, $end_iter, TRUE), + 0, + $instance->{prefix_length}); + while ($prefix !~ m/^ *[0-9a-f]+\.+.*$/) + { + if (! $start_iter->backward_line()) + { + $no_more = 1; + last; + } + $end_iter->backward_line(); + $end_iter->forward_to_line_end() + unless ($end_iter->ends_line()); + $prefix = substr($text_buffer->get_text($start_iter, + $end_iter, + TRUE), + 0, + $instance->{prefix_length}); + } + ($revision_part) = ($prefix =~ m/^ *([0-9a-f]+)\.+.*$/) + unless ($no_more); + } + + # Add a `Display Change Log' option to the right-click menu that displays + # the change log of the revision responsible for the text directly under + # the mouse cursor. + + $menu_item = Gtk2::MenuItem->new("Display Change _Log"); + if (! defined($revision_part)) + { + $menu_item->set_sensitive(FALSE); + } + else + { + $menu_item->signal_connect + ("activate", + sub { + + my($widget, $details) = @_; + + return if ($details->{instance}->{in_cb}); + local $details->{instance}->{in_cb} = 1; + + my @revision_ids; + my $wm = WindowManager->instance(); + + $wm->make_busy($details->{instance}, 1); + $instance->{appbar}-> + push($instance->{appbar}->get_status()->get_text()); + $instance->{appbar}->set_status(__("Finding change log")); + $wm->update_gui(); + + $details->{instance}->{mtn}-> + select(address@hidden, "i:" . $details->{revision_part}); + if (scalar(@revision_ids) == 1) + { + display_change_log($details->{instance}->{mtn}, + $revision_ids[0], + "", + undef); + } + else + { + my $dialog = Gtk2::MessageDialog->new + ($instance->{window}, + ["modal"], + "warning", + "close", + __("Cannot access unique revision id.")); + $dialog->run(); + $dialog->destroy(); + } + + $instance->{appbar}->pop(); + $wm->make_busy($details->{instance}, 0); + + }, + {instance => $instance, + revision_part => $revision_part}); + } + $menu_item->show(); + $separator = Gtk2::SeparatorMenuItem->new(); + $separator->show(); + $menu->append($separator); + $menu->append($menu_item); + +} +# +############################################################################## +# # Routine - get_annotation_window # # Description - Creates or prepares an existing annotation window for use. @@ -251,6 +387,7 @@ sub get_annotation_window() hide_find_text($instance->{annotation_textview}); $widget->hide(); $instance->{annotation_buffer}->set_text(""); + $instance->{mtn} = undef; return TRUE; }, $instance); @@ -264,10 +401,11 @@ sub get_annotation_window() # Register the window for management. - $wm->manage($instance, $window_type, $instance->{window}); - $wm->add_busy_windows($instance, - $instance->{annotation_textview}-> - get_window("text")); + $wm->manage($instance, + $window_type, + $instance->{window}, + undef, + $instance->{annotation_textview}->get_window("text")); } else { ============================================================ --- ChangeLog.pm 8c4a5ab8cd8fc1f6358cd19034a7453b199fed75 +++ ChangeLog.pm 89f70ee2d0dd7470cb5590dc9c22ece02bb8dc06 @@ -427,10 +427,11 @@ sub get_change_log_window() # Register the window for management. - $wm->manage($instance, $window_type, $instance->{window}); - $wm->add_busy_windows($instance, - $instance->{changelog_textview}-> - get_window("text")); + $wm->manage($instance, + $window_type, + $instance->{window}, + undef, + $instance->{changelog_textview}->get_window("text")); } else { ============================================================ --- FindText.pm 1ed4fb06ae9a50815ead9253eb8c327a2ee6f16f +++ FindText.pm 39ea4d5ebd6e568d9c81f72c856034190e43ee5d @@ -294,11 +294,9 @@ sub find_text_textview_key_press_event_c my($widget, $event, $instance) = @_; - return FALSE if ($instance->{in_cb}); + return FALSE if ($instance->{in_cb} || $widget->{find_text_disabled}); local $instance->{in_cb} = 1; - return FALSE if ($widget->{find_text_disabled}); - my($consumed_modifiers, $keymap, $keyval, @@ -492,7 +490,7 @@ sub find_button_clicked_cb($$) } $start_iter = ($instance->{text_view}->get_line_at_y($y))[0]; $end_iter = ($instance->{text_view}->get_line_at_y($y))[0]; - $end_iter->forward_to_line_end(); + $end_iter->forward_to_line_end() unless ($end_iter->ends_line()); } @@ -775,7 +773,7 @@ sub get_find_text_window($$) # If necessary, register the window for management. - $wm->manage($instance, $window_type, $instance->{window}) if ($new); + $wm->manage($instance, $window_type, $instance->{window}, undef) if ($new); return $instance; ============================================================ --- History.pm 67ca912ec21997a9775b03bcbfcdf0e2528c9bc8 +++ History.pm d6dad9209d2187519bd67157e783eed160663b2c @@ -1454,10 +1454,8 @@ sub get_history_window() $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}); - $wm->add_busy_windows($instance, - $instance->{history_textview}-> - get_window("text")); + $instance->{stop_button}, + $instance->{history_textview}->get_window("text")); } else { @@ -1710,10 +1708,8 @@ sub get_revision_comparison_window() $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}); - $wm->add_busy_windows($instance, - $instance->{comparison_textview}-> - get_window("text")); + $instance->{stop_button}, + $instance->{comparison_textview}->get_window("text")); } else { ============================================================ --- Preferences.pm 499a8f9813ceca365a122fb4b53dd603f9f76a23 +++ Preferences.pm 90ea14810e3e1261c6274543705063f785c38e9e @@ -1141,7 +1141,7 @@ sub get_preferences_window($$) # Register the window for management. - $wm->manage($instance, $window_type, $instance->{window}); + $wm->manage($instance, $window_type, $instance->{window}, undef); } else ============================================================ --- WindowManager.pm 22103783ebb0475581144a676cc5e2e749117c74 +++ WindowManager.pm f952244a969836e522550630537279fdcbf93480 @@ -81,14 +81,13 @@ my $singleton; # Public methods. -sub add_busy_windows($$@); sub allow_input($&); sub cleanup($); sub cond_find($$&); sub find_unused($$); sub instance($); sub make_busy($$$;$); -sub manage($$$$;$); +sub manage($$$$;$@); sub reset_state($); sub update_gui(); @@ -178,28 +177,30 @@ sub cleanup($) # Routine - manage # # Description - Take the given window instance record and start managing -# it. Please note that it is expected that the top level -# window widget will be in a field called `window'. +# it. # # Data - $this : The object. # $instance : A reference to the window instance record # that is to be managed. # $type : The type of window that is to be managed. -# $window : The Gtk2::Window object for the window that -# is to be managed. -# $grab_widget : The widget that is to still remain +# $window : The main Gtk2::Window object that is +# associated with $instance. +# $grab_widget : The widget object that is to still remain # responsive when making the window busy, most # typically this will be a `stop' button. This # is optional. +# @windows : A list of additional Gtk2::Gdk::Window +# objects that are to be managed in addition +# to $window. This is optional. # ############################################################################## -sub manage($$$$;$) +sub manage($$$$;$@) { - my($this, $instance, $type, $window, $grab_widget) = @_; + my($this, $instance, $type, $window, $grab_widget, @windows) = @_; # Simply store the details in our window list. @@ -207,53 +208,13 @@ sub manage($$$$;$) {instance => $instance, type => $type, window => $window, - busy_windows => [$window->window()], + busy_windows => [$window->window(), @windows], grab_widget => $grab_widget}); } # ############################################################################## # -# Routine - add_busy_windows -# -# Description - Add the specified additional windows for busy cursor -# handling. -# -# Data - $this : The object. -# $instance : A reference to the window instance record that -# is to be updated. -# @windows : The list of additional Gtk2::Gdk::Window -# objects that are to be handled. -# -############################################################################## - - - -sub add_busy_windows($$@) -{ - - my($this, $instance, @windows) = @_; - - my $entry; - - # Find the relevant entry for this instance. - - foreach my $win_instance (@{$this->{windows}}) - { - if ($win_instance->{instance} == $instance) - { - $entry = $win_instance; - last; - } - } - croak("Called with an unmanaged instance record") unless (defined($entry)); - - push(@{$entry->{busy_windows}}, @windows); - -} -# -############################################################################## -# # Routine - find_unused # # Description - Try and find an unused window of the specified type in the ============================================================ --- mtn-browse 0fe7623067ba6fb3c228e5fa2a5bfefcc5fd2061 +++ mtn-browse 95cb6a8f3691166b8795b620ceece7412c810b59 @@ -1644,9 +1644,11 @@ sub get_browser_window(;$$$$$) # Register the window for management. - $wm->manage($browser, $window_type, $browser->{window}); - $wm->add_busy_windows($browser, - $browser->{file_view_sv}->get_window("text")); + $wm->manage($browser, + $window_type, + $browser->{window}, + undef, + $browser->{file_view_sv}->get_window("text")); # Update the browser's internal state. ============================================================ --- mtn-browse.glade 393e92167fc51dff47ba78efad7ed3740246ad38 +++ mtn-browse.glade 8601c9c63f24e449ff2af42b19f5e722aa755583 @@ -4177,6 +4177,7 @@ selected file in an external viewer +