[Terminal] Add URL matching support
authorIra W. Snyder <devel@irasnyder.com>
Tue, 15 Jan 2008 03:53:40 +0000 (19:53 -0800)
committerIra W. Snyder <devel@irasnyder.com>
Tue, 15 Jan 2008 03:53:40 +0000 (19:53 -0800)
This adds the excellent URL matching support, mostly copied from the old
tilda_terminal.c.

tilda-terminal.c

index 78a91bf..0accb98 100644 (file)
@@ -7,6 +7,10 @@
 #define _(X) X
 #define N_(X) X
 
+#define DINGUS1 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?"
+#define DINGUS2 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"]"
+
+
 static void
 tilda_terminal_dbus_register_object (TildaTerminal *tt)
 {
@@ -175,6 +179,76 @@ tilda_terminal_window_title_changed_cb (GtkWidget *widget, gpointer data)
        g_free (new_title);
 }
 
+/**
+ * Gets called whenever there is a button-press event in the VteTerminal. It
+ * is used to open the user's web browser, for example.
+ */
+static gint
+tilda_terminal_button_press_cb (GtkWidget      *widget,
+                                                               GdkEventButton *event,
+                                                               gpointer        data)
+{
+       GError *error = NULL;
+       TildaTerminal *self = TILDA_TERMINAL(data);
+       VteTerminal *terminal = VTE_TERMINAL(self->vte_term);
+       gint tag, xpad, ypad;
+       gchar *match, *cmd, *web_browser_cmd;
+       gboolean ret = FALSE;
+
+       switch (event->button)
+       {
+               case 3: /* Right Click */
+                       // FIXME: need to add this
+                       //popup_menu (tt->tw, tt);
+                       g_print ("FIXME: popup_menu() here\n");
+                       break;
+
+               case 2: /* Middle Click */
+                       break;
+
+               case 1: /* Left Click */
+                       vte_terminal_get_padding (terminal, &xpad, &ypad);
+                       match = vte_terminal_match_check (terminal,
+                                       (event->x - ypad) / terminal->char_width,
+                                       (event->y - ypad) / terminal->char_height,
+                                       &tag);
+
+                       /* Check if we can launch a web browser, and do so if possible */
+                       if ((event->state & GDK_CONTROL_MASK) && match != NULL)
+                       {
+#if DEBUG
+                               g_print ("Got a Ctrl+Left Click -- Matched: `%s' (%d)\n", match, tag);
+#endif
+                               web_browser_cmd = g_strescape (self->web_browser, NULL);
+                               cmd = g_strdup_printf ("%s %s", web_browser_cmd, match);
+#if DEBUG
+                               g_print ("Launching command: `%s'\n", cmd);
+#endif
+                               ret = g_spawn_command_line_async(cmd, &error);
+
+                               /* Check that the command launched */
+                               if (!ret)
+                               {
+                                       g_printerr (_("Failed to launch web browser command: `%s'\n"), cmd);
+                                       g_printerr (_("Error message: %s\n"), error->message);
+                               }
+
+                               /* Free allocated memory */
+                               g_free (web_browser_cmd);
+                               g_free (cmd);
+                       }
+
+                       /* Always free match if it is non NULL */
+                       g_free (match);
+                       break;
+
+               default:
+                       break;
+       }
+
+       return FALSE;
+}
+
 /**
  * Set the given TildaTerminal to the appropriate transparency level
  * based on the self->transparency_percent member. */
@@ -552,6 +626,7 @@ tilda_terminal_constructor (GType                  type,
 {
        GObject *obj;
        TildaTerminal *self;
+       gint ret;
 
        /* Invoke parent constructor */
        TildaTerminalClass *klass;
@@ -571,6 +646,11 @@ tilda_terminal_constructor (GType                  type,
        gtk_box_pack_end (GTK_BOX(self->hbox), self->vte_term, TRUE, TRUE, 0);
        gtk_widget_show (self->scrollbar);
 
+       /* Match URL's, etc */
+       ret = vte_terminal_match_add (VTE_TERMINAL(self->vte_term), DINGUS1);
+       vte_terminal_match_set_cursor_type (VTE_TERMINAL(self->vte_term), ret, GDK_HAND2);
+       ret = vte_terminal_match_add(VTE_TERMINAL(self->vte_term), DINGUS2);
+       vte_terminal_match_set_cursor_type (VTE_TERMINAL(self->vte_term), ret, GDK_HAND2);
 
        /* Connect Signals */
        g_signal_connect (G_OBJECT(self->vte_term), "child-exited",
@@ -579,6 +659,8 @@ tilda_terminal_constructor (GType                  type,
                                          G_CALLBACK(tilda_terminal_child_exited_cb), self);
        g_signal_connect (G_OBJECT(self->vte_term), "window-title-changed",
                                          G_CALLBACK(tilda_terminal_window_title_changed_cb), self);
+       g_signal_connect (G_OBJECT(self->vte_term), "button-press-event",
+                                         G_CALLBACK(tilda_terminal_button_press_cb), self);
 
        tilda_terminal_start_shell (self);
        tilda_terminal_dbus_register_object (self);