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:
parent
64e573c5b6
commit
12c5dd9231
4 changed files with 147 additions and 34 deletions
77
src/data.c
77
src/data.c
|
@ -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)
|
||||||
|
@ -228,7 +231,54 @@ gboolean data_add_volume_to_manga(gint manga_id, gint volume)
|
||||||
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,
|
||||||
|
@ -348,6 +398,7 @@ static gint data_create_new_database(const gchar *filename)
|
||||||
" 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)) ",
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
13
src/data.h
13
src/data.h
|
@ -3,6 +3,14 @@
|
||||||
|
|
||||||
#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
|
||||||
|
@ -11,14 +19,17 @@ struct _manga
|
||||||
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__ */
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue