Author: kelnos Date: 2009-06-13 18:11:32 +0000 (Sat, 13 Jun 2009) New Revision: 30010
Modified: xfdesktop/trunk/NEWS xfdesktop/trunk/settings/main.c Log: add image DnD to settings dialog (bug 4337) Modified: xfdesktop/trunk/NEWS =================================================================== --- xfdesktop/trunk/NEWS 2009-06-13 18:11:19 UTC (rev 30009) +++ xfdesktop/trunk/NEWS 2009-06-13 18:11:32 UTC (rev 30010) @@ -1,3 +1,9 @@ +Xfce 4.7.x +---------- + + * Allow DnD to image list in settings dialog (bug 4337). + + Xfce 4.6.2 ---------- Modified: xfdesktop/trunk/settings/main.c =================================================================== --- xfdesktop/trunk/settings/main.c 2009-06-13 18:11:19 UTC (rev 30009) +++ xfdesktop/trunk/settings/main.c 2009-06-13 18:11:32 UTC (rev 30010) @@ -128,7 +128,12 @@ N_ICON_COLS, }; +enum +{ + TARGET_TEXT_URI_LIST = 0, +}; + /* assumes gdk lock is held on function enter, and should be held * on function exit */ static void @@ -355,6 +360,53 @@ } static GtkTreeIter * +xfdesktop_settings_image_treeview_add(GtkTreeModel *model, + const char *path) +{ + gboolean added = FALSE; + GtkTreeIter iter; + gchar *name = NULL, *name_utf8 = NULL, *name_markup = NULL; + gchar *lower = NULL, *key = NULL; + + /* FIXME: this is probably too slow */ + if(!xfdesktop_image_file_is_valid(path)) + return NULL; + + name = g_path_get_basename(path); + if(name) { + name_utf8 = g_filename_to_utf8(name, strlen(name), + NULL, NULL, NULL); + if(name_utf8) { + name_markup = g_markup_printf_escaped("<b>%s</b>", + name_utf8); + + lower = g_utf8_strdown(name_utf8, -1); + key = g_utf8_collate_key(lower, -1); + + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, + COL_NAME, name_markup, + COL_FILENAME, path, + COL_COLLATE_KEY, key, + -1); + + added = TRUE; + } + } + + g_free(name); + g_free(name_utf8); + g_free(name_markup); + g_free(lower); + g_free(key); + + if(added) + return gtk_tree_iter_copy(&iter); + else + return NULL; +} + +static GtkTreeIter * xfdesktop_image_list_add_dir(GtkListStore *ls, const char *path, const char *cur_image_file) @@ -362,7 +414,7 @@ GDir *dir; gboolean needs_slash = TRUE; const gchar *file; - GtkTreeIter iter, *iter_ret = NULL; + GtkTreeIter *iter, *iter_ret = NULL; gchar buf[PATH_MAX]; dir = g_dir_open(path, 0, 0); @@ -376,31 +428,12 @@ g_snprintf(buf, sizeof(buf), needs_slash ? "%s/%s" : "%s%s", path, file); - /* FIXME: this is probably too slow */ - if(xfdesktop_image_file_is_valid(buf)) { - gchar *name, *name_markup, *key = NULL; - - name = g_filename_to_utf8(file, strlen(file), NULL, NULL, NULL); - name_markup = g_markup_printf_escaped("<b>%s</b>", name); - if(name) { - gchar *lower = g_utf8_strdown(name, -1); - key = g_utf8_collate_key(lower, -1); - g_free(lower); - } - - gtk_list_store_append(ls, &iter); - gtk_list_store_set(ls, &iter, - COL_NAME, name_markup, - COL_FILENAME, buf, - COL_COLLATE_KEY, key, - -1); - - if(cur_image_file && !strcmp(buf, cur_image_file)) - iter_ret = gtk_tree_iter_copy(&iter); - - g_free(name); - g_free(name_markup); - g_free(key); + iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), buf); + if(iter) { + if(cur_image_file && !iter_ret && !strcmp(buf, cur_image_file)) + iter_ret = iter; + else + gtk_tree_iter_free(iter); } } @@ -548,7 +581,7 @@ { gchar prop_image[1024], prop_last[1024], *image_file; GtkListStore *ls; - GtkTreeIter iter, *image_file_iter = NULL; + GtkTreeIter *image_file_iter = NULL; gboolean do_sort = TRUE; GtkTreeSelection *sel; @@ -597,24 +630,9 @@ xfconf_channel_set_string(panel->channel, prop_last, image_file); for(i = 0; images[i]; ++i) { - gchar *name, *name_markup; - - name = g_strrstr(images[i], G_DIR_SEPARATOR_S); - if(name) - name++; - else - name = images[i]; - name = g_filename_to_utf8(name, strlen(name), NULL, NULL, NULL); - name_markup = g_markup_printf_escaped("<b>%s</b>", name); - - gtk_list_store_append(ls, &iter); - gtk_list_store_set(ls, &iter, - COL_NAME, name_markup, - COL_FILENAME, images[i], - -1); - - g_free(name); - g_free(name_markup); + GtkTreeIter *iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), images[i]); + if(iter) + gtk_tree_iter_free(iter); } g_strfreev(images); @@ -653,36 +671,9 @@ image_file_iter = tmp; } - if(!image_file_iter) { - gchar *name, *name_markup, *key = NULL; + if(!image_file_iter) + image_file_iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), image_file); - name = g_strrstr(image_file, G_DIR_SEPARATOR_S); - if(name) - name++; - else - name = image_file; - name = g_filename_to_utf8(name, strlen(name), NULL, NULL, NULL); - name_markup = g_markup_printf_escaped("<b>%s</b>", name); - - if(name) { - gchar *lower = g_utf8_strdown(name, -1); - key = g_utf8_collate_key(lower, -1); - g_free(lower); - } - - gtk_list_store_append(ls, &iter); - gtk_list_store_set(ls, &iter, - COL_NAME, name_markup, - COL_FILENAME, image_file, - COL_COLLATE_KEY, key, - -1); - image_file_iter = gtk_tree_iter_copy(&iter); - - g_free(name); - g_free(name_markup); - g_free(key); - } - panel->image_list_loaded = FALSE; panel->image_selector_loaded = TRUE; gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); @@ -840,33 +831,16 @@ pdata->model = g_object_ref(G_OBJECT(model)); for(l = filenames; l; l = l->next) { - /* all these copies are gross */ - char *filename = l->data; - char *name = g_path_get_basename(filename); - gchar *name_utf8 = g_filename_to_utf8(name, strlen(name), - NULL, NULL, NULL); - gchar *name_markup = g_markup_printf_escaped("<b>%s</b>", - name_utf8); - GtkTreeIter iter; + GtkTreeIter *iter = xfdesktop_settings_image_treeview_add(model, l->data); + if(iter) { + pdata->iters = g_slist_prepend(pdata->iters, iter); - gtk_list_store_append(GTK_LIST_STORE(model), &iter); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, - COL_NAME, name_markup, - COL_FILENAME, filename, - -1); - - /* auto-select the first one added */ - if(l == filenames) { - GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview)); - gtk_tree_selection_select_iter(sel, &iter); + /* auto-select the first one added */ + if(l == filenames) { + GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview)); + gtk_tree_selection_select_iter(sel, iter); + } } - - pdata->iters = g_slist_prepend(pdata->iters, gtk_tree_iter_copy(&iter)); - - g_free(filename); - g_free(name); - g_free(name_utf8); - g_free(name_markup); } g_slist_free(filenames); @@ -1077,6 +1051,153 @@ gtk_widget_set_sensitive(box, gtk_toggle_button_get_active(btn)); } +static void +image_treeview_drag_data_received(GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time_, + gpointer user_data) +{ + AppearancePanel *panel = user_data; + gboolean file_added; + gchar *p; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); + PreviewData *pdata = g_new0(PreviewData, 1); + + pdata->model = g_object_ref(G_OBJECT(model)); + + if(TARGET_TEXT_URI_LIST != info + || selection_data->format != 8 + || selection_data->length <= 0) + { + gtk_drag_finish(context, FALSE, FALSE, time_); + return; + } + + p = (gchar *)selection_data->data; + while(*p) { + if(*p != '#') { + gchar *q; + + while(g_ascii_isspace(*p)) + p++; + + q = p; + while(*q && *q != '\n' && *q != '\r') + q++; + + if(q > p) { + q--; + while(g_ascii_isspace(*q)) + q--; + + if(!strncmp(p, "file://", 7)) { + /* we only handle file uris */ + gchar oldq, *filename; + + q++; + oldq = *q; + *q = 0; + + filename = g_filename_from_uri(p, NULL, NULL); + if(filename) { + GtkTreeIter *iter = NULL; + + if(g_file_test(filename, G_FILE_TEST_IS_DIR)) { + GDir *dir = g_dir_open(filename, 0, 0); + + if(dir) { + const gchar *name; + gchar buf[PATH_MAX]; + gboolean needs_slash = TRUE; + + if(filename[strlen(filename)-1] == '/') + needs_slash = FALSE; + + while((name = g_dir_read_name(dir))) { + g_snprintf(buf, sizeof(buf), + needs_slash ? "%s/%s" : "%s%s", + filename, name); + iter = xfdesktop_settings_image_treeview_add(model, buf); + if(iter) + pdata->iters = g_slist_prepend(pdata->iters, iter); + } + g_dir_close(dir); + } + } else if(g_file_test(filename, G_FILE_TEST_EXISTS)) { + iter = xfdesktop_settings_image_treeview_add(model, filename); + if(iter) + pdata->iters = g_slist_prepend(pdata->iters, iter); + } + + g_free(filename); + } + + *q = oldq; + } + } + } + + p = strchr(p, '\n'); + if(p) + p++; + } + + file_added = !!pdata->iters; + + if(!pdata->iters + || !g_thread_create(xfdesktop_settings_create_some_previews, + pdata, FALSE, NULL)) + { + if(pdata->iters) + g_critical("Unable to create thread for single image preview."); + g_object_unref(G_OBJECT(pdata->model)); + g_slist_foreach(pdata->iters, (GFunc)gtk_tree_iter_free, NULL); + g_slist_free(pdata->iters); + g_free(pdata); + } + + gtk_drag_finish(context, file_added, FALSE, time_); + + if(file_added && panel->image_list_loaded) + xfdesktop_settings_save_backdrop_list(panel, model); +} + +static void +xfdesktop_settings_setup_image_treeview(AppearancePanel *panel) +{ + static GtkTargetEntry drag_targets[] = { + { "text/uri-list", 0, TARGET_TEXT_URI_LIST }, + }; + GtkCellRenderer *render; + GtkTreeViewColumn *col; + + render = gtk_cell_renderer_pixbuf_new(); + col = gtk_tree_view_column_new_with_attributes("thumbnail", render, + "pixbuf", COL_PIX, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), + col); + render = gtk_cell_renderer_text_new(); + col = gtk_tree_view_column_new_with_attributes("name", render, + "markup", COL_NAME, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), + col); + + g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview))), + "changed", + G_CALLBACK(cb_image_selection_changed), panel); + + gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(panel->image_treeview), + drag_targets, 1, + GDK_ACTION_DEFAULT | GDK_ACTION_COPY); + + g_signal_connect(G_OBJECT(panel->image_treeview), "drag-data-received", + G_CALLBACK(image_treeview_drag_data_received), panel); +} + static GtkWidget * xfdesktop_settings_dialog_new(GladeXML *main_gxml, XfconfChannel *channel) @@ -1116,8 +1237,6 @@ GladeXML *appearance_gxml; AppearancePanel *panel = g_new0(AppearancePanel, 1); GtkWidget *appearance_settings, *appearance_label; - GtkCellRenderer *render; - GtkTreeViewColumn *col; panel->channel = channel; panel->screen = i; @@ -1221,21 +1340,8 @@ panel->image_treeview = glade_xml_get_widget(appearance_gxml, "treeview_imagelist"); - render = gtk_cell_renderer_pixbuf_new(); - col = gtk_tree_view_column_new_with_attributes("thumbnail", render, - "pixbuf", COL_PIX, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), - col); - render = gtk_cell_renderer_text_new(); - col = gtk_tree_view_column_new_with_attributes("name", render, - "markup", COL_NAME, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), - col); + xfdesktop_settings_setup_image_treeview(panel); - g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview))), - "changed", - G_CALLBACK(cb_image_selection_changed), panel); - panel->btn_plus = glade_xml_get_widget(appearance_gxml, "btn_plus"); g_signal_connect(G_OBJECT(panel->btn_plus), "clicked", G_CALLBACK(add_file_button_clicked), panel); _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits