12.8. Example: The use of Gtk2::TextMarks

Objective

When text changed in a Gtk2::TextBuffer, we usually want to do something with the new text. This lesson will show you how to get the new text.

This example will take the previous one, and enhance it. Since this lesson works on a modified version of the previous example, it will only discuss enhancements. The program can be found here: 'Gtk2::TextMark Demo'

Adding a Gtk2::TextMark

In our program, we add a Gtk2::TextMark by using the Gtk2::TextBuffer's create_mark method. This will give a name to the created Gtk2::TextMark, which we can then later use when retrieving text from the Gtk2::TextBuffer.

#insert a textmark
$buffer->create_mark ($answer_text_start, $iter, TRUE);  

A typical "SAVE" button

We add a "SAVE" button to click when we want to get the new text, but we first disable it. We connect the Gtk2::TextBuffer's changed signal to an anonymous sub that will activate the "SAVE" button when text in the Gtk2::TextBuffer change.

The clicked method of the "SAVE" button is connected to an anonymous sub, which will extract the text and disable the button again.

Note

To "enable" and "disable" a widget, we use the Gtk2::Widget's set_sensitive method. This will determine if the widget can recieve input from the user, or not.

#add a "save" button
	my $btn_save = Gtk2::Button->new_from_stock('gtk-save');
	#gray it out
	$btn_save->set_sensitive(FALSE);

		#Once the button is created, we can connect the buffer's
		#"changed" signal to an anonymous sub that will activate the button
		$buffer->signal_connect("changed" =>sub {

			$btn_save->set_sensitive(TRUE);
		});


	#we connect the save button to an anonymous sub that will pop up
	#a message and, when the message is clicked, gray out the button again
	$btn_save->signal_connect('clicked' => sub { 
	
		my $text_current = &ret_between_marks($buffer,$answer_text_start,$answer_text_end);
		#print ("$text_current\n");
		&show_message_dialog('info',$text_current,'ok');
		$btn_save->set_sensitive(FALSE);
	});

Extracting text between two Gtk2::TextMarks.

This request may occur a few times. When something repeats itself, we should resort to a sub. In our program we call a sub, with the Gtk2::TextBuffer, start and end Gtk2::TextMarks as arguments. The sub will then return the text between the Gtk2::TextMarks.

To get the text, we first have to get the Gtk2::TextIters at the Gtk2::TextMarks. Once we have the two Gtk2::TextIters, we can use the get_slice method of the Gtk2::TextBuffer.

sub ret_between_marks {
  	#this sub takes a buffer, and the names of two marks, it 
	#then returns the text between them
	my ($buffer,$mrk_a,$mrk_b) = @_;
	
	my $tm_a = $buffer->get_mark ($mrk_a); 
	my $tm_b = $buffer->get_mark ($mrk_b);
	
	my $ti_one = $buffer->get_iter_at_mark ($tm_a);
	my $ti_two = $buffer->get_iter_at_mark ($tm_b);
	
	my $string = $buffer->get_slice ($ti_one, $ti_two, 1);
	chomp($string);
	#print("$string\n");
	return $string;

}

Displaying the text.

For this we use a standard Gtk2::MessageDialog. To refresh on its usage, you can go here:(see Chapter 8)