Manga volumes can be marked 'read'

In the eom-edit-window a list is shown with all the available manga which indicated which ones have been read
This commit is contained in:
Tom Willemsen 2011-01-30 23:42:13 +01:00
parent 64e573c5b6
commit 12c5dd9231
4 changed files with 147 additions and 34 deletions

View file

@ -90,10 +90,10 @@ Manga *data_get_manga_by_id(gint manga_id)
return manga; return manga;
} }
void data_get_volumes_by_manga_id(gint manga_id, gint *size, gint **vols) void data_get_volumes_for_manga(Manga *manga)
{ {
gint count; gint count;
gint *volumes; Volume *volumes;
sqlite3 *database; sqlite3 *database;
sqlite3_stmt *statement; sqlite3_stmt *statement;
gchar *data_file; gchar *data_file;
@ -107,7 +107,7 @@ void data_get_volumes_by_manga_id(gint manga_id, gint *size, gint **vols)
const char *sql = g_strdup_printf( const char *sql = g_strdup_printf(
" SELECT COUNT(id) " " SELECT COUNT(id) "
" FROM volume " " FROM volume "
" WHERE manga_id = %d ", manga_id); " WHERE manga_id = %d ", manga->id);
res = sqlite3_prepare_v2(database, sql, strlen(sql), &statement, NULL); res = sqlite3_prepare_v2(database, sql, strlen(sql), &statement, NULL);
if (res == SQLITE_OK) { if (res == SQLITE_OK) {
@ -117,21 +117,24 @@ void data_get_volumes_by_manga_id(gint manga_id, gint *size, gint **vols)
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);
volumes = (gint *)calloc(sizeof(gint), count); volumes = calloc(sizeof(Volume), count);
if (count > 0) { if (count > 0) {
sql = g_strdup_printf( sql = g_strdup_printf(
" SELECT id " " SELECT id, "
" read "
" FROM volume " " FROM volume "
" WHERE manga_id = %d ", manga_id); " WHERE manga_id = %d ", manga->id);
res = sqlite3_prepare_v2(database, sql, strlen(sql), &statement, NULL); res = sqlite3_prepare_v2(database, sql, strlen(sql), &statement, NULL);
if (res == SQLITE_OK) { if (res == SQLITE_OK) {
gint i = 0; gint i = 0;
while (sqlite3_step(statement) == SQLITE_ROW) { while (sqlite3_step(statement) == SQLITE_ROW) {
gint volume = sqlite3_column_int(statement, 0); volumes[i].number = sqlite3_column_int(statement, 0);
volumes[i++] = volume; volumes[i].read = sqlite3_column_int(statement, 1);
}
i++;
};
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);
@ -140,8 +143,8 @@ void data_get_volumes_by_manga_id(gint manga_id, gint *size, gint **vols)
sqlite3_close(database); sqlite3_close(database);
} }
*size = count; manga->vol_count = count;
*vols = volumes; manga->volumes = volumes;
} }
gboolean data_add_manga(gchar *name, gint total_qty) gboolean data_add_manga(gchar *name, gint total_qty)
@ -215,20 +218,67 @@ gboolean data_add_to_manga(gint manga_id, gint count)
gboolean data_add_volume_to_manga(gint manga_id, gint volume) gboolean data_add_volume_to_manga(gint manga_id, gint volume)
{ {
sqlite3 *database; sqlite3 *database;
sqlite3_stmt *statement; sqlite3_stmt *statement;
gchar *data_file; gchar *data_file;
gboolean result; gboolean result;
data_file = eom_get_data_file(); data_file = eom_get_data_file();
result = FALSE; result = FALSE;
if (data_check_and_create_database(data_file)) { if (data_check_and_create_database(data_file)) {
if (sqlite3_open(data_file, &database) == SQLITE_OK) { if (sqlite3_open(data_file, &database) == SQLITE_OK) {
int res; int res;
const char *sql = g_strdup_printf( const char *sql = g_strdup_printf(
" INSERT INTO volume " " INSERT INTO volume "
" VALUES (%d, %d) ", manga_id, volume); " VALUES (%d, %d, 0) ",
manga_id, volume);
res = sqlite3_prepare_v2(database,
sql,
strlen(sql),
&statement, NULL);
if (res == SQLITE_OK) {
res = sqlite3_step(statement);
if (res == SQLITE_DONE)
result = TRUE;
else
g_print("step did not return DONE, it DID return %d\n", res);
}
else
g_print("res was not OK\n");
sqlite3_finalize(statement);
}
else
g_print("database wasn't opened\n");
sqlite3_close(database);
}
else
g_print("couldn't check or create database\n");
return result;
}
gboolean data_mark_volume_read(int read, gint manga_id, gint volume)
{
sqlite3 *database;
sqlite3_stmt *statement;
gchar *data_file;
gboolean result;
data_file = eom_get_data_file();
result = FALSE;
if (data_check_and_create_database(data_file)) {
if (sqlite3_open(data_file, &database) == SQLITE_OK) {
int res;
const char *sql = g_strdup_printf(
" UPDATE volume "
" SET read = %d "
" WHERE manga_id = %d "
" AND id = %d ",
read, manga_id, volume);
res = sqlite3_prepare_v2(database, res = sqlite3_prepare_v2(database,
sql, sql,
@ -345,12 +395,13 @@ static gint data_create_new_database(const gchar *filename)
/* Create items table */ /* Create items table */
rc = sqlite3_exec(db, rc = sqlite3_exec(db,
" CREATE TABLE volume( " " CREATE TABLE volume( "
" manga_id INTEGER, " " manga_id INTEGER, "
" id INTEGER, " " id INTEGER, "
" read INTEGER, "
" PRIMARY KEY(manga_id, id), " " PRIMARY KEY(manga_id, id), "
" FOREIGN KEY(manga_id) " " FOREIGN KEY(manga_id) "
" REFERENCES manga(id)) ", " REFERENCES manga(id)) ",
NULL, NULL, &zErrMsg); NULL, NULL, &zErrMsg);
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
g_printerr("Can't create volume table: %s\n", zErrMsg); g_printerr("Can't create volume table: %s\n", zErrMsg);
@ -372,6 +423,8 @@ static Manga *data_get_manga_from_statement(sqlite3_stmt *stmt)
manga->name = g_strdup(sqlite3_column_text(stmt, 1)); manga->name = g_strdup(sqlite3_column_text(stmt, 1));
manga->current_qty = sqlite3_column_int(stmt, 2); manga->current_qty = sqlite3_column_int(stmt, 2);
manga->total_qty = sqlite3_column_int(stmt, 3); manga->total_qty = sqlite3_column_int(stmt, 3);
manga->volumes = NULL;
manga->vol_count = 0;
return manga; return manga;
} }

View file

@ -3,22 +3,33 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
typedef struct _volume Volume;
struct _volume
{
int number;
int read;
};
typedef struct _manga Manga; typedef struct _manga Manga;
struct _manga struct _manga
{ {
int id; int id;
int current_qty; int current_qty;
int total_qty; int total_qty;
char *name; char *name;
int vol_count;
Volume *volumes;
}; };
GList *data_get_manga(void); GList *data_get_manga(void);
Manga *data_get_manga_by_id(gint manga_id); Manga *data_get_manga_by_id(gint manga_id);
void data_get_volumes_by_manga_id(gint manga_id, gint *size, gint **vols); void data_get_volumes_for_manga(Manga *manga);
gboolean data_add_manga(gchar *name, gint total_qty); gboolean data_add_manga(gchar *name, gint total_qty);
gboolean data_add_to_manga(gint id, gint count); gboolean data_add_to_manga(gint id, gint count);
gboolean data_add_volume_to_manga(gint manga_id, gint volume); gboolean data_add_volume_to_manga(gint manga_id, gint volume);
gboolean data_mark_volume_read(gint read, gint manga_id, gint volume);
gboolean data_remove_volume_from_manga(gint manga_id, gint volume); gboolean data_remove_volume_from_manga(gint manga_id, gint volume);
#endif /* __DATA_H__ */ #endif /* __DATA_H__ */

View file

@ -14,6 +14,9 @@ static void eom_edit_window_set_manga_id(EomEditWindow *self,
gint manga_id); gint manga_id);
static void eom_edit_window_on_volume_toggled(GtkToggleButton *togglebutton, static void eom_edit_window_on_volume_toggled(GtkToggleButton *togglebutton,
gpointer user_data); gpointer user_data);
static void
eom_edit_window_on_volume_read_toggled(GtkToggleButton *togglebutton,
gpointer user_data);
G_DEFINE_TYPE(EomEditWindow, eom_edit_window, HILDON_TYPE_STACKABLE_WINDOW) G_DEFINE_TYPE(EomEditWindow, eom_edit_window, HILDON_TYPE_STACKABLE_WINDOW)
@ -106,31 +109,37 @@ static void eom_edit_window_init(EomEditWindow *self)
hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannablearea), hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(pannablearea),
table); table);
/* Label for the name field */
nameclabel = gtk_label_new("Name:"); nameclabel = gtk_label_new("Name:");
gtk_misc_set_alignment(GTK_MISC(nameclabel), 0.0, 0.5); gtk_misc_set_alignment(GTK_MISC(nameclabel), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), nameclabel, 0, 1, 0, 1, gtk_table_attach(GTK_TABLE(table), nameclabel, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
/* The name field */
self->name_entry = hildon_entry_new(HILDON_SIZE_AUTO); self->name_entry = hildon_entry_new(HILDON_SIZE_AUTO);
gtk_entry_set_alignment(GTK_ENTRY(self->name_entry), 1.0); gtk_entry_set_alignment(GTK_ENTRY(self->name_entry), 1.0);
gtk_table_attach(GTK_TABLE(table), self->name_entry, 1, 2, 0, 1, gtk_table_attach(GTK_TABLE(table), self->name_entry, 1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
/* Label for the collected field */
haveclabel = gtk_label_new("You have:"); haveclabel = gtk_label_new("You have:");
gtk_misc_set_alignment(GTK_MISC(haveclabel), 0.0, 0.5); gtk_misc_set_alignment(GTK_MISC(haveclabel), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), haveclabel, 0, 1, 1, 2, gtk_table_attach(GTK_TABLE(table), haveclabel, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
/* The collected field */
self->have_label = gtk_label_new(""); self->have_label = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(self->have_label), 1.0, 0.5); gtk_misc_set_alignment(GTK_MISC(self->have_label), 1.0, 0.5);
gtk_table_attach(GTK_TABLE(table), self->have_label, 1, 2, 1, 2, gtk_table_attach(GTK_TABLE(table), self->have_label, 1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
/* Label for the total field */
totalclabel = gtk_label_new("There are:"); totalclabel = gtk_label_new("There are:");
gtk_misc_set_alignment(GTK_MISC(totalclabel), 0.0, 0.5); gtk_misc_set_alignment(GTK_MISC(totalclabel), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), totalclabel, 0, 1, 2, 3, gtk_table_attach(GTK_TABLE(table), totalclabel, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
/* The total field */
self->total_entry = hildon_entry_new(HILDON_SIZE_AUTO); self->total_entry = hildon_entry_new(HILDON_SIZE_AUTO);
gtk_entry_set_alignment(GTK_ENTRY(self->total_entry), 1.0); gtk_entry_set_alignment(GTK_ENTRY(self->total_entry), 1.0);
gtk_table_attach(GTK_TABLE(table), self->total_entry, 1, 2, 2, 3, gtk_table_attach(GTK_TABLE(table), self->total_entry, 1, 2, 2, 3,
@ -141,17 +150,17 @@ static void eom_edit_window_init(EomEditWindow *self)
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
} }
static void eom_edit_window_set_manga_id(EomEditWindow *self, static void eom_edit_window_set_manga_id(EomEditWindow *self, gint manga_id)
gint manga_id)
{ {
Manga *manga; Manga *manga;
gint *volumes;
gint num_vols;
gint i; gint i;
gint j = 0; gint j = 0;
GtkWidget *clabel;
GtkWidget *tlabel;
GtkWidget *buttonbox;
manga = data_get_manga_by_id(manga_id); manga = data_get_manga_by_id(manga_id);
data_get_volumes_by_manga_id(manga_id, &num_vols, &volumes); data_get_volumes_for_manga(manga);
self->current_manga = manga; self->current_manga = manga;
@ -161,19 +170,36 @@ static void eom_edit_window_set_manga_id(EomEditWindow *self,
gtk_entry_set_text(GTK_ENTRY(self->total_entry), gtk_entry_set_text(GTK_ENTRY(self->total_entry),
g_strdup_printf("%d", manga->total_qty)); g_strdup_printf("%d", manga->total_qty));
/* TODO: Create labels for collected and read lists */
for (i = 0; i < manga->total_qty; i++) { for (i = 0; i < manga->total_qty; i++) {
GtkWidget *button; GtkWidget *button;
GtkWidget *read_button;
buttonbox = gtk_hbox_new(TRUE, 2);
gtk_box_pack_start(GTK_BOX(self->volumes_box), buttonbox, TRUE, TRUE, 0);
/* Button indicating collected state */
button = gtk_toggle_button_new_with_label(g_strdup_printf("%d", i + 1)); button = gtk_toggle_button_new_with_label(g_strdup_printf("%d", i + 1));
gtk_box_pack_start(GTK_BOX(self->volumes_box), button, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(buttonbox), button, TRUE, TRUE, 0);
if (j < num_vols && volumes[j] == i+1) { /* Button indicating read state */
read_button =
gtk_toggle_button_new_with_label(g_strdup_printf("%d", i + 1));
gtk_box_pack_start(GTK_BOX(buttonbox), read_button, TRUE, TRUE, 0);
if (j < manga->vol_count && manga->volumes[j].number == i+1) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
if (manga->volumes[j].read)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(read_button), TRUE);
j++; j++;
} }
g_signal_connect(button, "toggled", g_signal_connect(button, "toggled",
G_CALLBACK(eom_edit_window_on_volume_toggled), G_CALLBACK(eom_edit_window_on_volume_toggled),
(gpointer)self); (gpointer)self);
g_signal_connect(read_button, "toggled",
G_CALLBACK(eom_edit_window_on_volume_read_toggled),
(gpointer)self);
} }
} }
@ -190,6 +216,7 @@ static void eom_edit_window_on_volume_toggled(GtkToggleButton *togglebutton,
volume = atoi(gtk_button_get_label(GTK_BUTTON(togglebutton))); volume = atoi(gtk_button_get_label(GTK_BUTTON(togglebutton)));
if (active) { if (active) {
/* Add 1 to mangas collected */
if (!data_add_to_manga(self->current_manga->id, 1)) { if (!data_add_to_manga(self->current_manga->id, 1)) {
return; return;
} }
@ -200,6 +227,7 @@ static void eom_edit_window_on_volume_toggled(GtkToggleButton *togglebutton,
self->current_manga->current_qty++; self->current_manga->current_qty++;
} }
else { else {
/* Remove 1 from mangas collected */
if (!data_add_to_manga(self->current_manga->id, -1)) { if (!data_add_to_manga(self->current_manga->id, -1)) {
return; return;
} }
@ -213,3 +241,19 @@ static void eom_edit_window_on_volume_toggled(GtkToggleButton *togglebutton,
gtk_label_set_text(GTK_LABEL(self->have_label), gtk_label_set_text(GTK_LABEL(self->have_label),
g_strdup_printf("%d", self->current_manga->current_qty)); g_strdup_printf("%d", self->current_manga->current_qty));
} }
static void
eom_edit_window_on_volume_read_toggled(GtkToggleButton *togglebutton,
gpointer user_data)
{
EomEditWindow *self;
gboolean active;
gint volume;
self = (EomEditWindow *)user_data;
active = gtk_toggle_button_get_active(togglebutton);
volume = atoi(gtk_button_get_label(GTK_BUTTON(togglebutton)));
if (!data_mark_volume_read(active, self->current_manga->id, volume))
g_print("coulnd't mark volume as read\n");
}

View file

@ -39,6 +39,7 @@ GtkWidget *eom_main_window_new(void)
void eom_main_window_load(EomMainWindow *self) void eom_main_window_load(EomMainWindow *self)
{ {
GList *list; GList *list;
int i;
gtk_list_store_clear(self->store); gtk_list_store_clear(self->store);
@ -50,6 +51,10 @@ void eom_main_window_load(EomMainWindow *self)
manga->current_qty, manga->total_qty); manga->current_qty, manga->total_qty);
free(manga->name); free(manga->name);
if (manga->volumes != NULL) {
for (i = 0; i < manga->vol_count; i++)
free(manga->volumes + i);
}
free(manga); free(manga);
list = g_list_next(list); list = g_list_next(list);
} }