Problem
You want to allow users to insert links in a GtkTextView. The user will highlight some text and press the "Insert Link" button. A popup dialog box will appear where the user enters the URL address. On pressing return, the URL address will be registered, and the link highlighted in the standard blue underlined text as shown below:
Solution
- We use the same technique as outlined in the article How to highlight matching html tags in GtkTextView?
- Instead of highlighting the selected text in yellow background, we highlight the text in the standard style for links, i.e. as blue underlined text.
- Load the image with GtkImage::new_from_file.
- We use an array to keep track of the corresponding tag and link.
Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 20 24 25 26 27 28 29 30 31 32 33 34 35 45 46 47 48 49 50 51 52 53 54 55 62 64 65 66 67 68 69 70 71 72 74 75 76 77 78 79 81 88 89 90 92 93 94 96 97 98 99 100 101 102 103 104 106 107 109 110 111 112 113 114 115 116 117 119 123 124 125 126 128 129 130 131 132 134 135 136 137 138 139 140 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | <?php $window = new GtkWindow(); $window->set_size_request(400, 240); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel("Insert Links in GtkTextView - Part 1\n". "Highlight some text and press the \"Insert Link\" button.\n". "You will be prompted to enter the URL address."); $title->modify_font(new PangoFontDescription("Times New Roman Italic 10")); $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff")); $title->set_size_request(-1, 60); $title->set_justify(Gtk::JUSTIFY_CENTER); $alignment = new GtkAlignment(0.5, 0.5, 0, 0); $alignment->add($title); $vbox->pack_start($alignment); // Setup TextView $tag_count = 0; $buffer = new GtkTextBuffer(); $buffer->set_text('PHP-GTK2 resources: 1) manual: http://gtk.php.net/manual/en/gtkclasses.php 2) mailing list: http://www.nabble.com/Php---GTK---General-f171.html '); $view = new GtkTextView(); $view->set_buffer($buffer); $view->modify_font(new PangoFontDescription("Arial 10")); $view->set_wrap_mode(Gtk::WRAP_WORD); $hbox = new GtkHBox(); $hbox->pack_start($button = new GtkButton('Insert Link'), 0); $vbox->pack_start($hbox, 0); $button->connect('clicked', 'on_button', $buffer); // note 1 $scrolled_win = new GtkScrolledWindow(); $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $vbox->pack_start($scrolled_win); $scrolled_win->add($view); // Setup highlight tag $window->show_all(); Gtk::main(); class LinkTag extends GtkTextTag { // note 2 function __construct($link) { global $buffer; parent::__construct(); $this->set_property('foreground', "#0000ff"); $this->set_property('underline', Pango::UNDERLINE_SINGLE); $tag_table = $buffer->get_tag_table(); $tag_table->add($this); } } function on_button($button, $buffer) { global $view, $tag, $url, $tag_count; list($start, $end) = $buffer->get_selection_bounds(); // note 3 if ($start==null || $end==null) return; // no selection $url[$tag_count] = prompt("Enter URL:"); // note 4 $tag[$tag_count] = new LinkTag($url[$tag_count]); // note 5 $buffer->apply_tag($tag[$tag_count], $start, $end); // note 5 ++$tag_count; $buffer->place_cursor($end); $view->grab_focus(); } //function to prompt for user data function prompt($str) { // note 6 $prompt = new Prompt($str); $input = $prompt->entry->get_text(); return $input; } class Prompt{ var $entry; // the user input function Prompt($str) { $dialog = new GtkDialog('Prompt', null, Gtk::DIALOG_MODAL); $top_area = $dialog->vbox; $top_area->pack_start($hbox = new GtkHBox()); $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_QUESTION, Gtk::ICON_SIZE_DIALOG); $hbox->pack_start($stock, 0, 0); $hbox->pack_start(new GtkLabel($str)); $this->entry = new GtkEntry(); $hbox->pack_start($this->entry, 0, 0); $hbox->pack_start(new GtkLabel(' '), 0, 0); $dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK); $buttons = $dialog->action_area->get_children(); $button_ok = $buttons[0]; // get the ID of the OK button // simulate button click when user press enter $this->entry->connect('activate', array(&$this, 'on_enter'), $button_ok); $dialog->set_has_separator(false); $dialog->show_all(); $dialog->run(); $dialog->destroy(); } // simulate button click when user press enter function on_enter($entry, $button) { $button->clicked(); } } ?> |
Output
As shown above.Explanation
- Set up the "Insert Link" button.
- Extends GtkTextTag to form a new class LinkTag to display the link as blue underlined text.
- Get the current selection.
- Use a popup dialog box to get the URL address from user.
- Create a new tag and apply it.
- Pleaes refer to How to display a popup dialog to prompt for data? for detailed explanation of function
prompt()
.
Note
In this article, we have displayed the link.
In the next article, we will show you how to launch the link in the default browser when the user clicks on the link in the textview.
Related Links
- How to insert links in GtkTextView - Part 2 - Activate Link?
- How to insert links in GtkTextView - Part 3 - Display Link in Status Bar?
- How to insert links in GtkTextView - Part 4 - Change Cursor over Link?
- How to insert links in GtkTextView - Part 5 - Display Tooltip over Link?
- How to insert links in GtkTextView - Part 6 - Display Context Sensitive Menu?
- How to insert links in GtkTextView - Part 7 - Delete Link?
Read more...