gnome-terminal r2457 - trunk/src



Author: chpe
Date: Wed Mar 19 15:21:28 2008
New Revision: 2457
URL: http://svn.gnome.org/viewvc/gnome-terminal?rev=2457&view=rev

Log:
Make context menu use ui manager too.


Modified:
   trunk/src/terminal-screen.c
   trunk/src/terminal-screen.h
   trunk/src/terminal-window.c
   trunk/src/terminal.c
   trunk/src/terminal.h
   trunk/src/terminal.ui

Modified: trunk/src/terminal-screen.c
==============================================================================
--- trunk/src/terminal-screen.c	(original)
+++ trunk/src/terminal-screen.c	Wed Mar 19 15:21:28 2008
@@ -57,8 +57,6 @@
   char *cooked_title, *cooked_icon_title;
   char *title_from_arg;
   gboolean icon_title_set;
-  char *matched_string;
-  int matched_flavor;
   char **override_command;
   GtkWidget *title_editor;
   GtkWidget *title_entry;
@@ -77,6 +75,7 @@
   ICON_TITLE_CHANGED,
   SELECTION_CHANGED,
   ENCODING_CHANGED,
+  SHOW_POPUP_MENU,
   LAST_SIGNAL
 };
 
@@ -85,12 +84,6 @@
   PROP_TITLE
 };
 
-enum {
-  FLAVOR_AS_IS,
-  FLAVOR_DEFAULT_TO_HTTP,
-  FLAVOR_EMAIL
-};
-
 static void terminal_screen_init        (TerminalScreen      *screen);
 static void terminal_screen_class_init  (TerminalScreenClass *klass);
 static void terminal_screen_dispose     (GObject             *object);
@@ -477,6 +470,17 @@
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  signals[SHOW_POPUP_MENU] =
+    g_signal_new ("show-popup-menu",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (TerminalScreenClass, encoding_changed),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__POINTER,
+                  G_TYPE_NONE,
+                  1,
+                  G_TYPE_POINTER);
+
   g_object_class_install_property (object_class,
                                    PROP_TITLE,
                                    g_param_spec_string ("title", NULL, NULL,
@@ -548,7 +552,6 @@
   g_free (screen->priv->title_from_arg);
   g_free (screen->priv->raw_icon_title);
   g_free (screen->priv->cooked_icon_title);
-  g_free (screen->priv->matched_string);
   g_strfreev (screen->priv->override_command);
   g_free (screen->priv->working_dir);
 
@@ -1332,513 +1335,54 @@
     return FALSE;
 }
 
-static void
-new_window_callback (GtkWidget      *menu_item,
-                     TerminalScreen *screen)
+TerminalScreenPopupInfo *
+terminal_screen_popup_info_new (TerminalScreen *screen)
 {
-  char *name;
-  const char *dir;
+  TerminalScreenPopupInfo *info;
 
-  name = gdk_screen_make_display_name (gtk_widget_get_screen (menu_item));
-  dir = terminal_screen_get_working_dir (screen);
-  
-  terminal_app_new_terminal (terminal_app_get (),
-                             terminal_profile_get_for_new_term (screen->priv->profile),
-                             NULL,
-                             NULL,
-                             FALSE, FALSE, FALSE,
-                             NULL, NULL, NULL, dir, NULL, 1.0,
-                             NULL, name, -1);
-
-  g_free (name);
-}
-
-static void
-new_tab_callback (GtkWidget      *menu_item,
-                  TerminalScreen *screen)
-{
-  const char *dir;
-
-  dir = terminal_screen_get_working_dir (screen);
-
-  terminal_app_new_terminal (terminal_app_get (),
-                             terminal_profile_get_for_new_term (screen->priv->profile),
-                             screen->priv->window,
-                             NULL,
-                             FALSE, FALSE, FALSE,
-                             NULL, NULL, NULL, dir, NULL, 1.0,
-                             NULL, NULL, -1);
-}
-
-static void
-close_tab_callback (GtkWidget      *menuitem,
-                    TerminalScreen *screen)
-{
-  terminal_screen_close (screen);
-}
+  info = g_slice_new0 (TerminalScreenPopupInfo);
+  info->ref_count = 1;
+  info->screen = g_object_ref (screen);
+  info->window = screen->priv->window;
 
-static void
-copy_callback (GtkWidget      *menu_item,
-               TerminalScreen *screen)
-{
-  terminal_widget_copy_clipboard (screen->priv->term);
+  return info;
 }
 
-static void
-paste_callback (GtkWidget      *menu_item,
-                TerminalScreen *screen)
+TerminalScreenPopupInfo *
+terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info)
 {
-  terminal_widget_paste_clipboard (screen->priv->term);
-}
+  g_return_val_if_fail (info != NULL, NULL);
 
