Logo Search packages:      
Sourcecode: kazehakase version File versions

kz-actions-popup.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003 Takuro Ashie
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "kz-actions-popup.h"

#include <string.h>
#include <unistd.h>
#include <glib/gi18n.h>
#include "kz-entry-action.h"
#include "gtk-utils.h"
#include "glib-utils.h"
#include "kazehakase.h"
#include "kz-window.h"
#include "kz-tab-label.h"
#include "kz-actions-download.h"
#include "kz-embed.h"
#include "kz-favicon.h"
#include "kz-xml.h"

#define KZ_ACTIONS_POPUP_LANGUAGE_KEY "KzActionsPopup::Language"
#define KZ_ACTIONS_POPUP_TAB_KEY "KzActionsPopup::Tab"
#define KZ_ACTIONS_POPUP_COPY_IN_USER_FORMAT_KEY "KzActionsPopup::CopyInUserFormat"

typedef enum {
      LOCATION_LINK,
      LOCATION_IMAGE,
      LOCATION_FRAME          
} LocationType;

typedef enum {
      CURRENT_TAB,
      NEW_TAB,
      NEW_WINDOW
} WindowType;


typedef struct
{
      KzEmbed *kzembed;
      gchar *filename;  /* file name for edior */
      gpointer element; /* pointer indicated textarea */
} EditorInfo;

static gchar *label_color[KZ_TAB_LABEL_N_STATE];

static void kz_actions_popup_append_tablist_menuitem (KzWindow *kz, GtkWidget *tablist_menu);

static void
open_location (GtkAction *action, KzWindow *kz, LocationType location, WindowType window)
{
      const KzEmbedEventMouse *event;
      const gchar *uri = NULL;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      switch (location) {
      case LOCATION_LINK:
            uri = event->cinfo.link;
            break;
      case LOCATION_IMAGE:
            uri = event->cinfo.img;
            break;
      case LOCATION_FRAME:
            uri = event->cinfo.frame_src;
            break;
      default:
            g_return_if_reached();
            break;
      }

      if (!uri) return;

      switch (window) {
      case CURRENT_TAB:
            kz_window_load_url(kz, uri);
            break;
      case NEW_TAB:
            kz_window_open_new_tab_with_parent(kz, uri,
                                       KZ_WINDOW_CURRENT_PAGE(kz));
            break;
      case NEW_WINDOW:
      {
            GtkWidget *widget = kz_window_new(uri);
            gtk_widget_show(widget);
            break;
      }
      default:
            g_return_if_reached();
            break;
      }
}

static void
act_popup_open (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_LINK, CURRENT_TAB);
}

static void
act_popup_open_in_new_tab (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_LINK, NEW_TAB);
}

static void
act_popup_open_in_new_win (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_LINK, NEW_WINDOW);
}

static void
act_popup_copy_link_location (GtkAction *action, KzWindow *kz)
{
      const KzEmbedEventMouse *event;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      gtkutil_copy_text(event->cinfo.link);
}

static void
act_popup_open_image (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_IMAGE, CURRENT_TAB);
}

static void
act_popup_open_image_in_new_tab (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_IMAGE, NEW_TAB);
}

static void
act_popup_open_image_in_new_win (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_IMAGE, NEW_WINDOW);
}

static void
act_popup_save_link (GtkAction *action, KzWindow *kz)
{
      const KzEmbedEventMouse *event;
      const gchar *uri = NULL;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      uri = event->cinfo.link;
      kz_actions_download_open_save_dialog(GTK_WINDOW(kz), uri, FALSE);
}

static void
act_popup_save_image (GtkAction *action, KzWindow *kz)
{
      const KzEmbedEventMouse *event;
      const gchar *uri = NULL;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      uri = event->cinfo.img;
      kz_actions_download_open_save_dialog(GTK_WINDOW(kz), uri, FALSE);
}

static void
act_popup_copy_image_location (GtkAction *action, KzWindow *kz)
{
      const KzEmbedEventMouse *event;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      gtkutil_copy_text(event->cinfo.img);
}

static void
act_popup_open_frame (GtkAction *action, KzWindow *kz)
{
      open_location(action, kz, LOCATION_FRAME, CURRENT_TAB);
}

