diff options
Diffstat (limited to 'src/bookmarks/ephy-bookmark-properties.c')
-rw-r--r-- | src/bookmarks/ephy-bookmark-properties.c | 241 |
1 files changed, 174 insertions, 67 deletions
diff --git a/src/bookmarks/ephy-bookmark-properties.c b/src/bookmarks/ephy-bookmark-properties.c index 559b16b01..a1c7066e8 100644 --- a/src/bookmarks/ephy-bookmark-properties.c +++ b/src/bookmarks/ephy-bookmark-properties.c @@ -59,7 +59,9 @@ struct _EphyBookmarkPropertiesPrivate EphyNode *bookmark; gboolean creating; - EphyNode *duplicate; + gint duplicate_count; + gint duplicate_idle; + GtkWidget *warning; GtkWidget *entry; GtkWidget *palette; @@ -75,20 +77,45 @@ enum static GObjectClass *parent_class; +static gboolean +update_warning (EphyBookmarkProperties *properties) +{ + EphyBookmarkPropertiesPrivate *priv = properties->priv; + char *label; + + priv->duplicate_idle = 0; + priv->duplicate_count = ephy_bookmarks_count_duplicates + (priv->bookmarks, priv->bookmark); + + label = g_strdup_printf (_("%d _Similar"), priv->duplicate_count); + gtk_button_set_label (GTK_BUTTON (priv->warning), label); + g_free (label); + + g_object_set (priv->warning, "sensitive", priv->duplicate_count > 0, NULL); + + return FALSE; +} + static void -node_added_cb (EphyNode *bookmarks, - EphyNode *bookmark, - EphyBookmarkProperties *properties) +update_warning_idle (EphyBookmarkProperties *properties) { EphyBookmarkPropertiesPrivate *priv = properties->priv; - if (priv->duplicate == NULL) + if(priv->duplicate_idle != 0) { - priv->duplicate = ephy_bookmarks_find_duplicate - (priv->bookmarks, priv->bookmark); - g_object_set (priv->warning, "visible", - priv->duplicate != NULL, NULL); + g_source_remove (priv->duplicate_idle); } + + priv->duplicate_idle = g_timeout_add + (500, (GSourceFunc)update_warning, properties); +} + +static void +node_added_cb (EphyNode *bookmarks, + EphyNode *bookmark, + EphyBookmarkProperties *properties) +{ + update_warning_idle (properties); } static void @@ -97,15 +124,9 @@ node_changed_cb (EphyNode *bookmarks, guint property, EphyBookmarkProperties *properties) { - EphyBookmarkPropertiesPrivate *priv = properties->priv; - - if (priv->duplicate == bookmark || priv->bookmark == bookmark || - priv->duplicate == NULL) + if (property == EPHY_NODE_BMK_PROP_LOCATION) { - priv->duplicate = ephy_bookmarks_find_duplicate - (priv->bookmarks, priv->bookmark); - g_object_set (priv->warning, "visible", - priv->duplicate != NULL, NULL); + update_warning_idle (properties); } } @@ -115,21 +136,14 @@ node_removed_cb (EphyNode *bookmarks, guint index, EphyBookmarkProperties *properties) { - EphyBookmarkPropertiesPrivate *priv = properties->priv; - - if (priv->duplicate == bookmark) - { - priv->duplicate = ephy_bookmarks_find_duplicate - (priv->bookmarks, priv->bookmark); - g_object_set (priv->warning, "visible", - priv->duplicate != NULL, NULL); - } + update_warning_idle (properties); } static void node_destroy_cb (EphyNode *bookmark, GtkWidget *dialog) { + EPHY_BOOKMARK_PROPERTIES (dialog)->priv->creating = FALSE; gtk_widget_destroy (dialog); } @@ -157,17 +171,97 @@ ephy_bookmark_properties_set_bookmark (EphyBookmarkProperties *properties, G_OBJECT (properties)); } +static void +activate_merge_cb (GtkMenuItem *item, + EphyBookmarkProperties *properties) +{ + EphyBookmarkPropertiesPrivate *priv = properties->priv; + GPtrArray *duplicates; + GPtrArray *topics; + EphyNode *node, *topic; + gint i, j; + + duplicates = ephy_bookmarks_find_duplicates + (priv->bookmarks, priv->bookmark); + + node = ephy_bookmarks_get_keywords (priv->bookmarks); + topics = ephy_node_get_children (node); + + for (i = 0; i < duplicates->len; i++) + { + node = g_ptr_array_index (duplicates, i); + for (j = 0; j < topics->len; j++) + { + topic = g_ptr_array_index (topics, j); + + if (ephy_node_has_child (topic, node)) + { + ephy_bookmarks_set_keyword + (priv->bookmarks, topic, priv->bookmark); + } + } + ephy_node_unref (node); + } + + g_ptr_array_free (duplicates, TRUE); + + update_warning (properties); +} + +static void +activate_show_cb (GtkMenuItem *item, + EphyNode *node) +{ + ephy_bookmarks_ui_show_bookmark (node); +} static void show_duplicate_cb (GtkButton *button, EphyBookmarkProperties *properties) { EphyBookmarkPropertiesPrivate *priv = properties->priv; - EphyNode *dup = ephy_bookmarks_find_duplicate (priv->bookmarks, priv->bookmark); + EphyNode *node; + GPtrArray *duplicates; + GtkMenuShell *menu; + GtkWidget *item, *image; + gint i; + + update_warning (properties); + if (priv->duplicate_count == 0) + { + return; + } - g_return_if_fail (dup != NULL); + duplicates = ephy_bookmarks_find_duplicates + (priv->bookmarks, priv->bookmark); - ephy_bookmarks_ui_show_bookmark (dup); + menu = GTK_MENU_SHELL (gtk_menu_new ()); + item = gtk_image_menu_item_new_with_mnemonic (_("_Merge")); + image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + g_signal_connect (item, "activate", G_CALLBACK (activate_merge_cb), properties); + gtk_widget_show (image); + gtk_widget_show (item); + gtk_menu_shell_append (menu, item); + + item = gtk_separator_menu_item_new (); + gtk_widget_show (item); + gtk_menu_shell_append (menu, item); + + for (i = 0; i < duplicates->len; i++) + { + node = g_ptr_array_index (duplicates, i); + item = gtk_image_menu_item_new_with_label + (ephy_node_get_property_string (node, EPHY_NODE_BMK_PROP_TITLE)); + g_signal_connect (item, "activate", G_CALLBACK (activate_show_cb), node); + gtk_widget_show (item); + gtk_menu_shell_append (menu, item); + } + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + ephy_gui_menu_position_under_widget, button, + 0, gtk_get_current_event_time ()); + + g_ptr_array_free (duplicates, TRUE); } static void @@ -177,10 +271,16 @@ bookmark_properties_destroy_cb (GtkDialog *dialog, EphyBookmarkProperties *properties = EPHY_BOOKMARK_PROPERTIES (dialog); EphyBookmarkPropertiesPrivate *priv = properties->priv; - if (priv->creating && priv->bookmark != NULL) + if (priv->creating) { ephy_node_unref (priv->bookmark); - priv->bookmark = NULL; + priv->creating = FALSE; + } + + if(priv->duplicate_idle != 0) + { + g_source_remove (priv->duplicate_idle); + priv->duplicate_idle = 0; } } @@ -199,11 +299,8 @@ bookmark_properties_response_cb (GtkDialog *dialog, "epiphany", "to-edit-bookmark-properties"); 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 - * to NULL here to 'protect' it from unreffing. */ - priv->bookmark = NULL; + case GTK_RESPONSE_ACCEPT: + priv->creating = FALSE; break; default: break; @@ -273,7 +370,7 @@ toggled_cb (GtkToggleButton *button, if(gtk_toggle_button_get_active (button)) { g_object_set (priv->entry, "sensitive", FALSE, NULL); - g_object_set (priv->palette, "visible", TRUE, NULL); + gtk_widget_show (priv->palette); geometry.min_width = -1; geometry.min_height = 230; @@ -284,7 +381,7 @@ toggled_cb (GtkToggleButton *button, else { g_object_set (priv->entry, "sensitive", TRUE, NULL); - g_object_set (priv->palette, "visible", FALSE, NULL); + gtk_widget_hide (priv->palette); geometry.max_height = -1; geometry.max_width = G_MAXINT; @@ -310,10 +407,11 @@ ephy_bookmark_properties_constructor (GType type, EphyBookmarkProperties *properties; EphyBookmarkPropertiesPrivate *priv; GtkWidget *widget, *table, *label, *entry, *button; - GtkWidget *scrolled_window, *palette; + GtkWidget *container, *palette; GtkWindow *window; GtkDialog *dialog; const char *tmp; + char *text; object = parent_class->constructor (type, n_construct_properties, construct_params); @@ -349,7 +447,7 @@ ephy_bookmark_properties_constructor (GType type, 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_table_set_col_spacing (GTK_TABLE (table), 1, 6); gtk_container_set_border_width (GTK_CONTAINER (table), 5); gtk_widget_show (table); @@ -384,17 +482,6 @@ ephy_bookmark_properties_constructor (GType type, gtk_table_attach (GTK_TABLE (table), label, 0, 1, 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 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, 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); @@ -402,39 +489,57 @@ ephy_bookmark_properties_constructor (GType type, 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); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); palette = ephy_topics_palette_new (priv->bookmarks, priv->bookmark); - 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); - priv->palette = scrolled_window; - gtk_container_add (GTK_CONTAINER (scrolled_window), palette); + container = 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); + priv->palette = container; + gtk_container_add (GTK_CONTAINER (container), palette); gtk_widget_show (palette); - gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 3, 4, 5, + gtk_table_attach (GTK_TABLE (table), container, 1, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); - gtk_widget_show (scrolled_window); + gtk_widget_show (container); 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); + toggled_cb (GTK_TOGGLE_BUTTON (button), properties); gtk_widget_show (button); - gtk_table_attach (GTK_TABLE (table), button, 2, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0); - + gtk_table_attach (GTK_TABLE (table), button, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 0, 0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), table, TRUE, TRUE, 0); + priv->warning = gtk_button_new (); + gtk_button_set_use_underline (GTK_BUTTON (priv->warning), TRUE); + text = g_strdup_printf (_("%d _Similar"), 0); + gtk_button_set_label (GTK_BUTTON (priv->warning), text); + g_free (text); + widget = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (widget); + gtk_button_set_image (GTK_BUTTON (priv->warning), widget); + g_object_set (priv->warning, "sensitive", FALSE, NULL); + gtk_widget_show (priv->warning); + g_signal_connect (priv->warning, "clicked", + G_CALLBACK(show_duplicate_cb), properties); + gtk_dialog_add_button (dialog, GTK_STOCK_HELP, GTK_RESPONSE_HELP); + gtk_box_pack_end (GTK_BOX (dialog->action_area), + priv->warning, FALSE, TRUE, 0); + gtk_button_box_set_child_secondary + (GTK_BUTTON_BOX (dialog->action_area), priv->warning, TRUE); + if (priv->creating) { gtk_dialog_add_button (dialog, @@ -453,6 +558,8 @@ ephy_bookmark_properties_constructor (GType type, gtk_dialog_set_default_response (dialog, GTK_RESPONSE_CLOSE); } + update_warning_idle (properties); + return object; } |