diff options
author | Vincent Sanders <vince@kyllikki.org> | 2014-08-01 00:58:42 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2014-08-01 01:00:13 +0100 |
commit | 58eea873f875b58050a01478b4aaed0d75135e9a (patch) | |
tree | 50c532e971a097a756b7391de97960316b957ae8 /gtk | |
parent | 43fea75b7290cdcbfafa8e159dc3832581352755 (diff) | |
download | netsurf-58eea873f875b58050a01478b4aaed0d75135e9a.tar.gz netsurf-58eea873f875b58050a01478b4aaed0d75135e9a.tar.bz2 |
rationalise source view
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.target | 4 | ||||
-rw-r--r-- | gtk/dialogs/source.c | 536 | ||||
-rw-r--r-- | gtk/gui.c | 6 | ||||
-rw-r--r-- | gtk/gui.h | 1 | ||||
-rw-r--r-- | gtk/options.h | 3 | ||||
-rw-r--r-- | gtk/res/viewdata.gtk2.ui (renamed from gtk/res/source.gtk2.ui) | 28 | ||||
-rw-r--r-- | gtk/res/viewdata.gtk3.ui (renamed from gtk/res/source.gtk3.ui) | 64 | ||||
-rw-r--r-- | gtk/scaffolding.c | 5 | ||||
-rw-r--r-- | gtk/viewdata.c | 569 | ||||
-rw-r--r-- | gtk/viewdata.h | 36 | ||||
-rw-r--r-- | gtk/viewsource.c | 81 | ||||
-rw-r--r-- | gtk/viewsource.h (renamed from gtk/dialogs/source.h) | 11 |
12 files changed, 750 insertions, 594 deletions
diff --git a/gtk/Makefile.target b/gtk/Makefile.target index ec19d1b36..f69a73a95 100644 --- a/gtk/Makefile.target +++ b/gtk/Makefile.target @@ -110,8 +110,8 @@ S_GTK := font_pango.c bitmap.c gui.c schedule.c thumbnail.c plotters.c \ treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \ selection.c history.c window.c fetch.c download.c menu.c \ print.c search.c tabs.c theme.c toolbar.c gettext.c \ - compat.c cookies.c hotlist.c \ - $(addprefix dialogs/,preferences.c about.c source.c) + compat.c cookies.c hotlist.c viewdata.c viewsource.c \ + $(addprefix dialogs/,preferences.c about.c) S_GTK := $(addprefix gtk/,$(S_GTK)) $(addprefix utils/,container.c) # code in utils/container.ch is non-universal it seems diff --git a/gtk/dialogs/source.c b/gtk/dialogs/source.c deleted file mode 100644 index 8e4e43333..000000000 --- a/gtk/dialogs/source.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright 2009 Mark Benjamin <MarkBenjamin@dfgh.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf 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; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <string.h> -#include <gtk/gtk.h> - -#include "utils/log.h" -#include "utils/nsoption.h" -#include "utils/utf8.h" -#include "utils/messages.h" -#include "utils/url.h" -#include "utils/utils.h" -#include "utils/file.h" -#include "desktop/netsurf.h" -#include "desktop/browser.h" -#include "render/html.h" -#include "content/hlcache.h" -#include "content/content.h" - -#include "gtk/dialogs/about.h" -#include "gtk/fetch.h" -#include "gtk/compat.h" -#include "gtk/gui.h" -#include "gtk/dialogs/source.h" - -struct nsgtk_source_window { - gchar *url; - char *data; - size_t data_len; - GtkWindow *sourcewindow; - GtkTextView *gv; - struct browser_window *bw; - struct nsgtk_source_window *next; - struct nsgtk_source_window *prev; -}; - -struct menu_events { - const char *widget; - GCallback handler; -}; - -static GtkBuilder *glade_File; -static struct nsgtk_source_window *nsgtk_source_list = 0; -static char source_zoomlevel = 10; - -#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } -#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \ - GtkMenuItem *widget, gpointer g) - -MENUPROTO(source_save_as); -MENUPROTO(source_print); -MENUPROTO(source_close); -MENUPROTO(source_select_all); -MENUPROTO(source_cut); -MENUPROTO(source_copy); -MENUPROTO(source_paste); -MENUPROTO(source_delete); -MENUPROTO(source_zoom_in); -MENUPROTO(source_zoom_out); -MENUPROTO(source_zoom_normal); -MENUPROTO(source_about); - -static struct menu_events source_menu_events[] = { -MENUEVENT(source_save_as), -MENUEVENT(source_print), -MENUEVENT(source_close), -MENUEVENT(source_select_all), -MENUEVENT(source_cut), -MENUEVENT(source_copy), -MENUEVENT(source_paste), -MENUEVENT(source_delete), -MENUEVENT(source_zoom_in), -MENUEVENT(source_zoom_out), -MENUEVENT(source_zoom_normal), -MENUEVENT(source_about), -{NULL, NULL} -}; - -static void nsgtk_attach_source_menu_handlers(GtkBuilder *xml, gpointer g) -{ - struct menu_events *event = source_menu_events; - - while (event->widget != NULL) - { - GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(xml, event->widget)); - g_signal_connect(G_OBJECT(w), "activate", event->handler, g); - event++; - } -} - -static gboolean nsgtk_source_destroy_event(GtkBuilder *window, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - - if (nsg->next != NULL) - nsg->next->prev = nsg->prev; - - if (nsg->prev != NULL) - nsg->prev->next = nsg->next; - else - nsgtk_source_list = nsg->next; - - free(nsg->data); - free(nsg->url); - free(g); - - return FALSE; -} - -static gboolean nsgtk_source_delete_event(GtkWindow * window, gpointer g) -{ - return FALSE; -} - - -static nserror -nsgtk_source_win_init(GtkWindow *parent, struct browser_window *bw) -{ - char glade_Location[strlen(res_dir_location) + SLEN("source.gtk2.ui") + 1]; - - struct hlcache_handle *hlcontent; - GError* error = NULL; - const char *source_data; - unsigned long source_size; - char *data = NULL; - size_t data_len; - nserror ret; - GtkWindow *wndSource; - GtkWidget *cutbutton; - GtkWidget *pastebutton; - GtkWidget *deletebutton; - GtkWidget *printbutton; - GtkTextView *sourceview; - PangoFontDescription *fontdesc; - GtkTextBuffer *tb; - struct nsgtk_source_window *thiswindow; - - hlcontent = browser_window_get_content(bw); - if (hlcontent == NULL) { - return NSERROR_OK; - } - - if (content_get_type(hlcontent) != CONTENT_HTML) { - return NSERROR_OK; - } - - sprintf(glade_Location, "%ssource.gtk2.ui", res_dir_location); - - glade_File = gtk_builder_new(); - if (!gtk_builder_add_from_file(glade_File, glade_Location, &error)) { - g_warning ("Couldn't load builder file: %s", error->message); - g_error_free (error); - LOG(("error loading glade tree")); - return NSERROR_OK; - } - - source_data = content_get_source_data(hlcontent, &source_size); - - ret = utf8_from_enc(source_data, - html_get_encoding(hlcontent), - source_size, - &data, - &data_len); - if (ret != NSERROR_OK) { - return ret; - } - - wndSource = GTK_WINDOW(gtk_builder_get_object(glade_File, "wndSource")); - cutbutton = GTK_WIDGET(gtk_builder_get_object(glade_File, "source_cut")); - pastebutton = GTK_WIDGET(gtk_builder_get_object(glade_File, "source_paste")); - deletebutton = GTK_WIDGET(gtk_builder_get_object(glade_File, "source_delete")); - printbutton = GTK_WIDGET(gtk_builder_get_object(glade_File, "source_print")); - gtk_widget_set_sensitive(cutbutton, FALSE); - gtk_widget_set_sensitive(pastebutton, FALSE); - gtk_widget_set_sensitive(deletebutton, FALSE); - /* for now */ - gtk_widget_set_sensitive(printbutton, FALSE); - - thiswindow = malloc(sizeof(struct nsgtk_source_window)); - if (thiswindow == NULL) { - free(data); - return NSERROR_NOMEM; - } - - thiswindow->url = strdup(nsurl_access(browser_window_get_url(bw))); - if (thiswindow->url == NULL) { - free(thiswindow); - free(data); - return NSERROR_NOMEM; - } - - thiswindow->data = data; - thiswindow->data_len = data_len; - - thiswindow->sourcewindow = wndSource; - thiswindow->bw = bw; - - char title[strlen(thiswindow->url) + SLEN("Source of - NetSurf") + 1]; - sprintf(title, "Source of %s - NetSurf", thiswindow->url); - - thiswindow->next = nsgtk_source_list; - thiswindow->prev = NULL; - if (nsgtk_source_list != NULL) { - nsgtk_source_list->prev = thiswindow; - } - nsgtk_source_list = thiswindow; - - nsgtk_attach_source_menu_handlers(glade_File, thiswindow); - - gtk_window_set_title(wndSource, title); - - g_signal_connect(G_OBJECT(wndSource), "destroy", - G_CALLBACK(nsgtk_source_destroy_event), - thiswindow); - g_signal_connect(G_OBJECT(wndSource), "delete-event", - G_CALLBACK(nsgtk_source_delete_event), - thiswindow); - - sourceview = GTK_TEXT_VIEW( - gtk_builder_get_object(glade_File, - "source_view")); - - fontdesc = pango_font_description_from_string("Monospace 8"); - - thiswindow->gv = sourceview; - nsgtk_widget_modify_font(GTK_WIDGET(sourceview), fontdesc); - - tb = gtk_text_view_get_buffer(sourceview); - gtk_text_buffer_set_text(tb, thiswindow->data, -1); - - gtk_widget_show(GTK_WIDGET(wndSource)); - - return NSERROR_OK; -} - -/** - * create a new tab with page source - */ -static nserror -nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw) -{ - const char *source_data; - unsigned long source_size; - char *ndata = NULL; - size_t ndata_len; - nsurl *url; - nserror ret; - gchar *filename; - gint handle; - struct hlcache_handle *hlcontent; - FILE *f; - - hlcontent = browser_window_get_content(bw); - if (hlcontent == NULL) { - return NSERROR_OK; - } - - if (content_get_type(hlcontent) != CONTENT_HTML) { - return NSERROR_OK; - } - - source_data = content_get_source_data(hlcontent, &source_size); - - ret = utf8_from_enc(source_data, - html_get_encoding(hlcontent), - source_size, - &ndata, - &ndata_len); - if (ret != NSERROR_OK) { - return ret; - } - - handle = g_file_open_tmp("nsgtksourceXXXXXX", &filename, NULL); - if ((handle == -1) || (filename == NULL)) { - warn_user(messages_get("gtkSourceTabError"), 0); - free(ndata); - return NSERROR_SAVE_FAILED; - } - close(handle); /* in case it was binary mode */ - - f = fopen(filename, "w"); - if (f == NULL) { - warn_user(messages_get("gtkSourceTabError"), 0); - g_free(filename); - free(ndata); - return NSERROR_SAVE_FAILED; - } - fprintf(f, "%s", ndata); - fclose(f); - free(ndata); - - /* Open tab */ - ret = netsurf_path_to_nsurl(filename, &url); - g_free(filename); - if (ret == NSERROR_OK) { - ret = browser_window_create(BW_CREATE_TAB, - url, NULL, NULL, NULL); - nsurl_unref(url); - } - - return ret; -} - -void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw) -{ - nserror ret; - - if (nsoption_bool(source_tab)) { - ret = nsgtk_source_tab_init(parent, bw); - } else { - ret = nsgtk_source_win_init(parent, bw); - } - if (ret != NSERROR_OK) { - warn_user(messages_get_errorcode(ret), 0); - } -} - -static void nsgtk_source_file_save(GtkWindow *parent, const char *filename, - const char *data, size_t data_size) -{ - FILE *f; - GtkWidget *notif; - GtkWidget *label; - - f = fopen(filename, "w+"); - if (f != NULL) { - fwrite(data, data_size, 1, f); - fclose(f); - return; - } - - /* inform user of faliure */ - notif = gtk_dialog_new_with_buttons(messages_get("gtkSaveFailedTitle"), - parent, - GTK_DIALOG_MODAL, GTK_STOCK_OK, - GTK_RESPONSE_NONE, NULL); - - g_signal_connect_swapped(notif, "response", - G_CALLBACK(gtk_widget_destroy), notif); - - label = gtk_label_new(messages_get("gtkSaveFailed")); - gtk_container_add(GTK_CONTAINER(nsgtk_dialog_get_content_area(GTK_DIALOG(notif))), label); - gtk_widget_show_all(notif); - -} - - -gboolean nsgtk_on_source_save_as_activate(GtkMenuItem *widget, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - GtkWidget *fc = gtk_file_chooser_dialog_new( - messages_get("gtkSourceSave"), - nsg->sourcewindow, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, - GTK_RESPONSE_ACCEPT, - NULL); - char *filename; - nserror res; - - res = url_nice(nsg->url, &filename, false); - if (res != NSERROR_OK) { - filename = strdup(messages_get("SaveSource")); - if (filename == NULL) { - warn_user("NoMemory", 0); - return FALSE; - } - } - - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), filename); - - free(filename); - - gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), - TRUE); - - if (gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc)); - nsgtk_source_file_save(nsg->sourcewindow, filename, nsg->data, nsg->data_len); - g_free(filename); - } - - gtk_widget_destroy(fc); - - return TRUE; -} - - -gboolean nsgtk_on_source_print_activate( GtkMenuItem *widget, gpointer g) -{ - /* correct printing */ - - return TRUE; -} - -gboolean nsgtk_on_source_close_activate( GtkMenuItem *widget, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - - gtk_widget_destroy(GTK_WIDGET(nsg->sourcewindow)); - - return TRUE; -} - - - -gboolean nsgtk_on_source_select_all_activate (GtkMenuItem *widget, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - GtkTextBuffer *buf = gtk_text_view_get_buffer(nsg->gv); - GtkTextIter start, end; - - gtk_text_buffer_get_bounds(buf, &start, &end); - - gtk_text_buffer_select_range(buf, &start, &end); - - return TRUE; -} - -gboolean nsgtk_on_source_cut_activate(GtkMenuItem *widget, gpointer g) -{ - return TRUE; -} - -gboolean nsgtk_on_source_copy_activate(GtkMenuItem *widget, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(nsg->gv)); - - gtk_text_buffer_copy_clipboard(buf, - gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); - - return TRUE; -} - -gboolean nsgtk_on_source_paste_activate(GtkMenuItem *widget, gpointer g) -{ - return TRUE; -} - -gboolean nsgtk_on_source_delete_activate(GtkMenuItem *widget, gpointer g) -{ - return TRUE; -} - -static void nsgtk_source_update_zoomlevel(gpointer g) -{ - struct nsgtk_source_window *nsg; - GtkTextBuffer *buf; - GtkTextTagTable *tab; - GtkTextTag *tag; - - nsg = nsgtk_source_list; - while (nsg) { - if (nsg->gv) { - buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(nsg->gv)); - - tab = gtk_text_buffer_get_tag_table( - GTK_TEXT_BUFFER(buf)); - - tag = gtk_text_tag_table_lookup(tab, "zoomlevel"); - if (!tag) { - tag = gtk_text_tag_new("zoomlevel"); - gtk_text_tag_table_add(tab, GTK_TEXT_TAG(tag)); - } - - gdouble fscale = ((gdouble) source_zoomlevel) / 10; - - g_object_set(GTK_TEXT_TAG(tag), "scale", fscale, NULL); - - GtkTextIter start, end; - - gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buf), - &start, &end); - gtk_text_buffer_remove_all_tags(GTK_TEXT_BUFFER(buf), - &start, &end); - gtk_text_buffer_apply_tag(GTK_TEXT_BUFFER(buf), - GTK_TEXT_TAG(tag), &start, &end); - } - nsg = nsg->next; - } -} - -gboolean nsgtk_on_source_zoom_in_activate(GtkMenuItem *widget, gpointer g) -{ - source_zoomlevel++; - nsgtk_source_update_zoomlevel(g); - - return TRUE; -} - -gboolean nsgtk_on_source_zoom_out_activate(GtkMenuItem *widget, gpointer g) -{ - if (source_zoomlevel > 1) { - source_zoomlevel--; - nsgtk_source_update_zoomlevel(g); - } - - return TRUE; -} - - -gboolean nsgtk_on_source_zoom_normal_activate(GtkMenuItem *widget, gpointer g) -{ - source_zoomlevel = 10; - nsgtk_source_update_zoomlevel(g); - - return TRUE; -} - -gboolean nsgtk_on_source_about_activate(GtkMenuItem *widget, gpointer g) -{ - struct nsgtk_source_window *nsg = (struct nsgtk_source_window *) g; - - nsgtk_about_dialog_init(nsg->sourcewindow, netsurf_version); - - return TRUE; -} @@ -208,6 +208,11 @@ nsgtk_new_ui(char **respath, const char *name, GtkBuilder **pglade) if (pglade != NULL) { *pglade = builder; + } else { + /* release our reference to the builder if it is not + * being used. + */ + g_object_unref(G_OBJECT(builder)); } return filepath; @@ -237,6 +242,7 @@ nsgtk_init_glade(char **respath) glade_file_location->options = nsgtk_new_ui(respath, "options", NULL); glade_file_location->hotlist = nsgtk_new_ui(respath, "hotlist", NULL); glade_file_location->cookies = nsgtk_new_ui(respath, "cookies", NULL); + glade_file_location->viewdata = nsgtk_new_ui(respath, "viewdata", NULL); glade_file_location->warning = nsgtk_new_ui(respath, "warning", &gladeWarning); nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(gladeWarning, "wndWarning")); @@ -45,6 +45,7 @@ struct glade_file_location_s { char *history; char *hotlist; char *cookies; + char *viewdata; }; /** location of all glade files. */ diff --git a/gtk/options.h b/gtk/options.h index 612809eac..cdedbc6a7 100644 --- a/gtk/options.h +++ b/gtk/options.h @@ -68,6 +68,9 @@ NSOPTION_STRING(hotlist_path, NULL) /* open source views in a tab */ NSOPTION_BOOL(source_tab, false) +/* Developer information viewer display method */ +NSOPTION_INTEGER(developer_view, 0) + /* currently selected theme */ NSOPTION_INTEGER(current_theme, 0) diff --git a/gtk/res/source.gtk2.ui b/gtk/res/viewdata.gtk2.ui index 84c3e0cf5..c54545415 100644 --- a/gtk/res/source.gtk2.ui +++ b/gtk/res/viewdata.gtk2.ui @@ -2,7 +2,7 @@ <interface> <!-- interface-requires gtk+ 2.12 --> <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkWindow" id="wndSource"> + <object class="GtkWindow" id="ViewDataWindow"> <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> @@ -19,7 +19,7 @@ <object class="GtkMenu" id="menu1"> <property name="visible">True</property> <child> - <object class="GtkImageMenuItem" id="source_save_as"> + <object class="GtkImageMenuItem" id="viewdata_save_as"> <property name="label">gtk-save-as</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -28,7 +28,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_print"> + <object class="GtkImageMenuItem" id="viewdata_print"> <property name="label">gtk-print</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -42,7 +42,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_close"> + <object class="GtkImageMenuItem" id="viewdata_close"> <property name="label">gtk-close</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -62,7 +62,7 @@ <object class="GtkMenu" id="menu2"> <property name="visible">True</property> <child> - <object class="GtkImageMenuItem" id="source_select_all"> + <object class="GtkImageMenuItem" id="viewdata_select_all"> <property name="label">gtk-select-all</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -71,7 +71,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_cut"> + <object class="GtkImageMenuItem" id="viewdata_cut"> <property name="label">gtk-cut</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -79,7 +79,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_copy"> + <object class="GtkImageMenuItem" id="viewdata_copy"> <property name="label">gtk-copy</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -87,7 +87,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_paste"> + <object class="GtkImageMenuItem" id="viewdata_paste"> <property name="label">gtk-paste</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -95,7 +95,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_delete"> + <object class="GtkImageMenuItem" id="viewdata_delete"> <property name="label">gtk-delete</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -116,7 +116,7 @@ <object class="GtkMenu" id="menu4"> <property name="visible">True</property> <child> - <object class="GtkImageMenuItem" id="source_zoom_in"> + <object class="GtkImageMenuItem" id="viewdata_zoom_in"> <property name="label">gtk-zoom-in</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -125,7 +125,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_zoom_out"> + <object class="GtkImageMenuItem" id="viewdata_zoom_out"> <property name="label">gtk-zoom-out</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -134,7 +134,7 @@ </object> </child> <child> - <object class="GtkImageMenuItem" id="source_zoom_normal"> + <object class="GtkImageMenuItem" id="viewdata_zoom_normal"> <property name="label">gtk-zoom-100</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -155,7 +155,7 @@ <object class="GtkMenu" id="menu3"> <property name="visible">True</property> <child> - <object class="GtkImageMenuItem" id="source_about"> + <object class="GtkImageMenuItem" id="viewdata_about"> <property name="label">gtk-about</property> <property name="visible">True</property> <property name="use_underline">True</property> @@ -179,7 +179,7 @@ <property name="hscrollbar_policy">automatic</property> <property name="vscrollbar_policy">automatic</property> <child> - <object class="GtkTextView" id="source_view"> + <object class="GtkTextView" id="viewdata_view"> <property name="width_request">600</property> <property name="height_request">400</property> <property name="visible">True</property> diff --git a/gtk/res/source.gtk3.ui b/gtk/res/viewdata.gtk3.ui index b972315d3..e06aaf373 100644 --- a/gtk/res/source.gtk3.ui +++ b/gtk/res/viewdata.gtk3.ui @@ -37,34 +37,34 @@ </object> </child> <child> - <object class="GtkAction" id="source_select_all"> + <object class="GtkAction" id="viewdata_select_all"> <property name="stock_id" translatable="yes">gtk-select-all</property> - <property name="name">source_select_all</property> + <property name="name">viewdata_select_all</property> </object> <accelerator key="A" modifiers="GDK_CONTROL_MASK"/> </child> <child> - <object class="GtkAction" id="source_cut"> + <object class="GtkAction" id="viewdata_cut"> <property name="stock_id" translatable="yes">gtk-cut</property> - <property name="name">source_cut</property> + <property name="name">viewdata_cut</property> </object> </child> <child> - <object class="GtkAction" id="source_copy"> + <object class="GtkAction" id="viewdata_copy"> <property name="stock_id" translatable="yes">gtk-copy</property> - <property name="name">source_copy</property> + <property name="name">viewdata_copy</property> </object> </child> <child> - <object class="GtkAction" id="source_paste"> + <object class="GtkAction" id="viewdata_paste"> <property name="stock_id" translatable="yes">gtk-paste</property> - <property name="name">source_paste</property> + <property name="name">viewdata_paste</property> </object> </child> <child> - <object class="GtkAction" id="source_delete"> + <object class="GtkAction" id="viewdata_delete"> <property name="stock_id" translatable="yes">gtk-delete</property> - <property name="name">source_delete</property> + <property name="name">viewdata_delete</property> </object> <accelerator key="Delete" modifiers=""/> </child> @@ -75,23 +75,23 @@ </object> </child> <child> - <object class="GtkAction" id="source_zoom_in"> + <object class="GtkAction" id="viewdata_zoom_in"> <property name="stock_id" translatable="yes">gtk-zoom-in</property> - <property name="name">source_zoom_in</property> + <property name="name">viewdata_zoom_in</property> </object> <accelerator key="plus" modifiers="GDK_CONTROL_MASK"/> </child> <child> - <object class="GtkAction" id="source_zoom_out"> + <object class="GtkAction" id="viewdata_zoom_out"> <property name="stock_id" translatable="yes">gtk-zoom-out</property> - <property name="name">source_zoom_out</property> + <property name="name">viewdata_zoom_out</property> </object> <accelerator key="minus" modifiers="GDK_CONTROL_MASK"/> </child> <child> - <object class="GtkAction" id="source_zoom_normal"> + <object class="GtkAction" id="viewdata_zoom_normal"> <property name="stock_id" translatable="yes">gtk-zoom-100</property> - <property name="name">source_zoom_normal</property> + <property name="name">viewdata_zoom_normal</property> </object> <accelerator key="0" modifiers="GDK_CONTROL_MASK"/> </child> @@ -102,9 +102,9 @@ </object> </child> <child> - <object class="GtkAction" id="source_about"> + <object class="GtkAction" id="viewdata_about"> <property name="stock_id" translatable="yes">gtk-about</property> - <property name="name">source_about</property> + <property name="name">viewdata_about</property> </object> </child> </object> @@ -112,30 +112,30 @@ <ui> <menubar name="menubar1"> <menu action="menuitem1"> - <menuitem action="source_save_as"/> - <menuitem action="source_print"/> + <menuitem action="viewdata_save_as"/> + <menuitem action="viewdata_print"/> <separator/> - <menuitem action="source_close"/> + <menuitem action="viewdata_close"/> </menu> <menu action="menuitem2"> - <menuitem action="source_select_all"/> - <menuitem action="source_cut"/> - <menuitem action="source_copy"/> - <menuitem action="source_paste"/> - <menuitem action="source_delete"/> + <menuitem action="viewdata_select_all"/> + <menuitem action="viewdata_cut"/> + <menuitem action="viewdata_copy"/> + <menuitem action="viewdata_paste"/> + <menuitem action="viewdata_delete"/> </menu> <menu action="menuitem3"> - <menuitem action="source_zoom_in"/> - <menuitem action="source_zoom_out"/> - <menuitem action="source_zoom_normal"/> + <menuitem action="viewdata_zoom_in"/> + <menuitem action="viewdata_zoom_out"/> + <menuitem action="viewdata_zoom_normal"/> </menu> <menu action="menuitem4"> - <menuitem action="source_about"/> + <menuitem action="viewdata_about"/> </menu> </menubar> </ui> </object> - <object class="GtkWindow" id="wndSource"> + <object class="GtkWindow" id="ViewDataWindow"> <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> @@ -154,7 +154,7 @@ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <child> - <object class="GtkTextView" id="source_view"> + <object class="GtkTextView" id="viewdata_view"> <property name="width_request">600</property> <property name="height_request">400</property> <property name="visible">True</property> diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 77c8ddc39..0e6e8bccd 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -54,7 +54,7 @@ #include "gtk/completion.h" #include "gtk/dialogs/preferences.h" #include "gtk/dialogs/about.h" -#include "gtk/dialogs/source.h" +#include "gtk/viewsource.h" #include "gtk/bitmap.h" #include "gtk/gui.h" #include "gtk/history.h" @@ -1174,8 +1174,7 @@ MULTIHANDLER(fullscreen) MULTIHANDLER(viewsource) { - nsgtk_source_dialog_init(g->window, - nsgtk_get_browser_window(g->top_level)); + nsgtk_viewsource(g->window, nsgtk_get_browser_window(g->top_level)); return TRUE; } diff --git a/gtk/viewdata.c b/gtk/viewdata.c new file mode 100644 index 000000000..cb6e7c8de --- /dev/null +++ b/gtk/viewdata.c @@ -0,0 +1,569 @@ +/* + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf 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; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file generic data viewer implementation. + * + * This viewer can be used for utf-8 encoded chunk of data. Thie data + * might be page source or the debugging of dom or box trees. It will + * show the data in a tab, window or editor as per user configuration. + */ + +#include <stdlib.h> +#include <string.h> +#include <gtk/gtk.h> + +#include "utils/log.h" +#include "utils/nsoption.h" +#include "utils/utf8.h" +#include "utils/messages.h" +#include "utils/url.h" +#include "utils/utils.h" +#include "utils/file.h" +#include "desktop/netsurf.h" +#include "desktop/browser.h" +#include "render/html.h" +#include "content/hlcache.h" +#include "content/content.h" + +#include "gtk/dialogs/about.h" +#include "gtk/fetch.h" +#include "gtk/compat.h" +#include "gtk/gui.h" +#include "gtk/viewdata.h" + +struct nsgtk_viewdata_ctx { + char *data; + size_t data_len; + char *filename; + + GtkBuilder *builder; /**< The gtk builder that built the widgets. */ + GtkWindow *window; /**< handle to gtk window (builder holds reference) */ + GtkTextView *gv; /**< handle to gtk text view (builder holds reference) */ + + struct nsgtk_viewdata_ctx *next; + struct nsgtk_viewdata_ctx *prev; +}; + +struct menu_events { + const char *widget; + GCallback handler; +}; + +static struct nsgtk_viewdata_ctx *nsgtk_viewdata_list = NULL; +static char viewdata_zoomlevel = 10; + +#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } +#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \ + GtkMenuItem *widget, gpointer g) + +MENUPROTO(viewdata_save_as); +MENUPROTO(viewdata_print); +MENUPROTO(viewdata_close); +MENUPROTO(viewdata_select_all); +MENUPROTO(viewdata_cut); +MENUPROTO(viewdata_copy); +MENUPROTO(viewdata_paste); +MENUPROTO(viewdata_delete); +MENUPROTO(viewdata_zoom_in); +MENUPROTO(viewdata_zoom_out); +MENUPROTO(viewdata_zoom_normal); +MENUPROTO(viewdata_about); + +static struct menu_events viewdata_menu_events[] = { + MENUEVENT(viewdata_save_as), + MENUEVENT(viewdata_print), + MENUEVENT(viewdata_close), + MENUEVENT(viewdata_select_all), + MENUEVENT(viewdata_cut), + MENUEVENT(viewdata_copy), + MENUEVENT(viewdata_paste), + MENUEVENT(viewdata_delete), + MENUEVENT(viewdata_zoom_in), + MENUEVENT(viewdata_zoom_out), + MENUEVENT(viewdata_zoom_normal), + MENUEVENT(viewdata_about), + {NULL, NULL} +}; + +static void nsgtk_attach_viewdata_menu_handlers(GtkBuilder *xml, gpointer g) +{ + struct menu_events *event = viewdata_menu_events; + + while (event->widget != NULL) + { + GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(xml, event->widget)); + g_signal_connect(G_OBJECT(w), "activate", event->handler, g); + event++; + } +} + +static gboolean nsgtk_viewdata_destroy_event(GtkBuilder *window, gpointer g) +{ + struct nsgtk_viewdata_ctx *vdctx = (struct nsgtk_viewdata_ctx *)g; + + if (vdctx->next != NULL) { + vdctx->next->prev = vdctx->prev; + } + + if (vdctx->prev != NULL) { + vdctx->prev->next = vdctx->next; + } else { + nsgtk_viewdata_list = vdctx->next; + } + + /* release the data */ + free(vdctx->data); + + /* free the builder */ + g_object_unref(G_OBJECT(vdctx->builder)); + + /* free the context structure */ + free(vdctx); + + return FALSE; +} + +static gboolean nsgtk_viewdata_delete_event(GtkWindow * window, gpointer g) +{ + return FALSE; +} + + + +static void nsgtk_viewdata_file_save(GtkWindow *parent, const char *filename, + const char *data, size_t data_size) +{ + FILE *f; + GtkWidget *notif; + GtkWidget *label; + + f = fopen(filename, "w+"); + if (f != NULL) { + fwrite(data, data_size, 1, f); + fclose(f); + return; + } + + /* inform user of faliure */ + notif = gtk_dialog_new_with_buttons(messages_get("gtkSaveFailedTitle"), + parent, + GTK_DIALOG_MODAL, GTK_STOCK_OK, + GTK_RESPONSE_NONE, NULL); + + g_signal_connect_swapped(notif, "response", + G_CALLBACK(gtk_widget_destroy), notif); + + label = gtk_label_new(messages_get("gtkSaveFailed")); + gtk_container_add(GTK_CONTAINER(nsgtk_dialog_get_content_area(GTK_DIALOG(notif))), label); + gtk_widget_show_all(notif); + +} + + +gboolean nsgtk_on_viewdata_save_as_activate(GtkMenuItem *widget, gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg = (struct nsgtk_viewdata_ctx *) g; + GtkWidget *fc; + + fc = gtk_file_chooser_dialog_new(messages_get("gtkSaveFile"), + nsg->window, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, + GTK_RESPONSE_ACCEPT, + NULL); + + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), nsg->filename); + + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), + TRUE); + + if (gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_ACCEPT) { + char *filename; + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc)); + nsgtk_viewdata_file_save(nsg->window, filename, nsg->data, nsg->data_len); + g_free(filename); + } + + gtk_widget_destroy(fc); + + return TRUE; +} + + +gboolean nsgtk_on_viewdata_print_activate( GtkMenuItem *widget, gpointer g) +{ + /* correct printing */ + + return TRUE; +} + +gboolean nsgtk_on_viewdata_close_activate( GtkMenuItem *widget, gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg = (struct nsgtk_viewdata_ctx *) g; + + gtk_widget_destroy(GTK_WIDGET(nsg->window)); + + return TRUE; +} + + + +gboolean nsgtk_on_viewdata_select_all_activate (GtkMenuItem *widget, gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg = (struct nsgtk_viewdata_ctx *) g; + GtkTextBuffer *buf = gtk_text_view_get_buffer(nsg->gv); + GtkTextIter start, end; + + gtk_text_buffer_get_bounds(buf, &start, &end); + + gtk_text_buffer_select_range(buf, &start, &end); + + return TRUE; +} + +gboolean nsgtk_on_viewdata_cut_activate(GtkMenuItem *widget, gpointer g) +{ + return TRUE; +} + +gboolean nsgtk_on_viewdata_copy_activate(GtkMenuItem *widget, gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg = (struct nsgtk_viewdata_ctx *) g; + GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(nsg->gv)); + + gtk_text_buffer_copy_clipboard(buf, + gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); + + return TRUE; +} + +gboolean nsgtk_on_viewdata_paste_activate(GtkMenuItem *widget, gpointer g) +{ + return TRUE; +} + +gboolean nsgtk_on_viewdata_delete_activate(GtkMenuItem *widget, gpointer g) +{ + return TRUE; +} + +static void nsgtk_viewdata_update_zoomlevel(gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg; + GtkTextBuffer *buf; + GtkTextTagTable *tab; + GtkTextTag *tag; + + nsg = nsgtk_viewdata_list; + while (nsg) { + if (nsg->gv) { + buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(nsg->gv)); + + tab = gtk_text_buffer_get_tag_table( + GTK_TEXT_BUFFER(buf)); + + tag = gtk_text_tag_table_lookup(tab, "zoomlevel"); + if (!tag) { + tag = gtk_text_tag_new("zoomlevel"); + gtk_text_tag_table_add(tab, GTK_TEXT_TAG(tag)); + } + + gdouble fscale = ((gdouble) viewdata_zoomlevel) / 10; + + g_object_set(GTK_TEXT_TAG(tag), "scale", fscale, NULL); + + GtkTextIter start, end; + + gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buf), + &start, &end); + gtk_text_buffer_remove_all_tags(GTK_TEXT_BUFFER(buf), + &start, &end); + gtk_text_buffer_apply_tag(GTK_TEXT_BUFFER(buf), + GTK_TEXT_TAG(tag), &start, &end); + } + nsg = nsg->next; + } +} + +gboolean nsgtk_on_viewdata_zoom_in_activate(GtkMenuItem *widget, gpointer g) +{ + viewdata_zoomlevel++; + nsgtk_viewdata_update_zoomlevel(g); + + return TRUE; +} + +gboolean nsgtk_on_viewdata_zoom_out_activate(GtkMenuItem *widget, gpointer g) +{ + if (viewdata_zoomlevel > 1) { + viewdata_zoomlevel--; + nsgtk_viewdata_update_zoomlevel(g); + } + + return TRUE; +} + + +gboolean nsgtk_on_viewdata_zoom_normal_activate(GtkMenuItem *widget, gpointer g) +{ + viewdata_zoomlevel = 10; + nsgtk_viewdata_update_zoomlevel(g); + + return TRUE; +} + +gboolean nsgtk_on_viewdata_about_activate(GtkMenuItem *widget, gpointer g) +{ + struct nsgtk_viewdata_ctx *nsg = (struct nsgtk_viewdata_ctx *) g; + + nsgtk_about_dialog_init(nsg->window, netsurf_version); + + return TRUE; +} + +/** + * View the data in a gtk text window. + */ +static nserror +window_init(const char *title, + const char *filename, + char *ndata, + size_t ndata_len) +{ + GError* error = NULL; + GtkWindow *window; + GtkWidget *cutbutton; + GtkWidget *pastebutton; + GtkWidget *deletebutton; + GtkWidget *printbutton; + GtkTextView *dataview; + PangoFontDescription *fontdesc; + GtkTextBuffer *tb; + struct nsgtk_viewdata_ctx *newctx; + + newctx = malloc(sizeof(struct nsgtk_viewdata_ctx)); + if (newctx == NULL) { + return NSERROR_NOMEM; + } + + newctx->builder = gtk_builder_new(); + if (newctx->builder == NULL) { + free(newctx); + return NSERROR_INIT_FAILED; + } + + if (!gtk_builder_add_from_file(newctx->builder, + glade_file_location->viewdata, + &error)) { + LOG(("Couldn't load builder file: %s", error->message)); + g_error_free(error); + free(newctx); + return NSERROR_INIT_FAILED; + } + + + window = GTK_WINDOW(gtk_builder_get_object(newctx->builder, "ViewDataWindow")); + + if (window == NULL) { + LOG(("Unable to find window in builder ")); + + /* free the builder */ + g_object_unref(G_OBJECT(newctx->builder)); + + /* free the context structure */ + free(newctx); + + return NSERROR_INIT_FAILED; + } + + cutbutton = GTK_WIDGET(gtk_builder_get_object(newctx->builder, "viewdata_cut")); + pastebutton = GTK_WIDGET(gtk_builder_get_object(newctx->builder, "viewdata_paste")); + deletebutton = GTK_WIDGET(gtk_builder_get_object(newctx->builder, "viewdata_delete")); + printbutton = GTK_WIDGET(gtk_builder_get_object(newctx->builder, "viewdata_print")); + gtk_widget_set_sensitive(cutbutton, FALSE); + gtk_widget_set_sensitive(pastebutton, FALSE); + gtk_widget_set_sensitive(deletebutton, FALSE); + /* for now */ + gtk_widget_set_sensitive(printbutton, FALSE); + + + newctx->filename = strdup(filename); + + newctx->data = ndata; + newctx->data_len = ndata_len; + + newctx->window = window; + + newctx->next = nsgtk_viewdata_list; + newctx->prev = NULL; + if (nsgtk_viewdata_list != NULL) { + nsgtk_viewdata_list->prev = newctx; + } + nsgtk_viewdata_list = newctx; + + nsgtk_attach_viewdata_menu_handlers(newctx->builder, newctx); + + gtk_window_set_title(window, title); + + g_signal_connect(G_OBJECT(window), "destroy", + G_CALLBACK(nsgtk_viewdata_destroy_event), + newctx); + g_signal_connect(G_OBJECT(window), "delete-event", + G_CALLBACK(nsgtk_viewdata_delete_event), + newctx); + + dataview = GTK_TEXT_VIEW(gtk_builder_get_object(newctx->builder, + "viewdata_view")); + + fontdesc = pango_font_description_from_string("Monospace 8"); + + newctx->gv = dataview; + nsgtk_widget_modify_font(GTK_WIDGET(dataview), fontdesc); + + tb = gtk_text_view_get_buffer(dataview); + gtk_text_buffer_set_text(tb, newctx->data, -1); + + gtk_widget_show(GTK_WIDGET(window)); + + return NSERROR_OK; +} + +/** + * create a new tab with page source + */ +static nserror +tab_init(const char *title, + const char *filename, + char *ndata, + size_t ndata_len) +{ + nsurl *url; + nserror ret; + gchar *fname; + gint handle; + FILE *f; + + handle = g_file_open_tmp("nsgtksourceXXXXXX", &fname, NULL); + if ((handle == -1) || (fname == NULL)) { + return NSERROR_SAVE_FAILED; + } + close(handle); /* in case it was binary mode */ + + /* save data to temportary file */ + f = fopen(fname, "w"); + if (f == NULL) { + warn_user(messages_get("gtkSourceTabError"), 0); + g_free(fname); + return NSERROR_SAVE_FAILED; + } + fprintf(f, "%s", ndata); + fclose(f); + + /* Open tab on temporary file */ + ret = netsurf_path_to_nsurl(fname, &url); + g_free(fname); + if (ret != NSERROR_OK) { + return ret; + } + + /* open tab on temportary file */ + ret = browser_window_create(BW_CREATE_TAB | BW_CREATE_HISTORY, url, NULL, NULL, NULL); + nsurl_unref(url); + if (ret != NSERROR_OK) { + return ret; + } + + free(ndata); + + return NSERROR_OK; +} + +/** + * create a new tab with page source + */ +static nserror +editor_init(const char *title, + const char *filename, + char *ndata, + size_t ndata_len) +{ +/* find user configured app for opening text/plain */ + +/* + * serach path is ${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share} + * + * $XDG_DATA_HOME if empty use $HOME/.local/share + * + * XDG_DATA_DIRS if empty use /usr/local/share/:/usr/share/ + * + * search path looking for applications/defaults.list + * + * look for [Default Applications] + * search lines looking like mime/type=Desktop + * + * if mimetype is found + * use search path with applications/application.desktop + * + * search desktop file for: + * Exec=gedit %U + * + * execute target app on saved data + */ + + free(ndata); + + return NSERROR_OK; +} + +/* exported interface documented in gtk/viewdata.h */ +nserror +nsgtk_viewdata(const char *title, + const char *filename, + char *ndata, + size_t ndata_len) +{ + nserror ret; + + switch (nsoption_int(developer_view)) { + case 0: + ret = window_init(title, filename, ndata, ndata_len); + break; + + case 1: + ret = tab_init(title, filename, ndata, ndata_len); + break; + + case 2: + ret = editor_init(title, filename, ndata, ndata_len); + break; + + default: + ret = NSERROR_BAD_PARAMETER; + break; + } + if (ret != NSERROR_OK) { + /* release the data */ + free(ndata); + } + + + return ret; +} diff --git a/gtk/viewdata.h b/gtk/viewdata.h new file mode 100644 index 000000000..020603d6c --- /dev/null +++ b/gtk/viewdata.h @@ -0,0 +1,36 @@ +/* + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf 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; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_GTK_VIEWDATA_H_ +#define _NETSURF_GTK_VIEWDATA_H_ + +/** + * Display text to a user. + * + * The data is utf-8 encoded text and will be presented in a window, a + * tab or an editor as per the user configuration. + * + * \param title The title of the data being displayed. + * \param filename The suggested filename to be used. + * \param data The data to be shown. This data will be freed once the + * display is complete, the caller no longer owns the allocation. + * \param data_size The size of the data in data. + */ +nserror nsgtk_viewdata(const char *title, const char *filename, char *data, size_t data_size); + +#endif diff --git a/gtk/viewsource.c b/gtk/viewsource.c new file mode 100644 index 000000000..cbcbad712 --- /dev/null +++ b/gtk/viewsource.c @@ -0,0 +1,81 @@ +/* + * Copyright 2009 Mark Benjamin <MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf 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; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <gtk/gtk.h> + +#include "utils/nsurl.h" +#include "utils/url.h" +#include "utils/utils.h" +#include "utils/utf8.h" +#include "utils/messages.h" +#include "desktop/browser.h" +#include "content/content.h" +#include "render/html.h" + +#include "gtk/viewdata.h" +#include "gtk/viewsource.h" + +void nsgtk_viewsource(GtkWindow *parent, struct browser_window *bw) +{ + nserror ret; + struct hlcache_handle *hlcontent; + const char *source_data; + unsigned long source_size; + char *ndata = NULL; + size_t ndata_len; + char *filename; + char *title; + + hlcontent = browser_window_get_content(bw); + if (hlcontent == NULL) { + return; + } + + if (content_get_type(hlcontent) != CONTENT_HTML) { + return; + } + + source_data = content_get_source_data(hlcontent, &source_size); + + ret = url_nice(nsurl_access(browser_window_get_url(bw)), &filename, false); + if (ret != NSERROR_OK) { + filename = strdup(messages_get("SaveSource")); + if (filename == NULL) { + return; + } + } + + title = malloc(strlen(nsurl_access(browser_window_get_url(bw))) + SLEN("Source of - NetSurf") + 1); + sprintf(title, "Source of %s - NetSurf", nsurl_access(browser_window_get_url(bw))); + + ret = utf8_from_enc(source_data, + html_get_encoding(hlcontent), + source_size, + &ndata, + &ndata_len); + if (ret != NSERROR_OK) { + free(filename); + return; + } + + ret = nsgtk_viewdata(title, filename, ndata, ndata_len); + free(filename); +} diff --git a/gtk/dialogs/source.h b/gtk/viewsource.h index fcba6b664..fe85b30b5 100644 --- a/gtk/dialogs/source.h +++ b/gtk/viewsource.h @@ -1,5 +1,5 @@ /* - * Copyright 2009 Mark Benjamin <netsurfbrowser.org.MarkBenjamin@dfgh.net> + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,13 +16,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef netsurf_gtk_dialogs_source_h_ -#define netsurf_gtk_dialogs_source_h_ +#ifndef _NETSURF_GTK_VIEWSOURCE_H_ +#define _NETSURF_GTK_VIEWSOURCE_H_ -#include <gtk/gtk.h> -#include "desktop/browser.h" - -void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw); +void nsgtk_viewsource(GtkWindow *parent, struct browser_window *bw); #endif |