diff options
author | Peter Harvey <peter.a.harvey@gmail.com> | 2006-01-29 06:14:02 +0800 |
---|---|---|
committer | Peter Anthony Harvey <paharvey@src.gnome.org> | 2006-01-29 06:14:02 +0800 |
commit | 811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a (patch) | |
tree | c1b331413964754380f4ca45a6755c7a3daf8a85 /src | |
parent | 37a127559b9b67bd7b163177ced72539512c319c (diff) | |
download | gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar.gz gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar.bz2 gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar.lz gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar.xz gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.tar.zst gsoc2013-epiphany-811f68e7ed17fd4d4fcd620c3b9d1a543b376a9a.zip |
src/bookmarks/ephy-bookmark-properties.c src/bookmarks/ephy-topics-entry.c
2006-01-29 Peter Harvey <peter.a.harvey@gmail.com>
* src/bookmarks/ephy-bookmark-properties.c
* src/bookmarks/ephy-topics-entry.c
* src/bookmarks/ephy-topics-entry.h
* src/bookmarks/Makefile.am
* po/POTFILES.in
Ongoing Saga Of The Bookmark Properties Dialog.
Dialog is now much more compact, using a text entry by
default and offering the palette when desired.
* src/bookmarks/ephy-topics-palette.c
Simplified code and made more usable.
Removed the header from the last patch as well.
* src/bookmarks/ephy-bookmarks-ui.c
'Add bookmark' dialogs were not correctly removed from the
hashtable.
Diffstat (limited to 'src')
-rw-r--r-- | src/bookmarks/Makefile.am | 2 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmark-properties.c | 104 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks-ui.c | 9 | ||||
-rw-r--r-- | src/bookmarks/ephy-topics-entry.c | 520 | ||||
-rw-r--r-- | src/bookmarks/ephy-topics-entry.h | 61 | ||||
-rw-r--r-- | src/bookmarks/ephy-topics-palette.c | 156 |
6 files changed, 703 insertions, 149 deletions
diff --git a/src/bookmarks/Makefile.am b/src/bookmarks/Makefile.am index 1b4b8e679..43f22d152 100644 --- a/src/bookmarks/Makefile.am +++ b/src/bookmarks/Makefile.am @@ -23,6 +23,7 @@ NOINST_H_FILES = \ ephy-bookmark-factory-action.h \ ephy-topic-action-group.h \ ephy-bookmark-action-group.h \ + ephy-topics-entry.h \ ephy-topics-palette.h \ ephy-nodes-cover.h @@ -42,6 +43,7 @@ libephybookmarks_la_SOURCES = \ ephy-bookmark-factory-action.c \ ephy-topic-action-group.c \ ephy-bookmark-action-group.c \ + ephy-topics-entry.c \ ephy-topics-palette.c \ ephy-nodes-cover.c \ $(NOINST_H_FILES) \ diff --git a/src/bookmarks/ephy-bookmark-properties.c b/src/bookmarks/ephy-bookmark-properties.c index c5f274fbb..559b16b01 100644 --- a/src/bookmarks/ephy-bookmark-properties.c +++ b/src/bookmarks/ephy-bookmark-properties.c @@ -25,6 +25,7 @@ #include "ephy-bookmark-properties.h" #include "ephy-bookmarks-ui.h" +#include "ephy-topics-entry.h" #include "ephy-topics-palette.h" #include "ephy-stock-icons.h" #include "ephy-debug.h" @@ -56,11 +57,12 @@ struct _EphyBookmarkPropertiesPrivate { EphyBookmarks *bookmarks; EphyNode *bookmark; - EphyTopicsPalette *palette; gboolean creating; EphyNode *duplicate; GtkWidget *warning; + GtkWidget *entry; + GtkWidget *palette; }; enum @@ -71,11 +73,6 @@ enum PROP_CREATING }; -enum -{ - RESPONSE_NEW_TOPIC = 1 -}; - static GObjectClass *parent_class; static void @@ -202,10 +199,6 @@ bookmark_properties_response_cb (GtkDialog *dialog, "epiphany", "to-edit-bookmark-properties"); return; - case RESPONSE_NEW_TOPIC: - ephy_bookmarks_ui_add_topic (GTK_WIDGET (dialog), - priv->bookmark); - return; case GTK_RESPONSE_ACCEPT: /* On destruction of the dialog, if priv->creating==TRUE, * we will unref any bookmark we have, so we set it @@ -251,16 +244,6 @@ update_window_title (EphyBookmarkProperties *properties) g_free (title); } -static void -combo_changed_cb (GtkComboBox *combobox, - GtkWidget *palette) -{ - int active; - - active = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox)); - g_object_set (palette, "mode", active, NULL); -} - static void title_entry_changed_cb (GtkWidget *entry, EphyBookmarkProperties *props) @@ -281,6 +264,38 @@ location_entry_changed_cb (GtkWidget *entry, } static void +toggled_cb (GtkToggleButton *button, + EphyBookmarkProperties *properties) +{ + EphyBookmarkPropertiesPrivate *priv = properties->priv; + GdkGeometry geometry; + + if(gtk_toggle_button_get_active (button)) + { + g_object_set (priv->entry, "sensitive", FALSE, NULL); + g_object_set (priv->palette, "visible", TRUE, NULL); + + geometry.min_width = -1; + geometry.min_height = 230; + gtk_window_set_geometry_hints (GTK_WINDOW (properties), + priv->palette, &geometry, + GDK_HINT_MIN_SIZE); + } + else + { + g_object_set (priv->entry, "sensitive", TRUE, NULL); + g_object_set (priv->palette, "visible", FALSE, NULL); + + geometry.max_height = -1; + geometry.max_width = G_MAXINT; + gtk_window_set_geometry_hints (GTK_WINDOW (properties), + GTK_WIDGET (properties), + &geometry, GDK_HINT_MAX_SIZE); + } +} + + +static void ephy_bookmark_properties_init (EphyBookmarkProperties *properties) { properties->priv = EPHY_BOOKMARK_PROPERTIES_GET_PRIVATE (properties); @@ -294,8 +309,8 @@ ephy_bookmark_properties_constructor (GType type, GObject *object; EphyBookmarkProperties *properties; EphyBookmarkPropertiesPrivate *priv; - GtkWidget *widget, *table, *label, *entry, *palette; - GtkWidget *scrolled_window; + GtkWidget *widget, *table, *label, *entry, *button; + GtkWidget *scrolled_window, *palette; GtkWindow *window; GtkDialog *dialog; const char *tmp; @@ -322,7 +337,8 @@ ephy_bookmark_properties_constructor (GType type, ephy_state_add_window (widget, "bookmark_properties", 290, 280, FALSE, - EPHY_STATE_WINDOW_SAVE_SIZE); + EPHY_STATE_WINDOW_SAVE_SIZE | + EPHY_STATE_WINDOW_SAVE_POSITION); update_window_title (properties); @@ -330,9 +346,10 @@ ephy_bookmark_properties_constructor (GType type, gtk_container_set_border_width (GTK_CONTAINER (properties), 5); gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); - table = gtk_table_new (4, 2, FALSE); + table = gtk_table_new (4, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 12); + gtk_table_set_col_spacing (GTK_TABLE (table), 1, 3); gtk_container_set_border_width (GTK_CONTAINER (table), 5); gtk_widget_show (table); @@ -350,7 +367,7 @@ ephy_bookmark_properties_constructor (GType type, gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), entry, 1, 3, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); entry = gtk_entry_new (); tmp = ephy_node_get_property_string (properties->priv->bookmark, @@ -365,21 +382,30 @@ ephy_bookmark_properties_constructor (GType type, gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), entry, 1, 3, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); widget = gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_BUTTON); - priv->warning = gtk_button_new_with_mnemonic (_("_Show bookmark with same address")); + priv->warning = gtk_button_new_with_mnemonic (_("_Show similar bookmark")); gtk_button_set_image (GTK_BUTTON (priv->warning), widget); g_signal_connect (priv->warning, "clicked", G_CALLBACK(show_duplicate_cb), properties); gtk_widget_show (priv->warning); gtk_table_set_row_spacing (GTK_TABLE (table), 1, 0); - gtk_table_attach (GTK_TABLE (table), priv->warning, 1, 2, 2, 3, GTK_FILL, 0, 0, 3); + gtk_table_attach (GTK_TABLE (table), priv->warning, 1, 3, 2, 3, GTK_FILL, 0, 0, 3); priv->duplicate = ephy_bookmarks_find_duplicate (priv->bookmarks, priv->bookmark); g_object_set (priv->warning, "visible", priv->duplicate != NULL, NULL); + entry = ephy_topics_entry_new (priv->bookmarks, priv->bookmark); + priv->entry = entry; + gtk_widget_show (entry); + label = gtk_label_new_with_mnemonic(_("T_opics:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0); + palette = ephy_topics_palette_new (priv->bookmarks, priv->bookmark); - priv->palette = EPHY_TOPICS_PALETTE (palette); scrolled_window = g_object_new (GTK_TYPE_SCROLLED_WINDOW, "hadjustment", NULL, "vadjustment", NULL, @@ -387,25 +413,27 @@ ephy_bookmark_properties_constructor (GType type, "vscrollbar_policy", GTK_POLICY_AUTOMATIC, "shadow_type", GTK_SHADOW_IN, NULL); + priv->palette = scrolled_window; gtk_container_add (GTK_CONTAINER (scrolled_window), palette); gtk_widget_show (palette); - label = gtk_label_new_with_mnemonic(_("T_opics:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), palette); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 6); - gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 2, 3, 4, + gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 3, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); gtk_widget_show (scrolled_window); + widget = gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (widget); + button = gtk_toggle_button_new_with_label (""); + gtk_button_set_image (GTK_BUTTON (button), widget); + g_signal_connect (button, "toggled", G_CALLBACK (toggled_cb), properties); + toggled_cb (button, properties); + gtk_widget_show (button); + gtk_table_attach (GTK_TABLE (table), button, 2, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), table, TRUE, TRUE, 0); gtk_dialog_add_button (dialog, GTK_STOCK_HELP, GTK_RESPONSE_HELP); - gtk_dialog_add_button (dialog, - _("_New Topic"), - RESPONSE_NEW_TOPIC); if (priv->creating) { diff --git a/src/bookmarks/ephy-bookmarks-ui.c b/src/bookmarks/ephy-bookmarks-ui.c index 63f6d9df1..f560e1f56 100644 --- a/src/bookmarks/ephy-bookmarks-ui.c +++ b/src/bookmarks/ephy-bookmarks-ui.c @@ -412,10 +412,9 @@ ephy_bookmarks_ui_detach_window (EphyWindow *window) static void properties_dialog_destroy_cb (EphyBookmarkProperties *dialog, - gpointer user_data) + EphyNode *bookmark) { - g_hash_table_remove (properties_dialogs, - ephy_bookmark_properties_get_node (dialog)); + g_hash_table_remove (properties_dialogs, bookmark); } void @@ -437,7 +436,7 @@ ephy_bookmarks_ui_add_bookmark (const char *location, dialog = ephy_bookmark_properties_new (bookmarks, bookmark, TRUE); g_signal_connect (dialog, "destroy", - G_CALLBACK (properties_dialog_destroy_cb), bookmarks); + G_CALLBACK (properties_dialog_destroy_cb), bookmark); g_hash_table_insert (properties_dialogs, bookmark, dialog); @@ -661,7 +660,7 @@ ephy_bookmarks_ui_show_bookmark (EphyNode *bookmark) dialog = ephy_bookmark_properties_new (bookmarks, bookmark, FALSE); g_signal_connect (dialog, "destroy", - G_CALLBACK (properties_dialog_destroy_cb), bookmarks); + G_CALLBACK (properties_dialog_destroy_cb), bookmark); g_hash_table_insert (properties_dialogs, bookmark, dialog); } diff --git a/src/bookmarks/ephy-topics-entry.c b/src/bookmarks/ephy-topics-entry.c new file mode 100644 index 000000000..8c3af0007 --- /dev/null +++ b/src/bookmarks/ephy-topics-entry.c @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2002-2004 Marco Pesenti Gritti <mpeseng@tin.it> + * Copyright (C) 2005, 2006 Peter Harvey <pah06@uow.edu.au> + * + * 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 "config.h" + +#include "ephy-topics-entry.h" +#include "ephy-nodes-cover.h" +#include "ephy-node-common.h" +#include "ephy-bookmarks.h" +#include "ephy-debug.h" + +#include <glib/gi18n.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtkentrycompletion.h> +#include <string.h> + +static void ephy_topics_entry_class_init (EphyTopicsEntryClass *klass); +static void ephy_topics_entry_init (EphyTopicsEntry *editor); + +#define EPHY_TOPICS_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_TOPICS_ENTRY, EphyTopicsEntryPrivate)) + +struct _EphyTopicsEntryPrivate +{ + EphyBookmarks *bookmarks; + EphyNode *bookmark; + GtkListStore *store; + GtkEntryCompletion *completion; + gboolean update_keywords; + char *action; +}; + +enum +{ + PROP_0, + PROP_BOOKMARKS, + PROP_BOOKMARK +}; + +static GObjectClass *parent_class = NULL; + +GType +ephy_topics_entry_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyTopicsEntryClass), + NULL, + NULL, + (GClassInitFunc) ephy_topics_entry_class_init, + NULL, + NULL, + sizeof (EphyTopicsEntry), + 0, + (GInstanceInitFunc) ephy_topics_entry_init + }; + + type = g_type_register_static (GTK_TYPE_ENTRY, + "EphyTopicsEntry", + &our_info, 0); + } + + return type; +} + +static void +update_widget (EphyTopicsEntry *entry) +{ + EphyNode *node; + GPtrArray *children, *topics; + GtkTreeIter iter; + gint i, priority; + const char *title; + char *tmp1, *tmp2; + gboolean update_text; + + entry->priv->update_keywords = FALSE; + + update_text = !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (entry)); + gtk_entry_set_completion (GTK_ENTRY (entry), NULL); + gtk_list_store_clear (entry->priv->store); + if (update_text) gtk_entry_set_text (GTK_ENTRY (entry), ""); + + node = ephy_bookmarks_get_keywords (entry->priv->bookmarks); + children = ephy_node_get_children (node); + topics = g_ptr_array_sized_new (children->len); + + for (i = 0; i < children->len; i++) + { + node = g_ptr_array_index (children, i); + + priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (priority != EPHY_NODE_NORMAL_PRIORITY) + continue; + + g_ptr_array_add (topics, node); + } + + g_ptr_array_sort (topics, ephy_bookmarks_compare_topic_pointers); + + for (i = 0; i < topics->len; i++) + { + node = g_ptr_array_index (topics, i); + title = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); + + if (ephy_node_has_child (node, entry->priv->bookmark)) + { + if (update_text) + { + gtk_entry_append_text (GTK_ENTRY (entry), title); + gtk_entry_append_text (GTK_ENTRY (entry), "; "); + } + } + else + { + tmp1 = g_utf8_casefold (title, -1); + tmp2 = g_utf8_normalize (tmp1, -1, G_NORMALIZE_DEFAULT); + gtk_list_store_append (entry->priv->store, &iter); + gtk_list_store_set (entry->priv->store, &iter, 0, title, 1, tmp2, -1); + g_free (tmp2); + g_free (tmp1); + } + } + + g_ptr_array_free (topics, TRUE); + + gtk_entry_set_completion (GTK_ENTRY (entry), entry->priv->completion); + if (update_text) gtk_editable_set_position (GTK_EDITABLE (entry), -1); + + entry->priv->update_keywords = TRUE; +} + +static void +update_action (EphyTopicsEntry *entry) +{ + GtkEditable *editable = GTK_EDITABLE (entry); + const char *text = gtk_entry_get_text (GTK_ENTRY (entry)); + char *key; + gint start, end; + + if(entry->priv->action) + { + gtk_entry_completion_delete_action (entry->priv->completion, 0); + g_free (entry->priv->action); + entry->priv->action = 0; + } + + /* Find the start and end locations */ + start = gtk_editable_get_position (editable); + while (start > 0 && text[start-1] != ';') + { + start--; + } + if(start > 0 && text[start-1] == ';' && text[start] == ' ') + { + start++; + } + end = start; + while (text[end] && text[end] != ';') + { + end++; + } + + /* If no text to work with, exit */ + key = g_strndup (text+start, end-start); + g_strstrip (key); + if (*key != 0 && ephy_bookmarks_find_keyword (entry->priv->bookmarks, key, FALSE) == NULL) + { + entry->priv->action = key; + key = g_strdup_printf (_("Create topic ā%sā"), key); + gtk_entry_completion_insert_action_text (entry->priv->completion, 0, key); + } + + g_free (key); +} + +static void +update_keywords (EphyTopicsEntry *entry) +{ + EphyNode *node; + GPtrArray *children; + const char *text; + char **split; + char *title, *tmp; + gint i, j, priority; + + if(!entry->priv->update_keywords) return; + + /* Get the list of strings input by the user */ + text = gtk_entry_get_text (GTK_ENTRY (entry)); + split = g_strsplit (text, ";", 0); + for (i=0; split[i]; i++) + { + g_strstrip (split[i]); + + tmp = g_utf8_casefold (split[i], -1); + g_free (split[i]); + + split[i] = g_utf8_normalize (tmp, -1, G_NORMALIZE_DEFAULT); + g_free (tmp); + } + + /* Test each keyword and set/unset as appropriate */ + node = ephy_bookmarks_get_keywords (entry->priv->bookmarks); + children = ephy_node_get_children (node); + for (i = 0; i < children->len; i++) + { + node = g_ptr_array_index (children, i); + + priority = ephy_node_get_property_int (node, EPHY_NODE_KEYWORD_PROP_PRIORITY); + if (priority != EPHY_NODE_NORMAL_PRIORITY) + continue; + + text = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); + tmp = g_utf8_casefold (text, -1); + title = g_utf8_normalize (tmp, -1, G_NORMALIZE_DEFAULT); + g_free (tmp); + + for (j=0; split[j]; j++) + if (strcmp (title, split[j]) == 0) + break; + + if (split[j]) + { + split[j][0] = 0; + ephy_bookmarks_set_keyword (entry->priv->bookmarks, node, + entry->priv->bookmark); + } + else + { + ephy_bookmarks_unset_keyword (entry->priv->bookmarks, node, + entry->priv->bookmark); + } + + g_free (title); + } + + g_strfreev (split); + + update_action (entry); +} + +static void +insert_text (EphyTopicsEntry *entry, + const char *title) +{ + GtkEditable *editable = GTK_EDITABLE (entry); + const char *text = gtk_entry_get_text (GTK_ENTRY (entry)); + char *key; + gint start, end; + + /* Find the start and end locations */ + start = gtk_editable_get_position (editable); + while (start > 0 && text[start-1] != ';') + { + start--; + } + if(start > 0 && text[start-1] == ';' && text[start] == ' ') + { + start++; + } + end = start; + while (text[end] && text[end] != ';') + { + end++; + } + end = end; + if (text[end] == ';') + { + end++; + if (text[end] == ' ') + { + end++; + } + } + + /* If we were provided with nothing, then we're meant to find a topic + * or create one from whatever has been entered */ + if (title == NULL) + { + /* If no text to work with, exit */ + key = g_strndup (text+start, end-start); + g_strstrip (key); + if (*key == 0) + { + g_free (key); + return; + } + + } + + /* Replace the text in the current position with the title */ + gtk_editable_delete_text (editable, start, end); + gtk_editable_insert_text (editable, title, strlen(title), &start); + gtk_editable_insert_text (editable, "; ", 2, &start); + gtk_editable_set_position (editable, start); + update_widget(entry); +} + +static void +action_cb (GtkEntryCompletion *completion, + gint index, + gpointer user_data) +{ + EphyTopicsEntry *entry = EPHY_TOPICS_ENTRY (gtk_entry_completion_get_entry (completion)); + char *action = g_strdup(entry->priv->action); + + if (ephy_bookmarks_find_keyword (entry->priv->bookmarks, action, FALSE) == NULL) + { + ephy_bookmarks_add_keyword (entry->priv->bookmarks, action); + } + + insert_text (entry, action); + g_free (action); +} + +static gboolean +match_selected_cb (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + EphyTopicsEntry *entry = EPHY_TOPICS_ENTRY (gtk_entry_completion_get_entry (completion)); + char *title; + + gtk_tree_model_get (model, iter, 0, &title, -1); + insert_text (entry, title); + g_free (title); + + return TRUE; +} + +static void +tree_changed_cb (EphyBookmarks *bookmarks, + EphyTopicsEntry *entry) +{ + update_widget(entry); +} + +static gboolean +focus_out_cb (GtkEditable *editable, + GdkEventFocus *event, + gpointer user_data) +{ + update_widget (EPHY_TOPICS_ENTRY (editable)); + return FALSE; +} + +static gboolean +match_func (GtkEntryCompletion *completion, + const gchar *key, + GtkTreeIter *iter, + gpointer user_data) +{ + gboolean result; + const char *real_key; + char *text; + + real_key = g_strrstr (key, ";"); + if (real_key) real_key++; + else real_key = key; + while (*real_key == ' ') real_key++; + + gtk_tree_model_get (gtk_entry_completion_get_model (completion), iter, 1, &text, -1); + if (text == NULL) return FALSE; + result = g_str_has_prefix (text, real_key); + g_free (text); + + return result; +} + +static void +ephy_topics_entry_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyTopicsEntry *entry = EPHY_TOPICS_ENTRY (object); + + switch (prop_id) + { + case PROP_BOOKMARKS: + entry->priv->bookmarks = g_value_get_object (value); + g_signal_connect_object (entry->priv->bookmarks, "tree-changed", + G_CALLBACK (tree_changed_cb), entry, + G_CONNECT_AFTER); + break; + case PROP_BOOKMARK: + entry->priv->bookmark = g_value_get_pointer (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +ephy_topics_entry_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + EphyTopicsEntry *entry; + EphyTopicsEntryPrivate *priv; + + object = parent_class->constructor (type, n_construct_properties, + construct_params); + entry = EPHY_TOPICS_ENTRY (object); + priv = EPHY_TOPICS_ENTRY_GET_PRIVATE (object); + + priv->store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + priv->completion = gtk_entry_completion_new (); + priv->update_keywords = TRUE; + + gtk_entry_completion_set_model (priv->completion, GTK_TREE_MODEL (priv->store)); + gtk_entry_completion_set_text_column (priv->completion, 0); + gtk_entry_completion_set_popup_completion (priv->completion, TRUE); + gtk_entry_completion_set_popup_single_match (priv->completion, TRUE); + + gtk_entry_completion_set_match_func (priv->completion, match_func, NULL, NULL); + + g_signal_connect (priv->completion, "match-selected", + G_CALLBACK (match_selected_cb), NULL); + g_signal_connect (object, "focus-out-event", + G_CALLBACK (focus_out_cb), NULL); + g_signal_connect (object, "changed", + G_CALLBACK (update_keywords), NULL); + g_signal_connect (G_OBJECT (priv->completion), "action-activated", + G_CALLBACK (action_cb), NULL); + + update_widget (entry); + + return object; +} + +static void +ephy_topics_entry_init (EphyTopicsEntry *entry) +{ + entry->priv = EPHY_TOPICS_ENTRY_GET_PRIVATE (entry); + +} + +static void +ephy_topics_entry_finalize (GObject *object) +{ + EphyTopicsEntry *entry = EPHY_TOPICS_ENTRY (object); + + g_free (entry->priv->action); + + parent_class->finalize (object); +} + +GtkWidget * +ephy_topics_entry_new (EphyBookmarks *bookmarks, + EphyNode *bookmark) +{ + EphyTopicsEntry *entry; + + g_assert (bookmarks != NULL); + + entry = EPHY_TOPICS_ENTRY (g_object_new + (EPHY_TYPE_TOPICS_ENTRY, + "bookmarks", bookmarks, + "bookmark", bookmark, + NULL)); + + return GTK_WIDGET (entry); +} + +static void +ephy_topics_entry_class_init (EphyTopicsEntryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->set_property = ephy_topics_entry_set_property; + object_class->constructor = ephy_topics_entry_constructor; + object_class->finalize = ephy_topics_entry_finalize; + + g_object_class_install_property (object_class, + PROP_BOOKMARKS, + g_param_spec_object ("bookmarks", + "Bookmarks set", + "Bookmarks set", + EPHY_TYPE_BOOKMARKS, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (object_class, + PROP_BOOKMARK, + g_param_spec_pointer ("bookmark", + "Bookmark", + "Bookmark", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (object_class, sizeof(EphyTopicsEntryPrivate)); +} diff --git a/src/bookmarks/ephy-topics-entry.h b/src/bookmarks/ephy-topics-entry.h new file mode 100644 index 000000000..295e0ab65 --- /dev/null +++ b/src/bookmarks/ephy-topics-entry.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2002 Marco Pesenti Gritti <mpeseng@tin.it> + * + * 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_TOPICS_ENTRY_H +#define EPHY_TOPICS_ENTRY_H + +#include "ephy-bookmarks.h" +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_TOPICS_ENTRY (ephy_topics_entry_get_type ()) +#define EPHY_TOPICS_ENTRY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_TOPICS_ENTRY, EphyTopicsEntry)) +#define EPHY_TOPICS_ENTRY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_TOPICS_ENTRY, EphyTopicsEntryClass)) +#define EPHY_IS_TOPICS_ENTRY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_TOPICS_ENTRY)) +#define EPHY_IS_TOPICS_ENTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_TOPICS_ENTRY)) +#define EPHY_TOPICS_ENTRY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_TOPICS_ENTRY, EphyTopicsEntryClass)) + +typedef struct _EphyTopicsEntryPrivate EphyTopicsEntryPrivate; + +typedef struct +{ + GtkEntry parent; + + /*< private >*/ + EphyTopicsEntryPrivate *priv; +} EphyTopicsEntry; + +typedef struct +{ + GtkEntryClass parent; +} EphyTopicsEntryClass; + +GType ephy_topics_entry_get_type (void); + +GtkWidget *ephy_topics_entry_new (EphyBookmarks *bookmarks, + EphyNode *bookmark); + +void ephy_topics_entry_insert_topic (EphyTopicsEntry *entry, + const char *title); + +G_END_DECLS + +#endif /* EPHY_TOPICS_ENTRY_H */ diff --git a/src/bookmarks/ephy-topics-palette.c b/src/bookmarks/ephy-topics-palette.c index ee650b0a1..29ff7b0c5 100644 --- a/src/bookmarks/ephy-topics-palette.c +++ b/src/bookmarks/ephy-topics-palette.c @@ -57,10 +57,7 @@ enum { COLUMN_TITLE, COLUMN_NODE, - COLUMN_WEIGHT, COLUMN_SELECTED, - COLUMN_SEPARATOR, - COLUMN_SELECTABLE, COLUMNS }; @@ -106,70 +103,37 @@ append_topics (EphyTopicsPalette *palette, GtkTreeIter *iter, gboolean *valid, gboolean *first, - const char *label, - const char *empty, GPtrArray *topics) { EphyNode *node; const char *title; - char *noted; gint i; + if (topics->len == 0) + { + return; + } + if (!*first) { if (!*valid) gtk_list_store_append (palette->priv->store, iter); gtk_list_store_set (palette->priv->store, iter, COLUMN_TITLE, NULL, - COLUMN_NODE, NULL, COLUMN_SEPARATOR, TRUE, -1); + COLUMN_NODE, NULL, -1); *valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (palette->priv->store), iter); } - if (label != NULL) + for (i = 0; i < topics->len ; i++) { + node = g_ptr_array_index (topics, i); + title = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); + if (!*valid) gtk_list_store_append (palette->priv->store, iter); - gtk_list_store_set (palette->priv->store, iter, COLUMN_TITLE, label, - COLUMN_NODE, NULL, COLUMN_SELECTED, FALSE, - COLUMN_WEIGHT, PANGO_WEIGHT_BOLD, - COLUMN_SEPARATOR, FALSE, COLUMN_SELECTABLE, FALSE, -1); + gtk_list_store_set (palette->priv->store, iter, COLUMN_TITLE, title, + COLUMN_NODE, node, COLUMN_SELECTED, + ephy_node_has_child (node, palette->priv->bookmark), -1); *valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (palette->priv->store), iter); *first = FALSE; } - - if (!topics || topics->len == 0) - { - if (empty != NULL) - { - if (!*valid) gtk_list_store_append (palette->priv->store, iter); - gtk_list_store_set (palette->priv->store, iter, COLUMN_TITLE, empty, - COLUMN_NODE, NULL, COLUMN_SELECTED, FALSE, - COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, - COLUMN_SEPARATOR, FALSE, COLUMN_SELECTABLE, FALSE, -1); - *valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (palette->priv->store), iter); - *first = FALSE; - } - } - else - { - for (i = 0; i < topics->len ; i++) - { - node = g_ptr_array_index (topics, i); - title = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); - noted = NULL; - if (ephy_node_get_children(node)->len == 0) - { - noted = g_strdup_printf ("%s (unused)", title); - } - - if (!*valid) gtk_list_store_append (palette->priv->store, iter); - gtk_list_store_set (palette->priv->store, iter, COLUMN_TITLE, noted ? noted : title, - COLUMN_NODE, node, COLUMN_SELECTED, - ephy_node_has_child (node, palette->priv->bookmark), - COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, - COLUMN_SEPARATOR, FALSE, COLUMN_SELECTABLE, TRUE, -1); - *valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (palette->priv->store), iter); - *first = FALSE; - g_free (noted); - } - } } static void @@ -187,8 +151,6 @@ update_list (EphyTopicsPalette *palette) if (palette->priv->mode == MODE_LIST) { - gtk_tree_view_column_set_title (palette->priv->column, _("By title")); - /* Allocate and fill the suggestions array. */ node = ephy_bookmarks_get_keywords (palette->priv->bookmarks); children = ephy_node_get_children (node); @@ -205,15 +167,13 @@ update_list (EphyTopicsPalette *palette) } g_ptr_array_sort (topics, ephy_bookmarks_compare_topic_pointers); - append_topics (palette, &iter, &valid, &first, NULL, _("No topics"), topics); + append_topics (palette, &iter, &valid, &first, topics); g_ptr_array_free (topics, TRUE); } else if (palette->priv->mode == MODE_GROUPED) { GPtrArray *suggested, *selected; - gtk_tree_view_column_set_title (palette->priv->column, _("By relation")); - /* Allocate and fill the bookmarks array. */ node = ephy_bookmarks_get_bookmarks (palette->priv->bookmarks); children = ephy_node_get_children (node); @@ -277,9 +237,9 @@ update_list (EphyTopicsPalette *palette) g_ptr_array_sort (selected, ephy_bookmarks_compare_topic_pointers); g_ptr_array_sort (suggested, ephy_bookmarks_compare_topic_pointers); g_ptr_array_sort (topics, ephy_bookmarks_compare_topic_pointers); - append_topics (palette, &iter, &valid, &first, _("Selection"), _("No selected topics"), selected); - append_topics (palette, &iter, &valid, &first, _("Subtopics"), _("No more subtopics"), suggested); - append_topics (palette, &iter, &valid, &first, _("Other"), _("No other topics"), topics); + append_topics (palette, &iter, &valid, &first, selected); + append_topics (palette, &iter, &valid, &first, suggested); + append_topics (palette, &iter, &valid, &first, topics); g_ptr_array_free (selected, TRUE); g_ptr_array_free (suggested, TRUE); g_ptr_array_free (bookmarks, TRUE); @@ -291,6 +251,8 @@ update_list (EphyTopicsPalette *palette) valid = gtk_list_store_remove (palette->priv->store, &iter); } + gtk_tree_selection_unselect_all + (gtk_tree_view_get_selection (GTK_TREE_VIEW (palette))); } static gboolean @@ -351,14 +313,6 @@ ephy_topics_palette_set_property (GObject *object, } static void -column_clicked (GtkTreeViewColumn *column, - EphyTopicsPalette *palette) -{ - palette->priv->mode = (palette->priv->mode+1)%MODES; - update_list_idle (palette); -} - -static void cell_edited (GtkCellRendererText *renderer, const char *path_str, const char *new_text, @@ -368,7 +322,7 @@ cell_edited (GtkCellRendererText *renderer, { EphyNode *node; node = ephy_bookmarks_add_keyword (palette->priv->bookmarks, new_text); - ephy_bookmarks_set_keyword (palette->priv->bookmarks, node, + ephy_bookmarks_set_keyword (palette->priv->bookmarks, node, palette->priv->bookmark); } else @@ -388,30 +342,21 @@ toggled (GtkCellRendererToggle *cell_renderer, model = gtk_tree_view_get_model (GTK_TREE_VIEW (palette)); - if (gtk_tree_model_get_iter_from_string (model, &iter, path)) + g_return_if_fail(gtk_tree_model_get_iter_from_string (model, &iter, path)); + + gtk_tree_model_get (model, &iter, COLUMN_NODE, &topic, -1); + + if (ephy_node_has_child (topic, palette->priv->bookmark)) { - gtk_tree_model_get (model, &iter, COLUMN_NODE, &topic, -1); - if (topic == NULL) - { - char *title; - gtk_tree_model_get (model, &iter, COLUMN_TITLE, &title, -1); - g_return_if_fail (title != NULL && *title != 0); - topic = ephy_bookmarks_add_keyword (palette->priv->bookmarks, title); - g_free (title); - } - - if (ephy_node_has_child (topic, palette->priv->bookmark)) - { - ephy_bookmarks_unset_keyword (palette->priv->bookmarks, - topic, - palette->priv->bookmark); - } - else - { - ephy_bookmarks_set_keyword (palette->priv->bookmarks, - topic, - palette->priv->bookmark); - } + ephy_bookmarks_unset_keyword (palette->priv->bookmarks, + topic, + palette->priv->bookmark); + } + else + { + ephy_bookmarks_set_keyword (palette->priv->bookmarks, + topic, + palette->priv->bookmark); } } @@ -420,9 +365,9 @@ is_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { - gboolean separator; - gtk_tree_model_get (model, iter, COLUMN_SEPARATOR, &separator, -1); - return separator; + EphyNode *node; + gtk_tree_model_get (model, iter, COLUMN_NODE, &node, -1); + return (node == NULL); } static GObject * @@ -441,35 +386,29 @@ ephy_topics_palette_constructor (GType type, palette = EPHY_TOPICS_PALETTE (object); priv = EPHY_TOPICS_PALETTE_GET_PRIVATE (object); - priv->store = gtk_list_store_new (COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + priv->store = gtk_list_store_new (COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN); gtk_tree_view_set_model (GTK_TREE_VIEW (object), GTK_TREE_MODEL (priv->store)); g_object_unref (priv->store); priv->column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_clickable (priv->column, TRUE); - g_signal_connect (priv->column, "clicked", G_CALLBACK (column_clicked), palette); renderer = gtk_cell_renderer_toggle_new (); gtk_tree_view_column_pack_start (priv->column, renderer, FALSE); gtk_tree_view_column_add_attribute (priv->column, renderer, "active", COLUMN_SELECTED); - gtk_tree_view_column_add_attribute (priv->column, renderer, "visible", COLUMN_SELECTABLE); g_signal_connect (renderer, "toggled", G_CALLBACK (toggled), palette); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (priv->column, renderer, TRUE); gtk_tree_view_column_add_attribute (priv->column, renderer, "text", COLUMN_TITLE); - gtk_tree_view_column_add_attribute (priv->column, renderer, "weight", COLUMN_WEIGHT); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), palette); gtk_tree_view_append_column (GTK_TREE_VIEW (object), priv->column); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (object), TRUE); - gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (object), TRUE); gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (object), is_separator, NULL, NULL); gtk_tree_view_set_enable_search (GTK_TREE_VIEW (object), TRUE); gtk_tree_view_set_search_column (GTK_TREE_VIEW (object), COLUMN_TITLE); - gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)), GTK_SELECTION_NONE); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (object), FALSE); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)), GTK_SELECTION_BROWSE); update_list (palette); @@ -515,23 +454,28 @@ ephy_topics_palette_class_init (EphyTopicsPaletteClass *klass) "Bookmarks set", "Bookmarks set", EPHY_TYPE_BOOKMARKS, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); g_object_class_install_property (object_class, PROP_BOOKMARK, g_param_spec_pointer ("bookmark", "Bookmark", "Bookmark", - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); g_object_class_install_property (object_class, PROP_MODE, g_param_spec_int ("mode", "Mode", "Mode", - 0, MODES-1, 0, G_PARAM_WRITABLE)); + 0, MODES-1, 0, + G_PARAM_WRITABLE | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); g_type_class_add_private (object_class, sizeof(EphyTopicsPalettePrivate)); } |