forked from sergiotarxz/mangareader
Making possible to see the list of available chapters.
This commit is contained in:
parent
aad920661e
commit
ba2c4ac9f4
16
include/openmg/chapter.h
Normal file
16
include/openmg/chapter.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS;
|
||||||
|
|
||||||
|
#define MG_TYPE_MANGA_CHAPTER mg_manga_chapter_get_type()
|
||||||
|
G_DECLARE_FINAL_TYPE (MgMangaChapter, mg_manga_chapter, MG, MANGA_CHAPTER, GObject)
|
||||||
|
|
||||||
|
MgMangaChapter *
|
||||||
|
mg_manga_chapter_new (const char *const title,
|
||||||
|
const char *const published_text,
|
||||||
|
const char *const url);
|
||||||
|
char *
|
||||||
|
mg_manga_chapter_get_title (MgMangaChapter *self);
|
||||||
|
|
||||||
|
G_END_DECLS
|
@ -22,6 +22,10 @@ int
|
|||||||
mg_manga_has_details (MgManga *self);
|
mg_manga_has_details (MgManga *self);
|
||||||
void
|
void
|
||||||
mg_manga_details_recovered (MgManga *self);
|
mg_manga_details_recovered (MgManga *self);
|
||||||
|
void
|
||||||
|
mg_manga_set_chapter_list (MgManga *self, GListStore *chapter_list);
|
||||||
|
GListStore *
|
||||||
|
mg_manga_get_chapter_list (MgManga *self);
|
||||||
|
|
||||||
MgManga *mg_manga_new (const char *const image_url, const char *const title, const char *const id);
|
MgManga *mg_manga_new (const char *const image_url, const char *const title, const char *const id);
|
||||||
|
|
||||||
|
5
include/openmg/view/list_view_chapter.h
Normal file
5
include/openmg/view/list_view_chapter.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <openmg/manga.h>
|
||||||
|
|
||||||
|
GtkListView *
|
||||||
|
create_list_view_chapters (MgManga *manga);
|
@ -12,6 +12,7 @@ openmgdeps = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
|
'src/view/list_view_chapter.c',
|
||||||
'src/view/picture.c',
|
'src/view/picture.c',
|
||||||
'src/util/gobject_utility_extensions.c',
|
'src/util/gobject_utility_extensions.c',
|
||||||
'src/view/detail_manga.c',
|
'src/view/detail_manga.c',
|
||||||
@ -22,6 +23,7 @@ sources = [
|
|||||||
'src/view/list_view_manga.c',
|
'src/view/list_view_manga.c',
|
||||||
'src/view/main_view.c',
|
'src/view/main_view.c',
|
||||||
'src/manga.c',
|
'src/manga.c',
|
||||||
|
'src/chapter.c',
|
||||||
'src/backend/readmng.c',
|
'src/backend/readmng.c',
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
]
|
]
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <openmg/util/string.h>
|
#include <openmg/util/string.h>
|
||||||
|
|
||||||
#include <openmg/manga.h>
|
#include <openmg/manga.h>
|
||||||
|
#include <openmg/chapter.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MG_BACKEND_READMNG_BASE_URL = 1,
|
MG_BACKEND_READMNG_BASE_URL = 1,
|
||||||
@ -44,6 +45,17 @@ mg_backend_readmng_class_init (MgBackendReadmngClass *class) {
|
|||||||
mg_backend_readmng_properties);
|
mg_backend_readmng_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static xmlNodePtr
|
||||||
|
mg_backend_readmng_get_a_for_chapter (
|
||||||
|
MgBackendReadmng *self,
|
||||||
|
xmlNodePtr li);
|
||||||
|
static MgMangaChapter *
|
||||||
|
mg_backend_readmng_loop_li_chapter (
|
||||||
|
MgBackendReadmng *self,
|
||||||
|
xmlNodePtr li);
|
||||||
|
static GListStore *
|
||||||
|
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
|
||||||
|
xmlDocPtr html_document_details);
|
||||||
static xmlDocPtr
|
static xmlDocPtr
|
||||||
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
|
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
|
||||||
MgManga *manga);
|
MgManga *manga);
|
||||||
@ -140,13 +152,15 @@ mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
|
|||||||
xmlNodePtr *movie_detail = NULL;
|
xmlNodePtr *movie_detail = NULL;
|
||||||
xmlXPathObjectPtr xpath_result = NULL;
|
xmlXPathObjectPtr xpath_result = NULL;
|
||||||
xmlNodeSetPtr node_set = NULL;
|
xmlNodeSetPtr node_set = NULL;
|
||||||
|
GListStore *manga_chapters = NULL;
|
||||||
|
|
||||||
size_t movie_detail_len = 0;
|
size_t movie_detail_len = 0;
|
||||||
|
|
||||||
if (mg_manga_has_details (manga)) {
|
if (mg_manga_has_details (manga)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xml_utils = mg_util_xml_new ();
|
|
||||||
|
xml_utils = self->xml_utils;
|
||||||
html_document = mg_backend_readmng_fetch_xml_details (self,
|
html_document = mg_backend_readmng_fetch_xml_details (self,
|
||||||
manga);
|
manga);
|
||||||
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
|
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
|
||||||
@ -165,9 +179,87 @@ mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
|
|||||||
mg_manga_set_description (manga,
|
mg_manga_set_description (manga,
|
||||||
(char *) xmlNodeGetContent (movie_detail[0]));
|
(char *) xmlNodeGetContent (movie_detail[0]));
|
||||||
}
|
}
|
||||||
|
manga_chapters = mg_backend_readmng_recover_chapter_list (self, html_document);
|
||||||
|
mg_manga_set_chapter_list (manga, manga_chapters);
|
||||||
mg_manga_details_recovered (manga);
|
mg_manga_details_recovered (manga);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GListStore *
|
||||||
|
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
|
||||||
|
xmlDocPtr html_document_details) {
|
||||||
|
MgUtilXML *xml_utils = self->xml_utils;
|
||||||
|
xmlXPathObjectPtr xpath_result = NULL;
|
||||||
|
xmlNodeSetPtr node_set = NULL;
|
||||||
|
xmlNodePtr *uls = NULL;
|
||||||
|
xmlNodePtr ul;
|
||||||
|
GListStore *return_value = g_list_store_new (
|
||||||
|
MG_TYPE_MANGA_CHAPTER);
|
||||||
|
size_t ul_len = 0;
|
||||||
|
|
||||||
|
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
|
||||||
|
html_document_details, "//ul[@class]");
|
||||||
|
node_set = xpath_result->nodesetval;
|
||||||
|
if (!node_set) {
|
||||||
|
fprintf(stderr, "No matching ul\n");
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < node_set->nodeNr; i++) {
|
||||||
|
xmlNodePtr node = node_set->nodeTab[i];
|
||||||
|
uls = mg_util_xml_loop_search_class (xml_utils,
|
||||||
|
node, uls, "chp_lst", &ul_len);
|
||||||
|
}
|
||||||
|
if (!ul_len) {
|
||||||
|
fprintf(stderr, "No matching chp_lst\n");
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
ul = uls[0];
|
||||||
|
for (xmlNodePtr li = ul->children; li; li = li->next) {
|
||||||
|
if (!strcmp ((char *) li->name, "li")) {
|
||||||
|
MgMangaChapter *chapter = mg_backend_readmng_loop_li_chapter (self, li);
|
||||||
|
if (chapter) {
|
||||||
|
g_list_store_append (return_value, chapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MgMangaChapter *
|
||||||
|
mg_backend_readmng_loop_li_chapter (
|
||||||
|
MgBackendReadmng *self,
|
||||||
|
xmlNodePtr li) {
|
||||||
|
MgUtilXML *xml_utils = self->xml_utils;
|
||||||
|
xmlNodePtr a = mg_backend_readmng_get_a_for_chapter (
|
||||||
|
self, li);
|
||||||
|
if (!a) return NULL;
|
||||||
|
|
||||||
|
char *url = mg_util_xml_get_attr (xml_utils, a, "href");
|
||||||
|
size_t val_len = 0;
|
||||||
|
size_t dte_len = 0;
|
||||||
|
|
||||||
|
xmlNodePtr *val = mg_util_xml_find_class (xml_utils, a, "val", &val_len, NULL, 1);
|
||||||
|
xmlNodePtr *dte = mg_util_xml_find_class (xml_utils, a, "dte", &dte_len, NULL, 1);
|
||||||
|
if (val_len && dte_len) {
|
||||||
|
return mg_manga_chapter_new (
|
||||||
|
(char *) xmlNodeGetContent (val[0]),
|
||||||
|
(char *) xmlNodeGetContent(dte[0]),
|
||||||
|
url);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static xmlNodePtr
|
||||||
|
mg_backend_readmng_get_a_for_chapter (
|
||||||
|
MgBackendReadmng *self,
|
||||||
|
xmlNodePtr li) {
|
||||||
|
for (xmlNodePtr child = li->children; child; child = child->next) {
|
||||||
|
if (!strcmp((char *) child->name, "a")) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static xmlDocPtr
|
static xmlDocPtr
|
||||||
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
|
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
|
||||||
MgManga *manga) {
|
MgManga *manga) {
|
||||||
|
162
src/chapter.c
Normal file
162
src/chapter.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <openmg/chapter.h>
|
||||||
|
|
||||||
|
#include <openmg/util/string.h>
|
||||||
|
|
||||||
|
struct _MgMangaChapter {
|
||||||
|
GObject parent_instance;
|
||||||
|
char *title;
|
||||||
|
char *url;
|
||||||
|
char *published_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_class_init (MgMangaChapterClass *class);
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_class_init (MgMangaChapterClass *class);
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MgMangaChapter, mg_manga_chapter,
|
||||||
|
G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MG_MANGA_CHAPTER_TITLE = 1,
|
||||||
|
MG_MANGA_CHAPTER_URL,
|
||||||
|
MG_MANGA_CHAPTER_PUBLISHED_TEXT,
|
||||||
|
MG_MANGA_CHAPTER_N_PROPERTIES
|
||||||
|
} MgMangaChapterProperties;
|
||||||
|
|
||||||
|
static GParamSpec *manga_chapter_properties[MG_MANGA_CHAPTER_N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
|
||||||
|
MgMangaChapter *
|
||||||
|
mg_manga_chapter_new (const char *const title,
|
||||||
|
const char *const published_text,
|
||||||
|
const char *const url) {
|
||||||
|
MgMangaChapter *self = NULL;
|
||||||
|
MgUtilString *string_util = mg_util_string_new ();
|
||||||
|
|
||||||
|
self = MG_MANGA_CHAPTER (
|
||||||
|
g_object_new (MG_TYPE_MANGA_CHAPTER, NULL));
|
||||||
|
|
||||||
|
self->title = mg_util_string_alloc_string (
|
||||||
|
string_util, strlen (title));
|
||||||
|
self->url = mg_util_string_alloc_string (
|
||||||
|
string_util, strlen (url));
|
||||||
|
self->published_text = mg_util_string_alloc_string (
|
||||||
|
string_util, strlen (published_text));
|
||||||
|
|
||||||
|
mg_util_string_copy_substring (string_util,
|
||||||
|
title, self->title,
|
||||||
|
strlen(title) + 1, 0, strlen (title));
|
||||||
|
mg_util_string_copy_substring (string_util,
|
||||||
|
url, self->url,
|
||||||
|
strlen(url) + 1, 0, strlen (url));
|
||||||
|
mg_util_string_copy_substring (string_util,
|
||||||
|
published_text, self->published_text,
|
||||||
|
strlen(published_text) + 1, 0,
|
||||||
|
strlen (published_text));
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_class_init (MgMangaChapterClass *class) {
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
object_class->set_property = mg_manga_chapter_set_property;
|
||||||
|
object_class->get_property = mg_manga_chapter_get_property;
|
||||||
|
|
||||||
|
manga_chapter_properties[MG_MANGA_CHAPTER_TITLE] =
|
||||||
|
g_param_spec_string ("title",
|
||||||
|
"Title",
|
||||||
|
"Title of the chapter.",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY
|
||||||
|
| G_PARAM_READWRITE);
|
||||||
|
manga_chapter_properties[MG_MANGA_CHAPTER_URL] =
|
||||||
|
g_param_spec_string ("url",
|
||||||
|
"URL",
|
||||||
|
"URL of the chapter.",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY
|
||||||
|
| G_PARAM_READWRITE);
|
||||||
|
manga_chapter_properties[MG_MANGA_CHAPTER_PUBLISHED_TEXT] =
|
||||||
|
g_param_spec_string ("published_text",
|
||||||
|
"PublishedText",
|
||||||
|
"Text of publication.",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY
|
||||||
|
| G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_properties (object_class,
|
||||||
|
MG_MANGA_CHAPTER_N_PROPERTIES,
|
||||||
|
manga_chapter_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_init (MgMangaChapter *self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec) {
|
||||||
|
MgMangaChapter *self = MG_MANGA_CHAPTER (object);
|
||||||
|
switch ((MgMangaChapterProperties) property_id) {
|
||||||
|
case MG_MANGA_CHAPTER_TITLE:
|
||||||
|
g_value_set_string (value, self->title);
|
||||||
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_URL:
|
||||||
|
g_value_set_string (value, self->url);
|
||||||
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_PUBLISHED_TEXT:
|
||||||
|
g_value_set_string (value, self->published_text);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_manga_chapter_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec) {
|
||||||
|
MgMangaChapter *self = MG_MANGA_CHAPTER (object);
|
||||||
|
switch ((MgMangaChapterProperties) property_id) {
|
||||||
|
case MG_MANGA_CHAPTER_TITLE:
|
||||||
|
g_free (self->title);
|
||||||
|
self->title = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_URL:
|
||||||
|
g_free (self->url);
|
||||||
|
self->url = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_PUBLISHED_TEXT:
|
||||||
|
g_free (self->published_text);
|
||||||
|
self->published_text = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
mg_manga_chapter_get_title (MgMangaChapter *self) {
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init (&value, G_TYPE_STRING);
|
||||||
|
g_object_get_property (G_OBJECT (self), "title", &value);
|
||||||
|
return g_value_dup_string (&value);
|
||||||
|
}
|
48
src/manga.c
48
src/manga.c
@ -1,7 +1,11 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include <openmg/util/string.h>
|
#include <openmg/util/string.h>
|
||||||
#include <openmg/manga.h>
|
#include <openmg/manga.h>
|
||||||
|
#include <openmg/chapter.h>
|
||||||
|
|
||||||
struct _MgManga {
|
struct _MgManga {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -9,6 +13,7 @@ struct _MgManga {
|
|||||||
char *title;
|
char *title;
|
||||||
char *id;
|
char *id;
|
||||||
char *description;
|
char *description;
|
||||||
|
GListStore *chapter_list;
|
||||||
int has_details;
|
int has_details;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -19,6 +24,7 @@ typedef enum {
|
|||||||
MG_MANGA_TITLE,
|
MG_MANGA_TITLE,
|
||||||
MG_MANGA_ID,
|
MG_MANGA_ID,
|
||||||
MG_MANGA_DESCRIPTION,
|
MG_MANGA_DESCRIPTION,
|
||||||
|
MG_MANGA_CHAPTER_LIST,
|
||||||
MG_MANGA_N_PROPERTIES
|
MG_MANGA_N_PROPERTIES
|
||||||
} MgMangaProperties;
|
} MgMangaProperties;
|
||||||
|
|
||||||
@ -62,6 +68,13 @@ mg_manga_class_init (MgMangaClass *class) {
|
|||||||
"Description of the manga.",
|
"Description of the manga.",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
|
manga_properties[MG_MANGA_CHAPTER_LIST] = g_param_spec_object (
|
||||||
|
"chapter_list",
|
||||||
|
"ChapterList",
|
||||||
|
"List of chapters.",
|
||||||
|
G_TYPE_LIST_STORE,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
|
||||||
g_object_class_install_properties (object_class,
|
g_object_class_install_properties (object_class,
|
||||||
MG_MANGA_N_PROPERTIES,
|
MG_MANGA_N_PROPERTIES,
|
||||||
@ -123,6 +136,24 @@ mg_manga_get_description (MgManga *self) {
|
|||||||
return g_value_dup_string (&value);
|
return g_value_dup_string (&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GListStore *
|
||||||
|
mg_manga_get_chapter_list (MgManga *self) {
|
||||||
|
if (!mg_manga_has_details (self)) {
|
||||||
|
fprintf(stderr, "Manga has still not details\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
GListStore *return_value;
|
||||||
|
|
||||||
|
g_value_init (&value, G_TYPE_LIST_STORE);
|
||||||
|
g_object_get_property (G_OBJECT (self),
|
||||||
|
"chapter_list",
|
||||||
|
&value);
|
||||||
|
return_value = G_LIST_STORE (g_value_peek_pointer (&value));
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mg_manga_set_description (MgManga *self, const char *description) {
|
mg_manga_set_description (MgManga *self, const char *description) {
|
||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
@ -131,12 +162,21 @@ mg_manga_set_description (MgManga *self, const char *description) {
|
|||||||
g_object_set_property (G_OBJECT (self), "description", &value);
|
g_object_set_property (G_OBJECT (self), "description", &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mg_manga_set_chapter_list (MgManga *self, GListStore *chapter_list) {
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init (&value, G_TYPE_LIST_STORE);
|
||||||
|
g_value_set_instance (&value, chapter_list);
|
||||||
|
g_object_set_property (G_OBJECT (self), "chapter_list", &value);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mg_manga_set_property (GObject *object,
|
mg_manga_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec) {
|
GParamSpec *pspec) {
|
||||||
MgManga *self = MG_MANGA (object);
|
MgManga *self = MG_MANGA (object);
|
||||||
|
GListStore *chapter_list;
|
||||||
switch ((MgMangaProperties) property_id) {
|
switch ((MgMangaProperties) property_id) {
|
||||||
case MG_MANGA_IMAGE_URL:
|
case MG_MANGA_IMAGE_URL:
|
||||||
g_free (self->image_url);
|
g_free (self->image_url);
|
||||||
@ -154,6 +194,11 @@ mg_manga_set_property (GObject *object,
|
|||||||
g_free (self->description);
|
g_free (self->description);
|
||||||
self->description = g_value_dup_string (value);
|
self->description = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_LIST:
|
||||||
|
g_free (self->chapter_list);
|
||||||
|
chapter_list = g_value_peek_pointer (value);
|
||||||
|
self->chapter_list = chapter_list;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -179,6 +224,9 @@ mg_manga_get_property (GObject *object,
|
|||||||
case MG_MANGA_DESCRIPTION:
|
case MG_MANGA_DESCRIPTION:
|
||||||
g_value_set_string (value, self->description);
|
g_value_set_string (value, self->description);
|
||||||
break;
|
break;
|
||||||
|
case MG_MANGA_CHAPTER_LIST:
|
||||||
|
g_value_set_instance (value, self->chapter_list);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -6,26 +6,32 @@
|
|||||||
#include <openmg/backend/readmng.h>
|
#include <openmg/backend/readmng.h>
|
||||||
|
|
||||||
#include <openmg/util/xml.h>
|
#include <openmg/util/xml.h>
|
||||||
|
#include <openmg/util/gobject_utility_extensions.h>
|
||||||
|
|
||||||
#include <openmg/view/picture.h>
|
#include <openmg/view/picture.h>
|
||||||
#include <openmg/view/detail_manga.h>
|
#include <openmg/view/detail_manga.h>
|
||||||
|
#include <openmg/view/list_view_chapter.h>
|
||||||
|
|
||||||
GtkBox *
|
GtkBox *
|
||||||
create_detail_view (MgManga *manga) {
|
create_detail_view (MgManga *manga) {
|
||||||
MgBackendReadmng *readmng = mg_backend_readmng_new ();
|
MgBackendReadmng *readmng = mg_backend_readmng_new ();
|
||||||
|
GtkWidget *scroll;
|
||||||
GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
|
GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
|
||||||
GtkBox *avatar_title_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
|
GtkBox *avatar_title_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
|
||||||
MgUtilXML *xml_util = mg_util_xml_new ();
|
MgUtilXML *xml_util = mg_util_xml_new ();
|
||||||
GtkLabel *manga_title = NULL;
|
GtkLabel *manga_title = NULL;
|
||||||
GtkLabel *manga_description = NULL;
|
GtkLabel *manga_description = NULL;
|
||||||
|
GtkListView *chapter_list = NULL;
|
||||||
GtkPicture *manga_image = create_picture_from_url (
|
GtkPicture *manga_image = create_picture_from_url (
|
||||||
mg_manga_get_image_url(manga), 200);
|
mg_manga_get_image_url(manga), 200);
|
||||||
char *title_text = mg_util_xml_get_title_text (
|
char *title_text = mg_util_xml_get_title_text (
|
||||||
xml_util, mg_manga_get_title (manga));
|
xml_util, mg_manga_get_title (manga));
|
||||||
char *description_text;
|
char *description_text;
|
||||||
|
|
||||||
mg_backend_readmng_retrieve_manga_details (readmng, manga);
|
scroll = gtk_scrolled_window_new ();
|
||||||
|
|
||||||
|
mg_backend_readmng_retrieve_manga_details (readmng, manga);
|
||||||
|
chapter_list = create_list_view_chapters (manga);
|
||||||
description_text = mg_manga_get_description (manga);
|
description_text = mg_manga_get_description (manga);
|
||||||
|
|
||||||
manga_title = GTK_LABEL (gtk_label_new (title_text));
|
manga_title = GTK_LABEL (gtk_label_new (title_text));
|
||||||
@ -39,6 +45,9 @@ create_detail_view (MgManga *manga) {
|
|||||||
gtk_box_append (avatar_title_box, GTK_WIDGET (manga_title));
|
gtk_box_append (avatar_title_box, GTK_WIDGET (manga_title));
|
||||||
gtk_box_append (detail_view, GTK_WIDGET (avatar_title_box));
|
gtk_box_append (detail_view, GTK_WIDGET (avatar_title_box));
|
||||||
gtk_box_append (detail_view, GTK_WIDGET (manga_description));
|
gtk_box_append (detail_view, GTK_WIDGET (manga_description));
|
||||||
|
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scroll), GTK_WIDGET (chapter_list));
|
||||||
|
g_object_set_property_int (G_OBJECT (scroll), "vexpand", 1);
|
||||||
|
gtk_box_append (detail_view, GTK_WIDGET (scroll));
|
||||||
|
|
||||||
return detail_view;
|
return detail_view;
|
||||||
}
|
}
|
||||||
|
49
src/view/list_view_chapter.c
Normal file
49
src/view/list_view_chapter.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include <openmg/manga.h>
|
||||||
|
#include <openmg/chapter.h>
|
||||||
|
#include <openmg/backend/readmng.h>
|
||||||
|
#include <openmg/view/list_view_chapter.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
|
||||||
|
GtkListItem *list_item,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GtkListView *
|
||||||
|
create_list_view_chapters (MgManga *manga) {
|
||||||
|
GListStore *manga_chapter_list = NULL;
|
||||||
|
GtkListView *list_view_chapters = NULL;
|
||||||
|
GtkSingleSelection *selection = NULL;
|
||||||
|
GtkListItemFactory *factory =
|
||||||
|
gtk_signal_list_item_factory_new ();
|
||||||
|
|
||||||
|
manga_chapter_list = mg_manga_get_chapter_list (manga);
|
||||||
|
selection = gtk_single_selection_new
|
||||||
|
(G_LIST_MODEL (manga_chapter_list));
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (factory), "bind",
|
||||||
|
G_CALLBACK (setup_list_view_chapter_list),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
list_view_chapters = GTK_LIST_VIEW (gtk_list_view_new (GTK_SELECTION_MODEL (selection),
|
||||||
|
factory));
|
||||||
|
|
||||||
|
return list_view_chapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
|
||||||
|
GtkListItem *list_item,
|
||||||
|
gpointer user_data) {
|
||||||
|
MgMangaChapter *manga_chapter = gtk_list_item_get_item (list_item);
|
||||||
|
GtkBox *box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
|
||||||
|
GtkLabel *title = GTK_LABEL (gtk_label_new (mg_manga_chapter_get_title (manga_chapter)));
|
||||||
|
GtkImage *icon = GTK_IMAGE (gtk_image_new_from_icon_name (
|
||||||
|
"weather-clear-night-symbolic"));
|
||||||
|
gtk_image_set_icon_size (icon, GTK_ICON_SIZE_LARGE);
|
||||||
|
gtk_label_set_wrap (title, 1);
|
||||||
|
gtk_box_append (box, GTK_WIDGET (icon));
|
||||||
|
gtk_box_append (box, GTK_WIDGET (title));
|
||||||
|
gtk_list_item_set_child (list_item, GTK_WIDGET (box));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user