Logo Search packages:      
Sourcecode: galeon version File versions

galeon-popup.c

/*
 *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
 *  Copyright (C) 2003 Philip Langdale
 *
 *  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.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "galeon-popup.h"
#include "galeon-debug.h"
#include "galeon-embed-event.h"
#include "galeon-embed-shell.h"
#include "galeon-shell.h"
#include "prefs-strings.h"
#include "galeon-config.h"
#include "gul-string.h"
#include "galeon-embed-helper-list.h"
#include "bookmarks-gtk-menu.h"
#include "gul-gui.h"
#include "pixbuf-cache.h"

#include "popup-commands.h"

#include <glib/gi18n.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkstock.h>

#include <libgnomevfs/gnome-vfs-uri.h>

#define MENU_ITEM_NAME_MAX_LENGTH 40


typedef enum
{
      POPUP_INPUT,
      POPUP_DOCUMENT_NORMAL,
      POPUP_DOCUMENT_SIDEBAR,
      POPUP_LINK,
      POPUP_EMAIL_LINK,
      POPUP_IMAGE,
      POPUP_IMAGE_LINK,
      POPUP_IMAGE_EMAIL_LINK
} PopupType;

#define GALEON_POPUP_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
                               GALEON_TYPE_POPUP, GaleonPopupPrivate))

struct GaleonPopupPrivate
{
      GaleonWindow *window;
      GtkWidget *menu;
      GSList *bookmark_menus;
      GaleonEmbedHelperList *helper_list;
      GaleonEmbedEvent *event;
      GaleonEmbed *embed;
      EmbedEventContext context;
      GtkUIManager *merge;
      GtkActionGroup *action_group;
      PopupType popup_type;
};


enum
{
      PROP_0,
      PROP_WINDOW,
      PROP_EVENT,
      PROP_EMBED
};

static void galeon_popup_set_window (GaleonPopup *p, GaleonWindow *window);
static void galeon_popup_set_embed (GaleonPopup *p, GaleonEmbed *embed);

#define ACTION_ITEM(name) gtk_action_group_get_action(p->priv->action_group, name)

#define INPUT_POPUP_PATH                  "/GaleonEmbedInputPopup"
#define DOCUMENT_POPUP_NORMAL_PATH        "/GaleonEmbedDocumentNormalPopup"
#define DOCUMENT_POPUP_SIDEBAR_PATH       "/GaleonEmbedDocumentSidebarPopup"
#define LINK_POPUP_PATH                   "/GaleonEmbedLinkPopup"
#define EMAIL_LINK_POPUP_PATH             "/GaleonEmbedEmailLinkPopup"
#define IMAGE_POPUP_PATH                  "/GaleonEmbedImagePopup"
#define IMAGE_LINK_POPUP_PATH             "/GaleonEmbedImageLinkPopup"
#define IMAGE_EMAIL_LINK_POPUP_PATH       "/GaleonEmbedImageEmailLinkPopup"

#define OPEN_WITH_MENU_ACTION "DPOpenWithMenuAction"
#define OPEN_IMAGE_WITH_MENU_ACTION "EPOpenImageWithMenuAction"
#define OPEN_IMAGE_ACTION "EPOpenImageAction"
#define SAVE_BACKGROUND_AS_ACTION "DPSaveBackgroundAsAction"

#define COPY_TEXT_ACTION "EPEditCopyAction"

/*This command is from src/popup-commands.c but manipulating item label
 *text must be done here
 */
#define BLOCK_IMAGE_SITE_ACTION "EPBlockImageSiteAction"
#define ALLOW_IMAGE_SITE_ACTION "EPAllowImageSiteAction"

#define OPEN_IN_NEW_TAB_ACTION    "EPOpenInNewTabAction"
#define OPEN_IN_NEW_WINDOW_ACTION "EPOpenInNewWindowAction"
#define VIEW_SOURCE_ACTION        "EPViewSourceAction"

static GtkActionEntry entries[] = {
      { "PopupToplevelAction", NULL, (""), NULL, NULL, NULL },

      { COPY_TEXT_ACTION, GTK_STOCK_COPY, N_("_Copy Selected Text"), NULL,
        N_("Copy the selection to the clipboard"), G_CALLBACK (popup_copy_text_cmd) },
      /* Document actions, also Back, Forward, Copy, Reload and Add Bookmark */
      { OPEN_WITH_MENU_ACTION, NULL, N_("Open _With"), NULL, NULL, NULL },

      { "DPSavePageAsAction", GTK_STOCK_SAVE_AS, N_("_Save Page As..."), NULL,
        N_("Save the page"), G_CALLBACK(popup_save_page_as_cmd) },

      { "DPCopyLocationAction", NULL, N_("Copy _Page Address"), NULL,
        N_("Copy the current page address to the clipboard"), 
        G_CALLBACK(popup_copy_location_cmd) },

      { VIEW_SOURCE_ACTION, STOCK_VIEW_SOURCE, N_("_View Source"), NULL,
        N_("Show the source of the current page"), G_CALLBACK(popup_cmd_view_source) },
      
      { "DPSaveBackgroundAsAction", NULL, N_("Save Bac_kground As..."), NULL,
        N_("Save the page's background"), G_CALLBACK(popup_save_background_as_cmd) },

      { "DPOpenFrameAction", NULL, N_("_Open Frame"), NULL,
        N_("Open the frame in this window"), G_CALLBACK(popup_open_frame_cmd) },
      { "DPOpenFrameInNewWindowAction", NULL,  N_("Open Frame in _New Window"), NULL,
        N_("Open the frame in a new Galeon window"), G_CALLBACK(popup_cmd_frame_in_new_window) },
      { "DPOpenFrameInNewTabAction",      NULL, N_("Open Frame in New _Tab"), NULL,
        N_("Open the frame in a new tab in this window"), G_CALLBACK(popup_cmd_frame_in_new_tab) },
      { "DPReloadFrameAction", GTK_STOCK_REFRESH, N_("Reload Fra_me"), NULL,
        N_("Display the latest content of the frame"), G_CALLBACK (popup_cmd_reload_frame) },

      /* Link actions, plus copy */
      { "EPOpenAction", GTK_STOCK_JUMP_TO,  N_("_Open Link"), NULL,
        N_("Open the link in the current tab"), G_CALLBACK(popup_cmd_open_link) },
      { OPEN_IN_NEW_WINDOW_ACTION, NULL, N_("Open in New _Window"), NULL,
        N_("Open the link in a new window"), G_CALLBACK(popup_cmd_new_window) },
      { OPEN_IN_NEW_TAB_ACTION, NULL,  N_("Open in New _Tab"), NULL,
        N_("Open the link in a new tab in this window"), G_CALLBACK(popup_cmd_new_tab) },

      { "EPDownloadLinkAction", GALEON_STOCK_DOWNLOAD, N_("_Download Link"), NULL,
        N_("Download the link"), G_CALLBACK(popup_download_link_cmd) },

      { "EPCopyLinkLocationAction", NULL, N_("Copy _Link Address"), NULL,
        N_("Copy the link address to the clipboard"), G_CALLBACK(popup_copy_link_location_cmd) },
      { "EPAddBookmarkAction", STOCK_ADD_BOOKMARK,  N_("_Add Bookmark..."), NULL,
        N_("Add a bookmark for the link"), 
        G_CALLBACK(popup_cmd_add_bookmark) },

      /* Email actions, plus copy */

      { "EPSendEmailAction", STOCK_SEND_MAIL, N_("Sen_d Email..."), NULL,
        N_("Send an email using your email program"), G_CALLBACK(popup_cmd_open_link) },
      { "EPCopyEmailAction", NULL, N_("C_opy Email Address"), NULL,
        N_("Copy the Email address to the clipboard"), G_CALLBACK(popup_copy_email_cmd) },

      /* Image actions, plus link / email actions */
      { "EPOpenImageAction", NULL, N_("Ope_n Image"), NULL,
        N_("Open the image in this window"), G_CALLBACK(popup_open_image_cmd) },
      { "EPOpenImageInNewWindowAction", NULL,  N_("Open Image in N_ew Window"), NULL,
        N_("Open the image in a new Galeon window"), G_CALLBACK(popup_cmd_image_in_new_window) },
      { "EPOpenImageInNewTabAction",      NULL, N_("Open Image in New Ta_b"), NULL,
        N_("Open the image in a new tab in this window"), G_CALLBACK(popup_cmd_image_in_new_tab) },

      { OPEN_IMAGE_WITH_MENU_ACTION, NULL, N_("Open Image Wit_h"), NULL, NULL, NULL },
      { "EPSetImageAsBackgroundAction", NULL, N_("_Use Image As Background"), NULL,
        N_("Use the image as the desktop background image"), 
        G_CALLBACK(popup_set_image_as_background_cmd) },


      { "EPSaveImageAsAction", GTK_STOCK_SAVE_AS, N_("_Save Image As..."), NULL,
        N_("Save the image"), G_CALLBACK(popup_save_image_as_cmd) },
      { "EPCopyImageLocationAction", NULL, N_("_Copy Image Address"), NULL,
        N_("Copy the image address to the clipboard"), G_CALLBACK(popup_copy_image_location_cmd) },
      { "EPBlockImageSiteAction", NULL,  N_("Block I_mages From This Site"), NULL,
          N_("Block images from this image's originating host"), G_CALLBACK(popup_cmd_image_block_site) },
      { "EPAllowImageSiteAction", NULL,  N_("Allow I_mages From This Site"), NULL,
          N_("Allow images from this image's originating host"), G_CALLBACK(popup_cmd_image_block_site) }
};
static guint n_entries = G_N_ELEMENTS(entries);

