# # # patch "lib/perl/AdvancedFind.pm" # from [cdff0ecee46a675534e59e16dd909f595e0c4680] # to [f432e438049bfb004421bb6f0d11cf95f1b7af21] # # patch "lib/perl/Annotate.pm" # from [c460f56eab1ccb3ceb9ce3b0739091ca803c4126] # to [8e16510372349c2b286acd7d8f0c7c06e1975fe4] # # patch "lib/perl/ChangeLog.pm" # from [d008a33667f2a051a93218bd74ba436873b5c3dd] # to [f04c9d5849e92fe642eaa58b21866c23e3d41f55] # # patch "lib/perl/Common.pm" # from [eed18cd34345230a4b1af75918700e68fb3ca1c7] # to [3603c2d755e6dee8c4127276b570ebb6fe6ab910] # # patch "lib/perl/FindFiles.pm" # from [27829d8e08feb653dd77300b2d42970d95414e54] # to [d5c2aea4c55ed1cbab71eab77c50c0e9654d99ca] # # patch "lib/perl/FindText.pm" # from [84962543cd69a973957c121a9bdc38fc65920de6] # to [66d051cf3875e01c5578e9a6cf583643c9e9d2bd] # # patch "lib/perl/History.pm" # from [0429cad939f23bed90ff4f8c7618d96c7545efe2] # to [6a5a71441f721d4a9a4af1fb6e2376649c16f9ca] # # patch "lib/perl/Preferences.pm" # from [0192904c3adf257f2370d79c6d182e48b68d6d64] # to [c6fc2f1148d3f22fb064cfa27ad7fec2174ca351] # # patch "lib/perl/WindowManager.pm" # from [ca97b2b82209e409402a620b46d6b9f3870cf542] # to [75e477fa45e6350da4e3878ce91c6204279ad098] # # patch "lib/ui/mtn-browse.glade" # from [63c5b2fec95fadae114228db9f47d780387a4c56] # to [b6a6fe509788e353d998a8a8ba9e3f0426a7cef6] # # patch "locale/help/C/mtn-browse.xml" # from [f952b71fc9441d79aa993a918925b7eedddf6451] # to [c029971be0377ea30dd714be49360f60da65d842] # # patch "mtn-browse" # from [60f487dbe52575f282947312952f8e3d818297d9] # to [3d42a72487f95bc4a7eaf3ea46f6f28176acbd29] # ============================================================ --- lib/perl/AdvancedFind.pm cdff0ecee46a675534e59e16dd909f595e0c4680 +++ lib/perl/AdvancedFind.pm f432e438049bfb004421bb6f0d11cf95f1b7af21 @@ -690,13 +690,20 @@ sub get_advanced_find_window($) local $instance->{in_cb} = 1; $instance->{window}->show_all(); - # Register the window for management. + # Register the window for management and set up the help callbacks. $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}, - $instance->{details_textview}->get_window("text")); + $instance->{stop_button}); + register_help_callbacks + ($instance, + {widget => "simple_frame", + help_ref => __("mtnb-mcqc-simple-queries")}, + {widget => "advanced_frame", + help_ref => __("mtnb-mcqc-helper-tools")}, + {widget => undef, + help_ref => __("mtnb-mcqc-the-advanced-find-dialog-window")}); } else ============================================================ --- lib/perl/Annotate.pm c460f56eab1ccb3ceb9ce3b0739091ca803c4126 +++ lib/perl/Annotate.pm 8e16510372349c2b286acd7d8f0c7c06e1975fe4 @@ -745,13 +745,13 @@ sub get_annotation_window() create_format_tags($instance->{annotation_buffer}); $instance->{annotation_textview}->modify_font($mono_font); - # Register the window for management. + # Register the window for management and set up the help callbacks. - $wm->manage($instance, - $window_type, - $instance->{window}, - undef, - $instance->{annotation_textview}->get_window("text")); + $wm->manage($instance, $window_type, $instance->{window}); + register_help_callbacks + ($instance, + {widget => undef, + help_ref => __("mtnb-lachc-the-annotated-listing-window")}); } else { ============================================================ --- lib/perl/ChangeLog.pm d008a33667f2a051a93218bd74ba436873b5c3dd +++ lib/perl/ChangeLog.pm f04c9d5849e92fe642eaa58b21866c23e3d41f55 @@ -427,13 +427,13 @@ sub get_change_log_window() create_format_tags($instance->{changelog_buffer}); $instance->{changelog_textview}->modify_font($mono_font); - # Register the window for management. + # Register the window for management and set up the help callbacks. - $wm->manage($instance, - $window_type, - $instance->{window}, - undef, - $instance->{changelog_textview}->get_window("text")); + $wm->manage($instance, $window_type, $instance->{window}); + register_help_callbacks + ($instance, + {widget => undef, + help_ref => __("mtnb-lachc-the-change-log-window")}); } else { ============================================================ --- lib/perl/Common.pm eed18cd34345230a4b1af75918700e68fb3ca1c7 +++ lib/perl/Common.pm 3603c2d755e6dee8c4127276b570ebb6fe6ab910 @@ -70,6 +70,7 @@ sub open_database($$$); sub handle_comboxentry_history($$;$); sub hex_dump($); sub open_database($$$); +sub register_help_callbacks($@); sub run_command($@); sub save_as_file($$$); sub set_label_value($$); @@ -1183,6 +1184,48 @@ sub handle_comboxentry_history($$;$) # ############################################################################## # +# Routine - register_help_callbacks +# +# Description - Register all of the context sensitive help callbacks for +# the specified window instance. +# +# Data - $instance : The window instance. +# $details : A list of records containing the widget and +# help reference for that widget. If a widget is +# set to undef then that entry represents the +# default help callback for that entire window. +# +############################################################################## + + + +sub register_help_callbacks($@) +{ + + my($instance, @details) = @_; + + my $wm = WindowManager->instance(); + + foreach my $entry (@details) + { + my $help_ref = $entry->{help_ref}; + my $widget = defined($entry->{widget}) + ? $instance->{glade}->get_widget($entry->{widget}) : undef; + $wm->help_connect($instance, + $widget, + sub { + my($widget, $instance) = @_; + return if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + Gnome2::Help->display("mtn-browse.xml", + $help_ref); + }); + } + +} +# +############################################################################## +# # Routine - create_format_tags # # Description - Creates the Gtk2::TextBuffer tags that are used to pretty @@ -1405,7 +1448,7 @@ sub set_label_value($$) my($widget, $value) = @_; $widget->set_text($value); - $tooltips->set_tip($widget->parent(), $value); + $tooltips->set_tip($widget->get_parent(), $value); } # ============================================================ --- lib/perl/FindFiles.pm 27829d8e08feb653dd77300b2d42970d95414e54 +++ lib/perl/FindFiles.pm d5c2aea4c55ed1cbab71eab77c50c0e9654d99ca @@ -982,12 +982,24 @@ sub get_find_files_window() $widget->set_sensitive(FALSE); } - # Register the window for management. + # Register the window for management and set up the help callbacks. $wm->manage($instance, $window_type, $instance->{window}, $instance->{stop_button}); + register_help_callbacks + ($instance, + {widget => "name_vbox", + help_ref => __("mtnb-ffwarc-query-fields")}, + {widget => "contents_vbox", + help_ref => __("mtnb-ffwarc-query-fields")}, + {widget => "properties_table", + help_ref => __("mtnb-ffwarc-query-fields")}, + {widget => "button_vbox", + help_ref => __("mtnb-ffwarc-query-buttons")}, + {widget => undef, + help_ref => __("mtnb-ffwarc-the-find-files-window")}); } else ============================================================ --- lib/perl/FindText.pm 84962543cd69a973957c121a9bdc38fc65920de6 +++ lib/perl/FindText.pm 66d051cf3875e01c5578e9a6cf583643c9e9d2bd @@ -305,7 +305,7 @@ sub find_text_textview_key_press_event_c # Ignore the state of the caps-lock key. - $state = $event->state() - "lock_mask"; + $state = $event->state() - "lock-mask"; # Work out what the key is having taken into account any modifier keys # (except caps-lock). @@ -319,7 +319,7 @@ sub find_text_textview_key_press_event_c # We are only interested in Ctrl-f. if (defined($keyval) && $keyval == $Gtk2::Gdk::Keysyms{f} - && ($state - $consumed_modifiers) == "control_mask") + && ($state - $consumed_modifiers) eq "control-mask") { find_text($instance->{window}, $widget); return TRUE; @@ -774,9 +774,17 @@ sub get_find_text_window($$) $instance->{find_comboboxentry}->child()->grab_focus(); $instance->{find_comboboxentry}->child()->set_position(-1); - # If necessary, register the window for management. + # If necessary, register the window for management and set up the help + # callbacks. - $wm->manage($instance, $window_type, $instance->{window}, undef) if ($new); + if ($new) + { + $wm->manage($instance, $window_type, $instance->{window}); + register_help_callbacks + ($instance, + {widget => undef, + help_ref => __("mtnb-gsc-browser-buttons")}); + } return $instance; ============================================================ --- lib/perl/History.pm 0429cad939f23bed90ff4f8c7618d96c7545efe2 +++ lib/perl/History.pm 6a5a71441f721d4a9a4af1fb6e2376649c16f9ca @@ -1554,13 +1554,21 @@ sub get_history_window() create_format_tags($instance->{history_buffer}); $instance->{history_textview}->modify_font($mono_font); - # Register the window for management. + # Register the window for management and set up the help callbacks. $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}, - $instance->{history_textview}->get_window("text")); + $instance->{stop_button}); + register_help_callbacks + ($instance, + {widget => "stop_button", + help_ref => __("mtnb-lachc-history-buttons")}, + {widget => "compare_button", + help_ref => __("mtnb-lachc-history-buttons")}, + {widget => undef, + help_ref => __("mtnb-lachc-the-revision-and-file-history-" + . "windows")}); } else { @@ -1839,13 +1847,20 @@ sub get_revision_comparison_window() set_text(__("+ Revision Change Log")); } - # Register the window for management. + # Register the window for management and set up the help callbacks. $wm->manage($instance, $window_type, $instance->{window}, - $instance->{stop_button}, - $instance->{comparison_textview}->get_window("text")); + $instance->{stop_button}); + register_help_callbacks + ($instance, + {widget => "file_comparison_hbox", + help_ref => __("mtnb-lachc-differences-buttons")}, + {widget => "comparison_hbuttonbox", + help_ref => __("mtnb-lachc-differences-buttons")}, + {widget => undef, + help_ref => __("mtnb-lachc-the-differences-window")}); } else { ============================================================ --- lib/perl/Preferences.pm 0192904c3adf257f2370d79c6d182e48b68d6d64 +++ lib/perl/Preferences.pm c6fc2f1148d3f22fb064cfa27ad7fec2174ca351 @@ -1151,9 +1151,13 @@ sub get_preferences_window($$) local $instance->{in_cb} = 1; $instance->{window}->show_all(); - # Register the window for management. + # Register the window for management and set up the help callbacks. - $wm->manage($instance, $window_type, $instance->{window}, undef); + $wm->manage($instance, $window_type, $instance->{window}); + register_help_callbacks + ($instance, + {widget => undef, + help_ref => __("mtnb-upc-the-preferences-dialog-window")}); } else ============================================================ --- lib/perl/WindowManager.pm ca97b2b82209e409402a620b46d6b9f3870cf542 +++ lib/perl/WindowManager.pm 75e477fa45e6350da4e3878ce91c6204279ad098 @@ -56,8 +56,9 @@ use Carp; # Standard Perl and CPAN modules. use Carp; -use Glib; +use Glib qw(FALSE TRUE); use Gtk2; +use Gtk2::Gdk::Keysyms; # ***** GLOBAL DATA DECLARATIONS ***** @@ -81,19 +82,24 @@ my $singleton; # Public methods. +sub activate_context_sensitive_help($$); sub allow_input($&); sub cleanup($); sub cond_find($$&); sub find_unused($$); +sub help_connect($$$$); sub instance($); sub make_busy($$$;$); -sub manage($$$$;$@); +sub manage($$$$;$); sub reset_state($); sub update_gui(); # Private routines. -sub event_filter($$); +sub busy_event_filter($$); +sub find_gdk_windows($$); +sub find_record($$); +sub help_event_filter($$); # ***** PACKAGE INFORMATION ***** @@ -127,10 +133,38 @@ sub instance($) if (! defined($singleton)) { - $singleton = {windows => [], - busy_cursor => Gtk2::Gdk::Cursor->new("watch"), - state_stack => [], - allow_input => 0}; + my $accel = Gtk2::AccelGroup->new(); + $accel->connect($Gtk2::Gdk::Keysyms{F1}, + [], + [], + sub { + my $this = WindowManager->instance(); + if (defined($this->{help_contents_cb})) + { + &{$this->{help_contents_cb}}(undef, undef); + return TRUE; + } + return FALSE; + }); + $accel->connect($Gtk2::Gdk::Keysyms{F1}, + ["shift-mask"], + [], + sub { + my $this = WindowManager->instance(); + $this->activate_context_sensitive_help + (! $this->{help_active}); + return TRUE; + }); + $singleton = {windows => [], + busy_cursor => Gtk2::Gdk::Cursor->new("watch"), + busy_state_stack => [], + allow_input => 0, + help_active => 0, + help_gdk_windows => [], + help_accel => $accel, + help_cursor => Gtk2::Gdk::Cursor-> + new("question-arrow"), + help_contents_cb => undef}; return bless($singleton, $class); } @@ -189,32 +223,91 @@ sub cleanup($) # 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, @windows) = @_; + my($this, $instance, $type, $window, $grab_widget) = @_; - # Simply store the details in our window list. + my $list; + croak("Window argument must be an object derived from Gtk2::Window") + unless ($window->isa("Gtk2::Window")); + + # Set up the key to be an accelerator key that activates the context + # sensitive help mechanism. + + $window->add_accel_group($this->{help_accel}); + + # Traverse the widget hierarchy looking for additional windows that need to + # be handled WRT mouse cursor changes. + + $list = []; + find_gdk_windows($window, $list); + + # Store the details in our window list. + push(@{$this->{windows}}, - {instance => $instance, - type => $type, - window => $window, - busy_windows => [$window->window(), @windows], - grab_widget => $grab_widget}); + {instance => $instance, + type => $type, + window => $window, + gdk_windows => $list, + grab_widget => $grab_widget, + help_callbacks => {}}); } # ############################################################################## # +# Routine - help_connect +# +# Description - Register the specified help callback for the specified +# window instance and widget. +# +# Data - $this : The object. +# $instance : Either the window instance that is to have a +# context sensitive help callback registered or +# undef if the top level help contents callback +# is to be registered. +# $widget : Either the containing widget inside which the +# help event needs to occur for this callback to +# be invoked or undef if this callback is to be +# invoked if there are no more specific callbacks +# registered for the help event. +# $callback : A reference to the help callback routine that +# is to be called. +# +############################################################################## + + + +sub help_connect($$$$) +{ + + my($this, $instance, $widget, $callback) = @_; + + $widget = "" if (! defined($widget)); + + # Simply store the callback details depending upon its type. + + if (defined($instance)) + { + my $entry = $this->find_record($instance); + $entry->{help_callbacks}->{$widget} = $callback; + } + else + { + $this->{help_contents_cb} = $callback; + } + +} +# +############################################################################## +# # Routine - find_unused # # Description - Try and find an unused window of the specified type in the @@ -300,8 +393,9 @@ sub cond_find($$&) # active. # $exclude : True if the window referenced by $instance is # to be excluded from the list of windows that -# are to be made busy (this is used by modal -# dialogs). +# are to be made busy, otherwise false if all +# windows are to be made busy. This is used by +# modal dialogs. This is optional. # ############################################################################## @@ -312,25 +406,10 @@ sub make_busy($$$;$) my($this, $instance, $busy, $exclude) = @_; - my($entry, - $found, - $head, + my($head, @list); + my $entry = $this->find_record($instance); - $exclude = defined($exclude) ? $exclude : 0; - - # 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)); - # When making things busy filter out keyboard and mouse button events # unless they relate to the grab widget (usually a `stop' button) and make # the mouse cursor busy. Making things unbusy is simply the reverse. Also @@ -338,15 +417,15 @@ sub make_busy($$$;$) if ($busy) { - Gtk2::Gdk::Event->handler_set(\&event_filter, + Gtk2::Gdk::Event->handler_set(\&busy_event_filter, {singleton => $this, grab_widget => $entry->{grab_widget}}) - if (! $exclude); + unless ($exclude); foreach my $win_instance (@{$this->{windows}}) { if (! $exclude || $win_instance->{instance} != $instance) { - foreach my $window (@{$win_instance->{busy_windows}}) + foreach my $window (@{$win_instance->{gdk_windows}}) { if ($window->is_visible()) { @@ -356,26 +435,26 @@ sub make_busy($$$;$) } } } - push(@{$this->{state_stack}}, + push(@{$this->{busy_state_stack}}, {exclude => $exclude, grab_widget => $instance->{grab_widget}, window_list => address@hidden); } else { - pop(@{$this->{state_stack}}); - if (scalar(@{$this->{state_stack}}) == 0) + pop(@{$this->{busy_state_stack}}); + if (scalar(@{$this->{busy_state_stack}}) == 0) { - reset_state($this); + $this->reset_state(); } else { - $head = $this->{state_stack}->[$#{$this->{state_stack}}]; + $head = $this->{busy_state_stack}->[$#{$this->{busy_state_stack}}]; foreach my $win_instance (@{$this->{windows}}) { - foreach my $window (@{$win_instance->{busy_windows}}) + foreach my $window (@{$win_instance->{gdk_windows}}) { - $found = 0; + my $found = 0; foreach my $busy_window (@{$head->{window_list}}) { if ($window == $busy_window) @@ -401,7 +480,7 @@ sub make_busy($$$;$) else { Gtk2::Gdk::Event->handler_set - (\&event_filter, + (\&busy_event_filter, {singleton => $this, grab_widget => $entry->{grab_widget}}); } @@ -412,6 +491,36 @@ sub make_busy($$$;$) # ############################################################################## # +# Routine - update_gui +# +# Description - Process all outstanding Gtk2 toolkit events. This is used +# to update the GUI whilst the application is busy doing +# something. +# +# Data - None. +# +############################################################################## + + + +sub update_gui() +{ + + # Only allow this if we are actually running inside Gtk2. + + return if (Gtk2->main_level() == 0); + + # Process all outstanding events. + + while (Gtk2->events_pending()) + { + Gtk2->main_iteration(); + } + +} +# +############################################################################## +# # Routine - allow_input # # Description - Execute the specified code block whilst allowing mouse and @@ -438,6 +547,117 @@ sub allow_input($&) # ############################################################################## # +# Routine - activate_context_sensitive_help +# +# Description - Starts and stops the context sensitive help mode for the +# application (in this mode the user can click on a widget +# and get help on it). +# +# Data - $this : The object. +# $activate : True if the context sensitive help mode should +# be activated, otherwise false if it should be +# deactivated. +# +############################################################################## + + + +sub activate_context_sensitive_help($$) +{ + + my($this, $activate) = @_; + + my $head; + + # Ignore duplicate calls. + + return if (($activate && $this->{help_active}) + || ! ($activate || $this->{help_active})); + + if ($activate) + { + + # Activate context sensitive help. Do this by installing our custom + # event handler and then go through all visible unbusy windows changing + # their mouse cursor a question mark (also keep a record of what + # windows have been changed in help_gdk_windows so it can be undone). + + $this->{help_active} = 1; + $this->{help_gdk_windows} = []; + + Gtk2::Gdk::Event->handler_set(\&help_event_filter, $this); + + # Do we have any busy windows? + + if (scalar(@{$this->{busy_state_stack}}) == 0) + { + + # No we don't so change all visible windows. + + foreach my $win_instance (@{$this->{windows}}) + { + foreach my $window (@{$win_instance->{gdk_windows}}) + { + if ($window->is_visible()) + { + $window->set_cursor($this->{help_cursor}); + push(@{$this->{help_gdk_windows}}, $window); + } + } + } + + } + else + { + + # Yes we have so change only the non-busy windows. + + $head = $this->{busy_state_stack}->[$#{$this->{busy_state_stack}}]; + foreach my $win_instance (@{$this->{windows}}) + { + foreach my $window (@{$win_instance->{gdk_windows}}) + { + my $found = 0; + foreach my $busy_window (@{$head->{window_list}}) + { + if ($window == $busy_window) + { + $found = 1; + last; + } + } + if (! $found && $window->is_visible()) + { + $window->set_cursor($this->{help_cursor}); + push(@{$this->{help_gdk_windows}}, $window); + } + } + } + + } + + } + else + { + + # Deactivate context sensitive help. Simply do this by reinstating the + # default event handling and then resetting the mouse cursor on all of + # those windows that had their cursor changed in the first place. + + $this->{help_active} = 0; + Gtk2::Gdk::Event->handler_set(undef); + foreach my $window (@{$this->{help_gdk_windows}}) + { + $window->set_cursor(undef); + } + $this->{help_gdk_windows} = []; + + } + +} +# +############################################################################## +# # Routine - reset_state # # Description - Completely resets the state of all windows and input @@ -455,12 +675,14 @@ sub reset_state($) my $this = $_[0]; - $this->{state_stack} = []; + $this->{busy_state_stack} = []; $this->{allow_input} = 0; + $this->{help_active} = 0; + $this->{help_gdk_windows} = []; foreach my $win_instance (@{$this->{windows}}) { - foreach my $window (@{$win_instance->{busy_windows}}) + foreach my $window (@{$win_instance->{gdk_windows}}) { $window->set_cursor(undef); } @@ -471,33 +693,78 @@ sub reset_state($) # ############################################################################## # -# Routine - update_gui +# Routine - find_gdk_windows # -# Description - Process all outstanding Gtk2 toolkit events. This is used -# to update the GUI whilst the application is busy doing -# something. +# Description - Recursively descends the widget hierarchy from the +# specified widget, looking for widgets that need their own +# mouse cursor handling. # -# Data - None. +# Data - $widget : The widget from where the search is to be +# started. +# $list : A reference to a list that is to contain the +# Gtk2::Gdk:Window widgets for all of those widgets +# that need their own mouse cursor handling. # ############################################################################## -sub update_gui() +sub find_gdk_windows($$) { - return if (Gtk2->main_level() == 0); - while (Gtk2->events_pending()) + my($widget, $list) = @_; + + if ($widget->isa("Gtk2::Window")) { - Gtk2->main_iteration(); + push(@$list, $widget->window()); } + elsif ($widget->isa("Gtk2::TextView")) + { + push(@$list, $widget->get_window("text")); + } + if ($widget->isa("Gtk2::Container")) + { + foreach my $child ($widget->get_children()) + { + find_gdk_windows($child, $list); + } + } } # ############################################################################## # -# Routine - event_filter +# Routine - find_record # +# Description - Find and return the management record for the specified +# instance. +# +# Data - $this : The object. +# $instance : The window instance that is to be found. +# Return Value : A reference to the management record that +# manages the specified window instance. +# +############################################################################## + + + +sub find_record($$) +{ + + my($this, $instance) = @_; + + foreach my $win_instance (@{$this->{windows}}) + { + return $win_instance if ($win_instance->{instance} == $instance); + } + croak("Called with an unmanaged instance record"); + +} +# +############################################################################## +# +# Routine - busy_event_filter +# # Description - Filter for getting rid of unwanted keyboard and mouse # button events when the application is busy. # @@ -510,7 +777,7 @@ sub update_gui() -sub event_filter($$) +sub busy_event_filter($$) { my($event, $client_data) = @_; @@ -554,5 +821,139 @@ sub event_filter($$) Gtk2->main_do_event($event); } +# +############################################################################## +# +# Routine - help_event_filter +# +# Description - Filter for getting rid of unwanted keyboard and mouse +# button events when the application is in context sensitive +# help mode. +# +# Data - $event : The Gtk2::Gdk::Event object representing the +# current event. +# $client_data : The client data that was registered along +# with this event handler. +# +############################################################################## + + +sub help_event_filter($$) +{ + + my($event, $this) = @_; + + my $type = $event->type(); + + # See if it is an event we are interested in (pressing the key or + # pressing the left mouse button). + + # Key presses. + + if ($type eq "key-press") + { + + my($consumed_modifiers, + $keymap, + $keyval, + $state); + + # Ignore the state of the caps-lock key. + + $state = $event->state() - "lock-mask"; + + # Work out what the key is having taken into account any modifier keys + # (except caps-lock). + + $keymap = Gtk2::Gdk::Keymap->get_for_display + (Gtk2::Gdk::Display->get_default()); + ($keyval, $consumed_modifiers) = + ($keymap->translate_keyboard_state + ($event->hardware_keycode(), $state, $event->group()))[0, 3]; + + # We are only interested in (in which case just let it through to + # be processed in the normal way, which in turn will deactivate context + # sensitive help mode). + + return if (! (defined($keyval) && $keyval == $Gtk2::Gdk::Keysyms{F1} + && ($state - $consumed_modifiers) eq "shift-mask")); + + } + + # Mouse button presses. + + elsif ($type eq "button-press") + { + + # Only interested in the left mouse button without any keyboard + # modifiers active (except caps-lock). + + if ($event->button == 1 && ($event->state() - "lock-mask") == []) + { + my $event_widget; + if (defined($event_widget = Gtk2->get_event_widget($event))) + { + + my ($entry, + $help_cb, + $widget); + + # Assume that the top level window that is currently active is + # the one that was clicked on. + + foreach my $win_instance (@{$this->{windows}}) + { + if ($win_instance->{window}->is_active()) + { + $entry = $win_instance; + last; + } + } + return unless (defined($entry)); + + # Now find the relevant help callback for the widget or one of + # its containing parents. If nothing is found then check to see + # if there is a default help callback for the window (indicated + # by having the widget set to ''). + + $widget = $event_widget; + do + { + $help_cb = $entry->{help_callbacks}->{$widget} + if (exists($entry->{help_callbacks}->{$widget})); + } + while (defined($widget = $widget->get_parent()) + && ! defined($help_cb)); + if (! defined($help_cb)) + { + return unless (exists($entry->{help_callbacks}->{""})); + $help_cb = $entry->{help_callbacks}->{""}; + } + + # Now simply call the help callback. + + &$help_cb($event_widget, $entry->{instance}); + + $this->activate_context_sensitive_help(0); + + } + } + return; + + } + + # Discard any remaining user input events. + + elsif (exists($filtered_events{$type})) + { + return; + } + + # Actually process the event. + + Gtk2->main_do_event($event); + +} + 1; ============================================================ --- lib/ui/mtn-browse.glade 63c5b2fec95fadae114228db9f47d780387a4c56 +++ lib/ui/mtn-browse.glade b6a6fe509788e353d998a8a8ba9e3f0426a7cef6 @@ -64,7 +64,7 @@ - + True gtk-new 1 @@ -107,7 +107,7 @@ - + True gtk-quit 1 @@ -153,15 +153,15 @@ - + True - _Contents + _Help Contents True - + - + True gtk-help 1 @@ -175,6 +175,28 @@ + + True + _Context Help + True + + + + + + True + gtk-help + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + True @@ -188,7 +210,7 @@ - + True gtk-home 1 @@ -318,7 +340,7 @@ - + True Reload the current database Reload @@ -7494,14 +7516,14 @@ of the command False - + 5 True False 5 - + True 2 2 @@ -7523,7 +7545,7 @@ of the command - + True Enter the file name pattern that is to be searched for @@ -7752,7 +7774,7 @@ subdirectories or not 5 - + True Enter the text that is to be searched for inside files ============================================================ --- locale/help/C/mtn-browse.xml f952b71fc9441d79aa993a918925b7eedddf6451 +++ locale/help/C/mtn-browse.xml c029971be0377ea30dd714be49360f60da65d842 @@ -173,7 +173,7 @@ GNOME or DocBook. This chapter covers the basic usage of &APP;. For more advanced usage topics please look at the subsequent chapters. - + Opening A Database When &APP; first starts up, nearly everything is greyed out. You need to select a Monotone database by using the Open tool-bar button or the FileOpen menu option. Use the Open Database dialog window to select the database and left click on the Open button to finish. @@ -188,7 +188,7 @@ GNOME or DocBook. - + Monotone Browser Window - At A Glance Once a database has been opened you will be presented with a window like the one shown below. @@ -220,12 +220,12 @@ GNOME or DocBook. - + Browsing The Database This section covers how to quickly select a branch and revision and then get at the files within that revision. - + Selecting A Branch And Revision Before any information can be viewed, one has to select not only the database to use, but also the branch and revision that you wish to view. This is done by using the Branch and Revision combobox entry fields inside the View panel. There are a number of things that &APP; will do to help you select the item you want. @@ -261,7 +261,7 @@ GNOME or DocBook. - + Selecting A File To Display Once a revision has been displayed then the contents of that revision will be displayed in the Revision Browser panel. This acts as a simple file manager. Single left clicking on a file will display its contents and double left clicking on a directory will change into that directory. @@ -296,12 +296,12 @@ GNOME or DocBook. - + Monotone Browser Window - A Closer Look This section looks at the Monotone Browser window in greater detail, going through the menu options and buttons. - + Menus The menus on a Monotone Browser window largely provide an alternative means of accessing the functions provided by the tool-bar buttons. For example the FileOpen menu option does exactly the same thing as the Open tool-bar button. As the tool-bar buttons are discussed in the next section, I will not bother to elaborate on their menu counterparts here. However there are a few extra menu options that do not appear anywhere else: @@ -611,7 +611,7 @@ GNOME or DocBook. Mode - This panel simply allows you to select the type of query that you wish to perform, either a simple query or an advanced one. - Simple Query - This panel operates in a very similar fashion to the View panel found on a Monotone Browser window (see ), apart from all the revision buttons are missing and it operates in a slightly less restrictive manor. + Simple Query - This panel operates in a very similar fashion to the View panel found on a Monotone Browser window (see ), apart from all the revision buttons are missing and it operates in a slightly less restrictive manor. Advanced Query - This panel allows one to directly enter Monotone database queries, it also provides some tools to help those that are not familiar with Monotone's query syntax. ============================================================ --- mtn-browse 60f487dbe52575f282947312952f8e3d818297d9 +++ mtn-browse 3d42a72487f95bc4a7eaf3ea46f6f28176acbd29 @@ -125,6 +125,7 @@ sub close_toolbutton_clicked_cb($$); sub advanced_find_button_clicked_cb($$); sub annotate_button_clicked_cb($$); sub close_toolbutton_clicked_cb($$); +sub context_help_activate_cb($$); sub determine_mime_type($$$$); sub directory_up_button_clicked_cb($$); sub display_file($$); @@ -342,6 +343,11 @@ sub view_button_clicked_cb($$); } $mtn = undef; + # Setup the callback for the accelerator key for all windows. + + WindowManager->instance()->help_connect + (undef, undef, sub { Gnome2::Help->display("mtn-browse.xml"); }); + # Hand control over to Gtk2. Gtk2->main(); @@ -360,8 +366,8 @@ sub view_button_clicked_cb($$); # # Routine - quit_activate_cb # -# Description - Callback routine called when the user selects the quit file -# menu option. +# Description - Callback routine called when the user selects the quit menu +# option. # # Data - $widget : The widget object that received the signal. # $browser : The browser instance that is associated with @@ -395,10 +401,37 @@ sub quit_activate_cb($$) # ############################################################################## # +# Routine - context_help_activate_cb +# +# Description - Callback routine called when the user selects the context +# help menu option. +# +# Data - $widget : The widget object that received the signal. +# $browser : The browser instance that is associated with +# this widget. +# +############################################################################## + + + +sub context_help_activate_cb($$) +{ + + my($widget, $browser) = @_; + + return if ($browser->{in_cb}); + local $browser->{in_cb} = 1; + + WindowManager->instance()->activate_context_sensitive_help(1); + +} +# +############################################################################## +# # Routine - home_page_activate_cb # # Description - Callback routine called when the user selects the home page -# help menu option. +# menu option. # # Data - $widget : The widget object that received the signal. # $browser : The browser instance that is associated with @@ -442,7 +475,7 @@ sub home_page_activate_cb($$) # Routine - about_activate_cb # # Description - Callback routine called when the user selects the about -# help menu option. +# menu option. # # Data - $widget : The widget object that received the signal. # $browser : The browser instance that is associated with @@ -1559,7 +1592,7 @@ sub get_browser_window(;$$$$$) "main_vbox", "browser_hpaned", "close_toolbutton", - "properties_toolbutton", + "reload_toolbutton", "branch_comboboxentry", "revision_comboboxentry", "tagged_checkbutton", @@ -1717,13 +1750,33 @@ sub get_browser_window(;$$$$$) local $browser->{in_cb} = 1; $browser->{window}->show_all(); - # Register the window for management. + # Register the window for management and set up the help callbacks. - $wm->manage($browser, - $window_type, - $browser->{window}, - undef, - $browser->{file_view_sv}->get_window("text")); + $wm->manage($browser, $window_type, $browser->{window}); + register_help_callbacks + ($browser, + {widget => "menubar_bonobodockitem", + help_ref => __("mtnb-gsc-menus")}, + {widget => "toolbar_bonobodockitem", + help_ref => __("mtnb-gsc-tool-bar")}, + {widget => "view_frame", + help_ref => __("mtnb-gsc-selecting-a-branch-and-revision")}, + {widget => "view_button_hbox", + help_ref => __("mtnb-gsc-browser-buttons")}, + {widget => "revision_browser_frame", + help_ref => __("mtnb-gsc-selecting-a-file-to-display")}, + {widget => "directory_button_hbox", + help_ref => __("mtnb-gsc-browser-buttons")}, + {widget => "file_viewer_frame", + help_ref => __("mtnb-gsc-selecting-a-file-to-display")}, + {widget => "file_details_hbox", + help_ref => __("mtnb-gsc-information-fields")}, + {widget => "file_button_vbox", + help_ref => __("mtnb-gsc-browser-buttons")}, + {widget => "details_frame", + help_ref => __("mtnb-gsc-information-fields")}, + {widget => undef, + help_ref => __("mtnb-gsc-monotone-browser-window-at-a-glance")}); # Update the browser's internal state. @@ -1855,7 +1908,7 @@ sub update_browser_state($$) # Disable the browser as no database is associated with it. $browser->{close_toolbutton}->set_sensitive(FALSE); - $browser->{properties_toolbutton}->set_sensitive(FALSE); + $browser->{reload_toolbutton}->set_sensitive(FALSE); $browser->{main_vbox}->set_sensitive(FALSE); set_label_value($browser->{database_name_value_label}, ""); @@ -1866,7 +1919,7 @@ sub update_browser_state($$) # Enable the browser as there is a database associated with it. $browser->{close_toolbutton}->set_sensitive(TRUE); - $browser->{properties_toolbutton}->set_sensitive(TRUE); + $browser->{reload_toolbutton}->set_sensitive(TRUE); $browser->{main_vbox}->set_sensitive(TRUE); if (! defined($browser->{mtn}->get_db_name())) {