-static void
-configuration_callback (GtkWidget      *menu_item,
-                        TerminalScreen *screen)
-{
-  g_return_if_fail (screen->priv->profile);
-  
-  terminal_app_edit_profile (terminal_app_get (),
-                             screen->priv->profile, 
-                             GTK_WINDOW (screen->priv->window));
+  info->ref_count++;
+  return info;
 }
 
-static void
-choose_profile_callback (GtkWidget      *menu_item,
-                         TerminalScreen *screen)
+void
+terminal_screen_popup_info_unref (TerminalScreenPopupInfo *info)
 {
-  TerminalProfile *profile;
+  g_return_if_fail (info != NULL);
 
-  if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item)))
+  if (--info->ref_count > 0)
     return;
-  
-  profile = g_object_get_data (G_OBJECT (menu_item),
-                               "profile");
-
-  g_assert (profile);
-
-  if (!terminal_profile_get_forgotten (profile))
-    {
-      terminal_screen_set_profile (screen, profile);
-    }
-}
-
-static void
-show_menubar_callback (GtkWidget      *menu_item,
-                       TerminalScreen *screen)
-{
-  if (terminal_window_get_menubar_visible (screen->priv->window))
-    terminal_window_set_menubar_visible (screen->priv->window,
-                                         FALSE);
-  else
-    terminal_window_set_menubar_visible (screen->priv->window,
-                                         TRUE);
-}
-
-static void
-open_url (TerminalScreen *screen,
-          const char     *orig_url,
-          int             flavor)
-{
-  GError *err;
-  char *url;
-  
-  g_return_if_fail (orig_url != NULL);
-
-  /* this is to handle gnome_url_show reentrancy */
-  g_object_ref (G_OBJECT (screen));
-  
-  switch (flavor)
-    {
-    case FLAVOR_DEFAULT_TO_HTTP:
-      url = g_strdup_printf ("http:%s", orig_url);
-      break;
-    case FLAVOR_EMAIL:
-      if (strncmp ("mailto:";, orig_url, 7))
-	url = g_strdup_printf ("mailto:%s";, orig_url);
-      else
-	url = g_strdup (orig_url);
-      break;
-    case FLAVOR_AS_IS:
-      url = g_strdup (orig_url);
-      break;
-    default:
-      url = NULL;
-      g_assert_not_reached ();
-    }
-
-  err = NULL;
-  gnome_url_show (url, &err);
-
-  if (err)
-    {
-      GtkWidget *window;
-
-      if (screen->priv->term)
-        window = gtk_widget_get_ancestor (screen->priv->term,
-                                          GTK_TYPE_WINDOW);
-      else
-        window = NULL;
-      
-      terminal_util_show_error_dialog (window ? GTK_WINDOW (window) : NULL, NULL,
-                                       _("Could not open the address \"%s\":\n%s"),
-                                       url, err->message);
-      
-      g_error_free (err);
-    }
-
-  g_free (url);
-  g_object_unref (G_OBJECT (screen));
-}
-
-static void
-open_url_callback (GtkWidget      *menu_item,
-                   TerminalScreen *screen)
-{
-  if (screen->priv->matched_string)
-    {
-      open_url (screen, screen->priv->matched_string, screen->priv->matched_flavor);
-      g_free (screen->priv->matched_string);
-      screen->priv->matched_string = NULL;
-    }
-}
-
-static void
-copy_url_callback (GtkWidget      *menu_item,
-                   TerminalScreen *screen)
-{
-  if (screen->priv->matched_string)
-    {
-      GdkDisplay *display;
-      GtkClipboard *clipboard;
-
-      display = gtk_widget_get_display (GTK_WIDGET (screen->priv->window));
-      clipboard = gtk_clipboard_get_for_display (display, GDK_NONE);
-      gtk_clipboard_set_text (clipboard, screen->priv->matched_string, -1);
-      g_free (screen->priv->matched_string);
-      screen->priv->matched_string = NULL;
-    }
-}
-
-
-static void
-popup_menu_detach (GtkWidget *attach_widget,
-		   GtkMenu   *menu)
-{
-  TerminalScreen *screen;
-
-  screen = g_object_get_data (G_OBJECT (attach_widget), "terminal-screen");
-
-  g_assert (screen);
 
-  screen->priv->popup_menu = NULL;
-}
-
-static GtkWidget*
-append_menuitem (GtkWidget  *menu,
-		 const char *text,
-		 GCallback   callback,
-		 gpointer    data)
-{
-  GtkWidget *menu_item;
-  
-  menu_item = gtk_menu_item_new_with_mnemonic (text);
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                         menu_item);
-
-  g_signal_connect (G_OBJECT (menu_item),
-                    "activate",
-                    callback, data);
-
-  return menu_item;
-}
-
-static GtkWidget*
-append_stock_menuitem (GtkWidget  *menu,
-                       const char *text,
-                       GCallback   callback,
-                       gpointer    data)
-{
-  GtkWidget *menu_item;
-  GtkWidget *image;
-  GConfClient *client;
-  GError *error;
-  gboolean use_image;
-
-  
-  menu_item = gtk_image_menu_item_new_from_stock (text, NULL);
-  image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menu_item));
-
-  client = gconf_client_get_default ();
-  error = NULL;
-
-  use_image = gconf_client_get_bool (client,
-                                     "/desktop/gnome/interface/menus_have_icons",
-                                      &error);
-  if (error)
-    {
-      g_printerr (_("There was an error loading config value for whether to use image in menus. (%s)\n"),error->message);
-      g_error_free (error);
-    }
-  else
-    {
-      if (use_image)
-        gtk_widget_show (image);
-      else
-        gtk_widget_hide (image);
-    }
-
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                         menu_item);
-
-  if (callback)
-    g_signal_connect (G_OBJECT (menu_item),
-                      "activate",
-                      callback, data);
-
-  return menu_item;
-}
-
-static GtkWidget*
-append_check_menuitem (GtkWidget  *menu,
-                       const char *text,
-                       gboolean    active,
-                       GCallback   callback,
-                       gpointer    data)
-{
-  GtkWidget *menu_item;
-  
-  menu_item = gtk_check_menu_item_new_with_mnemonic (text);
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
-  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), active);
-
-  g_signal_connect (G_OBJECT (menu_item), "toggled", callback, data);
-
-  return menu_item;
-}
-
-typedef struct 
-{
-  TerminalScreen *screen;
-  gint button;
-  guint time;
-} PopupInfo;
-
-static void
-popup_clipboard_request_callback (GtkClipboard *clipboard,
-                                  const char   *text,
-                                  gpointer      user_data)
-{
-  PopupInfo *info = user_data;
-  TerminalScreen *screen;
-  GtkWidget *profile_menu;
-  GtkWidget *im_menu;
-  GtkWidget *menu_item;
-  GList *profiles;
-  GList *tmp;
-  GSList *group;
-  gboolean has_tabs;
-  gboolean show_input_method_menu;
-  
-  screen = info->screen;
-
-  if (!GTK_WIDGET_REALIZED (screen->priv->term)) 
-    goto cleanup;
-
-  if (screen->priv->popup_menu)
-    gtk_widget_destroy (screen->priv->popup_menu);
-
-  screen->priv->popup_menu = gtk_menu_new ();
-  gtk_menu_set_accel_group (GTK_MENU (screen->priv->popup_menu),
-                            terminal_accels_get_group_for_widget (screen->priv->popup_menu));
-
-  gtk_menu_attach_to_widget (GTK_MENU (screen->priv->popup_menu),
-                             GTK_WIDGET (screen->priv->term),
-                             popup_menu_detach);
-
-  if (screen->priv->matched_string != NULL) 
-    {
-      if (screen->priv->matched_flavor == FLAVOR_EMAIL &&
-	  strncmp ("mailto:";, screen->priv->matched_string, 7))
-	{
-	  menu_item = append_menuitem (screen->priv->popup_menu,
-				       _("_Send Mail To..."),
-				       G_CALLBACK (open_url_callback),
-				       screen);
-
-	  menu_item = append_menuitem (screen->priv->popup_menu,
-				       _("_Copy E-mail Address"),
-				       G_CALLBACK (copy_url_callback),
-				       screen);
-	}
-      else
-	{
-	  menu_item = append_menuitem (screen->priv->popup_menu,
-				       _("_Open Link"),
-				       G_CALLBACK (open_url_callback),
-				       screen);
-
-	  menu_item = append_menuitem (screen->priv->popup_menu,
-				       _("_Copy Link Address"),
-				       G_CALLBACK (copy_url_callback),
-				       screen);
-	}
-      menu_item = gtk_separator_menu_item_new ();
-      gtk_widget_show (menu_item);
-      gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu),
-			     menu_item);
-    }
-
-  menu_item = append_menuitem (screen->priv->popup_menu,
-                               _("Open _Terminal"),
-                               G_CALLBACK (new_window_callback),
-                               screen);
-
-  menu_item = append_menuitem (screen->priv->popup_menu,
-                               _("Open Ta_b"),
-                               G_CALLBACK (new_tab_callback),
-                               screen);
-
-  menu_item = gtk_separator_menu_item_new ();
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-
-  has_tabs = terminal_window_get_screen_count (terminal_screen_get_window (screen)) > 1;
-  menu_item = append_menuitem (screen->priv->popup_menu,
-                               has_tabs ? _("C_lose Tab") : _("C_lose Window"),
-                               has_tabs ? G_CALLBACK (close_tab_callback) : G_CALLBACK (close_tab_callback),
-                               screen);
-
-  menu_item = gtk_separator_menu_item_new ();
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-
-  menu_item = append_stock_menuitem (screen->priv->popup_menu,
-                                     GTK_STOCK_COPY,
-                                     G_CALLBACK (copy_callback),
-                                     screen);
-  gtk_widget_set_sensitive (menu_item, terminal_screen_get_text_selected (screen));
-
-  menu_item = append_stock_menuitem (screen->priv->popup_menu,
-                                     GTK_STOCK_PASTE,
-                                     G_CALLBACK (paste_callback),
-                                     screen);
-  gtk_widget_set_sensitive (menu_item, text != NULL);
-  
-  menu_item = gtk_separator_menu_item_new ();
-  gtk_widget_show (menu_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-
-  profile_menu = gtk_menu_new ();
-  menu_item = gtk_menu_item_new_with_mnemonic (_("Change P_rofile"));
-
-  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), profile_menu);
-
-  gtk_widget_show (profile_menu);
-  gtk_widget_show (menu_item);
-  
-  gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-
-  group = NULL;
-  profiles = terminal_profile_get_list ();
-  for (tmp = profiles; tmp != NULL; tmp = tmp->next)
-    {
-      TerminalProfile *profile;
-      
-      profile = tmp->data;
-      
-      /* Profiles can go away while the menu is up. */
-      g_object_ref (G_OBJECT (profile));
-
-      menu_item = gtk_radio_menu_item_new_with_label (group, terminal_profile_get_visible_name (profile));
-      group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
-      gtk_widget_show (menu_item);
-      gtk_menu_shell_append (GTK_MENU_SHELL (profile_menu), menu_item);
-
-      if (profile == screen->priv->profile)
-        {
-          gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
-        }
-      
-      g_signal_connect (G_OBJECT (menu_item), "toggled", G_CALLBACK (choose_profile_callback), screen);
-      g_object_set_data_full (G_OBJECT (menu_item), "profile", profile, (GDestroyNotify) g_object_unref);
-    }
-  g_list_free (profiles);
-
-  append_menuitem (screen->priv->popup_menu,
-		   _("_Edit Current Profile..."),
-		   G_CALLBACK (configuration_callback),
-		   screen);
-
-  menu_item = append_check_menuitem (screen->priv->popup_menu, 
-                                     _("Show _Menubar"), 
-                                     terminal_window_get_menubar_visible (screen->priv->window),
-                                     G_CALLBACK (show_menubar_callback),
-                                     screen);
- 
-  g_object_get (gtk_widget_get_settings (GTK_WIDGET (screen->priv->term)),
-                "gtk-show-input-method-menu", &show_input_method_menu,
-                NULL);
-
-  if (show_input_method_menu)
-    {
-      menu_item = gtk_separator_menu_item_new ();
-      gtk_widget_show (menu_item);
-      gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-
-      im_menu = gtk_menu_new ();
-      menu_item = gtk_menu_item_new_with_mnemonic (_("_Input Methods"));
-      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), im_menu);
-      terminal_widget_im_append_menuitems (screen->priv->term, GTK_MENU_SHELL (im_menu));
-      gtk_widget_show (im_menu);
-      gtk_widget_show (menu_item);
-      gtk_menu_shell_append (GTK_MENU_SHELL (screen->priv->popup_menu), menu_item);
-    }
-
-  gtk_menu_popup (GTK_MENU (screen->priv->popup_menu),
-                  NULL, NULL,
-                  NULL, NULL, 
-                  info->button,
-                  info->time);
-
-cleanup:
-  g_object_unref (G_OBJECT (info->screen));
-  g_free (info);
-}
-
-static void
-terminal_screen_do_popup (TerminalScreen *screen,
-                          GdkEventButton *event)
-{
-  PopupInfo *info;
-  GtkClipboard *clip;
-
-  info = g_new (PopupInfo, 1);
-
-  info->screen = g_object_ref (screen);
-
-  if (event != NULL)
-    {
-      info->button = event->button;
-      info->time = event->time;
-    }
-  else
-    {
-      info->button = 0;
-      info->time = gtk_get_current_event_time ();
-    }
-
-  clip = gtk_clipboard_get (GDK_NONE);
-  gtk_clipboard_request_text (clip, popup_clipboard_request_callback, info);
+  g_object_unref (info->screen);
+  g_free (info->string);
+  g_slice_free (TerminalScreenPopupInfo, info);
 }
 
 static gboolean
 terminal_screen_popup_menu (GtkWidget      *term,
                             TerminalScreen *screen)
 {
-  terminal_screen_do_popup (screen, NULL);
+  TerminalScreenPopupInfo *info;
+
+  info = terminal_screen_popup_info_new (screen);
+  info->button = 0;
+  info->timestamp = gtk_get_current_event_time ();
+
+  g_signal_emit (screen, signals[SHOW_POPUP_MENU], 0, info);
+  terminal_screen_popup_info_unref (info);
+
   return TRUE;
 }
 
@@ -1850,21 +1394,25 @@
   GtkWidget *term;
   int char_width, char_height;
   gboolean dingus_button;
-  
+  char *matched_string;
+  int matched_flavor;
+  guint state;
+
+  state = event->state & gtk_accelerator_get_default_mod_mask ();
+
   term = screen->priv->term;
 
   terminal_widget_get_cell_size (term, &char_width, &char_height);
-  
-  g_free (screen->priv->matched_string);
-  screen->priv->matched_string =
+
+  matched_string =
     terminal_widget_check_match (term,
                                  event->x / char_width,
                                  event->y / char_height,
-                                 &screen->priv->matched_flavor);
+                                 &matched_flavor);
   dingus_button = ((event->button == 1) || (event->button == 2));
 
   if (dingus_button &&
-      (event->state & GDK_CONTROL_MASK) &&
+      (state & GDK_CONTROL_MASK) &&
       terminal_profile_get_use_skey (screen->priv->profile))
     {
       gchar *skey_match;
@@ -1877,27 +1425,38 @@
 	{
 	  terminal_skey_do_popup (screen, GTK_WINDOW (terminal_screen_get_window (screen)), skey_match);
 	  g_free (skey_match);
+          g_free (matched_string);
 
 	  return TRUE;
 	}
     }
 
   if (dingus_button &&
-      (event->state & GDK_CONTROL_MASK) &&
-      (screen->priv->matched_string != NULL))
+      (state & GDK_CONTROL_MASK) != 0 &&
+      matched_string != NULL)
     {
       gtk_widget_grab_focus (widget);
       
-      open_url (screen, screen->priv->matched_string, screen->priv->matched_flavor);
-      g_free (screen->priv->matched_string);
-      screen->priv->matched_string = NULL;
+      terminal_util_open_url (GTK_WIDGET (screen->priv->window), matched_string, matched_flavor);
+      g_free (matched_string);
+
       return TRUE; /* don't do anything else such as select with the click */
     }
       
-  if ((event->button == 3) &&
-      !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)))
+  if (event->button == 3 &&
+      (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0)
     {
-      terminal_screen_do_popup (screen, event);
+      TerminalScreenPopupInfo *info;
+
+      info = terminal_screen_popup_info_new (screen);
+      info->button = event->button;
+      info->timestamp = event->time;
+      info->string = matched_string; /* adopted */
+      info->flavour = matched_flavor;
+
+      g_signal_emit (screen, signals[SHOW_POPUP_MENU], 0, info);
+      terminal_screen_popup_info_unref (info);
+
       return TRUE;
     }
 

Modified: trunk/src/terminal-screen.h
==============================================================================
--- trunk/src/terminal-screen.h	(original)
+++ trunk/src/terminal-screen.h	Wed Mar 19 15:21:28 2008
@@ -29,6 +29,7 @@
 G_BEGIN_DECLS
 
 /* Forward decls */
+typedef struct _TerminalScreenPopupInfo TerminalScreenPopupInfo;
 typedef struct _TerminalWindow        TerminalWindow;
 
 #define TERMINAL_TYPE_SCREEN              (terminal_screen_get_type ())
@@ -57,6 +58,8 @@
   void (* icon_title_changed) (TerminalScreen *screen);
   void (* selection_changed)  (TerminalScreen *screen);
   void (* encoding_changed)   (TerminalScreen *screen);
+  void (* show_popup_menu)    (TerminalScreen *screen,
+                               TerminalScreenPopupInfo *info);
 };
 
 GType terminal_screen_get_type (void) G_GNUC_CONST;