G_DEFINE_TYPE (GaleonPopup, galeon_popup, G_TYPE_OBJECT);

static const char *
galeon_popup_get_image_openwith_popup_path (GaleonPopup *p)
{
      const char *result = NULL;

      switch (p->priv->popup_type)
      {
            case POPUP_INPUT:
            case POPUP_LINK:
            case POPUP_DOCUMENT_NORMAL:
            case POPUP_EMAIL_LINK:
            case POPUP_DOCUMENT_SIDEBAR:
                  result = NULL;
                  break;
            case POPUP_IMAGE:
                  result = IMAGE_POPUP_PATH "/EPOpenImageWith";
                  break;
            case POPUP_IMAGE_LINK:
                  result = IMAGE_LINK_POPUP_PATH  "/EPOpenImageWith";
                  break;
            case POPUP_IMAGE_EMAIL_LINK:
                  result = IMAGE_EMAIL_LINK_POPUP_PATH  "/EPOpenImageWith";
                  break;
      }
      
      return result;
}

static const char *
galeon_popup_get_doc_openwith_popup_path (GaleonPopup *p)
{
      const char *result = NULL;

      switch (p->priv->popup_type)
      {
            case POPUP_INPUT:
            case POPUP_LINK:
            case POPUP_EMAIL_LINK:
            case POPUP_IMAGE:
            case POPUP_IMAGE_LINK:
            case POPUP_IMAGE_EMAIL_LINK:
                  result = NULL;
                  break;
            case POPUP_DOCUMENT_NORMAL:
                  result = DOCUMENT_POPUP_NORMAL_PATH "/DPOpenWith";
                  break;
            case POPUP_DOCUMENT_SIDEBAR:
                  result = DOCUMENT_POPUP_SIDEBAR_PATH "/DPOpenWith";
                  break;
      }
      
      return result;
}

static const char *
galeon_popup_get_popup_path (GaleonPopup *p)
{
      const char *result = NULL;

      switch (p->priv->popup_type)
      {
            case POPUP_INPUT:
                  result = INPUT_POPUP_PATH;
                  break;
            case POPUP_LINK:
                  result = LINK_POPUP_PATH;
                  break;
            case POPUP_EMAIL_LINK:
                  result = EMAIL_LINK_POPUP_PATH;
                  break;
            case POPUP_IMAGE:
                  result = IMAGE_POPUP_PATH;
                  break;
            case POPUP_IMAGE_LINK:
                  result = IMAGE_LINK_POPUP_PATH;
                  break;
            case POPUP_IMAGE_EMAIL_LINK:
                  result = IMAGE_EMAIL_LINK_POPUP_PATH;
                  break;
            case POPUP_DOCUMENT_NORMAL:
                  result = DOCUMENT_POPUP_NORMAL_PATH;
                  break;
            case POPUP_DOCUMENT_SIDEBAR:
                  result = DOCUMENT_POPUP_SIDEBAR_PATH;
                  break;
      }
      
      return result;
}

