157. How to insert links in GtkTextView - Part 1 - Show Link?

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:

How to insert links in GtkTextView - Part 1 - Show Link?


Solution


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

  1. Set up the "Insert Link" button.
  2. Extends GtkTextTag to form a new class LinkTag to display the link as blue underlined text.
  3. Get the current selection.
  4. Use a popup dialog box to get the URL address from user.
  5. Create a new tag and apply it.
  6. 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

Add comment


Security code
Refresh