#include "window_tag.h" #include "tags_ui.h" #include "db.h" #include "text_input_dialog.h" #include "tag_model.h" void on_tagview_cell_toggled(GtkCellRendererToggle *cell_renderer, gchar *path_string, gpointer user_data) { GtkTreeIter iter; GtkTreeModel *model; struct tagdialog_data_t *data; gboolean active, inconsistent; data = user_data; model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->tagview)); gtk_tree_model_get_iter_from_string(model, &iter, path_string); active = tag_model_get_checked(model, &iter); inconsistent = tag_model_get_inconsistent(model, &iter); if(inconsistent) { tag_model_set_inconsistent(GTK_TREE_MODEL(model), &iter, FALSE); } else { tag_model_set_checked(GTK_TREE_MODEL(model), &iter, !active); } } /** * foreach-callback for setting checked and inconsistent in the tag model. */ static gboolean tagview_model_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { struct tag_t *tag; struct tagdialog_data_t *data; struct tag_inconsistent_data_t *inconsistent_data; data = user_data; tag_model_get_tag_record(GTK_TREE_MODEL(model), iter, &tag); inconsistent_data = g_hash_table_lookup(data->inconsistent_table, (gpointer)tag->id); if(inconsistent_data) { tag_model_set_checked(GTK_TREE_MODEL(model), iter, inconsistent_data->active); tag_model_set_inconsistent(GTK_TREE_MODEL(model), iter, inconsistent_data->inconsistent); } return FALSE; } static void tagview_create_model(GtkTreeView *tagview, gpointer user_data) { GtkTreeModel *model; GArray *wallarray; struct tagdialog_data_t *data; data = user_data; wallarray = data->wallarray; db_wall_tags_inconsistent(wallarray, &(data->inconsistent_table)); model = GTK_TREE_MODEL(tag_model_new()); gtk_tree_view_set_model(tagview, GTK_TREE_MODEL(model)); gtk_tree_model_foreach(GTK_TREE_MODEL(model), tagview_model_foreach, user_data); gtk_tree_view_expand_all(tagview); } static void tagview_init(GtkTreeView *tagview, gpointer user_data) { GtkTreeViewColumn *col1, *col2; GtkCellRenderer *renderer; col1 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col1, "Select"); gtk_tree_view_append_column(tagview, col1); col2 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col2, "Name"); gtk_tree_view_append_column(tagview, col2); renderer = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(col1, renderer, FALSE); gtk_tree_view_column_add_attribute(col1, renderer, "active", 0); gtk_tree_view_column_add_attribute(col1, renderer, "inconsistent", 1); g_signal_connect(renderer, "toggled", G_CALLBACK(on_tagview_cell_toggled), user_data); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_end(col2, renderer, TRUE); gtk_tree_view_column_add_attribute(col2, renderer, "text", 2); tagview_create_model(tagview, user_data); } void on_tags_addbtn_clicked(GtkButton *button, gpointer user_data) { struct tagdialog_data_t *data; GtkDialog *dialog; gchar *s; data = user_data; dialog = text_input_dialog_new(data->dialog, "Enter the name of the new tag:"); if(gtk_dialog_run(dialog) == GTK_RESPONSE_OK) { s = text_input_dialog_get_text(GTK_WIDGET(dialog)); if(db_add_tag(s, 0)) tagview_create_model(GTK_TREE_VIEW(data->tagview), user_data); else g_warning("Failed to add tag \"%s\"\n", s); g_free(s); } gtk_widget_destroy(GTK_WIDGET(dialog)); } void on_tags_addchildbtn_clicked(GtkButton *button, gpointer user_data) { struct tagdialog_data_t *data; GtkDialog *dialog; gchar *s; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; struct tag_t *tag; data = user_data; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->tagview)); if(!gtk_tree_selection_get_selected(selection, &model, &iter)) { return; } tag_model_get_tag_record(GTK_TREE_MODEL(model), &iter, &tag); dialog = text_input_dialog_new(data->dialog, "Enter the name of the new tag:"); if(gtk_dialog_run(dialog) == GTK_RESPONSE_OK) { s = text_input_dialog_get_text(GTK_WIDGET(dialog)); if(db_add_tag(s, tag->id)) tagview_create_model(GTK_TREE_VIEW(data->tagview), user_data); else g_warning("Failed to add tag \"%s\"\n", s); g_free(s); } gtk_widget_destroy(GTK_WIDGET(dialog)); } void on_tags_rembtn_clicked(GtkButton *button, gpointer user_data) { GtkWidget *dialog; struct tagdialog_data_t *data; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; struct tag_t *tag; data = user_data; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->tagview)); if(!gtk_tree_selection_get_selected(selection, &model, &iter)) return; tag_model_get_tag_record(GTK_TREE_MODEL(model), &iter, &tag); dialog = gtk_message_dialog_new(GTK_WINDOW(data->dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Are you sure you want to delete the tag \"%s\" and all its children?", tag->name); if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) { db_remove_tag(tag->id); tagview_create_model(GTK_TREE_VIEW(data->tagview), user_data); } gtk_widget_destroy(dialog); } static void tags_select(gpointer user_data, gboolean select) { struct tagdialog_data_t *data; GtkTreeModel *model; GtkTreeIter iter; data = user_data; model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->tagview)); if(!gtk_tree_model_get_iter_first(model, &iter)) return; do { tag_model_set_checked(GTK_TREE_MODEL(model), &iter, select); } while(gtk_tree_model_iter_next(model, &iter)); } void on_tags_selallbtn_clicked(GtkButton *button, gpointer user_data) { tags_select(user_data, TRUE); } void on_tags_selnonebtn_clicked(GtkButton *button, gpointer user_data) { tags_select(user_data, FALSE); } void on_tagsdialog_destroy(GtkObject *object, gpointer user_data) { struct tagdialog_data_t *data; data = user_data; g_hash_table_destroy(data->inconsistent_table); g_free(user_data); } struct tagdialog_data_t *window_tagview_new(GtkWidget *parent, GArray* array) { GtkBuilder *builder; GtkDialog *dialog; GtkTreeView *tagview; GtkButton *selnonebtn; GtkImage *image; GError *error = NULL; struct tagdialog_data_t *data; builder = gtk_builder_new(); if(!gtk_builder_add_from_string(builder, tags_ui_string, -1, &error)) { g_warning("%s", error->message); g_error_free(error); return NULL; } dialog = GTK_DIALOG(gtk_builder_get_object(builder, "tagsdialog")); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent)); gtk_window_set_default_size(GTK_WINDOW(dialog), 300, 300); tagview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "tagview")); selnonebtn = GTK_BUTTON(gtk_builder_get_object(builder, "selnonebtn")); gtk_button_set_label(selnonebtn, "Select None"); image = GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON)); gtk_button_set_image(selnonebtn, GTK_WIDGET(image)); data = g_malloc(sizeof(struct tagdialog_data_t)); data->dialog = GTK_WIDGET(dialog); data->tagview = GTK_WIDGET(tagview); data->wallarray = array; data->inconsistent_table = NULL; tagview_init(tagview, data); gtk_builder_connect_signals(builder, data); return data; }