static void
setup_image_openwith (GaleonPopup *p)
{
      const gchar *path = galeon_popup_get_image_openwith_popup_path (p);
      GaleonEmbedEvent *info;
      const char *url;
      const GValue *value;
      GaleonEmbedHelperList *hl;
      GtkWidget *menuitem;
      GtkWidget *menu;
      g_return_if_fail (path != NULL);

      menuitem = gtk_ui_manager_get_widget(p->priv->window->merge, path);
      menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
      info = galeon_popup_get_event (p);
      value = galeon_embed_event_get_property (info, "image");
      url = g_value_get_string (value);
      hl = p->priv->helper_list;
      if (!galeon_embed_helper_list_set_uri (hl, url))
      {
            /* it must be an image, so let's try with png */
            galeon_embed_helper_list_add_mime_type (hl, "image/png");
      }

      gul_gui_remove_all_children (GTK_CONTAINER (menu));
      galeon_embed_helper_list_add_to_gtk_menu (hl, GTK_MENU_SHELL (menu));
}

static void 
setup_element_menu (GaleonPopup *p)
{
      gboolean is_image, is_sidebar, is_link;
      
      is_image = p->priv->context & EMBED_CONTEXT_IMAGE;
      is_sidebar = p->priv->context & EMBED_CONTEXT_SIDEBAR;
      is_link = p->priv->context & EMBED_CONTEXT_LINK;

      /* Hide items that doesnt make sense to show in the sidebar */
      g_object_set(G_OBJECT(ACTION_ITEM(OPEN_IMAGE_ACTION)),
                 "visible", !is_sidebar, NULL);

      if (is_image)
      {
            GaleonEmbedEvent *info;
            const GValue *value;
            char *open_image_str, *block_host_str,
                 *esc_file = NULL, *file = NULL;
            const char *host = NULL;
            GnomeVFSURI *uri = NULL;
            const char *show_action, *hide_action;
            PermissionActionType perm_action;
            const char *open_image_fmt = _("Ope_n Image (%s)");

            info = galeon_popup_get_event(p);

            value = galeon_embed_event_get_property(info, "image");

            uri = gnome_vfs_uri_new(g_value_get_string(value));

            if (uri)
            {
                  host = gnome_vfs_uri_get_host_name(uri);
                  file = gnome_vfs_uri_extract_short_name(uri);
            }

            if (!host)
                  host = _("This Site");

            if (file)
            {
                  int len = MENU_ITEM_NAME_MAX_LENGTH - g_utf8_strlen(open_image_fmt, -1);
                  char *shortened = gul_string_shorten (file, len);
                  esc_file = gul_string_double_underscores (shortened);
                  g_free(file);
                  g_free(shortened);
            }

            perm_action = galeon_embed_shell_test_permission(embed_shell,
                                                 g_value_get_string(value),
                                                 IMAGES_PERMISSION);

            if (perm_action == DENY_ACTION)
            {
                  block_host_str = g_strdup_printf(_("Allow I_mages From %s"),
                                           host);
                  show_action = ALLOW_IMAGE_SITE_ACTION;
                  hide_action = BLOCK_IMAGE_SITE_ACTION;
            }
            else
            {
                  block_host_str = g_strdup_printf(_("Block I_mages From %s"),
                                           host);
                  hide_action = ALLOW_IMAGE_SITE_ACTION;
                  show_action = BLOCK_IMAGE_SITE_ACTION;
            }

            g_object_set(G_OBJECT(ACTION_ITEM(show_action)),
                       "label", block_host_str, NULL);
            g_object_set(G_OBJECT(ACTION_ITEM(show_action)),
                       "visible", TRUE, NULL);
            g_object_set(G_OBJECT(ACTION_ITEM(hide_action)),
                       "visible", FALSE, NULL);

            open_image_str = g_strdup_printf(open_image_fmt, esc_file);

            g_object_set(G_OBJECT(ACTION_ITEM(OPEN_IMAGE_ACTION)),
                       "label", open_image_str, NULL);

            if (esc_file)
                  g_free(esc_file);

            if (uri)
                  gnome_vfs_uri_unref(uri);

            g_free(block_host_str);
            g_free(open_image_str);

            setup_image_openwith (p);
      }

      if (is_link)
      {
            gboolean is_web_link = 
                  galeon_embed_event_has_property (p->priv->event, 
                                           "link-can-open-in-new-tab");

            g_object_set(G_OBJECT(ACTION_ITEM(OPEN_IN_NEW_TAB_ACTION)),
                       "sensitive", is_web_link, NULL);
            g_object_set(G_OBJECT(ACTION_ITEM(OPEN_IN_NEW_WINDOW_ACTION)),
                       "sensitive", is_web_link, NULL);
      }
}

static void
setup_doc_openwith (GaleonPopup *popup)
{
      const gchar *path = galeon_popup_get_doc_openwith_popup_path (popup);
      char *location;
      GaleonEmbedHelperList *hl = popup->priv->helper_list;
      GtkWidget *menuitem;
      GtkWidget *menu;

      g_return_if_fail (popup->priv->embed != NULL);
      g_return_if_fail (path != NULL);

      menuitem = gtk_ui_manager_get_widget(popup->priv->window->merge, path);
      menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));

      location = galeon_embed_get_location (popup->priv->embed, FALSE, FALSE);
      if (!galeon_embed_helper_list_set_uri (hl, location))
      {
            /* well, it's very probably html */
            galeon_embed_helper_list_add_mime_type (hl, "text/html");
      }
      
      g_free (location);
      
      galeon_embed_helper_list_add_mime_type (hl, "text/plain");
      
      gul_gui_remove_all_children (GTK_CONTAINER (menu));
      galeon_embed_helper_list_add_to_gtk_menu (hl, GTK_MENU_SHELL (menu));
}

static void
setup_document_menu (GaleonPopup *p, gboolean is_framed)
{     
      gboolean has_background, can_view_source;
      GaleonEmbed *embed;

      embed = galeon_popup_get_embed (p);
      can_view_source = galeon_embed_can_view_source (embed);
      g_object_set(G_OBJECT(ACTION_ITEM(VIEW_SOURCE_ACTION)),
                 "sensitive", can_view_source, NULL);
      
      has_background = galeon_embed_event_has_property (p->priv->event,
                                            "background_image");
      g_object_set(G_OBJECT(ACTION_ITEM(SAVE_BACKGROUND_AS_ACTION)),
                 "visible", has_background, NULL);

      setup_doc_openwith (p);

      /* Hide / Show the frame actions */
      g_object_set (ACTION_ITEM("DPOpenFrameAction"), 
                  "visible", is_framed, "sensitive", is_framed, NULL);
      g_object_set (ACTION_ITEM("DPOpenFrameInNewWindowAction"), 
                  "visible", is_framed, "sensitive", is_framed, NULL);
      g_object_set (ACTION_ITEM("DPOpenFrameInNewTabAction"),
                  "visible", is_framed, "sensitive", is_framed, NULL);
      g_object_set (ACTION_ITEM("DPReloadFrameAction"),
                  "visible", is_framed, "sensitive", is_framed, NULL);
}

