# HG changeset patch # User Richard Laager # Date 1183241564 0 # Node ID fafb3af5aa126bf1e691443fda6b69d435f4fe94 # Parent 2aad33bb021d2d69bea210fee7705fd5bcd71525# Parent b2caad7bc71bce6c9ac4da228aa313490491a5bb propagate from branch 'im.pidgin.pidgin' (head ede31f4a584caeaede8c7c46cbece5a420b41050) to branch 'org.maemo.garage.pidgin.smiley-install' (head 5270b8d15c2c493dd6582ce904fd6072a53d469b) diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/dbus-bindings.h diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/dbus-useful.c diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/debug.c diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/plugins/perl/common/Connection.xs diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/protocols/jabber/jutil.c diff -r b2caad7bc71b -r fafb3af5aa12 libpurple/protocols/yahoo/yahoochat.h diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/gtkdocklet.c diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/gtklog.c diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Sat Jun 30 22:09:50 2007 +0000 +++ b/pidgin/gtkprefs.c Sat Jun 30 22:12:44 2007 +0000 @@ -60,6 +60,7 @@ static GtkWidget *sound_entry = NULL; static GtkListStore *smiley_theme_store = NULL; +static GtkTreeSelection *smiley_theme_sel = NULL; static GtkWidget *prefs_proxy_frame = NULL; static GtkWidget *prefs = NULL; @@ -366,9 +367,12 @@ GValue val; GtkTreePath *path, *oldpath; struct smiley_theme *new_theme, *old_theme; + GtkWidget *remove_button = g_object_get_data(G_OBJECT(sel), "remove_button"); - if (!gtk_tree_selection_get_selected(sel, &model, &iter)) + if (!gtk_tree_selection_get_selected(sel, &model, &iter)) { + gtk_widget_set_sensitive(remove_button, FALSE); return; + } old_theme = current_smiley_theme; val.g_type = 0; @@ -376,6 +380,8 @@ path = gtk_tree_model_get_path(model, &iter); themename = g_value_get_string(&val); purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", themename); + + gtk_widget_set_sensitive(remove_button, strcmp(themename, "none")); g_value_unset (&val); /* current_smiley_theme is set in callback for the above pref change */ @@ -514,8 +520,13 @@ g_free(destdir); theme_rowref = theme_refresh_theme_list(); - if (theme_rowref != NULL) + if (theme_rowref != NULL) { + GtkTreePath *tp = gtk_tree_row_reference_get_path(theme_rowref); + + if(tp) + gtk_tree_selection_select_path(smiley_theme_sel, tp); gtk_tree_row_reference_free(theme_rowref); + } } static void @@ -619,9 +630,56 @@ return ret; } +static void +request_theme_file_name_cb (gpointer data, char *theme_file_name) +{ + theme_install_theme (theme_file_name, NULL) ; +} + +static void +add_theme_button_clicked_cb (GtkWidget *widget, gpointer null) +{ + purple_request_file (NULL, "Install Theme", NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ; +} + +static void +remove_theme_button_clicked_cb(GtkWidget *button, GtkTreeView *tv) +{ + char *theme_name = NULL, *theme_file = NULL; + GtkTreeModel *tm; + GtkTreeIter itr; + GtkTreeRowReference *trr = NULL; + + if ((tm = gtk_tree_view_get_model(tv)) == NULL) return; + if (!gtk_tree_selection_get_selected(smiley_theme_sel, NULL, &itr)) return; + gtk_tree_model_get(tm, &itr, 2, &theme_file, 3, &theme_name, -1); + + if(theme_name && strcmp(theme_name, "none")) { + if (theme_file) { + pidgin_themes_remove_smiley_theme(theme_file); + } + } + + if ((trr = theme_refresh_theme_list()) != NULL) { + GtkTreePath *tp = gtk_tree_row_reference_get_path(trr); + + if (tp) { + gtk_tree_selection_select_path(smiley_theme_sel, tp); + gtk_tree_path_free(tp); + } + gtk_tree_row_reference_free(trr); + } + + g_free(theme_file); + g_free(theme_name); +} + static GtkWidget * theme_page() { + GtkWidget *add_button, *remove_button; + GtkWidget *hbox_buttons; + GtkWidget *alignment; GtkWidget *ret; GtkWidget *sw; GtkWidget *view; @@ -661,7 +719,7 @@ g_signal_connect(G_OBJECT(view), "drag_data_received", G_CALLBACK(theme_dnd_recv), smiley_theme_store); rend = gtk_cell_renderer_pixbuf_new(); - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + smiley_theme_sel = sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); /* Custom sort so "none" theme is at top of list */ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(smiley_theme_store), @@ -687,6 +745,25 @@ g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smiley_sel), NULL); + alignment = gtk_alignment_new(1.0, 0.5, 0.0, 1.0); + gtk_widget_show(alignment); + gtk_box_pack_start(GTK_BOX(ret), alignment, FALSE, TRUE, 0); + + hbox_buttons = gtk_hbox_new(TRUE, PIDGIN_HIG_CAT_SPACE); + gtk_widget_show(hbox_buttons); + gtk_container_add(GTK_CONTAINER(alignment), hbox_buttons); + + add_button = gtk_button_new_from_stock(GTK_STOCK_ADD); + gtk_widget_show(add_button); + gtk_box_pack_start(GTK_BOX(hbox_buttons), add_button, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(add_button), "clicked", (GCallback)add_theme_button_clicked_cb, view); + + remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); + gtk_widget_show(remove_button); + gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, FALSE, TRUE, 0); + g_signal_connect(G_OBJECT(remove_button), "clicked", (GCallback)remove_theme_button_clicked_cb, view); + g_object_set_data(G_OBJECT(sel), "remove_button", remove_button); + if (rowref) { GtkTreePath *path = gtk_tree_row_reference_get_path(rowref); gtk_tree_row_reference_free(rowref); diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/gtkthemes.c --- a/pidgin/gtkthemes.c Sat Jun 30 22:09:50 2007 +0000 +++ b/pidgin/gtkthemes.c Sat Jun 30 22:12:44 2007 +0000 @@ -36,6 +36,8 @@ GSList *smiley_themes = NULL; struct smiley_theme *current_smiley_theme; +static void pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme); + gboolean pidgin_themes_smileys_disabled() { if (!current_smiley_theme) @@ -44,6 +46,78 @@ return strcmp(current_smiley_theme->name, "none") == 0; } +static void +pidgin_themes_destroy_smiley_theme(struct smiley_theme *theme) { + pidgin_themes_destroy_smiley_theme_smileys(theme); + + g_free(theme->name); + g_free(theme->desc); + g_free(theme->author); + g_free(theme->icon); + g_free(theme->path); + g_free(theme); +} + +static void pidgin_themes_remove_theme_dir(const char *theme_dir_name) +{ + GString *str = NULL; + const char *file_name = NULL; + GDir *theme_dir = NULL; + + if ((theme_dir = g_dir_open(theme_dir_name, 0, NULL)) != NULL) { + if ((str = g_string_new(theme_dir_name)) != NULL) { + while ((file_name = g_dir_read_name(theme_dir)) != NULL) { + g_string_printf(str, "%s%s%s", theme_dir_name, G_DIR_SEPARATOR_S, file_name); + g_unlink(str->str); + } + g_string_free(str, TRUE); + } + g_dir_close(theme_dir); + g_rmdir(theme_dir_name); + } +} + +void pidgin_themes_remove_smiley_theme(const char *file) +{ + char *theme_dir = NULL, *last_slash = NULL; + g_return_if_fail(NULL != file); + + if (!g_file_test(file, G_FILE_TEST_EXISTS)) return; + if ((theme_dir = g_strdup(file)) == NULL) return ; + + if ((last_slash = g_strrstr(theme_dir, G_DIR_SEPARATOR_S)) != NULL) { + GSList *iter = NULL; + struct smiley_theme *theme = NULL, *new_theme = NULL; + + *last_slash = 0; + + /* Delete files on disk */ + pidgin_themes_remove_theme_dir(theme_dir); + + /* Find theme in themes list and remove it */ + for (iter = smiley_themes ; iter ; iter = iter->next) { + theme = ((struct smiley_theme *)(iter->data)); + if (!strcmp(theme->path, file)) + break ; + } + if (iter) { + if (theme == current_smiley_theme) { + new_theme = ((struct smiley_theme *)(NULL == iter->next ? (smiley_themes == iter ? NULL : smiley_themes->data) : iter->next->data)); + if (new_theme) + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme->name); + else + current_smiley_theme = NULL; + } + smiley_themes = g_slist_delete_link(smiley_themes, iter); + + /* Destroy theme structure */ + pidgin_themes_destroy_smiley_theme(theme); + } + } + + g_free(theme_dir); +} + void pidgin_themes_smiley_themeize(GtkWidget *imhtml) { struct smiley_list *list; @@ -64,7 +138,7 @@ } static void -pidgin_themes_destroy_smiley_theme(struct smiley_theme *theme) +pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme) { GHashTable *already_freed; struct smiley_list *wer; @@ -92,6 +166,44 @@ g_hash_table_destroy(already_freed); } +static void smiley_theme_free(struct smiley_theme *theme) +{ + pidgin_themes_destroy_smiley_theme(theme); + + g_free(theme->name); + g_free(theme->desc); + g_free(theme->author); + g_free(theme->icon); + g_free(theme->path); + g_free(theme); +} + +static void +pidgin_smiley_themes_remove_non_existing() +{ + static struct smiley_theme *theme = NULL; + GSList *iter = NULL; + + if (!smiley_themes) return ; + + for (iter = smiley_themes ; iter ; iter = iter->next) { + theme = ((struct smiley_theme *)(iter->data)); + if (!g_file_test(theme->path, G_FILE_TEST_EXISTS)) { + if (theme == current_smiley_theme) + current_smiley_theme = ((struct smiley_theme *)(NULL == iter->next ? NULL : iter->next->data)); + smiley_theme_free(theme); + iter->data = NULL; + } + } + /* Remove all elements whose data is NULL */ + smiley_themes = g_slist_remove_all(smiley_themes, NULL); + + if (!current_smiley_theme && smiley_themes) { + struct smiley_theme *smile = g_slist_last(smiley_themes)->data; + pidgin_themes_load_smiley_theme(smile->path, TRUE); + } +} + void pidgin_themes_load_smiley_theme(const char *file, gboolean load) { FILE *f = g_fopen(file, "r"); @@ -220,15 +332,7 @@ if (!theme->name || !theme->desc || !theme->author) { purple_debug_error("gtkthemes", "Invalid file format, not loading smiley theme from '%s'\n", file); - pidgin_themes_destroy_smiley_theme(theme); - - g_free(theme->name); - g_free(theme->desc); - g_free(theme->author); - g_free(theme->icon); - g_free(theme->path); - g_free(theme); - + smiley_theme_free(theme); return; } @@ -240,7 +344,7 @@ GList *cnv; if (current_smiley_theme) - pidgin_themes_destroy_smiley_theme(current_smiley_theme); + pidgin_themes_destroy_smiley_theme_smileys(current_smiley_theme); current_smiley_theme = theme; for (cnv = purple_get_conversations(); cnv != NULL; cnv = cnv->next) { @@ -258,10 +362,12 @@ { GDir *dir; const gchar *file; - gchar *path; + gchar *path, *test_path; int l; + char* probedirs[3]; - char* probedirs[3]; + pidgin_smiley_themes_remove_non_existing(); + probedirs[0] = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", NULL); probedirs[1] = g_build_filename(purple_user_dir(), "smileys", NULL); probedirs[2] = 0; @@ -269,14 +375,18 @@ dir = g_dir_open(probedirs[l], 0, NULL); if (dir) { while ((file = g_dir_read_name(dir))) { - path = g_build_filename(probedirs[l], file, "theme", NULL); + test_path = g_build_filename(probedirs[l], file, NULL); + if (g_file_test(test_path, G_FILE_TEST_IS_DIR)) { + path = g_build_filename(probedirs[l], file, "theme", NULL); - /* Here we check to see that the theme has proper syntax. - * We set the second argument to FALSE so that it doesn't load - * the theme yet. - */ - pidgin_themes_load_smiley_theme(path, FALSE); - g_free(path); + /* Here we check to see that the theme has proper syntax. + * We set the second argument to FALSE so that it doesn't load + * the theme yet. + */ + pidgin_themes_load_smiley_theme(path, FALSE); + g_free(path); + } + g_free(test_path); } g_dir_close(dir); } else if (l == 1) { @@ -284,6 +394,11 @@ } g_free(probedirs[l]); } + + if (!current_smiley_theme && smiley_themes) { + struct smiley_theme *smile = smiley_themes->data; + pidgin_themes_load_smiley_theme(smile->path, TRUE); + } } GSList *pidgin_themes_get_proto_smileys(const char *id) { @@ -333,5 +448,4 @@ struct smiley_theme *smile = smiley_themes->data; pidgin_themes_load_smiley_theme(smile->path, TRUE); } - } diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/gtkthemes.h --- a/pidgin/gtkthemes.h Sat Jun 30 22:09:50 2007 +0000 +++ b/pidgin/gtkthemes.h Sat Jun 30 22:12:44 2007 +0000 @@ -49,5 +49,6 @@ void pidgin_themes_smiley_themeize(GtkWidget *); void pidgin_themes_smiley_theme_probe(void); void pidgin_themes_load_smiley_theme(const char *file, gboolean load); +void pidgin_themes_remove_smiley_theme(const char *file); GSList *pidgin_themes_get_proto_smileys(const char *id); #endif /* _PIDGINDIALOGS_H_ */ diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/pixmaps/toolbar/16/Makefile.am diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/plugins/gestures/gestures.c diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/plugins/notify.c diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/plugins/spellchk.c diff -r b2caad7bc71b -r fafb3af5aa12 pidgin/plugins/timestamp.c