# # # add_file "FindText.pm" # content [cb5af559898d25130ce7407e57fc589ae2c6a350] # # patch "AdvancedFind.pm" # from [dab06fa171f32513f342afe4928b4e0883408791] # to [e590dc075f290fdd8cb6256481168d1eaf909faa] # # patch "Annotate.pm" # from [fdf6c24098c9b17339084f46abe2ed9477c172af] # to [3d84076dd913242ae97ac02928f0c9c06d135bb0] # # patch "ChangeLog.pm" # from [c1df85fb55c1046aaca0babef4b93a92b4a87cb3] # to [29bfd342dd8c58bec9de9a76117d716d1d751ec1] # # patch "History.pm" # from [41c40e6321bf77ae373492051e6386c353c23753] # to [5675816ebf847870454ac602826de5c0535e7d9d] # # patch "mtn-browse" # from [3430674b23ddf46f086b4001c0fa3c5ec495b605] # to [3782e1aaeb4ada57c8097aaf5cba7a9c1273dc7e] # # patch "mtn-browse.glade" # from [79138c09ac145c8365a8a8de09c67f80b4b834e3] # to [1a0bdb6e5042b92e99f3a088eae3a3e2bc4a7eaa] # ============================================================ --- FindText.pm cb5af559898d25130ce7407e57fc589ae2c6a350 +++ FindText.pm cb5af559898d25130ce7407e57fc589ae2c6a350 @@ -0,0 +1,594 @@ +############################################################################## +# +# File Name - FindText.pm +# +# Description - The find text module for the mtn-browse application. This +# module contains all the routines for implementing find text +# window. +# +# Author - A.E.Cooper. +# +# Legal Stuff - Copyright (c) 2007 Anthony Edward Cooper +# . +# +# This program is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; +# either version 3 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public +# License along with this software; if not, write to the Free +# Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307 USA. +# +############################################################################## +# +############################################################################## +# +# Global Data For This Module +# +############################################################################## + + + +# ***** DIRECTIVES ***** + +require 5.008; + +use strict; + +# ***** GLOBAL DATA DECLARATIONS ***** + +# The type of window that is going to be managed by this module. + +my $window_type = "find_text_window"; + +# ***** FUNCTIONAL PROTOTYPES FOR THIS FILE ***** + +# Public routines. + +sub disable_find_text($$); +sub find_text($$); +sub reset_find_text($); + +# Private routines. + +sub find_combo_changed_cb($$); +sub get_find_text_window($$); +# +############################################################################## +# +# Routine - find_text +# +# Description - Display the find text window associated with the specified +# text view widget, creating one if necessary, and allow the +# user to search through the related text buffer. +# +# Data - $parent : The parent window widget for the find text +# window. +# $text_view : The text view widget that is to be searched. +# +############################################################################## + + + +sub find_text($$) +{ + + my($parent, $text_view) = @_; + + my $instance; + + foreach my $window (@windows) + { + if ($window->{type} eq $window_type + && $window->{window}->mapped() + && $window->{text_view} == $text_view) + { + $instance = $window; + last; + } + } + + # A suitable mapped find text window cannot be found so reuse an unsued one + # or create a new one. + + if (! defined($instance)) + { + $instance = get_find_text_window($parent, $text_view); + } + +} +# +############################################################################## +# +# Routine - reset_find_text +# +# Description - Resets the search context for the find text window +# associated with the specified text view widget. +# +# Data - $text_view : The text view widget to which the find text +# window is associated. +# +############################################################################## + + + +sub reset_find_text($) +{ + + my $text_view = $_[0]; + + my $instance; + + foreach my $window (@windows) + { + if ($window->{type} eq $window_type + && $window->{window}->mapped() + && $window->{text_view} == $text_view) + { + $instance = $window; + last; + } + } + + # Simply reset the search context for the found find text window. + + $instance->{match_offset_start} = $instance->{match_offset_end} = -1 + if (defined($instance)); + +} +# +############################################################################## +# +# Routine - disable_find_text +# +# Description - Disables or enables the find text window associated with +# the specified text view widget. +# +# Data - $text_view : The text view widget to which the find text +# window is associated. +# $disable : True if the window is to be disabled, +# otherwise false if it is to be enabled. +# +############################################################################## + + + +sub disable_find_text($$) +{ + + my($text_view, $disable) = @_; + + my $instance; + + foreach my $window (@windows) + { + if ($window->{type} eq $window_type + && $window->{window}->mapped() + && $window->{text_view} == $text_view) + { + $instance = $window; + last; + } + } + + # Simply disable/enable the found find text window. + + $instance->{window}->set_sensitive($disable ? FALSE : TRUE) + if (defined($instance)); + +} +# +############################################################################## +# +# Routine - get_find_text_window +# +# Description - Creates or prepares an existing find text window for use. +# +# Data - $parent : The parent window widget for the find text +# window. +# $text_view : The text view widget that is to be searched. +# +############################################################################## + + + +sub get_find_text_window($$) +{ + + my($parent, $text_view) = @_; + + my($instance, + $new); + + foreach my $window (@windows) + { + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) + { + $instance = $window; + last; + } + } + + # Create a new find text window if an unused one wasn't found, otherwise + # reuse an existing unused one. + + if (! defined($instance)) + { + $new = 1; + $instance = {}; + $instance->{type} = $window_type; + $instance->{glade} = + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); + + # Flag to stop recursive calling of callbacks. + + $instance->{in_cb} = 0; + + # Connect Glade registered signal handlers. + + glade_signal_autoconnect($instance->{glade}, $instance); + + # Get the widgets that we are interested in. + + $instance->{window} = $instance->{glade}->get_widget($window_type); + $instance->{window}->set_icon($app_icon); + $instance->{find_combo} = + $instance->{glade}->get_widget("find_comboboxentry"); + $instance->{case_sensitive_tick} = + $instance->{glade}->get_widget("case_sensitive_checkbutton"); + $instance->{search_backwards_tick} = + $instance->{glade}->get_widget("search_backwards_checkbutton"); + $instance->{find_button} = + $instance->{glade}->get_widget("find_button"); + + # Setup the find text window deletion handlers. + + $instance->{window}->signal_connect + ("delete_event", + sub { + my($widget, $event, $instance) = @_; + return TRUE if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + $instance->{window}->hide(); + return TRUE; + }, + $instance); + $instance->{glade}->get_widget("close_button")->signal_connect + ("clicked", + sub { + my($widget, $instance) = @_; + return TRUE if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + $instance->{window}->hide(); + }, + $instance); + + # Setup the comboboxentry changed signal handler. + + $instance->{find_combo}->child()-> + signal_connect("changed", \&find_combo_changed_cb, $instance); + + # Setup the combobox. + + $instance->{find_combo}-> + set_model(Gtk2::ListStore->new("Glib::String")); + $instance->{find_combo}->set_text_column(0); + $instance->{search_history} = []; + } + else + { + $new = 0; + $instance->{in_cb} = 0; + $instance->{window}->set_sensitive(TRUE); + } + + # Reset the search context. + + $instance->{match_offset_start} = $instance->{match_offset_end} = -1; + $instance->{old_y} = 0; + $instance->{old_search_term} = ""; + + # Make sure the find button is only enabled when there is something entered + # into the comboboxentry widget. + + $instance->{find_button}->set_sensitive + ((length($instance->{find_combo}->child()->get_text()) > 0) ? + TRUE : FALSE); + + # Store the associated text view and text buffer. + + $instance->{text_view} = $text_view; + $instance->{text_buffer} = $instance->{text_view}->get_buffer(); + + # Reparent window and display it. + + $instance->{window}->set_transient_for($parent); + $instance->{window}->show_all(); + + # If necessary, setup the list of windows that can be made busy for this + # application window. + + if ($new) + { + $instance->{busy_windows} = []; + push(@{$instance->{busy_windows}}, $instance->{window}->window()); + + push(@windows, $instance); + } + + return $instance; + +} +# +############################################################################## +# +# Routine - find_button_clicked_cb +# +# Description - Callback routine called when the user clicks on the find +# button in the find text window. +# +# Data - $widget : The widget object that received the signal. +# $instance : The window instance that is associated with +# this widget. +# +############################################################################## + + + +sub find_button_clicked_cb($$) +{ + + my($widget, $instance) = @_; + + return if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + + my($case_sensitive, + $done, + $end_iter, + $expr, + $forward, + $found, + $line, + $rect, + $search_term, + $start_iter); + + $search_term = $instance->{find_combo}->child()->get_text(); + + # Just check that the user actually entered something. + + if (length($search_term) == 0) + { + my $dialog; + $dialog = Gtk2::MessageDialog->new + ($instance->{window}, + ["modal"], + "info", + "close", + "Enter some text to\nsearch for first"); + $dialog->run(); + $dialog->destroy(); + return; + } + + # Store the search term in the history. + + $found = 0; + foreach my $entry (@{$instance->{search_history}}) + { + if ($entry eq $search_term) + { + $found = 1; + last; + } + } + if (! $found) + { + if (unshift(@{$instance->{search_history}}, $search_term) > 20) + { + pop(@{$instance->{search_history}}); + } + $instance->{find_combo}->get_model()->clear(); + foreach my $entry (@{$instance->{search_history}}) + { + $instance->{find_combo}->append_text($entry); + } + } + + # Get the search parameters. + + $case_sensitive = $instance->{case_sensitive_tick}->get_active(); + $forward = ! $instance->{search_backwards_tick}->get_active(); + + # Work out where to start searching from. + + $rect = $instance->{text_view}->get_visible_rect(); + $done = 0; + if ($search_term eq $instance->{old_search_term} + && $instance->{old_y} == $rect->y() + && $instance->{match_offset_start} >= 0) + { + + # Resume searching from where we left off. Adjust the iters so as to + # encompass the remaining text on the line, or if there isn't any then + # move them to the next/previous line. + + if ($forward) + { + $start_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_end}); + $end_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_end}); + if ($start_iter->ends_line()) + { + $done = ! $start_iter->forward_line(); + $end_iter->forward_to_line_end(); + } + else + { + $end_iter->forward_to_line_end(); + } + } + else + { + $start_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_start}); + $end_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_start}); + if ($start_iter->starts_line()) + { + $done = ! $start_iter->backward_line(); + $end_iter->backward_line(); + $end_iter->forward_to_line_end() + unless ($end_iter->ends_line()); + } + else + { + $start_iter->backward_line(); + } + } + + } + else + { + + # Start searching from the visible part of the file. + + my $y; + + if ($forward) + { + $y = $rect->y(); + } + else + { + $y = $rect->y() + $rect->height(); + } + $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(); + + } + + # Precompile the regular expression based upon the search term. + + if ($case_sensitive) + { + $expr = qr/\Q$search_term\E/; + } + else + { + $expr = qr/\Q$search_term\E/i; + } + + # Search for the text. + + $found = 0; + while (! $done) + { + $line = + $instance->{text_buffer}->get_text($start_iter, $end_iter, TRUE); + if ($line =~ m/$expr/g) + { + $instance->{match_offset_start} = + $start_iter->get_offset() + pos($line) - length($search_term); + $instance->{match_offset_end} = + $start_iter->get_offset() + pos($line); + $done = $found = 1; + } + else + { + if ($forward) + { + $done = ! $start_iter->forward_line(); + $end_iter->forward_to_line_end(); + } + else + { + $done = ! $start_iter->backward_line(); + $end_iter->backward_line(); + $end_iter->forward_to_line_end() + unless ($end_iter->ends_line()); + } + } + } + + # Either select the found text or tell the user that nothing could be + # found. + + if ($found) + { + my $start_line_iter; + $start_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_start}); + $start_line_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_start}); + $start_line_iter->backward_line() + unless $start_line_iter->starts_line(); + $end_iter = $instance->{text_buffer}-> + get_iter_at_offset($instance->{match_offset_end}); + $instance->{text_buffer}->select_range($start_iter, $end_iter); + $instance->{text_view}->scroll_to_iter + ($start_line_iter, 0, FALSE, 0, 0); + $instance->{text_view}->scroll_to_iter($end_iter, 0, FALSE, 0, 0); + } + else + { + my $dialog; + $dialog = Gtk2::MessageDialog->new + ($instance->{window}, + ["modal"], + "info", + "close", + sprintf("Could not find\n`%s'", $search_term)); + $dialog->run(); + $dialog->destroy(); + } + + $rect = $instance->{text_view}->get_visible_rect(); + $instance->{old_y} = $rect->y(); + $instance->{old_search_term} = $search_term; + +} +# +############################################################################## +# +# Routine - find_combo_changed_cb +# +# Description - Callback routine called when the user changes the value of +# the find text comboboxentry by selecting an entry from its +# pulldown list or entering text directly. +# +# Data - $widget : The widget object that received the signal. +# $instance : The window instance that is associated with +# this widget. +# +############################################################################## + + + +sub find_combo_changed_cb($$) +{ + + my($widget, $instance) = @_; + + return if ($instance->{in_cb}); + local $instance->{in_cb} = 1; + + $instance->{find_button}->set_sensitive + ((length($instance->{find_combo}->child()->get_text()) > 0) ? + TRUE : FALSE); + +} + +1; ============================================================ --- AdvancedFind.pm dab06fa171f32513f342afe4928b4e0883408791 +++ AdvancedFind.pm e590dc075f290fdd8cb6256481168d1eaf909faa @@ -44,6 +44,12 @@ use strict; use strict; +# ***** GLOBAL DATA DECLARATIONS ***** + +# The type of window that is going to be managed by this module. + +my $window_type = "advanced_find_window"; + # ***** FUNCTIONAL PROTOTYPES FOR THIS FILE ***** # Public routines. @@ -96,8 +102,7 @@ sub advanced_find($$$) foreach my $window (@windows) { - if ($window->{type} eq "advanced_find_window" - && ! $window->{window}->mapped()) + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) { $advanced_find = $window; last; @@ -123,6 +128,7 @@ sub advanced_find($$$) { local $advanced_find->{in_cb} = 1; + $advanced_find->{selected} = 0; # Reset the window contents, then show it. @@ -249,9 +255,9 @@ sub create_advanced_find_window() $tv_column); $instance = {}; - $instance->{type} = "advanced_find_window"; + $instance->{type} = $window_type; $instance->{glade} = - Gtk2::GladeXML->new("../mtn-browse.glade", "advanced_find_window"); + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -267,8 +273,7 @@ sub create_advanced_find_window() # Get the widgets that we are interested in. - $instance->{window} = - $instance->{glade}->get_widget("advanced_find_window"); + $instance->{window} = $instance->{glade}->get_widget($window_type); $instance->{window}->set_icon($app_icon); $instance->{appbar} = $instance->{glade}->get_widget("appbar"); $instance->{simple_query_radiobutton} = ============================================================ --- Annotate.pm fdf6c24098c9b17339084f46abe2ed9477c172af +++ Annotate.pm 3d84076dd913242ae97ac02928f0c9c06d135bb0 @@ -42,7 +42,6 @@ require 5.008; require 5.008; -use lib "/home/aecoope/perl"; use strict; # ***** FUNCTIONAL PROTOTYPES FOR THIS FILE ***** @@ -207,12 +206,14 @@ sub get_annotation_window() my($font, $height, $instance, - $width); + $width, + $window_type); + $window_type = "annotation_window"; + foreach my $window (@windows) { - if ($window->{type} eq "annotation_window" - && ! $window->{window}->mapped()) + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) { $instance = $window; last; @@ -225,9 +226,9 @@ sub get_annotation_window() if (! defined($instance)) { $instance = {}; - $instance->{type} = "annotation_window"; + $instance->{type} = $window_type; $instance->{glade} = - Gtk2::GladeXML->new("../mtn-browse.glade", "annotation_window"); + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -239,8 +240,7 @@ sub get_annotation_window() # Get the widgets that we are interested in. - $instance->{window} = - $instance->{glade}->get_widget("annotation_window"); + $instance->{window} = $instance->{glade}->get_widget($window_type); $instance->{window}->set_icon($app_icon); $instance->{appbar} = $instance->{glade}->get_widget("appbar"); $instance->{annotation_textview} = ============================================================ --- ChangeLog.pm c1df85fb55c1046aaca0babef4b93a92b4a87cb3 +++ ChangeLog.pm 29bfd342dd8c58bec9de9a76117d716d1d751ec1 @@ -42,7 +42,6 @@ require 5.008; require 5.008; -use lib "/home/aecoope/perl"; use strict; # ***** FUNCTIONAL PROTOTYPES FOR THIS FILE ***** @@ -123,12 +122,14 @@ sub get_change_log_window() my($font, $height, $instance, - $width); + $width, + $window_type); + $window_type = "changelog_window"; + foreach my $window (@windows) { - if ($window->{type} eq "change_log_window" - && ! $window->{window}->mapped()) + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) { $instance = $window; last; @@ -141,9 +142,9 @@ sub get_change_log_window() if (! defined($instance)) { $instance = {}; - $instance->{type} = "change_log_window"; + $instance->{type} = $window_type; $instance->{glade} = - Gtk2::GladeXML->new("../mtn-browse.glade", "changelog_window"); + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -155,8 +156,7 @@ sub get_change_log_window() # Get the widgets that we are interested in. - $instance->{window} = - $instance->{glade}->get_widget("changelog_window"); + $instance->{window} = $instance->{glade}->get_widget($window_type); $instance->{window}->set_icon($app_icon); $instance->{changelog_textview} = $instance->{glade}->get_widget("changelog_textview"); ============================================================ --- History.pm 41c40e6321bf77ae373492051e6386c353c23753 +++ History.pm 5675816ebf847870454ac602826de5c0535e7d9d @@ -640,14 +640,16 @@ sub get_history_window() my($font, $height, $instance, - $width); + $width, + $window_type); + $window_type = "history_window"; + # Look for an unused window first. foreach my $window (@windows) { - if ($window->{type} eq "history_window" - && ! $window->{window}->mapped()) + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) { $instance = $window; last; @@ -660,9 +662,9 @@ sub get_history_window() if (! defined($instance)) { $instance = {}; - $instance->{type} = "history_window"; + $instance->{type} = $window_type; $instance->{glade} = - Gtk2::GladeXML->new("../mtn-browse.glade", "history_window"); + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -674,7 +676,7 @@ sub get_history_window() # Get the widgets that we are interested in. - $instance->{window} = $instance->{glade}->get_widget("history_window"); + $instance->{window} = $instance->{glade}->get_widget($window_type); $instance->{window}->set_icon($app_icon); $instance->{appbar} = $instance->{glade}->get_widget("appbar"); $instance->{history_label} = @@ -864,14 +866,16 @@ sub get_revision_comparison_window() $height, $instance, $renderer, - $width); + $width, + $window_type); + $window_type = "revision_comparison_window"; + # Look for an unused window first. foreach my $window (@windows) { - if ($window->{type} eq "revision_comparison_window" - && ! $window->{window}->mapped()) + if ($window->{type} eq $window_type && ! $window->{window}->mapped()) { $instance = $window; last; @@ -884,9 +888,9 @@ sub get_revision_comparison_window() if (! defined($instance)) { $instance = {}; - $instance->{type} = "revision_comparison_window"; - $instance->{glade} = Gtk2::GladeXML->new("../mtn-browse.glade", - "revision_comparison_window"); + $instance->{type} = $window_type; + $instance->{glade} = + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -907,8 +911,7 @@ sub get_revision_comparison_window() # Get the widgets that we are interested in. - $instance->{window} = - $instance->{glade}->get_widget("revision_comparison_window"); + $instance->{window} = $instance->{glade}->get_widget($window_type); $instance->{window}->set_icon($app_icon); $instance->{appbar} = $instance->{glade}->get_widget("appbar"); $instance->{comparison_label} = ============================================================ --- mtn-browse 3430674b23ddf46f086b4001c0fa3c5ec495b605 +++ mtn-browse 3782e1aaeb4ada57c8097aaf5cba7a9c1273dc7e @@ -79,6 +79,7 @@ use Completion; use ChangeLog; use ComboAutoCompletion; use Completion; +use FindText; use History; use Utilities; @@ -108,6 +109,7 @@ sub revision_change_log_button_clicked_c sub new_browser_instance(); sub revision_change_history_button_clicked_cb($$); sub revision_change_log_button_clicked_cb($$); +sub search_text_button_clicked_cb($$); sub setup_sigchld_handler($); sub sigchld_handler(); sub update_browser_state($$); @@ -390,6 +392,33 @@ sub directory_up_button_clicked_cb($$) # ############################################################################## # +# Routine - search_text_button_clicked_cb +# +# Description - Callback routine called when the user clicks on the search +# text button in a main browser window. +# +# Data - $widget : The widget object that received the signal. +# $browser : The browser instance that is associated with +# this widget. +# +############################################################################## + + + +sub search_text_button_clicked_cb($$) +{ + + my($widget, $browser) = @_; + + return if ($browser->{in_cb}); + local $browser->{in_cb} = 1; + + find_text($browser->{window}, $browser->{file_view_sv}); + +} +# +############################################################################## +# # Routine - annotate_button_clicked_cb # # Description - Callback routine called when the user clicks on the @@ -650,13 +679,16 @@ sub new_browser_instance() $image, $renderer, $tv_column, - $div); + $div, + $window_type); + $window_type = "main_window"; + $browser = {}; - $browser->{type} = "browser_window"; + $browser->{type} = $window_type; $browser->{mtn} = Monotone::AutomateStdio->new(); $browser->{glade} = - Gtk2::GladeXML->new("../mtn-browse.glade", "main_window"); + Gtk2::GladeXML->new("../mtn-browse.glade", $window_type); # Flag to stop recursive calling of callbacks. @@ -672,7 +704,7 @@ sub new_browser_instance() # Get the widgets that we are interested in. - $browser->{window} = $browser->{glade}->get_widget("main_window"); + $browser->{window} = $browser->{glade}->get_widget($window_type); $browser->{window}->set_icon($app_icon); $browser->{appbar} = $browser->{glade}->get_widget("appbar"); $browser->{branch_combo} = @@ -1268,7 +1300,8 @@ sub update_browser_state($$) $mime_type, $scrolled_window); - # Reset the file view buffer. + # Reset the file view buffer and the associated find text + # window. $browser->{file_button_vbox}->set_sensitive(TRUE); foreach my $widget (@{$browser->{text_file_sensitive_group}}) @@ -1277,6 +1310,8 @@ sub update_browser_state($$) } $browser->{file_view_svbuffer}->set_text(""); $browser->{file_view_svbuffer}->set("highlight", FALSE); + reset_find_text($browser->{file_view_sv}); + disable_find_text($browser->{file_view_sv}, 1); # Get contents. @@ -1349,6 +1384,11 @@ sub update_browser_state($$) if ($mime_type =~ m/^text\/.+$/o || $ok_to_render) { + + my $iter; + + # Display text file with possible syntax highlighting. + if (defined($lang = $browser->{file_view_svlangmgr}-> get_language_from_mime_type($mime_type))) { @@ -1358,21 +1398,40 @@ sub update_browser_state($$) set_language($lang); } - # Load in the contents. + # Load in the contents and then delete the trailing + # newline. $browser->{file_view_svbuffer}->set_text($contents); + $iter = $browser->{file_view_svbuffer}->get_end_iter(); + $browser->{file_view_svbuffer}->delete + ($iter, + $browser->{file_view_svbuffer}->get_end_iter()) + if ($iter->backward_char()); + + # Enable the file buttons applicable to text files. + foreach my $widget (@{$browser->{text_file_sensitive_group}}) { $widget->set_sensitive(TRUE); } + + # Enable any associated find text window that may be + # displayed. + + disable_find_text($browser->{file_view_sv}, 0); + } else { + + # Display mime type for undisplayable file contents. + $browser->{file_view_svbuffer}-> set("highlight", FALSE); $browser->{file_view_svbuffer}-> set_text("<" . $mime_type . ">\n"); + } } @@ -1427,7 +1486,7 @@ sub update_browser_state($$) else { - # Reset the file view buffer. + # Reset the file view buffer and the associated find text window. $browser->{file_button_vbox}->set_sensitive(FALSE); $browser->{file_view_svbuffer}->set_text(""); @@ -1436,6 +1495,7 @@ sub update_browser_state($$) set_label_value($browser->{file_id_label}, ""); set_label_value($browser->{last_update_label}, ""); set_label_value($browser->{file_revision_id_label}, ""); + disable_find_text($browser->{file_view_sv}, 1); } ============================================================ --- mtn-browse.glade 79138c09ac145c8365a8a8de09c67f80b4b834e3 +++ mtn-browse.glade 1a0bdb6e5042b92e99f3a088eae3a3e2bc4a7eaa @@ -882,7 +882,7 @@ criteria for selecting a revisionName of the file being displayed 1 1 - 0 0 127 10 114.3 127 + 0 0 130 10 117 130 0 0 17 10 15.3 17 @@ -944,7 +944,7 @@ criteria for selecting a revisionDate of when file was last changed 1 1 - 0 0 127 10 114.3 127 + 0 0 130 10 117 130 0 0 17 10 15.3 17 @@ -1035,7 +1035,7 @@ updated with respect to this revision

True - Last Update: + Last update: False False GTK_JUSTIFY_LEFT @@ -1089,7 +1089,7 @@ updated with respect to this revision

File's unique id in database 1 1 - 0 0 133 10 119.7 133 + 0 0 134 10 120.6 134 0 0 17 10 15.3 17 @@ -1152,7 +1152,7 @@ file was last changed file was last changed 1 1 - 0 0 133 10 119.7 133 + 0 0 134 10 120.6 134 0 0 17 10 15.3 17 @@ -1209,7 +1209,7 @@ file was last changed True - File Id: + File id: False False GTK_JUSTIFY_LEFT @@ -1243,7 +1243,7 @@ last updated with respect to this revisi True - Revision Id: + Revision id: False False GTK_JUSTIFY_LEFT @@ -1319,6 +1319,7 @@ last updated with respect to this revisi True GTK_RELIEF_NORMAL True + @@ -1753,7 +1754,7 @@ into a viewer True 1 1 - 0 0 282 10 253.8 282 + 0 0 286 10 257.4 286 0 0 17 10 15.3 17 @@ -1814,7 +1815,7 @@ into a viewer True 1 1 - 0 0 282 10 253.8 282 + 0 0 286 10 257.4 286 0 0 17 10 15.3 17 @@ -1871,7 +1872,7 @@ into a viewer True - Revision Id: + Revision id: False False GTK_JUSTIFY_LEFT @@ -1904,7 +1905,7 @@ into a viewer True - Change Log: + Change log: False False GTK_JUSTIFY_LEFT @@ -2047,7 +2048,7 @@ select the branch and revision from drop Select Simple Query you you just want to manually select the branch and revision from drop down lists True - Simple Query + Simple query True GTK_RELIEF_NORMAL True @@ -2069,7 +2070,7 @@ specify very specific selection critiaSelect Advanced Query if you want to specify very specific selection critia True - Advanced Query + Advanced query True GTK_RELIEF_NORMAL True @@ -2358,7 +2359,7 @@ entry field if you cannot remember the s True - Search Term: + Search term: False False GTK_JUSTIFY_LEFT @@ -2917,7 +2918,7 @@ Tag True - Revision Id: + Revision id: False False GTK_JUSTIFY_LEFT @@ -2951,7 +2952,7 @@ Tag True 1 1 - 0 0 286 10 257.4 286 + 0 0 287 10 258.3 287 0 0 17 10 15.3 17 @@ -3355,7 +3356,7 @@ Tag True 1 1 - 0 0 356 10 320.4 356 + 0 0 336 10 302.4 336 0 0 17 10 15.3 17 @@ -3412,7 +3413,7 @@ Tag True - Number Of Revisions: + Number of revisions: False False GTK_JUSTIFY_LEFT @@ -3448,20 +3449,10 @@ Tag False Stop gathering history details True + gtk-stop + True GTK_RELIEF_NORMAL True - - - - True - gtk-stop - 4 - 0.5 - 0.5 - 0 - 0 - - 0 @@ -3556,7 +3547,7 @@ Tag True 1 1 - 0 0 368 10 331.2 368 + 0 0 375 10 337.5 375 0 0 17 10 15.3 17 @@ -3618,7 +3609,7 @@ Tag True 1 1 - 0 0 368 10 331.2 368 + 0 0 375 10 337.5 375 0 0 17 10 15.3 17 @@ -3677,7 +3668,7 @@ file version that is to be compared True - First Revision Id: + First revision id: False False GTK_JUSTIFY_LEFT @@ -3711,7 +3702,7 @@ file version that is to be compared True - Second Revision Id: + Second revision id: False False GTK_JUSTIFY_LEFT @@ -3907,7 +3898,7 @@ file version that is to be compared True - Jump To File: + Jump to file: False False GTK_JUSTIFY_LEFT @@ -4217,4 +4208,193 @@ that had the green highlighted text + + Find Text + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_CENTER_ON_PARENT + False + False + False + True + True + False + GDK_WINDOW_TYPE_HINT_DIALOG + GDK_GRAVITY_NORTH_WEST + True + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_END + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + -7 + + + + + + True + True + True + gtk-find + True + GTK_RELIEF_NORMAL + True + 0 + + + + + + 0 + False + True + GTK_PACK_END + + + + + + 5 + True + False + 5 + + + + True + False + 5 + + + + True + Enter the text that is +to be searched for + True + False + + + + True + Search for: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + + + 0 + False + True + + + + + + 300 + True + + + + 0 + True + True + + + + + 0 + False + True + + + + + + True + False + 5 + + + + True + Choose whether searches are +to be case sensitive or not + True + Case sensitive + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + Select the direction +of the search + True + Search backwards + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + 0 + False + True + + + + + 0 + True + True + + + + + +