📄 html.c
字号:
/*************************************************************************** * Copyright (C) 2003 by zhong * * zhongz@163.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/#include <stdio.h>#include <dirent.h>#include <unistd.h>#include <sys/mman.h>#include <sys/types.h>#include <fcntl.h>#include <sys/stat.h>#include <string.h>#include <gtk/gtk.h>#include <libgnomevfs/gnome-vfs-utils.h>#include <gdk/gdk.h>#include <gtkhtml/gtkhtml.h>#include <gtkhtml/gtkhtml-stream.h>//#include <gtkhtml/htmlengine.h>#include "interface.h"#include "html.h"#include "menu_popup.h"static void chmsee_html_url_requested( GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data );static void chmsee_html_load_done( GtkWidget *html );static void chmsee_html_refresh( GtkWidget *html );static void chmsee_add_list (ChmSee *window, gchar *url, gint i);// static void chmsee_html_set_base (GtkWidget *html, const gchar *url);static void open_uri_errord();static void open_uri_errord(){ GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "这是一个错误连接"); g_signal_connect_swapped (GTK_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), GTK_OBJECT (dialog)); gtk_widget_show (dialog);}static void chmsee_html_url_requested (GtkHTML *html, const char *full_link, GtkHTMLStream *stream, gpointer data){ int fp; gchar *buffer; struct stat stbuf; gchar *conv_html_utf = NULL; gchar *s; ChmSee *window = (ChmSee *) data; s = g_strrstr(g_strdown(g_path_get_basename(full_link)) , "."); if (s) { if (g_strcasecmp(".htm", s) == 0 || g_strcasecmp(".html", s) == 0) { if (!lstat (full_link, &stbuf)) { if (opendir (full_link)) { } else if (opendir (full_link) == NULL && (fp = open (full_link, O_RDONLY | O_NONBLOCK))) { const gchar *utf8 = "UTF-8"; buffer = (gchar *) mmap (NULL, stbuf.st_size, PROT_READ, MAP_SHARED, fp, 0); if (g_strcasecmp("NONE", window->current_codeset) == 0 ) { conv_html_utf = g_strdup( buffer ); } else { conv_html_utf = g_convert(buffer, -1, utf8, window->current_codeset, NULL, NULL, NULL); } if (conv_html_utf) { gtk_html_write (GTK_HTML (html), stream, conv_html_utf, -1); } else { gtk_html_write (GTK_HTML (html), stream, buffer, stbuf.st_size); } close (fp); munmap (buffer, stbuf.st_size); gtk_html_end (GTK_HTML (html), stream, GTK_HTML_STREAM_OK); g_free(conv_html_utf); } } } else if (g_strcasecmp(".gif", s) == 0 || g_strcasecmp(".jpg", s) == 0 || g_strcasecmp(".jpeg", s) == 0 || g_strcasecmp(".png", s) == 0 || g_strcasecmp(".bmp", s) == 0) { gchar *strdown; strdown = g_convert(full_link, -1, "GB18030", "UTF-8", NULL, NULL, NULL); if (strdown) { full_link = (const char *) strdown; } full_link = (const gchar *) g_strdown((gchar *) full_link); if (!lstat (full_link, &stbuf)) { if (opendir (full_link)) { } else if (opendir (full_link) == NULL && (fp = open (full_link, O_RDONLY | O_NONBLOCK))) { buffer = (gchar *) mmap (NULL, stbuf.st_size, PROT_READ, MAP_SHARED, fp, 0); gtk_html_write (GTK_HTML (html), stream, buffer, stbuf.st_size); close (fp); munmap (buffer, stbuf.st_size); gtk_html_end (GTK_HTML (html), stream, GTK_HTML_STREAM_OK); } } } }}void on_chm_big (GtkWidget *widget, ChmSee *window) { gtk_html_zoom_in( GTK_HTML( window->chm_html ) );}void on_chm_reset (GtkWidget *widget, ChmSee *window) { gtk_html_zoom_reset( GTK_HTML( window->chm_html ) );}void on_chm_small (GtkWidget *widget, ChmSee *window) { gtk_html_zoom_out( GTK_HTML( window->chm_html ) );}static voidchmsee_html_load_done ( GtkWidget *html ){ gtk_widget_grab_focus ( GTK_WIDGET( html ) );}static void chmsee_html_refresh (GtkWidget *html) { gtk_widget_draw ( GTK_WIDGET( html ), NULL );}// chmsee_add_list 函数功能未完善 .....static void chmsee_add_list (ChmSee *window, gchar *url, gint i) { gchar *conv_url; conv_url = g_convert(url, -1, "UTF-8", "GB18030", NULL, NULL, NULL); if ( i == 0 ) { window->link = g_list_append (window->link, conv_url); window->link_pos = g_list_length (window->link); } else if ( i == 1 ) { GList *list = NULL; list = g_list_nth(window->link, g_list_length(window->link) - 1); g_list_delete_link(window->link, list); window->link = g_list_append (window->link, conv_url); window->link_pos = g_list_length (window->link); } if (window->link_pos > 1) { gtk_widget_set_sensitive (window->chm_back, TRUE); } else { gtk_widget_set_sensitive (window->chm_back, FALSE); } if (window->link_pos == g_list_length (window->link) ) { gtk_widget_set_sensitive (window->chm_forward, FALSE); } else { gtk_widget_set_sensitive (window->chm_forward, TRUE); }}/*static void chmsee_html_set_base (GtkWidget *html, const gchar *url) {}*/gchar *chmsee_conv_uri(gchar *uri) { gchar *url; gchar *conv_url; url = g_strdup_printf("file://%s", uri); conv_url = gnome_vfs_get_local_path_from_uri(url); g_free(url); return (conv_url);}static gchar *chmsee_html_split_uri (const gchar *uri, gchar **anchor){ gchar *ret_val; gchar *ch; if ((ch = strchr (uri, '?')) || (ch = strchr (uri, '#'))) { if (anchor) { *anchor = g_strdup (ch + 1); } ret_val = g_strndup (uri, ch - uri); } else { ret_val = g_strdup (uri); } return ret_val;}voidchm_html_open_uri (ChmSee *window, const gchar *str_uri, gint i){ GtkHTML *html = (GtkHTML *) window->chm_html; gchar *full_link; const gchar *set_base; gchar *anchor = NULL; gchar *conv_link; full_link = chmsee_html_split_uri(str_uri, &anchor); if (window->current_link) { if (g_strcasecmp (window->current_link, full_link) == 0 ) { if (anchor) { gtk_html_jump_to_anchor (GTK_HTML(html), anchor); } return; } } conv_link = g_strdup(chmsee_conv_uri(full_link)); if (!g_file_test (g_strdown(conv_link), G_FILE_TEST_EXISTS)) { open_uri_errord(); g_free (anchor); g_free (full_link); g_free (conv_link); return; } GdkCursor *cursor; cursor = gdk_cursor_new (GDK_WATCH); gdk_window_set_cursor (window->chm_html->window, cursor); gdk_cursor_unref (cursor); chmsee_add_list(window, (gchar *)str_uri, i); GtkHTMLStream *handle; handle = gtk_html_begin_content (GTK_HTML(html), "text/html; charset=utf-8"); set_base = g_strdup_printf("%s/", g_path_get_dirname(conv_link)); gtk_html_set_base (GTK_HTML(html), set_base); window->current_link = g_strdup(str_uri); chmsee_html_url_requested (GTK_HTML (html), g_strdown(conv_link), handle, window); if (anchor) { gtk_html_jump_to_anchor (GTK_HTML(html), anchor); } gdk_window_set_cursor (window->chm_html->window, NULL);}void on_chm_back( GtkWidget *widget, gpointer data ){ ChmSee *window = (ChmSee *) data; GList *list = NULL; gchar *url; window->link_pos--; list = g_list_nth(window->link, window->link_pos-1); url = g_convert((const gchar *) list->data, -1, "GB18030", "UTF-8", NULL, NULL, NULL); chm_html_open_uri(window, url, 2);}void on_chm_forward( GtkWidget *widget, gpointer data ){ ChmSee *window = (ChmSee *) data; GList *list = NULL; gchar *url; window->link_pos++; list = g_list_nth(window->link, window->link_pos-1); url = g_convert((const gchar *) list->data, -1, "GB18030", "UTF-8", NULL, NULL, NULL); chm_html_open_uri(window, url, 2);}voidchmsee_html_link_clicked (GtkWidget *html, const gchar *url, gpointer data){ ChmSee *window = (ChmSee *) data; gchar *full_link = NULL; gchar *s; gchar *anchor = NULL; gchar *str; gint i; full_link = chmsee_html_split_uri(url, &anchor); s = g_strrstr(g_strdown(g_path_get_basename(full_link)) , "."); if (s) { if (g_strcasecmp(".htm", s) == 0 || g_strcasecmp(".html", s) == 0) { str = g_strndup(full_link, strlen(window->tmpdir)); if (g_strcasecmp(window->tmpdir, str) == 0) { if (window->link_pos == g_list_length(window->link)-1) { i = 1; } else { i = 0; } full_link = g_convert(url, -1, "GB18030", "UTF-8", NULL, NULL, NULL); if (full_link) { chm_html_open_uri (window, (const gchar *)full_link, i); } else { chm_html_open_uri (window, url, i); } } } } else { if (anchor) { gtk_html_jump_to_anchor (GTK_HTML(html), anchor); } }}voidchmsee_html_reload (ChmSee *window, const gchar *str_uri){ GtkHTML *html = (GtkHTML *) window->chm_html; gchar *full_link; gchar *anchor = NULL;; gchar *conv_link; if (str_uri) { full_link = chmsee_html_split_uri(str_uri, &anchor); GtkHTMLStream *handle; handle = gtk_html_begin_content (GTK_HTML(html), "text/html; charset=utf-8"); conv_link = g_strdup(chmsee_conv_uri(full_link)); chmsee_html_url_requested (GTK_HTML (html), g_strdown(conv_link), handle, window); if (anchor) { gtk_html_jump_to_anchor (GTK_HTML(html), anchor); } }}gboolean chmsee_html_button_pressed (GtkWidget *widget, GdkEventButton *event, ChmSee *window){ if (event->type == GDK_BUTTON_PRESS) { if (event->button == 3) { chmsee_menu_popup (event, window); } } return FALSE;}void chmsee_html_load_empty(ChmSee *window) { gtk_html_load_empty( GTK_HTML( window->chm_html ) );}// void chmsee_html_on_url (GtkWidget *html, const gchar *url) {// g_print("on_url ->%s\n", url);// } GtkWidget* chmsee_html_view_new(void){ GtkWidget *html; html = gtk_html_new(); gtk_html_set_allow_frameset (GTK_HTML(html), TRUE); g_signal_connect (GTK_OBJECT(html), "load_done", G_CALLBACK(chmsee_html_load_done), NULL); g_signal_connect (GTK_OBJECT(html), "size_changed", G_CALLBACK(chmsee_html_refresh), NULL); g_signal_connect (GTK_OBJECT(html), "url_requested", G_CALLBACK (chmsee_html_url_requested), NULL); // g_signal_connect (GTK_OBJECT(html), "set_base",G_CALLBACK (chmsee_html_set_base), NULL);// g_signal_connect (GTK_OBJECT(html), "on_url", G_CALLBACK (chmsee_html_on_url), NULL); return (html);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -