#include "cart_item.h" #include typedef struct _YacosCartItemPriv { GtkWidget *box; GtkWidget *label_title; GtkWidget *label_description; GtkWidget *entry_comment; GtkWidget *label_id; GtkWidget *button_delete; GtkWidget *image; GtkStack *stack_image_loader; yacos_tag_id tag_id; yacos_cart_item_status status; YacosApi *api; } YacosCartItemPriv; struct _YacosCartItem { /* Inheritance */ GtkListBoxRow parent; /* Custom Elements */ YacosCartItemPriv priv; }; G_DEFINE_TYPE(YacosCartItem, yacos_cart_item, GTK_TYPE_LIST_BOX_ROW) static void yacos_cart_item_dispose(GObject *obj) { /* destroy parent container. This destroys all widgets inside */ G_OBJECT_CLASS(yacos_cart_item_parent_class)->dispose(obj); } static void yacos_cart_item_constructed(GObject *obj) { G_OBJECT_CLASS(yacos_cart_item_parent_class)->constructed(obj); } static void yacos_cart_item_finalize(GObject *gobject) { YacosCartItem *self = yacos_cart_item_get_instance_private(YACOS_CART_ITEM(gobject)); G_OBJECT_CLASS(yacos_cart_item_parent_class)->finalize(gobject); } static void yacos_cart_item_class_init(YacosCartItemClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS(klass); oclass->dispose = yacos_cart_item_dispose; oclass->constructed = yacos_cart_item_constructed; oclass->finalize = yacos_cart_item_finalize; } static void yacos_cart_item_button_delete_cb(GtkWidget *widget, gpointer user_data) { YacosCartItem *self = (YacosCartItem *)user_data; GtkWidget *list_box_row = gtk_widget_get_parent(self->priv.box); gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(list_box_row)), list_box_row); } static void yacos_cart_item_init(YacosCartItem *self) { GtkBuilder *builder; builder = gtk_builder_new_from_resource("/net/notsyncing/yacos/glade/cartItem.glade"); self->priv.box = GTK_WIDGET(gtk_builder_get_object(builder, "cart_item")); self->priv.label_id = GTK_WIDGET(gtk_builder_get_object(builder, "label_id")); self->priv.label_title = GTK_WIDGET(gtk_builder_get_object(builder, "label_title")); self->priv.entry_comment = GTK_WIDGET(gtk_builder_get_object(builder, "entry_comment")); self->priv.label_description = GTK_WIDGET(gtk_builder_get_object(builder, "label_description")); self->priv.button_delete = GTK_WIDGET(gtk_builder_get_object(builder, "button_delete")); self->priv.image = GTK_WIDGET(gtk_builder_get_object(builder, "image_item")); self->priv.stack_image_loader = GTK_STACK(gtk_builder_get_object(builder, "stack_image_loader")); g_signal_connect(self->priv.button_delete, "clicked", (GCallback) yacos_cart_item_button_delete_cb, self); gtk_container_add(GTK_CONTAINER(self), self->priv.box); g_object_unref(builder); GtkStyleContext *context; GtkCssProvider *provider; context = gtk_widget_get_style_context (self->priv.entry_comment); provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider), ".entry_comment {\n" " font-style: italic;\n" "}\n", -1, NULL); gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref (provider); } GtkWidget *yacos_cart_item_new(void) { return GTK_WIDGET(g_object_new(TYPE_YACOS_CART_ITEM, NULL)); } void yacos_cart_item_set_id(YacosCartItem *self, yacos_tag_id tag_id) { gchar *id_str; gchar *id_str2; self->priv.status = YACOS_CART_ITEM_STATUS_PENDING; self->priv.tag_id = tag_id; id_str = yacos_tag_id_to_str(tag_id); id_str2 = g_strdup_printf("#%s", id_str); g_free(id_str); gtk_label_set_text(GTK_LABEL(self->priv.label_id), id_str2); g_free(id_str2); } static void yacos_cart_item_fetch_meta_cb (guint status, JsonParser *parser, gpointer user_data) { YacosCartItem *self = YACOS_CART_ITEM(user_data); const char *temp; JsonReader *reader; const static GdkRGBA color_error = {.red = 1.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; if (status != 200) { g_warning("Received error code %d from server.", status); gtk_label_set_text(GTK_LABEL(self->priv.label_title), "Unknown article"); gtk_widget_override_color(self->priv.label_title, GTK_STATE_FLAG_NORMAL, &color_error); gtk_label_set_text(GTK_LABEL(self->priv.label_description), "This article will be ignored on checkout."); gtk_entry_set_text(GTK_ENTRY(self->priv.entry_comment), "If you think this is an error, please contact a member of staff."); self->priv.status = YACOS_CART_ITEM_STATUS_INVALID; return; } reader = json_reader_new (json_parser_get_root (parser)); json_reader_read_member (reader, "title"); temp = json_reader_get_string_value (reader); gtk_label_set_text(GTK_LABEL(self->priv.label_title), temp); json_reader_end_member (reader); json_reader_read_member (reader, "description"); temp = json_reader_get_string_value (reader); gtk_label_set_text(GTK_LABEL(self->priv.label_description), temp); json_reader_end_member (reader); json_reader_read_member (reader, "comment"); temp = json_reader_get_string_value (reader); if (*temp) gtk_entry_set_placeholder_text(GTK_ENTRY(self->priv.entry_comment), temp); else gtk_entry_set_placeholder_text(GTK_ENTRY(self->priv.entry_comment), "Click here to add a comment."); json_reader_end_member (reader); g_object_unref (reader); gtk_editable_set_editable(GTK_EDITABLE(self->priv.entry_comment), TRUE); self->priv.status = YACOS_CART_ITEM_STATUS_VALID; } void yacos_cart_item_fetch_meta(YacosCartItem *self) { gtk_label_set_text(GTK_LABEL(self->priv.label_title), "Loading ..."); gtk_label_set_text(GTK_LABEL(self->priv.label_description), ""); gtk_entry_set_text(GTK_ENTRY(self->priv.entry_comment), ""); yacos_api_fetch_meta(self->priv.api, self->priv.tag_id, yacos_cart_item_fetch_meta_cb, self); } static void yacos_cart_item_fetch_image_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { YacosCartItem *self = YACOS_CART_ITEM(user_data); GdkPixbuf *pixbuf_raw, *pixbuf_scaled; GMemoryInputStream *s; if (msg->status_code != 200) { g_warning("image: Received error code %d from server.", msg->status_code); } else { s = G_MEMORY_INPUT_STREAM(g_memory_input_stream_new()); g_memory_input_stream_add_data(s, msg->response_body->data, msg->response_body->length, NULL); pixbuf_raw = gdk_pixbuf_new_from_stream(G_INPUT_STREAM(s), NULL, NULL); g_object_unref(s); pixbuf_scaled = gdk_pixbuf_scale_simple(pixbuf_raw, 100, 100, GDK_INTERP_BILINEAR); g_object_unref(pixbuf_raw); gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv.image), pixbuf_scaled); g_object_unref(pixbuf_scaled); } gtk_stack_set_visible_child(self->priv.stack_image_loader, self->priv.image); } void yacos_cart_item_fetch_image(YacosCartItem *self) { yacos_api_fetch_image(self->priv.api, self->priv.tag_id, yacos_cart_item_fetch_image_cb, self); } yacos_tag_id yacos_cart_item_get_id(YacosCartItem *self) { return self->priv.tag_id; } void yacos_cart_item_set_yacos_api(YacosCartItem *self, YacosApi *api) { self->priv.api = api; }