From 15c7c143680175d37419d36b271b17d49a0991e3 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Wed, 24 Oct 2012 00:01:06 +0200 Subject: [PATCH] Add updating of data for manga The title and total numbers can now be changed. * src/data.c (data_add_manga): Change `name' to `const gchar*', we're not changing it. (data_update_manga): New function, updates a manga's information. * src/eom-detail-window.c (eom_detail_window_load): New function, prepares the tables to show the right data. (add_menu): New function, adds a menu to the window. (eom_detail_window_init): Call `add_menu' and prepare the other widgets for showing. (on_edit): New function, opens an edit dialog and reloads the screen afterwards. (set_manga_id): Move data filling to `eom_detail_window_load' and widget preparation to `eom_detail_window_init' and call `eom_detail_window_load'. * src/eom-detail-window.h (EomDetailWindow): Add `ctable' and `rtable' members, these are the tables that show the data. * src/eom-main-window.c (on_new): No need to save and copy the name of a manga, just destroy the widget later and destroy it always. * src/eom-new-item-dialog.c (eom_new_item_dialog_class_init): Add write-only `manga-id' property. (EOM_NEW_PROP_MID): New enum. (finalize): New function. Free the associated manga. (get_property): New function. Get a property, has no properties to get for now. (set_manga_id): New function. Show a manga's information in the entries. (set_property): New function. Set a property. Calls `set_manga_id' for the `manga-id' property. * src/eom-new-item-dialog.h (EomNewItemDialog): Add a `Manga' as member. --- src/data.c | 15 +++- src/data.h | 3 +- src/eom-detail-window.c | 172 +++++++++++++++++++++++++------------- src/eom-detail-window.h | 3 + src/eom-main-window.c | 14 +--- src/eom-new-item-dialog.c | 79 ++++++++++++++++- src/eom-new-item-dialog.h | 4 + 7 files changed, 220 insertions(+), 70 deletions(-) diff --git a/src/data.c b/src/data.c index e357f2e..94e4735 100644 --- a/src/data.c +++ b/src/data.c @@ -17,7 +17,7 @@ static GList *get_manga_for_query(const gchar*); static Manga *get_manga_from_statement(sqlite3_stmt*); gboolean -data_add_manga(gchar *name, gint total_qty) +data_add_manga(const gchar *name, gint total_qty) { gchar *sql = g_strdup_printf(" INSERT INTO manga (name, current_qty, " @@ -217,6 +217,19 @@ data_remove_volume_from_manga(gint manga_id, gint volume) return ret; } +gboolean +data_update_manga(gint manga_id, const gchar *name, gint total_qty) +{ + gchar *sql = + g_strdup_printf("UPDATE manga SET name = '%s', total_qty = %d " + "WHERE id = %d", name, total_qty, manga_id); + gboolean ret = execute_non_query(sql); + + g_free(sql); + + return ret; +} + static gboolean check_and_create_database(gchar *data_file) { diff --git a/src/data.h b/src/data.h index b34e2aa..9dbf5e6 100644 --- a/src/data.h +++ b/src/data.h @@ -19,7 +19,7 @@ typedef struct Volume *volumes; } Manga; -gboolean data_add_manga(gchar*, gint); +gboolean data_add_manga(const gchar*, gint); gboolean data_add_to_manga(gint, gint); gboolean data_add_volume_to_manga(gint, gint); GList *data_get_incomplete_manga(void); @@ -28,5 +28,6 @@ Manga *data_get_manga_by_id(gint); void data_get_volumes_for_manga(Manga*); gboolean data_mark_volume_read(gint, gint, gint); gboolean data_remove_volume_from_manga(gint, gint); +gboolean data_update_manga(gint, const gchar*, gint); #endif /* __DATA_H__ */ diff --git a/src/eom-detail-window.c b/src/eom-detail-window.c index ed8016b..2af6f8a 100644 --- a/src/eom-detail-window.c +++ b/src/eom-detail-window.c @@ -7,6 +7,8 @@ #include "data.h" #include "eom-main-window.h" +#include "eom-new-item-dialog.h" +#include "interface.h" #define COLUMNS 8 @@ -15,18 +17,69 @@ enum { EOM_EDIT_PROP_CID }; +static void add_menu(EomDetailWindow*); static GtkWidget *create_volume_button(gchar*, GtkTable*, int, int); static void eom_detail_window_class_init(EomDetailWindowClass*); static void eom_detail_window_init(EomDetailWindow *self); static void finalize(GObject*); static void get_property(GObject*, guint, GValue*, GParamSpec*); +static void on_edit(GtkWidget*, EomDetailWindow*); static void on_volume_read_toggled(GtkToggleButton*, gpointer); static void on_volume_toggled(GtkToggleButton*, gpointer); static void set_manga_id(EomDetailWindow*, gint); static void set_property(GObject*, guint, const GValue*, GParamSpec*); G_DEFINE_TYPE(EomDetailWindow, eom_detail_window, - HILDON_TYPE_STACKABLE_WINDOW) + HILDON_TYPE_STACKABLE_WINDOW); + +void +eom_detail_window_load(EomDetailWindow *self) +{ + gint i, j = 0, row = 0, col = 0; + int rows = (int)floor(self->manga->total_qty / COLUMNS); + + gtk_window_set_title(GTK_WINDOW(self), self->manga->name); + gtk_table_resize(GTK_TABLE(self->ctable), rows, COLUMNS); + gtk_table_resize(GTK_TABLE(self->rtable), rows, COLUMNS); + + for (i = 0; i < self->manga->total_qty; i++) { + GtkWidget *cbtn, *rbtn; + gchar *txt; + + if (i > 0 && i % COLUMNS == 0) { + row++; + col = 0; + } + + txt = g_strdup_printf("%d", i + 1); + cbtn = create_volume_button(txt, GTK_TABLE(self->ctable), col, + row); + rbtn = create_volume_button(txt, GTK_TABLE(self->rtable), col, + row); + + if (j < self->manga->vol_count + && self->manga->volumes[j].number == i + 1) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbtn), TRUE); + + if (self->manga->volumes[j].read) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rbtn), + TRUE); + + j++; + } + + g_signal_connect(cbtn, "toggled", G_CALLBACK(on_volume_toggled), + (gpointer)self); + g_signal_connect(rbtn, "toggled", + G_CALLBACK(on_volume_read_toggled), + (gpointer)self); + + g_free(txt); + col++; + } + + gtk_widget_show_all(self->volsbox); +} GtkWidget * eom_detail_window_new(gint manga_id) @@ -36,6 +89,24 @@ eom_detail_window_new(gint manga_id) NULL); } +static void +add_menu(EomDetailWindow *window) +{ + HildonAppMenu *appmenu; + GtkWidget *edit_button; + + appmenu = HILDON_APP_MENU(hildon_app_menu_new()); + + edit_button = hildon_gtk_button_new(HILDON_SIZE_AUTO); + gtk_button_set_label(GTK_BUTTON(edit_button), "Edit..."); + g_signal_connect_after(edit_button, "clicked", G_CALLBACK(on_edit), + window); + hildon_app_menu_append(appmenu, GTK_BUTTON(edit_button)); + gtk_widget_show_all(GTK_WIDGET(appmenu)); + hildon_stackable_window_set_main_menu(HILDON_STACKABLE_WINDOW(window), + HILDON_APP_MENU(appmenu)); +} + static GtkWidget * create_volume_button(gchar* text, GtkTable* table, int column, int row) { @@ -58,7 +129,7 @@ static void eom_detail_window_class_init(EomDetailWindowClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - GParamSpec *pspec; + GParamSpec *pspec; gobject_class->set_property = set_property; gobject_class->get_property = get_property; @@ -75,6 +146,9 @@ static void eom_detail_window_init(EomDetailWindow *self) { GtkWidget *panarea; + GtkWidget *clabel, *rlabel; + + add_menu(self); panarea = hildon_pannable_area_new(); g_object_set(G_OBJECT(panarea), @@ -86,6 +160,19 @@ eom_detail_window_init(EomDetailWindow *self) hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(panarea), self->volsbox); + clabel = gtk_label_new("Collected:"); + gtk_misc_set_alignment(GTK_MISC(clabel), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(self->volsbox), clabel, FALSE, FALSE, 0); + + self->ctable = gtk_table_new(0, 0, TRUE); + gtk_box_pack_start(GTK_BOX(self->volsbox), self->ctable, FALSE, FALSE, 0); + + rlabel = gtk_label_new("Read:"); + gtk_misc_set_alignment(GTK_MISC(rlabel), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(self->volsbox), rlabel, FALSE, FALSE, 0); + + self->rtable = gtk_table_new(0, 0, TRUE); + gtk_box_pack_start(GTK_BOX(self->volsbox), self->rtable, FALSE, FALSE, 0); } static void @@ -114,6 +201,32 @@ get_property(GObject *object, guint property_id, GValue *value, } } +static void +on_edit(GtkWidget *widget, EomDetailWindow *self) +{ + GtkWidget *dialog; + gint result; + const gchar *name = NULL; + gint total_qty; + + dialog = interface_show_new_item_dialog(GTK_WINDOW(self)); + g_object_set(G_OBJECT(dialog), "manga-id", self->manga->id, NULL); + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + + if (result == GTK_RESPONSE_OK) { + name = eom_new_item_dialog_get_name(EOM_NEW_ITEM_DIALOG(dialog)); + total_qty = eom_new_item_dialog_get_total_qty(EOM_NEW_ITEM_DIALOG(dialog)); + } + + if (name != NULL) { + if (data_update_manga(self->manga->id, name, total_qty)) + set_manga_id(self, self->manga->id); + } + + gtk_widget_destroy(dialog); +} + static void on_volume_read_toggled(GtkToggleButton *togglebutton, gpointer user_data) { @@ -160,66 +273,13 @@ on_volume_toggled(GtkToggleButton *togglebutton, gpointer user_data) static void set_manga_id(EomDetailWindow *self, gint manga_id) { - GtkWidget *clabel, *rlabel; - GtkWidget *ctable, *rtable; Manga *manga; - gint i, j = 0, row = 0, col = 0; manga = data_get_manga_by_id(manga_id); data_get_volumes_for_manga(manga); self->manga = manga; - gtk_window_set_title(GTK_WINDOW(self), manga->name); - - clabel = gtk_label_new("Collected:"); - gtk_misc_set_alignment(GTK_MISC(clabel), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(self->volsbox), clabel, FALSE, FALSE, 0); - - ctable = gtk_table_new((int)floor(manga->total_qty / COLUMNS), - COLUMNS, TRUE); - gtk_box_pack_start(GTK_BOX(self->volsbox), ctable, FALSE, FALSE, 0); - - rlabel = gtk_label_new("Read:"); - gtk_misc_set_alignment(GTK_MISC(rlabel), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(self->volsbox), rlabel, FALSE, FALSE, 0); - - rtable = gtk_table_new((int)floor(manga->total_qty / COLUMNS), - COLUMNS, TRUE); - gtk_box_pack_start(GTK_BOX(self->volsbox), rtable, FALSE, FALSE, 0); - - for (i = 0; i < manga->total_qty; i++) { - GtkWidget *cbtn, *rbtn; - gchar *txt; - - if (i > 0 && i % COLUMNS == 0) { - row++; - col = 0; - } - - txt = g_strdup_printf("%d", i + 1); - - cbtn = create_volume_button(txt, GTK_TABLE(ctable), col, row); - rbtn = create_volume_button(txt, GTK_TABLE(rtable), col, row); - - if (j < manga->vol_count && manga->volumes[j].number == i + 1) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbtn), TRUE); - - if (manga->volumes[j].read) - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rbtn), - TRUE); - - j++; - } - - g_signal_connect(cbtn, "toggled", G_CALLBACK(on_volume_toggled), - (gpointer)self); - g_signal_connect(rbtn, "toggled", - G_CALLBACK(on_volume_read_toggled), - (gpointer)self); - - g_free(txt); - col++; - } + eom_detail_window_load(self); } static void diff --git a/src/eom-detail-window.h b/src/eom-detail-window.h index f08362d..89746f3 100644 --- a/src/eom-detail-window.h +++ b/src/eom-detail-window.h @@ -42,10 +42,13 @@ typedef struct { HildonStackableWindow parent; GtkWidget *volsbox; + GtkWidget *ctable; + GtkWidget *rtable; Manga *manga; } EomDetailWindow; GType eom_detail_window_get_type(void); +void eom_detail_window_load(EomDetailWindow*); GtkWidget *eom_detail_window_new(gint); G_END_DECLS diff --git a/src/eom-main-window.c b/src/eom-main-window.c index 67d0429..f943e9f 100644 --- a/src/eom-main-window.c +++ b/src/eom-main-window.c @@ -233,29 +233,23 @@ on_new(GtkWidget *widget, GtkWindow *window) { GtkWidget *dialog; gint result; - gchar *name = NULL; + const gchar *name = NULL; gint total_qty; dialog = interface_show_new_item_dialog(window); result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_OK) { - const gchar *tmp; - tmp = eom_new_item_dialog_get_name(EOM_NEW_ITEM_DIALOG(dialog)); - name = (gchar *)malloc(strlen(tmp) + 1); - - strcpy(name, tmp); - strcat(name, "\0"); - + name = eom_new_item_dialog_get_name(EOM_NEW_ITEM_DIALOG(dialog)); total_qty = eom_new_item_dialog_get_total_qty(EOM_NEW_ITEM_DIALOG(dialog)); - - gtk_widget_destroy(dialog); } if (name != NULL) { if (data_add_manga(name, total_qty)) eom_main_window_load(EOM_MAIN_WINDOW(window)); } + + gtk_widget_destroy(dialog); } static void diff --git a/src/eom-new-item-dialog.c b/src/eom-new-item-dialog.c index e7d5052..1f53513 100644 --- a/src/eom-new-item-dialog.c +++ b/src/eom-new-item-dialog.c @@ -4,8 +4,18 @@ #include #include +#include "data.h" + +enum { + EOM_NEW_PROP_MID = 1 +}; + static void eom_new_item_dialog_class_init(EomNewItemDialogClass*); static void eom_new_item_dialog_init(EomNewItemDialog*); +static void finalize(GObject*); +static void get_property(GObject*, guint, GValue*, GParamSpec*); +static void set_manga_id(EomNewItemDialog*, gint); +static void set_property(GObject*, guint, const GValue*, GParamSpec*); G_DEFINE_TYPE(EomNewItemDialog, eom_new_item_dialog, GTK_TYPE_DIALOG) @@ -28,8 +38,21 @@ eom_new_item_dialog_new(void) } static void -eom_new_item_dialog_class_init(EomNewItemDialogClass *class) -{} +eom_new_item_dialog_class_init(EomNewItemDialogClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + gobject_class->set_property = set_property; + gobject_class->get_property = get_property; + gobject_class->finalize = finalize; + pspec = g_param_spec_int("manga-id", "ID of the manga", + "Set the manga-id", 0, INT_MAX, 0, + G_PARAM_WRITABLE); + + g_object_class_install_property(gobject_class, EOM_NEW_PROP_MID, + pspec); +} static void eom_new_item_dialog_init(EomNewItemDialog *dialog) @@ -58,3 +81,55 @@ eom_new_item_dialog_init(EomNewItemDialog *dialog) GTK_RESPONSE_OK, NULL); } + +static void +finalize(GObject *object) +{ + EomNewItemDialog *self = EOM_NEW_ITEM_DIALOG(object); + + g_free(self->manga); + + G_OBJECT_CLASS(eom_new_item_dialog_parent_class)->finalize(object); +} + +static void +get_property(GObject *object, guint property_id, GValue *value, + GParamSpec *pspec) +{ + EomNewItemDialog *self = EOM_NEW_ITEM_DIALOG(object); + + switch(property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void +set_manga_id(EomNewItemDialog *self, gint manga_id) +{ + Manga *manga = data_get_manga_by_id(manga_id); + gchar *txt; + self->manga = manga; + txt = g_strdup_printf("%d", manga->total_qty); + + gtk_entry_set_text(GTK_ENTRY(self->name_entry), manga->name); + gtk_entry_set_text(GTK_ENTRY(self->qty_entry), txt); + + g_free(txt); +} + +static void +set_property(GObject *object, guint property_id, const GValue *value, + GParamSpec *pspec) +{ + EomNewItemDialog *self = EOM_NEW_ITEM_DIALOG(object); + gint manga_id = g_value_get_int(value); + + switch (property_id) { + case EOM_NEW_PROP_MID: + set_manga_id(self, manga_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} diff --git a/src/eom-new-item-dialog.h b/src/eom-new-item-dialog.h index 5e74204..97528a0 100644 --- a/src/eom-new-item-dialog.h +++ b/src/eom-new-item-dialog.h @@ -3,6 +3,8 @@ #include +#include "data.h" + G_BEGIN_DECLS #define EOM_TYPE_NEW_ITEM_DIALOG \ @@ -42,6 +44,8 @@ typedef struct GtkWidget *name_entry; GtkWidget *qty_entry; + + Manga *manga; } EomNewItemDialog; const gchar *eom_new_item_dialog_get_name(EomNewItemDialog*);