static void
cb_embed_changed (KzEmbed *embed, EditorInfo *einfo)
{
      g_return_if_fail(KZ_IS_EMBED(embed));
      g_return_if_fail(einfo);

      g_signal_handlers_disconnect_by_func(embed,
                                   G_CALLBACK(cb_embed_changed),
                                   einfo);
      if (!einfo) return;

      if (einfo->filename)
            g_free(einfo->filename);
      einfo->filename = NULL;
      if (einfo->kzembed)
            g_object_unref(einfo->kzembed);
      einfo->kzembed  = NULL;
      einfo->element  = NULL;
}

static void
cb_editor_exit (GPid pid, gint status, gpointer data)
{
      gchar *text;
      gsize size;
      EditorInfo *einfo;
      
      /* close editor process */
      g_spawn_close_pid(pid);

      if (!data) return;

      einfo = (EditorInfo*)data;
      if (einfo->kzembed)
      {
            g_signal_handlers_disconnect_by_func(einfo->kzembed,
                                   G_CALLBACK(cb_embed_changed),
                                   einfo);
      }

      if (einfo->filename)
      {
            /* get text from temporary file */
            gboolean ret;
            ret = g_file_get_contents(einfo->filename, &text, &size, NULL);
            /* set text into textarea */
            if (ret)
            {
                  if (KZ_EMBED(einfo->kzembed) && einfo->element)
                  {
                        kz_embed_set_text_into_textarea(einfo->kzembed,
                                                einfo->element,
                                                text);
                  }
                  g_free(text);
            }

            g_free(einfo->filename);
            einfo->filename = NULL;
      }
      
      if (einfo->kzembed)
      {
            g_object_unref(einfo->kzembed);
      }
      einfo->kzembed  = NULL;
      einfo->element  = NULL;
      
      g_free(einfo);
      einfo = NULL;
}


static void
act_popup_launch_editor (GtkAction *action, KzWindow *kz)
{
      const KzEmbedEventMouse *event;
      GtkWidget *widget;

      GPid pid;
      GSpawnFlags flags;
      gint argc;
      gchar **argv = NULL;
      gchar *editor_command, *command, *text;
      EditorInfo *einfo = NULL;
      
      g_return_if_fail(KZ_IS_WINDOW(kz));
      widget = KZ_WINDOW_CURRENT_PAGE(kz);
      g_return_if_fail(KZ_EMBED(widget));

      event = kz_window_get_mouse_event_info(kz);
      g_return_if_fail(event);

      editor_command = KZ_CONF_GET_STR("Global", "editor_command");
      if (!editor_command)
            return;

      if (event->cinfo.context & KZ_CONTEXT_TEXTAREA)
      {
            einfo = g_new0(EditorInfo, 1);
            einfo->kzembed  = g_object_ref(KZ_EMBED(widget));
            einfo->element  = event->cinfo.element;
            text = kz_embed_get_text_from_textarea(KZ_EMBED(widget),
                                           einfo->element);
            /* text in textare store in temporary file */
            if (text)
            {
                  gint fd = g_file_open_tmp("kzXXXXXX",
                                      &einfo->filename,
                                      NULL);
                  write(fd, text, strlen(text));
                  close(fd);
                  g_free(text);
            }

            command = g_strdup_printf(editor_command, einfo->filename);
      }
      else
      {
            command = g_strdup_printf(editor_command, "");
      }
      
      /* */
      g_signal_connect(widget, "kz-net-start",
                   G_CALLBACK(cb_embed_changed), einfo);
      g_signal_connect(widget, "destroy",
                   G_CALLBACK(cb_embed_changed), einfo);
      /* launch editor */
      g_shell_parse_argv(command,
                     &argc,
                     &argv,
                     NULL);

      flags = G_SPAWN_SEARCH_PATH |
            G_SPAWN_DO_NOT_REAP_CHILD;
      g_spawn_async(NULL,
                  argv,
                  NULL,
                  flags,
                  NULL,
                  NULL,
                  &pid,
                  NULL);
      g_free(editor_command);
      g_free(command);
      g_strfreev(argv);

      g_child_watch_add(pid,
                    cb_editor_exit,
                    einfo);

}