@@ -129,6 +132,22 @@
 #define TERMINAL_SCALE_MINIMUM     (TERMINAL_SCALE_XXXXX_SMALL/1.2)
 #define TERMINAL_SCALE_MAXIMUM     (TERMINAL_SCALE_XXXXX_LARGE*1.2)
 
+#include "terminal.h"
+
+struct _TerminalScreenPopupInfo {
+  int ref_count;
+  TerminalWindow *window;
+  TerminalScreen *screen;
+  char *string;
+  TerminalURLFlavour flavour;
+  guint button;
+  guint32 timestamp;
+};
+
+TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo *info);
+
+void terminal_screen_popup_info_unref (TerminalScreenPopupInfo *info);
+
 G_END_DECLS
 
 #endif /* TERMINAL_SCREEN_H */

Modified: trunk/src/terminal-window.c
==============================================================================
--- trunk/src/terminal-window.c	(original)
+++ trunk/src/terminal-window.c	Wed Mar 19 15:21:28 2008
@@ -56,6 +56,9 @@
 
   TerminalTabsMenu *tabs_menu;
 
+  TerminalScreenPopupInfo *popup_info;
+  guint remove_popup_info_idle;
+
   GtkWidget *menubar;
   GtkWidget *notebook;
   guint terms;
@@ -268,6 +271,7 @@
 }
 
 #define PROFILES_UI_PATH "/menubar/Terminal/TerminalProfiles"
+#define PROFILES_POPUP_UI_PATH "/Popup/TerminalProfiles"
 
 static void
 terminal_window_update_set_profile_menu (TerminalWindow *window)
@@ -350,6 +354,10 @@
                              PROFILES_UI_PATH,
                              name, name,
                              GTK_UI_MANAGER_MENUITEM, FALSE);
