forked from sergiotarxz/mangareader
Adding support to look the first image of the
manga...
This commit is contained in:
parent
d91cd296a9
commit
490af0a0db
@ -5,6 +5,7 @@
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <openmg/manga.h>
|
||||
#include <openmg/chapter.h>
|
||||
|
||||
G_BEGIN_DECLS;
|
||||
|
||||
@ -32,5 +33,7 @@ mg_backend_readmng_get_featured_manga (MgBackendReadmng *self);
|
||||
void
|
||||
mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
|
||||
MgManga *manga);
|
||||
GListModel *
|
||||
mg_backend_readmng_get_chapter_images (MgBackendReadmng *self, MgMangaChapter *chapter);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -12,5 +12,7 @@ mg_manga_chapter_new (const char *const title,
|
||||
const char *const url);
|
||||
char *
|
||||
mg_manga_chapter_get_title (MgMangaChapter *self);
|
||||
char *
|
||||
mg_manga_chapter_get_url (MgMangaChapter *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
6
include/openmg/view/chapter_view.h
Normal file
6
include/openmg/view/chapter_view.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
void
|
||||
setup_chapter_view (MgMangaChapter *chapter, AdwLeaflet *views_leaflet);
|
@ -1,4 +1,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include <openmg/manga.h>
|
||||
|
||||
GtkBox *
|
||||
create_detail_view (MgManga *manga);
|
||||
create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet);
|
||||
|
@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include <openmg/manga.h>
|
||||
|
||||
GtkListView *
|
||||
create_list_view_chapters (MgManga *manga);
|
||||
create_list_view_chapters (MgManga *manga, AdwLeaflet *views_leaflet);
|
||||
|
@ -12,6 +12,7 @@ openmgdeps = [
|
||||
]
|
||||
|
||||
sources = [
|
||||
'src/view/chapter_view.c',
|
||||
'src/view/list_view_chapter.c',
|
||||
'src/view/picture.c',
|
||||
'src/util/gobject_utility_extensions.c',
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
|
||||
#include <openmg/backend/readmng.h>
|
||||
@ -57,6 +58,12 @@ static MgMangaChapter *
|
||||
mg_backend_readmng_loop_li_chapter (
|
||||
MgBackendReadmng *self,
|
||||
xmlNodePtr li);
|
||||
static GListModel *
|
||||
mg_backend_readmng_parse_page (MgBackendReadmng *self,
|
||||
xmlDocPtr html_document);
|
||||
static xmlDocPtr
|
||||
mg_backend_readmng_fetch_page_url (MgBackendReadmng *self,
|
||||
MgMangaChapter *chapter);
|
||||
static GListStore *
|
||||
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
|
||||
xmlDocPtr html_document_details);
|
||||
@ -147,6 +154,67 @@ mg_backend_readmng_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
GListModel *
|
||||
mg_backend_readmng_get_chapter_images (MgBackendReadmng *self, MgMangaChapter *chapter) {
|
||||
GListModel *images;
|
||||
xmlDocPtr html_document;
|
||||
html_document = mg_backend_readmng_fetch_page_url (self, chapter);
|
||||
images = mg_backend_readmng_parse_page (self, html_document);
|
||||
|
||||
xmlFreeDoc (html_document);
|
||||
return images;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
mg_backend_readmng_parse_page (MgBackendReadmng *self,
|
||||
xmlDocPtr html_document) {
|
||||
GListModel *images = G_LIST_MODEL
|
||||
(gtk_string_list_new (NULL));
|
||||
|
||||
MgUtilXML *xml_utils = self->xml_utils;
|
||||
xmlXPathObjectPtr xpath_result = NULL;
|
||||
xmlNodeSetPtr node_set = NULL;
|
||||
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
|
||||
html_document, "//img[@class]");
|
||||
node_set = xpath_result->nodesetval;
|
||||
if (!node_set) {
|
||||
fprintf(stderr, "No match for images.\n");
|
||||
return images;
|
||||
}
|
||||
for (int i = 0; i < node_set->nodeNr; i++) {
|
||||
xmlNodePtr node = node_set->nodeTab[i];
|
||||
const char *image_url = mg_util_xml_get_attr (xml_utils, node, "src");
|
||||
gtk_string_list_append (GTK_STRING_LIST (images), (void *)image_url);
|
||||
}
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
static xmlDocPtr
|
||||
mg_backend_readmng_fetch_page_url (MgBackendReadmng *self,
|
||||
MgMangaChapter *chapter) {
|
||||
size_t response_len = 0;
|
||||
MgUtilSoup *util_soup = mg_util_soup_new ();
|
||||
char *url = mg_manga_chapter_get_url (chapter);
|
||||
size_t concat_all_pages_len;
|
||||
char *concated_url;
|
||||
|
||||
concat_all_pages_len = snprintf (NULL, 0, "%s/all-pages", url);
|
||||
concated_url = g_malloc
|
||||
(sizeof *concated_url * (concat_all_pages_len + 1));
|
||||
snprintf (concated_url, concat_all_pages_len + 1,
|
||||
"%s/all-pages", url);
|
||||
|
||||
const char *html_response = mg_util_soup_get_request (util_soup, concated_url,
|
||||
&response_len);
|
||||
return htmlReadMemory (html_response, response_len,
|
||||
NULL, NULL,
|
||||
HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD
|
||||
| HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING );
|
||||
|
||||
}
|
||||
|
||||
|
||||
GListStore *
|
||||
mg_backend_readmng_get_featured_manga (MgBackendReadmng *self) {
|
||||
GListStore *mangas;
|
||||
@ -175,10 +243,10 @@ mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
|
||||
if (mg_manga_has_details (manga)) {
|
||||
goto cleanup_mg_backend_readmng_retrieve_manga_details;
|
||||
}
|
||||
|
||||
|
||||
xml_utils = self->xml_utils;
|
||||
html_document = mg_backend_readmng_fetch_xml_details (self,
|
||||
manga);
|
||||
manga);
|
||||
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
|
||||
html_document, "//li[@class]");
|
||||
node_set = xpath_result->nodesetval;
|
||||
@ -205,7 +273,7 @@ cleanup_mg_backend_readmng_retrieve_manga_details:
|
||||
static GListStore *
|
||||
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
|
||||
xmlDocPtr html_document_details) {
|
||||
MgUtilXML *xml_utils = self->xml_utils;
|
||||
MgUtilXML *xml_utils = self->xml_utils;
|
||||
xmlXPathObjectPtr xpath_result = NULL;
|
||||
xmlNodeSetPtr node_set = NULL;
|
||||
xmlNodePtr *uls = NULL;
|
||||
|
@ -160,3 +160,11 @@ mg_manga_chapter_get_title (MgMangaChapter *self) {
|
||||
g_object_get_property (G_OBJECT (self), "title", &value);
|
||||
return g_value_dup_string (&value);
|
||||
}
|
||||
|
||||
char *
|
||||
mg_manga_chapter_get_url (MgMangaChapter *self) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_object_get_property (G_OBJECT (self), "url", &value);
|
||||
return g_value_dup_string (&value);
|
||||
}
|
||||
|
64
src/view/chapter_view.c
Normal file
64
src/view/chapter_view.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <openmg/chapter.h>
|
||||
#include <openmg/view/chapter_view.h>
|
||||
#include <openmg/view/picture.h>
|
||||
#include <openmg/util/gobject_utility_extensions.h>
|
||||
#include <openmg/util/string.h>
|
||||
#include <openmg/backend/readmng.h>
|
||||
|
||||
static void
|
||||
fire_zoom (GtkGestureZoom *zoom,
|
||||
gdouble scale,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct {
|
||||
guint current_page;
|
||||
GListModel *pages;
|
||||
GtkPicture *current_picture;
|
||||
} ChapterVisorData;
|
||||
void
|
||||
setup_chapter_view (MgMangaChapter *chapter, AdwLeaflet *views_leaflet) {
|
||||
MgBackendReadmng *readmng = mg_backend_readmng_new ();
|
||||
MgUtilString *string_util = mg_util_string_new ();
|
||||
GtkBox *chapter_view_container = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
|
||||
GtkScrolledWindow *zoomable_picture_container = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new ());
|
||||
GtkGesture *zoom_controller = gtk_gesture_zoom_new ();
|
||||
GListModel *pages = mg_backend_readmng_get_chapter_images (readmng, chapter);
|
||||
ChapterVisorData *chapter_visor_data = g_malloc (sizeof *chapter_visor_data);
|
||||
GtkPicture *current_picture;
|
||||
chapter_visor_data->current_page = 0;
|
||||
chapter_visor_data->pages = pages;
|
||||
const char *url_image_not_owned =
|
||||
gtk_string_list_get_string (GTK_STRING_LIST
|
||||
(pages), 0);
|
||||
char *url_image = mg_util_string_alloc_string (string_util, strlen (url_image_not_owned));
|
||||
mg_util_string_copy_substring (string_util,
|
||||
url_image_not_owned, url_image,
|
||||
strlen(url_image_not_owned) + 1, 0,
|
||||
strlen (url_image_not_owned));
|
||||
|
||||
current_picture = create_picture_from_url
|
||||
(url_image, 200);
|
||||
g_object_set_property_int (G_OBJECT (current_picture), "vexpand", 1);
|
||||
g_object_set_property_int (G_OBJECT (current_picture), "hexpand", 1);
|
||||
chapter_visor_data->current_picture =
|
||||
current_picture;
|
||||
gtk_scrolled_window_set_child (zoomable_picture_container, GTK_WIDGET (current_picture));
|
||||
|
||||
|
||||
gtk_widget_add_controller (GTK_WIDGET (zoomable_picture_container),
|
||||
GTK_EVENT_CONTROLLER (zoom_controller));
|
||||
g_signal_connect (G_OBJECT (zoom_controller), "scale-changed", G_CALLBACK (fire_zoom), NULL);
|
||||
|
||||
gtk_box_append (chapter_view_container, GTK_WIDGET (zoomable_picture_container));
|
||||
adw_leaflet_append (views_leaflet, GTK_WIDGET (chapter_view_container));
|
||||
adw_leaflet_navigate (views_leaflet, ADW_NAVIGATION_DIRECTION_FORWARD);
|
||||
}
|
||||
|
||||
static void
|
||||
fire_zoom (GtkGestureZoom *zoom,
|
||||
gdouble scale,
|
||||
gpointer user_data) {
|
||||
// Do something.
|
||||
}
|
@ -48,7 +48,7 @@ toggle_folded (GtkButton *toggle_folded_button,
|
||||
}
|
||||
|
||||
GtkBox *
|
||||
create_detail_view (MgManga *manga) {
|
||||
create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet) {
|
||||
MgBackendReadmng *readmng = mg_backend_readmng_new ();
|
||||
GtkWidget *scroll;
|
||||
GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
|
||||
@ -73,7 +73,7 @@ create_detail_view (MgManga *manga) {
|
||||
g_object_set_property_int (G_OBJECT (scroll), "vexpand", 1);
|
||||
|
||||
mg_backend_readmng_retrieve_manga_details (readmng, manga);
|
||||
chapter_list = create_list_view_chapters (manga);
|
||||
chapter_list = create_list_view_chapters (manga, views_leaflet);
|
||||
|
||||
|
||||
g_signal_connect (G_OBJECT (toggle_folded_button), "clicked", G_CALLBACK (toggle_folded), foldable_manga_data);
|
||||
|
@ -4,14 +4,17 @@
|
||||
#include <openmg/chapter.h>
|
||||
#include <openmg/backend/readmng.h>
|
||||
#include <openmg/view/list_view_chapter.h>
|
||||
#include <openmg/view/chapter_view.h>
|
||||
|
||||
static void
|
||||
activate_chapter (GtkListView *list_view, guint position, gpointer user_data);
|
||||
static void
|
||||
setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item,
|
||||
gpointer user_data);
|
||||
|
||||
GtkListView *
|
||||
create_list_view_chapters (MgManga *manga) {
|
||||
create_list_view_chapters (MgManga *manga, AdwLeaflet *views_leaflet) {
|
||||
GListStore *manga_chapter_list = NULL;
|
||||
GtkListView *list_view_chapters = NULL;
|
||||
GtkSingleSelection *selection = NULL;
|
||||
@ -28,6 +31,9 @@ create_list_view_chapters (MgManga *manga) {
|
||||
|
||||
list_view_chapters = GTK_LIST_VIEW (gtk_list_view_new (GTK_SELECTION_MODEL (selection),
|
||||
factory));
|
||||
gtk_list_view_set_single_click_activate (list_view_chapters, 1);
|
||||
g_signal_connect (G_OBJECT (list_view_chapters), "activate",
|
||||
G_CALLBACK (activate_chapter), views_leaflet);
|
||||
|
||||
return list_view_chapters;
|
||||
}
|
||||
@ -47,3 +53,13 @@ setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
|
||||
gtk_box_append (box, GTK_WIDGET (title));
|
||||
gtk_list_item_set_child (list_item, GTK_WIDGET (box));
|
||||
}
|
||||
|
||||
static void
|
||||
activate_chapter (GtkListView *list_view, guint position, gpointer user_data) {
|
||||
GtkSingleSelection *selection = GTK_SINGLE_SELECTION
|
||||
(gtk_list_view_get_model (list_view));
|
||||
GListModel *chapters = gtk_single_selection_get_model (selection);
|
||||
MgMangaChapter *chapter = MG_MANGA_CHAPTER (g_list_model_get_item (chapters, position));
|
||||
AdwLeaflet *views_leaflet = ADW_LEAFLET (user_data);
|
||||
setup_chapter_view (chapter, views_leaflet);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ manga_selected (GtkListView *list_view,
|
||||
ADW_NAVIGATION_DIRECTION_FORWARD);
|
||||
}
|
||||
|
||||
GtkBox *detail_view = create_detail_view (manga);
|
||||
GtkBox *detail_view = create_detail_view (manga, views_leaflet);
|
||||
adw_leaflet_append (views_leaflet, GTK_WIDGET (detail_view));
|
||||
adw_leaflet_navigate (views_leaflet, ADW_NAVIGATION_DIRECTION_FORWARD);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user