static void
galeon_popup_setup_menu (GaleonPopup *p)
{
      const GValue *value;
      gboolean is_framed;
      gboolean setup_edit_actions = FALSE;

      g_return_if_fail (GALEON_IS_EMBED_EVENT (p->priv->event));
      g_return_if_fail (GALEON_IS_EMBED (p->priv->embed));

      value = galeon_embed_event_get_property (p->priv->event,
                                     "framed_page");
      is_framed = g_value_get_int (value);

      if (p->priv->context & EMBED_CONTEXT_EMAIL_LINK &&
          p->priv->context & EMBED_CONTEXT_IMAGE)
      {
            p->priv->popup_type = POPUP_IMAGE_EMAIL_LINK;
            setup_element_menu(p);
      }
      else if (p->priv->context & EMBED_CONTEXT_EMAIL_LINK)
      {
            setup_element_menu(p);
            p->priv->popup_type = POPUP_EMAIL_LINK;
            setup_edit_actions = TRUE;
      }
      else if (p->priv->context & EMBED_CONTEXT_LINK &&
             p->priv->context & EMBED_CONTEXT_IMAGE)
      {
            p->priv->popup_type = POPUP_IMAGE_LINK;
            setup_element_menu(p);
      }
      else if (p->priv->context & EMBED_CONTEXT_IMAGE)
      {
            p->priv->popup_type = POPUP_IMAGE;
            setup_element_menu(p);
      }
      else if (p->priv->context & EMBED_CONTEXT_LINK)
      {
            p->priv->popup_type = POPUP_LINK;
            setup_element_menu(p);
            setup_edit_actions = TRUE;
      }
      else if (p->priv->context & EMBED_CONTEXT_INPUT)
      {
            p->priv->popup_type = POPUP_INPUT;
            galeon_window_update_edit_actions_sensitivity (p->priv->window, FALSE);
      }
      else if (p->priv->context & (EMBED_CONTEXT_SIDEBAR))
      {
            p->priv->popup_type = POPUP_DOCUMENT_SIDEBAR;
            setup_document_menu(p, is_framed);
      }
      else
      {
            p->priv->popup_type = POPUP_DOCUMENT_NORMAL;
            setup_document_menu (p, is_framed);
            setup_edit_actions = TRUE;
      }

      if (setup_edit_actions)
      {
            gboolean can_copy;
            can_copy = galeon_embed_selection_can_copy (p->priv->embed);

            g_object_set(G_OBJECT(ACTION_ITEM(COPY_TEXT_ACTION)),
                       "sensitive", can_copy, "visible", can_copy, NULL);

      }
}

static void
galeon_window_bookmark_activated_cb (GObject *sender,
                             GbBookmarkEventActivated *ev,
                             GaleonWindow *w)
{
      galeon_window_bookmark_activate (w, ev);
}

static void
popup_menu_at_coords(GtkMenu *menu, gint *x, gint *y, gboolean *push_in,
                 gpointer user_data)
{
      GaleonPopup *p = user_data;
      GaleonEmbedEvent *event;
      GaleonWindow *window;
      
      event  = galeon_popup_get_event (p);
      window = galeon_popup_get_window (p);

      *x = event->x;
      *y = event->y;
      *push_in = FALSE;

      gul_gui_sanitise_popup_position (menu, GTK_WIDGET (window), x, y);
}

static void
hide_embed_input_popup_cb (GtkWidget *popup,
                     GaleonWindow *window)
{
      galeon_window_enable_edit_actions_sensitivity (window);

      g_signal_handlers_disconnect_by_func
            (popup, G_CALLBACK (hide_embed_input_popup_cb), window);
}

static gboolean
unref_when_idle (gpointer user_data)
{
      GaleonPopup *popup = GALEON_POPUP (user_data);
      if (popup->priv->event)
      {
            g_object_unref (popup->priv->event);
            popup->priv->event = NULL;
      }
      return FALSE;
}

static void
hide_embed_popup_cb (GtkWidget *menu,
                 GaleonPopup *popup)
{
      if (popup->priv->event)
      {
            /* Don't unref the event yet, this function gets called
             * before the menu item's callback is called, so
             * just do the unref on idle */
            g_idle_add (unref_when_idle, popup);
      }

      g_signal_handlers_disconnect_by_func
            (menu, G_CALLBACK (hide_embed_popup_cb), popup);
}

void
galeon_popup_show (GaleonPopup *p, GaleonEmbed *embed)
{
      GtkMenuPositionFunc posfunc = NULL;
      GaleonEmbedEvent *info = NULL;
      GdkEvent *event;
      guint button;
      GbBookmarkSet *bs = galeon_shell_get_bookmark_set (galeon_shell);

      galeon_popup_set_embed(p, embed);
      galeon_popup_setup_menu(p);
      
      /* If and only if the popup is initiated by a mouse button press should
       * we pass the button to gtk_menu_popup, otherwise items in _sub_menus
       * don't activate properly. */
      button = 0;
      event = gtk_get_current_event();
      if (event != NULL)
      {
            if (event->type == GDK_BUTTON_PRESS
                || event->type == GDK_2BUTTON_PRESS
                || event->type == GDK_3BUTTON_PRESS)
            {
                  button = event->button.button;
            }
            else if (event->type == GDK_KEY_PRESS)
            {
                  info = galeon_popup_get_event(p);
                  if (info != NULL && info->keycode != 0)
                  {
                        posfunc = popup_menu_at_coords;
                  }
            }
            gdk_event_free(event);
      }

      p->priv->menu = gtk_ui_manager_get_widget(p->priv->window->merge,
                                      galeon_popup_get_popup_path(GALEON_POPUP(p)));
      g_return_if_fail(p->priv->menu != NULL);

      if (p->priv->popup_type == POPUP_INPUT)
      {
            g_signal_connect (p->priv->menu, "hide",
                          G_CALLBACK (hide_embed_input_popup_cb), p->priv->window);
      }

      g_signal_connect (p->priv->menu, "hide",
                    G_CALLBACK (hide_embed_popup_cb), p);

      if (g_object_get_data (G_OBJECT (p->priv->menu), "GbGtkMenu") == NULL)
      {
            GbGtkMenu *ggm = gb_gtk_menu_new_context_only (bs, GTK_MENU_SHELL (p->priv->menu));
            gb_gtk_menu_set_location_source (ggm, GB_LOCATION_SOURCE (p->priv->window));
            gb_gtk_menu_set_statusbar (ggm, GTK_STATUSBAR (galeon_window_get_statusbar (p->priv->window)));
            gb_gtk_menu_fill_children_submenus (ggm);
            g_signal_connect (ggm, "bookmark-activated", 
                          G_CALLBACK (galeon_window_bookmark_activated_cb), p->priv->window);
            g_object_set_data (G_OBJECT (p->priv->menu), "GbGtkMenu", ggm);
            p->priv->bookmark_menus = g_slist_prepend (p->priv->bookmark_menus, ggm);
      }

      gtk_menu_popup(GTK_MENU(p->priv->menu),
                   NULL, NULL, posfunc, p,
                   button, gtk_get_current_event_time());
}


static void
galeon_popup_set_embed (GaleonPopup *p, GaleonEmbed *e)
{
      g_return_if_fail (GALEON_IS_POPUP (p));
      g_return_if_fail (GALEON_IS_EMBED (e));

      p->priv->embed = e;
      galeon_embed_helper_list_set_embed (p->priv->helper_list, e);
}

GaleonEmbed *
galeon_popup_get_embed (GaleonPopup *p)
{
      g_return_val_if_fail (GALEON_IS_POPUP (p), NULL);

      return p->priv->embed;
}


GaleonEmbedEvent *
galeon_popup_get_event (GaleonPopup *p)
{
      g_return_val_if_fail (GALEON_IS_POPUP (p), NULL);

      return p->priv->event;
}

void 
galeon_popup_set_event (GaleonPopup *p,
                  GaleonEmbedEvent *event)
{
      EmbedEventContext context;

      g_return_if_fail (GALEON_IS_POPUP (p));
      g_return_if_fail (GALEON_IS_EMBED_EVENT (event));

      if (p->priv->event)
      {
            g_object_unref (p->priv->event);
      }

      context = galeon_embed_event_get_context (event);
      
      p->priv->context = context;

      p->priv->event = event;
      g_object_ref (event);
}

static void
galeon_popup_set_window (GaleonPopup *p, GaleonWindow *window)
{
      g_return_if_fail (GALEON_IS_POPUP (p));
      g_return_if_fail (GALEON_IS_WINDOW (window));

      p->priv->window = window;
      p->priv->merge = window->merge;
      gtk_ui_manager_insert_action_group (p->priv->merge, p->priv->action_group, 0);
}

GaleonWindow *
galeon_popup_get_window (GaleonPopup *p)
{
      g_return_val_if_fail (GALEON_IS_POPUP (p), NULL);

      return p->priv->window;
}

static void
galeon_popup_set_property (GObject *object,
                     guint prop_id,
                     const GValue *value,
                     GParamSpec *pspec)
{
      GaleonPopup *p = GALEON_POPUP (object);

      switch (prop_id)
      {
      case PROP_WINDOW:
            galeon_popup_set_window 
                  (p, GALEON_WINDOW (g_value_get_object (value)));
            break;
      case PROP_EVENT:
            galeon_popup_set_event 
                  (p, GALEON_EMBED_EVENT (g_value_get_object (value)));
            break;
      case PROP_EMBED:
            galeon_popup_set_embed 
                  (p, GALEON_EMBED (g_value_get_object (value)));
            break;
      default: 
            break;
      }
}

static void
galeon_popup_get_property (GObject *object,
                     guint prop_id,
                     GValue *value,
                     GParamSpec *pspec)
{
      GaleonPopup *p = GALEON_POPUP (object);
      
      switch (prop_id)
      {
      case PROP_WINDOW:
            g_value_set_object (value, p->priv->window);
            break;
      case PROP_EVENT:
            g_value_set_object (value, p->priv->event);
            break;
      case PROP_EMBED:
            g_value_set_object (value, p->priv->embed);
            break;
      default: 
            break;
      }
}


static void
galeon_popup_finalize (GObject *object)
{
      GaleonPopup *gep = GALEON_POPUP (object);
      GSList *li;
      LOG ("GaleonPopup dtor (%p)", object);

      for (li = gep->priv->bookmark_menus; li; li = li->next)
      {
            g_object_unref (li->data);
      }
      g_slist_free (gep->priv->bookmark_menus);

      if (gep->priv->event)
      {
            g_object_unref (gep->priv->event);
      }     
      
      if (gep->priv->helper_list)
      {
            g_object_unref (gep->priv->helper_list);
      }

      if (gep->priv->action_group)
      {
            g_object_unref (gep->priv->action_group);
      }
      
      g_idle_remove_by_data (object);

      G_OBJECT_CLASS (galeon_popup_parent_class)->finalize (object);
}


static void
galeon_popup_init (GaleonPopup *gep)
{
      GtkAction *action;
      LOG ("GaleonPopup ctor (%p)", gep);

        gep->priv = GALEON_POPUP_GET_PRIVATE (gep);
      gep->priv->embed = NULL;
      gep->priv->event = NULL;
      gep->priv->helper_list = galeon_embed_helper_list_new ();
      gep->priv->window = NULL;
      gep->priv->menu = NULL;
      gep->priv->bookmark_menus = NULL;

      gep->priv->action_group = gtk_action_group_new("EmbedPopupActions");
      gtk_action_group_set_translation_domain (gep->priv->action_group, NULL);
      gtk_action_group_add_actions(gep->priv->action_group,
                             entries, n_entries, gep);

      action = gtk_action_group_get_action (gep->priv->action_group, "EPOpenImageWithMenuAction");
      g_object_set (action, "hide_if_empty", FALSE, NULL);

      action = gtk_action_group_get_action (gep->priv->action_group, "DPOpenWithMenuAction");
      g_object_set (action, "hide_if_empty", FALSE, NULL);
}

static void
galeon_popup_class_init (GaleonPopupClass *klass)
{
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

        object_class->finalize     = galeon_popup_finalize;
      object_class->set_property = galeon_popup_set_property;
      object_class->get_property = galeon_popup_get_property;

      g_object_class_install_property (object_class,
                                         PROP_WINDOW,
                                         g_param_spec_object ("GaleonWindow",
                                                              "GaleonWindow",
                                                              "Parent window",
                                                              GALEON_TYPE_WINDOW,
                                                              G_PARAM_READWRITE |
                                                G_PARAM_CONSTRUCT_ONLY));

      g_object_class_install_property (object_class,
                                         PROP_EVENT,
                                         g_param_spec_object ("event",
                                                              "event",
                                                              "Attached event",
                                                              GALEON_TYPE_EMBED_EVENT,
                                                              G_PARAM_READWRITE ));

      g_object_class_install_property (object_class,
                                         PROP_EVENT,
                                         g_param_spec_object ("embed",
                                                              "embed",
                                                              "Attached embed",
                                                              G_TYPE_OBJECT,
                                                              G_PARAM_READWRITE ));

      g_type_class_add_private (klass, sizeof (GaleonPopupPrivate));
}


GaleonPopup *
galeon_popup_new(GaleonWindow *window)
{
      GaleonPopup *p;
      
        p = g_object_new (GALEON_TYPE_POPUP, 
                    "GaleonWindow", window,
                    NULL);
      
        return p;
}


Generated by  Doxygen 1.6.0   Back to index