static void
cb_popup_menu_hide (void)
{
      gtk_main_quit();
}

static void
cb_copy_in_user_format_menuitem_activate (GtkWidget *menuitem, KzWindow *kz)
{
      GtkWidget *widget;
      gint idx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem),
                                         KZ_ACTIONS_POPUP_COPY_IN_USER_FORMAT_KEY));
      gchar conf_key[] = "copy_document_format99";
      gchar *format;
      gchar *text;
      gchar *str;
      gint i;
      gint counts = 0;

      g_return_if_fail(0 < idx && idx < 100);
      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = KZ_WINDOW_CURRENT_PAGE(kz);
       if (!KZ_IS_EMBED(widget)) return;

      text = kz_embed_get_selection_string(KZ_EMBED(widget));
      if (!text) text = g_strdup("");

      g_snprintf(conf_key, sizeof(conf_key), "copy_document_format%d", idx);
      format = KZ_CONF_GET_STR("Global" , conf_key);
      g_return_if_fail(format);

      for(i = 0; format[i] != '\0'; i++)
            if(format[i] == '%') counts++;
      counts++;

      if(counts != 1)
      {
            gchar **temp = g_alloca(sizeof(gchar*) * (counts + 1));
            gchar **splited = g_strsplit(format , "%" , counts);
            gint st = 0;

            for(i = 0; i < counts-1; i++)
            {
                  if(st == 0)
                  {
                        /* first state */
                        temp[i] = splited[i];
                        st = 1;
                  }
                  else if (st == 2)
                  {
                        /* after %t% and so on */
                        temp[i] = splited[i];
                        st = 1;
                  }
                  else if (splited[i][0] == '\0')
                  {
                        /* "%%" */
                        temp[i] = "%";
                        st = 0;
                  }
                  else if (splited[i][1] != '\0')
                  {
                        /* %text% */
                        temp[i] = splited[i];
                        st = 1;
                  }
                  else if(splited[i][0] == 't')
                  {
                        /* %t% */
                        temp[i] = (gchar*)kz_embed_get_title(KZ_EMBED(widget));
                        st = 2;
                  }
                  else if(splited[i][0] == 'u')
                  {
                        /* %u% */
                        temp[i] = (gchar*)kz_embed_get_location(KZ_EMBED(widget));
                        st = 2;
                  }
                  else if(splited[i][0] == 's')
                  {
                        /* %s% */
                        temp[i] = text;
                        st = 2;
                  }
                  else
                  {
                        /* '%' + other char + '%' */
                        temp[i] = splited[i];
                        st = 1;
                  }
            }
            temp[counts-1] = splited[counts-1];
            temp[counts] = NULL;

            str = g_strjoinv(NULL , temp);
            g_strfreev(splited);
      }
      else
      {
            str = g_strdup(format);
      }

      g_free(format);

      gtkutil_copy_text(str);

      if(str) g_free(str);
      if(text) g_free(text);
}

static void
cb_tablist_menuitem_activate (GtkWidget *menuitem, KzWindow *kz)
{
      gint page_num;
      GtkWidget *widget = g_object_get_data(G_OBJECT(menuitem),
                                    KZ_ACTIONS_POPUP_TAB_KEY);

      page_num = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook),
                               GTK_WIDGET(widget));

      gtk_notebook_set_current_page(GTK_NOTEBOOK(kz->notebook), page_num);
}


static void
act_popup_tab_list (GtkAction *action, KzWindow *kz)
{
      GtkWidget *popup_menu = NULL;
      GList *children, *node;

      popup_menu = gtk_ui_manager_get_widget(kz->menu_merge,
                                     "/TabListPopup");
      if (!popup_menu) return;

      /* remove previous menu item */
      children = g_list_copy(GTK_MENU_SHELL(popup_menu)->children);
      
      for (node = children; node; node = g_list_next(node))
      {
            GtkWidget *menuitem = node->data;
            gtk_widget_destroy(menuitem);
      }
      g_list_free(children);

      kz_actions_popup_append_tablist_menuitem(kz, popup_menu);
      
      g_signal_connect(popup_menu, "hide",
                   G_CALLBACK(cb_popup_menu_hide), kz);
      gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL,
                   NULL, NULL, 0, 0);
      gtk_main();

      g_signal_handlers_disconnect_by_func(popup_menu,
                                   G_CALLBACK(cb_popup_menu_hide), kz);
}

GtkActionEntry kz_actions_popup[] =
{
        /* Toplevel */

      {"OpenLink",            NULL, N_("_Open"),
       NULL, N_("Open link"), G_CALLBACK(act_popup_open)},
      {"OpenLinkInNewTab",    NULL, N_("Open in new _tab"),
       NULL, N_("Open link in a new tab"), G_CALLBACK(act_popup_open_in_new_tab)},
      {"OpenLinkInNewWindow", KZ_STOCK_OPEN_LINK_WINDOW, N_("Open in new _window"),
       NULL, N_("Open link in a new window"), G_CALLBACK(act_popup_open_in_new_win)},
      {"CopyLinkLocation", KZ_STOCK_COPY_URL, N_("Copy _link location"),
       NULL, N_("Copy the location of the link"), G_CALLBACK(act_popup_copy_link_location)},
      {"SaveLink", KZ_STOCK_SAVE_LINK, N_("Save lin_k to disk"),
       NULL, N_("Save the object to disk"), G_CALLBACK(act_popup_save_link)},

      {"OpenImage",           NULL, N_("Open _image"),
       NULL, N_("Open the image"), G_CALLBACK(act_popup_open_image)},
      {"OpenImageInNewTab",   NULL, N_("Open image in new ta_b"),
       NULL, N_("Open the image in a new tab"), G_CALLBACK(act_popup_open_image_in_new_tab)},
      {"OpenImageInNewWindow",KZ_STOCK_OPEN_IMAGE_WINDOW, N_("Open image in _new window"),
       NULL, N_("Open the image in a new window"), G_CALLBACK(act_popup_open_image_in_new_win)},
      {"CopyImageLocation", KZ_STOCK_COPY_IMAGE_URL, N_("Copy image l_ocation"),
       NULL, N_("Copy the location of the image"), G_CALLBACK(act_popup_copy_image_location)},
      {"SaveImage",           NULL, N_("Sa_ve image as"),
       NULL, N_("Save the image to disk"), G_CALLBACK(act_popup_save_image)},

      {"OpenThisFrame",        NULL, N_("Open this _frame"),
      NULL, N_("Open the frame in the current tab"),  G_CALLBACK(act_popup_open_frame)},

      {"LaunchEditor",         KZ_STOCK_EDITOR, N_("_Launch Editor"),
       NULL, N_("Launch external editor"), G_CALLBACK(act_popup_launch_editor)},
      {"PopupTabList",         NULL, N_("_Popup TabList"),
       NULL, N_("Display tab list"), G_CALLBACK(act_popup_tab_list)},

      {"StockEncodingMenu", NULL, N_("_Encoding"), NULL, NULL, NULL},
      {"StockTabList",      NULL, N_("_TabList"),  NULL, NULL, NULL},
};

const gint kz_actions_popup_len = G_N_ELEMENTS(kz_actions_popup);


GtkActionGroup *
kz_actions_popup_create_group (KzWindow *kz, GtkAccelGroup *accel_group)
{
      GtkActionGroup *action_group;
      GList *node, *action_list;

      action_group = gtk_action_group_new("KzWindowPopup");

      gtk_action_group_set_translation_domain(action_group, NULL);

      gtk_action_group_add_actions(action_group,
                             kz_actions_popup,
                             kz_actions_popup_len,
                             kz);

      action_list = gtk_action_group_list_actions(action_group);
      
      for (node = action_list; node; node = g_list_next(node))
      {
            gtk_action_set_accel_group(GTK_ACTION(node->data),
                                 accel_group);
            gtk_action_connect_accelerator(GTK_ACTION(node->data));
      }
      g_list_free(action_list);

      return action_group;
}

static GHashTable *popup_menu_table = NULL;

static void
cb_popup_destroy (GtkWidget *extra_menu)
{
      if (popup_menu_table) 
      {
            g_hash_table_remove(popup_menu_table, extra_menu);
      }
      return;
}

static gboolean 
cb_encoding_menuitem_destroy (GtkWidget *menuitem, gchar *encoding)
{
      g_return_val_if_fail (GTK_CHECK_MENU_ITEM(menuitem), FALSE);
      
      if (encoding)
            g_free(encoding);
      
      g_object_set_data(G_OBJECT(menuitem), 
                    KZ_ACTIONS_POPUP_LANGUAGE_KEY,
                    NULL);
      
      return FALSE;
}

static void
cb_encoding_menuitem_activate (GtkWidget *menuitem, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      if (GTK_CHECK_MENU_ITEM(menuitem)->active && KZ_EMBED(widget))
      {
            const gchar* code
                  = g_object_get_data(G_OBJECT(menuitem),
                                  KZ_ACTIONS_POPUP_LANGUAGE_KEY);
            GtkAction *action;

            kz_embed_set_encoding(KZ_EMBED(widget), code);

            action = gtk_action_group_get_action(kz->actions, "Reload");

            gtk_action_activate(action);
      }
      return;
}

static GtkWidget *
create_lang_menu_item (KzWindow *kz, KzXMLNode *node,
                   GSList **group, const gchar *current_encoding,
                   gboolean forced)
{
      GtkWidget *menuitem = NULL;
      const gchar *label;

      if (!kz_xml_node_is_element(node)) return NULL;

      label = kz_xml_node_get_attr(node, "label");
      g_return_val_if_fail(label, NULL);

      if (kz_xml_node_name_is(node, "group"))
      {
            GtkWidget *submenu;
            KzXMLNode *child_node;

            menuitem = gtk_menu_item_new_with_label(label);
            submenu = gtk_menu_new();
            gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
            gtk_widget_show(submenu);

            for (child_node = kz_xml_node_first_child(node);
                 child_node;
                 child_node = kz_xml_node_next(child_node))
            {
                  GtkWidget *child_menuitem;

                  child_menuitem = create_lang_menu_item
                        (kz, child_node, group,
                         current_encoding, forced);
                  if (!child_menuitem) continue;

                  gtk_menu_shell_append(GTK_MENU_SHELL(submenu),
                                    child_menuitem);
                  gtk_widget_show(child_menuitem);
            }
      }
      else if (kz_xml_node_name_is(node, "encoding"))
      {
            gchar *encoding;

            encoding = g_strdup(kz_xml_node_get_attr(node, "name"));

            menuitem = gtk_radio_menu_item_new_with_label(*group, _(label));
            g_object_set_data(G_OBJECT(menuitem),
                          KZ_ACTIONS_POPUP_LANGUAGE_KEY,
                          (gpointer) encoding);
            g_signal_connect(menuitem, "activate",
                         G_CALLBACK(cb_encoding_menuitem_activate), kz);
            g_signal_connect(menuitem, "destroy",
                         G_CALLBACK(cb_encoding_menuitem_destroy), encoding);

            if (forced && current_encoding &&
                !strcmp(current_encoding, encoding))
            {
                  gtk_check_menu_item_set_active
                        (GTK_CHECK_MENU_ITEM(menuitem),
                         TRUE);
            }
            *group = gtk_radio_menu_item_get_group
                        (GTK_RADIO_MENU_ITEM(menuitem));
      }
      else
      {
            /* warning? */
      }

      return menuitem;
}

