diff options
-rw-r--r-- | db.c | 77 | ||||
-rw-r--r-- | db.h | 1 | ||||
-rw-r--r-- | thumbnails.c | 2 | ||||
-rw-r--r-- | walls.ui | 20 | ||||
-rw-r--r-- | window_main.c | 144 |
5 files changed, 239 insertions, 5 deletions
@@ -402,6 +402,83 @@ int db_get_wallpapers(sqlite_uint64 dirid, GArray **array) { return 1; } +static gchar *gen_joinstring(int c) { + char **split, *join; + + split = g_malloc(sizeof(gchar*) * (c+1)); + split[c] = NULL; + + for(int i = 0; i < c; i++) { + split[i] = "?"; + } + + join = g_strjoinv(", ", split); + + g_free(split); + + return join; +} + +/* + * tags = uint64 + * walls = struct tag_t * + */ +int db_get_walls_by_tags(GArray *tags, GArray **array) { + sqlite3_stmt *stmt; + int rc; + char *join, *query; + struct wallpaper_t temp, *temp2; + + join = gen_joinstring(tags->len); + query = g_strdup_printf("SELECT w.id, w.filepath, w.size, w.width, w.height " + "FROM wallpaper w JOIN walltags t ON (t.wallid = w.id) WHERE t.tagid IN (%s)", + join); + g_free(join); + + rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); + + g_free(query); + + if(rc != SQLITE_OK) { + return 0; + } + + for(int i = 0; i < tags->len; i++) { + sqlite_uint64 id; + + id = g_array_index(tags, sqlite_uint64, i); + rc = sqlite3_bind_int64(stmt, i + 1, id); + + if(rc != SQLITE_OK) { + sqlite3_finalize(stmt); + return 0; + } + } + + *array = g_array_new(FALSE, FALSE, sizeof(struct wallpaper_t)); + while((rc = sqlite3_step(stmt)) == SQLITE_ROW) { + temp.filepath = g_strdup(sqlite3_column_text(stmt, 1)); + temp.id = sqlite3_column_int64(stmt, 0); + temp.size = sqlite3_column_int(stmt, 2); + temp.width = sqlite3_column_int(stmt, 3); + temp.height = sqlite3_column_int(stmt, 4); + g_array_append_val(*array, temp); + } + + sqlite3_finalize(stmt); + + if(rc != SQLITE_DONE) { + for(int i = 0; i < (*array)->len; i++) { + temp2 = &g_array_index(*array, struct wallpaper_t, i); + g_free(temp2->filepath); + } + g_array_free(*array, TRUE); + return 0; + } + + return 1; +} + sqlite_uint64 db_add_tag(const char *name) { sqlite3_stmt *stmt; int rc; @@ -33,6 +33,7 @@ sqlite_uint64 db_get_wallpaper(const char*); int db_get_wallpaper_data(sqlite_uint64, struct wallpaper_t*); int db_get_wall_tags(sqlite_uint64, GArray**); int db_get_wallpapers(sqlite_uint64, GArray**); +int db_get_walls_by_tags(GArray*, GArray**); sqlite_uint64 db_add_tag(const char*); int db_get_tags_all(GArray**); int db_add_wall_tag(sqlite_uint64, sqlite_uint64); diff --git a/thumbnails.c b/thumbnails.c index 003120e..0bffcf5 100644 --- a/thumbnails.c +++ b/thumbnails.c @@ -73,7 +73,7 @@ GdkPixbuf *get_thumbnail(const gchar *filepath) { if(!pb) { g_warning("%s", error->message); - g_free(error); + g_error_free(error); g_free(thumbname); return NULL; } @@ -95,6 +95,7 @@ <object class="GtkNotebook" id="left_pages"> <property name="visible">True</property> <property name="can_focus">True</property> + <signal name="switch_page" handler="on_left_pages_switch_page"/> <child> <object class="GtkScrolledWindow" id="filtree_scroller"> <property name="visible">True</property> @@ -118,6 +119,25 @@ <property name="tab_fill">False</property> </packing> </child> + <child> + <object class="GtkTreeView" id="tagview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="label" translatable="yes">Tags</property> + </object> + <packing> + <property name="position">1</property> + <property name="tab_fill">False</property> + </packing> + </child> </object> <packing> <property name="resize">False</property> diff --git a/window_main.c b/window_main.c index a78a6fa..5183c57 100644 --- a/window_main.c +++ b/window_main.c @@ -7,7 +7,6 @@ #include "walls_ui.h" #include "db.h" #include "browse_model.h" -#include "walls_model.h" #include "wallpapers.h" #include "thumbnails.h" #include "walls_conf.h" @@ -25,7 +24,7 @@ GtkImage *image = NULL; GtkWidget *layout = NULL; GtkStatusbar *statusbar; GtkIconView *thumbview; -GtkWidget *window_hpane, *window_vpane; +GtkWidget *window_hpane, *window_vpane, *foldtree, *tagview; GThread *add_thread = NULL, *thumb_thread = NULL; @@ -35,6 +34,7 @@ gchar *cur_wall_msg = NULL; guint image_context; void on_foldtree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data); +void on_main_tagview_cell_toggled(GtkCellRendererToggle *cell_renderer, gchar *path_string, gpointer user_data); inline static void foldtree_create_model(GtkTreeView *foldtree) { GtkTreeModel *tree_model; @@ -62,6 +62,52 @@ inline static void foldtree_init(GtkTreeView *foldtree) { g_signal_connect(selection, "changed", G_CALLBACK(on_foldtree_selection_changed), foldtree); } +inline static void tagview_create_model(GtkTreeView *tagview) { + GtkListStore *model; + GArray *array; + struct tag_t *tag; + GtkTreeIter iter; + + model = gtk_list_store_new(3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_UINT64); + + if(db_get_tags_all(&array)) { + for(int i = 0; i < array->len; i++) { + tag = &g_array_index(array, struct tag_t, i); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, 0, FALSE, 1, g_strdup(tag->name), 2, tag->id, -1); + g_free(tag->name); + } + g_array_free(array, TRUE); + } + + gtk_tree_view_set_model(tagview, GTK_TREE_MODEL(model)); +} + +inline static void tagview_init(GtkTreeView *tagview) { + GtkTreeViewColumn *col1, *col2; + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + + col1 = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col1, "Show"); + 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); + g_signal_connect(renderer, "toggled", G_CALLBACK(on_main_tagview_cell_toggled), tagview); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_end(col2, renderer, TRUE); + gtk_tree_view_column_add_attribute(col2, renderer, "text", 1); + + tagview_create_model(tagview); +} + static void set_resize_msg(gdouble scale) { gchar *msg; @@ -223,7 +269,7 @@ static void fill_wall_list(GtkListStore *liststore, GArray *array) { g_array_free(array, TRUE); } -void on_foldtree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data) { +static void display_from_foldtree(GtkTreeSelection *treeselection) { GtkTreeModel *model; GtkTreeIter iter; struct directory_t *dir; @@ -231,6 +277,9 @@ void on_foldtree_selection_changed(GtkTreeSelection *treeselection, gpointer use GtkListStore *liststore; GError *error = NULL; + if(treeselection == NULL) + treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(foldtree)); + if(gtk_tree_selection_get_selected(treeselection, &model, &iter)) { browse_model_get_dir_record(model, &iter, &dir); @@ -250,6 +299,11 @@ void on_foldtree_selection_changed(GtkTreeSelection *treeselection, gpointer use } } + +void on_foldtree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data) { + display_from_foldtree(treeselection); +} + void on_thumbview_selection_changed(GtkIconView *iconview, gpointer user_data) { GList *list; GValue value; @@ -276,6 +330,75 @@ void on_thumbview_selection_changed(GtkIconView *iconview, gpointer user_data) { } } + +void display_from_tagview() { + GtkTreeIter iter; + GtkTreeModel *model; + GtkListStore *liststore; + GValue value = {0}; + gboolean active; + GArray *tagarray, *wallarray; + guint64 id; + GError *error = NULL; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tagview)); + + if(!gtk_tree_model_get_iter_first(model, &iter)) + return; + + tagarray = g_array_new(FALSE, FALSE, sizeof(guint64)); + + do { + gtk_tree_model_get_value(model, &iter, 0, &value); + active = g_value_get_boolean(&value); + g_value_unset(&value); + + if(!active) + continue; + + gtk_tree_model_get_value(model, &iter, 2, &value); + id = g_value_get_uint64(&value); + g_value_unset(&value); + + g_array_append_val(tagarray, id); + } while(gtk_tree_model_iter_next(model, &iter)); + + if(!db_get_walls_by_tags(tagarray, &wallarray)) { + g_array_free(tagarray, TRUE); + g_warning("Could not fetch walls by tags\n"); + return; + } + + liststore = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_UINT64); + fill_wall_list(liststore, wallarray); + gtk_icon_view_set_model(thumbview, GTK_TREE_MODEL(liststore)); + + thumb_thread = g_thread_create(add_thumbs_thread, liststore, FALSE, &error); + + if(!thumb_thread) { + g_warning("%s\n", error->message); + g_error_free(error); + } +} + +void on_main_tagview_cell_toggled(GtkCellRendererToggle *cell_renderer, gchar *path_string, gpointer user_data) { + GtkTreeIter iter; + GtkTreeModel *model; + GValue value = {0}; + gboolean active; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tagview)); + + gtk_tree_model_get_iter_from_string(model, &iter, path_string); + gtk_tree_model_get_value(model, &iter, 0, &value); + active = g_value_get_boolean(&value); + g_value_unset(&value); + + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, !active, -1); + + display_from_tagview(); +} + gpointer add_dir_thread(gpointer data) { gchar *directory; @@ -433,6 +556,17 @@ gboolean on_thumbview_button_press_event(GtkWidget *widget, GdkEventButton *even return FALSE; } +gboolean on_left_pages_switch_page(GtkNotebook *notebook, GtkNotebookTab page, guint page_num, gpointer user_data) { + switch(page_num) { + case 0: + display_from_foldtree(NULL); + break; + case 1: + display_from_tagview(); + break; + } +} + static void save_window() { gint width, height; @@ -464,7 +598,6 @@ static void set_sizes() { } int gui_main(int argc, char **argv) { - GtkWidget *foldtree; GtkBuilder *builder ; GError *error = NULL; GdkColor color; @@ -492,6 +625,9 @@ int gui_main(int argc, char **argv) { foldtree = GTK_WIDGET(gtk_builder_get_object(builder, "foldtree")); foldtree_init(GTK_TREE_VIEW(foldtree)); + tagview = GTK_WIDGET(gtk_builder_get_object(builder, "tagview")); + tagview_init(GTK_TREE_VIEW(tagview)); + thumbview = GTK_ICON_VIEW(gtk_builder_get_object(builder, "thumbview")); gtk_icon_view_set_pixbuf_column(thumbview, 0); |