aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemsen2010-10-19 01:28:46 +0200
committerGravatar Tom Willemsen2010-10-19 01:28:46 +0200
commitc34819ee2c5d8d4fb536ea469588d8f0ccbf08e0 (patch)
treeca72a46cbe21d308d89b84077a43f036f58aed03
parent767ca99d338cddf3dff25d31e54739dbff400ad8 (diff)
downloadeye-on-manga-c34819ee2c5d8d4fb536ea469588d8f0ccbf08e0.tar.gz
eye-on-manga-c34819ee2c5d8d4fb536ea469588d8f0ccbf08e0.zip
Data
Data is gotten from an sqlite3 database New series can be added to the database
-rw-r--r--src/Makefile5
-rw-r--r--src/c-main-window.c87
-rw-r--r--src/c-main-window.h6
-rw-r--r--src/c-new-item-dialog.c3
-rw-r--r--src/collections.c25
-rw-r--r--src/collections.h2
-rw-r--r--src/data.c153
-rw-r--r--src/data.h11
-rw-r--r--src/interface.c5
9 files changed, 287 insertions, 10 deletions
diff --git a/src/Makefile b/src/Makefile
index 24b89b6..895314b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,4 +1,4 @@
-CFLAGS=`pkg-config hildon-1 --cflags --libs`
+CFLAGS=`pkg-config hildon-1 sqlite3 --cflags --libs`
all:
$(CC) -Wall -Wextra -pedantic \
@@ -6,6 +6,7 @@ all:
interface.c \
c-main-window.c \
c-new-item-dialog.c \
+ data.c \
$(CFLAGS) \
-o collections
@@ -13,4 +14,4 @@ all:
check-syntax:
/scratchbox/login $(CC) -pedantic -Wall -Wextra -fsyntax-only \
`readlink -f $(CHK_SOURCES)` \
- `/scratchbox/login pkg-config hildon-1 --cflags --libs`
+ `/scratchbox/login pkg-config hildon-1 sqlite3 --cflags --libs`
diff --git a/src/c-main-window.c b/src/c-main-window.c
index 79c47c6..2afc87b 100644
--- a/src/c-main-window.c
+++ b/src/c-main-window.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <stdlib.h>
#include "c-new-item-dialog.h"
+#include "data.h"
#include "interface.h"
G_DEFINE_TYPE(CMainWindow, c_main_window, HILDON_TYPE_STACKABLE_WINDOW)
@@ -17,12 +18,31 @@ enum {
static void c_main_window_add_menu(CMainWindow *window);
static void c_main_window_on_new(GtkWidget *widget, GtkWindow *window);
+static void c_main_window_on_selection_changed(GtkTreeSelection *selection,
+ gpointer user_data);
GtkWidget *c_main_window_new(void)
{
return g_object_new(C_TYPE_MAIN_WINDOW, NULL);
}
+void c_main_window_load(CMainWindow *self)
+{
+ GList *list;
+
+ gtk_list_store_clear(self->store);
+
+ list = data_get_series();
+
+ while (list) {
+ struct collection *col = list->data;
+ c_main_window_add_line(self, col->name, col->current_qty, col->total_qty);
+ list = g_list_next(list);
+ }
+
+ g_list_free_1(list);
+}
+
void c_main_window_add_line(CMainWindow *window,
const gchar *name,
gint current_qty,
@@ -36,6 +56,22 @@ void c_main_window_add_line(CMainWindow *window,
-1);
}
+void c_main_window_set_no_select(CMainWindow *self)
+{
+ if (GTK_IS_WIDGET(self->add_button))
+ gtk_widget_set_sensitive(GTK_WIDGET(self->add_button), FALSE);
+ if (GTK_IS_WIDGET(self->remove_button))
+ gtk_widget_set_sensitive(GTK_WIDGET(self->remove_button), FALSE);
+}
+
+void c_main_window_set_has_select(CMainWindow *self)
+{
+ if (GTK_IS_WIDGET(self->add_button))
+ gtk_widget_set_sensitive(GTK_WIDGET(self->add_button), TRUE);
+ if (GTK_IS_WIDGET(self->remove_button))
+ gtk_widget_set_sensitive(GTK_WIDGET(self->remove_button), TRUE);
+}
+
static void c_main_window_class_init(CMainWindowClass *class)
{}
@@ -43,7 +79,10 @@ static void c_main_window_init(CMainWindow *window)
{
GtkCellRenderer *renderer;
GtkWidget *view;
+ GtkWidget *vbox;
+ GtkWidget *hbuttonbox;
GtkTreeViewColumn *current_column;
+ GtkTreeSelection *selection;
int index;
index = -1;
@@ -58,7 +97,15 @@ static void c_main_window_init(CMainWindow *window)
G_TYPE_INT,
G_TYPE_INT);
+ vbox = gtk_vbox_new(FALSE, 0);
+
view = gtk_tree_view_new();
+ gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ g_signal_connect(selection, "changed",
+ G_CALLBACK(c_main_window_on_selection_changed),
+ (gpointer)window);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
@@ -71,7 +118,10 @@ static void c_main_window_init(CMainWindow *window)
gtk_tree_view_column_set_expand(current_column, TRUE);
renderer = gtk_cell_renderer_text_new();
- gtk_object_set(GTK_OBJECT(renderer), "xalign", 1.0, NULL);
+ gtk_object_set(GTK_OBJECT(renderer),
+ "xalign", 1.0,
+ "width", 100,
+ NULL);
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
++index,
"",
@@ -80,7 +130,10 @@ static void c_main_window_init(CMainWindow *window)
NULL);
renderer = gtk_cell_renderer_text_new();
- gtk_object_set(GTK_OBJECT(renderer), "xalign", 1.0, NULL);
+ gtk_object_set(GTK_OBJECT(renderer),
+ "xalign", 1.0,
+ "width", 100,
+ NULL);
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
++index,
"",
@@ -92,7 +145,19 @@ static void c_main_window_init(CMainWindow *window)
GTK_TREE_MODEL(window->store));
g_object_unref(window->store);
- gtk_container_add(GTK_CONTAINER(window), view);
+ hbuttonbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
+ gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0);
+
+ window->add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+ gtk_box_pack_start(GTK_BOX(hbuttonbox), window->add_button, FALSE, FALSE, 0);
+
+ window->remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+ gtk_box_pack_start(GTK_BOX(hbuttonbox), window->remove_button, FALSE, FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ c_main_window_set_no_select(window);
}
static void c_main_window_add_menu(CMainWindow *window)
@@ -141,6 +206,20 @@ static void c_main_window_on_new(GtkWidget *widget, GtkWindow *window)
}
if (name != NULL) {
- c_main_window_add_line(C_MAIN_WINDOW(window), name, 0, total_qty);
+ if (data_add_series(name, total_qty))
+ c_main_window_load(C_MAIN_WINDOW(window));
}
}
+
+static void c_main_window_on_selection_changed(GtkTreeSelection *selection,
+ gpointer user_data)
+{
+ gint count;
+ CMainWindow *self = (CMainWindow *)user_data;
+
+ count = gtk_tree_selection_count_selected_rows(selection);
+ if (count == 0)
+ c_main_window_set_no_select(self);
+ else
+ c_main_window_set_has_select(self);
+}
diff --git a/src/c-main-window.h b/src/c-main-window.h
index 185f532..29af0f5 100644
--- a/src/c-main-window.h
+++ b/src/c-main-window.h
@@ -45,16 +45,22 @@ struct _CMainWindow
GtkTreeIter iter;
GtkListStore *store;
+
+ GtkWidget *add_button;
+ GtkWidget *remove_button;
};
GType c_main_window_get_type(void);
GtkWidget *c_main_window_new(void);
+void c_main_window_load(CMainWindow *self);
void c_main_window_add_line(CMainWindow *window,
const gchar *name,
gint current_qty,
gint total_qty);
+void c_main_window_set_no_select(CMainWindow *self);
+void c_main_window_set_has_select(CMainWindow *self);
G_END_DECLS
diff --git a/src/c-new-item-dialog.c b/src/c-new-item-dialog.c
index 75142e9..76b0686 100644
--- a/src/c-new-item-dialog.c
+++ b/src/c-new-item-dialog.c
@@ -30,7 +30,7 @@ static void c_new_item_dialog_init(CNewItemDialog *dialog)
content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- hbox = gtk_vbox_new(FALSE, 0);
+ hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(content_area), hbox);
dialog->name_entry = hildon_entry_new(HILDON_SIZE_AUTO);
@@ -38,6 +38,7 @@ static void c_new_item_dialog_init(CNewItemDialog *dialog)
gtk_box_pack_start(GTK_BOX(hbox), dialog->name_entry, TRUE, TRUE, 0);
dialog->qty_entry = hildon_entry_new(HILDON_SIZE_AUTO);
+ g_object_set(G_OBJECT(dialog->qty_entry), "width-chars", 5, NULL);
hildon_entry_set_text(HILDON_ENTRY(dialog->qty_entry), "0");
gtk_box_pack_start(GTK_BOX(hbox), dialog->qty_entry, TRUE, TRUE, 0);
diff --git a/src/collections.c b/src/collections.c
index 38d9f76..56c75b7 100644
--- a/src/collections.c
+++ b/src/collections.c
@@ -1,5 +1,30 @@
#include <hildon/hildon.h>
+#include <stdlib.h>
#include "interface.h"
+#include "collections.h"
+
+gchar *collections_get_data_file(void)
+{
+ static gchar *filedir = NULL;
+
+ if (filedir == NULL) {
+ filedir = g_strdup_printf("%s/collections.db",
+ collections_get_config_dir());
+ }
+
+ return filedir;
+}
+
+gchar *collections_get_config_dir(void)
+{
+ static gchar *filedir = NULL;
+
+ if (filedir == NULL) {
+ filedir = g_strdup_printf("%s/.collections", getenv("HOME"));
+ }
+
+ return filedir;
+}
int main(int argc, char *argv[])
{
diff --git a/src/collections.h b/src/collections.h
new file mode 100644
index 0000000..b3f9240
--- /dev/null
+++ b/src/collections.h
@@ -0,0 +1,2 @@
+gchar *collections_get_data_file(void);
+gchar *collections_get_config_dir(void);
diff --git a/src/data.c b/src/data.c
new file mode 100644
index 0000000..0013ed2
--- /dev/null
+++ b/src/data.c
@@ -0,0 +1,153 @@
+#include "data.h"
+#include <sqlite3.h>
+#include <gtk/gtk.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "collections.h"
+
+static gboolean data_check_and_create_database(gchar *data_file);
+static gint data_create_new_database(const char *filename);
+
+GList *data_get_series(void)
+{
+ sqlite3 *database;
+ sqlite3_stmt *statement;
+ gchar *data_file;
+ GList *list = NULL;
+
+ data_file = collections_get_data_file();
+
+ if (data_check_and_create_database(data_file)) {
+ if (sqlite3_open(data_file, &database) == SQLITE_OK) {
+ int res;
+ const char *sqlStatement =
+ " SELECT name, "
+ " current_qty, "
+ " total_qty "
+ " FROM collection "
+ " ORDER BY name "
+ " COLLATE NOCASE ";
+
+ res = sqlite3_prepare_v2(database,
+ sqlStatement,
+ strlen(sqlStatement),
+ &statement, NULL);
+ if (res == SQLITE_OK) {
+ while (sqlite3_step(statement) == SQLITE_ROW) {
+ struct collection *col =
+ (struct collection *)malloc(sizeof(struct collection *));
+
+ col->name = g_strdup(sqlite3_column_text(statement, 0));
+ col->current_qty = sqlite3_column_int(statement, 1);
+ col->total_qty = sqlite3_column_int(statement, 2);
+
+ list = g_list_append(list, (gpointer)col);
+ }
+ }
+ else
+ g_print("error %d: %s\n", res, sqlite3_errmsg(database));
+ /* Release the compiled statement from memory */
+ sqlite3_finalize(statement);
+ }
+ sqlite3_close(database);
+ }
+
+ return list;
+}
+
+gboolean data_add_series(gchar *name, int total_qty)
+{
+ sqlite3 *database;
+ sqlite3_stmt *statement;
+ gchar *data_file;
+
+ data_file = collections_get_data_file();
+
+ if (data_check_and_create_database(data_file)) {
+ if (sqlite3_open(data_file, &database) == SQLITE_OK) {
+ int res;
+ const char *sqlStatement =
+ g_strdup_printf("INSERT INTO collection (name, current_qty, total_qty) "
+ " VALUES ('%s', 0, %d)", name, total_qty);
+
+ res = sqlite3_prepare_v2(database,
+ sqlStatement,
+ strlen(sqlStatement),
+ &statement, NULL);
+ if (res == SQLITE_OK) {
+ if (sqlite3_step(statement) == SQLITE_DONE)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean data_check_and_create_database(gchar *data_file)
+{
+ if (!access(data_file, R_OK) == 0)
+ if (data_create_new_database(data_file)) {
+ g_printerr("Couldn't create a new database\n");
+ return FALSE; /* Couldn't create database, can't continue */
+ }
+
+ return TRUE;
+}
+
+static gint data_create_new_database(const char *filename)
+{
+ sqlite3 *db;
+ char *zErrMsg = 0;
+ int rc;
+
+ if (access(collections_get_config_dir(), R_OK) == -1) {
+ if (mkdir(collections_get_config_dir(), S_IRWXU) == -1)
+ g_printerr("Can't create directory: %s\n", strerror(errno));
+ }
+
+ /* Open database connection, create file */
+ rc = sqlite3_open(filename, &db);
+ if (rc) {
+ g_printerr("Can't open database: %s\n", sqlite3_errmsg(db));
+ if (db)
+ sqlite3_close(db);
+ return -1;
+ }
+
+ /* Create collections table */
+ rc = sqlite3_exec(db, "CREATE TABLE collection("
+ "id INTEGER PRIMARY KEY,"
+ "name VARCHAR(100),"
+ "current_qty INTEGER,"
+ "total_qty INTEGER"
+ ")", NULL, NULL, &zErrMsg);
+ if (rc != SQLITE_OK) {
+ g_printerr("Can't create collection table: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ sqlite3_close(db);
+ return -1;
+ }
+
+ /* Create items table */
+ rc = sqlite3_exec(db, "CREATE TABLE item("
+ "collection_id INTEGER,"
+ "id INTEGER,"
+ "title VARCHAR(100),"
+ "PRIMARY KEY(collection_id, id),"
+ "FOREIGN KEY(collection_id)"
+ " REFERENCES collection(id)"
+ ")", NULL, NULL, &zErrMsg);
+ if (rc != SQLITE_OK) {
+ g_printerr("Can't create item table: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ sqlite3_close(db);
+ return -1;
+ }
+
+ sqlite3_close(db);
+ return 0;
+}
diff --git a/src/data.h b/src/data.h
new file mode 100644
index 0000000..3ebbb2e
--- /dev/null
+++ b/src/data.h
@@ -0,0 +1,11 @@
+#include <gtk/gtk.h>
+
+struct collection
+{
+ const gchar *name;
+ gint current_qty;
+ gint total_qty;
+};
+
+GList *data_get_series(void);
+gboolean data_add_series(gchar *name, int total_qty);
diff --git a/src/interface.c b/src/interface.c
index 5e68160..2e54ecd 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -2,6 +2,7 @@
#include "interface.h"
#include "c-main-window.h"
#include "c-new-item-dialog.h"
+#include "data.h"
void interface_show_main_window(void)
{
@@ -10,9 +11,7 @@ void interface_show_main_window(void)
window = c_main_window_new();
gtk_widget_show_all(window);
- c_main_window_add_line(C_MAIN_WINDOW(window), "Biomega", 2, 0);
- c_main_window_add_line(C_MAIN_WINDOW(window), "Blame!", 7, 10);
- c_main_window_add_line(C_MAIN_WINDOW(window), "Hellsing", 2, 14);
+ c_main_window_load(C_MAIN_WINDOW(window));
}
GtkWidget *interface_show_new_item_dialog(GtkWindow *window)