static void
kz_actions_popup_append_copy_in_user_format_menuitem (KzWindow *kz,
                                          GtkMenuItem *copy_in_user_format_menu)
{
      GtkWidget *copy_in_user_format_submenu;
      GtkWidget *menuitem;
      gchar *title;
      gchar conf_key[] = "copy_document_format_title99";
      gint i;

      if (!popup_menu_table)
      {
            popup_menu_table = g_hash_table_new(g_direct_hash,
                                        g_direct_equal);
      }

      copy_in_user_format_submenu = g_hash_table_lookup(popup_menu_table, copy_in_user_format_menu);
      if (copy_in_user_format_submenu) return;

      /* append copy in user format menuitem */
      copy_in_user_format_submenu = gtk_menu_new();

      for (i = 1; i < 100; i++)
      {
            g_snprintf(conf_key, sizeof(conf_key), "copy_document_format_title%d", i);
            title = KZ_CONF_GET_STR("Global" , conf_key);
            if(!title) break;

            menuitem = gtk_menu_item_new_with_label(title);

            g_object_set_data (G_OBJECT(menuitem),
                           KZ_ACTIONS_POPUP_COPY_IN_USER_FORMAT_KEY,
                           GINT_TO_POINTER(i));

            g_signal_connect(menuitem, "activate",
                         G_CALLBACK(cb_copy_in_user_format_menuitem_activate),
                         kz);

            gtk_menu_shell_append(GTK_MENU_SHELL(copy_in_user_format_submenu),
                              menuitem);
            gtk_widget_show(menuitem);

            g_free(title);
      }

      gtk_menu_item_set_submenu(GTK_MENU_ITEM(copy_in_user_format_menu),
                          copy_in_user_format_submenu);

      /* reference */
      g_hash_table_insert(popup_menu_table, copy_in_user_format_menu,
                      copy_in_user_format_submenu);
      g_signal_connect(copy_in_user_format_menu, "destroy",
                   G_CALLBACK(cb_popup_destroy), NULL);
}

static void
kz_actions_popup_append_encoding_menuitem (KzWindow *kz,
                                 GtkMenuItem *encoding_menu)
{
      GtkWidget *encoding_submenu;
      GtkWidget *menuitem;
      GSList *group = NULL;
      GtkWidget *page = KZ_WINDOW_CURRENT_PAGE(kz);
      gchar *current_encoding = NULL;
      gboolean forced = FALSE;
      KzXML *xml;
      KzXMLNode *node;

      if (!popup_menu_table)
      {
            popup_menu_table = g_hash_table_new(g_direct_hash,
                                        g_direct_equal);
      }

      encoding_submenu = g_hash_table_lookup(popup_menu_table, encoding_menu);
      if (encoding_submenu) return;

      /* append encodings menuitem */
      encoding_submenu = gtk_menu_new();
            
      /* get current charset */
      if(KZ_EMBED(page))
      {
            kz_embed_get_encoding(KZ_EMBED(page),
                              &current_encoding, &forced);
      }

      menuitem = gtk_radio_menu_item_new_with_label(group, _("Auto"));
      if(!forced) {
            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
                                     TRUE);
      }

      group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
      g_object_set_data(G_OBJECT(menuitem),
                    KZ_ACTIONS_POPUP_LANGUAGE_KEY, "");

      g_signal_connect(menuitem, "activate",
                   G_CALLBACK(cb_encoding_menuitem_activate), kz);

      gtk_menu_shell_append(GTK_MENU_SHELL(encoding_submenu), menuitem);
      gtk_widget_show(menuitem);

      /* separator */
      menuitem = gtk_separator_menu_item_new();
      gtk_menu_shell_append(GTK_MENU_SHELL(encoding_submenu), menuitem);
      gtk_widget_show(menuitem);

      xml = kz_xml_new();
      kz_xml_load(xml, KZ_SYSCONFDIR "/mozilla/encodings.xml");
      node = kz_xml_get_root_element(xml);
      if (node && kz_xml_node_name_is(node, "encodings"))
      {
            node = kz_xml_node_first_child(node);
            for (; node; node = kz_xml_node_next(node))
            {
                  menuitem = create_lang_menu_item(kz, node, &group,
                                           current_encoding,
                                           forced);
                  if (!menuitem) continue;

                  gtk_menu_shell_append(GTK_MENU_SHELL(encoding_submenu),
                                    menuitem);
                  gtk_widget_show(menuitem);
            }
      }
      g_object_unref(G_OBJECT(xml));

      gtk_menu_item_set_submenu(GTK_MENU_ITEM(encoding_menu),
                          encoding_submenu);

      g_free(current_encoding);

      /* reference */
      g_hash_table_insert(popup_menu_table, encoding_menu, encoding_submenu);
      g_signal_connect(encoding_menu, "destroy",
                   G_CALLBACK(cb_popup_destroy), NULL);
}


static void
kz_actions_popup_append_tablist_menuitem (KzWindow *kz, GtkWidget *tablist_menu)
{
      gint i;
      const gint num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));
      GtkWidget *tablist_submenu;
      GtkWidget *page;
      gint current_page_num;
      KzFavicon *kzfav;
      gchar *color = NULL;

      /* label color */
      color = KZ_CONF_GET_STR("Tab" , "normal_color");
      if (!color)
            color = g_strdup("#000000");

      if (label_color[KZ_TAB_LABEL_STATE_NORMAL])
            g_free(label_color[KZ_TAB_LABEL_STATE_NORMAL]);
      label_color[KZ_TAB_LABEL_STATE_NORMAL] = g_strdup(color);
      g_free(color);

      color = KZ_CONF_GET_STR("Tab" , "loading_color");
      if (!color)
            color = g_strdup("#ff0000");
      if (label_color[KZ_TAB_LABEL_STATE_LOADING])
            g_free(label_color[KZ_TAB_LABEL_STATE_LOADING]);
      label_color[KZ_TAB_LABEL_STATE_LOADING] = g_strdup(color);
      g_free(color);

      color = KZ_CONF_GET_STR("Tab" , "loaded_color");
      if (!color)
            color = g_strdup("#22aa44");
      if (label_color[KZ_TAB_LABEL_STATE_LOADED])
            g_free(label_color[KZ_TAB_LABEL_STATE_LOADED]);
      label_color[KZ_TAB_LABEL_STATE_LOADED] = g_strdup(color);
      g_free(color);

      kzfav = kz_favicon_get_instance();

      if (GTK_IS_MENU_ITEM(tablist_menu))
      {
            if (!popup_menu_table)
            {
                  popup_menu_table = g_hash_table_new(g_direct_hash,
                                              g_direct_equal);
            }

            tablist_submenu = g_hash_table_lookup(popup_menu_table,
                                          tablist_menu);

            if (tablist_submenu)
            {
                  gtk_menu_item_remove_submenu(GTK_MENU_ITEM(tablist_menu));
            }
            /* append tablist menuitem */
            tablist_submenu = gtk_menu_new();
      }
      else
      {
            tablist_submenu = tablist_menu;
      }

      page = KZ_WINDOW_CURRENT_PAGE(kz);
      current_page_num = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook),
                                     GTK_WIDGET(page));

      for (i = 0; i < num; i++)
      {
            KzEmbed *kzembed = KZ_EMBED(KZ_WINDOW_NTH_PAGE(kz, i));
            GtkWidget *favicon;

            if (KZ_EMBED(kzembed))
            {
                  gchar *title, *escaped, *markup_title;
                  GtkWidget *menuitem;
                  GtkWidget *tab;
                  KzTabLabelState state;
                  
                  tab = kz_window_get_tab_label(kz, GTK_WIDGET(kzembed));
                  state = kz_tab_label_get_state(KZ_TAB_LABEL(tab));
                  title = kz_embed_ensure_title(kzembed);
                  escaped = g_markup_escape_text(title,
                                           strlen(title));
                  menuitem = gtk_image_menu_item_new_with_label(title);

                  if (i == current_page_num)
                  {
                        markup_title = g_strdup_printf("<b>%s</b>",
                                                 escaped);
                  }
                  else
                  {
                        markup_title = g_strdup_printf("<span foreground=\"%s\">%s</span>",
                                                 label_color[state],
                                                 escaped);
                  }

                  gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem))),
                                   markup_title);
                  g_free(markup_title);
                  g_free(escaped);
                  
                  /* favicon */
                  favicon = kz_favicon_get_widget(kzfav,
                                          kz_embed_get_location(kzembed),
                                          KZ_ICON_SIZE_BOOKMARK_MENU);
                  if (favicon)
                  {
                        gtk_widget_show(favicon);
                        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
                                                favicon);
                  }

                  g_object_set_data (G_OBJECT(menuitem), KZ_ACTIONS_POPUP_TAB_KEY, kzembed);

                  g_signal_connect(menuitem, "activate",
                               G_CALLBACK(cb_tablist_menuitem_activate), kz);
                  gtk_menu_shell_append(GTK_MENU_SHELL(tablist_submenu), menuitem);
                  gtk_widget_show(menuitem);
                  g_free(title);
            }
      }
      if (GTK_IS_MENU_ITEM(tablist_menu))
      {
            gtk_menu_item_set_submenu(GTK_MENU_ITEM(tablist_menu),
                                tablist_submenu);

            /* reference */
            g_hash_table_insert(popup_menu_table,
                            tablist_menu,
                            tablist_submenu);
            g_signal_connect(tablist_menu, "destroy",
                         G_CALLBACK(cb_popup_destroy), NULL);
      }
      g_object_unref(kzfav);
      return;
}

#define GET_MENU(kz, path) \
      (gtk_ui_manager_get_widget(kz->menu_merge, path))


void
kz_actions_popup_menu_modal (KzWindow *kz, guint button, guint time)
{
      GtkWidget *popup_menu = NULL;
      GtkWidget *extra_menu = NULL;
      const KzEmbedEventMouse *event;
      gboolean is_selection, is_doc, is_link, is_image, is_input, is_frame;
      gchar path[64] = {0};
      gchar extra_menu_path[64] = {0};

      event = kz_window_get_mouse_event_info(kz);
      if (!event) return;

      is_selection = event->cinfo.context & KZ_CONTEXT_SELECTION;
      is_doc       = event->cinfo.context & KZ_CONTEXT_DOCUMENT;
      is_link      = event->cinfo.context & KZ_CONTEXT_LINK;
      is_image     = event->cinfo.context & KZ_CONTEXT_IMAGE;
      is_input     = event->cinfo.context & KZ_CONTEXT_INPUT;
      is_frame     = event->cinfo.context & KZ_CONTEXT_FRAME;

#if 0
      if (is_selection)
            /*
             * FIXME!! We should merge this menu items to other context's
             * menu.
             */
            popup_menu = GET_MENU(kz, "/SelectionPopup");
      else
#endif
      if (is_doc)
      {
            if (is_frame)
                  g_snprintf(path, sizeof(path), "/DocumentPopupinFrame");
            else
                  g_snprintf(path, sizeof(path), "/DocumentPopup");
      }
      if (is_link && is_image)
            g_snprintf(path, sizeof(path), "/LinkImagePopup");
      else if (is_link)
            g_snprintf(path, sizeof(path), "/LinkPopup");
      else if (is_image)
            g_snprintf(path, sizeof(path), "/ImagePopup");
      else if (is_input)
            g_snprintf(path, sizeof(path), "/InputPopup");

      if (!*path) return;

      popup_menu = GET_MENU(kz, path);
      if (!popup_menu) return;

      if (is_input) {
            gtkutil_append_im_menuitem(GTK_MENU_SHELL(popup_menu));
      }

        /* add copy in user format */
      g_snprintf(extra_menu_path,
               sizeof(extra_menu_path), "%s/CopyInUserFormat", path);

      extra_menu = GET_MENU(kz, extra_menu_path);
      if(extra_menu)
      {
            kz_actions_popup_append_copy_in_user_format_menuitem
                  (kz, GTK_MENU_ITEM(extra_menu));
      }

        /* add encoding menu */
      g_snprintf(extra_menu_path,
               sizeof(extra_menu_path), "%s/EncodingMenu", path);

      extra_menu = GET_MENU(kz, extra_menu_path);
      if(extra_menu) 
      {
            kz_actions_popup_append_encoding_menuitem
                  (kz, GTK_MENU_ITEM(extra_menu));
      }

        /* add tablist */
      g_snprintf(extra_menu_path,
               sizeof(extra_menu_path), "%s/TabList", path);
      extra_menu = GET_MENU(kz, extra_menu_path);
      if(extra_menu) 
      {
            kz_actions_popup_append_tablist_menuitem(kz, extra_menu);
      }

      g_signal_connect(popup_menu, "hide",
                   G_CALLBACK(cb_popup_menu_hide), kz);
      gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL,
                   NULL, NULL, 0, time);
      gtk_main();

      g_signal_handlers_disconnect_by_func(popup_menu,
                                   G_CALLBACK(cb_popup_menu_hide), kz);
}

Generated by  Doxygen 1.6.0   Back to index