Logo Search packages:      
Sourcecode: kazehakase version File versions

kz-actions.c

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

/*
 *  Copyright (C) 2002-2004 Hiroyuki Ikezoe
 *  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.h"

#include <string.h>
#include <glib/gi18n.h>

#include "gtk-utils.h"
#include "glib-utils.h"
#include "utils.h"
#include "kazehakase.h"
#include "kz-window.h"
#include "kz-tab-label.h"
#include "kz-prefs-win.h"
#include "kz-links-dialog.h"
#include "kz-password-manager-dialog.h"
#include "kz-smart-bookmark.h"
#include "kz-bookmark.h"
#include "kz-bookmark-editor.h"
#include "kz-bookmark-edit-win.h"
#include "kz-bookmark-filter.h"
#include "kz-bookmark-file.h"
#include "kz-entry-action.h"
#include "kz-location-entry-action.h"
#include "kz-navigation-action.h"
#include "kz-stop-reload-action.h"
#include "kz-smart-bookmark-action.h"
#include "kz-zoom-action.h"
#include "kz-embed.h"
#include "kz-actions-download.h"
#include "kz-actions-popup.h"
#include "kz-about-dialog.h"
#include "kz-paned.h"
#include "kz-bookmark-menu.h"
#include "kz-autoscroller.h"
#include "kz-popup-tablist.h"
#include "eggregex.h"
#include "kz-proxy-folder.h"

#include <time.h>

#define HTTP_REGEX "(https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+)"

enum {
      UI_BEGINNER,
      UI_MEDIUM,
      UI_EXPERT,
      UI_CUSTOM
};


static GQuark bookmark_quark = 0;


static void
act_save (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      KzEmbed *kzembed;
      gchar *filename;

      g_return_if_fail(KZ_IS_WINDOW(kz));
      g_return_if_fail(KZ_IS_EMBED(widget));
      
      kzembed = KZ_EMBED(widget);
      
      filename = kz_actions_download_open_save_dialog(GTK_WINDOW(kz),
                                          kz_embed_get_location(kzembed),
                                          TRUE);
      if (filename)
      {
            kz_embed_save_with_content(kzembed, filename);
            g_free(filename);
      }     
}


static void
act_close_window (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(KZ_IS_WINDOW(kz));

      kz_window_store_state(kz);
      kz_window_close_all_tab(kz);
      gtk_widget_destroy(GTK_WIDGET(kz));
}


static void
act_close_tab (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      if (widget)
            kz_window_close_tab(kz, widget);
}


static void
act_new_window (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      widget = kz_window_new(NULL);
      gtk_widget_show(widget);
}


static void
cb_remove_idle(KzWindow* kz)
{
      g_idle_remove_by_data(kz);
}


static gboolean
idle_focus_to_loc_ent(gpointer data)
{
      GtkAction *action;
      KzWindow *kz;

      g_return_val_if_fail(KZ_IS_WINDOW(data), FALSE);
      
      kz = KZ_WINDOW(data);
      action = gtk_action_group_get_action(kz->actions,"FocusLocationEntry");

      gtk_action_activate(action);
      g_signal_handlers_disconnect_by_func(kz,
                                   G_CALLBACK(cb_remove_idle), NULL);
      return FALSE;
}

static void
act_new_tab (GtkAction *action, KzWindow *kz)
{
      gboolean focus;
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));
      widget = kz_window_open_new_tab(kz, NULL);

      KZ_CONF_GET("Tab", "focus_open_new", focus, BOOL);
      if(focus && widget)
      {
            int num = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook),
                                    widget);
            if(num != -1)
                  gtk_notebook_set_current_page(GTK_NOTEBOOK(kz->notebook),
                                          num);

            KZ_CONF_GET("Tab","focus_loc_ent_new", focus, BOOL);
            if(focus)
            {
                  g_idle_add(idle_focus_to_loc_ent, kz);
                  g_signal_connect(kz, "destroy",
                               G_CALLBACK(cb_remove_idle), NULL);
            }
      }
}


static void
act_focus_loc_ent (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = NULL;
      GtkAction *ent_ac;

      widget = gtk_ui_manager_get_widget(kz->menu_merge, 
                                 "/MainToolBar/LocationEntry");

      ent_ac = gtk_action_group_get_action(kz->actions, "LocationEntry");

      if(widget)
      {
            GtkEntry *entry;
            entry = kz_entry_action_get_entry_widget(KZ_ENTRY_ACTION(ent_ac),
                                           widget);
            gtk_widget_grab_focus(GTK_WIDGET(entry));
      }
}

static void
act_clear_loc_ent (GtkAction *action, KzWindow *kz)
{
      GtkAction *loc_ent = gtk_action_group_get_action(kz->actions, "LocationEntry");
      GtkAction *focus_action  = gtk_action_group_get_action(kz->actions,
                                                 "FocusLocationEntry");

      kz_entry_action_set_text(KZ_ENTRY_ACTION(loc_ent), "");
      gtk_action_activate(focus_action);
}

static void
act_open_file (GtkAction *action, KzWindow *kz)
{
      GtkWidget *file_dialog;
      gchar *filename = NULL;
      gchar *uri = NULL;
      gint result;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      file_dialog = gtk_file_chooser_dialog_new (_("Open file"),
                                       GTK_WINDOW(kz),
                                       GTK_FILE_CHOOSER_ACTION_OPEN,
                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                       NULL);

      result = gtk_dialog_run(GTK_DIALOG(file_dialog));
      
      switch (result)
      {
       case GTK_RESPONSE_ACCEPT:
            filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_dialog));
            break;
       default:
            break;
      }

      if (filename)
        {
            gchar *utf8, *urlencode, *dirname, *basename;
            basename = g_path_get_basename(filename);
            dirname = g_path_get_dirname(filename);
            utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
            urlencode = url_encode(utf8);
            uri = g_strdup_printf("file://%s/%s", dirname, urlencode);
                g_free(utf8);
                g_free(basename);
                g_free(dirname);
            g_free(urlencode);
            g_free(filename);
        }

      gtk_widget_destroy(file_dialog);

      if (uri)
      {
            kz_window_load_url(kz, uri);
            g_free(uri);
      }
}


static void
act_open_selected_links (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GList *list = NULL, *node;

      if (!KZ_IS_EMBED(widget)) return;

      kz_embed_get_links(KZ_EMBED(widget), &list, TRUE);

      for (node = list; node; node = g_list_next(node))
      {
            KzBookmark *link = node->data;
            const gchar *uri;

            if (!link) continue;

            uri = kz_bookmark_get_link(link);
            if (!uri) continue;

            if (kz_bookmark_filter_out(link)) continue;

            kz_window_open_new_tab_with_parent(KZ_WINDOW(kz), uri,
                                       widget);
      }

      g_list_foreach(list, (GFunc) g_object_unref, NULL);
      g_list_free(list);
}


#warning FIXME! we should unify act_open_selection().
static void
act_open_selected_text (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      gchar *text;
      EggRegex *egg_regex;
      gint n_match, i = 1;
      GError *error = NULL;

      g_return_if_fail (KZ_IS_WINDOW((kz)));
 
      if (!KZ_IS_EMBED(widget)) return;
      
      egg_regex = egg_regex_new(HTTP_REGEX, 
                          0,
                          0, &error);

      if (error)
      {
            g_error_free(error);
            return;
      }

      text = kz_embed_get_selection_string(KZ_EMBED(widget));
      if (!text) return;

      n_match = egg_regex_match(egg_regex, text, -1, 0);
      
      if (n_match > 0)
      {
            gchar **uri;
            uri = egg_regex_fetch_all (egg_regex, text);

            while (uri[i])
            {
                  kz_window_open_new_tab_with_parent(KZ_WINDOW(kz),
                                             uri[i],
                                             widget);
                  i++;
            }
            if (uri)
                  g_strfreev(uri);
      }

      egg_regex_free(egg_regex);
      g_free(text);
}


static void
act_back (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_back(KZ_EMBED(widget));
}


static void
act_forward (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_forward(KZ_EMBED(widget));
}


static void
act_go_up (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_up(KZ_EMBED(widget));
}


static void
act_open_selection (GtkAction *action, KzWindow *kz)
{
      GtkAction *entry;
      GtkClipboard *clipboard;
      gchar *text;
 
      g_return_if_fail (KZ_IS_WINDOW((kz)));
 
      entry = gtk_action_group_get_action(kz->actions, "LocationEntry");
 
      clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);

      text = gtk_clipboard_wait_for_text(clipboard);
      if (text)
      {
            kz_entry_action_set_text (KZ_ENTRY_ACTION (entry), text);
            gtk_action_activate(entry);
            g_free (text);
      }
}


static void
act_go_location (GtkAction *action, KzWindow *kz)
{
      GtkAction *entry;

      g_return_if_fail(KZ_IS_WINDOW(kz)); 

      entry = gtk_action_group_get_action(kz->actions, "LocationEntry");
        gtk_action_activate(entry);
}


static void
act_index (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_nav_link(KZ_EMBED(widget), KZ_EMBED_LINK_INDEX);
}


static void
act_contents (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_nav_link(KZ_EMBED(widget), KZ_EMBED_LINK_CONTENTS);
}


static void
act_start (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_nav_link(KZ_EMBED(widget), KZ_EMBED_LINK_START);
}


static void
act_prev (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_nav_link(KZ_EMBED(widget), KZ_EMBED_LINK_PREV);
}


static void
act_next (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_go_nav_link(KZ_EMBED(widget), KZ_EMBED_LINK_NEXT);
}


static void 
act_stop (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
            kz_embed_stop_load(KZ_EMBED(widget));
}


static void
act_reload  (GtkAction *action, KzWindow *kz)
{
      GdkModifierType state = (GdkModifierType)0;
      gint x, y;
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      gdk_window_get_pointer(NULL, &x, &y, &state);

      widget = KZ_WINDOW_CURRENT_PAGE(kz);

      if (KZ_IS_EMBED(widget))
            kz_embed_reload(KZ_EMBED(widget),
                        (state & GDK_SHIFT_MASK) ?
                        KZ_EMBED_RELOAD_BYPASS_PROXY_AND_CACHE : 
                        KZ_EMBED_RELOAD_NORMAL);
}


static void 
act_stop_all (GtkAction *action, KzWindow *kz)
{
      gint i, num;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      for (i = num - 1; i >= 0; i--)
      {
            GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kz, i);

            if (KZ_IS_EMBED(widget))
                  kz_embed_stop_load(KZ_EMBED(widget));
      }
}

static void
act_reload_all  (GtkAction *action, KzWindow *kz)
{
      GdkModifierType state = (GdkModifierType)0;
      gint x, y;
      gint i, num;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      gdk_window_get_pointer(NULL, &x, &y, &state);

      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      for (i = num - 1; i >= 0; i--)
      {
            GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kz, i);

            if (KZ_IS_EMBED(widget))
                  kz_embed_reload(KZ_EMBED(widget),
                              (state & GDK_SHIFT_MASK) ?
                              KZ_EMBED_RELOAD_BYPASS_CACHE : 
                              KZ_EMBED_RELOAD_NORMAL);
      }
}


static void 
act_view_source (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GtkWidget *newtab;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
      {
            newtab = kz_window_open_new_tab(kz, NULL);

            kz_embed_copy_page(KZ_EMBED(widget),
                           KZ_EMBED(newtab));
            kz_embed_view_source(KZ_EMBED(newtab),
                             kz_embed_get_location(KZ_EMBED(widget)));
      }
}

#if 0
static void 
act_set_edit_mode (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
      {
            kz_embed_set_edit_mode(KZ_EMBED(widget));
      }
}

static void 
act_set_view_mode (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
      {
            kz_embed_set_view_mode(KZ_EMBED(widget));
      }
}
#endif

static void
act_popup_context_menu (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(GTK_IS_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));

      kz_actions_popup_menu_modal(kz, 0, 0);
}

static void
act_find (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(GTK_IS_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));

      gtk_widget_grab_focus(kz->find_area);
}

static void
act_prev_tab (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(KZ_IS_WINDOW(kz));

      gtk_notebook_prev_page(GTK_NOTEBOOK(kz->notebook));
}


static void
act_next_tab (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(KZ_IS_WINDOW(kz));

      gtk_notebook_next_page(GTK_NOTEBOOK(kz->notebook));
}


static void
act_preference (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = kz_prefs_win_get_instance();
      gtk_window_set_transient_for (GTK_WINDOW(widget), GTK_WINDOW(kz));
      gtk_widget_show (widget);
      gdk_window_raise(widget->window);
}


static void
act_detaild_preference (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;
      gint num;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      widget = kz_window_open_new_tab(kz, "about:config");
      num = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook), widget);
      gtk_notebook_set_current_page(GTK_NOTEBOOK(kz->notebook), num);
}


static void
act_ui_level (GtkRadioAction *action, GtkRadioAction *cur_action, KzWindow *kz)
{
      gint value;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      value = gtk_radio_action_get_current_value(action);

      switch (value) {
      case UI_BEGINNER:
            KZ_CONF_SET_STR("Global", "ui_level", "beginner");
            break;
      case UI_MEDIUM:
            KZ_CONF_SET_STR("Global", "ui_level", "medium");
            break;
      case UI_EXPERT:
            KZ_CONF_SET_STR("Global", "ui_level", "expert");
            break;
      case UI_CUSTOM:
            KZ_CONF_SET_STR("Global", "ui_level", "custom");
            break;
      default:
            break;
      }
}


static void
act_undo (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));
      
      if (GTK_IS_EDITABLE (widget))
        {
        }
      else
      {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
            kz_embed_do_command(kzembed,
                            "cmd_undo");
      }
}


static void
act_redo (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));
      
      if (GTK_IS_EDITABLE (widget))
        {
        }
      else
      {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
            kz_embed_do_command(kzembed,
                            "cmd_redo");
      }
}


static void
act_cut (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));

        if (GTK_IS_EDITABLE (widget))
        {
                gtk_editable_cut_clipboard (GTK_EDITABLE (widget));
        }
        else
        {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
                kz_embed_cut_selection (kzembed);
        }
}


static void
act_copy (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));

        if (GTK_IS_EDITABLE (widget))
        {
                gtk_editable_copy_clipboard (GTK_EDITABLE (widget));
        }
        else
        {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
                kz_embed_copy_selection (kzembed);
        }
}

static void
act_paste (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));

        if (GTK_IS_EDITABLE (widget))
        {
                gtk_editable_paste_clipboard (GTK_EDITABLE (widget));
        }
        else
        {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
                kz_embed_paste (kzembed);
        }
}


static void
act_select_all (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      widget = gtk_window_get_focus(GTK_WINDOW(kz));

        if (GTK_IS_EDITABLE (widget))
        {
                gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
        }
        else
        {
                KzEmbed *kzembed;

                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
                if (!KZ_IS_EMBED(kzembed)) return;
                kz_embed_select_all (kzembed);
        }
}


static void
act_copy_title (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;
      const gchar *text;

      g_return_if_fail(KZ_IS_WINDOW (kz));

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

      text = kz_embed_get_title(KZ_EMBED(widget));
      gtkutil_copy_text(text);
}


static void
act_copy_url (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;
      const gchar *text;

      g_return_if_fail(KZ_IS_WINDOW (kz));

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

      text = kz_embed_get_location(KZ_EMBED(widget));
      gtkutil_copy_text(text);
}

static void
act_copy_in_user_format(GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;
      gchar *text;
      gchar *format;
      gchar **splited = NULL;
      gint counts = 0;
      gint i;
      gchar *str = NULL;

      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("");

      format = KZ_CONF_GET_STR("Global" , "copy_document_format1");
      if(!format) return;

      for(i = 0;format[i] != '\0';i++)
            if(format[i] == '%') counts++;
      counts++;
      
      if(counts != 1)
      {
            gchar **temp = g_alloca(sizeof(gchar*) * (counts + 1));
            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
act_get_body_text (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      g_return_if_fail(KZ_IS_WINDOW(kz));

      if (KZ_IS_EMBED(widget))
      {
            gchar *text = kz_embed_get_body_text(KZ_EMBED(widget));
            g_free(text);
      }
}


static void
act_tab_pos (GtkRadioAction *action, GtkRadioAction *cur_action, KzWindow *kz)
{
      gint value;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      value = gtk_radio_action_get_current_value(cur_action);

      gtk_notebook_set_tab_pos(GTK_NOTEBOOK(kz->notebook), value);
}


static void
act_tab_close_backward_all (GtkAction *action, KzWindow *kz)
{
      gint i, pos, num;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(kz->notebook));
      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      for (i = pos - 1; i >= 0; i--)
      {
            GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kz, i);

            kz_window_close_tab(kz, widget);
      }
}


static void
act_tab_close_forward_all (GtkAction *action, KzWindow *kz)
{
      gint i, pos, num;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(kz->notebook));
      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      for (i = num - 1; i > pos; i--)
      {
            GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kz, i);

            kz_window_close_tab(kz, widget);
      }
}


static void
act_tab_close_all_without_active (GtkAction *action, KzWindow *kz)
{
      gint i, pos, num;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(kz->notebook));
      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      for (i = num - 1; i >= 0; i--)
      {
            GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kz, i);

            if (i == pos) continue;
            kz_window_close_tab(kz, widget);
      }
}


static void
act_bookmark_in_new_tab (GtkAction *action, KzWindow *kz)
{
      KzBookmark *bookmark;
      const gchar *uri;

      bookmark = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

      uri = kz_bookmark_get_link(bookmark);
      if (uri)
            kz_window_open_new_tab(kz, uri);
}


static void
open_all_bookmarks(KzWindow *kz, KzBookmark *folder, GtkWidget *parent,
               gboolean recurse)
{
      GList *children, *node;
      const gchar *uri;

      folder = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));
      g_return_if_fail(kz_bookmark_is_folder(folder));

      children = kz_bookmark_get_children(folder);
      for (node = children; node; node = g_list_next(node))
      {
            KzBookmark *item = node->data;
            GtkWidget *widget = parent;

            uri = kz_bookmark_get_link(item);
            if (uri)
                  widget = kz_window_open_new_tab_with_parent(kz, uri,
                                                    parent);

            if (kz_bookmark_is_folder(item) && recurse)
                  open_all_bookmarks(kz, item, widget, recurse);
      }
      g_list_free(children);
}


static void
act_open_all_bookmarks (GtkAction *action, KzWindow *kz)
{
      KzBookmark *folder;
      GtkWidget *parent = NULL;
      const gchar *uri;
      gboolean confirm;
      
      folder = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));
      g_return_if_fail(kz_bookmark_is_folder(folder));

      /* confirmation */
      KZ_CONF_GET("Global", "confirm_open_bookmarks", confirm, BOOL);
      if (confirm)
      {
            GtkWidget *dialog;
            gint res;
            dialog = gtk_message_dialog_new(GTK_WINDOW(kz),
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                    GTK_MESSAGE_QUESTION,
                                    GTK_BUTTONS_YES_NO,
                                    _("Open all bookmarks in this bookmark folder ?"));
            gtk_dialog_set_default_response(GTK_DIALOG(dialog),
                                    GTK_RESPONSE_YES);
            res = gtk_dialog_run(GTK_DIALOG(dialog));
            gtk_widget_destroy(dialog);
      
            if (res == GTK_RESPONSE_NO) return;
      }


      uri = kz_bookmark_get_link(folder);
      if (uri)
            parent = kz_window_open_new_tab_with_parent(kz, uri, parent);

      open_all_bookmarks(kz, folder, parent, FALSE);
}


static void
act_open_all_bookmarks_recursive (GtkAction *action, KzWindow *kz)
{
      KzBookmark *folder;
      GtkWidget *parent = NULL;
      const gchar *uri;

      folder = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));
      g_return_if_fail(kz_bookmark_is_folder(folder));

      uri = kz_bookmark_get_link(folder);
      if (uri)
            parent = kz_window_open_new_tab_with_parent(kz, uri, parent);

      open_all_bookmarks(kz, folder, parent, TRUE);
}


static void
act_add_bookmark (GtkAction *action, KzWindow *kz)
{
      KzBookmark *folder, *bookmark, *sibling = NULL;
      KzBookmark *file;
      GtkWidget *widget;
      const gchar *title, *uri;
      gchar *desc;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      folder = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));

      if (!kz_bookmark_is_folder(folder))
      {
            sibling = folder;
            folder = kz_bookmark_get_parent(folder);
            g_return_if_fail(KZ_IS_BOOKMARK(folder));
      }

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

      title = kz_embed_ensure_title(KZ_EMBED(widget));
      uri   = kz_embed_get_location(KZ_EMBED(widget));
      desc  = kz_embed_get_selection_string(KZ_EMBED(widget));

      if (!uri) return;

      bookmark = kz_bookmark_new_with_attrs(title, uri, desc);
      /* FIXME! show dialog */
      if (sibling)
            kz_bookmark_insert_before(folder, bookmark, sibling);
      else
            kz_bookmark_append(folder, bookmark);
      
      if (KZ_IS_BOOKMARK_FILE(folder))
            file = folder;
      else
            file = kz_bookmark_get_parent_file(folder);
      
      if (kz_bookmark_file_has_xmlrpc(KZ_BOOKMARK_FILE(file)))
      {
            kz_bookmark_file_xmlrpc_insert(KZ_BOOKMARK_FILE(file),
                                     folder,
                                     sibling,
                                     bookmark);
      }
      else
      {
            kz_bookmark_file_save(KZ_BOOKMARK_FILE(file));
      }

      if (desc)
            g_free(desc);

      g_object_unref(G_OBJECT(bookmark));
}


static void
act_remove_bookmark (GtkAction *action, KzWindow *kz)
{
      KzBookmark *folder, *bookmark;
      KzBookmark *file;
      const gchar *id;
      gboolean has_xmlrpc;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      bookmark = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

      folder = kz_bookmark_get_parent(bookmark);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));

      id = kz_bookmark_get_id(bookmark);
      if (KZ_IS_BOOKMARK_FILE(folder))
            file = folder;
      else
            file = kz_bookmark_get_parent_file(folder);

      has_xmlrpc = kz_bookmark_file_has_xmlrpc(KZ_BOOKMARK_FILE(file));
      if (has_xmlrpc)
      {
            kz_bookmark_file_xmlrpc_remove(KZ_BOOKMARK_FILE(file),
                                     bookmark);
      }

      kz_bookmark_remove(folder, bookmark);
      
      if (!has_xmlrpc)
            kz_bookmark_file_save(KZ_BOOKMARK_FILE(file));
}


static void
act_edit_bookmark (GtkAction *action, KzWindow *kz)
{
      KzBookmark *bookmark;
      GtkWidget *widget;
      gboolean is_folder, is_file, children_is_editable;

      bookmark = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

      is_folder = kz_bookmark_is_folder(bookmark);
      is_file   = KZ_IS_BOOKMARK_FILE(bookmark);
      children_is_editable = is_file ?
            kz_bookmark_file_is_editable(KZ_BOOKMARK_FILE(bookmark)) : TRUE;

      if (is_folder && children_is_editable)
      {
            widget = kz_bookmark_editor_new(bookmark);
            gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(kz));
            gtk_widget_show (widget);
            gdk_window_raise(widget->window);
      }
      else
      {
            widget = kz_bookmark_edit_win_new(bookmark);
            gtk_widget_show(widget);
      }
}


static void
act_edit_bookmark_bars (GtkAction *action, KzWindow *kz)
{
      KzBookmark *bookmark;
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      bookmark = kz_bookmarks->bookmark_bars;
      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));
      g_return_if_fail(kz_bookmark_is_folder(bookmark));

      widget = kz_bookmark_editor_new(bookmark);
      gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(kz));
      gtk_widget_show (widget);
      gdk_window_raise(widget->window);
}

static void
act_edit_smart_bookmarks (GtkAction *action, KzWindow *kz)
{
      KzBookmark *bookmark;
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      bookmark = kz_bookmarks->smarts;
      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));
      g_return_if_fail(kz_bookmark_is_folder(bookmark));

      widget = kz_bookmark_editor_new(bookmark);
      gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(kz));
      gtk_widget_show (widget);
      gdk_window_raise(widget->window);
}


static void
act_update_bookmark (GtkAction *action, KzWindow *kz)
{
      KzBookmark *folder;

      folder = kz_actions_get_bookmark_for_action(kz);
      g_return_if_fail(KZ_IS_BOOKMARK(folder));
      g_return_if_fail(kz_bookmark_is_folder(folder));

      kz_bookmark_file_load_start(KZ_BOOKMARK_FILE(folder));
}


static void
act_clip_selection (GtkAction *action, KzWindow *kz)
{
      KzBookmark *clip = kz_bookmarks->clip, *bookmark;
      GtkWidget *embed;
      const gchar *title, *uri;
      gchar *source = NULL;
      GTimeVal now;
      struct tm *date = NULL;
      time_t t;
      gchar time_string[20];
      gchar *filename, *htmlname = NULL, *dirname, *link, *name;
      gchar *pos, *full_htmlname;
      GIOChannel *io;

      if (!KZ_IS_WINDOW(kz)) return;

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

      g_get_current_time(&now);

      title = kz_window_get_title(kz);
      uri   = kz_window_get_uri(kz);
      
      /* create dir */
      t = (time_t)now.tv_sec;
      date = localtime(&t);
      strftime(time_string, 20, "%Y%m%d%H%M%S", date);

      name = create_filename_from_uri(uri);
      pos = strchr(name, '?');
      if (pos)
            htmlname = g_strndup(name, pos - name);
      else
            htmlname = g_strdup(name);
      g_free(name);
      name = htmlname;

      pos = strchr(name, '#');
      if (pos)
            htmlname = g_strndup(name, pos - name);
      else
            htmlname = g_strdup(name);
      g_free(name);

      full_htmlname = g_strconcat(htmlname, ".html", NULL);

      dirname = g_strconcat("clips/", htmlname, time_string, NULL);
      make_dir(dirname);

      source  = kz_embed_get_html_with_contents(KZ_EMBED(embed),
                                      dirname);

      filename = g_build_filename(g_get_home_dir(),
                            "."PACKAGE,
                            dirname,
                            full_htmlname,
                                  NULL);
      
      /* save */
      io = g_io_channel_new_file(filename, "w", NULL);
      g_io_channel_set_encoding(io, NULL, NULL);
      g_io_channel_write_chars(io, source, g_strlen(source),
                         NULL, NULL);
      g_io_channel_shutdown(io, TRUE, NULL);
      g_io_channel_unref(io);

      if (source)
            g_free(source);
      link = g_strconcat("file://", filename, NULL);
      bookmark = kz_bookmark_new_with_attrs(title, link, NULL);
      
      /* set the original URI */
      kz_bookmark_file_set_location(KZ_BOOKMARK_FILE(bookmark), uri);
      
      kz_bookmark_prepend(clip, bookmark);
      kz_bookmark_file_save(KZ_BOOKMARK_FILE(kz_bookmarks->clip));
      
      g_free(link);
      g_free(filename);
      g_free(dirname);
      g_free(htmlname);
      g_free(full_htmlname);
}

static void
act_extract_links (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GtkWidget *dialog;

      if (!KZ_IS_EMBED(widget)) return;

      dialog = kz_links_dialog_new(kz, KZ_EMBED(widget), FALSE);
      gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(kz));
      gtk_widget_show(dialog);
}


static void
act_extract_selected_links (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GtkWidget *dialog;

      if (!KZ_IS_EMBED(widget)) return;

      dialog = kz_links_dialog_new(kz, KZ_EMBED(widget), TRUE);
      gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(kz));
      gtk_widget_show(dialog);
}


#warning these codes about session will be obsolete. we need changing session function.
static void
act_save_session (GtkAction *action, KzWindow *kz)
{
      /*FIXME! set current tab position */ 
      kz_bookmark_file_save(KZ_BOOKMARK_FILE(kz_bookmarks->current_session));
}


static void
act_restore_session (GtkAction *action, KzWindow *kz)
{
      GList *list, *node;
      gchar *current_session;
      gint i, num, pos = 0;

      g_return_if_fail(KZ_IS_WINDOW (kz));

      if (is_restoring_session) return;
#if 1
      {
      GList *window_list, *window_node;
      KzBookmark *tmp_bookmark;

      /* reload from current session file */
      current_session  = g_build_filename(g_get_home_dir(),
                                  "."PACKAGE,
                                  "current_session.xml",
                                   NULL);
      if (!g_file_test(current_session, G_FILE_TEST_EXISTS))
            return;
      tmp_bookmark = KZ_BOOKMARK(kz_bookmark_file_new(current_session,
                                 _("Current Session"),
                                 "XBEL"));
      g_free(current_session);
      kz_bookmark_file_load(KZ_BOOKMARK_FILE(tmp_bookmark));

      window_list = kz_window_get_window_list();
      for (node = window_list; node; node = g_list_next (node))
      {
            KzWindow *window = KZ_WINDOW(node->data);
            num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook));
            for (i = num - 1; i >= 0; i--)
            {
                  GtkWidget *widget = KZ_WINDOW_NTH_PAGE(window, i);
                  kz_window_close_tab(window, widget);
            }
      }

      list = kz_bookmark_get_children(tmp_bookmark);

      window_node = window_list;
      /* windows */
      for (node = list; node; node = g_list_next(node))
      {
            GList *tabs, *tabnode;
            KzWindow *window;
            KzBookmark *window_bookmark = KZ_BOOKMARK(node->data);
            tabs = kz_bookmark_get_children(window_bookmark);

            if (!window_node)
            {
                  window = KZ_WINDOW(kz_window_new(NULL));
                  gtk_widget_show(GTK_WIDGET(window));
            }
            else
                  window = KZ_WINDOW(window_node->data);
      
            /* tabs */
            for (tabnode = tabs; tabnode; tabnode = g_list_next(tabnode))
            {
                  GtkWidget *widget;
                  KzBookmark *child = KZ_BOOKMARK(tabnode->data);

                  widget = kz_window_open_new_tab_at_tail(window, NULL);
                  kz_embed_set_history(KZ_EMBED(widget), child);
                  if (kz_bookmark_get_lock(child))
                  {
                        KzTabLabel *kztab;
                        kztab = KZ_TAB_LABEL(gtk_notebook_get_tab_label(GTK_NOTEBOOK(window->notebook),
                                                            widget));
                        kz_tab_label_set_lock(kztab, TRUE);
                  }
                  if (kz_bookmark_get_auto_refresh(child))
                  {
                        KzTabLabel *kztab;
                        kztab = KZ_TAB_LABEL(gtk_notebook_get_tab_label(GTK_NOTEBOOK(window->notebook),
                                                            widget));
                        kz_tab_label_set_auto_refresh(kztab, TRUE);
                  }
            }
            g_list_free(tabs);
            pos = kz_bookmark_get_current(window_bookmark);
            gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), pos);

            if (window_node)
                  window_node = g_list_next(window_node);
      }
      g_list_free(list);

      for (;window_node; window_node = g_list_next(window_node))
      {
            KzWindow *window = KZ_WINDOW(window_node->data);
            gtk_widget_destroy(GTK_WIDGET(window));
      }
      
      kz_bookmark_file_save(KZ_BOOKMARK_FILE(tmp_bookmark));
      g_object_unref(tmp_bookmark);
      }
#endif
}


static void
act_about (GtkAction *action, KzWindow *kz)
{
      g_return_if_fail(KZ_IS_WINDOW(kz));
      kz_about_dialog_new(kz);
}


static void
act_copy_tab (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      KzEmbed *kzembed, *dkzembed;

      g_return_if_fail(KZ_IS_WINDOW(kz));
      g_return_if_fail(KZ_IS_EMBED(widget));
      
      kzembed  = KZ_EMBED(widget);  
      dkzembed = KZ_EMBED(kz_window_open_new_tab(kz, NULL));

      kz_embed_copy_page(kzembed, dkzembed);
      kz_embed_shistory_copy(kzembed, dkzembed, TRUE, TRUE, TRUE);
}


static void
act_sidebar_pos (GtkRadioAction *action, GtkRadioAction *cur_action, KzWindow *kz)
{
      gint value;

      g_return_if_fail(KZ_IS_WINDOW(kz));

      value = gtk_radio_action_get_current_value(action);
      kz_paned_set_position(KZ_PANED(kz->pane), value);
}


static void
act_print (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

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

      kz_embed_print(KZ_EMBED(widget));
}

static void
act_print_preview (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget;

      g_return_if_fail(KZ_IS_WINDOW (kz));

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

      kz_embed_print_preview(KZ_EMBED(widget));
}


static void
act_show_password_manager (GtkAction *action, KzWindow *kz)
{
      GtkWidget *dialog;

      dialog = kz_password_manager_dialog_new(kz);
      gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(kz));
      gtk_widget_show(dialog);
}

static void
act_decrease_text_size (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      gint ratio;

      if (!KZ_IS_EMBED(widget)) return;

      ratio = kz_embed_get_text_size(KZ_EMBED(widget));
      ratio = ratio - 10;

      if (ratio > 0)
      {
            GtkAction *zoom;
            kz_embed_set_text_size(KZ_EMBED(widget), ratio, TRUE);

            zoom = gtk_action_group_get_action(kz->actions, "Zoom");
              kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                               ratio);
      }
}

static void
act_increase_text_size (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      gint ratio;

      if (!KZ_IS_EMBED(widget)) return;

      ratio = kz_embed_get_text_size(KZ_EMBED(widget));
      ratio = ratio + 10;

      if (ratio < 1000)
      {
            GtkAction *zoom;
            kz_embed_set_text_size(KZ_EMBED(widget), ratio, TRUE);

            zoom = gtk_action_group_get_action(kz->actions, "Zoom");
              kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                               ratio);
      }
}


static void
act_normal_text_size (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GtkAction *zoom;

      if (!KZ_IS_EMBED(widget)) return;

      kz_embed_set_text_size(KZ_EMBED(widget), 100, TRUE);
      
      zoom = gtk_action_group_get_action(kz->actions, "Zoom");
        kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                         100);
                              
}


static void
act_zoom_out (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      gint ratio;

      if (!KZ_IS_EMBED(widget)) return;

      ratio = kz_embed_zoom_get(KZ_EMBED(widget));
      ratio = ratio - 10;

      if (ratio > 0)
      {
            GtkAction *zoom;
            kz_embed_zoom_set(KZ_EMBED(widget), ratio, TRUE);

            zoom = gtk_action_group_get_action(kz->actions, "Zoom");
              kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                               ratio);
      }
}

static void
act_zoom_in (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      gint ratio;

      if (!KZ_IS_EMBED(widget)) return;

      ratio = kz_embed_zoom_get(KZ_EMBED(widget));
      ratio = ratio + 10;

      if (ratio < 1000)
      {
            GtkAction *zoom;
            kz_embed_zoom_set(KZ_EMBED(widget), ratio, TRUE);

            zoom = gtk_action_group_get_action(kz->actions, "Zoom");
              kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                               ratio);
      }
}


static void
act_zoom_100 (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
      GtkAction *zoom;

      if (!KZ_IS_EMBED(widget)) return;

      kz_embed_zoom_set(KZ_EMBED(widget), 100, TRUE);
      
      zoom = gtk_action_group_get_action(kz->actions, "Zoom");
        kz_zoom_action_set_ratio(KZ_ZOOM_ACTION(zoom),
                         100);
}


static void
act_page_up (GtkAction *action, KzWindow *kz)
{
      GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);

      if (!KZ_IS_EMBED(widget)) return;

      kz_embed_page_up(KZ_EMBED(widget));
}

static void
act_page_down (GtkAction *action, KzWindow *kz)
{
      GtkAccelKey key;
      GtkWidget *widget;

      widget = gtk_window_get_focus(GTK_WINDOW(kz));

        if (GTK_IS_EDITABLE(widget))
        {
            GdkEvent *event;
            event = gdk_event_new(GDK_KEY_PRESS);
            gtk_accel_map_lookup_entry("<Actions>/KzWindow/PageDown", &key);
            event->key.keyval = key.accel_key;
            gtk_propagate_event(widget, event);
            gdk_event_free(event);
        }
        else
        {
                KzEmbed *kzembed;
                kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE (kz));
            kz_embed_page_down(KZ_EMBED(kzembed));
        }
}

static void
act_auto_scroll_mode (GtkAction *action, KzWindow *kz)
{
      gint x, y;
      GdkDisplay *display;
      GtkWidget *widget;
      KzAutoscroller *as;

      g_return_if_fail(KZ_IS_WINDOW(kz));

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

      display = gtk_widget_get_display (widget);
      as = kz_autoscroller_new ();
      gdk_display_get_pointer (display, NULL, &x, &y, NULL);
      kz_autoscroller_set_embed (as, KZ_EMBED(widget));
      kz_autoscroller_start_scroll (as, GTK_WIDGET (kz), x, y);
      g_object_unref (as);
}


static void
cb_thumbnail_tablist_selected (KzPopupTablist *popup, 
                         KzBookmark* tab, gint index,
                         KzWindow* kz)
{
      gtk_notebook_set_current_page(GTK_NOTEBOOK(kz->notebook), index);

      gtk_widget_destroy(GTK_WIDGET(popup));
      kz->popup_tablist = NULL;
}

static void
act_thumbnail_tablist (GtkAction *action, KzWindow *kz)
{
      KzBookmark *proxy;
      
      if (!kz->popup_tablist)
            kz->popup_tablist = kz_popup_tablist_new(kz);

      proxy = kz_proxy_folder_new(kz->tabs);
      g_signal_connect(kz->popup_tablist, "selected",
                   G_CALLBACK(cb_thumbnail_tablist_selected), kz);
/* to keep KzPopupTablist from adhering to KzWindow, I can't pass KzWindow to KzPopupTablist directly... */
      kz_popup_tablist_show(KZ_POPUP_TABLIST(kz->popup_tablist), proxy);
      g_object_unref(proxy);
}

/* toggle actios */
static void
act_show_hide_sidebar (GtkAction *action, KzWindow *kz)
{
      gboolean active;
      g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));
      g_return_if_fail(GTK_IS_WIDGET(kz->sidebar));

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action));
      if (active)
            gtk_widget_show(kz->sidebar);
      else
            gtk_widget_hide(kz->sidebar);

      KZ_WINDOW_SET_VISIBLE(kz, "StockSidebarPosMenu", active);
}

static void
act_toggle_proxy_use (GtkAction *action, KzWindow *kz)
{
      gboolean use;
      g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));

      use = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action));
      KZ_CONF_SET("Global", "use_proxy", use, BOOL);
      KZ_WINDOW_SET_VISIBLE(kz, "StockProxyMenu", use);
}


static void
act_show_hide_bookmarkbars (GtkAction *action, KzWindow *kz)
{
      gboolean active;
      g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));
      g_return_if_fail(GTK_IS_WIDGET(kz->bookmark_bars_area));

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action));
      if (active)
            gtk_widget_show(kz->bookmark_bars_area);
      else
            gtk_widget_hide(kz->bookmark_bars_area);
}

static void
act_view_fullscreen (GtkAction *action, KzWindow *kz)
{
      gboolean active;
      g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
      g_return_if_fail(KZ_IS_WINDOW(kz));

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action));
      if (active)
      {
            gtk_window_fullscreen(GTK_WINDOW(kz));
            gtk_widget_hide(kz->bookmark_bars_area);
            gtk_widget_hide(kz->statusbar_area);
            gtk_widget_hide(kz->menu_box);
            gtk_notebook_set_show_tabs(GTK_NOTEBOOK(kz->notebook), FALSE);
      
      }
      else
      {
            GtkAction *toggle_action;
            gboolean toggle_active;

            gtk_window_unfullscreen(GTK_WINDOW(kz));
            gtk_widget_show(kz->statusbar_area);
            gtk_widget_show(kz->menu_box);
            gtk_notebook_set_show_tabs(GTK_NOTEBOOK(kz->notebook), TRUE);
            
            toggle_action = gtk_action_group_get_action(kz->actions,
                                              "ShowHideBookmarkbars");
            toggle_active = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(toggle_action));
            if (toggle_active)
                  gtk_widget_show(kz->bookmark_bars_area);
      }
}

#define CTRL "<control>"
#define SHFT "<shift>"
#define SFCT "<shift><control>"
#define ALT  "<alt>"
GtkActionEntry kz_actions[] =
{
  {"StockFileMenu",           NULL, N_("_File"),       NULL, NULL, NULL},
  {"StockEditMenu",           NULL, N_("_Edit"),       NULL, NULL, NULL},
  {"StockViewMenu",           NULL, N_("_View"),       NULL, NULL, NULL},
  {"StockTabMenu",            NULL, N_("_Tab"),        NULL, NULL, NULL},
  {"StockGoMenu",             NULL, N_("_Go"),         NULL, NULL, NULL},
  {"StockBookmarksMenu",      NULL, N_("_Bookmarks"),  NULL, NULL, NULL},
  {"StockOtherBookmarksMenu", NULL, N_("Other Bookmarks"),   NULL, NULL, NULL},
  {"StockToolsMenu",          NULL, N_("Too_ls"),      NULL, NULL, NULL},
  {"StockHelpMenu",           NULL, N_("_Help"),       NULL, NULL, NULL},
  {"StockUILevelMenu",        NULL, N_("UI Level"),    NULL, NULL, NULL},
  {"StockTabPosMenu",         NULL, N_("Tab _position"),     NULL, NULL, NULL},
  {"StockSidebarPosMenu",     NULL, N_("Sidebar position"),  NULL, NULL, NULL},
  {"StockInputMethodMenu",    NULL, N_("Input Methods"),     NULL, NULL, NULL},
  {"StockSessionMenu",        NULL, N_("Session"),           NULL, NULL, NULL},
  {"StockProxyMenu",          NULL, N_("Proxy"),             NULL, NULL, NULL},
  {"StockRecentCloseTabMenu", NULL, N_("Recent closed tabs"), NULL, NULL, NULL},
  {"StockClipMenu",           NULL, N_("Clip"),        NULL, NULL, NULL},

  {"NewWindow", KZ_STOCK_NEW_WINDOW, N_("_New Window"), CTRL"N",  N_("Open a new windw"), G_CALLBACK(act_new_window)},
  {"NewTab",    GTK_STOCK_NEW,       N_("New _Tab"),    CTRL"T",  N_("Open a new tab"), G_CALLBACK(act_new_tab)},

  {"FocusLocationEntry",        NULL, N_("Focus to location entry"),  NULL, N_("Move keyboard focus to location entry"), G_CALLBACK(act_focus_loc_ent)},
  {"ClearLocationEntry",        NULL, N_("Clear location entry and move keyboard focus to location entry"),  NULL, N_("Clear location entry and move keyboard focus to location entry"), G_CALLBACK(act_clear_loc_ent)},
  {"OpenSelection",         NULL,           N_("Open selection"),     NULL,     N_("Open selected text with smart bookmark of location entry"), G_CALLBACK(act_open_selection)},
  {"OpenSelectedText",         NULL,           N_("Open selected text"),     NULL,     N_("Open URIs extracted from selected text "), G_CALLBACK(act_open_selected_text)},
  {"Open",              GTK_STOCK_OPEN,     N_("_Open File..."),       CTRL"O",  N_("Open a local file"), G_CALLBACK(act_open_file)},

  {"OpenSelectedLinks", KZ_STOCK_OPEN_SELECTED_LINK, N_("Open selected links"), CTRL"G",  N_("Open slected links"), G_CALLBACK(act_open_selected_links)},

  {"CloseWindow",    KZ_STOCK_CLOSE_WINDOW, N_("_Close Window"),       CTRL"Q",  N_("Close the current window"), G_CALLBACK(act_close_window)},
  {"CloseTab",          GTK_STOCK_CLOSE,    N_("Close Ta_b"),          CTRL"W",  N_("Close the current tab"), G_CALLBACK(act_close_tab)},
  {"SavePage",          GTK_STOCK_SAVE_AS,  N_("Save A_s..."),         CTRL"S",  N_("Save the current page with a different name"), G_CALLBACK(act_save)},

      
  {"PrintPreview",     GTK_STOCK_PRINT_PREVIEW, N_("Print Preview"),  NULL,    N_("Print preview"), G_CALLBACK(act_print_preview)},
  {"Print",             GTK_STOCK_PRINT,        N_("_Print..."),      CTRL"P", N_("Print the current page"), G_CALLBACK(act_print)},

  {"Undo",               GTK_STOCK_UNDO,        N_("_Undo"),          CTRL"Z", N_("Undo the last action"), G_CALLBACK(act_undo)},
  {"Redo",               GTK_STOCK_REDO,        N_("_Redo"),          SFCT"Z", N_("Redo the last undone action"), G_CALLBACK(act_redo)},
  {"Cut",                GTK_STOCK_CUT,         N_("C_ut"),           CTRL"X", N_("Cut the selection"), G_CALLBACK(act_cut)},
  {"Copy",               GTK_STOCK_COPY,        N_("_Copy"),          CTRL"C", N_("Copy the selection"), G_CALLBACK(act_copy)},
  {"Paste",              GTK_STOCK_PASTE,       N_("_Paste"),         CTRL"V", N_("Paste the clipboard"), G_CALLBACK(act_paste)},
  {"SelectAll", KZ_STOCK_SELECT_ALL,            N_("Select _All"),    CTRL"A", N_("Select the entire page"), G_CALLBACK(act_select_all)},
  {"CopyTitle",          NULL          ,        N_("Copy _Title"),    NULL,    N_("Copy the title of the current page"), G_CALLBACK(act_copy_title)},
  {"CopyURL",            KZ_STOCK_COPY_URL,     N_("Copy _URL"),      NULL,    N_("Copy the URL of the current page"), G_CALLBACK(act_copy_url)},
  {"CopyInUserFormat",          NULL          ,        N_("Copy _In User Format"),    NULL,    N_("Copy Title, URI and Selected text in user format"), G_CALLBACK(act_copy_in_user_format)},
  {"Preference",         GTK_STOCK_PREFERENCES, N_("_Preference..."), NULL,    N_("Preference"), G_CALLBACK(act_preference)},
  {"DetailedPreference", NULL                 , N_("_Detailed Preference"), NULL, N_("Detailed preference"), G_CALLBACK(act_detaild_preference)},

  {"Back",          GTK_STOCK_GO_BACK,    N_("_Back"),          ALT"Left",  N_("Go to the previous visited page"), G_CALLBACK(act_back)},
  {"Forward",       GTK_STOCK_GO_FORWARD, N_("_Forward"),       ALT"Right", N_("Go to the next visited page"), G_CALLBACK(act_forward)},
  {"Reload",        GTK_STOCK_REFRESH,    N_("_Reload"),        CTRL"R",    N_("Display the latest content of the current page"), G_CALLBACK(act_reload)},
                                      
  {"GoUp",          GTK_STOCK_GO_UP,      N_("Go _Up"),         ALT"Up",    N_("Go up one level"), G_CALLBACK(act_go_up)},
  {"GotoLocation",  GTK_STOCK_JUMP_TO,    N_("Go to _Location"),NULL,       N_("Go to a specified location"), G_CALLBACK(act_go_location)},
                                      
  {"Index",         GTK_STOCK_INDEX,      N_("Index"),          NULL,       N_("Go to the index page"), G_CALLBACK(act_index)},
  {"Contents",      GTK_STOCK_GOTO_TOP,   N_("Contents"),       NULL,       N_("Go to the contents"), G_CALLBACK(act_contents)},
  {"Start",         GTK_STOCK_GOTO_FIRST, N_("Start"),          NULL,       N_("Go to the start page"), G_CALLBACK(act_start)},
  {"Prev",          GTK_STOCK_GO_BACK,    N_("Prev"),           NULL,       N_("Go to the previous page"), G_CALLBACK(act_prev)},
  {"Next",          GTK_STOCK_GO_FORWARD, N_("Next"),           NULL,       N_("Go to the next page"), G_CALLBACK(act_next)},
                                      
  {"Stop",          GTK_STOCK_STOP,       N_("_Stop"),          "Escape",   N_("Stop current data transfer"), G_CALLBACK(act_stop)},
  {"ReloadAll",     GTK_STOCK_REFRESH,    N_("Reload all"),     NULL,       NULL, G_CALLBACK(act_reload_all)},
  {"StopAll",       NULL,                 N_("Stop all"),       NULL,       NULL, G_CALLBACK(act_stop_all)},

  {"PageUp",      NULL,                   N_("Page Up"),       NULL,       NULL, G_CALLBACK(act_page_up)},
  {"PageDown",      NULL,                 N_("Page Down"),       NULL,       NULL, G_CALLBACK(act_page_down)},

  {"NormalTextSize",   NULL, N_("Normal text size"), NULL, N_("Use the normal text size"), G_CALLBACK(act_normal_text_size)},
  {"IncreaseTextSize", KZ_STOCK_FONT_INCREASE,  N_("Increase text size"),     NULL, N_("Increase the text size"),   G_CALLBACK(act_increase_text_size)},
  {"DecreaseTextSize", KZ_STOCK_FONT_DECREASE, N_("Decrease text size"),    NULL, N_("Decrease the text size"),   G_CALLBACK(act_decrease_text_size)},

  {"NormalSize", GTK_STOCK_ZOOM_100, N_("Normal size"), NULL, N_("Normal size"), G_CALLBACK(act_zoom_100)},
  {"ZoomIn",    GTK_STOCK_ZOOM_IN,  N_("Zoom in"),     NULL, N_("Zoom in this page"),   G_CALLBACK(act_zoom_in)},
  {"ZoomOut",   GTK_STOCK_ZOOM_OUT, N_("Zoom out"),    NULL, N_("Zoom out this page"),  G_CALLBACK(act_zoom_out)},

  {"ViewPageSource", KZ_STOCK_VIEW_SOURCE, N_("View page source"), NULL, N_("View the source code of the page"), G_CALLBACK(act_view_source)},
  {"AutoScrollMode", NULL,          N_("Autoscroll mode"), NULL, N_("set auto-scroll mode"), G_CALLBACK(act_auto_scroll_mode)},
  {"ThumbnailTabList", NULL,          N_("ThumbnailTabList"), NULL, N_("Display the tab list with thumbnail"), G_CALLBACK(act_thumbnail_tablist)},
/*
  {"EditMode", KZ_STOCK_VIEW_SOURCE, N_("EditMode"), NULL, N_("View the source code of the page"), G_CALLBACK(act_set_edit_mode)},
  {"ViewMode", KZ_STOCK_VIEW_SOURCE, N_("EditMode"), NULL, N_("View the source code of the page"), G_CALLBACK(act_set_view_mode)},
*/
  {"GetBodyText",    NULL, N_("Get Body Text"), NULL, NULL, G_CALLBACK(act_get_body_text)},

/*
  {"LocationEntry", N_("Location Entry"), GTK_STOCK_NEW,        NULL,     NULL, G_CALLBACK(act_location_enter), NULL, HISTORY_ACTION},
*/

  {"Find",          NULL,                 N_("Find"),         CTRL"F",  N_("Find a word or phrase in the page"), G_CALLBACK(act_find)},
  {"PrevTab", KZ_STOCK_TAB_PREV,    N_("_Previous Tab"),  ALT"L",   N_("Activate previous tab"), G_CALLBACK(act_prev_tab)},
  {"NextTab", KZ_STOCK_TAB_NEXT,    N_("_Next Tab"),      ALT"R",   N_("Activate next tab"), G_CALLBACK(act_next_tab)},

  {"CopyTab",       NULL, N_("_Copy Tab"),   NULL, N_("Duplicate the current tab"), G_CALLBACK(act_copy_tab)},

  {"CloseAllBackwardTab", KZ_STOCK_CLOSE_BACKWARD, N_("Close all _backward tabs"), NULL, NULL, G_CALLBACK(act_tab_close_backward_all)},
  {"CloseAllForwardTab", KZ_STOCK_CLOSE_FORWARD, N_("Close all _forward tabs"),  NULL, NULL, G_CALLBACK(act_tab_close_forward_all)},
  {"CloseAllTabWithoutActive", NULL, N_("Close all tabs without _active"), NULL, NULL, G_CALLBACK(act_tab_close_all_without_active)},

  {"OpenBookmarkInNewTab",      NULL, N_("Open the bookmark in new _tab"),   NULL,  NULL, G_CALLBACK(act_bookmark_in_new_tab)},
  {"OpenAllBookmarks",          NULL, N_("Open a_ll bookmarks"),             NULL,  NULL, G_CALLBACK(act_open_all_bookmarks)},
  {"OpenAllBookmarksRecursive", NULL, N_("Open all bookmarks _recursively"), NULL,  NULL, G_CALLBACK(act_open_all_bookmarks_recursive)},
  {"AddBookmark",               NULL, N_("_Add to bookmarks"),               NULL,  NULL, G_CALLBACK(act_add_bookmark)},
  {"RemoveBookmark",            NULL, N_("_Remove the bookmark"),            NULL,  NULL, G_CALLBACK(act_remove_bookmark)},
  {"EditBookmarks",             NULL, N_("_Edit bookmarks..."),              NULL,  NULL, G_CALLBACK(act_edit_bookmark)},
  {"EditBookmarkBars",          NULL, N_("Edit bookmark _bars..."),          NULL,  NULL, G_CALLBACK(act_edit_bookmark_bars)},
  {"EditSmartBookmarks",        NULL, N_("Edit _smart bookmarks..."),        NULL,  NULL, G_CALLBACK(act_edit_smart_bookmarks)},
  {"UpdateBookmarkFolder",      NULL, N_("_Update bookmark folder"),         NULL,  NULL, G_CALLBACK(act_update_bookmark)},

  {"ClipSelection",          NULL, N_("C_lip Selection"),        NULL,  N_("Clip the current selection"), G_CALLBACK(act_clip_selection)},

  {"ExtractLinks",         NULL, N_("_Extract links..."), NULL,  NULL, G_CALLBACK(act_extract_links)},
  {"ExtractSelectedLinks", NULL, N_("E_xtract selected links..."), NULL,  NULL, G_CALLBACK(act_extract_selected_links)},

  {"SaveSession",    NULL, N_("Save session"),    NULL, NULL, G_CALLBACK(act_save_session)},
  {"RestoreSession", NULL, N_("Restore session"), NULL, NULL, G_CALLBACK(act_restore_session)},
  /* {"SaveSessionAs", NULL, N_("Save session as ..."),        NULL, NULL, G_CALLBACK(act_save_session)}, */
  /* {"DeleteSession", NULL, N_("Delete current session"),     NULL, NULL, G_CALLBACK(act_save_session)}, */
  /* {"SwitchSession", NULL, N_("Switch current session ..."), NULL, NULL, G_CALLBACK(act_switch_session)}, */
  {"ShowPassword", NULL, N_("_Show Password Manager"), NULL,  NULL, G_CALLBACK(act_show_password_manager)},
  {"About",        NULL, N_("About Kazehakase"),       NULL,  N_("Display credits"), G_CALLBACK(act_about)},
  
  {"PopupContextMenu", NULL, N_("Popup context menu"), SHFT"F10",  N_("Popup context menu"), G_CALLBACK(act_popup_context_menu)},
};
const gint kz_actions_len = G_N_ELEMENTS(kz_actions);

static GtkToggleActionEntry kz_toggle_actions[] =
{
  {"ShowHideSidebar", NULL, N_("Sidebar"),          NULL, NULL, G_CALLBACK(act_show_hide_sidebar)},
  {"ShowHideBookmarkbars", NULL, N_("Bookmarkbar"), NULL, NULL, G_CALLBACK(act_show_hide_bookmarkbars)},
  {"ToggleProxyUse",  NULL, N_("Toggle Proxy Use"), NULL, NULL, G_CALLBACK(act_toggle_proxy_use)}, 
  {"ToggleFullScreen",NULL, N_("Toggle Full Screen Mode"), "F11", NULL, G_CALLBACK(act_view_fullscreen)}, 
};
static const gint kz_toggle_actions_len = G_N_ELEMENTS(kz_toggle_actions);

static GtkRadioActionEntry kz_sidebar_pos_radio_actions[] =
{
  {"SidebarPosTop",   NULL, N_("Sidebar _Top"),    NULL, NULL, GTK_POS_TOP},
  {"SidebarPosBottom",NULL, N_("Sidebar _Bottom"), NULL, NULL, GTK_POS_BOTTOM},
  {"SidebarPosLeft",  NULL, N_("Sidebar _Left"),   NULL, NULL, GTK_POS_LEFT},
  {"SidebarPosRight", NULL, N_("Sidebar _Right"),  NULL, NULL, GTK_POS_RIGHT},
};
static const gint kz_sidebar_pos_radio_actions_len = G_N_ELEMENTS(kz_sidebar_pos_radio_actions);

static GtkRadioActionEntry kz_ui_level_radio_actions[] =
{
  {"UILevelBeginner", NULL, N_("Beginner"), NULL, NULL, UI_BEGINNER},
  {"UILevelMedium",   NULL, N_("Medium"),   NULL, NULL, UI_MEDIUM},
  {"UILevelExpert",   NULL, N_("Expert"),   NULL, NULL, UI_EXPERT},
  {"UILevelCustom",   NULL, N_("Custom"),   NULL, NULL, UI_CUSTOM},
};
static const gint kz_ui_level_radio_actions_len = G_N_ELEMENTS(kz_ui_level_radio_actions);

static GtkRadioActionEntry kz_tab_pos_radio_actions[] =
{
  {"TabPosTop",     NULL, N_("Tab _Top"),    NULL, NULL, GTK_POS_TOP},
  {"TabPosBottom",  NULL, N_("Tab _Bottom"), NULL, NULL, GTK_POS_BOTTOM},
  {"TabPosLeft",    NULL, N_("Tab _Left"),   NULL, NULL, GTK_POS_LEFT},
  {"TabPosRight",   NULL, N_("Tab _Right"),  NULL, NULL, GTK_POS_RIGHT},
};
static const gint kz_tab_pos_radio_actions_len = G_N_ELEMENTS(kz_tab_pos_radio_actions);


static void
set_popup_menu_sensitive (KzWindow *kz, KzBookmark *bookmark)
{
      KzBookmark *bookmark_file;
      GtkAction *action;
      gboolean has_link, is_folder, is_file, has_children;
      gboolean children_is_editable, is_editable;

      g_return_if_fail(kz && bookmark);

      bookmark_file = kz_bookmark_get_parent_file(bookmark);

      has_link = kz_bookmark_get_link(bookmark) ? TRUE : FALSE;
      is_folder = kz_bookmark_is_folder(bookmark);
      is_file = KZ_IS_BOOKMARK_FILE(bookmark);
      has_children = kz_bookmark_has_children(bookmark);
      is_editable = kz_bookmark_is_editable(bookmark);
      if (is_file)
            children_is_editable = kz_bookmark_file_is_editable(KZ_BOOKMARK_FILE(bookmark));
      else if (is_folder && is_editable)
            children_is_editable = TRUE;
      else
            children_is_editable = FALSE;

      action = gtk_action_group_get_action(kz->actions,
                                   "OpenBookmarkInNewTab");
      g_object_set(action, "sensitive", has_link, NULL);

      action = gtk_action_group_get_action(kz->actions,
                                   "OpenAllBookmarks");
      g_object_set(action, "sensitive", is_folder && has_children, NULL);

      action = gtk_action_group_get_action(kz->actions,
                                   "AddBookmark");
      g_object_set(action, "sensitive", ((is_file && children_is_editable) ||
                                (!is_file && is_editable)), NULL);

      action = gtk_action_group_get_action(kz->actions,
                                   "RemoveBookmark");
      g_object_set(action, "sensitive", is_editable, NULL);

      action = gtk_action_group_get_action(kz->actions,
                                   "EditBookmarks");
      g_object_set(action, "sensitive", (is_editable  || children_is_editable)
                              , NULL);

      action = gtk_action_group_get_action(kz->actions,
                                   "UpdateBookmarkFolder");
      g_object_set(action, "sensitive", is_file, NULL);
}


static void
combine_favicon(GtkAction *action, const gchar *uri, KzWindow *kz)
{
      GtkWidget *widget;
      GSList *node, *proxies;
      KzFavicon *kzfav = kz->kzfav;

      proxies = gtk_action_get_proxies(action);
      for (node = proxies; node; node = g_slist_next(node))
      {
            GtkWidget *image;
            GdkPixbuf *favicon = NULL;
            if (!GTK_IS_WIDGET(node->data))
                  continue;

            widget = GTK_WIDGET(node->data);
            
            if (!GTK_IS_IMAGE_MENU_ITEM(widget) && 
                !GTK_IS_TOOL_BUTTON(widget))
                  continue;

            if (GTK_IS_IMAGE_MENU_ITEM(widget))
            {
                  gchar *stock_id;
                  favicon = kz_favicon_get_pixbuf(kzfav, uri,
                                          GTK_ICON_SIZE_MENU);
                  image = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(widget));
                  g_object_get(G_OBJECT(action),
                             "stock_id", &stock_id,
                             NULL);
                  gtkutil_superpose_pixbuf(image, favicon,
                                     stock_id,
                                     GTK_ICON_SIZE_MENU);
                  g_free(stock_id);
            }
            else if (GTK_IS_TOOL_BUTTON(widget))
            {
                  gchar *stock_id;
                  favicon = kz_favicon_get_pixbuf(kzfav, uri,
                                          GTK_ICON_SIZE_BUTTON);
                  image = gtk_image_new();
                  gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(widget),
                                          image);
                  gtk_widget_show(image);
                  g_object_get(G_OBJECT(action),
                             "stock_id", &stock_id,
                             NULL);
                  gtkutil_superpose_pixbuf(image, favicon,
                                     stock_id,
                                     GTK_ICON_SIZE_BUTTON);
                  g_free(stock_id);
            }
            if (favicon)
                  g_object_unref(favicon);
      }
}


void
kz_actions_set_selection_sensitive (KzWindow *kz, KzEmbed *kzembed)
{
      GtkWidget *focus;
      gboolean can_copy = FALSE, can_cut = FALSE, can_paste = FALSE;

      focus = gtk_window_get_focus(GTK_WINDOW(kz));

#warning FIXME! /* should track all GtkEditable's event and Embed's selection */
      if (kzembed && !kz_embed_selection_is_collapsed(kzembed))
      {
            KZ_WINDOW_SET_SENSITIVE(kz, "OpenSelectedLinks", TRUE);
      }
      else
      {
            KZ_WINDOW_SET_SENSITIVE(kz, "OpenSelectedLinks", FALSE);
      }

      if (GTK_IS_EDITABLE(focus))
      {
            gboolean selected = FALSE;
            selected = gtk_editable_get_selection_bounds
                        (GTK_EDITABLE(focus), NULL, NULL);
            if (selected)
            {
                  can_cut   = TRUE;
                  can_copy  = TRUE;
            }
            can_paste = TRUE;
      }
      else if (KZ_IS_EMBED(kzembed))
      {
            can_cut   = kz_embed_can_cut_selection(kzembed);
            can_copy  = kz_embed_can_copy_selection(kzembed);
            can_paste = kz_embed_can_paste(kzembed);
      }
      
      can_cut  = TRUE;
      can_copy  = TRUE;
      can_paste = TRUE;

      KZ_WINDOW_SET_SENSITIVE(kz, "Cut",   can_cut);
      KZ_WINDOW_SET_SENSITIVE(kz, "Copy",  can_copy);
      KZ_WINDOW_SET_SENSITIVE(kz, "Paste", can_paste);      

      KZ_WINDOW_SET_SENSITIVE(kz, "ClipSelection", can_copy);
}

void
kz_actions_set_tab_sensitive (KzWindow *kz, KzEmbed *kzembed)
{
      gint num, pos = 0;
      GtkAction *action;
      g_return_if_fail (KZ_IS_WINDOW(kz));

      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));
      
      if (!num) return;

      pos = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook),
                            GTK_WIDGET(kzembed));
      if (num > 1)
      {
            action = gtk_action_group_get_action(kz->actions,
                                         "PrevTab");
            if (pos == 0)
            {
                  combine_favicon(action, NULL, kz);
                  KZ_WINDOW_SET_SENSITIVE(kz, "PrevTab", FALSE);
                  KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllBackwardTab", FALSE);
            }
            else
            {
                  KzEmbed *prev = KZ_EMBED(KZ_WINDOW_NTH_PAGE(kz, pos - 1));
                  const gchar* uri = kz_embed_get_location(prev);
                  /* set favicon */
                  combine_favicon(action, uri, kz);
                  KZ_WINDOW_SET_SENSITIVE(kz, "PrevTab", TRUE);
                  KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllBackwardTab", TRUE);
            }

            action = gtk_action_group_get_action(kz->actions,
                                         "NextTab");
            if (pos == num - 1)
            {
                  combine_favicon(action, NULL, kz);
                  KZ_WINDOW_SET_SENSITIVE(kz, "NextTab", FALSE);
                  KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllForwardTab", FALSE);
            }
            else
            {
                  KzEmbed *next = KZ_EMBED(KZ_WINDOW_NTH_PAGE(kz, pos + 1));
                  const gchar* uri = kz_embed_get_location(next);
                  /* set favicon */
                  combine_favicon(action, uri, kz);
                  KZ_WINDOW_SET_SENSITIVE(kz, "NextTab", TRUE);
                  KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllForwardTab", TRUE);
            }
      }
      else
      {
            KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllBackwardTab",      FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllForwardTab",       FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CloseAllTabWithoutActive", FALSE);
      }
}

void
kz_actions_set_sensitive (KzWindow *kz, KzEmbed *kzembed)
{
      KzTabLabel *kztab;
      gboolean can_go_back = FALSE;
      gboolean can_go_forward = FALSE;
      gboolean can_go_up = FALSE;
      gboolean can_stop = FALSE;
      gboolean can_stop_all = FALSE;
      gboolean can_go_index = FALSE, can_go_contents = FALSE,
             can_go_start = FALSE, can_go_prev = FALSE, can_go_next = FALSE;
      gboolean can_close_tab = TRUE;
      gint i, num, pos = 0;
      GtkAction *action;
      gboolean active;
      KzStopReloadActionState state;

      g_return_if_fail (KZ_IS_WINDOW(kz));
      /* g_return_if_fail (KZ_IS_EMBED (kzembed)); */

      num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook));

      if (kzembed)
      {
            kztab = KZ_TAB_LABEL(kz_window_get_tab_label(kz, GTK_WIDGET(kzembed)));

            can_stop        = kz_embed_is_loading(kzembed);
            can_go_back     = kz_embed_can_go_back(kzembed);
            can_go_forward  = kz_embed_can_go_forward(kzembed);
            can_go_up       = kz_embed_can_go_up(kzembed);
            
            can_go_index    = kz_embed_can_go_nav_link(kzembed, KZ_EMBED_LINK_INDEX);
            can_go_contents = kz_embed_can_go_nav_link(kzembed, KZ_EMBED_LINK_CONTENTS);
            can_go_start    = kz_embed_can_go_nav_link(kzembed, KZ_EMBED_LINK_START);
            can_go_prev     = kz_embed_can_go_nav_link(kzembed, KZ_EMBED_LINK_PREV);
            can_go_next     = kz_embed_can_go_nav_link(kzembed, KZ_EMBED_LINK_NEXT);
            
            can_close_tab = !kz_tab_label_get_lock(kztab);

            pos = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook),
                                  GTK_WIDGET(kzembed));
            for (i = 0; i< num; i++)
            {
                  GtkWidget *widget;

                  widget = KZ_WINDOW_NTH_PAGE(kz, i);
                  if (!KZ_IS_EMBED(widget)) continue;
                  can_stop_all
                        = kz_embed_is_loading(KZ_EMBED(widget));
                  if (can_stop_all) break;
            }
      }

      if (num > 0)
      {
            GtkAction *nav;

            KZ_WINDOW_SET_SENSITIVE(kz, "Back",      can_go_back);
            KZ_WINDOW_SET_SENSITIVE(kz, "NavigationBack", can_go_back);
            action = gtk_action_group_get_action(kz->actions,
                                         "Back");
            nav = gtk_action_group_get_action(kz->actions,
                                      "NavigationBack");
            if (can_go_back)
            {
                  gchar *uri = NULL, *title = NULL;
                  kz_embed_shistory_get_nth(kzembed, -1,
                                      TRUE, &uri, &title);
                  if (uri)
                  {
                        combine_favicon(action, uri, kz);
                        combine_favicon(nav, uri, kz);
                        g_free(uri);
                  }
                  if (title)
                        g_free(title);
            }
            else
            {
                  combine_favicon(action, NULL, kz);
                  combine_favicon(nav, NULL, kz);
            }
            KZ_WINDOW_SET_SENSITIVE(kz, "Forward",   can_go_forward);
            action = gtk_action_group_get_action(kz->actions,
                                         "Forward");
            if (can_go_forward)
            {
                  gchar *uri = NULL, *title = NULL;
                  kz_embed_shistory_get_nth(kzembed, 1,
                                      TRUE, &uri, &title);
                  if (uri)
                  {
                        combine_favicon(action, uri, kz);
                        g_free(uri);
                  }
                  if (title)
                        g_free(title);
            }
            else 
                  combine_favicon(action, NULL, kz);

            KZ_WINDOW_SET_SENSITIVE(kz, "GoUp",      can_go_up);
            KZ_WINDOW_SET_SENSITIVE(kz, "Stop",      can_stop);
            KZ_WINDOW_SET_SENSITIVE(kz, "Reload",    !can_stop);
            KZ_WINDOW_SET_SENSITIVE(kz, "StopAll",   can_stop_all);
            KZ_WINDOW_SET_SENSITIVE(kz, "ReloadAll", TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CloseTab",  can_close_tab);
            KZ_WINDOW_SET_SENSITIVE(kz, "Search",    TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "ExtractLinks", TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CopyTitle",    TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CopyURL",      TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Index",    can_go_index);
            KZ_WINDOW_SET_SENSITIVE(kz, "Contents", can_go_contents);
            KZ_WINDOW_SET_SENSITIVE(kz, "Start",    can_go_start);
            KZ_WINDOW_SET_SENSITIVE(kz, "Prev",     can_go_prev);
            KZ_WINDOW_SET_SENSITIVE(kz, "Next",     can_go_next);
            KZ_WINDOW_SET_VISIBLE  (kz, "Index",    can_go_index);
            KZ_WINDOW_SET_VISIBLE  (kz, "Contents", can_go_contents);
            KZ_WINDOW_SET_VISIBLE  (kz, "Start",    can_go_start);
            KZ_WINDOW_SET_VISIBLE  (kz, "Prev",     can_go_prev);
            KZ_WINDOW_SET_VISIBLE  (kz, "Next",     can_go_next);
            KZ_WINDOW_SET_VISIBLE  (kz, "Stop",     can_stop);
            KZ_WINDOW_SET_VISIBLE  (kz, "Reload",   !can_stop);

            /* Stop/Reload action */
            KZ_WINDOW_SET_SENSITIVE(kz, "StopReload",      TRUE);
            action = gtk_action_group_get_action(kz->actions,
                                         "StopReload");
            state = can_stop?KZ_STOP_RELOAD_ACTION_STATE_STOP:KZ_STOP_RELOAD_ACTION_STATE_RELOAD;
            kz_stop_reload_action_set_state(
                  KZ_STOP_RELOAD_ACTION(action),
                  state);
            /* enable tab actions */
            gtk_action_group_set_sensitive (kz->tabpop_actions, TRUE);
      }
      else
      {
            KZ_WINDOW_SET_VISIBLE  (kz, "Stop",      FALSE);
            KZ_WINDOW_SET_VISIBLE  (kz, "Reload",    TRUE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Back",      FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Forward",   FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Stop",      FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Reload",    FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "StopAll",   FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "ReloadAll", FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CloseTab",  FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "PrevTab",   FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "NextTab",  FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "Search",    FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "ExtractLinks", FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CopyTitle",    FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "CopyURL",      FALSE);
            KZ_WINDOW_SET_SENSITIVE(kz, "NavigationBack", FALSE);
            /* Stop/Reload action */
            KZ_WINDOW_SET_SENSITIVE(kz, "StopReload",      FALSE);
            action = gtk_action_group_get_action(kz->actions,
                                         "StopReload");
            kz_stop_reload_action_set_state(
                  KZ_STOP_RELOAD_ACTION(action),
                  KZ_STOP_RELOAD_ACTION_STATE_RELOAD);
            /* disable tab actions */
            gtk_action_group_set_sensitive (kz->tabpop_actions, FALSE);
      }

      kz_actions_set_selection_sensitive (kz, kzembed);
      
      /* Sidebar position menu */
      action = gtk_action_group_get_action(kz->actions,
                                   "ShowHideSidebar");
      active = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
      KZ_WINDOW_SET_VISIBLE(kz, "StockSidebarPosMenu", active);

      set_popup_menu_sensitive(kz, kz_bookmarks->menu);
}


GtkActionGroup *
kz_actions_create_group (KzWindow *kz, GtkAccelGroup *accel_group)
{
      GtkActionGroup *action_group;
      GtkAction *action;
      GList *node, *action_list;

      action_group = gtk_action_group_new("KzWindow");
      gtk_action_group_set_translation_domain(action_group, NULL);

      gtk_action_group_add_actions(action_group,
                             kz_actions,
                             kz_actions_len,
                             kz);
      gtk_action_group_add_toggle_actions(action_group,
                                  kz_toggle_actions,
                                  kz_toggle_actions_len,
                                  kz);
      gtk_action_group_add_radio_actions(action_group,
                                 kz_sidebar_pos_radio_actions,
                                 kz_sidebar_pos_radio_actions_len,
                                 0,
                                 G_CALLBACK(act_sidebar_pos),
                                 kz);
      gtk_action_group_add_radio_actions(action_group,
                                 kz_ui_level_radio_actions,
                                 kz_ui_level_radio_actions_len,
                                 0,
                                 G_CALLBACK(act_ui_level),
                                 kz);
      gtk_action_group_add_radio_actions(action_group,
                                 kz_tab_pos_radio_actions,
                                 kz_tab_pos_radio_actions_len,
                                 -1,
                                 G_CALLBACK(act_tab_pos),
                                 kz);
#if 1
      /* Back and Forward Action */
      {
            action = g_object_new(KZ_TYPE_NAVIGATION_ACTION,
                              "name", "NavigationBack",
                              "label", _("Back"),
                              "stock_id", GTK_STOCK_GO_BACK,
                              "tooltip", _("Go back"),
                              "kz-window", kz,
                              NULL);

            gtk_action_group_add_action(action_group, action);
            g_object_unref(action);
      }
#endif
      /* StopReload action */
      {
            action = GTK_ACTION(kz_stop_reload_action_new(kz));
            gtk_action_group_add_action(action_group, action);
            g_object_unref(action);
      }

      /* Zoom action */
      {
            action = GTK_ACTION(kz_zoom_action_new(kz));
            gtk_action_group_add_action(action_group, action);
            g_object_unref(action);
      }
      
      /* Location Entry action */
      {
            action = GTK_ACTION(kz_location_entry_action_new(kz));
            gtk_action_group_add_action(action_group, action);
            g_object_unref(action);
      }

      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;
}


KzBookmark *
kz_actions_get_bookmark_for_action (KzWindow *kz)
{
      KzBookmark *bookmark;

      g_return_val_if_fail(KZ_IS_WINDOW(kz), NULL);

      if (!bookmark_quark)
            bookmark_quark = g_quark_from_string("KzAction::KzBookmark");
      bookmark = g_object_get_qdata(G_OBJECT(kz), bookmark_quark);

      if (KZ_IS_BOOKMARK(bookmark))
            return bookmark;

      return kz_bookmarks->menu;
}


void
kz_actions_set_bookmark_for_action (KzWindow *kz, KzBookmark *bookmark)
{
      g_return_if_fail(KZ_IS_WINDOW(kz));
      g_return_if_fail(!bookmark || KZ_IS_BOOKMARK(bookmark));

      if (!bookmark_quark)
            bookmark_quark = g_quark_from_string("KzAction::KzBookmark");
      g_object_set_qdata(G_OBJECT(kz), bookmark_quark, bookmark);
}


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


void
kz_actions_popup_bookmark_menu_modal (KzWindow *kz, KzBookmark *bookmark,
                              guint button, guint time)
{
      GtkWidget *popup_menu = NULL;

      g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

      kz_actions_set_bookmark_for_action (kz, bookmark);

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

      g_signal_connect(popup_menu, "hide",
                   G_CALLBACK(cb_popup_menu_hide), NULL);
      set_popup_menu_sensitive (kz, bookmark);
      gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL,
                   NULL, NULL, button, time);
      gtk_main();
      g_signal_handlers_disconnect_by_func(popup_menu,
                                   G_CALLBACK(cb_popup_menu_hide),
                                   NULL);

      kz_actions_set_bookmark_for_action (kz, NULL);

      set_popup_menu_sensitive (kz, kz_bookmarks->menu);
}


void
kz_actions_insert_smartbookmark (KzWindow *kz, KzBookmark *bookmark,
                         KzBookmark *child, KzBookmark *sibling)
{
      GtkAction *action;
      const gchar *action_name;
      const gchar *title;
      guint id;
      
      if (!KZ_IS_SMART_BOOKMARK(child) &&
          !kz_bookmark_is_folder(child)) return;
      
      title = kz_bookmark_get_title(child);
      
      /*
       * We should unite KzLocationEntry and KzSmartBookmark.
       */
      if (title && !strncmp(title, "LocationEntry", 13))
      {
            action = gtk_action_group_get_action(kz->actions,
                                         "LocationEntry");
            if (KZ_IS_LOCATION_ENTRY_ACTION(action))
            {
                  kz_location_entry_action_set_bookmark(
                        KZ_LOCATION_ENTRY_ACTION(action),
                        child);
            }
            return;
      }
      
      action = GTK_ACTION(kz_smart_bookmark_action_new
                     (kz, child));

      if (!action) return;

      id = gtk_ui_manager_new_merge_id(kz->menu_merge);
      action_name = gtk_action_get_name(action);

      gtk_action_group_add_action(kz->actions,
                            action);

      gtk_ui_manager_add_ui(kz->menu_merge,
                        id, 
                        "/MainToolBar/SmartBookmark",
                        action_name, 
                        action_name,
                        GTK_UI_MANAGER_TOOLITEM, FALSE);
      g_object_set_data(G_OBJECT(action), action_name, 
                    GUINT_TO_POINTER(id));
      g_object_unref(action);
}

void
kz_actions_remove_smartbookmark (KzWindow *kz, KzBookmark *bookmark,
                         KzBookmark *child)
{
      GtkAction *action;
      gpointer p;
      guint id;
      gchar *action_name;
      const gchar *title;

      title = kz_bookmark_get_title(child);
       
      if (title && !strncmp(title, "LocationEntry", 13))
            return;
      else
            action_name = g_strdup_printf("SmartBookmark:%p", child);

      action = gtk_action_group_get_action(kz->actions,
                                   action_name);
      
      if (action)
      {
            p = g_object_get_data(G_OBJECT(action),
                              action_name);
            if (p)
            {
                  id = GPOINTER_TO_UINT(p);
                  gtk_ui_manager_remove_ui(kz->menu_merge, id);
                  id = 0;
                  g_object_set_data(G_OBJECT(action),
                                action_name,
                                GUINT_TO_POINTER(id));
            }
            gtk_action_group_remove_action(kz->actions,
                                     action);
      }
      g_free(action_name);
}

void
kz_actions_update_smartbookmarks (KzWindow *kz, KzBookmark *bookmark)
{
      GList *children, *node;
      
      children = kz_bookmark_get_children(bookmark);
      for (node = children; node; node = g_list_next(node))
      {
            gpointer p;
            guint id;
            gchar *action_name;
            const gchar *title;
            GtkAction *action, *new_action = NULL;
            KzBookmark *child= node->data;

            if (!KZ_IS_SMART_BOOKMARK(child) &&
                !kz_bookmark_is_folder(child)) continue;
            
            title = kz_bookmark_get_title(child);
       
            if (title && !strncmp(title, "LocationEntry", 13))
            {
                  action = gtk_action_group_get_action(kz->actions,
                                               "LocationEntry");
                  kz_location_entry_action_set_bookmark(
                        KZ_LOCATION_ENTRY_ACTION(action),
                        child);
                  continue;
            }
            
            action_name = g_strdup_printf("SmartBookmark:%p", child);

            /* remove old one */
            action = gtk_action_group_get_action(kz->actions,
                                         action_name);
            if (action)
            {
                  p = g_object_get_data(G_OBJECT(action),
                                    action_name);
                  if (p)
                  {
                        id = GPOINTER_TO_UINT(p);
                        gtk_ui_manager_remove_ui(kz->menu_merge,
                                           id);
                  }
            }
            else
            {
                  /* add new one */
                  new_action = GTK_ACTION(kz_smart_bookmark_action_new
                                    (kz, child));
                  if (new_action)
                  {
                        gtk_action_group_add_action(kz->actions,
                                              new_action);
                        action = new_action;
                  }
            }
            
            if (!action)
            {
                  g_free(action_name);
                  continue;
            }

            id = gtk_ui_manager_new_merge_id(kz->menu_merge);
            gtk_ui_manager_add_ui(kz->menu_merge,
                              id, 
                              "/MainToolBar/SmartBookmark",
                              action_name, 
                              action_name,
                              GTK_UI_MANAGER_TOOLITEM, FALSE);
            g_object_set_data(G_OBJECT(action), 
                          action_name, 
                          GUINT_TO_POINTER(id));
            if (new_action)
                  g_object_unref(new_action);
            g_free(action_name);
      }
      g_list_free(children);
}


void
kz_actions_remove_smartbookmarks (KzWindow *kz, KzBookmark *bookmark)
{
      GList *children, *node;

      children = kz_bookmark_get_children(bookmark);
      for (node = children; node; node = g_list_next(node))
      {
            gpointer p;
            guint id;
            gchar *action_name;
            const gchar *title;
            GtkAction *action;
            GSList *p_node, *proxies;
            KzBookmark *child= node->data;

            if (!KZ_IS_SMART_BOOKMARK(child) &&
                !kz_bookmark_is_folder(child)) continue;
            
            title = kz_bookmark_get_title(child);
            if (title && !strncmp(title, "LocationEntry", 13))
                  action_name = g_strdup("LocationEntry");
            else
                  action_name = g_strdup_printf("SmartBookmark:%p", child);

            action = gtk_action_group_get_action(kz->actions,
                                         action_name);
                if (!action) continue;

            proxies = gtk_action_get_proxies(action);
                if (proxies)
            {
                  GSList *copy;
                      /* disconenct proxy explicitly */
                      copy = g_slist_copy(proxies);
                  for (p_node = copy; p_node; p_node = g_slist_next(p_node))
                  {
                        if (p_node->data && GTK_IS_WIDGET(p_node->data))
                            {
                                  gtk_action_disconnect_proxy(action, GTK_WIDGET(p_node->data));
                              }
                    }
                      g_slist_free(copy);
            }

            if (title && !strncmp(title, "LocationEntry", 13))
            {
                  g_free(action_name);
                  continue;
            }
            
            /* remove old one */
            p = g_object_get_data(G_OBJECT(action),
                              action_name);
            if (p)
            {
                  id = GPOINTER_TO_UINT(p);
                  gtk_ui_manager_remove_ui(kz->menu_merge,
                                     id);
            }
            
            g_free(action_name);
      }
      g_list_free(children);
}

Generated by  Doxygen 1.6.0   Back to index