/* * folder_tree.c - things related to the folder tree widget in the UI */ #include "lodju.h" static GtkCTree *folder_tree; static GtkCTreeNode *selected_node; static GtkWidget *rename_folder_entry; static GtkWidget *rename_folder_ok; static GtkWidget *new_folder_entry; static GtkWidget *new_folder_ok; void folder_tree_set(GtkCTree *ctree) { folder_tree = ctree; } GtkCTree *folder_tree_get(void) { return folder_tree; } ImageFolder *folder_tree_get_selected(void) { if (selected_node == NULL) return NULL; return gtk_ctree_node_get_row_data(folder_tree, selected_node); } GtkCTreeNode *folder_tree_get_node(void) { return selected_node; } void folder_tree_set_node(GtkCTreeNode *node) { selected_node = node; } void folder_tree_clear(void) { GtkCTreeNode *root; root = gtk_ctree_node_nth(folder_tree, 0); if (root != NULL) gtk_ctree_remove_node(folder_tree, root); } static GtkCTreeNode *append_folder_to_widget(ImageFolder *folder, GtkCTree *folder_tree, GtkCTreeNode *parent_node) { gchar *text[1]; GtkCTreeNode *node; text[0] = (gchar *) image_folder_get_attribute(folder, "name"); node = gtk_ctree_insert_node(folder_tree, parent_node, NULL, text, 0, NULL, NULL, NULL, NULL, FALSE, TRUE); gtk_ctree_node_set_row_data(GTK_CTREE(folder_tree), node, folder); /* * The selection mode for the folder tree is "browse". If the tree was * empty, when we added the new node above, then it generated and * handled the "tree_select_row" signal to select the new and only * node during the call to gtk_ctree_insert_node. Thus, we did not * have time to set the row data for the node. Thus, we re-select it * here in that case. This causes the handler for the signal to * actually do what it is supposed to do, when it can access the * row data. */ if (gtk_ctree_node_nth(GTK_CTREE(folder_tree), 0) == node) gtk_ctree_select(GTK_CTREE(folder_tree), node); return node; } void put_folder_tree_into_widget(ImageFolder *folder, GtkCTree *folder_tree, GtkCTreeNode *parent_node) { GtkCTreeNode *node; GList *list; GList *item; node = append_folder_to_widget(folder, folder_tree, parent_node); list = image_folder_get_folders(folder); for (item = list; item != NULL; item = item->next) put_folder_tree_into_widget(item->data, folder_tree, node); g_list_free(list); } void on_folder_tree_select_row(GtkCTree *ctree, GtkCTreeNode *node, gint column, gpointer user_data) { GList *images; GList *n; ImageFolder *folder; folder_tree_set_node(node); image_list_clear(); folder = folder_tree_get_selected(); if (folder != NULL) { images = image_folder_get_images(folder); for (n = images; n != NULL; n = n->next) image_list_append_image(n->data); g_list_free(images); } } void on_folder_tree_unselect_row(GtkCTree *ctree, GtkCTreeNode *node, gint column, gpointer user_data) { ImageFolder *folder; folder = gtk_ctree_node_get_row_data(ctree, node); if (folder_tree_get_selected() == folder) { folder_tree_set_node(NULL); image_list_clear(); meta_clear(); } } void on_rename_folder_entry_activate(GtkEditable *w, gpointer user_data) { if (rename_folder_ok != NULL) gtk_button_clicked(GTK_BUTTON(rename_folder_ok)); } void on_rename_folder_apply(GtkButton *button, gpointer user_data) { ImageFolder *folder; gchar *new_name; folder = folder_tree_get_selected(); if (folder == NULL) return; new_name = gtk_entry_get_text(GTK_ENTRY(rename_folder_entry)); image_folder_set_attribute(folder, "name", new_name); if (folder_tree_get_node() != NULL) gtk_ctree_node_set_text(folder_tree_get(), folder_tree_get_node(), 0, new_name); } void on_rename_folder_activate(GtkMenuItem *menuitem, gpointer user_data) { GladeXML *xml; GtkWidget *rfd; GtkWidget *cancel_button; const gchar *text; if (folder_tree_get_selected() == NULL) return; xml = load_user_interface("rename_folder_dialog"); if (xml == NULL) return; rfd = glade_xml_get_widget(xml, "rename_folder_dialog"); rename_folder_entry = glade_xml_get_widget(xml, "rename_folder_entry"); rename_folder_ok = glade_xml_get_widget(xml, "rename_folder_ok_button"); cancel_button = glade_xml_get_widget(xml, "rename_folder_cancel_button"); text = image_folder_get_attribute(folder_tree_get_selected(), "name"); gtk_entry_set_text(GTK_ENTRY(rename_folder_entry), text); gtk_editable_select_region(GTK_EDITABLE(rename_folder_entry), 0, strlen(text)); gtk_signal_connect_object(GTK_OBJECT(rename_folder_ok), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) rfd); gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) rfd); gtk_widget_show(rfd); } void on_new_folder_entry_activate(GtkEditable *w, gpointer user_data) { if (new_folder_ok != NULL) gtk_button_clicked(GTK_BUTTON(new_folder_ok)); } void on_new_folder_ok(GtkButton *button, gpointer user_data) { ImageFolder *folder; ImageFolder *new_folder; GtkCTreeNode *node; GtkCTreeNode *new_node; gchar *new_name; folder = folder_tree_get_selected(); node = folder_tree_get_node(); if (folder == NULL || node == NULL) return; new_folder = image_folder_create(folder); new_node = append_folder_to_widget(new_folder, folder_tree_get(), node); new_name = gtk_entry_get_text(GTK_ENTRY(new_folder_entry)); image_folder_set_attribute(new_folder, "name", new_name); gtk_ctree_node_set_text(folder_tree_get(), new_node, 0, new_name); } void on_new_folder_activate(GtkMenuItem *menuitem, gpointer user_data) { GladeXML *xml; GtkWidget *nfd; GtkWidget *cancel_button; if (folder_tree_get_selected() == NULL) return; xml = load_user_interface("new_folder_dialog"); if (xml == NULL) return; nfd = glade_xml_get_widget(xml, "new_folder_dialog"); new_folder_entry = glade_xml_get_widget(xml, "new_folder_entry"); new_folder_ok = glade_xml_get_widget(xml, "new_folder_ok_button"); cancel_button = glade_xml_get_widget(xml, "new_folder_cancel_button"); gtk_signal_connect_object(GTK_OBJECT(new_folder_ok), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) nfd); gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) nfd); gtk_widget_show(nfd); } #if 0 void on_new_folder_activate(GtkMenuItem *menuitem, gpointer user_data) { ImageFolder *folder; GtkCTreeNode *new_node; if (folder_tree_get_selected() == NULL || folder_tree_get_node() == NULL) return; folder = image_folder_create(folder_tree_get_selected()); new_node = append_folder_to_widget(folder, folder_tree_get(), folder_tree_get_node()); gtk_ctree_select(folder_tree_get(), new_node); on_rename_folder_activate(NULL, NULL); } #endif void on_folder_tree_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data) { gint row; gint column; GtkCTreeNode *node; ImageFolder *folder; ImageFolder *new_folder; gboolean ok; /* If the user drops below last row in tree, adjust x until it is at * the last row. */ for (;;) { ok = gtk_clist_get_selection_info(GTK_CLIST(folder_tree), x, y, &row, &column); if (ok) break; if (y == 0) return; /* Eek, this shouldn't really happen. Empty tree? */ --y; } node = gtk_ctree_node_nth(folder_tree, row); folder = gtk_ctree_node_get_row_data(folder_tree, node); switch (info) { case MIME_LODJU_DND_IMAGE: image_folder_import_from_xml(folder, data->data); break; case MIME_LODJU_DND_FOLDER: new_folder = image_folder_create_from_xml(folder, data->data); put_folder_tree_into_widget(new_folder, folder_tree, node); break; } } void on_folder_tree_drag_data_delete(GtkWidget *widget, GdkDragContext *drag_context, gpointer user_data) { if (folder_tree_get_selected() != NULL) { image_folder_destroy(folder_tree_get_selected()); if (folder_tree_get_node() != NULL) gtk_ctree_remove_node(folder_tree_get(), folder_tree_get_node()); folder_tree_set_node(NULL); image_list_clear(); meta_clear(); } } void on_remove_folder_ok_clicked(GtkButton *button, gpointer user_data) { if (folder_tree_get_selected() == NULL || folder_tree_get_node() == NULL) return; image_folder_destroy(folder_tree_get_selected()); image_list_clear(); gtk_ctree_remove_node(folder_tree_get(), folder_tree_get_node()); folder_tree_set_node(NULL); } void on_remove_folder_activate(GtkMenuItem *menuitem, gpointer user_data) { GladeXML *xml; GtkWidget *rfd; GtkWidget *ok_button; GtkWidget *cancel_button; if (folder_tree_get_selected == NULL) return; if (gtk_ctree_node_nth(folder_tree, 0) == folder_tree_get_node()) return; xml = load_user_interface("remove_folder_dialog"); if (xml == NULL) return; rfd = glade_xml_get_widget(xml, "remove_folder_dialog"); ok_button = glade_xml_get_widget(xml, "remove_folder_ok"); cancel_button = glade_xml_get_widget(xml, "remove_folder_cancel"); gtk_signal_connect_object(GTK_OBJECT(ok_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) rfd); gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) rfd); gtk_widget_show(rfd); } void on_folder_tree_drag_data_get(GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *data, guint info, guint time, gpointer user_data) { gchar *xml; if (folder_tree_get_selected() != NULL) { xml = image_folder_get_xml(folder_tree_get_selected()); gtk_selection_data_set(data, data->target, 8, xml, strlen(xml)); } }