+      gtk_ui_manager_add_ui (priv->ui_manager, priv->profiles_ui_id,
+                             PROFILES_POPUP_UI_PATH,
+                             name, name,
+                             GTK_UI_MANAGER_MENUITEM, FALSE);
     }
 
   g_list_free (profiles);
@@ -750,6 +758,225 @@
   g_signal_handlers_disconnect_by_func (window, terminal_window_realized_callback, NULL);
 }
 
+/* Terminal screen popup menu handling */
+
+static void
+popup_open_url_callback (GtkAction *action,
+                         TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+  TerminalScreenPopupInfo *info = priv->popup_info;
+
+  if (info == NULL)
+    return;
+
+  terminal_util_open_url (GTK_WIDGET (window), info->string, info->flavour);
+}
+
+static void
+popup_copy_url_callback (GtkAction *action,
+                         TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+  TerminalScreenPopupInfo *info = priv->popup_info;
+  GdkDisplay *display;
+  GtkClipboard *clipboard;
+
+  if (info == NULL)
+    return;
+
+  if (info->string == NULL)
+    return;
+
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_NONE);
+  gtk_clipboard_set_text (clipboard, info->string, -1);
+}
+
+/*static void
+popup_menu_detach (GtkWidget *attach_widget,
+		   GtkMenu   *menu)
+{
+  TerminalScreen *screen;
+
+  screen = g_object_get_data (G_OBJECT (attach_widget), "terminal-screen");
+
+  g_assert (screen);
+
+  screen->priv->popup_menu = NULL;
+}
+*/
+
+static void
+remove_popup_info (TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+
+  if (priv->remove_popup_info_idle != 0)
+    {
+      g_source_remove (priv->remove_popup_info_idle);
+      priv->remove_popup_info_idle = 0;
+    }
+
+  if (priv->popup_info != NULL)
+    {
+      terminal_screen_popup_info_unref (priv->popup_info);
+      priv->popup_info = NULL;
+    }
+}
+
+static gboolean
+idle_remove_popup_info (TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+
+  priv->remove_popup_info_idle = 0;
+  remove_popup_info (window);
+  return FALSE;
+}
+
+static void
+unset_popup_info (TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+
+  /* Unref the event from idle since we still need it
+    * from the action callbacks which will run before idle.
+    */
+  if (priv->remove_popup_info_idle == 0 &&
+      priv->popup_info != NULL)
+    {
+      priv->remove_popup_info_idle =
+        g_idle_add ((GSourceFunc) idle_remove_popup_info, window);
+    }
+}
+
+static void
+popup_menu_deactivate_callback (GtkWidget *popup,
+                                TerminalWindow *window)
+{
+  TerminalWindowPrivate *priv = window->priv;
+  GtkWidget *im_menu_item;
+
+  g_signal_handlers_disconnect_by_func
+    (popup, G_CALLBACK (popup_menu_deactivate_callback), window);
+
+  im_menu_item = gtk_ui_manager_get_widget (priv->ui_manager,
+                                            "/Popup/PopupInputMethods");
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), NULL);
+
+  unset_popup_info (window);
+}
+
+static void
+popup_clipboard_request_callback (GtkClipboard *clipboard,
+                                  const char   *text,
+                                  gpointer      user_data)
+{
+  TerminalScreenPopupInfo *info = user_data;
+  TerminalWindow *window = info->window;
+  TerminalWindowPrivate *priv = window->priv;
+  TerminalScreen *screen = info->screen;
+  GtkWidget *popup_menu, *im_menu, *im_menu_item;
+  GtkAction *action;
+  gboolean show_link, show_email_link, show_input_method_menu;
+  
+  remove_popup_info (window);
+
+  if (!GTK_WIDGET_REALIZED (terminal_screen_get_widget (info->screen)))
+    {
+      terminal_screen_popup_info_unref (info);
+      return;
+    }
+
+  priv->popup_info = info; /* adopt the ref added when requesting the clipboard */
+
+  show_link = info->string != NULL && info->flavour != FLAVOR_EMAIL;
+  show_email_link = info->string != NULL && info->flavour == FLAVOR_EMAIL;
+
+  action = gtk_action_group_get_action (priv->action_group, "PopupSendEmail");
+  gtk_action_set_visible (action, show_email_link);
+  action = gtk_action_group_get_action (priv->action_group, "PopupCopyEmailAddress");
+  gtk_action_set_visible (action, show_email_link);
+  action = gtk_action_group_get_action (priv->action_group, "PopupOpenLink");
+  gtk_action_set_visible (action, show_link);
+  action = gtk_action_group_get_action (priv->action_group, "PopupCopyLinkAddress");
+  gtk_action_set_visible (action, show_link);
+
+  action = gtk_action_group_get_action (priv->action_group, "PopupCloseWindow");
+  gtk_action_set_visible (action, priv->terms <= 1);
+  action = gtk_action_group_get_action (priv->action_group, "PopupCloseTab");
+  gtk_action_set_visible (action, priv->terms > 1);
+
+  action = gtk_action_group_get_action (priv->action_group, "PopupCopy");
+  gtk_action_set_sensitive (action, terminal_screen_get_text_selected (screen));
+  action = gtk_action_group_get_action (priv->action_group, "PopupPaste");
+  gtk_action_set_sensitive (action, text != NULL);
+  
+//   profile_menu = gtk_menu_new ();
+//   menu_item = gtk_menu_item_new_with_mnemonic (_("Change P_rofile"));
+// 
+//   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), profile_menu);
+
+//   append_menuitem (screen->priv->popup_menu,
+// 		   _("_Edit Current Profile..."),
+// 		   G_CALLBACK (configuration_callback),
+// 		   screen);
+
+  g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
+                "gtk-show-input-method-menu", &show_input_method_menu,
+                NULL);
+
+  action = gtk_action_group_get_action (priv->action_group, "PopupInputMethods");
+  gtk_action_set_visible (action, show_input_method_menu);
+
+  im_menu_item = gtk_ui_manager_get_widget (priv->ui_manager,
+                                            "/Popup/PopupInputMethods");
+  /* FIXME: fix this when gtk+ bug #500065 is done */
+  if (show_input_method_menu)
+    {
+      im_menu = gtk_menu_new ();
+      terminal_widget_im_append_menuitems (terminal_screen_get_widget (screen),
+                                           GTK_MENU_SHELL (im_menu));
+      gtk_widget_show (im_menu);
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), im_menu);
+    }
+  else
+    {
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), NULL);
+    }
+
+  popup_menu = gtk_ui_manager_get_widget (priv->ui_manager, "/Popup");
+  g_signal_connect (popup_menu, "deactivate",
+                    G_CALLBACK (popup_menu_deactivate_callback), window);
+
+  gtk_menu_popup (GTK_MENU (popup_menu),
+                  NULL, NULL,
+                  NULL, NULL, 
+                  info->button,
+                  info->timestamp);
+  /* FIXMEchpe? */
+//   gtk_menu_attach_to_widget (GTK_MENU (screen->priv->popup_menu),
+//                              GTK_WIDGET (screen->priv->term),
+//                              popup_menu_detach);
+}
+
+static void
+screen_show_popup_menu_callback (TerminalScreen *screen,
+                                 TerminalScreenPopupInfo *info,
+                                 TerminalWindow *window)
+{
+  GtkClipboard *clipboard;
+
+  g_return_if_fail (info->window == window);
+
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_NONE /* FIXMEchpe ? */);
+  gtk_clipboard_request_text (clipboard, popup_clipboard_request_callback,
+                              terminal_screen_popup_info_ref (info));
+}
+
+/*****************************************/
+
+
 static gboolean
 terminal_window_state_event (GtkWidget            *widget,
                              GdkEventWindowState  *event)
@@ -925,6 +1152,39 @@
       { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL,
         NULL,
         G_CALLBACK (help_about_callback) },
+
+      /* Popup menu */
+      { "PopupSendEmail", NULL, N_("_Send Mail To..."), NULL,
+        NULL,
+        G_CALLBACK (popup_open_url_callback) },
+      { "PopupCopyEmailAddress", NULL, N_("_Copy E-mail Address"), NULL,
+        NULL,
+        G_CALLBACK (popup_copy_url_callback) },
+      { "PopupOpenLink", NULL, N_("_Open Link"), NULL,
+        NULL,
+        G_CALLBACK (popup_open_url_callback) },
+      { "PopupCopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
+        NULL,
+        G_CALLBACK (popup_copy_url_callback) },
+      { "PopupCopy", GTK_STOCK_COPY, NULL, NULL,
+        NULL,
+        G_CALLBACK (edit_copy_callback) },
+      { "PopupPaste", GTK_STOCK_PASTE, NULL, NULL,
+        NULL,
+        G_CALLBACK (edit_paste_callback) },
+      { "PopupNewTerminal", NULL, N_("Open _Terminal"), NULL,
+        NULL,
+        G_CALLBACK (file_new_window_callback) },
+      { "PopupNewTab", NULL, N_("Open Ta_b"), NULL,
+        NULL,
+        G_CALLBACK (file_new_tab_callback) },
+      { "PopupCloseWindow", NULL, N_("C_lose Window"), NULL,
+        NULL,
+        G_CALLBACK (file_close_window_callback) },
+      { "PopupCloseTab", NULL, N_("C_lose Tab"), NULL,
+        NULL,
+        G_CALLBACK (file_close_tab_callback) },
+      { "PopupInputMethods", NULL, N_("_Input Methods") }
     };
   
   const GtkToggleActionEntry toggle_menu_entries[] =
@@ -1132,6 +1392,8 @@
   TerminalWindow *window = TERMINAL_WINDOW (object);
   TerminalWindowPrivate *priv = window->priv;
 
+  remove_popup_info (window);
+
   if (priv->notify_id != 0)
     {
       gconf_client_notify_remove (priv->conf, priv->notify_id);
@@ -1527,7 +1789,7 @@
   return gtk_container_get_children (GTK_CONTAINER (priv->notebook));
 }
 
-int    
+int
 terminal_window_get_screen_count (TerminalWindow *window)
 {
   TerminalWindowPrivate *priv = window->priv;
@@ -1659,6 +1921,7 @@
   }
 }
 
+/* FIXMEchpe make this also switch tabs! */
 void
 terminal_window_set_active (TerminalWindow *window,
                             TerminalScreen *screen)
@@ -1804,6 +2067,9 @@
                     G_CALLBACK (selection_changed_callback),
                     window);
 
+  g_signal_connect (screen, "show-popup-menu",
+                    G_CALLBACK (screen_show_popup_menu_callback), window);
+
   terminal_screen_update_scrollbar (screen);
 
   update_notebook (window);
@@ -1872,6 +2138,11 @@
                                         G_CALLBACK (selection_changed_callback),
                                         window);
 
+  g_signal_handlers_disconnect_by_func (screen,
+                                        G_CALLBACK (screen_show_popup_menu_callback),
+                                        window);
+
+  /* FIXMEchpe this should have been done by the parent-set handler already! */
   terminal_screen_set_window (screen, NULL);
   priv->terms--;
 

Modified: trunk/src/terminal.c
==============================================================================
--- trunk/src/terminal.c	(original)
+++ trunk/src/terminal.c	Wed Mar 19 15:21:28 2008
@@ -3190,6 +3190,47 @@
   return xml;
 }
 
+void
+terminal_util_open_url (GtkWidget *parent,
+                        const char *orig_url,
+                        TerminalURLFlavour flavor)
+{
+  GError *error = NULL;
+  char *url;
+  
+  g_return_if_fail (orig_url != NULL);
+
+  switch (flavor)
+    {
+    case FLAVOR_DEFAULT_TO_HTTP:
+      url = g_strdup_printf ("http:%s", orig_url);
+      break;
+    case FLAVOR_EMAIL:
+      if (strncmp ("mailto:";, orig_url, 7))
+	url = g_strdup_printf ("mailto:%s";, orig_url);
+      else
+	url = g_strdup (orig_url);
+      break;
+    case FLAVOR_AS_IS:
+      url = g_strdup (orig_url);
+      break;
+    default:
+      url = NULL;
+      g_assert_not_reached ();
+    }
+
+  if (!gnome_url_show_on_screen (url, gtk_widget_get_screen (parent), &error))
+    {
+      terminal_util_show_error_dialog (GTK_WINDOW (parent), NULL,
+                                       _("Could not open the address \"%s\":\n%s"),
+                                       url, error->message);
+      
+      g_error_free (error);
+    }
+
+  g_free (url);
+}
+
 /* Factory stuff */
 
 typedef struct

Modified: trunk/src/terminal.h
==============================================================================
--- trunk/src/terminal.h	(original)
+++ trunk/src/terminal.h	Wed Mar 19 15:21:28 2008
@@ -25,6 +25,13 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <glade/glade.h>
+
+typedef enum {
+  FLAVOR_AS_IS,
+  FLAVOR_DEFAULT_TO_HTTP,
+  FLAVOR_EMAIL
+} TerminalURLFlavour;
+
 #include "terminal-screen.h"
 
 typedef struct _TerminalApp TerminalApp;
@@ -87,5 +94,9 @@
                                          const char *widget_root,
                                          GtkWindow  *error_dialog_parent);
 
+void terminal_util_open_url (GtkWidget *parent,
+                             const char *orig_url,
+                             TerminalURLFlavour flavor);
+
 
 #endif /* TERMINAL_H */

Modified: trunk/src/terminal.ui
==============================================================================
--- trunk/src/terminal.ui	(original)
+++ trunk/src/terminal.ui	Wed Mar 19 15:21:28 2008
@@ -52,4 +52,26 @@
       <menuitem action="HelpAbout" />
     </menu>
   </menubar>
+
+  <popup name="Popup" action="Popup">
+    <menuitem action="PopupSendEmail" />
+    <menuitem action="PopupCopyEmailAddress" />
+    <menuitem action="PopupOpenLink" />
+    <menuitem action="PopupCopyLinkAddress" />
+    <separator />
+    <menuitem action="PopupNewTerminal" />
+    <menuitem action="PopupNewTab" />
+    <separator />
+    <menuitem action="PopupCloseTab" />
+    <menuitem action="PopupCloseWindow" />
+    <separator />
+    <menuitem action="EditCopy" />
+    <menuitem action="EditPaste" />
+    <separator />
+    <menu action="TerminalProfiles" />
+    <menuitem action="EditCurrentProfile" />
+    <menuitem action="ViewMenubar" />
+    <separator />
+    <menuitem action="PopupInputMethods" />
+  </popup>
 </ui>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]