ruby-****@sourc*****
ruby-****@sourc*****
2012年 9月 6日 (木) 09:16:46 JST
------------------------- REMOTE_ADDR = 70.49.49.99 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-txtw-itrsmrks ------------------------- @@ -185,6 +185,93 @@ * Gtk::TextBuffer#insert_range_interactive(iter, start, end, default_editable) +=== Revised and more complete example dealing with marks and iterators + +Now that we have learned the basics, let us look at the revised "iterators.rb" example, which in addition to simple insertions at a single selected location, also deals correctly with some arbitrarily selected text. That is, you can highlight a block of consecutive characters and replace them with the text from entry field when clicking "Insert" button. The solution with buttons is not the proper way to implement this feature (more appropriate would be the use of some kind of context menu), however, the mechanics of replacing selected text using of text buffer marks and iters would be identical. + +I have also included two simple debugging code segments, to additionally expose the use of Gtk::TextIter and Gtk::TextMark objects. You may have noticed that it is very easy to obtain or convert a mark to an iter with Gtk::TextBuffer#get_iter_at_mark(mark), and that there is no equivalent feature to convert an iter to mark, though you can always create a a new mark from an existing iter with Gtk::TextBuffer#create_mark(mark_name, iter, left_gravity). The debug sections also show you how the values of iterators change when you delete or insert text by printing byte offset boundaries for the selection in the text buffer, i.e. selection we are replacing with the text entered in the entry widget. + +But more important is the part demonstrating steps taken to replace the highlighted selection in the text buffer, where we first, if the delete the((*selected*))flag is returned by Gtk::TextBuffer#selection_bounds, delete the selection in the text buffer, retrieve now by deletion invalidated iter from the mark, and then use it to insert the string from entry widget. + + +{{br}} +((*Revised iterators.rb*)) + + #!/usr/bin/env ruby + require 'gtk2' + + # Insert the text from the GtkEntry into the GtkTextView. + def insert_text(ent, txtvu) + mark = txtvu.buffer.selection_bound + iter = txtvu.buffer.get_iter_at_mark(mark) + first, last, selected = txtvu.buffer.selection_bounds + # ----DEBUG:1-(s)------------------------------- + puts "first = #{first.offset}" + puts "last = #{last.offset}" + puts "selected=#{selected}" #=> selected = true or false + + mark_j = txtvu.buffer.create_mark("jack", iter, left_gravity=false) + puts "mark_j = #{mark_j.name}" #=> mark_j = jack + puts "mark = #{mark.name}" #=> mark = selection_bound + # ----DEBUG:1-(e)-------------------------------- + if selected + txtvu.buffer.delete(first, last) + iter = txtvu.buffer.get_iter_at_mark(mark) # delete invalidated stored value + # ----DEBUG:2-(s)-------------------------------- + puts "Selection iter after deletion: first = #{first.offset}" + puts "Selection iter after deletion: last = #{last.offset}" + # ----DEBUG:2-(e)-------------------------------- + end + txtvu.buffer.insert(iter, ent.text) + end + + # Retrieve the selected text from the GtkTextView and + # display it to the user. + def retrieve_text(tw) + + start_iter, end_iter, selected = tw.buffer.selection_bounds + if !selected + start_iter, end_iter = tw.buffer.bounds + end + + text = tw.buffer.get_text(start_iter, end_iter) + puts "selected=#{selected}; TEXT=#{text}" + end + + window = Gtk::Window.new("Text Iterators") + window.resizable = true + window.border_width = 10 + window.signal_connect('destroy') { Gtk.main_quit } + window.set_size_request(250, 150) + + textview = Gtk::TextView.new + + entry = Gtk::Entry.new + insert = Gtk::Button.new("Insert Text") + retrieve = Gtk::Button.new("Get Text") + + insert.signal_connect('clicked') { insert_text(entry, textview) } + retrieve.signal_connect('clicked') { retrieve_text(textview) } + + scrolled_win = Gtk::ScrolledWindow.new + scrolled_win.border_width = 5 + scrolled_win.add(textview) + scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS) + + hbox = Gtk::HBox.new(false, 5) + hbox.pack_start_defaults(entry) + hbox.pack_start_defaults(insert) + hbox.pack_start_defaults(retrieve) + vbox = Gtk::VBox.new(false, 5) + vbox.pack_start(scrolled_win, true, true, 0) + vbox.pack_start(hbox, false, true, 0) + window.add(vbox) + window.show_all + Gtk.main + + + + === Cutting, Copying and Pasting When you right-click a Gtk::TextView widget, you are presented with a pop-up menu containing multiple options, of which the tree we are interested in here are Cut, Copy, and Paste. These three options also have assigned to them a set of built-in accelerator keys Ctrl-X, Ctrl+C, and Ctrl-V respectively. In the next example program (cutcopypaste.rb) we will explore these three options: