From f4aaa4442027d3078cc2809a0c9db2d5b4e48d85 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 17 Apr 2003 18:34:38 +0000 Subject: New history dialog implementation. More similar to bookmarks. Yeah it 2003-04-17 Marco Pesenti Gritti * data/ui/Makefile.am: * embed/ephy-history.c: (ephy_history_init): * embed/ephy-history.h: * lib/widgets/ephy-tree-model-node.c: (ephy_tree_model_node_get_value): * src/Makefile.am: * src/ephy-shell.c: (ephy_shell_init), (ephy_shell_finalize), (ephy_shell_show_bookmarks_editor), (history_window_hide_cb), (ephy_shell_show_history_window): * src/ephy-shell.h: * src/ephy-window.c: (ephy_window_finalize), (update_embed_dialogs), (ephy_window_get_find_dialog): * src/ephy-window.h: * src/window-commands.c: (window_cmd_go_history): New history dialog implementation. More similar to bookmarks. Yeah it still sucks ... but the hard part is done. --- ChangeLog | 21 + data/ui/Makefile.am | 3 +- data/ui/epiphany-history-window-ui.xml.in | 28 + embed/ephy-history.c | 20 + embed/ephy-history.h | 3 +- lib/widgets/ephy-tree-model-node.c | 2 +- src/Makefile.am | 6 +- src/ephy-history-model.c | 844 ------------------------------ src/ephy-history-model.h | 84 --- src/ephy-history-window.c | 728 ++++++++++++++++++++++++++ src/ephy-history-window.h | 60 +++ src/ephy-shell.c | 42 +- src/ephy-shell.h | 4 +- src/ephy-window.c | 45 -- src/ephy-window.h | 2 - src/history-dialog.c | 631 ---------------------- src/history-dialog.h | 63 --- src/window-commands.c | 2 +- 18 files changed, 909 insertions(+), 1679 deletions(-) create mode 100644 data/ui/epiphany-history-window-ui.xml.in delete mode 100644 src/ephy-history-model.c delete mode 100644 src/ephy-history-model.h create mode 100644 src/ephy-history-window.c create mode 100644 src/ephy-history-window.h delete mode 100755 src/history-dialog.c delete mode 100644 src/history-dialog.h diff --git a/ChangeLog b/ChangeLog index 0f303a380..6090cddd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2003-04-17 Marco Pesenti Gritti + + * data/ui/Makefile.am: + * embed/ephy-history.c: (ephy_history_init): + * embed/ephy-history.h: + * lib/widgets/ephy-tree-model-node.c: + (ephy_tree_model_node_get_value): + * src/Makefile.am: + * src/ephy-shell.c: (ephy_shell_init), (ephy_shell_finalize), + (ephy_shell_show_bookmarks_editor), (history_window_hide_cb), + (ephy_shell_show_history_window): + * src/ephy-shell.h: + * src/ephy-window.c: (ephy_window_finalize), + (update_embed_dialogs), (ephy_window_get_find_dialog): + * src/ephy-window.h: + * src/window-commands.c: (window_cmd_go_history): + + New history dialog implementation. More similar + to bookmarks. Yeah it still sucks ... but the hard + part is done. + 2003-04-17 Marco Pesenti Gritti * lib/widgets/Makefile.am: diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am index 189a6e938..76467e77c 100644 --- a/data/ui/Makefile.am +++ b/data/ui/Makefile.am @@ -2,7 +2,8 @@ uixmldir = $(pkgdatadir) uixml_in_files = epiphany-ui.xml.in \ epiphany-bookmark-editor-ui.xml.in \ nautilus-epiphany-view.xml.in \ - epiphany-toolbar.xml.in + epiphany-toolbar.xml.in \ + epiphany-history-window-ui.xml.in uixml_DATA = $(uixml_in_files:.xml.in=.xml) diff --git a/data/ui/epiphany-history-window-ui.xml.in b/data/ui/epiphany-history-window-ui.xml.in new file mode 100644 index 000000000..a4a10885d --- /dev/null +++ b/data/ui/epiphany-history-window-ui.xml.in @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/embed/ephy-history.c b/embed/ephy-history.c index c1f7e2aa4..056d04c13 100644 --- a/embed/ephy-history.c +++ b/embed/ephy-history.c @@ -21,6 +21,7 @@ #include "ephy-file-helpers.h" #include "ephy-autocompletion-source.h" #include "ephy-debug.h" +#include "ephy-node-view.h" #include #include @@ -372,6 +373,8 @@ periodic_save_cb (EphyHistory *eh) static void ephy_history_init (EphyHistory *eb) { + GValue value = { 0, }; + eb->priv = g_new0 (EphyHistoryPrivate, 1); eb->priv->xml_file = g_build_filename (ephy_dot_dir (), @@ -391,6 +394,21 @@ ephy_history_init (EphyHistory *eb) /* Pages */ eb->priv->pages = ephy_node_new_with_id (PAGES_NODE_ID); ephy_node_ref (eb->priv->pages); + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, _("All")); + ephy_node_set_property (eb->priv->pages, + EPHY_NODE_PAGE_PROP_LOCATION, + &value); + ephy_node_set_property (eb->priv->pages, + EPHY_NODE_PAGE_PROP_TITLE, + &value); + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, EPHY_NODE_VIEW_ALL_PRIORITY); + ephy_node_set_property (eb->priv->pages, + EPHY_NODE_PAGE_PROP_PRIORITY, + &value); + g_value_unset (&value); g_signal_connect_object (G_OBJECT (eb->priv->pages), "child_added", G_CALLBACK (pages_added_cb), @@ -416,6 +434,8 @@ ephy_history_init (EphyHistory *eb) G_OBJECT (eb), 0); + ephy_node_add_child (eb->priv->hosts, eb->priv->pages); + ephy_history_load (eb); ephy_history_emit_data_changed (eb); diff --git a/embed/ephy-history.h b/embed/ephy-history.h index 4bb9c14b1..ccddbec67 100644 --- a/embed/ephy-history.h +++ b/embed/ephy-history.h @@ -43,7 +43,8 @@ enum EPHY_NODE_PAGE_PROP_VISITS = 4, EPHY_NODE_PAGE_PROP_LAST_VISIT = 5, EPHY_NODE_PAGE_PROP_FIRST_VISIT = 6, - EPHY_NODE_PAGE_PROP_HOST_ID = 7 + EPHY_NODE_PAGE_PROP_HOST_ID = 7, + EPHY_NODE_PAGE_PROP_PRIORITY = 8 }; struct EphyHistory diff --git a/lib/widgets/ephy-tree-model-node.c b/lib/widgets/ephy-tree-model-node.c index 35d36c98d..58b0f0baf 100644 --- a/lib/widgets/ephy-tree-model-node.c +++ b/lib/widgets/ephy-tree-model-node.c @@ -433,7 +433,7 @@ ephy_tree_model_node_get_value (GtkTreeModel *tree_model, g_return_if_fail (col != NULL); - if (col->prop_id > 0) + if (col->prop_id >= 0) { ephy_node_get_property (node, col->prop_id, diff --git a/src/Makefile.am b/src/Makefile.am index b097e5943..7e1ed32d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -55,8 +55,8 @@ epiphany_bin_SOURCES = \ ephy-go-action.h \ ephy-favorites-menu.c \ ephy-favorites-menu.h \ - ephy-history-model.c \ - ephy-history-model.h \ + ephy-history-window.c \ + ephy-history-window.h \ ephy-location-action.c \ ephy-location-action.h \ ephy-main.c \ @@ -72,8 +72,6 @@ epiphany_bin_SOURCES = \ ephy-window.h \ general-prefs.c \ general-prefs.h \ - history-dialog.c \ - history-dialog.h \ language-editor.c \ language-editor.h \ pdm-dialog.c \ diff --git a/src/ephy-history-model.c b/src/ephy-history-model.c deleted file mode 100644 index 6c5f5e787..000000000 --- a/src/ephy-history-model.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2002 Jorn Baayen - * - * 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 of the License, 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. - * - * $Id$ - */ - -#include -#include -#include -#include -#include -#include - -#include "ephy-node-filter.h" -#include "ephy-history-model.h" -#include "ephy-history.h" -#include "ephy-tree-model-node.h" -#include "ephy-stock-icons.h" -#include "ephy-node.h" - -static void ephy_history_model_class_init (EphyHistoryModelClass *klass); -static void ephy_history_model_init (EphyHistoryModel *model); -static void ephy_history_model_finalize (GObject *object); -static void ephy_history_model_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ephy_history_model_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static guint ephy_history_model_get_flags (GtkTreeModel *tree_model); -static int ephy_history_model_get_n_columns (GtkTreeModel *tree_model); -static GType ephy_history_model_get_column_type (GtkTreeModel *tree_model, - int index); -static gboolean ephy_history_model_get_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreePath *path); -static GtkTreePath *ephy_history_model_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static void ephy_history_model_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - int column, - GValue *value); -static gboolean ephy_history_model_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean ephy_history_model_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent); -static gboolean ephy_history_model_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static int ephy_history_model_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean ephy_history_model_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - int n); -static gboolean ephy_history_model_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child); -static void ephy_history_model_tree_model_init (GtkTreeModelIface *iface); -static void root_child_removed_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model); -static void root_child_added_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model); -static void root_child_changed_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model); -static inline void ephy_history_model_update_node (EphyHistoryModel *model, - EphyNode *node, - int idx); - -struct EphyHistoryModelPrivate -{ - EphyNode *root; - EphyNode *pages; - - EphyNodeFilter *filter; -}; - -enum -{ - PROP_0, - PROP_ROOT, - PROP_PAGES, - PROP_FILTER -}; - -static GObjectClass *parent_class = NULL; - -GType -ephy_history_model_get_type (void) -{ - static GType ephy_history_model_type = 0; - - if (ephy_history_model_type == 0) - { - static const GTypeInfo our_info = - { - sizeof (EphyHistoryModelClass), - NULL, - NULL, - (GClassInitFunc) ephy_history_model_class_init, - NULL, - NULL, - sizeof (EphyHistoryModel), - 0, - (GInstanceInitFunc) ephy_history_model_init - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) ephy_history_model_tree_model_init, - NULL, - NULL - }; - - ephy_history_model_type = g_type_register_static (G_TYPE_OBJECT, - "EphyHistoryModel", - &our_info, 0); - - g_type_add_interface_static (ephy_history_model_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return ephy_history_model_type; -} - -static void -ephy_history_model_class_init (EphyHistoryModelClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_history_model_finalize; - - object_class->set_property = ephy_history_model_set_property; - object_class->get_property = ephy_history_model_get_property; - - g_object_class_install_property (object_class, - PROP_ROOT, - g_param_spec_object ("root", - "Root node", - "Root node", - EPHY_TYPE_NODE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_PAGES, - g_param_spec_object ("pages", - "Pages node", - "Pages node", - EPHY_TYPE_NODE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_FILTER, - g_param_spec_object ("filter", - "Filter object", - "Filter object", - EPHY_TYPE_NODE_FILTER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -} - -static void -ephy_history_model_init (EphyHistoryModel *model) -{ - GtkWidget *dummy; - - do - { - model->stamp = g_random_int (); - } - while (model->stamp == 0); - - model->priv = g_new0 (EphyHistoryModelPrivate, 1); - - dummy = gtk_tree_view_new (); - - gtk_widget_destroy (dummy); -} - -static void -ephy_history_model_finalize (GObject *object) -{ - EphyHistoryModel *model; - - g_return_if_fail (object != NULL); - g_return_if_fail (EPHY_IS_HISTORY_MODEL (object)); - - model = EPHY_HISTORY_MODEL (object); - - g_return_if_fail (model->priv != NULL); - - g_free (model->priv); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -filter_changed_cb (EphyNodeFilter *filter, - EphyHistoryModel *model) -{ - GPtrArray *kids; - int i; - - kids = ephy_node_get_children (model->priv->root); - - for (i = 0; i < kids->len; i++) - { - ephy_history_model_update_node (model, - g_ptr_array_index (kids, i), - i); - } - - ephy_node_thaw (model->priv->root); -} - -static void -ephy_history_model_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (object); - - switch (prop_id) - { - case PROP_ROOT: - model->priv->root = g_value_get_object (value); - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_added", - G_CALLBACK (root_child_added_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_removed", - G_CALLBACK (root_child_removed_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->root), - "child_changed", - G_CALLBACK (root_child_changed_cb), - G_OBJECT (model), - 0); - break; - case PROP_PAGES: - model->priv->pages = g_value_get_object (value); - g_signal_connect_object (G_OBJECT (model->priv->pages), - "child_added", - G_CALLBACK (root_child_added_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->pages), - "child_removed", - G_CALLBACK (root_child_removed_cb), - G_OBJECT (model), - 0); - g_signal_connect_object (G_OBJECT (model->priv->pages), - "child_changed", - G_CALLBACK (root_child_changed_cb), - G_OBJECT (model), - 0); - break; - case PROP_FILTER: - model->priv->filter = g_value_get_object (value); - - if (model->priv->filter != NULL) - { - g_signal_connect_object (G_OBJECT (model->priv->filter), - "changed", - G_CALLBACK (filter_changed_cb), - G_OBJECT (model), - 0); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -ephy_history_model_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (object); - - switch (prop_id) - { - case PROP_ROOT: - g_value_set_object (value, model->priv->root); - break; - case PROP_PAGES: - g_value_set_object (value, model->priv->root); - break; - case PROP_FILTER: - g_value_set_object (value, model->priv->filter); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -EphyHistoryModel * -ephy_history_model_new (EphyNode *root, - EphyNode *pages, - EphyNodeFilter *filter) -{ - EphyHistoryModel *model; - - model = EPHY_HISTORY_MODEL (g_object_new (EPHY_TYPE_HISTORY_MODEL, - "filter", filter, - "root", root, - "pages", pages, - NULL)); - - g_return_val_if_fail (model->priv != NULL, NULL); - - return model; -} - -static void -ephy_history_model_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = ephy_history_model_get_flags; - iface->get_n_columns = ephy_history_model_get_n_columns; - iface->get_column_type = ephy_history_model_get_column_type; - iface->get_iter = ephy_history_model_get_iter; - iface->get_path = ephy_history_model_get_path; - iface->get_value = ephy_history_model_get_value; - iface->iter_next = ephy_history_model_iter_next; - iface->iter_children = ephy_history_model_iter_children; - iface->iter_has_child = ephy_history_model_iter_has_child; - iface->iter_n_children = ephy_history_model_iter_n_children; - iface->iter_nth_child = ephy_history_model_iter_nth_child; - iface->iter_parent = ephy_history_model_iter_parent; -} - -static guint -ephy_history_model_get_flags (GtkTreeModel *tree_model) -{ - return 0; -} - -static int -ephy_history_model_get_n_columns (GtkTreeModel *tree_model) -{ - return EPHY_HISTORY_MODEL_NUM_COLUMNS; -} - -static GType -ephy_history_model_get_column_type (GtkTreeModel *tree_model, - int index) -{ - g_return_val_if_fail (EPHY_IS_HISTORY_MODEL (tree_model), G_TYPE_INVALID); - g_return_val_if_fail ((index < EPHY_HISTORY_MODEL_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID); - - switch (index) - { - case EPHY_HISTORY_MODEL_COL_TITLE: - case EPHY_HISTORY_MODEL_COL_LOCATION: - case EPHY_HISTORY_MODEL_COL_VISITS: - case EPHY_HISTORY_MODEL_COL_LAST_VISIT: - case EPHY_HISTORY_MODEL_COL_FIRST_VISIT: - return G_TYPE_STRING; - case EPHY_HISTORY_MODEL_COL_VISIBLE: - return G_TYPE_BOOLEAN; - default: - g_assert_not_reached (); - return G_TYPE_INVALID; - } -} - -static gboolean -ephy_history_model_get_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreePath *path) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - gint *indices; - gint depth; - EphyNode *host; - - g_return_val_if_fail (EPHY_IS_HISTORY_MODEL (model), FALSE); - - indices = gtk_tree_path_get_indices (path); - depth = gtk_tree_path_get_depth (path); - - g_return_val_if_fail (depth > 0, FALSE); - - iter->stamp = model->stamp; - host = ephy_node_get_nth_child (model->priv->root, indices [0]); - - if (depth == 2 && host != NULL) - { - iter->user_data = ephy_node_get_nth_child (host, indices [1]); - } - else - { - iter->user_data = host; - } - - if (iter->user_data == NULL) - { - iter->stamp = 0; - return FALSE; - } - - return TRUE; -} - -static EphyNode * -ensure_iter (EphyHistoryModel *model, GtkTreeIter *parent) -{ - EphyNode *node; - - if (parent) - { - node = EPHY_NODE (parent->user_data); - } - else - { - node = model->priv->root; - } - - return node; -} - -static EphyNode * -get_parent_node (EphyHistoryModel *model, EphyNode *node) -{ - int host_id; - - host_id = ephy_node_get_property_int (node, EPHY_NODE_PAGE_PROP_HOST_ID); - - if (host_id < 0) - { - return model->priv->root; - } - else - { - EphyNode *host; - host = ephy_node_get_from_id (host_id); - return host; - } -} - -static inline GtkTreePath * -get_one_level_path_real (EphyHistoryModel *model, - EphyNode *node) -{ - GtkTreePath *retval; - EphyNode *my_parent; - - retval = gtk_tree_path_new (); - - my_parent = get_parent_node (model, node); - g_return_val_if_fail (my_parent != NULL, NULL); - - gtk_tree_path_append_index (retval, ephy_node_get_child_index (my_parent, node)); - - return retval; -} - -static inline GtkTreePath * -get_path_real (EphyHistoryModel *model, - EphyNode *page) -{ - GtkTreePath *retval; - EphyNode *host; - - host = get_parent_node (model, page); - if (host != NULL) return NULL; - - retval = gtk_tree_path_new (); - - gtk_tree_path_append_index (retval, ephy_node_get_child_index (model->priv->root, host)); - gtk_tree_path_append_index (retval, ephy_node_get_child_index (host, page)); - - return retval; -} - -static GtkTreePath * -ephy_history_model_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - g_return_val_if_fail (EPHY_IS_HISTORY_MODEL (tree_model), NULL); - g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (iter->user_data != NULL, NULL); - g_return_val_if_fail (iter->stamp == model->stamp, NULL); - - node = EPHY_NODE (iter->user_data); - - if (node == model->priv->root) - return gtk_tree_path_new (); - - return get_one_level_path_real (model, node); -} - -static void -get_property_as_date (EphyNode *node, - int id, - GValue *value) -{ - GTime time; - char s[50]; - GDate *date; - - time = ephy_node_get_property_int (node, id); - date = g_date_new (); - g_date_set_time (date, time); - g_date_strftime (s, 50, "%c", date); - - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, s); - - g_date_free (date); -} - -static void -ephy_history_model_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - int column, - GValue *value) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - g_return_if_fail (EPHY_IS_HISTORY_MODEL (tree_model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->stamp == model->stamp); - g_return_if_fail (EPHY_IS_NODE (iter->user_data)); - g_return_if_fail (column < EPHY_HISTORY_MODEL_NUM_COLUMNS); - - node = EPHY_NODE (iter->user_data); - - if (ephy_node_get_property_int (node, EPHY_NODE_PAGE_PROP_HOST_ID) < 0 && - (column == EPHY_HISTORY_MODEL_COL_FIRST_VISIT || - column == EPHY_HISTORY_MODEL_COL_LAST_VISIT || - column == EPHY_HISTORY_MODEL_COL_VISITS)) - { - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, ""); - return; - } - - switch (column) - { - case EPHY_HISTORY_MODEL_COL_TITLE: - ephy_node_get_property (node, - EPHY_NODE_PAGE_PROP_TITLE, - value); - break; - case EPHY_HISTORY_MODEL_COL_LOCATION: - ephy_node_get_property (node, - EPHY_NODE_PAGE_PROP_LOCATION, - value); - break; - case EPHY_HISTORY_MODEL_COL_VISITS: - ephy_node_get_property (node, - EPHY_NODE_PAGE_PROP_VISITS, - value); - break; - case EPHY_HISTORY_MODEL_COL_FIRST_VISIT: - get_property_as_date (node, - EPHY_NODE_PAGE_PROP_FIRST_VISIT, - value); - break; - case EPHY_HISTORY_MODEL_COL_LAST_VISIT: - get_property_as_date (node, - EPHY_NODE_PAGE_PROP_LAST_VISIT, - value); - break; - case EPHY_HISTORY_MODEL_COL_VISIBLE: - g_value_init (value, G_TYPE_BOOLEAN); - - if (model->priv->filter != NULL) - { - g_value_set_boolean (value, - ephy_node_filter_evaluate (model->priv->filter, node)); - } - else - { - g_value_set_boolean (value, TRUE); - } - break; - default: - g_assert_not_reached (); - break; - } -} - -static gboolean -ephy_history_model_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); - g_return_val_if_fail (iter->stamp == EPHY_HISTORY_MODEL (tree_model)->stamp, FALSE); - - node = EPHY_NODE (iter->user_data); - - iter->user_data = ephy_node_get_next_child - (get_parent_node (model, node), node); - - return (iter->user_data != NULL); -} - -static gboolean -ephy_history_model_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - node = ensure_iter (model, parent); - - iter->user_data = ephy_node_get_nth_child (node, 0); - iter->stamp = model->stamp; - - return (iter->user_data != NULL); -} - -static gboolean -ephy_history_model_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - int host_id; - - node = EPHY_NODE (iter->user_data); - host_id = ephy_node_get_property_int (node, EPHY_NODE_PAGE_PROP_HOST_ID); - if (host_id < 0) - { - return ephy_node_has_child (model->priv->root, node); - } - else - { - return FALSE; - } -} - -static int -ephy_history_model_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE); - - node = ensure_iter (model, iter); - - return ephy_node_get_n_children (node); -} - -static gboolean -ephy_history_model_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - int n) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *node; - - node = ensure_iter (model, parent); - - iter->user_data = ephy_node_get_nth_child (node, n); - iter->stamp = model->stamp; - - return (iter->user_data != NULL); -} - -static gboolean -ephy_history_model_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child) -{ - EphyHistoryModel *model = EPHY_HISTORY_MODEL (tree_model); - EphyNode *parent, *node; - - node = EPHY_NODE (iter->user_data); - parent = get_parent_node (model, node); - - if (parent != model->priv->root) - { - iter->user_data = parent; - iter->stamp = model->stamp; - return TRUE; - } - else - { - return FALSE; - } -} - -EphyNode * -ephy_history_model_node_from_iter (EphyHistoryModel *model, - GtkTreeIter *iter) -{ - return EPHY_NODE (iter->user_data); -} - -void -ephy_history_model_iter_from_node (EphyHistoryModel *model, - EphyNode *node, - GtkTreeIter *iter) -{ - iter->stamp = model->stamp; - iter->user_data = node; -} - -static inline void -ephy_history_model_update_node (EphyHistoryModel *model, - EphyNode *node, - int idx) -{ - GtkTreePath *path; - GtkTreeIter iter; - - ephy_history_model_iter_from_node (model, node, &iter); - - if (idx >= 0) - { - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, idx); - } - else - { - path = get_one_level_path_real (model, node); - } - - gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); - gtk_tree_path_free (path); -} - -static void -root_child_removed_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model) -{ - GtkTreePath *path; - - if (node == model->priv->root) - { - path = get_one_level_path_real (model, child); - } - else - { - path = get_path_real (model, child); - } - - if (path) - { - gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); - gtk_tree_path_free (path); - } -} - -static void -root_child_added_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model) -{ - GtkTreePath *path; - GtkTreeIter iter; - - ephy_history_model_iter_from_node (model, child, &iter); - - if (node == model->priv->root) - { - path = get_one_level_path_real (model, child); - } - else - { - path = get_path_real (model, child); - } - - gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); - gtk_tree_path_free (path); -} - -static void -root_child_changed_cb (EphyNode *node, - EphyNode *child, - EphyHistoryModel *model) -{ - ephy_history_model_update_node (model, child, -1); -} - -GType -ephy_history_model_column_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) - { - static const GEnumValue values[] = - { - { EPHY_HISTORY_MODEL_COL_TITLE, "EPHY_HISTORY_MODEL_COL_TITLE", "title" }, - { EPHY_HISTORY_MODEL_COL_LOCATION, "EPHY_HISTORY_MODEL_COL_LOCATION", "location" }, - { EPHY_HISTORY_MODEL_COL_VISITS, "EPHY_HISTORY_MODEL_COL_VISITS", "visits" }, - { EPHY_HISTORY_MODEL_COL_FIRST_VISIT, "EPHY_HISTORY_MODEL_COL_FIRST_VISIT", "last_visit" }, - { EPHY_HISTORY_MODEL_COL_LAST_VISIT, "EPHY_HISTORY_MODEL_COL_LAST_VISIT", "last_visit" }, - { EPHY_HISTORY_MODEL_COL_VISIBLE, "EPHY_HISTORY_MODEL_COL_FIRST_VISIT", "first_visit" }, - - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("EphyHistoryModelColumn", values); - } - - return etype; -} - diff --git a/src/ephy-history-model.h b/src/ephy-history-model.h deleted file mode 100644 index 6ff0058de..000000000 --- a/src/ephy-history-model.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2002 Jorn Baayen - * - * 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 of the License, 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. - * - * $Id$ - */ - -#ifndef __EPHY_HISTORY_MODEL_H -#define __EPHY_HISTORY_MODEL_H - -#include - -#include "ephy-node.h" -#include "ephy-node-filter.h" - -G_BEGIN_DECLS - -#define EPHY_TYPE_HISTORY_MODEL (ephy_history_model_get_type ()) -#define EPHY_HISTORY_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_HISTORY_MODEL, EphyHistoryModel)) -#define EPHY_HISTORY_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_HISTORY_MODEL, EphyHistoryModelClass)) -#define EPHY_IS_HISTORY_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_HISTORY_MODEL)) -#define EPHY_IS_HISTORY_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_HISTORY_MODEL)) -#define EPHY_HISTORY_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_HISTORY_MODEL, EphyHistoryModelClass)) - -typedef enum -{ - EPHY_HISTORY_MODEL_COL_TITLE, - EPHY_HISTORY_MODEL_COL_LOCATION, - EPHY_HISTORY_MODEL_COL_VISITS, - EPHY_HISTORY_MODEL_COL_FIRST_VISIT, - EPHY_HISTORY_MODEL_COL_LAST_VISIT, - EPHY_HISTORY_MODEL_COL_VISIBLE, - EPHY_HISTORY_MODEL_NUM_COLUMNS -} EphyHistoryModelColumn; - -GType ephy_history_model_column_get_type (void); - -#define EPHY_TYPE_HISTORY_MODEL_COLUMN (ephy_history_model_column_get_type ()) - -typedef struct EphyHistoryModelPrivate EphyHistoryModelPrivate; - -typedef struct -{ - GObject parent; - - EphyHistoryModelPrivate *priv; - - int stamp; -} EphyHistoryModel; - -typedef struct -{ - GObjectClass parent; -} EphyHistoryModelClass; - -GType ephy_history_model_get_type (void); - -EphyHistoryModel *ephy_history_model_new (EphyNode *root, - EphyNode *pages, - EphyNodeFilter *filter); - -EphyNode *ephy_history_model_node_from_iter (EphyHistoryModel *model, - GtkTreeIter *iter); - -void ephy_history_model_iter_from_node (EphyHistoryModel *model, - EphyNode *node, - GtkTreeIter *iter); - -G_END_DECLS - -#endif /* EPHY_HISTORY_MODEL_H */ diff --git a/src/ephy-history-window.c b/src/ephy-history-window.c new file mode 100644 index 000000000..10e06e592 --- /dev/null +++ b/src/ephy-history-window.c @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2003 Marco Pesenti Gritti + * + * 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 of the License, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ephy-node-view.h" +#include "ephy-window.h" +#include "ephy-history-window.h" +#include "ephy-shell.h" +#include "ephy-dnd.h" +#include "ephy-prefs.h" +#include "egg-action-group.h" +#include "egg-menu-merge.h" +#include "ephy-state.h" +#include "window-commands.h" +#include "ephy-file-helpers.h" +#include "ephy-debug.h" + +static GtkTargetEntry page_drag_types [] = +{ + { EPHY_DND_URI_LIST_TYPE, 0, 0 }, + { EPHY_DND_TEXT_TYPE, 0, 1 }, + { EPHY_DND_URL_TYPE, 0, 2 }, + { EPHY_DND_BOOKMARK_TYPE, 0, 3 } +}; +static int n_page_drag_types = G_N_ELEMENTS (page_drag_types); + +static void ephy_history_window_class_init (EphyHistoryWindowClass *klass); +static void ephy_history_window_init (EphyHistoryWindow *editor); +static void ephy_history_window_finalize (GObject *object); +static void ephy_history_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void ephy_history_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void search_entry_changed_cb (GtkWidget *entry, + EphyHistoryWindow *editor); +static void cmd_open_bookmarks_in_tabs (EggAction *action, + EphyHistoryWindow *editor); +static void cmd_open_bookmarks_in_browser (EggAction *action, + EphyHistoryWindow *editor); +static void cmd_clear (EggAction *action, + EphyHistoryWindow *editor); +static void cmd_close (EggAction *action, + EphyHistoryWindow *editor); +static void cmd_help_contents (EggAction *action, + EphyHistoryWindow *editor); + +struct EphyHistoryWindowPrivate +{ + EphyHistory *history; + GtkWidget *sites_view; + GtkWidget *pages_view; + EphyNodeFilter *pages_filter; + GtkWidget *search_entry; + GtkWidget *menu_dock; + GtkWidget *window; + EggMenuMerge *ui_merge; + EggActionGroup *action_group; +}; + +enum +{ + PROP_0, + PROP_HISTORY +}; + +static GObjectClass *parent_class = NULL; + +static EggActionGroupEntry ephy_history_ui_entries [] = { + /* Toplevel */ + { "File", N_("_File"), NULL, NULL, NULL, NULL, NULL }, + { "Help", N_("_Help"), NULL, NULL, NULL, NULL, NULL }, + { "FakeToplevel", (""), NULL, NULL, NULL, NULL, NULL }, + + { "OpenInWindow", N_("_Open in New Window"), GTK_STOCK_OPEN, "O", + NULL, G_CALLBACK (cmd_open_bookmarks_in_browser), NULL }, + + { "OpenInTab", N_("Open in New _Tab"), NULL, "O", + NULL, G_CALLBACK (cmd_open_bookmarks_in_tabs), NULL }, + + { "Clear", N_("Clea_r"), GTK_STOCK_CLEAR, NULL, + NULL, G_CALLBACK (cmd_clear), NULL }, + + { "Close", N_("_Close"), GTK_STOCK_CLOSE, "W", + NULL, G_CALLBACK (cmd_close), NULL }, + + { "HelpContents", N_("_Contents"), GTK_STOCK_HELP, "F1", + NULL, G_CALLBACK (cmd_help_contents), NULL }, + + { "HelpAbout", N_("_About"), GNOME_STOCK_ABOUT, NULL, + NULL, G_CALLBACK (window_cmd_help_about), NULL }, + +}; +static guint ephy_history_ui_n_entries = G_N_ELEMENTS (ephy_history_ui_entries); + +static void +cmd_clear (EggAction *action, + EphyHistoryWindow *editor) +{ +} + +static void +cmd_close (EggAction *action, + EphyHistoryWindow *editor) +{ + gtk_widget_hide (GTK_WIDGET (editor)); +} + +static GtkWidget * +get_target_window (EphyHistoryWindow *editor) +{ + if (editor->priv->window) + { + return editor->priv->window; + } + else + { + return GTK_WIDGET (ephy_shell_get_active_window (ephy_shell)); + } +} + +static void +cmd_open_bookmarks_in_tabs (EggAction *action, + EphyHistoryWindow *editor) +{ + EphyWindow *window; + GList *selection; + GList *l; + + window = EPHY_WINDOW (get_target_window (editor)); + selection = ephy_node_view_get_selection (EPHY_NODE_VIEW (editor->priv->pages_view)); + + for (l = selection; l; l = l->next) + { + EphyNode *node = EPHY_NODE (l->data); + const char *location; + + location = ephy_node_get_property_string (node, + EPHY_NODE_PAGE_PROP_LOCATION); + + ephy_shell_new_tab (ephy_shell, window, NULL, location, + EPHY_NEW_TAB_APPEND|EPHY_NEW_TAB_IN_EXISTING_WINDOW); + } + + g_list_free (selection); +} + +static void +cmd_open_bookmarks_in_browser (EggAction *action, + EphyHistoryWindow *editor) +{ + EphyWindow *window; + GList *selection; + GList *l; + + window = EPHY_WINDOW (get_target_window (editor)); + selection = ephy_node_view_get_selection (EPHY_NODE_VIEW (editor->priv->pages_view)); + + for (l = selection; l; l = l->next) + { + EphyNode *node = EPHY_NODE (l->data); + const char *location; + + location = ephy_node_get_property_string (node, + EPHY_NODE_PAGE_PROP_LOCATION); + + ephy_shell_new_tab (ephy_shell, window, NULL, location, + EPHY_NEW_TAB_IN_NEW_WINDOW); + } + + g_list_free (selection); +} + +static void +cmd_help_contents (EggAction *action, + EphyHistoryWindow *editor) +{ + /*FIXME: Implement help.*/ +} + +GType +ephy_history_window_get_type (void) +{ + static GType ephy_history_window_type = 0; + + if (ephy_history_window_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyHistoryWindowClass), + NULL, + NULL, + (GClassInitFunc) ephy_history_window_class_init, + NULL, + NULL, + sizeof (EphyHistoryWindow), + 0, + (GInstanceInitFunc) ephy_history_window_init + }; + + ephy_history_window_type = g_type_register_static (GTK_TYPE_WINDOW, + "EphyHistoryWindow", + &our_info, 0); + } + + return ephy_history_window_type; +} + +static void +ephy_history_window_class_init (EphyHistoryWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_history_window_finalize; + + object_class->set_property = ephy_history_window_set_property; + object_class->get_property = ephy_history_window_get_property; + + g_object_class_install_property (object_class, + PROP_HISTORY, + g_param_spec_object ("history", + "Global history", + "Global History", + EPHY_HISTORY_TYPE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +static void +ephy_history_window_finalize (GObject *object) +{ + EphyHistoryWindow *editor; + + g_return_if_fail (object != NULL); + g_return_if_fail (EPHY_IS_HISTORY_WINDOW (object)); + + editor = EPHY_HISTORY_WINDOW (object); + + g_return_if_fail (editor->priv != NULL); + + g_object_unref (G_OBJECT (editor->priv->pages_filter)); + + g_object_unref (editor->priv->action_group); + egg_menu_merge_remove_action_group (editor->priv->ui_merge, + editor->priv->action_group); + g_object_unref (editor->priv->ui_merge); + + if (editor->priv->window) + { + g_object_remove_weak_pointer + (G_OBJECT(editor->priv->window), + (gpointer *)&editor->priv->window); + } + + g_free (editor->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_history_window_node_activated_cb (GtkWidget *view, + EphyNode *node, + EphyHistoryWindow *editor) +{ + const char *location; + EphyWindow *window; + + g_return_if_fail (EPHY_IS_NODE (node)); + location = ephy_node_get_property_string + (node, EPHY_NODE_PAGE_PROP_LOCATION); + g_return_if_fail (location != NULL); + + window = EPHY_WINDOW (get_target_window (editor)); + if (window != NULL) + { + ephy_window_load_url (EPHY_WINDOW (window), location); + gtk_window_present (GTK_WINDOW (window)); + } + else + { + /* We have to create a browser window */ + ephy_shell_new_tab (ephy_shell, NULL, NULL, location, + EPHY_NEW_TAB_IN_NEW_WINDOW); + } +} + +static void +ephy_history_window_update_menu (EphyHistoryWindow *editor) +{ + gboolean open_in_window, open_in_tab; + gboolean pages_focus, pages_selection; + gboolean pages_multiple_selection; + EggActionGroup *action_group; + EggAction *action; + char *open_in_window_label, *open_in_tab_label; + + pages_focus = ephy_node_view_is_target + (EPHY_NODE_VIEW (editor->priv->pages_view)); + pages_selection = ephy_node_view_has_selection + (EPHY_NODE_VIEW (editor->priv->pages_view), + &pages_multiple_selection); + + if (pages_multiple_selection) + { + open_in_window_label = N_("_Open in New Windows"); + open_in_tab_label = N_("Open in New _Tabs"); + } + else + { + open_in_window_label = _("_Open in New Window"); + open_in_tab_label = _("Open in New _Tab"); + } + + open_in_window = (pages_focus && pages_selection); + open_in_tab = (pages_focus && pages_selection); + + action_group = editor->priv->action_group; + action = egg_action_group_get_action (action_group, "OpenInWindow"); + g_object_set (action, "sensitive", open_in_window, NULL); + g_object_set (action, "label", open_in_window_label, NULL); + action = egg_action_group_get_action (action_group, "OpenInTab"); + g_object_set (action, "sensitive", open_in_tab, NULL); + g_object_set (action, "label", open_in_tab_label, NULL); +} + +static void +ephy_history_window_show_popup_cb (GtkWidget *view, + EphyHistoryWindow *editor) +{ + GtkWidget *widget; + + widget = egg_menu_merge_get_widget (editor->priv->ui_merge, + "/popups/EphyHistoryWindowPopup"); + ephy_history_window_update_menu (editor); + gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL, 2, + gtk_get_current_event_time ()); +} + +static void +pages_filter (EphyHistoryWindow *editor, + EphyNode *site) +{ + ephy_node_filter_empty (editor->priv->pages_filter); + ephy_node_filter_add_expression (editor->priv->pages_filter, + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_HAS_PARENT, + site), + 0); + ephy_node_filter_done_changing (editor->priv->pages_filter); +} + +static void +reset_search_entry (EphyHistoryWindow *editor) +{ + g_signal_handlers_block_by_func + (G_OBJECT (editor->priv->search_entry), + G_CALLBACK (search_entry_changed_cb), + editor); + gtk_entry_set_text (GTK_ENTRY (editor->priv->search_entry), ""); + g_signal_handlers_unblock_by_func + (G_OBJECT (editor->priv->search_entry), + G_CALLBACK (search_entry_changed_cb), + editor); +} + +static void +site_node_selected_cb (EphyNodeView *view, + EphyNode *node, + EphyHistoryWindow *editor) +{ + EphyNode *pages; + + if (node == NULL) + { + pages = ephy_history_get_pages (editor->priv->history); + ephy_node_view_select_node (EPHY_NODE_VIEW (editor->priv->sites_view), pages); + } + else + { + reset_search_entry (editor); + pages_filter (editor, node); + } +} + +static void +search_entry_changed_cb (GtkWidget *entry, EphyHistoryWindow *editor) +{ + EphyNode *all; + char *search_text; + + g_signal_handlers_block_by_func + (G_OBJECT (editor->priv->sites_view), + G_CALLBACK (site_node_selected_cb), + editor); + all = ephy_history_get_pages (editor->priv->history); + ephy_node_view_select_node (EPHY_NODE_VIEW (editor->priv->sites_view), + all); + g_signal_handlers_unblock_by_func + (G_OBJECT (editor->priv->sites_view), + G_CALLBACK (site_node_selected_cb), + editor); + + search_text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); + + GDK_THREADS_ENTER (); + + ephy_node_filter_empty (editor->priv->pages_filter); + ephy_node_filter_add_expression (editor->priv->pages_filter, + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, + EPHY_NODE_PAGE_PROP_TITLE, + search_text), + 0); + ephy_node_filter_add_expression (editor->priv->pages_filter, + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, + EPHY_NODE_PAGE_PROP_LOCATION, + search_text), + 0); + ephy_node_filter_done_changing (editor->priv->pages_filter); + + GDK_THREADS_LEAVE (); + + g_free (search_text); +} + +static GtkWidget * +build_search_box (EphyHistoryWindow *editor) +{ + GtkWidget *box; + GtkWidget *label; + GtkWidget *entry; + char *str; + + box = gtk_hbox_new (FALSE, 6); + gtk_widget_show (box); + + entry = gtk_entry_new (); + editor->priv->search_entry = entry; + gtk_widget_show (entry); + g_signal_connect (G_OBJECT (entry), "changed", + G_CALLBACK (search_entry_changed_cb), + editor); + + label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + str = g_strconcat ("", _("_Search:"), "", NULL); + gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), str); + g_free (str); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); + gtk_widget_show (label); + + gtk_box_pack_start (GTK_BOX (box), + label, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), + entry, TRUE, TRUE, 0); + + return box; +} + +static void +add_widget (EggMenuMerge *merge, GtkWidget *widget, EphyHistoryWindow *editor) +{ + gtk_box_pack_start (GTK_BOX (editor->priv->menu_dock), + widget, FALSE, FALSE, 0); + gtk_widget_show (widget); +} + +static gboolean +delete_event_cb (EphyHistoryWindow *editor) +{ + gtk_widget_hide (GTK_WIDGET (editor)); + + return TRUE; +} + +static void +menu_activate_cb (EphyNodeView *view, + EphyHistoryWindow *editor) +{ + ephy_history_window_update_menu (editor); +} + +static void +ephy_history_window_construct (EphyHistoryWindow *editor) +{ + GtkTreeSelection *selection; + GtkWidget *vbox, *hpaned; + GtkWidget *pages_view, *sites_view; + GtkWidget *scrolled_window; + GtkWidget *menu; + EphyNode *node; + EggMenuMerge *ui_merge; + EggActionGroup *action_group; + const char *icon_path; + int i; + + ephy_state_add_window (GTK_WIDGET(editor), + "history_window", + 450, 400); + + gtk_window_set_title (GTK_WINDOW (editor), _("History")); + + icon_path = ephy_file ("epiphany-history.png"); + gtk_window_set_icon_from_file (GTK_WINDOW (editor), icon_path, NULL); + + g_signal_connect (editor, "delete_event", + G_CALLBACK (delete_event_cb), NULL); + + for (i = 0; i < ephy_history_ui_n_entries; i++) + { + ephy_history_ui_entries[i].user_data = editor; + } + + editor->priv->menu_dock = gtk_vbox_new (FALSE, 0); + gtk_widget_show (editor->priv->menu_dock); + gtk_container_add (GTK_CONTAINER (editor), editor->priv->menu_dock); + + ui_merge = egg_menu_merge_new (); + g_signal_connect (ui_merge, "add_widget", G_CALLBACK (add_widget), editor); + action_group = egg_action_group_new ("PopupActions"); + egg_action_group_add_actions (action_group, ephy_history_ui_entries, + ephy_history_ui_n_entries); + egg_menu_merge_insert_action_group (ui_merge, + action_group, 0); + egg_menu_merge_add_ui_from_file (ui_merge, + ephy_file ("epiphany-history-window-ui.xml"), + NULL); + gtk_window_add_accel_group (GTK_WINDOW (editor), ui_merge->accel_group); + egg_menu_merge_ensure_update (ui_merge); + editor->priv->ui_merge = ui_merge; + editor->priv->action_group = action_group; + + /* Update menu sensitivity before showing them */ + menu = egg_menu_merge_get_widget (ui_merge, "/menu/FileMenu"); + g_signal_connect (menu, "activate", G_CALLBACK (menu_activate_cb), editor); + + hpaned = gtk_hpaned_new (); + gtk_container_set_border_width (GTK_CONTAINER (hpaned), 6); + gtk_container_add (GTK_CONTAINER (editor->priv->menu_dock), hpaned); + gtk_widget_show (hpaned); + + g_assert (editor->priv->history); + + /* Sites View */ + node = ephy_history_get_hosts (editor->priv->history); + scrolled_window = g_object_new (GTK_TYPE_SCROLLED_WINDOW, + "hadjustment", NULL, + "vadjustment", NULL, + "hscrollbar_policy", GTK_POLICY_AUTOMATIC, + "vscrollbar_policy", GTK_POLICY_AUTOMATIC, + "shadow_type", GTK_SHADOW_IN, + NULL); + gtk_paned_add1 (GTK_PANED (hpaned), scrolled_window); + gtk_widget_show (scrolled_window); + sites_view = ephy_node_view_new (node, NULL); + ephy_node_view_enable_drag_source (EPHY_NODE_VIEW (sites_view), + page_drag_types, + n_page_drag_types, + EPHY_NODE_PAGE_PROP_LOCATION); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sites_view)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + ephy_node_view_add_column (EPHY_NODE_VIEW (sites_view), _("Sites"), + G_TYPE_STRING, + EPHY_NODE_PAGE_PROP_LOCATION, + EPHY_NODE_PAGE_PROP_PRIORITY, + FALSE, FALSE); + gtk_container_add (GTK_CONTAINER (scrolled_window), sites_view); + gtk_widget_show (sites_view); + editor->priv->sites_view = sites_view; + g_signal_connect (G_OBJECT (sites_view), + "node_selected", + G_CALLBACK (site_node_selected_cb), + editor); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_paned_add2 (GTK_PANED (hpaned), vbox); + gtk_widget_show (vbox); + + gtk_box_pack_start (GTK_BOX (vbox), + build_search_box (editor), + FALSE, FALSE, 0); + + + /* Pages View */ + scrolled_window = g_object_new (GTK_TYPE_SCROLLED_WINDOW, + "hadjustment", NULL, + "vadjustment", NULL, + "hscrollbar_policy", GTK_POLICY_AUTOMATIC, + "vscrollbar_policy", GTK_POLICY_AUTOMATIC, + "shadow_type", GTK_SHADOW_IN, + NULL); + gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); + gtk_widget_show (scrolled_window); + node = ephy_history_get_pages (editor->priv->history); + editor->priv->pages_filter = ephy_node_filter_new (); + pages_view = ephy_node_view_new (node, editor->priv->pages_filter); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pages_view), TRUE); + ephy_node_view_enable_drag_source (EPHY_NODE_VIEW (pages_view), + page_drag_types, + n_page_drag_types, + EPHY_NODE_PAGE_PROP_LOCATION); + ephy_node_view_add_column (EPHY_NODE_VIEW (pages_view), _("Title"), + G_TYPE_STRING, EPHY_NODE_PAGE_PROP_TITLE, + -1, FALSE, FALSE); + ephy_node_view_add_column (EPHY_NODE_VIEW (pages_view), _("Location"), + G_TYPE_STRING, EPHY_NODE_PAGE_PROP_LOCATION, + -1, FALSE, FALSE); + gtk_container_add (GTK_CONTAINER (scrolled_window), pages_view); + gtk_widget_show (pages_view); + editor->priv->pages_view = pages_view; + g_signal_connect (G_OBJECT (pages_view), + "node_activated", + G_CALLBACK (ephy_history_window_node_activated_cb), + editor); + g_signal_connect (G_OBJECT (pages_view), + "show_popup", + G_CALLBACK (ephy_history_window_show_popup_cb), + editor); +} + +void +ephy_history_window_set_parent (EphyHistoryWindow *ebe, + GtkWidget *window) +{ + if (ebe->priv->window) + { + g_object_remove_weak_pointer + (G_OBJECT(ebe->priv->window), + (gpointer *)&ebe->priv->window); + } + + ebe->priv->window = window; + + g_object_add_weak_pointer + (G_OBJECT(ebe->priv->window), + (gpointer *)&ebe->priv->window); + +} + +GtkWidget * +ephy_history_window_new (EphyHistory *history) +{ + EphyHistoryWindow *editor; + + g_assert (history != NULL); + + editor = EPHY_HISTORY_WINDOW (g_object_new + (EPHY_TYPE_HISTORY_WINDOW, + "history", history, + NULL)); + + ephy_history_window_construct (editor); + + return GTK_WIDGET (editor); +} + +static void +ephy_history_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyHistoryWindow *editor = EPHY_HISTORY_WINDOW (object); + + switch (prop_id) + { + case PROP_HISTORY: + editor->priv->history = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_history_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyHistoryWindow *editor = EPHY_HISTORY_WINDOW (object); + + switch (prop_id) + { + case PROP_HISTORY: + g_value_set_object (value, editor->priv->history); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_history_window_init (EphyHistoryWindow *editor) +{ + editor->priv = g_new0 (EphyHistoryWindowPrivate, 1); +} diff --git a/src/ephy-history-window.h b/src/ephy-history-window.h new file mode 100644 index 000000000..bf2e3473e --- /dev/null +++ b/src/ephy-history-window.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2003 Marco Pesenti Gritti + * + * 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 of the License, 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. + * + */ + +#ifndef EPHY_HISTORY_WINDOW_H +#define EPHY_HISTORY_WINDOW_H + +#include + +#include "ephy-node-view.h" +#include "ephy-history.h" + +G_BEGIN_DECLS + +#define EPHY_TYPE_HISTORY_WINDOW (ephy_history_window_get_type ()) +#define EPHY_HISTORY_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_HISTORY_WINDOW, EphyHistoryWindow)) +#define EPHY_HISTORY_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_HISTORY_WINDOW, EphyHistoryWindowClass)) +#define EPHY_IS_HISTORY_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_HISTORY_WINDOW)) +#define EPHY_IS_HISTORY_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_HISTORY_WINDOW)) +#define EPHY_HISTORY_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_HISTORY_WINDOW, EphyHistoryWindowClass)) + +typedef struct EphyHistoryWindowPrivate EphyHistoryWindowPrivate; + +typedef struct +{ + GtkWindow parent; + + EphyHistoryWindowPrivate *priv; +} EphyHistoryWindow; + +typedef struct +{ + GtkWindowClass parent; +} EphyHistoryWindowClass; + +GType ephy_history_window_get_type (void); + +GtkWidget *ephy_history_window_new (EphyHistory *history); + +void ephy_history_window_set_parent (EphyHistoryWindow *ehw, + GtkWidget *window); + +G_END_DECLS + +#endif /* EPHY_HISTORY_WINDOW_H */ diff --git a/src/ephy-shell.c b/src/ephy-shell.c index 78506c19e..29069a292 100644 --- a/src/ephy-shell.c +++ b/src/ephy-shell.c @@ -32,6 +32,7 @@ #include "ephy-thread-helpers.h" #include "ephy-bookmarks-import.h" #include "ephy-bookmarks-editor.h" +#include "ephy-history-window.h" #include "ephy-debug.h" #include "toolbar.h" @@ -58,6 +59,7 @@ struct EphyShellPrivate EphyAutocompletion *autocompletion; EphyBookmarks *bookmarks; GtkWidget *bme; + GtkWidget *history_window; }; enum @@ -260,6 +262,7 @@ ephy_shell_init (EphyShell *gs) gs->priv->session = NULL; gs->priv->bookmarks = NULL; gs->priv->bme = NULL; + gs->priv->history_window = NULL; ephy_shell = gs; g_object_add_weak_pointer (G_OBJECT(ephy_shell), @@ -324,6 +327,12 @@ ephy_shell_finalize (GObject *object) gtk_widget_destroy (GTK_WIDGET (gs->priv->bme)); } + LOG ("Unref History Window"); + if (gs->priv->history_window) + { + gtk_widget_destroy (GTK_WIDGET (gs->priv->history_window)); + } + LOG ("Unref bookmarks") if (gs->priv->bookmarks) { @@ -636,7 +645,7 @@ void ephy_shell_show_bookmarks_editor (EphyShell *gs) { EphyBookmarks *bookmarks; - + if (gs->priv->bme == NULL) { bookmarks = ephy_shell_get_bookmarks (ephy_shell); @@ -655,3 +664,34 @@ ephy_shell_show_bookmarks_editor (EphyShell *gs) gtk_window_present (GTK_WINDOW (gs->priv->bme)); } +static void +history_window_hide_cb (GtkWidget *widget, gpointer data) +{ + LOG ("Unref shell for history window") + g_object_unref (ephy_shell); +} + +void +ephy_shell_show_history_window (EphyShell *gs) +{ + EphyHistory *history; + + if (gs->priv->history_window == NULL) + { + history = ephy_embed_shell_get_global_history + (EPHY_EMBED_SHELL (ephy_shell)); + g_assert (history != NULL); + gs->priv->history_window = ephy_history_window_new (history); + g_signal_connect (gs->priv->history_window, "hide", + G_CALLBACK (history_window_hide_cb), NULL); + } + + if (!GTK_WIDGET_VISIBLE (gs->priv->history_window)) + { + LOG ("Ref shell for history window") + g_object_ref (ephy_shell); + } + + gtk_window_present (GTK_WINDOW (gs->priv->history_window)); +} + diff --git a/src/ephy-shell.h b/src/ephy-shell.h index f4ec200ed..ab4f3aa0e 100644 --- a/src/ephy-shell.h +++ b/src/ephy-shell.h @@ -94,7 +94,9 @@ EphyAutocompletion *ephy_shell_get_autocompletion (EphyShell *gs); EphyBookmarks *ephy_shell_get_bookmarks (EphyShell *gs); -void ephy_shell_show_bookmarks_editor (EphyShell *gs); +void ephy_shell_show_bookmarks_editor (EphyShell *gs); + +void ephy_shell_show_history_window (EphyShell *gs); G_END_DECLS diff --git a/src/ephy-window.c b/src/ephy-window.c index f9cd8addd..8c35cd91e 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -27,7 +27,6 @@ #include "ppview-toolbar.h" #include "window-commands.h" #include "find-dialog.h" -#include "history-dialog.h" #include "ephy-shell.h" #include "eel-gconf-extensions.h" #include "ephy-prefs.h" @@ -265,8 +264,6 @@ struct EphyWindowPrivate EphyTab *active_tab; GtkWidget *sidebar; EphyDialog *find_dialog; - EphyDialog *history_dialog; - EphyDialog *history_sidebar; EmbedChromeMask chrome_mask; gboolean closing; }; @@ -590,13 +587,6 @@ ephy_window_finalize (GObject *object) g_object_unref (G_OBJECT (window->priv->find_dialog)); } - if (window->priv->history_dialog) - { - g_object_remove_weak_pointer - (G_OBJECT(window->priv->history_dialog), - (gpointer *)&window->priv->history_dialog); - } - g_object_unref (window->priv->fav_menu); g_object_unref (window->priv->enc_menu); @@ -1359,8 +1349,6 @@ update_embed_dialogs (EphyWindow *window, { EphyEmbed *embed; EphyDialog *find_dialog = window->priv->find_dialog; - EphyDialog *history_dialog = window->priv->history_dialog; - EphyDialog *history_sidebar = window->priv->history_sidebar; embed = ephy_tab_get_embed (tab); @@ -1370,20 +1358,6 @@ update_embed_dialogs (EphyWindow *window, (EPHY_EMBED_DIALOG(find_dialog), embed); } - - if (history_dialog) - { - ephy_embed_dialog_set_embed - (EPHY_EMBED_DIALOG(history_dialog), - embed); - } - - if (history_sidebar) - { - ephy_embed_dialog_set_embed - (EPHY_EMBED_DIALOG(history_sidebar), - embed); - } } static void @@ -1450,25 +1424,6 @@ ephy_window_get_find_dialog (EphyWindow *window) return dialog; } -void -ephy_window_show_history (EphyWindow *window) -{ - EphyEmbed *embed; - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - window->priv->history_dialog = history_dialog_new_with_parent - (GTK_WIDGET(window), - embed, - FALSE); - g_object_add_weak_pointer - (G_OBJECT(window->priv->history_dialog), - (gpointer *)&window->priv->history_dialog); - - ephy_dialog_show (window->priv->history_dialog); -} - void ephy_window_set_zoom (EphyWindow *window, gint zoom) diff --git a/src/ephy-window.h b/src/ephy-window.h index f0e658a2a..a0e44269b 100644 --- a/src/ephy-window.h +++ b/src/ephy-window.h @@ -130,8 +130,6 @@ Toolbar *ephy_window_get_toolbar (EphyWindow *window); EphyDialog *ephy_window_get_find_dialog (EphyWindow *window); -void ephy_window_show_history (EphyWindow *window); - G_END_DECLS #endif diff --git a/src/history-dialog.c b/src/history-dialog.c deleted file mode 100755 index ed6003c19..000000000 --- a/src/history-dialog.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (C) 2002 Jorn Baayen - * - * 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 "ephy-node-view.h" -#include "history-dialog.h" -#include "ephy-shell.h" -#include "ephy-embed-shell.h" -#include "ephy-file-helpers.h" -#include "ephy-string.h" -#include "ephy-gui.h" -#include "ephy-dnd.h" -#include "ephy-node-filter.h" -#include "ephy-history-model.h" -#include "eggtreemodelfilter.h" -#include "eggtreemultidnd.h" -#include "ephy-tree-model-sort.h" -#include "toolbar.h" - -#include -#include -#include -#include - -static GtkTargetEntry url_drag_types [] = -{ - { EPHY_DND_URI_LIST_TYPE, 0, 0 }, - { EPHY_DND_TEXT_TYPE, 0, 1 }, - { EPHY_DND_URL_TYPE, 0, 2 } -}; -static int n_url_drag_types = G_N_ELEMENTS (url_drag_types); - -#define CONF_HISTORY_SEARCH_TEXT "/apps/epiphany/history/search_text" -#define CONF_HISTORY_SEARCH_TIME "/apps/epiphany/history/search_time" - -static void history_dialog_class_init (HistoryDialogClass *klass); -static void history_dialog_init (HistoryDialog *dialog); -static void history_dialog_finalize (GObject *object); -static void history_dialog_set_embedded (HistoryDialog *d, - gboolean embedded); - - -/* Glade callbacks */ -void -history_host_checkbutton_toggled_cb (GtkWidget *widget, - HistoryDialog *dialog); -void -history_time_optionmenu_changed_cb (GtkWidget *widget, - HistoryDialog *dialog); -void -history_entry_changed_cb (GtkWidget *widget, - HistoryDialog *dialog); -void -history_go_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog); -void -history_ok_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog); -void -history_clear_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog); - - -static GObjectClass *parent_class = NULL; - -struct HistoryDialogPrivate -{ - GtkWidget *window; - EphyHistory *gh; - EphyNode *root; - EphyNode *pages; - EphyNodeFilter *filter; - GtkTreeView *treeview; - GtkTreeModel *model; - EphyHistoryModel *nodemodel; - GtkTreeModel *filtermodel; - EphyTreeModelSort *sortmodel; - GtkWidget *go_button; - gboolean group; - gboolean embedded; -}; - -enum -{ - PROP_0, - PROP_EMBEDDED -}; - -enum -{ - PROP_WINDOW, - PROP_TREEVIEW, - PROP_WORD, - PROP_TIME, - PROP_GO_BUTTON -}; - -static const -EphyDialogProperty properties [] = -{ - { PROP_WINDOW, "history_dialog", NULL, PT_NORMAL, NULL }, - { PROP_TREEVIEW, "history_treeview", NULL, PT_NORMAL, NULL }, - { PROP_WORD, "history_entry", CONF_HISTORY_SEARCH_TEXT, PT_NORMAL, NULL }, - { PROP_TIME, "history_time_optionmenu", CONF_HISTORY_SEARCH_TIME, PT_NORMAL, NULL }, - { PROP_GO_BUTTON, "history_go_button", NULL, PT_NORMAL, NULL }, - { -1, NULL, NULL } -}; - -GType -history_dialog_get_type (void) -{ - static GType history_dialog_type = 0; - - if (history_dialog_type == 0) - { - static const GTypeInfo our_info = - { - sizeof (HistoryDialogClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) history_dialog_class_init, - NULL, - NULL, /* class_data */ - sizeof (HistoryDialog), - 0, /* n_preallocs */ - (GInstanceInitFunc) history_dialog_init - }; - - history_dialog_type = g_type_register_static (EPHY_EMBED_DIALOG_TYPE, - "HistoryDialog", - &our_info, 0); - } - - return history_dialog_type; - -} - -static void -history_dialog_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - HistoryDialog *d = HISTORY_DIALOG (object); - - switch (prop_id) - { - case PROP_EMBEDDED: - history_dialog_set_embedded - (d, g_value_get_boolean (value)); - break; - } -} - -static void -history_dialog_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - HistoryDialog *d = HISTORY_DIALOG (object); - - switch (prop_id) - { - case PROP_EMBEDDED: - g_value_set_boolean (value, d->priv->embedded); - break; - } -} - - -static void -history_dialog_class_init (HistoryDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = history_dialog_finalize; - object_class->set_property = history_dialog_set_property; - object_class->get_property = history_dialog_get_property; - - g_object_class_install_property (object_class, - PROP_EMBEDDED, - g_param_spec_boolean ("embedded", - "Show embedded in another widget", - "Show embedded in another widget", - TRUE, - G_PARAM_READWRITE)); -} - -static void -add_column (HistoryDialog *dialog, - const char *title, - EphyHistoryModelColumn column) -{ - GtkTreeViewColumn *gcolumn; - GtkCellRenderer *renderer; - - ephy_node_view_get_type (); - - gcolumn = (GtkTreeViewColumn *) gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (gcolumn, renderer, TRUE); - gtk_tree_view_column_set_attributes (gcolumn, renderer, - "text", column, - NULL); - gtk_tree_view_column_set_sizing (gcolumn, - GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_column_set_sort_column_id (gcolumn, column); - gtk_tree_view_column_set_title (gcolumn, title); - gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->treeview), - gcolumn); -} - -static void -history_view_selection_changed_cb (GtkTreeSelection *selection, - HistoryDialog *dialog) -{ - if (gtk_tree_selection_count_selected_rows (selection)) - gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->go_button), TRUE); - else - gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->go_button), FALSE); -} - -static void -history_view_row_activated_cb (GtkTreeView *treeview, - GtkTreePath *path, - GtkTreeViewColumn *column, - HistoryDialog *dialog) -{ - GtkTreeIter iter, iter2; - EphyNode *node; - EphyEmbed *embed; - const char *location; - - gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->priv->sortmodel), &iter, path); - gtk_tree_model_sort_convert_iter_to_child_iter - (GTK_TREE_MODEL_SORT (dialog->priv->sortmodel), &iter2, &iter); - egg_tree_model_filter_convert_iter_to_child_iter - (EGG_TREE_MODEL_FILTER (dialog->priv->filtermodel), &iter, &iter2); - - node = ephy_history_model_node_from_iter (dialog->priv->nodemodel, &iter); - location = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); - g_return_if_fail (location != NULL); - embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog)); - ephy_embed_load_url (embed, location); -} - -static void -node_from_sort_iter_cb (EphyTreeModelSort *model, - GtkTreeIter *iter, - void **node, - HistoryDialog *dialog) -{ - GtkTreeIter filter_iter, node_iter; - - gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model), - &filter_iter, iter); - egg_tree_model_filter_convert_iter_to_child_iter (EGG_TREE_MODEL_FILTER (dialog->priv->filtermodel), - &node_iter, &filter_iter); - *node = ephy_history_model_node_from_iter (EPHY_HISTORY_MODEL (dialog->priv->nodemodel), &node_iter); - g_return_if_fail (*node != NULL); -} - -static void -history_dialog_setup_view (HistoryDialog *dialog) -{ - dialog->priv->nodemodel = ephy_history_model_new (dialog->priv->root, - dialog->priv->pages, - dialog->priv->filter); - dialog->priv->filtermodel = egg_tree_model_filter_new (GTK_TREE_MODEL (dialog->priv->nodemodel), - NULL); - egg_tree_model_filter_set_visible_column (EGG_TREE_MODEL_FILTER (dialog->priv->filtermodel), - EPHY_HISTORY_MODEL_COL_VISIBLE); - dialog->priv->sortmodel = EPHY_TREE_MODEL_SORT ( - ephy_tree_model_sort_new (GTK_TREE_MODEL (dialog->priv->filtermodel))); - ephy_tree_model_sort_set_drag_property - (dialog->priv->sortmodel, EPHY_NODE_PAGE_PROP_LOCATION); - - g_signal_connect_object (G_OBJECT (dialog->priv->sortmodel), - "node_from_iter", - G_CALLBACK (node_from_sort_iter_cb), - dialog, - 0); - gtk_tree_view_set_model (dialog->priv->treeview, - GTK_TREE_MODEL (dialog->priv->sortmodel)); - - egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (dialog->priv->treeview)); - gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (dialog->priv->treeview), - GDK_BUTTON1_MASK, - url_drag_types, n_url_drag_types, - GDK_ACTION_COPY); - - add_column (dialog, _("Title"), EPHY_HISTORY_MODEL_COL_TITLE); - add_column (dialog, _("Location"), EPHY_HISTORY_MODEL_COL_LOCATION); - add_column (dialog, _("Last Visit"), EPHY_HISTORY_MODEL_COL_LAST_VISIT); - - g_signal_connect (dialog->priv->treeview, - "row_activated", - G_CALLBACK (history_view_row_activated_cb), - dialog); - - g_signal_connect (gtk_tree_view_get_selection (dialog->priv->treeview), - "changed", - G_CALLBACK (history_view_selection_changed_cb), - dialog); -} - -static GTime -get_date_filter (int filter_type, - GTime atime) -{ - GDate date, current_date; - struct tm tm; - - g_date_clear (¤t_date, 1); - g_date_set_time (¤t_date, time (NULL)); - - g_date_clear (&date, 1); - g_date_set_time (&date, atime); - - switch (filter_type) - { - /* Always */ - case 0: - return 0; - /* Today */ - case 1: - break; - /* Last two days */ - case 2: - g_date_subtract_days (¤t_date, 1); - break; - /* Last three days */ - case 3: - g_date_subtract_days (¤t_date, 2); - break; - /* Week */ - case 4: - g_date_subtract_days (¤t_date, 7); - break; - /* Two weeks */ - case 5: - g_date_subtract_days (¤t_date, 14); - break; - default: - break; - } - - g_date_to_struct_tm (¤t_date, &tm); - return mktime (&tm); -} - -static void -history_dialog_setup_filter (HistoryDialog *dialog) -{ - GValue word = {0, }; - GValue atime = {0, }; - const char *search_text; - GTime date_filter; - - ephy_dialog_get_value (EPHY_DIALOG(dialog), PROP_WORD, &word); - search_text = g_value_get_string (&word); - ephy_dialog_get_value (EPHY_DIALOG(dialog), PROP_TIME, &atime); - date_filter = get_date_filter (g_value_get_int (&atime), time (NULL)); - - GDK_THREADS_ENTER (); - - ephy_node_filter_empty (dialog->priv->filter); - ephy_node_filter_add_expression (dialog->priv->filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, - EPHY_NODE_PAGE_PROP_TITLE, - search_text), - 0); - ephy_node_filter_add_expression (dialog->priv->filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_STRING_PROP_CONTAINS, - EPHY_NODE_PAGE_PROP_LOCATION, - search_text), - 0); - ephy_node_filter_add_expression (dialog->priv->filter, - ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_INT_PROP_BIGGER_THAN, - EPHY_NODE_PAGE_PROP_LAST_VISIT, - date_filter), - 1); - - ephy_node_filter_done_changing (dialog->priv->filter); - - GDK_THREADS_LEAVE (); -} - -static void -history_dialog_init (HistoryDialog *dialog) -{ - EphyEmbedShell *ges; - - dialog->priv = g_new0 (HistoryDialogPrivate, 1); - - ges = EPHY_EMBED_SHELL (ephy_shell); - dialog->priv->gh = ephy_embed_shell_get_global_history (ges); - g_return_if_fail (dialog->priv->gh != NULL); - - dialog->priv->root = ephy_history_get_hosts (dialog->priv->gh); - dialog->priv->pages = ephy_history_get_pages (dialog->priv->gh); - dialog->priv->filter = ephy_node_filter_new (); -} - -static void -history_dialog_set_embedded (HistoryDialog *dialog, - gboolean embedded) -{ - const char *icon_path; - - dialog->priv->embedded = embedded; - - ephy_dialog_construct (EPHY_DIALOG (dialog), - properties, - "epiphany.glade", - embedded ? - "history_dock_box" : - "history_dialog"); - dialog->priv->window = ephy_dialog_get_control (EPHY_DIALOG (dialog), PROP_WINDOW); - dialog->priv->go_button = ephy_dialog_get_control (EPHY_DIALOG (dialog), PROP_GO_BUTTON); - dialog->priv->treeview = GTK_TREE_VIEW ( - ephy_dialog_get_control (EPHY_DIALOG(dialog), - PROP_TREEVIEW)); - - icon_path = ephy_file ("epiphany-history.png"); - gtk_window_set_icon_from_file (GTK_WINDOW(dialog->priv->window), icon_path, NULL); - - history_dialog_setup_view (dialog); - history_dialog_setup_filter (dialog); -} - -static void -history_dialog_finalize (GObject *object) -{ - HistoryDialog *dialog; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_HISTORY_DIALOG (object)); - - dialog = HISTORY_DIALOG (object); - - g_return_if_fail (dialog->priv != NULL); - - g_object_unref (G_OBJECT (dialog->priv->sortmodel)); - g_object_unref (G_OBJECT (dialog->priv->filtermodel)); - g_object_unref (G_OBJECT (dialog->priv->nodemodel)); - - g_free (dialog->priv); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -EphyDialog * -history_dialog_new (EphyEmbed *embed, - gboolean embedded) -{ - HistoryDialog *dialog; - - dialog = HISTORY_DIALOG (g_object_new (HISTORY_DIALOG_TYPE, - "embedded", embedded, - "EphyEmbed", embed, - NULL)); - - return EPHY_DIALOG(dialog); -} - -EphyDialog * -history_dialog_new_with_parent (GtkWidget *window, - EphyEmbed *embed, - gboolean embedded) -{ - HistoryDialog *dialog; - - dialog = HISTORY_DIALOG (g_object_new (HISTORY_DIALOG_TYPE, - "embedded", embedded, - "EphyEmbed", embed, - "ParentWindow", window, - NULL)); - - return EPHY_DIALOG(dialog); -} - -void -history_entry_changed_cb (GtkWidget *widget, - HistoryDialog *dialog) -{ - if (dialog->priv->treeview == NULL) return; - history_dialog_setup_filter (dialog); -} - -void -history_time_optionmenu_changed_cb (GtkWidget *widget, - HistoryDialog *dialog) -{ - if (dialog->priv->treeview == NULL) return; - history_dialog_setup_filter (dialog); -} - -void -history_go_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog) -{ - GtkTreeSelection *selection; - GtkTreeIter iter, iter2; - EphyNode *node; - EphyEmbed *embed; - const char *location; - - selection = gtk_tree_view_get_selection (dialog->priv->treeview); - g_return_if_fail (selection != NULL); - gtk_tree_selection_get_selected (selection, NULL, &iter); - gtk_tree_model_sort_convert_iter_to_child_iter - (GTK_TREE_MODEL_SORT (dialog->priv->sortmodel), &iter2, &iter); - egg_tree_model_filter_convert_iter_to_child_iter - (EGG_TREE_MODEL_FILTER (dialog->priv->filtermodel), &iter, &iter2); - - node = ephy_history_model_node_from_iter (dialog->priv->nodemodel, &iter); - location = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_LOCATION); - g_return_if_fail (location != NULL); - embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog)); - ephy_embed_load_url (embed, location); -} - -void -history_ok_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog) -{ - g_object_unref (G_OBJECT(dialog)); -} - -static void -clear_history_dialog_response_cb (GtkDialog *dialog, gint response, - HistoryDialog *history_dialog) -{ - const GList *windows; - Session *session; - - gtk_widget_destroy (GTK_WIDGET (dialog)); - - if (response != GTK_RESPONSE_OK) - return; - - session = ephy_shell_get_session (ephy_shell); - windows = session_get_windows (session); - - for (; windows != NULL; windows = windows->next) - { - Toolbar *t; - - t = ephy_window_get_toolbar (EPHY_WINDOW (windows->data)); - toolbar_clear_location_history (t); - } - - ephy_history_clear (history_dialog->priv->gh); -} - -void -history_clear_button_clicked_cb (GtkWidget *button, - HistoryDialog *dialog) -{ - GtkWidget *clear; - GtkWidget *label; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *image; - char *str; - - clear = gtk_dialog_new_with_buttons (_("Clear history"), - GTK_WINDOW (dialog->priv->window), - GTK_DIALOG_DESTROY_WITH_PARENT | - GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_CLEAR, - GTK_RESPONSE_OK, - NULL); - gtk_dialog_set_default_response (GTK_DIALOG (clear), GTK_RESPONSE_OK); - gtk_container_set_border_width (GTK_CONTAINER (clear), 6); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (clear)->vbox), 12); - - hbox = gtk_hbox_new (FALSE, 6); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (clear)->vbox), hbox, - TRUE, TRUE, 0); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, - GTK_ICON_SIZE_DIALOG); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); - gtk_widget_show (image); - gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - str = g_strconcat ("","", _("Clear browsing history?"),"", "", NULL); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - label = gtk_label_new (_("Clearing the browsing history will cause all history items to be permanently deleted.")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - g_signal_connect (clear, "response", - G_CALLBACK (clear_history_dialog_response_cb), dialog); - gtk_widget_show (clear); -} diff --git a/src/history-dialog.h b/src/history-dialog.h deleted file mode 100644 index 9a064de5c..000000000 --- a/src/history-dialog.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2002 Jorn Baayen - * - * 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. - */ - -#ifndef HISTORY_DIALOG_H -#define HISTORY_DIALOG_H - -#include "ephy-embed-dialog.h" - -#include -#include - -G_BEGIN_DECLS - -typedef struct HistoryDialog HistoryDialog; -typedef struct HistoryDialogClass HistoryDialogClass; - -#define HISTORY_DIALOG_TYPE (history_dialog_get_type ()) -#define HISTORY_DIALOG(obj) (GTK_CHECK_CAST ((obj), HISTORY_DIALOG_TYPE, HistoryDialog)) -#define HISTORY_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), HISTORY_DIALOG, HistoryDialogClass)) -#define IS_HISTORY_DIALOG(obj) (GTK_CHECK_TYPE ((obj), HISTORY_DIALOG_TYPE)) -#define IS_HISTORY_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HISTORY_DIALOG)) - -typedef struct HistoryDialogPrivate HistoryDialogPrivate; - -struct HistoryDialog -{ - EphyEmbedDialog parent; - HistoryDialogPrivate *priv; -}; - -struct HistoryDialogClass -{ - EphyEmbedDialogClass parent_class; -}; - -GType history_dialog_get_type (void); - -EphyDialog *history_dialog_new (EphyEmbed *embed, - gboolean embedded); - -EphyDialog *history_dialog_new_with_parent (GtkWidget *window, - EphyEmbed *embed, - gboolean embedded); - -G_END_DECLS - -#endif - diff --git a/src/window-commands.c b/src/window-commands.c index c0aee9d6b..49a9e2625 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -591,7 +591,7 @@ void window_cmd_go_history (EggAction *action, EphyWindow *window) { - ephy_window_show_history (window); + ephy_shell_show_history_window (ephy_shell); } void -- cgit v1.2.3